[Bf-blender-cvs] [1b6112b] depsgraph_refactor: Utility class DepsgraphOperation to bind the "context" arguments of an operation to the evaluation function.

Lukas Tönne noreply at git.blender.org
Thu Jun 5 20:21:06 CEST 2014


Commit: 1b6112b6fca73d4a4d0b08b3d7aab64e9cde4610
Author: Lukas Tönne
Date:   Thu Jun 5 18:08:58 2014 +0200
https://developer.blender.org/rB1b6112b6fca73d4a4d0b08b3d7aab64e9cde4610

Utility class DepsgraphOperation to bind the "context" arguments of an
operation to the evaluation function.

This can replace the simple callback function and avoid anonymous void*
context arguments, which would need to be casted explicitly. Further
the context arguments and the evaluation function can be combined in a
single struct.

Eventually it would be more elegant to have true function binding, but
this has only been added to the C++ standard in C++11. We could backport
boost implementation, but until then this is a usable compromise.

===================================================================

M	source/blender/depsgraph/intern/depsnode_operation.h

===================================================================

diff --git a/source/blender/depsgraph/intern/depsnode_operation.h b/source/blender/depsgraph/intern/depsnode_operation.h
index 67a7455..1464823 100644
--- a/source/blender/depsgraph/intern/depsnode_operation.h
+++ b/source/blender/depsgraph/intern/depsnode_operation.h
@@ -27,9 +27,13 @@
 #ifndef __DEPSNODE_OPERATION_H__
 #define __DEPSNODE_OPERATION_H__
 
+#include <stdlib.h>
+
 #include "MEM_guardedalloc.h"
 
 extern "C" {
+#include "BLI_utildefines.h"
+
 #include "RNA_access.h"
 }
 
@@ -43,6 +47,78 @@ struct ID;
 struct Depsgraph;
 struct DepsgraphCopyContext;
 
+class DepsgraphOperation {
+public:
+	typedef void (*call_func)(void *data);
+	typedef void (*free_func)(void *data);
+	
+	template <typename functor_t>
+	struct MemFunWrapper {
+		MemFunWrapper(const functor_t &f) :
+		    fun(f)
+		{}
+		
+		inline static void call(void *self)
+		{
+			((MemFunWrapper<functor_t> *)self)->fun();
+		}
+		
+		inline static void free(void *self)
+		{
+			delete (MemFunWrapper<functor_t> *)self;
+		}
+		
+	private:
+		functor_t fun;
+	};
+	
+	/* default constructor creates a NOOP */
+	DepsgraphOperation()
+	{
+		m_func = NULL;
+		m_data = NULL;
+		m_data_free = NULL;
+	}
+	
+	template <typename functor_t>
+	DepsgraphOperation(const functor_t &f)
+	{
+		typedef MemFunWrapper<functor_t> wrapper_t;
+		
+		/* TODO we make a new alloc here as the actual persistent copy,
+		 * so could use efficient memory management later, and don't need to
+		 * define new/delete in every operation args type! (using placement new/delete)
+		 */
+		wrapper_t *wrapper = new wrapper_t(f);
+		m_func = &wrapper_t::call;
+		m_data = wrapper;
+		m_data_free = &wrapper_t::free;
+	}
+	
+	~DepsgraphOperation()
+	{
+		/* XXX TODO Also consider placement new/delete here (see constructor) */
+		if (m_data && m_data_free)
+			m_data_free(m_data);
+	}
+	
+	inline void operator() () const
+	{
+		BLI_assert(m_func);
+		m_func(m_data);
+	}
+	
+	bool is_noop() const
+	{
+		return m_func == NULL;
+	}
+	
+private:
+	call_func m_func;
+	void *m_data;
+	free_func m_data_free;
+};
+
 /* Flags for Depsgraph Nodes */
 typedef enum eDepsOperation_Flag {
 	/* node needs to be updated */




More information about the Bf-blender-cvs mailing list