버그 처리

This commit is contained in:
logonkhi
2025-07-24 20:40:21 +09:00
parent a0c90b1e82
commit f5a36697ba
60 changed files with 70 additions and 93 deletions

View File

@@ -87,7 +87,7 @@ namespace UVC.Data
dataObject.MarkAllAsUpdated();
var newData = dataObject.Clone(fromPool: false);
dataObjects.Add(key, newData);
NotifyDataUpdate(key, newData);
NotifyDataUpdate(key, newData.Clone(false));
return dataObject;
}
else
@@ -104,7 +104,7 @@ namespace UVC.Data
newDataObject = dataObject;
}
bool shouldInvoke = !updatedDataOnly || newDataObject.UpdatedCount > 0;
if(shouldInvoke) NotifyDataUpdate(key, newDataObject);
if (shouldInvoke) NotifyDataUpdate(key, newDataObject == dataObject ? newDataObject.Clone(false) : newDataObject);
return newDataObject;
}
}

View File

@@ -96,34 +96,20 @@ namespace UVC.Data.Http
cancellationToken.ThrowIfCancellationRequested();
// 매핑된 데이터를 DataRepository에 저장하거나 업데이트합니다.
var repoObject = mappedObject;
if (mappedObject != null)
{
// DataRepository는 모든 데이터를 중앙에서 관리하는 저장소입니다.
repoObject = DataRepository.Instance.AddOrUpdateData(key, mappedObject, info.UpdatedDataOnly);
var repoObject = DataRepository.Instance.AddOrUpdateData(key, mappedObject, info.UpdatedDataOnly);
// 만약 반환된 객체가 원본과 같다면, 핸들러에 전달하기 위해 복제본을 만듭니다.
if (repoObject == mappedObject) repoObject = mappedObject.Clone(fromPool: false);
}
// 'UpdatedDataOnly' 옵션이 켜져 있고, 실제로 데이터가 업데이트되었을 때만 핸들러를 호출합니다.
if (info.UpdatedDataOnly)
{
if (repoObject != null && repoObject.UpdatedCount > 0)
{
if (info.SuccessHandler != null)
{
var handlerData = repoObject;
UniTask.Post(() => info.SuccessHandler.Invoke(handlerData));
}
return;
}
}
// 최종적으로 처리된 데이터가 있는 경우 성공 핸들러를 호출합니다.
if (repoObject != null)
{
if (info.SuccessHandler != null)
bool shouldInvoke = !info.UpdatedDataOnly || (repoObject != null && repoObject.UpdatedCount > 0);
// 'UpdatedDataOnly' 옵션이 켜져 있고, 실제로 데이터가 업데이트되었을 때만 핸들러를 호출합니다.
if (shouldInvoke && info.SuccessHandler != null)
{
var handlerData = repoObject;
UniTask.Post(() => info.SuccessHandler.Invoke(handlerData));
return;
}
}
// 처리된 데이터가 없는 경우 실패 핸들러를 호출합니다.

View File

