Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Rework Loading Screen State #9070

Merged
merged 3 commits into from
Oct 17, 2023
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
51 changes: 18 additions & 33 deletions packages/client-core/src/systems/LoadingUISystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import { AssetLoader } from '@etherealengine/engine/src/assets/classes/AssetLoad
import createReadableTexture from '@etherealengine/engine/src/assets/functions/createReadableTexture'
import { AppLoadingState, AppLoadingStates } from '@etherealengine/engine/src/common/AppLoadingService'
import { Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import { EngineActions, EngineState } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { EngineState } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene'
import {
addComponent,
Expand All @@ -52,7 +52,7 @@ import {
import { XRUIComponent } from '@etherealengine/engine/src/xrui/components/XRUIComponent'
import { createTransitionState } from '@etherealengine/engine/src/xrui/functions/createTransitionState'
import { ObjectFitFunctions } from '@etherealengine/engine/src/xrui/functions/ObjectFitFunctions'
import { defineActionQueue, defineState, getMutableState, getState, useHookstate } from '@etherealengine/hyperflux'
import { defineState, getMutableState, getState, useHookstate } from '@etherealengine/hyperflux'
import type { WebLayer3D } from '@etherealengine/xrui'

import { CameraComponent } from '@etherealengine/engine/src/camera/components/CameraComponent'
Expand Down Expand Up @@ -86,17 +86,13 @@ const LoadingUISystemState = defineState({
setObjectLayers(mesh, ObjectLayers.UI)

return {
metadataLoaded: false,
ui,
mesh,
transition
}
}
})

const avatarModelChangedQueue = defineActionQueue(EngineActions.avatarModelChanged.matches)
const spectateUserQueue = defineActionQueue(EngineActions.spectateUser.matches)

/** Scene Colors */
function setDefaultPalette() {
const uiState = getState(LoadingUISystemState).ui.state
Expand All @@ -120,25 +116,29 @@ const setColors = (image: HTMLImageElement) => {
function LoadingReactor() {
const loadingState = useHookstate(getMutableState(AppLoadingState))
const loadingProgress = useHookstate(getMutableState(EngineState).loadingProgress)
const sceneLoaded = useHookstate(getMutableState(EngineState).sceneLoaded)
const userReady = useHookstate(getMutableState(EngineState).userReady)
const state = useHookstate(getMutableState(LoadingUISystemState))
const sceneData = useHookstate(getMutableState(SceneState).sceneData)
const mesh = state.mesh.value
const metadataLoaded = state.metadataLoaded

/** Handle loading state changes */
useEffect(() => {
const transition = getState(LoadingUISystemState).transition
if (loadingState.state.value === AppLoadingStates.SCENE_LOADING && transition.state === 'OUT')
return transition.setState('IN')

if (loadingState.state.value === AppLoadingStates.FAIL && transition.state === 'IN')
return transition.setState('OUT')

if (
loadingState.state.value === AppLoadingStates.SCENE_LOADING &&
transition.state === 'OUT' &&
metadataLoaded.value
) {
transition.setState('IN')
}
if (loadingState.state.value === AppLoadingStates.FAIL && transition.state === 'IN') {
transition.setState('OUT')
}
}, [loadingState.state, metadataLoaded])
loadingState.state.value === AppLoadingStates.SUCCESS &&
transition.state === 'IN' &&
userReady.value &&
sceneLoaded.value
)
return transition.setState('OUT')
}, [loadingState.state, userReady, sceneLoaded])

/** Scene data changes */
useEffect(() => {
Expand Down Expand Up @@ -204,25 +204,11 @@ const mainThemeColor = new Color()
const defaultColor = new Color()

const execute = () => {
const { transition, ui, mesh, metadataLoaded } = getState(LoadingUISystemState)
const { transition, ui, mesh } = getState(LoadingUISystemState)
if (!transition) return

const appLoadingState = getState(AppLoadingState)
const engineState = getState(EngineState)

for (const action of spectateUserQueue()) {
if (appLoadingState.state === AppLoadingStates.SUCCESS && engineState.sceneLoaded) transition.setState('OUT')
}

for (const action of avatarModelChangedQueue()) {
if (
(action.entity === Engine.instance.localClientEntity || engineState.spectating) &&
appLoadingState.state === AppLoadingStates.SUCCESS &&
engineState.sceneLoaded
)
transition.setState('OUT')
}

if (transition.state === 'OUT' && transition.alpha === 0) {
removeComponent(ui.entity, ComputedTransformComponent)
return
Expand Down Expand Up @@ -299,7 +285,6 @@ const reactor = () => {
// removeEntity(ui.entity)
// mesh.removeFromParent()
// getMutableState(LoadingUISystemState).set({
// metadataLoaded: false,
// ui: null!,
// mesh: null!,
// transition: null!
Expand Down
7 changes: 4 additions & 3 deletions packages/engine/src/avatar/functions/avatarFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ import {
Vector3
} from 'three'

import { dispatchAction, getMutableState, getState } from '@etherealengine/hyperflux'
import { getMutableState, getState } from '@etherealengine/hyperflux'

import { AssetLoader } from '../../assets/classes/AssetLoader'
import { isClient } from '../../common/functions/getEnvironment'
import { iOS } from '../../common/functions/isMobile'
import { EngineActions, EngineState } from '../../ecs/classes/EngineState'
import { EngineState } from '../../ecs/classes/EngineState'
import { Entity } from '../../ecs/classes/Entity'
import {
addComponent,
Expand All @@ -64,6 +64,7 @@ import { AnimationState } from '../AnimationManager'
// import { retargetSkeleton, syncModelSkeletons } from '../animation/retargetSkeleton'
import config from '@etherealengine/common/src/config'
import { GLTF } from '../../assets/loaders/gltf/GLTFLoader'
import { Engine } from '../../ecs/classes/Engine'
import avatarBoneMatching, {
BoneNames,
findSkinnedMeshes,
Expand Down Expand Up @@ -148,7 +149,7 @@ export const loadAvatarForUser = async (
})
}

dispatchAction(EngineActions.avatarModelChanged({ entity }))
if (entity === Engine.instance.localClientEntity) getMutableState(EngineState).userReady.set(true)
}

export const setupAvatarForUser = (entity: Entity, model: VRM) => {
Expand Down
1 change: 1 addition & 0 deletions packages/engine/src/camera/systems/CameraSystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ const execute = () => {
for (const action of cameraSpawnActions()) cameraSpawnReceptor(action)

for (const action of spectateUserActions()) {
getMutableState(EngineState).userReady.set(true)
const cameraEntity = Engine.instance.cameraEntity
if (action.user) setComponent(cameraEntity, SpectatorComponent, { userId: action.user as UserID })
else
Expand Down
7 changes: 2 additions & 5 deletions packages/engine/src/ecs/classes/EngineState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export const EngineState = defineState({
frameTime: Date.now(),
simulationTime: Date.now(),

userReady: false,

deltaSeconds: 0,
elapsedSeconds: 0,

Expand Down Expand Up @@ -109,9 +111,4 @@ export class EngineActions {
targetEntity: matchesEntity.optional(),
handedness: matches.string as Validator<unknown, XRHandedness>
})

static avatarModelChanged = defineAction({
type: 'xre.engine.Engine.AVATAR_MODEL_CHANGED' as const,
entity: matchesEntity
})
}
Loading