Beispiel #1
0
        /// <summary>
        /// This is a helper method to know what RemoveQuantity will take (between RemovalMultiple and exactAmountOnly, it
        /// gets a little complex)
        /// </summary>
        public static double GetRemoveAmount(IContainer container, double amount, bool exactAmountOnly)
        {
            //NOTE: I couldn't think of a way to make this totally threadsafe without adding more to the IContainer interface that returns all the needed
            //variables in one shot.  But in reality, OnlyRemoveMultiples and RemovalMultiple should change very infrequently if ever

            double retVal = amount;

            double quantityCurrent = container.QuantityCurrent;

            // See if the outgoing flow needs to be restricted
            if (retVal > quantityCurrent)
            {
                retVal = quantityCurrent;
            }

            // See if it wants even multiples
            if (container.OnlyRemoveMultiples)
            {
                double removalMultiple = container.RemovalMultiple;

                if (!Math1D.IsDivisible(retVal, removalMultiple))
                {
                    // Remove as many multiples of the requested amount as possible
                    retVal = Math.Floor(retVal / removalMultiple) * removalMultiple;
                }
            }

            // Exact amount
            if (exactAmountOnly && !Math1D.IsNearValue(retVal, amount))
            {
                retVal = 0d;
            }

            // Exit Function
            return(retVal);
        }
Beispiel #2
0
        public double RemoveQuantity(double amount, bool exactAmountOnly)
        {
            lock (_lock)
            {
                double current = GetQuantityCurrent();
                double max     = GetQuantityMax().Item1;    // using the destroyed aware max

                double actualAmount = amount;

                // See if I need to restrict the outgoing flow
                if (actualAmount > current)
                {
                    actualAmount = current;
                }

                //NOTE: Only looking at the whole, not each individual container
                if (_onlyRemoveMultiples && !Math1D.IsDivisible(actualAmount, _removalMultiple))
                {
                    // Remove as many multiples of the requested amount as possible
                    actualAmount = Math.Floor(actualAmount / _removalMultiple) * _removalMultiple;
                }

                if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount))
                {
                    actualAmount = 0d;
                }

                if (actualAmount != 0d)
                {
                    #region Remove it

                    // Ensure that the containers are equalized
                    switch (_ownership)
                    {
                    case ContainerOwnershipType.GroupIsSoleOwner:
                        // Nothing to do
                        break;

                    case ContainerOwnershipType.QuantitiesCanChange:
                        EqualizeContainers(false);
                        break;

                    case ContainerOwnershipType.QuantitiesMaxesCanChange:
                        EqualizeContainers(true);
                        break;

                    default:
                        throw new ApplicationException("Unknown ContainerOwnershipType: " + _ownership.ToString());
                    }

                    // Remove the value evenly
                    for (int cntr = 0; cntr < _containers.Count; cntr++)
                    {
                        _containers[cntr].Item1.QuantityCurrent -= actualAmount * _ratios[cntr].Item1;      // using the destroyed aware ratio
                    }

                    // Cache the new value (this is used if sole owner)
                    _current = current - actualAmount;

                    #endregion
                }

                // Exit function
                return(amount - actualAmount);
            }
        }