• 🏆 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] Can i make an array of struct or store them in a hashtable ?

Status
Not open for further replies.
Level 6
Joined
Jan 4, 2014
Messages
227
Good Day,

Here is my struct from a system by TriggerHappy :

JASS:
struct ProgressBar
    
        unit bar
        unit target
        
        real xOffset = 0
        real yOffset = 0
        
        timer timer
        timer timer2
        
        private boolean t_enabled = false
        private real endVal
        private real curVal=0
        private real pspeed=0
        private boolean reverse
        private boolean done
        private boolean recycle
        
        readonly static unit array dummy
        readonly static integer lastDummyIndex = -1

        method operator x= takes real x returns nothing
            call SetUnitX(this.bar, x)
        endmethod

... etc etc

i want to create a bar for each player, so is there a way to create 12 of ProgressBars, which are accesible by an index ??
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
I'm not entirely sure how vJass works, but if it is anything like GUI, you could always use the player number as the index to make them unique to a player: ProgressBars[Player number of player]. I see no reason why you would need a 2D array to accomplish such a thing, but I could be understanding your question wrong x)
 
Level 6
Joined
Jan 4, 2014
Messages
227
@KILLCIDE : a bar for each player hero

progressbar[1] for player 1
progressbar[2] for player 2
progressbar[3] for player 3

... and so and so on

i just tried this :
JASS:
private ProgressBar array aPBar

and i think it works ^^
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
@KILLCIDE : a bar for each player hero

progressbar[1] for player 1
progressbar[2] for player 2
progressbar[3] for player 3

Ahh well it will have to be MUI then. The solution I provided for you is MPI. You might encounter a bit more complexity if you want to show it locally to the owner.


i just tried this :
JASS:
private ProgressBar array aPBar

and i think it works ^^
No idea how they work xD hopefully someone more experienced comes by to provide you a more accurate solution.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
@kamyflex
You shouldnt edit the ProgressBar struct.
That struct is just the object blueprint with all the functions and stuff that are necessary for it to work.

You should make another trigger, convert it to custom text and there create the progress bars.

If you only have 1 hero for each player, then you only need 12 of them.
If you have multiple heroes per player, then it gets slightly more complicated.
Like this:
JASS:
globals
    ProgressBar array heroBars
endglobals

//===========================================================================
function InitTrig_Player_ProgressBar takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen i >= 16
        
        set heroBars[i] = ProgressBar.create()
        
        set i = i +1
    endloop
endfunction
This will create your 16 progress bars (one for each possible player), you should change it so you wont be making any unnecessary progress bars though.

The bars will be set in a global array.
You can do whatever you like.

(Be aware of the naming of the function as you have to name it based on the name of your trigger... in this case it was "Player ProgressBar".)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Structs actually use arrays for their heap. When you assign a variable of type struct to a struct instance all it does is assign a struct reference (in the form of an integer) to that variable which can be used to get the instance from the struct heap. This means struct behaviour is very different from C/C++ where you need to manually allocate storage for it in the form of its type or malloc of size of type. Structs behave more like Java Classes than C structs.

If this struct is only intended for 1 instance per player then no need to create any manner of crazy reference arrays. You can make the struct "extends array" and use the type as an array of sorts where each instance is an index. This saves resolving indirection in the form of references.
 
What DSG wrote in easier to understand words:

Struct instances are basicly integers and can be used like integers.
This means that you can store them into a hashtable just like you would with an integer:

JASS:
local ProgressBar MyBar = ProgressBar.create()
call SaveInteger(HASH, 0, 0, MyBar)

This becomes important if you want to attach large amounts of data to units or timers. Structs are extremely convenient in this regard, as you only need to write a single integer into the hashtable and can later manually add new struct members at any time without having to mess with child hashtable indices.

For example, when having one bar per unit for a non-specified amount of units:
call SaveInteger(HASH, GetHandleId(unit), 0, MyBar)

... and to retrieve it, you can just do this:
local ProgressBar MyBar = LoadInteger(HASH, GetHandleId(unit), 0)
 
Level 6
Joined
Jan 4, 2014
Messages
227
Thanks guys !

@Wietlol, i dont intend to change any thing in the system and what i tried was :

JASS:
private ProgressBar array aPBar

