1 // Copyright (c) 2012 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 GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_ 6 #define GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_ 7 8 #include "base/bind.h" 9 #include "base/bind_helpers.h" 10 #include "base/callback.h" 11 12 #define INVALIDATION_CALLBACK1_TYPE(Arg1) ::base::Callback<void(Arg1)> 13 14 // Below are a collection of types and functions that adapt base::Callback's 15 // pass-by-value semantics to the pointer-based callback system that 16 // cacheinvalidation needs. 17 18 namespace invalidation { 19 20 typedef ::base::Closure Closure; 21 22 template <class T> 23 bool IsCallbackRepeatable(const T* callback) { 24 // The default cacheinvalidation Callbacks may be self-deleting. We don't 25 // support this behave, so we already return true to indicate that the 26 // cacheinvalidation implementation should delete our Callbacks. 27 return true; 28 } 29 30 namespace internal { 31 32 // Identity<T>::type is a typedef of T. Useful for preventing the 33 // compiler from inferring the type of an argument in templates. 34 template <typename T> 35 struct Identity { 36 typedef T type; 37 }; 38 39 } // namespace internal 40 41 // The cacheinvalidation callback system expects to take the callback by 42 // pointer and handle the ownership semantics itself. Adapting the 43 // Chromium Callback system requires returning a dynamically allocated 44 // copy of the result of Bind(). 45 46 inline Closure* NewPermanentCallback(void (*fn)()) { 47 return new ::base::Closure(::base::Bind(fn)); 48 } 49 50 template <class T1, class T2> 51 Closure* NewPermanentCallback( 52 T1* object, void (T2::*method)()) { 53 return new ::base::Closure(::base::Bind(method, base::Unretained(object))); 54 } 55 56 template <class T1, class T2, typename Arg1> 57 ::base::Callback<void(Arg1)>* NewPermanentCallback( 58 T1* object, void (T2::*method)(Arg1)) { 59 return new ::base::Callback<void(Arg1)>( 60 ::base::Bind(method, base::Unretained(object))); 61 } 62 63 template <class T1, class T2, typename Arg1> 64 Closure* NewPermanentCallback( 65 T1* object, 66 void (T2::*method)(Arg1), 67 typename internal::Identity<Arg1>::type arg1) { 68 return new ::base::Closure(::base::Bind(method, base::Unretained(object), 69 arg1)); 70 } 71 72 template <typename Arg1, typename Arg2> 73 Closure* NewPermanentCallback( 74 void (*fn)(Arg1, Arg2), 75 typename internal::Identity<Arg1>::type arg1, 76 typename internal::Identity<Arg2>::type arg2) { 77 return new ::base::Closure(::base::Bind(fn, arg1, arg2)); 78 } 79 80 template <class T1, class T2, typename Arg1, typename Arg2> 81 Closure* NewPermanentCallback( 82 T1* object, 83 void (T2::*method)(Arg1, Arg2), 84 typename internal::Identity<Arg1>::type arg1, 85 typename internal::Identity<Arg2>::type arg2) { 86 return new ::base::Closure(::base::Bind(method, base::Unretained(object), 87 arg1, arg2)); 88 } 89 90 template <class T1, class T2, typename Arg1, typename Arg2> 91 ::base::Callback<void(Arg2)>* NewPermanentCallback( 92 T1* object, 93 void (T2::*method)(Arg1, Arg2), 94 typename internal::Identity<Arg1>::type arg1) { 95 return new ::base::Callback<void(Arg2)>( 96 ::base::Bind(method, base::Unretained(object), arg1)); 97 } 98 99 template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3> 100 Closure* NewPermanentCallback( 101 T1* object, 102 void (T2::*method)(Arg1, Arg2, Arg3), 103 typename internal::Identity<Arg1>::type arg1, 104 typename internal::Identity<Arg2>::type arg2, 105 typename internal::Identity<Arg3>::type arg3) { 106 return new ::base::Closure(::base::Bind(method, base::Unretained(object), 107 arg1, arg2, arg3)); 108 } 109 110 template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3, 111 typename Arg4> 112 Closure* NewPermanentCallback( 113 T1* object, 114 void (T2::*method)(Arg1, Arg2, Arg3, Arg4), 115 typename internal::Identity<Arg1>::type arg1, 116 typename internal::Identity<Arg2>::type arg2, 117 typename internal::Identity<Arg3>::type arg3, 118 typename internal::Identity<Arg4>::type arg4) { 119 return new ::base::Closure(::base::Bind(method, base::Unretained(object), 120 arg1, arg2, arg3, arg4)); 121 } 122 123 // Creates a Closure that runs |callback| on |arg|. The returned Closure owns 124 // |callback|. 125 template <typename ArgType> 126 Closure* NewPermanentCallback( 127 INVALIDATION_CALLBACK1_TYPE(ArgType)* callback, 128 typename internal::Identity<ArgType>::type arg) { 129 return new ::base::Closure(::base::Bind( 130 &::base::Callback<void(ArgType)>::Run, base::Owned(callback), arg)); 131 } 132 133 } // namespace invalidation 134 135 #endif // GOOGLE_CACHEINVALIDATION_DEPS_CALLBACK_H_ 136