Example #1
0
        private static void DivideNode(BoundingRectangle space, INode <T> input, Node <T> output, ArrayPool <float> pool, Treemap <T> map)
        {
            //Recursion base case
            if (input.Count == 0)
            {
                return;
            }

            var h = pool.Allocate(input.Count);
            var v = pool.Allocate(input.Count);

            //Take the split with the least bad aspect ratio
            if (MeasureSizes(false, space, input, h) < MeasureSizes(true, space, input, v))
            {
                //Free the unused array
                pool.Free(v);

                SplitHorizontal(space, input, output, h, pool, map);
            }
            else
            {
                //Free the unused array
                pool.Free(h);

                SplitVertical(space, input, output, v, pool, map);
            }
        }
Example #2
0
        public void AssertThat_AllocatedArray_IsLargeEnough_WhenRecycling()
        {
            //Allocate a large enough array
            var a = _pool.Allocate(10);

            //Free it
            _pool.Free(a);

            //Allocate again, let's see if we get a large enough array
            Assert.IsTrue(_pool.Allocate(5).Length >= 5);
        }
Example #3
0
            public void CookOverride()
            {
                SmeltTicks++;
                if (SmeltTicks % 2 == 0)
                {
                    TrySmeltItems();
                }
                var burnable = _plugin.FindBurnable(Furnace);

                if (burnable == null)
                {
                    _plugin.StopCooking(Furnace);
                    return;
                }
                ItemModBurnable component = burnable.info.GetComponent <ItemModBurnable>();

                burnable.fuel -= 0.5f * Furnace.cookingTemperature / 200f;
                if (!burnable.HasFlag(global::Item.Flag.OnFire))
                {
                    burnable.SetFlag(global::Item.Flag.OnFire, true);
                    burnable.MarkDirty();
                }
                if (burnable.fuel <= 0f)
                {
                    var array = ArrayPool.Get(2);
                    array[0] = burnable;
                    array[1] = component;
                    ConsumeFuelMethod.Invoke(Furnace, array);
                    ArrayPool.Free(array);
                }
            }
Example #4
0
        private static void ApplySplit(BoundingRectangle space, INode <T> input, Node <T> output, float[] sizes, ArrayPool <float> pool, Treemap <T> map)
        {
            //Create child nodes and add them to the parent
            var index = 0;

            foreach (var child in input)
            {
                output.Add(new Node <T>(map, child.Value, sizes[index++]));
            }

            //Now that we're done with the array, free it
            pool.Free(sizes);

            //Recursively subdivide each child
            for (var i = 0; i < output.Count; i++)
            {
                var iNode = input[i];
                var oNode = output[i];

                //Calculate bounds for this node (the bounds are not in the right place, they are the right *size* which is the only thing we care about here)
                var box = output.SplitVertical
                    ? new BoundingRectangle(new Vector2(0, space.Min.Y), new Vector2(oNode.Length, space.Max.Y))
                    : new BoundingRectangle(new Vector2(space.Min.X, 0), new Vector2(space.Max.X, oNode.Length));

                //Recursion
                DivideNode(box, iNode, oNode, pool, map);
            }
        }
