Creates player state and uses it to get and set values from local storage
This commit is contained in:
parent
89cd292527
commit
bf69b55e99
10 changed files with 153 additions and 159 deletions
|
@ -3,7 +3,7 @@ import type { HasPlayerMovedEvent, HasPlayerMovedEventCallback } from "../Events
|
|||
import { Subject } from "rxjs";
|
||||
import { apiCallback } from "./registeredCallbacks";
|
||||
import { isHasPlayerMovedEvent } from "../Events/HasPlayerMovedEvent";
|
||||
import type { PlayerPropertyEvent } from "../Events/PlayerPropertyEvent";
|
||||
import { createState } from "./state";
|
||||
|
||||
const moveStream = new Subject<HasPlayerMovedEvent>();
|
||||
|
||||
|
@ -26,6 +26,8 @@ export const setUuid = (_uuid: string | undefined) => {
|
|||
};
|
||||
|
||||
export class WorkadventurePlayerCommands extends IframeApiContribution<WorkadventurePlayerCommands> {
|
||||
readonly state = createState("player");
|
||||
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "hasPlayerMoved",
|
||||
|
@ -68,20 +70,6 @@ export class WorkadventurePlayerCommands extends IframeApiContribution<Workadven
|
|||
}
|
||||
return uuid;
|
||||
}
|
||||
|
||||
getPlayerProperty(name: string): Promise<PlayerPropertyEvent> {
|
||||
return queryWorkadventure({
|
||||
type: "getPlayerProperty",
|
||||
data: name,
|
||||
});
|
||||
}
|
||||
|
||||
setPlayerProperty(property: PlayerPropertyEvent) {
|
||||
queryWorkadventure({
|
||||
type: "setPlayerProperty",
|
||||
data: property,
|
||||
}).catch((e) => console.error(e));
|
||||
}
|
||||
}
|
||||
|
||||
export default new WorkadventurePlayerCommands();
|
||||
|
|
|
@ -8,93 +8,101 @@ 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) => {
|
||||
const oldValue = variables.get(event.key);
|
||||
// If we are setting the same value, no need to do anything.
|
||||
// No need to do this check since it is already performed in SharedVariablesManager
|
||||
/*if (JSON.stringify(oldValue) === JSON.stringify(event.value)) {
|
||||
return;
|
||||
}*/
|
||||
|
||||
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> {
|
||||
private setVariableResolvers = new Subject<SetVariableEvent>();
|
||||
private variables = new Map<string, unknown>();
|
||||
private variableSubscribers = new Map<string, Subject<unknown>>();
|
||||
|
||||
constructor(private target: "global" | "player") {
|
||||
super();
|
||||
|
||||
this.setVariableResolvers.subscribe((event) => {
|
||||
const oldValue = this.variables.get(event.key);
|
||||
// If we are setting the same value, no need to do anything.
|
||||
// No need to do this check since it is already performed in SharedVariablesManager
|
||||
/*if (JSON.stringify(oldValue) === JSON.stringify(event.value)) {
|
||||
return;
|
||||
}*/
|
||||
|
||||
this.variables.set(event.key, event.value);
|
||||
const subject = this.variableSubscribers.get(event.key);
|
||||
if (subject !== undefined) {
|
||||
subject.next(event.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
callbacks = [
|
||||
apiCallback({
|
||||
type: "setVariable",
|
||||
typeChecker: isSetVariableEvent,
|
||||
callback: (payloadData) => {
|
||||
setVariableResolvers.next(payloadData);
|
||||
if (payloadData.target === this.target) {
|
||||
this.setVariableResolvers.next(payloadData);
|
||||
}
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
||||
// TODO: see how we can remove this method from types exposed to WA.state object
|
||||
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 (!this.variables.has(name)) {
|
||||
this.variables.set(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveVariable(key: string, value: unknown): Promise<void> {
|
||||
variables.set(key, value);
|
||||
this.variables.set(key, value);
|
||||
return queryWorkadventure({
|
||||
type: "setVariable",
|
||||
data: {
|
||||
key,
|
||||
value,
|
||||
target: this.target,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
loadVariable(key: string): unknown {
|
||||
return variables.get(key);
|
||||
return this.variables.get(key);
|
||||
}
|
||||
|
||||
hasVariable(key: string): boolean {
|
||||
return variables.has(key);
|
||||
return this.variables.has(key);
|
||||
}
|
||||
|
||||
onVariableChange(key: string): Observable<unknown> {
|
||||
let subject = variableSubscribers.get(key);
|
||||
let subject = this.variableSubscribers.get(key);
|
||||
if (subject === undefined) {
|
||||
subject = new Subject<unknown>();
|
||||
variableSubscribers.set(key, subject);
|
||||
this.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;
|
||||
},
|
||||
has(target: WorkadventureStateCommands, p: PropertyKey): boolean {
|
||||
if (p in target) {
|
||||
export function createState(target: "global" | "player"): WorkadventureStateCommands & { [key: string]: unknown } {
|
||||
return new Proxy(new WorkadventureStateCommands(target), {
|
||||
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;
|
||||
}
|
||||
return target.hasVariable(p.toString());
|
||||
},
|
||||
}) as WorkadventureStateCommands & { [key: string]: unknown };
|
||||
|
||||
export default proxyCommand;
|
||||
},
|
||||
has(target: WorkadventureStateCommands, p: PropertyKey): boolean {
|
||||
if (p in target) {
|
||||
return true;
|
||||
}
|
||||
return target.hasVariable(p.toString());
|
||||
},
|
||||
}) as WorkadventureStateCommands & { [key: string]: unknown };
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue