jsoysouvanh / Refureku

Cross-platform C++17 Runtime Reflection Library
https://jsoysouvanh.github.io/Refureku/
MIT License
212 stars 21 forks source link

Template class double registration #12

Open ghost opened 2 years ago

ghost commented 2 years ago

Here is the situation. I have an Engine library (DLL) where I try to reflect the std::vector class. I wanted to use this reflected vector in a Scripting dll driven by an Editor application. (Manipulate and display the vector content in an inspector). The problem is that when I'm trying to declare one in the Scripting dll, double registration warnings show up.

[Refureku] WARNING: Double registration detected: (6467467976038935076, HyVector) collides with entity: (6467467976038935076, HyVector)
[Refureku] WARNING: Double registration detected: (2076874076076324754, GetElementAt) collides with entity: (2076874076076324754, GetElementAt)
[Refureku] WARNING: Double registration detected: (7605404597672029496, size) collides with entity: (7605404597672029496, size)
[Refureku] WARNING: Double registration detected: (9954276657655150362, AddNewElement) collides with entity: (9954276657655150362, AddNewElement)

Here is the vector class :

// STDTemplateClass used as a global instance for all standard template classes
template <typename Type>
class HY_CLASS() HyVector final : public STDTemplateClass, public std::vector<Type>
{

public:
    HY_METHOD() std::size_t size();
    HY_METHOD() void* GetElementAt(std::size_t index);
    HY_METHOD() void* AddNewElement();

    HyVector_GENERATED
};

This drives to another problem. When I'm trying to retrieve some methods from the class template instantiation given by the field archetype, methods are not found and are set to null. I bypassed this problem by retrieving the base archetype on the database from the field archetype ID.

// From field archetype
rfk::Archetype const* fieldArchetype = field.getType().getArchetype();
rfk::ClassTemplateInstantiation const* cTempInstance = rfk::classTemplateInstantiationCast(fieldArchetype );

// Retrieve vector instance
STDTemplateClass& vecClass = *reinterpret_cast<STDTemplateClass*>(field.getPtr(owner));

// Here, the getMethod is not valid
rfk::Method const* getMethod = cTempInstance->getMethodByName("GetElementAt");

// From field archetype ID
fieldArchetype = rfk::getDatabase().getClassById(fieldArchetype ->getId());
cTempInstance = rfk::classTemplateInstantiationCast(fieldArchetype);

// Here, the getMethod is valid and usable
getMethod = cTempInstance->getMethodByName("GetElementAt");
jsoysouvanh commented 2 years ago

Hi, thank you for your feedback.

I indeed forgot to consider the case the same template is used in different translations units leading at a duplication of the same archetype... It doesn't seem trivial to fix either, I'll need a bit of time to find an elegant solution to fix this problem. Off the top of my head, I don't understand why the archetype duplicate doesn't contain the reflected method neither.

The workaround is almost performance-free so I recommand people having this issue to use it until the bug is fixed.