Delegate Common Tasks to your own Instance List Manager

Visual LANSA Framework

Delegate Common Tasks to your own Instance List 'Manager'  

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 'manager'. 

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 'manager' 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 manager is as follows:

In the instance list 'manager' define 2 collections like this:

* Keep track of all registered active filters and command handlers

 

DEFINE_COM CLASS(#Prim_Acol<#VF_ac007>) NAME(#ActiveFilters)

DEFINE_COM CLASS(#Prim_Acol<#VF_ac010>) NAME(#ActiveHandlers)

 

Then add 2 methods like this:

MthRoutine RegisterInitialize

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

Define_map *input #VF_AC010 #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_AC007 #Filter Pass(*By_Reference) Mandatory(null)

Define_map *input #VF_AC010 #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 the instance list manager:

 

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

 

  • Register with the instance list manager when starting up. In a filter do this:

 

    MthRoutine uInitialize Options(*Redefine)

    Invoke #EmployeeManager.RegisterInitialize Filter(#Com_Owner) 

    Endroutine

 

      In a command handler do this:

 

     MthRoutine uInitialize Options(*Redefine)

     Invoke #EmployeeManager.RegisterInitialize Handler(#Com_Owner) 

     Endroutine

 

  • (De)Register with the instance list manager when terminating. In a filter do this:

 

     MthRoutine uTerminate Options(*Redefine)

     Invoke #EmployeeManager.RegisterTerminate Filter(#Com_Owner) 

     Endroutine

 

      In a command handler do this:

 

     MthRoutine uTerminate Options(*Redefine)

     Invoke #EmployeeManager.RegisterTerminate Handler(#Com_Owner) 

     Endroutine

 

Your instance list 'manager' is now aware all active filters and command handlers that are actively doing something with the business object (eg: Employees).

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

For example, if your instance list 'manager' 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 manager 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 manager 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 Sig_EmployeeUpdate

Define_map *input #Empno #EmployeeNumber

Signal EmployeeUpdate EmployeeNumber(#EmployeeNumber) 

Endroutine

 

Mthroutine Sig_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(#EmployeeManager.EmployeeUpdate) EmployeeNumber(#EmployeeNUmber) Options(*NOCLEARMESSAGES *NOCLEARERRORS)

 

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

 

Endroutine

 

Evtroutine Handling(#EmployeeManager.EmployeeDelete) EmployeeNumber(#EmployeeNUmber) Options(*NOCLEARMESSAGES *NOCLEARERRORS)

 

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:

 

#EmployeeManager.Sig_EmployeeUpdate EmployeeNumber(#Empno)

or

#EmployeeManager.Sig_EmployeeDelete EmployeeNumber(#Empno)