vehicle "39230"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "39230";
+ };
name "BR 23";
locomotive true;
function 0 "light";
vehicle "29820-02"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "29820";
+ part "02";
+ };
name "BR 50";
locomotive true;
function 0 "light";
vehicle "29530-01"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "29530";
+ part "01";
+ };
name "BR 86";
locomotive true;
function 0 "light";
vehicle "36850"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "36850";
+ };
name "BR 185";
locomotive true;
function 0 "light";
vehicle "37225-02"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "37225";
+ part "02";
+ };
name "BR 194";
locomotive true;
function 0 "light";
vehicle "39410"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "39410";
+ };
name "BR E 41";
locomotive true;
function 0 "light";
vehicle "37574-01"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "37574";
+ part "01";
+ };
name "BR E 03";
locomotive true;
function 0 "light";
vehicle "37504"
{
// XXX The power car is really in the middle, but that configuration isn't supported yet
+ article_number
+ {
+ vendor "Märklin";
+ article "37504";
+ };
name "BR 420 S-bahn";
locomotive true;
function 0 "light";
vehicle "37851"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "37851";
+ };
name "BR 150";
locomotive true;
function 0 "light";
vehicle "37968"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "37968";
+ };
name "BR 96";
locomotive true;
function 0 "light";
delete *i;
extend_tracks = trks;
- map<ArticleNumber, unsigned> counts;
+ map<const TrackType *, unsigned> counts;
length = 0;
for(vector<Track *>::iterator i=extend_tracks.begin(); i!=extend_tracks.end(); ++i)
{
length += (*i)->get_type().get_total_length();
- ++counts[(*i)->get_type().get_article_number()];
+ ++counts[&(*i)->get_type()];
}
string detail;
- for(map<ArticleNumber, unsigned>::const_iterator i=counts.begin(); i!=counts.end(); ++i)
+ for(map<const TrackType *, unsigned>::const_iterator i=counts.begin(); i!=counts.end(); ++i)
{
if(!detail.empty())
detail += ", ";
- detail += format("%dx %s", i->second, i->first);
+ detail += format("%dx %s", i->second, i->first->get_article_number());
}
signal_status.emit(format("Extend: %.0fmm (%s)", length*1000, detail));
namespace R2C2 {
-ArticleNumber::ArticleNumber(unsigned n)
-{
- Part part;
- part.number = n;
- part.letter = 0;
- parts.push_back(part);
-}
-
-ArticleNumber::ArticleNumber(const string &s)
-{
- vector<string> sparts = split(s, '-');
- for(vector<string>::iterator i=sparts.begin(); i!=sparts.end(); ++i)
- {
- if(i->empty())
- throw invalid_argument("ArticleNumber::ArticleNumber");
+ArticleNumber::ArticleNumber(const string &a):
+ article(a)
+{ }
- unsigned nondigit = i->size();
- for(unsigned j=0; j<i->size(); ++j)
- if(!isdigit((*i)[j]))
- {
- nondigit = j;
- break;
- }
-
- if(!nondigit || nondigit<i->size()-1)
- throw invalid_argument("ArticleNumber::ArticleNumber");
-
- Part part;
- part.number = lexical_cast<unsigned>(i->substr(0, nondigit));
- part.letter = nondigit<i->size() ? (*i)[nondigit] : 0;
- parts.push_back(part);
- }
-}
+ArticleNumber::ArticleNumber(const string &v, const string &a, const string &p):
+ vendor(v),
+ article(a),
+ part(p)
+{ }
string ArticleNumber::str() const
{
string result;
- for(vector<Part>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+ if(!vendor.empty())
{
- if(!result.empty())
- result += '-';
-
- result += lexical_cast<string>(i->number);
- if(i->letter)
- result += i->letter;
+ result += vendor;
+ result += ' ';
+ }
+ result += article;
+ if(!part.empty())
+ {
+ result += '-';
+ result += part;
}
return result;
}
-bool ArticleNumber::operator<(const ArticleNumber &other) const
-{
- return parts<other.parts;
-}
-
-bool ArticleNumber::Part::operator<(const Part &other) const
+ArticleNumber::Loader::Loader(ArticleNumber &an):
+ DataFile::ObjectLoader<ArticleNumber>(an)
{
- if(number!=other.number)
- return number<other.number;
- return letter<other.letter;
+ add("vendor", &ArticleNumber::vendor);
+ add("article", &ArticleNumber::article);
+ add("part", &ArticleNumber::part);
}
-void operator>>(const LexicalConverter &conv, ArticleNumber &art_nr)
-{
- art_nr = ArticleNumber(conv.get());
-}
-
void operator<<(LexicalConverter &conv, const ArticleNumber &art_nr)
{
conv.result(art_nr.str());
#include <string>
#include <vector>
+#include <msp/datafile/objectloader.h>
#include <msp/strings/lexicalcast.h>
namespace R2C2 {
class ArticleNumber
{
-private:
- struct Part
+public:
+ class Loader: public Msp::DataFile::ObjectLoader<ArticleNumber>
{
- unsigned number;
- char letter;
-
- bool operator<(const Part &) const;
+ public:
+ Loader(ArticleNumber &);
};
- std::vector<Part> parts;
+private:
+ std::string vendor;
+ std::string article;
+ std::string part;
public:
ArticleNumber() { }
- ArticleNumber(unsigned);
ArticleNumber(const std::string &);
+ ArticleNumber(const std::string &, const std::string &, const std::string & = std::string());
+ const std::string &get_vendor() const { return vendor; }
+ const std::string &get_article() const { return article; }
+ const std::string &get_part() const { return part; }
std::string str() const;
-
- bool operator<(const ArticleNumber &) const;
};
-void operator>>(const Msp::LexicalConverter &, ArticleNumber &);
void operator<<(Msp::LexicalConverter &, const ArticleNumber &);
} // namespace R2C2
namespace R2C2 {
-BeamGateType::BeamGateType():
- ObjectType(ArticleNumber(0))
+BeamGateType::BeamGateType()
{
name = "Beam gate";
Geometry::TransformedShape<float, 3> box1(
scale(1),
layout(*this)
{
- add_type<TrackType>();
- add_type<SignalType>();
- add_type<VehicleType>();
- add_type<TerrainType>();
+ add_type<TrackType>().keyword("track");
+ add_type<SignalType>().keyword("signal");
+ add_type<VehicleType>().keyword("vehicle");
+ add_type<TerrainType>().keyword("terrain");
add_type<TrackAppearance>().keyword("track_appearance");
}
{
add("layout", &Loader::layout);
add("scale", &Loader::scale);
- add("signal", &Loader::signal);
- add("terrain", &Loader::terrain);
- add("track", &Loader::track);
- add("vehicle", &Loader::vehicle);
}
void Catalogue::Loader::layout()
cat.scale = n/d;
}
-void Catalogue::Loader::signal(const string &n)
-{
- RefPtr<SignalType> sig = new SignalType(n);
- load_sub(*sig);
- cat.add(n, sig.get());
- sig.release();
-}
-
-void Catalogue::Loader::terrain(const string &n)
-{
- RefPtr<TerrainType> ter = new TerrainType(n);
- load_sub(*ter);
- cat.add(n, ter.get());
- ter.release();
-}
-
-void Catalogue::Loader::track(const string &n)
-{
- RefPtr<TrackType> trk = new TrackType(n);
- load_sub(*trk, cat);
- cat.add(n, trk.get());
- trk.release();
-}
-
-void Catalogue::Loader::vehicle(const string &n)
-{
- RefPtr<VehicleType> veh = new VehicleType(n);
- load_sub(*veh);
- cat.add(n, veh.get());
- veh.release();
-}
-
} // namespace R2C2
private:
void layout();
void scale(float, float);
- void signal(const std::string &);
- void terrain(const std::string &);
- void track(const std::string &);
- void vehicle(const std::string &);
};
private:
namespace R2C2 {
-ObjectType::ObjectType(const ArticleNumber &an):
- art_nr(an),
+ObjectType::ObjectType():
shape(0)
{ }
ObjectType::Loader::Loader(ObjectType &ot):
DataFile::ObjectLoader<ObjectType>(ot)
{
+ add("article_number", &Loader::article_number);
add("description", &ObjectType::description);
add("name", &ObjectType::name);
}
+void ObjectType::Loader::article_number()
+{
+ load_sub(obj.art_nr);
+}
+
} // namespace R2C2
{
public:
Loader(ObjectType &);
+
+ private:
+ void article_number();
};
protected:
std::string description;
Shape *shape;
- ObjectType(const ArticleNumber &);
+ ObjectType();
public:
virtual ~ObjectType();
namespace R2C2 {
-SignalType::SignalType(const ArticleNumber &an):
- ObjectType(an)
+SignalType::SignalType()
{
shape = new Geometry::TransformedShape<float, 3>(
Geometry::ExtrudedShape<float, 3>(Geometry::Circle<float>(0.01), 0.12),
std::string object;
public:
- SignalType(const ArticleNumber & = ArticleNumber());
+ SignalType();
const IndicationList &get_indications() const { return indications; }
const std::string &get_object() const { return object; }
namespace R2C2 {
-TerrainType::TerrainType(const ArticleNumber &an):
- ObjectType(an),
+TerrainType::TerrainType():
tile_size(1),
elevation_granularity(0.1)
{ }
TerrainType::Loader::Loader(TerrainType &tt):
- DataFile::ObjectLoader<TerrainType>(tt)
+ DataFile::DerivedObjectLoader<TerrainType, ObjectType::Loader>(tt)
{
add("elevation_granularity", &TerrainType::elevation_granularity);
add("surface", &Loader::surface);
class TerrainType: public ObjectType
{
public:
- class Loader: public Msp::DataFile::ObjectLoader<TerrainType>
+ class Loader: public Msp::DataFile::DerivedObjectLoader<TerrainType, ObjectType::Loader>
{
public:
Loader(TerrainType &);
float elevation_granularity;
public:
- TerrainType(const ArticleNumber & = ArticleNumber());
+ TerrainType();
unsigned get_n_surface_types() const { return surface_types.size(); }
const SurfaceType &get_surface_type(unsigned) const;
namespace R2C2 {
-TrackType::TrackType(const ArticleNumber &an):
- ObjectType(an),
+TrackType::TrackType():
appearance(0),
state_bits(0),
autofit_preference(1)
std::string object;
public:
- TrackType(const ArticleNumber & = ArticleNumber());
+ TrackType();
const TrackAppearance &get_appearance() const;
float get_gauge() const;
namespace R2C2 {
-VehicleType::VehicleType(const ArticleNumber &an):
- ObjectType(an),
+VehicleType::VehicleType():
locomotive(false),
swap_direction(false),
gauge(1.524),
float max_speed;
public:
- VehicleType(const ArticleNumber & = ArticleNumber());
+ VehicleType();
bool is_locomotive() const { return locomotive; }
unsigned get_max_function() const;
-terrain "100001"
+terrain "tb5"
{
+ article_number
+ {
+ vendor "MSP";
+ article "tb5";
+ };
+
surface
{
};
layout
{
- terrain "100001"
+ terrain "tb5"
{
position 0.1519720 0.2448861 0.000000;
rotation 0.000000;
track "24064"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24064";
+ };
appearance "C";
description "Straight, 64.3mm (R3-R4-R5)";
part
track "24071"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24071";
+ };
appearance "C";
description "Straight, 70.8mm (for slim turnouts)";
part
track "24077"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24077";
+ };
appearance "C";
description "Straight, 77.5mm (R1-R2-R3)";
part
track "24094"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24094";
+ };
appearance "C";
description "Straight, 94.2mm";
part
track "24172"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24172";
+ };
appearance "C";
description "Straight, 171.7mm";
part
track "24188"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24188";
+ };
appearance "C";
description "Straight, 188.3mm (turnout length)";
part
track "24229"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24229";
+ };
appearance "C";
description "Straight, 229.3mm";
part
track "24236"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24236";
+ };
appearance "C";
description "Straight, 236.1mm (slim turnout length)";
part
track "24360"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24360";
+ };
appearance "C";
description "Straight, 360mm";
part
track "24107"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24107";
+ };
appearance "C";
description "Curve, R1 = 360mm, 7.5°";
part
track "24115"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24115";
+ };
appearance "C";
description "Curve, R1 = 360mm, 15°";
part
track "24130"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24130";
+ };
appearance "C";
description "Curve, R1 = 360mm, 30°";
part
track "24206"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24206";
+ };
appearance "C";
description "Curve, R2 = 437.5mm, 5.7° (turnout to 30°)";
part
track "24207"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24207";
+ };
appearance "C";
description "Curve, R2 = 437.5mm, 7.5°";
part
track "24215"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24215";
+ };
appearance "C";
description "Curve, R2 = 437.5mm, 15°";
part
track "24224"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24224";
+ };
appearance "C";
description "Curve, R2 = 437.5mm, 24.3° (turnout)";
part
track "24230"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24230";
+ };
appearance "C";
description "Curve, R2 = 437.5mm, 30°";
part
track "24330"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24330";
+ };
appearance "C";
description "Curve, R3 = 515mm, 30°";
part
track "24430"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24430";
+ };
appearance "C";
description "Curve, R4 = 579.3mm, 30°";
part
track "24530"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24530";
+ };
appearance "C";
description "Curve, R5 = 643.6mm, 30°";
part
track "24912"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24912";
+ };
appearance "C";
description "Curve, R = 1114.6mm, 12.1° (slim turnout)";
part
track "24671"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24671";
+ };
appearance "C";
description "Curved turnout, left";
part
track "24672"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24672";
+ };
appearance "C";
description "Curved turnout, right";
part
track "24611"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24611";
+ };
appearance "C";
description "Turnout, left";
part
track "24612"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24612";
+ };
appearance "C";
description "Turnout, right";
part
track "24630"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24630";
+ };
appearance "C";
description "Turnout, 3-way";
part
track "24624"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24624";
+ };
appearance "C";
description "Turnout, double slip";
state_bits 1;
track "24711"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24711";
+ };
appearance "C";
description "Slim turnout, left";
part
track "24712"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24712";
+ };
appearance "C";
description "Slim turnout, right";
part
track "24640"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24640";
+ };
appearance "C";
description "Crossing, 24.3°";
part
track "24649"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24649";
+ };
appearance "C";
description "Crossing, 48.6°";
part
track "24740"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24740";
+ };
appearance "C";
description "Slim crossing, 12.1°";
part
track "24977"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "24977";
+ };
appearance "C";
description "Bumper";
object "bumper.object";
signal "7039"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "7039";
+ };
indication "Hp1"
{
aspect 0;
vehicle "46274"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "46274";
+ };
name "Saar Railroad Gmhs 54";
gauge 16.5;
vehicle "29820-02b"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "29820";
+ part "02b";
+ };
name "BR 50 tender";
gauge 16.5;
vehicle "4442"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "4442";
+ };
name "Z";
gauge 16.5;
vehicle "29859b"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "29859";
+ part "b";
+ };
name "Zas";
gauge 16.5;
};
};
-vehicle "100004"
+vehicle "46034e"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "46034";
+ part "e";
+ };
name "Omm 52";
gauge 16.5;
vehicle "47001"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "47001";
+ };
name "Rs 684";
gauge 16.5;
vehicle "48943"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "48943";
+ };
name "BTr 10";
gauge 16.5;
vehicle "43222"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "43222";
+ };
name "B4üw 38 \"Schürzenwagen\"";
gauge 16.5;
vehicle "39230b"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "39230";
+ part "b";
+ };
name "BR 23 tender";
gauge 16.5;
vehicle "43800"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "43800";
+ };
name "B4nzb 64 \"Silberling\"";
gauge 16.5;
vehicle "47072"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "47042";
+ };
name "Sgns 691";
gauge 16.5;
vehicle "4624"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "4624";
+ };
name "Fals-u 176";
gauge 16.5;
vehicle "4423"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "4423";
+ };
name "Kklm 505";
gauge 16.5;
vehicle "4410"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "4410";
+ };
name "Gs 210";
gauge 16.5;
vehicle "46977"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "46977";
+ };
name "Rlmmso 56";
gauge 16.5;
vehicle "4699"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "4699";
+ };
name "Pwg 14";
gauge 16.5;
vehicle "46717"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "46717";
+ };
name "Railway crane";
gauge 16.5;
vehicle "4690"
{
+ article_number
+ {
+ vendor "Märklin";
+ article "4690";
+ };
name "Eaos 106";
gauge 16.5;
vehicle "37504b"
{
// XXX The power car is really in the middle, but that configuration isn't supported yet
+ article_number
+ {
+ vendor "Märklin";
+ article "37504";
+ part "b";
+ };
name "BR 421 S-bahn";
gauge 16.5;
vehicle "37504c"
{
// XXX Better solution would be to allow flipping of vehicles
+ article_number
+ {
+ vendor "Märklin";
+ article "37504";
+ part "c";
+ };
name "BR 420 S-bahn";
gauge 16.5;