From bcaa28cf6a9f5f06161cc9375a5b720826108629 Mon Sep 17 00:00:00 2001
From: Quaternions <krakow20@gmail.com>
Date: Wed, 14 Feb 2024 23:38:29 -0800
Subject: [PATCH] implement new loading api

---
 Cargo.lock |  2 +-
 Cargo.toml |  2 +-
 src/lib.rs |  4 ++--
 src/rbx.rs | 56 ++++++++++++++++++++++++++++++++++++++----------------
 4 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 180a3bd..00f0b4e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -420,7 +420,7 @@ dependencies = [
 [[package]]
 name = "strafesnet_common"
 version = "0.1.0"
-source = "git+https://git.itzana.me/StrafesNET/common?rev=47cdea0c8a5d10a2440ca6270a975d560aa3642d#47cdea0c8a5d10a2440ca6270a975d560aa3642d"
+source = "git+https://git.itzana.me/StrafesNET/common?rev=093a54c527134ef7020a22a0f5778df8cba60228#093a54c527134ef7020a22a0f5778df8cba60228"
 dependencies = [
  "glam",
  "id",
diff --git a/Cargo.toml b/Cargo.toml
index 0897aab..56c9c60 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,4 +12,4 @@ rbx_binary = "0.7.4"
 rbx_dom_weak = "2.7.0"
 rbx_reflection_database = "0.2.10"
 rbx_xml = "0.13.3"
-strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "47cdea0c8a5d10a2440ca6270a975d560aa3642d" }
+strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "093a54c527134ef7020a22a0f5778df8cba60228" }
diff --git a/src/lib.rs b/src/lib.rs
index 20f397a..412cb55 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -31,6 +31,6 @@ pub fn read<R:Read>(input:R)->Result<Dom,ReadError>{
 
 //ConvertError
 
-pub fn convert<F:FnMut(&str)->Option<strafesnet_common::model::TextureId>>(dom:&Dom,acquire_id:F)->strafesnet_common::map::CompleteMap{
-	rbx::convert(&dom.0,acquire_id)
+pub fn convert<F:FnMut(Option<&str>)->strafesnet_common::model::RenderConfigId>(dom:&Dom,acquire_render_config_id:F)->rbx::PartialMap1{
+	rbx::convert(&dom.0,acquire_render_config_id)
 }
\ No newline at end of file
diff --git a/src/rbx.rs b/src/rbx.rs
index d67c980..57b9a56 100644
--- a/src/rbx.rs
+++ b/src/rbx.rs
@@ -405,7 +405,7 @@ struct ModelOwnedAttributes{
 	color:model::Color4,//transparency is in here
 	transform:Planar64Affine3,
 }
-pub fn convert<F:FnMut(&str)->Option<model::TextureId>>(dom:&rbx_dom_weak::WeakDom,mut acquire_id:F)->map::CompleteMap{
+pub fn convert<F:FnMut(Option<&str>)->model::RenderConfigId>(dom:&rbx_dom_weak::WeakDom,mut acquire_render_config_id:F)->PartialMap1{
 	let mut modes_builder=ModesBuilder::default();
 
 	let mut models1=Vec::new();
@@ -418,10 +418,8 @@ pub fn convert<F:FnMut(&str)->Option<model::TextureId>>(dom:&rbx_dom_weak::WeakD
 	let mut wormhole_in_model_to_id=HashMap::new();
 	let mut wormhole_id_to_out_model=HashMap::new();
 
-	//TODO: some sort of thing like RobloxResources that describes where to get each resource
-	//this would be another dependency built for downloading resources to keep this one clean
-	let mut unique_render_groups=vec![RenderConfig::default()];
-	let textureless_render_group=RenderConfigId::new(0);
+	//just going to leave it like this for now instead of reworking the data structures for this whole thing
+	let textureless_render_group=acquire_render_config_id(None);
 
 	let mut object_refs=Vec::new();
 	let mut temp_objects=Vec::new();
@@ -503,14 +501,7 @@ pub fn convert<F:FnMut(&str)->Option<model::TextureId>>(dom:&rbx_dom_weak::WeakD
 							decal.properties.get("Color3"),
 							decal.properties.get("Transparency"),
 						) {
-							if let Some(texture_id)=acquire_id(content.as_ref()){
-								//this is equivalent to a get_or_create pattern because there is a singular no-texture RenderId
-								//so RenderId==TextureId+1
-								//not the most failsafe code but this is just for the map tool lmao
-								if unique_render_groups.len()==texture_id.get() as usize+1{
-									unique_render_groups.push(RenderConfig::texture(texture_id));
-								};
-								let render_id=RenderConfigId::new(texture_id.get()+1);
+							let render_id=acquire_render_config_id(Some(content.as_ref()));
 								let normal_id=normalid.to_u32();
 								if normal_id<6{
 									let (roblox_texture_color,roblox_texture_transform)=if decal.class=="Texture"{
@@ -557,7 +548,6 @@ pub fn convert<F:FnMut(&str)->Option<model::TextureId>>(dom:&rbx_dom_weak::WeakD
 								}else{
 									println!("NormalId={} unsupported for shape={:?}",normal_id,shape);
 								}
-							}
 						}
 					}
 				}
@@ -711,11 +701,45 @@ pub fn convert<F:FnMut(&str)->Option<model::TextureId>>(dom:&rbx_dom_weak::WeakD
 			attributes:attributes_id,
 		}
 	}).collect();
-	map::CompleteMap{
-		render_configs:unique_render_groups,//asset_id_from_texture_id.iter().map(|t|t.to_string()).collect(),
+	PartialMap1{
 		meshes,
 		models,
 		modes:modes_builder.build(),
 		attributes:unique_attributes,
 	}
 }
+
+pub struct PartialMap1{
+	meshes:Vec<model::Mesh>,
+	models:Vec<model::Model>,
+	modes:gameplay_modes::Modes,
+	attributes:Vec<strafesnet_common::gameplay_attributes::CollisionAttributes>,
+}
+impl PartialMap1{
+	pub fn add_render_configs_and_textures(
+		self,
+		render_configs:impl IntoIterator<Item=(model::RenderConfigId,model::RenderConfig)>,
+		textures:impl IntoIterator<Item=(model::TextureId,Vec<u8>)>,
+	)->map::CompleteMap{
+		let (textures,texture_id_map):(Vec<Vec<u8>>,HashMap<model::TextureId,model::TextureId>)
+		=textures.into_iter().enumerate().map(|(new_texture_id,(old_texture_id,texture))|{
+			(texture,(old_texture_id,model::TextureId::new(new_texture_id as u32)))
+		}).unzip();
+		let render_configs=render_configs.into_iter().map(|(render_config_id,mut render_config)|{
+			//this may generate duplicate no-texture render configs but idc
+			render_config.texture=render_config.texture.and_then(|texture_id|
+				texture_id_map.get(&texture_id).copied()
+			);
+			render_config
+		}).collect();
+		map::CompleteMap{
+			modes:self.modes,
+			attributes:self.attributes,
+			meshes:self.meshes,
+			models:self.models,
+			//the roblox legacy texture thing always works 
+			textures,
+			render_configs,
+		}
+	}
+}
\ No newline at end of file