[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.18.3 Perl Bindings

Crystal Space is accessible from Perl in two ways: (1) as a Crystal Space plugin module in which C++ code can call upon Perl code, and in which Perl code can call upon Crystal Space; (2) as a pure Perl module named ‘cspace’ which one can ‘use’ from within Perl programs. To use the first option, load the ‘csperl5’ plugin as you would load any other Crystal Space plugin, and interact with it via the SCF interface ‘iScript’ (see section The iScript Interface). The second approach allows you to write Crystal Space applications entirely in Perl, without any C++ coding. The rest of this document pertains to the second method of using Crystal Space from Perl, though much of the discussion is meaningful to both methods.

As well as this document, there also exists an example Perl script located at ‘scripts/perl5/perlsimp.pl’. It is basically the tutorial application ‘simple1’ re-written in Perl, and it demonstrates many of the features discussed in this document.

To make use of Crystal Space classes from a pure Perl script, first make sure that the file ‘cspace.pm’ is available to Perl. This file is installed at:

${prefix}/share/crystalspace/bindings/perl5/cspace.pm

where ‘${prefix}’ is the location at which Crystal Space was installed (typically, ‘/usr/local’). If you have not installed Crystal Space, then you can find this file in the top level build directory after building the project (the ‘CS’ directory if you built and configured there). There are several ways to tell Perl where this file resides. One way is to use the ‘lib’ pragma within your Perl code:

 
use lib "$ENV{CRYSTAL}/share/crystalspace/bindings/perl5";

You can also use Perl's ‘-I’ command-line option to tell it the location of this file. Finally, you can set the ‘PERL5LIB’ environment variable so that it mentions the directory containing ‘cspace.pm’. If you are using the Perl SCF plugin, then the correct directory will already be in the include list, so you need only call iScript::LoadModule("cspace").

In addition to the ‘.pm’ file, there is also a shared library, ‘cspace’, which contains the low-level bindings between Perl and Crystal Space. On Unix and MacOS/X, this file is named ‘cspace.so’; on Windows it is named ‘cspace.dll’. The shared library file should reside in the same directory as the ‘cspace.pm’ file. This happens automatically when you install Crystal Space (via ‘make install’ or ‘jam install’). If you have not installed Crystal Space, then the shared library will be put in the top-level build directory, along with ‘cspace.pm’. The preferred location is ‘scripts/perl5/’, and ‘cspace.pm’ and ‘cspace.so’ can be copied there by doing ‘jam perl5freeze’ and ‘perl5freezeobj’ respectively.

To actually utilize Crystal Space from within your script, begin with:

 
use cspace;

You may also import symbols and classes from the cspace module using the standard Perl syntax, for example:

 
use cspace qw(csVector3 csMatrix3 CS_QUERY_REGISTRY SCF_QUERY_INTERFACE);

Classes will be imported into the main:: namespace, while other symbols will be imported into the namespace of the current package. This will enable you to use these symbols and classes without using the cspace:: prefix.

Getting Started

To get started with pure Perl scripts, you probably want to know how to initialize Crystal Space and obtain an ‘iObjectRegistry’ pointer:

 
my $object_reg = cspace::csInitializer::CreateEnvironment([$0, @ARGV]);

If you are utilizing the Crystal Space Perl bindings module from within the Perl scripting plugin ‘iScript’ implementation, and CreateEnvironment() has already been called by C++ code, then the ‘iObjectRegistry’ will already be accessible to Perl code through $cspace::object_reg.

Objects

To create an object instance, use the ‘new’ method:

 
my $vect = new cspace::csVector3(1, 2, 3);

The object will be deleted automatically when it goes out of scope. Perl also has built-in reference counting, so if the object is still referenced in some other Perl code when one reference goes out of scope, it will continue to exist until there are no more references to it in Perl.

There are three ways to access object properties:

 
print $vect->x;			# Preferred way, conforms to Perl convention
print $vect->{'x'};		# Swig default way
print $vect->swig_x_get();	# Swig alternate way

And, three ways to modify object properties:

 
$vect->x(3.14);			# Preferred way, conforms to Perl convention
$vect->{'x'} = 3.14;		# Swig default way
$vect->swig_x_set(3.14);	# Swig alternate way

Calling methods works as you might expect:

 
$vect->Norm();

Arrays

Wherever an array is expected, and wherever an array is returned, in or from a Crystal Space C++ function, a Perl array reference is used.

Strings

Most of the methods of ‘csString’ and ‘iString’ are inaccessible from Perl code, but these classes can be converted into Perl strings very easily, using string interpolation:

 
my $string_object = new cspace::csString ('This is a csString');

print "$string_object that has been interpolated in double-quotes.\n";

# Output:
# This is a csString that has been interpolated in double-quotes.

This also applies to ‘iDataBuffer’.

To pass the null pointer as a char* argument, use Perl's undef keyword.

Vectors, Matrices and Colors

By using the array dereference operator on a ‘csVector2’ or ‘csVector3’, one will obtain a Perl array containing the components of the vector:

 
my $vector = new cspace::csVector3 (1, 2, 3);

print $vector->[0] . $vector->[1] . $vector->[2] . "\n";

my @reversed = reverse @$vector;
print "@reversed\n";

# Output:
# 123
# 3 2 1

Similarly, using the array dereference operator on a ‘csColor’, ‘csColor4’, ‘csRGBcolor’ or ‘csRGBpixel’ will yield a Perl array containing the red, green and blue components, and the alpha component if present.

With a ‘csMatrix2’ or ‘csMatrix3’, the array dereference will return a Perl two-dimensional array ("array of arrays") holding the components of the matrix.

Operator Overloading

The Crystal Space Perl module supports the following overloaded operators for objects: + - * / % ++ -- == != > < && ||

Those declared in C++ as friend functions will not be available.

Interface Pointers

Suppose you call a function that returns a pointer to some SCF interface. You can store the returned value in a variable, and use it similarly to how objects are used in Perl (see above). You can call methods in the same way, and pass them on to other functions as arguments where appropriate.

The Perl bindings automatically and correctly handle csRef<> and csPtr<>.

The null pointer is represented in Perl by the undef keyword.

Event Handling

In C++, the class method csInitializer::SetupEventHandler(object_reg, func_ptr, event_types) allows one to register a function pointer callback that will be called by the event queue when handling certain types of events. In Perl, a subroutine reference may be passed to this method in place of the function pointer.

This subroutine, when called, will be passed a single parameter: an object of type ‘iEvent’. It is expected to return true if the event was handled, or false if it was not.

The third parameter to SetupEventHandler is optional, and will be a reference to an array of strings specifying event types. These strings will automatically be translated into ‘csStringID’ using the event name registry. If not specified, all types of event will be passed to the callback.

Implementing Interfaces

You can write your own Perl class and have it inherit from a Crystal Space interface, then use instances of that class wherever an implementation of that interface is expected. Currently this feature is supported for the interfaces ‘iEventHandler’ and ‘iEventPlug’ but it is easy to add support for more.

 
package MyPerlEventHandler;
@ISA = qw( cspace::iEventHandler );
sub new
{
  my $x = {};
  bless($x, "MyPerlEventHandler");
  return $x;
}
sub HandleEvent
{
  my ($self, $event) = @_;
  # your event handler here...
}

package main;
my $eventq = cspace::CS_QUERY_REGISTRY($object_reg, "iEventQueue");
my $handler = new MyPerlEventHandler ();
$eventq->RegisterListener($handler);

Special Cases

Take note of the following special cases.

Macros Accepting Interfaces as Parameters

In Perl, Crystal Space macros that take interface names as parameters—for instance CS_QUERY_REGISTRY()—take interface names as strings:

 
my $engine = cspace::CS_QUERY_REGISTRY($object_reg, 'iEngine');

This differs from the CS_QUERY_REGISTRY() macro in C++ in which ‘iEngine’ would not be quoted.

csRGBpixel

To convert a ‘csRGBpixel’ to a ‘csRGBcolor’, use the csRGBpixel::asRGBcolor() method:

 
my $color = $pixel->asRGBcolor();

iSprite2DState

‘iSprite2DState’ has an extra method in Perl, GetVertexByIndex(), which accepts a single integer parameter (an array index) and returns a ‘csSprite2DVertex’ from the sprite's array of vertices.

iEvent

The overloaded iEvent::Add() and Retrieve() methods are replaced in Perl with ones given names which explicitly specify the types of their parameters (since otherwise Perl would not know which C++ function to call):

Renamed Methods

To workaround some shortcomings of Swig, a few methods from C++ have been renamed for Perl. These are:


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated using texi2html 1.76.