Пример #1
0
        public static object Predict(IUnitValuePort port, GraphReference reference)
        {
            Ensure.That(nameof(port)).IsNotNull(port);

            var flow = New(reference);

            flow.isPrediction = true;

            object value;

            if (port is ValueInput)
            {
                value = flow.GetValue((ValueInput)port);
            }
            else if (port is ValueOutput)
            {
                value = flow.GetValue((ValueOutput)port);
            }
            else
            {
                throw new NotSupportedException();
            }

            flow.Dispose();

            return(value);
        }
Пример #2
0
        public static void TriggerEventHandler <TArgs>(this GraphStack stack, Func <EventHook, bool> predicate, TArgs args, Func <IGraphParentElement, bool> recurse, bool force)
        {
            Ensure.That(nameof(stack)).IsNotNull(stack);

            GraphReference reference = null;

            foreach (var element in stack.graph.elements)
            {
                if (element is IGraphEventHandler <TArgs> handler)
                {
                    if (reference == null)
                    {
                        reference = stack.ToReference();
                    }

                    if (predicate == null || predicate.Invoke(handler.GetHook(reference)))
                    {
                        if (force || handler.IsListening(reference))
                        {
                            handler.Trigger(reference, args);
                        }
                    }
                }

                if (element is IGraphParentElement parentElement && recurse(parentElement))
                {
                    if (stack.TryEnterParentElementUnsafe(parentElement))
                    {
                        stack.TriggerEventHandler(predicate, args, recurse, force);
                        stack.ExitParentElement();
                    }
                }
            }
        }
Пример #3
0
        private static GraphReference New(GraphPointer model)
        {
            var reference = new GraphReference();

            reference.CopyFrom(model);
            return(reference);
        }
Пример #4
0
 private void TriggerUpdate(GraphReference reference)
 {
     using (var flow = Flow.New(reference))
     {
         Update(flow);
     }
 }
Пример #5
0
        public static bool CanPredict(IUnitValuePort port, GraphReference reference)
        {
            Ensure.That(nameof(port)).IsNotNull(port);

            var flow = New(reference);

            flow.isPrediction = true;

            bool canPredict;

            if (port is ValueInput)
            {
                canPredict = flow.CanPredict((ValueInput)port);
            }
            else if (port is ValueOutput)
            {
                canPredict = flow.CanPredict((ValueOutput)port);
            }
            else
            {
                throw new NotSupportedException();
            }

            flow.Dispose();

            return(canPredict);
        }
Пример #6
0
 private void OnButtonGUI(Rect sourcePosition)
 {
     if (GUI.Button(sourcePosition, "Edit Graph"))
     {
         GraphWindow.OpenActive(GraphReference.New((IMacro)metadata.value, true));
     }
 }
Пример #7
0
        // To minimize the amount of implementation needed, and simplify inversion of control,
        // we provide instantiation routines that fit most types of elements in the right order and
        // we provide implemented defaults for interfaces that the element could implement.
        // Normally, an element shouldn't have to override instantiate or uninstantiate directly.

        public virtual void Instantiate(GraphReference instance)
        {
            // Create the data for this graph, non-recursively, that is
            // required for the nest instantiation, so we do it first.
            if (this is IGraphElementWithData withData)
            {
                instance.data.CreateElementData(withData);
            }

            // Nest instantiation is a recursive operation that will
            // call Instantiate on descendant graphs and elements.
            // Because event listening will descend graph data recursively,
            // we need to create it before.
            if (this is IGraphNesterElement nester && nester.nest.graph != null)
            {
                GraphInstances.Instantiate(instance.ChildReference(nester, true));
            }

            // StartListening is a recursive operation that will
            // descend graphs recursively. It must be called after
            // instantiation of all child graphs because it will require
            // their data. The drawback with this approach is that it will be
            // called at each step bubbling up, whereas it will only
            // effectively trigger once we reach the top level.
            // Traversal is currently O(n!) where n is the number of descendants,
            // ideally it would be O(n) if only triggered from the root.

            // => Listening has to be implemented by Bolt classes, because Graphs isn't aware of the event system
        }
Пример #8
0
        private void OpenGraphAsset(UnityObject unityObject, bool shouldSetSceneAsDirty)
        {
            shouldCloseWindow = true;

            ScriptGraphAsset scriptGraphAsset = unityObject as ScriptGraphAsset;

            GraphReference graphReference = null;

            if (scriptGraphAsset != null)
            {
                graphReference = GraphReference.New(scriptGraphAsset, true);
            }
            else
            {
                StateGraphAsset stateGraphAsset = unityObject as StateGraphAsset;

                if (stateGraphAsset != null)
                {
                    graphReference = GraphReference.New(stateGraphAsset, true);
                }
            }

            if (shouldSetSceneAsDirty)
            {
                EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
            }

            GraphWindow.OpenActive(graphReference);

            GUIUtility.ExitGUI();
        }
