CallFunction

CallFunction
void CallFunction(string funcname, ... args)

Documentation

Note: As of Verge 3.1, there is a feature called string invocation which basically makes it even simpler to call functions.

Calls a function by name. This can be useful for creating "function tables" of a sort, which might be useful for item effects or magic visual effects or things like that.

The function to be called MUST be passed the correct number of parameters (before Verge 3.1 you could only call no-parameter functions). It may or may not return void, but it is impossible to catch the return value when called this way.

If you wish to simulate return values, it is neccesary to use a global variable for this role. Be careful in doing this, as it leaves a lot of room for user error. I would suggest heavy error checking within the functions, unless the CallFunc is something that's being called frequently.

If the specified function name does not exist, or is a v3 builtin function, CallFunction() will just do nothing (no error messages). If you care that a function exists, please refer to FunctionExists().

Example Usage

//
// A simple example.
//

void MyFunc()  
{ 
	exit( "Hello world!" );
}

void Autoexec()
{
	CallFunction("MyFunc");
}


//
// A more complicated example illuminating the possibilities of this function
//

void FuncA()  
{ 
	log( "Function A was called!  Eeeeh!" );
}

void FuncB()  
{ 
	log( "Function B was called! Bzzzz..." );
}

void Autoexec()
{
	int i, j; //for the for-loop lower down...
	
	// let's make a lookup table
	string MyLookupTable[2]; 
	
	// and now we initialize it...
	MyLookupTable[0] = "FuncA";
	MyLookupTable[1] = "FuncB";
	
	//and now let's set up a silly way to make it look things up
	for( i=0; i<100; i++ ) 
	{
		//j will be randomly set to 0 or 1 each iteration of this loop
		j = Random(0, 1);
		
		CallFunction( MyLookupTable[j] );
	}
}

// Another example! Only compatible with Verge 3.1 or higher.
// Showing argument passing this time.
// Also shows string-calling.
void MyFunc(int value)
{
	Log("It's a " + str(value) + "!");
}

void AutoExec()
{
	// Passing arguments.
	CallFunction("MyFunc", 3);

	// Note that the following syntax is identical:
	// You might like this more!
	string func = "MyFunc";
	func(3);
}
Talkback

Post a new comment?

Talkback #1 written by maripoga on 2005-04-03.


// This is a simple example of how to streamline CallFunction so that you can
// pass arguments easily and not have to worry about global variables getting
// confused -- say, if CallFunction is called simultaneously by both a normal
// function and a hooked function.
//
// This example implements some simple LIFO (last-in, first-out) stacks, using
// VC arrays. PushInt and PushString "push" values onto the "top" of the
// stacks, and PopInt and PopString remove those values from the top and
// return them. These helper functions will work on any arrays (as long as
// the first entry in the array is the size of the stack) but they are used
// here to store arguments and return values. This way, even if a
// CallFunction()"ed function is interrupted by a hooked function that uses
// CallFunction(), the hooked function will always leave the stack exactly as
// it found it -- even if IT is interrupted by yet ANOTHER hooked function.
//
// Usage is simple: before calling the function, use PushInt or PushString
// to "push" argument values onto the argument stacks ("IARGS" for
// integers, "SARGS" for strings).
// When the function is called, it should use PopInt and PopString to remove
// those values (remembering that they are removed in the reverse order they
// were applied). This leaves the stack as you found it.
// If the function is returning a value, it should then use PushInt or
// PushString to push its return value onto the return value stack. ("IRVALS"
// for integers, "SRVALS" for strings.) Note that this makes it possible to
// return as many values as you want (as long as you remember to take them all
// off -- and in the reverse order they went on).
// When the function is done, the return value(s) can be retrieved by using
// PopInt and PopString on "IRVALS" or "SRVALS".


// The maximum number of entries in the stack:
#define MAX_STACK_SIZE 40 // 1st entry stores size, so this holds 39

// The names here are shortened because they"ll have to be typed so often
// and capitalized so that they vaguely resemble registers.
int IARGS[MAX_STACK_SIZE]; // A stack of Integer Arguments
string SARGS[MAX_STACK_SIZE]; // A stack of String Arguments
int IRVALS[MAX_STACK_SIZE]; // A stack of Integer Return Values
string SRVALS[MAX_STACK_SIZE]; // A stack of String Return Values

