示例#1
0
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            _.Paragraph("uFrame utilizes a new concept developed to fit the uFrame and RX paradigm of programming.  " +
                        "We like to call this \"Re-active\" state machines. ");
            _.Paragraph("The main concept of state machines in uFrame MVVM is that when defining them in your " +
                        "diagrams you don't need to focus on anything other than the states and transitions that " +
                        "make up the machine.  Making the machine come to life is a matter of wiring them to " +
                        "computed properties, command bindings, and view bindings.  But initially, you can focus " +
                        "purely on the high-level rather than implementation, once commands and transitions " +
                        "are all wired together transitions and states can be easily tweaked with minimal to " +
                        "zero changes in your code.");
            _.Paragraph("Reactive State Machines employ the concept of data subscriptions causing transitions, rather than polling data every frame, this can give a definite increase in performance.");
            _.Break();
            _.ImageByUrl("http://i.imgur.com/CPymbPH.png");
            _.Break();
            _.Title2("Manually triggering transitions");
            _.Paragraph("To set a transition in code, you'll need to access the state machine property.  This should be the property that is connected to your state machine.");
            _.CodeSnippet("{ViewModel}.{StateMachinePropertyName}Property.Transition(\"NAME OF TRANSITION HERE\");");
            _.Break();
            _.Title2("Manually setting the state");
            _.CodeSnippet("{ViewModel}.{StateMachinePropertyName}Property.SetState<STATE_CLASS_NAME>();");
            _.Title3("or");
            _.CodeSnippet("{ViewModel}.{StateMachinePropertyName}Property.SetState(\"STATE_NAME\");");
            _.Break();



//            _.AlsoSeePages(typeof(UsingStateMachines));
        }
示例#2
0
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            _.Paragraph("Commands define a property of type ISignal<TCommandClass> on an element.  These act as a delegate to a pre-initialized handler." +
                        "The handlers are setup in the controllers initialize method to point to a method, this makes a controller a factory for a view-model." +
                        "");

            var ele = new ScaffoldGraph()
                      .BeginNode <ElementNode>("Player")
                      .AddItem <CommandsChildItem>("Hit")
                      .EndNode();

            _.Title2("Executing a command from a viewmodel.");
            _.CodeSnippet("MyViewModel.CommandName.OnNext(new {CommandName}Command() { });");
            _.Break();
            _.Title2("Generated Model Commands");
            _.TemplateExample <ViewModelTemplate, ElementNode>(ele as ElementNode, true, "CommandItems", "Bind");
            _.Break();
            _.Title2("Generated Controller Command Handlers");
            _.TemplateExample <ControllerTemplate, ElementNode>(ele as ElementNode, true, "CommandItems", "CommandMethod");
            _.Break();

            _.Break();
            _.Title3("Also See");
            _.LinkToPage <Controllers>();
            _.LinkToPage <CreationAndInitialization>();
        }
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            ElementNode elementNode;

            ScaffoldComputed(out elementNode);

            _.ImageByUrl("http://i.imgur.com/qeDjrVR.png");
            _.Paragraph("A Computed Property is an extremely powerful feature added to uFrame's ViewModel layer.  These properties can calculate their value based on other properties, and are recalculated whenever one of those change.  So for example, if you have a boolean IsDead computed property on a PlayerViewModel, dependent on a Player.Health property, uFrame will generate these three things on that PlayerViewModel for you to override:");
            _.Break();
            _.Title2("Under the hood");
            _.TemplateExample <ViewModelTemplate, ElementNode>(elementNode, true, "ComputedDependents", "ResetComputed", "Compute");

            _.Title3("ResetIsDead");
            _.Paragraph("Usually fine without overriding, used to set up the computed observable");

            _.Title3("ComputeIsDead");
            _.Paragraph("A \"getter\" used to compute the property, based on dependents");

            _.Title3("GetIsDeadDepedents");
            _.Paragraph("This where you would override and provide additional dependents, if needed");

            _.Break();
            _.Note("It's important to correctly set all the dependents, because the computed only knows when it needs to be recalculated by observing these dependents for changes.  This is done in the diagram by dragging a link from a ViewModel's property to the computed, or in code by overriding the Get{ComputedName}Dependents() function.");
        }
示例#4
0
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            var ele = new ScaffoldGraph()
                      .BeginNode <ElementNode>("Player")
                      .AddItem <PropertiesChildItem>("FirstName")
                      .AddItem <PropertiesChildItem>("LastName")
                      .EndNode();

            _.Title2("Subscribable Properties");
            _.TemplateExample <ViewModelTemplate, ElementNode>(ele as ElementNode, true, "ViewModelProperty");

            _.Title2("Value Wrapper Properties");
            _.TemplateExample <ViewModelTemplate, ElementNode>(ele as ElementNode, true, "ViewModelValueProperty");

            _.Title2("The Bind Method");
            _.TemplateExample <ViewModelTemplate, ElementNode>(ele as ElementNode, true, "Bind");
        }
