1use crate::{arc, define_cls, define_obj_type, ns, objc};
2
3#[cfg(feature = "dispatch")]
4use crate::dispatch;
5
6#[cfg(feature = "blocks")]
7use crate::blocks;
8
9define_obj_type!(
10 #[doc(alias = "NSOperation")]
11 pub Op(ns::Id)
12);
13
14impl Op {
15 define_cls!(NS_OPERATION);
16
17 #[objc::msg_send(isCancelled)]
18 pub fn is_cancelled(&self) -> bool;
19
20 #[objc::msg_send(cancel)]
21 pub fn cancel(&mut self);
22
23 #[objc::msg_send(isExecuting)]
25 pub fn is_executing(&self) -> bool;
26
27 #[objc::msg_send(isFinished)]
28 pub fn is_finished(&self) -> bool;
29
30 #[objc::msg_send(isReady)]
31 pub fn is_ready(&self) -> bool;
32
33 #[objc::msg_send(addDependency:)]
42 pub fn add_dependency(&mut self, val: &ns::Op);
43
44 #[objc::msg_send(removeDependency:)]
46 pub fn remove_dependency(&mut self, val: &ns::Op);
47
48 #[objc::msg_send(dependencies)]
50 pub fn dependencies(&self) -> arc::R<ns::Array<ns::Op>>;
51
52 #[objc::msg_send(name)]
53 pub fn name(&self) -> Option<arc::R<ns::String>>;
54
55 #[objc::msg_send(setName:)]
56 pub fn set_name(&mut self, val: Option<&ns::String>);
57
58 #[objc::msg_send(start)]
60 pub fn start(&mut self);
61
62 #[objc::msg_send(main)]
64 pub fn main(&mut self);
65}
66
67define_obj_type!(
68 #[doc(alias = "NSBlockOperation")]
69 pub BlockOp(Op)
70);
71
72impl BlockOp {
73 define_cls!(NS_BLOCK_OPERATION);
74
75 #[cfg(feature = "blocks")]
76 #[objc::msg_send(blockOperationWithBlock:)]
77 pub fn with_block(block: &mut blocks::WorkBlock) -> arc::R<Self>;
78}
79
80impl ns::KvObserverRegistration for Op {}
81impl ns::KvObserverRegistration for BlockOp {}
82
83define_obj_type!(
84 #[doc(alias = "NSOperationQueue")]
85 pub OpQueue(ns::Id), NS_OPERATION_QUEUE
86);
87
88impl ns::KvObserverRegistration for OpQueue {}
89
90impl OpQueue {
91 #[doc(alias = "NSOperationQueueDefaultMaxConcurrentOperationCount")]
95 pub const DEFAULT_MAX_CONCURRENT_OP_COUNT: isize = -1;
96
97 #[objc::msg_send(name)]
98 pub fn name(&self) -> Option<arc::R<ns::String>>;
99
100 #[objc::msg_send(setName:)]
101 pub fn set_name(&mut self, name: Option<&ns::String>);
102
103 #[objc::msg_send(addOperation:)]
104 pub fn add_op(&mut self, op: &Op);
105
106 #[cfg(feature = "blocks")]
107 #[objc::msg_send(addOperationWithBlock:)]
108 pub fn add_op_with_block(&mut self, block: &mut blocks::WorkBlock);
109
110 #[cfg(feature = "blocks")]
111 #[objc::msg_send(addBarrierBlock:)]
112 pub fn add_barrier_block(&mut self, barrier: &mut blocks::WorkBlock);
113
114 #[objc::msg_send(maxConcurrentOperationCount)]
125 pub fn max_concurrent_ops(&self) -> isize;
126
127 #[objc::msg_send(setMaxConcurrentOperationCount:)]
128 pub fn set_max_concurrent_ops(&mut self, val: isize);
129
130 #[objc::msg_send(isSuspended)]
143 pub fn is_suspended(&self) -> bool;
144
145 #[objc::msg_send(setSuspended:)]
146 pub fn set_suspended(&mut self, val: bool);
147
148 #[objc::msg_send(cancelAllOperations)]
149 pub fn cancel_all_ops(&mut self);
150
151 #[cfg(feature = "dispatch")]
152 #[objc::msg_send(underlyingQueue)]
153 pub fn underlying_queue(&self) -> Option<arc::R<dispatch::Queue>>;
154
155 #[cfg(feature = "dispatch")]
156 #[objc::msg_send(setUnderlyingQueue:)]
157 pub unsafe fn set_underlying_queue_throws(&mut self, val: Option<&dispatch::Queue>);
158
159 #[cfg(feature = "dispatch")]
160 pub fn set_underlying_queue<'ear>(
161 &mut self,
162 val: Option<&dispatch::Queue>,
163 ) -> ns::ExResult<'ear> {
164 ns::try_catch(|| unsafe { self.set_underlying_queue_throws(val) })
165 }
166
167 #[objc::msg_send(currentQueue)]
168 pub fn current() -> Option<arc::R<Self>>;
169
170 #[objc::msg_send(mainQueue)]
171 pub fn main() -> arc::R<Self>;
172}
173
174impl OpQueue {
176 #[objc::msg_send(progress)]
177 pub fn progress(&self) -> arc::R<ns::Progress>;
178}
179
180unsafe extern "C" {
181 static NS_OPERATION: &'static objc::Class<Op>;
182 static NS_BLOCK_OPERATION: &'static objc::Class<BlockOp>;
183 static NS_OPERATION_QUEUE: &'static objc::Class<OpQueue>;
184}
185
186#[cfg(test)]
187mod tests {
188 use crate::{dispatch, ns};
189
190 #[test]
191 fn basics() {
192 assert!(ns::OpQueue::current().is_none());
193 let mut queue = ns::OpQueue::new();
194 assert_eq!(
195 ns::OpQueue::DEFAULT_MAX_CONCURRENT_OP_COUNT,
196 queue.max_concurrent_ops()
197 );
198 assert!(queue.underlying_queue().is_none());
199 let dqueue = dispatch::Queue::new();
200 queue.set_underlying_queue(Some(&dqueue)).unwrap();
201 assert_eq!(queue.underlying_queue().as_ref(), Some(&dqueue));
202 assert_eq!(-1, queue.max_concurrent_ops());
203 queue.set_max_concurrent_ops(10);
204 assert_eq!(10, queue.max_concurrent_ops());
205 assert_eq!(queue.underlying_queue().as_ref(), Some(&dqueue));
206
207 let main_op_queue = ns::OpQueue::main();
208 println!("tid {main_op_queue:?}");
209 }
210}