kipphi 2.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/jumparray.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { NodeType } from "./util";
2
+ import Env from "./env";
2
3
 
3
4
  // type EndBeats = number;
4
- const MIN_LENGTH = 128
5
- const MAX_LENGTH = 1024
6
- const MINOR_PARTS = 16;
7
5
  /// #declaration:global
8
6
 
9
7
  type EndNextFn<T extends TwoDirectionNodeLike> = (node: T) => [endBeats: number, next: T];
@@ -23,6 +21,7 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
23
21
  averageBeats: number;
24
22
  effectiveBeats: number;
25
23
  goPrev: (node: T) => T;
24
+ readonly MINOR_SCALE_COUNT: number = Env.JUMPARRAY_MINOR_SCALE_COUNT;
26
25
 
27
26
  /**
28
27
  *
@@ -46,7 +45,7 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
46
45
  this.header = head;
47
46
  this.tailer = tail;
48
47
  // const originalListLength = this.listLength
49
- const listLength: number = Math.max(MIN_LENGTH, Math.min(originalListLength * 4, MAX_LENGTH));
48
+ const listLength: number = Math.max(Env.JUMPARRAY_MIN_LENGTH, Math.min(originalListLength * 4, Env.JUMPARRAY_MAX_LENGTH));
50
49
  const averageBeats: number = Math.pow(2, Math.ceil(Math.log2(effectiveBeats / listLength)));
51
50
  const exactLength: number = Math.ceil(effectiveBeats / averageBeats);
52
51
  // console.log(exactLength, listLength, averageBeats, exactLength)
@@ -91,6 +90,7 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
91
90
  updateRange(firstNode: T, lastNode: T) {
92
91
  const {endNextFn, effectiveBeats, resolveLastNode} = this;
93
92
  lastNode = resolveLastNode(lastNode);
93
+ const MINOR_PARTS = this.MINOR_SCALE_COUNT;
94
94
  // console.log(firstNode, lastNode)
95
95
  /**
96
96
  *
@@ -125,16 +125,13 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
125
125
  if (Array.isArray(jumpArray[jumpIndex])) {
126
126
  fillMinor(previousEndTime, endTime)
127
127
  } else {
128
- try {
129
- // console.log(jumpIndex, currentNode)
130
128
  jumpArray[jumpIndex] = currentNode;
131
- } catch (E) {console.log(jumpIndex, jumpArray);debugger}
132
129
  }
133
130
  jumpIndex++;
134
131
  }
135
132
  const currentJumpBeats: number = jumpIndex * averageBeats // 放错了
136
133
  if (endTime > currentJumpBeats) {
137
- let minor = jumpArray[jumpIndex];
134
+ const minor = jumpArray[jumpIndex];
138
135
  if (!Array.isArray(minor)) {
139
136
  jumpArray[jumpIndex] = new Array(MINOR_PARTS);
140
137
  }
@@ -175,8 +172,9 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
175
172
  const jumpAverageBeats = this.averageBeats;
176
173
  const jumpPos = Math.floor(beats / jumpAverageBeats);
177
174
  const rest = beats - jumpPos * jumpAverageBeats;
175
+ const MINOR_PARTS = this.MINOR_SCALE_COUNT;
178
176
  for (let i = jumpPos; i >= 0; i--) {
179
- let canBeNodeOrArray: T | T[] = this.array[i];
177
+ const canBeNodeOrArray: T | T[] = this.array[i];
180
178
  if (Array.isArray(canBeNodeOrArray)) {
181
179
  const minorIndex = Math.floor(rest / (jumpAverageBeats / MINOR_PARTS)) - 1;
182
180
  for (let j = minorIndex; j >= 0; j--) {
@@ -202,11 +200,12 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
202
200
  if (beats >= this.effectiveBeats) {
203
201
  return this.tailer;
204
202
  }
203
+ const MINOR_PARTS = this.MINOR_SCALE_COUNT;
205
204
  const jumpAverageBeats = this.averageBeats;
206
205
  const jumpPos = Math.floor(beats / jumpAverageBeats);
207
206
  const rest = beats - jumpPos * jumpAverageBeats;
208
207
  const nextFn = this.nextFn;
209
- let canBeNodeOrArray: T | T[] = this.array[jumpPos]
208
+ const canBeNodeOrArray: T | T[] = this.array[jumpPos]
210
209
  let node: T = Array.isArray(canBeNodeOrArray)
211
210
  ? canBeNodeOrArray[Math.floor(rest / (jumpAverageBeats / MINOR_PARTS))]
212
211
  : canBeNodeOrArray;
@@ -216,10 +215,11 @@ export class JumpArray<T extends TwoDirectionNodeLike> {
216
215
  // console.log(this, node, jumpPos, beats)
217
216
  if (!node) {
218
217
  console.warn("No node:", node, beats)
219
- debugger
218
+ throw new Error();
220
219
  }
221
220
  let next: T | false;
222
221
  // console.log(this)
222
+ // eslint-disable-next-line no-cond-assign
223
223
  while (next = nextFn(node, beats)) {
224
224
  node = next;
225
225
  if (node.type === NodeType.TAIL) {
package/note.ts CHANGED
@@ -5,30 +5,17 @@ import type { Chart } from "./chart";
5
5
  import { NoteType, type NNListDataKPA, type NoteDataKPA, type NoteDataRPE, type NoteNodeDataKPA, type TimeT } from "./chartTypes";
6
6
  import type { JudgeLine } from "./judgeline";
7
7
  import { JumpArray } from "./jumparray";
8
- import { TimeCalculator } from "./time";
8
+ import { type TimeCalculator } from "./bpm";
9
+ import TC from "./time";
9
10
  import { hex2rgb, NodeType, rgb2hex } from "./util";
10
11
 
11
12
  /// #declaration:global
12
13
 
13
- const TC = TimeCalculator;
14
14
 
15
15
  export type HEX = number;
16
16
 
17
17
 
18
18
 
19
- const node2string = (node: AnyNN) => {
20
- if (!node) {
21
- return "" + node
22
- }
23
- if (node.type === NodeType.HEAD || node.type === NodeType.TAIL) {
24
- return node.type === NodeType.HEAD ? "H" : node.type === NodeType.TAIL ? "T" : "???"
25
- }
26
- if (!node.notes) {
27
- return "EventNode"
28
- }
29
- return `NN(${node.notes.length}) at ${node.startTime}`
30
- }
31
-
32
19
 
33
20
 
34
21
  export const notePropTypes = {
@@ -98,18 +85,18 @@ export class Note {
98
85
  // posNext?: Note;
99
86
  // posPreviousSibling?: Note;
100
87
  // posNextSibling: Note;
101
- constructor(data: NoteDataRPE) {
88
+ constructor(data: NoteDataRPE | NoteDataKPA) {
102
89
  this.above = data.above === 1;
103
90
  this.alpha = data.alpha ?? 255;
104
- this.endTime = data.type === NoteType.hold ? TimeCalculator.validateIp(data.endTime) : TimeCalculator.validateIp([...data.startTime]);
91
+ this.endTime = data.type === NoteType.hold ? TC.validateIp(data.endTime) : TC.validateIp([...data.startTime]);
105
92
  this.isFake = Boolean(data.isFake);
106
93
  this.positionX = data.positionX;
107
94
  this.size = data.size ?? 1.0;
108
95
  this.speed = data.speed ?? 1.0;
109
- this.startTime = TimeCalculator.validateIp(data.startTime);
96
+ this.startTime = TC.validateIp(data.startTime);
110
97
  this.type = data.type;
111
98
  this.visibleTime = data.visibleTime;
112
- // @ts-expect-error
99
+ // @ts-expect-error 若data是RPE数据,则为undefined,无影响。
113
100
  this.yOffset = data.absoluteYOffset ?? data.yOffset * this.speed;
114
101
  // @ts-expect-error 若data是RPE数据,则为undefined,无影响。
115
102
  // 当然也有可能是KPA数据但是就是没有给
@@ -137,7 +124,7 @@ export class Note {
137
124
  this.visibleBeats = Infinity;
138
125
  return;
139
126
  }
140
- const hitBeats = TimeCalculator.toBeats(this.startTime);
127
+ const hitBeats = TC.toBeats(this.startTime);
141
128
  const hitSeconds = timeCalculator.toSeconds(hitBeats);
142
129
  const visabilityChangeSeconds = hitSeconds - this.visibleTime;
143
130
  const visabilityChangeBeats = timeCalculator.secondsToBeats(visabilityChangeSeconds);
@@ -150,8 +137,8 @@ export class Note {
150
137
  */
