Skip to content

Commit b207357

Browse files
committed
Feature: Add mechanics to walk through file specific xml nodes, and re-create them
Feature: Add mechanics to get class info from class name
1 parent a1084fb commit b207357

10 files changed

Lines changed: 143 additions & 40 deletions

File tree

SolutionProjectModel/CppReflect.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ using namespace pugi;
77
using namespace boolinq;
88

99

10+
std::map< std::string, pfuncGetClassInfo > CppTypeInfo::classNameToClassInfo;
11+
12+
1013
FieldInfo* CppTypeInfo::GetField(const char* name)
1114
{
1215
for( auto& f: fields )
@@ -25,6 +28,15 @@ int CppTypeInfo::GetFieldIndex(const char* name)
2528
return -1;
2629
}
2730

31+
32+
ReflectRegisterClassInfo::ReflectRegisterClassInfo(const char* className, pfuncGetClassInfo func)
33+
{
34+
if (strncmp(className, "class ", 6) == 0)
35+
className += 6;
36+
37+
CppTypeInfo::classNameToClassInfo[className] = func;
38+
}
39+
2840
//
2941
// Serializes class instance to xml node.
3042
//

SolutionProjectModel/CppReflect.h

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "MacroHelpers.h" //DOFOREACH_SEMICOLON
55
#include <memory> //shared_ptr
66
#include <vector>
7+
#include <string>
78

89
// warning C4275: non dll-interface class 'pugi::xml_document' used as base for dll-interface class 'Solution'
910
#pragma warning( disable: 4275 )
@@ -18,22 +19,58 @@
1819
#endif
1920

2021
class FieldInfo;
22+
class ReflectClass;
23+
24+
25+
typedef CppTypeInfo& (*pfuncGetClassInfo)();
26+
2127
class SPM_DLLEXPORT CppTypeInfo
2228
{
2329
public:
30+
static std::map< std::string, pfuncGetClassInfo > classNameToClassInfo;
31+
2432
// Type (class) name
2533
CStringA name;
2634
std::vector<FieldInfo> fields;
2735

28-
//
2936
// Gets field by name, nullptr if not found.
30-
//
3137
FieldInfo* GetField(const char* name);
3238

33-
//
3439
// Get field index, -1 if not found.
35-
//
3640
int GetFieldIndex(const char* name);
41+
42+
// Creates new class instance, converts it to ReflectClass* base class
43+
virtual ReflectClass* ReflectCreateInstance() = 0;
44+
45+
// Creates new class instance, tries to convert it to T - if ok, assigns it to shared_ptr
46+
template <class T>
47+
void ReflectCreateInstance( std::shared_ptr<T>& ptr )
48+
{
49+
ReflectClass* base = ReflectCreateInstance();
50+
T* t = dynamic_cast<T*>(base);
51+
if(!t)
52+
{
53+
delete base;
54+
return;
55+
}
56+
57+
ptr.reset(t);
58+
}
59+
};
60+
61+
class ReflectRegisterClassInfo
62+
{
63+
public:
64+
ReflectRegisterClassInfo( const char* className, pfuncGetClassInfo func);
65+
};
66+
67+
template <class T>
68+
class CppTypeInfoT : public CppTypeInfo
69+
{
70+
ReflectClass* ReflectCreateInstance()
71+
{
72+
return new T;
73+
}
3774
};
3875

3976

@@ -86,7 +123,7 @@ defines wont expand correctly.
86123
\
87124
static CppTypeInfo& GetType() \
88125
{ \
89-
static CppTypeInfo t; \
126+
static CppTypeInfoT<className> t; \
90127
if( t.name.GetLength() ) return t; \
91128
t.name = #className; \
92129
FieldInfo fi; \
@@ -219,5 +256,10 @@ class ReflectClassT : public ReflectClass
219256
{
220257
return (T*) this;
221258
}
259+
260+
static ReflectRegisterClassInfo _registerClassInfo;
222261
};
223262

263+
template <class T>
264+
ReflectRegisterClassInfo ReflectClassT<T>::_registerClassInfo (typeid(T).name(), &T::GetType);
265+

