public static void LatestConnectionRecord(ref string record) { var fp = new FilePersistence(Application.persistentDataPath); if (fp.IsExist("connectionRecord", "latestIp")) { record = fp.Load("connectionRecord", "latestIp"); return; } record = ""; }
private IEnumerator Load <T>(string url, string pathWithoutHash, string hash, string storePath, Func <byte[], T> bytesToTConverter, Action <T> onLoaded, Action <int, string> onLoadFailed, Dictionary <string, string> requestHeader = null, double timeout = BackyardSettings.HTTP_TIMEOUT_SEC) where T : UnityEngine.Object { // ファイルパス、ファイル名を生成する var targetFolderNameAndHash = GenerateFolderAndFilePath(pathWithoutHash, hash, storePath); var targetFolderName = targetFolderNameAndHash.url; var targetFileName = targetFolderNameAndHash.url + "_" + targetFolderNameAndHash.hash; // フォルダ、ファイルがあるかどうかチェックする var folderPath = Path.Combine(storePath, targetFolderName); var existFolderPaths = filePersist.FileNamesInDomain(folderPath); var fileUniquePath = Path.Combine(folderPath, targetFileName); // キャッシュに対象が存在するかどうか if (pathObjectCache.ContainsKey(fileUniquePath)) { var cached = pathObjectCache[fileUniquePath] as T; onLoaded(cached); yield break; } // もしすでにロード中だったら待機する if (cachingLock.ContainsKey(targetFolderName)) { while (cachingLock.ContainsKey(targetFolderName)) { yield return(null); } // 待機完了、オンメモリのキャッシュにあるかどうかチェックし、あれば返す。なければダウンロードに移行する。 UnityEngine.Object _object; if (pathObjectCache.TryGetValue(fileUniquePath, out _object)) { onLoaded(_object as T); yield break; } // ダウンロードに向かう。 } // 処理中のロックをかける lock (writeLock) { cachingLock.Add(targetFolderName, CONST_VALUE); } /* * ロック後に、オンメモリにロードする必要 or DLする必要のチェックを行う。 */ // 既にDL済みのファイルが一つ以上存在していて、hashもヒットした -> ファイルはまだオンメモリにはないので、ここでロードして返す。 if (0 < existFolderPaths.Length && filePersist.IsExist(folderPath, targetFileName)) { // byte列を非同期で読み出す filePersist.Load( folderPath, targetFileName, bytes => { // 読み出し成功したのでオンメモリに載せる。 var tObj = bytesToTConverter(bytes); pathObjectCache[fileUniquePath] = tObj; lock (writeLock) { cachingLock.Remove(targetFolderName); } onLoaded(tObj); }, error => { lock (writeLock) { cachingLock.Remove(targetFolderName); } onLoadFailed(0, error); } ); yield break; } // オンメモリ、ファイルとしても手元に存在しないので、DLして取得を行う。 // 求めるhashに合致しない古いキャッシュファイルがある場合、消す。 foreach (var path in existFolderPaths) { var fileName = Path.GetFileName(path); filePersist.Delete(folderPath, fileName); } // ダウンロードを行う。 using (var request = UnityWebRequest.Get(url)) { filePersist.CreateDirectory(Path.Combine(filePersist.basePath, folderPath)); var fileSavePath = Path.Combine(filePersist.basePath, folderPath, targetFileName); if (requestHeader == null) { requestHeader = new Dictionary <string, string>(); } foreach (var item in requestHeader) { request.SetRequestHeader(item.Key, item.Value); } var handler = new DownloadHandlerFile(fileSavePath); // 失敗時に中途半端なファイルを消す handler.removeFileOnAbort = true; request.downloadHandler = handler; request.timeout = (int)timeout; var p = request.SendWebRequest(); while (!p.isDone) { yield return(null); } var responseCode = (int)request.responseCode; if (request.isNetworkError) { filePersist.Delete(folderPath, targetFileName); lock (writeLock) { cachingLock.Remove(targetFolderName); } onLoadFailed(responseCode, request.error); yield break; } if (request.isHttpError) { filePersist.Delete(folderPath, targetFileName); lock (writeLock) { cachingLock.Remove(targetFolderName); } onLoadFailed(responseCode, request.error); yield break; } } // ダウンロードが成功、保存も完了 // 保存したデータのbyte列を非同期で読み出す filePersist.Load( folderPath, targetFileName, bytes => { // 型に対しての返還式を取り出し、byteからT型を生成する。 var obj = bytesToTConverter(bytes); // キャッシュを行う pathObjectCache[fileUniquePath] = obj; lock (writeLock) { cachingLock.Remove(targetFolderName); } // 取得したT型オブジェクトを返す onLoaded(obj); }, error => { lock (writeLock) { cachingLock.Remove(targetFolderName); } onLoadFailed(0, error); } ); }