|
|
ae9154 |
#pragma once
|
|
|
ae9154 |
|
|
|
ae9154 |
#ifndef TMETAIMAGE_INCLUDED
|
|
|
ae9154 |
#define TMETAIMAGE_INCLUDED
|
|
|
ae9154 |
|
|
|
ae9154 |
#include "timage.h"
|
|
|
ae9154 |
#include "tthreadmessage.h"
|
|
|
ae9154 |
#include "tsmartpointer.h"
|
|
|
ae9154 |
#include "tvariant.h"
|
|
|
57d357 |
#include "tconstwrapper.h"
|
|
|
ae9154 |
|
|
|
4da757 |
#include <qstring></qstring>
|
|
|
ae9154 |
#include <qreadlocker></qreadlocker>
|
|
|
ae9154 |
#include <qwritelocker></qwritelocker>
|
|
|
ae9154 |
#include <qreadwritelock></qreadwritelock>
|
|
|
ae9154 |
|
|
|
ae9154 |
#include <string></string>
|
|
|
ae9154 |
|
|
|
ae9154 |
#undef DVAPI
|
|
|
ae9154 |
#undef DVVAR
|
|
|
ae9154 |
#ifdef TMETAIMAGE_EXPORTS
|
|
|
ae9154 |
#define DVAPI DV_EXPORT_API
|
|
|
ae9154 |
#define DVVAR DV_EXPORT_VAR
|
|
|
ae9154 |
#else
|
|
|
ae9154 |
#define DVAPI DV_IMPORT_API
|
|
|
ae9154 |
#define DVVAR DV_IMPORT_VAR
|
|
|
ae9154 |
#endif
|
|
|
ae9154 |
|
|
|
ae9154 |
//-------------------------------------------------------------------
|
|
|
ae9154 |
|
|
|
ae9154 |
class TMetaObject;
|
|
|
ae9154 |
class TMetaObjectHandler;
|
|
|
57d357 |
typedef TSmartPointerT<tmetaobject> TMetaObjectP; //!< smart pointer to TMetaObject</tmetaobject>
|
|
|
57d357 |
typedef TMetaObjectP::Holder TMetaObjectH; //!< smart holder of TMetaObject
|
|
|
57d357 |
typedef TMetaObjectP::Const TMetaObjectPC; //!< smart pointer to constant TMetaObject
|
|
|
57d357 |
typedef std::vector<tmetaobjectp> TMetaObjectList;</tmetaobjectp>
|
|
|
57d357 |
typedef TConstArrayWrapperT<tmetaobjectpc, tmetaobjectp=""> TMetaObjectListCW; // TMetaObjectListConstWrapper</tmetaobjectpc,>
|
|
|
ae9154 |
|
|
|
ae9154 |
//-------------------------------------------------------------------
|
|
|
ae9154 |
|
|
|
4da757 |
class DVAPI TMetaObjectType {
|
|
|
4da757 |
public:
|
|
|
4da757 |
const TStringId name;
|
|
|
4da757 |
|
|
|
4da757 |
TMetaObjectType(const TStringId &name);
|
|
|
4da757 |
virtual ~TMetaObjectType();
|
|
|
4da757 |
|
|
|
4da757 |
void registerAlias(const TStringId &alias);
|
|
|
4da757 |
void unregisterAlias(const TStringId &alias);
|
|
|
4da757 |
|
|
|
4da757 |
virtual TMetaObjectHandler* createHandler(TMetaObject &obj) const
|
|
|
4da757 |
{ return 0; }
|
|
|
4da757 |
virtual QString getLocalName() const
|
|
|
4da757 |
{ return QString::fromStdString(name.str()); }
|
|
|
4da757 |
};
|
|
|
4da757 |
|
|
|
4da757 |
//-------------------------------------------------------------------
|
|
|
4da757 |
|
|
|
ae9154 |
class DVAPI TMetaObject: public TSmartObject, public TVariantOwner {
|
|
|
ae9154 |
public:
|
|
|
249386 |
typedef TMetaObjectHandler* (*Fabric)(TMetaObject&);
|
|
|
4da757 |
typedef std::map<tstringid, const="" tmetaobjecttype*=""> Registry;</tstringid,>
|
|
|
ae9154 |
|
|
|
4da757 |
struct LinkedList {
|
|
|
4da757 |
TMetaObject *first, *last;
|
|
|
4da757 |
LinkedList(): first(), last() { }
|
|
|
ae9154 |
};
|
|
|
4da757 |
typedef std::map<tstringid, linkedlist=""> LinkedMap;</tstringid,>
|
|
|
4da757 |
typedef LinkedMap::iterator LinkedMapEntry;
|
|
|
ae9154 |
|
|
|
ae9154 |
private:
|
|
|
4da757 |
LinkedMapEntry m_typeLink;
|
|
|
4da757 |
TMetaObject *m_previous, *m_next;
|
|
|
4da757 |
const TMetaObjectType *m_typeDesc;
|
|
|
ae9154 |
TMetaObjectHandler *m_handler;
|
|
|
ae9154 |
TVariant m_data;
|
|
|
ae9154 |
|
|
|
4da757 |
static Registry& registry();
|
|
|
4da757 |
static LinkedMap& linkedMap();
|
|
|
4da757 |
|
|
|
4da757 |
static void rewrapAll(const TStringId &type);
|
|
|
4da757 |
void rewrap(const TStringId &type);
|
|
|
4da757 |
|
|
|
4da757 |
void linkToType(const TStringId &type);
|
|
|
4da757 |
void unlinkFromType();
|
|
|
4da757 |
|
|
|
57d357 |
TMetaObject(const TMetaObject &other);
|
|
|
57d357 |
|
|
|
ae9154 |
public:
|
|
|
57d357 |
explicit TMetaObject(const TStringId &typeName = TStringId(), const TVariant &data = TVariant());
|
|
|
57d357 |
explicit TMetaObject(const std::string &typeName, const TVariant &data = TVariant());
|
|
|
ae9154 |
~TMetaObject();
|
|
|
ae9154 |
|
|
|
ae9154 |
void setType(const TStringId &name);
|
|
|
ae9154 |
inline void setType(const std::string &name)
|
|
|
ae9154 |
{ setType(TStringId(name)); }
|
|
|
ae9154 |
inline void resetType()
|
|
|
ae9154 |
{ setType(TStringId()); }
|
|
|
4da757 |
|
|
|
4da757 |
inline const TMetaObjectType* getTypeDesc() const
|
|
|
4da757 |
{ return m_typeDesc; }
|
|
|
ae9154 |
inline const TStringId& getType() const
|
|
|
4da757 |
{ return m_typeLink->first; }
|
|
|
ae9154 |
inline const std::string& getTypeName() const
|
|
|
4da757 |
{ return getType().str(); }
|
|
|
ae9154 |
inline const TVariant& data() const
|
|
|
ae9154 |
{ return m_data; }
|
|
|
ae9154 |
inline TVariant& data()
|
|
|
ae9154 |
{ return m_data; }
|
|
|
ae9154 |
|
|
|
57d357 |
void setDefaults();
|
|
|
57d357 |
|
|
|
ae9154 |
template<typename t=""></typename>
|
|
|
ae9154 |
const T* getHandler() const
|
|
|
249386 |
{ return dynamic_cast<const t*="">(m_handler); }</const>
|
|
|
ae9154 |
template<typename t=""></typename>
|
|
|
ae9154 |
T* getHandler()
|
|
|
ae9154 |
{ return dynamic_cast<t*>(m_handler); }</t*>
|
|
|
ae9154 |
|
|
|
57d357 |
TMetaObjectHandler* handler() { return m_handler; }
|
|
|
57d357 |
const TMetaObjectHandler* handler() const { return m_handler; }
|
|
|
57d357 |
|
|
|
ae9154 |
void onVariantChanged(const TVariant &value) override;
|
|
|
ae9154 |
|
|
|
57d357 |
virtual TMetaObject* clone() const;
|
|
|
57d357 |
|
|
|
4da757 |
public:
|
|
|
4da757 |
static const Registry& getRegistry() { return registry(); }
|
|
|
4da757 |
static void registerType(const TStringId &name, const TMetaObjectType &type); //!< register new or add alias
|
|
|
4da757 |
static void unregisterType(const TStringId &name); //!< unregister single alias
|
|
|
4da757 |
static void unregisterType(const TMetaObjectType &type); //!< unregister all aliases
|
|
|
4da757 |
static const TMetaObjectType* findType(const TStringId &name);
|
|
|
ae9154 |
};
|
|
|
ae9154 |
|
|
|
ae9154 |
//-------------------------------------------------------------------
|
|
|
ae9154 |
|
|
|
ae9154 |
class DVAPI TMetaObjectHandler {
|
|
|
57d357 |
protected:
|
|
|
57d357 |
class LockEvents {
|
|
|
57d357 |
public:
|
|
|
57d357 |
TMetaObjectHandler &owner;
|
|
|
57d357 |
explicit LockEvents(TMetaObjectHandler &owner):
|
|
|
57d357 |
owner(owner) { ++owner.m_locks; }
|
|
|
57d357 |
~LockEvents() { --owner.m_locks; }
|
|
|
57d357 |
};
|
|
|
57d357 |
|
|
|
ae9154 |
private:
|
|
|
ae9154 |
TMetaObject &m_object;
|
|
|
4da757 |
const TMetaObjectType &m_typeDesc;
|
|
|
57d357 |
TAtomicVar m_locks;
|
|
|
ae9154 |
|
|
|
ae9154 |
public:
|
|
|
ae9154 |
TMetaObjectHandler(TMetaObject &object):
|
|
|
4da757 |
m_object(object),
|
|
|
4da757 |
m_typeDesc(*m_object.getTypeDesc())
|
|
|
4da757 |
{ assert(m_object.getTypeDesc()); }
|
|
|
ae9154 |
virtual ~TMetaObjectHandler() { }
|
|
|
ae9154 |
|
|
|
4da757 |
inline const TMetaObjectType& getTypeDesc() const
|
|
|
4da757 |
{ return m_typeDesc; }
|
|
|
4da757 |
inline const TStringId& getType() const
|
|
|
4da757 |
{ return getTypeDesc().name; }
|
|
|
4da757 |
inline const std::string& getTypeName() const
|
|
|
4da757 |
{ return getType().str(); }
|
|
|
ae9154 |
inline const TMetaObject& object() const
|
|
|
ae9154 |
{ return m_object; }
|
|
|
ae9154 |
inline TMetaObject& object()
|
|
|
ae9154 |
{ return m_object; }
|
|
|
4da757 |
inline const TStringId& getAlias() const
|
|
|
4da757 |
{ return object().getType(); }
|
|
|
4da757 |
inline const std::string& getAliasName() const
|
|
|
4da757 |
{ return getAlias().str(); }
|
|
|
ae9154 |
inline const TVariant& data() const
|
|
|
ae9154 |
{ return object().data(); }
|
|
|
ae9154 |
inline TVariant& data()
|
|
|
ae9154 |
{ return object().data(); }
|
|
|
ae9154 |
|
|
|
9cf8be |
protected:
|
|
|
57d357 |
virtual void onSetDefaults() { }
|
|
|
ae9154 |
virtual void onDataChanged(const TVariant &value) { }
|
|
|
9cf8be |
virtual void onFixData() { }
|
|
|
9cf8be |
|
|
|
9cf8be |
public:
|
|
|
da847a |
void setDefaults() {
|
|
|
da847a |
{ LockEvents lock(*this); onSetDefaults(); }
|
|
|
da847a |
data().touch();
|
|
|
da847a |
}
|
|
|
9cf8be |
void dataChanged(const TVariant &value)
|
|
|
3a19fe |
{ LockEvents lock(*this); if (m_locks == 1) onDataChanged(value); }
|
|
|
57d357 |
void fixData()
|
|
|
57d357 |
{ LockEvents lock(*this); onFixData(); }
|
|
|
ae9154 |
};
|
|
|
ae9154 |
|
|
|
ae9154 |
//-------------------------------------------------------------------
|
|
|
ae9154 |
|
|
|
ae9154 |
//! An image containing an assistants for painting.
|
|
|
ae9154 |
|
|
|
ae9154 |
class DVAPI TMetaImage final : public TImage {
|
|
|
ae9154 |
public:
|
|
|
ae9154 |
class Reader: public QReadLocker {
|
|
|
ae9154 |
private:
|
|
|
ae9154 |
const TMetaImage &m_image;
|
|
|
57d357 |
const TMetaObjectListCW m_objects;
|
|
|
ae9154 |
public:
|
|
|
ae9154 |
Reader(const TMetaImage &image):
|
|
|
57d357 |
QReadLocker(&image.m_rwLock),
|
|
|
57d357 |
m_image(image),
|
|
|
57d357 |
m_objects(image.m_objects) { }
|
|
|
ae9154 |
const TMetaImage& image() const
|
|
|
ae9154 |
{ return m_image; }
|
|
|
57d357 |
const TMetaObjectListCW& get() const
|
|
|
57d357 |
{ return m_objects; }
|
|
|
57d357 |
const TMetaObjectListCW& operator*() const
|
|
|
ae9154 |
{ return get(); }
|
|
|
57d357 |
const TMetaObjectListCW* operator->() const
|
|
|
ae9154 |
{ return &get(); }
|
|
|
ae9154 |
};
|
|
|
ae9154 |
|
|
|
ae9154 |
class Writer: public QWriteLocker {
|
|
|
ae9154 |
private:
|
|
|
ae9154 |
TMetaImage &m_image;
|
|
|
ae9154 |
public:
|
|
|
ae9154 |
Writer(TMetaImage &image):
|
|
|
ae9154 |
QWriteLocker(&image.m_rwLock), m_image(image) { }
|
|
|
ae9154 |
TMetaImage& image() const
|
|
|
ae9154 |
{ return m_image; }
|
|
|
57d357 |
TMetaObjectList& get() const
|
|
|
ae9154 |
{ return m_image.m_objects; }
|
|
|
57d357 |
TMetaObjectList& operator*() const
|
|
|
ae9154 |
{ return get(); }
|
|
|
57d357 |
TMetaObjectList* operator->() const
|
|
|
ae9154 |
{ return &get(); }
|
|
|
ae9154 |
};
|
|
|
ae9154 |
|
|
|
ae9154 |
private:
|
|
|
ae9154 |
mutable QReadWriteLock m_rwLock;
|
|
|
57d357 |
TMetaObjectList m_objects;
|
|
|
ae9154 |
|
|
|
ae9154 |
TMetaImage(const TMetaImage &other);
|
|
|
57d357 |
|
|
|
57d357 |
//! not implemented
|
|
|
ae9154 |
TMetaImage &operator=(const TMetaImage &) { return *this; }
|
|
|
ae9154 |
|
|
|
ae9154 |
public:
|
|
|
ae9154 |
TMetaImage();
|
|
|
ae9154 |
~TMetaImage();
|
|
|
ae9154 |
|
|
|
ae9154 |
//! Return the image type
|
|
|
ae9154 |
TImage::Type getType() const override { return TImage::META; }
|
|
|
ae9154 |
//! Return a clone of image
|
|
|
ae9154 |
TImage* cloneImage() const override;
|
|
|
ae9154 |
//! Return the bbox of the image
|
|
|
ae9154 |
TRectD getBBox() const override;
|
|
|
ae9154 |
};
|
|
|
ae9154 |
|
|
|
ae9154 |
#endif
|