示例#1
0
        private static void ImportantMethods(IDocumentationBuilder _)
        {
            _.Title2("Execution Order");
            _.Paragraph("There are actually several different entry points on generated Views.  The usual order is:");
            _.Title3("For Views instantiated at runtime");
            _.Paragraph("Awake > OnEnable > PreBind > Bind > AfterBind > InitializeViewModel > Start > Update loop begins");
            _.Title3("For Views existing \"SceneFirst\" before runtime");
            _.Paragraph(
                "Awake > OnEnable > CreateModel > InitializeViewModel > Start (before base call) > PreBind > Bind > AfterBind > Start (after base call)");

            _.Title3("When Destroying an object");
            _.Paragraph(
                "OnDisable > OnDestroy (before base.OnDestroy() call) > UnBind > OnDestroy (after base.OnDestroy() call)");
            _.Break();
            _.Break();
            _.Title2("Help, my bindings have stopped working!");
            _.Paragraph(
                "There are a few methods that ALWAYS need their base.Method() calls intact, otherwise uFrame can easily  produce unexpected results.");
            _.Paragraph("These methods include a majority of the overridden standard Unity methods:");
            _.Paragraph(" - Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(" - PreBind(), Bind(), AfterBind(), UnBind(), InitializeViewModel()");
            _.Break();
            _.Break();
            _.Title2("Important Methods");
            _.Paragraph(
                "When looking for more clarity on how uFrame builds upon Monobehaviour, it can be fairly useful to look through ViewBase.cs, as this is what all uFrame Views inherit from.");

            _.Title3("PreBind()");
            _.Paragraph("This happens before the View begins creating bindings to its given ViewModel.");
            _.Break();

            _.Title3("Bind()");
            _.Paragraph(
                "This is where the View actually creates property bindings, collection bindings, and command bindings to the given ViewModel.  The base.Bind() call will automatically create the bindings specified in the uFrame diagram for this specific View type.  If you have any further manual bindings you need to do, this can be a good place to implement them.");
            _.Break();

            _.Title3("AfterBind()");
            _.Paragraph("This is called immediately after the View creates bindings to its ViewModel.");
            _.Break();

            _.Title3("CreateModel()");
            _.Paragraph(
                "This is when SceneFirst Views request a proper ViewModel from the scene's Dependency Container.  For the most part, this should be left alone.");
            _.Break();

            _.Title3("InitializeViewModel()");
            _.Paragraph(
                "On a View, when the Initialize ViewModel option is checked in the inspector, this is where the base.InitializeViewModel() call will set the ViewModel's properties to the values of the View's matching properties (which are underscored in code on the View).  This will usually never need to be overridden.");
            _.Break();

            _.Title3("Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(
                "These are all the same as their Unity counterparts, and must retain their base calls if you override them, in order for uFrame to function properly.");
            _.Break();
        }
示例#2
0
        private static void ImportantMethods(IDocumentationBuilder _)
        {
            _.Title2("Execution Order");
            _.Paragraph("There are actually several different entry points on generated Views.  The usual order is:");
            _.Title3("For Views instantiated at runtime");
            _.Paragraph("Awake > OnEnable > PreBind > Bind > AfterBind > InitializeViewModel > Start > Update loop begins");
            _.Title3("For Views existing \"SceneFirst\" before runtime");
            _.Paragraph(
                "Awake > OnEnable > CreateModel > InitializeViewModel > Start (before base call) > PreBind > Bind > AfterBind > Start (after base call)");

            _.Title3("When Destroying an object");
            _.Paragraph(
                "OnDisable > OnDestroy (before base.OnDestroy() call) > UnBind > OnDestroy (after base.OnDestroy() call)");
            _.Break();
            _.Break();
            _.Title2("Help, my bindings have stopped working!");
            _.Paragraph(
                "There are a few methods that ALWAYS need their base.Method() calls intact, otherwise uFrame can easily  produce unexpected results.");
            _.Paragraph("These methods include a majority of the overridden standard Unity methods:");
            _.Paragraph(" - Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(" - PreBind(), Bind(), AfterBind(), UnBind(), InitializeViewModel()");
            _.Break();
            _.Break();
            _.Title2("Important Methods");
            _.Paragraph(
                "When looking for more clarity on how uFrame builds upon Monobehaviour, it can be fairly useful to look through ViewBase.cs, as this is what all uFrame Views inherit from.");

            _.Title3("PreBind()");
            _.Paragraph("This happens before the View begins creating bindings to its given ViewModel.");
            _.Break();

            _.Title3("Bind()");
            _.Paragraph(
                "This is where the View actually creates property bindings, collection bindings, and command bindings to the given ViewModel.  The base.Bind() call will automatically create the bindings specified in the uFrame diagram for this specific View type.  If you have any further manual bindings you need to do, this can be a good place to implement them.");
            _.Break();

            _.Title3("AfterBind()");
            _.Paragraph("This is called immediately after the View creates bindings to its ViewModel.");
            _.Break();

            _.Title3("CreateModel()");
            _.Paragraph(
                "This is when SceneFirst Views request a proper ViewModel from the scene's Dependency Container.  For the most part, this should be left alone.");
            _.Break();

            _.Title3("InitializeViewModel()");
            _.Paragraph(
                "On a View, when the Initialize ViewModel option is checked in the inspector, this is where the base.InitializeViewModel() call will set the ViewModel's properties to the values of the View's matching properties (which are underscored in code on the View).  This will usually never need to be overridden.");
            _.Break();

            _.Title3("Awake(), Start(), OnEnable(), OnDisable(), OnDestroy(), Update(), LateUpdate()");
            _.Paragraph(
                "These are all the same as their Unity counterparts, and must retain their base calls if you override them, in order for uFrame to function properly.");
            _.Break();
        }
示例#3
0
    public override void GetContent(IDocumentationBuilder _)
    {
        base.GetContent(_);
        _.Title2("What is it?");
        _.Paragraph("Controllers dictate the rules of your game and, like ViewModels, they do not inherit from Unity's Monobehaviour.  As they only handle logic, there only ever needs to be one Controller for each type of ViewModel.  For example, when a PlayerViewModel performs the PickupItem command, the PlayerController would simply need to know which PlayerViewModel to execute that command logic on, and the logic remains the same whether there are 4 players or one.");

        _.Paragraph(" A controller is designed to implement the data-driven logic and rules behind an element " +
                    "and could be considered just a \"group\" of commands for a view-model. " +
                    "The Designer has enough information about an element to implement most of the controller itself " +
                    "In most instances, you only need to apply the logic and rules to each method.  ");

        _.Break();



        _.Title2("Best Practices");
        _.Paragraph("When implementing controllers, think of the element as its own little section of your world, " +
                    "if you want your element to interact or be visible to the entire world, publish events as " +
                    "necessary in your command controller methods.");
        _.Paragraph("To understand this idea a bit more, take a look at the following diagram.");
        _.ImageByUrl("http://i.imgur.com/KbPL9bw.png");
        _.Paragraph("So in the diagram above, on the EnemyHit command handler, we publish the command as 'global' event.  This means that services can be your general connection layer that make various elements work together.");
        _.Title3("But why should I do this?");
        _.Paragraph("Imagine you create a Player element, if it lives entirely on its own (no dependencies on other controllers, services..etc), you can re-use the element in another game and implement services to connect them together.");
        _.Break();
        _.Break();

        _.Title2("The Setup Method");
        _.Paragraph("The setup method is an implementation of the ISystemService interface, this means that all controllers are ultimately services, they do not derive from monobehaviour.  This means you can easily listen to any kind of event on a controller, as well as publish them.");
        _.Title3("Important Note");
        _.Paragraph("You must be careful when listening to events in controllers that use inheritance. For instance, if you have an elementA controller, and a derived elementB controller, and in the setup method you are listening to event 'C', then beth element A and element B will be listening to the same event.  In some cases this may be wanted behaviour, but its important to understand.");
        _.Break();
        _.Break();
        _.Title2("The Initialize Method");
        _.Paragraph("The initialize Method in a controller can be used to initialize an Element's ViewModel (similar to how it might be initialized in the inspector of a View). It is a great place to subscribe to 'Scene Properties'.");
        _.Title2("Command Handlers");
        _.Paragraph("Every command that is outlined on an element, in the Element Designer, will have a corresponding method in a controller (assuming the diagram is saved).  ");
        _.Paragraph("There are a few things to notice when looking at the code example below:");
        _.Paragraph(" - The \"FPSWeaponController\" is derived from \"FPSWeaponControllerBase\", which is generated by the designer.");
        _.Paragraph(" - All of these methods are overrides, because the base class has implemented an empty \"virtual method\" for each command.");
        _.Paragraph(" - The reload method has an IEnumerator result type, because is it is marked as a yield command (indicated by the yellow marker).  This can be achieved by right-clicking on a command and checking \"Is Yield Command\". It is used for simulating a co-routine.");
        _.Paragraph(" - In each method we are simply processing rules by reading and modifying the FPSWeaponViewModel's instance data .");
        _.ShowGist("7bba5439faf0b46efa61", "FPSWeaponController.cs");
    }