// Initialize with stuff // TODO: what to setup here? Networked game or not, loggers, properties etc.. public void Setup(StateManagerSetup setup) { if (currentState != null && currentState.IsUpdating) { // can't stop at the middle of an update delayedSetup = setup; } else { LateSetup(setup); } }
// Update loop, including logics and visualization update // It also automatically corrects the state when older input is detected public void Update(float deltaTime) { if (currentState == null) { // Not yet initialized return; } // Flush network events if (IsNetworked) { NetworkGame.Instance.FlushEvents(); } if (!IsPaused) { // rewind the game state due to uncatched old events, if any RewindIfNecessary(); // logics update cycles UpdateLogics(deltaTime); } // If the game was requested to restart during the previous update, do it now if (delayedSetup != null) { LateSetup(delayedSetup); delayedSetup = null; return; } if (currentState.Keyframe > 0) { // temporarily set back to current frame // because views may want to access (last) current keyframe currentState.Keyframe--; // visual update UpdateVisuals(deltaTime); // In the end we move to next frame again currentState.Keyframe++; } else { // no updates took place yet. Still update visuals (perhaps a loading screen going on?) UpdateVisuals(deltaTime); } }
private void LateSetup(StateManagerSetup setup) { // TODO: init state with proper seed, either random or agreed with network if (this.currentState != null) { currentState.Destroy(); } DefaultVCFactories.RegisterFactories(); this.currentState = new InternalState(setup.initialModel, 0); UpdateRate = setup.updateRate; this.latestUpdateDeltatimeRemainder = 0; // TODO: only create this if necessary, else set it to null this.statesBuffer = new StatesBufferBySerializing(); //this.statesBuffer = new StatesBufferByCloning(); this.eventsBuffer = new EventsBuffer(); saveStateFrequency = setup.saveStateFrequency; latestKeyframeBuffered = 0; // buffer state zero imediately statesBuffer.SetState(currentState); // TODO: add listeners and pause only if on networked game IsNetworked = setup.isNetworked; if (IsNetworked) { NetworkGame.Instance.onEventsAddedEvent += OnEventsAdded; NetworkGame.Instance.onPauseEvent += OnPause; NetworkGame.Instance.onResumeEvent += OnResume; NetworkGame.Instance.stateCorrectionEvent += OnStateCorrection; IsPaused = true; // wait for server order to resume } else { // No need to wait for resume (synch) IsPaused = false; } }