mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
build: add EnTT library
This commit is contained in:
161
include/entt/locator/locator.hpp
Normal file
161
include/entt/locator/locator.hpp
Normal file
@@ -0,0 +1,161 @@
|
||||
#ifndef ENTT_LOCATOR_LOCATOR_HPP
|
||||
#define ENTT_LOCATOR_LOCATOR_HPP
|
||||
|
||||
#include "../config/config.h"
|
||||
#include "../stl/concepts.hpp"
|
||||
#include "../stl/memory.hpp"
|
||||
#include "../stl/utility.hpp"
|
||||
|
||||
namespace entt {
|
||||
|
||||
/**
|
||||
* @brief Service locator, nothing more.
|
||||
*
|
||||
* A service locator is used to do what it promises: locate services.<br/>
|
||||
* Usually service locators are tightly bound to the services they expose and
|
||||
* thus it's hard to define a general purpose class to do that. This tiny class
|
||||
* tries to fill the gap and to get rid of the burden of defining a different
|
||||
* specific locator for each application.
|
||||
*
|
||||
* @note
|
||||
* Users shouldn't retain references to a service. The recommended way is to
|
||||
* retrieve the service implementation currently set each and every time the
|
||||
* need for it arises. The risk is to incur in unexpected behaviors otherwise.
|
||||
*
|
||||
* @tparam Service Service type.
|
||||
*/
|
||||
template<typename Service>
|
||||
class locator final {
|
||||
class service_handle {
|
||||
friend class locator<Service>;
|
||||
stl::shared_ptr<Service> value{};
|
||||
};
|
||||
|
||||
public:
|
||||
/*! @brief Service type. */
|
||||
using type = Service;
|
||||
/*! @brief Service node type. */
|
||||
using node_type = service_handle;
|
||||
|
||||
/*! @brief Default constructor, deleted on purpose. */
|
||||
locator() = delete;
|
||||
|
||||
/*! @brief Default copy constructor, deleted on purpose. */
|
||||
locator(const locator &) = delete;
|
||||
|
||||
/*! @brief Default destructor, deleted on purpose. */
|
||||
~locator() = delete;
|
||||
|
||||
/**
|
||||
* @brief Default copy assignment operator, deleted on purpose.
|
||||
* @return This locator.
|
||||
*/
|
||||
locator &operator=(const locator &) = delete;
|
||||
|
||||
/**
|
||||
* @brief Checks whether a service locator contains a value.
|
||||
* @return True if the service locator contains a value, false otherwise.
|
||||
*/
|
||||
[[nodiscard]] static bool has_value() noexcept {
|
||||
return (service != nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a reference to a valid service, if any.
|
||||
*
|
||||
* @warning
|
||||
* Invoking this function can result in undefined behavior if the service
|
||||
* hasn't been set yet.
|
||||
*
|
||||
* @return A reference to the service currently set, if any.
|
||||
*/
|
||||
[[nodiscard]] static Service &value() noexcept {
|
||||
ENTT_ASSERT(has_value(), "Service not available");
|
||||
return *service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a service if available or sets it from a fallback type.
|
||||
*
|
||||
* Arguments are used only if a service doesn't already exist. In all other
|
||||
* cases, they are discarded.
|
||||
*
|
||||
* @tparam Args Types of arguments to use to construct the fallback service.
|
||||
* @tparam Type Fallback service type.
|
||||
* @param args Parameters to use to construct the fallback service.
|
||||
* @return A reference to a valid service.
|
||||
*/
|
||||
template<stl::derived_from<Service> Type = Service, typename... Args>
|
||||
requires stl::constructible_from<Type, Args...>
|
||||
[[nodiscard]] static Service &value_or(Args &&...args) {
|
||||
return service ? *service : emplace<Type>(stl::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets or replaces a service.
|
||||
* @tparam Type Service type.
|
||||
* @tparam Args Types of arguments to use to construct the service.
|
||||
* @param args Parameters to use to construct the service.
|
||||
* @return A reference to a valid service.
|
||||
*/
|
||||
template<stl::derived_from<Service> Type = Service, typename... Args>
|
||||
requires stl::constructible_from<Type, Args...>
|
||||
static Service &emplace(Args &&...args) {
|
||||
service = stl::make_shared<Type>(stl::forward<Args>(args)...);
|
||||
return *service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets or replaces a service using a given allocator.
|
||||
* @tparam Type Service type.
|
||||
* @tparam Args Types of arguments to use to construct the service.
|
||||
* @param alloc The allocator to use.
|
||||
* @param args Parameters to use to construct the service.
|
||||
* @return A reference to a valid service.
|
||||
*/
|
||||
template<stl::derived_from<Service> Type = Service, typename... Args>
|
||||
requires stl::constructible_from<Type, Args...>
|
||||
static Service &emplace(stl::allocator_arg_t, auto alloc, Args &&...args) {
|
||||
service = stl::allocate_shared<Type>(alloc, stl::forward<Args>(args)...);
|
||||
return *service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a handle to the underlying service.
|
||||
* @return A handle to the underlying service.
|
||||
*/
|
||||
static node_type handle() noexcept {
|
||||
node_type node{};
|
||||
node.value = service;
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets or replaces a service.
|
||||
* @param other Optional handle with which to replace the service.
|
||||
*/
|
||||
static void reset(const node_type &other = {}) noexcept {
|
||||
service = other.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets or replaces a service.
|
||||
* @tparam Type Service type.
|
||||
* @tparam Deleter Deleter type.
|
||||
* @param elem A pointer to a service to manage.
|
||||
* @param deleter A deleter to use to destroy the service.
|
||||
*/
|
||||
template<stl::derived_from<Service> Type, typename Deleter = stl::default_delete<Type>>
|
||||
static void reset(Type *elem, Deleter deleter = {}) {
|
||||
service = stl::shared_ptr<Service>{elem, stl::move(deleter)};
|
||||
}
|
||||
|
||||
private:
|
||||
// stl::shared_ptr because of its type erased allocator which is useful here
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
||||
inline static stl::shared_ptr<Service> service{};
|
||||
};
|
||||
|
||||
} // namespace entt
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user