Rework SWE boundary control to ghost inflows and boundary profiles
This commit is contained in:
@@ -22,12 +22,20 @@ namespace FloodSWE.Networking
|
||||
private IPEndPoint serverEndpoint;
|
||||
private float lastAckTimeUnscaled = -1.0f;
|
||||
private float lastHelloSentTimeUnscaled = -1.0f;
|
||||
private float lastStateTimeUnscaled = -1.0f;
|
||||
private string lastAckMessage = "";
|
||||
private SweBoundaryStateMessage lastBoundaryState;
|
||||
private bool connectRequested;
|
||||
|
||||
public event Action<SweBoundaryStateMessage> BoundaryStateReceived;
|
||||
|
||||
public bool HasReceivedAck => lastAckTimeUnscaled >= 0.0f;
|
||||
public float LastAckAgeSeconds => HasReceivedAck ? Time.unscaledTime - lastAckTimeUnscaled : float.PositiveInfinity;
|
||||
public string LastAckMessage => lastAckMessage;
|
||||
public bool HasBoundaryState => lastStateTimeUnscaled >= 0.0f;
|
||||
public float LastBoundaryStateAgeSeconds =>
|
||||
HasBoundaryState ? Time.unscaledTime - lastStateTimeUnscaled : float.PositiveInfinity;
|
||||
public SweBoundaryStateMessage LastBoundaryState => lastBoundaryState;
|
||||
public bool IsConnectionAlive => HasReceivedAck && LastAckAgeSeconds <= Mathf.Max(0.1f, ackTimeoutSeconds);
|
||||
public bool IsWaitingForAck => connectRequested && !IsConnectionAlive && !HasReceivedAck;
|
||||
|
||||
@@ -46,7 +54,7 @@ namespace FloodSWE.Networking
|
||||
|
||||
private void Update()
|
||||
{
|
||||
PollAcks();
|
||||
PollMessages();
|
||||
TickKeepAlive();
|
||||
}
|
||||
|
||||
@@ -89,7 +97,9 @@ namespace FloodSWE.Networking
|
||||
|
||||
serverEndpoint = null;
|
||||
lastAckTimeUnscaled = -1.0f;
|
||||
lastStateTimeUnscaled = -1.0f;
|
||||
lastAckMessage = "";
|
||||
lastBoundaryState = null;
|
||||
connectRequested = false;
|
||||
}
|
||||
|
||||
@@ -104,21 +114,79 @@ namespace FloodSWE.Networking
|
||||
|
||||
public void SetSourceLevel(int sourceId, float level)
|
||||
{
|
||||
Send(new SweControlCommand
|
||||
{
|
||||
command = "set_source_level",
|
||||
sourceId = sourceId,
|
||||
sourceLevel = level,
|
||||
});
|
||||
SetBoundaryProfile(
|
||||
"source_area",
|
||||
sourceId,
|
||||
true,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
Mathf.Max(0.0f, level));
|
||||
}
|
||||
|
||||
public void SetSinkLevel(int sinkId, float level)
|
||||
{
|
||||
SetBoundaryProfile(
|
||||
"sink",
|
||||
sinkId,
|
||||
true,
|
||||
0.0f,
|
||||
0.0f,
|
||||
0.0f,
|
||||
-Mathf.Max(0.0f, level));
|
||||
}
|
||||
|
||||
public void SetBoundaryProfile(
|
||||
string boundaryKind,
|
||||
int boundaryId,
|
||||
bool enabled,
|
||||
float waterLevelM,
|
||||
float velocityUMps,
|
||||
float velocityVMps,
|
||||
float depthRateMps)
|
||||
{
|
||||
Send(new SweControlCommand
|
||||
{
|
||||
command = "set_sink_level",
|
||||
sinkId = sinkId,
|
||||
sinkLevel = level,
|
||||
command = "set_boundary_profile",
|
||||
boundaryKind = boundaryKind,
|
||||
boundaryId = boundaryId,
|
||||
enabled = enabled ? 1 : 0,
|
||||
waterLevelM = waterLevelM,
|
||||
velocityUMps = velocityUMps,
|
||||
velocityVMps = velocityVMps,
|
||||
depthRateMps = depthRateMps,
|
||||
});
|
||||
}
|
||||
|
||||
public void SetBoundariesBulk(SweBoundaryProfile[] profiles, bool replaceAll = false)
|
||||
{
|
||||
if (profiles == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Send(new SweControlCommand
|
||||
{
|
||||
command = "set_boundaries_bulk",
|
||||
replaceAll = replaceAll,
|
||||
boundaries = profiles,
|
||||
});
|
||||
}
|
||||
|
||||
public void RequestBoundaryConfig()
|
||||
{
|
||||
Send(new SweControlCommand
|
||||
{
|
||||
command = "get_boundary_config",
|
||||
});
|
||||
}
|
||||
|
||||
public void SubscribeBoundaryUpdates(bool subscribe = true)
|
||||
{
|
||||
Send(new SweControlCommand
|
||||
{
|
||||
command = "subscribe_boundary_updates",
|
||||
subscribe = subscribe,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -214,7 +282,7 @@ namespace FloodSWE.Networking
|
||||
socket.Send(payload, payload.Length, serverEndpoint);
|
||||
}
|
||||
|
||||
private void PollAcks()
|
||||
private void PollMessages()
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
@@ -234,17 +302,33 @@ namespace FloodSWE.Networking
|
||||
break;
|
||||
}
|
||||
|
||||
if (!SweUdpProtocol.TryDecodeAck(payload, out string message))
|
||||
if (SweUdpProtocol.TryDecodeAck(payload, out string message))
|
||||
{
|
||||
lastAckTimeUnscaled = Time.unscaledTime;
|
||||
lastAckMessage = message ?? "";
|
||||
|
||||
if (verboseLogging)
|
||||
{
|
||||
Debug.Log($"SweQuestControlClient: ack from {sender}: {lastAckMessage}");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
lastAckTimeUnscaled = Time.unscaledTime;
|
||||
lastAckMessage = message ?? "";
|
||||
|
||||
if (verboseLogging)
|
||||
if (SweUdpProtocol.TryDecodeState(payload, out SweBoundaryStateMessage state))
|
||||
{
|
||||
Debug.Log($"SweQuestControlClient: ack from {sender}: {lastAckMessage}");
|
||||
lastStateTimeUnscaled = Time.unscaledTime;
|
||||
lastBoundaryState = state;
|
||||
BoundaryStateReceived?.Invoke(state);
|
||||
|
||||
if (verboseLogging)
|
||||
{
|
||||
int count = state != null && state.boundaries != null ? state.boundaries.Length : 0;
|
||||
Debug.Log(
|
||||
$"SweQuestControlClient: boundary state from {sender}: type={state?.messageType} entries={count}");
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user