Observer pattern (aka. Notifications) for wxWidgets

Do you like to promote your wxWidgets based application or component!? Post it here and let's see what the critics have to say. Also, if you found that ONE wx component the world needs to know about, put it here for future reference.
Post Reply
ezequielv
Earned a small fee
Earned a small fee
Posts: 19
Joined: Sun Oct 10, 2004 9:20 pm
Location: Berkshire, England

Observer pattern (aka. Notifications) for wxWidgets

Post by ezequielv » Mon Nov 01, 2004 4:34 pm

Hi. I've recently developed (not finished yet, I'm just polishing everything before releasing it) a group of classes for implementing the observer pattern and event forwarding under wxWidgets.

The idea is to implement notifications using the event system that wxWidgets provides. Furthermore, it allows arbitrary plugging of external event handler functions without disrupting the object's normal event handling mechanism.

The main features are:

* Event handling mechanism for wxEvtHandler-derived objects is unchanged (no hidden event handlers are "pushed" nor "popped").
* For non-wxEvtHandler-derived classes: you can make any class a "model" ("subject"), without requiring you inheriting from any specific class.
* You can extend existing wxEvtHandler-derived classes with forwarding capabilities wihout the limitations of wxWidgets (ie. dynamic method attachment to handle events can only be made to the handler object (you can't connect other object's handlers to a wxEvtHandler object); push/pop event handlers require right sequence for disconnecting a specific handler (that is only available in wxWindow-derived classes anyway), etc.).
* You can (if templates support is enabled) forward event handling to any class, without requiring the target class to be inherited from wxObject, wxEvtHandler or any other.
* If templates are not enabled, all you need is your forward destination class to be inherited from wxObject (not necessarilly from wxEvtHandler), so it's still very lightweight.
* You can disconnect, without knowing the particulars, all methods for a particular object in a single function call (see example below).
* You can attach a "strategy" for event processing regardless of each event handler's code (to simulate notifications, in which handlers should not interfere with each other).
* No changes to wxWidgets library are required, and it's (should be) fully compatible with all platforms (it does not need templates) wxWidgets supports.
* The same limitations apply to virtual functions as forward (or notification) destinations (they work as regular functions) as in wxWidgets.

As I said, it's almost finished. I found this crucial to implement the observer pattern.

In plain english, you could do this:

[syntax="c"]
// notifier as member (for model classes that should not be re-inherited from other classes).
class CMyClass1
{
public:
wxNotifier m_notifier;
void SomeMethod( void );
};

void CMyClass1::SomeMethod( void )
{
// operations...

// notify
m_notifier.ProcessEvent( wxEvent( m_id, wxEVT_MODEL_NOTIFICATIONS ) );
};

// notification as a transparent added mechanism for this wxEvtHandler-based model class
class CMyClass2 :
// its own inheritance (somehow derived from wxEvtHandler)
public wxEvtForwarderImpl
{
// ...
DECLARE_EVTFORWARDER_CLASS(CMyClass2)
};

IMPLEMENT_EVTFORWARDER_CLASS(CMyClass2)

void CMyClass2::SomeMethod( void )
{
// operations...

// notify
ProcessEvent( wxEvent( m_id, wxEVT_MODEL_NOTIFICATIONS ) );
};

class CMyManager // somehow derived from wxObject
{
protected:
// my specific model class in this context.
// could be a singleton referred in the code below, etc.
CMyClass1 * m_pModel1;
CMyClass2 * m_pModel2;

public:
void ProcessNotification( wxEvent& event );
void ProcessToolbarClicked( wxEvent& event );
};

// example
CMyManager::SetupConnections( void )
{
// ...

// using "notifier" object
pModel1->m_notifier.ConnectObj( ID_MODEL1, wxEVT_MODEL_NOTIFICATIONS, this, (wxObjectEventFunction) (wxEventFunction) &CMyManager::ProcessNotification, pMyCallbackData1 );
// using wxEvtHandler-derived class directly.
pModel2->ConnectObj( ID_MODEL2, wxEVT_MODEL_NOTIFICATIONS, this, (wxObjectEventFunction) (wxEventFunction) &CMyManager::ProcessNotification, pMyCallbackData2 );

// interesting: connect dynamically to handle a toolbar click
wxGetApp().ConnectObj( ID_CMDSOMEACTION, wxEVT_COMMAND_TOOL_CLICKED, this, (wxObjectEventFunction) (wxEventFunction) &CMyManager::ProcessToolbarClicked );
}

void CMyManager::ProcessNotification( wxEvent& event )
{
// handling code
}

void CMyManager::ProcessToolbarClicked( wxEvent& event )
{
// handling code
}

CMyManager::~CMyManager()
{
// safe 'disconnect all' method
m_pModel1->m_notifier.DisconnectObj( this );
m_pModel2->DisconnectObj( this );
wxGetApp().DisconnectObj( this );
}
[/syntax]

