BVB Source Codes

CRYENGINE Show GameObjectSystem.cpp Source code

Return Download CRYENGINE: download GameObjectSystem.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "GameObjects/GameObject.h"
  5. #include "GameObjectSystem.h"
  6. #include "IGameObject.h"
  7.  
  8. static bool StringToKey(const char* s, uint32& key)
  9. {
  10.         const size_t len = strlen(s);
  11.         if (len > 4)
  12.                 return false;
  13.  
  14.         key = 0;
  15.         for (size_t i = 0; i < len; i++)
  16.         {
  17.                 key <<= 8;
  18.                 key |= uint8(s[i]);
  19.         }
  20.  
  21.         return true;
  22. }
  23.  
  24. bool CGameObjectSystem::Init()
  25. {
  26.         IEntityClassRegistry::SEntityClassDesc desc;
  27.         desc.sName = "PlayerProximityTrigger";
  28.         desc.flags = ECLF_INVISIBLE;
  29.         if (gEnv->pEntitySystem)
  30.         {
  31.                 IEntityClassRegistry* pClsReg = gEnv->pEntitySystem->GetClassRegistry();
  32.                 m_pClassPlayerProximityTrigger = pClsReg->RegisterStdClass(desc);
  33.                 if (!m_pClassPlayerProximityTrigger)
  34.                         return false;
  35.         }
  36.  
  37.         memset(&m_defaultProfiles, 0, sizeof(m_defaultProfiles));
  38.  
  39.         const char* schedulerFile = "Scripts/Network/EntityScheduler.xml";
  40.         if (gEnv->pCryPak->IsFileExist(schedulerFile))
  41.         {
  42.                 if (XmlNodeRef schedParams = gEnv->pSystem->LoadXmlFromFile(schedulerFile))
  43.                 {
  44.                         uint32 defaultPolicy = 0;
  45.  
  46.                         if (XmlNodeRef defpol = schedParams->findChild("Default"))
  47.                         {
  48.                                 if (!StringToKey(defpol->getAttr("policy"), defaultPolicy))
  49.                                 {
  50.                                         GameWarning("Unable to read Default from EntityScheduler.xml");
  51.                                 }
  52.                         }
  53.  
  54.                         m_defaultProfiles.normal = m_defaultProfiles.owned = defaultPolicy;
  55.  
  56.                         for (int i = 0; i < schedParams->getChildCount(); i++)
  57.                         {
  58.                                 XmlNodeRef node = schedParams->getChild(i);
  59.                                 if (0 != strcmp(node->getTag(), "Class"))
  60.                                         continue;
  61.  
  62.                                 string name = node->getAttr("name");
  63.  
  64.                                 SEntitySchedulingProfiles p;
  65.                                 p.normal = defaultPolicy;
  66.                                 if (node->haveAttr("policy"))
  67.                                         StringToKey(node->getAttr("policy"), p.normal);
  68.                                 p.owned = p.normal;
  69.                                 if (node->haveAttr("own"))
  70.                                         StringToKey(node->getAttr("own"), p.owned);
  71.  
  72. #if !defined(_RELEASE)
  73.                                 TSchedulingProfiles::iterator iter = m_schedulingParams.find(CONST_TEMP_STRING(name));
  74.                                 if (iter != m_schedulingParams.end())
  75.                                 {
  76.                                         GameWarning("Class '%s' has been defined multiple times in EntityScheduler.xml", name.c_str());
  77.                                 }
  78. #endif //#if !defined(_RELEASE)
  79.  
  80.                                 m_schedulingParams[name] = p;
  81.                         }
  82.                 }
  83.         }
  84.  
  85.         LoadSerializationOrderFile();
  86.  
  87.         return true;
  88. }
  89.  
  90. void CGameObjectSystem::Reset()
  91. {
  92. #if !defined(_RELEASE)
  93.         if (gEnv->bMultiplayer)
  94.         {
  95.                 IEntityClassRegistry* pClassReg = gEnv->pEntitySystem->GetClassRegistry();
  96.  
  97.                 TSchedulingProfiles::iterator iter = m_schedulingParams.begin();
  98.                 TSchedulingProfiles::iterator end = m_schedulingParams.end();
  99.                 for (; iter != end; ++iter)
  100.                 {
  101.                         string className = iter->first;
  102.                         if (!pClassReg->FindClass(className.c_str()))
  103.                         {
  104.                                 GameWarning("EntityScheduler.xml has a class defined '%s' but unable to find it in ClassRegistry", className.c_str());
  105.                         }
  106.                 }
  107.         }
  108. #endif //#if !defined(_RELEASE)
  109.  
  110.         stl::free_container(m_tempObjects);
  111.         stl::free_container(m_postUpdateObjects);
  112.         stl::free_container(m_activatedExtensions_top);
  113. }
  114.  
  115. //////////////////////////////////////////////////////////////////////////
  116. // this reads the .xml that defines in which order the extensions are serialized inside a game object
  117.  
  118. void CGameObjectSystem::LoadSerializationOrderFile()
  119. {
  120.         static const char* SERIALIZATIONORDER_FILE = "Scripts/GameObjectSerializationOrder.xml";
  121.         if (!gEnv->pCryPak->IsFileExist(SERIALIZATIONORDER_FILE))
  122.         {
  123.                 // Fail silently, we do not require the file
  124.                 return;
  125.         }
  126.  
  127.         XmlNodeRef xmlNodeRoot = GetISystem()->LoadXmlFromFile(SERIALIZATIONORDER_FILE);
  128.  
  129.         if (xmlNodeRoot == (IXmlNode*)NULL)
  130.         {
  131.                 CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "CGameObjectSystem::LoadSerializationOrderFile() - Failed to load '%s'. sorting disabled.", SERIALIZATIONORDER_FILE);
  132.                 return;
  133.         }
  134.  
  135.         uint32 count = xmlNodeRoot->getChildCount();
  136.         m_serializationOrderList.resize(count);
  137.         std::set<const char*, stl::less_stricmp<const char*>> duplicateCheckerList;
  138.  
  139.         bool duplicatedEntriesInXML = false;
  140.         for (uint32 i = 0; i < count; ++i)
  141.         {
  142.                 string& name = m_serializationOrderList[i];
  143.                 XmlNodeRef xmlNodeExtension = xmlNodeRoot->getChild(i);
  144.                 name = xmlNodeExtension->getTag();
  145.                 name.MakeLower();
  146.                 if ((duplicateCheckerList.insert(xmlNodeExtension->getTag())).second != true)
  147.                 {
  148.                         duplicatedEntriesInXML = true;
  149.                         CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_ERROR, "CGameObjectSystem::LoadSerializationOrderFile() - Duplicated game object extension: '%s'. Savegames wont have properly sorted game object extensions now", name.c_str());
  150.                 }
  151.         }
  152.         assert(!duplicatedEntriesInXML);
  153. }
  154.  
  155. //////////////////////////////////////////////////////////////////////////
  156. uint32 CGameObjectSystem::GetExtensionSerializationPriority(IGameObjectSystem::ExtensionID id)
  157. {
  158.         if (id > m_extensionInfo.size())
  159.                 return 0xffffffff; // minimum possible priority
  160.         else
  161.                 return m_extensionInfo[id].serializationPriority;
  162. }
  163.  
  164. //////////////////////////////////////////////////////////////////////////
  165. IEntity* CGameObjectSystem::CreatePlayerProximityTrigger()
  166. {
  167.         IEntitySystem* pES = gEnv->pEntitySystem;
  168.         SEntitySpawnParams params;
  169.         params.nFlags = ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_NO_SAVE;
  170.         params.pClass = m_pClassPlayerProximityTrigger;
  171.         params.sName = "PlayerProximityTrigger";
  172.         IEntity* pEntity = pES->SpawnEntity(params);
  173.         if (!pEntity)
  174.                 return NULL;
  175.         if (!pEntity->CreateProxy(ENTITY_PROXY_TRIGGER))
  176.         {
  177.                 pES->RemoveEntity(pEntity->GetId());
  178.                 return NULL;
  179.         }
  180.         return pEntity;
  181. }
  182.  
  183. void CGameObjectSystem::RegisterExtension(const char* szName, IGameObjectExtensionCreatorBase* pCreator, IEntityClassRegistry::SEntityClassDesc* pClsDesc)
  184. {
  185.         string sName = szName;
  186.  
  187.         if (m_nameToID.find(sName) != m_nameToID.end())
  188.                 CryFatalError("Duplicate game object extension %s found", szName);
  189.  
  190.         SExtensionInfo info;
  191.         info.name = sName;
  192.         info.pFactory = pCreator;
  193.  
  194.         string nameLower(szName);
  195.         nameLower.MakeLower();
  196.         std::vector<string>::const_iterator result = std::find(m_serializationOrderList.begin(), m_serializationOrderList.end(), nameLower);
  197.         std::vector<string>::const_iterator firstElem = m_serializationOrderList.begin();
  198.         info.serializationPriority = uint32(std::distance(firstElem, result)); // is a valid value even if name was not found (minimum priority in that case)
  199.  
  200.         ExtensionID id = static_cast<ExtensionID>(m_extensionInfo.size());
  201.         m_extensionInfo.push_back(info);
  202.         m_nameToID[sName] = id;
  203.  
  204.         CRY_ASSERT(GetName(GetID(sName)) == sName);
  205.  
  206.         // bind network interface
  207.         void* pRMI;
  208.         size_t nRMI;
  209.         pCreator->GetGameObjectExtensionRMIData(&pRMI, &nRMI);
  210.         m_dispatch.RegisterInterface((SGameObjectExtensionRMI*)pRMI, nRMI);
  211.  
  212.         if (pClsDesc)
  213.         {
  214.                 pClsDesc->pUserProxyCreateFunc = CreateGameObjectWithPreactivatedExtension;
  215.                 //              pClsDesc->pUserProxyData = new SSpawnUserData(sName);
  216.                 if (!gEnv->pEntitySystem->GetClassRegistry()->RegisterStdClass(*pClsDesc))
  217.                 {
  218.                         CRY_ASSERT_TRACE(0, ("Unable to register entity class '%s'", szName));
  219.                         return;
  220.                 }
  221.         }
  222. }
  223.  
  224. void CGameObjectSystem::RegisterSchedulingProfile(const char* szEntityClassName, const char* szNormalPolicy, const char* szOwnedPolicy)
  225. {
  226. #if !defined(_RELEASE)
  227.         TSchedulingProfiles::iterator iter = m_schedulingParams.find(CONST_TEMP_STRING(szEntityClassName));
  228.         if (iter != m_schedulingParams.end())
  229.         {
  230.                 GameWarning("Class '%s' has already a profile assigned", szEntityClassName);
  231.         }
  232. #endif //#if !defined(_RELEASE)
  233.  
  234.         SEntitySchedulingProfiles schedulingProfile = m_defaultProfiles;
  235.  
  236.         if (szNormalPolicy)
  237.         {
  238.                 StringToKey(szNormalPolicy, schedulingProfile.normal);
  239.                 schedulingProfile.owned = schedulingProfile.normal;
  240.         }
  241.  
  242.         if (szOwnedPolicy)
  243.         {
  244.                 StringToKey(szOwnedPolicy, schedulingProfile.owned);
  245.         }
  246.  
  247.         m_schedulingParams.insert(TSchedulingProfiles::value_type(szEntityClassName, schedulingProfile));
  248. }
  249.  
  250. void CGameObjectSystem::DefineProtocol(bool server, IProtocolBuilder* pBuilder)
  251. {
  252.         INetMessageSink* pSink = server ? m_dispatch.GetServerSink() : m_dispatch.GetClientSink();
  253.         pSink->DefineProtocol(pBuilder);
  254. }
  255.  
  256. IGameObjectSystem::ExtensionID CGameObjectSystem::GetID(const char* name)
  257. {
  258.         std::map<string, ExtensionID>::const_iterator iter = m_nameToID.find(CONST_TEMP_STRING(name));
  259.         if (iter != m_nameToID.end())
  260.                 return iter->second;
  261.         else
  262.                 return InvalidExtensionID;
  263. }
  264.  
  265. const char* CGameObjectSystem::GetName(ExtensionID id)
  266. {
  267.         if (id > m_extensionInfo.size())
  268.                 return NULL;
  269.         else
  270.                 return m_extensionInfo[id].name.c_str();
  271. }
  272.  
  273. void CGameObjectSystem::BroadcastEvent(const SGameObjectEvent& evt)
  274. {
  275.         FUNCTION_PROFILER(GetISystem(), PROFILE_ACTION);
  276.  
  277.         //CryLog("BroadcastEvent called");
  278.  
  279.         IEntityItPtr pEntIt = gEnv->pEntitySystem->GetEntityIterator();
  280.         while (IEntity* pEntity = pEntIt->Next())
  281.         {
  282.                 if (CGameObject* pGameObject = (CGameObject*)pEntity->GetProxy(ENTITY_PROXY_USER))
  283.                 {
  284.                         pGameObject->SendEvent(evt);
  285.                 }
  286.         }
  287. }
  288.  
  289. void CGameObjectSystem::RegisterEvent(uint32 id, const char* name)
  290. {
  291.         if (GetEventID(name) != InvalidEventID || GetEventName(id) != 0)
  292.         {
  293.                 CryFatalError("Duplicate game object event (%u - %s) found", id, name);
  294.         }
  295.  
  296.         m_eventNameToID[name] = id;
  297.         m_eventIDToName[id] = name;
  298. }
  299.  
  300. uint32 CGameObjectSystem::GetEventID(const char* name)
  301. {
  302.         if (!name)
  303.                 return InvalidEventID;
  304.  
  305.         std::map<string, uint32>::const_iterator iter = m_eventNameToID.find(CONST_TEMP_STRING(name));
  306.         if (iter != m_eventNameToID.end())
  307.                 return iter->second;
  308.         else
  309.                 return InvalidEventID;
  310. }
  311.  
  312. const char* CGameObjectSystem::GetEventName(uint32 id)
  313. {
  314.         std::map<uint32, string>::const_iterator iter = m_eventIDToName.find(id);
  315.         if (iter != m_eventIDToName.end())
  316.                 return iter->second.c_str();
  317.         else
  318.                 return 0;
  319. }
  320.  
  321. IGameObject* CGameObjectSystem::CreateGameObjectForEntity(EntityId entityId)
  322. {
  323.         if (IGameObject* pGameObject = CCryAction::GetCryAction()->GetGameObject(entityId))
  324.                 return pGameObject;
  325.  
  326.         IEntity* pEntity = gEnv->pEntitySystem->GetEntity(entityId);
  327.         if (pEntity)
  328.         {
  329.                 auto pGameObject = pEntity->CreateComponentClass<CGameObject>();
  330.  
  331.                 // call sink
  332.                 for (SinkList::iterator si = m_lstSinks.begin(); si != m_lstSinks.end(); ++si)
  333.                 {
  334.                         (*si)->OnAfterInit(pGameObject);
  335.                 }
  336.                 //
  337.                 return pGameObject;
  338.         }
  339.  
  340.         return 0;
  341. }
  342.  
  343. IEntityComponent* CGameObjectSystem::CreateGameObjectEntityProxy(IEntity& entity, IGameObject** ppGameObject)
  344. {
  345.         auto pGameObject = entity.CreateComponentClass<CGameObject>();
  346.         if (ppGameObject)
  347.         {
  348.                 *ppGameObject = pGameObject;
  349.         }
  350.         return pGameObject;
  351. }
  352.  
  353. IGameObjectExtension* CGameObjectSystem::Instantiate(ExtensionID id, IGameObject* pObject, TSerialize* pSpawnSerializer)
  354. {
  355.         if (id > m_extensionInfo.size())
  356.                 return nullptr;
  357.  
  358.         IEntity* pEntity = pObject->GetEntity();
  359.         IGameObjectExtension* pExt = m_extensionInfo[id].pFactory->Create(pEntity);
  360.         if (!pExt)
  361.                 return nullptr;
  362.  
  363.         if (pSpawnSerializer)
  364.                 pExt->SerializeSpawnInfo(*pSpawnSerializer);
  365.  
  366.         if (!pExt->Init(pObject))
  367.         {
  368.                 pEntity->RemoveComponent(pExt);
  369.                 return nullptr;
  370.         }
  371.         return pExt;
  372. }
  373.  
  374. /* static */
  375. IEntityComponent* CGameObjectSystem::CreateGameObjectWithPreactivatedExtension(IEntity* pEntity, SEntitySpawnParams& params, void* pUserData)
  376. {
  377.         auto pGameObject = pEntity->CreateComponentClass<CGameObject>();
  378.         if (!pGameObject->ActivateExtension(params.pClass->GetName()))
  379.         {
  380.                 pEntity->RemoveComponent(pGameObject);
  381.                 return nullptr;
  382.         }
  383.  
  384.         if (params.pUserData)
  385.         {
  386.                 SEntitySpawnParamsForGameObjectWithPreactivatedExtension* pParams =
  387.                         static_cast<SEntitySpawnParamsForGameObjectWithPreactivatedExtension*>(params.pUserData);
  388.                 if (!pParams->hookFunction(pEntity, pGameObject, pParams->pUserData))
  389.                 {
  390.                         pEntity->RemoveComponent(pGameObject);
  391.                         return nullptr;
  392.                 }
  393.         }
  394.  
  395. #if GAME_OBJECT_SUPPORTS_CUSTOM_USER_DATA
  396.         pGameObject->SetUserData(params.pUserData);
  397. #endif
  398.  
  399.         return pGameObject;
  400. }
  401.  
  402. void CGameObjectSystem::PostUpdate(float frameTime)
  403. {
  404.         m_tempObjects = m_postUpdateObjects;
  405.         for (std::vector<IGameObject*>::const_iterator iter = m_tempObjects.begin(); iter != m_tempObjects.end(); ++iter)
  406.         {
  407.                 (*iter)->PostUpdate(frameTime);
  408.         }
  409. }
  410.  
  411. void CGameObjectSystem::SetPostUpdate(IGameObject* pGameObject, bool enable)
  412. {
  413.         if (enable)
  414.                 stl::push_back_unique(m_postUpdateObjects, pGameObject);
  415.         else
  416.                 stl::find_and_erase(m_postUpdateObjects, pGameObject);
  417. }
  418.  
  419. const SEntitySchedulingProfiles* CGameObjectSystem::GetEntitySchedulerProfiles(IEntity* pEnt)
  420. {
  421.         if (!gEnv->bMultiplayer)
  422.                 return &m_defaultProfiles;
  423.  
  424.         if (pEnt->GetFlags() & (ENTITY_FLAG_CLIENT_ONLY | ENTITY_FLAG_SERVER_ONLY))
  425.                 return &m_defaultProfiles;
  426.  
  427.         TSchedulingProfiles::iterator iter = m_schedulingParams.find(CONST_TEMP_STRING(pEnt->GetClass()->GetName()));
  428.  
  429.         if (iter == m_schedulingParams.end())
  430.         {
  431.                 GameWarning("No network scheduling parameters set for entities of class '%s' in EntityScheduler.xml", pEnt->GetClass()->GetName());
  432.                 return &m_defaultProfiles;
  433.         }
  434.         return &iter->second;
  435. }
  436.  
  437. //////////////////////////////////////////////////////////////////////////
  438.  
  439. void CGameObjectSystem::GetMemoryUsage(ICrySizer* s) const
  440. {
  441.         SIZER_SUBCOMPONENT_NAME(s, "GameObjectSystem");
  442.  
  443.         s->AddObject(this, sizeof(*this));
  444.         s->AddObject(m_nameToID);
  445.         s->AddObject(m_extensionInfo);
  446.         s->AddObject(m_dispatch);
  447.         s->AddObject(m_postUpdateObjects);
  448.         s->AddObject(m_schedulingParams);
  449.  
  450.         IEntityItPtr pIt = gEnv->pEntitySystem->GetEntityIterator();
  451.         while (IEntity* pEnt = pIt->Next())
  452.         {
  453.                 s->AddObject((CGameObject*)pEnt->GetProxy(ENTITY_PROXY_USER));
  454.         }
  455. }
  456.  
  457. //////////////////////////////////////////////////////////////////////
  458. void CGameObjectSystem::AddSink(IGameObjectSystemSink* pSink)
  459. {
  460.         CRY_ASSERT(pSink);
  461.  
  462.         if (pSink)
  463.                 stl::push_back_unique(m_lstSinks, pSink);
  464. }
  465.  
  466. //////////////////////////////////////////////////////////////////////////
  467. void CGameObjectSystem::RemoveSink(IGameObjectSystemSink* pSink)
  468. {
  469.         CRY_ASSERT(pSink);
  470.  
  471.         m_lstSinks.remove(pSink);
  472. }
  473.  
downloadGameObjectSystem.cpp 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