mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21:16 +00:00
Remove some duplication in the documentation of API that's shared between Rust and C++
This change makes the start of sharing the docs for the `TimerMode` enum between Rust and C++. The reference to Timer::start in there works as both doxygen and rustdoc find the right reference, but this needs careful editing in the future and double-checking! Another "caveat" is that the docs for the TimerMode enum say that the enum is defined in the file "sixtyfps_generated_public.h", which is correct as-is but not as pretty as "sixtyfps.h". I tried various ways with \file and \includedoc, but couldn't get it working differently. To implement this, the cppdocs steps now also runs cbindgen and cbindgen generates a new sixtyfps_generated_public.h file that contains types we do want to have in the public sixtyfps namespace.
This commit is contained in:
parent
81602353e2
commit
174fd2659f
6 changed files with 72 additions and 36 deletions
|
@ -20,5 +20,9 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
|
||||
println!("cargo:GENERATED_INCLUDE_DIR={}", output_dir.display());
|
||||
|
||||
cbindgen::gen_all(&root_dir, &output_dir)
|
||||
let dependencies = cbindgen::gen_all(&root_dir, &output_dir)?;
|
||||
for path in dependencies {
|
||||
println!("cargo:rerun-if-changed={}", path.display());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -3,16 +3,19 @@
|
|||
|
||||
use anyhow::Context;
|
||||
use std::iter::Extend;
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
// cspell::ignore compat constexpr corelib sharedvector pathdata
|
||||
|
||||
fn ensure_cargo_rerun_for_crate(crate_dir: &Path) -> anyhow::Result<()> {
|
||||
println!("cargo:rerun-if-changed={}", crate_dir.display());
|
||||
fn ensure_cargo_rerun_for_crate(
|
||||
crate_dir: &Path,
|
||||
dependencies: &mut Vec<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
dependencies.push(crate_dir.to_path_buf());
|
||||
for entry in std::fs::read_dir(crate_dir)? {
|
||||
let entry = entry?;
|
||||
if entry.path().extension().map_or(false, |e| e == "rs") {
|
||||
println!("cargo:rerun-if-changed={}", entry.path().display());
|
||||
dependencies.push(entry.path());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -76,7 +79,11 @@ extern "C" {{
|
|||
)
|
||||
}
|
||||
|
||||
fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
||||
fn gen_corelib(
|
||||
root_dir: &Path,
|
||||
include_dir: &Path,
|
||||
dependencies: &mut Vec<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut config = default_config();
|
||||
|
||||
let items = [
|
||||
|
@ -150,6 +157,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
"sixtyfps_color_darker",
|
||||
"sixtyfps_image_size",
|
||||
"sixtyfps_image_path",
|
||||
"TimerMode", // included in generated_public.h
|
||||
]
|
||||
.iter()
|
||||
.map(|x| x.to_string())
|
||||
|
@ -158,7 +166,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
let mut crate_dir = root_dir.to_owned();
|
||||
crate_dir.extend(["sixtyfps_runtime", "corelib"].iter());
|
||||
|
||||
ensure_cargo_rerun_for_crate(&crate_dir)?;
|
||||
ensure_cargo_rerun_for_crate(&crate_dir, dependencies)?;
|
||||
|
||||
let mut string_config = config.clone();
|
||||
string_config.export.exclude = vec!["SharedString".into()];
|
||||
|
@ -296,6 +304,20 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
.write_to_file(include_dir.join(internal_header));
|
||||
}
|
||||
|
||||
// Generate a header file with some public API (enums, etc.)
|
||||
let mut public_config = config.clone();
|
||||
public_config.namespaces = Some(vec!["sixtyfps".into()]);
|
||||
public_config.export.item_types = vec![cbindgen::ItemType::Enums];
|
||||
public_config.export.include = vec!["TimerMode".into()];
|
||||
public_config.export.exclude.clear();
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_config(public_config)
|
||||
.with_src(crate_dir.join("timers.rs"))
|
||||
.generate()
|
||||
.context("Unable to generate bindings for sixtyfps_generated_public.h")?
|
||||
.write_to_file(include_dir.join("sixtyfps_generated_public.h"));
|
||||
|
||||
config.export.body.insert(
|
||||
"ItemTreeNode".to_owned(),
|
||||
" constexpr ItemTreeNode(Item_Body x) : item {x} {}
|
||||
|
@ -335,6 +357,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
.with_include("sixtyfps_image.h")
|
||||
.with_include("sixtyfps_pathdata.h")
|
||||
.with_include("sixtyfps_brush.h")
|
||||
.with_include("sixtyfps_generated_public.h")
|
||||
.with_header(format!(
|
||||
r"
|
||||
#define SIXTYFPS_VERSION_MAJOR {}
|
||||
|
@ -367,7 +390,11 @@ namespace sixtyfps {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn gen_backend_qt(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
||||
fn gen_backend_qt(
|
||||
root_dir: &Path,
|
||||
include_dir: &Path,
|
||||
dependencies: &mut Vec<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut config = default_config();
|
||||
|
||||
let items = [
|
||||
|
@ -395,7 +422,7 @@ fn gen_backend_qt(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
let mut crate_dir = root_dir.to_owned();
|
||||
crate_dir.extend(["sixtyfps_runtime", "rendering_backends", "qt"].iter());
|
||||
|
||||
ensure_cargo_rerun_for_crate(&crate_dir)?;
|
||||
ensure_cargo_rerun_for_crate(&crate_dir, dependencies)?;
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_config(config)
|
||||
|
@ -409,12 +436,16 @@ fn gen_backend_qt(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn gen_backend(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
||||
fn gen_backend(
|
||||
root_dir: &Path,
|
||||
include_dir: &Path,
|
||||
dependencies: &mut Vec<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
let config = default_config();
|
||||
let mut crate_dir = root_dir.to_owned();
|
||||
crate_dir.extend(["api", "sixtyfps-cpp"].iter());
|
||||
|
||||
ensure_cargo_rerun_for_crate(&crate_dir)?;
|
||||
ensure_cargo_rerun_for_crate(&crate_dir, dependencies)?;
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_config(config)
|
||||
|
@ -427,14 +458,18 @@ fn gen_backend(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn gen_interpreter(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
||||
fn gen_interpreter(
|
||||
root_dir: &Path,
|
||||
include_dir: &Path,
|
||||
dependencies: &mut Vec<PathBuf>,
|
||||
) -> anyhow::Result<()> {
|
||||
let mut config = default_config();
|
||||
// Avoid Value, just export ValueOpaque.
|
||||
config.export.exclude.push("Value".into());
|
||||
let mut crate_dir = root_dir.to_owned();
|
||||
|
||||
crate_dir.extend(["sixtyfps_runtime", "interpreter"].iter());
|
||||
ensure_cargo_rerun_for_crate(&crate_dir)?;
|
||||
ensure_cargo_rerun_for_crate(&crate_dir, dependencies)?;
|
||||
|
||||
cbindgen::Builder::new()
|
||||
.with_config(config)
|
||||
|
@ -451,12 +486,15 @@ fn gen_interpreter(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
|||
/// Generate the headers.
|
||||
/// `root_dir` is the root directory of the sixtyfps git repo
|
||||
/// `include_dir` is the output directory
|
||||
pub fn gen_all(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
|
||||
/// Returns the list of all paths that contain dependencies to the generated output. If you call this
|
||||
/// function from build.rs, feed each entry to stdout prefixed with `cargo:rerun-if-changed=`.
|
||||
pub fn gen_all(root_dir: &Path, include_dir: &Path) -> anyhow::Result<Vec<PathBuf>> {
|
||||
proc_macro2::fallback::force(); // avoid a abort if panic=abort is set
|
||||
std::fs::create_dir_all(include_dir).context("Could not create the include directory")?;
|
||||
gen_corelib(root_dir, include_dir)?;
|
||||
gen_backend_qt(root_dir, include_dir)?;
|
||||
gen_backend(root_dir, include_dir)?;
|
||||
gen_interpreter(root_dir, include_dir)?;
|
||||
Ok(())
|
||||
let mut deps = Vec::new();
|
||||
gen_corelib(root_dir, include_dir, &mut deps)?;
|
||||
gen_backend_qt(root_dir, include_dir, &mut deps)?;
|
||||
gen_backend(root_dir, include_dir, &mut deps)?;
|
||||
gen_interpreter(root_dir, include_dir, &mut deps)?;
|
||||
Ok(deps)
|
||||
}
|
||||
|
|
|
@ -56,8 +56,8 @@ exhale_args = {
|
|||
"doxygenStripFromPath": "..",
|
||||
"createTreeView": True,
|
||||
"exhaleExecutesDoxygen": True,
|
||||
"exhaleDoxygenStdin": """INPUT = ../../api/sixtyfps-cpp/include
|
||||
EXCLUDE_SYMBOLS = sixtyfps::cbindgen_private* sixtyfps::private_api* vtable*
|
||||
"exhaleDoxygenStdin": """INPUT = ../../api/sixtyfps-cpp/include generated_include
|
||||
EXCLUDE_SYMBOLS = sixtyfps::cbindgen_private* sixtyfps::private_api* vtable* SIXTYFPS_DECL_ITEM
|
||||
EXCLUDE = ../../api/sixtyfps-cpp/include/vtable.h ../../api/sixtyfps-cpp/include/sixtyfps_testing.h
|
||||
ENABLE_PREPROCESSING = YES
|
||||
PREDEFINED += DOXYGEN
|
||||
|
|
|
@ -337,20 +337,6 @@ private:
|
|||
private_api::WindowRc inner;
|
||||
};
|
||||
|
||||
#if !defined(DOXYGEN)
|
||||
using cbindgen_private::TimerMode;
|
||||
#else
|
||||
/// The TimerMode specifies what should happen after the timer fired.
|
||||
///
|
||||
/// Used by the sixtyfps::Timer::start() function.
|
||||
enum class TimerMode {
|
||||
/// A SingleShot timer is fired only once.
|
||||
SingleShot,
|
||||
/// A Repeated timer is fired repeatedly until it is stopped or dropped.
|
||||
Repeated,
|
||||
};
|
||||
#endif
|
||||
|
||||
/// A Timer that can call a callback at repeated interval
|
||||
///
|
||||
/// Use the static single_shot function to make a single shot timer
|
||||
|
@ -367,7 +353,7 @@ struct Timer
|
|||
template<typename F>
|
||||
Timer(std::chrono::milliseconds interval, F callback)
|
||||
: id(cbindgen_private::sixtyfps_timer_start(
|
||||
-1, cbindgen_private::TimerMode::Repeated, interval.count(),
|
||||
-1, TimerMode::Repeated, interval.count(),
|
||||
[](void *data) { (*reinterpret_cast<F *>(data))(); }, new F(std::move(callback)),
|
||||
[](void *data) { delete reinterpret_cast<F *>(data); }))
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue