I'm writing an ORPG. The code below is client-side.
I have a main thread looping in Game::Run
:
Game::~Game()
{
PopAllStates();
}
void Game::Run()
{
sf::Event Event;
while(Window->isOpen())
{
if(LoadQueueMutex.try_lock())
{
while(!LoadQueue.empty())
{
LoadQueue.front().first->Load(LoadQueue.front().second);
LoadQueue.pop();
}
LoadQueueMutex.unlock();
}
while(Window->pollEvent(Event))
{
StateStack.top()->HandleEvent(Event);
}
Window->clear();
StateStack.top()->Draw();
Window->display();
StateStack.top()->Update();
}
}
void Game::AddToLoadQueue(Loadable* pLoadable, WorldPacket Argv)
{
boost::mutex::scoped_lock lock(LoadQueueMutex);
LoadQueue.push(std::make_pair(pLoadable, Argv));
}
void Game::PushState(GameState* pState)
{
StateStack.push(pState);
}
void Game::PopState()
{
if(!StateStack.empty())
{
delete StateStack.top();
StateStack.pop();
}
}
void Game::PopAllStates()
{
while(!StateStack.empty())
{
PopState();
}
}
And another thread waiting for a packet:
void WorldSession::Start()
{
Packet = WorldPacket((uint16)MSG_NULL);
boost::asio::async_read(Socket,
boost::asio::buffer(Packet.GetDataWithHeader(), WorldPacket::HEADER_SIZE),
boost::bind(&WorldSession::HandleHeader, this, boost::asio::placeholders::error));
}
When the packet "arrives", this is usually done because OpenGL breaks if loaded from another thread:
void WorldSession::HandleSomeCoolOpcode()
{
//...
sGame->AddToLoadQueue(pSomethingCool, Packet);
}
When the main thread loads the Loadable*
, it will usually mess with the state stack:
void World::Load(WorldPacket Argv)
{
//...
sGame->PopState();
sGame->PushState(this);
}
Is there any way to improve this?