Delegate Common Tasks to your own Instance List Controller  

So far we have seen how the task of adding to, updating and deleting instance list entries may be delegated to a common shared instance list controller. 

Any other activity that is likely to involve repeated code in a filter or a command handler can usually be delegated in the same way.   

For example, in the preceding section RAMP scripts can access the instance list controller by signaling an event to it via a listening filter. Since you will not always know which filter is listening, you would have to repeat the listening code in every filter.   

One way to delegate this listening task, and virtually any listening task, to a common shared instance list controller is as follows:

In the instance list controller define 2 collections like this:

 

* Keep track of all registered active filters and command handlers

 

DEFINE_COM CLASS(#Prim_Acol<#VF_ac007O >) NAME(#ActiveFilters) /* VF_AC007 for WIN */

DEFINE_COM CLASS(#Prim_Acol<#VF_ac010O>) NAME(#ActiveHandlers) /* VF_AC010 for WIN */

 Then add 2 methods like this:

 

MthRoutine RegisterInitialize

Define_map *input #VF_AC007O #Filter Pass(*By_Reference) Mandatory(null)

Define_map *input #VF_AC010O #Handler Pass(*By_Reference) Mandatory(null)

* Keep track of registered and active filters  

If_ref #Filter is_not(*null)

Invoke #ActiveFilters.Insert Item(#Filter)

Endif

* Keep track of all registered and active command handlers

If_ref #Handler is_not(*null)

Invoke #ActiveHandlers.Insert Item(#Handler)

Endif

Endroutine

MthRoutine RegisterTerminate

Define_map *input #VF_AC007O #Filter Pass(*By_Reference) Mandatory(null)

Define_map *input #VF_AC010O #Handler Pass(*By_Reference) Mandatory(null)

* Remove the specified filter from the active collection

If_ref #Filter is_not(*null)

Invoke #ActiveFilters.Remove Object(#Filter)

Endif

* Remove the specifeid command handler from the active collection

If_ref #Handler is_not(*null)

Invoke #ActiveHandlers.Remove Object(#Handler)

Endif

Endroutine

 

Now, in each filter or command handler, you need to do three things:

 

 

    DEFINE_COM CLASS(#EMPMNGR) NAME(#EmployeeController) scope(*Application)

 

 

    MthRoutine uInitialize Options(*Redefine)

    Invoke # EmployeeController.RegisterInitialize Filter(#Com_Owner)

    Endroutine

 

      In a command handler do this:

 

     MthRoutine uInitialize Options(*Redefine)

     Invoke #EmployeeController.RegisterInitialize Handler(#Com_Owner)

     Endroutine

 

 

     MthRoutine uTerminate Options(*Redefine)

     Invoke #EmployeeController.RegisterTerminate Filter(#Com_Owner)

     Endroutine

 

      In a command handler do this:

 

     MthRoutine uTerminate Options(*Redefine)

     Invoke #EmployeeController.RegisterTerminate Handler(#Com_Owner)

     Endroutine

Note: It is really important that the uTerminate logic is used.

Your instance list controller is now aware all active filters and command handlers that are doing something with the business object (e.g. Employees).

It can start to perform common shared actions on their behalf. 

For example, if your instance list controller had an event routine like this in it:

 

Evtroutine Handling(#ActiveFilters<>.avEvent) WithId(#EventId) WithAInfo1(#AInfo1) WithAInfo2(#AInfo2) WithAInfo3(#AInfo3) COM_Sender(#SendingFilter) Options(*NOCLEARMESSAGES *NOCLEARERRORS)

Case #EventId.Value

When (= UPDATE_EMPLOYEE_5250)

#Com_Owner.UpdateListDetails ListManager(#SendingFilter.avListManager) ForEmpno(#AInfo1)

When (= DELETE_EMPLOYEE_5250)

 

#Com_Owner.DeleteListDetails ListManager(#SendingFilter.avListManager) ForEmpno(#AInfo1) inDepartment(#AInfo2) InSection(#AInfo3)

EndCase

Endroutine

 Then it has taken over the job of listening for RAMP script events for all filters.

There is no longer any need to add this listening code to any specific filter. 

The use of #ActiveFilters<>.avEvent is special.

This instance list controller event routine is listening in to (or, eavesdropping, if you like) to all the filters that have registered with it.

You can do the same sort of thing using #ActiveHandlers<> of course.

On the other side of this coin, an instance list controller can also signal events to all active filters and command handlers. Typically this is done like this:

First, define the events and methods to signal them into your instance lists 'manager', like in this example:

 

Define_Evt EmployeeUpdate

Define_map *input #Empno #EmployeeNumber

Define_Evt EmployeeDelete

Define_map *input #Empno #EmployeeNumber

Mthroutine Signal_EmployeeUpdate

Define_map *input #Empno #EmployeeNumber

Signal EmployeeUpdate EmployeeNumber(#EmployeeNumber) 

Endroutine

Mthroutine Signal_EmployeeDelete

Define_map *input #Empno #EmployeeNumber

Signal EmployeeDelete EmployeeNumber(#EmployeeNumber)

Endroutine

 Now, in any filter or command handler that wants to be notified when these events happen, you just need to put an event handling routine in to listen like this:

 

Evtroutine Handling(#EmployeeController.EmployeeUpdate)

           EmployeeNumber(#EmployeeNumber) 

Use Message_box_show (ok ok info *Component ("I have just been notified that employee number " + #EmployeeNumber + " has been updated"))

Endroutine

Evtroutine Handling(#EmployeeController.EmployeeDelete)

           EmployeeNumber(#EmployeeNUmber)

Use Message_box_show (ok ok info *Component ("I have just been notified that employee number " + #EmployeeNumber + " has been deleted"))

Endroutine

Finally, in the filter or command handler that wants to signal (or trigger, or notify) the event to others, you just need to do this:

 

#EmployeeController.Signal_EmployeeUpdate EmployeeNumber(#Empno)

or

#EmployeeController.Signal_EmployeeDelete EmployeeNumber(#Empno)