1 // Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_EVENT_BASE_H_ 6 #define PPAPI_CPP_EXTENSIONS_EVENT_BASE_H_ 7 8 #include "ppapi/c/extensions/dev/ppb_ext_events_dev.h" 9 #include "ppapi/c/pp_macros.h" 10 #include "ppapi/c/pp_stdint.h" 11 #include "ppapi/c/pp_var.h" 12 #include "ppapi/cpp/extensions/from_var_converter.h" 13 #include "ppapi/cpp/instance_handle.h" 14 #include "ppapi/cpp/logging.h" 15 16 namespace pp { 17 namespace ext { 18 namespace internal { 19 20 // This file contains base classes for events. Usually you don't need to use 21 // them directly. 22 // 23 // For each event type, there is a corresponding event class derived from 24 // EventBase[0-3]. The event class defines a Listener interface and exposes the 25 // public methods of GenericEventBase. 26 // 27 // Take pp::ext::alarms::OnAlarmEvent_Dev as example, your code to listen to the 28 // event would look like this: 29 // 30 // class MyListener : public pp::ext::alarms::OnAlarmEvent_Dev { 31 // ... 32 // // The parameter is a non-const reference so you could directly modify it 33 // // if necessary. 34 // virtual void OnAlarm(Alarm_Dev& alarm) { 35 // ...handle the event... 36 // } 37 // }; 38 // 39 // MyListener on_alarm_listener; 40 // // The listener is not owned by the event and must outlive it. 41 // pp::ext::alarms::OnAlarmEvent_Dev on_alarm(instance, &on_alarm_listener); 42 // on_alarm.StartListening(); 43 // ... 44 // // It is guaranteed that |on_alarm_listener| won't get called after 45 // // |on_alarm| goes away. So this step is optional. 46 // on_alarm.StopListening(); 47 48 class GenericEventBase { 49 public: 50 bool StartListening(); 51 void StopListening(); 52 53 bool IsListening() const { return listener_id_ != 0; } 54 uint32_t listener_id() const { return listener_id_; } 55 56 protected: 57 GenericEventBase(const InstanceHandle& instance, 58 const PP_Ext_EventListener& pp_listener); 59 ~GenericEventBase(); 60 61 InstanceHandle instance_; 62 uint32_t listener_id_; 63 const PP_Ext_EventListener pp_listener_; 64 65 private: 66 // Disallow copying and assignment. 67 GenericEventBase(const GenericEventBase&); 68 GenericEventBase& operator=(const GenericEventBase&); 69 }; 70 71 // EventBase[0-3] are event base classes which can be instantiated with a 72 // pointer to a PP_Ext_EventListener creation function and the input parameter 73 // types of the listener callback. 74 // 75 // For example, EvenBase1<PP_Ext_Alarms_OnAlarm_Dev, Alarm_Dev> deals with 76 // the event type defined by the PP_Ext_Alarms_OnAlarm_Dev function pointer. And 77 // it defines a pure virtual method as the listener callback: 78 // virtual void Callback(Alarm_Dev&) = 0; 79 80 typedef PP_Ext_EventListener (*CreatePPEventListener0)( 81 void (*)(uint32_t, void*), void*); 82 template <const CreatePPEventListener0 kCreatePPEventListener0> 83 class EventBase0 : public GenericEventBase { 84 public: 85 explicit EventBase0(const InstanceHandle& instance) 86 : PP_ALLOW_THIS_IN_INITIALIZER_LIST( 87 GenericEventBase(instance, 88 kCreatePPEventListener0(&CallbackThunk, this))) { 89 } 90 91 virtual ~EventBase0() {} 92 93 private: 94 virtual void Callback() = 0; 95 96 static void CallbackThunk(uint32_t listener_id, void* user_data) { 97 EventBase0<kCreatePPEventListener0>* event_base = 98 static_cast<EventBase0<kCreatePPEventListener0>*>(user_data); 99 PP_DCHECK(listener_id == event_base->listener_id_); 100 // Suppress unused variable warnings. 101 static_cast<void>(listener_id); 102 103 event_base->Callback(); 104 } 105 106 // Disallow copying and assignment. 107 EventBase0(const EventBase0<kCreatePPEventListener0>&); 108 EventBase0<kCreatePPEventListener0>& operator=( 109 const EventBase0<kCreatePPEventListener0>&); 110 }; 111 112 typedef PP_Ext_EventListener (*CreatePPEventListener1)( 113 void (*)(uint32_t, void*, PP_Var), void*); 114 template <const CreatePPEventListener1 kCreatePPEventListener1, class A> 115 class EventBase1 : public GenericEventBase { 116 public: 117 explicit EventBase1(const InstanceHandle& instance) 118 : PP_ALLOW_THIS_IN_INITIALIZER_LIST( 119 GenericEventBase(instance, 120 kCreatePPEventListener1(&CallbackThunk, this))) { 121 } 122 123 virtual ~EventBase1() {} 124 125 private: 126 virtual void Callback(A&) = 0; 127 128 static void CallbackThunk(uint32_t listener_id, 129 void* user_data, 130 PP_Var var_a) { 131 EventBase1<kCreatePPEventListener1, A>* event_base = 132 static_cast<EventBase1<kCreatePPEventListener1, A>*>(user_data); 133 PP_DCHECK(listener_id == event_base->listener_id_); 134 // Suppress unused variable warnings. 135 static_cast<void>(listener_id); 136 137 FromVarConverter<A> a(var_a); 138 event_base->Callback(a.value()); 139 } 140 141 // Disallow copying and assignment. 142 EventBase1(const EventBase1<kCreatePPEventListener1, A>&); 143 EventBase1<kCreatePPEventListener1, A>& operator=( 144 const EventBase1<kCreatePPEventListener1, A>&); 145 }; 146 147 typedef PP_Ext_EventListener (*CreatePPEventListener2)( 148 void (*)(uint32_t, void*, PP_Var, PP_Var), void*); 149 template <const CreatePPEventListener2 kCreatePPEventListener2, 150 class A, 151 class B> 152 class EventBase2 : public GenericEventBase { 153 public: 154 explicit EventBase2(const InstanceHandle& instance) 155 : PP_ALLOW_THIS_IN_INITIALIZER_LIST( 156 GenericEventBase(instance, 157 kCreatePPEventListener2(&CallbackThunk, this))) { 158 } 159 160 virtual ~EventBase2() {} 161 162 private: 163 virtual void Callback(A&, B&) = 0; 164 165 static void CallbackThunk(uint32_t listener_id, 166 void* user_data, 167 PP_Var var_a, 168 PP_Var var_b) { 169 EventBase2<kCreatePPEventListener2, A, B>* event_base = 170 static_cast<EventBase2<kCreatePPEventListener2, A, B>*>(user_data); 171 PP_DCHECK(listener_id == event_base->listener_id_); 172 // Suppress unused variable warnings. 173 static_cast<void>(listener_id); 174 175 FromVarConverter<A> a(var_a); 176 FromVarConverter<B> b(var_b); 177 event_base->Callback(a.value(), b.value()); 178 } 179 180 // Disallow copying and assignment. 181 EventBase2(const EventBase2<kCreatePPEventListener2, A, B>&); 182 EventBase2<kCreatePPEventListener2, A, B>& operator=( 183 const EventBase2<kCreatePPEventListener2, A, B>&); 184 }; 185 186 typedef PP_Ext_EventListener (*CreatePPEventListener3)( 187 void (*)(uint32_t, void*, PP_Var, PP_Var, PP_Var), void*); 188 template <const CreatePPEventListener3 kCreatePPEventListener3, 189 class A, 190 class B, 191 class C> 192 class EventBase3 : public GenericEventBase { 193 public: 194 explicit EventBase3(const InstanceHandle& instance) 195 : PP_ALLOW_THIS_IN_INITIALIZER_LIST( 196 GenericEventBase(instance, 197 kCreatePPEventListener3(&CallbackThunk, this))) { 198 } 199 200 virtual ~EventBase3() {} 201 202 private: 203 virtual void Callback(A&, B&, C&) = 0; 204 205 static void CallbackThunk(uint32_t listener_id, 206 void* user_data, 207 PP_Var var_a, 208 PP_Var var_b, 209 PP_Var var_c) { 210 EventBase3<kCreatePPEventListener3, A, B, C>* event_base = 211 static_cast<EventBase3<kCreatePPEventListener3, A, B, C>*>(user_data); 212 PP_DCHECK(listener_id == event_base->listener_id_); 213 // Suppress unused variable warnings. 214 static_cast<void>(listener_id); 215 216 FromVarConverter<A> a(var_a); 217 FromVarConverter<B> b(var_b); 218 FromVarConverter<C> c(var_c); 219 event_base->Callback(a.value(), b.value(), c.value()); 220 } 221 222 // Disallow copying and assignment. 223 EventBase3(const EventBase3<kCreatePPEventListener3, A, B, C>&); 224 EventBase3<kCreatePPEventListener3, A, B, C>& operator=( 225 const EventBase3<kCreatePPEventListener3, A, B, C>&); 226 }; 227 228 } // namespace internal 229 } // namespace ext 230 } // namespace pp 231 232 #endif // PPAPI_CPP_EXTENSIONS_EVENT_BASE_H_ 233