Files
GodotHelpers/GodotHelper/src/Reflector.cs

127 lines
3.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
namespace GodotHelpers;
using System;
using System.Collections.Generic;
using System.Linq;
using Godot;
using Godot.Collections;
using Array = Godot.Collections.Array;
/// <summary>
/// Strongtyped view of Godot's get_method_list / get_property_list output.
/// </summary>
public static class Reflector
{
/* ──────────── Typed records ──────────── */
public readonly record struct ArgInfo(
string Name,
Variant.Type Type,
PropertyHint Hint,
string HintString,
Variant DefaultValue);
public readonly record struct MethodInfoEx(
string Name,
IReadOnlyList<ArgInfo> Args,
IReadOnlyList<Variant> DefaultArgs,
MethodFlags Flags,
int Id,
ArgInfo? ReturnValue);
public readonly record struct PropertyInfoEx(
string Name,
string ClassName,
Variant.Type Type,
PropertyHint Hint,
string HintString,
PropertyUsageFlags Usage);
/* ──────────── Public helpers ──────────── */
public static List<MethodInfoEx> GetMethodsListEx(this GodotObject godotObject) => GetMethods(godotObject);
public static List<MethodInfoEx> GetMethods(GodotObject obj)
{
var raw = obj.GetMethodList();
var list = new List<MethodInfoEx>(raw.Count);
foreach (Dictionary dict in raw)
{
// — Parse args —
var argsRaw = (Array)dict["args"];
var args = new List<ArgInfo>(argsRaw.Count);
foreach (Dictionary a in argsRaw)
args.Add(ParseArg(a));
// — Parse return (may be empty) —
ArgInfo? ret = null;
if (dict.TryGetValue("return", out var retRaw) && retRaw.AsGodotDictionary() is Dictionary rd && rd.Count > 0)
ret = ParseArg(rd);
list.Add(new MethodInfoEx(
Name: (string)dict["name"],
Args: args,
DefaultArgs: (Array)dict["default_args"],
Flags: (MethodFlags)(int)dict["flags"],
Id: (int)dict["id"],
ReturnValue: ret
));
}
return list;
}
public static bool TryGetMethodInfo(this GodotObject godotObject, string property, out MethodInfoEx info)
{
foreach (var item in GetMethods(godotObject))
{
if (item.Name == property)
{
info = item;
return true;
}
}
info = default;
return false;
}
public static List<PropertyInfoEx> GetPropertyListEx(this GodotObject godotObject) => GetProperties(godotObject);
public static List<PropertyInfoEx> GetProperties(GodotObject obj)
{
var raw = obj.GetPropertyList();
var list = new List<PropertyInfoEx>(raw.Count);
foreach (Dictionary dict in raw)
{
list.Add(new PropertyInfoEx(
Name: (string)dict["name"],
ClassName: (string)dict["class_name"],
Type: (Variant.Type)(int)dict["type"],
Hint: (PropertyHint)(int)dict["hint"],
HintString: (string)dict["hint_string"],
Usage: (PropertyUsageFlags)(int)dict["usage"]
));
}
return list;
}
public static PropertyInfoEx GetProperty(this IEnumerable<PropertyInfoEx> properties, string name) => properties.FirstOrDefault(item => item.Name == name);
public static bool TryGetPropertyInfo(this GodotObject godotObject, string property, out PropertyInfoEx info)
{
foreach (var item in GetProperties(godotObject))
{
if (item.Name == property)
{
info = item;
return true;
}
}
info = default;
return false;
}
/* ──────────── Internals ──────────── */
private static ArgInfo ParseArg(Dictionary d) => new(
Name: (string)d["name"],
Type: (Variant.Type)(int)d["type"],
Hint: (PropertyHint)(int)d["hint"],
HintString: (string)d["hint_string"],
DefaultValue: d.TryGetValue("default_value", out var dv) ? dv : default);
}