1 #include <cpPlugins/Workspace.h>
2 #include <tinyxml2/tinyxml2.h>
4 // -------------------------------------------------------------------------
5 std::string cpPlugins::Workspace::
6 LoadWorkspace( const std::string& fname )
8 if( this->m_Interface == NULL )
9 return( "cpPlugins::Workspace: No valid plugins interface" );
10 tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
11 doc->LoadFile( fname.c_str( ) );
12 tinyxml2::XMLElement* root = doc->RootElement( );
14 return( "cpPlugins::Workspace: No valid file" );
15 if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
16 return( "cpPlugins::Workspace: No valid workspace" );
17 std::stringstream err;
20 auto loaded_plugins = this->m_Interface->GetPlugins( );
21 tinyxml2::XMLElement* plugins = root->FirstChildElement( "plugins" );
22 std::string plugins_errors = "";
23 while( plugins != NULL )
25 tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "plugin" );
26 while( plugin != NULL )
28 std::string name = plugin->Attribute( "name" );
29 if( loaded_plugins.find( name ) == loaded_plugins.end( ) )
33 this->m_Interface->LoadPlugin( name );
35 catch( std::exception& err )
37 plugins_errors += err.what( ) + std::string( "\n" );
42 plugin = plugin->NextSiblingElement( "plugin" );
45 plugins = plugins->NextSiblingElement( "plugins" );
48 if( plugins_errors != "" )
49 return( std::string( "cpPlugins::Workspace: " ) + plugins_errors );
52 tinyxml2::XMLElement* filter = root->FirstChildElement( "filter" );
53 while( filter != NULL )
55 const char* category_value = filter->Attribute( "category" );
56 const char* class_value = filter->Attribute( "class" );
57 const char* name_value = filter->Attribute( "name" );
58 float viewX = float( 0 ), viewY = float( 0 );
59 filter->QueryFloatAttribute( "ViewX", &viewX );
60 filter->QueryFloatAttribute( "ViewY", &viewY );
61 int explicit_re_execution = 0;
62 filter->QueryIntAttribute(
63 "ExplicitReExecution", &explicit_re_execution
65 if( class_value != NULL && name_value != NULL )
67 if( this->CreateFilter( category_value, class_value, name_value ) )
69 auto new_filter = this->GetFilter( name_value );
70 new_filter->SetViewCoords( viewX, viewY );
71 new_filter->SetExplicitReExecution( explicit_re_execution == 1 );
74 auto parameters = new_filter->GetParameters( );
75 parameters->FromXML( filter );
79 << "No valid class \"" << class_value << "\" with name \""
80 << name_value << "\"" << std::endl;
83 err << "Incomplete data." << std::endl;
84 filter = filter->NextSiblingElement( "filter" );
89 tinyxml2::XMLElement* connection = root->FirstChildElement( "connection" );
90 while( connection != NULL )
92 tinyxml2::XMLElement* orig = connection->FirstChildElement( "origin" );
93 tinyxml2::XMLElement* dest = connection->FirstChildElement( "destination" );
94 if( orig != NULL && dest != NULL )
96 const char* orig_filter = orig->Attribute( "filter" );
97 const char* dest_filter = dest->Attribute( "filter" );
98 const char* orig_name = orig->Attribute( "name" );
99 const char* dest_name = dest->Attribute( "name" );
101 orig_filter != NULL && dest_filter != NULL &&
102 orig_name != NULL && dest_name != NULL
104 this->Connect( orig_filter, dest_filter, orig_name, dest_name );
107 connection = connection->NextSiblingElement( "connection" );
111 // Read exposed inputs
112 tinyxml2::XMLElement* port = root->FirstChildElement( "exposed_input_port" );
113 while( port != NULL )
115 this->ExposeInputPort(
116 port->Attribute( "port_name" ),
117 port->Attribute( "filter" ),
118 port->Attribute( "filter_port_name" )
120 port = port->NextSiblingElement( "exposed_input_port" );
124 // Read exposed outputs
125 port = root->FirstChildElement( "exposed_output_port" );
126 while( port != NULL )
128 this->ExposeOutputPort(
129 port->Attribute( "port_name" ),
130 port->Attribute( "filter" ),
131 port->Attribute( "filter_port_name" )
133 port = port->NextSiblingElement( "exposed_output_port" );
139 return( err.str( ) );
142 // -------------------------------------------------------------------------
143 std::string cpPlugins::Workspace::
144 SaveWorkspace( const std::string& fname ) const
146 std::stringstream err;
147 tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
148 tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
149 std::set< std::string > used_plugins;
152 auto vIt = this->m_Graph->BeginVertices( );
153 for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
155 auto filter = dynamic_cast< ProcessObject* >( vIt->second.GetPointer( ) );
156 auto data = dynamic_cast< DataObject* >( vIt->second.GetPointer( ) );
159 used_plugins.insert( filter->GetPluginName( ) );
161 tinyxml2::XMLElement* e = doc->NewElement( "filter" );
162 e->SetAttribute( "category", filter->GetClassCategory( ) );
163 e->SetAttribute( "class", filter->GetClassName( ) );
164 e->SetAttribute( "name", vIt->first.c_str( ) );
165 e->SetAttribute( "ViewX", filter->GetViewX( ) );
166 e->SetAttribute( "ViewY", filter->GetViewY( ) );
168 "ExplicitReExecution", ( filter->GetExplicitReExecution( ) )? 1: 0
171 auto params = filter->GetParameters( );
172 params->ToXML( doc, e );
173 root->LinkEndChild( e );
175 else if( data != NULL )
183 tinyxml2::XMLElement* plugins = doc->NewElement( "plugins" );
184 for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
186 tinyxml2::XMLElement* e = doc->NewElement( "plugin" );
187 e->SetAttribute( "name", pIt->c_str( ) );
188 plugins->LinkEndChild( e );
191 root->LinkEndChild( plugins );
194 auto mIt = this->m_Graph->BeginEdgesRows( );
195 for( ; mIt != this->m_Graph->EndEdgesRows( ); ++mIt )
197 auto rIt = mIt->second.begin( );
198 for( ; rIt != mIt->second.end( ); ++rIt )
200 auto eIt = rIt->second.begin( );
201 for( ; eIt != rIt->second.end( ); ++eIt )
203 tinyxml2::XMLElement* conn = doc->NewElement( "connection" );
204 tinyxml2::XMLElement* orig = doc->NewElement( "origin" );
205 tinyxml2::XMLElement* dest = doc->NewElement( "destination" );
206 orig->SetAttribute( "filter", mIt->first.c_str( ) );
207 orig->SetAttribute( "name", eIt->first.c_str( ) );
208 dest->SetAttribute( "filter", rIt->first.c_str( ) );
209 dest->SetAttribute( "name", eIt->second.c_str( ) );
211 conn->LinkEndChild( orig );
212 conn->LinkEndChild( dest );
213 root->LinkEndChild( conn );
221 // Save exposed ports
222 auto eipIt = this->m_ExposedInputPorts.begin( );
223 for( ; eipIt != this->m_ExposedInputPorts.end( ); ++eipIt )
225 tinyxml2::XMLElement* port = doc->NewElement( "exposed_input_port" );
226 port->SetAttribute( "port_name", eipIt->first.c_str( ) );
227 port->SetAttribute( "filter", eipIt->second.first.c_str( ) );
228 port->SetAttribute( "filter_port_name", eipIt->second.second.c_str( ) );
229 root->LinkEndChild( port );
233 auto eopIt = this->m_ExposedOutputPorts.begin( );
234 for( ; eopIt != this->m_ExposedOutputPorts.end( ); ++eopIt )
236 tinyxml2::XMLElement* port = doc->NewElement( "exposed_output_port" );
237 port->SetAttribute( "port_name", eopIt->first.c_str( ) );
238 port->SetAttribute( "filter", eopIt->second.first.c_str( ) );
239 port->SetAttribute( "filter_port_name", eopIt->second.second.c_str( ) );
240 root->LinkEndChild( port );
244 // Physical write and return
245 doc->LinkEndChild( root );
246 doc->SaveFile( fname.c_str( ) );
248 return( err.str( ) );