Classes events
The events are calls made automatically by the supervisor to handle various events and change the default standard behavior of the supervisor layers through additional lines of code.
This document describes how events are called and their context.
Take care that in V11, the labels and variables used in the scripts associated to the class and representation events have been changed in order to clarify and simplify their management. The label
FOR COMPATIBILITY REASONS, THE PREVIOUS LABELS ($PROPERTIES and $ACTION) ARE STILL USABLE IN U10, BUT THEY WILL BE DEPRECATED IN V12. IT IS THEREFORE RECOMMENDED TO MODIFY THE SCRIPTS QUICKLY. |
In the Scripts section of the class dictionary, the development partner can define a list of ordered scripts (standard, vertical, or specific). In every script, four labels called $EVENTS
, $METHODS
$OPERATIONS
and $PROPERTIES
must exist:
$PROPERTIES
, we manage the events linked to properties methods (rules).$EVENTS
, we manage the global events associated to the class standard methods?$METHODS
, we manage the additional methods defined.$OPERATIONS
, we manage the additional operations defined.Note: the previous labels $ACTION and PROPERTIES that made the triage to rules, methods or operations is now obolete.
When the control is given to one of these labels through a Gosub
instruction, some variables are available to define the calling context:
ARULE
is a character string that provides the rule executed.AMETHOD
and AOPERATION
are character strings used respectively for defining the method and operation requested.CURPTH
is a character string that provides the class path used for child class, which is explained later in this document (only for standard events).CURPRO
is a character string variable that provides the property concerned (only for rules).The ARULE
value is used for properties and can be one of the following:
* INIT
, GET
, CONTROL
, PROPAGATE
for the rules.
The AEVENT
value is used for standard events and can have the following values:
* AINSERT
, AREAD
, AUPDATE
, ADELETE
only for the persistent class if the standard corresponding CRUD operation is not generated.
* Other codes such as AINSERT_CONTROL_BEFORE
, corresponding to events allowing a development partner to add code at a given step of the standard CRUD operations. These event have a name that start systematically with a A.
When a standard event is called for an instance of a child class, it is called as many times as the level is nested. For instance, it is called two times with a single level of nesting:
CURPTH
identifying the complete path to the child class element) thus allowing to complete the event.When a rule is called for an instance of a child class, it is also called as many times as the level is nested; but in this case, CURPTH
is not used : the path is given in CURPRO
depending on the current level. For example, in the header script, CURPRO
will be equal to "LINES.PROPERTY", while in the line script, CURPRO
will be equal to "PROPERTY".
In the code associated to $PROPERTIES
, $EVENTS
, $METHODS
and $OPERATIONS
labels, the development partner has access to different properties. Some of them are defined at calling time by the supervisor, and others are defined as additional properties in the class that are not defined in the class dictionary.
Be aware that this code is called through a Call
instruction FOLLOWED BY A Gosub
. Thus, the scope of the local variables declared in an event code is limited to the event where it is called. For example, when a sub-program is called by the $PROPERTIES
event, a local variable declared in that event is not visible for the next one:
$PROPERTIESCase [L]ARULEWhen "INIT"...When "CONTROL"Local Integer MY_VARIABLE...When "PROPAGATE"# Even if PROPAGATE rule is called once the CONTROL is successful, MY_VARIABLE is not visible hereWhen "GET"...EndcaseReturn
A normalization exists for the Sage X3 script files names declared in a class:
This section describes the different events available in standard CRUD operation performed on a persistent class.
These events are called on the methods previously defined through an Fmet
instruction, followed by Gosub
calls on every script associated to the classes and/or representations in the dictionary, in the order where they are defined. Depending on the type of event, a different label is called:
$EVENTS
label is called for the standard events associated to standard methods$METHODS
and $OPERATION
labels are called for methods and operations defined at class or representation level.$PROPERTIES
label is called for the rules defined on the properties of classes or representations.Usually, a script containing the code of the event looks like this:
########################################################################################################### EVENTS##########################################################################################################$EVENTSCase CURPTHWhen ""Case AEVENTWhen "event_name"Gosub METHOD_LABEL : # "event_name" is the standard event to be handled, and METHOD_LABEL the corresponding labelEndcaseEndcaseReturn########################################################################################################### RULES##########################################################################################################$PROPERTIESCase [L]CURPROWhen "property_path"Gosub PROP_LABEL : # "property_path" is the property path to be handled, and PROP_LABEL the corresponding labelEndcaseReturn# Example of rules handling (only the rules used are usually defined)$PROP_LABELCase [L]ARULEWhen "INIT" : # Init method...When "CONTROL" : # Control method...When "PROPAGATE" : # Propagatin method...When "GET" : # Get method...When "AINIT" : # Init method...When "AINIT" : # Init method...########################################################################################################### METHODS##########################################################################################################$METHODSCase [L]AMETHODWhen "method_name"Gosub METHOD_LABEL : # "method_name" is the method to be handled, and METHOD_LABEL the corresponding label...EndcaseEndcaseReturn########################################################################################################### OPERATIONS##########################################################################################################$OPERATIONSCase AOPERATIONWhen "operation_name"Gosub OPERATION_LABEL : # "operation_name" is the operation to be handled, and OPERATION_LABEL the corresponding labelEndcaseEndcaseReturn
Type of events | Calling conditions | Details | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Global AINIT event | Global event that is called at the end of the AINIT method (all the INIT rules associated to the different properties have already been called). | This event is called by the supervisor:
If the developer creates a line in a script, the AINIT method must be called manually after the class instantiation. This calls performs all the init rules on the properties (ARULE has a value equal to INIT), and ends with the event AINIT (AEVENT as a value equal to AINIT). | ||||||||||||||||
Global ACONTROL event | Global event that is called after all the CONTROL rules associated to the different properties have been called. | This event is called by the supervisor before an insert or an update:
| ||||||||||||||||
CRUD operation events | Called by the corresponding standard methods (AINSERT, AREAD, ADELETE, AUPDATE) on a class when the check boxes associated to the CRUD methods are not set in the class dictionary. The code of the event has to store or retrieve the data. If the boxes are set, the code that updates the database is generated at class validation and the event is not called. |
| ||||||||||||||||
CRUD control events | Called when a CRUD operation is performed (AINSERT, ADELETE, AUPDATE). The CRUD methods can be called:
|
| ||||||||||||||||
CRUD update events | Called when a CRUD operation is performed (AINSERT, ADELETE, AUPDATE). The CRUD methods can be called:
A database transaction is in progress to update the data when these events are executed. Setting an error will abort the transaction and trigger the rollback events. |
| ||||||||||||||||
CRUD error handling events | Called only when errors occur during the transaction execution. A rollback is performed, and then the control is given to the event to perform additional operations if necessary. |
| ||||||||||||||||
CRUD collection handling events | Called on the management of lines in collections (when the ADDLINE or ADELLINE standard methods are called). These methods can be called:
|
| ||||||||||||||||
CRUD read events | Called when the read method is called (in a script, or automatically from a version 7 native page). |
| ||||||||||||||||
Query events | Called during queries (no working copy is available; therefore, "This" is not available). The query is defined in the calling order. These events are useful when an interface class is used. In this case, no request is generated in the database to extract data. These events are called only for representations. |
| ||||||||||||||||
Search events | Called when a query is performed by the search engine to feed the search indexes. |
| ||||||||||||||||
Methods or operations | A method or an operation XXXX where XXXX is the code of the method or the operation | Any operation or method that is described in the Method tabs of the class, and any operation that is described in the Operation tab of the representation will trigger an event that the name of the operation or method, in the $METHODS or $OPERATION label. The context is slightly different when we run an operation or a method:
|
These events are called through $PROPERTIES for every property on the operations associated with it. CURPRO
contains the name of the property concerned, and "This" gives access to the current instance where the property is managed.
Value of ARULE | Details |
---|---|
INIT | This method is called by the supervisor:
If the developer creates a line in a script directly, the AINIT method must be called manually after the class instantiation. |
GET | Called when accessing a property value (for example, in a formula that needs the value to perform a control or make an assignment on another property). This rule is called only if the Get accessor checkbox is set for the given property in the class definition. This event should not be activated on too many properties, for performance considerations. |
CONTROL | Called every time an assignment is performed on a property of an instance, except when the assignment is performed in the AREAD_AFTER event. It is also called in the final control of a class before an insertion or an update, after verification that the field is not empty if mandatory, and after the control of format consistency. |
PROPAGATE | Called after the CONTROL rule when a modification has been performed (when the modification is accepted and the field modified). |
At event execution time, development partners have access to:
[L]ARULE
).This
keyword. Some additional technical properties such as context description and access to parents are also available as properties.Fmet
on a class instance (usually This
).The most important variables, properties, and methods are described as follows:
The following variables are local:
The ARULE
string defines the rule called. The different values this string can have will be defined in the next pages.
The AEVENT
string defines the standard event code called. The different values this string can have will be defined in the next pages.
The AMETHOD
string defines the method code called. The values of this string correspond to the method names defined at the class level.
The AOPERATION
string defines the operation code called. The values of this string correspond to the operation names defined at the class level.
The CURPRO
string variable defines the property in which the event has been called (through $PROPERTIES
label):
The CURPTH
string defines the class scope relatively to the script where te event is called.
Example of a SALESORDER
class having a child class SORDERLINE
:
Type of method | Level where the script is called | ARULE value | CURPRO value | CURPTH value | Operating on |
---|---|---|---|---|---|
Rule ($PROPERTIES) associated with a DISCOUNT property (GET, CONTROL, INIT, PROPAGATE) on MYORDER.LINE(3) | SALESORDER | GET, CONTROL, INIT, or PROPAGATE | LINE.DISCOUNT | empty | this.DISCOUNT (the property) |
Rule ($PROPERTIES) associated with a DISCOUNT property (GET, CONTROL, INIT, PROPAGATE) on MYORDER.LINE(3) | SORDERLINE | GET, CONTROL, INIT, or PROPAGATE | DISCOUNT | empty | this.DISCOUNT (the property) |
Standard event ($EVENTS) associated with a CRUD operation (such as AINSERT_CONTROL_BEFORE) | SORDER | AINSERT_CONTROL_BEFORE | empty | empty | this (SORDER instance) |
Standard event ($EVENTS) associated with a CRUD operation (such as AINSERT_CONTROL_BEFORE) | SORDERLINE | AINSERT_CONTROL_BEFORE | empty | empty | this (SORDERLINE instance) |
Method ($METHODS) or operations ($OPERATIONS) defined in SORDER class (for example, VALIDATE) | SORDER (1) | VALIDATE | empty | empty | this (SORDER instance) |
(1) A method or operation will call only the label in the scripts associated with the class in which it has been defined and not the scripts attached to child classes.
Gives access to the class instance in which the event has been called. Any property of the current class instance can be called through this.PROPERTY
syntax.
This
available in eventsthis.ASTALIN
is an integer defined by the supervisor as an additional property when a persistent class is created. The value defines which operations have been performed during a CRUD session. They are useful for child instances collection to identify which lines have been inserted, modified, or deleted in an update operation. They are defined by the following constants:
[V]CST_ALL
: Associated with an instance where no modification has been performed.[V]CST_ANEW
: Identifies a new class instance that must be inserted at CRUD completion.[V]CST_AUPD
: Associated with a modified instance where an update must be performed at CRUD completion.[V]CST_ADEL
: Identifies an instance in which a deletion is requested.[V]CST_ANEWDEL
: Identifies a new instance in which a deletion is requested. Nothing will be performed at CRUD completion.this.APARENT
property of a child instance gives access to the parent instance. This can be useful when a nested structure is used and if the event located on a line level needs to access to header values.
this.snapshot
is a reference to the original value of the properties in a class when an insertion or an update is in progress. If this.PROPERTY
is the current value (for example, in the CONTROL event), this.snapshot.PROPERTY
gives the value that was in the property at the beginning of the operation. The following example illustrates a modification in progress on a document with HEADER and LINE classes.
this
is the reference to the current header instance and this.snapshot
is the reference to the header values after the read operation.this
is the reference to the current line instance and this.snapshot
is the reference to the line values after the read operation.this.APARENT
is the reference to the header instance and this.APARENT.snapshot
is the reference to the structure storing the previous values of the header instance.this
is the reference to the current line instance and this.snapshot
is the reference to the line values that are empty.this.ACTX
property gives access to the current instance of the ACONTEXT
class. This class stores information related to the current context, especially in the following properties:
USER
provides the connected user code.AFOLDER
provides the folder name attached to the resource.LAN
and LANISO
provide the language code, currently for three characters, and the ISO language code for five characters.LOGIN
provides the login information for 30 characters.Additional information is stored in the context. For more information, see Workbench reference Context Dictionary.The use of global variables is strongly discouraged. The ACTX class (and its methods) has been performed to allow a fast access to parameters as well as global values.
this.UPDTICK
is an integer property attached to a persistent class instance and stored in the database. It represents the current version of the line in the database. If a line has not been created, this property has a value of 0. At creation time, a database trigger fills this property with 1, and the value is returned in the class instance. In every successful modification, this property is incremented by 1 by a database trigger. When a modification attempt is performed, the instruction RewriteByKey
updates the line only if the UPDTICK
value in the database is still the value that has been read when the user loaded the data for modification. If this is not the case, an error will occur because the record was modified by another user.
this.DETAILS(I)=NewInstance C_DETAIL AllocGroup this
this.CHILD(index).ANUMLIN
property is present on all child classes managed as a collection. This is a line number dynamically assigned at the read operation that will not change if an insertion or deletion is made. The new line inserted will receive a new number equal to the maximum number assigned plus 1. Retrieving a child instance with the line number LINENUM
can be performed by using the following method of the parent class:
I=Fmet this.AGETINDBYLINE("CHILD", LINENUM)
this.CHILD(I)
.this.CHILD(index).AORDER
property is present on all child classes managed as a collection. This is a line number that defines the display order if the property is published in a representation. This value is usually assigned when the instance is filled at the read operation. Any change on this property will change the order in which the lines are presented. Thus, inserting a line in the array can be performed by adding a new instance at the end of a child instance array when the AORDER properties have been changed so the line inserted appears in the right position.
An operation handles key values that allows to find the current instance on which the operation is executed, and possibly additional parameters that are identified by a code. All these parameters are sent when the operation is called with the name used in the class dictionary on the parameter values. For the key segments, the name are the column names of the key elements in the main table associated to the class; but the other elements can be defined freely.
$METHOD_SET_MYPROPLocal Integer OKOK = Fmet This.AREAD([L]BPCNUM)If OK=[V]CST_AOKThis.MYPROP=[L]NEWVALUEOK = Fmet This.AUPDATE...
This
The this.ASETERROR
method is used to set an error during a control.
PRO
is a string identifying the context (for example, CURPRO
).MES
is a string containing the message in the right language.NUM
is a numeric value (for example, an http error code).This method is used to set an error stored in a dedicated data structure which is available through the following property.This method returns the highest error code found in the error classes for a given property. PROPERTY_NAME is a string containing the property for which the error is requested. If the property is empty, the error relates to the errors found during class methods execution.
This method cancels the errors associated with a given property. PROPERTY_NAME is a string containing the property for which the error has to be cancelled. If the property is empty, the errors found globally for the class will be cancelled.
This method is used to change attributes values associated with properties. On classes, only some attributes are used, but other attributes related to the user interface can be set up for class properties embedded in representations.
The available attributes are described below. If they are not assigned by this method, the value defined in the class dictionary is used.
Code | Attribute | Possible values |
---|---|---|
$isMandatory | Mandatory property. This attribute is set at class level. | true, false |
$isDisabled | The property cannot be inputted. This attribute is valid only for properties in a representation. | true, false |
$isHidden | The property is not displayed. This attribute is valid only for properties in a representation. | true, false |
Some other attributes are managed by the supervisor and depend only from the meta data defined in the representation dictionary. Thus they cannot be changed dynamically. For instance:
For the fields having the Enterable check box set for the Edit facet, their state can be dynamically changed in a script by using the ASETATTRIBUTE method with the $isDisabled attribute. They can also be hidden by using the ASETATTRIBUTE method with the $isHidden attribute.
The fields defined with an Initial state equal to Visible (resp. Invisible) for a given facet will be visible (resp. invisible) by default on the facet. But this state can be changed dynamically in a script by using the ASETATTRIBUTE method with the $isHidden attribute.
Of course, any visible field can be hidden by personalization, and any hidden (not technical) field can be made visible by personalization.
There are many events available due to the complex hierarchy of classes that exists for the management of a complex entity. For example, we can have a MYDOC
instance of a DOCUMENT
class that has a collection of LINE
class called DOCLINE
, which has a collection of SUBLINES
named DETAIL
.
In this example, let's consider inserting new data using the 'AINSERT_CONTROL_BEFORE' event. The description of the event calls nesting is relevant if the complete CRUD execution code is generated at the DOCUMENT
level (if the Class management check box is not set on the Mapping section in the class dictionary). In that case, the events are called with the following logic:
AINSERT_CONTROL_BEFOREcalled in the files associated with DOCUMENT class:- on class DOCUMENT- for the document instance- this is the MYDOC class instance- CURPTH is empty (the control is done for the current class)For every LINE instance in the document (loop on I):| AINSERT_CONTROL_BEFORE called in the files associated with LINE class:| - on class LINE for the current line DOCLINE instance| - this is the MYDOC.DOCLINE(I) class instance| - CURPTH is empty (the control is done for the current class)| AINSERT_CONTROL_BEFORE called in the files associated with DOCUMENT class:| - on class DOCUMENT for the MYDOC.DOCLINE(I) instance| - this is the MYDOC class instance| - CURPTH is "DOCLINE" (the control is done for the child class)| For every SUBLINE in the line instance (loop on J):| | AINSERT_CONTROL_BEFORE called in the files associated with SUBLINE class:| | - on class SUBLINE| | - for the current SUBLINE instance| | - this is the MYDOC.DOCLINE(I).DETAIL(J) class instance| | - CURPTH is empty (the control is done for the current class)| | AINSERT_CONTROL_BEFORE called in the files associated with LINE class:| | - on class LINE| | - for the current LINE instance| | - this is the MYDOC.DOCLINE(I) class instance| | - CURPTH is "DETAIL" (the control is done for the child class)| | AINSERT_CONTROL_BEFORE called in the files associated with DOCUMENT class:| | - on class DOCUMENT| | - for the current DOCUMENT instance| | - this is the MYDOC class instance| | - CURPTH is "DOCLINE.DETAIL" (the control is done for the grand child class)| Next SUBLINE instance (loop on J)Next LINE instance (loop on J)
APARENT
. For instance, a property PROP1
of the DOCUMENT
class can be accessed in the code attached to SUBLINE
through the following syntax: this.APARENT.APARENT.PROP1
.This principle of code nesting exists on all the other events listed above, but on the 'AINSERT_AFTER', the event is performed on the nesting level after the events on the sub-level have been performed. This means that the order is as follows:
The previous example (Insertion) works when an insertion of a new instance of a class is performed.
On updates, when child class collections exist on a class, an update operation on a complex document can consist of inserting lines, deleting lines, or modifying lines. You must consider that a modification of a document will call the events defined for deletion, insertion, or modification on the child classes, depending on the modification encountered.
In fact, it will depend on the this.ASTALIN
property for a given instance at a given level:
[V]CST_ALL
or [V]CST_ANEWDEL
is found, nothing will be called. The line has not been modified, or has been temporarily inserted and then deleted.[V]CST_ANEW
is found, the events associated with an insertion will be performed.[V]CST_AUPD
is found, the events associated with an update will be performed.[V]CST_ADEL
is found, the events associated with a deletion will be performed.If a modification is done, the modification events will be performed at the document level.
The loop nesting principles are anyways the same, the 'BEFORE' operations are nested in descending level, while the 'AFTER' operation is performed on the lowest level of a collection of child class instances before performing it on the class including the collection.
This works also if a class has two child classes that are not nested. In this case, the loops are performed on the two child class instances independently.
When nested classes are declared, the calls on the CRUD events are performed at the different level as described above. On other class methods, the call is performed only on the scripts declared in the corresponding class and not on the child classes.
When the code associated with events is executed in service mode, no UI event interferes with the methods described previously, and the description of the nested event calls that has been done in the previous section is complete.
When a UI is involved in the process, there is a parent class associated with the main class (representation).
An additional level of event will be executed because the representation instance that can include additional properties dedicated only to the UI will also include a reference to the main class. The complete path of a sub-line property would then be in the representation event:
REPRESENTATION.DOCUMENT.LINE.SUBLINE.FINAL_PROPERTY
, and the event on the different events would also be called from the files associated with the representation using CURPRO="MYREP.MYDOC.LINE.SUBLINE"
where`this
would be equal to MYREP.MYDOC.LINE(I).SUBLINE(J)
.
Some additional events dedicated to UI methods and operation also exist. They are documented in the representation description.
Dedicated methods exist to enable or disable links associated to the page level and to the record level.
They work only in Details facet (not in Edit mode).
These methods are the following:
The parameters are, in both cases:
* CODLNK : a string that contains the code of the link
* AFFLNK : a local menu that can have one of the two following constant values: CST_AFFLNKREC and CST_AFFLNKPAG.
# After reading a record, we might disable links according to the content of the class$AREAD_AFTERIf this.MYCLASS.MYPROP="A1"[L]ASTATUS = fmet this.ASETLINKDISABLE("AEDIT",[V]CST_AFFLNKREC)[L]ASTATUS = fmet this.ASETLINKDISABLE("TEST",[V]CST_AFFLNKPAG)[L]ASTATUS = fmet this.ASETLINKDISABLE("ADELETE",[V]CST_AFFLNKREC)[L]ASTATUS = fmet this.ASETLINKDISABLE("ENR",[V]CST_AFFLNKREC) Elsif this.MYCLASS.MYPROP="A2"[L]ASTATUS = fmet this.ASETLINKDISABLE("AQUERY",[V]CST_AFFLNKPAG)[L]ASTATUS = fmet this.ASETLINKDISABLE("ACREATE",[V]CST_AFFLNKPAG)[L]ASTATUS = fmet this.ASETLINKENABLE("ENR",[V]CST_AFFLNKPAG)Else[L]ASTATUS = fmet this.ASETLINKDISABLE("AEDIT ",[V]CST_AFFLNKPAG)[L]ASTATUS = fmet this.ASETLINKDISABLE("ADELETE ",[V]CST_AFFLNKPAG)[L]ASTATUS = fmet this.ASETLINKDISABLE("AQUERY",[V]CST_AFFLNKPAG)Endif
This example illustrates a 'SORDER' class having a 'SORDERLINE' child class. It is the of a script declared in 'SORDER' class, which calls separate subprograms.
################ CLASS SORDER################ EVENTS###############$EVENTSCase CURPTHWhen "" Case AEVENTWhen "AINSERT_CONTROL_AFTER" : Gosub AINSERT_CONTROL_AFTER : # Standard CRUD methodWhen "AUPDATE_CONTROL_AFTER" : Gosub AUPDATE_CONTROL_AFTER : # Standard CRUD methodWhen "AINSERT_BEFORE" : Gosub AINSERT_BEFORE : # Standard CRUD methodWhen "AUPDATE_BEFORE" : Gosub AUPDATE_BEFORE : # Standard CRUD methodEndcaseWhen "LINE"Case AEVENTWhen "AINSERT_CONTROL_AFTER" : Gosub LINE_AINSERT_CONTROL_AFTER : # Standard CRUD operation on lineWhen "AUPDATE_CONTROL_AFTER" : Gosub LINE_AUPDATE_CONTROL_AFTER : # Standard CRUD operation on lineWhen "AINSERT_BEFORE": Gosub LINE_AINSERT_BEFORE : # Standard CRUD operation on lineEndcaseEndcase################ METHODS###############$METHODSCase AMETHODWhen "VALID" : Gosub VALID : # Class methodEndcaseReturn################ OPERATIONS###############$OPERATIONSCase AOPERATIONWhen "POST" : Gosub POST : # Class operationEndcaseReturn############## RULES#############$PROPERTIESCase CURPROWhen "PROP1": Gosub PROP1 : # Methods attached to property PROP1When "PROP2": Gosub PROP2 : # Methods attached to property PROP2When "LINES.PROP3" : Gosub PROP3 : # Methods attached to property PROP3 of a LINE child instanceEndcaseReturn#######$PROP1Case ARULEWhen "INIT" : Gosub PROP1_INIT : # Init rule attached to PROP1When "CONTROL" : Gosub PROP1_CONTROL : # Control rule attached to PROP1When "PROPAGATE" : Gosub PROP1_PROPAGATE : # Propagate rule attached to PROP1When "GET": Gosub PROP1_GET: # Get rule attached to PROP1 EndcaseReturn#######$PROP2Case RULEWhen "INIT" : Gosub PROP2_INIT : # Init rule attached to PROP2When "CONTROL" : Gosub PROP2_CONTROL : # Control rule attached to PROP2When "PROPAGATE" : Gosub PROP2_PROPAGATE : # Propagate rule attached to PROP2When "GET": Gosub PROP2_GET: # Get rule attached to PROP2Endcase#######$PROP3# As the rule is attached to a line instance# "this" is here the line instance and this.PROP3 the property on the current lineCase ACTIONWhen "INIT" : Gosub PROP3_INIT : # Init rule attached to PROP3When "CONTROL" : Gosub PROP3_CONTROL : # Control rule attached to PROP3When "PROPAGATE" : Gosub PROP3_PROPAGATE : # Propagate rule attached to PROP3When "GET": Gosub PROP3_GET: # Get rule attached to PROP3EndcaseReturn