Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions examples/demo-app/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,24 @@ use std::path::PathBuf;
fn main() {
let foreign = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("foreign-code");
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let lib = equilibrium_ffi::load(foreign.join("math.c")).expect("load math.c");
if let Some(code) = lib.bindings_code() {
std::fs::write(out_dir.join("math_bindings.rs"), code).expect("write bindings");

if cfg!(target_os = "macos") && std::path::Path::new("/usr/bin/ar").exists() {
// SAFETY: build scripts are single-threaded at the point this runs.
unsafe {
std::env::set_var("AR", "/usr/bin/ar");
}
}
println!("cargo:rerun-if-changed=foreign-code/*");
cc::Build::new()
.file(foreign.join("math.c"))
.compile("math");

let binding = equilibrium_ffi::generate_bindings(
&foreign.join("math.h"),
&equilibrium_ffi::BindingOptions::default(),
)
.expect("generate bindings");
std::fs::write(out_dir.join("math_bindings.rs"), binding.code).expect("write bindings");

println!("cargo:rerun-if-changed=foreign-code/math.c");
println!("cargo:rerun-if-changed=foreign-code/math.h");
}
24 changes: 20 additions & 4 deletions examples/full-demo/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,25 @@ use std::path::PathBuf;
fn main() {
let foreign = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("foreign-code");
let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap());
let lib = equilibrium_ffi::load(foreign.join("calculator.c")).expect("load calculator.c");
if let Some(code) = lib.bindings_code() {
std::fs::write(out_dir.join("calculator_bindings.rs"), code).expect("write bindings");

if cfg!(target_os = "macos") && std::path::Path::new("/usr/bin/ar").exists() {
// SAFETY: build scripts are single-threaded at the point this runs.
unsafe {
std::env::set_var("AR", "/usr/bin/ar");
}
}
println!("cargo:rerun-if-changed=foreign-code/*");
cc::Build::new()
.file(foreign.join("calculator.c"))
.compile("calculator");
println!("cargo:rustc-link-lib=m");

let binding = equilibrium_ffi::generate_bindings(
&foreign.join("calculator.h"),
&equilibrium_ffi::BindingOptions::default(),
)
.expect("generate bindings");
std::fs::write(out_dir.join("calculator_bindings.rs"), binding.code).expect("write bindings");

println!("cargo:rerun-if-changed=foreign-code/calculator.c");
println!("cargo:rerun-if-changed=foreign-code/calculator.h");
}
32 changes: 13 additions & 19 deletions examples/full-demo/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,31 @@
//! Full Demo - Actually calling C functions from Rust via FFI

extern "C" {
fn calc_add(a: i32, b: i32) -> i32;
fn calc_subtract(a: i32, b: i32) -> i32;
fn calc_multiply(a: i32, b: i32) -> i32;
fn calc_divide(a: f64, b: f64) -> f64;
fn calc_power(base: i32, exp: i32) -> i32;
fn calc_sqrt(n: f64) -> f64;
mod ffi {
include!(concat!(env!("OUT_DIR"), "/calculator_bindings.rs"));
}

fn main() {
println!("=== Full Equilibrium Demo ===");
println!("Calling C functions from Rust!\n");

unsafe {
// Arithmetic operations
println!("Arithmetic:");
println!(" 10 + 5 = {}", calc_add(10, 5));
println!(" 10 - 5 = {}", calc_subtract(10, 5));
println!(" 10 * 5 = {}", calc_multiply(10, 5));
println!(" 10.0 / 5.0 = {:.2}", calc_divide(10.0, 5.0));
println!(" 10 + 5 = {}", ffi::calc_add(10, 5));
println!(" 10 - 5 = {}", ffi::calc_subtract(10, 5));
println!(" 10 * 5 = {}", ffi::calc_multiply(10, 5));
println!(" 10.0 / 5.0 = {:.2}", ffi::calc_divide(10.0, 5.0));

// Advanced operations
println!("\nAdvanced:");
println!(" 2^8 = {}", calc_power(2, 8));
println!(" sqrt(144) = {:.2}", calc_sqrt(144.0));
println!(" sqrt(2) = {:.10}", calc_sqrt(2.0));
println!(" 2^8 = {}", ffi::calc_power(2, 8));
println!(" sqrt(144) = {:.2}", ffi::calc_sqrt(144.0));
println!(" sqrt(2) = {:.10}", ffi::calc_sqrt(2.0));
}

println!("\n✓ All C functions called successfully!");
println!("\nThis demonstrates:");
println!(" - C code compiled via cc crate");
println!(" - Rust FFI declarations");
println!(" - Rust FFI declarations generated by equilibrium-ffi");
println!(" - Calling C functions from Rust");
println!(" - Equilibrium would automate the FFI declaration part");
}
194 changes: 0 additions & 194 deletions examples/polyglot-gui/src/polyglot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,200 +322,6 @@ fn language_accent(lang: &str) -> &'static str {
}
}

pub fn constellation_lines(frame: &ConstellationFrame) -> Vec<String> {
frame
.rows
.iter()
.map(|row| {
debug_assert!(row.spans.iter().all(|span| span.start <= span.end
&& span.end <= row.text.len()
&& span.color <= 0x00ff_ffff));
row.text.clone()
})
.collect()
}

