Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Scripts (http://www.wc3c.net/forumdisplay.php?f=737)
-   -   Itemdex (http://www.wc3c.net/showthread.php?t=105971)

Vexorian 05-17-2009 03:31 AM

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

Features
* 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.



Usage:

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
endstruct


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


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...


[tables=updates]
* 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
[/table]

Gamat 05-17-2009 03:49 AM

Hey, i was needing something like this for my equipsys, i created one like UnitIndexing, but with items.

What happens if you use the unit_sells_item event for recycle and unit_picks_item for assign?

Vexorian 05-17-2009 03:51 AM

It wouldn't work. The pocket stash needs attaching without ever adding the item to a hero. And there are zillions (yes, really) of ways to remove items, you could pick a rune up, consume all charges of an item, put it on the ground and kill it, sell it to a store, call RemoveItem, etc...

Rising_Dusk 05-17-2009 03:57 AM

You should at the very least follow the trend we've been using for unit indexing and name your function GetItemId().

Gamat 05-17-2009 04:00 AM

Didn't the pocketstash use a dummyunit for storage?

Yeah, its true, but i think the most used is sold for campaigns or others, the removeitem can be fixed with a releaseindex func. and pick indexed runes well runes aren't used much (only in aos, and i think indexing them is bad)

Also the pawn item from shop will mostly do the job for maps like dota

Vexorian 05-18-2009 12:23 AM

Quote:

Originally Posted by Rising_Dusk
You should at the very least follow the trend we've been using for unit indexing and name your function GetItemId().

I actally have been feeling like making that function private.


Quote:

well runes aren't used much

Also the pawn item from shop will mostly do the job for maps like dota

I don't care, I want my systems to work everywhere, if they don't they suck.

Vexorian 05-21-2009 11:48 PM

All right, it is GetItemId now.

Anitarf 06-04-2009 07:28 PM

Is set i= i-indexN*(i/indexN) really faster than an if statement? Well, it sure is a lot less readable but if it's faster I guess that's ok.

The get method isn't finished yet, but since it's only used for debug messages I guess it doesn't matter. Unless you want this to wait in resource submissions until it is finalised, I will approve it.

Vexorian 06-04-2009 07:55 PM

the get method is finished. Its purpose is just to have a name in the debug message, so it will be removed when .name is added to structs.

I don't get the other statement too well, what's the if alternative? That's just a modulo operation.

Anitarf 06-04-2009 08:33 PM

Quote:

Originally Posted by Vexorian
the get method is finished. Its purpose is just to have a name in the debug message, so it will be removed when .name is added to structs.

Oh, ok. I understood it was a placeholder, just didn't know it was a functional one.
Quote:

I don't get the other statement too well, what's the if alternative? That's just a modulo operation.
Well, an alternative to set i= i-indexN*(i/indexN) would be something like:
Collapse JASS:
If i>=indexN then
    set i=0
endif

Vexorian 06-04-2009 10:05 PM

It's not exactly the same, though maybe it is better that way not sure.

I found i = i - indexN*(i/indexN) to be more readable becaue I would always implement this circular stuff using modulos.

the if is probably much faster.

Vexorian 06-05-2009 02:40 PM

I updated it to replace it with the ifs.

Anitarf 06-06-2009 09:55 AM

So, I moved the somewhat unrelated discussion to another thread, also, this is approved now.

Vexorian 06-07-2009 02:27 PM

I added a features section.

Vexorian 06-16-2009 11:09 PM

I added a read only thatItem member that points to the .. item.

It won't work in onDestroy.


All times are GMT. The time now is 08:17 PM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services