configuration/src/factory.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2008 by Tomassino Ferrauto                              *
00003  *   t_ferrauto@yahoo.it                                                   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "factory.h"
00022 #include <QStringList>
00023 
00024 namespace farsa {
00025 
00026 Factory& Factory::getInstance()
00027 {
00028     // The meyer singleton
00029     static Factory factory;
00030 
00031     return factory;
00032 }
00033 
00034 ConfigurationParameters& Factory::getTypeDescriptions() {
00035     static ConfigurationParameters typeDescriptions(true);
00036     return typeDescriptions;
00037 }
00038 
00039 Factory::Factory() :
00040     m_classMap(),
00041     m_parentsMap(),
00042     m_childrenMap()
00043 {
00044 }
00045 
00046 Factory::~Factory()
00047 {
00048     // Deleting all creators
00049     for(QMap<QString, ParameterSettableCreator*>::iterator i = m_classMap.begin(); i != m_classMap.end(); i++) {
00050         delete i.value();
00051         i.value() = NULL;
00052     }
00053 }
00054 
00055 QStringList Factory::getAllSubclasses(QString className, int levelToStop, bool noAbstractClasses)
00056 {
00057     QStringList subclasses;
00058     QStringList currents;
00059     currents.append(className);
00060     int level = 0;
00061     while (((level < levelToStop) || (levelToStop == -1)) && (currents.count() > 0)) {
00062         QStringList subs;
00063         foreach (QString current, currents) {
00064             subs.append(m_childrenMap[current]);
00065         }
00066         subclasses.append(subs);
00067         currents = subs;
00068         level++;
00069     }
00070     if (noAbstractClasses) {
00071         // filter QStringList
00072         QStringList filtered;
00073         foreach (QString current, subclasses) {
00074             if (isAbstract(current)) continue;
00075             filtered << current;
00076         }
00077         return filtered;
00078     }
00079     return subclasses;
00080 }
00081 
00082 bool Factory::isAbstract(QString className)
00083 {
00084     // if there is no creator, then it is abstract
00085     return !(m_classMap.contains(className));
00086 }
00087 
00088 void Factory::cleanupMapsForReRegistration(QString className)
00089 {
00090     // Need to check whether className was already registered to clean up things. We check m_parentsMap
00091     // because in the previous registration the class could have been an abstract class
00092     if (m_parentsMap.contains(className)) {
00093         // Removing the old creator if it exists
00094         if (m_classMap.contains(className)) {
00095             delete m_classMap[className];
00096         }
00097 
00098         // Also removing the class from the list of children of its parent class
00099         if (m_childrenMap.contains(m_parentsMap[className])) {
00100             const int nRemoved = m_childrenMap[m_parentsMap[className]].removeAll(className);
00101             Q_ASSERT_X((nRemoved <= 1), "Registering a class", ("More that one instance of " + className + " were present").toAscii().data());
00102         }
00103 
00104         // The class being re-registered could be a parent of other classes: as we don't know what
00105         // happened to that relations, we leave them as they are
00106     }
00107 }
00108 
00109 } // end namespace farsa