GenericObjectPool and reset data

Hi,
I have a question about GenericObjectPool.

I am adding two resources by the following code:
C#:
public void AddResource(CurrencyCollection r, bool hideNotification = false)
{
    _currencyOwner.AddCurrency(r);
     _hideNotification = hideNotification;
}

Now I am trying to add notification about added resource by the following code:
C#:
 private void CurrencyAmountOnOnAdd(ListSlice<CurrencyAmount> obj)
{
    ResourceUpdate?.Invoke();
    if (_hideNotification)
    {
        _hideNotification = false;
        return;
    }
    
    if(obj.Count == 0)// || obj.Last.Amount == 0)
        return;

    _notificationSystem.Notify(new ResourceNotification(obj, false));
}

In the first time I have the following values

DebugView.jpg

FirstResult.jpg

On second time (just add resource one more time) in the result I have
SecondResult.jpg
So data are incorrect. I think that the problem is in CurrencyCollection method which is not clear the data from pool before set it.
C#:
 protected virtual bool AddCurrencyInternal(ListSlice<CurrencyAmount> currencyAmounts, double multiplier, bool notify)
{
    var pooledArray = GenericObjectPool.Get<CurrencyAmount[]>();
    var lhsCurrencyAmountCopy = ListSlice.CopyTo(m_CurrencyAmounts, ref pooledArray);

    //m_CurrencyAmounts is about to be overwritten so return the array to the pool
    GenericObjectPool.Return(m_CurrencyAmounts.Array);
    var pooledArray2 = GenericObjectPool.Get<CurrencyAmount[]>();
    var added = Addition(lhsCurrencyAmountCopy, 1d, currencyAmounts, multiplier, ref pooledArray2);
    m_CurrencyAmounts.Initialize(pooledArray2, false, added.Count);

    if (notify) {
        var addedAmountPooledArray = GenericObjectPool.Get<CurrencyAmount[]>();
        ConvertToDiscrete(currencyAmounts, multiplier, ref addedAmountPooledArray);

        NotifyAdd(addedAmountPooledArray);
        GenericObjectPool.Return(addedAmountPooledArray);
    }

    GenericObjectPool.Return(pooledArray);
    //Don't return pooledArray2 because it is now used by m_CurrencyAmounts

    return true;
}

Can you tell me what can I do to fix this?
Inventory System version 1.1.7
 
Thank you for the detailed breakdown of the bug.
I think the issue might not be the Generic Pool, but that I'm sending the wrong data in notifyAdd.

Try this instead:
C#:
/// <summary>
/// Add currency to the collection.
/// </summary>
/// <param name="currencyAmounts">The currency amounts to add.</param>
/// <param name="multiplier">The multiplier.</param>
/// <returns>True if added correctly.</returns>
protected virtual bool AddCurrencyInternal(ListSlice<CurrencyAmount> currencyAmounts, double multiplier, bool notify)
{
    var pooledArray = GenericObjectPool.Get<CurrencyAmount[]>();
    var lhsCurrencyAmountCopy = ListSlice.CopyTo(m_CurrencyAmounts, ref pooledArray);
    //m_CurrencyAmounts is about to be overwritten so return the array to the pool
    GenericObjectPool.Return(m_CurrencyAmounts.Array);
    var pooledArray2 = GenericObjectPool.Get<CurrencyAmount[]>();
    var added = Addition(lhsCurrencyAmountCopy, 1d, currencyAmounts, multiplier, ref pooledArray2);
    m_CurrencyAmounts.Initialize(pooledArray2, false, added.Count);
    if (notify) {
        var addedAmountPooledArray = GenericObjectPool.Get<CurrencyAmount[]>();
        var discreteAddedAmount = ConvertToDiscrete(currencyAmounts, multiplier, ref addedAmountPooledArray);
        
        NotifyAdd(discreteAddedAmount);
        GenericObjectPool.Return(addedAmountPooledArray);
    }
    GenericObjectPool.Return(pooledArray);
    //Don't return pooledArray2 because it is now used by m_CurrencyAmounts
    return true;
}

I'm sending the discrete added amount now instead of the pooled array, so hopefully it will only notify the correct amount.

Just for context ListSlice is a struct that is used to choose the start and end index of a larger array. It allows us to avoid creating arrays constantly of different sizes. So we can pool a few arrays and then slice only the part we are interested in, reducing the amount of garbage allocation considerably.

Let me know if the code change above fixes your issue. If so it will be part of the next update
 
Thank you for letting me know!

I fixed it in the remove currency internal function too.

The fix will be available in the next update!
 
Top