示例#1
0
    public void Load(string url, int version, ResolveAction resolve, FallbackAction fallback)
    {
        CorgiMemoryChunk chunk = null;

        if (data.TryGetValue(url, out chunk))
        {
            if (chunk.version >= version)
            {
                queue.Remove(chunk.url);
                queue.AddFirst(chunk.url);
                resolve(chunk.tex);
                return;
            }
            else
            {
                queue.Remove(chunk.url);
                RemoveChunk(chunk);
            }
        }

        ResolveAction newResolve = (tex) =>
        {
            Debug.Log("memory new resolved!");
            resolve(tex);
            Save(tex, url, version);
        };

        fallback(url, version, newResolve);
    }
示例#2
0
    public void Load(string url, int version, ResolveAction resolve, FallbackAction fallback)
    {
        CorgiDiskChunk chunk = null;

        if (map.TryGetValue(url, out chunk))
        {
            if (chunk.version >= version)
            {
                queue.Remove(chunk.url);
                queue.AddFirst(chunk.url);
                StartCoroutine(DownloadLocal(chunk, resolve, fallback));
                return;
            }
            else
            {
                queue.Remove(chunk.url);
                RemoveChunk(chunk);
            }
        }

        ResolveAction newResolve = (tex) =>
        {
            Save(tex, url, version);
            resolve(tex);
        };

        fallback(url, version, newResolve);
    }
示例#3
0
    IEnumerator DownloadLocal(CorgiDiskChunk chunk, ResolveAction resolve, FallbackAction fallback)
    {
        var realPath = Path.Combine(Application.temporaryCachePath, chunk.path);
        var www      = new WWW("file:///" + realPath);

        Debug.Log("path=" + "file:///" + realPath);
        yield return(www);

        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log("[ERR]" + www.error + "\n" + chunk.url + " " + chunk.path);
            RemoveChunk(chunk);
            fallback(chunk.url, chunk.version, (bytes, tex) => {
                Save(bytes, chunk.url, chunk.version);
                resolve(bytes, tex);
            });
        }
        else
        {
            Debug.Log("Disk hit");
            Texture2D tex = new Texture2D(0, 0);
            www.LoadImageIntoTexture(tex);
            resolve(null, tex);
        }
    }
示例#4
0
    public void Load(string url, int version, ResolveAction resolve, FallbackAction fallback)
    {
        CorgiDiskChunk chunk = null;

        if (chunkData.TryGetValue(url, out chunk))
        {
            if (version >= 0 && chunk.version >= version)
            {
                chunkPriorityQueue.Remove(chunk.url);
                chunkPriorityQueue.AddFirst(chunk.url);
                corgi.StartCoroutine(DownloadLocal(chunk, resolve, fallback));
                return;
            }
            else
            {
                chunkPriorityQueue.Remove(chunk.url);
                RemoveChunk(chunk);
            }
        }

        fallback(url, version, (bytes, tex) =>
        {
            Save(bytes, url, version);
            resolve(bytes, tex);
        });
    }
示例#5
0
 public override int ComputeKey()
 {
     unchecked {
         var hashCode = BindingFlags.GetHashCode();
         hashCode = (hashCode * 397) ^ (Name != null ? Name.GetHashCode() : 0);
         hashCode = (hashCode * 397) ^ IsField.GetHashCode();
         hashCode = (hashCode * 397) ^ (FallbackAction != null ? FallbackAction.GetHashCode() : 0);
         hashCode = (hashCode * 397) ^ (GetterFallbackAction != null ? GetterFallbackAction.GetHashCode() : 0);
         hashCode = (hashCode * 397) ^ (SetterFallbackAction != null ? SetterFallbackAction.GetHashCode() : 0);
         hashCode = (hashCode * 397) ^ (InterfaceName != null ? InterfaceName.GetHashCode() : 0);
         hashCode = (hashCode * 397) ^ (FallbackMode != null ? FallbackMode.GetHashCode() : 0);
         return(hashCode);
     }
 }
