by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Apr 08 16:03
    davidgiven opened #312
  • Feb 26 08:49
    desca595 removed as member
  • Jan 15 09:58
    CrazyFlasher synchronize #80
  • Jan 15 09:23
    CrazyFlasher commented #311
  • Jan 15 09:17
    CrazyFlasher opened #80
  • Jan 15 08:43
    CrazyFlasher commented #311
  • Jan 15 08:43
    CrazyFlasher commented #311
  • Jan 15 08:26
    CrazyFlasher commented #311
  • Jan 14 08:30
    CrazyFlasher edited #311
  • Jan 14 08:30
    CrazyFlasher opened #311
  • Oct 23 2019 16:33
    CrazyFlasher commented #310
  • Oct 23 2019 16:31
    CrazyFlasher commented #310
  • Oct 23 2019 16:30
    CrazyFlasher commented #310
  • Oct 23 2019 16:30
    CrazyFlasher commented #310
  • Oct 23 2019 13:15
    st3veV commented #310
  • Oct 23 2019 13:00
    CrazyFlasher opened #310
  • Oct 21 2019 20:08
    CrazyFlasher edited #309
  • Oct 21 2019 20:07
    CrazyFlasher opened #309
  • Oct 21 2019 10:42
    back2dos reopened #308
  • Oct 21 2019 10:42
    back2dos commented #308
