FreeCAD

Форк
0
/
Type.cpp 
236 строк · 6.1 Кб
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
bool Type::canInstantiate() const
69
{
70
    instantiationMethod method = typedata[index]->instMethod;
71
    return method != nullptr;
72
}
73

74
void* Type::createInstanceByName(const char* TypeName, bool bLoadModule)
75
{
76
    // if not already, load the module
77
    if (bLoadModule) {
78
        importModule(TypeName);
79
    }
80

81
    // now the type should be in the type map
82
    Type type = fromName(TypeName);
83
    if (type == badType()) {
84
        return nullptr;
85
    }
86

87
    return type.createInstance();
88
}
89

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

108
string Type::getModuleName(const char* ClassName)
109
{
110
    string temp(ClassName);
111
    std::string::size_type pos = temp.find_first_of("::");
112

113
    if (pos != std::string::npos) {
114
        return {temp, 0, pos};
115
    }
116
    return {};
117
}
118

119
Type Type::badType()
120
{
121
    Type bad;
122
    bad.index = 0;
123
    return bad;
124
}
125

126

127
Type Type::createType(const Type& parent, const char* name, instantiationMethod method)
128
{
129
    Type newType;
130
    newType.index = static_cast<unsigned int>(Type::typedata.size());
131
    TypeData* typeData = new TypeData(name, newType, parent, method);
132
    Type::typedata.push_back(typeData);
133

134
    // add to dictionary for fast lookup
135
    Type::typemap[name] = newType.getKey();
136

137
    return newType;
138
}
139

140

141
void Type::init()
142
{
143
    assert(Type::typedata.empty());
144

145

146
    Type::typedata.push_back(new TypeData("BadType"));
147
    Type::typemap["BadType"] = 0;
148
}
149

150
void Type::destruct()
151
{
152
    for (auto it : typedata) {
153
        delete it;
154
    }
155
    typedata.clear();
156
    typemap.clear();
157
    loadModuleSet.clear();
158
}
159

160
Type Type::fromName(const char* name)
161
{
162
    std::map<std::string, unsigned int>::const_iterator pos;
163

164
    pos = typemap.find(name);
165
    if (pos != typemap.end()) {
166
        return typedata[pos->second]->type;
167
    }
168

169
    return Type::badType();
170
}
171

172
Type Type::fromKey(unsigned int key)
173
{
174
    if (key < typedata.size()) {
175
        return typedata[key]->type;
176
    }
177

178
    return Type::badType();
179
}
180

181
const char* Type::getName() const
182
{
183
    return typedata[index]->name.c_str();
184
}
185

186
Type Type::getParent() const
187
{
188
    return typedata[index]->parent;
189
}
190

191
bool Type::isDerivedFrom(const Type& type) const
192
{
193

194
    Type temp(*this);
195
    do {
196
        if (temp == type) {
197
            return true;
198
        }
199
        temp = temp.getParent();
200
    } while (temp != badType());
201

202
    return false;
203
}
204

205
int Type::getAllDerivedFrom(const Type& type, std::vector<Type>& List)
206
{
207
    int cnt = 0;
208

209
    for (auto it : typedata) {
210
        if (it->type.isDerivedFrom(type)) {
211
            List.push_back(it->type);
212
            cnt++;
213
        }
214
    }
215
    return cnt;
216
}
217

218
int Type::getNumTypes()
219
{
220
    return static_cast<int>(typedata.size());
221
}
222

223
Type Type::getTypeIfDerivedFrom(const char* name, const Type& parent, bool bLoadModule)
224
{
225
    if (bLoadModule) {
226
        importModule(name);
227
    }
228

229
    Type type = fromName(name);
230

231
    if (type.isDerivedFrom(parent)) {
232
        return type;
233
    }
234

235
    return Type::badType();
236
}
237

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

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

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

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