Permalink
Browse files

image/grid sync/async clear methods - refs mapbox/tilelive-mapnik#50

…- refs #93
  • Loading branch information...
1 parent 9f3aac2 commit d1ac32375ed46bd452b9dafcd4f4f268ef093630 Dane Springmeyer committed Nov 12, 2012
Showing with 180 additions and 12 deletions.
  1. +2 −2 README.md
  2. +88 −1 src/mapnik_grid.cpp
  3. +4 −0 src/mapnik_grid.hpp
  4. +83 −9 src/mapnik_image.cpp
  5. +3 −0 src/mapnik_image.hpp
View
@@ -53,9 +53,9 @@ For more sample code see 'examples/README.md'
* Node v0.6 or v0.8
* Mapnik 2.x
-Mapnik 2.1.0 is targeted, but 2.0.x is also supported.
+Mapnik 2.2.x is targeted, but 2.1.x and 2.0.x is also supported.
-This means that if you are running the Mapnik 2.1 series (current unreleased master) you must be running at least [0eddc2b5a0](https://github.com/mapnik/mapnik/commit/0eddc2b5a0d42fb1dcf5c228871eac145c089bbc).
+This means that if you are running the Mapnik 2.2 series (current unreleased master) you must be running at least [0eddc2b5a0](https://github.com/mapnik/mapnik/commit/eebc8cc73eb18903b07e3b3e0757c11925962124).
This means that if you are running the Mapnik 2.0.x series some minor test failures are expected:
View
@@ -35,12 +35,17 @@ void Grid::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "width", width);
NODE_SET_PROTOTYPE_METHOD(constructor, "height", height);
NODE_SET_PROTOTYPE_METHOD(constructor, "painted", painted);
-
+ NODE_SET_PROTOTYPE_METHOD(constructor, "clear", clear);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "clearSync", clear);
// properties
ATTR(constructor, "key", get_prop, set_prop);
target->Set(String::NewSymbol("Grid"),constructor->GetFunction());
+#if MAPNIK_VERSION >= 200200
NODE_MAPNIK_DEFINE_CONSTANT(constructor->GetFunction(), "base_mask", mapnik::grid::base_mask);
+#else
+ NODE_MAPNIK_DEFINE_CONSTANT(constructor->GetFunction(), "base_mask", 0);
+#endif
}
Grid::Grid(unsigned int width, unsigned int height, std::string const& key, unsigned int resolution) :
@@ -122,6 +127,88 @@ Handle<Value> Grid::New(const Arguments& args)
return Undefined();
}
+Handle<Value> Grid::clearSync(const Arguments& args)
+{
+ HandleScope scope;
+ Grid* g = ObjectWrap::Unwrap<Grid>(args.This());
+#if MAPNIK_VERSION >= 200200
+ g->get()->clear();
+#endif
+ return Undefined();
+}
+
+typedef struct {
+ uv_work_t request;
+ Grid* g;
+ std::string format;
+ bool error;
+ std::string error_name;
+ Persistent<Function> cb;
+} clear_grid_baton_t;
+
+Handle<Value> Grid::clear(const Arguments& args)
+{
+ HandleScope scope;
+ Grid* g = ObjectWrap::Unwrap<Grid>(args.This());
+
+ if (args.Length() == 0) {
+ return clearSync(args);
+ }
+ // ensure callback is a function
+ Local<Value> callback = args[args.Length()-1];
+ if (!args[args.Length()-1]->IsFunction())
+ return ThrowException(Exception::TypeError(
+ String::New("last argument must be a callback function")));
+ clear_grid_baton_t *closure = new clear_grid_baton_t();
+ closure->request.data = closure;
+ closure->g = g;
+ closure->error = false;
+ closure->cb = Persistent<Function>::New(Handle<Function>::Cast(callback));
+ uv_queue_work(uv_default_loop(), &closure->request, EIO_Clear, EIO_AfterClear);
+ g->Ref();
+ return Undefined();
+}
+
+void Grid::EIO_Clear(uv_work_t* req)
+{
+ clear_grid_baton_t *closure = static_cast<clear_grid_baton_t *>(req->data);
+ try
+ {
+#if MAPNIK_VERSION >= 200200
+ closure->g->get()->clear();
+#endif
+ }
+ catch(std::exception const& ex)
+ {
+ closure->error = true;
+ closure->error_name = ex.what();
+ }
+}
+
+void Grid::EIO_AfterClear(uv_work_t* req)
+{
+ HandleScope scope;
+ clear_grid_baton_t *closure = static_cast<clear_grid_baton_t *>(req->data);
+ TryCatch try_catch;
+ if (closure->error)
+ {
+ Local<Value> argv[1] = { Exception::Error(String::New(closure->error_name.c_str())) };
+ closure->cb->Call(Context::GetCurrent()->Global(), 1, argv);
+ }
+ else
+ {
+ Local<Value> argv[2] = { Local<Value>::New(Null()) };
+ closure->cb->Call(Context::GetCurrent()->Global(), 1, argv);
+ }
+ if (try_catch.HasCaught())
+ {
+ FatalException(try_catch);
+ }
+ closure->g->Unref();
+ closure->cb.Dispose();
+ delete closure;
+}
+
Handle<Value> Grid::painted(const Arguments& args)
{
HandleScope scope;
View
@@ -28,6 +28,10 @@ class Grid: public node::ObjectWrap {
static Handle<Value> width(const Arguments &args);
static Handle<Value> height(const Arguments &args);
static Handle<Value> painted(const Arguments &args);
+ static Handle<Value> clearSync(const Arguments& args);
+ static Handle<Value> clear(const Arguments& args);
+ static void EIO_Clear(uv_work_t* req);
+ static void EIO_AfterClear(uv_work_t* req);
static Handle<Value> get_prop(Local<String> property,
const AccessorInfo& info);
View
@@ -48,6 +48,7 @@ void Image::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "premultiply", premultiply);
NODE_SET_PROTOTYPE_METHOD(constructor, "demultiply", demultiply);
NODE_SET_PROTOTYPE_METHOD(constructor, "clear", clear);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "clearSync", clear);
ATTR(constructor, "background", get_prop, set_prop);
@@ -149,6 +150,88 @@ void Image::set_prop(Local<String> property,
}
}
+Handle<Value> Image::clearSync(const Arguments& args)
+{
+ HandleScope scope;
+ Image* im = ObjectWrap::Unwrap<Image>(args.This());
+#if MAPNIK_VERSION >= 200200
+ im->get()->clear();
+#endif
+ return Undefined();
+}
+
+typedef struct {
+ uv_work_t request;
+ Image* im;
+ std::string format;
+ bool error;
+ std::string error_name;
+ Persistent<Function> cb;
+} clear_image_baton_t;
+
+Handle<Value> Image::clear(const Arguments& args)
+{
+ HandleScope scope;
+ Image* im = ObjectWrap::Unwrap<Image>(args.This());
+
+ if (args.Length() == 0) {
+ return clearSync(args);
+ }
+ // ensure callback is a function
+ Local<Value> callback = args[args.Length()-1];
+ if (!args[args.Length()-1]->IsFunction())
+ return ThrowException(Exception::TypeError(
+ String::New("last argument must be a callback function")));
+ clear_image_baton_t *closure = new clear_image_baton_t();
+ closure->request.data = closure;
+ closure->im = im;
+ closure->error = false;
+ closure->cb = Persistent<Function>::New(Handle<Function>::Cast(callback));
+ uv_queue_work(uv_default_loop(), &closure->request, EIO_Clear, EIO_AfterClear);
+ im->Ref();
+ return Undefined();
+}
+
+void Image::EIO_Clear(uv_work_t* req)
+{
+ clear_image_baton_t *closure = static_cast<clear_image_baton_t *>(req->data);
+ try
+ {
+#if MAPNIK_VERSION >= 200200
+ closure->im->get()->clear();
+#endif
+ }
+ catch(std::exception const& ex)
+ {
+ closure->error = true;
+ closure->error_name = ex.what();
+ }
+}
+
+void Image::EIO_AfterClear(uv_work_t* req)
+{
+ HandleScope scope;
+ clear_image_baton_t *closure = static_cast<clear_image_baton_t *>(req->data);
+ TryCatch try_catch;
+ if (closure->error)
+ {
+ Local<Value> argv[1] = { Exception::Error(String::New(closure->error_name.c_str())) };
+ closure->cb->Call(Context::GetCurrent()->Global(), 1, argv);
+ }
+ else
+ {
+ Local<Value> argv[2] = { Local<Value>::New(Null()) };
+ closure->cb->Call(Context::GetCurrent()->Global(), 1, argv);
+ }
+ if (try_catch.HasCaught())
+ {
+ FatalException(try_catch);
+ }
+ closure->im->Unref();
+ closure->cb.Dispose();
+ delete closure;
+}
+
Handle<Value> Image::setGrayScaleToAlpha(const Arguments& args)
{
HandleScope scope;
@@ -194,15 +277,6 @@ Handle<Value> Image::setGrayScaleToAlpha(const Arguments& args)
return Undefined();
}
-Handle<Value> Image::clear(const Arguments& args)
-{
- HandleScope scope;
- Image* im = ObjectWrap::Unwrap<Image>(args.This());
- mapnik::image_data_32 & data = im->this_->data();
- std::memset(data.getData(),0,sizeof(mapnik::image_data_32::pixel_type)*data.width()*data.height());
- return Undefined();
-}
-
Handle<Value> Image::premultiply(const Arguments& args)
{
HandleScope scope;
View
@@ -33,7 +33,10 @@ class Image: public node::ObjectWrap {
static Handle<Value> composite(const Arguments &args);
static Handle<Value> premultiply(const Arguments& args);
static Handle<Value> demultiply(const Arguments& args);
+ static Handle<Value> clearSync(const Arguments& args);
static Handle<Value> clear(const Arguments& args);
+ static void EIO_Clear(uv_work_t* req);
+ static void EIO_AfterClear(uv_work_t* req);
static void EIO_Composite(uv_work_t* req);
static void EIO_AfterComposite(uv_work_t* req);

0 comments on commit d1ac323

Please sign in to comment.