St3veV
@st3veV
well of course ideally you have just one variable and only one login service... basically the best way would be to have two login modules... because that's what you're trying to do... I assume the implementation differs only in the service and a view... so you can have a general purpose login module with all the wiring which depends on two things - ILoginSevice and ILoginView... everything within the module doesn't know what it's dealing with and you construct those two things outside of the module and pass them in (for example in the constructor of the module)... when you'll have two modules living side by side and dealing with login and one of them will fire event/trigger that user has logged in... this way you can easily scale the whole thing horizontally just by adding views and services and the whole login problematic would be encapsulated inside one isolated general purpose module
no problem at all :)
St3veV
@st3veV
injector really isn't that complicated thing but for some reason many people think about it as some kind of magic... really, think about it as a map of names and instances... but generally I'd discourage remapping things at runtime because you can very easily shoot yourself in the leg if you're not carefully keeping track on what's mapped to what... that's why I'd suggest the second thing I wrote... single responsibility module which communicates only through interfaces and the dependencies are not instantiated within the module but outside of it
MIchael Solomon
@mikicho
Read twice to fully understand and I see what you mean...
Just to be sure you recommend one module that contains the command, viewHelper and the model and one module (or more) that contains the service and view?
Sounds better, but where I should "pass them in"?
Anyway I going try to do that...
St3veV
@st3veV
well you construct your module somewhere, don't you? I guess you're not using DSL configuration yet so somewhere you're doing new LoginModule()... and at that place you construct your view and service and do new LoginModule(facebookView, facebookService); and the same thing with google... so you'll end up with two instances of login module which work independently on each other... and eventually one of them will dispatch/trigger and event which will say that user is logged in and at that point you have what you need (the logged in user details) and you can safely destroy both of the modules as you don't need them anymore... the main point is that your login module will never know what login method it's actually using (and it doesn't really care)... so later if you then want to add for example twitter login, you just implement your twitter service and view, make another instance of your module and you're all set up... you can have this whole thing encapsulated in another module or it can be just part of your configuration - eventually you have to somewhere specify what login methods are going to be used
MIchael Solomon
@mikicho
Thank you! I think I understand, I'm trying now to implement this :) (and switch/give a chance to triggers too)
Laurent Deketelaere
@aliokan
You have an example of trigger usage in https://github.com/doclerlabs/hexTodoMVC
MIchael Solomon
@mikicho
Thanks! so this project before, didn't notice it using triggers
MIchael Solomon
@mikicho
Hey,
I moved to Triggers and after you get the point it's really more continence than events...
Now I'm not sure how I should to forward the click event from the view(UI) to my service, previously I used command but in the todoMVC example I see using in simple controller...
what the different between command and controller? when I should using command?
MIchael Solomon
@mikicho
@st3veV What I don't understand in your method (of two modules, one "controller" module and one module for the services and views) is why I need modules for services and views(without model)? they live outside the modules isn't? (inside the modules you have only the Interfaces)
and I'm using DSL because all the guides/examples are with it. maybe this is the reason I have some difficult to see the whole picture...
MIchael Solomon
@mikicho

Also, I can (and it will be "right") to do something like:
< login module>

<argument>googleLoginService</argument>

<argument>googleLoginView</argument>
</login module>

< login module>

<argument>facebookLoginService</argument>

<argument>facebookLoginView</argument>
</login module>

X twitter, github, etc...

St3veV
@st3veV
I didn't meant it as needing a additional module for services and views... if you now imagine the dsl you wrote inside its own context - that's the "third module"... the whole handling of login with all it's methods closed inside one big module... where the big module will be the context itself (the context also implements IContextModuleso you can use that just as another module)... so in your application DSL you will only include the "big" module, add listeners to it and on the big scope you don't even have to worry about login methods
St3veV
@st3veV

now that you already work with DSL, there are two types of DSL - XML and "flow"... beside the flow DSL having much more compact syntax it also provides few features that are not available in the XML and one of them is "import"... in flow you can do internalModule = new Context("path/to/internal/flowDSL.flow"); and this will instantiate and execute your configuration so you can literally use the context as other module.

Of course our documentation is not really covering everything but we have pretty good test suite which can be use as examples of supported features, you can find those here: https://github.com/DoclerLabs/hexDSL/tree/master/test/context and https://github.com/DoclerLabs/hexIoC/tree/master/test/context

I hope I'm not confusing you too much introducing those new not very well documented things but I hope you'll find them better in a same way like the Events vs. Triggers topic... the flow DSL is really superior to the XML one in many ways.
MIchael Solomon
@mikicho
image.png
After all the info you got me I started to trying to play with hexMachina test, super fun till now.
just a question, I know that reflection can have very bad performance, why are you guys using it in the MacroAdapterStrategy? there is a tricky macro trick here ?:)
MIchael Solomon
@mikicho
Also, I'm playing now with testEventTrigger test, and see that the receiver get the message between 300-350 ms, it's huge amount off time for dispatching a message isn't?, it's lot of time only because it's test?
image.png
St3veV
@st3veV
So... just to explain why some things are using reflection when the reflection is bad for performance... hexMachina is a project with history and is develop mainly to serve the needs of one particular big closed source project... and that project has a history as well... mainly the history is that it was in flash :) and when last year all the major browsers announced that flash will be turned off by default there was a need to quickly rewrite everything to html+js and quickly convert as3 devs to haxe... reflection all over the place made the framework more similar to Robotlegs which was used in the flash version and increased speed of porting the code and developers adoption... All the events, macro strategies, adapter strategies, runtime xml compiler etc are in the framework for exactly that reason - legacy. Currently as the "main" project evolves the team is starting to refactor everything and get rid of all those reflection based and type unsafe features and switch to static compiler and Triggers (don't confuse it with eventTrigger, because that thing is still using events), Expects to produce more compact, faster and type-safe code... And that's why I keep recommending you all the nicer features even though they're not really documented. ;)
and to your second question... 300ms seems a way too much... also the way you're measuring is a bit unusual... personally I'd create a Timer.stamp(), save it before the call as start time and when the call arrives trace("time " + (Timer.stamp()-startTime));... that should give you a a more accurate picture of how long things take
MIchael Solomon
@mikicho
Hey, I decided to start from the beginning and not use DSL because it's just "write the code for me" and hiding things and makes it more difficult to understand.
In hello world example, why the controller implements ICommandTrigger? https://github.com/DoclerLabs/hexMachina-HelloWorld/blob/master/src/module/control/HelloWorldController.hx
MIchael Solomon
@mikicho

As I said, I'm not using DSL right now, I'm trying to create a simple hello world base on the Hello World example, it looks everything works fine except that I get runtime error the my injected "model is undefined", I think it because my module and my view need to be under a context this is my current code:
Main.hx

class Main {
    static function main() {
        var view = new HelloWorldView();
        var module = new HelloWorldModule(view);
        module.initialize();
    }
}

HelloWorldController.hx

class HelloWorldController implements ICommandTrigger implements IHelloWorldController {
    @inject
    var model:IHelloWorldModel;

    public function sayHello(who:String) {
        // This line makes a runtime error "this.model is undefined"
        model.setMessage("Hello $who");
    }
}

How can I insert the view and the module into a context?

St3veV
@st3veV
Hello... sorry for the delay, I was on vacation and looks like @aliokan doesn't communicate much ;) ... so to answer first question - ICommandTrigger interface is there to provide the possibility to inject things in function bodies (yes, the name is a bit misleading)
St3veV
@st3veV
and for the second question... I think the problem is that the Inject metadata should be with uppercase "I" otherwise it's not processed by the reflection builder. If you're using the exactly same module as it's in the hello world repository to model and controller are properly mapped so there shouldn't be any issue with the way you're initializing things
MIchael Solomon
@mikicho
Thanks, I'm hope that you did well in yours vacation!
This was the problem :\
I struggled with that till you answered to me and I thought that it isn't working because the module and the view should be in some context like in the .flow files. why in flow files they start with: @context( name = 'applicationContext' ) {why this line is necessary?
module have it's own context? injector?
St3veV
@st3veV
the @context is to provide scope for the "application" (where application is a very vague term) - this block basically represents the same thing as a root node in XML DSL and it creates ApplicationContext but it can be used just the same as a module (both module and application context implement the same interface IContextOwner which exposes injector)... so to answer the second question - both module and context have injector, both have things mapped into the injector but they serve slightly different purpose... even though sometimes they can be used interchangeably (and there is a plan to allow that for more cases)
in theory the HelloWorld example could be created completely without the module class because that one only maps things into its internal injector and connects listeners... the only thing that's currently not possible to do without the module class is to deal with the events (the override function _onInitialisation() part) but that could be achieved by simply calling the controller directly from the Main class
MIchael Solomon
@mikicho
so module in @context is like context in context?
"HelloWorld example could be created completely without the module class " do you mean that ApplicationContext can use instead?
Thanks I'm continue to dig in hexMachina :)
MIchael Solomon
@mikicho
BTW: I encounter an interesting issue, when I'm trying to open popup in service that triggered by user click the browser(FireFox) block to popup, probably because there is some code after the click and the browser don't understand that the user is clicked for the popup. did you encounter that?
MIchael Solomon
@mikicho

Like this post

The general rule is that popup blockers will engage if window.open or similar is invoked from javascript that is not invoked by direct user action. That is, you can call window.open in response to a button click > without getting hit by the popup blocker, but if you put the same code in a timer event it will be blocked. Depth of call chain is also a factor - some older browsers only look at the immediate caller, newer
browsers can backtrack a little to see if the caller's caller was a mouse click etc. Keep it as shallow as you can to avoid the popup blockers.

St3veV
@st3veV
in sense module inside a context is a context inside a context, yes... essentially both things are doing the same thing - providing scope, they both have injector and they both maintain set of instances that are wired together... in the end this is a matter of taste and it also depends on the way you want to use the DSL... for example you could do:
    • Single application context that contains modules which contain functionality
      or
    • Single application context which contains other contexts which contain functionality because many times all you need is to expose some controllers API and wire it to another controller which you can do in the main context... basically you can decide to treat the flow file as a module definition
about the popup problem... I know that this is happening in browsers for years now but afaik I never encountered it but that's given by the nature of the projects I work on... the hexMachinas main user is single page app (although complicated and large) and my hobby project is a game so there was never need to open another window
St3veV
@st3veV
but to provide some advice - you don't have to inject only instances, you can also inject methods and call them directly to reduce the stack... for example you can do this:
@Inject
public var openWindow:Void->Void;

// ....

function onClick(e) {
    openWindow();
}
MIchael Solomon
@mikicho
Thanks, all the context in context is actually little weird but I think I'll dig in it later.
About the popup solution, first of all cool! second, the popup is google login and opened by service, if I'll call the service directly by the view it's not "kill" the module concept? I mean, suddenly I just skipping from the view to the service. little weird isn't?
I just upload my code to github if you may check it out and correct me if I'm doing things wrong, I'm not using DSL for now :) sorry if I'm bother you :O
MIchael Solomon
@mikicho
it's incomplete, but the only missing part is the "communication" between servie to model after the service is done, (i.e the complete service event), i'm wondering if I should to replace it with sync service instead of async one
MIchael Solomon
@mikicho
iDo you think t's "right" to "skip" over controller with triggers(model to view - i.e in model: this.trigger.onMessage(message);) or with Dependency injection (view to model - i.e in view @Inject model .... model.someFunction())?
St3veV
@st3veV
hey... so I went through the repo you sent and I can see couple of problems. Mainly it's about the way how things are coupled together... basically the View shouldn't know that there is such a thing as a service and it shouldn't even care about some module... view should only contain things like triggers... so ideally the ILoginView interface should contain trigger called something like onLoginRequested which will be triggered when user clicks on the button (the setUsername method is fine, no coupling to outside world).
The creation of LoginModule should be done in the main class - basically you want to create the module in main and give it the view and the service. The module knows how to control everything and it knows that the view implements the interface so it can connect to the exposed trigger directly to the controllers login method (in my opinion it can even connect the trigger directly to the service call but that's just matter of taste)
regarding the injection of model into view... my idea would be to just inject the method, not the whole model... so something like:
//where you're creating the mappings
injector.mapClassNameToValue("Void->Void", model.someFunction);

//and in the view
@Inject
public var someFunction:Void->Void;
St3veV
@st3veV
that way view doesn't know where the method is coming from, it only cares about calling it... it's the modules responsibility to provide that function
... and as always, sorry for the late response and thank you for your patience ;)
MIchael Solomon
@mikicho
Thanks a lot! I updated my repository with some fixes...
I encounter with irritating problem, in My model I trying to fire a trigger, but it's not file anything for some reason the trigger is empty(in console I see: Object { _inputs: Array[0] }) it worked before my changes :( please take a look.
MIchael Solomon
@mikicho
Now the view AND the model are trigger owner, maybe there is a problem with that?
MIchael Solomon
@mikicho

