From e8e51ee01f2a547452e36c5de4967a9ebdd42e8b Mon Sep 17 00:00:00 2001
From: Florent Lamiraux <florent@laas.fr>
Date: Tue, 21 Jun 2011 13:47:18 +0200
Subject: [PATCH] dynamicgraph::sot is now a singleton

    Replace sotPool by call to static method getInstance.
---
 doc/additionalDoc/package.h      |  38 ++++------
 include/sot/core/pool.hh         |  14 +++-
 src/factory/pool.cpp             |  68 ++++++++++-------
 src/feature/feature-abstract.cpp |   2 +-
 src/signal/signal-cast.cpp       |   2 +-
 src/sot/sot-command.h            |  11 +--
 src/sot/sot-qr.cpp               | 122 -------------------------------
 src/sot/sot.cpp                  |  22 ------
 src/task/task-abstract.cpp       |   2 +-
 src/task/task-command.h          |   3 +-
 src/task/task.cpp                |   3 -
 11 files changed, 78 insertions(+), 209 deletions(-)

diff --git a/doc/additionalDoc/package.h b/doc/additionalDoc/package.h
index 70c1f683..5376aae9 100644
--- a/doc/additionalDoc/package.h
+++ b/doc/additionalDoc/package.h
@@ -11,12 +11,10 @@ having high level software capabilities, like plugins and scripts.
 The code is based on the dynamic-graph package, which provides the
 framework from which sot-core relies. Hence most of the code in sot-core
 consists of classes that derive from entities. These entities are usually
-compiled and linked in their own dynamic library, as a "plugin"; hence
-you may choose to include (load) in your program only the ones you
-need.
+compiled and linked in their own dynamic library, as a python module
 
 Aside from the entities, there is a code base to the library, libsot-core,
-that provides functions and code common to all modules. All plugins
+that provides functions and code common to all modules. All python modules
 developed here link with libsot-core. For example, common mathematical
 entities, definitions and functions are in that library's base.
 See \ref sot_core_base for a list of what's in this code base.
@@ -37,7 +35,7 @@ alone is insufficient to simulate and control a robot.
 The following packages are recommended* in that case:
 \li sot-dynamic
 \li sot-pattern-generator
-\li sot-openhrp (openhrp plugin)
+\li sot-openhrp (openhrp python module)
 \li sot-openhrp-scripts
 
 * These packages are in development at the time of writing and may
@@ -66,12 +64,12 @@ This package is centered around a base library that implements
 the basic classes needed for operation of the stack of tasks. For
 more information, see \ref sot_core_base.
 
-\section sot_plugins Plugins
+\section sot_plugins Python Modules
 While the main library provides a basic framework for computation of a
 control law using the Stack of Tasks, it is not expressive enough for
 typical usage scenarios (for example, controlling the humanoid robot
 HRP-2). Hence, several "specialized" features and tasks have been developed,
-and can be used in the Stack of Tasks. For a list of plugins and a short
+and can be used in the Stack of Tasks. For a list of python modules and a short
 description, see \ref plugins_list.
 
 \section operation Operation of the stack of tasks
@@ -145,13 +143,13 @@ the dynamic-graph package).
 
 \subsection subsec_Features Features
 The class sot::FeatureAbstract is the base class for features.
-all other classes are in entity \ref sot_plugins "plugins".
+all other classes are in entity \ref sot_plugins "python modules".
 For more information on what is a feature, see \ref features.
 
 \subsection subsec_Tasks Tasks
 They are a certain number of pre-written tasks that can be used.
 They all derive from the task sot::TaskAbstract; specific tasks
-are defined as \ref sot_plugins "plugins".
+are defined as \ref sot_plugins "python modules".
 
 \subsection subsec_tools Mathematical base
 The following classes encapsulate common mathematical objects, and
@@ -169,8 +167,8 @@ See \ref factory for additional information.
 
 
 
-\defgroup plugins_list List of plugins
-These plugins are linked with the base library.
+\defgroup plugins_list List of python modules
+These python modules are linked with the base library.
 
 	sot/sot-qr
 	sot/weighted-sot
@@ -234,26 +232,18 @@ This code implements the factory design pattern, making creation of features,
 tasks and other objects available.
 
 Objects, which are derived from Entities, Tasks, or Features, can be
