diff --git a/bootstrap.js b/bootstrap.js index 7a124fe40d96dd84156fa72d339071ca0fc0e011..6db957fc552e42724e6172c92ed2c0f2910463fc 100644 --- a/bootstrap.js +++ b/bootstrap.js @@ -41,7 +41,15 @@ function bootloop() { console.error('loop halting, mgr bailing') return } - setTimeout(bootloop) + if(window.run) setTimeout(bootloop) +} + +window.run = true + +window.halt = (err) => { + window.run = false + console.error('HALTING') + throw new Error(err) } window.onload = () => { @@ -51,7 +59,7 @@ window.onload = () => { // manager wants view handle to render hunk DOM elements into plane ... // there's only one of each, so just window.tlv = tlv - window.nrol = nrol + window.nrol = nrol }).then(() => { // make ah graph, // outHunkIndex, outIndex, inHunkIndex, inIndex, debug diff --git a/core/scope.js b/core/scope.js index 8f20ddc5d2e327aab1275e0c4805b5799dceb153..b2f2503ff8b919862c5931de6498c0db36cf3457 100644 --- a/core/scope.js +++ b/core/scope.js @@ -291,16 +291,18 @@ export default function Scope(wrapper, tlv) { let open = (context) => { // new plane every time! - context.plane = $('<div>').addClass('subplane').addClass('block').attr('id', `${def.name}_plane`).get(0) + // handle to our context's container (the link) + let ldef = context.within + if (!ldef) throw new Error("no apparent link container for this context") + context.plane = $('<div>').addClass('block').addClass('subplane').attr('id', `${ldef.name}_plane`).get(0) context.plane.position = () => { - return { x: 0, y: blocks.getBlockStackHeight(def.blocks) } + return { x: 0, y: blocks.getBlockStackHeight(ldef.blocks) } } if (!context.size) context.size = { x: 800, y: 600 } - dt.writeContainerSize(context.size) + dt.writeContainerSize(context.plane, context.size) // blocks should have handles, context.plane.handle = context // this is a throwaway ... and maybe ah bugfarm // the context should be .within an ldef, we want this block to carry the plane around, - let ldef = context.within ldef.blocks.push(context.plane) ldef.blocks[0].take(context.plane) // 'parent' block, for positioning, kind of awkward // existence @@ -312,17 +314,19 @@ export default function Scope(wrapper, tlv) { size.x += deltas.x size.y += deltas.y dt.writeContainerSize(context.plane, size) - repositionDef(def) + blocks.repositionDef(ldef) // reposition all defs in the downstream: we might be squishing them about: for (let dsdef of context.defs) { - repositionDef(dsdef) + blocks.repositionDef(dsdef) } } // end onresize, // place, - repositionDef(def) + blocks.repositionDef(ldef) // toggle button state, - $(squid).html('<i class="em em-shell"></i> collapse link') - $(squid).one('click', close) + $(ldef.squid).html('<i class="em em-shell"></i> collapse link') + $(ldef.squid).one('click', (evt) => { + context.open = false + }) /* if (def.states[0].value) { // if is-connecting, context.refresh().then(() => { @@ -336,13 +340,23 @@ export default function Scope(wrapper, tlv) { let close = (context) => { - console.error('nah') - /* - // 'ldef.contains' is a ptr to the context (view) that is w i t h i n the link, accoring - // to our earlier piping, ldef.contains = view returned here - wipeContext(ldef.contains) + let ldef = context.within + if (!ldef) throw new Error("no apparent link container for this context") + // we should be prudent about also closing downstream links, + // for now here's a wrench across the terminals, + for (let def of context.defs) { + if (def.type == 'link') { + context.getLinkContext(def).then((sub) => { + if (sub && sub.open) { + throw new Error('need to recurse through and close downstream') + } + }) + } + } + // ok, cleanup: + blocks.wipeContext(context) $(ldef.contains.plane).remove() - // arduous: rm from ldef, and from titleblock, + // arduous: rm plane-as-block from ldef, and from titleblock, let bi = ldef.blocks.findIndex((cand) => { return (cand === ldef.contains.plane) }) @@ -351,16 +365,19 @@ export default function Scope(wrapper, tlv) { } else { console.error('lost plane block ... ') } - titleblock.remove(ldef.contains.plane) - delete ldef.contains.plane - // . then-> - - $(squid).html('<i class="em em-squid"></i> expand link') - $(squid).one('click', open) - repositionDef(ldef) - */ + ldef.blocks[0].remove(ldef.contains.plane) + // she gone, burn the letters + delete context.plane + // plenty of fish, + $(ldef.squid).html('<i class="em em-squid"></i> expand link') + $(ldef.squid).one('click', (evt) => { + context.open = true + }) + blocks.repositionDef(ldef) } + let once = false + this.check = () => { // check levels recursively, let recursor = (context) => { @@ -369,20 +386,20 @@ export default function Scope(wrapper, tlv) { if (def.type == 'link') { // find the context it's connected to, def.context.getLinkContext(def).then((nc) => { // next context, - if (nc.open && !nc.plane) { // open, no plane, so we build one: - console.log('opening') - console.log(nc.plane) // nc / linkcontext maybe not what you think it is ? - here you are - open(nc) - } - if (nc.plane && !nc.open) { // exist, but should be closed, run that - close(nc) - } - if (nc.plane) { // if plane still up, we passed the last if, recurse down - recursor(nc) + if (nc) { + if (nc.open && !nc.plane) { // open, no plane, so we build one: + open(nc) + } + if (nc.plane && !nc.open) { // exist, but should be closed, run that + close(nc) + } + if (nc.plane) { // if plane still up, we passed the last if, recurse down + recursor(nc) + } } - }).catch(() => { - // noop, no context, + }).catch((err) => { + window.halt(err) + //throw new Error(err) // I would prefer that these halt, }) } } diff --git a/hunks/view.js b/hunks/view.js index 3b3e12cf09cb3abf695fd708273216f227ac4eb7..55af914fcc30f22340a7d6b5b29b6b56b7b1fb04 100644 --- a/hunks/view.js +++ b/hunks/view.js @@ -1094,20 +1094,24 @@ function View() { this.makeLinkContext = (ldef) => { return new Promise((resolve, reject) => { - this.getLinkContext(ldef).then((context) => { - resolve(context) - }).catch(async () => { - // none, make one, - try { - let vdef = await window.tlv.requestAddHunk('view') - await this.buildRoute(vdef.outputs[0], ldef.inputs[1]) - await this.buildRoute(ldef.outputs[1], vdef.inputs[0]) - let view = vdef.hunk // views are always toplevel hunks, so they always have these handles - resolve(view) - } catch (err) { - console.error(err) - reject() + this.getLinkContext(ldef).then(async (context) => { + if(context){ + resolve(context) + } else { + // build it, cn it, continue, + try { + let vdef = await window.tlv.requestAddHunk('view') + await this.buildRoute(vdef.outputs[0], ldef.inputs[1]) + await this.buildRoute(ldef.outputs[1], vdef.inputs[0]) + let view = vdef.hunk // views are always toplevel hunks, so they always have these handles + resolve(view) + } catch (err) { + console.error(err) + reject() + } } + }).catch((err) => { + reject(err) }) }) } @@ -1126,7 +1130,7 @@ function View() { reject('looking for context, traces to non-view... ') } } else { - reject() + resolve() // resolve w/ response that no context exists for this link, } }) } diff --git a/view/blocks.js b/view/blocks.js index 7f8556cdcd8beb5c14375195956f2e0c20dda133..c95391e74440dd9be5c5e82eade78bfe4dd201b4 100644 --- a/view/blocks.js +++ b/view/blocks.js @@ -54,9 +54,9 @@ let getBlockStackWidth = (blocks) => { let getBlockStackRightWidth = (blocks) => { let x = getBlockStackWidth(blocks) let y = 0 - for(let bl of blocks) { - if($(bl).is('.output')) { - if(y < bl.clientWidth) y = bl.clientWidth + for (let bl of blocks) { + if ($(bl).is('.output')) { + if (y < bl.clientWidth) y = bl.clientWidth } } return (x + y + 5) @@ -64,9 +64,9 @@ let getBlockStackRightWidth = (blocks) => { let getBlockStackLeftWidth = (blocks) => { let x = 0 - for(let bl of blocks){ - if($(bl).is('.input')){ - if(x < bl.clientWidth) x = bl.clientWidth + for (let bl of blocks) { + if ($(bl).is('.input')) { + if (x < bl.clientWidth) x = bl.clientWidth } } return (x += 5) @@ -75,29 +75,25 @@ let getBlockStackLeftWidth = (blocks) => { // oboy, let makeLink = (ldef, titleblock) => { // ok, we have a new link, - if(!ldef.upstream){ - let squid = $('<div>').addClass('loosebutton').addClass('block').get(0) - squid.position = () => { - return { x: 0, y: -squid.clientHeight - 5 } + if (!ldef.upstream) { + ldef.squid = $('<div>').addClass('loosebutton').addClass('block').get(0) + ldef.squid.position = () => { + return { x: 0, y: -ldef.squid.clientHeight - 5 } } - squid.handle = ldef - titleblock.take(squid) - ldef.blocks.push(squid) - let open = (evt) => { + ldef.squid.handle = ldef + titleblock.take(ldef.squid) + ldef.blocks.push(ldef.squid) + $(ldef.squid).html('<i class="em em-squid"></i> expand link') + $(ldef.squid).one('click', (evt) => { ldef.context.makeLinkContext(ldef).then((context) => { context.open = true }) - } - let close = (evt) => { - ldef.contains.open = false - } - $(squid).html('<i class="em em-squid"></i> expand link') - $(squid).one('click', open) + }) } else { // static title, titleblock.position = () => { let y = 0; - for(let opd of ldef.outputs){ + for (let opd of ldef.outputs) { y += opd.block.clientHeight + 5 } return { x: 0, y: y } @@ -444,16 +440,16 @@ let repositionBlock = (block) => { let repositionDef = (def) => { // context bounds ... - if(!def.context.plane) { + if (!def.context.plane) { // not completely unlikely, invisible views refreshing, perhaps... but those // should come thru ah reposition check-switch, not here direct, so console.warn('reposition for invisible def, wyd?') return } // hmmm ... ok, for our siblings' children, we are subject to not-overrun them, - for(let df of def.context.defs){ - if(def.contains){ - if(def.contains.plane){ + for (let df of def.context.defs) { + if (def.contains) { + if (def.contains.plane) { // this one's tricky: we have potentially many-sub-planes, let's just // stick to not-excaping-our-own-bounds for now, } @@ -461,7 +457,7 @@ let repositionDef = (def) => { } // ok, for our parents: // ah ... titles drag blocks, not defs ... maybe they should drag defs. - if(def.context.within){ + if (def.context.within) { let bw = def.context.plane.clientWidth let bh = def.context.plane.clientHeight // clip to bounds, plus some margin... @@ -469,10 +465,10 @@ let repositionDef = (def) => { let wl = getBlockStackLeftWidth(def.blocks) let h = getBlockStackHeight(def.blocks) // cover bottom left: - if(def.position.x + wr > bw) def.position.x = bw - wr - if(def.position.y + h > bh) def.position.y = bh - h - if(def.position.x - wl < 0) def.position.x = wl - if(def.position.y < 0) def.position.y = 0 + if (def.position.x + wr > bw) def.position.x = bw - wr + if (def.position.y + h > bh) def.position.y = bh - h + if (def.position.x - wl < 0) def.position.x = wl + if (def.position.y < 0) def.position.y = 0 } // arrange, if (def.blocks) { @@ -515,6 +511,10 @@ export default { redrawDef, // to add / update anything repositionDef, // to move anything repositionBlock, // to move by block (dragging children along) + getBlockStackHeight, // total height of states, title + getBlockStackWidth, // states width + getBlockStackLeftWidth, // total left + getBlockStackRightWidth, // total right redrawContexWires, // when context link topology changes wipeContext // to shutdown / cleanup }