| Index: examples/graphics/life/life.cc
|
| ===================================================================
|
| --- examples/graphics/life/life.cc (revision 158)
|
| +++ examples/graphics/life/life.cc (working copy)
|
| @@ -1,178 +1,91 @@
|
| -// Copyright 2010 The Native Client SDK Authors. All rights reserved.
|
| +// Copyright 2011 The Native Client SDK Authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can
|
| // be found in the LICENSE file.
|
|
|
| -#include <assert.h>
|
| -#include <math.h>
|
| -#include <stdlib.h>
|
| -#include <string.h>
|
| +#include "examples/graphics/life/life.h"
|
|
|
| +#include <ppapi/cpp/completion_callback.h>
|
| +#include <ppapi/cpp/var.h>
|
| +
|
| #include <algorithm>
|
| +#include <cassert>
|
| +#include <cmath>
|
| +#include <cstdio>
|
| +#include <cstring>
|
| #include <string>
|
|
|
| -#include <nacl/nacl_npapi.h>
|
| -#include <nacl/npapi_extensions.h>
|
| -#include <nacl/npupp.h>
|
| -
|
| -#define JS_LOG(msg) \
|
| - const size_t line_number = __LINE__; \
|
| - size_t len = floor(line_number) + 1; \
|
| - len = std::string(msg).size() + strlen(__FILE__) + len + 5; \
|
| - char buffer[len]; \
|
| - memset(buffer, 0, len); \
|
| - snprintf(buffer, len, "%s:%i - ", __FILE__, line_number); \
|
| - strncat(buffer, std::string(msg).c_str(), len - strlen(buffer)); \
|
| - Log(npp_, buffer);
|
| -
|
| namespace {
|
| -// Log given message to javascript console.
|
| -bool Log(NPP npp, const char* msg, ...) {
|
| - bool rv = false;
|
| - NPObject* window = NULL;
|
| - if (NPERR_NO_ERROR == NPN_GetValue(npp, NPNVWindowNPObject, &window)) {
|
| - const char buffer[] = "top.console";
|
| - NPString console_stript = { 0 };
|
| - console_stript.UTF8Length = strlen(buffer);
|
| - console_stript.UTF8Characters = buffer;
|
| - NPVariant console;
|
| - if (NPN_Evaluate(npp, window, &console_stript, &console)) {
|
| - if (NPVARIANT_IS_OBJECT(console)) {
|
| - // Convert the message to NPString;
|
| - NPVariant text;
|
| - STRINGN_TO_NPVARIANT(msg, static_cast<uint32_t>(strlen(msg)),
|
| - text);
|
| - NPVariant result;
|
| - if (NPN_Invoke(npp, NPVARIANT_TO_OBJECT(console),
|
| - NPN_GetStringIdentifier("log"), &text, 1, &result)) {
|
| - NPN_ReleaseVariantValue(&result);
|
| - rv = true;
|
| - }
|
| - }
|
| - NPN_ReleaseVariantValue(&console);
|
| - }
|
| - }
|
| - return rv;
|
| -}
|
| +const char* const kUpdateMethodId = "update";
|
| +const char* const kAddCellAtPointMethodId = "addCellAtPoint";
|
| +const unsigned int kInitialRandSeed = 0xC0DE533D;
|
|
|
| -// seed for rand_r() - we only call rand_r from main thread.
|
| -static unsigned int gSeed = 0xC0DE533D;
|
| -
|
| -// random number helper
|
| -// binary rand() returns 0 or 1
|
| -inline unsigned char brand() {
|
| - return static_cast<unsigned char>(rand_r(&gSeed) & 1);
|
| -}
|
| -
|
| inline uint32_t MakeRGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a) {
|
| return (((a) << 24) | ((r) << 16) | ((g) << 8) | (b));
|
| }
|
|
|
| -void FlushCallback(NPP instance, NPDeviceContext* context,
|
| - NPError err, void* user_data) {
|
| -}
|
| +// Map of neighboring colors.
|
| +const uint32_t kNeighborColors[] = {
|
| + MakeRGBA(0x00, 0x00, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x40, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x60, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x80, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xA0, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xC0, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xE0, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x00, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x40, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x60, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0x80, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xA0, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xC0, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xE0, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| + MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| +};
|
|
|
| -void* life(void* data);
|
| +// These represent the new health value of a cell based on its neighboring
|
| +// values. The health is binary: either alive or dead.
|
| +const uint8_t kIsAlive[] = {
|
| + 0, 0, 0, 1, 0, 0, 0, 0, 0, // Values if the center cell is dead.
|
| + 0, 0, 1, 1, 0, 0, 0, 0, 0 // Values if the center cell is alive.
|
| + };
|
|
|
| -// Life class holds information and functionality needed to render
|
| -// life into an Pepper 2D surface.
|
| -class Life : public NPObject {
|
| - public:
|
| - Life(NPP npp);
|
| - ~Life();
|
| - NPError SetWindow(NPWindow* window);
|
| - void Update();
|
| - void Plot(int x, int y);
|
| - void Stir();
|
| - void Draw();
|
| - void UpdateCells();
|
| - void Swap();
|
| - void HandleEvent(NPPepperEvent* event);
|
| +void FlushCallback(void* data, int32_t result) {
|
| + static_cast<life::Life*>(data)->set_flush_pending(false);
|
| +}
|
| +} // namespace
|
|
|
| - private:
|
| - void CreateContext();
|
| - void DestroyContext();
|
| - bool IsContextValid() {
|
| - return context2d_.region != NULL;
|
| - }
|
| - int width() const {
|
| - return width_;
|
| - }
|
| - int height() const {
|
| - return height_;
|
| - }
|
| - void* pixels() {
|
| - return context2d_.region;
|
| - }
|
| -
|
| - NPP npp_;
|
| - NPExtensions* extensions_;
|
| - int width_, height_;
|
| - NPDevice* device2d_; // The PINPAPI 2D device.
|
| - NPDeviceContext2D context2d_; // The PINPAPI 2D drawing context.
|
| - bool scribble_;
|
| - bool quit_;
|
| - char *cell_in_;
|
| - char *cell_out_;
|
| -};
|
| -
|
| -Life::Life(NPP npp) : npp_(npp), extensions_(NULL), width_(0), height_(0),
|
| - device2d_(NULL), cell_in_(NULL), cell_out_(NULL) {
|
| - memset(&context2d_, 0, sizeof(context2d_));
|
| - NPN_GetValue(npp_, NPNVPepperExtensions, &extensions_);
|
| - device2d_ = extensions_->acquireDevice(npp_, NPPepper2DDevice);
|
| - assert(extensions_);
|
| +namespace life {
|
| +Life::Life(PP_Instance instance) : pp::Instance(instance),
|
| + graphics_2d_context_(NULL),
|
| + pixel_buffer_(NULL),
|
| + random_bits_(kInitialRandSeed),
|
| + flush_pending_(false),
|
| + cell_in_(NULL),
|
| + cell_out_(NULL) {
|
| }
|
|
|
| Life::~Life() {
|
| delete[] cell_in_;
|
| delete[] cell_out_;
|
| DestroyContext();
|
| + delete pixel_buffer_;
|
| }
|
|
|
| -void Life::CreateContext() {
|
| - if (IsContextValid())
|
| - return;
|
| - device2d_ = extensions_->acquireDevice(npp_, NPPepper2DDevice);
|
| - assert(device2d_);
|
| - NPDeviceContext2DConfig config;
|
| - NPError init_err = device2d_->initializeContext(npp_, &config, &context2d_);
|
| - assert(NPERR_NO_ERROR == init_err);
|
| +pp::Var Life::GetInstanceObject() {
|
| + LifeScriptObject* script_object = new LifeScriptObject(this);
|
| + return pp::Var(this, script_object);
|
| }
|
|
|
| -void Life::HandleEvent(NPPepperEvent* event) {
|
| - bool plot = false;
|
| - if (event->type == NPEventType_MouseDown) {
|
| - scribble_ = true;
|
| - plot = true;
|
| - }
|
| - if (event->type == NPEventType_MouseUp) {
|
| - JS_LOG("MouseUp event");
|
| - scribble_ = false;
|
| - }
|
| - if (event->type == NPEventType_MouseMove) {
|
| - plot = scribble_;
|
| - }
|
| - if (plot) {
|
| - // place a blob of life
|
| - Plot(event->u.mouse.x - 1, event->u.mouse.y - 1);
|
| - Plot(event->u.mouse.x + 0, event->u.mouse.y - 1);
|
| - Plot(event->u.mouse.x + 1, event->u.mouse.y - 1);
|
| - Plot(event->u.mouse.x - 1, event->u.mouse.y + 0);
|
| - Plot(event->u.mouse.x + 0, event->u.mouse.y + 0);
|
| - Plot(event->u.mouse.x + 1, event->u.mouse.y + 0);
|
| - Plot(event->u.mouse.x - 1, event->u.mouse.y + 1);
|
| - Plot(event->u.mouse.x + 0, event->u.mouse.y + 1);
|
| - Plot(event->u.mouse.x + 1, event->u.mouse.y + 1);
|
| - }
|
| +bool Life::Init(uint32_t argc, const char* argn[], const char* argv[]) {
|
| + return true;
|
| }
|
|
|
| -void Life::DestroyContext() {
|
| - if (!IsContextValid())
|
| - return;
|
| - device2d_->destroyContext(npp_, &context2d_);
|
| -}
|
| -
|
| void Life::Plot(int x, int y) {
|
| + if (cell_in_ == NULL)
|
| + return;
|
| if (x < 0) return;
|
| if (x >= width()) return;
|
| if (y < 0) return;
|
| @@ -180,283 +93,168 @@
|
| *(cell_in_ + x + y * width()) = 1;
|
| }
|
|
|
| -NPError Life::SetWindow(NPWindow* window) {
|
| - if (!window)
|
| - return NPERR_NO_ERROR;
|
| - width_ = window->width;
|
| - height_ = window->height;
|
| - if (!IsContextValid())
|
| - CreateContext();
|
| +void Life::DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
|
| + if (position.size().width() == width() &&
|
| + position.size().height() == height())
|
| + return; // Size didn't change, no need to update anything.
|
|
|
| - const size_t size = width() * height();
|
| + // Create a new device context with the new size.
|
| + DestroyContext();
|
| + CreateContext(position.size());
|
| + // Delete the old pixel buffer and create a new one.
|
| + delete pixel_buffer_;
|
| delete[] cell_in_;
|
| delete[] cell_out_;
|
| - cell_in_ = new char[size];
|
| - cell_out_ = new char[size];
|
| - std::fill(cell_in_, cell_in_ + size, 0);
|
| - std::fill(cell_out_, cell_out_ + size, 0);
|
| -
|
| - NPDeviceFlushContextCallbackPtr callback =
|
| - reinterpret_cast<NPDeviceFlushContextCallbackPtr>(&FlushCallback);
|
| - device2d_->flushContext(npp_, &context2d_, callback, NULL);
|
| - return NPERR_NO_ERROR;
|
| + pixel_buffer_ = NULL;
|
| + cell_in_ = cell_out_ = NULL;
|
| + if (graphics_2d_context_ != NULL) {
|
| + pixel_buffer_ = new pp::ImageData(this,
|
| + PP_IMAGEDATAFORMAT_BGRA_PREMUL,
|
| + graphics_2d_context_->size(),
|
| + false);
|
| + const size_t size = width() * height();
|
| + cell_in_ = new uint8_t[size];
|
| + cell_out_ = new uint8_t[size];
|
| + std::fill(cell_in_, cell_in_ + size, 0);
|
| + std::fill(cell_out_, cell_out_ + size, 0);
|
| + }
|
| }
|
|
|
| void Life::Update() {
|
| Stir();
|
| UpdateCells();
|
| Swap();
|
| - NPDeviceFlushContextCallbackPtr callback =
|
| - reinterpret_cast<NPDeviceFlushContextCallbackPtr>(&FlushCallback);
|
| - device2d_->flushContext(npp_, &context2d_, callback, NULL);
|
| + FlushPixelBuffer();
|
| }
|
|
|
| +void Life::AddCellAtPoint(const pp::Var& var_x, const pp::Var& var_y) {
|
| + if (!var_x.is_number() || !var_y.is_number())
|
| + return;
|
| + int32_t x, y;
|
| + x = var_x.is_int() ? var_x.AsInt() : static_cast<int32_t>(var_x.AsDouble());
|
| + y = var_y.is_int() ? var_y.AsInt() : static_cast<int32_t>(var_y.AsDouble());
|
| + Plot(x - 1, y - 1);
|
| + Plot(x + 0, y - 1);
|
| + Plot(x + 1, y - 1);
|
| + Plot(x - 1, y + 0);
|
| + Plot(x + 0, y + 0);
|
| + Plot(x + 1, y + 0);
|
| + Plot(x - 1, y + 1);
|
| + Plot(x + 0, y + 1);
|
| + Plot(x + 1, y + 1);
|
| +}
|
| +
|
| void Life::Stir() {
|
| + if (cell_in_ == NULL || cell_out_ == NULL)
|
| + return;
|
| const int height = this->height();
|
| const int width = this->width();
|
| for (int i = 0; i < width; ++i) {
|
| - cell_in_[i] = brand();
|
| - cell_in_[i + (height - 1) * width] = brand();
|
| + cell_in_[i] = random_bits_.value();
|
| + cell_in_[i + (height - 1) * width] = random_bits_.value();
|
| }
|
| for (int i = 0; i < height; ++i) {
|
| - cell_in_[i * width] = brand();
|
| - cell_in_[i * width + (width - 2)] = brand();
|
| + cell_in_[i * width] = random_bits_.value();
|
| + cell_in_[i * width + (width - 1)] = random_bits_.value();
|
| }
|
| }
|
|
|
| void Life::UpdateCells() {
|
| - // map neighbor count to color
|
| - static unsigned int colors[18] = {
|
| - MakeRGBA(0x00, 0x00, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x40, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x60, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x80, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xA0, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xC0, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xE0, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x00, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x40, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x60, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0x80, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xA0, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xC0, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xE0, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| - MakeRGBA(0x00, 0xFF, 0x00, 0xff),
|
| - };
|
| - // map neighbor count to alive/dead
|
| - static char replace[18] = {
|
| - 0, 0, 0, 1, 0, 0, 0, 0, // row for center cell dead
|
| - 0, 0, 1, 1, 0, 0, 0, 0, // row for center cell alive
|
| - };
|
| + if (cell_in_ == NULL || cell_out_ == NULL || pixels() == NULL)
|
| + return;
|
| const int height = this->height();
|
| const int width = this->width();
|
| - // do neighbor sumation; apply rules, output pixel color
|
| + // Do neighbor sumation; apply rules, output pixel color.
|
| for (int y = 1; y < (height - 1); ++y) {
|
| - char *src0 = cell_in_ + (y - 1) * width;
|
| - char *src1 = cell_in_ + (y) * width;
|
| - char *src2 = cell_in_ + (y + 1) * width;
|
| + uint8_t *src0 = (cell_in_ + (y - 1) * width) + 1;
|
| + uint8_t *src1 = src0 + width;
|
| + uint8_t *src2 = src1 + width;
|
| int count;
|
| - unsigned int color;
|
| - char *dst = cell_out_ + (y) * width;
|
| - uint32_t *pixels = static_cast<uint32_t*>(this->pixels()) + y * width;
|
| + uint32_t color;
|
| + uint8_t *dst = (cell_out_ + (y) * width) + 1;
|
| + uint32_t *pixel_buffer = pixels() + y * width;
|
| for (int x = 1; x < (width - 1); ++x) {
|
| - // build sum, weight center by 8x
|
| - count = src0[-1] + src0[0] + src0[1] +
|
| - src1[-1] + src1[0] * 8 + src1[1] +
|
| - src2[-1] + src2[0] + src2[1];
|
| - color = colors[count];
|
| - *pixels++ = color;
|
| - *dst++ = replace[count];
|
| - ++src0, ++src1, ++src2;
|
| + // Build sum, weight center by 9x.
|
| + count = src0[-1] + src0[0] + src0[1] +
|
| + src1[-1] + src1[0] * 9 + src1[1] +
|
| + src2[-1] + src2[0] + src2[1];
|
| + color = kNeighborColors[count];
|
| + *pixel_buffer++ = color;
|
| + *dst++ = kIsAlive[count];
|
| + ++src0;
|
| + ++src1;
|
| + ++src2;
|
| }
|
| }
|
| }
|
|
|
| void Life::Swap() {
|
| - char* tmp = cell_in_;
|
| + uint8_t* tmp = cell_in_;
|
| cell_in_ = cell_out_;
|
| cell_out_ = tmp;
|
| }
|
|
|
| -extern "C" {
|
| -
|
| -// The following functions implement functions to be used with npruntime.
|
| -static NPObject* AllocateLife(NPP npp, NPClass* npclass) {
|
| - Life* rv = new Life(npp);
|
| - return rv;
|
| -}
|
| -
|
| -static void Deallocate(NPObject* obj) {
|
| - Life* const life = static_cast<Life*>(obj);
|
| - delete life;
|
| -}
|
| -
|
| -// These are for npruntime.
|
| -static void Invalidate(NPObject*) {
|
| -}
|
| -
|
| -static bool HasMethod(NPObject*, NPIdentifier name) {
|
| - bool rv = false;
|
| - NPUTF8* method_name = NPN_UTF8FromIdentifier(name);
|
| - if (0 == memcmp(method_name, "update", sizeof("update"))) {
|
| - rv = true;
|
| +void Life::CreateContext(const pp::Size& size) {
|
| + if (IsContextValid())
|
| + return;
|
| + graphics_2d_context_ = new pp::Graphics2D(this, size, false);
|
| + if (!BindGraphics(*graphics_2d_context_)) {
|
| + printf("Couldn't bind the device context\n");
|
| }
|
| - NPN_MemFree(method_name);
|
| - return rv;
|
| }
|
|
|
| -static bool Invoke(NPObject *obj, NPIdentifier name, const NPVariant *args,
|
| - uint32_t argc, NPVariant *result) {
|
| - bool rv = false;
|
| - NPUTF8* method_name = NPN_UTF8FromIdentifier(name);
|
| - if (0 == memcmp(method_name, "update", sizeof("update"))) {
|
| - rv = true;
|
| - Life* const life = static_cast<Life*>(obj);
|
| - life->Update();
|
| - }
|
| - NPN_MemFree(method_name);
|
| - return rv;
|
| +void Life::DestroyContext() {
|
| + if (!IsContextValid())
|
| + return;
|
| + delete graphics_2d_context_;
|
| + graphics_2d_context_ = NULL;
|
| }
|
|
|
| -static bool InvokeDefault(NPObject *npobj, const NPVariant *args,
|
| - uint32_t argCount, NPVariant *result) {
|
| - return false;
|
| +void Life::FlushPixelBuffer() {
|
| + if (!IsContextValid())
|
| + return;
|
| + graphics_2d_context_->PaintImageData(*pixel_buffer_, pp::Point());
|
| + if (flush_pending())
|
| + return;
|
| + set_flush_pending(true);
|
| + graphics_2d_context_->Flush(pp::CompletionCallback(&FlushCallback, this));
|
| }
|
|
|
| -static bool HasProperty(NPObject *npobj, NPIdentifier name) {
|
| - return false;
|
| -}
|
| -
|
| -static bool GetProperty(NPObject *npobj, NPIdentifier name, NPVariant *result) {
|
| - return false;
|
| -}
|
| -
|
| -static bool SetProperty(NPObject *npobj, NPIdentifier name,
|
| - const NPVariant *value) {
|
| - return false;
|
| -}
|
| -
|
| -static bool RemoveProperty(NPObject *npobj, NPIdentifier name) {
|
| - return false;
|
| -}
|
| -
|
| -NPClass np_class = {
|
| - NP_CLASS_STRUCT_VERSION,
|
| - AllocateLife,
|
| - Deallocate,
|
| - Invalidate,
|
| - HasMethod,
|
| - Invoke,
|
| - InvokeDefault,
|
| - HasProperty,
|
| - GetProperty,
|
| - SetProperty,
|
| - RemoveProperty
|
| -};
|
| -
|
| -// These functions are required by both the develop and publish versions,
|
| -// they are called when a module instance is first loaded, and when the module
|
| -// instance is finally deleted. They must use C-style linkage.
|
| -NPError NPP_Destroy(NPP instance, NPSavedData** save) {
|
| - if (instance == NULL) {
|
| - return NPERR_INVALID_INSTANCE_ERROR;
|
| +bool Life::LifeScriptObject::HasMethod(
|
| + const pp::Var& method,
|
| + pp::Var* exception) {
|
| + if (!method.is_string()) {
|
| + return false;
|
| }
|
| -
|
| - Life* life = static_cast<Life*>(instance->pdata);
|
| - if (life != NULL) {
|
| - NPN_ReleaseObject(life);
|
| - }
|
| - return NPERR_NO_ERROR;
|
| + std::string method_name = method.AsString();
|
| + return method_name == kUpdateMethodId ||
|
| + method_name == kAddCellAtPointMethodId;
|
| }
|
|
|
| -// NPP_GetScriptableInstance retruns the NPObject pointer that corresponds to
|
| -// NPPVpluginScriptableNPObject queried by NPP_GetValue() from the browser.
|
| -NPObject* NPP_GetScriptableInstance(NPP instance) {
|
| - if (instance == NULL) {
|
| - return NULL;
|
| +pp::Var Life::LifeScriptObject::Call(
|
| + const pp::Var& method,
|
| + const std::vector<pp::Var>& args,
|
| + pp::Var* exception) {
|
| + if (!method.is_string()) {
|
| + return pp::Var(false);
|
| }
|
| - Life* life = static_cast<Life*>(instance->pdata);
|
| - return life;
|
| -}
|
| -
|
| -NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
|
| - if (NPPVpluginScriptableNPObject == variable) {
|
| - NPObject* scriptable_object = NPP_GetScriptableInstance(instance);
|
| - if (scriptable_object == NULL)
|
| - return NPERR_INVALID_INSTANCE_ERROR;
|
| - *reinterpret_cast<NPObject**>(value) = scriptable_object;
|
| - return NPERR_NO_ERROR;
|
| + std::string method_name = method.AsString();
|
| + if (app_instance_ != NULL) {
|
| + if (method_name == kUpdateMethodId) {
|
| + app_instance_->Update();
|
| + } else if (method_name == kAddCellAtPointMethodId) {
|
| + // Pull off the first two params.
|
| + if (args.size() < 2)
|
| + return pp::Var(false);
|
| + app_instance_->AddCellAtPoint(args[0], args[1]);
|
| + }
|
| }
|
| - return NPERR_INVALID_PARAM;
|
| + return pp::Var();
|
| }
|
|
|
| -int16_t NPP_HandleEvent(NPP instance, void* event) {
|
| - Life* life = static_cast<Life*>(instance->pdata);
|
| - if (NULL != life) {
|
| - NPPepperEvent* npevent = static_cast<NPPepperEvent*>(event);
|
| - life->HandleEvent(npevent);
|
| - }
|
| - return 0;
|
| +uint8_t Life::RandomBitGenerator::value() {
|
| + return static_cast<uint8_t>(rand_r(&random_bit_seed_) & 1);
|
| }
|
|
|
| -NPError NPP_New(NPMIMEType mime_type,
|
| - NPP instance,
|
| - uint16_t mode,
|
| - int16_t argc,
|
| - char* argn[],
|
| - char* argv[],
|
| - NPSavedData* saved) {
|
| - if (instance == NULL) {
|
| - return NPERR_INVALID_INSTANCE_ERROR;
|
| - }
|
| +} // namespace life
|
|
|
| - Life* const life = static_cast<Life*>(NPN_CreateObject(instance, &np_class));
|
| - instance->pdata = life;
|
| - return NPERR_NO_ERROR;
|
| -}
|
| -
|
| -NPError NPP_SetWindow(NPP instance, NPWindow* window) {
|
| - if (instance == NULL) {
|
| - return NPERR_INVALID_INSTANCE_ERROR;
|
| - }
|
| - if (window == NULL) {
|
| - return NPERR_GENERIC_ERROR;
|
| - }
|
| - Life* life = static_cast<Life*>(instance->pdata);
|
| - if (life != NULL) {
|
| - return life->SetWindow(window);
|
| - }
|
| - return NPERR_NO_ERROR;
|
| -}
|
| -
|
| -NPError NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) {
|
| - extern NPError InitializePluginFunctions(NPPluginFuncs* plugin_funcs);
|
| - return InitializePluginFunctions(plugin_funcs);
|
| -}
|
| -
|
| -NPError InitializePluginFunctions(NPPluginFuncs* plugin_funcs) {
|
| - memset(plugin_funcs, 0, sizeof(*plugin_funcs));
|
| - plugin_funcs->version = NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL;
|
| - plugin_funcs->size = sizeof(*plugin_funcs);
|
| - plugin_funcs->newp = NPP_New;
|
| - plugin_funcs->destroy = NPP_Destroy;
|
| - plugin_funcs->setwindow = NPP_SetWindow;
|
| - plugin_funcs->event = NPP_HandleEvent;
|
| - plugin_funcs->getvalue = NPP_GetValue;
|
| - return NPERR_NO_ERROR;
|
| -}
|
| -
|
| -NPError NP_Initialize(NPNetscapeFuncs* browser_functions,
|
| - NPPluginFuncs* plugin_functions) {
|
| - return NP_GetEntryPoints(plugin_functions);
|
| -}
|
| -
|
| -NPError NP_Shutdown() {
|
| - return NPERR_NO_ERROR;
|
| -}
|
| -
|
| -} // extern "C"
|
| -}
|
|
|
| Property changes on: examples/graphics/life/life.cc
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|