Merge pull request #72619 from raulsntos/dotnet/global-class-script
C#: Add global class support
This commit is contained in:
commit
3119255c0b
15 changed files with 201 additions and 25 deletions
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
#include "core/os/keyboard.h"
|
#include "core/os/keyboard.h"
|
||||||
|
#include "editor/editor_file_system.h"
|
||||||
#include "editor/editor_internal_calls.h"
|
#include "editor/editor_internal_calls.h"
|
||||||
#include "editor/editor_node.h"
|
#include "editor/editor_node.h"
|
||||||
#include "editor/editor_settings.h"
|
#include "editor/editor_settings.h"
|
||||||
|
@ -535,6 +536,48 @@ String CSharpLanguage::_get_indentation() const {
|
||||||
return "\t";
|
return "\t";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CSharpLanguage::handles_global_class_type(const String &p_type) const {
|
||||||
|
return p_type == get_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
String CSharpLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
|
||||||
|
Ref<CSharpScript> scr = ResourceLoader::load(p_path, get_type());
|
||||||
|
if (!scr.is_valid() || !scr->valid || !scr->global_class) {
|
||||||
|
// Invalid script or the script is not a global class.
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = scr->class_name;
|
||||||
|
if (unlikely(name.is_empty())) {
|
||||||
|
return String();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r_icon_path) {
|
||||||
|
if (scr->icon_path.is_empty() || scr->icon_path.is_absolute_path()) {
|
||||||
|
*r_icon_path = scr->icon_path.simplify_path();
|
||||||
|
} else if (scr->icon_path.is_relative_path()) {
|
||||||
|
*r_icon_path = p_path.get_base_dir().path_join(scr->icon_path).simplify_path();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (r_base_type) {
|
||||||
|
bool found_global_base_script = false;
|
||||||
|
const CSharpScript *top = scr->base_script.ptr();
|
||||||
|
while (top != nullptr) {
|
||||||
|
if (top->global_class) {
|
||||||
|
*r_base_type = top->class_name;
|
||||||
|
found_global_base_script = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
top = top->base_script.ptr();
|
||||||
|
}
|
||||||
|
if (!found_global_base_script) {
|
||||||
|
*r_base_type = scr->get_instance_base_type();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
String CSharpLanguage::debug_get_error() const {
|
String CSharpLanguage::debug_get_error() const {
|
||||||
return _debug_error;
|
return _debug_error;
|
||||||
}
|
}
|
||||||
|
@ -2203,11 +2246,21 @@ void CSharpScript::reload_registered_script(Ref<CSharpScript> p_script) {
|
||||||
update_script_class_info(p_script);
|
update_script_class_info(p_script);
|
||||||
|
|
||||||
p_script->_update_exports();
|
p_script->_update_exports();
|
||||||
|
|
||||||
|
#if TOOLS_ENABLED
|
||||||
|
// If the EditorFileSystem singleton is available, update the file;
|
||||||
|
// otherwise, the file will be updated when the singleton becomes available.
|
||||||
|
EditorFileSystem *efs = EditorFileSystem::get_singleton();
|
||||||
|
if (efs) {
|
||||||
|
efs->update_file(p_script->get_path());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract information about the script using the mono class.
|
// Extract information about the script using the mono class.
|
||||||
void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
|
void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
|
||||||
bool tool = false;
|
bool tool = false;
|
||||||
|
bool global_class = false;
|
||||||
|
|
||||||
// TODO: Use GDExtension godot_dictionary
|
// TODO: Use GDExtension godot_dictionary
|
||||||
Array methods_array;
|
Array methods_array;
|
||||||
|
@ -2217,11 +2270,17 @@ void CSharpScript::update_script_class_info(Ref<CSharpScript> p_script) {
|
||||||
Dictionary signals_dict;
|
Dictionary signals_dict;
|
||||||
signals_dict.~Dictionary();
|
signals_dict.~Dictionary();
|
||||||
|
|
||||||
|
String class_name;
|
||||||
|
String icon_path;
|
||||||
Ref<CSharpScript> base_script;
|
Ref<CSharpScript> base_script;
|
||||||
GDMonoCache::managed_callbacks.ScriptManagerBridge_UpdateScriptClassInfo(
|
GDMonoCache::managed_callbacks.ScriptManagerBridge_UpdateScriptClassInfo(
|
||||||
p_script.ptr(), &tool, &methods_array, &rpc_functions_dict, &signals_dict, &base_script);
|
p_script.ptr(), &class_name, &tool, &global_class, &icon_path,
|
||||||
|
&methods_array, &rpc_functions_dict, &signals_dict, &base_script);
|
||||||
|
|
||||||
|
p_script->class_name = class_name;
|
||||||
p_script->tool = tool;
|
p_script->tool = tool;
|
||||||
|
p_script->global_class = global_class;
|
||||||
|
p_script->icon_path = icon_path;
|
||||||
|
|
||||||
p_script->rpc_config.clear();
|
p_script->rpc_config.clear();
|
||||||
p_script->rpc_config = rpc_functions_dict;
|
p_script->rpc_config = rpc_functions_dict;
|
||||||
|
@ -2519,6 +2578,15 @@ Error CSharpScript::reload(bool p_keep_state) {
|
||||||
update_script_class_info(this);
|
update_script_class_info(this);
|
||||||
|
|
||||||
_update_exports();
|
_update_exports();
|
||||||
|
|
||||||
|
#if TOOLS_ENABLED
|
||||||
|
// If the EditorFileSystem singleton is available, update the file;
|
||||||
|
// otherwise, the file will be updated when the singleton becomes available.
|
||||||
|
EditorFileSystem *efs = EditorFileSystem::get_singleton();
|
||||||
|
if (efs) {
|
||||||
|
efs->update_file(script_path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
@ -2605,11 +2673,11 @@ bool CSharpScript::inherits_script(const Ref<Script> &p_script) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Script> CSharpScript::get_base_script() const {
|
Ref<Script> CSharpScript::get_base_script() const {
|
||||||
return base_script;
|
return base_script.is_valid() && !base_script->get_path().is_empty() ? base_script : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringName CSharpScript::get_global_name() const {
|
StringName CSharpScript::get_global_name() const {
|
||||||
return StringName();
|
return global_class ? StringName(class_name) : StringName();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const {
|
void CSharpScript::get_script_property_list(List<PropertyInfo> *r_list) const {
|
||||||
|
|
|
@ -62,6 +62,7 @@ class CSharpScript : public Script {
|
||||||
friend class CSharpLanguage;
|
friend class CSharpLanguage;
|
||||||
|
|
||||||
bool tool = false;
|
bool tool = false;
|
||||||
|
bool global_class = false;
|
||||||
bool valid = false;
|
bool valid = false;
|
||||||
bool reload_invalidated = false;
|
bool reload_invalidated = false;
|
||||||
|
|
||||||
|
@ -86,6 +87,8 @@ class CSharpScript : public Script {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String source;
|
String source;
|
||||||
|
String class_name;
|
||||||
|
String icon_path;
|
||||||
|
|
||||||
SelfList<CSharpScript> script_list = this;
|
SelfList<CSharpScript> script_list = this;
|
||||||
|
|
||||||
|
@ -442,6 +445,10 @@ public:
|
||||||
/* TODO? */ void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {}
|
/* TODO? */ void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const override {}
|
||||||
/* TODO */ void add_global_constant(const StringName &p_variable, const Variant &p_value) override {}
|
/* TODO */ void add_global_constant(const StringName &p_variable, const Variant &p_value) override {}
|
||||||
|
|
||||||
|
/* SCRIPT GLOBAL CLASS FUNCTIONS */
|
||||||
|
virtual bool handles_global_class_type(const String &p_type) const override;
|
||||||
|
virtual String get_global_class_name(const String &p_path, String *r_base_type = nullptr, String *r_icon_path = nullptr) const override;
|
||||||
|
|
||||||
/* DEBUGGER FUNCTIONS */
|
/* DEBUGGER FUNCTIONS */
|
||||||
String debug_get_error() const override;
|
String debug_get_error() const override;
|
||||||
int debug_get_stack_level_count() const override;
|
int debug_get_stack_level_count() const override;
|
||||||
|
|
|
@ -241,6 +241,9 @@ namespace Godot.SourceGenerators
|
||||||
public static bool IsGodotClassNameAttribute(this INamedTypeSymbol symbol)
|
public static bool IsGodotClassNameAttribute(this INamedTypeSymbol symbol)
|
||||||
=> symbol.ToString() == GodotClasses.GodotClassNameAttr;
|
=> symbol.ToString() == GodotClasses.GodotClassNameAttr;
|
||||||
|
|
||||||
|
public static bool IsGodotGlobalClassAttribute(this INamedTypeSymbol symbol)
|
||||||
|
=> symbol.ToString() == GodotClasses.GlobalClassAttr;
|
||||||
|
|
||||||
public static bool IsSystemFlagsAttribute(this INamedTypeSymbol symbol)
|
public static bool IsSystemFlagsAttribute(this INamedTypeSymbol symbol)
|
||||||
=> symbol.ToString() == GodotClasses.SystemFlagsAttr;
|
=> symbol.ToString() == GodotClasses.SystemFlagsAttr;
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace Godot.SourceGenerators
|
||||||
public const string SignalAttr = "Godot.SignalAttribute";
|
public const string SignalAttr = "Godot.SignalAttribute";
|
||||||
public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute";
|
public const string MustBeVariantAttr = "Godot.MustBeVariantAttribute";
|
||||||
public const string GodotClassNameAttr = "Godot.GodotClassNameAttribute";
|
public const string GodotClassNameAttr = "Godot.GodotClassNameAttribute";
|
||||||
|
public const string GlobalClassAttr = "Godot.GlobalClassAttribute";
|
||||||
public const string SystemFlagsAttr = "System.FlagsAttribute";
|
public const string SystemFlagsAttr = "System.FlagsAttribute";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -547,25 +547,32 @@ namespace Godot.SourceGenerators
|
||||||
{
|
{
|
||||||
if (memberNamedType.InheritsFrom("GodotSharp", "Godot.Resource"))
|
if (memberNamedType.InheritsFrom("GodotSharp", "Godot.Resource"))
|
||||||
{
|
{
|
||||||
string nativeTypeName = memberNamedType.GetGodotScriptNativeClassName()!;
|
|
||||||
|
|
||||||
hint = PropertyHint.ResourceType;
|
hint = PropertyHint.ResourceType;
|
||||||
hintString = nativeTypeName;
|
hintString = GetTypeName(memberNamedType);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memberNamedType.InheritsFrom("GodotSharp", "Godot.Node"))
|
if (memberNamedType.InheritsFrom("GodotSharp", "Godot.Node"))
|
||||||
{
|
{
|
||||||
string nativeTypeName = memberNamedType.GetGodotScriptNativeClassName()!;
|
|
||||||
|
|
||||||
hint = PropertyHint.NodeType;
|
hint = PropertyHint.NodeType;
|
||||||
hintString = nativeTypeName;
|
hintString = GetTypeName(memberNamedType);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string GetTypeName(INamedTypeSymbol memberSymbol)
|
||||||
|
{
|
||||||
|
if (memberSymbol.GetAttributes()
|
||||||
|
.Any(a => a.AttributeClass?.IsGodotGlobalClassAttribute() ?? false))
|
||||||
|
{
|
||||||
|
return memberSymbol.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return memberSymbol.GetGodotScriptNativeClassName()!;
|
||||||
|
}
|
||||||
|
|
||||||
static bool GetStringArrayEnumHint(VariantType elementVariantType,
|
static bool GetStringArrayEnumHint(VariantType elementVariantType,
|
||||||
AttributeData exportAttr, out string? hintString)
|
AttributeData exportAttr, out string? hintString)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace Godot
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Exposes the target class as a global script class to Godot Engine.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public sealed class GlobalClassAttribute : Attribute { }
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Godot
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies a custom icon for representing this class in the Godot Editor.
|
||||||
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
|
public sealed class IconAttribute : Attribute
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// File path to a custom icon for representing this class in the Godot Editor.
|
||||||
|
/// </summary>
|
||||||
|
public string Path { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specify the custom icon that represents the class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">File path to the custom icon.</param>
|
||||||
|
public IconAttribute(string path)
|
||||||
|
{
|
||||||
|
Path = path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,7 @@ namespace Godot.Bridge
|
||||||
public delegate* unmanaged<godot_string*, godot_ref*, void> ScriptManagerBridge_GetOrCreateScriptBridgeForPath;
|
public delegate* unmanaged<godot_string*, godot_ref*, void> ScriptManagerBridge_GetOrCreateScriptBridgeForPath;
|
||||||
public delegate* unmanaged<IntPtr, void> ScriptManagerBridge_RemoveScriptBridge;
|
public delegate* unmanaged<IntPtr, void> ScriptManagerBridge_RemoveScriptBridge;
|
||||||
public delegate* unmanaged<IntPtr, godot_bool> ScriptManagerBridge_TryReloadRegisteredScriptWithClass;
|
public delegate* unmanaged<IntPtr, godot_bool> ScriptManagerBridge_TryReloadRegisteredScriptWithClass;
|
||||||
public delegate* unmanaged<IntPtr, godot_bool*, godot_array*, godot_dictionary*, godot_dictionary*, godot_ref*, void> ScriptManagerBridge_UpdateScriptClassInfo;
|
public delegate* unmanaged<IntPtr, godot_string*, godot_bool*, godot_bool*, godot_string*, godot_array*, godot_dictionary*, godot_dictionary*, godot_ref*, void> ScriptManagerBridge_UpdateScriptClassInfo;
|
||||||
public delegate* unmanaged<IntPtr, IntPtr*, godot_bool, godot_bool> ScriptManagerBridge_SwapGCHandleForType;
|
public delegate* unmanaged<IntPtr, IntPtr*, godot_bool, godot_bool> ScriptManagerBridge_SwapGCHandleForType;
|
||||||
public delegate* unmanaged<IntPtr, delegate* unmanaged<IntPtr, godot_string*, void*, int, void>, void> ScriptManagerBridge_GetPropertyInfoList;
|
public delegate* unmanaged<IntPtr, delegate* unmanaged<IntPtr, godot_string*, void*, int, void>, void> ScriptManagerBridge_GetPropertyInfoList;
|
||||||
public delegate* unmanaged<IntPtr, delegate* unmanaged<IntPtr, void*, int, void>, void> ScriptManagerBridge_GetPropertyDefaultValues;
|
public delegate* unmanaged<IntPtr, delegate* unmanaged<IntPtr, void*, int, void>, void> ScriptManagerBridge_GetPropertyDefaultValues;
|
||||||
|
|
|
@ -298,6 +298,13 @@ namespace Godot.Bridge
|
||||||
|
|
||||||
_pathTypeBiMap.Add(scriptPathAttr.Path, type);
|
_pathTypeBiMap.Add(scriptPathAttr.Path, type);
|
||||||
|
|
||||||
|
// This method may be called before initialization.
|
||||||
|
if (NativeFuncs.godotsharp_dotnet_module_is_initialized().ToBool() && Engine.IsEditorHint())
|
||||||
|
{
|
||||||
|
using godot_string scriptPath = Marshaling.ConvertStringToNative(scriptPathAttr.Path);
|
||||||
|
NativeFuncs.godotsharp_internal_editor_file_system_update_file(scriptPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (AlcReloadCfg.IsAlcReloadingEnabled)
|
if (AlcReloadCfg.IsAlcReloadingEnabled)
|
||||||
{
|
{
|
||||||
AddTypeForAlcReloading(type);
|
AddTypeForAlcReloading(type);
|
||||||
|
@ -584,7 +591,8 @@ namespace Godot.Bridge
|
||||||
}
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
internal static unsafe void UpdateScriptClassInfo(IntPtr scriptPtr, godot_bool* outTool,
|
internal static unsafe void UpdateScriptClassInfo(IntPtr scriptPtr, godot_string* outClassName,
|
||||||
|
godot_bool* outTool, godot_bool* outGlobal, godot_string* outIconPath,
|
||||||
godot_array* outMethodsDest, godot_dictionary* outRpcFunctionsDest,
|
godot_array* outMethodsDest, godot_dictionary* outRpcFunctionsDest,
|
||||||
godot_dictionary* outEventSignalsDest, godot_ref* outBaseScript)
|
godot_dictionary* outEventSignalsDest, godot_ref* outBaseScript)
|
||||||
{
|
{
|
||||||
|
@ -593,6 +601,8 @@ namespace Godot.Bridge
|
||||||
// Performance is not critical here as this will be replaced with source generators.
|
// Performance is not critical here as this will be replaced with source generators.
|
||||||
var scriptType = _scriptTypeBiMap.GetScriptType(scriptPtr);
|
var scriptType = _scriptTypeBiMap.GetScriptType(scriptPtr);
|
||||||
|
|
||||||
|
*outClassName = Marshaling.ConvertStringToNative(scriptType.Name);
|
||||||
|
|
||||||
*outTool = scriptType.GetCustomAttributes(inherit: false)
|
*outTool = scriptType.GetCustomAttributes(inherit: false)
|
||||||
.OfType<ToolAttribute>()
|
.OfType<ToolAttribute>()
|
||||||
.Any().ToGodotBool();
|
.Any().ToGodotBool();
|
||||||
|
@ -607,6 +617,18 @@ namespace Godot.Bridge
|
||||||
if (!(*outTool).ToBool() && scriptType.Assembly.GetName().Name == "GodotTools")
|
if (!(*outTool).ToBool() && scriptType.Assembly.GetName().Name == "GodotTools")
|
||||||
*outTool = godot_bool.True;
|
*outTool = godot_bool.True;
|
||||||
|
|
||||||
|
var globalAttr = scriptType.GetCustomAttributes(inherit: false)
|
||||||
|
.OfType<GlobalClassAttribute>()
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
*outGlobal = (globalAttr != null).ToGodotBool();
|
||||||
|
|
||||||
|
var iconAttr = scriptType.GetCustomAttributes(inherit: false)
|
||||||
|
.OfType<IconAttribute>()
|
||||||
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
*outIconPath = Marshaling.ConvertStringToNative(iconAttr?.Path);
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
|
||||||
// Performance is not critical here as this will be replaced with source generators.
|
// Performance is not critical here as this will be replaced with source generators.
|
||||||
|
@ -693,7 +715,7 @@ namespace Godot.Bridge
|
||||||
}
|
}
|
||||||
|
|
||||||
*outRpcFunctionsDest = NativeFuncs.godotsharp_dictionary_new_copy(
|
*outRpcFunctionsDest = NativeFuncs.godotsharp_dictionary_new_copy(
|
||||||
(godot_dictionary)(rpcFunctions).NativeValue);
|
(godot_dictionary)rpcFunctions.NativeValue);
|
||||||
|
|
||||||
// Event signals
|
// Event signals
|
||||||
|
|
||||||
|
@ -755,7 +777,10 @@ namespace Godot.Bridge
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
ExceptionUtils.LogException(e);
|
ExceptionUtils.LogException(e);
|
||||||
|
*outClassName = default;
|
||||||
*outTool = godot_bool.False;
|
*outTool = godot_bool.False;
|
||||||
|
*outGlobal = godot_bool.False;
|
||||||
|
*outIconPath = default;
|
||||||
*outMethodsDest = NativeFuncs.godotsharp_array_new();
|
*outMethodsDest = NativeFuncs.godotsharp_array_new();
|
||||||
*outRpcFunctionsDest = NativeFuncs.godotsharp_dictionary_new();
|
*outRpcFunctionsDest = NativeFuncs.godotsharp_dictionary_new();
|
||||||
*outEventSignalsDest = NativeFuncs.godotsharp_dictionary_new();
|
*outEventSignalsDest = NativeFuncs.godotsharp_dictionary_new();
|
||||||
|
|
|
@ -37,6 +37,8 @@ namespace Godot.NativeInterop
|
||||||
|
|
||||||
// Custom functions
|
// Custom functions
|
||||||
|
|
||||||
|
internal static partial godot_bool godotsharp_dotnet_module_is_initialized();
|
||||||
|
|
||||||
public static partial IntPtr godotsharp_method_bind_get_method(in godot_string_name p_classname,
|
public static partial IntPtr godotsharp_method_bind_get_method(in godot_string_name p_classname,
|
||||||
in godot_string_name p_methodname);
|
in godot_string_name p_methodname);
|
||||||
|
|
||||||
|
@ -52,6 +54,8 @@ namespace Godot.NativeInterop
|
||||||
internal static partial void godotsharp_stack_info_vector_destroy(
|
internal static partial void godotsharp_stack_info_vector_destroy(
|
||||||
ref DebuggingUtils.godot_stack_info_vector p_stack_info_vector);
|
ref DebuggingUtils.godot_stack_info_vector p_stack_info_vector);
|
||||||
|
|
||||||
|
internal static partial void godotsharp_internal_editor_file_system_update_file(in godot_string p_script_path);
|
||||||
|
|
||||||
internal static partial void godotsharp_internal_script_debugger_send_error(in godot_string p_func,
|
internal static partial void godotsharp_internal_script_debugger_send_error(in godot_string p_func,
|
||||||
in godot_string p_file, int p_line, in godot_string p_err, in godot_string p_descr,
|
in godot_string p_file, int p_line, in godot_string p_err, in godot_string p_descr,
|
||||||
godot_bool p_warning, in DebuggingUtils.godot_stack_info_vector p_stack_info_vector);
|
godot_bool p_warning, in DebuggingUtils.godot_stack_info_vector p_stack_info_vector);
|
||||||
|
|
|
@ -60,7 +60,9 @@
|
||||||
<Compile Include="Core\Attributes\ExportCategoryAttribute.cs" />
|
<Compile Include="Core\Attributes\ExportCategoryAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\ExportGroupAttribute.cs" />
|
<Compile Include="Core\Attributes\ExportGroupAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\ExportSubgroupAttribute.cs" />
|
<Compile Include="Core\Attributes\ExportSubgroupAttribute.cs" />
|
||||||
|
<Compile Include="Core\Attributes\GlobalClassAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\GodotClassNameAttribute.cs" />
|
<Compile Include="Core\Attributes\GodotClassNameAttribute.cs" />
|
||||||
|
<Compile Include="Core\Attributes\IconAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\MustBeVariantAttribute.cs" />
|
<Compile Include="Core\Attributes\MustBeVariantAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\RpcAttribute.cs" />
|
<Compile Include="Core\Attributes\RpcAttribute.cs" />
|
||||||
<Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
|
<Compile Include="Core\Attributes\ScriptPathAttribute.cs" />
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
#include "core/os/os.h"
|
#include "core/os/os.h"
|
||||||
#include "core/string/string_name.h"
|
#include "core/string/string_name.h"
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
|
#include "editor/editor_file_system.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "../interop_types.h"
|
#include "../interop_types.h"
|
||||||
|
|
||||||
#include "modules/mono/csharp_script.h"
|
#include "modules/mono/csharp_script.h"
|
||||||
|
@ -57,6 +61,10 @@ static_assert(sizeof(SafeRefCount) == sizeof(uint32_t));
|
||||||
|
|
||||||
typedef Object *(*godotsharp_class_creation_func)();
|
typedef Object *(*godotsharp_class_creation_func)();
|
||||||
|
|
||||||
|
bool godotsharp_dotnet_module_is_initialized() {
|
||||||
|
return GDMono::get_singleton()->is_initialized();
|
||||||
|
}
|
||||||
|
|
||||||
MethodBind *godotsharp_method_bind_get_method(const StringName *p_classname, const StringName *p_methodname) {
|
MethodBind *godotsharp_method_bind_get_method(const StringName *p_classname, const StringName *p_methodname) {
|
||||||
return ClassDB::get_method(*p_classname, *p_methodname);
|
return ClassDB::get_method(*p_classname, *p_methodname);
|
||||||
}
|
}
|
||||||
|
@ -304,6 +312,20 @@ void godotsharp_internal_new_csharp_script(Ref<CSharpScript> *r_dest) {
|
||||||
memnew_placement(r_dest, Ref<CSharpScript>(memnew(CSharpScript)));
|
memnew_placement(r_dest, Ref<CSharpScript>(memnew(CSharpScript)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void godotsharp_internal_editor_file_system_update_file(const String *p_script_path) {
|
||||||
|
#if TOOLS_ENABLED
|
||||||
|
// If the EditorFileSystem singleton is available, update the file;
|
||||||
|
// otherwise, the file will be updated when the singleton becomes available.
|
||||||
|
EditorFileSystem *efs = EditorFileSystem::get_singleton();
|
||||||
|
if (efs) {
|
||||||
|
efs->update_file(*p_script_path);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// EditorFileSystem is only available when running in the Godot editor.
|
||||||
|
DEV_ASSERT(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool godotsharp_internal_script_load(const String *p_path, Ref<CSharpScript> *r_dest) {
|
bool godotsharp_internal_script_load(const String *p_path, Ref<CSharpScript> *r_dest) {
|
||||||
Ref<Resource> res = ResourceLoader::load(*p_path);
|
Ref<Resource> res = ResourceLoader::load(*p_path);
|
||||||
if (res.is_valid()) {
|
if (res.is_valid()) {
|
||||||
|
@ -1391,11 +1413,13 @@ void godotsharp_object_to_string(Object *p_ptr, godot_string *r_str) {
|
||||||
// The order in this array must match the declaration order of
|
// The order in this array must match the declaration order of
|
||||||
// the methods in 'GodotSharp/Core/NativeInterop/NativeFuncs.cs'.
|
// the methods in 'GodotSharp/Core/NativeInterop/NativeFuncs.cs'.
|
||||||
static const void *unmanaged_callbacks[]{
|
static const void *unmanaged_callbacks[]{
|
||||||
|
(void *)godotsharp_dotnet_module_is_initialized,
|
||||||
(void *)godotsharp_method_bind_get_method,
|
(void *)godotsharp_method_bind_get_method,
|
||||||
(void *)godotsharp_get_class_constructor,
|
(void *)godotsharp_get_class_constructor,
|
||||||
(void *)godotsharp_engine_get_singleton,
|
(void *)godotsharp_engine_get_singleton,
|
||||||
(void *)godotsharp_stack_info_vector_resize,
|
(void *)godotsharp_stack_info_vector_resize,
|
||||||
(void *)godotsharp_stack_info_vector_destroy,
|
(void *)godotsharp_stack_info_vector_destroy,
|
||||||
|
(void *)godotsharp_internal_editor_file_system_update_file,
|
||||||
(void *)godotsharp_internal_script_debugger_send_error,
|
(void *)godotsharp_internal_script_debugger_send_error,
|
||||||
(void *)godotsharp_internal_script_debugger_is_active,
|
(void *)godotsharp_internal_script_debugger_is_active,
|
||||||
(void *)godotsharp_internal_object_get_associated_gchandle,
|
(void *)godotsharp_internal_object_get_associated_gchandle,
|
||||||
|
|
|
@ -443,6 +443,8 @@ void GDMono::initialize() {
|
||||||
print_verbose(".NET: GodotPlugins initialized");
|
print_verbose(".NET: GodotPlugins initialized");
|
||||||
|
|
||||||
_on_core_api_assembly_loaded();
|
_on_core_api_assembly_loaded();
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
|
@ -527,14 +529,6 @@ Error GDMono::reload_project_assemblies() {
|
||||||
|
|
||||||
GDMono::GDMono() {
|
GDMono::GDMono() {
|
||||||
singleton = this;
|
singleton = this;
|
||||||
|
|
||||||
runtime_initialized = false;
|
|
||||||
finalizing_scripts_domain = false;
|
|
||||||
|
|
||||||
api_core_hash = 0;
|
|
||||||
#ifdef TOOLS_ENABLED
|
|
||||||
api_editor_hash = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GDMono::~GDMono() {
|
GDMono::~GDMono() {
|
||||||
|
|
|
@ -59,8 +59,9 @@ struct PluginCallbacks {
|
||||||
} // namespace gdmono
|
} // namespace gdmono
|
||||||
|
|
||||||
class GDMono {
|
class GDMono {
|
||||||
bool runtime_initialized;
|
bool initialized = false;
|
||||||
bool finalizing_scripts_domain;
|
bool runtime_initialized = false;
|
||||||
|
bool finalizing_scripts_domain = false;
|
||||||
|
|
||||||
void *hostfxr_dll_handle = nullptr;
|
void *hostfxr_dll_handle = nullptr;
|
||||||
bool is_native_aot = false;
|
bool is_native_aot = false;
|
||||||
|
@ -72,9 +73,9 @@ class GDMono {
|
||||||
bool _load_project_assembly();
|
bool _load_project_assembly();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint64_t api_core_hash;
|
uint64_t api_core_hash = 0;
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
uint64_t api_editor_hash;
|
uint64_t api_editor_hash = 0;
|
||||||
#endif
|
#endif
|
||||||
void _init_godot_api_hashes();
|
void _init_godot_api_hashes();
|
||||||
|
|
||||||
|
@ -119,6 +120,9 @@ public:
|
||||||
return singleton;
|
return singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ bool is_initialized() const {
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
_FORCE_INLINE_ bool is_runtime_initialized() const {
|
_FORCE_INLINE_ bool is_runtime_initialized() const {
|
||||||
return runtime_initialized;
|
return runtime_initialized;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ struct ManagedCallbacks {
|
||||||
using FuncScriptManagerBridge_GetOrCreateScriptBridgeForPath = void(GD_CLR_STDCALL *)(const String *, Ref<CSharpScript> *);
|
using FuncScriptManagerBridge_GetOrCreateScriptBridgeForPath = void(GD_CLR_STDCALL *)(const String *, Ref<CSharpScript> *);
|
||||||
using FuncScriptManagerBridge_RemoveScriptBridge = void(GD_CLR_STDCALL *)(const CSharpScript *);
|
using FuncScriptManagerBridge_RemoveScriptBridge = void(GD_CLR_STDCALL *)(const CSharpScript *);
|
||||||
using FuncScriptManagerBridge_TryReloadRegisteredScriptWithClass = bool(GD_CLR_STDCALL *)(const CSharpScript *);
|
using FuncScriptManagerBridge_TryReloadRegisteredScriptWithClass = bool(GD_CLR_STDCALL *)(const CSharpScript *);
|
||||||
using FuncScriptManagerBridge_UpdateScriptClassInfo = void(GD_CLR_STDCALL *)(const CSharpScript *, bool *, Array *, Dictionary *, Dictionary *, Ref<CSharpScript> *);
|
using FuncScriptManagerBridge_UpdateScriptClassInfo = void(GD_CLR_STDCALL *)(const CSharpScript *, String *, bool *, bool *, String *, Array *, Dictionary *, Dictionary *, Ref<CSharpScript> *);
|
||||||
using FuncScriptManagerBridge_SwapGCHandleForType = bool(GD_CLR_STDCALL *)(GCHandleIntPtr, GCHandleIntPtr *, bool);
|
using FuncScriptManagerBridge_SwapGCHandleForType = bool(GD_CLR_STDCALL *)(GCHandleIntPtr, GCHandleIntPtr *, bool);
|
||||||
using FuncScriptManagerBridge_GetPropertyInfoList = void(GD_CLR_STDCALL *)(CSharpScript *, Callback_ScriptManagerBridge_GetPropertyInfoList_Add);
|
using FuncScriptManagerBridge_GetPropertyInfoList = void(GD_CLR_STDCALL *)(CSharpScript *, Callback_ScriptManagerBridge_GetPropertyInfoList_Add);
|
||||||
using FuncScriptManagerBridge_GetPropertyDefaultValues = void(GD_CLR_STDCALL *)(CSharpScript *, Callback_ScriptManagerBridge_GetPropertyDefaultValues_Add);
|
using FuncScriptManagerBridge_GetPropertyDefaultValues = void(GD_CLR_STDCALL *)(CSharpScript *, Callback_ScriptManagerBridge_GetPropertyDefaultValues_Add);
|
||||||
|
|
Loading…
Reference in a new issue