using System; using System.Collections.Generic; using System.Linq; using UnityEditor; using UnityEngine; using Studio.Manage; using Studio.VirtualFactory; namespace Studio { public enum FactoryNeeds { GenerateAGV, StackerInputLoad, Stacking, GenerateLoad, StackerLoadOut, } public class VirtualFactoryManager : MonoBehaviour { public List stackerCranes = new(); public AGVManager agvManager; public AGVMap agvMap; public PortMap portMap; public List loads = new(); public Product prf_Load; public AGVNode startNode; public bool stackerHasEmptyCell; public int maxAGVCount = 4; public List needs = new(); public AGVNeedsScanner agvNeedScanner; public ResourceNeedsScanner resourceNeedsChecker; public StackerCraneNeedsScanner stackerNeedsChecker; public List scanners = new(); HashSet stackingReadys = new(); private StackerCraneManager stackerCraneManager; public override void AfterAwake() { agvMap = FindSingle(); portMap = FindSingle(); agvManager = ManagerHub.instance.Get(); stackerCranes = FindObjectsByType(UnityEngine.FindObjectsSortMode.None).ToList(); agvNeedScanner = new AGVNeedsScanner(this, agvManager); resourceNeedsChecker = new ResourceNeedsScanner(portMap); stackerNeedsChecker = new StackerCraneNeedsScanner(this, stackerCraneManager); scanners.Add(agvNeedScanner); scanners.Add(resourceNeedsChecker); scanners.Add(stackerNeedsChecker); agvNeedScanner.onScanningComplete += OnScanningComplete; resourceNeedsChecker.onScanningComplete += OnScanningComplete; stackerNeedsChecker.onScanningComplete += OnScanningComplete; Scanning(); } void Scanning() { Debug.Log("Needs Scanning"); foreach (var scanner in scanners) { scanner.Scanning(); } } private void OnScanningComplete(NeedsScanner scanner, List list) { Debug.Log($"On Needs Scanning Complete {scanner.GetType().Name}"); switch (scanner) { case AGVNeedsScanner _: AGVNeedsSolutioning(list); break; case ResourceNeedsScanner _: ResourceNeedsSolutioning(list); break; case StackerCraneNeedsScanner _: StackerNeedsSolutioning(list); break; } list.Clear(); } private void StackerNeedsSolutioning(List list) { foreach (var needs in list) { switch (needs) { case FactoryNeeds.StackerInputLoad: DeliveryStackerInputLoad(); break; case FactoryNeeds.Stacking: StackerStacking(); break; case FactoryNeeds.StackerLoadOut: StackerLoadOut(); break; } } } private void StackerLoadOut() { foreach (var stacker in stackerCranes) { stacker.AddTask(new OutputTask()); } } private void ResourceNeedsSolutioning(List list) { foreach (var needs in list) { switch (needs) { case FactoryNeeds.GenerateLoad: GenerateLoad(); break; } } } private void AGVNeedsSolutioning(List list) { foreach (var needs in list) { switch (needs) { case FactoryNeeds.GenerateAGV: GenerateAGV(); break; } } } private void StackerStacking() { foreach (var stacker in stackerCranes) { if (stackingReadys.Add(stacker) && !stacker.inputPort.isEmpty) { Debug.Log("Stacker Stacking"); stacker.onCompleteTask += OnStackerStackingComplete; stacker.AddTask(new InputTask()); } } } private void OnStackerStackingComplete(StackerCrane crane) { stackingReadys.Remove(crane); crane.onCompleteTask -= OnStackerStackingComplete; resourceNeedsChecker.Scanning(); stackerNeedsChecker.Scanning(); } private void OnStackerInputLoad(StackerCrane stacker) { Debug.Log($"Stacker {stacker.name} is On Input Load"); stacker.inputPort.onLoadEvent -= () => OnStackerInputLoad(stacker); } private void DeliveryStackerInputLoad() { if (!agvManager.TryGetIdleAGV(out var agvWorker)) { return; } if(!portMap.TryGetFullGeneratePort(out var generatePort)) { return; } if(!agvMap.TryGetEmptyInputPortNode(out var inputPortNode)) { return; } var startNode = agvWorker.currentNode; var generateNode = generatePort.GetComponent(); var getLoadPath = agvMap.FindPath(startNode, generateNode); var inputLoadPath = agvMap.FindPath(generateNode, inputPortNode); agvWorker.AddAction(new AGVMoveAction(getLoadPath)); agvWorker.AddAction(new AGVLoadAction(generatePort)); agvWorker.AddAction(new AGVMoveAction(inputLoadPath)); agvWorker.AddAction(new AGVUnloadAction(inputPortNode.loader)); agvWorker.onCompleteTask += OnAGVIdle; } void OnAGVIdle(AGV worker) { Debug.Log($"{worker.name} is On Enter idle"); stackerNeedsChecker.Scanning(); worker.onCompleteTask -= OnAGVIdle; } private void GenerateLoad() { if(portMap.TryGetEmptyGeneratePort(out var port)) { Debug.Log($"GenerateLoad"); var newLoad = Instantiate(prf_Load); port.Load(newLoad); loads.Add(newLoad); } } private void GenerateAGV() { Debug.Log($"GenerateAGV"); var newAGV = agvManager.CreateEmptyAGV(); newAGV.ForceSet(startNode); } } }