Skip to content

Commit

Permalink
add AudioEvent component (#926)
Browse files Browse the repository at this point in the history
* add AudioEvent component

* add 'getAudioState' helper for AudioStream component

* fix comments
  • Loading branch information
nicoecheza authored Apr 15, 2024
1 parent 0048266 commit f417f2c
Show file tree
Hide file tree
Showing 12 changed files with 169 additions and 19 deletions.
14 changes: 7 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-8299166777.commit-9493ffe",
"@dcl/protocol": "^1.0.0-8691799990.commit-4ba546c",
"@dcl/quickjs-emscripten": "^0.21.0-3680274614.commit-1808aa1",
"@dcl/ts-proto": "1.153.0",
"@types/fs-extra": "^9.0.12",
Expand Down
39 changes: 39 additions & 0 deletions packages/@dcl/ecs/src/components/extended/AudioStream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Entity, IEngine } from '../../engine'
import { LastWriteWinElementSetComponentDefinition } from '../../engine/component'
import { AudioStream, PBAudioEvent, AudioEvent as defineAudioEventComponent } from '../generated/index.gen'
import { PBAudioStream } from '../generated/pb/decentraland/sdk/components/audio_stream.gen'

/**
* @public
*/
export interface AudioStreamComponentDefinitionExtended
extends LastWriteWinElementSetComponentDefinition<PBAudioStream> {
/**
* @public
*
* Set playing=true the sound `$name`
* @param entity - entity with AudioStream component
* @param src - the path to the sound to play
* @param resetCursor - the sound starts at 0 or continues from the current cursor position
* @returns true in successful playing, false if it doesn't find the AudioStream component
*/
getAudioState(entity: Entity): PBAudioEvent | undefined
}

export function defineAudioStreamComponent(
engine: Pick<IEngine, 'defineComponentFromSchema' | 'defineValueSetComponentFromSchema'>
): AudioStreamComponentDefinitionExtended {
const theComponent = AudioStream(engine)
const AudioEvent = defineAudioEventComponent(engine)

return {
...theComponent,
getAudioState(entity: Entity) {
const AudioStream = theComponent.getMutableOrNull(entity)
if (!AudioStream || !AudioEvent.has(entity)) return undefined

const lastEvent = Array.from(AudioEvent.get(entity)).pop()
return lastEvent
}
}
}
9 changes: 9 additions & 0 deletions packages/@dcl/ecs/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import defineSyncComponent, { ISyncComponentsType } from './manual/SyncComponent
import defineNetworkEntity, { INetowrkEntityType } from './manual/NetworkEntity'
import defineNetworkParent, { INetowrkParentType } from './manual/NetworkParent'
import { defineTransformComponent, TransformComponentExtended } from './manual/Transform'
import { AudioStreamComponentDefinitionExtended, defineAudioStreamComponent } from './extended/AudioStream'
import { MediaState } from './generated/pb/decentraland/sdk/components/common/media_state.gen'

export * from './generated/index.gen'

Expand All @@ -37,6 +39,11 @@ export const Animator: LwwComponentGetter<AnimatorComponentDefinitionExtended> =
export const AudioSource: LwwComponentGetter<AudioSourceComponentDefinitionExtended> = (engine) =>
defineAudioSourceComponent(engine)

/* @__PURE__ */
export const AudioStream: (
engine: Pick<IEngine, 'defineComponentFromSchema' | 'defineValueSetComponentFromSchema'>
) => AudioStreamComponentDefinitionExtended = (engine) => defineAudioStreamComponent(engine)

