Files
XRLib/Assets/Scripts/Simulator/Components/ComponentsManager.cs
2025-11-04 19:02:01 +09:00

386 lines
15 KiB
C#

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<ComponentsManager>
{
private readonly Dictionary<string, string> prefabPaths = new Dictionary<string, string>()
{
{"source","prefabs/pallet"},
{"queue","prefabs/queue"},
{"rack","prefabs/rack"},
{"sink","prefabs/Sink_Container"},
{"asrs","prefabs/ASRS"},
};
public Dictionary<string, ComponentBase> componentDatas = new Dictionary<string, ComponentBase>();
Dictionary<ComponentType, DataMapper> dataMapperDict = new Dictionary<ComponentType, DataMapper>();
private GameObjectPool<SourceComponent>? sourcePool;
private GameObjectPool<SinkComponent>? sinkPool;
private GameObjectPool<QueueComponent>? queuePool;
private GameObjectPool<RackComponent>? rackPool;
private GameObjectPool<ASRSComponent>? asrsPool;
public LogicDetailData logicDetailData;
public SimulatorCodeDataClass codedata;
public GameObjectPool<SourceComponent> SourcePool
{
get
{
if (sourcePool == null)
{
Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return sourcePool!;
}
}
public GameObjectPool<SinkComponent> SinkPool
{
get
{
if (sourcePool == null)
{
Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return sinkPool!;
}
}
public GameObjectPool<QueueComponent> QueuePool
{
get
{
if (queuePool == null)
{
Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return queuePool!;
}
}
public GameObjectPool<RackComponent> RackPool
{
get
{
if (rackPool == null)
{
Debug.LogError("Pool is not initialized. Please call InitializePoolAsync first.");
}
return rackPool!;
}
}
public GameObjectPool<ASRSComponent> 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<string>(),
["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<string>(),
};
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<Totaljson>($"{Constants.HTTP_DOMAIN}/simulation/logics/61", null, null, true);
logicDetailData = data.data.data;
SimulatorCreateRequestParameter param = new SimulatorCreateRequestParameter();
param.speed = SimulationConfig.speed;
Dictionary<string, object> body = new Dictionary<string, object>()
{
{ "projectId",18 },
{ "logicId",61 },
{ "logicData",null },
{ "name","새 시뮬레이션2" },
{ "parameters",param }
};
//var cdata = await HttpRequester.RequestPost<SimulatorCodeDataClass>($"{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<GameObject>(prefabPaths["source"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["source"]}");
return;
}
sourcePool = new GameObjectPool<SourceComponent>(prefab, transform);
}
private async UniTask InitializeSinkPoolAsync()
{
if (sinkPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["sink"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["sink"]}");
return;
}
sinkPool = new GameObjectPool<SinkComponent>(prefab, transform);
}
private async UniTask InitializeQueuePoolAsync()
{
if (queuePool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["queue"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["queue"]}");
return;
}
queuePool = new GameObjectPool<QueueComponent>(prefab, transform);
}
private async UniTask InitializeRackPoolAsync()
{
if (rackPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["rack"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["rack"]}");
return;
}
rackPool = new GameObjectPool<RackComponent>(prefab, transform);
}
private async UniTask InitializeAsrsPoolAsync()
{
if (asrsPool != null) return;
var prefab = await Resources.LoadAsync<GameObject>(prefabPaths["asrs"]) as GameObject;
if (prefab == null)
{
Debug.LogError($"Prefab not found at path: {prefabPaths["asrs"]}");
return;
}
asrsPool = new GameObjectPool<ASRSComponent>(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);
}
}
}
}
}