ID:2189056
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
Basically we need some easy way to capture a proc by name that fails on compile if the proc doesn't exist.

Could be something something simple like proc()

if (calltimer)
deltimer(calltimer)
calltimer = addtimer(src, proc(src.dostuff), 10, TIMER_NORMAL, arg1, arg2)


This is mainly for code that calls a proc dynamically using call()().

Right now for first class variables (variables that hold procs) the options are:
  • Use a string (no errors on compile if the proc stops existing or if you made a typo)
  • Find (and pass) the entire proc definition "/mob/living/carbon/human/proc/dostuff" (long, unwieldy, sometimes you have to work to find the proc if you know the name but not where it's defined, (ie, you have to do more work then just calling the proc normally, for no reason))
  • Use : or . path operators depending on if its a overriden proc, global proc, or a proc defined at this level (doesn't work on procs on base types like atom or movable since it works on the path, not the type)


If we had something that could take a proc by name, in the same fashion that you call a proc with, (thing.proc or proc) and return a path reference to that proc, it would make doing dynamic proc calls much easier, and allow us to stay true the concept that typos in code should lead to compile errors, not runtime errors.
Hmm. I'm not even sure how I'd go about something like this. It's an interesting question.
I mean, somewhere you have something to resolve proc names taking scope, type of calling thing (if any), and stuff into account. move that to a function if needed, and call it on a new bytecode.

The system can already convert /type/path/proc/procname to something that works with call()() so you would be looking at doing the reverse

call()() is already merged in with normal proc calls in the back end, so you could do the same trick to just make a new kind of call()() type that returns a valuetype containing the same thing that specifying /type/path/proc/procname contains

Why not borrow the scope qualifier from C++ and modify it to suit DM's wonky syntax?

global::var/variable //same as global.variable
global::proc/herp //returns a proc ref to a global proc

when used on a type, it will access the bottom-most named member:

/mob::var/name //returns the value of /mob/var/name
/mob::proc/Bump //returns a procref to /mob/proc/Bump

when used on an instance, it will access the bottom-most named member of the type provided:

var/mob/m
m::var/name //same as mob.name
m::proc/Bump //returns a procref to /mob/proc/Bump
m::verb/take //returns a procref to /mob/verb/herp
I use .proc/ProcName all the time when using my Event library, e.g.
EVENT_ADD(target.SomeEvent, src, .proc/HandleSomeEvent)

In your case, it would be .proc/dostuff.

I wasn't sure if it would work for inherited procs too, but it seems like it does in most cases:
world
mob = /mob/player

mob
proc
A()
world << "[src]: A"

player
proc
B()
world << "[src]: B"

Login()
var
a = .proc/A
b = .proc/B
call(src, a)()
call(src, b)()

It doesn't seem to work for built-in procs or procs defined in different trees; e.g. referring to /atom/proc/C as .proc/C from /mob won't work.

edit: On further testing, this actually seems to crash the game with a "BYOND Error: bad instruction" runtime error:
mob/verb/test()
world << "Testing..."
sleep 10
var a = Bump
call(src, a)()
world << "Done"

mob/Bump()
world << "[src]: Bumped!"
It doesn't seem to work for built-in procs or procs defined in different trees; e.g. referring to /atom/proc/C as .proc/C from /mob won't work.

Ya, thats the issue. If i replace "procname" in our code with something thats a direct reference, if or buts or other edge cases can't exist or i won't be able to get the other devs to follow suit.

We use parent_type in /tg/ in a few places, so our type trees aren't that flat.
bump