From 7d72cca2cf259598f66e18423aa67a83094e6665 Mon Sep 17 00:00:00 2001 From: numzero Date: Sun, 25 Oct 2026 14:28:37 +0300 Subject: [PATCH] do it, ugly --- ui/CMakeLists.txt | 8 ++--- ui/Cargo.toml | 3 -- ui/build.rs | 7 +++++ ui/src/api.hxx | 2 +- ui/src/lib.rs | 75 ++++++++++++++++++++++++++++++++++------------- ui/src/main.cxx | 15 ---------- ui/src/main.rs | 26 ++++++++++++++++ 7 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 ui/build.rs create mode 100644 ui/src/main.rs diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt index 5a46b32..1115c6c 100644 --- a/ui/CMakeLists.txt +++ b/ui/CMakeLists.txt @@ -1,12 +1,12 @@ include(impl.cmake) -qt_add_executable(PROJECT-NAME +qt_add_library(PROJECT_NAME_ui STATIC src/main.cxx src/main_window.cxx src/main_window.ui src/viewport.cxx ) -target_link_libraries(PROJECT-NAME PRIVATE Qt6::Gui Qt6::Widgets) -target_link_libraries(PROJECT-NAME PRIVATE PROJECT_NAME_impl) -target_include_directories(PROJECT-NAME PRIVATE src) +target_link_libraries(PROJECT_NAME_ui PRIVATE Qt6::Gui Qt6::Widgets) +target_link_libraries(PROJECT_NAME_ui PRIVATE PROJECT_NAME_impl) +target_include_directories(PROJECT_NAME_ui PRIVATE src) diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 6565f4f..ff3b380 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -3,9 +3,6 @@ name = "PROJECT-NAME-impl" version = "0.1.0" edition = "2024" -[lib] -crate-type = ["staticlib"] - [dependencies] PROJECT-NAME = {path = "../"} diff --git a/ui/build.rs b/ui/build.rs new file mode 100644 index 0000000..22e3f25 --- /dev/null +++ b/ui/build.rs @@ -0,0 +1,7 @@ +fn main() { + println!("cargo::rustc-link-search=native=build/ui"); + println!("cargo::rustc-link-lib=dylib=Qt6Core"); + println!("cargo::rustc-link-lib=dylib=Qt6Gui"); + println!("cargo::rustc-link-lib=dylib=Qt6Widgets"); + println!("cargo::rustc-link-lib=dylib=stdc++"); +} diff --git a/ui/src/api.hxx b/ui/src/api.hxx index e73e15c..304d2a1 100644 --- a/ui/src/api.hxx +++ b/ui/src/api.hxx @@ -43,7 +43,7 @@ public: virtual void redraw(const RedrawArgs& args) = 0; }; -class ICoreFactory : public IBoxed { +class ICoreFactory { private: virtual ICore* new_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) const = 0; diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 62cabac..c5c4119 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -1,12 +1,12 @@ -use std::{ffi::c_void, num::NonZero, ptr::NonNull}; +use PROJECT_NAME::{Core, init_gpu_inner}; +use glam::UVec2; +use raw_window_handle::{RawDisplayHandle, RawWindowHandle}; -use PROJECT_NAME::{Core, RedrawArgs, init_gpu_inner}; -use glam::{UVec2, uvec2}; -use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle}; +use crate::core::ICoreImpl; -use crate::vtable::ICoreImpl; +pub use factory::ICoreFactoryImpl; -mod vtable { +mod core { use std::ops::{Deref, DerefMut}; use PROJECT_NAME::{Core, RedrawArgs}; @@ -32,9 +32,9 @@ mod vtable { } static VTABLE: ICoreVTable = ICoreVTable { - destroy: destroy, - configure: configure, - redraw: redraw, + destroy, + configure, + redraw, }; #[repr(C)] @@ -67,6 +67,51 @@ mod vtable { } } +mod factory { + use std::{ffi::c_void, num::NonZero, ptr::NonNull}; + + use glam::uvec2; + use raw_window_handle::{XcbDisplayHandle, XcbWindowHandle}; + + use crate::core::ICoreImpl; + + #[repr(C)] + struct ICoreFactoryVTable { + new_xcb: unsafe extern "C" fn( + this: &mut ICoreFactoryImpl, + connection: NonNull, + window: NonZero, + width: u32, + height: u32, + ) -> Box, + } + + unsafe extern "C" fn new_xcb( + _this: &mut ICoreFactoryImpl, + connection: NonNull, + window: NonZero, + width: u32, + height: u32, + ) -> Box { + let display = XcbDisplayHandle::new(Some(connection), 0); + let window = XcbWindowHandle::new(window); + unsafe { crate::create_viewport(display, window, uvec2(width, height)) } + } + + static VTABLE: ICoreFactoryVTable = ICoreFactoryVTable { new_xcb }; + + #[repr(C)] + pub struct ICoreFactoryImpl { + vtable: &'static ICoreFactoryVTable, + } + + impl ICoreFactoryImpl { + pub fn new() -> Self { + ICoreFactoryImpl { vtable: &VTABLE } + } + } +} + unsafe fn create_viewport( display: impl Into, window: impl Into, @@ -82,15 +127,3 @@ unsafe fn create_viewport( .unwrap(); ICoreImpl::new(Core::new(gpu, size)) } - -#[unsafe(no_mangle)] -unsafe extern "C" fn rt4_viewport_create( - connection: NonNull, - window: NonZero, - width: u32, - height: u32, -) -> Box { - let display = XcbDisplayHandle::new(Some(connection), 0); - let window = XcbWindowHandle::new(window); - unsafe { create_viewport(display, window, uvec2(width, height)) } -} diff --git a/ui/src/main.cxx b/ui/src/main.cxx index 5488615..863d48e 100644 --- a/ui/src/main.cxx +++ b/ui/src/main.cxx @@ -14,18 +14,3 @@ extern "C" int run(int argc, char* argv[], ICoreFactory* factory) { return app.exec(); } - -extern "C" ICore* rt4_viewport_create(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height); - -class CoreFactory : public ICoreFactory { -public: - void destroy() override {} - ICore* new_xcb(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height) const override { - return rt4_viewport_create(connection, window, width, height); - } -}; - -int main(int argc, char* argv[]) { - CoreFactory factory; - return run(argc, argv, &factory); -} diff --git a/ui/src/main.rs b/ui/src/main.rs new file mode 100644 index 0000000..4b0d49f --- /dev/null +++ b/ui/src/main.rs @@ -0,0 +1,26 @@ +use std::ffi::{c_char, c_int}; + +use PROJECT_NAME_impl::ICoreFactoryImpl; + +#[link(kind = "static", name = "PROJECT_NAME_ui")] +unsafe extern "C" { + fn run(argc: c_int, argv: *mut *mut c_char, factory: &ICoreFactoryImpl) -> c_int; +} + +fn main() { + let factory = ICoreFactoryImpl::new(); + let mut args: Vec<_> = std::env::args().collect(); + let mut argv: Vec<*mut c_char> = args + .iter_mut() + .map(|s| s.as_mut_ptr() as *mut c_char) + .collect(); + argv.push(std::ptr::null_mut()); + let exit_code = unsafe { + run( + args.len().try_into().expect("WAY too many arguments"), + argv.as_mut_ptr(), + &factory, + ) + }; + std::process::exit(exit_code); +}