Ejemplo n.º 1
0
        /// <summary>
        /// Invokes all matching methods contained in nodes on the given network.
        /// </summary>
        /// <param name="publishedData">The data passed to the methods to be invoked.</param>
        /// <param name="publisher">Typically, the object that is invoking publish.</param>
        /// <param name="network">The network to publish to.</param>
        protected static void PublishToNetwork(object publishedData, object publisher, Tags tags, string network)
        {
            CommunicationNode current = null;

            if (!root.TryGetValue(network, out current))
            {
                return;
            }

            List <CommunicationNode> orphanList = null;

            //iterate over all nodes on the network
            do
            {
                //keep track of orphaned nodes (unity objects that have been deleted will register as null)
                if (current.NodeOwner == null)
                {
                    if (orphanList == null)
                    {
                        orphanList = new List <CommunicationNode>();
                    }

                    orphanList.Add(current);
                    continue;
                }

                //prevent sources from publishing to themselves
                if (current.allowPublishToSelf || current.NodeOwner != publisher)
                {
                    if (debugPrintAllActivity)
                    {
                        DebugLogger.Log("Publish is Invoking handler for : " + publishedData.GetType().Name + " on " + GetObjectName(current.NodeOwner) + " sent by " + GetObjectName(publisher));
                    }
                    bool result = current.InvokeMatchingCallback(publishedData, publisher, tags);
                    if (result)
                    {
                        debugPublishWasHandled = true;
                    }
                }

                current = current.next[network];
            } while(current != root[network]);

            if (orphanList != null)
            {
                //remove/clean up orphaned nodes
                for (int i = 0; i < orphanList.Count; ++i)
                {
                    RemoveNode(orphanList[i]);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Add the given node to all networks.
        /// This method assumes that the networks exist and that the node is not already part of these networks.
        /// </summary>
        protected static void AddNodeToNetworks(CommunicationNode node, List <string> networkCollection)
        {
            foreach (string n in networkCollection)
            {
                CommunicationNode prev = root[n];
                CommunicationNode next = root[n].next[n];

                node.next[n] = next;
                node.prev[n] = prev;

                next.prev[n] = node;
                prev.next[n] = node;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Create any networks that don't already exist
        /// </summary>
        protected static void CreateNetworks(CommunicationNode node, List <string> networkCollection)
        {
            foreach (string n in networkCollection)
            {
                if (root.ContainsKey(n))
                {
                    continue;
                }

                root.Add(n, node);
                root[n].next[n] = root[n];
                root[n].prev[n] = root[n];
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Does this node have any non-null connections on any networks?
        /// </summary>
        protected static bool NodeHasAnyConnections(CommunicationNode node)
        {
            foreach (var n in node.next)
            {
                if (n.Value.next != null)
                {
                    return(true);
                }
            }

            foreach (var p in node.prev)
            {
                if (p.Value.prev != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Internal method that removes a node from the network in an intrusive linked-list style.
        /// </summary>
        protected static void RemoveNode(CommunicationNode node)
        {
            if (node.next == null)
            {
                return;
            }

            if (debugPrintAllActivity)
            {
                string removingNetworks = "";
                node.Networks.ToList().Select(x => { removingNetworks += x + ", "; return(x); });
                removingNetworks = removingNetworks.TrimEnd(',', ' ');
                DebugLogger.Log("Removing node with owner " + GetObjectName(node.NodeOwner) + " from network(s): " + removingNetworks);
            }

            foreach (string n in networks)
            {
                if (!node.next.ContainsKey(n))
                {
                    continue;
                }

                if (node.next[n] != null)
                {
                    node.next[n].prev[n] = node.prev[n];
                }
                if (node.prev[n] != null)
                {
                    node.prev[n].next[n] = node.next[n];
                }

                node.next[n] = null;
                node.prev[n] = null;

                //remove the network if it exists and it's empty
                if (root != null && root.ContainsKey(n) && root[n].next[n] == null && root[n].prev[n] == null)
                {
                    root.Remove(n);
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Internal method that adds a node to the given networks in an intrusive linked-list style.
        /// </summary>
        protected static void AddNode(CommunicationNode node, List <string> networks)
        {
            if (debugPrintAllActivity)
            {
                string addingToNetworks = "";
                networks.Select(x => { addingToNetworks += x + ", "; return(x); });
                addingToNetworks = addingToNetworks.TrimEnd(',', ' ');
                DebugLogger.Log("Adding node with owner " + GetObjectName(node.NodeOwner) + " to network(s): " + addingToNetworks);
            }

            //if the node has non-null connections, clear them by removing it before we process the insertion
            if (NodeHasAnyConnections(node))
            {
                RemoveNode(node);
            }

            CreateNetworks(node, networks);

            //add new nodes to the root
            AddNodeToNetworks(node, networks);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Removes the node from all networks. For a unity object this should typically go in OnDisable or OnDestroy, depending on the desired behavior.
 /// </summary>
 public virtual void DisableNode()
 {
     CommunicationNode.RemoveNode(this);
     NodeOwner = null;
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Enables this node on the network.
        /// Any methods in the nodeOwner object that have the [CommunicationCallback] attribute will be registered as handlers on the network.
        /// Typically this should be put in Start/Awake/OnEnable or some other similar method.
        /// </summary>
        /// <param name="nodeOwner">An object with zero or more methods decorated with the [CommunicationCallback] attribute.</param>
        /// <param name="networksToJoin">(Optional) Zero or more strings, arrays of string, or lists of strings specifying the networks to publish to. If empty, will publish to all networks.</param>
        public virtual void EnableNode(object nodeOwner, params object[] networksToJoin)
        {
            //error: nodes themselves cannot be owners
            if (nodeOwner.GetType() == this.GetType())
            {
                DisableNode();
                throw new InvalidOperationException("A CommunicationNode may not be the owner of itself. A CommunicationNode needs a reference to a class with zero or more methods that have the [CommunicationCallback] attribute.");
            }

            //There must be an owner, so treat this as a removal.
            if (nodeOwner == null)
            {
                DisableNode();
                return;
            }

            this.NodeOwner = nodeOwner;

            List <string> totalNetworks = new List <string>();

            //Attempt to cast the params to strings, arrays of strings, or lists of strings and concat them into totalNetworks
            foreach (var n in networksToJoin)
            {
                if (n == null)
                {
                    continue;
                }

                if (n as string[] != null)
                {
                    totalNetworks.AddRange(n as string[]);
                }
                else if (n as List <string> != null)
                {
                    totalNetworks.AddRange(n as List <string>);
                }
                else if (n as string != null)
                {
                    totalNetworks.Add(n as string);
                }
                else
                {
#if UNITY_5_3_OR_NEWER
                    DebugLogger.LogError("Non-string parameter type or container found in networksToJoin params. All network params must be string, arrays of string, or lists of string.");
#else
                    DebugLogger.Write("Non-string parameter type or container found in networksToJoin params. All network params must be string, arrays of string, or lists of string.");
#endif
                }
            }

            totalNetworks.AddRange(networksToJoinOnEnable);

            //By default, use the type name to add the object to its own network
            if (totalNetworks.Count <= 0)
            {
                totalNetworks.Add(nodeOwner.GetType().Name);
            }

            CommunicationNode.AddNode(this, totalNetworks);
            RefreshCallbackBindings();
        }