@thi.ng/timestep 0.2.0 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-04-28T17:22:36Z
3
+ - **Last updated**: 2023-05-05T21:29:28Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
@@ -9,6 +9,16 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
9
9
  **Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
10
10
  and/or version bumps of transitive dependencies.
11
11
 
12
+ ## [0.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/timestep@0.3.0) (2023-05-05)
13
+
14
+ #### 🚀 Features
15
+
16
+ - add AState.reset() & impls ([a2c4946](https://github.com/thi-ng/umbrella/commit/a2c4946))
17
+
18
+ #### ♻️ Refactoring
19
+
20
+ - rename IUpdatable => ITimeStep ([2cc3951](https://github.com/thi-ng/umbrella/commit/2cc3951))
21
+
12
22
  ## [0.2.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/timestep@0.2.0) (2023-04-28)
13
23
 
14
24
  #### 🚀 Features
package/README.md CHANGED
@@ -31,8 +31,8 @@ upon which this implementation is principally based on.
31
31
  The package provides a configurable [`TimeStep`
32
32
  class](https://docs.thi.ng/umbrella/timestep/classes/TimeStep.html) to manage
33
33
  the update logic. To participate in these managed updates, the user must provide
34
- state values/wrappers implementing the [`IUpdatable`
35
- interface](https://docs.thi.ng/umbrella/timestep/interfaces/IUpdatable.html) for
34
+ state values/wrappers implementing the [`ITimeStep`
35
+ interface](https://docs.thi.ng/umbrella/timestep/interfaces/ITimeStep.html) for
36
36
  the two main phases of the frame update:
37
37
 
38
38
  - `integrate(dt: number, ctx: ReadonlyTimeStep): void`: Depending on actual
@@ -75,7 +75,7 @@ const b = defVector([0, 0], (x, dt) => [x[0] - 10 * dt, x[1] + 20 * dt]);
75
75
  // the simulated render frame rate here is only 25 fps...
76
76
  setInterval(() => {
77
77
  // provide current time and an array of state values to update
78
- // (any IUpdatable impl can be given here, incl. custom types)
78
+ // (any ITimeStep impl can be given here, incl. custom types)
79
79
  sim.update(Date.now(), [a, b]);
80
80
  // show current frame, num updates, time (relative to start) and interpolated state values
81
81
  console.log(sim.frame, sim.updates, sim.current, a.value, b.value);
@@ -148,7 +148,7 @@ For Node.js REPL:
148
148
  const timestep = await import("@thi.ng/timestep");
149
149
  ```
150
150
 
151
- Package sizes (brotli'd, pre-treeshake): ESM: 518 bytes
151
+ Package sizes (brotli'd, pre-treeshake): ESM: 758 bytes
152
152
 
153
153
  ## Dependencies
154
154
 
package/api.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Interface for participating in the {@link TimeStep.update} logic.
3
3
  */
4
- export interface IUpdatable {
4
+ export interface ITimeStep {
5
5
  /**
6
6
  * 1st phase of the update cycle and main update function for this
7
7
  * simulation state. Receives timestep (in seconds) and a `ctx` object.
@@ -94,7 +94,7 @@ export type StateUpdate<T> = (curr: T, dt: number, ctx: ReadonlyTimeStep) => T;
94
94
  export type StateInterpolation<T> = (prev: T, curr: T, alpha: number, ctx: ReadonlyTimeStep) => T;
95
95
  /**
96
96
  * Event ID for {@link TimeStep.addListener} to be notified of individual
97
- * {@link IUpdatable.integrate} iterations.
97
+ * {@link ITimeStep.integrate} iterations.
98
98
  */
99
99
  export declare const EVENT_INTEGRATE = "integrate";
100
100
  /**
package/api.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Event ID for {@link TimeStep.addListener} to be notified of individual
3
- * {@link IUpdatable.integrate} iterations.
3
+ * {@link ITimeStep.integrate} iterations.
4
4
  */
5
5
  export const EVENT_INTEGRATE = "integrate";
6
6
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/timestep",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Deterministic fixed timestep simulation updates with state interpolation",
5
5
  "type": "module",
6
6
  "module": "./index.js",
@@ -88,5 +88,5 @@
88
88
  "status": "alpha",
89
89
  "year": 2023
90
90
  },
91
- "gitHead": "e71e2d061ac0a754ce4899bb59208afb8b3d94b2\n"
91
+ "gitHead": "81dcbba93e7230c2f400bee87878145d902e975b\n"
92
92
  }
package/state.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import type { IDeref } from "@thi.ng/api";
2
2
  import type { ReadonlyVec } from "@thi.ng/vectors";
3
- import type { IUpdatable, ReadonlyTimeStep, StateInterpolation, StateUpdate } from "./api.js";
3
+ import type { ITimeStep, ReadonlyTimeStep, StateInterpolation, StateUpdate } from "./api.js";
4
4
  /**
5
5
  * Abstract base class for simulation state wrappers.
6
6
  *
7
7
  * @remarks
8
8
  * See {@link defNumeric} and {@link defVector}.
9
9
  */
10
- export declare abstract class AState<T> implements IDeref<T>, IUpdatable {
10
+ export declare abstract class AState<T> implements IDeref<T>, ITimeStep {
11
11
  value: T;
12
12
  update: StateUpdate<T>;
13
13
  mix: StateInterpolation<T>;
@@ -17,12 +17,15 @@ export declare abstract class AState<T> implements IDeref<T>, IUpdatable {
17
17
  deref(): T;
18
18
  integrate(dt: number, ctx: ReadonlyTimeStep): void;
19
19
  interpolate(alpha: number, ctx: ReadonlyTimeStep): void;
20
+ abstract reset(value: T): void;
20
21
  }
21
22
  export declare class NumericState extends AState<number> {
22
23
  constructor(x: number, update: StateUpdate<number>);
24
+ reset(value: number): void;
23
25
  }
24
26
  export declare class VectorState extends AState<ReadonlyVec> {
25
27
  constructor(x: ReadonlyVec, update: StateUpdate<ReadonlyVec>);
28
+ reset(value: ReadonlyVec): void;
26
29
  }
27
30
  /**
28
31
  * Returns a new {@link NumericState} wrapper for given value `x` and its update
@@ -36,6 +39,10 @@ export declare const defNumeric: (x: number, update: StateUpdate<number>) => Num
36
39
  * Returns a new {@link VectorState} wrapper for given vector `v` and its update
37
40
  * function for use with {@link TimeStep.update}.
38
41
  *
42
+ * @remarks
43
+ * **IMPORTANT:** The `update` function MUST return a new vector and not mutate
44
+ * the existing one!
45
+ *
39
46
  * @param x
40
47
  * @param update
41
48
  */
package/state.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { mix } from "@thi.ng/math/mix";
2
2
  import { mixN } from "@thi.ng/vectors/mixn";
3
+ import { set } from "@thi.ng/vectors/set";
3
4
  /**
4
5
  * Abstract base class for simulation state wrappers.
5
6
  *
@@ -28,11 +29,19 @@ export class NumericState extends AState {
28
29
  constructor(x, update) {
29
30
  super(x, update, mix);
30
31
  }
32
+ reset(value) {
33
+ this.prev = this.curr = this.value = value;
34
+ }
31
35
  }
32
36
  export class VectorState extends AState {
33
37
  constructor(x, update) {
34
38
  super(x, update, (a, b, t) => mixN([], a, b, t));
35
39
  }
40
+ reset(value) {
41
+ set(this.prev, value);
42
+ set(this.curr, value);
43
+ set(this.value, value);
44
+ }
36
45
  }
37
46
  /**
38
47
  * Returns a new {@link NumericState} wrapper for given value `x` and its update
@@ -46,6 +55,10 @@ export const defNumeric = (x, update) => new NumericState(x, update);
46
55
  * Returns a new {@link VectorState} wrapper for given vector `v` and its update
47
56
  * function for use with {@link TimeStep.update}.
48
57
  *
58
+ * @remarks
59
+ * **IMPORTANT:** The `update` function MUST return a new vector and not mutate
60
+ * the existing one!
61
+ *
49
62
  * @param x
50
63
  * @param update
51
64
  */
package/timestep.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type Event, type INotify, type Listener } from "@thi.ng/api";
2
- import { type IUpdatable, type ReadonlyTimeStep, type TimeStepOpts } from "./api.js";
2
+ import { type ITimeStep, type ReadonlyTimeStep, type TimeStepOpts } from "./api.js";
3
3
  export declare class TimeStep implements INotify {
4
4
  start: number;
5
5
  dt: number;
@@ -17,37 +17,40 @@ export declare class TimeStep implements INotify {
17
17
  removeListener(id: string, fn: Listener, scope?: any): boolean;
18
18
  notify(event: Event): boolean;
19
19
  /**
20
- * Updates internal time to given new time `now` (in seconds) and performs
21
- * the required number of fixed timesteps to integrate and interpolate the
22
- * given `state` values.
20
+ * Updates internal time to given new time `now` (given value will be scaled
21
+ * via {@link TimeStepOpts.scale}) and performs the required number of fixed
22
+ * timesteps to integrate and interpolate the given `state` values.
23
23
  *
24
24
  * @remarks
25
- * If `interpolate` is false, the {@link IUpdatable.interpolate} phase of
26
- * the update cycle is skipped. This is useful when using this setup to
27
- * simulate sub-steps (e.g. in XPBD) and only requiring the interpolation
28
- * stage for the last step.
25
+ * If the scaled time difference since the last step is greater than
26
+ * {@link TimeStepOpts.maxFrameTime}, it will be limited to the latter.
27
+ *
28
+ * If `interpolate` is false, the {@link ITimeStep.interpolate} phase of the
29
+ * update cycle is skipped. This is useful when using this setup to simulate
30
+ * sub-steps (e.g. in XPBD) and only requiring the interpolation stage for
31
+ * the last step.
29
32
  *
30
33
  * @param now
31
34
  * @param items
32
35
  * @param interpolate
33
36
  */
34
- update(now: number, items: IUpdatable[], interpolate?: boolean): void;
37
+ update(now: number, items: ITimeStep[], interpolate?: boolean): void;
35
38
  }
36
39
  export declare const defTimeStep: (opts?: Partial<TimeStepOpts>) => TimeStep;
37
40
  /**
38
- * Calls {@link IUpdatable.integrate} for all given items (in given order).
41
+ * Calls {@link ITimeStep.integrate} for all given items (in given order).
39
42
  *
40
43
  * @param dt
41
44
  * @param ctx
42
45
  * @param items
43
46
  */
44
- export declare const integrateAll: (dt: number, ctx: ReadonlyTimeStep, ...items: IUpdatable[]) => void;
47
+ export declare const integrateAll: (dt: number, ctx: ReadonlyTimeStep, ...items: ITimeStep[]) => void;
45
48
  /**
46
- * Calls {@link IUpdatable.interpolate} for all given items (in given order).
49
+ * Calls {@link ITimeStep.interpolate} for all given items (in given order).
47
50
  *
48
51
  * @param dt
49
52
  * @param ctx
50
53
  * @param items
51
54
  */
52
- export declare const interpolateAll: (alpha: number, ctx: ReadonlyTimeStep, ...items: IUpdatable[]) => void;
55
+ export declare const interpolateAll: (alpha: number, ctx: ReadonlyTimeStep, ...items: ITimeStep[]) => void;
53
56
  //# sourceMappingURL=timestep.d.ts.map
package/timestep.js CHANGED
@@ -32,15 +32,18 @@ let TimeStep = class TimeStep {
32
32
  // @ts-ignore mixin
33
33
  notify(event) { }
34
34
  /**
35
- * Updates internal time to given new time `now` (in seconds) and performs
36
- * the required number of fixed timesteps to integrate and interpolate the
37
- * given `state` values.
35
+ * Updates internal time to given new time `now` (given value will be scaled
36
+ * via {@link TimeStepOpts.scale}) and performs the required number of fixed
37
+ * timesteps to integrate and interpolate the given `state` values.
38
38
  *
39
39
  * @remarks
40
- * If `interpolate` is false, the {@link IUpdatable.interpolate} phase of
41
- * the update cycle is skipped. This is useful when using this setup to
42
- * simulate sub-steps (e.g. in XPBD) and only requiring the interpolation
43
- * stage for the last step.
40
+ * If the scaled time difference since the last step is greater than
41
+ * {@link TimeStepOpts.maxFrameTime}, it will be limited to the latter.
42
+ *
43
+ * If `interpolate` is false, the {@link ITimeStep.interpolate} phase of the
44
+ * update cycle is skipped. This is useful when using this setup to simulate
45
+ * sub-steps (e.g. in XPBD) and only requiring the interpolation stage for
46
+ * the last step.
44
47
  *
45
48
  * @param now
46
49
  * @param items
@@ -75,7 +78,7 @@ TimeStep = __decorate([
75
78
  export { TimeStep };
76
79
  export const defTimeStep = (opts) => new TimeStep(opts);
77
80
  /**
78
- * Calls {@link IUpdatable.integrate} for all given items (in given order).
81
+ * Calls {@link ITimeStep.integrate} for all given items (in given order).
79
82
  *
80
83
  * @param dt
81
84
  * @param ctx
@@ -86,7 +89,7 @@ export const integrateAll = (dt, ctx, ...items) => {
86
89
  items[i].integrate(dt, ctx);
87
90
  };
88
91
  /**
89
- * Calls {@link IUpdatable.interpolate} for all given items (in given order).
92
+ * Calls {@link ITimeStep.interpolate} for all given items (in given order).
90
93
  *
91
94
  * @param dt
92
95
  * @param ctx