C#: Lookup signals and methods in Get method
Allows to retrieve `Callable`s and `Signal`s using `Get` like it works in GDScript.
This commit is contained in:
parent
3c9bf4bc21
commit
a6ba914f15
@ -272,6 +272,25 @@ namespace Godot.SourceGenerators
|
||||
source.Append(" }\n");
|
||||
}
|
||||
|
||||
// Generate HasGodotClassSignal
|
||||
|
||||
if (godotSignalDelegates.Count > 0)
|
||||
{
|
||||
source.Append(
|
||||
" protected override bool HasGodotClassSignal(in godot_string_name signal)\n {\n");
|
||||
|
||||
bool isFirstEntry = true;
|
||||
foreach (var signal in godotSignalDelegates)
|
||||
{
|
||||
GenerateHasSignalEntry(signal.Name, source, isFirstEntry);
|
||||
isFirstEntry = false;
|
||||
}
|
||||
|
||||
source.Append(" return base.HasGodotClassSignal(signal);\n");
|
||||
|
||||
source.Append(" }\n");
|
||||
}
|
||||
|
||||
source.Append("}\n"); // partial class
|
||||
|
||||
if (isInnerClass)
|
||||
@ -397,6 +416,20 @@ namespace Godot.SourceGenerators
|
||||
PropertyHint.None, string.Empty, propUsage, exported: false);
|
||||
}
|
||||
|
||||
private static void GenerateHasSignalEntry(
|
||||
string signalName,
|
||||
StringBuilder source,
|
||||
bool isFirstEntry
|
||||
)
|
||||
{
|
||||
source.Append(" ");
|
||||
if (!isFirstEntry)
|
||||
source.Append("else ");
|
||||
source.Append("if (signal == SignalName.");
|
||||
source.Append(signalName);
|
||||
source.Append(") {\n return true;\n }\n");
|
||||
}
|
||||
|
||||
private static void GenerateSignalEventInvoker(
|
||||
GodotSignalDelegateData signal,
|
||||
StringBuilder source
|
||||
|
@ -84,10 +84,12 @@ StringBuilder &operator<<(StringBuilder &r_sb, const char *p_cstring) {
|
||||
#define CS_PROPERTY_SINGLETON "Singleton"
|
||||
#define CS_METHOD_INVOKE_GODOT_CLASS_METHOD "InvokeGodotClassMethod"
|
||||
#define CS_METHOD_HAS_GODOT_CLASS_METHOD "HasGodotClassMethod"
|
||||
#define CS_METHOD_HAS_GODOT_CLASS_SIGNAL "HasGodotClassSignal"
|
||||
|
||||
#define CS_STATIC_FIELD_NATIVE_CTOR "NativeCtor"
|
||||
#define CS_STATIC_FIELD_METHOD_BIND_PREFIX "MethodBind"
|
||||
#define CS_STATIC_FIELD_METHOD_PROXY_NAME_PREFIX "MethodProxyName_"
|
||||
#define CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX "SignalProxyName_"
|
||||
|
||||
#define ICALL_PREFIX "godot_icall_"
|
||||
#define ICALL_CLASSDB_GET_METHOD "ClassDB_get_method"
|
||||
@ -1608,6 +1610,16 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
|
||||
<< " = \"" << imethod.proxy_name << "\";\n";
|
||||
}
|
||||
|
||||
// Generate signal names cache fields
|
||||
|
||||
for (const SignalInterface &isignal : itype.signals_) {
|
||||
output << MEMBER_BEGIN "// ReSharper disable once InconsistentNaming\n"
|
||||
<< INDENT1 "[DebuggerBrowsable(DebuggerBrowsableState.Never)]\n"
|
||||
<< INDENT1 "private static readonly StringName "
|
||||
<< CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX << isignal.name
|
||||
<< " = \"" << isignal.proxy_name << "\";\n";
|
||||
}
|
||||
|
||||
// TODO: Only generate HasGodotClassMethod and InvokeGodotClassMethod if there's any method
|
||||
|
||||
// Generate InvokeGodotClassMethod
|
||||
@ -1721,6 +1733,34 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
|
||||
}
|
||||
|
||||
output << INDENT1 "}\n";
|
||||
|
||||
// Generate HasGodotClassSignal
|
||||
|
||||
output << MEMBER_BEGIN "protected internal " << (is_derived_type ? "override" : "virtual")
|
||||
<< " bool " CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(in godot_string_name signal)\n"
|
||||
<< INDENT1 "{\n";
|
||||
|
||||
for (const SignalInterface &isignal : itype.signals_) {
|
||||
// We check for native names (snake_case). If we detect one, we call HasGodotClassSignal
|
||||
// again, but this time with the respective proxy name (PascalCase). It's the job of
|
||||
// user derived classes to override the method and check for those. Our C# source
|
||||
// generators take care of generating those override methods.
|
||||
output << INDENT2 "if (signal == SignalName." << isignal.proxy_name
|
||||
<< ")\n" INDENT2 "{\n"
|
||||
<< INDENT3 "if (" CS_METHOD_HAS_GODOT_CLASS_SIGNAL "("
|
||||
<< CS_STATIC_FIELD_SIGNAL_PROXY_NAME_PREFIX << isignal.name
|
||||
<< ".NativeValue.DangerousSelfRef))\n" INDENT3 "{\n"
|
||||
<< INDENT4 "return true;\n"
|
||||
<< INDENT3 "}\n" INDENT2 "}\n";
|
||||
}
|
||||
|
||||
if (is_derived_type) {
|
||||
output << INDENT2 "return base." CS_METHOD_HAS_GODOT_CLASS_SIGNAL "(signal);\n";
|
||||
} else {
|
||||
output << INDENT2 "return false;\n";
|
||||
}
|
||||
|
||||
output << INDENT1 "}\n";
|
||||
}
|
||||
|
||||
//Generate StringName for all class members
|
||||
|
@ -84,12 +84,29 @@ namespace Godot.Bridge
|
||||
if (godotObject == null)
|
||||
throw new InvalidOperationException();
|
||||
|
||||
// Properties
|
||||
if (godotObject.GetGodotClassPropertyValue(CustomUnsafe.AsRef(name), out godot_variant outRetValue))
|
||||
{
|
||||
*outRet = outRetValue;
|
||||
return godot_bool.True;
|
||||
}
|
||||
|
||||
// Signals
|
||||
if (godotObject.HasGodotClassSignal(CustomUnsafe.AsRef(name)))
|
||||
{
|
||||
godot_signal signal = new godot_signal(*name, godotObject.GetInstanceId());
|
||||
*outRet = VariantUtils.CreateFromSignalTakingOwnershipOfDisposableValue(signal);
|
||||
return godot_bool.True;
|
||||
}
|
||||
|
||||
// Methods
|
||||
if (godotObject.HasGodotClassMethod(CustomUnsafe.AsRef(name)))
|
||||
{
|
||||
godot_callable method = new godot_callable(*name, godotObject.GetInstanceId());
|
||||
*outRet = VariantUtils.CreateFromCallableTakingOwnershipOfDisposableValue(method);
|
||||
return godot_bool.True;
|
||||
}
|
||||
|
||||
var nameManaged = StringName.CreateTakingOwnershipOfDisposableValue(
|
||||
NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(name)));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user