Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: DoorKnobHandle on Wed 24/03/2010 01:39:51

Title: Returning multiple values from function
Post by: DoorKnobHandle on Wed 24/03/2010 01:39:51
Are there any nice workarounds for when you have a function that does a bigger task and you need to return several basic variables (in my case, floats and ints)?

I didn't realize pointers to these types weren't allowed in AGS.

Usually I would create several functions that would all perform the task and just return a different variable but I'm talking about a process that is quite processor heavy and thus I really don't want people to have to call a function three times more than necessary just to get all the necessary values returned.

This is actually ultimately something for a plugin but that shouldn't really matter as the plugin-functions also have to follow AGS's script rules.
Title: Re: Returning multiple values from function
Post by: monkey0506 on Wed 24/03/2010 01:51:16
AGS can return a dynamic array from a function, so as long as all the variables you're returning are the same type then you could reasonably do:

Code (ags) Select
int[] some_func() {
  int arr[] = new int[5];
  arr[0] = 1;
  arr[1] = 5;
  arr[2] = 13;
  arr[3] = 27;
  arr[3] = 49;
  arr[4] = 74;
  return arr;
}


If you need mixed types of data you could consider using a String[] instead:

Code (ags) Select
String[] some_func() {
  String arr[] = new String[3];
  arr[0] = "5";
  arr[1] = "13.0";
  arr[2] = "text";
  return arr;
}


Since there's currently no way to retrieve the size of a dynamic array I also recommend padding the array if it's of variable size/content-formatting, such as:

Code (ags) Select
String[] some_func() {
  String arr[] = new String[4];
  arr[0] = "3"; // I tend to use the first slot in the array to indicate the number of actual items stored in the array
  arr[1] = "5";
  arr[2] = "13.0";
  arr[3] = "text";
}
Title: Re: Returning multiple values from function
Post by: DoorKnobHandle on Wed 24/03/2010 02:14:02
Ah, okay. I need floats and ints.

Well, putting that into a c++ plug-in is going to be a major pain in the behind (if it all possible).

Also, the way with returning a String[] is really, really user unfriendly for a plug-in designed to be used by the most people possible, I guess, right?

Hm, damn, doesn't sound too good.

Thanks though! :D

EDIT: Hang on, just had an idea. Couldn't I at least get it to work (even if not pretty and ultimately not what I'd want newer users to have to cope with) by just having my parameters be pointers to Strings? I'll try that out. I mean like this:


function DoSomething (String *destination, String *x, String *y )
{
   destination = "base";
   x = "5.5";
   y = "3";
}


Would that work?
Title: Re: Returning multiple values from function
Post by: monkey0506 on Wed 24/03/2010 02:36:47
Well String is internally declared as using an automatic pointer so if you put String* in AGS then it's going to convert it into String** which will cause an error at compile-time.

Also because of this behaviour, you can't change the value of a String passed as a parameter in AGS, so you would have to make it return a single modified String.

What you could consider doing is using a single string value with some form of delimiter and then just splitting the string based on that. That's the basic principle I built my Stack module on.
Title: Re: Returning multiple values from function
Post by: Crimson Wizard on Wed 24/03/2010 02:42:18
I would go for using formatted String as in monkey's Stack module, OR using dummy variables in global scope... If there are only 3-4 of them needed, that won't hurt a single bit.

PS. lol, just invented a gag. It won't hurt a single bit... it would hurt 8 bits, or how much do you need to store your return values  ;D :=
Title: Re: Returning multiple values from function
Post by: Khris on Wed 24/03/2010 09:33:23
As a cheap workaround:

float f, g, h;
int i, j, k;

void Module.CPU_killer() {
  ...
  f = result1;
  g = result2;
  h = result3;
  i = result4;
  ...
}

int Module.Get_i() {
  return i;
}


Not pretty but will do the job.
Title: Re: Returning multiple values from function
Post by: DoorKnobHandle on Wed 24/03/2010 14:29:20
That would work except in my case I'm dealing with a plug-in, not a module. ;D Those can't have global variables as far as I know.

Anyways, I have found another workaround. I basically have a structure in my plug-in that contains all the ints and floats I need to pass to the user. Then my main function is called once and internally creates one of these mega-structures (and returns an int-handle to the std::vector in the plug-in). The user can then use that handle to get the single values with various functions. Every frame the std::vector of structures are erased so they only stay valid for one frame.

Better than nothing, I guess, but one heck of an additional workload for something that trivial in nature. :D

I assume we have already pestered CJ about this enough, haven't we?