Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions godot-mono-decomp/GodotMonoDecomp/GodotModuleDecompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ private string GetPathForType(ITypeDefinition? typeDef){
.Where(p => p.GetAttributes().Any(a => a.AttributeType.Name == "ExportAttribute")).ToList();
var fields = typeDef.Fields.Where(p => p.GetAttributes().Any(a => a.AttributeType.Name.Contains("Export")))
.ToList();
var signals = GodotStuff.GetSignalsInClass(typeDef);
var signals = GodotStuff.GetSignalDelegatesInClass(typeDef);
var syntaxTree = decompiler.DecompileTypes([type]);
var isTool = typeDef.GetAttributes().FirstOrDefault(a => a.AttributeType.Name == "ToolAttribute") != null;

Expand Down Expand Up @@ -618,7 +618,7 @@ private string GetPathForType(ITypeDefinition? typeDef){
args = invokeMethod.Parameters.Select(p => p.Name).ToArray();
argTypes = invokeMethod.Parameters.Select(p => p.Type.Name).ToArray();
}
signalsInfo.Add(new MethodInfo(signal.Name, "void", args, argTypes, false, false, false));
signalsInfo.Add(new MethodInfo(signal.Name.Substring(0, signal.Name.Length - GodotStuff.SIGNAL_DELEGATE_SUFFIX.Length), "void", args, argTypes, false, false, false));
}

