Implement .NET 7 runtime support and bindings generation
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
@@ -44,6 +45,7 @@ namespace FlaxEngine
|
||||
/// The node evaluation context structure.
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
[NativeMarshalling(typeof(ContextMarshaler))]
|
||||
public struct Context
|
||||
{
|
||||
/// <summary>
|
||||
@@ -92,6 +94,61 @@ namespace FlaxEngine
|
||||
public AnimatedModel Instance;
|
||||
}
|
||||
|
||||
[CustomMarshaller(typeof(Context), MarshalMode.Default, typeof(ContextMarshaler))]
|
||||
internal static class ContextMarshaler
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ContextNative
|
||||
{
|
||||
public IntPtr Graph;
|
||||
public IntPtr GraphExecutor;
|
||||
public IntPtr Node;
|
||||
public uint NodeId;
|
||||
public int BoxId;
|
||||
public float DeltaTime;
|
||||
public ulong CurrentFrameIndex;
|
||||
public IntPtr BaseModel;
|
||||
public IntPtr Instance;
|
||||
}
|
||||
|
||||
internal static Context ConvertToManaged(ContextNative unmanaged) => ToManaged(unmanaged);
|
||||
internal static ContextNative ConvertToUnmanaged(Context managed) => ToNative(managed);
|
||||
|
||||
internal static Context ToManaged(ContextNative managed)
|
||||
{
|
||||
return new Context()
|
||||
{
|
||||
Graph = managed.Graph,
|
||||
GraphExecutor = managed.GraphExecutor,
|
||||
Node = managed.Node,
|
||||
NodeId = managed.NodeId,
|
||||
BoxId = managed.BoxId,
|
||||
DeltaTime = managed.DeltaTime,
|
||||
CurrentFrameIndex = managed.CurrentFrameIndex,
|
||||
BaseModel = SkinnedModelMarshaller.ConvertToManaged(managed.BaseModel),
|
||||
Instance = AnimatedModelMarshaller.ConvertToManaged(managed.Instance),
|
||||
};
|
||||
}
|
||||
internal static ContextNative ToNative(Context managed)
|
||||
{
|
||||
return new ContextNative()
|
||||
{
|
||||
Graph = managed.Graph,
|
||||
GraphExecutor = managed.GraphExecutor,
|
||||
Node = managed.Node,
|
||||
NodeId = managed.NodeId,
|
||||
BoxId = managed.BoxId,
|
||||
DeltaTime = managed.DeltaTime,
|
||||
CurrentFrameIndex = managed.CurrentFrameIndex,
|
||||
BaseModel = SkinnedModelMarshaller.ConvertToUnmanaged(managed.BaseModel),
|
||||
Instance = AnimatedModelMarshaller.ConvertToUnmanaged(managed.Instance),
|
||||
};
|
||||
}
|
||||
internal static void Free(ContextNative unmanaged)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The animation graph 'impulse' connections data container (the actual transfer is done via pointer as it gives better performance).
|
||||
/// Container for skeleton nodes transformation hierarchy and any other required data.
|
||||
@@ -203,14 +260,16 @@ namespace FlaxEngine
|
||||
|
||||
#region Internal Calls
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern bool Internal_HasConnection(ref CustomNode.Context context, int boxId);
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_HasConnection")]
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
internal static partial bool Internal_HasConnection(ref AnimationGraph.CustomNode.Context context, int boxId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern object Internal_GetInputValue(ref CustomNode.Context context, int boxId);
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_GetInputValue")]
|
||||
[return: MarshalUsing(typeof(FlaxEngine.GCHandleMarshaller))]
|
||||
internal static partial object Internal_GetInputValue(ref AnimationGraph.CustomNode.Context context, int boxId);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||
internal static extern IntPtr Internal_GetOutputImpulseData(ref CustomNode.Context context);
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData")]
|
||||
internal static partial IntPtr Internal_GetOutputImpulseData(ref AnimationGraph.CustomNode.Context context);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include "Engine/Content/Assets/SkinnedModel.h"
|
||||
|
||||
#if USE_MONO
|
||||
|
||||
#include <ThirdParty/mono-2.0/mono/metadata/appdomain.h>
|
||||
#endif
|
||||
|
||||
struct InternalInitData
|
||||
{
|
||||
@@ -52,6 +52,7 @@ namespace AnimGraphInternal
|
||||
{
|
||||
bool HasConnection(InternalContext* context, int32 boxId)
|
||||
{
|
||||
SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_HasConnection")
|
||||
const auto box = context->Node->TryGetBox(boxId);
|
||||
if (box == nullptr)
|
||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||
@@ -60,6 +61,7 @@ namespace AnimGraphInternal
|
||||
|
||||
MonoObject* GetInputValue(InternalContext* context, int32 boxId)
|
||||
{
|
||||
SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_GetInputValue")
|
||||
const auto box = context->Node->TryGetBox(boxId);
|
||||
if (box == nullptr)
|
||||
DebugLog::ThrowArgumentOutOfRange("boxId");
|
||||
@@ -77,14 +79,13 @@ namespace AnimGraphInternal
|
||||
|
||||
AnimGraphImpulse* GetOutputImpulseData(InternalContext* context)
|
||||
{
|
||||
SCRIPTING_EXPORT("FlaxEngine.AnimationGraph::Internal_GetOutputImpulseData")
|
||||
const auto nodes = context->Node->GetNodes(context->GraphExecutor);
|
||||
context->GraphExecutor->InitNodes(nodes);
|
||||
return nodes;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void AnimGraphExecutor::initRuntime()
|
||||
{
|
||||
#if USE_MONO
|
||||
@@ -122,7 +123,7 @@ void AnimGraphExecutor::ProcessGroupCustom(Box* boxBase, Node* nodeBase, Value&
|
||||
internalContext.Instance = context.Data->Object ? context.Data->Object->GetOrCreateManagedInstance() : nullptr;
|
||||
|
||||
// Peek managed object
|
||||
const auto obj = mono_gchandle_get_target(data.Handle);
|
||||
const auto obj = MUtils::GetGCHandleTarget(data.Handle);
|
||||
if (obj == nullptr)
|
||||
{
|
||||
LOG(Warning, "Custom node instance is null.");
|
||||
@@ -166,7 +167,7 @@ void AnimGraph::ClearCustomNode(Node* node)
|
||||
if (data.Handle)
|
||||
{
|
||||
#if USE_MONO
|
||||
mono_gchandle_free(data.Handle);
|
||||
MUtils::FreeGCHandle(data.Handle);
|
||||
#endif
|
||||
data.Handle = 0;
|
||||
}
|
||||
@@ -216,7 +217,7 @@ bool AnimGraph::InitCustomNode(Node* node)
|
||||
|
||||
// Allocate managed node object (create GC handle to prevent destruction)
|
||||
const auto obj = type->CreateInstance();
|
||||
const auto handleGC = mono_gchandle_new(obj, false);
|
||||
const auto handleGC = MUtils::NewGCHandle(obj, false);
|
||||
|
||||
// Initialize node
|
||||
InternalInitData initData;
|
||||
@@ -228,7 +229,7 @@ bool AnimGraph::InitCustomNode(Node* node)
|
||||
load->Invoke(obj, params, &exception);
|
||||
if (exception)
|
||||
{
|
||||
mono_gchandle_free(handleGC);
|
||||
MUtils::FreeGCHandle(handleGC);
|
||||
|
||||
MException ex(exception);
|
||||
ex.Log(LogType::Warning, TEXT("AnimGraph"));
|
||||
|
||||
@@ -516,7 +516,7 @@ public:
|
||||
/// <summary>
|
||||
/// The GC handle to the managed instance of the node object.
|
||||
/// </summary>
|
||||
uint32 Handle;
|
||||
gchandle Handle;
|
||||
};
|
||||
|
||||
struct CurveData
|
||||
|
||||
Reference in New Issue
Block a user