registry: added ::patch, reintroduced ::replace from arguments (close #437)
This commit is contained in:
@@ -228,11 +228,15 @@ This function is overloaded and accepts also a couple of iterators in order to:
|
||||
registry.assign<position>(first, last, instances);
|
||||
```
|
||||
|
||||
If an entity already has the given component, the `replace` member function
|
||||
template can be used to edit it in-place:
|
||||
If an entity already has the given component, the `replace` and `patch` member
|
||||
function templates can be used to updated it:
|
||||
|
||||
```cpp
|
||||
registry.replace<position>(entity, [](auto &pos) { pos.x = pos.y = 0.; });
|
||||
// replaces the component in-place
|
||||
registry.patch<position>(entity, [](auto &pos) { pos.x = pos.y = 0.; });
|
||||
|
||||
// constructs a new instance from a list of arguments and replaces the component
|
||||
registry.replace<position>(entity, 0., 0.);
|
||||
```
|
||||
|
||||
When it's unknown whether an entity already owns an instance of a component,
|
||||
|
||||
@@ -693,7 +693,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Replaces the given component for an entity.
|
||||
* @brief Replaces the given component for an entity in-place.
|
||||
*
|
||||
* The signature of the functions should be equivalent to the following:
|
||||
*
|
||||
@@ -718,11 +718,48 @@ public:
|
||||
* @return A reference to the replaced component.
|
||||
*/
|
||||
template<typename Component, typename... Func>
|
||||
decltype(auto) replace(const entity_type entity, Func &&... func) {
|
||||
[[deprecated("use registry::patch instead")]]
|
||||
decltype(auto) patch(const entity_type entity, Func &&... func) {
|
||||
ENTT_ASSERT(valid(entity));
|
||||
return assure<Component>().replace(*this, entity, std::forward<Func>(func)...);
|
||||
}
|
||||
|
||||
/*! @copydoc patch */
|
||||
template<typename Component, typename... Func>
|
||||
[[deprecated("use registry::patch instead")]]
|
||||
auto replace(const entity_type entity, Func &&... func)
|
||||
-> decltype((func(assure<Component>().get(entity)), ...), assure<Component>().get(entity)) {
|
||||
return patch<Component>(entity, std::forward<Func>(func)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Replaces the given component for an entity.
|
||||
*
|
||||
* A new instance of the given component is created and initialized with the
|
||||
* arguments provided (the component must have a proper constructor or be of
|
||||
* aggregate type). Then the component is assigned to the given entity.
|
||||
*
|
||||
* @warning
|
||||
* Attempting to use an invalid entity or to replace a component of an
|
||||
* entity that doesn't own it results in undefined behavior.<br/>
|
||||
* An assertion will abort the execution at runtime in debug mode in case of
|
||||
* invalid entity or if the entity doesn't own an instance of the given
|
||||
* component.
|
||||
*
|
||||
* @tparam Component Type of component to replace.
|
||||
* @tparam Args Types of arguments to use to construct the component.
|
||||
* @param entity A valid entity identifier.
|
||||
* @param args Parameters to use to initialize the component.
|
||||
* @return A reference to the component being replaced.
|
||||
*/
|
||||
template<typename Component, typename... Args>
|
||||
auto replace(const entity_type entity, Args &&... args)
|
||||
-> decltype(std::enable_if_t<sizeof...(Args) != 0>(), Component{std::forward<Args>(args)...}, assure<Component>().get(entity)) {
|
||||
return patch<Component>(entity, [args = std::forward_as_tuple(std::forward<Args>(args)...)](auto &&component) {
|
||||
component = std::make_from_tuple<Component>(std::move(args));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes the given components from an entity.
|
||||
*
|
||||
|
||||
@@ -181,7 +181,8 @@ TEST(Registry, Functionalities) {
|
||||
ASSERT_NE(®istry.get<int>(e0), ®istry.get<int>(e2));
|
||||
ASSERT_NE(®istry.get<char>(e0), ®istry.get<char>(e2));
|
||||
|
||||
ASSERT_EQ(registry.replace<int>(e0, [](auto &instance) { instance = 3; }), 3);
|
||||
ASSERT_EQ(registry.replace<int>(e0, [](auto &instance) { instance = 2; }), 2);
|
||||
ASSERT_EQ(registry.replace<int>(e0, 3), 3);
|
||||
|
||||
ASSERT_NO_THROW(registry.assign_or_replace<int>(e0, 1));
|
||||
ASSERT_NO_THROW(registry.assign_or_replace<int>(e1, 1));
|
||||
|
||||
Reference in New Issue
Block a user