diff --git a/toonz/sources/common/tfx/tmacrofx.cpp b/toonz/sources/common/tfx/tmacrofx.cpp index 2759545..4d4c2f7 100644 --- a/toonz/sources/common/tfx/tmacrofx.cpp +++ b/toonz/sources/common/tfx/tmacrofx.cpp @@ -220,9 +220,9 @@ TFx *TMacroFx::clone(bool recursive) const { assert(fx); clones[i] = fx->clone(false); assert(table.count(fx) == 0); - table[fx] = i; + table[fx] = i; if (fx == m_root.getPointer()) rootIndex = i; - TFx *linkedFx = fx->getLinkedFx(); + TFx *linkedFx = fx->getLinkedFx(); if (linkedFx && table.find(linkedFx) != table.end()) clones[i]->linkParams(clones[table[linkedFx]].getPointer()); } @@ -476,9 +476,14 @@ void TMacroFx::loadData(TIStream &is) { std::string tagName; while (is.openChild(tagName)) { if (tagName == "root") { + // set the flag here in order to prevent the leaf macro fx in the tree + // to try to link this fx before finish loading + m_isLoading = true; TPersist *p = 0; is >> p; m_root = dynamic_cast(p); + // release the flag + m_isLoading = false; } else if (tagName == "nodes") { while (!is.eos()) { TPersist *p = 0; @@ -495,6 +500,11 @@ void TMacroFx::loadData(TIStream &is) { // collecting params just after loading nodes since they may need on // loading "super" tag in case it is linked with another macro fx collectParams(this); + // link parameters if there is a waiting fx for linking with this + if (m_waitingLinkFx) { + m_waitingLinkFx->linkParams(this); + m_waitingLinkFx = nullptr; + } } else if (tagName == "ports") { int i = 0; while (is.matchTag(tagName)) { @@ -567,5 +577,20 @@ void TMacroFx::saveData(TOStream &os) { } //-------------------------------------------------- + +void TMacroFx::linkParams(TFx *src) { + // in case the src fx is not yet loaded + // (i.e. we are in loading the src fx tree), + // wait linking the parameters until loading src is completed + TMacroFx *srcMacroFx = dynamic_cast(src); + if (srcMacroFx && srcMacroFx->isLoading()) { + srcMacroFx->setWaitingLinkFx(this); + return; + } + + TFx::linkParams(src); +} + +//-------------------------------------------------- FX_IDENTIFIER(TMacroFx, "macroFx") // FX_IDENTIFIER_IS_HIDDEN(TMacroFx, "macroFx") diff --git a/toonz/sources/include/tfx.h b/toonz/sources/include/tfx.h index 734613f..8149fd1 100644 --- a/toonz/sources/include/tfx.h +++ b/toonz/sources/include/tfx.h @@ -373,7 +373,7 @@ public: TFx *clone(TFx *fx, bool recursive) const; void unlinkParams(); - void linkParams(TFx *src); + virtual void linkParams(TFx *src); TFx *getLinkedFx() const; @@ -543,7 +543,7 @@ inline std::string TFx::getFxType() const { return getDeclaration()->getId(); } //------------------------------------------------------------------- #define FX_DECLARATION(T) \ - \ + \ public: \ const TPersistDeclaration *getDeclaration() const override; diff --git a/toonz/sources/include/tmacrofx.h b/toonz/sources/include/tmacrofx.h index 334459b..951b265 100644 --- a/toonz/sources/include/tmacrofx.h +++ b/toonz/sources/include/tmacrofx.h @@ -30,6 +30,9 @@ class DVAPI TMacroFx final : public TRasterFx { bool isaLeaf(TFx *fx) const; + bool m_isLoading = false; + TMacroFx *m_waitingLinkFx = nullptr; + public: static bool analyze(const std::vector &fxs, TFxP &root, std::vector &roots, std::vector &leafs); @@ -78,6 +81,10 @@ public: void compatibilityTranslatePort(int majorVersion, int minorVersion, std::string &portName) override; + void linkParams(TFx *src) override; + bool isLoading() { return m_isLoading; } + void setWaitingLinkFx(TMacroFx *linkFx) { m_waitingLinkFx = linkFx; } + private: // non implementati TMacroFx(const TMacroFx &);