protected virtual NodeStep EvaluateNode(Node node) { NodeStep step; Log.Trace("Entering node {0}", node.GetType().Name); try { step = node.Evaluate(); } catch { step = new NodeStep(NodeResult.Fail, null); } if (evaluating) { Log.Trace("Exiting node {0} with result {1}{2}", node.GetType().Name, step.Result, step.Slot == null ? "" : (" by slot " + step.Slot.Name)); } return(step); }
protected virtual void EvaluateNodes() { Node[] stepNodes; lock (Nodes) { if (Nodes.Count == 0) { return; } stepNodes = Nodes.ToArray(); Nodes.Clear(); } Thread[] threads = new Thread[stepNodes.Length]; for (int i = 0; i < stepNodes.Length; i++) { Node node = stepNodes[i]; // Create the thread threads[i] = new Thread(() => { NodeStep step = EvaluateNode(node); if (!evaluating) { Return(NodeResult.Stop); return; } switch (step.Result) { case NodeResult.Fail: Return(NodeResult.Fail); return; case NodeResult.Stop: Return(NodeResult.Stop); return; } if (step.Result == NodeResult.Success) { lock (Nodes) foreach (Node slotNode in step.Slot.Nodes) { Nodes.Add(slotNode); } } lock (this.threads) { this.threads.Remove(Thread.CurrentThread); if (this.threads.Count == 0 && Nodes.Count == 0) { Return(); return; } } if (evaluating && !evaluated) { EvaluateNodes(); } }); } if (!evaluating) { Return(NodeResult.Stop); return; } // Register threads lock (this.threads) this.threads.AddRange(threads); // Start threads foreach (Thread thread in threads) { thread.Start(); } }