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

Scene Data Refactor #7796

Merged
merged 8 commits into from
Mar 23, 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
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const useUserMediaWindowHook = ({ peerID, type }: Props) => {

const mediaStreamState = useHookstate(getMutableState(MediaStreamState))
const mediaSettingState = useHookstate(getMutableState(MediaSettingsState))
const mediaState = getMediaSceneMetadataState(Engine.instance.currentScene)
const mediaState = getMediaSceneMetadataState()
const rendered =
mediaSettingState.immersiveMediaMode.value === 'off' ||
(mediaSettingState.immersiveMediaMode.value === 'auto' && !mediaState.immersiveMedia.value)
Expand Down
63 changes: 35 additions & 28 deletions packages/client-core/src/components/World/LoadEngineWithScene.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,71 @@
import { useHookstate } from '@hookstate/core'
import React, { useEffect, useState } from 'react'
import React, { useEffect } from 'react'
import { useParams } from 'react-router-dom'

import { LocationInstanceConnectionServiceReceptor } from '@etherealengine/client-core/src/common/services/LocationInstanceConnectionService'
import { LocationService } from '@etherealengine/client-core/src/social/services/LocationService'
import { leaveNetwork } from '@etherealengine/client-core/src/transports/SocketWebRTCClientFunctions'
import { useAuthState } from '@etherealengine/client-core/src/user/services/AuthService'
import { SceneServiceReceptor, useSceneState } from '@etherealengine/client-core/src/world/services/SceneService'
import { UserId } from '@etherealengine/common/src/interfaces/UserId'
import multiLogger from '@etherealengine/common/src/logger'
import { getSearchParamFromURL } from '@etherealengine/common/src/utils/getSearchParamFromURL'
import { getRandomSpawnPoint, getSpawnPoint } from '@etherealengine/engine/src/avatar/AvatarSpawnSystem'
import { teleportAvatar } from '@etherealengine/engine/src/avatar/functions/moveAvatar'
import {
AppLoadingAction,
AppLoadingState,
AppLoadingStates
} from '@etherealengine/engine/src/common/AppLoadingService'
import { Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import { EngineActions, useEngineState } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { EngineActions, EngineState, useEngineState } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene'
import { addComponent } from '@etherealengine/engine/src/ecs/functions/ComponentFunctions'
import { SystemModuleType } from '@etherealengine/engine/src/ecs/functions/SystemFunctions'
import { initSystems, SystemModuleType } from '@etherealengine/engine/src/ecs/functions/SystemFunctions'
import { spawnLocalAvatarInWorld } from '@etherealengine/engine/src/networking/functions/receiveJoinWorld'
import { PortalEffects } from '@etherealengine/engine/src/scene/components/PortalComponent'
import { UUIDComponent } from '@etherealengine/engine/src/scene/components/UUIDComponent'
import { setAvatarToLocationTeleportingState } from '@etherealengine/engine/src/scene/functions/loaders/PortalFunctions'
import { XRState } from '@etherealengine/engine/src/xr/XRState'
import { addActionReceptor, dispatchAction, getMutableState, removeActionReceptor } from '@etherealengine/hyperflux'

import { AppLoadingAction, AppLoadingStates, useLoadingState } from '../../common/services/AppLoadingService'
import {
addActionReceptor,
dispatchAction,
getMutableState,
getState,
removeActionReceptor
} from '@etherealengine/hyperflux'
import { loadEngineInjection } from '@etherealengine/projects/loadEngineInjection'

import { API } from '../../API'
import { NotificationService } from '../../common/services/NotificationService'
import { useRouter } from '../../common/services/RouterService'
import { useLocationState } from '../../social/services/LocationService'
import { SocketWebRTCClientNetwork } from '../../transports/SocketWebRTCClientFunctions'
import { initClient, loadScene } from './LocationLoadHelper'
import { ClientModules } from '../../world/ClientModules'

const logger = multiLogger.child({ component: 'client-core:world' })

type LoadEngineProps = {
injectedSystems?: SystemModuleType<any>[]
}

export const initClient = async (injectedSystems: SystemModuleType<any>[] = []) => {
if (getMutableState(EngineState).isEngineInitialized.value) return

const projects = API.instance.client.service('projects').find()

await ClientModules()
await initSystems(injectedSystems)
await loadEngineInjection(await projects)

dispatchAction(EngineActions.initializeEngine({ initialised: true }))
}

export const useLoadEngine = ({ injectedSystems }: LoadEngineProps) => {
useEffect(() => {
initClient(injectedSystems)

addActionReceptor(SceneServiceReceptor)
addActionReceptor(LocationInstanceConnectionServiceReceptor)

return () => {
removeActionReceptor(SceneServiceReceptor)
removeActionReceptor(LocationInstanceConnectionServiceReceptor)
}
}, [])
Expand Down Expand Up @@ -157,29 +178,15 @@ type Props = {

export const LoadEngineWithScene = ({ injectedSystems, spectate }: Props) => {
const engineState = useEngineState()
const sceneState = useSceneState()
const loadingState = useLoadingState()
const sceneData = useHookstate(getMutableState(SceneState).sceneData)
const appState = useHookstate(getMutableState(AppLoadingState).state)

useLoadEngine({ injectedSystems })
useLocationSpawnAvatar(spectate)
usePortalTeleport()

/**
* load the scene whenever it changes
*/
useEffect(() => {
// loadScene() deserializes the scene data, and deserializers sometimes mutate/update that data for backwards compatability.
// Since hookstate throws errors when mutating proxied values, we have to pass down the unproxied value here
const sceneData = sceneState.currentScene.get({ noproxy: true })
if (engineState.isEngineInitialized.value && sceneData) {
if (loadingState.state.value !== AppLoadingStates.SUCCESS)
dispatchAction(AppLoadingAction.setLoadingState({ state: AppLoadingStates.SCENE_LOADING }))
loadScene(sceneData)
}
}, [engineState.isEngineInitialized, sceneState.currentScene])

useEffect(() => {
if (engineState.sceneLoaded.value && loadingState.state.value !== AppLoadingStates.SUCCESS)
if (engineState.sceneLoaded.value && appState.value !== AppLoadingStates.SUCCESS)
dispatchAction(AppLoadingAction.setLoadingState({ state: AppLoadingStates.SUCCESS }))
}, [engineState.sceneLoaded, engineState.loadingProgress])

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'

import { LocationAction, useLocationState } from '@etherealengine/client-core/src/social/services/LocationService'
import {
LocationAction,
LocationService,
useLocationState
} from '@etherealengine/client-core/src/social/services/LocationService'
import { useAuthState } from '@etherealengine/client-core/src/user/services/AuthService'
import { EngineActions } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { dispatchAction } from '@etherealengine/hyperflux'

import { retrieveLocationByName } from './LocationLoadHelper'

export const LoadLocationScene = () => {
const { t } = useTranslation()
const authState = useAuthState()
Expand All @@ -32,7 +33,7 @@ export const LoadLocationScene = () => {
locationState.locationName.value &&
authState.isLoggedIn.value
) {
retrieveLocationByName(locationState.locationName.value, selfUser.id.value)
LocationService.getLocationByName(locationState.locationName.value, selfUser.id.value)
}
}, [authState.isLoggedIn.value, locationState.locationName.value])

Expand Down

This file was deleted.

35 changes: 20 additions & 15 deletions packages/client-core/src/systems/LoadingUISystem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useEffect } from 'react'
import { DoubleSide, Mesh, MeshBasicMaterial, SphereGeometry, Texture } from 'three'

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 { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene'
import {
addComponent,
getComponent,
Expand Down Expand Up @@ -31,8 +33,6 @@ import {
} from '@etherealengine/hyperflux'
import type { WebLayer3D } from '@etherealengine/xrui'

import { AppLoadingState, AppLoadingStates, useLoadingState } from '../common/services/AppLoadingService'
import { SceneActions } from '../world/services/SceneService'
import { LoadingSystemState } from './state/LoadingState'
import { createLoaderDetailView } from './ui/LoadingDetailView'

Expand All @@ -57,7 +57,24 @@ export default async function LoadingUISystem() {

setObjectLayers(mesh, ObjectLayers.UI)

const currentSceneChangedQueue = createActionQueue(SceneActions.currentSceneChanged.matches)
const sceneDataReactor = startReactor(() => {
const sceneData = useHookstate(getMutableState(SceneState).sceneData)

useEffect(() => {
if (!sceneData.value) return
const thumbnailUrl = sceneData.value.thumbnailUrl.replace('thumbnail.jpeg', 'envmap.png')
if (thumbnailUrl && mesh.userData.url !== thumbnailUrl) {
mesh.userData.url = thumbnailUrl
textureLoader.load(thumbnailUrl, (texture) => {
if (texture) mesh.material.map = texture!
mesh.visible = true
})
}
}, [sceneData])

return null
})

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

Expand All @@ -77,17 +94,6 @@ export default async function LoadingUISystem() {
})

const execute = () => {
for (const action of currentSceneChangedQueue()) {
const thumbnailUrl = action.sceneData.thumbnailUrl.replace('thumbnail.jpeg', 'envmap.png')
if (thumbnailUrl && mesh.userData.url !== thumbnailUrl) {
mesh.userData.url = thumbnailUrl
textureLoader.load(thumbnailUrl, (texture) => {
if (texture) mesh.material.map = texture!
mesh.visible = true
})
}
}

for (const action of spectateUserQueue()) {
if (appLoadingState.state.value === AppLoadingStates.SUCCESS && engineState.sceneLoaded.value)
transition.setState('OUT')
Expand Down Expand Up @@ -145,7 +151,6 @@ export default async function LoadingUISystem() {
}

const cleanup = async () => {
removeActionQueue(currentSceneChangedQueue)
removeActionQueue(avatarModelChangedQueue)
removeActionQueue(spectateUserQueue)
removeEntity(ui.entity)
Expand Down
20 changes: 8 additions & 12 deletions packages/client-core/src/systems/ui/LoadingDetailView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { createState, State, useHookstate } from '@hookstate/core'
import { createState, useHookstate } from '@hookstate/core'
import getImagePalette from 'image-palette-core'
import React, { useEffect, useState } from 'react'
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { Color } from 'three'

import { Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import { useEngineState } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { EngineRenderer } from '@etherealengine/engine/src/renderer/WebGLRendererSystem'
import { XRState } from '@etherealengine/engine/src/xr/XRState'
import { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene'
import { createTransitionState } from '@etherealengine/engine/src/xrui/functions/createTransitionState'
import { createXRUI, XRUI } from '@etherealengine/engine/src/xrui/functions/createXRUI'
import { createXRUI } from '@etherealengine/engine/src/xrui/functions/createXRUI'
import { useXRUIState } from '@etherealengine/engine/src/xrui/functions/useXRUIState'
import { getMutableState } from '@etherealengine/hyperflux'

import { AppLoadingStates, useLoadingState } from '../../../common/services/AppLoadingService'
import { useSceneState } from '../../../world/services/SceneService'
import { LoadingSystemState } from '../../state/LoadingState'
import ProgressBar from './SimpleProgressBar'
import LoadingDetailViewStyle from './style'

Expand All @@ -40,7 +36,7 @@ function setDefaultPalette(colors) {

const LoadingDetailView = (props: { transition: ReturnType<typeof createTransitionState> }) => {
const uiState = useXRUIState<LoadingUIState>()
const sceneState = useSceneState()
const sceneData = useHookstate(getMutableState(SceneState).sceneData)
const engineState = useEngineState()
const { t } = useTranslation()
const colors = useHookstate({
Expand All @@ -50,7 +46,7 @@ const LoadingDetailView = (props: { transition: ReturnType<typeof createTransiti
})

useEffect(() => {
const thumbnailUrl = sceneState.currentScene.ornull?.thumbnailUrl.value
const thumbnailUrl = sceneData.ornull?.thumbnailUrl.value
const img = new Image()

if (thumbnailUrl) {
Expand Down Expand Up @@ -79,7 +75,7 @@ const LoadingDetailView = (props: { transition: ReturnType<typeof createTransiti
return () => {
img.onload = null
}
}, [sceneState.currentScene.ornull?.thumbnailUrl])
}, [sceneData.ornull?.thumbnailUrl])

const sceneLoaded = engineState.sceneLoaded.value
const joinedWorld = engineState.joinedWorld.value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ import {
import { isMobile } from '@etherealengine/engine/src/common/functions/isMobile'
import { Engine } from '@etherealengine/engine/src/ecs/classes/Engine'
import { EngineState } from '@etherealengine/engine/src/ecs/classes/EngineState'
import { SceneState } from '@etherealengine/engine/src/ecs/classes/Scene'
import { RendererState } from '@etherealengine/engine/src/renderer/RendererState'
import {
getPostProcessingSceneMetadataState,
PostProcessingSceneMetadataLabel
} from '@etherealengine/engine/src/renderer/WebGLRendererSystem'
import { XRState } from '@etherealengine/engine/src/xr/XRState'
import { dispatchAction, getMutableState, useHookstate } from '@etherealengine/hyperflux'
import { dispatchAction, getMutableState, getState, useHookstate } from '@etherealengine/hyperflux'
import Box from '@etherealengine/ui/src/Box'
import Grid from '@etherealengine/ui/src/Grid'
import Icon from '@etherealengine/ui/src/Icon'
Expand Down Expand Up @@ -61,10 +62,10 @@ const SettingMenu = ({ changeActiveMenu, isPopover }: Props): JSX.Element => {
const selectedTab = useHookstate('general')
const engineState = useHookstate(getMutableState(EngineState))

const postProcessingSceneMetadataState = Engine.instance.currentScene.sceneMetadataRegistry[
const postProcessingSceneMetadataState = getMutableState(SceneState).sceneMetadataRegistry[
PostProcessingSceneMetadataLabel
]
? getPostProcessingSceneMetadataState(Engine.instance.currentScene)
? getPostProcessingSceneMetadataState()
: undefined
const postprocessingSettings = postProcessingSceneMetadataState?.enabled
? useHookstate(postProcessingSceneMetadataState.enabled)
Expand Down
Loading