Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tconst.h"
Toshihiro Shimizu 890ddd
#include "tutil.h"
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tparamcontainer.h"
Toshihiro Shimizu 890ddd
#include "tfxattributes.h"
Toshihiro Shimizu 890ddd
#include "texternfx.h"
Toshihiro Shimizu 890ddd
#include "tpassivecachemanager.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <set></set>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TIStream &operator>>(TIStream &in, TFxP &p) {
Shinya Kitaoka 120a6e
  TPersist *tmp = 0;
Shinya Kitaoka 120a6e
  in >> tmp;
Shinya Kitaoka 120a6e
  p = TFxP(dynamic_cast<tfx *="">(tmp));</tfx>
Shinya Kitaoka 120a6e
  return in;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// namespace {}
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
typedef std::pair<std::string, *="" tfxport=""> NamePort;</std::string,>
Shinya Kitaoka 3bfa54
typedef std::map<std::string, *="" tfxport=""> PortTable;</std::string,>
Shinya Kitaoka 3bfa54
typedef std::vector<nameport> PortArray;</nameport>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class PortNameEq {
Shinya Kitaoka 120a6e
  std::string m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  PortNameEq(const std::string &name) : m_name(name) {}
Shinya Kitaoka 120a6e
  ~PortNameEq() {}
Shinya Kitaoka 120a6e
  bool operator()(const NamePort &np) { return np.first == m_name; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void skipChild(TIStream &is) {
Shinya Kitaoka 120a6e
  while (!is.eos()) {
Shinya Kitaoka 120a6e
    std::string dummy = is.getString();
Shinya Kitaoka 120a6e
    std::string tagName;
Shinya Kitaoka 120a6e
    while (is.openChild(tagName)) {
Shinya Kitaoka 120a6e
      skipChild(is);
Shinya Kitaoka 120a6e
      if (is.isBeginEndTag()) is.matchTag(tagName);
Shinya Kitaoka 120a6e
      is.closeChild();
Shinya Kitaoka 120a6e
    }
manongjohn 9e8e63
    if (is.isBeginEndTag()) is.matchTag(tagName);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD updateDagPosition(const TPointD &pos, const VersionNumber &tnzVersion) {
Shinya Kitaoka 120a6e
  if (tnzVersion < VersionNumber(1, 16)) return TConst::nowhere;
Shinya Kitaoka 120a6e
  return pos;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxParamChange
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxParamChange::TFxParamChange(TFx *fx, double firstAffectedFrame,
Shinya Kitaoka 120a6e
                               double lastAffectedFrame, bool dragging)
Shinya Kitaoka 120a6e
    : TFxChange(fx, firstAffectedFrame, lastAffectedFrame, dragging) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxParamChange::TFxParamChange(TFx *fx, const TParamChange &src)
Shinya Kitaoka 120a6e
    : TFxChange(fx, src.m_firstAffectedFrame, src.m_lastAffectedFrame,
Shinya Kitaoka 120a6e
                src.m_dragging) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxChange
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TFxChange::m_minFrame = -(std::numeric_limits<double>::max)();</double>
Toshihiro Shimizu 890ddd
double TFxChange::m_maxFrame = +(std::numeric_limits<double>::max)();</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxPortDynamicGroup
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxPortDynamicGroup::TFxPortDynamicGroup(const std::string &prefix, int minSize)
Shinya Kitaoka 120a6e
    : m_portsPrefix(prefix), m_minPortsCount(minSize) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxPortDynamicGroup::~TFxPortDynamicGroup() { clear(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFxPortDynamicGroup::addPort(TFxPort *port) { m_ports.push_back(port); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFxPortDynamicGroup::removePort(TFxPort *port) {
Shinya Kitaoka 120a6e
  m_ports.resize(std::remove(m_ports.begin(), m_ports.end(), port) -
Shinya Kitaoka 120a6e
                 m_ports.begin());
Shinya Kitaoka 120a6e
  delete port;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFxPortDynamicGroup::clear() {
Shinya Kitaoka 120a6e
  std::for_each(m_ports.begin(), m_ports.end(), TDeleteObjectFunctor());
Shinya Kitaoka 120a6e
  m_ports.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxImp
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TFxImp {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TFx *m_fx;                //!< Fx back-pointer
Shinya Kitaoka 120a6e
  TFxImp *m_prev, *m_next;  //!< Linked fxs
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::wstring m_name;
Shinya Kitaoka 120a6e
  std::wstring m_fxId;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PortTable m_portTable;  //!< Name -> port  map
Shinya Kitaoka 120a6e
  PortArray m_portArray;  //!< Ports container
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TParamContainer m_paramContainer;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::set<tfxport *=""> m_outputPort;</tfxport>
Shinya Kitaoka 120a6e
  TFxTimeRegion m_activeTimeRegion;
Shinya Kitaoka 120a6e
  std::set<tfxobserver *=""> m_observers;</tfxobserver>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxAttributes m_attributes;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static unsigned long m_nextId;
Shinya Kitaoka 120a6e
  unsigned long m_id;  //!< Unique fx identifier, per Toonz session.
Shinya Kitaoka 120a6e
                       //!< It is intended to be used \b solely to build
Shinya Kitaoka 120a6e
                       //!< an internal string description of the fx.
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TFxImp(TFx *fx)
Shinya Kitaoka 120a6e
      : m_fx(fx), m_activeTimeRegion(TFxTimeRegion::createUnlimited()), m_id() {
Shinya Kitaoka 120a6e
    m_prev = m_next = this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~TFxImp() {
Shinya Kitaoka 120a6e
    m_prev->m_next = m_next;
Shinya Kitaoka 120a6e
    m_next->m_prev = m_prev;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool checkLinks() const {
Shinya Kitaoka 120a6e
    assert(m_prev);
Shinya Kitaoka 120a6e
    assert(m_next);
Shinya Kitaoka 120a6e
    assert(m_prev->m_next == this);
Shinya Kitaoka 120a6e
    assert(m_next->m_prev == this);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not copyable
Shinya Kitaoka 120a6e
  TFxImp(const TFxImp &);
Shinya Kitaoka 120a6e
  TFxImp &operator=(const TFxImp &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
unsigned long TFxImp::m_nextId = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxFactory
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TFxFactory  // singleton
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  typedef std::map<std::string, *="" std::pair<tfxinfo,="" tfxdeclaration="">> Table;</std::string,>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  Table m_table;
Shinya Kitaoka 120a6e
  std::vector<std::string> m_map;</std::string>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxFactory() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  static TFxFactory *instance() {
Shinya Kitaoka 120a6e
    static TFxFactory _instance;
Shinya Kitaoka 120a6e
    return &_instance;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void add(const TFxInfo &info, TFxDeclaration *decl) {
Shinya Kitaoka 120a6e
    // check for dups ???
Shinya Kitaoka 120a6e
    std::pair<tfxinfo, *="" tfxdeclaration=""> p(info, decl);</tfxinfo,>
Shinya Kitaoka 120a6e
    m_table[info.m_name] = p;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFx *create(std::string name) {
Shinya Kitaoka 120a6e
    Table::iterator it = m_table.find(name);
Shinya Kitaoka 120a6e
    if (it != m_table.end()) {
Shinya Kitaoka 120a6e
      TFxDeclaration *decl = it->second.second;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TPersist *obj = decl->create();
Shinya Kitaoka 120a6e
      assert(obj);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return dynamic_cast<tfx *="">(obj);</tfx>
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      return TExternFx::create(name);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void getFxInfos(std::vector<tfxinfo> &info) const {</tfxinfo>
Shinya Kitaoka 120a6e
    for (Table::const_iterator it = m_table.begin(); it != m_table.end(); ++it)
Shinya Kitaoka 120a6e
      info.push_back(it->second.first);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TFxInfo getFxInfo(const std::string &fxIdentifier) const {
Shinya Kitaoka 120a6e
    Table::const_iterator it = m_table.find(fxIdentifier);
Shinya Kitaoka 120a6e
    return (it != m_table.end()) ? it->second.first : TFxInfo();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxDeclaration
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFxDeclaration::TFxDeclaration(const TFxInfo &info)
Shinya Kitaoka 120a6e
    : TPersistDeclaration(info.m_name) {
Shinya Kitaoka 120a6e
  TFxFactory::instance()->add(info, this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFx
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TFx, 3)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TFx::TFx()
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)  // TPersist(TFxImp::m_instances)
Shinya Kitaoka 120a6e
    , m_imp(new TFxImp(this)) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx::~TFx() {
Shinya Kitaoka 120a6e
  for (std::set<tfxport *="">::iterator it = m_imp->m_outputPort.begin();</tfxport>
Shinya Kitaoka 120a6e
       it != m_imp->m_outputPort.end(); ++it) {
Shinya Kitaoka 120a6e
    TFxPort *port = *it;
Shinya Kitaoka 120a6e
    port->setFx(0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  delete m_imp;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::wstring TFx::getName() const { return m_imp->m_name; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::setName(std::wstring name) { m_imp->m_name = name; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::wstring TFx::getFxId() const { return m_imp->m_fxId; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::setFxId(std::wstring id) { m_imp->m_fxId = id; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxAttributes *TFx::getAttributes() const { return &m_imp->m_attributes; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TParamContainer *TFx::getParams() const {
Shinya Kitaoka 120a6e
  return &m_imp->m_paramContainer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TParamContainer *TFx::getParams() { return &m_imp->m_paramContainer; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *TFx::clone(bool recursive) const {
Shinya Kitaoka 120a6e
  TFx *fx = TFx::create(getFxType());
Shinya Kitaoka 120a6e
  assert(fx);
Shinya Kitaoka 120a6e
  return this->clone(fx, recursive);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *TFx::clone(TFx *fx, bool recursive) const {
Shinya Kitaoka 120a6e
  // Copy misc stuff
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  fx->m_imp->m_activeTimeRegion = m_imp->m_activeTimeRegion;
Shinya Kitaoka 120a6e
  fx->setIdentifier(getIdentifier());
Shinya Kitaoka 120a6e
  fx->getParams()->copy(getParams());
Shinya Kitaoka 120a6e
  fx->setFxId(getFxId());
Shinya Kitaoka 120a6e
  fx->setName(getName());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Copy attributes
Shinya Kitaoka 120a6e
  *fx->getAttributes() = *getAttributes();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Clone the dynamic ports pool
Shinya Kitaoka 120a6e
  if (hasDynamicPortGroups()) {
Shinya Kitaoka 120a6e
    int p, pCount = m_imp->m_portArray.size();
Shinya Kitaoka 120a6e
    for (p = 0; p != pCount; ++p) {
Shinya Kitaoka 120a6e
      const NamePort &namedPort = m_imp->m_portArray[p];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      int groupIdx = namedPort.second->getGroupIndex();
Shinya Kitaoka 120a6e
      if (groupIdx >= 0 && !fx->getInputPort(namedPort.first))
Shinya Kitaoka 120a6e
        fx->addInputPort(namedPort.first, new TRasterFxPort, groupIdx);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    assert(pCount == fx->getInputPortCount());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // copia ricorsiva sulle porte
Shinya Kitaoka 120a6e
  if (recursive) {
Shinya Kitaoka 120a6e
    int p, pCount = getInputPortCount();
Shinya Kitaoka 120a6e
    for (p = 0; p != pCount; ++p) {
Shinya Kitaoka 120a6e
      TFxPort *port = getInputPort(p);
Shinya Kitaoka 120a6e
      if (port->getFx())
Shinya Kitaoka 120a6e
        fx->connect(getInputPortName(p), port->getFx()->clone(true));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::linkParams(TFx *fx) {
Shinya Kitaoka 120a6e
  if (this == fx) return;
Shinya Kitaoka 120a6e
  getParams()->link(fx->getParams());
Shinya Kitaoka 120a6e
  m_imp->m_activeTimeRegion = fx->m_imp->m_activeTimeRegion;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // aggiorno i link
Shinya Kitaoka 120a6e
  assert(m_imp->checkLinks());
Shinya Kitaoka 120a6e
  assert(fx->m_imp->checkLinks());
Toshihiro Shimizu 890ddd
otakuto ed7dcd
  std::swap(m_imp->m_next, fx->m_imp->m_next);
otakuto ed7dcd
  std::swap(m_imp->m_next->m_prev, fx->m_imp->m_next->m_prev);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(m_imp->checkLinks());
Shinya Kitaoka 120a6e
  assert(fx->m_imp->checkLinks());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::unlinkParams() {
Shinya Kitaoka 120a6e
  // clone dei parametri
Shinya Kitaoka 120a6e
  getParams()->unlink();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(m_imp->m_prev);
Shinya Kitaoka 120a6e
  assert(m_imp->m_next);
Shinya Kitaoka 120a6e
  assert(m_imp->m_prev->m_next == m_imp);
Shinya Kitaoka 120a6e
  assert(m_imp->m_next->m_prev == m_imp);
Shinya Kitaoka 120a6e
  m_imp->m_prev->m_next = m_imp->m_next;
Shinya Kitaoka 120a6e
  m_imp->m_next->m_prev = m_imp->m_prev;
Shinya Kitaoka 120a6e
  m_imp->m_next = m_imp->m_prev = m_imp;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  notify(TFxParamsUnlinked(this));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::addInputPort(const std::string &name, TFxPort &port) {
Shinya Kitaoka 120a6e
  PortTable::iterator it = m_imp->m_portTable.find(name);
Shinya Kitaoka 120a6e
  if (it != m_imp->m_portTable.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_portTable[name] = &port;
Shinya Kitaoka 120a6e
  m_imp->m_portArray.push_back(NamePort(name, &port));
Shinya Kitaoka 120a6e
  port.setOwnerFx(this);  // back pointer to the owner...
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::addInputPort(const std::string &name, TFxPort *port, int groupIndex) {
Shinya Kitaoka 120a6e
  if (!port) {
Shinya Kitaoka 120a6e
    assert(port);
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (groupIndex >= dynamicPortGroupsCount()) {
Shinya Kitaoka 120a6e
    assert(groupIndex < dynamicPortGroupsCount());
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!addInputPort(name, *port)) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Assign the port to the associated group
Shinya Kitaoka 120a6e
  port->m_groupIdx = groupIndex;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxPortDG *group = const_cast<tfxportdg *="">(dynamicPortGroup(groupIndex));</tfxportdg>
Shinya Kitaoka 120a6e
  group->addPort(port);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(name.find(group->m_portsPrefix) == 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::removeInputPort(const std::string &name) {
Shinya Kitaoka 120a6e
  m_imp->m_portTable.erase(name);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PortArray::iterator it = std::find_if(
Shinya Kitaoka 120a6e
      m_imp->m_portArray.begin(), m_imp->m_portArray.end(), PortNameEq(name));
Shinya Kitaoka 120a6e
  if (it == m_imp->m_portArray.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxPort *port = it->second;
Shinya Kitaoka 120a6e
  port->setOwnerFx(0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (port->m_groupIdx >= 0) {
Shinya Kitaoka 120a6e
    TFxPortDG *group =
Shinya Kitaoka 120a6e
        const_cast<tfxportdg *="">(this->dynamicPortGroup(port->m_groupIdx));</tfxportdg>
Shinya Kitaoka 120a6e
    group->removePort(port);  // The port is DELETED here
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_portArray.erase(it);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
struct IsPrefix {
Shinya Kitaoka 120a6e
  const std::string &m_prefix;
Shinya Kitaoka 120a6e
  bool operator()(const NamePort &nameport) {
Shinya Kitaoka 120a6e
    return (strncmp(m_prefix.c_str(), nameport.first.c_str(),
Shinya Kitaoka 120a6e
                    m_prefix.size()) == 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::clearDynamicPortGroup(int g) {
Shinya Kitaoka 120a6e
  TFxPortDG *dg = const_cast<tfxportdg *="">(this->dynamicPortGroup(g));</tfxportdg>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const std::string &prefix = dg->portsPrefix();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::string prefixEnd = prefix;
Shinya Kitaoka 120a6e
  ++prefixEnd[prefixEnd.size() - 1];
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    // Delete all associated ports from the ports table
Shinya Kitaoka 120a6e
    PortTable::iterator pBegin(m_imp->m_portTable.lower_bound(prefix));
Shinya Kitaoka 120a6e
    PortTable::iterator pEnd(m_imp->m_portTable.lower_bound(prefixEnd));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    m_imp->m_portTable.erase(pBegin, pEnd);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    // Traverse the ports array and remove all ports in the group
Shinya Kitaoka 120a6e
    IsPrefix func = {prefix};
Shinya Kitaoka 120a6e
    m_imp->m_portArray.resize(std::remove_if(m_imp->m_portArray.begin(),
Shinya Kitaoka 120a6e
                                             m_imp->m_portArray.end(), func) -
Shinya Kitaoka 120a6e
                              m_imp->m_portArray.begin());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  dg->clear();  // Has ports ownership, so deletes them
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::addOutputConnection(TFxPort *port) {
Shinya Kitaoka 120a6e
  assert(port->getFx() == this);
Shinya Kitaoka 120a6e
  return m_imp->m_outputPort.insert(port).second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::removeOutputConnection(TFxPort *port) {
Shinya Kitaoka 120a6e
  std::set<tfxport *="">::iterator it = m_imp->m_outputPort.find(port);</tfxport>
Shinya Kitaoka 120a6e
  if (it == m_imp->m_outputPort.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_outputPort.erase(it);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TFx::getOutputConnectionCount() const { return m_imp->m_outputPort.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxPort *TFx::getOutputConnection(int i) const {
Shinya Kitaoka 120a6e
  assert(0 <= i && i <= (int)m_imp->m_outputPort.size());
Shinya Kitaoka 120a6e
  std::set<tfxport *="">::iterator it = m_imp->m_outputPort.begin();</tfxport>
Shinya Kitaoka 120a6e
  std::advance(it, i);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_outputPort.end()) return 0;
Shinya Kitaoka 120a6e
  return *it;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::disconnect(const std::string &name) {
Shinya Kitaoka 120a6e
  TFxPort *port = getInputPort(name);
Shinya Kitaoka 120a6e
  if (!port) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  port->setFx(0);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::connect(const std::string &name, TFx *fx) {
Shinya Kitaoka 120a6e
  TFxPort *port = getInputPort(name);
Shinya Kitaoka 120a6e
  if (!port) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  port->setFx(fx);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TFx::getInputPortCount() const { return m_imp->m_portArray.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxPort *TFx::getInputPort(int index) const {
Shinya Kitaoka 120a6e
  assert(0 <= index && index < (int)m_imp->m_portArray.size());
Shinya Kitaoka 120a6e
  return m_imp->m_portArray[index].second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
std::string TFx::getInputPortName(int index) const {
Shinya Kitaoka 120a6e
  assert(0 <= index && index < (int)(m_imp->m_portArray.size()));
Shinya Kitaoka 120a6e
  return m_imp->m_portArray[index].first;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFx::renamePort(const std::string &oldName, const std::string &newName) {
Shinya Kitaoka 120a6e
  PortTable::iterator it = m_imp->m_portTable.find(oldName);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_portTable.end()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxPort *port = it->second;
Shinya Kitaoka 120a6e
  m_imp->m_portTable.erase(it);
Shinya Kitaoka 120a6e
  m_imp->m_portTable[newName] = port;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PortArray::iterator it2;
Shinya Kitaoka 120a6e
  for (it2 = m_imp->m_portArray.begin(); it2 != m_imp->m_portArray.end();
Shinya Kitaoka 120a6e
       ++it2) {
Shinya Kitaoka 120a6e
    if (it2->first != oldName) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    it2->first = newName;
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxPort *TFx::getInputPort(const std::string &name) const {
Shinya Kitaoka 120a6e
  PortTable::iterator it = m_imp->m_portTable.find(name);
Shinya Kitaoka 120a6e
  if (it == m_imp->m_portTable.end()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_imp->m_portTable[name];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TFx::getReferenceColumnIndex() const {
Shinya Kitaoka 120a6e
  if (!m_imp->m_portArray.empty()) {
Shinya Kitaoka 120a6e
    TFx *fx = m_imp->m_portArray[0].second->getFx();
Shinya Kitaoka 120a6e
    if (fx) return fx->getReferenceColumnIndex();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxTimeRegion TFx::getTimeRegion() const {
Shinya Kitaoka 120a6e
  if (m_imp->m_portTable.empty()) return TFxTimeRegion::createUnlimited();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFxTimeRegion tr((std::numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                   -(std::numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  PortTable::iterator it = m_imp->m_portTable.begin();
Shinya Kitaoka 120a6e
  for (; it != m_imp->m_portTable.end(); ++it) {
Shinya Kitaoka 120a6e
    TFxPort *port = it->second;
Shinya Kitaoka 120a6e
    if (port && port->isConnected() && !port->isaControlPort()) {
Shinya Kitaoka 120a6e
      TFx *fx = port->getFx();
Shinya Kitaoka 120a6e
      assert(fx);
Shinya Kitaoka 120a6e
      tr += fx->getTimeRegion();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return tr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::setActiveTimeRegion(const TFxTimeRegion &tr) {
Shinya Kitaoka 120a6e
  m_imp->m_activeTimeRegion = tr;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxTimeRegion TFx::getActiveTimeRegion() const {
Shinya Kitaoka 120a6e
  return m_imp->m_activeTimeRegion;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::onChange(const TParamChange &c) {
Shinya Kitaoka 120a6e
  TFxParamChange change(this, c);
Shinya Kitaoka 120a6e
  notify(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::addObserver(TFxObserver *obs) { m_imp->m_observers.insert(obs); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::removeObserver(TFxObserver *obs) { m_imp->m_observers.erase(obs); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::notify(const TFxChange &change) {
Shinya Kitaoka 120a6e
  for (std::set<tfxobserver *="">::iterator it = m_imp->m_observers.begin();</tfxobserver>
Shinya Kitaoka 120a6e
       it != m_imp->m_observers.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onChange(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::notify(const TFxPortAdded &change) {
Shinya Kitaoka 120a6e
  for (std::set<tfxobserver *="">::iterator it = m_imp->m_observers.begin();</tfxobserver>
Shinya Kitaoka 120a6e
       it != m_imp->m_observers.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onChange(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::notify(const TFxPortRemoved &change) {
Shinya Kitaoka 120a6e
  for (std::set<tfxobserver *="">::iterator it = m_imp->m_observers.begin();</tfxobserver>
Shinya Kitaoka 120a6e
       it != m_imp->m_observers.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onChange(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::notify(const TFxParamAdded &change) {
Shinya Kitaoka 120a6e
  for (std::set<tfxobserver *="">::iterator it = m_imp->m_observers.begin();</tfxobserver>
Shinya Kitaoka 120a6e
       it != m_imp->m_observers.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onChange(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::notify(const TFxParamRemoved &change) {
Shinya Kitaoka 120a6e
  for (std::set<tfxobserver *="">::iterator it = m_imp->m_observers.begin();</tfxobserver>
Shinya Kitaoka 120a6e
       it != m_imp->m_observers.end(); ++it)
Shinya Kitaoka 120a6e
    (*it)->onChange(change);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
unsigned long TFx::getIdentifier() const { return m_imp->m_id; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::setIdentifier(unsigned long id) { m_imp->m_id = id; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::setNewIdentifier() { m_imp->m_id = ++m_imp->m_nextId; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::loadData(TIStream &is) {
shun-iwasawa c1adfa
  // default version of fx is 1
shun-iwasawa c1adfa
  setFxVersion(1);
shun-iwasawa c1adfa
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  VersionNumber tnzVersion = is.getVersion();
shun-iwasawa e3d315
  // Prevent to load "params" tag under "super" tag on saving macro fx.
shun-iwasawa e3d315
  // For now "params" tag is no longer saved under "super" tag.
shun-iwasawa e3d315
  // This is for keeping compatibility with older versions.
shun-iwasawa e3d315
  bool isInSuperTag = (is.getCurrentTagName() == "super");
Shinya Kitaoka 120a6e
  QList<int> groupIds;</int>
Shinya Kitaoka 120a6e
  QList<std::wstring> groupNames;</std::wstring>
Shinya Kitaoka 120a6e
  while (is.openChild(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "params") {
shun-iwasawa e3d315
      if (isInSuperTag) {  // skip loading "params" tag under "super" tag
shun-iwasawa e3d315
        is.skipCurrentTag();
shun-iwasawa e3d315
        continue;
shun-iwasawa e3d315
      }
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        std::string paramName;
Shinya Kitaoka 120a6e
        while (is.openChild(paramName)) {
shun-iwasawa 9d0856
          TParamVar *paramVar = getParams()->getParamVar(paramName);
shun-iwasawa 9d0856
          if (paramVar && paramVar->getParam()) {
shun-iwasawa 9d0856
            paramVar->getParam()->loadData(is);
shun-iwasawa 9d0856
            if (paramVar->isObsolete())
shun-iwasawa 9d0856
              onObsoleteParamLoaded(paramVar->getParam()->getName());
shun-iwasawa 9d0856
          } else  // il parametro non e' presente -> skip
Shinya Kitaoka 120a6e
            skipChild(is);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
          is.closeChild();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "paramsLinkedTo") {
Shinya Kitaoka 120a6e
      TPersist *p = 0;
Shinya Kitaoka 120a6e
      is >> p;
Shinya Kitaoka 120a6e
      TFx *fx = dynamic_cast<tfx *="">(p);</tfx>
Shinya Kitaoka 120a6e
      if (fx == 0) throw TException("Missing linkedSetRoot");
Shinya Kitaoka 120a6e
      linkParams(fx);
Shinya Kitaoka 120a6e
    } else if (tagName == "ports") {
Shinya Kitaoka 120a6e
      std::string portName;
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        while (is.openChild(portName)) {
Shinya Kitaoka 120a6e
          VersionNumber version = is.getVersion();
Shinya Kitaoka 120a6e
          compatibilityTranslatePort(version.first, version.second, portName);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // Try to find the specified port
Shinya Kitaoka 120a6e
          TFxPort *port = getInputPort(portName);
Shinya Kitaoka 120a6e
          if (!port) {
Shinya Kitaoka 120a6e
            // Scan dynamic port groups for a containing one - add a port there
Shinya Kitaoka 120a6e
            // if found
Shinya Kitaoka 120a6e
            int g, gCount = dynamicPortGroupsCount();
Shinya Kitaoka 120a6e
            for (g = 0; g != gCount; ++g) {
Shinya Kitaoka 120a6e
              TFxPortDG *group = const_cast<tfxportdg *="">(dynamicPortGroup(g));</tfxportdg>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
              if (group->contains(portName)) {
Shinya Kitaoka 120a6e
                addInputPort(portName, port = new TRasterFxPort, g);
Shinya Kitaoka 120a6e
                break;
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          // Could not find (or add) a port with the corresponding name - throw
Shinya Kitaoka 120a6e
          if (!port)
Shinya Kitaoka 120a6e
            throw TException(std::string("port '") + portName +
Shinya Kitaoka 120a6e
                             "' is not present");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          if (!is.eos()) {
Shinya Kitaoka 120a6e
            TPersist *p = 0;
Shinya Kitaoka 120a6e
            is >> p;
Shinya Kitaoka 120a6e
            TFx *fx = dynamic_cast<tfx *="">(p);</tfx>
Shinya Kitaoka 120a6e
            port->setFx(fx);
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          is.closeChild();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "dagNodePos") {
Shinya Kitaoka 120a6e
      TPointD p;
Shinya Kitaoka 120a6e
      is >> p.x >> p.y;
Shinya Kitaoka 120a6e
      m_imp->m_attributes.setDagNodePos(updateDagPosition(p, tnzVersion));
Shinya Kitaoka 120a6e
    } else if (tagName == "numberId") {
Shinya Kitaoka 120a6e
      int numberId = 0;
Shinya Kitaoka 120a6e
      is >> numberId;
Shinya Kitaoka 120a6e
      m_imp->m_attributes.setId(numberId);
Shinya Kitaoka 120a6e
    } else if (tagName == "passiveCacheId") {
Shinya Kitaoka 120a6e
      int passiveCacheId = 0;
Shinya Kitaoka 120a6e
      is >> passiveCacheId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      assert(passiveCacheId > 0);
Shinya Kitaoka 120a6e
      TPassiveCacheManager::instance()->declareCached(this, passiveCacheId);
Shinya Kitaoka 120a6e
    } else if (tagName == "name") {
Shinya Kitaoka 120a6e
      // passo attraverso un filepath solo per evitare i problemi di blank
Shinya Kitaoka 120a6e
      // o caratteri strani dentro il nome (sospetto che tfilepath sia gestito
Shinya Kitaoka 120a6e
      // correttamente mentre wstring no
Shinya Kitaoka 120a6e
      TFilePath tmp;
Shinya Kitaoka 120a6e
      is >> tmp;
Shinya Kitaoka 120a6e
      setName(tmp.getWideName());
Shinya Kitaoka 120a6e
    } else if (tagName == "fxId") {
Shinya Kitaoka 120a6e
      TFilePath tmp;
Shinya Kitaoka 120a6e
      is >> tmp;
Shinya Kitaoka 120a6e
      setFxId(tmp.getWideName());
Shinya Kitaoka 120a6e
    } else if (tagName == "enabled") {
Shinya Kitaoka 120a6e
      int flag = 1;
Shinya Kitaoka 120a6e
      is >> flag;
Shinya Kitaoka 120a6e
      m_imp->m_attributes.enable(flag != 0);
Shinya Kitaoka 120a6e
    } else if (tagName == "opened") {
Shinya Kitaoka 120a6e
      int opened = 1;
Shinya Kitaoka 120a6e
      is >> opened;
Shinya Kitaoka 120a6e
      m_imp->m_attributes.setIsOpened(opened);
Shinya Kitaoka 120a6e
    } else if (tagName == "groupIds") {
Shinya Kitaoka 120a6e
      int groupId;
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        is >> groupId;
Shinya Kitaoka 120a6e
        groupIds.append(groupId);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "groupNames") {
Shinya Kitaoka 120a6e
      std::wstring groupName;
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        is >> groupName;
Shinya Kitaoka 120a6e
        groupNames.append(groupName);
Shinya Kitaoka 120a6e
      }
shun-iwasawa c1adfa
    } else if (tagName == "fxVersion") {
shun-iwasawa c1adfa
      int version = 1;
shun-iwasawa c1adfa
      is >> version;
shun-iwasawa c1adfa
      setFxVersion(version);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      throw TException("Unknown tag!");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    is.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (!groupIds.isEmpty()) {
Shinya Kitaoka 120a6e
    assert(groupIds.size() == groupNames.size());
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < groupIds.size(); i++) {
Shinya Kitaoka 120a6e
      m_imp->m_attributes.setGroupId(groupIds[i]);
Shinya Kitaoka 120a6e
      m_imp->m_attributes.setGroupName(groupNames[i]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//--------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TFx::saveData(TOStream &os) {
shun-iwasawa e3d315
  // Prevent to save "params" tag under "super" tag on saving macro fx.
shun-iwasawa e3d315
  // Parameters for macro fx are saved in "nodes" tag and corrected upon
shun-iwasawa e3d315
  // loading. Therefore, "params" tag is not needed and even causes crash if
shun-iwasawa e3d315
  // macrofx contains CurveFx (See the issue #2424)
shun-iwasawa e3d315
  bool isInSuperTag  = (os.getCurrentTagName() == "super");
Shinya Kitaoka 120a6e
  TFx *linkedSetRoot = this;
Shinya Kitaoka 120a6e
  if (m_imp->m_next != m_imp) {
Shinya Kitaoka 120a6e
    TFxImp *imp = m_imp->m_next;
Shinya Kitaoka 120a6e
    int guard   = 0;
Shinya Kitaoka 120a6e
    while (guard++ < 1000 && imp != m_imp) {
Shinya Kitaoka 120a6e
      if (imp->m_fx < linkedSetRoot) linkedSetRoot = imp->m_fx;
shun-iwasawa e3d315
      imp = imp->m_next;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    assert(imp == m_imp);
Shinya Kitaoka 120a6e
    assert(linkedSetRoot);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (linkedSetRoot == this) {
shun-iwasawa e3d315
    if (!isInSuperTag) {  // skip saving "params" tag under "super" tag
shun-iwasawa e3d315
      os.openChild("params");
shun-iwasawa e3d315
      for (int i = 0; i < getParams()->getParamCount(); i++) {
shun-iwasawa e3d315
        std::string paramName     = getParams()->getParamName(i);
shun-iwasawa e3d315
        const TParamVar *paramVar = getParams()->getParamVar(i);
shun-iwasawa e3d315
        // skip saving for the obsolete parameters
shun-iwasawa e3d315
        if (paramVar->isObsolete()) continue;
shun-iwasawa e3d315
        os.openChild(paramName);
shun-iwasawa e3d315
        paramVar->getParam()->saveData(os);
shun-iwasawa e3d315
        os.closeChild();
shun-iwasawa e3d315
      }
Shinya Kitaoka 120a6e
      os.closeChild();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    os.openChild("paramsLinkedTo");
Shinya Kitaoka 120a6e
    os << linkedSetRoot;
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.openChild("ports");
shun-iwasawa 809a66
  for (auto &namePort : m_imp->m_portArray) {
shun-iwasawa 809a66
    os.openChild(namePort.first);
shun-iwasawa 809a66
    if (namePort.second->isConnected())
shun-iwasawa 809a66
      os << TFxP(namePort.second->getFx()).getPointer();
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointD p = m_imp->m_attributes.getDagNodePos();
Shinya Kitaoka 120a6e
  if (p != TConst::nowhere) os.child("dagNodePos") << p.x << p.y;
Shinya Kitaoka 120a6e
  int numberId = m_imp->m_attributes.getId();
Shinya Kitaoka 120a6e
  os.child("numberId") << numberId;
Shinya Kitaoka 120a6e
  bool cacheEnabled = TPassiveCacheManager::instance()->cacheEnabled(this);
Shinya Kitaoka 120a6e
  if (cacheEnabled)
Shinya Kitaoka 120a6e
    os.child("passiveCacheId")
Shinya Kitaoka 120a6e
        << TPassiveCacheManager::instance()->getPassiveCacheId(this);
Shinya Kitaoka 120a6e
  std::wstring name = getName();
Shinya Kitaoka 120a6e
  if (name != L"") os.child("name") << TFilePath(name);
Shinya Kitaoka 120a6e
  std::wstring fxId = getFxId();
Shinya Kitaoka 120a6e
  os.child("fxId") << fxId;
Shinya Kitaoka 120a6e
  if (!m_imp->m_attributes.isEnabled()) os.child("enabled") << 0;
Shinya Kitaoka 120a6e
  os.child("opened") << (int)m_imp->m_attributes.isOpened();
Shinya Kitaoka 120a6e
  if (m_imp->m_attributes.isGrouped()) {
Shinya Kitaoka 120a6e
    os.openChild("groupIds");
Shinya Kitaoka 120a6e
    QStack<int> groupIdStack = m_imp->m_attributes.getGroupIdStack();</int>
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < groupIdStack.size(); i++) os << groupIdStack[i];
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
    os.openChild("groupNames");
Shinya Kitaoka 120a6e
    QStack<std::wstring> groupNameStack =</std::wstring>
Shinya Kitaoka 120a6e
        m_imp->m_attributes.getGroupNameStack();
Shinya Kitaoka 120a6e
    for (i = 0; i < groupNameStack.size(); i++) os << groupNameStack[i];
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
shun-iwasawa c1adfa
  if (getFxVersion() != 1) os.child("fxVersion") << getFxVersion();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//--------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TFx::loadPreset(TIStream &is) {
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  while (is.openChild(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "dvpreset") {
Shinya Kitaoka 120a6e
      std::string fxId = is.getTagAttribute("fxId");
Shinya Kitaoka 120a6e
      if (fxId != getFxType())
Shinya Kitaoka 120a6e
        throw TException("Preset doesn't match the fx type");
Shinya Kitaoka 120a6e
    } else if (tagName == "params") {
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        std::string paramName;
Shinya Kitaoka 120a6e
        while (is.openChild(paramName)) {
Shinya Kitaoka 120a6e
          try {
Shinya Kitaoka 120a6e
            TParamP param = getParams()->getParam(paramName);
Shinya Kitaoka 120a6e
            param->loadData(is);
Shinya Kitaoka 120a6e
          } catch (TException &) { /*skip*/
Shinya Kitaoka 120a6e
          }                        // il parametro non e' presente
Shinya Kitaoka 120a6e
          is.closeChild();
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      throw TException("Fx preset unknown tag!");
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::savePreset(TOStream &os) {
Shinya Kitaoka 120a6e
  std::map<std::string, std::string=""> attributes;</std::string,>
Shinya Kitaoka 120a6e
  attributes.insert(std::make_pair(std::string("ver"), std::string("1.0")));
Shinya Kitaoka 120a6e
  attributes.insert(std::make_pair(std::string("fxId"), getFxType()));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.openChild("dvpreset", attributes);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.openChild("params");
Shinya Kitaoka 120a6e
  for (int i = 0; i < getParams()->getParamCount(); i++) {
Shinya Kitaoka 120a6e
    std::string paramName = getParams()->getParamName(i);
Shinya Kitaoka 120a6e
    TParam *param         = getParams()->getParam(i);
Shinya Kitaoka 120a6e
    os.openChild(paramName);
Shinya Kitaoka 120a6e
    param->saveData(os);
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  os.closeChild();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::disconnectAll() {
Shinya Kitaoka 120a6e
  int p, pCount = getInputPortCount();
Shinya Kitaoka 120a6e
  for (p = 0; p != pCount; ++p) getInputPort(p)->setFx(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *TFx::create(std::string name) {
Shinya Kitaoka 120a6e
  return TFxFactory::instance()->create(name);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TFx::listFxs(std::vector<tfxinfo> &info) {</tfxinfo>
Shinya Kitaoka 120a6e
  TFxFactory::instance()->getFxInfos(info);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxInfo TFx::getFxInfo(const std::string &fxIdentifier) {
Shinya Kitaoka 120a6e
  return TFxFactory::instance()->getFxInfo(fxIdentifier);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFx *TFx::getLinkedFx() const {
Shinya Kitaoka 120a6e
  assert(m_imp->m_next);
Shinya Kitaoka 120a6e
  assert(m_imp->m_next->m_prev == m_imp);
Shinya Kitaoka 120a6e
  assert(m_imp->m_next->m_fx != 0);
Shinya Kitaoka 120a6e
  return m_imp->m_next->m_fx;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa c1adfa
//--------------------------------------------------
shun-iwasawa c1adfa
shun-iwasawa c1adfa
void TFx::setFxVersion(int v) { m_imp->m_attributes.setFxVersion(v); }
shun-iwasawa c1adfa
shun-iwasawa c1adfa
//--------------------------------------------------
shun-iwasawa c1adfa
shun-iwasawa c1adfa
int TFx::getFxVersion() const { return m_imp->m_attributes.getFxVersion(); }
shun-iwasawa c1adfa
Toshihiro Shimizu 890ddd
//===================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// TFxTimeRegion
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Creates an unlimited time region.
Toshihiro Shimizu 890ddd
TFxTimeRegion::TFxTimeRegion()
Shinya Kitaoka 120a6e
    : m_start((std::numeric_limits<double>::max)())</double>
Shinya Kitaoka 120a6e
    , m_end(-(std::numeric_limits<double>::max)()) {}</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//! Creates a time region with specified start (included) and end (\b excluded).
Toshihiro Shimizu 890ddd
TFxTimeRegion::TFxTimeRegion(double start, double end)
Shinya Kitaoka 120a6e
    : m_start(start), m_end(end) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TFxTimeRegion TFxTimeRegion::createUnlimited() {
Shinya Kitaoka 120a6e
  return TFxTimeRegion(-(std::numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                       (std::numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFxTimeRegion::contains(double time) const {
Shinya Kitaoka 120a6e
  return (m_start <= time && time < m_end);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFxTimeRegion::isUnlimited() const {
Shinya Kitaoka 120a6e
  return (m_start == -(std::numeric_limits<double>::max)() ||</double>
Shinya Kitaoka 120a6e
          m_end == (std::numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFxTimeRegion::isEmpty() const { return (m_end <= m_start); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TFxTimeRegion::getFrameCount(int &count) const {
Shinya Kitaoka 120a6e
  if (isUnlimited()) return false;
Shinya Kitaoka 120a6e
  count = tfloor(m_end) - tceil(m_start);
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TFxTimeRegion::getFirstFrame() const { return tceil(m_start); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TFxTimeRegion::getLastFrame() const {
Shinya Kitaoka 120a6e
  if (m_end == (std::numeric_limits<double>::max)())</double>
Shinya Kitaoka 120a6e
    return (std::numeric_limits<int>::max)();</int>
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return tceil(m_end) - 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================