Пример #9
0
        public static void OpenTab(GraphReference reference)
        {
            var tab = CreateInstance <GraphWindow>();

            tab.reference = reference;
            tab.Show();
        }
Пример #10
0
        public override void Instantiate(GraphReference instance)
        {
            base.Instantiate(instance);

            if (this is IGraphEventListener listener && instance.GetElementData <State.Data>(source).isActive)
            {
                listener.StartListening(instance);
            }
        }
Пример #11
0
        public override void Instantiate(GraphReference instance)
        {
            base.Instantiate(instance);

            if (this is IGraphEventListener listener && XGraphEventListener.IsHierarchyListening(instance))
            {
                listener.StartListening(instance);
            }
        }
Пример #12
0
        public override void Uninstantiate(GraphReference instance)
        {
            if (this is IGraphEventListener listener)
            {
                listener.StopListening(instance);
            }

            base.Uninstantiate(instance);
        }
Пример #13
0
 public IEnumerable <string> GetDynamicVariableNames(VariableKind kind, GraphReference reference)
 {
     return(units.OfType <IUnifiedVariableUnit>()
            .Where(v => v.kind == kind && Flow.CanPredict(v.name, reference))
            .Select(v => Flow.Predict <string>(v.name, reference))
            .Where(name => !StringUtility.IsNullOrWhiteSpace(name))
            .Distinct()
            .OrderBy(name => name));
 }
Пример #14
0
        public virtual void Uninstantiate(GraphReference instance)
        {
            // Debug.Log($"Uninstantiating graph {instance}");

            foreach (var element in elements)
            {
                element.Uninstantiate(instance);
            }
        }
Пример #15
0
        public static object FetchValue(ValueInput input, GraphReference reference)
        {
            var flow = New(reference);

            var result = flow.GetValue(input);

            flow.Dispose();

            return(result);
        }