// This initializes an integer stack
void InitIntStack(string stack_name) {
SetIntArray(stack_name, 0, 0); // Set the first entry (size) to zero
}

// This initializes a string stack
void InitStringStack(string stack_name) {
SetStringArray(stack_name, 0, str(0)); // Set the first entry to "0"
}

// This pushes an integer onto the top of an integer stack called <stack_name>
void PushInt(string stack_name, int value) {
int size = GetIntArray(stack_name, 0); // Grab the current size (1st Entry)
if(size < MAX_STACK_SIZE-1) { // If there is room in the stack for more
SetIntArray(stack_name, size+1, value); // Add this value to the top
size++; // increase the size
SetIntArray(stack_name, 0, size); // and store it (1st entry)
}
else { // Otherwise
Exit("Integer stack overflow of stack "
+ stack_name + "."); // Crash out
}
}

// This pushes a string onto the top of a string stack called <stack_name>
void PushString(string stack_name, string value) {
int size = val(GetStringArray(stack_name, 0)); // Grab the current size (1st entry -> int)
if(size < MAX_STACK_SIZE-1) { // If there is room in the stack for more
SetStringArray(stack_name, size+1, value); // Add this value to the top
size++; // Increase the size
SetStringArray(stack_name, 0, str(size)); // and store it (1st entry -> str)
}
else { // Otherwise
Exit("String stack overflow of stack "
+ stack_name + "."); // Crash out
}
}

// This function returns the top value off of <stack_name> (and deletes it from the stack)
int PopInt(string stack_name) {
int size = GetIntArray(stack_name, 0); // Grab the current size (1st entry)
if(size > 0) { // If there is anything on the stack
size--; // Reduce the size by one
SetIntArray(stack_name, 0, size); // Store it
return GetIntArray(stack_name, size+1); // and return the top value
}
else { // Otherwise
Exit("Attempt to pop empty integer stack "
+ stack_name + "."); // Crash out
}
}

// This function returns the top string off of <stack_name> (and deletes it
// from the stack)
string PopString(string stack_name) {
int size = val(GetStringArray(stack_name, 0)); // Grab the size (1st entry -> int)
if(size > 0) { // If there is anything left
size--; // Reduce the size by one
SetStringArray(stack_name, 0, str(size)); // Store it
return GetStringArray(stack_name, size+1); // and return the top value
}
else { // Otherwise
Exit("Attempt to pop empty string stack "
+ stack_name + "."); // Crash out
}
}

// This function takes a string and a number of times to repeat it, and
// returns a longer string. It would be written:
// "string RepeatText(string repeat_text, int repetitions) { ... }",
// but since it will be called with CallFunction, it will take its parameters
// from the stack. MAKE SURE TO POP VALUES OFF A STACK IN THE OPPOSITE ORDER
// YOU PUSHED THEM ON.
void RepeatText() {
int repetitions = PopInt("IARGS"); // Grab the first int arg
string repeat_text = PopString("SARGS");// Grab the first string arg

int i; // A generic counter
string out_text = repeat_text; // this is the output value

for(i=1; i<repetitions; i++) {
out_text = out_text + repeat_text; // keep adding copies
}

PushString("SRVALS", out_text); // Load the return value
}

void autoexec() {

// First we initalize all the stacks we"re going to use.
InitIntStack("IARGS");
InitIntStack("IRVALS");
InitStringStack("SARGS");
InitStringStack("SRVALS");

//Each simulated "function call" then consists of
// A) Loading arguments onto SARGS or IARGS
PushString("SARGS", "BLAH "); // Push the first string arg
PushInt("IARGS", 512); // Push the first int argument

// B) Calling the function
CallFunction("RepeatText");

// and C) Accessing the return value(s) from SRVALS or IRVALS
Exit( PopString("SRVALS") ); // Echo the return value & close
}

Post a new comment?

Ben McGraw's lovingly crafted this website from scratch for years.
It's a lot prettier this go around because of Jon Wofford.
Verge-rpg.com is a member of the lunarnet irc network, and would like to take this opportunity to remind you that regardless how babies taste, it is wrong to eat them.