From 750d38153d1e220c6b85778adab2fe81cc945a7b Mon Sep 17 00:00:00 2001 From: logonkhi Date: Fri, 27 Jun 2025 17:50:23 +0900 Subject: [PATCH] =?UTF-8?q?Pool=20=EC=A0=81=EC=9A=A9=20=EB=B2=84=EA=B7=B8?= =?UTF-8?q?=20=EC=9E=A1=EB=8A=94=20=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Prefabs/SampleProject/Factory/AGV.prefab | 72 ++- .../SampleProject/Factory/Alarm.prefab | 415 ++++++++++++++++++ .../SampleProject/Factory/Alarm.prefab.meta | 7 + .../SampleProject/Factory/AlarmIcon.prefab | 340 ++++++++++++++ .../Factory/AlarmIcon.prefab.meta | 7 + .../SampleProject/UI/InfoWindow.prefab | 259 +++++++++++ Assets/Scenes/SampleProject.unity | 156 +++++++ Assets/Scripts/SampleProject/AppMain.cs | 1 + Assets/Scripts/SampleProject/SceneMain.cs | 12 + Assets/Scripts/UVC/Data/DataArray.cs | 118 +++-- Assets/Scripts/UVC/Data/DataArrayPool.cs | 22 +- Assets/Scripts/UVC/Data/DataObject.cs | 137 +++++- Assets/Scripts/UVC/Data/DataObjectPool.cs | 38 +- Assets/Scripts/UVC/Data/DataRepository.cs | 3 +- Assets/Scripts/UVC/Data/HttpPipeLine.cs | 9 + Assets/Scripts/UVC/Data/IDataObject.cs | 3 +- Assets/Scripts/UVC/Data/MQTTPipeLine.cs | 20 +- .../Scripts/UVC/Factory/Alarm/AlarmManager.cs | 200 +++++++-- .../UVC/Factory/Alarm/AlarmUIController.cs | 40 +- .../UVC/Factory/Alarm/SingleAlarmIcon.cs | 43 +- Assets/Scripts/UVC/Factory/Component/AGV.cs | 75 ++-- .../UVC/Factory/Component/AGVManager.cs | 32 +- .../UVC/Factory/Component/FactoryObject.cs | 50 ++- .../Factory/Component/FactoryObjectManager.cs | 2 +- .../Scripts/UVC/Object3d/InteractiveObject.cs | 25 +- ...MonoBehaviourPool.cs => GameObjectPool.cs} | 57 ++- .../Scripts/UVC/Pool/GameObjectPool.cs.meta | 2 + .../UVC/Pool/MonoBehaviourPool.cs.meta | 2 - Assets/Scripts/UVC/UI/Info/InfoWindow.cs | 24 +- .../Scripts/UVC/UI/Menu/TopMenuController.cs | 17 +- Packages/manifest.json | 1 + Packages/packages-lock.json | 6 + 32 files changed, 1977 insertions(+), 218 deletions(-) create mode 100644 Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab create mode 100644 Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta create mode 100644 Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab create mode 100644 Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta rename Assets/Scripts/UVC/Pool/{MonoBehaviourPool.cs => GameObjectPool.cs} (83%) create mode 100644 Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta delete mode 100644 Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab b/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab index 5e341c0a..d9ee14cc 100644 --- a/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab +++ b/Assets/Resources/Prefabs/SampleProject/Factory/AGV.prefab @@ -10,9 +10,6 @@ GameObject: m_Component: - component: {fileID: 302300799186228596} - component: {fileID: 8488195170614820883} - - component: {fileID: 3820258601269832329} - - component: {fileID: 363746616583149630} - - component: {fileID: 5360656424770899642} m_Layer: 0 m_Name: AGV m_TagString: Untagged @@ -32,7 +29,8 @@ Transform: m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 - m_Children: [] + m_Children: + - {fileID: 8708419218786706813} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!114 &8488195170614820883 @@ -47,24 +45,72 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: bc083cb3e97c87446bc1a7db7b4ef9e4, type: 3} m_Name: m_EditorClassIdentifier: - moveSpeed: 1 - rotationSpeed: 1 + modelObject: {fileID: 7493524444357289953} + moveSpeed: 0.5 + rotationSpeed: 0.5 teleportDistanceThreshold: 5 ---- !u!33 &3820258601269832329 +--- !u!1 &6358428858938227828 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8708419218786706813} + - component: {fileID: 7493524444357289953} + - component: {fileID: 6887510220552103127} + - component: {fileID: 9132754914965147154} + - component: {fileID: 6486094733119401088} + m_Layer: 0 + m_Name: Cube + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &8708419218786706813 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6358428858938227828} + serializedVersion: 2 + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0.5, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 302300799186228596} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &7493524444357289953 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 6358428858938227828} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 369f10656ae555b4983fa3147fc56818, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!33 &6887510220552103127 MeshFilter: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1373625414374435398} + m_GameObject: {fileID: 6358428858938227828} m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0} ---- !u!23 &363746616583149630 +--- !u!23 &9132754914965147154 MeshRenderer: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1373625414374435398} + m_GameObject: {fileID: 6358428858938227828} m_Enabled: 1 m_CastShadows: 1 m_ReceiveShadows: 1 @@ -103,13 +149,13 @@ MeshRenderer: m_SortingLayer: 0 m_SortingOrder: 0 m_AdditionalVertexStreams: {fileID: 0} ---- !u!65 &5360656424770899642 +--- !u!65 &6486094733119401088 BoxCollider: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1373625414374435398} + m_GameObject: {fileID: 6358428858938227828} m_Material: {fileID: 0} m_IncludeLayers: serializedVersion: 2 @@ -118,7 +164,7 @@ BoxCollider: serializedVersion: 2 m_Bits: 0 m_LayerOverridePriority: 0 - m_IsTrigger: 1 + m_IsTrigger: 0 m_ProvidesContacts: 0 m_Enabled: 1 serializedVersion: 3 diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab new file mode 100644 index 00000000..88ac3a83 --- /dev/null +++ b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab @@ -0,0 +1,415 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &494093931030574861 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5765213305061083199} + - component: {fileID: 4826901156942800586} + - component: {fileID: 8650239058674280921} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5765213305061083199 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 494093931030574861} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2463437008278947656} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &4826901156942800586 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 494093931030574861} + m_CullTransparentMesh: 1 +--- !u!114 &8650239058674280921 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 494093931030574861} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: 0 + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2} + m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 36 + m_fontSizeBase: 36 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &952545100964675415 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8574585598928791195} + m_Layer: 5 + m_Name: expandedView + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8574585598928791195 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 952545100964675415} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 2463437008278947656} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &1828762385695490929 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 2463437008278947656} + - component: {fileID: 5380681345511526047} + m_Layer: 5 + m_Name: Alarm + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &2463437008278947656 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1828762385695490929} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5007029136827874888} + - {fileID: 5765213305061083199} + - {fileID: 8574585598928791195} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 100, y: 100} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5380681345511526047 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1828762385695490929} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 773fa02b59601044b8be752f78f63e55, type: 3} + m_Name: + m_EditorClassIdentifier: + clusterView: {fileID: 4918696741701580718} + alarmCountText: {fileID: 8650239058674280921} + expandedView: {fileID: 952545100964675415} + singleAlarmIconPrefab: {fileID: 7314511769243682470, guid: e9acc8c9a93a2b5409fc01661660b217, type: 3} +--- !u!1 &4918696741701580718 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5007029136827874888} + m_Layer: 5 + m_Name: clusterView + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5007029136827874888 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 4918696741701580718} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 7229327262419467602} + - {fileID: 1591538567731418999} + m_Father: {fileID: 2463437008278947656} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!1 &7297564150823027611 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7229327262419467602} + - component: {fileID: 7287393582081843390} + - component: {fileID: 4544043674251718843} + m_Layer: 5 + m_Name: shadow + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7229327262419467602 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7297564150823027611} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5007029136827874888} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 5, y: -5} + m_SizeDelta: {x: 10, y: 10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &7287393582081843390 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7297564150823027611} + m_CullTransparentMesh: 1 +--- !u!114 &4544043674251718843 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7297564150823027611} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 887145076, guid: 4cf3568ca3f55f64cb11447d139d7a3d, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7656214594090597472 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1591538567731418999} + - component: {fileID: 8641121927952400765} + - component: {fileID: 4970931623191621822} + m_Layer: 5 + m_Name: bg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1591538567731418999 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7656214594090597472} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 5007029136827874888} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8641121927952400765 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7656214594090597472} + m_CullTransparentMesh: 1 +--- !u!114 &4970931623191621822 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7656214594090597472} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -895992892, guid: 73d757b5d1b754245969af12daf01e78, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta new file mode 100644 index 00000000..3ecd0bd1 --- /dev/null +++ b/Assets/Resources/Prefabs/SampleProject/Factory/Alarm.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e8b88e69e607ee448806427e91440a8e +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab new file mode 100644 index 00000000..d2d29662 --- /dev/null +++ b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab @@ -0,0 +1,340 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &1326045257776503954 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8602533637707951236} + - component: {fileID: 5770335694761070239} + - component: {fileID: 2018211268787215362} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8602533637707951236 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1326045257776503954} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3374630250525829090} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: -20, y: -20} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5770335694761070239 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1326045257776503954} + m_CullTransparentMesh: 1 +--- !u!114 &2018211268787215362 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1326045257776503954} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: TR + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2} + m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4278190080 + m_fontColor: {r: 0, g: 0, b: 0, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 12 + m_fontSizeBase: 12 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 1 + m_VerticalAlignment: 256 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &3798696889335606665 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 6765948511015989509} + - component: {fileID: 2825211744860677609} + - component: {fileID: 7215137539608397115} + m_Layer: 5 + m_Name: shadow + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &6765948511015989509 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3798696889335606665} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3374630250525829090} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 5, y: -5} + m_SizeDelta: {x: 10, y: 10} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &2825211744860677609 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3798696889335606665} + m_CullTransparentMesh: 1 +--- !u!114 &7215137539608397115 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 3798696889335606665} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0, g: 0, b: 0, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 887145076, guid: 4cf3568ca3f55f64cb11447d139d7a3d, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &7314511769243682470 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 3374630250525829090} + - component: {fileID: 5545478218830425297} + m_Layer: 5 + m_Name: AlarmIcon + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &3374630250525829090 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7314511769243682470} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 6765948511015989509} + - {fileID: 5399931818953919527} + - {fileID: 8602533637707951236} + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0.5, y: 0.5} + m_AnchorMax: {x: 0.5, y: 0.5} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 100, y: 150} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!114 &5545478218830425297 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7314511769243682470} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: cd395cde180b3094a91d87699139bbcf, type: 3} + m_Name: + m_EditorClassIdentifier: + text: {fileID: 2018211268787215362} +--- !u!1 &8817008079317718099 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5399931818953919527} + - component: {fileID: 1290445261252787132} + - component: {fileID: 2283905710529375295} + m_Layer: 5 + m_Name: bg + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5399931818953919527 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8817008079317718099} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 3374630250525829090} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1290445261252787132 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8817008079317718099} + m_CullTransparentMesh: 1 +--- !u!114 &2283905710529375295 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8817008079317718099} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -895992892, guid: 73d757b5d1b754245969af12daf01e78, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 diff --git a/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta new file mode 100644 index 00000000..3825d7c4 --- /dev/null +++ b/Assets/Resources/Prefabs/SampleProject/Factory/AlarmIcon.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e9acc8c9a93a2b5409fc01661660b217 +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab b/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab index cd5c3e12..c2cb37bb 100644 --- a/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab +++ b/Assets/Resources/Prefabs/SampleProject/UI/InfoWindow.prefab @@ -208,6 +208,127 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &1844102171940980497 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1010396666164740167} + - component: {fileID: 380188952969839968} + - component: {fileID: 170663812404971233} + - component: {fileID: 8791400826399403740} + m_Layer: 5 + m_Name: CopyButton + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1010396666164740167 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1844102171940980497} + m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: + - {fileID: 5059140281209684741} + m_Father: {fileID: 4802890858156259540} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 1, y: 1} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: -20, y: -2} + m_SizeDelta: {x: 30, y: 15} + m_Pivot: {x: 1, y: 1} +--- !u!222 &380188952969839968 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1844102171940980497} + m_CullTransparentMesh: 1 +--- !u!114 &170663812404971233 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1844102171940980497} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 0.26415092, g: 0.26415092, b: 0.26415092, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: -27720893, guid: e5829cbc100001646956a9c3ed4e33c5, type: 3} + m_Type: 1 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &8791400826399403740 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1844102171940980497} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Navigation: + m_Mode: 3 + m_WrapAround: 0 + m_SelectOnUp: {fileID: 0} + m_SelectOnDown: {fileID: 0} + m_SelectOnLeft: {fileID: 0} + m_SelectOnRight: {fileID: 0} + m_Transition: 1 + m_Colors: + m_NormalColor: {r: 1, g: 1, b: 1, a: 1} + m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} + m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} + m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} + m_ColorMultiplier: 1 + m_FadeDuration: 0.1 + m_SpriteState: + m_HighlightedSprite: {fileID: 0} + m_PressedSprite: {fileID: 0} + m_SelectedSprite: {fileID: 0} + m_DisabledSprite: {fileID: 0} + m_AnimationTriggers: + m_NormalTrigger: Normal + m_HighlightedTrigger: Highlighted + m_PressedTrigger: Pressed + m_SelectedTrigger: Selected + m_DisabledTrigger: Disabled + m_Interactable: 1 + m_TargetGraphic: {fileID: 170663812404971233} + m_OnClick: + m_PersistentCalls: + m_Calls: [] --- !u!1 &4884066667293879814 GameObject: m_ObjectHideFlags: 0 @@ -316,6 +437,7 @@ RectTransform: - {fileID: 7383335062191980062} - {fileID: 2993317773174661490} - {fileID: 6308980257678838100} + - {fileID: 1010396666164740167} - {fileID: 6685372230643413407} m_Father: {fileID: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} @@ -346,6 +468,7 @@ MonoBehaviour: m_EditorClassIdentifier: text: {fileID: 4202672738064507978} closeButton: {fileID: 5925304901667948221} + copyButton: {fileID: 8791400826399403740} screenOffset: {x: 10, y: 10} menuBarHeight: 70 --- !u!1 &7346391167643616437 @@ -484,3 +607,139 @@ MonoBehaviour: m_hasFontAssetChanged: 0 m_baseMaterial: {fileID: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0} +--- !u!1 &7999202329282239406 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5059140281209684741} + - component: {fileID: 8801292156144245076} + - component: {fileID: 6403130881974049321} + m_Layer: 5 + m_Name: Text (TMP) + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5059140281209684741 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7999202329282239406} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 1010396666164740167} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 1, y: 1} + m_AnchoredPosition: {x: 0, y: 0} + m_SizeDelta: {x: 0, y: 0} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8801292156144245076 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7999202329282239406} + m_CullTransparentMesh: 1 +--- !u!114 &6403130881974049321 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7999202329282239406} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 1 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_text: Copy + m_isRightToLeft: 0 + m_fontAsset: {fileID: 11400000, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2} + m_sharedMaterial: {fileID: 4860575619018115804, guid: 08cebd004d97ca742ac80400f37f4eed, type: 2} + m_fontSharedMaterials: [] + m_fontMaterial: {fileID: 0} + m_fontMaterials: [] + m_fontColor32: + serializedVersion: 2 + rgba: 4294967295 + m_fontColor: {r: 1, g: 1, b: 1, a: 1} + m_enableVertexGradient: 0 + m_colorMode: 3 + m_fontColorGradient: + topLeft: {r: 1, g: 1, b: 1, a: 1} + topRight: {r: 1, g: 1, b: 1, a: 1} + bottomLeft: {r: 1, g: 1, b: 1, a: 1} + bottomRight: {r: 1, g: 1, b: 1, a: 1} + m_fontColorGradientPreset: {fileID: 0} + m_spriteAsset: {fileID: 0} + m_tintAllSprites: 0 + m_StyleSheet: {fileID: 0} + m_TextStyleHashCode: -1183493901 + m_overrideHtmlColors: 0 + m_faceColor: + serializedVersion: 2 + rgba: 4294967295 + m_fontSize: 8 + m_fontSizeBase: 8 + m_fontWeight: 400 + m_enableAutoSizing: 0 + m_fontSizeMin: 18 + m_fontSizeMax: 72 + m_fontStyle: 0 + m_HorizontalAlignment: 2 + m_VerticalAlignment: 512 + m_textAlignment: 65535 + m_characterSpacing: 0 + m_wordSpacing: 0 + m_lineSpacing: 0 + m_lineSpacingMax: 0 + m_paragraphSpacing: 0 + m_charWidthMaxAdj: 0 + m_TextWrappingMode: 1 + m_wordWrappingRatios: 0.4 + m_overflowMode: 0 + m_linkedTextComponent: {fileID: 0} + parentLinkedComponent: {fileID: 0} + m_enableKerning: 0 + m_ActiveFontFeatures: 6e72656b + m_enableExtraPadding: 0 + checkPaddingRequired: 0 + m_isRichText: 1 + m_EmojiFallbackSupport: 1 + m_parseCtrlCharacters: 1 + m_isOrthographic: 1 + m_isCullingEnabled: 0 + m_horizontalMapping: 0 + m_verticalMapping: 0 + m_uvLineOffset: 0 + m_geometrySortingOrder: 0 + m_IsTextObjectScaleStatic: 0 + m_VertexBufferAutoSizeReduction: 0 + m_useMaxVisibleDescender: 1 + m_pageToDisplay: 1 + m_margin: {x: 0, y: 0, z: 0, w: 0} + m_isUsingLegacyAnimationComponent: 0 + m_isVolumetricText: 0 + m_hasFontAssetChanged: 0 + m_baseMaterial: {fileID: 0} + m_maskOffset: {x: 0, y: 0, z: 0, w: 0} diff --git a/Assets/Scenes/SampleProject.unity b/Assets/Scenes/SampleProject.unity index 2893f250..53174c5d 100644 --- a/Assets/Scenes/SampleProject.unity +++ b/Assets/Scenes/SampleProject.unity @@ -926,6 +926,51 @@ RectTransform: m_CorrespondingSourceObject: {fileID: 8849628700159893901, guid: 5a23b2bd2bd04c045878e1a06b3b9aa2, type: 3} m_PrefabInstance: {fileID: 769109585} m_PrefabAsset: {fileID: 0} +--- !u!1 &784978156 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 784978157} + - component: {fileID: 784978158} + m_Layer: 0 + m_Name: AlarmManager + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &784978157 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 784978156} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 429.2735, y: 488.27496, z: 49.768143} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &784978158 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 784978156} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 6765c5d969530e44cbe4fc91d5e52ca1, type: 3} + m_Name: + m_EditorClassIdentifier: + alarmUIPrefab: {fileID: 1828762385695490929, guid: e8b88e69e607ee448806427e91440a8e, type: 3} --- !u!1 &832575517 GameObject: m_ObjectHideFlags: 0 @@ -980,6 +1025,115 @@ RectTransform: m_CorrespondingSourceObject: {fileID: 5064510836022735693, guid: 27ddee6261f49584c8634ba7c5f4ae46, type: 3} m_PrefabInstance: {fileID: 8261569461642068635} m_PrefabAsset: {fileID: 0} +--- !u!1 &1091201604 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1091201608} + - component: {fileID: 1091201607} + - component: {fileID: 1091201606} + - component: {fileID: 1091201605} + m_Layer: 0 + m_Name: Plane + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!64 &1091201605 +MeshCollider: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1091201604} + m_Material: {fileID: 0} + m_IncludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_ExcludeLayers: + serializedVersion: 2 + m_Bits: 0 + m_LayerOverridePriority: 0 + m_IsTrigger: 0 + m_ProvidesContacts: 0 + m_Enabled: 1 + serializedVersion: 5 + m_Convex: 0 + m_CookingOptions: 30 + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!23 &1091201606 +MeshRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1091201604} + m_Enabled: 1 + m_CastShadows: 1 + m_ReceiveShadows: 1 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 2 + m_RayTraceProcedural: 0 + m_RayTracingAccelStructBuildFlagsOverride: 0 + m_RayTracingAccelStructBuildFlags: 1 + m_SmallMeshCulling: 1 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 3 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_AdditionalVertexStreams: {fileID: 0} +--- !u!33 &1091201607 +MeshFilter: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1091201604} + m_Mesh: {fileID: 10209, guid: 0000000000000000e000000000000000, type: 0} +--- !u!4 &1091201608 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1091201604} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 1000, y: 0, z: 1000} + m_LocalScale: {x: 300, y: 1, z: 300} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1101428664 GameObject: m_ObjectHideFlags: 0 @@ -2069,8 +2223,10 @@ SceneRoots: - {fileID: 832575519} - {fileID: 632541407} - {fileID: 27812499} + - {fileID: 784978157} - {fileID: 2030316712} - {fileID: 483439351} - {fileID: 495653798} - {fileID: 88083293} - {fileID: 1840728471} + - {fileID: 1091201608} diff --git a/Assets/Scripts/SampleProject/AppMain.cs b/Assets/Scripts/SampleProject/AppMain.cs index fac28d7d..cc59f3e0 100644 --- a/Assets/Scripts/SampleProject/AppMain.cs +++ b/Assets/Scripts/SampleProject/AppMain.cs @@ -52,6 +52,7 @@ namespace SampleProject mqttPipeLine = new MQTTPipeLine("localhost", 1883); mqttPipeLine.AddTopic("AGV"); + //mqttPipeLine.AddTopic("ALARM"); mqttPipeLine.Execute(); //10รส ศฤ มคม๖ diff --git a/Assets/Scripts/SampleProject/SceneMain.cs b/Assets/Scripts/SampleProject/SceneMain.cs index bfb91e31..75341f79 100644 --- a/Assets/Scripts/SampleProject/SceneMain.cs +++ b/Assets/Scripts/SampleProject/SceneMain.cs @@ -1,6 +1,7 @@ ๏ปฟusing System; using UnityEngine; using UVC.Core; +using UVC.Factory.Alarm; using UVC.UI.Tooltip; namespace SampleProject @@ -21,6 +22,17 @@ namespace SampleProject AppMain.Instance.Initialized += OnAppInitialized; } + /// + /// AGV ๊ด€๋ฆฌ์ž๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ด ๋ฉ”์„œ๋“œ๋Š” AGV ๊ด€๋ฆฌ์ž ์ƒ์„ฑ๊ณผ ๊ด€๋ จ๋œ ํ•„์š”ํ•œ ์ดˆ๊ธฐํ™” ๋˜๋Š” ์„ค์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. + /// ๋‚ด๋ถ€์ ์œผ๋กœ ํ˜ธ์ถœ๋˜๋ฉฐ ์™ธ๋ถ€ ์ฝ”๋“œ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•˜๋„๋ก ์˜๋„๋œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. + /// + internal void OnAGVManagerCreated() + { + AlarmManager.Instance.Run(); + } + private void OnAppInitialized() { if (Initialized != null) diff --git a/Assets/Scripts/UVC/Data/DataArray.cs b/Assets/Scripts/UVC/Data/DataArray.cs index 0120ed4c..ebdd62f9 100644 --- a/Assets/Scripts/UVC/Data/DataArray.cs +++ b/Assets/Scripts/UVC/Data/DataArray.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; +using UnityEngine; namespace UVC.Data { @@ -11,12 +12,21 @@ namespace UVC.Data /// public class DataArray : List, IDataObject { - + private bool isInPool = false; /// /// ์ด ๊ฐ์ฒด๊ฐ€ ๊ฐ์ฒด ํ’€์— ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. /// ์ค‘๋ณต ๋ฐ˜ํ™˜์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด DataArrayPool์—์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. /// - internal bool IsInPool { get; set; } = false; + internal bool IsInPool { get => isInPool; + set + { + isInPool = value; + foreach (var item in this) + { + item.IsInPool = value; // ๋‚ด๋ถ€ DataObject๋„ ํ’€์— ์žˆ๋‹ค๊ณ  ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + } + } + } // ์ถ”๊ฐ€ ๋œ ํ•ญ๋ชฉ ๋ชฉ๋ก protected List addedList = new List(); @@ -77,6 +87,26 @@ namespace UVC.Data } } + public DataArray(System.IO.Stream jsonStream) + { + if (jsonStream == null) + throw new ArgumentNullException(nameof(jsonStream)); + + // ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ฒญํฌ ๋‹จ์œ„๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, + // ํ˜„์žฌ๋Š” Newtonsoft.Json์˜ ๊ธฐ๋ณธ ์—ญ์ง๋ ฌํ™” ์‚ฌ์šฉ + using (var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(jsonStream))) + { + // ์ฒญํฌ ์ฝ๊ธฐ ์„ค์ • - ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ตœ์ ํ™” + reader.SupportMultipleContent = true; + + var serializer = new Newtonsoft.Json.JsonSerializer(); + var sourceObject = serializer.Deserialize(reader); + + // ์ˆ˜์ •๋œ ์ฝ”๋“œ: ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  JArray ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ + if (sourceObject != null) FromJArray(sourceObject); + } + } + /// /// JArray๋กœ๋ถ€ํ„ฐ DataArray๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒ์„ฑ์ž /// @@ -191,8 +221,7 @@ namespace UVC.Data // ๊ธฐ์กด ๋ณ€๊ฒฝ ์ถ”์  ๋ชฉ๋ก์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ClearTrackedChanges(); - - // ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์œ„ํ•ด ID๋ฅผ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์ „์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. + var thisDict = this.ToDictionary(item => item.Id); var otherDict = otherArray.ToDictionary(item => item.Id); @@ -208,7 +237,7 @@ namespace UVC.Data // ์ถ”๊ฐ€๋œ ํ•ญ๋ชฉ ํ™•์ธ (๋‹ค๋ฅธ ๋ฐฐ์—ด์—๋Š” ์žˆ์ง€๋งŒ ํ˜„์žฌ ๋ฐฐ์—ด์—๋Š” ์—†๋Š” ํ•ญ๋ชฉ) foreach (var id in otherIds.Where(id => !thisIds.Contains(id))) { - addedList.Add(otherDict[id]); + addedList.Add(otherDict[id].Copy(fromPool: false)); } // ์ˆ˜์ •๋œ ํ•ญ๋ชฉ ํ™•์ธ (์–‘์ชฝ ๋ชจ๋‘์— ์žˆ์ง€๋งŒ ๋‚ด์šฉ์ด ๋‹ค๋ฅธ ํ•ญ๋ชฉ) @@ -230,6 +259,12 @@ namespace UVC.Data // [์„ฑ๋Šฅ ๊ฐœ์„ ] RemoveAll๊ณผ HashSet์„ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๊ฑฐ ์ž‘์—…์˜ ํšจ์œจ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค. if (removedList.Count > 0) { + // ์ œ๊ฑฐ๋  ๊ฐ์ฒด๋“ค์„ ๋จผ์ € ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + foreach (var item in removedList) + { + if (item.IsInPool) item.ReturnToPool(); + } + // ๊ทธ ๋‹ค์Œ ๋ฆฌ์ŠคํŠธ์—์„œ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. var removedItemIds = new HashSet(removedList.Select(i => i.Id)); this.RemoveAll(item => removedItemIds.Contains(item.Id)); } @@ -289,11 +324,10 @@ namespace UVC.Data /// public new void Clear() { - if (Count > 0) - { - ReturnToDataObjectPool(); - base.Clear(); - } + // ๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ์™€ ๋ณ€๊ฒฝ ์ถ”์  ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ๋น„์›๋‹ˆ๋‹ค. + ReturnToDataObjectPool(); + base.Clear(); + ClearTrackedChanges(); } /// @@ -301,16 +335,12 @@ namespace UVC.Data /// public void Reset() { - // ํฌํ•จ๋œ DataObject๋“ค์„ ๋จผ์ € ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - ReturnToDataObjectPool(); - - // ๋‚ด๋ถ€ ๋ฆฌ์ŠคํŠธ์™€ ๋ณ€๊ฒฝ ์ถ”์  ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ชจ๋‘ ๋น„์›๋‹ˆ๋‹ค. - base.Clear(); - ClearTrackedChanges(); + Clear(); } public void ReturnToPool() { + // ํฌํ•จ๋œ DataObject๋“ค์„ ๋จผ์ € ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. DataArrayPool.Return(this); } @@ -322,7 +352,7 @@ namespace UVC.Data { foreach (var item in this) { - DataObjectPool.Return(item); + item.ReturnToPool(); } } @@ -340,37 +370,53 @@ namespace UVC.Data /// ๋™์ผํ•œ ์ƒํƒœ์™€ ๊ฐ’์„ ๊ฐ€์ง„ ํ˜„์žฌ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด์˜ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. /// /// ๋ณต์ œ๋œ ๊ฐ์ฒด๋Š” ์›๋ณธ ๊ฐ์ฒด์™€ ๋…๋ฆฝ์ ์ด๋ฏ€๋กœ, ํ•œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. - /// + /// + /// ๊ฐ์ฒด ํ’€์—์„œ ๋ณต์ œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. /// ํ˜„์žฌ ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์ธ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - public IDataObject Clone() + public IDataObject Clone(bool fromPool = true) + { + return Copy(fromPool); + } + + /// + /// ํ˜„์žฌ ์ธ์Šคํ„ด์Šค์˜ ์š”์†Œ ๋ฐ ๊ด€๋ จ ์ƒํƒœ๋ฅผ ํฌํ•จํ•œ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. + /// + /// + /// ์ด ๋ฉ”์„œ๋“œ๋Š” ํ˜„์žฌ ๋ฐฐ์—ด์— ์žˆ๋Š” ๋ชจ๋“  ์š”์†Œ์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ํฌํ•จํ•˜๋Š” ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + /// ๋ณต์‚ฌ๋œ ์ธ์Šคํ„ด์Šค๋Š” ๋‚ด๋ถ€ ๋ชฉ๋ก์—์„œ ์ถ”์ ํ•˜๋Š” ์ถ”๊ฐ€, ์ œ๊ฑฐ ๋˜๋Š” ์ˆ˜์ •๋œ ์š”์†Œ๋ฅผ ํฌํ•จํ•˜์—ฌ ์›๋ณธ ์ธ์Šคํ„ด์Šค์˜ ์ƒํƒœ๋„ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. + /// + /// ๊ฐ์ฒด ํ’€์—์„œ ๋ณต์ œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. + /// ํ˜„์žฌ ์ธ์Šคํ„ด์Šค์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์ธ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + + public DataArray Copy(bool fromPool = true) { // ํ’€์—์„œ ์ƒˆ DataArray ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. - var clone = DataArrayPool.Get(); - clone.FromCapacity(this.Count); + DataArray clone; + if(fromPool) clone = DataArrayPool.Get(); + else clone = new DataArray(); // ๋ฐฐ์—ด์˜ ๋ชจ๋“  DataObject๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ๊ฐ๊ฐ์„ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. foreach (var item in this) { // DataObject์˜ Clone ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ณ , // base.Add๋ฅผ ์‚ฌ์šฉํ•ด ์ถ”์  ๋กœ์ง ์—†์ด ์ง์ ‘ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. - if (item.Clone() is DataObject clonedItem) + DataObject clonedItem = item.Copy(fromPool); + clone.Add(clonedItem); + if (addedList.Contains(item)) { - clone.Add(clonedItem); - if (addedList.Contains(item)) - { - clone.addedList.Add(clonedItem); - } - else if (removedList.Contains(item)) - { - clone.removedList.Add(clonedItem); - } - else if (modifiedList.Contains(item)) - { - clone.modifiedList.Add(clonedItem); - } + clone.addedList.Add(clonedItem); } + else if (removedList.Contains(item)) + { + clone.removedList.Add(clonedItem); + } + else if (modifiedList.Contains(item)) + { + clone.modifiedList.Add(clonedItem); + } + } - + return clone; } diff --git a/Assets/Scripts/UVC/Data/DataArrayPool.cs b/Assets/Scripts/UVC/Data/DataArrayPool.cs index 04e2d8ef..a1a2e1e0 100644 --- a/Assets/Scripts/UVC/Data/DataArrayPool.cs +++ b/Assets/Scripts/UVC/Data/DataArrayPool.cs @@ -10,7 +10,7 @@ namespace UVC.Data public static class DataArrayPool { private static readonly ConcurrentQueue _pool = new ConcurrentQueue(); - private static int _maxPoolSize = 500; // DataArray๋Š” DataObject๋ณด๋‹ค ์ˆ˜๊ฐ€ ์ ์„ ๊ฒƒ์ด๋ฏ€๋กœ ๊ธฐ๋ณธ๊ฐ’ ์กฐ์ • + private static int _maxPoolSize = 100; // DataArray๋Š” DataObject๋ณด๋‹ค ์ˆ˜๊ฐ€ ์ ์„ ๊ฒƒ์ด๋ฏ€๋กœ ๊ธฐ๋ณธ๊ฐ’ ์กฐ์ • // --- ํ†ต๊ณ„์šฉ ํ•„๋“œ --- private static int _inUseCount = 0; @@ -18,15 +18,16 @@ namespace UVC.Data private static int _poolMisses = 0; private static readonly object _statsLock = new object(); - /// - /// ํ’€์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - /// - /// ์„ค์ •ํ•  ์ตœ๋Œ€ ํฌ๊ธฐ - public static void SetMaxPoolSize(int size) + static DataArrayPool() { - _maxPoolSize = size > 0 ? size : 500; + // maxPoolSize๋งŒํผ์˜ DataObject ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•˜์—ฌ ํ’€์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. + for (int i = 0; i < _maxPoolSize; i++) + { + _pool.Enqueue(new DataArray() { IsInPool = true }); + } } + /// /// ํ’€์—์„œ DataArray ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ํ’€์ด ๋น„์–ด์žˆ์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. /// @@ -50,17 +51,16 @@ namespace UVC.Data { int oldSize = _maxPoolSize; _maxPoolSize += 100; // ์ฆ๊ฐ€๋Ÿ‰ ์กฐ์ • - Debug.Log($"DataArrayPool size automatically increased from {oldSize} to {_maxPoolSize}. Peak usage: {_peakUsage}"); + //Debug.Log($"DataArrayPool size automatically increased from {oldSize} to {_maxPoolSize}. Peak usage: {_peakUsage}"); } } } - if(_peakUsage % 100 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}"); + //if(_peakUsage % 10 == 0) Debug.Log($"DataArrayPool stats: {GetStats()}"); if (fromPool) { array.IsInPool = false; - array.Reset(); } return fromPool ? array : new DataArray(); } @@ -93,7 +93,7 @@ namespace UVC.Data /// ํ’€ ํ†ต๊ณ„ (์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰, ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰, ํ’€ ๋น„์–ด์žˆ์„ ๋•Œ ์ƒ์„ฑ ํšŸ์ˆ˜, ํ˜„์žฌ ํ’€ ํฌ๊ธฐ) public static string GetStats() { - return $"Peak Usage: {_peakUsage}, In Use: {_inUseCount}, Misses: {_poolMisses}, Pooled: {_pool.Count}, Max Size: {_maxPoolSize}"; + return $"์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰: {_peakUsage}, ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰: {_inUseCount}, ํ’€ ๋น„์–ด์žˆ์„ ๋•Œ ์ƒ์„ฑ ํšŸ์ˆ˜: {_poolMisses}, ํ˜„์žฌ ํ’€ ํฌ๊ธฐ: {_pool.Count}, Max Size: {_maxPoolSize}"; } /// diff --git a/Assets/Scripts/UVC/Data/DataObject.cs b/Assets/Scripts/UVC/Data/DataObject.cs index 6c67bb48..0507e629 100644 --- a/Assets/Scripts/UVC/Data/DataObject.cs +++ b/Assets/Scripts/UVC/Data/DataObject.cs @@ -49,12 +49,30 @@ namespace UVC.Data /// public class DataObject : OrderedDictionary, IDataObject { - + private bool isInPool = false; /// /// ์ด ๊ฐ์ฒด๊ฐ€ ๊ฐ์ฒด ํ’€์— ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. /// ์ค‘๋ณต ๋ฐ˜ํ™˜์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด DataObjectPool์—์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. /// - internal bool IsInPool { get; set; } = false; + internal bool IsInPool + { + get => isInPool; + set + { + isInPool = value; + foreach (var item in this) + { + if(item.Value is DataObject dataObject) + { + dataObject.isInPool = value; // ๋‚ด๋ถ€ DataObject๋„ ํ’€์— ์žˆ๋‹ค๊ณ  ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + } + else if(item.Value is DataArray dataArray) + { + dataArray.IsInPool = value; // ๋‚ด๋ถ€ DataArray๋„ ํ’€์— ์žˆ๋‹ค๊ณ  ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + } + } + } + } /// /// ๊ฐ์ฒด์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค. DataArray์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹๋ณ„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. @@ -104,6 +122,30 @@ namespace UVC.Data /// public DataObject() { } + public DataObject(string jsonString): this(JObject.Parse(jsonString)) + { + } + + public DataObject(System.IO.Stream jsonStream) + { + if (jsonStream == null) + throw new ArgumentNullException(nameof(jsonStream)); + + // ์ŠคํŠธ๋ฆผ ์ฒ˜๋ฆฌ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ฒญํฌ ๋‹จ์œ„๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์ง€๋งŒ, + // ํ˜„์žฌ๋Š” Newtonsoft.Json์˜ ๊ธฐ๋ณธ ์—ญ์ง๋ ฌํ™” ์‚ฌ์šฉ + using (var reader = new Newtonsoft.Json.JsonTextReader(new System.IO.StreamReader(jsonStream))) + { + // ์ฒญํฌ ์ฝ๊ธฐ ์„ค์ • - ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ตœ์ ํ™” + reader.SupportMultipleContent = true; + + var serializer = new Newtonsoft.Json.JsonSerializer(); + var sourceObject = serializer.Deserialize(reader); + + // ์ˆ˜์ •๋œ ์ฝ”๋“œ: ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋Œ€์‹  FromJObject ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉ + if(sourceObject != null) FromJObject(sourceObject); + } + } + /// /// JObject๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. /// @@ -270,6 +312,16 @@ namespace UVC.Data if (hasChanged) { + // ๊ธฐ์กด์— ํ’€๋ง ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๊ฐ€ ์žˆ์—ˆ๋‹ค๋ฉด ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + if (oldValue is DataObject oldDataObject) + { + if(oldDataObject.IsInPool) oldDataObject.ReturnToPool(); + } + else if (oldValue is DataArray oldDataArray) + { + if (oldDataArray.IsInPool) oldDataArray.ReturnToPool(); + } + // ๊ธฐ๋ณธ ๋”•์…”๋„ˆ๋ฆฌ์— ๊ฐ’์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. base[key] = value; @@ -289,7 +341,7 @@ namespace UVC.Data /// ์†์„ฑ ์ด๋ฆ„ /// ์†์„ฑ์ด ์—†๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’ /// ๋ณ€ํ™˜๋œ ์ •์ˆ˜ ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ๊ฐ’ - public int GetInt(string propertyName, int defaultValue = 0) + public int? GetInt(string propertyName, int? defaultValue = null) { if (TryGetValue(propertyName, out object? value) && value != null) { @@ -321,7 +373,7 @@ namespace UVC.Data /// ์†์„ฑ ์ด๋ฆ„ /// ์†์„ฑ์ด ์—†๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’ /// ๋ณ€ํ™˜๋œ ๋ถˆ๋ฆฌ์–ธ ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ๊ฐ’ - public bool GetBool(string propertyName, bool defaultValue = false) + public bool? GetBool(string propertyName, bool? defaultValue = false) { if (TryGetValue(propertyName, out object? value) && value != null) { @@ -338,7 +390,7 @@ namespace UVC.Data /// ์†์„ฑ ์ด๋ฆ„ /// ์†์„ฑ์ด ์—†๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’ /// ๋ณ€ํ™˜๋œ ๋ถ€๋™ ์†Œ์ˆ˜์  ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ๊ฐ’ - public float GetFloat(string propertyName, float defaultValue = 0f) + public float? GetFloat(string propertyName, float? defaultValue = null) { if (TryGetValue(propertyName, out object? value) && value != null) { @@ -355,7 +407,7 @@ namespace UVC.Data /// ์†์„ฑ ์ด๋ฆ„ /// ์†์„ฑ์ด ์—†๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’ /// ๋ณ€ํ™˜๋œ ๋”๋ธ” ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ๊ฐ’ - public double GetDouble(string propertyName, double defaultValue = 0.0) + public double? GetDouble(string propertyName, double? defaultValue = null) { if (TryGetValue(propertyName, out object? value) && value != null) { @@ -372,7 +424,7 @@ namespace UVC.Data /// ์†์„ฑ ์ด๋ฆ„ /// ์†์„ฑ์ด ์—†๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’ /// ๋ณ€ํ™˜๋œ long ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ๊ฐ’ - public long GetLong(string propertyName, long defaultValue = 0L) + public long? GetLong(string propertyName, long? defaultValue = null) { if (TryGetValue(propertyName, out object? value) && value != null) { @@ -407,7 +459,7 @@ namespace UVC.Data /// ์†์„ฑ ์ด๋ฆ„ /// ์†์„ฑ์ด ์—†๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ๋ฐ˜ํ™˜ํ•  ๊ธฐ๋ณธ๊ฐ’ /// ๋ณ€ํ™˜๋œ ์—ด๊ฑฐํ˜• ๊ฐ’ ๋˜๋Š” ๊ธฐ๋ณธ๊ฐ’ - public T GetEnum(string propertyName, T defaultValue = default) where T : Enum + public T? GetEnum(string propertyName, T? defaultValue = default) where T : Enum { if (TryGetValue(propertyName, out object? value) && value != null) { @@ -572,9 +624,22 @@ namespace UVC.Data /// ์ œ๊ฑฐ ์„ฑ๊ณต ์—ฌ๋ถ€ public new bool Remove(string key) { + // ์ œ๊ฑฐํ•˜๊ธฐ ์ „์— ์ด์ „ ๊ฐ’์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. + TryGetValue(key, out object? oldValue); + bool result = base.Remove(key); if (result) { + // ์ œ๊ฑฐ๋œ ๊ฐ์ฒด๊ฐ€ ํ’€๋ง ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + if (oldValue is DataObject dataObject) + { + if(dataObject.IsInPool) dataObject.ReturnToPool(); + } + else if (oldValue is DataArray dataArray) + { + if (dataArray.IsInPool) dataArray.ReturnToPool(); + } + // ๋ณ€๊ฒฝ ์ถ”์  ๋ชฉ๋ก์—์„œ๋„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. changedProperies.Remove(key); } @@ -586,6 +651,17 @@ namespace UVC.Data /// public void RemoveAll() { + foreach (var value in Values.ToList()) + { + if(value is DataObject dataObject) + { + dataObject.ReturnToPool(); // DataObject๋ฅผ ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + } + else if (value is DataArray dataArray) + { + dataArray.ReturnToPool(); // DataArray๋ฅผ ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + } + } base.Clear(); changedProperies.Clear(); } @@ -606,10 +682,27 @@ namespace UVC.Data /// /// ๋ณต์ œ๋œ ๊ฐ์ฒด๋Š” ์›๋ณธ ๊ฐ์ฒด์™€ ๋…๋ฆฝ์ ์ด๋ฏ€๋กœ, ํ•œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. /// + /// ๋ณต์ œ๋œ ๊ฐ์ฒด๊ฐ€ ํ’€์— ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. /// ํ˜„์žฌ ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์ธ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - public IDataObject Clone() + public IDataObject Clone(bool fromPool = true) { - var clone = DataObjectPool.Get(); + return Copy(fromPool); + } + + /// + /// ๋ชจ๋“  ํ‚ค-๊ฐ’ ์Œ์„ ํฌํ•จํ•˜์—ฌ ํ˜„์žฌ ์ธ์Šคํ„ด์Šค์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ด ๋ฉ”์„œ๋“œ๋Š” ์™€ ๊ทธ ๋‚ด์šฉ์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + /// ํ‚ค-๊ฐ’ ์Œ์˜ ๊ฐ’์ด ๋‹ค๋ฅธ ๋˜๋Š” ์ธ ๊ฒฝ์šฐ, + /// ๋ฉ”์„œ๋“œ๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์žฌ๊ท€์ ์œผ๋กœ ๋ณต์ œํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์œ ํ˜• ๋ฐ ๊ธฐํƒ€ ๋ณต์ œ ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฐ’์€ + /// ์ง์ ‘ ๋ณต์‚ฌ๋ฉ๋‹ˆ๋‹ค. + /// ๋ณต์ œ๋œ ๊ฐ์ฒด๊ฐ€ ํ’€์— ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. + /// ํ˜„์žฌ ๊ฐ์ฒด์˜ ๊นŠ์€ ๋ณต์‚ฌ๋ณธ์ธ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + public DataObject Copy(bool fromPool = true) + { + DataObject clone = DataObjectPool.Get(); + if(fromPool) clone = DataObjectPool.Get(); + else clone = new DataObject(); clone.Name = Name; clone.IdKey = IdKey; @@ -619,13 +712,13 @@ namespace UVC.Data object? clonedValue; switch (pair.Value) { - // ๊ฐ’์ด DataObject์ธ ๊ฒฝ์šฐ, ์žฌ๊ท€์ ์œผ๋กœ Clone์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. + // ๊ฐ’์ด DataObject์ธ ๊ฒฝ์šฐ, ์žฌ๊ท€์ ์œผ๋กœ Copy์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. case DataObject dataObjectValue: - clonedValue = dataObjectValue.Clone(); + clonedValue = dataObjectValue.Copy(fromPool); break; // ๊ฐ’์ด DataArray์ธ ๊ฒฝ์šฐ, ์žฌ๊ท€์ ์œผ๋กœ Clone์„ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. case DataArray dataArrayValue: - clonedValue = dataArrayValue.Clone(); + clonedValue = dataArrayValue.Copy(fromPool); break; // ๊ทธ ์™ธ์˜ ๊ฒฝ์šฐ (primitive ํƒ€์ž… ๋“ฑ)๋Š” ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. default: @@ -684,7 +777,23 @@ namespace UVC.Data || (this[keyValue.Key] != null && keyValue.Value == null) || (this[keyValue.Key] != null && keyValue.Value != null && !this[keyValue.Key]!.Equals(keyValue.Value))) { - this[keyValue.Key] = keyValue.Value; + //์ฐธ์กฐ ํƒ€์ž…๊ณผ ๊ฐ’ ํƒ€์ž… ๊ตฌ๋ถ„ํ•˜์—ฌ ๋ณต์‚ฌ + object? valueToSet; + switch (keyValue.Value) + { + // DataObject๋‚˜ DataArray๋Š” ํ’€์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + case DataObject dataObjectValue: + valueToSet = dataObjectValue.Copy(fromPool: false); + break; + case DataArray dataArrayValue: + valueToSet = dataArrayValue.Copy(fromPool: false); + break; + // ๊ทธ ์™ธ ํƒ€์ž…์€ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. + default: + valueToSet = keyValue.Value; + break; + } + this[keyValue.Key] = valueToSet; changedProperies.Add(keyValue.Key); } } diff --git a/Assets/Scripts/UVC/Data/DataObjectPool.cs b/Assets/Scripts/UVC/Data/DataObjectPool.cs index 78802002..62341663 100644 --- a/Assets/Scripts/UVC/Data/DataObjectPool.cs +++ b/Assets/Scripts/UVC/Data/DataObjectPool.cs @@ -22,7 +22,7 @@ namespace UVC.Data /// obj["age"] = 30; /// /// // ์ž‘์—… ์™„๋ฃŒ ํ›„ ํ’€์— ๋ฐ˜ํ™˜ - /// DataObjectPool.Return(obj); + /// obj.ReturnToPool(); /// /// // ํ’€ ํ†ต๊ณ„ ํ™•์ธ /// ULog.Debug(DataObjectPool.GetStats()); @@ -33,27 +33,26 @@ namespace UVC.Data /// /// DataObject ์ธ์Šคํ„ด์Šค๋ฅผ ์ €์žฅํ•˜๋Š” ์Šค๋ ˆ๋“œ ์•ˆ์ „ ํ์ž…๋‹ˆ๋‹ค. /// - private static ConcurrentQueue dataObjectPool = new ConcurrentQueue(); + private static ConcurrentQueue pool = new ConcurrentQueue(); /// /// ํ’€์˜ ์ตœ๋Œ€ ํฌ๊ธฐ์ž…๋‹ˆ๋‹ค. ์ด ํฌ๊ธฐ๋ฅผ ์ดˆ๊ณผํ•˜๋Š” ๊ฐ์ฒด๋Š” ํ’€์— ์ €์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. /// - private static int maxPoolSize = 1000; + private static int maxPoolSize = 4000; // --- ํ†ต๊ณ„์šฉ ํ•„๋“œ --- - private static int _inUseCount = 0; - private static int _peakUsage = 0; - private static int _poolMisses = 0; + private static int _inUseCount = 0; // ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ DataObject ์ธ์Šคํ„ด์Šค์˜ ์ˆ˜ + private static int _peakUsage = 0; // ์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰ ๊ธฐ๋ก + private static int _poolMisses = 0; // ํ’€์—์„œ ๊ฐ์ฒด๋ฅผ ์ฐพ์ง€ ๋ชปํ•˜๊ณ  ์ƒˆ๋กœ ์ƒ์„ฑํ•œ ํšŸ์ˆ˜ private static readonly object _statsLock = new object(); - - /// - /// ํ’€์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - /// - /// ์„ค์ •ํ•  ์ตœ๋Œ€ ํฌ๊ธฐ - public static void SetMaxPoolSize(int size) + static DataObjectPool() { - maxPoolSize = size > 0 ? size : 1000; + // maxPoolSize๋งŒํผ์˜ DataObject ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฏธ๋ฆฌ ์ƒ์„ฑํ•˜์—ฌ ํ’€์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. + for (int i = 0; i < maxPoolSize; i++) + { + pool.Enqueue(new DataObject() { IsInPool = true }); + } } /// @@ -63,7 +62,7 @@ namespace UVC.Data /// ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ DataObject ์ธ์Šคํ„ด์Šค public static DataObject Get() { - bool fromPool = dataObjectPool.TryDequeue(out var obj); + bool fromPool = pool.TryDequeue(out var obj); lock (_statsLock) { @@ -82,17 +81,16 @@ namespace UVC.Data { int oldSize = maxPoolSize; maxPoolSize += 1000; - Debug.Log($"DataObjectPool size automatically increased from {oldSize} to {maxPoolSize}. Peak usage: {_peakUsage}"); + //Debug.Log($"DataObjectPool size automatically increased from {oldSize} to {maxPoolSize}. Peak usage: {_peakUsage}"); } } } - if (_peakUsage % 100 == 0) Debug.Log($"DataObjectPool stats: {GetStats()}"); + //if (_peakUsage % 100 == 0) Debug.Log($"DataObjectPool stats: {GetStats()}"); if (fromPool) { obj.IsInPool = false; - obj.Reset(); } return fromPool ? obj : new DataObject(); } @@ -111,11 +109,11 @@ namespace UVC.Data _inUseCount--; } - if (dataObjectPool.Count < maxPoolSize) + if (pool.Count < maxPoolSize) { obj.Reset(); // ์žฌ์‚ฌ์šฉ ์ „ ์™„๋ฒฝํ•œ ์ดˆ๊ธฐํ™” obj.IsInPool = true; - dataObjectPool.Enqueue(obj); + pool.Enqueue(obj); } // ํ’€์ด ๊ฐ€๋“ ์ฐจ๋ฉด ๊ฐ์ฒด๋Š” ํ’€์— ์ถ”๊ฐ€๋˜์ง€ ์•Š๊ณ  GC ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค. } @@ -126,7 +124,7 @@ namespace UVC.Data /// ํ’€ ํ†ต๊ณ„ (์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰, ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰, ํ’€ ๋น„์–ด์žˆ์„ ๋•Œ ์ƒ์„ฑ ํšŸ์ˆ˜, ํ˜„์žฌ ํ’€ ํฌ๊ธฐ) public static string GetStats() { - return $"Peak Usage: {_peakUsage}, In Use: {_inUseCount}, Misses: {_poolMisses}, Pooled: {dataObjectPool.Count}, Max Size: {maxPoolSize}"; + return $"์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰: {_peakUsage}, ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰: {_inUseCount}, ํ’€ ๋น„์–ด์žˆ์„ ๋•Œ ์ƒ์„ฑ ํšŸ์ˆ˜: {_poolMisses}, ํ˜„์žฌ ํ’€ ํฌ๊ธฐ: {pool.Count}, Max Size: {maxPoolSize}"; } /// diff --git a/Assets/Scripts/UVC/Data/DataRepository.cs b/Assets/Scripts/UVC/Data/DataRepository.cs index a5f365e2..1f9f9f10 100644 --- a/Assets/Scripts/UVC/Data/DataRepository.cs +++ b/Assets/Scripts/UVC/Data/DataRepository.cs @@ -69,7 +69,8 @@ namespace UVC.Data { if (!dataObjects.ContainsKey(key)) { - var newData = dataObject.Clone(); + var newData = dataObject.Clone(false); + dataObjects.Add(key, newData); dataObject.MarkAllAsUpdated(); //UniTask.Post(() => NotifyDataUpdate(key, newData)); diff --git a/Assets/Scripts/UVC/Data/HttpPipeLine.cs b/Assets/Scripts/UVC/Data/HttpPipeLine.cs index bfc9c2d8..a684b51b 100644 --- a/Assets/Scripts/UVC/Data/HttpPipeLine.cs +++ b/Assets/Scripts/UVC/Data/HttpPipeLine.cs @@ -327,6 +327,10 @@ namespace UVC.Data mappedObject = info.DataMapper.Map(source); } } + else + { + mappedObject = new DataObject(result); + } } else if (result.StartsWith("[")) { @@ -403,6 +407,11 @@ namespace UVC.Data } } } + else + { + // DataMapper๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, JArray๋ฅผ IDataObject๋กœ ๋ณ€ํ™˜ + mappedObject = new DataArray(result); + } } } catch (JsonException ex) diff --git a/Assets/Scripts/UVC/Data/IDataObject.cs b/Assets/Scripts/UVC/Data/IDataObject.cs index b62d96e5..80ed6238 100644 --- a/Assets/Scripts/UVC/Data/IDataObject.cs +++ b/Assets/Scripts/UVC/Data/IDataObject.cs @@ -41,8 +41,9 @@ /// /// ๋ณต์ œ๋œ ๊ฐ์ฒด๋Š” ์›๋ณธ ๊ฐ์ฒด์™€ ๋…๋ฆฝ์ ์ด๋ฏ€๋กœ, ํ•œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•ด๋„ ๋‹ค๋ฅธ ๊ฐ์ฒด์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. /// + /// ๊ฐ์ฒด ํ’€์—์„œ ๋ณต์ œํ• ์ง€ ์—ฌ๋ถ€๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. /// ํ˜„์žฌ ๊ฐ์ฒด์˜ ๋ณต์‚ฌ๋ณธ์ธ ์ƒˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. - public IDataObject Clone(); + public IDataObject Clone(bool fromPool = true); /// diff --git a/Assets/Scripts/UVC/Data/MQTTPipeLine.cs b/Assets/Scripts/UVC/Data/MQTTPipeLine.cs index 7471a2ca..b6dcc377 100644 --- a/Assets/Scripts/UVC/Data/MQTTPipeLine.cs +++ b/Assets/Scripts/UVC/Data/MQTTPipeLine.cs @@ -198,6 +198,7 @@ namespace UVC.Data // ๋ฉ”์‹œ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰ํ•˜์—ฌ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ๋ถ€ํ•˜๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค. UniTask.RunOnThreadPool(() => { + // ํ† ํ”ฝ์ด infoList์™€ readyHandlerList์— ์กด์žฌํ•˜๊ณ , ์ค€๋น„ ์ƒํƒœ๊ฐ€ true์ธ ๊ฒฝ์šฐ์—๋งŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. if (infoList.ContainsKey(topic)) { MQTTPipeLineInfo info = infoList[topic]; @@ -211,7 +212,14 @@ namespace UVC.Data { JObject source = JObject.Parse(message); if (info.Validator != null && !info.Validator.IsValid(source)) return; - if (info.DataMapper != null) mappedObject = info.DataMapper.Map(source); + if (info.DataMapper != null) + { + mappedObject = info.DataMapper.Map(source); + } + else { + // DataMapper๊ฐ€ ์—†์œผ๋ฉด JObject๋ฅผ IDataObject๋กœ ๋ณ€ํ™˜ + mappedObject = new DataObject(source); + } } else if (message.StartsWith("[")) { @@ -223,7 +231,15 @@ namespace UVC.Data if (validSource == null || validSource.Count == 0) return; source = validSource; } - if (info.DataMapper != null) mappedObject = info.DataMapper.Map(source); + if (info.DataMapper != null) + { + mappedObject = info.DataMapper.Map(source); + } + else + { + // DataMapper๊ฐ€ ์—†์œผ๋ฉด JArray๋ฅผ IDataObject๋กœ ๋ณ€ํ™˜ + mappedObject = new DataArray(source); + } } if (mappedObject == null) return; diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs index 69bbe009..1c924d2f 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmManager.cs @@ -1,81 +1,197 @@ -๏ปฟusing System; +๏ปฟ#nullable enable + +using SampleProject; +using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; using UnityEngine; -using UVC.Factory; +using UVC.Core; +using UVC.Data; +using UVC.Extention; using UVC.Factory.Component; namespace UVC.Factory.Alarm { - public class AlarmManager : MonoBehaviour + public class AlarmManager : SingletonScene { - public static AlarmManager Instance { get; private set; } - + [Tooltip("์•Œ๋žŒ UI ํ”„๋ฆฌํŒน์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋ฆฌํŒน์€ ์•Œ๋žŒ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š” UI ์š”์†Œ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.")] public GameObject alarmUIPrefab; // ์•Œ๋žŒ UI ํ”„๋ฆฌํŒน (์•„๋ž˜์—์„œ ์„ค๋ช…) private Dictionary activeAlarmUIs = new Dictionary(); // FactoryDataManager์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ์ฐธ์กฐ๋ฅผ ์ €์žฅ - private FactoryObjectManager dataManager; + private FactoryObjectManager? dataManager; - void Awake() + /// + /// AlarmManager์˜ ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. + /// Awake ๋ฉ”์„œ๋“œ์—์„œ ํ˜ธ์ถœ๋˜๋ฉฐ, MonoBehaviour๊ฐ€ ์ƒ์„ฑ๋  ๋•Œ ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. + /// + protected override void Init() { - Instance = this; + SceneMain.Instance.Initialized += OnSceneInitialized; } - void Start() + private void OnSceneInitialized() { dataManager = FactoryObjectManager.Instance; - // ์˜ˆ์‹œ: FactoryDataManager์˜ ์•Œ๋žŒ ์ด๋ฒคํŠธ์— ๊ตฌ๋… - // dataManager.OnAlarmReceived += HandleNewAlarm; - // dataManager.OnAlarmCleared += HandleClearedAlarm; } - public void HandleNewAlarm(AlarmData data) + /// + /// Alarm ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ธฐ ์œ„ํ•œ MQTT ํŒŒ์ดํ”„๋ผ์ธ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + /// + public void Run() { + //๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ค ํ˜•์‹์œผ๋กœ ๋ฐ›์„์ง€ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. + var dataMask = new DataMask(); + dataMask.ObjectName = "Alarm"; // Alarm ๊ฐ์ฒด์˜ ์ด๋ฆ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + dataMask.ObjectIdKey = "ID"; // Alarm์˜ ๊ณ ์œ  ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉํ•  ํ‚ค๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + dataMask["ID"] = ""; + dataMask["ALARM_TYPE"] = ""; + dataMask["LEVEL"] = ""; + dataMask["LOGISTIC"] = ""; + dataMask["STATE"] = ""; + dataMask["MESSAGE"] = ""; + dataMask["CODE"] = ""; + dataMask["ICON"] = ""; + dataMask["MACHINENAME"] = ""; + dataMask["SHOPNAME"] = ""; + dataMask["TRANSPORT_EQP_NAME"] = ""; + dataMask["TRANSPORT_UNIT_NAME"] = ""; + dataMask["TRANSPORT_EQP_ID"] = ""; + dataMask["TRANSPORT_UNIT_ID"] = ""; + dataMask["SET_TIME"] = DateTime.Now; + dataMask["UPDATE_TIME"] = DateTime.Now; + dataMask["TIMESTAMP"] = DateTime.Now; + + // MQTT ํŒŒ์ดํ”„๋ผ์ธ ์ •๋ณด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. + // 'ALARM' ํ† ํ”ฝ์„ ๊ตฌ๋…ํ•˜๊ณ , ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋Š” ์œ„์—์„œ ์ •์˜ํ•œ dataMask๋กœ ๋งคํ•‘ํ•˜๋ฉฐ, + // ๋ฐ์ดํ„ฐ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด DataValidator๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + // ๋ฐ์ดํ„ฐ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋ฉด OnUpdateData ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + + DataValidator validator = new DataValidator(); + validator.AddValidator("MACHINENAME", value => value != null); + + var pipelineInfo = new MQTTPipeLineInfo("ALARM") + .setDataMapper(new DataMapper(dataMask)) + .setValidator(validator) + .setHandler(OnUpdateData); + + // ์ƒ์„ฑํ•œ ํŒŒ์ดํ”„๋ผ์ธ ์ •๋ณด๋ฅผ ์ „์—ญ MQTT ํŒŒ์ดํ”„๋ผ์ธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. + AppMain.Instance.MQTTPipeLine.Add(pipelineInfo); + } + /// + /// ๋ฐ์ดํ„ฐ ์ˆ˜์‹  ์‹œ ํ˜ธ์ถœ๋˜๋Š” ๊ณต๊ฐœ ํ•ธ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค. + /// ์ˆ˜์‹ ๋œ ALARM ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ ์”ฌ์— ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. + /// ์ถ”๊ฐ€, ์ œ๊ฑฐ, ์ˆ˜์ •๋œ ALARM ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ๊ฐ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. + /// + /// ์ˆ˜์‹ ๋œ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด (DataArray ํ˜•ํƒœ) + public void OnUpdateData(IDataObject? data) + { + + if (data == null) return; + + DataArray? arr = data as DataArray; + if (arr == null) return; + if (arr.Count == 0) + { + arr.ReturnToPool(); + return; + } + + // ๋ฐ์ดํ„ฐ ๋ฐฐ์—ด์—์„œ ์ถ”๊ฐ€, ์ œ๊ฑฐ, ์ˆ˜์ •๋œ ํ•ญ๋ชฉ ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. + var AddedItems = arr.AddedItems; + var RemovedItems = arr.RemovedItems; + var ModifiedList = arr.ModifiedList; + + Debug.Log($"AlarmManager OnUpdateData: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}"); + + // ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ ALARM ์ฒ˜๋ฆฌ + foreach (var item in AddedItems.ToList()) + { + HandleNewAlarm(item.Copy()); + } + + // ์ œ๊ฑฐ๋œ ALARM ์ฒ˜๋ฆฌ + foreach (var item in RemovedItems.ToList()) + { + HandleClearedAlarm(item.Copy()); + } + + // ์ •๋ณด๊ฐ€ ์ˆ˜์ •๋œ ALARM ์ฒ˜๋ฆฌ + foreach (var item in ModifiedList.ToList()) + { + HandleModifyAlarm(item.Copy()); + } + + arr.ReturnToPool(); + } + + /// + /// AlarmManager๊ฐ€ ํŒŒ๊ดด๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + /// MQTT ํŒŒ์ดํ”„๋ผ์ธ์—์„œ 'ALARM' ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. + /// + protected override void OnDestroy() + { + base.OnDestroy(); + AppMain.Instance.MQTTPipeLine.Remove("ALARM"); + } + + public void HandleNewAlarm(DataObject data) + { + if (data.Id == null) + { + Debug.LogError($"New Alarm Received No data. {data}"); + data.ReturnToPool(); + return; + } + + // ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ + FactoryObject? targetObject = dataManager!.FindById(data.GetString("MACHINENAME")!); + if (targetObject != null) + { + GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // ๋งค๋‹ˆ์ € ํ•˜์œ„์— ์ƒ์„ฑ + AlarmUIController newUiController = newUIObject.GetComponent(); + newUiController.Initialize(targetObject, data); + + activeAlarmUIs.Add(data.Id!, newUiController); + } + + } + + public void HandleModifyAlarm(DataObject data) + { + if (data.Id == null) + { + Debug.LogError($"Modify Alarm Received No data. {data}"); + data.ReturnToPool(); + return; + } // ์ด๋ฏธ ํ•ด๋‹น ์„ค๋น„์— ์•Œ๋žŒ UI๊ฐ€ ๋–  ์žˆ๋Š”์ง€ ํ™•์ธ - if (activeAlarmUIs.TryGetValue(data.objectId, out AlarmUIController uiController)) + if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController)) { // ์žˆ์œผ๋ฉด ๊ธฐ์กด UI์— ์•Œ๋žŒ ์ •๋ณด๋งŒ ์ถ”๊ฐ€ - uiController.AddAlarm(data); - } - else - { - // ์—†์œผ๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ - FactoryObject targetObject = dataManager.FindById(data.objectId); - if (targetObject != null) - { - GameObject newUIObject = Instantiate(alarmUIPrefab, transform); // ๋งค๋‹ˆ์ € ํ•˜์œ„์— ์ƒ์„ฑ - AlarmUIController newUiController = newUIObject.GetComponent(); - newUiController.Initialize(targetObject, data); - - activeAlarmUIs.Add(data.objectId, newUiController); - } + uiController.UpdateAlarm(data); } } - public void HandleClearedAlarm(AlarmData data) + public void HandleClearedAlarm(DataObject data) { - if (activeAlarmUIs.TryGetValue(data.objectId, out AlarmUIController uiController)) + if (data.Id.IsNullOrEmpty()) + { + Debug.LogError($"Clear Alarm Received No data. {data}"); + data.ReturnToPool(); + return; + } + if (activeAlarmUIs.TryGetValue(data.Id!, out AlarmUIController uiController)) { uiController.RemoveAlarm(data); if (uiController.GetAlarmCount() == 0) { - activeAlarmUIs.Remove(data.objectId); + activeAlarmUIs.Remove(data.Id!); Destroy(uiController.gameObject); } + data.ReturnToPool(); } } } - // ์•Œ๋žŒ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ์šฉ ํด๋ž˜์Šค - public class AlarmData - { - public string objectId; - public string alarmId; // ๊ฐ ์•Œ๋žŒ์˜ ๊ณ ์œ  ID - public string message; - // ... ์‹ฌ๊ฐ๋„, ์‹œ๊ฐ„ ๋“ฑ ๊ธฐํƒ€ ์ •๋ณด - } - } diff --git a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs index 452c4318..2b7ce080 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/AlarmUIController.cs @@ -1,23 +1,29 @@ ๏ปฟusing System.Collections.Generic; using TMPro; using UnityEngine; +using UnityEngine.EventSystems; +using UVC.Data; using UVC.Factory.Component; using UVC.Util; namespace UVC.Factory.Alarm { - public class AlarmUIController : MonoBehaviour + public class AlarmUIController : MonoBehaviour, IPointerClickHandler { + [Tooltip("์•Œ๋žŒ ํด๋Ÿฌ์Šคํ„ฐ ๋ทฐ์ž…๋‹ˆ๋‹ค.")] [SerializeField] private GameObject clusterView; + [Tooltip("์•Œ๋žŒ ๊ฐœ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค.")] [SerializeField] private TextMeshProUGUI alarmCountText; + [Tooltip("ํ™•์žฅ๋œ ์•Œ๋žŒ ๋ทฐ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์•Œ๋žŒ ์•„์ด์ฝ˜์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.")] [SerializeField] private GameObject expandedView; + [Tooltip("๊ฐœ๋ณ„ ์•Œ๋žŒ ์•„์ด์ฝ˜ ํ”„๋ฆฌํŒน์ž…๋‹ˆ๋‹ค. ์ด ํ”„๋ฆฌํŒน์€ ๊ฐœ๋ณ„ ์•Œ๋žŒ ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•˜๋Š” UI ์š”์†Œ๋ฅผ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.")] [SerializeField] private GameObject singleAlarmIconPrefab; // ๊ฐœ๋ณ„ ์•Œ๋žŒ ์•„์ด์ฝ˜ private Transform targetObject; - private List alarms = new List(); + private List alarms = new List(); private bool isExpanded = false; - public void Initialize(FactoryObject target, AlarmData initialAlarm) + public void Initialize(FactoryObject target, DataObject initialAlarm) { this.targetObject = target.transform; AddAlarm(initialAlarm); @@ -30,13 +36,32 @@ namespace UVC.Factory.Alarm transform.rotation = Camera.main.transform.rotation; } - public void AddAlarm(AlarmData alarm) + public void AddAlarm(DataObject alarm) { alarms.Add(alarm); UpdateView(); } - public void RemoveAlarm(AlarmData alarm) + public void UpdateAlarm(DataObject alarm) + { + // ์‹ค์ œ๋กœ๋Š” alarmId๋กœ ์ฐพ์•„์„œ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•จ + int index = alarms.FindIndex(a => a.Id == alarm.Id); + if (index >= 0) + { + foreach (var key in alarm.Keys) + { + alarms[index][key] = alarm[key]; // ๊ธฐ์กด ์•Œ๋žŒ ๋ฐ์ดํ„ฐ ์—…๋ฐ์ดํŠธ + } + alarm.ReturnToPool(); + UpdateView(); + } + else + { + Debug.LogWarning($"Alarm with ID {alarm.Id} not found for update."); + } + } + + public void RemoveAlarm(DataObject alarm) { // ์‹ค์ œ๋กœ๋Š” alarmId๋กœ ์ฐพ์•„์„œ ์ง€์›Œ์•ผ ํ•จ alarms.Remove(alarm); @@ -123,5 +148,10 @@ namespace UVC.Factory.Alarm } public int GetAlarmCount() => alarms.Count; + + public void OnPointerClick(PointerEventData eventData) + { + OnPointerClick(); + } } } diff --git a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs b/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs index 8734cce3..9173fd3d 100644 --- a/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs +++ b/Assets/Scripts/UVC/Factory/Alarm/SingleAlarmIcon.cs @@ -1,25 +1,56 @@ -๏ปฟusing UnityEngine; +๏ปฟusing TMPro; +using UnityEngine; +using UVC.Data; using UVC.Util; namespace UVC.Factory.Alarm { public class SingleAlarmIcon : MonoBehaviour { - private AlarmData myAlarmData; + + [Tooltip("์•Œ๋žŒ ๋‚ด์šฉ์„ ํ‘œ์‹œํ•˜๋Š” ํ…์ŠคํŠธ์ž…๋‹ˆ๋‹ค.")] + [SerializeField] private TextMeshProUGUI text; + + private DataObject data; private Transform equipmentTransform; - public void SetData(AlarmData data, Transform equipment) + public void SetData(DataObject newData, Transform equipment) { - myAlarmData = data; + if (data == null) + { + data = newData; + } + else + { + foreach (var keyValue in newData) + { + if (data.ContainsKey(keyValue.Key)) + { + data[keyValue.Key] = keyValue.Value; + } + } + } + equipmentTransform = equipment; - // ์•„์ด์ฝ˜ ๋ชจ์–‘์ด๋‚˜ ์ƒ‰์„ ์•Œ๋žŒ ์‹ฌ๊ฐ๋„์— ๋”ฐ๋ผ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ + + if (text != null) + { + string combinedString = string.Empty; + foreach (var kvp in data) + { + // ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ค„๋ฐ”๊ฟˆ ์‹œ์—๋„ ์ •๋ ฌ์ด ์œ ์ง€๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. + combinedString += $"{kvp.Key}{kvp.Value ?? "null"}\n"; + } + combinedString = combinedString.TrimEnd('\n'); // ๋งˆ์ง€๋ง‰ ์ค„๋ฐ”๊ฟˆ ์ œ๊ฑฐ + text.text = combinedString; + } } public void OnPointerClick() { // ํด๋ฆญ ์‹œ ํ•ด๋‹น ์„ค๋น„๋กœ ์นด๋ฉ”๋ผ ํฌ์ปค์Šค CameraController.Instance.FocusOnTarget(equipmentTransform, 3.0f); - Debug.Log($"์•Œ๋žŒ [{myAlarmData.message}]์ด ๋ฐœ์ƒํ•œ ์„ค๋น„๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค."); + Debug.Log($"์•Œ๋žŒ [{data.GetString("MESSAGE")}]์ด ๋ฐœ์ƒํ•œ ์„ค๋น„๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค."); // ์—ฌ๊ธฐ์„œ ์•Œ๋žŒ ์ƒ์„ธ์ •๋ณด ํŒจ๋„์„ ๋„์›Œ๋„ ์ข‹์Œ } } diff --git a/Assets/Scripts/UVC/Factory/Component/AGV.cs b/Assets/Scripts/UVC/Factory/Component/AGV.cs index d6e359ae..2c193cc0 100644 --- a/Assets/Scripts/UVC/Factory/Component/AGV.cs +++ b/Assets/Scripts/UVC/Factory/Component/AGV.cs @@ -104,46 +104,63 @@ namespace UVC.Factory.Component // ์ฒ˜์Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๋Š” ๊ฒฝ์šฐ, ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋กœ ์ฆ‰์‹œ ์œ„์น˜๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. if (data == null) { - float x = newData.GetFloat("X") * scaleFactor; - float y = newData.GetFloat("Y") * scaleFactor; - Quaternion rotation = Quaternion.Euler(0, newData.GetFloat("DEGREE"), 0); + float x = newData.GetFloat("X").Value * scaleFactor; + float y = newData.GetFloat("Y").Value * scaleFactor; + Quaternion rotation = Quaternion.Euler(0, newData.GetFloat("DEGREE").Value, 0); transform.position = new Vector3(x, 0, y); transform.rotation = rotation; } else // ์ดํ›„ ์—…๋ฐ์ดํŠธ์˜ ๊ฒฝ์šฐ { - // ์ƒˆ ๋ฐ์ดํ„ฐ๋กœ๋ถ€ํ„ฐ ๋ชฉํ‘œ ์œ„์น˜์™€ ํšŒ์ „๊ฐ’์„ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. - float x = data.GetFloat("X") * scaleFactor; - float y = data.GetFloat("Y") * scaleFactor; - Quaternion rotation = Quaternion.Euler(0, data.GetFloat("DEGREE"), 0); + bool isTeleport = false; - float newX = (newData.ContainsKey("X") ? newData.GetFloat("X") : data.GetFloat("X")) * scaleFactor; - float newY = (newData.ContainsKey("Y") ? newData.GetFloat("Y") : data.GetFloat("Y")) * scaleFactor; - float newDegree = (newData.ContainsKey("DEGREE") ? newData.GetFloat("DEGREE") : data.GetFloat("DEGREE")); - Quaternion newRotation = Quaternion.Euler(0, newDegree, 0); - Vector3 newTargetPosition = new Vector3(x, transform.position.y, y); - Quaternion newTargetRotation = rotation; - - if (x != newX || y != newY) newTargetPosition = new Vector3(newX, transform.position.y, newY); - if (rotation != newRotation) newTargetRotation = newRotation; - - // ํ˜„์žฌ ์œ„์น˜์™€ ์ƒˆ๋กœ์šด ๋ชฉํ‘œ ์œ„์น˜ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. - float distanceToTarget = Vector3.Distance(transform.position, newTargetPosition); - - // ๊ฑฐ๋ฆฌ๊ฐ€ ์„ค์ •๋œ ์ž„๊ณ„๊ฐ’์„ ์ดˆ๊ณผํ•˜๋ฉด, ๋ณด๊ฐ„์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์ฆ‰์‹œ ์œ„์น˜/ํšŒ์ „์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - if (distanceToTarget > teleportDistanceThreshold) + float? newX = newData.GetFloat("X"); + float? newY = newData.GetFloat("Y"); + if (newX.HasValue || newY.HasValue) { - transform.position = newTargetPosition; - transform.rotation = newTargetRotation; + float x = data.GetFloat("X").Value; + float y = data.GetFloat("Y").Value; + + Vector3 newTargetPosition = transform.position; + if (newX.HasValue && x != newX) newTargetPosition.x = newX.Value * scaleFactor; + if (newY.HasValue && y != newY) newTargetPosition.z = newY.Value * scaleFactor; + + if (newTargetPosition != transform.position) + { + + // ํ˜„์žฌ ์œ„์น˜์™€ ์ƒˆ๋กœ์šด ๋ชฉํ‘œ ์œ„์น˜ ์‚ฌ์ด์˜ ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. + float distanceToTarget = Vector3.Distance(transform.position, newTargetPosition); + + // ๊ฑฐ๋ฆฌ๊ฐ€ ์„ค์ •๋œ ์ž„๊ณ„๊ฐ’์„ ์ดˆ๊ณผํ•˜๋ฉด, ๋ณด๊ฐ„์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์ฆ‰์‹œ ์œ„์น˜์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + if (distanceToTarget > teleportDistanceThreshold) + { + transform.position = newTargetPosition; + isTeleport = true; // ์ˆœ๊ฐ„์ด๋™์ด ๋ฐœ์ƒํ–ˆ์Œ์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. + } + + // ์ƒˆ๋กœ์šด ๋ชฉํ‘œ ์ง€์ ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + // (์ˆœ๊ฐ„์ด๋™์„ ํ–ˆ๋“  ์•ˆ ํ–ˆ๋“ , ๋‹ค์Œ ํ”„๋ ˆ์ž„๋ถ€ํ„ฐ์˜ ๋ณด๊ฐ„์„ ์œ„ํ•ด ๋ชฉํ‘œ ์ง€์ ์€ ํ•ญ์ƒ ๊ฐฑ์‹ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.) + this.targetPosition = newTargetPosition; + } } - // ์ƒˆ๋กœ์šด ๋ชฉํ‘œ ์ง€์ ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. - // (์ˆœ๊ฐ„์ด๋™์„ ํ–ˆ๋“  ์•ˆ ํ–ˆ๋“ , ๋‹ค์Œ ํ”„๋ ˆ์ž„๋ถ€ํ„ฐ์˜ ๋ณด๊ฐ„์„ ์œ„ํ•ด ๋ชฉํ‘œ ์ง€์ ์€ ํ•ญ์ƒ ๊ฐฑ์‹ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.) - this.targetPosition = newTargetPosition; - this.targetRotation = newTargetRotation; + float? newDegree = newData.GetFloat("DEGREE"); + if(newDegree.HasValue) + { + if (data.GetFloat("DEGREE").Value != newDegree.Value) + { + Quaternion newTargetRotation = Quaternion.Euler(0, newDegree.Value, 0); + + // ๊ฑฐ๋ฆฌ๊ฐ€ ์„ค์ •๋œ ์ž„๊ณ„๊ฐ’์„ ์ดˆ๊ณผํ•˜๋ฉด, ๋ณด๊ฐ„์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ์ฆ‰์‹œ ์œ„์น˜/ํšŒ์ „์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค + if (isTeleport) transform.rotation = newTargetRotation; + + // ์ƒˆ๋กœ์šด ๋ชฉํ‘œ ์ง€์ ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. + // (์ˆœ๊ฐ„์ด๋™์„ ํ–ˆ๋“  ์•ˆ ํ–ˆ๋“ , ๋‹ค์Œ ํ”„๋ ˆ์ž„๋ถ€ํ„ฐ์˜ ๋ณด๊ฐ„์„ ์œ„ํ•ด ๋ชฉํ‘œ ์ง€์ ์€ ํ•ญ์ƒ ๊ฐฑ์‹ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.) + this.targetRotation = newTargetRotation; + } + } - newData.ReturnToPool(); // ์‚ฌ์šฉ์ด ๋๋‚œ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ํ’€์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. } } diff --git a/Assets/Scripts/UVC/Factory/Component/AGVManager.cs b/Assets/Scripts/UVC/Factory/Component/AGVManager.cs index 3cd77bfb..ed73e4ba 100644 --- a/Assets/Scripts/UVC/Factory/Component/AGVManager.cs +++ b/Assets/Scripts/UVC/Factory/Component/AGVManager.cs @@ -80,7 +80,21 @@ namespace UVC.Factory.Component { private readonly string prefabPath = "Prefabs/SampleProject/Factory/AGV"; - private MonoBehaviourPool? agvPool; + private GameObjectPool? agvPool; + + public GameObjectPool AGVPool + { + get + { + if (agvPool == null) + { + Debug.LogError("AGVPool is not initialized. Please call InitializePoolAsync first."); + } + return agvPool!; + } + } + + private bool created = false; /// /// AGVManager์˜ ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ์ž…๋‹ˆ๋‹ค. @@ -150,7 +164,7 @@ namespace UVC.Factory.Component Debug.LogError($"Prefab not found at path: {prefabPath}"); return; } - agvPool = new MonoBehaviourPool(prefab, transform); + agvPool = new GameObjectPool(prefab, transform); } /// @@ -176,7 +190,7 @@ namespace UVC.Factory.Component var RemovedItems = arr.RemovedItems; var ModifiedList = arr.ModifiedList; - Debug.Log($"AGVManager received data: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}"); + //Debug.Log($"AGVManager received data: Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}"); // ์ƒˆ๋กœ ์ถ”๊ฐ€๋œ AGV ์ฒ˜๋ฆฌ foreach (var item in AddedItems.ToList()) @@ -194,7 +208,7 @@ namespace UVC.Factory.Component "", item.GetString("MODE") ); - agv.UpdateData(item.Clone()); + agv.UpdateData(item.Copy()); } // ์ œ๊ฑฐ๋œ AGV ์ฒ˜๋ฆฌ @@ -211,16 +225,22 @@ namespace UVC.Factory.Component // ์ •๋ณด๊ฐ€ ์ˆ˜์ •๋œ AGV ์ฒ˜๋ฆฌ foreach (var item in ModifiedList.ToList()) { - Debug.Log($"AGVManager modified data: {item.ToString()}"); + if(item.Id == "HFF09CNA8047") Debug.Log($"AGVManager modified data: {item.ToString()}"); string vhlName = item.GetString("VHL_NAME")!; AGV? agv = agvPool.FindActiveItem(vhlName); if (agv != null) { - agv.UpdateData(item.Clone()); + agv.UpdateData(item.Copy()); } } arr.ReturnToPool(); + if(created == false) + { + created = true; + // ์”ฌ์ด ์ฒ˜์Œ ์ดˆ๊ธฐํ™”๋  ๋•Œ AGVManager๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์Œ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. + SceneMain.Instance.OnAGVManagerCreated(); + } } /// diff --git a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs index 30058035..971d61e5 100644 --- a/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs +++ b/Assets/Scripts/UVC/Factory/Component/FactoryObject.cs @@ -110,8 +110,11 @@ namespace UVC.Factory.Component /// } /// /// - public abstract class FactoryObject : InteractiveObject + public abstract class FactoryObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler { + [Tooltip("3D ๋ชจ๋ธ ๊ฐ์ฒด")] + public InteractiveObject? modelObject; + protected FactoryObjectInfo? info; /// @@ -149,9 +152,30 @@ namespace UVC.Factory.Component } } - - private void OnDestroy() + protected virtual void Awake() { + // ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. + if (modelObject == null) + { + Debug.LogError("FactoryObject requires an InteractiveObject component."); + } + else + { + modelObject.OnPointerClickHandler += OnPointerClick; + modelObject.OnPointerEnterHandler += OnPointerEnter; + modelObject.OnPointerExitHandler += OnPointerExit; + } + } + + + protected virtual void OnDestroy() + { + if (modelObject != null) + { + modelObject.OnPointerClickHandler -= OnPointerClick; + modelObject.OnPointerEnterHandler -= OnPointerEnter; + modelObject.OnPointerExitHandler -= OnPointerExit; + } FactoryObjectManager.Instance.UnregisterFactoryObject(Info!); } @@ -165,7 +189,7 @@ namespace UVC.Factory.Component /// `DataOrderedMask`๊ฐ€ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉด ํ•ด๋‹น ์ˆœ์„œ๋Œ€๋กœ, ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. /// /// ํฌ์ธํ„ฐ ํด๋ฆญ๊ณผ ๊ด€๋ จ๋œ ์ด๋ฒคํŠธ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. - public override void OnPointerClick(PointerEventData eventData) + public void OnPointerClick(PointerEventData eventData) { if (data != null && data.Count > 0) { @@ -190,18 +214,28 @@ namespace UVC.Factory.Component } } + /// + /// ํฌ์ธํ„ฐ๊ฐ€ ์ด ๊ฐ์ฒด ์œ„๋กœ ๋“ค์–ด์™”์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ด๋ผ์ดํŠธ ํšจ๊ณผ ๋“ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + /// + /// ํฌ์ธํ„ฐ ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. + public void OnPointerEnter(PointerEventData eventData) { } + + /// + /// ํฌ์ธํ„ฐ๊ฐ€ ์ด ๊ฐ์ฒด์—์„œ ๋ฒ—์–ด๋‚ฌ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. + /// + /// ํฌ์ธํ„ฐ ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. + public void OnPointerExit(PointerEventData eventData) { } + /// /// ์™ธ๋ถ€๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. /// ์ด ๋ฉ”์„œ๋“œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ `ProcessData`๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. /// MQTTPipeLineInfo.updatedDataOnly๊ฐ€ true์ธ ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ์—๋งŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. /// /// ์—…๋ฐ์ดํŠธํ•  ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ IDataObject ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. - public void UpdateData(IDataObject? newData) + public void UpdateData(DataObject newData) { if(newData == null) return; - DataObject? dataObject = newData as DataObject; - if (dataObject == null || dataObject.Count == 0) return; - ProcessData(dataObject); + ProcessData(newData); } /// diff --git a/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs b/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs index e3a9808d..ec9ed463 100644 --- a/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs +++ b/Assets/Scripts/UVC/Factory/Component/FactoryObjectManager.cs @@ -148,7 +148,7 @@ namespace UVC.Factory.Component /// ์ฐพ๊ณ ์ž ํ•˜๋Š” ๊ฐ์ฒด์˜ ID์ž…๋‹ˆ๋‹ค. /// ์ฒ˜์Œ์œผ๋กœ ๋ฐœ๊ฒฌ๋œ ์ผ์น˜ํ•˜๋Š” FactoryObject. ์—†์œผ๋ฉด null์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. public FactoryObject? FindById(string id) - { + { foreach (var kvp in FactoryObjects) { if (kvp.Key.Id.Equals(id, StringComparison.OrdinalIgnoreCase)) diff --git a/Assets/Scripts/UVC/Object3d/InteractiveObject.cs b/Assets/Scripts/UVC/Object3d/InteractiveObject.cs index c4aa8341..5dfa7f96 100644 --- a/Assets/Scripts/UVC/Object3d/InteractiveObject.cs +++ b/Assets/Scripts/UVC/Object3d/InteractiveObject.cs @@ -1,4 +1,6 @@ -๏ปฟusing UnityEngine; +๏ปฟusing System; +using Unity.VisualScripting; +using UnityEngine; using UnityEngine.EventSystems; namespace UVC.Object3d @@ -14,24 +16,37 @@ namespace UVC.Object3d /// 3. ๋ฉ”์ธ ์นด๋ฉ”๋ผ์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถ€์ฐฉ๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. /// [RequireComponent(typeof(Collider))] - public abstract class InteractiveObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler + public class InteractiveObject : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler { + public Action OnPointerClickHandler; + public Action OnPointerEnterHandler; + public Action OnPointerExitHandler; + /// /// ํฌ์ธํ„ฐ๋กœ ์ด ๊ฐ์ฒด๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. /// /// ํด๋ฆญ ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. - public virtual void OnPointerClick(PointerEventData eventData) {} + public virtual void OnPointerClick(PointerEventData eventData) + { + OnPointerClickHandler?.Invoke(eventData); + } /// /// ํฌ์ธํ„ฐ๊ฐ€ ์ด ๊ฐ์ฒด ์œ„๋กœ ๋“ค์–ด์™”์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ด๋ผ์ดํŠธ ํšจ๊ณผ ๋“ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. /// /// ํฌ์ธํ„ฐ ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. - public virtual void OnPointerEnter(PointerEventData eventData) {} + public virtual void OnPointerEnter(PointerEventData eventData) + { + OnPointerEnterHandler?.Invoke(eventData); + } /// /// ํฌ์ธํ„ฐ๊ฐ€ ์ด ๊ฐ์ฒด์—์„œ ๋ฒ—์–ด๋‚ฌ์„ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. /// /// ํฌ์ธํ„ฐ ์ด๋ฒคํŠธ์™€ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ์ž…๋‹ˆ๋‹ค. - public virtual void OnPointerExit(PointerEventData eventData) {} + public virtual void OnPointerExit(PointerEventData eventData) + { + OnPointerExitHandler?.Invoke(eventData); + } } } diff --git a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs b/Assets/Scripts/UVC/Pool/GameObjectPool.cs similarity index 83% rename from Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs rename to Assets/Scripts/UVC/Pool/GameObjectPool.cs index 507a49bc..d9c17ce0 100644 --- a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs +++ b/Assets/Scripts/UVC/Pool/GameObjectPool.cs @@ -17,12 +17,12 @@ namespace UVC.Pool /// { /// public GameObject bulletPrefab; /// public Transform bulletContainer; - /// private MonoBehaviourPool<Bullet> _bulletPool; + /// private GameObjectPool _bulletPool; /// /// void Start() /// { /// // ์ด์•Œ ํ”„๋ฆฌํŒน๊ณผ ๋ถ€๋ชจ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ’€์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. - /// _bulletPool = new MonoBehaviourPool<Bullet>(bulletPrefab, bulletContainer); + /// _bulletPool = new GameObjectPool(bulletPrefab, bulletContainer); /// } /// /// void SpawnBullet() @@ -42,7 +42,7 @@ namespace UVC.Pool /// /// /// ํ’€๋งํ•  MonoBehaviour ํƒ€์ž…์ž…๋‹ˆ๋‹ค. - public class MonoBehaviourPool where T : MonoBehaviour + public class GameObjectPool where T : MonoBehaviour { /// /// Resources ํด๋”์— ์žˆ๋Š” ํ”„๋ฆฌํŒน์˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. @@ -88,13 +88,19 @@ namespace UVC.Pool /// public Transform? RecycledItemContainer { get { return _recycledItemContainer; } } + // --- ํ†ต๊ณ„์šฉ ํ•„๋“œ --- + private int _inUseCount = 0; + private int _peakUsage = 0; + private int _poolMisses = 0; + private readonly object _statsLock = new object(); + /// /// GameObject ํ”„๋ฆฌํŒน์„ ์‚ฌ์šฉํ•˜์—ฌ ํ’€์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. /// /// ํ’€๋งํ•  ์˜ค๋ธŒ์ ํŠธ์˜ ์›๋ณธ ํ”„๋ฆฌํŒน์ž…๋‹ˆ๋‹ค. /// ํ™œ์„ฑํ™”๋œ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์œ„์น˜ํ•  ๋ถ€๋ชจ Transform์ž…๋‹ˆ๋‹ค. /// ๋น„ํ™œ์„ฑํ™”๋œ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์œ„์น˜ํ•  ๋ถ€๋ชจ Transform์ž…๋‹ˆ๋‹ค. ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด activeItemContainer๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. - public MonoBehaviourPool(GameObject originalPrefab, Transform activeItemContainer, Transform recycledItemContainer = null) + public GameObjectPool(GameObject originalPrefab, Transform activeItemContainer, Transform recycledItemContainer = null) { _originalPrefab = originalPrefab; _activeItemContainer = activeItemContainer; @@ -109,7 +115,7 @@ namespace UVC.Pool /// Resources ํด๋” ๊ธฐ์ค€์˜ ํ”„๋ฆฌํŒน ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค. /// ํ™œ์„ฑํ™”๋œ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์œ„์น˜ํ•  ๋ถ€๋ชจ Transform์ž…๋‹ˆ๋‹ค. /// ๋น„ํ™œ์„ฑํ™”๋œ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์œ„์น˜ํ•  ๋ถ€๋ชจ Transform์ž…๋‹ˆ๋‹ค. ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด activeItemContainer๊ฐ€ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. - public MonoBehaviourPool(string prefabsPath, Transform activeItemContainer, Transform recycledItemContainer) + public GameObjectPool(string prefabsPath, Transform activeItemContainer, Transform recycledItemContainer) { _prefabsPath = prefabsPath; _originalPrefab = Resources.Load(prefabsPath); @@ -133,6 +139,16 @@ namespace UVC.Pool } T? item = null; + + lock (_statsLock) + { + _inUseCount++; + if (_inUseCount > _peakUsage) + { + _peakUsage = _inUseCount; + } + } + if (_recycledItems.Count > 0) { item = _recycledItems[0]; @@ -140,6 +156,11 @@ namespace UVC.Pool } else { + lock (_statsLock) + { + _poolMisses++; + } + GameObject go = UnityEngine.Object.Instantiate(_originalPrefab); item = go.GetComponent(); } @@ -173,6 +194,11 @@ namespace UVC.Pool return; // ํ‚ค์— ํ•ด๋‹นํ•˜๋Š” ์•„์ดํ…œ์ด ์—†์œผ๋ฉด ๋ฐ˜ํ™˜ } + lock (_statsLock) + { + _inUseCount--; + } + _activeItems.Remove(key); _recycledItems.Add(item); @@ -224,5 +250,26 @@ namespace UVC.Pool } _recycledItems.Clear(); } + + /// + /// ํ’€์˜ ํ˜„์žฌ ์„ฑ๋Šฅ ํ†ต๊ณ„๋ฅผ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. + /// + /// ํ’€ ํ†ต๊ณ„ (์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰, ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰, ํ’€ ๋น„์–ด์žˆ์„ ๋•Œ ์ƒ์„ฑ ํšŸ์ˆ˜, ํ˜„์žฌ ํ’€ ํฌ๊ธฐ) + public string GetStats() + { + return $"์ตœ๋Œ€ ์‚ฌ์šฉ๋Ÿ‰: {_peakUsage}, ํ˜„์žฌ ์‚ฌ์šฉ๋Ÿ‰: {_inUseCount}, ํ’€ ๋น„์–ด์žˆ์„ ๋•Œ ์ƒ์„ฑ ํšŸ์ˆ˜: {_poolMisses}, ํ˜„์žฌ ํ’€ ํฌ๊ธฐ: {_recycledItems.Count}"; + } + + /// + /// ํ’€ ํ†ต๊ณ„๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. + /// + public void ResetStats() + { + lock (_statsLock) + { + _peakUsage = 0; + _poolMisses = 0; + } + } } } \ No newline at end of file diff --git a/Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta b/Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta new file mode 100644 index 00000000..17096f42 --- /dev/null +++ b/Assets/Scripts/UVC/Pool/GameObjectPool.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e163d2d37fef9bd49acd0f3fa5b5d2dc \ No newline at end of file diff --git a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta b/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta deleted file mode 100644 index e6061515..00000000 --- a/Assets/Scripts/UVC/Pool/MonoBehaviourPool.cs.meta +++ /dev/null @@ -1,2 +0,0 @@ -fileFormatVersion: 2 -guid: e9be41afc37616649924d7190be6215a \ No newline at end of file diff --git a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs b/Assets/Scripts/UVC/UI/Info/InfoWindow.cs index 63907495..b3ba6658 100644 --- a/Assets/Scripts/UVC/UI/Info/InfoWindow.cs +++ b/Assets/Scripts/UVC/UI/Info/InfoWindow.cs @@ -1,5 +1,6 @@ ๏ปฟ#nullable enable +using System; using System.Collections.Generic; using TMPro; using UnityEngine; @@ -19,10 +20,14 @@ namespace UVC.UI.Info [SerializeField] private TextMeshProUGUI text; - [Tooltip("์ •๋ณด ์ฐฝ์„ ๋‹ซ์„ ๋ฒ„ํŠผ")] + [Tooltip("์ •๋ณด ์ฐฝ์„ ๋‹ซ๋Š” ๋ฒ„ํŠผ")] [SerializeField] private Button closeButton; + [Tooltip("์ •๋ณด ์ฐฝ์˜ ๋‚ด์šฉ์„ ํด๋ฆฝ๋ณด๋“œ์— ๋ณต์‚ฌํ•  ๋ฒ„ํŠผ")] + [SerializeField] + private Button copyButton; + [Tooltip("UI๊ฐ€ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌ์ง€ ์•Š๋„๋ก ํ•  ์›”๋“œ ์ขŒํ‘œ๊ณ„ ์˜คํ”„์…‹")] [SerializeField] private Vector2 screenOffset = new Vector2(10f, 10f); @@ -34,6 +39,7 @@ namespace UVC.UI.Info // ์ •๋ณด ์ฐฝ์ด ๋”ฐ๋ผ๋‹ค๋‹ 3D ๊ฐ์ฒด์˜ Transform private Transform? target; + private string message = string.Empty; /// /// ์ •๋ณด ์ฐฝ์ด ํ˜„์žฌ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๊ณ  ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. @@ -54,6 +60,12 @@ namespace UVC.UI.Info closeButton.onClick.AddListener(Hide); } + if (copyButton != null) + { + copyButton.onClick.AddListener(CopyToClipboard); + } + + // ์ฒ˜์Œ์—๋Š” ์ •๋ณด ์ฐฝ์„ ์ˆจ๊น๋‹ˆ๋‹ค. if (gameObject.activeSelf) { @@ -61,6 +73,15 @@ namespace UVC.UI.Info } } + private void CopyToClipboard() + { + // ํด๋ฆฝ๋ณด๋“œ์— ํ˜„์žฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค. + if (!string.IsNullOrEmpty(message)) + { + GUIUtility.systemCopyBuffer = message; + } + } + private void LateUpdate() { // target์ด ์„ค์ •๋˜์–ด ์žˆ๊ณ  ํ™œ์„ฑํ™” ์ƒํƒœ์ผ ๋•Œ๋งŒ ์œ„์น˜์™€ ๋ฐฉํ–ฅ์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. @@ -158,6 +179,7 @@ namespace UVC.UI.Info } combinedString = combinedString.TrimEnd('\n'); // ๋งˆ์ง€๋ง‰ ์ค„๋ฐ”๊ฟˆ ์ œ๊ฑฐ text.text = combinedString; + message = combinedString; } // size๋ฅผ text์— ๋งž๊ฒŒ ์กฐ์ •ํ•ฉ๋‹ˆ๋‹ค. RectTransform? rect = GetComponent(); diff --git a/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs b/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs index 03b0f908..ad837bac 100644 --- a/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs +++ b/Assets/Scripts/UVC/UI/Menu/TopMenuController.cs @@ -1,6 +1,8 @@ ๏ปฟusing System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +using UVC.Data; +using UVC.Factory.Component; using UVC.Locale; using UVC.Log; using UVC.UI.Commands; @@ -215,17 +217,12 @@ namespace UVC.UI.Menu new MenuItemData("file_exit", "menu_file_exit", new QuitApplicationCommand()) // ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ ๋ช…๋ น ์—ฐ๊ฒฐ })); - // "ํŽธ์ง‘" ๋ฉ”๋‰ด ๋ฐ ํ•˜์œ„ ๋ฉ”๋‰ด๋“ค ์ •์˜ - model.MenuItems.Add(new MenuItemData("edit", "menu_edit", subMenuItems: new List + // pool ๋กœ๊ทธ + model.MenuItems.Add(new MenuItemData("log", "Log", subMenuItems: new List { - new MenuItemData("edit_undo", "menu_edit_undo", new DebugLogCommand("์‹คํ–‰ ์ทจ์†Œ ์„ ํƒ๋จ (Command ์‹คํ–‰)")), - new MenuItemData("edit_redo", "menu_edit_redo", new DebugLogCommand("๋‹ค์‹œ ์‹คํ–‰ ์„ ํƒ๋จ (Command ์‹คํ–‰)")), - MenuItemData.CreateSeparator("edit_sep1"), // ๊ตฌ๋ถ„์„  - new MenuItemData("file_save", "menu_file_save", command: new DebugLogCommand("์ €์žฅ ์„ ํƒ๋จ (Command ์‹คํ–‰)") , subMenuItems: new List - { - new MenuItemData("file_save_as", "menu_file_save_as", new DebugLogCommand("๋‹ค๋ฅธ ์ด๋ฆ„์œผ๋กœ ์ €์žฅ ์„ ํƒ๋จ (Command ์‹คํ–‰)")) - }), - new MenuItemData("preferences", "menu_preferences", new DebugLogCommand("ํ™˜๊ฒฝ์„ค์ • ์„ ํƒ๋จ (Command ์‹คํ–‰)")) + new MenuItemData("dataArray", "DataArray", new ActionCommand(() => Debug.Log($"DataArrayPool stats: {DataArrayPool.GetStats()}"))), + new MenuItemData("dataObject", "DataObjet", new ActionCommand(() => Debug.Log($"DataObjectPool stats: {DataObjectPool.GetStats()}"))), + new MenuItemData("agv", "AGVPool", new ActionCommand(() => Debug.Log($"AGVPool stats: {AGVManager.Instance.AGVPool.GetStats()}"))), })); model.MenuItems.Add(new MenuItemData("modal", "๋ชจ๋‹ฌ", subMenuItems: new List { diff --git a/Packages/manifest.json b/Packages/manifest.json index 2a5ed8b9..669a5e25 100644 --- a/Packages/manifest.json +++ b/Packages/manifest.json @@ -2,6 +2,7 @@ "dependencies": { "com.cysharp.unitask": "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask", "com.holyshovelsoft.opensource.log4uni": "https://github.com/HolyShovelSoft/log4uni.git#upm", + "com.unity.2d.sprite": "1.0.0", "com.unity.ai.navigation": "2.0.5", "com.unity.collab-proxy": "2.8.2", "com.unity.ide.rider": "3.0.31", diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 56f84e42..6de8da8f 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -14,6 +14,12 @@ "dependencies": {}, "hash": "39314556b525b9a5a4ea47b7166788422d1975e1" }, + "com.unity.2d.sprite": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, "com.unity.ai.navigation": { "version": "2.0.5", "depth": 0,