resource: remove the requirement to use shared_ptr (close #679)
This commit is contained in:
1
TODO
1
TODO
@@ -7,6 +7,7 @@
|
||||
* custom pools example (multi instance, tables, enable/disable, and so on...)
|
||||
|
||||
WIP:
|
||||
* HP: resource, forward the id to the loader from the cache and if constexpr the call to load, update doc and describe customization points
|
||||
* HP: any_vector for context variables
|
||||
* HP: make const registry::view thread safe, switch to a view<T...>{registry} model (long term goal)
|
||||
* HP: review registry::get, registry::try_get
|
||||
|
||||
@@ -23,7 +23,7 @@ loading, and so on.
|
||||
`EnTT` doesn't pretend to offer a _one-fits-all_ solution for the different
|
||||
cases. Instead, it offers a minimal and perhaps trivial cache that can be useful
|
||||
most of the time during prototyping and sometimes even in a production
|
||||
environment.<br/>
|
||||
environments.<br/>
|
||||
For those interested in the subject, the plan is to improve it considerably over
|
||||
time in terms of performance, memory usage and functionalities. Hoping to make
|
||||
it, of course, one step at a time.
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#define ENTT_RESOURCE_CACHE_HPP
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
@@ -93,18 +92,16 @@ struct resource_cache {
|
||||
template<typename Loader, typename... Args>
|
||||
resource_handle<Resource> load(const id_type id, Args &&... args) {
|
||||
static_assert(std::is_base_of_v<resource_loader<Loader, Resource>, Loader>, "Invalid loader type");
|
||||
resource_handle<Resource> resource{};
|
||||
|
||||
if(auto it = resources.find(id); it == resources.cend()) {
|
||||
if(auto instance = Loader{}.get(std::forward<Args>(args)...); instance) {
|
||||
resources[id] = instance;
|
||||
resource = std::move(instance);
|
||||
if(auto handle = temp<Loader>(std::forward<Args>(args)...); handle) {
|
||||
return (resources[id] = std::move(handle));
|
||||
}
|
||||
} else {
|
||||
resource = it->second;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return resource;
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +146,7 @@ struct resource_cache {
|
||||
*/
|
||||
template<typename Loader, typename... Args>
|
||||
[[nodiscard]] resource_handle<Resource> temp(Args &&... args) const {
|
||||
return { Loader{}.get(std::forward<Args>(args)...) };
|
||||
return Loader{}.get(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,8 +163,11 @@ struct resource_cache {
|
||||
* @return A handle for the given resource.
|
||||
*/
|
||||
[[nodiscard]] resource_handle<Resource> handle(const id_type id) const {
|
||||
auto it = resources.find(id);
|
||||
return { it == resources.end() ? nullptr : it->second };
|
||||
if(auto it = resources.find(id); it != resources.cend()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,15 +221,15 @@ struct resource_cache {
|
||||
if constexpr(std::is_invocable_v<Func, id_type>) {
|
||||
func(curr->first);
|
||||
} else if constexpr(std::is_invocable_v<Func, resource_handle<Resource>>) {
|
||||
func(resource_handle{ curr->second });
|
||||
func(curr->second);
|
||||
} else {
|
||||
func(curr->first, resource_handle{ curr->second });
|
||||
func(curr->first, curr->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<id_type, std::shared_ptr<Resource>> resources;
|
||||
std::unordered_map<id_type, resource_handle<Resource>> resources;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ struct resource_cache;
|
||||
|
||||
|
||||
template<typename>
|
||||
class resource_handle;
|
||||
struct resource_handle;
|
||||
|
||||
|
||||
template<typename, typename>
|
||||
|
||||
@@ -24,18 +24,18 @@ namespace entt {
|
||||
* @tparam Resource Type of resource managed by a handle.
|
||||
*/
|
||||
template<typename Resource>
|
||||
class resource_handle {
|
||||
/*! @brief Resource handles are friends of their caches. */
|
||||
friend struct resource_cache<Resource>;
|
||||
struct resource_handle {
|
||||
/*! @brief Default constructor. */
|
||||
resource_handle() ENTT_NOEXCEPT = default;
|
||||
|
||||
/**
|
||||
* @brief Creates a handle from a shared pointer, namely a resource.
|
||||
* @param res A pointer to a properly initialized resource.
|
||||
*/
|
||||
resource_handle(std::shared_ptr<Resource> res) ENTT_NOEXCEPT
|
||||
: resource{std::move(res)}
|
||||
{}
|
||||
|
||||
public:
|
||||
/*! @brief Default constructor. */
|
||||
resource_handle() ENTT_NOEXCEPT = default;
|
||||
|
||||
/**
|
||||
* @brief Gets a reference to the managed resource.
|
||||
*
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#define ENTT_RESOURCE_LOADER_HPP
|
||||
|
||||
|
||||
#include <memory>
|
||||
#include "fwd.hpp"
|
||||
#include "handle.hpp"
|
||||
|
||||
|
||||
namespace entt {
|
||||
@@ -15,14 +15,14 @@ namespace entt {
|
||||
* Resource loaders must inherit from this class and stay true to the CRTP
|
||||
* idiom. Moreover, a resource loader must expose a public, const member
|
||||
* function named `load` that accepts a variable number of arguments and returns
|
||||
* a shared pointer to the resource just created.<br/>
|
||||
* a handle to the resource just created.<br/>
|
||||
* As an example:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* struct my_resource {};
|
||||
*
|
||||
* struct my_loader: entt::resource_loader<my_loader, my_resource> {
|
||||
* std::shared_ptr<my_resource> load(int) const {
|
||||
* resource_handle<my_resource> load(int value) const {
|
||||
* // use the integer value somehow
|
||||
* return std::make_shared<my_resource>();
|
||||
* }
|
||||
@@ -53,7 +53,7 @@ class resource_loader {
|
||||
* @return The resource just loaded or an empty pointer in case of errors.
|
||||
*/
|
||||
template<typename... Args>
|
||||
[[nodiscard]] std::shared_ptr<Resource> get(Args &&... args) const {
|
||||
[[nodiscard]] resource_handle<Resource> get(Args &&... args) const {
|
||||
return static_cast<const Loader *>(this)->load(std::forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user