#define FLAG_ON 1
var/flag = 0
#define TURN_ON_BITFIELD(X) THIS | X
flag |= FLAG_ON
flag = THIS | FLAG_ON
flag = TURN_ON_BITFIELD(FLAG_ON)
// all of those do the same
#define TURN_OFF_BITFIELD(X) THIS & ~X
flag &= ~FLAG_ON
flag = THIS & ~FLAG_ON
flag = TURN_OFF_BITFIELD(FLAG_ON)
// all of those do the same
var
a = 10
b = 20
c = 30
d = 40
a = b = c = d = THIS + a
// THIS will indicate the variable that's recently used to assign.
// "THIS" here means d, "40 + 10", so, a,b,c,d vars will get "50"
a = 2
a = THIS + THIS * THIS // 2 + 2 * 2
var/err = THIS + 10 // this throws error
world.log << "[THIS]" // this throws error
world.log << "[a = THIS + 20]" // this is fine
// first THIS = a, and second THIS = b
if(a = THIS + 10 && b = THIS + 15)
world.log << "a: [a] / b: [b]"
// type example
var/datum/something = new()
#define MAKE_NEW(X) (X == "make new" ? THIS.make_new() : THIS)
something = MAKE_NEW("still the same one")
something = MAKE_NEW("make new") // we get new one here
/datum/proc/make_new()
return new type()
< Why would we need this? >
This is basically a macro for macros, not for standard codes. You'll never use THIS macro in non-macro codes. This can be used to make sane macro codes.
Whenever you need to make a macro, you always need to include a variable to assign, and that makes people read codes a bit delayed to understand fully.
#define FLAG_ON 1
var/flag = 0
#define TURN_OFF_BITFIELD(X) THIS & ~X
flag = TURN_OFF_BITFIELD(FLAG_ON)
#define TURN_OFF_BITFIELD_VAR(FLAG, BIT) FLAG &= ~BIT
TURN_OFF_BITFIELD_VAR(flag, FLAG_ON)
The first one is better than the later one because it's good to read as we can notice there is assignment operator(=), and we can quickly understand the macro's behaviour is intended to assign a value.
in the example, even if we know what TURN_OFF_BITFIELD_VAR(FLAG, BIT) does, we don't instantly notice if the macro does assignment.
So, again, THIS macro is a macro for macros, not direct uses in standard codes.