Home | History | Annotate | Download | only in extensions
      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