com.wallstop-studios.unity-helpers 2.0.0-rc57 → 2.0.0-rc58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.config/dotnet-tools.json +9 -9
- package/.editorconfig +184 -184
- package/.gitattributes +63 -63
- package/.github/workflows/npm-publish.yml +66 -66
- package/.pre-commit-config.yaml +21 -21
- package/Editor/AnimationCopier.cs +181 -181
- package/Editor/AnimationCopier.cs.meta +2 -2
- package/Editor/AnimationCreator.cs +253 -253
- package/Editor/AnimationCreator.cs.meta +11 -11
- package/Editor/AnimationEventEditor.cs +887 -887
- package/Editor/AnimatorControllerCopier.cs +162 -162
- package/Editor/AnimatorControllerCopier.cs.meta +2 -2
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +34 -34
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs.meta +2 -2
- package/Editor/CustomEditors.meta +2 -2
- package/Editor/FitTextureSizeWizard.cs +147 -147
- package/Editor/FitTextureSizeWizard.cs.meta +2 -2
- package/Editor/PrefabCheckWizard.cs +170 -170
- package/Editor/PrefabCheckWizard.cs.meta +11 -11
- package/Editor/SpriteSettingsApplier.cs +272 -272
- package/Editor/SpriteSettingsApplier.cs.meta +2 -2
- package/Editor/StringInListeDrawer.cs +56 -56
- package/Editor/TextureResizerWizard.cs +181 -181
- package/Editor/TextureResizerWizard.cs.meta +2 -2
- package/Editor/TextureSettingsApplier.cs +178 -178
- package/Editor/TextureSettingsApplier.cs.meta +2 -2
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs +26 -26
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs.meta +11 -11
- package/Editor/Utils/EditorUtilities.cs +22 -22
- package/Editor/Utils/EditorUtilities.cs.meta +11 -11
- package/Editor/Utils.meta +8 -8
- package/Editor/WShowIfPropertyDrawer.cs +63 -63
- package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef +17 -17
- package/Editor/WallstopStudios.UnityHelpers.Editor.asmdef.meta +7 -7
- package/LICENSE +21 -21
- package/LICENSE.md +6 -6
- package/LICENSE.meta +7 -7
- package/README.md +177 -177
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.dll.meta +33 -33
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.xml +223 -223
- package/Runtime/Binaries/Microsoft.Bcl.AsyncInterfaces.xml.meta +7 -7
- package/Runtime/Binaries/System.Text.Encodings.Web.dll.meta +33 -33
- package/Runtime/Binaries/System.Text.Encodings.Web.xml +935 -935
- package/Runtime/Binaries/System.Text.Encodings.Web.xml.meta +7 -7
- package/Runtime/Binaries/System.Text.Json.dll.meta +33 -33
- package/Runtime/Binaries/System.Text.Json.xml +4829 -4829
- package/Runtime/Binaries/System.Text.Json.xml.meta +7 -7
- package/Runtime/Binaries.meta +8 -8
- package/Runtime/Core/Attributes/AnimationEventAttribute.cs +131 -131
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs +209 -209
- package/Runtime/Core/Attributes/DxReadOnlyAttribute.cs +6 -6
- package/Runtime/Core/Attributes/KSerializableAttribute.cs +19 -19
- package/Runtime/Core/Attributes/NotNullAttribute.cs +32 -32
- package/Runtime/Core/Attributes/ParentComponent.cs +185 -185
- package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +14 -14
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +117 -117
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs +101 -101
- package/Runtime/Core/Attributes/ValidateAssignmentAttribute.cs.meta +11 -11
- package/Runtime/Core/Attributes/WShowIfAttribute.cs +16 -16
- package/Runtime/Core/Attributes.meta +8 -8
- package/Runtime/Core/DataStructure/Adapters/FastVector2Int.cs +92 -92
- package/Runtime/Core/DataStructure/Adapters/FastVector3Int.cs +185 -185
- package/Runtime/Core/DataStructure/Adapters/KGuid.cs +305 -305
- package/Runtime/Core/DataStructure/Adapters/KVector2.cs +80 -80
- package/Runtime/Core/DataStructure/Circle.cs +50 -50
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +153 -153
- package/Runtime/Core/DataStructure/ISpatialTree.cs +60 -60
- package/Runtime/Core/DataStructure/ISpatialTree.cs.meta +11 -11
- package/Runtime/Core/DataStructure/KDTree.cs +292 -292
- package/Runtime/Core/DataStructure/KDTree.cs.meta +11 -11
- package/Runtime/Core/DataStructure/QuadTree.cs +287 -287
- package/Runtime/Core/DataStructure/RTree.cs +346 -346
- package/Runtime/Core/DataStructure/RTree.cs.meta +11 -11
- package/Runtime/Core/DataStructure/StringWrapper.cs +91 -91
- package/Runtime/Core/DataStructure/TimedCache.cs +66 -66
- package/Runtime/Core/Extension/AnimatorExtensions.cs +25 -25
- package/Runtime/Core/Extension/AsyncOperationExtensions.cs +110 -110
- package/Runtime/Core/Extension/CircleExtensions.cs +25 -25
- package/Runtime/Core/Extension/ColorExtensions.cs +629 -629
- package/Runtime/Core/Extension/DictionaryExtensions.cs +279 -279
- package/Runtime/Core/Extension/DirectionExtensions.cs +213 -213
- package/Runtime/Core/Extension/EnumExtensions.cs +37 -37
- package/Runtime/Core/Extension/EnumExtensions.cs.meta +2 -2
- package/Runtime/Core/Extension/HashSetExtensions.cs +12 -12
- package/Runtime/Core/Extension/IEnumerableExtensions.cs +122 -122
- package/Runtime/Core/Extension/IListExtensions.cs +106 -106
- package/Runtime/Core/Extension/LoggingExtensions.cs +258 -258
- package/Runtime/Core/Extension/RandomExtensions.cs +109 -109
- package/Runtime/Core/Extension/SerializedPropertyExtensions.cs +157 -157
- package/Runtime/Core/Extension/StringExtensions.cs +151 -151
- package/Runtime/Core/Extension/UnityExtensions.cs +1608 -1608
- package/Runtime/Core/Helper/ArrayConverter.cs +39 -39
- package/Runtime/Core/Helper/ArrayConverter.cs.meta +2 -2
- package/Runtime/Core/Helper/AssignUtilities.cs +14 -14
- package/Runtime/Core/Helper/AssignUtilities.cs.meta +11 -11
- package/Runtime/Core/Helper/Enumerables.cs +17 -17
- package/Runtime/Core/Helper/FormattingHelpers.cs +32 -32
- package/Runtime/Core/Helper/Geometry.cs +43 -43
- package/Runtime/Core/Helper/Helpers.cs +722 -722
- package/Runtime/Core/Helper/Helpers.cs.meta +11 -11
- package/Runtime/Core/Helper/IterationHelpers.cs +32 -32
- package/Runtime/Core/Helper/IterationHelpers.cs.meta +11 -11
- package/Runtime/Core/Helper/LifetimeHelpers.cs +13 -13
- package/Runtime/Core/Helper/Objects.cs +769 -769
- package/Runtime/Core/Helper/Partials/LogHelpers.cs +13 -13
- package/Runtime/Core/Helper/Partials/LogHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials/MathHelpers.cs +30 -30
- package/Runtime/Core/Helper/Partials/MathHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +388 -388
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials/TransformHelpers.cs +189 -189
- package/Runtime/Core/Helper/Partials/TransformHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/Partials.meta +2 -2
- package/Runtime/Core/Helper/ReflectionHelpers.cs +452 -452
- package/Runtime/Core/Helper/ReflectionHelpers.cs.meta +2 -2
- package/Runtime/Core/Helper/SceneHelper.cs +209 -213
- package/Runtime/Core/Helper/SpriteHelpers.cs +41 -41
- package/Runtime/Core/Helper/SpriteHelpers.cs.meta +11 -11
- package/Runtime/Core/Helper/StringInList.cs +31 -31
- package/Runtime/Core/Helper/StringInList.cs.meta +11 -11
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +82 -82
- package/Runtime/Core/Helper/WallMath.cs +166 -166
- package/Runtime/Core/Math/Line.cs +55 -55
- package/Runtime/Core/Math/Parabola.cs +47 -47
- package/Runtime/Core/Math/PointPolygonCheck.cs +36 -36
- package/Runtime/Core/Math/PointPolygonCheck.cs.meta +11 -11
- package/Runtime/Core/Math/Range.cs +92 -92
- package/Runtime/Core/Math/XXHash.cs +310 -310
- package/Runtime/Core/Math/XXHash.cs.meta +11 -11
- package/Runtime/Core/Model/Direction.cs +43 -43
- package/Runtime/Core/OneOf/FastOneOf.cs +152 -152
- package/Runtime/Core/OneOf/None.cs +4 -4
- package/Runtime/Core/Random/AbstractRandom.cs +585 -585
- package/Runtime/Core/Random/DotNetRandom.cs +54 -54
- package/Runtime/Core/Random/DotNetRandom.cs.meta +2 -2
- package/Runtime/Core/Random/IRandom.cs +161 -161
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs +49 -49
- package/Runtime/Core/Random/NativePcgRandom.cs +97 -97
- package/Runtime/Core/Random/PRNG.cs +7 -7
- package/Runtime/Core/Random/PRNG.cs.meta +2 -2
- package/Runtime/Core/Random/PcgRandom.cs +149 -149
- package/Runtime/Core/Random/PerlinNoise.cs +369 -369
- package/Runtime/Core/Random/PerlinNoise.cs.meta +2 -2
- package/Runtime/Core/Random/RandomState.cs +131 -131
- package/Runtime/Core/Random/RandomUtilities.cs +26 -26
- package/Runtime/Core/Random/RandomUtilities.cs.meta +11 -11
- package/Runtime/Core/Random/RomuDuo.cs +116 -116
- package/Runtime/Core/Random/RomuDuo.cs.meta +2 -2
- package/Runtime/Core/Random/SplitMix64.cs +94 -94
- package/Runtime/Core/Random/SplitMix64.cs.meta +2 -2
- package/Runtime/Core/Random/SquirrelRandom.cs +84 -84
- package/Runtime/Core/Random/SystemRandom.cs +162 -162
- package/Runtime/Core/Random/ThreadLocalRandom.cs +12 -12
- package/Runtime/Core/Random/UnityRandom.cs +57 -57
- package/Runtime/Core/Random/UnityRandom.cs.meta +11 -11
- package/Runtime/Core/Random/WyRandom.cs +121 -121
- package/Runtime/Core/Random/WyRandom.cs.meta +2 -2
- package/Runtime/Core/Random/XorShiftRandom.cs +52 -52
- package/Runtime/Core/Random/XorShiftRandom.cs.meta +11 -11
- package/Runtime/Core/Random/XorShiroRandom.cs +119 -119
- package/Runtime/Core/Random/XorShiroRandom.cs.meta +2 -2
- package/Runtime/Core/Serialization/JsonConverters/ColorConverter.cs +88 -88
- package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +37 -37
- package/Runtime/Core/Serialization/JsonConverters/Matrix4x4Converter.cs +218 -218
- package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +28 -28
- package/Runtime/Core/Serialization/JsonConverters/Vector2Converter.cs +74 -74
- package/Runtime/Core/Serialization/JsonConverters/Vector3Converter.cs +81 -81
- package/Runtime/Core/Serialization/JsonConverters/Vector4Converter.cs +88 -88
- package/Runtime/Core/Serialization/Serializer.cs +195 -195
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +113 -113
- package/Runtime/Protobuf-Net/System.Buffers.dll.meta +33 -33
- package/Runtime/Protobuf-Net/System.Collections.Immutable.dll.meta +33 -33
- package/Runtime/Protobuf-Net/System.Collections.Immutable.xml +5379 -5379
- package/Runtime/Protobuf-Net/System.Collections.Immutable.xml.meta +7 -7
- package/Runtime/Protobuf-Net/System.Numerics.Vectors.dll.meta +33 -33
- package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.dll.meta +33 -33
- package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.xml +290 -290
- package/Runtime/Protobuf-Net/System.Runtime.CompilerServices.Unsafe.xml.meta +7 -7
- package/Runtime/Protobuf-Net/protobuf-net.Core.dll.meta +33 -33
- package/Runtime/Protobuf-Net/protobuf-net.dll.meta +33 -33
- package/Runtime/UI/LayeredImage.cs +364 -364
- package/Runtime/UI/LayeredImage.cs.meta +2 -2
- package/Runtime/UI.meta +2 -2
- package/Runtime/Utils/AnimationEventEqualityComparer.cs +161 -161
- package/Runtime/Utils/AnimatorEnumStateMachine.cs +88 -88
- package/Runtime/Utils/Buffers.cs +33 -33
- package/Runtime/Utils/CenterPointOffset.cs +30 -30
- package/Runtime/Utils/CenterPointOffset.cs.meta +2 -2
- package/Runtime/Utils/CircleLineRenderer.cs +134 -134
- package/Runtime/Utils/CoroutineHandler.cs +4 -4
- package/Runtime/Utils/CoroutineHandler.cs.meta +2 -2
- package/Runtime/Utils/DeferredDisposalResult.cs +23 -23
- package/Runtime/Utils/MatchColliderToSprite.cs +94 -94
- package/Runtime/Utils/MatchColliderToSprite.cs.meta +2 -2
- package/Runtime/Utils/Oscillator.cs +27 -27
- package/Runtime/Utils/RuntimeSingleton.cs +69 -69
- package/Runtime/Utils/RuntimeSingleton.cs.meta +11 -11
- package/Runtime/Utils/SetTextureImportData.cs +69 -69
- package/Runtime/Utils/SpriteRendererMetadata.cs +374 -374
- package/Runtime/Utils/SpriteRendererMetadata.cs.meta +2 -2
- package/Runtime/Utils/SpriteRendererSyncer.cs +100 -100
- package/Runtime/Utils/SpriteRendererSyncer.cs.meta +2 -2
- package/Runtime/Utils/TextureScale.cs +179 -179
- package/Runtime/Utils/TextureScale.cs.meta +2 -2
- package/Runtime/WallstopStudios.UnityHelpers.asmdef +13 -13
- package/Tests/Runtime/Attributes/ChildComponentTests.cs +81 -81
- package/Tests/Runtime/Attributes/Components/ExpectChildSpriteRenderers.cs +28 -28
- package/Tests/Runtime/Attributes/Components/ExpectParentSpriteRenderers.cs +28 -28
- package/Tests/Runtime/Attributes/ParentComponentTests.cs +68 -68
- package/Tests/Runtime/Components/RelationalComponentTesterComplex.cs +34 -34
- package/Tests/Runtime/Components/RelationalComponentTesterComplex.cs.meta +2 -2
- package/Tests/Runtime/Components/RelationalComponentsTesterSimple.cs +40 -40
- package/Tests/Runtime/Components.meta +2 -2
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs +14 -14
- package/Tests/Runtime/DataStructures/BalancedKDTreeTests.cs.meta +11 -11
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +324 -324
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs +14 -14
- package/Tests/Runtime/DataStructures/QuadTreeTests.cs.meta +11 -11
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +130 -130
- package/Tests/Runtime/DataStructures/SpatialTreeTests.cs.meta +11 -11
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs +14 -14
- package/Tests/Runtime/DataStructures/UnbalancedKDTreeTests.cs.meta +11 -11
- package/Tests/Runtime/DataStructures.meta +8 -8
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs +439 -439
- package/Tests/Runtime/Extensions/DictionaryExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs +128 -128
- package/Tests/Runtime/Extensions/EnumExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +104 -104
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs +27 -27
- package/Tests/Runtime/Extensions/RandomExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions/StringExtensionTests.cs +31 -31
- package/Tests/Runtime/Extensions/StringExtensionTests.cs.meta +2 -2
- package/Tests/Runtime/Extensions.meta +2 -2
- package/Tests/Runtime/Helper/ArrayConverterTests.cs +19 -19
- package/Tests/Runtime/Helper/ArrayConverterTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/FormattingHelperTests.cs +129 -129
- package/Tests/Runtime/Helper/FormattingHelperTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +402 -402
- package/Tests/Runtime/Helper/ObjectHelperTests.cs.meta +2 -2
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs +536 -536
- package/Tests/Runtime/Helper/SceneHelperTests.cs +94 -94
- package/Tests/Runtime/Helper/WallMathTests.cs +233 -233
- package/Tests/Runtime/Helper/WallMathTests.cs.meta +2 -2
- package/Tests/Runtime/Helper.meta +2 -2
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs +14 -14
- package/Tests/Runtime/Performance/KDTreePerformanceTests.cs.meta +11 -11
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs +14 -14
- package/Tests/Runtime/Performance/QuadTreePerformanceTests.cs.meta +11 -11
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +157 -157
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs.meta +11 -11
- package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs +61 -61
- package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs.meta +2 -2
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +154 -154
- package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs.meta +11 -11
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs +14 -14
- package/Tests/Runtime/Performance/UnbalancedKDTreeTests.cs.meta +11 -11
- package/Tests/Runtime/Performance.meta +8 -8
- package/Tests/Runtime/Random/DotNetRandomTests.cs +9 -9
- package/Tests/Runtime/Random/DotNetRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/LinearCongruentialGeneratorTests.cs +12 -12
- package/Tests/Runtime/Random/PcgRandomTests.cs +9 -9
- package/Tests/Runtime/Random/PcgRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/RandomTestBase.cs +787 -787
- package/Tests/Runtime/Random/RandomTestBase.cs.meta +11 -11
- package/Tests/Runtime/Random/RomuDuoRandomTests.cs +9 -9
- package/Tests/Runtime/Random/RomuDuoRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/SplitMix64RandomTests.cs +9 -9
- package/Tests/Runtime/Random/SplitMix64RandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/SquirrelRandomTests.cs +14 -14
- package/Tests/Runtime/Random/SquirrelRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/SystemRandomTests.cs +10 -10
- package/Tests/Runtime/Random/SystemRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/UnityRandomTests.cs +9 -9
- package/Tests/Runtime/Random/UnityRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/WyRandomTests.cs +9 -9
- package/Tests/Runtime/Random/WyRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random/XorShiftRandomTests.cs +9 -9
- package/Tests/Runtime/Random/XorShiftRandomTests.cs.meta +11 -11
- package/Tests/Runtime/Random/XorShiroRandomTests.cs +9 -9
- package/Tests/Runtime/Random/XorShiroRandomTests.cs.meta +2 -2
- package/Tests/Runtime/Random.meta +8 -8
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +156 -156
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs.meta +2 -2
- package/Tests/Runtime/Serialization.meta +2 -2
- package/Tests/Runtime/Utils/SpriteRendererMetadataTests.cs +399 -399
- package/Tests/Runtime/Utils/SpriteRendererMetadataTests.cs.meta +2 -2
- package/Tests/Runtime/Utils.meta +2 -2
- package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef +22 -22
- package/Tests/Runtime/WallstopStudios.UnityHelpers.Tests.Runtime.asmdef.meta +7 -7
- package/Tests/Runtime.meta +8 -8
- package/package.json +38 -38
|
@@ -1,452 +1,452 @@
|
|
|
1
|
-
namespace UnityHelpers.Core.Helper
|
|
2
|
-
{
|
|
3
|
-
using System;
|
|
4
|
-
using System.Collections;
|
|
5
|
-
using System.Collections.Generic;
|
|
6
|
-
using System.Reflection;
|
|
7
|
-
using System.Reflection.Emit;
|
|
8
|
-
using System.Runtime.CompilerServices;
|
|
9
|
-
using Extension;
|
|
10
|
-
|
|
11
|
-
public delegate void FieldSetter<TInstance, in TValue>(ref TInstance instance, TValue value);
|
|
12
|
-
|
|
13
|
-
public static class ReflectionHelpers
|
|
14
|
-
{
|
|
15
|
-
private static readonly Dictionary<Type, Func<int, Array>> ArrayCreators = new();
|
|
16
|
-
private static readonly Dictionary<Type, Func<IList>> ListCreators = new();
|
|
17
|
-
private static readonly Dictionary<Type, Func<int, IList>> ListWithCapacityCreators = new();
|
|
18
|
-
|
|
19
|
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
20
|
-
public static Array CreateArray(Type type, int length)
|
|
21
|
-
{
|
|
22
|
-
return ArrayCreators
|
|
23
|
-
// ReSharper disable once ConvertClosureToMethodGroup
|
|
24
|
-
.GetOrAdd(type, elementType => GetArrayCreator(elementType))
|
|
25
|
-
.Invoke(length);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
29
|
-
public static IList CreateList(Type elementType, int length)
|
|
30
|
-
{
|
|
31
|
-
return ListWithCapacityCreators
|
|
32
|
-
// ReSharper disable once ConvertClosureToMethodGroup
|
|
33
|
-
.GetOrAdd(elementType, type => GetListWithCapacityCreator(type))
|
|
34
|
-
.Invoke(length);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
38
|
-
public static IList CreateList(Type elementType)
|
|
39
|
-
{
|
|
40
|
-
// ReSharper disable once ConvertClosureToMethodGroup
|
|
41
|
-
return ListCreators.GetOrAdd(elementType, type => GetListCreator(type)).Invoke();
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public static Func<object, object> GetFieldGetter(FieldInfo field)
|
|
45
|
-
{
|
|
46
|
-
#if WEB_GL
|
|
47
|
-
return field.GetValue;
|
|
48
|
-
#else
|
|
49
|
-
DynamicMethod dynamicMethod = new(
|
|
50
|
-
$"Get{field.DeclaringType.Name}{field.Name}",
|
|
51
|
-
typeof(object),
|
|
52
|
-
new[] { typeof(object) },
|
|
53
|
-
field.DeclaringType,
|
|
54
|
-
true
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
58
|
-
il.Emit(OpCodes.Ldarg_0);
|
|
59
|
-
il.Emit(
|
|
60
|
-
field.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
|
|
61
|
-
field.DeclaringType
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
il.Emit(OpCodes.Ldfld, field);
|
|
65
|
-
|
|
66
|
-
// If the field's type is a value type, box it.
|
|
67
|
-
if (field.FieldType.IsValueType)
|
|
68
|
-
{
|
|
69
|
-
il.Emit(OpCodes.Box, field.FieldType);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
il.Emit(OpCodes.Ret);
|
|
73
|
-
|
|
74
|
-
return (Func<object, object>)dynamicMethod.CreateDelegate(typeof(Func<object, object>));
|
|
75
|
-
#endif
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
public static Func<object> GetStaticFieldGetter(FieldInfo field)
|
|
79
|
-
{
|
|
80
|
-
if (!field.IsStatic)
|
|
81
|
-
{
|
|
82
|
-
throw new ArgumentException(nameof(field));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
#if WEB_GL
|
|
86
|
-
return () => field.GetValue(null);
|
|
87
|
-
#else
|
|
88
|
-
DynamicMethod dynamicMethod = new(
|
|
89
|
-
$"Get{field.DeclaringType.Name}{field.Name}",
|
|
90
|
-
typeof(object),
|
|
91
|
-
Type.EmptyTypes, // No parameters for static fields
|
|
92
|
-
field.DeclaringType,
|
|
93
|
-
true
|
|
94
|
-
);
|
|
95
|
-
|
|
96
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
97
|
-
|
|
98
|
-
// Load the static field
|
|
99
|
-
il.Emit(OpCodes.Ldsfld, field);
|
|
100
|
-
|
|
101
|
-
// If the field's type is a value type, box it.
|
|
102
|
-
if (field.FieldType.IsValueType)
|
|
103
|
-
{
|
|
104
|
-
il.Emit(OpCodes.Box, field.FieldType);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
il.Emit(OpCodes.Ret);
|
|
108
|
-
|
|
109
|
-
return (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));
|
|
110
|
-
#endif
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
public static Func<TInstance, TValue> GetFieldGetter<TInstance, TValue>(FieldInfo field)
|
|
114
|
-
{
|
|
115
|
-
#if WEB_GL
|
|
116
|
-
return Getter;
|
|
117
|
-
TValue Getter(TInstance instance)
|
|
118
|
-
{
|
|
119
|
-
return (TValue)field.GetValue(instance);
|
|
120
|
-
}
|
|
121
|
-
#else
|
|
122
|
-
DynamicMethod dynamicMethod = new(
|
|
123
|
-
$"GetGeneric{field.DeclaringType.Name}{field.Name}",
|
|
124
|
-
typeof(TValue),
|
|
125
|
-
new[] { typeof(TInstance) },
|
|
126
|
-
field.DeclaringType,
|
|
127
|
-
true
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
131
|
-
|
|
132
|
-
if (!field.IsStatic)
|
|
133
|
-
{
|
|
134
|
-
if (typeof(TInstance).IsValueType)
|
|
135
|
-
{
|
|
136
|
-
il.Emit(OpCodes.Ldarga_S, 0);
|
|
137
|
-
}
|
|
138
|
-
else
|
|
139
|
-
{
|
|
140
|
-
il.Emit(OpCodes.Ldarg_0);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (field.DeclaringType != typeof(TInstance))
|
|
144
|
-
{
|
|
145
|
-
il.Emit(
|
|
146
|
-
field.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
|
|
147
|
-
field.DeclaringType
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
il.Emit(OpCodes.Ldfld, field);
|
|
152
|
-
}
|
|
153
|
-
else
|
|
154
|
-
{
|
|
155
|
-
il.Emit(OpCodes.Ldsfld, field);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (field.FieldType.IsValueType)
|
|
159
|
-
{
|
|
160
|
-
if (!typeof(TValue).IsValueType)
|
|
161
|
-
{
|
|
162
|
-
il.Emit(OpCodes.Box, field.FieldType);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
else
|
|
166
|
-
{
|
|
167
|
-
if (typeof(TValue).IsValueType)
|
|
168
|
-
{
|
|
169
|
-
il.Emit(OpCodes.Unbox_Any, typeof(TValue));
|
|
170
|
-
}
|
|
171
|
-
else if (typeof(TValue) != field.FieldType)
|
|
172
|
-
{
|
|
173
|
-
il.Emit(OpCodes.Castclass, typeof(TValue));
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
il.Emit(OpCodes.Ret);
|
|
178
|
-
return (Func<TInstance, TValue>)
|
|
179
|
-
dynamicMethod.CreateDelegate(typeof(Func<TInstance, TValue>));
|
|
180
|
-
#endif
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
public static Func<TValue> GetStaticFieldGetter<TValue>(FieldInfo field)
|
|
184
|
-
{
|
|
185
|
-
if (!field.IsStatic)
|
|
186
|
-
{
|
|
187
|
-
throw new ArgumentException(nameof(field));
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
#if WEB_GL
|
|
191
|
-
return Getter;
|
|
192
|
-
TValue Getter()
|
|
193
|
-
{
|
|
194
|
-
return (TValue)field.GetValue(null);
|
|
195
|
-
}
|
|
196
|
-
#else
|
|
197
|
-
DynamicMethod dynamicMethod = new(
|
|
198
|
-
$"GetGenericStatic{field.DeclaringType.Name}{field.Name}",
|
|
199
|
-
typeof(TValue),
|
|
200
|
-
Type.EmptyTypes, // no parameters needed for static fields
|
|
201
|
-
field.DeclaringType,
|
|
202
|
-
true
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
206
|
-
|
|
207
|
-
// Load the static field.
|
|
208
|
-
il.Emit(OpCodes.Ldsfld, field);
|
|
209
|
-
|
|
210
|
-
// Handle conversion from the field type to TValue.
|
|
211
|
-
if (field.FieldType.IsValueType)
|
|
212
|
-
{
|
|
213
|
-
if (!typeof(TValue).IsValueType)
|
|
214
|
-
{
|
|
215
|
-
il.Emit(OpCodes.Box, field.FieldType);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
else
|
|
219
|
-
{
|
|
220
|
-
if (typeof(TValue).IsValueType)
|
|
221
|
-
{
|
|
222
|
-
il.Emit(OpCodes.Unbox_Any, typeof(TValue));
|
|
223
|
-
}
|
|
224
|
-
else if (typeof(TValue) != field.FieldType)
|
|
225
|
-
{
|
|
226
|
-
il.Emit(OpCodes.Castclass, typeof(TValue));
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
il.Emit(OpCodes.Ret);
|
|
231
|
-
|
|
232
|
-
return (Func<TValue>)dynamicMethod.CreateDelegate(typeof(Func<TValue>));
|
|
233
|
-
#endif
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
public static FieldSetter<TInstance, TValue> GetFieldSetter<TInstance, TValue>(
|
|
237
|
-
FieldInfo field
|
|
238
|
-
)
|
|
239
|
-
{
|
|
240
|
-
#if WEB_GL
|
|
241
|
-
return Setter;
|
|
242
|
-
void Setter(ref TInstance instance, TValue newValue)
|
|
243
|
-
{
|
|
244
|
-
object value = instance;
|
|
245
|
-
field.SetValue(value, newValue);
|
|
246
|
-
instance = (TInstance)value;
|
|
247
|
-
}
|
|
248
|
-
#else
|
|
249
|
-
Type instanceType = field.DeclaringType;
|
|
250
|
-
Type valueType = field.FieldType;
|
|
251
|
-
|
|
252
|
-
DynamicMethod dynamicMethod = new(
|
|
253
|
-
$"SetFieldGeneric{field.DeclaringType.Name}{field.Name}",
|
|
254
|
-
MethodAttributes.Public | MethodAttributes.Static,
|
|
255
|
-
CallingConventions.Standard,
|
|
256
|
-
typeof(void),
|
|
257
|
-
new[] { instanceType.MakeByRefType(), valueType },
|
|
258
|
-
field.Module,
|
|
259
|
-
true
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
263
|
-
il.Emit(OpCodes.Ldarg_0);
|
|
264
|
-
if (!instanceType.IsValueType)
|
|
265
|
-
{
|
|
266
|
-
il.Emit(OpCodes.Ldind_Ref);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
il.Emit(OpCodes.Ldarg_1);
|
|
270
|
-
il.Emit(OpCodes.Stfld, field);
|
|
271
|
-
il.Emit(OpCodes.Ret);
|
|
272
|
-
|
|
273
|
-
Type delegateType = typeof(FieldSetter<,>).MakeGenericType(instanceType, valueType);
|
|
274
|
-
return (FieldSetter<TInstance, TValue>)dynamicMethod.CreateDelegate(delegateType);
|
|
275
|
-
#endif
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
public static Action<TValue> GetStaticFieldSetter<TValue>(FieldInfo field)
|
|
279
|
-
{
|
|
280
|
-
if (!field.IsStatic)
|
|
281
|
-
{
|
|
282
|
-
throw new ArgumentException(nameof(field));
|
|
283
|
-
}
|
|
284
|
-
#if WEB_GL
|
|
285
|
-
return Setter;
|
|
286
|
-
void Setter(TValue newValue)
|
|
287
|
-
{
|
|
288
|
-
field.SetValue(null, newValue);
|
|
289
|
-
}
|
|
290
|
-
#else
|
|
291
|
-
DynamicMethod dynamicMethod = new(
|
|
292
|
-
$"SetFieldGenericStatic{field.DeclaringType.Name}{field.Name}",
|
|
293
|
-
typeof(void),
|
|
294
|
-
new[] { typeof(TValue) },
|
|
295
|
-
field.Module,
|
|
296
|
-
true
|
|
297
|
-
);
|
|
298
|
-
|
|
299
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
300
|
-
il.Emit(OpCodes.Ldarg_0);
|
|
301
|
-
il.Emit(OpCodes.Stsfld, field);
|
|
302
|
-
il.Emit(OpCodes.Ret);
|
|
303
|
-
|
|
304
|
-
return (Action<TValue>)dynamicMethod.CreateDelegate(typeof(Action<TValue>));
|
|
305
|
-
#endif
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
public static Action<object, object> GetFieldSetter(FieldInfo field)
|
|
309
|
-
{
|
|
310
|
-
#if WEB_GL
|
|
311
|
-
return field.SetValue;
|
|
312
|
-
#else
|
|
313
|
-
DynamicMethod dynamicMethod = new(
|
|
314
|
-
$"SetField{field.DeclaringType.Name}{field.Name}",
|
|
315
|
-
null,
|
|
316
|
-
new[] { typeof(object), typeof(object) },
|
|
317
|
-
field.DeclaringType.Module,
|
|
318
|
-
true
|
|
319
|
-
);
|
|
320
|
-
|
|
321
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
322
|
-
|
|
323
|
-
il.Emit(OpCodes.Ldarg_0);
|
|
324
|
-
il.Emit(
|
|
325
|
-
field.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
|
|
326
|
-
field.DeclaringType
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
il.Emit(OpCodes.Ldarg_1);
|
|
330
|
-
il.Emit(
|
|
331
|
-
field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass,
|
|
332
|
-
field.FieldType
|
|
333
|
-
);
|
|
334
|
-
il.Emit(OpCodes.Stfld, field);
|
|
335
|
-
il.Emit(OpCodes.Ret);
|
|
336
|
-
return (Action<object, object>)
|
|
337
|
-
dynamicMethod.CreateDelegate(typeof(Action<object, object>));
|
|
338
|
-
#endif
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
public static Action<object> GetStaticFieldSetter(FieldInfo field)
|
|
342
|
-
{
|
|
343
|
-
if (!field.IsStatic)
|
|
344
|
-
{
|
|
345
|
-
throw new ArgumentException(nameof(field));
|
|
346
|
-
}
|
|
347
|
-
#if WEB_GL
|
|
348
|
-
return value => field.SetValue(null, value);
|
|
349
|
-
#else
|
|
350
|
-
DynamicMethod dynamicMethod = new(
|
|
351
|
-
$"SetFieldStatic{field.DeclaringType.Name}{field.Name}",
|
|
352
|
-
null,
|
|
353
|
-
new[] { typeof(object) },
|
|
354
|
-
field.DeclaringType.Module,
|
|
355
|
-
true
|
|
356
|
-
);
|
|
357
|
-
|
|
358
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
359
|
-
|
|
360
|
-
// Load the new value (argument 0)
|
|
361
|
-
il.Emit(OpCodes.Ldarg_0);
|
|
362
|
-
// Convert the object to the field's type (unbox or cast as needed)
|
|
363
|
-
il.Emit(
|
|
364
|
-
field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass,
|
|
365
|
-
field.FieldType
|
|
366
|
-
);
|
|
367
|
-
// Set the static field
|
|
368
|
-
il.Emit(OpCodes.Stsfld, field);
|
|
369
|
-
il.Emit(OpCodes.Ret);
|
|
370
|
-
|
|
371
|
-
return (Action<object>)dynamicMethod.CreateDelegate(typeof(Action<object>));
|
|
372
|
-
#endif
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
public static Func<int, Array> GetArrayCreator(Type elementType)
|
|
376
|
-
{
|
|
377
|
-
#if WEB_GL
|
|
378
|
-
return size => Array.CreateInstance(elementType, size);
|
|
379
|
-
#else
|
|
380
|
-
DynamicMethod dynamicMethod = new(
|
|
381
|
-
$"CreateArray{elementType.Name}",
|
|
382
|
-
typeof(Array), // Return type: Array
|
|
383
|
-
new[] { typeof(int) }, // Parameter: int (size)
|
|
384
|
-
true
|
|
385
|
-
);
|
|
386
|
-
|
|
387
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
388
|
-
il.Emit(OpCodes.Ldarg_0); // Load the array size
|
|
389
|
-
il.Emit(OpCodes.Newarr, elementType); // Create a new array of 'type'
|
|
390
|
-
il.Emit(OpCodes.Ret); // Return the array
|
|
391
|
-
return (Func<int, Array>)dynamicMethod.CreateDelegate(typeof(Func<int, Array>));
|
|
392
|
-
#endif
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
public static Func<IList> GetListCreator(Type elementType)
|
|
396
|
-
{
|
|
397
|
-
Type listType = typeof(List<>).MakeGenericType(elementType);
|
|
398
|
-
#if WEB_GL
|
|
399
|
-
return () => (IList)Activator.CreateInstance(listType);
|
|
400
|
-
#else
|
|
401
|
-
DynamicMethod dynamicMethod = new(
|
|
402
|
-
$"CreateList{listType.Name}",
|
|
403
|
-
typeof(IList), // Return type: IList
|
|
404
|
-
Type.EmptyTypes, // No parameters
|
|
405
|
-
true
|
|
406
|
-
);
|
|
407
|
-
|
|
408
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
409
|
-
ConstructorInfo constructor = listType.GetConstructor(Type.EmptyTypes);
|
|
410
|
-
if (constructor == null)
|
|
411
|
-
{
|
|
412
|
-
throw new ArgumentException(
|
|
413
|
-
$"Type {listType} does not have a parameterless constructor."
|
|
414
|
-
);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
il.Emit(OpCodes.Newobj, constructor); // Call List<T> constructor
|
|
418
|
-
il.Emit(OpCodes.Ret); // Return the instance
|
|
419
|
-
return (Func<IList>)dynamicMethod.CreateDelegate(typeof(Func<IList>));
|
|
420
|
-
#endif
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
public static Func<int, IList> GetListWithCapacityCreator(Type elementType)
|
|
424
|
-
{
|
|
425
|
-
Type listType = typeof(List<>).MakeGenericType(elementType);
|
|
426
|
-
#if WEB_GL
|
|
427
|
-
return _ => (IList)Activator.CreateInstance(listType);
|
|
428
|
-
#else
|
|
429
|
-
DynamicMethod dynamicMethod = new(
|
|
430
|
-
$"CreateListWithCapacity{listType.Name}",
|
|
431
|
-
typeof(IList), // Return type: IList
|
|
432
|
-
new[] { typeof(int) }, // Parameter: int (size)
|
|
433
|
-
true
|
|
434
|
-
);
|
|
435
|
-
|
|
436
|
-
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
437
|
-
ConstructorInfo constructor = listType.GetConstructor(new[] { typeof(int) });
|
|
438
|
-
if (constructor == null)
|
|
439
|
-
{
|
|
440
|
-
throw new ArgumentException(
|
|
441
|
-
$"Type {listType} does not have a constructor accepting an int."
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
il.Emit(OpCodes.Ldarg_0); // Load capacity argument
|
|
446
|
-
il.Emit(OpCodes.Newobj, constructor); // Call List<T>(int capacity) constructor
|
|
447
|
-
il.Emit(OpCodes.Ret); // Return the instance
|
|
448
|
-
return (Func<int, IList>)dynamicMethod.CreateDelegate(typeof(Func<int, IList>));
|
|
449
|
-
#endif
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
1
|
+
namespace UnityHelpers.Core.Helper
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections;
|
|
5
|
+
using System.Collections.Generic;
|
|
6
|
+
using System.Reflection;
|
|
7
|
+
using System.Reflection.Emit;
|
|
8
|
+
using System.Runtime.CompilerServices;
|
|
9
|
+
using Extension;
|
|
10
|
+
|
|
11
|
+
public delegate void FieldSetter<TInstance, in TValue>(ref TInstance instance, TValue value);
|
|
12
|
+
|
|
13
|
+
public static class ReflectionHelpers
|
|
14
|
+
{
|
|
15
|
+
private static readonly Dictionary<Type, Func<int, Array>> ArrayCreators = new();
|
|
16
|
+
private static readonly Dictionary<Type, Func<IList>> ListCreators = new();
|
|
17
|
+
private static readonly Dictionary<Type, Func<int, IList>> ListWithCapacityCreators = new();
|
|
18
|
+
|
|
19
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
20
|
+
public static Array CreateArray(Type type, int length)
|
|
21
|
+
{
|
|
22
|
+
return ArrayCreators
|
|
23
|
+
// ReSharper disable once ConvertClosureToMethodGroup
|
|
24
|
+
.GetOrAdd(type, elementType => GetArrayCreator(elementType))
|
|
25
|
+
.Invoke(length);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
29
|
+
public static IList CreateList(Type elementType, int length)
|
|
30
|
+
{
|
|
31
|
+
return ListWithCapacityCreators
|
|
32
|
+
// ReSharper disable once ConvertClosureToMethodGroup
|
|
33
|
+
.GetOrAdd(elementType, type => GetListWithCapacityCreator(type))
|
|
34
|
+
.Invoke(length);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
38
|
+
public static IList CreateList(Type elementType)
|
|
39
|
+
{
|
|
40
|
+
// ReSharper disable once ConvertClosureToMethodGroup
|
|
41
|
+
return ListCreators.GetOrAdd(elementType, type => GetListCreator(type)).Invoke();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public static Func<object, object> GetFieldGetter(FieldInfo field)
|
|
45
|
+
{
|
|
46
|
+
#if WEB_GL
|
|
47
|
+
return field.GetValue;
|
|
48
|
+
#else
|
|
49
|
+
DynamicMethod dynamicMethod = new(
|
|
50
|
+
$"Get{field.DeclaringType.Name}{field.Name}",
|
|
51
|
+
typeof(object),
|
|
52
|
+
new[] { typeof(object) },
|
|
53
|
+
field.DeclaringType,
|
|
54
|
+
true
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
58
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
59
|
+
il.Emit(
|
|
60
|
+
field.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
|
|
61
|
+
field.DeclaringType
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
il.Emit(OpCodes.Ldfld, field);
|
|
65
|
+
|
|
66
|
+
// If the field's type is a value type, box it.
|
|
67
|
+
if (field.FieldType.IsValueType)
|
|
68
|
+
{
|
|
69
|
+
il.Emit(OpCodes.Box, field.FieldType);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
il.Emit(OpCodes.Ret);
|
|
73
|
+
|
|
74
|
+
return (Func<object, object>)dynamicMethod.CreateDelegate(typeof(Func<object, object>));
|
|
75
|
+
#endif
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
public static Func<object> GetStaticFieldGetter(FieldInfo field)
|
|
79
|
+
{
|
|
80
|
+
if (!field.IsStatic)
|
|
81
|
+
{
|
|
82
|
+
throw new ArgumentException(nameof(field));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#if WEB_GL
|
|
86
|
+
return () => field.GetValue(null);
|
|
87
|
+
#else
|
|
88
|
+
DynamicMethod dynamicMethod = new(
|
|
89
|
+
$"Get{field.DeclaringType.Name}{field.Name}",
|
|
90
|
+
typeof(object),
|
|
91
|
+
Type.EmptyTypes, // No parameters for static fields
|
|
92
|
+
field.DeclaringType,
|
|
93
|
+
true
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
97
|
+
|
|
98
|
+
// Load the static field
|
|
99
|
+
il.Emit(OpCodes.Ldsfld, field);
|
|
100
|
+
|
|
101
|
+
// If the field's type is a value type, box it.
|
|
102
|
+
if (field.FieldType.IsValueType)
|
|
103
|
+
{
|
|
104
|
+
il.Emit(OpCodes.Box, field.FieldType);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
il.Emit(OpCodes.Ret);
|
|
108
|
+
|
|
109
|
+
return (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));
|
|
110
|
+
#endif
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public static Func<TInstance, TValue> GetFieldGetter<TInstance, TValue>(FieldInfo field)
|
|
114
|
+
{
|
|
115
|
+
#if WEB_GL
|
|
116
|
+
return Getter;
|
|
117
|
+
TValue Getter(TInstance instance)
|
|
118
|
+
{
|
|
119
|
+
return (TValue)field.GetValue(instance);
|
|
120
|
+
}
|
|
121
|
+
#else
|
|
122
|
+
DynamicMethod dynamicMethod = new(
|
|
123
|
+
$"GetGeneric{field.DeclaringType.Name}{field.Name}",
|
|
124
|
+
typeof(TValue),
|
|
125
|
+
new[] { typeof(TInstance) },
|
|
126
|
+
field.DeclaringType,
|
|
127
|
+
true
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
131
|
+
|
|
132
|
+
if (!field.IsStatic)
|
|
133
|
+
{
|
|
134
|
+
if (typeof(TInstance).IsValueType)
|
|
135
|
+
{
|
|
136
|
+
il.Emit(OpCodes.Ldarga_S, 0);
|
|
137
|
+
}
|
|
138
|
+
else
|
|
139
|
+
{
|
|
140
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (field.DeclaringType != typeof(TInstance))
|
|
144
|
+
{
|
|
145
|
+
il.Emit(
|
|
146
|
+
field.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
|
|
147
|
+
field.DeclaringType
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
il.Emit(OpCodes.Ldfld, field);
|
|
152
|
+
}
|
|
153
|
+
else
|
|
154
|
+
{
|
|
155
|
+
il.Emit(OpCodes.Ldsfld, field);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (field.FieldType.IsValueType)
|
|
159
|
+
{
|
|
160
|
+
if (!typeof(TValue).IsValueType)
|
|
161
|
+
{
|
|
162
|
+
il.Emit(OpCodes.Box, field.FieldType);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else
|
|
166
|
+
{
|
|
167
|
+
if (typeof(TValue).IsValueType)
|
|
168
|
+
{
|
|
169
|
+
il.Emit(OpCodes.Unbox_Any, typeof(TValue));
|
|
170
|
+
}
|
|
171
|
+
else if (typeof(TValue) != field.FieldType)
|
|
172
|
+
{
|
|
173
|
+
il.Emit(OpCodes.Castclass, typeof(TValue));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
il.Emit(OpCodes.Ret);
|
|
178
|
+
return (Func<TInstance, TValue>)
|
|
179
|
+
dynamicMethod.CreateDelegate(typeof(Func<TInstance, TValue>));
|
|
180
|
+
#endif
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public static Func<TValue> GetStaticFieldGetter<TValue>(FieldInfo field)
|
|
184
|
+
{
|
|
185
|
+
if (!field.IsStatic)
|
|
186
|
+
{
|
|
187
|
+
throw new ArgumentException(nameof(field));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
#if WEB_GL
|
|
191
|
+
return Getter;
|
|
192
|
+
TValue Getter()
|
|
193
|
+
{
|
|
194
|
+
return (TValue)field.GetValue(null);
|
|
195
|
+
}
|
|
196
|
+
#else
|
|
197
|
+
DynamicMethod dynamicMethod = new(
|
|
198
|
+
$"GetGenericStatic{field.DeclaringType.Name}{field.Name}",
|
|
199
|
+
typeof(TValue),
|
|
200
|
+
Type.EmptyTypes, // no parameters needed for static fields
|
|
201
|
+
field.DeclaringType,
|
|
202
|
+
true
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
206
|
+
|
|
207
|
+
// Load the static field.
|
|
208
|
+
il.Emit(OpCodes.Ldsfld, field);
|
|
209
|
+
|
|
210
|
+
// Handle conversion from the field type to TValue.
|
|
211
|
+
if (field.FieldType.IsValueType)
|
|
212
|
+
{
|
|
213
|
+
if (!typeof(TValue).IsValueType)
|
|
214
|
+
{
|
|
215
|
+
il.Emit(OpCodes.Box, field.FieldType);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else
|
|
219
|
+
{
|
|
220
|
+
if (typeof(TValue).IsValueType)
|
|
221
|
+
{
|
|
222
|
+
il.Emit(OpCodes.Unbox_Any, typeof(TValue));
|
|
223
|
+
}
|
|
224
|
+
else if (typeof(TValue) != field.FieldType)
|
|
225
|
+
{
|
|
226
|
+
il.Emit(OpCodes.Castclass, typeof(TValue));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
il.Emit(OpCodes.Ret);
|
|
231
|
+
|
|
232
|
+
return (Func<TValue>)dynamicMethod.CreateDelegate(typeof(Func<TValue>));
|
|
233
|
+
#endif
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public static FieldSetter<TInstance, TValue> GetFieldSetter<TInstance, TValue>(
|
|
237
|
+
FieldInfo field
|
|
238
|
+
)
|
|
239
|
+
{
|
|
240
|
+
#if WEB_GL
|
|
241
|
+
return Setter;
|
|
242
|
+
void Setter(ref TInstance instance, TValue newValue)
|
|
243
|
+
{
|
|
244
|
+
object value = instance;
|
|
245
|
+
field.SetValue(value, newValue);
|
|
246
|
+
instance = (TInstance)value;
|
|
247
|
+
}
|
|
248
|
+
#else
|
|
249
|
+
Type instanceType = field.DeclaringType;
|
|
250
|
+
Type valueType = field.FieldType;
|
|
251
|
+
|
|
252
|
+
DynamicMethod dynamicMethod = new(
|
|
253
|
+
$"SetFieldGeneric{field.DeclaringType.Name}{field.Name}",
|
|
254
|
+
MethodAttributes.Public | MethodAttributes.Static,
|
|
255
|
+
CallingConventions.Standard,
|
|
256
|
+
typeof(void),
|
|
257
|
+
new[] { instanceType.MakeByRefType(), valueType },
|
|
258
|
+
field.Module,
|
|
259
|
+
true
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
263
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
264
|
+
if (!instanceType.IsValueType)
|
|
265
|
+
{
|
|
266
|
+
il.Emit(OpCodes.Ldind_Ref);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
il.Emit(OpCodes.Ldarg_1);
|
|
270
|
+
il.Emit(OpCodes.Stfld, field);
|
|
271
|
+
il.Emit(OpCodes.Ret);
|
|
272
|
+
|
|
273
|
+
Type delegateType = typeof(FieldSetter<,>).MakeGenericType(instanceType, valueType);
|
|
274
|
+
return (FieldSetter<TInstance, TValue>)dynamicMethod.CreateDelegate(delegateType);
|
|
275
|
+
#endif
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
public static Action<TValue> GetStaticFieldSetter<TValue>(FieldInfo field)
|
|
279
|
+
{
|
|
280
|
+
if (!field.IsStatic)
|
|
281
|
+
{
|
|
282
|
+
throw new ArgumentException(nameof(field));
|
|
283
|
+
}
|
|
284
|
+
#if WEB_GL
|
|
285
|
+
return Setter;
|
|
286
|
+
void Setter(TValue newValue)
|
|
287
|
+
{
|
|
288
|
+
field.SetValue(null, newValue);
|
|
289
|
+
}
|
|
290
|
+
#else
|
|
291
|
+
DynamicMethod dynamicMethod = new(
|
|
292
|
+
$"SetFieldGenericStatic{field.DeclaringType.Name}{field.Name}",
|
|
293
|
+
typeof(void),
|
|
294
|
+
new[] { typeof(TValue) },
|
|
295
|
+
field.Module,
|
|
296
|
+
true
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
300
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
301
|
+
il.Emit(OpCodes.Stsfld, field);
|
|
302
|
+
il.Emit(OpCodes.Ret);
|
|
303
|
+
|
|
304
|
+
return (Action<TValue>)dynamicMethod.CreateDelegate(typeof(Action<TValue>));
|
|
305
|
+
#endif
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public static Action<object, object> GetFieldSetter(FieldInfo field)
|
|
309
|
+
{
|
|
310
|
+
#if WEB_GL
|
|
311
|
+
return field.SetValue;
|
|
312
|
+
#else
|
|
313
|
+
DynamicMethod dynamicMethod = new(
|
|
314
|
+
$"SetField{field.DeclaringType.Name}{field.Name}",
|
|
315
|
+
null,
|
|
316
|
+
new[] { typeof(object), typeof(object) },
|
|
317
|
+
field.DeclaringType.Module,
|
|
318
|
+
true
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
322
|
+
|
|
323
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
324
|
+
il.Emit(
|
|
325
|
+
field.DeclaringType.IsValueType ? OpCodes.Unbox : OpCodes.Castclass,
|
|
326
|
+
field.DeclaringType
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
il.Emit(OpCodes.Ldarg_1);
|
|
330
|
+
il.Emit(
|
|
331
|
+
field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass,
|
|
332
|
+
field.FieldType
|
|
333
|
+
);
|
|
334
|
+
il.Emit(OpCodes.Stfld, field);
|
|
335
|
+
il.Emit(OpCodes.Ret);
|
|
336
|
+
return (Action<object, object>)
|
|
337
|
+
dynamicMethod.CreateDelegate(typeof(Action<object, object>));
|
|
338
|
+
#endif
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
public static Action<object> GetStaticFieldSetter(FieldInfo field)
|
|
342
|
+
{
|
|
343
|
+
if (!field.IsStatic)
|
|
344
|
+
{
|
|
345
|
+
throw new ArgumentException(nameof(field));
|
|
346
|
+
}
|
|
347
|
+
#if WEB_GL
|
|
348
|
+
return value => field.SetValue(null, value);
|
|
349
|
+
#else
|
|
350
|
+
DynamicMethod dynamicMethod = new(
|
|
351
|
+
$"SetFieldStatic{field.DeclaringType.Name}{field.Name}",
|
|
352
|
+
null,
|
|
353
|
+
new[] { typeof(object) },
|
|
354
|
+
field.DeclaringType.Module,
|
|
355
|
+
true
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
359
|
+
|
|
360
|
+
// Load the new value (argument 0)
|
|
361
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
362
|
+
// Convert the object to the field's type (unbox or cast as needed)
|
|
363
|
+
il.Emit(
|
|
364
|
+
field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass,
|
|
365
|
+
field.FieldType
|
|
366
|
+
);
|
|
367
|
+
// Set the static field
|
|
368
|
+
il.Emit(OpCodes.Stsfld, field);
|
|
369
|
+
il.Emit(OpCodes.Ret);
|
|
370
|
+
|
|
371
|
+
return (Action<object>)dynamicMethod.CreateDelegate(typeof(Action<object>));
|
|
372
|
+
#endif
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
public static Func<int, Array> GetArrayCreator(Type elementType)
|
|
376
|
+
{
|
|
377
|
+
#if WEB_GL
|
|
378
|
+
return size => Array.CreateInstance(elementType, size);
|
|
379
|
+
#else
|
|
380
|
+
DynamicMethod dynamicMethod = new(
|
|
381
|
+
$"CreateArray{elementType.Name}",
|
|
382
|
+
typeof(Array), // Return type: Array
|
|
383
|
+
new[] { typeof(int) }, // Parameter: int (size)
|
|
384
|
+
true
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
388
|
+
il.Emit(OpCodes.Ldarg_0); // Load the array size
|
|
389
|
+
il.Emit(OpCodes.Newarr, elementType); // Create a new array of 'type'
|
|
390
|
+
il.Emit(OpCodes.Ret); // Return the array
|
|
391
|
+
return (Func<int, Array>)dynamicMethod.CreateDelegate(typeof(Func<int, Array>));
|
|
392
|
+
#endif
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
public static Func<IList> GetListCreator(Type elementType)
|
|
396
|
+
{
|
|
397
|
+
Type listType = typeof(List<>).MakeGenericType(elementType);
|
|
398
|
+
#if WEB_GL
|
|
399
|
+
return () => (IList)Activator.CreateInstance(listType);
|
|
400
|
+
#else
|
|
401
|
+
DynamicMethod dynamicMethod = new(
|
|
402
|
+
$"CreateList{listType.Name}",
|
|
403
|
+
typeof(IList), // Return type: IList
|
|
404
|
+
Type.EmptyTypes, // No parameters
|
|
405
|
+
true
|
|
406
|
+
);
|
|
407
|
+
|
|
408
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
409
|
+
ConstructorInfo constructor = listType.GetConstructor(Type.EmptyTypes);
|
|
410
|
+
if (constructor == null)
|
|
411
|
+
{
|
|
412
|
+
throw new ArgumentException(
|
|
413
|
+
$"Type {listType} does not have a parameterless constructor."
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
il.Emit(OpCodes.Newobj, constructor); // Call List<T> constructor
|
|
418
|
+
il.Emit(OpCodes.Ret); // Return the instance
|
|
419
|
+
return (Func<IList>)dynamicMethod.CreateDelegate(typeof(Func<IList>));
|
|
420
|
+
#endif
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
public static Func<int, IList> GetListWithCapacityCreator(Type elementType)
|
|
424
|
+
{
|
|
425
|
+
Type listType = typeof(List<>).MakeGenericType(elementType);
|
|
426
|
+
#if WEB_GL
|
|
427
|
+
return _ => (IList)Activator.CreateInstance(listType);
|
|
428
|
+
#else
|
|
429
|
+
DynamicMethod dynamicMethod = new(
|
|
430
|
+
$"CreateListWithCapacity{listType.Name}",
|
|
431
|
+
typeof(IList), // Return type: IList
|
|
432
|
+
new[] { typeof(int) }, // Parameter: int (size)
|
|
433
|
+
true
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
437
|
+
ConstructorInfo constructor = listType.GetConstructor(new[] { typeof(int) });
|
|
438
|
+
if (constructor == null)
|
|
439
|
+
{
|
|
440
|
+
throw new ArgumentException(
|
|
441
|
+
$"Type {listType} does not have a constructor accepting an int."
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
il.Emit(OpCodes.Ldarg_0); // Load capacity argument
|
|
446
|
+
il.Emit(OpCodes.Newobj, constructor); // Call List<T>(int capacity) constructor
|
|
447
|
+
il.Emit(OpCodes.Ret); // Return the instance
|
|
448
|
+
return (Func<int, IList>)dynamicMethod.CreateDelegate(typeof(Func<int, IList>));
|
|
449
|
+
#endif
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|