diff options
author | Josh Blum | 2013-03-17 11:17:15 -0700 |
---|---|---|
committer | Josh Blum | 2013-03-17 11:17:15 -0700 |
commit | b142e0e75f8ab4e7b2bb70c3fc71b61fd5f71651 (patch) | |
tree | 95fee7787912a90cce81cd3a8ce902068eff481e /include | |
parent | cebd974738fea792f70bca8ab0bb1d73e2116d81 (diff) | |
download | sandhi-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.txt | 2 | ||||
-rw-r--r-- | include/gras/block.hpp | 70 | ||||
-rw-r--r-- | include/gras/detail/block.hpp | 35 | ||||
-rw-r--r-- | include/gras/detail/property.hpp | 63 |
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*/ |