using LightGlue.Unity.Networking;
using LightGlue.Unity.Python;
using UnityEngine;
namespace LightGlue.Unity.Roma
{
///
/// Roma 新场景一键启动器:
/// - 启动广播发现
/// - 发现后配置 WiFi 图传并开启
/// - 启动 Roma Python(独立于 LightGlue_Deployment)
/// - 启动图像显示与结果接收(复用 UDPResultReceiver 协议/端口)
///
/// 约束:该脚本只应挂在 Roma 新场景中;用户不会同时运行旧场景与新场景。
///
public sealed class RomaSceneBootstrap : MonoBehaviour
{
[Header("Discovery + Control")]
public RomaDeviceDiscoveryListener discovery;
public RomaWifiCameraControlClient wifiControl;
[Header("Python (RoMa)")]
[Tooltip("Roma 专用 Python 进程控制器(需指向 LightGlue_Roma 工程目录与脚本)")]
public PythonProcessController romaPythonController;
[Header("Image Viewer (Python -> Unity)")]
public RomaForwardedImageViewer forwardedViewer;
[Header("Result Receiver (Python -> Unity)")]
[Tooltip("复用现有 UDPResultReceiver 协议(0x0001/20字节),监听 pythonResultPort=12348(可在 Inspector 改)")]
public bool enableResultReceiver = true;
public string resultBindIp = "127.0.0.1";
public int resultPort = 12348;
public int maxResultQueueSize = 10;
public UDPResultReceiver ResultReceiver => _resultReceiver;
private UDPResultReceiver _resultReceiver;
private void OnEnable()
{
// 如果已存在持久化 RomaManager,则不再在场景里重复启动/绑定端口
if (RomaManager.Instance != null)
{
enabled = false;
return;
}
Application.runInBackground = true;
if (discovery == null) discovery = FindObjectOfType();
if (wifiControl == null) wifiControl = FindObjectOfType();
if (forwardedViewer == null) forwardedViewer = FindObjectOfType();
if (wifiControl != null && discovery != null)
wifiControl.BindDiscovery(discovery);
if (discovery != null && !discovery.IsListening)
discovery.StartListening();
// 启动 Roma Python:这里不改旧工程逻辑,只调用 StartPython(Roma 控制器需在 Inspector 配好路径/脚本)
if (romaPythonController != null && !romaPythonController.IsRunning)
romaPythonController.StartPython();
if (enableResultReceiver)
{
try
{
_resultReceiver = new UDPResultReceiver(resultBindIp, resultPort, maxResultQueueSize);
_resultReceiver.Start();
}
catch (System.Exception ex)
{
Debug.LogError($"[RomaBootstrap] Start result receiver failed on {resultBindIp}:{resultPort}: {ex.Message}");
try { _resultReceiver?.Stop(); } catch { /* ignore */ }
_resultReceiver = null;
}
}
}
private void OnDisable()
{
try { _resultReceiver?.Stop(); } catch { /* ignore */ }
_resultReceiver = null;
}
///
/// Roma 场景侧提供一个“取最新结果”的便捷接口(与 Bridge.TryGetLatestResult 风格一致)。
///
public bool TryGetLatestResult(out LightGlueResult result)
{
result = default(LightGlueResult);
if (_resultReceiver == null) return false;
bool any = false;
while (_resultReceiver.TryDequeueResult(out var r))
{
result = r;
any = true;
}
return any;
}
}
}