MakeArray.g

MakeArray.g — creates an array point from individual points.

Code

[Note]

The code for this and other example scripts can be found in the DataHub distribution archive, typically at this location:

C:\Program Files\Cogent\Cogent DataHub\scripts\

Please refer to Section 3.1, “How to Run a Script” for more information on using scripts.

/* This script creates an output array point from an input set of
 * individual points.  The array can be any reasonable length, though
 * the algorithm is not efficient for large arrays whose constituent
 * points change quickly.
 * 
 * The only part of the code that you need to alter to create your
 * own arrays is the MakeArray.constructor method.
 *
 * If a change is made to any individual point, the array will be
 * updated immediately.
 *
 * If a change is made to the array point, the change will not affect
 * the individual points that make up the array.  
 */

require ("Application");

/* Applications share the execution thread and the global name
 * space, so we create a class that contains all of the functions
 * and variables for the application.  This does two things:
 *   1) creates a private name space for the application, and
 *   2) allows you to re-load the application to create either
 *      a new unique instance or multiple instances without
 *      damaging an existing running instance.
 */
class MakeArray Application
{
}

/* Ensure that a point exists in the DataHub data store.  We do this
 * because the startup order of the DataHub instance vs. the data 
 * source is not necessarily predictable. By creating the point now, 
 * we are sure that it exists even if the data source starts later.
 */
method MakeArray.CreatePoint(pointname, type?=nil)
{
    datahub_command(format("(create \"%s\" 1)", pointname), 1);
    if (type)
        datahub_command(format("(set_canonical \"%s\" \"%s\" 1)",
			       pointname, type), 1);
}

/* Write the array based on the input point list.  There are more
 * efficient ways to do this if the array is large or the data
 * updates very frequently.  It may also be reasonable to do it on
 * a timer rather than every time any constituent point changes.
 */
method MakeArray.EmitArray(arraypoint, inputpoints)
{
    local	val = make_array(0), i=0, tmp;
    with point in inputpoints do
    {
        val[i++] = undefined_p(tmp =
			       eval(symbol(point))) ? 0 : number(tmp);
    }
    set (symbol(arraypoint), val);
}

/* This is a convenient function that declares an array point to
 * create from a set of input points.  You can create as many of
 * these array points as you need, using any number of input points.
 * Just put all of the input points into the argument list of
 * the call (see the call in the constructor below).
 *
 * The arraytype is a VARIANT array type: I1, I2, I4, R4, R8, BSTR,
 * UI1, UI2, UI4 followed by a space and the word "array".
 * E.g., "R8 array" or "BSTR array".AddCustomMenuItem
 * BSTR means "string".
 */
method MakeArray.DeclareArray(arraypoint, arraytype, inputpoints...)
{
    .CreatePoint (arraypoint, arraytype);
    with point in inputpoints do
    {
        .CreatePoint(point);
        .OnChange(symbol(point),
		  `(@self).EmitArray(#@arraypoint, #@inputpoints));
    }
	
    // After creating everything, call the EmitArray method once to
    // initialize the array.  We do this in case the constituent
    // points are already present in the data set when the script
    // starts.  Otherwise we would have to wait until one
    // of the points changes before the array gets initialized.
    .EmitArray (arraypoint, inputpoints);
}

/* Write the 'main line' of the program here.  Call the
 * .DeclareArray method one or more times to set up the event
 * handling to construct an array from individual points
 */
method MakeArray.constructor ()
{
    .DeclareArray ("default:pointarray", "R8 array",
		   "default:pointname1", "default:pointname2",
                   "default:pointname3");
}

/* Any code to be run when the program gets shut down. */
method MakeArray.destructor ()
{
}

/* Start the program by instantiating the class.  If your
 * constructor code does not create a persistent reference to
 * the instance (self), then it will be destroyed by the
 * garbage collector soon after creation.  If you do not want
 * this to happen, assign the instance to a global variable, or
 * create a static data member in your class to which you assign
 * 'self' during the construction process.  ApplicationSingleton()
 * does this for you automatically. */
ApplicationSingleton (MakeArray);