mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-11 04:52:21 +02:00
Reflection SetField fixes
This commit is contained in:
parent
d864a912c5
commit
eda4e80715
2 changed files with 89 additions and 21 deletions
|
@ -46,7 +46,7 @@ namespace System.Reflection
|
|||
|
||||
public Result<void, Error> SetValue(Object obj, Object value)
|
||||
{
|
||||
int32 dataOffsetAdjust = 0;
|
||||
void* dataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj));
|
||||
if (mTypeInstance.IsStruct)
|
||||
{
|
||||
Type boxedType = obj.[Friend]RawGetType();
|
||||
|
@ -55,16 +55,18 @@ namespace System.Reflection
|
|||
{
|
||||
if (mTypeInstance == boxedType.UnderlyingType)
|
||||
{
|
||||
dataOffsetAdjust = boxedType.[Friend]mMemberDataOffset;
|
||||
dataAddr = (void*)((int)dataAddr + boxedType.[Friend]mMemberDataOffset);
|
||||
if (boxedType.IsBoxedStructPtr)
|
||||
dataAddr = *(void**)dataAddr;
|
||||
typeMatched = true;
|
||||
}
|
||||
}
|
||||
if (!typeMatched)
|
||||
return .Err(.InvalidTargetType); // "Invalid target type");
|
||||
}
|
||||
dataAddr = (void*)((int)dataAddr + mFieldData.mData);
|
||||
|
||||
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
|
||||
void* fieldDataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj)) + (int)mFieldData.mData + dataOffsetAdjust;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
|
@ -74,13 +76,15 @@ namespace System.Reflection
|
|||
}
|
||||
else
|
||||
{
|
||||
*((int*)fieldDataAddr) = 0;
|
||||
*((int*)dataAddr) = 0;
|
||||
return .Ok;
|
||||
}
|
||||
}
|
||||
|
||||
Type rawValueType = value.[Friend]RawGetType();
|
||||
void* valueDataAddr = ((uint8*)Internal.UnsafeCastToPtr(value)) + rawValueType.[Friend]mMemberDataOffset;
|
||||
if (rawValueType.IsBoxedStructPtr)
|
||||
valueDataAddr = *(void**)valueDataAddr;
|
||||
|
||||
Type valueType = value.GetType();
|
||||
|
||||
|
@ -90,9 +94,9 @@ namespace System.Reflection
|
|||
if (valueType == fieldType)
|
||||
{
|
||||
if (valueType.IsObject)
|
||||
*((void**)fieldDataAddr) = Internal.UnsafeCastToPtr(value);
|
||||
*((void**)dataAddr) = Internal.UnsafeCastToPtr(value);
|
||||
else
|
||||
Internal.MemCpy(fieldDataAddr, valueDataAddr, fieldType.[Friend]mSize);
|
||||
Internal.MemCpy(dataAddr, valueDataAddr, fieldType.[Friend]mSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -104,7 +108,7 @@ namespace System.Reflection
|
|||
|
||||
public Result<void> SetValue(Object obj, Variant value)
|
||||
{
|
||||
int32 dataOffsetAdjust = 0;
|
||||
void* dataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj));
|
||||
if (mTypeInstance.IsStruct)
|
||||
{
|
||||
Type boxedType = obj.[Friend]RawGetType();
|
||||
|
@ -113,20 +117,31 @@ namespace System.Reflection
|
|||
{
|
||||
if (mTypeInstance == boxedType.UnderlyingType)
|
||||
{
|
||||
dataOffsetAdjust = boxedType.[Friend]mMemberDataOffset;
|
||||
dataAddr = (void*)((int)dataAddr + boxedType.[Friend]mMemberDataOffset);
|
||||
if (boxedType.IsBoxedStructPtr)
|
||||
dataAddr = *(void**)dataAddr;
|
||||
typeMatched = true;
|
||||
}
|
||||
}
|
||||
if (!typeMatched)
|
||||
return .Err;//("Invalid target type");
|
||||
}
|
||||
dataAddr = (void*)((int)dataAddr + mFieldData.mData);
|
||||
|
||||
Type fieldType = Type.[Friend]GetType(mFieldData.mFieldTypeId);
|
||||
|
||||
void* dataAddr = ((uint8*)Internal.UnsafeCastToPtr(obj)) + (int)mFieldData.mData + dataOffsetAdjust;
|
||||
|
||||
if (value.VariantType != fieldType)
|
||||
let variantType = value.VariantType;
|
||||
if (variantType != fieldType)
|
||||
{
|
||||
if ((variantType.IsPointer) && (variantType.UnderlyingType == fieldType))
|
||||
{
|
||||
void* srcPtr = value.Get<void*>();
|
||||
Internal.MemCpy(dataAddr, srcPtr, fieldType.Size);
|
||||
return .Ok;
|
||||
}
|
||||
else
|
||||
return .Err;//("Invalid type");
|
||||
}
|
||||
|
||||
value.CopyValueData(dataAddr);
|
||||
|
||||
|
@ -149,6 +164,8 @@ namespace System.Reflection
|
|||
/*if (type.IsStruct)
|
||||
return &value;*/
|
||||
|
||||
if (type.IsBoxedStructPtr)
|
||||
return *(void**)(((uint8*)Internal.UnsafeCastToPtr(value)) + type.[Friend]mMemberDataOffset);
|
||||
if (type.IsBoxed)
|
||||
return ((uint8*)Internal.UnsafeCastToPtr(value)) + type.[Friend]mMemberDataOffset;
|
||||
return ((uint8*)Internal.UnsafeCastToPtr(value));
|
||||
|
|
|
@ -125,11 +125,18 @@ namespace Tests
|
|||
}
|
||||
}
|
||||
|
||||
struct StructC
|
||||
{
|
||||
public float mA;
|
||||
public float mB;
|
||||
}
|
||||
|
||||
[Reflect, AlwaysInclude(AssumeInstantiated=true, IncludeAllMethods=true)]
|
||||
struct StructB
|
||||
{
|
||||
public int mA;
|
||||
public String mB;
|
||||
public StructC mC;
|
||||
}
|
||||
|
||||
class ClassA2 : ClassA
|
||||
|
@ -485,20 +492,64 @@ namespace Tests
|
|||
StructB sb;
|
||||
sb.mA = 25;
|
||||
sb.mB = "Struct B";
|
||||
sb.mC = .() { mA = 1.2f, mB = 2.3f };
|
||||
|
||||
let type = sb.GetType() as TypeInstance;
|
||||
let fields = type.GetFields();
|
||||
int fieldIdx = 0;
|
||||
for (let field in fields)
|
||||
{
|
||||
let refP = field.GetValue(sb);
|
||||
let fieldVal = field.GetValue(sb);
|
||||
let fieldVal2 = field.GetValue(&sb);
|
||||
switch (fieldIdx)
|
||||
{
|
||||
case 0:
|
||||
Test.Assert(refP.Value.Get<int>() == 25);
|
||||
Test.Assert(fieldVal.Value.Get<int>() == 25);
|
||||
Variant newVal = Variant.Create<int>(32);
|
||||
field.SetValue(sb, newVal);
|
||||
Test.Assert(sb.mA == 25);
|
||||
|
||||
Test.Assert(fieldVal2.Value.Get<int>() == 25);
|
||||
field.SetValue(&sb, newVal);
|
||||
Test.Assert(sb.mA == 32);
|
||||
case 1:
|
||||
Test.Assert(refP.Value.Get<String>() === "Struct B");
|
||||
Test.Assert(fieldVal.Value.Get<String>() === "Struct B");
|
||||
field.SetValue(&sb, "Struct C");
|
||||
Test.Assert(sb.mB == "Struct C");
|
||||
case 2:
|
||||
StructC sc = .() { mA = 1.2f, mB = 2.3f };
|
||||
Test.Assert(fieldVal.Value.Get<StructC>() == sc);
|
||||
Test.Assert(fieldVal2.Value.Get<StructC>() == sc);
|
||||
sc.mA += 100;
|
||||
sc.mB += 100;
|
||||
field.SetValue(&sb, sc);
|
||||
Test.Assert(sb.mC.mA == 101.2f);
|
||||
Test.Assert(sb.mC.mB == 102.3f);
|
||||
sc.mA += 100;
|
||||
sc.mB += 100;
|
||||
field.SetValue(&sb, &sc);
|
||||
Test.Assert(sb.mC.mA == 201.2f);
|
||||
Test.Assert(sb.mC.mB == 202.3f);
|
||||
sc.mA += 100;
|
||||
sc.mB += 100;
|
||||
Variant newVariant = Variant.Create(sc);
|
||||
field.SetValue(&sb, newVariant);
|
||||
Test.Assert(sb.mC.mA == 301.2f);
|
||||
Test.Assert(sb.mC.mB == 302.3f);
|
||||
sc.mA += 100;
|
||||
sc.mB += 100;
|
||||
newVariant.Dispose();
|
||||
newVariant = Variant.Create(&sc);
|
||||
field.SetValue(&sb, newVariant);
|
||||
Test.Assert(sb.mC.mA == 401.2f);
|
||||
Test.Assert(sb.mC.mB == 402.3f);
|
||||
sc.mA += 100;
|
||||
sc.mB += 100;
|
||||
newVariant = Variant.CreateReference(typeof(StructC), &sc);
|
||||
field.SetValue(&sb, newVariant);
|
||||
Test.Assert(sb.mC.mA == 501.2f);
|
||||
Test.Assert(sb.mC.mB == 502.3f);
|
||||
case 3:
|
||||
Test.FatalError();
|
||||
}
|
||||
fieldIdx++;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue