diff --git a/Framework/XCode/Representations/DBManagedObject.h b/Framework/XCode/Representations/DBManagedObject.h index 33a6720c..a3e07257 100644 --- a/Framework/XCode/Representations/DBManagedObject.h +++ b/Framework/XCode/Representations/DBManagedObject.h @@ -309,5 +309,7 @@ extern char DBCacheSuffixChar; + (const char *)monoClassTypeName:(MonoClass *)klass; + (void)registerInternalCall:(NSString *)methodName callPointer:(void *)callPointer; +- (void)addMonoEventHandler:(MonoObject*)eventHandler toEventNamed:(NSString*)eventName; +- (void)removeMonoEventHandler:(MonoObject*)eventHandler fromEventNamed:(NSString*)eventName; @end diff --git a/Framework/XCode/Representations/DBManagedObject.m b/Framework/XCode/Representations/DBManagedObject.m index e9bf3d26..064a9b90 100644 --- a/Framework/XCode/Representations/DBManagedObject.m +++ b/Framework/XCode/Representations/DBManagedObject.m @@ -1346,4 +1346,22 @@ - (void)setAutomaticallyNotifiesObserversOfManagedPropertyChanges:(BOOL)value } } +- (void)addMonoEventHandler:(MonoObject*)eventHandler toEventNamed:(NSString*)eventName +{ + MonoObject* monoType = [self invokeMonoMethod:"GetType()" withNumArgs:0]; + DBManagedObject* dbType = [DBManagedObject objectWithMonoObject:monoType]; + + MonoObject* monoEventInfo = [dbType invokeMonoMethod:"System.Reflection.GetEvent(string)" withNumArgs:1, eventName.monoRTInvokeArg]; + DBManagedObject* eventInfo = [DBManagedObject objectWithMonoObject:monoEventInfo]; + [eventInfo invokeMonoMethod:"System.Reflection.EventInfo.AddEventHandler(object,System.Delegate)" withNumArgs:2, self.monoObject, eventHandler]; +} + +- (void)removeMonoEventHandler:(MonoObject*)eventHandler fromEventNamed:(NSString*)eventName +{ + MonoObject* monoType = [self invokeMonoMethod:"GetType()" withNumArgs:0]; + DBManagedObject* dbType = [DBManagedObject objectWithMonoObject:monoType]; + MonoObject* monoEventInfo = [dbType invokeMonoMethod:"System.Reflection.GetEvent(string)" withNumArgs:1, eventName.monoRTInvokeArg]; + DBManagedObject* eventInfo = [DBManagedObject objectWithMonoObject:monoEventInfo]; + [eventInfo invokeMonoMethod:"System.Reflection.EventInfo.RemoveEventHandler(object,System.Delegate)" withNumArgs:2, self.monoObject, eventHandler]; +} @end diff --git a/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.h b/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.h index c5533c1a..64946987 100644 --- a/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.h +++ b/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.h @@ -9,6 +9,8 @@ #import "System_Object.h" #import "System_Type.h" +@class System_Delegate; + @interface System_Object (mscorlib) /** @@ -98,4 +100,7 @@ - (uint32_t)unsigned32Value; - (uint64_t)unsigned64Value; +- (void)addEventHandler:(System_Delegate *)eventHandler toEventNamed:(NSString *)eventName; +- (void)removeEventHandler:(System_Delegate *)eventHandler fromEventNamed:(NSString *)eventName; +- (NSArray *)eventHandlersForEventNamed:(NSString *)eventName; @end diff --git a/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.m b/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.m index d92c4f66..a24be20b 100644 --- a/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.m +++ b/Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.m @@ -10,6 +10,8 @@ #import "System_Convert+mscorlib.h" #import "System_Type+mscorlib.h" #import "DBGenericTypeHelper.h" +#import "System_Delegate.h" +#import @implementation System_Object (mscorlib) @@ -116,4 +118,90 @@ - (uint64_t)unsigned64Value { return([System_Convert convertMonoObjectToUInt64:self.monoObject]); } +#pragma mark - +#pragma mark Events + +- (NSMutableDictionary *> *)eventHandlers +{ + NSMutableDictionary *handlers = objc_getAssociatedObject(self, @selector(eventHandlers)); + if (!handlers) { + handlers = NSMutableDictionary.dictionary; + objc_setAssociatedObject(self, @selector(eventHandlers), handlers, OBJC_ASSOCIATION_RETAIN); + } + + return handlers; +} + +- (void)addEventHandler:(System_Delegate *)eventHandler toEventNamed:(NSString *)eventName +{ + BOOL success = NO; + + @try { + [self addMonoEventHandler:eventHandler.monoObject toEventNamed:eventName]; + + success = YES; + } + @catch (NSException *ex) { + NSLog(@"%@:%s : %@", self.className, __FUNCTION__, ex.reason); + } + + if (!success) { + return; + } + + [self cacheEventHandler:eventHandler forEventNamed:eventName]; +} + +- (void)cacheEventHandler:(System_Delegate *)eventHandler forEventNamed:(NSString *)eventName +{ + NSMutableArray *handlers = [self.eventHandlers objectForKey:eventName]; + + if (!handlers) { + handlers = NSMutableArray.array; + self.eventHandlers[eventName] = handlers; + } + + [handlers addObject:eventHandler]; +} + +- (void)removeEventHandler:(System_Delegate *)eventHandler fromEventNamed:(NSString *)eventName +{ + BOOL success = NO; + + @try { + [self removeMonoEventHandler:eventHandler.monoObject fromEventNamed:eventName]; + success = YES; + } + @catch (NSException *ex) { + NSLog(@"%@:%s : %@", self.className, __FUNCTION__, ex.reason); + } + + if (!success) { + return; + } + + [self uncacheEventHandler:eventHandler forEventNamed:eventName]; +} + +- (void)uncacheEventHandler:(System_Delegate *)eventHandler forEventNamed:(NSString *)eventName +{ + NSMutableArray * handlers = [self.eventHandlers objectForKey:eventName]; + + if (!handlers) { + return; + } + + [handlers removeObject:eventHandler]; + + if (handlers.count <= 0) { + [self.eventHandlers removeObjectForKey:eventName]; + } +} + +- (NSArray *)eventHandlersForEventNamed:(NSString *)eventName +{ + NSArray* handlers = [self.eventHandlers objectForKey:eventName]; + + return handlers; +} @end