internal void LoadYAML() { if (!File.Exists(assetPath)) { state = FR2_AssetState.MISSING; return; } var text = string.Empty; try { text = File.ReadAllText(assetPath); } #if FR2_DEBUG catch (Exception e) { Debug.LogWarning("Guess Asset Type error :: " + e + "\n" + assetPath); #else catch { #endif state = FR2_AssetState.MISSING; return; } // PERFORMANCE HOG! var matches = Regex.Matches(text, @"\bguid: [a-f0-9]{32}\b"); foreach (Match match in matches) { var refGUID = match.Value.Replace("guid: ", string.Empty); if (UseGUIDs.Contains(refGUID)) { continue; } AddUseGUID(refGUID); } //var idx = text.IndexOf("guid: "); //var counter=0; //while (idx != -1) //{ // var guid = text.Substring(idx + 6, 32); // if (UseGUIDs.Contains(guid)) continue; // AddUseGUID(guid); // idx += 39; // if (idx > text.Length-40) break; // //Debug.Log(assetName + ":" + guid); // idx = text.IndexOf("guid: ", idx + 39); // if (counter++ > 100) break; //} //if (counter > 100){ // Debug.LogWarning("Never finish on " + assetName); //} }
internal void LoadFolder() { if (!Directory.Exists(assetPath)) { state = FR2_AssetState.MISSING; return; } try { var files = Directory.GetFiles(assetPath); var dirs = Directory.GetDirectories(assetPath); foreach (var f in files) { if (f.EndsWith(".meta", StringComparison.Ordinal)) { continue; } var fguid = AssetDatabase.AssetPathToGUID(f); if (string.IsNullOrEmpty(fguid)) { continue; } AddUseGUID(fguid, true); } foreach (var d in dirs) { var fguid = AssetDatabase.AssetPathToGUID(d); if (string.IsNullOrEmpty(fguid)) { continue; } AddUseGUID(fguid, true); } } #if FR2_DEBUG catch (Exception e) { Debug.LogWarning("LoadFolder() error :: " + e + "\n" + assetPath); #else catch { #endif state = FR2_AssetState.MISSING; } //Debug.Log("Load Folder :: " + assetName + ":" + type + ":" + UseGUIDs.Count); }
internal void LoadAssetInfo() { assetPath = AssetDatabase.GUIDToAssetPath(guid); if (string.IsNullOrEmpty(assetPath)) { state = FR2_AssetState.MISSING; return; } if (!assetPath.StartsWith("Assets/", StringComparison.Ordinal)) { #if FR2_DEBUG Debug.LogWarning("Something wrong ! Should never be here !\n" + assetPath + "\n" + guid); #endif return; } var info = new FileInfo(assetPath); assetName = info.Name; extension = info.Extension.ToLower(); assetFolder = assetPath.Substring(7, Mathf.Max(0, assetPath.Length - assetName.Length - 7)); // 7 = "Assets/".Length loaded = stamp == FR2_Unity.Epoch(info.LastWriteTime); if (Directory.Exists(info.FullName)) { type = FR2_AssetType.FOLDER; } else if (File.Exists(info.FullName)) { if (type == FR2_AssetType.UNKNOWN) { GuessAssetType(); } fileSize = info.Length; inEditor = assetPath.Contains("/Editor/"); inResources = assetPath.Contains("/Resources/"); inStreamingAsset = assetPath.Contains("/StreamingAsset/"); inPlugins = assetPath.StartsWith("Assets/Plugins/", StringComparison.Ordinal); fileInfoHash = info.Length + info.Extension; } else { state = FR2_AssetState.MISSING; } }
internal void LoadContent(bool force) { if (state == FR2_AssetState.NEW) { LoadAssetInfo(); } if (IsMissing || type == FR2_AssetType.NON_READABLE) { return; } if (type == FR2_AssetType.DLL) { #if FR2_DEBUG Debug.LogWarning("Parsing DLL not yet supportted "); #endif return; } if (loaded && !force) { return; } // Check for file / folder changes & validate if file / folder exist var newStamp = stamp; var exist = true; if (IsFolder) { var info = new DirectoryInfo(assetPath); exist = info.Exists; newStamp = FR2_Unity.Epoch(info.LastWriteTime); } else { var info = new FileInfo(assetPath); exist = info.Exists; newStamp = FR2_Unity.Epoch(info.LastWriteTime); } if (!exist) { state = FR2_AssetState.MISSING; return; } loaded = true; if (newStamp == stamp && !force) { #if FR2_DEBUG Debug.Log("Unchanged : " + stamp + ":" + assetName + ":" + type); #endif return; // nothing changed } stamp = newStamp; UseGUIDs.Clear(); if (IsFolder) { LoadFolder(); } else if (IsReferencable) { LoadYAML(); } else if (IsBinaryAsset) { LoadBinaryAsset(); } else if (IsScript) { LoadScript(); } }
// --------------------------------- APIs ------------------------------ internal void GuessAssetType() { if (SCRIPT_EXTENSIONS.Contains(extension)) { type = FR2_AssetType.SCRIPT; } else if (REFERENCABLE_EXTENSIONS.Contains(extension)) { var isUnity = extension == ".unity"; type = isUnity ? FR2_AssetType.SCENE : FR2_AssetType.REFERENCABLE; if (extension == ".asset" || isUnity) { var buffer = new byte[5]; try { var stream = File.OpenRead(assetPath); stream.Read(buffer, 0, 5); stream.Close(); } #if FR2_DEBUG catch (Exception e) { Debug.LogWarning("Guess Asset Type error :: " + e + "\n" + assetPath); #else catch { #endif state = FR2_AssetState.MISSING; return; } var str = string.Empty; foreach (var t in buffer) { str += (char)t; } if (str != "%YAML") { type = FR2_AssetType.BINARY_ASSET; //var assetData = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object)); //type = assetData is TerrainData ? FR2_AssetType.TERRAIN : FR2_AssetType.BINARY_ASSET; //assetData = null; //FR2_Unity.UnloadUnusedAssets(); } } } else if (extension == ".fbx") { type = FR2_AssetType.MODEL; } else if (extension == ".dll") { type = FR2_AssetType.DLL; } else { type = FR2_AssetType.NON_READABLE; } }
// ----------------------------- REPLACE GUIDS --------------------------------------- internal bool ReplaceReference(string fromGUID, string toGUID) { if (IsMissing) { return(false); } if (IsReferencable) { var text = string.Empty; if (!File.Exists(assetPath)) { state = FR2_AssetState.MISSING; return(false); } try { text = File.ReadAllText(assetPath).Replace("\r", "\n"); File.WriteAllText(assetPath, text.Replace(fromGUID, toGUID)); return(true); } catch (Exception e) { state = FR2_AssetState.MISSING; //#if FR2_DEBUG Debug.LogWarning("Replace Reference error :: " + e + "\n" + assetPath); //#endif } return(false); } if (type == FR2_AssetType.TERRAIN) { var fromObj = FR2_Unity.LoadAssetWithGUID <Object>(fromGUID); var toObj = FR2_Unity.LoadAssetWithGUID <Object>(toGUID); var found = 0; var terrain = AssetDatabase.LoadAssetAtPath(assetPath, typeof(Object)) as TerrainData; if (fromObj is Texture2D) { var arr = terrain.detailPrototypes; for (var i = 0; i < arr.Length; i++) { if (arr[i].prototypeTexture == (Texture2D)fromObj) { found++; arr[i].prototypeTexture = (Texture2D)toObj; } } terrain.detailPrototypes = arr; var arr3 = terrain.splatPrototypes; for (var i = 0; i < arr3.Length; i++) { if (arr3[i].texture == (Texture2D)fromObj) { found++; arr3[i].texture = (Texture2D)toObj; } if (arr3[i].normalMap == (Texture2D)fromObj) { found++; arr3[i].normalMap = (Texture2D)toObj; } } terrain.splatPrototypes = arr3; } if (fromObj is GameObject) { var arr2 = terrain.treePrototypes; for (var i = 0; i < arr2.Length; i++) { if (arr2[i].prefab == (GameObject)fromObj) { found++; arr2[i].prefab = (GameObject)toObj; } } terrain.treePrototypes = arr2; } EditorUtility.SetDirty(terrain); AssetDatabase.SaveAssets(); fromObj = null; toObj = null; terrain = null; FR2_Unity.UnloadUnusedAssets(); return(found > 0); } Debug.LogWarning("Something wrong, should never be here - Ignored <" + assetPath + "> : not a readable type, can not replace ! " + type); return(false); }
internal void LoadScript() { ScriptSymbols.Clear(); ScriptTokens.Clear(); var text = string.Empty; if (!File.Exists(assetPath)) { state = FR2_AssetState.MISSING; return; } try { text = File.ReadAllText(assetPath); } #if FR2_DEBUG catch (Exception e) { Debug.LogWarning("LoadScript() error :: " + e + "\n" + assetPath); #else catch { #endif state = FR2_AssetState.MISSING; return; } var idx = -1; var l = text.Length; int matchIdx; int matchCount; //bool isSymbol = false; //Debug.Log("loading ... " + assetName); //string lastKeyword = null; //string lastWord = null; var currentScope = new List <string>(); var braceLevel = 0; var stMap = new Dictionary <string, string>(); while (++idx < l) { var c = text[idx]; // Skip comments if (c == '/' && idx < l - 1) { var c1 = text[idx + 1]; if (c1 == '/') { //line comment idx++; while (++idx < l) { c1 = text[idx]; if (c1 == '\r' || c1 == '\n') { break; } } } else if (c1 == '*') { //block comment idx++; while (++idx < l) { c1 = text[idx]; if (c1 != '*' || idx == l - 1) { continue; } c1 = text[idx + 1]; if (c1 == '/') { break; } } } } // Skip strings if (c == '"' && idx < l - 2) { //var fromIdx = idx; while (++idx < l) { var c1 = text[idx]; if (c1 == '"' && text[idx - 1] != '\\') { break; } } //Debug.Log("Skip string \n" + text.Substring(fromIdx, idx-fromIdx)); continue; } if (c == '{') { //if (braceLevel == currentScope.Count && lastWord != null && (lastKeyword == "class" || lastKeyword == "namespace")) { // currentScope.Add(lastKeyword); // lastWord = null; //} braceLevel++; #if FR2_DEBUG_BRACE_LEVEL Debug.Log("------->" + braceLevel + "\n" + text.Substring(idx, Mathf.Min(l - idx, 20))); // #endif } else if (c == '}') { #if FR2_DEBUG_BRACE_LEVEL Debug.Log("<--------" + braceLevel + ":" + currentScope[currentScope.Count - 1] + ":" + "\n" + text.Substring(idx, Mathf.Min(l - idx, 20))); // #endif if ((currentScope.Count > 0) && (braceLevel == currentScope.Count)) { #if FR2_DEBUG_BRACE_LEVEL Debug.Log("out scope : " + currentScope[currentScope.Count - 1]); #endif currentScope.RemoveAt(currentScope.Count - 1); } braceLevel--; } if (!char.IsLetter(c) && c != '_') { continue; } matchIdx = idx; matchCount = 1; while (++idx < l && char.IsLetterOrDigit(c = text[idx]) || c == '_') { matchCount++; } if (matchIdx > 0 && text[matchIdx - 1] == '.') { continue; //skip function / method names } if (text[matchIdx] == '_') { //Debug.Log("Skipping name " + text.Substring(matchIdx, matchCount)); continue; // skip names starts with _ } var word = text.Substring(matchIdx, matchCount); //skip using and var if ((word == "using") && char.IsWhiteSpace(text[matchIdx + matchCount])) { while (idx++ < l - 2) { c = text[idx]; if (c == '\n' || c == '\r') { break; } } //Debug.Log("skip using ... " + text.Substring(matchIdx, idx-matchIdx)); //isSymbol = false; continue; } if (word == "var" && char.IsWhiteSpace(text[matchIdx + matchCount])) { while (idx++ < l - 2) { c = text[idx]; if (c == ';' || c == '=' || char.IsLetterOrDigit(c)) { break; } } //Debug.Log("skip var ... " + text.Substring(matchIdx, idx-matchIdx)); //isSymbol = false; } if (SCRIPT_KEYWORDS.Contains(word)) { var isSymbol = SCRIPT_SYMBOL.Contains(word); var isScope = word == "namespace" || word == "class"; var hasBrace = false; if (isSymbol || isScope) { var fromIdx = idx; var hasChar = false; while (idx++ < l - 2) { c = text[idx]; if (c == '{' || c == ':' || c == '<' || (hasChar && char.IsWhiteSpace(c))) { break; } if (!hasChar) { hasChar = char.IsLetter(c) || c == '_'; } } while (char.IsWhiteSpace(c)) { //fast forward to first non-whitespace character idx++; c = text[idx]; } hasBrace = c == '{'; var nextWord = text.Substring(fromIdx, idx - fromIdx).Trim(); if (word == "delegate") { fromIdx = idx; while (idx++ < l - 2) { c = text[idx]; if (!char.IsLetterOrDigit(c) && c != '_') { break; } } nextWord = text.Substring(fromIdx, idx - fromIdx).Trim(); //#if FR2_DEBUG_SYMBOL // Debug.Log("Delegate detected ! " + nextWord); //#endif } if (isSymbol) { string symb; var ns = currentScope.Count > 0 ? string.Join(".", currentScope.ToArray()) + "." : string.Empty; if (stMap.TryGetValue(nextWord, out symb)) { if (symb == "@token") { stMap[nextWord] = ns + nextWord; } else { #if FR2_DEV Debug.LogWarning("Not yet support same symbol name definitions <" + ns + nextWord + "> : " + symb); #endif } } else { stMap.Add(nextWord, ns + nextWord); } //#if FR2_DEBUG_SYMBOL // Debug.LogWarning(word + " : " + (ns + nextWord)); //#endif } if (isScope) { currentScope.Add(nextWord); //#if FR2_DEBUG_SYMBOL // Debug.LogWarning("Add scope : " + nextWord + ":" + braceLevel); //#endif } if (c == ':' && isSymbol) { //extends fromIdx = idx + 1; while (idx++ < l - 2) { c = text[idx]; if (c == '{') { break; } } hasBrace = true; nextWord = text.Substring(fromIdx, idx - fromIdx).Trim(); if (!stMap.ContainsKey(nextWord)) { stMap.Add(nextWord, "@token"); } } if (hasBrace) { braceLevel++; #if FR2_DEBUG_BRACE_LEVEL Debug.Log("------->" + braceLevel + "\n" + text.Substring(idx, Mathf.Min(l - idx, 20))); // #endif } } continue; } if (matchCount < 2) { //Debug.Log("Skipping name " + text.Substring(matchIdx, matchCount)); continue; // skip short names } if (char.ToLower(text[matchIdx]) == text[matchIdx]) { //Debug.Log("Skipping name " + text.Substring(matchIdx, matchCount)); continue; //starts with lowercase character } //if (isSymbol){ // if (!ScriptSymbols.Contains(word)){ // //Debug.Log("Symbol --------- " + word); // ScriptSymbols.Add(word); // if (ScriptTokens.Contains(word)) ScriptTokens.Remove(word); // } //} else if (!stMap.ContainsKey(word)) { var isFuncCall = idx < l - 2 && text[idx + 1] == '('; if (isFuncCall) { continue; //skip funtion calls } stMap.Add(word, "@token"); } //isSymbol = false; } foreach (var item in stMap) { if (item.Value == "@token") { ScriptTokens.Add(item.Key); #if FR2_DEBUG_SYMBOL Debug.Log("Add Token : " + item.Key); #endif } else { ScriptSymbols.Add(item.Value); #if FR2_DEBUG_SYMBOL Debug.Log("Add Symbol : " + item.Value); #endif } } }