working extension system
This commit is contained in:
@@ -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>) {}
|
||||
}
|
||||
@@ -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>)));
|
||||
@@ -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
@@ -1,12 +1,14 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
extensions::Extension,
|
||||
render_scope::RenderScope,
|
||||
style::Transform,
|
||||
widget::{Element, Widget},
|
||||
};
|
||||
|
||||
pub mod elements;
|
||||
pub mod extensions;
|
||||
pub mod macros;
|
||||
pub mod render_scope;
|
||||
pub mod style;
|
||||
@@ -15,12 +17,14 @@ pub mod widget;
|
||||
|
||||
pub struct Screen {
|
||||
pub elements: Vec<Arc<Widget>>,
|
||||
extensions: Vec<Arc<Box<dyn Extension>>>,
|
||||
}
|
||||
|
||||
impl Screen {
|
||||
pub fn new() -> Screen {
|
||||
Screen {
|
||||
elements: Vec::new(),
|
||||
extensions: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +33,10 @@ impl Screen {
|
||||
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<()> {
|
||||
for elem in &mut self.elements {
|
||||
elem.component(Transform::new());
|
||||
@@ -36,21 +44,23 @@ impl Screen {
|
||||
|
||||
utils::hide_cursor()?;
|
||||
|
||||
self.render()?;
|
||||
|
||||
loop {}
|
||||
loop {
|
||||
self.render()?;
|
||||
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();
|
||||
|
||||
utils::clear()?;
|
||||
for elem in &mut self.elements {
|
||||
for elem in &self.elements {
|
||||
scope.clear();
|
||||
if let Some(t) = elem.get() {
|
||||
scope.set_transform(&t);
|
||||
}
|
||||
|
||||
self.render_extension(elem.clone()).unwrap();
|
||||
elem.0.lock().unwrap().render(&mut scope);
|
||||
|
||||
if let Some(t) = elem.get() {
|
||||
@@ -60,4 +70,11 @@ impl Screen {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn render_extension(&self, wi: Arc<Widget>) -> std::io::Result<()> {
|
||||
for ext in &self.extensions {
|
||||
ext.render(&wi);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+24
-2
@@ -1,11 +1,33 @@
|
||||
use osui::{style::Transform, Screen};
|
||||
use osui::{
|
||||
extensions::{
|
||||
tick::{OnTick, TickExtension},
|
||||
velocity::{Velocity, VelocityExtension},
|
||||
},
|
||||
style::{Position, Transform},
|
||||
Screen,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut screen = Screen::new();
|
||||
screen.extension(VelocityExtension);
|
||||
screen.extension(TickExtension);
|
||||
|
||||
screen
|
||||
.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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user