]> git.tdb.fi Git - r2c2.git/commitdiff
Support more complex article numbers
authorMikko Rasa <tdb@tdb.fi>
Wed, 27 Oct 2010 20:28:20 +0000 (20:28 +0000)
committerMikko Rasa <tdb@tdb.fi>
Wed, 27 Oct 2010 20:28:20 +0000 (20:28 +0000)
Use typedefs for Catalogue maps

19 files changed:
locos.dat
source/3d/catalogue.cpp
source/designer/manipulator.cpp
source/engineer/trainproperties.cpp
source/libmarklin/articlenumber.cpp [new file with mode: 0644]
source/libmarklin/articlenumber.h [new file with mode: 0644]
source/libmarklin/catalogue.cpp
source/libmarklin/catalogue.h
source/libmarklin/layout.cpp
source/libmarklin/layout.h
source/libmarklin/tracktype.cpp
source/libmarklin/tracktype.h
source/libmarklin/train.cpp
source/libmarklin/train.h
source/libmarklin/vehicletype.cpp
source/libmarklin/vehicletype.h
source/network/packets.h
source/network/server.cpp
wagons.dat

index 1c182dce2fd7f48a648fce002f8db8242ade79e9..223cc6698139b7396257b423860b2030c79e4f21 100644 (file)
--- a/locos.dat
+++ b/locos.dat
@@ -114,7 +114,7 @@ vehicle 36850
        };
 };
 
-vehicle 37225
+vehicle \37225-02
 {
        name "BR 194";
        locomotive true;
index 5229499ad505f93912ca25784689ca00b53e9034..2f4fc04ded6ee6923322691354ebcba03c595334 100644 (file)
@@ -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<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));
index 42c422923ab7540c4e686263f1bc4a82040370f2..7abe3d750650448b31989e09f082d8919888da3c 100644 (file)
@@ -280,10 +280,10 @@ void Manipulator::connect()
                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)
index 81463d28498a6493281cecbf5558ac8fc927f5a2..efbf842c4ee10cc84368a850f42ff0738f443f8f 100644 (file)
@@ -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<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;
@@ -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<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;
@@ -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<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)
diff --git a/source/libmarklin/articlenumber.cpp b/source/libmarklin/articlenumber.cpp
new file mode 100644 (file)
index 0000000..cac3b32
--- /dev/null
@@ -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 <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
diff --git a/source/libmarklin/articlenumber.h b/source/libmarklin/articlenumber.h
new file mode 100644 (file)
index 0000000..0aa6498
--- /dev/null
@@ -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 <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
index beab69a62ae387cf37b54745518472ac14ee0ef9..97a91e23ad2af63081f85b0aa7c62324e196fa29 100644 (file)
@@ -24,9 +24,9 @@ Catalogue::Catalogue():
 
 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;
 }
 
@@ -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<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");
 
@@ -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<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");
 
@@ -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<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()
@@ -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<TrackType> 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<VehicleType> veh = new VehicleType(art_nr);
        load_sub(*veh);
index 9a21c5ebadcc15c3e8f57b4257be9293af18891a..a436994ecea6ae700268bd878d8c4a25135831be 100644 (file)
@@ -10,6 +10,7 @@ Distributed under the GPL
 
 #include <map>
 #include <msp/datafile/loader.h>
+#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<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;
 
@@ -44,8 +50,8 @@ private:
        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:
@@ -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<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; }
 };
index 338612a104e24a94567430084e61a6e0e3e4cd88..25568d6e6fb23d51e86ad003cf36d12c466314b9 100644 (file)
@@ -296,8 +296,10 @@ Layout::Loader::Loader(Layout &l):
        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()
@@ -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);
index e96bc951298c385d7906075238a092a738a5ff16..1ec1012c431d098c9ef1078fa621b2302f8bd53f 100644 (file)
@@ -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:
index 53c2bc47844c862e0a3b07db63f94aa71a37e041..432cea847f52b0e3b02415b8f503abc733d1b048 100644 (file)
@@ -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)
 { }
index b44374018239060f0dd62be2dbbae4cefc7701c3..b1aff1e0920e3229113c517d5fb228c62a511501 100644 (file)
@@ -9,6 +9,7 @@ Distributed under the GPL
 #define LIBMARKLIN_TRACKTYPE_H_
 
 #include <msp/datafile/loader.h>
+#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<TrackPart> parts;
        std::vector<Endpoint> 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;
index 38f1c765aead156f1e6b6a16f2df9d8c542c1079..6ab617ec1bbba2da119a58fc0689b017208ba192 100644 (file)
@@ -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);
index 4c4d1c353cb3145d566d7a5917d605c73cc02b74..8418d899c5d37980188d12bcc87c38d8dd4ff908 100644 (file)
@@ -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<void, const std::string &> signal_name_changed;
index 639415f640317bc87ad4e2299deb36f7c3198a94..5c14cbada6b5dc43905d6b064b087533bd87d066 100644 (file)
@@ -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),
index 9ef1c5ec9d22798620674d486588789cecb24e07..7844825ea17111188e6c560475c9afffcf1d5e0c 100644 (file)
@@ -9,6 +9,7 @@ Distributed under the GPL
 #define LIBMARKLIN_VEHICLETYPE_H_
 
 #include <msp/datafile/objectloader.h>
+#include "articlenumber.h"
 
 namespace Marklin {
 
@@ -67,7 +68,7 @@ public:
        };
 
 private:
-       unsigned art_nr;
+       ArticleNumber art_nr;
        std::string name;
        bool locomotive;
        std::map<unsigned, std::string> 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;
index 8bbaf8e239d4b8d3dd946f5c3e0817d1098df496..bb08941b49b1235d0e9529e57304e7126ded99b2 100644 (file)
@@ -15,7 +15,7 @@ namespace Marklin {
 struct TrainInfoPacket
 {
        unsigned address;
-       unsigned loco_type;
+       std::string loco_type;
        std::string name;
 };
 
index d27683965897161a1c50f26db4716070c53f5002..2bf641297309ad2e3a5ba304f6502af00fbc6fad 100644 (file)
@@ -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);
                }
index 9c99edbd22b2a3471c0917dde2e76a3bb2619bb9..ea9d1583cc79b0c7b10eb7aefe5f0108ecd624c2 100644 (file)
@@ -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";