Thread engine
This commit is contained in:
+11
-4
@@ -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();
|
||||
|
||||
+17
-15
@@ -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<Entity>) {}
|
||||
#[allow(unused_variables)]
|
||||
fn init(&mut self, entity: &mut Entity) {}
|
||||
fn init(&mut self, entity: &Arc<Entity>) {}
|
||||
#[allow(unused_variables)]
|
||||
fn tick(&mut self, entity: &mut Entity) {}
|
||||
fn tick(&mut self, entity: &Arc<Entity>) {}
|
||||
}
|
||||
|
||||
pub struct Entity {
|
||||
components: Vec<Box<dyn Component>>,
|
||||
render: Box<dyn FnMut(&mut Renderer)>,
|
||||
components: Mutex<Vec<Box<dyn Component>>>,
|
||||
render: Box<dyn Fn(&mut Renderer) + Send + Sync>,
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
pub fn new<F: FnMut(&mut Renderer) + 'static>(render: F) -> Self {
|
||||
Self {
|
||||
components: Vec::new(),
|
||||
pub fn new<F: Fn(&mut Renderer) + Send + Sync + 'static>(render: F) -> Arc<Self> {
|
||||
Arc::new(Self {
|
||||
components: Mutex::new(Vec::new()),
|
||||
render: Box::new(render),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
for comp in &mut self.components {
|
||||
// comp.tick(self);
|
||||
pub fn tick(self: &Arc<Self>) {
|
||||
for comp in self.components.lock().unwrap().iter_mut() {
|
||||
comp.tick(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+33
-22
@@ -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<Engine> {
|
||||
Arc::new(Engine {
|
||||
threads: Mutex::new(HashMap::new()),
|
||||
entities: Mutex::new(Vec::new()),
|
||||
})
|
||||
}
|
||||
|
||||
pub struct Engine {
|
||||
threads: HashMap<String, Box<dyn FnMut() + Send + Sync>>,
|
||||
entities: Vec<entity::Entity>,
|
||||
threads: Mutex<HashMap<String, Arc<dyn Fn(&Arc<Self>) + Send + Sync>>>,
|
||||
entities: Mutex<Vec<Arc<entity::Entity>>>,
|
||||
}
|
||||
|
||||
pub fn sleep(ms: u64) {
|
||||
@@ -23,38 +26,46 @@ pub fn sleep(ms: u64) {
|
||||
}
|
||||
|
||||
impl Engine {
|
||||
pub fn thread<F: FnMut() + Send + Sync + 'static>(&mut self, label: &str, f: F) {
|
||||
self.threads.insert(label.to_string(), Box::new(f));
|
||||
pub fn thread<F: Fn(&Arc<Self>) + Send + Sync + 'static>(self: &Arc<Self>, label: &str, f: 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);
|
||||
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<Self>) {
|
||||
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<Self>) {
|
||||
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<Self>) {
|
||||
for thr in self.threads.lock().unwrap().values() {
|
||||
let thr = thr.clone();
|
||||
let engine = self.clone();
|
||||
std::thread::spawn(move || (thr)(&engine));
|
||||
}
|
||||
|
||||
loop {
|
||||
|
||||
Reference in New Issue
Block a user