https://i.imgur.com/jOJwefa.jpeg
/datum/proc/StaticInitialize()
return
/datum/static_initializers/New()
var/static/already_run
if (already_run)
return
already_run = TRUE
var/start = world.time
for (var/init in typesof(/datum/static_initializers/proc))
if (copytext("[init]", 33, 36) != "SI_")
continue
var/init_type = call(src, init)()
if (world.time != start)
world.log << "[init_type] StaticInitialize slept!"
#define STATIC_INITIALIZE(type, tag) \
/datum/static_initializers/proc/SI_##tag() { \
call(##type, ##type::StaticInitialize())(); return ##type; } \
##type/StaticInitialize()
/datum/foo
var/static/name
STATIC_INITIALIZE(/datum/foo, A)
src::name = "foo"
world.log << "[src::name]"
/world/New()
..()
new /datum/static_initializers
world.log << "[(new /datum/foo).name] 2"
This works well enough given other limitations but the "tag" part of the macro is unpleasant. I find myself missing a source of magic values in the preprocessor that are valid as parts of signatures, be it proc name or path chunk.
Implementing a __COUNTER__ equivalent (see gcc doc) seems like a good neutral fit, and I can imagine a number of other use cases it would open up.