command stage 1

This commit is contained in:
2024-11-22 05:59:14 +01:00
parent 533ec30597
commit 10c8f6d0ca
3 changed files with 95 additions and 30 deletions
+19 -4
View File
@@ -4,8 +4,16 @@
#include <pthread.h> #include <pthread.h>
#include <time.h> #include <time.h>
typedef struct {
void* element;
void* sender;
void* receiver;
boolean_t running;
} LArgs;
extern boolean_t render(void* element); extern boolean_t render(void* element);
extern void *event_loop(void* element); extern void *event_loop(void* element);
extern void *cmd_loop(void* element);
void sleep_ms(long milliseconds) void sleep_ms(long milliseconds)
{ {
@@ -15,16 +23,23 @@ void sleep_ms(long milliseconds)
nanosleep(&ts, NULL); 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"); 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); sleep_ms(20);
} }
+62 -26
View File
@@ -3,14 +3,48 @@ use crossterm::{
terminal::{disable_raw_mode, enable_raw_mode}, terminal::{disable_raw_mode, enable_raw_mode},
}; };
use crate::{ use crate::prelude::*;
utils::{clear, create_frame, flush, get_term_size, hide_cursor, render_to_frame, show_cursor}, use crate::utils::{
Element, 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" { 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::<Command>();
let c = c_run(
element as *mut Element as *mut c_void,
&tx as *const mpsc::Sender<Command> as *const c_void,
&rx as *const mpsc::Receiver<Command> as *const c_void,
);
if !c {
show_cursor();
disable_raw_mode().unwrap();
clear();
}
return c;
}
} }
#[no_mangle] #[no_mangle]
@@ -33,37 +67,39 @@ extern "C" fn event_loop(ptr: *mut c_void) -> *const c_void {
if ptr.is_null() { if ptr.is_null() {
return null() as *const c_void; 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<Command>) };
let (width, height) = get_term_size(); let (width, height) = get_term_size();
element.update_data(width, height); element.update_data(width, height);
event(element, crossterm::event::Event::FocusGained); event(element, crossterm::event::Event::FocusGained);
loop {
while args.running {
if ptr.is_null() { if ptr.is_null() {
break; break;
} }
event(element, crossterm::event::read().unwrap()) event(element, crossterm::event::read().unwrap());
tx.send(Command::Exit).unwrap();
} }
null() as *const c_void null() as *const c_void
} }
fn event(element: &mut Element, event: Event) { #[no_mangle]
if let crossterm::event::Event::Resize(width, height) = event { extern "C" fn cmd_loop(ptr: *mut c_void) -> *const c_void {
element.update_data(width as usize, height as usize); if ptr.is_null() {
return null() as *const c_void;
} }
element.event(event); 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<Command>) };
pub fn run(element: &mut Element) -> bool { loop {
hide_cursor(); match rx.recv().unwrap() {
enable_raw_mode().unwrap(); Command::Exit => {
clear(); args.running = false;
unsafe { break;
let c = c_run(element as *mut Element as *mut c_void);
if !c {
show_cursor();
disable_raw_mode().unwrap();
clear();
}
return c;
} }
} }
}
null()
}
+15 -1
View File
@@ -43,7 +43,7 @@ pub use app::run;
pub mod prelude { pub mod prelude {
pub use crate::ui::Color::*; pub use crate::ui::Color::*;
pub use crate::{self as osui, css, rsx, rsx_elem, ui::*, Handler}; 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 // useful for Element making
pub use crate::{run_handler, Children, ElementCore, ElementWidget}; pub use crate::{run_handler, Children, ElementCore, ElementWidget};
pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind}; pub use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind};
@@ -195,3 +195,17 @@ impl Children {
pub fn convert<T>(widget: &mut Box<dyn ElementWidget>) -> &mut Box<T> { pub fn convert<T>(widget: &mut Box<dyn ElementWidget>) -> &mut Box<T> {
unsafe { &mut *(widget as *mut _ as *mut Box<T>) } unsafe { &mut *(widget as *mut _ as *mut Box<T>) }
} }
pub enum Command {
Exit,
}
pub struct Document {
cmd_sender: std::sync::mpsc::Sender<Command>,
}
impl Document {
pub fn exit(&self) {
self.cmd_sender.send(Command::Exit).unwrap();
}
}