[Insight-developers] InvokeEvent / Observer / Command

Luis Ibanez ibanez@cs.unc.edu
Sat, 20 Jan 2001 21:24:59 -0500 (EST)


Hi,


There is another easy alternative to get around 
the 'const' problem with the Command::Execute()
method.

The option is to define in the itk::Command class,
two Execute() methods, one with a normal pointer to
LigthObject and the other with a const pointer, as:

Command::Execute(       LightObject * , Event e ) = 0;
Command::Execute( const LightObject * , Event e ) = 0;


Then, in SubjectImplementation class create an 
additional InvokeEvent method, that receives a const
pointer to Light object, like:

SubjectImplementation::InvokeEvent( Event e, const LightObject * ) 
{
  // with the same body that the non-const InvokeEvent method
}


and finally in LightObject add a const InvokeEvent() method,


LightObject::InvokeEvent( Event e ) const
{
  // the same body as the non-const InvokeEvent method
}



In this way, when a const LightObject calls its InvokeEvent()
method, the const version of the method will be selected.
This version uses in its body the (const *) version of the
SubjectImplementation::InvokeEvent() method, and this one
will call the version of the Command::Execute() method that
receives a pointer to const LightObject.

This seems to be better that the previous suggestion
of creating a PassiveCommand / ActiveCommand pair, 
and having two separate list of observers in the 
SubjectImplementation class.

One advantage of this option is that the current hierarchy 
of Command's can be keept (with the only addition of the
Execute( const LightObject *, Event ) method in the
classes that derive from itk::Command.


This hierarchy actually looks like:

 
    +-------------+
    | LightObject |
    +-------------+
           | (has one)
           V
  +---------------------+ (points to many) +--------+
  |SubjectImplementation|----------------->|Observer|
  +---------------------+                  +--------+
                                                | (has one)
                                                V
                                           +---------+
                                           | Command |
                                           +---------+
                                                |
                                                |
                               +----------------+
                               |
                               | (derivation)
                               |
         +---------------------+---------------------+
         |                     |                     |
         V                     V                     V
 +---------------+  +---------------------+  +---------------+
 | MemberCommand |  | SimpleMemberCommand |  | CStyleCommand |
 +---------------+  +---------------------+  +---------------+
     


The only class that need more modifications with this option,
is CStyleCommand, which has a pointer to a normal C function
that receives a (LightObject *, Event).  It will need now a
second pointer to a C function that receives (const LightObject *,
Event ). Its second Execute() method will call this new pointer to
function  while the original Execute method will still use the 
original pointer to C function.

These modification compile fine, and as far as I've tested
it seems to run ok.




Luis