|
Boost-Commit : |
From: jared_at_[hidden]
Date: 2007-07-22 20:27:38
Author: jared
Date: 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
New Revision: 7508
URL: http://svn.boost.org/trac/boost/changeset/7508
Log:
Initial checkin of project pinhole
Added:
sandbox/pinhole/
sandbox/pinhole/boost/
sandbox/pinhole/boost/pinhole/
sandbox/pinhole/boost/pinhole/BoolEditor.h
sandbox/pinhole/boost/pinhole/DoubleEditor.h
sandbox/pinhole/boost/pinhole/Editor.h
sandbox/pinhole/boost/pinhole/EditorTypeFinder.h
sandbox/pinhole/boost/pinhole/FloatEditor.h
sandbox/pinhole/boost/pinhole/IntegerEditor.h
sandbox/pinhole/boost/pinhole/StringEditor.h
sandbox/pinhole/boost/pinhole/action_info.h
sandbox/pinhole/boost/pinhole/exceptions.h
sandbox/pinhole/boost/pinhole/find.h
sandbox/pinhole/boost/pinhole/main.cpp
sandbox/pinhole/boost/pinhole/map_key_value_iterators.h
sandbox/pinhole/boost/pinhole/property_group.h
sandbox/pinhole/boost/pinhole/property_group_wrapper.h
sandbox/pinhole/boost/pinhole/property_info.h
sandbox/pinhole/boost/pinhole/property_manager.h
sandbox/pinhole/doc/
sandbox/pinhole/libs/
sandbox/pinhole/libs/pinhole/
Added: sandbox/pinhole/boost/pinhole/BoolEditor.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/BoolEditor.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,35 @@
+// MscProperty system BoolEditor.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_BOOLEDITOR
+#define BOOST_BOOLEDITOR
+
+#include "Editor.h"
+
+namespace boost { namespace pinhole
+{
+ class BoolEditor : public Editor
+ {
+ public:
+ BoolEditor(EditorControlType controlType=Radio)
+ {
+ m_UItype = controlType;
+ }
+
+ ~BoolEditor() {;}
+
+ /**
+ * Retrieves the type of the property for the editor.
+ */
+ EditorPropertyType getEditorPropertyType() const
+ {
+ return( BooleanType );
+ }
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/DoubleEditor.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/DoubleEditor.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,84 @@
+// MscProperty system DoubleEditor.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DOUBLEEDITOR
+#define BOOST_DOUBLEEDITOR
+
+#include "Editor.h"
+
+namespace boost { namespace pinhole
+{
+ class DoubleEditor : public Editor
+ {
+ public:
+ DoubleEditor()
+ {
+ m_UItype = EditBox;
+ }
+
+ DoubleEditor( double dLowRange,
+ double dHighRange,
+ double dIncrement=0.5,
+ EditorControlType controlType=EditBox ) :
+ m_dLowRange( dLowRange ),
+ m_dHighRange( dHighRange ),
+ m_dIncrement( dIncrement ),
+ m_bHasRange( true )
+ {
+ m_UItype = controlType;
+ }
+
+
+ ~DoubleEditor() {;}
+
+ /**
+ * Retrieves the low range of the property for the editor.
+ */
+ double getLowRange() const
+ {
+ return( m_dLowRange );
+ }
+
+ /**
+ * Retrieves the high range of the property for the editor.
+ */
+ double getHighRange() const
+ {
+ return( m_dHighRange );
+ }
+
+ /**
+ * Retrieves the increment of the property for the editor.
+ */
+ double getIncrement() const
+ {
+ return( m_dIncrement );
+ }
+
+ /**
+ * Retrieves the flag to use range of the property for the editor.
+ */
+ bool UseRange() const
+ {
+ return( m_bHasRange );
+ }
+
+ /**
+ * Retrieves the type of the property for the editor.
+ */
+ EditorPropertyType getEditorPropertyType() const
+ {
+ return( DoubleType );
+ }
+
+ private:
+ double m_dLowRange, m_dHighRange, m_dIncrement;
+ bool m_bHasRange;
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/Editor.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/Editor.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,117 @@
+// MscProperty system Editor.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_EDITOR
+#define BOOST_EDITOR
+
+#include <map>
+#include <string>
+
+using namespace std;
+//using namespace boost;
+
+namespace boost { namespace pinhole
+{
+ enum EditorPropertyType
+ {
+ StringType,
+ IntegerType,
+ BooleanType,
+ FloatType,
+ DoubleType
+ };
+
+ enum EditorControlType
+ {
+ None=0,
+ EditBox=1,
+ Tracker=2,
+ DropDown=3,
+ Radio=4,
+ UpDown=5
+ };
+
+ class Editor
+ {
+ public:
+ typedef std::map<std::string, std::string> property_collection;
+ typedef property_collection::size_type size_type;
+ typedef property_collection::iterator iterator;
+ typedef property_collection::const_iterator const_iterator;
+
+ /**
+ * Constructor which creates a default editor that is defined as
+ * no editor.
+ */
+ Editor() : m_UItype(EditBox) {;}
+
+ /**
+ * Constructor that created an editor of the specified type.
+ * @param type The editor to use.
+ */
+ Editor(EditorControlType type)
+ {
+ m_UItype = type;
+ }
+
+ /**
+ * Destructor
+ */
+ virtual ~Editor() {;}
+
+ /**
+ * Retrieves the type of the editor to use.
+ */
+ EditorControlType GetControlType() const
+ {
+ return m_UItype;
+ }
+
+ /**
+ * Sets a property for the editor. Properties are simple key/value
+ * string pairs that are used by the editor to make decision. Each
+ * editor has a different set of properties that it will read.
+ * @param key The property key.
+ * @param value The property value.
+ */
+ Editor& operator()( std::string key, std::string value )
+ {
+ m_properties.insert( make_pair(key,value) );
+
+ return *this;
+ }
+
+ /**
+ * Overloaded operator equal.
+ * @param editor The Editor class to copy.
+ */
+ virtual Editor& operator=( const Editor& editor )
+ {
+ m_UItype = editor.m_UItype;
+
+ m_properties.clear();
+ m_properties.insert( editor.m_properties.begin(), editor.m_properties.end() );
+
+ return *this;
+ }
+
+
+ /**
+ * Retrieves the type of the property for the editor.
+ */
+ virtual EditorPropertyType getEditorPropertyType() const = 0;
+
+ protected:
+ EditorControlType m_UItype;
+#pragma warning(push)
+#pragma warning( disable: 4251 )
+ property_collection m_properties;
+#pragma warning(pop)
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/EditorTypeFinder.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/EditorTypeFinder.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,64 @@
+// MscProperty system EditorTypeFinder.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DETAIL_EDITORTYPEFINDER
+#define BOOST_DETAIL_EDITORTYPEFINDER
+
+#include <boost/mpl/void.hpp>
+#include "BoolEditor.h"
+#include "DoubleEditor.h"
+#include "FloatEditor.h"
+#include "IntegerEditor.h"
+#include "StringEditor.h"
+
+namespace boost { namespace pinhole { namespace detail
+{
+
+ template<typename Value_Type>
+ struct EditorTypeFinder
+ {
+ typedef boost::mpl::void_ type;
+ };
+
+ template<>
+ struct EditorTypeFinder<bool>
+ {
+ typedef BoolEditor type;
+ };
+
+ template<>
+ struct EditorTypeFinder<double>
+ {
+ typedef DoubleEditor type;
+ };
+
+ template<>
+ struct EditorTypeFinder<float>
+ {
+ typedef FloatEditor type;
+ };
+
+ template<>
+ struct EditorTypeFinder<int>
+ {
+ typedef IntegerEditor type;
+ };
+
+ template<>
+ struct EditorTypeFinder<time_t>
+ {
+ typedef IntegerEditor type;
+ };
+
+ template<>
+ struct EditorTypeFinder<std::string>
+ {
+ typedef StringEditor type;
+ };
+}}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/FloatEditor.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/FloatEditor.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,83 @@
+// MscProperty system FloatEditor.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FLOATEDITOR
+#define BOOST_FLOATEDITOR
+
+#include "Editor.h"
+
+namespace boost { namespace pinhole
+{
+ class FloatEditor : public Editor
+ {
+ public:
+ FloatEditor()
+ {
+ m_UItype = EditBox;
+ };
+
+ FloatEditor( float fLowRange,
+ float fHighRange,
+ float fIncrement=0.5,
+ EditorControlType controlType=EditBox ) :
+ m_fLowRange( fLowRange ),
+ m_fHighRange( fHighRange ),
+ m_fIncrement( fIncrement )
+ {
+ m_UItype = controlType;
+ m_bHasRange = true;
+ }
+
+ ~FloatEditor() {;}
+
+ /**
+ * Retrieves the low range of the property for the editor.
+ */
+ float getLowRange() const
+ {
+ return( m_fLowRange );
+ }
+
+ /**
+ * Retrieves the high range of the property for the editor.
+ */
+ float getHighRange() const
+ {
+ return( m_fHighRange );
+ }
+
+ /**
+ * Retrieves the increment of the property for the editor.
+ */
+ float getIncrement() const
+ {
+ return( m_fIncrement );
+ }
+
+ /**
+ * Retrieves the flag to use range of the property for the editor.
+ */
+ bool UseRange() const
+ {
+ return( m_bHasRange );
+ }
+
+ /**
+ * Retrieves the type of the property for the editor.
+ */
+ EditorPropertyType getEditorPropertyType() const
+ {
+ return( FloatType );
+ }
+
+ private:
+ float m_fLowRange, m_fHighRange, m_fIncrement;
+ bool m_bHasRange;
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/IntegerEditor.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/IntegerEditor.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,85 @@
+// MscProperty system IntegerEditor.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_INTEGEREDITOR
+#define BOOST_INTEGEREDITOR
+
+#include "Editor.h"
+
+namespace boost { namespace pinhole
+{
+ class IntegerEditor : public Editor
+ {
+ public:
+ IntegerEditor()
+ {
+ m_UItype = EditBox;
+ m_bHasRange = false;
+ }
+
+ IntegerEditor( int iLowRange,
+ int iHighRange,
+ int iIncrement=0,
+ EditorControlType controlType=EditBox ) :
+ m_iLowRange( iLowRange ),
+ m_iHighRange( iHighRange ),
+ m_iIncrement( iIncrement )
+ {
+ m_UItype = controlType;
+ m_bHasRange = true;
+ }
+
+ virtual ~IntegerEditor() {;}
+
+
+ /**
+ * Retrieves the low range of the property for the editor.
+ */
+ int getLowRange() const
+ {
+ return( m_iLowRange );
+ }
+
+ /**
+ * Retrieves the high range of the property for the editor.
+ */
+ int getHighRange() const
+ {
+ return( m_iHighRange );
+ }
+
+ /**
+ * Retrieves the increment of the property for the editor.
+ */
+ int getIncrement() const
+ {
+ return( m_iIncrement );
+ }
+
+ /**
+ * Retrieves the flag to use range of the property for the editor.
+ */
+ bool UseRange() const
+ {
+ return( m_bHasRange );
+ }
+
+ /**
+ * Retrieves the type of the property for the editor.
+ */
+ EditorPropertyType getEditorPropertyType() const
+ {
+ return( IntegerType );
+ }
+
+ private:
+ int m_iLowRange, m_iHighRange, m_iIncrement;
+ bool m_bHasRange;
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/StringEditor.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/StringEditor.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,35 @@
+// MscProperty system StringEditor.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_STRINGEDITOR
+#define BOOST_STRINGEDITOR
+
+#include "Editor.h"
+
+namespace boost { namespace pinhole
+{
+ class StringEditor : public Editor
+ {
+ public:
+ StringEditor()
+ {
+ m_UItype = EditBox;
+ }
+
+ ~StringEditor() {;}
+
+ /**
+ * Retrieves the type of the property for the editor.
+ */
+ EditorPropertyType getEditorPropertyType() const
+ {
+ return( StringType );
+ }
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/action_info.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/action_info.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,49 @@
+// MscProperty system action_info.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DETAILS_ACTION_INFO
+#define BOOST_DETAILS_ACTION_INFO
+
+#pragma warning(push)
+#pragma warning( disable: 4272 4394 )
+#include "Editor.h"
+#pragma warning(pop)
+
+#pragma warning(push)
+#pragma warning( disable: 4561 4793 )
+#include <boost/type_traits.hpp>
+#include <boost/function.hpp>
+#include <boost/lexical_cast.hpp>
+#pragma warning(pop)
+
+namespace boost { namespace pinhole { namespace detail
+{
+ struct action_info
+ {
+ private:
+ template<typename type> struct Internal;
+
+ public:
+ typedef boost::function<void ()> action_type;
+
+ action_type m_action;
+ std::string m_name;
+ std::string m_description;
+
+ /**
+ * Calls the appropriate action function for this parameter.
+ *
+ * @throw boost::bad_function_call There isn't a set function associated with this property.
+ */
+ virtual void trigger()
+ {
+ m_action();
+ }
+ };
+}}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/exceptions.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/exceptions.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,36 @@
+// MscProperty system Exceptions.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_DETAIL_EXCEPTIONS
+#define BOOST_DETAIL_EXCEPTIONS
+
+#include <exception>
+#include <stdexcept>
+#include <string>
+
+namespace boost { namespace pinhole
+{
+ class multiple_property_groups : public std::runtime_error
+ {
+ public: multiple_property_groups(const std::string& strErrMsg) : std::runtime_error(strErrMsg) {;}
+ };
+
+ class invalid_path : public std::runtime_error
+ {
+ public: invalid_path(const std::string& strErrMsg) : std::runtime_error(strErrMsg) {;}
+ };
+
+ class failed_to_find_group : public std::exception{};
+
+ class no_metadata_defined_error : public std::runtime_error
+ {
+ public:
+ no_metadata_defined_error() : runtime_error( "No Property Editor Defined" ) {;}
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/find.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/find.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,207 @@
+// MscProperty system Find.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_FIND
+#define BOOST_FIND
+
+#include "property_manager.h"
+
+namespace boost { namespace pinhole
+{
+ namespace detail
+ {
+ property_group* search_single_property_group_based_on_name( children_collection* current_property_group_collection,
+ const string& property_group_name)
+ {
+ property_group* property_group_found = 0;
+ for( children_collection::iterator iter = current_property_group_collection->begin(); iter != current_property_group_collection->end(); iter++)
+ {
+ property_group* current_property_group = *iter;
+ if(current_property_group->get_name() == property_group_name)
+ {
+ if(property_group_found != 0)
+ {
+ string strError = "Multiple " + property_group_name + " are found in property_manager::selectSingleNode";
+ throw multiple_property_groups(strError.c_str());
+ }
+ property_group_found = current_property_group;
+ }
+ }
+ if(property_group_found == 0)
+ {
+ throw no_metadata_defined_error();
+ }
+ return property_group_found;
+ }
+
+ property_group* search_single_property_group_based_on_property_value( children_collection* current_property_group_collection,
+ const string& property_group_name,
+ const string& property_name,
+ const string& property_value )
+ {
+ property_group* property_group_found = 0;
+ for(children_collection::iterator iter = current_property_group_collection->begin(); iter != current_property_group_collection->end(); iter++)
+ {
+ property_group* current_property_group = *iter;
+ if((current_property_group->get_name() == property_group_name) && (current_property_group->get_as_string(property_name) == property_value))
+ {
+ if(property_group_found != 0)
+ {
+ string strError = "Multiple " + property_group_name + "." + property_name + "=" + property_value + " are found in property_manager::selectSingleNode";
+ throw multiple_property_groups(strError.c_str());
+ }
+ property_group_found = current_property_group;
+ }
+ }
+ if(property_group_found == 0)
+ {
+ throw no_metadata_defined_error();
+ }
+ return property_group_found;
+ }
+ }
+
+ /**
+ * Returns a property_group based on a path that describes where that property_group
+ * exists within the property group hierarchy. This path can either be from the
+ * root of the hierarchy, or relative to the property_group passed in to the function
+ * @n
+ * Path format one: /A/X.Y=Z @n
+ * A represents a property group name. The assumption is that A is the only property
+ * group in the current level. The path search will start from root
+ * @n
+ * Path format two: A/X.Y=Z @n
+ * A represents a property group name. The assumption is that A is the only property
+ * group in the current level. The path search will start from current_property_group
+ * @n
+ * Path format three: /A.B=C/X.Y=Z @n
+ * A and X represent property group names. B and Y represent property names. C and Z
+ * represent property values. The path search will start from root.
+ * @n
+ * Path format four: A.B=C/X.Y=Z @n
+ * A and X represent property group names. B and Y represent property names. C and Z
+ * represent property values. The path search will start from current_property_group.
+ *
+ * @param current_property_group The property_group to perform relative searches under.
+ * @param path The path to search with.
+ * @return The property_group that was found to match the path.
+ * @retval NULL No property_group was found to match the path.
+ * @throw invalid_path The path does not meet the requirements for a valid path.
+ * @throw multiple_property_groups There were multiple property groups matching this path.
+ */
+ property_group* select_single_node(property_group* current_property_group, const string& path)
+ {
+ children_collection* current_property_group_collection = NULL;
+ if( NULL != current_property_group )
+ {
+ current_property_group_collection = ¤t_property_group->get_children_collection();
+ }
+ children_collection* root_property_group_collection = 0; //The root collection might not be needed if it is not referred.
+
+ typedef vector< string > split_vector_type;
+ split_vector_type vecproperty_groups;
+ boost::split( vecproperty_groups, path, boost::is_any_of("/") ); //Note: "/" is the separator for a property group
+ try
+ {
+ for(split_vector_type::const_iterator iter_property_group = vecproperty_groups.begin(); iter_property_group != vecproperty_groups.end(); iter_property_group++)
+ {
+ string strproperty_group = *iter_property_group;
+ split_vector_type properties;
+ boost::split( properties, strproperty_group, boost::is_any_of(".=") );
+ //Note: "." is the separator between Property group name and Property name.
+ //"=" is the separator between property name and property value. If there's no "." or "=",
+ //we will just use this property group.
+ size_t nNumOfItems = properties.size();
+ switch(nNumOfItems)
+ {
+ case 1:
+ {
+ string strItem = properties[0]; //It either is "/" or the property group name.
+ boost::trim(strItem);
+ if(strItem.empty()) //It is "/"
+ {
+ property_manager *manager = property_manager::instance();
+ root_property_group_collection = new children_collection();
+ property_manager::iterator iter = manager->begin();
+ property_manager::iterator iterEnd = manager->end();
+ for( ; iter != iterEnd; iter++)
+ {
+ root_property_group_collection->push_back(*iter);
+ }
+ current_property_group_collection = root_property_group_collection; //From now on, we only care about current_property_group_collection.
+ }
+ else
+ {
+ //strItem here must be a property group name.
+ //If multiple or none is found ,exception will be thrown.
+ current_property_group = detail::search_single_property_group_based_on_name(current_property_group_collection, strItem);
+ current_property_group_collection = ¤t_property_group->get_children_collection();
+ }
+ }
+ break;
+ case 3:
+ {
+ string property_group_name = properties[0];
+ boost::trim(property_group_name);
+
+ string property_name = properties[1];
+ boost::trim(property_name);
+
+ string property_value = properties[2];
+ boost::trim(property_value);
+ current_property_group = detail::search_single_property_group_based_on_property_value(current_property_group_collection, property_group_name, property_name, property_value);
+ current_property_group_collection = ¤t_property_group->get_children_collection();
+ }
+ break;
+ default:
+ {
+ string strError = path + " is not a valid path. Details: " + strproperty_group + " should be either A.B=C or A format";
+ throw invalid_path(strError.c_str());
+ }
+ }
+ }
+ }
+ catch(no_metadata_defined_error&)
+ {
+ current_property_group = NULL;
+ }
+
+ delete root_property_group_collection;
+ return current_property_group;
+ }
+
+ property_group* select_single_node(property_group& current_property_group, const string& path)
+ {
+ return select_single_node(¤t_property_group, path);
+ }
+
+ /**
+ * Returns a property_group based on a path that describes where that property_group
+ * exists within the property group hierarchy. This version does not allow for relative
+ * path accessing.
+ * @n
+ * Path format one: /A/X.Y=Z @n
+ * A represents a property group name. The assumption is that A is the only property
+ * group in the current level. The path search will start from root\
+ * @n
+ * Path format two: /A.B=C/X.Y=Z @n
+ * A and X represent property group names. B and Y represent property names. C and Z
+ * represent property values. The path search will start from root.
+ *
+ * @param path The path to search with.
+ * @return The property_group that was found to match the path.
+ * @retval NULL No property_group was found to match the path.
+ * @throw invalid_path The path does not meet the requirements for a valid path.
+ * @throw multiple_property_groups There were multiple property groups matching this path.
+ */
+ property_group* select_single_node(const string& path)
+ {
+ return select_single_node(NULL, path);
+ }
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/main.cpp
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/main.cpp 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,258 @@
+// MscProperty system property_manager.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+
+#include "property_group.h"
+#include "property_manager.h"
+#include "find.h"
+
+using namespace std;
+using namespace boost;
+using namespace boost::pinhole;
+
+// I can hide these two line if I don't do everything in headers
+shared_ptr<property_manager> property_manager::m_instance(new property_manager);
+event_source* event_source::m_instance = 0;
+
+class SubGroup : public property_group
+{
+public:
+ SubGroup(property_group* pParentproperty_group) : property_group("SubGroup", pParentproperty_group)
+ {
+ add_property<string>("Name", "name", BOOST_SETTER_NONE, BOOST_GETTER(&SubGroup::GetName));
+ }
+
+ string GetName()
+ {
+ return "SubGroup";
+ }
+};
+
+// For an object to be a property group, it must inherit from property_group. You could also
+// use the PropertGroupWrapper to create properties without inheriting, but it isn't as nice to work with,
+// and I don't have any examples here. We currently only use it to create logical property groups under an
+// existing property group that don't have an object to match up with them. I probably need to make an
+// example to have that make any sense.
+class test_group : public property_group
+{
+public:
+ enum eExample
+ {
+ Example1,
+ Example2
+ };
+
+ // The property_group constructor requires you to give the class a name and it's parent property_group if
+ // it has one. The name is used by the property system for path based lookups, but our code uses it,
+ // especially in the property debugging user interface. If your object never has a parent property group,
+ // as is the case here, default it to NULL and it will become a root property group. To see an example
+ // of parenting, see the definition of SubGroup above, and the use below. If you wanted to make SubGroup
+ // a root property group, you would just pass it NULL as parent.
+ //
+ // A root property group is one that shows up in the root list in property_manager. This has important
+ // implications in tree iteration and path lookup.
+ test_group() : property_group("test_group", NULL),
+ a_sub_group(this)
+ {
+ // Setup default values for our variables.
+ name = "Hello World!";
+ iVal = 123;
+ fFloat = 0.0f;
+
+ // Simple hooking up of getter/setters as properties
+ add_property<string>("Name", "name", BOOST_SETTER(&test_group::SetName), BOOST_GETTER(&test_group::GetName));
+ add_property<int>("iVal", "name", BOOST_SETTER(&test_group::SetIVal), BOOST_GETTER(&test_group::GetIVal));
+
+ // Slightly more advanced. Converts a function that takes two parameters into multiple valid getters
+ // for the property system by hard-coding one of the values passed in.
+ add_property<int>("example1", "name", BOOST_SETTER_NONE, boost::bind(&test_group::GetExample, this, Example1));
+ add_property<int>("example2", "name", BOOST_SETTER_NONE, boost::bind(&test_group::GetExample, this, Example2));
+
+ // Here is an example of how to expose a variable without associated getter/setter functions
+ add_property<float>("variable", "name", BOOST_SETTER_VAR(fFloat), BOOST_GETTER_VAR(fFloat));
+ }
+
+ string GetName()
+ {
+ return name;
+ }
+
+ void SetName(string newName)
+ {
+ name = newName;
+ }
+
+ int GetExample(eExample eVal)
+ {
+ switch(eVal)
+ {
+ case Example1:
+ return 1;
+ case Example2:
+ return 2;
+ }
+
+ return 0;
+ }
+
+ int GetIVal()
+ {
+ return iVal;
+ }
+
+ void SetIVal(int value)
+ {
+ iVal = value;
+ }
+
+ float fFloat;
+ string name;
+ int iVal;
+ SubGroup a_sub_group;
+};
+
+int main (int argc, char * const argv[])
+{
+ test_group test;
+
+ // This is an example of basic runtime type-safe property accessors (get/set)
+ cout << test.get<string>("Name") << endl;
+ test.set("Name", string("newName"));
+ cout << test.get<string>("Name") << endl;
+
+ // This is an example of accessors that return strings for all types. This is very
+ // useful when you need to write code that doesn't know anything about the types
+ // it is processing over. Examples of this are generic user interfaces that show
+ // all the property groups and their properties in the system so that they can be
+ // manipulated when the system is running. The UI can't know what the types are, but
+ // using this method it can still display them, and allow them to be changed.
+ string i = test.get_as_string("iVal");
+ cout << "Fetched by string: " << i << endl;
+ test.set_as_string("iVal", "20");
+ i = test.get_as_string("iVal");
+ cout << "Fetched by string: " << i << endl;
+
+ // This is an example of an accessor that is getting data from a function that isn't
+ // a simple getter function. Each one of these properties is actually calling the same
+ // function, but with different default parameters passed in. See the definition of
+ // test_group for more details.
+ cout << "Example1: " << test.get<int>("example1") << endl;
+ cout << "Example2: " << test.get<int>("example2") << endl;
+
+ // This is fetching from a property that is exposing a variable directly. There aren't any
+ // getter/setter methods for it, though you could add them later if you needed to change
+ // the default behavior and the users wouldn't have to change.
+ test.set("variable", 1.234567f);
+ cout << "Fetched wrapped variable: " << test.get<float>("variable") << endl;
+
+ // Here is an example of fetching a child property group based on a search path. The
+ // You can also iterate through all the children, and thus walk the entire property
+ // tree if you would like, or if you're code doesn't know what the hierarchy looks like
+ // when it is compiled.
+ property_group* found_property_group = select_single_node(test, "SubGroup.Name=SubGroup");
+ cout << "Subproperty_group Name: " << found_property_group->get<string>("Name") << endl;
+
+ // Here is an example of the above, but using a full path from the root of the property
+ // group tree. Note that we use the value "newName" for Name since we changed the name
+ // in an earlier example.
+ found_property_group = select_single_node("/test_group.Name=newName/SubGroup.Name=SubGroup");
+ cout << "Subproperty_group Name: " << found_property_group->get<string>("Name") << endl;
+
+ // Here is an example of iterating through all the child propety groups.
+ // ** I don't like the way this works today, so I'm leaving the example out for now.
+
+ // Here we see that we can get to the test_group instance from the property_manager.
+ property_manager* manager = property_manager::instance();
+
+ // Here is an example of iterating through all the root propety groups.
+ property_manager::iterator itrRoot = manager->begin();
+ property_manager::iterator itrRootEnd = manager->end();
+ for( ; itrRoot != itrRootEnd; ++itrRoot )
+ {
+ cout << "Found Root Item: " << (*itrRoot)->get_name() << endl;;
+ }
+
+ // All properties can have metadata associated to them. In the current form we store
+ // instances of the Editor class with each property (see "Areas that need work" below
+ // for where I admit this is too specific of a design). If you don't specify the Editor
+ // object in your call to add_property, the property system tries to find a default Editor
+ // based on the property type. None of the above examples specify an Editor, so they are
+ // all defaulted.
+ //
+ // Here is an example of accessing metadata for a specified property.
+ // ** I don't like the way this works today, so I'm leaving the example out for now.
+
+ /*
+ Areas that need work:
+
+ 1) Generic Metadata: Properties need to have metadata associated with them so that the system can learn more about
+ them. However, this metadata is system specific. I don't want to force everyone to use my metadata, when they will
+ likely need something completely different. Currently the property system is built for our simulation's needs, so
+ this metadata is hardcoded to the types it wants. This needs to be made generic. Perhaps use boost::any or maybe
+ an additional key/value pair component would work. Either way, it would be nice to try to keep the auto-selection of
+ metadata that already exists in the system.
+
+ 2) Extra Type Specification: There has to be a way to derive the type from the functions when you call add_property.
+ It is really ugly to have to specify it every time.
+
+ 2) Algorithms: We currently only have one path based search algorithm. This expects a single matching value and
+ throws otherwise. This is a useful search algorithm as is, but we need more. We need one that returns iterators
+ over all the items found. We need a version of that that returns them as they exist in the system, and one that
+ returns them sorted based on a given criteria. I also imagine there may be other algorithms for processing entire
+ property trees, or sub-trees. For example, we have a serialization algorithm that walks the entire tree and stores
+ the values of all properties. Given the same tree structure, it can re-walk the tree and set the values to their
+ stored values.
+
+ 3) More compile time optimizations: There are a lot of powerful things you can do by creating properties at runtime.
+ However, our experience shows that most properties are simple, and everything about them is known at compile time.
+ There should be some template mechanism we could use for creating this type of property that would reduce the amount
+ of time that is used at runtime to setup the property without reducing the utility of the system to create properties
+ purely at runtime.
+
+ 4) Property Manager Singleton: Currently the property manager is a singleton. This has been extremely helpful in
+ allowing us to build out the full property group tree and access it from anywhere. However, some people have
+ an aversion to this pattern, and there are cases where you may want multiple managers (if you have multiple copies
+ of your data layer, you probably don't want all those copies combined into the same property group tree). We haven't
+ really thought much further on how to do this better and are looking for insights.
+
+ 5) Safe Property Group: This is something I've been toying around with for a while. Currently it is advantagious to
+ get a property group and hold on to it. However, since property groups are retrieved largely as pointers, this can
+ be dangerious. I can't use shared_ptr since the object that it is pointing to may have been created on the stack,
+ and it won't have control over deletion (among other issues). I have a prototype class that wraps the property group
+ and listens to the property manager to see when it is destroyed, but I'm not sure I like that idea (and it is part of
+ our C++/CLI wrapper, so it isn't something I can share).
+
+ 6) Documentation: We currently have doxygen documented objects for this code. If we are going to submit to boost, we
+ would need quickbook docs on top of that that show how to use everything.
+
+ 7) Unit Tests: We currently have an entire set of unit tests for this code, but it uses UnitTest++. We'd need to
+ convert this to Boost::Test to submit it. This shouldn't be too hard.
+
+ Discussion Points:
+
+ 1) Header Files: I'm distributing this as header only. I did this since it simplified initial distribution (I didn't have
+ to get bjam working right away). In house, we build a library. There a lot of things that can be hidden from the user,
+ including defineing the static instances of the singeltons, if we use a library.
+
+ 2) Right now we have several different begin/end function pairs in property_group for accessing the different data in
+ the system. Is that really the best way to do it? Whould we be passing back const references to the collections instead?
+ If we did that, then what dop we do about retrieving a list of all the property names. That is really just keys to a map,
+ but we can hide that complexity from the user using the technique we use now.
+
+ Dreams:
+
+ 1) Events: Wouldn't it be cool if you could hook to an event that was fired whenever a specified property value
+ changed. Since the system is really just wrapping existing function calls, I haven't come up with a way to do this
+ that doesn't add a lot of work to property implementers, and would have high risk of being buggy. Any ideas?
+
+ 2) Thread Safety: Since the system is really just wrapping existing function calls, any thread safety is tied to
+ those function calls. I currently have no way of exposing complex techniques. Any ideas?
+ */
+
+ return 0;
+}
Added: sandbox/pinhole/boost/pinhole/map_key_value_iterators.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/map_key_value_iterators.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,126 @@
+// MscProperty system map_key_value_iterators.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MAP_KEY_VALUE_ITERATORS
+#define BOOST_MAP_KEY_VALUE_ITERATORS
+
+#pragma warning(push)
+#pragma warning(disable: 4561 4996)
+#include <boost/iterator.hpp>
+#include <boost/iterator/iterator_adaptor.hpp>
+#include <boost/iterator/iterator_categories.hpp>
+
+#include <boost/type_traits/is_pointer.hpp>
+#include <boost/static_assert.hpp>
+#pragma warning(pop)
+
+namespace boost { namespace pinhole
+{
+ template <class Reference, class Iterator>
+ class map_key_iterator;
+
+ namespace map_key_iterator_detail
+ {
+ template <class Reference, class Iterator>
+ struct iterator_base
+ {
+ typedef boost::iterator_adaptor<
+ map_key_iterator<Reference, Iterator>
+ , Iterator // Base
+ , boost::use_default // Value
+ , boost::use_default//boost::forward_traversal_tag // CategoryOrTraversal
+ , Reference
+ > type;
+ };
+ }
+
+ /** Iterates over all the keys in a map. */
+ template <class Reference, class Iterator>
+ class map_key_iterator
+ : public map_key_iterator_detail::iterator_base<Reference, Iterator>::type
+ {
+ private:
+ struct enabler {}; // a private type avoids misuse
+
+ typedef typename map_key_iterator_detail::iterator_base<
+ Reference, Iterator
+ >::type super_t;
+
+ friend class iterator_core_access;
+
+ public:
+ map_key_iterator() { }
+
+ map_key_iterator( Iterator x, Iterator end = Iterator()) : super_t(x) { }
+
+ Reference dereference() const
+ {
+ return (*this->base()).first;
+ }
+ };
+
+ /** Factory for creating map_key_iterator iterators. */
+ template <class Reference, class Iterator>
+ map_key_iterator<Reference, Iterator>
+ make_map_key_iterator(Iterator x, Iterator end = Iterator())
+ {
+ return map_key_iterator<Reference,Iterator>(x,end);
+ }
+
+ template <class Reference, class Iterator>
+ class map_value_iterator;
+
+ namespace map_value_iterator_detail
+ {
+ template <class Reference, class Iterator>
+ struct iterator_base
+ {
+ typedef boost::iterator_adaptor<
+ map_value_iterator<Reference, Iterator>
+ , Iterator // Base
+ , boost::use_default // Value
+ , boost::use_default//boost::forward_traversal_tag // CategoryOrTraversal
+ , Reference
+ > type;
+ };
+ }
+
+ /** Iterates over all the keys in a map. */
+ template <class Reference, class Iterator>
+ class map_value_iterator
+ : public map_value_iterator_detail::iterator_base<Reference, Iterator>::type
+ {
+ private:
+ struct enabler {}; // a private type avoids misuse
+
+ typedef typename map_value_iterator_detail::iterator_base<
+ Reference, Iterator
+ >::type super_t;
+
+ friend class iterator_core_access;
+
+ public:
+ map_value_iterator() { }
+
+ map_value_iterator( Iterator x, Iterator end = Iterator()) : super_t(x) { }
+
+ Reference dereference() const
+ {
+ return (*this->base()).second;
+ }
+ };
+
+ /** Factory for creating map_value_iterator iterators. */
+ template <class Reference, class Iterator>
+ map_value_iterator<Reference, Iterator>
+ make_map_value_iterator(Iterator x, Iterator end = Iterator())
+ {
+ return map_value_iterator<Reference,Iterator>(x,end);
+ }
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/property_group.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/property_group.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,680 @@
+// MscProperty system property_group.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROPERTY_GROUP
+#define BOOST_PROPERTY_GROUP
+
+#include "map_key_value_iterators.h"
+#include "EditorTypeFinder.h"
+#include "property_info.h"
+#include "action_info.h"
+#include "property_manager.h"
+#include <set>
+#include <list>
+#include <sstream>
+
+#pragma warning(push)
+#pragma warning( disable: 4561)
+#include <boost/bind.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/function.hpp>
+#include <boost/any.hpp>
+#pragma warning(pop)
+
+#define BOOST_SETTER(c) boost::bind(c, this, _1)
+#define BOOST_GETTER(c) boost::bind(c, this)
+#define BOOST_ACTION(c) boost::bind(c, this)
+
+namespace boost { namespace pinhole
+{
+ template<typename T>
+ struct property_system_var_setter
+ {
+ typedef T result_type;
+
+ property_system_var_setter(T &t) : var(t){}
+
+ void operator()(const T &value)
+ {
+ var = value;
+ }
+
+ T &var;
+ };
+
+ template<typename T>
+ inline boost::function<void (const T&)> property_system_var_setter_builder(T &t)
+ {
+ return boost::bind<void>(property_system_var_setter<T>(t), _1);
+ }
+
+ #define BOOST_SETTER_VAR(c) property_system_var_setter_builder(c)
+
+ template<typename T>
+ struct property_system_var_getter
+ {
+ typedef T result_type;
+
+ property_system_var_getter(T &t) : var(t){}
+
+ T operator()()
+ {
+ return var;
+ }
+
+ T &var;
+ };
+
+ template<typename T>
+ inline boost::function<T ()> property_system_var_getter_builder(T &t)
+ {
+ return boost::bind<T>(property_system_var_getter<T>(t));
+ }
+
+ #define BOOST_GETTER_VAR(c) property_system_var_getter_builder(c)
+
+ #define BOOST_SETTER_NONE NULL
+ #define BOOST_GETTER_NONE NULL
+
+ class property_group;
+
+ typedef std::set<std::string> category_collection;
+ typedef std::list<property_group*> children_collection;
+ typedef std::map<std::string, detail::property_info_base*> property_collection;
+ typedef std::map<std::string, detail::action_info*> action_collection;
+
+ /**
+ * Manages a list of properties for an object. A property is defined by a
+ * string that is unique to the object and a set of getter and setter
+ * functions that set and retrieve values.
+ */
+ class property_group
+ {
+ public:
+ /**
+ * Constructor.
+ * @param name The name of this property group
+ * @param parent The parent of the this object or NULL if it is a root group.
+ */
+ property_group( std::string name, property_group *parent=NULL ) :
+ m_name( name ),
+ m_parent( parent )
+ {
+ setup_parent_and_category_and_manager();
+ }
+
+ explicit property_group( const property_group& old_property_group )
+ {
+ m_name = old_property_group.m_name;
+ m_parent = old_property_group.m_parent;
+
+ setup_parent_and_category_and_manager();
+ }
+
+ /** Destructor. */
+ virtual ~property_group()
+ {
+ // Calling OnParentDeleting will likely modify m_children_collection,
+ // so we can't use it directly.
+ children_collection temp_child(m_children_collection);
+ children_collection::iterator childIter = temp_child.begin();
+ children_collection::iterator childIterEnd = temp_child.end();
+ for( ; childIter != childIterEnd; ++childIter )
+ {
+ (*childIter)->set_parent(NULL);
+ }
+ temp_child.clear();
+
+ if ( NULL != m_parent )
+ {
+ m_parent->remove_child(this);
+ }
+
+ if ( property_manager::instance() != NULL )
+ {
+ // Unregister this group with this property manager...
+ property_manager::instance()->unregister_property_group( this, m_category_collection );
+ }
+
+ // cleanup all the property_manager classes
+ property_collection::iterator propItr = m_properties.begin();
+ property_collection::iterator propItrEnd = m_properties.end();
+ for( ; propItr != propItrEnd; ++propItr )
+ {
+ delete (*propItr).second;
+ (*propItr).second = NULL;
+ }
+ m_properties.clear();
+
+ // cleanup all the action classes
+ action_collection::iterator actionItr = m_actions.begin();
+ action_collection::iterator actionItrEnd = m_actions.end();
+ for( ; actionItr != actionItrEnd; ++actionItr )
+ {
+ delete (*actionItr).second;
+ (*actionItr).second = NULL;
+ }
+ m_actions.clear();
+ }
+
+
+ /**
+ * Gets the parent of this property group.
+ * @return The parent of this property group.
+ */
+ property_group* get_parent() const
+ {
+ return( m_parent );
+ }
+
+ /**
+ * Sets the parent of this property group.
+ * @param new_parent The new parent of this property group.
+ */
+ void set_parent(property_group* new_parent)
+ {
+ if( NULL != property_manager::instance() )
+ {
+ // Register this group with this property manager...
+ property_manager::instance()->unregister_property_group(this, m_category_collection);
+ }
+
+ if ( NULL != m_parent )
+ {
+ m_parent->remove_child(this);
+ }
+
+ m_parent = new_parent;
+
+
+ if ( NULL != m_parent )
+ {
+ m_parent->add_child(this);
+ }
+
+ if( NULL != property_manager::instance() )
+ {
+ // Register this group with this property manager...
+ property_manager::instance()->register_property_group(this);
+ }
+ }
+
+ /**
+ * Gets the name of this property group.
+ * @return The name of this property group.
+ */
+ const std::string get_name() const
+ {
+ return( m_name );
+ }
+
+ /**
+ * Gets the category collection of this property group.
+ * @return The category collection of this property group.
+ * @todo Remove this accessor
+ */
+ const category_collection& get_category_collection()
+ {
+ return( m_category_collection );
+ }
+
+ /**
+ * Gets the property group children collection of this property group.
+ * @return The property group children collection of this property group.
+ * @todo Remove this accessor
+ */
+ children_collection& get_children_collection()
+ {
+ return( m_children_collection );
+ }
+
+ /** @name Properties */
+ //@{
+ typedef property_collection::size_type prop_size_type;
+ typedef map_key_iterator<std::string, property_collection::iterator> prop_iterator;
+ typedef map_key_iterator<std::string, property_collection::const_iterator> const_prop_iterator;
+
+ /**
+ * Retrieves an iterator pointing to the name of the first property.
+ */
+ prop_iterator prop_begin()
+ {
+ return make_map_key_iterator<string>( m_properties.begin() );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the name of the first property.
+ */
+ const_prop_iterator prop_begin() const
+ {
+ return make_map_key_iterator<string>( m_properties.begin() );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the property list.
+ */
+ prop_iterator prop_end()
+ {
+ return make_map_key_iterator<string>( m_properties.end() );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the property list.
+ */
+ const_prop_iterator prop_end() const
+ {
+ return make_map_key_iterator<string>( m_properties.end() );
+ }
+
+ /**
+ * Retrieves the number of properties.
+ */
+ prop_size_type prop_count() const
+ {
+ return m_properties.size();
+ }
+
+ /**
+ * Gets a property's value by it's type.
+ * @param property The name of the property.
+ * @return The value of the property.
+ * @throw boost::bad_function_call There isn't a get_as_string function associated with this property.
+ * @throw std::out_of_range The property requested does not exist.
+ * @throw std::bad_cast The requested return_type was not the same as the property's type.
+ */
+ template<typename Return_Type>
+ Return_Type get(const std::string &property) const
+ {
+ // The system does not allow you to use pointers as property
+ // types due to the ambiguity of their use.
+ BOOST_STATIC_ASSERT(false == boost::is_pointer<Return_Type>::value);
+
+ property_collection::const_iterator itemItr = m_properties.find(property);
+
+ if( m_properties.end() != itemItr )
+ {
+ detail::property_info_base* propInfo = (*itemItr).second;
+
+ // throws boost::bad_function_call if there isn't a get_as_string
+ // function associated with this property.
+ if( NULL != propInfo && typeid(Return_Type) == propInfo->m_type )
+ {
+ return static_cast<detail::property_info<Return_Type>*>(propInfo)->getter();
+ }
+
+ throw std::bad_cast();
+ }
+
+ stringstream err;
+ err << "The requested property \"" << property << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+
+ /**
+ * Sets a property's value.
+ * @param property The name of the property.
+ * @param value The value to set on the property.
+ * @throw boost::bad_function_call There isn't a set_as_string function associated with this property.
+ * @throw std::out_of_range The property requested does not exist.
+ * @throw std::bad_cast The Set_Type was not the same as the property's type.
+ */
+ template<typename Set_Type>
+ void set(const std::string &property, Set_Type value) const
+ {
+ // The system does not allow you to use pointers as property
+ // types due to the ambiguity of their use.
+ BOOST_STATIC_ASSERT(false == boost::is_pointer<Set_Type>::value);
+
+ property_collection::const_iterator itemItr = m_properties.find(property);
+
+ if( m_properties.end() != itemItr )
+ {
+ detail::property_info_base* propInfo = (*itemItr).second;
+
+ // throws boost::bad_function_call if there isn't a get_as_string
+ // function associated with this property.
+ if( NULL != propInfo && typeid(Set_Type) == propInfo->m_type )
+ {
+ return static_cast<detail::property_info<Set_Type>*>(propInfo)->setter(value);
+ }
+
+ throw std::bad_cast();
+ }
+
+ stringstream err;
+ err << "The requested property \"" << property << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+
+ /**
+ * Sets a property's value.
+ * @param property The name of the property.
+ * @param value A String representation of the value to set on the property.
+ * @throw boost::bad_function_call There isn't a set_as_string function associated with this property.
+ * @throw std::out_of_range The property requested does not exist.
+ * @throw std::invalid_argument The value string could not be converted to the
+ * type expected by the internal setter function.
+ */
+ void set_as_string(const std::string &property, const std::string &value)
+ {
+ property_collection::iterator itemItr = m_properties.find(property);
+
+ if( m_properties.end() != itemItr )
+ {
+ // throws boost::bad_function_call if there isn't a set_as_string
+ // function associated with this property.
+ (*itemItr).second->set_as_string(value);
+ }
+ else
+ {
+ stringstream err;
+ err << "The requested property \"" << property << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+ }
+
+ /**
+ * Gets a property's value.
+ * @param property The name of the property.
+ * @return A String representation of the value of the property.
+ * @throw boost::bad_function_call There isn't a get_as_string function associated with this property.
+ * @throw std::out_of_range The property requested does not exist.
+ */
+ std::string get_as_string(const std::string &property) const
+ {
+ property_collection::const_iterator itemItr = m_properties.find(property);
+
+ if( m_properties.end() != itemItr )
+ {
+ // throws boost::bad_function_call if there isn't a get_as_string
+ // function associated with this property.
+ return (*itemItr).second->get_as_string();
+ }
+
+ stringstream err;
+ err << "The requested property \"" << property << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+
+ /**
+ * Gets a property's Editor object.
+ * @param property The name of the property.
+ * @return The Editor of the property.
+ * @throw no_metadata_defined_error There isn't a property editor associated with this property.
+ * @throw std::out_of_range The property requested does not exist.
+ */
+ const Editor* get_metadata(const std::string &property) const
+ {
+ property_collection::const_iterator itemItr = m_properties.find(property);
+
+ if( itemItr != m_properties.end() )
+ {
+ // throws boost::bad_function_call if there isn't a get
+ // function associated with this property.
+ if ( (*itemItr).second->m_editor == NULL )
+ {
+ throw( no_metadata_defined_error() );
+ }
+ else
+ {
+ return( (*itemItr).second->m_editor );
+ }
+ }
+ else
+ {
+ stringstream err;
+ err << "The requested property \"" << property << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+ }
+
+ /**
+ * Gets a property's type_info structure.
+ * @param property The name of the property.
+ * @return The type_info structure of the property.
+ * @throw std::out_of_range The property requested does not exist.
+ */
+ const type_info& get_type_info(const std::string &property) const
+ {
+ property_collection::const_iterator itemItr = m_properties.find(property);
+
+ if( itemItr != m_properties.end() )
+ {
+ return (*itemItr).second->m_type;
+ }
+ else
+ {
+ stringstream err;
+ err << "The requested property \"" << property << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+ }
+
+ /**
+ * Retrieves whether the property is read only or not.
+ * @param property The name of the property.
+ * @retval true The property is read only.
+ * @retval false The property is writeable.
+ * @throw std::out_of_range The property requested does not exist.
+ */
+ bool is_read_only(const std::string &property) const;
+ //@}
+
+ /** @name Actions */
+ //@{
+ typedef action_collection::size_type action_size_type;
+ typedef map_key_iterator<std::string, action_collection::iterator> action_iterator;
+ typedef map_key_iterator<std::string, action_collection::const_iterator> const_action_iterator;
+
+ /**
+ * Retrieves an iterator pointing to the name of the first property.
+ */
+ action_iterator action_begin()
+ {
+ return make_map_key_iterator<string>( m_actions.begin() );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the name of the first property.
+ */
+ const_action_iterator action_begin() const
+ {
+ return make_map_key_iterator<string>( m_actions.begin() );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the property list.
+ */
+ action_iterator action_end()
+ {
+ return make_map_key_iterator<string>( m_actions.end() );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the property list.
+ */
+ const_action_iterator action_end() const
+ {
+ return make_map_key_iterator<string>( m_actions.end() );
+ }
+
+ /**
+ * Retrieves the number of properties.
+ */
+ action_size_type action_count() const
+ {
+ return m_actions.size();
+ }
+
+ /**
+ * Triggers an action.
+ * @param action The name of the action.
+ * @throw std::out_of_range The property requested does not exist.
+ */
+ void trigger(const std::string &action) const
+ {
+ action_collection::const_iterator itemItr = m_actions.find(action);
+
+ if( m_actions.end() != itemItr )
+ {
+ // throws boost::bad_function_call if there isn't a set
+ // function associated with this property.
+ (*itemItr).second->trigger();
+ }
+ else
+ {
+ stringstream err;
+ err << "The requested action \"" << action << "\" does not exist.";
+ throw std::out_of_range(err.str().c_str());
+ }
+ }
+
+ //@}
+
+ protected:
+
+ /**
+ * Adds a property to the property list.
+ * @param The name of the property.
+ * @param description A brief description of the property for the user interface.
+ * @param setter The function used to set the property.
+ * @param getter The function used to get the property.
+ */
+ template<typename Value_Type>
+ void add_property( std::string name,
+ std::string description,
+ boost::function<void (const Value_Type&)> setter,
+ boost::function<Value_Type ()> getter )
+ {
+ typedef typename detail::EditorTypeFinder<Value_Type>::type editor_type;
+
+ // You are using a Value_Type that does not have a default editor defined. Use once
+ // of the add_property functions where you explicitly define the editor or editor type.
+ BOOST_STATIC_ASSERT((false == boost::is_same<editor_type, boost::mpl::void_>::value));
+
+ add_property<Value_Type>( name, description, setter, getter, new editor_type() );
+ }
+
+ /**
+ * Adds a property to the property list.
+ * @param The name of the property.
+ * @param description A brief description of the property for the user interface.
+ * @param setter The function used to set the property.
+ * @param getter The function used to get the property.
+ * @param pEditor A pointer to the editor to be used with this property, or null
+ * if there isn't one.
+ */
+ template<typename Value_Type>
+ void add_property( std::string name,
+ std::string description,
+ boost::function<void (const Value_Type&)> setter,
+ boost::function<Value_Type ()> getter,
+ Editor *pEditor )
+ {
+ // If you get an error here, then the type you are using for the property likely doesn't have a proper operator<< for it
+ detail::property_info<Value_Type> *prop = new detail::property_info<Value_Type>();
+
+ prop->m_name = name;
+ prop->m_description = description;
+ if( BOOST_SETTER_NONE != setter )
+ {
+ prop->setter = setter;
+ }
+ if( BOOST_GETTER_NONE != getter )
+ {
+ prop->getter = getter;
+ }
+ prop->m_editor = pEditor;
+
+ m_properties.insert( std::make_pair(name, prop) );
+ }
+
+ /**
+ * Adds an action to the action list.
+ * @param The name of the action.
+ * @param description A brief description of the action for the user interface.
+ * @param action The function used to trigger the action.
+ */
+ void add_action( std::string name,
+ std::string description,
+ boost::function<void ()> action )
+ {
+ detail::action_info *action_info = new detail::action_info();
+
+ action_info->m_name = name;
+ action_info->m_description = description;
+ action_info->m_action = action;
+
+ m_actions.insert( std::make_pair(name, action_info) );
+ }
+
+ /**
+ * Adds this property to the specified category.
+ * @param category_name The name of the category to add.
+ */
+ void add_category( const std::string &category_name )
+ {
+ m_category_collection.insert( category_name );
+
+ // notify the Property Manager of this new category
+ if ( property_manager::instance() != NULL )
+ {
+ property_manager::instance()->add_category( category_name, this );
+ }
+ }
+
+ #pragma warning(push)
+ #pragma warning( disable: 4251 )
+ category_collection m_category_collection;
+ children_collection m_children_collection;
+ property_collection m_properties;
+ action_collection m_actions;
+ #pragma warning(pop)
+
+ private:
+ property_group();
+
+ void add_child(property_group* pChild)
+ {
+ if( NULL != pChild )
+ {
+ m_children_collection.push_back( pChild );
+ }
+ }
+
+ void remove_child(property_group* pChild)
+ {
+ if( NULL != pChild )
+ {
+ m_children_collection.remove(pChild);
+ }
+ }
+
+ void setup_parent_and_category_and_manager()
+ {
+ if ( NULL != m_parent )
+ {
+ m_parent->add_child(this);
+ }
+
+ add_category( "All" );
+
+ if ( property_manager::instance() != NULL )
+ {
+ // Register this group with this property manager...
+ property_manager::instance()->register_property_group( this );
+ }
+ }
+
+ std::string m_name;
+ property_group *m_parent;
+ };
+
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/property_group_wrapper.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/property_group_wrapper.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,100 @@
+// MscProperty system property_group_wrapper.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROPERTY_GROUP_WRAPPER
+#define BOOST_PROPERTY_GROUP_WRAPPER
+
+#include "property_group.h"
+
+namespace boost { namespace pinhole
+{
+ /**
+ * The property_group_wrapper allows you to create property groups without inheriting directly
+ * from property_group. This allows you to do things like create groups of properties for
+ * display in the UI that don't have a matching logical object in the system.
+ */
+ class property_group_wrapper : public property_group
+ {
+ public:
+ /**
+ * Constructor.
+ * @param name The name of this property group (like an xml node name)
+ * @param parent The parent of the this object.
+ */
+ property_group_wrapper(std::string name, property_group *parent) :
+ : property_group(name, parent){;}
+
+ ~property_group_wrapper(void){;}
+
+ /**
+ * Adds a property to the property list.
+ * @param The name of the property.
+ * @param description A brief description of the property for the user interface.
+ * @param setter The function used to set the property.
+ * @param getter The function used to get the property.
+ */
+ template<typename Value_Type>
+ void add_property( std::string name,
+ std::string description,
+ boost::function<void (const Value_Type&)> setter,
+ boost::function<Value_Type ()> getter )
+ {
+ property_group::add_property<Value_Type>( name, description,setter, getter );
+ }
+
+ /**
+ * Adds a property to the property list.
+ * @param The name of the property.
+ * @param description A brief description of the property for the user interface.
+ * @param setter The function used to set the property.
+ * @param getter The function used to get the property.
+ * @param pEditor A pointer to the editor to be used with this property, or null
+ * if there isn't one.
+ */
+ template<typename Value_Type>
+ void add_property( std::string name,
+ std::string description,
+ boost::function<void (const Value_Type&)> setter,
+ boost::function<Value_Type ()> getter,
+ Editor *pEditor )
+ {
+
+ property_group::add_property<Value_Type>( name, description,setter, getter, pEditor );
+ }
+
+ /**
+ * Adds an action to the action list.
+ * @param The name of the action.
+ * @param description A brief description of the action for the user interface.
+ * @param action The function used to trigger the action.
+ */
+ inline void add_action( std::string name,
+ std::string description,
+ boost::function<void ()> action )
+ {
+
+ property_group::add_action( name, description, action );
+ }
+
+ /**
+ * Gets an xml string representation of this property group
+ * @param string The name of the new category.
+ * @return The xml string representation of this property group.
+ */
+ inline void add_category( const std::string &category_name )
+ {
+ property_group::add_category( category_name );
+ }
+
+ private:
+ property_group_wrapper() : property_group("", NULL) {;}
+ property_group_wrapper(const property_group& object) : property_group(object) {;}
+ property_group_wrapper(const property_group_wrapper& object) : property_group(object) {;}
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/property_info.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/property_info.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,236 @@
+// MscProperty system property_manager.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROPERTY_INFO
+#define BOOST_PROPERTY_INFO
+
+#pragma warning(push)
+#pragma warning( disable: 4272 4394 )
+#include "Editor.h"
+#pragma warning(pop)
+
+#pragma warning(push)
+#pragma warning( disable: 4561 4793 )
+#include <boost/type_traits.hpp>
+#include <boost/function.hpp>
+#include <boost/lexical_cast.hpp>
+#pragma warning(pop)
+
+namespace boost { namespace pinhole { namespace detail
+{
+ #define BOOL_TRUE ("True")
+ #define BOOL_FALSE ("False")
+
+ ///////////////////////////////////////////////////
+ // set_as_string Override Functors
+ ///////////////////////////////////////////////////
+
+ /**
+ * The default setter processor. This uses lexical cast
+ * to convert the passed in set string to any type that
+ * has proper stream operators.
+ */
+ template<typename Value_Type>
+ struct internal_string_set
+ {
+ template<typename Set_Type>
+ inline void operator()( Set_Type setter, std::string value )
+ {
+ try
+ {
+ setter( boost::lexical_cast<Value_Type>(value) );
+ }
+ catch(boost::bad_lexical_cast &)
+ {
+ std::stringstream err;
+ err << "The value '" << value << "' is not valid for this property.";
+ throw std::invalid_argument(err.str().c_str());
+ }
+ }
+ };
+
+ /**
+ * Setter for handling string types. Since a string was passed in, and
+ * the type in the setter function is a string, we don't need to do any
+ * conversion.
+ */
+ template<>
+ struct internal_string_set<std::string>
+ {
+ template<typename Set_Type>
+ inline void operator()( Set_Type setter, std::string value )
+ {
+ setter( value );
+ }
+ };
+
+
+ /**
+ * Setter for handling bool types. Since a bool was passed in,
+ * we need to convert
+ */
+ template<>
+ struct internal_string_set<bool>
+ {
+ template<typename Set_Type>
+ inline void operator()( Set_Type setter, std::string value )
+ {
+ setter( value == BOOL_TRUE );
+ }
+ };
+
+ ///////////////////////////////////////////////////
+ // get_as_string Override Functors
+ ///////////////////////////////////////////////////
+
+ /**
+ * The default getter processor. This uses lexical cast
+ * to convert the returned value from the propertied
+ * getter function and convert to a string using
+ * lexical_cast. Any type that has proper stream operators
+ * should work.
+ */
+
+ template<typename Value_Type>
+ struct internal_string_get
+ {
+ template<typename Get_Type>
+ inline std::string operator()( Get_Type getter ) const
+ {
+ return boost::lexical_cast<string>( getter() );
+ }
+ };
+
+ /**
+ * Getter for handling string types. Since a string returned,
+ * and getter returns a string type, we don't need to do any
+ * conversion.
+ */
+ template<>
+ struct internal_string_get<std::string>
+ {
+ template<typename Get_Type>
+ inline std::string operator()( Get_Type getter ) const
+ {
+ return getter();
+ }
+ };
+
+ /**
+ * Getter for handling bool types. Since a string is returned,
+ * we need to convert the bool to a string.
+ */
+ template<>
+ struct internal_string_get<bool>
+ {
+ template<typename Get_Type>
+ inline std::string operator()( Get_Type getter ) const
+ {
+ return( getter() ? "True" : "False" );
+ }
+ };
+
+ struct property_info_base
+ {
+ public:
+ property_info_base(const type_info &type) :
+ m_editor( NULL ),
+ m_type(type)
+ {;}
+
+ virtual ~property_info_base()
+ {
+ if ( m_editor != NULL )
+ delete( m_editor );
+ }
+
+ std::string m_name;
+ std::string m_description;
+ Editor *m_editor;
+ const type_info &m_type;
+
+ virtual void set_as_string(std::string value) = 0;
+ virtual std::string get_as_string() const = 0;
+ virtual bool is_read_only() const = 0;
+ };
+
+ template<typename T>
+ struct property_info : property_info_base
+ {
+ private:
+
+ public:
+ typedef typename boost::remove_reference<T>::type Value_Type;
+ typedef boost::function<void (const Value_Type&)> setter_type;
+ typedef boost::function<Value_Type ()> getter_type;
+
+ // The system does not allow you to use pointers as property
+ // types due to the ambiguity of their use.
+ BOOST_STATIC_ASSERT(false == boost::is_pointer<Value_Type>::value);
+
+ setter_type setter;
+ getter_type getter;
+
+ property_info() : property_info_base(typeid(T)) {;}
+
+ /**
+ * Calls the appropriate getter function for this parameter and converts
+ * the value to a string for return.
+ *
+ * @return A String representation of the value of the property.
+ * @throw boost::bad_function_call There isn't a get_as_string function associated with this property.
+ */
+ virtual std::string get_as_string() const
+ {
+ // If you get an error here, and it complains about:
+ // error C2679: binary '<<' : no operator found which takes a right-hand operand of type
+ // then the type you are using for the property doesn't have a proper operator<< for it
+ //
+ // throws boost::bad_function_call if there isn't a get_as_string function associated with this property.
+ return internal_string_get<Value_Type>()(getter);
+ }
+
+ /**
+ * Calls the appropriate setter function for this parameter and converts
+ * the passed in string to whatever type the setter is expect. For example,
+ * if the properties setter is expecting an int, the string will be
+ * converted to an int before being passed to the function.
+ * <br><br>
+ * We call an internal setter in a struct so that we can override
+ * what the set does based on the type of Value_Type. For example,
+ * we wanted to write a special handler for the string type for
+ * performance, so we overrode the string handler in "struct Internal<string>"
+ * to just pass the string along instead of convert it. The beauty of doing it
+ * this way is that there is no runtime cost. All functions are inlined,
+ * and the additional function calls and type processing are optimized out
+ * at compile time.
+ *
+ * @param value A String representation of the value to set on the property.
+ * @throw boost::bad_function_call There isn't a set_as_string function associated with this property.
+ * @throw std::invalid_argument The value string could not be converted to the
+ * type expected by the internal setter function.
+ */
+ virtual void set_as_string(std::string value)
+ {
+ // see the function documentation for more information about this.
+ //
+ // throws boost::bad_function_call if there isn't a set_as_string function associated with this property.
+ internal_string_set<Value_Type>()(setter, value);
+ }
+
+ /**
+ * Checks if this is a read-only property (ie, cant set)
+ * @return true if the property is read-only.
+ */
+ virtual bool is_read_only() const
+ {
+ return( !setter );
+ }
+ };
+}}}
+
+#endif // include guard
\ No newline at end of file
Added: sandbox/pinhole/boost/pinhole/property_manager.h
==============================================================================
--- (empty file)
+++ sandbox/pinhole/boost/pinhole/property_manager.h 2007-07-22 20:27:37 EDT (Sun, 22 Jul 2007)
@@ -0,0 +1,270 @@
+// MscProperty system property_manager.h file
+//
+// Copyright Jared McIntyre 2007.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_PROPERTY_MANAGER
+#define BOOST_PROPERTY_MANAGER
+
+#include "exceptions.h"
+#include <set>
+#include <string>
+
+#pragma warning(push)
+#pragma warning( disable: 4561 4793 )
+#include <boost/shared_ptr.hpp>
+#include <boost/signals.hpp>
+#include <boost/algorithm/string.hpp>
+#pragma warning(pop)
+
+namespace boost { namespace pinhole
+{
+ class property_group;
+
+ typedef std::set<std::string> category_collection;
+ typedef std::list<property_group*> children_collection;
+
+ class event_source
+ {
+ public :
+ static event_source* instance()
+ {
+ if ( m_instance == 0 ) // is it the first call?
+ {
+ m_instance = new event_source; // create sole instance
+ }
+
+ return m_instance; // address of sole instance
+ }
+
+ #pragma warning(push)
+ #pragma warning( disable: 4251 )
+ boost::signal<void(property_group*)> add_event;
+ boost::signal<void(property_group*)> remove_event;
+ #pragma warning(pop)
+ void raise_on_add_event( property_group *group )
+ {
+ add_event( group );
+ }
+
+ void raise_on_remove_event( property_group *group )
+ {
+ remove_event( group );
+ }
+
+ private :
+ static event_source *m_instance;
+ event_source(){};
+
+ };
+
+ class property_manager
+ {
+ private:
+ static void deleter(property_manager* manager)
+ {
+ delete manager;
+ }
+
+ public:
+ typedef multimap<string, property_group*> category_to_property_group_map;
+ typedef map_value_iterator<property_group*, category_to_property_group_map::iterator> iterator;
+ typedef map_value_iterator<property_group*, category_to_property_group_map::const_iterator> const_iterator;
+
+ static property_manager* instance()
+ {
+ if ( m_instance.get() == NULL ) // is it the first call?
+ {
+ m_instance.reset( new property_manager, property_manager::deleter ); // create sole instance
+ }
+
+ return m_instance.get(); // address of sole instance
+ }
+
+ static bool exists()
+ {
+ return m_instance.get() != NULL;
+ }
+
+ static void delete_instance()
+ {
+ if( m_instance.get() != NULL )
+ {
+ m_instance.reset();
+ }
+ }
+
+ protected:
+ property_manager(){;}
+
+ // TODO: This needs to be protected so no-one will deal with it, but
+ // checked_delete can't be made a friend in gcc, so I can't shared_ptr
+ // to work.
+ public:
+ ~property_manager()
+ {
+ category_to_property_group_map::iterator itr = m_property_group_collection.begin();
+ category_to_property_group_map::iterator itr_end = m_property_group_collection.end();
+ for( ; itr != itr_end; ++itr )
+ {
+ event_source::instance()->raise_on_remove_event((*itr).second);
+ }
+ }
+
+ public:
+ /**
+ * Retrieves an iterator pointing to the first property group.
+ */
+ iterator begin()
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.lower_bound("All"),
+ m_property_group_collection.upper_bound("All") );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the first property group.
+ */
+ const_iterator begin() const
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.lower_bound("All"),
+ m_property_group_collection.upper_bound("All") );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the root property list.
+ */
+ iterator end()
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.upper_bound("All") );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the root property list.
+ */
+ const_iterator end() const
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.upper_bound("All") );
+ }
+
+ /**
+ * Retrieves the number of property groups.
+ */
+ size_t count() const
+ {
+ return m_property_group_collection.count("All");
+ }
+
+ /**
+ * Retrieves an iterator pointing to the first property group for a specified category.
+ */
+ iterator begin(const string& strCategory)
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.lower_bound(strCategory) );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the first property group for a specified category.
+ */
+ const_iterator begin(const string& strCategory) const
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.lower_bound(strCategory) );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the root property list for a specified category.
+ */
+ iterator end(const string& strCategory)
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.upper_bound(strCategory) );
+ }
+
+ /**
+ * Retrieves an iterator pointing to the end of the root property list for a specified category.
+ */
+ const_iterator end(const string& strCategory) const
+ {
+ return make_map_value_iterator<property_group*>( m_property_group_collection.upper_bound(strCategory) );
+ }
+
+ /**
+ * Retrieves the number of property groups for a specified category.
+ */
+ size_t count(const string& strCategory) const
+ {
+ return m_property_group_collection.count(strCategory);
+ }
+
+ /**
+ * Gets the master category list.
+ * @return master category list.
+ */
+ const category_collection* get_category_collection()
+ {
+ return( &m_category_collection );
+ }
+
+ protected:
+ /**
+ * Register's group with the property_manager.
+ */
+ virtual void register_property_group( property_group *group )
+ {
+ event_source::instance()->raise_on_add_event( group );
+ }
+
+ /**
+ * Unregister's group from the property_manager.
+ */
+ virtual void unregister_property_group( property_group *group, category_collection &categories )
+ {
+ category_collection::const_iterator categoryItr = categories.begin();
+ category_collection::const_iterator categoryEnd = categories.end();
+ for ( ; categoryItr != categoryEnd; ++categoryItr )
+ {
+ remove_category( *categoryItr, group );
+ }
+
+ event_source::instance()->raise_on_remove_event( group );
+ }
+
+ /**
+ * Adds a new category for the property group.
+ */
+ virtual void add_category( const string &category_name, property_group *group )
+ {
+ m_category_collection.insert( category_name );
+ m_property_group_collection.insert( make_pair( category_name, group ) );
+ }
+
+ virtual void remove_category( const string &category_name, property_group *group )
+ {
+ category_to_property_group_map::iterator pgItr;
+ for ( pgItr = m_property_group_collection.find( category_name );
+ pgItr != m_property_group_collection.end(); )
+ {
+ if ( pgItr->second == group )
+ {
+ m_property_group_collection.erase( pgItr++ );
+ }
+ else
+ {
+ pgItr++;
+ }
+ }
+ }
+
+ protected:
+ #pragma warning(push)
+ #pragma warning( disable: 4251 )
+ static boost::shared_ptr<property_manager> m_instance;
+ category_to_property_group_map m_property_group_collection;
+ category_collection m_category_collection;
+ #pragma warning(pop)
+
+ friend class property_group;
+ };
+}}
+
+#endif // include guard
\ No newline at end of file
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk