The Dink Network

Returning values from external

May 27th 2020, 09:50 PM
dinkdead.gif
You can return values when calling a function in another script using external.
It's 2am but I feel this is amazing and should be shared! Immediately!

For some reason this only appears to work when using &return.

// Script test.c
external("test2", "thingy");
say_stop("&return", 1);
external("test2", "thingy", 1);
say_stop("&return", 1);
external("test2", "thingy", 7);
say_stop("&return", 1);

// Script test2.c
void thingy (void)
{
  int &t;
  &t = 123;
  &t += &arg1;
  return(&t);
}

Dink will say, as expected, "123", "124", "130".

If you assign to a variable as usual, it won't work:
// Script test.c
int &temp;
&temp = external("test2", "thingy");
say_stop("&temp", 1);
&temp = external("test2", "thingy", 1);
say_stop("&temp", 1);
&temp = external("test2", "thingy", 7);
say_stop("&temp", 1);
say_stop("wut", 1);

Weird things will happen: Dink will say "wut" and nothing else. The script execution seems to skip to the line after all these external() calls and then continue. Why the say_stop's in between don't happen I have no idea.

Tested in 1.08, Freedink 109.6 and Dink HD.
I am way too excited about this (probably because it's 2am... I mean 2.45...)
May 27th 2020, 11:20 PM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
Yep, I stumbled upon this when developing push and pull, and got just as excited =D

This is how I managed to limit the scripts that need to be edited to just 1 script, even though there's over 10 scripts that work to make this system function properly, which all do calculations based on the numbers inputted in the original script. Things just get processed differently depending on what sp_custom values the author sets and stuff and passed onwards to other externals, where they are altered and then the new value returned back into the original calling procedure for the calculation to continue where it left off.. this is sort of how the collision system works.
Stacking them works the same way:

// Script exttest.c
 external("test", "thingy", 1);
 say_stop("&return", 1);


//script test.c
void thingy(void)
{
 int &crap = &arg1;
 &crap += 1;
 external("test2", "thingy2", &crap);
 return(&return);
}


//script test2.c
void thingy2(void)
{
 int &crap = &arg1;
 &crap += 1;
 return(&crap);
}


Dink will say "3".

------------------------------------

I copied your script examples though, and for me the say_stop lines were not skipped in the second instance for me. Dink said "0" though, which is expected, because as in the DinkC reference, the external function itself does not return a value. As you discovered, you are actually returning a value using the pseudo variable &return, which indeed returns the last known return value from a function or procedure.

But it's exciting stuff.

May 28th 2020, 01:29 AM
custom_robj.png
Robj
Jester He/Him Australia
You feed the madness, and it feeds on you. 
Sorry for double post, but to keep this separate compared to the "value return" topic. Here's what else I've learned about external.. if you delve a little deeper.

Also, personally, I think it would make sense if external indeed did return an integer value of the script number as well, just like spawn does, because through testing, it is evident that a procedure called by external runs on it's own script number, and you can do some weird and wonderful stuff. That way you could still do the stuff in your first example with pseudo variable &return, but you could also use the &temp = external("script", "procedure"); to save the script number of the procedure being called. But yeh theres work arounds. In regards to how the script numbers are handled..

e.g:
//script exttest.c attached to a sprite on the screen
void main(void)
{
 say_stop("main &current_script", &current_sprite);
 external("test", "thingy");
 
 say_stop("Main again &current_script", &current_sprite);
}


//script test.c
void thingy(void)
{
 say_stop("test &current_script", &current_sprite);
}


Tested on screen with one sprite with exttest.c attached to it: Sprite will say "main 4", "test 5, "main again 4".

------------------------------------

Here's an example of something weird you can do since it runs on its own script number.. Alter where the original script will return to after external completes (Resume operation from a different location in the original script).

e.g:

//script exttest.c attached to a sprite on the screen
void main(void)
{
 external("test", "thingy");

 say_stop("I'll never say this!", 1);
}

void continue(void)
{
 say_stop("This say line will run first!", 1);
 
 //let's run a return to allow remainder of external procedure to finish processing.
 return;
 
 say("This say line will run third!", 1);
}


//script test.c
void thingy(void)
{
 int &crap = is_script_attached(&current_sprite);
 run_script_by_number(&crap, "continue");
 say("This is the second say line that runs!", &current_sprite);
}


I won't write which order the say lines are triggered, I made it obvious in the say lines
But as seen we can call a procedure with external, than retrieve the script number of the current sprite using is_script_attached, poke it to jump to the continue proc, it'll then run until it hits a return or wait, then the external proc will finish, and the original script resumes operation from where it left off in the continue proc instead.
June 21st 2020, 05:02 PM
custom_marpro.png
Marpro
Peasant He/Him bloop
 
Where's the damn "like" button!