My post is mainly to ask people if there is an interest in having this sort of functionality in wxWidgets and to gather questions and suggestions. Basically, I want to know if it makes sense to continue this further, and make it go in a direction that people is interested in.

I've been using wxWidgets 2.4.2 as my reference code, but I don't think the functionality in 2.5.x is any different than 2.4.x's with respect to what I use.

Sorry for the clumsiness of the post but I don't have much time today.

Ideas, suggestions, comments are all welcome :)

Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg » Tue Nov 02, 2004 10:22 am

I wanted to reply to this post. YES I am interested. You should however document it very well, and provide a few samples. If you want this to be accepted by the wxWidgets community it should also fit in the contrib model (dir structure) so Julian or who else can easily fit it in when it is really used by the majority.

I would suggest CMake for compilation, or use the Bakefiles so everybody (Mac, Windows, Linux) can compile them. I wanted to look into Bakefiles, but due to a lacking GUI to create the bakefiles itself (I am reluctant in learning another script XML based language) I prefer CMake.

By the by ... maybe you should also post this on the mailing list (wx-user and wx-dev) so core devs can take a look at it and help you. It sounds really interesting.

ps. I moved this to the announce section as you are announcing it more then requesting help..



Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb

ezequielv
Earned a small fee
Earned a small fee
Posts: 19
Joined: Sun Oct 10, 2004 9:20 pm
Location: Berkshire, England

Post by ezequielv » Tue Nov 02, 2004 10:29 am

Jorg wrote:I wanted to reply to this post. YES I am interested. You should however document it very well, and provide a few samples. If you want this to be accepted by the wxWidgets community it should also fit in the contrib model (dir structure) so Julian or who else can easily fit it in when it is really used by the majority.

I would suggest CMake for compilation, or use the Bakefiles so everybody (Mac, Windows, Linux) can compile them. I wanted to look into Bakefiles, but due to a lacking GUI to create the bakefiles itself (I am reluctant in learning another script XML based language) I prefer CMake.

ps. I moved this to the announce section as you are announcing it more then requesting help..

Regards,
- Jorgen
Fantastic! My idea is to document it very well, as it fits the event handling model very well, although it does not require any hacking to wxWidgets itself :)

As for the building process, it's a personal mission to use something that works, it's portable, and can integrate well with other building systems (note this last one is kind of tricky). For example, Boost has its own building program (I don't remember the name just now), GNU/Linux use autotools these days (I can't make my mind as to use that and target GNU-based systems such as Linux and Cygwin, for example), and there are several other well-intentioned building tools available. I came across CMake yesterday browsing your wxWidgets website ;) and it looks promising.

On the other hand, wxGTK use autotools to detect configuration options, libraries, etc., so I'm not really sure CMake is necessarilly right for this. What do you think?

Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg » Tue Nov 02, 2004 10:38 am

Hi,

You must think of CMake as a tool that distantiates you from the autoconfig tools from the OS it is ran on. For example:

On Windows it can generate
- Makefiles (NMAKE)
- Visual Studio .NET
- Visual Studio 6

On Linux it can generate:
- Makefiles
- KDevelop files
- ?

On MAC it can generate:
- Makefiles

All those projects spring from one and the same script you are using. The OS dependent flags are kept abstract by shared directives so you don't have to figure that out. So with one script this all is maintained.

For example, I had wxTreeMultiCtrl and could only test it on linux and win32. Someone with HP-UX wanted to use it as well. It appeared one tiny darn directive in the compiler flags was making that HP-UX compiler gag and generate faulty code. I never knew, he never knew, but the CMake guys knew. When I converted my build env to CMake, the HP-UX files that were auto generated worked flawlessly.

So, this is what CMake does. I think the effort they put in it is great. And all my controls are in use everywhere, nobody ever complained about missing project files (since they also have to use CMake to compile my source).

As for the observer pattern, I am looking forward in using it in one of my projects. I already worked some with other patterns and tried to create my own observer pattern once. So if you need it reviewed I would like to help you with that ..

Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb

ezequielv
Earned a small fee
Earned a small fee
Posts: 19
Joined: Sun Oct 10, 2004 9:20 pm
Location: Berkshire, England

Post by ezequielv » Tue Nov 02, 2004 10:48 am

Jorg wrote:All those projects spring from one and the same script you are using. The OS dependent flags are kept abstract by shared directives so you don't have to figure that out. So with one script this all is maintained.

For example, I had wxTreeMultiCtrl and could only test it on linux and win32. Someone with HP-UX wanted to use it as well. It appeared one tiny darn directive in the compiler flags was making that HP-UX compiler gag and generate faulty code. I never knew, he never knew, but the CMake guys knew. When I converted my build env to CMake, the HP-UX files that were auto generated worked flawlessly.

So, this is what CMake does. I think the effort they put in it is great. And all my controls are in use everywhere, nobody ever complained about missing project files (since they also have to use CMake to compile my source).
Yes, it does sound great. It comforts me knowing that you have all your wxWidgets contributions source code using the CMake build system. If there is a problem in the future or with integrating the code to wxWidgets, well, there'll be at least two of us :)

