Property list (#338)

* Fix typo in comment
* Implemented a function for adding a list of properties to meta-item
This commit is contained in:
Innokentiy Alaytsev
2019-10-19 16:59:05 +04:00
committed by Michele Caini
parent ecaa9c275c
commit bfa46b795f
4 changed files with 56 additions and 5 deletions

View File

@@ -20,6 +20,7 @@ gale83
ghost
grdowns
Green-Sky
Innokentiy-Alaytsev
Kerndog73
Lawrencemm
mhammerc

View File

@@ -522,6 +522,11 @@ entt::meta<my_type>()
.prop(my_enum::a_value, 42);
```
Alternatively, the `props` function is available to associate several properties
at a time. However, in this case properties in the key/value form aren't
allowed, since they would be interpreted as two different properties rather than
a single one.
The meta objects for which properties are supported are currently the meta
types, meta constructors, meta data and meta functions. It's not possible to
attach properties to other types of meta objects and the factory returned as a

View File

@@ -703,8 +703,8 @@ class extended_meta_factory: public meta_factory<Type> {
}
template<typename Key, typename... Value>
void unpack(char, Key &&pkey, Value &&... pvalue) {
static auto property{std::make_tuple(std::forward<Key>(pkey), std::forward<Value>(pvalue)...)};
void unpack(char, Key &&key, Value &&... value) {
static auto property{std::make_tuple(std::forward<Key>(key), std::forward<Value>(value)...)};
static internal::meta_prop_node node{
*curr,
@@ -730,7 +730,7 @@ class extended_meta_factory: public meta_factory<Type> {
public:
/**
* @brief Assigns properties to the last meta object created.
* @brief Assigns a property to the last meta object created.
*
* Both the key and the value (if any) must be at least copy constructible.
*
@@ -747,6 +747,22 @@ public:
return *this;
}
/**
* @brief Assigns properties to the last meta object created.
*
* Both the keys and the values (if any) must be at least copy
* constructible.
*
* @tparam Property Types of the properties.
* @param property Properties to assign to the last meta object created.
* @return A meta factory for the parent type.
*/
template <typename... Property>
auto props(Property... property) {
(unpack(0, property), ...);
return *this;
}
private:
entt::internal::meta_prop_node **curr{nullptr};
};

View File

@@ -20,7 +20,8 @@ Type get(Type &prop) {
enum class properties {
prop_int,
prop_bool,
key_only
key_only,
prop_list
};
struct empty_type {
@@ -160,7 +161,9 @@ struct Meta: ::testing::Test {
.prop(properties::key_only)
.data<properties::key_only>("key_only"_hs)
.prop(properties::key_only)
.data<&set<properties>, &get<properties>>("value"_hs);
.data<&set<properties>, &get<properties>>("value"_hs)
.data<properties::prop_list>("prop_list"_hs)
.props(std::pair{properties::prop_bool, true}, std::pair{properties::prop_int, 0}, properties::key_only);
entt::meta<unsigned int>().data<0u>("min"_hs).data<100u>("max"_hs);
@@ -2028,6 +2031,32 @@ TEST_F(Meta, KeyOnlyProperties) {
ASSERT_FALSE(prop.value());
}
TEST_F(Meta, PropertyList) {
const auto type = entt::resolve<properties>();
const auto prop_list = type.data("prop_list"_hs);
const auto prop_bool = prop_list.prop(properties::prop_bool);
const auto prop_int = prop_list.prop(properties::prop_int);
const auto key_prop = prop_list.prop(properties::key_only);
ASSERT_TRUE(prop_bool);
ASSERT_EQ(prop_bool.key().type(), entt::resolve<properties>());
ASSERT_EQ(prop_bool.key().cast<properties>(), properties::prop_bool);
ASSERT_TRUE(prop_bool.value());
ASSERT_TRUE(prop_bool.value().try_cast<bool>());
ASSERT_TRUE(prop_int);
ASSERT_EQ(prop_int.key().type(), entt::resolve<properties>());
ASSERT_EQ(prop_int.key().cast<properties>(), properties::prop_int);
ASSERT_TRUE(prop_int.value());
ASSERT_TRUE(prop_int.value().try_cast<int>());
ASSERT_TRUE(key_prop);
ASSERT_TRUE(key_prop.key());
ASSERT_EQ(key_prop.key().type(), entt::resolve<properties>());
ASSERT_EQ(key_prop.key().cast<properties>(), properties::key_only);
ASSERT_FALSE(key_prop.value());
}
TEST_F(Meta, Reset) {
ASSERT_NE(*entt::internal::meta_info<>::global, nullptr);
ASSERT_NE(entt::internal::meta_info<>::local, nullptr);