]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/WorkspaceIO.cxx
0b48fc9ea6b0a74a577ab7b8e0d276f71cba38ad
[cpPlugins.git] / lib / cpPlugins / WorkspaceIO.cxx
1 #include <cpPlugins/Workspace.h>
2 #include <tinyxml/tinyxml2.h>
3
4 // -------------------------------------------------------------------------
5 std::string cpPlugins::Workspace::
6 LoadWorkspace( const std::string& fname )
7 {
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( );
13   if( root == NULL )
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;
18
19   // Load plugins
20   auto loaded_plugins = this->m_Interface->GetPlugins( );
21   tinyxml2::XMLElement* plugins = root->FirstChildElement( "plugins" );
22   std::string plugins_errors = "";
23   while( plugins != NULL )
24   {
25     tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "plugin" );
26     while( plugin != NULL )
27     {
28       std::string name = plugin->Attribute( "name" );
29       if( loaded_plugins.find( name ) == loaded_plugins.end( ) )
30       {
31         try
32         {
33           this->m_Interface->LoadPlugin( name );
34         }
35         catch( std::exception& err )
36         {
37           plugins_errors += err.what( ) + std::string( "\n" );
38
39         } // yrt
40
41       } // fi
42       plugin = plugin->NextSiblingElement( "plugin" );
43
44     } // elihw
45     plugins = plugins->NextSiblingElement( "plugins" );
46
47   } // elihw
48   if( plugins_errors != "" )
49     return( std::string( "cpPlugins::Workspace: " ) + plugins_errors );
50   
51   // Read filters
52   tinyxml2::XMLElement* filter = root->FirstChildElement( "filter" );
53   while( filter != NULL )
54   {
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
64       );
65     if( class_value != NULL && name_value != NULL )
66     {
67       if( this->CreateFilter( category_value, class_value, name_value ) )
68       {
69         auto new_filter = this->GetFilter( name_value );
70         new_filter->SetViewCoords( viewX, viewY );
71         new_filter->SetExplicitReExecution( explicit_re_execution == 1 );
72
73         // Read parameters
74         auto parameters = new_filter->GetParameters( );
75         parameters->FromXML( filter );
76       }
77       else
78         err
79           << "No valid class \"" << class_value << "\" with name \""
80           << name_value << "\"" << std::endl;
81     }
82     else
83       err << "Incomplete data." << std::endl;
84     filter = filter->NextSiblingElement( "filter" );
85
86   } // elihw
87
88   // Read connections
89   tinyxml2::XMLElement* connection = root->FirstChildElement( "connection" );
90   while( connection != NULL )
91   {
92     tinyxml2::XMLElement* orig = connection->FirstChildElement( "origin" );
93     tinyxml2::XMLElement* dest = connection->FirstChildElement( "destination" );
94     if( orig != NULL && dest != NULL )
95     {
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" );
100       if(
101         orig_filter != NULL && dest_filter != NULL &&
102         orig_name != NULL && dest_name != NULL
103         )
104         this->Connect( orig_filter, dest_filter, orig_name, dest_name );
105
106     } // fi
107     connection = connection->NextSiblingElement( "connection" );
108
109   } // elihw
110
111   // Read exposed inputs
112   tinyxml2::XMLElement* port = root->FirstChildElement( "exposed_input_port" );
113   while( port != NULL )
114   {
115     this->ExposeInputPort(
116       port->Attribute( "port_name" ),
117       port->Attribute( "filter" ),
118       port->Attribute( "filter_port_name" )
119       );
120     port = port->NextSiblingElement( "exposed_input_port" );
121
122   } // elihw
123
124   // Read exposed outputs
125   port = root->FirstChildElement( "exposed_output_port" );
126   while( port != NULL )
127   {
128     this->ExposeOutputPort(
129       port->Attribute( "port_name" ),
130       port->Attribute( "filter" ),
131       port->Attribute( "filter_port_name" )
132       );
133     port = port->NextSiblingElement( "exposed_output_port" );
134
135   } // elihw
136
137   // Finish and return
138   delete doc;
139   return( err.str( ) );
140 }
141
142 // -------------------------------------------------------------------------
143 std::string cpPlugins::Workspace::
144 SaveWorkspace( const std::string& fname ) const
145 {
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;
150
151   // Save vertices
152   auto vIt = this->m_Graph->BeginVertices( );
153   for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
154   {
155     auto filter = dynamic_cast< ProcessObject* >( vIt->second.GetPointer( ) );
156     auto data = dynamic_cast< DataObject* >( vIt->second.GetPointer( ) );
157     if( filter != NULL )
158     {
159       used_plugins.insert( this->m_Interface->GetPluginName( filter ) );
160
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( ) );
167       e->SetAttribute(
168         "ExplicitReExecution", ( filter->GetExplicitReExecution( ) )? 1: 0
169         );
170
171       auto params = filter->GetParameters( );
172       params->ToXML( doc, e );
173       root->LinkEndChild( e );
174     }
175     else if( data != NULL )
176     {
177       // TODO
178     } // fi
179
180   } // rof
181
182   // Save used plugins
183   tinyxml2::XMLElement* plugins = doc->NewElement( "plugins" );
184   for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
185   {
186     tinyxml2::XMLElement* e = doc->NewElement( "plugin" );
187     e->SetAttribute( "name", pIt->c_str( ) );
188     plugins->LinkEndChild( e );
189
190   } // rof
191   root->LinkEndChild( plugins );
192
193   // Save connections
194   auto mIt = this->m_Graph->BeginEdgesRows( );
195   for( ; mIt != this->m_Graph->EndEdgesRows( ); ++mIt )
196   {
197     auto rIt = mIt->second.begin( );
198     for( ; rIt != mIt->second.end( ); ++rIt )
199     {
200       auto eIt = rIt->second.begin( );
201       for( ; eIt != rIt->second.end( ); ++eIt )
202       {
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( ) );
210
211         conn->LinkEndChild( orig );
212         conn->LinkEndChild( dest );
213         root->LinkEndChild( conn );
214
215       } // rof
216
217     } // rof
218
219   } // rof
220
221   // Save exposed ports
222   auto eipIt = this->m_ExposedInputPorts.begin( );
223   for( ; eipIt != this->m_ExposedInputPorts.end( ); ++eipIt )
224   {
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 );
230
231   } // rof
232
233   auto eopIt = this->m_ExposedOutputPorts.begin( );
234   for( ; eopIt != this->m_ExposedOutputPorts.end( ); ++eopIt )
235   {
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 );
241
242   } // rof
243
244   // Physical write and return
245   doc->LinkEndChild( root );
246   doc->SaveFile( fname.c_str( ) );
247   delete doc;
248   return( err.str( ) );
249 }
250
251 // eof - $RCSfile$