Skip to content
Snippets Groups Projects
pool.cpp 8.38 KiB
Newer Older
Thomas Moulard's avatar
Thomas Moulard committed
/*
 * Copyright 2010,
 * François Bleibel,
 * Olivier Stasse,
Thomas Moulard's avatar
Thomas Moulard committed
 * CNRS/AIST
Thomas Moulard's avatar
Thomas Moulard committed
 * This file is part of dynamic-graph.
 * dynamic-graph is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * dynamic-graph is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.  You should
 * have received a copy of the GNU Lesser General Public License along
 * with dynamic-graph.  If not, see <http://www.gnu.org/licenses/>.
 */

/* --------------------------------------------------------------------- */
/* --- INCLUDE --------------------------------------------------------- */
/* --------------------------------------------------------------------- */

/* --- DYNAMIC-GRAPH --- */
#include <iostream>
#include <sstream>
#include <string>
#include "dynamic-graph/pool.h"
#include "dynamic-graph/debug.h"
#include "dynamic-graph/entity.h"

using namespace dynamicgraph;

/* --------------------------------------------------------------------- */
/* --- CLASS ----------------------------------------------------------- */
/* --------------------------------------------------------------------- */

PoolStorage* PoolStorage::
getInstance()
{
  if (instance_ == 0) {
    instance_ = new PoolStorage;
  }
  return instance_;
}

void PoolStorage::
destroy()
{
  delete instance_;
  instance_ = NULL;
}

Thomas Moulard's avatar
Thomas Moulard committed
~PoolStorage  ()
  for( Entities::iterator iter=entityMap.begin (); iter!=entityMap.end ();
       iter=entityMap.begin ())
    {
      dgDEBUG(15) << "Delete \""
		   << (iter->first) <<"\""<<std::endl;
      Entity* entity = iter->second;
      deregisterEntity(iter);
      delete (entity);
  dgDEBUGOUT(15);
}



/* --------------------------------------------------------------------- */
void PoolStorage::
registerEntity( const std::string& entname,Entity* ent )
{
  Entities::iterator entkey = entityMap.find(entname);
  if( entkey != entityMap.end () ) // key does exist
    {
      throw ExceptionFactory( ExceptionFactory::OBJECT_CONFLICT,
				 "Another entity already defined with the same name. ",
Thomas Moulard's avatar
Thomas Moulard committed
				 "Entity name is <%s>.",entname.c_str () );
    }
  else
    {
      dgDEBUG(10) << "Register entity <"<< entname
		   << "> in the pool." <<std::endl;
      entityMap[entname] = ent;
    }
}

