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

Remove entity node + various fixes #635

Merged
merged 16 commits into from
Jun 9, 2023
Merged
8 changes: 8 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
coverage:
status:
project:
default:
threshold: 1%
patch:
default:
threshold: 1%
10 changes: 10 additions & 0 deletions packages/@dcl/ecs/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { GrowOnlyValueSetComponentDefinition, LastWriteWinElementSetComponentDefinition } from '../engine/component'
import { IEngine } from '../engine/types'
import { AnimatorComponentDefinitionExtended, defineAnimatorComponent } from './extended/Animator'
import { defineMaterialComponent, MaterialComponentDefinitionExtended } from './extended/Material'
import { defineMeshColliderComponent, MeshColliderComponentDefinitionExtended } from './extended/MeshCollider'
import { defineMeshRendererComponent, MeshRendererComponentDefinitionExtended } from './extended/MeshRenderer'
import { LwwComponentGetter, GSetComponentGetter } from './generated/index.gen'
import defineNameComponent, { NameType } from './manual/Name'
import { defineTransformComponent, TransformComponentExtended } from './manual/Transform'

export * from './generated/index.gen'
Expand Down Expand Up @@ -33,3 +35,11 @@ export const MeshRenderer: LwwComponentGetter<MeshRendererComponentDefinitionExt
/* @__PURE__ */
export const MeshCollider: LwwComponentGetter<MeshColliderComponentDefinitionExtended> = (engine) =>
defineMeshColliderComponent(engine)

/**
* @alpha
*/
/* @__PURE__ */
export const Name: (engine: Pick<IEngine, 'defineComponent'>) => LastWriteWinElementSetComponentDefinition<NameType> = (
engine
) => defineNameComponent(engine)
16 changes: 16 additions & 0 deletions packages/@dcl/ecs/src/components/manual/Name.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { IEngine, LastWriteWinElementSetComponentDefinition } from '../../engine/types'
import { Schemas } from '../../schemas'

export type NameComponent = LastWriteWinElementSetComponentDefinition<NameType>
export interface NameType {
value: string
}

function defineNameComponent(engine: Pick<IEngine, 'defineComponent'>) {
const Name = engine.defineComponent('core-schema::Name', {
value: Schemas.String
})
return Name
}

export default defineNameComponent
1 change: 1 addition & 0 deletions packages/@dcl/ecs/src/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export type { MeshRendererComponentDefinitionExtended } from './extended/MeshRen
export type { MeshColliderComponentDefinitionExtended } from './extended/MeshCollider'
export type { TextureHelper, MaterialComponentDefinitionExtended } from './extended/Material'
export type { TransformComponentExtended, TransformTypeWithOptionals } from './manual/Transform'
export type { NameComponent, NameType } from './manual/Name'
14 changes: 14 additions & 0 deletions packages/@dcl/ecs/src/engine/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ export interface LastWriteWinElementSetComponentDefinition<T> extends BaseCompon
*/
getOrCreateMutable(entity: Entity, initialValue?: T): T
}
/**
* @public
*/
export type ReadOnlyLastWriteWinElementSetComponentDefinition<T> = Omit<
LastWriteWinElementSetComponentDefinition<T>,
'create' | 'createOrReplace' | 'deleteFrom' | 'getMutable' | 'getMutableOrNull' | 'getOrCreateMutable'
>

/**
* @public
Expand All @@ -194,9 +201,16 @@ export interface GrowOnlyValueSetComponentDefinition<T> extends BaseComponent<T>
get(entity: Entity): DeepReadonlySet<T>
}

/**
* @public
*/
export type ReadOnlyGrowOnlyValueSetComponentDefinition<T> = Omit<GrowOnlyValueSetComponentDefinition<T>, 'addValue'>

/**
* @public
*/
export type ComponentDefinition<T> =
| LastWriteWinElementSetComponentDefinition<T>
| GrowOnlyValueSetComponentDefinition<T>
| ReadOnlyGrowOnlyValueSetComponentDefinition<T>
| ReadOnlyLastWriteWinElementSetComponentDefinition<T>
22 changes: 16 additions & 6 deletions packages/@dcl/ecs/src/engine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ function preEngine(): PreEngine {
}

