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

suggestion for Custom Events

alexzhengalexzheng Guru
edited December 2011 in Roadmap
Event is a great pattern in the sdk.
as the doc depicted:
ClassA = gideros.class(EventDispatcher)
ClassB = gideros.class(EventDispatcher)

function ClassA:funcA(event)
print("funcA", self, event:getType(), event:getTarget())
end

local a = ClassA.new()
local b = ClassB.new()

b:addEventListener("myevent", a.funcA, a) -- when b dispatches an "myevent" event,
-- a.funcA will be called with 'a'
-- as first parameter

b:dispatchEvent(Event.new("myevent")) -- will print "funcA"

However,when it comes to make some common component,such as a score bar,I think broadcast event is more useful.
For example,when some object dispatch an event "addScore" with a parameter 10 without care about who will handle it,
just call
event = Event.new("addScore")
event.bonus = 10
b:dispatchEvent(event)


and on the receive side

self:addEventListener("addScore", self.funcA, self)

function ClassA:funcA(event)
print("funcA", self, event:getType(), event:getTarget(), event.bonus)
end


So ClassA and ClassB are indepent,without reference each other,just focus on the event.




Likes: plamen

+1 -1 (+1 / -0 )Share on Facebook

Comments

  • atilimatilim Maintainer
    great idea. I've added this to the todo list.
  • I think i am a bit late about this but is it already implemented or what?
  • This is kind of an old thread, but it appears that broadcast events may still be on the to do list. It seems like I have to dispatch my events directly to the object I want to handle the event. Here's how I set up my HUD to receive events saying some energy was created:
    gHud.energyConsumer = function(event)
    	print("hud.energyConsumer event captured");
    end
    gHud:addEventListener(Constants.ENERGY_GENERATED, gHud.energyConsumer);
    I would hope that I could get my HUD to respond by doing something like this (where self.owner is a sprite, so it implements dispatchEvent()):
    local event = Event.new(Constants.ENERGY_GENERATED);
    event.energy = self.owner.body:getAngularVelocity();
    self.owner:dispatchEvent(event);
    But the event doesn't get handled.

    If I do this, dispatching the event from gHud, it works:
    gHud:dispatchEvent(event);
    But what does that buy me? Why don't I just call gHud directly?
    gHud:energyConsumer()
    I don't see what the event is buying me if it isn't a general broadcast, like alexzheng suggests.

    Am I missing something?
  • amaximovamaximov Member
    edited August 2013
    @plamen if you call a function explicitly it will obviously be executed. However, dispatching an event can only guarantee the function will be called if a listener for the even has been registered. In essence the difference is do you want to call functions explicitly and include on/off if statements, or add remove event listeners for an event type.

    Also note that you can register multiple functions for a single event and remove them individually giving you a greater degree of control over what gets executed during a particular event. (Maybe you want to register 2 listeners for a single event but at some point remove one of them. Might be a hastle to do with if statements.)

    Also I have a class for global broadcasting of events that has the method Broadcaster.lua which I use. You have to add a listener object via
    BroadcasterInstance:registerListener()
    and unregister via
    BroadcasterInstance:unregisterListener()
    You can then broadcast events to all registered objects via
    BroadcasterInstance:dispatchGlobalEvent(event)
    Excuse the function name since the event isn't really "Global".

    The class is pretty simple and holds objects in weak tables (don't add to memory reference count of object) and can be extend to maybe add "channels" so that events can be sent to certain groups of objects. Attached is the class.
    lua
    lua
    Broadcaster.lua
    911B
  • Thanks, @amaximov. Good points about the usefulness of events, even though the Gideros implementation does seem a little too specific about who is participating, at least when compared with the way it's done in Cocoa, etc.

    Thank you so much for sharing your broadcaster class. It looks like a clean pub/sub model. My next step was going to be to write something similar, so this will save some typing, testing, and head scratching.
  • @amaximov: Your class worked a treat! Thanks so much for sharing the code!

    I'm pretty new to both Lua and Gideros, you just saved me a lot of heartache. Now to get back to game logic...
  • amaximovamaximov Member
    edited August 2013
    Here is a lightly improved version.

    Changes:

    1)Removed self.events table which was a leftover from a previous iteration
    2)Table keys are now weak and objects can only be registered once (Previous version allowed mistakenly adding same object multiple times)
    3)Performance improvement when adding lots of objects(No longer cycles through all numeric indeces to find a free one)
    4) Can register virtually unlimited amounts of objects

    Note: The class inherits from EventDispatcher but doesn't actually use any of its methods or functionality directly on itself. It's up to you if you want it to be a bare bones class or inherit if you want to add listeners directly to it.
    lua
    lua
    Broadcaster.lua
    817B

    Likes: bali001

    +1 -1 (+1 / -0 )Share on Facebook
  • Very nice, thanks.
Sign In or Register to comment.