summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJosh Blum2013-03-17 11:17:15 -0700
committerJosh Blum2013-03-17 11:17:15 -0700
commitb142e0e75f8ab4e7b2bb70c3fc71b61fd5f71651 (patch)
tree95fee7787912a90cce81cd3a8ce902068eff481e /include
parentcebd974738fea792f70bca8ab0bb1d73e2116d81 (diff)
downloadsandhi-b142e0e75f8ab4e7b2bb70c3fc71b61fd5f71651.tar.gz
sandhi-b142e0e75f8ab4e7b2bb70c3fc71b61fd5f71651.tar.bz2
sandhi-b142e0e75f8ab4e7b2bb70c3fc71b61fd5f71651.zip
gras: work on C++ API for properties interface
Diffstat (limited to 'include')
-rw-r--r--include/gras/CMakeLists.txt2
-rw-r--r--include/gras/block.hpp70
-rw-r--r--include/gras/detail/block.hpp35
-rw-r--r--include/gras/detail/property.hpp63
4 files changed, 169 insertions, 1 deletions
diff --git a/include/gras/CMakeLists.txt b/include/gras/CMakeLists.txt
index 301f96a..462b0ff 100644
--- a/include/gras/CMakeLists.txt
+++ b/include/gras/CMakeLists.txt
@@ -28,6 +28,8 @@ install(FILES
install(FILES
+ detail/block.hpp
+ detail/property.hpp
detail/sbuffer.hpp
detail/work_buffer.hpp
diff --git a/include/gras/block.hpp b/include/gras/block.hpp
index 1c6516d..d33457b 100644
--- a/include/gras/block.hpp
+++ b/include/gras/block.hpp
@@ -9,6 +9,7 @@
#include <gras/tags.hpp>
#include <gras/work_buffer.hpp>
#include <gras/buffer_queue.hpp>
+#include <gras/detail/property.hpp>
#include <vector>
#include <string>
@@ -105,7 +106,7 @@ struct GRAS_API OutputPortConfig
size_t maximum_items;
};
-struct GRAS_API Block : Element
+struct GRAS_API Block : Element, PropertyInterface
{
//! Contruct an empty/null block
@@ -214,6 +215,71 @@ struct GRAS_API Block : Element
PMCC pop_input_msg(const size_t which_input);
/*******************************************************************
+ * The property interface:
+ * Provides polymorphic, thread-safe access to block properties.
+ ******************************************************************/
+
+ /*!
+ * Register property get and set methods into the property interface.
+ * Call register_property() from the contructor of the block.
+ *
+ * Note: It is safe for the user to register a NULL function if the user
+ * wishes to not register a getter or setter for a particular property.
+ *
+ * Example register usage:
+ * this->register_property("foo", &MyBlock::get_foo, &MyBlock::set_foo);
+ *
+ * Example method declarations:
+ * int get_foo(void);
+ * void set_foo(const int &new_foo);
+ *
+ * \param key the string to identify this property
+ * \param get the class method to get the property
+ * \param set the class method to set the property
+ */
+ template <typename ClassType, typename ValueType>
+ void register_property(
+ const std::string &key,
+ ValueType(ClassType::*get)(void),
+ void(ClassType::*set)(const ValueType &)
+ );
+
+ /*!
+ * Set the value of a registered property.
+ *
+ * This call is synchronous and will not return until
+ * the block has actually called the registered set operation.
+ *
+ * Note: the user must be careful to only use a value
+ * that is of the exact type associated with this property.
+ * Otherwise, set_property with throw a type error.
+ *
+ * Example with template argument to be type explicit:
+ * my_block->set_property<size_t>("foo", 42);
+ *
+ * \param key the string to identify this property
+ * \param value the new value to set to this property
+ */
+ template <typename ValueType>
+ void set_property(const std::string &key, const ValueType &value);
+
+ /*!
+ * Get the value of a registered property.
+ *
+ * Note: the user must specify the correct value type
+ * that is of the exact type associated with this property.
+ * Otherwise, get_property with throw a type error.
+ *
+ * Example with template argument to be type explicit:
+ * const size_t foo = my_block->get_property<size_t>("foo");
+ *
+ * \param key the string to identify this property
+ * \return the value of this property
+ */
+ template <typename ValueType>
+ ValueType get_property(const std::string &key);
+
+ /*******************************************************************
* Work related routines and fail states
******************************************************************/
@@ -396,4 +462,6 @@ struct GRAS_API Block : Element
} //namespace gras
+#include <gras/detail/block.hpp>
+
#endif /*INCLUDED_GRAS_BLOCK_HPP*/
diff --git a/include/gras/detail/block.hpp b/include/gras/detail/block.hpp
new file mode 100644
index 0000000..483b2bf
--- /dev/null
+++ b/include/gras/detail/block.hpp
@@ -0,0 +1,35 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_GRAS_DETAIL_BLOCK_HPP
+#define INCLUDED_GRAS_DETAIL_BLOCK_HPP
+
+namespace gras
+{
+
+template <typename ClassType, typename ValueType>
+GRAS_FORCE_INLINE void Block::register_property(
+ const std::string &key,
+ ValueType(ClassType::*get)(void),
+ void(ClassType::*set)(const ValueType &)
+)
+{
+ boost::shared_ptr<PropertyRegistry> pr;
+ pr.reset(new PropertyRegistryImpl<ClassType, ValueType>(this, get, set));
+ this->property_interface_register(key, pr);
+}
+
+template <typename ValueType>
+GRAS_FORCE_INLINE void Block::set_property(const std::string &key, const ValueType &value)
+{
+ return this->property_interface_set(key, PMC_M(value));
+}
+
+template <typename ValueType>
+GRAS_FORCE_INLINE ValueType Block::get_property(const std::string &key)
+{
+ return this->property_interface_get(key).as<ValueType>();
+}
+
+} //namespace gras
+
+#endif /*INCLUDED_GRAS_DETAIL_BLOCK_HPP*/
diff --git a/include/gras/detail/property.hpp b/include/gras/detail/property.hpp
new file mode 100644
index 0000000..467fb70
--- /dev/null
+++ b/include/gras/detail/property.hpp
@@ -0,0 +1,63 @@
+// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.
+
+#ifndef INCLUDED_GRAS_DETAIL_PROPERTY_HPP
+#define INCLUDED_GRAS_DETAIL_PROPERTY_HPP
+
+#include <PMC/PMC.hpp>
+
+namespace gras
+{
+
+struct PropertyRegistry
+{
+ PropertyRegistry(void){}
+ ~PropertyRegistry(void){}
+ virtual void set(const PMCC &) = 0;
+ virtual PMCC get(void) = 0;
+};
+
+template <typename ClassType, typename ValueType>
+struct PropertyRegistryImpl : PropertyRegistry
+{
+ PropertyRegistryImpl(
+ ClassType *my_class,
+ ValueType(ClassType::*getter)(void),
+ void(ClassType::*setter)(const ValueType &)
+ ):
+ _my_class(my_class),
+ _getter(getter),
+ _setter(setter)
+ {}
+ ~PropertyRegistryImpl(void){}
+
+ void set(const PMCC &value)
+ {
+ return _setter(_my_class, value.as<ValueType>());
+ }
+
+ PMCC get(void)
+ {
+ return PMC_M(_getter(_my_class));
+ }
+
+ ClassType *_my_class;
+ ValueType(ClassType::*_getter)(void);
+ void(ClassType::*_setter)(const ValueType &);
+};
+
+struct PropertyInterface
+{
+ virtual void property_interface_register(
+ const std::string &key,
+ boost::shared_ptr<PropertyRegistry> pr
+ ) = 0;
+
+ virtual void property_interface_set(const std::string &key, const PMCC &value) = 0;
+
+ virtual PMCC property_interface_get(const std::string &key) = 0;
+
+};
+
+} //namespace gras
+
+#endif /*INCLUDED_GRAS_DETAIL_PROPERTY_HPP*/