From 181568b6456e8af0de8aeaf19527ea861b3d6be9 Mon Sep 17 00:00:00 2001
From: melody-rs <melody@melody-is.gay>
Date: Sat, 1 Feb 2025 14:58:47 -0800
Subject: [PATCH] Move command db to data crate to avoid cyclic dependency

---
 Cargo.lock                                |  1 +
 Cargo.toml                                |  2 ++
 crates/config/src/lib.rs                  |  1 -
 crates/config/src/project.rs              | 28 ++++++++++++++++---
 crates/data/Cargo.toml                    |  1 +
 crates/{config => data}/src/command_db.rs | 34 ++++-------------------
 crates/data/src/lib.rs                    |  2 ++
 crates/data/src/rmxp/map.rs               |  4 +++
 8 files changed, 39 insertions(+), 34 deletions(-)
 rename crates/{config => data}/src/command_db.rs (69%)

diff --git a/Cargo.lock b/Cargo.lock
index 79734d2d..fd0f4065 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3231,6 +3231,7 @@ dependencies = [
  "camino",
  "egui",
  "flate2",
+ "indextree",
  "num_enum",
  "paste",
  "rand",
diff --git a/Cargo.toml b/Cargo.toml
index 83212893..a4680c5f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -183,6 +183,8 @@ rand = "0.8.5" # Random number generators and other randomness functionality
 lexical-sort = "0.3.1" # Functions that compare and sort strings lexicographically
 indexmap = "2.2.6" # A hash table with consistent order and fast iteration
 
+indextree = "4.7.2" # A general tree structure which stores nodes in an arena
+
 # Fast and performant.
 [profile.release]
 opt-level = 3
diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs
index 848f9261..d8943ed3 100644
--- a/crates/config/src/lib.rs
+++ b/crates/config/src/lib.rs
@@ -15,7 +15,6 @@
 // You should have received a copy of the GNU General Public License
 // along with Luminol.  If not, see <http://www.gnu.org/licenses/>.
 
-pub mod command_db;
 pub mod global;
 pub mod project;
 #[cfg(not(target_arch = "wasm32"))]
diff --git a/crates/config/src/project.rs b/crates/config/src/project.rs
index ffe6f9b5..e7a69246 100644
--- a/crates/config/src/project.rs
+++ b/crates/config/src/project.rs
@@ -21,15 +21,15 @@
 // it with Steamworks API by Valve Corporation, containing parts covered by
 // terms of the Steamworks API by Valve Corporation, the licensors of this
 // Program grant you additional permission to convey the resulting work.
+use super::{DataFormat, RGSSVer, RMVer, VolumeScale};
+use once_cell::sync::Lazy;
 use serde::{Deserialize, Serialize};
 
-use super::{command_db, DataFormat, RGSSVer, RMVer, VolumeScale};
-
 #[derive(Debug, Clone)]
 #[allow(clippy::large_enum_variant)]
 pub struct Config {
     pub project: Project,
-    pub command_db: command_db::CommandDB,
+    pub command_db: luminol_data::CommandDB,
     pub game_ini: ini::Ini,
 }
 
@@ -65,6 +65,21 @@ impl Default for Project {
     }
 }
 
