104 lines
		
	
	
	
		
			3.2 KiB
			
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
	
		
			3.2 KiB
			
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2013 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.chromium file.
 | 
						|
 | 
						|
#ifndef ELECTRON_SHELL_COMMON_GIN_HELPER_WRAPPABLE_H_
 | 
						|
#define ELECTRON_SHELL_COMMON_GIN_HELPER_WRAPPABLE_H_
 | 
						|
 | 
						|
#include "base/functional/bind.h"
 | 
						|
#include "gin/per_isolate_data.h"
 | 
						|
#include "shell/common/gin_helper/constructor.h"
 | 
						|
 | 
						|
namespace gin_helper {
 | 
						|
 | 
						|
bool IsValidWrappable(const v8::Local<v8::Value>& obj,
 | 
						|
                      const gin::WrapperInfo* wrapper_info);
 | 
						|
 | 
						|
namespace internal {
 | 
						|
 | 
						|
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val);
 | 
						|
 | 
						|
}  // namespace internal
 | 
						|
 | 
						|
template <typename T>
 | 
						|
class Wrappable : public WrappableBase {
 | 
						|
 public:
 | 
						|
  Wrappable() = default;
 | 
						|
 | 
						|
  template <typename Sig>
 | 
						|
  static void SetConstructor(v8::Isolate* isolate,
 | 
						|
                             const base::RepeatingCallback<Sig>& constructor) {
 | 
						|
    v8::Local<v8::FunctionTemplate> templ = gin_helper::CreateFunctionTemplate(
 | 
						|
        isolate, base::BindRepeating(&internal::InvokeNew<Sig>, constructor));
 | 
						|
    templ->InstanceTemplate()->SetInternalFieldCount(1);
 | 
						|
    T::BuildPrototype(isolate, templ);
 | 
						|
    gin::PerIsolateData::From(isolate)->SetFunctionTemplate(&kWrapperInfo,
 | 
						|
                                                            templ);
 | 
						|
  }
 | 
						|
 | 
						|
  static v8::Local<v8::FunctionTemplate> GetConstructor(v8::Isolate* isolate) {
 | 
						|
    // Fill the object template.
 | 
						|
    auto* data = gin::PerIsolateData::From(isolate);
 | 
						|
    auto templ = data->GetFunctionTemplate(&kWrapperInfo);
 | 
						|
    if (templ.IsEmpty()) {
 | 
						|
      templ = v8::FunctionTemplate::New(isolate);
 | 
						|
      templ->InstanceTemplate()->SetInternalFieldCount(1);
 | 
						|
      T::BuildPrototype(isolate, templ);
 | 
						|
      data->SetFunctionTemplate(&kWrapperInfo, templ);
 | 
						|
    }
 | 
						|
    return templ;
 | 
						|
  }
 | 
						|
 | 
						|
 protected:
 | 
						|
  // Init the class with T::BuildPrototype.
 | 
						|
  void Init(v8::Isolate* isolate) {
 | 
						|
    v8::Local<v8::FunctionTemplate> templ = GetConstructor(isolate);
 | 
						|
 | 
						|
    // |wrapper| may be empty in some extreme cases, e.g., when
 | 
						|
    // Object.prototype.constructor is overwritten.
 | 
						|
    v8::Local<v8::Object> wrapper;
 | 
						|
    if (!templ->InstanceTemplate()
 | 
						|
             ->NewInstance(isolate->GetCurrentContext())
 | 
						|
             .ToLocal(&wrapper)) {
 | 
						|
      // The current wrappable object will be no longer managed by V8. Delete
 | 
						|
      // this now.
 | 
						|
      delete this;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    InitWith(isolate, wrapper);
 | 
						|
  }
 | 
						|
 | 
						|
 private:
 | 
						|
  static gin::WrapperInfo kWrapperInfo;
 | 
						|
};
 | 
						|
 | 
						|
// static
 | 
						|
template <typename T>
 | 
						|
gin::WrapperInfo Wrappable<T>::kWrapperInfo = {gin::kEmbedderNativeGin};
 | 
						|
 | 
						|
}  // namespace gin_helper
 | 
						|
 | 
						|
namespace gin {
 | 
						|
 | 
						|
template <typename T>
 | 
						|
struct Converter<
 | 
						|
    T*,
 | 
						|
    typename std::enable_if<
 | 
						|
        std::is_convertible<T*, gin_helper::WrappableBase*>::value>::type> {
 | 
						|
  static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
 | 
						|
    if (val)
 | 
						|
      return val->GetWrapper();
 | 
						|
    else
 | 
						|
      return v8::Null(isolate);
 | 
						|
  }
 | 
						|
 | 
						|
  static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, T** out) {
 | 
						|
    *out = static_cast<T*>(static_cast<gin_helper::WrappableBase*>(
 | 
						|
        gin_helper::internal::FromV8Impl(isolate, val)));
 | 
						|
    return *out != nullptr;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace gin
 | 
						|
 | 
						|
#endif  // ELECTRON_SHELL_COMMON_GIN_HELPER_WRAPPABLE_H_
 |