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

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

Warning: These instructions are not upto-date. Please re-visit this page in start of March 2004, these should be updated by then.
IGUANA has a number of multi-methods that bridge the application objects and the reps. Each such multi-method has a base method in IgBrowserMethods plus an extensible family of functions in plug-ins. Each method takes a main argument pair (for example, represent takes a pair <object, model> for which to create a rep); the method implementation selects from the family of functions the best match for the pair of actual arguments used. In this context, "best" means that no exact match is required -- the system uses the polymorphic nature of classes as one would expect.
Perhaps the important concept with these methods is that the family of functions varies based on which shared libraries are loaded. Thus, functions for a multi-method family need not be linked into the programs but can be put into separate IGUANA plug-in libraries. When dropped into the plug-in directories, IGUANA will automatically detect these libraries and load them on demand -- when objects of those arguments combinations are handled. It is therefore an advantage to split the rep mapping methods into fairly small granularity shared libraries. That way the minimum of code will be loaded, and even then only when it is actually needed. (Note that although the focus here is on lazy dynamic loading of extension code in shared libraries, IGUANA's plug-in mechanism is orthogonal to dynamic loading. It is possible to build plug-ins directly into the program itself, either fully so that it will never try to load anything dynamically, or partly so that some plug-ins are built into the program and others are loaded at run time.)
Multi-methods are not a native feature of C++, and hence are implemented by an additional library (classlib). We provide a number of preprocessor macros to make their use as simple and intuitive as possible. This guide explains both how to use and understand the macros as well as what the purpose of each method is. The methods available in IgBrowserMethods are explained below; each method consist of a pair: a front-end class-static function that should be used to call the method, and the multi-method itself.
  • represent/doRepresent: This method is used to create a rep for an application object (representable) into a browser model.
  • commit/doCommit: This method is used to commit changes made to a rep (in some browser) back into the application object. The change may apply to the whole object or only some part of it.
  • update/doUpdate: This method is used to update the existing reps of an application object when the object has changes.
  • expand/doExpand: This method is used to expand the representation of an object. It is used by browsers that construct a model for several objects lazily. When invoked, the method should create the "next level" of representations, whatever that means in the context of the model in question. For example, it could mean creating representations for the children of that object.
The functions for the multi-method families are usually "free functions" -- functions outside any class. That is, they are normally not members of the application object nor of the rep, but mediators between the two, and simply use the public interfaces of both classes to do their job. The package they are contained in normally links against both the application object library and the model libraries -- but typically not against the browsers that view the model.
Let us now describe the methods in more detail. The rest of this guide is divided into two parts, as shown below. The first part describes the steps required for writing a multi-method. The second part describes more precisely what functions in each method family should do.
This receipe assumes that you are using the IGUANA C++ templates (automatically available in our emacs customisation).

 Creating a multi-method

 Add src/plugin.cc

This is the main step of writing a new rep-mapping method. You should create a src/plugin.cc as is usual for plug-ins. In this file you need to do two things: define a new function for the multi-method family, and register the argument combination into the plug-in database as a capability. It is not necessary to define any new extensions or services -- the function extends the multi-method family simply by being present in a loaded shared library.
First you should add the following includes:
  • Include the headers of all the classes you use. This is at least the application object, the model and the rep type. You will most likely also need the header for IgRepContext and IgRepSet.
  • Include the xtypeinfo.h declarations for the types involved in the multi-methods: the application object, model and rep classes.
  • Include IgBrowserMethods.h from IgObjectBrowser.
  • Include typeinfo system header.
Go to the "public function definitions" section and define a new multi-method member (which is what "MMM" stands for). The multi-method family is the one that starts with do; for example, for represent the multi-method family is doRepresent. To declare a global free function as a member you should use the MMM_DEFUN_FUNC macro (use MMM_DEFUN_METHOD for class static methods). Note that despite all the macro sugar on top, you will be defining just a normal function -- the macro is there to hide implementation details.
The arguments of the macro are intended to read like a function prototype: return value, scope of the multi-method, its name, the actual argument list for this family member. The name would be for example doRepresent. The code for the declaration should look something like this:
MMM_DEFUN_FUNC(IgRepContext *,IgBrowserMethods::,doRepresent,
               (IgSoTwig *twig, Ig3DModel *model))
{
    // Code here -- see later for details
}
			
Next, you should declare the plug-in definition to declare the package capability so that library will be loaded when it is needed. Following the instructions in the plug-in creation how-to declare the capabilityh in the query method like this (note that the model comes first in this case!):
void
IgFooPlugin::query (void)
{
    declareCapability (IgBrowserMethods::key
		       (typeid (Ig3DModel).name (),
			typeid (IgSoTwig).name ()));
}
			

 Modify BuildFile

Nothing extraordinary here. You'll need dependencies on IgObjectBrowser and anything else you used. The BuildFile in the package root directory should now look like this:
<Use name=Ig_Framework/IgObjectBrowser>
<Use name=Ig_Modules/IgFooData>
<Use name=Ig_Modules/IgBarModel>
<Export>
  <Lib name=IgFooBarReps>
</Export>
			

 Build the package

You are now ready to build your plug-in with scram build. You should see your library linked against other libraries and a XML fragment created into the plug-in directory. Note that in IGUANA your package must be mentioned in the build order to build it from the top level. See the new package how-to for the instructions.

 Check the plug-in with iguana

Make sure the library loads properly as described in the the new plug-in how-to.

 Details on specific methods

 represent

FIXME: create a rep, then context for it; return the context. Don't use directly, use methods in IgRepSet instead (lookup)! An error to call this if rep already exists. If model maintains object relationships, have to careful to maintain them correctly here and in the rep. OK to return null if no rep can be created -- though better would be not to provide a method if it will always fail!

 commit

FIXME: commit changes from a rep back to object. Do use directly (usually from browsers or models). Can give sub-object detail (usually a field index -- but all users of the index must agree what they mean; FIXME: use object detail that will be shared with selection). remember to invoke update via methods in IgRepSet. Note that changes to parent object may require children to be updated too (but don't create reps if the children don't yet have them!).

 update

FIXME: update an existing rep for an object. Don't use directly, use methods in IgRepSet instead (update). An error to call this if no rep exists. FIXME: add single easy update method instead of two awkward ones. Additional argument tells what subfield originated the change, or zero if the whole object has changed (FIXME: object detail).

 expand

FIXME: expand object's contents (normally children in hierarchical views). Automatically IgRepSet::lookup kids' reps.