]> Creatis software - cpPlugins.git/blob - lib/cpPlugins/WorkspaceIO.cxx
...
[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     if( class_value != NULL && name_value != NULL )
62     {
63       if( this->CreateFilter( category_value, class_value, name_value ) )
64       {
65         auto new_filter = this->GetFilter( name_value );
66         new_filter->SetViewCoords( viewX, viewY );
67
68         // Read parameters
69         auto parameters = new_filter->GetParameters( );
70         parameters->FromXML( filter );
71       }
72       else
73         err
74           << "No valid class \"" << class_value << "\" with name \""
75           << name_value << "\"" << std::endl;
76     }
77     else
78       err << "Incomplete data." << std::endl;
79     filter = filter->NextSiblingElement( "filter" );
80
81   } // elihw
82
83   // Read connections
84   tinyxml2::XMLElement* connection = root->FirstChildElement( "connection" );
85   while( connection != NULL )
86   {
87     tinyxml2::XMLElement* orig = connection->FirstChildElement( "origin" );
88     tinyxml2::XMLElement* dest = connection->FirstChildElement( "destination" );
89     if( orig != NULL && dest != NULL )
90     {
91       const char* orig_filter = orig->Attribute( "filter" );
92       const char* dest_filter = dest->Attribute( "filter" );
93       const char* orig_name = orig->Attribute( "name" );
94       const char* dest_name = dest->Attribute( "name" );
95       if(
96         orig_filter != NULL && dest_filter != NULL &&
97         orig_name != NULL && dest_name != NULL
98         )
99         this->Connect( orig_filter, dest_filter, orig_name, dest_name );
100
101     } // fi
102     connection = connection->NextSiblingElement( "connection" );
103
104   } // elihw
105
106   // Read exposed inputs
107   tinyxml2::XMLElement* port = root->FirstChildElement( "exposed_input_port" );
108   while( port != NULL )
109   {
110     this->ExposeInputPort(
111       port->Attribute( "port_name" ),
112       port->Attribute( "filter" ),
113       port->Attribute( "filter_port_name" )
114       );
115     port = port->NextSiblingElement( "exposed_input_port" );
116
117   } // elihw
118
119   // Read exposed outputs
120   port = root->FirstChildElement( "exposed_output_port" );
121   while( port != NULL )
122   {
123     this->ExposeOutputPort(
124       port->Attribute( "port_name" ),
125       port->Attribute( "filter" ),
126       port->Attribute( "filter_port_name" )
127       );
128     port = port->NextSiblingElement( "exposed_output_port" );
129
130   } // elihw
131
132   // Finish and return
133   delete doc;
134   return( err.str( ) );
135 }
136
137 // -------------------------------------------------------------------------
138 std::string cpPlugins::Workspace::
139 SaveWorkspace( const std::string& fname ) const
140 {
141   std::stringstream err;
142   tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
143   tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
144   std::set< std::string > used_plugins;
145
146   // Save vertices
147   auto vIt = this->m_Graph->BeginVertices( );
148   for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
149   {
150     auto filter = dynamic_cast< ProcessObject* >( vIt->second.GetPointer( ) );
151     auto data = dynamic_cast< DataObject* >( vIt->second.GetPointer( ) );
152     if( filter != NULL )
153     {
154       used_plugins.insert( this->m_Interface->GetPluginName( filter ) );
155
156       tinyxml2::XMLElement* e = doc->NewElement( "filter" );
157       e->SetAttribute( "category", filter->GetClassCategory( ) );
158       e->SetAttribute( "class", filter->GetClassName( ) );
159       e->SetAttribute( "name", vIt->first.c_str( ) );
160       e->SetAttribute( "ViewX", filter->GetViewX( ) );
161       e->SetAttribute( "ViewY", filter->GetViewY( ) );
162
163       auto params = filter->GetParameters( );
164       params->ToXML( doc, e );
165       root->LinkEndChild( e );
166     }
167     else if( data != NULL )
168     {
169       // TODO
170     } // fi
171
172   } // rof
173
174   // Save used plugins
175   tinyxml2::XMLElement* plugins = doc->NewElement( "plugins" );
176   for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
177   {
178     tinyxml2::XMLElement* e = doc->NewElement( "plugin" );
179     e->SetAttribute( "name", pIt->c_str( ) );
180     plugins->LinkEndChild( e );
181
182   } // rof
183   root->LinkEndChild( plugins );
184
185   // Save connections
186   auto mIt = this->m_Graph->BeginEdgesRows( );
187   for( ; mIt != this->m_Graph->EndEdgesRows( ); ++mIt )
188   {
189     auto rIt = mIt->second.begin( );
190     for( ; rIt != mIt->second.end( ); ++rIt )
191     {
192       auto eIt = rIt->second.begin( );
193       for( ; eIt != rIt->second.end( ); ++eIt )
194       {
195         tinyxml2::XMLElement* conn = doc->NewElement( "connection" );
196         tinyxml2::XMLElement* orig = doc->NewElement( "origin" );
197         tinyxml2::XMLElement* dest = doc->NewElement( "destination" );
198         orig->SetAttribute( "filter", mIt->first.c_str( ) );
199         orig->SetAttribute( "name", eIt->first.c_str( ) );
200         dest->SetAttribute( "filter", rIt->first.c_str( ) );
201         dest->SetAttribute( "name", eIt->second.c_str( ) );
202
203         conn->LinkEndChild( orig );
204         conn->LinkEndChild( dest );
205         root->LinkEndChild( conn );
206
207       } // rof
208
209     } // rof
210
211   } // rof
212
213   // Save exposed ports
214   auto eipIt = this->m_ExposedInputPorts.begin( );
215   for( ; eipIt != this->m_ExposedInputPorts.end( ); ++eipIt )
216   {
217     tinyxml2::XMLElement* port = doc->NewElement( "exposed_input_port" );
218     port->SetAttribute( "port_name", eipIt->first.c_str( ) );
219     port->SetAttribute( "filter", eipIt->second.first.c_str( ) );
220     port->SetAttribute( "filter_port_name", eipIt->second.second.c_str( ) );
221     root->LinkEndChild( port );
222
223   } // rof
224
225   auto eopIt = this->m_ExposedOutputPorts.begin( );
226   for( ; eopIt != this->m_ExposedOutputPorts.end( ); ++eopIt )
227   {
228     tinyxml2::XMLElement* port = doc->NewElement( "exposed_output_port" );
229     port->SetAttribute( "port_name", eopIt->first.c_str( ) );
230     port->SetAttribute( "filter", eopIt->second.first.c_str( ) );
231     port->SetAttribute( "filter_port_name", eopIt->second.second.c_str( ) );
232     root->LinkEndChild( port );
233
234   } // rof
235
236   // Physical write and return
237   doc->LinkEndChild( root );
238   doc->SaveFile( fname.c_str( ) );
239   delete doc;
240   return( err.str( ) );
241 }
242
243 // eof - $RCSfile$