Skip to content

Commit

Permalink
Doc additions, minor tuneups (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilijapuaca authored Jun 8, 2020
1 parent 73579fe commit c4b6c52
Show file tree
Hide file tree
Showing 36 changed files with 290 additions and 190 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ endif()
# BUNDLE LIBRARY #
##################

# TODO: Should be a shared lib. Generate an empty source file?
# Currently only used internally to link against for testing purposes
add_library(deckgl-bundle INTERFACE)

# Define module libs
Expand Down
6 changes: 3 additions & 3 deletions cpp/modules/deck.gl/core/src/arrow/row.cc
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ auto Row::_getChunk(const std::string& columnName) const -> std::shared_ptr<arro

// Iterate over column chunks and find the chunk that contains row data
int64_t offset = 0;
for (auto chunk : column->chunks()) {
for (const auto& chunk : column->chunks()) {
if (this->_rowIndex >= offset && this->_rowIndex < offset + chunk->length()) {
// TODO(ilija@unfolded.ai): Cache
// TODO(ilija@unfolded.ai): Cache chunks once Rows are being reused properly
return chunk;
}

Expand Down Expand Up @@ -183,7 +183,7 @@ auto Row::_getRowChunkData(const std::shared_ptr<arrow::Table>& table, int64_t r
throw std::logic_error("Invalid chunk lookup");
}

// TODO(ilija@unfolded.ai): Sacrificing performance and precision for conciseness, revisit
// Sacrificing performance and precision for conciseness. Revisit if this becomes a bottleneck
auto Row::_getDouble(const std::shared_ptr<arrow::Array>& chunk) const -> std::optional<double> {
switch (chunk->type_id()) {
case arrow::Type::DOUBLE:
Expand Down
78 changes: 76 additions & 2 deletions cpp/modules/deck.gl/core/src/arrow/row.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

namespace deckgl {

/// \brief Utility structure that holds metadata of a generic list array.
struct ListArrayMetadata {
public:
ListArrayMetadata(int32_t offset, int32_t length, const std::shared_ptr<arrow::Array>& values)
Expand All @@ -45,36 +46,88 @@ struct ListArrayMetadata {
std::shared_ptr<arrow::Array> values;
};

/// \brief Represents a single row within a given table, which can be queried for easy access to typed data.
class Row {
public:
Row(const std::shared_ptr<arrow::Table>& table, int64_t rowIndex);

/// \brief Attempts to get an integer value in this row, for a given columnName.
/// If the value is of a different type, best effort will be used to convert it to an integer.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Integer value found in this row for the given columnName, or defaultValue if one isn't found.
auto getInt(const std::string& columnName, int defaultValue = 0) const -> int;

/// \brief Attempts to get a float value in this row, for a given columnName.
/// If the value is of a different type, best effort will be used to convert it to a float.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Float value found in this row for the given columnName, or defaultValue if one isn't found.
auto getFloat(const std::string& columnName, float defaultValue = 0.0) const -> float;

/// \brief Attempts to get a double value in this row, for a given columnName.
/// If the value is of a different type, best effort will be used to convert it to a double.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Double value found in this row for the given columnName, or defaultValue if one isn't found.
auto getDouble(const std::string& columnName, double defaultValue = 0.0) const -> double;

/// \brief Attempts to get a boolean value in this row, for a given columnName.
/// If the value is of a different type, best effort will be used to convert it to a boolean.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Boolean value found in this row for the given columnName, or defaultValue if one isn't found.
auto getBool(const std::string& columnName, bool defaultValue = false) const -> bool;

/// \brief Attempts to get a string value in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns String value found in this row for the given columnName, or defaultValue if one isn't found.
auto getString(const std::string& columnName, const std::string& defaultValue = "") const -> std::string;

/// \brief Attempts to get vector data out of a list array found in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Vector data, potentially padded with zeros if the list was not of a sufficient length,
/// or defaultValue if data could not be found.
template <typename T>
auto getVector2(const std::string& columnName, const mathgl::Vector2<T>& defaultValue = {}) const
-> mathgl::Vector2<T> {
auto data = this->getListData<T>(columnName, {defaultValue.x, defaultValue.y});
return mathgl::Vector2<T>{data.size() > 0 ? data.at(0) : 0, data.size() > 1 ? data.at(1) : 0};
}

/// \brief Attempts to get vector data out of a list array found in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Vector data, potentially padded with zeros if the list was not of a sufficient length,
/// or defaultValue if data could not be found.
template <typename T>
auto getVector3(const std::string& columnName, const mathgl::Vector3<T>& defaultValue = {}) const
-> mathgl::Vector3<T> {
auto data = this->getListData<T>(columnName, {defaultValue.x, defaultValue.y, defaultValue.z});
return mathgl::Vector3<T>{data.size() > 0 ? data.at(0) : 0, data.size() > 1 ? data.at(1) : 0,
data.size() > 2 ? data.at(2) : 0};
}

/// \brief Attempts to get vector data out of a list array found in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns Vector data, potentially padded with zeros if the list was not of a sufficient length,
/// or defaultValue if data could not be found.
template <typename T>
auto getVector4(const std::string& columnName, const mathgl::Vector4<T>& defaultValue = {}) const
-> mathgl::Vector4<T> {
auto data = this->getListData<T>(columnName, {defaultValue.x, defaultValue.y, defaultValue.z, defaultValue.w});
return mathgl::Vector4<T>{data.size() > 0 ? data.at(0) : 0, data.size() > 1 ? data.at(1) : 0,
data.size() > 2 ? data.at(2) : 0, data.size() > 3 ? data.at(3) : 0};
}

/// \brief Attempts to get a set of vector data out of a nested list array found in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns A collection of vector data, potentially padded with zeros if the list was not of a sufficient length,
/// or defaultValue if data could not be found.
template <typename T>
auto getVector2List(const std::string& columnName, const std::vector<mathgl::Vector2<T>>& defaultValue = {}) const
-> std::vector<mathgl::Vector2<T>> {
Expand All @@ -87,6 +140,12 @@ class Row {

return vectorData;
}

/// \brief Attempts to get a set of vector data out of a nested list array found in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns A collection of vector data, potentially padded with zeros if the list was not of a sufficient length,
/// or defaultValue if data could not be found.
template <typename T>
auto getVector3List(const std::string& columnName, const std::vector<mathgl::Vector3<T>>& defaultValue = {}) const
-> std::vector<mathgl::Vector3<T>> {
Expand All @@ -100,6 +159,12 @@ class Row {

return vectorData;
}

/// \brief Attempts to get a set of vector data out of a nested list array found in this row, for a given columnName.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns A collection of vector data, potentially padded with zeros if the list was not of a sufficient length,
/// or defaultValue if data could not be found.
template <typename T>
auto getVector4List(const std::string& columnName, const std::vector<mathgl::Vector4<T>>& defaultValue = {}) const
-> std::vector<mathgl::Vector4<T>> {
Expand All @@ -113,6 +178,11 @@ class Row {

return vectorData;
}

/// \brief Attempts to get a variable sized collection of arbitrary data.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns A collection of requested data type, or defaultValue if data could not be found.
template <typename T>
auto getListData(const std::string& columnName, const std::vector<T>& defaultValue = {}) const -> std::vector<T> {
if (!this->isValid(columnName)) {
Expand All @@ -128,6 +198,11 @@ class Row {

return this->_getListData(optionalMetadata.value(), defaultValue);
}

/// \brief Attempts to get a nested, variable sized collection of arbitrary data.
/// \param columnName Name of the column to get the data for.
/// \param defaultValue Default value that'll be returned if data could not be found.
/// \returns A collection of requested data type, or defaultValue if data could not be found.
template <typename T>
auto getNestedListData(const std::string& columnName, const std::vector<std::vector<T>>& defaultValue = {}) const
-> std::vector<std::vector<T>> {
Expand All @@ -151,6 +226,7 @@ class Row {
auto isValid(const std::string& columnName) const -> bool;

/// \brief Increments current row index.
/// \param increment Amount to increment the current row index by.
void incrementRowIndex(uint64_t increment = 1);

private:
Expand Down Expand Up @@ -249,8 +325,6 @@ class Row {

/// \brief Relative row index in respect to the chunk.
int64_t _chunkRowIndex;

// std::unordered_map<std::string, std::shared_ptr<arrow::Array>> _cache;
};

} // namespace deckgl
Expand Down
4 changes: 2 additions & 2 deletions cpp/modules/deck.gl/core/src/lib/component.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
using namespace deckgl;

// Setters and getters for properties
// TODO(ib@unfolded.ai): auto generate from language-independent prop definition schema
// TODO(ilija@unfolded.ai): Generate a unique id instead of an empty string for default value?
// TODO(ib@unfolded.ai): Auto generate from language-independent prop definition schema
// TODO(ilija@unfolded.ai): Generate a unique id instead of an empty string for default value of id?
static const std::vector<std::shared_ptr<Property>> propTypeDefs = {std::make_shared<PropertyT<std::string>>(
"id", [](const JSONObject* props) { return dynamic_cast<const Component::Props*>(props)->id; },
[](JSONObject* props, std::string value) { return dynamic_cast<Component::Props*>(props)->id = value; }, "")};
Expand Down
1 change: 1 addition & 0 deletions cpp/modules/deck.gl/core/src/lib/component.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

namespace deckgl {

/// \brief A root class for JSON-serialzed components of the API.
class Component {
public:
class Props;
Expand Down
6 changes: 3 additions & 3 deletions cpp/modules/deck.gl/core/src/lib/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@

namespace deckgl {

// Note: The numeric values here are matched by shader code in the
// NOTE: The numeric values here are matched by shader code in the
// "project" and "project64" shader modules. Both places need to be updated.

// Describes how positions are interpreted. Can be specified per layer
/// \brief Describes how positions are interpreted. Can be specified per layer
enum class COORDINATE_SYSTEM {
DEFAULT = -1, // `LNGLAT` if rendering into a geospatial viewport,
// `CARTESIAN` otherwise
Expand All @@ -52,7 +52,7 @@ inline auto fromJson<COORDINATE_SYSTEM>(const Json::Value& jsonValue) -> COORDIN
return static_cast<COORDINATE_SYSTEM>(fromJson<int>(jsonValue));
}

// Describes the common space
/// \brief Describes the common space.
enum class PROJECTION_MODE {
IDENTITY = 0,
WEB_MERCATOR = 1,
Expand Down
10 changes: 6 additions & 4 deletions cpp/modules/deck.gl/core/src/lib/deck.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
using namespace deckgl;

// Setters and getters for properties
// TODO(ib@unfolded.ai): auto generate from language-independent prop definition schema
// TODO(ib@unfolded.ai): Auto generate from language-independent prop definition schema
static const std::vector<std::shared_ptr<Property>> propTypeDefs = {
std::make_shared<PropertyT<std::list<std::shared_ptr<Layer::Props>>>>(
"layers", [](const JSONObject* props) { return dynamic_cast<const Deck::Props*>(props)->layers; },
Expand Down Expand Up @@ -200,9 +200,11 @@ void Deck::_drawLayers(wgpu::RenderPassEncoder pass, std::function<void(Deck*)>
// Expose the current viewport to layers for project* function
this->layerManager->activateViewport(viewport);

for (auto const& layer : this->layerManager->layers) {
// TODO(ilija@unfolded.ai): Pass relevant layer properties to getUniformsFromViewport
auto viewportUniforms = getUniformsFromViewport(viewport, this->animationLoop->devicePixelRatio());
for (auto const& layer : this->layerManager->layers()) {
auto layerProps = layer->props();
auto viewportUniforms = getUniformsFromViewport(viewport, this->animationLoop->devicePixelRatio(),
layerProps->modelMatrix, layerProps->coordinateSystem,
layerProps->coordinateOrigin, layerProps->wrapLongitude);

this->_viewportUniformsBuffer.SetSubData(0, sizeof(ViewportUniforms), &viewportUniforms);
for (auto const& model : layer->models()) {
Expand Down
25 changes: 24 additions & 1 deletion cpp/modules/deck.gl/core/src/lib/deck.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

namespace deckgl {

/// \brief Deck is a class that takes deck.gl layer instances and viewport parameters, and renders those
/// layers as a transparent overlay.
class Deck : public Component {
public:
class Props;
Expand All @@ -55,23 +57,40 @@ class Deck : public Component {
explicit Deck(std::shared_ptr<Deck::Props> props = std::make_shared<Deck::Props>());
~Deck();

/// \brief Returns the current properties attached to this Deck instance.
auto props() { return std::dynamic_pointer_cast<Props>(this->_props); }

/// \brief Sets a new set of properties, picking up all the differences compared to the current one.
/// @param props A new set of properties to use.
void setProps(std::shared_ptr<Deck::Props> props);

/// \brief Runs an animation loop that draws this Deck.
/// \param onAfterRender Function that'll be called whenever frame has been drawn.
void run(std::function<void(Deck*)> onAfterRender = [](Deck*) {});

/// \brief Draws the current Deck state into the given textureView, calling onAfteRender once drawing has finished.
/// \param textureView Texture view to draw the current state into.
/// \param onAfterRender Function that'll be called whenever frame has been drawn.
void draw(
wgpu::TextureView textureView, std::function<void(Deck*)> onAfterRender = [](Deck*) {});

/// \brief Stops the animation loop, if one is currently running.
void stop();

/// \brief Check if a redraw is needed.
/// \param clearRedrawFlags Whether needsRedraw flag should be cleared or not.
/// \returns Returns an optional string summarizing the redraw reason.
auto needsRedraw(bool clearRedrawFlags = false) -> std::optional<std::string>;

/// \brief Gets a list of views that this Deck is viewed from.
/// \returns A list of View instances that this Deck can be viewed from.
auto getViews() -> std::list<std::shared_ptr<View>> { return this->viewManager->getViews(); }

/// \brief Gets the current viewport size of this Deck.
/// \returns Width and height of the current viewport.
auto size() -> lumagl::Size { return this->_size; };

// TODO(ilija@unfolded.ai): These should be get-only?
std::shared_ptr<lumagl::AnimationLoop> animationLoop;
std::shared_ptr<ViewManager> viewManager{new ViewManager()};
std::shared_ptr<LayerContext> context;
Expand All @@ -96,13 +115,17 @@ class Deck : public Component {

// Instead of maintaining another structure with options, we reuse the relevant struct from lumagl
using DrawingOptions = lumagl::AnimationLoop::Options;
/// \brief A set of properties that represent a single Deck.
class Deck::Props : public Component::Props {
public:
using super = Component::Props;

int width{100}; // Dummy value, ensure something is visible if user forgets to set window size
/// \brief Width of the viewport, in pixels.
int width{100}; // Dummy value, ensure something is visible if user forgets to set window size
/// \brief Height of the viewport, in pixels.
int height{100}; // Dummy value, ensure something is visible if user forgets to set window size

/// \brief A set of options that customize the drawing of this Deck.
std::shared_ptr<DrawingOptions> drawingOptions;

// Layer/View/Controller settings
Expand Down
2 changes: 1 addition & 1 deletion cpp/modules/deck.gl/core/src/lib/layer-context.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class Deck;
class LayerManager;
class Viewport;

/// \brief LayerContext is data shared between all layers.
/// \brief LayerContext contains data shared between all layers.
class LayerContext {
public:
// TODO(ilija@unfolded.ai): Do we need to have this circular dependency here?
Expand Down
Loading

0 comments on commit c4b6c52

Please sign in to comment.