tag:robotlegs.tenderapp.com,2009-10-18:/discussions/robotlegs-2/68-modular-applicationRobotlegs: Discussion 2018-10-18T16:35:42Ztag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-22T05:11:21Z2012-09-22T05:11:21ZModular Application<div><p>Hello,</p>
<p>I am trying to create a Robotlegs 2 modular application... but
having some difficulties..<br>
I can't figure out the right sequence of things... and I can't find
an examples online.<br>
was wondering if you can help me with a small example.</p>
<p>Thanks,</p></div>mbarjawitag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-23T09:52:19Z2012-09-23T09:52:19ZModular Application<div><p>Hello,</p>
<p>A few months ago I put a project (AIR) on github. I was just
experimenting with modules and popups in rl2.</p>
<p>It’s not a demo!!!!!</p>
<p>I wanted to provide documentation for the project, but I
haven’t got a chance to finish it yet.<br>
You can take a look at <a href=
"https://github.com/Ondina/robotlegs2-sketches/tree/fac63ff90f99b2dfd3de2e8e1950eefba7ecb0fd/robotlegs-two-modules/src/yourdomain/modules/loginModule">
LoginModule<br></a>, which may be easier to understand than the
ChatModule.</p>
<p><strong>Use it at your own risk</strong> ;)</p>
<blockquote>
<p>I am trying to create a Robotlegs 2 modular application... but
having some difficulties.. I can't figure out the right sequence of
things.</p>
</blockquote>
<p>Can you be more specific?</p>
<p>Cheers,<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-24T20:02:36Z2012-09-24T20:02:36ZModular Application<div><p>Thank you Ondina for your help.</p>
<p>I am trying to create a simple module, load it in my Main
Application, and then be able to exchange data and events between
both sides. In future, I will have more than one module in my main
application, and I would want them to interact with each other as
well.</p>
<p>In your project I can see that you are utilizing the
<code>ScopedEventDispatcherExtension</code>. It seems that in each
module I need to extend this extension and use the scope names that
this module can listen and dispatch to. There is no
<strong>readme.md</strong> file for this extension so I am not
really 100% sure how we use it.</p>
<p>I am not sure how to route the events to a certain scope. For
example, if I am in the <code>global</code> scope and want to send
an event to the <code>channelOne</code> scope... or the other way
around.</p>
<p>Looking further into the framework, I can see the
<code>ModularityExtension</code> which requires the
<code>ContextViewExtension</code>... but again, other than adding
them to the context.. I have no idea if they are the ones that I
need, or even how to use them.</p>
<p>Thanks for your help,</p></div>mbarjawitag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-25T07:54:57Z2012-09-25T07:57:00ZModular Application<div><p>From what I've gathered by looking at the code, if you use
ModularityExtension, when you add your module to your application
it will actually put reference to parent injector in your
module...</p>
<p><em><em>childContext.injector.parentInjector =</em>
injector;</em></p>
<p>...where child context is your module.</p>
<p>I didn't try it out ye, just sharing my observations. I'm at the
point where I'll need to start working with modules too, so I'm
also interested in the subject.</p>
<p>Regards,<br>
Vjeko</p></div>Vj3k0tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-25T10:35:06Z2012-09-25T10:35:06ZModular Application<div><p>Hi guys,</p>
<p>ModularityExtension.as<br>
“This extension allows a context to inherit dependencies from
a parent context, and/or expose its dependencies to child
contexts.”<br>
and the<br>
<a href=
"https://github.com/robotlegs/robotlegs-framework/blob/d37fc9f6f11bd0c2d6ef2f66ef6fdaf258bd28c1/src/robotlegs/bender/extensions/modularity/readme.md">
readme</a> on github</p>
<p>For a more detailed explanation about ModularityExtension and
ScopedEventDispatcherExtension please look at Shaun’s
answers:</p>
<p><a href=
"https://groups.google.com/forum/?fromgroups=#!topic/robotlegs/jj9Y73WDXPg">
https://groups.google.com/forum/?fromgroups=#!topic/robotlegs/jj9Y7...</a></p>
<blockquote>
<p>It seems that in each module I need to extend this extension and
use the scope names that this module can listen and dispatch
to.</p>
</blockquote>
<p>I was experimenting with different settings in the different
contexts, and I forgot to comment out what’s not needed.</p>
<p>I used the MVCSBundle, but the following extensions would have
been enough to configure LoginModule:</p>
<pre>
<code>childContext.extend(ContextViewExtension);
childContext.extend(StageSyncExtension);
childContext.extend(
EventCommandMapExtension,
EventDispatcherExtension,
CommandMapExtension,
MediatorMapExtension,
LocalEventMapExtension);
childContext.extend(ModularityExtension);</code>
</pre>
<p>If the ScopedEventDispatcherExtension is installed like this in
the parent context</p>
<pre>
<code>context.extend(ScopedEventDispatcherExtension);</code>
</pre>
<p>then, LoginModule’s context will inherit parent’s
dependencies and have access to the shared dispatcher. All you have
to do is to use named injections for the shared dispatcher with the
default ‘global’ to allow the communication between
shell and module.</p>
<pre>
<code>[Inject (name="global")]
public var defaultDispatcher:IEventDispatcher;</code>
</pre>
<p>ScopedEventDispatcherExtension.as</p>
<pre>
<code>public function ScopedEventDispatcherExtension(... names)
{
_names=(names.length > 0) ? names : ["global"];
}</code>
</pre>
<p>If you wanted a custom name for the named injection, then in the
parent context you’d do this:</p>
<pre>
<code>context.extend(new ScopedEventDispatcherExtension("login"));</code>
</pre>
<p>and in LoginModule and in the shell’s classes that need to
share the same dispatcher:</p>
<pre>
<code>[Inject (name="login")]
public var loginDispatcher:IEventDispatcher;</code>
</pre>
<blockquote>
<p>I am not sure how to route the events to a certain scope. For
example, if I am in the global scope and want to send an event to
the channelOne scope... or the other way around.</p>
</blockquote>
<p>ChatModule is just an experiment. It’s a bit hard to
understand without explanations.</p>
<p>In fact, it’s quite easy to define the scopes.</p>
<p>Shell< == >Module communication<br>
If you look at LoginModule:</p>
<p>LoginLocallyService (Module)</p>
<pre>
<code>[Inject(name="global")]
public var defaultDispatcher:IEventDispatcher;
defaultDispatcher.dispatchEvent(new AlertEvent(AlertEvent.ERROR_ALERT, faultMessage));</code>
</pre>
<p>Here, you dispatch the event on the shared dispatcher.</p>
<p>AlertMediator (Shell)</p>
<pre>
<code>[Inject(name="global")]
public var defaultDispatcher:IEventDispatcher;
eventMap.mapListener(defaultDispatcher, AlertEvent.ERROR_ALERT, onErrorAlert, AlertEvent);</code>
</pre>
<p>Here, you map the listener as defaultDispatcher (the
„global“, shared dispatcher between shell and
module).</p>
<p>Module < == > Module communication<br>
If you had a parent’s context configuration like this:</p>
<pre>
<code>context.extend(new ScopedEventDispatcherExtension("channelOne"));</code>
</pre>
<p>and 2 Modules inheriting from the same parent, then all you need
is to inject the shared dispatcher into both modules (where you
need it), and they will communicate through that shared
dispatcher.</p>
<pre>
<code>[Inject(name="channelOne")]
public var someSharedDispatcher:IEventDispatcher;</code>
</pre>
<p>map listeners like this:</p>
<pre>
<code>eventMap.mapListener(someSharedDispatcher, InterModularEvent.MODULE_TO_MODULE, onIntermodularMessage, InterModularEvent);</code>
</pre>
<p>and dispatch the events like this:</p>
<pre>
<code>private function onModuleToModule(event:InterModularEvent):void
{
someSharedDispatcher.dispatchEvent(event);
}</code>
</pre>
<p>Hopefully my explanations made sense :)</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-25T19:19:11Z2012-09-25T19:19:11ZModular Application<div><p>Thanks again Ondina for your detailed explanation.</p>
<p>After deeply examining your project I was able to come to the
same conclusions that you explained in your post. Your post helped
me further clarify how things work.</p>
<p>I have created a small project (link <a href=
"https://github.com/MBarjawi/robotlegs2-ModularCommunications">here</a>)
that has two modules and a shell, it routes messages to: globally
to everyone, to modules only, to module 1 only, and to module 2
only. Could you please take a quick look at the project and let me
know if I am doing it the right way (with minimal code possible)...
or is there code that can (and maybe should) be deleted?</p>
<p>I made the following test, in the module 1 config file, I
initially have the context defined this way:</p>
<pre>
<code>context = new Context()
.extend( MVCSBundle )
.extend( ContextViewExtension )
.extend( ModularityExtension )
.extend( new ScopedEventDispatcherExtension( "global", "moduleOnly", "toModule1" ) )
.configure( _contextView );</code>
</pre>
<p>However, when I remove the middle three lines (extend
<code>ContextViewExtension</code>,
<code>ModularityExtension</code>, and
<code>ScopedEventDispatcherExtension</code>) everything still works
fine... so I thought that was strange. Then I thought maybe because
the <code>MVCSBundle</code> has the
<code>ContextViewExtension</code> and the
<code>ModularityExtension</code> installed in it... however it
doesn't have <code>ScopedEventDispatcherExtension</code>. Do you
have any idea why it still works without having the
<code>ScopedEventDispatcherExtension</code> defined in the child
contexts?</p>
<p>My guess is that since everything that is injected in the main
(a.k.a. shell) context is available in the children contexts
(probably because of the <code>ModularityExtension</code> but not
sure why)... so does the named <code>IEventDispatcher</code>s that
were injected in the main context.</p>
<p>The other thing that I am trying to understand here is the
<code>ModularityExtension</code>. I understand that (this extension
allows a context to inherit dependencies from a parent context,
and/or expose its dependencies to child contexts)... however what
does this mean? what are those dependencies?? is this why in my
child context I can see injections that were defined in the main
context? if so, then why I can't do it the other way? If I define
an injection in a module, I cannot get access to this injection in
the main context or in the other sibling module.</p>
<p>Thanks a lot for your efforts,</p></div>mbarjawitag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-26T06:20:59Z2012-09-26T08:34:48ZModular Application<div><p>If you are using <code>MVCSBundle</code> you don't have to
explicitly add <code>ContextViewExtension</code> and
<code>ModularityExtension</code> since they are included in it.</p>
<p>Are you positive that it works without
<code>ScopedEventDispatcherExtension</code>? Because I see that you
are using named injection in your mediators, so I'm wondering how
it would work if no injection is mapped (I think SWFSuspender
should throw you an error about missing injection).</p>
<p>As for <code>ModulartiyExtension</code>... If you take a peek at
the class itself you can see that there are 2 Booleans:
<em>inherit</em> and <em>expose</em>. What <em>inherit</em> will do
is, it will basically register its existence as module (to any
parent that may be listening), and <em>expose</em> will setup
listeners to accept any module.<br>
So when some module is added to its context it will run:<br>
<code>childContext.injector.parentInjector = injector;</code></p>
<p>And from what I gathered, this will say that all injections
defined in context of a parent will be also available in module.
But not the other way around.</p>
<p>So in your case you could share event dispatcher from parent
context in both module and parent.</p>
<p>Regards,<br>
Vjeko</p></div>Vj3k0tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-26T08:36:56Z2012-09-26T08:36:56ZModular Application<div><p>@Vjeko Your posts keep landing in the spam folder for some
reason. Good thing I’ve developed the habit of looking into
this folder periodically, to see if there are ‚false
positives’ ;)</p>
<blockquote>
<p>Are you positive that it works without
<code>ScopedEventDispatcherExtension</code>? Because I see that you
are using named injection in your mediators, so I'm wondering how
it would work if no injection is mapped (I think SWFSuspender
should throw you an error about missing injection).</p>
</blockquote>
<p>It works.<br>
I think that’s because this:</p>
<p>In parent’s context<br>
context.extend(new
ScopedEventDispatcherExtension("hello“));</p>
<p>is the same as this:</p>
<p>In parent’s context:<br>
injector.map(IEventDispatcher, "hello").toValue(new
EventDispatcher());</p>
<p>In a Module’s class:<br>
[Inject(name="hello")]<br>
public var helloDispatcher:IEventDispatcher;</p>
<p>@mbarjawi I am glad to be helping you!<br>
I’ll take a look at your code and I’ll report back
later today with answers or comments.</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-26T08:49:49Z2012-09-26T08:49:50ZModular Application<div><p><strong>@Ondina</strong></p>
<p>Aha I overlooked module configs, but only saw
RL2ModularCommunicationsConfig. That's why I didn't see how it
works.</p>
<p><strong>@mbarjawi</strong></p>
<p>Anyhow, yea, in <code>RL2ModularCommunicationsConfig</code> you
are defining mapping:<br>
<code>.extend( new ScopedEventDispatcherExtension( "global",
"moduleOnly", "toModule1", "toModule2" ) )</code> This will now be
mapped to your context injector. And with
<code>ModularityExtension</code> you make this mapping available to
your modules as well. This is why it works.</p>
<p>Regards,<br>
Vjeko</p></div>Vj3k0tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-26T12:00:43Z2012-09-26T12:00:43ZModular Application<div><p>Just to recap what was already said in the course of our
discussion:</p>
<p>=The main app(RL2ModularCommunications) loads 2 Modules:
ModuleView1<br>
ModuleView2</p>
<p>RL2ModularCommunicationsConfig:<br>
context.extend(new ScopedEventDispatcherExtension( "global",
"moduleOnly", "toModule1", "toModule2" ) )</p>
<p>The 2 modules inherit the dispatchers installed in main
RL2ModularCommunicationsConfig, so there is no need to extend<br>
ScopedEventDispatcherExtension in ModuleView1Config<br>
and ModuleView2Config.</p>
<p>=Let’s say ModuleView1 would load another module,
SubModuleOneView.</p>
<p>SubModuleOneView would inherit ModuleView1’s dependencies
and therefore it could communicate with the shell and other
modules.</p>
<p>If you wanted ModuleView1 and SubModuleOneView to have their
„private“ channel, you’d do this in
ModuleView1Config:</p>
<p>context.extend( new
ScopedEventDispatcherExtension("subModuleChannel"))</p>
<p>and inject the shared dispatcher into both mediators,
ModuleView1Mediator and SubModuleOneMediator:</p>
<p>[Inject(name="subModuleChannel")] public var
subModuleChannelDispatcher:IEventDispatcher;</p>
<p>You don’t need to extend( new
ScopedEventDispatcherExtension( "subModuleChannel")) in
SubModuleConfig, because it will inherit the dispatcher from
ModuleView1 in addition to all the dispatchers defined in the main
context.</p>
<p>=If you had the following in RL2ModularCommunicationsConfig</p>
<p>.extend( new ScopedEventDispatcherExtension("global",
"moduleOnly", "toModule1", "toModule2", "subModuleChannel") )</p>
<p>then all of the child contexts down the tree would inherit the
dispatchers, and you could inject them just into the classes which
need them. Say, if you don’t inject</p>
<p>[Inject(name="global")] public var
globalDispatcher:IEventDispatcher;</p>
<p>into SubModuleOneMediator, then it won’t receive any
messages dispatched on that dispatcher, and, of course, it
won’t be able to dispatch any events on it.</p>
<p>=MVCSBundle As Vjeko said, and as I mentioned in a previous
post, you either use the MVCSBundle, or your install only the
extensions that you need in your project, or MVCSBundle plus other
extensions that are not included in the bundle. You can, in fact,
create your custom MVCSBundle, extending only what you need for a
certain project.</p>
<p>So, if you have this in RL2ModularCommunicationsConfig</p>
<p>context = new Context()<br>
.extend( MVCSBundle ) .extend( new ScopedEventDispatcherExtension(
"global", "moduleOnly", "toModule1", "toModule2") ) .configure(
_contextView );</p>
<p>then ModuleView1Config and ModuleView2Config would look like
this:</p>
<p>context = new Context()<br>
.extend( MVCSBundle) .configure( _contextView );</p>
<p>@mbarjawi your example looks fine! I know that your example was
intended just to provide a common base for our discussion, but if
you have time to refine it, it could become a demo :)<br>
Just a suggestion: I wouldn’t listen for MouseEvent.CLICK in
the mediators. Instead I would dispatch a custom event from View
(can be the same TextMessageEvent) with the message and selected
dispatcher in the payload. Also, instead of the switch statement,
I’d use a dictionary to map the dispatchers’ names to
the shared dispatchers.</p>
<p>Hehe, I know, I should improve my example too, but I’m
afraid it won’t happen any time soon.</p>
<p>I guess Vjeko has already answered your question regarding the
ModulartiyExtension, right?</p>
<p>If you want to know more about parent and child injectors, you
can check out the links I provided in this thread:<br>
<a href=
"http://knowledge.robotlegs.org/discussions/questions/983-sharing-models-between-modules#comment_17776450">
http://knowledge.robotlegs.org/discussions/questions/983-sharing-mo...</a></p>
<p>Sorry, if you knew all this already :)</p>
<p>Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-26T21:02:36Z2012-09-27T10:28:34ZModular Application<div><p>Thank you @Vjeko and @Ondina for your help and explanation. I
better understand how things work now.</p>
<p>I have also refined my example: <a href=
"https://github.com/MBarjawi/robotlegs2-ModularCommunications">RL2ModularCommunications</a>,
so please take a look and let me know if you there is something
else that I should modify before adding it as a demo. It might be
helpful for someone out there looking for the same help as I
did.</p>
<p>About ModularityExtension, I think I understand it better now.
If my understanding is correct, then the shell should actually
extend</p>
<pre>
<code>.extend( new ModularityExtension( false, true ) );</code>
</pre>
<p>because the Shell doesn't inherit anything from anybody, and it
needs to expose itself to the modules.</p>
<p>In addition, the modules should extend:</p>
<pre>
<code> .extend( new ModularityExtension( true, false ) );</code>
</pre>
<p>This is true for my example, right?... if someone else has a
different scenario of course these extensions should be defined
differently. However, I just wrote those two statements to check if
my understanding of ModularityExtension is correct.</p>
<p>I think the comments in the ModularityExtension class itself are
not clear in this regard. If you read the comments on the
constructor, it says:</p>
<pre>
<code> /**
* Modularity
*
* @param inherit Should this context inherit dependencies?
* @param expose Should this context expose its dependencies?
*/</code>
</pre>
<p>Which I think was confusing because I thought for a while that
if I set this to (true, true) then it will become a two way
communication.. meaning that my module would be able to see the
Shell dependencies AND my Shell would be able to see my module's
dependencies (since they are exposed).</p>
<p>However, now that I read it again, and take a look at the
comment on the class itself, it clearly says:</p>
<pre>
<code> and/or expose its dependencies to child contexts</code>
</pre>
<p>Just a final check of my understanding, there is nothing
currently in the framework that allows the child context to share
its dependencies with parent context.. right? and from the links
posted above, @Stray talks about this as not being logical as the
Module should be a separate entity or something like that,
right?</p></div>mbarjawitag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-27T13:34:47Z2012-11-08T13:36:52ZModular Application<div><p>Hi,</p>
<p><strong>RL2ModularCommunications</strong></p>
<p>I took a look at your modified code, but I haven’t got the
time to try it out yet.<br>
Anyway, communicationChannels dictionary looks good!!</p>
<p>One thing, though:</p>
<p>You’re aggregating an instance of the EventDispatcher
class in your mediators:</p>
<pre>
<code>EventDispatcher( dispatchChannel[ "global" ] ).addEventListener( TextMessageEvent.TEXT_MESSAGE, messageReceived );</code>
</pre>
<p>In case you wanted to unload the module and you wanted it to get
gc-ed (garbage collected), you’d have to override
mediator’s destroy() and unmap those listeners manually.<br>
Listeners mapped through the eventMap get unmapped automatically
when the mediator gets removed (see rl’s Mediator.as
destroy()), which is very convenient, in my opinion.</p>
<p>So, if you’ll have to deal with gc (maybe in another
project) you could use mappings like these:</p>
<pre>
<code>eventMap.mapListener(dispatchChannel[ "global" ] , TextMessageEvent.TEXT_MESSAGE, messageReceived );
eventMap.mapListener(dispatchChannel[ "moduleOnly" ] , TextMessageEvent.TEXT_MESSAGE, messageReceived );
eventMap.mapListener(dispatchChannel[ "toModule1" ] , TextMessageEvent.TEXT_MESSAGE, messageReceived );</code>
</pre>
<p>Or</p>
<pre>
<code>for(var dispatcherName:String in dispatchChannel)
{
eventMap.mapListener(dispatchChannel[ dispatcherName ] , TextMessageEvent.TEXT_MESSAGE, messageReceived );
}</code>
</pre>
<p>and dispatch like this:</p>
<pre>
<code>dispatchChannel[ event.channel ].dispatchEvent( event );</code>
</pre>
<p>And the listeners will be removed automatically when the module
gets unloaded.</p>
<p>It’s important to dereference any objects that could keep
the Mediator and/or the View alive. Removing event listeners is
part of that cleaning up process.</p>
<p><strong>ModularityExtension</strong></p>
<p>Yes, you’re right about the ModularityExtension’s
booleans.</p>
<p>If Main display object loads Module1, which loads Submodule1,
then the settings would look like this:</p>
<p>=MainConfig</p>
<p>context.extend( new ScopedEventDispatcherExtension( "global",
"moduleOnly", "toModule1", "toModule2" ) )<br>
context.extend(new ModularityExtension(false, true));</p>
<p>=ModuleView1Config</p>
<p>context.extend( new ScopedEventDispatcherExtension(
"subModuleChannel");<br>
context.extend(new ModularityExtension(true, true));</p>
<p>=SubModule1Config</p>
<p>context.extend(new ModularityExtension(true, false));</p>
<p>Module1 will inherit Main’s dispatchers.<br>
SubModule1Config will inherit only the dispatcher installed in
Module1.</p>
<p>Main and Module1 have to set expose to true, but since
SubModule1Config has no children, it doesn’t need to expose
its dependencies.<br>
If you’d set expose to false in Main and Module1, the
injector would complain about missing a mapping or something. Same
would happen if Module1‘s and SubModule1’s inherit
param would be set to false.</p>
<p>I haven’t tried it out yet, so hopefully I’m not
wrong about it.</p>
<blockquote>
<p>Which I think was confusing because I thought for a while that
if I set this to (true, true) then it will become a two way
communication.. meaning that my module would be able to see the
Shell dependencies AND my Shell would be able to see my module's
dependencies (since they are exposed).</p>
</blockquote>
<p>Right, the dependencies are exposed only to the children.<br>
As in real life, parents shouldn’t know what their (adult)
children are doing in their own houses ;)<br>
If the children want to let their parents know about something
happening in their lives, they can give them a call (dispatch an
event). The “inherited” telephone(shared dispatcher)
should be the two-way communication channel between parents and
children. It’s not the best analogy, but you’ll get the
point.</p>
<p>And yes, a module should be a separate entity, encapsulated,
reusable in a variety of combinations, separately testable…
But, you know all this, so what am I talking about? :)<br>
Maybe your question is “If children are allowed to hide their
internal working, why are parents forced to expose
theirs?”</p>
<p>Oh, sorry, I’m running out of time. I’ll continue
later today or tomorrow, if you need more clarification (from me)
on any of this or if you have any other questions. But, actually,
the discussion is open to anyone who wants to share their rl2
opinions/experience.</p>
<p>Cheers,<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-28T07:28:40Z2012-09-28T07:28:40ZModular Application<div><p>I’ve just added your example to this list:<br>
<a href=
"http://knowledge.robotlegs.org/discussions/examples/20-links-to-robotlegs-v2-articles-examples-demos-utilities-and-tutorials">
http://knowledge.robotlegs.org/discussions/examples/20-links-to-rob...</a></p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-28T13:30:13Z2012-09-28T13:30:13ZModular Application<div><p>Thank you @Ondina for adding the project to RL2 examples.</p>
<p>I am glad that I was able to contribute to this community :) (of
course you get the credit for this project as I just implemented a
similar idea to what you had in your robotlegs2-sketches
project).</p>
<p>Thank you for bringing my attention to the cleaning up process.
I have added the changes to the project.</p>
<p>:) I like the father - child example.</p>
<p>Since we are talking about modular communications... the event
dispatcher channels use events to communication between modules.
How about if we want to use Signals? I haven't tried it yet... but
I would think that a signal would simply be defined in the Shell
context (similar to the event dispatchers that are defined there),
then injected into the module that wants to listen to it.</p></div>mbarjawitag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-28T14:34:05Z2012-09-28T14:34:05ZModular Application<div><blockquote>
<p>Thank you @Ondina for adding the project to RL2 examples. I am
glad that I was able to contribute to this community :) (of course
you get the credit for this project as I just implemented a similar
idea to what you had in your robotlegs2-sketches project).</p>
</blockquote>
<p>You are more than welcome :)<br>
I’m really glad that my experiments have been helpful. As I
said already, I won’t be able to refine my ChatModule, write
documentation and upload the tests for the project anytime soon, so
I think your example, being simple and clear enough, will be doing
a really good job at showing how the rl2 inter-modular
communication works.</p>
<p>If your time permits, I suggest to add a sub-module as well
(child of module one, for example) to exemplify the
ModularityExtension settings (inherit, expose) that we’ve
discussed previously.</p>
<blockquote>
<p>Since we are talking about modular communications... the event
dispatcher channels use events to communication between modules.
How about if we want to use Signals? I haven't tried it yet... but
I would think that a signal would simply be defined in the Shell
context (similar to the event dispatchers that are defined there),
then injected into the module that wants to listen to it.</p>
</blockquote>
<p>You’re right, mapping a signal like this in the parent
context:</p>
<p>injector.map(InterModularSignal).asSingleton();</p>
<p>should make it available to the child as well.</p>
<p>Why don’t you do a version of RL2ModularCommunications
with signals? ;)</p>
<p>If your questions have been answered and you think we’ve
solved all the problems (in the world!) you can close the thread
and re-open it later, if need be.</p>
<p>Cheers<br>
Ondina</p></div>Ondina D.F.tag:robotlegs.tenderapp.com,2009-10-18:Comment/189391292012-09-28T15:32:30Z2012-09-28T15:32:30ZModular Application<div><p>Thanks again, I will update the current example to have a
sub-module.</p>
<p>I will close this thread for now, and then once I have the
signals example, I'll reopen this thread, and post a link here.</p></div>mbarjawi