use std::collections::HashMap;
use std::sync::{Arc, RwLock};
pub const UNITY_TAG_URI: &str = "tag:unity3d.com,2011:";
pub const UNITY_YAML_VERSION: (u32, u32) = (1, 1);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LineEnding {
Unix, Windows, Mac, }
impl Default for LineEnding {
fn default() -> Self {
#[cfg(windows)]
return LineEnding::Windows;
#[cfg(not(windows))]
return LineEnding::Unix;
}
}
impl LineEnding {
pub fn as_str(&self) -> &'static str {
match self {
LineEnding::Unix => "\n",
LineEnding::Windows => "\r\n",
LineEnding::Mac => "\r",
}
}
pub fn from_string(s: &str) -> Self {
match s {
"\n" => LineEnding::Unix,
"\r\n" => LineEnding::Windows,
"\r" => LineEnding::Mac,
_ => LineEnding::default(),
}
}
}
pub struct UnityClassIdMap {
map: Arc<RwLock<HashMap<String, String>>>,
}
impl UnityClassIdMap {
pub fn new() -> Self {
Self {
map: Arc::new(RwLock::new(HashMap::new())),
}
}
pub fn get_or_create(&self, class_id: &str, class_name: &str) -> String {
let key = format!("{}-{}", class_id, class_name);
if let Ok(map) = self.map.read()
&& let Some(existing) = map.get(&key)
{
return existing.clone();
}
if let Ok(mut map) = self.map.write() {
map.insert(key.clone(), class_name.to_string());
}
class_name.to_string()
}
pub fn clear(&self) {
if let Ok(mut map) = self.map.write() {
map.clear();
}
}
pub fn get_class_name(&self, class_id: i32) -> Option<String> {
self.get_class_name_str(class_id).map(str::to_string)
}
pub fn get_class_name_str(&self, class_id: i32) -> Option<&'static str> {
class_id_name(class_id)
}
}
fn class_id_name(class_id: i32) -> Option<&'static str> {
match class_id {
0 => Some("Object"),
1 => Some("GameObject"),
2 => Some("Component"),
4 => Some("Transform"),
8 => Some("Behaviour"),
3 => Some("LevelGameManager"),
5 => Some("TimeManager"),
6 => Some("GlobalGameManager"),
9 => Some("GameManager"),
11 => Some("AudioManager"),
13 => Some("InputManager"),
20 => Some("Camera"),
21 => Some("Material"),
23 => Some("MeshRenderer"),
25 => Some("Renderer"),
27 => Some("Texture"),
28 => Some("Texture2D"),
33 => Some("MeshFilter"),
43 => Some("Mesh"),
48 => Some("Shader"),
49 => Some("TextAsset"),
74 => Some("AnimationClip"),
83 => Some("AudioClip"),
89 => Some("CubemapArray"),
90 => Some("Avatar"),
91 => Some("AnimatorController"),
95 => Some("Animator"),
108 => Some("Light"),
114 => Some("MonoBehaviour"),
115 => Some("MonoScript"),
128 => Some("Font"),
142 => Some("AssetBundle"),
152 => Some("MovieTexture"),
184 => Some("RenderTexture"),
212 => Some("SpriteRenderer"),
213 => Some("Sprite"),
1001 => Some("PrefabInstance"),
50 => Some("Rigidbody2D"),
54 => Some("Rigidbody"),
56 => Some("Collider"),
687078895 => Some("SpriteAtlas"),
_ => None,
}
}
impl Default for UnityClassIdMap {
fn default() -> Self {
Self::new()
}
}
lazy_static::lazy_static! {
pub static ref GLOBAL_CLASS_ID_MAP: UnityClassIdMap = UnityClassIdMap::new();
}
pub mod class_ids {
pub const OBJECT: i32 = 0;
pub const GAME_OBJECT: i32 = 1;
pub const COMPONENT: i32 = 2;
pub const BEHAVIOUR: i32 = 8;
pub const TRANSFORM: i32 = 4;
pub const CAMERA: i32 = 20;
pub const MATERIAL: i32 = 21;
pub const MESH_RENDERER: i32 = 23;
pub const TEXTURE_2D: i32 = 28;
pub const MESH: i32 = 43;
pub const SHADER: i32 = 48;
pub const TEXTURE: i32 = 27;
pub const TEXT_ASSET: i32 = 49;
pub const ANIMATION_CLIP: i32 = 74;
pub const AUDIO_CLIP: i32 = 83;
pub const ANIMATOR_CONTROLLER: i32 = 91;
pub const MONO_BEHAVIOUR: i32 = 114;
pub const MONO_SCRIPT: i32 = 115;
pub const ASSET_BUNDLE: i32 = 142;
pub const SPRITE_RENDERER: i32 = 212;
pub const SPRITE: i32 = 213;
pub const PREFAB_INSTANCE: i32 = 1001;
pub const SPRITE_ATLAS: i32 = 687078895;
}
pub mod class_names {
pub const OBJECT: &str = "Object";
pub const GAME_OBJECT: &str = "GameObject";
pub const COMPONENT: &str = "Component";
pub const TRANSFORM: &str = "Transform";
pub const CAMERA: &str = "Camera";
pub const MATERIAL: &str = "Material";
pub const MESH_RENDERER: &str = "MeshRenderer";
pub const TEXTURE_2D: &str = "Texture2D";
pub const MESH: &str = "Mesh";
pub const SHADER: &str = "Shader";
pub const TEXTURE: &str = "Texture";
pub const SPRITE: &str = "Sprite";
pub const MONO_BEHAVIOUR: &str = "MonoBehaviour";
pub const MONO_SCRIPT: &str = "MonoScript";
pub const PREFAB_INSTANCE: &str = "PrefabInstance";
pub const SPRITE_ATLAS: &str = "SpriteAtlas";
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_line_ending() {
assert_eq!(LineEnding::Unix.as_str(), "\n");
assert_eq!(LineEnding::Windows.as_str(), "\r\n");
assert_eq!(LineEnding::Mac.as_str(), "\r");
}
#[test]
fn test_common_class_ids() {
assert_eq!(class_ids::OBJECT, 0);
assert_eq!(class_ids::GAME_OBJECT, 1);
assert_eq!(class_ids::COMPONENT, 2);
assert_eq!(class_ids::TRANSFORM, 4);
assert_eq!(class_ids::BEHAVIOUR, 8);
assert_eq!(class_ids::SPRITE_RENDERER, 212);
assert_eq!(class_ids::SPRITE, 213);
assert_eq!(
GLOBAL_CLASS_ID_MAP.get_class_name(class_ids::SPRITE),
Some("Sprite".to_string())
);
assert_eq!(
GLOBAL_CLASS_ID_MAP.get_class_name(class_ids::SPRITE_RENDERER),
Some("SpriteRenderer".to_string())
);
assert_eq!(GLOBAL_CLASS_ID_MAP.get_class_name(256), None);
assert_eq!(GLOBAL_CLASS_ID_MAP.get_class_name(512), None);
assert_eq!(GLOBAL_CLASS_ID_MAP.get_class_name(768), None);
}
#[test]
fn test_class_id_map() {
let map = UnityClassIdMap::new();
let result = map.get_or_create("1", "GameObject");
assert_eq!(result, "GameObject");
let result2 = map.get_or_create("1", "GameObject");
assert_eq!(result2, "GameObject");
}
}