Addressed MR comments

This commit is contained in:
Ben Wallis 2021-06-18 22:04:24 +01:00
parent 6fff845ae9
commit c8d17d9753
14 changed files with 74 additions and 93 deletions

9
Cargo.lock generated
View File

@ -6184,11 +6184,7 @@ name = "veloren-voxygen-anim"
version = "0.10.0" version = "0.10.0"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"find_folder",
"lazy_static", "lazy_static",
"libloading 0.7.0",
"notify 5.0.0-pre.9",
"tracing",
"vek", "vek",
"veloren-common", "veloren-common",
"veloren-voxygen-dynlib", "veloren-voxygen-dynlib",
@ -6206,7 +6202,6 @@ name = "veloren-voxygen-dynlib"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"find_folder", "find_folder",
"lazy_static",
"libloading 0.7.0", "libloading 0.7.0",
"notify 5.0.0-pre.9", "notify 5.0.0-pre.9",
"tracing", "tracing",
@ -6218,11 +6213,7 @@ version = "0.9.0"
dependencies = [ dependencies = [
"egui", "egui",
"egui_winit_platform", "egui_winit_platform",
"find_folder",
"lazy_static", "lazy_static",
"libloading 0.7.0",
"notify 5.0.0-pre.9",
"tracing",
"veloren-client", "veloren-client",
"veloren-common", "veloren-common",
"veloren-voxygen-dynlib", "veloren-voxygen-dynlib",

View File

@ -85,7 +85,7 @@ impl Clock {
.map_or(self.last_dt.as_secs_f32(), |t| t.into_inner()), .map_or(self.last_dt.as_secs_f32(), |t| t.into_inner()),
); );
if self.last_dts.len() >= NUMBER_OF_DELTAS_COMPARED && self.last_dt > 2 * stable_dt { if self.last_dts.len() >= NUMBER_OF_DELTAS_COMPARED && self.last_dt > 2 * stable_dt {
tracing::debug!(?self.last_dt, ?self.total_tick_time, "lag spike detected, unusually slow tick"); tracing::trace!(?self.last_dt, ?self.total_tick_time, "lag spike detected, unusually slow tick");
stable_dt stable_dt
} else { } else {
self.last_dt self.last_dt

View File

@ -16,7 +16,6 @@ use crate::{
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::time::Duration; use std::time::Duration;
use strum_macros::Display; use strum_macros::Display;
use vek::*; use vek::*;

View File

@ -5,7 +5,7 @@ name = "veloren-voxygen-anim"
version = "0.10.0" version = "0.10.0"
[features] [features]
use-dyn-lib = ["libloading", "notify", "lazy_static", "tracing", "find_folder"] use-dyn-lib = ["lazy_static", "voxygen-dynlib"]
be-dyn-lib = [] be-dyn-lib = []
simd = ["vek/platform_intrinsics"] simd = ["vek/platform_intrinsics"]
@ -13,12 +13,10 @@ default = ["simd"]
[dependencies] [dependencies]
common = {package = "veloren-common", path = "../../common"} common = {package = "veloren-common", path = "../../common"}
find_folder = {version = "0.3.0", optional = true}
# inline_tweak = "1.0.2" # inline_tweak = "1.0.2"
lazy_static = {version = "1.4.0", optional = true} bytemuck = { version = "1.4", features=["derive"] }
libloading = {version = "0.7", optional = true}
notify = {version = "5.0.0-pre.2", optional = true}
tracing = {version = "0.1", optional = true}
vek = {version = "=0.14.1", features = ["serde"]} vek = {version = "=0.14.1", features = ["serde"]}
bytemuck = { version="1.4", features=["derive"] } voxygen-dynlib = {package = "veloren-voxygen-dynlib", path = "../dynlib", optional = true}
voxygen-dynlib = {package = "veloren-voxygen-dynlib", path = "../dynlib"}
# Hot Reloading
lazy_static = {version = "1.4.0", optional = true}

View File

@ -66,19 +66,13 @@ pub mod ship;
pub mod theropod; pub mod theropod;
pub mod vek; pub mod vek;
#[cfg(feature = "use-dyn-lib")]
use std::ffi::CStr;
use self::vek::*; use self::vek::*;
use bytemuck::{Pod, Zeroable}; use bytemuck::{Pod, Zeroable};
#[cfg(feature = "use-dyn-lib")] #[cfg(feature = "use-dyn-lib")]
use lazy_static::lazy_static; use {
#[cfg(feature = "use-dyn-lib")] lazy_static::lazy_static, std::ffi::CStr, std::sync::Arc, std::sync::Mutex,
use std::sync::Arc; voxygen_dynlib::LoadedLib,
#[cfg(feature = "use-dyn-lib")] };
use std::sync::Mutex;
#[cfg(feature = "use-dyn-lib")]
use voxygen_dynlib::LoadedLib;
type MatRaw = [[f32; 4]; 4]; type MatRaw = [[f32; 4]; 4];
@ -131,7 +125,7 @@ pub fn compute_matrices<S: Skeleton>(
let lib = &lock.as_ref().unwrap().lib; let lib = &lock.as_ref().unwrap().lib;
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
let compute_fn: libloading::Symbol< let compute_fn: voxygen_dynlib::Symbol<
fn(&S, Mat4<f32>, &mut [FigureBoneData; MAX_BONE_COUNT]) -> Vec3<f32>, fn(&S, Mat4<f32>, &mut [FigureBoneData; MAX_BONE_COUNT]) -> Vec3<f32>,
> = unsafe { lib.get(S::COMPUTE_FN) }.unwrap_or_else(|e| { > = unsafe { lib.get(S::COMPUTE_FN) }.unwrap_or_else(|e| {
panic!( panic!(
@ -183,7 +177,7 @@ pub trait Animation {
let lib = &lock.as_ref().unwrap().lib; let lib = &lock.as_ref().unwrap().lib;
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
let update_fn: libloading::Symbol< let update_fn: voxygen_dynlib::Symbol<
fn( fn(
&Self::Skeleton, &Self::Skeleton,
Self::Dependency<'a>, Self::Dependency<'a>,

View File

@ -6,7 +6,6 @@ edition = "2018"
[dependencies] [dependencies]
find_folder = {version = "0.3.0"} find_folder = {version = "0.3.0"}
lazy_static = {version = "1.4.0"}
libloading = {version = "0.7"} libloading = {version = "0.7"}
notify = {version = "5.0.0-pre.2"} notify = {version = "5.0.0-pre.2"}
tracing = "0.1" tracing = "0.1"

View File

@ -9,11 +9,15 @@ use std::{
use find_folder::Search; use find_folder::Search;
use std::{ use std::{
env, env,
env::consts::DLL_SUFFIX,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Arc, sync::Arc,
}; };
use tracing::{debug, error, info}; use tracing::{debug, error, info};
// Re-exports
pub use libloading::Symbol;
/// LoadedLib holds a loaded dynamic library and the location of library file /// LoadedLib holds a loaded dynamic library and the location of library file
/// with the appropriate OS specific name and extension i.e. /// with the appropriate OS specific name and extension i.e.
/// `libvoxygen_anim_dyn_active.dylib`, `voxygen_anim_dyn_active.dll`. /// `libvoxygen_anim_dyn_active.dylib`, `voxygen_anim_dyn_active.dll`.
@ -111,14 +115,17 @@ impl LoadedLib {
} }
} }
/// Initialise a watcher.
///
/// This will search for the directory named `package_source_dir` and watch the
/// files within it for any changes.
pub fn init( pub fn init(
lib_storage: Arc<Mutex<Option<LoadedLib>>>, lib_storage: Arc<Mutex<Option<LoadedLib>>>,
package: &'static str, package: &'static str,
dyn_package: &'static str, dyn_package: &'static str,
package_source_dir: &'static str, package_source_dir: &'static str,
) { ) {
let mut lock = lib_storage.lock().unwrap(); *lib_storage.lock().unwrap() = Some(LoadedLib::compile_load(dyn_package));
*lock = Some(LoadedLib::compile_load(dyn_package));
// TODO: use crossbeam // TODO: use crossbeam
let (reload_send, reload_recv) = mpsc::channel(); let (reload_send, reload_recv) = mpsc::channel();
@ -138,7 +145,6 @@ pub fn init(
watcher.watch(watch_dir, RecursiveMode::Recursive).unwrap(); watcher.watch(watch_dir, RecursiveMode::Recursive).unwrap();
let loaded_lib_clone = Arc::clone(&lib_storage);
// Start reloader that watcher signals // Start reloader that watcher signals
// "Debounces" events since I can't find the option to do this in the latest // "Debounces" events since I can't find the option to do this in the latest
// `notify` // `notify`
@ -158,7 +164,7 @@ pub fn init(
"Hot reloading {} because files in `{}` modified.", package, package_source_dir "Hot reloading {} because files in `{}` modified.", package, package_source_dir
); );
hotreload(dyn_package, loaded_lib_clone.clone()); hotreload(dyn_package, &lib_storage);
} }
}) })
.unwrap(); .unwrap();
@ -172,15 +178,11 @@ fn compiled_file(dyn_package: &str) -> String { dyn_lib_file(dyn_package, false)
fn active_file(dyn_package: &str) -> String { dyn_lib_file(dyn_package, true) } fn active_file(dyn_package: &str) -> String { dyn_lib_file(dyn_package, true) }
fn dyn_lib_file(dyn_package: &str, active: bool) -> String { fn dyn_lib_file(dyn_package: &str, active: bool) -> String {
#[cfg(target_os = "windows")]
const FILE_EXT: &str = ".dll";
#[cfg(not(target_os = "windows"))]
const FILE_EXT: &str = ".so";
format!( format!(
"{}{}{}", "{}{}{}",
dyn_package.replace("-", "_"), dyn_package.replace("-", "_"),
if active { "_active" } else { "" }, if active { "_active" } else { "" },
FILE_EXT DLL_SUFFIX
) )
} }
@ -209,7 +211,7 @@ fn event_fn(res: notify::Result<notify::Event>, sender: &mpsc::Sender<String>) {
/// ///
/// This will reload the dynamic library by first internally calling compile /// This will reload the dynamic library by first internally calling compile
/// and then reloading the library. /// and then reloading the library.
fn hotreload(dyn_package: &str, loaded_lib: Arc<Mutex<Option<LoadedLib>>>) { fn hotreload(dyn_package: &str, loaded_lib: &Mutex<Option<LoadedLib>>) {
// Do nothing if recompile failed. // Do nothing if recompile failed.
if compile(dyn_package) { if compile(dyn_package) {
let mut lock = loaded_lib.lock().unwrap(); let mut lock = loaded_lib.lock().unwrap();

View File

@ -5,7 +5,7 @@ edition = "2018"
version = "0.9.0" version = "0.9.0"
[features] [features]
use-dyn-lib = ["libloading", "notify", "lazy_static", "tracing", "find_folder"] use-dyn-lib = ["lazy_static", "voxygen-dynlib"]
be-dyn-lib = [] be-dyn-lib = []
[dependencies] [dependencies]
@ -13,12 +13,8 @@ client = {package = "veloren-client", path = "../../client"}
common = {package = "veloren-common", path = "../../common"} common = {package = "veloren-common", path = "../../common"}
egui = "0.12" egui = "0.12"
egui_winit_platform = "0.8" egui_winit_platform = "0.8"
voxygen-dynlib = {package = "veloren-voxygen-dynlib", path = "../dynlib"} voxygen-dynlib = {package = "veloren-voxygen-dynlib", path = "../dynlib", optional = true}
# Hot Reloading # Hot Reloading
find_folder = {version = "0.3.0", optional = true}
lazy_static = {version = "1.4.0", optional = true} lazy_static = {version = "1.4.0", optional = true}
libloading = {version = "0.7", optional = true}
notify = {version = "5.0.0-pre.2", optional = true}
tracing = {version = "0.1", optional = true}

View File

@ -5,9 +5,6 @@ name = "veloren-voxygen-egui-dyn"
version = "0.9.0" version = "0.9.0"
[lib] [lib]
# Using dylib instead of cdylib increases the size 3 -> 13 mb
# but it is needed to expose the symbols from the anim crate :(
# effect on compile time appears to be insignificant
crate-type = ["dylib"] crate-type = ["dylib"]
[features] [features]

View File

@ -20,8 +20,18 @@ pub fn draw_char_state_group(
}, },
CharacterState::DashMelee(data) => dash_melee_grid(ui, data), CharacterState::DashMelee(data) => dash_melee_grid(ui, data),
CharacterState::ChargedMelee(data) => charged_melee_grid(ui, data), CharacterState::ChargedMelee(data) => charged_melee_grid(ui, data),
// Character states with no associated data to display
CharacterState::Dance
| CharacterState::Idle
| CharacterState::Sit
| CharacterState::GlideWield
| CharacterState::Sneak
| CharacterState::Talk
| CharacterState::Wielding => {},
CharacterState::LeapMelee(data) => leap_melee_grid(ui, data), CharacterState::LeapMelee(data) => leap_melee_grid(ui, data),
_ => {}, _ => {
ui.label("<Rendering not yet implemented for this state>");
},
}; };
} }
@ -34,7 +44,7 @@ fn charged_melee_grid(ui: &mut Ui, data: &charged_melee::Data) {
two_col_row(ui, "Stage Section", data.stage_section.to_string()); two_col_row(ui, "Stage Section", data.stage_section.to_string());
two_col_row(ui, "Timer", format!("{}ms", data.timer.as_millis())); two_col_row(ui, "Timer", format!("{}ms", data.timer.as_millis()));
two_col_row(ui, "Charge Amount", format!("{:.1}", data.charge_amount)); two_col_row(ui, "Charge Amount", format!("{:.1}", data.charge_amount));
two_col_row(ui, "Exhausted", (if data.exhausted { "True" } else { "False" }).to_string()); two_col_row(ui, "Exhausted", if data.exhausted { "True" } else { "False" });
}); });
} }
@ -56,10 +66,10 @@ fn dash_melee_grid(ui: &mut Ui, data: &dash_melee::Data) {
.max_col_width(100.0) .max_col_width(100.0)
.striped(true) .striped(true)
.show(ui, |ui| #[rustfmt::skip] { .show(ui, |ui| #[rustfmt::skip] {
two_col_row(ui, "Auto Charge", (if data.auto_charge { "True" } else { "False " }).to_string()); two_col_row(ui, "Auto Charge", if data.auto_charge { "True" } else { "False " });
two_col_row(ui, "Timer", format!("{}ms", data.timer.as_millis())); two_col_row(ui, "Timer", format!("{}ms", data.timer.as_millis()));
two_col_row(ui, "Stage Section", data.stage_section.to_string()); two_col_row(ui, "Stage Section", data.stage_section.to_string());
two_col_row(ui, "Exhausted", (if data.exhausted { "True" } else { "False " }).to_string()); two_col_row(ui, "Exhausted", if data.exhausted { "True" } else { "False " });
two_col_row(ui, "Charge End Timer", format!("{}ms", data.charge_end_timer.as_millis())); two_col_row(ui, "Charge End Timer", format!("{}ms", data.charge_end_timer.as_millis()));
}); });
} }
@ -72,6 +82,6 @@ fn leap_melee_grid(ui: &mut Ui, data: &leap_melee::Data) {
.show(ui, |ui| #[rustfmt::skip] { .show(ui, |ui| #[rustfmt::skip] {
two_col_row(ui, "Stage Section", data.stage_section.to_string()); two_col_row(ui, "Stage Section", data.stage_section.to_string());
two_col_row(ui, "Timer", format!("{}ms", data.timer.as_millis())); two_col_row(ui, "Timer", format!("{}ms", data.timer.as_millis()));
two_col_row(ui, "Exhausted", (if data.exhausted { "True" } else { "False " }).to_string()); two_col_row(ui, "Exhausted", if data.exhausted { "True" } else { "False " });
}); });
} }

