]> git.saurik.com Git - cydia.git/blame - UICaboodle/UCYield.h
Merge branch 'master' of git.saurik.com:cydia
[cydia.git] / UICaboodle / UCYield.h
CommitLineData
11cd0308
JF
1@interface NSObject (UICaboodle)
2- (id) yieldToSelector:(SEL)selector withObject:(id)object;
3- (id) yieldToSelector:(SEL)selector;
4@end
5
6@implementation NSObject (UICaboodle)
7
8- (void) doNothing {
9}
10
11- (void) _yieldToContext:(NSMutableArray *)context { _pooled
12 SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
13 id object([[context objectAtIndex:1] nonretainedObjectValue]);
14 volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
15
16 /* XXX: deal with exceptions */
17 id value([self performSelector:selector withObject:object]);
18
19 NSMethodSignature *signature([self methodSignatureForSelector:selector]);
20 [context removeAllObjects];
21 if ([signature methodReturnLength] != 0 && value != nil)
22 [context addObject:value];
23
24 stopped = true;
25
26 [self
27 performSelectorOnMainThread:@selector(doNothing)
28 withObject:nil
29 waitUntilDone:NO
30 ];
31}
32
33- (id) yieldToSelector:(SEL)selector withObject:(id)object {
34 /*return [self performSelector:selector withObject:object];*/
35
36 volatile bool stopped(false);
37
38 NSMutableArray *context([NSMutableArray arrayWithObjects:
39 [NSValue valueWithPointer:selector],
40 [NSValue valueWithNonretainedObject:object],
41 [NSValue valueWithPointer:const_cast<bool *>(&stopped)],
42 nil]);
43
44 NSThread *thread([[[NSThread alloc]
45 initWithTarget:self
46 selector:@selector(_yieldToContext:)
47 object:context
48 ] autorelease]);
49
50 [thread start];
51
52 NSRunLoop *loop([NSRunLoop currentRunLoop]);
53 NSDate *future([NSDate distantFuture]);
54
55 while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
56
57 return [context count] == 0 ? nil : [context objectAtIndex:0];
58}
59
60- (id) yieldToSelector:(SEL)selector {
61 return [self yieldToSelector:selector withObject:nil];
62}
63
64@end