[general] moving ios and android project under ./platform folder
This commit is contained in:
74
include/mbgl/actor/actor.hpp
Normal file
74
include/mbgl/actor/actor.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/actor/aspiring_actor.hpp>
|
||||
#include <mbgl/actor/established_actor.hpp>
|
||||
#include <mbgl/actor/mailbox.hpp>
|
||||
#include <mbgl/actor/message.hpp>
|
||||
#include <mbgl/actor/actor_ref.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/*
|
||||
An `Actor<O>` is an owning reference to an asynchronous object of type `O`: an "actor".
|
||||
Communication with an actor happens via message passing: you send a message to the object
|
||||
(using `invoke`), passing a pointer to the member function to call and arguments which
|
||||
are then forwarded to the actor.
|
||||
|
||||
The actor receives messages sent to it asynchronously, in a manner defined its `Scheduler`.
|
||||
To store incoming messages before their receipt, each actor has a `Mailbox`, which acts as
|
||||
a FIFO queue. Messages sent from actor S to actor R are guaranteed to be processed in the
|
||||
order sent. However, relative order of messages sent by two *different* actors S1 and S2
|
||||
to R is *not* guaranteed (and can't be: S1 and S2 may be acting asynchronously with respect
|
||||
to each other).
|
||||
|
||||
An `Actor<O>` can be converted to an `ActorRef<O>`, a non-owning value object representing
|
||||
a (weak) reference to the actor. Messages can be sent via the `Ref` as well.
|
||||
|
||||
It's safe -- and encouraged -- to pass `Ref`s between actors via messages. This is how two-way
|
||||
communication and other forms of collaboration between multiple actors is accomplished.
|
||||
|
||||
It's safe for a `Ref` to outlive its `Actor` -- the reference is "weak", and does not extend
|
||||
the lifetime of the owning Actor, and sending a message to a `Ref` whose `Actor` has died is
|
||||
a no-op. (In the future, a dead-letters queue or log may be implemented.)
|
||||
|
||||
Construction and destruction of an Actor is synchronous: the corresponding `O`
|
||||
object is constructed synchronously by the `Actor` constructor, and destructed synchronously
|
||||
by the `~Actor` destructor, after ensuring that the `O` is not currently receiving an
|
||||
asynchronous message. The constructor of `O` is passed an `ActorRef<O>` referring to itself
|
||||
(which it can use to self-send messages), followed by the forwarded arguments passed to
|
||||
`Actor<O>`. Asynchronous object construction can be accomplished by directly using the
|
||||
lower-level types, `AspiringActor<O>` and `EstablishedActor<O>`.
|
||||
|
||||
Please don't send messages that contain shared pointers or references. That subverts the
|
||||
purpose of the actor model: prohibiting direct concurrent access to shared state.
|
||||
*/
|
||||
template <class Object>
|
||||
class Actor {
|
||||
public:
|
||||
template <class... Args>
|
||||
Actor(Scheduler& scheduler, Args&&... args)
|
||||
: target(scheduler, parent, std::forward<Args>(args)...) {}
|
||||
|
||||
template <class... Args>
|
||||
Actor(std::shared_ptr<Scheduler> scheduler, Args&&... args)
|
||||
: retainer(std::move(scheduler)), target(*retainer, parent, std::forward<Args>(args)...) {}
|
||||
|
||||
Actor(const Actor&) = delete;
|
||||
|
||||
ActorRef<std::decay_t<Object>> self() {
|
||||
return parent.self();
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Scheduler> retainer;
|
||||
AspiringActor<Object> parent;
|
||||
EstablishedActor<Object> target;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
64
include/mbgl/actor/actor_ref.hpp
Normal file
64
include/mbgl/actor/actor_ref.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/actor/mailbox.hpp>
|
||||
#include <mbgl/actor/message.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/*
|
||||
An `ActorRef<O>` is a *non*-owning, weak reference to an actor of type `O`. You can send it
|
||||
messages just like an `Actor<O>`. It's a value object: safe to copy and pass between actors
|
||||
via messages.
|
||||
|
||||
An `ActorRef<O>` does not extend the lifetime of the corresponding `Actor<O>`. That's determined
|
||||
entirely by whichever object owns the `Actor<O>` -- the actor's "supervisor".
|
||||
|
||||
It's safe for a `Ref` to outlive its `Actor` -- the reference is "weak", and does not extend
|
||||
the lifetime of the owning Actor, and sending a message to a `Ref` whose `Actor` has died is
|
||||
a no-op. (In the future, a dead-letters queue or log may be implemented.)
|
||||
*/
|
||||
|
||||
template <class Object>
|
||||
class ActorRef {
|
||||
public:
|
||||
ActorRef(Object& object_, std::weak_ptr<Mailbox> weakMailbox_)
|
||||
: object(&object_),
|
||||
weakMailbox(std::move(weakMailbox_)) {
|
||||
}
|
||||
|
||||
template <typename Fn, class... Args>
|
||||
void invoke(Fn fn, Args&&... args) const {
|
||||
if (auto mailbox = weakMailbox.lock()) {
|
||||
mailbox->push(actor::makeMessage(*object, fn, std::forward<Args>(args)...));
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Fn, class... Args>
|
||||
auto ask(Fn fn, Args&&... args) const {
|
||||
// Result type is deduced from the function's return type
|
||||
using ResultType = typename std::result_of<decltype(fn)(Object, Args...)>::type;
|
||||
|
||||
std::promise<ResultType> promise;
|
||||
auto future = promise.get_future();
|
||||
|
||||
if (auto mailbox = weakMailbox.lock()) {
|
||||
mailbox->push(
|
||||
actor::makeMessage(
|
||||
std::move(promise), *object, fn, std::forward<Args>(args)...
|
||||
)
|
||||
);
|
||||
} else {
|
||||
promise.set_exception(std::make_exception_ptr(std::runtime_error("Actor has gone away")));
|
||||
}
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private:
|
||||
Object* object;
|
||||
std::weak_ptr<Mailbox> weakMailbox;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
60
include/mbgl/actor/aspiring_actor.hpp
Normal file
60
include/mbgl/actor/aspiring_actor.hpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/actor/mailbox.hpp>
|
||||
#include <mbgl/actor/message.hpp>
|
||||
#include <mbgl/actor/actor_ref.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
template <class Object>
|
||||
class EstablishedActor;
|
||||
|
||||
template <class Object>
|
||||
class Actor;
|
||||
|
||||
/*
|
||||
An `AspiringActor<O>` is one half of the pair of types that comprise an actor (see `Actor<O>`),
|
||||
the other half being `EstablishedActor<O>`. It is responsible for:
|
||||
- ownership of the actor's `Mailbox`
|
||||
- allocating the memory for (but *not* constructing) the target object `O`
|
||||
|
||||
Using these two pieces--the mailbox and a stable address for `O`--an `AspiringActor<O>` can
|
||||
accept messages for the target object, or provide `ActorRef<O>`s that do so, before the object
|
||||
has actually been constructed by the corresponding `EstablishedActor<O>`. (Such messages are
|
||||
queued in the mailbox until after the object is constructed.)
|
||||
|
||||
This allows for an `AspiringActor<O>` to be created and safely used by a thread other than the
|
||||
one on which the target object will (eventually) live.
|
||||
*/
|
||||
template <class Object>
|
||||
class AspiringActor {
|
||||
public:
|
||||
AspiringActor() : mailbox(std::make_shared<Mailbox>()) {
|
||||
// mailbox starts closed because the `Object` hasn't yet been constructed
|
||||
assert(!mailbox->isOpen());
|
||||
}
|
||||
|
||||
AspiringActor(const AspiringActor&) = delete;
|
||||
|
||||
ActorRef<std::decay_t<Object>> self() {
|
||||
return ActorRef<std::decay_t<Object>>(object(), mailbox);
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Mailbox> mailbox;
|
||||
std::aligned_storage_t<sizeof(Object)> objectStorage;
|
||||
|
||||
Object& object() {
|
||||
return *reinterpret_cast<Object *>(&objectStorage);
|
||||
}
|
||||
|
||||
friend class EstablishedActor<Object>;
|
||||
friend class Actor<Object>;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
80
include/mbgl/actor/established_actor.hpp
Normal file
80
include/mbgl/actor/established_actor.hpp
Normal file
@@ -0,0 +1,80 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/actor/aspiring_actor.hpp>
|
||||
#include <mbgl/actor/mailbox.hpp>
|
||||
#include <mbgl/actor/message.hpp>
|
||||
#include <mbgl/actor/actor_ref.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <type_traits>
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/*
|
||||
An `EstablishedActor<O>` is one half of the pair of types that comprise an actor (see `Actor<O>`),
|
||||
the other half being `AspiringActor<O>`. It is responsible for managing the lifetime of the
|
||||
target object `O` and the open/closed state of the parent's `mailbox`.
|
||||
|
||||
The `O` object's lifetime is contained by that of its owning `EstablishedActor<O>`: the
|
||||
`EstablishedActor` constructor executes the `O` constructor via "placement new", constructing
|
||||
it at the address provided by the parent `AspiringActor`, and the `~EstablishedActor` destructor
|
||||
similarly executes the `~O` destructor (after closing the mailbox). `EstablishedActor` should
|
||||
therefore live entirely on the thread intended to own `O`.
|
||||
*/
|
||||
|
||||
template <class Object>
|
||||
class EstablishedActor {
|
||||
public:
|
||||
// Construct the Object from a parameter pack `args` (i.e. `Object(args...)`)
|
||||
template <typename U = Object, class... Args, typename std::enable_if<
|
||||
std::is_constructible<U, Args...>::value ||
|
||||
std::is_constructible<U, ActorRef<U>, Args...>::value
|
||||
>::type * = nullptr>
|
||||
EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, Args&& ... args)
|
||||
: parent(parent_) {
|
||||
emplaceObject(std::forward<Args>(args)...);
|
||||
parent.mailbox->open(scheduler);
|
||||
}
|
||||
|
||||
// Construct the `Object` from a tuple containing the constructor arguments (i.e.
|
||||
// `Object(std::get<0>(args), std::get<1>(args), ...)`)
|
||||
template <class ArgsTuple, std::size_t ArgCount = std::tuple_size<std::decay_t<ArgsTuple>>::value>
|
||||
EstablishedActor(Scheduler& scheduler, AspiringActor<Object>& parent_, ArgsTuple&& args)
|
||||
: parent(parent_) {
|
||||
emplaceObject(std::forward<ArgsTuple>(args), std::make_index_sequence<ArgCount>{});
|
||||
parent.mailbox->open(scheduler);
|
||||
}
|
||||
|
||||
EstablishedActor(const EstablishedActor&) = delete;
|
||||
|
||||
~EstablishedActor() {
|
||||
parent.mailbox->close();
|
||||
parent.object().~Object();
|
||||
}
|
||||
|
||||
private:
|
||||
// Enabled for Objects with a constructor taking ActorRef<Object> as the first parameter
|
||||
template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
|
||||
void emplaceObject(Args&&... args_) {
|
||||
new (&parent.objectStorage) Object(parent.self(), std::forward<Args>(args_)...);
|
||||
}
|
||||
|
||||
// Enabled for plain Objects
|
||||
template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, Args...>::value>::type * = nullptr>
|
||||
void emplaceObject(Args&&... args_) {
|
||||
new (&parent.objectStorage) Object(std::forward<Args>(args_)...);
|
||||
}
|
||||
|
||||
// Used to expand a tuple holding the constructor arguments
|
||||
template <class ArgsTuple, std::size_t... I>
|
||||
void emplaceObject(ArgsTuple&& args, std::index_sequence<I...>) {
|
||||
emplaceObject(std::move(std::get<I>(std::forward<ArgsTuple>(args)))...);
|
||||
(void) args; // mark args as used: if it's empty tuple, it's not actually used above.
|
||||
}
|
||||
|
||||
AspiringActor<Object>& parent;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
54
include/mbgl/actor/mailbox.hpp
Normal file
54
include/mbgl/actor/mailbox.hpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
#include <mapbox/std/weak.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Scheduler;
|
||||
class Message;
|
||||
|
||||
class Mailbox : public std::enable_shared_from_this<Mailbox> {
|
||||
public:
|
||||
|
||||
// Create a "holding" mailbox, messages to which will remain queued,
|
||||
// unconsumed, until the mailbox is associated with a Scheduler using
|
||||
// start(). This allows a Mailbox object to be created on one thread and
|
||||
// later transferred to a different target thread that may not yet exist.
|
||||
Mailbox();
|
||||
|
||||
Mailbox(Scheduler&);
|
||||
|
||||
// Attach the given scheduler to this mailbox and begin processing messages
|
||||
// sent to it. The mailbox must be a "holding" mailbox, as created by the
|
||||
// default constructor Mailbox().
|
||||
void open(Scheduler& scheduler_);
|
||||
void close();
|
||||
|
||||
bool isOpen() const;
|
||||
|
||||
void push(std::unique_ptr<Message>);
|
||||
void receive();
|
||||
|
||||
static void maybeReceive(const std::weak_ptr<Mailbox>&);
|
||||
static std::function<void()> makeClosure(std::weak_ptr<Mailbox>);
|
||||
|
||||
private:
|
||||
mapbox::base::WeakPtr<Scheduler> weakScheduler;
|
||||
|
||||
std::recursive_mutex receivingMutex;
|
||||
std::mutex pushingMutex;
|
||||
|
||||
bool closed { false };
|
||||
|
||||
std::mutex queueMutex;
|
||||
std::queue<std::unique_ptr<Message>> queue;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
108
include/mbgl/actor/message.hpp
Normal file
108
include/mbgl/actor/message.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <future>
|
||||
#include <utility>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
// A movable type-erasing function wrapper. This allows to store arbitrary invokable
|
||||
// things (like std::function<>, or the result of a movable-only std::bind()) in the queue.
|
||||
// Source: http://stackoverflow.com/a/29642072/331379
|
||||
class Message {
|
||||
public:
|
||||
virtual ~Message() = default;
|
||||
virtual void operator()() = 0;
|
||||
};
|
||||
|
||||
template <class Object, class MemberFn, class ArgsTuple>
|
||||
class MessageImpl : public Message {
|
||||
public:
|
||||
MessageImpl(Object& object_, MemberFn memberFn_, ArgsTuple argsTuple_)
|
||||
: object(object_),
|
||||
memberFn(memberFn_),
|
||||
argsTuple(std::move(argsTuple_)) {
|
||||
}
|
||||
|
||||
void operator()() override {
|
||||
invoke(std::make_index_sequence<std::tuple_size<ArgsTuple>::value>());
|
||||
}
|
||||
|
||||
template <std::size_t... I>
|
||||
void invoke(std::index_sequence<I...>) {
|
||||
(object.*memberFn)(std::move(std::get<I>(argsTuple))...);
|
||||
}
|
||||
|
||||
Object& object;
|
||||
MemberFn memberFn;
|
||||
ArgsTuple argsTuple;
|
||||
};
|
||||
|
||||
template <class ResultType, class Object, class MemberFn, class ArgsTuple>
|
||||
class AskMessageImpl : public Message {
|
||||
public:
|
||||
AskMessageImpl(std::promise<ResultType> promise_, Object& object_, MemberFn memberFn_, ArgsTuple argsTuple_)
|
||||
: object(object_),
|
||||
memberFn(memberFn_),
|
||||
argsTuple(std::move(argsTuple_)),
|
||||
promise(std::move(promise_)) {
|
||||
}
|
||||
|
||||
void operator()() override {
|
||||
promise.set_value(ask(std::make_index_sequence<std::tuple_size<ArgsTuple>::value>()));
|
||||
}
|
||||
|
||||
template <std::size_t... I>
|
||||
ResultType ask(std::index_sequence<I...>) {
|
||||
return (object.*memberFn)(std::move(std::get<I>(argsTuple))...);
|
||||
}
|
||||
|
||||
Object& object;
|
||||
MemberFn memberFn;
|
||||
ArgsTuple argsTuple;
|
||||
std::promise<ResultType> promise;
|
||||
};
|
||||
|
||||
template <class Object, class MemberFn, class ArgsTuple>
|
||||
class AskMessageImpl<void, Object, MemberFn, ArgsTuple> : public Message {
|
||||
public:
|
||||
AskMessageImpl(std::promise<void> promise_, Object& object_, MemberFn memberFn_, ArgsTuple argsTuple_)
|
||||
: object(object_),
|
||||
memberFn(memberFn_),
|
||||
argsTuple(std::move(argsTuple_)),
|
||||
promise(std::move(promise_)) {
|
||||
}
|
||||
|
||||
void operator()() override {
|
||||
ask(std::make_index_sequence<std::tuple_size<ArgsTuple>::value>());
|
||||
promise.set_value();
|
||||
}
|
||||
|
||||
template <std::size_t... I>
|
||||
void ask(std::index_sequence<I...>) {
|
||||
(object.*memberFn)(std::move(std::get<I>(argsTuple))...);
|
||||
}
|
||||
|
||||
Object& object;
|
||||
MemberFn memberFn;
|
||||
ArgsTuple argsTuple;
|
||||
std::promise<void> promise;
|
||||
};
|
||||
|
||||
namespace actor {
|
||||
|
||||
template <class Object, class MemberFn, class... Args>
|
||||
std::unique_ptr<Message> makeMessage(Object& object, MemberFn memberFn, Args&&... args) {
|
||||
auto tuple = std::make_tuple(std::forward<Args>(args)...);
|
||||
return std::make_unique<MessageImpl<Object, MemberFn, decltype(tuple)>>(object, memberFn, std::move(tuple));
|
||||
}
|
||||
|
||||
template <class ResultType, class Object, class MemberFn, class... Args>
|
||||
std::unique_ptr<Message> makeMessage(std::promise<ResultType>&& promise, Object& object, MemberFn memberFn, Args&&... args) {
|
||||
auto tuple = std::make_tuple(std::forward<Args>(args)...);
|
||||
return std::make_unique<AskMessageImpl<ResultType, Object, MemberFn, decltype(tuple)>>(std::move(promise), object, memberFn, std::move(tuple));
|
||||
}
|
||||
|
||||
} // namespace actor
|
||||
} // namespace mbgl
|
||||
105
include/mbgl/actor/scheduler.hpp
Normal file
105
include/mbgl/actor/scheduler.hpp
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/pass_types.hpp>
|
||||
|
||||
#include <mapbox/std/weak.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Mailbox;
|
||||
|
||||
/*
|
||||
A `Scheduler` is responsible for coordinating the processing of messages by
|
||||
one or more actors via their mailboxes. It's an abstract interface. Currently,
|
||||
the following concrete implementations exist:
|
||||
|
||||
* `ThreadPool` can coordinate an unlimited number of actors over any number of
|
||||
threads via a pool, preserving the following behaviors:
|
||||
|
||||
- Messages from each individual mailbox are processed in order
|
||||
- Only a single message from a mailbox is processed at a time; there is no
|
||||
concurrency within a mailbox
|
||||
|
||||
Subject to these constraints, processing can happen on whatever thread in the
|
||||
pool is available.
|
||||
|
||||
* `Scheduler::GetCurrent()` is typically used to create a mailbox and `ActorRef`
|
||||
for an object that lives on the main thread and is not itself wrapped an
|
||||
`Actor`. The underlying implementation of this Scheduler should usually be
|
||||
a `RunLoop`
|
||||
auto mailbox = std::make_shared<Mailbox>(*Scheduler::Get());
|
||||
Actor<Worker> worker(threadPool, ActorRef<Foo>(*this, mailbox));
|
||||
*/
|
||||
class Scheduler {
|
||||
public:
|
||||
virtual ~Scheduler() = default;
|
||||
|
||||
// Enqueues a function for execution.
|
||||
virtual void schedule(std::function<void()>) = 0;
|
||||
// Makes a weak pointer to this Scheduler.
|
||||
virtual mapbox::base::WeakPtr<Scheduler> makeWeakPtr() = 0;
|
||||
|
||||
// Returns a closure wrapping the given one.
|
||||
//
|
||||
// When the returned closure is invoked for the first time, it schedules
|
||||
// the given closure to this scheduler, the consequent calls of the
|
||||
// returned closure are ignored.
|
||||
//
|
||||
// If this scheduler is already deleted by the time the returnded closure is
|
||||
// first invoked, the call is ignored.
|
||||
std::function<void()> bindOnce(std::function<void()>);
|
||||
|
||||
// Enqueues the given |task| for execution into this scheduler's task queue and
|
||||
// then enqueues the |reply| with the captured task result to the current
|
||||
// task queue.
|
||||
//
|
||||
// The |TaskFn| return type must be compatible with the |ReplyFn| argument type.
|
||||
// Note: the task result is copied and passed by value.
|
||||
template <typename TaskFn, typename ReplyFn>
|
||||
void scheduleAndReplyValue(const TaskFn& task, const ReplyFn& reply) {
|
||||
assert(GetCurrent());
|
||||
scheduleAndReplyValue(task, reply, GetCurrent()->makeWeakPtr());
|
||||
}
|
||||
|
||||
// Set/Get the current Scheduler for this thread
|
||||
static Scheduler* GetCurrent();
|
||||
static void SetCurrent(Scheduler*);
|
||||
|
||||
// Get the scheduler for asynchronous tasks. This method
|
||||
// will lazily initialize a shared worker pool when ran
|
||||
// from the first time.
|
||||
// The scheduled tasks might run in parallel on different
|
||||
// threads.
|
||||
// TODO : Rename to GetPool()
|
||||
static PassRefPtr<Scheduler> GetBackground();
|
||||
|
||||
// Get the *sequenced* scheduler for asynchronous tasks.
|
||||
// Unlike the method above, the returned scheduler
|
||||
// (once stored) represents a single thread, thus each
|
||||
// newly scheduled task is guarantied to run after the
|
||||
// previously scheduled one.
|
||||
//
|
||||
// Sequenced scheduler can be used for running tasks
|
||||
// on the same thread-unsafe object.
|
||||
static PassRefPtr<Scheduler> GetSequenced();
|
||||
|
||||
protected:
|
||||
template <typename TaskFn, typename ReplyFn>
|
||||
void scheduleAndReplyValue(const TaskFn& task,
|
||||
const ReplyFn& reply,
|
||||
mapbox::base::WeakPtr<Scheduler> replyScheduler) {
|
||||
auto scheduled = [replyScheduler = std::move(replyScheduler), task, reply] {
|
||||
auto lock = replyScheduler.lock();
|
||||
if (!replyScheduler) return;
|
||||
auto scheduledReply = [reply, result = task()] { reply(result); };
|
||||
replyScheduler->schedule(std::move(scheduledReply));
|
||||
};
|
||||
|
||||
schedule(std::move(scheduled));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
70
include/mbgl/annotation/annotation.hpp
Normal file
70
include/mbgl/annotation/annotation.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/style/property_value.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using AnnotationID = uint64_t;
|
||||
using AnnotationIDs = std::vector<AnnotationID>;
|
||||
|
||||
class SymbolAnnotation {
|
||||
public:
|
||||
SymbolAnnotation(Point<double> geometry_, std::string icon_ = {}) : geometry(geometry_), icon(std::move(icon_)) {}
|
||||
|
||||
Point<double> geometry;
|
||||
std::string icon;
|
||||
};
|
||||
|
||||
using ShapeAnnotationGeometry = variant<
|
||||
LineString<double>,
|
||||
Polygon<double>,
|
||||
MultiLineString<double>,
|
||||
MultiPolygon<double>>;
|
||||
|
||||
class LineAnnotation {
|
||||
public:
|
||||
LineAnnotation(ShapeAnnotationGeometry geometry_,
|
||||
style::PropertyValue<float> opacity_ = 1.0f,
|
||||
style::PropertyValue<float> width_ = 1.0f,
|
||||
style::PropertyValue<Color> color_ = Color::black())
|
||||
: geometry(std::move(geometry_)),
|
||||
opacity(std::move(opacity_)),
|
||||
width(std::move(width_)),
|
||||
color(std::move(color_)) {}
|
||||
|
||||
ShapeAnnotationGeometry geometry;
|
||||
style::PropertyValue<float> opacity;
|
||||
style::PropertyValue<float> width;
|
||||
style::PropertyValue<Color> color;
|
||||
};
|
||||
|
||||
class FillAnnotation {
|
||||
public:
|
||||
FillAnnotation(ShapeAnnotationGeometry geometry_,
|
||||
style::PropertyValue<float> opacity_ = 1.0f,
|
||||
style::PropertyValue<Color> color_ = Color::black(),
|
||||
style::PropertyValue<Color> outlineColor_ = {})
|
||||
: geometry(std::move(geometry_)),
|
||||
opacity(std::move(opacity_)),
|
||||
color(std::move(color_)),
|
||||
outlineColor(std::move(outlineColor_)) {}
|
||||
|
||||
ShapeAnnotationGeometry geometry;
|
||||
style::PropertyValue<float> opacity;
|
||||
style::PropertyValue<Color> color;
|
||||
style::PropertyValue<Color> outlineColor;
|
||||
};
|
||||
|
||||
using Annotation = variant<
|
||||
SymbolAnnotation,
|
||||
LineAnnotation,
|
||||
FillAnnotation>;
|
||||
|
||||
} // namespace mbgl
|
||||
44
include/mbgl/gfx/backend.hpp
Normal file
44
include/mbgl/gfx/backend.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class Backend {
|
||||
public:
|
||||
enum class Type : uint8_t {
|
||||
OpenGL,
|
||||
};
|
||||
|
||||
static constexpr Type DefaultType = Type::OpenGL;
|
||||
|
||||
static void SetType(const Type value) {
|
||||
if (Value(value) != value) {
|
||||
abort(); // SetType must be called prior to any GetType calls.
|
||||
}
|
||||
}
|
||||
|
||||
static Type GetType() {
|
||||
return Value(DefaultType);
|
||||
}
|
||||
|
||||
template <typename T, typename... Args>
|
||||
static std::unique_ptr<T> Create(Args... args) {
|
||||
return Create<Type::OpenGL, T, Args...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
template <Type, typename T, typename... Args>
|
||||
static std::unique_ptr<T> Create(Args...);
|
||||
|
||||
static Type Value(Type value) {
|
||||
static const Type type = value;
|
||||
return type;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
37
include/mbgl/gfx/backend_scope.hpp
Normal file
37
include/mbgl/gfx/backend_scope.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class RendererBackend;
|
||||
|
||||
class BackendScope {
|
||||
public:
|
||||
// There are two types of scopes: Creating an "Implicit" scope tells Mapbox GL that the
|
||||
// supporting windowing system has already activated the GL Backend and that no further actions
|
||||
// are required. Creating an "Explicit" scope actually enables the GL Backend, and disables it
|
||||
// when the BackendScope is destroyed.
|
||||
enum class ScopeType : bool {
|
||||
Implicit,
|
||||
Explicit,
|
||||
};
|
||||
|
||||
BackendScope(RendererBackend&, ScopeType = ScopeType::Explicit);
|
||||
~BackendScope();
|
||||
|
||||
// Returns true when there is currently a BackendScope active in this thread.
|
||||
static bool exists();
|
||||
|
||||
private:
|
||||
void activate();
|
||||
void deactivate();
|
||||
|
||||
BackendScope* priorScope;
|
||||
BackendScope* nextScope;
|
||||
RendererBackend& backend;
|
||||
const ScopeType scopeType;
|
||||
bool activated = false;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
47
include/mbgl/gfx/renderable.hpp
Normal file
47
include/mbgl/gfx/renderable.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/size.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class RenderableResource {
|
||||
protected:
|
||||
explicit RenderableResource() = default;
|
||||
|
||||
public:
|
||||
virtual ~RenderableResource() = default;
|
||||
RenderableResource(const RenderableResource&) = delete;
|
||||
RenderableResource& operator=(const RenderableResource&) = delete;
|
||||
};
|
||||
|
||||
class Renderable {
|
||||
protected:
|
||||
Renderable(const Size size_, std::unique_ptr<RenderableResource> resource_)
|
||||
: size(size_), resource(std::move(resource_)) {
|
||||
}
|
||||
virtual ~Renderable() = default;
|
||||
|
||||
public:
|
||||
Size getSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& getResource() const {
|
||||
assert(resource);
|
||||
return static_cast<T&>(*resource);
|
||||
}
|
||||
|
||||
virtual void wait() {}
|
||||
|
||||
protected:
|
||||
Size size;
|
||||
std::unique_ptr<RenderableResource> resource;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
72
include/mbgl/gfx/renderer_backend.hpp
Normal file
72
include/mbgl/gfx/renderer_backend.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/util.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
class Context;
|
||||
class Renderable;
|
||||
class BackendScope;
|
||||
|
||||
// We can make some optimizations if we know that the drawing context is not shared with other code.
|
||||
enum class ContextMode : bool {
|
||||
Unique,
|
||||
Shared,
|
||||
};
|
||||
|
||||
class RendererBackend {
|
||||
protected:
|
||||
explicit RendererBackend(ContextMode);
|
||||
|
||||
public:
|
||||
virtual ~RendererBackend();
|
||||
RendererBackend(const RendererBackend&) = delete;
|
||||
RendererBackend& operator=(const RendererBackend&) = delete;
|
||||
|
||||
// Returns the device's context.
|
||||
Context& getContext();
|
||||
|
||||
template <typename T>
|
||||
T& getContext() {
|
||||
return static_cast<T&>(getContext());
|
||||
}
|
||||
|
||||
bool contextIsShared() const {
|
||||
return contextMode == ContextMode::Shared;
|
||||
}
|
||||
|
||||
// Returns a reference to the default surface that should be rendered on.
|
||||
virtual Renderable& getDefaultRenderable() = 0;
|
||||
|
||||
protected:
|
||||
virtual std::unique_ptr<Context> createContext() = 0;
|
||||
|
||||
// Called when the backend's GL context needs to be made active or inactive. These are called,
|
||||
// as a matched pair, exclusively through BackendScope, in two situations:
|
||||
//
|
||||
// 1. When releasing GL resources during Renderer destruction
|
||||
// (Including calling CustomLayerHost::deinitialize during RenderCustomLayer destruction)
|
||||
// 2. When renderering through Renderer::render()
|
||||
// (Including calling CustomLayerHost::initialize for newly added custom layers and
|
||||
// CustomLayerHost::deinitialize on layer removal)
|
||||
virtual void activate() = 0;
|
||||
virtual void deactivate() = 0;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Context> context;
|
||||
const ContextMode contextMode;
|
||||
std::once_flag initialized;
|
||||
|
||||
friend class BackendScope;
|
||||
};
|
||||
|
||||
MBGL_CONSTEXPR bool operator==(const RendererBackend& a, const RendererBackend& b) {
|
||||
return &a == &b;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
37
include/mbgl/gfx/rendering_stats.hpp
Normal file
37
include/mbgl/gfx/rendering_stats.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
struct RenderingStats {
|
||||
RenderingStats() = default;
|
||||
bool isZero() const;
|
||||
|
||||
int numDrawCalls;
|
||||
int numActiveTextures;
|
||||
int numCreatedTextures;
|
||||
int numBuffers;
|
||||
int numFrameBuffers;
|
||||
|
||||
int memTextures;
|
||||
int memIndexBuffers;
|
||||
int memVertexBuffers;
|
||||
|
||||
RenderingStats& operator+=(const RenderingStats& right);
|
||||
};
|
||||
|
||||
inline RenderingStats& RenderingStats::operator+=(const RenderingStats& r) {
|
||||
numDrawCalls += r.numDrawCalls;
|
||||
numActiveTextures += r.numActiveTextures;
|
||||
numCreatedTextures += r.numCreatedTextures;
|
||||
numBuffers += r.numBuffers;
|
||||
numFrameBuffers += r.numFrameBuffers;
|
||||
|
||||
memTextures += r.memTextures;
|
||||
memIndexBuffers += r.memIndexBuffers;
|
||||
memVertexBuffers += r.memVertexBuffers;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
84
include/mbgl/gl/custom_layer.hpp
Normal file
84
include/mbgl/gl/custom_layer.hpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/layer.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
/**
|
||||
* Parameters that define the current camera position for a `CustomLayerHost::render()` function.
|
||||
*/
|
||||
struct CustomLayerRenderParameters {
|
||||
double width;
|
||||
double height;
|
||||
double latitude;
|
||||
double longitude;
|
||||
double zoom;
|
||||
double bearing;
|
||||
double pitch;
|
||||
double fieldOfView;
|
||||
std::array<double, 16> projectionMatrix;
|
||||
};
|
||||
|
||||
class CustomLayerHost {
|
||||
public:
|
||||
virtual ~CustomLayerHost() = default;
|
||||
/**
|
||||
* Initialize any GL state needed by the custom layer. This method is called once, from the
|
||||
* main thread, at a point when the GL context is active but before rendering for the first
|
||||
* time.
|
||||
*
|
||||
* Resources that are acquired in this method must be released in the `deinitialize` function.
|
||||
*/
|
||||
virtual void initialize() = 0;
|
||||
|
||||
/**
|
||||
* Render the layer. This method is called once per frame. The implementation should not make
|
||||
* any assumptions about the GL state (other than that the correct context is active). It may
|
||||
* make changes to the state, and is not required to reset values such as the depth mask, stencil
|
||||
* mask, and corresponding test flags to their original values.
|
||||
* Make sure that you are drawing your fragments with a z value of 1 to take advantage of the
|
||||
* opaque fragment culling in case there are opaque layers above your custom layer.
|
||||
*/
|
||||
virtual void render(const CustomLayerRenderParameters&) = 0;
|
||||
|
||||
/**
|
||||
* Called when the system has destroyed the underlying GL context. The
|
||||
* `deinitialize` function will not be called in this case, however
|
||||
* `initialize` will be called instead to prepare for a new render.
|
||||
*
|
||||
*/
|
||||
virtual void contextLost() = 0;
|
||||
|
||||
/**
|
||||
* Destroy any GL state needed by the custom layer, and deallocate context, if necessary. This
|
||||
* method is called once, from the main thread, at a point when the GL context is active.
|
||||
*
|
||||
* Note that it may be called even when the `initialize` function has not been called.
|
||||
*/
|
||||
virtual void deinitialize() = 0;
|
||||
};
|
||||
|
||||
class CustomLayer final : public Layer {
|
||||
public:
|
||||
CustomLayer(const std::string& id,
|
||||
std::unique_ptr<CustomLayerHost> host);
|
||||
|
||||
CustomLayer(const CustomLayer&) = delete;
|
||||
~CustomLayer() final;
|
||||
class Impl;
|
||||
const Impl& impl() const;
|
||||
Mutable<Impl> mutableImpl() const;
|
||||
|
||||
private:
|
||||
optional<conversion::Error> setPropertyInternal(const std::string& name,
|
||||
const conversion::Convertible& value) final;
|
||||
StyleProperty getProperty(const std::string&) const final;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
|
||||
Mutable<Layer::Impl> mutableBaseImpl() const final;
|
||||
};
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
17
include/mbgl/gl/custom_layer_factory.hpp
Normal file
17
include/mbgl/gl/custom_layer_factory.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class CustomLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
24
include/mbgl/gl/renderable_resource.hpp
Normal file
24
include/mbgl/gl/renderable_resource.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/renderable.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
class RenderableResource : public gfx::RenderableResource {
|
||||
protected:
|
||||
explicit RenderableResource() = default;
|
||||
|
||||
public:
|
||||
virtual void bind() = 0;
|
||||
|
||||
virtual void swap() {
|
||||
// Renderable resources that require a swap function to be called explicitly
|
||||
// can override this method.
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
55
include/mbgl/gl/renderer_backend.hpp
Normal file
55
include/mbgl/gl/renderer_backend.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/util/image.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
#include <mbgl/util/util.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
using ProcAddress = void (*)();
|
||||
using FramebufferID = uint32_t;
|
||||
|
||||
class RendererBackend : public gfx::RendererBackend {
|
||||
public:
|
||||
RendererBackend(gfx::ContextMode);
|
||||
~RendererBackend() override;
|
||||
|
||||
// Called prior to rendering to update the internally assumed OpenGL state.
|
||||
virtual void updateAssumedState() = 0;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<gfx::Context> createContext() override;
|
||||
|
||||
// Called with the name of an OpenGL extension that should be loaded. RendererBackend implementations
|
||||
// must call the API-specific version that obtains the function pointer for this function,
|
||||
// or a null pointer if unsupported/unavailable.
|
||||
virtual ProcAddress getExtensionFunctionPointer(const char*) = 0;
|
||||
|
||||
// Reads the color pixel data from the currently bound framebuffer.
|
||||
PremultipliedImage readFramebuffer(const Size&);
|
||||
|
||||
// A constant to signal that a framebuffer is bound, but with an unknown ID.
|
||||
static constexpr const FramebufferID ImplicitFramebufferBinding =
|
||||
std::numeric_limits<FramebufferID>::max();
|
||||
|
||||
// Tells the renderer that OpenGL state has already been set by the windowing toolkit.
|
||||
// It sets the internal assumed state to the supplied values.
|
||||
void assumeFramebufferBinding(FramebufferID fbo);
|
||||
void assumeViewport(int32_t x, int32_t y, const Size&);
|
||||
void assumeScissorTest(bool);
|
||||
|
||||
// Returns true when assumed framebuffer binding hasn't changed from the implicit binding.
|
||||
bool implicitFramebufferBound();
|
||||
|
||||
public:
|
||||
// Triggers an OpenGL state update if the internal assumed state doesn't match the
|
||||
// supplied values.
|
||||
void setFramebufferBinding(FramebufferID fbo);
|
||||
void setViewport(int32_t x, int32_t y, const Size&);
|
||||
void setScissorTest(bool);
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
24
include/mbgl/i18n/collator.hpp
Normal file
24
include/mbgl/i18n/collator.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
class Collator {
|
||||
public:
|
||||
explicit Collator(bool caseSensitive, bool diacriticSensitive, const optional<std::string>& locale = nullopt);
|
||||
int compare(const std::string& lhs, const std::string& rhs) const;
|
||||
std::string resolvedLocale() const;
|
||||
bool operator==(const Collator& other) const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::shared_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
15
include/mbgl/i18n/number_format.hpp
Normal file
15
include/mbgl/i18n/number_format.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
std::string formatNumber(double number,
|
||||
const std::string& localeId,
|
||||
const std::string& currency,
|
||||
uint8_t minFractionDigits,
|
||||
uint8_t maxFractionDigits);
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
14
include/mbgl/layermanager/background_layer_factory.hpp
Normal file
14
include/mbgl/layermanager/background_layer_factory.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class BackgroundLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
17
include/mbgl/layermanager/circle_layer_factory.hpp
Normal file
17
include/mbgl/layermanager/circle_layer_factory.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class CircleLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<Layout> createLayout(const LayoutParameters& parameters,
|
||||
std::unique_ptr<GeometryTileLayer> tileLayer,
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
15
include/mbgl/layermanager/fill_extrusion_layer_factory.hpp
Normal file
15
include/mbgl/layermanager/fill_extrusion_layer_factory.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FillExtrusionLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<Layout> createLayout(const LayoutParameters&, std::unique_ptr<GeometryTileLayer>, const std::vector<Immutable<style::LayerProperties>>&) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
15
include/mbgl/layermanager/fill_layer_factory.hpp
Normal file
15
include/mbgl/layermanager/fill_layer_factory.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class FillLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<Layout> createLayout(const LayoutParameters&, std::unique_ptr<GeometryTileLayer>, const std::vector<Immutable<style::LayerProperties>>&) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
15
include/mbgl/layermanager/heatmap_layer_factory.hpp
Normal file
15
include/mbgl/layermanager/heatmap_layer_factory.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class HeatmapLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<Immutable<style::LayerProperties>>&) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
14
include/mbgl/layermanager/hillshade_layer_factory.hpp
Normal file
14
include/mbgl/layermanager/hillshade_layer_factory.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class HillshadeLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
42
include/mbgl/layermanager/layer_factory.hpp
Normal file
42
include/mbgl/layermanager/layer_factory.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/layer.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace style {
|
||||
class LayerProperties;
|
||||
} // namespace style
|
||||
class Bucket;
|
||||
class BucketParameters;
|
||||
class GeometryTileLayer;
|
||||
class Layout;
|
||||
class LayoutParameters;
|
||||
class RenderLayer;
|
||||
|
||||
/**
|
||||
* @brief The LayerFactory abstract class
|
||||
*
|
||||
* This class is responsible for creation of the layer objects that belong to a concrete layer type.
|
||||
*/
|
||||
class LayerFactory {
|
||||
public:
|
||||
virtual ~LayerFactory() = default;
|
||||
/// Returns the layer type data.
|
||||
virtual const style::LayerTypeInfo* getTypeInfo() const noexcept = 0;
|
||||
/// Returns a new Layer instance on success call; returns `nullptr` otherwise.
|
||||
virtual std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept = 0;
|
||||
/// Returns a new RenderLayer instance.
|
||||
virtual std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept = 0;
|
||||
/// Returns a new Bucket instance on success call; returns `nullptr` otherwise.
|
||||
virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<Immutable<style::LayerProperties>>&) noexcept;
|
||||
/// Returns a new Layout instance on success call; returns `nullptr` otherwise.
|
||||
virtual std::unique_ptr<Layout> createLayout(const LayoutParameters&, std::unique_ptr<GeometryTileLayer>, const std::vector<Immutable<style::LayerProperties>>&) noexcept;
|
||||
|
||||
protected:
|
||||
optional<std::string> getSource(const style::conversion::Convertible& value) const noexcept;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
70
include/mbgl/layermanager/layer_manager.hpp
Normal file
70
include/mbgl/layermanager/layer_manager.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/layer.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
class LayerProperties;
|
||||
} // namespace style
|
||||
class GeometryTileLayer;
|
||||
class LayerFactory;
|
||||
class RenderLayer;
|
||||
class Bucket;
|
||||
class BucketParameters;
|
||||
class Layout;
|
||||
class LayoutParameters;
|
||||
|
||||
/**
|
||||
* @brief A singleton class responsible for creating layer instances.
|
||||
*
|
||||
* The LayerManager has implementation per platform. The LayerManager implementation
|
||||
* defines what layer types are available and it can also disable annotations.
|
||||
*
|
||||
* Linker excludes the unreachable code for the disabled annotations and layers
|
||||
* from the binaries, significantly reducing their size.
|
||||
*/
|
||||
class LayerManager {
|
||||
public:
|
||||
/**
|
||||
* @brief A singleton getter.
|
||||
*
|
||||
* @return LayerManager*
|
||||
*/
|
||||
static LayerManager* get() noexcept;
|
||||
|
||||
/// Returns a new Layer instance on success call; returns `nullptr` otherwise.
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& type, const std::string& id,
|
||||
const style::conversion::Convertible& value, style::conversion::Error& error) noexcept;
|
||||
/// Returns a new RenderLayer instance on success call; returns `nullptr` otherwise.
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept;
|
||||
/// Returns a new Bucket instance on success call; returns `nullptr` otherwise.
|
||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<Immutable<style::LayerProperties>>&) noexcept;
|
||||
/// Returns a new Layout instance on success call; returns `nullptr` otherwise.
|
||||
std::unique_ptr<Layout> createLayout(const LayoutParameters&, std::unique_ptr<GeometryTileLayer>,
|
||||
const std::vector<Immutable<style::LayerProperties>>&) noexcept;
|
||||
|
||||
/**
|
||||
* @brief a build-time flag to enable/disable annotations in mapbox-gl-native core.
|
||||
*
|
||||
* At the moment, the annotations implementation in core is creating concrete
|
||||
* layer instances apart from LayerManager/LayerFactory code path.
|
||||
*
|
||||
* So, annotations must be disabled if the LayerManager implementation does
|
||||
* not provide line, fill or symbol layers (those, used by the annotations
|
||||
* implementation).
|
||||
*
|
||||
* Note: in future, annotations implemantation will be moved from the core to platform
|
||||
* SDK (see https://github.com/mapbox/mapbox-plugins-android/tree/master/plugin-annotation)
|
||||
* and this flag won't be needed any more.
|
||||
*/
|
||||
static const bool annotationsEnabled;
|
||||
|
||||
protected:
|
||||
virtual ~LayerManager() = default;
|
||||
virtual LayerFactory* getFactory(const std::string& type) noexcept = 0;
|
||||
virtual LayerFactory* getFactory(const style::LayerTypeInfo*) noexcept = 0;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
17
include/mbgl/layermanager/line_layer_factory.hpp
Normal file
17
include/mbgl/layermanager/line_layer_factory.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class LineLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<Layout> createLayout(const LayoutParameters& parameters,
|
||||
std::unique_ptr<GeometryTileLayer> tileLayer,
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class LocationIndicatorLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id,
|
||||
const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
14
include/mbgl/layermanager/raster_layer_factory.hpp
Normal file
14
include/mbgl/layermanager/raster_layer_factory.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RasterLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
17
include/mbgl/layermanager/symbol_layer_factory.hpp
Normal file
17
include/mbgl/layermanager/symbol_layer_factory.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/layermanager/layer_factory.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class SymbolLayerFactory : public LayerFactory {
|
||||
protected:
|
||||
const style::LayerTypeInfo* getTypeInfo() const noexcept final;
|
||||
std::unique_ptr<style::Layer> createLayer(const std::string& id, const style::conversion::Convertible& value) noexcept final;
|
||||
std::unique_ptr<Layout> createLayout(const LayoutParameters& parameters,
|
||||
std::unique_ptr<GeometryTileLayer> tileLayer,
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept final;
|
||||
std::unique_ptr<RenderLayer> createRenderLayer(Immutable<style::Layer::Impl>) noexcept final;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
46
include/mbgl/map/bound_options.hpp
Normal file
46
include/mbgl/map/bound_options.hpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/**
|
||||
* @brief Holds options to limit what parts of a map are visible. All fields are
|
||||
* optional.
|
||||
*/
|
||||
struct BoundOptions {
|
||||
/// Sets the latitude and longitude bounds to which the camera center are constrained
|
||||
BoundOptions& withLatLngBounds(LatLngBounds b) { bounds = b; return *this; }
|
||||
/// Sets the minimum zoom level
|
||||
BoundOptions& withMinZoom(double z) { minZoom = z; return *this; }
|
||||
/// Sets the maximum zoom level
|
||||
BoundOptions& withMaxZoom(double z) { maxZoom = z; return *this; }
|
||||
/// Sets the minimum pitch
|
||||
BoundOptions& withMinPitch(double p) {
|
||||
minPitch = p;
|
||||
return *this;
|
||||
}
|
||||
/// Sets the maximum pitch
|
||||
BoundOptions& withMaxPitch(double p) {
|
||||
maxPitch = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Constrain the center of the camera to be within these bounds.
|
||||
optional<LatLngBounds> bounds;
|
||||
|
||||
/// Maximum zoom level allowed.
|
||||
optional<double> maxZoom;
|
||||
|
||||
/// Minimum zoom level allowed.
|
||||
optional<double> minZoom;
|
||||
|
||||
/// Maximum pitch allowed in degrees.
|
||||
optional<double> maxPitch;
|
||||
|
||||
/// Minimum pitch allowed in degrees.
|
||||
optional<double> minPitch;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
141
include/mbgl/map/camera.hpp
Normal file
141
include/mbgl/map/camera.hpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/unitbezier.hpp>
|
||||
#include <mbgl/util/vectors.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/** Various options for describing the viewpoint of a map. All fields are
|
||||
optional.
|
||||
Anchor and center points are mutually exclusive, with preference for the
|
||||
center point when both are set.
|
||||
*/
|
||||
struct CameraOptions {
|
||||
CameraOptions& withCenter(const optional<LatLng>& o) { center = o; return *this; }
|
||||
CameraOptions& withPadding(const optional<EdgeInsets>& p) { padding = p; return *this; }
|
||||
CameraOptions& withAnchor(const optional<ScreenCoordinate>& o) { anchor = o; return *this; }
|
||||
CameraOptions& withZoom(const optional<double>& o) { zoom = o; return *this; }
|
||||
CameraOptions& withBearing(const optional<double>& o) { bearing = o; return *this; }
|
||||
CameraOptions& withPitch(const optional<double>& o) { pitch = o; return *this; }
|
||||
|
||||
/** Coordinate at the center of the map. */
|
||||
optional<LatLng> center;
|
||||
|
||||
/** Padding around the interior of the view that affects the frame of
|
||||
reference for `center`. */
|
||||
optional<EdgeInsets> padding;
|
||||
|
||||
/** Point of reference for `zoom` and `angle`, assuming an origin at the
|
||||
top-left corner of the view. */
|
||||
optional<ScreenCoordinate> anchor;
|
||||
|
||||
/** Zero-based zoom level. Constrained to the minimum and maximum zoom
|
||||
levels. */
|
||||
optional<double> zoom;
|
||||
|
||||
/** Bearing, measured in degrees from true north. Wrapped to [0, 360). */
|
||||
optional<double> bearing;
|
||||
|
||||
/** Pitch toward the horizon measured in degrees , with 0 deg resulting in a
|
||||
two-dimensional map. */
|
||||
optional<double> pitch;
|
||||
};
|
||||
|
||||
constexpr bool operator==(const CameraOptions& a, const CameraOptions& b) {
|
||||
return a.center == b.center
|
||||
&& a.padding == b.padding
|
||||
&& a.anchor == b.anchor
|
||||
&& a.zoom == b.zoom
|
||||
&& a.bearing == b.bearing
|
||||
&& a.pitch == b.pitch;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const CameraOptions& a, const CameraOptions& b) {
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/** Various options for describing a transition between viewpoints with
|
||||
animation. All fields are optional; the default values depend on how this
|
||||
struct is used. */
|
||||
struct AnimationOptions {
|
||||
/** Time to animate to the viewpoint defined herein. */
|
||||
optional<Duration> duration;
|
||||
|
||||
/** Average velocity of a flyTo() transition, measured in screenfuls per
|
||||
second, assuming a linear timing curve.
|
||||
|
||||
A <i>screenful</i> is the visible span in pixels. It does not correspond
|
||||
to a fixed physical distance but rather varies by zoom level. */
|
||||
optional<double> velocity;
|
||||
|
||||
/** Zero-based zoom level at the peak of the flyTo() transition’s flight
|
||||
path. */
|
||||
optional<double> minZoom;
|
||||
|
||||
/** The easing timing curve of the transition. */
|
||||
optional<mbgl::util::UnitBezier> easing;
|
||||
|
||||
/** A function that is called on each frame of the transition, just before a
|
||||
screen update, except on the last frame. The first parameter indicates
|
||||
the elapsed time as a percentage of the duration. */
|
||||
std::function<void(double)> transitionFrameFn;
|
||||
|
||||
/** A function that is called once on the last frame of the transition, just
|
||||
before the corresponding screen update. */
|
||||
std::function<void()> transitionFinishFn;
|
||||
|
||||
/** Creates an animation with no options specified. */
|
||||
AnimationOptions() = default;
|
||||
|
||||
/** Creates an animation with the specified duration. */
|
||||
AnimationOptions(Duration d)
|
||||
: duration(d) {}
|
||||
};
|
||||
|
||||
/** Various options for accessing physical properties of the underlying camera entity.
|
||||
A direct access to these properties allows more flexible and precise controlling of the camera
|
||||
while also being fully compatible and interchangeable with CameraOptions. All fields are optional. */
|
||||
struct FreeCameraOptions {
|
||||
/** Position of the camera in slightly modified web mercator coordinates
|
||||
- The size of 1 unit is the width of the projected world instead of the "mercator meter".
|
||||
Coordinate [0, 0, 0] is the north-west corner and [1, 1, 0] is the south-east corner.
|
||||
- Z coordinate is conformal and must respect minimum and maximum zoom values.
|
||||
- Zoom is automatically computed from the altitude (z)
|
||||
*/
|
||||
optional<vec3> position = nullopt;
|
||||
|
||||
/** Orientation of the camera represented as a unit quaternion [x, y, z, w].
|
||||
The default pose of the camera is such that the forward vector is looking up the -Z axis and
|
||||
the up vector is aligned with north orientation of the map:
|
||||
forward: [0, 0, -1]
|
||||
up: [0, -1, 0]
|
||||
right [1, 0, 0]
|
||||
|
||||
Orientation can be set freely but certain constraints still apply
|
||||
- Orientation must be representable with only pitch and bearing.
|
||||
- Pitch has an upper limit */
|
||||
optional<vec4> orientation = nullopt;
|
||||
|
||||
/** Helper function for setting the mercator position as Lat&Lng and altitude in meters */
|
||||
void setLocation(const LatLngAltitude& location);
|
||||
|
||||
/** Helper function for converting mercator position into Lat&Lng and altitude in meters.
|
||||
This function fails to return a value if `position` is invalid or is not set */
|
||||
optional<LatLngAltitude> getLocation() const;
|
||||
|
||||
/** Helper function for setting orientation of the camera by defining a focus point
|
||||
on the map. Up vector is required in certain scenarios where bearing can't be deduced
|
||||
from the viewing direction */
|
||||
void lookAtPoint(const LatLng& location, const optional<vec3>& upVector = nullopt);
|
||||
|
||||
/** Helper function for setting the orientation of the camera as a pitch and a bearing.
|
||||
Both values are in degrees */
|
||||
void setPitchBearing(double pitch, double bearing);
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
26
include/mbgl/map/change.hpp
Normal file
26
include/mbgl/map/change.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum MapChange : uint8_t {
|
||||
MapChangeRegionWillChange = 0,
|
||||
MapChangeRegionWillChangeAnimated = 1,
|
||||
MapChangeRegionIsChanging = 2,
|
||||
MapChangeRegionDidChange = 3,
|
||||
MapChangeRegionDidChangeAnimated = 4,
|
||||
MapChangeWillStartLoadingMap = 5,
|
||||
MapChangeDidFinishLoadingMap = 6,
|
||||
MapChangeDidFailLoadingMap = 7,
|
||||
MapChangeWillStartRenderingFrame = 8,
|
||||
MapChangeDidFinishRenderingFrame = 9,
|
||||
MapChangeDidFinishRenderingFrameFullyRendered = 10,
|
||||
MapChangeWillStartRenderingMap = 11,
|
||||
MapChangeDidFinishRenderingMap = 12,
|
||||
MapChangeDidFinishRenderingMapFullyRendered = 13,
|
||||
MapChangeDidFinishLoadingStyle = 14,
|
||||
MapChangeSourceDidChange = 15
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
154
include/mbgl/map/map.hpp
Normal file
154
include/mbgl/map/map.hpp
Normal file
@@ -0,0 +1,154 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/map/bound_options.hpp>
|
||||
#include <mbgl/map/map_observer.hpp>
|
||||
#include <mbgl/map/map_options.hpp>
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/map/projection_mode.hpp>
|
||||
#include <mbgl/storage/resource_options.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RendererFrontend;
|
||||
|
||||
namespace style {
|
||||
class Image;
|
||||
class Style;
|
||||
} // namespace style
|
||||
|
||||
class Map : private util::noncopyable {
|
||||
public:
|
||||
explicit Map(RendererFrontend&,
|
||||
MapObserver&,
|
||||
const MapOptions&,
|
||||
const ResourceOptions&);
|
||||
~Map();
|
||||
|
||||
// Register a callback that will get called (on the render thread) when all resources have
|
||||
// been loaded and a complete render occurs.
|
||||
using StillImageCallback = std::function<void (std::exception_ptr)>;
|
||||
void renderStill(StillImageCallback);
|
||||
void renderStill(const CameraOptions&, MapDebugOptions, StillImageCallback);
|
||||
|
||||
// Triggers a repaint.
|
||||
void triggerRepaint();
|
||||
|
||||
style::Style& getStyle();
|
||||
const style::Style& getStyle() const;
|
||||
|
||||
void setStyle(std::unique_ptr<style::Style>);
|
||||
|
||||
// Transition
|
||||
void cancelTransitions();
|
||||
void setGestureInProgress(bool);
|
||||
bool isGestureInProgress() const;
|
||||
bool isRotating() const;
|
||||
bool isScaling() const;
|
||||
bool isPanning() const;
|
||||
|
||||
// Camera
|
||||
CameraOptions getCameraOptions(const optional<EdgeInsets>& = {}) const;
|
||||
void jumpTo(const CameraOptions&);
|
||||
void easeTo(const CameraOptions&, const AnimationOptions&);
|
||||
void flyTo(const CameraOptions&, const AnimationOptions&);
|
||||
void moveBy(const ScreenCoordinate&, const AnimationOptions& = {});
|
||||
void scaleBy(double scale, const optional<ScreenCoordinate>& anchor, const AnimationOptions& animation = {});
|
||||
void pitchBy(double pitch, const AnimationOptions& animation = {});
|
||||
void rotateBy(const ScreenCoordinate& first, const ScreenCoordinate& second, const AnimationOptions& = {});
|
||||
CameraOptions cameraForLatLngBounds(const LatLngBounds&,
|
||||
const EdgeInsets&,
|
||||
const optional<double>& bearing = {},
|
||||
const optional<double>& pitch = {}) const;
|
||||
CameraOptions cameraForLatLngs(const std::vector<LatLng>&,
|
||||
const EdgeInsets&,
|
||||
const optional<double>& bearing = {},
|
||||
const optional<double>& pitch = {}) const;
|
||||
CameraOptions cameraForGeometry(const Geometry<double>&,
|
||||
const EdgeInsets&,
|
||||
const optional<double>& bearing = {},
|
||||
const optional<double>& pitch = {}) const;
|
||||
LatLngBounds latLngBoundsForCamera(const CameraOptions&) const;
|
||||
LatLngBounds latLngBoundsForCameraUnwrapped(const CameraOptions&) const;
|
||||
|
||||
/// @name Bounds
|
||||
/// @{
|
||||
|
||||
void setBounds(const BoundOptions& options);
|
||||
|
||||
/// Returns the current map bound options. All optional fields in BoundOptions are set.
|
||||
BoundOptions getBounds() const;
|
||||
|
||||
/// @}
|
||||
|
||||
// Map Options
|
||||
void setNorthOrientation(NorthOrientation);
|
||||
void setConstrainMode(ConstrainMode);
|
||||
void setViewportMode(ViewportMode);
|
||||
void setSize(Size);
|
||||
MapOptions getMapOptions() const;
|
||||
|
||||
//Projection Mode
|
||||
void setProjectionMode(const ProjectionMode&);
|
||||
ProjectionMode getProjectionMode() const;
|
||||
|
||||
// Projection
|
||||
ScreenCoordinate pixelForLatLng(const LatLng&) const;
|
||||
LatLng latLngForPixel(const ScreenCoordinate&) const;
|
||||
std::vector<ScreenCoordinate> pixelsForLatLngs(const std::vector<LatLng>&) const;
|
||||
std::vector<LatLng> latLngsForPixels(const std::vector<ScreenCoordinate>&) const;
|
||||
|
||||
// Annotations
|
||||
void addAnnotationImage(std::unique_ptr<style::Image>);
|
||||
void removeAnnotationImage(const std::string&);
|
||||
double getTopOffsetPixelsForAnnotationImage(const std::string&);
|
||||
|
||||
AnnotationID addAnnotation(const Annotation&);
|
||||
void updateAnnotation(AnnotationID, const Annotation&);
|
||||
void removeAnnotation(AnnotationID);
|
||||
|
||||
// Tile prefetching
|
||||
//
|
||||
// When loading a map, if `PrefetchZoomDelta` is set to any number greater than 0, the map will
|
||||
// first request a tile for `zoom - delta` in a attempt to display a full map at lower
|
||||
// resolution as quick as possible. It will get clamped at the tile source minimum zoom. The
|
||||
// default `delta` is 4.
|
||||
void setPrefetchZoomDelta(uint8_t delta);
|
||||
uint8_t getPrefetchZoomDelta() const;
|
||||
|
||||
// Debug
|
||||
void setDebug(MapDebugOptions);
|
||||
MapDebugOptions getDebug() const;
|
||||
|
||||
bool isFullyLoaded() const;
|
||||
void dumpDebugLogs() const;
|
||||
|
||||
// FreeCameraOptions provides more direct access to the underlying camera entity.
|
||||
// For backwards compatibility the state set using this API must be representable with
|
||||
// `CameraOptions` as well. Parameters are clamped to a valid range or discarded as invalid
|
||||
// if the conversion to the pitch and bearing presentation is ambiguous. For example orientation
|
||||
// can be invalid if it leads to the camera being upside down or the quaternion has zero length.
|
||||
void setFreeCameraOptions(const FreeCameraOptions& camera);
|
||||
FreeCameraOptions getFreeCameraOptions() const;
|
||||
|
||||
protected:
|
||||
class Impl;
|
||||
const std::unique_ptr<Impl> impl;
|
||||
|
||||
// For testing only.
|
||||
Map(std::unique_ptr<Impl>);
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
62
include/mbgl/map/map_observer.hpp
Normal file
62
include/mbgl/map/map_observer.hpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/style/image.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
enum class MapLoadError {
|
||||
StyleParseError,
|
||||
StyleLoadError,
|
||||
NotFoundError,
|
||||
UnknownError,
|
||||
};
|
||||
|
||||
class MapObserver {
|
||||
public:
|
||||
virtual ~MapObserver() = default;
|
||||
|
||||
static MapObserver& nullObserver() {
|
||||
static MapObserver mapObserver;
|
||||
return mapObserver;
|
||||
}
|
||||
|
||||
enum class CameraChangeMode : uint32_t {
|
||||
Immediate,
|
||||
Animated
|
||||
};
|
||||
|
||||
enum class RenderMode : uint32_t {
|
||||
Partial,
|
||||
Full
|
||||
};
|
||||
|
||||
struct RenderFrameStatus {
|
||||
RenderMode mode;
|
||||
bool needsRepaint; // In continous mode, shows that there are ongoig transitions.
|
||||
bool placementChanged;
|
||||
};
|
||||
|
||||
virtual void onCameraWillChange(CameraChangeMode) {}
|
||||
virtual void onCameraIsChanging() {}
|
||||
virtual void onCameraDidChange(CameraChangeMode) {}
|
||||
virtual void onWillStartLoadingMap() {}
|
||||
virtual void onDidFinishLoadingMap() {}
|
||||
virtual void onDidFailLoadingMap(MapLoadError, const std::string&) {}
|
||||
virtual void onWillStartRenderingFrame() {}
|
||||
virtual void onDidFinishRenderingFrame(RenderFrameStatus) {}
|
||||
virtual void onWillStartRenderingMap() {}
|
||||
virtual void onDidFinishRenderingMap(RenderMode) {}
|
||||
virtual void onDidFinishLoadingStyle() {}
|
||||
virtual void onSourceChanged(style::Source&) {}
|
||||
virtual void onDidBecomeIdle() {}
|
||||
virtual void onStyleImageMissing(const std::string&) {}
|
||||
// This method should return true if unused image can be removed,
|
||||
// false otherwise. By default, unused image will be removed.
|
||||
virtual bool onCanRemoveUnusedStyleImage(const std::string&) { return true; }
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
142
include/mbgl/map/map_options.hpp
Normal file
142
include/mbgl/map/map_options.hpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/map/mode.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/size.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/**
|
||||
* @brief Holds values for Map options.
|
||||
*/
|
||||
class MapOptions final {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a MapOptions object with default values.
|
||||
*/
|
||||
MapOptions();
|
||||
~MapOptions();
|
||||
|
||||
MapOptions(MapOptions&&) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Sets the map rendering mode. By default, it is set to Continuous
|
||||
* so the map will render as data arrives from the network and react
|
||||
* immediately to state changes.
|
||||
*
|
||||
* @param mode Map rendering mode.
|
||||
* @return MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withMapMode(MapMode mode);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) map mode.
|
||||
*
|
||||
* @return map mode.
|
||||
*/
|
||||
MapMode mapMode() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the map constrain mode. This can be used to limit the map
|
||||
* to wrap around the globe horizontally. By default, it is set to
|
||||
* HeightOnly.
|
||||
*
|
||||
* @param mode Map constrain mode.
|
||||
* @return MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withConstrainMode(ConstrainMode mode);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) constrain mode.
|
||||
*
|
||||
* @return constrain mode.
|
||||
*/
|
||||
ConstrainMode constrainMode() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the viewport mode. This can be used to flip the vertical
|
||||
* orientation of the map as some devices may use inverted orientation.
|
||||
*
|
||||
* @param mode Viewport mode.
|
||||
* @return MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withViewportMode(ViewportMode mode);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) viewport mode.
|
||||
*
|
||||
* @return viewport mode.
|
||||
*/
|
||||
ViewportMode viewportMode() const;
|
||||
|
||||
/**
|
||||
* @brief Specify whether to enable cross-source symbol collision detection
|
||||
* or not. By default, it is set to true.
|
||||
*
|
||||
* @param enableCollisions true to enable, false to disable
|
||||
* @return MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withCrossSourceCollisions(bool enableCollisions);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) crossSourceCollisions value.
|
||||
*
|
||||
* @return true if ecross-source symbol collision detection enabled,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool crossSourceCollisions() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the orientation of the Map. By default, it is set to
|
||||
* Upwards.
|
||||
*
|
||||
* @param orientation Orientation of the Map.
|
||||
* @return reference to MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withNorthOrientation(NorthOrientation orientation);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) orientation.
|
||||
*
|
||||
* @return Map orientation.
|
||||
*/
|
||||
NorthOrientation northOrientation() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the size to resize the map object and renderer backend.
|
||||
*
|
||||
* @param size_ A size given in logical pixels.
|
||||
* @return reference to MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withSize(Size size_);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set size.
|
||||
*
|
||||
* @return Size.
|
||||
*/
|
||||
Size size() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the custom pixel ratio. By default, it is set to 1.
|
||||
*
|
||||
* @param ratio Pixel ratio value.
|
||||
* @return reference to MapOptions for chaining options together.
|
||||
*/
|
||||
MapOptions& withPixelRatio(float ratio);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) pixel ratio value.
|
||||
*
|
||||
* @return pixel ratio value.
|
||||
*/
|
||||
float pixelRatio() const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
64
include/mbgl/map/mode.hpp
Normal file
64
include/mbgl/map/mode.hpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/util.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using EnumType = uint32_t;
|
||||
|
||||
enum class MapMode : EnumType {
|
||||
Continuous, // continually updating map
|
||||
Static, // a once-off still image of an arbitrary viewport
|
||||
Tile // a once-off still image of a single tile
|
||||
};
|
||||
|
||||
// We can choose to constrain the map both horizontally or vertically, or only
|
||||
// vertically e.g. while panning.
|
||||
enum class ConstrainMode : EnumType {
|
||||
None,
|
||||
HeightOnly,
|
||||
WidthAndHeight,
|
||||
};
|
||||
|
||||
// Satisfies embedding platforms that requires the viewport coordinate systems
|
||||
// to be set according to its standards.
|
||||
enum class ViewportMode : EnumType {
|
||||
Default,
|
||||
FlippedY,
|
||||
};
|
||||
|
||||
enum class MapDebugOptions : EnumType {
|
||||
NoDebug = 0,
|
||||
TileBorders = 1 << 1,
|
||||
ParseStatus = 1 << 2,
|
||||
Timestamps = 1 << 3,
|
||||
Collision = 1 << 4,
|
||||
Overdraw = 1 << 5,
|
||||
StencilClip = 1 << 6,
|
||||
DepthBuffer = 1 << 7,
|
||||
};
|
||||
|
||||
MBGL_CONSTEXPR MapDebugOptions operator|(MapDebugOptions lhs, MapDebugOptions rhs) {
|
||||
return MapDebugOptions(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs));
|
||||
}
|
||||
|
||||
MBGL_CONSTEXPR MapDebugOptions& operator|=(MapDebugOptions& lhs, MapDebugOptions rhs) {
|
||||
return (lhs = MapDebugOptions(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs)));
|
||||
}
|
||||
|
||||
MBGL_CONSTEXPR bool operator&(MapDebugOptions lhs, MapDebugOptions rhs) {
|
||||
return mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs);
|
||||
}
|
||||
|
||||
MBGL_CONSTEXPR MapDebugOptions& operator&=(MapDebugOptions& lhs, MapDebugOptions rhs) {
|
||||
return (lhs = MapDebugOptions(mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs)));
|
||||
}
|
||||
|
||||
MBGL_CONSTEXPR MapDebugOptions operator~(MapDebugOptions value) {
|
||||
return MapDebugOptions(~mbgl::underlying_type(value));
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
34
include/mbgl/map/projection_mode.hpp
Normal file
34
include/mbgl/map/projection_mode.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/**
|
||||
* @brief Holds values for Axonometric rendering. All fields are
|
||||
* optional.
|
||||
*/
|
||||
struct ProjectionMode {
|
||||
ProjectionMode& withAxonometric(bool o) { axonometric = o; return *this; }
|
||||
ProjectionMode& withXSkew(double o) { xSkew = o; return *this; }
|
||||
ProjectionMode& withYSkew(double o) { ySkew = o; return *this; }
|
||||
|
||||
/**
|
||||
* @brief Set to True to enable axonometric rendering, false otherwise.
|
||||
*/
|
||||
optional<bool> axonometric;
|
||||
|
||||
/**
|
||||
* @brief The X skew value represents how much to skew on the x-axis.
|
||||
*/
|
||||
optional<double> xSkew;
|
||||
|
||||
/**
|
||||
* @brief The Y skew value represents how much to skew on the y-axis.
|
||||
*/
|
||||
optional<double> ySkew;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
14
include/mbgl/math/clamp.hpp
Normal file
14
include/mbgl/math/clamp.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/math/minmax.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
template <typename T>
|
||||
T clamp(T value, T min_, T max_) {
|
||||
return max(min_, min(max_, value));
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
41
include/mbgl/math/log2.hpp
Normal file
41
include/mbgl/math/log2.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include <android/api-level.h>
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
// Computes the log2(x) rounded up to the next integer.
|
||||
// (== number of bits required to store x)
|
||||
uint32_t ceil_log2(uint64_t x);
|
||||
|
||||
template <typename T>
|
||||
T log2(T x) {
|
||||
// log2() is producing wrong results on ARMv5 binaries
|
||||
// running on ARMv7+ CPUs.
|
||||
#if defined(__ANDROID__)
|
||||
return ::log(x) / M_LN2;
|
||||
#else
|
||||
return ::log2(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
|
||||
// log2 is not available on Android before API 18.
|
||||
#if defined(__ANDROID__) && defined(__GNUC__) && \
|
||||
defined(__ANDROID_API__) && __ANDROID_API__ < 18
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if_t<std::is_floating_point<T>::value, T> log2(T x) {
|
||||
return ::log(x) / M_LN2;
|
||||
}
|
||||
|
||||
#endif
|
||||
41
include/mbgl/math/minmax.hpp
Normal file
41
include/mbgl/math/minmax.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if_t<std::is_integral<T>::value, T> max(T a, T b) {
|
||||
return std::max(a, b);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if_t<std::is_floating_point<T>::value, T> max(T a, T b) {
|
||||
return ::fmax(a, b);
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
typename std::enable_if_t<std::is_arithmetic<T>::value, T> max(T a, T b, Ts... args) {
|
||||
return max(a, max(b, args...));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if_t<std::is_integral<T>::value, T> min(T a, T b) {
|
||||
return std::min(a, b);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename std::enable_if_t<std::is_floating_point<T>::value, T> min(T a, T b) {
|
||||
return ::fmin(a, b);
|
||||
}
|
||||
|
||||
template <typename T, typename... Ts>
|
||||
typename std::enable_if_t<std::is_arithmetic<T>::value, T> min(T a, T b, Ts... args) {
|
||||
return min(a, min(b, args...));
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
24
include/mbgl/math/wrap.hpp
Normal file
24
include/mbgl/math/wrap.hpp
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
// Constrains n to the given range (including min, excluding max) via modular
|
||||
// arithmetic.
|
||||
template <typename T>
|
||||
T wrap(T value, T min, T max) {
|
||||
if (value >= min && value < max) {
|
||||
return value;
|
||||
} else if (value == max) {
|
||||
return min;
|
||||
}
|
||||
|
||||
const T delta = max - min;
|
||||
const T wrapped = min + std::fmod(value - min, delta);
|
||||
return value < min ? wrapped + delta : wrapped;
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
} // namespace mbgl
|
||||
337
include/mbgl/platform/gl_functions.hpp
Normal file
337
include/mbgl/platform/gl_functions.hpp
Normal file
@@ -0,0 +1,337 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
// Pointers to OpenGL ES 2.0 functions. They must be
|
||||
// initialized by the platform at linking time.
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define MBGL_CHECK_ERROR(cmd) ([&]() { struct __MBGL_CHECK_ERROR { ~__MBGL_CHECK_ERROR() noexcept(false) { mbgl::platform::glCheckError(#cmd, __FILE__, __LINE__); } } __MBGL_CHECK_ERROR; return cmd; }())
|
||||
#else
|
||||
#define MBGL_CHECK_ERROR(cmd) (cmd)
|
||||
#endif
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
using GLbitfield = unsigned int;
|
||||
using GLboolean = unsigned char;
|
||||
using GLchar = char;
|
||||
using GLdouble = double;
|
||||
using GLenum = unsigned int;
|
||||
using GLfloat = float;
|
||||
using GLint = int;
|
||||
using GLsizei = int;
|
||||
using GLubyte = unsigned char;
|
||||
using GLuint = unsigned int;
|
||||
using GLvoid = void;
|
||||
|
||||
#if defined(_WIN32)
|
||||
using GLintptr = long long;
|
||||
using GLsizeiptr = long long;
|
||||
#else
|
||||
using GLintptr = long;
|
||||
using GLsizeiptr = long;
|
||||
#endif
|
||||
|
||||
/// Pointer to glActiveTexture OpenGL function.
|
||||
extern void (* const glActiveTexture)(GLenum);
|
||||
/// Pointer to glAttachShader OpenGL function.
|
||||
extern void (* const glAttachShader)(GLuint, GLuint);
|
||||
/// Pointer to glBindAttribLocation OpenGL function.
|
||||
extern void (* const glBindAttribLocation)(GLuint, GLuint, const GLchar *);
|
||||
/// Pointer to glBindBuffer OpenGL function.
|
||||
extern void (* const glBindBuffer)(GLenum, GLuint);
|
||||
/// Pointer to glBindFramebuffer OpenGL function.
|
||||
extern void (* const glBindFramebuffer)(GLenum, GLuint);
|
||||
/// Pointer to glBindRenderbuffer OpenGL function.
|
||||
extern void (* const glBindRenderbuffer)(GLenum, GLuint);
|
||||
/// Pointer to glBindTexture OpenGL function.
|
||||
extern void (* const glBindTexture)(GLenum, GLuint);
|
||||
/// Pointer to glBlendColor OpenGL function.
|
||||
extern void (* const glBlendColor)(GLfloat, GLfloat, GLfloat, GLfloat);
|
||||
/// Pointer to glBlendEquation OpenGL function.
|
||||
extern void (* const glBlendEquation)(GLenum);
|
||||
/// Pointer to glBlendEquationSeparate OpenGL function.
|
||||
extern void (* const glBlendEquationSeparate)(GLenum, GLenum);
|
||||
/// Pointer to glBlendFunc OpenGL function.
|
||||
extern void (* const glBlendFunc)(GLenum, GLenum);
|
||||
/// Pointer to glBlendFuncSeparate OpenGL function.
|
||||
extern void (* const glBlendFuncSeparate)(GLenum, GLenum, GLenum, GLenum);
|
||||
/// Pointer to glBufferData OpenGL function.
|
||||
extern void (* const glBufferData)(GLenum, GLsizeiptr, const void *, GLenum);
|
||||
/// Pointer to glBufferSubData OpenGL function.
|
||||
extern void (* const glBufferSubData)(GLenum, GLintptr, GLsizeiptr, const void *);
|
||||
/// Pointer to glCheckFramebufferStatus OpenGL function.
|
||||
extern GLenum (* const glCheckFramebufferStatus)(GLenum);
|
||||
/// Pointer to glClear OpenGL function.
|
||||
extern void (* const glClear)(GLbitfield);
|
||||
/// Pointer to glClearColor OpenGL function.
|
||||
extern void (* const glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat);
|
||||
/// Pointer to glClearDepthf OpenGL function.
|
||||
extern void (* const glClearDepthf)(GLfloat);
|
||||
/// Pointer to glClearStencil OpenGL function.
|
||||
extern void (* const glClearStencil)(GLint);
|
||||
/// Pointer to glColorMask OpenGL function.
|
||||
extern void (* const glColorMask)(GLboolean, GLboolean, GLboolean, GLboolean);
|
||||
/// Pointer to glCompileShader OpenGL function.
|
||||
extern void (* const glCompileShader)(GLuint);
|
||||
/// Pointer to glCompressedTexImage2D OpenGL function.
|
||||
extern void (* const glCompressedTexImage2D)(GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const void *);
|
||||
/// Pointer to glCompressedTexSubImage2D OpenGL function.
|
||||
extern void (* const glCompressedTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const void *);
|
||||
/// Pointer to glCopyTexImage2D OpenGL function.
|
||||
extern void (* const glCopyTexImage2D)(GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint);
|
||||
/// Pointer to glCopyTexSubImage2D OpenGL function.
|
||||
extern void (* const glCopyTexSubImage2D)(GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei);
|
||||
/// Pointer to glCreateProgram OpenGL function.
|
||||
extern GLuint (* const glCreateProgram)();
|
||||
/// Pointer to glCreateShader OpenGL function.
|
||||
extern GLuint (* const glCreateShader)(GLenum);
|
||||
/// Pointer to glCullFace OpenGL function.
|
||||
extern void (* const glCullFace)(GLenum);
|
||||
/// Pointer to glDeleteBuffers OpenGL function.
|
||||
extern void (* const glDeleteBuffers)(GLsizei, const GLuint *);
|
||||
/// Pointer to glDeleteFramebuffers OpenGL function.
|
||||
extern void (* const glDeleteFramebuffers)(GLsizei, const GLuint *);
|
||||
/// Pointer to glDeleteProgram OpenGL function.
|
||||
extern void (* const glDeleteProgram)(GLuint);
|
||||
/// Pointer to glDeleteRenderbuffers OpenGL function.
|
||||
extern void (* const glDeleteRenderbuffers)(GLsizei, const GLuint *);
|
||||
/// Pointer to glDeleteShader OpenGL function.
|
||||
extern void (* const glDeleteShader)(GLuint);
|
||||
/// Pointer to glDeleteTextures OpenGL function.
|
||||
extern void (* const glDeleteTextures)(GLsizei, const GLuint *);
|
||||
/// Pointer to glDepthFunc OpenGL function.
|
||||
extern void (* const glDepthFunc)(GLenum);
|
||||
/// Pointer to glDepthMask OpenGL function.
|
||||
extern void (* const glDepthMask)(GLboolean);
|
||||
/// Pointer to glDepthRangef OpenGL function.
|
||||
extern void (* const glDepthRangef)(GLfloat, GLfloat);
|
||||
/// Pointer to glDetachShader OpenGL function.
|
||||
extern void (* const glDetachShader)(GLuint, GLuint);
|
||||
/// Pointer to glDisable OpenGL function.
|
||||
extern void (* const glDisable)(GLenum);
|
||||
/// Pointer to glDisableVertexAttribArray OpenGL function.
|
||||
extern void (* const glDisableVertexAttribArray)(GLuint);
|
||||
/// Pointer to glDrawArrays OpenGL function.
|
||||
extern void (* const glDrawArrays)(GLenum, GLint, GLsizei);
|
||||
/// Pointer to glDrawElements OpenGL function.
|
||||
extern void (* const glDrawElements)(GLenum, GLsizei, GLenum, const void *);
|
||||
/// Pointer to glEnable OpenGL function.
|
||||
extern void (* const glEnable)(GLenum);
|
||||
/// Pointer to glEnableVertexAttribArray OpenGL function.
|
||||
extern void (* const glEnableVertexAttribArray)(GLuint);
|
||||
/// Pointer to glFinish OpenGL function.
|
||||
extern void (* const glFinish)();
|
||||
/// Pointer to glFlush OpenGL function.
|
||||
extern void (* const glFlush)();
|
||||
/// Pointer to glFramebufferRenderbuffer OpenGL function.
|
||||
extern void (* const glFramebufferRenderbuffer)(GLenum, GLenum, GLenum, GLuint);
|
||||
/// Pointer to glFramebufferTexture2D OpenGL function.
|
||||
extern void (* const glFramebufferTexture2D)(GLenum, GLenum, GLenum, GLuint, GLint);
|
||||
/// Pointer to glFrontFace OpenGL function.
|
||||
extern void (* const glFrontFace)(GLenum);
|
||||
/// Pointer to glGenBuffers OpenGL function.
|
||||
extern void (* const glGenBuffers)(GLsizei, GLuint *);
|
||||
/// Pointer to glGenerateMipmap OpenGL function.
|
||||
extern void (* const glGenerateMipmap)(GLenum);
|
||||
/// Pointer to glGenFramebuffers OpenGL function.
|
||||
extern void (* const glGenFramebuffers)(GLsizei, GLuint *);
|
||||
/// Pointer to glGenRenderbuffers OpenGL function.
|
||||
extern void (* const glGenRenderbuffers)(GLsizei, GLuint *);
|
||||
/// Pointer to glGenTextures OpenGL function.
|
||||
extern void (* const glGenTextures)(GLsizei, GLuint *);
|
||||
/// Pointer to glGetActiveAttrib OpenGL function.
|
||||
extern void (* const glGetActiveAttrib)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *);
|
||||
/// Pointer to glGetActiveUniform OpenGL function.
|
||||
extern void (* const glGetActiveUniform)(GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *);
|
||||
/// Pointer to glGetAttachedShaders OpenGL function.
|
||||
extern void (* const glGetAttachedShaders)(GLuint, GLsizei, GLsizei *, GLuint *);
|
||||
/// Pointer to glGetAttribLocation OpenGL function.
|
||||
extern GLint (* const glGetAttribLocation)(GLuint, const GLchar *);
|
||||
/// Pointer to glGetBooleanv OpenGL function.
|
||||
extern void (* const glGetBooleanv)(GLenum, GLboolean *);
|
||||
/// Pointer to glGetBufferParameteriv OpenGL function.
|
||||
extern void (* const glGetBufferParameteriv)(GLenum, GLenum, GLint *);
|
||||
/// Pointer to glGetError OpenGL function.
|
||||
extern GLenum (* const glGetError)();
|
||||
/// Pointer to glGetFloatv OpenGL function.
|
||||
extern void (* const glGetFloatv)(GLenum, GLfloat *);
|
||||
/// Pointer to glGetFramebufferAttachmentParameteriv OpenGL function.
|
||||
extern void (* const glGetFramebufferAttachmentParameteriv)(GLenum, GLenum, GLenum, GLint *);
|
||||
/// Pointer to glGetIntegerv OpenGL function.
|
||||
extern void (* const glGetIntegerv)(GLenum, GLint *);
|
||||
/// Pointer to glGetProgramInfoLog OpenGL function.
|
||||
extern void (* const glGetProgramInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *);
|
||||
/// Pointer to glGetProgramiv OpenGL function.
|
||||
extern void (* const glGetProgramiv)(GLuint, GLenum, GLint *);
|
||||
/// Pointer to glGetRenderbufferParameteriv OpenGL function.
|
||||
extern void (* const glGetRenderbufferParameteriv)(GLenum, GLenum, GLint *);
|
||||
/// Pointer to glGetShaderInfoLog OpenGL function.
|
||||
extern void (* const glGetShaderInfoLog)(GLuint, GLsizei, GLsizei *, GLchar *);
|
||||
/// Pointer to glGetShaderiv OpenGL function.
|
||||
extern void (* const glGetShaderiv)(GLuint, GLenum, GLint *);
|
||||
/// Pointer to glGetShaderSource OpenGL function.
|
||||
extern void (* const glGetShaderSource)(GLuint, GLsizei, GLsizei *, GLchar *);
|
||||
/// Pointer to glGetString OpenGL function.
|
||||
extern const GLubyte *(*glGetString)(GLenum);
|
||||
/// Pointer to glGetTexParameterfv OpenGL function.
|
||||
extern void (* const glGetTexParameterfv)(GLenum, GLenum, GLfloat *);
|
||||
/// Pointer to glGetTexParameteriv OpenGL function.
|
||||
extern void (* const glGetTexParameteriv)(GLenum, GLenum, GLint *);
|
||||
/// Pointer to glGetUniformfv OpenGL function.
|
||||
extern void (* const glGetUniformfv)(GLuint, GLint, GLfloat *);
|
||||
/// Pointer to glGetUniformiv OpenGL function.
|
||||
extern void (* const glGetUniformiv)(GLuint, GLint, GLint *);
|
||||
/// Pointer to glGetUniformLocation OpenGL function.
|
||||
extern GLint (* const glGetUniformLocation)(GLuint, const GLchar *);
|
||||
/// Pointer to glGetVertexAttribfv OpenGL function.
|
||||
extern void (* const glGetVertexAttribfv)(GLuint, GLenum, GLfloat *);
|
||||
/// Pointer to glGetVertexAttribiv OpenGL function.
|
||||
extern void (* const glGetVertexAttribiv)(GLuint, GLenum, GLint *);
|
||||
/// Pointer to glGetVertexAttribPointerv OpenGL function.
|
||||
extern void (* const glGetVertexAttribPointerv)(GLuint, GLenum, void **);
|
||||
/// Pointer to glHint OpenGL function.
|
||||
extern void (* const glHint)(GLenum, GLenum);
|
||||
/// Pointer to glIsBuffer OpenGL function.
|
||||
extern GLboolean (* const glIsBuffer)(GLuint);
|
||||
/// Pointer to glIsEnabled OpenGL function.
|
||||
extern GLboolean (* const glIsEnabled)(GLenum);
|
||||
/// Pointer to glIsFramebuffer OpenGL function.
|
||||
extern GLboolean (* const glIsFramebuffer)(GLuint);
|
||||
/// Pointer to glIsProgram OpenGL function.
|
||||
extern GLboolean (* const glIsProgram)(GLuint);
|
||||
/// Pointer to glIsRenderbuffer OpenGL function.
|
||||
extern GLboolean (* const glIsRenderbuffer)(GLuint);
|
||||
/// Pointer to glIsShader OpenGL function.
|
||||
extern GLboolean (* const glIsShader)(GLuint);
|
||||
/// Pointer to glIsTexture OpenGL function.
|
||||
extern GLboolean (* const glIsTexture)(GLuint);
|
||||
/// Pointer to glLineWidth OpenGL function.
|
||||
extern void (* const glLineWidth)(GLfloat);
|
||||
/// Pointer to glLinkProgram OpenGL function.
|
||||
extern void (* const glLinkProgram)(GLuint);
|
||||
/// Pointer to glPixelStorei OpenGL function.
|
||||
extern void (* const glPixelStorei)(GLenum, GLint);
|
||||
/// Pointer to glPolygonOffset OpenGL function.
|
||||
extern void (* const glPolygonOffset)(GLfloat, GLfloat);
|
||||
/// Pointer to glReadPixels OpenGL function.
|
||||
extern void (* const glReadPixels)(GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, void *);
|
||||
/// Pointer to glRenderbufferStorage OpenGL function.
|
||||
extern void (* const glRenderbufferStorage)(GLenum, GLenum, GLsizei, GLsizei);
|
||||
/// Pointer to glSampleCoverage OpenGL function.
|
||||
extern void (* const glSampleCoverage)(GLfloat, GLboolean);
|
||||
/// Pointer to glScissor OpenGL function.
|
||||
extern void (* const glScissor)(GLint, GLint, GLsizei, GLsizei);
|
||||
/// Pointer to glShaderSource OpenGL function.
|
||||
extern void (* const glShaderSource)(GLuint, GLsizei, const GLchar * const*, const GLint *);
|
||||
/// Pointer to glStencilFunc OpenGL function.
|
||||
extern void (* const glStencilFunc)(GLenum, GLint, GLuint);
|
||||
/// Pointer to glStencilFuncSeparate OpenGL function.
|
||||
extern void (* const glStencilFuncSeparate)(GLenum, GLenum, GLint, GLuint);
|
||||
/// Pointer to glStencilMask OpenGL function.
|
||||
extern void (* const glStencilMask)(GLuint);
|
||||
/// Pointer to glStencilMaskSeparate OpenGL function.
|
||||
extern void (* const glStencilMaskSeparate)(GLenum, GLuint);
|
||||
/// Pointer to glStencilOp OpenGL function.
|
||||
extern void (* const glStencilOp)(GLenum, GLenum, GLenum);
|
||||
/// Pointer to glStencilOpSeparate OpenGL function.
|
||||
extern void (* const glStencilOpSeparate)(GLenum, GLenum, GLenum, GLenum);
|
||||
/// Pointer to glTexImage2D OpenGL function.
|
||||
extern void (* const glTexImage2D)(GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const void *);
|
||||
/// Pointer to glTexParameterf OpenGL function.
|
||||
extern void (* const glTexParameterf)(GLenum, GLenum, GLfloat);
|
||||
/// Pointer to glTexParameterfv OpenGL function.
|
||||
extern void (* const glTexParameterfv)(GLenum, GLenum, const GLfloat *);
|
||||
/// Pointer to glTexParameteri OpenGL function.
|
||||
extern void (* const glTexParameteri)(GLenum, GLenum, GLint);
|
||||
/// Pointer to glTexParameteriv OpenGL function.
|
||||
extern void (* const glTexParameteriv)(GLenum, GLenum, const GLint *);
|
||||
/// Pointer to glTexSubImage2D OpenGL function.
|
||||
extern void (* const glTexSubImage2D)(GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const void *);
|
||||
/// Pointer to glUniform1f OpenGL function.
|
||||
extern void (* const glUniform1f)(GLint, GLfloat);
|
||||
/// Pointer to glUniform1fv OpenGL function.
|
||||
extern void (* const glUniform1fv)(GLint, GLsizei, const GLfloat *);
|
||||
/// Pointer to glUniform1i OpenGL function.
|
||||
extern void (* const glUniform1i)(GLint, GLint);
|
||||
/// Pointer to glUniform1iv OpenGL function.
|
||||
extern void (* const glUniform1iv)(GLint, GLsizei, const GLint *);
|
||||
/// Pointer to glUniform2f OpenGL function.
|
||||
extern void (* const glUniform2f)(GLint, GLfloat, GLfloat);
|
||||
/// Pointer to glUniform2fv OpenGL function.
|
||||
extern void (* const glUniform2fv)(GLint, GLsizei, const GLfloat *);
|
||||
/// Pointer to glUniform2i OpenGL function.
|
||||
extern void (* const glUniform2i)(GLint, GLint, GLint);
|
||||
/// Pointer to glUniform2iv OpenGL function.
|
||||
extern void (* const glUniform2iv)(GLint, GLsizei, const GLint *);
|
||||
/// Pointer to glUniform3f OpenGL function.
|
||||
extern void (* const glUniform3f)(GLint, GLfloat, GLfloat, GLfloat);
|
||||
/// Pointer to glUniform3fv OpenGL function.
|
||||
extern void (* const glUniform3fv)(GLint, GLsizei, const GLfloat *);
|
||||
/// Pointer to glUniform3i OpenGL function.
|
||||
extern void (* const glUniform3i)(GLint, GLint, GLint, GLint);
|
||||
/// Pointer to glUniform3iv OpenGL function.
|
||||
extern void (* const glUniform3iv)(GLint, GLsizei, const GLint *);
|
||||
/// Pointer to glUniform4f OpenGL function.
|
||||
extern void (* const glUniform4f)(GLint, GLfloat, GLfloat, GLfloat, GLfloat);
|
||||
/// Pointer to glUniform4fv OpenGL function.
|
||||
extern void (* const glUniform4fv)(GLint, GLsizei, const GLfloat *);
|
||||
/// Pointer to glUniform4i OpenGL function.
|
||||
extern void (* const glUniform4i)(GLint, GLint, GLint, GLint, GLint);
|
||||
/// Pointer to glUniform4iv OpenGL function.
|
||||
extern void (* const glUniform4iv)(GLint, GLsizei, const GLint *);
|
||||
/// Pointer to glUniformMatrix2fv OpenGL function.
|
||||
extern void (* const glUniformMatrix2fv)(GLint, GLsizei, GLboolean, const GLfloat *);
|
||||
/// Pointer to glUniformMatrix3fv OpenGL function.
|
||||
extern void (* const glUniformMatrix3fv)(GLint, GLsizei, GLboolean, const GLfloat *);
|
||||
/// Pointer to glUniformMatrix4fv OpenGL function.
|
||||
extern void (* const glUniformMatrix4fv)(GLint, GLsizei, GLboolean, const GLfloat *);
|
||||
/// Pointer to glUseProgram OpenGL function.
|
||||
extern void (* const glUseProgram)(GLuint);
|
||||
/// Pointer to glValidateProgram OpenGL function.
|
||||
extern void (* const glValidateProgram)(GLuint);
|
||||
/// Pointer to glVertexAttrib1f OpenGL function.
|
||||
extern void (* const glVertexAttrib1f)(GLuint, GLfloat);
|
||||
/// Pointer to glVertexAttrib1fv OpenGL function.
|
||||
extern void (* const glVertexAttrib1fv)(GLuint, const GLfloat *);
|
||||
/// Pointer to glVertexAttrib2f OpenGL function.
|
||||
extern void (* const glVertexAttrib2f)(GLuint, GLfloat, GLfloat);
|
||||
/// Pointer to glVertexAttrib2fv OpenGL function.
|
||||
extern void (* const glVertexAttrib2fv)(GLuint, const GLfloat *);
|
||||
/// Pointer to glVertexAttrib3f OpenGL function.
|
||||
extern void (* const glVertexAttrib3f)(GLuint, GLfloat, GLfloat, GLfloat);
|
||||
/// Pointer to glVertexAttrib3fv OpenGL function.
|
||||
extern void (* const glVertexAttrib3fv)(GLuint, const GLfloat *);
|
||||
/// Pointer to glVertexAttrib4f OpenGL function.
|
||||
extern void (* const glVertexAttrib4f)(GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
|
||||
/// Pointer to glVertexAttrib4fv OpenGL function.
|
||||
extern void (* const glVertexAttrib4fv)(GLuint, const GLfloat *);
|
||||
/// Pointer to glVertexAttribPointer OpenGL function.
|
||||
extern void (* const glVertexAttribPointer)(GLuint, GLint, GLenum, GLboolean, GLsizei, const void *);
|
||||
/// Pointer to glViewport OpenGL function.
|
||||
extern void (* const glViewport)(GLint, GLint, GLsizei, GLsizei);
|
||||
|
||||
#ifndef MBGL_USE_GLES2
|
||||
/// Pointer to glDrawPixels OpenGL function.
|
||||
extern void (* const glDrawPixels)(GLsizei, GLsizei, GLenum, GLenum, const GLvoid *);
|
||||
/// Pointer to glGetDoublev OpenGL function.
|
||||
extern void (* const glGetDoublev)(GLenum, GLdouble *);
|
||||
/// Pointer to glPixelTransferf OpenGL function.
|
||||
extern void (* const glPixelTransferf)(GLenum, GLfloat);
|
||||
/// Pointer to glPixelZoom OpenGL function.
|
||||
extern void (* const glPixelZoom)(GLfloat, GLfloat);
|
||||
/// Pointer to glPointSize OpenGL function.
|
||||
extern void (* const glPointSize)(GLfloat);
|
||||
/// Pointer to glRasterPos4d OpenGL function.
|
||||
extern void (* const glRasterPos4d)(GLdouble, GLdouble, GLdouble, GLdouble);
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// Check for GL errors and print on the console.
|
||||
void glCheckError(const char *cmd, const char *file, int line);
|
||||
#endif
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
48
include/mbgl/platform/settings.hpp
Normal file
48
include/mbgl/platform/settings.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <mapbox/compatibility/value.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
#define DECLARE_MAPBOX_SETTING(name, value) constexpr const char* name = "mapbox_" #value
|
||||
|
||||
// The value for EXPERIMENTAL_THREAD_PRIORITY_* keys, must be a double.
|
||||
DECLARE_MAPBOX_SETTING(EXPERIMENTAL_THREAD_PRIORITY_WORKER, thread_priority_worker);
|
||||
DECLARE_MAPBOX_SETTING(EXPERIMENTAL_THREAD_PRIORITY_FILE, thread_priority_file);
|
||||
DECLARE_MAPBOX_SETTING(EXPERIMENTAL_THREAD_PRIORITY_NETWORK, thread_priority_network);
|
||||
DECLARE_MAPBOX_SETTING(EXPERIMENTAL_THREAD_PRIORITY_DATABASE, thread_priority_database);
|
||||
|
||||
// Settings class provides non-persistent, in-process key-value storage.
|
||||
class Settings final {
|
||||
public:
|
||||
// Returns singleton instance
|
||||
static Settings& getInstance() noexcept;
|
||||
|
||||
// Sets setting value for a specified key.
|
||||
void set(const std::string& key, mapbox::base::Value value) noexcept;
|
||||
|
||||
// Sets multiple setting values by merging current Settings object
|
||||
// with provided `values` object.
|
||||
void set(const mapbox::base::ValueObject& values) noexcept;
|
||||
|
||||
// Returns setting value for a specified key or NullValue if element
|
||||
// for specified key is missing.
|
||||
mapbox::base::Value get(const std::string& key) const noexcept;
|
||||
|
||||
// Returns values for settings whose keys are equal to the ones provided in `keys` argument.
|
||||
// Null values would be provided for keys whose elements are missing in Settings.
|
||||
mapbox::base::ValueObject get(const std::vector<std::string>& keys) const noexcept;
|
||||
|
||||
private:
|
||||
Settings();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
13
include/mbgl/platform/thread.hpp
Normal file
13
include/mbgl/platform/thread.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Called when a thread is created
|
||||
void attachThread();
|
||||
|
||||
// Called when a thread is destroyed
|
||||
void detachThread();
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
13
include/mbgl/platform/time.hpp
Normal file
13
include/mbgl/platform/time.hpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
|
||||
namespace mbgl {
|
||||
namespace platform {
|
||||
|
||||
// Returns the current time. Abstracted because some platforms
|
||||
// will not allow direct access to the current time via syscall.
|
||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> now();
|
||||
|
||||
} // namespace platform
|
||||
} // namespace mbgl
|
||||
43
include/mbgl/renderer/query.hpp
Normal file
43
include/mbgl/renderer/query.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/style/filter.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/**
|
||||
* Options for query rendered features.
|
||||
*/
|
||||
class RenderedQueryOptions {
|
||||
public:
|
||||
RenderedQueryOptions(optional<std::vector<std::string>> layerIDs_ = {},
|
||||
optional<style::Filter> filter_ = {})
|
||||
: layerIDs(std::move(layerIDs_)),
|
||||
filter(std::move(filter_)) {}
|
||||
|
||||
/** layerIDs to include in the query */
|
||||
optional<std::vector<std::string>> layerIDs;
|
||||
|
||||
optional<style::Filter> filter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Options for query source features
|
||||
*/
|
||||
class SourceQueryOptions {
|
||||
public:
|
||||
SourceQueryOptions(optional<std::vector<std::string>> sourceLayers_ = {},
|
||||
optional<style::Filter> filter_ = {})
|
||||
: sourceLayers(std::move(sourceLayers_)),
|
||||
filter(std::move(filter_)) {}
|
||||
|
||||
// Required for VectorSource, ignored for GeoJSONSource
|
||||
optional<std::vector<std::string>> sourceLayers;
|
||||
|
||||
optional<style::Filter> filter;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
113
include/mbgl/renderer/renderer.hpp
Normal file
113
include/mbgl/renderer/renderer.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/query.hpp>
|
||||
#include <mbgl/annotation/annotation.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/geojson.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RendererObserver;
|
||||
class RenderedQueryOptions;
|
||||
class SourceQueryOptions;
|
||||
class UpdateParameters;
|
||||
|
||||
namespace gfx {
|
||||
class RendererBackend;
|
||||
} // namespace gfx
|
||||
|
||||
struct PlacedSymbolData {
|
||||
// Contents of the label
|
||||
std::u16string key;
|
||||
// If symbol contains text, text collision box in viewport coordinates
|
||||
optional<mapbox::geometry::box<float>> textCollisionBox;
|
||||
// If symbol contains icon, icon collision box in viewport coordinates
|
||||
optional<mapbox::geometry::box<float>> iconCollisionBox;
|
||||
// Symbol text was placed
|
||||
bool textPlaced;
|
||||
// Symbol icon was placed
|
||||
bool iconPlaced;
|
||||
// Symbol text or icon collision box intersects tile borders
|
||||
bool intersectsTileBorder;
|
||||
// Viewport padding ({viewportPadding, viewportPadding} is a coordinate of the tile's top-left corner)
|
||||
float viewportPadding;
|
||||
// Layer id (leader of the symbol layout group)
|
||||
std::string layer;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
Renderer(gfx::RendererBackend&, float pixelRatio_, const optional<std::string>& localFontFamily = {});
|
||||
~Renderer();
|
||||
|
||||
void markContextLost();
|
||||
|
||||
void setObserver(RendererObserver*);
|
||||
|
||||
void render(const std::shared_ptr<UpdateParameters>&);
|
||||
|
||||
// Feature queries
|
||||
std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions& options = {}) const;
|
||||
std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate& point, const RenderedQueryOptions& options = {}) const;
|
||||
std::vector<Feature> queryRenderedFeatures(const ScreenBox& box, const RenderedQueryOptions& options = {}) const;
|
||||
std::vector<Feature> querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options = {}) const;
|
||||
AnnotationIDs queryPointAnnotations(const ScreenBox& box) const;
|
||||
AnnotationIDs queryShapeAnnotations(const ScreenBox& box) const;
|
||||
AnnotationIDs getAnnotationIDs(const std::vector<Feature>&) const;
|
||||
|
||||
// Feature extension query
|
||||
FeatureExtensionValue queryFeatureExtensions(const std::string& sourceID,
|
||||
const Feature& feature,
|
||||
const std::string& extension,
|
||||
const std::string& extensionField,
|
||||
const optional<std::map<std::string, Value>>& args = {}) const;
|
||||
|
||||
void setFeatureState(const std::string& sourceID, const optional<std::string>& sourceLayerID,
|
||||
const std::string& featureID, const FeatureState& state);
|
||||
|
||||
void getFeatureState(FeatureState& state,
|
||||
const std::string& sourceID,
|
||||
const optional<std::string>& sourceLayerID,
|
||||
const std::string& featureID) const;
|
||||
|
||||
void removeFeatureState(const std::string& sourceID,
|
||||
const optional<std::string>& sourceLayerID,
|
||||
const optional<std::string>& featureID,
|
||||
const optional<std::string>& stateKey);
|
||||
|
||||
// Debug
|
||||
void dumpDebugLogs();
|
||||
|
||||
/**
|
||||
* @brief In Tile map mode, enables or disables collecting of the placed symbols data,
|
||||
* which can be obtained with `getPlacedSymbolsData()`.
|
||||
*
|
||||
* The placed symbols data collecting is disabled by default.
|
||||
*/
|
||||
void collectPlacedSymbolData(bool enable);
|
||||
|
||||
/**
|
||||
* @brief If collecting of the placed symbols data is enabled, returns the reference
|
||||
* to the `PlacedSymbolData` vector holding the collected data.
|
||||
*
|
||||
* Note: the returned vector gets re-populated at every `render()` call.
|
||||
*
|
||||
* @return collected placed symbols data
|
||||
*/
|
||||
const std::vector<PlacedSymbolData>& getPlacedSymbolsData() const;
|
||||
|
||||
// Memory
|
||||
void reduceMemoryUse();
|
||||
void clearData();
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
31
include/mbgl/renderer/renderer_frontend.hpp
Normal file
31
include/mbgl/renderer/renderer_frontend.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RendererObserver;
|
||||
class UpdateParameters;
|
||||
|
||||
// The RenderFrontend is the bridge between the Map and
|
||||
// platform used to update and observer the Renderer
|
||||
//
|
||||
// It hides any threading specifics and always replies on
|
||||
// the original thread.
|
||||
class RendererFrontend {
|
||||
public:
|
||||
|
||||
virtual ~RendererFrontend() = default;
|
||||
|
||||
// Must synchronously clean up the Renderer if set
|
||||
virtual void reset() = 0;
|
||||
|
||||
// Implementer must bind the renderer observer to the renderer in a
|
||||
// appropriate manner so that the callbacks occur on the main thread
|
||||
virtual void setObserver(RendererObserver&) = 0;
|
||||
|
||||
// Coalescing updates is up to the implementer
|
||||
virtual void update(std::shared_ptr<UpdateParameters>) = 0;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
41
include/mbgl/renderer/renderer_observer.hpp
Normal file
41
include/mbgl/renderer/renderer_observer.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class RendererObserver {
|
||||
public:
|
||||
virtual ~RendererObserver() = default;
|
||||
|
||||
enum class RenderMode : uint32_t {
|
||||
Partial,
|
||||
Full
|
||||
};
|
||||
|
||||
// Signals that a repaint is required
|
||||
virtual void onInvalidate() {}
|
||||
|
||||
// Resource failed to download / parse
|
||||
virtual void onResourceError(std::exception_ptr) {}
|
||||
|
||||
// First frame
|
||||
virtual void onWillStartRenderingMap() {}
|
||||
|
||||
// Start of frame, initial is the first frame for this map
|
||||
virtual void onWillStartRenderingFrame() {}
|
||||
|
||||
// End of frame, booleans flags that a repaint is required and that placement changed.
|
||||
virtual void onDidFinishRenderingFrame(RenderMode, bool /*repaint*/, bool /*placementChanged*/) {}
|
||||
|
||||
// Final frame
|
||||
virtual void onDidFinishRenderingMap() {}
|
||||
|
||||
// Style is missing an image
|
||||
using StyleImageMissingCallback = std::function<void()>;
|
||||
virtual void onStyleImageMissing(const std::string&, const StyleImageMissingCallback& done) { done(); }
|
||||
virtual void onRemoveUnusedStyleImages(const std::vector<std::string>&) {}
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
36
include/mbgl/renderer/renderer_state.hpp
Normal file
36
include/mbgl/renderer/renderer_state.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class UpdateParameters;
|
||||
|
||||
/**
|
||||
* RendererState acts as a Memento object that is able to extract data out of UpdateParameters (an opaque object
|
||||
* from the public API perspective).
|
||||
*/
|
||||
class RendererState {
|
||||
public:
|
||||
|
||||
// Obtains a CameraOptions out of a given UpdateParameters object.
|
||||
static CameraOptions getCameraOptions(const UpdateParameters&, const EdgeInsets& = {});
|
||||
|
||||
// Returns whether an image with the given ID exists from a given UpdateParamters object.
|
||||
static bool hasImage(const UpdateParameters&, const std::string& id);
|
||||
|
||||
// Returns whether a layer with the given ID exists from a given UpdateParamters object.
|
||||
static bool hasLayer(const UpdateParameters&, const std::string& id);
|
||||
|
||||
// Returns whether a source with the given ID exists from a given UpdateParamters object.
|
||||
static bool hasSource(const UpdateParameters&, const std::string& id);
|
||||
|
||||
// Obtains the geographical coordinate out of a given screen coordinate.
|
||||
static ScreenCoordinate pixelForLatLng(const UpdateParameters&, const LatLng&);
|
||||
|
||||
// Obtains the screen coordinate out of a given geographical coordinate.
|
||||
static LatLng latLngForPixel(const UpdateParameters&, const ScreenCoordinate&);
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
240
include/mbgl/storage/database_file_source.hpp
Normal file
240
include/mbgl/storage/database_file_source.hpp
Normal file
@@ -0,0 +1,240 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/storage/offline.hpp>
|
||||
#include <mbgl/util/expected.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class ResourceOptions;
|
||||
|
||||
// TODO: Split DatabaseFileSource into Ambient cache and Database interfaces.
|
||||
class DatabaseFileSource : public FileSource {
|
||||
public:
|
||||
explicit DatabaseFileSource(const ResourceOptions& options);
|
||||
~DatabaseFileSource() override;
|
||||
|
||||
// FileSource overrides
|
||||
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
|
||||
void forward(const Resource&, const Response&, std::function<void()> callback) override;
|
||||
bool canRequest(const Resource&) const override;
|
||||
void setProperty(const std::string&, const mapbox::base::Value&) override;
|
||||
void pause() override;
|
||||
void resume() override;
|
||||
|
||||
// Methods common to Ambient cache and Offline functionality
|
||||
|
||||
/*
|
||||
* Sets path of a database to be used by DatabaseFileSource and invokes provided
|
||||
* callback when a database path is set.
|
||||
*/
|
||||
virtual void setDatabasePath(const std::string&, std::function<void()> callback);
|
||||
|
||||
/*
|
||||
* Delete existing database and re-initialize.
|
||||
*
|
||||
* When the operation is complete or encounters an error, the given callback will be
|
||||
* executed on the database thread; it is the responsibility of the SDK bindings
|
||||
* to re-execute a user-provided callback on the main thread.
|
||||
*/
|
||||
virtual void resetDatabase(std::function<void(std::exception_ptr)>);
|
||||
|
||||
/*
|
||||
* Packs the existing database file into a minimal amount of disk space.
|
||||
*
|
||||
* This operation has a performance impact as it will vacuum the database,
|
||||
* forcing it to move pages on the filesystem.
|
||||
*
|
||||
* When the operation is complete or encounters an error, the given callback will be
|
||||
* executed on the database thread; it is the responsibility of the SDK bindings
|
||||
* to re-execute a user-provided callback on the main thread.
|
||||
*/
|
||||
virtual void packDatabase(std::function<void(std::exception_ptr)> callback);
|
||||
|
||||
/*
|
||||
* Sets whether packing the database file occurs automatically after an offline
|
||||
* region is deleted (deleteOfflineRegion()) or the ambient cache is cleared
|
||||
* (clearAmbientCache()).
|
||||
*
|
||||
* By default, packing is enabled. If disabled, disk space will not be freed
|
||||
* after resources are removed unless packDatabase() is explicitly called.
|
||||
*/
|
||||
virtual void runPackDatabaseAutomatically(bool);
|
||||
|
||||
// Ambient cache
|
||||
|
||||
/*
|
||||
* Insert the provided resource into the ambient cache
|
||||
*
|
||||
* Consumers of the resource will expect the uncompressed version; the
|
||||
* OfflineDatabase will determine whether to compress the data on disk.
|
||||
* This call is asynchronous: the data may not be immediately available
|
||||
* for in-progress requests, although subsequent requests should have
|
||||
* access to the cached data.
|
||||
*/
|
||||
virtual void put(const Resource&, const Response&);
|
||||
|
||||
/*
|
||||
* Forces revalidation of the ambient cache.
|
||||
*
|
||||
* Forces Mapbox GL Native to revalidate resources stored in the ambient
|
||||
* cache with the tile server before using them, making sure they
|
||||
* are the latest version. This is more efficient than cleaning the
|
||||
* cache because if the resource is considered valid after the server
|
||||
* lookup, it will not get downloaded again.
|
||||
*
|
||||
* Resources overlapping with offline regions will not be affected
|
||||
* by this call.
|
||||
*/
|
||||
virtual void invalidateAmbientCache(std::function<void(std::exception_ptr)>);
|
||||
|
||||
/*
|
||||
* Erase resources from the ambient cache, freeing storage space.
|
||||
*
|
||||
* Erases the ambient cache, freeing resources.
|
||||
*
|
||||
* Note that this operation can be potentially slow if packing the database
|
||||
* occurs automatically (see runPackDatabaseAutomatically() and packDatabase()).
|
||||
*
|
||||
* Resources overlapping with offline regions will not be affected
|
||||
* by this call.
|
||||
*/
|
||||
virtual void clearAmbientCache(std::function<void(std::exception_ptr)>);
|
||||
|
||||
/*
|
||||
* Sets the maximum size in bytes for the ambient cache.
|
||||
*
|
||||
* This call is potentially expensive because it will try
|
||||
* to trim the data in case the database is larger than the
|
||||
* size defined. The size of offline regions are not affected
|
||||
* by this settings, but the ambient cache will always try
|
||||
* to not exceed the maximum size defined, taking into account
|
||||
* the current size for the offline regions.
|
||||
*
|
||||
* If the maximum size is set to 50 MB and 40 MB are already
|
||||
* used by offline regions, the cache size will be effectively
|
||||
* 10 MB.
|
||||
*
|
||||
* Setting the size to 0 will disable the cache if there is no
|
||||
* offline region on the database.
|
||||
*
|
||||
* This method should always be called before using the database,
|
||||
* otherwise the default maximum size will be used.
|
||||
*/
|
||||
virtual void setMaximumAmbientCacheSize(uint64_t size, std::function<void(std::exception_ptr)> callback);
|
||||
|
||||
// Offline
|
||||
|
||||
/*
|
||||
* Retrieve all regions in the offline database.
|
||||
*
|
||||
* The query will be executed asynchronously and the results passed to the given
|
||||
* callback, which will be executed on the database thread; it is the responsibility
|
||||
* of the SDK bindings to re-execute a user-provided callback on the main thread.
|
||||
*/
|
||||
virtual void listOfflineRegions(std::function<void(expected<OfflineRegions, std::exception_ptr>)>);
|
||||
|
||||
/*
|
||||
* Create an offline region in the database.
|
||||
*
|
||||
* When the initial database queries have completed, the provided callback will be
|
||||
* executed on the database thread; it is the responsibility of the SDK bindings
|
||||
* to re-execute a user-provided callback on the main thread.
|
||||
*
|
||||
* Note that the resulting region will be in an inactive download state; to begin
|
||||
* downloading resources, call `setOfflineRegionDownloadState(OfflineRegionDownloadState::Active)`,
|
||||
* optionally registering an `OfflineRegionObserver` beforehand.
|
||||
*/
|
||||
virtual void createOfflineRegion(const OfflineRegionDefinition& definition,
|
||||
const OfflineRegionMetadata& metadata,
|
||||
std::function<void(expected<OfflineRegion, std::exception_ptr>)>);
|
||||
/*
|
||||
* Update an offline region metadata in the database.
|
||||
*/
|
||||
virtual void updateOfflineMetadata(int64_t regionID,
|
||||
const OfflineRegionMetadata& metadata,
|
||||
std::function<void(expected<OfflineRegionMetadata, std::exception_ptr>)>);
|
||||
|
||||
/*
|
||||
* Register an observer to be notified when the state of the region changes.
|
||||
*/
|
||||
virtual void setOfflineRegionObserver(const OfflineRegion&, std::unique_ptr<OfflineRegionObserver>);
|
||||
|
||||
/*
|
||||
* Pause or resume downloading of regional resources.
|
||||
*/
|
||||
virtual void setOfflineRegionDownloadState(const OfflineRegion&, OfflineRegionDownloadState);
|
||||
|
||||
/*
|
||||
* Retrieve the current status of the region. The query will be executed
|
||||
* asynchronously and the results passed to the given callback, which will be
|
||||
* executed on the database thread; it is the responsibility of the SDK bindings
|
||||
* to re-execute a user-provided callback on the main thread.
|
||||
*/
|
||||
virtual void getOfflineRegionStatus(const OfflineRegion&,
|
||||
std::function<void(expected<OfflineRegionStatus, std::exception_ptr>)>) const;
|
||||
|
||||
/*
|
||||
* Merge offline regions from a secondary database into the main offline database.
|
||||
*
|
||||
* When the database merge is completed, the provided callback will be
|
||||
* executed on the database thread; it is the responsibility of the SDK bindings
|
||||
* to re-execute a user-provided callback on the main thread.
|
||||
*
|
||||
* The secondary database may need to be upgraded to the latest schema. This is done
|
||||
* in-place and requires write-access to `sideDatabasePath`; it is the
|
||||
* responsibility of the SDK bindings to ensure that this path is writeable.
|
||||
*
|
||||
* Only resources and tiles that belong to a region will be copied over. Identical
|
||||
* regions will be flattened into a single new region in the main database.
|
||||
*
|
||||
* Invokes the callback with a `MapboxOfflineTileCountExceededException` error if
|
||||
* the merge operation would result in the offline tile count limit being exceeded.
|
||||
*
|
||||
* Merged regions may not be in a completed status if the secondary database
|
||||
* does not contain all the tiles or resources required by the region definition.
|
||||
*/
|
||||
virtual void mergeOfflineRegions(const std::string& sideDatabasePath,
|
||||
std::function<void(expected<OfflineRegions, std::exception_ptr>)>);
|
||||
|
||||
/*
|
||||
* Remove an offline region from the database and perform any resources evictions
|
||||
* necessary as a result.
|
||||
*
|
||||
* Eviction works by removing the least-recently requested resources not also required
|
||||
* by other regions, until the database shrinks below a certain size.
|
||||
*
|
||||
* Note that this method takes ownership of the input, reflecting the fact that once
|
||||
* region deletion is initiated, it is not legal to perform further actions with the
|
||||
* region.
|
||||
*
|
||||
* Note that this operation can be potentially slow if packing the database occurs
|
||||
* automatically (see runPackDatabaseAutomatically() and packDatabase()).
|
||||
*
|
||||
* When the operation is complete or encounters an error, the given callback will be
|
||||
* executed on the database thread; it is the responsibility of the SDK bindings
|
||||
* to re-execute a user-provided callback on the main thread.
|
||||
*/
|
||||
virtual void deleteOfflineRegion(const OfflineRegion&, std::function<void(std::exception_ptr)>);
|
||||
|
||||
/*
|
||||
* Invalidate all the tiles from an offline region forcing Mapbox GL to revalidate
|
||||
* the tiles with the server before using. This is more efficient than deleting the
|
||||
* offline region and downloading it again because if the data on the cache matches
|
||||
* the server, no new data gets transmitted.
|
||||
*/
|
||||
virtual void invalidateOfflineRegion(const OfflineRegion&, std::function<void(std::exception_ptr)>);
|
||||
|
||||
/*
|
||||
* Changing or bypassing this limit without permission from Mapbox is prohibited
|
||||
* by the Mapbox Terms of Service.
|
||||
*/
|
||||
virtual void setOfflineMapboxTileCountLimit(uint64_t) const;
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
const std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
113
include/mbgl/storage/file_source.hpp
Normal file
113
include/mbgl/storage/file_source.hpp
Normal file
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/resource_transform.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
|
||||
#include <mapbox/compatibility/value.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class AsyncRequest;
|
||||
class Resource;
|
||||
|
||||
// TODO: Rename to ResourceProviderType
|
||||
enum FileSourceType : uint8_t {
|
||||
Asset,
|
||||
// TODO: split to separate types
|
||||
// - Cache for fast KV store (FASTER, LevelDB, RocksDB)
|
||||
// - Database for read-only offline use-cases
|
||||
Database,
|
||||
FileSystem,
|
||||
Network,
|
||||
// Resource loader acts as a proxy and has logic
|
||||
// for request delegation to Asset, Cache, and other
|
||||
// file sources.
|
||||
ResourceLoader
|
||||
};
|
||||
|
||||
// TODO: Rename to ResourceProvider to avoid confusion with
|
||||
// GeoJSONSource, RasterSource, VectorSource, CustomGeometrySource and other *Sources.
|
||||
class FileSource {
|
||||
public:
|
||||
FileSource(const FileSource&) = delete;
|
||||
FileSource& operator=(const FileSource&) = delete;
|
||||
virtual ~FileSource() = default;
|
||||
|
||||
using Callback = std::function<void (Response)>;
|
||||
|
||||
// Request a resource. The callback will be called asynchronously, in the same
|
||||
// thread as the request was made. This thread must have an active RunLoop. The
|
||||
// request may be cancelled before completion by releasing the returned AsyncRequest.
|
||||
// If the request is cancelled before the callback is executed, the callback will
|
||||
// not be executed.
|
||||
virtual std::unique_ptr<AsyncRequest> request(const Resource&, Callback) = 0;
|
||||
|
||||
// Allows to forward response from one source to another.
|
||||
// Optionally, callback can be provided to receive notification for forward
|
||||
// operation.
|
||||
//
|
||||
// NOLINTNEXTLINE(performance-unnecessary-value-param)
|
||||
virtual void forward(const Resource&, const Response&, std::function<void()>) {}
|
||||
|
||||
// When a file source supports consulting a local cache only, it must return true.
|
||||
// Cache-only requests are requests that aren't as urgent, but could be useful, e.g.
|
||||
// to cover part of the map while loading. The FileSource should only do cheap actions to
|
||||
// retrieve the data, e.g. load it from a cache, but not from the internet.
|
||||
virtual bool supportsCacheOnlyRequests() const { return false; }
|
||||
|
||||
// Checks whether a resource could be requested from this file source.
|
||||
virtual bool canRequest(const Resource&) const = 0;
|
||||
|
||||
/*
|
||||
* Pause file request activity.
|
||||
*
|
||||
* If pause is called then no revalidation or network request activity
|
||||
* will occur.
|
||||
*/
|
||||
virtual void pause() {}
|
||||
|
||||
/*
|
||||
* Resume file request activity.
|
||||
*
|
||||
* Calling resume will unpause the file source and process any tasks that
|
||||
* expired while the file source was paused.
|
||||
*/
|
||||
virtual void resume() {}
|
||||
|
||||
/*
|
||||
* Generic property setter / getter methods.
|
||||
*/
|
||||
virtual void setProperty(const std::string&, const mapbox::base::Value&){};
|
||||
virtual mapbox::base::Value getProperty(const std::string&) const { return {}; };
|
||||
|
||||
// When supported, sets the modifier of the requested resources.
|
||||
virtual void setResourceTransform(ResourceTransform) {} // NOLINT(performance-unnecessary-value-param)
|
||||
|
||||
protected:
|
||||
FileSource() = default;
|
||||
};
|
||||
|
||||
// Properties that may be supported by online file sources:
|
||||
|
||||
// Property name to set / get an access token.
|
||||
// type: std::string
|
||||
constexpr const char* ACCESS_TOKEN_KEY = "access-token";
|
||||
|
||||
// Property name to set / get base url.
|
||||
// type: std::string
|
||||
constexpr const char* API_BASE_URL_KEY = "api-base-url";
|
||||
|
||||
// Property name to set / get maximum number of concurrent requests.
|
||||
// type: unsigned
|
||||
constexpr const char* MAX_CONCURRENT_REQUESTS_KEY = "max-concurrent-requests";
|
||||
|
||||
// Properties that may be supported by database file sources:
|
||||
|
||||
// Property to set database mode. When set, database opens in read-only mode; database opens in read-write-create mode
|
||||
// otherwise. type: bool
|
||||
constexpr const char* READ_ONLY_MODE_KEY = "read-only-mode";
|
||||
|
||||
} // namespace mbgl
|
||||
51
include/mbgl/storage/file_source_manager.hpp
Normal file
51
include/mbgl/storage/file_source_manager.hpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/util/pass_types.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class ResourceOptions;
|
||||
|
||||
/**
|
||||
* @brief A singleton class responsible for managing file sources.
|
||||
*
|
||||
* The FileSourceManager provides following functionality:
|
||||
*
|
||||
* - provides access to file sources of a specific type and configuration
|
||||
* - caches previously created file sources of a (type, configuration) tuples
|
||||
* - allows to register and unregister file source factories
|
||||
*/
|
||||
class FileSourceManager {
|
||||
public:
|
||||
using FileSourceFactory = std::function<std::unique_ptr<FileSource>(const ResourceOptions&)>;
|
||||
|
||||
/**
|
||||
* @brief A singleton getter.
|
||||
*
|
||||
* @return FileSourceManager*
|
||||
*/
|
||||
static FileSourceManager* get() noexcept;
|
||||
|
||||
// Returns shared instance of a file source for (type, options) tuple.
|
||||
// Creates new instance via registered factory if needed. If new instance cannot be
|
||||
// created, nullptr would be returned.
|
||||
PassRefPtr<FileSource> getFileSource(FileSourceType, const ResourceOptions&) noexcept;
|
||||
|
||||
// Registers file source factory for a provided FileSourceType type. If factory for the
|
||||
// same type was already registered, will unregister previously registered factory.
|
||||
// Provided factory must not be null.
|
||||
virtual void registerFileSourceFactory(FileSourceType, FileSourceFactory&&) noexcept;
|
||||
|
||||
// Unregisters file source factory. If there are no registered factories for a FileSourceType
|
||||
// invocation has no effect.
|
||||
virtual FileSourceFactory unRegisterFileSourceFactory(FileSourceType) noexcept;
|
||||
|
||||
protected:
|
||||
FileSourceManager();
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
virtual ~FileSourceManager();
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
34
include/mbgl/storage/network_status.hpp
Normal file
34
include/mbgl/storage/network_status.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace util {
|
||||
class AsyncTask;
|
||||
} // namespace util
|
||||
|
||||
class NetworkStatus {
|
||||
public:
|
||||
enum class Status : uint8_t {
|
||||
Online,
|
||||
Offline,
|
||||
};
|
||||
|
||||
static Status Get();
|
||||
static void Set(Status);
|
||||
|
||||
static void Reachable();
|
||||
|
||||
static void Subscribe(util::AsyncTask* async);
|
||||
static void Unsubscribe(util::AsyncTask* async);
|
||||
|
||||
private:
|
||||
static std::atomic<bool> online;
|
||||
static std::mutex mtx;
|
||||
static std::unordered_set<util::AsyncTask*> observers;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
235
include/mbgl/storage/offline.hpp
Normal file
235
include/mbgl/storage/offline.hpp
Normal file
@@ -0,0 +1,235 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/geometry.hpp>
|
||||
#include <mbgl/util/range.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/storage/response.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TileID;
|
||||
|
||||
/*
|
||||
* An offline region defined by a style URL, geographic bounding box, zoom range, and
|
||||
* device pixel ratio.
|
||||
*
|
||||
* Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom.
|
||||
*
|
||||
* maxZoom may be ∞, in which case for each tile source, the region will include
|
||||
* tiles from minZoom up to the maximum zoom level provided by that source.
|
||||
*
|
||||
* pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
|
||||
*/
|
||||
class OfflineTilePyramidRegionDefinition {
|
||||
public:
|
||||
OfflineTilePyramidRegionDefinition(std::string, LatLngBounds, double, double, float, bool);
|
||||
|
||||
/* Private */
|
||||
std::string styleURL;
|
||||
LatLngBounds bounds;
|
||||
double minZoom;
|
||||
double maxZoom;
|
||||
float pixelRatio;
|
||||
bool includeIdeographs;
|
||||
};
|
||||
|
||||
/*
|
||||
* An offline region defined by a style URL, geometry, zoom range, and
|
||||
* device pixel ratio.
|
||||
*
|
||||
* Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom.
|
||||
*
|
||||
* maxZoom may be ∞, in which case for each tile source, the region will include
|
||||
* tiles from minZoom up to the maximum zoom level provided by that source.
|
||||
*
|
||||
* pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
|
||||
*/
|
||||
class OfflineGeometryRegionDefinition {
|
||||
public:
|
||||
OfflineGeometryRegionDefinition(std::string styleURL, Geometry<double>, double minZoom, double maxZoom, float pixelRatio, bool includeIdeographs);
|
||||
|
||||
/* Private */
|
||||
std::string styleURL;
|
||||
Geometry<double> geometry;
|
||||
double minZoom;
|
||||
double maxZoom;
|
||||
float pixelRatio;
|
||||
bool includeIdeographs;
|
||||
};
|
||||
|
||||
/*
|
||||
* The offline region definition types supported
|
||||
*/
|
||||
using OfflineRegionDefinition = variant<OfflineTilePyramidRegionDefinition, OfflineGeometryRegionDefinition>;
|
||||
|
||||
/*
|
||||
* The encoded format is private.
|
||||
*/
|
||||
std::string encodeOfflineRegionDefinition(const OfflineRegionDefinition&);
|
||||
OfflineRegionDefinition decodeOfflineRegionDefinition(const std::string&);
|
||||
|
||||
/*
|
||||
* Arbitrary binary region metadata. The contents are opaque to the mbgl implementation;
|
||||
* it just stores and retrieves a BLOB. SDK bindings should leave the interpretation of
|
||||
* this data up to the application; they _should not_ enforce a higher-level data format.
|
||||
* In the future we want offline database to be portable across target platforms, and a
|
||||
* platform-specific metadata format would prevent that.
|
||||
*/
|
||||
using OfflineRegionMetadata = std::vector<uint8_t>;
|
||||
|
||||
/*
|
||||
* A region is either inactive (not downloading, but previously-downloaded
|
||||
* resources are available for use), or active (resources are being downloaded
|
||||
* or will be downloaded, if necessary, when network access is available).
|
||||
*
|
||||
* This state is independent of whether or not the complete set of resources
|
||||
* is currently available for offline use. To check if that is the case, use
|
||||
* `OfflineRegionStatus::complete()`.
|
||||
*/
|
||||
enum class OfflineRegionDownloadState {
|
||||
Inactive,
|
||||
Active
|
||||
};
|
||||
|
||||
/*
|
||||
* A region's status includes its active/inactive state as well as counts
|
||||
* of the number of resources that have completed downloading, their total
|
||||
* size in bytes, and the total number of resources that are required.
|
||||
*
|
||||
* Note that the total required size in bytes is not currently available. A
|
||||
* future API release may provide an estimate of this number.
|
||||
*/
|
||||
class OfflineRegionStatus {
|
||||
public:
|
||||
OfflineRegionDownloadState downloadState = OfflineRegionDownloadState::Inactive;
|
||||
|
||||
/**
|
||||
* The number of resources that have been fully downloaded and are ready for
|
||||
* offline access.
|
||||
*/
|
||||
uint64_t completedResourceCount = 0;
|
||||
|
||||
/**
|
||||
* The cumulative size, in bytes, of all resources (inclusive of tiles) that have
|
||||
* been fully downloaded.
|
||||
*/
|
||||
uint64_t completedResourceSize = 0;
|
||||
|
||||
/**
|
||||
* The number of tiles that are known to be required for this region. This is a
|
||||
* subset of `completedResourceCount`.
|
||||
*/
|
||||
uint64_t completedTileCount = 0;
|
||||
|
||||
/**
|
||||
* The number of tiles that are known to be required for this region.
|
||||
*/
|
||||
uint64_t requiredTileCount = 0;
|
||||
|
||||
/**
|
||||
* The cumulative size, in bytes, of all tiles that have been fully downloaded.
|
||||
* This is a subset of `completedResourceSize`.
|
||||
*/
|
||||
uint64_t completedTileSize = 0;
|
||||
|
||||
/**
|
||||
* The number of resources that are known to be required for this region. See the
|
||||
* documentation for `requiredResourceCountIsPrecise` for an important caveat
|
||||
* about this number.
|
||||
*/
|
||||
uint64_t requiredResourceCount = 0;
|
||||
|
||||
/**
|
||||
* This property is true when the value of requiredResourceCount is a precise
|
||||
* count of the number of required resources, and false when it is merely a lower
|
||||
* bound.
|
||||
*
|
||||
* Specifically, it is false during early phases of an offline download. Once
|
||||
* style and tile sources have been downloaded, it is possible to calculate the
|
||||
* precise number of required resources, at which point it is set to true.
|
||||
*/
|
||||
bool requiredResourceCountIsPrecise = false;
|
||||
|
||||
bool complete() const {
|
||||
return completedResourceCount >= requiredResourceCount;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* A region can have a single observer, which gets notified whenever a change
|
||||
* to the region's status occurs.
|
||||
*/
|
||||
class OfflineRegionObserver {
|
||||
public:
|
||||
virtual ~OfflineRegionObserver() = default;
|
||||
|
||||
/*
|
||||
* Implement this method to be notified of a change in the status of an
|
||||
* offline region. Status changes include any change in state of the members
|
||||
* of OfflineRegionStatus.
|
||||
*
|
||||
* Note that this method will be executed on the database thread; it is the
|
||||
* responsibility of the SDK bindings to wrap this object in an interface that
|
||||
* re-executes the user-provided implementation on the main thread.
|
||||
*/
|
||||
virtual void statusChanged(OfflineRegionStatus) {}
|
||||
|
||||
/*
|
||||
* Implement this method to be notified of errors encountered while downloading
|
||||
* regional resources. Such errors may be recoverable; for example the implementation
|
||||
* will attempt to re-request failed resources based on an exponential backoff
|
||||
* algorithm, or when it detects that network access has been restored.
|
||||
*
|
||||
* Note that this method will be executed on the database thread; it is the
|
||||
* responsibility of the SDK bindings to wrap this object in an interface that
|
||||
* re-executes the user-provided implementation on the main thread.
|
||||
*/
|
||||
virtual void responseError(Response::Error) {} // NOLINT(performance-unnecessary-value-param)
|
||||
|
||||
/*
|
||||
* Implement this method to be notified when the limit on the number of Mapbox
|
||||
* tiles stored for offline regions has been reached.
|
||||
*
|
||||
* Once the limit has been reached, the SDK will not download further offline
|
||||
* tiles from Mapbox APIs until existing tiles have been removed.
|
||||
*
|
||||
* This limit does not apply to non-Mapbox tile sources.
|
||||
*
|
||||
* Note that this method will be executed on the database thread; it is the
|
||||
* responsibility of the SDK bindings to wrap this object in an interface that
|
||||
* re-executes the user-provided implementation on the main thread.
|
||||
*/
|
||||
virtual void mapboxTileCountLimitExceeded(uint64_t /* limit */) {}
|
||||
};
|
||||
|
||||
class OfflineRegion {
|
||||
public:
|
||||
~OfflineRegion();
|
||||
OfflineRegion() = delete;
|
||||
|
||||
int64_t getID() const;
|
||||
const OfflineRegionDefinition& getDefinition() const;
|
||||
const OfflineRegionMetadata& getMetadata() const;
|
||||
|
||||
private:
|
||||
friend class OfflineDatabase;
|
||||
|
||||
OfflineRegion(int64_t id,
|
||||
OfflineRegionDefinition,
|
||||
OfflineRegionMetadata);
|
||||
|
||||
int64_t id;
|
||||
OfflineRegionDefinition definition;
|
||||
OfflineRegionMetadata metadata;
|
||||
};
|
||||
|
||||
using OfflineRegions = std::vector<OfflineRegion>;
|
||||
|
||||
} // namespace mbgl
|
||||
27
include/mbgl/storage/online_file_source.hpp
Normal file
27
include/mbgl/storage/online_file_source.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/file_source.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class OnlineFileSource : public FileSource {
|
||||
public:
|
||||
OnlineFileSource();
|
||||
~OnlineFileSource() override;
|
||||
|
||||
private:
|
||||
// FileSource overrides
|
||||
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
|
||||
bool canRequest(const Resource&) const override;
|
||||
void pause() override;
|
||||
void resume() override;
|
||||
void setProperty(const std::string&, const mapbox::base::Value&) override;
|
||||
mapbox::base::Value getProperty(const std::string&) const override;
|
||||
void setResourceTransform(ResourceTransform) override;
|
||||
|
||||
class Impl;
|
||||
const std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
108
include/mbgl/storage/resource.hpp
Normal file
108
include/mbgl/storage/resource.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/response.hpp>
|
||||
#include <mbgl/util/bitmask_operations.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/font_stack.hpp>
|
||||
#include <mbgl/util/tileset.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Resource {
|
||||
public:
|
||||
enum Kind : uint8_t {
|
||||
Unknown = 0,
|
||||
Style,
|
||||
Source,
|
||||
Tile,
|
||||
Glyphs,
|
||||
SpriteImage,
|
||||
SpriteJSON,
|
||||
Image
|
||||
};
|
||||
|
||||
enum class Priority : bool {
|
||||
Regular,
|
||||
Low
|
||||
};
|
||||
|
||||
enum class Usage : bool {
|
||||
Online,
|
||||
Offline
|
||||
};
|
||||
|
||||
enum class StoragePolicy : bool { Permanent, Volatile };
|
||||
|
||||
struct TileData {
|
||||
std::string urlTemplate;
|
||||
uint8_t pixelRatio;
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
int8_t z;
|
||||
};
|
||||
|
||||
enum class LoadingMethod : uint8_t {
|
||||
None = 0b00,
|
||||
Cache = 0b01,
|
||||
Network = 0b10,
|
||||
|
||||
CacheOnly = Cache,
|
||||
NetworkOnly = Network,
|
||||
All = Cache | Network,
|
||||
};
|
||||
|
||||
Resource(Kind kind_,
|
||||
std::string url_,
|
||||
optional<TileData> tileData_ = {},
|
||||
LoadingMethod loadingMethod_ = LoadingMethod::All)
|
||||
: kind(kind_),
|
||||
loadingMethod(loadingMethod_),
|
||||
url(std::move(url_)),
|
||||
tileData(std::move(tileData_)) {
|
||||
}
|
||||
|
||||
void setPriority(Priority p) { priority = p; }
|
||||
void setUsage(Usage u) { usage = u; }
|
||||
|
||||
bool hasLoadingMethod(LoadingMethod method) const;
|
||||
|
||||
static Resource style(const std::string& url);
|
||||
static Resource source(const std::string& url);
|
||||
static Resource tile(const std::string& urlTemplate,
|
||||
float pixelRatio,
|
||||
int32_t x,
|
||||
int32_t y,
|
||||
int8_t z,
|
||||
Tileset::Scheme scheme,
|
||||
LoadingMethod = LoadingMethod::All);
|
||||
static Resource glyphs(const std::string& urlTemplate,
|
||||
const FontStack& fontStack,
|
||||
const std::pair<uint16_t, uint16_t>& glyphRange);
|
||||
static Resource spriteImage(const std::string& base, float pixelRatio);
|
||||
static Resource spriteJSON(const std::string& base, float pixelRatio);
|
||||
static Resource image(const std::string& url);
|
||||
|
||||
Kind kind;
|
||||
LoadingMethod loadingMethod;
|
||||
Usage usage{ Usage::Online };
|
||||
Priority priority{ Priority::Regular };
|
||||
std::string url;
|
||||
|
||||
// Includes auxiliary data if this is a tile request.
|
||||
optional<TileData> tileData;
|
||||
|
||||
optional<Timestamp> priorModified = {};
|
||||
optional<Timestamp> priorExpires = {};
|
||||
optional<std::string> priorEtag = {};
|
||||
std::shared_ptr<const std::string> priorData;
|
||||
Duration minimumUpdateInterval{Duration::zero()};
|
||||
StoragePolicy storagePolicy{StoragePolicy::Permanent};
|
||||
};
|
||||
|
||||
inline bool Resource::hasLoadingMethod(Resource::LoadingMethod method) const {
|
||||
return (loadingMethod & method);
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
122
include/mbgl/storage/resource_options.hpp
Normal file
122
include/mbgl/storage/resource_options.hpp
Normal file
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/**
|
||||
* @brief Holds values for resource options.
|
||||
*/
|
||||
class ResourceOptions final {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a ResourceOptions object with default values.
|
||||
*/
|
||||
ResourceOptions();
|
||||
~ResourceOptions();
|
||||
|
||||
ResourceOptions(ResourceOptions&&) noexcept;
|
||||
|
||||
ResourceOptions clone() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the Mapbox access token - see https://docs.mapbox.com/help/how-mapbox-works/access-tokens/ for details.
|
||||
*
|
||||
* @param token Mapbox access token.
|
||||
* @return ResourceOptions for chaining options together.
|
||||
*/
|
||||
ResourceOptions& withAccessToken(std::string token);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) Mapbox access token.
|
||||
*
|
||||
* @return const std::string& Mapbox access token.
|
||||
*/
|
||||
const std::string& accessToken() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the API base URL. Default is https://api.mapbox.com for Mapbox.
|
||||
*
|
||||
* @param baseURL API base URL.
|
||||
* @return ResourceOptions for chaining options together.
|
||||
*/
|
||||
ResourceOptions& withBaseURL(std::string baseURL);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) API base URL.
|
||||
*
|
||||
* @return const std::string& API base URL.
|
||||
*/
|
||||
const std::string& baseURL() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the cache path.
|
||||
*
|
||||
* @param path Cache path.
|
||||
* @return ResourceOptions for chaining options together.
|
||||
*/
|
||||
ResourceOptions& withCachePath(std::string path);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) cache path.
|
||||
*
|
||||
* @return cache path
|
||||
*/
|
||||
const std::string& cachePath() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the asset path, which is the root directory from where
|
||||
* the asset:// scheme gets resolved in a style.
|
||||
*
|
||||
* @param path Asset path.
|
||||
* @return ResourceOptions for chaining options together.
|
||||
*/
|
||||
ResourceOptions& withAssetPath(std::string path);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) asset path.
|
||||
*
|
||||
* @return asset path
|
||||
*/
|
||||
const std::string& assetPath() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the maximum cache size.
|
||||
*
|
||||
* @param size Cache maximum size in bytes.
|
||||
* @return reference to ResourceOptions for chaining options together.
|
||||
*/
|
||||
ResourceOptions& withMaximumCacheSize(uint64_t size);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) maximum allowed cache size.
|
||||
*
|
||||
* @return maximum allowed cache database size in bytes.
|
||||
*/
|
||||
uint64_t maximumCacheSize() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the platform context. A platform context is usually an object
|
||||
* that assists the creation of a file source.
|
||||
*
|
||||
* @param context Platform context.
|
||||
* @return reference to ResourceOptions for chaining options together.
|
||||
*/
|
||||
ResourceOptions& withPlatformContext(void* context);
|
||||
|
||||
/**
|
||||
* @brief Gets the previously set (or default) platform context.
|
||||
*
|
||||
* @return Platform context.
|
||||
*/
|
||||
void* platformContext() const;
|
||||
|
||||
private:
|
||||
ResourceOptions(const ResourceOptions&);
|
||||
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
23
include/mbgl/storage/resource_transform.hpp
Normal file
23
include/mbgl/storage/resource_transform.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/storage/resource.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class ResourceTransform {
|
||||
public:
|
||||
using FinishedCallback = std::function<void(const std::string&)>;
|
||||
using TransformCallback = std::function<void(Resource::Kind kind, const std::string& url, FinishedCallback)>;
|
||||
|
||||
ResourceTransform(TransformCallback = {});
|
||||
void transform(Resource::Kind, const std::string& url, FinishedCallback);
|
||||
explicit operator bool() const { return bool(transformCallback); }
|
||||
|
||||
private:
|
||||
TransformCallback transformCallback;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
72
include/mbgl/storage/response.hpp
Normal file
72
include/mbgl/storage/response.hpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Response {
|
||||
public:
|
||||
Response() = default;
|
||||
Response(const Response&);
|
||||
Response& operator=(const Response&);
|
||||
|
||||
public:
|
||||
class Error;
|
||||
// When this object is empty, the response was successful.
|
||||
std::unique_ptr<const Error> error;
|
||||
|
||||
// This is set to true for 204 Not Modified responses, and, for backward compatibility,
|
||||
// for 404 Not Found responses for tiles.
|
||||
bool noContent = false;
|
||||
|
||||
// This is set to true for 304 Not Modified responses.
|
||||
bool notModified = false;
|
||||
|
||||
// This is set to true when the server requested that no expired resources be used by
|
||||
// specifying "Cache-Control: must-revalidate".
|
||||
bool mustRevalidate = false;
|
||||
|
||||
// The actual data of the response. Present only for non-error, non-notModified responses.
|
||||
std::shared_ptr<const std::string> data;
|
||||
|
||||
optional<Timestamp> modified;
|
||||
optional<Timestamp> expires;
|
||||
optional<std::string> etag;
|
||||
|
||||
bool isFresh() const {
|
||||
return expires ? *expires > util::now() : !error;
|
||||
}
|
||||
|
||||
// Indicates whether we are allowed to use this response according to HTTP caching rules.
|
||||
// It may or may not be stale.
|
||||
bool isUsable() const {
|
||||
return !mustRevalidate || (expires && *expires > util::now());
|
||||
}
|
||||
};
|
||||
|
||||
class Response::Error {
|
||||
public:
|
||||
enum class Reason : uint8_t {
|
||||
Success = 1,
|
||||
NotFound = 2,
|
||||
Server = 3,
|
||||
Connection = 4,
|
||||
RateLimit = 5,
|
||||
Other = 6,
|
||||
} reason = Reason::Other;
|
||||
|
||||
// An error message from the request handler, e.g. a server message or a system message
|
||||
// informing the user about the reason for the failure.
|
||||
std::string message;
|
||||
|
||||
optional<Timestamp> retryAfter;
|
||||
|
||||
public:
|
||||
Error(Reason, std::string = "", optional<Timestamp> = {});
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
49
include/mbgl/style/color_ramp_property_value.hpp
Normal file
49
include/mbgl/style/color_ramp_property_value.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/variant.hpp>
|
||||
#include <mbgl/style/undefined.hpp>
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
/*
|
||||
* Special-case implementation of (a subset of) the PropertyValue<T> interface
|
||||
* used for building the HeatmapColor paint property traits class.
|
||||
*/
|
||||
class ColorRampPropertyValue {
|
||||
private:
|
||||
std::shared_ptr<expression::Expression> value;
|
||||
|
||||
friend bool operator==(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) {
|
||||
return (lhs.isUndefined() && rhs.isUndefined()) || (lhs.value && rhs.value && *(lhs.value) == *(rhs.value));
|
||||
}
|
||||
|
||||
friend bool operator!=(const ColorRampPropertyValue& lhs, const ColorRampPropertyValue& rhs) {
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
public:
|
||||
ColorRampPropertyValue() : value(nullptr) {}
|
||||
ColorRampPropertyValue(std::shared_ptr<expression::Expression> value_) : value(std::move(value_)) {}
|
||||
|
||||
bool isUndefined() const { return value == nullptr; }
|
||||
|
||||
// noop, needed for batch evaluation of paint property values to compile
|
||||
template <typename Evaluator>
|
||||
Color evaluate(const Evaluator&, TimePoint = {}) const { return {}; }
|
||||
|
||||
Color evaluate(double rampEvaluationParameter) const {
|
||||
const auto result = value->evaluate(expression::EvaluationContext({}, nullptr, {rampEvaluationParameter}));
|
||||
return *expression::fromExpressionValue<Color>(*result);
|
||||
}
|
||||
|
||||
bool isDataDriven() const { return false; }
|
||||
bool hasDataDrivenPropertyDifference(const ColorRampPropertyValue&) const { return false; }
|
||||
|
||||
const expression::Expression& getExpression() const { return *value; }
|
||||
};
|
||||
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
29
include/mbgl/style/conversion.hpp
Normal file
29
include/mbgl/style/conversion.hpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
// This is a forward-declaration only header intended to minimize dependencies and to improve
|
||||
// compilation speed. In order to specialize implementations and get access to the actual
|
||||
// implementation, include <mbgl/style/conversion_impl.hpp>.
|
||||
|
||||
struct Error { std::string message; };
|
||||
|
||||
template <typename T>
|
||||
class ConversionTraits;
|
||||
|
||||
class Convertible;
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct Converter;
|
||||
|
||||
template <typename T, typename Enable = void>
|
||||
struct ValueFactory;
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
|
||||
17
include/mbgl/style/conversion/color_ramp_property_value.hpp
Normal file
17
include/mbgl/style/conversion/color_ramp_property_value.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/color_ramp_property_value.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<ColorRampPropertyValue> {
|
||||
optional<ColorRampPropertyValue> operator()(const Convertible& value, Error& error, bool /* allowDataExpressions */ = false, bool /* convertTokens */ = false) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
69
include/mbgl/style/conversion/constant.hpp
Normal file
69
include/mbgl/style/conversion/constant.hpp
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<bool> {
|
||||
optional<bool> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<float> {
|
||||
optional<float> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<std::string> {
|
||||
optional<std::string> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct Converter<T, typename std::enable_if_t<std::is_enum<T>::value>> {
|
||||
optional<T> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct Converter<std::vector<T>, typename std::enable_if_t<std::is_enum<T>::value>> {
|
||||
optional<std::vector<T>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<Color> {
|
||||
optional<Color> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
struct Converter<std::array<float, N>> {
|
||||
optional<std::array<float, N>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<std::vector<float>> {
|
||||
optional<std::vector<float>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
struct Converter<std::array<double, N>> {
|
||||
optional<std::array<double, N>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<std::vector<std::string>> {
|
||||
optional<std::vector<std::string>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
19
include/mbgl/style/conversion/coordinate.hpp
Normal file
19
include/mbgl/style/conversion/coordinate.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template<>
|
||||
struct Converter<LatLng> {
|
||||
public:
|
||||
optional<LatLng> operator() (const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/sources/custom_geometry_source.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<CustomGeometrySource::Options> {
|
||||
optional<CustomGeometrySource::Options> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
19
include/mbgl/style/conversion/filter.hpp
Normal file
19
include/mbgl/style/conversion/filter.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/filter.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<Filter> {
|
||||
public:
|
||||
optional<Filter> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
25
include/mbgl/style/conversion/function.hpp
Normal file
25
include/mbgl/style/conversion/function.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/property_expression.hpp>
|
||||
#include <mbgl/style/conversion/constant.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
bool hasTokens(const std::string&);
|
||||
std::unique_ptr<expression::Expression> convertTokenStringToFormatExpression(const std::string&);
|
||||
std::unique_ptr<expression::Expression> convertTokenStringToImageExpression(const std::string&);
|
||||
std::unique_ptr<expression::Expression> convertTokenStringToExpression(const std::string&);
|
||||
|
||||
optional<std::unique_ptr<expression::Expression>> convertFunctionToExpression(expression::type::Type, const Convertible&, Error&, bool convertTokens);
|
||||
|
||||
template <class T>
|
||||
optional<PropertyExpression<T>> convertFunctionToExpression(const Convertible& value, Error& error, bool convertTokens);
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
22
include/mbgl/style/conversion/geojson.hpp
Normal file
22
include/mbgl/style/conversion/geojson.hpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/geojson.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
// Workaround until https://github.com/mapbox/mapbox-gl-native/issues/5623 is done.
|
||||
optional<GeoJSON> parseGeoJSON(const std::string&, Error&);
|
||||
|
||||
template <>
|
||||
struct Converter<GeoJSON> {
|
||||
public:
|
||||
optional<GeoJSON> operator()(const Convertible&, Error&) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
18
include/mbgl/style/conversion/geojson_options.hpp
Normal file
18
include/mbgl/style/conversion/geojson_options.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/sources/geojson_source.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<GeoJSONOptions> {
|
||||
optional<GeoJSONOptions> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
14
include/mbgl/style/conversion/get_json_type.hpp
Normal file
14
include/mbgl/style/conversion/get_json_type.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
std::string getJSONType(const Convertible& value);
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
23
include/mbgl/style/conversion/layer.hpp
Normal file
23
include/mbgl/style/conversion/layer.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/layer.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<std::unique_ptr<Layer>> {
|
||||
public:
|
||||
optional<std::unique_ptr<Layer>> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
optional<Error> setPaintProperties(Layer& layer, const Convertible& value);
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
19
include/mbgl/style/conversion/light.hpp
Normal file
19
include/mbgl/style/conversion/light.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/light.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<Light> {
|
||||
public:
|
||||
optional<Light> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
18
include/mbgl/style/conversion/position.hpp
Normal file
18
include/mbgl/style/conversion/position.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/position.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<Position> {
|
||||
optional<Position> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
56
include/mbgl/style/conversion/property_value.hpp
Normal file
56
include/mbgl/style/conversion/property_value.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/property_value.hpp>
|
||||
#include <mbgl/style/conversion/constant.hpp>
|
||||
#include <mbgl/style/conversion/function.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
#include <mbgl/style/expression/is_constant.hpp>
|
||||
#include <mbgl/style/expression/is_expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/expression/literal.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <class T>
|
||||
struct Converter<PropertyValue<T>> {
|
||||
optional<PropertyValue<T>> operator()(const Convertible& value, Error& error, bool allowDataExpressions, bool convertTokens) const;
|
||||
|
||||
template <class S>
|
||||
PropertyValue<T> maybeConvertTokens(const S& t) const {
|
||||
return PropertyValue<T>(t);
|
||||
};
|
||||
|
||||
PropertyValue<T> maybeConvertTokens(const std::string& t) const {
|
||||
return hasTokens(t)
|
||||
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToExpression(t)))
|
||||
: PropertyValue<T>(t);
|
||||
}
|
||||
|
||||
PropertyValue<T> maybeConvertTokens(const expression::Formatted& t) const {
|
||||
// This only works with a single-section `Formatted` created automatically
|
||||
// by parsing a plain-text `text-field` property.
|
||||
// Token conversion happens later than the initial string->Formatted conversion
|
||||
// General purpose `format` expressions with embedded tokens are not supported
|
||||
const std::string& firstUnformattedSection = t.sections[0].text;
|
||||
return hasTokens(firstUnformattedSection)
|
||||
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToFormatExpression(firstUnformattedSection)))
|
||||
: PropertyValue<T>(t);
|
||||
}
|
||||
|
||||
PropertyValue<T> maybeConvertTokens(const expression::Image& image) const {
|
||||
return hasTokens(image.id())
|
||||
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToImageExpression(image.id())))
|
||||
: PropertyValue<T>(image);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<PropertyValue<std::array<double, 3>>, void> {
|
||||
optional<PropertyValue<std::array<double, 3>>> operator()(const Convertible& value, Error& error, bool, bool) const;
|
||||
};
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
18
include/mbgl/style/conversion/rotation.hpp
Normal file
18
include/mbgl/style/conversion/rotation.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/rotation.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<style::Rotation> {
|
||||
optional<style::Rotation> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
21
include/mbgl/style/conversion/source.hpp
Normal file
21
include/mbgl/style/conversion/source.hpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/source.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<std::unique_ptr<Source>> {
|
||||
public:
|
||||
optional<std::unique_ptr<Source>> operator()(const Convertible& value, Error& error, const std::string& id) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
19
include/mbgl/style/conversion/tileset.hpp
Normal file
19
include/mbgl/style/conversion/tileset.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/util/tileset.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<Tileset> {
|
||||
public:
|
||||
optional<Tileset> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
19
include/mbgl/style/conversion/transition_options.hpp
Normal file
19
include/mbgl/style/conversion/transition_options.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/transition_options.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<TransitionOptions> {
|
||||
public:
|
||||
optional<TransitionOptions> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
384
include/mbgl/style/conversion_impl.hpp
Normal file
384
include/mbgl/style/conversion_impl.hpp
Normal file
@@ -0,0 +1,384 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/color_ramp_property_value.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
#include <mbgl/style/property_value.hpp>
|
||||
#include <mbgl/style/rotation.hpp>
|
||||
#include <mbgl/style/transition_options.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/geojson.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/traits.hpp>
|
||||
|
||||
#include <mapbox/compatibility/value.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
/*
|
||||
The `conversion` namespace defines conversions from JSON structures conforming to the schema defined by
|
||||
the Mapbox Style Specification, to the various C++ types that form the C++ model of that domain:
|
||||
|
||||
* `std::unique_ptr<Source>`
|
||||
* `std::unique_ptr<Layer>`
|
||||
* `Filter`
|
||||
* `PropertyValue<T>`
|
||||
|
||||
A single template function serves as the public interface:
|
||||
|
||||
template <class T>
|
||||
optional<T> convert(const Convertible& input, Error& error);
|
||||
|
||||
Where `T` is one of the above types. If the conversion fails, the result is empty, and the
|
||||
error parameter includes diagnostic text suitable for presentation to a library user. Otherwise,
|
||||
a filled optional is returned.
|
||||
|
||||
`Convertible` is a type that encapsulates a special form of polymorphism over various underlying types that
|
||||
can serve as input to the conversion algorithm. For instance, on macOS, we need to support
|
||||
conversion from both RapidJSON types, and a JSON structure represented with `NSArray`/`NSDictionary`/etc.
|
||||
On Qt, we need to support conversion from RapidJSON types and QVariant.
|
||||
|
||||
We don't want to use traditional forms of polymorphism to accomplish this:
|
||||
|
||||
* Compile time polymorphism using a template parameter for the actual value type leads to
|
||||
excessive code bloat and long compile times.
|
||||
* Runtime polymorphism using virtual methods requires extra heap allocation and ubiquitous
|
||||
use of std::unique_ptr, unsuitable for this performance-sensitive code.
|
||||
|
||||
Therefore, we're using a custom implementation of runtime polymorphism where we manually create and
|
||||
dispatch through a table of function pointers (vtable), while keeping the storage for any of the possible
|
||||
underlying types inline on the stack, using `std::aligned_storage`.
|
||||
|
||||
For a given underlying type T, an explicit specialization of `ConversionTraits<T>` must be provided. This
|
||||
specialization must provide the following static methods:
|
||||
|
||||
* `isUndefined(v)` -- returns a boolean indication whether `v` is undefined or a JSON null
|
||||
|
||||
* `isArray(v)` -- returns a boolean indicating whether `v` represents a JSON array
|
||||
* `arrayLength(v)` -- called only if `isArray(v)`; returns a size_t length
|
||||
* `arrayMember(v)` -- called only if `isArray(v)`; returns `V` or `V&`
|
||||
|
||||
* `isObject(v)` -- returns a boolean indicating whether `v` represents a JSON object
|
||||
* `objectMember(v, name)` -- called only if `isObject(v)`; `name` is `const char *`; return value:
|
||||
* is true when evaluated in a boolean context iff the named member exists
|
||||
* is convertable to a `V` or `V&` when dereferenced
|
||||
* `eachMember(v, [] (const std::string&, const V&) -> optional<Error> {...})` -- called
|
||||
only if `isObject(v)`; calls the provided lambda once for each key and value of the object;
|
||||
short-circuits if any call returns an `Error`
|
||||
|
||||
* `toBool(v)` -- returns `optional<bool>`, absence indicating `v` is not a JSON boolean
|
||||
* `toNumber(v)` -- returns `optional<float>`, absence indicating `v` is not a JSON number
|
||||
* `toDouble(v)` -- returns `optional<double>`, absence indicating `v` is not a JSON number
|
||||
* `toString(v)` -- returns `optional<std::string>`, absence indicating `v` is not a JSON string
|
||||
* `toValue(v)` -- returns `optional<Value>`, a variant type, for generic conversion,
|
||||
absence indicating `v` is not a boolean, number, or string. Numbers should be converted to
|
||||
unsigned integer, signed integer, or floating point, in descending preference.
|
||||
|
||||
In addition, the type T must be move-constructable. And finally, `Convertible::Storage`, a typedef for
|
||||
`std::aligned_storage_t`, must be large enough to satisfy the memory requirements for any of the
|
||||
possible underlying types. (A static assert will fail if this is not the case.)
|
||||
|
||||
`Convertible` itself is movable, but not copyable. A moved-from `Convertible` is in an invalid state;
|
||||
you must not do anything with it except let it go out of scope.
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
class ConversionTraits;
|
||||
|
||||
class Convertible {
|
||||
public:
|
||||
template <typename T>
|
||||
// NOLINTNEXTLINE(bugprone-forwarding-reference-overload)
|
||||
Convertible(T&& value) : vtable(vtableForType<std::decay_t<T>>()) {
|
||||
static_assert(sizeof(Storage) >= sizeof(std::decay_t<T>), "Storage must be large enough to hold value type");
|
||||
new (static_cast<void*>(&storage)) std::decay_t<T>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
Convertible(Convertible&& v) noexcept : vtable(v.vtable) {
|
||||
// NOLINTNEXTLINE(performance-move-const-arg)
|
||||
vtable->move(std::move(v.storage), storage);
|
||||
}
|
||||
|
||||
~Convertible() {
|
||||
vtable->destroy(storage);
|
||||
}
|
||||
|
||||
Convertible& operator=(Convertible&& v) noexcept {
|
||||
if (this != &v) {
|
||||
vtable->destroy(storage);
|
||||
vtable = v.vtable;
|
||||
// NOLINTNEXTLINE(performance-move-const-arg)
|
||||
vtable->move(std::move(v.storage), storage);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Convertible() = delete;
|
||||
Convertible(const Convertible&) = delete;
|
||||
Convertible& operator=(const Convertible&) = delete;
|
||||
|
||||
friend inline bool isUndefined(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->isUndefined(v.storage);
|
||||
}
|
||||
|
||||
friend inline bool isArray(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->isArray(v.storage);
|
||||
}
|
||||
|
||||
friend inline std::size_t arrayLength(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->arrayLength(v.storage);
|
||||
}
|
||||
|
||||
friend inline Convertible arrayMember(const Convertible& v, std::size_t i) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->arrayMember(v.storage, i);
|
||||
}
|
||||
|
||||
friend inline bool isObject(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->isObject(v.storage);
|
||||
}
|
||||
|
||||
friend inline optional<Convertible> objectMember(const Convertible& v, const char * name) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->objectMember(v.storage, name);
|
||||
}
|
||||
|
||||
friend inline optional<Error> eachMember(const Convertible& v, const std::function<optional<Error> (const std::string&, const Convertible&)>& fn) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->eachMember(v.storage, fn);
|
||||
}
|
||||
|
||||
friend inline optional<bool> toBool(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->toBool(v.storage);
|
||||
}
|
||||
|
||||
friend inline optional<float> toNumber(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->toNumber(v.storage);
|
||||
}
|
||||
|
||||
friend inline optional<double> toDouble(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->toDouble(v.storage);
|
||||
}
|
||||
|
||||
friend inline optional<std::string> toString(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->toString(v.storage);
|
||||
}
|
||||
|
||||
friend inline optional<Value> toValue(const Convertible& v) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->toValue(v.storage);
|
||||
}
|
||||
|
||||
friend inline optional<GeoJSON> toGeoJSON(const Convertible& v, Error& error) {
|
||||
assert(v.vtable);
|
||||
return v.vtable->toGeoJSON(v.storage, error);
|
||||
}
|
||||
|
||||
private:
|
||||
#if __ANDROID__
|
||||
// Android: JSValue* or mbgl::android::Value
|
||||
using Storage = std::aligned_storage_t<32, 8>;
|
||||
#elif __QT__
|
||||
// Qt: JSValue* or QVariant
|
||||
using Storage = std::aligned_storage_t<32, 8>;
|
||||
#else
|
||||
// Node: JSValue* or v8::Local<v8::Value>
|
||||
// iOS/macOS: JSValue* or id
|
||||
using Storage = std::aligned_storage_t<8, 8>;
|
||||
#endif
|
||||
|
||||
struct VTable {
|
||||
void (*move) (Storage&& src, Storage& dest);
|
||||
void (*destroy) (Storage&);
|
||||
|
||||
bool (*isUndefined) (const Storage&);
|
||||
|
||||
bool (*isArray) (const Storage&);
|
||||
std::size_t (*arrayLength) (const Storage&);
|
||||
Convertible (*arrayMember) (const Storage&, std::size_t);
|
||||
|
||||
bool (*isObject) (const Storage&);
|
||||
optional<Convertible> (*objectMember) (const Storage&, const char *);
|
||||
optional<Error> (*eachMember) (const Storage&, const std::function<optional<Error> (const std::string&, const Convertible&)>&);
|
||||
|
||||
optional<bool> (*toBool) (const Storage&);
|
||||
optional<float> (*toNumber) (const Storage&);
|
||||
optional<double> (*toDouble) (const Storage&);
|
||||
optional<std::string> (*toString) (const Storage&);
|
||||
optional<Value> (*toValue) (const Storage&);
|
||||
|
||||
// https://github.com/mapbox/mapbox-gl-native/issues/5623
|
||||
optional<GeoJSON> (*toGeoJSON) (const Storage&, Error&);
|
||||
};
|
||||
|
||||
// Extracted this function from the table below to work around a GCC bug with differing
|
||||
// visibility settings for capturing lambdas: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80947
|
||||
template <typename T>
|
||||
static auto vtableEachMember(const Storage& s, const std::function<optional<Error>(const std::string&, const Convertible&)>& fn) {
|
||||
return ConversionTraits<T>::eachMember(reinterpret_cast<const T&>(s), [&](const std::string& k, T&& v) {
|
||||
return fn(k, Convertible(std::move(v)));
|
||||
});
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static VTable* vtableForType() {
|
||||
using Traits = ConversionTraits<T>;
|
||||
static VTable vtable = {
|
||||
[] (Storage&& src, Storage& dest) {
|
||||
new (static_cast<void*>(&dest)) T(reinterpret_cast<T&&>(src));
|
||||
},
|
||||
[] (Storage& s) {
|
||||
reinterpret_cast<T&>(s).~T();
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::isUndefined(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::isArray(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::arrayLength(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s, std::size_t i) {
|
||||
return Convertible(Traits::arrayMember(reinterpret_cast<const T&>(s), i));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::isObject(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s, const char * key) {
|
||||
optional<T> member = Traits::objectMember(reinterpret_cast<const T&>(s), key);
|
||||
if (member) {
|
||||
return optional<Convertible>(Convertible(std::move(*member)));
|
||||
} else {
|
||||
return optional<Convertible>();
|
||||
}
|
||||
},
|
||||
vtableEachMember<T>,
|
||||
[] (const Storage& s) {
|
||||
return Traits::toBool(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::toNumber(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::toDouble(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::toString(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s) {
|
||||
return Traits::toValue(reinterpret_cast<const T&>(s));
|
||||
},
|
||||
[] (const Storage& s, Error& err) {
|
||||
return Traits::toGeoJSON(reinterpret_cast<const T&>(s), err);
|
||||
}
|
||||
};
|
||||
return &vtable;
|
||||
}
|
||||
|
||||
VTable* vtable;
|
||||
Storage storage;
|
||||
};
|
||||
|
||||
template <class T, class...Args>
|
||||
optional<T> convert(const Convertible& value, Error& error, Args&&...args) {
|
||||
return Converter<T>()(value, error, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <>
|
||||
struct ValueFactory<ColorRampPropertyValue> {
|
||||
static Value make(const ColorRampPropertyValue& value) { return value.getExpression().serialize(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ValueFactory<TransitionOptions> {
|
||||
static Value make(const TransitionOptions& value) { return value.serialize(); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ValueFactory<Color> {
|
||||
static Value make(const Color& color) { return color.serialize(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ValueFactory<T, typename std::enable_if<(!std::is_enum<T>::value && !is_linear_container<T>::value)>::type> {
|
||||
static Value make(const T& arg) { return {arg}; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ValueFactory<T, typename std::enable_if<std::is_enum<T>::value>::type> {
|
||||
static Value make(T arg) { return {Enum<T>::toString(arg)}; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct ValueFactory<T, typename std::enable_if<is_linear_container<T>::value>::type> {
|
||||
static Value make(const T& arg) {
|
||||
mapbox::base::ValueArray result;
|
||||
result.reserve(arg.size());
|
||||
for (const auto& item : arg) {
|
||||
result.emplace_back(ValueFactory<std::decay_t<decltype(item)>>::make(item));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ValueFactory<Position> {
|
||||
static Value make(const Position& position) {
|
||||
return ValueFactory<std::array<float, 3>>::make(position.getSpherical());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ValueFactory<Rotation> {
|
||||
static Value make(const Rotation& rotation) { return {rotation.getAngle()}; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Value makeValue(T&& arg) {
|
||||
return ValueFactory<std::decay_t<T>>::make(std::forward<T>(arg));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StyleProperty makeStyleProperty(const PropertyValue<T>& value) {
|
||||
return value.match([](const Undefined&) -> StyleProperty { return {}; },
|
||||
[](const Color& c) -> StyleProperty {
|
||||
return {makeValue(c), StyleProperty::Kind::Expression};
|
||||
},
|
||||
[](const PropertyExpression<T>& fn) -> StyleProperty {
|
||||
return {fn.getExpression().serialize(), StyleProperty::Kind::Expression};
|
||||
},
|
||||
[](const auto& t) -> StyleProperty {
|
||||
return {makeValue(t), StyleProperty::Kind::Constant};
|
||||
});
|
||||
}
|
||||
|
||||
inline StyleProperty makeStyleProperty(const TransitionOptions& value) {
|
||||
if (!value.isDefined()) return {};
|
||||
return {makeValue(value), StyleProperty::Kind::Transition};
|
||||
}
|
||||
|
||||
inline StyleProperty makeStyleProperty(const ColorRampPropertyValue& value) {
|
||||
if (value.isUndefined()) return {};
|
||||
return {makeValue(value), StyleProperty::Kind::Expression};
|
||||
}
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
36
include/mbgl/style/expression/assertion.hpp
Normal file
36
include/mbgl/style/expression/assertion.hpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Assertion : public Expression {
|
||||
public:
|
||||
Assertion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_);
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
mbgl::Value serialize() const override;
|
||||
std::string getOperator() const override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Expression>> inputs;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
45
include/mbgl/style/expression/at.hpp
Normal file
45
include/mbgl/style/expression/at.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class At : public Expression {
|
||||
public:
|
||||
At(std::unique_ptr<Expression> index_, std::unique_ptr<Expression> input_) :
|
||||
Expression(Kind::At, input_->getType().get<type::Array>().itemType),
|
||||
index(std::move(index_)),
|
||||
input(std::move(input_))
|
||||
{}
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (e.getKind() == Kind::At) {
|
||||
auto rhs = static_cast<const At*>(&e);
|
||||
return *index == *(rhs->index) && *input == *(rhs->input);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override {
|
||||
return { nullopt };
|
||||
}
|
||||
|
||||
std::string getOperator() const override { return "at"; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Expression> index;
|
||||
std::unique_ptr<Expression> input;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
52
include/mbgl/style/expression/boolean_operator.hpp
Normal file
52
include/mbgl/style/expression/boolean_operator.hpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Any : public Expression {
|
||||
public:
|
||||
Any(std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(Kind::Any, type::Boolean),
|
||||
inputs(std::move(inputs_))
|
||||
{}
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
bool operator==(const Expression& e) const override;
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
std::string getOperator() const override { return "any"; }
|
||||
private:
|
||||
std::vector<std::unique_ptr<Expression>> inputs;
|
||||
};
|
||||
|
||||
class All : public Expression {
|
||||
public:
|
||||
All(std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(Kind::All, type::Boolean),
|
||||
inputs(std::move(inputs_))
|
||||
{}
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
bool operator==(const Expression& e) const override;
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
std::string getOperator() const override { return "all"; }
|
||||
private:
|
||||
std::vector<std::unique_ptr<Expression>> inputs;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
39
include/mbgl/style/expression/case.hpp
Normal file
39
include/mbgl/style/expression/case.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Case : public Expression {
|
||||
public:
|
||||
using Branch = std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>;
|
||||
|
||||
Case(type::Type type_, std::vector<Branch> branches_, std::unique_ptr<Expression> otherwise_)
|
||||
: Expression(Kind::Case, std::move(type_)), branches(std::move(branches_)), otherwise(std::move(otherwise_)) {}
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
std::string getOperator() const override { return "case"; }
|
||||
private:
|
||||
std::vector<Branch> branches;
|
||||
std::unique_ptr<Expression> otherwise;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
17
include/mbgl/style/expression/check_subtype.hpp
Normal file
17
include/mbgl/style/expression/check_subtype.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/type.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
namespace type {
|
||||
|
||||
optional<std::string> checkSubtype(const Type& expected, const Type& t);
|
||||
|
||||
} // namespace type
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
48
include/mbgl/style/expression/coalesce.hpp
Normal file
48
include/mbgl/style/expression/coalesce.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Coalesce : public Expression {
|
||||
public:
|
||||
using Args = std::vector<std::unique_ptr<Expression>>;
|
||||
Coalesce(const type::Type& type_, Args args_) :
|
||||
Expression(Kind::Coalesce, type_),
|
||||
args(std::move(args_))
|
||||
{}
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
std::size_t getLength() const {
|
||||
return args.size();
|
||||
}
|
||||
|
||||
Expression* getChild(std::size_t i) const {
|
||||
return args.at(i).get();
|
||||
}
|
||||
|
||||
std::string getOperator() const override { return "coalesce"; }
|
||||
private:
|
||||
Args args;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
37
include/mbgl/style/expression/coercion.hpp
Normal file
37
include/mbgl/style/expression/coercion.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Coercion : public Expression {
|
||||
public:
|
||||
Coercion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_);
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& params) const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
|
||||
mbgl::Value serialize() const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
std::string getOperator() const override;
|
||||
private:
|
||||
EvaluationResult (*coerceSingleValue) (const Value& v);
|
||||
std::vector<std::unique_ptr<Expression>> inputs;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
|
||||
27
include/mbgl/style/expression/collator.hpp
Normal file
27
include/mbgl/style/expression/collator.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/i18n/collator.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Collator {
|
||||
public:
|
||||
Collator(bool caseSensitive, bool diacriticSensitive, const optional<std::string>& locale = {});
|
||||
|
||||
bool operator==(const Collator& other) const;
|
||||
|
||||
int compare(const std::string& lhs, const std::string& rhs) const;
|
||||
|
||||
std::string resolvedLocale() const;
|
||||
private:
|
||||
platform::Collator collator;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
44
include/mbgl/style/expression/collator_expression.hpp
Normal file
44
include/mbgl/style/expression/collator_expression.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class CollatorExpression : public Expression {
|
||||
public:
|
||||
CollatorExpression(std::unique_ptr<Expression> caseSensitive,
|
||||
std::unique_ptr<Expression> diacriticSensitive,
|
||||
optional<std::unique_ptr<Expression>> locale);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override;
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override {
|
||||
// Technically the set of possible outputs is the combinatoric set of Collators produced
|
||||
// by all possibleOutputs of locale/caseSensitive/diacriticSensitive
|
||||
// But for the primary use of Collators in comparison operators, we ignore the Collator's
|
||||
// possibleOutputs anyway, so we can get away with leaving this undefined for now.
|
||||
return { nullopt };
|
||||
}
|
||||
|
||||
mbgl::Value serialize() const override;
|
||||
std::string getOperator() const override { return "collator"; }
|
||||
private:
|
||||
std::unique_ptr<Expression> caseSensitive;
|
||||
std::unique_ptr<Expression> diacriticSensitive;
|
||||
optional<std::unique_ptr<Expression>> locale;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
68
include/mbgl/style/expression/comparison.hpp
Normal file
68
include/mbgl/style/expression/comparison.hpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/collator_expression.hpp>
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
ParseResult parseComparison(const mbgl::style::conversion::Convertible&, ParsingContext&);
|
||||
|
||||
class BasicComparison : public Expression {
|
||||
public:
|
||||
using CompareFunctionType = bool (*)(const Value&, const Value&);
|
||||
|
||||
BasicComparison(
|
||||
std::string op,
|
||||
std::unique_ptr<Expression> lhs,
|
||||
std::unique_ptr<Expression> rhs);
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
bool operator==(const Expression&) const override;
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override;
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
std::string getOperator() const override;
|
||||
|
||||
private:
|
||||
std::string op;
|
||||
CompareFunctionType compare;
|
||||
std::unique_ptr<Expression> lhs;
|
||||
std::unique_ptr<Expression> rhs;
|
||||
bool needsRuntimeTypeCheck;
|
||||
};
|
||||
|
||||
class CollatorComparison : public Expression {
|
||||
public:
|
||||
using CompareFunctionType = bool (*)(const std::string&, const std::string&, const Collator&);
|
||||
|
||||
CollatorComparison(
|
||||
std::string op,
|
||||
std::unique_ptr<Expression> lhs,
|
||||
std::unique_ptr<Expression> rhs,
|
||||
std::unique_ptr<Expression> collator);
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
bool operator==(const Expression&) const override;
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override;
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
std::string getOperator() const override;
|
||||
|
||||
private:
|
||||
std::string op;
|
||||
CompareFunctionType compare;
|
||||
std::unique_ptr<Expression> lhs;
|
||||
std::unique_ptr<Expression> rhs;
|
||||
std::unique_ptr<Expression> collator;
|
||||
bool needsRuntimeTypeCheck;
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
59
include/mbgl/style/expression/compound_expression.hpp
Normal file
59
include/mbgl/style/expression/compound_expression.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/expression/type.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
namespace detail {
|
||||
struct SignatureBase;
|
||||
} // namespace detail
|
||||
|
||||
/*
|
||||
CompoundExpression provides a mechanism for implementing an expression
|
||||
simply by providing a list of pure functions of the form
|
||||
(const T0& arg0, const T1& arg1, ...) -> Result<U> where T0, T1, ..., U are
|
||||
member types of mbgl::style::expression::Value.
|
||||
|
||||
The majority of expressions specified in the style-spec are implemented in
|
||||
this fashion (see compound_expression.cpp).
|
||||
*/
|
||||
class CompoundExpression : public Expression {
|
||||
public:
|
||||
CompoundExpression(const detail::SignatureBase&, std::vector<std::unique_ptr<Expression>>);
|
||||
|
||||
std::string getOperator() const override;
|
||||
EvaluationResult evaluate(const EvaluationContext& evaluationParams) const override;
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
optional<std::size_t> getParameterCount() const;
|
||||
|
||||
static bool exists(const std::string& name);
|
||||
|
||||
protected:
|
||||
const detail::SignatureBase& signature;
|
||||
std::vector<std::unique_ptr<Expression>> args;
|
||||
};
|
||||
|
||||
ParseResult parseCompoundExpression(const std::string& name,
|
||||
const mbgl::style::conversion::Convertible& value,
|
||||
ParsingContext& ctx);
|
||||
|
||||
ParseResult createCompoundExpression(const std::string& name,
|
||||
std::vector<std::unique_ptr<Expression>> args,
|
||||
ParsingContext& ctx);
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
37
include/mbgl/style/expression/distance.hpp
Normal file
37
include/mbgl/style/expression/distance.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <mapbox/cheap_ruler.hpp>
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/util/geojson.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Distance final : public Expression {
|
||||
public:
|
||||
Distance(GeoJSON geoJSONSource_, Feature::geometry_type geometries_);
|
||||
|
||||
~Distance() override;
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override;
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override {}
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override;
|
||||
|
||||
mbgl::Value serialize() const override;
|
||||
std::string getOperator() const override;
|
||||
|
||||
private:
|
||||
GeoJSON geoJSONSource;
|
||||
Feature::geometry_type geometries;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
99
include/mbgl/style/expression/dsl.hpp
Normal file
99
include/mbgl/style/expression/dsl.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/interpolator.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
namespace dsl {
|
||||
|
||||
// This convenience API does little to no expression validation or type-checking, and is intended for
|
||||
// use only by test and other non-production code.
|
||||
|
||||
template <class... Args>
|
||||
std::vector<std::unique_ptr<Expression>> vec(Args... args) {
|
||||
std::vector<std::unique_ptr<Expression>> result;
|
||||
util::ignore({ (result.push_back(std::move(args)), 0)... });
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> createExpression(const char* expr);
|
||||
std::unique_ptr<Expression> createExpression(const mbgl::style::conversion::Convertible& expr);
|
||||
std::unique_ptr<Expression> error(std::string);
|
||||
|
||||
std::unique_ptr<Expression> literal(const char* value);
|
||||
std::unique_ptr<Expression> literal(const Value& value);
|
||||
std::unique_ptr<Expression> literal(std::initializer_list<double> value);
|
||||
std::unique_ptr<Expression> literal(std::initializer_list<const char*> value);
|
||||
|
||||
std::unique_ptr<Expression> assertion(const type::Type&,
|
||||
std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> number(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> string(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> boolean(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
|
||||
std::unique_ptr<Expression> toColor(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> toString(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> toFormatted(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> toImage(std::unique_ptr<Expression>, std::unique_ptr<Expression> def = nullptr);
|
||||
|
||||
std::unique_ptr<Expression> get(const char* value);
|
||||
std::unique_ptr<Expression> get(std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> id();
|
||||
std::unique_ptr<Expression> zoom();
|
||||
|
||||
std::unique_ptr<Expression> eq(std::unique_ptr<Expression>, std::unique_ptr<Expression>);
|
||||
std::unique_ptr<Expression> ne(std::unique_ptr<Expression>, std::unique_ptr<Expression>);
|
||||
std::unique_ptr<Expression> gt(std::unique_ptr<Expression>, std::unique_ptr<Expression>);
|
||||
std::unique_ptr<Expression> lt(std::unique_ptr<Expression>, std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> step(std::unique_ptr<Expression> input,
|
||||
std::unique_ptr<Expression> output0,
|
||||
double input1, std::unique_ptr<Expression> output1);
|
||||
|
||||
Interpolator linear();
|
||||
Interpolator exponential(double base);
|
||||
Interpolator cubicBezier(double x1, double y1, double x2, double y2);
|
||||
|
||||
std::unique_ptr<Expression> interpolate(Interpolator interpolator,
|
||||
std::unique_ptr<Expression> input,
|
||||
double input1, std::unique_ptr<Expression> output1);
|
||||
|
||||
std::unique_ptr<Expression> interpolate(Interpolator interpolator,
|
||||
std::unique_ptr<Expression> input,
|
||||
double input1, std::unique_ptr<Expression> output1,
|
||||
double input2, std::unique_ptr<Expression> output2);
|
||||
|
||||
std::unique_ptr<Expression> interpolate(Interpolator interpolator,
|
||||
std::unique_ptr<Expression> input,
|
||||
double input1, std::unique_ptr<Expression> output1,
|
||||
double input2, std::unique_ptr<Expression> output2,
|
||||
double input3, std::unique_ptr<Expression> output3);
|
||||
|
||||
std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inputs);
|
||||
|
||||
std::unique_ptr<Expression> format(const char* value);
|
||||
std::unique_ptr<Expression> format(std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> image(const char* value);
|
||||
std::unique_ptr<Expression> image(std::unique_ptr<Expression>);
|
||||
|
||||
} // namespace dsl
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
39
include/mbgl/style/expression/error.hpp
Normal file
39
include/mbgl/style/expression/error.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Error : public Expression {
|
||||
public:
|
||||
Error(std::string message_)
|
||||
: Expression(Kind::Error, type::Error),
|
||||
message(std::move(message_)) {}
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override {}
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
return e.getKind() == Kind::Error;
|
||||
}
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override {
|
||||
return EvaluationError{message};
|
||||
}
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string getOperator() const override { return "error"; }
|
||||
|
||||
private:
|
||||
std::string message;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
262
include/mbgl/style/expression/expression.hpp
Normal file
262
include/mbgl/style/expression/expression.hpp
Normal file
@@ -0,0 +1,262 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/expression/type.hpp>
|
||||
#include <mbgl/style/expression/value.hpp>
|
||||
#include <mbgl/tile/tile_id.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/variant.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class GeometryTileFeature;
|
||||
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class EvaluationError {
|
||||
public:
|
||||
std::string message;
|
||||
};
|
||||
|
||||
class EvaluationContext {
|
||||
public:
|
||||
EvaluationContext() = default;
|
||||
explicit EvaluationContext(float zoom_) : zoom(zoom_) {}
|
||||
explicit EvaluationContext(GeometryTileFeature const * feature_) : feature(feature_) {}
|
||||
EvaluationContext(float zoom_, GeometryTileFeature const* feature_) : zoom(zoom_), feature(feature_) {}
|
||||
EvaluationContext(optional<mbgl::Value> accumulated_, GeometryTileFeature const * feature_) :
|
||||
accumulated(std::move(accumulated_)), feature(feature_)
|
||||
{}
|
||||
EvaluationContext(float zoom_, GeometryTileFeature const* feature_, const FeatureState* state_)
|
||||
: zoom(zoom_), feature(feature_), featureState(state_) {}
|
||||
EvaluationContext(optional<float> zoom_, GeometryTileFeature const * feature_, optional<double> colorRampParameter_) :
|
||||
zoom(std::move(zoom_)), feature(feature_), colorRampParameter(std::move(colorRampParameter_))
|
||||
{}
|
||||
|
||||
EvaluationContext& withFormattedSection(const Value* formattedSection_) noexcept {
|
||||
formattedSection = formattedSection_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
EvaluationContext& withFeatureState(const FeatureState* featureState_) noexcept {
|
||||
featureState = featureState_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
EvaluationContext& withAvailableImages(const std::set<std::string>* availableImages_) noexcept {
|
||||
availableImages = availableImages_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
EvaluationContext& withCanonicalTileID(const mbgl::CanonicalTileID* canonical_) noexcept {
|
||||
canonical = canonical_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
optional<float> zoom;
|
||||
optional<mbgl::Value> accumulated;
|
||||
GeometryTileFeature const* feature = nullptr;
|
||||
optional<double> colorRampParameter;
|
||||
// Contains formatted section object, std::unordered_map<std::string, Value>.
|
||||
const Value* formattedSection = nullptr;
|
||||
const FeatureState* featureState = nullptr;
|
||||
const std::set<std::string>* availableImages = nullptr;
|
||||
const mbgl::CanonicalTileID* canonical = nullptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class Result : private variant<EvaluationError, T> {
|
||||
public:
|
||||
using variant<EvaluationError, T>::variant;
|
||||
using Value = T;
|
||||
|
||||
Result() = default;
|
||||
|
||||
explicit operator bool () const {
|
||||
return this->template is<T>();
|
||||
}
|
||||
|
||||
// optional does some type trait magic for this one, so this might
|
||||
// be problematic as is.
|
||||
const T* operator->() const {
|
||||
assert(this->template is<T>());
|
||||
return std::addressof(this->template get<T>());
|
||||
}
|
||||
|
||||
T* operator->() {
|
||||
assert(this->template is<T>());
|
||||
return std::addressof(this->template get<T>());
|
||||
}
|
||||
|
||||
T& operator*() {
|
||||
assert(this->template is<T>());
|
||||
return this->template get<T>();
|
||||
}
|
||||
|
||||
const T& operator*() const {
|
||||
assert(this->template is<T>());
|
||||
return this->template get<T>();
|
||||
}
|
||||
|
||||
const EvaluationError& error() const {
|
||||
assert(this->template is<EvaluationError>());
|
||||
return this->template get<EvaluationError>();
|
||||
}
|
||||
};
|
||||
|
||||
class EvaluationResult : public Result<Value> {
|
||||
public:
|
||||
using Result::Result; // NOLINT
|
||||
|
||||
EvaluationResult() = default;
|
||||
|
||||
EvaluationResult(const std::array<double, 4>& arr) :
|
||||
Result(toExpressionValue(arr))
|
||||
{}
|
||||
|
||||
// used only for the special (private) "error" expression
|
||||
EvaluationResult(const type::ErrorType&) {
|
||||
assert(false);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Expression is an abstract class that serves as an interface and base class
|
||||
for particular expression implementations.
|
||||
|
||||
CompoundExpression implements the majority of expressions in the spec by
|
||||
inferring the argument and output from a simple function (const T0& arg0,
|
||||
const T1& arg1, ...) -> Result<U> where T0, T1, ..., U are member types of
|
||||
mbgl::style::expression::Value.
|
||||
|
||||
The other Expression subclasses (Let, Curve, Match, etc.) exist in order to
|
||||
implement expressions that need specialized parsing, type checking, or
|
||||
evaluation logic that can't be handled by CompoundExpression's inference
|
||||
mechanism.
|
||||
|
||||
Each Expression subclass also provides a static
|
||||
ParseResult ExpressionClass::parse(const V&, ParsingContext),
|
||||
which handles parsing a style-spec JSON representation of the expression.
|
||||
*/
|
||||
|
||||
enum class Kind : int32_t {
|
||||
Coalesce,
|
||||
CompoundExpression,
|
||||
Literal,
|
||||
At,
|
||||
Interpolate,
|
||||
Assertion,
|
||||
Length,
|
||||
Step,
|
||||
Let,
|
||||
Var,
|
||||
CollatorExpression,
|
||||
Coercion,
|
||||
Match,
|
||||
Error,
|
||||
Case,
|
||||
Any,
|
||||
All,
|
||||
Comparison,
|
||||
FormatExpression,
|
||||
FormatSectionOverride,
|
||||
NumberFormat,
|
||||
ImageExpression,
|
||||
In,
|
||||
Within,
|
||||
Distance
|
||||
};
|
||||
|
||||
class Expression {
|
||||
public:
|
||||
Expression(Kind kind_, type::Type type_) : kind(kind_), type(std::move(type_)) {}
|
||||
virtual ~Expression() = default;
|
||||
|
||||
virtual EvaluationResult evaluate(const EvaluationContext& params) const = 0;
|
||||
virtual void eachChild(const std::function<void(const Expression&)>&) const = 0;
|
||||
virtual bool operator==(const Expression&) const = 0;
|
||||
bool operator!=(const Expression& rhs) const {
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
Kind getKind() const { return kind; };
|
||||
type::Type getType() const { return type; };
|
||||
|
||||
EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> colorRampParameter) const;
|
||||
EvaluationResult evaluate(optional<float> zoom,
|
||||
const Feature& feature,
|
||||
optional<double> colorRampParameter,
|
||||
const std::set<std::string>& availableImages) const;
|
||||
EvaluationResult evaluate(optional<float> zoom,
|
||||
const Feature& feature,
|
||||
optional<double> colorRampParameter,
|
||||
const std::set<std::string>& availableImages,
|
||||
const CanonicalTileID& canonical) const;
|
||||
EvaluationResult evaluate(optional<mbgl::Value> accumulated, const Feature& feature) const;
|
||||
|
||||
/**
|
||||
* Statically analyze the expression, attempting to enumerate possible outputs. Returns
|
||||
* an array of values plus the sentinel null optional value, used to indicate that the
|
||||
* complete set of outputs is statically undecidable.
|
||||
*/
|
||||
virtual std::vector<optional<Value>> possibleOutputs() const = 0;
|
||||
|
||||
virtual mbgl::Value serialize() const {
|
||||
std::vector<mbgl::Value> serialized;
|
||||
serialized.emplace_back(getOperator());
|
||||
eachChild([&](const Expression &child) {
|
||||
serialized.emplace_back(child.serialize());
|
||||
});
|
||||
return serialized;
|
||||
};
|
||||
|
||||
virtual std::string getOperator() const = 0;
|
||||
|
||||
protected:
|
||||
template <typename T>
|
||||
static bool childrenEqual(const T& lhs, const T& rhs) {
|
||||
if (lhs.size() != rhs.size()) return false;
|
||||
for (auto leftChild = lhs.begin(), rightChild = rhs.begin();
|
||||
leftChild != lhs.end();
|
||||
leftChild++, rightChild++)
|
||||
{
|
||||
if (!Expression::childEqual(*leftChild, *rightChild)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool childEqual(const std::unique_ptr<Expression>& lhs, const std::unique_ptr<Expression>& rhs) {
|
||||
return *lhs == *rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool childEqual(const std::pair<T, std::unique_ptr<Expression>>& lhs,
|
||||
const std::pair<T, std::unique_ptr<Expression>>& rhs) {
|
||||
return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool childEqual(const std::pair<T, std::shared_ptr<Expression>>& lhs,
|
||||
const std::pair<T, std::shared_ptr<Expression>>& rhs) {
|
||||
return lhs.first == rhs.first && *(lhs.second) == *(rhs.second);
|
||||
}
|
||||
|
||||
static bool childEqual(const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& lhs,
|
||||
const std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>& rhs) {
|
||||
return *(lhs.first) == *(rhs.first) && *(lhs.second) == *(rhs.second);
|
||||
}
|
||||
|
||||
private:
|
||||
Kind kind;
|
||||
type::Type type;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
20
include/mbgl/style/expression/find_zoom_curve.hpp
Normal file
20
include/mbgl/style/expression/find_zoom_curve.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
|
||||
#include <mbgl/util/variant.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e);
|
||||
|
||||
variant<std::nullptr_t, const Interpolate*, const Step*> findZoomCurveChecked(const expression::Expression* e);
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
53
include/mbgl/style/expression/format_expression.hpp
Normal file
53
include/mbgl/style/expression/format_expression.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/parsing_context.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
struct FormatExpressionSection {
|
||||
explicit FormatExpressionSection(std::unique_ptr<Expression> content_);
|
||||
|
||||
void setTextSectionOptions(optional<std::unique_ptr<Expression>> fontScale_,
|
||||
optional<std::unique_ptr<Expression>> textFont_,
|
||||
optional<std::unique_ptr<Expression>> textColor_);
|
||||
|
||||
// Content can be expression that evaluates to String or Image.
|
||||
std::shared_ptr<Expression> content;
|
||||
|
||||
// Text related section options.
|
||||
optional<std::shared_ptr<Expression>> fontScale;
|
||||
optional<std::shared_ptr<Expression>> textFont;
|
||||
optional<std::shared_ptr<Expression>> textColor;
|
||||
};
|
||||
|
||||
class FormatExpression final : public Expression {
|
||||
public:
|
||||
explicit FormatExpression(std::vector<FormatExpressionSection> sections);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override;
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override {
|
||||
// Technically the combinatoric set of all children
|
||||
// Usually, this.text will be undefined anyway
|
||||
return { nullopt };
|
||||
}
|
||||
|
||||
const std::vector<FormatExpressionSection>& getSections() const { return sections; }
|
||||
|
||||
mbgl::Value serialize() const override;
|
||||
std::string getOperator() const override { return "format"; }
|
||||
private:
|
||||
std::vector<FormatExpressionSection> sections;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
86
include/mbgl/style/expression/format_section_override.hpp
Normal file
86
include/mbgl/style/expression/format_section_override.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/renderer/possibly_evaluated_property_value.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
template<class T>
|
||||
class FormatSectionOverride final : public Expression {
|
||||
public:
|
||||
FormatSectionOverride(const type::Type& type_,
|
||||
PossiblyEvaluatedPropertyValue<T> defaultValue_,
|
||||
std::string propertyName_) :
|
||||
Expression(Kind::FormatSectionOverride, type_),
|
||||
defaultValue(std::move(defaultValue_)),
|
||||
propertyName(std::move(propertyName_))
|
||||
{}
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext& context) const final {
|
||||
using Object = std::unordered_map<std::string, expression::Value>;
|
||||
if (context.formattedSection &&
|
||||
context.formattedSection->is<Object>()) {
|
||||
const auto& section = context.formattedSection->get<Object>();
|
||||
if (section.find(propertyName) != section.end()) {
|
||||
return section.at(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue.match(
|
||||
[&context] (const style::PropertyExpression<T>& e) { return e.getExpression().evaluate(context); },
|
||||
[] (const T& t) -> EvaluationResult { return t; }
|
||||
);
|
||||
}
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>& fn) const final {
|
||||
defaultValue.match([&fn] (const style::PropertyExpression<T>& e) { fn(e.getExpression()); },
|
||||
[] (const T&) {});
|
||||
}
|
||||
|
||||
bool operator==(const Expression& e) const final {
|
||||
if (e.getKind() == Kind::FormatSectionOverride) {
|
||||
const auto* other = static_cast<const FormatSectionOverride*>(&e);
|
||||
|
||||
if (getType() != other->getType() || propertyName != other->propertyName) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that default values or property expressions are equal.
|
||||
return defaultValue.match(
|
||||
[other] (const style::PropertyExpression<T>& thisExpr) {
|
||||
return other->defaultValue.match([&thisExpr] (const style::PropertyExpression<T>& otherExpr) {
|
||||
return thisExpr == otherExpr;
|
||||
},
|
||||
[] (const T&) {
|
||||
return false;
|
||||
});
|
||||
},
|
||||
[other] (const T& thisValue) {
|
||||
return other->defaultValue.match([&thisValue] (const T& otherValue) {
|
||||
return thisValue == otherValue;
|
||||
},
|
||||
[] (const style::PropertyExpression<T>&) {
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const final {
|
||||
return {nullopt};
|
||||
}
|
||||
|
||||
std::string getOperator() const final { return "format-section-override"; }
|
||||
|
||||
private:
|
||||
PossiblyEvaluatedPropertyValue<T> defaultValue;
|
||||
std::string propertyName;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user