diff options
-rw-r--r-- | source/blender/blenlib/BLI_resource_scope.hh | 193 | ||||
-rw-r--r-- | source/blender/blenlib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/blenlib/intern/resource_scope.cc | 32 |
3 files changed, 133 insertions, 93 deletions
diff --git a/source/blender/blenlib/BLI_resource_scope.hh b/source/blender/blenlib/BLI_resource_scope.hh index 761e1ef834c..8e88e251d30 100644 --- a/source/blender/blenlib/BLI_resource_scope.hh +++ b/source/blender/blenlib/BLI_resource_scope.hh @@ -56,106 +56,113 @@ class ResourceScope : NonCopyable, NonMovable { Vector<ResourceData> resources_; public: - ResourceScope() = default; - - ~ResourceScope() - { - /* Free in reversed order. */ - for (int64_t i = resources_.size(); i--;) { - ResourceData &data = resources_[i]; - data.free(data.data); - } - } + ResourceScope(); + ~ResourceScope(); - /** - * Pass ownership of the resource to the ResourceScope. It will be destructed and freed when - * the collector is destructed. - */ - template<typename T> T *add(std::unique_ptr<T> resource) - { - T *ptr = resource.release(); - if (ptr == nullptr) { - return nullptr; - } - this->add(ptr, [](void *data) { - T *typed_data = reinterpret_cast<T *>(data); - delete typed_data; - }); - return ptr; - } + template<typename T> T *add(std::unique_ptr<T> resource); + template<typename T> T *add(destruct_ptr<T> resource); + void add(void *userdata, void (*free)(void *)); - /** - * Pass ownership of the resource to the ResourceScope. It will be destructed when the - * collector is destructed. - */ - template<typename T> T *add(destruct_ptr<T> resource) - { - T *ptr = resource.release(); - if (ptr == nullptr) { - return nullptr; - } - /* There is no need to keep track of such types. */ - if (std::is_trivially_destructible_v<T>) { - return ptr; - } - - this->add(ptr, [](void *data) { - T *typed_data = reinterpret_cast<T *>(data); - typed_data->~T(); - }); - return ptr; - } + template<typename T> T &add_value(T &&value); + template<typename Func> void add_destruct_call(Func func); - /** - * Pass ownership of some resource to the ResourceScope. The given free function will be - * called when the collector is destructed. - */ - void add(void *userdata, void (*free)(void *)) - { - ResourceData data; - data.data = userdata; - data.free = free; - resources_.append(data); - } + template<typename T, typename... Args> T &construct(Args &&...args); - /** - * Construct an object with the same value in the ResourceScope and return a reference to the - * new value. - */ - template<typename T> T &add_value(T &&value) - { - return this->construct<T>(std::forward<T>(value)); - } + LinearAllocator<> &linear_allocator(); +}; - /** - * The passed in function will be called when the scope is destructed. - */ - template<typename Func> void add_destruct_call(Func func) - { - void *buffer = allocator_.allocate(sizeof(Func), alignof(Func)); - new (buffer) Func(std::move(func)); - this->add(buffer, [](void *data) { (*(Func *)data)(); }); - } +/* -------------------------------------------------------------------- + * #ResourceScope inline methods. + */ - /** - * Returns a reference to a linear allocator that is owned by the ResourcesCollector. Memory - * allocated through this allocator will be freed when the collector is destructed. - */ - LinearAllocator<> &linear_allocator() - { - return allocator_; +/** + * Pass ownership of the resource to the ResourceScope. It will be destructed and freed when + * the collector is destructed. + */ +template<typename T> inline T *ResourceScope::add(std::unique_ptr<T> resource) +{ + T *ptr = resource.release(); + if (ptr == nullptr) { + return nullptr; } - - /** - * Utility method to construct an instance of type T that will be owned by the ResourceScope. - */ - template<typename T, typename... Args> T &construct(Args &&...args) - { - destruct_ptr<T> value_ptr = allocator_.construct<T>(std::forward<Args>(args)...); - T &value_ref = *value_ptr; - this->add(std::move(value_ptr)); - return value_ref; + this->add(ptr, [](void *data) { + T *typed_data = reinterpret_cast<T *>(data); + delete typed_data; + }); + return ptr; +} + +/** + * Pass ownership of the resource to the ResourceScope. It will be destructed when the + * collector is destructed. + */ +template<typename T> inline T *ResourceScope::add(destruct_ptr<T> resource) +{ + T *ptr = resource.release(); + if (ptr == nullptr) { + return nullptr; } -}; + /* There is no need to keep track of such types. */ + if constexpr (std::is_trivially_destructible_v<T>) { + return ptr; + } + + this->add(ptr, [](void *data) { + T *typed_data = reinterpret_cast<T *>(data); + typed_data->~T(); + }); + return ptr; +} + +/** + * Pass ownership of some resource to the ResourceScope. The given free function will be + * called when the collector is destructed. + */ +inline void ResourceScope::add(void *userdata, void (*free)(void *)) +{ + ResourceData data; + data.data = userdata; + data.free = free; + resources_.append(data); +} + +/** + * Construct an object with the same value in the ResourceScope and return a reference to the + * new value. + */ +template<typename T> inline T &ResourceScope::add_value(T &&value) +{ + return this->construct<T>(std::forward<T>(value)); +} + +/** + * The passed in function will be called when the scope is destructed. + */ +template<typename Func> inline void ResourceScope::add_destruct_call(Func func) +{ + void *buffer = allocator_.allocate(sizeof(Func), alignof(Func)); + new (buffer) Func(std::move(func)); + this->add(buffer, [](void *data) { (*(Func *)data)(); }); +} + +/** + * Utility method to construct an instance of type T that will be owned by the ResourceScope. + */ +template<typename T, typename... Args> inline T &ResourceScope::construct(Args &&...args) +{ + destruct_ptr<T> value_ptr = allocator_.construct<T>(std::forward<Args>(args)...); + T &value_ref = *value_ptr; + this->add(std::move(value_ptr)); + return value_ref; +} + +/** + * Returns a reference to a linear allocator that is owned by the ResourcesCollector. Memory + * allocated through this allocator will be freed when the collector is destructed. + */ +inline LinearAllocator<> &ResourceScope::linear_allocator() +{ + return allocator_; +} } // namespace blender diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 1eaf007e01b..c886732365e 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -124,6 +124,7 @@ set(SRC intern/quadric.c intern/rand.cc intern/rct.c + intern/resource_scope.cc intern/scanfill.c intern/scanfill_utils.c intern/session_uuid.c diff --git a/source/blender/blenlib/intern/resource_scope.cc b/source/blender/blenlib/intern/resource_scope.cc new file mode 100644 index 00000000000..8c8a03b8ce5 --- /dev/null +++ b/source/blender/blenlib/intern/resource_scope.cc @@ -0,0 +1,32 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "BLI_resource_scope.hh" + +namespace blender { + +ResourceScope::ResourceScope() = default; + +ResourceScope::~ResourceScope() +{ + /* Free in reversed order. */ + for (int64_t i = resources_.size(); i--;) { + ResourceData &data = resources_[i]; + data.free(data.data); + } +} + +} // namespace blender |