Refactor Visual Script debugger apis to use bindings generator
This commit is contained in:
@@ -1343,108 +1343,6 @@ namespace FlaxEditor
|
||||
public float AutoRebuildNavMeshTimeoutMs;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[NativeMarshalling(typeof(VisualScriptLocalMarshaller))]
|
||||
internal struct VisualScriptLocal
|
||||
{
|
||||
public string Value;
|
||||
public string ValueTypeName;
|
||||
public uint NodeId;
|
||||
public int BoxId;
|
||||
}
|
||||
|
||||
[CustomMarshaller(typeof(VisualScriptLocal), MarshalMode.Default, typeof(VisualScriptLocalMarshaller))]
|
||||
internal static class VisualScriptLocalMarshaller
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct VisualScriptLocalNative
|
||||
{
|
||||
public IntPtr Value;
|
||||
public IntPtr ValueTypeName;
|
||||
public uint NodeId;
|
||||
public int BoxId;
|
||||
}
|
||||
|
||||
internal static VisualScriptLocal ConvertToManaged(VisualScriptLocalNative unmanaged) => ToManaged(unmanaged);
|
||||
internal static VisualScriptLocalNative ConvertToUnmanaged(VisualScriptLocal managed) => ToNative(managed);
|
||||
|
||||
internal static VisualScriptLocal ToManaged(VisualScriptLocalNative managed)
|
||||
{
|
||||
return new VisualScriptLocal()
|
||||
{
|
||||
Value = ManagedString.ToManaged(managed.Value),
|
||||
ValueTypeName = ManagedString.ToManaged(managed.ValueTypeName),
|
||||
NodeId = managed.NodeId,
|
||||
BoxId = managed.BoxId,
|
||||
};
|
||||
}
|
||||
|
||||
internal static VisualScriptLocalNative ToNative(VisualScriptLocal managed)
|
||||
{
|
||||
return new VisualScriptLocalNative()
|
||||
{
|
||||
Value = ManagedString.ToNative(managed.Value),
|
||||
ValueTypeName = ManagedString.ToNative(managed.ValueTypeName),
|
||||
NodeId = managed.NodeId,
|
||||
BoxId = managed.BoxId,
|
||||
};
|
||||
}
|
||||
|
||||
internal static void Free(VisualScriptLocalNative unmanaged)
|
||||
{
|
||||
ManagedString.Free(unmanaged.Value);
|
||||
ManagedString.Free(unmanaged.ValueTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[NativeMarshalling(typeof(VisualScriptStackFrameMarshaller))]
|
||||
internal struct VisualScriptStackFrame
|
||||
{
|
||||
public VisualScript Script;
|
||||
public uint NodeId;
|
||||
public int BoxId;
|
||||
}
|
||||
|
||||
[CustomMarshaller(typeof(VisualScriptStackFrame), MarshalMode.Default, typeof(VisualScriptStackFrameMarshaller))]
|
||||
internal static class VisualScriptStackFrameMarshaller
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct VisualScriptStackFrameNative
|
||||
{
|
||||
public IntPtr Script;
|
||||
public uint NodeId;
|
||||
public int BoxId;
|
||||
}
|
||||
|
||||
internal static VisualScriptStackFrame ConvertToManaged(VisualScriptStackFrameNative unmanaged) => ToManaged(unmanaged);
|
||||
internal static VisualScriptStackFrameNative ConvertToUnmanaged(VisualScriptStackFrame managed) => ToNative(managed);
|
||||
|
||||
internal static VisualScriptStackFrame ToManaged(VisualScriptStackFrameNative managed)
|
||||
{
|
||||
return new VisualScriptStackFrame()
|
||||
{
|
||||
Script = VisualScriptMarshaller.ConvertToManaged(managed.Script),
|
||||
NodeId = managed.NodeId,
|
||||
BoxId = managed.BoxId,
|
||||
};
|
||||
}
|
||||
|
||||
internal static VisualScriptStackFrameNative ToNative(VisualScriptStackFrame managed)
|
||||
{
|
||||
return new VisualScriptStackFrameNative()
|
||||
{
|
||||
Script = VisualScriptMarshaller.ConvertToUnmanaged(managed.Script),
|
||||
NodeId = managed.NodeId,
|
||||
BoxId = managed.BoxId,
|
||||
};
|
||||
}
|
||||
|
||||
internal static void Free(VisualScriptStackFrameNative unmanaged)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
internal void BuildCommand(string arg)
|
||||
{
|
||||
if (TryBuildCommand(arg))
|
||||
@@ -1723,21 +1621,6 @@ namespace FlaxEditor
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_RunVisualScriptBreakpointLoopTick", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
internal static partial void Internal_RunVisualScriptBreakpointLoopTick(float deltaTime);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetVisualScriptLocals", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "localsCount")]
|
||||
internal static partial VisualScriptLocal[] Internal_GetVisualScriptLocals(out int localsCount);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetVisualScriptStackFrames", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.Interop.ArrayMarshaller<,>), CountElementName = "stackFrameCount")]
|
||||
internal static partial VisualScriptStackFrame[] Internal_GetVisualScriptStackFrames(out int stackFrameCount);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_GetVisualScriptPreviousScopeFrame", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
internal static partial VisualScriptStackFrame Internal_GetVisualScriptPreviousScopeFrame();
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_EvaluateVisualScriptLocal", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_EvaluateVisualScriptLocal(IntPtr script, ref VisualScriptLocal local);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "EditorInternal_DeserializeSceneObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
|
||||
internal static partial void Internal_DeserializeSceneObject(IntPtr sceneObject, string json);
|
||||
|
||||
|
||||
@@ -526,133 +526,6 @@ DEFINE_INTERNAL_CALL(void) EditorInternal_RunVisualScriptBreakpointLoopTick(floa
|
||||
Engine::OnDraw();
|
||||
}
|
||||
|
||||
struct VisualScriptLocalManaged
|
||||
{
|
||||
MString* Value;
|
||||
MString* ValueTypeName;
|
||||
uint32 NodeId;
|
||||
int32 BoxId;
|
||||
};
|
||||
|
||||
DEFINE_INTERNAL_CALL(MArray*) EditorInternal_GetVisualScriptLocals(int* localsCount)
|
||||
{
|
||||
MArray* result = nullptr;
|
||||
*localsCount = 0;
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
if (stack && stack->Scope)
|
||||
{
|
||||
const int32 count = stack->Scope->Parameters.Length() + stack->Scope->ReturnedValues.Count();
|
||||
const MClass* mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptLocal");
|
||||
ASSERT(mclass);
|
||||
result = MCore::Array::New(mclass, count);
|
||||
VisualScriptLocalManaged local;
|
||||
local.NodeId = MAX_uint32;
|
||||
if (stack->Scope->Parameters.Length() != 0)
|
||||
{
|
||||
auto s = stack;
|
||||
while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope)
|
||||
s = s->PreviousFrame;
|
||||
if (s)
|
||||
local.NodeId = s->Node->ID;
|
||||
}
|
||||
VisualScriptLocalManaged* resultPtr = MCore::Array::GetAddress<VisualScriptLocalManaged>(result);
|
||||
for (int32 i = 0; i < stack->Scope->Parameters.Length(); i++)
|
||||
{
|
||||
auto& v = stack->Scope->Parameters[i];
|
||||
local.BoxId = i + 1;
|
||||
local.Value = MUtils::ToString(v.ToString());
|
||||
local.ValueTypeName = MUtils::ToString(v.Type.GetTypeName());
|
||||
resultPtr[i] = local;
|
||||
}
|
||||
for (int32 i = 0; i < stack->Scope->ReturnedValues.Count(); i++)
|
||||
{
|
||||
auto& v = stack->Scope->ReturnedValues[i];
|
||||
local.NodeId = v.NodeId;
|
||||
local.BoxId = v.BoxId;
|
||||
local.Value = MUtils::ToString(v.Value.ToString());
|
||||
local.ValueTypeName = MUtils::ToString(v.Value.Type.GetTypeName());
|
||||
resultPtr[stack->Scope->Parameters.Length() + i] = local;
|
||||
}
|
||||
*localsCount = count;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct VisualScriptStackFrameManaged
|
||||
{
|
||||
MObject* Script;
|
||||
uint32 NodeId;
|
||||
int32 BoxId;
|
||||
};
|
||||
|
||||
DEFINE_INTERNAL_CALL(MArray*) EditorInternal_GetVisualScriptStackFrames(int* stackFramesCount)
|
||||
{
|
||||
MArray* result = nullptr;
|
||||
*stackFramesCount = 0;
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
if (stack)
|
||||
{
|
||||
int32 count = 0;
|
||||
auto s = stack;
|
||||
while (s)
|
||||
{
|
||||
s = s->PreviousFrame;
|
||||
count++;
|
||||
}
|
||||
const MClass* mclass = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->GetClass("FlaxEditor.Editor+VisualScriptStackFrame");
|
||||
ASSERT(mclass);
|
||||
result = MCore::Array::New(mclass, count);
|
||||
VisualScriptStackFrameManaged* resultPtr = MCore::Array::GetAddress<VisualScriptStackFrameManaged>(result);
|
||||
s = stack;
|
||||
count = 0;
|
||||
while (s)
|
||||
{
|
||||
VisualScriptStackFrameManaged frame;
|
||||
frame.Script = s->Script->GetOrCreateManagedInstance();
|
||||
frame.NodeId = s->Node->ID;
|
||||
frame.BoxId = s->Box ? s->Box->ID : MAX_uint32;
|
||||
resultPtr[count] = frame;
|
||||
s = s->PreviousFrame;
|
||||
count++;
|
||||
}
|
||||
*stackFramesCount = count;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(VisualScriptStackFrameManaged) EditorInternal_GetVisualScriptPreviousScopeFrame()
|
||||
{
|
||||
VisualScriptStackFrameManaged frame;
|
||||
Platform::MemoryClear(&frame, sizeof(frame));
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
if (stack)
|
||||
{
|
||||
auto s = stack;
|
||||
while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope)
|
||||
s = s->PreviousFrame;
|
||||
if (s && s->PreviousFrame)
|
||||
{
|
||||
s = s->PreviousFrame;
|
||||
frame.Script = s->Script->GetOrCreateManagedInstance();
|
||||
frame.NodeId = s->Node->ID;
|
||||
frame.BoxId = s->Box ? s->Box->ID : MAX_uint32;
|
||||
}
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(bool) EditorInternal_EvaluateVisualScriptLocal(VisualScript* script, VisualScriptLocalManaged* local)
|
||||
{
|
||||
Variant v;
|
||||
if (VisualScripting::Evaluate(script, VisualScripting::GetThreadStackTop()->Instance, local->NodeId, local->BoxId, v))
|
||||
{
|
||||
local->Value = MUtils::ToString(v.ToString());
|
||||
local->ValueTypeName = MUtils::ToString(v.Type.GetTypeName());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) EditorInternal_DeserializeSceneObject(SceneObject* sceneObject, MString* jsonObj)
|
||||
{
|
||||
PROFILE_CPU_NAMED("DeserializeSceneObject");
|
||||
|
||||
@@ -489,6 +489,95 @@ void ManagedEditor::RequestStartPlayOnEditMode()
|
||||
Internal_RequestStartPlayOnEditMode->Invoke(GetManagedInstance(), nullptr, nullptr);
|
||||
}
|
||||
|
||||
Array<ManagedEditor::VisualScriptStackFrame> ManagedEditor::GetVisualScriptStackFrames()
|
||||
{
|
||||
Array<VisualScriptStackFrame> result;
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
auto s = stack;
|
||||
while (s)
|
||||
{
|
||||
VisualScriptStackFrame& frame = result.AddOne();
|
||||
frame.Script = s->Script;
|
||||
frame.NodeId = s->Node->ID;
|
||||
frame.BoxId = s->Box ? s->Box->ID : MAX_uint32;
|
||||
s = s->PreviousFrame;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ManagedEditor::VisualScriptStackFrame ManagedEditor::GetVisualScriptPreviousScopeFrame()
|
||||
{
|
||||
VisualScriptStackFrame frame;
|
||||
Platform::MemoryClear(&frame, sizeof(frame));
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
if (stack)
|
||||
{
|
||||
auto s = stack;
|
||||
while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope)
|
||||
s = s->PreviousFrame;
|
||||
if (s && s->PreviousFrame)
|
||||
{
|
||||
s = s->PreviousFrame;
|
||||
frame.Script = s->Script;
|
||||
frame.NodeId = s->Node->ID;
|
||||
frame.BoxId = s->Box ? s->Box->ID : MAX_uint32;
|
||||
}
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
Array<ManagedEditor::VisualScriptLocal> ManagedEditor::GetVisualScriptLocals()
|
||||
{
|
||||
Array<VisualScriptLocal> result;
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
if (stack && stack->Scope)
|
||||
{
|
||||
const int32 count = stack->Scope->Parameters.Length() + stack->Scope->ReturnedValues.Count();
|
||||
result.Resize(count);
|
||||
VisualScriptLocal local;
|
||||
local.NodeId = MAX_uint32;
|
||||
if (stack->Scope->Parameters.Length() != 0)
|
||||
{
|
||||
auto s = stack;
|
||||
while (s->PreviousFrame && s->PreviousFrame->Scope == stack->Scope)
|
||||
s = s->PreviousFrame;
|
||||
if (s)
|
||||
local.NodeId = s->Node->ID;
|
||||
}
|
||||
for (int32 i = 0; i < stack->Scope->Parameters.Length(); i++)
|
||||
{
|
||||
auto& v = stack->Scope->Parameters[i];
|
||||
local.BoxId = i + 1;
|
||||
local.Value = v.ToString();
|
||||
local.ValueTypeName = v.Type.GetTypeName();
|
||||
result[i] = local;
|
||||
}
|
||||
for (int32 i = 0; i < stack->Scope->ReturnedValues.Count(); i++)
|
||||
{
|
||||
auto& v = stack->Scope->ReturnedValues[i];
|
||||
local.NodeId = v.NodeId;
|
||||
local.BoxId = v.BoxId;
|
||||
local.Value = v.Value.ToString();
|
||||
local.ValueTypeName = v.Value.Type.GetTypeName();
|
||||
result[stack->Scope->Parameters.Length() + i] = local;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ManagedEditor::EvaluateVisualScriptLocal(VisualScript* script, VisualScriptLocal& local)
|
||||
{
|
||||
Variant v;
|
||||
const auto stack = VisualScripting::GetThreadStackTop();
|
||||
if (stack && VisualScripting::Evaluate(script, stack->Instance, local.NodeId, local.BoxId, v))
|
||||
{
|
||||
local.Value = v.ToString();
|
||||
local.ValueTypeName = v.Type.GetTypeName();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
|
||||
{
|
||||
ASSERT(!HasManagedInstance());
|
||||
|
||||
@@ -210,6 +210,31 @@ public:
|
||||
API_FUNCTION() static bool TryRestoreImportOptions(API_PARAM(Ref) AudioTool::Options& options, String assetPath);
|
||||
#endif
|
||||
|
||||
public:
|
||||
API_STRUCT(Internal, NoDefault) struct VisualScriptStackFrame
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(VisualScriptStackFrame);
|
||||
|
||||
API_FIELD() class VisualScript* Script;
|
||||
API_FIELD() uint32 NodeId;
|
||||
API_FIELD() int32 BoxId;
|
||||
};
|
||||
|
||||
API_STRUCT(Internal, NoDefault) struct VisualScriptLocal
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(VisualScriptLocal);
|
||||
|
||||
API_FIELD() String Value;
|
||||
API_FIELD() String ValueTypeName;
|
||||
API_FIELD() uint32 NodeId;
|
||||
API_FIELD() int32 BoxId;
|
||||
};
|
||||
|
||||
API_FUNCTION(Internal) static Array<VisualScriptStackFrame> GetVisualScriptStackFrames();
|
||||
API_FUNCTION(Internal) static VisualScriptStackFrame GetVisualScriptPreviousScopeFrame();
|
||||
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
|
||||
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
|
||||
|
||||
private:
|
||||
void OnEditorAssemblyLoaded(MAssembly* assembly);
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace FlaxEditor.Surface
|
||||
BoxId = box.ID,
|
||||
};
|
||||
var script = ((Windows.Assets.VisualScriptWindow)box.Surface.Owner).Asset;
|
||||
if (Editor.Internal_EvaluateVisualScriptLocal(Object.GetUnmanagedPtr(script), ref local))
|
||||
if (Editor.EvaluateVisualScriptLocal(script, ref local))
|
||||
{
|
||||
text = $"{local.Value ?? string.Empty} ({local.ValueTypeName})";
|
||||
return true;
|
||||
|
||||
@@ -797,11 +797,12 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
|
||||
// Check if any breakpoint was hit
|
||||
for (int i = 0; i < Surface.Breakpoints.Count; i++)
|
||||
var breakpoints = Surface.Breakpoints;
|
||||
for (int i = 0; i < breakpoints.Count; i++)
|
||||
{
|
||||
if (Surface.Breakpoints[i].ID == flowInfo.NodeId)
|
||||
if (breakpoints[i].ID == flowInfo.NodeId)
|
||||
{
|
||||
OnDebugBreakpointHit(ref flowInfo, Surface.Breakpoints[i]);
|
||||
OnDebugBreakpointHit(ref flowInfo, breakpoints[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -820,7 +821,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
var state = (BreakpointHangState)Editor.Instance.Simulation.BreakpointHangTag;
|
||||
if (state.Locals == null)
|
||||
{
|
||||
state.Locals = Editor.Internal_GetVisualScriptLocals(out var _);
|
||||
state.Locals = Editor.GetVisualScriptLocals();
|
||||
Editor.Instance.Simulation.BreakpointHangTag = state;
|
||||
}
|
||||
return state;
|
||||
@@ -831,7 +832,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
var state = (BreakpointHangState)Editor.Instance.Simulation.BreakpointHangTag;
|
||||
if (state.StackFrames == null)
|
||||
{
|
||||
state.StackFrames = Editor.Internal_GetVisualScriptStackFrames(out var _);
|
||||
state.StackFrames = Editor.GetVisualScriptStackFrames();
|
||||
Editor.Instance.Simulation.BreakpointHangTag = state;
|
||||
}
|
||||
return state;
|
||||
@@ -976,7 +977,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
return;
|
||||
|
||||
// Break on any of the output connects from the previous scope node
|
||||
var frame = Editor.Internal_GetVisualScriptPreviousScopeFrame();
|
||||
var frame = Editor.GetVisualScriptPreviousScopeFrame();
|
||||
if (frame.Script != null)
|
||||
{
|
||||
if (_debugStepOutNodesIds == null)
|
||||
|
||||
Reference in New Issue
Block a user