-
Notifications
You must be signed in to change notification settings - Fork 284
/
Copy pathBaseView.hh
219 lines (192 loc) · 9.49 KB
/
BaseView.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/*
* Copyright (C) 2021 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef IGNITION_GAZEBO_DETAIL_BASEVIEW_HH_
#define IGNITION_GAZEBO_DETAIL_BASEVIEW_HH_
#include <cstddef>
#include <set>
#include <unordered_map>
#include <vector>
#include "ignition/gazebo/Entity.hh"
#include "ignition/gazebo/Types.hh"
#include "ignition/gazebo/config.hh"
namespace ignition
{
namespace gazebo
{
// Inline bracket to help doxygen filtering.
inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
namespace detail
{
/// \brief A key into the map of views
using ComponentTypeKey = std::vector<ComponentTypeId>;
/// \brief Hash functor for ComponentTypeKey.
/// The implementation was inspired by:
/// * https://stackoverflow.com/a/20511429
/// * https://stackoverflow.com/a/4948967
/// * https://stackoverflow.com/a/35991300
/// * https://softwareengineering.stackexchange.com/a/402543
struct ComponentTypeHasher
{
std::size_t operator()(const std::vector<ComponentTypeId> &_vec) const
{
auto hash = _vec.size();
for (const auto &i : _vec)
hash ^= i + 0x9e3779b9 + (hash << 6) + (hash >> 2);
return hash;
}
};
/// \brief A view is a cache to entities, and their components, that
/// match a set of component types. A cache is used because systems will
/// frequently, potentially every iteration, query the
/// EntityComponentManager for sets of entities that match a set of
/// component types. Rather than look up the entities every time, we can
/// use a cache to improve performance.
///
/// Note that symbols for this class are visible because methods from this class
/// are used in templated Ignition::Gazebo::EntityComponentManager methods.
/// However, users should not use this class (or anything else in namespace
/// ignition::gazebo::detail) directly.
class IGNITION_GAZEBO_VISIBLE BaseView
{
/// \brief Destructor
public: virtual ~BaseView() = default;
/// \brief See if an entity is a part of the view
/// \param[in] _entity The entity
/// \return true if _entity is a part of the view, false otherwise
public: bool HasEntity(const Entity _entity) const;
/// \brief See if an entity is marked as an entity to be added to the view
/// \param[in] _entity The entity
/// \return true if _entity is to be added to the view, false otherwise
public: bool IsEntityMarkedForAddition(const Entity _entity) const;
/// \brief See if the view has cached the component data for an entity
/// \param[in] _entity The entity
/// \return true if _entity has component data cached in the view, false
/// otherwise
public: virtual bool HasCachedComponentData(const Entity _entity) const = 0;
/// \brief Save an entity as one to be added to the view, if the entity isn't
/// already a part of the view. This entity's component data should be added
/// to the view the next time the view is being used.
/// \param[in] _entity The entity to be added
/// \param[in] _new Whether to add the entity to the list of new entities.
/// The new here is to indicate whether the entity is new to the entity
/// component manager. An existing entity can be added when creating a new
/// view or when rebuilding the view.
/// \return True if _entity isn't already a part of the view and was marked as
/// an entity to be added. False otherwise
/// \sa HasEntity, IsEntityMarkedForAddition
public: bool MarkEntityToAdd(const Entity _entity, bool _new = false);
/// \brief See if the view requires a particular component type
/// \param[in] _typeId The component type
/// \return true if the view requires components of type _typeId, false
/// otherwise
public: bool RequiresComponent(const ComponentTypeId _typeId) const;
/// \brief Update the internal data in the view because a component has been
/// added to an entity. It is assumed that the entity is already associated
/// with the view, and that the added component type is required by the view.
/// \param[in] _entity The entity
/// \param[in] _newEntity Whether to add the entity to the list of new
/// entities. The new here is to indicate whether the entity is new to the
/// entity component manager.
/// \param[in] _typeId The type of component that was added to _entity
/// \return true if the notification related to the component addition of type
/// _typeId occurred for _entity, false otherwise
/// \sa HasCachedComponentData, RequiresComponent
public: virtual bool NotifyComponentAddition(const Entity _entity,
bool _newEntity, const ComponentTypeId _typeId) = 0;
/// \brief Update the internal data in the view because a component has been
/// removed to an entity. It is assumed that the entity is already associated
/// with the view, and that the removed component type is required by the view
/// \param[in] _entity The entity
/// \param[in] _typeId The type of component that was removed from _entity
/// \return true if the notification related to the component removal of type
/// _typeId occurred for _entity, false otherwise
/// \sa HasCachedComponentData, RequiresComponent
public: virtual bool NotifyComponentRemoval(const Entity _entity,
const ComponentTypeId _typeId) = 0;
/// \brief Remove an entity from the view.
/// \param[in] _entity The entity to remove.
/// \return True if the entity was removed, false if the entity did not
/// exist in the view.
public: virtual bool RemoveEntity(const Entity _entity) = 0;
/// \brief Add the entity to the list of entities to be removed
/// \param[in] _entity The entity to add.
/// \return True if the entity was added to the list, false if the entity
/// was not associated with the view.
public: bool MarkEntityToRemove(const Entity _entity);
/// \brief Update the entities in the view to no longer appear as newly
/// created. This method should be called whenever a new simulation step is
/// about to take place.
public: void ResetNewEntityState();
/// \brief Get the set of component types that this view requires.
/// \return The set of component types.
public: const std::set<ComponentTypeId> &ComponentTypes() const;
/// \brief Clear all data from the view and reset it to its original, empty
/// state.
public: virtual void Reset() = 0;
/// \brief Get all of the entities in the view
/// \return The entities in the view
public: const std::set<Entity> &Entities() const;
/// \brief Get all of the entities in the view that are considered "newly
/// created". While an entity may be new to the view, it may not be a newly
/// created entity (perhaps this entity has existed for some time, and just
/// had a component added to it that now makes this entity a part of the
/// view). An entity's "newness" is determined by the entity component
/// manager.
/// \return The newly created entities that are a part of the view
public: const std::set<Entity> &NewEntities() const;
/// \brief Get all of the entities to be removed from the view
/// \return The entities to be removed from the view
public: const std::set<Entity> &ToRemoveEntities() const;
/// \brief Get all of the entities that should be added to the view. This is
/// useful for adding entities to the view before the view is used to ensure
/// that the view is up-to-date. Once all entities marked "to be added" are
/// added to the view, the ClearToAddEntities method should be called.
/// \return The entities to be added to the view, with the key of the map
/// indicating whether an entity is a newly created entity or not.
/// \sa ClearToAddEntities
public: const std::unordered_map<Entity, bool> &ToAddEntities() const;
/// \brief Clear all of the entities that are marked as to be added to the
/// view. This should be called after all of the entities marked as to be
/// added to the view are actually added to the view.
/// \sa ToAddEntities
public: void ClearToAddEntities();
// TODO(adlarkin) make this a std::unordered_set for better performance.
// We need to make sure nothing else depends on the ordered preserved by
// std::set first
/// \brief All the entities that belong to this view.
protected: std::set<Entity> entities;
// TODO(adlarkin) make this a std::unordered_set for better performance.
// We need to make sure nothing else depends on the ordered preserved by
// std::set first
/// \brief List of newly created entities
protected: std::set<Entity> newEntities;
// TODO(adlarkin) make this a std::unordered_set for better performance.
// We need to make sure nothing else depends on the ordered preserved by
// std::set first
/// \brief List of entities about to be removed
protected: std::set<Entity> toRemoveEntities;
/// \brief List of entities to be added to the view. The value of the map
/// indicates whether the entity is new to the entity component manager or not
protected: std::unordered_map<Entity, bool> toAddEntities;
/// \brief The component types in the view
protected: std::set<ComponentTypeId> componentTypes;
};
} // namespace detail
} // namespace IGNITION_GAZEBO_VERSION_NAMESPACE
} // namespace gazebo
} // namespace ignition
#endif