Skip to content

Commit

Permalink
Implements #23. Unit tests still pass, but they don't as yet include …
Browse files Browse the repository at this point in the history
…implicit tests for this new functionality.
  • Loading branch information
Jonathan Mitchell committed Feb 6, 2019
1 parent 36a8712 commit df94f63
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Framework/XCode/Representations/DBManagedObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
18 changes: 18 additions & 0 deletions Framework/XCode/Representations/DBManagedObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#import "System_Object.h"
#import "System_Type.h"

@class System_Delegate;

@interface System_Object (mscorlib)

/**
Expand Down Expand Up @@ -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<System_Delegate *> *)eventHandlersForEventNamed:(NSString *)eventName;
@end
88 changes: 88 additions & 0 deletions Mono.mscorlib/Mono.mscorlib/Categories/System_Object+mscorlib.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#import "System_Convert+mscorlib.h"
#import "System_Type+mscorlib.h"
#import "DBGenericTypeHelper.h"
#import "System_Delegate.h"
#import <objc/runtime.h>

@implementation System_Object (mscorlib)

Expand Down Expand Up @@ -116,4 +118,90 @@ - (uint64_t)unsigned64Value {
return([System_Convert convertMonoObjectToUInt64:self.monoObject]);
}

#pragma mark -
#pragma mark Events

- (NSMutableDictionary<NSString *, NSMutableArray<System_Delegate *> *> *)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<System_Delegate *> *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<System_Delegate *> * handlers = [self.eventHandlers objectForKey:eventName];

if (!handlers) {
return;
}

[handlers removeObject:eventHandler];

if (handlers.count <= 0) {
[self.eventHandlers removeObjectForKey:eventName];
}
}

- (NSArray<System_Delegate *> *)eventHandlersForEventNamed:(NSString *)eventName
{
NSArray<System_Delegate*>* handlers = [self.eventHandlers objectForKey:eventName];

return handlers;
}
@end

0 comments on commit df94f63

Please sign in to comment.