foreach (var method in typeDef.Methods)
Expand Down
39 changes: 17 additions & 22 deletions godot-mono-decomp/GodotMonoDecomp/GodotStuff.cs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ public void Run(AstNode rootNode, TransformContext context)
public static class GodotStuff
{
public const string BACKING_FIELD_PREFIX = "backing_";
public const string EMIT_SIGNAL_METHOD_PREFIX = "EmitSignal";

// While signal delegates are user-defined, Godot source generators require them to have this suffix.
public const string SIGNAL_DELEGATE_SUFFIX = "EventHandler";

public static DotNetCoreDepInfo? GetGodotSharpPackageDep(DotNetCoreDepInfo? depInfo)
{
Expand Down Expand Up @@ -344,7 +348,7 @@ public static Dictionary<string, List<TypeDefinitionHandle>> CreateFileMap(Metad
bool useNestedDirectoriesForNamespaces,
ISet<TypeDefinitionHandle>? godotClassHandles = null)
{
var fileMap = new Dictionary<string, List<TypeDefinitionHandle>>(StringComparer.OrdinalIgnoreCase);
Dictionary<string, List<TypeDefinitionHandle>> fileMap = new Dictionary<string, List<TypeDefinitionHandle>>(StringComparer.OrdinalIgnoreCase);
godotClassHandles ??= new HashSet<TypeDefinitionHandle>();
var canonicalPaths = new HashSet<string>();
var canonicalHandles = new HashSet<TypeDefinitionHandle>();
Expand Down Expand Up @@ -988,23 +992,10 @@ public static bool IsGodotPartialClass(ITypeDefinition entity)

public static bool IsSignalDelegate(IEntity entity)
{
var attributes = entity.GetAttributes();

// check if any of the attributes are "Signal"
if (attributes.Any(a => a.AttributeType.FullName == "Godot.SignalAttribute"))
{
return true;
}

if (attributes.Any(a => a.AttributeType.Name == "SignalAttribute"))
{
return true;
}

return false;
return entity.GetAttributes().Any(a => a.AttributeType.FullName == "Godot.SignalAttribute");
}

public static IEnumerable<IType> GetSignalsInClass(ITypeDefinition entity)
public static IEnumerable<IType> GetSignalDelegatesInClass(ITypeDefinition entity)
{
return entity.NestedTypes.Where(IsSignalDelegate);
}
Expand All @@ -1014,7 +1005,7 @@ public static bool IsBackingSignalDelegateField(IEntity entity)
if (entity is IField field)
{
return field.Name.StartsWith(BACKING_FIELD_PREFIX) && field.DeclaringTypeDefinition != null &&
GetSignalsInClass(field.DeclaringTypeDefinition).Contains(field.Type.GetDefinition());
GetSignalDelegatesInClass(field.DeclaringTypeDefinition).Contains(field.Type.GetDefinition());
}

return false;
Expand Down Expand Up @@ -1140,21 +1131,25 @@ public static bool IsBannedGodotTypeMember(IEntity entity)
return true;
}

// TODO: fix this to check if the method ends with a signal name
// if the method name is EmitSignal<SignalName> and it's a protected or private void method, then it's an auto-generated signal emitter
if (
method is { IsVirtual: false, Accessibility: Accessibility.Internal or Accessibility.Protected or Accessibility.ProtectedOrInternal or Accessibility.ProtectedAndInternal or Accessibility.Private } &&
method.Name.StartsWith("EmitSignal") && method.ReturnType.FullName == "System.Void")
method is { IsVirtual: false, Accessibility: not (Accessibility.Public or Accessibility.None) } &&
method.Name.StartsWith(EMIT_SIGNAL_METHOD_PREFIX) && method.ReturnType.FullName == "System.Void" && method.DeclaringTypeDefinition != null)
{
return true;
var strippedName = method.Name.Substring(EMIT_SIGNAL_METHOD_PREFIX.Length);
if (GetSignalDelegatesInClass(method.DeclaringTypeDefinition).Any(d => d.Name == strippedName + SIGNAL_DELEGATE_SUFFIX))
{
return true;
}
return false;
}

// auto-generated getter methods for properties of parent classes


break;
case IEvent @event:
if (@event.DeclaringTypeDefinition != null && GetSignalsInClass(@event.DeclaringTypeDefinition).Contains(@event.ReturnType.GetDefinition()) &&
if (@event.DeclaringTypeDefinition != null && GetSignalDelegatesInClass(@event.DeclaringTypeDefinition).Contains(@event.ReturnType.GetDefinition()) &&
GetBackingSignalDelegateFieldNames(@event.DeclaringTypeDefinition)
.Contains(BACKING_FIELD_PREFIX + @event.Name))
{
Expand Down
40 changes: 40 additions & 0 deletions utility/cli_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
#include "core/templates/hash_set.h"
#include "core/variant/variant.h"

#if defined(WAYLAND_ENABLED)
#include "core/os/os.h"
#endif

#include "modules/gdsdecomp/utility/gdre_version.gen.h"

namespace gdre {
Expand All @@ -24,6 +28,41 @@
print_line("Godot RE Tools " + String(GDRE_VERSION));
}

static void remove_flag(List<String> *args, const String &flag, bool has_value = false) {

Check warning on line 31 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🍎 macOS Template Release

unused function 'remove_flag'

Check warning on line 31 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🍎 macOS Template Release

unused function 'remove_flag'

Check warning on line 31 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🍎 macOS Editor

unused function 'remove_flag'

Check warning on line 31 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🤖 Android Template Release

unused function 'remove_flag'

Check warning on line 31 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🤖 Android Template Release

unused function 'remove_flag'
for (List<String>::Element *E = args->front(); E; E = E->next()) {
auto arg_and_value = E->get().split("=", true, 1);
if (arg_and_value[0] == flag) {
// if the flag has a value, get the next element and remove it
if (has_value && arg_and_value.size() == 1 && E->next()) {
args->erase(E->next());
}
args->erase(E);
break;
}
}
}

static void insert_flag_at_front(List<String> *args, const String &flag, const String &value = "") {

Check warning on line 45 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🍎 macOS Template Release

unused function 'insert_flag_at_front'

Check warning on line 45 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🍎 macOS Template Release

unused function 'insert_flag_at_front'

Check warning on line 45 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🍎 macOS Editor

unused function 'insert_flag_at_front'

Check warning on line 45 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🤖 Android Template Release

unused function 'insert_flag_at_front'

Check warning on line 45 in utility/cli_helper.h

View workflow job for this annotation

GitHub Actions / 🤖 Android Template Release

unused function 'insert_flag_at_front'
for (List<String>::Element *E = args->front(); E; E = E->next()) {
if (E->get().begins_with("-")) {
auto inserted = args->insert_before(E, flag);
if (!value.is_empty()) {
args->insert_after(inserted, value);
}
break;
}
}
}

static void add_wayland_args(List<String> *args) {
#if defined(WAYLAND_ENABLED)
if (!OS::get_singleton()->get_environment("WAYLAND_DISPLAY").is_empty()) {
remove_flag(args, "--display-driver", true);
insert_flag_at_front(args, "--display-driver", "wayland");
}
#endif
}

// returns true if we should quit the program immediately
static bool modify_cli_args(List<String> *args, List<String> *user_args) {
Vector<String> engine_args;
Expand Down Expand Up @@ -74,6 +113,7 @@
break;
}
}
add_wayland_args(args);
return false;
}
} //namespace gdre
Loading