updated approach to deps, mod loading, main entrypoints

This commit is contained in:
Stewart Allen 2022-02-20 12:56:43 -05:00
commit 19522665b2
21 changed files with 299 additions and 321 deletions

28
app.js
View file

@ -54,7 +54,7 @@ function init(mod) {
let depcache = {}; let depcache = {};
function find_deps(path, seen = []) { function find_deps(path, seen = [], uses = []) {
let cached = depcache[path]; let cached = depcache[path];
if (cached) { if (cached) {
return cached; return cached;
@ -71,13 +71,21 @@ function init(mod) {
.toString() .toString()
.split('\n'); .split('\n');
for (let line of lines) { for (let line of lines) {
let upos = line.indexOf('// use:');
if (upos >= 0) {
let use = line.substring(upos + 7).trim().replace('.','/');
if (uses.indexOf(use) < 0) {
uses.push(use);
}
continue;
}
let dpos = line.indexOf('// dep:'); let dpos = line.indexOf('// dep:');
if (dpos >= 0) { if (dpos >= 0) {
let dep = line.substring(dpos+7).trim().replace('.','/'); let dep = line.substring(dpos + 7).trim().replace('.','/');
if (deps.indexOf(dep) < 0) { if (deps.indexOf(dep) < 0) {
deps.push(dep); deps.push(dep);
} }
let deep = find_deps(dep, seen); let deep = find_deps(dep, seen, uses);
deps = deps.filter(p => deep.indexOf(p) < 0); deps = deps.filter(p => deep.indexOf(p) < 0);
// deeper dependencies go first // deeper dependencies go first
deps = [...deep, ...deps]; deps = [...deep, ...deps];
@ -91,6 +99,7 @@ function init(mod) {
for (let [key,val] of Object.entries(script)) { for (let [key,val] of Object.entries(script)) {
let nval = val.map(p => p.charAt(0) === '&' ? p.substring(1) : p); let nval = val.map(p => p.charAt(0) === '&' ? p.substring(1) : p);
let modd = false; let modd = false;
let uses = [];
for (let path of val) { for (let path of val) {
let fc = path.charAt(0); let fc = path.charAt(0);
if (fc === '@') { if (fc === '@') {
@ -101,7 +110,16 @@ function init(mod) {
} else { } else {
continue; continue;
} }
let deps = find_deps(path); let uses = [];
let deps = find_deps(path, [], uses);
if (uses.length) {
let miss = uses.filter(u => deps.indexOf(u) < 0);
if (miss.length) {
val.appendAll(miss);
}
// console.log({key, uses, miss, deps});
deps.appendAll(miss);
}
if (deps) { if (deps) {
// remove deps already in list // remove deps already in list
deps = deps.filter(p => nval.indexOf(p) < 0); deps = deps.filter(p => nval.indexOf(p) < 0);
@ -110,7 +128,7 @@ function init(mod) {
throw `missing ${path} in nval`; throw `missing ${path} in nval`;
} }
// inject deps // inject deps
nval.splice(ppos,0,...deps); nval.splice(ppos, 0, ...deps);
modd = true; modd = true;
} }
// if list is modified, substitute // if list is modified, substitute

View file

@ -20,7 +20,7 @@
LOCAL = self.debug && !SETUP.remote, LOCAL = self.debug && !SETUP.remote,
EVENT = kiri.broker = gapp.broker, EVENT = kiri.broker = gapp.broker,
SDB = data.local, SDB = data.local,
SPACE = kiri.space = moto.Space, SPACE = kiri.space = moto.space,
FILES = kiri.catalog = kiri.openFiles(new data.Index(SETUP.d ? SETUP.d[0] : 'kiri')), FILES = kiri.catalog = kiri.openFiles(new data.Index(SETUP.d ? SETUP.d[0] : 'kiri')),
CONF = kiri.conf, CONF = kiri.conf,
clone = Object.clone; clone = Object.clone;

View file

@ -62,6 +62,8 @@ if (gapp.load) return;
let mods = []; let mods = [];
let modn = {}; let modn = {};
gapp.overlay = Object.assign;
// register module without a load function // register module without a load function
gapp.register = (name, deps, fn) => { gapp.register = (name, deps, fn) => {
gapp.load(undefined, name, deps); gapp.load(undefined, name, deps);
@ -70,14 +72,19 @@ gapp.register = (name, deps, fn) => {
let root = self; let root = self;
let map = toks.pop(); let map = toks.pop();
for (let tok of toks) { for (let tok of toks) {
root = root[tok]; if (!root[tok]) {
if (!root) { dbug.debug({creating_root: tok, for: name});
console.log({missing_root: tok, at: name});
root = root[tok] = {}; root = root[tok] = {};
} else {
root = root[tok];
} }
} }
map = root[map] = root[map] || {}; let tmp = root[map] || {};
fn(self, exports => Object.assign(map, exports)); fn(self, exports => {
if (exports) {
return root[map] = Object.assign(tmp, exports);
}
});
} }
}; };
@ -101,13 +108,15 @@ gapp.check = (name, deps = []) => {
}; };
// perform dependency checks and run module load functions // perform dependency checks and run module load functions
gapp.finalize = (app, deps) => { gapp.main = (app, deps, fn) => {
// app loader may also pass deps // app loader may also pass deps
gapp.check(app, deps); gapp.check(app, deps);
// load mods after checking if dependency is present // load mods after checking if dependency is present
for (let mod of mods) { for (let mod of mods) {
let { fn, name, deps } = mod; let { fn, name, deps } = mod;
gapp.check(name, deps); if (deps) {
gapp.check(name, deps);
}
// mods with no name can't be depended on, but are allowed // mods with no name can't be depended on, but are allowed
if (name) { if (name) {
dbug.debug(`${app} | load | ${name}`); dbug.debug(`${app} | load | ${name}`);
@ -117,9 +126,10 @@ gapp.finalize = (app, deps) => {
mod.fn(); mod.fn();
} }
} }
// produces an error if finalize is called twice // force runtime error if gapp.load() called gapp.main()
// or if load is called after finalize
mods = null; mods = null;
// optional if not called inline with startup
if (fn) fn(self);
}; };
})(); })();

View file

@ -2,23 +2,34 @@
"use strict"; "use strict";
(function() { // dep: moto.license
// dep: moto.webui
// dep: moto.client
// dep: moto.broker
// dep: moto.space
// dep: data.index
// dep: mesh.api
// dep: mesh.model
// dep: mesh.build
// dep: load.file
gapp.main("main.mesh", [], (root) => {
let broker = gapp.broker; const { Quaternion, Mesh, MeshPhongMaterial, PlaneGeometry, DoubleSide } = THREE;
let call = broker.send; const { broker } = gapp;
let dbindex = [ "admin", "space" ]; const { moto } = root;
let { Quaternion, Mesh, MeshPhongMaterial, PlaneGeometry, DoubleSide } = THREE; const { space } = moto;
const call = broker.send;
const dbindex = [ "admin", "space" ];
// set below. called once the DOM readyState = complete // set below. called once the DOM readyState = complete
// this is the main() entrypoint called after all dependents load // this is the main() entrypoint called after all dependents load
function init() { function init() {
let stores = data.open('mesh', { stores: dbindex, version: 4 }).init(), let stores = data.open('mesh', { stores: dbindex, version: 4 }).init(),
moto = self.moto,
dark = false, dark = false,
ortho = false, ortho = false,
zoomrev = true, zoomrev = true,
zoomspd = 1, zoomspd = 1,
space = moto.Space,
platform = space.platform, platform = space.platform,
db = mesh.db = { db = mesh.db = {
admin: stores.promise('admin'), admin: stores.promise('admin'),
@ -75,7 +86,7 @@ function init() {
function restore_space() { function restore_space() {
let { api } = mesh; let { api } = mesh;
let count = 0; let count = 0;
let space = moto.Space; let space = moto.space;
let mcache = {}; let mcache = {};
mesh.db.admin.get("camera") mesh.db.admin.get("camera")
.then(saved => { .then(saved => {
@ -142,7 +153,7 @@ let temp_mode;
// split functions // split functions
let split = { let split = {
start() { start() {
let space = moto.Space; let space = moto.space;
let { api, util } = mesh; let { api, util } = mesh;
// highlight button // highlight button
let button = event.target; let button = event.target;
@ -215,7 +226,7 @@ let split = {
}, },
end() { end() {
let space = moto.Space; let space = moto.space;
let { button, obj } = split.state; let { button, obj } = split.state;
button.classList.remove('selected'); button.classList.remove('selected');
space.scene.remove(obj); space.scene.remove(obj);
@ -484,7 +495,7 @@ function object_destroy(id) {
// listen for changes like dark mode toggle // listen for changes like dark mode toggle
function set_darkmode(dark) { function set_darkmode(dark) {
let { prefs, selection, model } = mesh.api; let { prefs, selection, model } = mesh.api;
let { sky, platform } = moto.Space; let { sky, platform } = moto.space;
prefs.map.space.dark = dark; prefs.map.space.dark = dark;
if (dark) { if (dark) {
mesh.material.wireframe.color.set(0xaaaaaa); mesh.material.wireframe.color.set(0xaaaaaa);
@ -535,18 +546,4 @@ document.onreadystatechange = function() {
} }
} }
// finalize modules });
gapp.finalize("main.mesh", [
"moto.license", // dep: moto.license
"moto.webui", // dep: moto.webui
"moto.client", // dep: moto.client
"moto.broker", // dep: moto.broker
"moto.space", // dep: moto.space
"data.index", // dep: data.index
"mesh.api", // dep: mesh.api
"mesh.model", // dep: mesh.model
"mesh.build", // dep: mesh.build
"load.file", // dep: load.file
]);
})();

View file

@ -2,27 +2,24 @@
"use strict"; "use strict";
// dep: moto.license
// dep: moto.client
// dep: moto.broker
// dep: moto.space
// dep: mesh.util
// dep: add.array
// dep: ext.three // dep: ext.three
// dep: ext.three-bgu // dep: ext.three-bgu
gapp.register("mesh.api", [ gapp.register("mesh.api", [], (root, exports) => {
"moto.license", // dep: moto.license
"moto.client", // dep: moto.client
"moto.broker", // dep: moto.broker
"moto.space", // dep: moto.space
"data.index", // dep: data.index
"mesh.tool", // dep: mesh.tool
"mesh.util", // dep: mesh.util
"add.array", // dep: add.array
], (root, exports) => {
const { Matrix4, Vector3 } = THREE; const { Matrix4, Vector3 } = THREE;
const { mesh, moto } = root; const { mesh, moto } = root;
const { space } = moto; const { space } = moto;
const { util } = mesh; const { util } = mesh;
let groups = []; const worker = moto.client.fn
const groups = [];
let selected = []; let selected = [];
const selection = { const selection = {
@ -628,7 +625,7 @@ const api = exports({
} }
}); });
const broker = gapp.broker; const { broker } = gapp;
// publish messages when api functions are called // publish messages when api functions are called
broker.wrapObject(selection, 'selection'); broker.wrapObject(selection, 'selection');
broker.wrapObject(model, 'model'); broker.wrapObject(model, 'model');

View file

@ -2,19 +2,16 @@
"use strict"; "use strict";
(function() { // dep: moto.broker
// dep: mesh.util
// dep: mesh.api
gapp.register("mesh.build", [], (root, exports) => {
gapp.register("mesh.build",[ const { broker } = gapp;
"moto.broker", // dep: moto.broker const { mesh } = root;
"mesh.util", // dep: mesh.util const { api, util } = mesh;
"mesh.api", // dep: mesh.api
]);
let mesh = self.mesh = self.mesh || {};
let broker = gapp.broker;
let call = broker.send; let call = broker.send;
let { api, util } = mesh;
let rad = 180 / Math.PI; let rad = 180 / Math.PI;
let und = undefined; let und = undefined;
@ -32,7 +29,7 @@ util.download = (data, filename = "mesh-data") => {
}; };
// add modal dialog functions to api // add modal dialog functions to api
let modal = api.modal = { const modal = api.modal = {
show(title, contents) { show(title, contents) {
if (this.info.showing) { if (this.info.showing) {
throw `modal conflict showing "${title}"`; throw `modal conflict showing "${title}"`;
@ -118,7 +115,7 @@ let modal = api.modal = {
}; };
// transient logging window bottom/left // transient logging window bottom/left
let log = api.log = { const log = api.log = {
age: 10000, // age out lines more than 10 seconds old age: 10000, // age out lines more than 10 seconds old
data: [], // last n messages data: [], // last n messages
@ -601,4 +598,4 @@ function ui_build() {
}); });
} }
})(); });

View file

@ -2,22 +2,16 @@
"use strict"; "use strict";
(function() { // dep: moto.license
// dep: add.array
// dep: ext.three // dep: ext.three
// dep: ext.three-bgu // dep: ext.three-bgu
gapp.register("mesh.geom", [ gapp.register("mesh.geom", [], (root, exports) => {
"moto.license", // dep: moto.license
"add.array", // dep: add.array
]);
let mesh = self.mesh = self.mesh || {}; const { Matrix4, Matrix3, Vector3, Box3 } = THREE;
if (mesh.geom) return;
let { Matrix4, Matrix3, Vector3, Box3 } = THREE;
// geometry helper functions // geometry helper functions
let geom = mesh.geom = { const geom = exports({
// given a closed polyline as an expanded point array // given a closed polyline as an expanded point array
// return enclosed area with sign indicating winding order // return enclosed area with sign indicating winding order
@ -100,6 +94,6 @@ let geom = mesh.geom = {
return recs; return recs;
} }
}; });
})(); });

View file

@ -2,27 +2,24 @@
"use strict"; "use strict";
(function() { // dep: add.array
// dep: add.three
// dep: moto.license
// dep: moto.broker
// dep: moto.client
// dep: mesh.object
// use: mesh.api
// use: mesh.model
gapp.register("mesh.group", [], (root, exports) => {
gapp.register("mesh.group", [ const { mesh, moto } = root;
"add.array", // dep: add.array const { Quaternion, Group, Vector3 } = THREE;
"add.three", // dep: add.three const { broker } = gapp;
"moto.license", // dep: moto.license const { space } = moto;
"moto.broker", // dep: moto.broker
"mesh.object", // dep: mesh.object
"mesh.model", // dep: mesh.model
"mesh.api", // dep: mesh.api
]);
let mesh = self.mesh = self.mesh || {}; const call = broker.send;
if (mesh.group) return; const worker = moto.client.fn;
const lookUp = new Vector3(0,0,-1);
let { Quaternion, Group, Vector3 } = THREE;
let broker = gapp.broker;
let call = broker.send;
let space = moto.Space;
let worker = moto.client.fn;
let lookUp = new Vector3(0,0,-1);
mesh.group = class MeshGroup extends mesh.object { mesh.group = class MeshGroup extends mesh.object {
@ -165,4 +162,4 @@ mesh.group = class MeshGroup extends mesh.object {
} }
}; };
})(); });

View file

@ -2,26 +2,23 @@
"use strict"; "use strict";
(function() { // dep: add.array
// dep: add.three
// dep: moto.license
// dep: moto.client
// dep: mesh.object
// use: mesh.api
// use: mesh.util
// use: mesh.group
gapp.register("mesh.model", [], (root, exports) => {
gapp.register("mesh.model", [ const { MeshPhongMaterial, MeshBasicMaterial } = THREE;
"add.array", // dep: add.array const { BufferGeometry, BufferAttribute, DoubleSide, Mesh } = THREE;
"add.three", // dep: add.three const { mesh, moto } = root;
"moto.license", // dep: moto.license const { space } = moto;
"mesh.object", // dep: mesh.object
"mesh.group", // dep: mesh.group
"mesh.util", // dep: mesh.util
"mesh.api", // dep: mesh.api
]);
let mesh = self.mesh = self.mesh || {}; const mapp = mesh;
if (mesh.model) return; const worker = moto.client.fn;
let mapp = mesh;
let space = moto.Space;
let worker = moto.client.fn;
let { MeshPhongMaterial, MeshBasicMaterial } = THREE;
let { BufferGeometry, BufferAttribute, DoubleSide, Mesh } = THREE;
/** default materials **/ /** default materials **/
let materials = mesh.material = { let materials = mesh.material = {
@ -606,4 +603,4 @@ mesh.model = class MeshModel extends mesh.object {
}; };
})(); });

View file

@ -2,23 +2,18 @@
"use strict"; "use strict";
(function() { // dep: add.three
// dep: moto.license
// dep: moto.broker
// use: mesh.api
// use: mesh.util
gapp.register("mesh.object", [], (root, exports) => {
gapp.register("mesh.object", [ const { Matrix4, Vector3, Box3, Box3Helper, Quaternion, Euler } = THREE;
"add.three", // dep: add.three const { mesh, moto } = root;
"moto.license", // dep: moto.license const { space } = moto;
"moto.broker", // dep: moto.broker
"mesh.util", // dep: mesh.util
"mesh.api", // dep: mesh.api
]);
let mesh = self.mesh = self.mesh || {}; const worker = moto.client.fn;
if (mesh.object) return;
let space = moto.Space;
let worker = moto.client.fn;
let { Matrix4, Vector3, Box3, Box3Helper, Quaternion, Euler } = THREE;
// broker updates generated by objects // broker updates generated by objects
let publish = { let publish = {
@ -195,4 +190,4 @@ mesh.object = class MeshObject {
} }
}; };
})(); });

View file

@ -2,11 +2,8 @@
"use strict"; "use strict";
(function() { // dep: moto.license
// dep: moto.worker
gapp.finalize("mesh.pool", [ gapp.main("mesh.pool", [], (root) => {
"moto.license", // dep: moto.license // todo
"moto.worker", // dep: moto.worker });
]);
})();

View file

@ -2,17 +2,12 @@
"use strict"; "use strict";
(function() {
// dep: ext.earcut // dep: ext.earcut
gapp.register("mesh.tool", [ // dep: mesh.geom
"mesh.geom", // dep: mesh.geom gapp.register("mesh.tool", [], (root, exports) => {
]);
let mesh = self.mesh = self.mesh || {}; const { mesh } = root;
if (mesh.tool) return; const { geom } = mesh;
let geom = mesh.geom;
/** /**
* tool for identiying defects and healing them * tool for identiying defects and healing them
@ -470,4 +465,4 @@ mesh.tool = class MeshTool {
} }
}; };
})(); });

View file

@ -2,25 +2,22 @@
"use strict"; "use strict";
(function() { // dep: moto.license
// dep: add.array
// dep: ext.three // dep: ext.three
// dep: ext.three-bgu // dep: ext.three-bgu
gapp.register("mesh.util", [ // use: mesh.api
"moto.license", // dep: moto.license gapp.register("mesh.util", [], (root, exports) => {
"add.array", // dep: add.array
]);
let mesh = self.mesh = self.mesh || {}; const { Matrix4, Matrix3, Vector3, Box3 } = THREE;
if (mesh.util) return; const { mesh } = root;
let { Matrix4, Matrix3, Vector3, Box3 } = THREE; const deferFn = [];
const boundsCache = {};
let deferFn = [];
let boundsCache = {};
// util functions augmented in build (download) // util functions augmented in build (download)
let util = mesh.util = { const util = exports({
uuid(segs = 1) { uuid(segs = 1) {
let uid = []; let uid = [];
while (segs-- > 0) { while (segs-- > 0) {
@ -62,7 +59,7 @@ let util = mesh.util = {
}, },
// @param object {THREE.Object3D | THREE.Object3D[] | MeshObject | MeshObject[]} // @param object {THREE.Object3D | THREE.Object3D[] | MeshObject | MeshObject[]}
// @returns bounds modified for moto.Space // @returns bounds modified for moto.space
bounds(object) { bounds(object) {
let box = new Box3(); let box = new Box3();
if (Array.isArray(object)) { if (Array.isArray(object)) {
@ -258,6 +255,6 @@ let util = mesh.util = {
return new VertexNormalsHelper(mesh); return new VertexNormalsHelper(mesh);
} }
}; });
})(); });

View file

@ -2,13 +2,15 @@
"use strict"; "use strict";
(function() { // dep: moto.license
// dep: ext.clip2
// start worker pool (disabled for now with *0)
moto.client.start(`/code/mesh_pool?${gapp.version}`, moto.client.max() * 0);
// dep: ext.three // dep: ext.three
// dep: ext.three-bgu // dep: ext.three-bgu
// dep: add.three
// dep: add.array
// dep: moto.client
// dep: moto.worker
// dep: mesh.util
// dep: geo.base // dep: geo.base
// dep: geo.line // dep: geo.line
// dep: geo.point // dep: geo.point
@ -17,24 +19,20 @@ moto.client.start(`/code/mesh_pool?${gapp.version}`, moto.client.max() * 0);
// dep: geo.bounds // dep: geo.bounds
// dep: geo.slicer // dep: geo.slicer
// dep: geo.csg // dep: geo.csg
// dep: ext.clip2 // dep: mesh.tool
gapp.finalize("mesh.work", [ gapp.main("mesh.work", [], (root) => {
"moto.license", // dep: moto.license
"moto.client", // dep: moto.client
"moto.worker", // dep: moto.worker
"mesh.tool", // dep: mesh.tool
"mesh.util", // dep: mesh.util
"add.three", // dep: add.three
]);
let { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE; const { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE;
const { mesh, moto } = root;
const { client, worker } = moto;
const { util } = mesh;
const cache = {};
// compensation for space/world/platform rotation // compensation for space/world/platform rotation
let core_matrix = new Matrix4().makeRotationX(Math.PI / 2); const core_matrix = new Matrix4().makeRotationX(Math.PI / 2);
let { client, worker } = moto; // start worker pool (disabled for now with *0)
let { util } = mesh; client.start(`/code/mesh_pool?${gapp.version}`, client.max() * 0);
let cache = {};
function log(msg) { function log(msg) {
return worker.publish("mesh.log", msg); return worker.publish("mesh.log", msg);
@ -445,4 +443,4 @@ worker.bindObject({
worker.ready(); worker.ready();
})(); });

View file

@ -2,41 +2,29 @@
"use strict"; "use strict";
(function() { gapp.register("moto.ajax", [], (root, exports) => {
gapp.register('moto.ajax'); function rnd() {
return Math.round(Math.random()*0xffffffff).toString(36);
}
let moto = self.moto = self.moto || {}; const KV = data.local,
if (moto.Ajax) return; KEY = "moto-ajax",
TIME = Date.now,
MOKEY = moto.id = KV.getItem(KEY) || (TIME().toString(36)+rnd()+rnd());
moto.Ajax = Ajax; KV.setItem(KEY, MOKEY);
moto.callAjax = function(url, handler) { const STATES = [
new Ajax(handler).request(url); "request not initialized", // 0
}; "server connection established", // 1
"request recieved", // 2
"processing request", // 3
"request complete" // 4
];
const AP = Ajax.prototype, class Ajax {
KV = data.local, constructor(callback, responseType) {
KEY = "moto-ajax",
TIME = function() { return new Date().getTime() },
MOKEY = moto.id = KV.getItem(KEY) || (TIME().toString(36)+rnd()+rnd());
moto.restore = function(id) {
MOKEY = moto.id = id;
KV.setItem(KEY, MOKEY);
}
KV.setItem(KEY, MOKEY);
const STATES = [
"request not initialized", // 0
"server connection established", // 1
"request recieved", // 2
"processing request", // 3
"request complete" // 4
];
function Ajax(callback, responseType) {
this.ajax = new XMLHttpRequest(); this.ajax = new XMLHttpRequest();
this.ajax.onreadystatechange = this.onStateChange.bind(this); this.ajax.onreadystatechange = this.onStateChange.bind(this);
this.ajax.withCredentials = true; this.ajax.withCredentials = true;
@ -45,11 +33,7 @@
this.responseType = responseType; this.responseType = responseType;
} }
function rnd() { onStateChange() {
return Math.round(Math.random()*0xffffffff).toString(36);
}
AP.onStateChange = function() {
this.state = STATES[this.ajax.readyState]; this.state = STATES[this.ajax.readyState];
if (this.ajax.readyState === 4 && this.callback) { if (this.ajax.readyState === 4 && this.callback) {
let status = this.ajax.status; let status = this.ajax.status;
@ -59,14 +43,9 @@
this.callback(null, this.ajax); this.callback(null, this.ajax);
} }
} }
}; }
/** request(url, send, headers) {
* @param {String} url
* @param {Object} [send]
* @param {Object} [headers]
*/
AP.request = function(url, send, headers) {
this.ajax.open(send ? "POST" : "GET", url, true); this.ajax.open(send ? "POST" : "GET", url, true);
if (this.responseType) this.ajax.responseType = this.responseType; if (this.responseType) this.ajax.responseType = this.responseType;
headers = headers || {}; headers = headers || {};
@ -79,6 +58,23 @@
} else { } else {
this.ajax.send(); this.ajax.send();
} }
}; return this;
}
}
})(); function call(url, handler) {
return new Ajax(handler).request(url);
}
function callAjax(url, handler) {
return new Ajax(handler).request(url);
};
function restore(id) {
MOKEY = moto.id = id;
KV.setItem(KEY, MOKEY);
}
exports({ Ajax, call, callAjax, restore });
});

View file

@ -2,13 +2,10 @@
"use strict"; "use strict";
(function() { gapp.register("moto.broker", [], (root, exports) => {
if (gapp.broker) return; class Broker {
gapp.register('moto.broker');
gapp.broker = new class Broker {
constructor() { constructor() {
this.topics = {}; this.topics = {};
this.used = {}; this.used = {};
@ -137,4 +134,7 @@ gapp.broker = new class Broker {
} }
})(); const { moto } = root;
gapp.broker = moto.broker = new Broker();
});

View file

@ -2,10 +2,14 @@
"use strict"; "use strict";
(function() { gapp.register("moto.client", [
let moto = self.moto = self.moto || {}, "add.array", // dep: add.array
ccvalue = self.navigator ? navigator.hardwareConcurrency || 1 : 1, "moto.broker", // dep: moto.broker
], (root, exports) => {
let ccvalue = self.navigator ? navigator.hardwareConcurrency || 1 : 1,
ccmax = ccvalue > 3 ? ccvalue - 1 : 1, ccmax = ccvalue > 3 ? ccvalue - 1 : 1,
workcc = false, // concurrent or not workcc = false, // concurrent or not
workurl = null, // url to load worker workurl = null, // url to load worker
@ -14,13 +18,6 @@ let moto = self.moto = self.moto || {},
queue = [], // array of work requests queue = [], // array of work requests
topics = {}; // topic handler (broker lite for worker > client msgs) topics = {}; // topic handler (broker lite for worker > client msgs)
if (moto.client) return;
gapp.register('moto.client', [
"add.array", // dep: add.array
"moto.broker", // dep: moto.broker
]);
function dispatch(topic, message) { function dispatch(topic, message) {
for (let fn of topics[topic] || []) { for (let fn of topics[topic] || []) {
fn(message); fn(message);
@ -28,7 +25,7 @@ function dispatch(topic, message) {
} }
// code is running in the browser / client context // code is running in the browser / client context
let client = moto.client = { const client = exports({
/** @returns [integer] total number of workers **/ /** @returns [integer] total number of workers **/
live: () => { live: () => {
@ -258,6 +255,6 @@ let client = moto.client = {
client.kick(); client.kick();
} }
}; });
})(); });

View file

@ -2,19 +2,18 @@
"use strict"; "use strict";
(function() { gapp.register("moto.orbit", [
let MOTO = self.moto = self.moto || {}; 'add.three', // dep: add.three
gapp.register('moto.orbit', [ ], (root, exports) => {
'add.three', // dep: add.three
]); const { moto } = root;
/** /**
* Adapted from THREE.OrbitControls * Adapted from THREE.OrbitControls
*/ */
moto.Orbit = function (object, domElement, notify, slider) {
MOTO.Orbit = function (object, domElement, notify, slider) {
this.object = object; this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document; this.domElement = ( domElement !== undefined ) ? domElement : document;
@ -630,6 +629,6 @@ MOTO.Orbit = function (object, domElement, notify, slider) {
window.addEventListener('keydown', onKeyDown, false); window.addEventListener('keydown', onKeyDown, false);
}; };
MOTO.Orbit.prototype = Object.create(THREE.EventDispatcher.prototype); moto.Orbit.prototype = Object.create(THREE.EventDispatcher.prototype);
})(); });

View file

@ -2,16 +2,18 @@
"use strict"; "use strict";
(function() { // dep: ext.tween
// dep: ext.tween gapp.register("moto.space", [
gapp.register('moto.space', [
'add.three', // dep: add.three
'add.array', // dep: add.array
'moto.orbit' // dep: moto.orbit
]);
let MOTO = self.moto = self.moto || {}, 'add.three', // dep: add.three
WIN = window, 'add.array', // dep: add.array
'moto.orbit' // dep: moto.orbit
], (root, exports) => {
const { moto } = root;
let WIN = window,
DOC = document, DOC = document,
SCENE = new THREE.Scene(), SCENE = new THREE.Scene(),
WORLD = new THREE.Group(), WORLD = new THREE.Group(),
@ -1000,7 +1002,7 @@
} }
} }
let Space = MOTO.Space = MOTO.space = { let Space = exports({
refresh: refresh, refresh: refresh,
update: requestRefresh, update: requestRefresh,
@ -1217,7 +1219,7 @@
raycaster = new THREE.Raycaster(); raycaster = new THREE.Raycaster();
viewControl = new MOTO.Orbit(camera, domelement, (position, moved) => { viewControl = new moto.Orbit(camera, domelement, (position, moved) => {
if (platform) { if (platform) {
platform.visible = hidePlatformBelow ? platform.visible = hidePlatformBelow ?
initialized && position.y >= 0 && showPlatform : showPlatform; initialized && position.y >= 0 && showPlatform : showPlatform;
@ -1326,13 +1328,15 @@
initialized = true; initialized = true;
} }
}; });
let cycle = [ let cycle = [
Space.view.front, Space.view.front,
Space.view.right, Space.view.right,
Space.view.back, Space.view.back,
Space.view.left, Space.view.left,
]; ];
let cycleInd = 0; let cycleInd = 0;
})(); });

View file

@ -2,35 +2,12 @@
"use strict"; "use strict";
(function() { gapp.register("moto.webui", [
gapp.register('moto.webui', [ "moto.license", // dep: moto.license
"moto.license", // dep: moto.license "add.array", // dep: add.array
"add.array", // dep: add.array
]);
let moto = self.moto = self.moto || {}; ], (root, exports) => {
if (moto.webui) return;
// window ui helpers
Object.assign(self, {
$: (id) => {
return document.getElementById(id);
},
$d: (id, v) => {
$(id).style.display = v;
},
$h: (id, h) => {
$(id).innerHTML = h;
},
estop: (evt) => {
evt.stopPropagation();
evt.preventDefault();
}
});
let nextid = 1; let nextid = 1;
@ -92,7 +69,7 @@ function build(data, context) {
} }
// core html builder funtions // core html builder funtions
let h = self.h = moto.webui = { let h = exports({
bind: (el, data, opt = {}) => { bind: (el, data, opt = {}) => {
let ctx = []; let ctx = [];
let html = build(data, ctx).join(''); let html = build(data, ctx).join('');
@ -120,7 +97,29 @@ let h = self.h = moto.webui = {
} }
return { type, attr, innr }; return { type, attr, innr };
} }
}; });
// window ui helpers
gapp.overlay(root, {
$: (id) => {
return document.getElementById(id);
},
$d: (id, v) => {
$(id).style.display = v;
},
$h: (id, h) => {
$(id).innerHTML = h;
},
h,
estop: (evt) => {
evt.stopPropagation();
evt.preventDefault();
}
});
// add common element types // add common element types
["a", "i", "div", "span", "label", "input", "button", "svg"].forEach(type => { ["a", "i", "div", "span", "label", "input", "button", "svg"].forEach(type => {
@ -129,4 +128,4 @@ let h = self.h = moto.webui = {
} }
}); });
})(); });

View file

@ -2,18 +2,12 @@
"use strict"; "use strict";
(function() { gapp.register("moto.worker", [], (root, exports) => {
let moto = self.moto = self.moto || {};
if (moto.worker) return;
gapp.register('moto.worker');
let endpoints = {}; let endpoints = {};
// code is running in the worker / server context // code is running in the worker / server context
const dispatch = moto.worker = { const dispatch = exports({
// bind an endpoint name to a function // bind an endpoint name to a function
bind(name, fn) { bind(name, fn) {
@ -100,9 +94,9 @@ const dispatch = moto.worker = {
} }
} }
}; });
// attach onmessage hanler // attach onmessage hanler
self.onmessage = dispatch.onmessage; self.onmessage = dispatch.onmessage;
})(); });