Refactor TaskButtonManager and TaskTimer to streamline timer command handling
This commit is contained in:
@ -15,10 +15,16 @@ public class TaskButtonManager : MonoBehaviour
|
|||||||
private Thread udpListenerThread;
|
private Thread udpListenerThread;
|
||||||
private bool isListening = false;
|
private bool isListening = false;
|
||||||
private string pendingSceneName = null;
|
private string pendingSceneName = null;
|
||||||
|
private string pendingTimerCommand = null;
|
||||||
private readonly object sceneLock = new object();
|
private readonly object sceneLock = new object();
|
||||||
|
private readonly object timerLock = new object();
|
||||||
|
private TaskTimer taskTimer;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
// Find TaskTimer in the scene
|
||||||
|
taskTimer = FindObjectOfType<TaskTimer>();
|
||||||
|
|
||||||
if (enableUDPControl)
|
if (enableUDPControl)
|
||||||
{
|
{
|
||||||
StartUDPListener();
|
StartUDPListener();
|
||||||
@ -37,6 +43,23 @@ public class TaskButtonManager : MonoBehaviour
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for pending timer commands (must be done on main thread)
|
||||||
|
lock (timerLock)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(pendingTimerCommand))
|
||||||
|
{
|
||||||
|
if (taskTimer != null)
|
||||||
|
{
|
||||||
|
taskTimer.ProcessTimerCommand(pendingTimerCommand);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning("TaskTimer not found in scene. Cannot process timer command.");
|
||||||
|
}
|
||||||
|
pendingTimerCommand = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VR Tasks (Keys 1-4)
|
// VR Tasks (Keys 1-4)
|
||||||
if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1))
|
if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1))
|
||||||
LoadSceneByName("VR-Task1");
|
LoadSceneByName("VR-Task1");
|
||||||
@ -108,20 +131,39 @@ public class TaskButtonManager : MonoBehaviour
|
|||||||
if (string.IsNullOrEmpty(message))
|
if (string.IsNullOrEmpty(message))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Parse command format: SWITCH:SceneName
|
// Parse command format: COMMAND:Parameter
|
||||||
string[] parts = message.Split(':');
|
string[] parts = message.Split(':');
|
||||||
if (parts.Length == 2 && parts[0].Trim().ToUpper() == "SWITCH")
|
if (parts.Length >= 2)
|
||||||
{
|
{
|
||||||
string sceneName = parts[1].Trim();
|
string commandType = parts[0].Trim().ToUpper();
|
||||||
lock (sceneLock)
|
string parameter = parts[1].Trim();
|
||||||
|
|
||||||
|
if (commandType == "SWITCH")
|
||||||
{
|
{
|
||||||
pendingSceneName = sceneName;
|
// Scene switching command
|
||||||
|
lock (sceneLock)
|
||||||
|
{
|
||||||
|
pendingSceneName = parameter;
|
||||||
|
}
|
||||||
|
Debug.Log($"Scheduled scene switch to: {parameter}");
|
||||||
|
}
|
||||||
|
else if (commandType == "TIMER")
|
||||||
|
{
|
||||||
|
// Timer control command
|
||||||
|
lock (timerLock)
|
||||||
|
{
|
||||||
|
pendingTimerCommand = parameter;
|
||||||
|
}
|
||||||
|
Debug.Log($"Scheduled timer command: {parameter}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Unknown UDP command type: {commandType}. Expected: SWITCH or TIMER");
|
||||||
}
|
}
|
||||||
Debug.Log($"Scheduled scene switch to: {sceneName}");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Debug.LogWarning($"Invalid UDP command format: {message}. Expected format: SWITCH:SceneName");
|
Debug.LogWarning($"Invalid UDP command format: {message}. Expected format: COMMAND:Parameter (e.g., SWITCH:SceneName or TIMER:START)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,10 +2,6 @@ using UnityEngine;
|
|||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
using TMPro;
|
using TMPro;
|
||||||
using System.Net;
|
|
||||||
using System.Net.Sockets;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
public class TaskTimer : MonoBehaviour
|
public class TaskTimer : MonoBehaviour
|
||||||
{
|
{
|
||||||
@ -20,8 +16,6 @@ public class TaskTimer : MonoBehaviour
|
|||||||
public float warningThreshold = 30f;
|
public float warningThreshold = 30f;
|
||||||
|
|
||||||
[Header("UDP Control Settings")]
|
[Header("UDP Control Settings")]
|
||||||
[SerializeField] private int udpPort = 5555;
|
|
||||||
[SerializeField] private bool enableUDPControl = true;
|
|
||||||
[Tooltip("If enabled, timer will only start via UDP command (ignores autoStart)")]
|
[Tooltip("If enabled, timer will only start via UDP command (ignores autoStart)")]
|
||||||
[SerializeField] private bool waitForUDPStart = false;
|
[SerializeField] private bool waitForUDPStart = false;
|
||||||
|
|
||||||
@ -45,21 +39,9 @@ public class TaskTimer : MonoBehaviour
|
|||||||
private float timeRemaining;
|
private float timeRemaining;
|
||||||
private bool isRunning;
|
private bool isRunning;
|
||||||
|
|
||||||
// UDP infrastructure
|
|
||||||
private UdpClient udpClient;
|
|
||||||
private Thread udpListenerThread;
|
|
||||||
private bool isListening = false;
|
|
||||||
private string pendingCommand = null;
|
|
||||||
private readonly object commandLock = new object();
|
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
timeRemaining = taskDuration;
|
timeRemaining = taskDuration;
|
||||||
|
|
||||||
if (enableUDPControl)
|
|
||||||
{
|
|
||||||
StartUDPListener();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only auto-start if not waiting for UDP command
|
// Only auto-start if not waiting for UDP command
|
||||||
if (autoStart && !waitForUDPStart)
|
if (autoStart && !waitForUDPStart)
|
||||||
@ -72,16 +54,6 @@ public class TaskTimer : MonoBehaviour
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
// Check for pending UDP commands (must be done on main thread)
|
|
||||||
lock (commandLock)
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(pendingCommand))
|
|
||||||
{
|
|
||||||
ProcessTimerCommand(pendingCommand);
|
|
||||||
pendingCommand = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isRunning)
|
if (!isRunning)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -189,72 +161,11 @@ public class TaskTimer : MonoBehaviour
|
|||||||
return 1f - (timeRemaining / taskDuration);
|
return 1f - (timeRemaining / taskDuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDP Control Methods
|
// Public method to process timer commands (called from UDP listener in TaskButtonManager)
|
||||||
private void StartUDPListener()
|
public void ProcessTimerCommand(string command)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
isListening = true;
|
|
||||||
udpClient = new UdpClient(udpPort);
|
|
||||||
udpListenerThread = new Thread(new ThreadStart(ListenForUDPCommands));
|
|
||||||
udpListenerThread.IsBackground = true;
|
|
||||||
udpListenerThread.Start();
|
|
||||||
Debug.Log($"TaskTimer: UDP Listener started on port {udpPort}");
|
|
||||||
}
|
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
Debug.LogError($"TaskTimer: Failed to start UDP listener: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ListenForUDPCommands()
|
|
||||||
{
|
|
||||||
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, udpPort);
|
|
||||||
|
|
||||||
while (isListening)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
byte[] data = udpClient.Receive(ref remoteEndPoint);
|
|
||||||
string message = Encoding.UTF8.GetString(data);
|
|
||||||
ProcessUDPCommand(message);
|
|
||||||
}
|
|
||||||
catch (System.Exception e)
|
|
||||||
{
|
|
||||||
if (isListening)
|
|
||||||
{
|
|
||||||
Debug.LogError($"TaskTimer: UDP receive error: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessUDPCommand(string message)
|
|
||||||
{
|
|
||||||
Debug.Log($"TaskTimer: Received UDP command: {message}");
|
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(message))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Parse command format: TIMER:COMMAND (e.g., TIMER:START, TIMER:PAUSE, TIMER:RESET, TIMER:RESUME)
|
|
||||||
string[] parts = message.Split(':');
|
|
||||||
if (parts.Length == 2 && parts[0].Trim().ToUpper() == "TIMER")
|
|
||||||
{
|
|
||||||
string command = parts[1].Trim().ToUpper();
|
|
||||||
lock (commandLock)
|
|
||||||
{
|
|
||||||
pendingCommand = command;
|
|
||||||
}
|
|
||||||
Debug.Log($"TaskTimer: Scheduled command: {command}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Debug.LogWarning($"TaskTimer: Invalid UDP command format: {message}. Expected format: TIMER:COMMAND (e.g., TIMER:START)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ProcessTimerCommand(string command)
|
|
||||||
{
|
{
|
||||||
|
command = command.ToUpper();
|
||||||
|
|
||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case "START":
|
case "START":
|
||||||
@ -274,34 +185,5 @@ public class TaskTimer : MonoBehaviour
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
StopUDPListener();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnApplicationQuit()
|
|
||||||
{
|
|
||||||
StopUDPListener();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StopUDPListener()
|
|
||||||
{
|
|
||||||
isListening = false;
|
|
||||||
|
|
||||||
if (udpClient != null)
|
|
||||||
{
|
|
||||||
udpClient.Close();
|
|
||||||
udpClient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (udpListenerThread != null && udpListenerThread.IsAlive)
|
|
||||||
{
|
|
||||||
udpListenerThread.Abort();
|
|
||||||
udpListenerThread = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug.Log("TaskTimer: UDP Listener stopped");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user