Made World derive from 'Clock' (now 'TimedRace') simplifying a lot of things, especially the race end process

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@2323 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria 2008-10-04 17:32:40 +00:00
parent 695255d9b6
commit 0c945d61d3
16 changed files with 95 additions and 121 deletions

View File

@ -10,7 +10,7 @@
**
***************************************************************************************************/
// Credits: The Clock class was inspired by the Timer classes in
// Credits: The TimedRace class was inspired by the Timer classes in
// Ogre (www.ogre3d.org).
#include "LinearMath/btQuickprof.h"

View File

@ -7,7 +7,7 @@
**
***************************************************************************************************/
// Credits: The Clock class was inspired by the Timer classes in
// Credits: The TimedRace class was inspired by the Timer classes in
// Ogre (www.ogre3d.org).
#ifndef QUICK_PROF_H
@ -153,7 +153,7 @@ public:
}
/// Returns the time in us since the last call to reset or since
/// the Clock was created.
/// the TimedRace was created.
unsigned long int getTimeMicroseconds()
{
#ifdef USE_WINDOWS_TIMERS

View File

@ -161,7 +161,7 @@ void Camera::update (float dt)
kart_hpr.setRoll(0.0f);
// Only adjust the pitch if it's not the race start, otherwise
// the camera will change pitch during ready-set-go.
if(RaceManager::getWorld()->getClock().isRacePhase())
if(RaceManager::getWorld()->isRacePhase())
{
// If the terrain pitch is 'significantly' different from the camera angle,
// start adjusting the camera. This helps with steep declines, where

View File

@ -915,7 +915,7 @@ void RaceGUI::drawStatusText(const float dt)
// The penalty message needs to be displayed for up to one second
// after the start of the race, otherwise it disappears if
// "Go" is displayed and the race starts
if(RaceManager::getWorld()->getClock().isStartPhase() || RaceManager::getWorld()->getTime()<1.0f)
if(RaceManager::getWorld()->isStartPhase() || RaceManager::getWorld()->getTime()<1.0f)
{
for(unsigned int i=0; i<race_manager->getNumLocalPlayers(); i++)
{
@ -936,7 +936,7 @@ void RaceGUI::drawStatusText(const float dt)
if(race_manager->getNumLocalPlayers() >= 3)
split_screen_ratio_x = 0.5;
if ( RaceManager::getWorld()->getClock().isRacePhase() )
if ( RaceManager::getWorld()->isRacePhase() )
{
KartIconDisplayInfo* info = RaceManager::getWorld()->getKartsDisplayInfo(this);

View File

@ -117,7 +117,7 @@ void MainLoop::run()
// Client: send current controls to server
// But don't do this if the race is in finish phase (otherwise
// messages can be mixed up in the race manager)
if(!race_manager->getWorld()->getClock().isFinishPhase())
if(!race_manager->getWorld()->isFinishPhase())
network_manager->sendUpdates();
music_on = false;
if(user_config->m_profile) dt=1.0f/60.0f;
@ -129,7 +129,7 @@ void MainLoop::run()
// race results are displayed (i.e. game is in finish phase)
// messages must be handled by the normal update of the network
// manager
if(!race_manager->getWorld()->getClock().isFinishPhase())
if(!race_manager->getWorld()->isFinishPhase())
network_manager->receiveUpdates();
if ( RaceManager::getWorld()->getPhase() != LIMBO_PHASE)

View File

@ -20,14 +20,15 @@
#include "audio/sound_manager.hpp"
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "network/network_manager.hpp"
#include "network/race_state.hpp"
//-----------------------------------------------------------------------------
Clock::Clock()
TimedRace::TimedRace()
{
m_mode = CHRONO;
m_time = 0.0f;
m_auxiliary_timer = 0.0f;
m_listener = NULL;
m_phase = SETUP_PHASE;
m_previous_phase = SETUP_PHASE; // initialise it just in case
@ -39,7 +40,7 @@ Clock::Clock()
m_start_sound = sfx_manager->newSFX(SFXManager::SOUND_START);
}
//-----------------------------------------------------------------------------
void Clock::reset()
void TimedRace::reset()
{
m_time = 0.0f;
m_auxiliary_timer = 0.0f;
@ -47,19 +48,19 @@ void Clock::reset()
m_previous_phase = SETUP_PHASE;
}
//-----------------------------------------------------------------------------
Clock::~Clock()
TimedRace::~TimedRace()
{
sfx_manager->deleteSFX(m_prestart_sound);
sfx_manager->deleteSFX(m_start_sound);
}
//-----------------------------------------------------------------------------
void Clock::setMode(const ClockType mode, const float initial_time)
void TimedRace::setMode(const ClockType mode, const float initial_time)
{
m_mode = mode;
m_time = initial_time;
}
//-----------------------------------------------------------------------------
void Clock::raceOver(const bool delay)
void TimedRace::enterRaceOverState(const bool delay)
{
if(m_phase == DELAY_FINISH_PHASE || m_phase == FINISH_PHASE) return; // we already know
@ -70,9 +71,12 @@ void Clock::raceOver(const bool delay)
}
else
m_phase = FINISH_PHASE;
if(network_manager->getMode()==NetworkManager::NW_SERVER)
network_manager->sendRaceResults();
}
//-----------------------------------------------------------------------------
void Clock::update(const float dt)
void TimedRace::update(const float dt)
{
switch(m_phase)
{
@ -102,8 +106,8 @@ void Clock::update(const float dt)
m_start_sound->play();
assert(m_listener != NULL);
m_listener -> onGo();
// event
onGo();
}
m_auxiliary_timer += dt;
return;
@ -123,7 +127,8 @@ void Clock::update(const float dt)
break;
}
case FINISH_PHASE:
m_listener->onTerminate();
// event
terminateRace();
return;
}
@ -137,8 +142,8 @@ void Clock::update(const float dt)
if(m_time <= 0.0)
{
assert(m_listener != NULL);
m_listener -> countdownReachedZero();
// event
countdownReachedZero();
}
break;
@ -146,23 +151,18 @@ void Clock::update(const float dt)
}
}
//-----------------------------------------------------------------------------
void Clock::setTime(const float time)
void TimedRace::setTime(const float time)
{
m_time = time;
}
//-----------------------------------------------------------------------------
void Clock::registerEventListener(ClockListener* listener)
{
m_listener = listener;
}
//-----------------------------------------------------------------------------
void Clock::pause()
void TimedRace::pause()
{
m_previous_phase = m_phase;
m_phase = LIMBO_PHASE;
}
//-----------------------------------------------------------------------------
void Clock::unpause()
void TimedRace::unpause()
{
m_phase = m_previous_phase;
}

View File

@ -52,34 +52,9 @@ enum Phase {
* A class that manages the clock (countdown, chrono, etc.) Also manages stuff
* like the 'ready/set/go' text at the beginning or the delay at the end of a race.
*/
class Clock
class TimedRace
{
public:
/**
* abstract base class, derive from it to receive events from the clock
*/
class ClockListener
{
public:
virtual ~ClockListener(){};
/*
* Will be called to notify your derived class that the clock,
* which is in COUNTDOWN mode, has reached zero.
*/
virtual void countdownReachedZero() = 0;
/*
* Called when the race actually starts.
*/
virtual void onGo() = 0;
/**
* Called when race is over and should be terminated (mostly called by the clock).
*/
virtual void onTerminate() = 0;
};
private:
protected:
SFXBase *m_prestart_sound;
SFXBase *m_start_sound;
@ -89,14 +64,10 @@ private:
float m_time;
ClockType m_mode;
/**
* This object will be called to notify it of events.
*/
ClockListener* m_listener;
Phase m_phase;
/**
* Counts time during the initial 'ready/set/go' phase, or at the end of a race.
* Counts time during the initial 'ready/set/go' phase, or at the end of a race.
* This timer basically kicks in when we need to calculate non-race time like labels.
*/
float m_auxiliary_timer;
@ -106,8 +77,8 @@ private:
*/
Phase m_previous_phase;
public:
Clock();
~Clock();
TimedRace();
~TimedRace();
void reset();
@ -140,10 +111,26 @@ public:
void pause();
void unpause();
void raceOver(const bool delay=false);
void registerEventListener(ClockListener* listener);
/** Gets called when the race is about to finish (but with the option of adding
* some delay to watch the end of the race. */
virtual void enterRaceOverState(const bool delay=false);
/** Called when it's really over (delay over if any)
*/
virtual void terminateRace() = 0;
/*
* Will be called to notify your derived class that the clock,
* which is in COUNTDOWN mode, has reached zero.
*/
virtual void countdownReachedZero() {};
/*
* Called when the race actually starts.
*/
virtual void onGo() {};
};

View File

@ -22,12 +22,11 @@
#include "translation.hpp"
//-----------------------------------------------------------------------------
FollowTheLeaderRace::FollowTheLeaderRace() : LinearWorld(), Clock::ClockListener()
FollowTheLeaderRace::FollowTheLeaderRace() : LinearWorld()
{
m_leader_intervals = stk_config->m_leader_intervals;
m_clock.registerEventListener(this);
m_clock.setMode(COUNTDOWN, m_leader_intervals[0]);
TimedRace::setMode(COUNTDOWN, m_leader_intervals[0]);
}
//-----------------------------------------------------------------------------
@ -35,7 +34,7 @@ FollowTheLeaderRace::~FollowTheLeaderRace()
{
}
#ifdef __APPLE__
#if 0
#pragma mark -
#pragma mark clock events
#endif
@ -55,12 +54,12 @@ void FollowTheLeaderRace::onGo()
}
}
//-----------------------------------------------------------------------------
void FollowTheLeaderRace::onTerminate()
void FollowTheLeaderRace::terminateRace()
{
World::terminateRace();
LinearWorld::terminateRace();
}
#ifdef __APPLE__
#if 0
#pragma mark -
#pragma mark overridden from World
#endif
@ -69,13 +68,13 @@ void FollowTheLeaderRace::onTerminate()
void FollowTheLeaderRace::update(float delta)
{
LinearWorld::update(delta);
if(!m_clock.isRacePhase()) return;
if(!TimedRace::isRacePhase()) return;
if(m_clock.getTime() < 0.0f)
if(TimedRace::getTime() < 0.0f)
{
if(m_leader_intervals.size()>1)
m_leader_intervals.erase(m_leader_intervals.begin());
m_clock.setTime(m_leader_intervals[0]);
TimedRace::setTime(m_leader_intervals[0]);
int kart_number;
// If the leader kart is not the first kart, remove the first
// kart, otherwise remove the last kart.
@ -109,9 +108,9 @@ void FollowTheLeaderRace::update(float delta)
// Add the results for the remaining kart
for(int i=1; i<(int)race_manager->getNumKarts(); i++)
if(!m_kart[i]->isEliminated())
race_manager->RaceFinished(m_kart[i], m_clock.getTime());
race_manager->RaceFinished(m_kart[i], TimedRace::getTime());
raceOver();
TimedRace::enterRaceOverState();
return;
}
}