示例#6
0
 private static async Task ExecuteAsync <TResult>(
     this ActionContext <TResult>[] actionCtxBatch,
     FallbackAction <TResult> fallbackAction)
 {
     try
     {
         await fallbackAction(actionCtxBatch);
     }
     catch (Exception ex)
     {
         foreach (var actionCtx in actionCtxBatch)
         {
             actionCtx.TaskCompletionSource.TrySetException(ex);
         }
     }
 }
示例#7
0
    public void Load(string url, int version, ResolveAction resolve, FallbackAction fallback)
    {
        CorgiMemoryChunk chunk = null;

        if (chunkData.TryGetValue(url, out chunk))
        {
            // 아래 레이어에서 로드중인데 계속 요청이 들어오면 해당 key resolveQueue에 저장했다가 완료시 한꺼번에 호출
            if (chunk == null)
            {
                Debug.Log("fetch pending.. " + url + " v." + version);
                ResolveAction delegates;
                if (resolveQueues.TryGetValue(url, out delegates))
                {
                    delegates += resolve;
                }
                else
                {
                    resolveQueues.Add(url, resolve);
                }

                return;
            }
            else if (version >= 0 && chunk.version >= version)
            {
                chunkPriorityQueue.Remove(chunk.url);
                chunkPriorityQueue.AddFirst(chunk.url);
                resolve(null, chunk.tex);
                return;
            }
            else
            {
                chunkPriorityQueue.Remove(chunk.url);
                RemoveChunk(chunk);
            }
        }

        //아래 레이어에서 로드중인경우 체크용으로 해당 key chunk에 null을 넣어둔다.
        chunkData.Add(url, null);

        fallback(url, version, (bytes, tex) =>
        {
            resolve(bytes, tex);
            OnResolve(url, version, tex);
        });
    }
示例#8
0
    IEnumerator DownloadURL(string url, int version, ResolveAction resolve, FallbackAction fallback)
    {
        var www = new WWW(url);

        yield return(www);

        if (string.IsNullOrEmpty(www.error))
        {
            Debug.Log("Web hit");
            Texture2D tex = new Texture2D(0, 0);
            www.LoadImageIntoTexture(tex);
            resolve(www.bytes, tex);
        }
        else
        {
            Debug.Log("Web Failed!");
            fallback(url, version, resolve);
        }
    }
示例#9
0
        internal static async Task ImplementationAsync <TResult>(
            SemaphoreSlim maxParallelizationSemaphore,
            int[] maxQueueingActionsLimits,
            ConcurrentQueue <ActionContext <TResult> > queuedActions,
            FallbackAction <TResult> fallbackAction)
        {
            do
            {
                if (!maxParallelizationSemaphore.Wait(0))
                {
                    return;
                }

                await Task
                .Run(() => queuedActions.ExecuteAsync(maxQueueingActionsLimits, fallbackAction))
                .ConfigureAwait(false);

                maxParallelizationSemaphore.Release();

                // This extra check is needed to prevent the possible race-condition where an action has
                // been enqueued in an empty queue while the Semaphore is being released, leading to a
                // situation where the last action is stuck in the queue until a new action is enqueued.
            } while (!queuedActions.IsEmpty);
        }
示例#10
0
        private static async Task ExecuteAsync <TResult>(
            this ConcurrentQueue <ActionContext <TResult> > queuedActions,
            int[] maxQueueingActionsLimits,
            FallbackAction <TResult> fallbackAction)
        {
            while (true)
            {
                var actionCtxBatch = default(ActionContext <TResult>[]);
                var actionCtx      = default(ActionContext <TResult>);

                lock (queuedActions)
                {
                    var exceededLimits = maxQueueingActionsLimits.Where(x => x <= queuedActions.Count);
                    if (exceededLimits.Any())
                    {
                        actionCtxBatch = queuedActions.Dequeue(exceededLimits.First());
                    }
                    else if (queuedActions.TryDequeue(out actionCtx))
                    {
                    }
                    else
                    {
                        break;
                    }
                }

                if (actionCtxBatch != null)
                {
                    await actionCtxBatch.ExecuteAsync(fallbackAction);
                }
                else
                {
                    await actionCtx.ExecuteAsync();
                }
            }
        }
示例#11
0
 void _Fallback(FallbackAction _fallback)
 {
     EnsureMainthread();
     _fallback += _fallback;
 }
