1 module unecht.core.assetDatabase; 2 3 import std.uuid; 4 5 import unecht.core.object; 6 import unecht.core.serialization.serializer; 7 8 /// 9 struct UEAsset 10 { 11 UEObject obj; 12 string path; 13 string metaPath; 14 } 15 16 /// 17 static struct UEAssetDatabase 18 { 19 static UEAsset[] assets; 20 21 static immutable EXT_METAFILE = ".uem"; 22 static immutable ASSETFOLDER = "/assets/"; 23 24 private static string assetPath() { 25 import std.path:dirName; 26 import std.file:thisExePath; 27 28 return dirName(thisExePath()) ~ ASSETFOLDER; 29 } 30 31 /// 32 static void refresh() 33 { 34 refresh(assetPath()); 35 } 36 37 /// 38 static void refresh(string path) 39 { 40 import std.file:DirEntry,dirEntries,SpanMode,exists; 41 import std.path:relativePath; 42 43 if(!exists(path)) 44 return; 45 46 foreach (DirEntry e; dirEntries(path, SpanMode.breadth)) 47 { 48 auto relPath = relativePath(e.name, path); 49 50 if(!containsPath(relPath)) 51 { 52 parseAssetFile(relPath); 53 } 54 } 55 } 56 57 static UUID[] getAllIds() 58 { 59 UUID[] res; 60 res.length = assets.length; 61 foreach(i,asset; assets) 62 res[i] = asset.obj.instanceId; 63 64 return res; 65 } 66 67 /// 68 static bool containsPath(string path) 69 { 70 import std.algorithm; 71 return countUntil!"a.path == b"(assets,path) != -1; 72 } 73 74 /// 75 static void parseAssetFile(string path) 76 { 77 import std.path:extension; 78 79 auto ext = extension(path); 80 81 import unecht.core.logger; 82 log.infof("parse: '%s' (%s)",path, ext); 83 84 //TODO: solve different extension using a dictonary of assetimporters 85 if(ext == ".png") 86 { 87 loadTextureAsset(path); 88 } 89 } 90 91 /// 92 static UEObject getAsset(string path) 93 { 94 foreach(asset; assets) 95 { 96 if(asset.path == path) 97 return asset.obj; 98 } 99 100 return null; 101 } 102 103 /// 104 static string getAssetName(UEObject object) 105 { 106 foreach(asset; assets) 107 { 108 if(asset.obj == object) 109 return asset.path; 110 } 111 112 return ""; 113 } 114 115 /// 116 static void loadTextureAsset(string path) 117 { 118 import std.file:exists; 119 import unecht.core.assets.texture; 120 121 UETexture2D tex; 122 immutable assetFile = assetPath ~ path; 123 immutable metaFilePath = assetFile ~ EXT_METAFILE; 124 125 if(exists(metaFilePath)) 126 { 127 tex = deserializeMetaFile!UETexture2D(metaFilePath); 128 } 129 else 130 { 131 tex = new UETexture2D(); 132 serializeMetaFile(tex, metaFilePath); 133 } 134 135 tex.loadFromFile(assetFile); 136 137 addAsset(tex, path, metaFilePath); 138 } 139 140 static void updateAssetMetafile(UEObject obj) 141 { 142 foreach(asset; assets) 143 { 144 if(asset.obj is obj) 145 { 146 serializeMetaFile(obj, asset.metaPath); 147 } 148 } 149 } 150 151 /// 152 static void addAsset(UEObject obj, string path, string metaPath) 153 { 154 assets ~= UEAsset(obj, path, metaPath); 155 } 156 157 /// 158 private static void serializeMetaFile(UEObject obj, string path) 159 { 160 import std.file; 161 162 UESerializer s; 163 obj.serialize(s); 164 165 auto serializedStr = s.toString(); 166 167 write(path, serializedStr); 168 169 import unecht.core.logger; 170 log.infof("written uem: (%s) -> \n%s",path,serializedStr); 171 } 172 173 /// 174 private static auto deserializeMetaFile(T)(string path) 175 { 176 import std.file; 177 string fileContent = cast(string)read(path); 178 179 import unecht.core.logger; 180 log.infof("uem read: (%s)",path); 181 182 UEDeserializer d = UEDeserializer(fileContent); 183 return d.deserializeFirst!T(); 184 } 185 }