Passing function parameters by reference [SOLVED]

Started by paolo, Sat 19/01/2008 13:00:26

Previous topic - Next topic

paolo

How can I get function parameters to be passed by reference? I suppose I should first ask whether this happens anyway. If not, is the best solution to pass pointers to the variables instead?

I want to write a function like this:

Code: ags

bool foo(int x, int y)
{
    if (certain conditions not met)
        return false;
    else set x and y appropriately
        return true;
}


The reason I need to do this is of course that you can only return one value through the return type, and I need to make the function effectively return three values. I could use global variables, but I'd prefer not to.

In C++, I could make the parameter types int& or int* to do this. What is the best way to do it in AGS?

Thanks.

monkey0506

#1
You have limited options I'm afraid.

1) Add an additional parameter to control which value is returned. This is probably the slowest as it requires 3 calls to the function:

Code: ags
int foo(int x, int y, int ret) {
  bool cond = /* conditions are met */;
  if (cond) {
    /* set x & y */
  }
  if (ret == 0) return cond;
  if (ret == 1) return x;
  if (ret == 2) return y;
}


2) Use global variables. You specifically said you didn't want to do this, but since AGS doesn't support parameters by reference or pointers to "basic types" its one of the few reasonable solutions:

Code: ags
int gx, gy;

bool foo(int x, int y) {
  if (/* conditions not met */) return false;
  else {
    gx = x;
    gy = y;
  }
  return true;
}


3) Use a String as the return type. You could use null as the "false" flag, and otherwise just store the data into the String:

Code: ags
String foo(int x, int y) {
  if (/* conditions not met */) return null;
  // modify x/y as needed
  return String.Format("%d,%d", x, y);
}

// later
String s = foo(mouse.x, mouse.y);
if (s == null) return; // x/y not set properly, abort
String sx = s.Substring(0, s.Contains(","));
String sy = s.Substring(s.Contains(",") + 1, s.Length);
int x = sx.AsInt;
int y = sy.AsInt;


4) This option requires AGS 3.0 or higher You could use a dynamic array as the return value which could hold all three values:

Code: ags
int[] foo(int x, int y) {
  int i[];
  if (/* conditions not met */) {
    i = new int[1];
    i[0] = false;
  }
  else {
    i = new int[3];
    i[0] = true;
    i[1] = x;
    i[2] = y;
  }
}

// later
int i[] = foo(mouse.x, mouse.y);
if ((i == null) || (i[0] == false)) return; // abort if x/y not set
// do stuff with x (i[1]) and y (i[2])

paolo

Thanks - this is very useful.

In the end, I went for global variables as the simplest solution for what I want to do.

monkey0506

Actually I wanted to note that the String method was added as somewhat of an afterthought and would probably provide the best "non-global-variable" solution for AGS 2.72 and prior. However it would be slower than the global variable route.

Dynamic arrays (AGS 3.0+) would probably be the best "non-gv" route for AGS 3.0 and higher. Presumably slightly slower due to dynamic allocation, but not as slow as the String method.

But I'm glad you got it sorted out. Global variables probably are the overall best solution in this case.

Monsieur OUXX

Quote from: paolo on Sat 19/01/2008 13:00:26
How can I get function parameters to be passed by reference?


ha HA! I knew someone would need to do that one day  ;)
 

SMF spam blocked by CleanTalk