diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-12-18 04:45:37 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-12-18 04:45:37 +0000 |
commit | 0fc0dea333f313a579558beb7ba498db0711780e (patch) | |
tree | 02bbfa9462cbe17476c7f06e594a9db8a8c8652c /experimental | |
parent | 4e8f1e56b17c3663d1892f44a4c1893b568ce67f (diff) |
Add a setTimer() function.
Seemed simple, but required adding a Global class that contains all the global state (instance and context) for our running V8 instance. Also moved canvas.inval to be just inval() at the global level.
BUG=
R=robertphillips@google.com
Author: jcgregorio@google.com
Review URL: https://codereview.chromium.org/103143009
git-svn-id: http://skia.googlecode.com/svn/trunk@12730 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'experimental')
-rw-r--r-- | experimental/SkV8Example/Global.cpp | 232 | ||||
-rw-r--r-- | experimental/SkV8Example/Global.h | 74 | ||||
-rw-r--r-- | experimental/SkV8Example/SkV8Example.cpp | 255 | ||||
-rw-r--r-- | experimental/SkV8Example/SkV8Example.h | 22 | ||||
-rw-r--r-- | experimental/SkV8Example/sample.js | 11 |
5 files changed, 394 insertions, 200 deletions
diff --git a/experimental/SkV8Example/Global.cpp b/experimental/SkV8Example/Global.cpp new file mode 100644 index 0000000000..a99ef05a03 --- /dev/null +++ b/experimental/SkV8Example/Global.cpp @@ -0,0 +1,232 @@ +/* + * Copyright 2013 Google Inc. + * + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ +#include "Global.h" + +#include "SkWindow.h" +#include "SkEvent.h" + + +Global* Global::gGlobal = NULL; + +// Extracts a C string from a V8 Utf8Value. +static const char* to_cstring(const v8::String::Utf8Value& value) { + return *value ? *value : "<string conversion failed>"; +} + +// Slight modification to an original function found in the V8 sample shell.cc. +void Global::reportException(TryCatch* tryCatch) { + HandleScope handleScope(fIsolate); + String::Utf8Value exception(tryCatch->Exception()); + const char* exceptionString = to_cstring(exception); + Handle<Message> message = tryCatch->Message(); + if (message.IsEmpty()) { + // V8 didn't provide any extra information about this error; just + // print the exception. + fprintf(stderr, "%s\n", exceptionString); + } else { + // Print (filename):(line number): (message). + String::Utf8Value filename(message->GetScriptResourceName()); + const char* filenameString = to_cstring(filename); + int linenum = message->GetLineNumber(); + fprintf(stderr, + "%s:%i: %s\n", filenameString, linenum, exceptionString); + // Print line of source code. + String::Utf8Value sourceline(message->GetSourceLine()); + const char* sourceLineString = to_cstring(sourceline); + fprintf(stderr, "%s\n", sourceLineString); + // Print wavy underline. + int start = message->GetStartColumn(); + for (int i = 0; i < start; i++) { + fprintf(stderr, " "); + } + int end = message->GetEndColumn(); + for (int i = start; i < end; i++) { + fprintf(stderr, "^"); + } + fprintf(stderr, "\n"); + String::Utf8Value stackTrace(tryCatch->StackTrace()); + if (stackTrace.length() > 0) { + const char* stackTraceString = to_cstring(stackTrace); + fprintf(stderr, "%s\n", stackTraceString); + } + } +} + +// The callback that implements the JavaScript 'inval' function. +// Invalidates the current window, forcing a redraw. +// +// JS: inval(); +void Global::Inval(const v8::FunctionCallbackInfo<Value>& args) { + gGlobal->getWindow()->inval(NULL); +} + +// The callback that is invoked by v8 whenever the JavaScript 'print' +// function is called. Prints its arguments on stdout separated by +// spaces and ending with a newline. +// +// JS: print("foo", "bar"); +void Global::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { + bool first = true; + HandleScope handleScope(args.GetIsolate()); + for (int i = 0; i < args.Length(); i++) { + if (first) { + first = false; + } else { + printf(" "); + } + v8::String::Utf8Value str(args[i]); + printf("%s", to_cstring(str)); + } + printf("\n"); + fflush(stdout); +} + +// The callback that is invoked by v8 whenever the JavaScript 'setTimeout' +// 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<v8::Value>& args) { + if (args.Length() != 2) { + args.GetIsolate()->ThrowException( + v8::String::NewFromUtf8( + args.GetIsolate(), "Error: 2 arguments required.")); + return; + } + + // Pull out the first arg, make sure it's a function. + if (!args[0]->IsFunction()) { + printf("Not a function passed to setTimeout.\n"); + return; + } + Handle<Function> timeoutFn = Handle<Function>::Cast(args[0]); + gGlobal->fTimeout.Reset(args.GetIsolate(), timeoutFn); + + double delay = args[1]->NumberValue(); + + // Create an SkEvent and add it with the right delay. + (new SkEvent())->setTargetProc(Global::TimeOutProc)->postDelay(delay); + + // TODO(jcgregorio) Return the ID as the return value. +} + +// Callback function for SkEvents used to implement timeouts. +bool Global::TimeOutProc(const SkEvent& evt) { + // Create a handle scope to keep the temporary object references. + HandleScope handleScope(gGlobal->getIsolate()); + + // Create a local context from our global context. + Local<Context> context = gGlobal->getContext(); + + // Enter the context so all the remaining operations take place there. + Context::Scope contextScope(context); + + // Set up an exception handler before calling the Process function. + TryCatch tryCatch; + + const int argc = 0; + Local<Function> onTimeout = + Local<Function>::New(gGlobal->getIsolate(), gGlobal->fTimeout); + Handle<Value> result = onTimeout->Call(context->Global(), argc, NULL); + + // Handle any exceptions or output. + if (result.IsEmpty()) { + SkASSERT(tryCatch.HasCaught()); + // Print errors that happened during execution. + gGlobal->reportException(&tryCatch); + } 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 true; +} + +// Creates a new execution environment containing the built-in functions. +Handle<Context> Global::createRootContext() { + // Create a template for the global object. + Handle<ObjectTemplate> global = ObjectTemplate::New(); + + global->Set(v8::String::NewFromUtf8(fIsolate, "print"), + v8::FunctionTemplate::New(Global::Print)); + global->Set(v8::String::NewFromUtf8(fIsolate, "setTimeout"), + v8::FunctionTemplate::New(Global::SetTimeout)); + global->Set(v8::String::NewFromUtf8(fIsolate, "inval"), + v8::FunctionTemplate::New(Global::Inval)); + + + return Context::New(fIsolate, NULL, global); +} + + +// Creates the root context, parses the script into it, then stores the +// context in a global. +// +// TODO(jcgregorio) Currently only handles one script. Need to move +// createRootContext to another call that's only done once. +bool Global::parseScript(const char script[]) { + + // Create a stack-allocated handle scope. + HandleScope handleScope(fIsolate); + + printf("Before create context\n"); + + // Create a new context. + Handle<Context> context = this->createRootContext(); + + // Enter the scope so all operations take place in the scope. + Context::Scope contextScope(context); + + v8::TryCatch tryCatch; + + // Compile the source code. + Handle<String> source = String::NewFromUtf8(fIsolate, script); + printf("Before Compile\n"); + Handle<Script> compiledScript = Script::Compile(source); + printf("After Compile\n"); + + if (compiledScript.IsEmpty()) { + // Print errors that happened during compilation. + this->reportException(&tryCatch); + return false; + } + printf("After Exception.\n"); + + // Try running it now to create the onDraw function. + Handle<Value> result = compiledScript->Run(); + + // Handle any exceptions or output. + if (result.IsEmpty()) { + SkASSERT(tryCatch.HasCaught()); + // 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. + fContext.Reset(fIsolate, context); + return true; +} diff --git a/experimental/SkV8Example/Global.h b/experimental/SkV8Example/Global.h new file mode 100644 index 0000000000..aa05b01aaf --- /dev/null +++ b/experimental/SkV8Example/Global.h @@ -0,0 +1,74 @@ +/* + * Copyright 2013 Google Inc. + * + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + */ + +#ifndef SkV8Example_Global_DEFINED +#define SkV8Example_Global_DEFINED + +#include <v8.h> + +using namespace v8; + +#include "SkTypes.h" +#include "SkEvent.h" + +class SkOSWindow; + +// Provides the global isolate and context for our V8 instance. +// Also implements all the global level functions. +class Global : SkNoncopyable { +public: + Global(Isolate* isolate) + : fIsolate(isolate) + , fWindow(NULL) + { + gGlobal = this; + } + virtual ~Global() {} + + // The script will be parsed into the context this Global contains. + bool parseScript(const char script[]); + + Local<Context> getContext() { + return Local<Context>::New(fIsolate, fContext); + } + + Isolate* getIsolate() { + return fIsolate; + } + + void setWindow(SkOSWindow* win) { + fWindow = win; + } + SkOSWindow* getWindow() { + return fWindow; + } + + void reportException(TryCatch* tryCatch); + +private: + Handle<Context> createRootContext(); + + static bool TimeOutProc(const SkEvent& evt); + + // Static functions that implement the global JS functions we add to + // the context. + static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Print(const v8::FunctionCallbackInfo<v8::Value>& args); + static void Inval(const v8::FunctionCallbackInfo<Value>& args); + + Persistent<Context> fContext; + Isolate* fIsolate; + SkOSWindow* fWindow; + static Global* gGlobal; + + // Handle to the function to call when the timeout triggers. + Persistent<Function> fTimeout; +}; + +#endif diff --git a/experimental/SkV8Example/SkV8Example.cpp b/experimental/SkV8Example/SkV8Example.cpp index a62b9191c6..7c6622696b 100644 --- a/experimental/SkV8Example/SkV8Example.cpp +++ b/experimental/SkV8Example/SkV8Example.cpp @@ -11,6 +11,7 @@ using namespace v8; #include "SkV8Example.h" +#include "Global.h" #include "gl/GrGLUtil.h" #include "gl/GrGLDefines.h" @@ -37,57 +38,11 @@ void application_term() { } // Extracts a C string from a V8 Utf8Value. -const char* ToCString(const v8::String::Utf8Value& value) { +// TODO(jcgregrio) Currently dup'd in two files, fix. +static const char* to_cstring(const v8::String::Utf8Value& value) { return *value ? *value : "<string conversion failed>"; } -// Slight modification to an original function found in the V8 sample shell.cc. -void reportException(Isolate* isolate, TryCatch* try_catch) { - HandleScope handleScope(isolate); - String::Utf8Value exception(try_catch->Exception()); - const char* exception_string = ToCString(exception); - Handle<Message> message = try_catch->Message(); - if (message.IsEmpty()) { - // V8 didn't provide any extra information about this error; just - // print the exception. - fprintf(stderr, "%s\n", exception_string); - } else { - // Print (filename):(line number): (message). - String::Utf8Value filename(message->GetScriptResourceName()); - const char* filename_string = ToCString(filename); - int linenum = message->GetLineNumber(); - fprintf(stderr, - "%s:%i: %s\n", filename_string, linenum, exception_string); - // Print line of source code. - String::Utf8Value sourceline(message->GetSourceLine()); - const char* sourceline_string = ToCString(sourceline); - fprintf(stderr, "%s\n", sourceline_string); - // Print wavy underline. - int start = message->GetStartColumn(); - for (int i = 0; i < start; i++) { - fprintf(stderr, " "); - } - int end = message->GetEndColumn(); - for (int i = start; i < end; i++) { - fprintf(stderr, "^"); - } - fprintf(stderr, "\n"); - String::Utf8Value stack_trace(try_catch->StackTrace()); - if (stack_trace.length() > 0) { - const char* stack_trace_string = ToCString(stack_trace); - fprintf(stderr, "%s\n", stack_trace_string); - } - } -} - -SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsCanvas* canvas) - : INHERITED(hwnd) - , fJsCanvas(canvas) -{ - this->setConfig(SkBitmap::kARGB_8888_Config); - this->setVisibleP(true); - this->setClipToBounds(false); -} JsCanvas* JsCanvas::Unwrap(Handle<Object> obj) { Handle<External> field = Handle<External>::Cast(obj->GetInternalField(0)); @@ -95,10 +50,6 @@ JsCanvas* JsCanvas::Unwrap(Handle<Object> obj) { return static_cast<JsCanvas*>(ptr); } -void JsCanvas::Inval(const v8::FunctionCallbackInfo<Value>& args) { - Unwrap(args.This())->fWindow->inval(NULL); -} - void JsCanvas::FillRect(const v8::FunctionCallbackInfo<Value>& args) { JsCanvas* jsCanvas = Unwrap(args.This()); SkCanvas* canvas = jsCanvas->fCanvas; @@ -164,7 +115,7 @@ void JsCanvas::SetFillStyle(Local<String> name, Local<Value> value, Persistent<ObjectTemplate> JsCanvas::fCanvasTemplate; Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { - EscapableHandleScope handleScope(fIsolate); + EscapableHandleScope handleScope(fGlobal->getIsolate()); Local<ObjectTemplate> result = ObjectTemplate::New(); @@ -173,18 +124,16 @@ Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { // Add accessors for each of the fields of the canvas object. result->SetAccessor( - String::NewFromUtf8(fIsolate, "fillStyle", String::kInternalizedString), + String::NewFromUtf8( + fGlobal->getIsolate(), "fillStyle", String::kInternalizedString), GetFillStyle, SetFillStyle); // Add methods. result->Set( String::NewFromUtf8( - fIsolate, "fillRect", String::kInternalizedString), + fGlobal->getIsolate(), "fillRect", + String::kInternalizedString), FunctionTemplate::New(FillRect)); - result->Set( - String::NewFromUtf8( - fIsolate, "inval", String::kInternalizedString), - FunctionTemplate::New(Inval)); // Return the result through the current handle scope. return handleScope.Escape(result); @@ -194,23 +143,23 @@ Handle<ObjectTemplate> JsCanvas::makeCanvasTemplate() { // Wraps 'this' in a Javascript object. Handle<Object> JsCanvas::wrap() { // Handle scope for temporary handles. - EscapableHandleScope handleScope(fIsolate); + EscapableHandleScope handleScope(fGlobal->getIsolate()); // Fetch the template for creating JavaScript JsCanvas wrappers. // It only has to be created once, which we do on demand. if (fCanvasTemplate.IsEmpty()) { Handle<ObjectTemplate> raw_template = this->makeCanvasTemplate(); - fCanvasTemplate.Reset(fIsolate, raw_template); + fCanvasTemplate.Reset(fGlobal->getIsolate(), raw_template); } Handle<ObjectTemplate> templ = - Local<ObjectTemplate>::New(fIsolate, fCanvasTemplate); + Local<ObjectTemplate>::New(fGlobal->getIsolate(), fCanvasTemplate); // Create an empty JsCanvas wrapper. Local<Object> result = templ->NewInstance(); // Wrap the raw C++ pointer in an External so it can be referenced // from within JavaScript. - Handle<External> canvasPtr = External::New(fIsolate, this); + Handle<External> canvasPtr = External::New(fGlobal->getIsolate(), this); // Store the canvas pointer in the JavaScript wrapper. result->SetInternalField(0, canvasPtr); @@ -222,16 +171,15 @@ Handle<Object> JsCanvas::wrap() { return handleScope.Escape(result); } -void JsCanvas::onDraw(SkCanvas* canvas, SkOSWindow* window) { +void JsCanvas::onDraw(SkCanvas* canvas) { // Record canvas and window in this. fCanvas = canvas; - fWindow = window; // Create a handle scope to keep the temporary object references. - HandleScope handleScope(fIsolate); + HandleScope handleScope(fGlobal->getIsolate()); // Create a local context from our global context. - Local<Context> context = Local<Context>::New(fIsolate, fContext); + Local<Context> context = fGlobal->getContext(); // Enter the context so all the remaining operations take place there. Context::Scope contextScope(context); @@ -247,140 +195,42 @@ void JsCanvas::onDraw(SkCanvas* canvas, SkOSWindow* window) { const int argc = 1; Handle<Value> argv[argc] = { canvasObj }; Local<Function> onDraw = - Local<Function>::New(fIsolate, fOnDraw); + Local<Function>::New(fGlobal->getIsolate(), fOnDraw); Handle<Value> result = onDraw->Call(context->Global(), argc, argv); // Handle any exceptions or output. if (result.IsEmpty()) { SkASSERT(tryCatch.HasCaught()); // Print errors that happened during execution. - reportException(fIsolate, &tryCatch); + fGlobal->reportException(&tryCatch); } 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 = ToCString(str); + const char* cstr = to_cstring(str); printf("%s\n", cstr); } } } -void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { - - canvas->save(); - canvas->drawColor(SK_ColorWHITE); - - // Now jump into JS and call the onDraw(canvas) method defined there. - fJsCanvas->onDraw(canvas, this); - - canvas->restore(); - - INHERITED::onDraw(canvas); -} - - -#ifdef SK_BUILD_FOR_WIN -void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) { - RECT winRect; - winRect.top = rect.top(); - winRect.bottom = rect.bottom(); - winRect.right = rect.right(); - winRect.left = rect.left(); - InvalidateRect((HWND)this->getHWND(), &winRect, false); -} -#endif - - -// The callback that is invoked by v8 whenever the JavaScript 'print' -// function is called. Prints its arguments on stdout separated by -// spaces and ending with a newline. -void Print(const v8::FunctionCallbackInfo<v8::Value>& args) { - bool first = true; - HandleScope handle_scope(args.GetIsolate()); - for (int i = 0; i < args.Length(); i++) { - if (first) { - first = false; - } else { - printf(" "); - } - v8::String::Utf8Value str(args[i]); - printf("%s", ToCString(str)); - } - printf("\n"); - fflush(stdout); -} - - -// Creates a new execution environment containing the built-in -// function draw(). -Handle<Context> createRootContext(Isolate* isolate) { - // Create a template for the global object. - Handle<ObjectTemplate> global = ObjectTemplate::New(); - - // This is where we would inject any globals into the root Context - // using global->Set(...) - - global->Set(v8::String::NewFromUtf8(isolate, "print"), - v8::FunctionTemplate::New(Print)); - - return Context::New(isolate, NULL, global); -} - - -// Parse and run script. Then fetch out the onDraw function from the global -// object. -bool JsCanvas::initialize(const char script[]) { +// Fetch the onDraw function from the global context. +bool JsCanvas::initialize() { // Create a stack-allocated handle scope. - HandleScope handleScope(fIsolate); + HandleScope handleScope(fGlobal->getIsolate()); - printf("Before create context\n"); - - // Create a new context. - Handle<Context> context = createRootContext(fIsolate); + // Create a local context from our global context. + Local<Context> context = fGlobal->getContext(); // Enter the scope so all operations take place in the scope. Context::Scope contextScope(context); v8::TryCatch try_catch; - // Compile the source code. - Handle<String> source = String::NewFromUtf8(fIsolate, script); - printf("Before Compile\n"); - Handle<Script> compiled_script = Script::Compile(source); - printf("After Compile\n"); - - if (compiled_script.IsEmpty()) { - // Print errors that happened during compilation. - reportException(fIsolate, &try_catch); - return false; - } - printf("After Exception.\n"); - - // Try running it now to create the onDraw function. - Handle<Value> result = compiled_script->Run(); - - // Handle any exceptions or output. - if (result.IsEmpty()) { - SkASSERT(try_catch.HasCaught()); - // Print errors that happened during execution. - reportException(fIsolate, &try_catch); - return false; - } else { - SkASSERT(!try_catch.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 = ToCString(str); - printf("%s\n", cstr); - return false; - } - } - - Handle<String> fn_name = String::NewFromUtf8(fIsolate, "onDraw"); + Handle<String> fn_name = String::NewFromUtf8( + fGlobal->getIsolate(), "onDraw"); Handle<Value> fn_val = context->Global()->Get(fn_name); if (!fn_val->IsFunction()) { @@ -393,13 +243,46 @@ bool JsCanvas::initialize(const char script[]) { // Store the function in a Persistent handle, since we also want that to // remain after this call returns. - fOnDraw.Reset(fIsolate, fn_fun); + fOnDraw.Reset(fGlobal->getIsolate(), fn_fun); - // Also make the context persistent. - fContext.Reset(fIsolate, context); return true; } + +SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, JsCanvas* canvas) + : INHERITED(hwnd) + , fJsCanvas(canvas) +{ + this->setConfig(SkBitmap::kARGB_8888_Config); + this->setVisibleP(true); + this->setClipToBounds(false); +} + +void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { + + canvas->save(); + canvas->drawColor(SK_ColorWHITE); + + // Now jump into JS and call the onDraw(canvas) method defined there. + fJsCanvas->onDraw(canvas); + + canvas->restore(); + + INHERITED::onDraw(canvas); +} + + +#ifdef SK_BUILD_FOR_WIN +void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) { + RECT winRect; + winRect.top = rect.top(); + winRect.bottom = rect.bottom(); + winRect.right = rect.right(); + winRect.left = rect.left(); + InvalidateRect((HWND)this->getHWND(), &winRect, false); +} +#endif + SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { printf("Started\n"); @@ -407,8 +290,7 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { // Get the default Isolate created at startup. Isolate* isolate = Isolate::GetCurrent(); - - JsCanvas* jsCanvas = new JsCanvas(isolate); + Global* global = new Global(isolate); const char* script = "function onDraw(canvas) { \n" @@ -426,9 +308,18 @@ SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { printf("Could not load file: %s.\n", FLAGS_infile[0]); exit(1); } - if (!jsCanvas->initialize(script)) { + + if (!global->parseScript(script)) { + exit(1); + } + + JsCanvas* jsCanvas = new JsCanvas(global); + + if (!jsCanvas->initialize()) { printf("Failed to initialize.\n"); exit(1); } - return new SkV8ExampleWindow(hwnd, jsCanvas); + SkV8ExampleWindow* win = new SkV8ExampleWindow(hwnd, jsCanvas); + global->setWindow(win); + return win; } diff --git a/experimental/SkV8Example/SkV8Example.h b/experimental/SkV8Example/SkV8Example.h index 9ed0eccb12..30737963f3 100644 --- a/experimental/SkV8Example/SkV8Example.h +++ b/experimental/SkV8Example/SkV8Example.h @@ -19,6 +19,7 @@ using namespace v8; class SkCanvas; class JsCanvas; +class Global; class SkV8ExampleWindow : public SkOSWindow { public: @@ -43,24 +44,22 @@ private: // function onDraw(canvas) { // canvas.fillStyle="#FF0000"; // canvas.fillRect(x, y, w, h); -// canvas.inval(); // } class JsCanvas { public: - JsCanvas(Isolate* isolate) - : fIsolate(isolate) + JsCanvas(Global* global) + : fGlobal(global) , fCanvas(NULL) - , fWindow(NULL) { fFillStyle.setColor(SK_ColorRED); } ~JsCanvas(); // Parse the script. - bool initialize(const char script[]); + bool initialize(); // Call this with the SkCanvas you want onDraw to draw on. - void onDraw(SkCanvas* canvas, SkOSWindow* window); + void onDraw(SkCanvas* canvas); private: // Implementation of the canvas.fillStyle field. @@ -72,9 +71,6 @@ private: // Implementation of the canvas.fillRect() JS function. static void FillRect(const v8::FunctionCallbackInfo<Value>& args); - // Implementation of the canvas.inval() JS function. - static void Inval(const v8::FunctionCallbackInfo<Value>& args); - // Get the pointer out of obj. static JsCanvas* Unwrap(Handle<Object> obj); @@ -85,19 +81,13 @@ private: // Wrap the 'this' pointer into an Object. Can be retrieved via Unwrap. Handle<Object> wrap(); - Isolate* fIsolate; + Global* fGlobal; // Only valid when inside OnDraw(). SkCanvas* fCanvas; SkPaint fFillStyle; - // Only valid when inside OnDraw(). - SkOSWindow* fWindow; - - // The context that the script will be parsed into. - Persistent<Context> fContext; - // A handle to the onDraw function defined in the script. Persistent<Function> fOnDraw; diff --git a/experimental/SkV8Example/sample.js b/experimental/SkV8Example/sample.js index 3a95e55106..b516062044 100644 --- a/experimental/SkV8Example/sample.js +++ b/experimental/SkV8Example/sample.js @@ -4,10 +4,17 @@ var onDraw = function(){ var tick = 0; function f(canvas) { - tick += 0.01; + tick += 0.1; canvas.fillStyle = '#0000ff'; canvas.fillRect(100, 100, Math.sin(tick)*100, Math.cos(tick)*100); - canvas.inval(); }; return f; }(); + +function onTimeout() { + inval(); + print("Got a timeout!"); + setTimeout(onTimeout, 33); +} + +setTimeout(onTimeout, 33); |