Allow world to have 2 process instances

Also add specific process type handling to world
This commit is contained in:
Benau 2020-02-28 09:43:25 +08:00
parent 1958e5940c
commit 6b08a873a2
6 changed files with 125 additions and 59 deletions

View File

@ -1746,7 +1746,7 @@ void clearGlobalVariables()
#ifdef ENABLE_WIIUSE #ifdef ENABLE_WIIUSE
wiimote_manager = NULL; wiimote_manager = NULL;
#endif #endif
World::setWorld(NULL); World::clear();
GUIEngine::resetGlobalVariables(); GUIEngine::resetGlobalVariables();
} // clearGlobalVariables } // clearGlobalVariables

View File

@ -87,7 +87,7 @@
#include <stdexcept> #include <stdexcept>
World* World::m_world = NULL; World* World::m_world[PT_COUNT];
/** The main world class is used to handle the track and the karts. /** The main world class is used to handle the track and the karts.
* The end of the race is detected in two phases: first the (abstract) * The end of the race is detected in two phases: first the (abstract)
@ -176,17 +176,20 @@ void World::init()
main_loop->renderGUI(1100); main_loop->renderGUI(1100);
// Grab the track file // Grab the track file
Track *track = track_manager->getTrack(RaceManager::get()->getTrackName()); Track *track = track_manager->getTrack(RaceManager::get()->getTrackName());
Scripting::ScriptEngine::getInstance<Scripting::ScriptEngine>(); if (m_process_type == PT_MAIN)
if(!track)
{ {
std::ostringstream msg; Scripting::ScriptEngine::getInstance<Scripting::ScriptEngine>();
msg << "Track '" << RaceManager::get()->getTrackName() if(!track)
<< "' not found.\n"; {
throw std::runtime_error(msg.str()); std::ostringstream msg;
} msg << "Track '" << RaceManager::get()->getTrackName()
<< "' not found.\n";
throw std::runtime_error(msg.str());
}
std::string script_path = track->getTrackFile("scripting.as"); std::string script_path = track->getTrackFile("scripting.as");
Scripting::ScriptEngine::getInstance()->loadScript(script_path, true); Scripting::ScriptEngine::getInstance()->loadScript(script_path, true);
}
main_loop->renderGUI(1200); main_loop->renderGUI(1200);
// Create the physics // Create the physics
Physics::create(); Physics::create();
@ -254,9 +257,10 @@ void World::init()
if (m_race_gui) if (m_race_gui)
m_race_gui->init(); m_race_gui->init();
powerup_manager->computeWeightsForRace(RaceManager::get()->getNumberOfKarts()); if (m_process_type == PT_MAIN)
powerup_manager->computeWeightsForRace(RaceManager::get()->getNumberOfKarts());
main_loop->renderGUI(7200); main_loop->renderGUI(7200);
if (UserConfigParams::m_particles_effects > 1) if (m_process_type == PT_MAIN && UserConfigParams::m_particles_effects > 1)
{ {
Weather::getInstance<Weather>(); // create Weather instance Weather::getInstance<Weather>(); // create Weather instance
} }
@ -348,7 +352,7 @@ void World::reset(bool restart)
for ( KartList::iterator i = m_karts.begin(); i != m_karts.end() ; ++i ) for ( KartList::iterator i = m_karts.begin(); i != m_karts.end() ; ++i )
{ {
(*i)->reset(); (*i)->reset();
if ((*i)->getController()->canGetAchievements()) if (m_process_type == PT_MAIN && (*i)->getController()->canGetAchievements())
{ {
updateAchievementModeCounters(true /*start*/); updateAchievementModeCounters(true /*start*/);
@ -408,7 +412,8 @@ void World::reset(bool restart)
} }
// Reset all data structures that depend on number of karts. // Reset all data structures that depend on number of karts.
irr_driver->reset(); if (m_process_type == PT_MAIN)
irr_driver->reset();
m_unfair_team = false; m_unfair_team = false;
} // reset } // reset
@ -581,10 +586,13 @@ Controller* World::loadAIController(AbstractKart* kart)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
World::~World() World::~World()
{ {
material_manager->unloadAllTextures(); if (m_process_type == PT_MAIN)
material_manager->unloadAllTextures();
RewindManager::destroy(); RewindManager::destroy();
irr_driver->onUnloadWorld(); if (m_process_type == PT_MAIN)
irr_driver->onUnloadWorld();
ProjectileManager::get()->cleanup(); ProjectileManager::get()->cleanup();
@ -607,8 +615,9 @@ World::~World()
// gui and this must be deleted. // gui and this must be deleted.
delete m_race_gui; delete m_race_gui;
} }
Weather::kill(); if (m_process_type == PT_MAIN)
Weather::kill();
m_karts.clear(); m_karts.clear();
if(RaceManager::get()->hasGhostKarts() || RaceManager::get()->isRecordingRace()) if(RaceManager::get()->hasGhostKarts() || RaceManager::get()->isRecordingRace())
@ -636,11 +645,13 @@ World::~World()
// but kill handles this correctly. // but kill handles this correctly.
Physics::destroy(); Physics::destroy();
Scripting::ScriptEngine::kill(); if (m_process_type == PT_MAIN)
Scripting::ScriptEngine::kill();
m_world = NULL; m_world[m_process_type] = NULL;
irr_driver->getSceneManager()->clear(); if (m_process_type == PT_MAIN)
irr_driver->getSceneManager()->clear();
#ifdef DEBUG #ifdef DEBUG
m_magic_number = 0xDEADBEEF; m_magic_number = 0xDEADBEEF;
@ -719,9 +730,11 @@ void World::terminateRace()
updateHighscores(&best_highscore_rank); updateHighscores(&best_highscore_rank);
} }
updateAchievementDataEndRace(); if (m_process_type == PT_MAIN)
{
PlayerManager::getCurrentPlayer()->raceFinished(); updateAchievementDataEndRace();
PlayerManager::getCurrentPlayer()->raceFinished();
}
if (m_race_gui) m_race_gui->clearAllMessages(); if (m_race_gui) m_race_gui->clearAllMessages();
// we can't delete the race gui here, since it is needed in case of // we can't delete the race gui here, since it is needed in case of
@ -839,9 +852,12 @@ void World::resetAllKarts()
} }
// Initialise the cameras, now that the correct kart positions are set // Initialise the cameras, now that the correct kart positions are set
for(unsigned int i=0; i<Camera::getNumCameras(); i++) if (!GUIEngine::isNoGraphics())
{ {
Camera::getCamera(i)->setInitialTransform(); for(unsigned int i=0; i<Camera::getNumCameras(); i++)
{
Camera::getCamera(i)->setInitialTransform();
}
} }
} // resetAllKarts } // resetAllKarts

