Skip to content

packages/core/src/features/particles/lib/system/hook.ts

Read as Markdown

This is the source snapshot used to build these API details. View this revision on GitHub.

Back to reference

1 import {
2   pibblInternalCurrentRenderOwner,
3   pibblInternalOnRenderFinish,
4   useInternalHookSlot,
5   type PibblInternalRenderOwner,
6 } from "@pibbl/core/internal";
7 import type {
8   PibblParticleEffect2D,
9   PibblParticleParameterValues,
10   PibblParticleSystem,
11   PibblParticleSystemOptions,
12 } from "../types.js";
13 import {
14   resolveSignalFields,
15   type SignalFields,
16 } from "../signal-inputs.js";
17 import { resolveSignalValue, type SignalValue } from "@pibbl/core";
18 import {
19   createParticleSystemController,
20   type ParticleSystemController,
21 } from "./controller.js";
22 
23 interface ParticleSystemHookSlot {
24   readonly controller: ParticleSystemController;
25   readonly owner: PibblInternalRenderOwner;
26   mountSettled: boolean;
27   revision: number;
28 }
29 
30 /**
31  * Creates a mount-owned system retaining the effect's emitter and parameter types. See
32  * {@link PibblParticleEffect2D}, {@link PibblParticleSystemOptions}, and {@link PibblParticleSystem}.
33  * @param effect - Effect definition, optionally supplied by a signal. See {@link SignalValue} ,
34  * {@link PibblParticleEffect2D} .
35  * @param options - Playback and simulation options, optionally supplied by a signal. See
36  * {@link SignalValue} , {@link SignalFields} , {@link PibblParticleSystemOptions} .
37  * @returns Stable mount-owned controls for the particle simulation. See {@link PibblParticleSystem}.
38  */
39 export function useParticleSystem<
40   EmitterName extends string,
41   Parameters extends PibblParticleParameterValues,
42 >(
43   effect: SignalValue<PibblParticleEffect2D<EmitterName, Parameters>>,
44   options?: SignalValue<SignalFields<PibblParticleSystemOptions>>,
45 ): PibblParticleSystem<EmitterName, Parameters>;
46 /**
47  * Creates one stable particle-system handle owned by the current hook slot.
48  *
49  * @param effectInput - Effect definition, optionally supplied by a signal. See {@link SignalValue}
50  * , {@link PibblParticleEffect2D} .
51  * @param optionsInput - Playback and simulation options, optionally supplied by a signal. See
52  * {@link SignalValue} , {@link SignalFields} , {@link PibblParticleSystemOptions} .
53  * @returns Stable mount-owned controls for the particle simulation. See {@link PibblParticleSystem}.
54  *
55  * @see {@link SignalValue}
56  * @see {@link PibblParticleEffect2D}
57  * @see {@link PibblParticleSystemOptions}
58  * @see {@link PibblParticleSystem}
59  */
60 export function useParticleSystem(
61   effectInput: SignalValue<PibblParticleEffect2D>,
62   optionsInput: SignalValue<SignalFields<PibblParticleSystemOptions>> = {},
63 ): PibblParticleSystem {
64   const owner = pibblInternalCurrentRenderOwner();
65   const effect = resolveSignalValue(effectInput);
66   const options = resolveSignalFields(optionsInput);
67   const slot = useInternalHookSlot<ParticleSystemHookSlot>(
68     "particle-system",
69     (teardowns) => {
70       const controller = createParticleSystemController(owner, effect, options);
71       const value: ParticleSystemHookSlot = {
72         controller,
73         owner,
74         mountSettled: false,
75         revision: 0,
76       };
77       teardowns.add(() => controller.dispose());
78       return value;
79     },
80   ).value;
81   if (slot.owner !== owner) {
82     throw new Error("A Pibbl particle system hook changed render ownership.");
83   }
84   const candidate = slot.controller.prepareEffect(effect, options);
85   const revision = ++slot.revision;
86   pibblInternalOnRenderFinish(owner, (success) => {
87     if (!success || revision !== slot.revision) {
88       slot.controller.cancelEffect(candidate);
89       return;
90     }
91     slot.controller.adoptEffect(candidate);
92     if (!slot.mountSettled) {
93       slot.mountSettled = true;
94       if (options.autoplay === true) slot.controller.handle.play();
95     }
96   });
97   return slot.controller.handle;
98 }
99 

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.