From cf207477f10cf16e0fcebb7b1e9ccb9f4172d97b Mon Sep 17 00:00:00 2001 From: Leo dev Date: Wed, 26 Nov 2025 20:13:15 +0100 Subject: [PATCH] Thread engine --- examples/cube.rs | 15 +++++++++---- src/entity.rs | 32 +++++++++++++++------------- src/lib.rs | 55 +++++++++++++++++++++++++++++------------------- 3 files changed, 61 insertions(+), 41 deletions(-) diff --git a/examples/cube.rs b/examples/cube.rs index c89dc24..77fa115 100644 --- a/examples/cube.rs +++ b/examples/cube.rs @@ -1,14 +1,21 @@ -use osmium::terminal; +use osmium::{sleep, terminal}; fn main() { terminal::hide_cursor().unwrap(); - let mut engine = osmium::init(); + let engine = osmium::init(); - engine.thread("Main.tick", || {}); + engine.thread("Main.tick", |engine| { + loop { + engine.tick(); + sleep(4); + } + }); let my_rect = engine.entity(|r| { - r.draw_rect(0, 0, 2, 1, 0x0000ff); + r.draw_rect(0, 0, 1, 2, 0xff0000); + r.draw_rect(1, 0, 1, 2, 0x00ff00); + r.draw_rect(2, 0, 1, 2, 0x0000ff); }); engine.start(); diff --git a/src/entity.rs b/src/entity.rs index 6cd0f2c..33ef37a 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -1,38 +1,40 @@ +use std::sync::{Arc, Mutex}; + use crate::Renderer; -pub trait Component { +pub trait Component: Send + Sync { #[allow(unused_variables)] - fn init_add(&mut self, entity: &mut Entity) {} + fn init_add(&mut self, entity: &Arc) {} #[allow(unused_variables)] - fn init(&mut self, entity: &mut Entity) {} + fn init(&mut self, entity: &Arc) {} #[allow(unused_variables)] - fn tick(&mut self, entity: &mut Entity) {} + fn tick(&mut self, entity: &Arc) {} } pub struct Entity { - components: Vec>, - render: Box, + components: Mutex>>, + render: Box, } impl Entity { - pub fn new(render: F) -> Self { - Self { - components: Vec::new(), + pub fn new(render: F) -> Arc { + Arc::new(Self { + components: Mutex::new(Vec::new()), render: Box::new(render), - } + }) } pub fn component(&mut self, c: C) { - self.components.push(Box::new(c)); + self.components.lock().unwrap().push(Box::new(c)); } - pub fn render(&mut self, renderer: &mut Renderer) { + pub fn render(self: &Arc, renderer: &mut Renderer) { (self.render)(renderer) } - pub fn tick(&mut self) { - for comp in &mut self.components { - // comp.tick(self); + pub fn tick(self: &Arc) { + for comp in self.components.lock().unwrap().iter_mut() { + comp.tick(self); } } } diff --git a/src/lib.rs b/src/lib.rs index 24fcbdb..257f238 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,20 +2,23 @@ pub mod entity; pub mod renderer; pub mod terminal; -use std::collections::HashMap; +use std::{ + collections::HashMap, + sync::{Arc, Mutex}, +}; use crate::renderer::Renderer; -pub fn init() -> Engine { - Engine { - threads: HashMap::new(), - entities: Vec::new(), - } +pub fn init() -> Arc { + Arc::new(Engine { + threads: Mutex::new(HashMap::new()), + entities: Mutex::new(Vec::new()), + }) } pub struct Engine { - threads: HashMap>, - entities: Vec, + threads: Mutex) + Send + Sync>>>, + entities: Mutex>>, } pub fn sleep(ms: u64) { @@ -23,38 +26,46 @@ pub fn sleep(ms: u64) { } impl Engine { - pub fn thread(&mut self, label: &str, f: F) { - self.threads.insert(label.to_string(), Box::new(f)); + pub fn thread) + Send + Sync + 'static>(self: &Arc, label: &str, f: F) { + self.threads + .lock() + .unwrap() + .insert(label.to_string(), Arc::new(f)); } - pub fn entity(&mut self, f: F) -> &mut entity::Entity { + pub fn entity( + self: &Arc, + f: F, + ) -> Arc { let e = entity::Entity::new(f); - self.entities.push(e); - self.entities + let mut entities = self.entities.lock().unwrap(); + entities.push(e); + entities .last_mut() .expect("Unable to obtain entity (unspawned)") + .clone() } - pub fn render(&mut self) { + pub fn render(self: &Arc) { terminal::clear().unwrap(); let mut renderer = renderer::Renderer::new(); - for entity in &mut self.entities { + for entity in self.entities.lock().unwrap().iter() { entity.render(&mut renderer); } } - pub fn tick(&mut self) { - terminal::clear().unwrap(); - - for entity in &mut self.entities { + pub fn tick(self: &Arc) { + for entity in self.entities.lock().unwrap().iter() { entity.tick(); } } - pub fn start(&mut self) { - for thr in &mut self.threads.values() { - // std::thread::spawn(thr); + pub fn start(self: &Arc) { + for thr in self.threads.lock().unwrap().values() { + let thr = thr.clone(); + let engine = self.clone(); + std::thread::spawn(move || (thr)(&engine)); } loop {