NAME

QGlobal - Internal PerlQt class, required by all other classes

SYNOPSIS

require QGlobal;

use QGlobal qw(...);

$object = new QClass->setImmortal

DESCRIPTION

The only relevant function in QGlobal (so far) is setImmortal(). It removes the tendency of Perl to free the memory used by an object when it goes out of scope. If you create say... a button that can live a life of it's own while within a subroutine, that button will be killed at the end of the subroutine without setImmortal().

Reading beyond this point implies that you care about the internals. Everything in here is subject to change at my whim (and probably already has).

Object internals

QGlobal is a repository for constansts requires by more than one independant class, and contains Qt::Base which is inherited by all Qt classes. Every Qt object has two vital hash elements, THIS and DESTROY. The THIS element holds the actual pointer to the C++ object represented in ram. PerlQt sub-classes all classes for convienience, access to protected members, and garbage-collection.

Internally, there are two types of sub-class types, the PClass, and the pClass. The pClass is availble only for classes which have protected or virtual members which are accessible via Perl. The PClass is the main sub-class type. Every class has a P version, and when a PClass is returned from an XS function, the DESTROY key is created and set to true. Only the existance of DESTROY is necessary to delete the object on destruction. PClass objects are returned from all constructors, and from all classes returning QClass & and QClass.

Object access

There are two functions that are universally useful and likely to be permanent. They are declared in pqt.h, and every class requires that header.

SV *objectify_ptr(void *ptr, char *clname, int delete_on_destroy = 0)

This function is used when you want to convert a class pointer to an object. NEVER, EVER, EVER try to convert a pointer to an SV manually!!! The internals are subject to change daily. And believe me, I've done it. This function is automatically used in the typemap.

The ptr argument is the object to be accessable in Perl. The clname argument is the name of the class. It is automatically modified so as to strip off any trailing garbage like spaces or *'s. That means macro conversions of pointer-types to strings are acceptable. In fact, that's how the typemap does it. The delete_on_destroy argument is pretty obvious. Just set it to a true value if you want the object to be deleted when it is destroyed.

void *extract_ptr(SV *obj, char *clname)

This does the opposite conversion from objectify_ptr. It will cause the program to croak if passed what it considers an invalid object. In XS files, the macro pextract(QClass, stackElem) is usually used to convert stack elements to pointers. It does automatic typecasting and ST() and clname.

Virtual functions

The way in which virtual function-calls from C++ to Perl are achieved is pretty simple at the moment. For every virtual function to be overridden, a function named QClass_virtualFunction is created in the QClass_virtualize class. There is a virtualize heirarchy mirroring the original QClass heirarchy, which passes virtual function guts along the way.

Since the PClasses don't inherit each other, the same virtual function must be overridden in all the sub-classes of the class with the virtual function as well, if you want people to sub-class those classes. Since every PClass which implements virtual classes inherits virtualize, all that is needed in the virtual override function is a stub which calls QClass_virtualFunction.

The QClass_virtualFunction itself just does a method-call to a perl object which was automatically saved when the object was created.

Every class has a #define QClass_virtual_functions, which contains a list of all virtual functions in that class. This, in turn, it placed in the class definition of PClass, and that PClass also inherits PClass_virtualize, thereby including everything necessary to successfully interface virtual functions.

Signals and slots

Once they are setup, signals and slots are pretty fast and efficient in Perl. The process of getting there is not.

The signals and slots for a class are accesible through %$signals::signals{QClass} and %$slots::slots{QClass}. These are filled in with use signals and use slots.

For every conection to a Perl QObject slot, a dummy pQtSigSlot object is created. It is given the object it is to be an interface to, and the slot-name it is supposed to call. The pQtSigSlot class holds all the stub functions to be used to call Perl methods. Mostly, those stub function just call the main functions, slot1(SV*), slot2(SV*,SV*), etc, with their arguments converted to their scalar values.

For every perl signal, a single dummy XS function is just given a new name. Since the CV* of a function is always passed to an XS function, it just sees which function-name it was called as, checks the %signals table for the signal to emit, and calls the relevant internal activate*() function.

All of the actual code for this is in QObject.xs from the main source-tree and sigslot.xs from libperlqt.

EXPORTED

QGlobal is a repository of globally useful constants/enums and functions for PerlQt.

Among these are %Align and it's friends, %Key and it's friends, %RasterOp, and %GUI.

CAVEATS

Everything will change.

AUTHOR

Ashley Winters <jql@accessone.com>