FreeCAD

Форк
0
/
Type.cpp 
231 строка · 6.0 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2011 Jürgen Riegel <juergen.riegel@web.de>              *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24

25
#ifndef _PreComp_
26
#include <cassert>
27
#endif
28

29
/// Here the FreeCAD includes sorted by Base,App,Gui......
30
#include "Type.h"
31
#include "Exception.h"
32
#include "Interpreter.h"
33
#include "Console.h"
34

35

36
using namespace Base;
37
using namespace std;
38

39

40
struct Base::TypeData
41
{
42
    TypeData(const char* theName,
43
             const Type type = Type::badType(),
44
             const Type theParent = Type::badType(),
45
             Type::instantiationMethod method = nullptr)
46
        : name(theName)
47
        , parent(theParent)
48
        , type(type)
49
        , instMethod(method)
50
    {}
51

52
    std::string name;
53
    Type parent;
54
    Type type;
55
    Type::instantiationMethod instMethod;
56
};
57

58
map<string, unsigned int> Type::typemap;
59
vector<TypeData*> Type::typedata;
60
set<string> Type::loadModuleSet;
61

62
void* Type::createInstance()
63
{
64
    instantiationMethod method = typedata[index]->instMethod;
65
    return method ? (*method)() : nullptr;
66
}
67

68

69
void* Type::createInstanceByName(const char* TypeName, bool bLoadModule)
70
{
71
    // if not already, load the module
72
    if (bLoadModule) {
73
        importModule(TypeName);
74
    }
75

76
    // now the type should be in the type map
77
    Type type = fromName(TypeName);
78
    if (type == badType()) {
79
        return nullptr;
80
    }
81

82
    return type.createInstance();
83
}
84

85
void Type::importModule(const char* TypeName)
86
{
87
    // cut out the module name
88
    string Mod = getModuleName(TypeName);
89
    // ignore base modules
90
    if (Mod != "App" && Mod != "Gui" && Mod != "Base") {
91
        // remember already loaded modules
92
        set<string>::const_iterator pos = loadModuleSet.find(Mod);
93
        if (pos == loadModuleSet.end()) {
94
            Interpreter().loadModule(Mod.c_str());
95
#ifdef FC_LOGLOADMODULE
96
            Console().Log("Act: Module %s loaded through class %s \n", Mod.c_str(), TypeName);
97
#endif
98
            loadModuleSet.insert(Mod);
99
        }
100
    }
101
}
102

103
string Type::getModuleName(const char* ClassName)
104
{
105
    string temp(ClassName);
106
    std::string::size_type pos = temp.find_first_of("::");
107

108
    if (pos != std::string::npos) {
109
        return {temp, 0, pos};
110
    }
111
    return {};
112
}
113

114
Type Type::badType()
115
{
116
    Type bad;
117
    bad.index = 0;
118
    return bad;
119
}
120

121

122
Type Type::createType(const Type& parent, const char* name, instantiationMethod method)
123
{
124
    Type newType;
125
    newType.index = static_cast<unsigned int>(Type::typedata.size());
126
    TypeData* typeData = new TypeData(name, newType, parent, method);
127
    Type::typedata.push_back(typeData);
128

129
    // add to dictionary for fast lookup
130
    Type::typemap[name] = newType.getKey();
131

132
    return newType;
133
}
134

135

136
void Type::init()
137
{
138
    assert(Type::typedata.empty());
139

140

141
    Type::typedata.push_back(new TypeData("BadType"));
142
    Type::typemap["BadType"] = 0;
143
}
144

145
void Type::destruct()
146
{
147
    for (auto it : typedata) {
148
        delete it;
149
    }
150
    typedata.clear();
151
    typemap.clear();
152
    loadModuleSet.clear();
153
}
154

155
Type Type::fromName(const char* name)
156
{
157
    std::map<std::string, unsigned int>::const_iterator pos;
158

159
    pos = typemap.find(name);
160
    if (pos != typemap.end()) {
161
        return typedata[pos->second]->type;
162
    }
163

164
    return Type::badType();
165
}
166

167
Type Type::fromKey(unsigned int key)
168
{
169
    if (key < typedata.size()) {
170
        return typedata[key]->type;
171
    }
172

173
    return Type::badType();
174
}
175

176
const char* Type::getName() const
177
{
178
    return typedata[index]->name.c_str();
179
}
180

181
Type Type::getParent() const
182
{
183
    return typedata[index]->parent;
184
}
185

186
bool Type::isDerivedFrom(const Type& type) const
187
{
188

189
    Type temp(*this);
190
    do {
191
        if (temp == type) {
192
            return true;
193
        }
194
        temp = temp.getParent();
195
    } while (temp != badType());
196

197
    return false;
198
}
199

200
int Type::getAllDerivedFrom(const Type& type, std::vector<Type>& List)
201
{
202
    int cnt = 0;
203

204
    for (auto it : typedata) {
205
        if (it->type.isDerivedFrom(type)) {
206
            List.push_back(it->type);
207
            cnt++;
208
        }
209
    }
210
    return cnt;
211
}
212

213
int Type::getNumTypes()
214
{
215
    return static_cast<int>(typedata.size());
216
}
217

218
Type Type::getTypeIfDerivedFrom(const char* name, const Type& parent, bool bLoadModule)
219
{
220
    if (bLoadModule) {
221
        importModule(name);
222
    }
223

224
    Type type = fromName(name);
225

226
    if (type.isDerivedFrom(parent)) {
227
        return type;
228
    }
229

230
    return Type::badType();
231
}
232

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.