151
138
  clone(offset: TimeT) {
152
139
  const data = this.dumpKPA();
153
- data.startTime = TimeCalculator.add(data.startTime, offset);
154
- data.endTime = TimeCalculator.add(data.endTime, offset); // 踩坑
140
+ data.startTime = TC.add(data.startTime, offset);
141
+ data.endTime = TC.add(data.endTime, offset); // 踩坑
155
142
  return new Note(data);
156
143
  }
157
144
  /*
@@ -167,7 +154,7 @@ export class Note {
167
154
  dumpRPE(timeCalculator: TimeCalculator): NoteDataRPE {
168
155
  let visibleTime: number;
169
156
  if (this.visibleBeats !== Infinity) {
170
- const beats = TimeCalculator.toBeats(this.startTime);
157
+ const beats = TC.toBeats(this.startTime);
171
158
  this.visibleBeats = timeCalculator.segmentToSeconds(beats - this.visibleBeats, beats);
172
159
  } else {
173
160
  visibleTime = 99999.0
@@ -211,7 +198,6 @@ export class Note {
211
198
  }
212
199
  }
213
200
 
214
- type Connectee = NoteNode | NNNode
215
201
 
216
202
 
217
203
 
@@ -254,13 +240,13 @@ export class NoteNode extends NoteNodeLike<NodeType.MIDDLE> {
254
240
  id: number;
255
241
  constructor(time: TimeT) {
256
242
  super(NodeType.MIDDLE);
257
- this.startTime = TimeCalculator.validateIp([...time]);
243
+ this.startTime = TC.validateIp([...time]);
258
244
  this.notes = [];
259
245
  this.id = NoteNode.count++;
260
246
  }
261
247
  static fromKPAJSON(data: NoteNodeDataKPA, timeCalculator: TimeCalculator) {
262
248
  const node = new NoteNode(data.startTime);
263
- for (let noteData of data.notes) {
249
+ for (const noteData of data.notes) {
264
250
  const note = Note.fromKPAJSON(noteData, timeCalculator);
265
251
  node.add(note);
266
252
  }
@@ -276,7 +262,7 @@ export class NoteNode extends NoteNodeLike<NodeType.MIDDLE> {
276
262
  return (this.notes.length === 0 || this.notes[0].type !== NoteType.hold) ? this.startTime : this.notes[0].endTime
277
263
  }
278
264
  add(note: Note) {
279
- if (!TimeCalculator.eq(note.startTime, this.startTime)) {
265
+ if (!TC.eq(note.startTime, this.startTime)) {
280
266
  console.warn("Wrong addition!")
281
267
  }
282
268
  this.notes.push(note);
@@ -303,7 +289,7 @@ export class NoteNode extends NoteNodeLike<NodeType.MIDDLE> {
303
289
  const note = notes[index];
304
290
  for (let i = index; i > 0; i--) {
305
291
  const prev = notes[i - 1];
306
- if (TimeCalculator.lt(prev.endTime, note.endTime)) {
292
+ if (TC.lt(prev.endTime, note.endTime)) {
307
293
  // swap
308
294
  notes[i] = prev;
309
295
  notes[i - 1] = note;
@@ -313,7 +299,7 @@ export class NoteNode extends NoteNodeLike<NodeType.MIDDLE> {
313
299
  }
314
300
  for (let i = index; i < notes.length - 1; i++) {
315
301
  const next = notes[i + 1];
316
- if (TimeCalculator.gt(next.endTime, note.endTime)) {
302
+ if (TC.gt(next.endTime, note.endTime)) {
317
303
  // swap
318
304
  notes[i] = next;
319
305
  notes[i + 1] = note;
@@ -410,7 +396,7 @@ export class NNList {
410
396
  if (prev.type === NodeType.HEAD) {
411
397
  return;
412
398
  }
413
- this.effectiveBeats = TimeCalculator.toBeats(prev.endTime)
399
+ this.effectiveBeats = TC.toBeats(prev.endTime)
414
400
  }
415
401
  const effectiveBeats: number = this.effectiveBeats;
416
402
  this.jump = new JumpArray<AnyNN>(
@@ -423,12 +409,11 @@ export class NNList {
423
409
  return [null, null]
424
410
  }
425
411
  const nextNode = node.next;
426
- const startTime = (node.type === NodeType.HEAD) ? 0 : TimeCalculator.toBeats(node.startTime)
412
+ const startTime = (node.type === NodeType.HEAD) ? 0 : TC.toBeats(node.startTime)
427
413
  return [startTime, nextNode]
428
414
  },
429
- // @ts-ignore
430
415
  (note: NoteNode, beats: number) => {
431
- return TimeCalculator.toBeats(note.startTime) >= beats ? false : <NoteNode>note.next; // getNodeAt有guard
416
+ return TC.toBeats(note.startTime) >= beats ? false : <NoteNode>note.next; // getNodeAt有guard
432
417
  })
433
418
  }
434
419
  /**
@@ -447,12 +432,12 @@ export class NNList {
447
432
  * @returns
448
433
  */
