MusicPartManager.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { MusicSheet } from "../MusicSheet";
  2. import { PartListEntry } from "../MusicSource/PartListEntry";
  3. import { Repetition } from "../MusicSource/Repetition";
  4. import { Fraction } from "../../Common/DataObjects/Fraction";
  5. import { MusicPartManagerIterator } from "./MusicPartManagerIterator";
  6. export class MusicPartManager /*implements ISelectionListener*/ {
  7. constructor(musicSheet: MusicSheet) {
  8. this.musicSheet = musicSheet;
  9. }
  10. private parts: PartListEntry[];
  11. private timestamps: TimestampTransform[];
  12. private musicSheet: MusicSheet;
  13. private sheetStart: Fraction;
  14. private sheetEnd: Fraction;
  15. public reInit(): void {
  16. this.init();
  17. }
  18. public init(): void {
  19. this.parts = this.musicSheet.Repetitions.slice();
  20. this.sheetStart = this.musicSheet.SelectionStart = new Fraction(0, 1);
  21. this.sheetEnd = this.musicSheet.SelectionEnd = this.musicSheet.SheetEndTimestamp;
  22. this.calcMapping();
  23. }
  24. public getCurrentRepetitionTimestampTransform(curEnrolledTimestamp: Fraction): TimestampTransform {
  25. let curTransform: TimestampTransform = undefined;
  26. for (let i: number = this.timestamps.length - 1; i >= 0; i--) {
  27. curTransform = this.timestamps[i];
  28. if (curEnrolledTimestamp >= curTransform.$from) {
  29. return curTransform;
  30. }
  31. }
  32. return this.timestamps[0];
  33. }
  34. public absoluteEnrolledToSheetTimestamp(timestamp: Fraction): Fraction {
  35. if (this.timestamps.length === 0) {
  36. return timestamp;
  37. }
  38. let transform: TimestampTransform = this.getCurrentRepetitionTimestampTransform(timestamp);
  39. return Fraction.plus(timestamp, Fraction.minus(transform.to, transform.$from)); // FIXME
  40. }
  41. public get Parts(): PartListEntry[] {
  42. return this.parts;
  43. }
  44. public get MusicSheet(): MusicSheet {
  45. return this.musicSheet;
  46. }
  47. public getIterator(start?: Fraction): MusicPartManagerIterator {
  48. if (start === undefined) {
  49. return new MusicPartManagerIterator(this, this.musicSheet.SelectionStart, this.musicSheet.SelectionEnd);
  50. }
  51. return new MusicPartManagerIterator(this, start, undefined);
  52. }
  53. public setSelectionStart(beginning: Fraction): void {
  54. this.musicSheet.SelectionStart = beginning;
  55. this.musicSheet.SelectionEnd = undefined;
  56. }
  57. public setSelectionRange(start: Fraction, end: Fraction): void {
  58. this.musicSheet.SelectionStart = start === undefined ? this.sheetStart : start;
  59. this.musicSheet.SelectionEnd = end === undefined ? this.sheetEnd : end;
  60. }
  61. private calcMapping(): void {
  62. let timestamps: TimestampTransform[] = [];
  63. let iterator: MusicPartManagerIterator = this.getIterator();
  64. let currentRepetition: Repetition = iterator.CurrentRepetition;
  65. let curTimestampTransform: TimestampTransform = new TimestampTransform(
  66. iterator.CurrentEnrolledTimestamp.clone(),
  67. iterator.CurrentSourceTimestamp.clone(),
  68. undefined,
  69. 0
  70. );
  71. timestamps.push(curTimestampTransform);
  72. while (!iterator.EndReached) {
  73. if (iterator.JumpOccurred || currentRepetition !== iterator.CurrentRepetition) {
  74. currentRepetition = iterator.CurrentRepetition;
  75. if (iterator.backJumpOccurred) {
  76. let jumpRep: Repetition = iterator.JumpResponsibleRepetition;
  77. curTimestampTransform.nextBackJump = iterator.CurrentEnrolledTimestamp;
  78. curTimestampTransform.curRepetition = jumpRep;
  79. curTimestampTransform.curRepetitionIteration = iterator.CurrentJumpResponsibleRepetitionIterationBeforeJump;
  80. for (let i: number = this.timestamps.length - 2; i >= 0; i--) {
  81. if (jumpRep.AbsoluteTimestamp > timestamps[i].to || timestamps[i].curRepetition !== undefined) {
  82. break;
  83. }
  84. timestamps[i].nextBackJump = curTimestampTransform.nextBackJump;
  85. timestamps[i].curRepetition = jumpRep;
  86. timestamps[i].curRepetitionIteration = curTimestampTransform.curRepetitionIteration;
  87. }
  88. }
  89. curTimestampTransform = new TimestampTransform(
  90. iterator.CurrentEnrolledTimestamp.clone(),
  91. iterator.CurrentSourceTimestamp.clone(),
  92. undefined,
  93. 0
  94. );
  95. timestamps.push(curTimestampTransform);
  96. }
  97. iterator.moveToNext();
  98. }
  99. this.timestamps = timestamps;
  100. }
  101. }
  102. export class TimestampTransform {
  103. constructor(sourceTimestamp: Fraction, enrolledTimestamp: Fraction, repetition: Repetition, curRepetitionIteration: number) {
  104. this.$from = sourceTimestamp;
  105. this.to = enrolledTimestamp;
  106. this.curRepetition = repetition;
  107. this.curRepetitionIteration = curRepetitionIteration;
  108. this.nextBackJump = undefined;
  109. this.nextForwardJump = undefined;
  110. }
  111. public $from: Fraction;
  112. public to: Fraction;
  113. public nextBackJump: Fraction;
  114. public nextForwardJump: Fraction;
  115. public curRepetition: Repetition;
  116. public curRepetitionIteration: number;
  117. }