};
};
-vehicle 37225
+vehicle \37225-02
{
name "BR 194";
locomotive true;
catalogue.signal_track_added.connect(sigc::mem_fun(this, &Catalogue3D::track_added));
catalogue.signal_vehicle_added.connect(sigc::mem_fun(this, &Catalogue3D::vehicle_added));
- const map<unsigned, TrackType *> &trks = catalogue.get_tracks();
- for(map<unsigned, TrackType *>::const_iterator i=trks.begin(); i!=trks.end(); ++i)
+ const Catalogue::TrackMap &trks = catalogue.get_tracks();
+ for(Catalogue::TrackMap::const_iterator i=trks.begin(); i!=trks.end(); ++i)
track_added(*i->second);
ballast_material.set_diffuse(GL::Color(0.25, 0.25, 0.25));
return;
}
- const map<unsigned, TrackType *> &track_types = designer.get_catalogue().get_tracks();
+ const Catalogue::TrackMap &track_types = designer.get_catalogue().get_tracks();
std::map<float, const TrackType *> types_by_length;
unsigned preference = 0;
- for(map<unsigned, TrackType *>::const_iterator i=track_types.begin(); i!=track_types.end(); ++i)
+ for(Catalogue::TrackMap::const_iterator i=track_types.begin(); i!=track_types.end(); ++i)
{
const vector<TrackPart> &parts = i->second->get_parts();
if(parts.size()!=1)
add(*(drp_type = new GLtk::Dropdown(res)));
drp_type->set_geometry(GLtk::Geometry(60, geom.h-50, geom.w-70, 20));
- const map<unsigned, VehicleType *> &vehs = engineer.get_catalogue().get_vehicles();
+ const Catalogue::VehicleMap &vehs = engineer.get_catalogue().get_vehicles();
unsigned n = 0;
- for(map<unsigned, VehicleType *>::const_iterator i=vehs.begin(); i!=vehs.end(); ++i)
+ for(Catalogue::VehicleMap::const_iterator i=vehs.begin(); i!=vehs.end(); ++i)
{
if(!i->second->is_locomotive())
continue;
drp_new_vehicle->set_geometry(GLtk::Geometry(10, geom.h-230, geom.w-20, 20));
drp_new_vehicle->append("(new vehicle)");
drp_new_vehicle->set_selected_index(0);
- for(map<unsigned, VehicleType *>::const_iterator i=vehs.begin(); i!=vehs.end(); ++i)
+ for(Catalogue::VehicleMap::const_iterator i=vehs.begin(); i!=vehs.end(); ++i)
{
if(i->second->is_locomotive())
continue;
const VehicleType &TrainProperties::get_vehicle_type(unsigned n, bool loco)
{
- const map<unsigned, VehicleType *> &vehs = engineer.get_catalogue().get_vehicles();
- map<unsigned, VehicleType *>::const_iterator i = vehs.begin();
+ const Catalogue::VehicleMap &vehs = engineer.get_catalogue().get_vehicles();
+ Catalogue::VehicleMap::const_iterator i = vehs.begin();
while(i!=vehs.end())
{
if(i->second->is_locomotive()==loco)
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#include <msp/strings/utils.h>
+#include "articlenumber.h"
+
+using namespace std;
+using namespace Msp;
+
+namespace Marklin {
+
+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 InvalidParameterValue("Malformed article number");
+
+ 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 InvalidParameterValue("Malformed article number");
+
+ Part part;
+ part.number = lexical_cast<unsigned>(i->substr(0, nondigit));
+ part.letter = nondigit<i->size() ? (*i)[nondigit] : 0;
+ parts.push_back(part);
+ }
+}
+
+string ArticleNumber::str() const
+{
+ string result;
+ for(vector<Part>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+ {
+ if(!result.empty())
+ result += '-';
+
+ result += lexical_cast(i->number);
+ if(i->letter)
+ result += i->letter;
+ }
+
+ return result;
+}
+
+bool ArticleNumber::operator<(const ArticleNumber &other) const
+{
+ return parts<other.parts;
+}
+
+
+bool ArticleNumber::Part::operator<(const Part &other) const
+{
+ if(number!=other.number)
+ return number<other.number;
+ return letter<other.letter;
+}
+
+
+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());
+}
+
+} // namespace Marklin
--- /dev/null
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010 Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
+#ifndef LIBMARKLIN_ARTICLENUMBER_H_
+#define LIBMARKLIN_ARTICLENUMBER_H_
+
+#include <string>
+#include <vector>
+#include <msp/strings/lexicalcast.h>
+
+namespace Marklin {
+
+class ArticleNumber
+{
+private:
+ struct Part
+ {
+ unsigned number;
+ char letter;
+
+ bool operator<(const Part &) const;
+ };
+
+ std::vector<Part> parts;
+
+public:
+ ArticleNumber() { }
+ ArticleNumber(unsigned);
+ ArticleNumber(const std::string &);
+
+ std::string str() const;
+
+ bool operator<(const ArticleNumber &) const;
+};
+
+void operator>>(const Msp::LexicalConverter &, ArticleNumber &);
+void operator<<(Msp::LexicalConverter &, const ArticleNumber &);
+
+} // namespace Marklin
+
+#endif
Catalogue::~Catalogue()
{
- for(map<unsigned, TrackType *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
+ for(TrackMap::iterator i=tracks.begin(); i!=tracks.end(); ++i)
delete i->second;
- for(map<unsigned, VehicleType *>::iterator i=vehicles.begin(); i!=vehicles.end(); ++i)
+ for(VehicleMap::iterator i=vehicles.begin(); i!=vehicles.end(); ++i)
delete i->second;
}
signal_track_added.emit(track);
}
-const TrackType &Catalogue::get_track(unsigned art_nr) const
+const TrackType &Catalogue::get_track(const ArticleNumber &art_nr) const
{
- map<unsigned, TrackType *>::const_iterator i=tracks.find(art_nr);
+ TrackMap::const_iterator i=tracks.find(art_nr);
if(i==tracks.end())
throw KeyError("Unknown track type");
signal_vehicle_added.emit(veh);
}
-const VehicleType &Catalogue::get_vehicle(unsigned art_nr) const
+const VehicleType &Catalogue::get_vehicle(const ArticleNumber &art_nr) const
{
- map<unsigned, VehicleType *>::const_iterator i = vehicles.find(art_nr);
+ VehicleMap::const_iterator i = vehicles.find(art_nr);
if(i==vehicles.end())
throw KeyError("Unknown vehicle type");
add("layout", &Loader::layout);
add("rail_profile", &Loader::rail_profile);
add("scale", &Loader::scale);
- add("track", &Loader::track);
- add("vehicle", &Loader::vehicle);
+ add("track", static_cast<void (Loader::*)(unsigned)>(&Loader::track));
+ add("track", static_cast<void (Loader::*)(ArticleNumber)>(&Loader::track));
+ add("vehicle", static_cast<void (Loader::*)(unsigned)>(&Loader::vehicle));
+ add("vehicle", static_cast<void (Loader::*)(ArticleNumber)>(&Loader::vehicle));
}
void Catalogue::Loader::ballast_profile()
}
void Catalogue::Loader::track(unsigned art_nr)
+{
+ track(ArticleNumber(art_nr));
+}
+
+void Catalogue::Loader::track(ArticleNumber art_nr)
{
RefPtr<TrackType> trk = new TrackType(art_nr);
load_sub(*trk);
}
void Catalogue::Loader::vehicle(unsigned art_nr)
+{
+ vehicle(ArticleNumber(art_nr));
+}
+
+void Catalogue::Loader::vehicle(ArticleNumber art_nr)
{
RefPtr<VehicleType> veh = new VehicleType(art_nr);
load_sub(*veh);
#include <map>
#include <msp/datafile/loader.h>
+#include "articlenumber.h"
#include "layout.h"
#include "profile.h"
void rail_profile();
void scale(float, float);
void track(unsigned);
+ void track(ArticleNumber);
void vehicle(unsigned);
+ void vehicle(ArticleNumber);
};
+ typedef std::map<ArticleNumber, TrackType *> TrackMap;
+ typedef std::map<ArticleNumber, VehicleType *> VehicleMap;
+
sigc::signal<void, const TrackType &> signal_track_added;
sigc::signal<void, const VehicleType &> signal_vehicle_added;
Profile rail_profile;
Profile ballast_profile;
Profile path_profile;
- std::map<unsigned, TrackType *> tracks;
- std::map<unsigned, VehicleType *> vehicles;
+ TrackMap tracks;
+ VehicleMap vehicles;
Layout layout;
public:
const Profile &get_path_profile() const { return path_profile; }
void add_track(TrackType &);
- const TrackType &get_track(unsigned) const;
- const std::map<unsigned, TrackType *> &get_tracks() const { return tracks; }
+ const TrackType &get_track(const ArticleNumber &) const;
+ const TrackMap &get_tracks() const { return tracks; }
void add_vehicle(VehicleType &);
- const VehicleType &get_vehicle(unsigned) const;
- const std::map<unsigned, VehicleType *> &get_vehicles() const { return vehicles; }
+ const VehicleType &get_vehicle(const ArticleNumber &) const;
+ const VehicleMap &get_vehicles() const { return vehicles; }
Layout &get_layout() { return layout; }
};
add("base", &Layout::base);
add("route", static_cast<void (Loader::*)()>(&Loader::route));
add("route", static_cast<void (Loader::*)(const string &)>(&Loader::route));
- add("track", &Loader::track);
- add("train", &Loader::train);
+ add("track", static_cast<void (Loader::*)(unsigned)>(&Loader::track));
+ add("track", static_cast<void (Loader::*)(ArticleNumber)>(&Loader::track));
+ add("train", static_cast<void (Loader::*)(unsigned, unsigned)>(&Loader::train));
+ add("train", static_cast<void (Loader::*)(ArticleNumber, unsigned)>(&Loader::train));
}
void Layout::Loader::finish()
}
void Layout::Loader::track(unsigned art_nr)
+{
+ track(ArticleNumber(art_nr));
+}
+
+void Layout::Loader::track(ArticleNumber art_nr)
{
Track *trk = new Track(obj, obj.catalogue.get_track(art_nr));
load_sub(*trk);
}
void Layout::Loader::train(unsigned art_nr, unsigned addr)
+{
+ train(ArticleNumber(art_nr), addr);
+}
+
+void Layout::Loader::train(ArticleNumber art_nr, unsigned addr)
{
Train *trn = new Train(obj, obj.catalogue.get_vehicle(art_nr), addr);
load_sub(*trn);
namespace Marklin {
+class ArticleNumber;
class Block;
class Catalogue;
class Driver;
void route();
void route(const std::string &);
void track(unsigned);
+ void track(ArticleNumber);
void train(unsigned, unsigned);
+ void train(ArticleNumber, unsigned);
};
public:
namespace Marklin {
-TrackType::TrackType(unsigned a):
- art_nr(a),
+TrackType::TrackType(const ArticleNumber &an):
+ art_nr(an),
double_address(false),
autofit_preference(1)
{ }
#define LIBMARKLIN_TRACKTYPE_H_
#include <msp/datafile/loader.h>
+#include "articlenumber.h"
#include "geometry.h"
#include "trackpart.h"
};
private:
- unsigned art_nr;
+ ArticleNumber art_nr;
std::string description;
std::vector<TrackPart> parts;
std::vector<Endpoint> endpoints;
unsigned autofit_preference;
public:
- TrackType(unsigned);
+ TrackType(const ArticleNumber &);
- unsigned get_article_number() const { return art_nr; }
+ const ArticleNumber &get_article_number() const { return art_nr; }
const std::string &get_description() const { return description; }
float get_total_length() const;
float get_path_length(int) const;
load_sub(*obj.timetable);
}
-void Train::Loader::vehicle(unsigned n)
+void Train::Loader::vehicle(ArticleNumber art_nr)
{
- const VehicleType &vtype = obj.layout.get_catalogue().get_vehicle(n);
+ const VehicleType &vtype = obj.layout.get_catalogue().get_vehicle(art_nr);
Vehicle *veh = new Vehicle(obj.layout, vtype);
obj.vehicles.back()->attach_back(*veh);
obj.vehicles.push_back(veh);
namespace Marklin {
+class ArticleNumber;
class Route;
class Timetable;
class Vehicle;
void real_speed(unsigned, float, float);
void route(const std::string &);
void timetable();
- void vehicle(unsigned);
+ void vehicle(ArticleNumber);
};
sigc::signal<void, const std::string &> signal_name_changed;
namespace Marklin {
-VehicleType::VehicleType(unsigned n):
- art_nr(n),
+VehicleType::VehicleType(const ArticleNumber &an):
+ art_nr(an),
locomotive(false),
length(0),
width(0),
#define LIBMARKLIN_VEHICLETYPE_H_
#include <msp/datafile/objectloader.h>
+#include "articlenumber.h"
namespace Marklin {
};
private:
- unsigned art_nr;
+ ArticleNumber art_nr;
std::string name;
bool locomotive;
std::map<unsigned, std::string> functions;
std::string object;
public:
- VehicleType(unsigned);
+ VehicleType(const ArticleNumber &);
- unsigned get_article_number() const { return art_nr; }
+ const ArticleNumber &get_article_number() const { return art_nr; }
const std::string &get_name() const { return name; }
bool is_locomotive() const { return locomotive; }
unsigned get_max_function() const;
struct TrainInfoPacket
{
unsigned address;
- unsigned loco_type;
+ std::string loco_type;
std::string name;
};
TrainInfoPacket pkt;
pkt.address = train.get_address();
- pkt.loco_type = train.get_locomotive_type().get_article_number();
+ pkt.loco_type = train.get_locomotive_type().get_article_number().str();
pkt.name = train.get_name();
send(pkt);
}
{
TrainInfoPacket pkt;
pkt.address = train.get_address();
- pkt.loco_type = train.get_locomotive_type().get_article_number();
+ pkt.loco_type = train.get_locomotive_type().get_article_number().str();
pkt.name = train.get_name();
comm.send(pkt);
}
axle { position -31; wheel_diameter 10; };
};
-vehicle 100001
+vehicle \37844b
{
name "BR 50 tender";
};
};
-vehicle 100005
+vehicle \39230b
{
name "BR 23 tender";