There is a new version of the forums ready for testing. Please post here if you're willing to help test! We could also use the help of coders!

Author Topic: Dynamically referencing a function  (Read 315 times)

Dynamically referencing a function
« on: 01 May 2022, 22:14 »
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.


Re: Dynamically referencing a function
« Reply #1 on: 01 May 2022, 22:17 »
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.

Re: Dynamically referencing a function
« Reply #2 on: 07 May 2022, 02:21 »
Cool! It's so awesome how much work is going into improving AGS over the years.

Re: Dynamically referencing a function
« Reply #3 on: 08 May 2022, 17:02 »
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: Adventure Game Studio
  1. function on_call(int fp)
  2. {
  3.     switch (fp)
  4.     {
  5.     case 1; foo(); return;
  6.     case 2: bar(); return;
  7.     case 3: baz(); return;
  8.     case 4: bork(); return;
  9.     …
  10.     }
  11. }

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: Adventure Game Studio
  1. import int ThingyGoesBoom;
In module.ASC
Code: Adventure Game Studio
  1. int ThingyGoesBoom;
  2. 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:
Code: Adventure Game Studio
  1. function CallTheUndertakers()
  2. {
  3.     …
  4. }
  5. function game_start()
  6. {
  7.     ThingyGoesBoom = 15;
  8. }

(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: Adventure Game Studio
  1. function on_call(int fp)
  2. {
  3.     if (fp == 15)
  4.         return CallTheUndertakers();
  5. }

This might feel as a bit of a kludge, but it works.
« Last Edit: 08 May 2022, 17:10 by fernewelten »