175 lines
5.0 KiB
C#
175 lines
5.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using XED.VirtualFactory;
|
|
|
|
namespace XED
|
|
{
|
|
public class VirtualFactoryManager : MonoBehaviour
|
|
{
|
|
public List<StackerCrane> stackerCranes = new();
|
|
public AGVManager agvManager;
|
|
public AGVMap agvMap;
|
|
public PortMap portMap;
|
|
public List<Product> loads = new();
|
|
public Product prf_Load;
|
|
public AGVNode startNode;
|
|
|
|
public bool stackerHasEmptyCell;
|
|
public int maxAGVCount = 4;
|
|
public enum FactoryNeeds
|
|
{
|
|
NeedAGV,
|
|
NeedLoad,
|
|
NeedStackerInputLoad,
|
|
NeedStackerInput,
|
|
}
|
|
|
|
public bool agvIsLack;
|
|
public bool loadIsLack;
|
|
public List<FactoryNeeds> needs = new();
|
|
public event Action scanningAction;
|
|
public event Action solutionAction;
|
|
public override void AfterAwake()
|
|
{
|
|
agvMap = FindSingle<AGVMap>();
|
|
portMap = FindSingle<PortMap>();
|
|
agvManager = FindSingle<AGVManager>();
|
|
stackerCranes = FindObjectsByType<StackerCrane>(UnityEngine.FindObjectsSortMode.None).ToList();
|
|
|
|
scanningAction += CheckAGVCount;
|
|
scanningAction += CheckStackerSpace;
|
|
scanningAction += CheckStackerInput;
|
|
}
|
|
|
|
private void CheckStackerInput()
|
|
{
|
|
foreach (var stacker in stackerCranes)
|
|
{
|
|
if (!stacker.hasEmptyCell)
|
|
continue;
|
|
|
|
if (stacker.inputPort.isEmpty)
|
|
{
|
|
Debug.Log("Need Stacker Input Load");
|
|
needs.Add(FactoryNeeds.NeedStackerInputLoad);
|
|
return;
|
|
}
|
|
|
|
Debug.Log($"Need Stacker Input");
|
|
needs.Add(FactoryNeeds.NeedStackerInput);
|
|
return;
|
|
}
|
|
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
ScanningVirtualFactory();
|
|
Solutioning();
|
|
}
|
|
|
|
void ScanningVirtualFactory()
|
|
{
|
|
scanningAction?.Invoke();
|
|
}
|
|
|
|
void Solutioning()
|
|
{
|
|
foreach(var n in needs)
|
|
{
|
|
switch (n)
|
|
{
|
|
case FactoryNeeds.NeedAGV:
|
|
solutionAction += GenerateAGV;
|
|
break;
|
|
case FactoryNeeds.NeedLoad:
|
|
solutionAction += GenerateLoad;
|
|
break;
|
|
case FactoryNeeds.NeedStackerInputLoad:
|
|
solutionAction += DeliveryStackerInputLoad;
|
|
break;
|
|
}
|
|
}
|
|
solutionAction?.Invoke();
|
|
solutionAction = null;
|
|
needs.Clear();
|
|
}
|
|
|
|
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<AGVNode>();
|
|
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));
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void CheckStackerSpace()
|
|
{
|
|
if (stackerCranes.Sum(sc => sc.cells.Count()) == loads.Count)
|
|
return;
|
|
|
|
foreach (var stacker in stackerCranes)
|
|
{
|
|
if (stacker.hasEmptyCell)
|
|
{
|
|
Debug.Log($"Need Stacker Load");
|
|
needs.Add(FactoryNeeds.NeedLoad);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CheckAGVCount()
|
|
{
|
|
Debug.Log($"CheckAGVCount");
|
|
if (maxAGVCount > agvManager.agvs.Count)
|
|
{
|
|
needs.Add(FactoryNeeds.NeedAGV);
|
|
}
|
|
else
|
|
{
|
|
scanningAction -= CheckAGVCount;
|
|
}
|
|
}
|
|
}
|
|
}
|