//----------------------------------------------------------------------- //----------------------------------------------------------------------- // file="Blueprint.cs" // Project: StgSharp // AuthorGroup: Nitload Space // Copyright (c) Nitload Space. All rights reserved. // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the “Software”), to deal in the Software without restriction, // including without limitation the rights to use, copy, modify, merge, // publish, distribute, sublicense, and/or sell copies of the Software, // and to permit persons to whom the Software is furnished to do so, // subject to the following conditions: // // The above copyright notice and // this permission notice shall be included in all copies // or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED “AS IS”, // WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, // ARISING FROM, OUT OF OR IN CONNECTION WITH // THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // //----------------------------------------------------------------------- //----------------------------------------------------------------------- using StgSharp; using StgSharp.Logic; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace StgSharpDebug.Logic { public class Blueprint { private BlueprintNode beginNode; private Dictionary allNode; private Func terminate; private int currentNodeIndex = 0; private List allThread; private List nativeNodeList; private List nodeList; public Blueprint() { allThread = new List(); nodeList = new List(); nativeNodeList = new List(); terminate = () => false; } public bool IsRunning => allThread.Any(t => t.Status == TaskStatus.Running); public void Init(int threadCount) { foreach (var item in allNode) { if (item.Value.IsNative) { nativeNodeList.Add(item.Value); } else { nodeList.Add(item.Value); } } nativeNodeList.Sort(); nodeList.Sort(); if (threadCount > nodeList.Count) { InternalIO.InternalWriteLog( "Thread setting error: amount of threads of this blueprint is larger than amount of nodes.", LogType.Warning); threadCount = nodeList.Count; } for (int i = 0; i < threadCount; i++) { allThread.Add(new Task( () => { while (true) { try { while (true) { RequestNextNode().Run(); } } catch (NodeClearException) { } if (terminate()) { return; } } } )); } } /// /// Run all nodes in current blueprint once. /// public void Run() { foreach (var t in allThread) { t.Start(); } foreach (var node in nativeNodeList) { node.Run(); } Task.WaitAll(allThread.ToArray()); } /// /// Run all nodes repeatedly until it is instructed to terminate. /// /// Instructor to terminate all tasks. Returns if tasks should terminate public void RunRepeatedly(Func terminateInstructor) { terminate = terminateInstructor; foreach (var t in allThread) { t.Start(); } foreach (var node in nativeNodeList) { node.Run(); } foreach (var node in nativeNodeList) { node.Run(); } } private BlueprintNode RequestNextNode() { if (currentNodeIndex < nodeList.Count) { BlueprintNode ret = nodeList[currentNodeIndex]; Interlocked.Increment(ref currentNodeIndex); return ret; } throw new NodeClearException(); } } internal class NodeClearException : Exception { } }