BVB Source Codes

CRYENGINE Show IGameObject.h Source code

Return Download CRYENGINE: download IGameObject.h Source code - Download CRYENGINE Source code - Type:.h
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #ifndef __IGAMEOBJECT_H__
  4. #define __IGAMEOBJECT_H__
  5.  
  6. #pragma once
  7.  
  8. // FIXME: Cell SDK GCC bug workaround.
  9. #ifndef __IGAMEOBJECTSYSTEM_H__
  10.         #include "IGameObjectSystem.h"
  11. #endif
  12.  
  13. #define GAME_OBJECT_SUPPORTS_CUSTOM_USER_DATA 1
  14.  
  15. #include <CryEntitySystem/IEntityComponent.h>
  16.  
  17. #include <CryNetwork/SerializeFwd.h>
  18. #include "IActionMapManager.h"
  19. #include <CryMemory/PoolAllocator.h>
  20. #include <CryFlowGraph/IFlowSystem.h>
  21.  
  22. inline void GameWarning(const char*, ...) PRINTF_PARAMS(1, 2);
  23.  
  24. struct IGameObjectExtension;
  25. struct IGameObjectView;
  26. struct IActionListener;
  27. struct IMovementController;
  28. struct IGameObjectProfileManager;
  29. struct IWorldQuery;
  30.  
  31. enum EEntityAspects
  32. {
  33.         eEA_All               = NET_ASPECT_ALL,
  34.         // 0x01u                       // aspect 0
  35.         eEA_Script            = 0x02u, // aspect 1
  36.         // 0x04u                       // aspect 2
  37.         eEA_Physics           = 0x08u, // aspect 3
  38.         eEA_GameClientStatic  = 0x10u, // aspect 4
  39.         eEA_GameServerStatic  = 0x20u, // aspect 5
  40.         eEA_GameClientDynamic = 0x40u, // aspect 6
  41.         eEA_GameServerDynamic = 0x80u, // aspect 7
  42. #if NUM_ASPECTS > 8
  43.         eEA_GameClientA       = 0x0100u, // aspect 8
  44.         eEA_GameServerA       = 0x0200u, // aspect 9
  45.         eEA_GameClientB       = 0x0400u, // aspect 10
  46.         eEA_GameServerB       = 0x0800u, // aspect 11
  47.         eEA_GameClientC       = 0x1000u, // aspect 12
  48.         eEA_GameServerC       = 0x2000u, // aspect 13
  49.         eEA_GameClientD       = 0x4000u, // aspect 14
  50.         eEA_GameClientE       = 0x8000u, // aspect 15
  51. #endif
  52. #if NUM_ASPECTS > 16
  53.         eEA_GameClientF = 0x00010000u,       // aspect 16
  54.         eEA_GameClientG = 0x00020000u,       // aspect 17
  55.         eEA_GameClientH = 0x00040000u,       // aspect 18
  56.         eEA_GameClientI = 0x00080000u,       // aspect 19
  57.         eEA_GameClientJ = 0x00100000u,       // aspect 20
  58.         eEA_GameServerD = 0x00200000u,       // aspect 21
  59.         eEA_GameClientK = 0x00400000u,       // aspect 22
  60.         eEA_GameClientL = 0x00800000u,       // aspect 23
  61.         eEA_GameClientM = 0x01000000u,       // aspect 24
  62.         eEA_GameClientN = 0x02000000u,       // aspect 25
  63.         eEA_GameClientO = 0x04000000u,       // aspect 26
  64.         eEA_GameClientP = 0x08000000u,       // aspect 27
  65.         eEA_GameServerE = 0x10000000u,       // aspect 28
  66.         eEA_Aspect29    = 0x20000000u,       // aspect 29
  67.         eEA_Aspect30    = 0x40000000u,       // aspect 30
  68.         eEA_Aspect31    = 0x80000000u,       // aspect 31
  69. #endif
  70. };
  71.  
  72. enum EEntityPhysicsEvents
  73. {
  74.         eEPE_OnCollisionLogged        = 1 << 0,   // Logged events on lower byte.
  75.         eEPE_OnPostStepLogged         = 1 << 1,
  76.         eEPE_OnStateChangeLogged      = 1 << 2,
  77.         eEPE_OnCreateEntityPartLogged = 1 << 3,
  78.         eEPE_OnUpdateMeshLogged       = 1 << 4,
  79.         eEPE_AllLogged                = eEPE_OnCollisionLogged | eEPE_OnPostStepLogged |
  80.                                         eEPE_OnStateChangeLogged | eEPE_OnCreateEntityPartLogged |
  81.                                         eEPE_OnUpdateMeshLogged,
  82.  
  83.         eEPE_OnCollisionImmediate        = 1 << 8, // Immediate events on higher byte.
  84.         eEPE_OnPostStepImmediate         = 1 << 9,
  85.         eEPE_OnStateChangeImmediate      = 1 << 10,
  86.         eEPE_OnCreateEntityPartImmediate = 1 << 11,
  87.         eEPE_OnUpdateMeshImmediate       = 1 << 12,
  88.         eEPE_AllImmediate                = eEPE_OnCollisionImmediate | eEPE_OnPostStepImmediate |
  89.                                            eEPE_OnStateChangeImmediate | eEPE_OnCreateEntityPartImmediate |
  90.                                            eEPE_OnUpdateMeshImmediate,
  91. };
  92.  
  93. static const int MAX_UPDATE_SLOTS_PER_EXTENSION = 5;
  94.  
  95. enum ERMInvocation
  96. {
  97.         eRMI_ToClientChannel = 0x01,
  98.         eRMI_ToOwnClient     = 0x02,
  99.         eRMI_ToOtherClients  = 0x04,
  100.         eRMI_ToAllClients    = 0x08,
  101.  
  102.         eRMI_ToServer        = 0x100,
  103.  
  104.         eRMI_NoLocalCalls    = 0x10000,
  105.         eRMI_NoRemoteCalls   = 0x20000,
  106.  
  107.         eRMI_ToRemoteClients = eRMI_NoLocalCalls | eRMI_ToAllClients
  108. };
  109.  
  110. enum EUpdateEnableCondition
  111. {
  112.         eUEC_Never,
  113.         eUEC_Always,
  114.         eUEC_Visible,
  115.         eUEC_InRange,
  116.         eUEC_VisibleAndInRange,
  117.         eUEC_VisibleOrInRange,
  118.         eUEC_VisibleOrInRangeIgnoreAI,
  119.         eUEC_VisibleIgnoreAI,
  120.         eUEC_WithoutAI,
  121. };
  122.  
  123. enum EPrePhysicsUpdate
  124. {
  125.         ePPU_Never,
  126.         ePPU_Always,
  127.         ePPU_WhenAIActivated
  128. };
  129.  
  130. enum EGameObjectAIActivationMode
  131. {
  132.         eGOAIAM_Never,
  133.         eGOAIAM_Always,
  134.         eGOAIAM_VisibleOrInRange,
  135.         // Must be last.
  136.         eGOAIAM_COUNT_STATES,
  137. };
  138.  
  139. enum EAutoDisablePhysicsMode
  140. {
  141.         eADPM_Never,
  142.         eADPM_WhenAIDeactivated,
  143.         eADPM_WhenInvisibleAndFarAway,
  144.         // Must be last.
  145.         eADPM_COUNT_STATES,
  146. };
  147.  
  148. enum EBindToNetworkMode
  149. {
  150.         eBTNM_Normal,
  151.         eBTNM_Force,
  152.         eBTNM_NowInitialized
  153. };
  154.  
  155. struct SGameObjectExtensionRMI
  156. {
  157.         void GetMemoryUsage(ICrySizer* pSizer) const {}
  158.         typedef INetAtSyncItem* (* DecoderFunction)(TSerialize, EntityId*, INetChannel*);
  159.  
  160.         DecoderFunction       decoder;
  161.         const char*           description;
  162.         const void*           pBase;
  163.         const SNetMessageDef* pMsgDef;
  164.         ERMIAttachmentType    attach;
  165.         bool                  isServerCall;
  166.         bool                  lowDelay;
  167.         ENetReliabilityType   reliability;
  168. };
  169.  
  170. template<size_t N>
  171. class CRMIAllocator
  172. {
  173. public:
  174.         static ILINE void* Allocate()
  175.         {
  176.                 if (!m_pAllocator)
  177.                         m_pAllocator = new stl::PoolAllocator<N>;
  178.                 return m_pAllocator->Allocate();
  179.         }
  180.         static ILINE void Deallocate(void* p)
  181.         {
  182.                 CRY_ASSERT(m_pAllocator);
  183.                 m_pAllocator->Deallocate(p);
  184.         }
  185.  
  186. private:
  187.         static stl::PoolAllocator<N>* m_pAllocator;
  188. };
  189. template<size_t N> stl::PoolAllocator<N>* CRMIAllocator<N>::m_pAllocator = 0;
  190.  
  191. // Summary
  192. //   Interface used to interact with a game object
  193. // See Also
  194. //   IGameObjectExtension
  195. struct IGameObject : public IEntityComponent, public IActionListener
  196. {
  197. protected:
  198.         class CRMIBody : public IRMIMessageBody
  199.         {
  200.         public:
  201.                 CRMIBody(const SGameObjectExtensionRMI* method, EntityId id, IRMIListener* pListener, int userId, EntityId dependentId) :
  202.                         IRMIMessageBody(method->reliability, method->attach, id, method->pMsgDef, pListener, userId, dependentId)
  203.                 {
  204.                 }
  205.         };
  206.  
  207.         template<class T>
  208.         class CRMIBodyImpl : public CRMIBody
  209.         {
  210.         public:
  211.                 void SerializeWith(TSerialize ser)
  212.                 {
  213.                         m_params.SerializeWith(ser);
  214.                 }
  215.  
  216.                 size_t GetSize()
  217.                 {
  218.                         return sizeof(*this);
  219.                 }
  220.  
  221. #if ENABLE_RMI_BENCHMARK
  222.                 virtual const SRMIBenchmarkParams* GetRMIBenchmarkParams()
  223.                 {
  224.                         return NetGetRMIBenchmarkParams<T>(m_params);
  225.                 }
  226. #endif
  227.  
  228.                 static CRMIBodyImpl* Create(const SGameObjectExtensionRMI* method, EntityId id, const T& params, IRMIListener* pListener, int userId, EntityId dependentId)
  229.                 {
  230.                         return new(CRMIAllocator<sizeof(CRMIBodyImpl)>::Allocate())CRMIBodyImpl(method, id, params, pListener, userId, dependentId);
  231.                 }
  232.  
  233.                 void DeleteThis()
  234.                 {
  235.                         this->~CRMIBodyImpl();
  236.                         CRMIAllocator<sizeof(CRMIBodyImpl)>::Deallocate(this);
  237.                 }
  238.  
  239.         private:
  240.                 T m_params;
  241.  
  242.                 CRMIBodyImpl(const SGameObjectExtensionRMI* method, EntityId id, const T& params, IRMIListener* pListener, int userId, EntityId dependentId) :
  243.                         CRMIBody(method, id, pListener, userId, dependentId),
  244.                         m_params(params)
  245.                 {
  246.                 }
  247.         };
  248.  
  249. public:
  250.         // bind this entity to the network system (it gets synchronized then...)
  251.         virtual bool                  BindToNetwork(EBindToNetworkMode mode = eBTNM_Normal) = 0;
  252.         // bind this entity to the network system, with a dependency on its parent
  253.         virtual bool                  BindToNetworkWithParent(EBindToNetworkMode mode, EntityId parentId) = 0;
  254.         // flag that we have changed the state of the game object aspect
  255.         virtual void                  ChangedNetworkState(NetworkAspectType aspects) = 0;
  256.         // enable/disable network aspects on game object
  257.         virtual void                  EnableAspect(NetworkAspectType aspects, bool enable) = 0;
  258.         // enable/disable delegatable aspects
  259.         virtual void                  EnableDelegatableAspect(NetworkAspectType aspects, bool enable) = 0;
  260.         // A one off call to never enable the physics aspect, this needs to be done *before* the BindToNetwork (typically in the GameObject's Init function)
  261.         virtual void                  DontSyncPhysics() = 0;
  262.         // query extension. returns 0 if extension is not there.
  263.         virtual IGameObjectExtension* QueryExtension(const char* extension) const = 0;
  264.         virtual IGameObjectExtension* QueryExtension(IGameObjectSystem::ExtensionID id) const = 0;
  265.  
  266.         // set extension parameters
  267.         virtual bool                  SetExtensionParams(const char* extension, SmartScriptTable params) = 0;
  268.         // get extension parameters
  269.         virtual bool                  GetExtensionParams(const char* extension, SmartScriptTable params) = 0;
  270.         // send a game object event
  271.         virtual void                  SendEvent(const SGameObjectEvent&) = 0;
  272.         // force the object to update even if extensions' slots are "sleeping"...
  273.         virtual void                  ForceUpdate(bool force) = 0;
  274.         virtual void                  ForceUpdateExtension(IGameObjectExtension* pGOE, int slot) = 0;
  275.         // get/set network channel
  276.         virtual uint16                GetChannelId() const = 0;
  277.         virtual void SetChannelId(uint16) = 0;
  278.         virtual INetChannel*          GetNetChannel() const = 0;
  279.         // serialize some aspects of the game object
  280.         virtual void                  FullSerialize(TSerialize ser) = 0;
  281.         virtual bool                  NetSerialize(TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags) = 0;
  282.         // in case things have to be set after serialization
  283.         virtual void                  PostSerialize() = 0;
  284.         // is the game object probably visible?
  285.         virtual bool                  IsProbablyVisible() = 0;
  286.         virtual bool                  IsProbablyDistant() = 0;
  287.         // change the profile of an aspect
  288.         virtual bool                  SetAspectProfile(EEntityAspects aspect, uint8 profile, bool fromNetwork = false) = 0;
  289.         virtual uint8                 GetAspectProfile(EEntityAspects aspect) = 0;
  290.         virtual IGameObjectExtension* GetExtensionWithRMIBase(const void* pBase) = 0;
  291.         virtual void                  EnablePrePhysicsUpdate(EPrePhysicsUpdate updateRule) = 0;
  292.         virtual void                  SetNetworkParent(EntityId id) = 0;
  293.         virtual void                  Pulse(uint32 pulse) = 0;
  294.         virtual void                  RegisterAsPredicted() = 0;
  295.         virtual void                  RegisterAsValidated(IGameObject* pGO, int predictionHandle) = 0;
  296.         virtual int                   GetPredictionHandle() = 0;
  297.  
  298.         virtual void                  RegisterExtForEvents(IGameObjectExtension* piExtention, const int* pEvents, const int numEvents) = 0;
  299.         virtual void                  UnRegisterExtForEvents(IGameObjectExtension* piExtention, const int* pEvents, const int numEvents) = 0;
  300.  
  301.         // enable/disable sending physics events to this game object
  302.         virtual void EnablePhysicsEvent(bool enable, int events) = 0;
  303.         virtual bool WantsPhysicsEvent(int events) = 0;
  304.         virtual void AttachDistanceChecker() = 0;
  305.  
  306.         // enable/disable AI activation flag
  307.         virtual bool SetAIActivation(EGameObjectAIActivationMode mode) = 0;
  308.         // enable/disable auto-disabling of physics
  309.         virtual void SetAutoDisablePhysicsMode(EAutoDisablePhysicsMode mode) = 0;
  310.         // for debugging updates
  311.         virtual bool ShouldUpdate() = 0;
  312.  
  313.         // register a partial update in the netcode without actually serializing - useful only for working around other bugs
  314.         virtual void RequestRemoteUpdate(NetworkAspectType aspectMask) = 0;
  315.  
  316.         // WARNING: there *MUST* be at least one frame between spawning ent and using this function to send an RMI if
  317.         // that RMI is _FAST, otherwise the dependent entity is ignored
  318.         template<class MI, class T>
  319.         void InvokeRMIWithDependentObject(const MI method, const T& params, unsigned where, EntityId ent, int channel = -1)
  320.         {
  321.                 InvokeRMI_Primitive(method, params, where, 0, 0, channel, ent);
  322.         }
  323.  
  324.         template<class MI, class T>
  325.         void InvokeRMI(const MI method, const T& params, unsigned where, int channel = -1)
  326.         {
  327.                 InvokeRMI_Primitive(method, params, where, 0, 0, channel, 0);
  328.         }
  329.  
  330.         template<class MI, class T>
  331.         void InvokeRMI_Primitive(const MI method, const T& params, unsigned where, IRMIListener* pListener, int userId, int channel, EntityId dependentId)
  332.         {
  333.                 method.Verify(params);
  334.                 DoInvokeRMI(CRMIBodyImpl<T>::Create(method.pMethodInfo, GetEntityId(), params, pListener, userId, dependentId), where, channel);
  335.         }
  336.  
  337.         // turn an extension on
  338.         ILINE bool                  ActivateExtension(const char* extension)   { return ChangeExtension(extension, eCE_Activate) != 0; }
  339.         // turn an extension off
  340.         ILINE void                  DeactivateExtension(const char* extension) { ChangeExtension(extension, eCE_Deactivate); }
  341.         // forcefully get a pointer to an extension (may instantiate if needed)
  342.         ILINE IGameObjectExtension* AcquireExtension(const char* extension)    { return ChangeExtension(extension, eCE_Acquire); }
  343.         // release a previously acquired extension
  344.         ILINE void                  ReleaseExtension(const char* extension)    { ChangeExtension(extension, eCE_Release); }
  345.  
  346.         ILINE EntityId GetEntityId() const
  347.         {
  348.                 return m_entityId;
  349.         }
  350.  
  351.         // for extensions to register for special things
  352.         virtual bool                       CaptureView(IGameObjectView* pGOV) = 0;
  353.         virtual void                       ReleaseView(IGameObjectView* pGOV) = 0;
  354.         virtual bool                       CaptureActions(IActionListener* pAL) = 0;
  355.         virtual void                       ReleaseActions(IActionListener* pAL) = 0;
  356.         virtual bool                       CaptureProfileManager(IGameObjectProfileManager* pPH) = 0;
  357.         virtual void                       ReleaseProfileManager(IGameObjectProfileManager* pPH) = 0;
  358.         virtual void                       EnableUpdateSlot(IGameObjectExtension* pExtension, int slot) = 0;
  359.         virtual void                       DisableUpdateSlot(IGameObjectExtension* pExtension, int slot) = 0;
  360.         virtual uint8                      GetUpdateSlotEnables(IGameObjectExtension* pExtension, int slot) = 0;
  361.         virtual void                       EnablePostUpdates(IGameObjectExtension* pExtension) = 0;
  362.         virtual void                       DisablePostUpdates(IGameObjectExtension* pExtension) = 0;
  363.         virtual void                       SetUpdateSlotEnableCondition(IGameObjectExtension* pExtension, int slot, EUpdateEnableCondition condition) = 0;
  364.         virtual void                       PostUpdate(float frameTime) = 0;
  365.         virtual IWorldQuery*               GetWorldQuery() = 0;
  366.  
  367.         virtual bool                       IsJustExchanging() = 0;
  368.  
  369.         ILINE void                         SetMovementController(IMovementController* pMC) { m_pMovementController = pMC; }
  370.         virtual ILINE IMovementController* GetMovementController()                         { return m_pMovementController; }
  371.  
  372.         virtual void                       GetMemoryUsage(ICrySizer* pSizer) const         {};
  373.  
  374. #if GAME_OBJECT_SUPPORTS_CUSTOM_USER_DATA
  375.         virtual void* GetUserData() const = 0;
  376.         virtual void  SetUserData(void* ptr) = 0;
  377. #endif
  378.  
  379. protected:
  380.         enum EChangeExtension
  381.         {
  382.                 eCE_Activate,
  383.                 eCE_Deactivate,
  384.                 eCE_Acquire,
  385.                 eCE_Release
  386.         };
  387.  
  388.         IGameObject() : m_entityId(0), m_pMovementController(0) {}
  389.         EntityId             m_entityId;
  390.         IMovementController* m_pMovementController;
  391.  
  392. private:
  393.         // change extension activation/reference somehow
  394.         virtual IGameObjectExtension* ChangeExtension(const char* extension, EChangeExtension change, TSerialize* pSpawnSerializer = 0) = 0;
  395.         // invoke an RMI call
  396.         virtual void                  DoInvokeRMI(_smart_ptr<CRMIBody> pBody, unsigned where, int channel) = 0;
  397. };
  398.  
  399. struct IRMIAtSyncItem : public INetAtSyncItem, public IRMICppLogger {};
  400.  
  401. template<class T, class Obj>
  402. class CRMIAtSyncItem : public IRMIAtSyncItem
  403. {
  404. public:
  405.         typedef bool (Obj::* CallbackFunc)(const T&, INetChannel*);
  406.  
  407.         // INetAtSyncItem
  408.         // INetAtSyncItem
  409.  
  410.         static ILINE CRMIAtSyncItem* Create(const T& params, EntityId id, const SGameObjectExtensionRMI* pRMI, CallbackFunc callback, INetChannel* pChannel)
  411.         {
  412.                 return new(CRMIAllocator<sizeof(CRMIAtSyncItem)>::Allocate())CRMIAtSyncItem(params, id, pRMI, callback, pChannel);
  413.         }
  414.  
  415.         bool Sync()
  416.         {
  417.                 bool ok = false;
  418.                 bool foundObject = false;
  419.                 char msg[256];
  420.                 msg[0] = 0;
  421.  
  422.                 if (IGameObject* pGameObject = gEnv->pGameFramework->GetGameObject(m_id))
  423.                 {
  424.                         INDENT_LOG_DURING_SCOPE(true, "During game object sync: %s %s", pGameObject->GetEntity()->GetEntityTextDescription().c_str(), m_pRMI->pMsgDef->description);
  425.  
  426.                         if (Obj* pGameObjectExtension = (Obj*)pGameObject->GetExtensionWithRMIBase(m_pRMI->pBase))
  427.                         {
  428.                                 ok = (pGameObjectExtension->*m_callback)(m_params, m_pChannel);
  429.                                 foundObject = true;
  430.                         }
  431.                         else
  432.                         {
  433.                                 CryWarning(VALIDATOR_MODULE_NETWORK, VALIDATOR_ERROR,
  434.                                         "Game object extension with base %.8x for entity %s for RMI %s not found",
  435.                                         (uint32)(TRUNCATE_PTR)m_pRMI->pBase, pGameObject->GetEntity()->GetName(),
  436.                                         m_pRMI->pMsgDef->description);
  437.                         }
  438.                 }
  439.                 else
  440.                 {
  441.                         cry_sprintf(msg, "Entity %u for RMI %s not found", m_id, m_pRMI->pMsgDef->description);
  442.                 }
  443.  
  444.                 if (!ok)
  445.                 {
  446.                         CryWarning(VALIDATOR_MODULE_NETWORK, VALIDATOR_ERROR,
  447.                                 "Error handling RMI %s", m_pRMI->pMsgDef->description);
  448.  
  449.                         if (!foundObject && !gEnv->bServer && !m_pChannel->IsInTransition())
  450.                         {
  451.                                 CRY_ASSERT(msg[0]);
  452.                                 m_pChannel->Disconnect(eDC_ContextCorruption, msg);
  453.                         }
  454.                         else
  455.                         {
  456.                                 ok = true;
  457.                                 // fake for singleplayer/multiplayer server
  458.                                 // singleplayer - 'impossible' to get right during quick-load
  459.                                 // multiplayer server - object can be deleted while the message is in flight
  460.                         }
  461.                 }
  462.  
  463.                 if (!foundObject)
  464.                         return true; // for editor
  465.                 else
  466.                         return ok;
  467.         }
  468.  
  469.         bool SyncWithError(EDisconnectionCause& disconnectCause, string& disconnectMessage)
  470.         {
  471.                 return Sync();
  472.         }
  473.  
  474.         void DeleteThis()
  475.         {
  476.                 this->~CRMIAtSyncItem();
  477.                 CRMIAllocator<sizeof(CRMIAtSyncItem)>::Deallocate(this);
  478.         }
  479.         // ~INetAtSyncItem
  480.  
  481.         // IRMICppLogger
  482.         virtual const char* GetName()
  483.         {
  484.                 return m_pRMI->description;
  485.         }
  486.         virtual void SerializeParams(TSerialize ser)
  487.         {
  488.                 m_params.SerializeWith(ser);
  489.         }
  490.         // ~IRMICppLogger
  491.  
  492. private:
  493.         CRMIAtSyncItem(const T& params, EntityId id, const SGameObjectExtensionRMI* pRMI, CallbackFunc callback, INetChannel* pChannel) : m_params(params), m_id(id), m_pRMI(pRMI), m_callback(callback), m_pChannel(pChannel) {}
  494.  
  495.         T                              m_params;
  496.         EntityId                       m_id;
  497.         const SGameObjectExtensionRMI* m_pRMI;
  498.         CallbackFunc                   m_callback;
  499.         INetChannel*                   m_pChannel;
  500. };
  501.  
  502. struct IGameObject;
  503. struct SViewParams;
  504.  
  505. template<class T_Derived, class T_Parent, size_t MAX_STATIC_MESSAGES = 64>
  506. class CGameObjectExtensionHelper : public T_Parent
  507. {
  508. public:
  509.         static void GetGameObjectExtensionRMIData(void** ppRMI, size_t* nCount)
  510.         {
  511.                 *ppRMI = ms_statics.m_vMessages;
  512.                 *nCount = ms_statics.m_nMessages;
  513.         }
  514.  
  515.         const void* GetRMIBase() const
  516.         {
  517.                 return ms_statics.m_vMessages;
  518.         }
  519.  
  520.         static void SetExtensionId(IGameObjectSystem::ExtensionID id) { ms_statics.m_extensionId = id; }
  521.  
  522. protected:
  523.  
  524.         static T_Derived* QueryExtension(EntityId id)
  525.         {
  526.                 IGameObject* pGO = gEnv->pGameFramework->GetGameObject(id);
  527.                 if (pGO)
  528.                 {
  529.                         return static_cast<T_Derived*>(pGO->QueryExtension(T_Derived::ms_statics.m_extensionId));
  530.                 }
  531.  
  532.                 return NULL;
  533.         }
  534.  
  535.         static void ActivateOutputPort(EntityId id, int port, const TFlowInputData& data)
  536.         {
  537.                 SEntityEvent evnt;
  538.                 evnt.event = ENTITY_EVENT_ACTIVATE_FLOW_NODE_OUTPUT;
  539.                 evnt.nParam[0] = port;
  540.                 evnt.nParam[1] = (INT_PTR)&data;
  541.  
  542.                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(id);
  543.                 if (pEntity)
  544.                         pEntity->SendEvent(evnt);
  545.         }
  546.  
  547.         static const SGameObjectExtensionRMI* Helper_AddMessage(SGameObjectExtensionRMI::DecoderFunction decoder, const char* description, ERMIAttachmentType attach, bool isServerCall, ENetReliabilityType reliability, bool lowDelay)
  548.         {
  549.                 if (ms_statics.m_nMessages >= MAX_STATIC_MESSAGES)
  550.                 {
  551.                         // Assert or CryFatalError here uses gEnv, which is not yet initialized.
  552.                         __debugbreak();
  553.                         ((void (*)())NULL)();
  554.                         return NULL;
  555.                 }
  556.                 SGameObjectExtensionRMI& rmi = ms_statics.m_vMessages[ms_statics.m_nMessages++];
  557.                 rmi.decoder = decoder;
  558.                 rmi.description = description;
  559.                 rmi.attach = attach;
  560.                 rmi.isServerCall = isServerCall;
  561.                 rmi.pBase = ms_statics.m_vMessages;
  562.                 rmi.reliability = reliability;
  563.                 rmi.pMsgDef = 0;
  564.                 rmi.lowDelay = lowDelay;
  565.                 return &rmi;
  566.         }
  567.  
  568. private:
  569.         struct Statics
  570.         {
  571.                 size_t                         m_nMessages;
  572.                 SGameObjectExtensionRMI        m_vMessages[MAX_STATIC_MESSAGES];
  573.                 IGameObjectSystem::ExtensionID m_extensionId;
  574.         };
  575.  
  576.         static Statics ms_statics;
  577. };
  578.  
  579. #define DECLARE_RMI(name, params, reliability, attachment, isServer, lowDelay)                              \
  580.   public:                                                                                                   \
  581.     struct MethodInfo_ ## name                                                                              \
  582.     {                                                                                                       \
  583.       MethodInfo_ ## name(const SGameObjectExtensionRMI * pMethodInfo) { this->pMethodInfo = pMethodInfo; } \
  584.       const SGameObjectExtensionRMI* pMethodInfo;                                                           \
  585.       ILINE void Verify(const params &p) const                                                              \
  586.       {                                                                                                     \
  587.       }                                                                                                     \
  588.     };                                                                                                      \
  589.   private:                                                                                                  \
  590.     static INetAtSyncItem* Decode_ ## name(TSerialize, EntityId*, INetChannel*);                            \
  591.     bool Handle_ ## name(const params &, INetChannel*);                                                     \
  592.     static const ERMIAttachmentType Attach_ ## name = attachment;                                           \
  593.     static const bool ServerCall_ ## name = isServer;                                                       \
  594.     static const ENetReliabilityType Reliability_ ## name = reliability;                                    \
  595.     static const bool LowDelay_ ## name = lowDelay;                                                         \
  596.     typedef params Params_ ## name;                                                                         \
  597.     static MethodInfo_ ## name m_info ## name;                                                              \
  598.   public:                                                                                                   \
  599.     static const MethodInfo_ ## name& name() { return m_info ## name; }
  600.  
  601. #define DECLARE_INTERFACE_RMI(name, params, reliability, attachment, isServer, lowDelay)                    \
  602.   protected:                                                                                                \
  603.     static const ERMIAttachmentType Attach_ ## name = attachment;                                           \
  604.     static const bool ServerCall_ ## name = isServer;                                                       \
  605.     static const ENetReliabilityType Reliability_ ## name = reliability;                                    \
  606.     static const bool LowDelay_ ## name = lowDelay;                                                         \
  607.     typedef params Params_ ## name;                                                                         \
  608.   public:                                                                                                   \
  609.     struct MethodInfo_ ## name                                                                              \
  610.     {                                                                                                       \
  611.       MethodInfo_ ## name(const SGameObjectExtensionRMI * pMethodInfo) { this->pMethodInfo = pMethodInfo; } \
  612.       const SGameObjectExtensionRMI* pMethodInfo;                                                           \
  613.       ILINE void Verify(const params &p) const                                                              \
  614.       {                                                                                                     \
  615.       }                                                                                                     \
  616.     };                                                                                                      \
  617.     virtual const MethodInfo_ ## name& name() = 0
  618.  
  619. #define DECLARE_IMPLEMENTATION_RMI(name)                                  \
  620.   private:                                                                \
  621.     INetAtSyncItem * Decode_ ## name(TSerialize, EntityId, INetChannel*); \
  622.     static bool Handle_ ## name(const Params_ ## name &, INetChannel*);   \
  623.     static MethodInfo_ ## name m_info ## name;                            \
  624.   public:                                                                 \
  625.     const MethodInfo_ ## name& name() { return m_info ## name; }
  626.  
  627. #define IMPLEMENT_RMI(cls, name)                                                                                                                                                                                            \
  628.   cls::MethodInfo_ ## name cls::m_info ## name = cls::Helper_AddMessage(&cls::Decode_ ## name, "RMI:" # cls ":" # name, cls::Attach_ ## name, cls::ServerCall_ ## name, cls::Reliability_ ## name, cls::LowDelay_ ## name); \
  629.   INetAtSyncItem* cls::Decode_ ## name(TSerialize ser, EntityId * pID, INetChannel * pChannel)                                                                                                                              \
  630.   {                                                                                                                                                                                                                         \
  631.     CRY_ASSERT(pID);                                                                                                                                                                                                        \
  632.     Params_ ## name params;                                                                                                                                                                                                 \
  633.     params.SerializeWith(ser);                                                                                                                                                                                              \
  634.     NetLogRMIReceived(params, pChannel);                                                                                                                                                                                    \
  635.     return CRMIAtSyncItem<Params_ ## name, cls>::Create(params, *pID, m_info ## name.pMethodInfo, &cls::Handle_ ## name, pChannel);                                                                                         \
  636.   }                                                                                                                                                                                                                         \
  637.   ILINE bool cls::Handle_ ## name(const Params_ ## name & params, INetChannel * pNetChannel)
  638.  
  639. #define IMPLEMENT_INTERFACE_RMI(cls, name)                                                                                                                                                                                  \
  640.   cls::MethodInfo_ ## name cls::m_info ## name = cls::Helper_AddMessage(&cls::Decode_ ## name, "RMI:" # cls ":" # name, cls::Attach_ ## name, cls::ServerCall_ ## name, cls::Reliability_ ## name, cls::LowDelay_ ## name); \
  641.   INetAtSyncItem* cls::Decode_ ## name(TSerialize ser, INetChannel * pChannel)                                                                                                                                              \
  642.   {                                                                                                                                                                                                                         \
  643.     Params_ ## name params;                                                                                                                                                                                                 \
  644.     params.SerializeWith(ser);                                                                                                                                                                                              \
  645.     return CRMIAtSyncItem<Params_ ## name, cls>::Create(params, id, m_info ## name.pMethodInfo, &cls::Handle_ ## name, pChannel);                                                                                           \
  646.   }                                                                                                                                                                                                                         \
  647.   ILINE bool cls::Handle_ ## name(const Params_ ## name & params, INetChannel * pNetChannel)
  648.  
  649. /*
  650.  * _FAST versions may send the RMI without waiting for the frame to end; be sure that consistency with the entity is not important!
  651.  */
  652.  
  653. //
  654. // PreAttach/PostAttach RMI's cannot have their reliability specified (see CGameObjectDispatch::RegisterInterface() for details)
  655. #define DECLARE_SERVER_RMI_PREATTACH(name, params)             DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PreAttach, true, false)
  656. #define DECLARE_CLIENT_RMI_PREATTACH(name, params)             DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PreAttach, false, false)
  657. #define DECLARE_SERVER_RMI_POSTATTACH(name, params)            DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PostAttach, true, false)
  658. #define DECLARE_CLIENT_RMI_POSTATTACH(name, params)            DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PostAttach, false, false)
  659. #define DECLARE_SERVER_RMI_NOATTACH(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_NoAttach, true, false)
  660. #define DECLARE_CLIENT_RMI_NOATTACH(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_NoAttach, false, false)
  661.  
  662. // PreAttach/PostAttach RMI's cannot have their reliability specified (see CGameObjectDispatch::RegisterInterface() for details)
  663. #define DECLARE_SERVER_RMI_PREATTACH_FAST(name, params)             DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PreAttach, true, true)
  664. #define DECLARE_CLIENT_RMI_PREATTACH_FAST(name, params)             DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PreAttach, false, true)
  665. #define DECLARE_SERVER_RMI_POSTATTACH_FAST(name, params)            DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PostAttach, true, true)
  666. #define DECLARE_CLIENT_RMI_POSTATTACH_FAST(name, params)            DECLARE_RMI(name, params, eNRT_UnreliableOrdered, eRAT_PostAttach, false, true)
  667. #define DECLARE_SERVER_RMI_NOATTACH_FAST(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_NoAttach, true, true)
  668. #define DECLARE_CLIENT_RMI_NOATTACH_FAST(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_NoAttach, false, true)
  669.  
  670. #if ENABLE_URGENT_RMIS
  671.         #define DECLARE_SERVER_RMI_URGENT(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_Urgent, true, false)
  672.         #define DECLARE_CLIENT_RMI_URGENT(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_Urgent, false, false)
  673. #else
  674.         #define DECLARE_SERVER_RMI_URGENT(name, params, reliability) DECLARE_SERVER_RMI_NOATTACH(name, params, reliability)
  675.         #define DECLARE_CLIENT_RMI_URGENT(name, params, reliability) DECLARE_CLIENT_RMI_NOATTACH(name, params, reliability)
  676. #endif // ENABLE_URGENT_RMIS
  677.  
  678. #if ENABLE_INDEPENDENT_RMIS
  679.         #define DECLARE_SERVER_RMI_INDEPENDENT(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_Independent, true, false)
  680.         #define DECLARE_CLIENT_RMI_INDEPENDENT(name, params, reliability) DECLARE_RMI(name, params, reliability, eRAT_Independent, false, false)
  681. #else
  682.         #define DECLARE_SERVER_RMI_INDEPENDENT(name, params, reliability) DECLARE_SERVER_RMI_NOATTACH(name, params, reliability)
  683.         #define DECLARE_CLIENT_RMI_INDEPENDENT(name, params, reliability) DECLARE_CLIENT_RMI_NOATTACH(name, params, reliability)
  684. #endif // ENABLE_INDEPENDENT_RMIS
  685.  
  686. /*
  687.    // Todo:
  688.    //           Temporary, until a good solution for sending noattach fast messages can be found
  689.    #define DECLARE_SERVER_RMI_NOATTACH_FAST(a,b,c) DECLARE_SERVER_RMI_NOATTACH(a,b,c)
  690.    #define DECLARE_CLIENT_RMI_NOATTACH_FAST(a,b,c) DECLARE_CLIENT_RMI_NOATTACH(a,b,c)
  691.  */
  692.  
  693. //
  694. #define DECLARE_INTERFACE_SERVER_RMI_PREATTACH(name, params, reliability)       DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PreAttach, true, false)
  695. #define DECLARE_INTERFACE_CLIENT_RMI_PREATTACH(name, params, reliability)       DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PreAttach, false, false)
  696. #define DECLARE_INTERFACE_SERVER_RMI_POSTATTACH(name, params, reliability)      DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PostAttach, true, false)
  697. #define DECLARE_INTERFACE_CLIENT_RMI_POSTATTACH(name, params, reliability)      DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PostAttach, false, false)
  698.  
  699. #define DECLARE_INTERFACE_SERVER_RMI_PREATTACH_FAST(name, params, reliability)  DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PreAttach, true, true)
  700. #define DECLARE_INTERFACE_CLIENT_RMI_PREATTACH_FAST(name, params, reliability)  DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PreAttach, false, true)
  701. #define DECLARE_INTERFACE_SERVER_RMI_POSTATTACH_FAST(name, params, reliability) DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PostAttach, true, true)
  702. #define DECLARE_INTERFACE_CLIENT_RMI_POSTATTACH_FAST(name, params, reliability) DECLARE_INTERFACE_RMI(name, params, reliability, eRAT_PostAttach, false, true)
  703.  
  704. template<class T, class U, size_t N>
  705. typename CGameObjectExtensionHelper<T, U, N>::Statics CGameObjectExtensionHelper<T, U, N>::ms_statics;
  706.  
  707. struct IGameObjectView
  708. {
  709.         virtual ~IGameObjectView(){}
  710.         virtual void UpdateView(SViewParams& params) = 0;
  711.         virtual void PostUpdateView(SViewParams& params) = 0;
  712. };
  713.  
  714. struct IGameObjectProfileManager
  715. {
  716.         virtual ~IGameObjectProfileManager(){}
  717.         virtual bool  SetAspectProfile(EEntityAspects aspect, uint8 profile) = 0;
  718.         virtual uint8 GetDefaultProfile(EEntityAspects aspect) = 0;
  719. };
  720.  
  721. // Summary
  722. //   Interface used to implement a game object extension
  723. struct IGameObjectExtension : public IEntityComponent
  724. {
  725.         IGameObjectExtension() : m_pGameObject(0) {}
  726.  
  727.         // IEntityComponent
  728.         virtual uint64 GetEventMask() const { return ~(BIT64(ENTITY_EVENT_PREPHYSICSUPDATE)|BIT64(ENTITY_EVENT_UPDATE)); } // All events except update and pre-physics update are subscribed to
  729.         virtual void Initialize() {};
  730.         // ~IEntityComponent
  731.  
  732.         // Summary
  733.         //   Initialize the extension
  734.         // Parameters
  735.         //   pGameObject - a pointer to the game object which will use the extension
  736.         // Remarks
  737.         //   IMPORTANT: It's very important that the implementation of this function
  738.         //   call the protected function SetGameObject() during the execution of the
  739.         //   Init() function. Unexpected results would happen otherwise.
  740.         virtual bool Init(IGameObject* pGameObject) = 0;
  741.  
  742.         // Summary
  743.         //   Post-initialize the extension
  744.         // Description
  745.         //   During the post-initialization, the extension is now contained in the
  746.         //   game object
  747.         // Parameters
  748.         //   pGameObject - a pointer to the game object which owns the extension
  749.         virtual void PostInit(IGameObject* pGameObject) = 0;
  750.  
  751.         // Summary
  752.         //   Initialize the extension (client only)
  753.         // Description
  754.         //   This initialization function should be use to initialize resource only
  755.         //   used in the client
  756.         // Parameters
  757.         //   channelId - id of the server channel of the client to receive the
  758.         //               initialization
  759.         virtual void InitClient(int channelId) = 0;
  760.  
  761.         // Summary
  762.         //   Post-initialize the extension (client only)
  763.         // Description
  764.         //   This initialization function should be use to initialize resource only
  765.         //   used in the client. During the post-initialization, the extension is now
  766.         //   contained in the game object
  767.         // Parameters
  768.         //   channelId - id of the server channel of the client to receive the
  769.         //               initialization
  770.         virtual void PostInitClient(int channelId) = 0;
  771.  
  772.         // Summary
  773.         //   Reload the extension
  774.         // Description
  775.         //   Called when owning entity is reloaded
  776.         // Parameters
  777.         //   pGameObject - a pointer to the game object which owns the extension
  778.         // Returns
  779.         //   TRUE if the extension should be kept, FALSE if it should be removed
  780.         // Remarks
  781.         //   IMPORTANT: It's very important that the implementation of this function
  782.         //   call the protected function ResetGameObject() during the execution of the
  783.         //   ReloadExtension() function. Unexpected results would happen otherwise.
  784.         virtual bool ReloadExtension(IGameObject* pGameObject, const SEntitySpawnParams& params) = 0;
  785.  
  786.         // Summary
  787.         //   Post-reload the extension
  788.         // Description
  789.         //   Called when owning entity is reloaded and all its extensions have either
  790.         //   either been reloaded or destroyed
  791.         // Parameters
  792.         //   pGameObject - a pointer to the game object which owns the extension
  793.         virtual void PostReloadExtension(IGameObject* pGameObject, const SEntitySpawnParams& params) = 0;
  794.  
  795.         // Summary
  796.         //   Performs the serialization the extension
  797.         // Parameters
  798.         //   ser - object used to serialize values
  799.         //   aspect - serialization aspect, used for network serialization
  800.         //   profile - which profile to serialize; 255 == don't care
  801.         //   flags - physics flags to be used for serialization
  802.         // See Also
  803.         //   ISerialize
  804.         virtual void FullSerialize(TSerialize ser) = 0;
  805.         virtual bool NetSerialize(TSerialize ser, EEntityAspects aspect, uint8 profile, int pflags) = 0;
  806.  
  807.         // Summary
  808.         //   Return the aspects NetSerialize serializes.
  809.         //   Overriding this to return only the aspects used will speed up the net bind of the object.
  810.         virtual NetworkAspectType GetNetSerializeAspects() { return eEA_All; }
  811.  
  812.         // Summary
  813.         //   Performs post serialization fixes
  814.         virtual void PostSerialize() = 0;
  815.  
  816.         // Summary
  817.         //   Performs the serialization of special spawn information
  818.         // Parameters
  819.         //   ser - object used to serialize values
  820.         // See Also
  821.         //   Serialize, ISerialize
  822.         virtual void                 SerializeSpawnInfo(TSerialize ser) = 0;
  823.  
  824.         virtual ISerializableInfoPtr GetSpawnInfo() = 0;
  825.  
  826.         // Summary
  827.         //   Performs frame dependent extension updates
  828.         // Parameters
  829.         //   ctx - Update context
  830.         //   updateSlot - updateSlot
  831.         // See Also
  832.         //   PostUpdate, SEntityUpdateContext, IGameObject::EnableUpdateSlot
  833.         virtual void Update(SEntityUpdateContext& ctx, int updateSlot) = 0;
  834.  
  835.         // Summary
  836.         //   Processes game specific events
  837.         // Parameters
  838.         //   event - game event
  839.         // See Also
  840.         //   SGameObjectEvent
  841.         virtual void HandleEvent(const SGameObjectEvent& event) = 0;
  842.  
  843.         virtual void GameSerialize(TSerialize ser ){ FullSerialize(ser); };                         //!< From IEntityComponent
  844.  
  845.         virtual void SetChannelId(uint16 id) = 0;
  846.         virtual void SetAuthority(bool auth) = 0;
  847.  
  848.         // Summary
  849.         //   Retrieves the RMI Base pointer
  850.         // Description
  851.         //   Internal function used for RMI. It's usually implemented by
  852.         //   CGameObjectExtensionHelper provides a way of checking who should
  853.         //   receive some RMI call.
  854.         virtual const void* GetRMIBase() const = 0;
  855.  
  856.         // Summary
  857.         //   Performs an additional update
  858.         // Parameters
  859.         //   frameTime - time elapsed since the last frame update
  860.         // See Also
  861.         //   Update, IGameObject::EnablePostUpdates, IGameObject::DisablePostUpdates
  862.         virtual void PostUpdate(float frameTime) = 0;
  863.  
  864.         // Summary
  865.         virtual void PostRemoteSpawn() = 0;
  866.  
  867.         // Summary
  868.         //   Retrieves the pointer to the game object
  869.         // Returns
  870.         //   A pointer to the game object which hold this extension
  871.         ILINE IGameObject* GetGameObject() const { return m_pGameObject; }
  872.  
  873. protected:
  874.         void SetGameObject(IGameObject* pGameObject)
  875.         {
  876.                 m_pGameObject = pGameObject;
  877.         }
  878.  
  879.         // Kept around for legacy reasons
  880.         void ResetGameObject() {}
  881.  
  882. private:
  883.         IGameObject* m_pGameObject;
  884. };
  885.  
  886. #define CHANGED_NETWORK_STATE(object, aspects)     do { /* IEntity * pEntity = object->GetGameObject()->GetEntity(); CryLogAlways("%s changed aspect %x (%s %d)", pEntity ? pEntity->GetName() : "NULL", aspects, __FILE__, __LINE__); */ object->GetGameObject()->ChangedNetworkState(aspects); } while (0)
  887. #define CHANGED_NETWORK_STATE_GO(object, aspects)  do { /* IEntity * pEntity = object->GetEntity(); CryLogAlways("%s changed aspect %x (%s %d)", pEntity ? pEntity->GetName() : "NULL", aspects, __FILE__, __LINE__); */ object->ChangedNetworkState(aspects); } while (0)
  888. #define CHANGED_NETWORK_STATE_REF(object, aspects) do { /* IEntity * pEntity = object.GetGameObject()->GetEntity(); CryLogAlways("%s changed aspect %x (%s %d)", pEntity ? pEntity->GetName() : "NULL", aspects, __FILE__, __LINE__); */ object.GetGameObject()->ChangedNetworkState(aspects); } while (0)
  889.  
  890. #endif
  891.  
downloadIGameObject.h Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top