mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-29 21:34:50 +00:00
Add another way to load .60 files from a build script
This commit is contained in:
parent
0553ab8b1a
commit
9fc60e104f
10 changed files with 219 additions and 2 deletions
|
@ -8,12 +8,14 @@ members = [
|
|||
'sixtyfps_compiler/parser_test_macro',
|
||||
'api/sixtyfps-rs',
|
||||
'api/sixtyfps-rs/sixtyfps-rs-macro',
|
||||
'api/sixtyfps-rs/sixtyfps-build',
|
||||
'api/sixtyfps-node/native',
|
||||
'tools/compiler',
|
||||
'tools/viewer',
|
||||
'tools/syntax_updater',
|
||||
'examples/graphicstest',
|
||||
'examples/rusttest',
|
||||
'examples/rusttest2',
|
||||
'examples/rustwasmtest',
|
||||
'helper_crates/const-field-offset',
|
||||
'helper_crates/vtable',
|
||||
|
|
|
@ -1,6 +1,72 @@
|
|||
/*!
|
||||
# SixtyFPS
|
||||
|
||||
This create is the main entry point for project using SixtyFPS UI in rust.
|
||||
|
||||
## How to use:
|
||||
|
||||
There are two ways to use this crate.
|
||||
|
||||
- The `.60` code inline in a macro.
|
||||
- The `.60` code in external files compiled with `build.rs`
|
||||
|
||||
### The .60 code in a macro
|
||||
|
||||
This is the simpler way, just put the
|
||||
|
||||
```rust
|
||||
sixtyfps::sixtyfps!{
|
||||
HelloWolrd := Text { text: "hello world"; }
|
||||
}
|
||||
fn main() {
|
||||
# return; // Don't run a window in an example
|
||||
HelloWolrd::default().run()
|
||||
}
|
||||
```
|
||||
|
||||
### The .60 file in external files compiled with `build.rs`
|
||||
|
||||
In your Cargo.toml:
|
||||
|
||||
FIXME! set the version
|
||||
|
||||
```toml
|
||||
[package]
|
||||
...
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
sixtyfps = "*"
|
||||
...
|
||||
|
||||
[build-dependencies]
|
||||
sixtyfps-build = "*"
|
||||
```
|
||||
|
||||
In the `build.rs` file:
|
||||
|
||||
```ignore
|
||||
fn main() {
|
||||
sixtyfps_build::compile("ui/hello.60");
|
||||
}
|
||||
```
|
||||
|
||||
Then in your main file
|
||||
|
||||
```ignore
|
||||
sixtyfps::include_modules!();
|
||||
fn main() {
|
||||
HelloWolrd::default().run()
|
||||
}
|
||||
```
|
||||
*/
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
pub use sixtyfps_rs_macro::sixtyfps;
|
||||
|
||||
/// internal re_exports used by the macro generated
|
||||
#[doc(hidden)]
|
||||
pub mod re_exports {
|
||||
pub use const_field_offset::{self, FieldOffsets};
|
||||
pub use corelib::abi::datastructures::{Component, ComponentTO, ComponentVTable, ItemTreeNode};
|
||||
|
@ -17,3 +83,11 @@ pub mod re_exports {
|
|||
|
||||
#[cfg(doctest)]
|
||||
mod compile_fail_tests;
|
||||
|
||||
/// Include the code generated with the sixtyfps-build crate from the build script
|
||||
#[macro_export]
|
||||
macro_rules! include_modules {
|
||||
() => {
|
||||
include!(env!("SIXTYFPS_INCLUDE_GENERATED"));
|
||||
};
|
||||
}
|
||||
|
|
12
api/sixtyfps-rs/sixtyfps-build/Cargo.toml
Normal file
12
api/sixtyfps-rs/sixtyfps-build/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "sixtyfps-build"
|
||||
version = "0.1.0"
|
||||
authors = ["Sixty FPS <info@sixtyfps.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies]
|
||||
sixtyfps_compilerlib = { path = "../../../sixtyfps_compiler", features = ["rust", "display-diagnostics"] }
|
||||
thiserror = "1"
|
77
api/sixtyfps-rs/sixtyfps-build/lib.rs
Normal file
77
api/sixtyfps-rs/sixtyfps-build/lib.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*!
|
||||
This crate serves as a compagnon crate for the sixtyfps crate.
|
||||
It is meant to be able to compile the `.60` files from your `build.rs`script
|
||||
|
||||
The main entry point of this crate is the gernerate() function
|
||||
*/
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use sixtyfps_compilerlib::*;
|
||||
use std::env;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
/// Error returned by the `compile` function
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum CompileError {
|
||||
/// Cannot read environment variable CARGO_MANIFEST_DIR or OUT_DIR. The build script need to be run via cargo.
|
||||
#[error("Cannot read environment variable CARGO_MANIFEST_DIR or OUT_DIR. The build script need to be run via cargo.")]
|
||||
NotRunViaCargo,
|
||||
/// Cannot load the input .60 file
|
||||
#[error("Cannot load the .60 file: {0}")]
|
||||
LoadError(std::io::Error),
|
||||
/// Parse error. The error are printed in the stderr, and also are in the vector
|
||||
#[error("{0:?}")]
|
||||
CompileError(Vec<String>),
|
||||
/// Cannot write the generated file
|
||||
#[error("Cannot load the .60 file: {0}")]
|
||||
SaveError(std::io::Error),
|
||||
}
|
||||
|
||||
/// Compile the `.60` file and generate rust code for it.
|
||||
///
|
||||
/// The path is relative to the `CARGO_MANIFEST_DIR`.
|
||||
///
|
||||
/// The following line need to be added within your crate to include the generated code.
|
||||
/// ```ignore
|
||||
/// sixtyfps::include_modules!();
|
||||
/// ```
|
||||
pub fn compile(path: impl AsRef<std::path::Path>) -> Result<(), CompileError> {
|
||||
let path = Path::new(&env::var_os("CARGO_MANIFEST_DIR").ok_or(CompileError::NotRunViaCargo)?)
|
||||
.join(path.as_ref());
|
||||
|
||||
let source = std::fs::read_to_string(&path).map_err(CompileError::LoadError)?;
|
||||
let (syntax_node, mut diag) = parser::parse(&source);
|
||||
diag.current_path = path.clone();
|
||||
|
||||
if diag.has_error() {
|
||||
let vec = diag.inner.iter().map(|d| d.message.clone()).collect();
|
||||
diag.print(source);
|
||||
return Err(CompileError::CompileError(vec));
|
||||
}
|
||||
|
||||
let mut tr = typeregister::TypeRegister::builtin();
|
||||
let doc = object_tree::Document::from_node(syntax_node, &mut diag, &mut tr);
|
||||
run_passes(&doc, &mut diag, &mut tr);
|
||||
|
||||
if diag.has_error() {
|
||||
let vec = diag.inner.iter().map(|d| d.message.clone()).collect();
|
||||
diag.print(source);
|
||||
return Err(CompileError::CompileError(vec));
|
||||
}
|
||||
|
||||
let output_file_path = Path::new(&env::var_os("OUT_DIR").ok_or(CompileError::NotRunViaCargo)?)
|
||||
.join(path.file_name().map(Path::new).unwrap_or(Path::new("sixtyfps_out.rs")));
|
||||
|
||||
let mut file = std::fs::File::create(&output_file_path).map_err(CompileError::SaveError)?;
|
||||
let generated = generator::rust::generate(&doc.root_component, &mut diag).ok_or_else(|| {
|
||||
let vec = diag.inner.iter().map(|d| d.message.clone()).collect();
|
||||
diag.print(source);
|
||||
CompileError::CompileError(vec)
|
||||
})?;
|
||||
write!(file, "{}", generated).map_err(CompileError::SaveError)?;
|
||||
println!("cargo:rerun-if-changed={}", path.to_string_lossy());
|
||||
println!("cargo:rustc-env=SIXTYFPS_INCLUDE_GENERATED={}", output_file_path.to_string_lossy());
|
||||
Ok(())
|
||||
}
|
12
examples/rusttest2/Cargo.toml
Normal file
12
examples/rusttest2/Cargo.toml
Normal file
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "rusttest2"
|
||||
version = "0.1.0"
|
||||
authors = ["Sixty FPS <info@sixtyfps.io>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
sixtyfps = { path = "../../api/sixtyfps-rs" }
|
||||
|
||||
[build-dependencies]
|
||||
sixtyfps-build = { path = "../../api/sixtyfps-rs/sixtyfps-build" }
|
3
examples/rusttest2/build.rs
Normal file
3
examples/rusttest2/build.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
fn main() {
|
||||
sixtyfps_build::compile("../cpptest/hello.60").unwrap();
|
||||
}
|
16
examples/rusttest2/src/main.rs
Normal file
16
examples/rusttest2/src/main.rs
Normal file
|
@ -0,0 +1,16 @@
|
|||
sixtyfps::include_modules!();
|
||||
|
||||
fn main() {
|
||||
let mut app = Hello::default();
|
||||
|
||||
app.plus_clicked.set_handler(|context, ()| {
|
||||
let app = context.component.downcast::<Hello>().unwrap();
|
||||
app.counter.set(app.counter.get(context) + 1);
|
||||
});
|
||||
app.minus_clicked.set_handler(|context, ()| {
|
||||
let app = context.component.downcast::<Hello>().unwrap();
|
||||
app.counter.set(app.counter.get(context) - 1);
|
||||
});
|
||||
|
||||
app.run();
|
||||
}
|
|
@ -1,7 +1,11 @@
|
|||
/*!
|
||||
# The SixtyFPS compiler
|
||||
# The SixtyFPS compiler library
|
||||
|
||||
The different modules tage the source code and transform into data structures
|
||||
**NOTE:** This library is an internal crate for the SixtyFPS project.
|
||||
This crate should not be used directly by application using SixtyFPS.
|
||||
You should use the `sixtyfps` crate instead
|
||||
|
||||
The different modules take the source code and transform into data structures
|
||||
according to the following schema
|
||||
|
||||
```text
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
/*!
|
||||
|
||||
# SixtyFPS runtime library
|
||||
|
||||
**NOTE:** This library is an internal crate for the SixtyFPS project.
|
||||
This crate should not be used directly by application using SixtyFPS.
|
||||
You should use the `sixtyfps` crate instead
|
||||
*/
|
||||
|
||||
pub mod graphics;
|
||||
pub mod input;
|
||||
pub mod layout;
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
/*!
|
||||
# SixtyFPS interpreter library
|
||||
|
||||
**NOTE:** This library is an internal crate for the SixtyFPS project.
|
||||
This crate should not be used directly by application using SixtyFPS.
|
||||
You should use the `sixtyfps` crate instead
|
||||
*/
|
||||
|
||||
mod dynamic_component;
|
||||
mod dynamic_type;
|
||||
mod eval;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue