diff --git a/Cargo.lock b/Cargo.lock index da75dd1..73484b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,3 +5,12 @@ version = 4 [[package]] name = "daria" version = "0.1.0" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "1.0.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e136bfa874086c78f34d6eba98c423fefe464ce57f38164d16893ba8ed358e70" diff --git a/Cargo.toml b/Cargo.toml index 41420e2..e3e8550 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,5 @@ path = "src/l3/r4/r4d.rs" [lib] name = "alice_and_misc" path = "src/l2/allie_rs/lib.rs" +[dependencies] +libc = "1.0.0-alpha.3" diff --git a/src/l2/allie_cpp/glue.c b/src/l2/allie_cpp/glue.c index 6fcc9da..7afd745 100644 --- a/src/l2/allie_cpp/glue.c +++ b/src/l2/allie_cpp/glue.c @@ -25,6 +25,7 @@ void allie_Alice_lucy_cache_add_glyphs(Alice* alice, VecLucyGlyphCachingRequest Alice_lucy_cache_add_glyphs(alice, req); } +// todo: transition to cvec4 from vec4 color (vec4 color makes no sense for fonts) void allie_Alice_lucy_renderer_add_simple_label(Alice* alice, RBTreeNodeLucyFaceFixedSize* ffs, vec4 color, S32 additional_y_advance, SpanU8 text, ivec2 start_pos ) { diff --git a/src/l2/allie_rs/alice.rs b/src/l2/allie_rs/alice.rs new file mode 100644 index 0000000..ab7eb91 --- /dev/null +++ b/src/l2/allie_rs/alice.rs @@ -0,0 +1,103 @@ +use std::ffi::{c_void}; +use std::marker::PhantomData; +use crate::geom::{*}; +use crate::allie; +use crate::allie::CSpan; +use crate::uint_segments::{U32Segment}; + +pub struct LucyFaceFixedSize { + opa: allie::LucyFaceFixedSize, +} + +impl Drop for LucyFaceFixedSize { + fn drop(&mut self) { + // todo: so something + } +} + +pub struct LucyFace { + opa: allie::LucyFace, +} + +impl LucyFace { + pub fn of_size(&self, size: u32) -> LucyFaceFixedSize{ + LucyFaceFixedSize{opa: unsafe { allie::LucyFace_of_size(self.opa, size) }} + } +} + + +impl Drop for LucyFace { + fn drop(&mut self) { + // todo: oh what should I do + } +} + + +pub struct Alice { + opa: allie::Alice, +} + +pub struct AliceCallbacks<'a> { + pub on_wl_pointer_button: Box, + pub on_wl_keyboard_key: Box, + pub on_another_frame: Box, + pub on_wl_pointer_motion: Box, +} + +pub struct LucyGlyphCachingRequest<'a> { + pub sized_face: &'a mut LucyFaceFixedSize, + pub codepoint_ranges: Vec, +} +impl<'a> From<& LucyGlyphCachingRequest<'a>> for allie::LucyGlyphCachingRequest<'a> { + fn from(value: & LucyGlyphCachingRequest<'a>) -> Self { + Self{phantom: PhantomData, + sized_face: value.sized_face.opa, + codepoint_ranges: allie::CVec::::from(&value.codepoint_ranges)} + } +} + + +impl Alice { + pub fn new() -> Self { + Alice{opa: unsafe { allie::Alice_new() }} + } + + pub fn mainloop<'a>(&'a self, mut cb: AliceCallbacks<'a>) { + let guest_data = (&raw mut cb) as allie::Alice; + + let a_cb = allie::AliceCallbacks { + guest: guest_data, + on_wl_pointer_button: allie::AliceCallbacks_on_wl_pointer_button, + on_wl_keyboard_key: allie::AliceCallbacks_on_wl_keyboard_key, + on_another_frame: allie::AliceCallbacks_on_another_frame, + on_wl_pointer_motion: allie::AliceCallbacks_on_wl_pointer_motion, + }; + + unsafe{ allie::Alice_mainloop(self.opa, &a_cb) }; + } + + pub fn set_clear_color(&self, color: vec4) { + unsafe { allie::Alice_set_clear_color(self.opa, color) }; + } + + pub fn new_lucy_face(&self, path: &str) -> LucyFace{ + LucyFace{opa: unsafe { allie::Alice_new_LucyFace(self.opa, allie::CVec::::from(path)) } } + } + + pub fn lucy_cache_add_glyphs(&self, req: Vec){ + let a_req = allie::CVec::::from(&req); + unsafe { allie::Alice_lucy_cache_add_glyphs(self.opa, a_req) }; + } + + pub fn lucy_renderer_add_simple_label(&self, ffs: &LucyFaceFixedSize, color: vec4, + additional_y_advance: i32, text: &str, start_pos: ivec2 + ) { + unsafe { allie::Alice_lucy_renderer_add_simple_label(self.opa, ffs.opa, color, + additional_y_advance, allie::CSpan::::from(text), start_pos) } + } +} +impl Drop for Alice { + fn drop(&mut self) { + // todo: do something + } +} diff --git a/src/l2/allie_rs/allie.rs b/src/l2/allie_rs/allie.rs new file mode 100644 index 0000000..08386e4 --- /dev/null +++ b/src/l2/allie_rs/allie.rs @@ -0,0 +1,131 @@ +use std::ffi::c_void; +use crate::alice; +use crate::geom::{vec2, vec4, ivec2}; +use std::ptr::copy_nonoverlapping; +use std::ptr; +use libc::{calloc, free}; +use std::mem::size_of; +use std::marker::PhantomData; +use crate::uint_segments::{*}; + +/* usize is u64, ok? */ +// fn safe_calloc(nobj: usize, size: usize) -> *mut c_void{ +// let p = unsafe { calloc(nobj, size) }; +// if (p.is_null()){ panic!("calloc: Not enough memory\n") } +// p +// } + +fn safe_calloc(nobj: usize) ->* mut T { + let p = unsafe { calloc(nobj, size_of::()) }; + if (p.is_null()){ panic!("calloc: Not enough memory\n") } + p as *mut T +} + +pub type Alice = *mut c_void; +pub type LucyFace = *mut c_void; +pub type LucyFaceFixedSize = *mut c_void; + +#[repr(C)] +pub struct CSpan<'a, T> { + phantom: PhantomData<&'a T>, + data: *const T, + len: u64 +} + +impl<'a> From<&'a str> for CSpan<'a, u8> { + fn from(s: &'a str) -> Self { + let data: *const u8 = s.as_ptr(); + Self{phantom: PhantomData, data, len: s.len() as u64} + } +} + + +#[repr(C)] +pub struct CVec { + buf: *mut T, + len: u64, capacity: u64 +} + +impl<'a, Td, Ts> From<&'a Vec> for CVec where Td: From<&'a Ts>{ + fn from(value: &'a Vec) -> Self { + let buf: *mut Td = safe_calloc(value.len()); + for (i, src) in value.iter().enumerate() { + unsafe { ptr::write(buf.add(i), Td::from(src)) }; + } + Self {buf, len: value.len() as u64, capacity: value.len() as u64} + } +} + +impl From<&str> for CVec { + fn from(s: &str) -> Self { + let buf: *mut u8 = safe_calloc(s.len()); + unsafe { copy_nonoverlapping(s.as_ptr(), buf, s.len()) }; + Self{buf, len: s.len() as u64, capacity: s.len() as u64} + } +} + +impl Drop for CVec{ + fn drop(&mut self) { + unsafe { free(self.buf as *mut c_void) }; + } +} + +#[repr(C)] +pub struct LucyGlyphCachingRequest<'a> { + pub phantom: PhantomData<&'a u8>, + pub sized_face: LucyFaceFixedSize, + pub codepoint_ranges: CVec, +} +/* Copying from Rust analog type to C allie type will be implemented outside */ + + +#[repr(C)] +pub struct AliceCallbacks { + pub guest: Alice, + /* guest data, button, btn action */ + pub on_wl_pointer_button: extern "C" fn (Alice, u32, u32), + /* guest data, keysym, key action (wl_keyboard_key_state) */ + pub on_wl_keyboard_key: extern "C" fn (Alice, u32, u32), + /* guest data, passed time */ + pub on_another_frame: extern "C" fn (Alice, f32), + pub on_wl_pointer_motion: extern "C" fn (Alice, vec2), +} + +unsafe extern "C" { + #[link_name="Alice_new"] + pub fn Alice_new() -> Alice; + #[link_name="Alice_mainloop"] + pub fn Alice_mainloop(alice: Alice, cb: *const AliceCallbacks); + #[link_name="Alice_set_clear_color"] + pub fn Alice_set_clear_color(alice: Alice, color: vec4); + #[link_name="Alice_new_LucyFace"] + pub fn Alice_new_LucyFace(alice: Alice, path: CVec) -> LucyFace; + #[link_name="LucyFace_of_size"] + pub fn LucyFace_of_size(alice: LucyFace, size: u32) -> LucyFaceFixedSize; + #[link_name="Alice_lucy_cache_add_glyphs"] + pub fn Alice_lucy_cache_add_glyphs(alice: Alice, req: CVec); + #[link_name="Alice_lucy_renderer_add_simple_label"] + pub fn Alice_lucy_renderer_add_simple_label( /* todo: make color cvec4 */ + alice: Alice, ffs: LucyFaceFixedSize, + color: vec4, additional_y_advance: i32, text: CSpan, start_pos: ivec2); +} + +pub extern "C" fn AliceCallbacks_on_wl_pointer_button(dt: Alice, button: u32, act: u32){ + let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) }; + (cb.on_wl_pointer_button)(button, act); +} + +pub extern "C" fn AliceCallbacks_on_wl_keyboard_key(dt: Alice, keysym: u32, act: u32){ + let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) }; + (cb.on_wl_keyboard_key)(keysym, act); +} + +pub extern "C" fn AliceCallbacks_on_another_frame(dt: Alice, fl: f32){ + let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) }; + (cb.on_another_frame)(fl); +} + +pub extern "C" fn AliceCallbacks_on_wl_pointer_motion(dt: Alice, pos: vec2){ + let cb: &mut alice::AliceCallbacks = unsafe { &mut *(dt as *mut alice::AliceCallbacks) }; + (cb.on_wl_pointer_motion)(pos); +} diff --git a/src/l2/allie_rs/geom.rs b/src/l2/allie_rs/geom.rs index 0504503..82aba30 100644 --- a/src/l2/allie_rs/geom.rs +++ b/src/l2/allie_rs/geom.rs @@ -9,6 +9,7 @@ impl AssertTrue for Assert{} /* Turn out for tuple struct, where clause goes after the field list */ #[repr(C)] +#[derive(Clone, Copy, Debug)] pub struct GeomVec (pub [T; N]) where T: Copy + Clone; impl Add for GeomVec where @@ -21,19 +22,6 @@ impl Add for GeomVec where } } -trait HasY { - fn has_foo() -> bool { - return true; - } -} - -// impl HasY for GeomVec where -// T: Copy + Clone, -// Assert<{N >= 1}> : AssertTrue { -// -// } - - impl GeomVec where T: Copy + Clone, Assert<{N >= 1}> : AssertTrue { diff --git a/src/l2/allie_rs/lib.rs b/src/l2/allie_rs/lib.rs index e6d24d7..a371be8 100644 --- a/src/l2/allie_rs/lib.rs +++ b/src/l2/allie_rs/lib.rs @@ -9,89 +9,6 @@ /* *c_void is nothing special, it is the same as *u8 for example */ pub mod geom; pub mod int_primitives; - -use std::ffi::{c_void}; -use geom::{*}; - -type VoidPtr = *mut c_void; - -#[repr(C)] -struct allie_AliceCallbacks{ - guest: VoidPtr, - /* guest data, button, btn action */ - on_wl_pointer_button: extern "C" fn (VoidPtr, u32, u32), - /* guest data, keysym, key action (wl_keyboard_key_state) */ - on_wl_keyboard_key: extern "C" fn (VoidPtr, u32, u32), - /* guest data, passed time */ - on_another_frame: extern "C" fn (VoidPtr, f32), - on_wl_pointer_motion: extern "C" fn (VoidPtr, vec2), -} - -unsafe extern "C" { - #[link_name="Alice_new"] - fn allie_Alice_new() -> *mut c_void; - #[link_name="Alice_mainloop"] - fn allie_Alice_mainloop(alice: VoidPtr, cb: *const allie_AliceCallbacks); - #[link_name="Alice_set_clear_color"] - fn allie_Alice_set_clear_color(alice: VoidPtr, color: vec4); -} - -pub struct Alice { - opa: *mut c_void, -} - -pub struct AliceCallbacks { - pub on_wl_pointer_button: Box, - pub on_wl_keyboard_key: Box, - pub on_another_frame: Box, - pub on_wl_pointer_motion: Box, -} - -extern "C" fn allie_AliceCallbacks_on_wl_pointer_button(dt: VoidPtr, button: u32, act: u32){ - let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) }; - (cb.on_wl_pointer_button)(button, act); -} - -extern "C" fn allie_AliceCallbacks_on_wl_keyboard_key(dt: VoidPtr, keysym: u32, act: u32){ - let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) }; - (cb.on_wl_keyboard_key)(keysym, act); -} - -extern "C" fn allie_AliceCallbacks_on_another_frame(dt: VoidPtr, fl: f32){ - let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) }; - (cb.on_another_frame)(fl); -} - -extern "C" fn allie_AliceCallbacks_on_wl_pointer_motion(dt: VoidPtr, pos: vec2){ - let cb: &mut AliceCallbacks = unsafe { &mut *(dt as *mut AliceCallbacks) }; - (cb.on_wl_pointer_motion)(pos); -} - -impl Alice { - pub fn new() -> Self { - Alice{opa: unsafe { allie_Alice_new() }} - } - - pub fn mainloop(&self, mut cb: AliceCallbacks) { - let guest_data = (&raw mut cb) as VoidPtr; - - let a_cb = allie_AliceCallbacks { - guest: guest_data, - on_wl_pointer_button: allie_AliceCallbacks_on_wl_pointer_button, - on_wl_keyboard_key: allie_AliceCallbacks_on_wl_keyboard_key, - on_another_frame: allie_AliceCallbacks_on_another_frame, - on_wl_pointer_motion: allie_AliceCallbacks_on_wl_pointer_motion, - }; - - unsafe{ allie_Alice_mainloop(self.opa, &a_cb) }; - } - - pub fn set_clear_color(&self, color: vec4) { - unsafe { allie_Alice_set_clear_color(self.opa, color) }; - } -} -impl Drop for Alice { - fn drop(&mut self) { - // todo: do something - } -} +mod allie; +pub mod alice; +pub mod uint_segments; diff --git a/src/l2/allie_rs/uint_segments.rs b/src/l2/allie_rs/uint_segments.rs new file mode 100644 index 0000000..579d918 --- /dev/null +++ b/src/l2/allie_rs/uint_segments.rs @@ -0,0 +1,20 @@ +/* I am not proud of this */ + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct UIntSegment{ + pub start: T, + pub len: T, +} + +impl UIntSegment { + pub fn new(start: T, len: T) -> Self{ Self {start, len} } +} + +pub type U32Segment = UIntSegment; +pub type U64Segment = UIntSegment; + +/* Common sense decided to die */ +impl From<& UIntSegment> for UIntSegment { + fn from(value: &UIntSegment) -> Self { *value } +} \ No newline at end of file diff --git a/src/l3/r4/r4d.rs b/src/l3/r4/r4d.rs index 9b65fb7..c76d0ce 100644 --- a/src/l3/r4/r4d.rs +++ b/src/l3/r4/r4d.rs @@ -1,11 +1,18 @@ -use alice_and_misc::{*}; +use alice_and_misc::alice::{*}; use alice_and_misc::geom::{*}; +use alice_and_misc::uint_segments::U32Segment; fn main() { let v = vec2(1.0, 2.0); - let alice = Alice::new(); - alice.set_clear_color(vec4(0., 1., 0., 1.)); + let mut alice = Alice::new(); + alice.set_clear_color(vec4(0., 0.5, 0.5, 1.)); + let mut face = alice.new_lucy_face("./src/l3/fonts/DMSerifText-Regular.ttf"); + let mut face_40 = face.of_size(40); + alice.lucy_cache_add_glyphs(vec![ + LucyGlyphCachingRequest{sized_face: &mut face_40, + codepoint_ranges: vec![U32Segment::new(32, 126 - 32 + 1)]} + ]); alice.mainloop(AliceCallbacks{ on_wl_pointer_button: Box::new(|_: u32, _: u32| { println!("pointer button") @@ -14,7 +21,8 @@ fn main() { println!("keyboard key"); }), on_another_frame: Box::new(|_: f32| { - + alice.lucy_renderer_add_simple_label(&face_40, vec4(1., 0.5, 0., 1.), + 0, "Hello from Rust", ivec2(40, 40)); }), on_wl_pointer_motion: Box::new(|_: vec2| { println!("pointer motion");