Switching setVariable to a query and fixing error hangling in query mechanism
This commit is contained in:
parent
c30de8c6db
commit
bf17ad4567
@ -50,7 +50,6 @@ export type IframeEventMap = {
|
|||||||
getState: undefined;
|
getState: undefined;
|
||||||
registerMenuCommand: MenuItemRegisterEvent;
|
registerMenuCommand: MenuItemRegisterEvent;
|
||||||
setTiles: SetTilesEvent;
|
setTiles: SetTilesEvent;
|
||||||
setVariable: SetVariableEvent;
|
|
||||||
};
|
};
|
||||||
export interface IframeEvent<T extends keyof IframeEventMap> {
|
export interface IframeEvent<T extends keyof IframeEventMap> {
|
||||||
type: T;
|
type: T;
|
||||||
@ -93,6 +92,10 @@ export type IframeQueryMap = {
|
|||||||
query: undefined,
|
query: undefined,
|
||||||
answer: MapDataEvent,
|
answer: MapDataEvent,
|
||||||
},
|
},
|
||||||
|
setVariable: {
|
||||||
|
query: SetVariableEvent,
|
||||||
|
answer: void
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IframeQuery<T extends keyof IframeQueryMap> {
|
export interface IframeQuery<T extends keyof IframeQueryMap> {
|
||||||
|
@ -105,9 +105,6 @@ class IframeListener {
|
|||||||
private readonly _setTilesStream: Subject<SetTilesEvent> = new Subject();
|
private readonly _setTilesStream: Subject<SetTilesEvent> = new Subject();
|
||||||
public readonly setTilesStream = this._setTilesStream.asObservable();
|
public readonly setTilesStream = this._setTilesStream.asObservable();
|
||||||
|
|
||||||
private readonly _setVariableStream: Subject<SetVariableEvent> = new Subject();
|
|
||||||
public readonly setVariableStream = this._setVariableStream.asObservable();
|
|
||||||
|
|
||||||
private readonly iframes = new Set<HTMLIFrameElement>();
|
private readonly iframes = new Set<HTMLIFrameElement>();
|
||||||
private readonly iframeCloseCallbacks = new Map<HTMLIFrameElement, (() => void)[]>();
|
private readonly iframeCloseCallbacks = new Map<HTMLIFrameElement, (() => void)[]>();
|
||||||
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
||||||
@ -171,13 +168,7 @@ class IframeListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.resolve(answerer(query.data)).then((value) => {
|
const errorHandler = (reason: any) => {
|
||||||
iframe?.contentWindow?.postMessage({
|
|
||||||
id: queryId,
|
|
||||||
type: query.type,
|
|
||||||
data: value
|
|
||||||
}, '*');
|
|
||||||
}).catch(reason => {
|
|
||||||
console.error('An error occurred while responding to an iFrame query.', reason);
|
console.error('An error occurred while responding to an iFrame query.', reason);
|
||||||
let reasonMsg: string;
|
let reasonMsg: string;
|
||||||
if (reason instanceof Error) {
|
if (reason instanceof Error) {
|
||||||
@ -191,8 +182,31 @@ class IframeListener {
|
|||||||
type: query.type,
|
type: query.type,
|
||||||
error: reasonMsg
|
error: reasonMsg
|
||||||
} as IframeErrorAnswerEvent, '*');
|
} as IframeErrorAnswerEvent, '*');
|
||||||
});
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
Promise.resolve(answerer(query.data)).then((value) => {
|
||||||
|
iframe?.contentWindow?.postMessage({
|
||||||
|
id: queryId,
|
||||||
|
type: query.type,
|
||||||
|
data: value
|
||||||
|
}, '*');
|
||||||
|
}).catch(errorHandler);
|
||||||
|
} catch (reason) {
|
||||||
|
errorHandler(reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSetVariableIframeEvent(payload.query)) {
|
||||||
|
// Let's dispatch the message to the other iframes
|
||||||
|
for (iframe of this.iframes) {
|
||||||
|
if (iframe.contentWindow !== message.source) {
|
||||||
|
iframe.contentWindow?.postMessage({
|
||||||
|
'type': 'setVariable',
|
||||||
|
'data': payload.query.data
|
||||||
|
}, '*');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (isIframeEventWrapper(payload)) {
|
} else if (isIframeEventWrapper(payload)) {
|
||||||
if (payload.type === "showLayer" && isLayerEvent(payload.data)) {
|
if (payload.type === "showLayer" && isLayerEvent(payload.data)) {
|
||||||
this._showLayerStream.next(payload.data);
|
this._showLayerStream.next(payload.data);
|
||||||
@ -246,18 +260,6 @@ class IframeListener {
|
|||||||
handleMenuItemRegistrationEvent(payload.data);
|
handleMenuItemRegistrationEvent(payload.data);
|
||||||
} else if (payload.type == "setTiles" && isSetTilesEvent(payload.data)) {
|
} else if (payload.type == "setTiles" && isSetTilesEvent(payload.data)) {
|
||||||
this._setTilesStream.next(payload.data);
|
this._setTilesStream.next(payload.data);
|
||||||
} else if (isSetVariableIframeEvent(payload)) {
|
|
||||||
this._setVariableStream.next(payload.data);
|
|
||||||
|
|
||||||
// Let's dispatch the message to the other iframes
|
|
||||||
for (iframe of this.iframes) {
|
|
||||||
if (iframe.contentWindow !== message.source) {
|
|
||||||
iframe.contentWindow?.postMessage({
|
|
||||||
'type': 'setVariable',
|
|
||||||
'data': payload.data
|
|
||||||
}, '*');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -119,9 +119,9 @@ export class WorkadventureRoomCommands extends IframeApiContribution<Workadventu
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
saveVariable(key : string, value : unknown): void {
|
saveVariable(key : string, value : unknown): Promise<void> {
|
||||||
variables.set(key, value);
|
variables.set(key, value);
|
||||||
sendToWorkadventure({
|
return queryWorkadventure({
|
||||||
type: 'setVariable',
|
type: 'setVariable',
|
||||||
data: {
|
data: {
|
||||||
key,
|
key,
|
||||||
|
@ -14,7 +14,6 @@ interface Variable {
|
|||||||
|
|
||||||
export class SharedVariablesManager {
|
export class SharedVariablesManager {
|
||||||
private _variables = new Map<string, unknown>();
|
private _variables = new Map<string, unknown>();
|
||||||
private iframeListenerSubscription: Subscription;
|
|
||||||
private variableObjects: Map<string, Variable>;
|
private variableObjects: Map<string, Variable>;
|
||||||
|
|
||||||
constructor(private roomConnection: RoomConnection, private gameMap: GameMap) {
|
constructor(private roomConnection: RoomConnection, private gameMap: GameMap) {
|
||||||
@ -28,7 +27,7 @@ export class SharedVariablesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// When a variable is modified from an iFrame
|
// When a variable is modified from an iFrame
|
||||||
this.iframeListenerSubscription = iframeListener.setVariableStream.subscribe((event) => {
|
iframeListener.registerAnswerer('setVariable', (event) => {
|
||||||
const key = event.key;
|
const key = event.key;
|
||||||
|
|
||||||
if (!this.variableObjects.has(key)) {
|
if (!this.variableObjects.has(key)) {
|
||||||
@ -75,7 +74,7 @@ export class SharedVariablesManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public close(): void {
|
public close(): void {
|
||||||
this.iframeListenerSubscription.unsubscribe();
|
iframeListener.unregisterAnswerer('setVariable');
|
||||||
}
|
}
|
||||||
|
|
||||||
get variables(): Map<string, unknown> {
|
get variables(): Map<string, unknown> {
|
||||||
|
@ -192,7 +192,18 @@ window.addEventListener(
|
|||||||
|
|
||||||
console.debug(payload);
|
console.debug(payload);
|
||||||
|
|
||||||
if (isIframeAnswerEvent(payload)) {
|
if (isIframeErrorAnswerEvent(payload)) {
|
||||||
|
const queryId = payload.id;
|
||||||
|
const payloadError = payload.error;
|
||||||
|
|
||||||
|
const resolver = answerPromises.get(queryId);
|
||||||
|
if (resolver === undefined) {
|
||||||
|
throw new Error('In Iframe API, got an error answer for a question that we have no track of.');
|
||||||
|
}
|
||||||
|
resolver.reject(new Error(payloadError));
|
||||||
|
|
||||||
|
answerPromises.delete(queryId);
|
||||||
|
} else if (isIframeAnswerEvent(payload)) {
|
||||||
const queryId = payload.id;
|
const queryId = payload.id;
|
||||||
const payloadData = payload.data;
|
const payloadData = payload.data;
|
||||||
|
|
||||||
@ -202,17 +213,6 @@ window.addEventListener(
|
|||||||
}
|
}
|
||||||
resolver.resolve(payloadData);
|
resolver.resolve(payloadData);
|
||||||
|
|
||||||
answerPromises.delete(queryId);
|
|
||||||
} else if (isIframeErrorAnswerEvent(payload)) {
|
|
||||||
const queryId = payload.id;
|
|
||||||
const payloadError = payload.error;
|
|
||||||
|
|
||||||
const resolver = answerPromises.get(queryId);
|
|
||||||
if (resolver === undefined) {
|
|
||||||
throw new Error('In Iframe API, got an error answer for a question that we have no track of.');
|
|
||||||
}
|
|
||||||
resolver.reject(payloadError);
|
|
||||||
|
|
||||||
answerPromises.delete(queryId);
|
answerPromises.delete(queryId);
|
||||||
} else if (isIframeResponseEventWrapper(payload)) {
|
} else if (isIframeResponseEventWrapper(payload)) {
|
||||||
const payloadData = payload.data;
|
const payloadData = payload.data;
|
||||||
|
@ -2,8 +2,10 @@ WA.onInit().then(() => {
|
|||||||
console.log('Trying to read variable "doorOpened" whose default property is true. This should display "true".');
|
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.room.loadVariable('doorOpened'));
|
||||||
|
|
||||||
console.log('Trying to set variable "not_exists". This should display an error in the console.')
|
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');
|
WA.room.saveVariable('not_exists', 'foo').catch((e) => {
|
||||||
|
console.log('Successfully caught error: ', e);
|
||||||
|
});
|
||||||
|
|
||||||
console.log('Trying to set variable "config". This should work.');
|
console.log('Trying to set variable "config". This should work.');
|
||||||
WA.room.saveVariable('config', {'foo': 'bar'});
|
WA.room.saveVariable('config', {'foo': 'bar'});
|
||||||
|
Loading…
Reference in New Issue
Block a user