One question to Eleandor, why making a struct member private? I know that I make functions private because I don't want them to conflict with other functions, so I can for example have tons of private function Actions takes nothing returns nothing, but struct members can't conflict with anything, because it gets the prefix after the struct name, right?
Firstly because it's considered to be a rule amongst programmers. It's a design choice to hide the implementation of your structs.
Just look at units. To get the unit's hit points you must use GetUnitState(u, UNIT_STATE_LIFE). They've written a function that does this. They could have also just added something like set u.hitpoints = u.hitpoints +5, but then didn't.
Secondly because it can be the cause of bugs. To give a similar example with units:
If I could say:
set u.hitpoints = -1
Then the unit would
STILL be on the map, because u.hitpoints is nothing more than a variable. Still, it would be logical to assume a unit to be dead when he's got negative hit points, right?
SetUnitState() however takes care of other details too. On top of changing u.hitpoints, SetUnitState also checks if the new hitpoints are negative. If it's negative, SetUnitState will make sure the unit actually dies. Therefor, it is important that you, as the programmer of the new datatype, make sure that whoever uses the datatype uses it correctly, in order to avoid bugs.
Often it will still be useful to make members
readonly
. As you could guess from the name: this means you can "read" the member but cannot modify it (unless through methods). This allows you to safely retrieve info from a struct without screwing things up.
1) When I say a struct member, the word member does it include structs or just the standard variable-types ?
A struct member is... well, a member of a struct
JASS:
struct MyStruct
private integer var // this is a member
method Test takes nothing returns nothing // this is also a member.
endmethod
// Still, 90% of the time that we speak of structmembers, we refer to the variables, and not to the methods. Generally, the "variables" are the struct's members, and the "functions" are the struct's methods.
2) What is meant by class as in the manual:
structs and classes, while not being completely the same in many languages, are the same thing in jass. Well, technically, there's no such thing as a "class" in jass. But talking about classes and talking about structs is talking about the same thing.
3) What is the difference between static and instance ?
Let me give some examples to explain the terminology:
JASS:
struct Human
readonly string name
public static integer default_legs = 2
readonly integer legs = 2
method CarAccident takes nothing returns nothing
set this.legs = 1 // ouch
endmethod
endstruct
// ...
local Human eleandor = Human.create()
local Human starguizer = Human.create()
call eleandor.CarAccident()
call BJDebugMsg(I2S(eleandor.legs)) // display 1
call BJDebugMsg(I2S(eleandor.default_legs)) // display 2
set eleandor.default_legs = 1 // I know: wtf am I doing now?
call BJDebugMsg(I2S(starguizer.default_legs)) // display 1
A "Human" is a definition. It "defines" what a Human is. In this case, a Human is defined as something that has a name, and an amount of legs.
eleandor is called an "instance" of a human. eleandor behaves like a human, but has specific characteristics. In this case, I've had a caraccident which is why I only have 1 leg. But even though I have special attributes, I'm still a human. Because I'm able to have special attributes, I'm called an "instance" of a human.
You too are an "instance" of a Human.
eleandor.legs will clearly display "1", because I only have 1 leg.
eleandor.default_legs will show "2". default_legs is the same for every instance of "Human". It is an attribute of "Humans" in general.
If eleandor.default_legs would be changed into 1, starguizer.default_legs TOO will now be 1. However, starguizer.legs will still be 2.
static methods or static variables are variables that are "generic", they count for the whole struct type. normal methods/variables however perform specific actions on an instance of a struct. For example: a specific instance can have a car accident which changes that specific instance's legs.
The same is said for other variables:
local unit u = CreateUnit(...) // u is an "instance" of type "unit".
P.s. I still have both legs, this is just an example
P.p.s. ok, maybe that's a really strange example... but it's the best I can do
P.p.p.s. Indeed, "C" in your example is an instance of the "complex" type.
Am I totally wrong or are you wrong? I mean the INIT_TRIG_XXX activated the trigger to be runned on the map init. The function which is runned is the _Action function, but without the init trigger, the action function won't be runned, would it?
No, you're wrong (sorry
)
The InitTrig action runs on map initialization, regardless of whether you want or not. InitTrig makes sure the trigger itself gets initialized by adding events, conditions and actions to it.
Without the InitTrig function, there IS no trigger.
However, through 'run on map init', you can run the Actions, regardless of whatever you wrote in InitTrig.
Also, I don't understand the purpose of using interface ?
An interface is there so you can use the same rules for your structs. For example, if you implement:
JASS:
interface Creature
method moveTo takes real x, real y returns nothing
endinterface
struct Human extends Creature // Notice: a human "extends" a Creature. It means that a Human "is" a creature, just with some more specific features
method moveTo takes real x, real y returns nothing
// Do stuff to make the human move
endmethod
endstruct
struct Fish extends Creature
method moveTo takes real x, real y returns nothing
// Do different stuff to make the fish move
endmethod
endstruct
// Somewhere...
local Creature c = Human.create() // c is of type "Human" but can also be called "Creature" because a "Creature" is a more general way of calling you "Human".
local Creature d = Fish.create()
call c.moveTo(-2.0, 52.0)
call d.moveTo(-5.0, 50.0)
A struct that extends an interface inherits all of the interface's abilities (this means: a struct must have all the interface's members and methods), and is supposed to extend on this interface.
I personally don't use interfaces now that struct inheritance & stub methods are possible (read more on this further in the vjass manual).