Пример #16
0
        public override void Instantiate(GraphReference instance)
        {
            base.Instantiate(instance);

            var data = instance.GetElementData <Data>(this);

            if (this is IGraphEventListener listener && data.isActive)
            {
                listener.StartListening(instance);
            }
Пример #17
0
        public static Flow New(GraphReference reference)
        {
            Ensure.That(nameof(reference)).IsNotNull(reference);

            var flow = GenericPool <Flow> .New(() => new Flow());;

            flow.stack = reference.ToStackPooled();

            return(flow);
        }
Пример #18
0
        public override EventHook GetHook(GraphReference reference)
        {
            if (!reference.hasData)
            {
                return(hookName);
            }

            var data = reference.GetElementData <Data>(this);

            return(new EventHook(hookName, data.target));
        }
Пример #19
0
        protected GraphContext(GraphReference reference)
        {
            Ensure.That(nameof(reference)).IsNotNull(reference);
            Ensure.That(nameof(reference.graph)).IsOfType <TGraph>(reference.graph);

            this.reference = reference;

            analyserProvider = new AnalyserProvider(reference);
            graphMetadata    = Metadata.Root().StaticObject(reference.graph);
            extensions       = this.Extensions().ToList().AsReadOnly();
            sidebarPanels    = SidebarPanels().ToList().AsReadOnly();
        }
Пример #20
0
        public static void Uninstantiate(GraphReference instance)
        {
            lock (@lock)
            {
                instance.graph.Uninstantiate(instance);

                if (!byGraph.TryGetValue(instance.graph, out var instancesWithGraph))
                {
                    throw new InvalidOperationException("Graph instance not found via graph.");
                }

                if (instancesWithGraph.Remove(instance))
                {
                    // Debug.Log($"Removed graph instance mapping:\n{instance.graph} => {instance}");

                    // Free the key references for GC collection
                    if (instancesWithGraph.Count == 0)
                    {
                        byGraph.Remove(instance.graph);
                    }
                }
                else
                {
                    Debug.LogWarning($"Could not find graph instance mapping to remove:\n{instance.graph} => {instance}");
                }

                if (!byParent.TryGetValue(instance.parent, out var instancesWithParent))
                {
                    throw new InvalidOperationException("Graph instance not found via parent.");
                }

                if (instancesWithParent.Remove(instance))
                {
                    // Debug.Log($"Removed parent instance mapping:\n{instance.parent.ToSafeString()} => {instance}");

                    // Free the key references for GC collection
                    if (instancesWithParent.Count == 0)
                    {
                        byParent.Remove(instance.parent);
                    }
                }
                else
                {
                    Debug.LogWarning($"Could not find parent instance mapping to remove:\n{instance.parent.ToSafeString()} => {instance}");
                }

                // It's important to only free the graph data after
                // dissociating the instance mapping, because the data
                // is used as part of the equality comparison for pointers
                instance.FreeGraphData();
            }
        }
Пример #21
0
        protected void CreateGraph()
        {
            m_Macro = ScriptableObject.CreateInstance <ScriptGraphAsset>();
            AssetDatabase.CreateAsset(m_Macro, k_AssetPath);

            m_Graph      = m_Macro.graph;
            m_Canvas     = new FlowCanvas(m_Graph);
            m_Reference  = GraphReference.New(m_Macro, false);
            m_GameObject = new GameObject();

            m_Machine            = m_GameObject.AddComponent <FlowMachine>();
            m_Machine.nest.macro = m_Macro;
        }
Пример #22
0
        public static GraphReference New(UnityObject rootObject, IEnumerable <Guid> parentElementGuids, bool ensureValid)
        {
            if (!ensureValid && !IsValidRoot(rootObject))
            {
                return(null);
            }

            var reference = new GraphReference();

            reference.Initialize(rootObject, parentElementGuids, ensureValid);
            reference.Hash();
            return(reference);
        }
Пример #23
0
        public static GraphReference New(IGraphRoot root, IEnumerable <IGraphParentElement> parentElements, bool ensureValid)
        {
            if (!ensureValid && !IsValidRoot(root))
            {
                return(null);
            }

            var reference = new GraphReference();

            reference.Initialize(root, parentElements, ensureValid);
            reference.Hash();
            return(reference);
        }
Пример #24
0
        public static GraphReference New(IGraphRoot root, bool ensureValid)
        {
            if (!ensureValid && !IsValidRoot(root))
            {
                return(null);
            }

            var reference = new GraphReference();

            reference.Initialize(root);
            reference.Hash();
            return(reference);
        }
Пример #25
0
        public void Trigger(GraphReference reference, TArgs args)
        {
            var flow = Flow.New(reference);

            if (!ShouldTrigger(flow, args))
            {
                flow.Dispose();
                return;
            }

            AssignArguments(flow, args);

            Run(flow);
        }
Пример #26
0
        public virtual void Uninstantiate(GraphReference instance)
        {
            // See above comments, in reverse order.

            if (this is IGraphNesterElement nester && nester.nest.graph != null)
            {
                GraphInstances.Uninstantiate(instance.ChildReference(nester, true));
            }

            if (this is IGraphElementWithData withData)
            {
                instance.data.FreeElementData(withData);
            }
        }
Пример #27
0
 public static void OpenActive(GraphReference reference)
 {
     if (active == null)
     {
         active           = GetWindow <GraphWindow>();
         active.reference = reference;
         active.Show();
     }
     else
     {
         active.reference = reference;
         active.Focus();
     }
 }
Пример #28
0
 public static void OpenActive(GraphReference reference)
 {
     VSUsageUtility.isVisualScriptingUsed = true;
     if (active == null)
     {
         active           = GetWindow <GraphWindow>();
         active.reference = reference;
         active.Show();
     }
     else
     {
         active.reference = reference;
         active.Focus();
     }
 }
Пример #29
0
        public static IEnumerable <IUnitOption> Subset(UnitOptionFilter filter, GraphReference reference)
        {
            lock (@lock)
            {
                if (options == null)
                {
                    Load();
                }

                var dynamicOptions    = UnityAPI.Await(() => GetDynamicOptions().ToHashSet());
                var contextualOptions = UnityAPI.Await(() => GetContextualOptions(reference).ToHashSet());

                return(LinqUtility.Concat <IUnitOption>(options, dynamicOptions, contextualOptions)
                       .Where((filter ?? UnitOptionFilter.Any).ValidateOption)
                       .ToArray());
            }
        }
Пример #30
0
        public override void Uninstantiate(GraphReference instance)
        {
            // Here, we're relying on the fact that OnDestroy calls Uninstantiate.
            // We need to force-dispose any remaining coroutine to avoid
            // memory leaks, because OnDestroy on the runner will not keep
            // executing MoveNext() until our soft-destroy call at the end of Flow.Coroutine
            // or even dispose the coroutine's enumerator (!).
            var data       = instance.GetElementData <Data>(this);
            var coroutines = data.activeCoroutines.ToHashSetPooled();

#if UNITY_EDITOR
            new FrameDelayedCallback(() => StopAllCoroutines(coroutines), 1);
#else
            StopAllCoroutines(coroutines);
#endif

            base.Uninstantiate(instance);
        }