[oden] Oh boy here we go

This commit is contained in:
John Doty 2023-06-21 21:57:32 -07:00
parent 8218b88820
commit 14f9eb655f
4 changed files with 206 additions and 31 deletions

93
src/script/graphics.rs Normal file
View file

@ -0,0 +1,93 @@
use oden_js::{module, ContextRef, Error, Value, ValueRef, ValueResult};
use std::sync::mpsc::Sender;
use std::sync::Arc;
pub struct PrintCommand {
pub text: String,
}
pub struct ClearCommand {
pub color: [f64; 4],
}
pub enum GraphicsCommand {
Clear(ClearCommand),
Print(PrintCommand),
EndFrame,
}
const MAGIC_VALUE: u64 = 0xABCDB00BABCDBEEB;
struct GraphicsImpl {
magic: u64,
sender: Sender<GraphicsCommand>,
}
impl GraphicsImpl {
pub fn new(sender: Sender<GraphicsCommand>) -> Self {
GraphicsImpl {
magic: MAGIC_VALUE,
sender,
}
}
fn print_fn(&self, ctx: &ContextRef, args: &[&ValueRef]) -> ValueResult {
assert_eq!(self.magic, MAGIC_VALUE);
let mut text = String::with_capacity(128);
for arg in args {
let v = arg.to_string(ctx)?;
text.push_str(&v);
}
let _ = self
.sender
.send(GraphicsCommand::Print(PrintCommand { text }));
Ok(Value::undefined(ctx))
}
fn cls_fn(&self, ctx: &ContextRef, args: &[&ValueRef]) -> ValueResult {
assert_eq!(self.magic, MAGIC_VALUE);
if args.len() != 3 {
return Err(Error::ArgumentCountMismatch {
expected: 3,
received: args.len(),
});
}
let r = args[0].to_float64(&ctx)?;
let g = args[1].to_float64(&ctx)?;
let b = args[1].to_float64(&ctx)?;
let _ = self.sender.send(GraphicsCommand::Clear(ClearCommand {
color: [r, g, b, 1.0],
}));
Ok(Value::undefined(ctx))
}
}
pub struct GraphicsAPI {
gfx: Arc<GraphicsImpl>,
}
impl GraphicsAPI {
pub fn define(ctx: &ContextRef, sender: Sender<GraphicsCommand>) -> oden_js::Result<Self> {
let gfx = Arc::new(GraphicsImpl::new(sender));
let gfx_a = gfx.clone();
let gfx_b = gfx.clone();
module::NativeModuleBuilder::new(ctx)
.export(
"print",
ctx.new_dynamic_fn(move |ctx, _, args| gfx_a.print_fn(ctx, args))?,
)?
.export(
"cls",
ctx.new_dynamic_fn(move |ctx, _, args| gfx_b.cls_fn(ctx, args))?,
)?
.build("graphics")?;
Ok(GraphicsAPI { gfx })
}
pub fn end_frame(&self) {
let _ = self.gfx.sender.send(GraphicsCommand::EndFrame);
}
}