1 #include "TypeDescription.h"
11 using std::invalid_argument;
15 using std::stringstream;
20 void TypeDescription::AddField(const std::string &n, const FieldDescription &f) {
22 throw std::invalid_argument("duplicate definition of field " + n + " of type " + name);
24 fields.insert(std::make_pair(n, f));
28 bool TypeDescription::HasField(const std::string &name) const {
29 return fields.count(name);
32 const FieldDescription &TypeDescription::GetField(const std::string &n) const {
33 map<string, FieldDescription>::const_iterator result(fields.find(n));
34 if (result != fields.end()) {
35 return result->second;
37 throw std::invalid_argument("undefined field " + n + " of type " + name);
41 void TypeDescription::Construct(void *data) const {
45 std::memset(data, 0, Size());
49 void TypeDescription::Init(void *data) const {
55 void TypeDescription::Load(void *data) const {
62 void TypeDescription::AddSupertype(int id, std::ptrdiff_t offset) {
63 supertypes[id] = offset;
66 bool TypeDescription::IsSubtypeOf(int id) const {
67 return supertypes.count(id);
70 std::ptrdiff_t TypeDescription::SupertypeOffset(int id) const {
71 return supertypes.at(id);
75 map<int, TypeDescription> TypeDescription::typeDescriptions;
76 map<string, int> TypeDescription::typeName2ID;
78 TypeDescription &TypeDescription::Create(int id, const std::string &name) {
79 if (typeDescriptions.count(id)) {
80 std::stringstream msg;
81 msg << "duplicate type ID " << id
82 << " (have " << Get(id).TypeName() << ", got " << name << ")";
83 throw std::invalid_argument(msg.str());
85 if (typeName2ID.count(name)) {
86 std::stringstream msg;
87 msg << "duplicate type name " << name
88 << " (have " << GetTypeId(name) << ", got " << id << ")";
89 throw std::invalid_argument(msg.str());
91 typeName2ID[name] = id;
92 return typeDescriptions.insert(make_pair(id, TypeDescription(id, name))).first->second;
95 int TypeDescription::GetTypeId(const std::string &name) {
96 map<string, int>::const_iterator i(typeName2ID.find(name));
97 if (i != typeName2ID.end()) {
100 throw invalid_argument("unknown type name " + name);
104 const TypeDescription &TypeDescription::Get(int id) {
105 map<int, TypeDescription>::const_iterator i(typeDescriptions.find(id));
106 if (i != typeDescriptions.end()) {
109 std::stringstream msg;
110 msg << "invalid type ID " << id;
111 throw invalid_argument(msg.str());
116 int TypeDescription::GetMaxSize() {
118 for (map<int, TypeDescription>::const_iterator
119 i(typeDescriptions.begin()),
120 end(typeDescriptions.end());
122 if (i->second.Size() > max) {
123 max = i->second.Size();
130 void TypeDescription::WriteSourceWiki(std::ostream &out) {
131 vector<string> types;
132 for (map<int, TypeDescription>::const_iterator i(typeDescriptions.begin()), end(typeDescriptions.end()); i != end; ++i) {
133 if (i->second.name != "Animation") {
134 types.push_back(i->second.name);
137 std::sort(types.begin(), types.end());
139 out << "h2. Data types" << endl << endl;
141 for (vector<string>::const_iterator i(types.begin()), end(types.end()); i != end; ++i) {
142 out << "* [[LoaderSource#" << *i << "|" << *i << "]]" << endl;
146 for (vector<string>::const_iterator i(types.begin()), end(types.end()); i != end; ++i) {
147 const TypeDescription &td(Get(GetTypeId(*i)));
148 out << "h3. " << td.TypeName() << endl << endl;
150 out << "Type ID: @" << td.TypeId() << "@" << endl << endl;
152 if (td.Description()) {
153 out << td.Description() << endl << endl;
156 if (td.FieldsBegin() == td.FieldsEnd()) {
157 out << "No properties." << endl << endl;
159 out << "| *Property* | *Type* | *Description* |" << endl;
160 for (FieldIterator field(td.FieldsBegin()); field != td.FieldsEnd(); ++field) {
161 const FieldDescription &fd(field->second);
162 out << "| " << field->first << " | ";
163 if (fd.IsAggregate()) {
164 out << "Array<" << Get(fd.TypeId()).TypeName() << ">";
166 out << Get(fd.TypeId()).TypeName();
169 if (fd.Description()) {
170 out << fd.Description();