]> Creatis software - cpPlugins.git/blobdiff - lib/cpPlugins/WorkspaceIO.cxx
Code cleaning
[cpPlugins.git] / lib / cpPlugins / WorkspaceIO.cxx
diff --git a/lib/cpPlugins/WorkspaceIO.cxx b/lib/cpPlugins/WorkspaceIO.cxx
new file mode 100644 (file)
index 0000000..b9c1558
--- /dev/null
@@ -0,0 +1,251 @@
+#include <cpPlugins/Workspace.h>
+#include <tinyxml2/tinyxml2.h>
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::Workspace::
+LoadWorkspace( const std::string& fname )
+{
+  if( this->m_Interface == NULL )
+    return( "cpPlugins::Workspace: No valid plugins interface" );
+  tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
+  doc->LoadFile( fname.c_str( ) );
+  tinyxml2::XMLElement* root = doc->RootElement( );
+  if( root == NULL )
+    return( "cpPlugins::Workspace: No valid file" );
+  if( std::string( root->Value( ) ) != "cpPlugins_Workspace" )
+    return( "cpPlugins::Workspace: No valid workspace" );
+  std::stringstream err;
+
+  // Load plugins
+  auto loaded_plugins = this->m_Interface->GetPlugins( );
+  tinyxml2::XMLElement* plugins = root->FirstChildElement( "plugins" );
+  std::string plugins_errors = "";
+  while( plugins != NULL )
+  {
+    tinyxml2::XMLElement* plugin = plugins->FirstChildElement( "plugin" );
+    while( plugin != NULL )
+    {
+      std::string name = plugin->Attribute( "name" );
+      if( loaded_plugins.find( name ) == loaded_plugins.end( ) )
+      {
+        try
+        {
+          this->m_Interface->LoadPlugin( name );
+        }
+        catch( std::exception& err )
+        {
+          plugins_errors += err.what( ) + std::string( "\n" );
+
+        } // yrt
+
+      } // fi
+      plugin = plugin->NextSiblingElement( "plugin" );
+
+    } // elihw
+    plugins = plugins->NextSiblingElement( "plugins" );
+
+  } // elihw
+  if( plugins_errors != "" )
+    return( std::string( "cpPlugins::Workspace: " ) + plugins_errors );
+  
+  // Read filters
+  tinyxml2::XMLElement* filter = root->FirstChildElement( "filter" );
+  while( filter != NULL )
+  {
+    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_re_execution = 0;
+    filter->QueryIntAttribute(
+      "ExplicitReExecution", &explicit_re_execution
+      );
+    if( class_value != NULL && name_value != NULL )
+    {
+      if( this->CreateFilter( category_value, class_value, name_value ) )
+      {
+        auto new_filter = this->GetFilter( name_value );
+        new_filter->SetViewCoords( viewX, viewY );
+        new_filter->SetExplicitReExecution( explicit_re_execution == 1 );
+
+        // Read parameters
+        auto parameters = new_filter->GetParameters( );
+        parameters->FromXML( filter );
+      }
+      else
+        err
+          << "No valid class \"" << class_value << "\" with name \""
+          << name_value << "\"" << std::endl;
+    }
+    else
+      err << "Incomplete data." << std::endl;
+    filter = filter->NextSiblingElement( "filter" );
+
+  } // elihw
+
+  // Read connections
+  tinyxml2::XMLElement* connection = root->FirstChildElement( "connection" );
+  while( connection != NULL )
+  {
+    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" );
+      if(
+        orig_filter != NULL && dest_filter != NULL &&
+        orig_name != NULL && dest_name != NULL
+        )
+        this->Connect( orig_filter, dest_filter, orig_name, dest_name );
+
+    } // fi
+    connection = connection->NextSiblingElement( "connection" );
+
+  } // elihw
+
+  // Read exposed inputs
+  tinyxml2::XMLElement* port = root->FirstChildElement( "exposed_input_port" );
+  while( port != NULL )
+  {
+    this->ExposeInputPort(
+      port->Attribute( "port_name" ),
+      port->Attribute( "filter" ),
+      port->Attribute( "filter_port_name" )
+      );
+    port = port->NextSiblingElement( "exposed_input_port" );
+
+  } // elihw
+
+  // Read exposed outputs
+  port = root->FirstChildElement( "exposed_output_port" );
+  while( port != NULL )
+  {
+    this->ExposeOutputPort(
+      port->Attribute( "port_name" ),
+      port->Attribute( "filter" ),
+      port->Attribute( "filter_port_name" )
+      );
+    port = port->NextSiblingElement( "exposed_output_port" );
+
+  } // elihw
+
+  // Finish and return
+  delete doc;
+  return( err.str( ) );
+}
+
+// -------------------------------------------------------------------------
+std::string cpPlugins::Workspace::
+SaveWorkspace( const std::string& fname ) const
+{
+  std::stringstream err;
+  tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument( );
+  tinyxml2::XMLElement* root = doc->NewElement( "cpPlugins_Workspace" );
+  std::set< std::string > used_plugins;
+
+  // Save vertices
+  auto vIt = this->m_Graph->BeginVertices( );
+  for( ; vIt != this->m_Graph->EndVertices( ); ++vIt )
+  {
+    auto filter = dynamic_cast< ProcessObject* >( vIt->second.GetPointer( ) );
+    auto data = dynamic_cast< DataObject* >( vIt->second.GetPointer( ) );
+    if( filter != NULL )
+    {
+      used_plugins.insert( filter->GetPluginName( ) );
+
+      tinyxml2::XMLElement* e = doc->NewElement( "filter" );
+      e->SetAttribute( "category", filter->GetClassCategory( ) );
+      e->SetAttribute( "class", filter->GetClassName( ) );
+      e->SetAttribute( "name", vIt->first.c_str( ) );
+      e->SetAttribute( "ViewX", filter->GetViewX( ) );
+      e->SetAttribute( "ViewY", filter->GetViewY( ) );
+      e->SetAttribute(
+        "ExplicitReExecution", ( filter->GetExplicitReExecution( ) )? 1: 0
+        );
+
+      auto params = filter->GetParameters( );
+      params->ToXML( doc, e );
+      root->LinkEndChild( e );
+    }
+    else if( data != NULL )
+    {
+      // TODO
+    } // fi
+
+  } // rof
+
+  // Save used plugins
+  tinyxml2::XMLElement* plugins = doc->NewElement( "plugins" );
+  for( auto pIt = used_plugins.begin( ); pIt != used_plugins.end( ); ++pIt )
+  {
+    tinyxml2::XMLElement* e = doc->NewElement( "plugin" );
+    e->SetAttribute( "name", pIt->c_str( ) );
+    plugins->LinkEndChild( e );
+
+  } // rof
+  root->LinkEndChild( plugins );
+
+  // Save connections
+  auto mIt = this->m_Graph->BeginEdgesRows( );
+  for( ; mIt != this->m_Graph->EndEdgesRows( ); ++mIt )
+  {
+    auto rIt = mIt->second.begin( );
+    for( ; rIt != mIt->second.end( ); ++rIt )
+    {
+      auto eIt = rIt->second.begin( );
+      for( ; eIt != rIt->second.end( ); ++eIt )
+      {
+        tinyxml2::XMLElement* conn = doc->NewElement( "connection" );
+        tinyxml2::XMLElement* orig = doc->NewElement( "origin" );
+        tinyxml2::XMLElement* dest = doc->NewElement( "destination" );
+        orig->SetAttribute( "filter", mIt->first.c_str( ) );
+        orig->SetAttribute( "name", eIt->first.c_str( ) );
+        dest->SetAttribute( "filter", rIt->first.c_str( ) );
+        dest->SetAttribute( "name", eIt->second.c_str( ) );
+
+        conn->LinkEndChild( orig );
+        conn->LinkEndChild( dest );
+        root->LinkEndChild( conn );
+
+      } // rof
+
+    } // rof
+
+  } // rof
+
+  // Save exposed ports
+  auto eipIt = this->m_ExposedInputPorts.begin( );
+  for( ; eipIt != this->m_ExposedInputPorts.end( ); ++eipIt )
+  {
+    tinyxml2::XMLElement* port = doc->NewElement( "exposed_input_port" );
+    port->SetAttribute( "port_name", eipIt->first.c_str( ) );
+    port->SetAttribute( "filter", eipIt->second.first.c_str( ) );
+    port->SetAttribute( "filter_port_name", eipIt->second.second.c_str( ) );
+    root->LinkEndChild( port );
+
+  } // rof
+
+  auto eopIt = this->m_ExposedOutputPorts.begin( );
+  for( ; eopIt != this->m_ExposedOutputPorts.end( ); ++eopIt )
+  {
+    tinyxml2::XMLElement* port = doc->NewElement( "exposed_output_port" );
+    port->SetAttribute( "port_name", eopIt->first.c_str( ) );
+    port->SetAttribute( "filter", eopIt->second.first.c_str( ) );
+    port->SetAttribute( "filter_port_name", eopIt->second.second.c_str( ) );
+    root->LinkEndChild( port );
+
+  } // rof
+
+  // Physical write and return
+  doc->LinkEndChild( root );
+  doc->SaveFile( fname.c_str( ) );
+  delete doc;
+  return( err.str( ) );
+}
+
+// eof - $RCSfile$