khors/modules/khors-steel/src/lib.rs

103 lines
2.7 KiB
Rust
Raw Normal View History

2024-04-01 20:51:39 -06:00
extern crate khors_core;
use flax::{component, BoxedSystem, EntityBorrow, Query, QueryBorrow, Schedule, System, World};
2024-04-01 20:51:39 -06:00
use khors_core::module::Module;
use steel::steel_vm::engine::Engine;
use steel_derive::Steel;
component! {
steel_script: String,
steel_event_tx: flume::Sender<SteelEvent>,
resources,
}
pub fn execute_script_system() -> BoxedSystem {
let tx_query = Query::new(steel_event_tx()).entity(resources());
let script_query = Query::new(steel_script());
System::builder()
.with_query(tx_query)
.with_query(script_query)
.build(|mut tx_query: EntityBorrow<'_, flax::Component<flume::Sender<SteelEvent>>>, mut script_query: QueryBorrow<flax::Component<String>>| {
if let Ok(tx) = tx_query.get() {
for script in &mut script_query {
println!("Got script and tx");
tx.send(SteelEvent::Execute(script.into())).unwrap();
}
}
})
.boxed()
}
#[derive(Debug, Steel)]
enum SteelEvent {
Execute(String),
}
#[allow(dead_code)]
#[derive(Steel, Clone)]
pub struct SteelModule {
engine: Engine,
// schedule: Schedule,
rx: flume::Receiver<SteelEvent>,
}
impl SteelModule {
pub fn new(
schedule: &mut Schedule,
world: &mut World,
2024-04-01 20:51:39 -06:00
_events: &mut khors_core::events::Events,
) -> Self {
2024-04-01 20:51:39 -06:00
let engine = Engine::new();
let (tx, rx) = flume::unbounded::<SteelEvent>();
let schedule_r = Schedule::builder()
.with_system(execute_script_system())
.build();
schedule.append(schedule_r);
world.set(resources(), steel_event_tx(), tx).unwrap();
// Some testing
let entity = world.spawn();
world.set(entity, steel_script(), r#"
(require-builtin steel/time)
(display "Hello ")
(time/sleep-ms 5000)
(display "World!")"#.into()).unwrap();
Self {
engine,
// schedule,
rx,
}
}
}
impl Module for SteelModule {
fn on_update(
&mut self,
2024-04-01 20:51:39 -06:00
_world: &mut World,
_events: &mut khors_core::events::Events,
_frame_time: std::time::Duration,
) -> anyhow::Result<()> {
// self.schedule.execute_par(world).unwrap();
if let Ok(event) = self.rx.recv() {
match event {
SteelEvent::Execute(script) => {
2024-04-01 20:51:39 -06:00
let _handle = std::thread::spawn(|| {
let mut engine = Engine::new();
let val = engine.run(script).unwrap();
println!("Steel val: {:?}", val);
});
}
}
}
Ok(())
}
}