+static XP_COMMANDS: Lazy<luminol_data::CommandSet> = Lazy::new(|| {
+    let dir = luminol_macros::include_asset_dir_ids!("assets/commands/XP");
+    dir.into_iter()
+        .map(|(id, data)| {
+            let str = std::str::from_utf8(data).unwrap();
+            let cmd = ron::from_str(str).unwrap();
+            (id, cmd)
+        })
+        .collect()
+});
+
+static VX_COMMANDS: Lazy<luminol_data::CommandSet> = Lazy::new(|| todo!());
+
+static ACE_COMMANDS: Lazy<luminol_data::CommandSet> = Lazy::new(|| todo!());
+
 impl Config {
     pub fn from_project(project: Project) -> Self {
         let mut game_ini = ini::Ini::new();
@@ -77,7 +92,12 @@ impl Config {
             .set("RTP2", "")
             .set("RTP3", "");
 
-        let command_db = command_db::CommandDB::new(project.editor_ver);
+        let default = match project.editor_ver {
+            RMVer::XP => &*XP_COMMANDS,
+            RMVer::VX => &*VX_COMMANDS,
+            RMVer::Ace => &*ACE_COMMANDS,
+        };
+        let command_db = luminol_data::CommandDB::from_defaults(default.clone());
 
         Self {
             project,
diff --git a/crates/data/Cargo.toml b/crates/data/Cargo.toml
index 123737f4..7b505b03 100644
--- a/crates/data/Cargo.toml
+++ b/crates/data/Cargo.toml
@@ -43,3 +43,4 @@ egui.workspace = true
 # * Misc * #
 rand.workspace = true
 flate2 = "1.0"        # DEFLATE compression and decompression exposed as Read/BufRead/Write streams
+indextree.workspace = true
\ No newline at end of file
diff --git a/crates/config/src/command_db.rs b/crates/data/src/command_db.rs
similarity index 69%
rename from crates/config/src/command_db.rs
rename to crates/data/src/command_db.rs
index f35e64d0..e8bb162b 100644
--- a/crates/config/src/command_db.rs
+++ b/crates/data/src/command_db.rs
@@ -22,29 +22,10 @@
 // terms of the Steamworks API by Valve Corporation, the licensors of this
 // Program grant you additional permission to convey the resulting work.
 
-use luminol_data::commands::Command;
-use once_cell::sync::Lazy;
-use std::collections::HashMap;
-
+use crate::commands::Command;
 use serde::{Deserialize, Serialize};
 
-use super::RMVer;
-
-type CommandSet = HashMap<u16, Command>;
-static XP_DEFAULT: Lazy<CommandSet> = Lazy::new(|| {
-    let dir = luminol_macros::include_asset_dir_ids!("assets/commands/XP");
-    dir.into_iter()
-        .map(|(id, data)| {
-            let str = std::str::from_utf8(data).unwrap();
-            let cmd = ron::from_str(str).unwrap();
-            (id, cmd)
-        })
-        .collect()
-});
-
-static VX_DEFAULT: Lazy<CommandSet> = Lazy::new(|| todo!());
-
-static ACE_DEFAULT: Lazy<CommandSet> = Lazy::new(|| todo!());
+pub type CommandSet = std::collections::HashMap<u16, Command>;
 
 #[derive(Deserialize, Serialize, Debug, Clone)]
 pub struct CommandDB {
@@ -56,15 +37,10 @@ pub struct CommandDB {
 }
 
 impl CommandDB {
-    pub fn new(ver: RMVer) -> Self {
+    pub fn from_defaults(default: CommandSet) -> Self {
         Self {
-            default: match ver {
-                RMVer::XP => &*XP_DEFAULT,
-                RMVer::VX => &*VX_DEFAULT,
-                RMVer::Ace => &*ACE_DEFAULT,
-            }
-            .clone(),
-            user: HashMap::new(),
+            default,
+            user: CommandSet::new(),
         }
     }
 
diff --git a/crates/data/src/lib.rs b/crates/data/src/lib.rs
index 408da518..a115c767 100644
--- a/crates/data/src/lib.rs
+++ b/crates/data/src/lib.rs
@@ -12,8 +12,10 @@ mod rgss_structs;
 
 pub mod helpers;
 
+mod command_db;
 pub mod commands;
 
+pub use command_db::{CommandDB, CommandSet};
 pub use helpers::*;
 pub use option_vec::OptionVec;
 pub use rgss_structs::{Color, Table1, Table2, Table3, Tone};
diff --git a/crates/data/src/rmxp/map.rs b/crates/data/src/rmxp/map.rs
index d21ab4b6..1ceb9d6c 100644
--- a/crates/data/src/rmxp/map.rs
+++ b/crates/data/src/rmxp/map.rs
@@ -39,3 +39,7 @@ pub struct Map {
     #[serde(skip)]
     pub modified: bool,
 }
+
+pub struct MapDeserializer<'de> {
+    command_db: &'de crate::CommandDB,
+}