using Cysharp.Threading.Tasks; using Simulator.Config; using Simulator.Data; using Simulator.Data.Transport; using System; using System.Collections.Generic; using UnityEngine; using UVC.Core; using UVC.Data; using UVC.Data.Core; using UVC.Data.Mqtt; using UVC.Network; using UVC.Pool; namespace Simulator.Data { public class ComponentsManager : SingletonScene { private readonly Dictionary prefabPaths = new Dictionary() { {"source","prefabs/pallet"}, {"queue","prefabs/queue"}, {"rack","prefabs/rack"}, {"sink","prefabs/Sink_Container"}, {"asrs","prefabs/ASRS"}, }; public Dictionary componentDatas = new Dictionary(); Dictionary dataMapperDict = new Dictionary(); private GameObjectPool? sourcePool; private GameObjectPool? sinkPool; private GameObjectPool? queuePool; private GameObjectPool? rackPool; private GameObjectPool? asrsPool; public LogicDetailData logicDetailData; public SimulatorCodeDataClass codedata; public GameObjectPool SourcePool { get { if (sourcePool == null) { Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return sourcePool!; } } public GameObjectPool SinkPool { get { if (sourcePool == null) { Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return sinkPool!; } } public GameObjectPool QueuePool { get { if (queuePool == null) { Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return queuePool!; } } public GameObjectPool RackPool { get { if (rackPool == null) { Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return rackPool!; } } public GameObjectPool AsrsPool { get { if (asrsPool == null) { Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first."); } return asrsPool!; } } protected override void Init() { InitializeSourcePoolAsync().ContinueWith(() => { var sourceDataMask = new DataMask(); sourceDataMask.ObjectName = "Source"; // AGV 객체의 이름을 설정합니다. sourceDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다. sourceDataMask["component_id"] = ""; sourceDataMask["event_name"] = ""; sourceDataMask["timestamp"] = new DateTime(); sourceDataMask["data"] = new DataMask() { ["entity_ids"] = new List(), ["total_entity"] = 0 }; DataMapper sourceMapper = new DataMapper(sourceDataMask); dataMapperDict.Add(ComponentType.Source, sourceMapper); }); InitializeSinkPoolAsync().ContinueWith(() => { var sinkDataMask = new DataMask(); sinkDataMask.ObjectName = "Sink"; // AGV 객체의 이름을 설정합니다. sinkDataMask.ObjectIdKey = "component_id"; // AGV의 고유 식별자로 사용할 키를 설정합니다. sinkDataMask["component_id"] = ""; sinkDataMask["event_name"] = ""; sinkDataMask["timestamp"] = new DateTime(); sinkDataMask["data"] = new DataMask() { ["entity_ids"] = new List(), }; DataMapper sinkmapper = new DataMapper(sinkDataMask); dataMapperDict.Add(ComponentType.Sink, sinkmapper); }); InitializeQueuePoolAsync().ContinueWith(() => { dataMapperDict.Add(ComponentType.Queue, null); }); InitializeRackPoolAsync().ContinueWith(() => { var rackDataMask = new DataMask(); rackDataMask.ObjectName = "Rack"; rackDataMask.ObjectIdKey = "component_id"; rackDataMask["component_id"] = ""; rackDataMask["event_name"] = ""; rackDataMask["timestamp"] = new DateTime(); rackDataMask["data"] = new DataMask() { ["entity_id"] = "", ["coordinates"] = new DataMask() { ["x"] = 0, ["y"] = 0, ["z"] = 0 } }; DataMapper rackmapper = new DataMapper(rackDataMask); dataMapperDict.Add(ComponentType.Rack, rackmapper); }); InitializeAsrsPoolAsync().ContinueWith(() => { var asrsDataMask = new DataMask(); DataMapper asrsmapper = new DataMapper(asrsDataMask); dataMapperDict.Add(ComponentType.ASRS, asrsmapper); }); testRequest(); } private async void testRequest() { var data = await HttpRequester.RequestGet($"{Constants.HTTP_DOMAIN}/simulation/logics/61", null, null, true); logicDetailData = data.data.data; SimulatorCreateRequestParameter param = new SimulatorCreateRequestParameter(); param.speed = SimulationConfig.speed; Dictionary body = new Dictionary() { { "projectId",18 }, { "logicId",61 }, { "logicData",null }, { "name","새 시뮬레이션2" }, { "parameters",param } }; //var cdata = await HttpRequester.RequestPost($"{Constants.HTTP_DOMAIN}/simulation/histories", body, null, true); //codedata = cdata; //SimulationConfig.SimulationCode = codedata.data.data.simulationCode; if (data.data.data.production_system.conveyors != null && data.data.data.production_system.conveyors.Count >= 1) { ConveyorManager.Instance.Build(data.data.data.production_system.conveyors); } if (data.data.data.transport_system != null) { if (data.data.data.transport_system.node_networks != null && data.data.data.transport_system.node_networks.Count >= 1) { AGVNodeManager.Instance.SpawnNode(data.data.data.transport_system.node_networks[0].nodes); AGVNodeManager.Instance.LinkNode(data.data.data.transport_system.node_networks[0].paths); } if (data.data.data.transport_system.transport_managers != null && data.data.data.transport_system.transport_managers.Count >= 1) { if (data.data.data.transport_system.transport_managers[0].vehicle_fleets != null && data.data.data.transport_system.transport_managers[0].vehicle_fleets.Count >= 1) { AGVManager.Instance.InitAGV(data.data.data.transport_system.transport_managers[0].vehicle_fleets[0].vehicles); } } } //SpawnComponents(data.data.data); //SubscribeTopic(); //DataRepository.Instance.MqttReceiver.Start(); } void SubscribeTopic() { foreach (var componentdata in componentDatas) { DataRepository.Instance.MqttReceiver.AddTopic($"simulation/{codedata.data.data.simulationCode}/components/+/{componentdata.Key}/#"); var mqttConfig = new MqttSubscriptionConfig($"simulation/{SimulationConfig.SimulationCode}/components/+/{componentdata.Key}/#"); mqttConfig.SetDataMapper(dataMapperDict[componentdata.Value.componentType]); mqttConfig.SetHandler((value) => OnUpdateData(value, componentdata.Value.componentType)); //mqttConfig.SetHandler((value)=>Debug.Log(value)); DataRepository.Instance.MqttReceiver.Add(mqttConfig); } } public void OnUpdateData(IDataObject data, ComponentType type) { if (data == null) return; DataObject? obj = data as DataObject; if (obj == null) return; //Debug.Log($"OnUpdateData:{obj}, {obj["data"]}"); switch (type) { case ComponentType.Source: if (string.Equals(obj.GetString("event_name"), "completed")) { SourceComponent? source = sourcePool.GetItem(obj.GetString("component_id")!); source.GetModelData(obj); } break; case ComponentType.Sink: if (string.Equals(obj.GetString("event_name"), "completed")) { SinkComponent? sink = sinkPool.GetItem(obj.GetString("component_id")!); sink.GetModelData(obj); } break; case ComponentType.Queue: if (string.Equals(obj.GetString("event_name"), "completed")) { QueueComponent? queue = QueuePool.GetItem(obj.GetString("component_id")!); queue.GetModelData(obj); } break; case ComponentType.Rack: if (string.Equals(obj.GetString("event_name"), "arrived")) { RackComponent? rack = rackPool.GetItem(obj.GetString("component_id")!); rack.GetModelData(obj); } break; case ComponentType.ASRS: ASRSComponent? asrs = asrsPool.GetItem(obj.GetString("component_id")!); asrs.GetModelData(obj); break; } } private async UniTask InitializeSourcePoolAsync() { if (sourcePool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["source"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["source"]}"); return; } sourcePool = new GameObjectPool(prefab, transform); } private async UniTask InitializeSinkPoolAsync() { if (sinkPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["sink"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["sink"]}"); return; } sinkPool = new GameObjectPool(prefab, transform); } private async UniTask InitializeQueuePoolAsync() { if (queuePool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["queue"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["queue"]}"); return; } queuePool = new GameObjectPool(prefab, transform); } private async UniTask InitializeRackPoolAsync() { if (rackPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["rack"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["rack"]}"); return; } rackPool = new GameObjectPool(prefab, transform); } private async UniTask InitializeAsrsPoolAsync() { if (asrsPool != null) return; var prefab = await Resources.LoadAsync(prefabPaths["asrs"]) as GameObject; if (prefab == null) { Debug.LogError($"Prefab not found at path: {prefabPaths["asrs"]}"); return; } asrsPool = new GameObjectPool(prefab, transform); } private void SpawnComponents(LogicDetailData data) { foreach (var component in data.production_system.sources) { var source = sourcePool.GetItem($"{component.name}"); source.componentType = ComponentType.Source; source.SetComponent(component); source.SetPosition(); componentDatas.Add(component.name, source); } foreach (var component in data.production_system.sinks) { var sink = sinkPool.GetItem($"{component.name}"); sink.componentType = ComponentType.Sink; sink.SetComponent(component); sink.SetPosition(); componentDatas.Add(component.name, sink); } foreach (var component in data.infrastructure.queues) { var queue = queuePool.GetItem($"{component.name}"); queue.componentType = ComponentType.Queue; queue.SetComponent(component); queue.SetPosition(); componentDatas.Add(component.name, queue); } if (data.production_system.racks != null) { foreach (var component in data.production_system.racks) { var rack = rackPool.GetItem($"{component.name}"); rack.componentType = ComponentType.Rack; rack.SetComponent(component); componentDatas.Add(component.name, rack); } } if (data.production_system.asrs != null) { foreach (var component in data.production_system.asrs) { var asrs = asrsPool.GetItem($"{component.name}"); asrs.componentType = ComponentType.ASRS; asrs.SetComponent(component); componentDatas.Add(component.name, asrs); } } } } }