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:
parent
53f9faa4e0
commit
3a5ad160f7
@ -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};
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user