// Invoked when a load requeset has failed to download the model data it needs // Requests are retried RETRY_LIMIT times if they fail more than that the request is abandoned (error is logged) // When this happens if any dependent cubes want the resource that failed one request is re-queued to try again (under that requests Retry quota) private void FailGetGeometryBufferRequest(LoadCubeRequest loadRequest, string modelPath) { CheckIfBackgroundThread(); loadRequest.Failures++; lock (_geometryBufferCache) { // Remove the 'in progress' marker from the cache _geometryBufferCache.Remove(modelPath); } if (RETRY_LIMIT > loadRequest.Failures) { Debug.LogError("Retry limit hit for: " + modelPath); Debug.LogError("Cube load failed for " + loadRequest); // Let another depenent cube try lock (_dependentCubes) { LinkedList <LoadCubeRequest> dependentRequests; if (_dependentCubes.TryGetValue(modelPath, out dependentRequests)) { var request = dependentRequests.Last.Value; dependentRequests.RemoveLast(); _loadGeometryBufferQueue.ConcurrentEnqueue(request).Wait(); } } } else { // Queue for retry _loadGeometryBufferQueue.ConcurrentEnqueue(loadRequest).Wait(); } }
private IEnumerator GetModelForRequest(LoadCubeRequest loadRequest) { //var modelPath = loadRequest.Query.GetModelPath(loadRequest.LodIndex, loadRequest.X, loadRequest.Y, loadRequest.Z); var modelPath = pyriteQuery.GetModelPath(loadRequest.LodIndex, loadRequest.X, loadRequest.Y, loadRequest.Z); while (!Monitor.TryEnter(_eboCache)) { yield return(null); } // If the geometry data is being loaded or this is the first request to load it add the request the dependency list if (!_eboCache.ContainsKey(modelPath) || _eboCache[modelPath] == null) { yield return(StartCoroutine(AddDependentRequest(loadRequest, modelPath))); if (!_eboCache.ContainsKey(modelPath)) { // Model data was not present in cache nor has any request started constructing it //EboCacheMisses++; _eboCache[modelPath] = null; if (UseWwwForEbo) { var cachePath = CacheWebRequest.GetCacheFilePath(modelPath); WWW modelWww; if (CacheWebRequest.IsItemInCache(cachePath)) { //FileCacheHits++; modelWww = new WWW("file:///" + cachePath); yield return(modelWww); } else { //FileCacheMisses++; modelWww = new WWW(modelPath); yield return(modelWww); CacheWebRequest.AddToCache(cachePath, modelWww.bytes); } GeometryBuffer buffer = new GeometryBuffer(_geometryBufferAltitudeTransform, true) { Buffer = modelWww.bytes }; buffer.Process(); _eboCache[modelPath] = buffer; yield return(StartCoroutine(SucceedGetGeometryBufferRequest(modelPath, buffer))); } else { CacheWebRequest.GetBytes(modelPath, modelResponse => { lock (_eboCache) { if (modelResponse.Status == CacheWebRequest.CacheWebResponseStatus.Error) { Debug.LogError("Error getting model [" + modelPath + "] " + modelResponse.ErrorMessage); FailGetGeometryBufferRequest(loadRequest, modelPath); } else if (modelResponse.Status == CacheWebRequest.CacheWebResponseStatus.Cancelled) { _eboCache.Remove(modelPath); } else { if (modelResponse.IsCacheHit) { //FileCacheHits++; } else { //FileCacheMisses++; } GeometryBuffer buffer = new GeometryBuffer(_geometryBufferAltitudeTransform, true) { Buffer = modelResponse.Content }; buffer.Process(); _eboCache[modelPath] = buffer; SucceedGetGeometryBufferRequest(modelPath, buffer).Wait(); } } }, DependentRequestsExistBlocking); } } } else // The model data was in the cache { // Model was constructed move request to next step //EboCacheHits++; loadRequest.GeometryBuffer = _eboCache[modelPath]; MoveRequestForward(loadRequest); } Monitor.Exit(_eboCache); }