|
@@ -12,22 +12,11 @@ namespace Godot.Bridge
|
|
{
|
|
{
|
|
public static class ScriptManagerBridge
|
|
public static class ScriptManagerBridge
|
|
{
|
|
{
|
|
- private static System.Collections.Generic.Dictionary<string, ScriptLookupInfo> _scriptLookupMap = new();
|
|
|
|
- private static System.Collections.Generic.Dictionary<IntPtr, Type> _scriptBridgeMap = new();
|
|
|
|
|
|
+ private static System.Collections.Generic.Dictionary<string, Type> _pathScriptMap = new();
|
|
|
|
|
|
- private struct ScriptLookupInfo
|
|
|
|
- {
|
|
|
|
- public string ClassNamespace { get; private set; }
|
|
|
|
- public string ClassName { get; private set; }
|
|
|
|
- public Type ScriptType { get; private set; }
|
|
|
|
-
|
|
|
|
- public ScriptLookupInfo(string classNamespace, string className, Type scriptType)
|
|
|
|
- {
|
|
|
|
- ClassNamespace = classNamespace;
|
|
|
|
- ClassName = className;
|
|
|
|
- ScriptType = scriptType;
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
|
|
+ private static readonly object ScriptBridgeLock = new();
|
|
|
|
+ private static System.Collections.Generic.Dictionary<IntPtr, Type> _scriptTypeMap = new();
|
|
|
|
+ private static System.Collections.Generic.Dictionary<Type, IntPtr> _typeScriptMap = new();
|
|
|
|
|
|
[UnmanagedCallersOnly]
|
|
[UnmanagedCallersOnly]
|
|
internal static void FrameCallback()
|
|
internal static void FrameCallback()
|
|
@@ -80,7 +69,7 @@ namespace Godot.Bridge
|
|
try
|
|
try
|
|
{
|
|
{
|
|
// 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.
|
|
- Type scriptType = _scriptBridgeMap[scriptPtr];
|
|
|
|
|
|
+ Type scriptType = _scriptTypeMap[scriptPtr];
|
|
var obj = (Object)FormatterServices.GetUninitializedObject(scriptType);
|
|
var obj = (Object)FormatterServices.GetUninitializedObject(scriptType);
|
|
|
|
|
|
var ctor = scriptType
|
|
var ctor = scriptType
|
|
@@ -133,7 +122,7 @@ namespace Godot.Bridge
|
|
try
|
|
try
|
|
{
|
|
{
|
|
// 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.
|
|
- if (!_scriptBridgeMap.TryGetValue(scriptPtr, out var scriptType))
|
|
|
|
|
|
+ if (!_scriptTypeMap.TryGetValue(scriptPtr, out var scriptType))
|
|
{
|
|
{
|
|
*outRes = default;
|
|
*outRes = default;
|
|
return;
|
|
return;
|
|
@@ -225,7 +214,7 @@ namespace Godot.Bridge
|
|
if (scriptPathAttr == null)
|
|
if (scriptPathAttr == null)
|
|
return;
|
|
return;
|
|
|
|
|
|
- _scriptLookupMap[scriptPathAttr.Path] = new ScriptLookupInfo(type.Namespace, type.Name, type);
|
|
|
|
|
|
+ _pathScriptMap[scriptPathAttr.Path] = type;
|
|
}
|
|
}
|
|
|
|
|
|
var assemblyHasScriptsAttr = assembly.GetCustomAttributes(inherit: false)
|
|
var assemblyHasScriptsAttr = assembly.GetCustomAttributes(inherit: false)
|
|
@@ -304,7 +293,7 @@ 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.
|
|
using var signals = new Dictionary();
|
|
using var signals = new Dictionary();
|
|
|
|
|
|
- Type top = _scriptBridgeMap[scriptPtr];
|
|
|
|
|
|
+ Type top = _scriptTypeMap[scriptPtr];
|
|
Type native = Object.InternalGetClassNativeBase(top);
|
|
Type native = Object.InternalGetClassNativeBase(top);
|
|
|
|
|
|
while (top != null && top != native)
|
|
while (top != null && top != native)
|
|
@@ -400,7 +389,7 @@ namespace Godot.Bridge
|
|
|
|
|
|
string signalNameStr = Marshaling.ConvertStringToManaged(*signalName);
|
|
string signalNameStr = Marshaling.ConvertStringToManaged(*signalName);
|
|
|
|
|
|
- Type top = _scriptBridgeMap[scriptPtr];
|
|
|
|
|
|
+ Type top = _scriptTypeMap[scriptPtr];
|
|
Type native = Object.InternalGetClassNativeBase(top);
|
|
Type native = Object.InternalGetClassNativeBase(top);
|
|
|
|
|
|
while (top != null && top != native)
|
|
while (top != null && top != native)
|
|
@@ -446,10 +435,10 @@ namespace Godot.Bridge
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- if (!_scriptBridgeMap.TryGetValue(scriptPtr, out var scriptType))
|
|
|
|
|
|
+ if (!_scriptTypeMap.TryGetValue(scriptPtr, out var scriptType))
|
|
return false.ToGodotBool();
|
|
return false.ToGodotBool();
|
|
|
|
|
|
- if (!_scriptBridgeMap.TryGetValue(scriptPtrMaybeBase, out var maybeBaseType))
|
|
|
|
|
|
+ if (!_scriptTypeMap.TryGetValue(scriptPtrMaybeBase, out var maybeBaseType))
|
|
return false.ToGodotBool();
|
|
return false.ToGodotBool();
|
|
|
|
|
|
return (scriptType == maybeBaseType || maybeBaseType.IsAssignableFrom(scriptType)).ToGodotBool();
|
|
return (scriptType == maybeBaseType || maybeBaseType.IsAssignableFrom(scriptType)).ToGodotBool();
|
|
@@ -466,12 +455,19 @@ namespace Godot.Bridge
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- string scriptPathStr = Marshaling.ConvertStringToManaged(*scriptPath);
|
|
|
|
|
|
+ lock (ScriptBridgeLock)
|
|
|
|
+ {
|
|
|
|
+ if (!_scriptTypeMap.ContainsKey(scriptPtr))
|
|
|
|
+ {
|
|
|
|
+ string scriptPathStr = Marshaling.ConvertStringToManaged(*scriptPath);
|
|
|
|
|
|
- if (!_scriptLookupMap.TryGetValue(scriptPathStr, out var lookupInfo))
|
|
|
|
- return false.ToGodotBool();
|
|
|
|
|
|
+ if (!_pathScriptMap.TryGetValue(scriptPathStr, out Type scriptType))
|
|
|
|
+ return false.ToGodotBool();
|
|
|
|
|
|
- _scriptBridgeMap.Add(scriptPtr, lookupInfo.ScriptType);
|
|
|
|
|
|
+ _scriptTypeMap.Add(scriptPtr, scriptType);
|
|
|
|
+ _typeScriptMap.Add(scriptType, scriptPtr);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
return true.ToGodotBool();
|
|
return true.ToGodotBool();
|
|
}
|
|
}
|
|
@@ -482,15 +478,49 @@ namespace Godot.Bridge
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- internal static void AddScriptBridgeWithType(IntPtr scriptPtr, Type scriptType)
|
|
|
|
- => _scriptBridgeMap.Add(scriptPtr, scriptType);
|
|
|
|
|
|
+ [UnmanagedCallersOnly]
|
|
|
|
+ internal static unsafe void GetOrCreateScriptBridgeForPath(godot_string* scriptPath, godot_ref* outScript)
|
|
|
|
+ {
|
|
|
|
+ string scriptPathStr = Marshaling.ConvertStringToManaged(*scriptPath);
|
|
|
|
+
|
|
|
|
+ if (!_pathScriptMap.TryGetValue(scriptPathStr, out Type scriptType))
|
|
|
|
+ {
|
|
|
|
+ NativeFuncs.godotsharp_internal_new_csharp_script(outScript);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ GetOrCreateScriptBridgeForType(scriptType, outScript);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ internal static unsafe void GetOrCreateScriptBridgeForType(Type scriptType, godot_ref* outScript)
|
|
|
|
+ {
|
|
|
|
+ lock (ScriptBridgeLock)
|
|
|
|
+ {
|
|
|
|
+ if (_typeScriptMap.TryGetValue(scriptType, out IntPtr scriptPtr))
|
|
|
|
+ {
|
|
|
|
+ NativeFuncs.godotsharp_ref_new_from_ref_counted_ptr(out *outScript, scriptPtr);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ NativeFuncs.godotsharp_internal_new_csharp_script(outScript);
|
|
|
|
+ scriptPtr = outScript->Reference;
|
|
|
|
+
|
|
|
|
+ _scriptTypeMap.Add(scriptPtr, scriptType);
|
|
|
|
+ _typeScriptMap.Add(scriptType, scriptPtr);
|
|
|
|
+
|
|
|
|
+ NativeFuncs.godotsharp_internal_reload_registered_script(scriptPtr);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
[UnmanagedCallersOnly]
|
|
[UnmanagedCallersOnly]
|
|
internal static void RemoveScriptBridge(IntPtr scriptPtr)
|
|
internal static void RemoveScriptBridge(IntPtr scriptPtr)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- _scriptBridgeMap.Remove(scriptPtr);
|
|
|
|
|
|
+ lock (ScriptBridgeLock)
|
|
|
|
+ {
|
|
|
|
+ _ = _scriptTypeMap.Remove(scriptPtr);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
catch (Exception e)
|
|
{
|
|
{
|
|
@@ -505,7 +535,7 @@ namespace Godot.Bridge
|
|
try
|
|
try
|
|
{
|
|
{
|
|
// 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 = _scriptBridgeMap[scriptPtr];
|
|
|
|
|
|
+ var scriptType = _scriptTypeMap[scriptPtr];
|
|
|
|
|
|
*outTool = scriptType.GetCustomAttributes(inherit: false)
|
|
*outTool = scriptType.GetCustomAttributes(inherit: false)
|
|
.OfType<ToolAttribute>()
|
|
.OfType<ToolAttribute>()
|
|
@@ -630,7 +660,7 @@ namespace Godot.Bridge
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- Type scriptType = _scriptBridgeMap[scriptPtr];
|
|
|
|
|
|
+ Type scriptType = _scriptTypeMap[scriptPtr];
|
|
GetPropertyInfoListForType(scriptType, scriptPtr, addPropInfoFunc);
|
|
GetPropertyInfoListForType(scriptType, scriptPtr, addPropInfoFunc);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
catch (Exception e)
|
|
@@ -752,7 +782,7 @@ namespace Godot.Bridge
|
|
{
|
|
{
|
|
try
|
|
try
|
|
{
|
|
{
|
|
- Type top = _scriptBridgeMap[scriptPtr];
|
|
|
|
|
|
+ Type top = _scriptTypeMap[scriptPtr];
|
|
Type native = Object.InternalGetClassNativeBase(top);
|
|
Type native = Object.InternalGetClassNativeBase(top);
|
|
|
|
|
|
while (top != null && top != native)
|
|
while (top != null && top != native)
|