From 026f4787ad84006a608c575536992c4f3a2c885a Mon Sep 17 00:00:00 2001 From: ghost Date: Wed, 18 Oct 2023 21:39:58 -0400 Subject: [PATCH] permanent dumplings reuse old dumplings --- core/dumpling/a-dumpling.js | 35 +- .../items/devcommentary/devcommentary.p.html | 415 ++++++++++++++++-- forest/items/devcommentary/wordhack.js | 317 ------------- index.p.html | 18 +- 4 files changed, 419 insertions(+), 366 deletions(-) delete mode 100644 forest/items/devcommentary/wordhack.js diff --git a/core/dumpling/a-dumpling.js b/core/dumpling/a-dumpling.js index b8d185c..9f1abf4 100644 --- a/core/dumpling/a-dumpling.js +++ b/core/dumpling/a-dumpling.js @@ -532,14 +532,15 @@ export class Dumpling extends HTMLParsedElement { // if permanent... const isPermanent = m.hasAttrWithAliases(k.attr.permanent) if (isPermanent) { - // (if this is already in the inventory, remove it) - const inventory = document.getElementById(k.id.permanent) - if (inventory != null) { - const other = inventory.querySelector(`#${m.id}`) - if (other != null && this !== other) { - m.remove() - return true - } + const other = ( + m.findDuplicateInParent(k.id.transient) || + m.findDuplicateInParent(k.id.permanent) + ) + + if (other != null && m !== other) { + m.remove() + other.show() + return true } // ...and visible, move to the inventory instead @@ -627,7 +628,10 @@ export class Dumpling extends HTMLParsedElement { sendEvent(type, detail = null) { const m = this - m.dispatchEvent(new CustomEvent(type, { detail: detail || m })) + m.dispatchEvent(new CustomEvent(type, { + detail: detail || m, + bubbles: true, + })) } // -- c/gesture @@ -1087,7 +1091,7 @@ export class Dumpling extends HTMLParsedElement { return this.$body != null ? this.$body.children[0] : null } - // -- q/iframe -- + // -- q/iframe /// find our inner iframe, if any findIframe() { return this.asIframe(this.findInner()) @@ -1098,6 +1102,17 @@ export class Dumpling extends HTMLParsedElement { return k.tag.iframe.has($child && $child.nodeName) ? $child : null } + // -- q/duplicate + /// find a duplicate of this dumpling in the parent + findDuplicateInParent(id) { + const parent = document.getElementById(id) + if (parent == null) { + return null + } + + return parent.querySelector(`#${this.id}`) + } + // -- title -- _title = null diff --git a/forest/items/devcommentary/devcommentary.p.html b/forest/items/devcommentary/devcommentary.p.html index 3c7377a..fcc193c 100644 --- a/forest/items/devcommentary/devcommentary.p.html +++ b/forest/items/devcommentary/devcommentary.p.html @@ -1,37 +1,5 @@ - - - - - - - - -
@@ -64,6 +32,385 @@

- - + + + + diff --git a/forest/items/devcommentary/wordhack.js b/forest/items/devcommentary/wordhack.js deleted file mode 100644 index 4173314..0000000 --- a/forest/items/devcommentary/wordhack.js +++ /dev/null @@ -1,317 +0,0 @@ -import { Inventory } from "../../inventory.js" - -// -- types -- -const Actions = { - Start: 0, - Next: 1, - Reset: 2, -} - -// -- elements -- -const $el = { - config: { - frame: null, - input: null, - }, - timer: { - names: null, - limit: null, - }, - action: null, -} - -// -- props -- -let mNames = null -let mLimit = null - -// -- lifetime -- -function init() { - // capture elements - $el.config.frame = document.getElementById("config") - $el.config.group = document.getElementById("group") - - $el.timer.names = document.getElementById("names") - $el.timer.limit = document.getElementById("limit") - - $el.action = document.getElementById("action") - - // bind events - $el.action.addEventListener("click", didClickAction) - document.addEventListener("keydown", OnKeyDown) - - // set initial state - reset() -} - -// -- commands -- -function reset() { - // reset state - if (mLimit != null) { - mLimit.stop() - mLimit = null - } - - // reset view - // TODO: this is getting gross - drawNames() - drawLimit() - drawAction() - drawConfig() -} - -function start() { - // advance to the first step - mNames = decodeBag($el.config.group.value) - advance() - - // hide the config - drawConfig() -} - -function Act() { - switch (getAction()) { - case Actions.Start: - start(); break - case Actions.Next: - advance(); break - case Actions.Reset: - reset(); break - } -} - -function advance() { - // stop previous limit - if (mLimit != null) { - mLimit.stop() - } - - // update the names - drawNames(rollNames()) - - // update the limit - mLimit = rollLimit() - mLimit.init() - - // update the action - drawAction() -} - -// -- c/drawing -function drawConfig() { - $el.config.frame.classList.toggle("is-hidden", getAction() !== Actions.Start) -} - -function drawNames(names = null) { - $el.timer.names.innerText = names != null ? `${names.join(", ")}` : "" -} - -function drawLimit(content = null) { - $el.timer.limit.innerText = content -} - -function drawAction() { - $el.action.innerText = getActionName() -} - -// -- queries -- -function rollNames() { - // draw at least one name - const names = [mNames.draw()] - - // add another person for every nat 20 - while (!mNames.isEmpty && roll("1d20") == 20) { - names.push(mNames.draw()) - } - - return names -} - -function rollLimit() { - if (roll("1d6") <= 4) { - return initTimeLimit() - } else { - return initWordLimit() - } -} - -function getAction() { - if (mLimit == null) { - return Actions.Start - } else if (mNames.isEmpty) { - return Actions.Start - } else { - return Actions.Next - } -} - -function getActionName() { - switch (getAction()) { - case Actions.Start: - return "start" - case Actions.Next: - return "next" - case Actions.Reset: - return "reset" - } -} - - -// -- q/bag -function decodeBag(str) { - switch (str) { - case "studio ii": - return new Bag(["d", "darwin", "fran", "jen", "mut", "ty"]) - case "seminar": - return new Bag(["frank"]) - default: - return decodeBagFromList(str) - } -} - -function decodeBagFromList(str) { - const re = /(\w+),?/g - const items = [] - - let match = null - while (match = re.exec(str)) { - items.push(match[1]) - } - - return new Bag(items) -} - -// -- events -- -function didClickAction() { - Act() -} - -function OnKeyDown(evt) { - if (evt.isComposing || evt.keyCode === 229) { - return; - } - - if (evt.keyCode >= 96 && evt.keyCode <= 105) { - Act() - } -} - -// -- limits -- -function initTimeLimit() { - return initLimit({ - duration: 5 + roll("1d20"), - loop() { - let now = seconds() - if (this.t0 == null) { - this.t0 = now - } - - // draw the time display - const elapsed = now - this.t0 - const remaining = Math.max(this.duration - elapsed, 0) - drawLimit(`${remaining} seconds`) - - // continue as long as there is time remaining - if (remaining <= 0) { - this.stop() - } - }, - }) -} - -function initWordLimit() { - return initLimit({ - count: 1 + roll("1d6"), - init() { - drawLimit(`${this.count} words`) - }, - }) -} - -// -- l/base -function initLimit(limit) { - return { - // props - request: null, - stopped: false, - // override point for one-off limits - init() { - this.start() - }, - // override point for continuous limits - loop() { - }, - // start the loop; probably don't override this - start() { - const thiz = this - - function loop() { - if (!thiz.stopped) { - thiz.loop() - thiz.request = requestAnimationFrame(loop) - } - } - - loop() - }, - // stop the loop; probably don't modify this - stop() { - this.stopped = true - - if (this.request != null) { - cancelAnimationFrame(this.request) - } - }, - ...limit, - } -} - -// -- utilities -- -// a resettable shuffle bag -class Bag { - constructor(items) { - this.items = items - this.reset() - } - - // -- commands -- - // reset the bag's contents - reset() { - this.contents = this.items.slice() - } - - // pull an item out of the bag - draw() { - const i = rand(this.contents.length) - const [item] = this.contents.splice(i, 1) - return item - } - - // -- queries -- - get isEmpty() { - return this.contents.length == 0 - } -} - -// roll dice in the form "3d10" -function roll(str) { - const [count, sides] = str.split("d").map(Number) - - // make the rolls - let total = 0 - for (let i = 0; i < count; i++) { - total += rand(sides) + 1 - } - - return total -} - -function rand(size) { - return Math.floor(Math.random() * size) -} - -function seconds() { - return Math.floor(new Date().getTime() / 1000) -} - -// -- bootstrap -- -init() diff --git a/index.p.html b/index.p.html index 96f9139..481cd03 100644 --- a/index.p.html +++ b/index.p.html @@ -38,6 +38,18 @@

hello web user + + @@ -152,11 +164,7 @@

} function OnDevToggleClicked() { - mInventory.addNamed("devcommentary", { - w: 80, - h: 50, - temperament: "phlegmatic", - }, false) + Frames.show("devcom") } // function OnDevCommentaryChanged() {