diff options
Diffstat (limited to 'ppapi/cpp')
-rw-r--r-- | ppapi/cpp/extensions/dev/alarms_dev.cc | 173 | ||||
-rw-r--r-- | ppapi/cpp/extensions/dev/alarms_dev.h | 113 | ||||
-rw-r--r-- | ppapi/cpp/extensions/dev/events_dev.cc | 43 | ||||
-rw-r--r-- | ppapi/cpp/extensions/dev/events_dev.h | 34 | ||||
-rw-r--r-- | ppapi/cpp/extensions/dict_field.h | 69 | ||||
-rw-r--r-- | ppapi/cpp/extensions/event_base.cc | 44 | ||||
-rw-r--r-- | ppapi/cpp/extensions/event_base.h | 232 | ||||
-rw-r--r-- | ppapi/cpp/extensions/ext_output_traits.h | 133 | ||||
-rw-r--r-- | ppapi/cpp/extensions/from_var_converter.h | 100 | ||||
-rw-r--r-- | ppapi/cpp/extensions/optional.h | 91 | ||||
-rw-r--r-- | ppapi/cpp/extensions/to_var_converter.h | 89 | ||||
-rw-r--r-- | ppapi/cpp/output_traits.h | 45 | ||||
-rw-r--r-- | ppapi/cpp/var.cc | 12 | ||||
-rw-r--r-- | ppapi/cpp/var.h | 7 |
14 files changed, 1165 insertions, 20 deletions
diff --git a/ppapi/cpp/extensions/dev/alarms_dev.cc b/ppapi/cpp/extensions/dev/alarms_dev.cc new file mode 100644 index 0000000..a77fed0 --- /dev/null +++ b/ppapi/cpp/extensions/dev/alarms_dev.cc @@ -0,0 +1,173 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/extensions/dev/alarms_dev.h" + +#include "ppapi/cpp/completion_callback.h" +#include "ppapi/cpp/extensions/optional.h" +#include "ppapi/cpp/extensions/to_var_converter.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_Ext_Alarms_Dev_0_1>() { + return PPB_EXT_ALARMS_DEV_INTERFACE_0_1; +} + +} // namespace + +namespace ext { +namespace alarms { + +const char* const Alarm_Dev::kName = "name"; +const char* const Alarm_Dev::kScheduledTime = "scheduledTime"; +const char* const Alarm_Dev::kPeriodInMinutes = "periodInMinutes"; + +Alarm_Dev::Alarm_Dev() + : name(kName), + scheduled_time(kScheduledTime), + period_in_minutes(kPeriodInMinutes) { +} + +Alarm_Dev::~Alarm_Dev() { +} + +bool Alarm_Dev::Populate(const PP_Ext_Alarms_Alarm_Dev& value) { + Var var(value); + + bool result = name.Populate(var); + result = scheduled_time.Populate(var) && result; + result = period_in_minutes.Populate(var) && result; + + return result; +} + +Var Alarm_Dev::CreateVar() const { + Var var; + + name.AddTo(&var); + scheduled_time.AddTo(&var); + period_in_minutes.MayAddTo(&var); + + return var; +} + +const char* const AlarmCreateInfo_Dev::kWhen = "when"; +const char* const AlarmCreateInfo_Dev::kDelayInMinutes = "delayInMinutes"; +const char* const AlarmCreateInfo_Dev::kPeriodInMinutes = "periodInMinutes"; + +AlarmCreateInfo_Dev::AlarmCreateInfo_Dev() + : when(kWhen), + delay_in_minutes(kDelayInMinutes), + period_in_minutes(kPeriodInMinutes) { +} + +AlarmCreateInfo_Dev::~AlarmCreateInfo_Dev() { +} + +bool AlarmCreateInfo_Dev::Populate( + const PP_Ext_Alarms_AlarmCreateInfo_Dev& value) { + Var var(value); + + bool result = when.Populate(var); + result = delay_in_minutes.Populate(var) && result; + result = period_in_minutes.Populate(var) && result; + + return result; +} + +Var AlarmCreateInfo_Dev::CreateVar() const { + Var var; + + when.MayAddTo(&var); + delay_in_minutes.MayAddTo(&var); + period_in_minutes.MayAddTo(&var); + + return var; +} + +Alarms_Dev::Alarms_Dev(const InstanceHandle& instance) : instance_(instance) { +} + +Alarms_Dev::~Alarms_Dev() { +} + +void Alarms_Dev::Create(const Optional<std::string>& name, + const AlarmCreateInfo_Dev& alarm_info) { + if (!has_interface<PPB_Ext_Alarms_Dev_0_1>()) + return; + + internal::ToVarConverter<Optional<std::string> > name_var(name); + internal::ToVarConverter<AlarmCreateInfo_Dev> alarm_info_var(alarm_info); + + return get_interface<PPB_Ext_Alarms_Dev_0_1>()->Create( + instance_.pp_instance(), + name_var.pp_var(), + alarm_info_var.pp_var()); +} + +int32_t Alarms_Dev::Get( + const Optional<std::string>& name, + const CompletionCallbackWithOutput<Alarm_Dev>& callback) { + if (!has_interface<PPB_Ext_Alarms_Dev_0_1>()) + return callback.MayForce(PP_ERROR_NOINTERFACE); + + internal::ToVarConverter<Optional<std::string> > name_var(name); + + return get_interface<PPB_Ext_Alarms_Dev_0_1>()->Get( + instance_.pp_instance(), + name_var.pp_var(), + callback.output(), + callback.pp_completion_callback()); +} + +int32_t Alarms_Dev::GetAll( + const CompletionCallbackWithOutput<std::vector<Alarm_Dev> >& callback) { + if (!has_interface<PPB_Ext_Alarms_Dev_0_1>()) + return callback.MayForce(PP_ERROR_NOINTERFACE); + + return get_interface<PPB_Ext_Alarms_Dev_0_1>()->GetAll( + instance_.pp_instance(), + callback.output(), + callback.pp_completion_callback()); +} + +void Alarms_Dev::Clear(const Optional<std::string>& name) { + if (!has_interface<PPB_Ext_Alarms_Dev_0_1>()) + return; + + internal::ToVarConverter<Optional<std::string> > name_var(name); + + return get_interface<PPB_Ext_Alarms_Dev_0_1>()->Clear( + instance_.pp_instance(), + name_var.pp_var()); +} + +void Alarms_Dev::ClearAll() { + if (!has_interface<PPB_Ext_Alarms_Dev_0_1>()) + return; + + return get_interface<PPB_Ext_Alarms_Dev_0_1>()->ClearAll( + instance_.pp_instance()); +} + +OnAlarmEvent_Dev::OnAlarmEvent_Dev( + const InstanceHandle& instance, + Listener* listener) + : internal::EventBase1<PP_Ext_Alarms_OnAlarm_Dev, Alarm_Dev>(instance), + listener_(listener) { +} + +OnAlarmEvent_Dev::~OnAlarmEvent_Dev() { +} + +void OnAlarmEvent_Dev::Callback(Alarm_Dev& alarm) { + listener_->OnAlarm(alarm); +} + +} // namespace alarms +} // namespace ext +} // namespace pp diff --git a/ppapi/cpp/extensions/dev/alarms_dev.h b/ppapi/cpp/extensions/dev/alarms_dev.h new file mode 100644 index 0000000..762e006 --- /dev/null +++ b/ppapi/cpp/extensions/dev/alarms_dev.h @@ -0,0 +1,113 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_DEV_ALARMS_DEV_H_ +#define PPAPI_CPP_EXTENSIONS_DEV_ALARMS_DEV_H_ + +#include <string> +#include <vector> + +#include "ppapi/c/extensions/dev/ppb_alarms_dev.h" +#include "ppapi/cpp/extensions/dict_field.h" +#include "ppapi/cpp/extensions/event_base.h" +#include "ppapi/cpp/extensions/ext_output_traits.h" +#include "ppapi/cpp/instance_handle.h" +#include "ppapi/cpp/var.h" + +namespace pp { + +template <class T> +class CompletionCallbackWithOutput; + +namespace ext { + +template <class T> +class Optional; + +namespace alarms { + +// Data types ------------------------------------------------------------------ +class Alarm_Dev : public internal::OutputObjectBase { + public: + Alarm_Dev(); + ~Alarm_Dev(); + + bool Populate(const PP_Ext_Alarms_Alarm_Dev& value); + + Var CreateVar() const; + + static const char* const kName; + static const char* const kScheduledTime; + static const char* const kPeriodInMinutes; + + DictField<std::string> name; + DictField<double> scheduled_time; + OptionalDictField<double> period_in_minutes; +}; + +class AlarmCreateInfo_Dev { + public: + AlarmCreateInfo_Dev(); + ~AlarmCreateInfo_Dev(); + + bool Populate(const PP_Ext_Alarms_AlarmCreateInfo_Dev& value); + + Var CreateVar() const; + + static const char* const kWhen; + static const char* const kDelayInMinutes; + static const char* const kPeriodInMinutes; + + OptionalDictField<double> when; + OptionalDictField<double> delay_in_minutes; + OptionalDictField<double> period_in_minutes; +}; + +// Functions ------------------------------------------------------------------- +class Alarms_Dev { + public: + explicit Alarms_Dev(const InstanceHandle& instance); + ~Alarms_Dev(); + + void Create(const Optional<std::string>& name, + const AlarmCreateInfo_Dev& alarm_info); + int32_t Get(const Optional<std::string>& name, + const CompletionCallbackWithOutput<Alarm_Dev>& callback); + int32_t GetAll( + const CompletionCallbackWithOutput<std::vector<Alarm_Dev> >& callback); + void Clear(const Optional<std::string>& name); + void ClearAll(); + + private: + InstanceHandle instance_; +}; + +// Events ---------------------------------------------------------------------- +// Please see ppapi/cpp/extensions/event_base.h for how to use an event class. + +class OnAlarmEvent_Dev + : public internal::EventBase1<PP_Ext_Alarms_OnAlarm_Dev, Alarm_Dev> { + public: + class Listener { + public: + virtual ~Listener() {} + + virtual void OnAlarm(Alarm_Dev& alarm) = 0; + }; + + // |listener| is not owned by this instance and must outlive it. + OnAlarmEvent_Dev(const InstanceHandle& instance, Listener* listener); + virtual ~OnAlarmEvent_Dev(); + + private: + virtual void Callback(Alarm_Dev& alarm); + + Listener* listener_; +}; + +} // namespace alarms +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_DEV_ALARMS_DEV_H_ diff --git a/ppapi/cpp/extensions/dev/events_dev.cc b/ppapi/cpp/extensions/dev/events_dev.cc new file mode 100644 index 0000000..4b51fb5 --- /dev/null +++ b/ppapi/cpp/extensions/dev/events_dev.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/extensions/dev/events_dev.h" + +#include "ppapi/c/extensions/dev/ppb_events_dev.h" +#include "ppapi/cpp/module_impl.h" + +namespace pp { + +namespace { + +template <> const char* interface_name<PPB_Ext_Events_Dev_0_1>() { + return PPB_EXT_EVENTS_DEV_INTERFACE_0_1; +} + +} // namespace + +namespace ext { +namespace events { + +// static +uint32_t Events_Dev::AddListener(PP_Instance instance, + const PP_Ext_EventListener& listener) { + if (!has_interface<PPB_Ext_Events_Dev_0_1>()) + return 0; + return get_interface<PPB_Ext_Events_Dev_0_1>()->AddListener(instance, + listener); +} + +// static +void Events_Dev::RemoveListener(PP_Instance instance, + uint32_t listener_id) { + if (has_interface<PPB_Ext_Events_Dev_0_1>()) { + get_interface<PPB_Ext_Events_Dev_0_1>()->RemoveListener(instance, + listener_id); + } +} + +} // namespace events +} // namespace ext +} // namespace pp diff --git a/ppapi/cpp/extensions/dev/events_dev.h b/ppapi/cpp/extensions/dev/events_dev.h new file mode 100644 index 0000000..e816ca5 --- /dev/null +++ b/ppapi/cpp/extensions/dev/events_dev.h @@ -0,0 +1,34 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_DEV_EVENTS_DEV_H_ +#define PPAPI_CPP_EXTENSIONS_DEV_EVENTS_DEV_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_stdint.h" + +struct PP_Ext_EventListener; + +namespace pp { +namespace ext { +namespace events { + +// This is a simple wrapper of the PPB_Ext_Events_Dev interface. +// +// Usually you don't have to directly use this interface. Instead, you could +// use those more object-oriented event classes. Please see +// ppapi/cpp/extensions/event_base.h for more details. +class Events_Dev { + public: + static uint32_t AddListener(PP_Instance instance, + const PP_Ext_EventListener& listener); + + static void RemoveListener(PP_Instance instance, uint32_t listener_id); +}; + +} // namespace events +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_DEV_EVENTS_DEV_H_ diff --git a/ppapi/cpp/extensions/dict_field.h b/ppapi/cpp/extensions/dict_field.h new file mode 100644 index 0000000..d137025 --- /dev/null +++ b/ppapi/cpp/extensions/dict_field.h @@ -0,0 +1,69 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_DICT_FIELD_H_ +#define PPAPI_CPP_EXTENSIONS_DICT_FIELD_H_ + +#include <string> + +#include "ppapi/cpp/extensions/optional.h" + +namespace pp { + +class Var; + +namespace ext { + +template <class T> +class DictField { + public: + explicit DictField(const std::string& in_key) : key(in_key), value() { + } + + ~DictField() { + } + + // Adds this field to the dictionary var. + bool AddTo(Var* /* var */) const { + // TODO(yzshen): change Var to DictionaryVar and add support. + return true; + } + + bool Populate(const Var& /* var */) { + // TODO(yzshen): change Var to DictionaryVar and add support. + return true; + } + + const std::string key; + T value; +}; + +template <class T> +class OptionalDictField { + public: + explicit OptionalDictField(const std::string& in_key) : key(in_key) { + } + + ~OptionalDictField() { + } + + // Adds this field to the dictionary var, if |value| has been set. + bool MayAddTo(Var* /* var */) const { + // TODO(yzshen): change Var to DictionaryVar and add support + return true; + } + + bool Populate(const Var& /* var */) { + // TODO(yzshen): change Var to DictionaryVar and add support. + return true; + } + + const std::string key; + Optional<T> value; +}; + +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_DICT_FIELD_H_ diff --git a/ppapi/cpp/extensions/event_base.cc b/ppapi/cpp/extensions/event_base.cc new file mode 100644 index 0000000..210b213 --- /dev/null +++ b/ppapi/cpp/extensions/event_base.cc @@ -0,0 +1,44 @@ +// Copyright (c) 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ppapi/cpp/extensions/event_base.h" + +#include "ppapi/cpp/extensions/dev/events_dev.h" + +namespace pp { +namespace ext { +namespace internal { + +GenericEventBase::GenericEventBase( + const InstanceHandle& instance, + const PP_Ext_EventListener& pp_listener) + : instance_(instance), + listener_id_(0), + pp_listener_(pp_listener) { +} + +GenericEventBase::~GenericEventBase() { + StopListening(); +} + +bool GenericEventBase::StartListening() { + if (IsListening()) + return true; + + listener_id_ = events::Events_Dev::AddListener(instance_.pp_instance(), + pp_listener_); + return IsListening(); +} + +void GenericEventBase::StopListening() { + if (!IsListening()) + return; + + events::Events_Dev::RemoveListener(instance_.pp_instance(), listener_id_); + listener_id_ = 0; +} + +} // namespace internal +} // namespace ext +} // namespace pp diff --git a/ppapi/cpp/extensions/event_base.h b/ppapi/cpp/extensions/event_base.h new file mode 100644 index 0000000..8a65fb0 --- /dev/null +++ b/ppapi/cpp/extensions/event_base.h @@ -0,0 +1,232 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_EVENT_BASE_H_ +#define PPAPI_CPP_EXTENSIONS_EVENT_BASE_H_ + +#include "ppapi/c/extensions/dev/ppb_events_dev.h" +#include "ppapi/c/pp_macros.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/c/pp_var.h" +#include "ppapi/cpp/extensions/from_var_converter.h" +#include "ppapi/cpp/instance_handle.h" +#include "ppapi/cpp/logging.h" + +namespace pp { +namespace ext { +namespace internal { + +// This file contains base classes for events. Usually you don't need to use +// them directly. +// +// For each event type, there is a corresponding event class derived from +// EventBase[0-3]. The event class defines a Listener interface and exposes the +// public methods of GenericEventBase. +// +// Take pp::ext::alarms::OnAlarmEvent_Dev as example, your code to listen to the +// event would look like this: +// +// class MyListener : public pp::ext::alarms::OnAlarmEvent_Dev { +// ... +// // The parameter is a non-const reference so you could directly modify it +// // if necessary. +// virtual void OnAlarm(Alarm_Dev& alarm) { +// ...handle the event... +// } +// }; +// +// MyListener on_alarm_listener; +// // The listener is not owned by the event and must outlive it. +// pp::ext::alarms::OnAlarmEvent_Dev on_alarm(instance, &on_alarm_listener); +// on_alarm.StartListening(); +// ... +// // It is guaranteed that |on_alarm_listener| won't get called after +// // |on_alarm| goes away. So this step is optional. +// on_alarm.StopListening(); + +class GenericEventBase { + public: + bool StartListening(); + void StopListening(); + + bool IsListening() const { return listener_id_ != 0; } + uint32_t listener_id() const { return listener_id_; } + + protected: + GenericEventBase(const InstanceHandle& instance, + const PP_Ext_EventListener& pp_listener); + ~GenericEventBase(); + + InstanceHandle instance_; + uint32_t listener_id_; + const PP_Ext_EventListener pp_listener_; + + private: + // Disallow copying and assignment. + GenericEventBase(const GenericEventBase&); + GenericEventBase& operator=(const GenericEventBase&); +}; + +// EventBase[0-3] are event base classes which can be instantiated with a +// pointer to a PP_Ext_EventListener creation function and the input parameter +// types of the listener callback. +// +// For example, EvenBase1<PP_Ext_Alarms_OnAlarm_Dev, Alarm_Dev> deals with +// the event type defined by the PP_Ext_Alarms_OnAlarm_Dev function pointer. And +// it defines a pure virtual method as the listener callback: +// virtual void Callback(Alarm_Dev&) = 0; + +typedef PP_Ext_EventListener (*CreatePPEventListener0)( + void (*)(uint32_t, void*), void*); +template <const CreatePPEventListener0 kCreatePPEventListener0> +class EventBase0 : public GenericEventBase { + public: + explicit EventBase0(const InstanceHandle& instance) + : PP_ALLOW_THIS_IN_INITIALIZER_LIST( + GenericEventBase(instance, + kCreatePPEventListener0(&CallbackThunk, this))) { + } + + virtual ~EventBase0() {} + + private: + virtual void Callback() = 0; + + static void CallbackThunk(uint32_t listener_id, void* user_data) { + EventBase0<kCreatePPEventListener0>* event_base = + static_cast<EventBase0<kCreatePPEventListener0>*>(user_data); + PP_DCHECK(listener_id == event_base->listener_id_); + // Suppress unused variable warnings. + static_cast<void>(listener_id); + + event_base->Callback(); + } + + // Disallow copying and assignment. + EventBase0(const EventBase0<kCreatePPEventListener0>&); + EventBase0<kCreatePPEventListener0>& operator=( + const EventBase0<kCreatePPEventListener0>&); +}; + +typedef PP_Ext_EventListener (*CreatePPEventListener1)( + void (*)(uint32_t, void*, PP_Var), void*); +template <const CreatePPEventListener1 kCreatePPEventListener1, class A> +class EventBase1 : public GenericEventBase { + public: + explicit EventBase1(const InstanceHandle& instance) + : PP_ALLOW_THIS_IN_INITIALIZER_LIST( + GenericEventBase(instance, + kCreatePPEventListener1(&CallbackThunk, this))) { + } + + virtual ~EventBase1() {} + + private: + virtual void Callback(A&) = 0; + + static void CallbackThunk(uint32_t listener_id, + void* user_data, + PP_Var var_a) { + EventBase1<kCreatePPEventListener1, A>* event_base = + static_cast<EventBase1<kCreatePPEventListener1, A>*>(user_data); + PP_DCHECK(listener_id == event_base->listener_id_); + // Suppress unused variable warnings. + static_cast<void>(listener_id); + + FromVarConverter<A> a(var_a); + event_base->Callback(a.value()); + } + + // Disallow copying and assignment. + EventBase1(const EventBase1<kCreatePPEventListener1, A>&); + EventBase1<kCreatePPEventListener1, A>& operator=( + const EventBase1<kCreatePPEventListener1, A>&); +}; + +typedef PP_Ext_EventListener (*CreatePPEventListener2)( + void (*)(uint32_t, void*, PP_Var, PP_Var), void*); +template <const CreatePPEventListener2 kCreatePPEventListener2, + class A, + class B> +class EventBase2 : public GenericEventBase { + public: + explicit EventBase2(const InstanceHandle& instance) + : PP_ALLOW_THIS_IN_INITIALIZER_LIST( + GenericEventBase(instance, + kCreatePPEventListener2(&CallbackThunk, this))) { + } + + virtual ~EventBase2() {} + + private: + virtual void Callback(A&, B&) = 0; + + static void CallbackThunk(uint32_t listener_id, + void* user_data, + PP_Var var_a, + PP_Var var_b) { + EventBase2<kCreatePPEventListener2, A, B>* event_base = + static_cast<EventBase2<kCreatePPEventListener2, A, B>*>(user_data); + PP_DCHECK(listener_id == event_base->listener_id_); + // Suppress unused variable warnings. + static_cast<void>(listener_id); + + FromVarConverter<A> a(var_a); + FromVarConverter<B> b(var_b); + event_base->Callback(a.value(), b.value()); + } + + // Disallow copying and assignment. + EventBase2(const EventBase2<kCreatePPEventListener2, A, B>&); + EventBase2<kCreatePPEventListener2, A, B>& operator=( + const EventBase2<kCreatePPEventListener2, A, B>&); +}; + +typedef PP_Ext_EventListener (*CreatePPEventListener3)( + void (*)(uint32_t, void*, PP_Var, PP_Var, PP_Var), void*); +template <const CreatePPEventListener3 kCreatePPEventListener3, + class A, + class B, + class C> +class EventBase3 : public GenericEventBase { + public: + explicit EventBase3(const InstanceHandle& instance) + : PP_ALLOW_THIS_IN_INITIALIZER_LIST( + GenericEventBase(instance, + kCreatePPEventListener3(&CallbackThunk, this))) { + } + + virtual ~EventBase3() {} + + private: + virtual void Callback(A&, B&, C&) = 0; + + static void CallbackThunk(uint32_t listener_id, + void* user_data, + PP_Var var_a, + PP_Var var_b, + PP_Var var_c) { + EventBase3<kCreatePPEventListener3, A, B, C>* event_base = + static_cast<EventBase3<kCreatePPEventListener3, A, B, C>*>(user_data); + PP_DCHECK(listener_id == event_base->listener_id_); + // Suppress unused variable warnings. + static_cast<void>(listener_id); + + FromVarConverter<A> a(var_a); + FromVarConverter<B> b(var_b); + FromVarConverter<C> c(var_c); + event_base->Callback(a.value(), b.value(), c.value()); + } + + // Disallow copying and assignment. + EventBase3(const EventBase3<kCreatePPEventListener3, A, B, C>&); + EventBase3<kCreatePPEventListener3, A, B, C>& operator=( + const EventBase3<kCreatePPEventListener3, A, B, C>&); +}; + +} // namespace internal +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_EVENT_BASE_H_ diff --git a/ppapi/cpp/extensions/ext_output_traits.h b/ppapi/cpp/extensions/ext_output_traits.h new file mode 100644 index 0000000..b49ff9f --- /dev/null +++ b/ppapi/cpp/extensions/ext_output_traits.h @@ -0,0 +1,133 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ +#define PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ + +#include <vector> + +#include "ppapi/c/pp_var.h" +#include "ppapi/cpp/extensions/from_var_converter.h" +#include "ppapi/cpp/logging.h" +#include "ppapi/cpp/pass_ref.h" +#include "ppapi/cpp/var.h" + +namespace pp { +namespace ext { +namespace internal { + +// Base class for all those types within the pp::ext namespace that are used +// with CompletionCallbackWithOutput. This class doesn't do anything itself, +// but it affects the behavior of CallbackOutputTraits for all its subclasses. +// +// TODO(yzshen): Within pp::ext, basic types such as std::string or double may +// be used with CompletionCallbackWithOutput as well. This approach doesn't +// work for them. One way is to refactor CallbackOutputTraits to consider not +// only the output C++ object type, but also the output parameter type that the +// C interface uses. And then we can remove this class. +class OutputObjectBase { +}; + +template <class T> +class VarOutputAdapterWithStorage { + public: + VarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) { + } + + ~VarOutputAdapterWithStorage() { + PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED); + } + + PP_Var& pp_var() { return pp_var_; } + + T& output() { + converter_.Set(PASS_REF, pp_var_); + pp_var_ = PP_MakeUndefined(); + return converter_.value(); + } + + private: + PP_Var pp_var_; + FromVarConverter<T> converter_; + + // Disallow copying and assignment. + VarOutputAdapterWithStorage(const VarOutputAdapterWithStorage<T>&); + VarOutputAdapterWithStorage<T>& operator=( + const VarOutputAdapterWithStorage<T>&); +}; + +template <class T> +struct ExtensionsCallbackOutputTraits { + typedef PP_Var* APIArgType; + typedef VarOutputAdapterWithStorage<T> StorageType; + + static inline APIArgType StorageToAPIArg(StorageType& t) { + return &t.pp_var(); + } + + // This must be called exactly once to consume the one PP_Var reference + // assigned to us by the browser. + static inline T& StorageToPluginArg(StorageType& t) { + return t.output(); + } +}; + +// This class provides storage for a PP_Var and a vector of objects which are +// of type T. The PP_Var is used as an output parameter to recevie an array var +// from the browser. Each element in the array var is converted to a T object, +// using FromVarConverter, and stores in the vector. +template <class T> +class ArrayVarOutputAdapterWithStorage { + public: + ArrayVarOutputAdapterWithStorage() : pp_var_(PP_MakeUndefined()) { + } + + ~ArrayVarOutputAdapterWithStorage() { + PP_DCHECK(pp_var_.type == PP_VARTYPE_UNDEFINED); + } + + PP_Var& pp_var() { return pp_var_; } + + std::vector<T>& output() { + PP_DCHECK(output_storage_.empty()); + + // TODO(yzshen): Add support for ArrayVar and read the contents from + // |pp_var_| and put into |output_storage_|. + Var auto_release(PASS_REF, pp_var_); + pp_var_ = PP_MakeUndefined(); + + return output_storage_; + } + + private: + PP_Var pp_var_; + std::vector<T> output_storage_; + + // Disallow copying and assignment. + ArrayVarOutputAdapterWithStorage(const ArrayVarOutputAdapterWithStorage<T>&); + ArrayVarOutputAdapterWithStorage<T>& operator=( + const ArrayVarOutputAdapterWithStorage<T>&); +}; + +template <class T> +struct ExtensionsVectorCallbackOutputTraits { + typedef PP_Var* APIArgType; + typedef ArrayVarOutputAdapterWithStorage<T> StorageType; + + static inline APIArgType StorageToAPIArg(StorageType& t) { + return &t.pp_var(); + } + + // This must be called exactly once to consume the one PP_Var reference + // assigned to us by the browser. + static inline std::vector<T>& StorageToPluginArg(StorageType& t) { + return t.output(); + } +}; + +} // namespace internal +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_OUTPUT_TRAITS_H_ diff --git a/ppapi/cpp/extensions/from_var_converter.h b/ppapi/cpp/extensions/from_var_converter.h new file mode 100644 index 0000000..7fe0ac5 --- /dev/null +++ b/ppapi/cpp/extensions/from_var_converter.h @@ -0,0 +1,100 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_FROM_VAR_CONVERTOR_H_ +#define PPAPI_CPP_EXTENSIONS_FROM_VAR_CONVERTOR_H_ + +#include <string> + +#include "ppapi/c/pp_var.h" +#include "ppapi/cpp/logging.h" +#include "ppapi/cpp/pass_ref.h" +#include "ppapi/cpp/var.h" + +namespace pp { +namespace ext { +namespace internal { + +template <class T> +class FromVarConverterBase { + public: + T& value() { return value_; } + + protected: + FromVarConverterBase() : value_() { + } + + explicit FromVarConverterBase(const T& value) : value_(value) { + } + + ~FromVarConverterBase() { + } + + T value_; +}; + +template <class T> +class FromVarConverter : public FromVarConverterBase<T> { + public: + FromVarConverter() { + } + + FromVarConverter(const PP_Var& var) { + Set(PASS_REF, Var(var).Detach()); + } + + ~FromVarConverter() { + } + + void Set(PassRef pass_ref, const PP_Var& var) { + Var auto_release(pass_ref, var); + + bool succeeded = FromVarConverterBase<T>::value_.Populate(var); + // Suppress unused variable warnings. + static_cast<void>(succeeded); + PP_DCHECK(succeeded); + } +}; + +template <> +class FromVarConverter<std::string> : public FromVarConverterBase<std::string> { + public: + FromVarConverter() { + } + + FromVarConverter(const PP_Var& var) { + Set(PASS_REF, Var(var).Detach()); + } + + ~FromVarConverter() { + } + + void Set(PassRef pass_ref, const PP_Var& var) { + FromVarConverterBase<std::string>::value_ = Var(pass_ref, var).AsString(); + } +}; + +template <> +class FromVarConverter<double> : public FromVarConverterBase<double> { + public: + FromVarConverter() { + } + + FromVarConverter(const PP_Var& var) { + Set(PASS_REF, Var(var).Detach()); + } + + ~FromVarConverter() { + } + + void Set(PassRef pass_ref, const PP_Var& var) { + FromVarConverterBase<double>::value_ = Var(pass_ref, var).AsDouble(); + } +}; + +} // namespace internal +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_FROM_VAR_CONVERTOR_H_ diff --git a/ppapi/cpp/extensions/optional.h b/ppapi/cpp/extensions/optional.h new file mode 100644 index 0000000..cd6f40b --- /dev/null +++ b/ppapi/cpp/extensions/optional.h @@ -0,0 +1,91 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_OPTIONAL_H_ +#define PPAPI_CPP_EXTENSIONS_OPTIONAL_H_ + +namespace pp { +namespace ext { + +template <class T> +class Optional { + public: + Optional() : value_(NULL) { + } + // Takes ownership of |value|. + explicit Optional(T* value) : value_(value) { + } + Optional(const T& value) : value_(new T(value)) { + } + Optional(const Optional<T>& other) + : value_(other.value_ ? new T(*other.value_) : NULL) { + } + + ~Optional() { + Reset(); + } + + Optional<T>& operator=(const T& other) { + if (value_ == &other) + return *this; + + Reset(); + value_ = new T(other); + + return *this; + } + + Optional<T>& operator=(const Optional<T>& other) { + if (value_ == other.value_) + return *this; + + Reset(); + if (other.value_) + value_ = new T(*other.value_); + + return *this; + } + + bool IsSet() const { + return !!value_; + } + + T* Get() const { + return value_; + } + + // Should only be used when IsSet() is true. + T& operator*() const { + return *value_; + } + + // Should only be used when IsSet() is true. + T* operator->() const { + PP_DCHECK(value_); + return value_; + } + + // Takes ownership of |value|. + void Set(T* value) { + if (value == value_) + return; + + Reset(); + *value_ = value; + } + + void Reset() { + T* value = value_; + value_ = NULL; + delete value; + } + + private: + T* value_; +}; + +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_OPTIONAL_H_ diff --git a/ppapi/cpp/extensions/to_var_converter.h b/ppapi/cpp/extensions/to_var_converter.h new file mode 100644 index 0000000..e221ab9 --- /dev/null +++ b/ppapi/cpp/extensions/to_var_converter.h @@ -0,0 +1,89 @@ +// Copyright (c) 2013 The Chromium 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 PPAPI_CPP_EXTENSIONS_TO_VAR_CONVERTOR_H_ +#define PPAPI_CPP_EXTENSIONS_TO_VAR_CONVERTOR_H_ + +#include <string> + +#include "ppapi/c/pp_var.h" +#include "ppapi/cpp/extensions/optional.h" +#include "ppapi/cpp/var.h" + +namespace pp { +namespace ext { +namespace internal { + +class ToVarConverterBase { + public: + PP_Var pp_var() const { + return var_.pp_var(); + } + + protected: + ToVarConverterBase() { + } + + explicit ToVarConverterBase(const PP_Var& var) : var_(var) { + } + + explicit ToVarConverterBase(const Var& var): var_(var) { + } + + ~ToVarConverterBase() { + } + + Var var_; +}; + +template <class T> +class ToVarConverter : public ToVarConverterBase { + public: + explicit ToVarConverter(const T& object) + : ToVarConverterBase(object.CreateVar()) { + } + + ~ToVarConverter() { + } +}; + +template <class T> +class ToVarConverter<Optional<T> > : public ToVarConverterBase { + public: + explicit ToVarConverter(const Optional<T>& object) + : ToVarConverterBase( + object.IsSet() ? ToVarConverter<T>(*object).pp_var() : + PP_MakeUndefined()) { + } + + ~ToVarConverter() { + } +}; + +template <> +class ToVarConverter<std::string> : public ToVarConverterBase { + public: + explicit ToVarConverter(const std::string& object) + : ToVarConverterBase(Var(object)) { + } + + ~ToVarConverter() { + } +}; + +template <> +class ToVarConverter<double> : public ToVarConverterBase { + public: + explicit ToVarConverter(double object) : ToVarConverterBase(Var(object)) { + } + + ~ToVarConverter() { + } +}; + +} // namespace internal +} // namespace ext +} // namespace pp + +#endif // PPAPI_CPP_EXTENSIONS_TO_VAR_CONVERTOR_H_ diff --git a/ppapi/cpp/output_traits.h b/ppapi/cpp/output_traits.h index cc04330..889c612 100644 --- a/ppapi/cpp/output_traits.h +++ b/ppapi/cpp/output_traits.h @@ -10,6 +10,8 @@ #include "ppapi/c/pp_resource.h" #include "ppapi/cpp/array_output.h" #include "ppapi/cpp/dev/directory_entry_dev.h" +#include "ppapi/cpp/extensions/ext_output_traits.h" +#include "ppapi/cpp/resource.h" /// @file /// This file defines internal templates for defining how data is passed to the @@ -23,7 +25,6 @@ struct PP_Var; namespace pp { -class Resource; class Var; namespace internal { @@ -117,16 +118,20 @@ struct ResourceCallbackOutputTraits { }; // The general templatized base class for all CallbackOutputTraits. This class -// covers both resources and POD (ints, structs, etc.) by inheriting from the -// appropriate base class depending on whether the given type derives from -// pp::Resource. This trick allows us to do this once rather than writing -// specializations for every resource object type. +// covers resources, extensions API output objects and POD (ints, structs, etc.) +// by inheriting from the appropriate base class depending on whether the given +// type derives from pp::Resource or ext::internal::OutputObjectBase. This trick +// allows us to do this once rather than writing specializations for every +// object type. template<typename T> struct CallbackOutputTraits - : public InheritIf<GenericCallbackOutputTraits<T>, - !IsBaseOf<Resource, T>::value>, - public InheritIf<ResourceCallbackOutputTraits<T>, - IsBaseOf<Resource, T>::value> { + : public InheritIf<ResourceCallbackOutputTraits<T>, + IsBaseOf<Resource, T>::value>, + public InheritIf<ext::internal::ExtensionsCallbackOutputTraits<T>, + IsBaseOf<ext::internal::OutputObjectBase, T>::value>, + public InheritIf<GenericCallbackOutputTraits<T>, + !IsBaseOf<Resource, T>::value && + !IsBaseOf<ext::internal::OutputObjectBase, T>::value> { }; // A specialization of CallbackOutputTraits for pp::Var output parameters. @@ -199,17 +204,21 @@ struct ResourceVectorCallbackOutputTraits { } }; -// Specialization of CallbackOutputTraits for vectors. This struct covers both -// arrays of resources and arrays of POD (ints, structs, etc.) by inheriting -// from the appropriate base class depending on whether the given type derives -// from pp::Resource. This trick allows us to do this once rather than writing -// specializations for every resource object type. +// Specialization of CallbackOutputTraits for vectors. This struct covers arrays +// of resources, extensions API output objects and POD (ints, structs, etc.) by +// inheriting from the appropriate base class depending on whether the given +// type derives from pp::Resource or ext::internal::OutputObjectBase. This trick +// allows us to do this once rather than writing specializations for every +// object type. template<typename T> struct CallbackOutputTraits< std::vector<T> > - : public InheritIf<GenericVectorCallbackOutputTraits<T>, - !IsBaseOf<Resource, T>::value>, - public InheritIf<ResourceVectorCallbackOutputTraits<T>, - IsBaseOf<Resource, T>::value> { + : public InheritIf<ResourceVectorCallbackOutputTraits<T>, + IsBaseOf<Resource, T>::value>, + public InheritIf<ext::internal::ExtensionsVectorCallbackOutputTraits<T>, + IsBaseOf<ext::internal::OutputObjectBase, T>::value>, + public InheritIf<GenericVectorCallbackOutputTraits<T>, + !IsBaseOf<Resource, T>::value && + !IsBaseOf<ext::internal::OutputObjectBase, T>::value> { }; // A specialization of CallbackOutputTraits to provide the callback system diff --git a/ppapi/cpp/var.cc b/ppapi/cpp/var.cc index 7fc67f5..09a8fe3 100644 --- a/ppapi/cpp/var.cc +++ b/ppapi/cpp/var.cc @@ -101,6 +101,18 @@ Var::Var(const std::string& utf8_str) { is_managed_ = true; } + +Var::Var(const PP_Var& var) { + var_ = var; + is_managed_ = true; + if (NeedsRefcounting(var_)) { + if (has_interface<PPB_Var_1_0>()) + get_interface<PPB_Var_1_0>()->AddRef(var_); + else + var_.type = PP_VARTYPE_NULL; + } +} + Var::Var(const Var& other) { var_ = other.var_; is_managed_ = true; diff --git a/ppapi/cpp/var.h b/ppapi/cpp/var.h index 437eed9..d114054 100644 --- a/ppapi/cpp/var.h +++ b/ppapi/cpp/var.h @@ -55,11 +55,14 @@ class Var { /// /// You will not normally need to use this constructor because /// the reference count will not normally be incremented for you. - Var(PassRef, PP_Var var) { + Var(PassRef, const PP_Var& var) { var_ = var; is_managed_ = true; } + /// A constructor that increments the reference count. + explicit Var(const PP_Var& var); + struct DontManage {}; // TODO(brettw): remove DontManage when this bug is fixed @@ -70,7 +73,7 @@ class Var { /// increased or decreased by this class instance. /// /// @param[in] var A <code>Var</code>. - Var(DontManage, PP_Var var) { + Var(DontManage, const PP_Var& var) { var_ = var; is_managed_ = false; } |