Files
Cydia/UICaboodle/UCYield.h
Victor Bodinaud 954e43aa2f first commit
2025-03-03 13:59:05 +01:00

65 lines
1.8 KiB
Objective-C

@interface NSObject (UICaboodle)
- (id) yieldToSelector:(SEL)selector withObject:(id)object;
- (id) yieldToSelector:(SEL)selector;
@end
@implementation NSObject (UICaboodle)
- (void) doNothing {
}
- (void) _yieldToContext:(NSMutableArray *)context { _pooled
SEL selector(reinterpret_cast<SEL>([[context objectAtIndex:0] pointerValue]));
id object([[context objectAtIndex:1] nonretainedObjectValue]);
volatile bool &stopped(*reinterpret_cast<bool *>([[context objectAtIndex:2] pointerValue]));
/* XXX: deal with exceptions */
id value([self performSelector:selector withObject:object]);
NSMethodSignature *signature([self methodSignatureForSelector:selector]);
[context removeAllObjects];
if ([signature methodReturnLength] != 0 && value != nil)
[context addObject:value];
stopped = true;
[self
performSelectorOnMainThread:@selector(doNothing)
withObject:nil
waitUntilDone:NO
];
}
- (id) yieldToSelector:(SEL)selector withObject:(id)object {
/*return [self performSelector:selector withObject:object];*/
volatile bool stopped(false);
NSMutableArray *context([NSMutableArray arrayWithObjects:
[NSValue valueWithPointer:selector],
[NSValue valueWithNonretainedObject:object],
[NSValue valueWithPointer:const_cast<bool *>(&stopped)],
nil]);
NSThread *thread([[[NSThread alloc]
initWithTarget:self
selector:@selector(_yieldToContext:)
object:context
] autorelease]);
[thread start];
NSRunLoop *loop([NSRunLoop currentRunLoop]);
NSDate *future([NSDate distantFuture]);
while (!stopped && [loop runMode:NSDefaultRunLoopMode beforeDate:future]);
return [context count] == 0 ? nil : [context objectAtIndex:0];
}
- (id) yieldToSelector:(SEL)selector {
return [self yieldToSelector:selector withObject:nil];
}
@end