emit signals from modules

tom's Avatar

tom

29 May, 2010 12:33 AM

is there any approach to emit/respond to signals from modules (using robotlegs-utilities-Modular) instead of dispatching events via moduleDispatcher?
calling commands on the core (using signals-extensions-CommandSignal) would be great.

  1. 1 Posted by tom on 29 May, 2010 12:39 AM

    tom's Avatar

    sorry, wrong category. this is not a problem but a question.

  2. 2 Posted by Stray on 29 May, 2010 08:18 AM

    Stray's Avatar

    Hi Tom,

    the easiest way to do that would be to have a strongly typed object which contains the signals (let's call it a signal bus), a single instance of which is injected or passed into all of the modules.

    I would great multiple interfaces for the signal bus with getters for the different signals.

    Then Module A only needs to be coupled to an interface containing the signals that Modules B, C and D might dispatch that it's interested in, and not to the module directly, or even the whole signal bus (otherwise you could be looking at having to recompile multiple modules when you add a new signal).

    In the signal bus itself I'd probably add a locking mechanism so that the signal is actually relayed, something like:

    public function dispatchUsernameUpdatedSignal(username:String, senderModule:ModuleTypeA):void
    {
    _usernameUpdatedSignal.dispatch(username);

    }

    this would prevent module A from being able to send module B signals.

    Again you'd want to individually interface this to prevent the actual signal bus from being compiled into every module. The concrete signal bus class would only be required in the shell that instantiates it and passes or injects it to the other modules.

    This could be overkill - there's a whole bunch of less rigorous versions of this you could implement - just drop what you don't need.

    I've thought about this a lot, and in my case recompiling is something I'd like to avoid, so my modular app is happy with events. They do have their benefits in these situations.

    Hope that's helpful - far too early on a Saturday here so please excuse any rubbish thinking or typos!

    Stray

  3. Support Staff 3 Posted by Joel Hooks on 29 May, 2010 03:11 PM

    Joel Hooks's Avatar

    I'm really not a fan of the SignalBus concept. Now you get a (likely) bloated manager class that is responsible for and provides unfettered access to n+x Signals.

    I'd favor a CommonSignalLib that was shared by the modules. It would contain strongly typed Signal extensions that would be mapped for injection in the shell. The child Contexts would have them available for injection for use in your modules.

  4. 4 Posted by Stray on 29 May, 2010 04:53 PM

    Stray's Avatar

    Agreed, I think it's straying into controller territory, though of course if you started to feel there were too many in one class you could break it up - as long as you honoured the interfaces that would be a low-impact refactor.

    Say more about the strongly typed Signal / CommonSignalLib thing... do you mean injecting the signals into the dispatcher and the recipient? That definitely works but I'm still not sold on there being enough extra 'win' over Events, as you have to create a new class for each signal anyway.

    It would depend I guess on why you wanted Signals rather than Events. Synchronicity would be a strong case.

  5. Support Staff 5 Posted by Joel Hooks on 30 May, 2010 02:36 PM

    Joel Hooks's Avatar

    I don't have any issues with making lots of single-responsibility Signal classes. You can type their values explicitly and they are just generally strong OO where Events are not. The Signals can then be added to interfaces and injected as needed. Injecting them into the dispatcher and recipient clearly defines the relationships the classes have with one another and avoids the grossness of a controller. The only cost here, imo, is the extra classes. I really don't mind having finely grained class level responsibilities in my applications though.

    A modular Robolegs-Signals example is in the works!

  6. 6 Posted by tom on 30 May, 2010 02:43 PM

    tom's Avatar

    thank you for your comments. looking forward to learn from the example.

  7. 7 Posted by Stray on 30 May, 2010 05:08 PM

    Stray's Avatar

    I'm into extra classes too - I have a lot of strongly typed events, with strongly typed parameters - none of which are optional.

    I'm clearly missing something here - help me understand what it is...

    I'm using (and loving signals) where ClassA does

    instanceOfClassB.someSignal.add ...

    I can see that there's an additional level of checking, because - unlike events - you can't listen for a Signal which the class will never dispatch. Lovely. The interface of classB tells me that this signal is going to be available. Great! Particularly fab for view->mediator relationships.

    But where you're injecting SomeSignal into 2 modules, so that moduleA (rightly) has no knowledge of moduleB ... surely moduleA can still be listening on a signal that is of no relevance to moduleB (or any other module). Only the developer knows whether they have injected the signal somewhere where it might be dispatched.

    If you're not actually injecting the signal at both ends, and instead one module is relying on an interface on the other, then I think that's a possible disadvantage, because you have to actually make an instance of ModuleB available to ModuleA, and you're now compiling IModuleB (or a part of it) into ModuleA.

    And if you're injecting at both ends (into the dispatcher and the recipient) then there's no more guarantee than with an Event that you're listening for something 'real'.

    I get that in many situations Signals bring an advantage over Events, but I don't see how what you're describing is better than strongly typed Events - other than the synchronous nature, or the possibly (fractionally) shorter code.

    There's no compile time type checking of the Signal dispatch/handler relationship as far as I know, so in some ways you get better compile time checking with a multi-property strongly typed Event, where properties are strongly typed, because you only have to get one thing right: the event type. The dispatch/handler relationship can involve multiple properties, which have to be the correct type as well as in order - hence I'm favouring Signals for no-property or single-value dispatches, but events for where I need to pass more stuff. Otherwise I guess I could pass a TypedVO but that feels like no gain over events at all!

    Am I confused here? I must be missing something key! How are they stronger OO than (Strongly typed) Events if you're Injecting at both ends? Is it because the Signal is a property of each module, so it illustrates their intent to use it? That's what the redispatch stuff in the ModuleMediator does for me - so I'm a fan, but not sure Signals are a better way to achieve it.

    Persuade me... :)

  8. Support Staff 8 Posted by Joel Hooks on 31 May, 2010 04:57 PM

    Joel Hooks's Avatar

    I don't think ModuleA can ever really know (or care) that what it is listening for is "real" in the sense that it may or may not get dispatched from anywhere. In this regard events/signals are in parity. There is no way to force a contract across modules to be sure that moduleA is going to strictly receive a Signal from moduleB.

    Signals are "more" object-oriented in the sense that they are actual properties of the classes that listen to and dispatch from them. The very fact that they can be injected is to me innately more OO than events. I don't know that their use is more appropriate in the case of inter-module communication, but the post here is about how to do it. I just don't like the controller/bus approach to signals. It masks too much information. One of my favorite aspects of Signals is that by injecting them individually I am instantly clued in when my class is doing too much. Injecting a ton of Signals? Your class is probably breaking SRP. It is painfully obvious very quickly.

    Frankly, there are a lot of circumstances where I would favor Events over Signals simply because Events are native and understood by Flash developers. There is something to be said for basic conventions. So I'm not really trying to persuade you to use Signals over Events ;)

  9. 9 Posted by tom on 31 May, 2010 06:01 PM

    tom's Avatar

    this discussion is valuable to me. please keep it on :) thank you.

  10. 10 Posted by Stray on 31 May, 2010 06:37 PM

    Stray's Avatar

    Ah :)

    I'm very much with you on the SRP flag with Signals.

    I like to play the Sesame Street Favourite - "One of these things is not like the others... " and if I one of my Signals doesn't fit then it's time for a refactor.

    And I agree on the grossness of the bus - I don't like container classes for anything other than user-info static string constants (app error messages and the like).

    Bear with me, but here's my mental analogy of the differences:

    A signal bus is like an octopus, reaching into many modules with its tentacles, and permanently joined at the middle.

    Injected signals are like pieces of string - hopefully there's something else at the other end, but who knows. Depending on your implementation it can be beautifully woven or a total tangle. A big advantage is that if you tug the string, that's felt instantly at the other end.

    Events are like bees, visiting their listeners in no particular order, and largely in their own sweet time.

    As you say - pros and cons.

    I'm glad this is helpful Tom.

    Interesting stuff - especially as the module is kind of a meta version of general class-to-class implementations. One thing Joel and I very much agree on - more specific classes is a good thing (assuming they're named and packaged usefully). Whether those should be events or signals probably comes down to the specifics of each individual use-case. If you were truly looking for best practice you'd probably mix the two!

  11. 11 Posted by Maciek on 01 Jun, 2010 04:17 PM

    Maciek's Avatar

    I get that in many situations Signals bring an advantage over Events, but I don't see how what you're describing is better than strongly typed Events - other than the synchronous nature, or the possibly (fractionally) shorter code.

    This is kind of a tangent, but I don't think signals are any more synchronous than events. E.g., if you add something like

    addEventListener('foo', function(e:Event):void { trace('handling', e.type) });
    trace('before dispatching foo');
    dispatch(new Event('foo'));
    trace('after dispatching foo');
    

    to an EventDispatcher, you'll see

    before dispatching foo
    handling foo
    after dispatching foo
    

    . Things get trickier on the display list, but I imagine the same thing would happen with signals if they could be used in place of events there. Or is there a particular case you're thinking of that I'm missing?

  12. 12 Posted by derekdon on 08 Jun, 2010 01:45 PM

    derekdon's Avatar

    Interesting reading... I was just about to post a question on Signals usage in a modular application. I like Signals but agree with Joel's comment in relation to favouring Events over Signals in certain circumstances. I fear Signals may cause problems within large teams contributing to enterprise flash/flex applications. Maybe it's to early to adopt Signals in these instances?

  13. 13 Posted by RayReadyRay on 23 Aug, 2010 10:38 PM

    RayReadyRay's Avatar

    I forked Joels Modular Doodad example and added a ModularSignalMap.

    So here is a working example of modules communicating via Signals-
    http://github.com/RayReadyRay/robotlegs-examples-ModularDoodads

  14. 14 Posted by jonasnys on 24 Aug, 2010 05:19 AM

    jonasnys's Avatar

    @RayReadyRay: The main application class in your modular example seems to have the wrong name. I'ts referred to as "ModularSignalDoodads" in context and mediator, but actually has Joel's original name "ModularDoodads". It has to be renamed for the example to run. Thanks for sharing anyway!

  15. 15 Posted by RayReadyRay on 24 Aug, 2010 07:54 PM

    RayReadyRay's Avatar

    @jonasnys Thanks! Fixed.

  16. 16 Posted by Nikos on 28 Jan, 2011 01:35 PM

    Nikos 's Avatar

    So is there an official ModularSignal approach or is the events way the official way to do it?

  17. 17 Posted by Maciek on 28 Jan, 2011 05:15 PM

    Maciek's Avatar

    Nikos,

    I don't know about "official", but I wrote an app using modules and signals. I prototyped it using this example app. Let me know if you have any feedback.

  18. 18 Posted by Nikos on 01 Feb, 2011 11:27 PM

    Nikos 's Avatar

    As far as I know we can get signals to modules from other modules via adding callbacks to child injectors injected signals(contained in other objects,eg models). I guess to emit a signal from a module to call a command elsewhere in another context we just need to reflect upwards from a shared signalbus :)

  19. Stray closed this discussion on 11 Feb, 2011 11:18 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac