1
0
forked from 0ad/0ad

Make CFsm a template

The context doesn't have to be converted to `void*` and back.


Differential Revision: https://code.wildfiregames.com/D5253
This was SVN commit r28074.
This commit is contained in:
phosit 2024-05-04 16:13:02 +00:00
parent 53f9faa4e0
commit 3a5ad160f7
7 changed files with 221 additions and 227 deletions

View File

@ -24,22 +24,6 @@
constexpr unsigned int FSM_INVALID_STATE{std::numeric_limits<unsigned int>::max()};
class CFsmEvent;
class CFsm;
using Action = bool(void* pContext, CFsmEvent* pEvent);
struct CallbackFunction
{
Action* pFunction{nullptr};
void* pContext{nullptr};
bool operator()(CFsmEvent& event) const
{
return !pFunction || pFunction(pContext, &event);
}
};
/**
* Represents a signal in the state machine that a change has occurred.
* The CFsmEvent objects are under the control of CFsm so
@ -47,11 +31,11 @@ struct CallbackFunction
*/
class CFsmEvent
{
NONCOPYABLE(CFsmEvent);
public:
CFsmEvent(unsigned int type, void* pParam);
~CFsmEvent();
CFsmEvent(unsigned int type, void* pParam) :
m_Type{type},
m_Param{pParam}
{}
unsigned int GetType() const
{
@ -79,24 +63,47 @@ private:
* transitions; Mealy machines are event driven where an
* event triggers a state transition.
*/
template <typename Context>
class CFsm
{
using Action = bool(Context* pContext, CFsmEvent* pEvent);
struct CallbackFunction
{
Action* pFunction{nullptr};
Context* pContext{nullptr};
bool operator()(CFsmEvent& event) const
{
return !pFunction || pFunction(pContext, &event);
}
};
public:
/**
* Adds a new transistion to the state machine.
*/
void AddTransition(unsigned int state, unsigned int eventType, unsigned int nextState,
Action* pAction = nullptr, void* pContext = nullptr);
Action* pAction = nullptr, Context* pContext = nullptr)
{
m_Transitions.insert({TransitionKey{state, eventType},
Transition{{pAction, pContext}, nextState}});
}
/**
* Sets the initial state for FSM.
*/
void SetFirstState(unsigned int firstState);
void SetFirstState(unsigned int firstState)
{
m_FirstState = firstState;
}
/**
* Sets the current state and update the last state to the current state.
*/
void SetCurrState(unsigned int state);
void SetCurrState(unsigned int state)
{
m_CurrState = state;
}
unsigned int GetCurrState() const
{
return m_CurrState;
@ -116,12 +123,40 @@ public:
* Updates the FSM and retrieves next state.
* @return whether the state was changed.
*/
bool Update(unsigned int eventType, void* pEventData);
bool Update(unsigned int eventType, void* pEventData)
{
if (IsFirstTime())
m_CurrState = m_FirstState;
// Lookup transition
auto transitionIterator = m_Transitions.find({m_CurrState, eventType});
if (transitionIterator == m_Transitions.end())
return false;
CFsmEvent event{eventType, pEventData};
// Save the default state transition (actions might call SetNextState
// to override this)
SetNextState(transitionIterator->second.nextState);
if (!transitionIterator->second.action(event))
return false;
SetCurrState(GetNextState());
// Reset the next state since it's no longer valid
SetNextState(FSM_INVALID_STATE);
return true;
}
/**
* Tests whether the state machine has finished its work.
*/
bool IsDone() const;
bool IsDone() const
{
return m_Done;
}
private:
struct TransitionKey
@ -153,12 +188,16 @@ private:
unsigned int nextState;
};
using TransitionMap = std::unordered_map<TransitionKey, const Transition, TransitionKey::Hash>;
using TransitionMap = std::unordered_map<TransitionKey, const Transition,
typename TransitionKey::Hash>;
/**
* Verifies whether state machine has already been updated.
*/
bool IsFirstTime() const;
bool IsFirstTime() const
{
return m_CurrState == FSM_INVALID_STATE;
}
bool m_Done{false};
unsigned int m_FirstState{FSM_INVALID_STATE};

View File

@ -64,62 +64,60 @@ CNetClient::CNetClient(CGame* game) :
{
m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it
void* context = this;
JS_AddExtraGCRootsTracer(GetScriptInterface().GetGeneralJSContext(), CNetClient::Trace, this);
// Set up transitions for session
AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, &OnConnect, context);
AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, &OnConnect, this);
AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, &OnHandshake, context);
AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, &OnHandshake, this);
AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, &OnHandshakeResponse, context);
AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, &OnHandshakeResponse, this);
AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NCS_AUTHENTICATE, &OnAuthenticateRequest, context);
AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_PREGAME, &OnAuthenticate, context);
AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NCS_AUTHENTICATE, &OnAuthenticateRequest, this);
AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_PREGAME, &OnAuthenticate, this);
AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, &OnChat, context);
AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, &OnReady, context);
AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, &OnGameSetup, context);
AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, &OnPlayerAssignment, context);
AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, &OnKicked, context);
AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, &OnClientTimeout, context);
AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, &OnClientPerformance, context);
AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, &OnGameStart, context);
AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, &OnJoinSyncStart, context);
AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, &OnChat, this);
AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, &OnReady, this);
AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, &OnGameSetup, this);
AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, &OnPlayerAssignment, this);
AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, &OnKicked, this);
AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, &OnClientTimeout, this);
AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, &OnClientPerformance, this);
AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, &OnGameStart, this);
AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, &OnJoinSyncStart, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, &OnChat, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, &OnGameSetup, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_JOIN_SYNCING, &OnPlayerAssignment, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_KICKED, NCS_JOIN_SYNCING, &OnKicked, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_TIMEOUT, NCS_JOIN_SYNCING, &OnClientTimeout, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_PERFORMANCE, NCS_JOIN_SYNCING, &OnClientPerformance, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_START, NCS_JOIN_SYNCING, &OnGameStart, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_SIMULATION_COMMAND, NCS_JOIN_SYNCING, &OnInGame, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_END_COMMAND_BATCH, NCS_JOIN_SYNCING, &OnJoinSyncEndCommandBatch, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NCS_INGAME, &OnLoadedGame, context);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, &OnChat, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, &OnGameSetup, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_JOIN_SYNCING, &OnPlayerAssignment, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_KICKED, NCS_JOIN_SYNCING, &OnKicked, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_TIMEOUT, NCS_JOIN_SYNCING, &OnClientTimeout, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_PERFORMANCE, NCS_JOIN_SYNCING, &OnClientPerformance, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_START, NCS_JOIN_SYNCING, &OnGameStart, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_SIMULATION_COMMAND, NCS_JOIN_SYNCING, &OnInGame, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_END_COMMAND_BATCH, NCS_JOIN_SYNCING, &OnJoinSyncEndCommandBatch, this);
AddTransition(NCS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NCS_INGAME, &OnLoadedGame, this);
AddTransition(NCS_LOADING, (uint)NMT_CHAT, NCS_LOADING, &OnChat, context);
AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, &OnGameSetup, context);
AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, &OnPlayerAssignment, context);
AddTransition(NCS_LOADING, (uint)NMT_KICKED, NCS_LOADING, &OnKicked, context);
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_TIMEOUT, NCS_LOADING, &OnClientTimeout, context);
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_PERFORMANCE, NCS_LOADING, &OnClientPerformance, context);
AddTransition(NCS_LOADING, (uint)NMT_CLIENTS_LOADING, NCS_LOADING, &OnClientsLoading, context);
AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, &OnLoadedGame, context);
AddTransition(NCS_LOADING, (uint)NMT_CHAT, NCS_LOADING, &OnChat, this);
AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, &OnGameSetup, this);
AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, &OnPlayerAssignment, this);
AddTransition(NCS_LOADING, (uint)NMT_KICKED, NCS_LOADING, &OnKicked, this);
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_TIMEOUT, NCS_LOADING, &OnClientTimeout, this);
AddTransition(NCS_LOADING, (uint)NMT_CLIENT_PERFORMANCE, NCS_LOADING, &OnClientPerformance, this);
AddTransition(NCS_LOADING, (uint)NMT_CLIENTS_LOADING, NCS_LOADING, &OnClientsLoading, this);
AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, &OnLoadedGame, this);
AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, &OnRejoined, context);
AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, &OnKicked, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_INGAME, &OnClientTimeout, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_INGAME, &OnClientPerformance, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENTS_LOADING, NCS_INGAME, &OnClientsLoading, context);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PAUSED, NCS_INGAME, &OnClientPaused, context);
AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, &OnChat, context);
AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, &OnGameSetup, context);
AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, &OnPlayerAssignment, context);
AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, &OnInGame, context);
AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, &OnInGame, context);
AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, &OnInGame, context);
AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, &OnRejoined, this);
AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, &OnKicked, this);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_INGAME, &OnClientTimeout, this);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_INGAME, &OnClientPerformance, this);
AddTransition(NCS_INGAME, (uint)NMT_CLIENTS_LOADING, NCS_INGAME, &OnClientsLoading, this);
AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PAUSED, NCS_INGAME, &OnClientPaused, this);
AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, &OnChat, this);
AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, &OnGameSetup, this);
AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, &OnPlayerAssignment, this);
AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, &OnInGame, this);
AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, &OnInGame, this);
AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, &OnInGame, this);
// Set first state
SetFirstState(NCS_UNCONNECTED);
@ -604,12 +602,10 @@ void CNetClient::SendAuthenticateMessage()
SendMessage(&authenticate);
}
bool CNetClient::OnConnect(void* context, CFsmEvent* event)
bool CNetClient::OnConnect(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CONNECT_COMPLETE);
CNetClient* client = static_cast<CNetClient*>(context);
client->PushGuiMessage(
"type", "netstatus",
"status", "connected");
@ -617,12 +613,10 @@ bool CNetClient::OnConnect(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnHandshake(void* context, CFsmEvent* event)
bool CNetClient::OnHandshake(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE);
CNetClient* client = static_cast<CNetClient*>(context);
CCliHandshakeMessage handshake;
handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE;
handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
@ -632,11 +626,10 @@ bool CNetClient::OnHandshake(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnHandshakeResponse(void* context, CFsmEvent* event)
bool CNetClient::OnHandshakeResponse(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE);
CNetClient* client = static_cast<CNetClient*>(context);
CSrvHandshakeResponseMessage* message = static_cast<CSrvHandshakeResponseMessage*>(event->GetParamRef());
client->m_GUID = message->m_GUID;
@ -661,20 +654,18 @@ bool CNetClient::OnHandshakeResponse(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnAuthenticateRequest(void* context, CFsmEvent* event)
bool CNetClient::OnAuthenticateRequest(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE);
CNetClient* client = static_cast<CNetClient*>(context);
client->SendAuthenticateMessage();
return true;
}
bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
bool CNetClient::OnAuthenticate(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT);
CNetClient* client = static_cast<CNetClient*>(context);
CAuthenticateResultMessage* message = static_cast<CAuthenticateResultMessage*>(event->GetParamRef());
LOGMESSAGE("Net: Authentication result: host=%u, %s", message->m_HostID, utf8_from_wstring(message->m_Message));
@ -691,11 +682,10 @@ bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnChat(void* context, CFsmEvent* event)
bool CNetClient::OnChat(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CHAT);
CNetClient* client = static_cast<CNetClient*>(context);
CChatMessage* message = static_cast<CChatMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -706,11 +696,10 @@ bool CNetClient::OnChat(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnReady(void* context, CFsmEvent* event)
bool CNetClient::OnReady(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_READY);
CNetClient* client = static_cast<CNetClient*>(context);
CReadyMessage* message = static_cast<CReadyMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -721,11 +710,10 @@ bool CNetClient::OnReady(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnGameSetup(void* context, CFsmEvent* event)
bool CNetClient::OnGameSetup(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_GAME_SETUP);
CNetClient* client = static_cast<CNetClient*>(context);
CGameSetupMessage* message = static_cast<CGameSetupMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -735,11 +723,10 @@ bool CNetClient::OnGameSetup(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnPlayerAssignment(void* context, CFsmEvent* event)
bool CNetClient::OnPlayerAssignment(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT);
CNetClient* client = static_cast<CNetClient*>(context);
CPlayerAssignmentMessage* message = static_cast<CPlayerAssignmentMessage*>(event->GetParamRef());
// Unpack the message
@ -763,11 +750,10 @@ bool CNetClient::OnPlayerAssignment(void* context, CFsmEvent* event)
// This is called either when the host clicks the StartGame button or
// if this client rejoins and finishes the download of the simstate.
bool CNetClient::OnGameStart(void* context, CFsmEvent* event)
bool CNetClient::OnGameStart(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_GAME_START);
CNetClient* client = static_cast<CNetClient*>(context);
CGameStartMessage* message = static_cast<CGameStartMessage*>(event->GetParamRef());
// Find the player assigned to our GUID
@ -793,12 +779,10 @@ bool CNetClient::OnGameStart(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnJoinSyncStart(void* context, CFsmEvent* event)
bool CNetClient::OnJoinSyncStart(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_JOIN_SYNC_START);
CNetClient* client = static_cast<CNetClient*>(context);
CJoinSyncStartMessage* joinSyncStartMessage = (CJoinSyncStartMessage*)event->GetParamRef();
// The server wants us to start downloading the game state from it, so do so
@ -820,12 +804,10 @@ bool CNetClient::OnJoinSyncStart(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event)
bool CNetClient::OnJoinSyncEndCommandBatch(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH);
CNetClient* client = static_cast<CNetClient*>(context);
CEndCommandBatchMessage* endMessage = (CEndCommandBatchMessage*)event->GetParamRef();
client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength);
@ -836,11 +818,10 @@ bool CNetClient::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnRejoined(void* context, CFsmEvent* event)
bool CNetClient::OnRejoined(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_REJOINED);
CNetClient* client = static_cast<CNetClient*>(context);
CRejoinedMessage* message = static_cast<CRejoinedMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -850,11 +831,10 @@ bool CNetClient::OnRejoined(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnKicked(void *context, CFsmEvent* event)
bool CNetClient::OnKicked(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_KICKED);
CNetClient* client = static_cast<CNetClient*>(context);
CKickedMessage* message = static_cast<CKickedMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -865,13 +845,12 @@ bool CNetClient::OnKicked(void *context, CFsmEvent* event)
return true;
}
bool CNetClient::OnClientTimeout(void *context, CFsmEvent* event)
bool CNetClient::OnClientTimeout(CNetClient* client, CFsmEvent* event)
{
// Report the timeout of some other client
ENSURE(event->GetType() == (uint)NMT_CLIENT_TIMEOUT);
CNetClient* client = static_cast<CNetClient*>(context);
CClientTimeoutMessage* message = static_cast<CClientTimeoutMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -883,13 +862,12 @@ bool CNetClient::OnClientTimeout(void *context, CFsmEvent* event)
return true;
}
bool CNetClient::OnClientPerformance(void *context, CFsmEvent* event)
bool CNetClient::OnClientPerformance(CNetClient* client, CFsmEvent* event)
{
// Performance statistics for one or multiple clients
ENSURE(event->GetType() == (uint)NMT_CLIENT_PERFORMANCE);
CNetClient* client = static_cast<CNetClient*>(context);
CClientPerformanceMessage* message = static_cast<CClientPerformanceMessage*>(event->GetParamRef());
// Display warnings for other clients with bad ping
@ -908,11 +886,10 @@ bool CNetClient::OnClientPerformance(void *context, CFsmEvent* event)
return true;
}
bool CNetClient::OnClientsLoading(void *context, CFsmEvent *event)
bool CNetClient::OnClientsLoading(CNetClient* client, CFsmEvent *event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENTS_LOADING);
CNetClient* client = static_cast<CNetClient*>(context);
CClientsLoadingMessage* message = static_cast<CClientsLoadingMessage*>(event->GetParamRef());
std::vector<CStr> guids;
@ -926,11 +903,10 @@ bool CNetClient::OnClientsLoading(void *context, CFsmEvent *event)
return true;
}
bool CNetClient::OnClientPaused(void *context, CFsmEvent *event)
bool CNetClient::OnClientPaused(CNetClient* client, CFsmEvent *event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED);
CNetClient* client = static_cast<CNetClient*>(context);
CClientPausedMessage* message = static_cast<CClientPausedMessage*>(event->GetParamRef());
client->PushGuiMessage(
@ -941,12 +917,10 @@ bool CNetClient::OnClientPaused(void *context, CFsmEvent *event)
return true;
}
bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event)
bool CNetClient::OnLoadedGame(CNetClient* client, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
CNetClient* client = static_cast<CNetClient*>(context);
// All players have loaded the game - start running the turn manager
// so that the game begins
client->m_Game->SetTurnManager(client->m_ClientTurnManager);
@ -962,11 +936,10 @@ bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event)
return true;
}
bool CNetClient::OnInGame(void *context, CFsmEvent* event)
bool CNetClient::OnInGame(CNetClient* client, CFsmEvent* event)
{
// TODO: should split each of these cases into a separate method
CNetClient* client = static_cast<CNetClient*>(context);
CNetMessage* message = static_cast<CNetMessage*>(event->GetParamRef());
if (message)

View File

@ -56,7 +56,7 @@ enum
* It provides an interface between the GUI, the network (via CNetClientSession),
* and the game (via CGame and CNetClientTurnManager).
*/
class CNetClient : public CFsm
class CNetClient : public CFsm<CNetClient>
{
NONCOPYABLE(CNetClient);
@ -266,26 +266,26 @@ private:
void SendAuthenticateMessage();
// Net message / FSM transition handlers
static bool OnConnect(void* context, CFsmEvent* event);
static bool OnHandshake(void* context, CFsmEvent* event);
static bool OnHandshakeResponse(void* context, CFsmEvent* event);
static bool OnAuthenticateRequest(void* context, CFsmEvent* event);
static bool OnAuthenticate(void* context, CFsmEvent* event);
static bool OnChat(void* context, CFsmEvent* event);
static bool OnReady(void* context, CFsmEvent* event);
static bool OnGameSetup(void* context, CFsmEvent* event);
static bool OnPlayerAssignment(void* context, CFsmEvent* event);
static bool OnInGame(void* context, CFsmEvent* event);
static bool OnGameStart(void* context, CFsmEvent* event);
static bool OnJoinSyncStart(void* context, CFsmEvent* event);
static bool OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event);
static bool OnRejoined(void* context, CFsmEvent* event);
static bool OnKicked(void* context, CFsmEvent* event);
static bool OnClientTimeout(void* context, CFsmEvent* event);
static bool OnClientPerformance(void* context, CFsmEvent* event);
static bool OnClientsLoading(void* context, CFsmEvent* event);
static bool OnClientPaused(void* context, CFsmEvent* event);
static bool OnLoadedGame(void* context, CFsmEvent* event);
static bool OnConnect(CNetClient* client, CFsmEvent* event);
static bool OnHandshake(CNetClient* client, CFsmEvent* event);
static bool OnHandshakeResponse(CNetClient* client, CFsmEvent* event);
static bool OnAuthenticateRequest(CNetClient* client, CFsmEvent* event);
static bool OnAuthenticate(CNetClient* client, CFsmEvent* event);
static bool OnChat(CNetClient* client, CFsmEvent* event);
static bool OnReady(CNetClient* client, CFsmEvent* event);
static bool OnGameSetup(CNetClient* client, CFsmEvent* event);
static bool OnPlayerAssignment(CNetClient* client, CFsmEvent* event);
static bool OnInGame(CNetClient* client, CFsmEvent* event);
static bool OnGameStart(CNetClient* client, CFsmEvent* event);
static bool OnJoinSyncStart(CNetClient* client, CFsmEvent* event);
static bool OnJoinSyncEndCommandBatch(CNetClient* client, CFsmEvent* event);
static bool OnRejoined(CNetClient* client, CFsmEvent* event);
static bool OnKicked(CNetClient* client, CFsmEvent* event);
static bool OnClientTimeout(CNetClient* client, CFsmEvent* event);
static bool OnClientPerformance(CNetClient* client, CFsmEvent* event);
static bool OnClientsLoading(CNetClient* client, CFsmEvent* event);
static bool OnClientPaused(CNetClient* client, CFsmEvent* event);
static bool OnLoadedGame(CNetClient* client, CFsmEvent* event);
/**
* Take ownership of a session object, and use it for all network communication.

View File

@ -625,43 +625,41 @@ void CNetServerWorker::HandleMessageReceive(const CNetMessage* message, CNetServ
void CNetServerWorker::SetupSession(CNetServerSession* session)
{
void* context = session;
// Set up transitions for session
session->AddTransition(NSS_UNCONNECTED, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED);
session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED);
session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CLIENT_HANDSHAKE, NSS_AUTHENTICATE, &OnClientHandshake, context);
session->AddTransition(NSS_HANDSHAKE, (uint)NMT_CLIENT_HANDSHAKE, NSS_AUTHENTICATE, &OnClientHandshake, session);
session->AddTransition(NSS_LOBBY_AUTHENTICATE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED);
session->AddTransition(NSS_LOBBY_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, &OnAuthenticate, context);
session->AddTransition(NSS_LOBBY_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, &OnAuthenticate, session);
session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED);
session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, &OnAuthenticate, context);
session->AddTransition(NSS_AUTHENTICATE, (uint)NMT_AUTHENTICATE, NSS_PREGAME, &OnAuthenticate, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, &OnDisconnect, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_CHAT, NSS_PREGAME, &OnChat, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_READY, NSS_PREGAME, &OnReady, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_CLEAR_ALL_READY, NSS_PREGAME, &OnClearAllReady, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_SETUP, NSS_PREGAME, &OnGameSetup, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_ASSIGN_PLAYER, NSS_PREGAME, &OnAssignPlayer, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_KICKED, NSS_PREGAME, &OnKickPlayer, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_START, NSS_PREGAME, &OnGameStart, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_LOADED_GAME, NSS_INGAME, &OnLoadedGame, context);
session->AddTransition(NSS_PREGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, &OnDisconnect, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_CHAT, NSS_PREGAME, &OnChat, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_READY, NSS_PREGAME, &OnReady, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_CLEAR_ALL_READY, NSS_PREGAME, &OnClearAllReady, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_SETUP, NSS_PREGAME, &OnGameSetup, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_ASSIGN_PLAYER, NSS_PREGAME, &OnAssignPlayer, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_KICKED, NSS_PREGAME, &OnKickPlayer, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_GAME_START, NSS_PREGAME, &OnGameStart, session);
session->AddTransition(NSS_PREGAME, (uint)NMT_LOADED_GAME, NSS_INGAME, &OnLoadedGame, session);
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_KICKED, NSS_JOIN_SYNCING, &OnKickPlayer, context);
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, &OnDisconnect, context);
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NSS_INGAME, &OnJoinSyncingLoadedGame, context);
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_KICKED, NSS_JOIN_SYNCING, &OnKickPlayer, session);
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, &OnDisconnect, session);
session->AddTransition(NSS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NSS_INGAME, &OnJoinSyncingLoadedGame, session);
session->AddTransition(NSS_INGAME, (uint)NMT_REJOINED, NSS_INGAME, &OnRejoined, context);
session->AddTransition(NSS_INGAME, (uint)NMT_KICKED, NSS_INGAME, &OnKickPlayer, context);
session->AddTransition(NSS_INGAME, (uint)NMT_CLIENT_PAUSED, NSS_INGAME, &OnClientPaused, context);
session->AddTransition(NSS_INGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, &OnDisconnect, context);
session->AddTransition(NSS_INGAME, (uint)NMT_CHAT, NSS_INGAME, &OnChat, context);
session->AddTransition(NSS_INGAME, (uint)NMT_SIMULATION_COMMAND, NSS_INGAME, &OnSimulationCommand, context);
session->AddTransition(NSS_INGAME, (uint)NMT_SYNC_CHECK, NSS_INGAME, &OnSyncCheck, context);
session->AddTransition(NSS_INGAME, (uint)NMT_END_COMMAND_BATCH, NSS_INGAME, &OnEndCommandBatch, context);
session->AddTransition(NSS_INGAME, (uint)NMT_REJOINED, NSS_INGAME, &OnRejoined, session);
session->AddTransition(NSS_INGAME, (uint)NMT_KICKED, NSS_INGAME, &OnKickPlayer, session);
session->AddTransition(NSS_INGAME, (uint)NMT_CLIENT_PAUSED, NSS_INGAME, &OnClientPaused, session);
session->AddTransition(NSS_INGAME, (uint)NMT_CONNECTION_LOST, NSS_UNCONNECTED, &OnDisconnect, session);
session->AddTransition(NSS_INGAME, (uint)NMT_CHAT, NSS_INGAME, &OnChat, session);
session->AddTransition(NSS_INGAME, (uint)NMT_SIMULATION_COMMAND, NSS_INGAME, &OnSimulationCommand, session);
session->AddTransition(NSS_INGAME, (uint)NMT_SYNC_CHECK, NSS_INGAME, &OnSyncCheck, session);
session->AddTransition(NSS_INGAME, (uint)NMT_END_COMMAND_BATCH, NSS_INGAME, &OnEndCommandBatch, session);
// Set first state
session->SetFirstState(NSS_HANDSHAKE);
@ -874,11 +872,10 @@ void CNetServerWorker::ProcessLobbyAuth(const CStr& name, const CStr& token)
(*it)->SendMessage(&emptyMessage);
}
bool CNetServerWorker::OnClientHandshake(void* context, CFsmEvent* event)
bool CNetServerWorker::OnClientHandshake(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENT_HANDSHAKE);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CCliHandshakeMessage* message = (CCliHandshakeMessage*)event->GetParamRef();
@ -922,11 +919,10 @@ bool CNetServerWorker::OnClientHandshake(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
bool CNetServerWorker::OnAuthenticate(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
// Prohibit joins while the game is loading
@ -1145,11 +1141,11 @@ bool CNetServerWorker::OnAuthenticate(void* context, CFsmEvent* event)
session->SetNextState(NSS_JOIN_SYNCING);
return true;
}
bool CNetServerWorker::OnSimulationCommand(void* context, CFsmEvent* event)
bool CNetServerWorker::OnSimulationCommand(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_SIMULATION_COMMAND);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CSimulationMessage* message = (CSimulationMessage*)event->GetParamRef();
@ -1183,11 +1179,10 @@ bool CNetServerWorker::OnSimulationCommand(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnSyncCheck(void* context, CFsmEvent* event)
bool CNetServerWorker::OnSyncCheck(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_SYNC_CHECK);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CSyncCheckMessage* message = (CSyncCheckMessage*)event->GetParamRef();
@ -1196,11 +1191,10 @@ bool CNetServerWorker::OnSyncCheck(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnEndCommandBatch(void* context, CFsmEvent* event)
bool CNetServerWorker::OnEndCommandBatch(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CEndCommandBatchMessage* message = (CEndCommandBatchMessage*)event->GetParamRef();
@ -1210,11 +1204,10 @@ bool CNetServerWorker::OnEndCommandBatch(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnChat(void* context, CFsmEvent* event)
bool CNetServerWorker::OnChat(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CHAT);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CChatMessage* message = (CChatMessage*)event->GetParamRef();
@ -1226,11 +1219,10 @@ bool CNetServerWorker::OnChat(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnReady(void* context, CFsmEvent* event)
bool CNetServerWorker::OnReady(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_READY);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
// Occurs if a client presses not-ready
@ -1247,11 +1239,10 @@ bool CNetServerWorker::OnReady(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnClearAllReady(void* context, CFsmEvent* event)
bool CNetServerWorker::OnClearAllReady(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CLEAR_ALL_READY);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
if (session->GetGUID() == server.m_ControllerGUID)
@ -1260,11 +1251,10 @@ bool CNetServerWorker::OnClearAllReady(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event)
bool CNetServerWorker::OnGameSetup(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_GAME_SETUP);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
// Changing the settings after gamestart is not implemented and would cause an Out-of-sync error.
@ -1284,10 +1274,9 @@ bool CNetServerWorker::OnGameSetup(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event)
bool CNetServerWorker::OnAssignPlayer(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_ASSIGN_PLAYER);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
if (session->GetGUID() == server.m_ControllerGUID)
@ -1298,10 +1287,9 @@ bool CNetServerWorker::OnAssignPlayer(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnGameStart(void* context, CFsmEvent* event)
bool CNetServerWorker::OnGameStart(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_GAME_START);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
if (session->GetGUID() != server.m_ControllerGUID)
@ -1312,11 +1300,10 @@ bool CNetServerWorker::OnGameStart(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event)
bool CNetServerWorker::OnLoadedGame(CNetServerSession* loadedSession, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
CNetServerSession* loadedSession = (CNetServerSession*)context;
CNetServerWorker& server = loadedSession->GetServer();
// We're in the loading state, so wait until every client has loaded
@ -1343,7 +1330,7 @@ bool CNetServerWorker::OnLoadedGame(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnJoinSyncingLoadedGame(void* context, CFsmEvent* event)
bool CNetServerWorker::OnJoinSyncingLoadedGame(CNetServerSession* session, CFsmEvent* event)
{
// A client rejoining an in-progress game has now finished loading the
// map and deserialized the initial state.
@ -1358,7 +1345,6 @@ bool CNetServerWorker::OnJoinSyncingLoadedGame(void* context, CFsmEvent* event)
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CLoadedGameMessage* message = (CLoadedGameMessage*)event->GetParamRef();
@ -1396,12 +1382,11 @@ bool CNetServerWorker::OnJoinSyncingLoadedGame(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnRejoined(void* context, CFsmEvent* event)
bool CNetServerWorker::OnRejoined(CNetServerSession* session, CFsmEvent* event)
{
// A client has finished rejoining and the loading screen disappeared.
ENSURE(event->GetType() == (uint)NMT_REJOINED);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
// Inform everyone of the client having rejoined
@ -1421,11 +1406,10 @@ bool CNetServerWorker::OnRejoined(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnKickPlayer(void* context, CFsmEvent* event)
bool CNetServerWorker::OnKickPlayer(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_KICKED);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
if (session->GetGUID() == server.m_ControllerGUID)
@ -1436,11 +1420,10 @@ bool CNetServerWorker::OnKickPlayer(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnDisconnect(void* context, CFsmEvent* event)
bool CNetServerWorker::OnDisconnect(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CONNECTION_LOST);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
server.OnUserLeave(session);
@ -1448,11 +1431,10 @@ bool CNetServerWorker::OnDisconnect(void* context, CFsmEvent* event)
return true;
}
bool CNetServerWorker::OnClientPaused(void* context, CFsmEvent* event)
bool CNetServerWorker::OnClientPaused(CNetServerSession* session, CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED);
CNetServerSession* session = (CNetServerSession*)context;
CNetServerWorker& server = session->GetServer();
CClientPausedMessage* message = (CClientPausedMessage*)event->GetParamRef();

View File

@ -294,23 +294,23 @@ private:
void OnUserJoin(CNetServerSession* session);
void OnUserLeave(CNetServerSession* session);
static bool OnClientHandshake(void* context, CFsmEvent* event);
static bool OnAuthenticate(void* context, CFsmEvent* event);
static bool OnSimulationCommand(void* context, CFsmEvent* event);
static bool OnSyncCheck(void* context, CFsmEvent* event);
static bool OnEndCommandBatch(void* context, CFsmEvent* event);
static bool OnChat(void* context, CFsmEvent* event);
static bool OnReady(void* context, CFsmEvent* event);
static bool OnClearAllReady(void* context, CFsmEvent* event);
static bool OnGameSetup(void* context, CFsmEvent* event);
static bool OnAssignPlayer(void* context, CFsmEvent* event);
static bool OnGameStart(void* context, CFsmEvent* event);
static bool OnLoadedGame(void* context, CFsmEvent* event);
static bool OnJoinSyncingLoadedGame(void* context, CFsmEvent* event);
static bool OnRejoined(void* context, CFsmEvent* event);
static bool OnKickPlayer(void* context, CFsmEvent* event);
static bool OnDisconnect(void* context, CFsmEvent* event);
static bool OnClientPaused(void* context, CFsmEvent* event);
static bool OnClientHandshake(CNetServerSession* session, CFsmEvent* event);
static bool OnAuthenticate(CNetServerSession* session, CFsmEvent* event);
static bool OnSimulationCommand(CNetServerSession* session, CFsmEvent* event);
static bool OnSyncCheck(CNetServerSession* session, CFsmEvent* event);
static bool OnEndCommandBatch(CNetServerSession* session, CFsmEvent* event);
static bool OnChat(CNetServerSession* session, CFsmEvent* event);
static bool OnReady(CNetServerSession* session, CFsmEvent* event);
static bool OnClearAllReady(CNetServerSession* session, CFsmEvent* event);
static bool OnGameSetup(CNetServerSession* session, CFsmEvent* event);
static bool OnAssignPlayer(CNetServerSession* session, CFsmEvent* event);
static bool OnGameStart(CNetServerSession* session, CFsmEvent* event);
static bool OnLoadedGame(CNetServerSession* session, CFsmEvent* event);
static bool OnJoinSyncingLoadedGame(CNetServerSession* session, CFsmEvent* event);
static bool OnRejoined(CNetServerSession* session, CFsmEvent* event);
static bool OnKickPlayer(CNetServerSession* session, CFsmEvent* event);
static bool OnDisconnect(CNetServerSession* session, CFsmEvent* event);
static bool OnClientPaused(CNetServerSession* session, CFsmEvent* event);
/**
* Checks if all clients have finished loading.

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2022 Wildfire Games.
/* Copyright (C) 2024 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -151,7 +151,7 @@ private:
* Thread-safety:
* - This is constructed and used by CNetServerWorker in the network server thread.
*/
class CNetServerSession : public CFsm, public INetSession
class CNetServerSession : public CFsm<CNetServerSession>, public INetSession
{
NONCOPYABLE(CNetServerSession);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2023 Wildfire Games.
/* Copyright (C) 2024 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -29,13 +29,13 @@ class TestFSM : public CxxTest::TestSuite
};
template<size_t N>
static bool IncrementGlobal(void* state, CFsmEvent*)
static bool IncrementGlobal(FSMGlobalState* state, CFsmEvent*)
{
++std::get<N>(reinterpret_cast<FSMGlobalState*>(state)->occurCount);
++std::get<N>(state->occurCount);
return true;
}
static bool IncrementParam(void*, CFsmEvent* event)
static bool IncrementParam(FSMGlobalState*, CFsmEvent* event)
{
++*reinterpret_cast<size_t*>(event->GetParamRef());
return true;
@ -60,7 +60,7 @@ public:
void test_global()
{
FSMGlobalState globalState;
CFsm FSMObject;
CFsm<FSMGlobalState> FSMObject;
/*
Corresponding pseudocode
@ -83,16 +83,16 @@ public:
FSMObject.AddTransition(static_cast<unsigned int>(State::ZERO),
static_cast<unsigned int>(Instruction::TO_ONE), static_cast<unsigned int>(State::ONE),
&IncrementGlobal<1>, static_cast<void*>(&globalState));
&IncrementGlobal<1>, &globalState);
FSMObject.AddTransition(static_cast<unsigned int>(State::ONE),
static_cast<unsigned int>(Instruction::TO_TWO), static_cast<unsigned int>(State::TWO),
&IncrementGlobal<2>, static_cast<void*>(&globalState));
&IncrementGlobal<2>, &globalState);
FSMObject.AddTransition(static_cast<unsigned int>(State::ONE),
static_cast<unsigned int>(Instruction::TO_ZERO), static_cast<unsigned int>(State::ZERO),
&IncrementGlobal<0>, static_cast<void*>(&globalState));
&IncrementGlobal<0>, &globalState);
FSMObject.AddTransition(static_cast<unsigned int>(State::TWO),
static_cast<unsigned int>(Instruction::TO_ZERO), static_cast<unsigned int>(State::ZERO),
&IncrementGlobal<0>, static_cast<void*>(&globalState));
&IncrementGlobal<0>, &globalState);
FSMObject.SetFirstState(static_cast<unsigned int>(State::ZERO));
@ -125,7 +125,7 @@ public:
void test_param()
{
FSMGlobalState globalState;
CFsm FSMObject;
CFsm<FSMGlobalState> FSMObject;
// Equal to the FSM in test_global.
FSMObject.AddTransition(static_cast<unsigned int>(State::ZERO),