little insert optimization

This commit is contained in:
2019-09-01 13:01:47 +07:00
parent e3056de688
commit 60c476a291
2 changed files with 50 additions and 59 deletions

View File

@@ -105,6 +105,7 @@ namespace ecs_hpp
std::tuple<T, Ts...>&& t, std::tuple<T, Ts...>&& t,
std::index_sequence<Is...> iseq) std::index_sequence<Is...> iseq)
{ {
(void)t;
(void)iseq; (void)iseq;
return std::make_tuple(std::move(std::get<Is + 1u>(t))...); return std::make_tuple(std::move(std::get<Is + 1u>(t))...);
} }
@@ -114,6 +115,7 @@ namespace ecs_hpp
const std::tuple<T, Ts...>& t, const std::tuple<T, Ts...>& t,
std::index_sequence<Is...> iseq) std::index_sequence<Is...> iseq)
{ {
(void)t;
(void)iseq; (void)iseq;
return std::make_tuple(std::get<Is + 1u>(t)...); return std::make_tuple(std::get<Is + 1u>(t)...);
} }
@@ -312,14 +314,14 @@ namespace ecs_hpp
incremental_locker& operator=(const incremental_locker&) = delete; incremental_locker& operator=(const incremental_locker&) = delete;
static bool is_locked() noexcept { static bool is_locked() noexcept {
return lock_count_; return !!lock_count_;
} }
private: private:
static std::size_t lock_count_; static std::size_t lock_count_;
}; };
template < typename Tag > template < typename Tag >
std::size_t incremental_locker<Tag>::lock_count_{0u}; std::size_t incremental_locker<Tag>::lock_count_ = 0u;
} }
} }
@@ -402,11 +404,6 @@ namespace ecs_hpp
return true; return true;
} }
template < typename... Args >
bool emplace(Args&&... args) {
return insert(T(std::forward<Args>(args)...));
}
bool unordered_erase(const T& v) noexcept { bool unordered_erase(const T& v) noexcept {
if ( !has(v) ) { if ( !has(v) ) {
return false; return false;
@@ -543,27 +540,14 @@ namespace ecs_hpp
} }
template < typename UK, typename UT > template < typename UK, typename UT >
bool insert(UK&& k, UT&& v) { std::pair<T*, bool> insert(UK&& k, UT&& v) {
if ( keys_.has(k) ) { if ( T* value = find(k) ) {
return false; return std::make_pair(value, false);
} }
values_.push_back(std::forward<UT>(v)); values_.push_back(std::forward<UT>(v));
try { try {
return keys_.insert(std::forward<UK>(k)); keys_.insert(std::forward<UK>(k));
} catch (...) { return std::make_pair(&values_.back(), true);
values_.pop_back();
throw;
}
}
template < typename UK, typename... Args >
bool emplace(UK&& k, Args&&... args) {
if ( keys_.has(k) ) {
return false;
}
values_.emplace_back(std::forward<Args>(args)...);
try {
return keys_.insert(std::forward<UK>(k));
} catch (...) { } catch (...) {
values_.pop_back(); values_.pop_back();
throw; throw;
@@ -571,13 +555,18 @@ namespace ecs_hpp
} }
template < typename UK, typename UT > template < typename UK, typename UT >
bool insert_or_assign(UK&& k, UT&& v) { std::pair<T*, bool> insert_or_assign(UK&& k, UT&& v) {
if ( keys_.has(k) ) { if ( T* value = find(k) ) {
get(k) = std::forward<UT>(v); *value = std::forward<UT>(v);
return false; return std::make_pair(value, false);
} else { }
insert(std::forward<UK>(k), std::forward<UT>(v)); values_.push_back(std::forward<UT>(v));
return true; try {
keys_.insert(std::forward<UK>(k));
return std::make_pair(&values_.back(), true);
} catch (...) {
values_.pop_back();
throw;
} }
} }
@@ -699,22 +688,21 @@ namespace ecs_hpp
template < typename... Args > template < typename... Args >
T& assign(entity_id id, Args&&... args) { T& assign(entity_id id, Args&&... args) {
if ( components_.has(id) ) { if ( T* value = components_.find(id) ) {
return components_.get(id) = T(std::forward<Args>(args)...); *value = T(std::forward<Args>(args)...);
return *value;
} }
assert(!components_locker::is_locked()); assert(!components_locker::is_locked());
components_.emplace(id, std::forward<Args>(args)...); return *components_.insert(id, T(std::forward<Args>(args)...)).first;
return components_.get(id);
} }
template < typename... Args > template < typename... Args >
T& ensure(entity_id id, Args&&... args) { T& ensure(entity_id id, Args&&... args) {
if ( components_.has(id) ) { if ( T* value = components_.find(id) ) {
return components_.get(id); return *value;
} }
assert(!components_locker::is_locked()); assert(!components_locker::is_locked());
components_.emplace(id, std::forward<Args>(args)...); return *components_.insert(id, T(std::forward<Args>(args)...)).first;
return components_.get(id);
} }
bool exists(entity_id id) const noexcept { bool exists(entity_id id) const noexcept {
@@ -793,7 +781,7 @@ namespace ecs_hpp
return empty_value_; return empty_value_;
} }
assert(!components_locker::is_locked()); assert(!components_locker::is_locked());
components_.emplace(id); components_.insert(id);
return empty_value_; return empty_value_;
} }
@@ -803,7 +791,7 @@ namespace ecs_hpp
return empty_value_; return empty_value_;
} }
assert(!components_locker::is_locked()); assert(!components_locker::is_locked());
components_.emplace(id); components_.insert(id);
return empty_value_; return empty_value_;
} }
@@ -2358,24 +2346,28 @@ namespace ecs_hpp
template < typename... Ts > template < typename... Ts >
std::tuple<Ts&...> registry::get_components(const uentity& ent) { std::tuple<Ts&...> registry::get_components(const uentity& ent) {
(void)ent;
assert(valid_entity(ent)); assert(valid_entity(ent));
return std::make_tuple(std::ref(get_component<Ts>(ent))...); return std::make_tuple(std::ref(get_component<Ts>(ent))...);
} }
template < typename... Ts > template < typename... Ts >
std::tuple<const Ts&...> registry::get_components(const const_uentity& ent) const { std::tuple<const Ts&...> registry::get_components(const const_uentity& ent) const {
(void)ent;
assert(valid_entity(ent)); assert(valid_entity(ent));
return std::make_tuple(std::cref(get_component<Ts>(ent))...); return std::make_tuple(std::cref(get_component<Ts>(ent))...);
} }
template < typename... Ts > template < typename... Ts >
std::tuple<Ts*...> registry::find_components(const uentity& ent) noexcept { std::tuple<Ts*...> registry::find_components(const uentity& ent) noexcept {
(void)ent;
assert(valid_entity(ent)); assert(valid_entity(ent));
return std::make_tuple(find_component<Ts>(ent)...); return std::make_tuple(find_component<Ts>(ent)...);
} }
template < typename... Ts > template < typename... Ts >
std::tuple<const Ts*...> registry::find_components(const const_uentity& ent) const noexcept { std::tuple<const Ts*...> registry::find_components(const const_uentity& ent) const noexcept {
(void)ent;
assert(valid_entity(ent)); assert(valid_entity(ent));
return std::make_tuple(find_component<Ts>(ent)...); return std::make_tuple(find_component<Ts>(ent)...);
} }
@@ -2460,10 +2452,9 @@ namespace ecs_hpp
[](priority_t pr, const auto& r){ [](priority_t pr, const auto& r){
return pr < r.first; return pr < r.first;
}); });
systems_.emplace( systems_.insert(
iter, iter,
priority, std::make_pair(priority, std::make_unique<T>(std::forward<Args>(args)...)));
std::make_unique<T>(std::forward<Args>(args)...));
} }
inline void registry::process_all_systems() { inline void registry::process_all_systems() {
@@ -2540,7 +2531,7 @@ namespace ecs_hpp
return *storage; return *storage;
} }
const auto family = detail::type_family<T>::id(); const auto family = detail::type_family<T>::id();
storages_.emplace( storages_.insert(
family, family,
std::make_unique<detail::component_storage<T>>(*this)); std::make_unique<detail::component_storage<T>>(*this));
return *static_cast<detail::component_storage<T>*>( return *static_cast<detail::component_storage<T>*>(

View File

@@ -177,7 +177,7 @@ TEST_CASE("detail") {
REQUIRE(s.insert(position_c(1,2))); REQUIRE(s.insert(position_c(1,2)));
REQUIRE_FALSE(s.insert(position_c(1,2))); REQUIRE_FALSE(s.insert(position_c(1,2)));
REQUIRE(s.has(position_c(1,2))); REQUIRE(s.has(position_c(1,2)));
REQUIRE(s.emplace(3,4)); REQUIRE(s.insert(position_c(3,4)));
REQUIRE(s.has(position_c(3,4))); REQUIRE(s.has(position_c(3,4)));
REQUIRE(s.get_dense_index(position_c(1,2)) == 0); REQUIRE(s.get_dense_index(position_c(1,2)) == 0);
REQUIRE(s.get_dense_index(position_c(3,4)) == 1); REQUIRE(s.get_dense_index(position_c(3,4)) == 1);
@@ -209,16 +209,16 @@ TEST_CASE("detail") {
{ {
obj_t o{21u}; obj_t o{21u};
REQUIRE(m.insert(21u, o)); REQUIRE(m.insert(21u, o).second);
REQUIRE(m.insert(42u, obj_t{42u})); REQUIRE(m.insert(42u, obj_t{42u}).second);
REQUIRE(m.emplace(84u, 84u)); REQUIRE(m.insert(84u, obj_t(84u)).second);
} }
{ {
obj_t o{21u}; obj_t o{21u};
REQUIRE_FALSE(m.insert(21u, o)); REQUIRE_FALSE(m.insert(21u, o).second);
REQUIRE_FALSE(m.insert(42u, obj_t{42u})); REQUIRE_FALSE(m.insert(42u, obj_t{42u}).second);
REQUIRE_FALSE(m.emplace(84u, 84u)); REQUIRE_FALSE(m.insert(84u, obj_t(84u)).second);
} }
REQUIRE_FALSE(m.empty()); REQUIRE_FALSE(m.empty());
@@ -270,10 +270,10 @@ TEST_CASE("detail") {
}; };
sparse_map<position_c, obj_t, position_c_indexer> s{position_c_indexer()}; sparse_map<position_c, obj_t, position_c_indexer> s{position_c_indexer()};
REQUIRE(s.insert(position_c(1,2), obj_t{1})); REQUIRE(s.insert(position_c(1,2), obj_t{1}).second);
REQUIRE_FALSE(s.insert(position_c(1,2), obj_t{1})); REQUIRE_FALSE(s.insert(position_c(1,2), obj_t{1}).second);
REQUIRE(s.has(position_c(1,2))); REQUIRE(s.has(position_c(1,2)));
REQUIRE(s.emplace(position_c(3,4), obj_t{3})); REQUIRE(s.insert(position_c(3,4), obj_t{3}).second);
REQUIRE(s.has(position_c(3,4))); REQUIRE(s.has(position_c(3,4)));
REQUIRE(s.get(position_c(1,2)).x == 1); REQUIRE(s.get(position_c(1,2)).x == 1);
REQUIRE(s.get(position_c(3,4)).x == 3); REQUIRE(s.get(position_c(3,4)).x == 3);
@@ -291,14 +291,14 @@ TEST_CASE("detail") {
}; };
sparse_map<unsigned, obj_t> m; sparse_map<unsigned, obj_t> m;
REQUIRE(m.insert_or_assign(42, obj_t(42))); REQUIRE(m.insert_or_assign(42, obj_t(42)).second);
REQUIRE(m.has(42)); REQUIRE(m.has(42));
REQUIRE(m.get(42).x == 42); REQUIRE(m.get(42).x == 42);
REQUIRE_FALSE(m.insert_or_assign(42, obj_t(21))); REQUIRE_FALSE(m.insert_or_assign(42, obj_t(21)).second);
REQUIRE(m.has(42)); REQUIRE(m.has(42));
REQUIRE(m.get(42).x == 21); REQUIRE(m.get(42).x == 21);
REQUIRE(m.size() == 1); REQUIRE(m.size() == 1);
REQUIRE(m.insert_or_assign(84, obj_t(84))); REQUIRE(m.insert_or_assign(84, obj_t(84)).second);
REQUIRE(m.has(84)); REQUIRE(m.has(84));
REQUIRE(m.get(84).x == 84); REQUIRE(m.get(84).x == 84);
REQUIRE(m.size() == 2); REQUIRE(m.size() == 2);