예제 #1
0
        internal static void SetUpdateState(UpdateStates state)
        {
            Scheduler.Add(delegate
            {
                if (state == UpdateState)
                {
                    return;
                }

                UpdateState = state;

                VoidDelegate d = UpdateStateChanged;
                if (d != null)
                {
                    d();
                }

                switch (UpdateState)
                {
                case UpdateStates.EmergencyFallback:
                    //let's hope we never need this.
                    OsuMain.Repair(true);
                    break;

                case UpdateStates.Completed:
                    ConfigManager.sUpdateFailCount.Value = 0;

                    //Update has completed and doesn't need a restart.
                    ConfigManager.sUpdatePending.Value = false;
                    ConfigManager.SaveConfig();

                    string lastVersion = ConfigManager.sLastVersion;

                    NotificationManager.ShowMessage(
                        string.Format(LocalisationManager.GetString(OsuString.Update_Complete), General.BUILD_NAME) + '\n' +
                        LocalisationManager.GetString(OsuString.GameBase_Updater_Changelog),
                        Color.Pink, 10000, delegate
                    {
                        if (string.IsNullOrEmpty(General.SUBVERSION))
                        {
                            //public releases
                            GameBase.ProcessStart(string.Format(@"https://osu.ppy.sh/p/changelog?v={0}&s={1}&l={2}",
                                                                General.BUILD_NAME, General.TargetedPublicStream.ToString().ToLower(), lastVersion));
                        }
                        else
                        {
                            //beta or cutting edge
                            GameBase.ProcessStart(@"https://osu.ppy.sh/p/changelog?v=next");
                        }
                    });
                    break;

                case UpdateStates.Error:
                    ConfigManager.sUpdatePending.Value = false;

                    if (CommonUpdater.LastError != null)
                    {
                        if (CommonUpdater.LastError is MissingFrameworkVersionException)
                        {
                            CommonUpdater.ResetError();
                            NotificationManager.ShowMessage(LocalisationManager.GetString(OsuString.GameBase_UpdateFailedFrameworkVersion), Color.Red, 300000, delegate { OsuMain.ForceUpdate(true); });
                        }
                        else
                        {
                            RunBackgroundThread(delegate
                            {
                                ErrorSubmission.Submit(new OsuError(CommonUpdater.LastError)
                                {
                                    Feedback = @"update error",
                                    ILTrace  = CommonUpdater.LastErrorExtraInformation ?? string.Empty
                                });

                                CommonUpdater.ResetError();
                            });
                        }
                    }

                    ConfigManager.ResetHashes();

                    ConfigManager.sUpdateFailCount.Value++;
                    break;

                case UpdateStates.NeedsRestart:

                    //the update could have already moved the files into their new place, so we want to make sure we have reloaded the master config file.
                    ConfigManager.ReloadHashCache();

                    ConfigManager.sUpdateFailCount.Value = 0;

                    bool isNewUpdate = !ConfigManager.sUpdatePending.Value;

                    ConfigManager.sUpdatePending.Value = true;

                    //Update completed but needs a restart. We either want to force a restart or just wait for the next user-triggered restart.
                    if (UpdateForceRestart)
                    {
                        CompleteUpdate();
                    }
                    else if (Mode != OsuModes.Menu && isNewUpdate)
                    {
                        NotificationManager.ShowMessage(LocalisationManager.GetString(OsuString.General_NewVersion), Color.Pink, 10000);
                    }

                    UpdatePendingRestart = true;
                    break;

                case UpdateStates.NoUpdate:
                    ConfigManager.sUpdateFailCount.Value = 0;
                    break;
                }
            });
        }
예제 #2
0
        public void TestScheduleOnce([Values(false, true)] bool fromMainThread, [Values(false, true)] bool forceScheduled)
        {
            this.fromMainThread = fromMainThread;

            int invocations = 0;

            scheduler.Add(() => invocations++, forceScheduled);

            if (fromMainThread && !forceScheduled)
            {
                Assert.AreEqual(1, invocations);
            }
            else
            {
                Assert.AreEqual(0, invocations);
            }

            scheduler.Update();
            Assert.AreEqual(1, invocations);

            // Ensures that the delegate runs only once in the scheduled/not on main thread branch
            scheduler.Update();
            Assert.AreEqual(1, invocations);
        }
