• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Getting a specific instance of a struct

Status
Not open for further replies.
Level 18
Joined
Mar 21, 2011
Messages
1,622
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.
 
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.
 
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.
 
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.
Back
Top