current stable:
0.99.6
unstable:
cvs (0.99.7)
General
  Home / News
  About
  Contact
  The Team

Obtaining
  Download
  Source Tarball
  CVS Web View
  Misc. Files

Documentation
  Introduction
The Manual
  Download [html]
  Download [pdf]
  View Online
API
  Download [html]
  View Online
Resources
  Script Examples

Developer
  Introduction
Developer Guide
  Download [html]
  Download [pdf]
  View Online
Ferite C API
  Download [html]
  View Online




Open Source Approved

SourceForge Logo
KwMap.net - browse the Keyword Map of ferite.org

[previous] Working With Objects And Classes[up][toc]Raising Exceptions and Reporting Errors [next]


Calling Functions

Variables are fun for a while, but when you want to start doing things, you will want to play with calling of functions. For this you will need one vital ingredient a pointer to a FeriteFunction.

Namespace Functions

Once you have a FeriteFunction *, the next thing you're probably going to want to do is call the function it to which it refers. This is one of the trickier things to do in ferite, but only because it involves several stages in order to complete.

Firstly, you need your FeriteFunction *, which can be obtained by using the ferite_find_namespace() function. Then you'll need to create a parameter list that you wish to pass to the function. This is done with the following function:

    FeriteVariable **ferite_create_parameter_list_from_data( FeriteScript *script, char *format, ... );
    				

This function does its best to make creating parameter lists simple. The first parameter is the script, the second is a format string that describes the types of variables that will make up the argument list, and the rest of the parameters are the values to be used as described by the format string. The format string must be zero or more of the following:

  • n - a number, the value passed must be a C variable of type double

  • l - a number, the value passed must be a C variable of type long

  • s - a string, the value passed must be a pointer to FeriteString

  • o - an object, the value passed must be a pointer to a FeriteObject

  • a - an array, the value passed must be a pointer to a FeriteUnifiedArray

The function will return a parameter list (FeriteVariable **) which can then be used as a parameter in the next function to be dicussed. For your information, a parameter list is simply a NULL terminated c array of FeriteVariable* - these are easy to create by hand, but this function simply aids the creation.

    FeriteVariable *ferite_call_function( FeriteScript *script, FeriteFunction *function, FeriteVariable **params );
    				

This function will call the function and return a FeriteVariable *, which will be the returned value of the called function. It must be caught and destroyed, or you will leak memory. Even functions returning void will return a fully allocated FeriteVariable * of type F_VAR_VOID.

The first parameter is the script, the second is the pointer to the FeriteFunction you wish to call, and the last is the parameter list you had created with the previously described ferite_create_parameter_list_from_data() function.

When you are finished with the parameter list, simply delete it with this function:

    void ferite_delete_parameter_list( FeriteScript *script, FeriteVariable **list );
    				

So there you have it, three steps to calling another function within ferite. Here is a complete example which calls 'Console.println' with the string 'Hello World':

    FeriteFunction *println = NULL;
    FeriteVariable **params = NULL;
    FeriteVariable *rval = NULL;
    
    /* Create a string to pass to the function */
    FeriteString *hello = ferite_str_new( "Hello World", 0, FE_CHARSET_DEFAULT );
    
    /* Find the function in the scripts main namespace */
    FeriteNamespaceBucket *nsb = ferite_find_namespace( script, script->mainns, "Console.println", FENS_FNC );
    
    if( NULL != nsb ) /* Check to see if we have the function ... */
    {
    	println = nsb->data;
    
    	/* Create the parameter list */
    	params = ferite_create_parameter_list_from_data( script, "s", hello )
    
    	/* Call the function */
    	rval = ferite_call_function( script, println, params );
    
    	/* And finally clear up after ourselves */
    	ferite_delete_parameter_list( script, params );
    	ferite_variable_destroy( script, rval );
    	ferite_str_destroy( script, hello );
    }
    else    /* We dont.. lets print an error! */
    	printf( "Cant find 'Console.println'! Is the console module loaded?\n" );
    				

It should be noted that the above method for calling functions works for any function that is not an instance method within an object. This will be discussed further in the next section as there are a couple of things the have to be done on top of the above steps.

Object and Class Functions

Calling methods of objects is much like calling regular functions. There are really only two differences.

Firstly, you look up the FeriteFunction * from within the object using the ferite_object_get_function() function, and you always pass the object itself as the last two parameters to the method, this must be done regardless of the number of arguments the object's function takes.

Example: (assume obj is of type FeriteVariable * and is a valid object)

    FeriteFunction *func = NULL;
    FeriteVariable **params = NULL;
    FeriteVariable *rval = NULL;
    
    func = ferite_object_get_function(script, VAO(obj), "function");
    params = ferite_create_parameter_list_from_data( script, "oo", VAO(obj), VAO(obj) );
    rval = ferite_call_function( script, function, params );
    ferite_variable_destroy(script, return);
    ferite_delete_parameter_list( script, params );
    				

As you can see, it's very similar to calling normal functions. You may also want to know that there is a helper function (used in the example below) for ensuring proper placement of the object in the parameter list called ferite_object_add_self_variable_to_params().

Example: (assume obj is of type FeriteVariable * and is a valid object)

    FeriteFunction *func = NULL;
    FeriteVariable **params = NULL;
    FeriteVariable *rval = NULL;
    
    func = ferite_object_get_function(script, VAO(obj), "function");
    
    /* Create an empty parameter list */
    params = ferite_create_parameter_list_from_data( script, "" );
    
    /* Add the 'self' variable to the parameter list */
    params = ferite_object_add_self_variable_to_params( script, params, VAO(obj) );
    
    rval = ferite_call_function( script, function, params );
    ferite_variable_destroy(script, return);
    ferite_delete_parameter_list( script, params );
    				

Calling methods of classes (static methods) is sort of a hybrid between calling normal functions and object methods. With classes you look up the FeriteFunction * from within the functions element of the FeriteClass struct using the ferite_class_get_function() function, and then you call it like a standard function. You do not pass the object to class methods because there is no object associated with the method. For all intents and purposes class functions within ferite are treated the same as namespace functions.

Here is an example: (assume klass is of type FeriteClass * and it is a valid class)

    FeriteFunction *func = NULL;
    FeriteVariable **params = NULL;
    FeriteVariable *rval = NULL;
    FeriteString *hello = ferite_str_new( "Hello World", 0, FE_CHARSET_DEFAULT );
    
    func = ferite_class_get_function(script, klass,"function");
    params = ferite_create_parameter_list_from_data(script, "s", hello);
    return = ferite_call_function(script, func, params);
    ferite_variable_destroy(script, return);
    ferite_delete_parameter_list(script, params);
    ferite_str_destroy( script, hello );
    				

And there you have it. You can now call class and object methods, and access variables within classes and objects.

Function Shortcuts



[previous] Working With Objects And Classes[up][toc]Raising Exceptions and Reporting Errors [next]
ferite et al © 2000-2004, Chris Ross