mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 05:44:52 +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',
|
'sixtyfps_compiler/parser_test_macro',
|
||||||
'api/sixtyfps-rs',
|
'api/sixtyfps-rs',
|
||||||
'api/sixtyfps-rs/sixtyfps-rs-macro',
|
'api/sixtyfps-rs/sixtyfps-rs-macro',
|
||||||
|
'api/sixtyfps-rs/sixtyfps-build',
|
||||||
'api/sixtyfps-node/native',
|
'api/sixtyfps-node/native',
|
||||||
'tools/compiler',
|
'tools/compiler',
|
||||||
'tools/viewer',
|
'tools/viewer',
|
||||||
'tools/syntax_updater',
|
'tools/syntax_updater',
|
||||||
'examples/graphicstest',
|
'examples/graphicstest',
|
||||||
'examples/rusttest',
|
'examples/rusttest',
|
||||||
|
'examples/rusttest2',
|
||||||
'examples/rustwasmtest',
|
'examples/rustwasmtest',
|
||||||
'helper_crates/const-field-offset',
|
'helper_crates/const-field-offset',
|
||||||
'helper_crates/vtable',
|
'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;
|
pub use sixtyfps_rs_macro::sixtyfps;
|
||||||
|
|
||||||
/// internal re_exports used by the macro generated
|
/// internal re_exports used by the macro generated
|
||||||
|
#[doc(hidden)]
|
||||||
pub mod re_exports {
|
pub mod re_exports {
|
||||||
pub use const_field_offset::{self, FieldOffsets};
|
pub use const_field_offset::{self, FieldOffsets};
|
||||||
pub use corelib::abi::datastructures::{Component, ComponentTO, ComponentVTable, ItemTreeNode};
|
pub use corelib::abi::datastructures::{Component, ComponentTO, ComponentVTable, ItemTreeNode};
|
||||||
|
@ -17,3 +83,11 @@ pub mod re_exports {
|
||||||
|
|
||||||
#[cfg(doctest)]
|
#[cfg(doctest)]
|
||||||
mod compile_fail_tests;
|
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
|
according to the following schema
|
||||||
|
|
||||||
```text
|
```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 graphics;
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod layout;
|
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_component;
|
||||||
mod dynamic_type;
|
mod dynamic_type;
|
||||||
mod eval;
|
mod eval;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue