Skip to content

Commit 91f027a

Browse files
committed
chore: remove useProps to hooks and export createEntity
1 parent b2fbb1c commit 91f027a

6 files changed

Lines changed: 108 additions & 104 deletions

File tree

playground/controls/OrbitControls.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { createEffect, createMemo, onCleanup, type Ref } from "solid-js"
22
import type { Event } from "three"
33
import { OrbitControls as ThreeOrbitControls } from "three-stdlib"
4+
import { useProps } from "../../src/hooks.ts"
45
import { useFrame, useThree, type S3 } from "../../src/index.ts"
5-
import { useProps } from "../../src/props.ts"
66
import { whenEffect } from "../../src/utils/conditionals.ts"
77
import { processProps } from "./process-props.ts"
88

src/components.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
splitProps,
88
} from "solid-js"
99
import { Object3D } from "three"
10-
import { threeContext, useThree } from "./hooks.ts"
11-
import { manageSceneGraph, useProps } from "./props.ts"
10+
import { threeContext, useProps, useThree } from "./hooks.ts"
11+
import { manageSceneGraph } from "./props.ts"
1212
import type { Constructor, Instance, Overwrite, Props } from "./types.ts"
1313
import { type InstanceFromConstructor } from "./types.ts"
1414
import { augment, autodispose, isConstructor, isInstance, withContext } from "./utils.ts"

src/create-t.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createMemo, type JSX, mergeProps } from "solid-js"
2-
import { useProps } from "./props.ts"
2+
import { useProps } from "./hooks.ts"
33
import type { Component } from "./types.ts"
44
import { augment } from "./utils.ts"
55

@@ -24,7 +24,7 @@ export function createT<TCatalogue extends Record<string, unknown>>(catalogue: T
2424
if (!constructor) return undefined
2525

2626
/* Otherwise, create and memoize a component for that constructor. */
27-
cache.set(name, createTComponent(constructor))
27+
cache.set(name, createEntity(constructor))
2828
}
2929

3030
return cache.get(name)
@@ -33,18 +33,18 @@ export function createT<TCatalogue extends Record<string, unknown>>(catalogue: T
3333
}
3434

