mesh app work. improve script setup

This commit is contained in:
Stewart Allen 2021-12-26 19:43:48 -05:00
commit 16fa536605
8 changed files with 286 additions and 86 deletions

84
app.js
View file

@ -289,7 +289,7 @@ const script = {
"kiri/tools", "kiri/tools",
"@devices", "@devices",
"@icons" "@icons"
].map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p), ],
worker : [ worker : [
"main/kiri", "main/kiri",
"ext/three", "ext/three",
@ -341,7 +341,7 @@ const script = {
"kiri/print", "kiri/print",
"kiri/codec", "kiri/codec",
"kiri/worker" "kiri/worker"
].map(p => `src/${p}.js`), ],
minion : [ minion : [
"main/kiri", "main/kiri",
"add/license", "add/license",
@ -367,7 +367,7 @@ const script = {
"kiri/widget", "kiri/widget",
"kiri/codec", "kiri/codec",
"kiri/minion" "kiri/minion"
].map(p => `src/${p}.js`), ],
engine : [ engine : [
"main/kiri", "main/kiri",
"add/license", "add/license",
@ -394,10 +394,10 @@ const script = {
"kiri/widget", "kiri/widget",
"kiri/codec", "kiri/codec",
"kiri/engine" "kiri/engine"
].map(p => `src/${p}.js`), ],
frame : [ frame : [
"kiri/frame" "kiri/frame"
].map(p => `src/${p}.js`), ],
meta : [ meta : [
"ext/three", "ext/three",
"add/license", "add/license",
@ -425,32 +425,19 @@ const script = {
"moto/ui", "moto/ui",
"kiri/catalog", "kiri/catalog",
"main/meta" "main/meta"
].map(p => `src/${p}.js`), ],
mesh : [ mesh : [
"main/mesh", "main/mesh",
"moto/client",
"ext/three", "ext/three",
"ext/three-bgu", "ext/three-bgu",
"ext/three-svg", "ext/three-svg",
"ext/jszip",
"add/license", "add/license",
"ext/clip2",
"ext/tween", "ext/tween",
"ext/fsave", "ext/fsave",
"ext/earcut",
"ext/base64",
"add/array", "add/array",
"add/three", "add/three",
"geo/base",
"geo/point",
"geo/points",
"geo/slope",
"geo/line",
"geo/bounds",
"geo/polygon",
"geo/polygons",
"geo/mesh", "geo/mesh",
// "moto/kv",
// "moto/ajax",
"moto/ctrl", "moto/ctrl",
"moto/space", "moto/space",
"moto/load-3mf", "moto/load-3mf",
@ -460,28 +447,35 @@ const script = {
"moto/load-url", "moto/load-url",
"moto/load-file", "moto/load-file",
"moto/broker", "moto/broker",
"moto/db", "moto/db"
// "kiri/ui", ],
// "kiri/do", mesh_work : [
// "kiri/lang", "moto/worker",
// "kiri/lang-en", "add/license",
// "kiri/catalog", "ext/jszip",
// "kiri/slice", "ext/clip2",
// "kiri/layers", "ext/earcut",
// "kiri/client", "ext/base64",
// "kiri/stack", "ext/three",
// "kiri/stacks", "add/three",
// "kiri/widget", "ext/three-bgu",
// "kiri/print", "geo/base",
// "kiri/codec", "geo/point",
// "kiri/conf", "geo/points",
// "kiri/main", "geo/slope",
// "kiri/init", "geo/line",
// "kiri/export", "geo/bounds",
// "kiri/tools", "geo/polygon",
].map(p => `src/${p}.js`), "geo/polygons",
"geo/mesh",
]
}; };
// process script dependencies, expand paths
for (let [key,val] of Object.entries(script)) {
script[key] = val.map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p);
}
// prevent caching of specified modules // prevent caching of specified modules
const cachever = {}; const cachever = {};
@ -644,13 +638,9 @@ function generateDevices() {
function prepareScripts() { function prepareScripts() {
generateIcons(); generateIcons();
generateDevices(); generateDevices();
code.meta = concatCode(script.meta); for (let key of Object.keys(script)) {
code.mesh = concatCode(script.mesh); code[key] = concatCode(script[key]);
code.kiri = concatCode(script.kiri); }
code.worker = concatCode(script.worker);
code.minion = concatCode(script.minion);
code.engine = concatCode(script.engine);
code.frame = concatCode(script.frame);
} }
function concatCode(array) { function concatCode(array) {

View file

@ -1,4 +1,4 @@
# Kiri:Moto todo and notes # Kiri:Moto / Grid:Apps notes
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix ## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
@ -108,20 +108,3 @@
# Laser # Laser
* `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL) * `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL)
# References
* https://www.canva.com/colors/color-wheel/
* http://lcamtuf.coredump.cx/gcnc/full/
* http://wiki.imal.org/howto/cnc-milling-introduction-cutting-tools
* http://www.twak.co.uk/2011/01/degeneracy-in-weighted-straight.html
* http://photon.chrisgraf.de/
* https://github.com/Jack000/SVGnest
# More CNC
* https://www.researchgate.net/publication/250328721_Toolpath_Optimization_on_Automatic_Removal_Uncut_and_Application
# Meta
* free-space tetrahedron modeler with vertex mating

View file

@ -48,8 +48,8 @@ if installing the app-server fails or gives you permissions errors, then your no
sudo npm install -g @gridspace/app-server sudo npm install -g @gridspace/app-server
``` ```
to start a local instance of the apps. then open to start a local instance of the apps. then use a browser to open
[localhost:8080/kiri](http://localhost:8080/kiri) on your local host [localhost:8080/kiri](http://localhost:8080/kiri)
Alternatively, if you are using a packaged version of npm that ships with Alternatively, if you are using a packaged version of npm that ships with
a Linux distribution, but still want to install in your home directory, you a Linux distribution, but still want to install in your home directory, you
@ -73,7 +73,7 @@ cd grid-apps
docker-compose -f src/dock/compose.yml up docker-compose -f src/dock/compose.yml up
``` ```
You can now access your environment of grid-apps by going to: You can now access your environment of grid-apps by going to
[localhost:8080/kiri](http://127.0.0.1:8080/kiri) [localhost:8080/kiri](http://127.0.0.1:8080/kiri)
### Windows Developers ### Windows Developers

View file

@ -1,10 +1,14 @@
// required for license and other grid app dependencies // required for license and other grid app dependencies
self.gapp = {}; self.gapp = self.gapp || {};
function $(id) { function $(id) {
return document.getElementById(id); return document.getElementById(id);
} }
function $d(id, v) {
$(id).style.display = v;
}
function init() { function init() {
let container = $('container'), let container = $('container'),
moto = self.moto, moto = self.moto,
@ -28,10 +32,13 @@ function init() {
Space.useDefaultKeys(true); Space.useDefaultKeys(true);
// hide loading curtain // hide loading curtain
$('curtain').style.display = 'none'; $d('curtain','none');
// remove version cache bust from url // remove version cache bust from url
window.history.replaceState({},'','/mesh/'); window.history.replaceState({},'','/mesh/');
// start worker
moto.client.start(`/code/mesh_work?${gapp.version}`);
} }
document.onreadystatechange = function() { document.onreadystatechange = function() {

124
src/moto/client.js Normal file
View file

@ -0,0 +1,124 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
let MOTO = self.moto = self.moto || {},
time = function() { return new Date().getTime() },
restarting = false,
running = {},
workurl = null,
worker = null,
seqid = 1;
/**
* @param {Function} fn name of function in MOTO.worker
* @param {Object} data to send to server
* @param {Function} onreply function to call on reply messages
* @param {Object[]} zerocopy array of objects to pass using zerocopy
*/
function send(fn, data, onreply, zerocopy) {
let seq = seqid++;
if (onreply) {
// establish listener and track replies
running[seq] = { fn:onreply };
}
let msg = {
seq: seq,
task: fn,
time: time(),
data: data
};
try {
worker.postMessage(msg, zerocopy);
} catch (error) {
console.trace('work send error', {data, error});
}
}
// code is running in the browser / client context
let CLIENT = MOTO.client = {
send: send,
// factory can be overridden
newWorker: function(url = workurl) {
if (self.createWorker) {
return self.createWorker();
} else {
return new Worker(workurl = url);
}
},
// return number of running requests
current: function() {
let current = 0;
for (let rec of Object.values(running)) {
if (rec.fn) current++;
}
return current;
},
stop: function() {
if (worker) {
worker.terminate();
worker = null;
}
},
// same as restart
start: function(url) {
CLIENT.restart(url);
},
restart: function(url) {
// prevent re-entry from cancel callback
if (restarting) {
return;
}
CLIENT.stop();
restarting = true;
for (let key in running) {
let rec = running[key];
if (rec.fn) {
rec.fn({error: "cancelled operation"});
}
}
running = {};
worker = CLIENT.newWorker(url);
// bind to CLIENT to enable synth injections
CLIENT.onmessage = worker.onmessage = function(e) {
let now = time(),
reply = e.data,
record = running[reply.seq],
onreply = record ? record.fn : undefined;
if (reply.done) {
delete running[reply.seq];
}
// calculate and replace recv time
reply.time_recv = now - reply.time_recv;
if (onreply) {
onreply(reply.data, reply);
} else {
console.log({drop_reply: reply});
}
};
// signal worker client is ready
worker.postMessage("--init--");
restarting = false;
}
};
})();

80
src/moto/worker.js Normal file
View file

@ -0,0 +1,80 @@
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
"use strict";
(function() {
let MOTO = self.moto = self.moto || {},
time = Date.now;
// allow license to inject module
self.gapp = self.gapp || MOTO;
// code is running in the worker / server context
const dispatch = MOTO.worker = {
send: (msg) => {
self.postMessage(msg);
},
onmessage: (e) => {
if (e.data === '--init--') {
console.log('worker got init');
return;
}
let time_recv = time(),
msg = e.data || {},
run = dispatch[msg.task],
send = {
data : function(data,direct) {
dispatch.send({
seq: msg.seq,
task: msg.task,
done: false,
data: data
}, direct);
},
done : function(data,direct) {
dispatch.send({
seq: msg.seq,
task: msg.task,
done: true,
data: data
}, direct);
}
};
if (run) {
try {
let time_xfer = (time_recv - msg.time),
output = run(msg.data, send),
time_send = time(),
time_proc = time_send - time_recv;
if (output) dispatch.send({
seq: msg.seq,
task: msg.task,
time_send: time_xfer,
time_proc: time_proc,
// replaced on reply side
time_recv: time(),
data: output
});
} catch (wrkerr) {
// console.log(wrkerr);
console.trace(wrkerr.stack);
send.done({error: wrkerr.toString()});
}
} else {
console.log({worker_unhandled: e, msg, fn: dispatch[msg.task]});
}
}
};
// attach onmessage hanler
self.onmessage = dispatch.onmessage;
})();

View file

@ -9,7 +9,7 @@
} }
@font-face { @font-face {
font-family: 'Russo One'; font-family: 'Russo One';
src: url('ext/russo-one.ttf'); src: url('/kiri/ext/russo-one.ttf');
} }
a, a:hover, a:visited { a, a:hover, a:visited {
border: none; border: none;
@ -28,17 +28,33 @@ a, a:hover, a:visited {
bottom: 0; bottom: 0;
} }
#app-name { #app-name {
position: absolute; xposition: absolute;
top: 50%; top: 50%;
left: 50%; left: 50%;
transform: translateX(-50%) translateY(-50%); transform: translateX(-50%) translateY(-50%);
z-index: 50; z-index: 50;
} }
#app-name, #app-mode-name, #app-acct { #app-name:hover #app-info {
cursor: pointer; display: flex;
} }
#app-mode-name { #app-info {
border-bottom: 2px dotted grey; display: none;
position: absolute;
white-space: nowrap;
font-size: smaller;
font-family: sans-serif;
margin-top: 5px;
padding: 5px;
transform: translateX(-50%);
left: 50%;
top: 100%;
color: var(--fg-gray);
border-radius: 3px;
border: 1px solid #ddd;
background-color: white;
}
#app-name, #app-acct {
cursor: pointer;
} }
#app,div { #app,div {
display: flex; display: flex;
@ -46,6 +62,11 @@ a, a:hover, a:visited {
border: 0; border: 0;
margin: 0; margin: 0;
} }
#top-sep, #mid-sep {
z-index: 14;
height: 1px;
background-image: var(--gradbar);
}
#gsbox { #gsbox {
width: 40px; width: 40px;
height: 40px; height: 40px;

