Skip to content

Commit

Permalink
implement control_forever & stop button, and fix motion_gotoxy (#7)
Browse files Browse the repository at this point in the history
* implement control_forever

* fix motion_gotoxy

* code cleanup

* add more blocks that request redraw

* remove unneeded logs
  • Loading branch information
pufferfish101007 committed Jan 17, 2024
1 parent af3d383 commit 1548330
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 99 deletions.
5 changes: 4 additions & 1 deletion playground/components/ProjectPlayer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<!--<template v-else>-->
<br>
<br>
<button @click="greenFlag">green flag</button> <button>stop</button>
<button @click="greenFlag">green flag</button> <button @click="stop">stop</button>
<canvas width="480" height="360" ref="canvas"></canvas>
<div id="hq-output">Project output:<br></div>
<!--</template>-->
Expand Down Expand Up @@ -55,6 +55,9 @@
}
});
}
function stop() {
window.stop()
}
</script>

<style scoped>
Expand Down
94 changes: 7 additions & 87 deletions playground/lib/project-runner.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { memoryUsage } from "node:process";

function createSkin(renderer, type, layer, ...params) {
let drawable = renderer.createDrawable(layer.toString());
let skin = renderer[`create${type}Skin`](...params);
Expand All @@ -26,18 +24,6 @@ export default (
window.renderer = renderer;
renderer.setLayerGroupOrdering(["background", "video", "pen", "sprite"]);
//window.open(URL.createObjectURL(new Blob([wasm_bytes], { type: "octet/stream" })));
let sprite_info = Array.from({ length: target_names.length }, (_) => ({
x: 0,
y: 0,
pen: {
color: 66.66,
saturation: 100,
brightness: 100,
transparency: 0,
color4f: [0, 0, 1, 1],
size: 1,
},
}));
const pen_skin = createSkin(renderer, "Pen", "pen");
if (typeof require === "undefined") {
browser = true;
Expand Down Expand Up @@ -99,21 +85,9 @@ export default (
`\x1b[1;32m${targetName} ${verb}:\x1b[0m \x1b[35m${text}\x1b[0m`
);
} else {
//output_div.appendChild(text_div(`${targetName} ${verb}: ${text}`));
renderer.updateTextSkin(renderBubble, verb, text, false);
}
};
/*function updatePenColor(i) {
const rgb = hsvToRgb({
h: (sprite_info[i].pen.color * 360) / 100,
s: sprite_info[i].pen.saturation / 100,
v: sprite_info[i].pen.brightness / 100,
});
sprite_info[i].pen.color4f[0] = rgb.r / 255.0;
sprite_info[i].pen.color4f[1] = rgb.g / 255.0;
sprite_info[i].pen.color4f[2] = rgb.b / 255.0;
sprite_info[i].pen.color4f[3] = 1 - sprite_info[i].pen.transparency / 100;
}*/
let updatePenColor;
let start_time = 0;
let sprite_info_offset = 0;
Expand All @@ -129,11 +103,9 @@ export default (
},
runtime: {
looks_say: (ty, val, targetIndex) => {
console.log("a");
targetOutput(targetIndex, "say", wasm_val_to_js(ty, val));
},
looks_think: (ty, val, targetIndex) => {
console.log("b");
targetOutput(targetIndex, "think", wasm_val_to_js(ty, val));
},
operator_equals: (ty1, val1, ty2, val2) => {
Expand Down Expand Up @@ -189,9 +161,7 @@ export default (
renderer.penPoint(
pen_skin,
{
//diameter: sprite_info[i].pen.size * 2,
diameter: radius * 1,
//color4f: sprite_info[i].pen.color4f,
diameter: radius, // awkward variable naming moment
color4f: [r, g, b, a],
},
x,
Expand All @@ -209,72 +179,39 @@ export default (
pen_setcolor: () => null,
pen_changecolorparam: () => null,
pen_setcolorparam: (param, val, i) => {
console.log(
"pensetcolorparam",
Array.from({ length: 14 }, (_, j) =>
new DataView(memory.buffer).getFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + j * 4,
true
)
)
);
switch (param) {
case "color":
new DataView(memory.buffer).setFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + 16,
val,
true
);
//sprite_info[i].pen.color = val;
break;
case "saturation":
new DataView(memory.buffer).setFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + 20,
val,
true
);
//sprite_info[i].pen.saturation = val;
break;
case "brightness":
new DataView(memory.buffer).setFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + 24,
val,
true
);
//sprite_info[i].pen.brightness = val;
break;
case "transparency":
new DataView(memory.buffer).setFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + 28,
val,
true
);
//sprite_info[i].pen.transparency = val;
break;
default:
console.warn(`can\'t update invalid color param ${param}`);
}
console.log(
"pensetcolorparam",
Array.from({ length: 14 }, (_, j) =>
new DataView(memory.buffer).getFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + j * 4,
true
)
),
[]
);
updatePenColor(i);
console.log(
"pensetcolorparam",
Array.from({ length: 14 }, (_, j) =>
new DataView(memory.buffer).getFloat32(
sprite_info_offset + (i - 1) * spriteInfoLen + j * 4,
true
)
),
[]
);
},
pen_changesize: () => null,
pen_changehue: () => null,
Expand All @@ -286,7 +223,6 @@ export default (
floattostring: Number.prototype.toString,
},
};
//const buf = new Uint8Array(wasm_bytes);
try {
assert(WebAssembly.validate(wasm_bytes));
} catch {
Expand Down Expand Up @@ -324,18 +260,18 @@ export default (
// @ts-ignore
strings.set(i, str);
}
console.log([...new Uint8Array(memory.buffer.slice(0, 256))]);
updatePenColor = (i) => upc(i - 1);
strings_tbl = strings;
window.memory = memory;
window.stop = () => {
for (let i = 0; i < new Uint32Array(memory.buffer)[thn_offset.value / 4]; i++) {
new Uint32Array(memory.buffer)[(i + sprite_info_offset + spriteInfoLen * (target_names.length - 1)) / 4] = 0;
}
};
// @ts-ignore
sprite_info_offset = vars_num.value * 12 + thn_offset + 4;
const dv = new DataView(memory.buffer);
for (let i = 0; i < target_names.length - 1; i++) {
console.log(
sprite_info_offset + i * spriteInfoLen + 16,
(sprite_info_offset + i * spriteInfoLen + 16) / 4
);
dv.setFloat32(
sprite_info_offset + i * spriteInfoLen + 16,
66.66,
Expand All @@ -348,38 +284,23 @@ export default (
dv.setFloat32(sprite_info_offset + i * spriteInfoLen + 44, 1, true);
dv.setFloat64(sprite_info_offset + i * spriteInfoLen + 48, 1, true);
}
console.log(
"hola",
Array.from({ length: 64 }, (_, i) =>
new DataView(memory.buffer).getFloat32(i * 4, true)
)
);
console.log(`sprite_info_offset + 16: ${sprite_info_offset + 16}`);
/*resolve({ strings, green_flag, step_funcs, tick, memory })*/ // @ts-ignore
green_flag();
console.log([...new Uint8Array(memory.buffer.slice(0, 256))]);
start_time = Date.now();
console.log("green_flag()");
$outertickloop: while (true) {
console.log([...new Uint8Array(memory.buffer.slice(0, 256))]);
// console.log(new Uint32Array(memory.buffer)[thn_offset.value / 4])
renderer.draw();
// console.log('outer')
const thisTickStartTime = Date.now();
// @ts-ignore
$innertickloop: while (
Date.now() - thisTickStartTime < 23 &&
new Uint8Array(memory.buffer)[rr_offset.value] === 0
) {
//console.log('inner')
){//for (const _ of [1]) {
// @ts-ignore
console.log([...new Uint8Array(memory.buffer.slice(0, 256))]);
tick();
// @ts-ignore
if (new Uint32Array(memory.buffer)[thn_offset.value / 4] === 0) {
break $outertickloop;
}
//console.log([...new Uint8Array(memory.buffer.slice(0, 1000))]);
}
// @ts-ignore
new Uint8Array(memory.buffer)[rr_offset.value] = 0;
Expand All @@ -390,7 +311,6 @@ export default (
} else {
await waitAnimationFrame();
}
console.log([...new Uint8Array(memory.buffer.slice(0, 256))]);
}
})
.catch((e) => {
Expand Down
31 changes: 31 additions & 0 deletions src/ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,9 @@ impl IrBlock {
does_yield: true,
..
}
| motion_gotoxy
| pen_penDown
| pen_clear
)
}
pub fn is_hat(&self) -> bool {
Expand Down Expand Up @@ -883,6 +886,34 @@ impl IrBlockVec for Vec<IrBlock> {
IrOpcode::hq_goto { step: Some((target_id, substack_id)), does_yield: false },
]
}
BlockOpcode::control_forever => {
let substack_id = if let BlockArrayOrId::Id(id) = block_info.inputs.get("SUBSTACK").expect("missing SUBSTACK input for control_if").get_1().unwrap().clone().unwrap() { id } else { panic!("malformed SUBSTACK input") };
let mut condition_opcodes = vec![
//IrOpcode::hq_goto_if { step: Some((target_id.clone(), block_info.next.clone().unwrap())), does_yield: true }.into(),
IrOpcode::hq_goto { step: Some((target_id.clone(), substack_id.clone())), does_yield: true }.into(),
];
let looper_id = Uuid::new_v4().to_string();
if !steps.contains_key(&(target_id.clone(), looper_id.clone())) {
let mut looper_opcodes = vec![];
//looper_opcodes.add_inputs(&block_info.inputs, blocks, Rc::clone(&context), steps, target_id.clone());
looper_opcodes.append(&mut condition_opcodes.clone());
looper_opcodes.fixup_types();
steps.insert((target_id.clone(), looper_id.clone()), Step::new(looper_opcodes, Rc::clone(&context)));
}
if let Some(next) = block_info.next.clone() {
step_from_top_block(next, last_nexts, blocks, Rc::clone(&context), steps, target_id.clone());
}
step_from_top_block(substack_id.clone(), vec![looper_id], blocks, Rc::clone(&context), steps, target_id.clone());
let mut opcodes = vec![];
//opcodes.add_inputs(&block_info.inputs, blocks, Rc::clone(&context), steps, target_id.clone());
opcodes.append(&mut condition_opcodes);
opcodes.fixup_types();
steps.insert((target_id.clone(), block_id.clone()), Step::new(opcodes.clone(), Rc::clone(&context)));
vec![
//IrOpcode::hq_goto_if { step: Some((target_id.clone(), block_info.next.clone().unwrap())), does_yield: true },
IrOpcode::hq_goto { step: Some((target_id, substack_id)), does_yield: false },
]
}
_ => todo!(),
}).into_iter().map(IrBlock::from).collect());
}
Expand Down
Loading

0 comments on commit 1548330

Please sign in to comment.