1
0
forked from 0ad/0ad
0ad/source/simulation/TurnManager.cpp
2006-08-26 20:25:37 +00:00

147 lines
3.0 KiB
C++

#include "precompiled.h"
#include "TurnManager.h"
#include "network/NetMessage.h"
#include "network/Network.h"
#include "ps/GameRecord.h"
#include "ps/CLogger.h"
#include <vector>
CSinglePlayerTurnManager *g_SinglePlayerTurnManager=NULL;
CTurnManager::CTurnManager()
{
for (int i=0;i<3;i++)
m_Batches[i].m_TurnLength=40;
}
void CTurnManager::ClearBatch(uint batch)
{
typedef std::vector<SMessageSyncEntry> MsgVector;
MsgVector &messages=m_Batches[batch].m_Messages;
MsgVector::iterator it=messages.begin();
while (it != messages.end())
{
delete it->m_pMessage;
++it;
}
messages.clear();
}
void CTurnManager::SBatch::Swap(SBatch &other)
{
std::swap(m_Messages, other.m_Messages);
std::swap(m_TurnLength, other.m_TurnLength);
}
void CTurnManager::RotateBatches()
{
// {a, b, c} => {b, c, a}:
// {a, b, c}
// -- swap (0, 1)
// {b, a, c}
// -- swap (1, 2)
// {b, c, a}
m_Batches[0].Swap(m_Batches[1]);
m_Batches[1].Swap(m_Batches[2]);
}
void CTurnManager::IterateBatch(uint batch, BatchIteratorFunc *fp, void *userdata)
{
typedef std::vector<SMessageSyncEntry> MsgVector;
MsgVector &messages=m_Batches[batch].m_Messages;
MsgVector::iterator it=messages.begin();
while (it != messages.end())
{
it->m_ClientMask=(*fp)(it->m_pMessage, it->m_ClientMask, userdata);
++it;
}
}
void CTurnManager::SendBatch(uint batch)
{
typedef std::vector<SMessageSyncEntry> MsgVector;
MsgVector &messages=m_Batches[batch].m_Messages;
MsgVector::iterator it=messages.begin();
while (it != messages.end())
{
SendMessage(it->m_pMessage, it->m_ClientMask);
++it;
}
CEndCommandBatch *pMsg=new CEndCommandBatch();
pMsg->m_TurnLength=m_Batches[batch].m_TurnLength;
SendMessage(pMsg, (uint)-1);
}
void CTurnManager::SendMessage(CNetMessage *pMsg, uint clientMask)
{
for (uint i=0;i<m_Clients.size();i++)
{
if (clientMask & (1<<i))
{
if (m_Clients[i].m_Pipe)
m_Clients[i].m_Pipe->Push(pMsg->Copy());
}
}
}
void CTurnManager::QueueMessage(uint batch, CNetMessage *pMsg)
{
m_Batches[batch].m_Messages.push_back(SMessageSyncEntry(pMsg));
}
void CTurnManager::SetClientPipe(uint client, IMessagePipeEnd *pipe)
{
m_Clients[client].m_Pipe=pipe;
}
void CTurnManager::SetTurnLength(uint batch, uint turnLength)
{
m_Batches[batch].m_TurnLength=turnLength;
}
uint CTurnManager::GetTurnLength()
{
return m_Batches[0].m_TurnLength;
}
void CTurnManager::Initialize(size_t numClients)
{
m_Clients.resize(numClients);
}
void CTurnManager::RecordBatch(uint batch)
{
IterateBatch(batch, RecordIterator, m_pRecord);
CEndCommandBatch msg;
m_pRecord->WriteMessage(&msg);
}
uint CTurnManager::RecordIterator(CNetMessage *pMsg, uint clientMask, void *userdata)
{
CGameRecord *pRecord=(CGameRecord *)userdata;
pRecord->WriteMessage(pMsg);
return clientMask;
}
CSinglePlayerTurnManager::CSinglePlayerTurnManager()
{}
void CSinglePlayerTurnManager::NewTurn()
{
RecordBatch(2);
RotateBatches();
ClearBatch(2);
}
void CSinglePlayerTurnManager::QueueLocalCommand(CNetMessage *pMsg)
{
QueueMessage(2, pMsg);
}