MakeArray.g — creates an array point from individual points.
![]() | The code for this and other example scripts can be found in the DataHub distribution archive, typically at one of these locations: C:\Program Files\Cogent\OPC DataHub\scripts\ C:\Program Files\Cogent\Cascade 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 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);
Copyright © 1995-2010 by Cogent Real-Time Systems, Inc. All rights reserved.