BVB Source Codes

CRYENGINE Show FlowModuleNodes.cpp Source code

Return Download CRYENGINE: download FlowModuleNodes.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 "FlowModuleNodes.h"
  5.  
  6. #include "FlowSystem/FlowSystem.h"
  7. #include "ModuleManager.h"
  8. #include "Module.h"
  9. #include "ILevelSystem.h"
  10.  
  11. //////////////////////////////////////////////////////////////////////////
  12. //
  13. // Start Node factory
  14. //
  15. //////////////////////////////////////////////////////////////////////////
  16.  
  17. CFlowModuleStartNodeFactory::CFlowModuleStartNodeFactory(CFlowGraphModule* pModule)
  18.         : m_pModule(pModule),
  19.         m_nRefCount(0)
  20. {}
  21.  
  22. CFlowModuleStartNodeFactory::~CFlowModuleStartNodeFactory()
  23. {
  24.         Reset();
  25. }
  26.  
  27. void CFlowModuleStartNodeFactory::Reset()
  28. {
  29.         stl::free_container(m_outputs);
  30. }
  31.  
  32. void CFlowModuleStartNodeFactory::GetConfiguration(SFlowNodeConfig& config)
  33. {
  34.         static const SInputPortConfig in_config[] = {
  35.                 { 0 }
  36.         };
  37.         config.pInputPorts = in_config;
  38.         config.nFlags |= EFLN_HIDE_UI | EFLN_UNREMOVEABLE;
  39.         config.SetCategory(EFLN_APPROVED);
  40.  
  41.         // if we are in runtime, the ports are no longer changing, so we only need to build once (when empty), no need to rebuild
  42.         if (m_pModule && (gEnv->IsEditing() || m_outputs.empty()))
  43.         {
  44.                 size_t customPortCount = m_pModule->GetModuleInputPortCount(); // inputs to the module should be outputs for the Start node
  45.                 size_t idx = 0;
  46.                 m_outputs.resize(5 + customPortCount); // 4 fixed ports + custom + sentinel
  47.  
  48.                 m_outputs[idx].type = eFDT_EntityId;
  49.                 m_outputs[idx].name = "EntityID";
  50.                 m_outputs[idx].description = _HELP("The ID of the Entity set in the CallNode (may be invalid if not set).");
  51.                 m_outputs[idx].humanName = _HELP("Entity ID");
  52.                 ++idx;
  53.  
  54.                 m_outputs[idx].type = eFDT_Any;
  55.                 m_outputs[idx].name = "Start";
  56.                 m_outputs[idx].description = _HELP("Activates when the module instance starts");
  57.                 ++idx;
  58.  
  59.                 m_outputs[idx].type = eFDT_Any;
  60.                 m_outputs[idx].name = "Update";
  61.                 m_outputs[idx].description = _HELP("Activates when the module instance is updated");
  62.                 ++idx;
  63.  
  64.                 m_outputs[idx].type = eFDT_Any;
  65.                 m_outputs[idx].name = "Cancel";
  66.                 m_outputs[idx].description = _HELP("Activates when the module instance is cancelled");
  67.                 ++idx;
  68.  
  69.                 for (size_t i = 0; i < customPortCount; ++i)
  70.                 {
  71.                         // inputs to the module should be outputs for the Start node
  72.                         const IFlowGraphModule::SModulePortConfig* pPort = m_pModule->GetModuleInputPort(i);
  73.                         if (pPort)
  74.                         {
  75.                                 m_outputs[idx + i].type = pPort->type;
  76.                                 m_outputs[idx + i].name = pPort->name;
  77.                         }
  78.                 }
  79.  
  80.                 m_outputs[idx + customPortCount].name = 0; //sentinel
  81.         }
  82.  
  83.         config.pOutputPorts = &m_outputs[0];
  84. }
  85.  
  86. IFlowNodePtr CFlowModuleStartNodeFactory::Create(IFlowNode::SActivationInfo* pActInfo)
  87. {
  88.         return new CFlowModuleStartNode(this, pActInfo);
  89. }
  90.  
  91. //////////////////////////////////////////////////////////////////////////
  92. //
  93. // Start Node
  94. //
  95. //////////////////////////////////////////////////////////////////////////
  96.  
  97. CFlowModuleStartNode::CFlowModuleStartNode(CFlowModuleStartNodeFactory* pFactory, SActivationInfo* pActInfo)
  98.         : m_pFactory(pFactory)
  99.         , m_pModule(pFactory->m_pModule)
  100.         , m_entityId(INVALID_ENTITYID)
  101.         , m_instanceId(MODULEINSTANCE_INVALID)
  102.         , m_bStarted(false)
  103. {}
  104.  
  105. IFlowNodePtr CFlowModuleStartNode::Clone(SActivationInfo* pActInfo)
  106. {
  107.         CFlowModuleStartNode* pNode = new CFlowModuleStartNode(m_pFactory, pActInfo);
  108.         pNode->m_entityId = m_pModule->GetEntityOfInstanceBeingCreated();
  109.         pNode->m_instanceId = m_pModule->GetInstanceIdOfInstanceBeingCreated();
  110.         m_pModule->RegisterStartNodeForInstanceBeingCreated(pNode);
  111.         return pNode;
  112. };
  113.  
  114. void CFlowModuleStartNode::GetConfiguration(SFlowNodeConfig& config)
  115. {
  116.         m_pFactory->GetConfiguration(config);
  117. }
  118.  
  119. void CFlowModuleStartNode::ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  120. {
  121.         if (eFE_Initialize == event)
  122.         {
  123.                 m_actInfo = *pActInfo;
  124.                 m_bStarted = false;
  125.         }
  126. }
  127.  
  128. void CFlowModuleStartNode::OnUpdateAllInputs(TModuleParams const* params)
  129. {
  130.         ActivateOutput(&m_actInfo, m_bStarted ? eOP_Update : eOP_Start, true);
  131.         ActivateOutput(&m_actInfo, eOP_EntityId, m_entityId);
  132.         if (params)
  133.         {
  134.                 // number of params passed in should match the number of outputs-eOP_Param1-1 for the sentinel
  135.                 assert(params->size() == m_pFactory->m_outputs.size() - eOP_Param1 - 1);
  136.                 for (size_t i = 0; i < params->size(); ++i)
  137.                 {
  138.                         ActivateOutput(&m_actInfo, eOP_Param1 + i, (*params)[i]);
  139.                 }
  140.         }
  141.         m_bStarted = true;
  142. }
  143.  
  144. void CFlowModuleStartNode::OnUpdateSingleInput(size_t idx, const TFlowInputData& value)
  145. {
  146.         assert(idx < m_pFactory->m_outputs.size() - eOP_Param1 - 1); // -1 for the sentinel
  147.  
  148.         ActivateOutput(&m_actInfo, eOP_Update, true);
  149.         ActivateOutput(&m_actInfo, eOP_Param1 + idx, value);
  150. }
  151.  
  152. void CFlowModuleStartNode::OnCancel()
  153. {
  154.         ActivateOutput(&m_actInfo, eOP_Cancel, true);
  155. }
  156.  
  157. //////////////////////////////////////////////////////////////////////////
  158. //
  159. // Return node factory
  160. //
  161. //////////////////////////////////////////////////////////////////////////
  162.  
  163. CFlowModuleReturnNodeFactory::CFlowModuleReturnNodeFactory(CFlowGraphModule* pModule)
  164.         : m_pModule(pModule)
  165.         , m_nRefCount(0)
  166. {}
  167.  
  168. CFlowModuleReturnNodeFactory::~CFlowModuleReturnNodeFactory()
  169. {
  170.         Reset();
  171. }
  172.  
  173. void CFlowModuleReturnNodeFactory::Reset()
  174. {
  175.         stl::free_container(m_inputs);
  176. }
  177.  
  178. void CFlowModuleReturnNodeFactory::GetConfiguration(SFlowNodeConfig& config)
  179. {
  180.         static const SOutputPortConfig out_config[] = {
  181.                 { 0 }
  182.         };
  183.         config.pOutputPorts = out_config;
  184.         config.nFlags |= EFLN_HIDE_UI | EFLN_UNREMOVEABLE;
  185.         config.SetCategory(EFLN_APPROVED);
  186.  
  187.         // if we are in runtime, the ports are no longer changing, so we only need to build once (when empty), no need to rebuild
  188.         if (m_pModule && (gEnv->IsEditing() || m_inputs.empty()))
  189.         {
  190.                 size_t customPortCount = m_pModule->GetModuleOutputPortCount(); // outputs from the module should be inputs for the Return node
  191.                 size_t idx = 0;
  192.                 m_inputs.resize(3 + customPortCount); // 2 fixed ports + custom + sentinel
  193.  
  194.                 m_inputs[idx].defaultData = TFlowInputData(0, false); // eFDT_Any
  195.                 m_inputs[idx].name = "Success";
  196.                 m_inputs[idx].description = _HELP("Activate to end this module instance (success)");
  197.                 ++idx;
  198.  
  199.                 m_inputs[idx].defaultData = TFlowInputData(0, false); // eFDT_Any
  200.                 m_inputs[idx].name = "Cancel";
  201.                 m_inputs[idx].description = _HELP("Activate to end this module instance (canceled)");
  202.                 ++idx;
  203.  
  204.                 for (size_t i = 0; i < customPortCount; ++i)
  205.                 {
  206.                         // outputs from the module should be inputs for the Return node
  207.                         const IFlowGraphModule::SModulePortConfig* pPort = m_pModule->GetModuleOutputPort(i);
  208.                         if (pPort)
  209.                         {
  210.                                 m_inputs[idx + i].defaultData = TFlowInputData::CreateDefaultInitializedForTag((int)pPort->type, (pPort->type == eFDT_Any ? false : true)); //lock ports of specific type
  211.                                 m_inputs[idx + i].name = pPort->name;
  212.                         }
  213.                 }
  214.  
  215.                 m_inputs[idx + customPortCount].name = 0; //sentinel
  216.         }
  217.  
  218.         config.pInputPorts = &m_inputs[0];
  219. }
  220.  
  221. IFlowNodePtr CFlowModuleReturnNodeFactory::Create(IFlowNode::SActivationInfo* pActInfo)
  222. {
  223.         return new CFlowModuleReturnNode(this, pActInfo);
  224. }
  225.  
  226. //////////////////////////////////////////////////////////////////////////
  227. //
  228. // Return node
  229. //
  230. //////////////////////////////////////////////////////////////////////////
  231.  
  232. CFlowModuleReturnNode::CFlowModuleReturnNode(CFlowModuleReturnNodeFactory* pFactory, SActivationInfo* pActInfo)
  233.         : m_pFactory(pFactory)
  234.         , m_pModule(pFactory->m_pModule)
  235.         , m_entityId(INVALID_ENTITYID)
  236.         , m_instanceId(MODULEINSTANCE_INVALID)
  237.         , m_bFinished(false)
  238. {}
  239.  
  240. IFlowNodePtr CFlowModuleReturnNode::Clone(SActivationInfo* pActInfo)
  241. {
  242.         CFlowModuleReturnNode* pNode = new CFlowModuleReturnNode(m_pFactory, pActInfo);
  243.         pNode->m_entityId = m_pModule->GetEntityOfInstanceBeingCreated();
  244.         pNode->m_instanceId = m_pModule->GetInstanceIdOfInstanceBeingCreated();
  245.         return pNode;
  246. };
  247.  
  248. void CFlowModuleReturnNode::GetConfiguration(SFlowNodeConfig& config)
  249. {
  250.         m_pFactory->GetConfiguration(config);
  251. }
  252.  
  253. void CFlowModuleReturnNode::ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  254. {
  255.         if (eFE_Initialize == event)
  256.         {
  257.                 m_actInfo = *pActInfo;
  258.         }
  259.         else if (eFE_Activate == event)
  260.         {
  261.                 // pass outputs, they will be forwarded to every call node of this instance and then effectively activated according to the output mode
  262.                 for (size_t i = eIP_Param1, numInputs = m_pFactory->m_inputs.size() - 1; i < numInputs; ++i)
  263.                 {
  264.                         if (IsPortActive(pActInfo, i))
  265.                         {
  266.                                 m_pModule->UpdateInstanceOutputPort(m_entityId, m_instanceId, i - eIP_Param1, GetPortAny(&m_actInfo, i));
  267.                         }
  268.                 }
  269.  
  270.                 if (IsPortActive(pActInfo, eIP_Success))
  271.                         OnFinished(true);
  272.                 else if (IsPortActive(pActInfo, eIP_Cancel))
  273.                         OnFinished(false);
  274.         }
  275. }
  276.  
  277. void CFlowModuleReturnNode::OnFinished(bool success)
  278. {
  279.         if (m_bFinished)
  280.         {
  281.                 return;
  282.         }
  283.  
  284.         TModuleParams params;
  285.         for (size_t i = eIP_Param1, numInputs = m_pFactory->m_inputs.size() - 1; i < numInputs; ++i)
  286.         {
  287.                 params.push_back(GetPortAny(&m_actInfo, i));
  288.         }
  289.  
  290.         m_pModule->OnInstanceFinished(m_entityId, m_instanceId, success, params);
  291.         m_bFinished = true; // the node can get multiple finish activations on the same tick, but it should only 'finish' once. ignore the following ones.
  292. }
  293.  
  294. //////////////////////////////////////////////////////////////////////////
  295. //
  296. // Call node factory
  297. //
  298. //////////////////////////////////////////////////////////////////////////
  299.  
  300. CFlowModuleCallNodeFactory::CFlowModuleCallNodeFactory(CFlowGraphModule* pModule)
  301.         : m_pModule(pModule)
  302.         , m_nRefCount(0)
  303. {}
  304.  
  305. CFlowModuleCallNodeFactory::~CFlowModuleCallNodeFactory()
  306. {
  307.         Reset();
  308. }
  309.  
  310. void CFlowModuleCallNodeFactory::Reset()
  311. {
  312.         stl::free_container(m_inputs);
  313.         stl::free_container(m_outputs);
  314. }
  315.  
  316. void CFlowModuleCallNodeFactory::GetConfiguration(SFlowNodeConfig& config)
  317. {
  318.         config.nFlags |= EFLN_TARGET_ENTITY;
  319.         config.SetCategory(EFLN_APPROVED);
  320.         config.sDescription = _HELP("Node for calling instances of a FG Module");
  321.  
  322.         // if we are in runtime, the ports are no longer changing, so we only need to build once (when empty), no need to rebuild
  323.         if (m_pModule && (gEnv->IsEditing() || m_outputs.empty() || m_inputs.empty()))
  324.         {
  325.                 // inputs
  326.                 {
  327.                         size_t customPortCount = m_pModule->GetModuleInputPortCount();
  328.                         size_t idx = 0;
  329.                         m_inputs.resize(7 + customPortCount); // 6 fixed ports + custom + sentinel
  330.  
  331.                         m_inputs[idx].defaultData = TFlowInputData(0, false); //eFDT_Any
  332.                         m_inputs[idx].name = "Call";
  333.                         m_inputs[idx].description = _HELP("Activate to call an instance of this module, if it is already running, it will update the instance with the current inputs (regardless of the input mode)");
  334.                         ++idx;
  335.  
  336.                         m_inputs[idx].defaultData = TFlowInputData(0, false); //eFDT_Any
  337.                         m_inputs[idx].name = "Cancel";
  338.                         m_inputs[idx].description = _HELP("Send a Cancel input to the module instance");
  339.                         ++idx;
  340.  
  341.                         m_inputs[idx].defaultData = TFlowInputData(false, true);
  342.                         m_inputs[idx].name = "GlobalController";
  343.                         m_inputs[idx].description = _HELP("Set to true to send inputs and listen to outputs of all the active instances of the module");
  344.                         ++idx;
  345.  
  346.                         m_inputs[idx].defaultData = TFlowInputData(-1, true);
  347.                         m_inputs[idx].name = "InstanceID";
  348.                         m_inputs[idx].description = _HELP("ID to identify instance of the module run by this call node. -1 will automatically generate an ID");
  349.                         ++idx;
  350.  
  351.                         m_inputs[idx].defaultData = TFlowInputData(false, true);
  352.                         m_inputs[idx].name = "ContinuousInput";
  353.                         m_inputs[idx].description = _HELP("If set to true, it will pass in inputs individually to the instance when they are triggered without need for a 'Call' trigger. Otherwise, all inputs are passed in to the instance only when 'Call' is triggered.");
  354.                         ++idx;
  355.  
  356.                         m_inputs[idx].defaultData = TFlowInputData(false, true);
  357.                         m_inputs[idx].name = "ContinuousOutput";
  358.                         m_inputs[idx].description = _HELP("If set to true, this node's output will activate immediately when the instance sends them. Otherwise this node only activates the outputs when the instance is 'Done' sucessfuly.");
  359.                         ++idx;
  360.  
  361.                         for (size_t i = 0; i < customPortCount; ++i)
  362.                         {
  363.                                 const IFlowGraphModule::SModulePortConfig* pPort = m_pModule->GetModuleInputPort(i);
  364.                                 if (pPort && pPort->input)
  365.                                 {
  366.                                         m_inputs[idx + i].defaultData = TFlowInputData::CreateDefaultInitializedForTag((int)pPort->type, (pPort->type == eFDT_Any ? false : true)); //lock ports of specific type
  367.                                         m_inputs[idx + i].name = pPort->name;
  368.                                 }
  369.                         }
  370.  
  371.                         m_inputs[idx + customPortCount].name = 0; //sentinel
  372.                 }
  373.  
  374.                 // outputs
  375.                 {
  376.                         size_t customPortCount = m_pModule->GetModuleOutputPortCount();
  377.                         size_t idx = 0;
  378.                         m_outputs.resize(4 + customPortCount); // 3 fixed ports + custom + sentinel
  379.  
  380.                         m_outputs[idx].type = eFDT_Int;
  381.                         m_outputs[idx].name = "OnCalled";
  382.                         m_outputs[idx].description = _HELP("Activated when the module instance is created. Outputs the ID of the instance run by this call node");
  383.                         ++idx;
  384.  
  385.                         m_outputs[idx].type = eFDT_Any;
  386.                         m_outputs[idx].name = "Done";
  387.                         m_outputs[idx].description = _HELP("Called when the instance finishes with a successful status");
  388.                         ++idx;
  389.  
  390.                         m_outputs[idx].type = eFDT_Any;
  391.                         m_outputs[idx].name = "Canceled";
  392.                         m_outputs[idx].description = _HELP("Called when the module was cancelled internally");
  393.                         ++idx;
  394.  
  395.                         for (size_t i = 0; i < customPortCount; ++i)
  396.                         {
  397.                                 const IFlowGraphModule::SModulePortConfig* pPort = m_pModule->GetModuleOutputPort(i);
  398.                                 if (pPort && !pPort->input)
  399.                                 {
  400.                                         m_outputs[idx + i].type = pPort->type;
  401.                                         m_outputs[idx + i].name = pPort->name;
  402.                                 }
  403.                         }
  404.  
  405.                         m_outputs[idx + customPortCount].name = 0; //sentinel
  406.                 }
  407.         }
  408.  
  409.         config.pInputPorts = &m_inputs[0];
  410.         config.pOutputPorts = &m_outputs[0];
  411. }
  412.  
  413. IFlowNodePtr CFlowModuleCallNodeFactory::Create(IFlowNode::SActivationInfo* pActInfo)
  414. {
  415.         return new CFlowModuleCallNode(this, pActInfo);
  416. }
  417.  
  418. //////////////////////////////////////////////////////////////////////////
  419. //
  420. // Call node
  421. //
  422. //////////////////////////////////////////////////////////////////////////
  423.  
  424. uint CFlowModuleCallNode::s_nextCallNodeId = 0;
  425.  
  426. CFlowModuleCallNode::CFlowModuleCallNode(CFlowModuleCallNodeFactory* pFactory, SActivationInfo* pActInfo)
  427.         : m_callNodeId(++s_nextCallNodeId)
  428.         , m_pFactory(pFactory)
  429.         , m_pModule(pFactory->m_pModule)
  430.         , m_moduleId(pFactory->m_pModule->GetId())
  431.         , m_entityId(INVALID_ENTITYID)
  432.         , m_instanceId(MODULEINSTANCE_INVALID)
  433.         , m_bIsGlobal(false)
  434.         , m_bEntityChanged(false)
  435. {}
  436.  
  437. CFlowModuleCallNode::~CFlowModuleCallNode()
  438. {
  439.         CFlowGraphModuleManager* pModuleManager = static_cast<CFlowSystem*>(gEnv->pFlowSystem)->GetModuleManager();
  440.         if (!pModuleManager->GetModule(m_moduleId))
  441.         {
  442.                 // it is possible that the module that a call node is associated with was already deleted
  443.                 // if there is a circular dependency of module calls when running from the launcher. check just in case.
  444.                 // no need to unregister from the module if it was already deleted
  445.                 return;
  446.         }
  447.  
  448.         // remove all references that could possibly be registered
  449.         m_pModule->UnregisterCallNodeForInstance(m_entityId, m_instanceId, m_callNodeId);
  450.         m_pModule->UnregisterGlobalControlNode(m_callNodeId);
  451. }
  452.  
  453. IFlowNodePtr CFlowModuleCallNode::Clone(SActivationInfo* pActInfo)
  454. {
  455.         IFlowNode* pNode = new CFlowModuleCallNode(m_pFactory, pActInfo);
  456.         return pNode;
  457. };
  458.  
  459. void CFlowModuleCallNode::GetConfiguration(SFlowNodeConfig& config)
  460. {
  461.         m_pFactory->GetConfiguration(config);
  462. }
  463.  
  464. void CFlowModuleCallNode::ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  465. {
  466.         if (eFE_Initialize == event)
  467.         {
  468.                 m_actInfo = *pActInfo;
  469.  
  470.                 m_instanceId = static_cast<TModuleInstanceId>(GetPortInt(pActInfo, eIP_InstanceId));
  471.                 m_entityId = pActInfo->pEntity ? pActInfo->pEntity->GetId() : INVALID_ENTITYID;
  472.  
  473.                 m_bIsGlobal = GetPortBool(pActInfo, eIP_IsGlobalController);
  474.                 if (m_bIsGlobal)
  475.                 {
  476.                         // global nodes ignore the entityID. This is a design decision.
  477.                         // The alternative would be to update instances only of that entity, which sounds consistent, but in practice is not a common case
  478.                         // (common case would be to accidentally set the entity and only have 1 instance updated instead of all)
  479.                         m_pModule->RegisterGlobalControlNode(m_callNodeId, this);
  480.                 }
  481.                 else
  482.                 {
  483.                         m_pModule->RegisterCallNodeForInstance(m_entityId, m_instanceId, m_callNodeId, this);
  484.                 }
  485.  
  486.                 m_bEntityChanged = false;
  487.         }
  488.         else if (event == eFE_SetEntityId)
  489.         {
  490.                 m_bEntityChanged = true;
  491.         }
  492.         else if (eFE_Activate == event)
  493.         {
  494.                 // Abandon all hope, ye who enter here
  495.                 // do not add 'else' to the 'ifs' - all ports can be triggered in combination at the same time
  496.  
  497.                 if (IsPortActive(pActInfo, eIP_InstanceId) || m_bEntityChanged)
  498.                 {
  499.                         if (!GetPortBool(pActInfo, eIP_IsGlobalController))
  500.                         {
  501.                                 // change registry of this call node to the new Entity + Instance ID if it changed
  502.                                 EntityId newEntityId = pActInfo->pEntity ? pActInfo->pEntity->GetId() : INVALID_ENTITYID;
  503.                                 TModuleInstanceId newInstanceId = static_cast<TModuleInstanceId>(GetPortInt(pActInfo, eIP_InstanceId));
  504.                                 if (newEntityId != m_entityId || newInstanceId != m_instanceId)
  505.                                 {
  506.                                         m_pModule->ChangeRegisterCallNodeForInstance(m_entityId, m_instanceId, newEntityId, newInstanceId, m_callNodeId, this);
  507.                                         m_entityId = newEntityId;
  508.                                         m_instanceId = newInstanceId;
  509.                                 }
  510.                         }
  511.                 }
  512.  
  513.                 if (IsPortActive(pActInfo, eIP_IsGlobalController))
  514.                 {
  515.                         bool bNewIsGlobal = GetPortBool(pActInfo, eIP_IsGlobalController);
  516.                         if (m_bIsGlobal != bNewIsGlobal)
  517.                         {
  518.                                 if (bNewIsGlobal)
  519.                                 {
  520.                                         // node changed to global
  521.                                         m_pModule->UnregisterCallNodeForInstance(m_entityId, m_instanceId, m_callNodeId);
  522.                                         m_pModule->RegisterGlobalControlNode(m_callNodeId, this);
  523.                                 }
  524.                                 else
  525.                                 {
  526.                                         // node changed to not global
  527.                                         m_pModule->UnregisterGlobalControlNode(m_callNodeId);
  528.                                         if (m_entityId || m_instanceId != MODULEINSTANCE_INVALID)
  529.                                         {
  530.                                                 m_pModule->RegisterCallNodeForInstance(m_entityId, m_instanceId, m_callNodeId, this);
  531.                                         }
  532.                                 }
  533.                                 m_bIsGlobal = bNewIsGlobal;
  534.                         }
  535.                 }
  536.  
  537.                 if (IsPortActive(pActInfo, eIP_Call))
  538.                 {
  539.                         // extract and load parameters
  540.                         TModuleParams params;
  541.                         for (size_t i = eIP_Param1, numInputs = m_pFactory->m_inputs.size() - 1; i < numInputs; ++i) // size-1 for the sentinel
  542.                         {
  543.                                 params.push_back(GetPortAny(pActInfo, i));
  544.                         }
  545.  
  546.                         if (GetPortBool(pActInfo, eIP_IsGlobalController))
  547.                         {
  548.                                 m_pModule->CallAllModuleInstances(params, this);
  549.                         }
  550.                         else
  551.                         {
  552.                                 // call the instance will start it or update it with new inputs
  553.                                 // the instance is always called with the actual id on the port (not the saved member variable), specially in case it is '-1'
  554.                                 TModuleInstanceId actualInstanceId = static_cast<TModuleInstanceId>(GetPortInt(pActInfo, eIP_InstanceId));
  555.                                 if (actualInstanceId != m_instanceId)
  556.                                 {
  557.                                         // CallModuleInstance will change the instance this node is associated with.
  558.                                         m_pModule->UnregisterCallNodeForInstance(m_entityId, m_instanceId, m_callNodeId);
  559.                                 }
  560.                                 m_instanceId = m_pModule->CallModuleInstance(m_entityId, actualInstanceId, params, this);
  561.                         }
  562.                 }
  563.  
  564.                 if (IsPortActive(pActInfo, eIP_Cancel))
  565.                 {
  566.                         if (GetPortBool(pActInfo, eIP_IsGlobalController))
  567.                         {
  568.                                 m_pModule->CancelAllInstances();
  569.                         }
  570.                         else
  571.                         {
  572.                                 m_pModule->CancelInstance(m_entityId, m_instanceId);
  573.                         }
  574.                 }
  575.  
  576.                 if (IsPortActive(pActInfo, eIP_ContInput) || IsPortActive(pActInfo, eIP_ContOutput))
  577.                 {
  578.                         // no need to do anything
  579.                 }
  580.  
  581.                 // data inputs for the module
  582.                 // without continuous input, a trigger on the call port is required to update inputs
  583.                 if (GetPortBool(pActInfo, eIP_ContInput))
  584.                 {
  585.                         if (GetPortBool(pActInfo, eIP_IsGlobalController))
  586.                         {
  587.                                 // pass active inputs to all existing instances. do not create new ones.
  588.                                 for (size_t i = eIP_Param1, numInputs = m_pFactory->m_inputs.size() - 1; i < numInputs; ++i) // size-1 for the sentinel
  589.                                 {
  590.                                         if (IsPortActive(pActInfo, i))
  591.                                         {
  592.                                                 m_pModule->UpdateAllInstancesInputPort(i - eIP_Param1, GetPortAny(pActInfo, i));
  593.                                         }
  594.                                 }
  595.                         }
  596.                         else
  597.                         {
  598.                                 // pass active inputs in to existing instance. do not create a new one.
  599.                                 if (m_entityId != INVALID_ENTITYID || m_instanceId != MODULEINSTANCE_INVALID)
  600.                                 {
  601.                                         for (size_t i = eIP_Param1, numInputs = m_pFactory->m_inputs.size() - 1; i < numInputs; ++i) // size-1 for the sentinel
  602.                                         {
  603.                                                 if (IsPortActive(pActInfo, i))
  604.                                                 {
  605.                                                         m_pModule->UpdateInstanceInputPort(m_entityId, m_instanceId, i - eIP_Param1, GetPortAny(pActInfo, i));
  606.                                                 }
  607.                                         }
  608.                                 }
  609.                         }
  610.                 }
  611.  
  612.                 m_bEntityChanged = false;
  613.         }
  614. }
  615.  
  616. void CFlowModuleCallNode::OnInstanceStarted(TModuleInstanceId instanceId)
  617. {
  618.         if (instanceId == MODULEINSTANCE_INVALID && (m_bIsGlobal || m_entityId != INVALID_ENTITYID))
  619.         {
  620.                 ActivateOutput(&m_actInfo, eOP_OnCall, -1);
  621.         }
  622.         else
  623.         {
  624.                 ActivateOutput(&m_actInfo, eOP_OnCall, instanceId);
  625.         }
  626. }
  627.  
  628. void CFlowModuleCallNode::OnInstanceOutput(size_t paramIdx, const TFlowInputData& value)
  629. {
  630.         assert(paramIdx < m_pFactory->m_outputs.size());
  631.  
  632.         if (GetPortBool(&m_actInfo, eIP_ContOutput))
  633.         {
  634.                 ActivateOutput(&m_actInfo, eOP_Param1 + paramIdx, value);
  635.         }
  636. }
  637.  
  638. void CFlowModuleCallNode::OnInstanceFinished(bool bSuccess, const TModuleParams& params)
  639. {
  640.         assert(params.size() == m_pFactory->m_outputs.size() - eOP_Param1 - 1);
  641.  
  642.         if (bSuccess)
  643.         {
  644.                 ActivateOutput(&m_actInfo, eOP_Success, true);
  645.  
  646.                 if (!GetPortBool(&m_actInfo, eIP_ContOutput))
  647.                 {
  648.                         for (size_t i = 0, numOutputs = m_pFactory->m_outputs.size() - eOP_Param1 - 1; i < numOutputs; ++i)
  649.                         {
  650.                                 ActivateOutput(&m_actInfo, eOP_Param1 + i, params[i]);
  651.                         }
  652.                 }
  653.         }
  654.         else
  655.         {
  656.                 ActivateOutput(&m_actInfo, eOP_Canceled, true);
  657.         }
  658.  
  659.         m_instanceId = MODULEINSTANCE_INVALID;
  660. }
  661.  
  662. //////////////////////////////////////////////////////////////////////////
  663. //
  664. // Module ID map node
  665. //
  666. //////////////////////////////////////////////////////////////////////////
  667. CFlowModuleUserIdNode::TInstanceUserIDs CFlowModuleUserIdNode::s_ids;
  668.  
  669. void CFlowModuleUserIdNode::GetConfiguration(SFlowNodeConfig& config)
  670. {
  671.         static const SInputPortConfig in_config[] = {
  672.                 InputPortConfig_Void("Get",           _HELP("Get Module instance id for given user id")),
  673.                 InputPortConfig_Void("Set",           _HELP("Sets Module instance id for given user id")),
  674.                 InputPortConfig<int>("UserID",     0, _HELP("Custom user id (e.g. an entity id)")),
  675.                 InputPortConfig<string>("ModuleName", _HELP("Name of the FG Module"), _HELP("Module Name"), _UICONFIG("dt=fgmodules")),
  676.                 InputPortConfig<int>("InstanceID",-1, _HELP("Module instance id")),
  677.                 { 0 }
  678.         };
  679.  
  680.         static const SOutputPortConfig out_config[] = {
  681.                 OutputPortConfig<int>("ModuleId", _HELP("Module instance id for given user id (returns -1 if not id was found)"), _HELP("InstanceID")),
  682.                 { 0 }
  683.         };
  684.  
  685.         config.sDescription = _HELP("Node to create and access a map of 'user IDs' to module instance IDs. 'Users' are anything that relate with instances (eg: associate an Entity ID with an Instance ID).");
  686.         config.pInputPorts = in_config;
  687.         config.pOutputPorts = out_config;
  688.         config.SetCategory(EFLN_APPROVED);
  689. }
  690.  
  691. void CFlowModuleUserIdNode::ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  692. {
  693.         switch (event)
  694.         {
  695.         case eFE_Initialize:
  696.                 s_ids.clear();
  697.                 break;
  698.         case eFE_Activate:
  699.                 if (IsPortActive(pActInfo, eIP_Get))
  700.                 {
  701.                         const string& moduleName = GetPortString(pActInfo, eIP_ModuleName);
  702.                         const int userid = GetPortInt(pActInfo, eIP_UserId);
  703.  
  704.                         TInstanceUserIDs::const_iterator it = s_ids.find(moduleName);
  705.                         if (it != s_ids.end())
  706.                         {
  707.                                 std::map<int, TModuleInstanceId>::const_iterator it2 = it->second.find(userid);
  708.                                 if (it2 != it->second.end())
  709.                                 {
  710.                                         ActivateOutput(pActInfo, eOP_ModuleInstanceId, it2->second);
  711.                                 }
  712.                                 else
  713.                                 {
  714.                                         ActivateOutput(pActInfo, eOP_ModuleInstanceId, MODULEINSTANCE_INVALID);
  715.                                 }
  716.                         }
  717.                         else
  718.                         {
  719.                                 ActivateOutput(pActInfo, eOP_ModuleInstanceId, MODULEINSTANCE_INVALID);
  720.                         }
  721.                 }
  722.                 else if (IsPortActive(pActInfo, eIP_Set))
  723.                 {
  724.                         const string& moduleName = GetPortString(pActInfo, eIP_ModuleName);
  725.                         const int instanceId = GetPortInt(pActInfo, eIP_ModuleInstanceId);
  726.                         const int userid = GetPortInt(pActInfo, eIP_UserId);
  727.                         s_ids[moduleName][userid] = instanceId;
  728.                 }
  729.                 break;
  730.         }
  731. }
  732.  
  733. //////////////////////////////////////////////////////////////////////////
  734. //
  735. // Running Instances Count Listener Node
  736. //
  737. //////////////////////////////////////////////////////////////////////////
  738. CFlowModuleCountListener::CFlowModuleCountListener(SActivationInfo* pActInfo)
  739.         : m_sModuleName(nullptr)
  740. {
  741.         CFlowGraphModuleManager* pModuleManager = static_cast<CFlowSystem*>(gEnv->pFlowSystem)->GetModuleManager();
  742.         pModuleManager->RegisterListener(this, "CFlowModuleCountListener");
  743. }
  744.  
  745. CFlowModuleCountListener::~CFlowModuleCountListener()
  746. {
  747.         CFlowGraphModuleManager* pModuleManager = static_cast<CFlowSystem*>(gEnv->pFlowSystem)->GetModuleManager();
  748.         pModuleManager->UnregisterListener(this);
  749. }
  750.  
  751. IFlowNodePtr CFlowModuleCountListener::Clone(SActivationInfo* pActInfo)
  752. {
  753.         return new CFlowModuleCountListener(pActInfo);
  754. }
  755.  
  756. void CFlowModuleCountListener::GetConfiguration(SFlowNodeConfig& config)
  757. {
  758.         static const SInputPortConfig in_config[] = {
  759.                 InputPortConfig<string>("ModuleName", _HELP("Name of the FG Module"), _HELP("Module Name"), _UICONFIG("dt=fgmodules")),
  760.                 { 0 }
  761.         };
  762.  
  763.         static const SOutputPortConfig out_config[] = {
  764.                 OutputPortConfig<int>("Count", _HELP("Number of running instances of this module. -1 if the module name is not found")),
  765.                 { 0 }
  766.         };
  767.  
  768.         config.sDescription = _HELP("Outputs in real-time the number of running instances of a given module");
  769.         config.pInputPorts = in_config;
  770.         config.pOutputPorts = out_config;
  771.         config.SetCategory(EFLN_APPROVED);
  772. }
  773.  
  774. void CFlowModuleCountListener::ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  775. {
  776.         switch (event)
  777.         {
  778.         case eFE_Initialize:
  779.                 m_actInfo = *pActInfo;
  780.                 m_sModuleName = GetPortString(pActInfo, eIP_ModuleName);
  781.                 break;
  782.         case eFE_Activate:
  783.                 if (IsPortActive(pActInfo, eIP_ModuleName))
  784.                 {
  785.                         m_sModuleName = GetPortString(pActInfo, eIP_ModuleName);
  786.                         CFlowGraphModuleManager* pModuleManager = static_cast<CFlowSystem*>(gEnv->pFlowSystem)->GetModuleManager();
  787.                         CFlowGraphModule* pModule = static_cast<CFlowGraphModule*>(pModuleManager->GetModule(m_sModuleName.c_str()));
  788.                         ActivateOutput(pActInfo, eOP_InstanceCount, pModule ? static_cast<int>(pModule->GetRunningInstancesCount()) : -1);
  789.                 }
  790.                 break;
  791.         }
  792. }
  793.  
  794. void CFlowModuleCountListener::OnModuleInstanceCreated(IFlowGraphModule* pModule, TModuleInstanceId instanceID)
  795. {
  796.         if (m_sModuleName.compareNoCase(pModule->GetName()) == 0)
  797.         {
  798.                 ActivateOutput(&m_actInfo, eOP_InstanceCount, static_cast<int>(pModule->GetRunningInstancesCount()));
  799.         }
  800. }
  801.  
  802. void CFlowModuleCountListener::OnModuleInstanceDestroyed(IFlowGraphModule* pModule, TModuleInstanceId instanceID)
  803. {
  804.         if (m_sModuleName.compareNoCase(pModule->GetName()) == 0)
  805.         {
  806.                 ActivateOutput(&m_actInfo, eOP_InstanceCount, static_cast<int>(pModule->GetRunningInstancesCount()));
  807.         }
  808. }
  809.  
  810. REGISTER_FLOW_NODE("Module:Utils:UserIDToModuleID", CFlowModuleUserIdNode);
  811. REGISTER_FLOW_NODE("Module:Utils:InstanceCountListener", CFlowModuleCountListener);
  812.  
downloadFlowModuleNodes.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