Skip to content

Instantly share code, notes, and snippets.

@ArnCarveris
Last active November 13, 2018 22:12
Show Gist options
  • Save ArnCarveris/ab673b7d125077a70472f00338574b64 to your computer and use it in GitHub Desktop.
Save ArnCarveris/ab673b7d125077a70472f00338574b64 to your computer and use it in GitHub Desktop.
EnTT Core Group
#ifndef ENTT_CORE_GROUP_HPP
#define ENTT_CORE_GROUP_HPP
#include "family.hpp"
#include <vector>
namespace entt {
/*! @brief TODO */
template<typename Base, typename... Identity>
class group
{
using underlying_family_type = Family<Identity...>;
public:
/*! @brief TODO */
using family_type = typename underlying_family_type::family_type;
/*! @brief TODO */
using base_type = Base;
/*! @brief TODO */
using ptr_type = std::shared_ptr<Base>;
/*! @brief TODO */
group() = default;
/*! @brief TODO */
group(group&&) = default;
/*! @brief TODO */
group(const group&) = delete;
/*! @brief TODO */
template<typename Type>
inline static family_type type() ENTT_NOEXCEPT {
return underlying_family_type::type<Type>();
}
/*! @brief TODO */
template<typename Type, typename Func, typename... Args>
Type& build(Func&& func, Args&&... args) {
auto i = type<Type>();
if (i >= family_type(types.size()))
{
types.resize(i + 1);
}
auto& ptr = types[i];
build(ptr, std::forward<Args>(args)...);
return *static_cast<Type*>(ptr.get());
}
/*! @brief TODO */
template<typename Type>
Type& assure() {
return build([](auto& ptr) {
if (!ptr) {
ptr = std::make_shared<Type>();
}
});
}
/*! @brief TODO */
template<typename Type, typename... Args>
Type& make(Args&&... args) {
return build([](auto& ptr, Args&&... args) {
ptr = std::make_shared<Type>(std::forward<Args>(args)...);
}, std::forward<Args>(args)...);
}
/*! @brief TODO */
template<typename Type>
Type& set(Type&& arg) {
return make<Type, Type>(std::forward<Type>(arg));
}
/*! @brief TODO */
template<typename Type>
void unset() {
auto i = type<Type>();
if (i < family_type(types.size())) {
types[i] = nullptr;
}
}
/*! @brief TODO */
base_type* get(family_type i) const ENTT_NOEXCEPT {
if (i < family_type(types.size())) {
return types[i].get();
}
return nullptr;
}
/*! @brief TODO */
template<typename Type>
Type* get() const ENTT_NOEXCEPT {
return static_cast<Type*>(get(type<Type>(i)));
}
/*! @brief TODO */
template<typename Type>
bool has() const ENTT_NOEXCEPT {
return get<Type>() != nullptr;
}
/*! @brief TODO */
template<typename Type, typename Func, typename... Args>
bool probe(Func&& func, Args&&... args) const {
if (auto ptr = get<Type>()) {
func(ptr, std::forward<Args>(args)...);
return true;
}
return false;
}
/*! @brief TODO */
template<typename Func, typename... Args>
bool probe(family_type i, Func&& func, Args&&... args) const {
if (auto ptr = get(i)) {
func(ptr, std::forward<Args>(args)...);
return true;
}
return false;
}
/*! @brief TODO */
template<typename Func, typename... Args>
void visit(Func&& func, Args&&... args) const {
for (family_type i = 0, n = family_type(types.size()); i < n; ++i) {
if (auto ptr = types[i].get()) {
func(i, ptr, std::forward<Args>(args)...);
}
}
}
/*! @brief TODO */
void clear() {
types.clear();
}
private:
std::vector<ptr_type> types;
};
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment