![]() |
echo $fn ?> |
1: /* --------------------------------------------------------------------------------------- */ 2: /* No freakin' copyright, no stinkin' license, no guarantees or warranties */ 3: /* (implied, explicit or whatever). Usage is totally and completely at your own risk. */ 4: /* Please keep this comment block as is when modifying this code. Thanks in advance, */ 5: /* Ruurd Idenburg */ 6: /* --------------------------------------------------------------------------------------- */ 7: /** 8: The eventable class is a mixin class, that can be used in the 9: inheriting class to define events (by name) and trigger those events so that 10: other classes may act upon those events. 11:12: Events are defined as indexes in an events directory. The events directory 13: is created in the events instance init method and is therefore 14: available after the inheriting class instance creation has called it's super 15: class init method, so the logical thing to do is to define the 16: class instance events in the inheriting class init method for 17: new instances. However events can also be defined later on by the inheriting 18: class instance methods. 19:
20: Event handlers/listeners need to define an instance method with the name of 21: the defined event. That method will be invoked by the triggering of the event. 22: The handler/listener method should return the boolean .true or .false 23: depending on whether possible other handlers/listeners should be given the 24: opportunity to act on the event. Returning .false will allow other 25: handlers/listeners to be invoked as well, returning .true will stop 26: invoking other handlers/listeners. 27:
28: Handlers/Listeners are kept as members of an array that is the item in the 29: directory entry for the index that has the name of the event. 30: */ 31: ::class eventable public mixinclass object 32: 33: /** 34: The events attribute is a directory, whose entries can only be set privately 35: by the inheriting class instance methods. The directory is created in the 36: init instance method of this (the events) class. 37: */ 38: ::attribute events get 39: 40: ::attribute events set private 41: 42: /** 43: The init method creates the directory that will have the event 44: names as indexes and the array of handlers/listeners as items. 45:
46: @param eventArray=(.array~new) - optional, an array of event names provided by the inheriting class 47:48: If an array with event names is provided, the entries are created in the events directory 49: with empty arrays as items to hold future handlers/listeners. 50: */ 51: ::method init 52: expose events 53: use strict arg eventArray=(.array~new) 54: events = .directory~new 55: if eventArray~class~id==.array then do 56: do a over eventArray 57: events[a] = .array~new 58: end 59: end 60: 61: /** 62: addEventHander is a synonym for addEventListener 63:
64: @see #addEventListener 65: */ 66: ::method addEventHandler 67: use strict arg event, handler 68: self~addEventListener(event, handler) 69: 70: /** 71: Adds an object to the group of interested parties 72:
73: @param event - the name of an event 74: @param listener - the object interested in that event 75:76: If the array of handlers/listeners does not exist yet for the event it will 77: be created. The handler/listener object is appended to the existing or new array 78:
79: It is not verified if the event is a valid event for the object, the result for 80: that condition will be that the handler/listener will never be invoked. 81:
82: The same handler/listener can be added multiple times, if for some reason that 83: would be necessary for proper functioning and provided some earlier handler/listener 84: did not return .true. 85: */ 86: ::method addEventListener 87: expose events 88: --trace i 89: use strict arg event, listener 90: if events[event]==.nil then do 91: events[event] = .array~new 92: end 93: events[event]~append(listener) 94: 95: /** 96: removeEventHandler is a synonym for removeEventListener 97:
98: @see #removeEventListener 99: */ 100: ::method removeEventHandler 101: use strict arg event, handler 102: self~removeEventListener(event, handler) 103: 104: /** 105: Removes a party from the group interested in an event 106:
107: @param event - the name of an event 108: @param listener - the handler/listener object to be removed 109:110: If the event is not known, the object can not be removed obviously 111:
112: If the listener is not a member of the interested handlers/listeners, 113: nothing can be removed. 114:
115: The handlers/listeners will be regenerated to prevent sparseness. 116: */ 117: ::method removeEventListener 118: expose events 119: --trace i 120: use strict arg event, listener 121: if events[event]~class~id==.array then do 122: events[event]~removeItem(listener) 123: events[event] = events[event]~makeArray 124: end 125: 126: /** 127: Returns the list of defined events for the object 128:
129: @return anArray - an array of event names for the object 130:131: The array can be empty if no events have been defined 132: */ 133: ::method eventNames 134: use strict arg 135: return self~events~makeArray 136: 137: /** 138: eventHandlers is a synonym for eventListeners 139:
140: @see #eventListeners 141: */ 142: ::method eventHandlers 143: use strict arg event 144: return self~eventListeners(event) 145: 146: /** 147: Returns an array of handlers/listeners for an event. 148:
149: @param event - the name of an event 150: @return anArray - an array of handlers/listeners for an event 151:152: The returned array can be empty if there are no listeners for the event 153: or if the event is unknown. 154: */ 155: ::method eventListeners 156: expose events 157: use strict arg event 158: if events[event]~isA(.array) then return events[event] 159: return .array~new 160: 161: /** 162: Invokes the event handling method in the handlers/listeners for an 163: event while successive handlers/listeners return .false, and stops 164: to invoke following handlers/listeners on the first .true return. 165:
166: @expose events - the directory of triggerable events for the class 167: @param event - the name of the event to be handled 168: @param args=(.array~new) - optional arguments for the handler method 169:170: */ 171: ::method triggerEvent 172: expose events 173: --trace i 174: use strict arg event, args=(.array~new) 175: if events[event]==.nil then do 176: --.error~lineout('Event:' event 'is not defined') 177: return 178: end 179: if events[event]~items==0 then do 180: --.error~lineout('Event:' event 'does not have listeners') 181: return 182: end 183: result = .false 184: do l over events[event] while result==.false 185: if l~hasMethod(event) then do 186: msg = .message~new(l,event,'I',args~makeString('L',',')) 187: --.traceoutput~say(msg~messageName msg~target msg~arguments~makeString('L',',')) 188: msg~send --start 189: result = msg~result 190: end 191: else do 192: --.error~lineout('Event:' event 'is not a defined method in handler/listener:' l) 193: end 194: end 195:
All content © Ruurd Idenburg, 2007–2025,
except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only.
The Idenburg website records no personal information and sets no ‘cookies’.
This site is hosted on my on server at my home, falling under Dutch (privacy) laws.
This page updated on Wed, 28 May 2025 10:38:18 +0200. |