Merge branch 'master' into fuzz-pipe

Conflicts:
	test/test.gyp
This commit is contained in:
Mike Morris
2014-07-15 11:16:54 -04:00
24 changed files with 274 additions and 179 deletions

View File

@@ -42,7 +42,7 @@ xtest: config.gypi clear_xcode_cache node
# Builds the linux app with make. This is also used by Travis CI
linux: config.gypi linux/llmr-app.gyp node
deps/run_gyp linux/llmr-app.gyp --depth=. -Goutput_dir=.. --generator-output=./build/linux -f make
$(MAKE) -C build/linux BUILDTYPE=Testing V=$(V) linuxapp
$(MAKE) -C build/linux BUILDTYPE=$(BUILDTYPE) V=$(V) linuxapp
# Executes the Linux binary
run-linux: linux

View File

@@ -31,13 +31,12 @@ This will clear cached build data and update to the latest versions of dependenc
The demo applications use Mapbox vector tiles, which **require a Mapbox account and API access token**. Obtain an access token on the [Mapbox account page](https://www.mapbox.com/account/apps/).
For iOS and OS X use of the demo apps in Xcode, setup the access token by editing the scheme for the application target, then adding an environment variable with the name `MAPBOX_ACCESS_TOKEN`.
![setting access token in Xcode scheme](https://cloud.githubusercontent.com/assets/52399/3543326/9e7cfbb8-0860-11e4-8def-3684a9028b61.png)
## OS X
in the Xcode project, click on the Target icon next to the Run/Stop button, and then "Edit Scheme". In the screen, add an environment variable with the name `MAPBOX_ACCESS_TOKEN` to the targets you want to run.
![Setting the access token](https://cloud.githubusercontent.com/assets/52399/3543326/9e7cfbb8-0860-11e4-8def-3684a9028b61.png)
Run:
make setup
@@ -61,8 +60,6 @@ First, pull down the submodule(s):
git submodule init
git submodule update
Insert your access token into `MBXViewController.h`.
Then run:
make setup

View File

@@ -7,7 +7,7 @@
namespace llmr {
void NSLogBackend::record(EventSeverity severity, Event event, const std::string &msg) {
NSLog(@"[%s] %s: %@", stringifyEventSeverity(severity), stringifyEvent(event),
NSLog(@"[%s] %s: %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(),
[[NSString alloc] initWithBytes:msg.data()
length:msg.size()
encoding:NSUTF8StringEncoding]);
@@ -23,15 +23,15 @@ void NSLogBackend::record(EventSeverity severity, Event event, const char* forma
va_start(args, format);
vsnprintf(buffer.get(), len + 1, format, args);
va_end(args);
NSLog(@"[%s] %s: %s", stringifyEventSeverity(severity), stringifyEvent(event), buffer.get());
NSLog(@"[%s] %s: %s", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), buffer.get());
}
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code) {
NSLog(@"[%s] %s: (%lld)", stringifyEventSeverity(severity), stringifyEvent(event), code);
NSLog(@"[%s] %s: (%lld)", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), code);
}
void NSLogBackend::record(EventSeverity severity, Event event, int64_t code, const std::string &msg) {
NSLog(@"[%s] %s: (%lld) %@", stringifyEventSeverity(severity), stringifyEvent(event), code,
NSLog(@"[%s] %s: (%lld) %@", EventSeverityClass(severity).c_str(), EventClass(event).c_str(), code,
[[NSString alloc] initWithBytes:msg.data()
length:msg.size()
encoding:NSUTF8StringEncoding]);

View File

@@ -52,7 +52,7 @@ public:
void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height);
// Styling
const std::set<std::shared_ptr<Source>> getActiveSources() const;
const std::set<std::shared_ptr<StyleSource>> getActiveSources() const;
void setAppliedClasses(const std::vector<std::string> &classes);
void toggleClass(const std::string &name);
const std::vector<std::string> &getAppliedClasses() const;
@@ -178,7 +178,7 @@ private:
int indent = 0;
std::set<std::shared_ptr<Source>> activeSources;
std::set<std::shared_ptr<StyleSource>> activeSources;
private:
bool async = false;

View File

@@ -1,8 +1,9 @@
#ifndef LLMR_PLATFORM_EVENT
#define LLMR_PLATFORM_EVENT
#include <llmr/util/enum.hpp>
#include <cstdint>
#include <ostream>
namespace llmr {
@@ -14,9 +15,14 @@ enum class EventSeverity : uint8_t {
Error,
};
EventSeverity parseEventSeverity(const char *name);
const char *stringifyEventSeverity(EventSeverity eventSeverity);
::std::ostream& operator<<(::std::ostream& os, EventSeverity eventSeverity);
LLMR_DEFINE_ENUM_CLASS(EventSeverityClass, EventSeverity, {
{ EventSeverity::Debug, "DEBUG" },
{ EventSeverity::Info, "INFO" },
{ EventSeverity::Test, "TEST" },
{ EventSeverity::Warning, "WARNING" },
{ EventSeverity::Error, "ERROR" },
{ EventSeverity(-1), "UNKNOWN" },
});
enum class Event : uint8_t {
General,
@@ -28,9 +34,17 @@ enum class Event : uint8_t {
HttpRequest,
};
Event parseEvent(const char *name);
const char *stringifyEvent(Event event);
::std::ostream& operator<<(::std::ostream& os, Event event);
LLMR_DEFINE_ENUM_CLASS(EventClass, Event, {
{ Event::General, "General" },
{ Event::Setup, "Setup" },
{ Event::Shader, "Shader" },
{ Event::ParseStyle, "ParseStyle" },
{ Event::ParseTile, "ParseTile" },
{ Event::Render, "Render" },
{ Event::HttpRequest, "HttpRequest" },
{ Event(-1), "Unknown" },
});
struct EventPermutation {
const EventSeverity severity;

View File

@@ -34,6 +34,7 @@ class Style;
class Tile;
class GlyphAtlas;
class Source;
class StyleSource;
class FillBucket;
class LineBucket;
@@ -106,7 +107,7 @@ public:
// Configures the painter strata that is used for early z-culling of fragments.
void setStrata(float strata);
void drawClippingMasks(const std::set<std::shared_ptr<Source>> &sources);
void drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &sources);
void drawClippingMask(const mat4& matrix, const ClipID& clip);
void clearFramebuffers();

View File

@@ -76,7 +76,6 @@ public:
std::string name;
std::shared_ptr<StyleSource> style_source;
std::shared_ptr<Source> source;
std::string source_layer;
FilterExpression filter;
StyleBucketRender render = std::false_type();

View File

@@ -3,25 +3,27 @@
#include <llmr/style/types.hpp>
#include <memory>
namespace llmr {
struct StyleSource {
const SourceType type;
const std::string url;
const uint32_t tile_size;
const int32_t min_zoom;
const int32_t max_zoom;
class Source;
StyleSource(SourceType type = SourceType::Vector,
const std::string &url = "",
uint32_t tile_size = 512, uint32_t min_zoom = 0,
uint32_t max_zoom = 22)
: type(type),
url(url),
tile_size(tile_size),
min_zoom(min_zoom),
max_zoom(max_zoom) {}
};
class StyleSource {
public:
const SourceType type;
const std::string url;
const uint32_t tile_size;
const int32_t min_zoom;
const int32_t max_zoom;
bool enabled = false;
std::shared_ptr<Source> source;
StyleSource(SourceType type = SourceType::Vector, const std::string &url = "",
uint32_t tile_size = 512, uint32_t min_zoom = 0, uint32_t max_zoom = 22)
: type(type), url(url), tile_size(tile_size), min_zoom(min_zoom), max_zoom(max_zoom) {}
};
};
#endif

View File

@@ -1,6 +1,8 @@
#ifndef LLMR_STYLE_TYPES
#define LLMR_STYLE_TYPES
#include <llmr/util/enum.hpp>
#include <string>
#include <array>
@@ -20,9 +22,17 @@ enum class StyleLayerType : uint8_t {
Background
};
StyleLayerType parseStyleLayerType(const std::string &type);
const char *stringifyStyleLayerType(StyleLayerType type);
std::ostream& operator<<(std::ostream&, StyleLayerType type);
LLMR_DEFINE_ENUM_CLASS(StyleLayerTypeClass, StyleLayerType, {
{ StyleLayerType::Unknown, "unknown" },
{ StyleLayerType::Fill, "fill" },
{ StyleLayerType::Line, "line" },
{ StyleLayerType::Icon, "icon" },
{ StyleLayerType::Text, "text" },
{ StyleLayerType::Raster, "raster" },
{ StyleLayerType::Composite, "composite" },
{ StyleLayerType::Background, "background" },
{ StyleLayerType(-1), "unknown" },
});
enum class WindingType : uint8_t {

View File

@@ -0,0 +1,55 @@
#ifndef LLMR_UTIL_ENUM
#define LLMR_UTIL_ENUM
#include <iosfwd>
#include <string>
namespace llmr {
template <typename Type>
struct EnumValue {
const Type value;
const char *name;
};
template <typename EnumName, const EnumValue<EnumName> *names, const size_t length>
struct Enum {
using Type = EnumName;
Type value;
static const constexpr size_t l = length;
private:
static constexpr inline bool compare(const char *a, const char *b) {
return *a == *b && (*a == '\0' || compare(a + 1, b + 1));
}
static constexpr inline const char *lookup_type(Type e, EnumValue<Type> const * const l, size_t r) {
return r == 0 ? "" : l->value == e ? l->name : lookup_type(e, l + 1, r - 1);
}
static constexpr inline Type lookup_name(const char *n, EnumValue<Type> const * const l, size_t r) {
return r == 0 ? Type(-1) : compare(l->name, n) ? l->value : lookup_name(n, l + 1, r - 1);
}
public:
inline constexpr Enum(const char *n) : value(lookup_name(n, names, length)) {}
inline constexpr Enum(const std::string &n) : value(lookup_name(n.c_str(), names, length)) {}
inline constexpr Enum(Type t) : value(t) {}
inline void operator=(const char *n) { value = lookup_name(n, names, length); }
inline void operator=(const std::string &n) { *this = n.c_str(); }
inline void operator=(Type t) { value = t; }
inline constexpr bool valid() const { return value != Type(-1); }
inline constexpr const char *c_str() const { return lookup_type(value, names, length); }
inline std::string str() const { return c_str(); }
inline constexpr operator Type() const { return value; }
};
#define LLMR_DEFINE_ENUM_CLASS(name, type, strings...) \
const constexpr ::llmr::EnumValue<type> type##_names[] = strings; \
using name = ::llmr::Enum<type, type##_names, sizeof(type##_names) / sizeof(::llmr::EnumValue<type>)>; \
inline std::ostream& operator<<(std::ostream& os, type t) { return os << name(t).str(); }
}
#endif

View File

@@ -11,6 +11,10 @@ template<typename T, typename ...Args>
return ::std::unique_ptr<T>(new T(::std::forward<Args>(args)...));
}
}
namespace llmr {
namespace util {
template <typename Container, typename ForwardIterator, typename Predicate>
void erase_if(Container &container, ForwardIterator it, const ForwardIterator end, Predicate pred) {
@@ -28,6 +32,7 @@ void erase_if(Container &container, Predicate pred) {
erase_if(container, container.begin(), container.end(), pred);
}
}
}
#endif

View File

@@ -17,12 +17,9 @@ int main() {
map.setDebug(settings.debug);
// Set access token if present
const char *token = getenv("MAPBOX_ACCESS_TOKEN");
if (token == nullptr) {
llmr::Log::Warning(llmr::Event::Setup, "no access token set. mapbox.com tiles won't work.");
} else {
map.setAccessToken(std::string(token));
}
NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
if ( ! accessToken) llmr::Log::Warning(llmr::Event::Setup, "No access token set. Mapbox vector tiles won't work.");
if (accessToken) map.setAccessToken([accessToken cStringUsingEncoding:[NSString defaultCStringEncoding]]);
// Load style
NSString *path = [[NSBundle mainBundle] pathForResource:@"style.min" ofType:@"js"];

View File

@@ -228,7 +228,7 @@ void SpriteAtlas::update(const Sprite &sprite) {
if (!sprite.isLoaded()) return;
SpriteAtlas &atlas = *this;
std::erase_if(uninitialized, [&sprite, &atlas](const std::string &name) {
util::erase_if(uninitialized, [&sprite, &atlas](const std::string &name) {
Rect<dimension> dst = atlas.getImage(name, sprite);
const SpritePosition &src = sprite.getSpritePosition(name);
if (!src) {

View File

@@ -9,6 +9,7 @@
#include <llmr/util/string.hpp>
#include <llmr/util/constants.hpp>
#include <llmr/util/uv.hpp>
#include <llmr/util/std.hpp>
#include <llmr/style/style_layer_group.hpp>
#include <llmr/style/style_bucket.hpp>
#include <llmr/geometry/sprite_atlas.hpp>
@@ -410,11 +411,32 @@ void Map::setDefaultTransitionDuration(uint64_t duration_milliseconds) {
}
void Map::updateSources() {
activeSources.clear();
// First, disable all existing sources.
for (const std::shared_ptr<StyleSource> &source : activeSources) {
source->enabled = false;
}
// Then, reenable all of those that we actually use when drawing this layer.
updateSources(style->layers);
// Then, construct or destroy the actual source object, depending on enabled state.
for (const std::shared_ptr<StyleSource> &source : activeSources) {
if (source->enabled) {
if (!source->source) {
source->source = std::make_shared<Source>(*source, getAccessToken());
}
} else {
source->source.reset();
}
}
// Finally, remove all sources that are disabled.
util::erase_if(activeSources, [](std::shared_ptr<StyleSource> source){
return !source->enabled;
});
}
const std::set<std::shared_ptr<Source>> Map::getActiveSources() const {
const std::set<std::shared_ptr<StyleSource>> Map::getActiveSources() const {
return activeSources;
}
@@ -426,8 +448,7 @@ void Map::updateSources(const std::shared_ptr<StyleLayerGroup> &group) {
if (!layer) continue;
if (layer->bucket) {
if (layer->bucket->style_source) {
auto ret = activeSources.emplace(std::make_shared<Source>(*layer->bucket->style_source, this->getAccessToken()));
layer->bucket->source = *ret.first;
(*activeSources.emplace(layer->bucket->style_source).first)->enabled = true;
}
} else if (layer->layers) {
updateSources(layer->layers);
@@ -436,23 +457,23 @@ void Map::updateSources(const std::shared_ptr<StyleLayerGroup> &group) {
}
void Map::updateTiles() {
for (const std::shared_ptr<Source> &source : getActiveSources()) {
source->update(*this);
for (const std::shared_ptr<StyleSource> &source : getActiveSources()) {
source->source->update(*this);
}
}
void Map::updateRenderState() {
std::forward_list<Tile::ID> ids;
for (const std::shared_ptr<Source> &source : getActiveSources()) {
ids.splice_after(ids.before_begin(), source->getIDs());
source->updateMatrices(painter.projMatrix, state);
for (const std::shared_ptr<StyleSource> &source : getActiveSources()) {
ids.splice_after(ids.before_begin(), source->source->getIDs());
source->source->updateMatrices(painter.projMatrix, state);
}
const std::map<Tile::ID, ClipID> clipIDs = computeClipIDs(ids);
for (const std::shared_ptr<Source> &source : getActiveSources()) {
source->updateClipIDs(clipIDs);
for (const std::shared_ptr<StyleSource> &source : getActiveSources()) {
source->source->updateClipIDs(clipIDs);
}
}
@@ -531,8 +552,8 @@ void Map::render() {
// This guarantees that we have at least one function per tile called.
// When only rendering layers via the stylesheet, it's possible that we don't
// ever visit a tile during rendering.
for (const std::shared_ptr<Source> &source : getActiveSources()) {
source->finishRender(painter);
for (const std::shared_ptr<StyleSource> &source : getActiveSources()) {
source->source->finishRender(painter);
}
painter.renderMatte();
@@ -629,6 +650,8 @@ void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass) {
return;
}
StyleSource &style_source = *layer_desc->bucket->style_source;
// Abort early if we can already deduce from the bucket type that
// we're not going to render anything anyway during this pass.
switch (layer_desc->type) {
@@ -660,6 +683,8 @@ void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass) {
<< layer_desc->type << ")" << std::endl;
}
layer_desc->bucket->source->render(painter, layer_desc);
if (style_source.source) {
style_source.source->render(painter, layer_desc);
}
}
}

View File

@@ -284,7 +284,7 @@ bool Source::updateTiles(Map &map) {
// Remove tiles that we definitely don't need, i.e. tiles that are not on
// the required list.
std::set<Tile::ID> retain_data;
std::erase_if(tiles, [&retain, &retain_data, &changed](std::pair<const Tile::ID, std::unique_ptr<Tile>> &pair) {
util::erase_if(tiles, [&retain, &retain_data, &changed](std::pair<const Tile::ID, std::unique_ptr<Tile>> &pair) {
Tile &tile = *pair.second;
bool obsolete = std::find(retain.begin(), retain.end(), tile.id) == retain.end();
if (obsolete) {
@@ -296,7 +296,7 @@ bool Source::updateTiles(Map &map) {
});
// Remove all the expired pointers from the set.
std::erase_if(tile_data, [&retain_data](std::pair<const Tile::ID, std::weak_ptr<TileData>> &pair) {
util::erase_if(tile_data, [&retain_data](std::pair<const Tile::ID, std::weak_ptr<TileData>> &pair) {
const std::shared_ptr<TileData> tile = pair.second.lock();
if (!tile) {
return true;

View File

@@ -1,60 +0,0 @@
#include <llmr/platform/event.hpp>
#include <cstring>
namespace llmr {
EventSeverity parseEventSeverity(const char *name) {
if (strcmp(name, "DEBUG") == 0) return EventSeverity::Debug;
if (strcmp(name, "INFO") == 0) return EventSeverity::Info;
if (strcmp(name, "TEST") == 0) return EventSeverity::Test;
if (strcmp(name, "WARNING") == 0) return EventSeverity::Warning;
if (strcmp(name, "ERROR") == 0) return EventSeverity::Error;
return EventSeverity(-1);
}
const char *stringifyEventSeverity(EventSeverity eventSeverity) {
switch (eventSeverity) {
case EventSeverity::Debug: return "DEBUG";
case EventSeverity::Info: return "INFO";
case EventSeverity::Test: return "TEST";
case EventSeverity::Warning: return "WARNING";
case EventSeverity::Error: return "ERROR";
default: return "UNKNOWN";
}
}
::std::ostream& operator<<(::std::ostream& os, EventSeverity eventSeverity) {
return os << stringifyEventSeverity(eventSeverity);
}
Event parseEvent(const char *name) {
if (strcmp(name, "General") == 0) return Event::General;
if (strcmp(name, "Setup") == 0) return Event::Setup;
if (strcmp(name, "Shader") == 0) return Event::Shader;
if (strcmp(name, "ParseStyle") == 0) return Event::ParseStyle;
if (strcmp(name, "ParseTile") == 0) return Event::ParseTile;
if (strcmp(name, "Render") == 0) return Event::Render;
if (strcmp(name, "HttpRequest") == 0) return Event::HttpRequest;
return Event(-1);
}
const char *stringifyEvent(Event event) {
switch (event) {
case Event::General: return "General";
case Event::Setup: return "Setup";
case Event::Shader: return "Shader";
case Event::ParseStyle: return "ParseStyle";
case Event::ParseTile: return "ParseTile";
case Event::Render: return "Render";
case Event::HttpRequest: return "HttpRequest";
default: return "Unknown";
}
}
::std::ostream& operator<<(::std::ostream& os, Event event) {
return os << stringifyEvent(event);
}
}

View File

@@ -6,7 +6,7 @@
using namespace llmr;
void Painter::drawClippingMasks(const std::set<std::shared_ptr<Source>> &sources) {
void Painter::drawClippingMasks(const std::set<std::shared_ptr<StyleSource>> &sources) {
gl::group group("clipping masks");
useProgram(plainShader->program);
@@ -18,8 +18,8 @@ void Painter::drawClippingMasks(const std::set<std::shared_ptr<Source>> &sources
coveringPlainArray.bind(*plainShader, tileStencilBuffer, BUFFER_OFFSET(0));
for (const std::shared_ptr<Source> &source : sources) {
source->drawClippingMasks(*this);
for (const std::shared_ptr<StyleSource> &source : sources) {
source->source->drawClippingMasks(*this);
}
glEnable(GL_DEPTH_TEST);

View File

@@ -2,6 +2,7 @@
#include <llmr/renderer/text_bucket.hpp>
#include <llmr/style/style_layer.hpp>
#include <llmr/map/map.hpp>
#include <llmr/util/math.hpp>
#include <cmath>
using namespace llmr;
@@ -88,12 +89,37 @@ void Painter::renderText(TextBucket& bucket, std::shared_ptr<StyleLayer> layer_d
textShader->setMaxFadeZoom(std::floor(highZ * 10));
textShader->setFadeZoom((map.getState().getNormalizedZoom() + bump) * 10);
// This defines the gamma around the SDF cutoff value.
const float sdfGamma = 0.75f / 10.0f;
// Our signed distance fields are scaled so that 1 pixel is scaled to 32 pixels.
// Our cutoff between positive and negative values is hard coded to 64 (== 2 pixels).
// This means that our 6/8 of the value range lies outside the glyph outline.
const float sdfOffset = (256.0f - 64.0f) / 32.0f;
// Currently, all of our fonts are rendered with a font size of 24px.
const float sdfFontSize = 24.0f;
// The default gamma value has to be adjust for the current pixelratio so that we're not drawing
// blurry font on retina screens.
const float gamma = sdfGamma * sdfFontSize / fontSize / map.getState().getPixelRatio();
// We're drawing in the translucent pass which is bottom-to-top, so we need
// to draw the halo first.
if (properties.halo_color[3] > 0.0f) {
// TODO: Get rid of the 2.4 magic value. It is currently 24 / 10, with 24 being the font size
// of the SDF glyphs.
textShader->setGamma(properties.halo_blur * 2.4f / fontSize / map.getState().getPixelRatio());
const float haloWidth = util::clamp((sdfOffset - properties.halo_width / (fontSize / sdfFontSize)) / 8.0f, 0.0f, 1.0f);
if (properties.halo_blur != 0.0f) {
// We are converting the halo_blur value to current screen pixels.
// Then we're dividing it by two because the gamma value is added/subtracted into both
// directions in the shader, but the halo_blur describes the entire width of the blur.
// Note that this does *not* have to be adjusted for retina screens, because we want the
// same blur width when we explicitly specify one.
textShader->setGamma((properties.halo_blur / (fontSize / sdfFontSize)) / 8.0f / 2.0f);
} else {
textShader->setGamma(sdfGamma);
}
if (properties.opacity < 1.0f) {
Color color = properties.halo_color;
color[0] *= properties.opacity;
@@ -104,16 +130,14 @@ void Painter::renderText(TextBucket& bucket, std::shared_ptr<StyleLayer> layer_d
} else {
textShader->setColor(properties.halo_color);
}
textShader->setBuffer(properties.halo_width);
textShader->setBuffer(haloWidth);
glDepthRange(strata, 1.0f);
bucket.drawGlyphs(*textShader);
}
if (properties.color[3] > 0.0f) {
// Then, we draw the text over the halo
// TODO: Get rid of the 2.4 magic value. It is currently 24 / 10, with 24 being the font size
// of the SDF glyphs.
textShader->setGamma(2.4f / fontSize / map.getState().getPixelRatio());
textShader->setGamma(gamma);
if (properties.opacity < 1.0f) {
Color color = properties.color;
color[0] *= properties.opacity;

View File

@@ -4,6 +4,7 @@
#include <llmr/platform/log.hpp>
#include <cstring>
#include <cstdlib>
using namespace llmr;

View File

@@ -560,7 +560,7 @@ void StyleParser::parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair
if (!type.IsString()) {
Log::Warning(Event::ParseStyle, "layer type of '%s' must be a string", layer->id.c_str());
} else {
layer->type = parseStyleLayerType({ type.GetString(), type.GetStringLength() });
layer->type = StyleLayerTypeClass(std::string { type.GetString(), type.GetStringLength() });
}
}

View File

@@ -1,35 +0,0 @@
#include <llmr/style/types.hpp>
#include <iostream>
namespace llmr {
StyleLayerType parseStyleLayerType(const std::string &type) {
if (type == "fill") return StyleLayerType::Fill;
if (type == "line") return StyleLayerType::Line;
if (type == "icon") return StyleLayerType::Icon;
if (type == "text") return StyleLayerType::Text;
if (type == "raster") return StyleLayerType::Raster;
if (type == "composite") return StyleLayerType::Composite;
if (type == "background") return StyleLayerType::Background;
return StyleLayerType::Unknown;
}
const char *stringifyStyleLayerType(StyleLayerType type) {
switch (type) {
case StyleLayerType::Fill: return "fill";
case StyleLayerType::Line: return "line";
case StyleLayerType::Icon: return "icon";
case StyleLayerType::Text: return "text";
case StyleLayerType::Raster: return "raster";
case StyleLayerType::Composite: return "composite";
case StyleLayerType::Background: return "background";
default: return "unknown";
}
}
std::ostream& operator<<(std::ostream& os, StyleLayerType type) {
return os << stringifyStyleLayerType(type);
}
}

43
test/enums.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include <iostream>
#include "gtest/gtest.h"
#include <algorithm>
#include <llmr/style/types.hpp>
using namespace llmr;
TEST(Enums, StyleLayerType) {
std::cerr << StyleLayerType::Raster;
ASSERT_EQ(StyleLayerType::Unknown, StyleLayerTypeClass("unknown"));
ASSERT_EQ(StyleLayerType::Fill, StyleLayerTypeClass("fill"));
ASSERT_EQ(StyleLayerType::Line, StyleLayerTypeClass("line"));
ASSERT_EQ(StyleLayerType::Icon, StyleLayerTypeClass("icon"));
ASSERT_EQ(StyleLayerType::Text, StyleLayerTypeClass("text"));
ASSERT_EQ(StyleLayerType::Raster, StyleLayerTypeClass("raster"));
ASSERT_EQ(StyleLayerType::Composite, StyleLayerTypeClass("composite"));
ASSERT_EQ(StyleLayerType::Background, StyleLayerTypeClass("background"));
ASSERT_EQ(StyleLayerType::Unknown, StyleLayerTypeClass(StyleLayerType::Unknown));
ASSERT_EQ(StyleLayerType::Fill, StyleLayerTypeClass(StyleLayerType::Fill));
ASSERT_EQ(StyleLayerType::Line, StyleLayerTypeClass(StyleLayerType::Line));
ASSERT_EQ(StyleLayerType::Icon, StyleLayerTypeClass(StyleLayerType::Icon));
ASSERT_EQ(StyleLayerType::Text, StyleLayerTypeClass(StyleLayerType::Text));
ASSERT_EQ(StyleLayerType::Raster, StyleLayerTypeClass(StyleLayerType::Raster));
ASSERT_EQ(StyleLayerType::Composite, StyleLayerTypeClass(StyleLayerType::Composite));
ASSERT_EQ(StyleLayerType::Background, StyleLayerTypeClass(StyleLayerType::Background));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Unknown), StyleLayerTypeClass(StyleLayerType::Unknown));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Fill), StyleLayerTypeClass(StyleLayerType::Fill));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Line), StyleLayerTypeClass(StyleLayerType::Line));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Icon), StyleLayerTypeClass(StyleLayerType::Icon));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Text), StyleLayerTypeClass(StyleLayerType::Text));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Raster), StyleLayerTypeClass(StyleLayerType::Raster));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Composite), StyleLayerTypeClass(StyleLayerType::Composite));
ASSERT_EQ(StyleLayerTypeClass(StyleLayerType::Background), StyleLayerTypeClass(StyleLayerType::Background));
ASSERT_EQ(false, StyleLayerTypeClass("").valid());
ASSERT_EQ(false, StyleLayerTypeClass("Backgrund").valid());
}

View File

@@ -94,8 +94,8 @@ TEST_P(HeadlessTest, render) {
if (js_entry.Size() == 5) {
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString()),
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
js_entry[rapidjson::SizeType(3)].GetInt64(),
js_entry[rapidjson::SizeType(4)].GetString()
};
@@ -104,15 +104,15 @@ TEST_P(HeadlessTest, render) {
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
if (js_entry[rapidjson::SizeType(3)].IsString()) {
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString()),
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
js_entry[rapidjson::SizeType(3)].GetString()
};
ASSERT_EQ(count, log.count(message)) << "Message: " << message << "Full Log: " << std::endl << log.messages;
} else {
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString()),
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString()),
js_entry[rapidjson::SizeType(3)].GetInt64()
};
ASSERT_EQ(count, log.count(message)) << "Message: " << message << "Full Log: " << std::endl << log.messages;
@@ -120,8 +120,8 @@ TEST_P(HeadlessTest, render) {
} else if (js_entry.Size() == 3) {
const uint32_t count = js_entry[rapidjson::SizeType(0)].GetUint();
const FixtureLogBackend::LogMessage message {
parseEventSeverity(js_entry[rapidjson::SizeType(1)].GetString()),
parseEvent(js_entry[rapidjson::SizeType(2)].GetString())
EventSeverityClass(js_entry[rapidjson::SizeType(1)].GetString()),
EventClass(js_entry[rapidjson::SizeType(2)].GetString())
};
ASSERT_EQ(count, log.count(message)) << "Message: " << message << "Full Log: " << std::endl << log.messages;
} else {

View File

@@ -90,6 +90,22 @@
"../llmr.gyp:llmr-x86"
]
},
{
"target_name": "enums",
"product_name": "test_enums",
"type": "executable",
"libraries": [
"-lpthread",
],
"sources": [
"./main.cpp",
"./enums.cpp",
],
"dependencies": [
"../deps/gtest/gtest.gyp:gtest",
"../llmr.gyp:llmr-x86"
]
},
{
"target_name": "style",
"product_name": "test_style",
@@ -185,6 +201,7 @@
"dependencies": [
"rotation_range",
"clip_ids",
"enums",
"variant",
"tile",
"functions",