source: Revenant/yamlprovider/src/yamlgmcfgrd.cpp@ 7ef8ec4

port/mars-tycoon
Last change on this file since 7ef8ec4 was 80a6a52, checked in by Jonathan Neufeld <support@…>, 3 years ago

Get to a compile state for terrain procedural generation

  • Property mode set to 100755
File size: 9.2 KB
Line 
1#include "yamlgmcfgrd.h"
2
3#include "yamlext.h"
4
5#include <yaml.h>
6
7#include <iostream>
8#include <fstream>
9#include <sstream>
10
11#include <gwconfig.h>
12
13namespace genesis
14{
15 using namespace geoworld;
16
17 class ConfigValue : public IConfigValue
18 {
19 protected:
20 const YAML::Node & _node;
21 mutable IConfigSection * _sect;
22 mutable IConfigSequence * _seq;
23
24 template< typename T >
25 mars::Range< T > autorange () const
26 {
27 T min, max;
28
29 if (_node.Type() == YAML::NodeType::Sequence)
30 {
31 _node[0] >> min;
32 _node[1] >> max;
33 } else
34 {
35 _node >> min;
36 _node >> max;
37 }
38
39 return mars::Range< T > (min, max);
40 }
41
42 virtual mars::RangeX< double > & toRange (mars::RangeX< double > & out) const;
43 virtual mars::RangeX< long > & toRange (mars::RangeX< long > & out) const;
44
45 public:
46 ConfigValue( const YAML::Node & nd );
47
48 virtual IConfigSection * operator >> (IConfigSection * & pSection) const;
49 virtual IConfigSequence * operator >> (IConfigSequence * & pSequence) const;
50 virtual std::string & operator >> (std::string & out) const;
51 virtual float & operator >> (float & out) const;
52 virtual bool & operator >> (bool & out) const;
53 virtual unsigned int & operator >> (unsigned int & out) const;
54 virtual unsigned short & operator >> (unsigned short & out) const;
55
56 virtual VectorTag< GeoHeightMap::Precision >::V2 & operator >> (VectorTag< GeoHeightMap::Precision >::V2 & out) const;
57 virtual VectorTag< GeoHeightMap::Precision >::V3 & operator >> (VectorTag< GeoHeightMap::Precision >::V3 & out) const;
58
59 virtual ~ConfigValue();
60 };
61
62 class ConfigSection : public IConfigSection
63 {
64 private:
65 typedef std::map< std::string, ConfigValue * > Map;
66
67 mutable Map _map;
68 const YAML::Node & _node;
69
70 public:
71 ConfigSection( const YAML::Node & nd );
72
73 virtual const IConfigValue * operator []( const std::string & sKey ) const;
74
75 virtual ~ConfigSection();
76 };
77
78 class ConfigSequence : public IConfigSequence
79 {
80 private:
81 typedef std::vector< ConfigValue * > List;
82
83 mutable List _list;
84 const YAML::Node & _node;
85
86 public:
87 ConfigSequence( const YAML::Node & nd );
88
89 virtual const IConfigValue * operator []( const size_t & nIdx ) const;
90
91 virtual ~ConfigSequence();
92 };
93
94 class GMFactory : public IConfigGMFactory
95 {
96 private:
97 ConfigSection _section;
98
99 public:
100 GMFactory(const std::string & name, const std::string & alias, const YAML::Node & nd, const Settings & settings)
101 : IConfigGMFactory(name, alias, settings), _section(nd) {}
102
103 virtual IConfigSection * getSection() { return &_section; }
104 };
105
106 class GTFactory : public IConfigGTFactory
107 {
108 private:
109 ConfigSection _section;
110
111 public:
112 GTFactory(const std::string & name, const std::string & alias, const YAML::Node & nd, const Settings & settings)
113 : IConfigGTFactory(name, alias, settings), _section(nd) {}
114
115 virtual IConfigSection * getSection() { return &_section; }
116 };
117
118 YAMLGeoMorphConfigReader::YAMLGeoMorphConfigReader(std::istream & input)
119 : _pList(new FactoryVector()), _pNodes(new NodeVector()), _input(input)
120 {}
121
122 YAMLGeoMorphConfigReader::~YAMLGeoMorphConfigReader()
123 {
124 for (FactoryVector::iterator i = _pList->begin(); i != _pList->end(); ++i)
125 delete *i;
126 delete _pList;
127 delete _pNodes;
128 }
129
130 IConfigFactoryBase * YAMLGeoMorphConfigReader::readNext()
131 {
132 using namespace YAML;
133 Node node = Load(_input);
134
135 if (node.IsNull())
136 return NULL;
137
138 if (node.Type() != NodeType::Map)
139 throw GMMalformedConfigEx("Expected map"); // TODO: Proper exception handling
140
141 std::string sName, sAlias;
142
143 node["factory"] >> sName;
144
145 try
146 {
147 node["alias"] >> sAlias;
148 }
149 catch (YAML::TypedKeyNotFound< std::string >)
150 {
151 sAlias = sName;
152 }
153
154 IConfigFactoryBase * pFactory;
155
156 if (node.Tag() == "!template")
157 pFactory = readGTFactory(sName, sAlias, &node);
158 else
159 if (node.Tag() == "!morph" || node.Tag().empty())
160 pFactory = readGMFactory(sName, sAlias, &node);
161 else
162 throw GMMalformedConfigEx("Unknown document tag type: " + node.Tag());
163
164 _pNodes->push_back(node);
165 _pList->push_back(pFactory);
166 return pFactory;
167 }
168
169 GeoTemplatePhase YAMLGeoMorphConfigReader::getPhaseFor( const std::string & sPhase )
170 {
171 if (sPhase == "pre")
172 return geoworld::GTP_Pre;
173 else if (sPhase == "post")
174 return geoworld::GTP_Post;
175 else
176 throw InvalidPhaseName();
177 }
178
179 geoworld::IConfigGMFactory * YAMLGeoMorphConfigReader::readGMFactory(const std::string & sName, const std::string & sAlias, const YAML::Node * pndConfigSection)
180 {
181 IConfigGMFactory::Settings settings;
182
183 (*pndConfigSection)["frequency"] >> settings.frequency;
184 return new GMFactory(sName, sAlias, (*pndConfigSection)["parameters"], settings);
185 }
186
187 geoworld::IConfigGTFactory * YAMLGeoMorphConfigReader::readGTFactory(const std::string & sName, const std::string & sAlias, const YAML::Node * pndConfigSection)
188 {
189 IConfigGTFactory::Settings settings;
190
191 std::string sPhase;
192
193 (*pndConfigSection)["phase"] >> sPhase;
194 try
195 {
196 settings.phase = getPhaseFor(sPhase);
197 }
198 catch (InvalidPhaseName &)
199 {
200 throw YAML::InvalidScalar(pndConfigSection->Mark());
201 }
202
203 return new GTFactory(sName, sAlias, (*pndConfigSection)["parameters"], settings);
204 }
205
206
207 ConfigSection::ConfigSection( const YAML::Node & nd )
208 : _node(nd)
209 {
210 if (nd.Type() != YAML::NodeType::Map)
211 throw GMMalformedConfigEx("Expected map");
212 }
213
214 ConfigSection::~ConfigSection()
215 {
216 for (Map::iterator i = _map.begin(); i != _map.end(); ++i)
217 delete i->second;
218 }
219
220 const IConfigValue * ConfigSection::operator [] ( const std::string & sKey ) const
221 {
222 ConfigValue * pValue = NULL;
223
224 if (_map.find(sKey) == _map.end())
225 {
226 pValue = new ConfigValue(_node[sKey]);
227 _map[sKey] = pValue;
228 } else
229 pValue = _map[sKey];
230
231 return pValue;
232 }
233
234 ConfigSequence::ConfigSequence( const YAML::Node & nd )
235 : _node(nd)
236 {
237 if (nd.Type() != YAML::NodeType::Sequence)
238 throw GMMalformedConfigEx("Expected sequence");
239 }
240
241 ConfigSequence::~ConfigSequence()
242 {
243 for (List::iterator i = _list.begin(); i != _list.end(); ++i)
244 delete *i;
245 }
246
247 const IConfigValue * ConfigSequence::operator [] ( const size_t & nIdx ) const
248 {
249 ConfigValue * pValue = NULL;
250
251 if (nIdx >= _list.size())
252 {
253 _list.resize(nIdx + 1);
254 pValue = new ConfigValue(_node[nIdx]);
255 _list[nIdx] = pValue;
256 } else
257 pValue = _list[nIdx];
258
259 return pValue;
260 }
261
262 std::string & ConfigValue::operator >> ( std::string & out ) const
263 {
264 try
265 {
266 _node >> out;
267 return out;
268 }
269 catch (YAML::TypedKeyNotFound< std::string > & e)
270 {
271 throw GMInvalidPropertyEx(e.key, e.msg.c_str());
272 }
273 }
274
275 IConfigSection * ConfigValue::operator >>( IConfigSection * & pSection ) const
276 {
277 if (_sect == NULL)
278 _sect = new ConfigSection(_node);
279
280 return _sect;
281 }
282
283 IConfigSequence * ConfigValue::operator>>( IConfigSequence * & pSequence ) const
284 {
285 if (_seq == NULL)
286 _seq = new ConfigSequence(_node);
287
288 return _seq;
289 }
290
291 float & ConfigValue::operator >> ( float & out ) const
292 {
293 try
294 {
295 _node >> out;
296 }
297 catch (YAML::TypedKeyNotFound< std::string > & e)
298 {
299 throw GMInvalidPropertyEx(e.key, e.msg.c_str());
300 }
301 return out;
302 }
303
304 bool & ConfigValue::operator >> (bool & out) const
305 {
306 try
307 {
308 _node >> out;
309 }
310 catch (YAML::TypedKeyNotFound< std::string > & e)
311 {
312 throw GMInvalidPropertyEx(e.key, e.msg.c_str());
313 }
314 return out;
315 }
316 unsigned int & ConfigValue::operator >> (unsigned int & out) const
317 {
318 try
319 {
320 _node >> out;
321 }
322 catch (YAML::TypedKeyNotFound< std::string > & e)
323 {
324 throw GMInvalidPropertyEx(e.key, e.msg.c_str());
325 }
326 return out;
327 }
328
329 unsigned short & ConfigValue::operator >>( unsigned short & out ) const
330 {
331 try
332 {
333 _node >> out;
334 }
335 catch (YAML::TypedKeyNotFound< std::string > & e)
336 {
337 throw GMInvalidPropertyEx(e.key, e.msg.c_str());
338 }
339 return out;
340 }
341
342 VectorTag< GeoHeightMap::Precision >::V2 & ConfigValue::operator >>( VectorTag< GeoHeightMap::Precision >::V2 & out ) const
343 {
344 if (_node.Type() != YAML::NodeType::Sequence)
345 throw GMMalformedConfigEx("Expected a sequence");
346
347 return out = VectorTag< GeoHeightMap::Precision >::V2 (_node[0].as<GeoHeightMap::Precision>(), _node[1].as<GeoHeightMap::Precision>());
348 }
349
350 VectorTag< GeoHeightMap::Precision >::V3 & ConfigValue::operator >>( VectorTag< GeoHeightMap::Precision >::V3 & out ) const
351 {
352 using Numba = GeoHeightMap::Precision;
353 if (_node.Type() != YAML::NodeType::Sequence)
354 throw GMMalformedConfigEx("Expected a sequence");
355
356 return out = VectorTag< Numba >::V3 (
357 _node[0].as<Numba>(),
358 _node[1].as<Numba>(),
359 _node[2].as<Numba>()
360 );
361 }
362
363 mars::RangeX< double > & ConfigValue::toRange( mars::RangeX< double > & out ) const
364 {
365 try
366 {
367 return out = autorange< double >();
368 }
369 catch (YAML::TypedKeyNotFound< int > & e)
370 {
371 throw GMIndexOutOfBoundsEx(e.key, e.msg);
372 }
373 }
374
375 mars::RangeX< long > & ConfigValue::toRange( mars::RangeX< long > & out ) const
376 {
377 try
378 {
379 return out = autorange< long >();
380 }
381 catch (YAML::TypedKeyNotFound< int > & e)
382 {
383 throw GMIndexOutOfBoundsEx(e.key, e.msg);
384 }
385 }
386
387 ConfigValue::ConfigValue( const YAML::Node & nd )
388 : _node(nd), _sect(NULL), _seq(NULL) {}
389
390 ConfigValue::~ConfigValue()
391 {
392 delete _sect;
393 delete _seq;
394 }
395
396}
Note: See TracBrowser for help on using the repository browser.