Thread engine

This commit is contained in:
2025-11-26 20:13:15 +01:00
parent 23144fb802
commit cf207477f1
3 changed files with 61 additions and 41 deletions
+11 -4
View File
@@ -1,14 +1,21 @@
use osmium::terminal; use osmium::{sleep, terminal};
fn main() { fn main() {
terminal::hide_cursor().unwrap(); 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| { 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(); engine.start();
+17 -15
View File
@@ -1,38 +1,40 @@
use std::sync::{Arc, Mutex};
use crate::Renderer; use crate::Renderer;
pub trait Component { pub trait Component: Send + Sync {
#[allow(unused_variables)] #[allow(unused_variables)]
fn init_add(&mut self, entity: &mut Entity) {} fn init_add(&mut self, entity: &Arc<Entity>) {}
#[allow(unused_variables)] #[allow(unused_variables)]
fn init(&mut self, entity: &mut Entity) {} fn init(&mut self, entity: &Arc<Entity>) {}
#[allow(unused_variables)] #[allow(unused_variables)]
fn tick(&mut self, entity: &mut Entity) {} fn tick(&mut self, entity: &Arc<Entity>) {}
} }
pub struct Entity { pub struct Entity {
components: Vec<Box<dyn Component>>, components: Mutex<Vec<Box<dyn Component>>>,
render: Box<dyn FnMut(&mut Renderer)>, render: Box<dyn Fn(&mut Renderer) + Send + Sync>,
} }
impl Entity { impl Entity {
pub fn new<F: FnMut(&mut Renderer) + 'static>(render: F) -> Self { pub fn new<F: Fn(&mut Renderer) + Send + Sync + 'static>(render: F) -> Arc<Self> {
Self { Arc::new(Self {
components: Vec::new(), components: Mutex::new(Vec::new()),
render: Box::new(render), render: Box::new(render),
} })
} }
pub fn component<C: Component + 'static>(&mut self, c: C) { pub fn component<C: Component + 'static>(&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<Self>, renderer: &mut Renderer) {
(self.render)(renderer) (self.render)(renderer)
} }
pub fn tick(&mut self) { pub fn tick(self: &Arc<Self>) {
for comp in &mut self.components { for comp in self.components.lock().unwrap().iter_mut() {
// comp.tick(self); comp.tick(self);
} }
} }
} }
+33 -22
View File
@@ -2,20 +2,23 @@ pub mod entity;
pub mod renderer; pub mod renderer;
pub mod terminal; pub mod terminal;
use std::collections::HashMap; use std::{
collections::HashMap,
sync::{Arc, Mutex},
};
use crate::renderer::Renderer; use crate::renderer::Renderer;
pub fn init() -> Engine { pub fn init() -> Arc<Engine> {
Engine { Arc::new(Engine {
threads: HashMap::new(), threads: Mutex::new(HashMap::new()),
entities: Vec::new(), entities: Mutex::new(Vec::new()),
} })
} }
pub struct Engine { pub struct Engine {
threads: HashMap<String, Box<dyn FnMut() + Send + Sync>>, threads: Mutex<HashMap<String, Arc<dyn Fn(&Arc<Self>) + Send + Sync>>>,
entities: Vec<entity::Entity>, entities: Mutex<Vec<Arc<entity::Entity>>>,
} }
pub fn sleep(ms: u64) { pub fn sleep(ms: u64) {
@@ -23,38 +26,46 @@ pub fn sleep(ms: u64) {
} }
impl Engine { impl Engine {
pub fn thread<F: FnMut() + Send + Sync + 'static>(&mut self, label: &str, f: F) { pub fn thread<F: Fn(&Arc<Self>) + Send + Sync + 'static>(self: &Arc<Self>, label: &str, f: F) {
self.threads.insert(label.to_string(), Box::new(f)); self.threads
.lock()
.unwrap()
.insert(label.to_string(), Arc::new(f));
} }
pub fn entity<F: FnMut(&mut Renderer) + 'static>(&mut self, f: F) -> &mut entity::Entity { pub fn entity<F: Fn(&mut Renderer) + Send + Sync + 'static>(
self: &Arc<Self>,
f: F,
) -> Arc<entity::Entity> {
let e = entity::Entity::new(f); let e = entity::Entity::new(f);
self.entities.push(e); let mut entities = self.entities.lock().unwrap();
self.entities entities.push(e);
entities
.last_mut() .last_mut()
.expect("Unable to obtain entity (unspawned)") .expect("Unable to obtain entity (unspawned)")
.clone()
} }
pub fn render(&mut self) { pub fn render(self: &Arc<Self>) {
terminal::clear().unwrap(); terminal::clear().unwrap();
let mut renderer = renderer::Renderer::new(); let mut renderer = renderer::Renderer::new();
for entity in &mut self.entities { for entity in self.entities.lock().unwrap().iter() {
entity.render(&mut renderer); entity.render(&mut renderer);
} }
} }
pub fn tick(&mut self) { pub fn tick(self: &Arc<Self>) {
terminal::clear().unwrap(); for entity in self.entities.lock().unwrap().iter() {
for entity in &mut self.entities {
entity.tick(); entity.tick();
} }
} }
pub fn start(&mut self) { pub fn start(self: &Arc<Self>) {
for thr in &mut self.threads.values() { for thr in self.threads.lock().unwrap().values() {
// std::thread::spawn(thr); let thr = thr.clone();
let engine = self.clone();
std::thread::spawn(move || (thr)(&engine));
} }
loop { loop {