示例#12
0
        /// <summary>
        /// Builds a bulkhead isolation <see cref="AsyncPolicy{TResult}" />, which limits the maximum concurrency of actions executed through the policy.  Imposing a maximum concurrency limits the potential of governed actions, when faulting, to bring down the system.
        /// <para>When an execution would cause the number of actions executing concurrently through the policy to exceed <paramref name="maxParallelization" /> they will be queued and executed in-order.  When an execution would cause the number of queuing actions to exceed any of the <paramref name="maxQueuingActionsLimits" />, <paramref name="fallbackActionAsync" /> is called with a number of <see cref="ActionContext{TResult}" /> equal to the largest exceeded limit in <paramref name="maxQueuingActionsLimits" />.</para>
        /// </summary>
        /// <param name="maxParallelization">The maximum number of concurrent actions that may be executing through the policy.</param>
        /// <param name="maxQueuingActionsLimits">The maxmimum number of actions that may be queuing, waiting for an execution slot.</param>
        /// <param name="fallbackActionAsync">An action to call asynchronously, if the bulkhead rejects execution due to oversubscription.</param>
        /// <returns>The policy instance.</returns>
        /// <exception cref="System.ArgumentOutOfRangeException">maxParallelization;Value must be greater than zero.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">maxQueuingActionsLimits;Value must be greater than or equal to zero.</exception>
        /// <exception cref="System.ArgumentNullException">fallbackActionAsync</exception>
        public static AsyncFallbackBulkheadPolicy <TResult> Create <TResult>(int maxParallelization, FallbackAction <TResult> fallbackActionAsync, params int[] maxQueuingActionsLimits)
        {
            if (maxParallelization <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(maxParallelization), "Value must be greater than zero.");
            }
            if (maxQueuingActionsLimits.Any(x => x <= 0))
            {
                throw new ArgumentOutOfRangeException(nameof(maxQueuingActionsLimits), "Value must be greater than zero.");
            }
            if (fallbackActionAsync == null)
            {
                throw new ArgumentNullException(nameof(fallbackActionAsync));
            }

            return(new AsyncFallbackBulkheadPolicy <TResult>(
                       maxParallelization,
                       fallbackActionAsync,
                       maxQueuingActionsLimits
                       ));
        }
示例#13
0
 void _Fallback(FallbackAction _fallback)
 {
     fallbackDelegate = _fallback;
 }
示例#14
0
    /*
     * public static void AddCacheLayer(int priority, FallbackAction action)
     * {
     *  instance._AddCacheLayer(priority, action);
     * }
     *
     * void _AddCacheLayer(int priority, FallbackAction action)
     * {
     * }
     */

    public static void Fallback(FallbackAction fallback)
    {
        instance._Fallback(fallback);
    }
示例#15
0
        private void RunCall(IDataContainer obj, string func, object[] parameters, bool isSelf, FallbackAction fallback)
        {
            // This executes in the job thread.

            // Checks if this is still alive.
            if (IsDisposed)
            {
                return;
            }

            // Checks if the function still exists.
            LuaDataContainer dc = obj as LuaDataContainer;

            if (dc == null)
            {
                return;
            }

            IDataProvider lf = dc.GetProvider(func, isSelf);

            if (lf == null)
            {
                return;
            }

            // Calls the function.
            try
            {
                lf.Execute(parameters);
            }
            catch (InvalidOperationException ex)
            {
                // Last chance fallback action, if any.
                if (fallback != null)
                {
                    fallback(ex);
                }
                else if (DefaultFallbackAction != null)
                {
                    DefaultFallbackAction(ex);
                }
                else
                {
                    // No fallback action: let's rethrow this.
                    throw;
                }
            }
            catch (Exception)
            {
                // Other exceptions than InvalidOperationException are
                // immediately rethrown because they are, indeed, unexpected.
                throw;
            }
        }
示例#16
0
 private Action GetJob(IDataContainer obj, string func, object[] parameters, bool isSelf, FallbackAction fallbackAction)
 {
     return(new Action(() => RunCall(obj, func, parameters, isSelf, fallbackAction)));
 }
