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

Side by Side Diff: base/uber_callback.h.pump

Issue 6109007: Unified callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: pumped up Created 9 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« base/uber_callback.h ('K') | « base/uber_callback.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 BASE_UBER_CALLBACK_H_
6 #define BASE_UBER_CALLBACK_H_
7 #pragma once
8
9 #include "base/ref_counted.h"
10
11 // New, super-duper, unified Callback system. This will eventually replace
12 // NewRunnableMethod, NewRunnableFunction, CreateFunctor, and CreateCallback
13 // systems currently in the Chromium code base.
14 //
15 // WHAT IS THIS:
16 //
17 // The templated Callback class is a generalized funciton object. Together
18 // with the Prebind() function, they provide a type-safe method for
19 // creating a "closure." In programing languages, a closure is a first-class
20 // function where all its parameters have been bound. Closures are well suited
21 // for passing around a unit of delayed execution. They are used in Chromium
22 // code to schedule tasks on different MessageLoops.
23 //
24 // EXAMPLE USAGE:
25 //
26 // TODO(ajwong): Add some good examples.
27 //
28 //
29 // WHERE IS THIS DESIGN FROM:
30 //
31 // The design Callback and Prebind is heavily influenced by C++'s
32 // tr1::function/tr1::bind, and by the "Google Callback" system used inside
33 // Google.
34 //
35 //
36 // WHY NOT TR1 FUNCTION/BIND?
37 //
38 // Direct use of tr1::function and tr1::bind was considered, but ultimately
39 // rejected because of the number of copy constructors invocations when binding
40 // arguments. These copies will no longer be an issue in C++0x; C++0x will
41 // support rvalue reference which will solve the copies. However, waiting for
42 // C++0x is not an option.
43 //
44 // Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
45 // tr1::bind call itself will invoke a non-trivial copy constructor three times
46 // for each bound parameter. Also, each when passing a tr1::function, each
47 // bound argument will be copied again.
48
49 namespace base {
50
51 // InvokerStorageBase is used to provide an opaque handle that the Callback
52 // class can use to represent a function object with bound arguments. It
53 // behaves as an existential type that is used by a corresponding
54 // PolymorphicInvoke function to perform the function execution. This allows
55 // us to shield the Callback class from the types of the bound arguments via
56 // "type erasure."
57 //
58 // TODO(ajwong): Explain the PolymorphicInvoke setup is more understandable
59 // terms.
60 class InvokerStorageBase : public RefCountedThreadSafe<InvokerStorageBase> {
61 protected:
62 friend class RefCountedThreadSafe<InvokerStorageBase>;
63 virtual ~InvokerStorageBase() {}
64 };
65
66 template <typename T>
67 struct InvokerStorageHolder {
68 explicit InvokerStorageHolder(T* invoker_storage)
69 : invoker_storage_(invoker_storage) {
70 }
71 scoped_refptr<InvokerStorageBase> invoker_storage_;
72 };
73
74 template <typename T>
75 InvokerStorageHolder<T> MakeInvokerStorageHolder(T* o) {
76 return InvokerStorageHolder<T>(o);
77 }
78
79 // First, forward declare the Callback class template. This informs the
80 // compiler that ther template only have 1 type parameter, the function
81 // signature that the Callback is abstracting.
82 //
83 // After this, create template specializations for 0-5 parameters. Note that
84 // even though the template typelist grows, that the specialization still
85 // only has one type: the function signature.
86 //
87 // Also, note that the templated constructor should *not* be explicit. This is
88 // to allow the natural assignment syntax from the result of Prebind().
89 template <typename Sig>
90 class Callback;
91
92 $var MAX_ARITY = 6
93
94 $range ARITY 0..MAX_ARITY
95 $for ARITY [[
96 $range ARG 1..ARITY
97
98 $if ARITY == 0 [[
99 template <typename R>
100 class Callback<R(void)> {
101 ]] $else [[
102 template <typename R, $for ARG , [[typename A$(ARG)]]>
103 class Callback<R($for ARG , [[A$(ARG)]])> {
104 ]]
105
106 public:
107 typedef R(*PolymorphicInvoke)(InvokerStorageBase*[[]]
108 $if ARITY != 0 [[, ]] $for ARG , [[A$(ARG)]]);
109
110 template <typename T>
111 Callback(const InvokerStorageHolder<T>& invoker_holder)
112 : polymorphic_invoke_(&T::FunctionTraits::DoInvoke) {
113 invoker_storage_.swap(
114 const_cast<InvokerStorageHolder<T>&>(invoker_holder).invoker_storage_);
115 }
116
117
118 $if ARITY == 0 [[
119 R Run(void) {
120 ]] $else [[
121 R Run($for ARG , [[A$(ARG) a$(ARG)]]) {
122 ]]
123
124 return polymorphic_invoke_(invoker_storage_.get()[[]]
125 $if ARITY != 0 [[, ]] $for ARG , [[a$(ARG)]]);
126 }
127
128 private:
129 scoped_refptr<InvokerStorageBase> invoker_storage_;
130 PolymorphicInvoke polymorphic_invoke_;
131 };
132
133
134 ]] $$ for ARITY
135
136 // Syntactic sugar to make Callbacks<void(void)> easier to read since it will
137 // be used in a lot of APIs with delayed execution.
138 typedef Callback<void(void)> Closure;
139
140 } // namespace base
141
142 #endif // BASE_UBER_CALLBACK_H
OLDNEW
« base/uber_callback.h ('K') | « base/uber_callback.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698