Add support for multiple instances

This commit is contained in:
Micah Allen 2018-11-04 12:06:06 -05:00
parent ab75af3697
commit 24d9313c99
2 changed files with 122 additions and 115 deletions

File diff suppressed because one or more lines are too long

View File

@ -8,31 +8,20 @@ const ERR_NOT_FOUND = 'PROCEDURE_NOT_FOUND';
const PROCESS_EVENT = '__rpc:process'; const PROCESS_EVENT = '__rpc:process';
const PROCEDURE_EXISTS = '__rpc:exists'; const PROCEDURE_EXISTS = '__rpc:exists';
const listeners = {}; const glob = environment === "cef" ? window : global;
const pending = {};
let passEventToBrowser, passEventToBrowsers; const init = !glob[PROCESS_EVENT];
if(environment === "client"){
passEventToBrowser = (browser, data) => {
const raw = util.stringifyData(data);
browser.execute(`var process = window["${PROCESS_EVENT}"]; if(process){ process('${raw}'); }else{ mp.trigger("${PROCESS_EVENT}", '{"ret":1,"id":"${data.id}","err":"${ERR_NOT_FOUND}"}'); }`);
};
passEventToBrowsers = (data) => { if(init){
mp.browsers.forEach(browser => passEventToBrowser(browser, data)); glob.__rpcListeners = {};
}; glob.__rpcPending = {};
}
async function callProcedure(name, args, info){ glob[PROCESS_EVENT] = (...args) => {
if(!listeners[name]) throw ERR_NOT_FOUND;
return listeners[name](args, info);
}
const processEvent = (...args) => {
let rawData = args[0]; let rawData = args[0];
if(environment === "server") rawData = args[1]; if(environment === "server") rawData = args[1];
const data = util.parseData(rawData); const data = util.parseData(rawData);
if(data.req){ // someone is trying to remotely call a procedure if(data.req){ // someone is trying to remotely call a procedure
const info = { const info = {
id: data.id, id: data.id,
@ -102,20 +91,52 @@ const processEvent = (...args) => {
} }
} }
}else if(data.ret){ // a previously called remote procedure has returned }else if(data.ret){ // a previously called remote procedure has returned
const info = pending[data.id]; const info = glob.__rpcPending[data.id];
if(info){ if(info){
if(data.err) info.reject(data.err); if(data.err) info.reject(data.err);
else info.resolve(data.res); else info.resolve(data.res);
pending[data.id] = undefined; glob.__rpcPending[data.id] = undefined;
} }
} }
}; };
if(environment === "cef"){ if(environment === "cef"){
window[PROCESS_EVENT] = processEvent; window[PROCEDURE_EXISTS] = name => !!glob.__rpcListeners[name];
window[PROCEDURE_EXISTS] = name => !!listeners[name]; }else{
}else{ mp.events.add(PROCESS_EVENT, glob[PROCESS_EVENT]);
mp.events.add(PROCESS_EVENT, processEvent);
if(environment === "client"){
// set up internal pass-through events
register('__rpc:callServer', ([name, args], info) => {
return _callServer(name, args, {
fenv: info.environment
});
});
register('__rpc:callBrowsers', ([name, args], info) => {
return _callBrowsers(name, args, null, {
fenv: info.environment
});
});
}
}
}
let passEventToBrowser, passEventToBrowsers;
if(environment === "client"){
passEventToBrowser = (browser, data) => {
const raw = util.stringifyData(data);
browser.execute(`var process = window["${PROCESS_EVENT}"]; if(process){ process('${raw}'); }else{ mp.trigger("${PROCESS_EVENT}", '{"ret":1,"id":"${data.id}","err":"${ERR_NOT_FOUND}"}'); }`);
};
passEventToBrowsers = (data) => {
mp.browsers.forEach(browser => passEventToBrowser(browser, data));
};
}
async function callProcedure(name, args, info){
const listener = glob.__rpcListeners[name];
if(!listener) throw ERR_NOT_FOUND;
return listener(args, info);
} }
/** /**
@ -125,7 +146,7 @@ if(environment === "cef"){
*/ */
export function register(name, cb){ export function register(name, cb){
if(arguments.length !== 2) throw 'register expects 2 arguments: "name" and "cb"'; if(arguments.length !== 2) throw 'register expects 2 arguments: "name" and "cb"';
listeners[name] = cb; glob.__rpcListeners[name] = cb;
} }
/** /**
@ -134,7 +155,7 @@ export function register(name, cb){
*/ */
export function unregister(name){ export function unregister(name){
if(arguments.length !== 1) throw 'unregister expects 1 argument: "name"'; if(arguments.length !== 1) throw 'unregister expects 1 argument: "name"';
listeners[name] = undefined; glob.__rpcListeners[name] = undefined;
} }
/** /**
@ -159,7 +180,7 @@ function _callServer(name, args, extraData){
case "client": { case "client": {
const id = util.uid(); const id = util.uid();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
pending[id] = { glob.__rpcPending[id] = {
resolve, resolve,
reject reject
}; };
@ -220,7 +241,7 @@ export function callClient(player, name, args){
if((arguments.length !== 2 && arguments.length !== 3) || typeof player !== "object") return Promise.reject('callClient from the server expects 2 or 3 arguments: "player", "name", and optional "args"'); if((arguments.length !== 2 && arguments.length !== 3) || typeof player !== "object") return Promise.reject('callClient from the server expects 2 or 3 arguments: "player", "name", and optional "args"');
const id = util.uid(); const id = util.uid();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
pending[id] = { glob.__rpcPending[id] = {
resolve, resolve,
reject reject
}; };
@ -239,7 +260,7 @@ export function callClient(player, name, args){
if((arguments.length !== 1 && arguments.length !== 2) || typeof name !== "string") return Promise.reject('callClient from the browser expects 1 or 2 arguments: "name" and optional "args"'); if((arguments.length !== 1 && arguments.length !== 2) || typeof name !== "string") return Promise.reject('callClient from the browser expects 1 or 2 arguments: "name" and optional "args"');
const id = util.uid(); const id = util.uid();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
pending[id] = { glob.__rpcPending[id] = {
resolve, resolve,
reject reject
}; };
@ -257,7 +278,7 @@ export function callClient(player, name, args){
function _callBrowser(id, browser, name, args, extraData){ function _callBrowser(id, browser, name, args, extraData){
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
pending[id] = { glob.__rpcPending[id] = {
resolve, resolve,
reject reject
}; };
@ -352,17 +373,3 @@ export function callBrowser(browser, name, args){
const id = util.uid(); const id = util.uid();
return _callBrowser(id, browser, name, args, {}); return _callBrowser(id, browser, name, args, {});
} }
// set up internal pass-through events
if(environment === "client"){
register('__rpc:callServer', ([name, args], info) => {
return _callServer(name, args, {
fenv: info.environment
});
});
register('__rpc:callBrowsers', ([name, args], info) => {
return _callBrowsers(name, args, null, {
fenv: info.environment
});
});
}