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 18namespace invalidation { 19 20typedef ::base::Closure Closure; 21 22template <class T> 23bool 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 30namespace 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. 34template <typename T> 35struct 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 46inline Closure* NewPermanentCallback(void (*fn)()) { 47 return new ::base::Closure(::base::Bind(fn)); 48} 49 50template <class T1, class T2> 51Closure* NewPermanentCallback( 52 T1* object, void (T2::*method)()) { 53 return new ::base::Closure(::base::Bind(method, base::Unretained(object))); 54} 55 56template <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 63template <class T1, class T2, typename Arg1> 64Closure* 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 72template <typename Arg1, typename Arg2> 73Closure* 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 80template <class T1, class T2, typename Arg1, typename Arg2> 81Closure* 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 90template <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 99template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3> 100Closure* 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 110template <class T1, class T2, typename Arg1, typename Arg2, typename Arg3, 111 typename Arg4> 112Closure* 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|. 125template <typename ArgType> 126Closure* 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