Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement control_forever & stop button, and fix motion_gotoxy #7

Merged
merged 5 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading