public ScalarNode(IType type,
                          ObjectNode parent, string subpath,
                          IEnvironment environment,
                          object initialSnapshot,
                          Func <object, IStateTreeNode, object> createNewInstance,
                          Action <INode, object, IStateTreeNode> finalizeNewInstance = null)
        {
            Type = type;

            Parent = parent;

            Environment = environment;

            Subpath = subpath;

            IStateTreeNode meta = new StateTreeNode(this);

            StoredValue = createNewInstance(initialSnapshot, meta);

            AutoUnbox = true;

            State = NodeLifeCycle.INITIALIZING;

            bool sawException = true;

            try
            {
                finalizeNewInstance?.Invoke(this, initialSnapshot, meta);

                State = NodeLifeCycle.CREATED;

                sawException = false;
            }
            finally
            {
                if (sawException)
                {
                    // short-cut to die the instance, to avoid the snapshot computed starting to throw...
                    State = NodeLifeCycle.DEAD;
                }
            }
        }
示例#2
0
        public ObjectNode(IType type,
                          ObjectNode parent, string subpath,
                          IEnvironment environment,
                          object initialSnapshot,
                          Func <object, IStateTreeNode, object> createNewInstance,
                          Action <INode, object, IStateTreeNode> finalizeNewInstance = null)
        {
            NodeId = ++NextNodeId;

            Type = type;

            //_initialSnapshot = initialSnapshot;
            //_createNewInstance = createNewInstance;
            //_finalizeNewInstance = finalizeNewInstance;

            State = NodeLifeCycle.INITIALIZING;

            SubpathAtom = new Atom("path");

            Subpath        = subpath;
            EscapedSubpath = subpath.EscapeJsonPath();

            Parent = parent;

            Environment = environment;

            _IsRunningAction = false;

            IsProtectionEnabled = true;

            AutoUnbox = true;

            PreBoot();

            if (type is IObjectType objectType)
            {
                IdentifierAttribute = objectType.IdentifierAttribute;

                // identifier can not be changed during lifecycle of a node
                // so we safely can read it from initial snapshot

                if (!string.IsNullOrWhiteSpace(IdentifierAttribute))
                {
                    Identifier = Convert.ToString(StateTreeUtils.GetPropertyValue(initialSnapshot, IdentifierAttribute));
                }
            }

            if (parent == null)
            {
                IdentifierCache = new IdentifierCache();
            }

            var childNodes = type.InitializeChildNodes(this, initialSnapshot);

            if (parent == null)
            {
                IdentifierCache.AddNodeToCache(this);
            }
            else
            {
                parent.Root.IdentifierCache.AddNodeToCache(this);
            }

            IStateTreeNode meta = new StateTreeNode(this);

            StoredValue = createNewInstance(childNodes, meta);

            PostBoot();

            PreCompute();

            bool sawException = true;

            try
            {
                _IsRunningAction = true;

                finalizeNewInstance?.Invoke(this, childNodes, meta);

                _IsRunningAction = false;

                FireHook(Hook.AfterCreate);

                State = NodeLifeCycle.CREATED;

                sawException = false;
            }
            finally
            {
                if (sawException)
                {
                    // short-cut to die the instance, to avoid the snapshot computed starting to throw...
                    State = NodeLifeCycle.DEAD;
                }
            }

            // NOTE: we need to touch snapshot, because non-observable
            // "observableInstanceCreated" field was touched
            // _Snapshot.TrackAndCompute();

            if (IsRoot)
            {
                AddSnapshotReaction();
            }

            FinalizeCreation();

            // _childNodes = null;
            // _initialSnapshot = null;
            // _createNewInstance = null;
            // _finalizeNewInstance = null;
        }