Progress
ADM 2 Guide


Writing Super Procedures

Another task that you perform when you extend the ADM, whether by creating a new class or by customizing an existing class, is writing super procedures; that is, adding to the super procedure file custom functions and/or internal procedures that support the special behavior of your class. If you are creating a new class, you do this for the standard super procedure file; if you are customizing an existing class, you do it for the custom super procedure file.

Two important points to keep in mind when writing any functions or internal procedures that go into an ADM super procedure are:

References in Super Procedures to Other Procedures

When you write the functions or internal procedures that go into an ADM super procedure, keep in mind that there is nothing about a super procedure that identifies it as a super procedure. It is simply a Progress procedure file that is run as a persistent procedure and then added as a super procedure to some other running procedure. The source code or compiled r-code for a super procedure contains nothing special that identifies it as a super procedure.

What is special about a super procedure is the style of the code within its functions and internal procedures, which must account for the fact that these entry points are run on behalf of some other procedure. ADM super procedures must therefore always refer to the procedure on whose behalf they run. The basic mechanism is the TARGET–PROCEDURE built-in function, which evaluates to the procedure handle of the procedure from which the entry point was originally invoked. The {get} and {set} include files, which provide a pseudo-syntax for getting and setting ADM properties, support this mechanism by always referring back to the TARGET–PROCEDURE, so you should always use {get} and {set} when writing property references in super procedures. In addition, these include files identify whether a given property can be accessed directly out of the ADMProps temp–table record in the TARGET–PROCEDURE or instead requires the execution of the actual getpropname or setpropname function. For detailed information on these property mechanisms, see the "{get} and {set} Pseudo-syntax for Object Properties" and "Get and Set Functions for Object Properties" sections in SmartObject Interactions."

For example, an internal procedure that operates on the RowObject buffer handle of its TARGET begins by retrieving that property value:

DEFINE VARIABLE hRowObject AS HANDLE NO-UNDO.
...
{get Rowobject hRowObject}. 

Note that if you want to retrieve the value of a property from an object other than the TARGET–PROCEDURE, you can specify an optional final argument for the {get} and {set} include files that is the object’s procedure handle. For example, the following code gets the value of the EnabledTables property from the Data–Source of the TARGET–PROCEDURE:

{get DataSource hSource}.
{get EnabledTables cTables hSource}. 

You can also use the include file {fn} as a convenient way to invoke a function in TARGET–PROCEDURE; for example:

{fn openQuery}  /* invoke the openQuery function in my TARGET-PROCEDURE */ 

Similarly, the variant {fnarg} invokes a function that takes a single argument; for example:

{fnarg colValues pcViewColList}.  /* invoke the colValues function in my
                                     TARGET-PROCEDURE, and pass
                                     pcViewColList as the one input parameter. */ 

Shared Super Procedures

ADM super procedures are designed to be shared among all running instances of the SmartObjects that use that procedure.

NOTE: It is possible to create a super procedure that is intended to serve exactly one running procedure at a time, but this is not the correct design for super procedures that are part of the ADM class hierarchy and that are started in the standard way (that is, by running start–super–proc in the ADM include files).

Because ADM super procedures are shared, you must ensure that their code never assumes continuity between calls. If a particular operation involves executing two entry points in a super procedure, the code should not share property values between calls (whether by using local variables defined in the Definitions section or by using some other technique); instead, it should retrieve any property values that are needed at the top of each entry point. Although this might seem slightly inefficient, using {get} to retrieve a property value from the property temp–table compiles into a single in-line Progress 4GL ASSIGN statement and is quite fast. Using this technique assures that your super procedures can be shared among all running instances of your new class.

Likewise, because super procedures operate on behalf of other procedures, you must always PUBLISH events FROM TARGET–PROCEDURE. If you do not do this, your event will normally not have any effect, because the SmartObjects will not have subscribed to that event in the super procedure itself.

Also, when you invoke one entry point in a super procedure from another, you must preserve the value of TARGET–PROCEDURE in the called entry point. For example, suppose that your super procedure contains two procedures named ProcA and ProcB, and you want to run ProcB from ProcA in that super procedure. You have basically two choices, depending on whether ProcB is a PRIVATE internal procedure or function that should never be run from any other procedure, or an entry point that you might want to run or to override from its TARGET–PROCEDURE or some other procedure:


Copyright © 2004 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095