State stack system

This commit is contained in:
James Turk 2005-08-10 21:22:33 +00:00
parent a1d7a0d57f
commit 8412cbab72
11 changed files with 109 additions and 28 deletions

View File

@ -1,13 +1,18 @@
Changelog for Photon Changelog for Photon
$Id: CHANGELOG.txt,v 1.5 2005/08/09 07:30:14 cozman Exp $ $Id: CHANGELOG.txt,v 1.6 2005/08/10 21:22:33 cozman Exp $
+ : New Features + : New Features
- : Feature Removal - : Feature Removal
* : Minor Changes/Bugfixes
! : Major Changes ! : Major Changes
* : Minor Changes/Bugfixes
0.0.2 0.0.2
+ Code::Blocks and Dev-C++ support + Code::Blocks and Dev-C++ support
+ Addition of a State stack allowing for applications to fall back to the
previous state when done with a particular state.
* Fixed X11 fullscreen mode
* Removed ALUT dependencies by adding custom WAV loading code
0.0.1 - Released 2005-08-08 0.0.1 - Released 2005-08-08
+ State-based design that allows easy creation of applications by simply + State-based design that allows easy creation of applications by simply

View File

@ -5,13 +5,13 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Application.hpp,v 1.16 2005/08/08 21:39:41 cozman Exp $ // $Id: Application.hpp,v 1.17 2005/08/10 21:22:33 cozman Exp $
#ifndef PHOTON_APPLICATION_HPP #ifndef PHOTON_APPLICATION_HPP
#define PHOTON_APPLICATION_HPP #define PHOTON_APPLICATION_HPP
#include <vector> #include <vector>
#include <map> #include <stack>
#include <string> #include <string>
#include <boost/utility.hpp> #include <boost/utility.hpp>
@ -297,13 +297,25 @@ public:
// Group: State Management // Group: State Management
public: public:
// Function: setCurrentState // Function: setState
// Set the current Application <State>. // Set the current Application <State>, removing all other <States>.
// //
// Template Parameters: // Template Parameters:
// StateT - Class derived from <State> to register. // StateT - Class derived from <State> to set as current.
template<class StateT> template<class StateT>
void setCurrentState(); void setState();
// Function: pushState
// Push a new <State>, does not remove old <State>.
//
// Template Parameters:
// StateT - Class derived from <State> to push.
template<class StateT>
void pushState();
// Function: popState
// Pop the current <State>, returning to the prior <State> on the stack.
void popState();
#ifdef PHOTON_USE_OPENAL #ifdef PHOTON_USE_OPENAL
// Group: AudioCore // Group: AudioCore
@ -416,6 +428,9 @@ private:
static std::vector<InputListener*> listeners_; static std::vector<InputListener*> listeners_;
static std::vector<KeyCode> pressedKeys_; static std::vector<KeyCode> pressedKeys_;
// state system
std::stack<StatePtr> stateStack_;
// Cores // Cores
#ifdef PHOTON_USE_OPENAL #ifdef PHOTON_USE_OPENAL
std::auto_ptr<audio::AudioCore> audioCore_; std::auto_ptr<audio::AudioCore> audioCore_;
@ -423,11 +438,42 @@ private:
}; };
template<class StateT> template<class StateT>
void Application::setCurrentState() void Application::setState()
{ {
stateRender_->state_ = stateUpdate_->state_ = StatePtr(new StateT); StatePtr newState(new StateT);
// clear stack
while(!stateStack_.empty())
{
// pop then resume
stateStack_.pop();
if(!stateStack_.empty())
{
stateStack_.top()->onResume();
}
}
stateStack_.push(newState); // make newState the only state on stack
stateRender_->state_ = stateUpdate_->state_ = newState;
} }
template<class StateT>
void Application::pushState()
{
StatePtr newState(new StateT);
// if a state is currently running, pause it
if(!stateStack_.empty())
{
stateStack_.top()->onPause();
}
stateStack_.push(newState); // push newState on top of stack
stateRender_->state_ = stateUpdate_->state_ = newState;
}
} }
#endif //PHOTON_APPLICATION_HPP #endif //PHOTON_APPLICATION_HPP

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: State.hpp,v 1.1 2005/08/08 19:19:25 cozman Exp $ // $Id: State.hpp,v 1.2 2005/08/10 21:22:33 cozman Exp $
#ifndef PHOTON_STATE_HPP #ifndef PHOTON_STATE_HPP
#define PHOTON_STATE_HPP #define PHOTON_STATE_HPP
@ -21,7 +21,7 @@
// Implement as many or as few of the members of State as needed (the only // Implement as many or as few of the members of State as needed (the only
// necessary member being <render>) and make the state as current via // necessary member being <render>) and make the state as current via
// <Application::setCurrentState>. Once a state is made current it's // <Application::setState>. Once a state is made current it's
// update and render methods will be called every frame until either a new // update and render methods will be called every frame until either a new
// state is made current or the application ends. // state is made current or the application ends.
class State class State
@ -30,7 +30,7 @@ class State
public: public:
// Function: State // Function: State
// A State's constructor is called whenever the state is made active via // A State's constructor is called whenever the state is made active via
// <Application::setCurrentState>. // <Application::setState>.
State() { }; State() { };
// Function: ~State // Function: ~State
@ -51,6 +51,21 @@ public:
// screen while the State is active should be drawn in render. Game logic // screen while the State is active should be drawn in render. Game logic
// inside of render should be kept to a minimum for optimum performance. // inside of render should be kept to a minimum for optimum performance.
virtual void render()=0; virtual void render()=0;
// Function: onPause
// If a state is executing and a new state is pushed onto the stack via
// <Application::pushState> the state will be paused until a time that it
// is either unpaused or popped from the stack itself. When it is paused
// the state management system will call onPause which may perform any
// necessary work before the state goes idle.
virtual void onPause() { };
// Function: onResume
// If a state has been paused and is then made current again by the
// state(s) pushed on top of it being popped, the state management system
// will call onResume allowing the state to undo any work that had been
// done in <onPause>.
virtual void onResume() { };
}; };
typedef photon::shared_ptr<State> StatePtr; typedef photon::shared_ptr<State> StatePtr;

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: entrypoint.hpp,v 1.8 2005/08/08 19:19:25 cozman Exp $ // $Id: entrypoint.hpp,v 1.9 2005/08/10 21:22:33 cozman Exp $
#ifndef PHOTON_ENTRYPOINT_HPP #ifndef PHOTON_ENTRYPOINT_HPP
@ -33,7 +33,7 @@
// Application::getInstance().createDisplay(800,600,32,0,0,false); // Application::getInstance().createDisplay(800,600,32,0,0,false);
// //
// // set current state // // set current state
// Application::getInstance().setCurrentState<MainMenu>(); // Application::getInstance().setState<MainMenu>();
// //
// // can also add any tasks here // // can also add any tasks here
// //

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Application.cpp,v 1.21 2005/08/10 05:36:58 cozman Exp $ // $Id: Application.cpp,v 1.22 2005/08/10 21:22:33 cozman Exp $
#include "Application.hpp" #include "Application.hpp"
@ -389,6 +389,21 @@ double Application::getFramerate()
{ {
return 1/updateTask_->secPerFrame_; return 1/updateTask_->secPerFrame_;
} }
// States //////////////////////////////////////////////////////////////////////
void Application::popState()
{
stateStack_.pop(); // pop current state from stack
// if there is another state, resume it it
if(!stateStack_.empty())
{
stateStack_.top()->onResume();
stateRender_->state_ = stateUpdate_->state_ = stateStack_.top();
}
}
// AudioCore /////////////////////////////////////////////////////////////////// // AudioCore ///////////////////////////////////////////////////////////////////
#ifdef PHOTON_USE_OPENAL #ifdef PHOTON_USE_OPENAL

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Audio_test.cpp,v 1.12 2005/08/08 21:39:41 cozman Exp $ // $Id: Audio_test.cpp,v 1.13 2005/08/10 21:22:33 cozman Exp $
#include "photon.hpp" #include "photon.hpp"
using namespace photon; using namespace photon;
@ -193,7 +193,7 @@ int PhotonMain(const StrVec& args)
Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask()));
// register state and make active // register state and make active
Application::getInstance().setCurrentState<MainState>(); Application::getInstance().setState<MainState>();
// run until finished // run until finished
Kernel::getInstance().run(); Kernel::getInstance().run();

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Font_test.cpp,v 1.10 2005/08/08 06:37:10 cozman Exp $ // $Id: Font_test.cpp,v 1.11 2005/08/10 21:22:33 cozman Exp $
#include "photon.hpp" #include "photon.hpp"
using namespace photon; using namespace photon;
@ -56,7 +56,7 @@ int PhotonMain(const StrVec& args)
Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask()));
// set current state // set current state
Application::getInstance().setCurrentState<MainState>(); Application::getInstance().setState<MainState>();
// run until finished // run until finished
Kernel::getInstance().run(); Kernel::getInstance().run();

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Image_test.cpp,v 1.10 2005/08/08 06:37:10 cozman Exp $ // $Id: Image_test.cpp,v 1.11 2005/08/10 21:22:33 cozman Exp $
#include "photon.hpp" #include "photon.hpp"
using namespace photon; using namespace photon;
@ -67,7 +67,7 @@ int PhotonMain(const StrVec& args)
Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask()));
// set current state // set current state
Application::getInstance().setCurrentState<MainState>(); Application::getInstance().setState<MainState>();
// run until finished // run until finished
Kernel::getInstance().run(); Kernel::getInstance().run();

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Input_test.cpp,v 1.8 2005/08/08 19:24:31 cozman Exp $ // $Id: Input_test.cpp,v 1.9 2005/08/10 21:22:33 cozman Exp $
#include "photon.hpp" #include "photon.hpp"
using namespace photon; using namespace photon;
@ -120,7 +120,7 @@ int PhotonMain(const StrVec& args)
Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask()));
// set current state // set current state
Application::getInstance().setCurrentState<MainState>(); Application::getInstance().setState<MainState>();
// run until finished // run until finished
Kernel::getInstance().run(); Kernel::getInstance().run();

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Pen_test.cpp,v 1.7 2005/08/08 06:37:10 cozman Exp $ // $Id: Pen_test.cpp,v 1.8 2005/08/10 21:22:33 cozman Exp $
#include "photon.hpp" #include "photon.hpp"
using namespace photon; using namespace photon;
@ -80,7 +80,7 @@ int PhotonMain(const StrVec& args)
Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask()));
// set current state // set current state
Application::getInstance().setCurrentState<MainState>(); Application::getInstance().setState<MainState>();
// run until finished // run until finished
Kernel::getInstance().run(); Kernel::getInstance().run();

View File

@ -5,7 +5,7 @@
// James Turk (jpt2433@rit.edu) // James Turk (jpt2433@rit.edu)
// //
// Version: // Version:
// $Id: Texture_test.cpp,v 1.8 2005/08/08 06:37:10 cozman Exp $ // $Id: Texture_test.cpp,v 1.9 2005/08/10 21:22:33 cozman Exp $
#include "photon.hpp" #include "photon.hpp"
using namespace photon; using namespace photon;
@ -80,7 +80,7 @@ int PhotonMain(const StrVec& args)
Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask())); Kernel::getInstance().addTask(TaskPtr(new FPSDisplayTask()));
// set current state // set current state
Application::getInstance().setCurrentState<MainState>(); Application::getInstance().setState<MainState>();
// run until finished // run until finished
Kernel::getInstance().run(); Kernel::getInstance().run();