This commit is contained in:
2025-06-24 17:21:12 +02:00
parent f72959bcee
commit 6c0dde8e85
5 changed files with 65 additions and 88 deletions
+13 -31
View File
@@ -1,35 +1,17 @@
use std::{any::TypeId, thread, time::Duration}; pub mod text;
pub mod macros;
pub mod output; use std::fmt::Debug;
use downcast_rs::{impl_downcast, DowncastSync};
pub trait Component: DowncastSync + Debug {}
impl_downcast!(sync Component);
pub trait Element {
fn get_component<T: Component + 'static>(&mut self) -> Option<&mut T>;
fn add_component<T: Component + 'static>(&mut self, component: T);
}
pub trait Extension { pub trait Extension {
fn tick(&mut self, args: &mut Args); fn tick(&mut self);
}
pub trait BaseElement {
fn init(&mut self);
fn get_components<'a>(&'a mut self) -> &'a mut Vec<Box<dyn ElementComponent>>;
}
pub trait ElementComponent {
fn get_type_id(&self) -> TypeId;
}
pub struct Args {
pub tick_rate: u16,
pub base_elements: Vec<Box<dyn BaseElement>>,
}
pub fn run(mut args: Args, mut extensions: Vec<Box<dyn Extension>>) {
for elem in &mut args.base_elements {
elem.init();
}
loop {
for extension in &mut extensions {
extension.tick(&mut args);
}
thread::sleep(Duration::from_millis(1000 / args.tick_rate as u64));
}
} }
+12
View File
@@ -0,0 +1,12 @@
#[macro_export]
macro_rules! components {
($($a:ty: $e:expr),*) => {
{
let mut hm: HashMap<TypeId, Box<dyn Component>> = HashMap::new();
$(
hm.insert(TypeId::of::<$a>(), Box::new($e));
)*
hm
}
};
}
+7 -26
View File
@@ -1,31 +1,12 @@
use osui::{ use osui::{
output::{OutputExtension, RenderAble}, text::{text, DisplayComponent},
run, Args, BaseElement, Element,
}; };
pub struct MyElem(*mut Vec<Box<dyn osui::ElementComponent>>);
impl BaseElement for MyElem {
fn init(&mut self) {
unsafe {
(*self.0).push(RenderAble::new(|| String::from("value")));
}
}
fn get_components<'a>(&'a mut self) -> &'a mut Vec<Box<dyn osui::ElementComponent>> {
unsafe { &mut *self.0 }
}
}
impl MyElem {
pub fn new(mut v: Vec<Box<dyn osui::ElementComponent>>) -> Box<MyElem> {
Box::new(MyElem(&mut v))
}
}
fn main() { fn main() {
let args = Args { let mut e = text("Hello, World!");
tick_rate: 40,
base_elements: vec![], if let Some(comp) = e.get_component::<DisplayComponent>() {
}; println!("Ok: {:?}", comp);
run(args, vec![Box::new(OutputExtension)]); }
} }
-31
View File
@@ -1,31 +0,0 @@
use std::{any::TypeId, fmt::Debug};
use crate::{ElementComponent, Extension};
pub struct OutputExtension;
impl Extension for OutputExtension {
fn tick(&mut self, args: &mut crate::Args) {
for elem in &mut args.base_elements {
for comp in elem.get_components() {
if comp.get_type_id() == TypeId::of::<RenderAble>() {
comp
}
}
}
}
}
pub struct RenderAble(pub Box<dyn Fn() -> String>);
impl ElementComponent for RenderAble {
fn get_type_id(&self) -> std::any::TypeId {
TypeId::of::<RenderAble>()
}
}
impl RenderAble {
pub fn new<F: Fn() -> String + 'static>(f: F) -> Box<RenderAble> {
Box::new(RenderAble(Box::new(f)))
}
}
+33
View File
@@ -0,0 +1,33 @@
use crate::{components, Component, Element};
use std::{any::TypeId, collections::HashMap};
#[derive(Debug)]
pub struct DisplayComponent();
impl Component for DisplayComponent {}
pub struct Text {
text: String,
components: HashMap<TypeId, Box<dyn Component>>,
}
impl Element for Text {
fn get_component<T: Component + 'static>(&mut self) -> Option<&mut T> {
self.components
.get_mut(&TypeId::of::<T>())?
.downcast_mut::<T>()
}
fn add_component<T: Component + 'static>(&mut self, component: T) {
if !self.components.contains_key(&TypeId::of::<T>()) {
self.components
.insert(TypeId::of::<T>(), Box::new(component));
}
}
}
pub fn text(text: &str) -> Text {
Text {
text: text.to_string(),
components: components!(DisplayComponent: DisplayComponent()),
}
}