@@ -43,6 +43,7 @@ bevy_mod_xr = { git = "https://github.com/Schmarni-Dev/bevy_openxr", branch = "0
|
||||
bevy_mod_openxr = { git = "https://github.com/Schmarni-Dev/bevy_openxr", branch = "0.15rc" }
|
||||
bevy_xr_utils = { git = "https://github.com/Schmarni-Dev/bevy_openxr", branch = "0.15rc" }
|
||||
openxr = "0.19"
|
||||
winit = { version = "0.30", default-features = false, features = [] }
|
||||
# small utility thingys
|
||||
once_cell = "1.19.0"
|
||||
nanoid = "0.4.0"
|
||||
|
||||
@@ -5,7 +5,7 @@ use bevy::{
|
||||
prelude::*,
|
||||
};
|
||||
use bevy_mod_openxr::session::OxrSession;
|
||||
use bevy_mod_xr::session::{session_available, XrSessionCreated};
|
||||
use bevy_mod_xr::session::{session_available, XrFirst, XrSessionCreated};
|
||||
use openxr::ReferenceSpaceType;
|
||||
use stardust_xr::values::color::{color_space::LinearRgb, AlphaColor, Rgb};
|
||||
|
||||
@@ -18,6 +18,8 @@ pub struct DbusConnection(pub zbus::Connection);
|
||||
|
||||
#[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct InputUpdate;
|
||||
#[derive(ScheduleLabel, Hash, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct StardustFirst;
|
||||
impl Plugin for StardustBevyPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_schedule(StardustExtract);
|
||||
@@ -29,6 +31,17 @@ impl Plugin for StardustBevyPlugin {
|
||||
let mut schedule = Schedule::new(InputUpdate);
|
||||
schedule.set_executor_kind(ExecutorKind::Simple);
|
||||
app.add_schedule(schedule);
|
||||
|
||||
let mut schedule = Schedule::new(StardustFirst);
|
||||
schedule.set_executor_kind(ExecutorKind::Simple);
|
||||
app.add_schedule(schedule);
|
||||
|
||||
let labels = &mut app.world_mut().resource_mut::<MainScheduleOrder>().labels;
|
||||
let xr_first_intern = (XrFirst).intern();
|
||||
if labels.remove(0) != xr_first_intern {
|
||||
panic!("first schedule was not XrFirst!");
|
||||
}
|
||||
labels.insert(0, (StardustFirst).intern());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use crate::core::error::Result;
|
||||
use crate::nodes::alias::get_original;
|
||||
use crate::nodes::Node;
|
||||
use crate::TOKIO;
|
||||
use crate::{core::client::Client, nodes::Message};
|
||||
use once_cell::sync::OnceCell;
|
||||
use parking_lot::Mutex;
|
||||
@@ -68,7 +69,7 @@ impl MethodResponseSender {
|
||||
self,
|
||||
f: impl Future<Output = Result<(T, Vec<OwnedFd>)>> + Send + 'static,
|
||||
) {
|
||||
tokio::task::spawn(async move { self.0.send(map_method_return(f.await)) });
|
||||
TOKIO.spawn(async move { self.0.send(map_method_return(f.await)) });
|
||||
}
|
||||
}
|
||||
fn map_method_return<T: Serialize>(
|
||||
|
||||
@@ -2,6 +2,8 @@ use color_eyre::eyre::Result;
|
||||
use std::future::Future;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
use crate::TOKIO;
|
||||
|
||||
#[allow(unused_variables)]
|
||||
pub fn new<
|
||||
F: FnOnce() -> S,
|
||||
@@ -13,7 +15,7 @@ pub fn new<
|
||||
async_future: A,
|
||||
) -> Result<JoinHandle<O>> {
|
||||
#[cfg(not(feature = "profile_tokio"))]
|
||||
let result = Ok(tokio::task::spawn(async_future));
|
||||
let result = Ok(TOKIO.spawn(async_future));
|
||||
#[cfg(feature = "profile_tokio")]
|
||||
let result = tokio::task::Builder::new()
|
||||
.name(name_fn().as_ref())
|
||||
|
||||
53
src/main.rs
53
src/main.rs
@@ -12,7 +12,7 @@ use crate::core::destroy_queue;
|
||||
// use crate::nodes::items::camera;
|
||||
use crate::nodes::{audio, drawable, input};
|
||||
|
||||
use bevy::app::{App, PluginGroup, Startup, Update};
|
||||
use bevy::app::{App, PluginGroup, PluginsState, Startup, Update};
|
||||
use bevy::asset::{AssetServer, Handle};
|
||||
use bevy::core_pipeline::Skybox;
|
||||
use bevy::image::Image;
|
||||
@@ -20,12 +20,12 @@ use bevy::log::LogPlugin;
|
||||
use bevy::pbr::StandardMaterial;
|
||||
use bevy::prelude::{
|
||||
on_event, resource_added, Camera3d, ClearColor, Commands, Entity, EventReader,
|
||||
IntoSystemConfigs, Local, Query, Res, Resource, With,
|
||||
IntoSystemConfigs, Local, Query, Res, Resource, With, World,
|
||||
};
|
||||
use bevy::render::pipelined_rendering::PipelinedRenderingPlugin;
|
||||
use bevy::time::Time;
|
||||
use bevy::utils::default;
|
||||
use bevy::winit::{WakeUp, WinitPlugin};
|
||||
use bevy::winit::{EventLoopProxyWrapper, WakeUp, WinitPlugin};
|
||||
use bevy::DefaultPlugins;
|
||||
use bevy_mod_openxr::action_set_syncing::{OxrActionSyncingPlugin, OxrSyncActionSet};
|
||||
use bevy_mod_openxr::exts::OxrExtensions;
|
||||
@@ -37,7 +37,7 @@ use bevy_mod_openxr::session::OxrSession;
|
||||
use bevy_mod_openxr::types::{AppInfo, Version};
|
||||
use bevy_mod_openxr::{add_xr_plugins, openxr_session_running};
|
||||
use bevy_mod_xr::session::{XrFirst, XrSessionCreated, XrSessionPlugin};
|
||||
use bevy_plugin::{DbusConnection, InputUpdate, StardustBevyPlugin};
|
||||
use bevy_plugin::{DbusConnection, InputUpdate, StardustBevyPlugin, StardustFirst};
|
||||
use clap::Parser;
|
||||
use core::client::Client;
|
||||
use core::task;
|
||||
@@ -54,12 +54,11 @@ use oxr_render_plugin::StardustOxrRenderPlugin;
|
||||
use session::{launch_start, save_session};
|
||||
use stardust_xr::schemas::dbus::object_registry::ObjectRegistry;
|
||||
use stardust_xr::server;
|
||||
use std::ops::Deref;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::net::UnixListener;
|
||||
use tokio::sync::Notify;
|
||||
use tracing::metadata::LevelFilter;
|
||||
use tracing::{debug_span, error, info, warn};
|
||||
use tracing_subscriber::{fmt, prelude::*, EnvFilter};
|
||||
use zbus::fdo::ObjectManager;
|
||||
@@ -99,10 +98,26 @@ struct CliArgs {
|
||||
}
|
||||
|
||||
static STARDUST_INSTANCE: OnceCell<String> = OnceCell::new();
|
||||
static TOKIO: RuntimeWrapper = RuntimeWrapper(OnceCell::new());
|
||||
|
||||
// #[tokio::main]
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
async fn main() {
|
||||
struct RuntimeWrapper(OnceCell<tokio::runtime::Runtime>);
|
||||
impl Deref for RuntimeWrapper {
|
||||
type Target = tokio::runtime::Runtime;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.get().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let runtime = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.unwrap();
|
||||
TOKIO.0.set(runtime).unwrap();
|
||||
TOKIO.block_on(setup())
|
||||
}
|
||||
async fn setup() {
|
||||
color_eyre::install().unwrap();
|
||||
|
||||
let registry = tracing_subscriber::registry();
|
||||
@@ -245,7 +260,7 @@ fn stereokit_loop(
|
||||
exts
|
||||
},
|
||||
blend_modes: Some(vec![
|
||||
openxr::EnvironmentBlendMode::ALPHA_BLEND,
|
||||
// openxr::EnvironmentBlendMode::ALPHA_BLEND,
|
||||
openxr::EnvironmentBlendMode::OPAQUE,
|
||||
]),
|
||||
synchronous_pipeline_compilation: false,
|
||||
@@ -262,6 +277,7 @@ fn stereokit_loop(
|
||||
});
|
||||
}
|
||||
bevy_app.add_event::<OxrSyncActionSet>();
|
||||
bevy_app.add_plugins(bevy_xr_utils::hand_gizmos::HandGizmosPlugin);
|
||||
}
|
||||
bevy_app.add_plugins(StardustBevyPlugin);
|
||||
bevy_app.add_plugins((
|
||||
@@ -343,16 +359,16 @@ fn stereokit_loop(
|
||||
}
|
||||
}
|
||||
|
||||
debug_span!("bevy").in_scope(|| loop {
|
||||
bevy_app.insert_resource(objects);
|
||||
|
||||
let bevy_step = |world: &mut World| {
|
||||
let _span = debug_span!("Bevy step");
|
||||
let _span = _span.enter();
|
||||
|
||||
// camera::update(token);
|
||||
#[cfg(feature = "wayland")]
|
||||
wayland.frame_event();
|
||||
destroy_queue::clear();
|
||||
|
||||
let world = bevy_app.world_mut();
|
||||
let time = world.get_resource_mut::<OxrFrameState>().map(|mut s| {
|
||||
let t = openxr::Time::from_nanos(
|
||||
s.predicted_display_time.as_nanos() + s.predicted_display_period.as_nanos(),
|
||||
@@ -369,7 +385,9 @@ fn stereokit_loop(
|
||||
}
|
||||
world.run_schedule(InputUpdate);
|
||||
let session = world.remove_resource::<OxrSession>();
|
||||
let mut objects = world.remove_resource::<ServerObjects>().unwrap();
|
||||
objects.update(session.as_deref(), time);
|
||||
world.insert_resource(objects);
|
||||
if let Some(session) = session {
|
||||
world.insert_resource(session);
|
||||
}
|
||||
@@ -382,15 +400,14 @@ fn stereokit_loop(
|
||||
let mut waiter = world.remove_resource::<OxrFrameWaiter>().unwrap();
|
||||
let state = waiter.wait().unwrap();
|
||||
world.insert_resource(OxrFrameState(state));
|
||||
world.insert_resource(waiter);
|
||||
world.run_system_cached(update_cameras);
|
||||
}
|
||||
#[cfg(feature = "wayland")]
|
||||
wayland.update();
|
||||
bevy_app.update();
|
||||
if let Some(exit) = bevy_app.should_exit() {
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
||||
bevy_app.add_systems(StardustFirst, bevy_step);
|
||||
bevy_app.run();
|
||||
|
||||
#[cfg(feature = "wayland")]
|
||||
drop(wayland);
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
DefaultMaterial,
|
||||
};
|
||||
use bevy::{
|
||||
app::{App, Plugin},
|
||||
app::{App, Plugin, PostUpdate, PreUpdate},
|
||||
asset::{AssetServer, Assets, RenderAssetUsages},
|
||||
color::Color,
|
||||
image::Image,
|
||||
@@ -54,7 +54,8 @@ impl Plugin for StardustTextPlugin {
|
||||
let (tx, rx) = crossbeam_channel::unbounded();
|
||||
SPAWN_TEXT_SENDER.set(tx);
|
||||
app.insert_resource(SpawnTextReader(rx));
|
||||
todo!()
|
||||
app.add_systems(PostUpdate, update_text);
|
||||
app.add_systems(PreUpdate, spawn_text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,24 +111,24 @@ fn update_controllers(
|
||||
.spatial
|
||||
.set_local_transform(world_transform);
|
||||
}
|
||||
controller.datamap.select = controller
|
||||
.actions
|
||||
.trigger
|
||||
.state(&session, openxr::Path::NULL)
|
||||
.map(|v| v.current_state)
|
||||
.unwrap_or_default();
|
||||
controller.datamap.grab = controller
|
||||
.actions
|
||||
.grip
|
||||
.state(&session, openxr::Path::NULL)
|
||||
.map(|v| v.current_state)
|
||||
.unwrap_or_default();
|
||||
controller.datamap.scroll = controller
|
||||
.actions
|
||||
.stick
|
||||
.state(&session, openxr::Path::NULL)
|
||||
.map(|v| v.current_state.to_vec2())
|
||||
.unwrap_or_default();
|
||||
// controller.datamap.select = controller
|
||||
// .actions
|
||||
// .trigger
|
||||
// .state(&session, openxr::Path::NULL)
|
||||
// .map(|v| v.current_state)
|
||||
// .unwrap_or_default();
|
||||
// controller.datamap.grab = controller
|
||||
// .actions
|
||||
// .grip
|
||||
// .state(&session, openxr::Path::NULL)
|
||||
// .map(|v| v.current_state)
|
||||
// .unwrap_or_default();
|
||||
// controller.datamap.scroll = controller
|
||||
// .actions
|
||||
// .stick
|
||||
// .state(&session, openxr::Path::NULL)
|
||||
// .map(|v| v.current_state.to_vec2())
|
||||
// .unwrap_or_default();
|
||||
*controller.input.datamap.lock() = Datamap::from_typed(&controller.datamap).unwrap();
|
||||
|
||||
// remove the capture when it's removed from captures list
|
||||
|
||||
@@ -7,7 +7,9 @@ use crate::{
|
||||
spatial::{Spatial, EXPORTED_SPATIALS},
|
||||
Node, OwnedNode,
|
||||
},
|
||||
TOKIO,
|
||||
};
|
||||
use bevy::prelude::Resource;
|
||||
use bevy_mod_openxr::helper_traits::{ToQuat, ToVec3};
|
||||
use glam::{vec3, Mat4};
|
||||
use input::{
|
||||
@@ -46,6 +48,7 @@ struct ControllerInput {
|
||||
scroll: openxr::Action<openxr::Vector2f>,
|
||||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
pub struct ServerObjects {
|
||||
connection: Connection,
|
||||
hmd: (Arc<Spatial>, ObjectHandle<SpatialRef>),
|
||||
@@ -76,7 +79,7 @@ impl ServerObjects {
|
||||
// let play_space = None;
|
||||
// if play_space.is_some() {
|
||||
// let dbus_connection = connection.clone();
|
||||
// tokio::task::spawn(async move {
|
||||
// TOKIO.spawn(async move {
|
||||
// PlaySpaceBounds::create(&dbus_connection).await;
|
||||
// dbus_connection
|
||||
// .request_name("org.stardustxr.PlaySpace")
|
||||
@@ -85,7 +88,7 @@ impl ServerObjects {
|
||||
// });
|
||||
// }
|
||||
|
||||
tokio::task::spawn({
|
||||
TOKIO.spawn({
|
||||
let connection = connection.clone();
|
||||
async move {
|
||||
connection
|
||||
@@ -224,7 +227,7 @@ impl<I: Interface> Drop for ObjectHandle<I> {
|
||||
fn drop(&mut self) {
|
||||
let connection = self.0.clone();
|
||||
let object_path = self.1.clone();
|
||||
tokio::task::spawn(async move {
|
||||
TOKIO.spawn(async move {
|
||||
connection.object_server().remove::<I, _>(object_path);
|
||||
});
|
||||
}
|
||||
@@ -238,7 +241,7 @@ impl SpatialRef {
|
||||
let uid: u64 = rand::random();
|
||||
EXPORTED_SPATIALS.lock().insert(uid, node.0.clone());
|
||||
|
||||
tokio::task::spawn({
|
||||
TOKIO.spawn({
|
||||
let connection = connection.clone();
|
||||
let path = path.to_string();
|
||||
async move {
|
||||
@@ -280,7 +283,7 @@ impl FieldRef {
|
||||
let uid: u64 = rand::random();
|
||||
EXPORTED_FIELDS.lock().insert(uid, node.0.clone());
|
||||
|
||||
tokio::task::spawn({
|
||||
TOKIO.spawn({
|
||||
let connection = connection.clone();
|
||||
let path = path.to_string();
|
||||
async move {
|
||||
|
||||
@@ -49,12 +49,6 @@ impl Plugin for StardustOxrRenderPlugin {
|
||||
)
|
||||
.init_resource::<OxrViews>();
|
||||
|
||||
let labels = &mut app.world_mut().resource_mut::<MainScheduleOrder>().labels;
|
||||
let xr_first_intern = (XrFirst).intern();
|
||||
if labels.remove(0) != xr_first_intern {
|
||||
panic!("first schedule was not XrFirst!");
|
||||
}
|
||||
|
||||
let render_app = app.sub_app_mut(RenderApp);
|
||||
|
||||
render_app
|
||||
|
||||
Reference in New Issue
Block a user