| Index: tonic/dart_wrappable.h
|
| diff --git a/tonic/dart_wrappable.h b/tonic/dart_wrappable.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..13feb999cf4771cb0d5e6971e8254bd1e09d290e
|
| --- /dev/null
|
| +++ b/tonic/dart_wrappable.h
|
| @@ -0,0 +1,146 @@
|
| +// 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_WRAPPABLE_H_
|
| +#define SKY_ENGINE_TONIC_DART_WRAPPABLE_H_
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/template_util.h"
|
| +#include "dart/runtime/include/dart_api.h"
|
| +#include "tonic/dart_converter.h"
|
| +#include "tonic/dart_error.h"
|
| +#include "tonic/dart_state.h"
|
| +#include "tonic/dart_wrapper_info.h"
|
| +
|
| +namespace blink {
|
| +class DartGCVisitor;
|
| +struct DartWrapperInfo;
|
| +
|
| +// DartWrappable is a base class that you can inherit from in order to be
|
| +// exposed to Dart code as an interface.
|
| +class DartWrappable {
|
| + public:
|
| + enum DartNativeFields {
|
| + kPeerIndex, // Must be first to work with Dart_GetNativeReceiver.
|
| + kWrapperInfoIndex,
|
| + kNumberOfNativeFields,
|
| + };
|
| +
|
| + DartWrappable() : dart_wrapper_(nullptr) {}
|
| +
|
| + // Subclasses that wish to expose a new interface must override this function
|
| + // and provide information about their wrapper. There is no need to call your
|
| + // base class's implementation of this function.
|
| + virtual const DartWrapperInfo& GetDartWrapperInfo() const = 0;
|
| +
|
| + // Subclasses that wish to integrate with the Dart garbage collector should
|
| + // override this function. Please call your base class's AcceptDartGCVisitor
|
| + // at the end of your override.
|
| + virtual void AcceptDartGCVisitor(DartGCVisitor& visitor) const;
|
| +
|
| + Dart_Handle CreateDartWrapper(DartState* dart_state);
|
| + void AssociateWithDartWrapper(Dart_NativeArguments args);
|
| + Dart_WeakPersistentHandle dart_wrapper() const { return dart_wrapper_; }
|
| +
|
| + protected:
|
| + virtual ~DartWrappable();
|
| +
|
| + private:
|
| + static void FinalizeDartWrapper(void* isolate_callback_data,
|
| + Dart_WeakPersistentHandle wrapper,
|
| + void* peer);
|
| +
|
| + Dart_WeakPersistentHandle dart_wrapper_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(DartWrappable);
|
| +};
|
| +
|
| +#define DEFINE_WRAPPERTYPEINFO() \
|
| + public: \
|
| + const DartWrapperInfo& GetDartWrapperInfo() const override { \
|
| + return dart_wrapper_info_; \
|
| + } \
|
| + private: \
|
| + static const DartWrapperInfo& dart_wrapper_info_
|
| +
|
| +struct DartConverterWrappable {
|
| + static DartWrappable* FromDart(Dart_Handle handle);
|
| + static DartWrappable* FromArguments(Dart_NativeArguments args,
|
| + int index,
|
| + Dart_Handle& exception);
|
| + static DartWrappable* FromArgumentsWithNullCheck(Dart_NativeArguments args,
|
| + int index,
|
| + Dart_Handle& exception);
|
| +};
|
| +
|
| +template<typename T>
|
| +struct DartConverter<
|
| + T*,
|
| + typename base::enable_if<
|
| + base::is_convertible<T*, DartWrappable*>::value>::type> {
|
| + static Dart_Handle ToDart(DartWrappable* val) {
|
| + if (!val)
|
| + return Dart_Null();
|
| + if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper())
|
| + return Dart_HandleFromWeakPersistent(wrapper);
|
| + return val->CreateDartWrapper(DartState::Current());
|
| + }
|
| +
|
| + static void SetReturnValue(Dart_NativeArguments args,
|
| + DartWrappable* val,
|
| + bool auto_scope = true) {
|
| + if (!val)
|
| + Dart_SetReturnValue(args, Dart_Null());
|
| + else if (Dart_WeakPersistentHandle wrapper = val->dart_wrapper())
|
| + Dart_SetWeakHandleReturnValue(args, wrapper);
|
| + else
|
| + Dart_SetReturnValue(args, val->CreateDartWrapper(DartState::Current()));
|
| + }
|
| +
|
| + static T* FromDart(Dart_Handle handle) {
|
| + // TODO(abarth): We're missing a type check.
|
| + return static_cast<T*>(DartConverterWrappable::FromDart(handle));
|
| + }
|
| +
|
| + static T* FromArguments(Dart_NativeArguments args,
|
| + int index,
|
| + Dart_Handle& exception,
|
| + bool auto_scope = true) {
|
| + // TODO(abarth): We're missing a type check.
|
| + return static_cast<T*>(DartConverterWrappable::FromArguments(
|
| + args, index, exception));
|
| + }
|
| +
|
| + static T* FromArgumentsWithNullCheck(Dart_NativeArguments args,
|
| + int index,
|
| + Dart_Handle& exception,
|
| + bool auto_scope = true) {
|
| + // TODO(abarth): We're missing a type check.
|
| + return static_cast<T*>(DartConverterWrappable::FromArgumentsWithNullCheck(
|
| + args, index, exception));
|
| + }
|
| +};
|
| +
|
| +template<typename T>
|
| +struct DartConverter<RefPtr<T>> {
|
| + static Dart_Handle ToDart(RefPtr<T> val) {
|
| + return DartConverter<T*>::ToDart(val.get());
|
| + }
|
| +
|
| + static RefPtr<T> FromDart(Dart_Handle handle) {
|
| + return DartConverter<T*>::FromDart(handle);
|
| + }
|
| +};
|
| +
|
| +template<typename T>
|
| +inline T* GetReceiver(Dart_NativeArguments args) {
|
| + intptr_t receiver;
|
| + Dart_Handle result = Dart_GetNativeReceiver(args, &receiver);
|
| + DCHECK(!Dart_IsError(result));
|
| + return static_cast<T*>(reinterpret_cast<DartWrappable*>(receiver));
|
| +}
|
| +
|
| +} // namespace blink
|
| +
|
| +#endif // SKY_ENGINE_TONIC_DART_WRAPPABLE_H_
|
|
|