SolutionProjectModel/Project.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ pugi::xml_node Project::selectProjectNodes(const wchar_t* _name2select, const wc
217217
xml_node LocateInsert( xml_node current, bool asChild, const wchar_t* name2select,
218218
const wchar_t* confName, const wchar_t* platform, const wchar_t* label, bool bLabelAfterCondition )
219219
{
220-
xml_node next;
220+
xml_node next, parent;
221221
wstring name;
222222
xml_attribute attr;
223223
xml_node selected;
@@ -226,7 +226,11 @@ xml_node LocateInsert( xml_node current, bool asChild, const wchar_t* name2selec
226226
label = nullptr;
227227

228228
if( asChild )
229+
{
230+
parent = current;
229231
next = current.first_child();
232+
current = xml_node();
233+
}
230234
else
231235
next = current.next_sibling();
232236

@@ -263,9 +267,9 @@ xml_node LocateInsert( xml_node current, bool asChild, const wchar_t* name2selec
263267
if (asChild)
264268
{
265269
if(current.empty())
266-
selected = current.append_child(name2select);
270+
selected = parent.append_child(name2select);
267271
else
268-
selected = current.insert_child_after(name2select, current);
272+
selected = parent.insert_child_after(name2select, current);
269273
}
270274
else
271275
selected = current.parent().insert_child_after(name2select, current);

SolutionProjectModel/Project.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// Project
1010
//---------------------------------------------------------
1111
class SPM_DLLEXPORT Project :
12-
ReflectClassT<Project>,
12+
public ReflectClassT<Project>,
1313
pugi::xml_document
1414
{
1515
public:

SolutionProjectModel/ProjectFile.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <algorithm>
66

77
using namespace std;
8+
using namespace pugi;
89
using namespace std::filesystem;
910

1011
string lowercased( string s )
@@ -18,11 +19,52 @@ ProjectFile::ProjectFile()
1819
ReflectConnectChildren(nullptr);
1920
}
2021

21-
void ProjectFile::VisitTool(std::function<void(BuildToolProperties&)> visitConf, const char* configurationName, const char* platformName)
22+
void ProjectFile::VisitTool(
23+
std::function<void(PlatformConfigurationProperties&)> visitConf,
24+
CppTypeInfo* confType,
25+
const wchar_t* _configurationName, const wchar_t* _platform)
2226
{
2327
if(!project)
2428
return;
2529

30+
function<void(const wchar_t*, const wchar_t*)> visitTool = [&]( const wchar_t* configurationName, const wchar_t* platform )
31+
{
32+
auto it = find_if(tools.begin(), tools.end(), [&](auto& t) { return t->platform == platform && t->configurationName == configurationName; });
33+
if (it != tools.end())
34+
{
35+
if(visitConf)
36+
visitConf(**it);
37+
38+
return;
39+
}
40+
41+
if(!confType)
42+
return;
43+
44+
shared_ptr<PlatformConfigurationProperties> props;
45+
confType->ReflectCreateInstance(props);
46+
props->node = LocateInsert(node, true, as_wide(confType->name).c_str(), configurationName, platform);
47+
tools.push_back(props);
48+
49+
if (visitConf)
50+
visitConf(*props);
51+
};
52+
53+
if (_configurationName == nullptr || _platform == nullptr)
54+
{
55+
project->VisitConfigurations
56+
(
57+
[&](VCConfiguration& c)
58+
{
59+
visitTool(c.platform.c_str(), c.configurationName.c_str());
60+
},
61+
_configurationName, _platform
62+
);
63+
}
64+
else
65+
{
66+
visitTool(_configurationName, _platform);
67+
}
2668
}
2769

2870

SolutionProjectModel/ProjectFile.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#pragma once
2-
#include "../pugixml/pugixml.hpp"
32
#include <string>
43
#include <functional>
54
#include "ProjectFileTypes.h"
@@ -9,7 +8,7 @@ class Project;
98
//
109
// Information about that particular file.
1110
//
12-
class SPM_DLLEXPORT ProjectFile : ReflectClassT<ProjectFile>
11+
class SPM_DLLEXPORT ProjectFile : public ReflectClassT<ProjectFile>
1312
{
1413
public:
1514
ProjectFile();
@@ -18,7 +17,12 @@ class SPM_DLLEXPORT ProjectFile : ReflectClassT<ProjectFile>
1817
(ProjectItemGeneralConf)General
1918
);
2019

21-
void VisitTool(std::function<void(BuildToolProperties&)> visitConf, const char* configurationName = nullptr, const char* platformName = nullptr);
20+
void VisitTool(
21+
std::function<void(PlatformConfigurationProperties&)> visitConf,
22+
CppTypeInfo* confType, // Type to create, null if just to locate
23+
const wchar_t* configurationName = nullptr,
24+
const wchar_t* platform = nullptr
25+
);
2226

2327
// Generic autoprobe - file extension to guessed type.
2428
static EItemType GetFromPath(const wchar_t* file);
@@ -29,7 +33,7 @@ class SPM_DLLEXPORT ProjectFile : ReflectClassT<ProjectFile>
2933
virtual void OnAfterSetProperty(ReflectPath& path);
3034

3135
// Configuration/platform specific tools
32-
std::vector< std::shared_ptr<BuildToolProperties> > tools;
36+
std::vector< std::shared_ptr<PlatformConfigurationProperties> > tools;
3337

3438
// Xml node containing child xml data.
3539
pugi::xml_node node;

SolutionProjectModel/ProjectFileTypes.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include "../pugixml/pugixml.hpp" //pugi::xml_node
23
#include "EnumReflect.h"
34
#include "CppReflect.h"
45

@@ -87,7 +88,7 @@ DECLARE_ENUM(EItemType, "",
8788
Natvis
8889
);
8990

90-
class SPM_DLLEXPORT ProjectItemGeneralConf : ReflectClassT<ProjectItemGeneralConf>
91+
class SPM_DLLEXPORT ProjectItemGeneralConf : public ReflectClassT<ProjectItemGeneralConf>
9192
{
9293
public:
9394
REFLECTABLE(ProjectItemGeneralConf,
@@ -137,7 +138,7 @@ DECLARE_ENUM(EKeyword, "projecttype_",
137138
projecttype_GradlePackage
138139
);
139140

140-
class SPM_DLLEXPORT ProjectGlobalConf : ReflectClassT<ProjectGlobalConf>
141+
class SPM_DLLEXPORT ProjectGlobalConf : public ReflectClassT<ProjectGlobalConf>
141142
{
142143
public:
143144
REFLECTABLE(ProjectGlobalConf,
@@ -239,11 +240,21 @@ DECLARE_ENUM(EGenerateDebugInformation, "debuginfo_",
239240
);
240241

241242

242-
class SPM_DLLEXPORT BuildToolProperties
243+
class SPM_DLLEXPORT PlatformConfigurationProperties
243244
{
245+
public:
246+
// So can safely delete by base pointer.
247+
virtual ~PlatformConfigurationProperties() { }
248+
249+
// Configuration name / platform of specific configuration
250+
std::wstring configurationName;
251+
std::wstring platform;
252+
253+
pugi::xml_node node;
254+
244255
};
245256

246-
class SPM_DLLEXPORT CustomBuildToolProperties : BuildToolProperties, ReflectClassT<CustomBuildToolProperties>
257+
class SPM_DLLEXPORT CustomBuildToolProperties : public PlatformConfigurationProperties, public ReflectClassT<CustomBuildToolProperties>
247258
{
248259
public:
249260
REFLECTABLE(CustomBuildToolProperties,
@@ -263,15 +274,15 @@ class SPM_DLLEXPORT CustomBuildToolProperties : BuildToolProperties, ReflectClas
263274

264275

265276

266-
class SPM_DLLEXPORT LinkerSystemConf: ReflectClassT<LinkerSystemConf>
277+
class SPM_DLLEXPORT LinkerSystemConf: public ReflectClassT<LinkerSystemConf>
267278
{
268279
public:
269280
REFLECTABLE(LinkerSystemConf,
270281
(ESubSystem)SubSystem
271282
);
272283
};
273284

274-
class SPM_DLLEXPORT LinkerDebuggingConf : ReflectClassT<LinkerDebuggingConf>
285+
class SPM_DLLEXPORT LinkerDebuggingConf : public ReflectClassT<LinkerDebuggingConf>
275286
{
276287
public:
277288
REFLECTABLE(LinkerDebuggingConf,

SolutionProjectModel/VCConfiguration.h

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
class Project;
77

88

9-
class SPM_DLLEXPORT VCConfiguration : ReflectClassT<VCConfiguration>
9+
class SPM_DLLEXPORT VCConfiguration : public PlatformConfigurationProperties, public ReflectClassT<VCConfiguration>
1010
{
1111
public:
1212
Project* project;
@@ -16,33 +16,15 @@ class SPM_DLLEXPORT VCConfiguration : ReflectClassT<VCConfiguration>
1616

1717
VCConfiguration() :
1818
project(nullptr)
19-
{
20-
Init();
21-
}
22-
23-
VCConfiguration(const VCConfiguration& clone) :
24-
project(clone.project),
25-
configurationName(clone.configurationName),
26-
platform(clone.platform)
27-
{
28-
Init();
29-
}
30-
31-
void Init()
3219
{
3320
// Define configuration "category" (will be used when serializing / restoring)
3421
Linker.propertyName = "Link";
3522
CCpp.propertyName = "ClCompile";
3623
ReflectConnectChildren(nullptr);
3724
}
3825

39-
4026
virtual void OnAfterSetProperty(ReflectPath& path);
4127

42-
// Configuration name / platform of specific configuration
43-
std::wstring configurationName;
44-
std::wstring platform;
45-
4628
//
4729
// Individual tools settings, depending on project type (static library, dynamic library) individual tool configuration is not necessarily used.
4830
//

SolutionProjectModel/cppexec/cppexec.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ using namespace std;
77
using namespace filesystem;
88

99

10-
class CommandLineArguments : ReflectClassT<CommandLineArguments>
10+
class CommandLineArguments : public ReflectClassT<CommandLineArguments>
1111
{
1212
public:
1313
CommandLineArguments():

SolutionProjectModel/testCppApp.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ void main(void)
2727

2828
auto f = p.File(L"..\\SolutionProjectModel.dll", true);
2929
f->General.ItemType = CustomBuild;
30+
//f->VisitTool(nullptr, &CustomBuildToolProperties::GetType());
31+
f->VisitTool(
32+
[](PlatformConfigurationProperties&)
33+
{
34+
}
35+
, &CustomBuildToolProperties::GetType());
3036

3137

3238

0 commit comments

Comments
 (0)