From 872796bb8eaabbd9ab76dc8821310438aa690d85 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Fri, 20 Dec 2013 15:56:52 +0000 Subject: Allow multiple concurrent timers. BUG= R=robertphillips@google.com Author: jcgregorio@google.com Review URL: https://codereview.chromium.org/118473006 git-svn-id: http://skia.googlecode.com/svn/trunk@12802 2bbb7eff-a529-9590-31e7-b0007b416f81 --- experimental/SkV8Example/Global.cpp | 43 +++++++++++++++++++------------- experimental/SkV8Example/Global.h | 13 ++++++++-- experimental/SkV8Example/SkV8Example.cpp | 1 + experimental/SkV8Example/sample.js | 3 +-- 4 files changed, 39 insertions(+), 21 deletions(-) (limited to 'experimental') diff --git a/experimental/SkV8Example/Global.cpp b/experimental/SkV8Example/Global.cpp index a99ef05a03..b45d2de3c6 100644 --- a/experimental/SkV8Example/Global.cpp +++ b/experimental/SkV8Example/Global.cpp @@ -19,6 +19,16 @@ static const char* to_cstring(const v8::String::Utf8Value& value) { return *value ? *value : ""; } +int32_t Global::getNextTimerID() { + do { + fLastTimerID++; + if (fLastTimerID < 0) { + fLastTimerID = 0; + } + } while (fTimeouts.find(fLastTimerID) != fTimeouts.end()); + return fLastTimerID; +} + // Slight modification to an original function found in the V8 sample shell.cc. void Global::reportException(TryCatch* tryCatch) { HandleScope handleScope(fIsolate); @@ -91,9 +101,6 @@ void Global::Print(const v8::FunctionCallbackInfo& args) { // function is called. // // JS: setTimeout(on_timeout, 500); -// -// TODO(jcgregorio) Currently only handles one timeout, should support any -// number. void Global::SetTimeout(const v8::FunctionCallbackInfo& args) { if (args.Length() != 2) { args.GetIsolate()->ThrowException( @@ -108,14 +115,19 @@ void Global::SetTimeout(const v8::FunctionCallbackInfo& args) { return; } Handle timeoutFn = Handle::Cast(args[0]); - gGlobal->fTimeout.Reset(args.GetIsolate(), timeoutFn); double delay = args[1]->NumberValue(); + int32_t id = gGlobal->getNextTimerID(); + + gGlobal->fTimeouts[id].Reset(gGlobal->fIsolate, timeoutFn); // Create an SkEvent and add it with the right delay. - (new SkEvent())->setTargetProc(Global::TimeOutProc)->postDelay(delay); + SkEvent* evt = new SkEvent(); + evt->setTargetProc(Global::TimeOutProc); + evt->setFast32(id); + evt->postDelay(delay); - // TODO(jcgregorio) Return the ID as the return value. + args.GetReturnValue().Set(Integer::New(id)); } // Callback function for SkEvents used to implement timeouts. @@ -132,10 +144,17 @@ bool Global::TimeOutProc(const SkEvent& evt) { // Set up an exception handler before calling the Process function. TryCatch tryCatch; + int32_t id = evt.getFast32(); + if (gGlobal->fTimeouts.find(gGlobal->fLastTimerID) == gGlobal->fTimeouts.end()) { + printf("Not a valid timer ID.\n"); + return true; + } + const int argc = 0; Local onTimeout = - Local::New(gGlobal->getIsolate(), gGlobal->fTimeout); + Local::New(gGlobal->getIsolate(), gGlobal->fTimeouts[id]); Handle result = onTimeout->Call(context->Global(), argc, NULL); + gGlobal->fTimeouts.erase(id); // Handle any exceptions or output. if (result.IsEmpty()) { @@ -214,16 +233,6 @@ bool Global::parseScript(const char script[]) { // Print errors that happened during execution. this->reportException(&tryCatch); return false; - } else { - SkASSERT(!tryCatch.HasCaught()); - if (!result->IsUndefined()) { - // If all went well and the result wasn't undefined then print - // the returned value. - String::Utf8Value str(result); - const char* cstr = to_cstring(str); - printf("%s\n", cstr); - return false; - } } // Also make the context persistent. diff --git a/experimental/SkV8Example/Global.h b/experimental/SkV8Example/Global.h index aa05b01aaf..3377e21ede 100644 --- a/experimental/SkV8Example/Global.h +++ b/experimental/SkV8Example/Global.h @@ -10,6 +10,8 @@ #ifndef SkV8Example_Global_DEFINED #define SkV8Example_Global_DEFINED +#include + #include using namespace v8; @@ -19,6 +21,8 @@ using namespace v8; class SkOSWindow; +typedef Persistent > CopyablePersistentFn; + // Provides the global isolate and context for our V8 instance. // Also implements all the global level functions. class Global : SkNoncopyable { @@ -26,6 +30,7 @@ public: Global(Isolate* isolate) : fIsolate(isolate) , fWindow(NULL) + , fLastTimerID(0) { gGlobal = this; } @@ -53,6 +58,7 @@ public: private: Handle createRootContext(); + int32_t getNextTimerID(); static bool TimeOutProc(const SkEvent& evt); @@ -67,8 +73,11 @@ private: SkOSWindow* fWindow; static Global* gGlobal; - // Handle to the function to call when the timeout triggers. - Persistent fTimeout; + // Handle to the functions to call when a timeout triggers as indexed by id. + std::map fTimeouts; + + // Last timer ID generated. + int32_t fLastTimerID; }; #endif diff --git a/experimental/SkV8Example/SkV8Example.cpp b/experimental/SkV8Example/SkV8Example.cpp index 7c6622696b..fb4f42d705 100644 --- a/experimental/SkV8Example/SkV8Example.cpp +++ b/experimental/SkV8Example/SkV8Example.cpp @@ -310,6 +310,7 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { } if (!global->parseScript(script)) { + printf("Failed to parse file: %s.\n", FLAGS_infile[0]); exit(1); } diff --git a/experimental/SkV8Example/sample.js b/experimental/SkV8Example/sample.js index b516062044..841dd5daa7 100644 --- a/experimental/SkV8Example/sample.js +++ b/experimental/SkV8Example/sample.js @@ -13,8 +13,7 @@ var onDraw = function(){ function onTimeout() { inval(); - print("Got a timeout!"); - setTimeout(onTimeout, 33); + print(setTimeout(onTimeout, 33)); } setTimeout(onTimeout, 33); -- cgit v1.2.3