예제 #3
0
 public void Execute(Action op)
 {
     Scheduler.Add(op);
 }
예제 #4
0
 Task IMultiplayerClient.SettingsChanged(MultiplayerRoomSettings newSettings)
 {
     Scheduler.Add(() => updateLocalRoomSettings(newSettings));
     return(Task.CompletedTask);
 }
예제 #5
0
 private void onAutoSize()
 {
     Scheduler.Add(() => activityAutosize.FadeOutFromOne(1));
 }
예제 #6
0
 private void onInvalidate(Drawable d)
 {
     Scheduler.Add(() => activityInvalidate.FadeOutFromOne(1));
 }
예제 #7
0
 /// <summary>
 /// Retrieves the total score of a <see cref="ScoreInfo"/> in the given <see cref="ScoringMode"/>.
 /// The score is returned in a callback that is run on the update thread.
 /// </summary>
 /// <param name="score">The <see cref="ScoreInfo"/> to calculate the total score of.</param>
 /// <param name="callback">The callback to be invoked with the total score.</param>
 /// <param name="mode">The <see cref="ScoringMode"/> to return the total score as.</param>
 /// <param name="cancellationToken">A <see cref="CancellationToken"/> to cancel the process.</param>
 public void GetTotalScore([NotNull] ScoreInfo score, [NotNull] Action <long> callback, ScoringMode mode = ScoringMode.Standardised, CancellationToken cancellationToken = default)
 {
     GetTotalScoreAsync(score, mode, cancellationToken)
     .ContinueWith(s => scheduler.Add(() => callback(s.Result)), TaskContinuationOptions.OnlyOnRanToCompletion);
 }
예제 #8
0
        public void TestLogOutputFromManyQueuedTasks([Values(false, true)] bool withFlushing)
        {
            int matchingLogCount = 0;

            using (var storage = new TemporaryNativeStorage(nameof(TestLogOutputFromManyQueuedTasks)))
            {
                Logger.Storage = storage;
                Logger.Enabled = true;

                Logger.NewEntry += logTest;

                Assert.AreEqual(0, matchingLogCount);

                for (int i = 0; i < Scheduler.LOG_EXCESSSIVE_QUEUE_LENGTH_INTERVAL / 2; i++)
                {
                    scheduler.Add(() => { });
                    if (withFlushing)
                    {
                        scheduler.Update();
                    }
                }

                Assert.AreEqual(0, matchingLogCount);

                for (int i = 0; i < Scheduler.LOG_EXCESSSIVE_QUEUE_LENGTH_INTERVAL / 2; i++)
                {
                    scheduler.Add(() => { });
                    if (withFlushing)
                    {
                        scheduler.Update();
                    }
                }

                Assert.AreEqual(withFlushing ? 0 : 1, matchingLogCount);

                for (int i = 0; i < Scheduler.LOG_EXCESSSIVE_QUEUE_LENGTH_INTERVAL; i++)
                {
                    scheduler.Add(() => { });
                    if (withFlushing)
                    {
                        scheduler.Update();
                    }
                }

                Assert.AreEqual(withFlushing ? 0 : 2, matchingLogCount);

                Logger.NewEntry -= logTest;
                Logger.Enabled   = false;
                Logger.Flush();

                void logTest(LogEntry entry)
                {
                    if (entry.Target == LoggingTarget.Performance && entry.Message.Contains("tasks pending"))
                    {
                        matchingLogCount++;
                    }
                }
            }
        }
예제 #9
0
        //~EventWorld()
        //{
        //    //CurrentEvent.EventEnd(this, (TwitchChat)mod);
        //}

        public void AddTask(Action task)
        {
            WorldScheduler.Add(task);
        }
