]> git.saurik.com Git - cydia.git/blob - UICaboodle/UCYield.h
Verified 2.2+ methods against 2.1 SDK: all were present.
[cydia.git] / UICaboodle / UCYield.h
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