mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-21 12:55:31 +08:00
Issue #77 Move mixin classes to separate files
By separating them from unrelated code, their dependents can use them without depending on unrelated code, which in turn helps to reduce cyclic dependencies.
This commit is contained in:
@@ -12,13 +12,14 @@
|
||||
#define BLACKMISC_PROPERTYINDEXVARIANTMAP_H
|
||||
|
||||
#include "blackmisc/blackmiscexport.h"
|
||||
#include "blackmisc/compare.h"
|
||||
#include "blackmisc/dbus.h"
|
||||
#include "blackmisc/mixin/mixincompare.h"
|
||||
#include "blackmisc/mixin/mixindbus.h"
|
||||
#include "blackmisc/inheritancetraits.h"
|
||||
#include "blackmisc/predicates.h"
|
||||
#include "blackmisc/propertyindex.h"
|
||||
#include "blackmisc/propertyindexlist.h"
|
||||
#include "blackmisc/stringutils.h"
|
||||
#include "blackmisc/mixin/mixinstring.h"
|
||||
#include "blackmisc/mixin/mixinmetatype.h"
|
||||
#include "blackmisc/variant.h"
|
||||
|
||||
#include <QDBusArgument>
|
||||
@@ -33,93 +34,6 @@
|
||||
|
||||
namespace BlackMisc
|
||||
{
|
||||
class CPropertyIndexVariantMap;
|
||||
|
||||
namespace Mixin
|
||||
{
|
||||
/*!
|
||||
* CRTP class template from which a derived class can inherit property indexing functions.
|
||||
*
|
||||
* This is only a placeholder for future support of implementing property indexing through the tuple system.
|
||||
* At the moment, it just implements the default properties: String, Icon, and Pixmap.
|
||||
*/
|
||||
template <class Derived>
|
||||
class Index
|
||||
{
|
||||
public:
|
||||
//! Base class enums
|
||||
enum ColumnIndex
|
||||
{
|
||||
IndexPixmap = 10, // manually set to avoid circular dependencies
|
||||
IndexIcon,
|
||||
IndexString
|
||||
};
|
||||
|
||||
//! Update by variant map
|
||||
//! \return number of values changed, with skipEqualValues equal values will not be changed
|
||||
CPropertyIndexList apply(const CPropertyIndexVariantMap &indexMap, bool skipEqualValues = false);
|
||||
|
||||
//! Set property by index
|
||||
void setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant);
|
||||
|
||||
//! Property by index
|
||||
CVariant propertyByIndex(const CPropertyIndex &index) const;
|
||||
|
||||
//! Property by index as String
|
||||
QString propertyByIndexAsString(const CPropertyIndex &index, bool i18n = false) const;
|
||||
|
||||
//! Compare for index
|
||||
int comparePropertyByIndex(const CPropertyIndex &index, const Derived &compareValue) const;
|
||||
|
||||
//! Is given variant equal to value of property index?
|
||||
bool equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const;
|
||||
|
||||
private:
|
||||
const Derived *derived() const { return static_cast<const Derived *>(this); }
|
||||
Derived *derived() { return static_cast<Derived *>(this); }
|
||||
|
||||
template <typename T, std::enable_if_t<std::is_default_constructible<T>::value, int> = 0>
|
||||
CVariant myself() const { return CVariant::from(*derived()); }
|
||||
template <typename T, std::enable_if_t<std::is_default_constructible<T>::value, int> = 0>
|
||||
void myself(const CVariant &variant) { *derived() = variant.to<T>(); }
|
||||
|
||||
template <typename T, std::enable_if_t<! std::is_default_constructible<T>::value, int> = 0>
|
||||
CVariant myself() const { qFatal("isMyself should have been handled before reaching here"); return {}; }
|
||||
template <typename T, std::enable_if_t<! std::is_default_constructible<T>::value, int> = 0>
|
||||
void myself(const CVariant &) { qFatal("isMyself should have been handled before reaching here"); }
|
||||
|
||||
template <typename T>
|
||||
CVariant basePropertyByIndex(const T *base, const CPropertyIndex &index) const { return base->propertyByIndex(index); }
|
||||
template <typename T>
|
||||
void baseSetPropertyByIndex(T *base, const CVariant &var, const CPropertyIndex &index) { base->setPropertyByIndex(index, var); }
|
||||
|
||||
CVariant basePropertyByIndex(const void *, const CPropertyIndex &index) const
|
||||
{
|
||||
qFatal("%s", qPrintable("Property by index not found, index: " + index.toQString())); return {};
|
||||
}
|
||||
|
||||
void baseSetPropertyByIndex(void *, const CVariant &, const CPropertyIndex &index)
|
||||
{
|
||||
qFatal("%s", qPrintable("Property by index not found (setter), index: " + index.toQString()));
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* When a derived class and a base class both inherit from Mixin::Index,
|
||||
* the derived class uses this macro to disambiguate the inherited members.
|
||||
*/
|
||||
// *INDENT-OFF*
|
||||
# define BLACKMISC_DECLARE_USING_MIXIN_INDEX(DERIVED) \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::apply; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::setPropertyByIndex; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::propertyByIndex; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::propertyByIndexAsString; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::comparePropertyByIndex; \
|
||||
using ::BlackMisc::Mixin::Index<DERIVED>::equalsPropertyByIndex;
|
||||
// *INDENT-ON*
|
||||
|
||||
} // Mixin
|
||||
|
||||
/*!
|
||||
* Specialized value object compliant map for variants,
|
||||
* based on indexes
|
||||
@@ -225,93 +139,6 @@ namespace BlackMisc
|
||||
//! \copydoc BlackMisc::Mixin::DataStreamByMetaClass::unmarshalFromDataStream
|
||||
void unmarshalFromDataStream(QDataStream &stream);
|
||||
};
|
||||
|
||||
namespace Mixin
|
||||
{
|
||||
template <class Derived>
|
||||
CPropertyIndexList Index<Derived>::apply(const BlackMisc::CPropertyIndexVariantMap &indexMap, bool skipEqualValues)
|
||||
{
|
||||
if (indexMap.isEmpty()) return {};
|
||||
|
||||
CPropertyIndexList changed;
|
||||
const auto &map = indexMap.map();
|
||||
for (auto it = map.begin(); it != map.end(); ++it)
|
||||
{
|
||||
const CVariant value = it.value();
|
||||
const CPropertyIndex index = it.key();
|
||||
if (skipEqualValues)
|
||||
{
|
||||
const bool equal = derived()->equalsPropertyByIndex(value, index);
|
||||
if (equal) { continue; }
|
||||
}
|
||||
derived()->setPropertyByIndex(index, value);
|
||||
changed.push_back(index);
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void Index<Derived>::setPropertyByIndex(const CPropertyIndex &index, const CVariant &variant)
|
||||
{
|
||||
if (index.isMyself())
|
||||
{
|
||||
myself<Derived>(variant);
|
||||
}
|
||||
else
|
||||
{
|
||||
baseSetPropertyByIndex(static_cast<TIndexBaseOfT<Derived> *>(derived()), variant, index);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
CVariant Index<Derived>::propertyByIndex(const CPropertyIndex &index) const
|
||||
{
|
||||
if (index.isMyself()) { return myself<Derived>(); }
|
||||
const auto i = index.frontCasted<ColumnIndex>(); // keep that "auto", otherwise I won's compile
|
||||
switch (i)
|
||||
{
|
||||
case IndexIcon: return CVariant::from(derived()->toIcon());
|
||||
case IndexPixmap: return CVariant::from(derived()->toPixmap());
|
||||
case IndexString: return CVariant(derived()->toQString());
|
||||
default: return basePropertyByIndex(static_cast<const TIndexBaseOfT<Derived> *>(derived()), index);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
QString Index<Derived>::propertyByIndexAsString(const CPropertyIndex &index, bool i18n) const
|
||||
{
|
||||
return derived()->propertyByIndex(index).toQString(i18n);
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
bool Index<Derived>::equalsPropertyByIndex(const CVariant &compareValue, const CPropertyIndex &index) const
|
||||
{
|
||||
return derived()->propertyByIndex(index) == compareValue;
|
||||
}
|
||||
|
||||
template<class Derived>
|
||||
int Index<Derived>::comparePropertyByIndex(const CPropertyIndex &index, const Derived &compareValue) const
|
||||
{
|
||||
if (this == &compareValue) { return 0; }
|
||||
if (index.isMyself()) {
|
||||
// slow, only last resort
|
||||
return derived()->toQString().compare(compareValue.toQString());
|
||||
}
|
||||
|
||||
const auto i = index.frontCasted<ColumnIndex>();
|
||||
switch (i)
|
||||
{
|
||||
case IndexIcon:
|
||||
case IndexPixmap:
|
||||
case IndexString:
|
||||
default:
|
||||
break; // also covers
|
||||
}
|
||||
|
||||
// slow, only last resort
|
||||
return derived()->toQString().compare(compareValue.toQString());
|
||||
}
|
||||
} // Mixin
|
||||
} // ns
|
||||
|
||||
Q_DECLARE_METATYPE(BlackMisc::CPropertyIndexVariantMap)
|
||||
|
||||
Reference in New Issue
Block a user