예제 #10
0
파일: ChatOverlay.cs 프로젝트: Remenems/osu
        private void currentChannelChanged(ValueChangedEvent <Channel> e)
        {
            if (e.NewValue == null)
            {
                textbox.Current.Disabled = true;
                currentChannelContainer.Clear(false);
                ChannelSelectionOverlay.Show();
                checkIsLoggedIn();
                return;
            }

            if (e.NewValue is ChannelSelectorTabItem.ChannelSelectorTabChannel)
            {
                checkIsLoggedIn();
                return;
            }

            textbox.Current.Disabled = e.NewValue.ReadOnly;

            if (ChannelTabControl.Current.Value != e.NewValue)
            {
                Scheduler.Add(() => ChannelTabControl.Current.Value = e.NewValue);
            }

            var loaded = loadedChannels.Find(d => d.Channel == e.NewValue);

            if (loaded == null)
            {
                currentChannelContainer.FadeOut(500, Easing.OutQuint);
                loading.Show();

                loaded = new DrawableChannel(e.NewValue);
                loadedChannels.Add(loaded);
                LoadComponentAsync(loaded, l =>
                {
                    if (currentChannel.Value != e.NewValue)
                    {
                        checkIsLoggedIn();
                        return;
                    }

                    loading.Hide();

                    currentChannelContainer.Clear(false);
                    currentChannelContainer.Add(loaded);
                    currentChannelContainer.FadeIn(500, Easing.OutQuint);
                });
            }
            else
            {
                currentChannelContainer.Clear(false);
                currentChannelContainer.Add(loaded);
            }

            // mark channel as read when channel switched
            if (e.NewValue.Messages.Any())
            {
                channelManager.MarkChannelAsRead(e.NewValue);
            }

            checkIsLoggedIn();
        }