fn constellation_frame(
width: usize,
height: usize,
tick: f32,
stars: &[Star],
shooting_star: &ShootingStar,
bursts: &[Burst],
) -> ConstellationFrame {
let rows = height.clamp(6, 360);
let cols = width.clamp(20, 920);
let tick_bucket = (tick * 6.0) as usize;
let mut grid: Vec<Vec<ConstellationCell>> = (0..rows)
.map(|y| constellation_base_row(y, rows, cols, tick, tick_bucket))
.collect();

for star in stars {
let x = (star.x * cols as f32).clamp(0.0, (cols - 1) as f32) as usize;
let y = (star.y * rows as f32).clamp(0.0, (rows - 1) as f32) as usize;
let pulse = ((star.phase + tick * (0.35 + star.z)).sin() + 1.0) * 0.5;
let ch = match ((pulse * 5.0 + star.z * 3.0) as usize).min(7) {
0 => '.',
1 => '·',
2 => ':',
3 => '*',
4 => '+',
5 => 'o',
6 => '✦',
_ => '✧',
};
grid[y][x] = ConstellationCell {
ch,
color: language_color(7),
};
}

for i in 0..24 {
let fade = i as f32 / 24.0;
let tx = shooting_star.x - shooting_star.vx * i as f32 * 9.0;
let ty = shooting_star.y - shooting_star.vy * i as f32 * 9.0;
if (0.0..=1.0).contains(&tx) && (0.0..=1.0).contains(&ty) {
let x = (tx * cols as f32).clamp(0.0, (cols - 1) as f32) as usize;
let y = (ty * rows as f32).clamp(0.0, (rows - 1) as f32) as usize;
grid[y][x] = ConstellationCell {
ch: if fade < 0.2 {
'✦'
} else if fade < 0.45 {
'/'
} else if fade < 0.7 {
'·'
} else {
'.'
},
color: 0xf59e0b,
};
}
}

for burst in bursts {
let bx = (burst.x * cols as f32).clamp(0.0, (cols - 1) as f32) as i32;
let by = (burst.y * rows as f32).clamp(0.0, (rows - 1) as f32) as i32;
let radius = 1 + (burst.age * 4.0) as i32;
for dy in -radius..=radius {
for dx in -radius..=radius {
let x = bx + dx;
let y = by + dy;
if x >= 0
&& y >= 0
&& (x as usize) < cols
&& (y as usize) < rows
&& dx.abs() + dy.abs() <= radius
{
grid[y as usize][x as usize] = ConstellationCell {
ch: match burst.seed % 4 {
0 => '@',
1 => '#',
2 => '%',
_ => '&',
},
color: if burst.seed % 2 == 0 {
language_color(5)
} else {
language_color(6)
},
};
}
}
}
}

ConstellationFrame {
rows: grid.into_iter().map(constellation_row_data).collect(),
}
}

fn constellation_base_row(
y: usize,
rows: usize,
cols: usize,
tick: f32,
tick_bucket: usize,
) -> Vec<ConstellationCell> {
let fy = y as f32 / rows as f32;
let y_wave = (fy * 10.0 - tick * 0.25).cos();
(0..cols)
.map(|x| {
let fx = x as f32 / cols as f32;
let ribbon =
((fx * 12.0 + tick * 0.35).sin() + y_wave + ((fx + fy) * 18.0).sin() * 0.45) / 2.45;
let shimmer = (x * 17 + y * 29 + tick_bucket).is_multiple_of(113);
let ch = if shimmer {
':'
} else if ribbon > 0.78 {
'.'
} else if ribbon > 0.62 {
'·'
} else if ribbon < -0.86 {
','
} else {
' '
};
let color = match ch {
':' => {
if (x + y + tick_bucket).is_multiple_of(2) {
language_color(3)
} else {
language_color(4)
}
}
'.' | '·' => language_color(0),
',' => language_color(1),
_ => 0x334155,
};
ConstellationCell { ch, color }
})
.collect()
}

fn language_color(index: usize) -> u32 {
match index % 8 {
0 => 0x10b981,
1 => 0x38bdf8,
2 => 0xf59e0b,
3 => 0x22d3ee,
4 => 0x4ade80,
5 => 0x60a5fa,
6 => 0xfb7185,
_ => 0xe879f9,
}
}

fn constellation_row_data(row: Vec<ConstellationCell>) -> ConstellationRow {
let mut text = String::with_capacity(row.len() * 2);
let mut spans = Vec::new();
let mut run_start = 0usize;
let mut run_color = row.first().map_or(0x334155, |cell| cell.color);

for cell in row {
let start = text.len();
if cell.color != run_color && start > run_start {
spans.push(ConstellationSpan {
start: run_start,
end: start,
color: run_color,
});
run_start = start;
run_color = cell.color;
}
text.push(cell.ch);
}

if text.len() > run_start {
spans.push(ConstellationSpan {
start: run_start,
end: text.len(),
color: run_color,
});
}

ConstellationRow { text, spans }
}

pub fn rust_is_prime(n: u64) -> bool {
if n < 2 {
return false;
Expand Down
Loading
Loading