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.