Menu

Aspect interface

2006-04-03
2013-04-08
  • Nobody/Anonymous

    Hi,

    I was wondering if their is a reason why the widget aspect don't inherit from a virtual interface.

    For exemple:

    template<class WindowOriginalType>
    class IAspectEnabled
    {
    public:
    virtual void setEnabled( bool enabled ) = 0;
    virtual bool getEnabled() const = 0;
    };

    template<...>
    class AspectEnabled :
       public IAspectEnabled<WindowOriginalType>
    {
    ...
    };

    This would make it very easy to make collection of widget ( like vector<Widget *> ) and use dynamic_cast to get the aspect interface we want from the widget.

    Since the template declaration of aspects include a the base widget type, it make it impossible to iterate through a Widget collection of different widget and do a common action.

    I think it could be a nice add on to SmartWin, but maybe their is a reason it's not done that way?

    Nicolas

     
    • Thomas Hansen

      Thomas Hansen - 2006-04-03

      If you need to make it a template class (the interface) you gain nothing that you don't have today.
      You'd still have to cast to the template type, and if you know the template type you can do more or less the exact same thing you can do today!
      Now if we COULD get rid of the template type it would carry some positive sides like e.g. we could stuff them into arrays (through references or pointers) and thereby could iterate over them (probably as you mean) but that would make the interfaces pretty thin, though in some places I guess this would be justifyable like the Sizable aspect would be pretty useful to be able to iterate across pointers to widgets without having to know their explicit types.
      But as long as we keep the template parameter we gain almost nothing!

      Now if we made an abstract class called e.g. IAspectSizable that was not a template class then this could be a positive thing in such a way that we could iterate across all sizable widgets and do stuff to them and not caring about the concrete implementation class.

      Though we would not be able to get or set the event handlers (since they depend upon the template parameter) and it would still require some overhead and all over add to the complexity of the library so as you see I'm pretty reluctant against doing this.

      Maybe we'll do it if Bjarne changes his mind and adds up "override" keyword as a mandatory keyword for overriding virtual functions... ;)
      (in addition to a warning about hiding virtual base class functions when no "override" is supplied and off course a compile time bug for override functions where no virtual function exists to override...)
      (JOKE!  <-- with an ironic serious undertone... ;)

      .t

       
    • Nobody/Anonymous

      I was proposing this for the AspectSizeable. Exactly like you said, it would make it easy to do a layout manager that keep a list of widget if we can have a base interface for AspectSizeable.

      I kept a template parameter in my exemple but maybe I named it wrong. I wanted to keep a template parameter that indicate the parent window type of the interface, so that you still keep some type-safety. I thought this was one of the goal of the library!

      Of course, an aspect interface wouldn't have the event handler function, just the function that don't have template argument.

      As for the overhead, well... it is either that or a hand made switch table :-)

      The reason I proposed this was that I am generating interface dynamically and I have to keep an array of created widget. To do the layout, since I can't cast to AspectSizeable, I have to use the Widget::handle method and use WinAPI call. I added an IAspectSizeable interface to solve this problem.

      Also, with base class for AspectEnabled and AspectVisible, you could also itterate through widget to update your GUI.

      As for the complexity, It is pretty simple to implement and isn't a breaking change! So it is pretty much the overhead that is the drawback (the way I see it anyway :-) ).

      Well, sorry to be insistent, I just miss the ability to dynamic_cast my widgets (i'll just modify my version!). Appart from that, I think you did a great job with SmartWin!

      Nicolas

       
      • Thomas Hansen

        Thomas Hansen - 2006-04-05

        To cast to AspectSizable is not really much more difficult than to cast to an interface of that type...
        You'll just have to remember to give all the template params correctly!
        Also you won't be able to cast a WidgetChildWindow but all control widgets (also those embedded within a WidgetChildWindow) can be casted this way!

        .t

         
    • Nobody/Anonymous

      But since one of the template parameter of AspectSizeable is the widget type, we still have to know the type of widget, so it isn't possible to create a container of different widget of unknown type.

      Anyway, I've decided to go another way to solve the problem, I created a virtual base class:

      class IAspectSizeable
      {
      public:
         virtual void setBounds( Rectangle r ) = 0;
         ....
      };

      and a template implementation class that delegate to the widget:

      template< class WidgetT >
      class IAspectSizeableImpl :
         public IAspectSizeable
      {
      public:
         IAspectSizeableImpl(WidgetT::ObjectType w)
            itsWidget(w) {}
         virtual void setBounds( Rectangle r )
         {
            itsWidget->setBound(r);
         }
         ...
      protected:
         WidgetT::ObjectType itsWidget;
      };

      This way I can create container of widget easily without changing the source code of SmartWin.

      By the way, is virtual function overhead is significally noticeable (maybe on pocket PC??) ?

       
      • Thomas Hansen

        Thomas Hansen - 2006-04-06

        Virtual functions implementation is per definition (C++ std) platform independant, though in practice they're always implemented as a "vtable".
        A vtable is a table of pointers to functions so it requires ONE extra indirection, comparable to the difference between reading a value or reading the contents of the address of a pointer.
        In practice one extra memory MOV instruction...
        Rarely no more than 1-5 CPU cycles.
        Said with other words; "nothing"!! :)

        .t

         

Log in to post a comment.