From: dsc Date: Sat, 4 Jun 2011 09:40:12 +0000 (-0700) Subject: Adds support to Sparrow's SPEventDispatcher to subscribe to all events using SP_EVENT... X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=35eed295c68be1b3cafc864d5b2f5ff0890a9ed1;p=tanks-ios.git Adds support to Sparrow's SPEventDispatcher to subscribe to all events using SP_EVENT_TYPE_ANY. --- diff --git a/libs/sparrow/src/Classes/SPEvent.h b/libs/sparrow/src/Classes/SPEvent.h index a4c2a90..6553cdb 100644 --- a/libs/sparrow/src/Classes/SPEvent.h +++ b/libs/sparrow/src/Classes/SPEvent.h @@ -11,6 +11,7 @@ #import +#define SP_EVENT_TYPE_ANY @"" #define SP_EVENT_TYPE_ADDED @"added" #define SP_EVENT_TYPE_ADDED_TO_STAGE @"addedToStage" #define SP_EVENT_TYPE_REMOVED @"removed" diff --git a/libs/sparrow/src/Classes/SPEventDispatcher.h b/libs/sparrow/src/Classes/SPEventDispatcher.h index 264e9da..f3b2c08 100644 --- a/libs/sparrow/src/Classes/SPEventDispatcher.h +++ b/libs/sparrow/src/Classes/SPEventDispatcher.h @@ -54,13 +54,14 @@ { @private NSMutableDictionary *mEventListeners; + NSArray* mAnyEventListeners; } /// ------------- /// @name Methods /// ------------- -/// Registers an event listener at a certain object. +/// Registers an event listener at a certain object. Passing the empty string or nil will register for all events. - (void)addEventListener:(SEL)listener atObject:(id)object forType:(NSString*)eventType retainObject:(BOOL)retain; diff --git a/libs/sparrow/src/Classes/SPEventDispatcher.m b/libs/sparrow/src/Classes/SPEventDispatcher.m index 9721b9d..b4e1ce1 100644 --- a/libs/sparrow/src/Classes/SPEventDispatcher.m +++ b/libs/sparrow/src/Classes/SPEventDispatcher.m @@ -26,6 +26,8 @@ NSInvocation *invocation = [NSInvocation invocationWithTarget:object selector:listener]; if (doRetain) [invocation retainArguments]; + if (eventType == nil) eventType = @""; + // When an event listener is added or removed, a new NSArray object is created, instead of // changing the array. The reason for this is that we can avoid creating a copy of the NSArray // in the "dispatchEvent"-method, which is called far more often than @@ -34,15 +36,14 @@ NSArray *listeners = [mEventListeners objectForKey:eventType]; if (!listeners) { - listeners = [[NSArray alloc] initWithObjects:invocation, nil]; - [mEventListeners setObject:listeners forKey:eventType]; - [listeners release]; + listeners = [NSArray arrayWithObject:invocation]; } else { listeners = [listeners arrayByAddingObject:invocation]; - [mEventListeners setObject:listeners forKey:eventType]; - } + } + [mEventListeners setObject:listeners forKey:eventType]; + } - (void)addEventListener:(SEL)listener atObject:(id)object forType:(NSString*)eventType @@ -52,6 +53,8 @@ - (void)removeEventListener:(SEL)listener atObject:(id)object forType:(NSString*)eventType { + if (eventType == nil) eventType = @""; + NSArray *listeners = [mEventListeners objectForKey:eventType]; if (listeners) { @@ -76,13 +79,15 @@ - (BOOL)hasEventListenerForType:(NSString*)eventType { + if (eventType == nil) eventType = @""; return [mEventListeners objectForKey:eventType] != nil; } - (void)dispatchEvent:(SPEvent*)event { - NSMutableArray *listeners = [mEventListeners objectForKey:event.type]; - if (!event.bubbles && !listeners) return; // no need to do anything. + NSArray *listenersOfType = [mEventListeners objectForKey:event.type]; + NSArray *listenersOfAllEvents = [mEventListeners objectForKey:@""]; + if (!event.bubbles && !(listenersOfType || listenersOfAllEvents)) return; // no need to do anything. // if the event already has a current target, it was re-dispatched by user -> we change the // target to 'self' for now, but undo that later on (instead of creating a copy, which could @@ -94,23 +99,26 @@ [self retain]; // the event listener could release 'self', so we have to make sure that it // stays valid while we're here. - BOOL stopImmediatPropagation = NO; - if (listeners.count != 0) - { - // we can enumerate directly over the array, since "add"- and "removeEventListener" won't - // change it, but instead always create a new array. - [listeners retain]; - for (NSInvocation *inv in listeners) - { - [inv setArgument:&event atIndex:2]; - [inv invoke]; - if (event.stopsImmediatePropagation) + BOOL stopImmediatPropagation = NO; + NSArray *listeners = listenersOfType; + while (listeners) { + if (listeners.count != 0) { + // we can enumerate directly over the array, since "add"- and "removeEventListener" won't + // change it, but instead always create a new array. + [listeners retain]; + for (NSInvocation *inv in listeners) { - stopImmediatPropagation = YES; - break; + [inv setArgument:&event atIndex:2]; + [inv invoke]; + if (event.stopsImmediatePropagation) + { + stopImmediatPropagation = YES; + break; + } } + [listeners release]; } - [listeners release]; + listeners = (listeners != listenersOfAllEvents ? listenersOfAllEvents : nil); } if (!stopImmediatPropagation)