NEW FILE HEADER / COPYRIGHT FORMAT
[senf.git] / PPI / Events.hh
index cb21dd7..75e8a21 100644 (file)
@@ -1,6 +1,6 @@
 // Copyright (C) 2007 
-// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS)
-// Kompetenzzentrum fuer Satelitenkommunikation (SatCom)
+// Fraunhofer Institute for Open Communication Systems (FOKUS) 
+// Competence Center NETwork research (NET), St. Augustin, GERMANY 
 //     Stefan Bund <g0dil@berlios.de>
 //
 // This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,8 @@
 #define HH_Events_ 1
 
 // Custom includes
-#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <vector>
+#include "../Scheduler/ClockService.hh"
 #include "predecl.hh"
 
 //#include "Events.mpp"
 
 namespace senf {
 namespace ppi {
+    
+    /** \defgroup event_group Events
+
+        Events provide notification of events outside the PPI framework: I/O activity, Timers
+        etc. Events are very important since they drive the PPI: Without events, nothing will
+        happen.
+
+        \section event_impl Implementing Events
+
+        All events are derived from EventImplementation which is based on EventDescriptor.
+        \see EventImplementation \n
+            \ref ppi_events        
+     */
 
     // Implementation: The concrete EventDescriptor implementation will need to set things up so
     // some callback (within the EventDescriptor implementation) will be called when the event
@@ -42,10 +56,11 @@ namespace ppi {
     // 'callback()' will access the EventBinding wrapper to find the user-callback to signal. It
     // will do any needed internal processing, call that user callback and clean up afterwards.
 
-    /** \brief Generic event interface baseclass
+    /** \brief Generic event interface base-class
 
-        The EventDescriptor baseclass provides an interface to manipulate events in a generic
-        way. This allows to register events or to temporarily disable event processing.
+        The EventDescriptor base-class provides an interface to control events.
+
+        \see \ref ppi_events
      */ 
     class EventDescriptor
     {
@@ -64,23 +79,107 @@ namespace ppi {
 
         virtual bool v_isRegistered() = 0;
 
+        void notifyThrottle();
+        void notifyUnthrottle();
+
+        void registerRoute(ForwardingRoute & route);
+
         bool enabled_;
+
+        typedef std::vector<ForwardingRoute*> Routes;
+        Routes routes_;
+
+        friend class ForwardingRoute;
+    };
+    
+    /** \brief Internal: Callback forwarders
+     */
+    template <class EventType, class Self>
+    class EventImplementationHelper
+    {
+    protected:
+        typedef typename detail::EventArgType<EventType>::type EventArg;
+
+        void callback(EventArg event, ClockService::clock_type time);
+                                        ///< Forward event to user callback
+                                        /**< \param[in] event Event argument to pass to the user
+                                             callback
+                                             \param[in] time Expected time of the event */
+        void callback(EventArg event);  ///< Forward event to user callback
+                                        /**< \param[in] event Event argument to pass to the user
+                                             callback. */
+
+    private:
+        detail::EventBinding<EventType> & binding();
+    };
+    
+#ifndef DOXYGEN
+
+    template <class Self>
+    class EventImplementationHelper<void,Self>
+    {
+    protected:
+        void callback(ClockService::clock_type time);
+        void callback();
+
+    private:
+        detail::EventBinding<void> & binding();
     };
 
+#endif
+
+    /** \brief Event implementation base class
+
+        EventImplementation provides the base-class for all Event implementations. 
+        \code
+        class SomeEvent : public EventImplementation<SomeEventArg>
+        {
+        public:
+            SomeEvent() {}
+
+        private:
+            virtual void v_enable() {
+                // register cb() to be called when the event occurs
+            }
+
+            virtual void v_disable() {
+                // unregister cb()
+            }
+
+            void cb() {
+                // Build event argument
+                SomeEventArg arg (...); 
+                // Call the event callback
+                callback(arg);
+            }
+        };
+        \endcode
+
+        Every event needs to implement v_enable() and v_disable(). v_enable() should register some
+        member (in the example \c cb() ) to be called whenever the event occurs, while v_disable()
+        should unregister it.
+
+        The \a EventType argument to EventImplementation defines the type of argument passed to the
+        user callback. It defaults to \c void. . This user callback is called from within the
+        registered member (e.g. \c cb() ) by calling the inherited callback() member. This member
+        takes an \a EventType reference as argument which will be forwarded to the user callback. If
+        available, you should also provide the \e expected event time as a second argument.
+     */
     template <class EventType>
     class EventImplementation
-        : public EventDescriptor
+        : public EventDescriptor, 
+          public EventImplementationHelper< EventType, EventImplementation<EventType> >
     {
     public:
         typedef EventType Event;
         typedef typename detail::EventArgType<EventType>::type EventArg;
 
+        module::Module & module() const; ///< Module in which the event is registered
+        EventManager & manager() const; ///< EventManager of the event
+        
     protected:
         EventImplementation();
 
-        void callback(EventArg event, boost::posix_time::ptime time);
-        void callback(EventArg event);
-
     private:
         virtual bool v_isRegistered();
         void setBinding(detail::EventBinding<Event> & binding);
@@ -88,6 +187,7 @@ namespace ppi {
         detail::EventBinding<Event> * binding_;
 
         friend class EventManager;
+        friend class EventImplementationHelper< EventType, EventImplementation<EventType> >;
     };
 
 }}