Skip to content
Closed
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
13 changes: 6 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"bugs": "https://github.com/decentraland/js-sdk-toolchain/issues",
"dependencies": {
"@actions/core": "^1.10.0",
"@dcl/protocol": "1.0.0-30862383737.commit-36e5967",
"@dcl/protocol": "https://sdk-team-cdn.decentraland.org/@dcl/protocol/branch//dcl-protocol-1.0.0-30917362428.commit-788564b.tgz",
"@dcl/quickjs-emscripten": "^0.21.0-3680274614.commit-1808aa1",
"@dcl/ts-proto": "1.153.0",
"@types/fs-extra": "^9.0.12",
Expand Down
1 change: 1 addition & 0 deletions packages/@dcl/ecs/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { cyclicParentingChecker } from './systems/cyclicParentingChecker'
export * from './systems/events'
export * from './systems/raycast'
export * from './systems/videoEvents'
export * from './systems/audioEvents'
export * from './systems/assetLoad'
export * from './systems/async-task'
export * from './systems/tween'
Expand Down
8 changes: 8 additions & 0 deletions packages/@dcl/ecs/src/runtime/initialization/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createPointerEventsSystem, PointerEventsSystem } from '../../systems/ev
import { createInputSystem, IInputSystem } from './../../engine/input'
import { createRaycastSystem, RaycastSystem } from '../../systems/raycast'
import { createVideoEventsSystem, VideoEventsSystem } from '../../systems/videoEvents'
import { createAudioEventsSystem, AudioEventsSystem } from '../../systems/audioEvents'
import { createAssetLoadLoadingStateSystem, AssetLoadLoadingStateSystem } from '../../systems/assetLoad'
import { TweenSystem, createTweenSystem } from '../../systems/tween'
import { pointerEventColliderChecker } from '../../systems/pointer-event-collider-checker'
Expand Down Expand Up @@ -63,6 +64,13 @@ export { RaycastSystem }
export const videoEventsSystem: VideoEventsSystem = /* @__PURE__ */ createVideoEventsSystem(engine)
export { VideoEventsSystem }

/**
* @public
* Register callback functions to a particular entity on audio events.
*/
export const audioEventsSystem: AudioEventsSystem = /* @__PURE__ */ createAudioEventsSystem(engine)
export { AudioEventsSystem }

/**
* @public
* Register callback functions to a particular entity on asset pre-load events.
Expand Down
101 changes: 101 additions & 0 deletions packages/@dcl/ecs/src/systems/audioEvents.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import * as components from '../components'
import { DeepReadonlyObject, Entity, IEngine } from '../engine'
import { PBAudioEvent } from '../components'
import { EntityState } from '../engine/entity'

/**
* @public
*/
export type AudioEventsSystemCallback = (event: DeepReadonlyObject<PBAudioEvent>) => void

/**
* @public
*/
export interface AudioEventsSystem {
removeAudioEventsEntity(entity: Entity): void

registerAudioEventsEntity(entity: Entity, callback: AudioEventsSystemCallback): void

hasAudioEventsEntity(entity: Entity): boolean

/**
* Returns the latest state of the AudioEvent
* @param entity - Entity to retrieve the audio status
*/
getAudioState(entity: Entity): DeepReadonlyObject<PBAudioEvent> | undefined
}

