@byloth/core 2.0.0-rc.3 → 2.0.0-rc.5

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.
@@ -35,5 +35,5 @@ export default class Publisher<A extends unknown[] = [], R = void>
35
35
  .map((subscriber) => subscriber(...args));
36
36
  }
37
37
 
38
- public get [Symbol.toStringTag]() { return "Publisher"; }
38
+ public readonly [Symbol.toStringTag]: string = "Publisher";
39
39
  }
@@ -6,13 +6,17 @@ import Publisher from "../publisher.js";
6
6
 
7
7
  export default class Clock extends GameLoop
8
8
  {
9
- protected _publisher: Publisher<[number]>;
9
+ protected _starter: Publisher;
10
+ protected _stopper: Publisher;
11
+ protected _ticker: Publisher<[number]>;
10
12
 
11
- public constructor(fpsIfNotBrowser: number = TimeUnit.Second)
13
+ public constructor(msIfNotBrowser: number = TimeUnit.Second)
12
14
  {
13
- super((elapsedTime) => this._publisher.publish(elapsedTime), fpsIfNotBrowser);
15
+ super((elapsedTime) => this._ticker.publish(elapsedTime), msIfNotBrowser);
14
16
 
15
- this._publisher = new Publisher();
17
+ this._starter = new Publisher();
18
+ this._stopper = new Publisher();
19
+ this._ticker = new Publisher();
16
20
  }
17
21
 
18
22
  public start(elapsedTime = 0): void
@@ -20,6 +24,8 @@ export default class Clock extends GameLoop
20
24
  if (this._isRunning) { throw new RuntimeException("The clock has already been started."); }
21
25
 
22
26
  super.start(elapsedTime);
27
+
28
+ this._starter.publish();
23
29
  }
24
30
 
25
31
  public stop(): void
@@ -27,16 +33,27 @@ export default class Clock extends GameLoop
27
33
  if (!(this._isRunning)) { throw new RuntimeException("The clock hadn't yet started."); }
28
34
 
29
35
  super.stop();
36
+
37
+ this._stopper.publish();
38
+ }
39
+
40
+ public onStart(callback: () => void): () => void
41
+ {
42
+ return this._starter.subscribe(callback);
43
+ }
44
+ public onStop(callback: () => void): () => void
45
+ {
46
+ return this._stopper.subscribe(callback);
30
47
  }
31
48
 
32
49
  public onTick(callback: (elapsedTime: number) => void, tickStep = 0): () => void
33
50
  {
34
51
  if (tickStep < 0) { throw new RangeException("The tick step must be a non-negative number."); }
35
- if (tickStep === 0) { return this._publisher.subscribe(callback); }
52
+ if (tickStep === 0) { return this._ticker.subscribe(callback); }
36
53
 
37
54
  let lastTick = 0;
38
55
 
39
- return this._publisher.subscribe((elapsedTime: number) =>
56
+ return this._ticker.subscribe((elapsedTime: number) =>
40
57
  {
41
58
  if ((elapsedTime - lastTick) < tickStep) { return; }
42
59
 
@@ -44,4 +61,6 @@ export default class Clock extends GameLoop
44
61
  lastTick = elapsedTime;
45
62
  });
46
63
  }
64
+
65
+ public readonly [Symbol.toStringTag]: string = "Clock";
47
66
  }
@@ -9,7 +9,11 @@ import Publisher from "../publisher.js";
9
9
  export default class Countdown extends GameLoop
10
10
  {
11
11
  protected _deferrer?: DeferredPromise<void>;
12
- protected _publisher: Publisher<[number]>;
12
+
13
+ protected _expirer: Publisher;
14
+ protected _starter: Publisher;
15
+ protected _stopper: Publisher<[unknown]>;
16
+ protected _ticker: Publisher<[number]>;
13
17
 
14
18
  protected _duration: number;
15
19
  public get duration(): number
@@ -22,22 +26,44 @@ export default class Countdown extends GameLoop
22
26
  return this._duration - this.elapsedTime;
23
27
  }
24
28
 
25
- public constructor(duration: number, fpsIfNotBrowser: number = TimeUnit.Second)
29
+ public constructor(duration: number, msIfNotBrowser: number = TimeUnit.Second)
26
30
  {
27
31
  const callback = () =>
28
32
  {
29
33
  const remainingTime = this.remainingTime;
30
- this._publisher.publish(remainingTime);
34
+ this._ticker.publish(remainingTime);
35
+
36
+ if (remainingTime <= 0)
37
+ {
38
+ this._deferrerStop();
31
39
 
32
- if (remainingTime <= 0) { this.stop(); }
40
+ this._expirer.publish();
41
+ }
33
42
  };
34
43
 
35
- super(callback, fpsIfNotBrowser);
44
+ super(callback, msIfNotBrowser);
45
+
46
+ this._expirer = new Publisher();
47
+ this._starter = new Publisher();
48
+ this._stopper = new Publisher();
49
+ this._ticker = new Publisher();
36
50
 
37
- this._publisher = new Publisher();
38
51
  this._duration = duration;
39
52
  }