I'm continue trying some things with hexMachina and I inject controller to my view:

@Inject
 public var controller:IGeneratorController;

When I tried in module insert the view into injector like following, it didn't worked:

this.getInjector().mapToValue(ITransferView, transferView);

But this working:

this.getInjector().injectInto(transferView);

what injectInto do?
And also, I should to "attach" to view into the module (i.e "mapToValue") and not the module to view (i.e "injectInto"), I'm afraid that I not exactly understand the "Injector" thing...

MIchael Solomon
@mikicho
Hm... I think I understand the injector thing: each object that implements IInjectorContainer get an injector object, but it's empty, so in the module I should "share" the module's injector with view's injector by this.getInjector().injectInto(transferView);, but if I want add something to module injector I just need to "map it in" by this.getInjector().map methods or by this._map etc...
St3veV
@st3veV
so first about the injector... if a class implements IInjectorContainer it will get a special reflection treatment to convert all the metadata into executable code so to make it the injection perform a bit faster than using standard Reflect.
so class that implements IInjectorContainer doesn't actually include injector... it just means that it can be injected into
St3veV
@st3veV
the way map method works is following:
// code:
injector.map(ClassX).toValue(x);
// english:
// every time when something requires ClassX provide it this specific value x ... aka singleton pattern
//-----
// code:
injector.map(ClassX).toType(ClassX);
// english:
// every time when something requires ClassX create a new instance of ClassX and provide that instance ... aka factory pattern
so that's what map does
injector.injectInto(instance) does following... it takes the instance you're passing in and goes through all the pre-reflected data (generated by the IInjectorContainer described above) and does injector.getInstance(_whatever type is the public variable type_) which returns instances based on the mapping (or rules in other words) described above