BVB Source Codes

CRYENGINE Show FlowDelayNode.cpp Source code

Return Download CRYENGINE: download FlowDelayNode.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 "FlowDelayNode.h"
  5. #include "CryAction.h"
  6.  
  7. CFlowDelayNode::CFlowDelayNode(SActivationInfo* pActInfo) : m_actInfo(*pActInfo)
  8. {
  9. }
  10.  
  11. CFlowDelayNode::~CFlowDelayNode()
  12. {
  13.         RemovePendingTimers();
  14. }
  15.  
  16. void
  17. CFlowDelayNode::RemovePendingTimers()
  18. {
  19.         // remove all old timers we have
  20.         if (!gEnv->IsEditor() && !gEnv->pSystem->IsQuitting())
  21.         {
  22.                 Activations::iterator iter;
  23.                 if (!m_activations.empty())
  24.                 {
  25.                         for (iter = m_activations.begin(); iter != m_activations.end(); ++iter)
  26.                         {
  27.                                 CCryAction::GetCryAction()->RemoveTimer((*iter).first);
  28.                         }
  29.                 }
  30.         }
  31.         // clear in any case (Editor and Game mode)
  32.         m_activations.clear();
  33. }
  34.  
  35. IFlowNodePtr CFlowDelayNode::Clone(SActivationInfo* pActInfo)
  36. {
  37.         return new CFlowDelayNode(pActInfo);
  38. }
  39.  
  40. void CFlowDelayNode::Serialize(SActivationInfo* pActInfo, TSerialize ser)
  41. {
  42.         CTimeValue curTime = gEnv->pTimer->GetFrameStartTime();
  43.  
  44.         ser.BeginGroup("Local");
  45.         // Editor mode: map with
  46.         // key:  abs time in ms
  47.         // data: SDelayData
  48.         //
  49.         // Game mode: map with
  50.         // key:  timer id (we don't care about it)
  51.         // data: SDelayData
  52.         if (ser.IsWriting())
  53.         {
  54.                 // when writing, currently relative values are stored!
  55.                 ser.Value("m_activations", m_activations);
  56. #if 0
  57.                 CryLogAlways("CDelayNode write: current time(ms): %f", curTime.GetMilliSeconds());
  58.                 Activations::iterator iter = m_activations.begin();
  59.                 while (iter != m_activations.end())
  60.                 {
  61.                         CryLogAlways("CDelayNode write: ms=%d  timevalue(ms): %f", (*iter).first, (*iter).second.m_timeout.GetMilliSeconds());
  62.                         ++iter;
  63.                 }
  64. #endif
  65.         }
  66.         else
  67.         {
  68.                 // FIXME: should we read the curTime from the file
  69.                 //        or is the FrameStartTime already set to the serialized value?
  70.                 // ser.Value("curTime", curTime);
  71.  
  72.                 // when reading we have to differentiate between Editor and Game Mode
  73.                 if (gEnv->IsEditor())
  74.                 {
  75.                         // we can directly read into the m_activations array
  76.                         // regular update is handled by CFlowGraph
  77.                         ser.Value("m_activations", m_activations);
  78.                         Activations::iterator iter = m_activations.begin();
  79. #if 0
  80.                         CryLogAlways("CDelayNode read: current time(ms): %f", curTime.GetMilliSeconds());
  81.                         while (iter != m_activations.end())
  82.                         {
  83.                                 CryLogAlways("CDelayNode read: ms=%d  timevalue(ms): %f", (*iter).first, (*iter).second.m_timeout.GetMilliSeconds());
  84.                                 ++iter;
  85.                         }
  86. #endif
  87.                         pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, !m_activations.empty());
  88.                 }
  89.                 else
  90.                 {
  91.                         RemovePendingTimers();
  92.                         // read serialized activations and re-register at timer
  93.                         Activations::iterator iter;
  94.                         Activations activations;
  95.                         ser.Value("m_activations", activations);
  96.                         for (iter = activations.begin(); iter != activations.end(); ++iter)
  97.                         {
  98.                                 CTimeValue relTime = (*iter).second.m_timeout - curTime;
  99.                                 IGameFramework::TimerID timerId = CCryAction::GetCryAction()->AddTimer(relTime, false, functor(CFlowDelayNode::OnTimer),
  100.                                                                                                        this);
  101.                                 m_activations[timerId] = (*iter).second;
  102.                         }
  103.                 }
  104.         }
  105.         ser.EndGroup();
  106. }
  107.  
  108. void CFlowDelayNode::GetConfiguration(SFlowNodeConfig& config)
  109. {
  110.         static const SInputPortConfig inputs[] = {
  111.                 InputPortConfig_AnyType("in",         _HELP("Value to be passed after [Delay] time"), _HELP("In")),
  112.                 InputPortConfig<float>("delay",       1.0f,                                           _HELP("Delay time in seconds"),                                                                                             _HELP("Delay")),
  113.                 InputPortConfig<bool>("resetOnInput", false,                                          _HELP("When true, the node is reseted with each input (delay counter is reseted to 0, and previous inputs are forgotten)")),
  114.                 { 0 }
  115.         };
  116.  
  117.         static const SOutputPortConfig outputs[] = {
  118.                 OutputPortConfig_AnyType("out", _HELP("Out")),
  119.                 { 0 }
  120.         };
  121.  
  122.         config.sDescription = _HELP("This node will delay passing the signal from [In] to [Out] for the specified number of seconds in [Delay]");
  123.         config.pInputPorts = inputs;
  124.         config.pOutputPorts = outputs;
  125.         config.SetCategory(EFLN_APPROVED);
  126. }
  127.  
  128. void CFlowDelayNode::ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  129. {
  130.         switch (event)
  131.         {
  132.         case eFE_Initialize:
  133.                 RemovePendingTimers();
  134.                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  135.                 break;
  136.  
  137.         case eFE_Activate:
  138.                 // we request a final activation if the input value changed
  139.                 // thus in case we get several inputs in ONE frame, we always only use the LAST one!
  140.                 if (IsPortActive(pActInfo, INP_IN))
  141.                 {
  142.                         pActInfo->pGraph->RequestFinalActivation(pActInfo->myID);
  143.                 }
  144.                 break;
  145.  
  146.         case eFE_FinalActivate:
  147.                 {
  148.                         bool shouldReset = GetShouldReset(pActInfo);
  149.  
  150.                         if (gEnv->IsEditor())
  151.                         {
  152.                                 if (shouldReset)
  153.                                         m_activations.clear();
  154.                                 const float delay = GetDelayTime(pActInfo);
  155.                                 CTimeValue finishTime = gEnv->pTimer->GetFrameStartTime() + delay;
  156.                                 m_activations[(int)finishTime.GetMilliSeconds()] = SDelayData(finishTime, pActInfo->pInputPorts[0]);
  157.                                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);
  158.                         }
  159.                         else
  160.                         {
  161.                                 if (shouldReset)
  162.                                 {
  163.                                         for (Activations::iterator iter = m_activations.begin(); iter != m_activations.end(); ++iter)
  164.                                         {
  165.                                                 IGameFramework::TimerID timerId = (*iter).first;
  166.                                                 CCryAction::GetCryAction()->RemoveTimer(timerId);
  167.                                         }
  168.                                         m_activations.clear();
  169.                                 }
  170.  
  171.                                 const float delay = GetDelayTime(pActInfo);
  172.                                 CTimeValue finishTime = gEnv->pTimer->GetFrameStartTime() + delay;
  173.                                 IGameFramework::TimerID timerId = CCryAction::GetCryAction()->AddTimer(delay, false, functor(CFlowDelayNode::OnTimer),
  174.                                                                                                        this);
  175.                                 m_activations[timerId] = SDelayData(finishTime, pActInfo->pInputPorts[0]);
  176.                         }
  177.                         break;
  178.                 }
  179.  
  180.         case eFE_Update:
  181.                 CRY_ASSERT(gEnv->IsEditor());
  182.                 CRY_ASSERT(!m_activations.empty());
  183.                 CTimeValue curTime = gEnv->pTimer->GetFrameStartTime();
  184.  
  185.                 while (!m_activations.empty() && m_activations.begin()->second.m_timeout < curTime)
  186.                 {
  187.                         ActivateOutput(pActInfo, 0, m_activations.begin()->second.m_data);
  188.                         m_activations.erase(m_activations.begin());
  189.                 }
  190.                 if (m_activations.empty())
  191.                         pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  192.                 break;
  193.         }
  194. }
  195.  
  196. float CFlowDelayNode::GetDelayTime(SActivationInfo* pActInfo) const
  197. {
  198.         return GetPortFloat(pActInfo, INP_DELAY);
  199. }
  200.  
  201. void CFlowDelayNode::OnTimer(void* pUserData, IGameFramework::TimerID ref)
  202. {
  203.         CRY_ASSERT(gEnv->IsEditor() == false);
  204.  
  205.         CFlowDelayNode* pThis = static_cast<CFlowDelayNode*>(pUserData);
  206.         Activations::iterator iter = pThis->m_activations.find(ref);
  207.         if (iter == pThis->m_activations.end())
  208.         {
  209.                 GameWarning("CFlowDelayNode::OnTimer: Stale reference %d", ref);
  210.                 return;
  211.         }
  212.         ActivateOutput(&pThis->m_actInfo, 0, iter->second.m_data);
  213.         pThis->m_activations.erase(iter);
  214. }
  215.  
  216. bool CFlowDelayNode::GetShouldReset(SActivationInfo* pActInfo)
  217. {
  218.         return GetPortBool(pActInfo, INP_RESET_ON_EACH_INPUT);
  219. }
  220.  
  221. //////////////////////////////////////////////////////////////////////////
  222. class CFlowRandomDelayNode : public CFlowDelayNode
  223. {
  224. public:
  225.         CFlowRandomDelayNode(SActivationInfo* pActInfo) : CFlowDelayNode(pActInfo)
  226.         {
  227.         }
  228.  
  229.         virtual ~CFlowRandomDelayNode()
  230.         {
  231.         }
  232.  
  233.         IFlowNodePtr Clone(SActivationInfo* pActInfo)
  234.         {
  235.                 return new CFlowRandomDelayNode(pActInfo);
  236.         }
  237.  
  238.         void GetConfiguration(SFlowNodeConfig& config)
  239.         {
  240.                 static const SInputPortConfig inputs[] = {
  241.                         InputPortConfig_AnyType("In",      _HELP("Value to be passed after delay time")),
  242.                         InputPortConfig<float>("MinDelay", 1.0f,                                         _HELP("Minimum random delay time in seconds")),
  243.                         InputPortConfig<float>("MaxDelay", 2.0f,                                         _HELP("Maximum random delay time in seconds")),
  244.                         { 0 }
  245.                 };
  246.  
  247.                 static const SOutputPortConfig outputs[] = {
  248.                         OutputPortConfig_AnyType("Out"),
  249.                         { 0 }
  250.                 };
  251.  
  252.                 config.sDescription = _HELP("This node will delay passing the signal from the [In] to [Out] for a random amount of time in the interval [MinDelay,MaxDelay]");
  253.                 config.pInputPorts = inputs;
  254.                 config.pOutputPorts = outputs;
  255.                 config.SetCategory(EFLN_APPROVED);
  256.         }
  257.  
  258. protected:
  259.         /* virtual */ float GetDelayTime(SActivationInfo* pActInfo) const
  260.         {
  261.                 return cry_random(GetPortFloat(pActInfo, 1), GetPortFloat(pActInfo, 2));
  262.         }
  263.  
  264.         bool GetShouldReset(SActivationInfo* pActInfo)
  265.         {
  266.                 return false;
  267.         }
  268.  
  269. };
  270.  
  271. class CFlowFrameDelayNode : public CFlowBaseNode<eNCT_Instanced>
  272. {
  273. public:
  274.         CFlowFrameDelayNode(SActivationInfo* pActInfo) : m_frameStamp(0) {}
  275.  
  276.         IFlowNodePtr Clone(SActivationInfo* pActInfo)
  277.         {
  278.                 return new CFlowFrameDelayNode(pActInfo);
  279.         }
  280.  
  281.         void GetConfiguration(SFlowNodeConfig& config)
  282.         {
  283.                 static const SInputPortConfig inputs[] = {
  284.                         InputPortConfig_AnyType("in", _HELP("Value to be passed after one frame delay"), _HELP("In")),
  285.                         { 0 }
  286.                 };
  287.  
  288.                 static const SOutputPortConfig outputs[] = {
  289.                         OutputPortConfig_AnyType("out", _HELP("Out")),
  290.                         { 0 }
  291.                 };
  292.  
  293.                 config.sDescription = _HELP("This node will delay passing the signal from [In] to [Out] for one frame");
  294.                 config.pInputPorts = inputs;
  295.                 config.pOutputPorts = outputs;
  296.                 config.SetCategory(EFLN_APPROVED);
  297.         }
  298.  
  299.         void ProcessEvent(EFlowEvent event, SActivationInfo* pActInfo)
  300.         {
  301.                 switch (event)
  302.                 {
  303.                 case eFE_Initialize:
  304.                         pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  305.                         break;
  306.                 case eFE_Activate:
  307.                         if (IsPortActive(pActInfo, 0))
  308.                         {
  309.                                 pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true);
  310.                                 m_InputData = pActInfo->pInputPorts[0];
  311.                                 m_frameStamp = gEnv->nMainFrameID;
  312.                         }
  313.                         break;
  314.                 case eFE_Update:
  315.                         if (m_frameStamp != gEnv->nMainFrameID - 1)
  316.                         {
  317.                                 CryLogAlways("Frame delay node didn't skip 1 frame - activated frame %d, updated frame %d", m_frameStamp, gEnv->nMainFrameID);
  318.                         }
  319.                         ActivateOutput(pActInfo, 0, m_InputData);
  320.                         pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false);
  321.                         break;
  322.                 }
  323.         }
  324.         virtual void GetMemoryUsage(ICrySizer* s) const
  325.         {
  326.                 s->Add(*this);
  327.         }
  328. private:
  329.         TFlowInputData m_InputData;
  330.         int            m_frameStamp;
  331. };
  332.  
  333. REGISTER_FLOW_NODE("Time:Delay", CFlowDelayNode);
  334. REGISTER_FLOW_NODE("Time:RandomDelay", CFlowRandomDelayNode);
  335. REGISTER_FLOW_NODE("Time:FrameDelay", CFlowFrameDelayNode);
  336.  
downloadFlowDelayNode.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