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

Side by Side Diff: ppapi/example/example.cc

Issue 9381010: Convert resources to take an instance key instead of an Instance*. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 10 months 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <math.h> 5 #include "ppapi/c/pp_errors.h"
6 #include <stdio.h> // FIXME(brettw) erase me. 6 #include "ppapi/cpp/input_event.h"
7 #ifndef _WIN32 7 #include "ppapi/cpp/instance.h"
8 #include <sys/time.h> 8 #include "ppapi/cpp/module.h"
9 #else 9 #include "ppapi/utility/completion_callback_factory.h"
10 #include <windows.h> 10 #include "ppapi/utility/threading/simple_thread.h"
11 #endif
12 #include <time.h>
13 11
14 #include <algorithm> 12 class MyInstance : public pp::Instance {
15
16 #include "ppapi/c/dev/ppb_console_dev.h"
17 #include "ppapi/c/dev/ppb_cursor_control_dev.h"
18 #include "ppapi/c/dev/ppp_printing_dev.h"
19 #include "ppapi/c/pp_errors.h"
20 #include "ppapi/c/pp_rect.h"
21 #include "ppapi/cpp/completion_callback.h"
22 #include "ppapi/cpp/dev/memory_dev.h"
23 #include "ppapi/cpp/dev/scriptable_object_deprecated.h"
24 #include "ppapi/cpp/graphics_2d.h"
25 #include "ppapi/cpp/image_data.h"
26 #include "ppapi/cpp/input_event.h"
27 #include "ppapi/cpp/private/instance_private.h"
28 #include "ppapi/cpp/module.h"
29 #include "ppapi/cpp/private/var_private.h"
30 #include "ppapi/cpp/rect.h"
31 #include "ppapi/cpp/url_loader.h"
32 #include "ppapi/cpp/url_request_info.h"
33 #include "ppapi/cpp/var.h"
34 #include "ppapi/utility/completion_callback_factory.h"
35
36 static const int kStepsPerCircle = 800;
37
38 void FlushCallback(void* data, int32_t result);
39
40 void FillRect(pp::ImageData* image, int left, int top, int width, int height,
41 uint32_t color) {
42 for (int y = std::max(0, top);
43 y < std::min(image->size().height() - 1, top + height);
44 y++) {
45 for (int x = std::max(0, left);
46 x < std::min(image->size().width() - 1, left + width);
47 x++)
48 *image->GetAddr32(pp::Point(x, y)) = color;
49 }
50 }
51
52 class MyScriptableObject : public pp::deprecated::ScriptableObject {
53 public: 13 public:
54 explicit MyScriptableObject(pp::InstancePrivate* instance) 14 MyInstance(PP_Instance instance) : pp::Instance(instance) {
55 : instance_(instance) {} 15 thread_ = new pp::SimpleThread(this);
56 16 factory_.Initialize(this);
57 virtual bool HasMethod(const pp::Var& method, pp::Var* exception) {
58 return method.AsString() == "toString";
59 } 17 }
60 18
61 virtual bool HasProperty(const pp::Var& name, pp::Var* exception) { 19 virtual ~MyInstance() {
62 if (name.is_string() && name.AsString() == "blah") 20 delete thread_;
63 return true;
64 return false;
65 } 21 }
66 22
67 virtual pp::Var GetProperty(const pp::Var& name, pp::Var* exception) { 23 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
68 if (name.is_string() && name.AsString() == "blah") 24 thread_->Start();
69 return pp::VarPrivate(instance_, new MyScriptableObject(instance_)); 25 thread_->message_loop().PostWork(
70 return pp::Var(); 26 factory_.NewCallback(&MyInstance::CallOnBackground));
27 return true;
71 } 28 }
72 29
73 virtual void GetAllPropertyNames(std::vector<pp::Var>* names, 30 virtual void DidChangeView(const pp::View& view) {
74 pp::Var* exception) {
75 names->push_back("blah");
76 }
77
78 virtual pp::Var Call(const pp::Var& method,
79 const std::vector<pp::Var>& args,
80 pp::Var* exception) {
81 if (method.AsString() == "toString")
82 return pp::Var("hello world");
83 return pp::Var();
84 } 31 }
85 32
86 private: 33 private:
87 pp::InstancePrivate* instance_; 34 void CallOnBackground(int32_t result) {
35 }
36
37 pp::CompletionCallbackFactory<MyInstance> factory_;
38
39 pp::SimpleThread* thread_;
dmichael (off chromium) 2012/02/21 23:38:02 I'm guessing the changes in this file weren't mean
88 }; 40 };
89 41
90 class MyFetcherClient {
91 public:
92 virtual void DidFetch(bool success, const std::string& data) = 0;
93 };
94
95 class MyFetcher {
96 public:
97 MyFetcher() : client_(NULL) {
98 callback_factory_.Initialize(this);
99 }
100
101 void Start(const pp::InstancePrivate& instance,
102 const pp::Var& url,
103 MyFetcherClient* client) {
104 pp::URLRequestInfo request;
105 request.SetURL(url);
106 request.SetMethod("GET");
107
108 loader_ = pp::URLLoader(instance);
109 client_ = client;
110
111 pp::CompletionCallback callback =
112 callback_factory_.NewOptionalCallback(&MyFetcher::DidOpen);
113 int rv = loader_.Open(request, callback);
114 if (rv != PP_OK_COMPLETIONPENDING)
115 callback.Run(rv);
116 }
117
118 void StartWithOpenedLoader(const pp::URLLoader& loader,
119 MyFetcherClient* client) {
120 loader_ = loader;
121 client_ = client;
122
123 ReadMore();
124 }
125
126 private:
127 void ReadMore() {
128 pp::CompletionCallback callback =
129 callback_factory_.NewOptionalCallback(&MyFetcher::DidRead);
130 int rv = loader_.ReadResponseBody(buf_, sizeof(buf_), callback);
131 if (rv != PP_OK_COMPLETIONPENDING)
132 callback.Run(rv);
133 }
134
135 void DidOpen(int32_t result) {
136 if (result == PP_OK) {
137 ReadMore();
138 } else {
139 DidFinish(result);
140 }
141 }
142
143 void DidRead(int32_t result) {
144 if (result > 0) {
145 data_.append(buf_, result);
146 ReadMore();
147 } else {
148 DidFinish(result);
149 }
150 }
151
152 void DidFinish(int32_t result) {
153 if (client_)
154 client_->DidFetch(result == PP_OK, data_);
155 }
156
157 pp::CompletionCallbackFactory<MyFetcher> callback_factory_;
158 pp::URLLoader loader_;
159 MyFetcherClient* client_;
160 char buf_[4096];
161 std::string data_;
162 };
163
164 class MyInstance : public pp::InstancePrivate, public MyFetcherClient {
165 public:
166 MyInstance(PP_Instance instance)
167 : pp::InstancePrivate(instance),
168 time_at_last_check_(0.0),
169 fetcher_(NULL),
170 width_(0),
171 height_(0),
172 animation_counter_(0),
173 print_settings_valid_(false),
174 showing_custom_cursor_(false) {
175 RequestInputEvents(PP_INPUTEVENT_CLASS_MOUSE);
176 }
177
178 virtual ~MyInstance() {
179 if (fetcher_) {
180 delete fetcher_;
181 fetcher_ = NULL;
182 }
183 }
184
185 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
186 return true;
187 }
188
189 void Log(PP_LogLevel_Dev level, const pp::Var& value) {
190 const PPB_Console_Dev* console = reinterpret_cast<const PPB_Console_Dev*>(
191 pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE));
192 if (!console)
193 return;
194 console->Log(pp_instance(), level, value.pp_var());
195 }
196
197 virtual bool HandleDocumentLoad(const pp::URLLoader& loader) {
198 fetcher_ = new MyFetcher();
199 fetcher_->StartWithOpenedLoader(loader, this);
200 return true;
201 }
202
203 virtual bool HandleInputEvent(const pp::InputEvent& event) {
204 switch (event.GetType()) {
205 case PP_INPUTEVENT_TYPE_MOUSEDOWN:
206 SayHello();
207 ToggleCursor();
208 return true;
209 case PP_INPUTEVENT_TYPE_MOUSEMOVE:
210 return true;
211 case PP_INPUTEVENT_TYPE_KEYDOWN:
212 return true;
213 default:
214 return false;
215 }
216 }
217
218 virtual pp::Var GetInstanceObject() {
219 return pp::VarPrivate(this, new MyScriptableObject(this));
220 }
221
222 pp::ImageData PaintImage(int width, int height) {
223 pp::ImageData image(this, PP_IMAGEDATAFORMAT_BGRA_PREMUL,
224 pp::Size(width, height), false);
225 if (image.is_null()) {
226 printf("Couldn't allocate the image data: %d, %d\n", width, height);
227 return image;
228 }
229
230 // Fill with semitransparent gradient.
231 for (int y = 0; y < image.size().height(); y++) {
232 char* row = &static_cast<char*>(image.data())[y * image.stride()];
233 for (int x = 0; x < image.size().width(); x++) {
234 row[x * 4 + 0] = y;
235 row[x * 4 + 1] = y;
236 row[x * 4 + 2] = 0;
237 row[x * 4 + 3] = y;
238 }
239 }
240
241 // Draw the orbiting box.
242 float radians = static_cast<float>(animation_counter_) / kStepsPerCircle *
243 2 * 3.14159265358979F;
244
245 float radius = static_cast<float>(std::min(width, height)) / 2.0f - 3.0f;
246 int x = static_cast<int>(cos(radians) * radius + radius + 2);
247 int y = static_cast<int>(sin(radians) * radius + radius + 2);
248
249 const uint32_t box_bgra = 0x80000000; // Alpha 50%.
250 FillRect(&image, x - 3, y - 3, 7, 7, box_bgra);
251 return image;
252 }
253
254 void Paint() {
255 pp::ImageData image = PaintImage(width_, height_);
256 if (!image.is_null()) {
257 device_context_.ReplaceContents(&image);
258 device_context_.Flush(pp::CompletionCallback(&FlushCallback, this));
259 } else {
260 printf("NullImage: %d, %d\n", width_, height_);
261 }
262 }
263
264 virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
265 Log(PP_LOGLEVEL_LOG, "DidChangeView");
266 if (position.size().width() == width_ &&
267 position.size().height() == height_)
268 return; // We don't care about the position, only the size.
269
270 width_ = position.size().width();
271 height_ = position.size().height();
272 printf("DidChangeView relevant change: width=%d height:%d\n",
273 width_, height_);
274
275 device_context_ = pp::Graphics2D(this, pp::Size(width_, height_), false);
276 if (!BindGraphics(device_context_)) {
277 printf("Couldn't bind the device context\n");
278 return;
279 }
280
281 Paint();
282 }
283
284 #if defined(_WIN32)
285 struct timeval {
286 long tv_sec;
287 long tv_usec;
288 };
289
290 struct timezone {
291 long x;
292 long y;
293 };
294
295 #define EPOCHFILETIME (116444736000000000i64)
296
297 int gettimeofday(struct timeval *tv, struct timezone*) {
298 FILETIME ft;
299 ::GetSystemTimeAsFileTime(&ft);
300 LARGE_INTEGER li = {ft.dwLowDateTime, ft.dwHighDateTime};
301 __int64 t = li.QuadPart - EPOCHFILETIME;
302 tv->tv_sec = static_cast<long>(t / 10000000);
303 tv->tv_usec = static_cast<long>(t % 10000000);
304 return 0;
305 }
306 #endif // if defined(_WIN32)
307
308 void UpdateFps() {
309 pp::VarPrivate window = GetWindowObject();
310 if (window.is_undefined())
311 return;
312 pp::VarPrivate doc = window.GetProperty("document");
313 pp::VarPrivate fps = doc.Call("getElementById", "fps");
314
315 struct timeval tv;
316 struct timezone tz = {0, 0};
317 gettimeofday(&tv, &tz);
318
319 double time_now = tv.tv_sec + tv.tv_usec / 1000000.0;
320
321 if (animation_counter_ > 0) {
322 char fps_text[64];
323 sprintf(fps_text, "%g fps",
324 kStepsPerCircle / (time_now - time_at_last_check_));
325 fps.SetProperty("innerHTML", fps_text);
326 }
327
328 time_at_last_check_ = time_now;
329 }
330
331 // Print interfaces.
332 // TODO(mball,dmichael) Replace this with the PPP_PRINTING_DEV_USE_0_4 version
333 virtual PP_PrintOutputFormat_Dev* QuerySupportedPrintOutputFormats(
334 uint32_t* format_count) {
335 pp::Memory_Dev memory;
336 PP_PrintOutputFormat_Dev* format =
337 static_cast<PP_PrintOutputFormat_Dev*>(
338 memory.MemAlloc(sizeof(PP_PrintOutputFormat_Dev)));
339 *format = PP_PRINTOUTPUTFORMAT_RASTER;
340 *format_count = 1;
341 return format;
342 }
343
344 virtual int32_t PrintBegin(const PP_PrintSettings_Dev& print_settings) {
345 if (print_settings_.format != PP_PRINTOUTPUTFORMAT_RASTER)
346 return 0;
347
348 print_settings_ = print_settings;
349 print_settings_valid_ = true;
350 return 1;
351 }
352
353 virtual pp::Resource PrintPages(
354 const PP_PrintPageNumberRange_Dev* page_ranges,
355 uint32_t page_range_count) {
356 if (!print_settings_valid_)
357 return pp::Resource();
358
359 if (page_range_count != 1)
360 return pp::Resource();
361
362 // Check if the page numbers are valid. We returned 1 in PrintBegin so we
363 // only have 1 page to print.
364 if (page_ranges[0].first_page_number || page_ranges[0].last_page_number) {
365 return pp::Resource();
366 }
367
368 int width = static_cast<int>(
369 (print_settings_.printable_area.size.width / 72.0) *
370 print_settings_.dpi);
371 int height = static_cast<int>(
372 (print_settings_.printable_area.size.height / 72.0) *
373 print_settings_.dpi);
374
375 return PaintImage(width, height);
376 }
377
378 virtual void PrintEnd() {
379 print_settings_valid_ = false;
380 }
381
382 void OnFlush() {
383 if (animation_counter_ % kStepsPerCircle == 0)
384 UpdateFps();
385 animation_counter_++;
386 Paint();
387 }
388
389 private:
390 void SayHello() {
391 pp::VarPrivate window = GetWindowObject();
392 pp::VarPrivate doc = window.GetProperty("document");
393 pp::VarPrivate body = doc.GetProperty("body");
394
395 pp::VarPrivate obj(this, new MyScriptableObject(this));
396
397 // Our object should have its toString method called.
398 Log(PP_LOGLEVEL_LOG, "Testing MyScriptableObject::toString():");
399 Log(PP_LOGLEVEL_LOG, obj);
400
401 // body.appendChild(body) should throw an exception
402 Log(PP_LOGLEVEL_LOG, "Calling body.appendChild(body):");
403 pp::Var exception;
404 body.Call("appendChild", body, &exception);
405 Log(PP_LOGLEVEL_LOG, exception);
406
407 Log(PP_LOGLEVEL_LOG, "Enumeration of window properties:");
408 std::vector<pp::Var> props;
409 window.GetAllPropertyNames(&props);
410 for (size_t i = 0; i < props.size(); ++i)
411 Log(PP_LOGLEVEL_LOG, props[i]);
412
413 pp::VarPrivate location = window.GetProperty("location");
414 pp::VarPrivate href = location.GetProperty("href");
415
416 if (!fetcher_) {
417 fetcher_ = new MyFetcher();
418 fetcher_->Start(*this, href, this);
419 }
420 }
421
422 void DidFetch(bool success, const std::string& data) {
423 Log(PP_LOGLEVEL_LOG, "Downloaded location.href:");
424 if (success) {
425 Log(PP_LOGLEVEL_LOG, data);
426 } else {
427 Log(PP_LOGLEVEL_ERROR, "Failed to download.");
428 }
429 delete fetcher_;
430 fetcher_ = NULL;
431 }
432
433 void ToggleCursor() {
434 const PPB_CursorControl_Dev* cursor_control =
435 reinterpret_cast<const PPB_CursorControl_Dev*>(
436 pp::Module::Get()->GetBrowserInterface(
437 PPB_CURSOR_CONTROL_DEV_INTERFACE));
438 if (!cursor_control)
439 return;
440
441 if (showing_custom_cursor_) {
442 cursor_control->SetCursor(pp_instance(), PP_CURSORTYPE_POINTER, 0, NULL);
443 } else {
444 pp::ImageData image_data(this, pp::ImageData::GetNativeImageDataFormat(),
445 pp::Size(50, 50), false);
446 FillRect(&image_data, 0, 0, 50, 50,
447 image_data.format() == PP_IMAGEDATAFORMAT_BGRA_PREMUL ?
448 0x80800000 : 0x80000080);
449 pp::Point hot_spot(0, 0);
450 cursor_control->SetCursor(pp_instance(), PP_CURSORTYPE_CUSTOM,
451 image_data.pp_resource(), &hot_spot.pp_point());
452 }
453
454 showing_custom_cursor_ = !showing_custom_cursor_;
455 }
456
457 pp::Var console_;
458 pp::Graphics2D device_context_;
459
460 double time_at_last_check_;
461
462 MyFetcher* fetcher_;
463
464 int width_;
465 int height_;
466
467 // Incremented for each flush we get.
468 int animation_counter_;
469 bool print_settings_valid_;
470 PP_PrintSettings_Dev print_settings_;
471
472 bool showing_custom_cursor_;
473 };
474
475 void FlushCallback(void* data, int32_t result) {
476 static_cast<MyInstance*>(data)->OnFlush();
477 }
478 42
479 class MyModule : public pp::Module { 43 class MyModule : public pp::Module {
480 public: 44 public:
481 MyModule() : pp::Module() {} 45 MyModule() : pp::Module() {}
482 virtual ~MyModule() {} 46 virtual ~MyModule() {}
483 47
484 virtual pp::Instance* CreateInstance(PP_Instance instance) { 48 virtual pp::Instance* CreateInstance(PP_Instance instance) {
485 return new MyInstance(instance); 49 return new MyInstance(instance);
486 } 50 }
487 }; 51 };
488 52
489 namespace pp { 53 namespace pp {
490 54
491 // Factory function for your specialization of the Module object. 55 // Factory function for your specialization of the Module object.
492 Module* CreateModule() { 56 Module* CreateModule() {
493 return new MyModule(); 57 return new MyModule();
494 } 58 }
495 59
496 } // namespace pp 60 } // namespace pp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698