public LoadingGameState(GameMain game, CancellationToken cancelMarker) : base() { this.Game = game; var taskMgr = this.Game.Services.GetService <TaskManager>(); this._SpriteBatch = new SpriteBatch(this.Game.GraphicsDevice); // Display help text at the start. this._HelpText = this.Game.GetHelpText(); this._HelpText.SpriteBatch = this._SpriteBatch; // Show an animation while loading. this._LoaderAnimation = this.GetLoadingAnimation(); this._LoaderAnimation.SpriteBatch = this._SpriteBatch; var loadTimers = new LoadTimers(); // Create loader thread. // This is executed in the first call to Update(). this._Loader = new Task(() => { var loadStopwatch = System.Diagnostics.Stopwatch.StartNew(); if (cancelMarker.IsCancellationRequested) { cancelMarker.ThrowIfCancellationRequested(); } // Create services. this.Game.Services.AddService(typeof(IConfigurationService), new ConfigurationManager(this.Game)); this.Game.Services.AddService(typeof(IBabyPackageProvider), new XmlFolderBabyPackage(this.Game)); this.Game.Services.AddService(typeof(ISoundService), new SoundServiceContainer(new SoundService(this.Game))); this.Game.Services.AddService(typeof(IApplicationUpdater), new ApplicationUpdater(this.Game)); if (cancelMarker.IsCancellationRequested) { cancelMarker.ThrowIfCancellationRequested(); } // Load content based on those services. var startConfigLoad = loadStopwatch.Elapsed; var configMgr = this.Game.Services.GetService <IConfigurationService>(); bool configExists = configMgr.Exists; configMgr.Load(); if (!configExists) // Ensure the configuration file is saved. { configMgr.Save(configMgr.Current); } loadTimers.ConfigLoadTime = loadStopwatch.Elapsed.Subtract(startConfigLoad); if (cancelMarker.IsCancellationRequested) { cancelMarker.ThrowIfCancellationRequested(); } // Load up the baby package. var startBabyPackageLoad = loadStopwatch.Elapsed; var babyPackpageProvider = this.Game.Services.GetService(typeof(IBabyPackageProvider)) as IBabyPackageProvider; babyPackpageProvider.Load(configMgr.Current.PathToBabyPackage, cancelMarker); loadTimers.BabyPackageLoadTime = loadStopwatch.Elapsed; if (cancelMarker.IsCancellationRequested) { cancelMarker.ThrowIfCancellationRequested(); } // Loading can generate lots of garbage, so do a collection while the loading animation is still on screen. GC.Collect(); loadStopwatch.Stop(); loadTimers.TotalLoadTime = loadStopwatch.Elapsed; }); var loaderComplete = this._Loader.ContinueWith((t) => { // When loading is finished, null it and remove the loading animation. this._Loader = null; // Notify that we've finished loading. if (this.LoadComplete != null) { this._HelpText.SpriteBatch = null; this.LoadComplete(this, new LoadCompleteEventArgs(this._HelpText, loadTimers)); } // Load up a few assemblies from disk to keep the options screen responsive. var optionsLoader = new Task(() => { var optionsScreen = new OptionsMenuDialog(this.Game); var guiManager = new Nuclex.UserInterface.GuiManager(this.Game.Services); this.Game.Services.RemoveService(typeof(Nuclex.UserInterface.IGuiService)); var fileBrowseDialog = new System.Windows.Forms.OpenFileDialog(); }); taskMgr.RegisterTask(optionsLoader); optionsLoader.Start(); }, CancellationToken.None, TaskContinuationOptions.NotOnFaulted, TaskScheduler.FromCurrentSynchronizationContext()); var updaterTask = loaderComplete.ContinueWith(t => { // Spin up the updater (which delays a bit before running). var updater = this.Game.Services.GetService <IApplicationUpdater>(); if (updater.SupportsUpdates) { Thread.Sleep(TimeSpan.FromSeconds(30)); updater.DoCheckAndUpdate(); } }, TaskContinuationOptions.NotOnFaulted); // Register all the tasks with the game to handle exceptions. taskMgr.RegisterTask(this._Loader); taskMgr.RegisterTask(loaderComplete); taskMgr.RegisterTask(updaterTask); }
internal LoadCompleteEventArgs(StringShape helpText, LoadTimers loadTimers) { this.LoadTimers = loadTimers; this.HelpText = helpText; }