/// <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);
     }
 });
Exemple #2
0
        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;
                }
            }
        }
Exemple #3
0
 /// <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;
     }
 }
Exemple #6
0
        /// <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);
        }
Exemple #8
0
        /// <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);
     }
 }
Exemple #10
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);
     }
 }
Exemple #12
0
 /// <summary>
 ///     Ran on a separate thread to
 /// </summary>
 private void RunObjectScreenCheckThread() => ThreadScheduler.Run(() =>
 {
     while (!Ruleset.Screen.Exiting)
     {
         CheckIfObjectsOnScreen();
         Thread.Sleep(30);
     }
 });
Exemple #13
0
        /// <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,
        };
Exemple #14
0
        /// <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();
        }
Exemple #17
0
        /// <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();
            }
        }
Exemple #19
0
        /// <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);
        }
Exemple #22
0
 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);
        }
Exemple #25
0
        /// <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));
        }
Exemple #26
0
        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);
                }
            }));
        }
Exemple #27
0
        /// <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;
                }
            });
        }
Exemple #28
0
        /// <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);
            }
        }
Exemple #29
0
        /// <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);
        }