mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-26 10:45:37 +08:00
refs #413 Decomposed property indexing functions of CValueObject into Mixin::Index.
This commit is contained in:
@@ -616,6 +616,62 @@ namespace BlackMisc
|
|||||||
Derived *derived() { return static_cast<Derived *>(this); }
|
Derived *derived() { return static_cast<Derived *>(this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* CRTP class template from which a derived class can inherit property indexing functions.
|
||||||
|
*/
|
||||||
|
template <class Derived, bool BaseIsEmpty = true>
|
||||||
|
class Index
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Update by variant map
|
||||||
|
//! \return number of values changed, with skipEqualValues equal values will not be changed
|
||||||
|
CPropertyIndexList apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues = false); // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
//! Set property by index
|
||||||
|
virtual void setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index); // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
//! Property by index
|
||||||
|
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
//! Property by index as String
|
||||||
|
virtual QString propertyByIndexAsString(const CPropertyIndex &index, bool i18n = false) const; // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
//! Is given variant equal to value of property index?
|
||||||
|
virtual bool equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const; // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||||
|
Derived *derived() { return static_cast<Derived *>(this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Specialization of Index for classes further down an inheritance hierarchy.
|
||||||
|
*/
|
||||||
|
template <class Derived>
|
||||||
|
class Index<Derived, false>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//! Update by variant map
|
||||||
|
//! \return number of values changed, with skipEqualValues equal values will not be changed
|
||||||
|
CPropertyIndexList apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues = false); // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
//! Set property by index
|
||||||
|
virtual void setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index) { derived()->Derived::base_type::setPropertyByIndex(variant, index); }
|
||||||
|
|
||||||
|
//! Property by index
|
||||||
|
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; // implemented later due to cyclic include dependency
|
||||||
|
|
||||||
|
//! Property by index as String
|
||||||
|
virtual QString propertyByIndexAsString(const CPropertyIndex &index, bool i18n = false) const { return derived()->Derived::base_type::propertyByIndexAsString(index, i18n); }
|
||||||
|
|
||||||
|
//! Is given variant equal to value of property index?
|
||||||
|
virtual bool equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const { return derived()->Derived::base_type::equalsPropertyByIndex(compareValue, index); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||||
|
Derived *derived() { return static_cast<Derived *>(this); }
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -637,12 +693,11 @@ namespace BlackMisc
|
|||||||
public Mixin::EqualsByTuple<Derived, Policy::Equals::IsMetaTuple<Derived, Base>::value>,
|
public Mixin::EqualsByTuple<Derived, Policy::Equals::IsMetaTuple<Derived, Base>::value>,
|
||||||
public Mixin::LessThanByTuple<Derived, Policy::LessThan::IsMetaTuple<Derived, Base>::value>,
|
public Mixin::LessThanByTuple<Derived, Policy::LessThan::IsMetaTuple<Derived, Base>::value>,
|
||||||
public Mixin::CompareByTuple<Derived, Policy::Compare::IsMetaTuple<Derived, Base>::value>,
|
public Mixin::CompareByTuple<Derived, Policy::Compare::IsMetaTuple<Derived, Base>::value>,
|
||||||
public Mixin::String<Derived>
|
public Mixin::String<Derived>,
|
||||||
|
public Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<CEmpty, Base>::value || IsValueObject<Base>::value, "Base must be either CEmpty or derived from CValueObject");
|
static_assert(std::is_same<CEmpty, Base>::value || IsValueObject<Base>::value, "Base must be either CEmpty or derived from CValueObject");
|
||||||
|
|
||||||
using PropertyIndexPolicy = typename CValueObjectPolicy<Derived>::PropertyIndex;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Base class
|
//! Base class
|
||||||
using base_type = Base;
|
using base_type = Base;
|
||||||
@@ -667,9 +722,8 @@ namespace BlackMisc
|
|||||||
//! \copydoc BlackMisc::Mixin::String::toStdString
|
//! \copydoc BlackMisc::Mixin::String::toStdString
|
||||||
using Mixin::String<Derived>::toStdString;
|
using Mixin::String<Derived>::toStdString;
|
||||||
|
|
||||||
//! Update by variant map
|
//! \copydoc BlackMisc::Mixin::Index::apply
|
||||||
//! \return number of values changed, with skipEqualValues equal values will not be changed
|
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::apply;
|
||||||
CPropertyIndexList apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues = false); // implemented later due to cyclic include dependency
|
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Mixin::MetaType::toCVariant
|
//! \copydoc BlackMisc::Mixin::MetaType::toCVariant
|
||||||
using Mixin::MetaType<Derived>::toCVariant;
|
using Mixin::MetaType<Derived>::toCVariant;
|
||||||
@@ -689,17 +743,17 @@ namespace BlackMisc
|
|||||||
//! \copydoc BlackMisc::Mixin::MetaType::convertFromQVariant
|
//! \copydoc BlackMisc::Mixin::MetaType::convertFromQVariant
|
||||||
using Mixin::MetaType<Derived>::convertFromQVariant;
|
using Mixin::MetaType<Derived>::convertFromQVariant;
|
||||||
|
|
||||||
//! Set property by index
|
//! \copydoc BlackMisc::Mixin::Index::setPropertyByIndex
|
||||||
virtual void setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index) { PropertyIndexPolicy::setPropertyByIndex(*derived(), variant, index); }
|
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::setPropertyByIndex;
|
||||||
|
|
||||||
//! Property by index
|
//! \copydoc BlackMisc::Mixin::Index::propertyByIndex
|
||||||
virtual CVariant propertyByIndex(const BlackMisc::CPropertyIndex &index) const; // implemented later due to cyclic include dependency
|
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::propertyByIndex;
|
||||||
|
|
||||||
//! Property by index as String
|
//! \copydoc BlackMisc::Mixin::Index::propertyByIndexAsString
|
||||||
virtual QString propertyByIndexAsString(const CPropertyIndex &index, bool i18n = false) const { return PropertyIndexPolicy::propertyByIndexAsString(*derived(), index, i18n); }
|
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::propertyByIndexAsString;
|
||||||
|
|
||||||
//! Is given variant equal to value of property index?
|
//! \copydoc BlackMisc::Mixin::Index::equalsPropertyByIndex
|
||||||
virtual bool equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const { return PropertyIndexPolicy::equalsPropertyByIndex(*derived(), compareValue, index); }
|
using Mixin::Index<Derived, std::is_same<Base, CEmpty>::value>::equalsPropertyByIndex;
|
||||||
|
|
||||||
//! \copydoc BlackMisc::Mixin::MetaType::isA
|
//! \copydoc BlackMisc::Mixin::MetaType::isA
|
||||||
using Mixin::MetaType<Derived>::isA;
|
using Mixin::MetaType<Derived>::isA;
|
||||||
@@ -708,9 +762,6 @@ namespace BlackMisc
|
|||||||
using Mixin::MetaType<Derived>::registerMetadata;
|
using Mixin::MetaType<Derived>::registerMetadata;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template <typename T>
|
|
||||||
friend struct Private::CValueObjectMetaInfo;
|
|
||||||
|
|
||||||
//! Default constructor.
|
//! Default constructor.
|
||||||
CValueObject() = default;
|
CValueObject() = default;
|
||||||
|
|
||||||
@@ -737,10 +788,6 @@ namespace BlackMisc
|
|||||||
|
|
||||||
//! \copydoc BlackMisc::Mixin::DBusByTuple::unmarshallFromDbus
|
//! \copydoc BlackMisc::Mixin::DBusByTuple::unmarshallFromDbus
|
||||||
using Mixin::DBusByTuple<Derived, Policy::DBus::IsMetaTuple<Derived, Base>::value>::unmarshallFromDbus;
|
using Mixin::DBusByTuple<Derived, Policy::DBus::IsMetaTuple<Derived, Base>::value>::unmarshallFromDbus;
|
||||||
|
|
||||||
private:
|
|
||||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
|
||||||
Derived *derived() { return static_cast<Derived *>(this); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@@ -766,97 +813,86 @@ namespace BlackMisc
|
|||||||
{
|
{
|
||||||
derived()->convertFromQVariant(variant.getQVariant());
|
derived()->convertFromQVariant(variant.getQVariant());
|
||||||
}
|
}
|
||||||
}
|
template <class Derived>
|
||||||
template <class Derived, class Base>
|
CPropertyIndexList Index<Derived, false>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
|
||||||
CPropertyIndexList CValueObject<Derived, Base>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
|
|
||||||
{
|
|
||||||
CPropertyIndexList result;
|
|
||||||
PropertyIndexPolicy::apply(*derived(), indexMap, result, skipEqualValues);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
template <class Derived, class Base>
|
|
||||||
CVariant CValueObject<Derived, Base>::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
|
||||||
{
|
|
||||||
CVariant result;
|
|
||||||
PropertyIndexPolicy::propertyByIndex(*derived(), index, result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
namespace Policy
|
|
||||||
{
|
|
||||||
namespace PropertyIndex
|
|
||||||
{
|
{
|
||||||
template <class T, class...>
|
return derived()->Derived::base_type::apply(indexMap, skipEqualValues);
|
||||||
void Default::apply(T &obj, const CPropertyIndexVariantMap &indexMap, CPropertyIndexList &o_changed, bool skipEqualValues, Default::EnableIfEmptyBase<T>)
|
}
|
||||||
{
|
template <class Derived>
|
||||||
if (indexMap.isEmpty()) return;
|
CVariant Index<Derived, false>::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
|
||||||
|
{
|
||||||
|
return derived()->Derived::base_type::propertyByIndex(index);
|
||||||
|
}
|
||||||
|
template <class Derived, bool BaseIsEmpty>
|
||||||
|
CPropertyIndexList Index<Derived, BaseIsEmpty>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
|
||||||
|
{
|
||||||
|
if (indexMap.isEmpty()) return {};
|
||||||
|
|
||||||
const auto &map = indexMap.map();
|
CPropertyIndexList changed;
|
||||||
for (auto it = map.begin(); it != map.end(); ++it)
|
const auto &map = indexMap.map();
|
||||||
{
|
for (auto it = map.begin(); it != map.end(); ++it)
|
||||||
const CVariant value = it.value().toCVariant();
|
|
||||||
const CPropertyIndex index = it.key();
|
|
||||||
if (skipEqualValues)
|
|
||||||
{
|
|
||||||
bool equal = obj.equalsPropertyByIndex(value, index);
|
|
||||||
if (equal) { continue; }
|
|
||||||
}
|
|
||||||
obj.setPropertyByIndex(value, index);
|
|
||||||
o_changed.push_back(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
template <class T, class...>
|
|
||||||
void Default::setPropertyByIndex(T &obj, const CVariant &variant, const CPropertyIndex &index, Default::EnableIfEmptyBase<T>)
|
|
||||||
{
|
{
|
||||||
if (index.isMyself())
|
const CVariant value = it.value().toCVariant();
|
||||||
|
const CPropertyIndex index = it.key();
|
||||||
|
if (skipEqualValues)
|
||||||
{
|
{
|
||||||
obj.convertFromCVariant(variant);
|
bool equal = derived()->equalsPropertyByIndex(value, index);
|
||||||
return;
|
if (equal) { continue; }
|
||||||
}
|
}
|
||||||
|
derived()->setPropertyByIndex(value, index);
|
||||||
|
changed.push_back(index);
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
template <class Derived, bool BaseIsEmpty>
|
||||||
|
void Index<Derived, BaseIsEmpty>::setPropertyByIndex(const CVariant &variant, const CPropertyIndex &index)
|
||||||
|
{
|
||||||
|
if (index.isMyself())
|
||||||
|
{
|
||||||
|
derived()->convertFromCVariant(variant);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// not all classes have implemented nesting
|
// not all classes have implemented nesting
|
||||||
const QString m = QString("Property by index not found (setter), index: ").append(index.toQString());
|
const QString m = QString("Property by index not found (setter), index: ").append(index.toQString());
|
||||||
qFatal("%s", qPrintable(m));
|
qFatal("%s", qPrintable(m));
|
||||||
}
|
}
|
||||||
template <class T, class...>
|
template <class Derived, bool BaseIsEmpty>
|
||||||
void Default::propertyByIndex(const T &obj, const CPropertyIndex &index, CVariant &o_property, Default::EnableIfEmptyBase<T>)
|
CVariant Index<Derived, BaseIsEmpty>::propertyByIndex(const CPropertyIndex &index) const
|
||||||
|
{
|
||||||
|
if (index.isMyself())
|
||||||
{
|
{
|
||||||
if (index.isMyself())
|
return derived()->toCVariant();
|
||||||
{
|
}
|
||||||
o_property = obj.toCVariant();
|
using Base = CValueObject<Derived, typename Derived::base_type>;
|
||||||
return;
|
auto i = index.frontCasted<typename CValueObject<Derived, typename Derived::base_type>::ColumnIndex>();
|
||||||
}
|
switch (i)
|
||||||
using Base = CValueObject<T, typename T::base_type>;
|
{
|
||||||
auto i = index.frontCasted<typename CValueObject<T, typename T::base_type>::ColumnIndex>();
|
case Base::IndexIcon:
|
||||||
switch (i)
|
return CVariant::from(derived()->toIcon());
|
||||||
{
|
case Base::IndexPixmap:
|
||||||
case Base::IndexIcon:
|
return CVariant::from(derived()->toPixmap());
|
||||||
o_property = CVariant::from(obj.toIcon());
|
case Base::IndexString:
|
||||||
return;
|
return CVariant(derived()->toQString());
|
||||||
case Base::IndexPixmap:
|
default:
|
||||||
o_property = CVariant::from(obj.toPixmap());
|
break;
|
||||||
return;
|
}
|
||||||
case Base::IndexString:
|
|
||||||
o_property = CVariant(obj.toQString());
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not all classes have implemented nesting
|
// not all classes have implemented nesting
|
||||||
const QString m = QString("Property by index not found, index: ").append(index.toQString());
|
const QString m = QString("Property by index not found, index: ").append(index.toQString());
|
||||||
qFatal("%s", qPrintable(m));
|
qFatal("%s", qPrintable(m));
|
||||||
}
|
return {};
|
||||||
template <class T, class...>
|
}
|
||||||
QString Default::propertyByIndexAsString(const T &obj, const CPropertyIndex &index, bool i18n, Default::EnableIfEmptyBase<T>)
|
template <class Derived, bool BaseIsEmpty>
|
||||||
{
|
QString Index<Derived, BaseIsEmpty>::propertyByIndexAsString(const CPropertyIndex &index, bool i18n) const
|
||||||
// default implementation, requires propertyByIndex
|
{
|
||||||
return obj.propertyByIndex(index).toQString(i18n);
|
// default implementation, requires propertyByIndex
|
||||||
}
|
return derived()->propertyByIndex(index).toQString(i18n);
|
||||||
template <class T, class...>
|
}
|
||||||
bool Default::equalsPropertyByIndex(const T &obj, const CVariant &compareValue, const CPropertyIndex &index, Default::EnableIfEmptyBase<T>)
|
template <class Derived, bool BaseIsEmpty>
|
||||||
{
|
bool Index<Derived, BaseIsEmpty>::equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const
|
||||||
return obj.propertyByIndex(index) == compareValue;
|
{
|
||||||
}
|
return derived()->propertyByIndex(index) == compareValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user