Generically dispatch system events to your object event listeners (?)

Within your Corona world there are many different events happening, and many different ways to handle them.

The two main types of events are system events and object events. The first ones are kind of system wide events, like “enterFrame” that are not associated with any particular object and are registered with system-wide components like Runtime. The latter ones are events that are directly associated with your object, like “touch” or “collision”, are registered with the objects themselves, and will provide you with a reference to the object state inside of the handler (e.g. thru “event.target”).

There is actually a third type, which are system events that you want to associate with a certain object, like an “enterFrame” event handler where you want to have dedicated code that deals with a particular object’s state. In order to deal with those kinds of events, Corona allows you to register a table-listener that is your object with a handler function that has the name of the event and is a property of your object, like: “myObject.enterFrame = function(self, event)…end”. In that case the object (-state) is accessed thru the self parameter.

The only problem with those object-system-event handlers is that you can have only one of them (as far as I have been able to find out…as you can have only a single object.enterFrame handler), while you can register as many object- or system event handlers for one particular event. Being able to partition your code in different handlers for the same event allows you to keep your code modular. So having only a single option for a object-system-event handler forces you to dispatch inside of that single handler, which soon gets kind of ugly…

I may have found a way to do that dispatching inside of a object-system-event handler generically by forwarding the event to an object event handler for that object:

The single generic function that is registered as an object-system-event handler is:
[lua]-------------------------------------------------------------------------------

objectRuntimeEventDispatcher = function(self, event)
– Usage for “enterFrame” events with a display object “ob”:
– ob[enterFrame] = caEventHandlers.objectRuntimeEventDispatcher
– Register object-table event handler with Runtime like:
– Runtime:addEventListener( “enterFrame”, ob )
– will then forward “enterFrame” event to object’s event handlers like
– “myEnterFrameHandler(event)” that have been registered like:
– ob:addEventListener( “enterFrame”, myEnterFrameHandler )

if (not self.dispatchEvent) then
– poor-man’s test for display object existence
– if we’re here, then only skeleton object exists and we should clean-up
Runtime:removeEventListener( event.name, self )
return true
else
– dispatch event to object itself
– we cannot annotate and reuse the event table as bad things will happen
– so we have to copy the event table for dispatching
local ev = {}
for k,v in pairs(event)do
ev[k]=v
end
– add self as the target such that the handler can find the self-state
ev.target = self
self:dispatchEvent(ev)
return false
end
end

-------------------------------------------------------------------------------[/lua]

* the provided solution is somewhat of a hack as it uses some empirically found knowledge (= debugging weird, surprising behavior ;-)) about Corona’s internals… but seems to work. Any comments/suggestions/alternatives would be very much appreciated

* if the event table would include a event.target property that would point at the object the handler was registered, like “Runtime”, we could make that objectRuntimeEventDispatcher more generic as you can then find out from which object you should remove the handler.

* it is difficult to do the memory management “right” when you annotate display objects with custom properties/attributes - all that monkey patching bites you when your display object has been “removed” by the Corona runtime, but some skeleton is left behind that gets still treated like a display object… It would help if you would have a Corona API that given a display object would tell you whether is has been deleted or not by the Corona runtime. My test of “if (not self.dispatchEvent) then…” seems to work but is kind of a hack until an official function is provided.

* even better… Corona’s event handler dispatch code could include tests that would automatically remove table-event-handlers from display objects that have been deleted - saving a lot of event firing to non-existing objects and memory management issues.

Regards, Frank.

[import]uid: 8093 topic_id: 4505 reply_id: 304505[/import]