View file

@ -14,7 +14,7 @@
<title>Mesh:Tool</title> <title>Mesh:Tool</title>
<link rel="icon" href="/kiri/favicon.ico"> <link rel="icon" href="/kiri/favicon.ico">
<link rel="apple-touch-icon" href="/kiri/favicon-mobile.png"> <link rel="apple-touch-icon" href="/kiri/favicon-mobile.png">
<link rel="stylesheet" type="text/css" href="/kiri/index.css?{{version}}"> <link rel="stylesheet" type="text/css" href="/mesh/index.css?{{version}}">
<link href="/font/css/all.min.css" rel="stylesheet"> <link href="/font/css/all.min.css" rel="stylesheet">
<script src="/font/js/all.min.js" crossorigin="anonymous"></script> <script src="/font/js/all.min.js" crossorigin="anonymous"></script>
<script src="/code/mesh.js?{{version}}"></script> <script src="/code/mesh.js?{{version}}"></script>
@ -24,23 +24,18 @@
<div id="curtain" class="j-center a-center"><img id="gsbox"/>loading...</div> <div id="curtain" class="j-center a-center"><img id="gsbox"/>loading...</div>
<div id="container"></div> <div id="container"></div>
<div id="tracker"></div> <div id="tracker"></div>
<div id="top-sep"></div>
<div id="top" class="f-row"> <div id="top" class="f-row">
<div id="app-name" class="f-col a-center">
<div>Mesh:Tool<div id="app-info">version</div></div>
</div> </div>
</div>
<div id="mid-sep"></div>
<div id="gdpr" class="noshow"> <div id="gdpr" class="noshow">
<p>this site uses <A href="/privacy.html" target="privacy">cookies</a> to preserve application preferences</p> <p>this site uses <A href="/privacy.html" target="privacy">cookies</a> to preserve application preferences</p>
<button id="gotit" class="f-col j-center">got it</button> <button id="gotit" class="f-col j-center">got it</button>
</div> </div>
<div id="tool-info" class="noshow"></div> <div id="tool-info" class="noshow"></div>
<div id="fps" class="noshow"></div> <div id="fps" class="noshow"></div>
<div id="alert-area">
<div id="alert-border">
<div id="alert-text">alerts<br>alerts<br>alerts</div>
</div>
</div>
<div id="top-slider" class="f-col grow">
<input id="anim-slider" type="range" min="0" max="1000" value="0"></input>
</div>
</div> </div>
</body> </body>
</html> </html>