kitgit

tirbofish/dropbear · commit

824aa2553eba98a05b3757180380b9779e7ca089

adding a custom clippy lint for hecs::World::query_one_mut so i don't deal with that mistake.

Unverified

tk <4tkbytes@pm.me> · 2025-09-18 10:12

view full diff

diff --git a/Cargo.toml b/Cargo.toml
index 5061850..64b1587 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,7 +6,7 @@ package.repository = "https://github.com/4tkbytes/dropbear-engine"
 package.readme = "README.md"
 
 resolver = "3"
-members = ["dropbear-engine", "eucalyptus-core", "eucalyptus-editor"]
+members = ["deny_query_one_mut_lint", "dropbear-engine", "eucalyptus-core", "eucalyptus-editor"]
 # members = ["dropbear-engine", "eucalyptus-core", "eucalyptus-editor", "redback-runtime"]
 
 
@@ -42,8 +42,6 @@ open = "5"
 parking_lot = {version = "0.12", features = ["deadlock_detection"] }
 rfd = "0.15.4"
 ron = "0.11"
-# russimp-ng = { version = "3.2", features = ["static-link"] }
-# rustyscript = { version = "0.12" }
 serde = { version = "1.0.219", features = ["derive"] }
 spin_sleep = "1.3"
 transform-gizmo-egui = { git = "https://github.com/4tkbytes/transform-gizmo"}
@@ -52,7 +50,6 @@ wgpu = "25"
 winit = { version = "0.30", features = [] }
 zip = "5.1"
 walkdir = "2.3"
-# wasmer = { version = "6.1.0-rc.3" }
 rayon = "1.11"
 flate2 = "1.1"
 reqwest = { version = "0.11", features = ["stream"] }
@@ -61,10 +58,8 @@ async-trait = "0.1"
 futures-util = "0.3"
 boa_engine = "0.20"
 backtrace = "0.3"
-
-
 gltf = "1"
-thiserror = "2.0"
+os_info = "3.12"
 
 [workspace.dependencies.image]
 version = "0.25"