/**
* @internal
*/
export function createAudioEventsSystem(engine: IEngine): AudioEventsSystem {
const audioSourceComponent = components.AudioSource(engine)
const audioStreamComponent = components.AudioStream(engine)
const audioEventComponent = components.AudioEvent(engine)
const entitiesCallbackAudioStateMap = new Map<
Entity,
{
callback: AudioEventsSystemCallback
lastAudioState?: number
}
>()

function registerAudioEventsEntity(entity: Entity, callback: AudioEventsSystemCallback) {
// audio event component is not added here because the renderer adds it
// to every entity with an AudioSource or AudioStream component
entitiesCallbackAudioStateMap.set(entity, { callback: callback })
}

function removeAudioEventsEntity(entity: Entity) {
entitiesCallbackAudioStateMap.delete(entity)
}

function hasAudioEventsEntity(entity: Entity) {
return entitiesCallbackAudioStateMap.has(entity)
}

// @internal
engine.addSystem(function EventSystem() {
for (const [entity, data] of entitiesCallbackAudioStateMap) {
const hasAudioSource = audioSourceComponent.has(entity)
const hasAudioStream = audioStreamComponent.has(entity)
if (engine.getEntityState(entity) === EntityState.Removed || (!hasAudioSource && !hasAudioStream)) {
removeAudioEventsEntity(entity)
continue
}

// Compare with last state
const audioEvent = audioEventComponent.get(entity)
const values = Array.from(audioEvent.values())
const lastValue = values[audioEvent.size - 1]

if (lastValue === undefined || (data.lastAudioState !== undefined && data.lastAudioState === lastValue.state))
continue

data.callback(lastValue)

entitiesCallbackAudioStateMap.set(entity, {
callback: data.callback,
lastAudioState: lastValue.state
})
}
})

return {
removeAudioEventsEntity(entity: Entity) {
removeAudioEventsEntity(entity)
},
registerAudioEventsEntity(entity: Entity, callback: AudioEventsSystemCallback) {
registerAudioEventsEntity(entity, callback)
},
hasAudioEventsEntity(entity: Entity) {
return hasAudioEventsEntity(entity)
},
getAudioState(entity: Entity) {
const audioEvent = audioEventComponent.get(entity)
const values = Array.from(audioEvent.values())
const lastValue = values[audioEvent.size - 1]
return lastValue
}
}
}
25 changes: 25 additions & 0 deletions packages/@dcl/playground-assets/etc/playground-assets.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ export type AudioAnalysisView = {
// @public (undocumented)
export const AudioEvent: GrowOnlyValueSetComponentDefinition<PBAudioEvent>;

// @public (undocumented)
export interface AudioEventsSystem {
getAudioState(entity: Entity): DeepReadonlyObject<PBAudioEvent> | undefined;
// (undocumented)
hasAudioEventsEntity(entity: Entity): boolean;
// (undocumented)
registerAudioEventsEntity(entity: Entity, callback: AudioEventsSystemCallback): void;
// (undocumented)
removeAudioEventsEntity(entity: Entity): void;
}

// @public
export const audioEventsSystem: AudioEventsSystem;

// @public (undocumented)
export type AudioEventsSystemCallback = (event: DeepReadonlyObject<PBAudioEvent>) => void;

// Warning: (ae-missing-release-tag) "AudioSource" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
Expand Down Expand Up @@ -1163,6 +1180,13 @@ export interface EcsElements {
};
}

// @public (undocumented)
export const enum EmoteState {
ES_FINISHED = 1,
ES_INTERRUPTED = 2,
ES_STARTED = 0
}

// @public @deprecated
export function Engine(options?: IEngineOptions): IEngine;

Expand Down Expand Up @@ -2549,6 +2573,7 @@ export interface PBAvatarEmoteCommand {
loop: boolean;
// (undocumented)
mask?: AvatarMask | undefined;
state?: EmoteState | undefined;
timestamp: number;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/@dcl/sdk-commands/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/@dcl/sdk-commands/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@dcl/inspector": "7.36.3",
"@dcl/linker-dapp": "0.15.2",
"@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be",
"@dcl/protocol": "1.0.0-30862383737.commit-36e5967",
"@dcl/protocol": "https://sdk-team-cdn.decentraland.org/@dcl/protocol/branch//dcl-protocol-1.0.0-30917362428.commit-788564b.tgz",
"@dcl/quests-client": "^1.0.3",
"@dcl/quests-manager": "^0.1.4",
"@dcl/rpc": "^1.1.1",
Expand Down
29 changes: 26 additions & 3 deletions test/ecs/components/AvatarEmoteCommand.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AvatarMask, Engine, components } from '../../../packages/@dcl/ecs/src'
import { AvatarMask, EmoteState, Engine, components } from '../../../packages/@dcl/ecs/src'
import { testSchemaSerializationIdentity } from './assertion'

describe('Generated AvatarEmoteCommand ProtoBuf', () => {
Expand All @@ -10,13 +10,36 @@ describe('Generated AvatarEmoteCommand ProtoBuf', () => {
emoteUrn: 'boedo',
loop: false,
timestamp: 1,
mask: undefined
mask: undefined,
state: undefined
})
testSchemaSerializationIdentity(AvatarEmoteCommand.schema, {
emoteUrn: 'boedo',
loop: false,
timestamp: 1,
mask: AvatarMask.AM_UPPER_BODY
mask: AvatarMask.AM_UPPER_BODY,
state: undefined
})
testSchemaSerializationIdentity(AvatarEmoteCommand.schema, {
emoteUrn: 'boedo',
loop: false,
timestamp: 1,
mask: AvatarMask.AM_UPPER_BODY,
state: EmoteState.ES_STARTED
})
testSchemaSerializationIdentity(AvatarEmoteCommand.schema, {
emoteUrn: 'boedo',
loop: false,
timestamp: 1,
mask: undefined,
state: EmoteState.ES_FINISHED
})
testSchemaSerializationIdentity(AvatarEmoteCommand.schema, {
emoteUrn: 'boedo',
loop: false,
timestamp: 1,
mask: undefined,
state: EmoteState.ES_INTERRUPTED
})
})
})
Loading
Loading