@@ -99,6 +99,9 @@ namespace UVC.Data.Mqtt
private MockMQTTService? mockupMQTT;
public string LastMessage { get; private set; } = string.Empty;
/// <summary>
/// MqttDataReceiver 인스턴스를 생성합니다.
/// </summary>
@@ -231,7 +234,8 @@ namespace UVC.Data.Mqtt
{
IDataObject? mappedObject = null;
message = message.Trim();
message = message.Trim();
LastMessage = message; // 마지막 메시지를 저장하여 나중에 사용할 수 있습니다.
if (!string.IsNullOrEmpty(message))
{
try

View File

@@ -142,7 +142,6 @@ namespace UVC.Factory.Alarm
DataArray? arr = data as DataArray;
if (arr == null || arr.Count == 0) return;
//Debug.Log($"AlarmManager OnUpdateData: count:{arr.Count}, Added={arr.AddedItems.Count}, Removed={arr.RemovedItems.Count}, Modified={arr.ModifiedList.Count}");
//3d 객체가 생성 된 후 호출 되도록 하기 위해
// Run으로 호출 된 후 호출 되도록
@@ -152,6 +151,13 @@ namespace UVC.Factory.Alarm
return;
}
//Debug.Log($"AlarmManager OnUpdateData: count:{arr.Count}, Added={arr.AddedItems.Count}, Removed={arr.RemovedItems.Count}, Modified={arr.ModifiedList.Count}");
// 디버그용: 알람 데이터의 총 개수, 추가된 항목+제거된 항목+수정된 항목의 합이 다른것은 ModifiedList으로 분류 되서 항목들을 검사했지만 다른 부분이 없어서 ModifiedList 항목에 추가 되지 않은 것임
//if (arr.Count != arr.AddedItems.Count + arr.RemovedItems.Count + arr.ModifiedList.Count)
//{
// Debug.Log("AlarmManager not same");
//}
// 데이터 배열에서 추가, 제거, 수정된 항목 리스트를 가져옵니다.
var AddedItems = arr.AddedItems;
var RemovedItems = new List<DataObject>(arr.RemovedItems);

View File

@@ -88,13 +88,11 @@ namespace UVC.Factory.Component
else // 이미 데이터가 있는 경우 (업데이트)
{
if (data.Id == "HFF09CNA8061") Debug.Log($"AGV: {newData}");
// 새 데이터를 기반으로 목표 위치와 회전을 갱신합니다.
UpdatePositionAndRotation(newData);
// 기존 데이터(data)에 새로운 데이터(newData)의 내용을 덮어씁니다.
foreach (var keyValue in newData)
{
{
data[keyValue.Key] = keyValue.Value;
}
}
@@ -124,23 +122,17 @@ namespace UVC.Factory.Component
float? newX = newData.GetFloat("X");
float? newY = newData.GetFloat("Y");
if (data.Id == "HFF09CNA8061") Debug.Log($"AGV newX.HasValue:{newX.HasValue}, newY.HasValue:{newY.HasValue}");
if (newX.HasValue || newY.HasValue)
float x = data.GetFloat("X").Value;
float y = data.GetFloat("Y").Value;
if ((newX.HasValue && x != newX) || (newY.HasValue && y != newY))
{
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;
// 현재 위치와 새로운 목표 위치 사이의 거리를 계산합니다.
float distanceToTarget = Vector3.Distance(transform.position, newTargetPosition);
if (data.Id == "HFF09CNA8061") Debug.Log($"AGV distanceToTarget:{distanceToTarget}, x:{newTargetPosition.x}_{transform.position.x}, z:{newTargetPosition.z}_{transform.position.z}, y:{newTargetPosition.y}_{transform.position.y}");
if (distanceToTarget > 0)
{
//Debug.Log($"AGV {data.GetString("VHL_NAME")} moving to new position: {newTargetPosition} (Distance: {distanceToTarget})");
// 거리가 설정된 임계값을 초과하면, 보간을 건너뛰고 즉시 위치을 설정합니다.
if (distanceToTarget > teleportDistanceThreshold)
{
@@ -156,31 +148,26 @@ namespace UVC.Factory.Component
}
float? newDegree = newData.GetFloat("DEGREE");
if (newDegree.HasValue)
if (newDegree.HasValue && data.GetFloat("DEGREE").Value != newDegree.Value)
{
if (data.GetFloat("DEGREE").Value != newDegree.Value)
{
Quaternion newTargetRotation = Quaternion.Euler(0, newDegree.Value, 0);
Quaternion newTargetRotation = Quaternion.Euler(0, newDegree.Value, 0);
// 거리가 설정된 임계값을 초과하면, 보간을 건너뛰고 즉시 위치/회전을 설정합니다
if (isTeleport) transform.rotation = newTargetRotation;
// 거리가 설정된 임계값을 초과하면, 보간을 건너뛰고 즉시 위치/회전을 설정합니다
if (isTeleport) transform.rotation = newTargetRotation;
// 새로운 목표 지점을 설정합니다.
// (순간이동을 했든 안 했든, 다음 프레임부터의 보간을 위해 목표 지점은 항상 갱신되어야 합니다.)
this.targetRotation = newTargetRotation;
changed = true;
}
// 새로운 목표 지점을 설정합니다.
// (순간이동을 했든 안 했든, 다음 프레임부터의 보간을 위해 목표 지점은 항상 갱신되어야 합니다.)
this.targetRotation = newTargetRotation;
changed = true;
}
if (data.Id == "HFF09CNA8061") Debug.Log($"AGV changed: {changed}");
if (changed)
{
ChangeColor(Color.red);
}
else
{
//ChangeColor(Color.white);
ChangeColor(Color.white);
}
}
}

View File

@@ -80,7 +80,7 @@ namespace UVC.Factory.Component
public class AGVManager : SingletonScene<AGVManager>
{
private readonly string prefabPath = "Prefabs/UI/Factory/AGV";
private readonly string prefabPath = "Prefabs/Factory/AGV";
private GameObjectPool<AGV>? agvPool;
public GameObjectPool<AGV> AGVPool
@@ -168,7 +168,7 @@ namespace UVC.Factory.Component
var RemovedItems = arr.RemovedItems;
var ModifiedList = arr.ModifiedList;
Debug.Log($"AGVManager received data: count:{arr.Count}, Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
//Debug.Log($"AGVManager received data: count:{arr.Count}, Added={AddedItems.Count}, Removed={RemovedItems.Count}, Modified={ModifiedList.Count}");
// 새로 추가된 AGV 처리
foreach (var item in AddedItems.ToList())

View File

@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
@@ -201,14 +201,14 @@ namespace UVC.Factory.Component
{
if (data.ContainsKey(key))
{
info[key] = data[key];
info[key] = data[key]!;
}
}
}
else
{
// dataOrderedMask가 설정되어 있지 않으면 모든 데이터를 사용합니다.
info = new Dictionary<string, object>(data);
info = new Dictionary<string, object>(data!);
}
InfoWindow.Instance.Show(transform, info);
}

View File

@@ -1,4 +1,4 @@
using UnityEngine;
using UnityEngine;
using UVC.Data;
using UVC.Factory.Playback.UI;
using UVC.UI.Commands;
@@ -12,7 +12,7 @@ namespace UVC.Factory.Playback
public async void Execute(object parameter = null)
{
var modalContent = new ModalContent("Prefabs/Factory/Playback/UIPlaybackListModal")
var modalContent = new ModalContent(UIPlaybackListModal.PrefabPath)
{
Title = "Playback List",
ConfirmButtonText = "Play",

View File

@@ -1,10 +1,11 @@
#nullable enable
#nullable enable
using Best.HTTP;
using Cysharp.Threading.Tasks;
using SampleProject.Config;
using System;
using System.Collections.Generic;
using UnityEngine;
using UVC.Data;
using UVC.Network;
namespace UVC.Factory.Playback
@@ -28,7 +29,7 @@ namespace UVC.Factory.Playback
{
return await UniTask.RunOnThreadPool<Dictionary<string, Dictionary<string, string>>?>(async () =>
{
var response = await HttpRequester.RequestGet<HttpResponseModel<Dictionary<string, Dictionary<string, string>>>>($"{Constants.PlaybackDomain}/playback/list");
var response = await HttpRequester.RequestGet<HttpResponseModel<Dictionary<string, Dictionary<string, string>>>>(URLList.Get("playbackList"));
if (response.message.ToLower() == "success")
{
return new Dictionary<string, Dictionary<string, string>>(response.data);

View File

@@ -1,4 +1,4 @@
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using System.IO;
@@ -6,9 +6,7 @@ using System.Linq;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UVC.Extension;
using UVC.Log;
using UVC.UI;
using UVC.UI.Modal;
using UVC.Util;
@@ -37,19 +35,13 @@ namespace UVC.Factory.Playback.UI
private TMP_Dropdown dropdownDate;
[SerializeField]
private ScrollRect scrollRectTime;
public void Init()
{
initContent();
}
public override async UniTask OnOpen(ModalContent content)
{
await base.OnOpen(content); // 부모의 OnOpen을 먼저 호출해서 기본 UI를 설정해요.
initContent();
}
public override object GetResult()
@@ -61,8 +53,8 @@ namespace UVC.Factory.Playback.UI
public override async UniTask OnClose(ModalContent content)
{
await base.OnClose(content);
}
@@ -254,7 +246,7 @@ namespace UVC.Factory.Playback.UI
dateList.Sort((b, a) => a.text.CompareTo(b.text));
dropdownDate.options = dateList;
dropdownDate.value = -1;
}