From e392d397f6b86a49a05e9738357ccbfc2a922f01 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 27 Oct 2010 20:28:20 +0000 Subject: [PATCH] Support more complex article numbers Use typedefs for Catalogue maps --- locos.dat | 2 +- source/3d/catalogue.cpp | 4 +- source/designer/manipulator.cpp | 4 +- source/engineer/trainproperties.cpp | 10 ++-- source/libmarklin/articlenumber.cpp | 90 +++++++++++++++++++++++++++++ source/libmarklin/articlenumber.h | 45 +++++++++++++++ source/libmarklin/catalogue.cpp | 28 ++++++--- source/libmarklin/catalogue.h | 18 ++++-- source/libmarklin/layout.cpp | 16 ++++- source/libmarklin/layout.h | 3 + source/libmarklin/tracktype.cpp | 4 +- source/libmarklin/tracktype.h | 7 ++- source/libmarklin/train.cpp | 4 +- source/libmarklin/train.h | 3 +- source/libmarklin/vehicletype.cpp | 4 +- source/libmarklin/vehicletype.h | 7 ++- source/network/packets.h | 2 +- source/network/server.cpp | 4 +- wagons.dat | 4 +- 19 files changed, 215 insertions(+), 44 deletions(-) create mode 100644 source/libmarklin/articlenumber.cpp create mode 100644 source/libmarklin/articlenumber.h diff --git a/locos.dat b/locos.dat index 1c182dc..223cc66 100644 --- a/locos.dat +++ b/locos.dat @@ -114,7 +114,7 @@ vehicle 36850 }; }; -vehicle 37225 +vehicle \37225-02 { name "BR 194"; locomotive true; diff --git a/source/3d/catalogue.cpp b/source/3d/catalogue.cpp index 5229499..2f4fc04 100644 --- a/source/3d/catalogue.cpp +++ b/source/3d/catalogue.cpp @@ -22,8 +22,8 @@ Catalogue3D::Catalogue3D(Catalogue &c): 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 &trks = catalogue.get_tracks(); - for(map::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)); diff --git a/source/designer/manipulator.cpp b/source/designer/manipulator.cpp index 42c4229..7abe3d7 100644 --- a/source/designer/manipulator.cpp +++ b/source/designer/manipulator.cpp @@ -280,10 +280,10 @@ void Manipulator::connect() return; } - const map &track_types = designer.get_catalogue().get_tracks(); + const Catalogue::TrackMap &track_types = designer.get_catalogue().get_tracks(); std::map types_by_length; unsigned preference = 0; - for(map::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 &parts = i->second->get_parts(); if(parts.size()!=1) diff --git a/source/engineer/trainproperties.cpp b/source/engineer/trainproperties.cpp index 81463d2..efbf842 100644 --- a/source/engineer/trainproperties.cpp +++ b/source/engineer/trainproperties.cpp @@ -35,9 +35,9 @@ TrainProperties::TrainProperties(Engineer &e, const GLtk::Resources &r, Train *t add(*(drp_type = new GLtk::Dropdown(res))); drp_type->set_geometry(GLtk::Geometry(60, geom.h-50, geom.w-70, 20)); - const map &vehs = engineer.get_catalogue().get_vehicles(); + const Catalogue::VehicleMap &vehs = engineer.get_catalogue().get_vehicles(); unsigned n = 0; - for(map::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; @@ -67,7 +67,7 @@ TrainProperties::TrainProperties(Engineer &e, const GLtk::Resources &r, Train *t 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::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; @@ -126,8 +126,8 @@ void TrainProperties::new_vehicle_selected(unsigned n, const string &) const VehicleType &TrainProperties::get_vehicle_type(unsigned n, bool loco) { - const map &vehs = engineer.get_catalogue().get_vehicles(); - map::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) diff --git a/source/libmarklin/articlenumber.cpp b/source/libmarklin/articlenumber.cpp new file mode 100644 index 0000000..cac3b32 --- /dev/null +++ b/source/libmarklin/articlenumber.cpp @@ -0,0 +1,90 @@ +/* $Id$ + +This file is part of the MSP Märklin suite +Copyright © 2010 Mikkosoft Productions, Mikko Rasa +Distributed under the GPL +*/ + +#include +#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 sparts = split(s, '-'); + for(vector::iterator i=sparts.begin(); i!=sparts.end(); ++i) + { + if(i->empty()) + throw InvalidParameterValue("Malformed article number"); + + unsigned nondigit = i->size(); + for(unsigned j=0; jsize(); ++j) + if(!isdigit((*i)[j])) + { + nondigit = j; + break; + } + + if(!nondigit || nondigitsize()-1) + throw InvalidParameterValue("Malformed article number"); + + Part part; + part.number = lexical_cast(i->substr(0, nondigit)); + part.letter = nondigitsize() ? (*i)[nondigit] : 0; + parts.push_back(part); + } +} + +string ArticleNumber::str() const +{ + string result; + for(vector::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>(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 diff --git a/source/libmarklin/articlenumber.h b/source/libmarklin/articlenumber.h new file mode 100644 index 0000000..0aa6498 --- /dev/null +++ b/source/libmarklin/articlenumber.h @@ -0,0 +1,45 @@ +/* $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 +#include +#include + +namespace Marklin { + +class ArticleNumber +{ +private: + struct Part + { + unsigned number; + char letter; + + bool operator<(const Part &) const; + }; + + std::vector 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 diff --git a/source/libmarklin/catalogue.cpp b/source/libmarklin/catalogue.cpp index beab69a..97a91e2 100644 --- a/source/libmarklin/catalogue.cpp +++ b/source/libmarklin/catalogue.cpp @@ -24,9 +24,9 @@ Catalogue::Catalogue(): Catalogue::~Catalogue() { - for(map::iterator i=tracks.begin(); i!=tracks.end(); ++i) + for(TrackMap::iterator i=tracks.begin(); i!=tracks.end(); ++i) delete i->second; - for(map::iterator i=vehicles.begin(); i!=vehicles.end(); ++i) + for(VehicleMap::iterator i=vehicles.begin(); i!=vehicles.end(); ++i) delete i->second; } @@ -44,9 +44,9 @@ void Catalogue::add_track(TrackType &track) 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::const_iterator i=tracks.find(art_nr); + TrackMap::const_iterator i=tracks.find(art_nr); if(i==tracks.end()) throw KeyError("Unknown track type"); @@ -62,9 +62,9 @@ void Catalogue::add_vehicle(VehicleType &veh) 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::const_iterator i = vehicles.find(art_nr); + VehicleMap::const_iterator i = vehicles.find(art_nr); if(i==vehicles.end()) throw KeyError("Unknown vehicle type"); @@ -80,8 +80,10 @@ Catalogue::Loader::Loader(Catalogue &c): 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(&Loader::track)); + add("track", static_cast(&Loader::track)); + add("vehicle", static_cast(&Loader::vehicle)); + add("vehicle", static_cast(&Loader::vehicle)); } void Catalogue::Loader::ballast_profile() @@ -113,6 +115,11 @@ void Catalogue::Loader::scale(float n, float d) } void Catalogue::Loader::track(unsigned art_nr) +{ + track(ArticleNumber(art_nr)); +} + +void Catalogue::Loader::track(ArticleNumber art_nr) { RefPtr trk = new TrackType(art_nr); load_sub(*trk); @@ -121,6 +128,11 @@ void Catalogue::Loader::track(unsigned art_nr) } void Catalogue::Loader::vehicle(unsigned art_nr) +{ + vehicle(ArticleNumber(art_nr)); +} + +void Catalogue::Loader::vehicle(ArticleNumber art_nr) { RefPtr veh = new VehicleType(art_nr); load_sub(*veh); diff --git a/source/libmarklin/catalogue.h b/source/libmarklin/catalogue.h index 9a21c5e..a436994 100644 --- a/source/libmarklin/catalogue.h +++ b/source/libmarklin/catalogue.h @@ -10,6 +10,7 @@ Distributed under the GPL #include #include +#include "articlenumber.h" #include "layout.h" #include "profile.h" @@ -32,9 +33,14 @@ public: void rail_profile(); void scale(float, float); void track(unsigned); + void track(ArticleNumber); void vehicle(unsigned); + void vehicle(ArticleNumber); }; + typedef std::map TrackMap; + typedef std::map VehicleMap; + sigc::signal signal_track_added; sigc::signal signal_vehicle_added; @@ -44,8 +50,8 @@ private: Profile rail_profile; Profile ballast_profile; Profile path_profile; - std::map tracks; - std::map vehicles; + TrackMap tracks; + VehicleMap vehicles; Layout layout; public: @@ -60,12 +66,12 @@ public: const Profile &get_path_profile() const { return path_profile; } void add_track(TrackType &); - const TrackType &get_track(unsigned) const; - const std::map &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 &get_vehicles() const { return vehicles; } + const VehicleType &get_vehicle(const ArticleNumber &) const; + const VehicleMap &get_vehicles() const { return vehicles; } Layout &get_layout() { return layout; } }; diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index 338612a..25568d6 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -296,8 +296,10 @@ Layout::Loader::Loader(Layout &l): add("base", &Layout::base); add("route", static_cast(&Loader::route)); add("route", static_cast(&Loader::route)); - add("track", &Loader::track); - add("train", &Loader::train); + add("track", static_cast(&Loader::track)); + add("track", static_cast(&Loader::track)); + add("train", static_cast(&Loader::train)); + add("train", static_cast(&Loader::train)); } void Layout::Loader::finish() @@ -320,6 +322,11 @@ void Layout::Loader::route(const string &n) } 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); @@ -330,6 +337,11 @@ void Layout::Loader::track(unsigned art_nr) } 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); diff --git a/source/libmarklin/layout.h b/source/libmarklin/layout.h index e96bc95..1ec1012 100644 --- a/source/libmarklin/layout.h +++ b/source/libmarklin/layout.h @@ -15,6 +15,7 @@ Distributed under the GPL namespace Marklin { +class ArticleNumber; class Block; class Catalogue; class Driver; @@ -38,7 +39,9 @@ public: void route(); void route(const std::string &); void track(unsigned); + void track(ArticleNumber); void train(unsigned, unsigned); + void train(ArticleNumber, unsigned); }; public: diff --git a/source/libmarklin/tracktype.cpp b/source/libmarklin/tracktype.cpp index 53c2bc4..432cea8 100644 --- a/source/libmarklin/tracktype.cpp +++ b/source/libmarklin/tracktype.cpp @@ -13,8 +13,8 @@ using namespace Msp; namespace Marklin { -TrackType::TrackType(unsigned a): - art_nr(a), +TrackType::TrackType(const ArticleNumber &an): + art_nr(an), double_address(false), autofit_preference(1) { } diff --git a/source/libmarklin/tracktype.h b/source/libmarklin/tracktype.h index b443740..b1aff1e 100644 --- a/source/libmarklin/tracktype.h +++ b/source/libmarklin/tracktype.h @@ -9,6 +9,7 @@ Distributed under the GPL #define LIBMARKLIN_TRACKTYPE_H_ #include +#include "articlenumber.h" #include "geometry.h" #include "trackpart.h" @@ -37,7 +38,7 @@ public: }; private: - unsigned art_nr; + ArticleNumber art_nr; std::string description; std::vector parts; std::vector endpoints; @@ -45,9 +46,9 @@ private: 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; diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index 38f1c76..6ab617e 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -1431,9 +1431,9 @@ void Train::Loader::timetable() 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); diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index 4c4d1c3..8418d89 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -17,6 +17,7 @@ Distributed under the GPL namespace Marklin { +class ArticleNumber; class Route; class Timetable; class Vehicle; @@ -41,7 +42,7 @@ public: void real_speed(unsigned, float, float); void route(const std::string &); void timetable(); - void vehicle(unsigned); + void vehicle(ArticleNumber); }; sigc::signal signal_name_changed; diff --git a/source/libmarklin/vehicletype.cpp b/source/libmarklin/vehicletype.cpp index 639415f..5c14cba 100644 --- a/source/libmarklin/vehicletype.cpp +++ b/source/libmarklin/vehicletype.cpp @@ -12,8 +12,8 @@ using namespace Msp; namespace Marklin { -VehicleType::VehicleType(unsigned n): - art_nr(n), +VehicleType::VehicleType(const ArticleNumber &an): + art_nr(an), locomotive(false), length(0), width(0), diff --git a/source/libmarklin/vehicletype.h b/source/libmarklin/vehicletype.h index 9ef1c5e..7844825 100644 --- a/source/libmarklin/vehicletype.h +++ b/source/libmarklin/vehicletype.h @@ -9,6 +9,7 @@ Distributed under the GPL #define LIBMARKLIN_VEHICLETYPE_H_ #include +#include "articlenumber.h" namespace Marklin { @@ -67,7 +68,7 @@ public: }; private: - unsigned art_nr; + ArticleNumber art_nr; std::string name; bool locomotive; std::map functions; @@ -79,9 +80,9 @@ private: 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; diff --git a/source/network/packets.h b/source/network/packets.h index 8bbaf8e..bb08941 100644 --- a/source/network/packets.h +++ b/source/network/packets.h @@ -15,7 +15,7 @@ namespace Marklin { struct TrainInfoPacket { unsigned address; - unsigned loco_type; + std::string loco_type; std::string name; }; diff --git a/source/network/server.cpp b/source/network/server.cpp index d276839..2bf6412 100644 --- a/source/network/server.cpp +++ b/source/network/server.cpp @@ -54,7 +54,7 @@ void Server::train_added(Train &train) 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); } @@ -135,7 +135,7 @@ void Server::Connection::handshake_done() { 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); } diff --git a/wagons.dat b/wagons.dat index 9c99edb..ea9d158 100644 --- a/wagons.dat +++ b/wagons.dat @@ -17,7 +17,7 @@ vehicle 46274 axle { position -31; wheel_diameter 10; }; }; -vehicle 100001 +vehicle \37844b { name "BR 50 tender"; @@ -155,7 +155,7 @@ vehicle 43222 }; }; -vehicle 100005 +vehicle \39230b { name "BR 23 tender"; -- 2.43.0