resource management
This commit is contained in:
+7
-11
@@ -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<Vec<Arc<Widget>>>);
|
||||
pub struct IdExtension(pub Arc<Screen>);
|
||||
|
||||
impl Extension for Arc<IdExtension> {
|
||||
fn init(&mut self, widgets: &Vec<Arc<Widget>>) {
|
||||
self.0.lock().unwrap().append(&mut widgets.clone());
|
||||
}
|
||||
}
|
||||
impl Extension for Arc<IdExtension> {}
|
||||
|
||||
impl IdExtension {
|
||||
pub fn new() -> Arc<Self> {
|
||||
Arc::new(Self(Mutex::new(Vec::new())))
|
||||
pub fn new(screen: Arc<Screen>) -> Arc<Self> {
|
||||
Arc::new(IdExtension(screen))
|
||||
}
|
||||
|
||||
pub fn get_element(self: &Arc<IdExtension>, id: usize) -> Option<Arc<Widget>> {
|
||||
for elem in self.0.lock().unwrap().iter() {
|
||||
for elem in self.0.widgets.lock().unwrap().iter() {
|
||||
if let Some(current_id) = elem.get::<Id>() {
|
||||
if current_id.0 == id {
|
||||
return Some(elem.clone());
|
||||
|
||||
@@ -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<Arc<Widget>>) {}
|
||||
fn init(&mut self, _screen: Arc<Screen>) {}
|
||||
fn render_widget(&mut self, _scope: &mut RenderScope, _widget: &Arc<Widget>) {}
|
||||
}
|
||||
|
||||
|
||||
+16
-10
@@ -1,16 +1,22 @@
|
||||
use crate::{event, widget::Component};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Resource<T>(pub T);
|
||||
#[derive(Clone)]
|
||||
pub struct VecResource<T>(Arc<Mutex<Box<dyn FnMut(&T) + Send + Sync>>>);
|
||||
|
||||
impl<T: Send + Sync + 'static> Component for Resource<T> {
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
impl<T: Send + Sync + 'static> VecResource<T> {
|
||||
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<F: FnMut(&T) + Send + Sync + 'static>(&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);
|
||||
|
||||
@@ -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<Arc<Widget>>) {
|
||||
fn init(&mut self, screen: Arc<Screen>) {
|
||||
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::<Handler<TickEvent>>() {
|
||||
on_tick.call(&w, &TickEvent(tick))
|
||||
}
|
||||
|
||||
@@ -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<Arc<Widget>>) {
|
||||
fn init(&mut self, screen: Arc<Screen>) {
|
||||
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 {
|
||||
|
||||
+23
-19
@@ -16,8 +16,8 @@ pub mod utils;
|
||||
pub mod widget;
|
||||
|
||||
pub struct Screen {
|
||||
pub widgets: Vec<Arc<Widget>>,
|
||||
extensions: Vec<Arc<Mutex<Box<dyn Extension>>>>,
|
||||
pub widgets: Mutex<Vec<Arc<Widget>>>,
|
||||
extensions: Mutex<Vec<Arc<Mutex<Box<dyn Extension + Send + Sync>>>>>,
|
||||
}
|
||||
|
||||
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<Self> {
|
||||
Arc::new(Self {
|
||||
widgets: Mutex::new(Vec::new()),
|
||||
extensions: Mutex::new(Vec::new()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn draw<E: Element + 'static>(&mut self, element: E) -> &Arc<Widget> {
|
||||
self.widgets.push(Arc::new(Widget::new(Box::new(element))));
|
||||
self.widgets.last().unwrap()
|
||||
pub fn draw<E: Element + 'static>(self: &Arc<Self>, element: E) -> Arc<Widget> {
|
||||
let w = Arc::new(Widget::new(Box::new(element)));
|
||||
self.widgets.lock().unwrap().push(w.clone());
|
||||
w
|
||||
}
|
||||
|
||||
pub fn extension<E: Extension + 'static>(&mut self, ext: E) {
|
||||
self.extensions.push(Arc::new(Mutex::new(Box::new(ext))));
|
||||
pub fn extension<E: Extension + Send + Sync + 'static>(self: &Arc<Self>, 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<Self>) -> 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<Self>) -> 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::<Handler<RenderWrapperEvent>>() {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
+21
-32
@@ -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 = <VecResource<&str>>::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::<Resource<Vec<&str>>>().unwrap();
|
||||
res.0.push("Hello World");
|
||||
w.set_component(res);
|
||||
}
|
||||
})),
|
||||
);
|
||||
|
||||
for i in row_widget.get::<Resource<Vec<&str>>>().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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user