• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Getting a specific instance of a struct

Status
Not open for further replies.
Level 17
Joined
Mar 21, 2011
Messages
1,597
Hi there,

i have a function
JASS:
function AddTile takes integer x, integer y, Tile whichtile returns nothing

now, i want to be able to simply put a created tile (an instance of Tile) into the function like this:

JASS:
local Tile forest = Tile.create("Forest")
local Tile mountain = Tile.create("Mountain")
local Tile castle = Tile.create("Castle")
// ---------------------
set forest.evasion = 20
set forest.defense = 1
// ---------------------
set mountain.evasion = 30
set mountain.defense = 1
// ---------------------
set castle.evasion = 20
set castle.defense = 2
set castle.healing = 20
JASS:
call ch1.AddTile(0, 0, Tile["Forest"])

for now, i came up with this solution, looping through every instance and searching for the same name:
JASS:
library TileLib
   
    struct Tile
       
        static integer index = 0
        static integer array tileid
        static string array tilename
       
        integer evasion
        integer defense
        integer healing
        string name
       
        static method operator [] takes string s returns thistype
            local integer i = 0
            loop
                if tilename[i] == s then
                    return tileid[i]
                endif
                set i = i + 1
                exitwhen i == index
            endloop
            return 0
        endmethod
   
        static method create takes string s returns thistype
            local thistype this = thistype.allocate()
            set tileid[index] = this
            set tilename[index] = s
            set index = index + 1
            return this
        endmethod
       
        method destroy takes nothing returns nothing
            call this.deallocate()
        endmethod
   
    endstruct

endlibrary

is there a better solution for this? it doenst have to be a string, i can be something similar that makes it as readable.
 
Level 14
Joined
Jan 16, 2009
Messages
716
Your solution is fine and shouldn't cause any issue.
Alternatively you could store the struct instance into an hashtable. Try using the Table library.
However, I couldn't say which is better because it depends on the actual usage and what are you looking for.
 
Level 7
Joined
Oct 19, 2015
Messages
286
StringHash + hashtable is the solution (assuming recent patches ahven't broken anything).

Use StringHash as a hashtable key and store the instance (cast to integer) into the hashtable using that key when you create the instance.

Then, retrieve the instance from the hashtable in your [] operator.
 

~El

Level 17
Joined
Jun 13, 2016
Messages
556
Yes it does return a unique integer for strings. So StringHash("GIM") value differs from StringHash("Li"). You might bind data like this to strings via hashtable.
Though, it's not case sensitive (at least it was I think), so StringHash("HELLO") would equal StringHash("hello"), etc.

It is, indeed, non-case sensitive. There are also some other caveats - for example, the algorithm used doesn't distinguish between forward and backward slashes - / and \ are the same to it.

It may also produce collisions in other cases - though uncommon, it can still happen, meaning that 2 different strings may produce the same hash.
 
Status
Not open for further replies.
Top