예제 #11
0
        private void InitializeTester()
        {
            if (!PREDEFINED_TEST)
            {
                return;
            }

            if (BeatmapManager.Beatmaps.Count > 0)
            {
                if (USE_LAST_PLAYED_BEATMAP)
                {
                    List <Beatmap> temp = new List <Beatmap>(BeatmapManager.Beatmaps);
                    temp.Sort((a, b) => { return(a.DateLastPlayed.CompareTo(b.DateLastPlayed)); });
                    BeatmapManager.Current = temp[temp.Count - 1];
                }
                else //Choose a random beatmap
                {
                    BeatmapManager.Current = BeatmapManager.Beatmaps[RNG.Next(0, BeatmapManager.Beatmaps.Count)];
                }
            }

            if (MULTIPLAYER_MATCH)
            {
                if (BeatmapManager.Current == null)
                {
                    NotificationManager.ShowMessage("Couldn't start in specified test mode because no beatmaps were available.");
                    return;
                }

                BanchoClient.Start();

                Mode = OsuModes.MatchSetup;

                const int player_count = 8;

                while (!BanchoClient.Connected || !BanchoClient.InitializationComplete)
                {
                    Scheduler.Update();
                }

                PresenceCache.QueryAll();

                while (User.Id <= 0 || BanchoClient.Users.Count < player_count)
                {
                    Scheduler.Update();
                }

                List <User> users = BanchoClient.Users.FindAll(u => u.InitialLoadComplete && u.Id != User.Id);
                users.Insert(0, User); //we are the first user.

                MatchSetup.Match = new ClientSideMatch(new bMatch(MatchTypes.Standard,
                                                                  MatchScoringTypes.Score,
                                                                  MatchTeamTypes.TeamVs,
                                                                  PlayModes.Osu,
                                                                  @"My test game",
                                                                  string.Empty,
                                                                  player_count,
                                                                  BeatmapManager.Current.SortTitle,
                                                                  BeatmapManager.Current.BeatmapChecksum,
                                                                  BeatmapManager.Current.BeatmapId,
                                                                  MODS_TO_USE,
                                                                  2,
                                                                  MultiSpecialModes.FreeMod
                                                                  ));

                for (int i = 0; i < player_count; i++)
                {
                    MatchSetup.Match.slotId[i]    = users[i].Id;
                    MatchSetup.Match.UserSlots[i] = users[i];

                    MatchSetup.Match.slotStatus[i] = SlotStatus.Playing;
                    switch (MatchSetup.Match.matchTeamType)
                    {
                    case MatchTeamTypes.TagTeamVs:
                    case MatchTeamTypes.TeamVs:
                        MatchSetup.Match.slotTeam[i] = i % 2 == 0 ? SlotTeams.Blue : SlotTeams.Red;
                        break;
                    }
                }

                bScoreFrame[] frames = new bScoreFrame[player_count];
                for (int i = 0; i < player_count; i++)
                {
                    frames[i] = new bScoreFrame {
                        id = (byte)i, pass = true, currentHp = 200
                    }
                }
                ;

                RunBackgroundThread(delegate
                {
                    Thread.Sleep(5000);

                    for (int i = 0; i < player_count; i++)
                    {
                        PlayerVs.MatchPlayerSkipped(i);
                        Thread.Sleep(100);
                    }

                    Thread.Sleep(2000);

                    Player.QueueSkip();
                    Player.Instance?.DoSkip();

                    PlayerVs.AllPlayersLoaded    = true;
                    PlayerVs.AllPlayersCompleted = true;

                    while (true)
                    {
                        byte player = (byte)RNG.Next(0, player_count);

                        switch (RNG.Next(0, 30))
                        {
                        default:
                            frames[player].count300 += 1;
                            frames[player].currentCombo++;
                            frames[player].currentHp += 3;
                            break;

                        case 1:
                        case 2:
                        case 3:
                            frames[player].count100 += 1;
                            frames[player].currentCombo++;
                            frames[player].currentHp += 2;
                            break;

                        case 4:
                        case 5:
                            frames[player].count50   += 1;
                            frames[player].currentHp += 1;
                            frames[player].currentCombo++;
                            break;

                        case 6:
                            frames[player].countMiss   += 1;
                            frames[player].currentHp   -= 50;
                            frames[player].currentCombo = 0;
                            break;
                        }

                        frames[player].currentHp = OsuMathHelper.Clamp(frames[player].currentHp, 0, 200);

                        if (frames[player].currentHp == 0)
                        {
                            frames[player].pass = false;
                        }
                        else if (frames[player].currentHp > 100)
                        {
                            frames[player].pass = true;
                        }

                        frames[player].totalScore += frames[player].currentCombo * 300;
                        frames[player].maxCombo    = Math.Max(frames[player].maxCombo, frames[player].currentCombo);


                        PlayerVs.MatchScoreUpdate(frames[player]);

                        Thread.Sleep(50);
                    }
                });
            }

            switch (INITIAL_MODE)
            {
            case OsuModes.Play:
                if (BeatmapManager.Current == null)
                {
                    NotificationManager.ShowMessage("Couldn't start in specified test mode because no beatmaps were available.");
                    return;
                }

                ModManager.ModStatus = MODS_TO_USE;

                if (AUTOMATIC_SKIP)
                {
                    GameBase.RunBackgroundThread(delegate
                    {
                        while (true)
                        {
                            if (Player.Instance != null && Player.Instance.Status != PlayerStatus.Busy)
                            {
                                Scheduler.Add(delegate { Player.Instance?.DoSkip(); });
                                if (Player.HasSkipped)
                                {
                                    break;
                                }
                            }

                            Thread.Sleep(200);
                        }
                    });
                }

                if (AUTOPLAY)
                {
                    ModManager.ModStatus |= Mods.Autoplay;
                }

                break;
            }

            QueuedMode  = INITIAL_MODE;
            Player.Mode = INITIAL_PLAY_MODE;
        }
    }
예제 #12
0
 private void Start()
 {
     scheduler.Add(0, "School");
     scheduler.Add(1, "School");
 }
