[core] Merge Sprite into SpriteStore
This commit is contained in:
@@ -168,7 +168,7 @@ std::unique_ptr<Bucket> SymbolLayer::createBucket(StyleBucketParameters& paramet
|
||||
|
||||
bucket->parseFeatures(parameters.layer, filter);
|
||||
|
||||
if (bucket->needsDependencies(parameters.glyphStore, parameters.sprite)) {
|
||||
if (bucket->needsDependencies(parameters.glyphStore, parameters.spriteStore)) {
|
||||
parameters.partialParse = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,7 @@ void MapContext::update() {
|
||||
|
||||
data.setAnimationTime(Clock::now());
|
||||
|
||||
if (style->sprite && updateFlags & Update::Annotations) {
|
||||
if (updateFlags & Update::Annotations) {
|
||||
data.getAnnotationManager()->updateStyle(*style);
|
||||
updateFlags |= Update::Classes;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ TileWorker::TileWorker(TileID id_,
|
||||
sourceID(sourceID_),
|
||||
style(style_),
|
||||
state(state_) {
|
||||
assert(style.sprite);
|
||||
}
|
||||
|
||||
TileWorker::~TileWorker() {
|
||||
@@ -64,7 +63,7 @@ TileParseResult TileWorker::parsePendingLayers() {
|
||||
|
||||
if (layer.type == StyleLayerType::Symbol) {
|
||||
auto symbolBucket = dynamic_cast<SymbolBucket*>(bucket.get());
|
||||
if (!symbolBucket->needsDependencies(*style.glyphStore, *style.sprite)) {
|
||||
if (!symbolBucket->needsDependencies(*style.glyphStore, *style.spriteStore)) {
|
||||
symbolBucket->addFeatures(reinterpret_cast<uintptr_t>(this), *style.spriteAtlas,
|
||||
*style.glyphAtlas, *style.glyphStore, *collisionTile);
|
||||
insertBucket(layer.bucketName(), std::move(bucket));
|
||||
@@ -130,7 +129,7 @@ void TileWorker::parseLayer(const StyleLayer& layer, const GeometryTile& geometr
|
||||
reinterpret_cast<uintptr_t>(this),
|
||||
partialParse,
|
||||
*style.spriteAtlas,
|
||||
*style.sprite,
|
||||
*style.spriteStore,
|
||||
*style.glyphAtlas,
|
||||
*style.glyphStore,
|
||||
*collisionTile);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <mbgl/renderer/symbol_bucket.hpp>
|
||||
#include <mbgl/layer/symbol_layer.hpp>
|
||||
#include <mbgl/map/geometry_tile.hpp>
|
||||
#include <mbgl/sprite/sprite.hpp>
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
#include <mbgl/sprite/sprite_atlas.hpp>
|
||||
#include <mbgl/geometry/text_buffer.hpp>
|
||||
#include <mbgl/geometry/icon_buffer.hpp>
|
||||
@@ -158,13 +158,12 @@ void SymbolBucket::parseFeatures(const GeometryTileLayer& layer,
|
||||
}
|
||||
}
|
||||
|
||||
bool SymbolBucket::needsDependencies(GlyphStore& glyphStore,
|
||||
Sprite& sprite) {
|
||||
bool SymbolBucket::needsDependencies(GlyphStore& glyphStore, SpriteStore& spriteStore) {
|
||||
if (!layout.text.field.value.empty() && !layout.text.font.value.empty() && !glyphStore.hasGlyphRanges(layout.text.font, ranges)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!layout.icon.image.value.empty() && !sprite.isLoaded()) {
|
||||
if (!layout.icon.image.value.empty() && !spriteStore.isLoaded()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class CollisionBoxShader;
|
||||
class DotShader;
|
||||
class CollisionTile;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class SpriteStore;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
|
||||
@@ -88,8 +88,7 @@ public:
|
||||
|
||||
void parseFeatures(const GeometryTileLayer&,
|
||||
const FilterExpression&);
|
||||
bool needsDependencies(GlyphStore& glyphStore,
|
||||
Sprite& sprite);
|
||||
bool needsDependencies(GlyphStore&, SpriteStore&);
|
||||
void placeFeatures(CollisionTile&) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
#include <mbgl/sprite/sprite.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/storage/request_holder.hpp>
|
||||
#include <mbgl/util/exception.hpp>
|
||||
#include <mbgl/util/raster.hpp>
|
||||
#include <mbgl/util/thread.hpp>
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct Sprite::Loader {
|
||||
std::shared_ptr<const std::string> image;
|
||||
std::shared_ptr<const std::string> json;
|
||||
RequestHolder jsonRequest;
|
||||
RequestHolder spriteRequest;
|
||||
};
|
||||
|
||||
Sprite::Sprite(const std::string& baseUrl, float pixelRatio_)
|
||||
: pixelRatio(pixelRatio_ > 1 ? 2 : 1) {
|
||||
if (baseUrl.empty()) {
|
||||
// Treat a non-existent sprite as a successfully loaded empty sprite.
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string spriteURL(baseUrl + (pixelRatio_ > 1 ? "@2x" : "") + ".png");
|
||||
std::string jsonURL(baseUrl + (pixelRatio_ > 1 ? "@2x" : "") + ".json");
|
||||
|
||||
loader = std::make_unique<Loader>();
|
||||
|
||||
FileSource* fs = util::ThreadContext::getFileSource();
|
||||
loader->jsonRequest = fs->request({ Resource::Kind::SpriteJSON, jsonURL }, util::RunLoop::getLoop(),
|
||||
[this, jsonURL](const Response& res) {
|
||||
if (res.stale) {
|
||||
// Only handle fresh responses.
|
||||
return;
|
||||
}
|
||||
loader->jsonRequest = nullptr;
|
||||
|
||||
if (res.error) {
|
||||
std::stringstream message;
|
||||
message << "Failed to load [" << jsonURL << "]: " << res.error->message;
|
||||
emitSpriteLoadingFailed(message.str());
|
||||
return;
|
||||
} else {
|
||||
loader->json = res.data;
|
||||
}
|
||||
emitSpriteLoadedIfComplete();
|
||||
});
|
||||
|
||||
loader->spriteRequest =
|
||||
fs->request({ Resource::Kind::SpriteImage, spriteURL }, util::RunLoop::getLoop(),
|
||||
[this, spriteURL](const Response& res) {
|
||||
if (res.stale) {
|
||||
// Only handle fresh responses.
|
||||
return;
|
||||
}
|
||||
loader->spriteRequest = nullptr;
|
||||
|
||||
if (res.error) {
|
||||
std::stringstream message;
|
||||
message << "Failed to load [" << spriteURL << "]: " << res.error->message;
|
||||
emitSpriteLoadingFailed(message.str());
|
||||
return;
|
||||
} else {
|
||||
loader->image = res.data;
|
||||
}
|
||||
emitSpriteLoadedIfComplete();
|
||||
});
|
||||
}
|
||||
|
||||
Sprite::~Sprite() {
|
||||
}
|
||||
|
||||
void Sprite::emitSpriteLoadedIfComplete() {
|
||||
assert(loader);
|
||||
|
||||
if (!loader->image || !loader->json || !observer) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto local = std::move(loader);
|
||||
auto result = parseSprite(*local->image, *local->json);
|
||||
if (result.is<Sprites>()) {
|
||||
loaded = true;
|
||||
observer->onSpriteLoaded(result.get<Sprites>());
|
||||
} else {
|
||||
emitSpriteLoadingFailed(result.get<std::string>());
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::emitSpriteLoadingFailed(const std::string& message) {
|
||||
if (!observer) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto error = std::make_exception_ptr(util::SpriteLoadingException(message));
|
||||
observer->onSpriteLoadingFailed(error);
|
||||
}
|
||||
|
||||
void Sprite::setObserver(Observer* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
|
||||
void Sprite::dumpDebugLogs() const {
|
||||
Log::Info(Event::General, "Sprite::loaded: %d", loaded);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -1,57 +0,0 @@
|
||||
#ifndef MBGL_SPRITE
|
||||
#define MBGL_SPRITE
|
||||
|
||||
#include <mbgl/sprite/sprite_parser.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/storage/request.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <atomic>
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Request;
|
||||
|
||||
class Sprite : private util::noncopyable {
|
||||
public:
|
||||
class Observer {
|
||||
public:
|
||||
virtual ~Observer() = default;
|
||||
|
||||
virtual void onSpriteLoaded(const Sprites& sprites) = 0;
|
||||
virtual void onSpriteLoadingFailed(std::exception_ptr error) = 0;
|
||||
};
|
||||
|
||||
Sprite(const std::string& baseUrl, float pixelRatio);
|
||||
~Sprite();
|
||||
|
||||
inline bool isLoaded() const {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void dumpDebugLogs() const;
|
||||
|
||||
const float pixelRatio;
|
||||
|
||||
void setObserver(Observer* observer);
|
||||
|
||||
private:
|
||||
void emitSpriteLoadedIfComplete();
|
||||
void emitSpriteLoadingFailed(const std::string& message);
|
||||
|
||||
struct Loader;
|
||||
std::unique_ptr<Loader> loader;
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
Observer* observer = nullptr;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
#endif
|
||||
@@ -10,13 +10,10 @@
|
||||
#include <mbgl/util/scaling.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
|
||||
#include <mbgl/sprite/sprite.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
SpriteAtlas::SpriteAtlas(dimension width_, dimension height_, float pixelRatio_, SpriteStore& store_)
|
||||
|
||||
@@ -1,9 +1,122 @@
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
|
||||
#include <mbgl/sprite/sprite_parser.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/storage/request_holder.hpp>
|
||||
#include <mbgl/util/exception.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
struct SpriteStore::Loader {
|
||||
std::shared_ptr<const std::string> image;
|
||||
std::shared_ptr<const std::string> json;
|
||||
RequestHolder jsonRequest;
|
||||
RequestHolder spriteRequest;
|
||||
};
|
||||
|
||||
SpriteStore::SpriteStore(float pixelRatio_)
|
||||
: pixelRatio(pixelRatio_ > 1 ? 2 : 1) {
|
||||
}
|
||||
|
||||
SpriteStore::~SpriteStore() = default;
|
||||
|
||||
void SpriteStore::setURL(const std::string& url) {
|
||||
if (url.empty()) {
|
||||
// Treat a non-existent sprite as a successfully loaded empty sprite.
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string spriteURL(url + (pixelRatio > 1 ? "@2x" : "") + ".png");
|
||||
std::string jsonURL(url + (pixelRatio > 1 ? "@2x" : "") + ".json");
|
||||
|
||||
loader = std::make_unique<Loader>();
|
||||
|
||||
FileSource* fs = util::ThreadContext::getFileSource();
|
||||
loader->jsonRequest = fs->request({ Resource::Kind::SpriteJSON, jsonURL }, util::RunLoop::getLoop(),
|
||||
[this, jsonURL](const Response& res) {
|
||||
if (res.stale) {
|
||||
// Only handle fresh responses.
|
||||
return;
|
||||
}
|
||||
loader->jsonRequest = nullptr;
|
||||
|
||||
if (res.error) {
|
||||
std::stringstream message;
|
||||
message << "Failed to load [" << jsonURL << "]: " << res.error->message;
|
||||
emitSpriteLoadingFailed(message.str());
|
||||
return;
|
||||
} else {
|
||||
loader->json = res.data;
|
||||
}
|
||||
emitSpriteLoadedIfComplete();
|
||||
});
|
||||
|
||||
loader->spriteRequest =
|
||||
fs->request({ Resource::Kind::SpriteImage, spriteURL }, util::RunLoop::getLoop(),
|
||||
[this, spriteURL](const Response& res) {
|
||||
if (res.stale) {
|
||||
// Only handle fresh responses.
|
||||
return;
|
||||
}
|
||||
loader->spriteRequest = nullptr;
|
||||
|
||||
if (res.error) {
|
||||
std::stringstream message;
|
||||
message << "Failed to load [" << spriteURL << "]: " << res.error->message;
|
||||
emitSpriteLoadingFailed(message.str());
|
||||
return;
|
||||
} else {
|
||||
loader->image = res.data;
|
||||
}
|
||||
emitSpriteLoadedIfComplete();
|
||||
});
|
||||
}
|
||||
|
||||
void SpriteStore::emitSpriteLoadedIfComplete() {
|
||||
assert(loader);
|
||||
|
||||
if (!loader->image || !loader->json) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto local = std::move(loader);
|
||||
auto result = parseSprite(*local->image, *local->json);
|
||||
if (result.is<Sprites>()) {
|
||||
loaded = true;
|
||||
setSprites(result.get<Sprites>());
|
||||
if (observer) {
|
||||
observer->onSpriteLoaded();
|
||||
}
|
||||
} else {
|
||||
emitSpriteLoadingFailed(result.get<std::string>());
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteStore::emitSpriteLoadingFailed(const std::string& message) {
|
||||
if (!observer) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto error = std::make_exception_ptr(util::SpriteLoadingException(message));
|
||||
observer->onSpriteLoadingFailed(error);
|
||||
}
|
||||
|
||||
void SpriteStore::setObserver(Observer* observer_) {
|
||||
observer = observer_;
|
||||
}
|
||||
|
||||
void SpriteStore::dumpDebugLogs() const {
|
||||
Log::Info(Event::General, "SpriteStore::loaded: %d", loaded);
|
||||
}
|
||||
|
||||
void SpriteStore::setSprite(const std::string& name, std::shared_ptr<const SpriteImage> sprite) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
_setSprite(name, sprite);
|
||||
|
||||
@@ -2,24 +2,39 @@
|
||||
#define MBGL_SPRITE_STORE
|
||||
|
||||
#include <mbgl/sprite/sprite_image.hpp>
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
// The SpriteStore object holds Sprite images.
|
||||
class SpriteStore : private util::noncopyable {
|
||||
public:
|
||||
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
|
||||
|
||||
public:
|
||||
class Observer {
|
||||
public:
|
||||
virtual ~Observer() = default;
|
||||
|
||||
virtual void onSpriteLoaded() = 0;
|
||||
virtual void onSpriteLoadingFailed(std::exception_ptr) = 0;
|
||||
};
|
||||
|
||||
SpriteStore(float pixelRatio);
|
||||
~SpriteStore();
|
||||
|
||||
void setURL(const std::string&);
|
||||
|
||||
bool isLoaded() const {
|
||||
return loaded;
|
||||
}
|
||||
|
||||
void dumpDebugLogs() const;
|
||||
|
||||
void setObserver(Observer* observer);
|
||||
|
||||
// Adds/replaces a Sprite image.
|
||||
void setSprite(const std::string&, std::shared_ptr<const SpriteImage> = nullptr);
|
||||
|
||||
@@ -35,9 +50,21 @@ public:
|
||||
// Returns Sprite images that changed since the last invocation of this function.
|
||||
Sprites getDirty();
|
||||
|
||||
const float pixelRatio;
|
||||
|
||||
private:
|
||||
void _setSprite(const std::string&, const std::shared_ptr<const SpriteImage>& = nullptr);
|
||||
|
||||
void emitSpriteLoadedIfComplete();
|
||||
void emitSpriteLoadingFailed(const std::string& message);
|
||||
|
||||
struct Loader;
|
||||
std::unique_ptr<Loader> loader;
|
||||
|
||||
bool loaded = false;
|
||||
|
||||
Observer* observer = nullptr;
|
||||
|
||||
// Lock for sprites and dirty maps.
|
||||
std::mutex mutex;
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <mbgl/map/map_data.hpp>
|
||||
#include <mbgl/map/source.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/sprite/sprite.hpp>
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
#include <mbgl/sprite/sprite_atlas.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
@@ -28,12 +27,13 @@ Style::Style(MapData& data_)
|
||||
: data(data_),
|
||||
glyphStore(std::make_unique<GlyphStore>()),
|
||||
glyphAtlas(std::make_unique<GlyphAtlas>(1024, 1024)),
|
||||
spriteStore(std::make_unique<SpriteStore>()),
|
||||
spriteStore(std::make_unique<SpriteStore>(data.pixelRatio)),
|
||||
spriteAtlas(std::make_unique<SpriteAtlas>(512, 512, data.pixelRatio, *spriteStore)),
|
||||
lineAtlas(std::make_unique<LineAtlas>(512, 512)),
|
||||
mtx(std::make_unique<uv::rwlock>()),
|
||||
workers(4) {
|
||||
glyphStore->setObserver(this);
|
||||
spriteStore->setObserver(this);
|
||||
}
|
||||
|
||||
void Style::setJSON(const std::string& json, const std::string&) {
|
||||
@@ -55,10 +55,8 @@ void Style::setJSON(const std::string& json, const std::string&) {
|
||||
addLayer(std::move(layer));
|
||||
}
|
||||
|
||||
sprite = std::make_unique<Sprite>(parser.getSprite(), data.pixelRatio);
|
||||
sprite->setObserver(this);
|
||||
|
||||
glyphStore->setURL(parser.getGlyphURL());
|
||||
spriteStore->setURL(parser.getSpriteURL());
|
||||
}
|
||||
|
||||
Style::~Style() {
|
||||
@@ -67,10 +65,7 @@ Style::~Style() {
|
||||
}
|
||||
|
||||
glyphStore->setObserver(nullptr);
|
||||
|
||||
if (sprite) {
|
||||
sprite->setObserver(nullptr);
|
||||
}
|
||||
spriteStore->setObserver(nullptr);
|
||||
}
|
||||
|
||||
void Style::addSource(std::unique_ptr<Source> source) {
|
||||
@@ -186,7 +181,7 @@ bool Style::isLoaded() const {
|
||||
}
|
||||
}
|
||||
|
||||
if (sprite && !sprite->isLoaded()) {
|
||||
if (!spriteStore->isLoaded()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -230,10 +225,7 @@ void Style::onTileLoadingFailed(std::exception_ptr error) {
|
||||
emitResourceLoadingFailed(error);
|
||||
}
|
||||
|
||||
void Style::onSpriteLoaded(const Sprites& sprites) {
|
||||
// Add all sprite images to the SpriteStore object
|
||||
spriteStore->setSprites(sprites);
|
||||
|
||||
void Style::onSpriteLoaded() {
|
||||
shouldReparsePartialTiles = true;
|
||||
emitTileDataChanged();
|
||||
}
|
||||
@@ -272,11 +264,7 @@ void Style::dumpDebugLogs() const {
|
||||
source->dumpDebugLogs();
|
||||
}
|
||||
|
||||
if (!sprite) {
|
||||
Log::Info(Event::General, "no sprite loaded");
|
||||
} else {
|
||||
sprite->dumpDebugLogs();
|
||||
}
|
||||
spriteStore->dumpDebugLogs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,9 @@
|
||||
#include <mbgl/style/zoom_history.hpp>
|
||||
|
||||
#include <mbgl/map/source.hpp>
|
||||
#include <mbgl/sprite/sprite.hpp>
|
||||
#include <mbgl/text/glyph_store.hpp>
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
@@ -27,8 +26,8 @@ class LineAtlas;
|
||||
class StyleLayer;
|
||||
|
||||
class Style : public GlyphStore::Observer,
|
||||
public SpriteStore::Observer,
|
||||
public Source::Observer,
|
||||
public Sprite::Observer,
|
||||
public util::noncopyable {
|
||||
public:
|
||||
Style(MapData&);
|
||||
@@ -74,7 +73,6 @@ public:
|
||||
MapData& data;
|
||||
std::unique_ptr<GlyphStore> glyphStore;
|
||||
std::unique_ptr<GlyphAtlas> glyphAtlas;
|
||||
util::ptr<Sprite> sprite;
|
||||
std::unique_ptr<SpriteStore> spriteStore;
|
||||
std::unique_ptr<SpriteAtlas> spriteAtlas;
|
||||
std::unique_ptr<LineAtlas> lineAtlas;
|
||||
@@ -89,16 +87,16 @@ private:
|
||||
void onGlyphRangeLoaded() override;
|
||||
void onGlyphRangeLoadingFailed(std::exception_ptr error) override;
|
||||
|
||||
// SpriteStore::Observer implementation.
|
||||
void onSpriteLoaded() override;
|
||||
void onSpriteLoadingFailed(std::exception_ptr error) override;
|
||||
|
||||
// Source::Observer implementation.
|
||||
void onSourceLoaded() override;
|
||||
void onSourceLoadingFailed(std::exception_ptr error) override;
|
||||
void onTileLoaded(bool isNewTile) override;
|
||||
void onTileLoadingFailed(std::exception_ptr error) override;
|
||||
|
||||
// Sprite::Observer implementation.
|
||||
void onSpriteLoaded(const Sprites& sprites) override;
|
||||
void onSpriteLoadingFailed(std::exception_ptr error) override;
|
||||
|
||||
void emitTileDataChanged();
|
||||
void emitResourceLoadingFailed(std::exception_ptr error);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ class TileID;
|
||||
class GeometryTileLayer;
|
||||
class GeometryTileFeature;
|
||||
class SpriteAtlas;
|
||||
class Sprite;
|
||||
class SpriteStore;
|
||||
class GlyphAtlas;
|
||||
class GlyphStore;
|
||||
class CollisionTile;
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
uintptr_t tileUID_,
|
||||
bool& partialParse_,
|
||||
SpriteAtlas& spriteAtlas_,
|
||||
Sprite& sprite_,
|
||||
SpriteStore& spriteStore_,
|
||||
GlyphAtlas& glyphAtlas_,
|
||||
GlyphStore& glyphStore_,
|
||||
CollisionTile& collisionTile_)
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
tileUID(tileUID_),
|
||||
partialParse(partialParse_),
|
||||
spriteAtlas(spriteAtlas_),
|
||||
sprite(sprite_),
|
||||
spriteStore(spriteStore_),
|
||||
glyphAtlas(glyphAtlas_),
|
||||
glyphStore(glyphStore_),
|
||||
collisionTile(collisionTile_) {}
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
uintptr_t tileUID;
|
||||
bool& partialParse;
|
||||
SpriteAtlas& spriteAtlas;
|
||||
Sprite& sprite;
|
||||
SpriteStore& spriteStore;
|
||||
GlyphAtlas& glyphAtlas;
|
||||
GlyphStore& glyphStore;
|
||||
CollisionTile& collisionTile;
|
||||
|
||||
@@ -24,11 +24,17 @@ void StyleParser::parse(const JSVal& document) {
|
||||
}
|
||||
|
||||
if (document.HasMember("sprite")) {
|
||||
parseSprite(document["sprite"]);
|
||||
const JSVal& sprite = document["sprite"];
|
||||
if (sprite.IsString()) {
|
||||
spriteURL = { sprite.GetString(), sprite.GetStringLength() };
|
||||
}
|
||||
}
|
||||
|
||||
if (document.HasMember("glyphs")) {
|
||||
parseGlyphURL(document["glyphs"]);
|
||||
const JSVal& glyphs = document["glyphs"];
|
||||
if (glyphs.IsString()) {
|
||||
glyphURL = { glyphs.GetString(), glyphs.GetStringLength() };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,18 +272,6 @@ void StyleParser::parseLayer(const std::string& id, const JSVal& value, util::pt
|
||||
layer->parsePaints(value);
|
||||
}
|
||||
|
||||
void StyleParser::parseSprite(const JSVal& value) {
|
||||
if (value.IsString()) {
|
||||
sprite = { value.GetString(), value.GetStringLength() };
|
||||
}
|
||||
}
|
||||
|
||||
void StyleParser::parseGlyphURL(const JSVal& value) {
|
||||
if (value.IsString()) {
|
||||
glyph_url = { value.GetString(), value.GetStringLength() };
|
||||
}
|
||||
}
|
||||
|
||||
void StyleParser::parseVisibility(StyleLayer& layer, const JSVal& value) {
|
||||
if (!value.HasMember("visibility")) {
|
||||
return;
|
||||
|
||||
@@ -31,20 +31,18 @@ public:
|
||||
return layers;
|
||||
}
|
||||
|
||||
std::string getSprite() const {
|
||||
return sprite;
|
||||
std::string getSpriteURL() const {
|
||||
return spriteURL;
|
||||
}
|
||||
|
||||
std::string getGlyphURL() const {
|
||||
return glyph_url;
|
||||
return glyphURL;
|
||||
}
|
||||
|
||||
private:
|
||||
void parseSources(const JSVal&);
|
||||
void parseLayers(const JSVal&);
|
||||
void parseLayer(const std::string& id, const JSVal&, util::ptr<StyleLayer>&);
|
||||
void parseSprite(const JSVal&);
|
||||
void parseGlyphURL(const JSVal&);
|
||||
void parseVisibility(StyleLayer&, const JSVal& value);
|
||||
|
||||
std::uint8_t version;
|
||||
@@ -58,11 +56,8 @@ private:
|
||||
// Store a stack of layer IDs we're parsing right now. This is to prevent reference cycles.
|
||||
std::forward_list<std::string> stack;
|
||||
|
||||
// Base URL of the sprite image.
|
||||
std::string sprite;
|
||||
|
||||
// URL template for glyph PBFs.
|
||||
std::string glyph_url;
|
||||
std::string spriteURL;
|
||||
std::string glyphURL;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
#include "../fixtures/fixture_log_observer.hpp"
|
||||
#include "../fixtures/mock_file_source.hpp"
|
||||
#include "../fixtures/util.hpp"
|
||||
|
||||
#include <mbgl/sprite/sprite.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/util/thread.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
using SpriteTestCallback = std::function<void(Sprite*, const Sprites&, std::exception_ptr)>;
|
||||
|
||||
struct SpriteParams {
|
||||
const std::string baseUrl;
|
||||
const float pixelRatio;
|
||||
};
|
||||
|
||||
class SpriteThread : public Sprite::Observer {
|
||||
public:
|
||||
SpriteThread(FileSource* fileSource, SpriteTestCallback callback) : callback_(callback) {
|
||||
util::ThreadContext::setFileSource(fileSource);
|
||||
}
|
||||
|
||||
void loadSprite(const SpriteParams& params) {
|
||||
sprite_.reset(new Sprite(params.baseUrl, params.pixelRatio));
|
||||
sprite_->setObserver(this);
|
||||
}
|
||||
|
||||
void unloadSprite() {
|
||||
sprite_->setObserver(nullptr);
|
||||
sprite_.reset();
|
||||
}
|
||||
|
||||
void onSpriteLoaded(const Sprites& sprites) override {
|
||||
callback_(sprite_.get(), sprites, nullptr);
|
||||
}
|
||||
|
||||
void onSpriteLoadingFailed(std::exception_ptr error) override {
|
||||
callback_(sprite_.get(), Sprites(), error);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Sprite> sprite_;
|
||||
SpriteTestCallback callback_;
|
||||
};
|
||||
|
||||
class SpriteTest : public testing::Test {
|
||||
protected:
|
||||
void runTest(const SpriteParams& params, FileSource* fileSource, SpriteTestCallback callback) {
|
||||
util::RunLoop loop(uv_default_loop());
|
||||
|
||||
async_ = std::make_unique<uv::async>(loop.get(), [&] { loop.stop(); });
|
||||
async_->unref();
|
||||
|
||||
const util::ThreadContext context = {"Map", util::ThreadType::Map, util::ThreadPriority::Regular};
|
||||
|
||||
util::Thread<SpriteThread> tester(context, fileSource, callback);
|
||||
tester.invoke(&SpriteThread::loadSprite, params);
|
||||
|
||||
uv_run(loop.get(), UV_RUN_DEFAULT);
|
||||
|
||||
tester.invoke(&SpriteThread::unloadSprite);
|
||||
}
|
||||
|
||||
void stopTest() {
|
||||
async_->send();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<uv::async> async_;
|
||||
};
|
||||
|
||||
TEST_F(SpriteTest, LoadingSuccess) {
|
||||
SpriteParams params = {
|
||||
"test/fixtures/resources/sprite",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this, ¶ms](Sprite* sprite, const Sprites& sprites, std::exception_ptr error) {
|
||||
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
ASSERT_TRUE(error == nullptr);
|
||||
|
||||
ASSERT_TRUE(!sprites.empty());
|
||||
|
||||
ASSERT_EQ(sprite->pixelRatio, params.pixelRatio);
|
||||
ASSERT_NE(sprite->pixelRatio, 1.5);
|
||||
ASSERT_NE(sprite->pixelRatio, 2.0);
|
||||
|
||||
ASSERT_TRUE(sprite->isLoaded());
|
||||
|
||||
stopTest();
|
||||
};
|
||||
|
||||
MockFileSource fileSource(MockFileSource::Success, "");
|
||||
runTest(params, &fileSource, callback);
|
||||
}
|
||||
|
||||
TEST_F(SpriteTest, LoadingFail) {
|
||||
SpriteParams params = {
|
||||
"test/fixtures/resources/sprite",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this, ¶ms](Sprite* sprite, const Sprites&, std::exception_ptr error) {
|
||||
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
ASSERT_TRUE(error != nullptr);
|
||||
|
||||
ASSERT_EQ(sprite->pixelRatio, params.pixelRatio);
|
||||
ASSERT_NE(sprite->pixelRatio, 1.5);
|
||||
ASSERT_NE(sprite->pixelRatio, 2.0);
|
||||
|
||||
ASSERT_FALSE(sprite->isLoaded());
|
||||
|
||||
stopTest();
|
||||
};
|
||||
|
||||
MockFileSource fileSourceFailSpriteJSON(MockFileSource::RequestFail, "sprite.json");
|
||||
runTest(params, &fileSourceFailSpriteJSON, callback);
|
||||
|
||||
MockFileSource fileSourceFailSpriteImage(MockFileSource::RequestFail, "sprite.png");
|
||||
runTest(params, &fileSourceFailSpriteImage, callback);
|
||||
|
||||
MockFileSource fileSourceCorruptedSpriteJSON(MockFileSource::RequestWithCorruptedData, "sprite.json");
|
||||
runTest(params, &fileSourceCorruptedSpriteJSON, callback);
|
||||
|
||||
MockFileSource fileSourceCorruptedSpriteImage(MockFileSource::RequestWithCorruptedData, "sprite.png");
|
||||
runTest(params, &fileSourceCorruptedSpriteImage, callback);
|
||||
}
|
||||
|
||||
TEST_F(SpriteTest, LoadingCancel) {
|
||||
SpriteParams params = {
|
||||
"test/fixtures/resources/sprite",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this](Sprite*, const Sprites&, std::exception_ptr) {
|
||||
FAIL() << "Should never be called";
|
||||
};
|
||||
|
||||
MockFileSource fileSourceDelaySpriteJSON(MockFileSource::SuccessWithDelay, "sprite.json");
|
||||
fileSourceDelaySpriteJSON.setOnRequestDelayedCallback([this]{
|
||||
stopTest();
|
||||
});
|
||||
runTest(params, &fileSourceDelaySpriteJSON, callback);
|
||||
|
||||
MockFileSource fileSourceDelaySpriteImage(MockFileSource::SuccessWithDelay, "sprite.png");
|
||||
fileSourceDelaySpriteImage.setOnRequestDelayedCallback([this]{
|
||||
stopTest();
|
||||
});
|
||||
runTest(params, &fileSourceDelaySpriteImage, callback);
|
||||
}
|
||||
|
||||
TEST_F(SpriteTest, InvalidURL) {
|
||||
SpriteParams params = {
|
||||
"foo bar",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this](Sprite* sprite, const Sprites&, std::exception_ptr error) {
|
||||
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
ASSERT_TRUE(error != nullptr);
|
||||
|
||||
ASSERT_EQ(sprite->isLoaded(), false);
|
||||
|
||||
stopTest();
|
||||
};
|
||||
|
||||
MockFileSource fileSource(MockFileSource::Success, "");
|
||||
runTest(params, &fileSource, callback);
|
||||
}
|
||||
@@ -15,7 +15,7 @@ TEST(Sprite, SpriteAtlas) {
|
||||
auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
|
||||
util::read_file("test/fixtures/annotations/emerald.json"));
|
||||
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
store.setSprites(spriteParseResult.get<Sprites>());
|
||||
|
||||
SpriteAtlas atlas(63, 112, 1, store);
|
||||
@@ -90,7 +90,7 @@ TEST(Sprite, SpriteAtlasSize) {
|
||||
auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
|
||||
util::read_file("test/fixtures/annotations/emerald.json"));
|
||||
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
store.setSprites(spriteParseResult.get<Sprites>());
|
||||
|
||||
SpriteAtlas atlas(63, 112, 1.4, store);
|
||||
@@ -124,7 +124,7 @@ TEST(Sprite, SpriteAtlasSize) {
|
||||
}
|
||||
|
||||
TEST(Sprite, SpriteAtlasUpdates) {
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
|
||||
SpriteAtlas atlas(32, 32, 1, store);
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#include "../fixtures/util.hpp"
|
||||
#include "../fixtures/fixture_log_observer.hpp"
|
||||
#include "../fixtures/mock_file_source.hpp"
|
||||
|
||||
#include <mbgl/sprite/sprite_store.hpp>
|
||||
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/util/thread.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(Sprite, SpriteStore) {
|
||||
@@ -13,7 +17,7 @@ TEST(Sprite, SpriteStore) {
|
||||
const auto sprite3 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
|
||||
|
||||
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
|
||||
// Adding single
|
||||
store.setSprite("one", sprite1);
|
||||
@@ -77,7 +81,7 @@ TEST(Sprite, SpriteStoreOtherPixelRatio) {
|
||||
const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 1, std::string(8 * 8 * 4, '\0'));
|
||||
|
||||
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
|
||||
// Adding mismatched sprite image
|
||||
store.setSprite("one", sprite1);
|
||||
@@ -89,7 +93,7 @@ TEST(Sprite, SpriteStoreMultiple) {
|
||||
const auto sprite2 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
|
||||
|
||||
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
|
||||
store.setSprites({
|
||||
{ "one", sprite1 }, { "two", sprite2 },
|
||||
@@ -108,7 +112,7 @@ TEST(Sprite, SpriteStoreReplace) {
|
||||
const auto sprite2 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
|
||||
|
||||
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
|
||||
store.setSprite("sprite", sprite1);
|
||||
EXPECT_EQ(sprite1, store.getSprite("sprite"));
|
||||
@@ -125,7 +129,7 @@ TEST(Sprite, SpriteStoreReplaceWithDifferentDimensions) {
|
||||
const auto sprite2 = std::make_shared<SpriteImage>(9, 9, 2, std::string(18 * 18 * 4, '\0'));
|
||||
|
||||
using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
|
||||
SpriteStore store;
|
||||
SpriteStore store(1);
|
||||
|
||||
store.setSprite("sprite", sprite1);
|
||||
store.setSprite("sprite", sprite2);
|
||||
@@ -141,3 +145,168 @@ TEST(Sprite, SpriteStoreReplaceWithDifferentDimensions) {
|
||||
|
||||
EXPECT_EQ(Sprites({ { "sprite", sprite1 } }), store.getDirty());
|
||||
}
|
||||
|
||||
using SpriteTestCallback = std::function<void(SpriteStore*, std::exception_ptr)>;
|
||||
|
||||
struct SpriteParams {
|
||||
const std::string baseUrl;
|
||||
const float pixelRatio;
|
||||
};
|
||||
|
||||
class SpriteThread : public SpriteStore::Observer {
|
||||
public:
|
||||
SpriteThread(FileSource* fileSource, SpriteTestCallback callback) : callback_(callback) {
|
||||
util::ThreadContext::setFileSource(fileSource);
|
||||
}
|
||||
|
||||
void loadSprite(const SpriteParams& params) {
|
||||
spriteStore_.reset(new SpriteStore(params.pixelRatio));
|
||||
spriteStore_->setObserver(this);
|
||||
spriteStore_->setURL(params.baseUrl);
|
||||
}
|
||||
|
||||
void unloadSprite() {
|
||||
spriteStore_->setObserver(nullptr);
|
||||
spriteStore_.reset();
|
||||
}
|
||||
|
||||
void onSpriteLoaded() override {
|
||||
callback_(spriteStore_.get(), nullptr);
|
||||
}
|
||||
|
||||
void onSpriteLoadingFailed(std::exception_ptr error) override {
|
||||
callback_(spriteStore_.get(), error);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<SpriteStore> spriteStore_;
|
||||
SpriteTestCallback callback_;
|
||||
};
|
||||
|
||||
class SpriteTest : public testing::Test {
|
||||
protected:
|
||||
void runTest(const SpriteParams& params, FileSource* fileSource, SpriteTestCallback callback) {
|
||||
util::RunLoop loop(uv_default_loop());
|
||||
|
||||
async_ = std::make_unique<uv::async>(loop.get(), [&] { loop.stop(); });
|
||||
async_->unref();
|
||||
|
||||
const util::ThreadContext context = {"Map", util::ThreadType::Map, util::ThreadPriority::Regular};
|
||||
|
||||
util::Thread<SpriteThread> tester(context, fileSource, callback);
|
||||
tester.invoke(&SpriteThread::loadSprite, params);
|
||||
|
||||
uv_run(loop.get(), UV_RUN_DEFAULT);
|
||||
|
||||
tester.invoke(&SpriteThread::unloadSprite);
|
||||
}
|
||||
|
||||
void stopTest() {
|
||||
async_->send();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<uv::async> async_;
|
||||
};
|
||||
|
||||
TEST_F(SpriteTest, LoadingSuccess) {
|
||||
SpriteParams params = {
|
||||
"test/fixtures/resources/sprite",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this, ¶ms](SpriteStore* spriteStore, std::exception_ptr error) {
|
||||
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
ASSERT_TRUE(error == nullptr);
|
||||
|
||||
ASSERT_TRUE(!spriteStore->getDirty().empty());
|
||||
|
||||
ASSERT_EQ(spriteStore->pixelRatio, params.pixelRatio);
|
||||
ASSERT_NE(spriteStore->pixelRatio, 1.5);
|
||||
ASSERT_NE(spriteStore->pixelRatio, 2.0);
|
||||
|
||||
ASSERT_TRUE(spriteStore->isLoaded());
|
||||
|
||||
stopTest();
|
||||
};
|
||||
|
||||
MockFileSource fileSource(MockFileSource::Success, "");
|
||||
runTest(params, &fileSource, callback);
|
||||
}
|
||||
|
||||
TEST_F(SpriteTest, LoadingFail) {
|
||||
SpriteParams params = {
|
||||
"test/fixtures/resources/sprite",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this, ¶ms](SpriteStore* spriteStore, std::exception_ptr error) {
|
||||
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
ASSERT_TRUE(error != nullptr);
|
||||
|
||||
ASSERT_EQ(spriteStore->pixelRatio, params.pixelRatio);
|
||||
ASSERT_NE(spriteStore->pixelRatio, 1.5);
|
||||
ASSERT_NE(spriteStore->pixelRatio, 2.0);
|
||||
|
||||
ASSERT_FALSE(spriteStore->isLoaded());
|
||||
|
||||
stopTest();
|
||||
};
|
||||
|
||||
MockFileSource fileSourceFailSpriteJSON(MockFileSource::RequestFail, "sprite.json");
|
||||
runTest(params, &fileSourceFailSpriteJSON, callback);
|
||||
|
||||
MockFileSource fileSourceFailSpriteImage(MockFileSource::RequestFail, "sprite.png");
|
||||
runTest(params, &fileSourceFailSpriteImage, callback);
|
||||
|
||||
MockFileSource fileSourceCorruptedSpriteJSON(MockFileSource::RequestWithCorruptedData, "sprite.json");
|
||||
runTest(params, &fileSourceCorruptedSpriteJSON, callback);
|
||||
|
||||
MockFileSource fileSourceCorruptedSpriteImage(MockFileSource::RequestWithCorruptedData, "sprite.png");
|
||||
runTest(params, &fileSourceCorruptedSpriteImage, callback);
|
||||
}
|
||||
|
||||
TEST_F(SpriteTest, LoadingCancel) {
|
||||
SpriteParams params = {
|
||||
"test/fixtures/resources/sprite",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this](SpriteStore*, std::exception_ptr) {
|
||||
FAIL() << "Should never be called";
|
||||
};
|
||||
|
||||
MockFileSource fileSourceDelaySpriteJSON(MockFileSource::SuccessWithDelay, "sprite.json");
|
||||
fileSourceDelaySpriteJSON.setOnRequestDelayedCallback([this]{
|
||||
stopTest();
|
||||
});
|
||||
runTest(params, &fileSourceDelaySpriteJSON, callback);
|
||||
|
||||
MockFileSource fileSourceDelaySpriteImage(MockFileSource::SuccessWithDelay, "sprite.png");
|
||||
fileSourceDelaySpriteImage.setOnRequestDelayedCallback([this]{
|
||||
stopTest();
|
||||
});
|
||||
runTest(params, &fileSourceDelaySpriteImage, callback);
|
||||
}
|
||||
|
||||
TEST_F(SpriteTest, InvalidURL) {
|
||||
SpriteParams params = {
|
||||
"foo bar",
|
||||
1.0,
|
||||
};
|
||||
|
||||
auto callback = [this](SpriteStore* spriteStore, std::exception_ptr error) {
|
||||
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
ASSERT_TRUE(error != nullptr);
|
||||
|
||||
ASSERT_EQ(spriteStore->isLoaded(), false);
|
||||
|
||||
stopTest();
|
||||
};
|
||||
|
||||
MockFileSource fileSource(MockFileSource::Success, "");
|
||||
runTest(params, &fileSource, callback);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
'style/pending_resources.cpp',
|
||||
'style/resource_loading.cpp',
|
||||
|
||||
'sprite/sprite.cpp',
|
||||
'sprite/sprite_atlas.cpp',
|
||||
'sprite/sprite_image.cpp',
|
||||
'sprite/sprite_parser.cpp',
|
||||
|
||||
Reference in New Issue
Block a user