working extension system

This commit is contained in:
2025-06-29 11:49:11 -05:00
parent af719d83db
commit 85bfa0f45f
5 changed files with 115 additions and 7 deletions
+10
View File
@@ -0,0 +1,10 @@
pub mod tick;
pub mod velocity;
use std::sync::Arc;
use crate::widget::Widget;
pub trait Extension {
fn render(&self, _widget: &Arc<Widget>) {}
}
+15
View File
@@ -0,0 +1,15 @@
use std::sync::Arc;
use crate::{component, extensions::Extension, widget::Widget};
pub struct TickExtension;
impl Extension for TickExtension {
fn render(&self, _widget: &Arc<Widget>) {
if let Some(on_tick) = _widget.get::<OnTick>() {
(on_tick.0)(_widget)
}
}
}
component!(OnTick(pub fn(&Arc<Widget>)));
+44
View File
@@ -0,0 +1,44 @@
use std::sync::Arc;
use crate::{
component,
extensions::Extension,
style::{Position, Transform},
widget::Widget,
};
pub struct VelocityExtension;
impl Extension for VelocityExtension {
fn render(&self, _widget: &Arc<Widget>) {
if let Some(velocity) = _widget.get::<Velocity>() {
if let Some(mut t) = _widget.get::<Transform>() {
match &mut t.x {
Position::Const(x) => {
if velocity.0 > 0 {
*x += 1;
} else if velocity.0 < 0 {
*x -= 1;
}
}
_ => {}
}
match &mut t.y {
Position::Const(y) => {
if velocity.1 > 0 {
*y += 1;
} else if velocity.1 < 0 {
*y -= 1;
}
}
_ => {}
}
_widget.set_component(t);
}
}
}
}
component!(Velocity(pub i32, pub i32));
+22 -5
View File
@@ -1,12 +1,14 @@
use std::sync::Arc; use std::sync::Arc;
use crate::{ use crate::{
extensions::Extension,
render_scope::RenderScope, render_scope::RenderScope,
style::Transform, style::Transform,
widget::{Element, Widget}, widget::{Element, Widget},
}; };
pub mod elements; pub mod elements;
pub mod extensions;
pub mod macros; pub mod macros;
pub mod render_scope; pub mod render_scope;
pub mod style; pub mod style;
@@ -15,12 +17,14 @@ pub mod widget;
pub struct Screen { pub struct Screen {
pub elements: Vec<Arc<Widget>>, pub elements: Vec<Arc<Widget>>,
extensions: Vec<Arc<Box<dyn Extension>>>,
} }
impl Screen { impl Screen {
pub fn new() -> Screen { pub fn new() -> Screen {
Screen { Screen {
elements: Vec::new(), elements: Vec::new(),
extensions: Vec::new(),
} }
} }
@@ -29,6 +33,10 @@ impl Screen {
self.elements.last().unwrap() self.elements.last().unwrap()
} }
pub fn extension<E: Extension + 'static>(&mut self, ext: E) {
self.extensions.push(Arc::new(Box::new(ext)));
}
pub fn run(&mut self) -> std::io::Result<()> { pub fn run(&mut self) -> std::io::Result<()> {
for elem in &mut self.elements { for elem in &mut self.elements {
elem.component(Transform::new()); elem.component(Transform::new());
@@ -36,21 +44,23 @@ impl Screen {
utils::hide_cursor()?; utils::hide_cursor()?;
self.render()?; loop {
self.render()?;
loop {} std::thread::sleep(std::time::Duration::from_millis(50));
}
} }
pub fn render(&mut self) -> std::io::Result<()> { pub fn render(&self) -> std::io::Result<()> {
let mut scope = RenderScope::new(); let mut scope = RenderScope::new();
utils::clear()?; utils::clear()?;
for elem in &mut self.elements { for elem in &self.elements {
scope.clear(); scope.clear();
if let Some(t) = elem.get() { if let Some(t) = elem.get() {
scope.set_transform(&t); scope.set_transform(&t);
} }
self.render_extension(elem.clone()).unwrap();
elem.0.lock().unwrap().render(&mut scope); elem.0.lock().unwrap().render(&mut scope);
if let Some(t) = elem.get() { if let Some(t) = elem.get() {
@@ -60,4 +70,11 @@ impl Screen {
} }
Ok(()) Ok(())
} }
pub fn render_extension(&self, wi: Arc<Widget>) -> std::io::Result<()> {
for ext in &self.extensions {
ext.render(&wi);
}
Ok(())
}
} }
+24 -2
View File
@@ -1,11 +1,33 @@
use osui::{style::Transform, Screen}; use osui::{
extensions::{
tick::{OnTick, TickExtension},
velocity::{Velocity, VelocityExtension},
},
style::{Position, Transform},
Screen,
};
fn main() { fn main() {
let mut screen = Screen::new(); let mut screen = Screen::new();
screen.extension(VelocityExtension);
screen.extension(TickExtension);
screen screen
.draw(format!("Hello, World!")) .draw(format!("Hello, World!"))
.component(Transform::center()); .component(Transform::new())
.component(Velocity(1, 0))
.component(OnTick(|w| {
if let Some(mut v) = w.get::<Velocity>() {
if let Some(t) = w.get::<Transform>() {
if let Position::Const(c) = t.x {
if c == 30 {
v.0 = 0;
w.set_component(v);
}
}
}
}
}));
screen.run().unwrap(); screen.run().unwrap();
} }