diff --git a/src/SceneGraph/AbstractGroupedFeature.h b/src/SceneGraph/AbstractGroupedFeature.h index e0273d3a0..2eba08bd1 100644 --- a/src/SceneGraph/AbstractGroupedFeature.h +++ b/src/SceneGraph/AbstractGroupedFeature.h @@ -28,7 +28,6 @@ * @brief Class Magnum::SceneGraph::AbstractGroupedFeature, alias Magnum::SceneGraph::AbstractGroupedFeature2D, Magnum::SceneGraph::AbstractGroupedFeature3D */ -#include #include #include "AbstractFeature.h" @@ -53,6 +52,16 @@ class Drawable: public SceneGraph::AbstractGroupedFeature3D { typedef SceneGraph::FeatureGroup3D DrawableGroup; @endcode +@section AbstractGroupedFeature-explicit-specializations Explicit template specializations + +The following specialization are explicitly compiled into %SceneGraph library. +For other specializations (e.g. using Double type) you have to use +AbstractGroupedFeature.hpp implementation file to avoid linker errors. See also +@ref compilation-speedup-hpp for more information. + + - @ref AbstractFeatureGroup "AbstractFeatureGroup<2, Float>" + - @ref AbstractFeatureGroup "AbstractFeatureGroup<3, Float>" + @see @ref scenegraph, AbstractGroupedFeature2D, AbstractGroupedFeature3D, FeatureGroup, FeatureGroup2D, FeatureGroup3D */ diff --git a/src/SceneGraph/CMakeLists.txt b/src/SceneGraph/CMakeLists.txt index 3ad414690..3279d44c5 100644 --- a/src/SceneGraph/CMakeLists.txt +++ b/src/SceneGraph/CMakeLists.txt @@ -61,6 +61,7 @@ set(MagnumSceneGraph_HEADERS RigidMatrixTransformation2D.h RigidMatrixTransformation3D.h FeatureGroup.h + FeatureGroup.hpp MatrixTransformation2D.h MatrixTransformation3D.h Object.h diff --git a/src/SceneGraph/FeatureGroup.h b/src/SceneGraph/FeatureGroup.h index bbf622566..0f7e3cc61 100644 --- a/src/SceneGraph/FeatureGroup.h +++ b/src/SceneGraph/FeatureGroup.h @@ -28,14 +28,36 @@ * @brief Class Magnum::SceneGraph::FeatureGroup, alias Magnum::SceneGraph::FeatureGroup2D, Magnum::SceneGraph::FeatureGroup3D */ -#include #include #include -#include "SceneGraph.h" +#include "SceneGraph/SceneGraph.h" +#include "SceneGraph/magnumSceneGraphVisibility.h" namespace Magnum { namespace SceneGraph { +/** +@brief Base for group of features + +See FeatureGroup. +*/ +#ifndef DOXYGEN_GENERATING_OUTPUT +template +#else +template +#endif +class MAGNUM_SCENEGRAPH_EXPORT AbstractFeatureGroup { + template friend class FeatureGroup; + + explicit AbstractFeatureGroup(); + ~AbstractFeatureGroup(); + + void add(AbstractFeature* feature); + void remove(AbstractFeature* feature); + + std::vector*> features; +}; + /** @brief Group of features @@ -47,7 +69,7 @@ template #else template #endif -class FeatureGroup { +class FeatureGroup: public AbstractFeatureGroup { friend class AbstractGroupedFeature; public: @@ -58,24 +80,22 @@ class FeatureGroup { * * Removes all features belonging to this group, but not deletes them. */ - inline virtual ~FeatureGroup() { - for(auto i: features) i->_group = nullptr; - } + virtual ~FeatureGroup(); /** @brief Whether the group is empty */ - inline bool isEmpty() const { return features.empty(); } + inline bool isEmpty() const { return this->features.empty(); } /** @brief Count of features in the group */ - inline std::size_t size() const { return features.size(); } + inline std::size_t size() const { return this->features.size(); } /** @brief Feature at given index */ inline Feature* operator[](std::size_t index) { - return features[index]; + return static_cast(this->features[index]); } /** @overload */ inline const Feature* operator[](std::size_t index) const { - return features[index]; + return static_cast(this->features[index]); } /** @@ -85,16 +105,7 @@ class FeatureGroup { * If the features is part of another group, it is removed from it. * @see remove(), AbstractGroupedFeature::AbstractGroupedFeature() */ - FeatureGroup* add(Feature* feature) { - /* Remove from previous group */ - if(feature->_group) - feature->_group->remove(feature); - - /* Crossreference the feature and group together */ - features.push_back(feature); - feature->_group = this; - return this; - } + FeatureGroup* add(Feature* feature); /** * @brief Remove feature from the group @@ -103,18 +114,7 @@ class FeatureGroup { * The feature must be part of the group. * @see add() */ - FeatureGroup* remove(Feature* feature) { - CORRADE_ASSERT(feature->_group == this, - "SceneGraph::AbstractFeatureGroup::remove(): feature is not part of this group", this); - - /* Remove the feature and reset group pointer */ - features.erase(std::find(features.begin(), features.end(), feature)); - feature->_group = nullptr; - return this; - } - - private: - std::vector features; + FeatureGroup* remove(Feature* feature); }; #ifndef CORRADE_GCC46_COMPATIBILITY @@ -151,6 +151,30 @@ template using FeatureGroup3D = FeatureGroup<3, Feature, T>; #endif +template FeatureGroup::~FeatureGroup() { + for(auto i: this->features) static_cast(i)->_group = nullptr; +} + +template FeatureGroup* FeatureGroup::add(Feature* feature) { + /* Remove from previous group */ + if(feature->_group) + feature->_group->remove(feature); + + /* Crossreference the feature and group together */ + AbstractFeatureGroup::add(feature); + feature->_group = this; + return this; +} + +template FeatureGroup* FeatureGroup::remove(Feature* feature) { + CORRADE_ASSERT(feature->_group == this, + "SceneGraph::AbstractFeatureGroup::remove(): feature is not part of this group", this); + + AbstractFeatureGroup::remove(feature); + feature->_group = nullptr; + return this; +} + }} #endif diff --git a/src/SceneGraph/FeatureGroup.hpp b/src/SceneGraph/FeatureGroup.hpp new file mode 100644 index 000000000..0f2cd1f1f --- /dev/null +++ b/src/SceneGraph/FeatureGroup.hpp @@ -0,0 +1,50 @@ +#ifndef Magnum_SceneGraph_FeatureGroup_hpp +#define Magnum_SceneGraph_FeatureGroup_hpp +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief @ref compilation-speedup-hpp "Template implementation" for FeatureGroup.h + */ + +#include "FeatureGroup.h" + +#include + +namespace Magnum { namespace SceneGraph { + +template AbstractFeatureGroup::AbstractFeatureGroup() = default; +template AbstractFeatureGroup::~AbstractFeatureGroup() = default; + +template void AbstractFeatureGroup::add(AbstractFeature* feature) { + features.push_back(feature); +} + +template void AbstractFeatureGroup::remove(AbstractFeature* feature) { + features.erase(std::find(features.begin(), features.end(), feature)); +} + +}} + +#endif diff --git a/src/SceneGraph/Object.cpp b/src/SceneGraph/Object.cpp index 0a4c679c8..1522bf42b 100644 --- a/src/SceneGraph/Object.cpp +++ b/src/SceneGraph/Object.cpp @@ -23,6 +23,7 @@ */ #include "Object.hpp" +#include "FeatureGroup.hpp" namespace Magnum { namespace SceneGraph { @@ -31,4 +32,7 @@ template class AbstractObject<3>; template class AbstractTransformation<2>; template class AbstractTransformation<3>; +template class AbstractFeatureGroup<2>; +template class AbstractFeatureGroup<3>; + }} diff --git a/src/SceneGraph/SceneGraph.h b/src/SceneGraph/SceneGraph.h index 8e3ccb63e..0d8263fb3 100644 --- a/src/SceneGraph/SceneGraph.h +++ b/src/SceneGraph/SceneGraph.h @@ -50,6 +50,12 @@ template using AbstractFeature2D = AbstractFeature<2, T>; template using AbstractFeature3D = AbstractFeature<3, T>; #endif +template class AbstractFeatureGroup; +#ifndef CORRADE_GCC46_COMPATIBILITY +template using AbstractFeatureGroup2D = AbstractFeatureGroup<2, T>; +template using AbstractFeatureGroup3D = AbstractFeatureGroup<3, T>; +#endif + template class AbstractGroupedFeature; #ifndef CORRADE_GCC46_COMPATIBILITY template using AbstractGroupedFeature2D = AbstractGroupedFeature<2, Derived, T>;