and it works :)

@Dr Super Good : by extending you mean my struct inhertits from an array ? is array a Type in JASS (or vJASS) ??

@Zwiebelchen : Thanks for the hash table explanations, i could use that for illusions of the hero (or clones)
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
@Dr Super Good : by extending you mean my struct inhertits from an array ? is array a Type in JASS (or vJASS) ??
Structs are a vJASS feature so clearly it has nothing to do with JASS syntax. It is a special language feature of structs, which syntax makes little sense but is well documented.

From the official JassHelper manual...
Array structs

Sometimes, you'd like to have a global array of a struct type, just to be able to have that field syntax we all like so much, it can be more complicated than it is supposed to, for example you have to manually initialize all the indexes to create the unique indexes, etc. Another issue is when you do not really want to use .allocate() and .destroy() you would like to have your own ways for allocation. Array structs are a small syntax enhancement that is equivalent to an array of a struct type, you would be able to use the members for each index and you will not have to worry about .create().
JASS:
//Array structs are hard to explain, but should be simple to understand with an example

struct playerdata extends array //syntax to declare an array struct
     integer a
     integer b
     integer c
endstruct

function init takes nothing returns nothing
  local playerdata pd

     set playerdata[3].a=12  //modifying player 3's fields.
     set playerdata[3].b=34  //notice it behaves as a global array
     set playerdata[3].c=500

     set pd=playerdata[4]
     set pd.a=17             //modifying player 4's fields.
     set pd.b=111            //yep, this is also valid
     set pd.c=501
endfunction

function updatePlayerStuff takes player p returns nothing
  local integer i=GetPlayerId(p)

     //some random function.
     set playerdata[i].a=playerdata[i].b

endfunction
Certain issues with array structs: You cannot declare default values (they would automatically be zero, null or false depending on the type of the member) , you cannot declare onDestroy (it would be pointless), you cannot use .allocate or .destroy, you cannot have array members. Notice that the problem with default values and array members are likely to be fixed in a next version.

Notice that you can use operator declarations to override the get [] operator, in this case, to be able to use ids you would be able to use the typecast operator, e.g. playerdata(4) to get the instances. If you did not understand this last paragraph, don't worry, you probably did not need to know this anyway.
The advantage of this feature is it removes indirection when a struct type is only intended to be used as a single array.
 
Level 6
Joined
Jan 4, 2014
Messages
227
What you say seems mainly related to memory managment, so i'm gonna just follow the exemples provided with the system so that i do nothing wrong, i may later dig deeper about what you sad if needed ...
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
What you say seems mainly related to memory managment, so i'm gonna just follow the exemples provided with the system so that i do nothing wrong, i may later dig deeper about what you sad if needed ...
Stop looking at the vJASS code and look at the JASS code it produces. A lot of the suggestions given above have a pointless array if you statically map 1 instance to one player. Hence why the "extends array" syntax exists so that you can perform such mapping while keeping the readability of a struct.
 
Level 7
Joined
Oct 19, 2015
Messages
286
Judging by his later post, it seems like this is more a case of one instance per hero rather than one instance per player, so that's a moot point.
 
Stop looking at the vJASS code and look at the JASS code it produces. A lot of the suggestions given above have a pointless array if you statically map 1 instance to one player. Hence why the "extends array" syntax exists so that you can perform such mapping while keeping the readability of a struct.
Struct extends array destroys several key features of structs in the default implementation (like inheritance and .getType()).
This is something for speed freaks and there is no reason not to use the default syntax when you don't care for speed.

Seriously, people need to stop suggesting struct extends array, especially to new coders.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,198
Struct extends array destroys several key features of structs in the default implementation (like inheritance and .getType()).
This is something for speed freaks and there is no reason not to use the default syntax when you don't care for speed.

Seriously, people need to stop suggesting struct extends array, especially to new coders.
Problem is that it is a key feature required to combat the bad definition of "struct type" in vJASS. Just like there should be a syntax for a struct singleton (no backing array).

If they were C/C++ style struct types and the array heap mechanics of them was a separate feature (part of "new" and "destroy" syntax) it would not be a problem. What we call a struct variable now would be a struct reference variable.
 
Status
Not open for further replies.
Top