Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

Enable cancelling localization sessions #247

Merged
merged 14 commits into from
Oct 22, 2019
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace Microsoft.MixedReality.SpatialAlignment
internal class SpatialAnchorsAndroidCoordinateService : SpatialAnchorsCoordinateService
{
private long lastFrameProcessedTimeStamp;
private static bool initialized = false;

/// <summary>
/// Instantiates a new <see cref="SpatialAnchorsAndroidCoordinateService"/>.
Expand All @@ -30,16 +31,31 @@ public SpatialAnchorsAndroidCoordinateService(SpatialAnchorsConfiguration spatia
/// <inheritdoc/>
protected override Task OnInitializeAsync()
{
if (initialized)
chrisfromwork marked this conversation as resolved.
Show resolved Hide resolved
{
Debug.Log("SpatialAnchorsAndroidCoordinateService: session already initialized");
return Task.CompletedTask;
}

TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>();

UnityAndroidHelper.Instance.DispatchUiThread(unityActivity =>
{
if (initialized)
{
Debug.Log("SpatialAnchorsAndroidCoordinateService: session already initialized");
taskCompletionSource.SetResult(null);
return;
}

try
{
// We should only run the java initialization once
using (AndroidJavaClass cloudServices = new AndroidJavaClass("com.microsoft.CloudServices"))
{
cloudServices.CallStatic("initialize", unityActivity);
Debug.Log("SpatialAnchorsAndroidCoordinateService: session successfully initialized");
initialized = true;
taskCompletionSource.SetResult(null);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,11 @@ private async Task<ISpatialCoordinate> TryCreateCoordinateImplAsync(Vector3 worl
await session.CreateAnchorAsync(cloudSpatialAnchor);
return new SpatialAnchorsCoordinate(cloudSpatialAnchor, spawnedAnchorObject);
}
catch(TaskCanceledException)
chrisfromwork marked this conversation as resolved.
Show resolved Hide resolved
{
Debug.Log("Create coordinate was cancelled.");
UnityEngine.Object.Destroy(spawnedAnchorObject);
}
catch
{
UnityEngine.Object.Destroy(spawnedAnchorObject);
Expand All @@ -334,6 +339,8 @@ private async Task<ISpatialCoordinate> TryCreateCoordinateImplAsync(Vector3 worl
{
ReleaseSessionStartRequest();
}

return null;
chrisfromwork marked this conversation as resolved.
Show resolved Hide resolved
}

private async Task<ISpatialCoordinate> TryCreateCoordinateEditorAsync(Vector3 worldPosition, Quaternion worldRotation, CancellationToken cancellationToken)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,17 @@ private void Update()
Updated?.Invoke();
}

private class SpatialCoordinateLocalizationSession : DisposableBase, ISpatialLocalizationSession
private class SpatialCoordinateLocalizationSession : SpatialLocalizationSession
{
public IPeerConnection Peer => peerConnection;
public override IPeerConnection Peer => peerConnection;
chrisfromwork marked this conversation as resolved.
Show resolved Hide resolved

private readonly IPeerConnection peerConnection;
private readonly SpatialAnchorsCoordinateService coordinateService;
private readonly SpatialAnchorsConfiguration configuration;
private readonly SpatialAnchorsLocalizer localizer;
private readonly TaskCompletionSource<string> coordinateIdentifierTaskSource;

public SpatialCoordinateLocalizationSession(SpatialAnchorsLocalizer localizer, SpatialAnchorsCoordinateService coordinateService, SpatialAnchorsConfiguration configuration, IPeerConnection peerConnection)
public SpatialCoordinateLocalizationSession(SpatialAnchorsLocalizer localizer, SpatialAnchorsCoordinateService coordinateService, SpatialAnchorsConfiguration configuration, IPeerConnection peerConnection) : base()
{
this.localizer = localizer;
this.coordinateService = coordinateService;
Expand All @@ -116,38 +116,47 @@ private void OnUpdated()
coordinateService.FrameUpdate();
}

public async Task<ISpatialCoordinate> LocalizeAsync(CancellationToken cancellationToken)
public override async Task<ISpatialCoordinate> LocalizeAsync(CancellationToken cancellationToken)
{
ISpatialCoordinate coordinateToReturn = null;
if (configuration.IsCoordinateCreator)
using (var cancellableCTS = CancellationTokenSource.CreateLinkedTokenSource(defaultCTS.Token, cancellationToken))
{
localizer.DebugLog("User getting initialized coordinate");
coordinateToReturn = await coordinateService.TryCreateCoordinateAsync(localizer.anchorPosition, Quaternion.Euler(localizer.anchorRotation), cancellationToken);

localizer.DebugLog($"Sending coordinate id: {coordinateToReturn.Id}");
peerConnection.SendData(writer => writer.Write(coordinateToReturn.Id));

localizer.DebugLog("Message sent.");
}
else
{
localizer.DebugLog("Non-host waiting for coord id to be sent over");
string coordinateIdentifier = await coordinateIdentifierTaskSource.Task.Unless(cancellationToken);

if (!cancellationToken.IsCancellationRequested)
if (configuration.IsCoordinateCreator)
{
localizer.DebugLog($"Coordinate id: {coordinateIdentifier}, starting discovery.");
if (await coordinateService.TryDiscoverCoordinatesAsync(cancellationToken, coordinateIdentifier))
{
localizer.DebugLog("Discovery complete, retrieving reference to ISpatialCoordinate");
if (!coordinateService.TryGetKnownCoordinate(coordinateIdentifier, out coordinateToReturn))
{
Debug.LogError("We discovered, but for some reason failed to get coordinate from service.");
}
localizer.DebugLog("User getting initialized coordinate");
coordinateToReturn = await coordinateService.TryCreateCoordinateAsync(localizer.anchorPosition, Quaternion.Euler(localizer.anchorRotation), cancellableCTS.Token);
if (coordinateToReturn != null)
{
localizer.DebugLog($"Sending coordinate id: {coordinateToReturn.Id}");
peerConnection.SendData(writer => writer.Write(coordinateToReturn.Id));
localizer.DebugLog("Message sent.");
}
else
{
Debug.LogError("Failed to discover spatial coordinate.");
Debug.LogError("Coordinate discovery returned null coordinate");
return null;
}
}
else
{
localizer.DebugLog("Non-host waiting for coord id to be sent over");
string coordinateIdentifier = await coordinateIdentifierTaskSource.Task.Unless(cancellableCTS.Token);

if (!cancellableCTS.Token.IsCancellationRequested)
{
localizer.DebugLog($"Coordinate id: {coordinateIdentifier}, starting discovery.");
if (await coordinateService.TryDiscoverCoordinatesAsync(cancellableCTS.Token, coordinateIdentifier))
{
localizer.DebugLog("Discovery complete, retrieving reference to ISpatialCoordinate");
if (!coordinateService.TryGetKnownCoordinate(coordinateIdentifier, out coordinateToReturn))
{
Debug.LogError("We discovered, but for some reason failed to get coordinate from service.");
}
}
else
{
Debug.LogError("Failed to discover spatial coordinate.");
}
}
}
}
Expand All @@ -163,9 +172,9 @@ protected override void OnManagedDispose()
localizer.Updated -= OnUpdated;
}

public void OnDataReceived(BinaryReader reader)
public override void OnDataReceived(BinaryReader reader)
{
coordinateIdentifierTaskSource.SetResult(reader.ReadString());
coordinateIdentifierTaskSource.TrySetResult(reader.ReadString());
}
}
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1969,7 +1969,7 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 0, a: 1}
m_Color: {r: 1, g: 0, b: 0, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,24 @@ protected void DoStopListening(ref SocketerClient listener)
/// <param name="port">port to use for communication</param>
public void ConnectTo(string serverAddress, int port)
{
if (client != null)
{
if (client.Host == serverAddress &&
client.Port == port)
{
Debug.Log($"Client already created: {client.Host}:{client.Port}");
return;
}
else
{
Debug.Log($"Disconnecting existing client {client.Host}:{client.Port}");
client.Stop();
client.Connected -= OnClientConnected;
client.Disconnected -= OnClientDisconnected;
client = null;
}
}

Debug.LogFormat($"Connecting to {serverAddress}:{port}");
client = SocketerClient.CreateSender(SocketerClient.Protocol.TCP, serverAddress, port);
client.Connected += OnClientConnected;
Expand Down Expand Up @@ -152,6 +170,20 @@ private void OnClientDisconnected(SocketerClient client, int sourceId, string ho
oldConnections.Enqueue(clientConnection);
clientConnection = null;
}

if (!AttemptReconnectWhenClient)
{
Debug.Log("Stopping subscriptions to disconnected client");
client.Stop();
client.Connected -= OnClientConnected;
client.Disconnected -= OnClientDisconnected;

if (this.client == client)
{
Debug.Log("Clearing client cache");
this.client = null;
}
}
}

private void Update()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public interface ISpatialLocalizationSession : IDisposable
/// <returns></returns>
Task<ISpatialCoordinate> LocalizeAsync(CancellationToken cancellationToken);

/// <summary>
/// Call to cancel the localization sessions
/// </summary>
void Cancel();

/// <summary>
/// Call to provide network information
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ public override bool TryDeserializeSettings(BinaryReader reader, out MarkerVisua
return true;
}

private class LocalizationSession : DisposableBase, ISpatialLocalizationSession
private class LocalizationSession : SpatialLocalizationSession
{
public IPeerConnection Peer => peerConnection;
/// <inheritdoc />
public override IPeerConnection Peer => peerConnection;

private readonly MarkerVisualDetectorSpatialLocalizer localizer;
private readonly MarkerVisualDetectorLocalizationSettings settings;
Expand All @@ -54,7 +55,7 @@ private class LocalizationSession : DisposableBase, ISpatialLocalizationSession

private string coordinateId = string.Empty;

public LocalizationSession(MarkerVisualDetectorSpatialLocalizer localizer, MarkerVisualDetectorLocalizationSettings settings, IPeerConnection peerConnection, bool debugLogging = false)
public LocalizationSession(MarkerVisualDetectorSpatialLocalizer localizer, MarkerVisualDetectorLocalizationSettings settings, IPeerConnection peerConnection, bool debugLogging = false) : base()
{
DebugLog("Session created");
this.localizer = localizer;
Expand All @@ -70,49 +71,59 @@ public LocalizationSession(MarkerVisualDetectorSpatialLocalizer localizer, Marke
/// <inheritdoc />
protected override void OnManagedDispose()
{
coordinateService.Dispose();
base.OnManagedDispose();
discoveryCTS.Dispose();
coordinateService.Dispose();
}

/// <inheritdoc />
public async Task<ISpatialCoordinate> LocalizeAsync(CancellationToken cancellationToken)
public override async Task<ISpatialCoordinate> LocalizeAsync(CancellationToken cancellationToken)
{
DebugLog($"Waiting for marker visual, CanBeCanceled:{cancellationToken.CanBeCanceled}, IsCancellationRequested:{cancellationToken.IsCancellationRequested}");
await Task.WhenAny(coordinateAssigned.Task, Task.Delay(-1, cancellationToken));
if (string.IsNullOrEmpty(coordinateId))
if (!defaultCTS.Token.CanBeCanceled)
chrisfromwork marked this conversation as resolved.
Show resolved Hide resolved
{
DebugLog("Failed to assign coordinate id");
Debug.LogError("Session is invalid. No localization performed.");
return null;
}

ISpatialCoordinate coordinate = null;
using (var cts = CancellationTokenSource.CreateLinkedTokenSource(discoveryCTS.Token, cancellationToken))
DebugLog($"Waiting for marker visual, CanBeCanceled:{cancellationToken.CanBeCanceled}, IsCancellationRequested:{cancellationToken.IsCancellationRequested}");
using (var cancellableCTS = CancellationTokenSource.CreateLinkedTokenSource(defaultCTS.Token, cancellationToken))
{
DebugLog($"Attempting to discover coordinate: {coordinateId}, CanBeCanceled:{cts.Token.CanBeCanceled}, IsCancellationRequested:{cts.Token.IsCancellationRequested}");
if (await coordinateService.TryDiscoverCoordinatesAsync(cts.Token, new string[] { coordinateId.ToString() }))
await Task.WhenAny(coordinateAssigned.Task, Task.Delay(-1, cancellableCTS.Token));
if (string.IsNullOrEmpty(coordinateId))
{
DebugLog($"Coordinate discovery completed: {coordinateId}");
if (!coordinateService.TryGetKnownCoordinate(coordinateId, out coordinate))
DebugLog("Failed to assign coordinate id");
return null;
}

ISpatialCoordinate coordinate = null;
using (var cts = CancellationTokenSource.CreateLinkedTokenSource(discoveryCTS.Token, cancellableCTS.Token))
{
DebugLog($"Attempting to discover coordinate: {coordinateId}, CanBeCanceled:{cts.Token.CanBeCanceled}, IsCancellationRequested:{cts.Token.IsCancellationRequested}");
if (await coordinateService.TryDiscoverCoordinatesAsync(cts.Token, new string[] { coordinateId.ToString() }))
{
DebugLog("Failed to find spatial coordinate although discovery completed.");
DebugLog($"Coordinate discovery completed: {coordinateId}");
if (!coordinateService.TryGetKnownCoordinate(coordinateId, out coordinate))
{
DebugLog("Failed to find spatial coordinate although discovery completed.");
}
else
{
SendCoordinateFound(coordinate.Id);
return coordinate;
}
}
else
{
SendCoordinateFound(coordinate.Id);
return coordinate;
DebugLog("TryDiscoverCoordinatesAsync failed.");
}
}
else
{
DebugLog("TryDiscoverCoordinatesAsync failed.");
}
}

return null;
}

/// <inheritdoc />
public void OnDataReceived(BinaryReader reader)
public override void OnDataReceived(BinaryReader reader)
{
string command = reader.ReadString();
DebugLog($"Received command: {command}");
Expand Down