Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Unified Diff: experimental/SkV8Example/Global.cpp

Issue 103143009: Add a setTimer() function. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: spacing Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: experimental/SkV8Example/Global.cpp
diff --git a/experimental/SkV8Example/Global.cpp b/experimental/SkV8Example/Global.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..265f4413c98acb25ac96044569696d494cfb05c7
--- /dev/null
+++ b/experimental/SkV8Example/Global.cpp
@@ -0,0 +1,224 @@
+#include "Global.h"
robertphillips 2013/12/17 23:35:53 Header!
jcgregorio 2013/12/18 04:32:53 Done.
+
+#include "SkWindow.h"
+#include "SkEvent.h"
+
+
+Global* Global::gGlobal = NULL;
+
+// Extracts a C string from a V8 Utf8Value.
robertphillips 2013/12/17 23:35:53 to_cstring?
jcgregorio 2013/12/18 04:32:53 Done.
+static const char* ToCString(const v8::String::Utf8Value& value) {
+ return *value ? *value : "<string conversion failed>";
+}
+
+// Slight modification to an original function found in the V8 sample shell.cc.
robertphillips 2013/12/17 23:35:53 tryCatch?
jcgregorio 2013/12/18 04:32:53 Done.
+void Global::reportException(TryCatch* try_catch) {
+ HandleScope handleScope(fIsolate);
+ String::Utf8Value exception(try_catch->Exception());
robertphillips 2013/12/17 23:35:53 exceptionString?
jcgregorio 2013/12/18 04:32:53 Done.
+ 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());
robertphillips 2013/12/17 23:35:53 filenameString?
jcgregorio 2013/12/18 04:32:53 Done.
+ 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());
robertphillips 2013/12/17 23:35:53 sourceLineString?
jcgregorio 2013/12/18 04:32:53 Done.
+ 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) {
robertphillips 2013/12/17 23:35:53 stackTraceString?
jcgregorio 2013/12/18 04:32:53 Done.
+ const char* stack_trace_string = ToCString(stack_trace);
+ fprintf(stderr, "%s\n", stack_trace_string);
+ }
+ }
+}
+
+// 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;
robertphillips 2013/12/17 23:35:53 handleScope?
jcgregorio 2013/12/18 04:32:53 Done.
+ 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);
+}
+
+// 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;
+ }
robertphillips 2013/12/17 23:35:53 timeoutFn?
jcgregorio 2013/12/18 04:32:53 Done.
+ Handle<Function> timeout_fn = Handle<Function>::Cast(args[0]);
+ gGlobal->fTimeout.Reset(args.GetIsolate(), timeout_fn);
+
+ 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 = ToCString(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);
+
robertphillips 2013/12/17 23:35:53 tryCatch?
jcgregorio 2013/12/18 04:32:53 Done.
+ v8::TryCatch try_catch;
+
+ // Compile the source code.
+ Handle<String> source = String::NewFromUtf8(fIsolate, script);
+ printf("Before Compile\n");
robertphillips 2013/12/17 23:35:53 compiledScript?
jcgregorio 2013/12/18 04:32:53 Done.
+ Handle<Script> compiled_script = Script::Compile(source);
+ printf("After Compile\n");
+
+ if (compiled_script.IsEmpty()) {
+ // Print errors that happened during compilation.
+ this->reportException(&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.
+ this->reportException(&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;
+ }
+ }
+
+ // Also make the context persistent.
+ fContext.Reset(fIsolate, context);
+ return true;
+}

Powered by Google App Engine
This is Rietveld 408576698