From 00d960d61e2f022e14bf06bb1ad782aaf9df4f69 Mon Sep 17 00:00:00 2001 From: Wojciech Figat Date: Mon, 2 Jan 2023 10:35:39 +0100 Subject: [PATCH] Refactor abstract classes handling for scripting types creation (eg. Script or GPUResource) under dotnet7 --- Source/Engine/Engine/NativeInterop.cs | 9 +++++---- Source/Engine/Visject/VisjectScript.cpp | 6 ------ Source/Engine/Visject/VisjectScript.h | 14 -------------- .../Bindings/BindingsGenerator.CSharp.cs | 4 ++++ 4 files changed, 9 insertions(+), 24 deletions(-) delete mode 100644 Source/Engine/Visject/VisjectScript.cpp delete mode 100644 Source/Engine/Visject/VisjectScript.h diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs index b23170a26..07aba41f8 100644 --- a/Source/Engine/Engine/NativeInterop.cs +++ b/Source/Engine/Engine/NativeInterop.cs @@ -12,7 +12,6 @@ using System.Runtime.CompilerServices; using FlaxEngine.Assertions; using FlaxEngine.Utilities; using System.Runtime.InteropServices.Marshalling; -using FlaxEngine.Visject; using System.Buffers; using System.Collections.Concurrent; using System.Text; @@ -1845,10 +1844,12 @@ namespace FlaxEngine internal static IntPtr NewObject(IntPtr typeHandle) { Type type = Unsafe.As(GCHandle.FromIntPtr(typeHandle).Target); - if (type == typeof(Script)) + if (type.IsAbstract) { - // FIXME: Script is an abstract type which can not be instantiated - type = typeof(VisjectScript); + // Dotnet doesn't allow to instantiate abstract type thus allow to use generated mock class usage (eg. for Script or GPUResource) for generated abstract types + var abstractWrapper = type.GetNestedType("AbstractWrapper", BindingFlags.NonPublic); + if (abstractWrapper != null) + type = abstractWrapper; } object value = RuntimeHelpers.GetUninitializedObject(type); return GCHandle.ToIntPtr(GCHandle.Alloc(value)); diff --git a/Source/Engine/Visject/VisjectScript.cpp b/Source/Engine/Visject/VisjectScript.cpp deleted file mode 100644 index 1ae6cafda..000000000 --- a/Source/Engine/Visject/VisjectScript.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "VisjectScript.h" - -VisjectScript::VisjectScript(const SpawnParams& params) - : Script(params) -{ -} diff --git a/Source/Engine/Visject/VisjectScript.h b/Source/Engine/Visject/VisjectScript.h deleted file mode 100644 index 1e5389a77..000000000 --- a/Source/Engine/Visject/VisjectScript.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved. - -#pragma once - -#include "Engine/Scripting/Script.h" - -/// -/// -/// -API_CLASS(Namespace = "FlaxEngine.Visject") class FLAXENGINE_API VisjectScript : public Script -{ - API_AUTO_SERIALIZATION(); - DECLARE_SCRIPTING_TYPE(VisjectScript); -}; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 7f55e3223..64cd3683f 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -1227,6 +1227,10 @@ namespace Flax.Build.Bindings GenerateCSharpManagedTypeInternals(buildData, classInfo, contents, indent); + // Abstract wrapper (to ensure C# class can be created for Visual Scripts, see NativeInterop.NewObject) + if (classInfo.IsAbstract) + contents.AppendLine().Append(indent).Append("[Unmanaged] private sealed class AbstractWrapper : ").Append(classInfo.Name).AppendLine(" { }"); + // Nested types foreach (var apiTypeInfo in classInfo.Children) {