void PoolStorage::
deregisterEntity( const std::string& entname )
{
  Entities::iterator entkey = entityMap.find(entname);
  if( entkey == entityMap.end () ) // key doesnot exist
    {
      throw ExceptionFactory( ExceptionFactory::OBJECT_CONFLICT,
				 "Entity not defined yet. ",
Thomas Moulard's avatar
Thomas Moulard committed
				 "Entity name is <%s>.",entname.c_str () );
    }
  else
    {
      dgDEBUG(10) << "Deregister entity <"<< entname
		   << "> from the pool." <<std::endl;
      deregisterEntity(entkey);
void PoolStorage::
deregisterEntity( const Entities::iterator& entity )
{
  entityMap.erase( entity );
}

Entity& PoolStorage::
getEntity( const std::string& name )
{
  dgDEBUG(25) << "Get <" << name << ">"<<std::endl;
  Entities::iterator entPtr = entityMap.find( name );
  if( entPtr == entityMap.end () )
    {
      DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_OBJECT,
				     "Unknown entity."," (while calling <%s>)",
Thomas Moulard's avatar
Thomas Moulard committed
				     name.c_str () );
const PoolStorage::Entities& PoolStorage::
getEntityMap () const
{
  return entityMap;
}

bool PoolStorage::
existEntity (const std::string& name)
{
  return entityMap.find( name ) != entityMap.end();
}
bool PoolStorage::
existEntity (const std::string& name, Entity*& ptr)
{
  Entities::iterator entPtr = entityMap.find( name );
  if( entPtr == entityMap.end () ) return false;
  else
    {
      ptr = entPtr->second;
      return true;
    }
}


void PoolStorage::
clearPlugin( const std::string& name )
{
  dgDEBUGIN(5);
Thomas Moulard's avatar
Thomas Moulard committed
  std::list<Entity*> toDelete;
  for (Entities::iterator entPtr = entityMap.begin  ();
       entPtr != entityMap.end  (); ++entPtr)
Thomas Moulard's avatar
Thomas Moulard committed
    if (entPtr->second->getClassName () == name)
Thomas Moulard's avatar
Thomas Moulard committed
      toDelete.push_back (entPtr->second);
Thomas Moulard's avatar
Thomas Moulard committed
  for (std::list< Entity* >::iterator iter = toDelete.begin  ();
       iter != toDelete.end  (); ++iter)
Thomas Moulard's avatar
Thomas Moulard committed
    delete (Entity*) *iter;
  dgDEBUGOUT(5);
}



/* --------------------------------------------------------------------- */


#ifdef WIN32
#include <time.h>
#endif /*WIN32*/

void PoolStorage::
writeGraph(const std::string &aFileName)
{
  size_t IdxPointFound = aFileName.rfind(".");
  std::string tmp1 = aFileName.substr(0,IdxPointFound);
  size_t IdxSeparatorFound = aFileName.rfind("/");
  std::string GenericName;
  if (IdxSeparatorFound!=std::string::npos)
Thomas Moulard's avatar
Thomas Moulard committed
    GenericName = tmp1.substr(IdxSeparatorFound,tmp1.length ());
  else
    GenericName = tmp1;

  /* Reading local time */
  time_t ltime;
  ltime = time(NULL);
  struct tm ltimeformatted;
#ifdef WIN32
  localtime_s(&ltimeformatted,&ltime);
#else
  localtime_r(&ltime,&ltimeformatted);
#endif /*WIN32*/

  /* Opening the file and writing the first comment. */
Thomas Moulard's avatar
Thomas Moulard committed
  std::ofstream GraphFile (aFileName.c_str (),std::ofstream::out);
  GraphFile << "/* This graph has been automatically generated. " << std::endl;
  GraphFile << "   " << 1900+ltimeformatted.tm_year
	    << " Month: " << 1+ltimeformatted.tm_mon
	    << " Day: " << ltimeformatted.tm_mday
	    << " Time: " << ltimeformatted.tm_hour
	    << ":" << ltimeformatted.tm_min;
  GraphFile << " */" << std::endl;
  GraphFile << "digraph \"" << GenericName << "\" { ";
  GraphFile << "\t graph [ label=\"" << GenericName << "\" bgcolor = white rankdir=LR ]" << std::endl
	    << "\t node [ fontcolor = black, color = black, fillcolor = gold1, style=filled, shape=box ] ; " << std::endl;
  GraphFile << "\tsubgraph cluster_Entities { " << std::endl;

  GraphFile << "\t} " << std::endl;

  for( Entities::iterator iter=entityMap.begin ();
       iter!=entityMap.end (); ++iter)
      GraphFile << "\"" << ent->getName () << "\""
Thomas Moulard's avatar
Thomas Moulard committed
		<<" [ label = \"" << ent->getName () << "\" ," << std::endl
		<<"   fontcolor = black, color = black, fillcolor=cyan, style=filled, shape=box ]" << std::endl;
      ent->writeGraph(GraphFile);
    }


  GraphFile << "}"<< std::endl;

Thomas Moulard's avatar
Thomas Moulard committed
  GraphFile.close ();
}

void PoolStorage::
writeCompletionList(std::ostream& os)
{
  for( Entities::iterator iter=entityMap.begin ();
       iter!=entityMap.end (); ++iter)
    {
      Entity* ent = iter->second;
      ent->writeCompletionList(os);
    }


}


void PoolStorage::
commandLine( const std::string& objectName,const std::string& functionName,
	     std::istringstream& cmdArg, std::ostream& os )
{
  dgDEBUG(15) << "Object <" << objectName<< "> function <"
	       <<functionName<<">"<<std::endl;

  if( objectName=="pool" )
    {
      if( functionName=="help" )
	{
	  os <<"Pool: " << std::endl
	     <<"  - list" << std::endl
	     << " - writegraph FileName" << std::endl;
	}
      else if( functionName=="list" )
	{
	  for( Entities::iterator iter=entityMap.begin ();
	       iter!=entityMap.end (); ++iter)
Thomas Moulard's avatar
Thomas Moulard committed
	      os << ent->getName ()
		 <<" (" << ent->getClassName () << ")" << std::endl;
	    }

	}
      else if (functionName=="writegraph")
	{
	  std::string aFileName;
	  cmdArg >> aFileName;
	  writeGraph(aFileName);
	}

    }
  else
    {
      Entity& ent = getEntity(objectName);
      ent.commandLine(functionName,cmdArg,os);
    }
}

static bool
objectNameParser( std::istringstream& cmdparse,
		  std::string& objName,
		  std::string& funName  )
{
  const int SIZE=128;
  char buffer[SIZE];
  cmdparse >> std::ws;
  cmdparse.getline( buffer,SIZE,'.' );
  if(! cmdparse.good () ) // The callback is not an object method
    return false;

  objName = buffer;
  //cmdparse.getline( buffer,SIZE );
  //funName = buffer;
  cmdparse >> funName;
  return true;
}

SignalBase<int>&
PoolStorage::
getSignal( std::istringstream& sigpath )
{
  std::string objname,signame;
  if(! objectNameParser( sigpath,objname,signame ) )
    { DG_THROW ExceptionFactory( ExceptionFactory::UNREFERED_SIGNAL,
				     "Parse error in signal name" ); }

  Entity& ent = getEntity( objname );
  return ent.getSignal( signame );
}

PoolStorage* PoolStorage::instance_ = 0;