*My second update. Previous posts were overly complicated and impractical.
Some simple code to add/remove listeners. Nothing special going on here, I basically wanted the ability to remove all listeners pertaining to a specific sprite in one line.
You'll notice in the 'addListener' function, there is a 'target' parameter. This should be used when the event you're listening for is not dispatched to the sprite handling the listener function.
No additional closures are created so performance of a dispatched event is normal.
MySprite = Core.class(Sprite)
function MySprite:addListener(type, listener, data, target)
local store = self.myEventStore or {}
local target = target or self
if not store[type] then
store[type] = { listener = listener, data = data, target = target }
target:addEventListener(type, listener, data)
end
self.myEventStore = store
end
function MySprite:removeListener(type)
local store = self.myEventStore
local event = store[type]
if store and event then
event.target:removeEventListener(type, event.listener, event.data)
store[type] = nil
self.myEventStore = store
end
end
function MySprite:removeAllListeners()
local store = self.myEventStore
if store then
for type, event in pairs(store) do
event.target:removeEventListener(type, event.listener, event.data)
end
self.myEventStore = nil
end
end |
Use like so:
------- Make listener --------
-- Make sprite
local sprite = MySprite.new()
-- Listener function
local function onEvent(sprite, event)
print(event:getType())
end
-------- Example A ----------
-- Add a Listener
sprite:addListener("goat", onEvent, sprite)
-- Dispatch Event: Good!
sprite:dispatchEvent(Event.new("goat"))
-- Remove Listener
sprite:removeListener("goat")
-- Dispatch Event: Nothing!
sprite:dispatchEvent(Event.new("goat"))
-------- Example B ------------
-- Add a couple Listeners
sprite:addListener("beast", onEvent, sprite)
sprite:addListener("cheese", onEvent, sprite)
-- Dispatch those events: Good!
sprite:dispatchEvent(Event.new("beast"))
sprite:dispatchEvent(Event.new("cheese"))
-- Remove all Listeners
sprite:removeAllListeners()
-- Dispatch those events: Nothing!
sprite:dispatchEvent(Event.new("beast"))
sprite:dispatchEvent(Event.new("cheese"))
------ Example C ---------------
-- Make another sprite ( note: doesn't have to be MySprtie class )
local otherSprite = Sprite.new()
-- Add a Listener to target otherSprite
sprite:addListener("chicken", onEvent, sprite, otherSprite)
-- Dispatch event: good!
otherSprite:dispatchEvent(Event.new("chicken"))
-- Remove listener for other sprite
sprite:removeListener("chicken")
-- Dispatch event: Nothing!
otherSprite:dispatchEvent(Event.new("chicken")) |
Comments
Of course, I'm sure you know, it is not necessary to remove listeners before removing a sprite. Just remove/nil out the sprite and all its listeners die with it. (unless I'm completely wrong...)
https://github.com/gideros/gideros
https://www.youtube.com/c/JohnBlackburn1975
You're reply got me wondering, so I did some testing and here's what I came up with...
Yes, if a sprite doesn't exist, then events attached to it will die... but only upon garbage collection. From my experience, garbage collection by default doesn't happen too frequently in cases where memory consumption is low.
Now... a sprite that doesn't exist means that:
- It can't be a parent
- It can't be a child
- it can't be referenced in a living table or variable
Here's a sample of what would be required to remove an event listener without manually doing so:
BTW, Longford does not pass any events to sprites which have been removed from the display tree.
http://www.giderosmobile.com/forum/discussion/4469/introducing-longford-a-partly-gideros-compatible-open-source-game-engine
https://github.com/gideros/gideros
https://www.youtube.com/c/JohnBlackburn1975
Thanks for posting that link. That engine you have there has a lot of nice features. I need to check it out further.
Btw, can longford export to windows 8 app (windows store)?
https://github.com/gideros/gideros
https://www.youtube.com/c/JohnBlackburn1975