IGUANA
Interactive Graphics for User ANAlysis - (Version 6.13.0.g4.81)
Guide > Developer > How to > Create a Driver
 

Valid XHTML 1.0 Transitional
Valid CSS!
Browser compatibility
tested on:
Opera/9.10
Firefox/1.5.0.7
Safari/2.0.4
IE/6.0.2900



 Overview

IGUANA has a generic main program that simply loads the real main program -- an application driver -- and tells it to run. This how-to explains the steps required to create a new application driver. You might want to refer to the architectural description first however.
The steps to create an application driver are as follows:
This receipe assumes that you are using the IGUANA C++ templates (automatically available in our emacs customisation).

 Should you write a driver at all?

If you are developing the driver for IGUANA, please take a moment to consider whether it would better to make your class a service or an auto-loaded GUI extension working against the existing applications. We want to move towards one main IGUANA application that is able to bind with most of the functionality we provide.
Whether you develop in IGUANA or not, it is best to keep most of the functionality away from the driver in dynamically loaded extensions. This will allow your driver to load faster and begin to respond to user quickly, and allows the functionality to be extended easier. It is more work up-front however, so you are certainly welcome to prototype with a simple driver.
Please try to be smart about the packages you create however. We would rather not end up with many deleted or poorly named packages in CVS. If you are unsure of how to lay out your classes, we suggest you first work with packages only in your working area and check the packages into CVS only once you have a clearer idea. This will require a little more acrobatics to check the code into CVS at the end. You will have to move the code in your local area to some other name, create the new package as explained in the package creation how-to, check it out, and then copy your existing code into it.

 Define the driver class

Assuming that your new driver is to be called IgFooDriver, create interface/IgFooDriver.h in which you declare class IgFooDriver. Opening a new file with that name in emacs will automatically insert the header file and basic class structure if you are using our C++ customisation layer.
Your class should inherit IgDriver and define at least the constructor and override the run method. The factory will invoke the constructor with a pointer to an IgSession object as an argument; it should be stashed away, so declare a member variable as well. Other member variables depend on what your run method will do. For this sample you will not need any so your header should look something like this:
#ifndef IG_FOO_DRIVER_IG_FOO_DRIVER_H
# define IG_FOO_DRIVER_IG_FOO_DRIVER_H

//<<<<<< INCLUDES                                   >>>>>>

# include "Ig_Modules/IgFooDriver/interface/config.h"
# include "Ig_Framework/IgObjectBrowser/interface/IgDriver.h"

//<<<<<< PUBLIC DEFINES                             >>>>>>
//<<<<<< PUBLIC CONSTANTS                           >>>>>>
//<<<<<< PUBLIC TYPES                               >>>>>>

class IgSession;

//<<<<<< PUBLIC VARIABLES                           >>>>>>
//<<<<<< PUBLIC FUNCTIONS                           >>>>>>
//<<<<<< CLASS DECLARATIONS                         >>>>>>

class IG_FOO_DRIVER_API IgFooDriver : public IgDriver
{
public:
    IgFooDriver (IgSession *session);
    // implicit copy constructor
    // implicit assignment operator
    // implicit destructor

    virtual int		run (void);

private:
    IgSession		*m_session;
};

//<<<<<< INLINE PUBLIC FUNCTIONS                    >>>>>>
//<<<<<< INLINE MEMBER FUNCTIONS                    >>>>>>

#endif // IG_FOO_DRIVER_IG_FOO_DRIVER_H
	

 Implement the driver

Now implement the driver in src/IgFooDriver.cc. Opening a new file with that name in emacs will automatically insert the basic structure if you are using our C++ customisation layer.
Define the constructor as declared in the class. Normally you just stash away the session pointer into m_session.
You can do whatever you want in the run method: this is your main program. The architecture document describes the general conceptual structure; you might want to use the existing driver modules as an example. In this example we will simply create a simple Qt application window, resulting in a source file something like this:
//<<<<<< INCLUDES                                   >>>>>>

#include "Ig_Modules/IgFooDriver/interface/IgFooDriver.h"
#include "Ig_Modules/IgQtBrowser/interface/IgQtSite.h"
#include "Ig_Modules/IgQtBrowser/interface/IgQtAppExtensions.h"
#include "Ig_Framework/IgObjectBrowser/interface/IgSession.h"
#include "Ig_Framework/IgObjectBrowser/interface/IgPluginDatabase.h"
#include <qapplication.h>
#include <qwindowsstyle.h>

