Tinderbox v9 Icon

Delaying code execution in prototypes and notes using prototypes

When using pre-planned structural prototypes, i.e. those stored apart from actual content and with no purpose other than as a means to configure other content notes, consideration should be given to whether action code such as found in in Action-type attributes is run in the prototype itself, or should be suppressed there and only run in a note inheriting from the prototype. This scenario affects code placed in the Action-type attributes (e.g. via their create/rename dialog boxes):

In large or complex documents, it is possible to end up with many notes using the same prototype. If the later has a complex $Rule or $DisplayExpression, this can place quite a loading on the speed with which the cycle of running action code is completed. These two action attributes attributes have additional special system attributes specifically to suppress prototype-based execution. as a result the attributes $RuleDisabled or $DisplayExpressionDisabled are intrinsic: setting them in the prototype has no effect as these attributes are inherent and not inherited by notes using the prototype.

Controlling use of inherited complex actions

Thus, in some cases it is desirable to delay code execution as the code is written with the intention of running in an inherited context, using actual data from the inheriting note, but only when intended. This scenario requires a different approach. One method is to make the action in inheriting notes check the disablement state in their prototype. This example is for a rule:

    if($RuleDisabled($Prototype)){
        if($MyNum>0){
            $Color="bright red"
        }else{
            $Color=;
        };
    }

However, be aware the rule still exists and the outer if() condition is still evaluated, so this approach does not remove the rule entirely. For actions with no disablement attribute, consider the same but using a user Boolean attribute set in the prototype.

Another example:

    if(!$IsPrototype){
        $AgentQuery="Topics("+$Name+")";
    }

The above ensures that, in a prototype agent, the agent's query is not set within the prototype whereas in all agents inheriting from the prototype the query will be set. The need for a wrapping if() conditional test becomes clearer with this rule:

    if(!$IsPrototype){
        $AgentQuery="Topics("+$Name+")";
        $Rule="";
}

Without the if() test, the latter rule would run and delete itself within the prototype and never set anything in the inheriting agents.

Note too, that if using self-deleting rules via a prototype the act of clearing the rule breaks inheritance for the $Rule attribute.

Using multiple prototypes

Another method for switching complex actions on/off is to use prototypes for the existing prototype. For instance, in the example of a complex rule, keep the existing prototype but cut the rule code and move it to a new, otherwise un-customised prototype. Now, to turn the rule on, set the $Prototype of the existing prototype to the name of the new one; this causes it to inherit the rule. Resetting the $Prototype value to the default (nothing) causes the main prototype to inherit the default $Rule, i.e. nothing. Be aware that this method only really works for turning one attribute (i.e. a rule or edict) on or off, or if multiple actions (e.g. both rule and edict) are to always enabled/disabled at the same time.



A Tinderbox Reference File : Automating Tinderbox : Coding : Action Code : Delaying code execution in prototypes and notes using prototypes