@ikijs/engine 0.1.0 → 0.1.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/README.md CHANGED
@@ -30,8 +30,11 @@ player.setParameter(StandardParameter.MouthOpen, 0.7);
30
30
  ```
31
31
 
32
32
  `load()` decodes and uploads every texture before swapping the model in, so a
33
- frame is never half-textured. Parameter writes are clamped to the declared
34
- range; unknown ids and non-finite values are ignored.
33
+ frame is never half-textured. That swap is also why it must be awaited before
34
+ `getParameters()`: an un-awaited `load()` leaves the parameter store empty for
35
+ the rest of the tick, and the engine reports that case rather than let a host
36
+ read `[]` and conclude the model declares no parameters. Parameter writes are
37
+ clamped to the declared range; unknown ids and non-finite values are ignored.
35
38
 
36
39
  ## API
37
40
 
package/dist/index.d.mts CHANGED
@@ -50,6 +50,10 @@ declare class IkiPlayer {
50
50
  private textures;
51
51
  /** Bumped by every `load` and by `destroy`; lets a stale async load bail. */
52
52
  private loadGeneration;
53
+ /** True from the moment `load()` is entered until it resolves or throws. */
54
+ private loadPending;
55
+ /** Latches the un-awaited-load report, so a repeat caller says it once. */
56
+ private warnedLoadUnfinished;
53
57
  private destroyed;
54
58
  /**
55
59
  * Engine-internal mesh buffers, keyed by the part's INDEX in `this.parts`
@@ -78,8 +82,14 @@ declare class IkiPlayer {
78
82
  * Mesh buffer allocation failure IS fatal (unlike per-texture skip) because
79
83
  * textures have an `IkiLoadResult.failedTextures` reporting surface and mesh
80
84
  * buffers have none — there is no partial-mesh concept in the format.
85
+ *
86
+ * AWAIT THIS before reading {@link getParameters}. The swap happens after
87
+ * texture decoding, so an un-awaited `load()` leaves the parameter store
88
+ * empty for the rest of the tick; `getParameters` reports that case rather
89
+ * than letting a host conclude the model drives nothing.
81
90
  */
82
91
  load(model: IkiModel): Promise<IkiLoadResult>;
92
+ private adoptModel;
83
93
  /**
84
94
  * Start the render loop. Safe to call more than once, and a no-op after
85
95
  * {@link destroy} — the program and buffers the loop draws with are gone, so
@@ -101,7 +111,17 @@ declare class IkiPlayer {
101
111
  * mirror's clamping in step with {@link ParameterStore} by hand.
102
112
  */
103
113
  getParameter(id: string): number;
104
- /** The model's parameter descriptors, for building UI or host wiring. */
114
+ /**
115
+ * The model's parameter descriptors, for building UI or host wiring.
116
+ *
117
+ * Empty until the first {@link load} resolves. Reaching it through an
118
+ * un-awaited `load()` is the one mistake in this class that produces no
119
+ * error and no motion: the caller gets `[]`, concludes the model has no
120
+ * parameters, and drives nothing — so that case is reported instead of
121
+ * being indistinguishable from a model that really declares none. A
122
+ * reload is deliberately NOT reported: those parameters are stale rather
123
+ * than absent, and warning there would fire on legitimate concurrent reads.
124
+ */
105
125
  getParameters(): IkiParameter[];
106
126
  destroy(): void;
107
127
  private renderFrame;
package/dist/index.d.ts CHANGED
@@ -50,6 +50,10 @@ declare class IkiPlayer {
50
50
  private textures;
51
51
  /** Bumped by every `load` and by `destroy`; lets a stale async load bail. */
52
52
  private loadGeneration;
53
+ /** True from the moment `load()` is entered until it resolves or throws. */
54
+ private loadPending;
55
+ /** Latches the un-awaited-load report, so a repeat caller says it once. */
56
+ private warnedLoadUnfinished;
53
57
  private destroyed;
54
58
  /**
55
59
  * Engine-internal mesh buffers, keyed by the part's INDEX in `this.parts`
@@ -78,8 +82,14 @@ declare class IkiPlayer {
78
82
  * Mesh buffer allocation failure IS fatal (unlike per-texture skip) because
79
83
  * textures have an `IkiLoadResult.failedTextures` reporting surface and mesh
80
84
  * buffers have none — there is no partial-mesh concept in the format.
85
+ *
86
+ * AWAIT THIS before reading {@link getParameters}. The swap happens after
87
+ * texture decoding, so an un-awaited `load()` leaves the parameter store
88
+ * empty for the rest of the tick; `getParameters` reports that case rather
89
+ * than letting a host conclude the model drives nothing.
81
90
  */
82
91
  load(model: IkiModel): Promise<IkiLoadResult>;
92
+ private adoptModel;
83
93
  /**
84
94
  * Start the render loop. Safe to call more than once, and a no-op after
85
95
  * {@link destroy} — the program and buffers the loop draws with are gone, so
@@ -101,7 +111,17 @@ declare class IkiPlayer {
101
111
  * mirror's clamping in step with {@link ParameterStore} by hand.
102
112
  */
103
113
  getParameter(id: string): number;
104
- /** The model's parameter descriptors, for building UI or host wiring. */
114
+ /**
115
+ * The model's parameter descriptors, for building UI or host wiring.
116
+ *
117
+ * Empty until the first {@link load} resolves. Reaching it through an
118
+ * un-awaited `load()` is the one mistake in this class that produces no
119
+ * error and no motion: the caller gets `[]`, concludes the model has no
120
+ * parameters, and drives nothing — so that case is reported instead of
121
+ * being indistinguishable from a model that really declares none. A
122
+ * reload is deliberately NOT reported: those parameters are stale rather
123
+ * than absent, and warning there would fire on legitimate concurrent reads.
124
+ */
105
125
  getParameters(): IkiParameter[];
106
126
  destroy(): void;
107
127
  private renderFrame;
package/dist/index.js CHANGED
@@ -452,6 +452,10 @@ var IkiPlayer = class {
452
452
  textures = [];
453
453
  /** Bumped by every `load` and by `destroy`; lets a stale async load bail. */
454
454
  loadGeneration = 0;
455
+ /** True from the moment `load()` is entered until it resolves or throws. */
456
+ loadPending = false;
457
+ /** Latches the un-awaited-load report, so a repeat caller says it once. */
458
+ warnedLoadUnfinished = false;
455
459
  destroyed = false;
456
460
  /**
457
461
  * Engine-internal mesh buffers, keyed by the part's INDEX in `this.parts`
@@ -479,8 +483,21 @@ var IkiPlayer = class {
479
483
  * Mesh buffer allocation failure IS fatal (unlike per-texture skip) because
480
484
  * textures have an `IkiLoadResult.failedTextures` reporting surface and mesh
481
485
  * buffers have none — there is no partial-mesh concept in the format.
486
+ *
487
+ * AWAIT THIS before reading {@link getParameters}. The swap happens after
488
+ * texture decoding, so an un-awaited `load()` leaves the parameter store
489
+ * empty for the rest of the tick; `getParameters` reports that case rather
490
+ * than letting a host conclude the model drives nothing.
482
491
  */
483
492
  async load(model) {
493
+ this.loadPending = true;
494
+ try {
495
+ return await this.adoptModel(model);
496
+ } finally {
497
+ this.loadPending = false;
498
+ }
499
+ }
500
+ async adoptModel(model) {
484
501
  const { gl } = this;
485
502
  const generation = ++this.loadGeneration;
486
503
  const sources = model.textures ?? [];
@@ -692,8 +709,24 @@ var IkiPlayer = class {
692
709
  getParameter(id) {
693
710
  return this.params.get(id);
694
711
  }
695
- /** The model's parameter descriptors, for building UI or host wiring. */
712
+ /**
713
+ * The model's parameter descriptors, for building UI or host wiring.
714
+ *
715
+ * Empty until the first {@link load} resolves. Reaching it through an
716
+ * un-awaited `load()` is the one mistake in this class that produces no
717
+ * error and no motion: the caller gets `[]`, concludes the model has no
718
+ * parameters, and drives nothing — so that case is reported instead of
719
+ * being indistinguishable from a model that really declares none. A
720
+ * reload is deliberately NOT reported: those parameters are stale rather
721
+ * than absent, and warning there would fire on legitimate concurrent reads.
722
+ */
696
723
  getParameters() {
724
+ if (this.loadPending && this.model === void 0 && !this.warnedLoadUnfinished) {
725
+ this.warnedLoadUnfinished = true;
726
+ console.error(
727
+ "Iki: getParameters() ran before load() finished, so it returned an empty list \u2014 await load() before reading parameters."
728
+ );
729
+ }
697
730
  return this.params.list();
698
731
  }
699
732
  destroy() {