private void showNextStep() { Debug.Assert(currentStepIndex != null); Debug.Assert(stack != null); currentStepIndex++; if (currentStepIndex < steps.Count) { var nextScreen = (Screen)Activator.CreateInstance(steps[currentStepIndex.Value]); loadingShowDelegate = Scheduler.AddDelayed(() => loading.Show(), 200); nextScreen.OnLoadComplete += _ => { loadingShowDelegate?.Cancel(); loading.Hide(); }; stack.Push(nextScreen); } else { showFirstRunSetup.Value = false; currentStepIndex = null; Hide(); } updateButtons(); }
public void TestClickTwiceOnClearButton() { KeyBindingRow firstRow = null; AddStep("click first row", () => { firstRow = panel.ChildrenOfType <KeyBindingRow>().First(); InputManager.MoveMouseTo(firstRow); InputManager.Click(MouseButton.Left); }); AddStep("schedule button clicks", () => { var clearButton = firstRow.ChildrenOfType <KeyBindingRow.ClearButton>().Single(); InputManager.MoveMouseTo(clearButton); int buttonClicks = 0; ScheduledDelegate clickDelegate = null; clickDelegate = Scheduler.AddDelayed(() => { InputManager.PressButton(MouseButton.Left); InputManager.ReleaseButton(MouseButton.Left); if (++buttonClicks == 2) { // ReSharper disable once AccessToModifiedClosure Debug.Assert(clickDelegate != null); // ReSharper disable once AccessToModifiedClosure clickDelegate.Cancel(); } }, 0, true); }); }
public void TestCancelAfterRepeatReschedule() { var clock = new StopwatchClock(); scheduler.UpdateClock(clock); int invocations = 0; ScheduledDelegate del; scheduler.Add(del = new ScheduledDelegate(() => invocations++, 500, 500)); Assert.AreEqual(ScheduledDelegate.RunState.Waiting, del.State); clock.Seek(750); scheduler.Update(); Assert.AreEqual(1, invocations); Assert.AreEqual(ScheduledDelegate.RunState.Complete, del.State); del.Cancel(); Assert.AreEqual(ScheduledDelegate.RunState.Cancelled, del.State); clock.Seek(1250); scheduler.Update(); Assert.AreEqual(1, invocations); Assert.AreEqual(ScheduledDelegate.RunState.Cancelled, del.State); }
public async Task TakeScreenshotAsync() => await Task.Run(async() => { Interlocked.Increment(ref screenShotTasks); if (!captureMenuCursor.Value) { cursorVisibility.Value = false; // We need to wait for at most 3 draw nodes to be drawn, following which we can be assured at least one DrawNode has been generated/drawn with the set value const int frames_to_wait = 3; int framesWaited = 0; ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() => framesWaited++, 0, true); while (framesWaited < frames_to_wait) { Thread.Sleep(10); } waitDelegate.Cancel(); } using (var image = await host.TakeScreenshotAsync()) { Interlocked.Decrement(ref screenShotTasks); var fileName = getFileName(); if (fileName == null) { return; } var stream = storage.GetStream(fileName, FileAccess.Write); switch (screenshotFormat.Value) { case ScreenshotFormat.Png: image.SaveAsPng(stream); break; case ScreenshotFormat.Jpg: image.SaveAsJpeg(stream); break; default: throw new ArgumentOutOfRangeException(nameof(screenshotFormat)); } notificationOverlay.Post(new SimpleNotification { Text = $"{fileName} saved!", Activated = () => { storage.OpenInNativeExplorer(); return(true); } }); } });
public void TestHighFrameRate() { ScheduledDelegate moveFunction = null; AddStep("move to center", () => InputManager.MoveMouseTo(recordingManager.ScreenSpaceDrawQuad.Centre)); AddStep("much move", () => moveFunction = Scheduler.AddDelayed(() => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(-1, 0)), 10, true)); AddWaitStep("move", 10); AddStep("stop move", () => moveFunction.Cancel()); AddAssert("at least 60 frames recorded", () => replay.Frames.Count > 60); }
public void TestAddCancelledDelegate() { int invocations = 0; ScheduledDelegate del = new ScheduledDelegate(() => invocations++); del.Cancel(); scheduler.Add(del); scheduler.Update(); Assert.AreEqual(0, invocations); }
public void TestLimitedFrameRate() { ScheduledDelegate moveFunction = null; int initialFrameCount = 0; AddStep("lower rate", () => recorder.RecordFrameRate = 2); AddStep("count frames", () => initialFrameCount = replay.Frames.Count); AddStep("move to center", () => InputManager.MoveMouseTo(recordingManager.ScreenSpaceDrawQuad.Centre)); AddStep("much move", () => moveFunction = Scheduler.AddDelayed(() => InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(-1, 0)), 10, true)); AddWaitStep("move", 10); AddStep("stop move", () => moveFunction.Cancel()); AddAssert("less than 10 frames recorded", () => replay.Frames.Count - initialFrameCount < 10); }
public override void Reset() { base.Reset(); createArea(scrollDir = Direction.Vertical); AddButton("Vertical", delegate { createArea(scrollDir = Direction.Vertical); }); AddButton("Horizontal", delegate { createArea(scrollDir = Direction.Horizontal); }); AddButton("Both", delegate { createAreaBoth(); }); AddButton("Dragger Anchor 1", delegate { scroll.ScrollDraggerAnchor = scrollDir == Direction.Vertical ? Anchor.TopRight : Anchor.BottomLeft; }); AddButton("Dragger Anchor 2", delegate { scroll.ScrollDraggerAnchor = scrollDir == Direction.Vertical ? Anchor.TopLeft : Anchor.TopLeft; }); AddButton("Dragger Visible", delegate { scroll.ScrollDraggerVisible = !scroll.ScrollDraggerVisible; }); AddButton("Dragger Overlap", delegate { scroll.ScrollDraggerOverlapsContent = !scroll.ScrollDraggerOverlapsContent; }); boxCreator?.Cancel(); boxCreator = Scheduler.AddDelayed(delegate { if (Parent == null) { return; } Box box; Container container = new Container { Size = new Vector2(80, 80), Children = new[] { box = new Box { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, Colour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1) } } }; flow.Add(container); container.FadeInFromZero(1000); container.Delay(RNG.Next(0, 20000), true); container.FadeOutFromOne(4000); box.RotateTo((RNG.NextSingle() - 0.5f) * 90, 4000); box.ScaleTo(0.5f, 4000); container.Expire(); }, 100, true); }
/// <summary> /// selection has been changed as the result of interaction with the carousel. /// </summary> private void carouselSelectionChanged(BeatmapInfo beatmap) { Action performLoad = delegate { bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value.BeatmapInfo.BeatmapSetInfoID; Beatmap.Value = database.GetWorkingBeatmap(beatmap, Beatmap); ensurePlayingSelected(preview); changeBackground(Beatmap.Value); }; if (beatmap == null) { if (!Beatmap.IsDefault) { performLoad(); } } else { selectionChangedDebounce?.Cancel(); if (beatmap.Equals(beatmapNoDebounce)) { return; } if (beatmap.BeatmapSetInfoID == beatmapNoDebounce?.BeatmapSetInfoID) { sampleChangeDifficulty.Play(); } else { sampleChangeBeatmap.Play(); } beatmapNoDebounce = beatmap; if (beatmap == Beatmap.Value.BeatmapInfo) { performLoad(); } else { selectionChangedDebounce = Scheduler.AddDelayed(performLoad, 100); } } }
public TestSceneScrollableFlow() { Direction scrollDir; createArea(scrollDir = Direction.Vertical); AddStep("Vertical", delegate { createArea(scrollDir = Direction.Vertical); }); AddStep("Horizontal", delegate { createArea(scrollDir = Direction.Horizontal); }); AddStep("Both", createAreaBoth); AddStep("Dragger Anchor 1", delegate { scroll.ScrollbarAnchor = scrollDir == Direction.Vertical ? Anchor.TopRight : Anchor.BottomLeft; }); AddStep("Dragger Anchor 2", delegate { scroll.ScrollbarAnchor = Anchor.TopLeft; }); AddStep("Dragger Visible", delegate { scroll.ScrollbarVisible = !scroll.ScrollbarVisible; }); AddStep("Dragger Overlap", delegate { scroll.ScrollbarOverlapsContent = !scroll.ScrollbarOverlapsContent; }); boxCreator?.Cancel(); boxCreator = Scheduler.AddDelayed(delegate { if (Parent == null) { return; } Box box; Container container = new Container { Size = new Vector2(80, 80), Children = new[] { box = new Box { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, Colour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1) } } }; flow.Add(container); container.FadeInFromZero(1000); double displayTime = RNG.Next(0, 20000); box.Delay(displayTime).ScaleTo(0.5f, 4000).RotateTo((RNG.NextSingle() - 0.5f) * 90, 4000); container.Delay(displayTime).FadeOut(4000).Expire(); }, 100, true); }
protected override bool OnHover(HoverEvent e) { playDelegate?.Cancel(); if (HoverDebounceTime <= 0) { sampleHover?.Play(); } else { playDelegate = Scheduler.AddDelayed(() => sampleHover?.Play(), HoverDebounceTime); } return(base.OnHover(e)); }
public void TestLimitedFrameRateWithImportantFrames() { ScheduledDelegate moveFunction = null; AddStep("lower rate", () => recorder.RecordFrameRate = 2); AddStep("move to center", () => InputManager.MoveMouseTo(recordingManager.ScreenSpaceDrawQuad.Centre)); AddStep("much move with press", () => moveFunction = Scheduler.AddDelayed(() => { InputManager.MoveMouseTo(InputManager.CurrentState.Mouse.Position + new Vector2(-1, 0)); InputManager.Click(MouseButton.Left); }, 10, true)); AddWaitStep("move", 10); AddStep("stop move", () => moveFunction.Cancel()); AddAssert("at least 60 frames recorded", () => replay.Frames.Count > 60); }
protected override void CancelTasks() { base.CancelTasks(); if (unloadSchedule != null) { unloadSchedule.Cancel(); unloadSchedule = null; total_loaded.Value--; } scheduledUnloadCheckRegistration?.Cancel(); scheduledUnloadCheckRegistration = null; }
private void expandVolumeBarTemporarily() { // avoid starting a new transform if one is already active. if (expandTransform == null) { expandTransform = volumeDisplay.ResizeWidthTo(6, 500, Easing.OutQuint); expandTransform.Finally(_ => expandTransform = null); } contractTransform?.Cancel(); contractTransform = Scheduler.AddDelayed(() => { volumeDisplay.ResizeWidthTo(3f, 500, Easing.OutQuint); }, 1000); }
public void Filter(FilterCriteria newCriteria = null, bool debounce = true) { if (newCriteria != null) { criteria = newCriteria; } Action perform = delegate { filterTask = null; criteria.Filter(groups); var filtered = new List <BeatmapGroup>(groups); scrollableContent.Clear(false); panels.Clear(); groups.Clear(); foreach (var g in filtered) { addGroup(g); } computeYPositions(); if (selectedGroup == null || selectedGroup.State == BeatmapGroupState.Hidden) { SelectNext(); } else { selectGroup(selectedGroup, selectedPanel); } }; filterTask?.Cancel(); filterTask = null; if (debounce) { filterTask = Scheduler.AddDelayed(perform, 250); } else { perform(); } }
protected void UpdateScores() { // don't display any scores or placeholder until the first Scores_Set has been called. // this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished. if (!scoresLoadedOnce) { return; } getScoresRequest?.Cancel(); getScoresRequest = null; pendingUpdateScores?.Cancel(); pendingUpdateScores = Schedule(() => { if (api?.IsLoggedIn != true) { PlaceholderState = PlaceholderState.NotLoggedIn; return; } PlaceholderState = PlaceholderState.Retrieving; loading.Show(); getScoresRequest = FetchScores(scores => Schedule(() => { Scores = scores; PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; })); if (getScoresRequest == null) { return; } getScoresRequest.Failure += e => Schedule(() => { if (e is OperationCanceledException) { return; } PlaceholderState = PlaceholderState.NetworkFailure; }); api.Queue(getScoresRequest); }); }
private void scheduleGotoRanking() { completionProgressDelegate?.Cancel(); completionProgressDelegate = Schedule(delegate { var score = CreateScore(); if (DrawableRuleset.ReplayScore == null) { scoreManager.Import(score).ContinueWith(_ => Schedule(() => this.Push(CreateResults(score)))); } else { this.Push(CreateResults(score)); } }); }
private void updateProcessingMode() { bool enabled = OverlayActivationMode.Value == OverlayActivation.All || State.Value == Visibility.Visible; notificationsEnabler?.Cancel(); if (enabled) { // we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed. notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, State.Value == Visibility.Visible ? 0 : 1000); } else { processingPosts = false; } }
private void apiStateChanged(ValueChangedEvent <APIState> state) { switch (state.NewValue) { case APIState.Offline: case APIState.Failing: break; case APIState.Connecting: break; case APIState.Online: scheduledHide?.Cancel(); scheduledHide = Schedule(Hide); break; } }
public void RunAllSteps(Action onCompletion = null, Action <Exception> onError = null, Func <StepButton, bool> stopCondition = null, StepButton startFromStep = null) { // schedule once as we want to ensure we have run our LoadComplete before attempting to execute steps. // a user may be adding a step in LoadComplete. Schedule(() => { stepRunner?.Cancel(); foreach (var step in StepsContainer.FlowingChildren.OfType <StepButton>()) { step.Reset(); } actionIndex = startFromStep != null ? StepsContainer.IndexOf(startFromStep) + 1 : -1; actionRepetition = 0; runNextStep(onCompletion, onError, stopCondition); }); }
public void TestCancelDelayedDelegate() { var clock = new StopwatchClock(); scheduler.UpdateClock(clock); int invocations = 0; ScheduledDelegate del; scheduler.Add(del = new ScheduledDelegate(() => invocations++, 1000)); del.Cancel(); clock.Seek(1500); scheduler.Update(); Assert.AreEqual(0, invocations); }
private void initializeChannels() { if (api.State != APIAccess.APIState.Online) { return; } messageRequest?.Cancel(); ListChannelsRequest req = new ListChannelsRequest(); req.Success += delegate(List <Channel> channels) { this.channels = channels; messageRequest = scheduler.AddDelayed(requestNewMessages, 1000, true); }; api.Queue(req); }
/// <summary> /// Stops playing this <see cref="PreviewTrack"/>. /// </summary> public void Stop() { startDelegate?.Cancel(); if (track == null) { return; } if (!hasStarted) { return; } hasStarted = false; track.Stop(); Stopped?.Invoke(); }
public void TestRapidSwitching() { ScheduledDelegate switchStep = null; int switchCount = 0; AddStep("install quick switch step", () => { switchStep = Scheduler.AddDelayed(() => { executionMode.Value = executionMode.Value == ExecutionMode.MultiThreaded ? ExecutionMode.SingleThread : ExecutionMode.MultiThreaded; switchCount++; }, 0, true); }); AddUntilStep("switch count sufficiently high", () => switchCount > 1000); AddStep("remove", () => switchStep.Cancel()); }
private void initializeChannels() { careChannels = new List <Channel>(); if (api.State != APIState.Online) { return; } Add(flow = new FlowContainer { RelativeSizeAxes = Axes.Both, Direction = FlowDirection.VerticalOnly }); SpriteText loading; Add(loading = new SpriteText { Text = @"Loading available channels...", Anchor = Anchor.Centre, Origin = Anchor.Centre, TextSize = 40, }); messageRequest?.Cancel(); ListChannelsRequest req = new ListChannelsRequest(); req.Success += delegate(List <Channel> channels) { Scheduler.Add(delegate { loading.FadeOut(100); }); addChannel(channels.Find(c => c.Name == @"#osu")); addChannel(channels.Find(c => c.Name == @"#lobby")); addChannel(channels.Find(c => c.Name == @"#english")); messageRequest = scheduler.AddDelayed(() => FetchNewMessages(api), 1000, true); }; api.Queue(req); }
private void updateDisplay(BeatmapMeta beatmap, TransformDirection direction) { pendingBeatmapSwitch?.Cancel(); pendingBeatmapSwitch = Schedule(delegate { if (beatmap == null) { title.Text = @"Nothing to play!"; artist.Text = @"Nothing to play!"; } else { SongMetadata metadata = beatmap.Metadata.Song; title.Text = new LocalisedString((metadata.NameUnicode, metadata.Name)); artist.Text = new LocalisedString((metadata.AuthorUnicode, metadata.Author)); } LoadComponentAsync(new Background(beatmap) { Depth = float.MaxValue }, newBackground => { switch (direction) { case TransformDirection.Next: newBackground.Position = new Vector2(400, 0); newBackground.MoveToX(0, 500, Easing.OutCubic); background.MoveToX(-400, 500, Easing.OutCubic); break; case TransformDirection.Prev: newBackground.Position = new Vector2(-400, 0); newBackground.MoveToX(0, 500, Easing.OutCubic); background.MoveToX(400, 500, Easing.OutCubic); break; } background.Expire(); background = newBackground; playerContainer.Add(newBackground); }); });
/// <summary> /// Request loading the next background. /// </summary> /// <returns>Whether a new background was queued for load. May return false if the current background is still valid.</returns> public virtual bool Next() { var nextBackground = createBackground(); // in the case that the background hasn't changed, we want to avoid cancelling any tasks that could still be loading. if (nextBackground == background) return false; cancellationTokenSource?.Cancel(); cancellationTokenSource = new CancellationTokenSource(); nextTask?.Cancel(); nextTask = Scheduler.AddDelayed(() => { LoadComponentAsync(nextBackground, displayNext, cancellationTokenSource.Token); }, 100); return true; }
internal override void Reset() { base.Reset(); FlowContainer flow = new FlowContainer() { LayoutDuration = 100, LayoutEasing = EasingTypes.Out, Padding = new Vector2(1, 1), SizeMode = InheritMode.X }; boxCreator?.Cancel(); boxCreator = scheduler.AddDelayed(delegate { if (Parent == null) { return; } Box box = new Box() { Size = new Vector2(80, 80), Colour = new Color4(RNG.NextSingle(), RNG.NextSingle(), RNG.NextSingle(), 1) }; flow.Add(box); box.FadeInFromZero(1000); box.Delay(RNG.Next(0, 20000)); box.FadeOutFromOne(4000); box.Expire(); }, 100, true); scheduler.Add(boxCreator); ScrollContainer scrolling = new ScrollContainer(); scrolling.Add(flow); Add(scrolling); }
protected override void LoadComplete() { base.LoadComplete(); currentRuleset.BindValueChanged(_ => updateTrackedBindables()); currentMods.BindValueChanged(mods => { modSettingChangeTracker?.Dispose(); updateTrackedBindables(); modSettingChangeTracker = new ModSettingChangeTracker(mods.NewValue); modSettingChangeTracker.SettingChanged += _ => { debouncedModSettingsChange?.Cancel(); debouncedModSettingsChange = Scheduler.AddDelayed(updateTrackedBindables, 100); }; }, true); }
/// <summary> /// Assign this drawable to a consumer. /// </summary> /// <exception cref="InvalidOperationException">Thrown if this drawable is still in use.</exception> internal void Assign() { if (IsInUse) { throw new InvalidOperationException($"This {nameof(PoolableDrawable)} is already in use"); } IsInUse = true; waitingForPrepare = true; // prepare call is scheduled as it may contain user code dependent on the clock being updated. // must use Scheduler.Add, not Schedule as we may have the wrong clock at this point in load. scheduledPrepare?.Cancel(); scheduledPrepare = Scheduler.Add(() => { PrepareForUse(); waitingForPrepare = false; }); }