#include <cpPlugins/Interface/Workspace.h>
-#include <third_party/tinyxml/tinyxml.h>
+#include <tinyxml2/tinyxml2.h>
// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Workspace::
-LoadWorkspace( const std::string& fname )
+void cpPlugins::Interface::Workspace::
+Load( const std::string& fname )
{
- TiXmlDocument* doc = new TiXmlDocument( fname.c_str( ) );
- doc->LoadFile( );
- TiXmlElement* root = doc->RootElement( );
+ this->Clear( );
+ TInterface::Pointer interface = TInterface::New( );
+
+ // Read from disk
+ tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
+ doc->LoadFile( fname.c_str( ) );
+ tinyxml2::XMLElement* root = doc->RootElement( );
if( root == NULL )
- return( "cpPlugins::Interface::Workspace: No valid file" );
- if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
- return( "cpPlugins::Interface::Workspace: No valid workspace" );
- std::stringstream err;
+ {
+ delete doc;
+ throw std::runtime_error( "cpPlugins::Workspace: No valid file" );
- // Read plugins files
- TiXmlElement* plugins = root->FirstChildElement( "plugins" );
- while( plugins != NULL )
+ } // fi
+ if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
{
- const char* value = plugins->Attribute( "filename" );
- if( value != NULL )
- {
- if( !( this->LoadPlugins( value ) ) )
- err << "no valid plugins file \"" << value << "\"" << std::endl;
+ delete doc;
+ throw std::runtime_error( "cpPlugins::Workspace: Not a valid workspace" );
- } // fi
- plugins = plugins->NextSiblingElement( "plugins" );
+ } // fi
- } // elihw
-
- // Read plugins paths
- plugins = root->FirstChildElement( "plugins_dir" );
+ // Load plugins
+ auto loaded_plugins = interface->GetPlugins( );
+ tinyxml2::XMLElement* plugins = root->FirstChildElement( "Plugins" );
+ std::string plugins_errors = "";
while( plugins != NULL )
{
- const char* value = plugins->Attribute( "path" );
- if( value != NULL )
+ tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "Plugin" );
+ while( plugin != NULL )
{
- int recursive;
- if( plugins->QueryIntAttribute( "recursive", &recursive ) != TIXML_SUCCESS )
- recursive = 0;
- if( !( this->LoadPluginsPath( value, recursive == 1 ) ) )
- err << "No valid plugins path \"" << value << "\"" << std::endl;
+ std::string name = plugin->Attribute( "Name" );
+ if( loaded_plugins.find( name ) == loaded_plugins.end( ) )
+ {
+ try
+ {
+ interface->LoadPlugin( name );
+ }
+ catch( std::exception& err )
+ {
+ plugins_errors += err.what( ) + std::string( "\n" );
- } // fi
- plugins = plugins->NextSiblingElement( "plugins_dir" );
+ } // yrt
+
+ } // fi
+ plugin = plugin->NextSiblingElement( "Plugin" );
+
+ } // elihw
+ plugins = plugins->NextSiblingElement( "Plugins" );
} // elihw
+ if( plugins_errors != "" )
+ {
+ delete doc;
+ throw std::runtime_error(
+ std::string( "cpPlugins::Workspace: " ) + plugins_errors
+ );
+
+ } // fi
// Read filters
- TiXmlElement* filter = root->FirstChildElement( "filter" );
+ std::stringstream err;
+ tinyxml2::XMLElement* filter = root->FirstChildElement( "Filter" );
while( filter != NULL )
{
- const char* class_value = filter->Attribute( "class" );
- const char* name_value = filter->Attribute( "name" );
+ const char* category_value = filter->Attribute( "Category" );
+ const char* class_value = filter->Attribute( "Class" );
+ const char* name_value = filter->Attribute( "Name" );
+ float viewX = float( 0 ), viewY = float( 0 );
+ filter->QueryFloatAttribute( "ViewX", &viewX );
+ filter->QueryFloatAttribute( "ViewY", &viewY );
+ int explicit_execution = 0;
+ filter->QueryIntAttribute(
+ "ExplicitExecution", &explicit_execution
+ );
if( class_value != NULL && name_value != NULL )
{
- if( this->CreateFilter( class_value, name_value ) )
+ auto new_filter =
+ this->CreateFilter( category_value, class_value, name_value );
+ if( new_filter != NULL )
{
- // Read parameters
- TParameters* parameters = this->GetParameters( name_value );
- TiXmlElement* param = filter->FirstChildElement( "parameter" );
- while( param != NULL )
- {
- const char* param_name = param->Attribute( "name" );
- const char* param_type = param->Attribute( "type" );
- if( param_name != NULL && param_type != NULL )
- {
- std::string param_type_str( param_type );
- const char* value = param->Attribute( "value" );
- if( value != NULL )
- {
- std::istringstream value_str( value );
- if( param_type_str == "String" )
- parameters->SetString( param_name, value );
- else if( param_type_str == "Bool" )
- parameters->SetBool( param_name, value[ 0 ] != '0' );
- else if( param_type_str == "Int" )
- {
- TParameters::TInt v;
- value_str >> v;
- parameters->SetInt( param_name, v );
- }
- else if( param_type_str == "Uint" )
- {
- TParameters::TUint v;
- value_str >> v;
- parameters->SetUint( param_name, v );
- }
- else if( param_type_str == "Real" )
- {
- TParameters::TReal v;
- value_str >> v;
- parameters->SetReal( param_name, v );
- }
- /* TODO
- else if( param_type_str == "Index" )
- else if( param_type_str == "Point" )
- else if( param_type_str == "Vector" )
- */
- }
- else
- {
- if( param_type_str == "StringList" )
- {
- TiXmlElement* item = param->FirstChildElement( "item" );
- while( item != NULL )
- {
- value = item->Attribute( "value" );
- if( value != NULL )
- parameters->AddToStringList( param_name, value );
- item = item->NextSiblingElement( "item" );
-
- } // elihw
- }
- else if( param_type_str == "BoolList" )
- {
- TiXmlElement* item = param->FirstChildElement( "item" );
- while( item != NULL )
- {
- value = item->Attribute( "value" );
- if( value != NULL )
- parameters->AddToBoolList( param_name, value[ 0 ] != '0' );
- item = item->NextSiblingElement( "item" );
-
- } // elihw
- }
- else if( param_type_str == "IntList" )
- {
- TiXmlElement* item = param->FirstChildElement( "item" );
- while( item != NULL )
- {
- value = item->Attribute( "value" );
- if( value != NULL )
- {
- std::istringstream value_str( value );
- TParameters::TInt v;
- value_str >> v;
- parameters->AddToIntList( param_name, v );
-
- } // fi
- item = item->NextSiblingElement( "item" );
-
- } // elihw
- }
- else if( param_type_str == "UintList" )
- {
- TiXmlElement* item = param->FirstChildElement( "item" );
- while( item != NULL )
- {
- value = item->Attribute( "value" );
- if( value != NULL )
- {
- std::istringstream value_str( value );
- TParameters::TUint v;
- value_str >> v;
- parameters->AddToUintList( param_name, v );
-
- } // fi
- item = item->NextSiblingElement( "item" );
-
- } // elihw
- }
- else if( param_type_str == "RealList" )
- {
- TiXmlElement* item = param->FirstChildElement( "item" );
- while( item != NULL )
- {
- value = item->Attribute( "value" );
- if( value != NULL )
- {
- std::istringstream value_str( value );
- TParameters::TReal v;
- value_str >> v;
- parameters->AddToRealList( param_name, v );
-
- } // fi
- item = item->NextSiblingElement( "item" );
-
- } // elihw
- }
- /* TODO
- else if( param_type_str == "IndexList" )
- else if( param_type_str == "PointList" )
- else if( param_type_str == "VectorList" )
- else if( param_type_str == "Choices" );
- */
- } // fi
-
- } // fi
- param = param->NextSiblingElement( "parameter" );
-
- } // elihw
+ new_filter->SetViewCoords( viewX, viewY );
+ new_filter->SetExplicitExecution( explicit_execution == 1 );
+ new_filter->GetParameters( )->FromXML( filter );
}
else
err
}
else
err << "Incomplete data." << std::endl;
- filter = filter->NextSiblingElement( "filter" );
+ filter = filter->NextSiblingElement( "Filter" );
} // elihw
- // Read filters
- TiXmlElement* connection = root->FirstChildElement( "connection" );
+ // Read connections
+ tinyxml2::XMLElement* connection = root->FirstChildElement( "Connection" );
while( connection != NULL )
{
- TiXmlElement* orig = connection->FirstChildElement( "origin" );
- TiXmlElement* dest = connection->FirstChildElement( "destination" );
+ tinyxml2::XMLElement* orig = connection->FirstChildElement( "Origin" );
+ tinyxml2::XMLElement* dest = connection->FirstChildElement( "Destination" );
if( orig != NULL && dest != NULL )
{
- const char* orig_filter = orig->Attribute( "filter" );
- const char* dest_filter = dest->Attribute( "filter" );
- const char* orig_name = orig->Attribute( "name" );
- const char* dest_name = dest->Attribute( "name" );
+ const char* orig_filter = orig->Attribute( "Filter" );
+ const char* dest_filter = dest->Attribute( "Filter" );
+ const char* orig_name = orig->Attribute( "Name" );
+ const char* dest_name = dest->Attribute( "Name" );
if(
orig_filter != NULL && dest_filter != NULL &&
orig_name != NULL && dest_name != NULL
)
- this->Connect( orig_filter, dest_filter, orig_name, dest_name );
+ {
+ try
+ {
+ this->Connect( orig_filter, dest_filter, orig_name, dest_name );
+ }
+ catch( std::exception& exc )
+ {
+ err << exc.what( ) << std::endl;
+
+ } // yrt
+
+ } // fi
} // fi
- connection = connection->NextSiblingElement( "connection" );
+ connection = connection->NextSiblingElement( "Connection" );
+
+ } // elihw
+
+ // Read exposed inputs
+ tinyxml2::XMLElement* port = root->FirstChildElement( "ExposedInput" );
+ while( port != NULL )
+ {
+ this->ExposeInput(
+ port->Attribute( "Name" ),
+ port->Attribute( "Filter" ),
+ port->Attribute( "Input" )
+ );
+ port = port->NextSiblingElement( "ExposedInput" );
+
+ } // elihw
+
+ // Read exposed outputs
+ port = root->FirstChildElement( "ExposedOutput" );
+ while( port != NULL )
+ {
+ this->ExposeOutput(
+ port->Attribute( "Name" ),
+ port->Attribute( "Filter" ),
+ port->Attribute( "Output" )
+ );
+ port = port->NextSiblingElement( "ExposedOutput" );
} // elihw
- // Finish and return
+ // Throw errors
+ std::string err_str = err.str( );
+ if( err_str != "" )
+ {
+ delete doc;
+ throw std::runtime_error(
+ std::string( "cpPlugins::Workspace " ) + err_str
+ );
+
+ } // fi
+
+ // Finish
delete doc;
- return( err.str( ) );
}
// -------------------------------------------------------------------------
-std::string cpPlugins::Interface::Workspace::
-SaveWorkspace( const std::string& fname ) const
+void cpPlugins::Interface::Workspace::
+Save( const std::string& fname ) const
{
- std::stringstream err;
- TiXmlDocument* doc = new TiXmlDocument( );
- TiXmlElement* root = new TiXmlElement( "cpPlugins_Workspace" );
-
- // Save plugins
- for(
- auto plugIt = this->m_LoadedPlugins.begin( );
- plugIt != this->m_LoadedPlugins.end( );
- ++plugIt
- )
+ tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
+ tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
+ std::set< std::string > used_plugins;
+
+ // Save filter data
+ for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
+ {
+ auto filter = i->second;
+ used_plugins.insert( filter->GetPluginName( ) );
+ tinyxml2::XMLElement* e = doc->NewElement( "Filter" );
+ e->SetAttribute( "Category", filter->GetClassCategory( ) );
+ e->SetAttribute( "Class", filter->GetClassName( ) );
+ e->SetAttribute( "Name", filter->GetName( ) );
+ e->SetAttribute( "ViewX", filter->GetViewX( ) );
+ e->SetAttribute( "ViewY", filter->GetViewY( ) );
+ e->SetAttribute(
+ "ExplicitExecution", ( filter->GetExplicitExecution( ) )? 1: 0
+ );
+
+ auto params = filter->GetParameters( );
+ params->ToXML( doc, e );
+ root->LinkEndChild( e );
+
+ } // rof
+
+ // Save used plugins
+ tinyxml2::XMLElement* plugins = doc->NewElement( "Plugins" );
+ for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
{
- TiXmlElement* plugin = new TiXmlElement( "plugins" );
- plugin->SetAttribute( "filename", plugIt->c_str( ) );
- root->LinkEndChild( plugin );
+ tinyxml2::XMLElement* e = doc->NewElement( "Plugin" );
+ e->SetAttribute( "Name", pIt->c_str( ) );
+ plugins->LinkEndChild( e );
} // rof
+ root->LinkEndChild( plugins );
- // Save vertices
- auto vIt = this->m_Graph->BeginVertices( );
- for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
+ // Save connections
+ for( auto i = this->m_Filters.begin( ); i != this->m_Filters.end( ); ++i )
{
- auto filter = dynamic_cast< TFilter* >( vIt->second.GetPointer( ) );
- auto data = dynamic_cast< TData* >( vIt->second.GetPointer( ) );
- if( filter != NULL )
+ auto orig = i->second;
+ auto outputs = orig->GetOutputsNames( );
+ if( outputs.size( ) == 0 )
+ continue;
+ for( auto j = this->m_Filters.begin( ); j != this->m_Filters.end( ); ++j )
{
- TiXmlElement* e = new TiXmlElement( "filter" );
- e->SetAttribute( "class", filter->GetClassName( ).c_str( ) );
- e->SetAttribute( "name", filter->GetName( ) );
-
- const TParameters* params = filter->GetParameters( );
- std::vector< std::string > names;
- params->GetNames( names );
- for( auto nIt = names.begin( ); nIt != names.end( ); ++nIt )
+ if( i == j )
+ continue;
+ auto dest = j->second;
+ auto inputs = dest->GetInputsNames( );
+ if( inputs.size( ) == 0 )
+ continue;
+
+ for( auto oIt = outputs.begin( ); oIt != outputs.end( ); ++oIt )
{
- TiXmlElement* p = new TiXmlElement( "parameter" );
- p->SetAttribute( "name", nIt->c_str( ) );
- //const char* param_type = param->Attribute( "type" );
- if( params->HasString( *nIt ) )
- p->SetAttribute( "type", "String" );
- else if( params->HasBool( *nIt ) )
- p->SetAttribute( "type", "Bool" );
- else if( params->HasInt( *nIt ) )
- p->SetAttribute( "type", "Int" );
- else if( params->HasUint( *nIt ) )
- p->SetAttribute( "type", "Uint" );
- else if( params->HasReal( *nIt ) )
- p->SetAttribute( "type", "Real" );
- else if( params->HasIndex( *nIt ) )
- p->SetAttribute( "type", "Index" );
- else if( params->HasPoint( *nIt ) )
- p->SetAttribute( "type", "Point" );
- else if( params->HasVector( *nIt ) )
- p->SetAttribute( "type", "Vector" );
- else if( params->HasStringList( *nIt ) )
- p->SetAttribute( "type", "StringList" );
- else if( params->HasBoolList( *nIt ) )
- p->SetAttribute( "type", "BoolList" );
- else if( params->HasIntList( *nIt ) )
- p->SetAttribute( "type", "IntList" );
- else if( params->HasUintList( *nIt ) )
- p->SetAttribute( "type", "UintList" );
- else if( params->HasRealList( *nIt ) )
- p->SetAttribute( "type", "RealList" );
- else if( params->HasIndexList( *nIt ) )
- p->SetAttribute( "type", "IndexList" );
- else if( params->HasPointList( *nIt ) )
- p->SetAttribute( "type", "PointList" );
- else if( params->HasVectorList( *nIt ) )
- p->SetAttribute( "type", "VectorList" );
- else if( params->HasChoices( *nIt ) )
- p->SetAttribute( "type", "Choices" );
- p->SetAttribute( "value", params->GetString( *nIt, false ).c_str( ) );
- e->LinkEndChild( p );
+ auto od = orig->GetOutput( *oIt );
+ for( auto iIt = inputs.begin( ); iIt != inputs.end( ); ++iIt )
+ {
+ auto id = dest->GetInput( *iIt );
+ if( od != NULL && od == id )
+ {
+ tinyxml2::XMLElement* e_conn = doc->NewElement( "Connection" );
+ tinyxml2::XMLElement* e_orig = doc->NewElement( "Origin" );
+ tinyxml2::XMLElement* e_dest = doc->NewElement( "Destination" );
+ e_orig->SetAttribute( "Filter", orig->GetName( ) );
+ e_orig->SetAttribute( "Name", oIt->c_str( ) );
+ e_dest->SetAttribute( "Filter", dest->GetName( ) );
+ e_dest->SetAttribute( "Name", iIt->c_str( ) );
+ e_conn->LinkEndChild( e_orig );
+ e_conn->LinkEndChild( e_dest );
+ root->LinkEndChild( e_conn );
+
+ } // fi
+
+ } // rof
} // rof
- root->LinkEndChild( e );
- }
- else if( data != NULL )
- {
- } // fi
+
+ } // rof
+
+ } // rof
+
+
+ // Save exposed ports
+ auto eipIt = this->m_ExposedInputs.begin( );
+ for( ; eipIt != this->m_ExposedInputs.end( ); ++eipIt )
+ {
+ tinyxml2::XMLElement* port = doc->NewElement( "ExposedInput" );
+ port->SetAttribute( "Name", eipIt->first.c_str( ) );
+ port->SetAttribute( "Filter", eipIt->second.first.c_str( ) );
+ port->SetAttribute( "Input", eipIt->second.second.c_str( ) );
+ root->LinkEndChild( port );
+
+ } // rof
+
+ auto eopIt = this->m_ExposedOutputs.begin( );
+ for( ; eopIt != this->m_ExposedOutputs.end( ); ++eopIt )
+ {
+ tinyxml2::XMLElement* port = doc->NewElement( "ExposedOutput" );
+ port->SetAttribute( "Name", eopIt->first.c_str( ) );
+ port->SetAttribute( "Filter", eopIt->second.first.c_str( ) );
+ port->SetAttribute( "Output", eopIt->second.second.c_str( ) );
+ root->LinkEndChild( port );
} // rof
// Physical write and return
doc->LinkEndChild( root );
- doc->SaveFile( fname.c_str( ) );
+ auto error = doc->SaveFile( fname.c_str( ) );
delete doc;
- return( err.str( ) );
+ if( error != tinyxml2::XML_SUCCESS )
+ {
+ std::string m;
+ switch( error )
+ {
+ case tinyxml2::XML_NO_ATTRIBUTE:
+ m = "No attribute."; break;
+ case tinyxml2::XML_WRONG_ATTRIBUTE_TYPE:
+ m = "Wrong attribute."; break;
+ case tinyxml2::XML_ERROR_FILE_NOT_FOUND:
+ m = "File not found."; break;
+ case tinyxml2::XML_ERROR_FILE_COULD_NOT_BE_OPENED:
+ m = "File not opened."; break;
+ case tinyxml2::XML_ERROR_FILE_READ_ERROR:
+ m = "File not read."; break;
+ case tinyxml2::XML_ERROR_ELEMENT_MISMATCH:
+ m = "Element mismatch."; break;
+ case tinyxml2::XML_ERROR_PARSING_ELEMENT:
+ m = "Parsing element."; break;
+ case tinyxml2::XML_ERROR_PARSING_ATTRIBUTE:
+ m = "Parsing attribute."; break;
+ case tinyxml2::XML_ERROR_IDENTIFYING_TAG:
+ m = "Tag Id."; break;
+ case tinyxml2::XML_ERROR_PARSING_TEXT:
+ m = "Parsing text."; break;
+ case tinyxml2::XML_ERROR_PARSING_CDATA:
+ m = "Parsing cdata."; break;
+ case tinyxml2::XML_ERROR_PARSING_COMMENT:
+ m = "Parsing comment."; break;
+ case tinyxml2::XML_ERROR_PARSING_DECLARATION:
+ m = "Parsing declaration."; break;
+ case tinyxml2::XML_ERROR_PARSING_UNKNOWN:
+ m = "Parsing unknown."; break;
+ case tinyxml2::XML_ERROR_EMPTY_DOCUMENT:
+ m = "Empty document."; break;
+ case tinyxml2::XML_ERROR_MISMATCHED_ELEMENT:
+ m = "Mismatched element."; break;
+ case tinyxml2::XML_ERROR_PARSING:
+ m = "Parsing."; break;
+ case tinyxml2::XML_CAN_NOT_CONVERT_TEXT:
+ m = "Cannot convert."; break;
+ case tinyxml2::XML_NO_TEXT_NODE:
+ m = "No text."; break;
+ default:
+ m = "Unknown error."; break;
+ } // hctiws
+ throw std::runtime_error(
+ std::string( "cpPlugins::Workspace: Error while saving \"" ) +
+ fname + std::string( "\": " ) + m
+ );
+
+ } // fi
}
// eof - $RCSfile$