Compare commits

...

10 Commits

4 changed files with 118 additions and 9 deletions

24
bridge/Cargo.lock generated
View File

@@ -1732,6 +1732,15 @@ dependencies = [
"minimal-lexical",
]
[[package]]
name = "nu-ansi-term"
version = "0.50.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "num-traits"
version = "0.2.19"
@@ -2505,6 +2514,7 @@ dependencies = [
"stardust-xr-asteroids",
"stardust-xr-fusion",
"tokio",
"tracing-subscriber",
"zbus",
]
@@ -2877,6 +2887,17 @@ dependencies = [
"tracing-subscriber",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.20"
@@ -2884,13 +2905,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"parking_lot 0.12.5",
"regex-automata",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]

View File

@@ -13,6 +13,7 @@ glam = "0.28"
lazy_static = "1.4"
zbus = { version = "5.5.0", features = ["tokio"] }
serde = { version = "1.0", features = ["derive"] }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
[dependencies.stardust-xr-asteroids]
path = "../third_party/asteroids"

View File

@@ -0,0 +1,19 @@
// Minimal test to verify socket connection
use tokio::net::UnixStream;
#[tokio::main]
async fn main() {
let socket_path = std::env::var("XDG_RUNTIME_DIR")
.unwrap_or_else(|_| "/run/user/1000".to_string()) + "/stardust-0";
println!("Attempting to connect to: {}", socket_path);
match UnixStream::connect(&socket_path).await {
Ok(_stream) => {
println!("✓ Successfully connected to socket!");
}
Err(e) => {
println!("✗ Failed to connect: {}", e);
}
}
}

View File

