- Joined
- Nov 7, 2014
- Messages
- 571
Suppose we wanted to write the function iminmax that took two integers A and B and would return to us
the minumum and the maximum of the two, well... we "can't" do it in jass because we can't return multiple values.
What do other langauges that can't return multiple values do? Well they return records/structs, but hey vJass has structs could we use those? Maybe, lets see:
Notice that there's a slight problem now, if iminmax was called more than 8190 times it will fail because we would run out of struct instances,
one way to fix that would be to force the caller to call the imm.destroy method, and that would work, but it's somewhat error prone and annoying.
In order not to force the caller to call .destroy we can use our own struct allocation scheme and thankfully vJass allows us to do that (via "extends array"):
Good, now users of iminmax, can call it as much as they want and don't have to worry about "destroying" things.
Now, let's say we want to write the function rminmax which works the same way as iminmax but for real numbers not integers, well we could just
copy the iminmax struct rename it and it's members types and then go and write rminmax.
But notice that the code for the new_result method and the next_result variable will always stay the same, no matter what the other members of the result struct were.
We can avoid having to write/copy-paste this duplication by hand by using the module feature of vJass:
And now the rminmax_result struct would look like:
and the rminmax function
And that's basically it, we can now easily write functions that have multiple return values.
the minumum and the maximum of the two, well... we "can't" do it in jass because we can't return multiple values.
What do other langauges that can't return multiple values do? Well they return records/structs, but hey vJass has structs could we use those? Maybe, lets see:
JASS:
struct iminmax_result
int min
int max
endstruct
function iminmax takes integer a, integer b returns iminmax_result
local iminmax_result imm = iminmax_result.create()
if a < b then
set imm.min = a
set imm.max = b
else
set imm.min = b
set imm.max = a
endif
return imm
endfunction
function use_iminmax takes nothing returns nothing
local iminmax_result imm = iminmax(GetHeroStr(my_hero, /*include-bonuses*/ true), GetHeroAgi(my_hero, /*include-bonuses*/ true))
// do something, idk, the higher stat deals damage, the lower heals the hero or something... doesn't matter
endfunction
Notice that there's a slight problem now, if iminmax was called more than 8190 times it will fail because we would run out of struct instances,
one way to fix that would be to force the caller to call the imm.destroy method, and that would work, but it's somewhat error prone and annoying.
In order not to force the caller to call .destroy we can use our own struct allocation scheme and thankfully vJass allows us to do that (via "extends array"):
JASS:
struct iminmax_result extends array // "extends array" instructs the vJass preprocessor (jasshelper.exe) not to create a default allocate/create method because we will write our own
integer min
integer max
static iminmax_result next_result = 0
// we can call our "create" method whatever we think makes the most sense
static method new_result takes nothing returns iminmax_result
set next_result = next_result + 1
if next_result >= 8191 then
set next_result = 1
endif
return next_result
endmethod
endstruct
function iminmax takes integer a, integer b returns iminmax_result
local iminmax_result result = iminmax_result.new_result()
if a < b then
set result.min = a
set result.max = b
else
set result.min = b
set result.max = a
endif
return result
endfunction
function use_iminmax takes nothing returns nothing
local iminmax_result imm = iminmax(GetHeroStr(my_hero, /*include-bonuses*/ true), GetHeroAgi(my_hero, /*include-bonuses*/ true))
// do something, idk, the higher stat deals damage, the lower heals the hero, or something... doesn't matter
endfunction
Good, now users of iminmax, can call it as much as they want and don't have to worry about "destroying" things.
Now, let's say we want to write the function rminmax which works the same way as iminmax but for real numbers not integers, well we could just
copy the iminmax struct rename it and it's members types and then go and write rminmax.
But notice that the code for the new_result method and the next_result variable will always stay the same, no matter what the other members of the result struct were.
We can avoid having to write/copy-paste this duplication by hand by using the module feature of vJass:
JASS:
module Result_Struct
static thistype next_result = 0
static method new_result takes nothing returns thistype
set next_result = next_result + 1
if next_result >= 8191 then
set next_result = 1
endif
return next_result
endmethod
endmodule
And now the rminmax_result struct would look like:
JASS:
struct rminmax_result extends array // we, again, don't want vJass's default methods
real min
real max
implement Result_Struct
endstruct
and the rminmax function
JASS:
function rminmax takes real a, real b returns rminmax_result
local rminmax_result result = rminmax_result.new_result()
if a < b then
set result.min = a
set result.max = b
else
set result.min = b
set result.max = a
endif
return result
endfunction
And that's basically it, we can now easily write functions that have multiple return values.