1mod abi;
9mod context;
10mod dialog;
11mod download;
12mod ffi;
13mod logic;
14mod lower;
15mod place;
16mod program;
17mod show;
18pub mod symbols;
19mod value;
20mod window;
21
22use std::process;
23use std::rc::Rc;
24
25use nifty_runtime::{AppTemplate, Backend, Engine, ErrorHandler, Ui};
26
27pub use context::{AppError, Context, SourceLocation};
28pub use download::{DownloadBinding, DownloadDesc};
29pub use ffi::{Slice, Str};
30pub use logic::{Binding, Compiled, Frame, Region};
31pub use place::{PathStep, PlaceDesc, StepKind};
32pub use program::{
33 ABI_VERSION, ActionFn, BindingDesc, ExpandFn, FrameDesc, InitFn, MenuDesc, MenuEntryDesc,
34 MenuEntryKind, ProgramDesc, ReadFn, RegionDesc, ShortcutDesc, SpanDesc, StateDesc,
35 TemplateDesc, TemplateKind, ViewDesc, WindowDesc, WriteFn,
36};
37pub use show::Sink;
38pub use value::{BOOL, FLOAT, INT, STRING, Slot, TypeDesc, TypeKind};
39
40const EXIT_FAILED: i32 = 1;
42
43#[cfg(target_os = "macos")]
48pub const NATIVE_LIBS: &[&str] = &[
49 "-lc",
50 "-lm",
51 "-liconv",
52 "-lobjc",
53 "-framework",
54 "AppKit",
55 "-framework",
56 "CloudKit",
57 "-framework",
58 "CoreData",
59 "-framework",
60 "CoreFoundation",
61 "-framework",
62 "CoreGraphics",
63 "-framework",
64 "CoreImage",
65 "-framework",
66 "CoreText",
67 "-framework",
68 "CoreVideo",
69 "-framework",
70 "Foundation",
71 "-framework",
72 "QuartzCore",
73 "-framework",
74 "Security",
75];
76
77#[cfg(windows)]
79pub const NATIVE_LIBS: &[&str] = &[
80 "kernel32.lib",
81 "ntdll.lib",
82 "userenv.lib",
83 "ws2_32.lib",
84 "dbghelp.lib",
85 "/defaultlib:libcmt",
86];
87
88#[derive(Debug)]
90pub struct Prepared {
91 app: AppTemplate<Compiled>,
92 views: Vec<logic::ViewTemplate>,
93 context: Context,
94}
95
96pub fn prepare(program: &'static ProgramDesc) -> Result<Prepared, AppError> {
101 let lower::Lowered { app, views } = lower::lower(program)?;
102 let context = Context::new(program)?;
103 Ok(Prepared {
104 app,
105 views,
106 context,
107 })
108}
109
110impl Prepared {
111 pub fn show<B: Backend>(
116 self,
117 ui: Ui<B>,
118 on_error: ErrorHandler<AppError>,
119 ) -> Result<Rc<Engine<Compiled, B>>, AppError> {
120 let Self {
121 app,
122 views,
123 context,
124 } = self;
125 Engine::start(ui, app, on_error, |ui, engine| {
126 Compiled::new(context, views, ui, engine)
127 })
128 }
129}
130
131#[unsafe(no_mangle)]
139pub unsafe extern "C" fn nifty_rt_main(program: *const ProgramDesc) -> i32 {
140 let Some(program) = (unsafe { program.as_ref() }) else {
142 eprintln!("{}", AppError::malformed("its program is missing"));
143 return EXIT_FAILED;
144 };
145 let on_error = Rc::new(|error: AppError| {
146 eprintln!("{error}");
147 process::exit(EXIT_FAILED);
148 });
149 let shown = prepare(program)
150 .and_then(|prepared| prepared.show(Ui::new(nifty_platform::platform_backend()), on_error));
151 match shown {
152 Ok(engine) => {
153 engine.run();
154 0
155 }
156 Err(error) => {
157 eprintln!("{error}");
158 EXIT_FAILED
159 }
160 }
161}
162
163#[cfg(test)]
164mod tests;