Dynamically referencing a function

Started by timid_dolphin, Sun 01/05/2022 22:14:11

Previous topic - Next topic

timid_dolphin

Is there anyway in AGS to dynamically reference a function?

Like in Javascript you can use a function as a argument for a function, or even put a function in a variable.

It would be cool if there was a pointer or something which could point to a function so that you could swap out blocks of code at runtime.


eri0o

there isn't right now. There's ongoing work to have delegates in AGS4, which is the C#-like approach. AGS4 will feature a new script compiler.

timid_dolphin

Cool! It's so awesome how much work is going into improving AGS over the years.

fernewelten

#3
In the meantime, you might be able to use the CallRoomScript() mechanism as a "poor man's function pointer".

Your rooms would have an on_call() event such as the following:
Code: ags

function on_call(int fp)
{
    switch (fp)
    {
    case 1; foo(); return;
    case 2: bar(); return;
    case 3: baz(); return;
    case 4: bork(); return;
    …
    }
}


Instead of keeping and passing around a function pointer variable that might point to foo() or baz(), as the case may be, you keep and pass around an integer variable that contains 1 or 3, respectively.

Let's say the integer variable is called MyPoorMansFunctionPointerInt. Instead of calling the function pointer, you'd go CallRoomScript(MyPoorMansFunctionPointerInt);. This would end up as a call to on_call(MyPoorMansFunctionPointerInt) of the respective room and its switch would convert this to a call to the corresponding function.


This is especially interesting if you are writing a module. You want to call a function whenever something happens, but you don't know what functions your module users want you to call. It should work for any function that the module user may want to configure. And the module users should not need to touch your module code in order to configure the function to call.

Well, make a global variable that is externally visible and call CallRoomScript() with that variable. Your module users can set this variable, e.g., in game_start() of GlobalScript.asc and then catch your calls in the on_call event of their rooms.

For instance, your module might have a global variable ThingyGoesBoom that the module calls whenever this has happened.
In module.ASH
Code: ags

import int ThingyGoesBoom;

In module.ASC
Code: ags

int ThingyGoesBoom;
export ThingyGoesBoom;


Whenever the module determines that the thingy has gone boom, it calls CallRoomScript(ThingyGoesBoom);

A module user might have a function CallTheUndertakers(). They want this function to be called whenever the thingy has gone boom. They code:
GlobalScript.ASC
Code: ags

function CallTheUndertakers()
{
    …
}
…
function game_start()
{
    ThingyGoesBoom = 15;
}


(The specific number 15 in the code above is arbitrary but should, of course, be unique for this purpose.)

In the rooms, near the end of the room code
Code: ags

function on_call(int fp)
{
    if (fp == 15)
        return CallTheUndertakers();
}


This might feel as a bit of a kludge, but it works.

SMF spam blocked by CleanTalk