//navigation

        //navigate to new browse path
        private void Navigate(IReadOnlyList <string> newBrowsePath)
        {
            //throw if task running, or errored
            if (CurrentTask != null && !CurrentTask.IsCompleted)
            {
                throw new InvalidOperationException();
            }

            if (FatalErrorEncountered)
            {
                throw new InvalidOperationException();
            }

            //clear data and add previous browse path as row
            DisableUI();
            XSMPState.BrowseData?.Clear();

            //if they're the same, it's a refresh and/or doesn't matter
            if (XSMPState.CurrentBrowsePath != null && !newBrowsePath.SequenceEqual(XSMPState.CurrentBrowsePath))
            {
                XSMPState.LastBrowsePath = XSMPState.CurrentBrowsePath;
            }

            //set browse path
            XSMPState.CurrentBrowsePath = new List <string>(newBrowsePath);

            //async magic
            CurrentTokenSource = new CancellationTokenSource();
            CurrentTask        = NavigateAsync(CurrentTokenSource.Token);
            AsyncUtils.RunWithExceptionHandling(async() => await CurrentTask);  //TODO replace this with custom exception handling instead of bodging it into NavigateAsync
        }
        public void HandleRefreshLibraryButtonClicked()
        {
            //throw if task running, or errored
            if (CurrentTask != null && !CurrentTask.IsCompleted)
            {
                throw new InvalidOperationException();
            }

            if (FatalErrorEncountered)
            {
                throw new InvalidOperationException();
            }

            DisableUI();

            //clear data and browse path
            XSMPState.BrowseData?.Clear();
            XSMPState.CurrentBrowsePath = new List <string>();

            //TODO also clear playlist?

            CurrentTokenSource = new CancellationTokenSource();
            CurrentTask        = refreshLibraryAsync(CurrentTokenSource.Token);
            AsyncUtils.RunWithExceptionHandling(async() => await CurrentTask);

            async Task refreshLibraryAsync(CancellationToken token)
            {
                try
                {
                    await Task.Run(() => XSMPModule.Instance.RefreshLibrary(token));
                }
                catch (Exception e)
                {
                    AsyncUtils.ThrowIfEditorStopped();

                    if (e is TaskCanceledException || e is OperationCanceledException)
                    {
                        Debug.Log("[XSMP] Async operation cancelled");
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    EnableUI();
                    SignalPaint();
                }
            }
        }
예제 #3
0
        public override void OnFrameUpdate()
        {
            if (!Enabled)
            {
                return;
            }

            //use this to update status periodically
            if (Time.unscaledTime > LastStatusUpdateTime + Config.StatusUpdateInterval)
            {
                AsyncUtils.RunWithExceptionHandling(async() => await Task.Run(UpdateStatus));
                LastStatusUpdateTime = Time.unscaledTime;
            }
        }
예제 #4
0
    public static void TestWeakReferencePauseLock()
    {
        AsyncUtils.RunWithExceptionHandling(async() =>
        {
            object lockObject = new object();
            WeakReference untypedWeakReference = new WeakReference(lockObject);
            LockPauseModule.PauseGame(PauseLockType.AllowMenu, untypedWeakReference);
            Debug.Log("Untyped lock added!");

            await Task.Delay(3000);
            AsyncUtils.ThrowIfEditorStopped();

            lockObject = null;
            CoreUtils.CollectGarbage(false);

            Debug.Log("Untyped lock released!");

            await Task.Yield();
            AsyncUtils.ThrowIfEditorStopped();

            LockPauseModule.ForceCleanLocks();

            Debug.Log("Locks cleaned!");

            await Task.Delay(5000);
            AsyncUtils.ThrowIfEditorStopped();

            IEnumerable typedLockObject = new string[] { "lol", "hi" };
            WeakReference <IEnumerable> typedWeakReference = new WeakReference <IEnumerable>(typedLockObject);

            LockPauseModule.PauseGame(PauseLockType.AllowMenu, typedWeakReference);
            Debug.Log("Typed lock added!");

            await Task.Delay(3000);
            AsyncUtils.ThrowIfEditorStopped();

            typedLockObject = null;
            CoreUtils.CollectGarbage(false);

            Debug.Log("Typed lock released!");

            await Task.Yield();
            AsyncUtils.ThrowIfEditorStopped();

            LockPauseModule.ForceCleanLocks();

            Debug.Log("Locks cleaned!");
        });
    }
예제 #5
0
        public static void TestScreenFader()
        {
            AsyncUtils.RunWithExceptionHandling(async() =>
            {
                ScreenFader.FadeTo(Color.white, 5.0f, true, true, true);

                await Task.Delay(6000);
                AsyncUtils.ThrowIfEditorStopped();

                SharedUtils.ChangeScene("TestScene");

                await Task.Delay(5000);
                AsyncUtils.ThrowIfEditorStopped();

                ScreenFader.FadeFrom(null, 1.0f, false, true, true);

                await Task.Delay(5000);
                AsyncUtils.ThrowIfEditorStopped();

                ScreenFader.Crossfade(Color.blue, Color.red, 5.0f, false, false, false);

                await Task.Delay(3000);
                AsyncUtils.ThrowIfEditorStopped();

                ScreenFader.ClearFade();

                await Task.Delay(5000);
                AsyncUtils.ThrowIfEditorStopped();

                ScreenFader.Crossfade(Color.blue, Color.red, 5.0f, false, false, false);

                await Task.Delay(1000);
                AsyncUtils.ThrowIfEditorStopped();

                SharedUtils.ChangeScene("TestScene");

                await Task.Delay(5000);
                AsyncUtils.ThrowIfEditorStopped();

                ScreenFader.FadeTo(Color.black, 1.0f, true, false, true);

                await Task.Delay(1500);
                AsyncUtils.ThrowIfEditorStopped();

                SharedUtils.EndGame();
            });
        }
예제 #6
0
        public async void HandleClickButtonTestDelayTask()
        {
            AsyncUtils.RunWithExceptionHandling(async() =>
            {
                TestText.text = "Before delays";

                await SkippableWait.DelayScaled(5f);

                TestText.text = "Done gametime delay";

                await SkippableWait.DelayRealtime(5f);

                TestText.text = "Done realtime delay";

                await Task.Delay(5000);

                TestText.text = "Done task.delay";
            });
        }
예제 #7
0
 public XSMPServerWrapper()
 {
     CurrentTokenSource = new CancellationTokenSource();
     CurrentTask        = Task.Run(() => StartServer(CurrentTokenSource.Token));
     AsyncUtils.RunWithExceptionHandling(async() => await CurrentTask);
 }