workadventure/front/src/Api/iframe/room.ts

150 lines
4.8 KiB
TypeScript
Raw Normal View History

import { Subject } from "rxjs";
2021-06-23 20:19:38 +02:00
import { isDataLayerEvent } from "../Events/DataLayerEvent";
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
import { isGameStateEvent } from "../Events/GameStateEvent";
import { IframeApiContribution, sendToWorkadventure } from "./IframeApiContribution";
import { apiCallback } from "./registeredCallbacks";
2021-06-23 20:19:38 +02:00
import type { ITiledMap } from "../../Phaser/Map/ITiledMap";
import type { DataLayerEvent } from "../Events/DataLayerEvent";
import type { GameStateEvent } from "../Events/GameStateEvent";
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
2021-06-23 11:32:11 +02:00
const dataLayerResolver = new Subject<DataLayerEvent>();
const stateResolvers = new Subject<GameStateEvent>();
2021-06-23 20:19:38 +02:00
let immutableDataPromise: Promise<GameStateEvent> | undefined = undefined;
2021-06-23 11:32:11 +02:00
interface Room {
2021-06-23 20:19:38 +02:00
id: string;
mapUrl: string;
map: ITiledMap;
startLayer: string | null;
2021-06-23 11:32:11 +02:00
}
interface User {
2021-06-23 20:19:38 +02:00
id: string | undefined;
nickName: string | null;
tags: string[];
2021-06-23 11:32:11 +02:00
}
interface TileDescriptor {
x: number
y: number
tile: number | string
layer: string
}
2021-06-23 11:32:11 +02:00
function getGameState(): Promise<GameStateEvent> {
2021-06-23 20:19:38 +02:00
if (immutableDataPromise === undefined) {
immutableDataPromise = new Promise<GameStateEvent>((resolver, thrower) => {
2021-06-23 11:32:11 +02:00
stateResolvers.subscribe(resolver);
2021-06-23 20:19:38 +02:00
sendToWorkadventure({ type: "getState", data: null });
});
2021-06-23 11:32:11 +02:00
}
2021-06-23 20:19:38 +02:00
return immutableDataPromise;
2021-06-23 11:32:11 +02:00
}
function getDataLayer(): Promise<DataLayerEvent> {
return new Promise<DataLayerEvent>((resolver, thrower) => {
dataLayerResolver.subscribe(resolver);
2021-06-23 20:19:38 +02:00
sendToWorkadventure({ type: "getDataLayer", data: null });
});
2021-06-23 11:32:11 +02:00
}
class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomCommands> {
callbacks = [
apiCallback({
callback: (payloadData: EnterLeaveEvent) => {
enterStreams.get(payloadData.name)?.next();
},
type: "enterEvent",
2021-06-23 20:19:38 +02:00
typeChecker: isEnterLeaveEvent,
}),
apiCallback({
type: "leaveEvent",
typeChecker: isEnterLeaveEvent,
callback: (payloadData) => {
leaveStreams.get(payloadData.name)?.next();
2021-06-23 20:19:38 +02:00
},
2021-06-23 11:32:11 +02:00
}),
apiCallback({
type: "gameState",
typeChecker: isGameStateEvent,
callback: (payloadData) => {
stateResolvers.next(payloadData);
2021-06-23 20:19:38 +02:00
},
2021-06-23 11:32:11 +02:00
}),
apiCallback({
type: "dataLayer",
typeChecker: isDataLayerEvent,
callback: (payloadData) => {
dataLayerResolver.next(payloadData);
2021-06-23 20:19:38 +02:00
},
2021-06-23 11:32:11 +02:00
}),
2021-06-23 20:19:38 +02:00
];
onEnterZone(name: string, callback: () => void): void {
let subject = enterStreams.get(name);
if (subject === undefined) {
subject = new Subject<EnterLeaveEvent>();
enterStreams.set(name, subject);
}
subject.subscribe(callback);
}
onLeaveZone(name: string, callback: () => void): void {
let subject = leaveStreams.get(name);
if (subject === undefined) {
subject = new Subject<EnterLeaveEvent>();
leaveStreams.set(name, subject);
}
subject.subscribe(callback);
}
2021-06-23 11:32:11 +02:00
showLayer(layerName: string): void {
2021-06-23 20:19:38 +02:00
sendToWorkadventure({ type: "showLayer", data: { name: layerName } });
2021-06-23 11:32:11 +02:00
}
hideLayer(layerName: string): void {
2021-06-23 20:19:38 +02:00
sendToWorkadventure({ type: "hideLayer", data: { name: layerName } });
2021-06-23 11:32:11 +02:00
}
setProperty(layerName: string, propertyName: string, propertyValue: string | number | boolean | undefined): void {
sendToWorkadventure({
2021-06-23 20:19:38 +02:00
type: "setProperty",
2021-06-23 11:32:11 +02:00
data: {
2021-06-23 20:19:38 +02:00
layerName: layerName,
propertyName: propertyName,
propertyValue: propertyValue,
},
});
2021-06-23 11:32:11 +02:00
}
getCurrentRoom(): Promise<Room> {
return getGameState().then((gameState) => {
2021-06-23 20:19:38 +02:00
return getDataLayer().then((mapJson) => {
return {
id: gameState.roomId,
map: mapJson.data as ITiledMap,
mapUrl: gameState.mapUrl,
startLayer: gameState.startLayerName,
};
});
});
2021-06-23 11:32:11 +02:00
}
getCurrentUser(): Promise<User> {
return getGameState().then((gameState) => {
2021-06-23 20:19:38 +02:00
return { id: gameState.uuid, nickName: gameState.nickname, tags: gameState.tags };
});
2021-06-23 11:32:11 +02:00
}
changeTile(tiles: TileDescriptor[]) {
sendToWorkadventure({
type: 'changeTile',
data: tiles
})
}
}
export default new WorkadventureRoomCommands();