godot/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/SceneTreeExtensions.cs
Ignacio Roldán Etcheverry 50b603c7dc C#: Begin move to .NET Core
We're targeting .NET 5 for now to make development easier while
.NET 6 is not yet released.

TEMPORARY REGRESSIONS
---------------------

Assembly unloading is not implemented yet. As such, many Godot
resources are leaked at exit. This will be re-implemented later
together with assembly hot-reloading.
2021-09-22 08:27:12 +02:00

65 lines
2.2 KiB
C#

using System.Reflection;
using System.Runtime.CompilerServices;
using Godot.Collections;
using Godot.NativeInterop;
namespace Godot
{
public partial class SceneTree
{
public unsafe Array<T> GetNodesInGroup<T>(StringName group) where T : class
{
var array = GetNodesInGroup(group);
if (array.Count == 0)
return new Array<T>(array);
var typeOfT = typeof(T);
bool nativeBase = InternalIsClassNativeBase(typeOfT);
if (nativeBase)
{
// Native type
var field = typeOfT.GetField("NativeName",
BindingFlags.DeclaredOnly | BindingFlags.Static |
BindingFlags.Public | BindingFlags.NonPublic);
var nativeName = (StringName)field!.GetValue(null);
godot_string_name nativeNameAux = nativeName.NativeValue;
godot_array inputAux = array.NativeValue;
godot_array filteredArray;
NativeFuncs.godotsharp_array_filter_godot_objects_by_native(
&nativeNameAux, &inputAux, &filteredArray);
return Array<T>.CreateTakingOwnershipOfDisposableValue(filteredArray);
}
else
{
// Custom derived type
godot_array inputAux = array.NativeValue;
godot_array filteredArray;
NativeFuncs.godotsharp_array_filter_godot_objects_by_non_native(&inputAux, &filteredArray);
var filteredArrayWrapped = Array.CreateTakingOwnershipOfDisposableValue(filteredArray);
// Re-use first array as its size is the same or greater than the filtered one
var resWrapped = new Array<T>(array);
int j = 0;
for (int i = 0; i < filteredArrayWrapped.Count; i++)
{
if (filteredArrayWrapped[i] is T t)
{
resWrapped[j] = t;
j++;
}
}
// Remove trailing elements, since this was re-used
resWrapped.Resize(j);
return resWrapped;
}
}
}
}