/// <summary> /// Repositions the lines, usually used when the user changes zoom/audio rate. /// </summary> public void RepositionLines() => ThreadScheduler.Run(() => { foreach (var item in CachedLines) { item.Value.ForEach(x => x.Y = Container.HitPositionY - x.Time * Container.TrackSpeed - x.Height); } });
public async Task ReadAsyncCallbackRunsOnReaderScheduler() { using (var pool = new TestMemoryPool()) { using (var scheduler = new ThreadScheduler()) { var pipe = new Pipe(new PipeOptions(pool, scheduler)); Func <Task> doRead = async() => { int oid = Thread.CurrentThread.ManagedThreadId; ReadResult result = await pipe.Reader.ReadAsync(); Assert.NotEqual(oid, Thread.CurrentThread.ManagedThreadId); Assert.Equal(Thread.CurrentThread.ManagedThreadId, scheduler.Thread.ManagedThreadId); pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End); pipe.Reader.Complete(); }; Task reading = doRead(); PipeWriter buffer = pipe.Writer; buffer.Write(Encoding.UTF8.GetBytes("Hello World")); await buffer.FlushAsync(); await reading; } } }
/// <summary> /// Cancels any existing token for loading scores and loads new scores for the current /// map. /// </summary> public void LoadNewScores() { Source?.Cancel(); Source?.Dispose(); Source = new CancellationTokenSource(); ThreadScheduler.Run(() => InitiateScoreLoad(Source.Token)); }
public async Task ReadAsyncCallbackRunsOnReaderScheduler() { using (var pool = new TestMemoryPool()) { using (var scheduler = new ThreadScheduler()) { var pipe = new Pipe(new PipeOptions(pool, scheduler, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false)); Func <Task> doRead = async() => { Assert.False(Thread.CurrentThread.IsThreadPoolThread, "We started on the thread pool"); ReadResult result = await pipe.Reader.ReadAsync(); Assert.Equal(Thread.CurrentThread.ManagedThreadId, scheduler.Thread.ManagedThreadId); pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End); pipe.Reader.Complete(); }; Task reading = ExecuteOnNonThreadPoolThread(doRead); PipeWriter buffer = pipe.Writer; buffer.Write(Encoding.UTF8.GetBytes("Hello World")); await buffer.FlushAsync(); await reading; } } }
void OnDisable() { if (instance == this) { instance = null; } }
/// <summary> /// Goes through the score submission process. /// saves score to local database. /// </summary> private void SubmitScore() { // Don't save scores if the user quit themself. if (Gameplay.HasQuit || Gameplay.InReplayMode) { return; } // Don't submit scores at all if the user has ALL misses for their judgements. // They basically haven't actually played the map. if (ScoreProcessor.CurrentJudgements[Judgement.Miss] == ScoreProcessor.TotalJudgementCount) { return; } ThreadScheduler.Run(SaveLocalScore); // Don't submit scores if disconnected from the server completely. if (OnlineManager.Status.Value == ConnectionStatus.Disconnected) { return; } ThreadScheduler.Run(() => { Logger.Important($"Beginning to submit score on map: {Gameplay.MapHash}", LogType.Network); OnlineManager.Client?.Submit(new OnlineScore(Gameplay.MapHash, Gameplay.ReplayCapturer.Replay, ScoreProcessor, ScrollSpeed, ModHelper.GetRateFromMods(ModManager.Mods), TimeHelper.GetUnixTimestampMilliseconds(), SteamManager.PTicket)); }); }
/// <summary> /// Closes the dialog. /// </summary> public void Close() { if (IsClosing) { return; } IsClosing = true; Animations.Clear(); Animations.Add(new Animation(AnimationProperty.Alpha, Easing.Linear, Alpha, 0f, 200)); ThreadScheduler.RunAfter(() => { lock (DialogManager.Dialogs) DialogManager.Dismiss(this); ButtonManager.Remove(this); IsClosing = false; var game = GameBase.Game as QuaverGame; var screen = game?.CurrentScreen as EditorScreen; var view = screen?.View as EditorScreenView; view.ControlBar.Parent = view.Container; }, 450); }
/// <summary> /// </summary> public void CreateGame() { if (MapManager.Selected.Value == null) { NotificationManager.Show(NotificationLevel.Error, "You cannot create a game without having a map selected!"); return; } if (string.IsNullOrEmpty(GameName.Textbox.RawText) || string.IsNullOrWhiteSpace(GameName.Textbox.RawText)) { NotificationManager.Show(NotificationLevel.Error, "You must provide a valid game name."); return; } DialogManager.Show(new JoiningGameDialog(JoiningGameDialogType.Creating)); ThreadScheduler.Run(() => { var game = MultiplayerGame.CreateCustom(MultiplayerGameType.Friendly, GameName.Textbox.RawText, Password.Textbox.RawText, int.Parse(MaxPlayers.Selector.SelectedItemText.Text), MapManager.Selected.Value.ToString(), MapManager.Selected.Value.MapId, MapManager.Selected.Value.MapSetId, Enum.Parse <MultiplayerGameRuleset>(Ruleset.Selector.SelectedItemText.Text.Replace("-", "_")), AutoHostRotation.Selector.SelectedItemText.Text == "Yes", (byte)MapManager.Selected.Value.Mode, MapManager.Selected.Value.DifficultyFromMods(ModManager.Mods), MapManager.Selected.Value.Md5Checksum, MapManager.Selected.Value.GetDifficultyRatings(), MapManager.Selected.Value.GetJudgementCount(), MapManager.Selected.Value.GetAlternativeMd5()); OnlineManager.Client.CreateMultiplayerGame(game); }); Dialog.Close(); }
public void unstarted_threads_should_be_empty() { using (var scheduler = new ThreadScheduler(5)) { scheduler.Threads.ShouldHaveCount(0); } }
/// <summary> /// Toggles the chat overlay on/off. /// </summary> public static void ToggleChatOverlay(bool forceOpen = false) { if (Dialog.JoinChannelDialog != null && Dialog.JoinChannelDialog.IsOnTop) { return; } if (OnlineManager.Connected && (KeyboardManager.IsUniqueKeyPress(Keys.F8) || forceOpen || KeyboardManager.IsUniqueKeyPress(Keys.Escape) && IsActive) || (!OnlineManager.Connected && IsActive) && TimeSinceLastActivated >= 450) { TimeSinceLastActivated = 0; IsActive = !IsActive; var targetX = IsActive ? 0 : -Dialog.DialogContainer.Width; Dialog.DialogContainer.Animations.Clear(); Dialog.DialogContainer.Animations.Add(new Animation(AnimationProperty.X, Easing.OutQuint, Dialog.DialogContainer.X, targetX, 600)); if (!IsActive) { Dialog.IsClickable = false; ThreadScheduler.RunAfter(() => { DialogManager.Dismiss(Dialog); }, 450); } else { Dialog.IsClickable = true; DialogManager.Show(Dialog); } } }
public void can_use_multiple_threads() { using (var scheduler = new ThreadScheduler(5)) { scheduler.Start(() => { }); scheduler.Threads.ShouldHaveCount(5); } }
/// <summary> /// Ran on a separate thread to /// </summary> private void RunObjectScreenCheckThread() => ThreadScheduler.Run(() => { while (!Ruleset.Screen.Exiting) { CheckIfObjectsOnScreen(); Thread.Sleep(30); } });
/// <summary> /// Creates the navbar at the bottom of the screen /// </summary> private void CreateBottomNavbar() => BottomNavbar = new Navbar(new List <NavbarItem>() { // Mods new NavbarItem("Modifiers", false, (o, e) => DialogManager.Show(new ModifiersDialog()), true, false, true), // Edit new NavbarItem("Edit", false, (o, e) => { NotificationManager.Show(NotificationLevel.Warning, "Not implemented yet. Check back soon!"); }, true, false, true), // Export Mapset new NavbarItem("Export", false, (o, e) => { if (Math.Abs(GameBase.Game.TimeRunning - LastExportTime) < 2000) { NotificationManager.Show(NotificationLevel.Error, "Slow down! You can only export a set every 2 seconds."); return; } LastExportTime = GameBase.Game.TimeRunning; ThreadScheduler.Run(() => { NotificationManager.Show(NotificationLevel.Info, "Exporting mapset to file..."); MapManager.Selected.Value.Mapset.ExportToZip(); NotificationManager.Show(NotificationLevel.Success, "Successfully exported mapset!"); }); }, true, false, true) }, new List <NavbarItem>() { // Play new NavbarItem("Play", false, (o, e) => { switch (ActiveContainer) { case SelectContainerStatus.Mapsets: SwitchToContainer(SelectContainerStatus.Difficulty); break; case SelectContainerStatus.Difficulty: var screen = Screen as SelectScreen; screen?.ExitToGameplay(); break; default: throw new ArgumentOutOfRangeException(); } }, true, false, true), // Game Options new NavbarItem("Options", false, (o, e) => DialogManager.Show(new SettingsDialog()), true, false, true) }, true) { Parent = Container, Alignment = Alignment.TopLeft, };
/// <summary> /// Called when /// </summary> public void OnClicked() { var screen = (DownloadScreen)Container.View.Screen; // On the very first click of this mapset, set the bindables value // so that the download status can be aware of this clicked on mapset. if (screen.SelectedMapset.Value != this) { screen.SelectedMapset.Value = this; return; } if (Download != null) { NotificationManager.Show(NotificationLevel.Error, "This mapset is already downloading!"); return; } screen.SelectedMapset.Value = null; // Begin downloading the map. Download = MapsetDownloadManager.Download(Mapset); if (Download == null) { return; } // Update the progress bar Download.Progress.ValueChanged += (o, e) => Progress.Bindable.Value = e.Value.ProgressPercentage; // Handle download completions. Download.Completed.ValueChanged += (o, e) => { if (e.Value.Cancelled) { NotificationManager.Show(NotificationLevel.Info, $"Cancelled download for mapset: {MapsetId}!"); } else if (e.Value.Error == null) { NotificationManager.Show(NotificationLevel.Success, $"Downloaded: {Mapset["artist"]} - {Mapset["title"]}!"); // Animate it off-screen MoveToX(-Width, Easing.OutQuint, 400); // Remove the mapset from the list and destroy it. Container.Mapsets.Remove(this); ThreadScheduler.RunAfter(Destroy, 450); Container.RealignMapsets(); } else { NotificationManager.Show(NotificationLevel.Error, $"An error has occurred while downloading: {MapsetId}."); } }; }
/// <summary> /// </summary> public void CompletelyReinitialize() => ThreadScheduler.Run(() => { foreach (var item in CachedLines) { item.Value.ForEach(x => x.Destroy()); } CachedLines.Clear(); InitializeLines(true); });
/// <inheritdoc /> /// <summary> /// </summary> public override void OnFirstUpdate() { ThreadScheduler.Run(() => { ParseAndLoadMap(); LoadGameplayScreen(); }); base.OnFirstUpdate(); }
/// <summary> /// Handles the username selection process /// </summary> /// <param name="text"></param> private void OnBoxSubmitted(string text) { DialogManager.Dismiss(); ThreadScheduler.Run(() => { OnlineManager.Client.ChooseUsername(text, SteamUser.GetSteamID().m_SteamID, SteamFriends.GetPersonaName(), SteamManager.PTicket, SteamManager.PcbTicket); }); }
public void can_schedule_work() { var ran = false; using (var scheduler = ThreadScheduler.Default()) { scheduler.Start(() => ran = true); Wait.Until(() => ran).ShouldBeTrue(); } }
/// <summary> /// Exits to watch a replay online. /// </summary> private void WatchOnlineReplay() { if (IsFetchingOnlineReplay) { return; } IsFetchingOnlineReplay = true; Logger.Important($"Fetching online replay for score: {Score.Id}", LogType.Network); var dialog = new DownloadingReplayDialog(); DialogManager.Show(dialog); ThreadScheduler.Run(() => { var dir = $"{ConfigManager.DataDirectory}/Downloads"; var path = $"{dir}/{Score.Id}.qr"; Directory.CreateDirectory(dir); try { OnlineManager.Client?.DownloadReplay(Score.Id, path); var replay = new Replay(path); // Load up the .qua file again var qua = MapManager.Selected.Value.LoadQua(); MapManager.Selected.Value.Qua = qua; Exit(() => { if (AudioEngine.Track != null) { lock (AudioEngine.Track) AudioEngine.Track.Fade(10, 300); } return(new GameplayScreen(MapManager.Selected.Value.Qua, MapManager.Selected.Value.Md5Checksum, new List <Score>(), replay)); }); } catch (Exception e) { Logger.Error(e, LogType.Network); NotificationManager.Show(NotificationLevel.Error, "Failed to download online replay"); } finally { DialogManager.Dismiss(dialog); File.Delete(path); IsFetchingOnlineReplay = false; } }); }
/// <summary> /// Closes the dialog. /// </summary> private void Close() { if (isClosing) { return; } isClosing = true; InterfaceContainer.Animations.Clear(); InterfaceContainer.Animations.Add(new Animation(AnimationProperty.Y, Easing.OutQuint, InterfaceContainer.Y, InterfaceContainer.Height, 600)); ThreadScheduler.RunAfter(() => DialogManager.Dismiss(this), 450); }
/// <inheritdoc /> /// <summary> /// </summary> public OffsetCalibratorTip() { Tint = Color.Black; Size = new ScalableVector2(WindowManager.Width, 100); Alpha = 0; SetChildrenAlpha = true; FadeTo(0.85f, Easing.Linear, 400); Animations.Add(new Animation(AnimationProperty.Wait, Easing.Linear, 0, 1, 2000)); // ReSharper disable once ObjectCreationAsStatement new Sprite { Parent = this, Size = new ScalableVector2(Width, 2), Tint = Colors.MainAccent }; Icon = new Sprite { Parent = this, Alignment = Alignment.TopCenter, Image = FontAwesome.Get(FontAwesomeIcon.fa_information_button), Y = 18, Size = new ScalableVector2(24, 24) }; // ReSharper disable once ObjectCreationAsStatement var text = new SpriteTextBitmap(FontsBitmap.AllerRegular, "Play through the map, and at the end, a new global audio offset will be suggested to you.") { Parent = this, FontSize = 20, Y = Icon.Y + Icon.Height + 15, Alignment = Alignment.TopCenter }; // ReSharper disable once ObjectCreationAsStatement new Sprite { Parent = this, Size = new ScalableVector2(Width, 2), Tint = Colors.MainAccent, Alignment = Alignment.BotLeft }; ThreadScheduler.RunAfter(() => { ClearAnimations(); text.Visible = false; FadeTo(0, Easing.Linear, 200); }, 3500); }
private void RestoreDevice() { if (RestoreThread == null) { RestoreThread = new ThreadScheduler(); RestoreThread.Name = "RestoreThread"; RestoreThread.IsBackground = false; } RestoreThread.Start(new Action(() => { Restore.Start(); })); }
/// <summary> /// Saves the map /// </summary> public void Save(bool exitAfter = false) { if (IsQuittingAfterSave) { return; } if (exitAfter) { IsQuittingAfterSave = true; } if (MapManager.Selected.Value.Game != MapGame.Quaver) { NotificationManager.Show(NotificationLevel.Error, "You cannot save a map loaded from another game."); return; } if (SaveInProgress) { NotificationManager.Show(NotificationLevel.Error, "Slow down! We're already saving your map."); return; } if (!MapDatabaseCache.MapsToUpdate.Contains(MapManager.Selected.Value)) { MapDatabaseCache.MapsToUpdate.Add(MapManager.Selected.Value); } // Impoortant. Save the last save action, so we know whether or not the user has made changes. Ruleset.ActionManager.LastSaveAction = Ruleset.ActionManager.UndoStack.Count == 0 ? null : Ruleset.ActionManager.UndoStack.Peek(); ThreadScheduler.Run(() => { var path = $"{ConfigManager.SongDirectory}/{MapManager.Selected.Value.Directory}/{MapManager.Selected.Value.Path}"; SaveInProgress = true; WorkingMap.Save(path); SaveInProgress = false; LastSaveTime = GameBase.Game.TimeRunning; if (exitAfter) { ExitToSelect(); } else { NotificationManager.Show(NotificationLevel.Success, "Successfully saved the map."); } }); }
/// <summary> /// Closes the dialog. /// </summary> public void Close() { if (IsClosing) { return; } IsClosing = true; CreateGameInterface.Animations.Clear(); CreateGameInterface.MoveToX(-CreateGameInterface.Width - 2, Easing.OutQuint, 400); Alpha = 0f; ThreadScheduler.RunAfter(() => DialogManager.Dismiss(this), 450); }
/// <summary> /// If the client is currently being spectated, replay frames should be sent to the server /// </summary> public void SendReplayFramesToServer(bool force = false) { if (!OnlineManager.IsBeingSpectated || InReplayMode) { return; } if (TimeSinceSpectatorFramesLastSent < 750 && !force) { return; } TimeSinceSpectatorFramesLastSent = 0; if (ReplayCapturer.Replay.Frames.Count == 0 && !force) { return; } if (ReplayCapturer.Replay.Frames.Count == LastReplayFrameIndexSentToServer + 1 && !force) { return; } var frames = new List <ReplayFrame>(); for (var i = LastReplayFrameIndexSentToServer + 1; i < ReplayCapturer.Replay.Frames.Count; i++) { frames.Add(ReplayCapturer.Replay.Frames[i]); } LastReplayFrameIndexSentToServer = ReplayCapturer.Replay.Frames.Count - 1; SpectatorClientStatus status; if (LastReplayFrameIndexSentToServer == -1) { status = SpectatorClientStatus.NewSong; } else if (IsPaused) { status = SpectatorClientStatus.Paused; } else { status = SpectatorClientStatus.Playing; } ThreadScheduler.Run(() => OnlineManager.Client?.SendReplaySpectatorFrames(status, AudioEngine.Track.Time, frames)); }
private void GetiDevice() { if (DeviceCheckerThread == null) { DeviceCheckerThread = new ThreadScheduler(); DeviceCheckerThread.Name = "DeviceCheckerThread"; DeviceCheckerThread.IsBackground = true; } DeviceCheckerThread.Start(new Action(() => { while (KeepCheckingiDevices) { DeviceConnected = ConnectedDevice.CheckforDevices(); if (DeviceConnected) { ConnectedDevice.ConnectToDevice(); } else { ConnectedDevice.DiconnectDevice(); } if (deviceNameLbl.InvokeRequired) { deviceNameLbl.BeginInvoke((MethodInvoker) delegate() { SetLabelText(deviceNameLbl, NoDeviceName + ConnectedDevice.Name); }); } if (deviceModelLbl.InvokeRequired) { deviceModelLbl.BeginInvoke((MethodInvoker) delegate() { SetLabelText(deviceModelLbl, NoModel + ConnectedDevice.DeviceIdentifier); }); } if (deviceVersionLbl.InvokeRequired) { deviceVersionLbl.BeginInvoke((MethodInvoker) delegate() { SetLabelText(deviceVersionLbl, NoVersion + ConnectedDevice.Version); }); } Thread.Sleep(1000); } })); }
/// <summary> /// Exits to watch a replay online. /// </summary> private void WatchOnlineReplay() { if (IsFetchingOnlineReplay) { return; } IsFetchingOnlineReplay = true; Logger.Important($"Fetching online replay for score: {Score.Id}", LogType.Network); var dialog = new DownloadingReplayDialog(); DialogManager.Show(dialog); ThreadScheduler.Run(() => { var dir = $"{ConfigManager.DataDirectory}/Downloads"; var path = $"{dir}/{Score.Id}.qr"; Directory.CreateDirectory(dir); try { OnlineManager.Client?.DownloadReplay(Score.Id, path); var replay = new Replay(path); Exit(() => { if (AudioEngine.Track != null) { lock (AudioEngine.Track) AudioEngine.Track.Fade(10, 300); } GameBase.Game.GlobalUserInterface.Cursor.Alpha = 0; return(new MapLoadingScreen(new List <Score>(), replay)); }); } catch (Exception e) { Logger.Error(e, LogType.Network); NotificationManager.Show(NotificationLevel.Error, "Failed to download online replay"); } finally { DialogManager.Dismiss(dialog); File.Delete(path); IsFetchingOnlineReplay = false; } }); }
/// <summary> /// Called every frame. Waits for a skin reload to be queued up. /// </summary> public static void HandleSkinReloading() { // Reload skin when applicable if (TimeSkinReloadRequested != 0 && GameBase.Game.TimeRunning - TimeSkinReloadRequested >= 400) { Load(); TimeSkinReloadRequested = 0; ThreadScheduler.RunAfter(() => { Transitioner.FadeOut(); NotificationManager.Show(NotificationLevel.Success, "Skin has been successfully loaded!"); }, 200); } }
/// <summary> /// Closes the JoinChannelDialog if it is already open. /// </summary> public void CloseJoinChannelDialog() { if (JoinChannelDialog == null) { return; } TimeSinceLastChannelDialogOpened = 0; JoinChannelDialog.InterfaceContainer.Animations.Clear(); JoinChannelDialog.InterfaceContainer.Animations.Add(new Animation(AnimationProperty.Y, Easing.OutQuint, JoinChannelDialog.InterfaceContainer.Y, JoinChannelDialog.InterfaceContainer.Height, 600)); ThreadScheduler.RunAfter(() => DialogManager.Dismiss(JoinChannelDialog), 450); }
/// <summary> /// Closes the dialog. /// </summary> public void Close() { if (IsClosing) { return; } IsClosing = true; MetadataChanger.Animations.Clear(); MetadataChanger.MoveToX(-MetadataChanger.Width - 2, Easing.OutQuint, 400); Animations.Clear(); Animations.Add(new Animation(AnimationProperty.Alpha, Easing.Linear, Alpha, 0f, 200)); ThreadScheduler.RunAfter(() => DialogManager.Dismiss(this), 450); }