예제 #13
0
파일: APIAccess.cs 프로젝트: Nicemale/osu
 /// <summary>
 /// Register a component to receive API events.
 /// Fires <see cref="IOnlineComponent.APIStateChanged"/> once immediately to ensure a correct state.
 /// </summary>
 /// <param name="component"></param>
 public void Register(IOnlineComponent component)
 {
     Scheduler.Add(delegate { components.Add(component); });
     component.APIStateChanged(this, state);
 }
예제 #14
0
 private void onMatchStarted() => Scheduler.Add(() =>
 {
     loadingDisplay.Hide();
     base.StartGameplay();
 });
예제 #15
0
파일: ChatOverlay.cs 프로젝트: nekodex/osu
        private void currentChannelChanged(ValueChangedEvent <Channel> e)
        {
            if (e.NewValue == null)
            {
                textBox.Current.Disabled = true;
                currentChannelContainer.Clear(false);
                ChannelSelectionOverlay.Show();
                return;
            }

            if (e.NewValue is ChannelSelectorTabItem.ChannelSelectorTabChannel)
            {
                return;
            }

            textBox.Current.Disabled = e.NewValue.ReadOnly;

            if (ChannelTabControl.Current.Value != e.NewValue)
            {
                Scheduler.Add(() => ChannelTabControl.Current.Value = e.NewValue);
            }

            var loaded = loadedChannels.Find(d => d.Channel == e.NewValue);

            if (loaded == null)
            {
                currentChannelContainer.FadeOut(500, Easing.OutQuint);
                loading.Show();

                loaded = new DrawableChannel(e.NewValue);
                loadedChannels.Add(loaded);
                LoadComponentAsync(loaded, l =>
                {
                    if (currentChannel.Value != e.NewValue)
                    {
                        return;
                    }

                    // check once more to ensure the channel hasn't since been removed from the loaded channels list (may have been left by some automated means).
                    if (!loadedChannels.Contains(loaded))
                    {
                        return;
                    }

                    loading.Hide();

                    currentChannelContainer.Clear(false);
                    currentChannelContainer.Add(loaded);
                    currentChannelContainer.FadeIn(500, Easing.OutQuint);
                });
            }
            else
            {
                currentChannelContainer.Clear(false);
                currentChannelContainer.Add(loaded);
            }

            // mark channel as read when channel switched
            if (e.NewValue.Messages.Any())
            {
                channelManager.MarkChannelAsRead(e.NewValue);
            }
        }
예제 #16
0
 internal static void ScheduleDisposal(Action disposalAction)
 {
     host?.UpdateThread.Scheduler.Add(() => reset_scheduler.Add(disposalAction.Invoke));
 }
예제 #17
0
 /// <summary>
 /// Enqueues a texture to be uploaded in the next frame.
 /// </summary>
 /// <param name="texture">The texture to be uploaded.</param>
 public static void EnqueueTextureUpload(TextureGL texture)
 {
     //todo: don't use scheduler
     resetScheduler.Add(() => texture.Upload());
 }
예제 #18
0
        private BuildResultCode BuildSlave()
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory);

            VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath);

            // Open WCF channel with master builder
            var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                SendTimeout = TimeSpan.FromSeconds(300.0), MaxReceivedMessageSize = int.MaxValue
            };
            var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(builderOptions.SlavePipe));

            try
            {
                RegisterRemoteLogger(processBuilderRemote);

                // Make sure to laod all assemblies containing serializers
                // TODO: Review how costly it is to do so, and possibily find a way to restrict what needs to be loaded (i.e. only app plugins?)
                foreach (var assemblyLocation in processBuilderRemote.GetAssemblyContainerLoadedAssemblies())
                {
                    AssemblyContainer.Default.LoadAssemblyFromPath(assemblyLocation, builderOptions.Logger);
                }

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string buildPath = builderOptions.BuildDirectory;

                Builder.OpenObjectDatabase(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName);

                var         logger      = builderOptions.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = processBuilderRemote.GetCommandToExecute();

                    // Run command
                    var inputHashes    = FileVersionTracker.GetDefault();
                    var builderContext = new BuilderContext(inputHashes, null);

                    var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger);
                    MicrothreadLocalDatabases.MountDatabase(commandContext.GetOutputObjectsGroups());
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    processBuilderRemote.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    builderOptions.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
            finally
            {
                // Close WCF channel
                // ReSharper disable SuspiciousTypeConversion.Global
                ((IClientChannel)processBuilderRemote).Close();
                // ReSharper restore SuspiciousTypeConversion.Global
            }
        }