449
434
  getNodeOf(time: TimeT): NoteNode {
450
- let node = this.getNodeAt(TimeCalculator.toBeats(time), false)
435
+ let node = this.getNodeAt(TC.toBeats(time), false)
451
436
  .previous;
452
437
 
453
438
 
454
- let isEqual = node.type !== NodeType.HEAD && TimeCalculator.eq((node as NoteNode).startTime, time)
455
- if (node.next.type !== NodeType.TAIL && TimeCalculator.eq((node.next as NoteNode).startTime, time)) {
439
+ let isEqual = node.type !== NodeType.HEAD && TC.eq((node as NoteNode).startTime, time)
440
+ if (node.next.type !== NodeType.TAIL && TC.eq((node.next as NoteNode).startTime, time)) {
456
441
  isEqual = true;
457
442
  node = node.next;
458
443
  }
@@ -567,14 +552,12 @@ export class HNList extends NNList {
567
552
  if (node.type === NodeType.TAIL) {
568
553
  return [null, null]
569
554
  }
570
- if (!node) debugger
571
555
  const nextNode = node.next;
572
- const endTime = node.type === NodeType.HEAD ? 0 : TimeCalculator.toBeats(node.endTime)
556
+ const endTime = node.type === NodeType.HEAD ? 0 : TC.toBeats(node.endTime)
573
557
  return [endTime, nextNode]
574
558
  },
575
- // @ts-ignore
576
559
  (node: NoteNode, beats: number) => {
577
- return TimeCalculator.toBeats(node.endTime) >= beats ? false : <NoteNode>node.next; // getNodeAt有guard
560
+ return TC.toBeats(node.endTime) >= beats ? false : <NoteNode>node.next; // getNodeAt有guard
578
561
  }
579
562
  )
580
563
  }
