Skip to content

Commit 9fa5dc0

Browse files
authored
DevExp improvements (#950)
* Add pointer event collider checker Use width as a default value for UiEntities (useful for UiText) Fix React.JSX type * fix build * fix tests add warning & remove invalid sync components * fix uiComponent types * ignore check test * export types * fix build * fix componentid mutables
1 parent e3dda7a commit 9fa5dc0

File tree

12 files changed

+168
-26
lines changed

12 files changed

+168
-26
lines changed

packages/@dcl/ecs/src/runtime/initialization/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { createInputSystem, IInputSystem } from './../../engine/input'
1010
import { createRaycastSystem, RaycastSystem } from '../../systems/raycast'
1111
import { createVideoEventsSystem, VideoEventsSystem } from '../../systems/videoEvents'
1212
import { TweenSystem, createTweenSystem } from '../../systems/tween'
13+
import { pointerEventColliderChecker } from '../../systems/pointer-event-collider-checker'
1314

1415
/**
1516
* @public
@@ -64,6 +65,11 @@ export { VideoEventsSystem }
6465
export const tweenSystem: TweenSystem = createTweenSystem(engine)
6566
export { TweenSystem }
6667

68+
/**
69+
* Adds pointer event collider system only in DEV env
70+
*/
71+
pointerEventColliderChecker(engine)
72+
6773
/**
6874
* @public
6975
* Runs an async function

packages/@dcl/ecs/src/systems/events.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as components from '../components'
55
import { IEngine } from '../engine/types'
66
import { Entity, EntityState } from '../engine/entity'
77
import { IInputSystem } from '../engine/input'
8-
import { checkNotThenable } from '../runtime/invariant'
8+
import { __DEV__, checkNotThenable } from '../runtime/invariant'
99

1010
/**
1111
* @public
@@ -151,7 +151,6 @@ export function createPointerEventsSystem(engine: IEngine, inputSystem: IInputSy
151151
event.delete(type)
152152
}
153153

154-
// @internal
155154
engine.addSystem(function EventSystem() {
156155
for (const [entity, event] of eventsMap) {
157156
if (engine.getEntityState(entity) === EntityState.Removed) {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* istanbul ignore file */
2+
import * as components from '../components'
3+
import { Entity } from '../engine'
4+
import { IEngine } from '../engine/types'
5+
6+
/**
7+
* It checks all the entities that has a PointerEvent and check if it has a collider.
8+
* *
9+
* @public
10+
* @params engine
11+
*/
12+
export function pointerEventColliderChecker(engine: IEngine) {
13+
const PointerEvents = components.PointerEvents(engine)
14+
const MeshCollider = components.MeshCollider(engine)
15+
const GltfContainer = components.GltfContainer(engine)
16+
const UiTransform = components.UiTransform(engine)
17+
const alreadyShownlog = new Set<Entity>()
18+
let timer = 0
19+
function systemChecker(dt: number) {
20+
timer += dt
21+
if (timer <= 10) {
22+
return
23+
}
24+
timer = 0
25+
for (const [entity] of engine.getEntitiesWith(PointerEvents)) {
26+
if (alreadyShownlog.has(entity)) continue
27+
// Maybe the collider is inside the GLTFContainer. Ignore it
28+
if (GltfContainer.has(entity)) continue
29+
30+
// UI handles the pointer's in a diff way.
31+
if (UiTransform.has(entity)) continue
32+
33+
// check for Mesh Pointer Collision Layer
34+
const mesh = MeshCollider.getOrNull(entity)
35+
if (mesh) {
36+
if (mesh.collisionMask === undefined || mesh.collisionMask & components.ColliderLayer.CL_POINTER) {
37+
continue
38+
}
39+
}
40+
alreadyShownlog.add(entity)
41+
console.log(
42+
`⚠️ Missing MeshCollider component on entity ${entity}. Add a MeshCollider to the entity so it can be clickeable by the player.
43+
See https://docs.decentraland.org/creator/development-guide/sdk7/colliders/#pointer-blocking`
44+
)
45+
}
46+
}
47+
engine.removeSystem(systemChecker)
48+
engine.addSystem(systemChecker)
49+
}

packages/@dcl/playground-assets/etc/playground-assets.api.md

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ export const enum CameraType {
365365
// Warning: (ae-missing-release-tag) "Children" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
366366
//
367367
// @public (undocumented)
368-
export type Children = unknown;
368+
export type Children = ReactNode;
369369

370370
// @public (undocumented)
371371
export const enum ColliderLayer {
@@ -1012,7 +1012,7 @@ export const enum EasingFunction {
10121012
export interface EcsElements {
10131013
// (undocumented)
10141014
entity: Partial<EntityComponents> & {
1015-
children?: Children;
1015+
children?: ReactNode;
10161016
key?: Key;
10171017
};
10181018
}
@@ -1458,11 +1458,16 @@ export namespace JSX {
14581458
export interface Component {
14591459
}
14601460
// (undocumented)
1461-
export type Element = {} | null;
1461+
export interface Element extends ReactElement<any, any> {
1462+
}
14621463
// (undocumented)
1463-
export type IntrinsicElements = EcsElements;
1464+
export interface IntrinsicElements extends EcsElements {
1465+
}
14641466
}
14651467

1468+
// @public (undocumented)
1469+
export type JSXElementConstructor<P> = (props: P) => ReactElement<any, any> | null;
1470+
14661471
// @public (undocumented)
14671472
export type JustifyType = 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly';
14681473

@@ -3464,8 +3469,12 @@ export namespace ReactEcs {
34643469
export interface Component {
34653470
}
34663471
// (undocumented)
3467-
export type Element = {} | null;
3468-
export type IntrinsicElements = EcsElements;
3472+
export interface Element extends ReactElement<any, any> {
3473+
}
3474+
export interface IntrinsicElements extends EcsElements {
3475+
}
3476+
// (undocumented)
3477+
export type ReactNode = ReactElement | string | number | boolean | null | undefined;
34693478
}
34703479
const // (undocumented)
34713480
createElement: any;
@@ -3478,6 +3487,19 @@ export namespace ReactEcs {
34783487
// @public
34793488
export const ReactEcsRenderer: ReactBasedUiSystem;
34803489

3490+
// @public (undocumented)
3491+
export interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
3492+
// (undocumented)
3493+
key: Key | null;
3494+
// (undocumented)
3495+
props: P;
3496+
// (undocumented)
3497+
type: T;
3498+
}
3499+
3500+
// @public (undocumented)
3501+
export type ReactNode = ReactElement | string | number | boolean | null | undefined;
3502+
34813503
// @public (undocumented)
34823504
export type ReadonlyComponentSchema<T extends [ComponentDefinition<unknown>, ...ComponentDefinition<unknown>[]]> = {
34833505
[K in keyof T]: T[K] extends ComponentDefinition<unknown> ? ReturnType<T[K]['get']> : never;
@@ -3976,7 +3998,7 @@ export interface UiButtonProps extends UiLabelProps, EntityPropTypes {
39763998
export const UiCanvasInformation: LastWriteWinElementSetComponentDefinition<PBUiCanvasInformation>;
39773999

39784000
// @public (undocumented)
3979-
export type UiComponent = () => ReactEcs.JSX.Element;
4001+
export type UiComponent = () => ReactEcs.JSX.ReactNode;
39804002

39814003
// @public (undocumented)
39824004
export const UiDropdown: LastWriteWinElementSetComponentDefinition<PBUiDropdown>;

packages/@dcl/react-ecs/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"directory": "packages/@dcl/react-ecs"
3131
},
3232
"scripts": {
33-
"build": "tsc -p tsconfig.json"
33+
"build": "tsc -p tsconfig.json",
34+
"start": "tsc -p tsconfig.json --watch"
3435
},
3536
"typedoc": {
3637
"entryPoint": "./src/index.ts",

packages/@dcl/react-ecs/src/components/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ReactNode } from '../react-ecs'
12
import { Listeners } from './listeners/types'
23
import { UiBackgroundProps } from './uiBackground/types'
34
import { UiTransformProps } from './uiTransform/types'
@@ -21,7 +22,7 @@ export interface EntityPropTypes extends Listeners {
2122
* @public
2223
*/
2324
export type Key = number | string
24-
export type Children = unknown
25+
export type Children = ReactNode
2526

2627
/**
2728
* unit value type. i.e. 'vw' || 'vh'

packages/@dcl/react-ecs/src/components/uiTransform/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const defaultUiTransform: PBUiTransform = {
7474
positionTop: 0,
7575
positionTopUnit: YGUnit.YGU_UNDEFINED,
7676
flexBasisUnit: YGUnit.YGU_UNDEFINED,
77-
widthUnit: YGUnit.YGU_UNDEFINED,
77+
widthUnit: YGUnit.YGU_AUTO,
7878
heightUnit: YGUnit.YGU_UNDEFINED,
7979
pointerFilter: PointerFilterMode.PFM_NONE
8080
}

packages/@dcl/react-ecs/src/react-ecs.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/* eslint-disable @typescript-eslint/no-empty-interface */
22
import { PBUiBackground, PBUiText, PBUiTransform, PBUiInput, PBUiDropdown } from '@dcl/ecs'
33
import React from 'react'
4-
import { Callback, Children, Key } from './components'
4+
import { Callback, Key } from './components'
55

66
/**
77
* @public
88
*/
99
export interface EcsElements {
10-
entity: Partial<EntityComponents> & { children?: Children; key?: Key }
10+
entity: Partial<EntityComponents> & { children?: ReactNode; key?: Key }
1111
}
1212

1313
/**
@@ -27,12 +27,31 @@ export type EntityComponents = {
2727
* @hidden
2828
*/
2929
export namespace JSX {
30-
// eslint-disable-next-line @typescript-eslint/ban-types
31-
export type Element = {} | null
32-
export type IntrinsicElements = EcsElements
30+
export interface Element extends ReactElement<any, any> {}
31+
export interface IntrinsicElements extends EcsElements {}
3332
export interface Component {}
3433
}
34+
/**
35+
* @public
36+
*/
37+
export type JSXElementConstructor<P> = (props: P) => ReactElement<any, any> | null
38+
39+
/**
40+
* @public
41+
*/
42+
export interface ReactElement<
43+
P = any,
44+
T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>
45+
> {
46+
type: T
47+
props: P
48+
key: Key | null
49+
}
3550

51+
/**
52+
* @public
53+
*/
54+
export type ReactNode = ReactElement | string | number | boolean | null | undefined
3655
/**
3756
* @public
3857
*/
@@ -41,13 +60,16 @@ export namespace ReactEcs {
4160
/**
4261
* @public
4362
*/
44-
// eslint-disable-next-line @typescript-eslint/ban-types
45-
export type Element = {} | null
63+
export type ReactNode = ReactElement | string | number | boolean | null | undefined
64+
/**
65+
* @public
66+
*/
67+
export interface Element extends ReactElement<any, any> {}
4668
/**
4769
* @public
4870
* HTML tag elements
4971
*/
50-
export type IntrinsicElements = EcsElements
72+
export interface IntrinsicElements extends EcsElements {}
5173
/**
5274
* @public
5375
* Component empty interface

packages/@dcl/react-ecs/src/reconciler/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ export function createReconciler(
351351
}
352352

353353
return {
354-
update: function (component: ReactEcs.JSX.Element) {
354+
update: function (component: ReactEcs.JSX.ReactNode) {
355355
if (changeEvents.size) {
356356
handleOnChange(UiInput.componentId, UiInputResult)
357357
handleOnChange(UiDropdown.componentId, UiDropdownResult)

packages/@dcl/react-ecs/src/system.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { createReconciler } from './reconciler'
66
/**
77
* @public
88
*/
9-
export type UiComponent = () => ReactEcs.JSX.Element
9+
export type UiComponent = () => ReactEcs.JSX.ReactNode
1010

1111
/**
1212
* @public

0 commit comments

Comments
 (0)