packages/core/src/features/particles/lib/system/hook.ts
This is the source snapshot used to build these API details. View this revision on GitHub.
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 version
Section titled “Documentation version”Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.