1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/base/task.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,670 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef BASE_TASK_H_ 1.9 +#define BASE_TASK_H_ 1.10 + 1.11 +#include "base/non_thread_safe.h" 1.12 +#include "base/revocable_store.h" 1.13 +#include "base/tracked.h" 1.14 +#include "base/tuple.h" 1.15 + 1.16 +// Task ------------------------------------------------------------------------ 1.17 +// 1.18 +// A task is a generic runnable thingy, usually used for running code on a 1.19 +// different thread or for scheduling future tasks off of the message loop. 1.20 + 1.21 +class Task : public tracked_objects::Tracked { 1.22 + public: 1.23 + Task() {} 1.24 + virtual ~Task() {} 1.25 + 1.26 + // Tasks are automatically deleted after Run is called. 1.27 + virtual void Run() = 0; 1.28 +}; 1.29 + 1.30 +class CancelableTask : public Task { 1.31 + public: 1.32 + // Not all tasks support cancellation. 1.33 + virtual void Cancel() = 0; 1.34 +}; 1.35 + 1.36 +// Scoped Factories ------------------------------------------------------------ 1.37 +// 1.38 +// These scoped factory objects can be used by non-refcounted objects to safely 1.39 +// place tasks in a message loop. Each factory guarantees that the tasks it 1.40 +// produces will not run after the factory is destroyed. Commonly, factories 1.41 +// are declared as class members, so the class' tasks will automatically cancel 1.42 +// when the class instance is destroyed. 1.43 +// 1.44 +// Exampe Usage: 1.45 +// 1.46 +// class MyClass { 1.47 +// private: 1.48 +// // This factory will be used to schedule invocations of SomeMethod. 1.49 +// ScopedRunnableMethodFactory<MyClass> some_method_factory_; 1.50 +// 1.51 +// public: 1.52 +// // It is safe to suppress warning 4355 here. 1.53 +// MyClass() : some_method_factory_(this) { } 1.54 +// 1.55 +// void SomeMethod() { 1.56 +// // If this function might be called directly, you might want to revoke 1.57 +// // any outstanding runnable methods scheduled to call it. If it's not 1.58 +// // referenced other than by the factory, this is unnecessary. 1.59 +// some_method_factory_.RevokeAll(); 1.60 +// ... 1.61 +// } 1.62 +// 1.63 +// void ScheduleSomeMethod() { 1.64 +// // If you'd like to only only have one pending task at a time, test for 1.65 +// // |empty| before manufacturing another task. 1.66 +// if (!some_method_factory_.empty()) 1.67 +// return; 1.68 +// 1.69 +// // The factories are not thread safe, so always invoke on 1.70 +// // |MessageLoop::current()|. 1.71 +// MessageLoop::current()->PostDelayedTask(FROM_HERE, 1.72 +// some_method_factory_.NewRunnableMethod(&MyClass::SomeMethod), 1.73 +// kSomeMethodDelayMS); 1.74 +// } 1.75 +// }; 1.76 + 1.77 +// A ScopedTaskFactory produces tasks of type |TaskType| and prevents them from 1.78 +// running after it is destroyed. 1.79 +template<class TaskType> 1.80 +class ScopedTaskFactory : public RevocableStore { 1.81 + public: 1.82 + ScopedTaskFactory() { } 1.83 + 1.84 + // Create a new task. 1.85 + inline TaskType* NewTask() { 1.86 + return new TaskWrapper(this); 1.87 + } 1.88 + 1.89 + class TaskWrapper : public TaskType, public NonThreadSafe { 1.90 + public: 1.91 + explicit TaskWrapper(RevocableStore* store) : revocable_(store) { } 1.92 + 1.93 + virtual void Run() { 1.94 + if (!revocable_.revoked()) 1.95 + TaskType::Run(); 1.96 + } 1.97 + 1.98 + private: 1.99 + Revocable revocable_; 1.100 + 1.101 + DISALLOW_EVIL_CONSTRUCTORS(TaskWrapper); 1.102 + }; 1.103 + 1.104 + private: 1.105 + DISALLOW_EVIL_CONSTRUCTORS(ScopedTaskFactory); 1.106 +}; 1.107 + 1.108 +// A ScopedRunnableMethodFactory creates runnable methods for a specified 1.109 +// object. This is particularly useful for generating callbacks for 1.110 +// non-reference counted objects when the factory is a member of the object. 1.111 +template<class T> 1.112 +class ScopedRunnableMethodFactory : public RevocableStore { 1.113 + public: 1.114 + explicit ScopedRunnableMethodFactory(T* object) : object_(object) { } 1.115 + 1.116 + template <class Method> 1.117 + inline Task* NewRunnableMethod(Method method) { 1.118 + typedef typename ScopedTaskFactory<RunnableMethod< 1.119 + Method, Tuple0> >::TaskWrapper TaskWrapper; 1.120 + 1.121 + TaskWrapper* task = new TaskWrapper(this); 1.122 + task->Init(object_, method, MakeTuple()); 1.123 + return task; 1.124 + } 1.125 + 1.126 + template <class Method, class A> 1.127 + inline Task* NewRunnableMethod(Method method, const A& a) { 1.128 + typedef typename ScopedTaskFactory<RunnableMethod< 1.129 + Method, Tuple1<A> > >::TaskWrapper TaskWrapper; 1.130 + 1.131 + TaskWrapper* task = new TaskWrapper(this); 1.132 + task->Init(object_, method, MakeTuple(a)); 1.133 + return task; 1.134 + } 1.135 + 1.136 + template <class Method, class A, class B> 1.137 + inline Task* NewRunnableMethod(Method method, const A& a, const B& b) { 1.138 + typedef typename ScopedTaskFactory<RunnableMethod< 1.139 + Method, Tuple2<A, B> > >::TaskWrapper TaskWrapper; 1.140 + 1.141 + TaskWrapper* task = new TaskWrapper(this); 1.142 + task->Init(object_, method, MakeTuple(a, b)); 1.143 + return task; 1.144 + } 1.145 + 1.146 + template <class Method, class A, class B, class C> 1.147 + inline Task* NewRunnableMethod(Method method, 1.148 + const A& a, 1.149 + const B& b, 1.150 + const C& c) { 1.151 + typedef typename ScopedTaskFactory<RunnableMethod< 1.152 + Method, Tuple3<A, B, C> > >::TaskWrapper TaskWrapper; 1.153 + 1.154 + TaskWrapper* task = new TaskWrapper(this); 1.155 + task->Init(object_, method, MakeTuple(a, b, c)); 1.156 + return task; 1.157 + } 1.158 + 1.159 + template <class Method, class A, class B, class C, class D> 1.160 + inline Task* NewRunnableMethod(Method method, 1.161 + const A& a, 1.162 + const B& b, 1.163 + const C& c, 1.164 + const D& d) { 1.165 + typedef typename ScopedTaskFactory<RunnableMethod< 1.166 + Method, Tuple4<A, B, C, D> > >::TaskWrapper TaskWrapper; 1.167 + 1.168 + TaskWrapper* task = new TaskWrapper(this); 1.169 + task->Init(object_, method, MakeTuple(a, b, c, d)); 1.170 + return task; 1.171 + } 1.172 + 1.173 + template <class Method, class A, class B, class C, class D, class E> 1.174 + inline Task* NewRunnableMethod(Method method, 1.175 + const A& a, 1.176 + const B& b, 1.177 + const C& c, 1.178 + const D& d, 1.179 + const E& e) { 1.180 + typedef typename ScopedTaskFactory<RunnableMethod< 1.181 + Method, Tuple5<A, B, C, D, E> > >::TaskWrapper TaskWrapper; 1.182 + 1.183 + TaskWrapper* task = new TaskWrapper(this); 1.184 + task->Init(object_, method, MakeTuple(a, b, c, d, e)); 1.185 + return task; 1.186 + } 1.187 + 1.188 + protected: 1.189 + template <class Method, class Params> 1.190 + class RunnableMethod : public Task { 1.191 + public: 1.192 + RunnableMethod() { } 1.193 + 1.194 + void Init(T* obj, Method meth, const Params& params) { 1.195 + obj_ = obj; 1.196 + meth_ = meth; 1.197 + params_ = params; 1.198 + } 1.199 + 1.200 + virtual void Run() { DispatchToMethod(obj_, meth_, params_); } 1.201 + 1.202 + private: 1.203 + T* obj_; 1.204 + Method meth_; 1.205 + Params params_; 1.206 + 1.207 + DISALLOW_EVIL_CONSTRUCTORS(RunnableMethod); 1.208 + }; 1.209 + 1.210 + private: 1.211 + T* object_; 1.212 + 1.213 + DISALLOW_EVIL_CONSTRUCTORS(ScopedRunnableMethodFactory); 1.214 +}; 1.215 + 1.216 +// General task implementations ------------------------------------------------ 1.217 + 1.218 +// Task to delete an object 1.219 +template<class T> 1.220 +class DeleteTask : public CancelableTask { 1.221 + public: 1.222 + explicit DeleteTask(T* obj) : obj_(obj) { 1.223 + } 1.224 + virtual void Run() { 1.225 + delete obj_; 1.226 + } 1.227 + virtual void Cancel() { 1.228 + obj_ = NULL; 1.229 + } 1.230 + private: 1.231 + T* obj_; 1.232 +}; 1.233 + 1.234 +// Task to Release() an object 1.235 +template<class T> 1.236 +class ReleaseTask : public CancelableTask { 1.237 + public: 1.238 + explicit ReleaseTask(T* obj) : obj_(obj) { 1.239 + } 1.240 + virtual void Run() { 1.241 + if (obj_) 1.242 + obj_->Release(); 1.243 + } 1.244 + virtual void Cancel() { 1.245 + obj_ = NULL; 1.246 + } 1.247 + private: 1.248 + T* obj_; 1.249 +}; 1.250 + 1.251 +// RunnableMethodTraits -------------------------------------------------------- 1.252 +// 1.253 +// This traits-class is used by RunnableMethod to manage the lifetime of the 1.254 +// callee object. By default, it is assumed that the callee supports AddRef 1.255 +// and Release methods. A particular class can specialize this template to 1.256 +// define other lifetime management. For example, if the callee is known to 1.257 +// live longer than the RunnableMethod object, then a RunnableMethodTraits 1.258 +// struct could be defined with empty RetainCallee and ReleaseCallee methods. 1.259 + 1.260 +template <class T> 1.261 +struct RunnableMethodTraits { 1.262 + static void RetainCallee(T* obj) { 1.263 + obj->AddRef(); 1.264 + } 1.265 + static void ReleaseCallee(T* obj) { 1.266 + obj->Release(); 1.267 + } 1.268 +}; 1.269 + 1.270 +// RunnableMethod and RunnableFunction ----------------------------------------- 1.271 +// 1.272 +// Runnable methods are a type of task that call a function on an object when 1.273 +// they are run. We implement both an object and a set of NewRunnableMethod and 1.274 +// NewRunnableFunction functions for convenience. These functions are 1.275 +// overloaded and will infer the template types, simplifying calling code. 1.276 +// 1.277 +// The template definitions all use the following names: 1.278 +// T - the class type of the object you're supplying 1.279 +// this is not needed for the Static version of the call 1.280 +// Method/Function - the signature of a pointer to the method or function you 1.281 +// want to call 1.282 +// Param - the parameter(s) to the method, possibly packed as a Tuple 1.283 +// A - the first parameter (if any) to the method 1.284 +// B - the second parameter (if any) to the mathod 1.285 +// 1.286 +// Put these all together and you get an object that can call a method whose 1.287 +// signature is: 1.288 +// R T::MyFunction([A[, B]]) 1.289 +// 1.290 +// Usage: 1.291 +// PostTask(FROM_HERE, NewRunnableMethod(object, &Object::method[, a[, b]]) 1.292 +// PostTask(FROM_HERE, NewRunnableFunction(&function[, a[, b]]) 1.293 + 1.294 +// RunnableMethod and NewRunnableMethod implementation ------------------------- 1.295 + 1.296 +template <class T, class Method, class Params> 1.297 +class RunnableMethod : public CancelableTask, 1.298 + public RunnableMethodTraits<T> { 1.299 + public: 1.300 + RunnableMethod(T* obj, Method meth, const Params& params) 1.301 + : obj_(obj), meth_(meth), params_(params) { 1.302 + this->RetainCallee(obj_); 1.303 + } 1.304 + ~RunnableMethod() { 1.305 + ReleaseCallee(); 1.306 + } 1.307 + 1.308 + virtual void Run() { 1.309 + if (obj_) 1.310 + DispatchToMethod(obj_, meth_, params_); 1.311 + } 1.312 + 1.313 + virtual void Cancel() { 1.314 + ReleaseCallee(); 1.315 + } 1.316 + 1.317 + private: 1.318 + void ReleaseCallee() { 1.319 + if (obj_) { 1.320 + RunnableMethodTraits<T>::ReleaseCallee(obj_); 1.321 + obj_ = NULL; 1.322 + } 1.323 + } 1.324 + 1.325 + T* obj_; 1.326 + Method meth_; 1.327 + Params params_; 1.328 +}; 1.329 + 1.330 +template <class T, class Method> 1.331 +inline CancelableTask* NewRunnableMethod(T* object, Method method) { 1.332 + return new RunnableMethod<T, Method, Tuple0>(object, method, MakeTuple()); 1.333 +} 1.334 + 1.335 +template <class T, class Method, class A> 1.336 +inline CancelableTask* NewRunnableMethod(T* object, Method method, const A& a) { 1.337 + return new RunnableMethod<T, Method, Tuple1<A> >(object, 1.338 + method, 1.339 + MakeTuple(a)); 1.340 +} 1.341 + 1.342 +template <class T, class Method, class A, class B> 1.343 +inline CancelableTask* NewRunnableMethod(T* object, Method method, 1.344 +const A& a, const B& b) { 1.345 + return new RunnableMethod<T, Method, Tuple2<A, B> >(object, method, 1.346 + MakeTuple(a, b)); 1.347 +} 1.348 + 1.349 +template <class T, class Method, class A, class B, class C> 1.350 +inline CancelableTask* NewRunnableMethod(T* object, Method method, 1.351 + const A& a, const B& b, const C& c) { 1.352 + return new RunnableMethod<T, Method, Tuple3<A, B, C> >(object, method, 1.353 + MakeTuple(a, b, c)); 1.354 +} 1.355 + 1.356 +template <class T, class Method, class A, class B, class C, class D> 1.357 +inline CancelableTask* NewRunnableMethod(T* object, Method method, 1.358 + const A& a, const B& b, 1.359 + const C& c, const D& d) { 1.360 + return new RunnableMethod<T, Method, Tuple4<A, B, C, D> >(object, method, 1.361 + MakeTuple(a, b, 1.362 + c, d)); 1.363 +} 1.364 + 1.365 +template <class T, class Method, class A, class B, class C, class D, class E> 1.366 +inline CancelableTask* NewRunnableMethod(T* object, Method method, 1.367 + const A& a, const B& b, 1.368 + const C& c, const D& d, const E& e) { 1.369 + return new RunnableMethod<T, 1.370 + Method, 1.371 + Tuple5<A, B, C, D, E> >(object, 1.372 + method, 1.373 + MakeTuple(a, b, c, d, e)); 1.374 +} 1.375 + 1.376 +template <class T, class Method, class A, class B, class C, class D, class E, 1.377 + class F> 1.378 +inline CancelableTask* NewRunnableMethod(T* object, Method method, 1.379 + const A& a, const B& b, 1.380 + const C& c, const D& d, const E& e, 1.381 + const F& f) { 1.382 + return new RunnableMethod<T, 1.383 + Method, 1.384 + Tuple6<A, B, C, D, E, F> >(object, 1.385 + method, 1.386 + MakeTuple(a, b, c, d, e, 1.387 + f)); 1.388 +} 1.389 + 1.390 +template <class T, class Method, class A, class B, class C, class D, class E, 1.391 + class F, class G> 1.392 +inline CancelableTask* NewRunnableMethod(T* object, Method method, 1.393 + const A& a, const B& b, 1.394 + const C& c, const D& d, const E& e, 1.395 + const F& f, const G& g) { 1.396 + return new RunnableMethod<T, 1.397 + Method, 1.398 + Tuple7<A, B, C, D, E, F, G> >(object, 1.399 + method, 1.400 + MakeTuple(a, b, c, d, 1.401 + e, f, g)); 1.402 +} 1.403 + 1.404 +// RunnableFunction and NewRunnableFunction implementation --------------------- 1.405 + 1.406 +template <class Function, class Params> 1.407 +class RunnableFunction : public CancelableTask { 1.408 + public: 1.409 + RunnableFunction(Function function, const Params& params) 1.410 + : function_(function), params_(params) { 1.411 + } 1.412 + 1.413 + ~RunnableFunction() { 1.414 + } 1.415 + 1.416 + virtual void Run() { 1.417 + if (function_) 1.418 + DispatchToFunction(function_, params_); 1.419 + } 1.420 + 1.421 + virtual void Cancel() { 1.422 + function_ = NULL; 1.423 + } 1.424 + 1.425 + private: 1.426 + Function function_; 1.427 + Params params_; 1.428 +}; 1.429 + 1.430 +template <class Function> 1.431 +inline CancelableTask* NewRunnableFunction(Function function) { 1.432 + return new RunnableFunction<Function, Tuple0>(function, MakeTuple()); 1.433 +} 1.434 + 1.435 +template <class Function, class A> 1.436 +inline CancelableTask* NewRunnableFunction(Function function, const A& a) { 1.437 + return new RunnableFunction<Function, Tuple1<A> >(function, MakeTuple(a)); 1.438 +} 1.439 + 1.440 +template <class Function, class A, class B> 1.441 +inline CancelableTask* NewRunnableFunction(Function function, 1.442 + const A& a, const B& b) { 1.443 + return new RunnableFunction<Function, Tuple2<A, B> >(function, 1.444 + MakeTuple(a, b)); 1.445 +} 1.446 + 1.447 +template <class Function, class A, class B, class C> 1.448 +inline CancelableTask* NewRunnableFunction(Function function, 1.449 + const A& a, const B& b, 1.450 + const C& c) { 1.451 + return new RunnableFunction<Function, Tuple3<A, B, C> >(function, 1.452 + MakeTuple(a, b, c)); 1.453 +} 1.454 + 1.455 +template <class Function, class A, class B, class C, class D> 1.456 +inline CancelableTask* NewRunnableFunction(Function function, 1.457 + const A& a, const B& b, 1.458 + const C& c, const D& d) { 1.459 + return new RunnableFunction<Function, Tuple4<A, B, C, D> >(function, 1.460 + MakeTuple(a, b, 1.461 + c, d)); 1.462 +} 1.463 + 1.464 +template <class Function, class A, class B, class C, class D, class E> 1.465 +inline CancelableTask* NewRunnableFunction(Function function, 1.466 + const A& a, const B& b, 1.467 + const C& c, const D& d, 1.468 + const E& e) { 1.469 + return new RunnableFunction<Function, Tuple5<A, B, C, D, E> >(function, 1.470 + MakeTuple(a, b, 1.471 + c, d, 1.472 + e)); 1.473 +} 1.474 + 1.475 +// Callback -------------------------------------------------------------------- 1.476 +// 1.477 +// A Callback is like a Task but with unbound parameters. It is basically an 1.478 +// object-oriented function pointer. 1.479 +// 1.480 +// Callbacks are designed to work with Tuples. A set of helper functions and 1.481 +// classes is provided to hide the Tuple details from the consumer. Client 1.482 +// code will generally work with the CallbackRunner base class, which merely 1.483 +// provides a Run method and is returned by the New* functions. This allows 1.484 +// users to not care which type of class implements the callback, only that it 1.485 +// has a certain number and type of arguments. 1.486 +// 1.487 +// The implementation of this is done by CallbackImpl, which inherits 1.488 +// CallbackStorage to store the data. This allows the storage of the data 1.489 +// (requiring the class type T) to be hidden from users, who will want to call 1.490 +// this regardless of the implementor's type T. 1.491 +// 1.492 +// Note that callbacks currently have no facility for cancelling or abandoning 1.493 +// them. We currently handle this at a higher level for cases where this is 1.494 +// necessary. The pointer in a callback must remain valid until the callback 1.495 +// is made. 1.496 +// 1.497 +// Like Task, the callback executor is responsible for deleting the callback 1.498 +// pointer once the callback has executed. 1.499 +// 1.500 +// Example client usage: 1.501 +// void Object::DoStuff(int, string); 1.502 +// Callback2<int, string>::Type* callback = 1.503 +// NewCallback(obj, &Object::DoStuff); 1.504 +// callback->Run(5, string("hello")); 1.505 +// delete callback; 1.506 +// or, equivalently, using tuples directly: 1.507 +// CallbackRunner<Tuple2<int, string> >* callback = 1.508 +// NewCallback(obj, &Object::DoStuff); 1.509 +// callback->RunWithParams(MakeTuple(5, string("hello"))); 1.510 + 1.511 +// Base for all Callbacks that handles storage of the pointers. 1.512 +template <class T, typename Method> 1.513 +class CallbackStorage { 1.514 + public: 1.515 + CallbackStorage(T* obj, Method meth) : obj_(obj), meth_(meth) { 1.516 + } 1.517 + 1.518 + protected: 1.519 + T* obj_; 1.520 + Method meth_; 1.521 +}; 1.522 + 1.523 +// Interface that is exposed to the consumer, that does the actual calling 1.524 +// of the method. 1.525 +template <typename Params> 1.526 +class CallbackRunner { 1.527 + public: 1.528 + typedef Params TupleType; 1.529 + 1.530 + virtual ~CallbackRunner() {} 1.531 + virtual void RunWithParams(const Params& params) = 0; 1.532 + 1.533 + // Convenience functions so callers don't have to deal with Tuples. 1.534 + inline void Run() { 1.535 + RunWithParams(Tuple0()); 1.536 + } 1.537 + 1.538 + template <typename Arg1> 1.539 + inline void Run(const Arg1& a) { 1.540 + RunWithParams(Params(a)); 1.541 + } 1.542 + 1.543 + template <typename Arg1, typename Arg2> 1.544 + inline void Run(const Arg1& a, const Arg2& b) { 1.545 + RunWithParams(Params(a, b)); 1.546 + } 1.547 + 1.548 + template <typename Arg1, typename Arg2, typename Arg3> 1.549 + inline void Run(const Arg1& a, const Arg2& b, const Arg3& c) { 1.550 + RunWithParams(Params(a, b, c)); 1.551 + } 1.552 + 1.553 + template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 1.554 + inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, const Arg4& d) { 1.555 + RunWithParams(Params(a, b, c, d)); 1.556 + } 1.557 + 1.558 + template <typename Arg1, typename Arg2, typename Arg3, 1.559 + typename Arg4, typename Arg5> 1.560 + inline void Run(const Arg1& a, const Arg2& b, const Arg3& c, 1.561 + const Arg4& d, const Arg5& e) { 1.562 + RunWithParams(Params(a, b, c, d, e)); 1.563 + } 1.564 +}; 1.565 + 1.566 +template <class T, typename Method, typename Params> 1.567 +class CallbackImpl : public CallbackStorage<T, Method>, 1.568 + public CallbackRunner<Params> { 1.569 + public: 1.570 + CallbackImpl(T* obj, Method meth) : CallbackStorage<T, Method>(obj, meth) { 1.571 + } 1.572 + virtual void RunWithParams(const Params& params) { 1.573 + // use "this->" to force C++ to look inside our templatized base class; see 1.574 + // Effective C++, 3rd Ed, item 43, p210 for details. 1.575 + DispatchToMethod(this->obj_, this->meth_, params); 1.576 + } 1.577 +}; 1.578 + 1.579 +// 0-arg implementation 1.580 +struct Callback0 { 1.581 + typedef CallbackRunner<Tuple0> Type; 1.582 +}; 1.583 + 1.584 +template <class T> 1.585 +typename Callback0::Type* NewCallback(T* object, void (T::*method)()) { 1.586 + return new CallbackImpl<T, void (T::*)(), Tuple0 >(object, method); 1.587 +} 1.588 + 1.589 +// 1-arg implementation 1.590 +template <typename Arg1> 1.591 +struct Callback1 { 1.592 + typedef CallbackRunner<Tuple1<Arg1> > Type; 1.593 +}; 1.594 + 1.595 +template <class T, typename Arg1> 1.596 +typename Callback1<Arg1>::Type* NewCallback(T* object, 1.597 + void (T::*method)(Arg1)) { 1.598 + return new CallbackImpl<T, void (T::*)(Arg1), Tuple1<Arg1> >(object, method); 1.599 +} 1.600 + 1.601 +// 2-arg implementation 1.602 +template <typename Arg1, typename Arg2> 1.603 +struct Callback2 { 1.604 + typedef CallbackRunner<Tuple2<Arg1, Arg2> > Type; 1.605 +}; 1.606 + 1.607 +template <class T, typename Arg1, typename Arg2> 1.608 +typename Callback2<Arg1, Arg2>::Type* NewCallback( 1.609 + T* object, 1.610 + void (T::*method)(Arg1, Arg2)) { 1.611 + return new CallbackImpl<T, void (T::*)(Arg1, Arg2), 1.612 + Tuple2<Arg1, Arg2> >(object, method); 1.613 +} 1.614 + 1.615 +// 3-arg implementation 1.616 +template <typename Arg1, typename Arg2, typename Arg3> 1.617 +struct Callback3 { 1.618 + typedef CallbackRunner<Tuple3<Arg1, Arg2, Arg3> > Type; 1.619 +}; 1.620 + 1.621 +template <class T, typename Arg1, typename Arg2, typename Arg3> 1.622 +typename Callback3<Arg1, Arg2, Arg3>::Type* NewCallback( 1.623 + T* object, 1.624 + void (T::*method)(Arg1, Arg2, Arg3)) { 1.625 + return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3), 1.626 + Tuple3<Arg1, Arg2, Arg3> >(object, method); 1.627 +} 1.628 + 1.629 +// 4-arg implementation 1.630 +template <typename Arg1, typename Arg2, typename Arg3, typename Arg4> 1.631 +struct Callback4 { 1.632 + typedef CallbackRunner<Tuple4<Arg1, Arg2, Arg3, Arg4> > Type; 1.633 +}; 1.634 + 1.635 +template <class T, typename Arg1, typename Arg2, typename Arg3, typename Arg4> 1.636 +typename Callback4<Arg1, Arg2, Arg3, Arg4>::Type* NewCallback( 1.637 + T* object, 1.638 + void (T::*method)(Arg1, Arg2, Arg3, Arg4)) { 1.639 + return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4), 1.640 + Tuple4<Arg1, Arg2, Arg3, Arg4> >(object, method); 1.641 +} 1.642 + 1.643 +// 5-arg implementation 1.644 +template <typename Arg1, typename Arg2, typename Arg3, 1.645 + typename Arg4, typename Arg5> 1.646 +struct Callback5 { 1.647 + typedef CallbackRunner<Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> > Type; 1.648 +}; 1.649 + 1.650 +template <class T, typename Arg1, typename Arg2, 1.651 + typename Arg3, typename Arg4, typename Arg5> 1.652 +typename Callback5<Arg1, Arg2, Arg3, Arg4, Arg5>::Type* NewCallback( 1.653 + T* object, 1.654 + void (T::*method)(Arg1, Arg2, Arg3, Arg4, Arg5)) { 1.655 + return new CallbackImpl<T, void (T::*)(Arg1, Arg2, Arg3, Arg4, Arg5), 1.656 + Tuple5<Arg1, Arg2, Arg3, Arg4, Arg5> >(object, method); 1.657 +} 1.658 + 1.659 +// An UnboundMethod is a wrapper for a method where the actual object is 1.660 +// provided at Run dispatch time. 1.661 +template <class T, class Method, class Params> 1.662 +class UnboundMethod { 1.663 + public: 1.664 + UnboundMethod(Method m, Params p) : m_(m), p_(p) {} 1.665 + void Run(T* obj) const { 1.666 + DispatchToMethod(obj, m_, p_); 1.667 + } 1.668 + private: 1.669 + Method m_; 1.670 + Params p_; 1.671 +}; 1.672 + 1.673 +#endif // BASE_TASK_H_