Author Topic: FlxGroup Internal Bug? Adding a third object adds a 4th null object  (Read 1430 times)

NateTheGreatt

  • Member
  • **
  • Posts: 83
  • Karma: +0/-0
  • smell the sound
    • View Profile
    • n8bit
When I add two objects to an FlxGroup and I log members.length, it returns 2. If I add a third object, members.length logs to 4. Is this a bug?

I thought it was Flixel 2.50 so I tried updating to 2.55 and the bug persisted. Also, I noticed that when I logged FlxGroup.members it would log a list of objects to the console. After updating to 2.55, it logs nothing for FlxGroup.members.

Are these bugs?
« Last Edit: Tue, Sep 6, 2011 by NateTheGreatt »
"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
-Antoine de Saint-Exupery

auriplane

  • Snails!!
  • Contributor
  • ****
  • Posts: 497
  • Karma: +1/-0
  • Snails!!
    • View Profile
Check length, not members.length.

Code: [Select]
        public var members:Array;
        /**
         * The number of entries in the members array.
         * For performance and safety you should check this variable
         * instead of members.length unless you really know what you're doing!
         */
        public var length:Number;

Code: [Select]
        /**
         * Adds a new <code>FlxBasic</code> subclass (FlxBasic, FlxSprite, Enemy, etc) to the group.
         * FlxGroup will try to replace a null member of the array first.
         * Failing that, FlxGroup will add it to the end of the member array,
         * assuming there is room for it, and doubling the size of the array if necessary.
         *
         * <p>WARNING: If the group has a maxSize that has already been met,
         * the object will NOT be added to the group!</p>
         *
         * @param   Object      The object you want to add to the group.
         *
         * @return  The same <code>FlxBasic</code> object that was passed in.
         */
        public function add(Object:FlxBasic):FlxBasic
        {
            //Don't bother adding an object twice.
            if(members.indexOf(Object) >= 0)
                return Object;

            //First, look for a null entry where we can add the object.
            var i:uint = 0;
            var l:uint = members.length;
            while(i < l)
            {
                if(members[i] == null)
                {
                    members[i] = Object;
                    if(i >= length)
                        length = i+1;
                    return Object;
                }
                i++;
            }

            //Failing that, expand the array (if we can) and add the object.
            if(_maxSize > 0)
            {
                if(members.length >= _maxSize)
                    return Object;
                else if(members.length * 2 <= _maxSize)
                    members.length *= 2;
                else
                    members.length = _maxSize;
            }
            else
                members.length *= 2;

            //If we made it this far, then we successfully grew the group,
            //and we can go ahead and add the object at the first open slot.
            members[i] = Object;
            length = i+1;
            return Object;
        }

Arkeus

  • Contributor
  • ****
  • Posts: 321
  • Karma: +1/-0
    • View Profile
    • I, Arkeus
What auriplane said. The reasoning being, once you fill up the array, it doubles the size of array (for performance reasons). So if it's of length 64, and you add a 65th thing, it will now say 128. Because of this, using the groups length instead of members length is what you want.

NateTheGreatt

  • Member
  • **
  • Posts: 83
  • Karma: +0/-0
  • smell the sound
    • View Profile
    • n8bit
Ahh that makes sense. I didn't even realize there was another length variable. Thank you!
"A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away."
-Antoine de Saint-Exupery

KWarp

  • Active Member
  • ***
  • Posts: 105
  • Karma: +0/-0
  • Game Programmer
    • View Profile
    • kwarp.com
I am skeptical if there is a performance benefit to doubling the array size every once-in-a-while. The problem is that we have no idea of Flash Arrays stores it's elements continuously in memory. Flash Vectors, on the other hand, densely pack objects together, are strongly typed, and have better performance... why don't FlxGroups uses a Vector of FlxBasics?
To understand recursion, you must first understand recursion.

auriplane

  • Snails!!
  • Contributor
  • ****
  • Posts: 497
  • Karma: +1/-0
  • Snails!!
    • View Profile
Flash Vectors, on the other hand, (...) have better performance... why don't FlxGroups uses a Vector of FlxBasics?

Measure it and report back.  At one point, Vector was fast storing numeric types, slow storing objects.  I wouldn't assume this is still true, or that it isn't, without measuring it.