Files
HDRobotics/Assets/Scripts/Presenter/ProgramPresenter.cs

306 lines
10 KiB
C#
Raw Normal View History

2025-10-24 11:55:43 +09:00
using System;
2025-10-30 09:31:05 +09:00
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
2025-10-24 11:55:43 +09:00
using UnityEngine.XR.ARSubsystems;
2025-10-30 09:31:05 +09:00
public enum PopupState
{
None,
ConfirmAddPoint,
ConfirmModifyPoint,
MoveOrDelete,
ConfirmDelete
}
public class ProgramPresenter
{
private ProgramModel model;
private IProgramView view;
2025-10-24 14:36:33 +09:00
private TCPView tcpView;
private RobotController controlledRobot;
private string _programId;
2025-10-24 11:55:43 +09:00
private bool lastKnownMotorState = false;
2025-10-30 09:31:05 +09:00
private IInteractionView interactionView;
private IPointManagerView pointManagerView;
private IPathLineView pathLineView;
private IPopupView popupView;
private PopupState currentPopupState = PopupState.None;
private RobotData pendingPointData; // <20>˾<EFBFBD>â<EFBFBD><C3A2> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD><D9B8><EFBFBD> <20>ӽ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private int activePointIndex = -1; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20>ε<EFBFBD><CEB5><EFBFBD>
private bool IsDragging = false;
public ProgramPresenter(ProgramModel model, IProgramView view, TCPView tcpView,
IInteractionView interactionView, IPointManagerView pmView, IPopupView popView, IPathLineView pathLineView)
{
this.model = model;
this.view = view;
2025-10-24 14:36:33 +09:00
this.tcpView = tcpView;
this.view.OnCreateProgramClicked += async (id) => await HandleCreateProgram(id);
this.view.OnLoadProgramListRequested += HandleLoadProgramList;
this.view.OnProgramSelectedToLoad += HandleProgramSelected;
this.view.OnOpenProgramClicked += async () => await HandleOpenProgram();
this.view.OnSaveClicked += HandleSaveProgram;
this.view.OnAddPointClicked += HandleAddPoint;
2025-10-24 14:36:33 +09:00
this.tcpView.OnTCPupdateRequested += HandleTCPViewUpdate;
2025-10-30 09:31:05 +09:00
//this.interactionView.OnRobotReleased += HandleRobotReleased;
//this.interactionView.OnPointClicked += HandlePointClicked;
//this.interactionView.OnPointDragStart += HandlePointDragStart;
//this.interactionView.OnPointDragUpdate += HandlePointDragUpdate;
//this.interactionView.OnPointDragEnd += HandlePointDragEnd;
//this.popupView.OnPopupResponse += HandlePopupResponse;
}
public void RegisterControlledRobot(RobotController robot)
{
this.controlledRobot = robot;
2025-10-30 09:31:05 +09:00
this.controlledRobot.OnPoseUpdateRequest += HandlePoseViewUpdate;
}
2025-10-24 11:55:43 +09:00
public async Task UpdateMotorStateAsync()
{
try
{
bool currentState = await model.GetRobotMotorStateAsync();
if (currentState != lastKnownMotorState)
{
controlledRobot.SetMotorState(currentState);
lastKnownMotorState = currentState;
}
}
catch (Exception e)
{
Debug.LogWarning($"<22><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD>: {e.Message}");
}
}
public void OnApplicationStart()
{
if (controlledRobot != null)
{
2025-10-24 11:55:43 +09:00
Debug.Log("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD>ϵǾ<CFB5><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>.");
}
else
{
Debug.LogError("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>κ<EFBFBD><CEBA><EFBFBD> <20><><EFBFBD>ϵ<EFBFBD><CFB5><EFBFBD> <20>ʾҽ<CABE><D2BD>ϴ<EFBFBD>");
}
}
private async Task HandleCreateProgram(string programId)
{
if (await model.CreateNewProgram(programId))
{
2025-10-24 11:55:43 +09:00
view.DisplayProgram(programId);
view.HideProgramSelectPanel();
OnApplicationStart();
}
else
{
view.ShowMessage($"Error: Program ID '{programId}.job' already exists or is invalid.");
}
}
private void HandleLoadProgramList()
{
var programIds = model.GetAllProgramIds();
view.ShowProgramList(programIds);
}
private void HandleProgramSelected(string programId)
{
_programId = programId;
}
private async Task HandleOpenProgram()
{
if(_programId != null && await model.LoadProgram(_programId))
{
2025-10-24 11:55:43 +09:00
view.DisplayProgram(_programId);
view.HideProgramSelectPanel();
view.HideProgramList();
OnApplicationStart();
_programId = null;
}
}
private void HandleSaveProgram()
{
//model.SaveCurrentProgram();
}
private void HandleAddPoint()
{
//// <20><><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD> UI<55><49><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5> <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><>ǥ<EFBFBD><C7A5> <20>޾ƿ;<C6BF> <20><>
//// <20><><EFBFBD><EFBFBD><E2BCAD> <20><><EFBFBD>÷<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ǥ<EFBFBD><C7A5> <20><><EFBFBD><EFBFBD>
//Vector3 newPoint = new Vector3(Random.Range(-1f, 1f), Random.Range(0f, 1f), Random.Range(-1f, 1f));
//model.AddPointToCurrentProgram(newPoint);
//view.DisplayProgram(model.CurrentProgram);
}
2025-10-24 14:36:33 +09:00
private void HandleTCPViewUpdate()
{
if (model.IsNewDataAvailable())
{
RobotData data = model.GetLatestRobotData();
tcpView.SetCoordinates(data);
}
}
2025-10-30 09:31:05 +09:00
// --- <20>ǽð<C7BD> <20><><EFBFBD><EFBFBD>ȭ ---
private void HandlePoseViewUpdate()
{
RobotData data = model.GetLatestRobotData();
controlledRobot.SetRobotPosition(data); // 3D <20><><EFBFBD><EFBFBD> <20>κ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ġ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ
}
// --- <20><> <20><><EFBFBD><EFBFBD>Ʈ <20>߰<EFBFBD> ---
private void HandleRobotReleased(RobotData pose)
{
pendingPointData = pose; // 1. <20>ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>
currentPopupState = PopupState.ConfirmAddPoint; // 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
popupView.ShowConfirmPopup("<22><>ġ Ȯ<><C8AE>", "<22><> <20><>ġ<EFBFBD><C4A1> <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻðڽ<C3B0><DABD>ϱ<EFBFBD>?"); // 3. <20>˾<EFBFBD> <20><>û
}
// --- <20><><EFBFBD><EFBFBD>Ʈ Ŭ<><C5AC> ---
private void HandlePointClicked(int index)
{
activePointIndex = index; // <20>ε<EFBFBD><CEB5><EFBFBD> <20><><EFBFBD><EFBFBD>
currentPopupState = PopupState.MoveOrDelete; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
popupView.ShowOptionPopup("<22><><EFBFBD><EFBFBD>Ʈ <20>۾<EFBFBD>", "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ͻðڽ<C3B0><DABD>ϱ<EFBFBD>?", "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD>", "<22><><EFBFBD><EFBFBD>"); // <20>˾<EFBFBD> <20><>û
}
// --- <20><><EFBFBD><EFBFBD>Ʈ <20><EFBFBD><E5B7A1> ---
private RobotData originalDragPose; // <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>ư<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ġ
private void HandlePointDragStart(int index)
{
IsDragging = true;
activePointIndex = index;
originalDragPose = model.CurrentProgram.GetStepPose(index);
//interactionView.ShowDragArrow(GetPositionFromPose(originalDragPose));
interactionView.ShowGhostRobot(originalDragPose);
}
private async void HandlePointDragUpdate(int index, Vector3 newWorldPos)
{
if (!IsDragging) return;
//RobotData newPose = ConvertVectorToRobotData(newWorldPos);
// <20><><EFBFBD><EFBFBD>Ʈ <20>κ<EFBFBD>, <20><><EFBFBD><EFBFBD>Ʈ, <20><><EFBFBD><EFBFBD> <20>ǽð<C7BD> <20>̵<EFBFBD>
//interactionView.ShowGhostRobot(newPose);
//pointManagerView.UpdatePointPosition(index, newPose);
//pathLineView.DrawPath(GetFullPathOfProgramWithTempChange(index, newPose)); // <20>ӽ<EFBFBD> <20><><EFBFBD><EFBFBD> <20>׸<EFBFBD><D7B8><EFBFBD>
//await model.StreamPoseToRobotUdpAsync(newPose);
}
private void HandlePointDragEnd(int index)
{
//IsDragging = false;
//interactionView.HideDragArrow();
//interactionView.HideGhostRobot();
//// (<28><><EFBFBD><EFBFBD> <20>κ<EFBFBD> <20><>ġ <20>̵<EFBFBD> <20><><EFBFBD><EFBFBD> - 5<>ܰ<EFBFBD>)
//// robotController.SetRobotPosition(newPose);
//pendingPointData = ConvertVectorToRobotData(GetLastDragPosition()); // <20>ӽ<EFBFBD> <20><><EFBFBD><EFBFBD>
//currentPopupState = PopupState.ConfirmModifyPoint; // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
//popupView.ShowConfirmPopup("<22><>ġ <20><><EFBFBD><EFBFBD>", "<22><> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻðڽ<C3B0><DABD>ϱ<EFBFBD>?"); // <20>˾<EFBFBD> <20><>û
}
// --- <20>˾<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ڵ鷯 ---
private async void HandlePopupResponse(PopupResponse response)
{
popupView.HidePopup();
switch (currentPopupState)
{
case PopupState.ConfirmAddPoint:
if (response == PopupResponse.Confirm) // Ȯ<><C8AE>
{
await model.SavePointToProgramAsync(pendingPointData);
RedrawSceneFromModel(); // <20><> <20><><EFBFBD><EFBFBD>
}
break;
// <20><EFBFBD><E5B7A1> Ȯ<><C8AE>/<2F><><EFBFBD><EFBFBD>
case PopupState.ConfirmModifyPoint:
if (response == PopupResponse.Confirm) // Ȯ<><C8AE>
{
// <20><><EFBFBD><EFBFBD> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
// <20><EFBFBD>װ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><>ġ<EFBFBD><C4A1> <20><><EFBFBD>α׷<CEB1><D7B7><EFBFBD> <20><><EFBFBD><EFBFBD>
await model.SavePointToProgramAsync(pendingPointData, activePointIndex);
RedrawSceneFromModel();
}
else // <20><><EFBFBD><EFBFBD>
{
pointManagerView.UpdatePointPosition(activePointIndex, originalDragPose); // <20><><EFBFBD><EFBFBD>ġ
RedrawSceneFromModel(); // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ġ
}
break;
// <20>̵<EFBFBD>/<2F><><EFBFBD><EFBFBD>
case PopupState.MoveOrDelete:
if (response == PopupResponse.Option1) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD>
{
RobotData targetPose = model.CurrentProgram.GetStepPose(activePointIndex);
//await model.StartMovement(targetPose);
}
else if (response == PopupResponse.Option2) // <20><><EFBFBD><EFBFBD>
{
currentPopupState = PopupState.ConfirmDelete;
popupView.ShowConfirmPopup("<22><><EFBFBD><EFBFBD> Ȯ<><C8AE>", "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD><EFBFBD>Ͻðڽ<C3B0><DABD>ϱ<EFBFBD>?");
}
break;
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
case PopupState.ConfirmDelete:
if (response == PopupResponse.Confirm)
{
await model.DeletePointFromProgramAsync(activePointIndex);
RedrawSceneFromModel();
}
break;
}
// <20><><EFBFBD><EFBFBD> <20>۾<EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20>ʱ<EFBFBD>ȭ
currentPopupState = PopupState.None;
activePointIndex = -1;
}
// Model<65><6C> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>¸<EFBFBD> <20>о<EFBFBD> <20><><EFBFBD><EFBFBD> View(<28><><EFBFBD><EFBFBD>Ʈ, <20><><EFBFBD><EFBFBD>)<29><> <20><><EFBFBD><EFBFBD> <20><>ħ
private void RedrawSceneFromModel()
{
//if (model.CurrentProgram == null) return;
//// (RobotProgram.Steps (List<RobotMoveStep>)<29><> List<RobotData><3E><> <20><>ȯ<EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>)
//List<RobotData> poses = model.CurrentProgram.GetAllStepPoses();
//pointManagerView.RedrawPoints(poses); // <20><><EFBFBD><EFBFBD>Ʈ <20>ٽ<EFBFBD> <20>׸<EFBFBD>
//pathLineView.DrawPath(poses); // <20><><EFBFBD><EFBFBD> <20>ٽ<EFBFBD> <20>׸<EFBFBD>
}
private void Destroy()
{
this.view.OnCreateProgramClicked -= async (id) => await HandleCreateProgram(id);
this.view.OnLoadProgramListRequested -= HandleLoadProgramList;
this.view.OnProgramSelectedToLoad -= HandleProgramSelected;
this.view.OnOpenProgramClicked -= async () => await HandleOpenProgram();
this.view.OnSaveClicked -= HandleSaveProgram;
this.view.OnAddPointClicked -= HandleAddPoint;
2025-10-24 14:36:33 +09:00
this.tcpView.OnTCPupdateRequested -= HandleTCPViewUpdate;
}
}