invokeIOMethod

invokeIOMethod(targetContext: ApplicationContext;
               targetMethod:  Method;
               paramList:     ParamListType io): Any;

The invokeIOMethod method of the Object class sends the specified target method containing a variable list of parameters to the receiver, after switching to the specified targetContext execution context.

The return type of the invokeIOMethod method is to allow for an optional return value from the method being called. If the called method returns a value, the Any result must be cast to the appropriate type, to access that result.

After the method has finished, the execution context switches back to the current context. For details about using this method to call user methods from packages, see "Calling User Methods from Packages", in Chapter 8 of the JADE Developer’s Reference.

The targetMethod parameter must be a valid method, which is executed when the invokeIOMethod method is called.

Use the paramList parameter to specify a variable list of parameters of any type that are passed to the method or condition specified in the targetMethod parameter when it is executed.

If the number or type of the actual parameters passed to a method by a parameter list does not correspond exactly to the formal parameter list declaration, an exception or an unpredictable result may occur, as the compiler is unable to perform any type checking on the values that are passed to a parameter list. However, the Method class isCallCompatibleWith method enables you to validate the number and type of parameters.

For details about the ParamListType pseudo type, see "ParamListType" under "Pseudo Types", in Chapter 1 of the JADE Developer’s Reference. See also "Passing Variable Parameters to Methods" under "JADE Language Syntax", in Chapter 1 of the JADE Developer’s Reference.

As the application context used by invokeIOMethod is transient, it can switch to a context only within the same process. The mechanism is not designed to call a method running in another process in the node or in another node. In addition, as the context is transient, any connection between a context and a method to be invoked must be set up again if an application is stopped and then restarted.

If you want to save events to be called persistently so that methods would still be called if the application stops and restarts (for example, in a scheduler application), you would have to re-supply a context when the application restarts and events are loaded. The target method and object could be persistent but the context is not.

Although the callback mechanism is designed with packages in mind, you can also use it to allow a method to be invoked from within the same context. If the context in the invokeIOMethod call is null, the current context (that is, appContext) is used. This therefore enables you to invoke a specific saved method (for example, myClass::myMethod) rather than calling the Object class sendMsg method, which allows you to provide only the name of the method to which the message is sent. Within a package, the package writer may want to check that the method supplied by the user of the package is appropriate.

The Method class isCallCompatibleWith method checks that the target method supplied by the package user cannot be invoked only on the specified target object but that it has a signature that is compatible with that expected by the package. The Method class isCallCompatibleWith method has the following signature.

isCallCompatibleWith(targetObject:  Object;
                     exampleMethod: Method): Boolean;

The method in the following example shows an example of the invokeIOMethod when the timer fires and inspects all events at the start of the queue and calls all those whose time has passed.

causeDueEvents();
vars
    se : ScheduledEvent;
begin
    foreach se in allScheduledEvents do
        if se.whenToStart > app.actualTime.time then
            return;
        endif;
        // Call users method, supplying expected start time as a parameter
        if se.targetObject <> null and se.targetMethod <> null then
            se.targetObject.invokeMethod(se.targetContext, se.targetMethod,
                                         se.whenToStart);
            se.myScheduler := null;
            delete se;
        endif;
    endforeach;
end;