Just remember that autotools are (supposedly) also meant to generate standard Makefiles. aclocal && automake && autoconf && ./configure && make :)
Jorg wrote:As for the observer pattern, I am looking forward in using it in one of my projects. I already worked some with other patterns and tried to create my own observer pattern once. So if you need it reviewed I would like to help you with that ..
Sure thing. I'll be tidying things up before releasing even the first version.

One more thing. Is there any "standard" unit testing system in use for making sure wxWidgets works? I mean, I could try and (learn and) use cppunit, but I want to concentrate on coding instead of unit testing at this stage. On the other hand, I want to make sure the code actually works, and for this sort of non-GUI code unit testing would be a great asset.

Edit: fixed typo

Ryan Wilcox
I live to help wx-kind
I live to help wx-kind
Posts: 194
Joined: Mon Aug 30, 2004 1:26 pm
Location: PA, USA
Contact:

Post by Ryan Wilcox » Tue Nov 02, 2004 2:47 pm

the wxWidgets core devs use CppUnit. I actually prefer something a little lighter and use a modified version of Chuck Allison's TestSuite, from an article in the C++ Users Journal. With a small GUI wrapper around this, to run my unit tests I simply launch my main program, and click the "Test" button.

See http://www.wilcoxd.com/products/WDTestHarness.html for more info.
Ryan Wilcox
Wilcox Development Solutions
http://www.wilcoxd.com

ezequielv
Earned a small fee
Earned a small fee
Posts: 19
Joined: Sun Oct 10, 2004 9:20 pm
Location: Berkshire, England

Post by ezequielv » Tue Nov 02, 2004 2:52 pm

Ryan Wilcox wrote:the wxWidgets core devs use CppUnit. I actually prefer something a little lighter and use a modified version of Chuck Allison's TestSuite, from an article in the C++ Users Journal. With a small GUI wrapper around this, to run my unit tests I simply launch my main program, and click the "Test" button.
Cheers, Ryan. I'll look into that. I'll still be considering cppunit, but I have to factor the time-to-production in the equation :)

User avatar
tierra
Site Admin
Site Admin
Posts: 1343
Joined: Sun Aug 29, 2004 7:14 pm
Location: Salt Lake City, Utah, USA
Contact:

Post by tierra » Tue Nov 02, 2004 10:38 pm

Mmmmm... Observer pattern....

This is very handy in Java, I don't see why it wouldn't be helpful here.

gunnar
In need of some credit
In need of some credit
Posts: 5
Joined: Wed Oct 13, 2004 11:27 am

Post by gunnar » Sat Jan 15, 2005 5:10 pm

Hello ezequielv,
this stuff seems rather nice for wxWidgets users.
But now there are more than 2 month since the last post.
Is there an chance, to get acess to your code, ezequielv?

regards,
gunnar
Get the music out of wxWidgets, use wxMusik ;-)
from http://musik.berlios.de

ezequielv
Earned a small fee
Earned a small fee
Posts: 19
Joined: Sun Oct 10, 2004 9:20 pm
Location: Berkshire, England

Project not dead, only slightly delayed...

Post by ezequielv » Sun Jan 16, 2005 11:00 am

gunnar wrote:Hello ezequielv,
this stuff seems rather nice for wxWidgets users.
But now there are more than 2 month since the last post.
Is there an chance, to get acess to your code, ezequielv?
Sorry, I've been busy :? (setting up Gentoo Linux at my laptop and struggling with the dodgy hardware it has).

However, I *do* have some code working, although not thoroughly tested. I'd like to create a project at, say, sf.net and host it there. Maybe I'll do so in the next few days, if there's enough interest.

The interface to each of the classes is still not deffinitive, but some things are very likely to stay as they are (especially at the high level).

So, how many people are interested in this? Please PM me and say "I do" :) . If it's only a few people, maybe I'd just add some copyright and license information to my source files and send them privately to those interested. At least until I have some time and host them properly @sf or somewhere else.

gunnar
In need of some credit
In need of some credit
Posts: 5
Joined: Wed Oct 13, 2004 11:27 am

Post by gunnar » Sun Jan 16, 2005 1:05 pm

Hmm i am too dumb to figure out how to send a private mail.
So i make a public "I do" request.

regards,
gunnar
Get the music out of wxWidgets, use wxMusik ;-)
from http://musik.berlios.de

ezequielv
Earned a small fee
Earned a small fee
Posts: 19
Joined: Sun Oct 10, 2004 9:20 pm
Location: Berkshire, England

Post by ezequielv » Sun Jan 16, 2005 8:36 pm

To send a Private Message ("PM"), just click on the "PM" link just at the bottom of a post made by the user you want to send the message to. For example, to send a PM to me, you'd click on the "PM" link just below this text 8)

Post Reply