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

Unified Diff: base/callback.h

Issue 6109007: Unified callback system. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/base
Patch Set: Illustrates the basic structure of classes. Created 9 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/prebind.h » ('j') | base/prebind.h » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/callback.h
diff --git a/base/callback.h b/base/callback.h
index e5ea7716b10ab236caaa7df54aff51fd8b89df14..cbdc9b177a70ef8226e30395560d76ae3b2884ce 100644
--- a/base/callback.h
+++ b/base/callback.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -7,6 +7,7 @@
#pragma once
#include "base/tuple.h"
+#include "base/ref_counted.h"
#include "base/raw_scoped_refptr_mismatch_checker.h"
// Callback --------------------------------------------------------------------
@@ -251,4 +252,127 @@ NewCallbackWithReturnValue(T* object, ReturnValue (T::*method)()) {
object, method);
}
+// New, super-duper, unified Callback system. This will eventually replace
+// NewRunnableMethod, NewRunnableFunction, CreateFunctor, and CreateCallback
+// systems currently in the Chromium code base.
+//
+// WHAT IS THIS:
+//
+// The templated Callback class is a generalized funciton object. Together
+// with the Prebind() function, they provide a type-safe method for
+// creating a "closure." In programing languages, a closure is a first-class
+// function where all its parameters have been bound. Closures are well suited
+// for passing around a unit of delayed execution. They are used in Chromium
+// code to schedule tasks on different MessageLoops.
+//
+// EXAMPLE USAGE:
+//
+// TODO(ajwong): Add some good examples.
+//
+//
+// WHERE IS THIS DESIGN FROM:
+//
+// The design Callback and Prebind is heavily influenced by C++'s
+// tr1::function/tr1::bind, and by the "Google Callback" system used inside
+// Google.
+//
+//
+// WHY NOT TR1 FUNCTION/BIND?
+//
+// Direct use of tr1::function and tr1::bind was considered, but ultimately
+// rejected because of the number of copy constructors invocations when binding arguments.
willchan no longer on Chromium 2011/01/19 16:57:43 I'm not trying to wordsmith the comments here, jus
awong 2011/01/20 20:27:35 Ooh...good point. Will add a note about it.
+//
+// Measured with valgrind on gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5), the
+// tr1::bind call itself will invoke a non-trivial copy constructor three times
+// for each bound parameter. Also, each when passing a tr1::function, each
+// bound argument will be copied again.
+namespace base {
+
+// InvokerBase is used to provide an opaque handle that the Callback class can
+// use to represent a function object with bound arguments. It behaves as an
+// existential type that is used by a corresponding PolymorphicInvoke function
+// to perform the function execution. This allows us to shield the Callback
+// class from the types of the bound arguments via "type erasure."
+//
+// TODO(ajwong): Explain the PolymorphicInvoke setup is more understandable
+// terms.
+class InvokerBase : public RefCountedThreadSafe<InvokerBase> {
willchan no longer on Chromium 2011/01/19 16:57:43 Just noting that this is RefCountedThreadSafe. Eve
awong 2011/01/20 20:27:35 I think we started talking about it, but never act
+ protected:
+ virtual ~InvokerBase() {}
willchan no longer on Chromium 2011/01/19 16:57:43 Why is this virtual?
awong 2011/01/20 20:27:35 The scope_refptr's static type is scoped_refptr<In
willchan no longer on Chromium 2011/01/21 02:30:12 Yes, I'm wrong. I wrote that comment early on when
+};
+
+// First, forward declare the Callback class template. This informs the
+// compiler that ther template only have 1 type parameter, the function
+// signature that the Callback is abstracting.
+//
+// After this, create template specializations for 0-5 parameters. Note that
+// even though the template typelist grows, that the specialization still
+// only has one type: the function signature.
+template <typename Sig>
+class Callback;
+
+template <typename R>
+class Callback<R(void)> {
+ public:
+ typedef R(*PolymorphicInvoke)(InvokerBase*);
+
+ Callback(InvokerBase* invoker, PolymorphicInvoke* polymorphic_invoke)
+ : invoker_(invoker),
+ polymorphic_invoke_(polymorphic_invoke) {
+ }
+
+ R Run(void) {
+ return polymorphic_invoke_(invoker_.get());
+ }
+
+ private:
+ scoped_refptr<InvokerBase> invoker_;
+ PolymorphicInvoke polymorphic_invoke_;
+};
+
+template <typename R, typename A0>
+class Callback<R(A0)> {
+ public:
+ typedef R(*PolymorphicInvoke)(InvokerBase*, const A0&);
+
+ Callback(InvokerBase* invoker, PolymorphicInvoke* polymorphic_invoke)
+ : invoker_(invoker),
+ polymorphic_invoke_(polymorphic_invoke) {
+ }
+
+ R Run(const A0& a0) {
+ return polymorphic_invoke_(invoker_.get(), a0);
+ }
+
+ private:
+ scoped_refptr<InvokerBase> invoker_;
+ PolymorphicInvoke polymorphic_invoke_;
+};
+
+template <typename R, typename A0, typename A1>
+class Callback<R(A0, A1)> {
+ public:
+ typedef R(*PolymorphicInvoke)(void*, const A0&, const A1&);
+
+ Callback(InvokerBase* invoker, PolymorphicInvoke* polymorphic_invoke)
+ : invoker_(invoker),
+ polymorphic_invoke_(polymorphic_invoke) {
+ }
+
+ R Run(const A0& a0, const A1& a1) {
+ return polymorphic_invoke_(invoker_.get(), a0, a1);
+ }
+
+ private:
+ scoped_refptr<InvokerBase> invoker_;
+ PolymorphicInvoke polymorphic_invoke_;
+};
+
+
+// Syntactic sugar to make Callbacks<void(void)> easier to read since it will
+// be used in a lot of APIs with delayed execution.
+typename Callback<void(void)> Closure;
+
+} // namespace base
+
#endif // BASE_CALLBACK_H
« no previous file with comments | « no previous file | base/prebind.h » ('j') | base/prebind.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698