[Bf-blender-cvs] [5d4bf32c40e] functions: allocate type extensions in type directly
Jacques Lucke
noreply at git.blender.org
Thu May 2 11:44:57 CEST 2019
Commit: 5d4bf32c40ee3494c2a675e4519b42e16481abf4
Author: Jacques Lucke
Date: Thu May 2 11:19:05 2019 +0200
Branches: functions
https://developer.blender.org/rB5d4bf32c40ee3494c2a675e4519b42e16481abf4
allocate type extensions in type directly
This makes sense, since every extension is owned
by a Type object. Also this improves thread safety.
===================================================================
M source/blender/blenlib/BLI_composition.hpp
M source/blender/functions/core/type.hpp
M source/blender/functions/types/boolean.cpp
M source/blender/functions/types/numeric.cpp
M source/blender/functions/types/numeric_lists.cpp
===================================================================
diff --git a/source/blender/blenlib/BLI_composition.hpp b/source/blender/blenlib/BLI_composition.hpp
index ad0e6b6c839..68e67b764f9 100644
--- a/source/blender/blenlib/BLI_composition.hpp
+++ b/source/blender/blenlib/BLI_composition.hpp
@@ -35,6 +35,11 @@ class Composition {
}
}
+ template<typename T> inline bool has() const
+ {
+ return m_elements.contains(this->get_key<T>());
+ }
+
~Composition()
{
for (const Entry &entry : m_elements.values()) {
diff --git a/source/blender/functions/core/type.hpp b/source/blender/functions/core/type.hpp
index 11ee8feba13..0b774e324e4 100644
--- a/source/blender/functions/core/type.hpp
+++ b/source/blender/functions/core/type.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <string>
+#include <mutex>
#include "BLI_composition.hpp"
#include "BLI_shared.hpp"
@@ -8,7 +9,23 @@ namespace FN {
using namespace BLI;
+class Type;
+
class TypeExtension {
+ private:
+ Type *m_owner = nullptr;
+ friend Type;
+
+ void set_owner(Type *owner)
+ {
+ m_owner = owner;
+ }
+
+ public:
+ Type *owner() const
+ {
+ return m_owner;
+ }
};
class Type final : public RefCountedBase {
@@ -23,16 +40,35 @@ class Type final : public RefCountedBase {
return m_name;
}
- template<typename T> inline T *extension() const
+ template<typename T> bool has_extension() const
+ {
+ std::lock_guard<std::mutex> lock(m_extension_mutex);
+ return m_extensions.has<T>();
+ }
+
+ template<typename T> T *extension() const
{
+ /* TODO: Check if we really need a lock here.
+ * Since extensions can't be removed, it might be
+ * to access existing extensions without a lock. */
+ std::lock_guard<std::mutex> lock(m_extension_mutex);
return m_extensions.get<T>();
}
- template<typename T> void extend(T *extension)
+ template<typename T, typename... Args> bool extend(Args &&... args)
{
- BLI_assert(m_extensions.get<T>() == nullptr);
+ std::lock_guard<std::mutex> lock(m_extension_mutex);
static_assert(std::is_base_of<TypeExtension, T>::value, "");
- m_extensions.add(extension);
+
+ if (m_extensions.has<T>()) {
+ return false;
+ }
+ else {
+ T *new_extension = new T(std::forward<Args>(args)...);
+ new_extension->set_owner(this);
+ m_extensions.add(new_extension);
+ return true;
+ }
}
friend bool operator==(const Type &a, const Type &b)
@@ -43,6 +79,7 @@ class Type final : public RefCountedBase {
private:
std::string m_name;
Composition m_extensions;
+ mutable std::mutex m_extension_mutex;
};
using SharedType = AutoRefCount<Type>;
diff --git a/source/blender/functions/types/boolean.cpp b/source/blender/functions/types/boolean.cpp
index 377b4c1a34b..33c7db570e4 100644
--- a/source/blender/functions/types/boolean.cpp
+++ b/source/blender/functions/types/boolean.cpp
@@ -34,8 +34,8 @@ class LLVMBool : public TrivialLLVMTypeInfo {
LAZY_INIT_REF__NO_ARG(SharedType, GET_TYPE_bool)
{
SharedType type = SharedType::New("Bool");
- type->extend(new CPPTypeInfoForType<bool>());
- type->extend(new LLVMBool());
+ type->extend<CPPTypeInfoForType<bool>>();
+ type->extend<LLVMBool>();
return type;
}
diff --git a/source/blender/functions/types/numeric.cpp b/source/blender/functions/types/numeric.cpp
index 4e59a8003c7..a214b1bf5a5 100644
--- a/source/blender/functions/types/numeric.cpp
+++ b/source/blender/functions/types/numeric.cpp
@@ -10,18 +10,18 @@ namespace Types {
LAZY_INIT_REF__NO_ARG(SharedType, GET_TYPE_float)
{
SharedType type = SharedType::New("Float");
- type->extend(new CPPTypeInfoForType<float>());
- type->extend(new PackedLLVMTypeInfo(
- [](llvm::LLVMContext &context) { return llvm::Type::getFloatTy(context); }));
+ type->extend<CPPTypeInfoForType<float>>();
+ type->extend<PackedLLVMTypeInfo>(
+ [](llvm::LLVMContext &context) { return llvm::Type::getFloatTy(context); });
return type;
}
LAZY_INIT_REF__NO_ARG(SharedType, GET_TYPE_int32)
{
SharedType type = SharedType::New("Int32");
- type->extend(new CPPTypeInfoForType<int32_t>());
- type->extend(new PackedLLVMTypeInfo(
- [](llvm::LLVMContext &context) { return llvm::Type::getIntNTy(context, 32); }));
+ type->extend<CPPTypeInfoForType<int32_t>>();
+ type->extend<PackedLLVMTypeInfo>(
+ [](llvm::LLVMContext &context) { return llvm::Type::getIntNTy(context, 32); });
return type;
}
@@ -67,8 +67,8 @@ class FloatVectorType : public TrivialLLVMTypeInfo {
LAZY_INIT_REF__NO_ARG(SharedType, GET_TYPE_fvec3)
{
SharedType type = SharedType::New("FVec3");
- type->extend(new CPPTypeInfoForType<Vector>());
- type->extend(new FloatVectorType(3));
+ type->extend<CPPTypeInfoForType<Vector>>();
+ type->extend<FloatVectorType>(3);
return type;
}
diff --git a/source/blender/functions/types/numeric_lists.cpp b/source/blender/functions/types/numeric_lists.cpp
index 3b50d554246..5274ae223f3 100644
--- a/source/blender/functions/types/numeric_lists.cpp
+++ b/source/blender/functions/types/numeric_lists.cpp
@@ -7,40 +7,32 @@
namespace FN {
namespace Types {
-template<typename T> class ListLLVMTypeInfo : public LLVMTypeInfo {
- private:
- static void *copy_func(void *value)
- {
- List<T> *list = (List<T> *)value;
- list->new_user();
- return list;
- }
-
- static void free_func(void *value)
- {
- List<T> *list = (List<T> *)value;
- list->remove_user();
- }
+template<typename T> static void *copy_func(void *value)
+{
+ List<T> *list = (List<T> *)value;
+ list->new_user();
+ return list;
+}
- static void *default_func()
- {
- return new List<T>();
- }
+template<typename T> static void free_func(void *value)
+{
+ List<T> *list = (List<T> *)value;
+ list->remove_user();
+}
- public:
- static LLVMTypeInfo *Create()
- {
- static_assert(sizeof(SharedList<T>) == sizeof(List<T> *),
- "Currently it is assumed that only a pointer to the list is stored");
- return new PointerLLVMTypeInfo(copy_func, free_func, default_func);
- }
-};
+template<typename T> static void *default_func()
+{
+ return new List<T>();
+}
template<typename T> SharedType create_list_type(std::string name)
{
+ static_assert(sizeof(SharedList<T>) == sizeof(List<T> *),
+ "Currently it is assumed that only a pointer to the list is stored");
+
SharedType type = SharedType::New(name);
- type->extend(new CPPTypeInfoForType<SharedList<T>>());
- type->extend(ListLLVMTypeInfo<T>::Create());
+ type->extend<CPPTypeInfoForType<SharedList<T>>>();
+ type->extend<PointerLLVMTypeInfo>(copy_func<T>, free_func<T>, default_func<T>);
return type;
}
More information about the Bf-blender-cvs
mailing list