예제 #19
0
        private BuildResultCode BuildSlave()
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory);

            PrepareDatabases();

            VirtualFileSystem.CreateDirectory("/data/");
            VirtualFileSystem.CreateDirectory("/data/db/");

            // Open WCF channel with master builder
            var namedPipeBinding = new NetNamedPipeBinding(NetNamedPipeSecurityMode.None)
            {
                SendTimeout = TimeSpan.FromSeconds(300.0)
            };
            var processBuilderRemote = ChannelFactory <IProcessBuilderRemote> .CreateChannel(namedPipeBinding, new EndpointAddress(builderOptions.SlavePipe));

            try
            {
                RegisterRemoteLogger(processBuilderRemote);

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string buildPath    = builderOptions.BuildDirectory;
                string buildProfile = builderOptions.BuildProfile;

                Builder.SetupBuildPath(buildPath);

                var         logger      = builderOptions.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = processBuilderRemote.GetCommandToExecute();
                    BuildParameterCollection parameters = processBuilderRemote.GetBuildParameters();

                    // Run command
                    var inputHashes    = FileVersionTracker.GetDefault();
                    var builderContext = new BuilderContext(buildPath, buildProfile, inputHashes, parameters, 0, null);

                    var commandContext = new RemoteCommandContext(processBuilderRemote, command, builderContext, logger);
                    IndexFileCommand.MountDatabase(commandContext.GetOutputObjectsGroups());
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    processBuilderRemote.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    builderOptions.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
            finally
            {
                // Close WCF channel
                // ReSharper disable SuspiciousTypeConversion.Global
                ((IClientChannel)processBuilderRemote).Close();
                // ReSharper restore SuspiciousTypeConversion.Global
            }
        }
예제 #20
0
 private void onLayout()
 {
     Scheduler.Add(() => activityLayout.FadeOutFromOne(1));
 }
예제 #21
0
파일: APIAccess.cs 프로젝트: Vagacoder/osu
 public void Unregister(IOnlineComponent component)
 {
     Scheduler.Add(delegate { components.Remove(component); });
 }
예제 #22
0
 private void schedule(Action action) => Scheduler.Add(action, false);