diff --git a/deny_query_one_mut_lint/Cargo.toml b/deny_query_one_mut_lint/Cargo.toml
new file mode 100644
index 0000000..30fe50b
--- /dev/null
+++ b/deny_query_one_mut_lint/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "deny_query_one_mut_lint"
+version.workspace = true
+edition.workspace = true
+license = "MIT"
+repository.workspace = true
+readme = "README.md"
+
+[lib]
+crate-type = ["dylib"]
+
+[dependencies]
+
+
+[features]
+default = []
diff --git a/deny_query_one_mut_lint/README.md b/deny_query_one_mut_lint/README.md
new file mode 100644
index 0000000..09f8231
--- /dev/null
+++ b/deny_query_one_mut_lint/README.md
@@ -0,0 +1,28 @@
+# deny_query_one_mut_lint
+
+A custom lint for all codebases in the dropbear-engine that check if the usage of [`hecs::World::query_one_mut`] 
+is used. 
+
+### Cause
+
+The editor is required to have the world be threadsafe. This is achieved with the help of `Arc<RwLock<T>>`. 
+This is a great way to achieve threadsafety, however writing to the world often creates a 
+[deadlock](https://en.wikipedia.org/wiki/Deadlock_(computer_science)). A deadlock in Rust is undetectable during
+compile-time and when ran during runtime, it can cause the program to freeze and not respond. 
+
+### Fix
+
+To solve this conundrum, I have implemented a couple of fixes:
+1. Using a [`std::sync::Mutex`](https://doc.rust-lang.org/std/sync/struct.Mutex.html) allows for locking, which allows 
+for mutability but blocks that thread. Furthermore, it cannot/shouldn't be used in threads where a mutex uses `Send`. 
+To fix this, I switched to [`parking_lot::RwLock`](https://docs.rs/parking_lot/latest/parking_lot/type.RwLock.html), 
+which doesn't use `Send` (making it even more threadsafe).
+Conveniently, it also includes deadlock detection (as an enabled feature), which can point out if a deadlock is in progress or if an expensive
+operation is being run. 
+2. I have switched from `hecs::World::query_one_mut` to `hecs::World::query_one` to use only the `RwLock::read(&self)`,
+which doesn't require a mutable reference from `self.world`. 
+
+Even with such fixes, deadlocks are inevitable in the codebase. This crate aims to fix this by creating a custom rustc
+lint. 
+
+Note: https://blog.guillaume-gomez.fr/articles/2024-01-18+Writing+your+own+Rust+linter
\ No newline at end of file
diff --git a/deny_query_one_mut_lint/src/lib.rs b/deny_query_one_mut_lint/src/lib.rs
new file mode 100644
index 0000000..b93cf3f
--- /dev/null
+++ b/deny_query_one_mut_lint/src/lib.rs
@@ -0,0 +1,14 @@
+pub fn add(left: u64, right: u64) -> u64 {
+    left + right
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn it_works() {
+        let result = add(2, 2);
+        assert_eq!(result, 4);
+    }
+}
diff --git a/dropbear-engine/Cargo.toml b/dropbear-engine/Cargo.toml
index 6cf629b..0f198f4 100644
--- a/dropbear-engine/Cargo.toml
+++ b/dropbear-engine/Cargo.toml
@@ -23,13 +23,11 @@ gilrs.workspace = true
 glam.workspace = true
 log.workspace = true
 log-once.workspace = true
-# russimp-ng.workspace = true
 serde.workspace = true
 spin_sleep.workspace = true
 wgpu.workspace = true
 winit.workspace = true
 hecs.workspace = true
-# once_cell.workspace = true
 parking_lot.workspace = true
 lazy_static.workspace = true
 gltf.workspace = true
@@ -37,7 +35,7 @@ rayon.workspace = true
 tokio.workspace = true
 async-trait.workspace = true
 backtrace.workspace = true
-os_info = "*"
+os_info.workspace = true
 
 [target.'cfg(not(target_os = "android"))'.dependencies]
 rfd.workspace = true
diff --git a/eucalyptus-core/Cargo.toml b/eucalyptus-core/Cargo.toml
index 1abdd68..6507faf 100644
--- a/eucalyptus-core/Cargo.toml
+++ b/eucalyptus-core/Cargo.toml
@@ -28,9 +28,6 @@ tokio.workspace = true
 boa_engine.workspace = true
 rayon.workspace = true
 
-[dev-dependencies]
-pollster = "*"
-
 [features]
 editor = []
 
diff --git a/eucalyptus-editor/src/editor/dock.rs b/eucalyptus-editor/src/editor/dock.rs
index aaaee6f..28a68db 100644
--- a/eucalyptus-editor/src/editor/dock.rs
+++ b/eucalyptus-editor/src/editor/dock.rs
@@ -386,47 +386,49 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                 if !matches!(self.viewport_mode, ViewportMode::None) {
                     if let Some(entity_id) = self.selected_entity {
                         {
-                            if let Ok(transform) = self.world.write()
-                                .query_one_mut::<&mut Transform>(*entity_id)
+                            if let Ok(mut q) = self.world.read()
+                                .query_one::<&mut Transform>(*entity_id)
                             {
-                                let was_focused = cfg.is_focused;
-                                cfg.is_focused = self.gizmo.is_focused();
+                                if let Some(transform) = q.get() {
+                                    let was_focused = cfg.is_focused;
+                                    cfg.is_focused = self.gizmo.is_focused();
 
-                                if cfg.is_focused && !was_focused {
-                                    cfg.old_pos = *transform;
-                                }
+                                    if cfg.is_focused && !was_focused {
+                                        cfg.old_pos = *transform;
+                                    }
 
-                                let gizmo_transform =
-                                    transform_gizmo_egui::math::Transform::from_scale_rotation_translation(
-                                        transform.scale,
-                                        transform.rotation,
-                                        transform.position,
-                                    );
+                                    let gizmo_transform =
+                                        transform_gizmo_egui::math::Transform::from_scale_rotation_translation(
+                                            transform.scale,
+                                            transform.rotation,
+                                            transform.position,
+                                        );
 
-                                if let Some((_result, new_transforms)) =
-                                    self.gizmo.interact(ui, &[gizmo_transform])
-                                {
-                                    if let Some(new_transform) = new_transforms.first() {
-                                        transform.position = new_transform.translation.into();
-                                        transform.rotation = new_transform.rotation.into();
-                                        transform.scale = new_transform.scale.into();
+                                    if let Some((_result, new_transforms)) =
+                                        self.gizmo.interact(ui, &[gizmo_transform])
+                                    {
+                                        if let Some(new_transform) = new_transforms.first() {
+                                            transform.position = new_transform.translation.into();
+                                            transform.rotation = new_transform.rotation.into();
+                                            transform.scale = new_transform.scale.into();
+                                        }
                                     }
-                                }
 
-                                if was_focused && !cfg.is_focused {
-                                    let transform_changed = cfg.old_pos.position != transform.position
-                                        || cfg.old_pos.rotation != transform.rotation
-                                        || cfg.old_pos.scale != transform.scale;
-
-                                    if transform_changed {
-                                        UndoableAction::push_to_undo(
-                                            &mut self.undo_stack,
-                                            UndoableAction::Transform(
-                                                entity_id.clone(),
-                                                cfg.old_pos.clone(),
-                                            ),
-                                        );
-                                        log::debug!("Pushed transform action to stack");
+                                    if was_focused && !cfg.is_focused {
+                                        let transform_changed = cfg.old_pos.position != transform.position
+                                            || cfg.old_pos.rotation != transform.rotation
+                                            || cfg.old_pos.scale != transform.scale;
+
+                                        if transform_changed {
+                                            UndoableAction::push_to_undo(
+                                                &mut self.undo_stack,
+                                                UndoableAction::Transform(
+                                                    entity_id.clone(),
+                                                    cfg.old_pos.clone(),
+                                                ),
+                                            );
+                                            log::debug!("Pushed transform action to stack");
+                                        }
                                     }
                                 }
                             }
@@ -1018,21 +1020,25 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                             log::debug!("Add Component clicked");
                             if let Some(entity) = self.selected_entity {
                                 {
-                                    if let Ok(..) = self.world.write()
-                                        .query_one_mut::<&AdoptedEntity>(*entity)
+                                    if let Ok(mut q) = self.world.read()
+                                        .query_one::<&AdoptedEntity>(*entity)
                                     {
-                                        log::debug!("Queried selected entity, it is an entity");
-                                        *self.signal =
-                                            Signal::AddComponent(*entity, EntityType::Entity);
+                                        if let Some(..) = q.get() {
+                                            log::debug!("Queried selected entity, it is an entity");
+                                            *self.signal =
+                                                Signal::AddComponent(*entity, EntityType::Entity);
+                                        }
                                     }
                                 }
 
                                 {
-                                    if let Ok(..) = self.world.write()
-                                        .query_one_mut::<&Light>(*entity)
+                                    if let Ok(mut q) = self.world.read()
+                                        .query_one::<&Light>(*entity)
                                     {
-                                        log::debug!("Queried selected entity, it is a light");
-                                        *self.signal = Signal::AddComponent(*entity, EntityType::Light);
+                                        if let Some(..) = q.get() {
+                                            log::debug!("Queried selected entity, it is a light");
+                                            *self.signal = Signal::AddComponent(*entity, EntityType::Light);
+                                        }
                                     }
                                 }
                             } else {
@@ -1054,16 +1060,18 @@ impl<'a> TabViewer for EditorTabViewer<'a> {
                         EditorTabMenuAction::RemoveComponent => {
                             log::debug!("Remove Component clicked");
                             if let Some(entity) = self.selected_entity {
-                                if let Ok(script) = self.world.write()
-                                    .query_one_mut::<&ScriptComponent>(*entity)
+                                if let Ok(mut q) = self.world.write()
+                                    .query_one::<&ScriptComponent>(*entity)
                                 {
-                                    log::debug!(
-                                        "Queried selected entity, it has a script component"
-                                    );
-                                    *self.signal = Signal::RemoveComponent(
-                                        *entity,
-                                        ComponentType::Script(script.clone()),
-                                    );
+                                    if let Some(script) = q.get() {
+                                        log::debug!(
+                                            "Queried selected entity, it has a script component"
+                                        );
+                                        *self.signal = Signal::RemoveComponent(
+                                            *entity,
+                                            ComponentType::Script(script.clone()),
+                                        );
+                                    }
                                 } else {
                                     warn!(
                                         "Selected entity does not have a script component to remove"
diff --git a/eucalyptus-editor/src/editor/mod.rs b/eucalyptus-editor/src/editor/mod.rs
index 1fc3842..806f2fe 100644
--- a/eucalyptus-editor/src/editor/mod.rs
+++ b/eucalyptus-editor/src/editor/mod.rs
@@ -1092,41 +1092,49 @@ impl UndoableAction {
                 match action {
                     UndoableCameraAction::Speed(entity, speed) => {
                         {
-                            if let Ok((cam, comp)) =
-                                world.write().query_one_mut::<(&mut Camera, &mut CameraComponent)>(*entity)
+                            if let Ok(mut q) =
+                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
                             {
-                                comp.speed = *speed;
-                                comp.update(cam);
+                                if let Some((cam, comp)) = q.get() {
+                                    comp.speed = *speed;
+                                    comp.update(cam);
+                                }
                             }
                         }
                     }
                     UndoableCameraAction::Sensitivity(entity, sensitivity) => {
                         {
-                            if let Ok((cam, comp)) =
-                                world.write().query_one_mut::<(&mut Camera, &mut CameraComponent)>(*entity)
+                            if let Ok(mut q) =
+                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
                             {
-                                comp.sensitivity = *sensitivity;
-                                comp.update(cam);
+                                if let Some((cam, comp)) = q.get() {
+                                    comp.sensitivity = *sensitivity;
+                                    comp.update(cam);
+                                }
                             }
                         }
                     }
                     UndoableCameraAction::FOV(entity, fov) => {
                         {
-                            if let Ok((cam, comp)) =
-                                world.write().query_one_mut::<(&mut Camera, &mut CameraComponent)>(*entity)
+                            if let Ok(mut q) =
+                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
                             {
-                                comp.fov_y = *fov;
-                                comp.update(cam);
+                                if let Some((cam, comp)) = q.get() {
+                                    comp.fov_y = *fov;
+                                    comp.update(cam);
+                                }
                             }
                         }
                     }
                     UndoableCameraAction::Type(entity, camera_type) => {
                         {
-                            if let Ok((cam, comp)) =
-                                world.write().query_one_mut::<(&mut Camera, &mut CameraComponent)>(*entity)
+                            if let Ok(mut q) =
+                                world.read().query_one::<(&mut Camera, &mut CameraComponent)>(*entity)
                             {
-                                comp.camera_type = *camera_type;
-                                comp.update(cam);
+                                if let Some((cam, comp)) = q.get() {
+                                    comp.camera_type = *camera_type;
+                                    comp.update(cam);
+                                }
                             }
                         }
                     }
diff --git a/eucalyptus-editor/src/editor/scene.rs b/eucalyptus-editor/src/editor/scene.rs
index 03621ef..0ab84d8 100644
--- a/eucalyptus-editor/src/editor/scene.rs
+++ b/eucalyptus-editor/src/editor/scene.rs
@@ -767,93 +767,95 @@ impl Scene for Editor {
             Signal::AddComponent(entity, e_type) => {
                 match e_type {
                     EntityType::Entity => {
-                        if let Ok(e) = self.world.write()
-                            .query_one_mut::<&AdoptedEntity>(*entity)
+                        if let Ok(mut q) = self.world.read()
+                            .query_one::<&AdoptedEntity>(*entity)
                         {
-                            let mut local_signal: Option<Signal> = None;
-                            let label = e.label().clone();
-                            let mut show = true;
-                            egui::Window::new(format!("Add component for {}", label))
-                                .title_bar(true)
-                                .open(&mut show)
-                                .scroll([false, true])
-                                .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                                .enabled(true)
-                                .show(&graphics.shared.get_egui_context(), |ui| {
-                                    if ui
-                                        .add_sized(
-                                            [ui.available_width(), 30.0],
-                                            egui::Button::new("Scripting"),
-                                        )
-                                        .clicked()
-                                    {
-                                        log::debug!(
+                            if let Some(e) = q.get() {
+                                let mut local_signal: Option<Signal> = None;
+                                let label = e.label().clone();
+                                let mut show = true;
+                                egui::Window::new(format!("Add component for {}", label))
+                                    .title_bar(true)
+                                    .open(&mut show)
+                                    .scroll([false, true])
+                                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                                    .enabled(true)
+                                    .show(&graphics.shared.get_egui_context(), |ui| {
+                                        if ui
+                                            .add_sized(
+                                                [ui.available_width(), 30.0],
+                                                egui::Button::new("Scripting"),
+                                            )
+                                            .clicked()
+                                        {
+                                            log::debug!(
                                             "Adding scripting component to entity [{}]",
                                             label
                                         );
-                                        {
-                                            if let Err(e) = self.world.write()
-                                                .insert_one(*entity, ScriptComponent::default())
                                             {
-                                                warn!(
+                                                if let Err(e) = self.world.write()
+                                                    .insert_one(*entity, ScriptComponent::default())
+                                                {
+                                                    warn!(
                                                 "Failed to add scripting component to entity: {}",
                                                 e
                                             );
-                                            } else {
-                                                success!("Added the scripting component");
+                                                } else {
+                                                    success!("Added the scripting component");
+                                                }
                                             }
+                                            local_signal = Some(Signal::None);
                                         }
-                                        local_signal = Some(Signal::None);
-                                    }
-                                    if ui
-                                        .add_sized(
-                                            [ui.available_width(), 30.0],
-                                            egui::Button::new("Camera"),
-                                        )
-                                        .clicked()
-                                    {
-                                        log::debug!(
+                                        if ui
+                                            .add_sized(
+                                                [ui.available_width(), 30.0],
+                                                egui::Button::new("Camera"),
+                                            )
+                                            .clicked()
+                                        {
+                                            log::debug!(
                                             "Adding camera component to entity [{}]",
                                             label
                                         );
 
-                                        let has_camera = self.world.read()
-                                            .query_one::<(&Camera, &CameraComponent)>(*entity)
-                                            .is_ok();
+                                            let has_camera = self.world.read()
+                                                .query_one::<(&Camera, &CameraComponent)>(*entity)
+                                                .is_ok();
 
-                                        if has_camera {
-                                            warn!(
+                                            if has_camera {
+                                                warn!(
                                                 "Entity [{}] already has a camera component",
                                                 label
                                             );
-                                        } else {
-                                            let camera = Camera::predetermined(
-                                                graphics.shared.clone(),
-                                                Some(&format!("{} Camera", label)),
-                                            );
-                                            let component = CameraComponent::new();
+                                            } else {
+                                                let camera = Camera::predetermined(
+                                                    graphics.shared.clone(),
+                                                    Some(&format!("{} Camera", label)),
+                                                );
+                                                let component = CameraComponent::new();
 
-                                            {
-                                                if let Err(e) = self.world.write()
-                                                    .insert(*entity, (camera, component))
                                                 {
-                                                    warn!(
+                                                    if let Err(e) = self.world.write()
+                                                        .insert(*entity, (camera, component))
+                                                    {
+                                                        warn!(
                                                     "Failed to add camera component to entity: {}",
                                                     e
                                                 );
-                                                } else {
-                                                    success!("Added the camera component");
+                                                    } else {
+                                                        success!("Added the camera component");
+                                                    }
                                                 }
                                             }
+                                            local_signal = Some(Signal::None);
                                         }
-                                        local_signal = Some(Signal::None);
-                                    }
-                                });
-                            if !show {
-                                self.signal = Signal::None;
-                            }
-                            if let Some(signal) = local_signal {
-                                self.signal = signal
+                                    });
+                                if !show {
+                                    self.signal = Signal::None;
+                                }
+                                if let Some(signal) = local_signal {
+                                    self.signal = signal
+                                }
                             }
                         } else {
                             log_once::warn_once!(
@@ -863,38 +865,40 @@ impl Scene for Editor {
                     }
                     EntityType::Light => {
                         {
-                            if let Ok(light) = self.world.write()
-                                .query_one_mut::<&Light>(*entity)
+                            if let Ok(mut q) = self.world.read()
+                                .query_one::<&Light>(*entity)
                             {
-                                let mut show = true;
-                                egui::Window::new(format!("Add component for {}", light.label))
-                                    .scroll([false, true])
-                                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                                    .enabled(true)
-                                    .open(&mut show)
-                                    .title_bar(true)
-                                    .show(&graphics.shared.get_egui_context(), |ui| {
-                                        if ui
-                                            .add_sized(
-                                                [ui.available_width(), 30.0],
-                                                egui::Button::new("Scripting"),
-                                            )
-                                            .clicked()
-                                        {
-                                            log::debug!(
+                                if let Some(light) = q.get() {
+                                    let mut show = true;
+                                    egui::Window::new(format!("Add component for {}", light.label))
+                                        .scroll([false, true])
+                                        .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                                        .enabled(true)
+                                        .open(&mut show)
+                                        .title_bar(true)
+                                        .show(&graphics.shared.get_egui_context(), |ui| {
+                                            if ui
+                                                .add_sized(
+                                                    [ui.available_width(), 30.0],
+                                                    egui::Button::new("Scripting"),
+                                                )
+                                                .clicked()
+                                            {
+                                                log::debug!(
                                             "Adding scripting component to light [{}]",
                                             light.label
                                         );
 
-                                            success!(
+                                                success!(
                                             "Added the scripting component to light [{}]",
                                             light.label
                                         );
-                                            self.signal = Signal::None;
-                                        }
-                                    });
-                                if !show {
-                                    self.signal = Signal::None;
+                                                self.signal = Signal::None;
+                                            }
+                                        });
+                                    if !show {
+                                        self.signal = Signal::None;
+                                    }
                                 }
                             } else {
                                 log_once::warn_once!(
@@ -905,33 +909,35 @@ impl Scene for Editor {
                     }
                     EntityType::Camera => {
                         {
-                            if let Ok((cam, _comp)) = self.world.write()
-                                .query_one_mut::<(&Camera, &CameraComponent)>(*entity)
+                            if let Ok(mut q) = self.world.write()
+                                .query_one::<(&Camera, &CameraComponent)>(*entity)
                             {
-                                let mut show = true;
-                                egui::Window::new(format!("Add component for {}", cam.label))
-                                    .scroll([false, true])
-                                    .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
-                                    .enabled(true)
-                                    .open(&mut show)
-                                    .title_bar(true)
-                                    .show(&graphics.shared.get_egui_context(), |ui| {
-                                        egui_extras::install_image_loaders(ui.ctx());
-                                        ui.add(Image::from_bytes(
-                                            "bytes://theres_nothing.jpg",
-                                            include_bytes!("../../../resources/theres_nothing.jpg"),
-                                        ));
-                                        ui.label("Theres nothing...");
-                                        // // scripting
-                                        // if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Scripting")).clicked() {
-                                        //     log::debug!("Adding scripting component to camera [{}]", cam.label);
-
-                                        //     success!("Added the scripting component to camera [{}]", cam.label);
-                                        //     self.signal = Signal::None;
-                                        // }
-                                    });
-                                if !show {
-                                    self.signal = Signal::None;
+                                if let Some((cam, _comp)) = q.get() {
+                                    let mut show = true;
+                                    egui::Window::new(format!("Add component for {}", cam.label))
+                                        .scroll([false, true])
+                                        .anchor(Align2::CENTER_CENTER, [0.0, 0.0])
+                                        .enabled(true)
+                                        .open(&mut show)
+                                        .title_bar(true)
+                                        .show(&graphics.shared.get_egui_context(), |ui| {
+                                            egui_extras::install_image_loaders(ui.ctx());
+                                            ui.add(Image::from_bytes(
+                                                "bytes://theres_nothing.jpg",
+                                                include_bytes!("../../../resources/theres_nothing.jpg"),
+                                            ));
+                                            ui.label("Theres nothing...");
+                                            // // scripting
+                                            // if ui.add_sized([ui.available_width(), 30.0], egui::Button::new("Scripting")).clicked() {
+                                            //     log::debug!("Adding scripting component to camera [{}]", cam.label);
+
+                                            //     success!("Added the scripting component to camera [{}]", cam.label);
+                                            //     self.signal = Signal::None;
+                                            // }
+                                        });
+                                    if !show {
+                                        self.signal = Signal::None;
+                                    }
                                 }
                             } else {
                                 log_once::warn_once!(
diff --git a/scripts/gen_docs.bat b/scripts/gen_docs.bat
deleted file mode 100644
index 5b04b65..0000000
--- a/scripts/gen_docs.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-
-npm install --save-dev typedoc
-npx typedoc resources/dropbear.ts
diff --git a/scripts/gen_docs.sh b/scripts/gen_docs.sh
deleted file mode 100644
index ec47d76..0000000
--- a/scripts/gen_docs.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-npm install --save-dev typedoc
-npx typedoc resources/dropbear.ts
diff --git a/tsconfig.json b/tsconfig.json
deleted file mode 100644
index 91c334d..0000000
--- a/tsconfig.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "compilerOptions": {
-        "lib": ["es6", "DOM"],
-        "target": "es5",
-        "forceConsistentCasingInFileNames": true,
-        "strict": true
-    },
-}
\ No newline at end of file
diff --git a/typedoc.json b/typedoc.json
deleted file mode 100644
index 1ff8547..0000000
--- a/typedoc.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-    "name": "dropbear",
-    "projectDocuments": ["ts/articles/*.md"]
-}
\ No newline at end of file