提交 ca934cf9 编写于 作者: A Adam Barth

Reduce the boilerplate when creating bindings

Instead, use C++ template to generate the callback trampolines and the
registration block.
上级 decb96b6
......@@ -7,25 +7,18 @@
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "sky/engine/tonic/dart_args.h"
#include "sky/engine/tonic/dart_binding_macros.h"
#include "sky/engine/tonic/dart_converter.h"
#include "sky/engine/tonic/dart_library_natives.h"
namespace blink {
namespace {
void DisposeCallback(Dart_NativeArguments args) {
DartCall(&Scene::dispose, args);
}
} // namespace
IMPLEMENT_WRAPPERTYPEINFO(Scene);
void Scene::RegisterNatives(DartLibraryNatives* natives) {
natives->Register({
{ "Scene_dispose", DisposeCallback, 1, true },
});
}
#define FOR_EACH_BINDING(V) \
V(Scene, dispose)
DART_BIND_ALL(Scene, FOR_EACH_BINDING)
PassRefPtr<Scene> Scene::create(
std::unique_ptr<sky::compositor::Layer> rootLayer,
......
......@@ -16,17 +16,17 @@
#include "sky/compositor/statistics_layer.h"
#include "sky/compositor/transform_layer.h"
#include "sky/engine/tonic/dart_args.h"
#include "sky/engine/tonic/dart_binding_macros.h"
#include "sky/engine/tonic/dart_converter.h"
#include "sky/engine/tonic/dart_library_natives.h"
namespace blink {
namespace {
void ConstructorCallback(Dart_NativeArguments args) {
static void SceneBuilder_constructor(Dart_NativeArguments args) {
DartCallConstructor(&SceneBuilder::create, args);
}
void PushTransformCallback(Dart_NativeArguments args) {
static void SceneBuilder_pushTransform(Dart_NativeArguments args) {
DartArgIterator it(args);
Float64List matrix4 = it.GetNext<Float64List>();
if (it.had_exception())
......@@ -37,64 +37,27 @@ void PushTransformCallback(Dart_NativeArguments args) {
Dart_ThrowException(es.GetDartException(args, true));
}
void PushClipRectCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::pushClipRect, args);
}
void PushClipRRectCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::pushClipRRect, args);
}
void PushClipPathCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::pushClipPath, args);
}
void PushOpacityCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::pushOpacity, args);
}
void PushColorFilterCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::pushColorFilter, args);
}
void PopCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::pop, args);
}
void AddPictureCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::addPicture, args);
}
void AddStatisticsCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::addStatistics, args);
}
void SetRasterizerTracingThresholdCallback(Dart_NativeArguments args) {
DartCall(&SceneBuilder::setRasterizerTracingThreshold, args);
}
void BuildCallback(Dart_NativeArguments args) {
DartCallAndReturn(&SceneBuilder::build, args);
}
IMPLEMENT_WRAPPERTYPEINFO(SceneBuilder);
} // namespace
#define FOR_EACH_BINDING(V) \
V(SceneBuilder, pushClipRect) \
V(SceneBuilder, pushClipRRect) \
V(SceneBuilder, pushClipPath) \
V(SceneBuilder, pushOpacity) \
V(SceneBuilder, pushColorFilter) \
V(SceneBuilder, pop) \
V(SceneBuilder, addPicture) \
V(SceneBuilder, addStatistics) \
V(SceneBuilder, setRasterizerTracingThreshold) \
V(SceneBuilder, build)
IMPLEMENT_WRAPPERTYPEINFO(SceneBuilder);
FOR_EACH_BINDING(DART_NATIVE_CALLBACK)
void SceneBuilder::RegisterNatives(DartLibraryNatives* natives) {
natives->Register({
{ "SceneBuilder_constructor", ConstructorCallback, 2, true },
{ "SceneBuilder_pushTransform", PushTransformCallback, 2, true },
{ "SceneBuilder_pushClipRect", PushClipRectCallback, 2, true },
{ "SceneBuilder_pushClipRRect", PushClipRRectCallback, 3, true },
{ "SceneBuilder_pushClipPath", PushClipPathCallback, 3, true },
{ "SceneBuilder_pushOpacity", PushOpacityCallback, 3, true },
{ "SceneBuilder_pushColorFilter", PushColorFilterCallback, 4, true },
{ "SceneBuilder_pop", PopCallback, 1, true },
{ "SceneBuilder_addPicture", AddPictureCallback, 4, true },
{ "SceneBuilder_addStatistics", AddStatisticsCallback, 3, true },
{ "SceneBuilder_setRasterizerTracingThreshold", SetRasterizerTracingThresholdCallback, 2, true },
{ "SceneBuilder_build", BuildCallback, 1, true },
{ "SceneBuilder_constructor", SceneBuilder_constructor, 2, true },
{ "SceneBuilder_pushTransform", SceneBuilder_pushTransform, 2, true },
FOR_EACH_BINDING(DART_REGISTER_NATIVE)
});
}
......
......@@ -5,6 +5,8 @@
source_set("tonic") {
sources = [
"dart_api_scope.h",
"dart_args.h",
"dart_binding_macros.h",
"dart_class_library.cc",
"dart_class_library.h",
"dart_class_provider.cc",
......
......@@ -66,14 +66,16 @@ class IndicesForSignature {};
template <typename ResultType,
typename... ArgTypes>
struct IndicesForSignature<ResultType (*)(ArgTypes...)> {
using type = typename IndicesGenerator<sizeof...(ArgTypes)>::type;
static const size_t count = sizeof...(ArgTypes);
using type = typename IndicesGenerator<count>::type;
};
template <typename C,
typename ResultType,
typename... ArgTypes>
struct IndicesForSignature<ResultType (C::*)(ArgTypes...)> {
using type = typename IndicesGenerator<sizeof...(ArgTypes)>::type;
static const size_t count = sizeof...(ArgTypes);
using type = typename IndicesGenerator<count>::type;
};
template<size_t index, typename ArgType>
......@@ -89,19 +91,19 @@ struct DartArgHolder {
};
template <typename IndicesType, typename T>
class DartDecoder {
class DartDispatcher {
};
template <size_t... indices,
typename ResultType,
typename... ArgTypes>
struct DartDecoder<IndicesHolder<indices...>, ResultType (*)(ArgTypes...)>
struct DartDispatcher<IndicesHolder<indices...>, ResultType (*)(ArgTypes...)>
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = ResultType (*)(ArgTypes...);
DartArgIterator* it_;
explicit DartDecoder(DartArgIterator* it)
explicit DartDispatcher(DartArgIterator* it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) { }
ResultType Dispatch(FunctionPtr func) {
......@@ -109,22 +111,41 @@ struct DartDecoder<IndicesHolder<indices...>, ResultType (*)(ArgTypes...)>
}
};
template <size_t... indices,
typename C,
typename... ArgTypes>
struct DartDispatcher<IndicesHolder<indices...>, void (C::*)(ArgTypes...)>
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = void (C::*)(ArgTypes...);
DartArgIterator* it_;
explicit DartDispatcher(DartArgIterator* it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) { }
void Dispatch(FunctionPtr func) {
(GetReceiver<C>(it_->args())->*func)(
DartArgHolder<indices, ArgTypes>::value...);
}
};
template <size_t... indices,
typename C,
typename ResultType,
typename... ArgTypes>
struct DartDecoder<IndicesHolder<indices...>, ResultType (C::*)(ArgTypes...)>
struct DartDispatcher<IndicesHolder<indices...>, ResultType (C::*)(ArgTypes...)>
: public DartArgHolder<indices, ArgTypes>... {
using FunctionPtr = ResultType (C::*)(ArgTypes...);
DartArgIterator* it_;
explicit DartDecoder(DartArgIterator* it)
explicit DartDispatcher(DartArgIterator* it)
: DartArgHolder<indices, ArgTypes>(it)..., it_(it) { }
ResultType Dispatch(FunctionPtr func) {
return (GetReceiver<C>(it_->args())->*func)(
DartArgHolder<indices, ArgTypes>::value...);
void Dispatch(FunctionPtr func) {
DartReturn((GetReceiver<C>(it_->args())->*func)(
DartArgHolder<indices, ArgTypes>::value...),
it_->args());
}
};
......@@ -137,27 +158,17 @@ template<typename Sig>
void DartCall(Sig func, Dart_NativeArguments args) {
DartArgIterator it(args);
using Indices = typename IndicesForSignature<Sig>::type;
DartDecoder<Indices, Sig> decoder(&it);
DartDispatcher<Indices, Sig> decoder(&it);
if (it.had_exception())
return;
decoder.Dispatch(func);
}
template<typename Sig>
void DartCallAndReturn(Sig func, Dart_NativeArguments args) {
DartArgIterator it(args);
using Indices = typename IndicesForSignature<Sig>::type;
DartDecoder<Indices, Sig> decoder(&it);
if (it.had_exception())
return;
DartReturn(decoder.Dispatch(func), args);
}
template<typename Sig>
void DartCallConstructor(Sig func, Dart_NativeArguments args) {
DartArgIterator it(args);
using Indices = typename IndicesForSignature<Sig>::type;
DartDecoder<Indices, Sig> decoder(&it);
DartDispatcher<Indices, Sig> decoder(&it);
if (it.had_exception())
return;
decoder.Dispatch(func)->AssociateWithDartWrapper(args);
......
// Copyright 2015 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.
#ifndef SKY_ENGINE_TONIC_DART_BINDING_MACROS_H_
#define SKY_ENGINE_TONIC_DART_BINDING_MACROS_H_
#include "sky/engine/tonic/dart_args.h"
#define DART_NATIVE_CALLBACK(CLASS, METHOD) \
static void CLASS_##METHOD(Dart_NativeArguments args) { \
DartCall(&CLASS::METHOD, args); \
}
#define DART_REGISTER_NATIVE(CLASS, METHOD) \
{ #CLASS "_" #METHOD, CLASS_##METHOD, \
IndicesForSignature<decltype(&CLASS::METHOD)>::count + 1, true },
#define DART_BIND_ALL(CLASS, FOR_EACH) \
FOR_EACH(DART_NATIVE_CALLBACK) \
void CLASS::RegisterNatives(DartLibraryNatives* natives) { \
natives->Register({ \
FOR_EACH(DART_REGISTER_NATIVE) \
}); \
}
#endif // SKY_ENGINE_TONIC_DART_BINDING_MACROS_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册