Migrating variables functions to the "state" namespace.
This commit is contained in:
parent
e65e8b2097
commit
b1cb12861f
16
CHANGELOG.md
16
CHANGELOG.md
@ -8,14 +8,24 @@
|
||||
- Migrated the admin console to Svelte, and redesigned the console #1211
|
||||
- Layer properties (like `exitUrl`, `silent`, etc...) can now also used in tile properties #1210 (@jonnytest1)
|
||||
- New scripting API features :
|
||||
- Use `WA.onInit(): Promise<void>` to wait for scripting API initialization
|
||||
- Use `WA.room.showLayer(): void` to show a layer
|
||||
- Use `WA.room.hideLayer(): void` to hide a layer
|
||||
- Use `WA.room.setProperty() : void` to add or change existing property of a layer
|
||||
- Use `WA.player.onPlayerMove(): void` to track the movement of the current player
|
||||
- Use `WA.room.getCurrentUser(): Promise<User>` to get the ID, name and tags of the current player
|
||||
- Use `WA.room.getCurrentRoom(): Promise<Room>` to get the ID, JSON map file, url of the map of the current room and the layer where the current player started
|
||||
- Use `WA.ui.registerMenuCommand(): void` to add a custom menu
|
||||
- Use `WA.player.id: string|undefined` to get the ID of the current player
|
||||
- Use `WA.player.name: string` to get the name of the current player
|
||||
- Use `WA.player.tags: string[]` to get the tags of the current player
|
||||
- Use `WA.room.id: string` to get the ID of the room
|
||||
- Use `WA.room.mapURL: string` to get the URL of the map
|
||||
- Use `WA.room.mapURL: string` to get the URL of the map
|
||||
- Use `WA.room.getMap(): Promise<ITiledMap>` to get the JSON map file
|
||||
- Use `WA.room.setTiles(): void` to change an array of tiles
|
||||
- Use `WA.ui.registerMenuCommand(): void` to add a custom menu
|
||||
- Use `WA.state.loadVariable(key: string): unknown` to retrieve a variable
|
||||
- Use `WA.state.saveVariable(key: string, value: unknown): Promise<void>` to set a variable (across the room, for all users)
|
||||
- Use `WA.state.onVariableChange(key: string): Subscription<unknown>` to track a variable
|
||||
- Use `WA.state.[any variable]: unknown` to access directly any variable (this is a shortcut to using `WA.state.loadVariable` and `WA.state.saveVariable`)
|
||||
- Users blocking now relies on UUID rather than ID. A blocked user that leaves a room and comes back will stay blocked.
|
||||
|
||||
## Version 1.4.3 - 1.4.4 - 1.4.5
|
||||
|
@ -4,15 +4,11 @@ import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
||||
|
||||
import {IframeApiContribution, queryWorkadventure, sendToWorkadventure} from "./IframeApiContribution";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import {isSetVariableEvent, SetVariableEvent} from "../Events/SetVariableEvent";
|
||||
|
||||
import type { ITiledMap } from "../../Phaser/Map/ITiledMap";
|
||||
|
||||
const enterStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||
const leaveStreams: Map<string, Subject<EnterLeaveEvent>> = new Map<string, Subject<EnterLeaveEvent>>();
|
||||
const setVariableResolvers = new Subject<SetVariableEvent>();
|
||||
const variables = new Map<string, unknown>();
|
||||
const variableSubscribers = new Map<string, Subject<unknown>>();
|
||||
|
||||
interface TileDescriptor {
|
||||
x: number;
|
||||
@ -33,24 +29,6 @@ export const setMapURL = (url: string) => {
|
||||
mapURL = url;
|
||||
}
|
||||
|
||||
export const initVariables = (_variables: Map<string, unknown>): void => {
|
||||
for (const [name, value] of _variables.entries()) {
|
||||
// In case the user already decided to put values in the variables (before onInit), let's make sure onInit does not override this.
|
||||
if (!variables.has(name)) {
|
||||
variables.set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setVariableResolvers.subscribe((event) => {
|
||||
variables.set(event.key, event.value);
|
||||
const subject = variableSubscribers.get(event.key);
|
||||
if (subject !== undefined) {
|
||||
subject.next(event.value);
|
||||
}
|
||||
});
|
||||
|
||||
export class WorkadventureRoomCommands extends IframeApiContribution<WorkadventureRoomCommands> {
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
@ -67,13 +45,6 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
||||
leaveStreams.get(payloadData.name)?.next();
|
||||
},
|
||||
}),
|
||||
apiCallback({
|
||||
type: "setVariable",
|
||||
typeChecker: isSetVariableEvent,
|
||||
callback: (payloadData) => {
|
||||
setVariableResolvers.next(payloadData);
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
onEnterZone(name: string, callback: () => void): void {
|
||||
@ -119,31 +90,6 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
||||
});
|
||||
}
|
||||
|
||||
saveVariable(key : string, value : unknown): Promise<void> {
|
||||
variables.set(key, value);
|
||||
return queryWorkadventure({
|
||||
type: 'setVariable',
|
||||
data: {
|
||||
key,
|
||||
value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
loadVariable(key: string): unknown {
|
||||
return variables.get(key);
|
||||
}
|
||||
|
||||
onVariableChange(key: string): Observable<unknown> {
|
||||
let subject = variableSubscribers.get(key);
|
||||
if (subject === undefined) {
|
||||
subject = new Subject<unknown>();
|
||||
variableSubscribers.set(key, subject);
|
||||
}
|
||||
return subject.asObservable();
|
||||
}
|
||||
|
||||
|
||||
get id() : string {
|
||||
if (roomId === undefined) {
|
||||
throw new Error('Room id not initialized yet. You should call WA.room.id within a WA.onInit callback.');
|
||||
|
85
front/src/Api/iframe/state.ts
Normal file
85
front/src/Api/iframe/state.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import {Observable, Subject} from "rxjs";
|
||||
|
||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "../Events/EnterLeaveEvent";
|
||||
|
||||
import {IframeApiContribution, queryWorkadventure, sendToWorkadventure} from "./IframeApiContribution";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import {isSetVariableEvent, SetVariableEvent} from "../Events/SetVariableEvent";
|
||||
|
||||
import type { ITiledMap } from "../../Phaser/Map/ITiledMap";
|
||||
|
||||
const setVariableResolvers = new Subject<SetVariableEvent>();
|
||||
const variables = new Map<string, unknown>();
|
||||
const variableSubscribers = new Map<string, Subject<unknown>>();
|
||||
|
||||
export const initVariables = (_variables: Map<string, unknown>): void => {
|
||||
for (const [name, value] of _variables.entries()) {
|
||||
// In case the user already decided to put values in the variables (before onInit), let's make sure onInit does not override this.
|
||||
if (!variables.has(name)) {
|
||||
variables.set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setVariableResolvers.subscribe((event) => {
|
||||
variables.set(event.key, event.value);
|
||||
const subject = variableSubscribers.get(event.key);
|
||||
if (subject !== undefined) {
|
||||
subject.next(event.value);
|
||||
}
|
||||
});
|
||||
|
||||
export class WorkadventureStateCommands extends IframeApiContribution<WorkadventureStateCommands> {
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "setVariable",
|
||||
typeChecker: isSetVariableEvent,
|
||||
callback: (payloadData) => {
|
||||
setVariableResolvers.next(payloadData);
|
||||
}
|
||||
}),
|
||||
];
|
||||
|
||||
saveVariable(key : string, value : unknown): Promise<void> {
|
||||
variables.set(key, value);
|
||||
return queryWorkadventure({
|
||||
type: 'setVariable',
|
||||
data: {
|
||||
key,
|
||||
value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
loadVariable(key: string): unknown {
|
||||
return variables.get(key);
|
||||
}
|
||||
|
||||
onVariableChange(key: string): Observable<unknown> {
|
||||
let subject = variableSubscribers.get(key);
|
||||
if (subject === undefined) {
|
||||
subject = new Subject<unknown>();
|
||||
variableSubscribers.set(key, subject);
|
||||
}
|
||||
return subject.asObservable();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const proxyCommand = new Proxy(new WorkadventureStateCommands(), {
|
||||
get(target: WorkadventureStateCommands, p: PropertyKey, receiver: unknown): unknown {
|
||||
if (p in target) {
|
||||
return Reflect.get(target, p, receiver);
|
||||
}
|
||||
return target.loadVariable(p.toString());
|
||||
},
|
||||
set(target: WorkadventureStateCommands, p: PropertyKey, value: unknown, receiver: unknown): boolean {
|
||||
// Note: when using "set", there is no way to wait, so we ignore the return of the promise.
|
||||
// User must use WA.state.saveVariable to have error message.
|
||||
target.saveVariable(p.toString(), value);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
export default proxyCommand;
|
@ -177,7 +177,6 @@ export class RoomConnection implements RoomConnection {
|
||||
}
|
||||
}
|
||||
} else if (message.hasRoomjoinedmessage()) {
|
||||
console.error('COUCOU')
|
||||
const roomJoinedMessage = message.getRoomjoinedmessage() as RoomJoinedMessage;
|
||||
|
||||
const items: { [itemId: number]: unknown } = {};
|
||||
|
@ -11,7 +11,8 @@ import nav from "./Api/iframe/nav";
|
||||
import controls from "./Api/iframe/controls";
|
||||
import ui from "./Api/iframe/ui";
|
||||
import sound from "./Api/iframe/sound";
|
||||
import room, {initVariables, setMapURL, setRoomId} from "./Api/iframe/room";
|
||||
import room, {setMapURL, setRoomId} from "./Api/iframe/room";
|
||||
import state, {initVariables} from "./Api/iframe/state";
|
||||
import player, {setPlayerName, setTags, setUuid} from "./Api/iframe/player";
|
||||
import type { ButtonDescriptor } from "./Api/iframe/Ui/ButtonDescriptor";
|
||||
import type { Popup } from "./Api/iframe/Ui/Popup";
|
||||
@ -42,6 +43,7 @@ const wa = {
|
||||
sound,
|
||||
room,
|
||||
player,
|
||||
state,
|
||||
|
||||
onInit(): Promise<void> {
|
||||
return initPromise;
|
||||
|
@ -1,20 +1,26 @@
|
||||
WA.onInit().then(() => {
|
||||
console.log('Trying to read variable "doorOpened" whose default property is true. This should display "true".');
|
||||
console.log('doorOpened', WA.room.loadVariable('doorOpened'));
|
||||
console.log('doorOpened', WA.state.loadVariable('doorOpened'));
|
||||
|
||||
console.log('Trying to set variable "not_exists". This should display an error in the console, followed by a log saying the error was caught.')
|
||||
WA.room.saveVariable('not_exists', 'foo').catch((e) => {
|
||||
WA.state.saveVariable('not_exists', 'foo').catch((e) => {
|
||||
console.log('Successfully caught error: ', e);
|
||||
});
|
||||
|
||||
console.log('Trying to set variable "myvar". This should work.');
|
||||
WA.room.saveVariable('myvar', {'foo': 'bar'});
|
||||
WA.state.saveVariable('myvar', {'foo': 'bar'});
|
||||
|
||||
console.log('Trying to read variable "myvar". This should display a {"foo": "bar"} object.');
|
||||
console.log(WA.room.loadVariable('myvar'));
|
||||
console.log(WA.state.loadVariable('myvar'));
|
||||
|
||||
console.log('Trying to set variable "myvar" using proxy. This should work.');
|
||||
WA.state.myvar = {'baz': 42};
|
||||
|
||||
console.log('Trying to read variable "myvar" using proxy. This should display a {"baz": 42} object.');
|
||||
console.log(WA.state.myvar);
|
||||
|
||||
console.log('Trying to set variable "config". This should not work because we are not logged as admin.');
|
||||
WA.room.saveVariable('config', {'foo': 'bar'}).catch(e => {
|
||||
WA.state.saveVariable('config', {'foo': 'bar'}).catch(e => {
|
||||
console.log('Successfully caught error because variable "config" is not writable: ', e);
|
||||
});
|
||||
});
|
||||
|
@ -12,21 +12,21 @@
|
||||
WA.onInit().then(() => {
|
||||
console.log('After WA init');
|
||||
const textField = document.getElementById('textField');
|
||||
textField.value = WA.room.loadVariable('textField');
|
||||
textField.value = WA.state.loadVariable('textField');
|
||||
|
||||
textField.addEventListener('change', function (evt) {
|
||||
console.log('saving variable')
|
||||
WA.room.saveVariable('textField', this.value);
|
||||
WA.state.saveVariable('textField', this.value);
|
||||
});
|
||||
|
||||
WA.room.onVariableChange('textField').subscribe((value) => {
|
||||
WA.state.onVariableChange('textField').subscribe((value) => {
|
||||
console.log('variable changed received')
|
||||
textField.value = value;
|
||||
});
|
||||
|
||||
document.getElementById('btn').addEventListener('click', () => {
|
||||
console.log(WA.room.loadVariable('textField'));
|
||||
document.getElementById('placeholder').innerText = WA.room.loadVariable('textField');
|
||||
console.log(WA.state.loadVariable('textField'));
|
||||
document.getElementById('placeholder').innerText = WA.state.loadVariable('textField');
|
||||
});
|
||||
});
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user