/** Run the actual main loop. */ void MainLoop::run() { IrrlichtDevice* device = irr_driver->getDevice(); m_curr_time = device->getTimer()->getRealTime(); while(!m_abort) { PROFILER_PUSH_CPU_MARKER("Main loop", 0xFF, 0x00, 0xF7); m_prev_time = m_curr_time; float dt = getLimitedDt(); network_manager->update(dt); if (World::getWorld()) // race is active if world exists { // Busy wait if race_manager is active (i.e. creating of world is done) // till all clients have reached this state. if (network_manager->getState()==NetworkManager::NS_READY_SET_GO_BARRIER) continue; updateRace(dt); } // if race is active // We need to check again because update_race may have requested // the main loop to abort; and it's not a good idea to continue // since the GUI engine is no more to be called then. // Also only do music, input, and graphics update if graphics are // enabled. if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music manager update", 0x7F, 0x00, 0x00); music_manager->update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Input manager update", 0x00, 0x7F, 0x00); input_manager->update(dt); PROFILER_POP_CPU_MARKER(); #ifdef ENABLE_WIIUSE wiimote_manager->update(); #endif PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F); irr_driver->update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_SYNC_FRAME(); } PROFILER_POP_CPU_MARKER(); } // while !m_exit } // run
/** Run the actual main loop. * The sequnce in which various parts of STK are updated is: * - Determine next time step size (`getLimitedDt`). This takes maximum fps * into account (i.e. sleep if the fps would be too high), and will actually * slow down the in-game clock if the fps are too low (if more than 3/60 of * a second have passed, more than 3 physics time steps would be needed, * and physics do at most 3 time steps). * - if a race is taking place (i.e. not only a menu being shown), call * `updateRace()`, which is a thin wrapper around a call to * `World::updateWorld()`: * - Update history manager (which will either set the kart position and/or * controls when replaying, or store the current info for a replay). * This is mostly for debugging only (though available even in release * mode). * - Updates Replays - either storing data when not replaying, or * updating kart positions/control when replaying). * - Calls `WorldStatus::update()`, which updates the race state (e.g. * go from 'ready' to 'set' etc), and clock. * - Updates the physics (`Physics::update()`). This will simulate all * physical objects for the specified time with bullet. * - Updates all karts (`Kart::update()`). Obviously the update function * does a lot more than what is described here, this is only supposed to * be a _very_ high level overview: * - Updates its rewinder (to store potentially changed controls * as events) in `KartRewinder::update()`. * - Calls `Moveable::update()`, which takes the new position from * the physics and saves it (and computes dependent values, like * heading, local velocity). * - Updates its controller. This is either: * - an AI using `SkiddingController::update()` (which then will * compute the new controls), or * - a player controller using `PlayerController::update()`, which will * handle smooth steering (in case of digital input devices steering * is adjusted a bit over time to avoid an instant change from all * left to all right). Input events will be handled when updating * the irrlicht driver later at the end of the main loop. * - Updates kart animation (like rescue, ...) if one is shown atm. * - Update attachments. * - update physics, i.e. taking the current steering and updating * the bullet raycast vehicle with that data. The settings are actually * only used in the next frame when the physics are updated. * - Updates all cameras via `Camera::update()`. The camera position and * rotation is adjusted according to the position etc of the kart (and * special circumstances like rescue, falling). * - Updates all projectiles using the projectile manager. Some of the * projectiles are mostly handled by the physics (e.g. a cake will mainly * check if it's out of bounds), others (like basket ball) do all * their aiming and movement here. * - Updates the rewind manager to store rewind states. * - Updates the music manager. * - Updates the input manager (which only updates internal time, actual * input handling follows late) * - Updates the wiimote manager. This will read the data of all wiimotes * and feed the corresponding events to the irrlicht event system. * - Updates the STK internal gui engine. This updates all widgets, and * e.g. takes care of the rotation of the karts in the KartSelection * screen using the ModelViewWidget. * - Updates STK's irrlicht driver `IrrDriver::update()`: * - Calls Irrlicht's `beginScene()` . * - Renders the scene (several times with different viewport if * split screen is being used) * - Calls `GUIEngine::render()`, which renders all widgets with the * help of Irrlicht's GUIEnvironment (`drawAll()`). This will also * handle all events, i.e. all input is now handled (e.g. steering, * firing etc are all set in the corresponding karts depending on * user input). * - Calls Irrlicht's `endScene()` */ void MainLoop::run() { IrrlichtDevice* device = irr_driver->getDevice(); m_curr_time = device->getTimer()->getRealTime(); while(!m_abort) { PROFILER_PUSH_CPU_MARKER("Main loop", 0xFF, 0x00, 0xF7); m_prev_time = m_curr_time; float dt = getLimitedDt(); if (!m_abort && !ProfileWorld::isNoGraphics()) { // Render the previous frame, and also handle all user input. PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F); irr_driver->update(dt); PROFILER_POP_CPU_MARKER(); } if (World::getWorld()) // race is active if world exists { PROFILER_PUSH_CPU_MARKER("Update race", 0, 255, 255); updateRace(dt); PROFILER_POP_CPU_MARKER(); } // if race is active // We need to check again because update_race may have requested // the main loop to abort; and it's not a good idea to continue // since the GUI engine is no more to be called then. // Also only do music, input, and graphics update if graphics are // enabled. if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); input_manager->update(dt); #ifdef ENABLE_WIIUSE wiimote_manager->update(); #endif GUIEngine::update(dt); PROFILER_POP_CPU_MARKER(); // Update sfx and music after graphics, so that graphics code // can use as many threads as possible without interfering // with audio PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); SFXManager::get()->update(); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Protocol manager update", 0x7F, 0x00, 0x7F); if (STKHost::existHost()) { if (STKHost::get()->requestedShutdown()) STKHost::get()->shutdown(); else ProtocolManager::getInstance()->update(dt); } PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F); Online::RequestManager::get()->update(dt); PROFILER_POP_CPU_MARKER(); } else if (!m_abort && ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Protocol manager update", 0x7F, 0x00, 0x7F); if(NetworkConfig::get()->isNetworking()) ProtocolManager::getInstance()->update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F); Online::RequestManager::get()->update(dt); PROFILER_POP_CPU_MARKER(); } if (World::getWorld() ) { World::getWorld()->updateTime(dt); } PROFILER_POP_CPU_MARKER(); PROFILER_SYNC_FRAME(); } // while !m_abort } // run
/** Run the actual main loop. */ void MainLoop::run() { IrrlichtDevice* device = irr_driver->getDevice(); m_curr_time = device->getTimer()->getRealTime(); while(!m_abort) { PROFILER_PUSH_CPU_MARKER("Main loop", 0xFF, 0x00, 0xF7); m_prev_time = m_curr_time; float dt = getLimitedDt(); if (World::getWorld()) // race is active if world exists { PROFILER_PUSH_CPU_MARKER("Update race", 0, 255, 255); updateRace(dt); PROFILER_POP_CPU_MARKER(); } // if race is active // We need to check again because update_race may have requested // the main loop to abort; and it's not a good idea to continue // since the GUI engine is no more to be called then. // Also only do music, input, and graphics update if graphics are // enabled. if (!m_abort && !ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Music/input/GUI", 0x7F, 0x00, 0x00); music_manager->update(dt); input_manager->update(dt); #ifdef ENABLE_WIIUSE wiimote_manager->update(); #endif GUIEngine::update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("IrrDriver update", 0x00, 0x00, 0x7F); irr_driver->update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Protocol manager update", 0x7F, 0x00, 0x7F); ProtocolManager::getInstance()->update(); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F); Online::RequestManager::get()->update(dt); PROFILER_POP_CPU_MARKER(); PROFILER_SYNC_FRAME(); } else if (!m_abort && ProfileWorld::isNoGraphics()) { PROFILER_PUSH_CPU_MARKER("Protocol manager update", 0x7F, 0x00, 0x7F); ProtocolManager::getInstance()->update(); PROFILER_POP_CPU_MARKER(); PROFILER_PUSH_CPU_MARKER("Database polling update", 0x00, 0x7F, 0x7F); Online::RequestManager::get()->update(dt); PROFILER_POP_CPU_MARKER(); } PROFILER_SYNC_FRAME(); PROFILER_POP_CPU_MARKER(); } // while !m_exit } // run