diff --git a/src/extensions/id.rs b/src/extensions/id.rs index 66259d4..de629d9 100644 --- a/src/extensions/id.rs +++ b/src/extensions/id.rs @@ -1,22 +1,18 @@ -use std::sync::{Arc, Mutex}; +use std::sync::Arc; -use crate::{component, extensions::Extension, widget::Widget}; +use crate::{component, extensions::Extension, widget::Widget, Screen}; -pub struct IdExtension(Mutex>>); +pub struct IdExtension(pub Arc); -impl Extension for Arc { - fn init(&mut self, widgets: &Vec>) { - self.0.lock().unwrap().append(&mut widgets.clone()); - } -} +impl Extension for Arc {} impl IdExtension { - pub fn new() -> Arc { - Arc::new(Self(Mutex::new(Vec::new()))) + pub fn new(screen: Arc) -> Arc { + Arc::new(IdExtension(screen)) } pub fn get_element(self: &Arc, id: usize) -> Option> { - for elem in self.0.lock().unwrap().iter() { + for elem in self.0.widgets.lock().unwrap().iter() { if let Some(current_id) = elem.get::() { if current_id.0 == id { return Some(elem.clone()); diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index 1745c5d..0bc0e5b 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -1,7 +1,7 @@ pub mod id; +pub mod resources; pub mod tick; pub mod velocity; -pub mod resources; use std::{ any::{type_name, Any}, @@ -12,10 +12,11 @@ use std::{ use crate::{ render_scope::RenderScope, widget::{Component, Widget}, + Screen, }; pub trait Extension { - fn init(&mut self, _widgets: &Vec>) {} + fn init(&mut self, _screen: Arc) {} fn render_widget(&mut self, _scope: &mut RenderScope, _widget: &Arc) {} } diff --git a/src/extensions/resources.rs b/src/extensions/resources.rs index d529382..1542111 100644 --- a/src/extensions/resources.rs +++ b/src/extensions/resources.rs @@ -1,16 +1,22 @@ -use crate::{event, widget::Component}; +use std::sync::{Arc, Mutex}; -#[derive(Debug, Clone)] -pub struct Resource(pub T); +#[derive(Clone)] +pub struct VecResource(Arc>>); -impl Component for Resource { - fn as_any(&self) -> &dyn std::any::Any { - self +impl VecResource { + pub fn new() -> Self { + Self(Arc::new(Mutex::new(Box::new(|_| {})))) } - fn as_any_mut(&mut self) -> &mut dyn std::any::Any { - self + pub fn iterate(&self, f: F) { + *self.0.lock().unwrap() = Box::new(f); + } + + pub fn push(&self, e: T) { + let i = self.0.clone(); + + std::thread::spawn(move || { + (i.lock().unwrap())(&e); + }); } } - -event!(ResourceUpdate); diff --git a/src/extensions/tick.rs b/src/extensions/tick.rs index d203f41..9ee857a 100644 --- a/src/extensions/tick.rs +++ b/src/extensions/tick.rs @@ -1,20 +1,19 @@ use std::{fmt::Debug, sync::Arc}; -use crate::event; +use crate::extensions::Extension; use crate::extensions::Handler; -use crate::{extensions::Extension, widget::Widget}; +use crate::{event, Screen}; pub struct TickExtension(pub u16); impl Extension for TickExtension { - fn init(&mut self, widgets: &Vec>) { + fn init(&mut self, screen: Arc) { let rate_dur = 1000 / self.0 as u64; std::thread::spawn({ - let widgets = widgets.clone(); move || { let mut tick = 0; loop { - for w in &widgets { + for w in screen.widgets.lock().unwrap().iter() { if let Some(on_tick) = w.get::>() { on_tick.call(&w, &TickEvent(tick)) } diff --git a/src/extensions/velocity.rs b/src/extensions/velocity.rs index c33acf5..1f3fefb 100644 --- a/src/extensions/velocity.rs +++ b/src/extensions/velocity.rs @@ -5,6 +5,7 @@ use crate::{ extensions::Extension, style::{Position, Transform}, widget::Widget, + Screen, }; pub struct VelocityExtension; @@ -42,13 +43,12 @@ impl VelocityExtension { } impl Extension for VelocityExtension { - fn init(&mut self, widgets: &Vec>) { + fn init(&mut self, screen: Arc) { std::thread::spawn({ - let widgets = widgets.clone(); move || { let mut tick = 0; loop { - for widget in &widgets { + for widget in screen.widgets.lock().unwrap().iter() { Self::apply_velocity_xy(tick, widget); } if tick > 1000 { diff --git a/src/lib.rs b/src/lib.rs index fe9ac0e..3318b90 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,8 +16,8 @@ pub mod utils; pub mod widget; pub struct Screen { - pub widgets: Vec>, - extensions: Vec>>>, + pub widgets: Mutex>>, + extensions: Mutex>>>>, } event!(RenderWrapperEvent(*mut RenderScope)); @@ -32,29 +32,33 @@ unsafe impl Send for RenderWrapperEvent {} unsafe impl Sync for RenderWrapperEvent {} impl Screen { - pub fn new() -> Screen { - Screen { - widgets: Vec::new(), - extensions: Vec::new(), - } + pub fn new() -> Arc { + Arc::new(Self { + widgets: Mutex::new(Vec::new()), + extensions: Mutex::new(Vec::new()), + }) } - pub fn draw(&mut self, element: E) -> &Arc { - self.widgets.push(Arc::new(Widget::new(Box::new(element)))); - self.widgets.last().unwrap() + pub fn draw(self: &Arc, element: E) -> Arc { + let w = Arc::new(Widget::new(Box::new(element))); + self.widgets.lock().unwrap().push(w.clone()); + w } - pub fn extension(&mut self, ext: E) { - self.extensions.push(Arc::new(Mutex::new(Box::new(ext)))); + pub fn extension(self: &Arc, ext: E) { + self.extensions + .lock() + .unwrap() + .push(Arc::new(Mutex::new(Box::new(ext)))); } - pub fn run(&mut self) -> std::io::Result<()> { - for elem in &mut self.widgets { + pub fn run(self: &Arc) -> std::io::Result<()> { + for elem in self.widgets.lock().unwrap().iter() { elem.component(Transform::new()); } - for ext in &self.extensions { - ext.lock().unwrap().init(&self.widgets); + for ext in self.extensions.lock().unwrap().iter() { + ext.lock().unwrap().init(self.clone()); } utils::hide_cursor()?; @@ -65,13 +69,13 @@ impl Screen { } } - pub fn render(&self) -> std::io::Result<()> { + pub fn render(self: &Arc) -> std::io::Result<()> { let mut scope = RenderScope::new(); let (w, h) = crossterm::terminal::size().unwrap(); scope.set_parent_size(w, h); utils::clear()?; - for elem in &self.widgets { + for elem in self.widgets.lock().unwrap().iter() { if let Some(wrapper) = elem.get::>() { wrapper.call(elem, &RenderWrapperEvent(&mut scope)); } else { @@ -80,7 +84,7 @@ impl Screen { scope.set_transform(&t); } - for ext in &self.extensions { + for ext in self.extensions.lock().unwrap().iter() { ext.lock().unwrap().render_widget(&mut scope, elem); } diff --git a/src/main.rs b/src/main.rs index c661349..d1f4041 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,7 @@ use osui::{ - elements::{ - div::Div, - grid::{HGrid, VGrid}, - }, + elements::grid::VGrid, extensions::{ - resources::Resource, + resources::VecResource, tick::{TickEvent, TickExtension}, Handler, }, @@ -13,43 +10,35 @@ use osui::{ }; fn main() { - let mut screen = Screen::new(); + let screen = Screen::new(); screen.extension(TickExtension(10)); - let container = Div::new(0xffff00); + let items = >::new(); + + let vgrid = VGrid::new(0x000000, 0); screen - .draw(container.clone()) - .component(Transform::center().dimensions(70, 11)); + .draw(vgrid.clone()) + .component(Transform::center()) + .component(Handler::new({ + let items = items.clone(); + move |_, e: &TickEvent| { + if e.0 == 1 { + items.push("Hello?"); + } + } + })); - let vgrid = VGrid::new(0x0000ff, 1); - - container.draw(screen.draw(vgrid.clone()).component(Transform::center())); - - for _ in 1..6 { - let row = HGrid::new(0xff00ff, 1); - - let row_widget = vgrid.draw( - screen - .draw(row.clone()) - .component(Resource(Vec::<&str>::from(["Test"]))) - .component(Handler::new(|w, t: &TickEvent| { - if t.0 >= 10 { - let mut res = w.get::>>().unwrap(); - res.0.push("Hello World"); - w.set_component(res); - } - })), - ); - - for i in row_widget.get::>>().unwrap().0 { - row.draw( + items.iterate({ + let screen = screen.clone(); + move |i| { + vgrid.draw( screen .draw((i.to_string(), 0xff0000)) .component(Transform::new()), ); } - } + }); screen.run().unwrap(); }