blob: 09a85e4860c9067965d8d877086b83250147e357 [file] [log] [blame]
Paul Stewart75897df2011-04-27 09:05:53 -07001// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SHILL_EVENT_
6#define SHILL_EVENT_
7
8#include <vector>
9
10namespace shill {
11
12// This is a pure-virtual base class for callback objects which can be
13// queued up and called later. The callback virtual method takes a single
14// argument, which will be handed to the dispatcher to call on all listeners.
15template <typename Arg>
16class Callback {
17 public:
18 virtual ~Callback() {}
19 virtual void Run(Arg arg) = 0;
20};
21
22// This is a callback subclass that contains an object and method to call.
23// These methods take a passed-in argument specific to the callback type.
24template <typename Class, typename Arg>
25class ClassCallback : public Callback<Arg> {
26 public:
27 typedef void (Class::*MethodType)(Arg arg);
28
29 ClassCallback(Class* object, MethodType method)
30 : object_(object), method_(method) {}
31 ~ClassCallback() {}
32
33 void Run(Arg arg) {
34 (object_->*method_)(arg);
35 }
36
37 private:
38 Class* object_;
39 MethodType method_;
40};
41
42// This is the event queue superclass, which contains a function for
43// dispatching all events in the queue to their respective listeners.
44// A common "AlertDispatcher()" function is used by subclasses to alert
45// the central dispatcher that events have been queued and a dispatch
46// should be performed soon.
47class EventDispatcher;
48class EventQueueItem {
49 public:
50 EventQueueItem(EventDispatcher *dispatcher);
51 ~EventQueueItem();
52 virtual void Dispatch() = 0;
53 void AlertDispatcher();
54 private:
55 EventDispatcher *dispatcher_;
56};
57
58// This is a template subclass of EventQueueItem which is specific to
59// a particular argument type. This object contains a queue of events
60// waiting for delivery to liesteners, and a list of even callbacks --
61// the listeners for this event.
62template <typename Arg>
63class EventQueue : public EventQueueItem {
64 typedef Callback<Arg>CallbackType;
65
66 public:
67 explicit EventQueue(EventDispatcher *dispatcher)
68 : EventQueueItem(dispatcher) {}
69
70 inline void AddCallback(CallbackType *cb) {
71 callback_list_.push_back(cb);
72 }
73
74 void RemoveCallback(CallbackType *cb) {
75 for (size_t event_idx = 0; event_idx < callback_list_.size(); ++event_idx) {
76 if (callback_list_[event_idx] == cb) {
77 callback_list_.erase(callback_list_.begin() + event_idx);
78 return;
79 }
80 }
81 }
82
83 void Dispatch() {
84 for (size_t event_idx = 0; event_idx < event_queue_.size(); ++event_idx)
85 for (size_t call_idx = 0; call_idx < callback_list_.size(); ++call_idx)
86 callback_list_[call_idx]->Run(event_queue_[event_idx]);
87 event_queue_.clear();
88 }
89
90 void AddEvent(Arg arg) {
91 event_queue_.push_back(arg);
92 AlertDispatcher();
93 }
94
95 private:
96 std::vector<CallbackType *> callback_list_;
97 std::vector<Arg> event_queue_;
98};
99
100// This is the main event dispatcher. It contains a central instance, and
101// is the entity responsible for dispatching events out of all queues to
102// their listeners during the idle loop.
103class EventDispatcher {
104 public:
105 void DispatchEvents();
106 void ExecuteOnIdle();
107 void RegisterCallbackQueue(EventQueueItem *queue);
108 void UnregisterCallbackQueue(EventQueueItem *queue);
109 private:
110 std::vector<EventQueueItem*> queue_list_;
111};
112
113} // namespace shill
114
115#endif // SHILL_EVENT_