Thread: Best way to fire events in C++?

  1. #1
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544

    Best way to fire events in C++?

    I've got some code which fires multiple events and I'm trying to put it into a reusable class. I'm wondering what is considered the best method to make events available from a C++ class. Plain C style callback functions? Some sort of class based system (overridden functions in a derived class, for example)? Thanks.

  2. #2
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    Another possible solution is a queue similiar to a message queue in windows. Essentially its either on the server (send) side or client (receiver) side.

    Kuphryn

  3. #3
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    Most of us actually avoid events like the plague due to hard to catch race conditions caused by the next to useless PulseEvent. Semaphores can be used instead but are slower due to kernel transitions.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Another possible solution is a queue similiar to a message queue in windows. Essentially its either on the server (send) side or client (receiver) side.
    This is an interesting idea. However, the program would already be running a Windows message loop, so I'm not sure how practical a secondary message pump would be. Window messages would be an option, but there may be no window. I'm more interested in a callback solution. I'm unsure what the preferred callback pattern is in C++. Should the callbacks be standalone C style functions, or part of a class? If I use a class, is it possible to make it so that not all of the event functions need to be implemented?
    Most of us actually avoid events like the plague due to hard to catch race conditions caused by the next to useless PulseEvent. Semaphores can be used instead but are slower due to kernel transitions.
    Sorry, my post wasn't entirely clear. I was not talking about Windows event objects, rather triggered events. For example, one event is the screen saver starting, another is the network cable unplugged. I'm wondering how, once received by my class, these events would best be dispatched to the user code.

  5. #5
    Magically delicious LuckY's Avatar
    Join Date
    Oct 2001
    Posts
    856
    It's quite interesting that you ask about this because I'm working on exactly such a thing right now. The way I've implementing it is within a wrapper interface to the API. (Btw, shouldn't this be on the Windows board?) There are two points at which you can intercept the messages of which you're speaking, but it should be obvious that they would not be possible in an MFC app. First, in my message loop I call the primary window's process_message() function which acts similar to PreTranslateMessage(). Now, this is probably not going to work for you because it assumes and depends too many variables. The second method would be to have an event-handler installation procedure that maps specific messages to a [member] function of your class. Then in your WindowProcedure the first thing you can do is check the map to see if the msg is mapped to a function. If it is, invoke it (and check the return value to determine if the message should be processed any further). Otherwise, just DefWindowProc() as usual.

    Here's some pseudocode in an effort to provide you with a better understanding of my suggestion:
    Code:
    install_event_handler(msg_you_want, function_pointer_to_your_handler);// call to the event handler installation function
    
    // now here's what you can do in your WindowProc
    iterator itr = the_message_map.find(msg);
    if (itr != the_map.end())
      itr->second(wparam, lparam);
    It's not going to be as simple as I've written it here, but it should get some idea juices flowing.

  6. #6
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    Whats going to be calling your callbacks? What exactly are you trying to do? Would the command pattern with generalized functors be any help. Hard to tell without more info.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  7. #7
    Toaster Zach L.'s Avatar
    Join Date
    Aug 2001
    Posts
    2,686
    I'm rather fond of the observer pattern myself. Since I'm too lazy at the moment to write much, here is a decent looking link.

    You can of course, modify this. Perhaps, have subject adapters and listener adapters for your objects, and run all messages through a central observer-manager of sorts.
    The word rap as it applies to music is the result of a peculiar phonological rule which has stripped the word of its initial voiceless velar stop.

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Command and Observer patterns typically use object interfaces and polymorphism as the "callback mechanism". This is a common method of generalizing a callback with a known interface.

    Another way of generalizing a callback with a known interface is to use a functor object as a templated type. This method can also utilize polymorphism but isn't needed. For example, the STL uses this method when ever a predicate of some sort (pun intended) is needed.

    boost::function can be a usefull tool when designing a framework that involves callbacks.

    gg

  9. #9
    Registered User
    Join Date
    Aug 2003
    Posts
    470
    I've got some code which fires multiple events and I'm trying to put it into a reusable class. I'm wondering what is considered the best method to make events available from a C++ class. Plain C style callback functions? Some sort of class based system (overridden functions in a derived class, for example)? Thanks.
    If you have a lot of C++ events, you could try using a slot library. The boost library has one and so does the gnome libraries. Otherwise, I'd just go with what the other posters said.

  10. #10
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    OK, I've been madly reading up on event maps (thanks LuckY), the command pattern (thanks Stoned_Coder & Codeplug), the observer pattern (thanks Zach L.), delegates (which seem very similar to the signal/slot pattern) and the signal/slot pattern (also good PDF writeup) (thanks okinrus).

    While I think all these solutions are workable (although the observer pattern would seem to be best suited for situations where the subject maintains state that can be retrieved by the observer), the signal/slot pattern seems the neatest. I find it a little ironic, that given all the power of the C++, we get back to nearly C style function callbacks (albeit callbacks that can be attached to a class and have lifetime management).

    However, in the end, I went with overridden methods in a class derived from the source sink. This is not 100% ideal, but means no extra code to handle event dispatching. The user code looks like this:
    Code:
    class MySensSink : public CSensSink
    {
      STDMETHODIMP StartScreenSaver(BSTR bstrUserName)
      {
    	puts("Start Overridden");
    	return NOERROR;
      }
    
      STDMETHODIMP StopScreenSaver(BSTR bstrUserName)
      {
    	puts("Stop Overridden");
    	return NOERROR;
      }
    
      /* Other overridden methods here. */
    };
    
    
    int main(void)
    {
    	CSensSystem sens;
    	MySensSink* sink = new MySensSink;
    
    	CoInitialize(NULL);
    
    	sens.HookEvent(SENS_StartScreenSaver,  sink);
    	sens.HookEvent(SENS_StopScreenSaver, sink);
    
    	...
    }
    The main drawback with this solution is that CSensSink, being a COM object, has internal lifetime management (delete this is called when the ref count reaches zero). This means that the derived event sink cannot be created on the stack or explicitly deleted. As I said, not 100% ideal...

    Thanks everybody for the help, I've learnt a lot. I'll post the complete code when it's finished (in the Windows forum).
    Last edited by anonytmouse; 06-13-2005 at 02:02 PM.

  11. #11
    Registered User
    Join Date
    Jul 2005
    Posts
    3
    Hey,

    I started writing some code in c++ where I raise signals.
    Does anyone know if it's possible to "catch" signals (like events) in vb.net?
    (i'm wrapping my c++ function, so I wanted to do something like raising events, without all the complicated code; hence signals; but now I dont know how to handle the event/signal in vb.net)

    If raising signals cannot be handled in vb.net, how would I raise something like events in c++ and have corresponding handlers in vb.net? (Does anyone know the syntax?)

    THANKS!!

  12. #12
    Registered User
    Join Date
    Jul 2005
    Posts
    3
    anyone??

  13. #13
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Welcome to the boards.

    Please read the Forum Guidelines, paying special attention to #5.

    A listing of the different board topics can be found here: http://cboard.cprogramming.com/index.php

    As you can see, there is no "VB.NET" board. The C# board may be able to help you in generic ".NET" terms.

    gg

  14. #14
    Registered User
    Join Date
    Jul 2005
    Posts
    3
    sorry i didnt know.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. seismic events program
    By santaclaus in forum C Programming
    Replies: 16
    Last Post: 11-23-2003, 03:23 PM
  2. ATL: fireing events from a Instanced object
    By CHECCO in forum C++ Programming
    Replies: 2
    Last Post: 09-03-2002, 07:05 AM
  3. forest fire
    By Kohatian 3279 in forum C++ Programming
    Replies: 0
    Last Post: 04-18-2002, 01:52 PM
  4. Windows events
    By Unregistered in forum Windows Programming
    Replies: 1
    Last Post: 12-22-2001, 01:44 PM