View Issue Details

IDProjectCategoryView StatusLast Update
0003565NoesisGUIC++ SDKpublic2024-07-30 17:52
Reportern3b Assigned Tojsantos  
PrioritynormalSeverityfeature 
Status assignedResolutionopen 
Product Version3.2.4 
Summary0003565: overridable TypeProperty::FindMeta
Description

Currently it's possible to define runtime reflection types as instances of the same type with only exception when such instances are nested.
TypeProperty::FindMeta does not differentiate such instances and relies on static types only.
It would be nice to be able to override TypeProperty::FindMeta to feed a proper TypeClass* to the base method.

PlatformAny

Activities

jsantos

jsantos

2024-07-30 13:37

manager   ~0009846

I am not sure to be following here. Could you please give more detail with a specific example?

n3b

n3b

2024-07-30 17:52

reporter   ~0009850

So consider this setup:

struct RuntimeComponentField
{
RuntimeComponentField(Symbol name, Symbol type) : name(name), type(type) {}
Symbol name;
Symbol type;
};
static vector<RuntimeComponentField> fields{};

struct RuntimeComponent : NotifyPropertyChangedBase
{
RuntimeComponent(Symbol s) { type = dynamic_cast<const TypeClass>(Reflection::GetType(s)); }
const TypeClass
GetClassType() const override { return type; }
const TypeClass* type;

friend class TypeClassCreator;
static void StaticFillClassType(TypeClassCreator& helper)
{
            auto builder = *reinterpret_cast<TypeClassBuilder**>(&helper);
    for (auto& f : fields)
    {
        builder->AddProperty(typePropertyFactory[f.type - startIndex](f.name, offset));
    }
}

}
typePropertyFactory is a vector of generic functions creating a TypeProperty for a given field type.

Now this allows us to create reflections at runtime with:
void registerRuntimeType(const char name, RuntimeComponentField fieldsArr, int numFields)
{
fields.insert(fields.end(), fieldsArr, fieldsArr + numFields);
auto type = dynamic_cast<const TypeClass>(Reflection::RegisterType((name), TypeClassCreator::Create<RuntimeComponent>, TypeClassCreator::Fill<RuntimeComponent, NotifyPropertyChangedBase>));
RegisterComponent(type, [](Symbol s) -> BaseComponent
{ return new RuntimeComponent>(s); });
fields.clear();
}

Now we can use XAML with models that were not known at compile time.
However "{Binding Path=InstanceOfRuntimeComponent.AnotherInstanceOfRuntimeComponent, UpdateSourceTrigger=PropertyChanged}"

will always go through the static context, meaning components that have different RuntimeComponent::type share the same StaticGetClassType:
template<class T> T FindMeta(const TypeProperty type)
{
return (T)(type->FindMeta(T::StaticGetClassType((TypeTag<T>)nullptr)));
}

If TypeProperty::FindMeta would have been virtual, we could have extend TypePropertyOffset and others to keep either TypeClass* or Symbol and then just do Base::FindMeta(actualTypeClassOfProperty)

Issue History

Date Modified Username Field Change
2024-07-29 19:05 n3b New Issue
2024-07-30 13:37 jsantos Assigned To => jsantos
2024-07-30 13:37 jsantos Status new => assigned
2024-07-30 13:37 jsantos Note Added: 0009846
2024-07-30 13:38 jsantos Status assigned => feedback
2024-07-30 17:52 n3b Note Added: 0009850
2024-07-30 17:52 n3b Status feedback => assigned