Node platform improvements (#891)

This commit is contained in:
tdcosta100
2023-03-09 04:27:14 +00:00
committed by GitHub
parent 9a3afedb25
commit 9766f6fcc2
5 changed files with 212 additions and 14 deletions

View File

@@ -102,6 +102,7 @@ ParseError)JS").ToLocalChecked()).ToLocalChecked();
Nan::SetPrototypeMethod(tpl, "setLayoutProperty", SetLayerProperty);
Nan::SetPrototypeMethod(tpl, "setPaintProperty", SetLayerProperty);
Nan::SetPrototypeMethod(tpl, "setFilter", SetFilter);
Nan::SetPrototypeMethod(tpl, "setSize", SetSize);
Nan::SetPrototypeMethod(tpl, "setCenter", SetCenter);
Nan::SetPrototypeMethod(tpl, "setZoom", SetZoom);
Nan::SetPrototypeMethod(tpl, "setBearing", SetBearing);
@@ -426,11 +427,11 @@ void NodeMap::Render(const Nan::FunctionCallbackInfo<v8::Value>& info) {
auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
if (info.Length() <= 0 || !info[0]->IsObject()) {
return Nan::ThrowTypeError("First argument must be an options object");
if (info.Length() <= 0 || (!info[0]->IsObject() && !info[0]->IsFunction())) {
return Nan::ThrowTypeError("First argument must be an options object or a callback function");
}
if (info.Length() <= 1 || !info[1]->IsFunction()) {
if ((info.Length() <= 1 && !info[0]->IsFunction()) || (info.Length() > 1 && !info[1]->IsFunction())) {
return Nan::ThrowTypeError("Second argument must be a callback function");
}
@@ -443,12 +444,20 @@ void NodeMap::Render(const Nan::FunctionCallbackInfo<v8::Value>& info) {
}
try {
auto options = ParseOptions(Nan::To<v8::Object>(info[0]).ToLocalChecked());
assert(!nodeMap->req);
assert(!nodeMap->image.data);
nodeMap->req = std::make_unique<RenderRequest>(Nan::To<v8::Function>(info[1]).ToLocalChecked());
if (info[0]->IsFunction()) {
assert(!nodeMap->req);
assert(!nodeMap->image.data);
nodeMap->req = std::make_unique<RenderRequest>(Nan::To<v8::Function>(info[0]).ToLocalChecked());
nodeMap->startRender(options);
nodeMap->startRender();
} else {
auto options = ParseOptions(Nan::To<v8::Object>(info[0]).ToLocalChecked());
assert(!nodeMap->req);
assert(!nodeMap->image.data);
nodeMap->req = std::make_unique<RenderRequest>(Nan::To<v8::Function>(info[1]).ToLocalChecked());
nodeMap->startRender(options);
}
} catch (const mbgl::style::conversion::Error& err) {
return Nan::ThrowTypeError(err.message.c_str());
} catch (const mbgl::util::StyleParseException& ex) {
@@ -460,6 +469,27 @@ void NodeMap::Render(const Nan::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().SetUndefined();
}
void NodeMap::startRender() {
map->renderStill([this](const std::exception_ptr& eptr) {
if (eptr) {
error = eptr;
uv_async_send(async);
} else {
assert(!image.data);
image = frontend->readStillImage();
uv_async_send(async);
}
});
// Retain this object, otherwise it might get destructed before we are finished rendering the
// still image.
Ref();
// Similarly, we're now waiting for the async to be called, so we need to make sure that it
// keeps the loop alive.
uv_ref(reinterpret_cast<uv_handle_t*>(async));
}
void NodeMap::startRender(const NodeMap::RenderOptions& options) {
frontend->setSize(options.size);
map->setSize(options.size);
@@ -640,7 +670,7 @@ void NodeMap::cancel() {
reinterpret_cast<NodeMap *>(h->data)->renderFinished();
});
frontend = std::make_unique<mbgl::HeadlessFrontend>(mbgl::Size{ 256, 256 }, pixelRatio);
frontend = std::make_unique<mbgl::HeadlessFrontend>(mbgl::Size{ 512, 512 }, pixelRatio);
map = std::make_unique<mbgl::Map>(*frontend, mapObserver,
mbgl::MapOptions().withSize(frontend->getSize())
.withPixelRatio(pixelRatio)
@@ -925,6 +955,30 @@ void NodeMap::SetFilter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
layer->setFilter(filter);
}
void NodeMap::SetSize(const Nan::FunctionCallbackInfo<v8::Value>& info) {
auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
if (info.Length() <= 0 || !info[0]->IsArray()) {
return Nan::ThrowTypeError("First argument must be an array");
}
auto size = info[0].As<v8::Array>();
uint32_t width= 0;
uint32_t height = 0;
if (size->Length() > 0) { width = Nan::To<uint32_t>(Nan::Get(size, 0).ToLocalChecked()).ToChecked(); }
if (size->Length() > 1) { height = Nan::To<uint32_t>(Nan::Get(size, 1).ToLocalChecked()).ToChecked(); }
try {
nodeMap->frontend->setSize({ width, height });
nodeMap->map->setSize({ width, height });
} catch (const std::exception &ex) {
return Nan::ThrowError(ex.what());
}
info.GetReturnValue().SetUndefined();
}
void NodeMap::SetCenter(const Nan::FunctionCallbackInfo<v8::Value>& info) {
auto nodeMap = Nan::ObjectWrap::Unwrap<NodeMap>(info.Holder());
if (!nodeMap->map) return Nan::ThrowError(releasedMessage());
@@ -1419,7 +1473,7 @@ NodeMap::NodeMap(v8::Local<v8::Object> options)
: true;
}())
, mapObserver(NodeMapObserver())
, frontend(std::make_unique<mbgl::HeadlessFrontend>(mbgl::Size { 256, 256 }, pixelRatio))
, frontend(std::make_unique<mbgl::HeadlessFrontend>(mbgl::Size { 512, 512 }, pixelRatio))
, map(std::make_unique<mbgl::Map>(*frontend, mapObserver,
mbgl::MapOptions().withSize(frontend->getSize())
.withPixelRatio(pixelRatio)

View File

@@ -55,6 +55,7 @@ public:
static void SetLayerZoomRange(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetLayerProperty(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetFilter(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetSize(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetCenter(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetZoom(const Nan::FunctionCallbackInfo<v8::Value>&);
static void SetBearing(const Nan::FunctionCallbackInfo<v8::Value>&);
@@ -72,6 +73,7 @@ public:
static v8::Local<v8::Value> ParseError(const char* msg);
void startRender();
void startRender(const RenderOptions& options);
void renderFinished();