disas69/Unity-PooledScrollList-Asset

Out of range exception in PooledLayoutController.ReorientElement

Closed this issue · 1 comments

Hi,

I'm getting a few of these exception every day. It doesn't appear to be a common occurence but under some condition the ReorientElement method can crap out.

Message:ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

Stack_Trace:System.ThrowHelper.ThrowArgumentOutOfRangeException (System.ExceptionArgument argument, System.ExceptionResource resource) (at <00000000000000000000000000000000>:0)
System.ThrowHelper.ThrowArgumentOutOfRangeException () (at <00000000000000000000000000000000>:0)
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <00000000000000000000000000000000>:0)
Assets.Scripts.PooledScrollList.PooledLayoutController`2[TData,TElement].ReorientElement (Assets.Scripts.PooledScrollList.PooledScrollRectController`2+ReorientMethod[TData,TElement] reorientMethod, System.Int32 elementsCulledAbove) (at <00000000000000000000000000000000>:0)
Assets.Scripts.PooledScrollList.PooledLayoutController`2[TData,TElement].UpdateContent () (at <00000000000000000000000000000000>:0)
Assets.Scripts.PooledScrollList.PooledScrollRectController`2[TData,TElement].Initialize () (at <00000000000000000000000000000000>:0)

Here is the current method

protected override void ReorientElement(ReorientMethod reorientMethod, int elementsCulledAbove)
{
    if (ActiveElements.Count == 0)
    {
        return;
    }

    if (reorientMethod == ReorientMethod.TopToBottom)
    {
        var top = ActiveElements[0];
        ActiveElements.RemoveAt(0);
        ActiveElements.Add(top);

        top.transform.SetSiblingIndex(ActiveElements[ActiveElements.Count - 2].transform.GetSiblingIndex() + 1);
        top.Data = Data[elementsCulledAbove + ActiveElements.Count - 1];
    }
    else
    {
        var bottom = ActiveElements[ActiveElements.Count - 1];
        ActiveElements.RemoveAt(ActiveElements.Count - 1);
        ActiveElements.Insert(0, bottom);

        bottom.transform.SetSiblingIndex(ActiveElements[1].transform.GetSiblingIndex());
        bottom.Data = Data[elementsCulledAbove];
    }
}

It looks like accessing the list at index ActiveElements.Count - 2 will be allowed if there is 1 element in the list, resulting in index -1 being seeked out. Same goes for index ActiveElements[1] in the else condition.

It is possible to change the return-check at the beginning of the method to < 2 but I don't know whether that will put the object in an unexpected state or not.

Cheers,
Alain-Daniel

Hi,

Thanks for finding the issue and giving such a detailed explanation!

I could not reproduce it but I see the problem, so I followed your advice and fixed the return check. The fix is included in version 1.1.

Regards,
Eugene