From 10c8f6d0cad0fe5b2a547332a8563dcc0ae0be0f Mon Sep 17 00:00:00 2001 From: Leo dev Date: Fri, 22 Nov 2024 05:59:14 +0100 Subject: [PATCH] command stage 1 --- src/app.c | 23 ++++++++++++--- src/app.rs | 86 ++++++++++++++++++++++++++++++++++++++---------------- src/lib.rs | 16 +++++++++- 3 files changed, 95 insertions(+), 30 deletions(-) diff --git a/src/app.c b/src/app.c index 50a5475..027523a 100644 --- a/src/app.c +++ b/src/app.c @@ -4,8 +4,16 @@ #include #include +typedef struct { + void* element; + void* sender; + void* receiver; + boolean_t running; +} LArgs; + extern boolean_t render(void* element); extern void *event_loop(void* element); +extern void *cmd_loop(void* element); void sleep_ms(long milliseconds) { @@ -15,16 +23,23 @@ void sleep_ms(long milliseconds) nanosleep(&ts, NULL); } -boolean_t c_run(void* element) +boolean_t c_run(void* element, void* sender, void* receiver) { - pthread_t thread; + pthread_t event_thread; + pthread_t cmd_thread; + LArgs args = { .element = element, .sender = sender, .receiver = receiver, .running = 1 }; - if (pthread_create(&thread, NULL, event_loop, element) != 0) + if (pthread_create(&event_thread, NULL, event_loop, &args) != 0) { perror("Failed to create thread"); } - while (render(element)) + if (pthread_create(&cmd_thread, NULL, cmd_loop, &args) != 0) + { + perror("Failed to create thread"); + } + + while (render(element) && args.running) { sleep_ms(20); } diff --git a/src/app.rs b/src/app.rs index 86eafac..d20ecd1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -3,14 +3,48 @@ use crossterm::{ terminal::{disable_raw_mode, enable_raw_mode}, }; -use crate::{ - utils::{clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor}, - Element, +use crate::prelude::*; +use crate::utils::{ + clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor, }; -use std::{ffi::c_void, ptr::null}; +use std::{ffi::c_void, ptr::null, sync::mpsc}; + +pub struct LArgs { + pub element: *mut c_void, + pub sender: *const c_void, + pub receiver: *const c_void, + pub running: bool, +} extern "C" { - fn c_run(element: *mut c_void) -> bool; + fn c_run(element: *mut c_void, sender: *const c_void, receiver: *const c_void) -> bool; +} + +fn event(element: &mut Element, event: Event) { + if let crossterm::event::Event::Resize(width, height) = event { + element.update_data(width as usize, height as usize); + } + element.event(event); +} + +pub fn run(element: &mut Element) -> bool { + hide_cursor(); + enable_raw_mode().unwrap(); + clear(); + unsafe { + let (tx, rx) = mpsc::channel::(); + let c = c_run( + element as *mut Element as *mut c_void, + &tx as *const mpsc::Sender as *const c_void, + &rx as *const mpsc::Receiver as *const c_void, + ); + if !c { + show_cursor(); + disable_raw_mode().unwrap(); + clear(); + } + return c; + } } #[no_mangle] @@ -33,37 +67,39 @@ extern "C" fn event_loop(ptr: *mut c_void) -> *const c_void { if ptr.is_null() { return null() as *const c_void; } - let element = unsafe { &mut *(ptr as *mut Element) }; + let args = unsafe { &mut *(ptr as *mut LArgs) }; + let element = unsafe { &mut *(args.element as *mut Element) }; + let tx = unsafe { &*(args.sender as *const mpsc::Sender) }; + let (width, height) = get_term_size(); element.update_data(width, height); event(element, crossterm::event::Event::FocusGained); - loop { + + while args.running { if ptr.is_null() { break; } - event(element, crossterm::event::read().unwrap()) + event(element, crossterm::event::read().unwrap()); + tx.send(Command::Exit).unwrap(); } null() as *const c_void } -fn event(element: &mut Element, event: Event) { - if let crossterm::event::Event::Resize(width, height) = event { - element.update_data(width as usize, height as usize); +#[no_mangle] +extern "C" fn cmd_loop(ptr: *mut c_void) -> *const c_void { + if ptr.is_null() { + return null() as *const c_void; } - element.event(event); -} - -pub fn run(element: &mut Element) -> bool { - hide_cursor(); - enable_raw_mode().unwrap(); - clear(); - unsafe { - let c = c_run(element as *mut Element as *mut c_void); - if !c { - show_cursor(); - disable_raw_mode().unwrap(); - clear(); + let args = unsafe { &mut *(ptr as *mut LArgs) }; + let _element = unsafe { &mut *(args.element as *mut Element) }; + let rx = unsafe { &*(args.receiver as *const mpsc::Receiver) }; + loop { + match rx.recv().unwrap() { + Command::Exit => { + args.running = false; + break; + } } - return c; } + null() } diff --git a/src/lib.rs b/src/lib.rs index 00c65a9..3cead75 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -43,7 +43,7 @@ pub use app::run; pub mod prelude { pub use crate::ui::Color::*; pub use crate::{self as osui, css, rsx, rsx_elem, ui::*, Handler}; - pub use crate::{style, Element, Value}; + pub use crate::{style, Command, Element, Value, Document}; // useful for Element making pub use crate::{run_handler, Children, ElementCore, ElementWidget}; pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind}; @@ -194,4 +194,18 @@ impl Children { /// Converts a `Element` into the struct pub fn convert(widget: &mut Box) -> &mut Box { unsafe { &mut *(widget as *mut _ as *mut Box) } +} + +pub enum Command { + Exit, +} + +pub struct Document { + cmd_sender: std::sync::mpsc::Sender, +} + +impl Document { + pub fn exit(&self) { + self.cmd_sender.send(Command::Exit).unwrap(); + } } \ No newline at end of file