OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 * | 7 * |
8 */ | 8 */ |
9 #include <v8.h> | 9 #include <v8.h> |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 void application_init() { | 24 void application_init() { |
25 SkGraphics::Init(); | 25 SkGraphics::Init(); |
26 SkEvent::Init(); | 26 SkEvent::Init(); |
27 } | 27 } |
28 | 28 |
29 void application_term() { | 29 void application_term() { |
30 SkEvent::Term(); | 30 SkEvent::Term(); |
31 SkGraphics::Term(); | 31 SkGraphics::Term(); |
32 } | 32 } |
33 | 33 |
34 SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd) | 34 // Extracts a C string from a V8 Utf8Value. |
35 : INHERITED(hwnd) { | 35 const char* ToCString(const v8::String::Utf8Value& value) { |
| 36 return *value ? *value : "<string conversion failed>"; |
| 37 } |
36 | 38 |
| 39 // Slight modification to an original function found in the V8 sample shell.cc. |
| 40 void reportException(Isolate* isolate, TryCatch* try_catch) { |
| 41 HandleScope handle_scope(isolate); |
| 42 String::Utf8Value exception(try_catch->Exception()); |
| 43 const char* exception_string = ToCString(exception); |
| 44 Handle<Message> message = try_catch->Message(); |
| 45 if (message.IsEmpty()) { |
| 46 // V8 didn't provide any extra information about this error; just |
| 47 // print the exception. |
| 48 fprintf(stderr, "%s\n", exception_string); |
| 49 } else { |
| 50 // Print (filename):(line number): (message). |
| 51 String::Utf8Value filename(message->GetScriptResourceName()); |
| 52 const char* filename_string = ToCString(filename); |
| 53 int linenum = message->GetLineNumber(); |
| 54 fprintf(stderr, "%s:%i: %s\n", filename_string, linenum, exception_string); |
| 55 // Print line of source code. |
| 56 String::Utf8Value sourceline(message->GetSourceLine()); |
| 57 const char* sourceline_string = ToCString(sourceline); |
| 58 fprintf(stderr, "%s\n", sourceline_string); |
| 59 // Print wavy underline. |
| 60 int start = message->GetStartColumn(); |
| 61 for (int i = 0; i < start; i++) { |
| 62 fprintf(stderr, " "); |
| 63 } |
| 64 int end = message->GetEndColumn(); |
| 65 for (int i = start; i < end; i++) { |
| 66 fprintf(stderr, "^"); |
| 67 } |
| 68 fprintf(stderr, "\n"); |
| 69 String::Utf8Value stack_trace(try_catch->StackTrace()); |
| 70 if (stack_trace.length() > 0) { |
| 71 const char* stack_trace_string = ToCString(stack_trace); |
| 72 fprintf(stderr, "%s\n", stack_trace_string); |
| 73 } |
| 74 } |
| 75 } |
| 76 |
| 77 SkV8ExampleWindow::SkV8ExampleWindow(void* hwnd, |
| 78 Isolate* isolate, |
| 79 Handle<Context> context, |
| 80 Handle<Script> script) |
| 81 : INHERITED(hwnd) |
| 82 , fIsolate(isolate) |
| 83 { |
| 84 // Convert the Handle<> objects into Persistent<> objects using Reset(). |
| 85 fContext.Reset(isolate, context); |
| 86 fScript.Reset(isolate, script); |
| 87 |
| 88 fRotationAngle = SkIntToScalar(0); |
37 this->setConfig(SkBitmap::kARGB_8888_Config); | 89 this->setConfig(SkBitmap::kARGB_8888_Config); |
38 this->setVisibleP(true); | 90 this->setVisibleP(true); |
39 this->setClipToBounds(false); | 91 this->setClipToBounds(false); |
40 } | 92 } |
41 | 93 |
| 94 // Simple global for the Draw function. |
| 95 SkCanvas* gCanvas = NULL; |
42 | 96 |
43 void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { | |
44 printf("Draw\n"); | |
45 | 97 |
46 canvas->drawColor(SK_ColorWHITE); | 98 // Draw is called from within V8 when the Javascript function draw() is called. |
| 99 void Draw(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 100 if (NULL == gCanvas) { |
| 101 printf("Can't Draw Now.\n"); |
| 102 return; |
| 103 } |
| 104 |
| 105 gCanvas->drawColor(SK_ColorWHITE); |
47 SkPaint paint; | 106 SkPaint paint; |
48 paint.setColor(SK_ColorRED); | 107 paint.setColor(SK_ColorRED); |
49 | 108 |
50 // Draw a rectangle with blue paint | 109 // Draw a rectangle with blue paint |
51 SkRect rect = { | 110 SkRect rect = { |
52 SkIntToScalar(10), SkIntToScalar(10), | 111 SkIntToScalar(10), SkIntToScalar(10), |
53 SkIntToScalar(128), SkIntToScalar(128) | 112 SkIntToScalar(128), SkIntToScalar(128) |
54 }; | 113 }; |
55 canvas->drawRect(rect, paint); | 114 gCanvas->drawRect(rect, paint); |
| 115 } |
| 116 |
| 117 void SkV8ExampleWindow::onDraw(SkCanvas* canvas) { |
| 118 printf("Draw\n"); |
| 119 |
| 120 gCanvas = canvas; |
| 121 canvas->save(); |
| 122 fRotationAngle += SkDoubleToScalar(0.2); |
| 123 if (fRotationAngle > SkDoubleToScalar(360.0)) { |
| 124 fRotationAngle -= SkDoubleToScalar(360.0); |
| 125 } |
| 126 canvas->rotate(fRotationAngle); |
| 127 |
| 128 // Create a Handle scope for temporary references. |
| 129 HandleScope handle_scope(fIsolate); |
| 130 |
| 131 // Create a local context from our persistent context. |
| 132 Local<Context> context = |
| 133 Local<Context>::New(fIsolate, fContext); |
| 134 |
| 135 // Enter the context so all operations take place within it. |
| 136 Context::Scope context_scope(context); |
| 137 |
| 138 TryCatch try_catch; |
| 139 |
| 140 // Create a local script from our persistent script. |
| 141 Local<Script> script = |
| 142 Local<Script>::New(fIsolate, fScript); |
| 143 |
| 144 // Run the script. |
| 145 Handle<Value> result = script->Run(); |
| 146 |
| 147 if (result.IsEmpty()) { |
| 148 SkASSERT(try_catch.HasCaught()); |
| 149 // Print errors that happened during execution. |
| 150 reportException(fIsolate, &try_catch); |
| 151 } else { |
| 152 SkASSERT(!try_catch.HasCaught()); |
| 153 if (!result->IsUndefined()) { |
| 154 // If all went well and the result wasn't undefined then print |
| 155 // the returned value. |
| 156 String::Utf8Value str(result); |
| 157 const char* cstr = ToCString(str); |
| 158 printf("%s\n", cstr); |
| 159 } |
| 160 } |
| 161 |
| 162 canvas->restore(); |
| 163 |
| 164 // Trigger an invalidation which should trigger another redraw to simulate |
| 165 // animation. |
| 166 this->inval(NULL); |
56 | 167 |
57 INHERITED::onDraw(canvas); | 168 INHERITED::onDraw(canvas); |
58 } | 169 } |
59 | 170 |
| 171 |
60 #ifdef SK_BUILD_FOR_WIN | 172 #ifdef SK_BUILD_FOR_WIN |
61 void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) { | 173 void SkV8ExampleWindow::onHandleInval(const SkIRect& rect) { |
62 RECT winRect; | 174 RECT winRect; |
63 winRect.top = rect.top(); | 175 winRect.top = rect.top(); |
64 winRect.bottom = rect.bottom(); | 176 winRect.bottom = rect.bottom(); |
65 winRect.right = rect.right(); | 177 winRect.right = rect.right(); |
66 winRect.left = rect.left(); | 178 winRect.left = rect.left(); |
67 InvalidateRect((HWND)this->getHWND(), &winRect, false); | 179 InvalidateRect((HWND)this->getHWND(), &winRect, false); |
68 } | 180 } |
69 #endif | 181 #endif |
70 | 182 |
| 183 // Creates a new execution environment containing the built-in |
| 184 // function draw(). |
| 185 Handle<Context> createRootContext(Isolate* isolate) { |
| 186 // Create a template for the global object. |
| 187 Handle<ObjectTemplate> global = ObjectTemplate::New(); |
| 188 // Bind the global 'draw' function to the C++ Draw callback. |
| 189 global->Set(String::NewFromUtf8(isolate, "draw"), |
| 190 FunctionTemplate::New(Draw)); |
| 191 |
| 192 return Context::New(isolate, NULL, global); |
| 193 } |
71 | 194 |
72 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { | 195 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { |
73 printf("Started\n"); | 196 printf("Started\n"); |
74 | 197 |
75 // Get the default Isolate created at startup. | 198 // Get the default Isolate created at startup. |
76 Isolate* isolate = Isolate::GetCurrent(); | 199 Isolate* isolate = Isolate::GetCurrent(); |
| 200 printf("Isolate\n"); |
77 | 201 |
78 // Create a stack-allocated handle scope. | 202 // Create a stack-allocated handle scope. |
79 HandleScope handle_scope(isolate); | 203 HandleScope handle_scope(isolate); |
80 | 204 |
| 205 printf("Before create context\n"); |
81 // Create a new context. | 206 // Create a new context. |
82 Handle<Context> context = Context::New(isolate); | 207 // |
| 208 Handle<Context> context = createRootContext(isolate); |
83 | 209 |
84 // Here's how you could create a Persistent handle to the context, if needed. | 210 // Enter the scope so all operations take place in the scope. |
85 Persistent<Context> persistent_context(isolate, context); | |
86 | |
87 // Enter the created context for compiling and | |
88 // running the hello world script. | |
89 Context::Scope context_scope(context); | 211 Context::Scope context_scope(context); |
90 | 212 |
91 // Create a string containing the JavaScript source code. | 213 v8::TryCatch try_catch; |
92 Handle<String> source = String::New("'Hello' + ', World!'"); | |
93 | 214 |
94 // Compile the source code. | 215 // Compile the source code. |
| 216 Handle<String> source = String::NewFromUtf8(isolate, "draw();"); |
| 217 printf("Before Compile\n"); |
95 Handle<Script> script = Script::Compile(source); | 218 Handle<Script> script = Script::Compile(source); |
| 219 printf("After Compile\n"); |
96 | 220 |
97 // Run the script to get the result. | 221 // Try running it now. It won't have a valid context, but shouldn't fail. |
98 Handle<Value> result = script->Run(); | 222 script->Run(); |
99 | 223 |
100 // The persistent handle needs to be eventually disposed. | 224 if (script.IsEmpty()) { |
101 persistent_context.Dispose(); | 225 // Print errors that happened during compilation. |
| 226 reportException(isolate, &try_catch); |
| 227 exit(1); |
| 228 } |
| 229 printf("After Exception.\n"); |
102 | 230 |
103 // Convert the result to an ASCII string and print it. | 231 // SkV8ExampleWindow will make persistent handles to hold the context and scri
pt. |
104 String::AsciiValue ascii(result); | 232 return new SkV8ExampleWindow(hwnd, isolate, context, script); |
105 printf("%s\n", *ascii); | |
106 | |
107 return new SkV8ExampleWindow(hwnd); | |
108 } | 233 } |
OLD | NEW |