--- /dev/null
+// =========================================================================
+// @author Leonardo Florez-Valencia (florez-l@javeriana.edu.co)
+// =========================================================================
+
+$include "Value.e"
+
+#include <cpPlugins/Parameters.h>
+#include <cpPlugins/ProcessObject.h>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/tokenizer.hpp>
+
+// -------------------------------------------------------------------------
+#define cpPlugins_Parameters_SetInsert( _set_, _value_ ) \
+ _set_.insert( _value_ )
+
+#define cpPlugins_Parameters_SequenceInsert( _sequence_, _value_ ) \
+ _sequence_.push_back( _value_ )
+
+// -------------------------------------------------------------------------
+cpPlugins::Parameters::
+Parameters( )
+{
+}
+
+// -------------------------------------------------------------------------
+cpPlugins::Parameters::
+~Parameters( )
+{
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+Print( std::ostream& o ) const
+{
+ {{#t}}
+ if( this->m_{{t}}ValueParams.size( ) > 0 )
+ {
+ o << "+ {{t}} scalar parameters:" << std::endl;
+ for( const TValueParams::value_type& p: this->m_{{t}}ValueParams )
+ o << p.first << " = " << *( p.second.second.get( ) ) << std::endl;
+ } // end if
+ {{#c}}
+ if( this->m_{{t}}{{c}}Params.size( ) > 0 )
+ {
+ o << "+ {{t}} {{c}} parameters:" << std::endl;
+ for( const T{{c}}Params::value_type& p: this->m_{{t}}{{c}}Params )
+ {
+ o << p.first;
+ for( const TValuePtr& s: p.second.second )
+ o << " : " << *( s.get( ) );
+ o << std::endl;
+
+ } // end for
+ } // end if
+ {{/c}}{{/t}}
+}
+
+{{#t}}{{#a}}
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+Configure{{t}}{{a}}( const TString& name, const TValue& templ )
+{
+ {{#w}}
+ if( templ.GetTypeName( ) == typeid( T{{w}} ).name( ) )
+ {
+ this->Configure{{t}}{{a}}< T{{w}} >( name );
+ }
+ else
+ {{/w}};
+}
+{{/a}}{{/t}}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+ConfigureInValue( const TString& name )
+{
+ typedef TValuePair _TPair;
+ typedef TValueParams::value_type _TValuePair;
+
+ if( this->m_InValueParams.find( name ) == this->m_InValueParams.end( ) )
+ {
+ this->m_InValueParams.insert(
+ _TValuePair(
+ name, _TPair( TValue( typeid( _TValue ) ), TValuePtr( ) )
+ )
+ );
+ } // end if
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+ConfigureOutValue( const TString& name )
+{
+ typedef TValuePair _TPair;
+ typedef TValueParams::value_type _TValuePair;
+
+ if( this->m_OutValueParams.find( name ) == this->m_OutValueParams.end( ) )
+ {
+ TValue t( typeid( _TValue ) );
+ TValuePtr p = std::make_shared< TValue >( );
+ t.SetSource( this );
+ p->SetSource( this );
+ this->m_OutValueParams.insert( _TValuePair( name, _TPair( t, p ) ) );
+ } // end if
+}
+
+{{#t}}{{#c}}
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+Configure{{t}}{{c}}( const TString& name )
+{
+ typedef T{{c}}Pair _TPair;
+ typedef T{{c}}Params::value_type _T{{c}}Pair;
+
+ if(
+ this->m_{{t}}{{c}}Params.find( name ) == this->m_{{t}}{{c}}Params.end( )
+ )
+ {
+ this->m_{{t}}{{c}}Params.insert(
+ _T{{c}}Pair(
+ name, _TPair( TValue( typeid( _TValue ) ), T{{c}}( ) )
+ )
+ );
+ } // end if
+}
+{{/c}}{{/t}}
+
+{{#t}}
+// -------------------------------------------------------------------------
+const cpPlugins::Parameters::
+TValue& cpPlugins::Parameters::
+Get{{t}}Value( const TString& name ) const
+{
+ TValueParams::const_iterator i = this->m_{{t}}ValueParams.find( name );
+ if( i != this->m_{{t}}ValueParams.end( ) )
+ {
+ if( i->second.second )
+ return( *( i->second.second.get( ) ) );
+ else
+ cpPluginsErrorMacro(
+ << "{{t}}ValueParameter \"" << name << "\" is not yet assigned." );
+ }
+ else
+ cpPluginsErrorMacro(
+ << "{{t}}ValueParameter \"" << name << "\" not found." );
+}
+{{/t}}
+
+{{#t}}{{#c}}
+// -------------------------------------------------------------------------
+const cpPlugins::Parameters::
+T{{c}}& cpPlugins::Parameters::
+Get{{t}}{{c}}( const TString& name ) const
+{
+ T{{c}}Params::const_iterator i = this->m_{{t}}{{c}}Params.find( name );
+ if( i != this->m_{{t}}{{c}}Params.end( ) )
+ return( i->second.second );
+ else
+ cpPluginsErrorMacro(
+ << "{{t}}ValueParameter \"" << name << "\" not found." );
+}
+{{/c}}{{/t}}
+
+// -------------------------------------------------------------------------
+cpPlugins::Parameters::
+TValuePtr& cpPlugins::Parameters::
+GetOutValuePtr( const TString& name )
+{
+ TValueParams::iterator i = this->m_OutValueParams.find( name );
+ if( i != this->m_OutValueParams.end( ) )
+ return( i->second.second );
+ else
+ cpPluginsErrorMacro(
+ << "OutValueParameter \"" << name << "\" not found." );
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Parameters::
+TValuePtr& cpPlugins::Parameters::
+GetOutValuePtr( const TString& name ) const
+{
+ TValueParams::const_iterator i = this->m_OutValueParams.find( name );
+ if( i != this->m_OutValueParams.end( ) )
+ return( i->second.second );
+ else
+ cpPluginsErrorMacro(
+ << "OutValueParameter \"" << name << "\" not found." );
+}
+
+{{#t}}{{#a}}
+// -------------------------------------------------------------------------
+std::set< std::string > cpPlugins::Parameters::
+Get{{t}}{{a}}Names( ) const
+{
+ std::set< std::string > names;
+ for( const T{{a}}Params::value_type& v: this->m_{{t}}{{a}}Params )
+ names.insert( v.first );
+ return( names );
+}
+{{/a}}{{/t}}
+
+{{#t}}{{#a}}
+// -------------------------------------------------------------------------
+const cpPlugins::Parameters::
+TValue& cpPlugins::Parameters::
+Get{{t}}{{a}}Template( const TString& name ) const
+{
+ T{{a}}Params::const_iterator i = this->m_{{t}}{{a}}Params.find( name );
+ if( i != this->m_{{t}}{{a}}Params.end( ) )
+ return( i->second.first );
+ else
+ cpPluginsErrorMacro( << "Parameter \"" << name << "\" not found." );
+}
+{{/a}}{{/t}}
+
+{{#t}}{{#a}}
+// -------------------------------------------------------------------------
+bool cpPlugins::Parameters::
+Has{{t}}{{a}}( const TString& name ) const
+{
+ T{{a}}Params::const_iterator i = this->m_{{t}}{{a}}Params.find( name );
+ return( i != this->m_{{t}}{{a}}Params.end( ) );
+}
+{{/a}}{{/t}}
+
+{{#t}}
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+Set{{t}}Value( const TString& name, const _TValue& value )
+{
+ TValueParams::iterator i = this->m_{{t}}ValueParams.find( name );
+ if( i != this->m_{{t}}ValueParams.end( ) )
+ {
+ // Copy configured type and value
+ if( !bool( i->second.second ) )
+ i->second.second = std::make_shared< TValue >( );
+ *( i->second.second.get( ) ) = i->second.first;
+ *( i->second.second.get( ) ) = value;
+
+ // Inform the modification
+ this->Modified{{t}}Value( name );
+ } // end if
+}
+{{/t}}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+SetInValuePtr( const TString& name, TValuePtr& value )
+{
+ TValueParams::iterator i = this->m_InValueParams.find( name );
+ if( i != this->m_InValueParams.end( ) )
+ {
+ i->second.second = value;
+ this->ModifiedInValue( name );
+ } // end if
+}
+
+{{#t}}{{#c}}
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+AddTo{{t}}{{c}}( const TString& name, const _TValue& value )
+{
+ T{{c}}Params::iterator i = this->m_{{t}}{{c}}Params.find( name );
+ if( i != this->m_{{t}}{{c}}Params.end( ) )
+ {
+ // Copy configured type and value
+ TValuePtr nv = std::make_shared< TValue >( i->second.first );
+ *( nv.get( ) ) = value;
+
+ // Add to container and inform
+ cpPlugins_Parameters_{{c}}Insert( i->second.second, nv );
+ this->Modified{{t}}{{c}}( name );
+ } // end if
+}
+{{/c}}{{/t}}
+
+{{#t}}{{#c}}
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+Clear{{t}}{{c}}( const TString& name )
+{
+ T{{c}}Params::iterator i = this->m_{{t}}{{c}}Params.find( name );
+ if( i != this->m_{{t}}{{c}}Params.end( ) )
+ {
+ i->second.second.clear( );
+ this->Modified{{t}}{{c}}( name );
+ } // end if
+}
+{{/c}}{{/t}}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+AddChoice( const TString& name, const _TValue& v )
+{
+ TChoiceParams::iterator i = this->m_ChoiceParams.find( name );
+ if( i != this->m_ChoiceParams.end( ) )
+ {
+ TValuePtr nv = std::make_shared< TValue >( i->second.first.first );
+ *( nv.get( ) ) = v;
+ i->second.second = i->second.first.second.insert( nv ).first;
+ this->ModifiedChoice( name );
+ } // end if
+}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+ClearChoice( const TString& name )
+{
+ TChoiceParams::iterator i = this->m_ChoiceParams.find( name );
+ if( i != this->m_ChoiceParams.end( ) )
+ {
+ i->second.second = i->second.first.second.end( );
+ this->ModifiedChoice( name );
+ } // end if
+}
+
+// -------------------------------------------------------------------------
+template< class _TValue >
+void cpPlugins::Parameters::
+ConfigureChoices( const TString& name )
+{
+ if( this->m_ChoiceParams.find( name ) == this->m_ChoiceParams.end( ) )
+ {
+ TSetPair s( TValue( typeid( _TValue ) ), TSet( ) );
+ this->m_ChoiceParams.insert(
+ TChoiceParams::value_type( name, TChoicePair( s, s.second.end( ) ) )
+ );
+ } // end if
+}
+
+// -------------------------------------------------------------------------
+const cpPlugins::Parameters::
+TValue& cpPlugins::Parameters::
+GetChoice( const TString& name ) const
+{
+ static const TValue zero;
+ TChoiceParams::const_iterator i = this->m_ChoiceParams.find( name );
+ if( i != this->m_ChoiceParams.end( ) )
+ {
+ if( i->second.second != i->second.first.second.end( ) )
+ return( *( i->second.second->get( ) ) );
+ else
+ return( zero );
+ }
+ else
+ return( zero );
+}
+
+{{#a}}{{#t}}
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+Modified{{t}}{{a}}( const std::string& name )
+{
+ // Do nothing at this level
+}
+{{/t}}{{/a}}
+
+// -------------------------------------------------------------------------
+void cpPlugins::Parameters::
+ModifiedChoice( const std::string& name )
+{
+ // Do nothing at this level
+}
+
+// -------------------------------------------------------------------------
+bool cpPlugins::Parameters::
+Update( )
+{
+ bool updated = true;
+ for( TValueParams::value_type& v: this->m_InValueParams )
+ {
+ if( v.second.second )
+ {
+ cpPlugins::ProcessObject* po = v.second.second->GetSource( );
+ if( po != NULL )
+ {
+ if( !( po->IsUpdated( ) ) )
+ {
+ po->Update( );
+ updated = false;
+
+ } // end if
+ } // end if
+ } // end if
+ } // end for
+ return( updated );
+}
+
+// -------------------------------------------------------------------------
+template<>
+void cpPlugins::Parameters::
+LoadXML( const boost::property_tree::ptree::value_type& node )
+{
+ typedef boost::char_separator< char > _TSep;
+ typedef boost::tokenizer< _TSep > _TTok;
+
+ for( const boost::property_tree::ptree::value_type& p: node.second )
+ {
+ {{#t}}
+ if( p.first == "{{t}}ValueParameter" )
+ {
+ std::string pn = p.second.get< std::string >( "<xmlattr>.name" );
+ std::string pv = p.second.get< std::string >( "<xmlattr>.value" );
+ this->Set{{t}}Value( pn, pv );
+ }
+ else
+ {{/t}}
+ {{#t}}{{#c}}
+ if( p.first == "{{t}}{{c}}Parameter" )
+ {
+ std::string pn = p.second.get< std::string >( "<xmlattr>.name" );
+ std::string pv = p.second.get< std::string >( "<xmlattr>.value" );
+ this->Clear{{t}}{{c}}( pn );
+ _TTok tok( pv, _TSep( "@" ) );
+ for( _TTok::const_iterator tIt = tok.begin( ); tIt != tok.end( ); ++tIt )
+ this->AddTo{{t}}{{c}}( pn, *tIt );
+ }
+ else
+ {{/c}}{{/t}};
+ // TODO: Set and Sequence
+ } // end for
+}
+
+// -------------------------------------------------------------------------
+template<>
+void cpPlugins::Parameters::
+SaveXML( boost::property_tree::ptree* node ) const
+{
+ {{#t}}
+ if( this->m_{{t}}ValueParams.size( ) > 0 )
+ {
+ for( const TValueParams::value_type& p: this->m_{{t}}ValueParams )
+ {
+ if( p.second.second )
+ {
+ boost::property_tree::ptree param;
+ param.put( "<xmlattr>.name", p.first );
+ param.put(
+ "<xmlattr>.value", std::string( *( p.second.second.get( ) ) )
+ );
+ node->add_child( "{{t}}ValueParameter", param );
+ } // end if
+ } // end for
+ } // end if
+ {{#c}}
+ if( this->m_{{t}}{{c}}Params.size( ) > 0 )
+ {
+ std::stringstream str;
+ for( const T{{c}}Params::value_type& p: this->m_{{t}}{{c}}Params )
+ {
+ for( const TValuePtr& s: p.second.second )
+ str << *( s.get( ) ) << "@";
+ boost::property_tree::ptree param;
+ param.put( "<xmlattr>.name", p.first );
+ param.put( "<xmlattr>.value", str.str( ) );
+ node->add_child( "{{t}}{{c}}Parameter", param );
+ } // end for
+ } // end if
+ {{/c}}{{/t}}
+}
+
+// -------------------------------------------------------------------------
+$nm=cpPlugins::Parameters;
+$q=$s$;cpPlugins::Value;
+
+template $ex$ void $nm$::Configure$t$$a$< $s$ >( const TString& );
+template $ex$ void $nm$::Set$t$Value< $q$ >( const TString&, const $q$& );
+template $ex$ void $nm$::AddTo$t$$c$< $q$ >( const TString&, const $q$& );
+template $ex$ void $nm$::AddChoice< $q$ >( const TString&, const $q$& );
+template $ex$ void $nm$::ConfigureChoices< $s$ >( const TString& );
+
+// eof - $RCSfile$