Visual Computing Library  devel
Loading...
Searching...
No Matches
component.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_MESH_COMPONENTS_BASE_COMPONENT_H
24#define VCL_MESH_COMPONENTS_BASE_COMPONENT_H
25
26#include "base.h"
27
28#include "../concepts/component.h"
29#include "../detail/component_data.h"
30
31namespace vcl::comp {
32
34
116template<
117 typename DerivedComponent, // CRTP pattern, derived class
118 uint COMP_ID, // component id
119 typename DataType, // data stored by the component
120 typename ParentElemType, // parent element type
121 bool VERT, // true if component vertical
122 bool OPT, // true if component vertical and optional
123 typename... ReferencedTypes> // types of the refs stored by the component
124class Component : public ReferencesComponentTriggerer<ReferencedTypes>...
125{
126public:
131 using DataValueType = DataType;
132
137 static const bool IS_VERTICAL =
138 !std::is_same_v<ParentElemType, void> && VERT;
139
143 static const uint COMPONENT_ID = COMP_ID;
144
149 static const bool IS_OPTIONAL = VERT && OPT;
150
151private:
152 detail::ComponentData<DataValueType, IS_VERTICAL> mData;
153
154public:
166 bool isAvailable() const
167 {
168 return mData.template isComponentAvailable<ParentElemType>(
169 static_cast<const DerivedComponent*>(this));
170 }
171
172protected:
173 DataValueType& data()
174 {
175 return mData.template get<ParentElemType>(
176 static_cast<DerivedComponent*>(this));
177 }
178
179 const DataValueType& data() const
180 {
181 return mData.template get<ParentElemType>(
182 static_cast<const DerivedComponent*>(this));
183 }
184
185 ParentElemType* parentElement()
186 {
187 static_assert(
188 !std::is_same_v<ParentElemType, void>,
189 "The component should know its parent element type to get access "
190 "to its pointer. You should define the component by passing the "
191 "element type as template parameter. E.G., for a Face element:\n"
192 "vcl::face::TriangleVertexPtrs<Vertex<Scalar>, Face<Scalar>>\n"
193 " ^^^^^^^^^^^^ \n");
194
195 return static_cast<ParentElemType*>(this);
196 }
197
198 const ParentElemType* parentElement() const
199 {
200 static_assert(
201 !std::is_same_v<ParentElemType, void>,
202 "The component should know its parent element type to get access "
203 "to its pointer. You should define the component by passing the "
204 "element type as template parameter. E.G., for a Face element:\n"
205 "vcl::face::TriangleVertexPtrs<Vertex<Scalar>, Face<Scalar>>\n"
206 " ^^^^^^^^^^^^ \n");
207
208 return static_cast<const ParentElemType*>(this);
209 }
210};
211
224template<uint COMPONENT_ID, typename T>
225bool isComponentAvailableOn(const T& obj)
226{
227 if constexpr (HasOptionalComponentOfType<T, COMPONENT_ID>) {
228 using ComponentType =
229 ComponentOfType<COMPONENT_ID, typename T::Components>;
230 const ComponentType& c = static_cast<const ComponentType&>(obj);
231 return c.isAvailable();
232 }
233 else
234 return HasComponentOfType<T, COMPONENT_ID>;
235}
236
243template<typename T>
244struct IsComponentPred
245{
246 static const bool value = ComponentConcept<T>;
247};
248
249template<typename T>
250struct IsVerticalComponentPred
251{
252 static const bool value = IsVerticalComponent<T>;
253};
254
256
257} // namespace vcl::comp
258
259#endif // VCL_MESH_COMPONENTS_BASE_COMPONENT_H