Unity STRANGEIOC Framework (ii)

Source: Internet
Author: User

Mvcscontex:the Big Picture

1. The portal to the application is a class that becomes contextview, which is an monobehavior instantiation Mvcscontext

2. Use Mvcscontext to perform various bindings.

3. The dispatcher is a communication bus that allows you to re-send messages, in Mvcscontext they send the timevents, or you can follow the above steps to rewrite the context to use signals

4. The command class is triggered by a timeevents or signal, and then he executes some app logic.

5. Model Storage Status

6.services part of the communication with the app unexpectedly (such as the Access Faebook)

7. Interface script attached to the object: Player interaction with the game

8.Mediators (intermediary) is also monobehavior but he can also isolate the view and other parts.

This picture of the warrior how these parts work together

General introduction of how to set up the project below

A contextview begins

Contextview is a monobehaviour used to instantiate your context (contextual) Myfirstprojectroot is a subclass of Contextview, here is the beginning of the application

Using system;using unityengine;using strange.extensions.context.impl;using strange.extensions.context.api;
namespace strange.examples.myfirstproject{public class Myfirstprojectroot:contextview { void Awake () { //instantiate the context, passing it this instance. context = new Myfirstcontext (this,contextstartupflags.manual_mapping);
       Context. Start ();}} }

This is to use strange. Extensions. Context. Impl and using Strange.extensions.context.api namespaces

Contextview defines a property called context, which of course refers to our context. We just need to define what it is. We write a script called Myfirstcontext. This referring to Myfirstprojectroot, he told the context which Gameobject was considered contextview. contextstartupflags.manual_mapping shows that once we start everything will continue. Call the context. Start () Let it be put into action. Does not continue if start is not called

    • Contextstartupflags.automatic: Context will automatically map bindings and starts (default)
    • Contextstartupflags.manual_mapping: The online text will start, then after the core binding, the mapping will stop before instantiation or any custom binding, and start () must be called to proceed
    • Contextstartupflags.manual_launch: The online text will start and then stop after the core binding, before calling Contextevent.start or similar signals. You must use launch () to continue
The context binds (contextual binding)

The context is where all bindings occur, and if there is no binding, the strange app is just a bunch of disconnected parts. Context is the glue that brings order to chaos. From our extended mvcscontext, we got a whole bunch of core bindings, Mvcscontext is to give us all the clean structures we need a control reversal style application: An injection (injector), a command bus, model and service support, and a mediation interface.

 
Using system;using unityengine;using strange.extensions.context.api;using strange.extensions.context.impl;using Strange.extensions.dispatcher.eventdispatcher.api;using Strange.extensions.dispatcher.eventdispatcher.impl;  Namespace strange.examples.myfirstproject{public class Myfirstcontext:mvcscontext {public myfirstcontext (Monobehaviour view): Base (view) {} public Myfirstcontext (Monobehaviour view, Contextstar            Tupflags flags): Base (view, Flags) {} protected override void Mapbindings () { Injectionbinder.bind<iexamplemodel> (). To<examplemodel> ().            Tosingleton (); Injectionbinder.bind<iexampleservice> (). To<exampleservice> ().             Tosingleton (); Mediationbinder.bind<exampleview> ().             To<examplemediator> (); Commandbinder.bind (Exampleevent.request_web_service)                .            To<callwebservicecommand> (); Commandbinder.bind (Contextevent.start). To<startcommand> ().         Once (); }    }}

