private ResourceHandle *GetResourceHandler(bool isSync, ResourceManager *resourceManager, ResourceCategory *categoryId,
                                               ResourceType *resourceType, int *resourceHash, byte *path, void *unk, bool isUnk)
    {
        if (!Utf8GamePath.FromPointer(path, out var gamePath))
        {
            PluginLog.Error("Could not create GamePath from resource path.");
            return(CallOriginalHandler(isSync, resourceManager, categoryId, resourceType, resourceHash, path, unk, isUnk));
        }

        CompareHash(gamePath.Path.Crc32, *resourceHash, gamePath);

        ResourceRequested?.Invoke(gamePath, isSync);

        // If no replacements are being made, we still want to be able to trigger the event.
        var(resolvedPath, data) = ResolvePath(gamePath, *categoryId, *resourceType, *resourceHash);
        PathResolved?.Invoke(gamePath, resolvedPath, data);
        if (resolvedPath == null)
        {
            var retUnmodified = CallOriginalHandler(isSync, resourceManager, categoryId, resourceType, resourceHash, path, unk, isUnk);
            ResourceLoaded?.Invoke((Structs.ResourceHandle *)retUnmodified, gamePath, null, data);
            return(retUnmodified);
        }

        // Replace the hash and path with the correct one for the replacement.
        *resourceHash = resolvedPath.Value.InternalName.Crc32;
        path = resolvedPath.Value.InternalName.Path;
        var retModified = CallOriginalHandler(isSync, resourceManager, categoryId, resourceType, resourceHash, path, unk, isUnk);

        ResourceLoaded?.Invoke((Structs.ResourceHandle *)retModified, gamePath, resolvedPath.Value, data);
        return(retModified);
    }
Example #2
0
 /// <summary>
 /// Reserves the specified request. Removes it from availability, but not from the pool. This is typically an intermediate state held during resource negotiation.
 /// </summary>
 /// <param name="request">The request.</param>
 /// <returns><c>true</c> if the resource was successfully reserved, <c>false</c> otherwise.</returns>
 public bool Reserve(IResourceRequest request)
 {
     ResourceRequested?.Invoke(request, this);
     RequestEvent?.Invoke(request, this);
     lock (this) {
         if (AttemptExecution(request))
         {
             ReservedEvent?.Invoke(request, this);
             ResourceReserved?.Invoke(request, this);
             return(true);
         }
         return(false);
     }
 }
Example #3
0
 /// <summary>
 /// Acquires the specified request. Removes it from availability and from the resource pool.
 /// </summary>
 /// <param name="request">The request.</param>
 /// <returns><c>true</c> if if the resource was successfully acquired, <c>false</c> otherwise.</returns>
 public bool Acquire(IResourceRequest request)
 {
     ResourceRequested?.Invoke(request, this);
     RequestEvent?.Invoke(request, this);
     lock (this) {
         if (AttemptExecution(request))
         {
             AcquiredEvent?.Invoke(request, this);
             ResourceAcquired?.Invoke(request, this);
             return(true);
         }
         else
         {
             return(false);
         }
     }
 }
Example #4
0
        /// <summary>
        /// Determines and reserves the 'best' resource in the pool for the specified resource request. The
        /// determination is based on the access regulator agreeing that the requestor may request it, and the
        /// scoring algorithm in the resourceRequest providing the best score for the resource.
        /// </summary>
        /// <param name="resourceRequest">The resource request that contains the description of the resource
        /// desired, and with the algorithm to apparaise the 'goodness' of each resource.</param>
        /// <returns>true if a resource was successfully reserved.</returns>
        protected virtual bool ReserveBestResource(IResourceRequest resourceRequest)
        {
            if (resourceRequest.Status == RequestStatus.Reserved)
            {
                return(true);
            }

            ResourceRequested?.Invoke(resourceRequest, null);

            // If the resource request provides a selection strategy, we will use it.
            // otherwise, we will cycle through resources, executing the scoring strategy.
            if (resourceRequest.ResourceSelectionStrategy != null)
            {
                return(resourceRequest.ResourceSelectionStrategy(m_resources) != null);
            }

            double highestCapacity = double.MinValue;

            double    bestScore    = double.MinValue;
            IResource bestResource = null;

            foreach (IResource resource in m_resources)
            {
                if (m_accessRegulator == null || m_accessRegulator.CanAcquire(resource, resourceRequest.Key))
                {
                    if (resource.Capacity > highestCapacity)
                    {
                        highestCapacity = resource.Capacity;
                    }
                    lock ( resource ) {
                        if ((resource.Available + resource.PermissibleOverbook) < resourceRequest.QuantityDesired)
                        {
                            continue;
                        }
                        double thisScore = resourceRequest.GetScore(resource);
                        if (thisScore > bestScore)
                        {
                            bestResource?.Unreserve(resourceRequest);
                            if (resource.Reserve(resourceRequest))
                            {
                                bestScore    = thisScore;
                                bestResource = resource;
                                // ReSharper disable once CompareOfFloatsByEqualityOperator (Explicitly set to this.)
                                if (bestScore == Double.MaxValue)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }

//			if ( ( bestResource == null ) && highestCapacity < resourceRequest.QuantityDesired ) {
//				throw new ResourcePoolInsufficientException(this,resourceRequest);
//			}
            if (bestResource != null)
            {
                resourceRequest.ResourceObtainedFrom = this;
                _Debug.Assert(resourceRequest.Status == RequestStatus.Free);
                resourceRequest.Status = RequestStatus.Reserved;
                return(true);
            }
            else
            {
//				// Let's see if we can *ever* satisfy the request in this Resource Request...
//				foreach ( IResource resource in m_resources ) {
//					if ( resourceRequest.GetScore(resource) > double.MinValue ) return false;
//				}
//				throw new ApplicationException("Resource manager " + Name + " cannot satisfy resource request " + resourceRequest.ToString());
                return(false);
            }
        }