예제 #23
0
        private BuildResultCode BuildSlave()
        {
            // Mount build path
            ((FileSystemProvider)VirtualFileSystem.ApplicationData).ChangeBasePath(builderOptions.BuildDirectory);

            VirtualFileSystem.CreateDirectory(VirtualFileSystem.ApplicationDatabasePath);

            // Open ServiceWire Client Channel
            using (var client = new NpClient <IProcessBuilderRemote>(new NpEndPoint(builderOptions.SlavePipe), new StrideServiceWireSerializer()))
            {
                RegisterRemoteLogger(client);

                // Make sure to laod all assemblies containing serializers
                // TODO: Review how costly it is to do so, and possibily find a way to restrict what needs to be loaded (i.e. only app plugins?)
                foreach (var assemblyLocation in client.Proxy.GetAssemblyContainerLoadedAssemblies())
                {
                    AssemblyContainer.Default.LoadAssemblyFromPath(assemblyLocation, builderOptions.Logger);
                }

                // Create scheduler
                var scheduler = new Scheduler();

                var status = ResultStatus.NotProcessed;

                // Schedule command
                string buildPath = builderOptions.BuildDirectory;

                Builder.OpenObjectDatabase(buildPath, VirtualFileSystem.ApplicationDatabaseIndexName);

                var         logger      = builderOptions.Logger;
                MicroThread microthread = scheduler.Add(async() =>
                {
                    // Deserialize command and parameters
                    Command command = client.Proxy.GetCommandToExecute();

                    // Run command
                    var inputHashes    = FileVersionTracker.GetDefault();
                    var builderContext = new BuilderContext(inputHashes, null);

                    var commandContext = new RemoteCommandContext(client.Proxy, command, builderContext, logger);
                    MicrothreadLocalDatabases.MountDatabase(commandContext.GetOutputObjectsGroups());
                    command.PreCommand(commandContext);
                    status = await command.DoCommand(commandContext);
                    command.PostCommand(commandContext, status);

                    // Returns result to master builder
                    client.Proxy.RegisterResult(commandContext.ResultEntry);
                });

                while (true)
                {
                    scheduler.Run();

                    // Exit loop if no more micro threads
                    lock (scheduler.MicroThreads)
                    {
                        if (!scheduler.MicroThreads.Any())
                        {
                            break;
                        }
                    }

                    Thread.Sleep(0);
                }

                // Rethrow any exception that happened in microthread
                if (microthread.Exception != null)
                {
                    builderOptions.Logger.Fatal(microthread.Exception.ToString());
                    return(BuildResultCode.BuildError);
                }

                if (status == ResultStatus.Successful || status == ResultStatus.NotTriggeredWasSuccessful)
                {
                    return(BuildResultCode.Successful);
                }

                return(BuildResultCode.BuildError);
            }
        }
예제 #24
0
 public void Execute(Task task)
 {
     Scheduler.Add(task.RunSynchronously);
 }
예제 #25
0
        /// <summary>
        /// Applies a new <see cref="HitObject"/> to be represented by this <see cref="DrawableHitObject"/>.
        /// </summary>
        /// <param name="hitObject">The <see cref="HitObject"/> to apply.</param>
        /// <param name="lifetimeEntry">The <see cref="HitObjectLifetimeEntry"/> controlling the lifetime of <paramref name="hitObject"/>.</param>
        public void Apply([NotNull] HitObject hitObject, [CanBeNull] HitObjectLifetimeEntry lifetimeEntry)
        {
            free();

            HitObject = hitObject ?? throw new InvalidOperationException($"Cannot apply a null {nameof(HitObject)}.");

            this.lifetimeEntry = lifetimeEntry;

            if (lifetimeEntry != null)
            {
                // Transfer lifetime from the entry.
                LifetimeStart = lifetimeEntry.LifetimeStart;
                LifetimeEnd   = lifetimeEntry.LifetimeEnd;

                // Copy any existing result from the entry (required for rewind / judgement revert).
                Result = lifetimeEntry.Result;
            }
            else
            {
                LifetimeStart = HitObject.StartTime - InitialLifetimeOffset;
            }

            // Ensure this DHO has a result.
            Result ??= CreateResult(HitObject.CreateJudgement())
            ?? throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");

            // Copy back the result to the entry for potential future retrieval.
            if (lifetimeEntry != null)
            {
                lifetimeEntry.Result = Result;
            }

            foreach (var h in HitObject.NestedHitObjects)
            {
                var pooledDrawableNested = pooledObjectProvider?.GetPooledDrawableRepresentation(h);
                var drawableNested       = pooledDrawableNested
                                           ?? CreateNestedHitObject(h)
                                           ?? throw new InvalidOperationException($"{nameof(CreateNestedHitObject)} returned null for {h.GetType().ReadableName()}.");

                // Invoke the event only if this nested object is just created by `CreateNestedHitObject`.
                if (pooledDrawableNested == null)
                {
                    OnNestedDrawableCreated?.Invoke(drawableNested);
                }

                drawableNested.OnNewResult            += onNewResult;
                drawableNested.OnRevertResult         += onRevertResult;
                drawableNested.ApplyCustomUpdateState += onApplyCustomUpdateState;

                nestedHitObjects.Value.Add(drawableNested);
                AddNestedHitObject(drawableNested);

                drawableNested.OnParentReceived(this);
            }

            StartTimeBindable.BindTo(HitObject.StartTimeBindable);
            StartTimeBindable.BindValueChanged(onStartTimeChanged);

            if (HitObject is IHasComboInformation combo)
            {
                comboIndexBindable.BindTo(combo.ComboIndexBindable);
            }

            samplesBindable.BindTo(HitObject.SamplesBindable);
            samplesBindable.BindCollectionChanged(onSamplesChanged, true);

            HitObject.DefaultsApplied += onDefaultsApplied;

            OnApply(hitObject);
            HitObjectApplied?.Invoke(this);

            // If not loaded, the state update happens in LoadComplete(). Otherwise, the update is scheduled to allow for lifetime updates.
            if (IsLoaded)
            {
                Scheduler.Add(() =>
                {
                    if (Result.IsHit)
                    {
                        updateState(ArmedState.Hit, true);
                    }
                    else if (Result.HasResult)
                    {
                        updateState(ArmedState.Miss, true);
                    }
                    else
                    {
                        updateState(ArmedState.Idle, true);
                    }
                });
            }

            hasHitObjectApplied = true;
        }
