Apparently singleton is a bad approach, and a lot of the discussions I've read had been saying stuff like 'it's bad for unit testing' or stuff like (BTW what exactly is meant by unit testing in relation to Game Development?).
Now the thing is I have a situation where I can't find any other pattern or implementation method where singleton wouldn't be the best approach. Currently I'm making a state based game engine to help with transitioning between menu and gameplay and anything else which can be considered it's own 'game state' as to only have ONE instance of a gamestate running at one time. So e.g. hit play, go to gameplay, delete the previous state from memory(to keep it from leaking or anything tragic otherwise) and than continue gameplay, hit exit in game, return to menu, delete game play from memory. So rinse repeat this. The way I do it is I have a 'state' which any class inherits to maintain base functionality. Than if I want to switch, all I do in the game is call StateSystem::switchStates(new Menu()); and it will go to a menu. Is this bad and if so how have others managed to do the same? From switching to game to menu and not having to change things inside the main while loop?
So enough of my rant here's the code
main.c
Display *display= NULL;
GL_Controller *myGLController = NULL;
StateSystem *stateSystem = NULL;
State *tempState = NULL;
void setupDisplay()
{
display = Display::createInstance();
display->initialise(640, 480, 24);
display->createPerspectiveProjection(60, 1, 5.0f, 500);
}
void setupGLController()
{
myGLController = GL_Controller::createInstance();
myGLController->initialiseGLController();
printf("OpenGL Version: %f\n", myGLController->returnGLVersion());
if(myGLController->checkVBOOn())
printf("Vertex Buffer Objects Available: True\n");
else
printf("Vertex Buffer Objects Available: False\n");
if(myGLController->returnGLVersion() < 1.5f)
glClearColor(0, 0, 1, 0);
}
int main(int argc, char* args[])
{
float rot = 0;
setupDisplay();
setupGLController();
SDL_Event event;
Timer *timer = new Timer();
stateSystem = StateSystem::create();
bool switched = false;
stateSystem->switchStates(new FileReadTest());
glEnable(GL_CULL_FACE);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
while(1)
{
timer->processTime();
timer->processFrameRate();
if((SDL_PollEvent(&event) && event.key.keysym.sym == SDLK_ESCAPE))
break;
rot += 0.1f;
glTranslatef(-25,0,-80);
stateSystem->updateState();
display->updateDisplay();
}
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
timer->saveHighestFrameRate();
return 1;
}
StateSystem .h
#include "State.h"
class StateSystem
{
public:
StateSystem();
virtual ~StateSystem();
void initialise();
void updateState();
void shutdownState();
void switchStates(State*);
static StateSystem* create();
protected:
private:
static StateSystem* instance;
State *current;
bool updatePrint;
};
StateSystem.cpp
#include "StateSystem.h"
#include "stdio.h"
StateSystem* StateSystem::instance = 0;
StateSystem::StateSystem()
{
current = 0;
updatePrint = false;
}
void StateSystem::initialise()
{
}
void StateSystem::switchStates(State* newState)
{
if(current != 0)
{
delete current;
current = 0;
}
current = newState;
current->initialise();
}
void StateSystem::updateState()
{
current->update();
}
StateSystem* StateSystem::create()
{
if(instance==0)
{
instance = new StateSystem();
}
return instance;
}
StateSystem::~StateSystem()
{
//dtor
}
State.h
class State
{
public:
State();
virtual ~State();
virtual void initialise()=0;
virtual void update()=0;
protected:
SDL_Event event;
private:
};