test
This commit is contained in:
+13
-31
@@ -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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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)]);
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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()),
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user