Example #5
0
        /// <summary>
        /// Returns the matrix to the pool
        /// </summary>
        /// <param name="matrices"></param>
        public void Free(params Matrix[] matrices)
        {
            foreach (var mtx in matrices)
            {
                if (mtx.CoreArray == null)
                {
                    continue;
                }

                Pool.Free(mtx.CoreArray);
                mtx.CoreArray = null;
                TotalReturns++;
            }
        }
        protected List <HookMethod> FindHooks(string name, object[] args)
        {
            HookCache hookCache;

            object[]          defaultValue;
            bool              flag;
            List <HookMethod> hookMethod = this.HooksCache.GetHookMethod(name, args, out hookCache);

            if (hookMethod != null)
            {
                return(hookMethod);
            }
            List <HookMethod> hookMethods = new List <HookMethod>();

            if (!this.Hooks.TryGetValue(name, out hookMethod))
            {
                return(hookMethods);
            }
            HookMethod hookMethod1 = null;
            HookMethod hookMethod2 = null;

            foreach (HookMethod hookMethod3 in hookMethod)
            {
                if (!hookMethod3.IsBaseHook)
                {
                    int  num   = (args != null ? (int)args.Length : 0);
                    bool flag1 = false;
                    if (num == (int)hookMethod3.Parameters.Length)
                    {
                        defaultValue = args;
                    }
                    else
                    {
                        defaultValue = ArrayPool.Get((int)hookMethod3.Parameters.Length);
                        flag1        = true;
                        if (num > 0 && defaultValue.Length != 0)
                        {
                            Array.Copy(args, defaultValue, Math.Min(num, (int)defaultValue.Length));
                        }
                        if ((int)defaultValue.Length > num)
                        {
                            for (int i = num; i < (int)defaultValue.Length; i++)
                            {
                                ParameterInfo parameters = hookMethod3.Parameters[i];
                                if (parameters.DefaultValue != null && parameters.DefaultValue != DBNull.Value)
                                {
                                    defaultValue[i] = parameters.DefaultValue;
                                }
                                else if (parameters.ParameterType.IsValueType)
                                {
                                    defaultValue[i] = Activator.CreateInstance(parameters.ParameterType);
                                }
                            }
                        }
                    }
                    if (hookMethod3.HasMatchingSignature(defaultValue, out flag))
                    {
                        if (!flag)
                        {
                            hookMethod2 = hookMethod3;
                        }
                        else
                        {
                            hookMethod1 = hookMethod3;
                            if (hookMethod1 != null)
                            {
                                hookMethods.Add(hookMethod1);
                            }
                            else if (hookMethod2 != null)
                            {
                                hookMethods.Add(hookMethod2);
                            }
                            hookCache.SetupMethods(hookMethods);
                            return(hookMethods);
                        }
                    }
                    if (!flag1)
                    {
                        continue;
                    }
                    ArrayPool.Free(defaultValue);
                }
                else
                {
                    hookMethods.Add(hookMethod3);
                }
            }
            if (hookMethod1 != null)
            {
                hookMethods.Add(hookMethod1);
            }
            else if (hookMethod2 != null)
            {
                hookMethods.Add(hookMethod2);
            }
            hookCache.SetupMethods(hookMethods);
            return(hookMethods);
        }
        protected sealed override object OnCallHook(string name, object[] args)
        {
            object[] defaultValue;
            object   obj  = null;
            bool     flag = false;

            foreach (HookMethod hookMethod in this.FindHooks(name, args))
            {
                int num = (args != null ? (int)args.Length : 0);
                if (num == (int)hookMethod.Parameters.Length)
                {
                    defaultValue = args;
                }
                else
                {
                    defaultValue = ArrayPool.Get((int)hookMethod.Parameters.Length);
                    flag         = true;
                    if (num > 0 && defaultValue.Length != 0)
                    {
                        Array.Copy(args, defaultValue, Math.Min(num, (int)defaultValue.Length));
                    }
                    if ((int)defaultValue.Length > num)
                    {
                        for (int i = num; i < (int)defaultValue.Length; i++)
                        {
                            ParameterInfo parameters = hookMethod.Parameters[i];
                            if (parameters.DefaultValue != null && parameters.DefaultValue != DBNull.Value)
                            {
                                defaultValue[i] = parameters.DefaultValue;
                            }
                            else if (parameters.ParameterType.IsValueType)
                            {
                                defaultValue[i] = Activator.CreateInstance(parameters.ParameterType);
                            }
                        }
                    }
                }
                try
                {
                    obj = this.InvokeMethod(hookMethod, defaultValue);
                }
                catch (TargetInvocationException targetInvocationException1)
                {
                    TargetInvocationException targetInvocationException = targetInvocationException1;
                    if (flag)
                    {
                        ArrayPool.Free(defaultValue);
                    }
                    Exception innerException = targetInvocationException.InnerException;
                    if (innerException == null)
                    {
                        innerException = targetInvocationException;
                    }
                    throw innerException;
                }
                if (num != (int)hookMethod.Parameters.Length)
                {
                    for (int j = 0; j < (int)hookMethod.Parameters.Length; j++)
                    {
                        if (hookMethod.Parameters[j].IsOut || hookMethod.Parameters[j].ParameterType.IsByRef)
                        {
                            args[j] = defaultValue[j];
                        }
                    }
                }
                if (!flag)
                {
                    continue;
                }
                ArrayPool.Free(defaultValue);
            }
            return(obj);
        }
Example #8
0
        /// <summary>
        /// Calls a hook on all plugins of this manager
        /// </summary>
        /// <param name="hook"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public object CallHook(string hook, params object[] args)
        {
            // Locate the sublist
            if (!hookSubscriptions.TryGetValue(hook, out IList <Plugin> plugins))
            {
                return(null);
            }

            if (plugins.Count == 0)
            {
                return(null);
            }

            // Loop each item
            object[] values      = ArrayPool.Get(plugins.Count);
            int      returnCount = 0;
            object   finalValue  = null;
            Plugin   finalPlugin = null;

            for (int i = 0; i < plugins.Count; i++)
            {
                // Call the hook
                object value = plugins[i].CallHook(hook, args);
                if (value != null)
                {
                    values[i]   = value;
                    finalValue  = value;
                    finalPlugin = plugins[i];
                    returnCount++;
                }
            }

            // Is there a return value?
            if (returnCount == 0)
            {
                ArrayPool.Free(values);
                return(null);
            }

            if (returnCount > 1 && finalValue != null)
            {
                // Notify log of hook conflict
                hookConflicts.Clear();
                for (int i = 0; i < plugins.Count; i++)
                {
                    object value = values[i];
                    if (value == null)
                    {
                        continue;
                    }

                    if (value.GetType().IsValueType)
                    {
                        if (!values[i].Equals(finalValue))
                        {
                            hookConflicts.Add($"{plugins[i].Name} - {value} ({value.GetType().Name})");
                        }
                    }
                    else
                    {
                        if (values[i] != finalValue)
                        {
                            hookConflicts.Add($"{plugins[i].Name} - {value} ({value.GetType().Name})");
                        }
                    }
                }
                if (hookConflicts.Count > 0)
                {
                    hookConflicts.Add($"{finalPlugin.Name} ({finalValue} ({finalValue.GetType().Name}))");
                    Logger.Write(LogType.Warning, "Calling hook {0} resulted in a conflict between the following plugins: {1}", hook, string.Join(", ", hookConflicts.ToArray()));
                }
            }
            ArrayPool.Free(values);

            return(finalValue);
        }
        public object CallHook(string hook, params object[] args)
        {
            IList <Plugin> plugins;

            if (!this.hookSubscriptions.TryGetValue(hook, out plugins))
            {
                return(null);
            }
            if (plugins.Count == 0)
            {
                return(null);
            }
            object[] objArray = ArrayPool.Get(plugins.Count);
            int      num      = 0;
            object   obj      = null;
            Plugin   item     = null;

            for (int i = 0; i < plugins.Count; i++)
            {
                object obj1 = plugins[i].CallHook(hook, args);
                if (obj1 != null)
                {
                    objArray[i] = obj1;
                    obj         = obj1;
                    item        = plugins[i];
                    num++;
                }
            }
            if (num == 0)
            {
                ArrayPool.Free(objArray);
                return(null);
            }
            if (num > 1 && obj != null)
            {
                this.hookConflicts.Clear();
                for (int j = 0; j < plugins.Count; j++)
                {
                    object obj2 = objArray[j];
                    if (obj2 != null)
                    {
                        if (obj2.GetType().IsValueType)
                        {
                            if (!objArray[j].Equals(obj))
                            {
                                this.hookConflicts.Add(string.Format("{0} - {1} ({2})", plugins[j].Name, obj2, obj2.GetType().Name));
                            }
                        }
                        else if (objArray[j] != obj)
                        {
                            this.hookConflicts.Add(string.Format("{0} - {1} ({2})", plugins[j].Name, obj2, obj2.GetType().Name));
                        }
                    }
                }
                if (this.hookConflicts.Count > 0)
                {
                    this.hookConflicts.Add(string.Format("{0} ({1} ({2}))", item.Name, obj, obj.GetType().Name));
                    this.Logger.Write(LogType.Warning, "Calling hook {0} resulted in a conflict between the following plugins: {1}", new object[] { hook, string.Join(", ", this.hookConflicts.ToArray()) });
                }
            }
            ArrayPool.Free(objArray);
            return(obj);
        }