예제 #26
0
        /// <summary>
        /// Creates a <see cref="OsuTKWindow"/> with a given <see cref="IGameWindow"/> implementation.
        /// </summary>
        protected OsuTKWindow([NotNull] IGameWindow osuTKGameWindow)
        {
            OsuTKGameWindow          = osuTKGameWindow;
            OsuTKGameWindow.KeyDown += OnKeyDown;

            CurrentDisplay.Value = PrimaryDisplay;

            // Moving or resizing the window needs to check to see if we've moved to a different display.
            // This will update the CurrentDisplay bindable.
            Move   += (sender, e) => checkCurrentDisplay();
            Resize += (sender, e) => checkCurrentDisplay();

            Closing += (sender, e) => e.Cancel = ExitRequested?.Invoke() ?? false;
            Closed  += (sender, e) => Exited?.Invoke();

            MouseEnter += (sender, args) => cursorInWindow.Value = true;
            MouseLeave += (sender, args) => cursorInWindow.Value = false;

            FocusedChanged += (o, e) => isActive.Value = Focused;

            supportedWindowModes.AddRange(DefaultSupportedWindowModes);

            UpdateFrame += (o, e) => UpdateFrameScheduler.Update();
            UpdateFrameScheduler.Add(() => isActive.Value = Focused);

            WindowStateChanged += (o, e) => isActive.Value = WindowState != WindowState.Minimised;

            MakeCurrent();

            string version = GL.GetString(StringName.Version);
            string versionNumberSubstring = getVersionNumberSubstring(version);

            GLVersion = new Version(versionNumberSubstring);

            // As defined by https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetString.xml
            IsEmbedded = version.Contains("OpenGL ES");

            version = GL.GetString(StringName.ShadingLanguageVersion);

            if (!string.IsNullOrEmpty(version))
            {
                try
                {
                    GLSLVersion = new Version(versionNumberSubstring);
                }
                catch (Exception e)
                {
                    Logger.Error(e, $@"couldn't set GLSL version using string '{version}'");
                }
            }

            if (GLSLVersion == null)
            {
                GLSLVersion = new Version();
            }

            Logger.Log($@"GL Initialized
                        GL Version:                 {GL.GetString(StringName.Version)}
                        GL Renderer:                {GL.GetString(StringName.Renderer)}
                        GL Shader Language version: {GL.GetString(StringName.ShadingLanguageVersion)}
                        GL Vendor:                  {GL.GetString(StringName.Vendor)}
                        GL Extensions:              {GL.GetString(StringName.Extensions)}");
        }
예제 #27
0
 protected override void LoadComplete()
 {
     base.LoadComplete();
     Scheduler.Add(updateTimeWithReschedule);
 }