Skip to content

Commit

Permalink
Add a simple one shot and repeating timer API for Mojo.js.
Browse files Browse the repository at this point in the history
Various further rework of bindings stuff to facilitate.

Review URL: https://codereview.chromium.org/120043008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@242284 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
aa@chromium.org committed Dec 21, 2013
1 parent 91b82ad commit 2491f14
Show file tree
Hide file tree
Showing 27 changed files with 339 additions and 46 deletions.
7 changes: 7 additions & 0 deletions gin/function_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,13 @@ inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
return true;
}

// It's common for clients to just need the isolate, so we make that easy.
inline bool GetNextArgument(Arguments* args, int create_flags,
bool is_first, v8::Isolate** result) {
*result = args->isolate();
return true;
}


// DispatchToCallback converts all the JavaScript arguments to C++ types and
// invokes the base::Callback.
Expand Down
7 changes: 7 additions & 0 deletions gin/function_template.h.pump
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,13 @@ inline bool GetNextArgument(Arguments* args, int create_flags, bool is_first,
return true;
}

// It's common for clients to just need the isolate, so we make that easy.
inline bool GetNextArgument(Arguments* args, int create_flags,
bool is_first, v8::Isolate** result) {
*result = args->isolate();
return true;
}


// DispatchToCallback converts all the JavaScript arguments to C++ types and
// invokes the base::Callback.
Expand Down
3 changes: 3 additions & 0 deletions gin/gin.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
'modules/module_registry.h',
'modules/module_runner_delegate.cc',
'modules/module_runner_delegate.h',
'modules/timer.cc',
'modules/timer.h',
'object_template_builder.cc',
'object_template_builder.h',
'per_context_data.cc',
Expand Down Expand Up @@ -112,6 +114,7 @@
],
'sources': [
'converter_unittest.cc',
'modules/timer_unittest.cc',
'test/run_all_unittests.cc',
'test/run_js_tests.cc',
'runner_unittest.cc',
Expand Down
4 changes: 2 additions & 2 deletions gin/modules/console.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ WrapperInfo g_wrapper_info = { kEmbedderNativeGin };

const char Console::kModuleName[] = "console";

v8::Local<ObjectTemplate> Console::GetTemplate(v8::Isolate* isolate) {
v8::Local<v8::Value> Console::GetModule(v8::Isolate* isolate) {
PerIsolateData* data = PerIsolateData::From(isolate);
v8::Local<ObjectTemplate> templ = data->GetObjectTemplate(&g_wrapper_info);
if (templ.IsEmpty()) {
Expand All @@ -38,7 +38,7 @@ v8::Local<ObjectTemplate> Console::GetTemplate(v8::Isolate* isolate) {
.Build();
data->SetObjectTemplate(&g_wrapper_info, templ);
}
return templ;
return templ->NewInstance();
}

} // namespace gin
2 changes: 1 addition & 1 deletion gin/modules/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace gin {
class GIN_EXPORT Console {
public:
static const char kModuleName[];
static v8::Local<v8::ObjectTemplate> GetTemplate(v8::Isolate* isolate);
static v8::Local<v8::Value> GetModule(v8::Isolate* isolate);
};

} // namespace gin
Expand Down
7 changes: 3 additions & 4 deletions gin/modules/module_registry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,10 @@ ModuleRegistry* ModuleRegistry::From(v8::Handle<Context> context) {
return static_cast<ModuleRegistry*>(external->Value());
}

void ModuleRegistry::AddBuiltinModule(Isolate* isolate,
const std::string& id,
v8::Handle<ObjectTemplate> templ) {
void ModuleRegistry::AddBuiltinModule(Isolate* isolate, const std::string& id,
v8::Handle<Value> module) {
DCHECK(!id.empty());
RegisterModule(isolate, id, templ->NewInstance());
RegisterModule(isolate, id, module);
}

void ModuleRegistry::AddPendingModule(Isolate* isolate,
Expand Down
5 changes: 2 additions & 3 deletions gin/modules/module_registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ class GIN_EXPORT ModuleRegistry : public ContextSupplement {
v8::Handle<v8::ObjectTemplate> templ);

// The caller must have already entered our context.
void AddBuiltinModule(v8::Isolate* isolate,
const std::string& id,
v8::Handle<v8::ObjectTemplate> templ);
void AddBuiltinModule(v8::Isolate* isolate, const std::string& id,
v8::Handle<v8::Value> module);

// The caller must have already entered our context.
void AddPendingModule(v8::Isolate* isolate,
Expand Down
4 changes: 2 additions & 2 deletions gin/modules/module_runner_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ ModuleRunnerDelegate::~ModuleRunnerDelegate() {
}

void ModuleRunnerDelegate::AddBuiltinModule(const std::string& id,
ModuleTemplateGetter templ) {
builtin_modules_[id] = templ;
ModuleGetter getter) {
builtin_modules_[id] = getter;
}

void ModuleRunnerDelegate::AttemptToLoadMoreModules(Runner* runner) {
Expand Down
12 changes: 3 additions & 9 deletions gin/modules/module_runner_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@

namespace gin {

typedef v8::Local<v8::ObjectTemplate> (*ModuleTemplateGetter)(
v8::Isolate* isolate);
typedef v8::Local<v8::Value> (*ModuleGetter)(v8::Isolate* isolate);

// Emebedders that use AMD modules will probably want to use a RunnerDelegate
// that inherits from ModuleRunnerDelegate. ModuleRunnerDelegate lets embedders
Expand All @@ -26,18 +25,13 @@ class GIN_EXPORT ModuleRunnerDelegate : public RunnerDelegate {
const std::vector<base::FilePath>& search_paths);
virtual ~ModuleRunnerDelegate();

// Lets you register a built-in module. Built-in modules are instantiated by
// creating a new instance of a v8::ObjectTemplate rather than by executing
// code. This function takes a ModuleTemplateGetter rather than a
// v8::ObjectTemplate directly so that embedders can create object templates
// lazily.
void AddBuiltinModule(const std::string& id, ModuleTemplateGetter templ);
void AddBuiltinModule(const std::string& id, ModuleGetter getter);

protected:
void AttemptToLoadMoreModules(Runner* runner);

private:
typedef std::map<std::string, ModuleTemplateGetter> BuiltinModuleMap;
typedef std::map<std::string, ModuleGetter> BuiltinModuleMap;

// From RunnerDelegate:
virtual v8::Handle<v8::ObjectTemplate> GetGlobalTemplate(
Expand Down
95 changes: 95 additions & 0 deletions gin/modules/timer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// 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 file.

#include "gin/modules/timer.h"

#include "base/bind.h"
#include "gin/object_template_builder.h"
#include "gin/per_context_data.h"

namespace gin {

namespace {

v8::Handle<v8::String> GetHiddenPropertyName(v8::Isolate* isolate) {
return gin::StringToSymbol(isolate, "::gin::Timer");
}

} // namespace

// Timer

gin::WrapperInfo Timer::kWrapperInfo = { gin::kEmbedderNativeGin };

// static
Handle<Timer> Timer::Create(TimerType type, v8::Isolate* isolate, int delay_ms,
v8::Handle<v8::Function> function) {
return CreateHandle(isolate, new Timer(isolate, type == TYPE_REPEATING,
delay_ms, function));
}

ObjectTemplateBuilder Timer::GetObjectTemplateBuilder(v8::Isolate* isolate) {
return Wrappable<Timer>::GetObjectTemplateBuilder(isolate)
.SetMethod("cancel",
base::Bind(&base::Timer::Stop, base::Unretained(&timer_)))
.SetMethod("reset",
base::Bind(&base::Timer::Reset, base::Unretained(&timer_)));
}

Timer::Timer(v8::Isolate* isolate, bool repeating, int delay_ms,
v8::Handle<v8::Function> function)
: weak_factory_(this),
timer_(false, repeating),
runner_(PerContextData::From(
isolate->GetCurrentContext())->runner()->GetWeakPtr()) {
GetWrapper(runner_->isolate())->SetHiddenValue(GetHiddenPropertyName(isolate),
function);
timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(delay_ms),
base::Bind(&Timer::OnTimerFired, weak_factory_.GetWeakPtr()));
}

Timer::~Timer() {
}

void Timer::OnTimerFired() {
if (!runner_)
return;
Runner::Scope scope(runner_.get());
v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(
GetWrapper(runner_->isolate())->GetHiddenValue(
GetHiddenPropertyName(runner_->isolate())));
runner_->Call(function, v8::Undefined(runner_->isolate()), 0, NULL);
}


// TimerModule

WrapperInfo TimerModule::kWrapperInfo = { kEmbedderNativeGin };

// static
Handle<TimerModule> TimerModule::Create(v8::Isolate* isolate) {
return CreateHandle(isolate, new TimerModule());
}

// static
v8::Local<v8::Value> TimerModule::GetModule(v8::Isolate* isolate) {
return Create(isolate)->GetWrapper(isolate);
}

TimerModule::TimerModule() {
}

TimerModule::~TimerModule() {
}

ObjectTemplateBuilder TimerModule::GetObjectTemplateBuilder(
v8::Isolate* isolate) {
return Wrappable<TimerModule>::GetObjectTemplateBuilder(isolate)
.SetMethod("createOneShot",
base::Bind(&Timer::Create, Timer::TYPE_ONE_SHOT))
.SetMethod("createRepeating",
base::Bind(&Timer::Create, Timer::TYPE_REPEATING));
}

} // namespace gin
63 changes: 63 additions & 0 deletions gin/modules/timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 file.

#ifndef GIN_MODULES_TIMER_H_
#define GIN_MODULES_TIMER_H_

#include "base/memory/weak_ptr.h"
#include "base/timer/timer.h"
#include "gin/gin_export.h"
#include "gin/handle.h"
#include "gin/runner.h"
#include "gin/wrappable.h"
#include "v8/include/v8.h"

namespace gin {

class ObjectTemplateBuilder;

// A simple scriptable timer that can work in one-shot or repeating mode.
class GIN_EXPORT Timer : public Wrappable<Timer> {
public:
enum TimerType {
TYPE_ONE_SHOT,
TYPE_REPEATING
};

static WrapperInfo kWrapperInfo;
static Handle<Timer> Create(TimerType type, v8::Isolate* isolate,
int delay_ms, v8::Handle<v8::Function> function);

virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;

private:
Timer(v8::Isolate* isolate, bool repeating, int delay_ms,
v8::Handle<v8::Function> function);
virtual ~Timer();
void OnTimerFired();

base::WeakPtrFactory<Timer> weak_factory_;
base::Timer timer_;
base::WeakPtr<gin::Runner> runner_;
};


class GIN_EXPORT TimerModule : public Wrappable<TimerModule> {
public:
static WrapperInfo kWrapperInfo;
static Handle<TimerModule> Create(v8::Isolate* isolate);
static v8::Local<v8::Value> GetModule(v8::Isolate* isolate);

private:
TimerModule();
virtual ~TimerModule();

virtual ObjectTemplateBuilder GetObjectTemplateBuilder(
v8::Isolate* isolate) OVERRIDE;
};

} // namespace gin

#endif // GIN_MODULES_TIMER_H_
Loading

0 comments on commit 2491f14

Please sign in to comment.