Example #10
0
        protected List <HookMethod> FindHooks(string name, object[] args)
        {
            // Get the full name of the hook `name(argument type 1, argument type 2, ..., argument type x)`

            // Check the cache if we already found a match for this hook
            HookCache         cache;
            List <HookMethod> methods = HooksCache.GetHookMethod(name, args, out cache);

            if (methods != null)
            {
                return(methods);
            }
            List <HookMethod> matches = new List <HookMethod>();

            // Get all hook methods that could match, return an empty list if none match
            if (!Hooks.TryGetValue(name, out methods))
            {
                return(matches);
            }

            // Find matching hooks
            HookMethod exactMatch      = null;
            HookMethod overloadedMatch = null;

            foreach (HookMethod h in methods)
            {
                // A base hook should always have a matching signature either directly or through inheritance
                // and should always be called as core functionality depends on it.
                if (h.IsBaseHook)
                {
                    matches.Add(h);
                    continue;
                }

                // Check if this method matches the hook arguments passed if it isn't a base hook
                object[] hookArgs;
                int      received = args?.Length ?? 0;

                bool pooledArray = false;

                if (received != h.Parameters.Length)
                {
                    // The call argument count is different to the declared callback methods argument count
                    hookArgs    = ArrayPool.Get(h.Parameters.Length);
                    pooledArray = true;

                    if (received > 0 && hookArgs.Length > 0)
                    {
                        // Remove any additional arguments which the callback method does not declare
                        Array.Copy(args, hookArgs, Math.Min(received, hookArgs.Length));
                    }

                    if (hookArgs.Length > received)
                    {
                        // Create additional parameters for arguments excluded in this hook call
                        for (int n = received; n < hookArgs.Length; n++)
                        {
                            ParameterInfo parameter = h.Parameters[n];
                            if (parameter.DefaultValue != null && parameter.DefaultValue != DBNull.Value)
                            {
                                // Use the default value that was provided by the method definition
                                hookArgs[n] = parameter.DefaultValue;
                            }
                            else if (parameter.ParameterType.IsValueType)
                            {
                                // Use the default value for value types
                                hookArgs[n] = Activator.CreateInstance(parameter.ParameterType);
                            }
                        }
                    }
                }
                else
                {
                    hookArgs = args;
                }

                bool isExactMatch;
                if (h.HasMatchingSignature(hookArgs, out isExactMatch))
                {
                    if (isExactMatch)
                    {
                        exactMatch = h;
                        break;
                    }

                    // Should we determine the level and call the closest overloaded match? Performance impact?
                    overloadedMatch = h;
                }

                if (pooledArray)
                {
                    ArrayPool.Free(hookArgs);
                }
            }

            if (exactMatch != null)
            {
                matches.Add(exactMatch);
            }
            else
            {
                if (overloadedMatch != null)
                {
                    matches.Add(overloadedMatch);
                }
            }

            cache.SetupMethods(matches);

            return(matches);
        }
