use eclisp::{Lisp, LispClass, LispError, lisp_impl};
#[derive(LispClass)]
#[lisp(name = "transform", auto)]
struct Transform {
x: f32,
y: f32,
}
#[derive(LispClass)]
#[lisp(name = "player", impl)]
struct Player {
#[lisp]
health: i32,
#[lisp(ref)]
transform: Transform,
}
#[lisp_impl]
impl Player {
#[method]
fn transform_ref(&mut self) -> &mut Transform {
&mut self.transform
}
}
fn main() -> Result<(), LispError> {
let lisp = Lisp::new()?;
lisp.enter(|ctx| {
ctx.defclass(Transform::class())?;
ctx.defclass(Player::class())?;
ctx.eval(
r#"
(defun move-player (player)
(let ((transform (player-transform player)))
(incf (transform-x transform) 5.0)
(incf (transform-y transform) 10.0)))
"#,
)?;
let mut player = Player {
health: 100,
transform: Transform { x: 1.0, y: 2.0 },
};
println!("Player before:");
println!(" Health: {}", player.health);
println!(
" Position: ({}, {})",
player.transform.x, player.transform.y
);
ctx.with(&mut player, |obj| {
ctx.call("move-player", &[obj])?;
let transform = ctx.call("player-transform-ref", &[obj])?;
let x = ctx.call("transform-x", &[&transform])?;
let y = ctx.call("transform-y", &[&transform])?;
println!(
"Position through Lisp: ({}, {})",
x.try_as_f64()?,
y.try_as_f64()?
);
Ok::<(), LispError>(())
})?;
println!("\nPlayer after:");
println!(" Health: {}", player.health);
println!(
" Position: ({}, {})",
player.transform.x, player.transform.y
);
Ok::<(), LispError>(())
})
}