From 50fa0f5258b3b0b9905e623a471058682f77cd99 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Sun, 5 Jul 2026 09:55:02 -0400 Subject: [PATCH] Revert "wip timeline" This reverts commit be29c0138da771561a7c8ade128137b666b82bda. --- index.html | 141 +++++++++++++++++++++++++++++++--------------------- timeline.js | 119 -------------------------------------------- 2 files changed, 83 insertions(+), 177 deletions(-) delete mode 100644 timeline.js diff --git a/index.html b/index.html index 803c21ca..f8558483 100644 --- a/index.html +++ b/index.html @@ -129,7 +129,6 @@ import {Engine} from './engine.js'; import {Diorama} from './diorama.js'; import {World} from './world.js'; - import {Timeline} from './timeline.js'; async function initDocument() { try { @@ -158,6 +157,37 @@ world1.set('lodestone', 0, -1, 0); world1.set('piston', 0, -2, 0, {facing: 'north', extended: 'false'}); + const world2 = new World(); + world2.set('minecraft:redstone_wire', 0, 0, 0, { + east: 'side', + west: 'none', + north: 'none', + south: 'none', + power: '0' + }); + world2.set('minecraft:repeater', 1, 0, 0, { + facing: 'east', + delay: '4', + locked: 'false', + powered: 'false' + }); + world2.set('minecraft:sticky_piston', 2, 0, 0, {facing: 'east', extended: 'false'}); + world2.set('minecraft:sticky_piston', 2, 0, 1, {facing: 'east', extended: 'true'}); + world2.set('minecraft:sticky_piston', 2, 0, 2, {facing: 'east', extended: 'true'}); + world2.set('minecraft:piston_head', 2.5, 0, 1, { + facing: 'east', + short: 'true', + type: 'sticky' + }); + world2.set('minecraft:piston_head', 3, 0, 2, { + facing: 'east', + short: 'false', + type: 'sticky' + }); + world2.set('minecraft:glass', 3, 0, 0); + world2.set('minecraft:observer', 3.5, 0, 1, {facing: 'up', powered: 'true'}); + world2.set('minecraft:redstone_block', 4, 0, 2); + const demo1 = new Diorama('demo-1', world1, () => engine.requestRender()) demo1.radius = 2; demo1.phi = 10; @@ -166,75 +196,70 @@ demo1.saveState() engine.addDiorama(demo1); - const world2 = new World(); - - // Initialize the Timeline and compile the scene/animation - const timeline = new Timeline(world2); - timeline.compile(` - @-1 - place 0 0 0 minecraft:redstone_wire power=0 east=side west=none north=none south=none - place 1 0 0 minecraft:repeater facing=east delay=4 locked=false powered=false - place 2 0 0 minecraft:sticky_piston facing=east extended=false - place 2 0 1 minecraft:sticky_piston facing=east extended=true - place 2 0 2 minecraft:sticky_piston facing=east extended=true - place 2.5 0 1 minecraft:piston_head facing=east short=true type=sticky - place 3 0 2 minecraft:piston_head facing=east short=false type=sticky - place 3 0 0 minecraft:glass - place 3.5 0 1 minecraft:observer facing=up powered=true - place 4 0 2 minecraft:redstone_block - - @0 - update 2 0 2 extended=false - place 3 0 2 minecraft:redstone_block - del 2.5 0 2 - del 3.5 0 2 - - @1 - update 2 0 2 extended=true - del 3 0 2 - place 2.5 0 2 minecraft:piston_head facing=east short=true type=sticky - place 3.5 0 2 minecraft:redstone_block - - @2 - place 3 0 2 minecraft:piston_head facing=east short=false type=sticky - del 2.5 0 2 - del 3.5 0 2 - place 4 0 2 minecraft:redstone_block - - @3 - del 4 0 2 - del 3 0 2 - place 2.5 0 2 minecraft:piston_head facing=east short=true type=sticky - place 3.5 0 2 minecraft:redstone_block - `); - - // Load the initial layout - timeline.seek(0); - - const demo2 = new Diorama('demo-2', world2, () => engine.requestRender()); + const demo2 = new Diorama('demo-2', world2, () => engine.requestRender()) demo2.radius = 4; demo2.theta = 180; demo2.phi = 90; - demo2.centerView(); - demo2.saveState(); + demo2.centerView() + demo2.saveState() engine.addDiorama(demo2); - const demo3 = new Diorama('demo-3', world2, () => engine.requestRender()); + const demo3 = new Diorama('demo-3', world2, () => engine.requestRender()) demo3.radius = 4; demo3.theta = 0; demo3.phi = 0; - demo3.centerView(); - demo3.saveState(); + demo3.centerView() + demo3.saveState() engine.addDiorama(demo3); + // Fetch and build everything concurrently! await engine.updateAll(); - // Manually cycle through the timeline ticks for the demo - let currentTick = 0; - setInterval(() => { - timeline.seek(currentTick); - currentTick = (currentTick + 1) % 4; - }, 1000); + function set0() { + world2.set('minecraft:sticky_piston', 2, 0, 2, {facing: 'east', extended: 'false'}); + world2.set('minecraft:redstone_block', 3, 0, 2); + world2.del(2.5, 0, 2); + world2.del(3.5, 0, 2); + setTimeout(set1, 250) + } + + function set1() { + world2.set('minecraft:sticky_piston', 2, 0, 2, {facing: 'east', extended: 'true'}); + world2.del(3, 0, 2) + world2.set('minecraft:piston_head', 2.5, 0, 2, { + facing: 'east', + short: 'true', + type: 'sticky' + }); + world2.set('minecraft:redstone_block', 3.5, 0, 2); + setTimeout(set2, 250) + } + + function set2() { + world2.set('minecraft:piston_head', 3, 0, 2, { + facing: 'east', + short: 'false', + type: 'sticky' + }); + world2.del(2.5, 0, 2); + world2.del(3.5, 0, 2); + world2.set('minecraft:redstone_block', 4, 0, 2); + setTimeout(set3, 250) + } + + function set3() { + world2.del(4, 0, 2) + world2.del(3, 0, 2) + world2.set('minecraft:piston_head', 2.5, 0, 2, { + facing: 'east', + short: 'true', + type: 'sticky' + }); + world2.set('minecraft:redstone_block', 3.5, 0, 2); + setTimeout(set0, 250) + } + + setTimeout(set3, 1000) } catch (err) { console.error("Renderer Initialization Failed:", err); } diff --git a/timeline.js b/timeline.js deleted file mode 100644 index 6668c093..00000000 --- a/timeline.js +++ /dev/null @@ -1,119 +0,0 @@ -// timeline.js - -export class Timeline { - constructor(world) { - this.world = world; - this.events = []; - this.cursorIndex = 0; - this.currentTime = -1; - } - - /** - * Parses the custom syntax and builds the reversible event array. - */ - compile(script) { - this.events = []; - let currentTime = 0; - let subTick = 0; - - // We use a shadow map to track what the world *will* look like - // at any point during parsing, so we can capture accurate undo states. - const shadowWorld = new Map(); - - const lines = script.split('\n').map(l => l.trim()).filter(l => l && !l.startsWith('#')); - - for (const line of lines) { - if (line.startsWith('@')) { - currentTime = parseFloat(line.substring(1)); - subTick = 0; - continue; - } - - const tokens = line.split(' '); - const action = tokens[0]; - const x = parseFloat(tokens[1]); - const y = parseFloat(tokens[2]); - const z = parseFloat(tokens[3]); - const key = `${x},${y},${z}`; - - const propsArray = tokens.slice(action === 'place' ? 5 : 4); - const state = {}; - for (const prop of propsArray) { - const [k, v] = prop.split('='); - state[k] = v; - } - - // Capture the current shadow state for the undo action - const prevState = shadowWorld.has(key) ? JSON.parse(JSON.stringify(shadowWorld.get(key))) : null; - - if (action === 'place') { - const id = tokens[4]; - const blockData = { id, state }; - - // Update shadow world - shadowWorld.set(key, blockData); - - this.events.push({ - time: currentTime, - subTick: subTick++, - forward: (world) => world.set(id, x, y, z, { ...state }), - backward: (world) => { - if (prevState) world.set(prevState.id, x, y, z, { ...prevState.state }); - else world.del(x, y, z); - } - }); - - } else if (action === 'update') { - // Update shadow world - if (shadowWorld.has(key)) { - const block = shadowWorld.get(key); - Object.assign(block.state, state); - } - - this.events.push({ - time: currentTime, - subTick: subTick++, - forward: (world) => { - const block = world.get(x, y, z); - if (block) world.set(block.id, x, y, z, { ...block.state, ...state }); - }, - backward: (world) => { - if (prevState) world.set(prevState.id, x, y, z, { ...prevState.state }); - } - }); - } else if (action === 'del') { - shadowWorld.delete(key); - - this.events.push({ - time: currentTime, - subTick: subTick++, - forward: (world) => world.del(x, y, z), - backward: (world) => { - if (prevState) world.set(prevState.id, x, y, z, { ...prevState.state }); - } - }); - } - } - } - - /** - * Scrubs the timeline to an exact tick, resolving all forward and backward - * events deterministically based on their sub-tick ordering. - */ - seek(targetTime) { - // Scrub Forward - while (this.cursorIndex < this.events.length && this.events[this.cursorIndex].time <= targetTime) { - this.events[this.cursorIndex].forward(this.world); - this.cursorIndex++; - } - - // Scrub Backward - // Notice the strictly reverse evaluation order - while (this.cursorIndex > 0 && this.events[this.cursorIndex - 1].time > targetTime) { - this.cursorIndex--; - this.events[this.cursorIndex].backward(this.world); - } - - this.currentTime = targetTime; - } -} \ No newline at end of file