using Cysharp.Threading.Tasks; using System; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.SocialPlatforms; using UVC.Core; using UVC.Data; using UVC.Data.Core; using UVC.Data.Mqtt; using Simulator.Config; using UVC.Pool; namespace Simulator.Data.Transport { public enum AGVDataType { Moving, LoadingStart, LoadingEnd, UnLoadingStart, UnLoadingEnd, Idle } public class AGVManager : SingletonScene { private readonly Dictionary prefabPaths = new Dictionary() { {"agv","prefabs/agv"}, {"afl","prefabs/afl"}, {"forkLift","prefabs/forkLift"} }; private GameObjectPool? agvPool; public GameObjectPool AGVPool { get { if (agvPool == null) { //Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return agvPool!; } } private GameObjectPool? aflPool; public GameObjectPool AFLPool { get { if (aflPool == null) { //Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return aflPool!; } } private GameObjectPool? forkLiftPool; public GameObjectPool ForkLiftPool { get { if (forkLiftPool == null) { //Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return forkLiftPool!; } } private DataMapper agvMoveMapper; private DataMapper agvLoadMapper; private DataMapper agvUnLoadMapper; private Dictionary agvMap = new Dictionary(); protected override void Init() { InitializeAGVPoolAsync().ContinueWith(() => { var agvMoveDataMask = new DataMask(); agvMoveDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다. agvMoveDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다. agvMoveDataMask["component_id"] = ""; agvMoveDataMask["component_type"] = ""; agvMoveDataMask["event_name"] = ""; agvMoveDataMask["timestamp"] = new DateTime(); agvMoveDataMask["data"] = new DataMask() { ["from_node"] = "", ["to_node"] = "", ["timing"] = new DataMask() { ["duration"] = new DataMask() { ["real_seconds"] = 0.0f } } }; agvMoveMapper = new DataMapper(agvMoveDataMask); var agvLoadDataMask = new DataMask(); agvLoadDataMask.ObjectName = "agv"; // AGV 객체의 이름을 설정합니다. agvLoadDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다. agvLoadDataMask["component_id"] = ""; agvLoadDataMask["component_type"] = ""; agvLoadDataMask["event_name"] = ""; agvLoadDataMask["timestamp"] = new DateTime(); agvLoadDataMask["data"] = new DataMask() { ["from_node"] = "", ["to_node"] = "", ["entity_ids"] = new DataMask() { ["entity_id"] = "" } }; agvLoadMapper = new DataMapper(agvLoadDataMask); var agvUnLoadDataMask = new DataMask(); agvUnLoadMapper = new DataMapper(agvUnLoadDataMask); }); InitializeAFLPoolAsync().ContinueWith(() => { }); InitializeForkLiftPoolAsync().ContinueWith(() => { }); } public void SpawnAGV(List datas, string type) { foreach (var data in datas) { switch (type) { case "agv": if (data.initial_node == null) { return; } var agv = agvPool.GetItem($"{data.name}"); agv.data = data; agv.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node)); agvMap.Add(data.name, agv); agv.dataType = AGVDataType.Idle; PlayerPropertyDataBase.Instance.CollectSpawnAGV(agv); break; case "afl": var afl = aflPool.GetItem($"{data.name}"); afl.data = data; afl.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node)); agvMap.Add(data.name, afl); afl.dataType = AGVDataType.Idle; PlayerPropertyDataBase.Instance.CollectSpawnAGV(afl); break; case "forklift": var forkLift = forkLiftPool.GetItem($"{data.name}"); forkLift.data = data; forkLift.UpdatePosition(AGVNodeManager.Instance.GetNodePosition(data.initial_node)); agvMap.Add(data.name, forkLift); forkLift.dataType = AGVDataType.Idle; PlayerPropertyDataBase.Instance.CollectSpawnAGV(forkLift); break; } } } public void InitAGV(List datas) { foreach (var data in datas) { DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/moving"); var mqttConfigAGVMoving = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/moving"); mqttConfigAGVMoving.SetDataMapper(agvMoveMapper); mqttConfigAGVMoving.SetHandler((value) => OnUpdateData(value, AGVDataType.Moving)); DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVMoving); DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_end"); var mqttConfigAGVLoading = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_end"); mqttConfigAGVLoading.SetDataMapper(agvLoadMapper); mqttConfigAGVLoading.SetHandler((value) => OnUpdateData(value, AGVDataType.LoadingEnd)); DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVLoading); DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_start"); var mqttConfigAGVLoadingStart = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/loading_start"); mqttConfigAGVLoadingStart.SetDataMapper(agvLoadMapper); mqttConfigAGVLoadingStart.SetHandler((value) => OnUpdateData(value, AGVDataType.LoadingStart)); DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVLoading); DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_end"); var mqttConfigAGVUnLoading = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_end",false); mqttConfigAGVUnLoading.SetDataMapper(agvUnLoadMapper); mqttConfigAGVUnLoading.SetHandler((value) => OnUpdateData(value, AGVDataType.UnLoadingEnd)); DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVUnLoading); DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_start"); var mqttConfigAGVUnLoadingStart = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{data.name}/+/unloading_start"); mqttConfigAGVUnLoadingStart.SetDataMapper(agvUnLoadMapper); mqttConfigAGVUnLoadingStart.SetHandler((value) => OnUpdateData(value, AGVDataType.UnLoadingStart)); DataRepository.Instance.MqttReceiver.Add(mqttConfigAGVUnLoadingStart); } } public void OnUpdateData(IDataObject data, AGVDataType type) { if (data == null) return; DataObject? obj = data as DataObject; if (obj == null) return; var componentName = obj.GetString("component_id"); AGV agv = agvMap[componentName]; switch (type) { case AGVDataType.Moving: agv.SetTargetPosition(obj); agv.dataType = AGVDataType.Moving; break; case AGVDataType.LoadingEnd: agv.LoadEntity(obj); agv.dataType = AGVDataType.Idle; break; case AGVDataType.LoadingStart: agv.dataType = AGVDataType.LoadingStart; break; case AGVDataType.UnLoadingEnd: agv.UnLoadEntity(obj); agv.dataType = AGVDataType.Idle; break; case AGVDataType.UnLoadingStart: agv.dataType = AGVDataType.UnLoadingStart; break; } } private async UniTask InitializeAGVPoolAsync() { if (agvPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["agv"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["agv"]}"); return; } agvPool = new GameObjectPool(prefab, transform); } private async UniTask InitializeAFLPoolAsync() { if (aflPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["afl"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["afl"]}"); return; } aflPool = new GameObjectPool(prefab, transform); } private async UniTask InitializeForkLiftPoolAsync() { if (forkLiftPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["forkLift"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["forkLift"]}"); return; } forkLiftPool = new GameObjectPool(prefab, transform); } } }