#undef emit // zap qt's placeholder macro
#include <classlib/debug.h>

//<<<<<< PRIVATE DEFINES                            >>>>>>
//<<<<<< PRIVATE CONSTANTS                          >>>>>>
//<<<<<< PRIVATE TYPES                              >>>>>>
//<<<<<< PRIVATE VARIABLE DEFINITIONS               >>>>>>
//<<<<<< PUBLIC VARIABLE DEFINITIONS                >>>>>>
//<<<<<< CLASS STRUCTURE INITIALIZATION             >>>>>>
//<<<<<< PRIVATE FUNCTION DEFINITIONS               >>>>>>
//<<<<<< PUBLIC FUNCTION DEFINITIONS                >>>>>>
//<<<<<< MEMBER FUNCTION DEFINITIONS                >>>>>>

IgFooDriver::IgFooDriver (IgSession *session)
    : m_session (session)
{ ASSERT (m_session); }

int
IgFooDriver::run (void)
{
    // Create a Qt application and main window, then install all usual
    // Qt application gadgetry into it.
    QApplication	qapp (m_session->args (), m_session->argv ());
    IgSite		*main = m_session->plugins ()->createSite
				("QMainWindow", m_session, 0);
    QWidget		*window = IgQtSite::selfFrom (main);

    qapp.setMainWidget (window);
    qapp.setStyle (new QWindowsStyle);

    IgQtAppExtensions::install (m_session, window);

    // Now auto-load all other GUI extensions.
    m_session->autoload ("Extensions/GUI/Qt/");

    // Make windows visible.
    window->setCaption ("Foo Application");
    window->resize (600, 400);
    window->show ();

    // Run the application.  This will run the Qt GUI event loop.
    return IgQtAppLoopService::instance (m_session)->run ();
}
	

 Add src/plugin.cc

We are now almost done. You still need to export the driver to the base architecture so that iguana can load and run it. Include first your IgFooDriver.h and then IgPluginDef.h and IgSimpleDriverFactory.h from Ig_Framework/IgObjectBrowser. Declare your plug-in class as described in the plug-in how-to. In the query method, declare your driver giving it a name that is to be given to iguana on command line. In the attach method install a factory for the driver. Your src/plugin.cc should now look like this:
//<<<<<< INCLUDES                                   >>>>>>

#include "Ig_Modules/IgFooDriver/interface/IgSoReaderAppDriver.h"
#include "Ig_Framework/IgObjectBrowser/interface/IgPluginDef.h"
#include "Ig_Framework/IgObjectBrowser/interface/IgSimpleDriverFactory.h"

//<<<<<< PRIVATE DEFINES                            >>>>>>
//<<<<<< PRIVATE CONSTANTS                          >>>>>>
//<<<<<< PRIVATE TYPES                              >>>>>>

class IgFooDriverPlugin : public IgPluginDef
{
public:
    virtual void	query (void);
    virtual void	attach (void);
};

//<<<<<< PRIVATE VARIABLE DEFINITIONS               >>>>>>
//<<<<<< PUBLIC VARIABLE DEFINITIONS                >>>>>>
//<<<<<< CLASS STRUCTURE INITIALIZATION             >>>>>>

DEFINE_IGUANA_PLUGIN (IgFooDriverPlugin);

//<<<<<< PRIVATE FUNCTION DEFINITIONS               >>>>>>
//<<<<<< PUBLIC FUNCTION DEFINITIONS                >>>>>>
//<<<<<< MEMBER FUNCTION DEFINITIONS                >>>>>>

void
IgFooDriverPlugin::query (void)
{
    declareDriver ("Foo");
}

void
IgFooDriverPlugin::attach (void)
{
    installDriver ("Foo", new IgSimpleDriverFactory<IgFooDriver>);
}
	

 Modify BuildFile

Modify your SCRAM BuildFile as described in the package creation and plug-in creation guides. In this case it should look something like this:
<Use name=Ig_Modules/IgQtBrowser>
<External ref=Qt>
<Export>
  <Lib name=IgFooDriver>
</Export>

include $(LOCALTOP)/$(projconfigdir)/plugin_makefile.mk
	

 Build the package

Follow the instructions in plug-in creation guide.

 Check the driver with iguana

Follow the instructions in plug-in creation guide. To execute the driver, give the name you registered in query as the second argument to iguana, like this:
$ eval `scram runtime -sh`
$ iguana Foo