command stage 1
This commit is contained in:
@@ -4,8 +4,16 @@
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
+61
-25
@@ -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::<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]
|
||||
@@ -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<Command>) };
|
||||
|
||||
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<Command>) };
|
||||
loop {
|
||||
match rx.recv().unwrap() {
|
||||
Command::Exit => {
|
||||
args.running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
null()
|
||||
}
|
||||
|
||||
+15
-1
@@ -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};
|
||||
@@ -195,3 +195,17 @@ impl Children {
|
||||
pub fn convert<T>(widget: &mut Box<dyn ElementWidget>) -> &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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user