@@ -10,7 +10,7 @@ use glam::Mat4;
use stardust_xr_asteroids as ast; // alias for brevity
use stardust_xr_asteroids::{
client::ClientState,
elements::{PlaySpace, Axes},
elements::{PlaySpace, Lines},
Migrate, Reify,
};
use stardust_xr_asteroids::{CustomElement, Transformable};
@@ -53,15 +53,35 @@ impl ClientState for BridgeState {
impl Reify for BridgeState {
fn reify(&self) -> impl ast::Element<Self> {
// Root playspace. Attach a visible Axes element per tracked node id.
// Root playspace. Attach a visible cube wireframe per tracked node id.
let children = self.nodes.iter().map(|(id, node)| {
// Decompose transform into TRS
let (scale, rot, trans) = node.transform.to_scale_rotation_translation();
// Make axes much larger and visible: default is 1cm, scale up to 20cm
let vis_scale = glam::Vec3::splat(20.0) * scale.x;
// Visible cube size: 20cm, scaled by node scale
let vis_scale = glam::Vec3::splat(0.20) * scale.x;
// Build cube edges as 12 line segments
use stardust_xr_molecules::lines::{line_from_points, LineExt};
use stardust_xr_fusion::values::color::rgba_linear;
let t = 0.004; // thickness
let c = rgba_linear!(0.8, 0.8, 0.9, 1.0);
let hs = 0.5f32; // half size in model space (unit cube)
let mut seg = |a: [f32;3], b: [f32;3]| {
line_from_points(vec![a, b]).thickness(t).color(c)
};
let corners = [
[-hs, -hs, -hs], [ hs, -hs, -hs], [ hs, hs, -hs], [-hs, hs, -hs],
[-hs, -hs, hs], [ hs, -hs, hs], [ hs, hs, hs], [-hs, hs, hs],
];
// Edges: 0-1-2-3-0 (bottom), 4-5-6-7-4 (top), verticals 0-4,1-5,2-6,3-7
let lines = vec![
seg(corners[0], corners[1]), seg(corners[1], corners[2]), seg(corners[2], corners[3]), seg(corners[3], corners[0]),
seg(corners[4], corners[5]), seg(corners[5], corners[6]), seg(corners[6], corners[7]), seg(corners[7], corners[4]),
seg(corners[0], corners[4]), seg(corners[1], corners[5]), seg(corners[2], corners[6]), seg(corners[3], corners[7]),
];
(
*id,
Axes::default()
Lines::new(lines)
.pos([trans.x, trans.y, trans.z])
.rot([rot.x, rot.y, rot.z, rot.w])
.scl([vis_scale.x, vis_scale.y, vis_scale.z])
@@ -76,6 +96,7 @@ impl Reify for BridgeState {
}
static STARTED: AtomicBool = AtomicBool::new(false);
static CONNECTED: AtomicBool = AtomicBool::new(false);
lazy_static::lazy_static! {
static ref CTRL: Mutex<Ctrl> = Mutex::new(Ctrl::default());
}
@@ -124,12 +145,18 @@ pub extern "C" fn sdxr_start(app_id: *const std::os::raw::c_char) -> i32 {
let shared_state = Arc::new(Mutex::new(BridgeState::default()));
let shared_for_commands = Arc::clone(&shared_state);
// Build a single-threaded Tokio runtime for the client
let rt = tokio::runtime::Builder::new_current_thread()
// Build a multi-threaded Tokio runtime for the client
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.expect("tokio runtime");
let handle = std::thread::spawn(move || {
// Initialize tracing for debugging
let _ = tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env()
.add_directive("stardust_xr_fusion=debug".parse().unwrap()))
.try_init();
let res = rt.block_on(async move {
// Spawn command processor task that updates shared state
let cmd_task = tokio::spawn(async move {
@@ -157,26 +184,64 @@ pub extern "C" fn sdxr_start(app_id: *const std::os::raw::c_char) -> i32 {
}
});
println!("[bridge] Connecting to Stardust server...");
// Debug: try raw socket connection first
let socket_path = std::env::var("XDG_RUNTIME_DIR")
.map(|dir| format!("{}/stardust-0", dir))
.or_else(|_| std::env::var("STARDUST_INSTANCE").map(|inst| format!("/run/user/1000/{}", inst)))
.unwrap_or_else(|_| "/run/user/1000/stardust-0".to_string());
println!("[bridge] Socket path: {}", socket_path);
match tokio::net::UnixStream::connect(&socket_path).await {
Ok(_) => println!("[bridge] Raw socket connection OK"),
Err(e) => println!("[bridge] Raw socket connection failed: {}", e),
}
// Run the client - asteroids will manage the projector and call reify() each frame
ast::client::run::<BridgeState>(&[]).await;
// This blocks until the client disconnects or is shut down
match stardust_xr_fusion::client::Client::connect().await {
Ok(_client) => {
println!("[bridge] Connected to Stardust server successfully");
// Now try to run the full asteroids client
ast::client::run::<BridgeState>(&[]).await;
},
Err(e) => {
println!("[bridge] Failed to connect to Stardust server: {:?}", e);
}
}
println!("[bridge] Client disconnected");
let _ = cmd_task;
});
drop(rt);
let _ = res;
STARTED.store(false, Ordering::SeqCst);
CONNECTED.store(false, Ordering::SeqCst);
});
ctrl.rt = None; // runtime consumed inside thread
ctrl.handle = Some(handle);
// Store the shared state so we can read from it later
ctrl.shared_state = Some(shared_state);
// Give the async runtime a moment to attempt connection
std::thread::sleep(std::time::Duration::from_millis(100));
// If the thread is still alive, assume connection succeeded
// (if it failed immediately, STARTED would be false)
if STARTED.load(Ordering::SeqCst) {
CONNECTED.store(true, Ordering::SeqCst);
}
0
}
#[no_mangle]
pub extern "C" fn sdxr_poll() -> i32 {
if !STARTED.load(Ordering::SeqCst) { return -1; }
0
// Return 0 if connected and running, -1 if disconnected
if CONNECTED.load(Ordering::SeqCst) { 0 } else { -1 }
}
#[no_mangle]