next up previous contents
Next: General Methods Up: Some Functions and Methods Previous: Some Functions and Methods   Contents

Plug-in Interface

$\bullet$
QplugReturnStatus YourPlugin(QplugArgList *object_list),
This is your plug-in function that is called by qsas when the run button is pushed. The return value must be one of the enumerated values,
  typedef enum QplugReturnStatus_e {
    QPLUG_SUCCESS,
    QPLUG_WARNING,
    QPLUG_FAILURE
  } QplugReturnStatus;
with the obvious meanings. The function argument is a pointer to a C++ vector of QdObject_var objects. When the function is called it contains the input objects in the order they appear in the template file, and before return the output objects should be created and pushed back on to the end of this vector.

The QplugArgList has the standard methods defined for vectors in C++; useful examples are...

$\bullet$
size(), which returns an int giving the number of input objects, e.g.
    int n_inputs = object_list->size();
    if (nlist < 2){
     QplugAppendTextDisplay( "Not enough arguments from GUI\n");
     return QPLUG_FAILURE;
    }  //endif
$\bullet$
[n], an object on the input list can be dereferenced directly according to its position on the list (in the order they appear in the .qtpl template), starting from zero. Note, object_list is itself a pointer to the QplugArgList list and must itself be dereferenced first, (* object_list), so that (* object_list)[n] is the QdObject_var pointer at position n on the input list.
   QdObject_var input0 = (*object_list)[0];

$\bullet$
QdObject_var::narrow()

The objects passed to the plug-in are all QdObject_var pointers as this is the parent class for all qdos object types. It is necessary in most cases to narrow these objects to the actual type being handled.

The following example shows three ways to unpack the input.

   QdObject_var input0 = (*object_list)[0]; 
   QdTimeInterval_var ti = get_timeinterval(input0);

   QdRScalar_var input1 = QdRScalar_var::narrow((*object_list)[1]); 
   
   
   QdObject_var input2 = (*object_list)[2]; 
   QdRScalarSeq_var SS = QdRScalarSeq_var::narrow(input2);
   QdRMatrixSeq_var MS = QdRMatrixSeq_var::narrow(input2);
   if( !SS.is_nil() ){
       // operate on scalar input sequence
   }
   else if( !MS.is_nil() ){
       // operate on matrix (or vector) input sequence
   }
   else return QPLUG_FAILURE;

The first input is a time interval, and after creating a local pointer to the input object we use a utility call to create a time interval from it. This is a special case since it is possible to derive a time interval from a time series, a series of time tags or a time interval object, so a single utility call is provided (see below).

The second input object is a single scalar value and is narrowed on the fly while dereferencing the input list.

The third object may be either a scalar sequence or matrix (or vector) sequence, and after retrieving it from the input list we try to narrow to the possible input types. Note that the test is_nil() returns true if the input object is not of the requested type, so we negate it in the if() test. Tests on cartesian three vectors are described later. Note also that physical 3-vectors such as position or magnetic field vectors are stored as QdRMatrix objects, and utilities are provided to identify such objects and manipulate them (see below).

$\bullet$
push_back(QdObject_var output),
   QdRScalarSeq_var output;
   object_list->push_back( (QdObject_var) output);
places the output object on the list for return to qsas to be placed on the working list. It must be cast to a QdObject_var since this is the parent class to which all qdos objects belong.
$\bullet$
void QplugAppendTextDisplay(char *text), allows the plug-in to write messages to the plug-in message pane. e.g.
    #include "qplug_if.h"
    QplugAppendTextDisplay("Plug-in version 1.1, Nov 2001\n");
$\bullet$
char * QplugNewSTR( char * oldStr), creates a copy of the input string oldStr. It allocates the space using malloc, and the calling function is responsible for freeing the returned char * pointer afterwards. It is safe against a NULL input string, in which case it returns a null terminated empty string. The returned string is always safe to free. e.g.
    #include "qplug_if.h"
    char * text = QplugNewSTR("Plug-in version 1.1, Nov 2001\n");
    QplugAppendTextDisplay(text);
    free (text);
$\bullet$
char * GetSlotText( int n), gets a pointer to the text held in the n$^{th}$ output slot. This pointer should not be freed. The output slots count from 0, and are numbered in the order they appear in the .qtpl file. e.g.
    #include "qplug_if.h"
    char * out_name = GetSlotText(0);
    QuSetTxtAttr("FIELDNAM", out_name, out_ptr);
The output slot should contain the (possibly user entered) name of the output object to be created.
$\bullet$
void SetSlotText(int n, char * text), Sets the text held in the n$^{th}$ output slot that will be used to name the output object on the Working List. This function frees the previously held string before replacing it with new string text. The output slots count from 0, and are numbered in the order they appear in the .qtpl file. e.g.
    #include "qplug_if.h"
    char * out_name = GetSlotText(0);
    if (strcmp(out_name, "") == 0)
       SetSlotText(0, "DefaultName"); // ensure valid name
The output slot contains the name of the output object to be created. This function allows the user set name to be overridden. Changes do NOT appear in the GUI window, but a warning is written to the plug-in text pane when a change is detected.

$\bullet$
try{} catch(Exception &e){}, should be used whenever using qdos intrinsic operations since qdos will throw an exception whenever an operation is invalid or cannot be completed for any reason. For example,
#include "qplug_if.h"
#include "QdUtils.h"
#include "Qdos.h"
using namespace QSAS;
try{ 
  QdObject_var RadSquared = QuGetObjByName("RadiusSquared");
  rad_series = QdRScalarSeq_var::narrow(sqrt(RadSquared_var));
  if ( rad_series.is_nil() ) {
    QplugAppendTextDisplay("rad_series not a scalar series\n");
    return QPLUG_FAILURE;
  }
}
catch(Exception &e){
   e.print_msg();
   return QPLUG_FAILURE;   
}
In this example a scalar series on the Working List called ``RadiusSquared'' has been retrieved (see below) and the square root taken. If either the named object does not exist or the operation sqrt cannot be performed on it an exception is thrown and execution is passed to the catch statement which prints the QDOS error message and returns from the plug-in. Note that the narrow does not throw an exception, so it is still necesary to test is_nil() after the narrow. Several calls to qdos operations can be enclosed in a single try-catch block as any throw will go immediately to the enclosing catch without trying to complete other operations in the block.


next up previous contents
Next: General Methods Up: Some Functions and Methods Previous: Some Functions and Methods   Contents
Anthony Allen 2005-11-07