- declared within the code and compiled to shared librairies (.so/.dll files).
-These librairies can be loaded at run-time using the sotPluginLoader methods,
-and at the same time register their class names to the Factory (see the
-sotFactory documentation to learn how).
+ declared within the code and compiled to C++ python modules.  These
+ modules can be imported at run-time and register their class names to
+ the Factory (see the sotFactory documentation to learn how).
 
 The Factory can then create instances of these objects and subsequently
 register them in the Pool, where they can be listed, accessed, and acted upon
-(see sotPoolStorage documentation). Basic commands defined by entities include
+(see sot::PoolStorage documentation). Basic commands defined by entities include
 signal connection graph file generation, help and name print, and signals.
 
-Finally, a shell (command-line) interface is made available thanks to the
-sotInterpretor class (see the file test_shell.cpp). Objects deriving from
-Entity can expose their own commands by overriding the Entity's default
-commandLine() method. It is possible to load a plugin to register custom
-shell commands; see sotShellFunctions and sotShellProcedure for an example.
-
 The public static objects (singletons) made available by including the
 corresponding headers in this module are:
-\li sotFactory: sotFactoryStorage
-\li sotPool: sotPoolStorage
+\li sot::PoolStorage, accessed by method getInstance.
 
 \image html schema_plugin.png
 
diff --git a/include/sot/core/pool.hh b/include/sot/core/pool.hh
index 542fa790..959c4b9d 100644
--- a/include/sot/core/pool.hh
+++ b/include/sot/core/pool.hh
@@ -48,7 +48,7 @@ class TaskAbstract;
 
 
 /*! @ingroup factory
-  \brief This class keep tracks of all the objects in the stack of Tasks.
+  \brief This singleton class keep tracks of all features and tasks.
 
   Three kinds of objects are handled:
   \li The controllers, i.e. the tasks which inherits from TaskAbstract.
@@ -99,6 +99,12 @@ class SOT_CORE_EXPORT PoolStorage
   /*! \brief Default destructor */
   ~PoolStorage( void );
 
+  /// \brief Get unique instance of the class
+  static PoolStorage* getInstance();
+
+  /// \brief destroy unique instance of the class
+  static void destroy();
+
   /*! \name Methods related to the handling of the features
     @{
    */
@@ -134,9 +140,11 @@ class SOT_CORE_EXPORT PoolStorage
   /*! \brief This method write a graph description on the file named FileName. */
   void writeGraph(const std::string &aFileName);
   void writeCompletionList(std::ostream& os);
-};
 
-SOT_CORE_EXPORT extern sot::PoolStorage sotPool;
+ private:
+  PoolStorage();
+  static PoolStorage* instance_;
+};
 
 } /* namespace sot */} /* namespace dynamicgraph */
 
diff --git a/src/factory/pool.cpp b/src/factory/pool.cpp
index 87521dec..1840d6aa 100644
--- a/src/factory/pool.cpp
+++ b/src/factory/pool.cpp
@@ -38,18 +38,18 @@ namespace dynamicgraph {
     /* --------------------------------------------------------------------- */
     /* --- CLASS ----------------------------------------------------------- */
     /* --------------------------------------------------------------------- */
-    
+
     PoolStorage::
     ~PoolStorage( void )
     {
       sotDEBUGIN(15);
-      
-      
+
+
       sotDEBUGOUT(15);
       return;
     }
-    
-    
+
+
     /* --------------------------------------------------------------------- */
     void PoolStorage::
     registerTask( const std::string& entname,TaskAbstract* ent )
@@ -69,7 +69,7 @@ namespace dynamicgraph {
 	  task[entname] = ent;
 	}
     }
-    
+
     TaskAbstract& PoolStorage::
     getTask( const std::string& name )
     {
@@ -82,9 +82,9 @@ namespace dynamicgraph {
 	}
       return *entPtr->second;
     }
-    
-    
-    
+
+
+
     /* --------------------------------------------------------------------- */
     void PoolStorage::
     registerFeature( const std::string& entname,FeatureAbstract* ent )
@@ -104,7 +104,7 @@ namespace dynamicgraph {
 	  feature[entname] = ent;
 	}
     }
-    
+
     FeatureAbstract& PoolStorage::
     getFeature( const std::string& name )
     {
@@ -117,7 +117,7 @@ namespace dynamicgraph {
 	}
       return *entPtr->second;
     }
