Structs and reflection

About Monkey 2 Forums Monkey 2 Development Structs and reflection

Tagged: 

This topic contains 11 replies, has 3 voices, and was last updated by  Mark Sibly 1 year, 5 months ago.

Viewing 12 posts - 1 through 12 (of 12 total)
  • Author
    Posts
  • #10652

    Ethernaut
    Participant

    Is there any chance structs will be supported by the reflection system in the future? (i.e. no technical reason why it can’t happen?)

    I’m working on a basic general purpose serialization that uses reflection to load and save all of an object’s “settable” properties, but I got stuck figuring out the type of properties that contain structs.

    I don’t need this right now, so I can put this aside until there’s a solution, but I need to know if it’s not really doable so I can try to find a different solution on my own side.

    Thanks!

    #10656

    Mark Sibly
    Keymaster

    Just had a look at this, and the big problem is that structs are always passed ‘by value’, which means its impossible to modify them ‘by reference’, eg:

    This fails to SetX because SetX() receives a copy of ‘c’, not a reference to the same ‘c’.

    Reflection has a similar problem – when you pass the ‘instance’ object to ‘Set’ or ‘Invoke’, you’re passing a copy of the struct value, so any modifications made by Set or Invoke are being made to a copy that will just be thrown away.

    So I’ll keep looking, but right now the answer is no.

    #10657

    Mark Sibly
    Keymaster

    I’ve actually had some success with this and it may yet happen!

    The trick is to treat the Variant as a ‘box’ for struct values. The struct value still gets copied when you set or get it, but the Set() and Invoke() methods can directly access the value in the variant/box.

    So as long as you keep passing the same variant to decl.Set() etc, you’ll be updating the same struct value.

    #10658

    nerobot
    Participant

    Very nice!

    #10716

    Ethernaut
    Participant

    So close! This code almost works with the latest dev branch. The goal is to print out all settable properties, recursively.
    Only when we uncomment the “BrandNewName” property, which returns a struct, it fails. Can’t see why, since the Color property also returns a struct, yet that one works perfectly.

    This will spit out the following string:

    Sorry for all the Monty Python references.

    #10717

    Ethernaut
    Participant

    Found it. The property that wasn’t working returns a struct “NonsenseStruct”, but it sets a String property in that struct, instead of setting the struct itself.
    Changing it to this works:

    #10750

    Mark Sibly
    Keymaster

    Nice work, very bleeding edge! Will fix the property type bug ASAP.

    I’ve successfully had generic struct instances reflected here (eg: Vec3f, Mat4f etc) but it needs a bit more work and I think a REFLECTION_FILTER equivalent also needs to be added before any of this is truly useful.

    #10786

    Ethernaut
    Participant

    Thanks Mark!

    Things are working nicely, but I’ve ran into a problem that may be more related to how inheritance works than to reflection… in the following code, I can’t serialize the objects coming from a stack with the correct extended type. They end up all being serialized as “BaseClass”, even though one of them is “ExtendedClass”.

    Is there a way to cast them as i iterate through the stack?

    #10807

    Mark Sibly
    Keymaster

    This is because Variant.Type only returns the static type of the variant. You’ll need to use InstanceType on the object contained in the variant instead of v.Type, eg:

    Local type:=Cast<Object>( v ).InstanceType

    …safer…

    I now think InstanceType should probably be renamed to DynamicType, and possibly the above DynamicType code added to Variant too which can do it more efficiently.

    Anyway, quick fix for the above: change the Default block to:

    #10810

    Ethernaut
    Participant

    Sweet! Works now.

    I remember something about serialization not recognizing generics, and I definitely see it not working.It also fails on Enum types, apparently. The way I’m gonna work around it is having properties that return arrays or other values, instead of generic classes and structs, so that instead of:

    I’ll do:

    Or I can create ToArray() and FromArray() method extensions to classes and structs I know I’ll use anyway, like Vec3f, etc.

    Gonna work on loading now. Will post Serialize/Deserialize code to archives once it works well (I already have it handling arrays, yay!).

    Monkey2 is a lot of fun. Cheers!

    #11372

    nerobot
    Participant

    and I think a REFLECTION_FILTER equivalent also needs to be added before any of this is truly useful.

    I’m waiting for such filter!:)

    I want to have minimal reflection where each class/interface would have its own instance for Typeof – to have comparison of them, and type should have at least Name property.

    #11375

    Mark Sibly
    Keymaster

    I’m waiting for such filter!:)

    Soon – hopefully by v1.1.09!

Viewing 12 posts - 1 through 12 (of 12 total)

You must be logged in to reply to this topic.