1 #pragma once
2
3 #ifndef TFX_INCLUDED
4 #define TFX_INCLUDED
5
6 #include <memory>
7
8 // TnzCore includes
9 #include "tsmartpointer.h"
10 #include "tpersist.h"
11 #include "texception.h"
12 #include "ttile.h"
13 #include "tgeometry.h"
14
15 // TnzBase includes
16 #include "tparamchange.h"
17
18 #undef DVAPI
19 #undef DVVAR
20 #ifdef TFX_EXPORTS
21 #define DVAPI DV_EXPORT_API
22 #define DVVAR DV_EXPORT_VAR
23 #else
24 #define DVAPI DV_IMPORT_API
25 #define DVVAR DV_IMPORT_VAR
26 #endif
27
28 //===================================================================
29
30 // Forward declarations
31
32 class TFxImp;
33 class TFx;
34 class TParam;
35 class TFxAttributes;
36 class TParamContainer;
37 class TParamVar;
38 class TRenderSettings;
39 class TParamUIConcept;
40
41 //===================================================================
42
43 class DVAPI TFxPort {
44 friend class TFx;
45
46 protected:
47 TFx *m_owner; //!< This is an input port of m_owner
48 int m_groupIdx; //!< Dynamic group index this belongs to in m_owner (-1 if
49 //! none)
50 bool m_isControl;
51
52 public:
TFxPort(bool isControl)53 TFxPort(bool isControl)
54 : m_owner(0), m_groupIdx(-1), m_isControl(isControl) {}
~TFxPort()55 virtual ~TFxPort() {}
56
57 virtual TFx *getFx() const = 0;
58 virtual void setFx(TFx *) = 0;
59
isConnected()60 bool isConnected() const { return getFx() != 0; }
isaControlPort()61 bool isaControlPort() const { return m_isControl; }
62
getGroupIndex()63 int getGroupIndex() const { return m_groupIdx; }
64
getOwnerFx()65 TFx *getOwnerFx() const { return m_owner; }
setOwnerFx(TFx * fx)66 void setOwnerFx(TFx *fx) { m_owner = fx; }
67
68 private:
69 // Not copiable
70 TFxPort(const TFxPort &);
71 TFxPort &operator=(const TFxPort &);
72 };
73
74 //-------------------------------------------------------------------
75
76 template <class T>
77 class TFxPortT : public TFxPort {
78 friend class TFx;
79
80 protected:
81 T *m_fx;
82
83 public:
TFxPort(isControl)84 TFxPortT(bool isControl = false) : TFxPort(isControl), m_fx(0) {}
~TFxPortT()85 ~TFxPortT() {
86 if (m_fx) {
87 m_fx->removeOutputConnection(this);
88 m_fx->release();
89 }
90 }
91
getFx()92 TFx *getFx() const override { return m_fx; }
93
setFx(TFx * fx)94 void setFx(TFx *fx) override {
95 if (m_fx) m_fx->removeOutputConnection(this);
96
97 if (fx == 0) {
98 if (m_fx) m_fx->release();
99 m_fx = 0;
100 } else {
101 T *fxt = dynamic_cast<T *>(fx);
102 if (!fxt) throw TException("Fx: port type mismatch");
103
104 fxt->addRef();
105 if (m_fx) m_fx->release();
106
107 m_fx = fxt;
108 m_fx->addOutputConnection(this);
109 }
110 }
111
112 T *operator->() {
113 assert(m_fx);
114 return m_fx;
115 }
116 };
117
118 //===================================================================
119
120 /*
121 \brief A TFxPortDynamicGroup represents a group of fx ports with the
122 same name prefix whose ports that are added or removed dynamically by
123 Toonz on user request.
124
125 \sa The TFx::dynamicPortsGroup() method.
126 */
127 class DVAPI TFxPortDynamicGroup {
128 public:
129 typedef std::vector<TFxPort *> PortsContainer;
130
131 public:
132 TFxPortDynamicGroup(const std::string &portsPrefix, int minPortsCount = 1);
133 ~TFxPortDynamicGroup();
134
135 //! Returns the group's displayed ports prefix (ports added to the group \b
136 //! must
137 //! have this prefix).
portsPrefix()138 const std::string &portsPrefix() const { return m_portsPrefix; }
139
140 //! Returns the minimal number of ports to be displayed in the group. The
141 //! group
142 //! <B> must not <\B> be initialized in an fx implementation with more ports
143 //! than
144 //! this number.
minPortsCount()145 int minPortsCount() const { return m_minPortsCount; }
146
147 //! Returns the list of ports currently in the group (may contain empty
148 //! ports).
ports()149 const PortsContainer &ports() const { return m_ports; }
150
151 //! Equivalent to checking the portName prefix against the stored one.
contains(const std::string & portName)152 bool contains(const std::string &portName) const {
153 return (strncmp(m_portsPrefix.c_str(), portName.c_str(),
154 m_portsPrefix.size()) == 0);
155 }
156
157 private:
158 std::string m_portsPrefix; //!< Name prefix of each stored port
159 int m_minPortsCount; //!< Ports count \a should not be smaller
160
161 std::vector<TFxPort *> m_ports; //!< \b Owned ports (deleted on destruction)
162
163 private:
164 friend class TFx;
165
166 // Not copyable
167 TFxPortDynamicGroup(const TFxPortDynamicGroup &);
168 TFxPortDynamicGroup &operator=(const TFxPortDynamicGroup &);
169
170 void addPort(TFxPort *port);
171 void removePort(
172 TFxPort *port); //!< Removes <I> and deletes <\I> the specified port
173 void clear();
174 };
175
176 typedef TFxPortDynamicGroup TFxPortDG;
177
178 //===================================================================
179
180 class DVAPI TFxTimeRegion {
181 public:
182 TFxTimeRegion();
183 TFxTimeRegion(double start, double end);
184
185 static TFxTimeRegion createUnlimited();
186
187 TFxTimeRegion &operator+=(const TFxTimeRegion &rhs) {
188 m_start = std::min(m_start, rhs.m_start);
189 m_end = std::max(m_end, rhs.m_end);
190 return *this;
191 }
192
193 TFxTimeRegion &operator+=(double shift) {
194 m_start += shift;
195 m_end += shift;
196 return *this;
197 }
198
199 TFxTimeRegion &operator-=(double shift) { return operator+=(-shift); }
200
201 bool contains(double time) const;
202 bool isUnlimited() const;
203 bool isEmpty() const;
204
205 bool getFrameCount(int &count) const;
206 int getFirstFrame() const;
207 int getLastFrame() const;
208
209 double m_start;
210 double m_end;
211 };
212
213 inline TFxTimeRegion operator+(const TFxTimeRegion &tr1,
214 const TFxTimeRegion &tr2) {
215 return TFxTimeRegion(tr1) += tr2;
216 }
217
218 inline TFxTimeRegion operator+(const TFxTimeRegion &tr1, double shift) {
219 return TFxTimeRegion(tr1) += shift;
220 }
221
222 inline TFxTimeRegion operator-(const TFxTimeRegion &tr1, double shift) {
223 return TFxTimeRegion(tr1) -= shift;
224 }
225
226 //===================================================================
227
228 class DVAPI TFxChange {
229 public:
230 TFx *m_fx;
231
232 double m_firstAffectedFrame;
233 double m_lastAffectedFrame;
234 bool m_dragging;
235
236 static double m_minFrame;
237 static double m_maxFrame;
238
239 public:
TFxChange(TFx * fx,double firstAffectedFrame,double lastAffectedFrame,bool dragging)240 TFxChange(TFx *fx, double firstAffectedFrame, double lastAffectedFrame,
241 bool dragging)
242 : m_fx(fx)
243 , m_firstAffectedFrame(firstAffectedFrame)
244 , m_lastAffectedFrame(lastAffectedFrame)
245 , m_dragging(dragging) {}
246
247 private:
248 TFxChange();
249 };
250
251 //------------------------------------------------------------------------------
252
253 class TFxParamChange final : public TFxChange {
254 public:
255 TFxParamChange(TFx *fx, double firstAffectedFrame, double lastAffectedFrame,
256 bool dragging);
257 TFxParamChange(TFx *fx, const TParamChange &src);
258 };
259
260 //------------------------------------------------------------------------------
261
262 class TFxPortAdded final : public TFxChange {
263 public:
TFxPortAdded(TFx * fx)264 TFxPortAdded(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxPortAdded()265 ~TFxPortAdded() {}
266 };
267
268 //------------------------------------------------------------------------------
269
270 class TFxPortRemoved final : public TFxChange {
271 public:
TFxPortRemoved(TFx * fx)272 TFxPortRemoved(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxPortRemoved()273 ~TFxPortRemoved() {}
274 };
275
276 //------------------------------------------------------------------------------
277
278 class TFxParamAdded final : public TFxChange {
279 public:
TFxParamAdded(TFx * fx)280 TFxParamAdded(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxParamAdded()281 ~TFxParamAdded() {}
282 };
283
284 //------------------------------------------------------------------------------
285
286 class TFxParamRemoved final : public TFxChange {
287 public:
TFxParamRemoved(TFx * fx)288 TFxParamRemoved(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxParamRemoved()289 ~TFxParamRemoved() {}
290 };
291
292 //------------------------------------------------------------------------------
293
294 class TFxParamsUnlinked final : public TFxChange {
295 public:
TFxParamsUnlinked(TFx * fx)296 TFxParamsUnlinked(TFx *fx) : TFxChange(fx, m_minFrame, m_maxFrame, false) {}
~TFxParamsUnlinked()297 ~TFxParamsUnlinked() {}
298 };
299
300 //===================================================================
301
302 class DVAPI TFxObserver {
303 public:
TFxObserver()304 TFxObserver() {}
~TFxObserver()305 virtual ~TFxObserver() {}
306
307 virtual void onChange(const TFxChange &change) = 0;
308
onChange(const TFxPortAdded & change)309 virtual void onChange(const TFxPortAdded &change) {
310 onChange(static_cast<const TFxChange &>(change));
311 }
312
onChange(const TFxPortRemoved & change)313 virtual void onChange(const TFxPortRemoved &change) {
314 onChange(static_cast<const TFxChange &>(change));
315 }
316
onChange(const TFxParamAdded & change)317 virtual void onChange(const TFxParamAdded &change) {
318 onChange(static_cast<const TFxChange &>(change));
319 }
320
onChange(const TFxParamRemoved & change)321 virtual void onChange(const TFxParamRemoved &change) {
322 onChange(static_cast<const TFxChange &>(change));
323 }
324
onChange(const TFxParamsUnlinked & change)325 virtual void onChange(const TFxParamsUnlinked &change) {
326 onChange(static_cast<const TFxChange &>(change));
327 }
328 };
329
330 //===================================================================
331
332 class TFxInfo {
333 public:
334 std::string m_name;
335 bool m_isHidden;
336
337 public:
TFxInfo()338 TFxInfo() {}
TFxInfo(const std::string & name,bool isHidden)339 TFxInfo(const std::string &name, bool isHidden)
340 : m_name(name), m_isHidden(isHidden) {}
341 };
342
343 //===================================================================
344
345 #ifdef _WIN32
346 template class DVAPI TSmartPointerT<TFx>;
347 #endif
348 typedef TSmartPointerT<TFx> TFxP;
349
350 //===================================================================
351
352 class DVAPI TFx : public TSmartObject, public TPersist, public TParamObserver {
353 DECLARE_CLASS_CODE
354
355 TFxImp *m_imp;
356
357 public:
358 typedef TFx *CreateProc();
359
360 TFx();
361 virtual ~TFx();
362
363 virtual std::wstring getName() const;
364 void setName(std::wstring name);
365 std::wstring getFxId() const;
366 void setFxId(std::wstring id);
367
368 TParamContainer *getParams();
369 const TParamContainer *getParams() const;
370 void addParamVar(TParamVar *var);
371
372 virtual TFx *clone(bool recursive = true) const;
373 TFx *clone(TFx *fx, bool recursive) const;
374
375 void unlinkParams();
376 virtual void linkParams(TFx *src);
377
378 TFx *getLinkedFx() const;
379
380 bool addInputPort(const std::string &name, TFxPort &p); //!< Adds a port with
381 //! given name,
382 //! returns false on
383 //! duplicate names.
384 //! Ownership of the port belongs to derived implementations of TFx.
385 bool addInputPort(const std::string &name, TFxPort *p,
386 int groupIndex); //!< Adds a port with given name to the
387 //! specified dynamic group,
388 //! returns false on duplicate names. Ownership is transferred to the group.
389 bool removeInputPort(const std::string &name); //!< Removes the port with
390 //! given name, returns false
391 //! if not found.
392
393 bool renamePort(const std::string &oldName, const std::string &newName);
394
395 bool connect(
396 const std::string &name,
397 TFx *other); //!< Equivalent to getInputPort(name)->setFx(other).
398 bool disconnect(const std::string
399 &name); //!< Equivalent to getInputPort(name)->setFx(0).
400
401 int getInputPortCount() const;
402 TFxPort *getInputPort(int index) const;
403 TFxPort *getInputPort(const std::string &name) const;
404 std::string getInputPortName(int index) const;
405
dynamicPortGroupsCount()406 virtual int dynamicPortGroupsCount() const { return 0; }
dynamicPortGroup(int g)407 virtual const TFxPortDG *dynamicPortGroup(int g) const { return 0; }
hasDynamicPortGroups()408 bool hasDynamicPortGroups() const { return (dynamicPortGroupsCount() > 0); }
409 void clearDynamicPortGroup(
410 int g); //!< \warning Users must ensure that the group's minimal
411 //! ports count is respected - this method does \b not.
412 bool addOutputConnection(TFxPort *port);
413 bool removeOutputConnection(TFxPort *port);
414
415 static void listFxs(std::vector<TFxInfo> &fxInfos);
416 static TFxInfo getFxInfo(const std::string &fxIdentifier); //!< Returns info
417 //! associated to
418 //! an fx
419 //! identifier, or
420 //! an
421 //! unnamed one if none was found.
isZerary()422 virtual bool isZerary() const { return getInputPortCount() == 0; }
423
424 // returns the column index that provides reference frame for the FX.
425 // (TColumnFx and Zerary fxs return their column indexes, n-ary FXs return
426 // the reference column index of their first argument)
427 // note: it returns -1 if the column is undefined (e.g. a n-ary FX with
428 // arguments undefined yet)
429 virtual int getReferenceColumnIndex() const;
430
431 // se getXsheetPort() != 0 e la porta non e' connessa la si considera connessa
432 // a tutte le colonne precedenti a quella corrente.
433 // cfr. AddFx
getXsheetPort()434 virtual TFxPort *getXsheetPort() const { return 0; }
435
436 int getOutputConnectionCount() const;
437 TFxPort *getOutputConnection(int i) const;
438
439 virtual TFxTimeRegion getTimeRegion() const;
440
441 void setActiveTimeRegion(const TFxTimeRegion &tr);
442 TFxTimeRegion getActiveTimeRegion() const;
443
checkActiveTimeRegion()444 virtual bool checkActiveTimeRegion() const { return true; }
445
446 void disconnectAll();
447
448 //! Returns a list of User Interface Concepts to be displayed when editing the
449 //! fx parameters.
450 //! \note Ownership of the returned array allocated with new[] is passed to
451 //! callers.
getParamUIs(TParamUIConcept * & params,int & length)452 virtual void getParamUIs(TParamUIConcept *¶ms, int &length) {
453 params = 0, length = 0;
454 }
455
456 inline std::string getFxType() const;
457 virtual std::string getPluginId() const = 0;
458
459 static TFx *create(std::string name);
460
461 // TParamObserver-related methods
462 void onChange(const TParamChange &c) override;
463
464 void addObserver(TFxObserver *);
465 void removeObserver(TFxObserver *);
466 void notify(const TFxChange &change);
467 void notify(const TFxPortAdded &change);
468 void notify(const TFxPortRemoved &change);
469 void notify(const TFxParamAdded &change);
470 void notify(const TFxParamRemoved &change);
471
472 void loadData(TIStream &is) override;
473 void saveData(TOStream &os) override;
474
475 void loadPreset(TIStream &is); // solleva un eccezione se il preset non
476 // corrisponde all'effetto
477 void savePreset(TOStream &os);
478
479 TFxAttributes *getAttributes() const;
480
getAlias(double frame,const TRenderSettings & info)481 virtual std::string getAlias(double frame,
482 const TRenderSettings &info) const {
483 return "";
484 }
485
486 //! Compatibility function - used to translate a port name from older Toonz
487 //! versions into its current form.
compatibilityTranslatePort(int majorVersion,int minorVersion,std::string & portName)488 virtual void compatibilityTranslatePort(int majorVersion, int minorVersion,
489 std::string &portName) {}
490
491 /*-- Rendering(目玉)ボタンがOFFのときに使用されるInputPort --*/
getPreferredInputPort()492 virtual int getPreferredInputPort() { return 0; }
493
494 /* RasterFxPluginHost 用の仮想関数 */
callStartRenderHandler()495 virtual void callStartRenderHandler() {}
callEndRenderHandler()496 virtual void callEndRenderHandler() {}
callStartRenderFrameHandler(const TRenderSettings * rs,double frame)497 virtual void callStartRenderFrameHandler(const TRenderSettings *rs,
498 double frame) {}
callEndRenderFrameHandler(const TRenderSettings * rs,double frame)499 virtual void callEndRenderFrameHandler(const TRenderSettings *rs,
500 double frame) {}
501
502 // This function will be called in TFx::loadData whenever the obsolete
503 // parameter is loaded. Do nothing by default.
onObsoleteParamLoaded(const std::string & paramName)504 virtual void onObsoleteParamLoaded(const std::string ¶mName) {}
505
506 void setFxVersion(int);
507 int getFxVersion() const;
508
509 public:
510 // Id-related functions
511
512 unsigned long getIdentifier() const;
513 void setIdentifier(unsigned long id);
514 void setNewIdentifier();
515
516 private:
517 // not implemented
518 TFx(const TFx &);
519 TFx &operator=(const TFx &);
520 };
521
522 //===================================================================
523
524 DVAPI TIStream &operator>>(TIStream &in, TFxP &p);
525
526 //===================================================================
527
528 //===================================================================
529
530 class DVAPI TFxDeclaration : public TPersistDeclaration {
531 public:
532 TFxDeclaration(const TFxInfo &info);
533 };
534
535 template <class T>
536 class TFxDeclarationT final : public TFxDeclaration {
537 public:
TFxDeclarationT(const TFxInfo & info)538 TFxDeclarationT(const TFxInfo &info) : TFxDeclaration(info) {}
create()539 TPersist *create() const override { return new T; }
540 };
541
542 //-------------------------------------------------------------------
543
getFxType()544 inline std::string TFx::getFxType() const { return getDeclaration()->getId(); }
545
546 //-------------------------------------------------------------------
547
548 #define FX_DECLARATION(T) \
549 \
550 public: \
551 const TPersistDeclaration *getDeclaration() const override;
552
553 #define FX_IDENTIFIER(T, I) \
554 namespace { \
555 TFxDeclarationT<T> info##T(TFxInfo(I, false)); \
556 } \
557 const TPersistDeclaration *T::getDeclaration() const { return &info##T; }
558
559 #define FX_IDENTIFIER_IS_HIDDEN(T, I) \
560 namespace { \
561 TFxDeclarationT<T> info##T(TFxInfo(I, true)); \
562 } \
563 const TPersistDeclaration *T::getDeclaration() const { return &info##T; }
564
565 //===================================================================
566
567 #endif
568