/* @__PURE__ */
export const MeshRenderer: LwwComponentGetter<MeshRendererComponentDefinitionExtended> = (engine) =>
defineMeshRendererComponent(engine)
Expand Down Expand Up @@ -79,3 +86,5 @@ export const NetworkEntity: (
export const NetworkParent: (
engine: Pick<IEngine, 'defineComponent'>
) => LastWriteWinElementSetComponentDefinition<INetowrkParentType> = (engine) => defineNetworkParent(engine)

export { MediaState }
1 change: 1 addition & 0 deletions packages/@dcl/ecs/src/components/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export type { AnimatorComponentDefinitionExtended } from './extended/Animator'
export type { AudioSourceComponentDefinitionExtended } from './extended/AudioSource'
export type { AudioStreamComponentDefinitionExtended } from './extended/AudioStream'
export type { MeshRendererComponentDefinitionExtended } from './extended/MeshRenderer'
export type { MeshColliderComponentDefinitionExtended } from './extended/MeshCollider'
export type { TextureHelper, MaterialComponentDefinitionExtended } from './extended/Material'
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 @@ -27,6 +27,7 @@ import {
TransformComponentExtended,
AnimatorComponentDefinitionExtended,
AudioSourceComponentDefinitionExtended,
AudioStreamComponentDefinitionExtended,
ISyncComponents,
TweenComponentDefinitionExtended,
INetowrkEntity,
Expand All @@ -38,6 +39,7 @@ import { NameComponent } from './components/manual/Name'
export const Transform: TransformComponentExtended = /* @__PURE__*/ components.Transform(engine)
export const Animator: AnimatorComponentDefinitionExtended = /* @__PURE__*/ components.Animator(engine)
export const AudioSource: AudioSourceComponentDefinitionExtended = /* @__PURE__*/ components.AudioSource(engine)
export const AudioStream: AudioStreamComponentDefinitionExtended = /* @__PURE__*/ components.AudioStream(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)
Expand Down
48 changes: 47 additions & 1 deletion packages/@dcl/playground-assets/etc/playground-assets.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export namespace AppendValueOperation {
// @public
export function areConnected(parcels: Coords[]): boolean;

// @public (undocumented)
export const AudioEvent: GrowOnlyValueSetComponentDefinition<PBAudioEvent>;

// 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 All @@ -61,8 +64,15 @@ export interface AudioSourceComponentDefinitionExtended extends LastWriteWinElem
stopSound(entity: Entity, resetCursor?: boolean): boolean;
}

// Warning: (ae-missing-release-tag) "AudioStream" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
export const AudioStream: LastWriteWinElementSetComponentDefinition<PBAudioStream>;
export const AudioStream: AudioStreamComponentDefinitionExtended;

// @public (undocumented)
export interface AudioStreamComponentDefinitionExtended extends LastWriteWinElementSetComponentDefinition<PBAudioStream> {
getAudioState(entity: Entity): PBAudioEvent | undefined;
}

// @public (undocumented)
export const enum AvatarAnchorPointType {
Expand Down Expand Up @@ -529,6 +539,7 @@ export type ComponentDefinition<T> = LastWriteWinElementSetComponentDefinition<T
// @public
export const componentDefinitionByName: {
"core::Animator": LwwComponentGetter<LastWriteWinElementSetComponentDefinition<PBAnimator>>;
"core::AudioEvent": GSetComponentGetter<GrowOnlyValueSetComponentDefinition<PBAudioEvent>>;
"core::AudioSource": LwwComponentGetter<LastWriteWinElementSetComponentDefinition<PBAudioSource>>;
"core::AudioStream": LwwComponentGetter<LastWriteWinElementSetComponentDefinition<PBAudioStream>>;
"core::AvatarAttach": LwwComponentGetter<LastWriteWinElementSetComponentDefinition<PBAvatarAttach>>;
Expand Down Expand Up @@ -1787,6 +1798,26 @@ export namespace Matrix {
export function Zero(): MutableMatrix;
}

// @public (undocumented)
export const enum MediaState {
// (undocumented)
MS_BUFFERING = 5,
// (undocumented)
MS_ERROR = 1,
// (undocumented)
MS_LOADING = 2,
// (undocumented)
MS_NONE = 0,
// (undocumented)
MS_PAUSED = 7,
// (undocumented)
MS_PLAYING = 4,
// (undocumented)
MS_READY = 3,
// (undocumented)
MS_SEEKING = 6
}

// Warning: (ae-missing-release-tag) "MeshCollider" 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 @@ -2080,6 +2111,21 @@ export namespace PBAnimator {
export function encode(message: PBAnimator, writer?: _m0.Writer): _m0.Writer;
}

// @public (undocumented)
export interface PBAudioEvent {
// (undocumented)
state: MediaState;
timestamp: number;
}

// @public (undocumented)
export namespace PBAudioEvent {
// (undocumented)
export function decode(input: _m0.Reader | Uint8Array, length?: number): PBAudioEvent;
// (undocumented)
export function encode(message: PBAudioEvent, writer?: _m0.Writer): _m0.Writer;
}

// @public (undocumented)
export interface PBAudioSource {
audioClipUrl: string;
Expand Down
14 changes: 7 additions & 7 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 @@ -13,7 +13,7 @@
"@dcl/inspector": "file:../inspector",
"@dcl/linker-dapp": "^0.12.0",
"@dcl/mini-comms": "1.0.1-20230216163137.commit-a4c75be",
"@dcl/protocol": "1.0.0-8299166777.commit-9493ffe",
"@dcl/protocol": "^1.0.0-8691799990.commit-4ba546c",
"@dcl/quests-client": "^1.0.3",
"@dcl/quests-manager": "^0.1.4",
"@dcl/rpc": "^1.1.1",
Expand Down
2 changes: 1 addition & 1 deletion scripts/protocol-buffer-generation/generateIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function exportComponent(component: Component) {
return `export * from './pb/decentraland/sdk/components/${component.componentFile}.gen'`
}

const GROWN_ONLY_COMPONENTS = ['PointerEventsResult', 'VideoEvent', 'AvatarEmoteCommand']
const GROWN_ONLY_COMPONENTS = ['PointerEventsResult', 'VideoEvent', 'AvatarEmoteCommand', 'AudioEvent']
function isGrowOnlyValueSet(component: Component): boolean {
return GROWN_ONLY_COMPONENTS.includes(component.componentPascalName)
}
Expand Down
26 changes: 26 additions & 0 deletions test/ecs/components/AudioEvent.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { components, Engine, MediaState } from '../../../packages/@dcl/ecs/src'
import { testSchemaSerializationIdentity } from './assertion'

describe('Generated AudioEvent ProtoBuf', () => {
it('should serialize', () => {
const newEngine = Engine()
const AudioEvent = components.AudioEvent(newEngine)

testSchemaSerializationIdentity(AudioEvent.schema, {
timestamp: 5,
state: MediaState.MS_LOADING
})

testSchemaSerializationIdentity(AudioEvent.schema, {
timestamp: 10,
state: MediaState.MS_PLAYING
})

testSchemaSerializationIdentity(AudioEvent.schema, {
timestamp: 30,
state: MediaState.MS_PLAYING
})

testSchemaSerializationIdentity(AudioEvent.schema, AudioEvent.schema.create())
})
})
29 changes: 28 additions & 1 deletion test/ecs/components/AudioStream.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Engine, components } from '../../../packages/@dcl/ecs/src'
import { MediaState, Engine, components } from '../../../packages/@dcl/ecs/src'
import { testComponentSerialization } from './assertion'

describe('Generated AudioStream ProtoBuf', () => {
Expand All @@ -18,4 +18,31 @@ describe('Generated AudioStream ProtoBuf', () => {
url: 'FakeUrl2'
})
})

it('should AudioStream.getAudioState helper return current stream state', () => {
const newEngine = Engine()
const AudioStream = components.AudioStream(newEngine)
const AudioEvent = components.AudioEvent(newEngine)
const entity = newEngine.addEntity()
const entityWithoutAudioStream = newEngine.addEntity()

AudioStream.create(entity, {
url: 'some-src',
playing: true
})

// entity without AudioStream
expect(AudioStream.getAudioState(entityWithoutAudioStream)).toBe(undefined)

// entity with AudioStream without AudioEvents
expect(AudioStream.getAudioState(entity)).toBe(undefined)

// add some states
AudioEvent.addValue(entity, { state: MediaState.MS_BUFFERING, timestamp: 1 })
AudioEvent.addValue(entity, { state: MediaState.MS_ERROR, timestamp: 2 })
AudioEvent.addValue(entity, { state: MediaState.MS_PLAYING, timestamp: 3 })

// get last state
expect(AudioStream.getAudioState(entity)).toStrictEqual({ state: MediaState.MS_PLAYING, timestamp: 3 })
})
})

0 comments on commit f417f2c

Please sign in to comment.