Exemple #1
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
        }
Exemple #2
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);
            }
        }
        public static void TriggerEventHandler <TArgs>(this GraphReference reference, Func <EventHook, bool> predicate, TArgs args, Func <IGraphParentElement, bool> recurse, bool force)
        {
            Ensure.That(nameof(reference)).IsNotNull(reference);

            foreach (var element in reference.graph.elements)
            {
                if (element is IGraphEventHandler <TArgs> handler && (predicate?.Invoke(handler.GetHook(reference)) ?? true))
                {
                    if (force || handler.IsListening(reference))
                    {
                        handler.Trigger(reference, args);
                    }
                }

                if (element is IGraphParentElement parentElement && recurse(parentElement))
                {
                    reference.ChildReference(parentElement, false, 0)?.TriggerEventHandler(predicate, args, recurse, force);
                }
            }
        }