-
-
Notifications
You must be signed in to change notification settings - Fork 360
/
function.h
1015 lines (847 loc) · 30.6 KB
/
function.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
Q Light Controller Plus
function.h
Copyright (C) 2004 Heikki Junnila
Massimo Callegari
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.txt
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef FUNCTION_H
#define FUNCTION_H
#include <QWaitCondition>
#include <QObject>
#include <QString>
#include <QMutex>
#include <QList>
#include <QIcon>
#include <QMap>
#include "universe.h"
#include "functionparent.h"
class QXmlStreamReader;
class GenericFader;
class MasterTimer;
class Function;
class Doc;
class FunctionUiState;
/** @addtogroup engine_functions Functions
* @{
*/
#define KXMLQLCFunction QString("Function")
#define KXMLQLCFunctionName QString("Name")
#define KXMLQLCFunctionID QString("ID")
#define KXMLQLCFunctionType QString("Type")
#define KXMLQLCFunctionData QString("Data")
#define KXMLQLCFunctionPath QString("Path")
#define KXMLQLCFunctionHidden QString("Hidden")
#define KXMLQLCFunctionBlendMode QString("BlendMode")
#define KXMLQLCFunctionValue QString("Value")
#define KXMLQLCFunctionValueType QString("Type")
#define KXMLQLCFunctionChannel QString("Channel")
#define KXMLQLCFunctionStep QString("Step")
#define KXMLQLCFunctionNumber QString("Number")
#define KXMLQLCFunctionDirection QString("Direction")
#define KXMLQLCFunctionRunOrder QString("RunOrder")
#define KXMLQLCFunctionEnabled QString("Enabled")
#define KXMLQLCFunctionSpeed QString("Speed")
#define KXMLQLCFunctionSpeedFadeIn QString("FadeIn")
#define KXMLQLCFunctionSpeedHold QString("Hold")
#define KXMLQLCFunctionSpeedFadeOut QString("FadeOut")
#define KXMLQLCFunctionSpeedDuration QString("Duration")
typedef struct
{
QString m_name;
qreal m_value;
qreal m_min;
qreal m_max;
int m_flags;
bool m_isOverridden;
qreal m_overrideValue;
} Attribute;
typedef struct
{
int m_attrIndex;
qreal m_value;
} AttributeOverride;
class Function : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(Function)
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(quint32 id READ id CONSTANT)
Q_PROPERTY(Type type READ type CONSTANT)
Q_PROPERTY(quint32 totalDuration READ totalDuration WRITE setTotalDuration NOTIFY totalDurationChanged)
Q_PROPERTY(RunOrder runOrder READ runOrder WRITE setRunOrder NOTIFY runOrderChanged)
Q_PROPERTY(TempoType tempoType READ tempoType WRITE setTempoType NOTIFY tempoTypeChanged FINAL)
public:
/**
* All known function types.
* This is a bit mask to facilitate easy AND-mode type filtering
*/
enum Type
{
Undefined = 0,
SceneType = 1 << 0,
ChaserType = 1 << 1,
EFXType = 1 << 2,
CollectionType = 1 << 3,
ScriptType = 1 << 4,
RGBMatrixType = 1 << 5,
ShowType = 1 << 6,
SequenceType = 1 << 7,
AudioType = 1 << 8
#if QT_VERSION >= 0x050000
, VideoType = 1 << 9
#endif
};
#if QT_VERSION >= 0x050500
Q_ENUM(Type)
#endif
/**
* Common attributes
*/
enum Attr
{
Intensity = 0
};
public:
enum PropType { Name = 0, FadeIn, Hold, FadeOut, Duration, Notes };
#if QT_VERSION >= 0x050500
Q_ENUM(PropType)
#endif
/*********************************************************************
* Initialization
*********************************************************************/
public:
/** Create a new function instance with the given QObject parent. */
Function(QObject* parent = 0);
/**
* Create a new function
*
* @param doc The parent object that owns this function (Doc)
* @param t The function type (see enum Type)
*/
Function(Doc* doc, Type t);
/**
* Destroy this function
*/
virtual ~Function();
/** Get the parent Doc object */
Doc* doc() const;
signals:
/** Signal telling that the contents of this function have changed */
void changed(quint32 fid);
/*********************************************************************
* Copying
*********************************************************************/
public:
/**
* Create a copy of a function to the given doc object and return the
* newly-created function, unless an error has occurred.
*
* @param doc The QLC Doc object that owns all functions
* @param addToDoc enable/disable addition of the function copy to Doc
* @return The newly-created function or NULL in case of an error
*/
virtual Function* createCopy(Doc* doc, bool addToDoc = true);
/**
* Copy this function's contents from the given function. Finally emits
* the changed() signal so don't emit it from subclasses' copyFrom()
* implementations, but call this one just before return.
*
* @param function The function to copy from
* @return true if successful, otherwise false
*/
virtual bool copyFrom(const Function* function);
/*********************************************************************
* ID
*********************************************************************/
public:
/**
* Set this function's unique ID
*
* @param id This function's unique ID
*/
void setID(quint32 id);
/**
* Get this function's unique ID
*/
quint32 id() const;
/**
* Get the value for an invalid function ID (for comparison etc.)
*/
static quint32 invalidId();
private:
quint32 m_id;
/*********************************************************************
* Name
*********************************************************************/
public:
/**
* Set a name for this function
*
* @param name The function's new name
*/
void setName(const QString& name);
/**
* Return the name of this function
*/
QString name() const;
signals:
/** Signal telling that the name of this function have changed */
void nameChanged(quint32 fid);
private:
QString m_name;
/*********************************************************************
* Type
*********************************************************************/
public:
/**
* Return the type of this function (see the enum above)
*/
Type type() const;
/**
* Return the type of this function as a string
*/
QString typeString() const;
/**
* Convert a type to string
*
* @param type The type to convert
*/
static QString typeToString(Function::Type type);
/**
* Convert a string to Type
*
* @param str The string to convert
*/
static Type stringToType(const QString& str);
/** Virtual method to retrieve a QIcon based on a Function type.
* Subclasses should reimplement this */
virtual QIcon getIcon() const;
protected:
Type m_type;
/*********************************************************************
* Path
*********************************************************************/
public:
/** Set the function path for folder grouping */
void setPath(QString path);
/** Retrieve the currently set path */
QString path(bool simplified = false) const;
private:
QString m_path;
/*********************************************************************
* Visibility
*********************************************************************/
public:
/** Set the function visibility status. Hidden Functions will not be displayed in the UI */
void setVisible(bool visible);
/** Retrieve the current visibility status */
bool isVisible() const;
private:
bool m_visible;
/*********************************************************************
* Common XML
*********************************************************************/
protected:
/** Save function's common attributes in $doc, under $root */
bool saveXMLCommon(QXmlStreamWriter *doc) const;
/*********************************************************************
* Running order
*********************************************************************/
public:
enum RunOrder { Loop = 0, SingleShot, PingPong, Random };
#if QT_VERSION >= 0x050500
Q_ENUM(RunOrder)
#endif
public:
/**
* Set this function's running order
*
* @param dir This function's running order
*/
void setRunOrder(const Function::RunOrder& order);
/**
* Get this function's running order
*/
Function::RunOrder runOrder() const;
/**
* Convert a RunOrder to string
*
* @param order RunOrder to convert
*/
static QString runOrderToString(const Function::RunOrder& order);
/**
* Convert a string to RunOrder
*
* @param str The string to convert
*/
static Function::RunOrder stringToRunOrder(const QString& str);
protected:
/** Save function's running order in $doc */
bool saveXMLRunOrder(QXmlStreamWriter *doc) const;
/** Load function's direction from $root */
bool loadXMLRunOrder(QXmlStreamReader &root);
signals:
void runOrderChanged();
private:
RunOrder m_runOrder;
/*********************************************************************
* Direction
*********************************************************************/
public:
enum Direction { Forward = 0, Backward };
#if QT_VERSION >= 0x050500
Q_ENUM(Direction)
#endif
public:
/**
* Set this function's direction
*
* @param dir This function's direction
*/
void setDirection(const Function::Direction& dir);
/**
* Get this function's direction
*/
Function::Direction direction() const;
/**
* Convert a Direction to a string
*
* @param dir Direction to convert
*/
static QString directionToString(const Function::Direction& dir);
/**
* Convert a string to Direction
*
* @param str The string to convert
*/
static Function::Direction stringToDirection(const QString& str);
protected:
/** Save function's direction in $doc */
bool saveXMLDirection(QXmlStreamWriter *doc) const;
/** Load function's direction from $root */
bool loadXMLDirection(QXmlStreamReader &root);
private:
Direction m_direction;
/*********************************************************************
* Tempo type
*********************************************************************/
public:
enum TempoType
{
Original = -1,
Time = 0,
Beats = 1
};
enum FractionsType
{
NoFractions = 0,
ByTwoFractions,
AllFractions
};
#if QT_VERSION >= 0x050500
Q_ENUM(TempoType)
Q_ENUM(FractionsType)
#endif
public:
/**
* Set the speed type of this function.
* When switching from a type to another, the current fade in, hold, fade out
* and duration times will be converted to the new type.
*
* @param type the speed type
*/
void setTempoType(const Function::TempoType& type);
/**
* Get the Function current speed type
*/
Function::TempoType tempoType() const;
/**
* Convert a tempo type to a string
*
* @param type Tempo type to convert
*/
static QString tempoTypeToString(const Function::TempoType& type);
/**
* Convert a string to a tempo type
*
* @param str The string to convert
*/
static Function::TempoType stringToTempoType(const QString& str);
/** Convert a time value in milliseconds to a beat value */
static uint timeToBeats(uint time, int beatDuration);
/** Convert a beat value to a time value in milliseconds */
static uint beatsToTime(uint beats, int beatDuration);
/** Get the override speed type (done by a Chaser) */
TempoType overrideTempoType() const;
/** Set the override speed type (done by a Chaser) */
void setOverrideTempoType(TempoType type);
signals:
void tempoTypeChanged();
protected slots:
/**
* This slot is connected to the Master Timer and it is invoked
* when this Function is in 'Beats' tempo type and the BPM
* number changed. Subclasses should reimplement this.
*/
virtual void slotBPMChanged(int bpmNumber);
private:
TempoType m_tempoType;
TempoType m_overrideTempoType;
bool m_beatResyncNeeded;
/*********************************************************************
* Speed
*********************************************************************/
public:
/** Set the fade in time in milliseconds */
void setFadeInSpeed(uint ms);
/** Get the fade in time in milliseconds */
uint fadeInSpeed() const;
/** Set the fade out time in milliseconds */
void setFadeOutSpeed(uint ms);
/** Get the fade out time in milliseconds */
uint fadeOutSpeed() const;
/** Set the duration in milliseconds */
virtual void setDuration(uint ms);
/** Get the duration in milliseconds */
uint duration() const;
/** Get the total duration in milliseconds.
* This differs from duration as it considers
* the steps or the specific Function parameters */
virtual quint32 totalDuration();
/** Set the total duration in milliseconds.
* This method should be reimplemented only
* by Functions supporting the stretch functionality */
virtual void setTotalDuration(quint32 msec);
/** Set the override fade in speed (done by chaser in Common speed mode) */
void setOverrideFadeInSpeed(uint ms);
/** Get the override fade in speed */
uint overrideFadeInSpeed() const;
/** Set the override fade out speed (done by chaser in Common speed mode) */
void setOverrideFadeOutSpeed(uint ms);
/** Get the override fade out speed */
uint overrideFadeOutSpeed() const;
/** Set the override duration */
void setOverrideDuration(uint ms);
/** Get the override duration */
uint overrideDuration() const;
/** Tell the function that it has been "tapped". Default implementation does nothing. */
virtual void tap();
static uint defaultSpeed();
static uint infiniteSpeed();
/** Pretty-print the given speed into a QString */
static QString speedToString(uint ms);
/** returns value in msec of a string created by speedToString */
static uint stringToSpeed(QString speed);
/** Safe speed operations */
static uint speedNormalize(uint speed);
static uint speedAdd(uint left, uint right);
static uint speedSubtract(uint left, uint right);
signals:
void totalDurationChanged();
protected:
/** Load the contents of a speed node */
bool loadXMLSpeed(QXmlStreamReader &speedRoot);
/** Save function's speed values in $doc */
bool saveXMLSpeed(QXmlStreamWriter *doc) const;
private:
uint m_fadeInSpeed;
uint m_fadeOutSpeed;
uint m_duration;
uint m_overrideFadeInSpeed;
uint m_overrideFadeOutSpeed;
uint m_overrideDuration;
/*********************************************************************
* UI State
*********************************************************************/
public:
/** Get/Set a generic UI property specific to this Function */
QVariant uiStateValue(QString property);
void setUiStateValue(QString property, QVariant value);
/** Get the whole UI state map */
QMap<QString, QVariant> uiStateMap() const;
private:
/** A generic map to temporary store key/value
* pairs that the UI can use to remember how an editor
* was configured. Note: this is not saved into XML */
QMap<QString, QVariant> m_uiState;
/*********************************************************************
* Fixtures
*********************************************************************/
public slots:
/** Slot that captures Doc::fixtureRemoved signals */
virtual void slotFixtureRemoved(quint32 fxi_id);
/*********************************************************************
* Load & Save
*********************************************************************/
public:
/**
* Save this function to an XML document
*
* @param doc The XML document to save to
*/
virtual bool saveXML(QXmlStreamWriter *doc);
/**
* Read this function's contents from an XML document
*
* @param doc An XML document to load from
* @param root An XML root element of a function
*/
virtual bool loadXML(QXmlStreamReader &root);
/**
* Load a new function from an XML tag and add it to the given doc
* object, if loading was successful.
*
* @param root An XML root element of a function
* @param doc The QLC document object, that owns all functions
* @return true if successful, otherwise false
*/
static bool loader(QXmlStreamReader &root, Doc* doc);
/**
* Called for each Function-based object after everything has been loaded.
* Do any post-load cleanup, function mappings etc. if needed. Default
* implementation does nothing.
*/
virtual void postLoad();
/**
* Check if a Function ID is included/controlled by this Function.
* Subclasses should reimplement this.
*/
virtual bool contains(quint32 functionId);
/**
* Return a list of components such as Functions/Fixtures with unique IDs.
* Subclasses should reimplement this.
*/
virtual QList<quint32> components();
/*********************************************************************
* Flash
*********************************************************************/
public:
/** Flash the function */
virtual void flash(MasterTimer* timer, bool shouldOverride, bool forceLTP);
/** UnFlash the function */
virtual void unFlash(MasterTimer* timer);
/** Check, whether the function is flashing */
virtual bool flashing() const;
signals:
/**
* Tells listeners that this function is flashing or that is just
* stopped flashing.
*
* @param fid The flashing function's ID
* @param state true if the function flashing, false if the function
* just stopped flashing
*/
void flashing(quint32 fid, bool state);
private:
bool m_flashing;
/*********************************************************************
* Running
*********************************************************************/
public:
/**
* Called by MasterTimer when the function is started. MasterTimer's
* function list mutex is locked during this call, so functions must
* not attempt to start/stop additional functions from their preRun()
* methods because it would result in a deadlock.
*
* @param timer The MasterTimer instance that takes care of running
* the function in correct intervals.
*/
virtual void preRun(MasterTimer* timer);
/**
* Write next values to universes. This method is called periodically
* by the MasterTimer instance that the
* function has been set to run in, to write the next values to the
* given DMX universe buffer. This method is called for each function
* in the order that they were set to run. When this method has been
* called for each running function, the buffer is written to OutputMap.
*
* MasterTimer calls this method for each function to get their DMX
* data for the given array of universes. This method will be called
* for each running function until Function::stopped() returns true.
*
* @param timer The MasterTimer that is running the function
* @param universes The DMX universe buffer to write values into
*/
virtual void write(MasterTimer* timer, QList<Universe*> universes);
/**
* Called by MasterTimer when the function is stopped. No more write()
* calls will arrive to the function after this call. The function may
* still write its last data packet to $universes during this call or
* hand over channel zero-fading to $timer's generic fader.
*
* MasterTimer's function list mutex is locked during this call, so
* functions must not attempt to start/stop additional functions from
* their postRun() method as it would result in a deadlock situation.
*
* @param timer The MasterTimer that has stopped running the function
* @param universes Universe buffer to write the function's exit data
*/
virtual void postRun(MasterTimer* timer, QList<Universe*> universes);
protected:
/** Helper method to dismiss all the faders previously added to
* m_fadersMap. This is usually called on Function postRun when
* no fade out is requested */
virtual void dismissAllFaders();
signals:
/**
* Emitted when a function is started (i.e. added to MasterTimer's
* list of running functions).
*
* @param id The ID of the started function
*/
void running(quint32 id);
/**
* Emitted when a function is really finished (i.e. removed from
* MasterTimer's list of running functions).
*
* @param id The ID of the stopped function
*/
void stopped(quint32 id);
protected:
/** Map used to lookup a GenericFader instance for a Universe ID */
QMap<quint32, QSharedPointer <GenericFader> > m_fadersMap;
/*********************************************************************
* Elapsed
*********************************************************************/
public:
/**
* Get number of elapsed ticks for this function (0 unless the function
* is running).
*
* @return Number of elapsed timer ticks since the function was started
*/
quint32 elapsed() const;
quint32 elapsedBeats() const;
protected:
/** Reset elapsed timer ticks to zero */
void resetElapsed();
/** Increment the elapsed timer ticks by one */
void incrementElapsed();
/** Increment the elapsed beats by one */
void incrementElapsedBeats();
void roundElapsed(quint32 roundTime);
private:
/* The elapsed time in ms when tempoType is Time */
quint32 m_elapsed;
/* The elapsed beats when tempoType is Beats */
quint32 m_elapsedBeats;
/*********************************************************************
* Start & Stop
*********************************************************************/
public:
/**
* Start running the function in the given MasterTimer instance.
*
* @param timer The MasterTimer that should run the function
* @param child Use true if called from another function
* @param overrideFadeIn Override the function's default fade in speed
* @param overrideFadeOut Override the function's default fade out speed
* @param overrideDuration Override the function's default duration
* @param overrideTempoType Override the tempo type of the function
*/
void start(MasterTimer* timer, FunctionParent parent, quint32 startTime = 0,
uint overrideFadeIn = defaultSpeed(),
uint overrideFadeOut = defaultSpeed(),
uint overrideDuration = defaultSpeed(),
TempoType overrideTempoType = Original);
/**
* Pause a running Function. Subclasses should check the paused state
* immediately in the write call and, in case, return, to avoid performing
* any action and moreover to increment the elapsed time.
* This is declared as virtual for those subclasses where the actual
* Function progress is handled in a separate thread, like multimedia
* functions, or where the Function handles a few children Functions.
*/
virtual void setPause(bool enable);
/**
* Mark the function to be stopped ASAP. MasterTimer will stop running
* the function on the next pass after this method has been called.
* There is no way to cancel it, but the function can be started again
* normally.
*/
void stop(FunctionParent parent, bool preserveAttributes = false);
/**
* Check, whether the function should be stopped ASAP. Functions can use this
* to check, whether they should continue running or bail out.
*
* @return true if the function should be stopped, otherwise false.
*/
bool stopped() const;
/**
* Mark the function to be stopped and block the calling thread until it is
* actually stopped. To prevent deadlocks the function only waits for 2s.
*
* @return true if the function was stopped. false if the function did not
* stop withing two seconds
*/
bool stopAndWait();
/**
* Check, whether the function is currently running (preRun() has been run)
* or not (postRun() has been completed). This should be used only from MasterTimer.
*
* @return true if function is running, false if not
*/
bool isRunning() const;
/**
* Check if the function is currently in a paused state. This is invoked
* by subclasses to understand if they have to do something during the
* write call
*/
bool isPaused() const;
bool startedAsChild() const;
private:
/** Running state flags. The rules are:
* - m_stop resets also m_paused
* - m_paused and m_running can be both true
* - if m_paused is true, a start(...) call will just reset it to false
* These are private to prevent Functions from modifying them. */
bool m_stop;
bool m_running;
bool m_paused;
QList<FunctionParent> m_sources;
QMutex m_sourcesMutex;
QMutex m_stopMutex;
QWaitCondition m_functionStopped;
/*************************************************************************
* Attributes
*************************************************************************/
public:
enum OverrideFlags
{
Multiply = (1 << 0), /** The original attribute value should be multiplied by the overridden values */
LastWins = (1 << 1), /** The original attribute value is overridden by the last requested override value */
Single = (1 << 2) /** Only one attribute override ID will be allowed */
};
static int invalidAttributeId();
/**
* Register a new attribute for this function.
* If the attribute already exists, it will be overwritten.
*
* @param name The attribute name
* @param min The attribute minimum value
* @param max The attribute maximum value
* @param value The attribute initial value
*/
int registerAttribute(QString name, int flags = Multiply, qreal min = 0.0, qreal max = 1.0, qreal value = 1.0);
/**
* Request a new attribute override ID. A Function will always return a new ID,
* that the caller can use in the adjustAttribute method.
*
* @param attributeIndex the attribute index that will be overridden by the caller
* @param value an initial override value
*
* @return an override ID to be used to adjust the overridden value,
* or -1 if the specified $attributeIndex is not valid
*/
int requestAttributeOverride(int attributeIndex, qreal value = 1.0);
/**
* Release an attribute override no longer needed
*
* @param attributeId and ID previously acquired with requestAttributeOverride
*/
void releaseAttributeOverride(int attributeId);
/**
* Unregister a previously created attribute for this function.
* If the attribute doesn't exist, false will be returned.
*
* @param name The attribute name
*/
bool unregisterAttribute(QString name);
/**
* Rename an existing attribute
*
* @param idx the attribute index
* @param newName the new name for the attribute
* @return true on success, false on error
*/
bool renameAttribute(int idx, QString newName);
/**
* Adjust an attribute value with the given new $value.
* If $attributeId is within the registered attributes range,
* the oiginal attribute value will be changed.
* Warning: only Function editors or the Function itself should do this !
* Otherwise, if $attributeId is >= OVERRIDE_ATTRIBUTE_START_ID
* it means the caller wants to control a value override.
* This operation will then recalculate the final override value
* according to the original attribute flags
*
* @param value the new attribute value
* @param attributeId the ID of the attribute to control
*
* @return the original attribute index or -1 on error
*/
virtual int adjustAttribute(qreal value, int attributeId);
/**
* Reset the overridden attributes, while keeping
* the original attribute values unchanged
*/
void resetAttributes();
/**
* Get a specific function attribute by index
*
* @param attributeIndex the attribute index
* @return the requested attribute value (on error return 0.0)
*/
qreal getAttributeValue(int attributeIndex) const;
/**
* Get a specific function attribute by name
*
* @param name the attribute name
* @return the requested attribute index
*/
int getAttributeIndex(QString name) const;
/**
* Get a list of the registered function's attributes
*
* @return a list of Attributes
*/
QList <Attribute> attributes() const;
protected:
/**
* Mark an attribute with the given $attributeIndex as overridden, and
* calculates the final override value according to the registered attribute flags
*
* @param attributeIndex the attribute index
*/
void calculateOverrideValue(int attributeIndex);
signals:
/** Notify the listeners that an attribute has changed */
void attributeChanged(int index, qreal fraction);
private:
/** A list of the registered attributes */
QList <Attribute> m_attributes;
/** A map of the overridden attributes */
QMap <int, AttributeOverride> m_overrideMap;
/** Last assigned override ID */
int m_lastOverrideAttributeId;
/** Flag to preserve or discard attributes on stop calls */
bool m_preserveAttributes;
/*************************************************************************
* Blend mode
*************************************************************************/
public:
/**
* Set a specific blend mode to be used by this Function
* For now this is used only by RGBMatrix but it's been
* placed here for generic usage