Example #11
0
        /// <summary>
        /// Calls the specified hook on this plugin
        /// </summary>
        /// <param name="name"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        protected sealed override object OnCallHook(string name, object[] args)
        {
            object returnvalue = null;
            bool   pooledArray = false;

            // Call all hooks that match the signature
            foreach (HookMethod h in FindHooks(name, args))
            {
                int      received = args?.Length ?? 0;
                object[] hookArgs;

                if (received != h.Parameters.Length)
                {
                    // The call argument count is different to the declared callback methods argument count
                    hookArgs    = ArrayPool.Get(h.Parameters.Length);
                    pooledArray = true;

                    if (received > 0 && hookArgs.Length > 0)
                    {
                        // Remove any additional arguments which the callback method does not declare
                        Array.Copy(args, hookArgs, Math.Min(received, hookArgs.Length));
                    }

                    if (hookArgs.Length > received)
                    {
                        // Create additional parameters for arguments excluded in this hook call
                        for (int n = received; n < hookArgs.Length; n++)
                        {
                            ParameterInfo parameter = h.Parameters[n];
                            if (parameter.DefaultValue != null && parameter.DefaultValue != DBNull.Value)
                            {
                                // Use the default value that was provided by the method definition
                                hookArgs[n] = parameter.DefaultValue;
                            }
                            else if (parameter.ParameterType.IsValueType)
                            {
                                // Use the default value for value types
                                hookArgs[n] = Activator.CreateInstance(parameter.ParameterType);
                            }
                        }
                    }
                }
                else
                {
                    hookArgs = args;
                }

                try
                {
                    returnvalue = InvokeMethod(h, hookArgs);
                }
                catch (TargetInvocationException ex)
                {
                    if (pooledArray)
                    {
                        ArrayPool.Free(hookArgs);
                    }
                    throw ex.InnerException ?? ex;
                }

                if (received != h.Parameters.Length)
                {
                    // A copy of the call arguments was used for this method call
                    for (int n = 0; n < h.Parameters.Length; n++)
                    {
                        // Copy output values for out and by reference arguments back to the calling args
                        if (h.Parameters[n].IsOut || h.Parameters[n].ParameterType.IsByRef)
                        {
                            args[n] = hookArgs[n];
                        }
                    }
                }

                if (pooledArray)
                {
                    ArrayPool.Free(hookArgs);
                }
            }

            return(returnvalue);
        }
 public static void Free <T>(this T[] array)
 {
     ArrayPool <T> .Free(array);
 }
        private async Task QueryCore(
            bool async,
            string queryText,
            PostgresCommand command,
            CancellationToken cancellationToken)
        {
            BindParameter[] parameters     = null;
            var             parameterCount = command.Parameters.Count;

            try
            {
                if (parameterCount > 0)
                {
                    parameters = ArrayPool <BindParameter>
                                 .GetArray(parameterCount);

                    var encoding = ClientState.ClientEncoding;

                    for (var i = 0; i < parameterCount; ++i)
                    {
                        var param = command.Parameters[i].Value;

                        if (param == null)
                        {
                            parameters[i] = new BindParameter {
                                ParameterByteCount = 0,
                                Parameters         = EmptyArray <byte> .Value
                            };

                            continue;
                        }

                        // TODO: This allocation fest is terrible. Make this
                        // write directly to the memorystream instead of having
                        // intermittent buffers for everything.

                        var paramString = param.ToString();

                        var maxBytes = encoding
                                       .GetMaxByteCount(paramString.Length);

                        var paramBuffer = ArrayPool <byte> .GetArray(maxBytes);

                        var actualBytes = encoding.GetBytes(
                            paramString, 0, paramString.Length,
                            paramBuffer, 0);

                        parameters[i] = new BindParameter {
                            ParameterByteCount = actualBytes,
                            Parameters         = paramBuffer
                        };
                    }
                }

                WriteMessage(new ParseMessage {
                    Query = queryText
                });

                WriteMessage(new BindMessage {
                    PreparedStatementName       = "",
                    ResultColumnFormatCodeCount = 1,
                    ParameterCount          = (short)parameterCount,
                    Parameters              = parameters,
                    ResultColumnFormatCodes =
                        QueryResultFormat == PostgresFormatCode.Binary
                            ? _binaryFormatCode
                            : _textFormatCode
                });

                WriteMessage(new DescribeMessage {
                    StatementTargetType = StatementTargetType.Portal
                });

                WriteMessage(new ExecuteMessage {
                });

                WriteMessage(new SyncMessage {
                });

                await FlushWrites(async, cancellationToken)
                .ConfigureAwait(false);
            }
            finally
            {
                if (parameters != null)
                {
                    for (var i = 0; i < parameterCount; ++i)
                    {
                        var param = parameters[i].Parameters;
                        ArrayPool.Free(ref param);
                    }
                }
            }
        }
        private async Task OpenAsync(bool async,
                                     CancellationToken cancellationToken)
        {
            ResetBuffer();

            _state = ConnectionState.Connecting;

            await CreateConnection(cancellationToken)
            .ConfigureAwait(false);

            const int messageCount = 3;
            var       messages     = ArrayPool <KeyValuePair <string, string> >
                                     .GetArray(messageCount);

            try
            {
                messages[0] = new KeyValuePair <string, string>(
                    "user", PostgresConnectionString.Username);
                messages[1] = new KeyValuePair <string, string>(
                    "client_encoding", PostgresConnectionString.Encoding);
                messages[2] = new KeyValuePair <string, string>(
                    "database", PostgresConnectionString.Database);

                WriteMessage(new StartupMessage {
                    MessageCount = messageCount,
                    Messages     = messages
                });
            }
            finally
            {
                ArrayPool.Free(ref messages);
            }

            await FlushWrites(async, cancellationToken)
            .ConfigureAwait(false);

            var authMessageTask = EnsureNextMessage <AuthenticationMessage>(
                async, cancellationToken);

            using (var authMessage = await authMessageTask
                                     .ConfigureAwait(false))
            {
                Authenticate(authMessage);
            }

            await FlushWrites(async, cancellationToken)
            .ConfigureAwait(false);

            var authMessageOkTask = EnsureNextMessage <AuthenticationMessage>(
                async, cancellationToken);

            using (var authOkMessage = await authMessageOkTask
                                       .ConfigureAwait(false))
            {
                authOkMessage.AsssertIsOk();
            }

            var foundIdleMessage = false;

            do
            {
                var message = await ReadNextMessage(async, cancellationToken)
                              .ConfigureAwait(false);

                switch (message)
                {
                case BackendKeyDataMessage keyDataMessage:
                    // TODO: Throw not supported exception?
                    break;

                case ReadyForQueryMessage readyMessage:
                    _state = ConnectionState.Open;
                    readyMessage.AssertType(TransactionIndicatorType.Idle);
                    foundIdleMessage = true;
                    break;

                default:
                    throw new PostgresInvalidMessageException(message);
                }
            } while (!foundIdleMessage);
        }