Index: source/gui/scripting/ScriptFunctions.cpp
===================================================================
--- source/gui/scripting/ScriptFunctions.cpp
+++ source/gui/scripting/ScriptFunctions.cpp
@@ -37,7 +37,6 @@
#include "lobby/scripting/JSInterface_Lobby.h"
#include "maths/FixedVector3D.h"
#include "network/NetClient.h"
-#include "network/NetMessage.h"
#include "network/NetServer.h"
#include "ps/CConsole.h"
#include "ps/CLogger.h"
Index: source/network/Fsm.h
===================================================================
--- /dev/null
+++ source/network/Fsm.h
@@ -0,0 +1,121 @@
+/* Copyright (C) 2017 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see .
+ */
+
+#ifndef FSM_H
+#define FSM_H
+
+#include "NetMessageBuffer.h"
+
+class CFsmEvent;
+class CFsmTransition;
+class CFsm;
+
+using Action = bool(*)(void* pContext, const CFsmEvent* pEvent);
+
+struct StoredAction
+{
+ Action m_Function;
+ void* m_Context;
+};
+
+/**
+ * Represents a signal in the state machine that a change has occurred.
+ * The CFsmEvent objects are under the control of CFsm so
+ * they are created and deleted via CFsm.
+ */
+class CFsmEvent
+{
+public:
+ CFsmEvent(u32 type, const CNetMessageBuffer* buffer = nullptr);
+
+ u32 GetType() const;
+ const CNetMessageBuffer& GetMessageBuffer() const;
+ void SetMessage(const CNetMessageBuffer& buffer);
+
+private:
+ const CNetMessageBuffer* m_Buffer;
+ u32 m_Type;
+};
+
+/**
+ * An association of event, condition, action and next state.
+ */
+class CFsmTransition
+{
+public:
+ CFsmTransition(u32 state, u32 eventType, u32 nextState, StoredAction action);
+
+ u32 GetCurrState() const;
+ u32 GetEventType() const;
+ u32 GetNextState() const;
+ bool RunAction(CFsmEvent* event) const;
+
+private:
+ u32 m_CurrState;
+ u32 m_EventType;
+ u32 m_NextState;
+ StoredAction m_Action;
+};
+
+/**
+ * Manages states, events, actions and transitions
+ * between states. It provides an interface for advertising
+ * events and track the current state. The implementation is
+ * a Mealy state machine, so the system respond to events
+ * and execute some action.
+ *
+ * A Mealy state machine has behaviour associated with state
+ * transitions; Mealy machines are event driven where an
+ * event triggers a state transition
+ */
+class CFsm
+{
+public:
+ CFsm(u32 firstState);
+ virtual ~CFsm() {}
+
+ void AddTransition(u32 state, u32 eventType, u32 nextState);
+ void AddTransition(u32 state, u32 eventType, u32 nextState, Action action, void* context);
+
+ void SetCurrState(u32 state);
+ u32 GetCurrState() const;
+ void SetNextState(u32 nextState);
+
+ bool Update(u32 type, const CNetMessageBuffer* message);
+
+private:
+ const u32 INVALID_STATE = ~0;
+
+ using StateSet = std::set;
+ using EventSet = std::set;
+ using TransitionList = std::vector;
+
+ const CFsmTransition* GetTransition(u32 state, u32 eventType) const;
+ void AddState(u32 state);
+ void AddEvent(u32 eventType);
+ bool IsValidState(u32 state) const;
+ bool IsValidEvent(u32 eventType) const;
+
+ u32 m_FirstState;
+ u32 m_CurrState;
+ u32 m_NextState;
+ StateSet m_States;
+ EventSet m_Events;
+ TransitionList m_Transitions;
+};
+
+#endif // FSM_H
Index: source/network/Fsm.cpp
===================================================================
--- /dev/null
+++ source/network/Fsm.cpp
@@ -0,0 +1,169 @@
+/* Copyright (C) 2017 Wildfire Games.
+ * This file is part of 0 A.D.
+ *
+ * 0 A.D. is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 0 A.D. is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with 0 A.D. If not, see .
+ */
+
+#include "precompiled.h"
+#include "Fsm.h"
+
+CFsmEvent::CFsmEvent(u32 type, const CNetMessageBuffer* buffer) :
+ m_Buffer(buffer),
+ m_Type(type)
+{
+}
+
+u32 CFsmEvent::GetType() const
+{
+ return m_Type;
+}
+
+const CNetMessageBuffer& CFsmEvent::GetMessageBuffer() const
+{
+ ENSURE(m_Buffer);
+ return *m_Buffer;
+}
+
+void CFsmEvent::SetMessage(const CNetMessageBuffer& buffer)
+{
+ m_Buffer = &buffer;
+}
+
+CFsmTransition::CFsmTransition(u32 state, u32 eventType, u32 nextState, StoredAction action) :
+ m_CurrState(state),
+ m_EventType(eventType),
+ m_NextState(nextState),
+ m_Action(action)
+{
+}
+
+u32 CFsmTransition::GetCurrState() const
+{
+ return m_CurrState;
+}
+
+u32 CFsmTransition::GetEventType() const
+{
+ return m_EventType;
+}
+
+u32 CFsmTransition::GetNextState() const
+{
+ return m_NextState;
+}
+
+bool CFsmTransition::RunAction(CFsmEvent* event) const
+{
+ bool result = true;
+
+ if (m_Action.m_Function)
+ result &= m_Action.m_Function(m_Action.m_Context, event);
+
+ return result;
+}
+
+CFsm::CFsm(u32 firstState) :
+ m_FirstState(firstState),
+ m_CurrState(firstState),
+ m_NextState(INVALID_STATE)
+{
+}
+
+void CFsm::AddTransition(u32 state, u32 eventType, u32 nextState)
+{
+ AddState(state);
+ AddEvent(eventType);
+ AddState(nextState);
+
+ m_Transitions.push_back(CFsmTransition(state, eventType, nextState, StoredAction{nullptr, nullptr}));
+}
+
+void CFsm::AddTransition(u32 state, u32 eventType, u32 nextState, Action action, void* context )
+{
+ AddState(state);
+ AddEvent(eventType);
+ AddState(nextState);
+
+ m_Transitions.push_back(CFsmTransition(state, eventType, nextState, StoredAction{action, context}));
+}
+
+void CFsm::SetCurrState(u32 state)
+{
+ m_CurrState = state;
+}
+
+u32 CFsm::GetCurrState() const
+{
+ return m_CurrState;
+}
+
+void CFsm::SetNextState(u32 nextState)
+{
+ m_NextState = nextState;
+}
+
+bool CFsm::Update(u32 type, const CNetMessageBuffer* message)
+{
+ const CFsmTransition* transition = GetTransition(m_CurrState, type);
+ if (!transition)
+ return false;
+
+ // Save the default state transition (actions might call SetNextState to override this)
+ SetNextState(transition->GetNextState());
+
+ CFsmEvent event(type, message);
+ if (!transition->RunAction(&event))
+ return false;
+
+ m_CurrState = m_NextState;
+
+ SetNextState(INVALID_STATE);
+
+ return true;
+}
+
+const CFsmTransition* CFsm::GetTransition(u32 state, u32 eventType) const
+{
+ if (!IsValidState(state) || !IsValidEvent(eventType))
+ return nullptr;
+
+ TransitionList::const_iterator it = std::find_if(m_Transitions.begin(), m_Transitions.end(), [state, eventType](const CFsmTransition& transition) {
+ return transition.GetCurrState() == state && transition.GetEventType() == eventType;
+ });
+
+ if (it == m_Transitions.end())
+ return nullptr;
+
+ return &(*it);
+}
+
+void CFsm::AddState(u32 state)
+{
+ m_States.insert(state);
+}
+
+void CFsm::AddEvent(u32 eventType)
+{
+ m_Events.insert(eventType);
+}
+
+bool CFsm::IsValidState(u32 state) const
+{
+ return m_States.find(state) != m_States.end();
+}
+
+bool CFsm::IsValidEvent(u32 eventType) const
+{
+ return m_Events.find(eventType) != m_Events.end();
+}
Index: source/network/NMTCreator.h
===================================================================
--- source/network/NMTCreator.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Copyright (C) 2015 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D. If not, see .
- */
-
-#include "Serialization.h"
-#include
-
-// If included from within the NMT Creation process, perform a pass
-#ifdef CREATING_NMT
-
-#include NMT_CREATE_HEADER_NAME
-
-#undef START_NMTS
-#undef END_NMTS
-#undef START_NMT_CLASS
-#undef START_NMT_CLASS_DERIVED
-#undef NMT_FIELD_INT
-#undef NMT_FIELD
-#undef NMT_START_ARRAY
-#undef NMT_END_ARRAY
-#undef END_NMT_CLASS
-
-#else
-// If not within the creation process, and called with argument, perform the
-// creation process with the header specified
-#ifdef NMT_CREATE_HEADER_NAME
-
-#ifndef ARRAY_STRUCT_PREFIX
-#define ARRAY_STRUCT_PREFIX(_nm) S_##_nm
-#endif
-
-#define CREATING_NMT
-
-#ifndef NMT_CREATOR_IMPLEMENT
-
-/*************************************************************************/
-// Pass 1, class definition
-#define NMT_CREATOR_PASS_CLASSDEF
-#define START_NMTS()
-#define END_NMTS()
-
-#define START_NMT_CLASS(_nm, _tp) \
- START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
-
-/**
- * Start the definition of a network message type.
- *
- * @param _base The name of the base class of the message
- * @param _nm The name of the class
- * @param _tp The NetMessageType associated with the class. It is *not* safe to
- * have several classes with the same value of _tp in the same executable
- */
-#define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
-CNetMessage *Deserialize##_nm(const u8 *, size_t); \
-class _nm: public _base \
-{ \
-protected: \
- _nm(NetMessageType type): _base(type) {}\
- \
- /* This one is for subclasses that want to use the base class' string */ \
- /* converters to get SubMessage { , ... } */ \
- CStr ToStringRaw() const;\
-public: \
- _nm(): _base(_tp) {} \
- virtual size_t GetSerializedLength() const; \
- virtual u8 *Serialize(u8 *buffer) const; \
- virtual const u8 *Deserialize(const u8 *pos, const u8 *end); \
- virtual CStr ToString() const; \
- inline operator CStr () const \
- { return ToString(); }
-
-/**
- * Add an integer field to the message type.
- *
- * @param _nm The name of the field
- * @param _hosttp The local type of the field (the data type used in the field
- * definition)
- * @param _netsz The number of bytes that should be serialized. If the variable
- * has a value larger than the maximum value of the specified network size,
- * higher order bytes will be discarded.
- */
-#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
- _hosttp _nm;
-
-/**
- * Add a generic field to the message type. The data type must be a class
- * implementing the ISerializable interface
- *
- * @param _tp The local data type of the field
- * @param _nm The name of the field
- * @see ISerializable
- */
-#define NMT_FIELD(_tp, _nm) \
- _tp _nm;
-
-#define NMT_START_ARRAY(_nm) \
- struct ARRAY_STRUCT_PREFIX(_nm); \
- std::vector _nm; \
- struct ARRAY_STRUCT_PREFIX(_nm) {
-
-#define NMT_END_ARRAY() \
- };
-
-#define END_NMT_CLASS() };
-
-#include "NMTCreator.h"
-#undef NMT_CREATOR_PASS_CLASSDEF
-
-#else // NMT_CREATOR_IMPLEMENT
-
-#include "StringConverters.h"
-
-/*************************************************************************/
-// Pass 2, GetSerializedLength
-#define NMT_CREATOR_PASS_GETLENGTH
-#define START_NMTS()
-#define END_NMTS()
-
-#define START_NMT_CLASS(_nm, _tp) \
- START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
-#define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
-size_t _nm::GetSerializedLength() const \
-{ \
- size_t ret=_base::GetSerializedLength(); \
- const _nm *thiz=this;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_START_ARRAY(_nm) \
- std::vector ::const_iterator it=_nm.begin(); \
- while (it != _nm.end()) \
- { \
- const ARRAY_STRUCT_PREFIX(_nm) *thiz=&*it;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_END_ARRAY() \
- ++it; \
- }
-
-#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
- ret += _netsz;
-
-#define NMT_FIELD(_tp, _nm) \
- ret += thiz->_nm.GetSerializedLength();
-
-#define END_NMT_CLASS() \
- return ret; \
-};
-
-#include "NMTCreator.h"
-#undef NMT_CREATOR_PASS_GETLENGTH
-
-/*************************************************************************/
-// Pass 3, Serialize
-
-#define NMT_CREATOR_PASS_SERIALIZE
-
-#define START_NMTS()
-#define END_NMTS()
-
-#define START_NMT_CLASS(_nm, _tp) \
- START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
-#define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
-u8 *_nm::Serialize(u8 *buffer) const \
-{ \
- /*printf("In " #_nm "::Serialize()\n");*/ \
- u8 *pos=_base::Serialize(buffer); \
- const _nm *thiz=this;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_START_ARRAY(_nm) \
- std::vector ::const_iterator it=_nm.begin(); \
- while (it != _nm.end()) \
- { \
- const ARRAY_STRUCT_PREFIX(_nm) *thiz=&*it;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_END_ARRAY() \
- ++it; \
- }
-
-#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
- Serialize_int_##_netsz(pos, thiz->_nm); \
-
-#define NMT_FIELD(_tp, _nm) \
- pos=thiz->_nm.Serialize(pos);
-
-#define END_NMT_CLASS() \
- return pos; \
-}
-
-#include "NMTCreator.h"
-
-#undef NMT_CREATOR_PASS_SERIALIZE
-
-/*************************************************************************/
-// Pass 4, Deserialize
-
-#define NMT_CREATOR_PASS_DESERIALIZE
-
-#define START_NMTS()
-#define END_NMTS()
-
-#define BAIL_DESERIALIZER return NULL
-
-#define START_NMT_CLASS(_nm, _tp) \
- START_NMT_CLASS_DERIVED(CNetMessage, _nm, _tp)
-#define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
-const u8 *_nm::Deserialize(const u8 *pos, const u8 *end) \
-{ \
- pos=_base::Deserialize(pos, end); \
- _nm *thiz=this; \
- /*printf("In Deserialize" #_nm "\n"); */\
- UNUSED2(thiz); // preempt any "unused" warning
-
-
-#define NMT_START_ARRAY(_nm) \
- while (pos < end) \
- { \
- ARRAY_STRUCT_PREFIX(_nm) *thiz=&*_nm.insert(_nm.end(), ARRAY_STRUCT_PREFIX(_nm)());\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_END_ARRAY() \
- }
-
-#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
- if (pos+_netsz > end) BAIL_DESERIALIZER; \
- Deserialize_int_##_netsz(pos, thiz->_nm); \
- /*printf("\t" #_nm " == 0x%x\n", thiz->_nm);*/
-
-#define NMT_FIELD(_tp, _nm) \
- if ((pos=thiz->_nm.Deserialize(pos, end)) == NULL) BAIL_DESERIALIZER;
-
-#define END_NMT_CLASS() \
- return pos; \
-}
-
-#include "NMTCreator.h"
-
-#undef BAIL_DESERIALIZER
-
-#undef NMT_CREATOR_PASS_DESERIALIZE
-
-/*************************************************************************/
-// Pass 5, String Representation
-
-#define START_NMTS()
-#define END_NMTS()
-
-#define START_NMT_CLASS(_nm, _tp) \
-CStr _nm::ToString() const \
-{ \
- CStr ret=#_nm " { "; \
- return ret + ToStringRaw() + " }"; \
-} \
-CStr _nm::ToStringRaw() const \
-{ \
- CStr ret; \
- const _nm *thiz=this;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define START_NMT_CLASS_DERIVED(_base, _nm, _tp) \
-CStr _nm::ToString() const \
-{ \
- CStr ret=#_nm " { "; \
- return ret + ToStringRaw() + " }"; \
-} \
-CStr _nm::ToStringRaw() const \
-{ \
- CStr ret=_base::ToStringRaw() + ", "; \
- const _nm *thiz=this;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_START_ARRAY(_nm) \
- ret+=#_nm ": { "; \
- std::vector < ARRAY_STRUCT_PREFIX(_nm) >::const_iterator it=_nm.begin(); \
- while (it != _nm.end()) \
- { \
- ret+=" { "; \
- const ARRAY_STRUCT_PREFIX(_nm) *thiz=&*it;\
- UNUSED2(thiz); // preempt any "unused" warning
-
-#define NMT_END_ARRAY() \
- ++it; \
- ret=ret.substr(0, ret.length()-2)+" }, "; \
- } \
- ret=ret.substr(0, ret.length()-2)+" }, ";
-
-#define NMT_FIELD_INT(_nm, _hosttp, _netsz) \
- ret += #_nm ": "; \
- ret += NetMessageStringConvert(thiz->_nm); \
- ret += ", ";
-
-#define NMT_FIELD(_tp, _nm) \
- ret += #_nm ": "; \
- ret += NetMessageStringConvert(thiz->_nm); \
- ret += ", ";
-
-#define END_NMT_CLASS() \
- return ret.substr(0, ret.length()-2); \
-}
-
-#include "NMTCreator.h"
-
-#endif // #ifdef NMT_CREATOR_IMPLEMENT
-
-/*************************************************************************/
-// Cleanup
-#undef NMT_CREATE_HEADER_NAME
-#undef NMT_CREATOR_IMPLEMENT
-#undef CREATING_NMT
-
-#endif // #ifdef NMT_CREATE_HEADER_NAME
-#endif // #ifndef CREATING_NMT
Index: source/network/NetClient.h
===================================================================
--- source/network/NetClient.h
+++ source/network/NetClient.h
@@ -18,7 +18,7 @@
#ifndef NETCLIENT_H
#define NETCLIENT_H
-#include "network/fsm.h"
+#include "network/Fsm.h"
#include "network/NetFileTransfer.h"
#include "network/NetHost.h"
#include "scriptinterface/ScriptVal.h"
@@ -164,7 +164,7 @@
* @param message message to send
* @return true on success
*/
- bool SendMessage(const CNetMessage* message);
+ bool SendMessage(const CNetMessageBuffer& message);
/**
* Call when the network connection has been successfully initiated.
@@ -179,7 +179,7 @@
/**
* Call when a message has been received from the network.
*/
- bool HandleMessage(CNetMessage* message);
+ bool HandleMessage(const CNetMessageBuffer& message);
/**
* Call when the game has started and all data files have been loaded,
@@ -217,25 +217,25 @@
private:
// 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 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(void* context, const CFsmEvent* event);
+ static bool OnHandshake(void* context, const CFsmEvent* event);
+ static bool OnHandshakeResponse(void* context, const CFsmEvent* event);
+ static bool OnAuthenticate(void* context, const CFsmEvent* event);
+ static bool OnChat(void* context, const CFsmEvent* event);
+ static bool OnReady(void* context, const CFsmEvent* event);
+ static bool OnGameSetup(void* context, const CFsmEvent* event);
+ static bool OnPlayerAssignment(void* context, const CFsmEvent* event);
+ static bool OnInGame(void* context, const CFsmEvent* event);
+ static bool OnGameStart(void* context, const CFsmEvent* event);
+ static bool OnJoinSyncStart(void* context, const CFsmEvent* event);
+ static bool OnJoinSyncEndCommandBatch(void* context, const CFsmEvent* event);
+ static bool OnRejoined(void* context, const CFsmEvent* event);
+ static bool OnKicked(void* context, const CFsmEvent* event);
+ static bool OnClientTimeout(void* context, const CFsmEvent* event);
+ static bool OnClientPerformance(void* context, const CFsmEvent* event);
+ static bool OnClientsLoading(void* context, const CFsmEvent* event);
+ static bool OnClientPaused(void* context, const CFsmEvent* event);
+ static bool OnLoadedGame(void* context, const CFsmEvent* event);
/**
* Take ownership of a session object, and use it for all network communication.
Index: source/network/NetClient.cpp
===================================================================
--- source/network/NetClient.cpp
+++ source/network/NetClient.cpp
@@ -20,7 +20,6 @@
#include "NetClient.h"
#include "NetClientTurnManager.h"
-#include "NetMessage.h"
#include "NetSession.h"
#include "lib/byte_order.h"
@@ -59,7 +58,7 @@
// Pretend the server told us to start the game
CGameStartMessage start;
- m_Client.HandleMessage(&start);
+ m_Client.HandleMessage(CNetMessageBuffer(start));
}
private:
@@ -67,13 +66,17 @@
};
CNetClient::CNetClient(CGame* game, bool isLocalClient) :
- m_Session(NULL),
+ CFsm(NCS_UNCONNECTED),
+ m_Game(game),
m_UserName(L"anonymous"),
- m_GUID(ps_generate_guid()), m_HostID((u32)-1), m_ClientTurnManager(NULL), m_Game(game),
- m_GameAttributes(game->GetSimulation2()->GetScriptInterface().GetContext()),
+ m_Session(NULL),
+ m_ClientTurnManager(NULL),
+ m_HostID((u32)-1),
+ m_Rejoin(false),
m_IsLocalClient(isLocalClient),
- m_LastConnectionCheck(0),
- m_Rejoin(false)
+ m_GameAttributes(game->GetSimulation2()->GetScriptInterface().GetContext()),
+ m_GUID(ps_generate_guid()),
+ m_LastConnectionCheck(0)
{
m_Game->SetTurnManager(NULL); // delete the old local turn manager so we don't accidentally use it
@@ -82,61 +85,58 @@
JS_AddExtraGCRootsTracer(GetScriptInterface().GetJSRuntime(), CNetClient::Trace, this);
// Set up transitions for session
- AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, (void*)&OnConnect, context);
-
- AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, (void*)&OnHandshake, context);
-
- AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, (void*)&OnHandshakeResponse, context);
-
- AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_INITIAL_GAMESETUP, (void*)&OnAuthenticate, context);
-
- AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
-
- AddTransition(NCS_PREGAME, (uint)NMT_CHAT, NCS_PREGAME, (void*)&OnChat, context);
- AddTransition(NCS_PREGAME, (uint)NMT_READY, NCS_PREGAME, (void*)&OnReady, context);
- AddTransition(NCS_PREGAME, (uint)NMT_GAME_SETUP, NCS_PREGAME, (void*)&OnGameSetup, context);
- AddTransition(NCS_PREGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_PREGAME, (void*)&OnPlayerAssignment, context);
- AddTransition(NCS_PREGAME, (uint)NMT_KICKED, NCS_PREGAME, (void*)&OnKicked, context);
- AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_PREGAME, (void*)&OnClientTimeout, context);
- AddTransition(NCS_PREGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_PREGAME, (void*)&OnClientPerformance, context);
- AddTransition(NCS_PREGAME, (uint)NMT_GAME_START, NCS_LOADING, (void*)&OnGameStart, context);
- AddTransition(NCS_PREGAME, (uint)NMT_JOIN_SYNC_START, NCS_JOIN_SYNCING, (void*)&OnJoinSyncStart, context);
-
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CHAT, NCS_JOIN_SYNCING, (void*)&OnChat, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_SETUP, NCS_JOIN_SYNCING, (void*)&OnGameSetup, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_JOIN_SYNCING, (void*)&OnPlayerAssignment, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_KICKED, NCS_JOIN_SYNCING, (void*)&OnKicked, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_TIMEOUT, NCS_JOIN_SYNCING, (void*)&OnClientTimeout, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_CLIENT_PERFORMANCE, NCS_JOIN_SYNCING, (void*)&OnClientPerformance, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_GAME_START, NCS_JOIN_SYNCING, (void*)&OnGameStart, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_SIMULATION_COMMAND, NCS_JOIN_SYNCING, (void*)&OnInGame, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_END_COMMAND_BATCH, NCS_JOIN_SYNCING, (void*)&OnJoinSyncEndCommandBatch, context);
- AddTransition(NCS_JOIN_SYNCING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context);
-
- AddTransition(NCS_LOADING, (uint)NMT_CHAT, NCS_LOADING, (void*)&OnChat, context);
- AddTransition(NCS_LOADING, (uint)NMT_GAME_SETUP, NCS_LOADING, (void*)&OnGameSetup, context);
- AddTransition(NCS_LOADING, (uint)NMT_PLAYER_ASSIGNMENT, NCS_LOADING, (void*)&OnPlayerAssignment, context);
- AddTransition(NCS_LOADING, (uint)NMT_KICKED, NCS_LOADING, (void*)&OnKicked, context);
- AddTransition(NCS_LOADING, (uint)NMT_CLIENT_TIMEOUT, NCS_LOADING, (void*)&OnClientTimeout, context);
- AddTransition(NCS_LOADING, (uint)NMT_CLIENT_PERFORMANCE, NCS_LOADING, (void*)&OnClientPerformance, context);
- AddTransition(NCS_LOADING, (uint)NMT_CLIENTS_LOADING, NCS_LOADING, (void*)&OnClientsLoading, context);
- AddTransition(NCS_LOADING, (uint)NMT_LOADED_GAME, NCS_INGAME, (void*)&OnLoadedGame, context);
-
- AddTransition(NCS_INGAME, (uint)NMT_REJOINED, NCS_INGAME, (void*)&OnRejoined, context);
- AddTransition(NCS_INGAME, (uint)NMT_KICKED, NCS_INGAME, (void*)&OnKicked, context);
- AddTransition(NCS_INGAME, (uint)NMT_CLIENT_TIMEOUT, NCS_INGAME, (void*)&OnClientTimeout, context);
- AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PERFORMANCE, NCS_INGAME, (void*)&OnClientPerformance, context);
- AddTransition(NCS_INGAME, (uint)NMT_CLIENTS_LOADING, NCS_INGAME, (void*)&OnClientsLoading, context);
- AddTransition(NCS_INGAME, (uint)NMT_CLIENT_PAUSED, NCS_INGAME, (void*)&OnClientPaused, context);
- AddTransition(NCS_INGAME, (uint)NMT_CHAT, NCS_INGAME, (void*)&OnChat, context);
- AddTransition(NCS_INGAME, (uint)NMT_GAME_SETUP, NCS_INGAME, (void*)&OnGameSetup, context);
- AddTransition(NCS_INGAME, (uint)NMT_PLAYER_ASSIGNMENT, NCS_INGAME, (void*)&OnPlayerAssignment, context);
- AddTransition(NCS_INGAME, (uint)NMT_SIMULATION_COMMAND, NCS_INGAME, (void*)&OnInGame, context);
- AddTransition(NCS_INGAME, (uint)NMT_SYNC_ERROR, NCS_INGAME, (void*)&OnInGame, context);
- AddTransition(NCS_INGAME, (uint)NMT_END_COMMAND_BATCH, NCS_INGAME, (void*)&OnInGame, context);
-
- // Set first state
- SetFirstState(NCS_UNCONNECTED);
+ AddTransition(NCS_UNCONNECTED, (uint)NMT_CONNECT_COMPLETE, NCS_CONNECT, &OnConnect, context);
+
+ AddTransition(NCS_CONNECT, (uint)NMT_SERVER_HANDSHAKE, NCS_HANDSHAKE, &OnHandshake, context);
+
+ AddTransition(NCS_HANDSHAKE, (uint)NMT_SERVER_HANDSHAKE_RESPONSE, NCS_AUTHENTICATE, &OnHandshakeResponse, context);
+
+ AddTransition(NCS_AUTHENTICATE, (uint)NMT_AUTHENTICATE_RESULT, NCS_INITIAL_GAMESETUP, &OnAuthenticate, context);
+
+ AddTransition(NCS_INITIAL_GAMESETUP, (uint)NMT_GAME_SETUP, NCS_PREGAME, &OnGameSetup, context);
+
+ 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_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_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_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);
}
CNetClient::~CNetClient()
@@ -298,7 +298,7 @@
PushGuiMessage(msg);
}
-bool CNetClient::SendMessage(const CNetMessage* message)
+bool CNetClient::SendMessage(const CNetMessageBuffer& message)
{
if (!m_Session)
return false;
@@ -330,9 +330,8 @@
void CNetClient::SendGameSetupMessage(JS::MutableHandleValue attrs, ScriptInterface& scriptInterface)
{
- CGameSetupMessage gameSetup(scriptInterface);
- gameSetup.m_Data = attrs;
- SendMessage(&gameSetup);
+ CGameSetupMessage gameSetup(scriptInterface, attrs);
+ SendMessage(CNetMessageBuffer(gameSetup));
}
void CNetClient::SendAssignPlayerMessage(const int playerID, const CStr& guid)
@@ -340,39 +339,39 @@
CAssignPlayerMessage assignPlayer;
assignPlayer.m_PlayerID = playerID;
assignPlayer.m_GUID = guid;
- SendMessage(&assignPlayer);
+ SendMessage(CNetMessageBuffer(assignPlayer));
}
void CNetClient::SendChatMessage(const std::wstring& text)
{
CChatMessage chat;
chat.m_Message = text;
- SendMessage(&chat);
+ SendMessage(CNetMessageBuffer(chat));
}
void CNetClient::SendReadyMessage(const int status)
{
CReadyMessage readyStatus;
readyStatus.m_Status = status;
- SendMessage(&readyStatus);
+ SendMessage(CNetMessageBuffer(readyStatus));
}
void CNetClient::SendClearAllReadyMessage()
{
CClearAllReadyMessage clearAllReady;
- SendMessage(&clearAllReady);
+ SendMessage(CNetMessageBuffer(clearAllReady));
}
void CNetClient::SendStartGameMessage()
{
CGameStartMessage gameStart;
- SendMessage(&gameStart);
+ SendMessage(CNetMessageBuffer(gameStart));
}
void CNetClient::SendRejoinedMessage()
{
CRejoinedMessage rejoinedMessage;
- SendMessage(&rejoinedMessage);
+ SendMessage(CNetMessageBuffer(rejoinedMessage));
}
void CNetClient::SendKickPlayerMessage(const CStrW& playerName, bool ban)
@@ -380,17 +379,17 @@
CKickedMessage kickPlayer;
kickPlayer.m_Name = playerName;
kickPlayer.m_Ban = ban;
- SendMessage(&kickPlayer);
+ SendMessage(CNetMessageBuffer(kickPlayer));
}
void CNetClient::SendPausedMessage(bool pause)
{
CClientPausedMessage pausedMessage;
pausedMessage.m_Pause = pause;
- SendMessage(&pausedMessage);
+ SendMessage(CNetMessageBuffer(pausedMessage));
}
-bool CNetClient::HandleMessage(CNetMessage* message)
+bool CNetClient::HandleMessage(const CNetMessageBuffer& message)
{
// Handle non-FSM messages first
@@ -400,9 +399,10 @@
if (status != INFO::SKIPPED)
return false;
- if (message->GetType() == NMT_FILE_TRANSFER_REQUEST)
+ if (message.GetType() == NMT_FILE_TRANSFER_REQUEST)
{
- CFileTransferRequestMessage* reqMessage = (CFileTransferRequestMessage*)message;
+ CFileTransferRequestMessage reqMessage;
+ message.GetMessage(reqMessage);
// TODO: we should support different transfer request types, instead of assuming
// it's always requesting the simulation state
@@ -421,15 +421,15 @@
std::string compressed;
CompressZLib(stream.str(), compressed, true);
- m_Session->GetFileTransferer().StartResponse(reqMessage->m_RequestID, compressed);
+ m_Session->GetFileTransferer().StartResponse(reqMessage.m_RequestID, compressed);
return true;
}
// Update FSM
- bool ok = Update(message->GetType(), message);
+ bool ok = Update(message.GetType(), &message);
if (!ok)
- LOGERROR("Net client: Error running FSM update (type=%d state=%d)", (int)message->GetType(), (int)GetCurrState());
+ LOGERROR("Net client: Error running FSM update (type=%d state=%d)", (int)message.GetType(), (int)GetCurrState());
return ok;
}
@@ -473,10 +473,10 @@
CLoadedGameMessage loaded;
loaded.m_CurrentTurn = m_ClientTurnManager->GetCurrentTurn();
- SendMessage(&loaded);
+ SendMessage(loaded);
}
-bool CNetClient::OnConnect(void* context, CFsmEvent* event)
+bool CNetClient::OnConnect(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CONNECT_COMPLETE);
@@ -492,7 +492,7 @@
return true;
}
-bool CNetClient::OnHandshake(void* context, CFsmEvent* event)
+bool CNetClient::OnHandshake(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE);
@@ -502,12 +502,12 @@
handshake.m_MagicResponse = PS_PROTOCOL_MAGIC_RESPONSE;
handshake.m_ProtocolVersion = PS_PROTOCOL_VERSION;
handshake.m_SoftwareVersion = PS_PROTOCOL_VERSION;
- client->SendMessage(&handshake);
+ client->SendMessage(handshake);
return true;
}
-bool CNetClient::OnHandshakeResponse(void* context, CFsmEvent* event)
+bool CNetClient::OnHandshakeResponse(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_SERVER_HANDSHAKE_RESPONSE);
@@ -518,12 +518,12 @@
authenticate.m_Name = client->m_UserName;
authenticate.m_Password = L""; // TODO
authenticate.m_IsLocalClient = client->m_IsLocalClient;
- client->SendMessage(&authenticate);
+ client->SendMessage(authenticate);
return true;
}
-bool CNetClient::OnAuthenticate(void* context, CFsmEvent* event)
+bool CNetClient::OnAuthenticate(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_AUTHENTICATE_RESULT);
@@ -532,12 +532,13 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CAuthenticateResultMessage* message = (CAuthenticateResultMessage*)event->GetParamRef();
+ CAuthenticateResultMessage message;
+ event->GetMessageBuffer().GetMessage(message);
- LOGMESSAGE("Net: Authentication result: host=%u, %s", message->m_HostID, utf8_from_wstring(message->m_Message));
+ LOGMESSAGE("Net: Authentication result: host=%u, %s", message.m_HostID, utf8_from_wstring(message.m_Message));
- client->m_HostID = message->m_HostID;
- client->m_Rejoin = message->m_Code == ARC_OK_REJOINING;
+ client->m_HostID = message.m_HostID;
+ client->m_Rejoin = message.m_Code == ARC_OK_REJOINING;
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({'type':'netstatus','status':'authenticated'})", &msg);
@@ -547,7 +548,7 @@
return true;
}
-bool CNetClient::OnChat(void* context, CFsmEvent* event)
+bool CNetClient::OnChat(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_CHAT);
@@ -555,18 +556,19 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CChatMessage* message = (CChatMessage*)event->GetParamRef();
+ CChatMessage message;
+ event->GetMessageBuffer().GetMessage(message);
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({'type':'chat'})", &msg);
- client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false);
- client->GetScriptInterface().SetProperty(msg, "text", std::wstring(message->m_Message), false);
+ client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID), false);
+ client->GetScriptInterface().SetProperty(msg, "text", std::wstring(message.m_Message), false);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnReady(void* context, CFsmEvent* event)
+bool CNetClient::OnReady(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_READY);
@@ -574,18 +576,19 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CReadyMessage* message = (CReadyMessage*)event->GetParamRef();
+ CReadyMessage message;
+ event->GetMessageBuffer().GetMessage(message);
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({'type':'ready'})", &msg);
- client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false);
- client->GetScriptInterface().SetProperty(msg, "status", int (message->m_Status), false);
+ client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID), false);
+ client->GetScriptInterface().SetProperty(msg, "status", int (message.m_Status), false);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnGameSetup(void* context, CFsmEvent* event)
+bool CNetClient::OnGameSetup(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_GAME_SETUP);
@@ -593,36 +596,37 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CGameSetupMessage* message = (CGameSetupMessage*)event->GetParamRef();
-
- client->m_GameAttributes = message->m_Data;
+ CGameSetupMessage message(client->GetScriptInterface());
+ event->GetMessageBuffer().GetMessage(message);
+ client->m_GameAttributes = message.m_JSData.m_Data;
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({'type':'gamesetup'})", &msg);
- client->GetScriptInterface().SetProperty(msg, "data", message->m_Data, false);
+ client->GetScriptInterface().SetProperty(msg, "data", message.m_JSData.m_Data, false);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnPlayerAssignment(void* context, CFsmEvent* event)
+bool CNetClient::OnPlayerAssignment(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_PLAYER_ASSIGNMENT);
CNetClient* client = (CNetClient*)context;
- CPlayerAssignmentMessage* message = (CPlayerAssignmentMessage*)event->GetParamRef();
+ CPlayerAssignmentMessage message;
+ event->GetMessageBuffer().GetMessage(message);
// Unpack the message
PlayerAssignmentMap newPlayerAssignments;
- for (size_t i = 0; i < message->m_Hosts.size(); ++i)
+ for (size_t i = 0; i < message.m_Hosts.size(); ++i)
{
PlayerAssignment assignment;
assignment.m_Enabled = true;
- assignment.m_Name = message->m_Hosts[i].m_Name;
- assignment.m_PlayerID = message->m_Hosts[i].m_PlayerID;
- assignment.m_Status = message->m_Hosts[i].m_Status;
- newPlayerAssignments[message->m_Hosts[i].m_GUID] = assignment;
+ assignment.m_Name = message.m_Hosts[i].m_Name;
+ assignment.m_PlayerID = message.m_Hosts[i].m_PlayerID;
+ assignment.m_Status = message.m_Hosts[i].m_Status;
+ newPlayerAssignments[message.m_Hosts[i].m_GUID] = assignment;
}
client->m_PlayerAssignments.swap(newPlayerAssignments);
@@ -632,7 +636,7 @@
return true;
}
-bool CNetClient::OnGameStart(void* context, CFsmEvent* event)
+bool CNetClient::OnGameStart(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_GAME_START);
@@ -658,7 +662,7 @@
return true;
}
-bool CNetClient::OnJoinSyncStart(void* context, CFsmEvent* event)
+bool CNetClient::OnJoinSyncStart(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_JOIN_SYNC_START);
@@ -672,15 +676,16 @@
return true;
}
-bool CNetClient::OnJoinSyncEndCommandBatch(void* context, CFsmEvent* event)
+bool CNetClient::OnJoinSyncEndCommandBatch(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_END_COMMAND_BATCH);
CNetClient* client = (CNetClient*)context;
- CEndCommandBatchMessage* endMessage = (CEndCommandBatchMessage*)event->GetParamRef();
+ CEndCommandBatchMessage endMessage;
+ event->GetMessageBuffer().GetMessage(endMessage);
- client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength);
+ client->m_ClientTurnManager->FinishedAllCommands(endMessage.m_Turn, endMessage.m_TurnLength);
// Execute all the received commands for the latest turn
client->m_ClientTurnManager->UpdateFastForward();
@@ -688,7 +693,7 @@
return true;
}
-bool CNetClient::OnRejoined(void* context, CFsmEvent* event)
+bool CNetClient::OnRejoined(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_REJOINED);
@@ -696,16 +701,17 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CRejoinedMessage* message = (CRejoinedMessage*)event->GetParamRef();
+ CRejoinedMessage message;
+ event->GetMessageBuffer().GetMessage(message);
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({'type':'rejoined'})", &msg);
- client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID), false);
+ client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID), false);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnKicked(void *context, CFsmEvent* event)
+bool CNetClient::OnKicked(void *context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_KICKED);
@@ -713,19 +719,20 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CKickedMessage* message = (CKickedMessage*)event->GetParamRef();
+ CKickedMessage message;
+ event->GetMessageBuffer().GetMessage(message);
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({})", &msg);
- client->GetScriptInterface().SetProperty(msg, "username", message->m_Name);
+ client->GetScriptInterface().SetProperty(msg, "username", message.m_Name);
client->GetScriptInterface().SetProperty(msg, "type", CStr("kicked"));
- client->GetScriptInterface().SetProperty(msg, "banned", message->m_Ban != 0);
+ client->GetScriptInterface().SetProperty(msg, "banned", message.m_Ban != 0);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnClientTimeout(void *context, CFsmEvent* event)
+bool CNetClient::OnClientTimeout(void *context, const CFsmEvent* event)
{
// Report the timeout of some other client
@@ -738,18 +745,19 @@
if (client->GetCurrState() == NCS_LOADING)
return true;
- CClientTimeoutMessage* message = (CClientTimeoutMessage*)event->GetParamRef();
+ CClientTimeoutMessage message;
+ event->GetMessageBuffer().GetMessage(message);
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-timeout' })", &msg);
- client->GetScriptInterface().SetProperty(msg, "guid", std::string(message->m_GUID));
- client->GetScriptInterface().SetProperty(msg, "lastReceivedTime", message->m_LastReceivedTime);
+ client->GetScriptInterface().SetProperty(msg, "guid", std::string(message.m_GUID));
+ client->GetScriptInterface().SetProperty(msg, "lastReceivedTime", message.m_LastReceivedTime);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnClientPerformance(void *context, CFsmEvent* event)
+bool CNetClient::OnClientPerformance(void *context, const CFsmEvent* event)
{
// Performance statistics for one or multiple clients
@@ -762,33 +770,35 @@
if (client->GetCurrState() == NCS_LOADING)
return true;
- CClientPerformanceMessage* message = (CClientPerformanceMessage*)event->GetParamRef();
+ CClientPerformanceMessage message;
+ event->GetMessageBuffer().GetMessage(message);
// Display warnings for other clients with bad ping
- for (size_t i = 0; i < message->m_Clients.size(); ++i)
+ for (size_t i = 0; i < message.m_Clients.size(); ++i)
{
- if (message->m_Clients[i].m_MeanRTT < DEFAULT_TURN_LENGTH_MP || message->m_Clients[i].m_GUID == client->m_GUID)
+ if (message.m_Clients[i].m_MeanRTT < DEFAULT_TURN_LENGTH_MP || message.m_Clients[i].m_GUID == client->m_GUID)
continue;
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({ 'type':'netwarn', 'warntype': 'client-latency' })", &msg);
- client->GetScriptInterface().SetProperty(msg, "guid", message->m_Clients[i].m_GUID);
- client->GetScriptInterface().SetProperty(msg, "meanRTT", message->m_Clients[i].m_MeanRTT);
+ client->GetScriptInterface().SetProperty(msg, "guid", message.m_Clients[i].m_GUID);
+ client->GetScriptInterface().SetProperty(msg, "meanRTT", message.m_Clients[i].m_MeanRTT);
client->PushGuiMessage(msg);
}
return true;
}
-bool CNetClient::OnClientsLoading(void *context, CFsmEvent *event)
+bool CNetClient::OnClientsLoading(void *context, const CFsmEvent *event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENTS_LOADING);
- CClientsLoadingMessage* message = (CClientsLoadingMessage*)event->GetParamRef();
+ CClientsLoadingMessage message;
+ event->GetMessageBuffer().GetMessage(message);
std::vector guids;
- guids.reserve(message->m_Clients.size());
- for (const CClientsLoadingMessage::S_m_Clients& client : message->m_Clients)
+ guids.reserve(message.m_Clients.size());
+ for (const CClientsLoadingMessage::SClient& client : message.m_Clients)
guids.push_back(client.m_GUID);
CNetClient* client = (CNetClient*)context;
@@ -802,7 +812,7 @@
return true;
}
-bool CNetClient::OnClientPaused(void *context, CFsmEvent *event)
+bool CNetClient::OnClientPaused(void *context, const CFsmEvent *event)
{
ENSURE(event->GetType() == (uint)NMT_CLIENT_PAUSED);
@@ -810,18 +820,19 @@
JSContext* cx = client->GetScriptInterface().GetContext();
JSAutoRequest rq(cx);
- CClientPausedMessage* message = (CClientPausedMessage*)event->GetParamRef();
+ CClientPausedMessage message;
+ event->GetMessageBuffer().GetMessage(message);
JS::RootedValue msg(cx);
client->GetScriptInterface().Eval("({ 'type':'paused' })", &msg);
- client->GetScriptInterface().SetProperty(msg, "pause", message->m_Pause != 0);
- client->GetScriptInterface().SetProperty(msg, "guid", message->m_GUID);
+ client->GetScriptInterface().SetProperty(msg, "pause", message.m_Pause != 0);
+ client->GetScriptInterface().SetProperty(msg, "guid", message.m_GUID);
client->PushGuiMessage(msg);
return true;
}
-bool CNetClient::OnLoadedGame(void* context, CFsmEvent* event)
+bool CNetClient::OnLoadedGame(void* context, const CFsmEvent* event)
{
ENSURE(event->GetType() == (uint)NMT_LOADED_GAME);
@@ -844,30 +855,30 @@
return true;
}
-bool CNetClient::OnInGame(void *context, CFsmEvent* event)
+bool CNetClient::OnInGame(void *context, const CFsmEvent* event)
{
// TODO: should split each of these cases into a separate method
CNetClient* client = (CNetClient*)context;
- CNetMessage* message = (CNetMessage*)event->GetParamRef();
- if (message)
+ const CNetMessageBuffer& message = event->GetMessageBuffer();
+ if (message.GetType() == NMT_SIMULATION_COMMAND)
+ {
+ CSimulationMessage simMessage(client->GetScriptInterface());
+ message.GetMessage(simMessage);
+ client->m_ClientTurnManager->OnSimulationMessage(&simMessage);
+ }
+ else if (message.GetType() == NMT_SYNC_ERROR)
+ {
+ CSyncErrorMessage syncMessage;
+ message.GetMessage(syncMessage);
+ client->m_ClientTurnManager->OnSyncError(syncMessage.m_Turn, syncMessage.m_HashExpected, syncMessage.m_PlayerNames);
+ }
+ else if (message.GetType() == NMT_END_COMMAND_BATCH)
{
- if (message->GetType() == NMT_SIMULATION_COMMAND)
- {
- CSimulationMessage* simMessage = static_cast (message);
- client->m_ClientTurnManager->OnSimulationMessage(simMessage);
- }
- else if (message->GetType() == NMT_SYNC_ERROR)
- {
- CSyncErrorMessage* syncMessage = static_cast (message);
- client->m_ClientTurnManager->OnSyncError(syncMessage->m_Turn, syncMessage->m_HashExpected, syncMessage->m_PlayerNames);
- }
- else if (message->GetType() == NMT_END_COMMAND_BATCH)
- {
- CEndCommandBatchMessage* endMessage = static_cast (message);
- client->m_ClientTurnManager->FinishedAllCommands(endMessage->m_Turn, endMessage->m_TurnLength);
- }
+ CEndCommandBatchMessage endMessage;
+ message.GetMessage(endMessage);
+ client->m_ClientTurnManager->FinishedAllCommands(endMessage.m_Turn, endMessage.m_TurnLength);
}
return true;
Index: source/network/NetClientTurnManager.h
===================================================================
--- source/network/NetClientTurnManager.h
+++ source/network/NetClientTurnManager.h
@@ -19,7 +19,7 @@
#define INCLUDED_NETCLIENTTURNMANAGER
#include "simulation2/system/TurnManager.h"
-#include "NetMessage.h"
+#include "NetMessages.h"
class CNetClient;
@@ -41,7 +41,7 @@
*/
void OnDestroyConnection();
- void OnSyncError(u32 turn, const CStr& expectedHash, const std::vector& playerNames);
+ void OnSyncError(u32 turn, const CStr& expectedHash, const std::vector& playerNames);
private:
void NotifyFinishedOwnCommands(u32 turn) override;
Index: source/network/NetClientTurnManager.cpp
===================================================================
--- source/network/NetClientTurnManager.cpp
+++ source/network/NetClientTurnManager.cpp
@@ -44,7 +44,7 @@
// Transmit command to server
CSimulationMessage msg(m_Simulation2.GetScriptInterface(), m_ClientId, m_PlayerId, m_CurrentTurn + COMMAND_DELAY, data);
- m_NetClient.SendMessage(&msg);
+ m_NetClient.SendMessage(msg);
// Add to our local queue
//AddCommand(m_ClientId, m_PlayerId, data, m_CurrentTurn + COMMAND_DELAY);
@@ -64,7 +64,7 @@
// It could be used to verify that the client simulated the correct turn length.
msg.m_TurnLength = 0;
- m_NetClient.SendMessage(&msg);
+ m_NetClient.SendMessage(msg);
}
void CNetClientTurnManager::NotifyFinishedUpdate(u32 turn)
@@ -88,7 +88,7 @@
CSyncCheckMessage msg;
msg.m_Turn = turn;
msg.m_Hash = hash;
- m_NetClient.SendMessage(&msg);
+ m_NetClient.SendMessage(CNetMessageBuffer(msg));
}
void CNetClientTurnManager::OnDestroyConnection()
@@ -99,10 +99,10 @@
void CNetClientTurnManager::OnSimulationMessage(CSimulationMessage* msg)
{
// Command received from the server - store it for later execution
- AddCommand(msg->m_Client, msg->m_Player, msg->m_Data, msg->m_Turn);
+ AddCommand(msg->m_Client, msg->m_Player, msg->m_JSData.m_Data, msg->m_Turn);
}
-void CNetClientTurnManager::OnSyncError(u32 turn, const CStr& expectedHash, const std::vector& playerNames)
+void CNetClientTurnManager::OnSyncError(u32 turn, const CStr& expectedHash, const std::vector& playerNames)
{
NETCLIENTTURN_LOG("OnSyncError(%d, %hs)\n", turn, Hexify(expectedHash).c_str());
@@ -127,7 +127,7 @@
playerNamesStrings.reserve(playerNames.size());
for (size_t i = 0; i < playerNames.size(); ++i)
{
- CStr name = utf8_from_wstring(playerNames[i].m_Name);
+ CStr name = utf8_from_wstring(playerNames[i]);
playerNamesString << (i == 0 ? "" : ", ") << name;
playerNamesStrings.push_back(name);
}
Index: source/network/NetFileTransfer.h
===================================================================
--- source/network/NetFileTransfer.h
+++ source/network/NetFileTransfer.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2016 Wildfire Games.
+/* Copyright (C) 2017 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -18,9 +18,10 @@
#ifndef NETFILETRANSFER_H
#define NETFILETRANSFER_H
+#include "NetMessages.h"
+
#include