示例#17
0
 /// <summary>
 /// Executes asynchronously a call to a Lua self-function on the thread this ExecutionQueue is associated with.
 /// </summary>
 /// <remarks>This method returns once the call job is queued.</remarks>
 /// <param name="obj">IDataContainer that contains the self-function.</param>
 /// <param name="func">Field name in <paramref name="obj"/> that corresponds to the function to call.</param>
 /// <param name="fallback">Action that is executed if an exception occurs during the
 /// execution of the job. If this parameter is null, any exception occuring will be
 /// rethrown.</param>
 /// <param name="parameters">Optional parameters to pass to the function. <paramref name="obj"/> is automatically
 /// added as first parameter.</param>
 public void BeginCallSelf(IDataContainer obj, string func, FallbackAction fallback, params object[] parameters)
 {
     // Conforms the parameters and enqueues a job.
     AcceptJob(GetJob(obj, func, ConformParameters(parameters), true, fallback));
 }
示例#18
0
        private void RunCall(IDataContainer obj, string func, object[] parameters, bool isSelf, FallbackAction fallback)
        {
            // This executes in the job thread.

            // Checks if this is still alive. 
            if (IsDisposed)
                return;

            // Checks if the function still exists.
            LuaDataContainer dc = obj as LuaDataContainer;
            if (dc == null)
                return;

            IDataProvider lf = dc.GetProvider(func, isSelf);            

            if (lf == null)
                return;

            // Calls the function.
			try
			{
				lf.Execute(parameters);
			}
			catch (InvalidOperationException ex)
			{
				// Last chance fallback action, if any.
				if (fallback != null)
				{
					fallback(ex);
				}
				else if (DefaultFallbackAction != null)
				{
					DefaultFallbackAction(ex);
				}
				else
				{
					// No fallback action: let's rethrow this.
					throw;
				}
			}
			catch (Exception)
			{
				// Other exceptions than InvalidOperationException are
				// immediately rethrown because they are, indeed, unexpected.
				throw;
			}
        }
示例#19
0
		private Action GetJob(IDataContainer obj, string func, object[] parameters, bool isSelf, FallbackAction fallbackAction)
		{
			return new Action(() => RunCall(obj, func, parameters, isSelf, fallbackAction));
		}
示例#20
0
		/// <summary>
		/// Executes asynchronously a call to a Lua self-function on the thread this ExecutionQueue is associated with.
		/// </summary>
		/// <remarks>This method returns once the call job is queued.</remarks>
		/// <param name="obj">IDataContainer that contains the self-function.</param>
		/// <param name="func">Field name in <paramref name="obj"/> that corresponds to the function to call.</param>
		/// <param name="fallback">Action that is executed if an exception occurs during the
		/// execution of the job. If this parameter is null, any exception occuring will be
		/// rethrown.</param>
		/// <param name="parameters">Optional parameters to pass to the function. <paramref name="obj"/> is automatically
		/// added as first parameter.</param>
		public void BeginCallSelf(IDataContainer obj, string func, FallbackAction fallback, params object[] parameters)
		{
			// Conforms the parameters and enqueues a job.
			AcceptJob(GetJob(obj, func, ConformParameters(parameters), true, fallback));
		}
示例#21
0
        /// <summary>
        /// Builds a bulkhead isolation <see cref="AsyncPolicy{TResult}" />, which limits the maximum concurrency of actions executed through the policy.  Imposing a maximum concurrency limits the potential of governed actions, when faulting, to bring down the system.
        /// <para>When an execution would cause the number of actions executing concurrently through the policy to exceed <paramref name="maxParallelization" /> they will be queued and executed in-order.</para>
        /// </summary>
        /// <param name="maxParallelization">The maximum number of concurrent actions that may be executing through the policy.</param>
        /// <returns>The policy instance.</returns>
        public static AsyncFallbackBulkheadPolicy <TResult> Create <TResult>(int maxParallelization)
        {
            FallbackAction <TResult> doNothingAsync = _ => TaskHelper.EmptyTask;

            return(Create(maxParallelization, doNothingAsync));
        }
示例#22
0
 public void Load(string url, int version, ResolveAction resolve, FallbackAction fallback)
 {
     corgi.StartCoroutine(DownloadURL(url, version, resolve, fallback));
 }