示例#5
0
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            _.Paragraph("Collections are a bindable list on a view model that allow anything to be notified when a change occurs to the collection.");

            var ele = new ScaffoldGraph()
                      .BeginNode <ElementNode>("Player")
                      .AddItem <CollectionsChildItem>("Children")
                      .EndNode();

            _.Title2("Generated Model Collections");
            _.TemplateExample <ViewModelTemplate, ElementNode>(ele as ElementNode, true, "CollectionProperty", "Bind");
        }
示例#6
0
 public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
 {
     base.GetContent(_);
     _.Title2("What is it?");
     _.Paragraph("ViewModels are the theoretical objects in your game.  " +
                 "They consist of data in the form of properties and collections, " +
                 "and also define the available commands for that object.  Because " +
                 "they are regular C# classes and do not inherit from Monobehaviour, " +
                 "ViewModels are very portable.  Although they do not require a View " +
                 "in order to exist, if you would like to represent a ViewModel's data " +
                 "in Unity, you would create a View and bind it to that ViewModel.");
     _.Break();
     _.Title2("Where does it exist in Unity?");
     _.Paragraph("ViewModels don't technically exist until runtime, at which point they are " +
                 "instantiated into memory as needed.  If a View exists in your scene, at runtime " +
                 "it will publish the 'ViewCreatedEvent' for the specific ViewModel it wants to bind to, at which " +
                 "point the ViewService will set the ViewModel with the matching given identifier," +
                 " creating it if it doesn't exist.  When defining single instances of a particular " +
                 "ViewModel through the uFrame Editor window on a subsystem, these instances are also " +
                 "created at runtime and will be readily available in the SceneManager's Dependency " +
                 "Container for any Views requesting them.");
 }
示例#7
0
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            if (_uFrameBindingTypes == null)
            {
                _uFrameBindingTypes = InvertApplication.Container.ResolveAll <uFrameBindingType>();
            }
            foreach (var item in _uFrameBindingTypes)
            {
                _.Title2(item.DisplayFormat, "{Name}");
                _.Paragraph(item.Description);

                //var tempDecleration = new CodeTypeDeclaration();
                //item.CreateBindingSignature(new CreateBindingSignatureParams(tempDecleration,_=>new CodeTypeReference("PROPERTY_TYPE"), ))
                //   item.CreateBindingSignature()
            }
        }
        public override void GetContent(Invert.Core.GraphDesigner.IDocumentationBuilder _)
        {
            base.GetContent(_);
            _.Paragraph("Usually a property binding is a one-way stream of information, where a View is simply receiving information about a property's changing values.  In a game environment however, there are times where it makes sense to allow Views to actually determine these values as well, for things like a GameObject's position, rotation, etc.  This is where two-way bindings are needed.");
            _.Paragraph("Scene Properties are two-way bindings, and allows for a View to calculate and set a property on its ViewModel.  This is done in an observable way, and when adding a scene property to a view, 3 specific methods are made available.  For example, adding a Position scene property on a PlayerView will result in these underlying base methods:");

            var graph = new ScaffoldGraph();
            PropertiesChildItem positionProperty;
            var player = graph.BeginNode <ElementNode>("Player")
                         .AddItem("Position", out positionProperty, "Vector3")
                         .EndNode();

            var view = (ViewNode)graph
                       .BeginNode <ViewNode>("PlayerView")

                       .EndNode()
            ;

            graph.AddConnection(player, view.ElementInputSlot);
            graph.AddConnection(positionProperty, view.ScenePropertiesInputSlot);

            _.Break();
            _.Title2("Under the hood. Generated Scene Properties");
            _.TemplateExample <ViewTemplate, ViewNode>(view, true, new [] { "ResetProperty", "CalculateProperty", "GetPropertyObservable", "Bind" });
            _.Break();
            _.Title3("ResetPosition");
            _.Paragraph("ResetPosition() is mostly used to initialize the binding, is called in the View's base Bind() method, and typically doesn't need to be overridden and altered.");
            _.Break();
            _.Title3("CalculatePosition");
            _.Paragraph("CalculatePosition() is the main method you would override on your generated PlayerView, where you would return a Vector3 to give the player's position.");
            _.ShowGist("2e5c9b6d07b76bcaedb1", "CalculatePosition.cs");
            _.Break();
            _.Title3("GetPositionObservable");
            _.Paragraph("GetPositionObservable() should only be overridden in cases where you have a more convenient or performant method of observing the scene property change, because as you see, this calculation is happening every Update by default.  In this case, we know that ViewBase is already monitoring a TransformChangedObservable (and specifically a PositionChangedObservable as well), so on our PlayerView we would override the GetPositionObservable like this:");
            _.ShowGist("3d0e2f8bd65a044e82d6", "GetPositionObservable.cs");
            _.Break();
        }