lunchboxjs 0.2.1001-beta.1 → 0.2.1001-beta.2

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.
@@ -38,7 +38,7 @@ export const update: Lunch.UpdateCallback = (opts) => {
38
38
  }
39
39
 
40
40
  // prep options
41
- const { app, renderer, scene, camera } = opts
41
+ const { app, renderer, scene } = opts
42
42
 
43
43
  // BEFORE RENDER
44
44
  app.config.globalProperties.lunchbox.beforeRender.forEach((cb) => {
@@ -46,14 +46,14 @@ export const update: Lunch.UpdateCallback = (opts) => {
46
46
  })
47
47
 
48
48
  // RENDER
49
- if (renderer && scene && camera) {
49
+ if (renderer && scene && opts.app.config.globalProperties.lunchbox.camera) {
50
50
  if (app.customRender) {
51
51
  app.customRender(opts)
52
52
  } else {
53
53
  renderer.render(
54
54
  toRaw(scene),
55
- // opts.app.config.globalProperties.lunchbox.camera!
56
- toRaw(camera)
55
+ opts.app.config.globalProperties.lunchbox.camera
56
+ // toRaw(camera)
57
57
  )
58
58
  }
59
59
  }
@@ -66,7 +66,7 @@ export const update: Lunch.UpdateCallback = (opts) => {
66
66
 
67
67
  // before render
68
68
  // ====================
69
- // TODO: document
69
+ /** Obtain callback methods for `onBeforeRender` and `offBeforeRender`. Usually used internally by Lunchbox. */
70
70
  export const useBeforeRender = () => {
71
71
  return {
72
72
  onBeforeRender: inject<typeof onBeforeRender>(Keys.onBeforeRenderKey),
@@ -76,19 +76,25 @@ export const useBeforeRender = () => {
76
76
  }
77
77
  }
78
78
 
79
- // TODO: document
79
+ /** Run a function before every render.
80
+ *
81
+ * Note that if `updateSource` is set in the Lunchbox wrapper component, this will **only** run
82
+ * before a render triggered by that `updateSource`. Normally, the function should run every frame.
83
+ */
80
84
  export const onBeforeRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
81
85
  useBeforeRender().onBeforeRender?.(cb, index)
82
86
  }
83
87
 
84
- // TODO: document
88
+ /** Remove a function from the `beforeRender` callback list. Useful for tearing down functions added
89
+ * by `onBeforeRender`.
90
+ */
85
91
  export const offBeforeRender = (cb: Lunch.UpdateCallback | number) => {
86
92
  useBeforeRender().offBeforeRender?.(cb)
87
93
  }
88
94
 
89
95
  // after render
90
96
  // ====================
91
- // TODO: document
97
+ /** Obtain callback methods for `onAfterRender` and `offAfterRender`. Usually used internally by Lunchbox. */
92
98
  export const useAfterRender = () => {
93
99
  return {
94
100
  onAfterRender: inject<typeof onAfterRender>(Keys.onBeforeRenderKey),
@@ -96,17 +102,25 @@ export const useAfterRender = () => {
96
102
  }
97
103
  }
98
104
 
99
- // TODO: document
105
+ /** Run a function after every render.
106
+ *
107
+ * Note that if `updateSource` is set in the Lunchbox wrapper component, this will **only** run
108
+ * after a render triggered by that `updateSource`. Normally, the function should run every frame.
109
+ */
100
110
  export const onAfterRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
101
111
  useBeforeRender().onBeforeRender?.(cb, index)
102
112
  }
103
113
 
104
- // TODO: document
114
+ /** Remove a function from the `afterRender` callback list. Useful for tearing down functions added
115
+ * by `onAfterRender`.
116
+ */
105
117
  export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
106
118
  useBeforeRender().offBeforeRender?.(cb)
107
119
  }
108
120
 
109
- // TODO: document
121
+ /** Obtain a function used to cancel the current update frame. Use `cancelUpdate` if you wish
122
+ * to immediately invoke the cancellation function. Usually used internally by Lunchbox.
123
+ */
110
124
  export const useCancelUpdate = () => {
111
125
  const frameId = inject<number>(Keys.frameIdKey)
112
126
  return () => {
@@ -114,12 +128,14 @@ export const useCancelUpdate = () => {
114
128
  }
115
129
  }
116
130
 
117
- // TODO: document
131
+ /** Cancel the current update frame. Usually used internally by Lunchbox. */
118
132
  export const cancelUpdate = () => {
119
133
  useCancelUpdate()?.()
120
134
  }
121
135
 
122
- // TODO: document
136
+ /** Obtain a function used to cancel an update source. Use `cancelUpdateSource` if you wish to
137
+ * immediately invoke the cancellation function. Usually used internally by Lunchbox.
138
+ */
123
139
  export const useCancelUpdateSource = () => {
124
140
  const cancel = inject<
125
141
  Lunch.App['config']['globalProperties']['watchStopHandle']
@@ -127,7 +143,7 @@ export const useCancelUpdateSource = () => {
127
143
  return () => cancel?.()
128
144
  }
129
145
 
130
- // TODO: document
146
+ /** Cancel an update source. Usually used internally by Lunchbox. */
131
147
  export const cancelUpdateSource = () => {
132
148
  useCancelUpdateSource()?.()
133
149
  }
@@ -58,6 +58,7 @@ export function updateObjectProp({
58
58
  }
59
59
 
60
60
  // change property
61
+ // first, save as array in case we need to spread it
61
62
  if (liveProperty && isNumber(value) && liveProperty.setScalar) {
62
63
  // if value is a number and the property has a `setScalar` method, use that
63
64
  liveProperty.setScalar(value)
@@ -66,8 +67,21 @@ export function updateObjectProp({
66
67
  const nextValueAsArray = Array.isArray(value) ? value : [value]
67
68
  ;(target as any)[finalKey].set(...nextValueAsArray)
68
69
  } else if (typeof liveProperty === 'function') {
69
- // if property is a function, let's try calling it
70
- liveProperty.bind(node.instance)(...value)
70
+ // some function properties are set rather than called, so let's handle them
71
+ if (
72
+ finalKey.toLowerCase() === 'onbeforerender' ||
73
+ finalKey.toLowerCase() === 'onafterrender'
74
+ ) {
75
+ ;(target as any)[finalKey] = value
76
+ } else {
77
+ if (!Array.isArray(value)) {
78
+ throw new Error(
79
+ 'Arguments on a declarative method must be wrapped in an array.\nWorks:\n<example :methodCall="[256]" />\nDoesn\'t work:\n<example :methodCall="256" />'
80
+ )
81
+ }
82
+ // if property is a function, let's try calling it
83
+ liveProperty.bind(node.instance)(...value)
84
+ }
71
85
 
72
86
  // pass the result to the parent
73
87
  // const parent = node.parentNode
package/src/index.ts CHANGED
@@ -2,19 +2,14 @@ import {
2
2
  computed,
3
3
  createRenderer,
4
4
  Component,
5
+ ComputedRef,
5
6
  inject,
6
7
  watch,
7
8
  reactive,
8
9
  Ref,
9
10
  } from 'vue'
10
11
  import { createNodeOps } from './nodeOps'
11
- import {
12
- ensuredCamera,
13
- ensureRenderer,
14
- ensuredScene,
15
- extend,
16
- MiniDom,
17
- } from './core'
12
+ import { extend, MiniDom } from './core'
18
13
  import { components } from './components'
19
14
  import { Lunch } from './types'
20
15
 
@@ -27,28 +22,58 @@ export * from './keys'
27
22
  // Utilities
28
23
  export * from './utils/find'
29
24
 
30
- /** The current camera. Often easier to use `useCamera` instead of this. */
31
- // TODO: update docs
32
- export const camera = ensuredCamera
33
- // TODO: update docs
34
- export const useCamera = () => ensuredCamera()
25
+ /** The current camera as a computed value. */
26
+ export const useCamera = <T extends THREE.Camera = THREE.Camera>() =>
27
+ inject<ComputedRef<T>>(Keys.appCameraKey)!
28
+ /** Run a function using the current camera when it's present. */
29
+ export const onCameraReady = <T extends THREE.Camera = THREE.Camera>(
30
+ cb: (camera?: T) => void
31
+ ) => {
32
+ const stopWatch = watch(
33
+ useCamera<T>(),
34
+ (newVal) => {
35
+ if (newVal) {
36
+ cb(newVal)
37
+ stopWatch()
38
+ }
39
+ },
40
+ { immediate: true }
41
+ )
42
+ }
35
43
 
36
- /** The current renderer as a computed value. Often easier to use `useRenderer` instead of this. */
37
- export const renderer = ensureRenderer
44
+ /** The current renderer as a computed value. */
45
+ export const useRenderer = <T extends THREE.Renderer = THREE.WebGLRenderer>() =>
46
+ inject<ComputedRef<T>>(Keys.appRenderersKey)!
38
47
  /** Run a function using the current renderer when it's present. */
39
- export const useRenderer = () => ensureRenderer()!
48
+ export const onRendererReady = <T extends THREE.Renderer = THREE.Renderer>(
49
+ cb: (renderer?: T) => void
50
+ ) => {
51
+ const stopWatch = watch(
52
+ useRenderer<T>(),
53
+ (newVal) => {
54
+ if (newVal) {
55
+ cb(newVal)
56
+ stopWatch()
57
+ }
58
+ },
59
+ { immediate: true }
60
+ )
61
+ }
40
62
 
41
- /** The current scene. Often easier to use `useScene` instead of this. */
42
- // TODO: update docs
43
- export const scene = ensuredScene
63
+ /** The current scene as a computed value. */
64
+ export const useScene = <T extends THREE.Scene = THREE.Scene>() =>
65
+ inject<ComputedRef<T>>(Keys.appSceneKey)!
44
66
  /** Run a function using the current scene when it's present. */
45
- // TODO: update docs
46
- export function useScene(callback: (newScene: THREE.Scene) => void) {
47
- return watch(
48
- scene,
67
+ export const onSceneReady = <T extends THREE.Scene = THREE.Scene>(
68
+ cb: (scene?: T) => void
69
+ ) => {
70
+ const stopWatch = watch(
71
+ useScene<T>(),
49
72
  (newVal) => {
50
- if (!newVal) return
51
- callback(newVal.value as THREE.Scene)
73
+ if (newVal) {
74
+ cb(newVal)
75
+ stopWatch()
76
+ }
52
77
  },
53
78
  { immediate: true }
54
79
  )
@@ -116,18 +141,15 @@ export const updateGlobals = (newValue: Partial<Lunch.AppGlobals>) => {
116
141
  useUpdateGlobals()?.(newValue)
117
142
  }
118
143
 
119
- // TODO: document
120
- export const useRootNode = () =>
121
- inject<MiniDom.RendererRootNode>(Keys.appRootNodeKey)
122
-
123
- // TODO: document
144
+ /** Use the current Lunchbox app. Usually used internally by Lunchbox. */
124
145
  export const useApp = () => inject<Lunch.App>(Keys.appKey)
125
146
 
126
- // TODO: document
147
+ /** Obtain a list of the start callback functions. Usually used internally by Lunchbox. */
127
148
  export const useStartCallbacks = () =>
128
- inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey) //[] as Lunch.UpdateCallback[]
149
+ inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey)
129
150
 
130
- // TODO: document
151
+ /** Run a given callback once when the Lunchbox app starts. Include an index to
152
+ * splice the callback at that index in the callback queue. */
131
153
  export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
132
154
  const callbacks = useStartCallbacks()
133
155
  if (index === Infinity) {
@@ -137,7 +159,7 @@ export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
137
159
  }
138
160
  }
139
161
 
140
- // TODO: document
162
+ /** Obtain a list of interactable objects (registered via onClick, onHover, etc events). Usually used internally by Lunchbox. */
141
163
  export const useLunchboxInteractables = () =>
142
164
  inject<Ref<Lunch.Node[]>>(Keys.lunchboxInteractables)
143
165
 
@@ -43,3 +43,13 @@ export const isLunchboxStandardNode = (
43
43
  export const isLunchboxRootNode = (node: any): node is Lunch.RootMeta => {
44
44
  return node.isLunchboxRootNode
45
45
  }
46
+
47
+ export const waitFor = async (get: () => any) => {
48
+ let output = get()
49
+ while (!output) {
50
+ await new Promise((resolve) => requestAnimationFrame(resolve))
51
+ output = get()
52
+ console.log(output)
53
+ }
54
+ return output
55
+ }
@@ -1,16 +0,0 @@
1
- import { ComputedRef, inject } from 'vue'
2
- import * as Keys from '../keys'
3
-
4
- export const ensuredCamera = <T extends THREE.Camera = THREE.Camera>() =>
5
- inject<ComputedRef<T>>(Keys.appCameraKey)!
6
-
7
- // ENSURE RENDERER
8
- // ====================
9
- export const ensureRenderer = <
10
- T extends THREE.Renderer = THREE.WebGLRenderer
11
- >() => inject<ComputedRef<T>>(Keys.appRenderersKey)
12
-
13
- // ENSURE SCENE
14
- // ====================
15
- export const ensuredScene = <T extends THREE.Scene = THREE.Scene>() =>
16
- inject<ComputedRef<T>>(Keys.appSceneKey)