Monday 9 April 2012

Object List - Add & Delete

To add an object to the object list, we use a function called AddWorkObject().

function AddWorkObject( thisObjectID, thisSprite )
   thisObject = FirstFreeWorkObject()
   if thisObject > TopWorkObject() then numWorkObjects = thisObject
   if WorkObjectValid( thisObject )
      workObject[ thisObject ].isFree = 0
      workObject[ thisObject ].objectID = thisObjectID
      workObject[ thisObject ].sprite = thisSprite
   endif
endfunction thisObject

This takes as it's parameters the values we are going to store in the array and returns the position in the array where it has put them, making the task of adding the object completely self-contained.

The first line calls FirstFreeWorkObject() to find a free space to store the object and puts the result in thisObject.  This result will either be a valid array position or zero if none exists.

The second line checks to see if the position in the array is higher than the current top entry, and if so it moves the top entry up.  It does not need to check the maximum size of the array as this was already done by  FirstFreeWorkObject().  

If there wasn't a free space in the array, then thisObject will be zero, which can't be bigger than the top entry

Since WorkObjectValid() checks to make sure the object reference is above zero and less than or equal to the top entry, the top entry needs to be moved up before this check is called.

The third line checks if the object is valid, using the WorkObjectValid() function, if so it adds the details to the array.

The function then exits, passing the reference used in the array back to the calling instruction.

To delete an object, we use the function DelWorkObject().

function DelWorkObject( thisObject )
   if WorkObjectValid( thisObject )
      workObject[ thisObject ].isFree = 1
      if workObject[ thisObject ].sprite > 0
         thisSprite = workObject[ thisObject ].sprite
         workObject[ thisObject ].sprite = 0
         if getSpriteExists( thisSprite ) then deleteSprite( thisSprite )
      endif
      while workObject[ TopWorkObject() ].isFree = 1 and TopWorkObject() >= 0
         dec numWorkObjects , 1
      endwhile
   endif
endfunction

This takes the array index as it's parameter and does not return a value.

The first thing this does is make sure the index passed is valid, if not, nothing is done.

If the index is valid the function performs a number of tasks.

First, It marks the array entry as free.

Next, it checks to see if the sprite field contains a non-zero value.  Since this is used to store a sprite reference, it then checks to see if the sprite exists and if so, deletes that sprite.

This is a backup in case the main program didn't delete the sprite before it deleted the object. It ensures we don't have a rogue sprite floating about with no reference stored.

Final it performs a while/end while loop to move the pointer to the top entry down.  This is to ensure that searches through the array only need check as far as the last entry used.

What this does is check to see if the .isFree field for the top entry is set to 1 - which would be true if the entry we are deleting is the top entry and that the top entry is greater than zero - which it will be for this entry.

If both things are true, then it reduces the top entry by one.

We could have used an if/endif statement to move the entry down by 1 place, but this routine does a little more. It  also cleans up earlier deletions which were not at the top.

I'll clarify that with an example.

Suppose we had a list of ten objects.  The top entry would be 10.

We then delete entries 8 and 9.  These are not actually deleted, but their .isFree field is simply set to 1.  Since neither are at the top, the top would remain at 10 as entry 10 is still in use.

Now we delete entry 10.

If we had used an if/endif statement to move the top down, it would only move it down 1 space to 9.

But since both 9 and 8 are also empty from the earlier deletions, the top actually needs to be moved down further to 7.

By using a while/endwhile loop, it will keep moving the top down until it finds an entry which has not been  deleted.  One where the isFree field is zero, which will be 7.

Now the difference might be minimal with this example, but suppose we have an array of 1000 items and items 11 to 999, then we delete entry 1000.  We actually then only need to check items  1 to 10, rathr than 1 to 1000.

It just keeps everything that little bit tidier.

No comments:

Post a Comment