public override void ApplySnapshot(INode node, IMap <string, S> snapshot)
        {
            StateTreeUtils.Typecheck(this, snapshot);

            var map = GetValue(node);

            var keysmap = map.Keys.Aggregate(new Map <string, bool>(), (acc, key) =>
            {
                acc[key] = false;
                return(acc);
            });

            foreach (var pair in snapshot)
            {
                map[pair.Key]     = SubType.Create(pair.Value, Node.Environment);
                keysmap[pair.Key] = true;
            }

            foreach (var pair in keysmap)
            {
                if (!pair.Value)
                {
                    map.Remove(pair.Key);
                }
            }
        }
        public static INode ValueAsNode <Sx, Tx>(IType <Sx, Tx> type, ObjectNode parent, string subpath, object value, INode oldNode)
        {
            StateTreeUtils.Typecheck(type, value);

            // the new value has a MST node
            if (value.IsStateTreeNode())
            {
                var node = value.GetStateTreeNode();

                node.AssertAlive();

                // the node lives here
                if (node.Parent != null && node.Parent == parent)
                {
                    node.SetParent(parent, subpath);

                    if (oldNode != null && oldNode != node)
                    {
                        oldNode.Dispose();
                    }
                    return(node);
                }
            }

            // there is old node and new one is a value/snapshot
            if (oldNode != null)
            {
                var node = type.Reconcile(oldNode, value);
                node.SetParent(parent, subpath);
                return(node);
            }

            // nothing to do, create from scratch
            return(type.Instantiate(parent, subpath, parent.Environment, value));
        }
Beispiel #3
0
        private S GetDefaultValue()
        {
            var defaultValue = _DefaultValue != null?_DefaultValue() : default(S);

            StateTreeUtils.Typecheck(_Type, defaultValue);

            return(defaultValue);
        }
Beispiel #4
0
        public T Create(S snapshot = default(S), IEnvironment environment = null)
        {
            snapshot = snapshot != null ? snapshot : GetDefaultSnapshot();

            StateTreeUtils.Typecheck(this, snapshot);

            return((T)Instantiate(null, "", environment, snapshot).Value);
        }
        public override void ApplySnapshot(INode node, S[] snapshot)
        {
            StateTreeUtils.Typecheck(this, snapshot);

            var values = snapshot.Select(snap => SubType.Create(snap, node.Environment)).ToArray();

            GetValue(node).Replace(values);
        }
        public override void ApplySnapshot(INode node, S snapshot)
        {
            var value = (S)ApplySnapshotPreProcessor(snapshot);

            StateTreeUtils.Typecheck(this, value);

            if (node.StoredValue is IObservableObject <T, INode> observable)
            {
                foreach (var property in PropertyNames)
                {
                    observable.Write(property, GetPropertyValue(value, property));
                }
            }
        }
        private IObjectWillChange WillChange(IObjectWillChange change)
        {
            var node = change.Object.GetStateTreeNode();

            node.AssertWritable();

            // only properties are typed, state are stored as-is references
            var type = Properties.ContainsKey(change.Name) ? Properties[change.Name] : null;

            if (type != null)
            {
                StateTreeUtils.Typecheck(type, change.NewValue);

                change.NewValue = type.Reconcile(node.GetChildNode(change.Name), change.NewValue);
            }

            return(change);
        }
        private IMapWillChange <string, INode> WillChange(IMapWillChange <string, INode> change)
        {
            var node = change.Object.GetStateTreeNode() as ObjectNode;

            node.AssertWritable();

            var map = change.Object as IObservableMap <string, INode, T>;

            switch (change.Type)
            {
            case ChangeType.UPDATE:
            {
                var oldValue = map.GetValue(change.Name);

                if (change.NewValue == oldValue)
                {
                    return(null);
                }

                StateTreeUtils.Typecheck(SubType, change.NewValue.StoredValue);

                change.NewValue = SubType.Reconcile(node.GetChildNode(change.Name), change.NewValue.StoredValue);

                ProcessIdentifier(change.Name, change.NewValue);
            }
            break;

            case ChangeType.ADD:
            {
                StateTreeUtils.Typecheck(SubType, change.NewValue);

                change.NewValue = SubType.Instantiate(node, change.Name, Node.Environment, change.NewValue.StoredValue);

                ProcessIdentifier(change.Name, change.NewValue);
            }
            break;
            }

            return(change);
        }