View File

@ -20,7 +20,7 @@
#include "modes/linear_world.hpp"
class FollowTheLeaderRace : public LinearWorld, public Clock::ClockListener
class FollowTheLeaderRace : public LinearWorld
{
std::vector<float> m_leader_intervals; // time till elimination in follow leader
public:
@ -30,7 +30,7 @@ public:
// clock events
virtual void countdownReachedZero();
virtual void onGo();
virtual void onTerminate();
virtual void terminateRace();
// overriding World methods
virtual void update(float delta);

View File

@ -21,10 +21,9 @@
#include "gui/menu_manager.hpp"
//-----------------------------------------------------------------------------
StandardRace::StandardRace() : LinearWorld(), Clock::ClockListener()
StandardRace::StandardRace() : LinearWorld()
{
m_clock.registerEventListener(this);
m_clock.setMode(CHRONO);
TimedRace::setMode(CHRONO);
}
//-----------------------------------------------------------------------------
@ -32,7 +31,7 @@ StandardRace::~StandardRace()
{
}
#ifdef __APPLE__
#if 0
#pragma mark -
#pragma mark clock events
#endif
@ -51,12 +50,12 @@ void StandardRace::onGo()
}
}
//-----------------------------------------------------------------------------
void StandardRace::onTerminate()
void StandardRace::terminateRace()
{
World::terminateRace();
LinearWorld::terminateRace();
}
#ifdef __APPLE__
#if 0
#pragma mark -
#pragma mark overridden from World
#endif
@ -70,12 +69,12 @@ void StandardRace::restartRace()
void StandardRace::update(float delta)
{
LinearWorld::update(delta);
if(!m_clock.isRacePhase()) return;
if(!TimedRace::isRacePhase()) return;
// All karts are finished
if(race_manager->getFinishedKarts() >= race_manager->getNumKarts() )
{
raceOver();
TimedRace::enterRaceOverState();
if(user_config->m_profile<0) printProfileResultAndExit();
unlock_manager->raceFinished();
} // if all karts are finished
@ -86,7 +85,7 @@ void StandardRace::update(float delta)
{
// Set delay mode to have time for camera animation, and
// to give the AI some time to get non-estimated timings
raceOver(true /* delay */);
TimedRace::enterRaceOverState(true /* delay */);
}
}