-    
+
     void PoolStorage::
     writeGraph(const std::string &aFileName)
     {
@@ -129,7 +129,7 @@ namespace dynamicgraph {
 	GenericName = tmp1.substr(IdxSeparatorFound,tmp1.length());
       else
 	GenericName = tmp1;
-      
+
       /* Reading local time */
       time_t ltime;
       ltime = time(NULL);
@@ -139,7 +139,7 @@ namespace dynamicgraph {
 #else
       localtime_r(&ltime,&ltimeformatted);
 #endif /*WIN32*/
-      
+
       /* Opening the file and writing the first comment. */
       std::ofstream GraphFile;
       GraphFile.open(aFileName.c_str(),std::ofstream::out);
@@ -158,7 +158,7 @@ namespace dynamicgraph {
 	"fillcolor = gold1, style=filled, shape=box ] ; " << std::endl;
       GraphFile << "\tsubgraph cluster_Tasks { " << std::endl;
       GraphFile << "\t\t color=blue; label=\"Tasks\";" << std::endl;
-      
+
       for( Tasks::iterator iter=task.begin();
 	   iter!=task.end();iter++ )
 	{
@@ -168,27 +168,43 @@ namespace dynamicgraph {
 		    <<"\t\t   fontcolor = black, color = black, "
 	    "fillcolor = magenta, style=filled, shape=box ]" << std::endl;
 	}
-      
-      
+
+
       GraphFile << "}"<< std::endl;
-      
+
       GraphFile.close();
     }
-    
+
     void PoolStorage::
     writeCompletionList(std::ostream& /*os*/ )
     {
     }
-    
-    
+
+
     void PoolStorage::
-    commandLine( const std::string& objectName,const std::string& functionName,
-		 std::istringstream& cmdArg, std::ostream& os )
+    commandLine( const std::string&,const std::string&,
+		 std::istringstream&, std::ostream& )
     {
     }
-    
-    /// The global sotPool object
-    
-    PoolStorage sotPool;
+
+
+    PoolStorage* PoolStorage::getInstance()
+    {
+      if (instance_ == 0) {
+	instance_ = new PoolStorage;
+      }
+      return instance_;
+    }
+    void PoolStorage::destroy()
+    {
+      delete instance_;
+      instance_ = 0;
+    }
+
+    PoolStorage::PoolStorage()
+    {
+    }
+
+    PoolStorage* PoolStorage::instance_ = 0;
   } // namespace sot
 } // namespace dynamicgraph
diff --git a/src/feature/feature-abstract.cpp b/src/feature/feature-abstract.cpp
index 3d93e4d2..dc1f0cdc 100644
--- a/src/feature/feature-abstract.cpp
+++ b/src/feature/feature-abstract.cpp
@@ -57,7 +57,7 @@ FeatureAbstract( const std::string& name )
 void FeatureAbstract::
 featureRegistration( void )
 {
-  sotPool.registerFeature(name,this);
+  PoolStorage::getInstance()->registerFeature(name,this);
 }
 
 
diff --git a/src/signal/signal-cast.cpp b/src/signal/signal-cast.cpp
index 8aefab6f..07875ae9 100644
--- a/src/signal/signal-cast.cpp
+++ b/src/signal/signal-cast.cpp
@@ -76,7 +76,7 @@ namespace dynamicgraph
     std::string name; iss >> name;
     if( name.length())
       {
-	ref = &sotPool.getFeature(name);
+	ref = &dynamicgraph::sot::PoolStorage::getInstance()->getFeature(name);
       }
     else { ref = NULL; }
     return ref;
diff --git a/src/sot/sot-command.h b/src/sot/sot-command.h
index 10803d9d..ad127fa3 100644
--- a/src/sot/sot-command.h
+++ b/src/sot/sot-command.h
@@ -51,7 +51,8 @@ namespace dynamicgraph { namespace sot {
 	  std::string constraintName = values[0].value();
 
 	  Constraint& constraint =
-	    dynamic_cast<Constraint&>(sotPool.getTask(constraintName));
+	    dynamic_cast<Constraint&>(PoolStorage::getInstance()->
+				      getTask(constraintName));
 	  sot.addConstraint(constraint);
 	  sot.constraintSOUT.setReady();
 	  // return void
@@ -77,7 +78,7 @@ namespace dynamicgraph { namespace sot {
 	  std::vector<Value> values = getParameterValues();
 	  std::string taskName = values[0].value();
 
-	  TaskAbstract& task = sotPool.getTask(taskName);
+	  TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName);
 	  sot.push(task);
 	  // return void
 	  return Value();
@@ -102,7 +103,7 @@ namespace dynamicgraph { namespace sot {
 	  std::vector<Value> values = getParameterValues();
 	  std::string taskName = values[0].value();
 
-	  TaskAbstract& task = sotPool.getTask(taskName);
+	  TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName);
 	  sot.remove(task);
 	  // return void
 	  return Value();
@@ -127,7 +128,7 @@ namespace dynamicgraph { namespace sot {
 	  std::vector<Value> values = getParameterValues();
 	  std::string taskName = values[0].value();
 
-	  TaskAbstract& task = sotPool.getTask(taskName);
+	  TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName);
 	  sot.up(task);
 	  // return void
 	  return Value();
@@ -152,7 +153,7 @@ namespace dynamicgraph { namespace sot {
 	  std::vector<Value> values = getParameterValues();
 	  std::string taskName = values[0].value();
 
-	  TaskAbstract& task = sotPool.getTask(taskName);
+	  TaskAbstract& task = PoolStorage::getInstance()->getTask(taskName);
 	  sot.down(task);
 	  // return void
 	  return Value();
diff --git a/src/sot/sot-qr.cpp b/src/sot/sot-qr.cpp
index d09aaed1..f7a74e42 100644
--- a/src/sot/sot-qr.cpp
+++ b/src/sot/sot-qr.cpp
@@ -992,128 +992,6 @@ void SotQr::
 commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,
 	     std::ostream& os )
 {
-  sotDEBUGIN(15);
-
-  if( cmdLine == "help")
-    {
-      os << "Stack of Tasks: "<<endl
-	 << " - push <task>"<< endl
-	 << " - pop"<< endl
-	 << " - down <task>"<< endl
-	 << " - up <task>"<< endl
-	 << " - rm <task>"<< endl
-	 << " - clear"<< endl
-	 << " - display"<< endl
-
-	 << " - addConstraint <constraint> "<<endl
-	 << " - rmConstraint <constraint> "<<endl
-	 << " - clearConstraint"<<endl
-	 << " - printConstraint "<<endl
-
-	 << " - nbJoints <nb> "<<endl;
-      Entity::commandLine( cmdLine,cmdArgs,os );
-    }
-  else if( cmdLine == "clear")
-    {
-      clear();
-    }
-  else if( cmdLine == "push")
-    {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      push(task);
-    }
-  else if( cmdLine == "gradient")
-    {
-      std::string tname; cmdArgs >> std::ws;
-      if( cmdArgs.good() )
-	{
-	  cmdArgs >> tname;
-	  if( ( "0"==tname )||( "rm"==tname ) )
-	    { taskGradient = 0; }
-	  else
-	    {
-	      TaskAbstract & task = sotPool.getTask( tname );
-	      taskGradient = &task;
-	    }
-	}
-      else
-	{
-	  os << "gradient = ";
-	  if( taskGradient ) os << (*taskGradient) << std::endl;
-	  else os << "undef. " << std::endl;
-	}
-      controlSOUT.setReady();
-    }
-  else if( cmdLine == "up")
-    {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      up(task);
-    }
-  else if( cmdLine == "down")
-    {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      down(task);
-    }
-  else if( cmdLine == "rm")
-    {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      remove(task);
-    }
-  else if( cmdLine == "pop")
-    {
-      TaskAbstract& task = pop();
-      os << "Remove : "<< task << std::endl;
-    }
-
-  else if( cmdLine == "addConstraint" )
-    {
-      std::string cstname; cmdArgs >> cstname;
-      Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname ));
-      addConstraint( cs );
-      constraintSOUT.setReady();
-    }
-  else if( cmdLine == "rmConstraint" )
-    {
-      std::string cstname; cmdArgs >> cstname;
-      Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname ));
-      removeConstraint( cs );
-      constraintSOUT.setReady();
-    }
-  else if( cmdLine == "clearConstraint" )
-    {
-      clearConstraint( );
-      constraintSOUT.setReady();
-    }
-  else if( cmdLine == "printConstraint" )
-    {
-      os<< "Constraints: "<<std::endl;
-      for( ConstraintListType::iterator it = constraintList.begin();
-	   it!=constraintList.end();++it )
-	{ os<< "  - "<< (*it)->getName() << endl; }
-    }
-  else if( cmdLine == "nbJoints")
-    {
-      cmdArgs>>ws;
-      if( cmdArgs.good() )
-	{
-	  cmdArgs >> nbJoints;
-	} else { os << "nbJoints = "<< nbJoints <<endl; }
-      constraintSOUT.setReady();
-      controlSOUT.setReady();
-    }
-  else if( cmdLine == "display")
-    {
-      display(os);
-    }
-  else
-    Entity::commandLine( cmdLine,cmdArgs,os );
-
-
-  sotDEBUGOUT(15);
 }
 
 std::ostream& SotQr::
diff --git a/src/sot/sot.cpp b/src/sot/sot.cpp
index 4f41c1d2..2fd0f793 100644
--- a/src/sot/sot.cpp
+++ b/src/sot/sot.cpp
@@ -899,9 +899,6 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,
     }
   else if( cmdLine == "push")
     {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      push(task);
     }
   else if( cmdLine == "gradient")
     {
@@ -913,8 +910,6 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,
 	    { taskGradient = 0; }
 	  else
 	    {
-	      TaskAbstract & task = sotPool.getTask( tname );
-	      taskGradient = &task;
 	    }
 	}
       else
@@ -927,21 +922,12 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,
     }
   else if( cmdLine == "up")
     {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      up(task);
     }
   else if( cmdLine == "down")
     {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      down(task);
     }
   else if( cmdLine == "rm")
     {
-      std::string tname; cmdArgs >> tname;
-      TaskAbstract & task = sotPool.getTask( tname );
-      remove(task);
     }
   else if( cmdLine == "pop")
     {
@@ -951,17 +937,9 @@ commandLine( const std::string& cmdLine,std::istringstream& cmdArgs,
 
   else if( cmdLine == "addConstraint" )
     {
-      std::string cstname; cmdArgs >> cstname;
-      Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname ));
-      addConstraint( cs );
-      constraintSOUT.setReady();
     }
   else if( cmdLine == "rmConstraint" )
     {
-      std::string cstname; cmdArgs >> cstname;
-      Constraint &cs = dynamic_cast<Constraint&>(sotPool.getTask( cstname ));
-      removeConstraint( cs );
-      constraintSOUT.setReady();
     }
   else if( cmdLine == "clearConstraint" )
     {
diff --git a/src/task/task-abstract.cpp b/src/task/task-abstract.cpp
index 28581d03..2dca7ba6 100644
--- a/src/task/task-abstract.cpp
+++ b/src/task/task-abstract.cpp
@@ -52,7 +52,7 @@ TaskAbstract( const std::string& n )
 void TaskAbstract::
 taskRegistration( void )
 {
-  sotPool.registerTask(name,this);
+  PoolStorage::getInstance()->registerTask(name,this);
 }
 
 
diff --git a/src/task/task-command.h b/src/task/task-command.h
index 0ed72515..806b7d46 100644
--- a/src/task/task-command.h
+++ b/src/task/task-command.h
@@ -49,7 +49,8 @@ namespace dynamicgraph { namespace sot {
 	  Task& task = static_cast<Task&>(owner());
 	  std::vector<Value> values = getParameterValues();
 	  std::string featureName = values[0].value();
-	  FeatureAbstract& feature = sotPool.getFeature(featureName);
+	  FeatureAbstract& feature =
+	    PoolStorage::getInstance()->getFeature(featureName);
 	  task.addFeature(feature);
 	  // return void
 	  return Value();
diff --git a/src/task/task.cpp b/src/task/task.cpp
index f9cc07f5..9bc5cc28 100644
--- a/src/task/task.cpp
+++ b/src/task/task.cpp
@@ -370,9 +370,6 @@ commandLine( const std::string& cmdLine
     }
   else if( cmdLine=="add" )
     {
-      std::string f; cmdArgs >> f;
-      FeatureAbstract& feat = sotPool.getFeature( f );
-      addFeature( feat );
     }
   else if( cmdLine=="selec" )
     {
-- 
GitLab