Files
Studio/Assets/Scripts/XED/Machine/AGV/AGVNode/AGVNodeManager.cs
2025-02-28 15:37:55 +09:00

462 lines
15 KiB
C#

using Newtonsoft.Json;
using Ookii.Dialogs;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using TriLibCore.SFB;
using UnityEngine;
using UnityEngine.EventSystems;
using XRLib;
using XED.Interfaces;
using XED.Manage;
using NUnit.Framework.Interfaces;
namespace XED.Machine
{
public enum NodeSelectMode
{
Idle,
Draw,
SelectRunNode,
Select,
Setting
}
public class AGVNodeManager : MonoBehaviour, ISingle, IModeController, IInputHandler
{
[SerializeField]
GameObject nodePrefab;
[SerializeField]
GameObject markerPrefab;
GameObject nodeTarget;
NodeSelectMode nodeSelectMode = NodeSelectMode.Idle;
public event Action<AGVNode, AGVNode> onNodeConnectionAdded;
public event Action<AGVNode, AGVNode> onNodeConnectionUpdated;
public event Action<AGVNode, AGVNode> onNodeConnectionRemoved;
public AGVNode currentlySelectedNode;
public event Action<GameObject> onNodeGizmoSelected;
public event Action<GameObject> onNodeSettingSelected;
public event Action onNodeDeselected;
public event Action<List<AGVNode>> onNodeSequenceUpdated;
public event Action<List<AGVNode>> onNodeSequenceOrdered;
public AGVNodeMap agvNodeMap;
Dictionary<string, AGVNode> nodeTable = new();
List<AGVNode> selectedNodeSequence = new List<AGVNode>();
InputHandler myHandler;
NodeGizmoController nodeGizmoController;
public ModePanel.ProgramMode mode => ModePanel.ProgramMode.AGVPathDrawing;
public override void AfterStart()
{
agvNodeMap = new AGVNodeMap();
myHandler = GetInputHandler();
nodeGizmoController = FindSingle<NodeGizmoController>();
}
private void Update()
{
if (currentlySelectedNode)
{
foreach (var c in currentlySelectedNode.nodeClass.linkedNodID)
{
onNodeConnectionUpdated?.Invoke(currentlySelectedNode, nodeTable[c]);
}
agvNodeMap.agvNodeData.Find(n => n.id == currentlySelectedNode.nodeClass.id).x = currentlySelectedNode.transform.position.x.ToString();
agvNodeMap.agvNodeData.Find(n => n.id == currentlySelectedNode.nodeClass.id).y = currentlySelectedNode.transform.position.y.ToString();
agvNodeMap.agvNodeData.Find(n => n.id == currentlySelectedNode.nodeClass.id).z = currentlySelectedNode.transform.position.z.ToString();
}
}
public void ChangeSelectMode(NodeSelectMode selectMode)
{
if (nodeSelectMode == selectMode)
{
return;
}
nodeSelectMode = selectMode;
if (selectMode == NodeSelectMode.Draw)
{
DrawMarker(true);
}
else
{
DrawMarker(false);
}
foreach (var n in selectedNodeSequence)
{
n.DeleteColor();
}
selectedNodeSequence.Clear();
onNodeSequenceUpdated?.Invoke(selectedNodeSequence);
DeselectNode();
}
public void OnClickAGVNode(RaycastHit hit, Component comp)
{
if (nodeGizmoController.GetGizmoHover()||nodeSelectMode==NodeSelectMode.Idle)
{
return;
}
var selectnode = comp.GetComponent<AGVNode>();
if (nodeSelectMode == NodeSelectMode.SelectRunNode)
{
if (selectedNodeSequence.Contains(selectnode))
{
OrderNodeRemove(selectnode);
}
else
{
OrderNodeAdd(selectnode);
}
}
else
{
if (selectnode == currentlySelectedNode)
{
DeselectNode();
}
else
{
SelectNode(selectnode);
}
}
}
private void SelectNode(AGVNode node)
{
currentlySelectedNode = node;
if (nodeSelectMode == NodeSelectMode.Setting)
{
onNodeSettingSelected?.Invoke(currentlySelectedNode.gameObject);
}
else
{
onNodeGizmoSelected?.Invoke(currentlySelectedNode.gameObject);
}
}
private void DeselectNode()
{
onNodeDeselected?.Invoke();
if (currentlySelectedNode)
{
currentlySelectedNode.DeleteColor();
}
currentlySelectedNode = null;
}
public void Load()
{
ClearNodes();
string json = "";
var data = StandaloneFileBrowser.OpenFilePanel("AGV Node Dialog", "", "json", false);
if (data.Count >= 1 && !string.IsNullOrEmpty(data[0].Name))
{
json = System.IO.File.ReadAllText(data[0].Name);
try
{
agvNodeMap = JsonConvert.DeserializeObject<AGVNodeMap>(json);
} catch
{
Debug.Log("¸Â´Â json Çü½ÄÀÌ ¾Æ´Õ´Ï´Ù");
}
}
if (string.IsNullOrEmpty(json))
{
Debug.Log("File not found!");
return;
}
foreach (var nd in agvNodeMap.agvNodeData)
{
CreateNode(nd);
}
LoadNodeConnections();
}
public void Save()
{
string json = JsonConvert.SerializeObject(agvNodeMap);
var data=StandaloneFileBrowser.SaveFilePanel("AGV Node Dialog", "", "agvnodedata", "json");
if (!string.IsNullOrEmpty(data.Name))
{
FileStream f = new FileStream(data.Name, FileMode.Create, FileAccess.Write);
StreamWriter writer = new StreamWriter(f, System.Text.Encoding.Unicode);
writer.Write(json);
writer.Close();
}
}
public void DrawMarker(bool flag)
{
if (flag)
{
nodeTarget = Instantiate(markerPrefab);
}
else
{
if (nodeTarget)
{
Destroy(nodeTarget);
}
}
}
void MoveDrawTarget(RaycastHit hit, Component comp)
{
if (nodeTarget)
{
nodeTarget.transform.position = hit.point;
}
}
void CreateNode(AGVNodeClass nodedata)
{
if (nodeTable.ContainsKey(nodedata.id))
{
return;
}
GameObject go = Instantiate(nodePrefab);
var objNode = go.GetComponent<AGVNode>();
nodeTable.Add(nodedata.id, objNode);
objNode.Initialize(nodedata);
var x = float.Parse(nodedata.x);
var y = float.Parse(nodedata.y);
var z = float.Parse(nodedata.z);
go.transform.position = new Vector3(x, y, z);
}
void LoadNodeConnections()
{
foreach (var nodedata in nodeTable.Values)
{
foreach (var c in nodedata.nodeClass.linkedNodID)
{
onNodeConnectionAdded?.Invoke(nodeTable[nodedata.nodeClass.id], nodeTable[c]);
}
}
}
public void ONClickGround(RaycastHit hit, Component comp)
{
if (nodeGizmoController.GetGizmoHover() || nodeSelectMode == NodeSelectMode.Idle)
{
return;
}
DeselectNode();
if (nodeSelectMode == NodeSelectMode.Draw)
{
GameObject go = Instantiate(nodePrefab);
go.transform.position = hit.point;
var objNode = go.GetComponent<AGVNode>();
int maxid = int.Parse(agvNodeMap.maxid);
maxid++;
AGVNodeClass objNodeClass = new AGVNodeClass();
objNodeClass.id = maxid.ToString();
objNodeClass.x = hit.point.x.ToString();
objNodeClass.y = hit.point.y.ToString();
objNodeClass.z = hit.point.z.ToString();
objNode.Initialize(objNodeClass);
agvNodeMap.maxid = maxid.ToString();
agvNodeMap.agvNodeData.Add(objNode.nodeClass);
nodeTable.Add(maxid.ToString(), objNode);
}
}
public void AddNode()
{
if (!currentlySelectedNode)
{
return;
}
GameObject NewNode = Instantiate(nodePrefab, currentlySelectedNode.transform.position + Vector3.right, Quaternion.identity);
AGVNode node = NewNode.GetComponent<AGVNode>();
int maxid = int.Parse(agvNodeMap.maxid);
maxid++;
agvNodeMap.maxid = maxid.ToString();
AGVNodeClass nodeClass = new AGVNodeClass();
nodeClass.id = maxid.ToString();
nodeClass.x = (currentlySelectedNode.transform.position.x + 1f).ToString();
nodeClass.y = (currentlySelectedNode.transform.position.y).ToString();
nodeClass.z = (currentlySelectedNode.transform.position.z).ToString();
node.Initialize(nodeClass);
nodeTable.Add(maxid.ToString(), node);
currentlySelectedNode.nodeClass.linkedNodID.Add(maxid.ToString());
node.nodeClass.linkedNodID.Add(currentlySelectedNode.nodeClass.id);
agvNodeMap.agvNodeData.Add(node.nodeClass);
onNodeConnectionAdded?.Invoke(currentlySelectedNode, node);
SelectNode(node);
}
public void RemoveNode()
{
if (!currentlySelectedNode)
{
return;
}
foreach (var c in currentlySelectedNode.nodeClass.linkedNodID)
{
onNodeConnectionRemoved?.Invoke(currentlySelectedNode, nodeTable[c]);
nodeTable[c].nodeClass.linkedNodID.Remove(currentlySelectedNode.nodeClass.id);
}
agvNodeMap.agvNodeData.Remove(currentlySelectedNode.nodeClass);
foreach (var n in agvNodeMap.agvNodeData)
{
n.linkedNodID.Remove(currentlySelectedNode.nodeClass.id);
}
Destroy(currentlySelectedNode.gameObject);
DeselectNode();
}
public void NodeTypeChange(int index)
{
if (currentlySelectedNode)
{
currentlySelectedNode.nodeClass.type = (AGVNodeType)index;
nodeTable[currentlySelectedNode.nodeClass.id].nodeClass.type = (AGVNodeType)index;
agvNodeMap.agvNodeData.Find(n => n.id == currentlySelectedNode.nodeClass.id).type = (AGVNodeType)index;
}
}
public void RemoveNode(AGVNode node)
{
if (!node)
{
return;
}
foreach (var c in node.nodeClass.linkedNodID)
{
onNodeConnectionRemoved?.Invoke(node, nodeTable[c]);
nodeTable[c].nodeClass.linkedNodID.Remove(node.nodeClass.id);
}
agvNodeMap.agvNodeData.Remove(node.nodeClass);
foreach (var n in agvNodeMap.agvNodeData)
{
n.linkedNodID.Remove(node.nodeClass.id);
}
Destroy(node.gameObject);
DeselectNode();
}
public void ClearNodes()
{
foreach (var n in nodeTable)
{
RemoveNode(n.Value);
}
nodeTable.Clear();
selectedNodeSequence.Clear();
onNodeSequenceUpdated?.Invoke(selectedNodeSequence);
}
public void ordertoAGV()
{
if (selectedNodeSequence.Count <= 1)
{
return;
}
onNodeSequenceOrdered?.Invoke(selectedNodeSequence);
for (int i = 0; i < selectedNodeSequence.Count; i++)
{
if (i < selectedNodeSequence.Count - 1)
{
selectedNodeSequence[i].nodeClass.linkedNodID.Add(selectedNodeSequence[i+1].nodeClass.id);
selectedNodeSequence[i + 1].nodeClass.linkedNodID.Add(selectedNodeSequence[i].nodeClass.id);
}
else
{
selectedNodeSequence[i].nodeClass.linkedNodID.Add(selectedNodeSequence[0].nodeClass.id);
selectedNodeSequence[0].nodeClass.linkedNodID.Add(selectedNodeSequence[i].nodeClass.id);
}
}
}
public void OrderNodeAdd(AGVNode node)
{
if (selectedNodeSequence.Contains(node))
{
return;
}
node.SetColor(new Color(0f, 0.5f, 0f));
selectedNodeSequence.Add(node);
onNodeSequenceUpdated?.Invoke(selectedNodeSequence);
}
public void OrderNodeRemove(AGVNode node)
{
if (!selectedNodeSequence.Contains(node))
{
return;
}
node.DeleteColor();
selectedNodeSequence.Remove(node);
onNodeSequenceUpdated?.Invoke(selectedNodeSequence);
}
public void StatusEnterEvent()
{
var raycaster = FindSingle<Raycaster>();
FindSingle<UserInputManager>().SetHandler(myHandler);
raycaster.AddEvent(Raycaster.EventType.FirstLeftClickOnly, typeof(AGVNode), OnClickAGVNode);
raycaster.AddEvent(Raycaster.EventType.Stay, typeof(Map), MoveDrawTarget);
raycaster.AddEvent(Raycaster.EventType.FirstLeftClickOnly, typeof(Map), ONClickGround);
}
public void StatusExitEvent()
{
var raycaster = FindSingle<Raycaster>();
FindSingle<UserInputManager>().RemoveHandler(myHandler);
raycaster.RemoveEvent(Raycaster.EventType.FirstLeftClickOnly, typeof(AGVNode), OnClickAGVNode);
raycaster.RemoveEvent(Raycaster.EventType.Stay, typeof(Map), MoveDrawTarget);
raycaster.RemoveEvent(Raycaster.EventType.FirstLeftClickOnly, typeof(Map), ONClickGround);
}
public InputHandler GetInputHandler()
{
var getKeyActions = new Dictionary<KeyCode, Action>();
var downKeyActions = new Dictionary<KeyCode, Action>();
var upKeyActions = new Dictionary<KeyCode, Action>();
getKeyActions.Add(KeyCode.Alpha1, ()=>ChangeSelectMode(NodeSelectMode.Draw));
getKeyActions.Add(KeyCode.Alpha2, () => ChangeSelectMode(NodeSelectMode.Select));
getKeyActions.Add(KeyCode.Alpha3, () => ChangeSelectMode(NodeSelectMode.Setting));
getKeyActions.Add(KeyCode.Alpha4, () => ChangeSelectMode(NodeSelectMode.SelectRunNode));
getKeyActions.Add(KeyCode.Escape, () => ChangeSelectMode(NodeSelectMode.Idle));
var handler = new InputHandler(getKeyActions, downKeyActions, upKeyActions);
return handler;
}
protected override void OnDestroy()
{
//vistaOpenFileDialog.Dispose();
//saveFileDialog.Dispose();
}
}
}