function defineComponentFromSchema<T>(componentName: string, schema: ISchema<T>) {
/* istanbul ignore next */
if (sealed) throw new Error('Engine is already sealed. No components can be added at this stage')
const componentId = componentNumberFromName(componentName)
const prev = componentsDefinition.get(componentId)
if (prev) {
// TODO: assert spec === prev.spec
return prev as components.LastWriteWinElementSetComponentDefinition<T>
}
/* istanbul ignore next */
if (sealed) throw new Error('Engine is already sealed. No components can be added at this stage')
const newComponent = createComponentDefinitionFromSchema<T>(componentName, componentId, schema)
componentsDefinition.set(componentId, newComponent)
return newComponent as components.LastWriteWinElementSetComponentDefinition<T>
Expand All @@ -95,14 +95,14 @@ function preEngine(): PreEngine {
schema: ISchema<T>,
options: ValueSetOptions<T>
): components.GrowOnlyValueSetComponentDefinition<T> {
/* istanbul ignore next */
if (sealed) throw new Error('Engine is already sealed. No components can be added at this stage')
const componentId = componentNumberFromName(componentName)
const prev = componentsDefinition.get(componentId)
if (prev) {
// TODO: assert spec === prev.spec
return prev as components.GrowOnlyValueSetComponentDefinition<T>
}
/* istanbul ignore next */
if (sealed) throw new Error('Engine is already sealed. No components can be added at this stage')
const newComponent = createValueSetComponentDefinitionFromSchema<T>(componentName, componentId, schema, options)
componentsDefinition.set(componentId, newComponent)
return newComponent as components.GrowOnlyValueSetComponentDefinition<T>
Expand All @@ -113,13 +113,13 @@ function preEngine(): PreEngine {
mapSpec: T,
constructorDefault?: Partial<MapResult<T>>
) {
if (sealed) throw new Error('Engine is already sealed. No components can be added at this stage')
const componentId = componentNumberFromName(componentName)
const prev = componentsDefinition.get(componentId)
if (prev) {
// TODO: assert spec === prev.spec
return prev as MapComponentDefinition<MapResult<T>>
}
if (sealed) throw new Error('Engine is already sealed. No components can be added at this stage')

const schemaSpec = Schemas.Map(mapSpec, constructorDefault)
const def = createComponentDefinitionFromSchema<MapResult<T>>(componentName, componentId, schemaSpec)
Expand Down Expand Up @@ -167,6 +167,14 @@ function preEngine(): PreEngine {
}
}

function getEntityOrNullByName(value: string) {
const LabelComponent = components.Name({ defineComponent })
for (const [entity, name] of getEntitiesWith(LabelComponent)) {
if (name.value === value) return entity
}
return null
}

function* getComponentDefGroup<T extends ComponentDefinition<any>[]>(...args: T): Iterable<[Entity, ...T]> {
const [firstComponentDef, ...componentDefinitions] = args
for (const [entity] of firstComponentDef.iterator()) {
Expand Down Expand Up @@ -219,7 +227,8 @@ function preEngine(): PreEngine {
defineValueSetComponentFromSchema,
getEntitiesWith,
getComponent,
getComponentOrNull,
getComponentOrNull: getComponentOrNull as IEngine['getComponentOrNull'],
getEntityOrNullByName,
removeComponentDefinition,
registerComponentDefinition,
entityContainer,
Expand Down Expand Up @@ -269,6 +278,7 @@ export function Engine(options?: IEngineOptions): IEngine {
removeComponentDefinition: partialEngine.removeComponentDefinition,
componentsIter: partialEngine.componentsIter,
seal: partialEngine.seal,
getEntityOrNullByName: partialEngine.getEntityOrNullByName,

update,

Expand Down
10 changes: 9 additions & 1 deletion packages/@dcl/ecs/src/engine/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export type PreEngine = Pick<
| 'componentsIter'
| 'seal'
| 'entityContainer'
| 'getEntityOrNullByName'
> & {
getSystems: () => SystemItem[]
}
Expand Down Expand Up @@ -231,14 +232,21 @@ export interface IEngine {
...components: T
): Iterable<[Entity, ...ReadonlyComponentSchema<T>]>

/**
* @alpha
* Search for the entity that matches de label string defined in the editor.
* @param value - Name value string
*/
getEntityOrNullByName(label: string): Entity | null

/**
* @public
* @param deltaTime - deltaTime in seconds
*/
update(deltaTime: number): Promise<void>

/**
* @internal
* @public
* @param componentId - component number or name
*/
removeComponentDefinition(componentId: number | string): void
Expand Down
2 changes: 2 additions & 0 deletions packages/@dcl/ecs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@ import {
TransformComponentExtended,
AnimatorComponentDefinitionExtended
} from './components/types'
import { NameComponent } from './components/manual/Name'

// export components for global engine
export const Transform: TransformComponentExtended = /* @__PURE__*/ components.Transform(engine)
export const Animator: AnimatorComponentDefinitionExtended = /* @__PURE__*/ components.Animator(engine)
export const Material: MaterialComponentDefinitionExtended = /* @__PURE__*/ components.Material(engine)
export const MeshRenderer: MeshRendererComponentDefinitionExtended = /* @__PURE__*/ components.MeshRenderer(engine)
export const MeshCollider: MeshColliderComponentDefinitionExtended = /* @__PURE__*/ components.MeshCollider(engine)
export const Name: NameComponent = /* @__PURE__*/ components.Name(engine)

// export components for global engine
export * from './components/generated/global.gen'
Expand Down
2 changes: 1 addition & 1 deletion packages/@dcl/ecs/src/runtime/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type { SystemFn } from '../engine/systems'
export type { SystemFn, SYSTEMS_REGULAR_PRIORITY } from '../engine/systems'
export type { TransportMessage, ReceiveMessage, Transport } from '../systems/crdt/types'
export { TransformType, TransformComponent } from '../components/manual/Transform'
export * from '../engine/component'
Expand Down
17 changes: 9 additions & 8 deletions packages/@dcl/inspector/src/components/Toolbar/Camera/Camera.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import './Camera.css'

export const Camera = withSdk(({ sdk }) => {
const [showPanel, setShowPanel] = useState(false)
const [freeCameraInvertRotation, setFreeCameraInvertRotation] = useState(sdk.preferences.data.freeCameraInvertRotation)
const [freeCameraInvertRotation, setFreeCameraInvertRotation] = useState(
sdk.preferences.data.freeCameraInvertRotation
)

const handleTogglePanel = useCallback(() => {setShowPanel(!showPanel)}, [showPanel])
const handleTogglePanel = useCallback(() => {
setShowPanel(!showPanel)
}, [showPanel])
const handleClosePanel = useCallback(() => setShowPanel(false), [])
const ref = useOutsideClick(handleClosePanel)

Expand All @@ -31,15 +35,12 @@ export const Camera = withSdk(({ sdk }) => {
</ToolbarButton>
<div className={cx('panel', { visible: showPanel })}>
<div className="axis">
<label>Invert rotation</label>
<FreeCameraInvertRotationIcon
className="icon"
onClick={handleToggleFreeCameraInvertRotation}
/>
<label>Invert rotation</label>
<FreeCameraInvertRotationIcon className="icon" onClick={handleToggleFreeCameraInvertRotation} />
</div>
</div>
</div>
)
})

export default Camera
export default Camera
11 changes: 2 additions & 9 deletions packages/@dcl/inspector/src/hooks/sdk/useComponentValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { recursiveCheck } from 'jest-matcher-deep-close-to/lib/recursiveCheck'

import { Component } from '../../lib/sdk/components'
import { useChange } from './useChange'
import { isEqual } from '../../lib/data-layer/host/utils/component'
import { useSdk } from './useSdk'

export function isLastWriteWinComponent<T = unknown>(
Expand All @@ -30,17 +29,11 @@ export const useComponentValue = <ComponentValueType>(entity: Entity, component:
// sync state -> engine
useEffect(() => {
if (value === null) return
const isEqualValue = isEqual(component, getComponentValue(entity, component), value)
const isEqualValue = !recursiveCheck(getComponentValue(entity, component), value, 2)

if (isEqualValue) {
return
}
const sameValue = !recursiveCheck(getComponentValue(entity, component), value, 2)
if (sameValue && !isEqualValue) {
console.log(
'TODO: maybe use this isEqual instead of the Uint8Array. Value is the same, but not for Uint8Array compare'
)
}
if (isLastWriteWinComponent(component) && sdk) {
sdk.operations.updateValue(component, entity, value!)
void sdk.operations.dispatch()
Expand Down Expand Up @@ -69,7 +62,7 @@ export const useComponentValue = <ComponentValueType>(entity: Entity, component:
)

function isComponentEqual(val: ComponentValueType) {
return isEqual(component, value, val)
return !recursiveCheck(getComponentValue(entity, component), val, 2)
}

return [value, setValue, isComponentEqual] as const
Expand Down
14 changes: 7 additions & 7 deletions packages/@dcl/inspector/src/hooks/sdk/useTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ export const useTree = () => {
if (sdk) {
const {
engine,
components: { EntityNode },
components: { Transform },
operations
} = sdk
return getTreeFromEngine(engine, operations, EntityNode)
return getTreeFromEngine(engine, operations, Transform)
} else {
return getEmptyTree()
}
Expand Down Expand Up @@ -52,8 +52,8 @@ export const useTree = () => {
(entity: Entity) => {
if (entity === ROOT) return 'Scene'
if (!sdk) return entity.toString()
const { EntityNode } = sdk.components
return EntityNode.has(entity) ? EntityNode.get(entity).label : entity.toString()
const { Name } = sdk.components
return Name.has(entity) ? Name.get(entity).value : entity.toString()
},
[sdk]
)
Expand Down Expand Up @@ -87,10 +87,10 @@ export const useTree = () => {
)

const rename = useCallback(
async (entity: Entity, label: string) => {
async (entity: Entity, value: string) => {
if (entity === ROOT || !sdk) return
const { EntityNode } = sdk.components
sdk.operations.updateValue(EntityNode, entity, { label })
const { Name } = sdk.components
sdk.operations.updateValue(Name, entity, { value })
await sdk.operations.dispatch()
handleUpdate()
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export class SceneContext {
MeshRenderer = components.MeshRenderer(this.engine)
GltfContainer = components.GltfContainer(this.engine)
TextShape = components.TextShape(this.engine)
Name = components.Name(this.engine)

readonly editorComponents = createEditorComponents(this.engine)

Expand Down Expand Up @@ -149,6 +150,7 @@ export class SceneContext {
}

async getFile(src: string): Promise<Uint8Array | null> {
if (!src) return null
gonpombo8 marked this conversation as resolved.
Show resolved Hide resolved
try {
const response = await this.dataLayer.getAssetData({ path: src })
return response.data
Expand Down
Loading