Type.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Riegel         <juergen.riegel@web.de>                  *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include "PreCompiled.h"
00024 
00025 #ifndef _PreComp_
00026 # include <assert.h>
00027 #endif
00028 
00030 #include "Type.h"
00031 #include "Exception.h"
00032 #include "Interpreter.h"
00033 #include "Console.h"
00034 
00035 
00036 using namespace Base;
00037 using namespace std;
00038 
00039 
00040 struct Base::TypeData 
00041 {
00042   TypeData(const char *theName,
00043            const Type type = Type::badType(),
00044            const Type theParent = Type::badType(),
00045            Type::instantiationMethod method = 0
00046           ):name(theName),parent(theParent),type(type),instMethod(method) { }
00047 
00048   std::string name;
00049   Type parent;
00050   Type type;
00051   Type::instantiationMethod instMethod;
00052 };
00053 
00054 map<string,unsigned int> Type::typemap;
00055 vector<TypeData*>        Type::typedata;
00056 set<string>              Type::loadModuleSet;
00057 
00058 //**************************************************************************
00059 // Construction/Destruction
00060 
00065 Type::Type()
00066 : index(0)
00067 {
00068 }
00069 
00070 
00071 Type::Type(const Type& type)
00072 :index(type.index)
00073 {
00074 }
00075 
00076 
00081 Type::~Type()
00082 {
00083 }
00084 
00085 void *Type::createInstance(void)
00086 {
00087   return (typedata[index]->instMethod)();
00088 }
00089 
00090 
00091 void *Type::createInstanceByName(const char* TypeName, bool bLoadModule)
00092 {
00093   // if not allready, load the module
00094   if(bLoadModule)
00095   {
00096     // cut out the module name 
00097     string Mod = getModuleName(TypeName);
00098     // ignore base modules
00099     if(Mod != "App" && Mod != "Gui" && Mod != "Base")
00100     {
00101       // remember allready loaded modules
00102       set<string>::const_iterator pos = loadModuleSet.find(Mod);
00103       if(pos == loadModuleSet.end())
00104       {
00105         Interpreter().loadModule(Mod.c_str());
00106 #ifdef FC_LOGLOADMODULE
00107         Console().Log("Act: Module %s loaded through class %s \n",Mod.c_str(),TypeName);
00108 #endif
00109         loadModuleSet.insert(Mod);
00110       }
00111     }
00112   }
00113 
00114   // now the type should be in the type map
00115   Type t = fromName(TypeName);
00116   if(t == badType())
00117     return 0;
00118 
00119   return t.createInstance();
00120 
00121 }
00122 
00123 string Type::getModuleName(const char* ClassName)
00124 {
00125   string temp(ClassName);
00126   std::string::size_type pos = temp.find_first_of("::");
00127 
00128   if(pos != std::string::npos)
00129     return string(temp,0,pos);
00130   else
00131     return string();
00132 }
00133 
00134 Type Type::badType(void)
00135 {
00136   Type bad;
00137   bad.index = 0;
00138   return bad;
00139 }
00140 
00141 
00142 const Type Type::createType(const Type parent, const char *name, instantiationMethod method)
00143 {
00144   Type newType;
00145   newType.index = Type::typedata.size();
00146   TypeData * typeData = new TypeData(name, newType, parent,method);
00147   Type::typedata.push_back(typeData);
00148 
00149   // add to dictionary for fast lookup
00150   Type::typemap[name] = newType.getKey();
00151 
00152   return newType;
00153 }
00154 
00155 
00156 void Type::init(void)
00157 {
00158   assert(Type::typedata.size() == 0);
00159 
00160 
00161   Type::typedata.push_back(new TypeData("BadType"));
00162   Type::typemap["BadType"] = 0;
00163 
00164 
00165 }
00166 
00167 void Type::destruct(void)
00168 {
00169   for(std::vector<TypeData*>::const_iterator it = typedata.begin();it!= typedata.end();++it)
00170     delete *it;
00171   typedata.clear();
00172   typemap.clear();
00173   loadModuleSet.clear();
00174 }
00175 
00176 Type Type::fromName(const char *name)
00177 {
00178   std::map<std::string,unsigned int>::const_iterator pos;
00179   
00180   pos = typemap.find(name);
00181   if(pos != typemap.end())
00182     return typedata[pos->second]->type;
00183   else
00184     return Type::badType();
00185 }
00186 
00187 const char *Type::getName(void) const
00188 {
00189   return typedata[index]->name.c_str();
00190 }
00191 
00192 const Type Type::getParent(void) const
00193 {
00194   return typedata[index]->parent;
00195 }
00196 
00197 bool Type::isDerivedFrom(const Type type) const
00198 {
00199   
00200   Type temp(*this);
00201   do {
00202     if(temp == type)
00203       return true;
00204     temp = temp.getParent();
00205   } while (temp != badType());
00206 
00207   return false;
00208 }
00209 
00210 int Type::getAllDerivedFrom(const Type type, std::vector<Type> & List)
00211 {
00212   int cnt = 0;
00213 
00214   for(std::vector<TypeData*>::const_iterator it = typedata.begin();it!= typedata.end();++it)
00215   {
00216     if((*it)->type.isDerivedFrom(type))
00217     {
00218       List.push_back((*it)->type);
00219       cnt++;
00220     }
00221   }
00222   return cnt;
00223 }
00224 
00225 int Type::getNumTypes(void)
00226 {
00227   return typedata.size();
00228 }

Generated on Wed Nov 23 19:00:51 2011 for FreeCAD by  doxygen 1.6.1