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

[vJASS] 2-D Arrays in structs

Status
Not open for further replies.
Level 15
Joined
Aug 7, 2013
Messages
1,338
Hi,

I did a basic implementation of a 2-D array, e.g. [i * j + offset], but I realized this doesn't work if the 2-D array is in a struct, because what is happening is newer structs are overwriting the values of the previously instantiated structs as they don't really have their own separate array unfortunately.

I need 2-d array because in the struct, there is an array of dialogs, and I have to keep track of each dialog's set of buttons, and each dialog's button's message like so

button array[dialogNumber][bttnNumber]

string array[dialogNumber][bttnNumberMessage]

What would be a quick fix for this ... ?
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Here's my problem.

I have an abstract struct which several different structs extend. The abstract struct provides all the generalized code (dialogs, etc. are managed the same, regardless of the struct) and also many of the same fields (notably 2-D arrays)

I then have an array of these abstract structs, which stores instances of the child struct.

That way I basically was able to do this, regardless of the different functions of each child struct

JASS:
abstractArray[i].mainFunction(...)

So I guess what would be better, keeping a counter each time a struct is made to keep the 2-D arrays in line (I increment it by the appropriate size each time) and keep this implementation, or just make them all separate structs and copy the code in each one?

The former preserves the OOPness of my code, but the latter would allow me 8000+ instances of each child struct, rather than 8190 / highest array member size struct instances.

Not sure which to do yet...
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Well I did the extra offset trick and everything's working now.

I reduced the size of the 2-D arrays to [5 x 7], with ten players this leaves roughly 23 structs per player. Of course I can probably reduce it to around [3 x 6], which gives 45 structs per player (a much better number). I'll just need to set up a decent dialog recycling mechanic.

How would Table alleviate this issue?
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
JASS:
struct myStruct
    integer array arr[10]
endstruct
will limit the number of instances to 801

JASS:
struct myStruct
    Table arr
    static method create takes nothing returns thistype
        local thistype this = .allocate()
        set this.arr = Table.create()
        return this
    endmethod
    method destroy takes nothing returns nothing
        call .deallocate()
        call arr.destroy()
    endmethod
endstruct

yes, Table requires a creation and deletion of some sort, but it will give you -2,147,483,648 to 2,147,483,647 indexes for EACH struct instance

Table uses 1 hashtable for all data attached to all instances of Table and/or TableArray

if you want 2D array, you just do:

JASS:
struct myStruct
    TableArray table
    static method create takes nothing returns thistype
        local thistype this = .allocate()
        set table = TableArray[0x2000] //argument passed is the size of first dimension
        return this
    endmethod
    method destroy takes nothing returns nothing
        call .deallocate()
        call table.destroy()
    endmethod
endstruct

and it allows you to store much more than just integers, you can store in Table and TableArray almost anything

Example:

JASS:
Table t = Table.create()
t[54] = 456
t.unit[52] = CreateUnit(...)
t.boolexpr[11] = Filter(function someFunction)

TableArray table = TableArray[0x2000]
table[20][30] = 567
table[20].unit[31] = CreateUnit(...)
//etc etc
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
@cokemonkey

I am aware of the 2-D arrays, but nobody bothered to implement them for structs (you can't have array[x][y] as a struct field, outside of a struct it's legal though).

I did not consider more complicated data structures like a linked list, though I'm trying to avoid as much overhead as possible. Usually more complex structures give better performance (space and time), but come at a cost of code readability.

Well besides doing struct[20000], I could just make a static array of a massive size that all the instances share, e.g. array[50000]. That way I won't run out of room. And seeing as now I am managing part of how the structs share space with the 2-D array, I might as well push it into being just a static or global array...Obviously it would cost me a lot of time and be inefficient, but would I really notice a slowdown with what I'm doing (manipulating dialogs/buttons?).

@edo

I will try to understand this "Table," but what on earth did you pass for the 2-D argument?

And how would you use the Table as a 2-D array?
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
well, for 2D you can use the TableArray, its simple, you do TableArrayInstance[indexA][indexB] = 145

and if you want to store more than integer, you can do:

TableArrayInstance[indexA].type[indexB] = something

How do I specify the size of it though?

You put "0x2000" as a size. That's gibberish to me.
 
constant is slower, because its variable read, 0x2000 is literal

Facepalm

and the TableArray is not limited to 8192, you can do TableArray tab = TableArray[50000] and it will give you range [0, 49999]

I didn't say that, I just explained why 0x2000 was chosen.
 
Maybe I should inline all 113 constant instances in my Orianna spell pack - after all, reading variables is slower than literals.

The "use" of using constants is that it improves readability.

8192 looks like a number produced by hexadecimal, 0x2000 is a big hexadecimal number, but only JASS_MAX_ARRAY_SIZE actually describes WHAT it is and WHY you'd choose it.
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
Question about the table--if I have two 2-D arrays, do I also need two Tables per struct?

One is the 2-d array of buttons and the other a 2-D array of strings.
 
Level 15
Joined
Aug 7, 2013
Messages
1,338
??? How could I use a hashtable..?

I am mapping 1 value to many with 2-D array

array[x][y]

array[x] --> {y0, y1, y2, y3, ..., yn}
 
Level 14
Joined
Jun 27, 2008
Messages
1,325
??? How could I use a hashtable..?

I am mapping 1 value to many with 2-D array

array[x][y]

array[x] --> {y0, y1, y2, y3, ..., yn}

No a 2d array is mapping 2 values to one. If you want to map 1 value to 2 you can just use 2 normal 1d arrays or an array of structs (which is internally the exact same).

A hashtable is basically a 2d array, you map the combination of parentkey and childkey to a single value.
array: index -> value
2d array: index1 x index2 -> value
hashtable : parent x child -> value

vJass array members are basically the same as static 2d arrays (which vjass knows too), index1 is the objects "this" pointer and index2 is the index of the arraymember.
If you want to create a 2d array member you will need a static 3d array, and so on...
 
Status
Not open for further replies.
Top