diff --git a/toonz/sources/common/tmetaimage/tmetaimage.cpp b/toonz/sources/common/tmetaimage/tmetaimage.cpp index f7af5d5..b3e48e8 100644 --- a/toonz/sources/common/tmetaimage/tmetaimage.cpp +++ b/toonz/sources/common/tmetaimage/tmetaimage.cpp @@ -5,16 +5,23 @@ //--------------------------------------------------------- -TMetaObject::TMetaObject(const TStringId &typeName): +TMetaObject::TMetaObject(const TMetaObject &other): m_handler(), - m_data(*this) + m_data(*this, other.data()) + { setType(other.getType()); } + +//--------------------------------------------------------- + +TMetaObject::TMetaObject(const TStringId &typeName, const TVariant &data): + m_handler(), + m_data(*this, data) { setType(typeName); } //--------------------------------------------------------- -TMetaObject::TMetaObject(const std::string &typeName): +TMetaObject::TMetaObject(const std::string &typeName, const TVariant &data): m_handler(), - m_data(*this) + m_data(*this, data) { setType(typeName); } //--------------------------------------------------------- @@ -43,6 +50,18 @@ TMetaObject::onVariantChanged(const TVariant &value) //--------------------------------------------------------- +void +TMetaObject::setDefaults() + { m_data.reset(); if (m_handler) m_handler->setDefaults(); } + +//--------------------------------------------------------- + +TMetaObject* +TMetaObject::clone() const + { return new TMetaObject(*this); } + +//--------------------------------------------------------- + TMetaObject::Registry& TMetaObject::registry() { static Registry registry; @@ -74,9 +93,13 @@ TMetaImage::TMetaImage() //--------------------------------------------------------- -TMetaImage::TMetaImage(const TMetaImage &other): - m_objects(*Reader(other)) - { } +TMetaImage::TMetaImage(const TMetaImage &other) { + Reader reader(other); + m_objects.reserve(reader->size()); + for(TMetaObjectListCW::iterator i = reader->begin(); i != reader->end(); ++i) + if (*i) + m_objects.push_back( TMetaObjectP((*i)->clone()) ); +} //--------------------------------------------------------- diff --git a/toonz/sources/image/tzm/tiio_tzm.cpp b/toonz/sources/image/tzm/tiio_tzm.cpp index 7a8421f..0435259 100644 --- a/toonz/sources/image/tzm/tiio_tzm.cpp +++ b/toonz/sources/image/tzm/tiio_tzm.cpp @@ -58,7 +58,7 @@ namespace { TVariant &frameData = m_data["frames"][frameId.expand()]; TVariant &objectsData = frameData["objects"]; objectsData.setType(TVariant::List); - for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i) { + for(TMetaObjectListCW::iterator i = reader->begin(); i != reader->end(); ++i) { if (*i) { TVariant &objectData = objectsData[ objectsData.size() ]; objectData["type"].setString( (*i)->getTypeName() ); @@ -162,7 +162,7 @@ namespace { for(int j = 0; j < objectsData.size(); ++j) { const TVariant &objectData = objectsData[j]; if (!objectData["type"].getString().empty()) { - TMetaObjectR obj( new TMetaObject(objectData["type"].getString()) ); + TMetaObjectP obj( new TMetaObject(objectData["type"].getString()) ); obj->data() = objectData["data"]; writer->push_back(obj); } diff --git a/toonz/sources/include/tmetaimage.h b/toonz/sources/include/tmetaimage.h index f172e48..09a5cc0 100644 --- a/toonz/sources/include/tmetaimage.h +++ b/toonz/sources/include/tmetaimage.h @@ -7,6 +7,7 @@ #include "tthreadmessage.h" #include "tsmartpointer.h" #include "tvariant.h" +#include "tconstwrapper.h" #include #include @@ -28,9 +29,11 @@ class TMetaObject; class TMetaObjectHandler; -typedef TSmartPointerT TMetaObjectP; -typedef TSmartRefT TMetaObjectR; -typedef std::vector TMetaObjectRefList; +typedef TSmartPointerT TMetaObjectP; //!< smart pointer to TMetaObject +typedef TMetaObjectP::Holder TMetaObjectH; //!< smart holder of TMetaObject +typedef TMetaObjectP::Const TMetaObjectPC; //!< smart pointer to constant TMetaObject +typedef std::vector TMetaObjectList; +typedef TConstArrayWrapperT TMetaObjectListCW; // TMetaObjectListConstWrapper //------------------------------------------------------------------- @@ -56,9 +59,11 @@ private: TMetaObjectHandler *m_handler; TVariant m_data; + TMetaObject(const TMetaObject &other); + public: - explicit TMetaObject(const TStringId &typeName = TStringId()); - explicit TMetaObject(const std::string &typeName); + explicit TMetaObject(const TStringId &typeName = TStringId(), const TVariant &data = TVariant()); + explicit TMetaObject(const std::string &typeName, const TVariant &data = TVariant()); ~TMetaObject(); void setType(const TStringId &name); @@ -75,6 +80,8 @@ public: inline TVariant& data() { return m_data; } + void setDefaults(); + template const T* getHandler() const { return dynamic_cast(m_handler); } @@ -82,8 +89,13 @@ public: T* getHandler() { return dynamic_cast(m_handler); } + TMetaObjectHandler* handler() { return m_handler; } + const TMetaObjectHandler* handler() const { return m_handler; } + void onVariantChanged(const TVariant &value) override; + virtual TMetaObject* clone() const; + static Registry& registry(); static void registerType(const TStringId &name, Fabric fabric); static void unregisterType(const TStringId &name); @@ -96,9 +108,18 @@ public: //------------------------------------------------------------------- class DVAPI TMetaObjectHandler { +protected: + class LockEvents { + public: + TMetaObjectHandler &owner; + explicit LockEvents(TMetaObjectHandler &owner): + owner(owner) { ++owner.m_locks; } + ~LockEvents() { --owner.m_locks; } + }; + private: TMetaObject &m_object; - TAtomicVar m_fixingData; + TAtomicVar m_locks; public: TMetaObjectHandler(TMetaObject &object): @@ -115,18 +136,17 @@ public: { return object().data(); } protected: + virtual void onSetDefaults() { } virtual void onDataChanged(const TVariant &value) { } virtual void onFixData() { } public: + void setDefaults() + { onSetDefaults(); } void dataChanged(const TVariant &value) - { if (m_fixingData == 0) onDataChanged(value); } - - void fixData() { - ++m_fixingData; - if (m_fixingData == 1) onFixData(); - --m_fixingData; - } + { if (m_locks == 0) onDataChanged(value); } + void fixData() + { LockEvents lock(*this); onFixData(); } }; //------------------------------------------------------------------- @@ -138,16 +158,19 @@ public: class Reader: public QReadLocker { private: const TMetaImage &m_image; + const TMetaObjectListCW m_objects; public: Reader(const TMetaImage &image): - QReadLocker(&image.m_rwLock), m_image(image) { } + QReadLocker(&image.m_rwLock), + m_image(image), + m_objects(image.m_objects) { } const TMetaImage& image() const { return m_image; } - const TMetaObjectRefList& get() const - { return m_image.m_objects; } - const TMetaObjectRefList& operator*() const + const TMetaObjectListCW& get() const + { return m_objects; } + const TMetaObjectListCW& operator*() const { return get(); } - const TMetaObjectRefList* operator->() const + const TMetaObjectListCW* operator->() const { return &get(); } }; @@ -159,20 +182,21 @@ public: QWriteLocker(&image.m_rwLock), m_image(image) { } TMetaImage& image() const { return m_image; } - TMetaObjectRefList& get() const + TMetaObjectList& get() const { return m_image.m_objects; } - TMetaObjectRefList& operator*() const + TMetaObjectList& operator*() const { return get(); } - TMetaObjectRefList* operator->() const + TMetaObjectList* operator->() const { return &get(); } }; private: mutable QReadWriteLock m_rwLock; - TMetaObjectRefList m_objects; + TMetaObjectList m_objects; - //! not implemented TMetaImage(const TMetaImage &other); + + //! not implemented TMetaImage &operator=(const TMetaImage &) { return *this; } public: diff --git a/toonz/sources/tnztools/modifiers/modifierassistants.cpp b/toonz/sources/tnztools/modifiers/modifierassistants.cpp index 99a8ad8..03a71c0 100644 --- a/toonz/sources/tnztools/modifiers/modifierassistants.cpp +++ b/toonz/sources/tnztools/modifiers/modifierassistants.cpp @@ -86,7 +86,7 @@ TModifierAssistants::scanAssistants( if (draw) { glPushMatrix(); tglMultMatrix(imageToTrack); } TMetaImage::Reader reader(*metaImage); - for(TMetaObjectRefList::const_iterator i = reader->begin(); i != reader->end(); ++i) + for(TMetaObjectListCW::iterator i = reader->begin(); i != reader->end(); ++i) if (*i) if (const TAssistant *assistant = (*i)->getHandler()) {