View File

@ -24,7 +24,7 @@
* Represents a standard race, i.e. with a start, end and laps.
* Used in Grand Prix, Quick Race and Time Trial.
*/
class StandardRace : public LinearWorld, public Clock::ClockListener
class StandardRace : public LinearWorld
{
public:
StandardRace();
@ -33,7 +33,7 @@ public:
// clock events
virtual void countdownReachedZero();
virtual void onGo();
virtual void onTerminate();
virtual void terminateRace();
// overriding World methods
virtual void update(float delta);

View File

@ -55,7 +55,7 @@
#endif
//-----------------------------------------------------------------------------
World::World()
World::World() : TimedRace()
{
RaceManager::setWorld(this);
race_state = new RaceState();
@ -66,7 +66,7 @@ World::World()
m_eliminated_karts = 0;
m_eliminated_players = 0;
m_clock.setMode( CHRONO );
TimedRace::setMode( CHRONO );
m_use_highscores = true;
// Grab the track file
@ -198,7 +198,7 @@ World::~World()
void World::terminateRace()
{
updateHighscores();
m_clock.pause();
TimedRace::pause();
menu_manager->pushMenu(MENUID_RACERESULT);
unlock_manager->raceFinished();
}
@ -257,7 +257,7 @@ void World::resetAllKarts()
//-----------------------------------------------------------------------------
void World::update(float dt)
{
m_clock.update(dt);
TimedRace::update(dt);
// Clear race state so that new information can be stored
race_state->clear();
if(user_config->m_replay_history) dt=history->GetNextDelta();
@ -278,13 +278,6 @@ void World::update(float dt)
callback_manager->update(dt);
}
// ----------------------------------------------------------------------------
void World::raceOver(bool delay)
{
m_clock.raceOver(delay);
if(network_manager->getMode()==NetworkManager::NW_SERVER)
network_manager->sendRaceResults();
} // raceOver
// ----------------------------------------------------------------------------
HighscoreEntry* World::getHighscores() const
{
@ -417,7 +410,7 @@ void World::removeKart(int kart_number)
// ignored in all loops). Important:world->getCurrentNumKarts() returns
// the number of karts still racing. This value can not be used for loops
// over all karts, use race_manager->getNumKarts() instead!
race_manager->RaceFinished(kart, m_clock.getTime());
race_manager->RaceFinished(kart, TimedRace::getTime());
kart->eliminate();
m_eliminated_karts++;
@ -472,7 +465,7 @@ void World::getDefaultCollectibles(int& collectible_type, int& amount )
//-----------------------------------------------------------------------------
void World::restartRace()
{
m_clock.reset();
TimedRace::reset();
m_faster_music_active = false;
m_eliminated_karts = 0;
m_eliminated_players = 0;
@ -527,7 +520,7 @@ void World::pause()
{
sound_manager->pauseMusic();
sfx_manager->pauseAll();
m_clock.pause();
TimedRace::pause();
}
//-----------------------------------------------------------------------------
@ -535,7 +528,7 @@ void World::unpause()
{
sound_manager->resumeMusic() ;
sfx_manager->resumeAll();
m_clock.unpause();
TimedRace::unpause();
}
/* EOF */

View File

@ -78,7 +78,7 @@ class btRigidBody;
* RaceManager).
*/
class World
class World : public TimedRace
{
public:
typedef std::vector<Kart*> Karts;
@ -89,7 +89,6 @@ protected:
std::vector<NetworkKart*> m_network_karts;
RandomGenerator m_random;
Clock m_clock;
Karts m_kart;
Physics* m_physics;
float m_fastest_lap;
@ -146,12 +145,9 @@ public:
float getFastestLapTime() const { return m_fastest_lap; }
void setFastestLap(Kart *k, float time) {m_fastest_kart=k;m_fastest_lap=time; }
HighscoreEntry* getHighscores() const;
float getTime() const { return m_clock.getTime(); }
Phase getPhase() const { return m_clock.getPhase(); }
const Clock &getClock() { return m_clock; }
/** Gets called when the race is about to finish (but with the option of adding
* some delay to watch the end of the race. */
void raceOver(bool delay=false);
float getTime() const { return TimedRace::getTime(); }
Phase getPhase() const { return TimedRace::getPhase(); }
virtual void terminateRace();
/** Called to determine the default collectibles to give each player for this
@ -177,9 +173,9 @@ public:
* The code that draws the timer should call this first to know
* whether the game mode wants a timer drawn
*/
bool shouldDrawTimer() const { return ((m_clock.getPhase() == RACE_PHASE ||
m_clock.getPhase() == DELAY_FINISH_PHASE) &&
m_clock.getMode() != CLOCK_NONE); }
bool shouldDrawTimer() const { return ((TimedRace::getPhase() == RACE_PHASE ||
TimedRace::getPhase() == DELAY_FINISH_PHASE) &&
TimedRace::getMode() != CLOCK_NONE); }
/** Called by the code that draws the list of karts on the race GUI
* to know what needs to be drawn in the current mode

View File

@ -632,7 +632,7 @@ void NetworkManager::receiveUpdates()
{
RaceResultMessage m(event.packet);
m_state = NS_WAIT_FOR_RACE_RESULT;
race_manager->getWorld()->raceOver();
race_manager->getWorld()->enterRaceOverState();
return;
}
race_state->receive(event.packet);

View File

@ -171,7 +171,7 @@ void PlayerKart::update(float dt)
{
steer(dt, m_steer_val);
if(RaceManager::getWorld()->getClock().isStartPhase())
if(RaceManager::getWorld()->isStartPhase())
{
if(m_controls.accel!=0.0 || m_controls.brake!=false ||
m_controls.fire|m_controls.wheelie|m_controls.jump)

View File

@ -97,7 +97,7 @@ void DefaultRobot::update( float delta )
return;
}
if( RaceManager::getWorld()->getClock().isStartPhase() )
if( RaceManager::getWorld()->isStartPhase() )
{
handle_race_start();
AutoKart::update( delta );
@ -532,7 +532,7 @@ void DefaultRobot::handle_rescue(const float DELTA)
// check if kart is stuck
if(getSpeed()<2.0f && !isRescue() && !RaceManager::getWorld()->getClock().isStartPhase())
if(getSpeed()<2.0f && !isRescue() && !RaceManager::getWorld()->isStartPhase())
{
m_time_since_stuck += DELTA;
if(m_time_since_stuck > 2.0f)