From 378f04522aa762729c0d5651fb60ad7e4d8ba9f3 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 26 Sep 2010 09:28:16 +0000 Subject: [PATCH] Full vehicle unification Add controls for adding vehicles to TrainProperties --- locos.dat | 15 +++-- source/engineer/trainpanel.cpp | 2 +- source/engineer/trainproperties.cpp | 89 ++++++++++++++++++++++------- source/engineer/trainproperties.h | 5 ++ source/libmarklin/catalogue.cpp | 20 +------ source/libmarklin/catalogue.h | 3 - source/libmarklin/layout.cpp | 4 +- source/libmarklin/locotype.cpp | 37 ------------ source/libmarklin/locotype.h | 39 ------------- source/libmarklin/train.cpp | 31 +++++++++- source/libmarklin/train.h | 12 ++-- source/libmarklin/vehicle.cpp | 4 ++ source/libmarklin/vehicletype.cpp | 29 +++++++--- source/libmarklin/vehicletype.h | 7 ++- source/network/server.cpp | 2 +- source/network/train.cpp | 2 +- source/network/train.h | 6 +- source/remote/trainpanel.cpp | 1 - tracks.dat | 2 +- 19 files changed, 161 insertions(+), 149 deletions(-) delete mode 100644 source/libmarklin/locotype.cpp delete mode 100644 source/libmarklin/locotype.h diff --git a/locos.dat b/locos.dat index c8a435f..9f05b8e 100644 --- a/locos.dat +++ b/locos.dat @@ -3,9 +3,10 @@ scale 1 87; gauge 16.5; -locomotive 39230 +vehicle 39230 { name "BR 23"; + locomotive true; function 0 "light"; function 1 "smke"; function 2 "sfx"; @@ -32,9 +33,10 @@ locomotive 39230 }; }; -locomotive 37844 +vehicle 37844 { name "BR 50"; + locomotive true; function 0 "light"; function 1 "smke"; function 2 "telex"; @@ -59,9 +61,10 @@ locomotive 37844 axle { position -50; wheel_diameter 16; powered true; }; }; -locomotive 33961 +vehicle 33961 { name "BR 86"; + locomotive true; function 0 "light"; function 2 "telex"; @@ -85,9 +88,10 @@ locomotive 33961 }; }; -locomotive 36850 +vehicle 36850 { name "BR 185"; + locomotive true; function 0 "light"; length 218; @@ -110,9 +114,10 @@ locomotive 36850 }; }; -locomotive 37225 +vehicle 37225 { name "BR 194"; + locomotive true; function 0 "light"; length 212; diff --git a/source/engineer/trainpanel.cpp b/source/engineer/trainpanel.cpp index 590f1cd..7177489 100644 --- a/source/engineer/trainpanel.cpp +++ b/source/engineer/trainpanel.cpp @@ -8,8 +8,8 @@ Distributed under the GPL #include #include #include -#include "libmarklin/locotype.h" #include "libmarklin/timetable.h" +#include "libmarklin/vehicletype.h" #include "engineer.h" #include "routeselect.h" #include "timetabledialog.h" diff --git a/source/engineer/trainproperties.cpp b/source/engineer/trainproperties.cpp index 4596000..bdd39fb 100644 --- a/source/engineer/trainproperties.cpp +++ b/source/engineer/trainproperties.cpp @@ -5,11 +5,11 @@ Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa Distributed under the GPL */ -#include #include #include #include -#include "libmarklin/locotype.h" +#include "libmarklin/vehicle.h" +#include "libmarklin/vehicletype.h" #include "engineer.h" #include "trainproperties.h" @@ -23,23 +23,23 @@ TrainProperties::TrainProperties(Engineer &e, const GLtk::Resources &r, Train *t engineer(e), train(t) { - set_size(200, 145); + set_size(200, 275); GLtk::Label *label; - add(*(label=new GLtk::Label(res, "Train properties"))); + add(*(label = new GLtk::Label(res, "Train properties"))); label->set_geometry(GLtk::Geometry(10, geom.h-25, geom.w-20, 20)); - add(*(ent_addr=new GLtk::Entry(res))); + add(*(ent_addr = new GLtk::Entry(res))); ent_addr->set_geometry(GLtk::Geometry(10, geom.h-50, 40, 20)); - add(*(drp_type=new GLtk::Dropdown(res))); + 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(); unsigned n = 0; for(map::const_iterator i=vehs.begin(); i!=vehs.end(); ++i, ++n) { - if(!dynamic_cast(i->second)) + if(!i->second->is_locomotive()) continue; drp_type->append(format("%d %s", i->second->get_article_number(), i->second->get_name())); @@ -47,10 +47,10 @@ TrainProperties::TrainProperties(Engineer &e, const GLtk::Resources &r, Train *t drp_type->set_selected_index(n); } - add(*(ent_name=new GLtk::Entry(res))); + add(*(ent_name = new GLtk::Entry(res))); ent_name->set_geometry(GLtk::Geometry(10, geom.h-75, geom.w-20, 20)); - add(*(drp_priority=new GLtk::Dropdown(res))); + add(*(drp_priority = new GLtk::Dropdown(res))); drp_priority->set_geometry(GLtk::Geometry(10, geom.h-100, geom.w-20, 20)); drp_priority->append("Standard freight"); drp_priority->append("Express freight"); @@ -58,11 +58,34 @@ TrainProperties::TrainProperties(Engineer &e, const GLtk::Resources &r, Train *t drp_priority->append("Standard passenger"); drp_priority->append("Express passenger"); + add(*(lst_vehicles = new GLtk::List(res))); + lst_vehicles->set_geometry(GLtk::Geometry(10, geom.h-205, geom.w-20, 100)); + + add(*(drp_new_vehicle = new GLtk::Dropdown(res))); + 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) + { + if(i->second->is_locomotive()) + continue; + + drp_new_vehicle->append(format("%d %s", i->second->get_article_number(), i->second->get_name())); + } + drp_new_vehicle->signal_item_selected.connect(sigc::mem_fun(this, &TrainProperties::new_vehicle_selected)); + if(train) { ent_addr->set_text(lexical_cast(train->get_address())); ent_name->set_text(train->get_name()); drp_priority->set_selected_index(train->get_priority()+2); + + unsigned n_vehicles = train->get_n_vehicles(); + for(unsigned i=1; iget_vehicle(i).get_type(); + lst_vehicles->append(format("%d %s", type.get_article_number(), type.get_name())); + } } else { @@ -75,22 +98,44 @@ void TrainProperties::on_ok_clicked() { if(!train) { - const map &vehs = engineer.get_catalogue().get_vehicles(); - map::const_iterator i = vehs.begin(); - unsigned n = drp_type->get_selected_index(); - while(!dynamic_cast(i->second)) - ++i; - while(n) - { - if(dynamic_cast(i->second)) - --n; - ++i; - } - + const VehicleType &type = get_vehicle_type(drp_type->get_selected_index(), true); unsigned addr = lexical_cast(ent_addr->get_text()); - train = new Train(engineer.get_layout(), *dynamic_cast(i->second), addr); + train = new Train(engineer.get_layout(), type, addr); } train->set_name(ent_name->get_text()); train->set_priority(drp_priority->get_selected_index()-2); + + for(vector::const_iterator i=add_vehicles.begin(); i!=add_vehicles.end(); ++i) + train->add_vehicle(**i); +} + +void TrainProperties::new_vehicle_selected(unsigned n, const string &) +{ + if(n==0) + return; + + const VehicleType &type = get_vehicle_type(n-1, false); + add_vehicles.push_back(&type); + lst_vehicles->append(format("%d %s", type.get_article_number(), type.get_name())); + + drp_new_vehicle->set_selected_index(0); +} + +const VehicleType &TrainProperties::get_vehicle_type(unsigned n, bool loco) +{ + const map &vehs = engineer.get_catalogue().get_vehicles(); + map::const_iterator i = vehs.begin(); + while(i!=vehs.end()) + { + if(i->second->is_locomotive()==loco) + { + if(!n) + return *i->second; + --n; + } + ++i; + } + + throw InvalidParameterValue("Vehicle type index out of range"); } diff --git a/source/engineer/trainproperties.h b/source/engineer/trainproperties.h index 3c1a372..c75015b 100644 --- a/source/engineer/trainproperties.h +++ b/source/engineer/trainproperties.h @@ -24,11 +24,16 @@ private: Msp::GLtk::Dropdown *drp_type; Msp::GLtk::Entry *ent_name; Msp::GLtk::Dropdown *drp_priority; + Msp::GLtk::List *lst_vehicles; + Msp::GLtk::Dropdown *drp_new_vehicle; + std::vector add_vehicles; public: TrainProperties(Engineer &, const Msp::GLtk::Resources &, Marklin::Train *); private: virtual void on_ok_clicked(); + void new_vehicle_selected(unsigned, const std::string &); + const Marklin::VehicleType &get_vehicle_type(unsigned, bool); }; #endif diff --git a/source/libmarklin/catalogue.cpp b/source/libmarklin/catalogue.cpp index 286407c..fca6045 100644 --- a/source/libmarklin/catalogue.cpp +++ b/source/libmarklin/catalogue.cpp @@ -8,8 +8,8 @@ Distributed under the GPL #include #include #include "catalogue.h" -#include "locotype.h" #include "tracktype.h" +#include "vehicletype.h" using namespace std; using namespace Msp; @@ -66,15 +66,6 @@ const VehicleType &Catalogue::get_vehicle(unsigned art_nr) const return *i->second; } -const LocoType &Catalogue::get_locomotive(unsigned art_nr) const -{ - const VehicleType &veh = get_vehicle(art_nr); - if(const LocoType *loco = dynamic_cast(&veh)) - return *loco; - - throw Exception("Vehicle is not a locomotive"); -} - Catalogue::Loader::Loader(Catalogue &c): DataFile::BasicLoader(c) @@ -82,7 +73,6 @@ Catalogue::Loader::Loader(Catalogue &c): add("ballast_profile", &Loader::ballast_profile); add("gauge", &Loader::gauge); add("layout", &Loader::layout); - add("locomotive", &Loader::locomotive); add("rail_profile", &Loader::rail_profile); add("scale", &Loader::scale); add("track", &Loader::track); @@ -107,14 +97,6 @@ void Catalogue::Loader::layout() load_sub(obj.layout); } -void Catalogue::Loader::locomotive(unsigned art_nr) -{ - RefPtr loco = new LocoType(art_nr); - load_sub(*loco); - obj.add_vehicle(*loco); - loco.release(); -} - void Catalogue::Loader::rail_profile() { load_sub(obj.rail_profile); diff --git a/source/libmarklin/catalogue.h b/source/libmarklin/catalogue.h index 524d3f2..d529cfc 100644 --- a/source/libmarklin/catalogue.h +++ b/source/libmarklin/catalogue.h @@ -15,7 +15,6 @@ Distributed under the GPL namespace Marklin { -class LocoType; class TrackType; class VehicleType; @@ -30,7 +29,6 @@ public: void ballast_profile(); void gauge(float); void layout(); - void locomotive(unsigned); void rail_profile(); void scale(float, float); void track(unsigned); @@ -66,7 +64,6 @@ public: void add_vehicle(VehicleType &); const VehicleType &get_vehicle(unsigned) const; - const LocoType &get_locomotive(unsigned) const; const std::map &get_vehicles() const { return vehicles; } Layout &get_layout() { return layout; } diff --git a/source/libmarklin/layout.cpp b/source/libmarklin/layout.cpp index 9729741..1448a1d 100644 --- a/source/libmarklin/layout.cpp +++ b/source/libmarklin/layout.cpp @@ -15,11 +15,11 @@ Distributed under the GPL #include "catalogue.h" #include "driver.h" #include "layout.h" -#include "locotype.h" #include "route.h" #include "track.h" #include "tracktype.h" #include "train.h" +#include "vehicletype.h" using namespace std; using namespace Msp; @@ -414,7 +414,7 @@ void Layout::Loader::track(unsigned art_nr) void Layout::Loader::train(unsigned art_nr, unsigned addr) { - Train *trn = new Train(obj, obj.catalogue.get_locomotive(art_nr), addr); + Train *trn = new Train(obj, obj.catalogue.get_vehicle(art_nr), addr); load_sub(*trn); } diff --git a/source/libmarklin/locotype.cpp b/source/libmarklin/locotype.cpp deleted file mode 100644 index c00f7d3..0000000 --- a/source/libmarklin/locotype.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id$ - -This file is part of the MSP Märklin suite -Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - -#include "locotype.h" - -using namespace std; - -namespace Marklin { - -LocoType::LocoType(unsigned an): - VehicleType(an) -{ } - -unsigned LocoType::get_max_function() const -{ - if(funcs.empty()) - return 0; - return (--funcs.end())->first; -} - - -LocoType::Loader::Loader(LocoType <): - VehicleType::Loader(lt) -{ - add("function", &Loader::function); -} - -void LocoType::Loader::function(unsigned i, const string &f) -{ - static_cast(obj).funcs[i] = f; -} - -} // namespace Marklin diff --git a/source/libmarklin/locotype.h b/source/libmarklin/locotype.h deleted file mode 100644 index 8234c4f..0000000 --- a/source/libmarklin/locotype.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id$ - -This file is part of the MSP Märklin suite -Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa -Distributed under the GPL -*/ - -#ifndef LIBMARKLIN_LOCOTYPE_H_ -#define LIBMARKLIN_LOCOTYPE_H_ - -#include "vehicletype.h" - -namespace Marklin { - -class LocoType: public VehicleType -{ -public: - class Loader: public VehicleType::Loader - { - public: - Loader(LocoType &); - private: - void function(unsigned, const std::string &); - }; - -private: - unsigned art_nr; - std::string name; - std::map funcs; - -public: - LocoType(unsigned); - unsigned get_max_function() const; - const std::map &get_functions() const { return funcs; } -}; - -} // namespace Marklin - -#endif diff --git a/source/libmarklin/train.cpp b/source/libmarklin/train.cpp index a6fd46d..eadc37d 100644 --- a/source/libmarklin/train.cpp +++ b/source/libmarklin/train.cpp @@ -13,20 +13,20 @@ Distributed under the GPL #include "catalogue.h" #include "driver.h" #include "layout.h" -#include "locotype.h" #include "route.h" #include "simplephysics.h" #include "timetable.h" #include "tracktype.h" #include "train.h" #include "vehicle.h" +#include "vehicletype.h" using namespace std; using namespace Msp; namespace Marklin { -Train::Train(Layout &l, const LocoType &t, unsigned a): +Train::Train(Layout &l, const VehicleType &t, unsigned a): layout(l), loco_type(t), address(a), @@ -49,6 +49,9 @@ Train::Train(Layout &l, const LocoType &t, unsigned a): accurate_position(false), overshoot_dist(false) { + if(!loco_type.is_locomotive()) + throw InvalidParameterValue("Initial vehicle must be a locomotive"); + vehicles.push_back(new Vehicle(layout, loco_type)); layout.add_train(*this); @@ -87,6 +90,30 @@ void Train::set_priority(int p) priority = p; } +void Train::add_vehicle(const VehicleType &vt) +{ + Vehicle *veh = new Vehicle(layout, vt); + vehicles.back()->attach_back(*veh); + vehicles.push_back(veh); +} + +void Train::remove_vehicle(unsigned i) +{ + if(i>=vehicles.size()) + throw InvalidParameterValue("Vehicle index out of range"); + if(i==0) + throw InvalidParameterValue("Can't remove the locomotive"); + delete vehicles[i]; + vehicles.erase(vehicles.begin()+i); + if(iattach_back(*vehicles[i]); +} + +unsigned Train::get_n_vehicles() const +{ + return vehicles.size(); +} + Vehicle &Train::get_vehicle(unsigned i) { if(i>=vehicles.size()) diff --git a/source/libmarklin/train.h b/source/libmarklin/train.h index ccfcbec..e8785f5 100644 --- a/source/libmarklin/train.h +++ b/source/libmarklin/train.h @@ -16,10 +16,10 @@ Distributed under the GPL namespace Marklin { class ControlModel; -class LocoType; class Route; class Timetable; class Vehicle; +class VehicleType; class Train: public sigc::trackable { @@ -28,6 +28,7 @@ public: { private: Block *prev_block; + bool blocks_valid; public: Loader(Train &); @@ -68,7 +69,7 @@ private: }; Layout &layout; - const LocoType &loco_type; + const VehicleType &loco_type; unsigned address; std::string name; int priority; @@ -97,11 +98,11 @@ private: float overshoot_dist; public: - Train(Layout &, const LocoType &, unsigned); + Train(Layout &, const VehicleType &, unsigned); ~Train(); Layout &get_layout() const { return layout; } - const LocoType &get_locomotive_type() const { return loco_type; } + const VehicleType &get_locomotive_type() const { return loco_type; } unsigned get_address() const { return address; } void set_name(const std::string &); const std::string &get_name() const { return name; } @@ -109,6 +110,9 @@ public: int get_priority() const { return priority; } ControlModel &get_control() const { return *control; } + void add_vehicle(const VehicleType &); + void remove_vehicle(unsigned); + unsigned get_n_vehicles() const; Vehicle &get_vehicle(unsigned); const Vehicle &get_vehicle(unsigned) const; diff --git a/source/libmarklin/vehicle.cpp b/source/libmarklin/vehicle.cpp index 1f3d3ec..109c3f4 100644 --- a/source/libmarklin/vehicle.cpp +++ b/source/libmarklin/vehicle.cpp @@ -31,6 +31,10 @@ Vehicle::Vehicle(Layout &l, const VehicleType &t): Vehicle::~Vehicle() { + if(next) + detach_back(); + if(prev) + detach_front(); layout.remove_vehicle(*this); } diff --git a/source/libmarklin/vehicletype.cpp b/source/libmarklin/vehicletype.cpp index 0c057e2..dd15b48 100644 --- a/source/libmarklin/vehicletype.cpp +++ b/source/libmarklin/vehicletype.cpp @@ -7,6 +7,7 @@ Distributed under the GPL #include "vehicletype.h" +using namespace std; using namespace Msp; namespace Marklin { @@ -18,6 +19,13 @@ VehicleType::VehicleType(unsigned n): height(0) { } +unsigned VehicleType::get_max_function() const +{ + if(functions.empty()) + return 0; + return (--functions.end())->first; +} + VehicleType::Axle::Axle(): position(0), @@ -35,13 +43,15 @@ VehicleType::Bogie::Bogie(): VehicleType::Loader::Loader(VehicleType &vt): DataFile::ObjectLoader(vt) { - add("axle", &Loader::axle); - add("bogie", &Loader::bogie); - add("height", &Loader::height); - add("length", &Loader::length); - add("object", &VehicleType::object); - add("name", &VehicleType::name); - add("width", &Loader::width); + add("axle", &Loader::axle); + add("bogie", &Loader::bogie); + add("function", &Loader::function); + add("height", &Loader::height); + add("length", &Loader::length); + add("locomotive", &VehicleType::locomotive); + add("object", &VehicleType::object); + add("name", &VehicleType::name); + add("width", &Loader::width); } void VehicleType::Loader::axle() @@ -58,6 +68,11 @@ void VehicleType::Loader::bogie() obj.bogies.push_back(bog); } +void VehicleType::Loader::function(unsigned i, const string &f) +{ + obj.functions[i] = f; +} + void VehicleType::Loader::height(float h) { obj.height = h/1000; diff --git a/source/libmarklin/vehicletype.h b/source/libmarklin/vehicletype.h index 65f69e7..2edf3bf 100644 --- a/source/libmarklin/vehicletype.h +++ b/source/libmarklin/vehicletype.h @@ -22,6 +22,7 @@ public: private: void axle(); void bogie(); + void function(unsigned, const std::string &); void height(float); void length(float); void width(float); @@ -67,6 +68,8 @@ public: private: unsigned art_nr; std::string name; + bool locomotive; + std::map functions; float length; float width; float height; @@ -76,10 +79,12 @@ private: public: VehicleType(unsigned); - virtual ~VehicleType() { } // XXX temporary unsigned 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; + const std::map &get_functions() const { return functions; } float get_length() const { return length; } float get_width() const { return width; } float get_height() const { return height; } diff --git a/source/network/server.cpp b/source/network/server.cpp index dd0dd8b..8db6871 100644 --- a/source/network/server.cpp +++ b/source/network/server.cpp @@ -6,9 +6,9 @@ Distributed under the GPL */ #include -#include "libmarklin/locotype.h" #include "libmarklin/route.h" #include "libmarklin/train.h" +#include "libmarklin/vehicletype.h" #include "server.h" using namespace std; diff --git a/source/network/train.cpp b/source/network/train.cpp index 5c4b457..6a0c3a8 100644 --- a/source/network/train.cpp +++ b/source/network/train.cpp @@ -14,7 +14,7 @@ namespace Marklin { NetTrain::NetTrain(Client &c, const TrainInfoPacket &pkt): client(c), - loco_type(client.get_catalogue().get_locomotive(pkt.loco_type)), + loco_type(client.get_catalogue().get_vehicle(pkt.loco_type)), address(pkt.address), name(pkt.name), functions(0) diff --git a/source/network/train.h b/source/network/train.h index 74c6ccb..3de4f7d 100644 --- a/source/network/train.h +++ b/source/network/train.h @@ -9,7 +9,7 @@ Distributed under the GPL #define MARKLINNET_TRAIN_H_ #include -#include "libmarklin/locotype.h" +#include "libmarklin/vehicletype.h" #include "packets.h" namespace Marklin { @@ -27,7 +27,7 @@ public: private: Client &client; - const LocoType &loco_type; + const VehicleType &loco_type; unsigned address; std::string name; std::map controls; @@ -38,7 +38,7 @@ private: public: NetTrain(Client &, const TrainInfoPacket &); - const LocoType &get_loco_type() const { return loco_type; } + const VehicleType &get_loco_type() const { return loco_type; } unsigned get_address() const { return address; } const std::string &get_name() const { return name; } void set_control(const std::string &, float); diff --git a/source/remote/trainpanel.cpp b/source/remote/trainpanel.cpp index 37d75af..45435d5 100644 --- a/source/remote/trainpanel.cpp +++ b/source/remote/trainpanel.cpp @@ -7,7 +7,6 @@ Distributed under the GPL #include #include -#include "libmarklin/locotype.h" #include "remote.h" #include "trainpanel.h" diff --git a/tracks.dat b/tracks.dat index 7a2c07a..fac3dfc 100644 --- a/tracks.dat +++ b/tracks.dat @@ -442,7 +442,7 @@ track 24977 description "Bumper"; part { - length 94.2; + length 77.5; dead_end true; }; }; -- 2.43.0