Add Delay node to Visual Scripting

This commit is contained in:
Wojtek Figat
2021-06-14 16:10:08 +02:00
parent 90105c421d
commit f5cdb0abfd
9 changed files with 170 additions and 144 deletions

View File

@@ -19,6 +19,7 @@
#include "Engine/Serialization/JsonWriter.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Utilities/StringConverter.h"
#include "Engine/Threading/MainThreadTask.h"
#include "FlaxEngine.Gen.h"
namespace
@@ -83,6 +84,41 @@ VisualScriptExecutor::VisualScriptExecutor()
_perGroupProcessCall[17] = (ProcessBoxHandler)&VisualScriptExecutor::ProcessGroupFlow;
}
void VisualScriptExecutor::Invoke(const Guid& scriptId, int32 nodeId, int32 boxId, const Guid& instanceId, Variant& result) const
{
auto script = Content::Load<VisualScript>(scriptId);
if (!script)
return;
const auto node = script->Graph.GetNode(nodeId);
if (!node)
return;
const auto box = node->GetBox(boxId);
if (!box)
return;
auto instance = Scripting::FindObject<ScriptingObject>(instanceId);
// Add to the calling stack
VisualScripting::ScopeContext scope;
auto& stack = ThreadStacks.Get();
VisualScripting::StackFrame frame;
frame.Script = script;
frame.Node = node;
frame.Box = box;
frame.Instance = instance;
frame.PreviousFrame = stack.Stack;
frame.Scope = &scope;
stack.Stack = &frame;
stack.StackFramesCount++;
// Call per group custom processing event
const auto func = VisualScriptingExecutor._perGroupProcessCall[node->GroupID];
(VisualScriptingExecutor.*func)(box, node, result);
// Remove from the calling stack
stack.StackFramesCount--;
stack.Stack = frame.PreviousFrame;
}
VisjectExecutor::Value VisualScriptExecutor::eatBox(Node* caller, Box* box)
{
// Check if graph is looped or is too deep
@@ -1273,6 +1309,46 @@ void VisualScriptExecutor::ProcessGroupFlow(Box* boxBase, Node* node, Value& val
}
}
break;
}
// Delay
case 6:
{
boxBase = node->GetBox(2);
if (!boxBase->HasConnection())
break;
const float duration = (float)tryGetValue(node->GetBox(1), node->Values[0]);
if (duration > ZeroTolerance)
{
class DelayTask : public MainThreadTask
{
public:
Guid Script;
Guid Instance;
int32 Node;
int32 Box;
protected:
bool Run() override
{
Variant result;
VisualScriptingExecutor.Invoke(Script, Node, Box, Instance, result);
return false;
}
};
const auto& stack = ThreadStacks.Get().Stack;
auto task = New<DelayTask>();
task->Script = stack->Script->GetID();;
task->Instance = stack->Instance->GetID();;
task->Node = ((Node*)boxBase->FirstConnection()->Parent)->ID;
task->Box = boxBase->FirstConnection()->ID;
task->InitialDelay = duration;
task->Start();
}
else
{
eatBox(node, boxBase->FirstConnection());
}
break;
}
}
}