//[CallOnThread("Updater")] public void Update() { Profiler.Start(); try { watchdogToken.Ping(); CurrentFrame.Clear(); foreach (GameComponent component in GameComponents) { if (component.Enabled) { component.Update(gameTime); } } if (game.State != null) { game.State.Update(CurrentFrame, gameTime.TotalGameTime.TotalSeconds, gameTime); CurrentFrame.Sort(); } } finally { Profiler.Stop(); } }
//[CallOnThread("Loader")] public void Load() { Profiler.Start(); try { WatchdogToken.Ping(); Game.State.Load(); } finally { Profiler.Stop(); } }
//[CallOnThread("Updater")] public void Update() { Profiler.Start(); try { WatchdogToken.Ping(); CurrentFrame.Clear(); Game.State.Update(CurrentFrame, TotalRealSeconds); CurrentFrame.Sort(); } finally { Profiler.Stop(); } }
internal void BeginDraw() { if (game.State == null) { return; } Profiler.Start(); watchdogToken.Ping(); // Sort-of hack to allow the NVIDIA PerfHud to display correctly. GraphicsDevice.DepthStencilState = DepthStencilState.Default; CurrentFrame.IsScreenChanged = (DisplaySize.X != GraphicsDevice.Viewport.Width) || (DisplaySize.Y != GraphicsDevice.Viewport.Height); if (CurrentFrame.IsScreenChanged) { DisplaySize = new Point(GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); InitializeShadowMapLocations(); } game.State.BeginRender(CurrentFrame); }
//[CallOnThread("Sound")] void Sound() { Profiler.Start(); try { WatchdogToken.Ping(); var viewer = Game.RenderProcess.Viewer; if (viewer == null) { return; } OpenAL.alListenerf(OpenAL.AL_GAIN, Simulator.Instance.Paused ? 0 : (float)Game.Settings.SoundVolumePercent / 100f); // Update activity sounds if (viewer.Simulator.SoundNotify != TrainEvent.None) { if (viewer.World.GameSounds != null) { viewer.World.GameSounds.HandleEvent(viewer.Simulator.SoundNotify); } viewer.Simulator.SoundNotify = TrainEvent.None; } // Update all sound in our list //float UpdateInterrupts = 0; StartUpdateTime = viewer.RealTime; int RetryUpdate = 0; int restartIndex = -1; while (RetryUpdate >= 0) { bool updateInterrupted = false; lock (SoundSources) { UpdateCounter++; UpdateCounter %= FULLUPDATECYCLE; var removals = new List <KeyValuePair <object, SoundSourceBase> >(); #if DEBUG_SOURCE_SOURCES SoundSrcBaseCount += SoundSources.Count; #endif foreach (var sources in SoundSources) { restartIndex++; #if DEBUG_SOURCE_SOURCES SoundSrcCount += sources.Value.Count; if (sources.Value.Count < 1) { NullSoundSrcBaseCount++; //Trace.TraceInformation("Null SoundSourceBase {0}", sources.Key.ToString()); } #endif if (restartIndex >= RetryUpdate) { for (int i = 0; i < sources.Value.Count; i++) { if (!sources.Value[i].NeedsFrequentUpdate && UpdateCounter > 0) { continue; } if (!sources.Value[i].Update()) { removals.Add(new KeyValuePair <object, SoundSourceBase>(sources.Key, sources.Value[i])); } } } // Check if Add or Remove Sound Sources is waiting to get in - allow it if so. // Update can be a (relatively) long process. if (ASyncUpdatePending > 0) { updateInterrupted = true; RetryUpdate = restartIndex; //Trace.TraceInformation("Sound Source Updates Interrupted: {0}, Restart Index:{1}", UpdateInterrupts, restartIndex); break; } } if (!updateInterrupted) { RetryUpdate = -1; } #if DEBUG_SOURCE_SOURCES Trace.TraceInformation("SoundProcess: sound source self-removal on " + Thread.CurrentThread.Name); #endif // Remove Sound Sources for train no longer active. This doesn't seem to be necessary - // cleanup when a train is removed seems to do it anyway with hardly any delay. foreach (var removal in removals) { // If either of the key or value no longer exist, we can't remove them - so skip over them. if (SoundSources.ContainsKey(removal.Key) && SoundSources[removal.Key].Contains(removal.Value)) { removal.Value.Uninitialize(); SoundSources[removal.Key].Remove(removal.Value); if (SoundSources[removal.Key].Count == 0) { SoundSources.Remove(removal.Key); } } } } //Update check for activity sounds if (ORTSActSoundSourceList != null) { ORTSActSoundSourceList.Update(); } } //if (UpdateInterrupts > 1) // Trace.TraceInformation("Sound Source Update Interrupted more than once: {0}", UpdateInterrupts); // <CSComment> the block below could provide better sound response but is more demanding in terms of CPU time, especially for slow CPUs /* int resptime = (int)((viewer.RealTime - StartUpdateTime) * 1000); * SleepTime = 50 - resptime; * if (SleepTime < 5) * SleepTime = 5;*/ #if DEBUG_SOURCE_SOURCES SoundTime += (int)((viewer.RealTime - StartUpdateTime) * 1000); if (viewer.RealTime - ConsoleWriteTime >= 15f) { Trace.WriteLine("SoundSourceBases (Null): {0} ({1}), SoundSources: {2}, Time: {3}ms", (int)(SoundSrcBaseCount / UpdateCounter), (int)(NullSoundSrcBaseCount / UpdateCounter), (int)(SoundSrcCount / UpdateCounter), (int)(SoundTime / UpdateCounter)); ConsoleWriteTime = viewer.RealTime; SoundTime = 0; UpdateCounter = 0; SoundSrcCount = 0; SoundSrcBaseCount = 0; NullSoundSrcBaseCount = 0; } #endif } finally { Profiler.Stop(); } }