Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(266)

Unified Diff: components/arc/arc_service_manager.h

Issue 2622843002: arc: Provide a per-service getter for ArcServiceManager (Closed)
Patch Set: I forgot how to ::type Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | components/arc/arc_service_manager.cc » ('j') | components/arc/arc_service_manager.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/arc/arc_service_manager.h
diff --git a/components/arc/arc_service_manager.h b/components/arc/arc_service_manager.h
index 81a4ea9e98b2e715e289b112d3cae2660d72cbd6..129e17b857f393c8275862c95b46bebebf2cd4e0 100644
--- a/components/arc/arc_service_manager.h
+++ b/components/arc/arc_service_manager.h
@@ -6,6 +6,10 @@
#define COMPONENTS_ARC_ARC_SERVICE_MANAGER_H_
#include <memory>
+#include <string>
+#include <type_traits>
+#include <unordered_map>
+#include <utility>
#include <vector>
#include "base/macros.h"
@@ -22,6 +26,38 @@ class ArcBridgeService;
class ArcIntentHelperObserver;
class ArcService;
+namespace internal {
+
+// If an ArcService is declared with a Name, e.g.:
+//
+// class MyArcService : public ArcService {
+// public:
+// static const char Name[];
Yusuke Sato 2017/01/10 07:11:11 The variable name 'Name' doesn't seem to follow th
Luis Héctor Chávez 2017/01/10 18:41:55 Done.
+// ...
+// };
+//
+// it can then be retrieved from ArcServiceManager in a type-safe way using
+// Get<T>(). This struct allows the use of std::enable_if<...> to choose the
+// correct implementation of the AddService() functions to enable this
+// functionality.
+template <typename T>
hidehiko 2017/01/10 08:03:12 Optional: How about minimizing template magic? E.g
Luis Héctor Chávez 2017/01/10 18:41:56 Simplified the first function a bit, but done.
+struct NamedServiceTraits {
+ private:
+ typedef char No[1];
Yusuke Sato 2017/01/10 07:11:11 nit: do we have a reason to skip 0? No can be [0]
hidehiko 2017/01/10 08:03:12 FYI: 0 length is illegal, IIUC. http://stackoverfl
Luis Héctor Chávez 2017/01/10 18:41:56 This is a commonly-used Method Detector idiom: htt
hidehiko 2017/01/11 05:17:45 Yes, I know, but it was developed in C++03 era, an
+ typedef char Yes[2];
+
+ template <typename U>
+ static Yes& test(decltype(U::Name) *);
Yusuke Sato 2017/01/10 07:11:11 nit: no space before *, maybe?
hidehiko 2017/01/10 08:03:12 Optional: Even in this way, trailing return type c
Luis Héctor Chávez 2017/01/10 18:41:56 Acknowledged.
+
+ template <typename U>
+ static No& test(...);
+
+ public:
+ enum : bool { HasName = sizeof(test<T>(nullptr)) == sizeof(Yes) };
hidehiko 2017/01/10 08:03:12 With std::{true,false}_type, constexpr bool kValu
Luis Héctor Chávez 2017/01/10 18:41:56 Acknowledged.
+};
+
+} // namespace internal
+
// Manages creation and destruction of services that communicate with the ARC
// instance via the ArcBridgeService.
class ArcServiceManager {
@@ -49,7 +85,26 @@ class ArcServiceManager {
ArcBridgeService* arc_bridge_service();
// Adds a service to the managed services list.
- void AddService(std::unique_ptr<ArcService> service);
+ template <typename T,
+ typename std::enable_if<!internal::NamedServiceTraits<T>::HasName,
+ int>::type = 0>
+ void AddService(std::unique_ptr<T> service) {
+ AddServiceInternal(std::move(service));
+ }
+
+ // Adds a named service to the managed services list.
+ template <typename T,
+ typename std::enable_if<internal::NamedServiceTraits<T>::HasName,
+ int>::type = 0>
+ void AddService(std::unique_ptr<T> service) {
+ AddNamedServiceInternal(std::string(T::Name), std::move(service));
Yusuke Sato 2017/01/10 07:11:11 nit: the cast (to string) seems unnecessary
Luis Héctor Chávez 2017/01/10 18:41:56 Done.
+ }
+
+ // Gets the named service from the managed services list.
Yusuke Sato 2017/01/10 07:11:11 For developers who don't want to read the template
hidehiko 2017/01/10 08:03:12 Also, could you explicitly comment that, this will
Luis Héctor Chávez 2017/01/10 18:41:56 Done.
+ template <typename T>
+ T* GetService() {
Yusuke Sato 2017/01/10 07:11:11 I think GetService<T>() is easy to test. How about
Luis Héctor Chávez 2017/01/10 18:41:56 Done.
+ return static_cast<T*>(GetNamedServiceInternal(T::Name));
+ }
// Gets the global instance of the ARC Service Manager. This can only be
// called on the thread that this class was created on.
@@ -81,6 +136,12 @@ class ArcServiceManager {
private:
class IntentHelperObserverImpl; // implemented in arc_service_manager.cc.
+ // Helper methods for AddService and GetService.
+ void AddServiceInternal(std::unique_ptr<ArcService> service);
+ void AddNamedServiceInternal(const std::string& name,
+ std::unique_ptr<ArcService> service);
+ ArcService* GetNamedServiceInternal(const std::string& name);
+
base::ThreadChecker thread_checker_;
scoped_refptr<base::TaskRunner> blocking_task_runner_;
@@ -89,6 +150,7 @@ class ArcServiceManager {
std::unique_ptr<ArcBridgeService> arc_bridge_service_;
std::vector<std::unique_ptr<ArcService>> services_;
+ std::unordered_map<std::string, std::unique_ptr<ArcService>> named_services_;
hidehiko 2017/01/10 08:03:12 Optional: how about mergine services_ and named_se
Luis Héctor Chávez 2017/01/10 18:41:56 Done.
scoped_refptr<ActivityIconLoader> icon_loader_;
scoped_refptr<LocalActivityResolver> activity_resolver_;
« no previous file with comments | « no previous file | components/arc/arc_service_manager.cc » ('j') | components/arc/arc_service_manager.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698