Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: src/GlobalJsObject.cpp

Issue 10085006: Implement setTimeout (Closed)
Patch Set: Created April 8, 2013, 1:07 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « libadblockplus.gyp ('k') | src/JsEngine.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/GlobalJsObject.cpp
===================================================================
--- a/src/GlobalJsObject.cpp
+++ b/src/GlobalJsObject.cpp
@@ -1,7 +1,87 @@
+#include <vector>
+#include <stdexcept>
+
#include "GlobalJsObject.h"
+#include "Thread.h"
using namespace AdblockPlus;
+namespace
+{
+ class TimeoutThread : public Thread
+ {
+ public:
+ TimeoutThread(v8::Isolate* const isolate, const v8::Arguments& arguments)
+ : isolate(isolate)
+ {
+ if (arguments.Length() < 2)
+ throw std::runtime_error("setTimeout requires at least 2 parameters");
+
+ const v8::Local<v8::Value> functionValue = arguments[0];
+ if (!functionValue->IsFunction())
+ throw std::runtime_error("No valid function passed to setTimeout");
Wladimir Palant 2013/04/08 14:03:47 Nit: I think the canonical message is: "First argu
+
+ const v8::Local<v8::Value> delayValue = arguments[1];
+ if (!delayValue->IsNumber())
+ throw std::runtime_error("No valid delay passed to setTimeout");
Wladimir Palant 2013/04/08 14:03:47 Nit: I think the canonical message is: "Second arg
+
+ function = v8::Persistent<v8::Function>::New(
+ isolate, v8::Local<v8::Function>::Cast(functionValue));
+ delay = delayValue->ToNumber()->Value();
+ for (int i = 2; i < arguments.Length(); i++)
+ {
+ const Value argument = Value::New(isolate, arguments[i]);
+ functionArguments.push_back(argument);
+ }
+ }
+
+ ~TimeoutThread()
+ {
+ function.Dispose(isolate);
+ for (Values::iterator it = functionArguments.begin();
+ it != functionArguments.end(); it++)
+ it->Dispose(isolate);
+ }
+
+ void Run()
+ {
+ Sleep(delay);
+ const v8::Locker locker(isolate);
+ const v8::HandleScope handleScope;
+ function->Call(function, functionArguments.size(), &functionArguments[0]);
+ delete this;
+ }
+
+ private:
+ typedef v8::Persistent<v8::Value> Value;
+ typedef std::vector<Value> Values;
+
+ v8::Isolate* const isolate;
+ v8::Persistent<v8::Function> function;
+ int delay;
+ Values functionArguments;
+ };
+
+ v8::Handle<v8::Value> SetTimeoutCallback(const v8::Arguments& arguments)
+ {
+ TimeoutThread* timeoutThread;
+ try
+ {
+ timeoutThread = new TimeoutThread(v8::Isolate::GetCurrent(), arguments);
+ }
+ catch (const std::exception& e)
+ {
+ return v8::ThrowException(v8::String::New(e.what()));
+ }
+ timeoutThread->Start();
+
+ // We should actually return the timer ID here, which could be
+ // used via clearTimeout(). But since we don't seem to need
+ // clearTimeout(), we can save that for later.
+ return v8::Undefined();
+ }
+}
+
v8::Handle<v8::ObjectTemplate> GlobalJsObject::Create(
ErrorCallback& errorCallback)
{
@@ -11,5 +91,8 @@
const v8::Handle<v8::ObjectTemplate> console =
AdblockPlus::ConsoleJsObject::Create(errorCallback);
global->Set(v8::String::New("console"), console);
+ const v8::Handle<v8::FunctionTemplate> setTimeoutFunction =
+ v8::FunctionTemplate::New(SetTimeoutCallback);
+ global->Set(v8::String::New("setTimeout"), setTimeoutFunction);
return handleScope.Close(global);
}
« no previous file with comments | « libadblockplus.gyp ('k') | src/JsEngine.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld