Common alias for QMetaType int Qt6
Since Qt6, QMetaType
registers custom types under a typename that may vary with respect to the compiler. This is very problematic since the typename was used in dtk
as a cross-platform identifier for serialisation and deserialisation processes.
See this forum discussion for an example of the problem that this regression may occur.
dtkCoreParameter
makes an intensive use of serialisation/deserialisation process but as this issue may regard any kind of classes, a global solution at the scale of the whole dtk
ecosystem has to be featured.
Hence, dtkCoreMetaType
now features the singleton dtkCoreMetaTypeRegistry
which provides a map between the integer given by qMetaTypeId<T>()
and a QString
as common custom alias.
In the case of dtkCoreParameter
, the MACRO DTK_DEFINE_PARAMETER(type, name_space)
, which is mandatory to make parameters work, is used to perform the registration into dtkCoreMetaTypeRegistry
automatically without any additional code for the developers. The alias will be equal to the first argument of the macro, namely type
.
For instance in dtkCoreParameterNumeric.h
, one declares an alias for dtkCoreParameterNumeric<double>
as follows:
namespace dtk {
using d_real = dtkCoreParameterNumeric<double>;
}
DTK_DECLARE_PARAMETER(dtk::d_real);
And in dtkCoreParameterNumeric.cpp
, the following code is written:
DTK_DEFINE_PARAMETER(dtk::d_real, d_real);
Firstly, this enables to register the type dtkCoreParameterNumeric<double>
to the QMetaType system with an additional alias dtk::d_real
so that one can instantiate a QMetaType
object using this alias:
auto mt = QMetaType::fromName("dtk::d_real");
qDebug() << (qMetaTypeId<dtkCoreParemeterNumeric<double>>() == mt.id()); // must display true
Secondly, it enables to populate the dtkCoreMetaTypeRegistry
with the pair {qMetaTypeId<dtkCoreParemeterNumeric<double>>, "dtk::d_real"}
so that the serialisation process of the parameter can be done as follows in dtkCoreParameterBase
CRTP class:
template <typename Derive>
inline QVariantHash dtkCoreParameterBase<Derive>::toVariantHash(void) const
{
QVariantHash hash;
auto alias = dtk::metaTypeRegistry().alias(qMetaTypeId<Derive>());
hash.insert("type", alias);
...
}