Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v9] fix: remove useUpdate #3262

Merged
merged 5 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 0 additions & 121 deletions example/src/demos/Update.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions example/src/demos/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ const Test = { Component: lazy(() => import('./Test')) }
const Viewcube = { Component: lazy(() => import('./Viewcube')) }
const Portals = { Component: lazy(() => import('./Portals')) }
const ViewTracking = { Component: lazy(() => import('./ViewTracking')) }
const Update = { Component: lazy(() => import('./Update')) }

export {
Animation,
Expand All @@ -51,5 +50,4 @@ export {
MultiView,
Portals,
ViewTracking,
Update,
}
18 changes: 1 addition & 17 deletions packages/fiber/src/core/hooks.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as THREE from 'three'
import * as React from 'react'
import { suspend, preload, clear } from 'suspend-react'
import { context, RootState, RenderCallback, UpdateCallback, StageTypes, RootStore } from './store'
import { context, RootState, RenderCallback, RootStore } from './store'
import { buildGraph, ObjectMap, is, useMutableCallback, useIsomorphicLayoutEffect, isObject3D } from './utils'
import { Stages } from './stages'
import type { Instance } from './reconciler'

/**
Expand Down Expand Up @@ -54,21 +53,6 @@ export function useFrame(callback: RenderCallback, renderPriority: number = 0):
return null
}

/**
* Executes a callback in a given update stage.
* Uses the stage instance to identify which stage to target in the lifecycle.
*/
export function useUpdate(callback: UpdateCallback, stage: StageTypes = Stages.Update): void {
const store = useStore()
const stages = store.getState().internal.stages
// Memoize ref
const ref = useMutableCallback(callback)
// Throw an error if a stage does not exist in the lifecycle
if (!stages.includes(stage)) throw new Error(`An invoked stage does not exist in the lifecycle.`)
// Subscribe on mount, unsubscribe on unmount
useIsomorphicLayoutEffect(() => stage.add(ref, store), [stage])
}

/**
* Returns a node graph of an object with named nodes & materials.
* @see https://docs.pmnd.rs/react-three-fiber/api/hooks#usegraph
Expand Down
8 changes: 0 additions & 8 deletions packages/fiber/src/core/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,15 @@ export type {
export { extend, reconciler } from './reconciler'
export type { ReconcilerRoot, GLProps, CameraProps, RenderProps, InjectState } from './renderer'
export { _roots, render, createRoot, unmountComponentAtNode, createPortal } from './renderer'
export type { UpdateSubscription } from './stages'
export { Stage, FixedStage, Stages } from './stages'
export type {
Subscription,
Dpr,
Size,
Viewport,
RenderCallback,
UpdateCallback,
LegacyAlways,
FrameloopMode,
FrameloopRender,
FrameloopLegacy,
Frameloop,
Performance,
Renderer,
StageTypes,
XRManager,
RootState,
RootStore,
Expand Down
21 changes: 15 additions & 6 deletions packages/fiber/src/core/loop.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { _roots } from './renderer'
import type { RootState } from './store'
import type { RootState, Subscription } from './store'

export type GlobalRenderCallback = (timestamp: number) => void
interface SubItem {
Expand Down Expand Up @@ -54,22 +54,31 @@ export function flushGlobalEffects(type: GlobalEffectType, timestamp: number): v
}
}

let subscribers: Subscription[]
let subscription: Subscription

function update(timestamp: number, state: RootState, frame?: XRFrame) {
// Run local effects
let delta = state.clock.getDelta()

// In frameloop='never' mode, clock times are updated using the provided timestamp
if (state.frameloop === 'never' && typeof timestamp === 'number') {
delta = timestamp - state.clock.elapsedTime
state.clock.oldTime = state.clock.elapsedTime
state.clock.elapsedTime = timestamp
} else {
delta = Math.max(Math.min(delta, state.internal.maxDelta), 0)
}
// Call subscribers (useUpdate)
for (const stage of state.internal.stages) {
stage.frame(delta, frame)

// Call subscribers (useFrame)
subscribers = state.internal.subscribers
for (let i = 0; i < subscribers.length; i++) {
subscription = subscribers[i]
subscription.ref.current(subscription.store.getState(), delta, frame)
}

// Render content
if (!state.internal.priority && state.gl.render) state.gl.render(state.scene, state.camera)

// Decrease frame count
state.internal.frames = Math.max(0, state.internal.frames - 1)
return state.frameloop === 'always' ? 1 : state.internal.frames
}
Expand Down
42 changes: 0 additions & 42 deletions packages/fiber/src/core/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
Size,
Dpr,
Performance,
Subscription,
Frameloop,
RootStore,
} from './store'
Expand All @@ -34,7 +33,6 @@ import {
getColorManagement,
} from './utils'
import { useStore } from './hooks'
import { Stage, Lifecycle, Stages } from './stages'

// Shim for OffscreenCanvas since it was removed from DOM types
// https://github.com/DefinitelyTyped/DefinitelyTyped/pull/54988
Expand Down Expand Up @@ -107,9 +105,6 @@ export interface RenderProps<TCanvas extends HTMLCanvasElement | OffscreenCanvas
onCreated?: (state: RootState) => void
/** Response for pointer clicks that have missed any target */
onPointerMissed?: (event: MouseEvent) => void
/** Create a custom lifecycle of stages */
stages?: Stage[]
render?: 'auto' | 'manual'
}

const createRendererInstance = <TCanvas extends HTMLCanvasElement | OffscreenCanvas>(
Expand All @@ -128,39 +123,6 @@ const createRendererInstance = <TCanvas extends HTMLCanvasElement | OffscreenCan
})
}

const createStages = (stages: Stage[] | undefined, store: RootStore) => {
const state = store.getState()
let subscribers: Subscription[]
let subscription: Subscription

const _stages = stages ?? Lifecycle

if (!_stages.includes(Stages.Update)) throw 'The Stages.Update stage is required for R3F.'
if (!_stages.includes(Stages.Render)) throw 'The Stages.Render stage is required for R3F.'

state.set(({ internal }) => ({ internal: { ...internal, stages: _stages } }))

// Add useFrame loop to update stage
const frameCallback = {
current(state: RootState, delta: number, frame?: XRFrame | undefined) {
subscribers = state.internal.subscribers
for (let i = 0; i < subscribers.length; i++) {
subscription = subscribers[i]
subscription.ref.current(subscription.store.getState(), delta, frame)
}
},
}
Stages.Update.add(frameCallback, store)

// Add render callback to render stage
const renderCallback = {
current(state: RootState) {
if (state.internal.render === 'auto' && state.gl.render) state.gl.render(state.scene, state.camera)
},
}
Stages.Render.add(renderCallback, store)
}

export interface ReconcilerRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas> {
configure: (config?: RenderProps<TCanvas>) => ReconcilerRoot<TCanvas>
render: (element: React.ReactNode) => RootStore
Expand Down Expand Up @@ -247,7 +209,6 @@ export function createRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(
raycaster: raycastOptions,
camera: cameraOptions,
onPointerMissed,
stages,
} = props

let state = store.getState()
Expand Down Expand Up @@ -426,9 +387,6 @@ export function createRoot<TCanvas extends HTMLCanvasElement | OffscreenCanvas>(
if (performance && !is.equ(performance, state.performance, shallowLoose))
state.set((state) => ({ performance: { ...state.performance, ...performance } }))

// Create update stages. Only do this once on init
if (state.internal.stages.length === 0) createStages(stages, store)

// Set locals
onCreated = onCreatedCallback
configured = true
Expand Down
Loading