Last active
November 13, 2018 22:12
-
-
Save ArnCarveris/ab673b7d125077a70472f00338574b64 to your computer and use it in GitHub Desktop.
EnTT Core Group
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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