introduce tags, structs, and reticles

this was meant to be split into smaller changes, but I realised I edited my existing revision too late.
This commit is contained in:
りき萌 2024-09-08 13:53:29 +02:00
parent 8356b6c750
commit 5b7d9586ea
26 changed files with 1113 additions and 351 deletions

View file

@ -0,0 +1,78 @@
use tiny_skia::Pixmap;
use crate::{
render::{Renderer, RendererLimits},
system::System,
value::{Ref, Reticle, Value, Vec2},
vm::{Exception, Vm},
};
#[derive(Debug, Clone, Copy)]
pub struct Trampoline {
pub value: Value,
}
// NOTE: This must be kept in sync with haku.js.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Cont {
Scribble,
Dotter,
}
impl Trampoline {
pub fn new(init: Value) -> Self {
Self { value: init }
}
pub fn cont(&self, vm: &Vm) -> Cont {
let Some((_, refv)) = vm.get_ref_value(self.value) else {
return Cont::Scribble;
};
match refv {
Ref::Reticle(_) => Cont::Dotter,
_ => Cont::Scribble,
}
}
pub fn scribble(
&mut self,
vm: &Vm,
pixmap: &mut Pixmap,
translation: Vec2,
limits: &RendererLimits,
) -> Result<(), Exception> {
let mut renderer = Renderer::new(&mut *pixmap, limits);
renderer.translate(translation.x, translation.y);
renderer.render(vm, self.value)
}
pub fn dotter(
&mut self,
vm: &mut Vm,
system: &System,
from: Vec2,
to: Vec2,
num: f32,
) -> Result<(), Exception> {
let (_, vref) = vm.get_ref_value(self.value).expect("value must be a ref");
let &Ref::Reticle(Reticle::Dotter {
draw: Value::Ref(draw_id),
}) = vref
else {
panic!("value must be a dotter reticle");
};
let dotter = vm.create_ref(Ref::Closure(system.create_dotter(
from.into(),
to.into(),
num,
)))?;
let value = vm.run(system, draw_id, &[Value::Ref(dotter)])?;
self.value = value;
Ok(())
}
}