private bool TryCleanupExistingLocalizationSession(SpatialCoordinateSystemParticipant participant)
        {
            bool succeeded = true;
            LocalizationSessionDetails sessionToCancel = null;

            lock (localizationLock)
            {
                if (currentLocalizationSession != null)
                {
                    if (currentLocalizationSession.Participant == participant)
                    {
                        sessionToCancel            = currentLocalizationSession;
                        currentLocalizationSession = null;
                    }
                    else
                    {
                        succeeded = false;
                    }
                }
            }

            if (sessionToCancel != null)
            {
                DebugLog($"Cancelling spatial localization session for participant: {participant?.SocketEndpoint?.Address ?? "Unknown"}");
                sessionToCancel.Session.Cancel();
                sessionToCancel.Session.Dispose();
                sessionToCancel.CompletionSource.TrySetResult(false);
            }

            return(succeeded);
        }
Пример #2
0
        private bool TryCleanupExistingLocalizationSession(SpatialCoordinateSystemParticipant participant)
        {
            bool succeeded = true;
            LocalizationSessionDetails sessionToCancel = null;

            lock (localizationLock)
            {
                if (currentLocalizationSession != null)
                {
                    // When connecting to the StationaryCameraBroadcaster within the editor and performing spatial coordinate sharing through it,
                    // both sessions are running within the editor. Completing one part of the session will leave a completed task assigned to
                    // the remote participant within the same session. That session should be cleaned up here to allow the local session
                    // to start.
                    if (currentLocalizationSession.Participant == participant || currentLocalizationSession.CompletionSource.Task.IsCompleted)
                    {
                        sessionToCancel            = currentLocalizationSession;
                        currentLocalizationSession = null;
                    }
                    else
                    {
                        succeeded = false;
                    }
                }
            }

            if (sessionToCancel != null)
            {
                DebugLog($"Cancelling spatial localization session for participant: {participant?.NetworkConnection?.ToString() ?? "Unknown"}");
                sessionToCancel.Session.Cancel();
                sessionToCancel.Session.Dispose();
                sessionToCancel.CompletionSource.TrySetResult(false);
            }

            return(succeeded);
        }
        private async Task <bool> RunLocalizationSessionAsync(ISpatialLocalizer localizer, ISpatialLocalizationSettings settings, SpatialCoordinateSystemParticipant participant)
        {
            if (!TryCleanupExistingLocalizationSession(participant))
            {
                DebugLog("Existing localization session with different participant prevented creating new localization session");
                return(false);
            }

            if (!localizer.TryCreateLocalizationSession(participant, settings, out var localizationSession))
            {
                Debug.LogError($"Failed to create an ISpatialLocalizationSession from localizer {localizer.SpatialLocalizerId}");
                return(false);
            }

            Task <bool> resultTask;
            bool        startSession = false;
            var         localizationSessionDetails = new LocalizationSessionDetails(localizationSession, participant);

            lock (localizationLock)
            {
                if (currentLocalizationSession != null)
                {
                    DebugLog($"Current localization session repopulated after cleanup, localization not performed.");
                    localizationSessionDetails.Session.Dispose();
                    resultTask = Task.FromResult(false);
                }
                else
                {
                    currentLocalizationSession = localizationSessionDetails;
                    localizationSessionDetails.Participant.CurrentLocalizationSession = localizationSessionDetails.Session;
                    resultTask   = localizationSessionDetails.CompletionSource.Task;
                    startSession = true;
                }
            }

            if (startSession)
            {
                await Dispatcher.ScheduleAsync(async() =>
                {
                    try
                    {
                        // Some SpatialLocalizers/SpatialCoordinateServices key off of token cancellation for their logic flow.
                        // Therefore, we need to create a cancellation token even it is never actually cancelled by the SpatialCoordinateSystemManager.
                        using (var localizeCTS = new CancellationTokenSource())
                        {
                            var coordinate = await localizationSessionDetails.Session.LocalizeAsync(localizeCTS.Token);
                            bool succeeded = (coordinate != null);
                            localizationSessionDetails.Session.Dispose();
                            localizationSessionDetails.CompletionSource.TrySetResult(succeeded);

                            if (localizationSessionDetails.Participant.CurrentLocalizationSession == localizationSessionDetails.Session)
                            {
                                localizationSessionDetails.Participant.Coordinate = coordinate;
                                localizationSessionDetails.Participant.CurrentLocalizationSession = null;
                            }
                            else
                            {
                                Debug.LogWarning("Localization session completed but was no longer assigned to the associated participant");
                            }
                        }
                    }
                    catch (OperationCanceledException)
                    {
                        DebugLog("Localization operation cancelled.");
                    }
                    catch (Exception e)
                    {
                        Debug.LogError($"Exception thrown localizing experience: {e.ToString()}");
                    }
                }, CancellationToken.None, true);
            }

            return(await resultTask);
        }