예제 #1
0
        private void HandleRequest(Guid assetId, AssetRequest.AssetRequestHandler handler, AssetRequest.AssetErrorHandler errHandler)
        {
            var reader = ConfigSingleton.ChattelReader;

            if (reader == null)
            {
                // There's no Chattel. Fail.
                errHandler(new AssetError {
                    Error   = AssetErrorType.ConfigIncorrect,
                    Message = "Chattel was null!",
                });
                return;
            }

            reader.GetAssetAsync(assetId, asset => {
                if (asset == null)
                {
                    errHandler(new AssetError {
                        Error   = AssetErrorType.AssetIdUnknown,
                        Message = $"Could not find any asset with ID {assetId}",
                    });
                    return;
                }

                if (!ConfigSingleton.ValidTypes.Contains(asset.Type))
                {
                    errHandler(new AssetError {
                        Error = AssetErrorType.AssetTypeWrong,
                    });
                    return;
                }

                handler(asset);
            });
        }
예제 #2
0
        public void RequestMeshAssetOnCap(Guid capId, Guid assetId, AssetRequest.AssetRequestHandler handler, AssetRequest.AssetErrorHandler errHandler)
        {
            handler    = handler ?? throw new ArgumentNullException(nameof(handler));
            errHandler = errHandler ?? throw new ArgumentNullException(nameof(errHandler));

            if (_negativeCache != null)
            {
                _negativeCacheLock.EnterReadLock();
                var negCacheContainsId = false;
                try {
                    negCacheContainsId = _negativeCache.Contains(assetId.ToString("N"));
                }
                finally {
                    _negativeCacheLock.ExitReadLock();
                }

                if (negCacheContainsId)
                {
                    errHandler(new AssetError {
                        Error = AssetErrorType.AssetTypeWrong,
                    });
                    return;
                }
            }

            if (_caps.TryGetValue(capId, out Capability cap))
            {
                cap.RequestAsset(
                    assetId,
                    (asset) => {
                    if (!ConfigSingleton.ValidTypes.Any(type => type == asset.Type))
                    {
                        if (_negativeCache != null)
                        {
                            _negativeCacheLock.EnterWriteLock();
                            try {
                                _negativeCache.Set(new System.Runtime.Caching.CacheItem(assetId.ToString("N"), 0), _negativeCachePolicy);
                            }
                            finally {
                                _negativeCacheLock.ExitWriteLock();
                            }
                        }

                        errHandler(new AssetError {
                            Error = AssetErrorType.AssetTypeWrong,
                        });
                    }

                    if (asset.Type == 49)
                    {
                        handler(asset);
                    }
                    else
                    {
                        errHandler(new AssetError {
                            Error = AssetErrorType.AssetTypeWrong,
                        });
                    }
                },
                    errHandler
                    );

                return;
            }

            errHandler(new AssetError {
                Error = AssetErrorType.CapabilityIdUnknown,
            });
        }
예제 #3
0
        public void RequestAsset(Guid assetId, AssetRequest.AssetRequestHandler handler, AssetRequest.AssetErrorHandler errHandler)
        {
            if (!IsActive)               // Paused
            {
                AssetRequest requestToProcess = null;
                var          gotLock          = false;
                try {                 // Skiplock: Only locking because of possible shutdown action.
                    Monitor.TryEnter(_requests, ref gotLock);

                    if (gotLock)
                    {
                        _requests.Enqueue(new AssetRequest(assetId, handler, errHandler));

                        if (_requests.Count > MAX_QUEUED_REQUESTS)
                        {
                            _requests.TryDequeue(out requestToProcess);
                        }
                    }
                }
                finally {
                    if (gotLock)
                    {
                        Monitor.Exit(_requests);
                    }
                }

                var errors = new Queue <Exception>();                // Have to make sure both operations below happen, even if they throw.

                if (!gotLock)
                {
                    // It seems that this cap cannot queue the request. Probably shutting down. Tell the client no such luck.
                    try {
                        errHandler(new AssetError {
                            Error = AssetErrorType.QueueFilled,
                        });
                    }
                    catch (Exception e) {
                        errors.Enqueue(e);
                    }
                }

                try {
                    requestToProcess?.Respond(new AssetError {
                        Error = AssetErrorType.QueueFilled,
                    });
                }
                catch (Exception e) {
                    errors.Enqueue(e);
                }

                if (errors.Count > 0)
                {
                    throw new AggregateException(errors);
                }

                return;
            }

            // Not paused, query Chattel.
            HandleRequest(assetId, handler, errHandler);
        }