]> git.localhorst.tv Git - l2e.git/blob - src/loader/TypeDescription.cpp
added textual type/field descriptions and wiki mode
[l2e.git] / src / loader / TypeDescription.cpp
1 /*
2  * TypeDescription.cpp
3  *
4  *  Created on: Sep 4, 2012
5  *      Author: holy
6  */
7
8 #include "TypeDescription.h"
9
10 #include <algorithm>
11 #include <cassert>
12 #include <cstring>
13 #include <ostream>
14 #include <stdexcept>
15
16 using std::endl;
17 using std::map;
18 using std::string;
19 using std::vector;
20
21 namespace loader {
22
23 void TypeDescription::AddField(const std::string &n, const FieldDescription &f) {
24         if (HasField(n)) {
25                 throw std::invalid_argument("duplicate definition of field " + n + " of type " + name);
26         } else {
27                 fields.insert(std::make_pair(n, f));
28         }
29 }
30
31 bool TypeDescription::HasField(const std::string &name) const {
32         return fields.count(name);
33 }
34
35 const FieldDescription &TypeDescription::GetField(const std::string &n) const {
36         map<string, FieldDescription>::const_iterator result(fields.find(n));
37         if (result != fields.end()) {
38                 return result->second;
39         } else {
40                 throw std::invalid_argument("undefined field " + n + " of type " + name);
41         }
42 }
43
44 void TypeDescription::Construct(void *data) const {
45         if (constructor) {
46                 (*constructor)(data);
47         } else {
48                 std::memset(data, 0, Size());
49         }
50 }
51
52 void TypeDescription::Load(void *data) const {
53         if (loader) {
54                 (*loader)(data);
55         }
56 }
57
58
59 void TypeDescription::AddSupertype(int id, std::ptrdiff_t offset) {
60         supertypes[id] = offset;
61 }
62
63 bool TypeDescription::IsSubtypeOf(int id) const {
64         return supertypes.count(id);
65 }
66
67 std::ptrdiff_t TypeDescription::SupertypeOffset(int id) const {
68         return supertypes.at(id);
69 }
70
71
72 vector<TypeDescription> TypeDescription::typeDescriptions;
73
74 TypeDescription &TypeDescription::CreateOrGet(const std::string &name) {
75         for (vector<TypeDescription>::iterator i(typeDescriptions.begin()), end(typeDescriptions.end()); i != end; ++i) {
76                 if (i->name == name) {
77                         return *i;
78                 }
79         }
80         typeDescriptions.push_back(TypeDescription(typeDescriptions.size(), name));
81         return typeDescriptions.back();
82 }
83
84 int TypeDescription::GetTypeId(const std::string &name) {
85         for (vector<TypeDescription>::size_type i(0), end(typeDescriptions.size()); i < end; ++i) {
86                 if (typeDescriptions[i].name == name) {
87                         return i;
88                 }
89         }
90         typeDescriptions.push_back(TypeDescription(typeDescriptions.size(), name));
91         return typeDescriptions.size() - 1;
92 }
93
94 const TypeDescription &TypeDescription::Get(int id) {
95         assert(id >= 0 && id < int(typeDescriptions.size()));
96         return typeDescriptions[id];
97 }
98
99
100 void TypeDescription::WriteSourceWiki(std::ostream &out) {
101         vector<string> types;
102         for (vector<TypeDescription>::const_iterator i(typeDescriptions.begin()), end(typeDescriptions.end()); i != end; ++i) {
103                 if (i->name != "Animation") {
104                         types.push_back(i->name);
105                 }
106         }
107         std::sort(types.begin(), types.end());
108
109         out << "h2. Data types" << endl << endl;
110
111         for (vector<string>::const_iterator i(types.begin()), end(types.end()); i != end; ++i) {
112                 out << "* [[LoaderSource#" << *i << "|" << *i << "]]" << endl;
113         }
114         out << endl << endl;
115
116         for (vector<string>::const_iterator i(types.begin()), end(types.end()); i != end; ++i) {
117                 const TypeDescription &td(Get(GetTypeId(*i)));
118                 out << "h3. " << td.TypeName() << endl << endl;
119
120                 if (td.Description()) {
121                         out << td.Description() << endl << endl;
122                 }
123
124                 if (td.FieldsBegin() == td.FieldsEnd()) {
125                         out << "No properties." << endl << endl;
126                 } else {
127                         out << "| *Property* | *Type* | *Description* |" << endl;
128                         for (FieldIterator field(td.FieldsBegin()); field != td.FieldsEnd(); ++field) {
129                                 const FieldDescription &fd(field->second);
130                                 out << "| " << field->first << " | ";
131                                 if (fd.IsAggregate()) {
132                                         out << "Array<" << Get(fd.TypeId()).TypeName() << ">";
133                                 } else {
134                                         out << Get(fd.TypeId()).TypeName();
135                                 }
136                                 out << " | ";
137                                 if (fd.Description()) {
138                                         out << fd.Description();
139                                 }
140                                 out << " |" << endl;
141                         }
142                         out << endl;
143                 }
144         }
145 }
146
147 }