As you can see, we extend the mvcscontext, which means we inherit all of its mappings (explore the depth of its class and you'll find it interesting). We already have a injectionbinder and commandbinder and dispatcher dispatcher. Note that the scheduler can be coupled throughout the application, and Commandbinder, so any event dispatch can trigger a callback that also triggers the command commands and sequence sequences.

The mapping here is exactly what you expect if you read the various component injections, we map a model and a service are singleton. We will have only one view (Exampleview) In this example, we bind it to an intermediary (examplemediator). Finally, we map two commands. The two more important is that Startcommand binds to a special event:Contextevent.start. This is an event trigger to launch your app. You need to bind some commands or queues to it to want Init () to enter your application. We're tied up . Once (), a special method that was untied at the end of the unbinds.

Note there is a postbindings () method here. This is a very useful place to put some code that you need to run after the binding. But after he runs in Launch () , Mvcscontext uses this method to deal with any views interface which is earlier in the register (called after mapbindings). Another obvious and useful situation is called dontdestroyonload (Contextview) in Postbindings (). Used to keep Contextview (and the Context) when you load a new scene.

A command fires (an order is triggered)

Contextevent.start was punished because it was tied to Startcommand, a new Startcommand instance will be instantiated and executed.

Using system;using unityengine;using strange.extensions.context.api;using strange.extensions.command.impl;using Strange.extensions.dispatcher.eventdispatcher.impl;namespace strange.examples.myfirstproject{Public    class Startcommand:eventcommand    {                [Inject (Contextkeys.context_view)] public        gameobject Contextview{get;set ;}                public override void Execute ()        {            Gameobject go = new Gameobject ();            Go.name = "Exampleview";            Go. Addcomponent<exampleview> ();            Go.transform.parent = Contextview.transform;}}    }

Startcommand extension Eventcommand means that this is a fixed command commandbinder can handle, and everything he inherits comes from command and Eventcommand. In particular, inheriting eventcommand means you get a ievent injection, and you can access dispatcher.

If you just extend the command, you won't have automatic access to these objects, but you can still manually inject them

[Inject (Contextkeys.context_dispatcher)] Ieventdispatcher Dispatcher{get;set;} [Inject] IEvent Evt{get;set;}

Note the two different types of injections that are used. Both Ieventdispatcher and Gameobject create multiple instances with names. This is because we want to reference very specific versions of these objects. We don't want to be any gameobject. We need a tag like contextview. We also do not accept any old ieventdispatcher. The only one that will communicate between contexts, he is marked as contextkeys.context_dispatcher. on the other hand, IEvent is a simple mapping for this particular command (technically he maps to a value), so there is no necessary name.

Depending on what we will use in the current scene is Contextview, they add a child view to it.

The Execute () method is automatically triggered by Commandbinder. In most cases, the order of execution is this

    1. Instantiate command commands bound to Ievent.type
    2. Injecting dependencies, including IEvent itself
    3. Call Excute ()
    4. Remove Command command

The command does not need to be cleaned up immediately, but we will get a little. If you look at the code in execute (), you will find that he is pure unity. Create a gameobject, attach Monobehaviour, and then set it's father to Contextview. We are using specific Monobehaviour (code), however, happens to be a strange IView, since we mapped this interface in context.

Mediationbinder.bind<exampleview> (). To<examplemediator> ();

This interface is automatically dispatched, which means a new examplemediator has just been created!

A View is mediated (an interface is dispatched)

If you spend some time writing code for unity, you create an interface, you need to call Monobehavior, but the point is that the interface doesn't appear on the screen. I'm not going to take the time to execute the Exampleview code. You can look at the sample files if you are afraid you already know C # and unity you don't need him. I just want to get two-bit attention. First of all:

public class Exampleview:view

By extending the view, you will get the code that connects each view to the context. With strange you no longer need to expand the view or rewrite the method inside. But if you don't expand the view, you still need to implement the iview interface. This needs to make sure that you monobehaviour the context to operate.

The second point

[Inject]public ieventdispatcher dispatcher{get; set;}

Note that we inject ieventdispatcher. But it's not the same dispatch as Startcommand. Take a closer look at the code first written in Eventcommand (I showed above) is this

[Inject (Contextkeys.context_dispatcher)]public ieventdispatcher dispatcher{get; set;}

By name injection, the specified command uses a common context dispatcher. This interface should not be injected into the dispatcher. The purpose of the mediation is to isolate the application's view and vice-versa strange allow the view to be injected. But this feature is best when strictly limited, injecting local dispatchers and intermediaries to communicate well. So inject the configuration/layout file (which is useful if you publish to multiple platforms). But if you listen to my advice, do not inject into a model or service or other out-of-pool views and mediations.

Tell you the right way: For most developers, the hardest part is mastering the concept of the entire framework. A view should only be displayed and entered. When certain inputs occur, the view should notify the media. The mediation mediator (allows injection of context dispatchers) to abstract the point of view and focus on the rest of the application. This protects the application's view code, which usually and protects your interface is confusing, contrary to the situation.

Note that the base view class uses the standard Monobehaviour handler  Awake() , Start() and OnDestroy()。如果你重写这些处理程序,确保你调用了base.Awake()等。这样Strange才能正常运行。

Observing dispatchers

Using system;using unityengine;using strange.extensions.dispatcher.eventdispatcher.api;using Strange.extensions.mediation.impl;namespace strange.examples.myfirstproject{public class ExampleMediator:                eventmediator {[Inject] public exampleview view{get; set;}  public override void Onregister () {View.dispatcher.AddListener (exampleview.click_event,            onviewclicked); Dispatcher.            AddListener (Exampleevent.score_change, Onscorechange);        View.init (); } public override void OnRemove () {View.dispatcher.RemoveListener (Exampl            Eview.click_event, onviewclicked); Dispatcher.            RemoveListener (Exampleevent.score_change, Onscorechange);        Debug.Log ("Mediator OnRemove");            } private void Onviewclicked () {Debug.Log ("View click Detected"); Dispatcher. Dispatch (ExampLeevent.request_web_service, "http://www.thirdmotion.com/");            } private void Onscorechange (IEvent evt) {String score = (string) evt.data;        View.updatescore (score); }    }}

At the top we injected the Exampleview. This is how dispatcher mediator knows how to dispatch that interface. The media can know a lot about their interface. Mediations are often considered "scrap (out of the box) code" because it is a very special detail view and application. Of course this intermediary can know that the view has a dispatcher and the event that dispatches this program becomes exampleview.click_event. By listening to this event, the mediation establishes a handler (onviewclicked ()) that tells the rest of the application what this click means. The view should not send the Request_web_service event. The interface is just the interface. It should dispatch events like this help_button_clicked, collision, Swipe_right. This should be the work of the mediator mediator, mapping these events to the rest of the application's meaningful parts. such as Request_help missile_enemy_collision player_reload. The events behind him map to commands that invoke the Help system, calculate the score increase (increase the scoring model), or determine whether the player is allowed to reload.

The onregister () and onremove () methods are like the constructors and destructors of mediator schedulers. Onregister () occurs after injection. So I often use it to set the listener and Invoke init () method instance interface, OnRemove () occurs after Monobehavior's OnDestroy () is called. It triggers when you can use to clean up the monitor. Make sure you remove your listener, otherwise it will result in an incorrect garbage collection.

Finally note that by extending eventmediator we have a public dispatcher. The dispatcher listens for Score_change events on the bus.

Another command fires (other commands triggered)

Let's look back at the context of this line there are problems we ignore:

Commandbinder.bind (Exampleevent.request_web_service). To<callwebservicecommand> ();

This means that any time the public bus receives this event, it will start Callwebservicecommand. But he attracts your attention because of the use of commands in different ways.

Using system;using system.collections;using unityengine;using strange.extensions.context.api;using Strange.extensions.command.impl;using Strange.extensions.dispatcher.eventdispatcher.api;namespace strange.examples.myfirstproject{public class Callwebservicecommand:eventcommand {[Inject] public I                Examplemodel Model{get;set;}         [Inject] public iexampleservice service{get;set;}            public override void Execute () {Retain ();            Service.dispatcher.AddListener (Exampleevent.fulfill_service_request, OnComplete); String url = evt.data As String service.        Request (URL);                } private void OnComplete (IEvent result) {Service.dispatcher.RemoveListener            (Exampleevent.fulfill_service_request, OnComplete);            Model.data = Result.data As String; Dispatcher.            Dispatch (Exampleevent.score_change, evt.data);   Release ();     }    }} 

We listen to the service and call a method. We use the valid data data in the event to trigger the Mediator dispatcher service. Request (the URL). When the service is over, he distributes it. Trigger Oncomplate (). We cancel the listener mapping, set a value of the model, dispatch Score_change that which dispatcher received to do the corresponding processing.

But if you've been watching closely you'll remember, as I mentioned before, the command immediately cleans up when execute () finishes. So why not this command will not be garbage collected. The answer is the topmost call to the Retain () method reserved. Retain () marks this command as an exemption from cleanup. This will remain known after the release () is called. Obviously, this means that the call to release () is very important, otherwise it can cause a running memory leak risk.

Do not allow models and services to listen for events. Use their dispatcher to listen for events mapping Across contexts (mapping through contexts)

In general you have to obey the contextual boundaries. After all, its boundaries are for a reason: it allows for the isolation of parts of the application, making the program more modular. But sometimes there are objects, perhaps a model, a service, or a signal that needs to be accessed across multiple contexts.

Injectionbinder.bind<istarship> (). To

Adding a crosscontext () signal binding requires instantiation through the context boundary. It will be provided to all children contexts. Note that you can also overwrite a crosscontext binding. If you insinuate a local key, the local binding will overwrite the Crosscontext.

All the document content is over here. Getting started with a few small chestnuts can quickly understand and adapt to such architectures.  Architecture learning can really change people's coding habits. It's been a lot of sense to read the documents these days. Hope to have a small learning partner to communicate with each other.

Unity STRANGEIOC Framework (ii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.