Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
Custom Broadcast Events — Gideros Forum

Custom Broadcast Events

moopfmoopf Guru
edited October 2012 in General questions
I've seen this mentioned before and found a thread from last December about it (here: http://www.giderosmobile.com/forum/discussion/287/suggestion-for-custom-events#Item_1 ) but are custom broadcast events possible yet? By that I mean an event that goes to all objects that have a listener for it, rather than just a specific object?

I think I've got a way around it by getting my sub-objects to register a listener on the main parent that receives the event. I've done this by something like the following in the constructor for my objects:
<pre>
function Blah:init()
	function stageAdded(event)
		gamespace:addEventListener("game_paused", pauseGame) 
		gamespace:addEventListener("game_resumed", resumeGame) 
	end
 
	function stageRemoved(event)
		gamespace:removeEventListener("game_paused", pauseGame)
		gamespace:removeEventListener("game_resumed", resumeGame)
	end
 
	self:addEventListener(Event.ADDED_TO_STAGE, stageAdded) 
	self:addEventListener(Event.REMOVED_FROM_STAGE, stageRemoved) 
end
This appears to work (although I haven't tested it fully) but it's a bit of a hack really because gamespace (in this example) is global.

Comments

  • Hi @moopf,

    I don't have much time to answer but there were a couple of suggestions that people made on that thread :
    Broadcast messages for custom events : how to?.

    That's the result I got : Broadcast messages - result

    I hope you will find some things that will help you there.
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • Hi @Mells, thank for that. I did see your thread as well about messages but I'm looking for something where the receivers are more arbitrary, and trying to avoid lots of loops to achieve it.

    I think there's a problem with my solution though as I'm getting periodic crashes caused by the event dispatcher dispatching an event to an object that's no longer a child. Going to debug that this morning to see what's going on. As I'm removing all children from the scene before destroying them, first place to check is that Event.REMOVED_FROM_STAGE is actually triggering 100% of the time.
  • atilimatilim Maintainer
    Accepted Answer
    Using weak tables can be another option:
    allEventDispatchers = setmetatable({}, {__mode = "v"})
     
    function broadcastEvent(event)
    	for k in pairs(allEventDispatchers) do
    		k:dispatchEvent(event)
    	end
    end
     
    -- usage example
     
    MySprite = Core.class(Sprite)
     
    function MySprite:init()
    	allEventDispatchers[self] = true
    	-- init continues from here
    	self:addEventListener("foo", function() print("foo") end)
    end
     
    MySprite = MySprite.new()
     
    broadcastEvent(Event.new("foo"))

    Likes: Mells, moopf

    +1 -1 (+2 / -0 )Share on Facebook
  • Hi @atilim, that's a really good idea actually. I think I'll take your idea here and change my code this morning as this should automatically resolve calls to objects that no longer exist which is apparently what I'm currently getting with my quick and dirty solution at the moment :)
  • MellsMells Guru
    edited October 2012
    @atilim
    I learned something new today.

    For those who want to have a better understanding of the solution provided by atilim :
    Weak Tables Tutorial - at lua-users.org
    twitter@TheWindApps Artful applications : The Wind Forest. #art #japan #apps
  • @Mells Weak tables are very useful, I just hadn't thought of using it in this situation but it's a good solution to the problem.
  • atilimatilim Maintainer
    edited October 2012
    Also after reading your post, I've decided to test Event.ADDED_TO_STAGE and Event.REMOVED_FROM_STAGE again and couldn't catch any bugs. For the people who are interested, here is my test code:
    local spritesOnStage = {}
     
    MySprite = Core.class(Sprite)
     
    function MySprite:init()
    	self:addEventListener(Event.ADDED_TO_STAGE, self.onAddedToStage, self)
    	self:addEventListener(Event.REMOVED_FROM_STAGE, self.onRemovedFromStage, self)
    end
     
    function MySprite:onAddedToStage()
    	if spritesOnStage[self] == true then
    		print("error! onAddedToStage")
    	end
    	spritesOnStage[self] = true
    end
     
    function MySprite:onRemovedFromStage()
    	if spritesOnStage[self] == nil then
    		print("error! onRemovedFromStage")
    	end
    	spritesOnStage[self] = nil
    end
     
    local function populate(sprite, sprites)
    	for i=1,sprite:getNumChildren() do
    		local child = sprite:getChildAt(i)
    		sprites[child] = true
    		populate(child, sprites)
    	end
    	return sprites
    end
     
    local function check()
    	local spritesOnStage2 = populate(stage, {})
     
    	for k,v in pairs(spritesOnStage) do
    		if spritesOnStage2[k] == nil then
    			print("error! check1")
    		end
    	end
     
    	for k,v in pairs(spritesOnStage2) do
    		if spritesOnStage[k] == nil then
    			print("error! check2")
    		end
    	end
    end
     
    local sprites = {}
    for i=1,20 do
    	sprites[i] = MySprite.new()
    	stage:addChild(sprites[i])
    end
    sprites[#sprites + 1] = stage
     
    local n = 0
     
    local function onEnterFrame()
    	if math.random(1, 4) == 1 then
    		local sprite = sprites[math.random(1, #sprites - 1)]
    		sprite:removeFromParent()
    	else
    		local sprite1 = sprites[math.random(1, #sprites)]       
    		local sprite2 = sprites[math.random(1, #sprites - 1)]       
    		pcall(function() sprite1:addChild(sprite2) end)
    	end
    	check()
    	n = n + 1
    	if n % 100 == 0 then
    		print("tested "..n.." tree mutations...")
    	end
    end
     
    stage:addEventListener(Event.ENTER_FRAME, onEnterFrame)

    Likes: moopf

    +1 -1 (+1 / -0 )Share on Facebook
  • Hi @atilim, yes it was my own stupidity causing the crash. Took me a while to track down what was going on but got there in the end (it was unrelated to by ADDED_TO_STAGE, REMOVED_FROM_STAGE listeners but I've changed that implementation to yours which is definitely better). It was all to do with registering on the wrong object rather than self.
  • atilimatilim Maintainer
    @moopf, when somebody mentions a possibility of a bug, I can't wait to test it :)
  • haha, yes I know that feeling all too well @atilim - that's why I won't call something a bug here unless I'm pretty sure it is. I hate investigating something that isn't actually broken even though sometimes it can be a useful exercise.

    Likes: atilim

    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.