Index: shill_event.h |
diff --git a/shill_event.h b/shill_event.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..09a85e4860c9067965d8d877086b83250147e357 |
--- /dev/null |
+++ b/shill_event.h |
@@ -0,0 +1,115 @@ |
+// Copyright (c) 2009 The Chromium OS Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef SHILL_EVENT_ |
+#define SHILL_EVENT_ |
+ |
+#include <vector> |
+ |
+namespace shill { |
+ |
+// This is a pure-virtual base class for callback objects which can be |
+// queued up and called later. The callback virtual method takes a single |
+// argument, which will be handed to the dispatcher to call on all listeners. |
+template <typename Arg> |
+class Callback { |
+ public: |
+ virtual ~Callback() {} |
+ virtual void Run(Arg arg) = 0; |
+}; |
+ |
+// This is a callback subclass that contains an object and method to call. |
+// These methods take a passed-in argument specific to the callback type. |
+template <typename Class, typename Arg> |
+class ClassCallback : public Callback<Arg> { |
+ public: |
+ typedef void (Class::*MethodType)(Arg arg); |
+ |
+ ClassCallback(Class* object, MethodType method) |
+ : object_(object), method_(method) {} |
+ ~ClassCallback() {} |
+ |
+ void Run(Arg arg) { |
+ (object_->*method_)(arg); |
+ } |
+ |
+ private: |
+ Class* object_; |
+ MethodType method_; |
+}; |
+ |
+// This is the event queue superclass, which contains a function for |
+// dispatching all events in the queue to their respective listeners. |
+// A common "AlertDispatcher()" function is used by subclasses to alert |
+// the central dispatcher that events have been queued and a dispatch |
+// should be performed soon. |
+class EventDispatcher; |
+class EventQueueItem { |
+ public: |
+ EventQueueItem(EventDispatcher *dispatcher); |
+ ~EventQueueItem(); |
+ virtual void Dispatch() = 0; |
+ void AlertDispatcher(); |
+ private: |
+ EventDispatcher *dispatcher_; |
+}; |
+ |
+// This is a template subclass of EventQueueItem which is specific to |
+// a particular argument type. This object contains a queue of events |
+// waiting for delivery to liesteners, and a list of even callbacks -- |
+// the listeners for this event. |
+template <typename Arg> |
+class EventQueue : public EventQueueItem { |
+ typedef Callback<Arg>CallbackType; |
+ |
+ public: |
+ explicit EventQueue(EventDispatcher *dispatcher) |
+ : EventQueueItem(dispatcher) {} |
+ |
+ inline void AddCallback(CallbackType *cb) { |
+ callback_list_.push_back(cb); |
+ } |
+ |
+ void RemoveCallback(CallbackType *cb) { |
+ for (size_t event_idx = 0; event_idx < callback_list_.size(); ++event_idx) { |
+ if (callback_list_[event_idx] == cb) { |
+ callback_list_.erase(callback_list_.begin() + event_idx); |
+ return; |
+ } |
+ } |
+ } |
+ |
+ void Dispatch() { |
+ for (size_t event_idx = 0; event_idx < event_queue_.size(); ++event_idx) |
+ for (size_t call_idx = 0; call_idx < callback_list_.size(); ++call_idx) |
+ callback_list_[call_idx]->Run(event_queue_[event_idx]); |
+ event_queue_.clear(); |
+ } |
+ |
+ void AddEvent(Arg arg) { |
+ event_queue_.push_back(arg); |
+ AlertDispatcher(); |
+ } |
+ |
+ private: |
+ std::vector<CallbackType *> callback_list_; |
+ std::vector<Arg> event_queue_; |
+}; |
+ |
+// This is the main event dispatcher. It contains a central instance, and |
+// is the entity responsible for dispatching events out of all queues to |
+// their listeners during the idle loop. |
+class EventDispatcher { |
+ public: |
+ void DispatchEvents(); |
+ void ExecuteOnIdle(); |
+ void RegisterCallbackQueue(EventQueueItem *queue); |
+ void UnregisterCallbackQueue(EventQueueItem *queue); |
+ private: |
+ std::vector<EventQueueItem*> queue_list_; |
+}; |
+ |
+} // namespace shill |
+ |
+#endif // SHILL_EVENT_ |