Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / [DBP] - Free-List Library

Author
Message
Mr Kohlenstoff
17
Years of Service
User Offline
Joined: 7th Jun 2006
Location: Germany
Posted: 21st Feb 2012 15:05 Edited at: 28th Feb 2012 11:58
Hi,

I realized that not only Tree Structures were missing in DBP but also a convenient way to handle a "Free List".

Take an array of units for a shooter game for example, most of them being AI-controlled. Some AI-Units may have an attack-target, which is a reference to another unit. Now imagine that a unit is killed - there are two ways to handle this event:
1. You can remove the unit from the unit-array - this has the striking disadvantage that the ID of all units that came after this one will now have a reduced array-position. Consequently you'd have to update all unit-references to avoid cases where the death of one unit results in most AI-units suddenly having another target.
2. You can use a boolean "exist"-flag for each unit which determines whether the unit is alive. If a unit dies, you simply set Unit(ID).exist = 0. This way the unit IDs stay the same when a unit dies, but there is another disadvantage: Either the unit array keeps growing and growing because every dead unit keeps its array element, or you actively search for those death units to overwrite them when creating a new one, which is in my opinion the best solution. But then again, there's much overhead because when the array gets big you may have to search for quite a while (only to realize that there is no dead unit in the worst case, so the whole search was pointless and a new element has to be created).

This problem is solved by a free list: There's a second array keeping hold of all the array-IDs of all dead units. When a new unit has to be created you simply pick an arbitrary array ID from the free list and use it as new unit ID.

Implementing such free lists individually when you need them is not all that hard, but can still be made easier by using a central system that manages several free lists at once. And this is, finally, where the library below comes in.


The commands available:
Quote: "
fl_init() - should be called once after starting your program
listID = fl_newList() - sets up a new list and returns the lists ID
fl_register(listID, index) - adds a value to the given Free-List, this value is usually an index of the array the list is responsible for
index = fl_revive(listID) - if the given Free-List still contains registered elements, it will return one of the indices you registered earlier; otherwise it returns -1.
string = fl_toString(listID) - converts the content of a free List into a string - can be used for debugging purposes
"


Here's the code for the library itself:




And here's the code together with a usage example:





- - - - - - - - - - - - - - - - - - - - - - -



Now to get back to the scenario describes in the beginning, here's some pseudo code:

1. Deleting dead units


Problem: Array IDs get messed up quickly and the whole system gets inconsistent as soon as you're using values that refer to those array IDs.


2. exist-Flag, first Version: dead units are kept in the array

Problem: After some time the array gets huge, generating much overhead in the handleUnits-function since a ton of dead units have to be traversed, although they are not actually needed.


3. exist-Flag, second Version: dead units are replaced by searching them when adding a new unit

Problem: Searching for free IDs takes some time. Usually you won't notice that because it's probably a matter of less than a milisecond, but still there may be cases when extensive data has to be handled this way and the search process may become the bottle neck.


4. exist-Flag, third and final Version: Using a free list


Problem: Solved.

noobnerd
13
Years of Service
User Offline
Joined: 30th Nov 2010
Location:
Posted: 21st Feb 2012 21:16
im not 100% sure if this is exactly what i think it is, but if so then there it can be found in the matrix utils plugin. It is the largest collection of extra commands for DBP and i think most of us have it.

there are commands in it that does this exactly i think, i use them all the time and as you said they are extremely usefull. matrix utils also have commands for finding free sprites, images etc.

but again, nice code! and you are quite effective at producing it !
Mr Kohlenstoff
17
Years of Service
User Offline
Joined: 7th Jun 2006
Location: Germany
Posted: 21st Feb 2012 21:56
Well as it turned out, you're absolutely right.
There are some commands that seemingly do exactly what I implemented here.

Anyway, this way it is possible to manipulate parts of the code if required - if not, the plugin is most certainly the better choice.

MrValentine
AGK Backer
13
Years of Service
User Offline
Joined: 5th Dec 2010
Playing: FFVII
Posted: 28th Feb 2012 02:20
Quote: "Anyway, this way it is possible to manipulate parts of the code if required - if not, the plugin is most certainly the better choice."


in all fairness... your code allows for DLL'less management so for those looking to reduce DLL's [say a competition that has size restrictions] then I suppose you hit the bag

Smile always find a reason to smile buddy you did something some of us were too under experienced to do.

Well Done!

but yeah I might just use IanM's

IanM
Retired Moderator
21
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 13th Apr 2012 00:52
Interesting fact: The prototype of the free-list functions in my plug-ins was originally written in pure DBPro too

Login to post a reply

Server time is: 2024-04-19 15:42:39
Your offset time is: 2024-04-19 15:42:39