40
53
 
54
+ protected _deferrerStop(reason?: unknown): void
55
+ {
56
+ if (!(this._isRunning)) { throw new RuntimeException("The countdown hadn't yet started."); }
57
+ if (!(this._deferrer)) { throw new FatalErrorException(); }
58
+
59
+ super.stop();
60
+
61
+ if (reason !== undefined) { this._deferrer.reject(reason); }
62
+ else { this._deferrer.resolve(); }
63
+
64
+ this._deferrer = undefined;
65
+ }
66
+
41
67
  public start(remainingTime: number = this.duration): SmartPromise<void>
42
68
  {
43
69
  if (this._isRunning) { throw new RuntimeException("The countdown has already been started."); }
@@ -46,29 +72,39 @@ export default class Countdown extends GameLoop
46
72
  this._deferrer = new DeferredPromise();
47
73
  super.start(this.duration - remainingTime);
48
74
 
75
+ this._starter.publish();
76
+
49
77
  return this._deferrer;
50
78
  }
51
79
  public stop(reason?: unknown): void
52
80
  {
53
- if (!(this._isRunning)) { throw new RuntimeException("The countdown hadn't yet started."); }
54
- if (!(this._deferrer)) { throw new FatalErrorException(); }
81
+ this._deferrerStop(reason);
55
82
 
56
- super.stop();
83
+ this._stopper.publish(reason);
84
+ }
57
85
 
58
- if (reason !== undefined) { this._deferrer.reject(reason); }
59
- else { this._deferrer.resolve(); }
86
+ public onExpire(callback: () => void): () => void
87
+ {
88
+ return this._expirer.subscribe(callback);
89
+ }
60
90
 
61
- this._deferrer = undefined;
91
+ public onStart(callback: () => void): () => void
92
+ {
93
+ return this._starter.subscribe(callback);
94
+ }
95
+ public onStop(callback: (reason?: unknown) => void): () => void
96
+ {
97
+ return this._stopper.subscribe(callback);
62
98
  }
63
99
 
64
100
  public onTick(callback: (remainingTime: number) => void, tickStep = 0): () => void
65
101
  {
66
102
  if (tickStep < 0) { throw new RangeException("The tick step must be a non-negative number."); }
67
- if (tickStep === 0) { return this._publisher.subscribe(callback); }
103
+ if (tickStep === 0) { return this._ticker.subscribe(callback); }
68
104
 
69
105
  let lastTick = 0;
70
106
 
71
- return this._publisher.subscribe((remainingTime: number) =>
107
+ return this._ticker.subscribe((remainingTime: number) =>
72
108
  {
73
109
  if ((lastTick - remainingTime) < tickStep) { return; }
74
110
 
@@ -76,4 +112,6 @@ export default class Countdown extends GameLoop
76
112
  lastTick = remainingTime;
77
113
  });
78
114
  }
115
+
116
+ public readonly [Symbol.toStringTag]: string = "Countdown";
79
117
  }
package/src/utils/date.ts CHANGED
@@ -1,7 +1,10 @@
1
+
1
2
  import { SmartIterator } from "../models/index.js";
2
3
 
3
4
  export enum TimeUnit
4
5
  {
6
+ /* eslint-disable @typescript-eslint/prefer-literal-enum-member */
7
+
5
8
  Millisecond = 1,
6
9
  Second = 1000,
7
10
  Minute = 60 * Second,
@@ -2,7 +2,7 @@ import { ValueException } from "../models/index.js";
2
2
 
3
3
  export default class Random
4
4
  {
5
- public static Boolean(ratio: number = 0.5): boolean
5
+ public static Boolean(ratio = 0.5): boolean
6
6
  {
7
7
  return (Math.random() < ratio);
8
8
  }
@@ -38,6 +38,7 @@ export default class Random
38
38
  return elements[Random.Index(elements)];
39
39
  }
40
40
 
41
- // eslint-disable-next-line no-useless-constructor
42
- private constructor() { }
41
+ private constructor() { /* ... */ }
42
+
43
+ public readonly [Symbol.toStringTag]: string = "Random";
43
44
  }