public static void ClearCache()
 {
     while (_cachedTreesHead != null)
     {
         var node = _cachedTreesHead;
         _cachedTreesHead = _cachedTreesHead.next;
         node.next        = null;
     }
     _NUM_CACHED_QUAD_TREES = 0;
 }
        public static FlxQuadTree Recycle(float x, float y, float width, float height, FlxQuadTree parent = null)
        {
            if (_cachedTreesHead != null)
            {
                FlxQuadTree cachedTree = _cachedTreesHead;
                _cachedTreesHead = _cachedTreesHead.next;
                _NUM_CACHED_QUAD_TREES--;

                cachedTree.Reset(x, y, width, height, parent);
                return(cachedTree);
            }
            else
            {
                return(new FlxQuadTree(x, y, width, height, parent));
            }
        }
        public void Dispose()
        {
            _headA = null;
            _headB = null;

            _tailA = null;
            _tailB = null;

            _northWestTree = null;
            _northEastTree = null;

            _southEastTree = null;
            _southWestTree = null;

            _object             = null;
            _processingCallback = null;
            _notifyCallback     = null;

            Exists = false;

            next             = _cachedTreesHead;
            _cachedTreesHead = this;
            _NUM_CACHED_QUAD_TREES++;
        }
 public FlxQuadTree(float x, float y, float width, float height, FlxQuadTree parent = null)
 {
     Set(x, y, width, height);
     Reset(x, y, width, height, parent);
 }
        private void AddObject()
        {
            // If this quad (not its children) lies entirely inside this object, add it here
            if (!_canSubdivide ||
                (_leftEdge >= _objectLeftEdge && _rightEdge <= _objectRightEdge && _topEdge >= _objectTopEdge && _bottomEdge <= _objectBottomEdge))
            {
                AddToList();
                return;
            }

            // See if the selected object fits completely inside any of the quadrants
            if ((_objectLeftEdge > _leftEdge) && (_objectRightEdge < _midpointX))
            {
                if ((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY))
                {
                    if (_northWestTree == null)
                    {
                        _northWestTree = FlxQuadTree.Recycle(_leftEdge, _topEdge, _halfWidth, _halfHeight, this);
                    }
                    _northWestTree.AddObject();
                    return;
                }
                if ((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge))
                {
                    if (_southWestTree == null)
                    {
                        _southWestTree = FlxQuadTree.Recycle(_leftEdge, _midpointY, _halfWidth, _halfHeight, this);
                    }
                    _southWestTree.AddObject();
                    return;
                }
            }
            if ((_objectLeftEdge > _midpointX) && (_objectRightEdge < _rightEdge))
            {
                if ((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY))
                {
                    if (_northEastTree == null)
                    {
                        _northEastTree = FlxQuadTree.Recycle(_midpointX, _topEdge, _halfWidth, _halfHeight, this);
                    }
                    _northEastTree.AddObject();
                    return;
                }
                if ((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge))
                {
                    if (_southEastTree == null)
                    {
                        _southEastTree = FlxQuadTree.Recycle(_midpointX, _midpointY, _halfWidth, _halfHeight, this);
                    }
                    _southEastTree.AddObject();
                    return;
                }
            }

            // If it wasn't completely contained we have to check out the partial overlaps
            if ((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY))
            {
                if (_northWestTree == null)
                {
                    _northWestTree = FlxQuadTree.Recycle(_leftEdge, _topEdge, _halfWidth, _halfHeight, this);
                }
                _northWestTree.AddObject();
            }
            if ((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY))
            {
                if (_northEastTree == null)
                {
                    _northEastTree = FlxQuadTree.Recycle(_midpointX, _topEdge, _halfWidth, _halfHeight, this);
                }
                _northEastTree.AddObject();
            }
            if ((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge))
            {
                if (_southEastTree == null)
                {
                    _southEastTree = FlxQuadTree.Recycle(_midpointX, _midpointY, _halfWidth, _halfHeight, this);
                }
                _southEastTree.AddObject();
            }
            if ((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge))
            {
                if (_southWestTree == null)
                {
                    _southWestTree = FlxQuadTree.Recycle(_leftEdge, _midpointY, _halfWidth, _halfHeight, this);
                }
                _southWestTree.AddObject();
            }
        }
        public void Reset(float x, float y, float width, float height, FlxQuadTree parent = null)
        {
            Exists = true;
            Set(x, y, width, height);

            _headA = _tailA = FlxLinkedList.Recycle();
            _headB = _tailB = FlxLinkedList.Recycle();

            if (parent != null)
            {
                FlxLinkedList iterator;
                FlxLinkedList ot;
                if (parent._headA.FlxObject != null)
                {
                    iterator = parent._headA;
                    while (iterator != null)
                    {
                        if (_tailA.FlxObject != null)
                        {
                            ot      = _tailA;
                            _tailA  = FlxLinkedList.Recycle();
                            ot.Next = _tailA;
                        }
                        _tailA.FlxObject = iterator.FlxObject;
                        iterator         = iterator.Next;
                    }
                }
                if (parent._headB.FlxObject != null)
                {
                    iterator = parent._headB;
                    while (iterator != null)
                    {
                        if (_tailB.FlxObject != null)
                        {
                            ot      = _tailB;
                            _tailB  = FlxLinkedList.Recycle();
                            ot.Next = _tailB;
                        }
                        _tailB.FlxObject = iterator.FlxObject;
                        iterator         = iterator.Next;
                    }
                }
            }
            else
            {
                _min = (int)Math.Floor((Width + Height) / (2 * Divisions));
            }
            _canSubdivide = Width > _min || Height > _min;

            _northWestTree = null;
            _northEastTree = null;
            _southWestTree = null;
            _southEastTree = null;
            _leftEdge      = X;
            _rightEdge     = Right;
            _halfWidth     = Width / 2;
            _midpointX     = _leftEdge + _halfWidth;
            _topEdge       = Y;
            _bottomEdge    = Bottom;
            _halfHeight    = Height / 2;
            _midpointY     = _topEdge + _halfHeight;
        }