272 lines
12 KiB
C#
272 lines
12 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UVC.Core;
|
|
|
|
namespace UVC.Factory.Component
|
|
{
|
|
/// <summary>
|
|
/// 씬에 존재하는 모든 FactoryObject 인스턴스를 관리하는 싱글톤 클래스입니다.
|
|
/// 이 매니저를 통해 팩토리 객체를 등록, 등록 해제 및 검색할 수 있습니다.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// SingletonScene을 상속받아 구현되었으므로, `FactoryObjectManager.Instance`를 통해 씬의 어디에서든 쉽게 접근할 수 있습니다.
|
|
/// FactoryObject는 Info 속성이 설정될 때 자동으로 이 매니저에 등록되며, 파괴될 때 자동으로 등록 해제됩니다.
|
|
/// 따라서 개발자가 직접 Register/Unregister 메서드를 호출할 일은 거의 없습니다.
|
|
/// </remarks>
|
|
/// <example>
|
|
/// 다음은 FactoryObjectManager를 사용하여 씬에 있는 특정 기계를 찾고 제어하는 예제입니다.
|
|
/// <code>
|
|
/// using UnityEngine;
|
|
/// using UVC.Factory.Component;
|
|
/// using UVC.Data;
|
|
///
|
|
/// public class ControlPanel : MonoBehaviour
|
|
/// {
|
|
/// void Start()
|
|
/// {
|
|
/// // 가정: 씬 어딘가에 이미 FactoryObject(예: MachineObject)가 생성되어 있고,
|
|
/// // Info 속성이 설정되어 FactoryObjectManager에 등록된 상태입니다.
|
|
/// //
|
|
/// // var machine = new MachineObject();
|
|
/// // machine.Info = new FactoryObjectInfo("Drill-01", "MC-1024", ...);
|
|
/// }
|
|
///
|
|
/// // UI 버튼 클릭 시 호출될 함수
|
|
/// public void OnFindAndStartMachineButtonClick()
|
|
/// {
|
|
/// // 1. ID를 사용하여 FactoryObjectManager에서 특정 기계를 찾습니다.
|
|
/// FactoryObject machine = FactoryObjectManager.Instance.FindById("MC-1024");
|
|
///
|
|
/// if (machine != null)
|
|
/// {
|
|
/// Debug.Log($"기계를 찾았습니다: {machine.Info.Name}");
|
|
///
|
|
/// // 2. 찾은 기계의 데이터를 업데이트하여 가동시킵니다.
|
|
/// var command = new DataObject { { "status", "running" } };
|
|
/// machine.UpdateData(command);
|
|
/// }
|
|
/// else
|
|
/// {
|
|
/// Debug.LogWarning("ID 'MC-1024'에 해당하는 기계를 찾을 수 없습니다.");
|
|
/// }
|
|
/// }
|
|
///
|
|
/// // 특정 구역의 모든 객체를 찾는 예시
|
|
/// public void OnFindAllObjectsInArea_A_ButtonClick()
|
|
/// {
|
|
/// // "Area-A" 구역에 있는 모든 객체를 찾습니다.
|
|
/// List<FactoryObject> objectsInArea = FactoryObjectManager.Instance.FindByArea("Area-A");
|
|
///
|
|
/// Debug.Log($"'Area-A' 구역에서 {objectsInArea.Count}개의 객체를 찾았습니다.");
|
|
///
|
|
/// foreach (var obj in objectsInArea)
|
|
/// {
|
|
/// Debug.Log($"- 객체 이름: {obj.Info.Name}, ID: {obj.Info.Id}");
|
|
/// }
|
|
/// }
|
|
/// }
|
|
/// </code>
|
|
/// </example>
|
|
public class FactoryObjectManager : SingletonScene<FactoryObjectManager>
|
|
{
|
|
/// <summary>
|
|
/// 등록된 모든 FactoryObject를 저장하는 딕셔너리입니다.
|
|
/// Key는 객체의 식별 정보인 FactoryObjectInfo이고, Value는 FactoryObject 인스턴스입니다.
|
|
/// </summary>
|
|
public Dictionary<FactoryObjectInfo, FactoryObject> FactoryObjects { get; private set; } = new Dictionary<FactoryObjectInfo, FactoryObject>();
|
|
|
|
/// <summary>
|
|
/// 새로운 FactoryObject를 매니저에 등록합니다.
|
|
/// 일반적으로 FactoryObject의 Info 속성이 설정될 때 자동으로 호출됩니다.
|
|
/// </summary>
|
|
/// <param name="factoryObject">등록할 FactoryObject 인스턴스입니다.</param>
|
|
/// <exception cref="ArgumentNullException">factoryObject 또는 factoryObject.Info가 null일 때 발생합니다.</exception>
|
|
public void RegisterFactoryObject(FactoryObject factoryObject)
|
|
{
|
|
if (factoryObject == null || factoryObject.Info == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(factoryObject), "FactoryObject cannot be null.");
|
|
}
|
|
if (!FactoryObjects.ContainsKey(factoryObject.Info!))
|
|
{
|
|
FactoryObjects.Add(factoryObject.Info!, factoryObject);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 매니저에서 FactoryObject의 등록을 해제합니다.
|
|
/// 일반적으로 FactoryObject가 파괴될 때(OnDestroy) 자동으로 호출됩니다.
|
|
/// </summary>
|
|
/// <param name="factoryObjectInfo">등록 해제할 객체의 FactoryObjectInfo입니다.</param>
|
|
public void UnregisterFactoryObject(FactoryObjectInfo factoryObjectInfo)
|
|
{
|
|
if (factoryObjectInfo == null)
|
|
{
|
|
//throw new ArgumentNullException(nameof(factoryObjectInfo), "factoryObjectInfo cannot be null.");
|
|
return; // Do not throw exception, just return if null
|
|
}
|
|
FactoryObjects.Remove(factoryObjectInfo);
|
|
}
|
|
|
|
/// <summary>
|
|
/// FactoryObjectInfo를 사용하여 등록된 FactoryObject 인스턴스를 가져옵니다.
|
|
/// </summary>
|
|
/// <param name="factoryObjectInfo">찾고자 하는 객체의 FactoryObjectInfo입니다.</param>
|
|
/// <returns>발견된 FactoryObject 인스턴스. 없으면 null을 반환합니다.</returns>
|
|
/// <exception cref="ArgumentNullException">factoryObjectInfo가 null일 때 발생합니다.</exception>
|
|
public FactoryObject? GetFactoryObject(FactoryObjectInfo factoryObjectInfo)
|
|
{
|
|
if (factoryObjectInfo == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(factoryObjectInfo), "factoryObjectInfo cannot be null.");
|
|
}
|
|
FactoryObjects.TryGetValue(factoryObjectInfo, out var factoryObject);
|
|
return factoryObject;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 객체의 이름(Name)으로 FactoryObject를 검색합니다. 대소문자를 구분하지 않습니다.
|
|
/// </summary>
|
|
/// <param name="name">찾고자 하는 객체의 이름입니다.</param>
|
|
/// <returns>처음으로 발견된 일치하는 FactoryObject. 없으면 null을 반환합니다.</returns>
|
|
public FactoryObject? FindByName(string name)
|
|
{
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
if (kvp.Key.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return kvp.Value;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 객체의 고유 ID로 FactoryObject를 검색합니다. 대소문자를 구분하지 않습니다.
|
|
/// </summary>
|
|
/// <param name="id">찾고자 하는 객체의 ID입니다.</param>
|
|
/// <returns>처음으로 발견된 일치하는 FactoryObject. 없으면 null을 반환합니다.</returns>
|
|
public FactoryObject? FindById(string id)
|
|
{
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
if (kvp.Key.Id.Equals(id, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return kvp.Value;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 객체의 위치(Position) 정보로 FactoryObject를 검색합니다. 대소문자를 구분하지 않습니다.
|
|
/// </summary>
|
|
/// <param name="position">찾고자 하는 객체의 위치 정보입니다.</param>
|
|
/// <returns>처음으로 발견된 일치하는 FactoryObject. 없으면 null을 반환합니다.</returns>
|
|
public FactoryObject? FindByPosition(string position)
|
|
{
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
if (kvp.Key.Position.Equals(position, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return kvp.Value;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 구역(Area)에 속한 모든 FactoryObject를 검색합니다. 대소문자를 구분하지 않습니다.
|
|
/// </summary>
|
|
/// <param name="area">찾고자 하는 구역의 이름입니다.</param>
|
|
/// <returns>발견된 모든 FactoryObject의 리스트. 없으면 빈 리스트를 반환합니다.</returns>
|
|
public List<FactoryObject> FindByArea(string area)
|
|
{
|
|
List<FactoryObject> foundObjects = new List<FactoryObject>();
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
if (kvp.Key.Area.Equals(area, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
foundObjects.Add(kvp.Value);
|
|
}
|
|
}
|
|
return foundObjects;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 특정 층(Floor)에 속한 모든 FactoryObject를 검색합니다. 대소문자를 구분하지 않습니다.
|
|
/// </summary>
|
|
/// <param name="floor">찾고자 하는 층의 이름입니다.</param>
|
|
/// <returns>발견된 모든 FactoryObject의 리스트. 없으면 빈 리스트를 반환합니다.</returns>
|
|
public List<FactoryObject> FindByFloor(string floor)
|
|
{
|
|
List<FactoryObject> foundObjects = new List<FactoryObject>();
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
if (kvp.Key.Floor.Equals(floor, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
foundObjects.Add(kvp.Value);
|
|
}
|
|
}
|
|
return foundObjects;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 전체 FactoryObjectInfo를 반환합니다.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<FactoryObjectInfo> GetAllFactoryObjectInfos()
|
|
{
|
|
List<FactoryObjectInfo> infos = new List<FactoryObjectInfo>();
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
infos.Add(kvp.Key);
|
|
}
|
|
return infos;
|
|
}
|
|
|
|
/// <summary>
|
|
/// FactoryObject 인스턴스의 리스트를 반환합니다.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<FactoryObject> GetAllFactoryObjects()
|
|
{
|
|
List<FactoryObject> objects = new List<FactoryObject>();
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
objects.Add(kvp.Value);
|
|
}
|
|
return objects;
|
|
}
|
|
|
|
/// <summary>
|
|
/// category 이름을 key, FactoryObjectInfo 리스트가 value인 딕셔너리를 반환합니다.
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public SortedDictionary<string, List<FactoryObjectInfo>> GetFactoryObjectInfosByCategory()
|
|
{
|
|
SortedDictionary<string, List<FactoryObjectInfo>> categoryDict = new SortedDictionary<string, List<FactoryObjectInfo>>();
|
|
foreach (var kvp in FactoryObjects)
|
|
{
|
|
var info = kvp.Key;
|
|
if (!categoryDict.ContainsKey(info.Category))
|
|
{
|
|
categoryDict[info.Category] = new List<FactoryObjectInfo>();
|
|
}
|
|
categoryDict[info.Category].Add(info);
|
|
}
|
|
|
|
//key 순 정렬
|
|
|
|
//name 순 정렬
|
|
foreach (var key in categoryDict.Keys)
|
|
{
|
|
categoryDict[key].Sort((a, b) => a.Name.CompareTo(b.Name));
|
|
}
|
|
return categoryDict;
|
|
}
|
|
|
|
}
|
|
}
|