15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifndef GOOGLE_APIS_DRIVE_TASK_UTIL_H_
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define GOOGLE_APIS_DRIVE_TASK_UTIL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google_apis {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Runs the task with the task runner.
145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void RunTaskWithTaskRunner(scoped_refptr<base::TaskRunner> task_runner,
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           const base::Closure& task);
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace internal {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation of the composed callback, whose signature is |Sig|.
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename Sig> struct ComposedCallback;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// ComposedCallback with no argument.
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochtemplate<>
24ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstruct ComposedCallback<void()> {
25ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  static void Run(
26ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      const base::Callback<void(const base::Closure&)>& runner,
27ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      const base::Closure& callback) {
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    runner.Run(callback);
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
30ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch};
31ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ComposedCallback with one argument.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T1>
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ComposedCallback<void(T1)> {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Run(
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(T1)>& callback,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T1 arg1) {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    runner.Run(base::Bind(callback, arg1));
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ComposedCallback with two arguments.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T1, typename T2>
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ComposedCallback<void(T1, T2)> {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Run(
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(T1, T2)>& callback,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T1 arg1, T2 arg2) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    runner.Run(base::Bind(callback, arg1, arg2));
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ComposedCallback with two arguments, and the last one is scoped_ptr.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T1, typename T2, typename D2>
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ComposedCallback<void(T1, scoped_ptr<T2, D2>)> {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Run(
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(T1, scoped_ptr<T2, D2>)>& callback,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T1 arg1, scoped_ptr<T2, D2> arg2) {
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    runner.Run(base::Bind(callback, arg1, base::Passed(&arg2)));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ComposedCallback with three arguments.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T1, typename T2, typename T3>
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ComposedCallback<void(T1, T2, T3)> {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Run(
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(T1, T2, T3)>& callback,
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T1 arg1, T2 arg2, T3 arg3) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    runner.Run(base::Bind(callback, arg1, arg2, arg3));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ComposedCallback with three arguments, and the last one is scoped_ptr.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename T1, typename T2, typename T3, typename D3>
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ComposedCallback<void(T1, T2, scoped_ptr<T3, D3>)> {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Run(
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(T1, T2, scoped_ptr<T3, D3>)>& callback,
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T1 arg1, T2 arg2, scoped_ptr<T3, D3> arg3) {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    runner.Run(base::Bind(callback, arg1, arg2, base::Passed(&arg3)));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ComposedCallback with four arguments.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename T1, typename T2, typename T3, typename T4>
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ComposedCallback<void(T1, T2, T3, T4)> {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void Run(
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(const base::Closure&)>& runner,
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::Callback<void(T1, T2, T3, T4)>& callback,
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      T1 arg1, T2 arg2, T3 arg3, T4 arg4) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    runner.Run(base::Bind(callback, arg1, arg2, arg3, arg4));
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace internal
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Returns callback that takes arguments (arg1, arg2, ...), create a closure
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// by binding them to |callback|, and runs |runner| with the closure.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// I.e. the returned callback works as follows:
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//   runner.Run(Bind(callback, arg1, arg2, ...))
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename CallbackType>
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CallbackType CreateComposedCallback(
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::Callback<void(const base::Closure&)>& runner,
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CallbackType& callback) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!runner.is_null());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!callback.is_null());
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::Bind(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &internal::ComposedCallback<typename CallbackType::RunType>::Run,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      runner, callback);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns callback which runs the given |callback| on the current thread.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename CallbackType>
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CallbackType CreateRelayCallback(const CallbackType& callback) {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateComposedCallback(
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      base::Bind(&RunTaskWithTaskRunner, base::MessageLoopProxy::current()),
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google_apis
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // GOOGLE_APIS_DRIVE_TASK_UTIL_H_
126