Skip to content

Commit

Permalink
Add layer view implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
albin-johansson committed Jul 13, 2024
1 parent 2afaded commit 5c1ea4b
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 0 deletions.
2 changes: 2 additions & 0 deletions source/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ target_sources(tactile-core
"src/tactile/core/debug/stacktrace.cpp"
"src/tactile/core/debug/terminate.cpp"
"src/tactile/core/document/document_manager.cpp"
"src/tactile/core/document/layer_view_impl.cpp"
"src/tactile/core/document/map_document.cpp"
"src/tactile/core/document/meta_view_impl.cpp"
"src/tactile/core/document/object_view_impl.cpp"
Expand Down Expand Up @@ -131,6 +132,7 @@ target_sources(tactile-core
"inc/tactile/core/document/document.hpp"
"inc/tactile/core/document/document_info.hpp"
"inc/tactile/core/document/document_manager.hpp"
"inc/tactile/core/document/layer_view_impl.hpp"
"inc/tactile/core/document/map_document.hpp"
"inc/tactile/core/document/meta_view_impl.hpp"
"inc/tactile/core/document/object_view_impl.hpp"
Expand Down
65 changes: 65 additions & 0 deletions source/core/inc/tactile/core/document/layer_view_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#pragma once

#include "tactile/base/document/layer_view.hpp"
#include "tactile/base/prelude.hpp"
#include "tactile/core/document/meta_view_impl.hpp"
#include "tactile/core/entity/entity.hpp"

namespace tactile {

class MapDocument;
class ILayerView;

/**
* A layer view implementation.
*/
class LayerViewImpl final : public ILayerView
{
public:
/**
* Creates a layer view.
*
* \param document The associated document.
* \param parent_layer The parent layer, if any.
* \param layer_id The layer entity identifier.
*/
LayerViewImpl(const MapDocument* document,
const ILayerView* parent_layer,
EntityID layer_id);

void accept(IDocumentVisitor& visitor) const override;

[[nodiscard]]
auto get_parent_layer() const -> const ILayerView* override;

[[nodiscard]]
auto get_type() const -> LayerType override;

[[nodiscard]]
auto get_opacity() const -> float override;

[[nodiscard]]
auto is_visible() const -> bool override;

[[nodiscard]]
auto get_global_index() const -> usize override;

[[nodiscard]]
auto get_tile(const MatrixIndex& index) const -> Optional<TileID> override;

[[nodiscard]]
auto get_extent() const -> Optional<MatrixExtent> override;

[[nodiscard]]
auto get_meta() const -> const IMetaView& override;

private:
const MapDocument* mDocument;
const ILayerView* mParentLayer;
EntityID mLayerId;
MetaViewImpl mMeta;
};

} // namespace tactile
130 changes: 130 additions & 0 deletions source/core/src/tactile/core/document/layer_view_impl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (C) 2024 Albin Johansson (GNU General Public License v3.0)

#include "tactile/core/document/layer_view_impl.hpp"

#include "tactile/base/document/document_visitor.hpp"
#include "tactile/core/debug/exception.hpp"
#include "tactile/core/debug/validation.hpp"
#include "tactile/core/document/map_document.hpp"
#include "tactile/core/document/object_view_impl.hpp"
#include "tactile/core/entity/registry.hpp"
#include "tactile/core/layer/group_layer.hpp"
#include "tactile/core/layer/layer.hpp"
#include "tactile/core/layer/object_layer.hpp"
#include "tactile/core/layer/tile_layer.hpp"
#include "tactile/core/map/map.hpp"
#include "tactile/core/meta/meta.hpp"

namespace tactile {

LayerViewImpl::LayerViewImpl(const MapDocument* document,
const ILayerView* parent_layer,
const EntityID layer_id)
: mDocument {require_not_null(document, "null document")},
mParentLayer {parent_layer},
mLayerId {layer_id},
mMeta {document, mLayerId}
{}

void LayerViewImpl::accept(IDocumentVisitor& visitor) const
{
const auto& registry = mDocument->get_registry();

visitor.visit(*this);

if (is_group_layer(registry, mLayerId)) {
const auto& group_layer = registry.get<CGroupLayer>(mLayerId);

for (const auto sublayer_id : group_layer.layers) {
const LayerViewImpl sublayer_view {mDocument, this, sublayer_id};
sublayer_view.accept(visitor);
}
}
else if (is_object_layer(registry, mLayerId)) {
const auto& object_layer = registry.get<CObjectLayer>(mLayerId);

for (const auto object_id : object_layer.objects) {
const ObjectViewImpl object_view {mDocument, this, object_id};
object_view.accept(visitor);
}
}
}

auto LayerViewImpl::get_parent_layer() const -> const ILayerView*
{
return mParentLayer;
}

auto LayerViewImpl::get_opacity() const -> float
{
const auto& registry = mDocument->get_registry();
const auto& layer = registry.get<CLayer>(mLayerId);

return layer.opacity;
}

auto LayerViewImpl::is_visible() const -> bool
{
const auto& registry = mDocument->get_registry();
const auto& layer = registry.get<CLayer>(mLayerId);

return layer.visible;
}

auto LayerViewImpl::get_global_index() const -> usize
{
const auto map_id = mDocument->get_root_entity();

const auto& registry = mDocument->get_registry();
const auto& map = registry.get<CMap>(map_id);

return get_global_layer_index(registry, map.root_layer, mLayerId).value();
}

auto LayerViewImpl::get_type() const -> LayerType
{
const auto& registry = mDocument->get_registry();

if (is_tile_layer(registry, mLayerId)) {
return LayerType::kTileLayer;
}

if (is_object_layer(registry, mLayerId)) {
return LayerType::kObjectLayer;
}

if (is_group_layer(registry, mLayerId)) {
return LayerType::kGroupLayer;
}

throw Exception {"unexpected layer type"};
}

auto LayerViewImpl::get_tile(const MatrixIndex& index) const -> Optional<TileID>
{
const auto& registry = mDocument->get_registry();

if (!is_tile_layer(registry, mLayerId)) {
return kNone;
}

return get_tile_layer_data(registry, mLayerId).at(index);
}

auto LayerViewImpl::get_extent() const -> Optional<MatrixExtent>
{
const auto& registry = mDocument->get_registry();

if (!is_tile_layer(registry, mLayerId)) {
return kNone;
}

return get_tile_layer_data(registry, mLayerId).get_extent();
}

auto LayerViewImpl::get_meta() const -> const IMetaView&
{
return mMeta;
}

} // namespace tactile

0 comments on commit 5c1ea4b

Please sign in to comment.