View File

@ -1,7 +1,10 @@
#![feature(stmt_expr_attributes)] #![feature(stmt_expr_attributes)]
mod character_states;
#[cfg(all(feature = "be-dyn-lib", feature = "use-dyn-lib"))] #[cfg(all(feature = "be-dyn-lib", feature = "use-dyn-lib"))]
compile_error!("Can't use both \"be-dyn-lib\" and \"use-dyn-lib\" features at once"); compile_error!("Can't use both \"be-dyn-lib\" and \"use-dyn-lib\" features at once");
mod character_states;
use client::{Client, Join, World, WorldExt}; use client::{Client, Join, World, WorldExt};
use common::{ use common::{
comp, comp,
@ -25,15 +28,10 @@ use crate::character_states::draw_char_state_group;
use common::comp::{aura::AuraKind::Buff, Body, Fluid}; use common::comp::{aura::AuraKind::Buff, Body, Fluid};
use egui_winit_platform::Platform; use egui_winit_platform::Platform;
#[cfg(feature = "use-dyn-lib")] #[cfg(feature = "use-dyn-lib")]
use lazy_static::lazy_static; use {
#[cfg(feature = "use-dyn-lib")] lazy_static::lazy_static, std::ffi::CStr, std::sync::Arc, std::sync::Mutex,
use std::ffi::CStr; voxygen_dynlib::LoadedLib,
#[cfg(feature = "use-dyn-lib")] };
use std::sync::Arc;
#[cfg(feature = "use-dyn-lib")]
use std::sync::Mutex;
#[cfg(feature = "use-dyn-lib")]
use voxygen_dynlib::LoadedLib;
#[cfg(feature = "use-dyn-lib")] #[cfg(feature = "use-dyn-lib")]
lazy_static! { lazy_static! {
@ -69,7 +67,7 @@ pub fn maintain(
let lib = &lock.as_ref().unwrap().lib; let lib = &lock.as_ref().unwrap().lib;
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
let maintain_fn: libloading::Symbol< let maintain_fn: voxygen_dynlib::Symbol<
fn( fn(
&mut Platform, &mut Platform,
&mut EguiInnerState, &mut EguiInnerState,
@ -148,12 +146,12 @@ pub enum DebugShapeAction {
radius: f32, radius: f32,
height: f32, height: f32,
}, },
RemoveShape(u64),
SetPosAndColor { SetPosAndColor {
id: u64, id: u64,
pos: [f32; 4], pos: [f32; 4],
color: [f32; 4], color: [f32; 4],
}, },
RemoveCylinder(u64),
} }
#[derive(Default)] #[derive(Default)]
@ -217,7 +215,7 @@ pub fn maintain_egui_inner(
ui.label("Show EGUI Windows"); ui.label("Show EGUI Windows");
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.checkbox(&mut egui_windows.egui_inspection, "🔍 Inspection"); ui.checkbox(&mut egui_windows.egui_inspection, "🔍 Inspection");
ui.checkbox(&mut egui_windows.egui_settings, "🔍 Settings"); ui.checkbox(&mut egui_windows.egui_settings, "🔧 Settings");
ui.checkbox(&mut egui_windows.egui_memory, "📝 Memory"); ui.checkbox(&mut egui_windows.egui_memory, "📝 Memory");
}) })
}) })
@ -398,7 +396,7 @@ pub fn maintain_egui_inner(
if let Some(debug_shape_id) = previous.debug_shape_id { if let Some(debug_shape_id) = previous.debug_shape_id {
egui_actions egui_actions
.actions .actions
.push(DebugShapeAction::RemoveCylinder(debug_shape_id)); .push(DebugShapeAction::RemoveShape(debug_shape_id));
} }
}; };
@ -409,7 +407,7 @@ pub fn maintain_egui_inner(
{ {
egui_actions egui_actions
.actions .actions
.push(DebugShapeAction::RemoveCylinder(debug_shape_id)); .push(DebugShapeAction::RemoveShape(debug_shape_id));
egui_actions.actions.push(DebugShapeAction::AddCylinder { egui_actions.actions.push(DebugShapeAction::AddCylinder {
radius: 1.0, radius: 1.0,
height: selected_entity_cylinder_height, height: selected_entity_cylinder_height,

View File

@ -57,7 +57,8 @@ impl<'frame> Pipelines<'frame> {
struct RendererBorrow<'frame> { struct RendererBorrow<'frame> {
queue: &'frame wgpu::Queue, queue: &'frame wgpu::Queue,
device: &'frame wgpu::Device, device: &'frame wgpu::Device,
_sc_desc: &'frame wgpu::SwapChainDescriptor, #[cfg(feature = "egui-ui")]
sc_desc: &'frame wgpu::SwapChainDescriptor,
shadow: Option<&'frame super::Shadow>, shadow: Option<&'frame super::Shadow>,
pipelines: Pipelines<'frame>, pipelines: Pipelines<'frame>,
locals: &'frame super::locals::Locals, locals: &'frame super::locals::Locals,
@ -107,7 +108,7 @@ impl<'frame> Drawer<'frame> {
let borrow = RendererBorrow { let borrow = RendererBorrow {
queue: &renderer.queue, queue: &renderer.queue,
device: &renderer.device, device: &renderer.device,
_sc_desc: &renderer.sc_desc, sc_desc: &renderer.sc_desc,
shadow, shadow,
pipelines, pipelines,
locals: &renderer.locals, locals: &renderer.locals,
@ -278,8 +279,8 @@ impl<'frame> Drawer<'frame> {
let paint_jobs = platform.context().tessellate(paint_commands); let paint_jobs = platform.context().tessellate(paint_commands);
let screen_descriptor = ScreenDescriptor { let screen_descriptor = ScreenDescriptor {
physical_width: self.borrow._sc_desc.width, physical_width: self.borrow.sc_desc.width,
physical_height: self.borrow._sc_desc.height, physical_height: self.borrow.sc_desc.height,
scale_factor: scale_factor as f32, scale_factor: scale_factor as f32,
}; };
@ -309,11 +310,6 @@ impl<'frame> Drawer<'frame> {
); );
} }
#[cfg(feature = "egui-ui")]
pub fn egui_renderpass(&mut self) -> &mut egui_wgpu_backend::RenderPass {
self.borrow.egui_render_pass
}
/// Does nothing if the shadow pipelines are not available or shadow map /// Does nothing if the shadow pipelines are not available or shadow map
/// rendering is disabled /// rendering is disabled
pub fn draw_point_shadows<'data: 'frame>( pub fn draw_point_shadows<'data: 'frame>(

View File

@ -1408,7 +1408,9 @@ impl PlayState for SessionState {
/// This method should be called once per frame. /// This method should be called once per frame.
fn render(&mut self, global_state: &mut GlobalState) { fn render(&mut self, global_state: &mut GlobalState) {
let _scale_factor = global_state.window.window().scale_factor() as f32; #[cfg(feature = "egui-ui")]
let scale_factor = global_state.window.window().scale_factor() as f32;
let renderer = global_state.window.renderer_mut(); let renderer = global_state.window.renderer_mut();
let settings = &global_state.settings; let settings = &global_state.settings;
@ -1470,7 +1472,7 @@ impl PlayState for SessionState {
#[cfg(feature = "egui-ui")] #[cfg(feature = "egui-ui")]
if global_state.settings.interface.toggle_debug { if global_state.settings.interface.toggle_debug {
drawer.draw_egui(&mut global_state.egui_state.platform, _scale_factor); drawer.draw_egui(&mut global_state.egui_state.platform, scale_factor);
} }
} }
} }

View File

@ -4,7 +4,6 @@ use crate::{
}; };
use client::Client; use client::Client;
use common::debug_info::DebugInfo; use common::debug_info::DebugInfo;
use core::mem;
use egui::FontDefinitions; use egui::FontDefinitions;
use egui_winit_platform::{Platform, PlatformDescriptor}; use egui_winit_platform::{Platform, PlatformDescriptor};
use voxygen_egui::{DebugShapeAction, EguiInnerState, EguiWindows}; use voxygen_egui::{DebugShapeAction, EguiInnerState, EguiWindows};
@ -41,7 +40,7 @@ impl EguiState {
&mut self.egui_windows, &mut self.egui_windows,
client, client,
debug_info, debug_info,
mem::take(&mut self.new_debug_shape_id), self.new_debug_shape_id.take(),
); );
egui_actions.actions.iter().for_each(|action| match action { egui_actions.actions.iter().for_each(|action| match action {
@ -52,7 +51,7 @@ impl EguiState {
}); });
self.new_debug_shape_id = Some(shape_id.0); self.new_debug_shape_id = Some(shape_id.0);
}, },
DebugShapeAction::RemoveCylinder(debug_shape_id) => { DebugShapeAction::RemoveShape(debug_shape_id) => {
scene.debug.remove_shape(DebugShapeId(*debug_shape_id)); scene.debug.remove_shape(DebugShapeId(*debug_shape_id));
}, },
DebugShapeAction::SetPosAndColor { id, pos, color } => { DebugShapeAction::SetPosAndColor { id, pos, color } => {