@@ -596,7 +579,7 @@ export type NNNOrHead = NNNode | NNNodeLike<NodeType.HEAD>;
596
579
  export type NNNOrTail = NNNode | NNNodeLike<NodeType.TAIL>;
597
580
  type AnyNNN = NNNode | NNNodeLike<NodeType.HEAD> | NNNodeLike<NodeType.TAIL>;
598
581
 
599
- class NNNodeLike<T extends NodeType> {
582
+ export class NNNodeLike<T extends NodeType> {
600
583
  previous: NNNOrHead;
601
584
  next: NNNOrTail;
602
585
  startTime: TimeT;
@@ -618,7 +601,7 @@ export class NNNode extends NNNodeLike<NodeType.MIDDLE> {
618
601
  super(NodeType.MIDDLE);
619
602
  this.noteNodes = []
620
603
  this.holdNodes = [];
621
- this.startTime = TimeCalculator.validateIp([...time])
604
+ this.startTime = TC.validateIp([...time])
622
605
  }
623
606
  get endTime() {
624
607
  let latest: TimeT = this.startTime;
@@ -681,7 +664,7 @@ export class NNNList {
681
664
  const originalListLength = this.timesWithNotes || 512;
682
665
  /*
683
666
  if (!this.effectiveBeats) {
684
- this.effectiveBeats = TimeCalculator.toBeats(this.tail.previous.endTime)
667
+ this.effectiveBeats = TC.toBeats(this.tail.previous.endTime)
685
668
  }
686
669
  */
687
670
  const effectiveBeats: number = this.effectiveBeats;
@@ -695,25 +678,19 @@ export class NNNList {
695
678
  return [null, null]
696
679
  }
697
680
  const nextNode = node.next;
698
- const startTime = node.type === NodeType.HEAD ? 0 : TimeCalculator.toBeats((node as NNNode).startTime)
681
+ const startTime = node.type === NodeType.HEAD ? 0 : TC.toBeats((node as NNNode).startTime)
699
682
  return [startTime, nextNode]
700
683
  },
701
- // @ts-ignore
702
684
  (note: NNNode, beats: number) => {
703
- return TimeCalculator.toBeats(note.startTime) >= beats ? false : <NNNode>note.next; // getNodeAt有guard
704
- }
705
- /*,
706
- (note: Note) => {
707
- const prev = note.previous;
708
- return prev.type === NodeType.HEAD ? note : prev
709
- })*/)
685
+ return TC.toBeats(note.startTime) >= beats ? false : <NNNode>note.next; // getNodeAt有guard
686
+ })
710
687
  }
711
688
  getNodeAt(beats: number, beforeEnd=false): NNNode | NNNodeLike<NodeType.TAIL> {
712
689
  return this.jump.getNodeAt(beats) as NNNode | NNNodeLike<NodeType.TAIL>;
713
690
  }
714
691
  getNode(time: TimeT): NNNode {
715
- const node = this.getNodeAt(TimeCalculator.toBeats(time), false).previous;
716
- if (node.type === NodeType.HEAD || TimeCalculator.ne((node as NNNode).startTime, time)) {
692
+ const node = this.getNodeAt(TC.toBeats(time), false).previous;
693
+ if (node.type === NodeType.HEAD || TC.ne((node as NNNode).startTime, time)) {
717
694
  const newNode = new NNNode(time);
718
695
  const next = node.next
719
696
  NNNode.insert(node, newNode, next);