• 🏆 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!

[vJASS] Arrays Variables

Status
Not open for further replies.
Level 17
Joined
Apr 27, 2008
Messages
2,455
You can't, however you can probably abuse vJass features :

JASS:
struct My3D

    integer array var[10][20]

    static method operator [] takes integer x return thistype
        return thistype(x)
    endmethod

endstruct

set My3D[1].var[2][3] = 42

// or without the method operator : set My3D(1).var[2][3]

But maybe it's too much ugly.
To know how far you can go just read the jasshelper documentation, don't forget to read about structs.

Now if you really want N-D array, then it will probably better to use a custom function.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
You know the struct abuse is likely to not work i guess, i suppose using My3D.create() will return 1, then 41, 81, etc ...
Well, at least a test is needed, i don't remember how vJass is "compiled" in jass.

Which N-dimension do you want to use ?
 
Level 16
Joined
Mar 3, 2006
Messages
1,564
As long as the demensions have a constant size you can use mathematics to emulate a nD array.

A 3D array formula...
x*ymax*zmax + y*zmax + z

I know about this formula. But if I am using it in a spell for example I will have to make the size constant which will make the spell less reliable to be used.

One of the problems I faced is making a Full Screen Inventory (FSI) I wished for a 4-D variable, I know you can overcome this with other means, all I am just saying is that it would have been better if there is a way to make N-D variables but it seems as always Blizzard make things harder.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Moar vJass abuse, if my assumption is correct (i'm really bad at maths), this should work :

JASS:
library Var4D

    globals
        private integer array Size
    endglobals
    
    struct Var
    
        private static constant integer A = 10
        private static constant integer B = 2
        private static constant integer C = 30
        private static constant integer D = 4
        
        private static integer index
    
        integer int
        
        static method operator [] takes integer x returns thistype
            set thistype.index = 0
            return thistype(x*thistype.B*thistype.C*thistype.D)
        endmethod
        
        method operator [] takes integer x returns thistype
            local integer i
            set thistype.index = thistype.index+1
            set i = thistype.index
            
            loop
            exitwhen i >= 3
                set i = i+1
                set x = x*Size[i]
            endloop
            return thistype(this + x)
        endmethod
        
        static method onInit takes nothing returns nothing
            set Size[0] = thistype.A
            set Size[1] = thistype.B
            set Size[2] = thistype.C
            set Size[3] = thistype.D
        endmethod
        
    endstruct
    
endlibrary
My assumption is that for 4D array the formula to make it 1d is :

A*Bmax*Cmax*Dmax + B*Cmax*Dmax + C*Dmax + D

Now, since it uses a struct, and then a global array on the background, Amax*Bmax*Cmax*Dmax must be less or equal than 8191, or even let's say 8190.
It can happen very quickly.
You could "improve" it, increasing the range available using an hashtable instead.

Example of use :

set Var[9][1][29][3].int = 42

Ofc you can use textmacros to create more 4d variables easier.
You can also declare as many members as you want, it won't decrease the range available of your 4D array.
 
IMO I would use:
http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/
And then just use the TableArray struct. Using arrays for this may not be the best option because (1) math is confusing (2) it is very easy to get out of index 8191 when flattening an n-dimensional array (3) may allocate more memory than necessary.

If it works for you, you can use it. Just make sure you take a bit of caution.

To answer your question, no there is no easier way.
 
idk. I remember it being able to do something like that. It is mentioned in some of the posts of the thread. Mag and Bribe probably know a way to make it do that. I haven't really used that feature and I can't test it so I can't be sure. But it should be possible to make it that way, and I think it'll still be "clean". (but fugly on the inside)
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I will take a better look to Table by Bribe if someone don't answer it in few days.

Just for saying, while keeping the same API, i can dramatically increase the range available of the 4D variable, simply by using an hashtable (or Table for that matter) to "hash" the result in 1D, but then you won't be able to use more than 8191 4D "instances" at the same time.

I agree that actually my code, once "compiled" in jass is horrible, but i'm just sure it's still much nicer than TableArray, simply because it doesn't use an hashtable all the time.

Don't take me wrong i'm not bitching the library Table, that was just fun to answer this thread.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I've not tried to follow the logic behind Table, just read the API and the sample provided, hence my question.
But well, it's not really hard to read a code, once you know the features of the language and the API. Excepted if there is no comment or only few and/or the names of functions and variables are short and/or senseless.

But vJass abuses are legion though, which can lead to spaghetti meaningless code.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Arrays are by very nature bounded in size. A 4D array retains these restrictions.

The only violation to this is when achieveing multi demensional arrays using arrays of pointers. Although access through such systems might appear as multi dimensional arrays, it is nothing more than a chain of single array lookups as the first n-1 tiers of arrays are pointers to another array and so evaluate to an array.

The disadvantage of the pointer approach is reduced memory efficiency (as you now have tiers of arrays holding pointers to the arrays holding actual data) and potentially lower perfromance (every tier of arrays requires a memory read to evaluate past).
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Well, it's still limited to 8190-8192 "instances". However you can't avoid that if you want to keep the same struct API. Maybe you can extend the range with extended struct, i have not thought about it. But if you go with that solution you will get moar bloat jass code ofc.
And in some cases that would still be not enough.

It always uses an hashtable, so it isn't that much clean. But if you don't have to define the size of the array it could be considered as a major pro i suppose.

Now, all these workarounds are fugly, including "mine".

EDIT : Jesus4Lyf's way uses one struct allocation for each method operator [], which is quite lame, because it reduces dramatically how many 4D you can use at the same time.
"My" solution uses only one struct "allocation" per unique array 4D index, and if the formula is correct you can easily make a wrapper for an N-D array using a textmacro, module, whatever ...
 
Last edited:
Status
Not open for further replies.
Top