Implemented prebuilt view. Same-process mode not working due to static variable not unifying after static link.
This commit is contained in:
parent
7e500558b2
commit
6b45f54a2e
|
@ -9,4 +9,5 @@ screenshot.*
|
|||
wip
|
||||
cargo-timing*
|
||||
large-image.*
|
||||
examples/_*.rs
|
||||
examples/_*.rs
|
||||
zero-ui-view-prebuilt/lib/zero_ui_view.*
|
|
@ -47,9 +47,10 @@ image = "0.23"
|
|||
# enable test util
|
||||
zero-ui-core = { path = "zero-ui-core", features = ["test_util"] }
|
||||
zero-ui-view = { path = "zero-ui-view" }
|
||||
zero-ui-view-prebuilt = { path = "zero-ui-view-prebuilt" }
|
||||
|
||||
[workspace]
|
||||
members = ["zero-ui-view-api", "zero-ui-view", "zero-ui-proc-macros", "zero-ui-core"]
|
||||
members = ["zero-ui-view-api", "zero-ui-view", "zero-ui-view-prebuilt", "zero-ui-proc-macros", "zero-ui-core"]
|
||||
exclude = ["dependencies/webrender"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
use zero_ui::prelude::*;
|
||||
|
||||
use zero_ui_view_prebuilt as zero_ui_view;
|
||||
|
||||
fn main() {
|
||||
// zero_ui_view::run_same_process(app_main);
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ use zero_ui::core::{image::ImageLimits, timer::Timers};
|
|||
use zero_ui::prelude::*;
|
||||
use zero_ui::widgets::image::properties::{image_error_view, image_loading_view, ImageErrorArgs, ImageLoadingArgs};
|
||||
|
||||
use zero_ui_view_prebuilt as zero_ui_view;
|
||||
|
||||
fn main() {
|
||||
// zero_ui_view::run_same_process(app_main);
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
//#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
use zero_ui::core::{
|
||||
units::{DipPoint, DipSize},
|
||||
window::WindowStateChangedArgs,
|
||||
};
|
||||
use zero_ui::prelude::*;
|
||||
|
||||
fn main() {
|
||||
// zero_ui_view::run_same_process(app_main);
|
||||
//use zero_ui_view_prebuilt as zero_ui_view;
|
||||
|
||||
zero_ui_view::init();
|
||||
app_main();
|
||||
fn main() {
|
||||
zero_ui_view::run_same_process(app_main);
|
||||
|
||||
//zero_ui_view::init();
|
||||
//app_main();
|
||||
}
|
||||
|
||||
fn app_main() {
|
||||
|
|
|
@ -13,6 +13,7 @@ fn main() {
|
|||
"doc" => doc(args),
|
||||
"expand" => expand(args),
|
||||
"build" | "b" => build(args),
|
||||
"prebuild" => prebuild(args),
|
||||
"clean" => clean(args),
|
||||
"asm" => asm(args),
|
||||
"help" | "--help" => help(args),
|
||||
|
@ -389,6 +390,29 @@ fn release_rust_flags(is_release: bool) -> (&'static str, String) {
|
|||
rust_flags
|
||||
}
|
||||
|
||||
// do prebuild
|
||||
// Compile the pre-build `zero-ui-view` release.
|
||||
fn prebuild(args: Vec<&str>) {
|
||||
cmd("cargo", &["build", "-p", "zero-ui-view", "--release"], &args);
|
||||
|
||||
let files = staticlib_files("target/release/zero_ui_view");
|
||||
|
||||
if files.is_empty() {
|
||||
error("no `staticlib` output found");
|
||||
return;
|
||||
}
|
||||
|
||||
for file in files {
|
||||
let target = format!("zero-ui-view-prebuilt/lib/{}", file_name(&file));
|
||||
if let Err(e) = std::fs::copy(&file, &target) {
|
||||
error(f!("failed to copy pre-build lib `{}` to `{}`, {}", file, target, e))
|
||||
}
|
||||
}
|
||||
|
||||
// test build
|
||||
cmd("cargo", &["build", "-p", "zero-ui-view-prebuilt", "--release"], &[]);
|
||||
}
|
||||
|
||||
// do clean [--test-crates] [--tools] [--workspace] [<cargo-clean-args>]
|
||||
// Remove workspace, test-crates and tools target directories.
|
||||
// USAGE:
|
||||
|
|
|
@ -265,6 +265,27 @@ pub fn build_test_cases() -> Vec<(String, String)> {
|
|||
}
|
||||
}
|
||||
|
||||
// Get "staticlib" crate output.
|
||||
pub fn staticlib_files(path: &str) -> Vec<String> {
|
||||
let unix = format!("{}.a", path);
|
||||
let windows = format!("{}.lib", path);
|
||||
|
||||
let mut r = vec![];
|
||||
if std::path::PathBuf::from(&unix).exists() {
|
||||
r.push(unix);
|
||||
}
|
||||
if std::path::PathBuf::from(&windows).exists() {
|
||||
r.push(windows);
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
// Extracts the file name from path, or panics.
|
||||
pub fn file_name(path: &str) -> String {
|
||||
std::path::PathBuf::from(path).file_name().unwrap().to_str().unwrap().to_owned()
|
||||
}
|
||||
|
||||
fn glob(pattern: &str) -> Vec<String> {
|
||||
match glob::glob(pattern) {
|
||||
Ok(iter) => iter
|
||||
|
|
|
@ -207,7 +207,7 @@ macro_rules! context_var {
|
|||
$(#[$outer])*
|
||||
///
|
||||
/// # ContextVar
|
||||
///
|
||||
///
|
||||
/// This `struct` is a [`ContextVar`](crate::var::ContextVar).
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
$vis struct $ident;
|
||||
|
|
|
@ -32,6 +32,7 @@ impl ViewConfig {
|
|||
/// Returns `true` if the current process is awaiting for the config to start the
|
||||
/// view process in the same process.
|
||||
pub(crate) fn waiting_same_process() -> bool {
|
||||
println!("[2]SAME_PROCESS_CONFIG@0x{:x}", (&SAME_PROCESS_CONFIG) as *const _ as usize);
|
||||
SAME_PROCESS_CONFIG.lock().is_some()
|
||||
}
|
||||
|
||||
|
@ -51,6 +52,7 @@ impl ViewConfig {
|
|||
|
||||
/// Wait for config from same-process.
|
||||
pub fn wait_same_process() -> ViewConfig {
|
||||
println!("[1]SAME_PROCESS_CONFIG@0x{:x}", (&SAME_PROCESS_CONFIG) as *const _ as usize);
|
||||
let mut config = SAME_PROCESS_CONFIG.lock();
|
||||
let waiter = Arc::new(Condvar::new());
|
||||
*config = Some(SameProcessConfig {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[package]
|
||||
name = "zero-ui-view-prebuilt"
|
||||
version = "0.1.0"
|
||||
authors = ["Samuel Guerra <sam.rodr.g@gmail.com>", "Well <well-r@hotmail.com>"]
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,8 @@
|
|||
use std::{env, path::Path};
|
||||
|
||||
fn main() {
|
||||
let dir = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
println!("cargo:rerun-if-changed=lib/*.lib");
|
||||
println!("cargo:rerun-if-changed=lib/*.a");
|
||||
println!("cargo:rustc-link-search={}", Path::new(&dir).join("lib").display());
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
# Build
|
||||
|
||||
Run `do prebuild` to compile the binaries used in this crate.
|
|
@ -0,0 +1,61 @@
|
|||
//! Pre-built [`zero-ui-view`].
|
||||
//!
|
||||
//! [`zero-ui-view`]: https://docs.rs/zero-ui-view
|
||||
|
||||
use std::sync::atomic::{AtomicU8, Ordering};
|
||||
|
||||
#[cfg(not(doc))]
|
||||
#[link(name = "zero_ui_view", kind = "static")]
|
||||
extern "C" {
|
||||
fn extern_init();
|
||||
fn extern_run_same_process(run_app: extern "C" fn()) -> !;
|
||||
}
|
||||
|
||||
/// Call the pre-built [`init`].
|
||||
///
|
||||
/// [`init`]: https://docs.rs/zero-ui-view/fn.init.html
|
||||
pub fn init() {
|
||||
// SAFETY: this is safe.
|
||||
#[cfg(not(doc))]
|
||||
unsafe {
|
||||
extern_init()
|
||||
}
|
||||
}
|
||||
|
||||
/// Call the pre-build [`run_same_process`].
|
||||
///
|
||||
/// [`run_same_process`]: https://docs.rs/zero-ui-view/fn.run_same_process.html
|
||||
pub fn run_same_process(run_app: impl FnOnce() + Send + 'static) -> ! {
|
||||
// SAFETY: access to `RUN` is atomic.
|
||||
|
||||
#[cfg(not(doc))]
|
||||
unsafe {
|
||||
static STATE: AtomicU8 = AtomicU8::new(ST_NONE);
|
||||
const ST_NONE: u8 = 0;
|
||||
const ST_SOME: u8 = 1;
|
||||
const ST_TAKEN: u8 = 2;
|
||||
|
||||
static mut RUN: Option<Box<dyn FnOnce() + Send>> = None;
|
||||
|
||||
if STATE.swap(ST_SOME, Ordering::SeqCst) != ST_NONE {
|
||||
panic!("expected only one call to `run_same_process`");
|
||||
}
|
||||
|
||||
RUN = Some(Box::new(run_app));
|
||||
|
||||
extern "C" fn run() {
|
||||
if STATE.swap(ST_TAKEN, Ordering::SeqCst) != ST_SOME {
|
||||
panic!("expected only one call to `run_app` closure");
|
||||
}
|
||||
|
||||
let run_app = unsafe { RUN.take() }.unwrap();
|
||||
run_app();
|
||||
}
|
||||
extern_run_same_process(run);
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
{
|
||||
unreachable!("expected `extern_run_same_process` to never return");
|
||||
}
|
||||
}
|
|
@ -5,6 +5,9 @@ authors = ["Samuel Guerra <sam.rodr.g@gmail.com>", "Well <well-r@hotmail.com>"]
|
|||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib", "staticlib"]
|
||||
|
||||
[dependencies]
|
||||
zero-ui-view-api = { path = "../zero-ui-view-api" }
|
||||
webrender = { path = "../dependencies/webrender/webrender" }
|
||||
|
|
|
@ -114,6 +114,12 @@ pub fn init() {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn extern_init() {
|
||||
init()
|
||||
}
|
||||
|
||||
/// Runs the view-process server in the current process and calls `run_app` to also
|
||||
/// run the app in the current process. Note that `run_app` will be called in a different thread
|
||||
/// so it must be [`Send`].
|
||||
|
@ -172,6 +178,13 @@ pub fn run_same_process(run_app: impl FnOnce() + Send + 'static) -> ! {
|
|||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn extern_run_same_process(run_app: extern "C" fn()) -> ! {
|
||||
#[allow(clippy::redundant_closure)]
|
||||
run_same_process(move || run_app())
|
||||
}
|
||||
|
||||
/// The backend implementation.
|
||||
pub(crate) struct App<S> {
|
||||
started: bool,
|
||||
|
|
Loading…
Reference in New Issue