introspectable.h

00001 /***************************************************************************
00002  *   Copyright (C) 2004 by Rick L. Vinyard, Jr.                            *
00003  *   rvinyard@cs.nmsu.edu                                                  *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation version 2.1.                *
00008  *                                                                         *
00009  *   This program is distributed in the hope that it will be useful,       *
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00012  *   GNU General Public License for more details.                          *
00013  *                                                                         *
00014  *   You should have received a copy of the GNU Lesser General Public      *
00015  *   License along with this library; if not, write to the                 *
00016  *   Free Software Foundation, Inc.,                                       *
00017  *   51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA              *
00018  ***************************************************************************/
00019 
00020 #ifndef IDIOSKOPOSINTROSPECTABLE_H
00021 #define IDIOSKOPOSINTROSPECTABLE_H
00022 
00023 #include <map>
00024 #include <string>
00025 
00026 #include <sigc++/sigc++.h>
00027 
00028 #include <idioskopos/pointer.h>
00029 #include <idioskopos/error.h>
00030 #include <idioskopos/object.h>
00031 #include <idioskopos/property.h>
00032 #include <idioskopos/referenceproperty.h>
00033 
00034 namespace Idioskopos
00035 {
00036 
00037   typedef std::map<Object*, Object::pointer> DynamicPropertyMap;
00038   typedef std::map<Glib::ustring, Object*> PropertyMap;
00039 
00044   class Introspectable: public Object
00045   {
00046     public:
00047       typedef IdioskoposPointer<Introspectable> pointer;
00048 
00049       IDIOSKOPOS_OBJECT_AND_REGISTRAR(Introspectable);
00050 
00051       Introspectable( const Glib::ustring& name,
00052                       sigc::slot<void> slot=sigc::slot<void>() );
00053 
00054       Introspectable( const Glib::ustring& name,
00055                       Introspectable& container,
00056                       sigc::slot<void> slot=sigc::slot<void>() );
00057 
00058       static pointer create( const Glib::ustring& name,
00059                              sigc::slot<void> slot=sigc::slot<void>() );
00060 
00061       static pointer create( const Glib::ustring& name,
00062                              Introspectable& container,
00063                              sigc::slot<void> slot=sigc::slot<void>() );
00064 
00065       ~Introspectable();
00066 
00067       Object* get_property( const Glib::ustring& name );
00068 
00069       bool has_property( const Glib::ustring& name );
00070 
00074       bool add_property( Object& property );
00075 
00076       bool add_property( Object::pointer property );
00077 
00078       void remove_property( const Glib::ustring& name );
00079 
00080       sigc::signal<void, Object*> signal_property_value_changed();
00081 
00082       sigc::signal<void, Object*, const Glib::ustring&> signal_property_name_changed();
00083 
00084       virtual sigc::signal<void, Object*> signal_property_added();
00085 
00086       virtual sigc::signal<void, Object*> signal_property_removed();
00087 
00088       template <typename T>
00089       PropertyBase<T>& property( const Glib::ustring& name );
00090 
00091       template <typename T>
00092       PropertyBase<T>* property_ptr( const Glib::ustring& name );
00093 
00094       const std::type_info& type() const
00095       {
00096         return typeid( Introspectable );
00097       }
00098 
00104       virtual size_t num_properties() const;
00105 
00106       virtual Glib::ustring xml(int indent=-1);
00107 
00108       virtual void set_xml(const Glib::ustring& s, bool change_names=false, bool create_missing=true);
00109 
00110       virtual void set_xml(const xmlpp::Node* n, bool change_names=false, bool create_missing=true);
00111 
00112       virtual iterator properties_begin();
00113       virtual iterator properties_end();
00114 
00115       virtual Object& operator[] ( const Glib::ustring& name ) throw ( error::bad_property_name );
00116 
00117     protected:
00118       std::set<Object*> m_properties;
00119       PropertyMap m_property_name_map;
00120       DynamicPropertyMap m_dynamic_property_map;
00121 
00122       Glib::ustring m_separator;
00123 
00124       sigc::signal<void, Object*> m_signal_property_value_changed;
00125       std::map<Object*, sigc::connection> m_property_value_changed_connection;
00126       void on_property_value_changed( Object* );
00127 
00128       sigc::signal<void, Object*, const Glib::ustring&> m_signal_property_name_changed;
00129       std::map<Object*, sigc::connection> m_property_name_changed_connection;
00130       void on_property_name_changed( const Glib::ustring&, Object* );
00131 
00132 
00133       sigc::signal<void, Object*> m_signal_property_added;
00134 
00135       sigc::signal<void, Object*> m_signal_property_removed;
00136 
00137       virtual iterator next_property(std::set<Object*>::iterator i);
00138 
00139       virtual iterator previous_property(std::set<Object*>::iterator i);
00140   };
00141 
00142   template <typename T>
00143   inline
00144   PropertyBase<T>& Introspectable::property( const Glib::ustring& name )
00145   {
00146     Object * pb = get_property( name );
00147     if ( pb == NULL )
00148       throw error::bad_property_name();
00149     try {
00150       PropertyBase<T>& prop = dynamic_cast<PropertyBase<T>&>( *pb );
00151       return prop;
00152     } catch ( ... ) {
00153       throw error::cast::wrong_property_type();
00154     }
00155   }
00156 
00157   template <typename T>
00158   inline
00159   PropertyBase<T>* Introspectable::property_ptr( const Glib::ustring& name )
00160   {
00161     PropertyBase<T>* prop;
00162     Object* pb = get_property( name );
00163     if ( pb == NULL )
00164       return NULL;
00165     try {
00166       prop = dynamic_cast<PropertyBase<T>*>( pb );
00167       return prop;
00168     } catch ( ... ) {
00169       return NULL;
00170     }
00171   }
00172 
00173 }
00174 
00175 #endif

Generated on Thu Jan 11 00:26:41 2007 by  doxygen 1.5.1