X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=PPI%2FEvents.hh;h=3f2fc25b25bc694456b14ee0af70c02be97152d4;hb=81f84badf27b66dbadec9890646ca1193e998505;hp=0a89adb062dfe107d0794e2421f427879209f668;hpb=31d85cd6b8e03c5ecc924ca8892906be1bab702f;p=senf.git diff --git a/PPI/Events.hh b/PPI/Events.hh index 0a89adb..3f2fc25 100644 --- a/PPI/Events.hh +++ b/PPI/Events.hh @@ -1,6 +1,8 @@ -// Copyright (C) 2007 -// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) -// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// $Id$ +// +// Copyright (C) 2007 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund // // This program is free software; you can redistribute it and/or modify @@ -21,54 +23,181 @@ /** \file \brief Events public header */ -#ifndef HH_Events_ -#define HH_Events_ 1 +#ifndef HH_SENF_PPI_Events_ +#define HH_SENF_PPI_Events_ 1 // Custom includes +#include +#include "../Scheduler/ClockService.hh" +#include "predecl.hh" //#include "Events.mpp" ///////////////////////////////hh.p//////////////////////////////////////// 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 + // happens. This setup happens in 'v_enable()'. This internal handler sets up an EventType + // instance if needed and calls 'callback()'. + // + // '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 base-class - /** \brief Generic event interface baseclass + The EventDescriptor base-class provides an interface to control events. - The EventDescriptor baseclass provides an interface to manuplate events in a generic - way. This allows to register events or to temporarily disable event processing. + \see \ref ppi_events */ class EventDescriptor { public: + virtual ~EventDescriptor(); + bool enabled(); ///< Check, whether the event is currently enabled - void enabled(bool); ///< Enable or disable the event + void enabled(bool v); ///< Enable or disable the event protected: - typedef unspecified CallbackType; ///< Fixed type of the (internal) event handler. - - void register(CallbackType handler); ///< Register the event - void unregister(); ///< Unregister the event + EventDescriptor(); private: - virtual void v_register(CallbackType handler) = 0; ///< Called to register the event - virtual void v_unregister() = 0; ///< Called to unregister the event virtual void v_enable() = 0; ///< Called to enable the event delivery - virtual void v_disable() = 0; ///< Called to disable the event delilvery - virtual void v_process() = 0; ///< Called whenever the event is signaled - /**< This virtual method is called \e after every call to - the event handler to provide a hook for further - processing (example: calculate the next time, an - interval timer expires) */ + virtual void v_disable() = 0; ///< Called to disable the event delivery + + virtual bool v_isRegistered() = 0; + + void notifyThrottle(); + void notifyUnthrottle(); + + void registerRoute(ForwardingRoute & route); bool enabled_; + + typedef std::vector Routes; + Routes routes_; + + friend class ForwardingRoute; + }; + + /** \brief Internal: Callback forwarders + */ + template + class EventImplementationHelper + { + protected: + typedef typename detail::EventArgType::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 & binding(); + }; + +#ifndef DOXYGEN + + template + class EventImplementationHelper + { + protected: + void callback(ClockService::clock_type time); + void callback(); + + private: + detail::EventBinding & binding(); + }; + +#endif + + /** \brief Event implementation base class + + EventImplementation provides the base-class for all Event implementations. + \code + class SomeEvent : public EventImplementation + { + 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 EventImplementation + : public EventDescriptor, + public EventImplementationHelper< EventType, EventImplementation > + { + public: + typedef EventType Event; + typedef typename detail::EventArgType::type EventArg; + + module::Module & module() const; ///< Module in which the event is registered + EventManager & manager() const; ///< EventManager of the event + + protected: + EventImplementation(); + + private: + virtual bool v_isRegistered(); + void setBinding(detail::EventBinding & binding); + + detail::EventBinding * binding_; + + friend class EventManager; + friend class EventImplementationHelper< EventType, EventImplementation >; }; }} ///////////////////////////////hh.e//////////////////////////////////////// -//#include "Events.cci" +#include "Events.cci" //#include "Events.ct" -//#include "Events.cti" +#include "Events.cti" #endif @@ -79,4 +208,5 @@ namespace ppi { // indent-tabs-mode: nil // ispell-local-dictionary: "american" // compile-command: "scons -u test" +// comment-column: 40 // End: