Rogue Wave banner
Previous fileTop of DocumentContentsIndexNext file

8.6 The Functor List Subpackage

Functor lists provide a mechanism for grouping together a number of different functions into one coherent object. With a single invocation, several related tasks can be accomplished.

Because this single invocation shares its API with the basic functors, functor lists can be used wherever a functor is expected but a sequence of functors would be more useful. In fact, the code to which the functor list is passed need not know. The code invokes what appears to be a simple functor, and the list handles the complexity of invoking all of its encapsulated functions.

For example, suppose a button widget invokes a functor when pushed. If your application needs to associate a number of actions with the button, you can group them together in a functor list and pass that list to the button widget. When the button is pushed, the widget invokes the functor list, and all of the actions are fired. The button widget code doesn't change at all.

8.6.1 How Do They Work?

Like basic functors, functor lists are implemented by a number of template classes. Depending on the number of arguments passed at invocation time, different functor lists are required.

Because the invocation of the list invokes all the functors within the list, they all must have the same invocation signature and either share the same functor handle type or be derived from the same functor handle type.

Like functors, functor lists use the handle body idiom. Because each functor list handle can point to exactly one type of functor list, however, the body is created automatically as a part of the handle's construction. Copying functor lists follows the general rules discussed in Section 7.3.1.4, "Handle-body Mechanics." With this technique, the copy constructor and assignment operators reference the old object and, as a result, are very fast.


NOTE: After the assignment, changes to either functor list object affect the other one.

8.6.2 Functor List Class Hierarchy

The Functor List subpackage is made up of classes designed to accommodate functor arguments of different numbers and types. Functor list classes are an extension to the functor class hierarchy, as shown in Figure 51.

Figure 51 -- Hierarchy of functor list classes and the functor classes from which they derive

Class names are constructed from the base name RWTFunctorList for templatized classes or RWFunctorList for the few non-templatized classes by adding 0, 1 or 2 for the number of caller arguments.

The formal template parameters (shown in the hierarchy) include:

S1 - The type of the functor list's first argument.

S2 - The type of the functor list's second argument.


NOTE: Functor lists do not provide R0, R1, or R2 classes.

8.6.3 Using Functor Lists

The specific type of functor list that you need depends on the type of functors to be held within the list. All functors in a list must be of the same handle type or be derived from the same handle type. If you are starting with a function that you wish to wrap, see Section 8.4.1, "Analyzing Functor Requirements," to select a functor type.

8.6.3.1 Constructing Functor Lists

To construct a functor list, you need to know what type of list to create, based on the functor type.

The following steps show how to create a functor list to hold a set of functors.

  1. Start with a set of functions, for example:

  2. void foo(int int_arg) { 
      cout << "foo was passed " <<  int_arg << endl; }
    void bar(short short_arg){ 
      cout << "bar was passed " << short_arg << endl;}
  3. Decide what functor type you need and build functors from the functions:

  4. RWTFunctor1<short> fooFunctor = 
      rwtMakeFunctor1( (void(*)(short))NULL, foo);
    
    RWTFunctor1<short> barFunctor = 
      rwtMakeFunctor1( (void(*)(short))NULL, bar);
  5. Create the appropriate functor list to hold that functor type:

  6. RWTFunctorList1<short> flist;

8.6.3.2 Adding Functors to the List

At this point, you have a complete but empty functor list instance. Next, you add functors to the list, as shown in Example 74.

When adding a functor, you can specify how long it remains a part of the list. If the functor will remain indefinitely, add it with the RW_CALL_REPEATEDLY flag. If you intend to call the functor only once, however, add it with the RW_CALL_ONCE flag.


NOTE: Functors added with the RW_CALL_ONCE flag are automatically removed after invocation.

Example 74 -- Adding functors to a functor list

8.6.3.3 Invoking Functor Lists

Once the list contains entries, you can invoke it. Invocation consists of iterating through the list invoking each functor with the given caller values and then removing the functor from the list, if it was added with the RW_CALL_ONCE flag.


NOTE: If you invoke a functor list that has no entries, nothing happens.

For example, suppose you call the functor list with the functors added in the previous section, like this:

This call performs the following actions:

This output is produced:

If you invoked the list a second time, only barFunctor would be invoked, because fooFunctor was removed.

8.6.3.4 Removing Functors from the List

To remove a functor from the list, call the remove() function with the functor to be removed.

8.6.3.5 Updating Functor Lists

To provide the maximum level of concurrency, additions and removals are buffered, and the actual update of the list is postponed until the next list invocation. The performance hit for updating a list is small in most cases. If an extremely large number of additions and or removals are done, however, this cost can become non-trivial. For such cases, the functor list classes have an update() function, which forces an update immediately.

Use of this function is not required and will not change the program's logic.

8.6.3.6 Using a Functor List as a Callback

Example 75 shows how to use a functor list as a callback. It is essentially the same as the pushButton example in examples\thr0200osfam\functor, except that replacing a functor with a functor list enables you to attach more than one callback to the button. This complete example is available in examples\thr0200osfam\functor\list\pushButtonList.cpp.

Example 75 -- Using a functor list as a callback


Previous fileTop of DocumentContentsIndexNext file

©Copyright 2000, Rogue Wave Software, Inc.
Contact Rogue Wave about documentation or support issues.