Rsx
This commit is contained in:
+38
-3
@@ -1,19 +1,19 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{widget::Element};
|
||||
use crate::widget::Element;
|
||||
|
||||
pub trait DependencyHandler: std::fmt::Debug + Send + Sync {
|
||||
fn add(&self);
|
||||
fn check(&self) -> bool;
|
||||
}
|
||||
|
||||
pub struct Dependency<T: Element> {
|
||||
pub struct Dependency<T> {
|
||||
handlers: Vec<std::sync::Arc<dyn DependencyHandler>>,
|
||||
element: T,
|
||||
element_reset: Box<dyn FnMut() -> T + Send + Sync>,
|
||||
}
|
||||
|
||||
impl<T: Element> Dependency<T> {
|
||||
impl<T> Dependency<T> {
|
||||
pub fn new<F: FnMut() -> T + Send + Sync + 'static>(mut f: F) -> Self {
|
||||
Self {
|
||||
handlers: Vec::new(),
|
||||
@@ -22,6 +22,21 @@ impl<T: Element> Dependency<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(
|
||||
mut f: Box<dyn FnMut() -> T + Send + Sync>,
|
||||
handlers: Vec<std::sync::Arc<dyn DependencyHandler>>,
|
||||
) -> Self {
|
||||
for h in &handlers {
|
||||
h.add();
|
||||
}
|
||||
|
||||
Self {
|
||||
handlers,
|
||||
element: f(),
|
||||
element_reset: f,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn auto_reset(&mut self) {
|
||||
for i in &self.handlers {
|
||||
if i.check() {
|
||||
@@ -37,6 +52,26 @@ impl<T: Element> Dependency<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Element for Dependency<Box<dyn Element>> {
|
||||
fn render(&mut self, scope: &mut crate::render_scope::RenderScope) {
|
||||
self.element.render(scope);
|
||||
self.auto_reset();
|
||||
}
|
||||
|
||||
fn after_render(&mut self, scope: &crate::render_scope::RenderScope) {
|
||||
self.element.after_render(scope);
|
||||
self.auto_reset();
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Element + 'static> Element for Dependency<T> {
|
||||
fn render(&mut self, scope: &mut crate::render_scope::RenderScope) {
|
||||
self.element.render(scope);
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
dependency::{Dependency, DependencyHandler},
|
||||
widget::{Element, Widget},
|
||||
Screen,
|
||||
};
|
||||
|
||||
pub struct Rsx(
|
||||
pub Vec<(
|
||||
Box<dyn FnMut() -> Box<dyn Element> + Send + Sync>,
|
||||
Vec<std::sync::Arc<dyn DependencyHandler>>,
|
||||
)>,
|
||||
);
|
||||
|
||||
impl Rsx {
|
||||
pub fn draw(self, screen: &Arc<Screen>) {
|
||||
for i in self.0 {
|
||||
let d = Dependency::from(i.0, i.1);
|
||||
screen.draw_widget(Widget::new(Box::new(d)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ use crate::{
|
||||
pub mod dependency;
|
||||
pub mod elements;
|
||||
pub mod extensions;
|
||||
pub mod frontend;
|
||||
pub mod macros;
|
||||
pub mod render_scope;
|
||||
pub mod style;
|
||||
@@ -46,6 +47,12 @@ impl Screen {
|
||||
w
|
||||
}
|
||||
|
||||
pub fn draw_widget(self: &Arc<Self>, w: Widget) -> Arc<Widget> {
|
||||
let w = Arc::new(w);
|
||||
self.widgets.lock().unwrap().push(w.clone());
|
||||
w
|
||||
}
|
||||
|
||||
pub fn extension<E: Extension + Send + Sync + 'static>(self: &Arc<Self>, ext: E) {
|
||||
self.extensions
|
||||
.lock()
|
||||
|
||||
+16
-1
@@ -125,5 +125,20 @@ macro_rules! event_handler {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! rsx {
|
||||
() => {};
|
||||
($($inner:tt)*) => {{
|
||||
let mut r = Rsx(Vec::new());
|
||||
|
||||
$crate::rsx_inner! { r, $($inner)* };
|
||||
|
||||
r
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! rsx_inner {
|
||||
($r:expr, $(%$dep:ident)* $s:literal $($rest:tt)*) => {
|
||||
$r.0.push((Box::new({ $(let $dep = $dep.clone();)* move || Box::new(format!($s)) }), vec![$(Arc::new($dep.clone()),)*]));
|
||||
$crate::rsx_inner!{ $r, $($rest)* };
|
||||
};
|
||||
($r:expr,) => {};
|
||||
}
|
||||
|
||||
+15
-14
@@ -1,26 +1,27 @@
|
||||
use osui::{dependency::Dependency, elements::state::use_state, style::Transform, Screen};
|
||||
use std::sync::Arc;
|
||||
|
||||
use osui::{elements::state::use_state, frontend::Rsx, rsx, Screen};
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let screen = Screen::new();
|
||||
|
||||
app().draw(&screen);
|
||||
|
||||
screen.run()
|
||||
}
|
||||
|
||||
fn app() -> Rsx {
|
||||
let count = use_state(0);
|
||||
|
||||
std::thread::spawn({
|
||||
let count = count.clone();
|
||||
move || loop {
|
||||
std::thread::sleep(std::time::Duration::from_millis(1000));
|
||||
**count.get() += 500;
|
||||
std::thread::sleep(std::time::Duration::from_millis(50));
|
||||
**count.get() += 1;
|
||||
}
|
||||
});
|
||||
|
||||
screen
|
||||
.draw(
|
||||
Dependency::new({
|
||||
let count = count.clone();
|
||||
move || format!("{count}")
|
||||
})
|
||||
.add(count.clone()),
|
||||
)
|
||||
.component(Transform::center());
|
||||
|
||||
screen.run()
|
||||
rsx! {
|
||||
%count "{count}"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user