Support more generic index factories in ecs container
This commit is contained in:
parent
c7b1bc0b0a
commit
fa214ed956
2 changed files with 32 additions and 8 deletions
|
|
@ -364,6 +364,9 @@ namespace psemek::ecs
|
||||||
template <typename Index, typename ... Args>
|
template <typename Index, typename ... Args>
|
||||||
Index & index(Args && ... args);
|
Index & index(Args && ... args);
|
||||||
|
|
||||||
|
template <typename Index, typename Factory>
|
||||||
|
Index & index_factory(Factory && factory);
|
||||||
|
|
||||||
template <typename ... Components>
|
template <typename ... Components>
|
||||||
std::size_t memory_usage();
|
std::size_t memory_usage();
|
||||||
|
|
||||||
|
|
@ -767,6 +770,12 @@ namespace psemek::ecs
|
||||||
return index_container_.get<Index>(*this, std::forward<Args>(args)...);
|
return index_container_.get<Index>(*this, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Index, typename Factory>
|
||||||
|
Index & container::index_factory(Factory && factory)
|
||||||
|
{
|
||||||
|
return index_container_.set<Index>(std::move(factory));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ... Components>
|
template <typename ... Components>
|
||||||
std::size_t container::memory_usage()
|
std::size_t container::memory_usage()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <psemek/util/hash_table.hpp>
|
#include <psemek/util/hash_table.hpp>
|
||||||
#include <psemek/util/type_name.hpp>
|
#include <psemek/util/type_name.hpp>
|
||||||
#include <psemek/util/exception.hpp>
|
#include <psemek/util/exception.hpp>
|
||||||
|
#include <psemek/util/function.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -24,19 +25,21 @@ namespace psemek::ecs::detail
|
||||||
{
|
{
|
||||||
auto uuid = Index::uuid();
|
auto uuid = Index::uuid();
|
||||||
if (auto it = storage_.find(uuid); it != storage_.end())
|
if (auto it = storage_.find(uuid); it != storage_.end())
|
||||||
return *reinterpret_cast<Index *>(it->second.get());
|
return *reinterpret_cast<Index *>(it->second());
|
||||||
|
|
||||||
if constexpr (std::is_constructible_v<Index, ecs::container &, Args && ...>)
|
if constexpr (std::is_constructible_v<Index, ecs::container &, Args && ...>)
|
||||||
{
|
{
|
||||||
auto ptr = std::make_shared<Index>(container, std::forward<Args>(args)...);
|
auto ptr = std::make_unique<Index>(container, std::forward<Args>(args)...);
|
||||||
storage_.insert({uuid, ptr});
|
auto result = ptr.get();
|
||||||
return *ptr;
|
storage_.insert({uuid, [ptr = std::move(ptr)]{ return ptr.get(); }});
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_constructible_v<Index, Args && ...>)
|
else if constexpr (std::is_constructible_v<Index, Args && ...>)
|
||||||
{
|
{
|
||||||
auto ptr = std::make_shared<Index>(std::forward<Args>(args)...);
|
auto ptr = std::make_unique<Index>(std::forward<Args>(args)...);
|
||||||
storage_.insert({uuid, ptr});
|
auto result = ptr.get();
|
||||||
return *ptr;
|
storage_.insert({uuid, [ptr = std::move(ptr)]{ return ptr.get(); }});
|
||||||
|
return *result;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -44,8 +47,20 @@ namespace psemek::ecs::detail
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Index, typename Factory>
|
||||||
|
Index & set(Factory && factory)
|
||||||
|
{
|
||||||
|
auto uuid = Index::uuid();
|
||||||
|
if (storage_.contains(uuid))
|
||||||
|
throw util::exception("Index " + util::type_name<Index>() + " is already set");
|
||||||
|
|
||||||
|
auto result = factory();
|
||||||
|
storage_[Index::uuid()] = std::move(factory);
|
||||||
|
return *result;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
util::hash_map<util::uuid, std::shared_ptr<void>> storage_;
|
util::hash_map<util::uuid, util::function<void*()>> storage_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue