added entt::label

This commit is contained in:
Michele Caini
2018-07-07 13:40:20 +02:00
parent d5b3933752
commit 0e68bb3d2c
5 changed files with 75 additions and 5 deletions

View File

@@ -29,6 +29,7 @@
* [Prototype](#prototype)
* [Helpers](#helpers)
* [Dependency function](#dependency-function)
* [Labels](#labels)
* [Null entity](#null-entity)
* [View: to persist or not to persist?](#view-to-persist-or-not-to-persist)
* [Standard View](#standard-view)
@@ -1154,6 +1155,20 @@ A dependency can easily be broken by means of the same function template:
entt::dependency<AType, AnotherType>(entt::break_t{}, registry.construction<MyType>());
```
#### Labels
There's nothing magical about the way labels can be assigned to entities while
avoiding a performance hit at runtime. Nonetheless, the syntax can be annoying
and that's why a more user-friendly shortcut is provided to do it.<br/>
This shortcut is the alias template `entt::label`.
If used in combination with hashed strings, it helps to use labels where types
would be required otherwise. As an example:
```cpp
registry.assign<entt::label<"enemy"_hs>>(entity);
```
### Null entity
In `EnTT`, there exists a sort of _null entity_ made available to users that is
@@ -1784,6 +1799,13 @@ auto load(entt::HashedString::hash_type resource) {
auto resource = load(entt::HashedString{"gui/background"});
```
There is also a _user defined literal_ dedicated to hashed strings to make them
more user-friendly:
```cpp
constexpr auto str = "text"_hs;
```
### Conflicts
The hashed string class uses internally FNV-1a to compute the numeric

4
TODO
View File

@@ -4,11 +4,7 @@
* debugging tools (#60): the issue online already contains interesting tips on this, look at it
* define basic reactive systems (track entities to which component is attached, track entities from which component is removed, and so on)
* define systems as composable mixins (initializazion, reactive, update, whatever) with flexible auto-detected arguments (registry, views, etc)
* add to the prototype the possibility to submit components during creation to use to initialize the ones created by the prototype itself
* create dedicated flat map based on types implementation (sort of "type map") for types to use within the registry and so on...
* ease the assignment of tags as string (type-less assign member function + user defined literal for hashed strings)
* move signals within sparse set and attacchee if possible, it would be less error-prone
* family -> std::uint32_t (or some other fixed and known size type)
* work stealing job system (see #100)
* C++17. That's all.
* AOB

View File

@@ -108,6 +108,11 @@ constexpr bool operator!=(const HashedString &lhs, const HashedString &rhs) ENTT
}
/**
* @brief User defined literal for hashed strings.
* @param str The literal without its suffix.
* @return A properly initialized hashed string.
*/
constexpr entt::HashedString operator"" ENTT_HS_SUFFIX(const char *str, std::size_t) ENTT_NOEXCEPT {
return entt::HashedString{str};
}

View File

@@ -2,6 +2,8 @@
#define ENTT_ENTITY_HELPER_HPP
#include <type_traits>
#include "../core/hashed_string.hpp"
#include "../signal/sigh.hpp"
#include "registry.hpp"
#include "utility.hpp"
@@ -78,6 +80,25 @@ void dependency(break_t, Sink<void(Registry<Entity> &, const Entity)> sink) {
}
/**
* @brief Alias template to ease the assignment of labels to entities.
*
* If used in combination with hashed strings, it simplifies the assignment of
* labels to entities and the use of labels in general where a type would be
* required otherwise.<br/>
* As an example and where the user defined literal for hashed strings hasn't
* been changed:
* @code{.cpp}
* entt::DefaultRegistry registry;
* registry.assign<entt::label<"enemy"_hs>>(entity);
* @endcode
*
* @tparam Value The numeric representation of an instance of hashed string.
*/
template<typename HashedString::hash_type Value>
using label = std::integral_constant<typename HashedString::hash_type, Value>;
}

View File

@@ -1,8 +1,9 @@
#include <gtest/gtest.h>
#include <entt/core/hashed_string.hpp>
#include <entt/entity/helper.hpp>
#include <entt/entity/registry.hpp>
TEST(Dependency, Functionalities) {
TEST(Helper, Dependency) {
entt::DefaultRegistry registry;
const auto entity = registry.create();
entt::dependency<double, float>(registry.construction<int>());
@@ -47,3 +48,28 @@ TEST(Dependency, Functionalities) {
ASSERT_FALSE(registry.has<double>(entity));
ASSERT_FALSE(registry.has<float>(entity));
}
TEST(Helper, Label) {
entt::DefaultRegistry registry;
const auto entity = registry.create();
registry.assign<entt::label<"foobar"_hs>>(entity);
registry.assign<int>(entity, 42);
int counter{};
ASSERT_FALSE(registry.has<entt::label<"barfoo"_hs>>(entity));
ASSERT_TRUE(registry.has<entt::label<"foobar"_hs>>(entity));
for(auto entity: registry.view<int, entt::label<"foobar"_hs>>()) {
(void)entity;
++counter;
}
ASSERT_NE(counter, 0);
for(auto entity: registry.view<entt::label<"foobar"_hs>>()) {
(void)entity;
--counter;
}
ASSERT_EQ(counter, 0);
}