Exemple #1
0
        private void PostBoot()
        {
            _ApplyPatches = StateTreeAction.CreateActionInvoker <IJsonPatch[]>
                            (
                StoredValue, "@APPLY_PATCHES",

                (IJsonPatch[] patches) =>
            {
                foreach (var patch in patches)
                {
                    var paths = patch.Path.SplitJsonPath();
                    var node  = this.ResolveNodeByPaths(paths.Take(paths.Length - 1));
                    (node as ObjectNode).ApplyPatchLocally(paths[paths.Length - 1], patch);
                }
            }
                            );

            _ApplySnapshot = StateTreeAction.CreateActionInvoker <object>
                             (
                StoredValue, "@APPLY_SNAPSHOT",

                (object snapshot) =>
            {
                // if the snapshot is the same as the current one, avoid performing a reconcile
                if (snapshot != Snapshot)
                {
                    // apply it by calling the type logic
                    Type.ApplySnapshot(this, snapshot);
                }
            }
                             );
        }
        protected void FinalizeNewInstance(INode node, IMap <string, INode> childNodes)
        {
            var instance = node.StoredValue as IObservableObject <T, INode>;

            // Node = node as ObjectNode;

            if (instance != null)
            {
                foreach (var property in childNodes)
                {
                    instance.Write(property.Key, property.Value);
                }

                foreach (var initializer in Initializers)
                {
                    initializer(instance);
                }

                if (instance is IObservableObject <T, INode> observable)
                {
                    foreach (var action in Actions)
                    {
                        observable.AddAction(action.Name, StateTreeAction.CreateActionInvoker(instance, action.Name, action.Action));
                    }

                    foreach (var hook in Hooks)
                    {
                        var hookAction = (Action <object[]>)Delegate.Combine(hook.Value.ToArray());

                        observable.AddAction(hook.Key.ToString(), Observable.Actions.CreateAction(hook.Key.ToString(), (arguments) =>
                        {
                            hookAction(new object[] { instance }.Concat(arguments).ToArray());
                            return(null);
                        }));
                    }

                    //Actions.RunInAction(call.Name, action, new object[] { call.Target }.Concat(call.Arguments).ToArray())
                }

                instance.Intercept(change => WillChange(change));

                instance.Observe(change => DidChange(change));
            }
        }
        public static IDisposable OnAction(this object target, Action <ISerializedActionCall> listener, bool attachAfter = true)
        {
            if (!target.IsStateTreeNode())
            {
                throw new InvalidOperationException("Can not listen for action on Non State Tree Node");
            }

            void FireListener(IMiddlewareEvent call)
            {
                if (call.Type == MiddlewareEventType.Action && call.Id == call.RootId)
                {
                    var source = call.Context.GetStateTreeNode();

                    var data = new SerializedActionCall
                    {
                        Name = call.Name,

                        Path = StateTreeUtils.GetRelativePathBetweenNodes(target.GetStateTreeNode(), source),

                        //TODO: serialize arguments
                        Arguments = call.Arguments.ToArray()
                    };

                    listener(data);
                }
            }

            Action <IMiddlewareEvent, Action <IMiddlewareEvent, Func <object, object> >, Action <object> > onAfterAction = (IMiddlewareEvent call, Action <IMiddlewareEvent, Func <object, object> > next, Action <object> action) =>
            {
                next(call, null);

                FireListener(call);
            };

            Action <IMiddlewareEvent, Action <IMiddlewareEvent, Func <object, object> >, Action <object> > onBeforeAction = (IMiddlewareEvent call, Action <IMiddlewareEvent, Func <object, object> > next, Action <object> action) =>
            {
                FireListener(call);

                next(call, null);
            };

            return(StateTreeAction.AddMiddleware(target.GetStateTree(), attachAfter ? onAfterAction : onBeforeAction));
        }