Thread: Itemdex
View Single Post
Old 05-17-2009, 03:31 AM   #1
Free Software Terrorist
Vexorian's Avatar

Technical Director
Join Date: Apr 2003
Posts: 14,898

Submissions (37)

Vexorian has a reputation beyond repute (1062)Vexorian has a reputation beyond repute (1062)Vexorian has a reputation beyond repute (1062)Vexorian has a reputation beyond repute (1062)Vexorian has a reputation beyond repute (1062)Vexorian has a reputation beyond repute (1062)Vexorian has a reputation beyond repute (1062)

Hero Contest #3 - 2nd Place

Default Itemdex

This is just an indexer for items, I would need it for the PocketStash and InvX...

* Easy to use.
* Feel free to use RemoveItem or sell items or do whatever you want to get rid of items that have indexes (like using runes/tomes), the indexes will be recycled eventually.
* Feel free to create items in the map, if you call Itemdex on them before they are picked up, it will work perfectly ok.
* Supports UserData or Table, so you can stop worrying about incompatibility issues, if something else in your map uses ItemUserData, feel free to use the Table version.
* The module will call your struct's onDestroy method just fine.
* Use .destroy to get rid of the item structs, it will detach them.
* Modules are superior to text macros in every imaginable way, the syntax is good and readable and there are no name conflict risks.
* Can use Table or UserData depending on whether you want speed or compatibility.

Possible cons
* Recycling is not instant but it should be quick enough. The limit of item ids is bellow 8191 because of this reason, never calculated how low, but, worse case scenario it is 4000~ , if you have a map with 4000 active items in your map, each one using an id, perhaps you might need to use something different.
* GetItemId does not get inlined. Worse, in the Table version GetItemId uses gamecache! If you ever need to call Itemdex on 100 items every 0.025 seconds, don't use Itemdex, use the faster alternatives so your framerate jumps from 20.0 FPS to 23.2 FPS.
* It does not automatically clean up Rune/Tome leaks. I could make it clean those ups but it would only mess with those that have an index. Only way would be to index every item possible and therefore try to hopelessly detect their creation, something I am not interested in doing. We lived with that leak for many years without problems, but I think I will make another system independent on indexing for it, in case your map actually suffers from this issue. (I would say this is a problem for very few maps).
* The Table version uses H2I which means Jesus4Lyf's pet's ghost will come to your house and cause you nightmares for the rest of your life.


Collapse JASS:
   local integer it = GetItemId( someitem)

GetItemId is inline unfriendly, there's no such thing as an Enter Region event for items, so it can't just call GetItemUserData...

Also comes with a module you can use for structs specialized on being fields for items:
Collapse JASS:
struct HolyCow
    integer score = 0
    integer bonusA

    implement Itemdex
    //adds a static [] operator that takes items, it
    // will automatically call .create if necessary
    // destroy is also automatic as well when it detects
    // the item to which the instance was attached to
    // goes away
   // don't use .destroy directly on these structs, use
   // .release, this would basically reset the item's data

function meh takes item it returns nothing
    set it:HolyCow.score = it:HolyCow.score + 1

Of course, auto cleaning allows cute things as you can attach things like handles and other structs to an item and they will eventually get cleaned by calling your onDestroy and all is MUI...

Due to a lot of things related to how much items suck, the cleaning is done by a timer that periodically checks if the indexes are healthy and must be recycled, there's another cleaning thing related to the module, in which it will detect if the index was assigned to another item and thus readapt, so onDestroy may not get called as soon as we'd like, don't expect it to work like an instant "onItemRemove" event, it's rather just something you use to avoid memory leaks.

It may take a good while before onDestroy is called on a struct that belongs to a removed item. But it is still effective at preventing big leaks when there is a lot of usage. It works without further complications in all cases in which items can be considered removed.

I plan to make onDestroy get called at the moment the index is recycled, though I need to make some changes to jasshelper first...

Due to modules, it requires jasshelper 0.9.G.0 or greater ( I recommend the latest...)

Oh and there's a Table version that requires Table it is meant to be used in case the guy already was using ItemUserData for something else.

To be honest, the Table version is good enough unless you really need speed which I seriously doubt. The good thing about it is that Itemdex does not need to kidnap your ItemUserData rights. It also doesn't force archaic things like textmacros on you. All good.

Expand Itemdex:

The names are final.

And of course, it will explode if you reach more than x*8190 items where x is around 0.73333 I think, the reason is that there is a 8190 index limit, but as it takes some time to find dead indexes and call onDestroy, the limit should be 25% smaller, I would say...

I'd just like to see a map with over 1000 items though...

* There is now only one version, however, you can set it to use Table instead of UserData by setting USE_USER_DATA to false.
* You can now use .destroy freely in your Itemdex structs.
* onDestroy can now use .thatItem
Zoom (requires log in)Wc3 map optimizer 5.0
Someone should fix .wav sound in this thing.
Zoom (requires log in)JassHelper 0.A.2.A
Turns your simple code into something that is complicated enough to work.
Faster != more useful
Vexorian is offline   Reply With Quote
Sponsored Links - Login to hide this ad!