3535
/**
36-
* Creates a ThreeComponent instance for a given source constructor.
36+
* Creates an Entity-instance from a given source constructor.
3737
*
38-
* @template TSource The source constructor type.
39-
* @param source - The constructor from which the component will be created.
38+
* @template TConstructor The source constructor type.
39+
* @param Constructor - The constructor from which the component will be created.
4040
* @returns The created component.
4141
*/
42-
export function createTComponent<TSource>(source: TSource): Component<TSource> {
42+
export function createEntity<TConstructor>(Constructor: TConstructor): Component<TConstructor> {
4343
return (props: any) => {
4444
const merged = mergeProps({ args: [] }, props)
4545
const memo = createMemo(() => {
4646
try {
47-
return augment(new (source as any)(...merged.args), { props })
47+
return augment(new (Constructor as any)(...merged.args), { props })
4848
} catch (e) {
4949
console.error(e)
5050
throw new Error("")

src/hooks.ts

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,18 @@
1-
import { type Accessor, type Resource, createContext, createResource, useContext } from "solid-js"
1+
import {
2+
type Accessor,
3+
type Resource,
4+
children,
5+
createContext,
6+
createRenderEffect,
7+
createResource,
8+
onCleanup,
9+
splitProps,
10+
untrack,
11+
useContext,
12+
} from "solid-js"
13+
import { applyProps } from "./props.ts"
214
import type { Context } from "./types"
3-
4-
/**********************************************************************************/
5-
/* */
6-
/* Use Three */
7-
/* */
8-
/**********************************************************************************/
9-
10-
export const threeContext = createContext<Context>(null!)
11-
12-
/**
13-
* Custom hook to access all necessary Three.js objects needed to manage a 3D scene.
14-
* This hook must be used within a component that is a descendant of the `<Canvas/>` component.
15-
*
16-
* @template T The expected return type after applying the callback to the context.
17-
* @param [callback] - Optional callback function that processes and returns a part of the context.
18-
* @returns Returns `Context` directly, or as a selector if a callback is provided.
19-
* @throws Throws an error if used outside of the Canvas component context.
20-
*/
21-
export function useThree(): Context
22-
export function useThree<T>(callback: (value: Context) => T): Accessor<T>
23-
export function useThree(callback?: (value: Context) => any) {
24-
const store = useContext(threeContext)
25-
if (!store) {
26-
throw new Error("S3: Hooks can only be used within the Canvas component!")
27-
}
28-
if (callback) return () => callback(store)
29-
return store
30-
}
15+
import { check } from "./utils/conditionals.ts"
3116

3217
/**********************************************************************************/
3318
/* */
@@ -130,3 +115,82 @@ export function useLoader<
130115
? Resource<LoaderResult<TLoader>>
131116
: */ Resource<{ [K in keyof TArgs]: LoaderResult<TLoader> }>
132117
}
118+
119+
/**********************************************************************************/
120+
/* */
121+
/* Use Props */
122+
/* */
123+
/**********************************************************************************/
124+
125+
/**
126+
* Manages and applies `solid-three` props to its Three.js object. This function sets up reactive effects
127+
* to ensure that properties are correctly applied and updated in response to changes. It also manages the
128+
* attachment of children and the disposal of the object.
129+
*
130+
* @template T - The type of the augmented element.
131+
* @param object - An accessor function that returns the target object to which properties will be applied.
132+
* @param props - An object containing the props to apply. This includes both direct properties
133+
* and special properties like `ref` and `children`.
134+
*/
135+
export function useProps<T extends object>(object: Accessor<T>, props: any) {
136+
const [local, instanceProps] = splitProps(props, ["ref", "args", "object", "attach", "children"])
137+
138+
// Assign ref
139+
createRenderEffect(() => {
140+
if (local.ref instanceof Function) local.ref(object())
141+
else local.ref = object()
142+
})
143+
144+
createRenderEffect(() => {
145+
if ("children" in props) {
146+
// Connect or attach children to THREE-instance
147+
const childrenAccessor = children(() => props.children)
148+
// @ts-expect-error TODO: fix type-error
149+
manageSceneGraph(object(), childrenAccessor as unknown as Accessor<Instance>)
150+
}
151+
})
152+
153+
// Apply the props to THREE-instance
154+
createRenderEffect(() => {
155+
applyProps(object(), instanceProps)
156+
// NOTE: see "onUpdate should not update itself"-test
157+
untrack(() => props.onUpdate)?.(object())
158+
})
159+
160+
// Automatically dispose
161+
onCleanup(() =>
162+
check(object, object => {
163+
if ("dispose" in object && typeof object.dispose === "function") {
164+
object.dispose()
165+
}
166+
}),
167+
)
168+
}
169+
170+
/**********************************************************************************/
171+
/* */
172+
/* Use Three */
173+
/* */
174+
/**********************************************************************************/
175+
176+
export const threeContext = createContext<Context>(null!)
177+
178+
/**
179+
* Custom hook to access all necessary Three.js objects needed to manage a 3D scene.
180+
* This hook must be used within a component that is a descendant of the `<Canvas/>` component.
181+
*
182+
* @template T The expected return type after applying the callback to the context.
183+
* @param [callback] - Optional callback function that processes and returns a part of the context.
184+
* @returns Returns `Context` directly, or as a selector if a callback is provided.
185+
* @throws Throws an error if used outside of the Canvas component context.
186+
*/
187+
export function useThree(): Context
188+
export function useThree<T>(callback: (value: Context) => T): Accessor<T>
189+
export function useThree(callback?: (value: Context) => any) {
190+
const store = useContext(threeContext)
191+
if (!store) {
192+
throw new Error("S3: Hooks can only be used within the Canvas component!")
193+
}
194+
if (callback) return () => callback(store)
195+
return store
196+
}

src/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
export { Canvas, type CanvasProps } from "./canvas.tsx"
22
export { Entity, Portal } from "./components.tsx"
33
export { $S3C } from "./constants.ts"
4-
export { createT, createTComponent } from "./create-t.tsx"
5-
export { useFrame, useLoader, useThree } from "./hooks.ts"
6-
export { applyProps, useProps } from "./props.ts"
4+
export { createEntity, createT } from "./create-t.tsx"
5+
export { useFrame, useLoader, useProps, useThree } from "./hooks.ts"
6+
export { applyProps } from "./props.ts"
77
export * as S3 from "./types.ts"
8-
export { autodispose, buildGraph } from "./utils.ts"
8+
export { autodispose } from "./utils.ts"

src/props.ts

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,4 @@
1-
import {
2-
type Accessor,
3-
children,
4-
createRenderEffect,
5-
mapArray,
6-
onCleanup,
7-
splitProps,
8-
untrack,
9-
} from "solid-js"
1+
import { type Accessor, createRenderEffect, mapArray, onCleanup } from "solid-js"
102
import {
113
BufferGeometry,
124
Color,
@@ -24,58 +16,6 @@ import { useThree } from "./hooks.ts"
2416
import { addToEventListeners, useCanvasProps } from "./internal-context.ts"
2517
import type { Instance } from "./types.ts"
2618
import { hasColorSpace, isInstance, resolve } from "./utils.ts"
27-
import { check } from "./utils/conditionals.ts"
28-
29-
/**********************************************************************************/
30-
/* */
31-
/* Manage Props */
32-
/* */
33-
/**********************************************************************************/
34-
35-
/**
36-
* Manages and applies `solid-three` props to its Three.js object. This function sets up reactive effects
37-
* to ensure that properties are correctly applied and updated in response to changes. It also manages the
38-
* attachment of children and the disposal of the object.
39-
*
40-
* @template T - The type of the augmented element.
41-
* @param object - An accessor function that returns the target object to which properties will be applied.
42-
* @param props - An object containing the props to apply. This includes both direct properties
43-
* and special properties like `ref` and `children`.
44-
*/
45-
export function useProps<T extends object>(object: Accessor<T>, props: any) {
46-
const [local, instanceProps] = splitProps(props, ["ref", "args", "object", "attach", "children"])
47-
48-
// Assign ref
49-
createRenderEffect(() => {
50-
if (local.ref instanceof Function) local.ref(object())
51-
else local.ref = object()
52-
})
53-
54-
createRenderEffect(() => {
55-
if ("children" in props) {
56-
// Connect or attach children to THREE-instance
57-
const childrenAccessor = children(() => props.children)
58-
// @ts-expect-error TODO: fix type-error
59-
manageSceneGraph(object(), childrenAccessor as unknown as Accessor<Instance>)
60-
}
61-
})
62-
63-
// Apply the props to THREE-instance
64-
createRenderEffect(() => {
65-
applyProps(object(), instanceProps)
66-
// NOTE: see "onUpdate should not update itself"-test
67-
untrack(() => props.onUpdate)?.(object())
68-
})
69-
70-
// Automatically dispose
71-
onCleanup(() =>
72-
check(object, object => {
73-
if ("dispose" in object && typeof object.dispose === "function") {
74-
object.dispose()
75-
}
76-
}),
77-
)
78-
}
7919

8020
/**********************************************************************************/
8121
/* */

0 commit comments

Comments
 (0)