• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

Getter Setter in a struct

Status
Not open for further replies.
Level 17
Joined
Mar 21, 2011
Messages
1,597
hi,
i'm new to structs and i wondered if there is something like a "dynamic" get-set method
JASS:
struct

    integer i
    integer j
    integer k
   
    call func(i, 1)
    call func(j, 9)
    call func(k, 100)

endstruct
or do i need to write a method for each variable?
 
it is hard to get that functionality because you can't pass variables around as pointers, only as values.

one idea is to use a hashtable combined with StringHash(). Instead of storing your data as struct variables, you would store it with parent key this and child key StringHash("some variable name"), e.g.:
JASS:
call SaveInteger(myHashtable, this, StringHash("a"), value)

You can even emulate struct functionality if you want:
JASS:
struct Example

    method operator i takes nothing returns integer
         return LoadSavedInteger(myHashtable, this, StringHash("i"))       
    endmethod

    method operator i= takes integer value returns nothing
          call SaveInteger(myHashtable, this, StringHash("i"), value)
    endmethod

endstruct

That way you can treat it like a variable, set Example.i = 10, and then you can write a function like so:
JASS:
function func takes string name, integer value returns nothing
     call SaveInteger(myHashtable, this, StringHash(name), value)
endfunction

Not sure if this fits your use-case, but it is one way to approach the problem.
 
Last edited:
Level 17
Joined
Mar 21, 2011
Messages
1,597
thanks for the reply!

i wonder what is better in terms of efficiency/readability, having more methods doing simple stuff or having one method doing everything?


JASS:
struct

    integer a
    integer b
  
    method SetA takes integer i returns nothing
        set this.a = i
    endmethod
  
    method AddA takes integer i returns nothing
        set this.a = this.a + i
    endmethod
  
    method SetB takes integer i returns nothing
        set this.b = i
    endmethod
  
    method AddB takes integer i returns nothing
        set this.b = this.b + i
    endmethod

endstruct

call SetA(1)
call AddB(4)



JASS:
globals
    integer A = 0
    integer B = 1
  
    integer SET = 0
    integer ADD = 1
endglobals

struct

    integer a
    integer b
  
    method SetVar takes integer whichvar, integer math, integer amount returns nothing
        if whichvar == A then
            if math == SET then
                set this.a = amount
            else
                set this.a = this.a + amount
            endif
        else
            if math == SET then
                set this.b = amount
            else
                set this.b = this.b + amount
            endif
        endif
    endmethod

endstruct

call SetVar(A, SET, 1)
call SetVar(B, ADD, 4)
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
Having more methods doing simple, focused stuff is typically better. I would only opt for the second option if you don't know which variable you want to set at compile time (e.g. if whichVar is specified dynamically, or randomly).
Ok thanks,
in my struct, i have stats as variables like
int strength
int speed
int intelligence
...

now, i have a few cases where i would need to go through all of these variables and change their values, in this case a level up function which increases every stat by a certain amount.
with the upper method i would need to call all the functions in the level up method
method levelup
increaseStr(2)
increaseSpd(3)
increaseInt(1)
....

with the other method i could just loop through the whole stat list

so i'm not quite sure what to do :O
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
alright, thanks alot!
sooo, i started thinking about how to make it as short as possible.


this would be the method for one stat only, so imagine this times 7

JASS:
        method SetStatByIndex1 takes integer whichstat, integer whichtype, integer math, integer amount returns nothing
            if whichstat == STAT_HP then
                if whichtype == STAT_VALUE then
                    if math == SET then
                        set this.hp = amount
                    else
                        set this.hp = this.hp + amount
                    endif
                    if this.hp > this.hp_cap then
                        set this.hp = this.hp_cap
                    endif
                elseif whichtype == STAT_CAP then
                    if math == SET then
                        set this.hp_cap = amount
                    else
                        set this.hp_cap = this.hp_cap + amount
                    endif
                else
                    if math == SET then
                        set this.hp_grow = amount
                    else
                        set this.hp_grow = this.hp_cap + amount
                    endif
                endif
            endif
        endmethod


you can shorten in down with additional functions, again, this example is for one stat only


JASS:
        static method SetValue takes integer value, integer amount, integer math returns integer
            if math == SET then
                return amount
            else
                return value + amount
            endif
        endmethod
     
        method SetStatByIndex takes integer whichstat, integer whichtype, integer math, integer amount returns nothing
            if whichstat == STAT_HP then
                if whichtype == STAT_VALUE then
                    call SetValue(this.hp, amount, math)
                    if this.hp > this.hp_cap then
                        set this.hp = hp_cap
                    endif
                elseif whichtype == STAT_CAP then
                    call SetValue(this.hp_cap, amount, math)
                else
                    call SetValue(this.hp_grow, amount, math)
                endif
            endif
        endmethod


i thought about saving all the stats into a hashtable instead, using the index/custom value of a unit as an offset/pointer. this would basically give each stat an index already, which might come in handy


JASS:
        method SetStat takes integer whichstat, integer whichtype, integer math, integer amount returns nothing
            local integer value = LoadInteger(StatHash, whichstat + (this*20), whichtype)
            local integer cap = LoadInteger(StatHash, whichstat, whichtype+1)
            if math == SET then
                set value = amount
            else
                set value = value + amount
            endif
            if whichtype == STAT_VALUE and value > cap then
                set value = cap
            endif
            call SaveInteger(StatHash, whichstat + (this*20), whichtype, value)
        endmethod

this is the whole code i need for ALL stats, which would be significantly shorter. what do you think about it? are there any disadvantages using a hashtable?
 
Status
Not open for further replies.
Top