View File

@ -25,6 +25,7 @@
* battle, etc.) * battle, etc.)
*/ */
#include <cstring>
#include <limits> #include <limits>
#include <map> #include <map>
#include <memory> #include <memory>
@ -37,6 +38,7 @@
#include "states_screens/race_gui_base.hpp" #include "states_screens/race_gui_base.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "utils/random_generator.hpp" #include "utils/random_generator.hpp"
#include "utils/stk_process.hpp"
#include "LinearMath/btTransform.h" #include "LinearMath/btTransform.h"
@ -88,7 +90,7 @@ public:
typedef std::vector<std::shared_ptr<AbstractKart> > KartList; typedef std::vector<std::shared_ptr<AbstractKart> > KartList;
private: private:
/** A pointer to the global world object for a race. */ /** A pointer to the global world object for a race. */
static World *m_world; static World *m_world[PT_COUNT];
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setAITeam(); void setAITeam();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -208,16 +210,31 @@ public:
// ================================= // =================================
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a pointer to the (singleton) world object. */ /** Returns a pointer to the (singleton) world object. */
static World* getWorld() { return m_world; } static World* getWorld()
{
ProcessType type = STKProcess::getType();
return m_world[type];
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Delete the )singleton) world object, if it exists, and sets the /** Delete the )singleton) world object, if it exists, and sets the
* singleton pointer to NULL. It's harmless to call this if the world * singleton pointer to NULL. It's harmless to call this if the world
* has been deleted already. */ * has been deleted already. */
static void deleteWorld() { delete m_world; m_world = NULL; } static void deleteWorld()
{
ProcessType type = STKProcess::getType();
delete m_world[type];
m_world[type] = NULL;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Sets the pointer to the world object. This is only used by /** Sets the pointer to the world object. This is only used by
* the race_manager.*/ * the race_manager.*/
static void setWorld(World *world) {m_world = world; } static void setWorld(World *world)
{
ProcessType type = STKProcess::getType();
m_world[type] = world;
}
// ------------------------------------------------------------------------
static void clear() { memset(m_world, 0, sizeof(m_world)); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Pure virtual functions // Pure virtual functions

View File

@ -33,13 +33,15 @@
#include "network/rewind_manager.hpp" #include "network/rewind_manager.hpp"
#include "network/race_event_manager.hpp" #include "network/race_event_manager.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "utils/stk_process.hpp"
#include <irrlicht.h> #include <irrlicht.h>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
WorldStatus::WorldStatus() WorldStatus::WorldStatus() : m_process_type(STKProcess::getType())
{ {
main_loop->setFrameBeforeLoadingWorld(); if (m_process_type == PT_MAIN)
main_loop->setFrameBeforeLoadingWorld();
m_clock_mode = CLOCK_CHRONO; m_clock_mode = CLOCK_CHRONO;
m_phase = SETUP_PHASE; m_phase = SETUP_PHASE;
@ -55,10 +57,14 @@ WorldStatus::WorldStatus()
m_play_ready_set_go_sounds = true; m_play_ready_set_go_sounds = true;
m_play_racestart_sounds = true; m_play_racestart_sounds = true;
m_live_join_world = false; m_live_join_world = false;
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) if (m_process_type == PT_MAIN)
device->getTimer()->start(); {
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped())
device->getTimer()->start();
}
} // WorldStatus } // WorldStatus
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -95,13 +101,16 @@ void WorldStatus::reset(bool restart)
// Just in case that the game is reset during the intro phase // Just in case that the game is reset during the intro phase
m_track_intro_sound->stop(); m_track_intro_sound->stop();
IrrlichtDevice *device = irr_driver->getDevice(); if (m_process_type == PT_MAIN)
{
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) if (device->getTimer()->isStopped())
device->getTimer()->start(); device->getTimer()->start();
// Set the right music // Set the right music
Track::getCurrentTrack()->startMusic(); Track::getCurrentTrack()->startMusic();
}
} // reset } // reset
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -112,10 +121,14 @@ WorldStatus::~WorldStatus()
m_prestart_sound->deleteSFX(); m_prestart_sound->deleteSFX();
m_start_sound->deleteSFX(); m_start_sound->deleteSFX();
m_track_intro_sound->deleteSFX(); m_track_intro_sound->deleteSFX();
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped()) if (m_process_type == PT_MAIN)
device->getTimer()->start(); {
IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped())
device->getTimer()->start();
}
} // ~WorldStatus } // ~WorldStatus
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -208,7 +221,7 @@ void WorldStatus::updateTime(int ticks)
m_track_intro_sound->play(); m_track_intro_sound->play();
} }
if (Weather::getInstance()) if (m_process_type == PT_MAIN && Weather::getInstance())
{ {
Weather::getInstance()->playSound(); Weather::getInstance()->playSound();
} }
@ -438,7 +451,7 @@ void WorldStatus::updateTime(int ticks)
switch (m_clock_mode) switch (m_clock_mode)
{ {
case CLOCK_CHRONO: case CLOCK_CHRONO:
if (!device->getTimer()->isStopped()) if (m_process_type == PT_CHILD || !device->getTimer()->isStopped())
{ {
m_time_ticks++; m_time_ticks++;
m_time = stk_config->ticks2Time(m_time_ticks); m_time = stk_config->ticks2Time(m_time_ticks);
@ -452,12 +465,12 @@ void WorldStatus::updateTime(int ticks)
m_time_ticks = 0; m_time_ticks = 0;
m_time = 0.0f; m_time = 0.0f;
// For rescue animation playing (if any) in result screen // For rescue animation playing (if any) in result screen
if (!device->getTimer()->isStopped()) if (m_process_type == PT_CHILD || !device->getTimer()->isStopped())
m_count_up_ticks++; m_count_up_ticks++;
break; break;
} }
if (!device->getTimer()->isStopped()) if (m_process_type == PT_CHILD || !device->getTimer()->isStopped())
{ {
m_time_ticks--; m_time_ticks--;
m_time = stk_config->ticks2Time(m_time_ticks); m_time = stk_config->ticks2Time(m_time_ticks);
@ -524,6 +537,10 @@ void WorldStatus::pause(Phase phase)
m_previous_phase = m_phase; m_previous_phase = m_phase;
m_phase = phase; m_phase = phase;
if (m_process_type != PT_MAIN)
return;
IrrlichtDevice *device = irr_driver->getDevice(); IrrlichtDevice *device = irr_driver->getDevice();
if (!device->getTimer()->isStopped() && if (!device->getTimer()->isStopped() &&
@ -540,6 +557,10 @@ void WorldStatus::unpause()
// Set m_previous_phase so that we can use an assert // Set m_previous_phase so that we can use an assert
// in pause to detect incorrect pause/unpause sequences. // in pause to detect incorrect pause/unpause sequences.
m_previous_phase = UNDEFINED_PHASE; m_previous_phase = UNDEFINED_PHASE;
if (m_process_type != PT_MAIN)
return;
IrrlichtDevice *device = irr_driver->getDevice(); IrrlichtDevice *device = irr_driver->getDevice();
if (device->getTimer()->isStopped() && if (device->getTimer()->isStopped() &&

View File

@ -21,6 +21,7 @@
#include "utils/cpp2011.hpp" #include "utils/cpp2011.hpp"
#include <atomic> #include <atomic>
enum ProcessType : unsigned int;
class SFXBase; class SFXBase;
/** /**
@ -98,6 +99,9 @@ protected:
/** If the start race should be played, disabled in cutscenes. */ /** If the start race should be played, disabled in cutscenes. */
bool m_play_racestart_sounds; bool m_play_racestart_sounds;
/** Process type of this world (main or child). */
const ProcessType m_process_type;
private: private:
/** Sound to play at the beginning of a race, during which a /** Sound to play at the beginning of a race, during which a
* a camera intro of the track can be shown. */ * a camera intro of the track can be shown. */

View File

@ -507,17 +507,20 @@ void RaceManager::startNew(bool from_overworld)
*/ */
void RaceManager::startNextRace() void RaceManager::startNextRace()
{ {
ProcessType type = STKProcess::getType();
main_loop->renderGUI(0); main_loop->renderGUI(0);
// Uncomment to debug audio leaks // Uncomment to debug audio leaks
// sfx_manager->dump(); // sfx_manager->dump();
IrrlichtDevice* device = irr_driver->getDevice(); if (type == PT_MAIN)
GUIEngine::clearLoadingTips(); {
GUIEngine::renderLoading(true/*clearIcons*/, false/*launching*/, false/*update_tips*/); IrrlichtDevice* device = irr_driver->getDevice();
device->getVideoDriver()->endScene(); GUIEngine::clearLoadingTips();
device->getVideoDriver()->beginScene(true, true, GUIEngine::renderLoading(true/*clearIcons*/, false/*launching*/, false/*update_tips*/);
video::SColor(255,100,101,140)); device->getVideoDriver()->endScene();
device->getVideoDriver()->beginScene(true, true,
video::SColor(255,100,101,140));
}
m_num_finished_karts = 0; m_num_finished_karts = 0;
m_num_finished_players = 0; m_num_finished_players = 0;
@ -647,7 +650,8 @@ void RaceManager::startNextRace()
} }
} }
irr_driver->onLoadWorld(); if (type == PT_MAIN)
irr_driver->onLoadWorld();
main_loop->renderGUI(8100); main_loop->renderGUI(8100);
// Save the current score and set last time to zero. This is necessary // Save the current score and set last time to zero. This is necessary
@ -670,7 +674,8 @@ void RaceManager::startNextRace()
*/ */
void RaceManager::next() void RaceManager::next()
{ {
PropertyAnimator::get()->clear(); if (STKProcess::getType() == PT_MAIN)
PropertyAnimator::get()->clear();
World::deleteWorld(); World::deleteWorld();
m_num_finished_karts = 0; m_num_finished_karts = 0;
m_num_finished_players = 0; m_num_finished_players = 0;
@ -835,6 +840,7 @@ void RaceManager::exitRace(bool delete_world)
// Only display the grand prix result screen if all tracks // Only display the grand prix result screen if all tracks
// were finished, and not when a race is aborted. // were finished, and not when a race is aborted.
MessageQueue::discardStatic(); MessageQueue::discardStatic();
ProcessType type = STKProcess::getType();
if ( m_major_mode==MAJOR_MODE_GRAND_PRIX && if ( m_major_mode==MAJOR_MODE_GRAND_PRIX &&
m_track_number==(int)m_tracks.size() ) m_track_number==(int)m_tracks.size() )
@ -890,7 +896,8 @@ void RaceManager::exitRace(bool delete_world)
if (delete_world) if (delete_world)
{ {
PropertyAnimator::get()->clear(); if (type == PT_MAIN)
PropertyAnimator::get()->clear();
World::deleteWorld(); World::deleteWorld();
} }
delete_world = false; delete_world = false;
@ -933,7 +940,8 @@ void RaceManager::exitRace(bool delete_world)
if (delete_world) if (delete_world)
{ {
PropertyAnimator::get()->clear(); if (type == PT_MAIN)
PropertyAnimator::get()->clear();
World::deleteWorld(); World::deleteWorld();
} }