scale 1 87;
gauge 16.5;
-locomotive 39230
+vehicle 39230
{
name "BR 23";
+ locomotive true;
function 0 "light";
function 1 "smke";
function 2 "sfx";
};
};
-locomotive 37844
+vehicle 37844
{
name "BR 50";
+ locomotive true;
function 0 "light";
function 1 "smke";
function 2 "telex";
axle { position -50; wheel_diameter 16; powered true; };
};
-locomotive 33961
+vehicle 33961
{
name "BR 86";
+ locomotive true;
function 0 "light";
function 2 "telex";
};
};
-locomotive 36850
+vehicle 36850
{
name "BR 185";
+ locomotive true;
function 0 "light";
length 218;
};
};
-locomotive 37225
+vehicle 37225
{
name "BR 194";
+ locomotive true;
function 0 "light";
length 212;
#include <cmath>
#include <msp/gltk/button.h>
#include <msp/strings/formatter.h>
-#include "libmarklin/locotype.h"
#include "libmarklin/timetable.h"
+#include "libmarklin/vehicletype.h"
#include "engineer.h"
#include "routeselect.h"
#include "timetabledialog.h"
Distributed under the GPL
*/
-#include <msp/gltk/button.h>
#include <msp/gltk/label.h>
#include <msp/strings/formatter.h>
#include <msp/strings/lexicalcast.h>
-#include "libmarklin/locotype.h"
+#include "libmarklin/vehicle.h"
+#include "libmarklin/vehicletype.h"
#include "engineer.h"
#include "trainproperties.h"
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<unsigned, VehicleType *> &vehs = engineer.get_catalogue().get_vehicles();
unsigned n = 0;
for(map<unsigned, VehicleType *>::const_iterator i=vehs.begin(); i!=vehs.end(); ++i, ++n)
{
- if(!dynamic_cast<LocoType *>(i->second))
+ if(!i->second->is_locomotive())
continue;
drp_type->append(format("%d %s", i->second->get_article_number(), i->second->get_name()));
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");
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<unsigned, VehicleType *>::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; i<n_vehicles; ++i)
+ {
+ const VehicleType &type = train->get_vehicle(i).get_type();
+ lst_vehicles->append(format("%d %s", type.get_article_number(), type.get_name()));
+ }
}
else
{
{
if(!train)
{
- const map<unsigned, VehicleType *> &vehs = engineer.get_catalogue().get_vehicles();
- map<unsigned, VehicleType *>::const_iterator i = vehs.begin();
- unsigned n = drp_type->get_selected_index();
- while(!dynamic_cast<LocoType *>(i->second))
- ++i;
- while(n)
- {
- if(dynamic_cast<LocoType *>(i->second))
- --n;
- ++i;
- }
-
+ const VehicleType &type = get_vehicle_type(drp_type->get_selected_index(), true);
unsigned addr = lexical_cast<unsigned>(ent_addr->get_text());
- train = new Train(engineer.get_layout(), *dynamic_cast<LocoType *>(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 VehicleType *>::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<unsigned, VehicleType *> &vehs = engineer.get_catalogue().get_vehicles();
+ map<unsigned, VehicleType *>::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");
}
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<const Marklin::VehicleType *> 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
#include <msp/core/refptr.h>
#include <msp/datafile/parser.h>
#include "catalogue.h"
-#include "locotype.h"
#include "tracktype.h"
+#include "vehicletype.h"
using namespace std;
using namespace Msp;
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<const LocoType *>(&veh))
- return *loco;
-
- throw Exception("Vehicle is not a locomotive");
-}
-
Catalogue::Loader::Loader(Catalogue &c):
DataFile::BasicLoader<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);
load_sub(obj.layout);
}
-void Catalogue::Loader::locomotive(unsigned art_nr)
-{
- RefPtr<LocoType> loco = new LocoType(art_nr);
- load_sub(*loco);
- obj.add_vehicle(*loco);
- loco.release();
-}
-
void Catalogue::Loader::rail_profile()
{
load_sub(obj.rail_profile);
namespace Marklin {
-class LocoType;
class TrackType;
class VehicleType;
void ballast_profile();
void gauge(float);
void layout();
- void locomotive(unsigned);
void rail_profile();
void scale(float, float);
void track(unsigned);
void add_vehicle(VehicleType &);
const VehicleType &get_vehicle(unsigned) const;
- const LocoType &get_locomotive(unsigned) const;
const std::map<unsigned, VehicleType *> &get_vehicles() const { return vehicles; }
Layout &get_layout() { return layout; }
#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;
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);
}
+++ /dev/null
-/* $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<LocoType &>(obj).funcs[i] = f;
-}
-
-} // namespace Marklin
+++ /dev/null
-/* $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<unsigned, std::string> funcs;
-
-public:
- LocoType(unsigned);
- unsigned get_max_function() const;
- const std::map<unsigned, std::string> &get_functions() const { return funcs; }
-};
-
-} // namespace Marklin
-
-#endif
#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),
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);
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(i<vehicles.size())
+ vehicles[i-1]->attach_back(*vehicles[i]);
+}
+
+unsigned Train::get_n_vehicles() const
+{
+ return vehicles.size();
+}
+
Vehicle &Train::get_vehicle(unsigned i)
{
if(i>=vehicles.size())
namespace Marklin {
class ControlModel;
-class LocoType;
class Route;
class Timetable;
class Vehicle;
+class VehicleType;
class Train: public sigc::trackable
{
{
private:
Block *prev_block;
+ bool blocks_valid;
public:
Loader(Train &);
};
Layout &layout;
- const LocoType &loco_type;
+ const VehicleType &loco_type;
unsigned address;
std::string name;
int priority;
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; }
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;
Vehicle::~Vehicle()
{
+ if(next)
+ detach_back();
+ if(prev)
+ detach_front();
layout.remove_vehicle(*this);
}
#include "vehicletype.h"
+using namespace std;
using namespace Msp;
namespace Marklin {
height(0)
{ }
+unsigned VehicleType::get_max_function() const
+{
+ if(functions.empty())
+ return 0;
+ return (--functions.end())->first;
+}
+
VehicleType::Axle::Axle():
position(0),
VehicleType::Loader::Loader(VehicleType &vt):
DataFile::ObjectLoader<VehicleType>(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()
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;
private:
void axle();
void bogie();
+ void function(unsigned, const std::string &);
void height(float);
void length(float);
void width(float);
private:
unsigned art_nr;
std::string name;
+ bool locomotive;
+ std::map<unsigned, std::string> functions;
float length;
float width;
float height;
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<unsigned, std::string> &get_functions() const { return functions; }
float get_length() const { return length; }
float get_width() const { return width; }
float get_height() const { return height; }
*/
#include <msp/net/inet.h>
-#include "libmarklin/locotype.h"
#include "libmarklin/route.h"
#include "libmarklin/train.h"
+#include "libmarklin/vehicletype.h"
#include "server.h"
using namespace std;
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)
#define MARKLINNET_TRAIN_H_
#include <sigc++/signal.h>
-#include "libmarklin/locotype.h"
+#include "libmarklin/vehicletype.h"
#include "packets.h"
namespace Marklin {
private:
Client &client;
- const LocoType &loco_type;
+ const VehicleType &loco_type;
unsigned address;
std::string name;
std::map<std::string, float> controls;
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);
#include <gtkmm/box.h>
#include <gtkmm/liststore.h>
-#include "libmarklin/locotype.h"
#include "remote.h"
#include "trainpanel.h"
description "Bumper";
part
{
- length 94.2;
+ length 77.5;
dead_end true;
};
};