Etterna 0.74.4
Loading...
Searching...
No Matches
TimingSegments.h
1#ifndef TIMING_SEGMENTS_H
2#define TIMING_SEGMENTS_H
3
4#include <utility>
5
6#include "NoteTypes.h" // Converting rows to beats and vice~versa.
7
8enum TimingSegmentType
9{
10 SEGMENT_BPM,
11 SEGMENT_STOP,
12 SEGMENT_DELAY,
13 SEGMENT_TIME_SIG,
14 SEGMENT_WARP,
15 SEGMENT_LABEL,
16 SEGMENT_TICKCOUNT,
17 SEGMENT_COMBO,
18 SEGMENT_SPEED,
19 SEGMENT_SCROLL,
20 SEGMENT_FAKE,
21 NUM_TimingSegmentType,
22 TimingSegmentType_Invalid,
23};
24
25// XXX: dumb names
26enum SegmentEffectType
27{
28 SegmentEffectType_Row, // takes effect on a single row
29 SegmentEffectType_Range, // takes effect for a definite amount of rows
30 SegmentEffectType_Indefinite, // takes effect until the next segment of its
31 // type
32 NUM_SegmentEffectType,
33 SegmentEffectType_Invalid,
34};
35
36#define FOREACH_TimingSegmentType(tst) FOREACH_ENUM(TimingSegmentType, tst)
37
38auto
39TimingSegmentTypeToString(TimingSegmentType tst) -> const std::string&;
40
41const int ROW_INVALID = -1;
42
43#define COMPARE(x) \
44 if (this->x != other.x) \
45 return false
46#define COMPARE_FLOAT(x) \
47 if (fabsf(this->x - other.x) > EPSILON) \
48 return false
49
55{
56 [[nodiscard]] virtual auto GetType() const -> TimingSegmentType
57 {
58 return TimingSegmentType_Invalid;
59 }
60
61 [[nodiscard]] virtual auto GetEffectType() const -> SegmentEffectType
62 {
63 return SegmentEffectType_Invalid;
64 }
65
66 [[nodiscard]] virtual auto Copy() const -> TimingSegment* = 0;
67
68 [[nodiscard]] virtual auto IsNotable() const -> bool = 0;
69 virtual void DebugPrint() const;
70
71 // don't allow base TimingSegments to be instantiated directly
72 TimingSegment(int iRow = ROW_INVALID)
73 : m_iStartRow(iRow)
74 {
75 }
76 TimingSegment(float fBeat)
77 : m_iStartRow(ToNoteRow(fBeat))
78 {
79 }
80
81 TimingSegment(const TimingSegment& other)
82 : m_iStartRow(other.GetRow())
83 {
84 }
85
86 // for our purposes, two floats within this level of error are equal
87 static const double EPSILON;
88
89 virtual ~TimingSegment() = default;
90
97 virtual void Scale(int start, int length, int newLength);
98
99 [[nodiscard]] auto GetRow() const -> int { return m_iStartRow; }
100 void SetRow(int iRow) { m_iStartRow = iRow; }
101
102 [[nodiscard]] auto GetBeat() const -> float
103 {
104 return NoteRowToBeat(m_iStartRow);
105 }
106 void SetBeat(float fBeat) { SetRow(BeatToNoteRow(fBeat)); }
107
108 [[nodiscard]] virtual auto ToString(int /* dec */) const -> std::string
109 {
110 return FloatToString(GetBeat());
111 }
112
113 [[nodiscard]] virtual auto GetValues() const -> std::vector<float>
114 {
115 return std::vector<float>(0);
116 }
117
118 auto operator<(const TimingSegment& other) const -> bool
119 {
120 return GetRow() < other.GetRow();
121 }
122
123 // overloads should not call this base version; derived classes
124 // should only compare contents, and this compares position.
125 virtual auto operator==(const TimingSegment& other) const -> bool
126 {
127 return GetRow() == other.GetRow();
128 }
129
130 virtual auto operator!=(const TimingSegment& other) const -> bool
131 {
132 return !this->operator==(other);
133 }
134
135 private:
137 int m_iStartRow;
138};
139
152{
153 [[nodiscard]] auto GetType() const -> TimingSegmentType override
154 {
155 return SEGMENT_FAKE;
156 }
157
158 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
159 {
160 return SegmentEffectType_Range;
161 }
162
163 [[nodiscard]] auto Copy() const -> TimingSegment* override
164 {
165 return new FakeSegment(*this);
166 }
167
168 [[nodiscard]] auto IsNotable() const -> bool override
169 {
170 return m_iLengthRows > 0;
171 }
172 void DebugPrint() const override;
173
174 FakeSegment(int iStartRow, int iLengthRows)
175 : TimingSegment(iStartRow)
176 , m_iLengthRows(iLengthRows)
177 {
178 }
179
180 FakeSegment(int iStartRow, float fBeats)
181 : TimingSegment(iStartRow)
182 , m_iLengthRows(ToNoteRow(fBeats))
183 {
184 }
185
186 FakeSegment(const FakeSegment& other)
187 : TimingSegment(other.GetRow())
188 , m_iLengthRows(other.GetLengthRows())
189 {
190 }
191
192 FakeSegment() = default;
193
194 [[nodiscard]] auto GetLengthRows() const -> int { return m_iLengthRows; }
195 [[nodiscard]] auto GetLengthBeats() const -> float
196 {
197 return ToBeat(m_iLengthRows);
198 }
199 [[nodiscard]] auto GetLength() const -> float
200 {
201 return GetLengthBeats();
202 } // compatibility
203
204 void SetLength(int iRows) { m_iLengthRows = ToNoteRow(iRows); }
205 void SetLength(float fBeats) { m_iLengthRows = ToNoteRow(fBeats); }
206
207 void Scale(int start, int length, int newLength) override;
208
209 [[nodiscard]] auto ToString(int dec) const -> std::string override;
210
211 [[nodiscard]] auto GetValues() const -> std::vector<float> override
212 {
213 return std::vector<float>(1, GetLength());
214 }
215
216 auto operator==(const FakeSegment& other) const -> bool
217 {
218 return m_iLengthRows == other.m_iLengthRows;
219 }
220
221 auto operator==(const TimingSegment& other) const -> bool override
222 {
223 if (GetType() != other.GetType()) {
224 return false;
225 }
226
227 return operator==(static_cast<const FakeSegment&>(other));
228 }
229
230 private:
232 int m_iLengthRows{ -1 };
233};
234
243{
244 [[nodiscard]] auto GetType() const -> TimingSegmentType override
245 {
246 return SEGMENT_WARP;
247 }
248
249 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
250 {
251 return SegmentEffectType_Range;
252 }
253
254 [[nodiscard]] auto Copy() const -> TimingSegment* override
255 {
256 return new WarpSegment(*this);
257 }
258
259 [[nodiscard]] auto IsNotable() const -> bool override
260 {
261 return m_iLengthRows > 0;
262 }
263 void DebugPrint() const override;
264
265 WarpSegment(const WarpSegment& other)
266 : TimingSegment(other.GetRow())
267 , m_iLengthRows(other.GetLengthRows())
268 {
269 }
270
271 WarpSegment(int iStartRow, int iLengthRows)
272 : TimingSegment(iStartRow)
273 , m_iLengthRows(iLengthRows)
274 {
275 }
276
277 WarpSegment(int iStartRow, float fBeats)
278 : TimingSegment(iStartRow)
279 , m_iLengthRows(ToNoteRow(fBeats))
280 {
281 }
282
283 WarpSegment() = default;
284
285 [[nodiscard]] auto GetLengthRows() const -> int { return m_iLengthRows; }
286 [[nodiscard]] auto GetLengthBeats() const -> float
287 {
288 return ToBeat(m_iLengthRows);
289 }
290 [[nodiscard]] auto GetLength() const -> float
291 {
292 return GetLengthBeats();
293 } // compatibility
294
295 void SetLength(int iRows) { m_iLengthRows = ToNoteRow(iRows); }
296 void SetLength(float fBeats) { m_iLengthRows = ToNoteRow(fBeats); }
297
298 void Scale(int start, int length, int newLength) override;
299 [[nodiscard]] auto ToString(int dec) const -> std::string override;
300
301 [[nodiscard]] auto GetValues() const -> std::vector<float> override
302 {
303 return std::vector<float>(1, GetLength());
304 }
305
306 auto operator==(const WarpSegment& other) const -> bool
307 {
308 return m_iLengthRows == other.m_iLengthRows;
309 }
310
311 auto operator==(const TimingSegment& other) const -> bool override
312 {
313 if (GetType() != other.GetType()) {
314 return false;
315 }
316
317 return operator==(static_cast<const WarpSegment&>(other));
318 }
319
320 private:
322 int m_iLengthRows{ 0 };
323};
324
335{
337 static const unsigned DEFAULT_TICK_COUNT = 4;
338
339 [[nodiscard]] auto GetType() const -> TimingSegmentType override
340 {
341 return SEGMENT_TICKCOUNT;
342 }
343
344 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
345 {
346 return SegmentEffectType_Indefinite;
347 }
348
349 [[nodiscard]] auto IsNotable() const -> bool override
350 {
351 return true;
352 } // indefinite segments are always true
353 void DebugPrint() const override;
354
355 [[nodiscard]] auto Copy() const -> TimingSegment* override
356 {
357 return new TickcountSegment(*this);
358 }
359
360 TickcountSegment(int iStartRow = ROW_INVALID,
361 int iTicks = DEFAULT_TICK_COUNT)
362 : TimingSegment(iStartRow)
363 , m_iTicksPerBeat(iTicks)
364 {
365 }
366
368 : TimingSegment(other.GetRow())
369 , m_iTicksPerBeat(other.GetTicks())
370 {
371 }
372
373 [[nodiscard]] auto GetTicks() const -> int { return m_iTicksPerBeat; }
374 void SetTicks(int iTicks) { m_iTicksPerBeat = iTicks; }
375
376 [[nodiscard]] auto ToString(int dec) const -> std::string override;
377
378 [[nodiscard]] auto GetValues() const -> std::vector<float> override
379 {
380 return std::vector<float>(1, GetTicks() * 1.F);
381 }
382
383 auto operator==(const TickcountSegment& other) const -> bool
384 {
385 return m_iTicksPerBeat == other.m_iTicksPerBeat;
386 }
387
388 auto operator==(const TimingSegment& other) const -> bool override
389 {
390 if (GetType() != other.GetType()) {
391 return false;
392 }
393
394 return operator==(static_cast<const TickcountSegment&>(other));
395 }
396
397 private:
399 int m_iTicksPerBeat;
400};
401
409{
410 [[nodiscard]] auto GetType() const -> TimingSegmentType override
411 {
412 return SEGMENT_COMBO;
413 }
414
415 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
416 {
417 return SegmentEffectType_Indefinite;
418 }
419
420 [[nodiscard]] auto IsNotable() const -> bool override
421 {
422 return true;
423 } // indefinite segments are always true
424 void DebugPrint() const override;
425
426 [[nodiscard]] auto Copy() const -> TimingSegment* override
427 {
428 return new ComboSegment(*this);
429 }
430
431 ComboSegment(int iStartRow = ROW_INVALID,
432 int iCombo = 1,
433 int iMissCombo = 1)
434 : TimingSegment(iStartRow)
435 , m_iCombo(iCombo)
436 , m_iMissCombo(iMissCombo)
437 {
438 }
439
440 ComboSegment(const ComboSegment& other)
441 : TimingSegment(other.GetRow())
442 , m_iCombo(other.GetCombo())
443 , m_iMissCombo(other.GetMissCombo())
444 {
445 }
446
447 [[nodiscard]] auto GetCombo() const -> int { return m_iCombo; }
448 [[nodiscard]] auto GetMissCombo() const -> int { return m_iMissCombo; }
449
450 void SetCombo(int iCombo) { m_iCombo = iCombo; }
451 void SetMissCombo(int iCombo) { m_iMissCombo = iCombo; }
452
453 [[nodiscard]] auto ToString(int dec) const -> std::string override;
454 [[nodiscard]] auto GetValues() const -> std::vector<float> override;
455
456 auto operator==(const ComboSegment& other) const -> bool
457 {
458 COMPARE(m_iCombo);
459 COMPARE(m_iMissCombo);
460 return true;
461 }
462
463 auto operator==(const TimingSegment& other) const -> bool override
464 {
465 if (GetType() != other.GetType()) {
466 return false;
467 }
468
469 return operator==(static_cast<const ComboSegment&>(other));
470 }
471
472 private:
474 int m_iCombo;
475
477 int m_iMissCombo;
478};
479
487{
488 [[nodiscard]] auto GetType() const -> TimingSegmentType override
489 {
490 return SEGMENT_LABEL;
491 }
492
493 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
494 {
495 return SegmentEffectType_Indefinite;
496 }
497
498 [[nodiscard]] auto IsNotable() const -> bool override
499 {
500 return true;
501 } // indefinite segments are always true
502 void DebugPrint() const override;
503
504 [[nodiscard]] auto Copy() const -> TimingSegment* override
505 {
506 return new LabelSegment(*this);
507 }
508
509 LabelSegment(int iStartRow = ROW_INVALID,
510 std::string sLabel = std::string())
511 : TimingSegment(iStartRow)
512 , m_sLabel(std::move(sLabel))
513 {
514 }
515
516 LabelSegment(const LabelSegment& other)
517 : TimingSegment(other.GetRow())
518 , m_sLabel(other.GetLabel())
519 {
520 }
521
522 [[nodiscard]] auto GetLabel() const -> const std::string&
523 {
524 return m_sLabel;
525 }
526 void SetLabel(const std::string& sLabel) { m_sLabel.assign(sLabel); }
527
528 [[nodiscard]] auto ToString(int dec) const -> std::string override;
529 // Use the default definition for GetValues because the value for a
530 // LabelSegment is not a float or set of floats. TimingSegmentSetToLuaTable
531 // in TimingData.cpp has a special case for labels to handle this.
532
533 auto operator==(const LabelSegment& other) const -> bool
534 {
535 return m_sLabel == other.m_sLabel;
536 }
537
538 auto operator==(const TimingSegment& other) const -> bool override
539 {
540 if (GetType() != other.GetType()) {
541 return false;
542 }
543
544 return operator==(static_cast<const LabelSegment&>(other));
545 }
546
547 private:
549 std::string m_sLabel;
550};
551
556{
557 [[nodiscard]] auto GetType() const -> TimingSegmentType override
558 {
559 return SEGMENT_BPM;
560 }
561
562 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
563 {
564 return SegmentEffectType_Indefinite;
565 }
566
567 [[nodiscard]] auto IsNotable() const -> bool override
568 {
569 return true;
570 } // indefinite segments are always true
571 void DebugPrint() const override;
572
573 [[nodiscard]] auto Copy() const -> TimingSegment* override
574 {
575 return new BPMSegment(*this);
576 }
577
578 // note that this takes a BPM, not a BPS (compatibility)
579 BPMSegment(int iStartRow = ROW_INVALID, float fBPM = 0.0F)
580 : TimingSegment(iStartRow)
581 {
582 SetBPM(fBPM);
583 }
584
585 BPMSegment(const BPMSegment& other)
586 : TimingSegment(other.GetRow())
587 , m_fBPS(other.GetBPS())
588 {
589 }
590
591 [[nodiscard]] auto GetBPS() const -> float { return m_fBPS; }
592 [[nodiscard]] auto GetBPM() const -> float { return m_fBPS * 60.0F; }
593
594 void SetBPS(float fBPS) { m_fBPS = fBPS; }
595 void SetBPM(float fBPM) { m_fBPS = fBPM / 60.0F; }
596
597 [[nodiscard]] auto ToString(int dec) const -> std::string override;
598
599 [[nodiscard]] auto GetValues() const -> std::vector<float> override
600 {
601 return std::vector<float>(1, GetBPM());
602 }
603
604 auto operator==(const BPMSegment& other) const -> bool
605 {
606 COMPARE_FLOAT(m_fBPS);
607 return true;
608 }
609
610 auto operator==(const TimingSegment& other) const -> bool override
611 {
612 if (GetType() != other.GetType()) {
613 return false;
614 }
615
616 return operator==(static_cast<const BPMSegment&>(other));
617 }
618
619 private:
621 float m_fBPS{};
622};
623
632{
633 [[nodiscard]] auto GetType() const -> TimingSegmentType override
634 {
635 return SEGMENT_TIME_SIG;
636 }
637
638 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
639 {
640 return SegmentEffectType_Indefinite;
641 }
642
643 [[nodiscard]] auto IsNotable() const -> bool override
644 {
645 return true;
646 } // indefinite segments are always true
647 void DebugPrint() const override;
648
649 [[nodiscard]] auto Copy() const -> TimingSegment* override
650 {
651 return new TimeSignatureSegment(*this);
652 }
653
654 TimeSignatureSegment(int iStartRow = ROW_INVALID,
655 int iNum = 4,
656 int iDenom = 4)
657 : TimingSegment(iStartRow)
658 , m_iNumerator(iNum)
659 , m_iDenominator(iDenom)
660 {
661 }
662
664 : TimingSegment(other.GetRow())
665 , m_iNumerator(other.GetNum())
666 , m_iDenominator(other.GetDen())
667 {
668 }
669
670 [[nodiscard]] auto GetNum() const -> int { return m_iNumerator; }
671 void SetNum(int num) { m_iNumerator = num; }
672
673 [[nodiscard]] auto GetDen() const -> int { return m_iDenominator; }
674 void SetDen(int den) { m_iDenominator = den; }
675
676 void Set(int num, int den)
677 {
678 m_iNumerator = num;
679 m_iDenominator = den;
680 }
681
682 [[nodiscard]] auto ToString(int dec) const -> std::string override;
683 [[nodiscard]] auto GetValues() const -> std::vector<float> override;
684
697 [[nodiscard]] auto GetNoteRowsPerMeasure() const -> int
698 {
699 return BeatToNoteRow(1) * 4 * m_iNumerator / m_iDenominator;
700 }
701
702 auto operator==(const TimeSignatureSegment& other) const -> bool
703 {
704 COMPARE(m_iNumerator);
705 COMPARE(m_iDenominator);
706 return true;
707 }
708
709 auto operator==(const TimingSegment& other) const -> bool override
710 {
711 if (GetType() != other.GetType()) {
712 return false;
713 }
714
715 return operator==(static_cast<const TimeSignatureSegment&>(other));
716 }
717
718 private:
719 int m_iNumerator, m_iDenominator;
720};
721
733{
734 [[nodiscard]] auto GetType() const -> TimingSegmentType override
735 {
736 return SEGMENT_SPEED;
737 }
738
739 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
740 {
741 return SegmentEffectType_Indefinite;
742 }
743
744 [[nodiscard]] auto IsNotable() const -> bool override
745 {
746 return true;
747 } // indefinite segments are always true
748 void DebugPrint() const override;
749
750 [[nodiscard]] auto Copy() const -> TimingSegment* override
751 {
752 return new SpeedSegment(*this);
753 }
754
757 {
758 UNIT_BEATS,
759 UNIT_SECONDS
760 };
761
762 SpeedSegment(int iStartRow = ROW_INVALID,
763 float fRatio = 1.0F,
764 float fDelay = 0.0F,
765 BaseUnit unit = UNIT_BEATS)
766 : TimingSegment(iStartRow)
767 , m_fRatio(fRatio)
768 , m_fDelay(fDelay)
769 , m_Unit(unit)
770 {
771 }
772
773 SpeedSegment(const SpeedSegment& other)
774 : TimingSegment(other.GetRow())
775 , m_fRatio(other.GetRatio())
776 , m_fDelay(other.GetDelay())
777 , m_Unit(other.GetUnit())
778 {
779 }
780
781 [[nodiscard]] auto GetRatio() const -> float { return m_fRatio; }
782 void SetRatio(float fRatio) { m_fRatio = fRatio; }
783
784 [[nodiscard]] auto GetDelay() const -> float { return m_fDelay; }
785 void SetDelay(float fDelay) { m_fDelay = fDelay; }
786
787 [[nodiscard]] auto GetUnit() const -> BaseUnit { return m_Unit; }
788 void SetUnit(BaseUnit unit) { m_Unit = unit; }
789
790 void Scale(int start, int length, int newLength) override;
791
792 [[nodiscard]] auto ToString(int dec) const -> std::string override;
793 [[nodiscard]] auto GetValues() const -> std::vector<float> override;
794
795 auto operator==(const SpeedSegment& other) const -> bool
796 {
797 COMPARE_FLOAT(m_fRatio);
798 COMPARE_FLOAT(m_fDelay);
799 COMPARE(m_Unit);
800 return true;
801 }
802
803 auto operator==(const TimingSegment& other) const -> bool override
804 {
805 if (GetType() != other.GetType()) {
806 return false;
807 }
808
809 return operator==(static_cast<const SpeedSegment&>(other));
810 }
811
812 private:
814 float m_fRatio;
815
819 float m_fDelay;
820
822 BaseUnit m_Unit;
823};
824
834{
835 [[nodiscard]] auto GetType() const -> TimingSegmentType override
836 {
837 return SEGMENT_SCROLL;
838 }
839
840 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
841 {
842 return SegmentEffectType_Indefinite;
843 }
844
845 [[nodiscard]] auto IsNotable() const -> bool override
846 {
847 return true;
848 } // indefinite segments are always true
849 void DebugPrint() const override;
850
851 [[nodiscard]] auto Copy() const -> TimingSegment* override
852 {
853 return new ScrollSegment(*this);
854 }
855
856 ScrollSegment(int iStartRow = ROW_INVALID, float fRatio = 1.0F)
857 : TimingSegment(iStartRow)
858 , m_fRatio(fRatio)
859 {
860 }
861
862 ScrollSegment(const ScrollSegment& other)
863 : TimingSegment(other.GetRow())
864 , m_fRatio(other.GetRatio())
865 {
866 }
867
868 [[nodiscard]] auto GetRatio() const -> float { return m_fRatio; }
869 void SetRatio(float fRatio) { m_fRatio = fRatio; }
870
871 [[nodiscard]] auto ToString(int dec) const -> std::string override;
872
873 [[nodiscard]] auto GetValues() const -> std::vector<float> override
874 {
875 return std::vector<float>(1, GetRatio());
876 }
877
878 auto operator==(const ScrollSegment& other) const -> bool
879 {
880 COMPARE_FLOAT(m_fRatio);
881 return true;
882 }
883
884 auto operator==(const TimingSegment& other) const -> bool override
885 {
886 if (GetType() != other.GetType()) {
887 return false;
888 }
889
890 return operator==(static_cast<const ScrollSegment&>(other));
891 }
892
893 private:
895 float m_fRatio;
896};
897
902{
903 [[nodiscard]] auto GetType() const -> TimingSegmentType override
904 {
905 return SEGMENT_STOP;
906 }
907
908 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
909 {
910 return SegmentEffectType_Row;
911 }
912
913 [[nodiscard]] auto IsNotable() const -> bool override
914 {
915 return m_fSeconds > 0;
916 }
917 void DebugPrint() const override;
918
919 [[nodiscard]] auto Copy() const -> TimingSegment* override
920 {
921 return new StopSegment(*this);
922 }
923
924 StopSegment(int iStartRow = ROW_INVALID, float fSeconds = 0.0F)
925 : TimingSegment(iStartRow)
926 , m_fSeconds(fSeconds)
927 {
928 }
929
930 StopSegment(const StopSegment& other)
931 : TimingSegment(other.GetRow())
932 , m_fSeconds(other.GetPause())
933 {
934 }
935
936 [[nodiscard]] auto GetPause() const -> float { return m_fSeconds; }
937 void SetPause(float fSeconds) { m_fSeconds = fSeconds; }
938
939 [[nodiscard]] auto ToString(int dec) const -> std::string override;
940
941 [[nodiscard]] auto GetValues() const -> std::vector<float> override
942 {
943 return std::vector<float>(1, GetPause());
944 }
945
946 auto operator==(const StopSegment& other) const -> bool
947 {
948 COMPARE_FLOAT(m_fSeconds);
949 return true;
950 }
951
952 auto operator==(const TimingSegment& other) const -> bool override
953 {
954 if (GetType() != other.GetType()) {
955 return false;
956 }
957
958 return operator==(static_cast<const StopSegment&>(other));
959 }
960
961 private:
963 float m_fSeconds;
964};
965
970{
971 [[nodiscard]] auto GetType() const -> TimingSegmentType override
972 {
973 return SEGMENT_DELAY;
974 }
975
976 [[nodiscard]] auto GetEffectType() const -> SegmentEffectType override
977 {
978 return SegmentEffectType_Row;
979 }
980
981 [[nodiscard]] auto IsNotable() const -> bool override
982 {
983 return m_fSeconds > 0;
984 }
985 void DebugPrint() const override;
986
987 [[nodiscard]] auto Copy() const -> TimingSegment* override
988 {
989 return new DelaySegment(*this);
990 }
991
992 DelaySegment(int iStartRow = ROW_INVALID, float fSeconds = 0)
993 : TimingSegment(iStartRow)
994 , m_fSeconds(fSeconds)
995 {
996 }
997
998 DelaySegment(const DelaySegment& other)
999 : TimingSegment(other.GetRow())
1000 , m_fSeconds(other.GetPause())
1001 {
1002 }
1003
1004 [[nodiscard]] auto GetPause() const -> float { return m_fSeconds; }
1005 void SetPause(float fSeconds) { m_fSeconds = fSeconds; }
1006
1007 [[nodiscard]] auto ToString(int dec) const -> std::string override;
1008
1009 [[nodiscard]] auto GetValues() const -> std::vector<float> override
1010 {
1011 return std::vector<float>(1, GetPause());
1012 }
1013
1014 auto operator==(const DelaySegment& other) const -> bool
1015 {
1016 COMPARE_FLOAT(m_fSeconds);
1017 return true;
1018 }
1019
1020 auto operator==(const TimingSegment& other) const -> bool override
1021 {
1022 if (GetType() != other.GetType()) {
1023 return false;
1024 }
1025
1026 return operator==(static_cast<const DelaySegment&>(other));
1027 }
1028
1029 private:
1031 float m_fSeconds;
1032};
1033
1034#undef COMPARE
1035#undef COMPARE_FLOAT
1036
1037#endif
Identifies when a song changes its BPM.
Definition TimingSegments.h:556
Identifies when a chart is to have a different combo multiplier value.
Definition TimingSegments.h:409
Identifies when a song has a delay, or pump style stop.
Definition TimingSegments.h:970
Identifies when a whole region of arrows is to be ignored.
Definition TimingSegments.h:152
void Scale(int start, int length, int newLength) override
Scales itself.
Definition TimingSegments.cpp:157
Identifies when a chart is entering a different section.
Definition TimingSegments.h:487
Identifies when the chart scroll changes.
Definition TimingSegments.h:834
Identifies when the arrow scroll changes.
Definition TimingSegments.h:733
BaseUnit
The type of unit used for segment scaling.
Definition TimingSegments.h:757
void Scale(int start, int length, int newLength) override
Scales itself.
Definition TimingSegments.cpp:279
Identifies when a song has a stop, DDR/ITG style.
Definition TimingSegments.h:902
Identifies when a chart is to have a different tickcount value for hold notes.
Definition TimingSegments.h:335
static const unsigned DEFAULT_TICK_COUNT
The default amount of ticks per beat.
Definition TimingSegments.h:337
Identifies when a song changes its time signature.
Definition TimingSegments.h:632
auto GetNoteRowsPerMeasure() const -> int
Retrieve the number of note rows per measure within the TimeSignatureSegment.
Definition TimingSegments.h:697
The base timing segment for make glorious benefit wolfman XXX: this should be an abstract class.
Definition TimingSegments.h:55
virtual void Scale(int start, int length, int newLength)
Scales itself.
Definition TimingSegments.cpp:21
Identifies when a song needs to warp to a new beat.
Definition TimingSegments.h:243
void Scale(int start, int length, int newLength) override
Scales itself.
Definition TimingSegments.cpp:182