public void Start(IGameSettings settings) { _gameCount++; _gameIndex = _gameCount; GameLoop = _resolver.Container.Resolve <IGameLoop>(new TypedParameter(typeof(AGS.API.Size), settings.VirtualResolution)); TypedParameter settingsParameter = new TypedParameter(typeof(IGameSettings), settings); bool isNewWindow = false; if (GameWindow == null) { isNewWindow = true; try { GameWindow = Resolver.Container.Resolve <IGameWindow>(settingsParameter); } catch (Exception ese) { Debug.WriteLine(ese.ToString()); throw; } } _updateThread = new AGSUpdateThread(GameWindow); //using (GameWindow) { try { GameWindow.Load += (sender, e) => { onGameWindowLoaded(settingsParameter, settings); }; if (!isNewWindow) { onGameWindowLoaded(settingsParameter, settings); } GameWindow.Resize += (sender, e) => { Events.OnScreenResize.Invoke(); }; _updateThread.OnThreadStarted += (sender, e) => { _updateMessagePump.SetSyncContext(); }; _updateThread.UpdateFrame += onUpdateFrame; GameWindow.RenderFrame += onRenderFrame; // Run the game at 60 updates per second _updateThread.Run(UPDATE_RATE); if (isNewWindow) { GameWindow.Run(UPDATE_RATE); } } catch (Exception exx) { Debug.WriteLine(exx.ToString()); throw; } } }
public void Start(IGameSettings settings) { GameLoop = _resolver.Container.Resolve <IGameLoop>(new TypedParameter(typeof(AGS.API.Size), settings.VirtualResolution)); TypedParameter settingsParameter = new TypedParameter(typeof(IGameSettings), settings); try { GameWindow = Resolver.Container.Resolve <IGameWindow>(settingsParameter); } catch (Exception ese) { Debug.WriteLine(ese.ToString()); throw; } _updateThread = new AGSUpdateThread(GameWindow); //using (GameWindow) { try { TypedParameter gameWindowParameter = new TypedParameter(typeof(IGameWindow), GameWindow); GameWindow.Load += (sender, e) => { Settings = Resolver.Container.Resolve <IRuntimeSettings>(settingsParameter, gameWindowParameter); _graphics.ClearColor(0f, 0f, 0f, 1f); _graphics.Init(); _glUtils.GenBuffers(); Factory = Resolver.Container.Resolve <IGameFactory>(); TypedParameter sizeParameter = new TypedParameter(typeof(AGS.API.Size), Settings.VirtualResolution); Input = _resolver.Container.Resolve <IInput>(gameWindowParameter, sizeParameter); TypedParameter inputParamater = new TypedParameter(typeof(IInput), Input); TypedParameter gameParameter = new TypedParameter(typeof(IGame), this); RenderLoop = _resolver.Container.Resolve <IRendererLoop>(inputParamater, gameParameter); updateResolver(); HitTest = _resolver.Container.Resolve <IHitTest>(); AudioSettings = _resolver.Container.Resolve <IAudioSettings>(); SaveLoad = _resolver.Container.Resolve <ISaveLoad>(); _glUtils.AdjustResolution(settings.VirtualResolution.Width, settings.VirtualResolution.Height); Events.OnLoad.Invoke(); }; GameWindow.Resize += (sender, e) => { Events.OnScreenResize.Invoke(); }; _updateThread.OnThreadStarted += (sender, e) => { _updateMessagePump.SetSyncContext(); }; _updateThread.UpdateFrame += async(sender, e) => { if (_updateFrameRetries > 3) { return; } try { _updateMessagePump.PumpMessages(); if (State.Paused) { return; } adjustSpeed(); await GameLoop.UpdateAsync(); //Invoking repeatedly execute asynchronously, as if one subscriber is waiting on another subscriber the event will //never get to it (for example: calling ChangeRoom from within RepeatedlyExecute calls StopWalking which //waits for the walk to stop, only the walk also happens on RepeatedlyExecute and we'll hang. //Since we're running asynchronously, the next UpdateFrame will call RepeatedlyExecute for the walk cycle to stop itself and we're good. ///The downside of this approach is that we need to look out for re-entrancy issues. await Events.OnRepeatedlyExecute.InvokeAsync(); } catch (Exception ex) { _updateFrameRetries++; Debug.WriteLine(ex.ToString()); throw ex; } }; GameWindow.RenderFrame += (sender, e) => { if (RenderLoop == null || _renderFrameRetries > 3) { return; } try { _renderMessagePump.PumpMessages(); // render graphics _graphics.ClearScreen(); Events.OnBeforeRender.Invoke(); if (RenderLoop.Tick()) { GameWindow.SwapBuffers(); } if (Repeat.OnceOnly("SetFirstRestart")) { SaveLoad.SetRestartPoint(); } } catch (Exception ex) { _renderFrameRetries++; Debug.WriteLine("Exception when rendering:"); Debug.WriteLine(ex.ToString()); throw; } }; // Run the game at 60 updates per second _updateThread.Run(UPDATE_RATE); GameWindow.Run(UPDATE_RATE); } catch (Exception exx) { Debug.WriteLine(exx.ToString()); throw; } } }