const Vector &pos = vehicle.get_position();
matrix.translate(pos.x, pos.y, pos.z);
- matrix.rotate(vehicle.get_direction(), 0, 0, 1);
+ matrix.rotate(vehicle.get_rotation(), 0, 0, 1);
if(bogie)
{
const Vector &pos = vehicle.get_position();
matrix.translate(pos.x, pos.y, pos.z);
- matrix.rotate(vehicle.get_direction(), 0, 0, 1);
+ matrix.rotate(vehicle.get_rotation(), 0, 0, 1);
matrix.translate(bogie.type->position, 0, 0);
float dir = bogie.direction;
GL::Matrix matrix;
const Vector &pos = vehicle.get_position();
matrix.translate(pos.x, pos.y, pos.z);
- matrix.rotate(vehicle.get_direction(), 0, 0, 1);
+ matrix.rotate(vehicle.get_rotation(), 0, 0, 1);
matrix.translate(rod.position.x, rod.position.y, rod.position.z);
if(rod.type->mirror_object)
{
const Vector &pos = signal.get_position();
renderer.matrix_stack() *= GL::Matrix::translation(pos.x, pos.y, pos.z);
- renderer.matrix_stack() *= GL::Matrix::rotation(signal.get_direction(), 0, 0, 1);
+ renderer.matrix_stack() *= GL::Matrix::rotation(signal.get_rotation(), 0, 0, 1);
// XXX Use track gauge, configure signal side
renderer.matrix_stack() *= GL::Matrix::translation(0, -0.035, 0);
}
GL::Matrix matrix;
const Vector &pos = vehicle.get_position();
matrix.translate(pos.x, pos.y, pos.z);
- float dir = vehicle.get_direction();
+ float rot = vehicle.get_rotation();
if(vehicle.get_type().get_rotate_object())
- dir += M_PI;
- matrix.rotate(dir, 0, 0, 1);
+ rot += M_PI;
+ matrix.rotate(rot, 0, 0, 1);
renderer.matrix_stack() *= matrix;
}
{
const Vehicle &veh = train.get_vehicle(0);
const Vector &pos = veh.get_position();
- float angle = veh.get_direction();
+ float angle = veh.get_rotation();
if(!forward)
angle += M_PI;
float c = cos(angle);
Track *Layout::pick_track(const Vector &start, const Vector &ray)
{
- for(set<Track *>::iterator i=tracks.begin(); i!=tracks.end(); ++i)
- if((*i)->collide_ray(start, ray))
- return *i;
-
- return 0;
+ return pick(tracks, start, ray);
}
void Layout::remove_track(Track &t)
signal_signal_added.emit(s);
}
+Signal *Layout::pick_signal(const Vector &start, const Vector &ray)
+{
+ return pick(signals, start, ray);
+}
+
void Layout::remove_signal(Signal &s)
{
if(signals.erase(&s))
signal_signal_removed.emit(s);
}
+Object *Layout::pick_object(const Vector &start, const Vector &ray)
+{
+ if(Object *obj = pick_track(start, ray))
+ return obj;
+ else if((obj = pick_signal(start, ray)))
+ return obj;
+ return 0;
+}
+
+template<typename T>
+T *Layout::pick(const set<T *> &objs, const Vector &start, const Vector &ray)
+{
+ for(typename set<T *>::const_iterator i=objs.begin(); i!=objs.end(); ++i)
+ if((*i)->collide_ray(start, ray))
+ return *i;
+
+ return 0;
+}
+
void Layout::add_block(Block &b)
{
blocks.insert(&b);
void add_signal(Signal &);
const std::set<Signal *> &get_signals() const { return signals; }
+ Signal *pick_signal(const Vector &, const Vector &);
void remove_signal(Signal &);
+ Object *pick_object(const Vector &, const Vector &);
+
+private:
+ template<typename T>
+ static T *pick(const std::set<T *> &, const Vector &, const Vector &);
+
+public:
void add_block(Block &);
Block &get_block(unsigned) const;
const std::set<Block *> &get_blocks() const { return blocks; }
--- /dev/null
+#ifndef LIBR2C2_OBJECT_H_
+#define LIBR2C2_OBJECT_H_
+
+#include "geometry.h"
+#include "objecttype.h"
+
+namespace R2C2 {
+
+class Layout;
+
+class Object
+{
+protected:
+ Layout &layout;
+ Vector position;
+ float rotation;
+
+ Object(Layout &l): layout(l) { }
+public:
+ virtual ~Object() { }
+
+ virtual Object *clone(Layout * = 0) const = 0;
+ virtual const ObjectType &get_type() const = 0;
+ Layout &get_layout() const { return layout; }
+ virtual void set_position(const Vector &) = 0;
+ virtual void set_rotation(float) = 0;
+ const Vector &get_position() const { return position; }
+ float get_rotation() const { return rotation; }
+ virtual Object *get_parent() const { return 0; }
+ virtual bool collide_ray(const Vector &, const Vector &) const = 0;
+};
+
+} // namespace R2C2
+
+#endif
--- /dev/null
+#include "objecttype.h"
+
+using namespace Msp;
+
+namespace R2C2 {
+
+ObjectType::Loader::Loader(ObjectType &ot):
+ DataFile::ObjectLoader<ObjectType>(ot)
+{
+ add("description", &ObjectType::description);
+ add("name", &ObjectType::name);
+}
+
+} // namespace R2C2
--- /dev/null
+#ifndef LIBR2C2_OBJECTTYPE_H_
+#define LIBR2C2_OBJECTTYPE_H_
+
+#include <string>
+#include <msp/datafile/objectloader.h>
+#include "articlenumber.h"
+
+namespace R2C2 {
+
+class ObjectType
+{
+public:
+ class Loader: public Msp::DataFile::ObjectLoader<ObjectType>
+ {
+ public:
+ Loader(ObjectType &);
+ };
+
+protected:
+ ArticleNumber art_nr;
+ std::string name;
+ std::string description;
+
+ ObjectType(const ArticleNumber &a): art_nr(a) { }
+public:
+ virtual ~ObjectType() { }
+
+ const ArticleNumber &get_article_number() const { return art_nr; }
+ const std::string &get_name() const { return name; }
+ const std::string &get_description() const { return description; }
+};
+
+} // namespace R2C2
+
+#endif
namespace R2C2 {
Signal::Signal(Layout &l, const SignalType &t):
- layout(l),
+ Object(l),
type(t),
address(0),
track(0),
layout.remove_signal(*this);
}
+Signal *Signal::clone(Layout *to_layout) const
+{
+ Signal *sig = new Signal((to_layout ? *to_layout : layout), type);
+ sig->set_position(position);
+ sig->set_rotation(rotation);
+ return sig;
+}
+
void Signal::set_address(unsigned a)
{
address = a;
if(d<dist || dist<0)
{
position = n.pos;
- direction = n.dir;
+ rotation = n.dir;
track = *i;
dist = d;
}
unsigned n_endpoints = track->get_type().get_endpoints().size();
for(unsigned j=0; j<n_endpoints; ++j)
{
- float a = track->get_endpoint_direction(j)-direction;
+ float a = track->get_endpoint_direction(j)-rotation;
while(a<-M_PI/2)
a += M_PI*2;
while(a>M_PI*3/2)
}
}
-void Signal::set_direction(float d)
+void Signal::set_rotation(float r)
{
- float a = direction-d;
+ float a = rotation-r;
while(a>M_PI*3/2)
a -= M_PI*2;
while(a<-M_PI/2)
a += M_PI*2;
if(a>=M_PI/2)
{
- direction += M_PI;
- if(direction>M_PI*2)
- direction -= M_PI*2;
+ rotation += M_PI;
+ if(rotation>M_PI*2)
+ rotation -= M_PI*2;
}
normalize_location();
}
+bool Signal::collide_ray(const Vector &start, const Vector &ray) const
+{
+ // XXX Totally hardcoded stuff, should be replaced with a geometry system
+ Vector center = position;
+ center.x += sin(rotation)*0.035;
+ center.y -= cos(rotation)*0.035;
+ Vector d(center.x-start.x, center.y-start.y);
+ float x = (d.x*ray.x+d.y*ray.y)/(ray.x*ray.x+ray.y*ray.y);
+ Vector nearest(start.x+ray.x*x-center.x, start.y+ray.y*x-center.y, start.z+ray.z*x-center.z);
+ if(nearest.z<0|| nearest.z>0.12)
+ return false;
+ return nearest.x*nearest.x+nearest.y*nearest.y<0.0001;
+}
+
void Signal::tick(const Time::TimeDelta &)
{
if(check_allocated_blocks)
void Signal::save(list<DataFile::Statement> &st) const
{
st.push_back((DataFile::Statement("position"), position.x, position.y, position.z));
- st.push_back((DataFile::Statement("direction"), direction));
+ st.push_back((DataFile::Statement("rotation"), rotation));
if(address)
st.push_back((DataFile::Statement("address"), address));
}
Signal::Loader::Loader(Signal &s):
DataFile::ObjectLoader<Signal>(s)
{
- add("address", &Loader::address);
- add("direction", &Loader::direction);
- add("position", &Loader::position);
+ add("address", &Loader::address);
+ add("position", &Loader::position);
+ add("rotation", &Loader::rotation);
}
void Signal::Loader::address(unsigned a)
obj.set_address(a);
}
-void Signal::Loader::direction(float d)
+void Signal::Loader::position(float x, float y, float z)
{
- obj.set_direction(d);
+ obj.set_position(Vector(x, y, z));
}
-void Signal::Loader::position(float x, float y, float z)
+void Signal::Loader::rotation(float d)
{
- obj.set_position(Vector(x, y, z));
+ obj.set_rotation(d);
}
} // namespace R2C2
#include <msp/datafile/objectloader.h>
#include <msp/time/timedelta.h>
#include "geometry.h"
+#include "object.h"
+#include "signaltype.h"
+#include "track.h"
namespace R2C2 {
class Block;
class Layout;
-class SignalType;
-class Track;
class Train;
-class Signal
+class Signal: public Object
{
public:
class Loader: public Msp::DataFile::ObjectLoader<Signal>
private:
void address(unsigned);
- void direction(float);
void position(float, float, float);
+ void rotation(float);
};
private:
- Layout &layout;
const SignalType &type;
unsigned address;
- Vector position;
- float direction;
Track *track;
Block *block;
unsigned entry;
Signal(Layout &, const SignalType &);
~Signal();
- const SignalType &get_type() const { return type; }
+ virtual Signal *clone(Layout * = 0) const;
+ virtual const SignalType &get_type() const { return type; }
void set_address(unsigned);
- void set_position(const Vector &);
- void set_direction(float);
+ virtual void set_position(const Vector &);
+ virtual void set_rotation(float);
private:
void normalize_location();
public:
- const Vector &get_position() const { return position; }
- float get_direction() const { return direction; }
+ virtual Track *get_parent() const { return track; }
+
+ virtual bool collide_ray(const Vector &, const Vector &) const;
void tick(const Msp::Time::TimeDelta &);
#include "signaltype.h"
using namespace std;
+using namespace Msp;
namespace R2C2 {
SignalType::SignalType(const ArticleNumber &an):
- art_nr(an)
+ ObjectType(an)
{
}
SignalType::Loader::Loader(SignalType &st):
- ObjectLoader<SignalType>(st)
+ DataFile::DerivedObjectLoader<SignalType, ObjectType::Loader>(st)
{
- add("description", &SignalType::description);
add("indication", &Loader::indication);
add("object", &SignalType::object);
}
#define LIBR2C2_SIGNALTYPE_H_
#include <msp/datafile/objectloader.h>
-#include "articlenumber.h"
+#include "objecttype.h"
namespace R2C2 {
-class SignalType
+class SignalType: public ObjectType
{
public:
struct Indication
unsigned free_blocks;
};
- class Loader: public Msp::DataFile::ObjectLoader<SignalType>
+ class Loader: public Msp::DataFile::DerivedObjectLoader<SignalType, ObjectType::Loader>
{
public:
Loader(SignalType &);
typedef std::list<Indication> IndicationList;
private:
- ArticleNumber art_nr;
- std::string description;
IndicationList indications;
std::string object;
public:
SignalType(const ArticleNumber &);
- const ArticleNumber &get_article_number() const { return art_nr; }
const IndicationList &get_indications() const { return indications; }
const std::string &get_object() const { return object; }
};
namespace R2C2 {
Track::Track(Layout &l, const TrackType &t):
- layout(l),
+ Object(l),
type(t),
block(0),
- rot(0),
slope(0),
flex(false),
turnout_id(0),
layout.remove_track(*this);
}
+Track *Track::clone(Layout *to_layout) const
+{
+ Track *track = new Track((to_layout ? *to_layout : layout), type);
+ track->set_position(position);
+ track->set_rotation(rotation);
+ return track;
+}
+
void Track::set_block(Block *b)
{
if(b && !b->has_track(*this))
void Track::set_position(const Vector &p)
{
- pos = p;
+ position = p;
}
void Track::set_rotation(float r)
{
- rot = r;
- while(rot<0)
- rot += M_PI*2;
- while(rot>M_PI*2)
- rot -= M_PI*2;
+ rotation = r;
+ while(rotation<0)
+ rotation += M_PI*2;
+ while(rotation>M_PI*2)
+ rotation -= M_PI*2;
}
void Track::set_slope(float s)
{
Vector epp0 = links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this));
Vector epp1 = links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this));
- pos.z = epp0.z;
- slope = epp1.z-pos.z;
+ position.z = epp0.z;
+ slope = epp1.z-position.z;
}
else
{
if(links[0])
{
Vector epp = links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this));
- pos.z = epp.z;
+ position.z = epp.z;
}
else if(links[1])
{
Vector epp = links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this));
- pos.z = epp.z;
+ position.z = epp.z;
}
}
}
const TrackType::Endpoint &ep = eps[epi];
- float c = cos(rot);
- float s = sin(rot);
+ float c = cos(rotation);
+ float s = sin(rotation);
- Vector p(pos.x+c*ep.pos.x-s*ep.pos.y, pos.y+s*ep.pos.x+c*ep.pos.y, pos.z);
+ Vector p(position.x+c*ep.pos.x-s*ep.pos.y, position.y+s*ep.pos.x+c*ep.pos.y, position.z);
if(eps.size()==2 && epi==1)
p.z += slope;
return p;
const TrackType::Endpoint &ep = eps[epi];
- return rot+ep.dir;
+ return rotation+ep.dir;
}
bool Track::snap_to(Track &other, bool link, float limit)
{
if(!link || (!flex && !other.get_flex()))
{
- set_rotation(other.rot+other_eps[j].dir-eps[i].dir+M_PI);
- Vector p(epp2.x-(eps[i].pos.x*cos(rot)-eps[i].pos.y*sin(rot)),
- epp2.y-(eps[i].pos.y*cos(rot)+eps[i].pos.x*sin(rot)),
+ set_rotation(other.rotation+other_eps[j].dir-eps[i].dir+M_PI);
+ Vector p(epp2.x-(eps[i].pos.x*cos(rotation)-eps[i].pos.y*sin(rotation)),
+ epp2.y-(eps[i].pos.y*cos(rotation)+eps[i].pos.x*sin(rotation)),
epp2.z);
if(eps.size()==2 && i==1)
p.z -= slope;
if(dx*dx+dy*dy<1e-4)
{
pt = epp;
- d = rot+eps[i].dir;
+ d = rotation+eps[i].dir;
return true;
}
}
TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const
{
TrackPoint p = type.get_point(epi, path, d);
- float c = cos(rot);
- float s = sin(rot);
+ float c = cos(rotation);
+ float s = sin(rotation);
- p.pos = Vector(pos.x+c*p.pos.x-s*p.pos.y, pos.y+s*p.pos.x+c*p.pos.y, pos.z);
- p.dir += rot;
+ p.pos = Vector(position.x+c*p.pos.x-s*p.pos.y, position.y+s*p.pos.x+c*p.pos.y, position.z);
+ p.dir += rotation;
if(type.get_endpoints().size()==2)
{
float len = type.get_path_length(path);
TrackPoint Track::get_nearest_point(const Vector &p) const
{
- Vector local(p.x-pos.x, p.y-pos.y, p.z-pos.z);
- float c = cos(rot);
- float s = sin(rot);
+ Vector local(p.x-position.x, p.y-position.y, p.z-position.z);
+ float c = cos(rotation);
+ float s = sin(rotation);
local = Vector(c*local.x+s*local.y, c*local.y-s*local.x, local.z);
TrackPoint tp = type.get_nearest_point(local);
- tp.pos = Vector(pos.x+tp.pos.x*c-tp.pos.y*s, pos.y+tp.pos.y*c+tp.pos.x*s, pos.z+tp.pos.z);
- tp.dir += rot;
+ tp.pos = Vector(position.x+tp.pos.x*c-tp.pos.y*s, position.y+tp.pos.y*c+tp.pos.x*s, position.z+tp.pos.z);
+ tp.dir += rotation;
return tp;
}
-bool Track::collide_ray(const Vector &start, const Vector &ray)
+bool Track::collide_ray(const Vector &start, const Vector &ray) const
{
- Vector local_start(start.x-pos.x, start.y-pos.y, start.z-pos.z);
- float c = cos(rot);
- float s = sin(rot);
+ Vector local_start(start.x-position.x, start.y-position.y, start.z-position.z);
+ float c = cos(rotation);
+ float s = sin(rotation);
local_start = Vector(c*local_start.x+s*local_start.y, c*local_start.y-s*local_start.x, local_start.z);
Vector local_ray(c*ray.x+s*ray.y, c*ray.y-s*ray.x, ray.z);
void Track::save(list<DataFile::Statement> &st) const
{
- st.push_back((DataFile::Statement("position"), pos.x, pos.y, pos.z));
- st.push_back((DataFile::Statement("rotation"), rot));
+ st.push_back((DataFile::Statement("position"), position.x, position.y, position.z));
+ st.push_back((DataFile::Statement("rotation"), rotation));
st.push_back((DataFile::Statement("slope"), slope));
if(turnout_id)
st.push_back((DataFile::Statement("turnout_id"), turnout_id));
DataFile::ObjectLoader<Track>(t)
{
add("position", &Loader::position);
- add("rotation", &Track::rot);
+ add("rotation", &Loader::rotation);
add("slope", &Track::slope);
add("turnout_id", &Loader::turnout_id);
add("sensor_id", &Loader::sensor_id);
void Track::Loader::position(float x, float y, float z)
{
- obj.pos = Vector(x, y, z);
+ obj.position = Vector(x, y, z);
+}
+
+void Track::Loader::rotation(float r)
+{
+ obj.rotation = r;
}
void Track::Loader::sensor_id(unsigned id)
#include <sigc++/trackable.h>
#include <msp/datafile/objectloader.h>
#include "geometry.h"
+#include "object.h"
+#include "tracktype.h"
namespace R2C2 {
class Block;
class Layout;
-class TrackType;
-class Track: public sigc::trackable
+class Track: public Object, public sigc::trackable
{
public:
class Loader: public Msp::DataFile::ObjectLoader<Track>
Loader(Track &);
private:
void position(float, float, float);
+ void rotation(float);
void sensor_id(unsigned);
void turnout_id(unsigned);
};
sigc::signal<void, unsigned> signal_path_changed;
private:
- Layout &layout;
const TrackType &type;
Block *block;
- Vector pos;
- float rot;
float slope;
bool flex;
unsigned turnout_id;
Track(Layout &, const TrackType &);
~Track();
- Layout &get_layout() const { return layout; }
- const TrackType &get_type() const { return type; }
+ virtual Track *clone(Layout * = 0) const;
+ virtual const TrackType &get_type() const { return type; }
void set_block(Block *);
Block &get_block() const;
- void set_position(const Vector &);
- void set_rotation(float);
+ virtual void set_position(const Vector &);
+ virtual void set_rotation(float);
void set_slope(float);
void set_flex(bool);
- const Vector &get_position() const { return pos; }
- float get_rotation() const { return rot; }
float get_slope() const { return slope; }
bool get_flex() const { return flex; }
void check_slope();
TrackPoint get_point(unsigned, float) const;
TrackPoint get_nearest_point(const Vector &) const;
- bool collide_ray(const Vector &, const Vector &);
+ virtual bool collide_ray(const Vector &, const Vector &) const;
void save(std::list<Msp::DataFile::Statement> &) const;
private:
namespace R2C2 {
TrackType::TrackType(const ArticleNumber &an):
- art_nr(an),
+ ObjectType(an),
state_bits(0),
autofit_preference(1)
{ }
TrackType::Loader::Loader(TrackType &t):
- Msp::DataFile::ObjectLoader<TrackType>(t),
+ DataFile::DerivedObjectLoader<TrackType, ObjectType::Loader>(t),
state_bits_set(false)
{
add("autofit_preference", &TrackType::autofit_preference);
- add("description", &TrackType::description);
add("object", &TrackType::object);
add("state_bits", &Loader::state_bits);
add("part", &Loader::part);
#include <msp/datafile/objectloader.h>
#include "articlenumber.h"
#include "geometry.h"
+#include "objecttype.h"
#include "trackpart.h"
namespace R2C2 {
-class TrackType
+class TrackType: public ObjectType
{
public:
struct Endpoint
bool has_common_paths(const Endpoint &e) const { return paths&e.paths; }
};
- class Loader: public Msp::DataFile::ObjectLoader<TrackType>
+ class Loader: public Msp::DataFile::DerivedObjectLoader<TrackType, ObjectType::Loader>
{
private:
bool state_bits_set;
};
private:
- ArticleNumber art_nr;
- std::string description;
std::vector<TrackPart> parts;
std::vector<Endpoint> endpoints;
unsigned state_bits;
public:
TrackType(const ArticleNumber &);
- 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;
unsigned get_paths() const;
namespace R2C2 {
Vehicle::Vehicle(Layout &l, const VehicleType &t):
- layout(l),
+ Object(l),
type(t),
next(0),
prev(0),
- direction(0),
front_sensor(0),
back_sensor(0)
{
layout.remove_vehicle(*this);
}
+Vehicle *Vehicle::clone(Layout *to_layout) const
+{
+ Vehicle *veh = new Vehicle((to_layout ? *to_layout : layout), type);
+ veh->set_position(position);
+ veh->set_rotation(rotation);
+ return veh;
+}
+
void Vehicle::attach_back(Vehicle &veh)
{
if(next || veh.prev)
position = tp.pos;
position.z += layout.get_catalogue().get_rail_elevation();
- direction = tp.dir;
+ rotation = tp.dir;
}
void Vehicle::update_position_from(const Vehicle &veh)
#define LIBR2C2_VEHICLE_H_
#include "geometry.h"
+#include "object.h"
#include "vehicletype.h"
namespace R2C2 {
};
-class Vehicle
+class Vehicle: public Object
{
public:
enum PlaceMode
TrackPoint get_point() const;
};
- Layout &layout;
const VehicleType &type;
Vehicle *next;
Vehicle *prev;
TrackPosition track_pos;
- Vector position;
- float direction;
std::vector<Axle> axles;
std::vector<Bogie> bogies;
std::vector<Rod> rods;
Vehicle(Layout &, const VehicleType &);
~Vehicle();
- const VehicleType &get_type() const { return type; }
+ virtual Vehicle *clone(Layout * = 0) const;
+ virtual const VehicleType &get_type() const { return type; }
void attach_back(Vehicle &);
void attach_front(Vehicle &);
Vehicle *get_next() const { return next; }
Vehicle *get_previous() const { return prev; }
+ // TODO implement these - should call place() with suitable parameters
+ virtual void set_position(const Vector &) { }
+ virtual void set_rotation(float) { }
void place(Track &, unsigned, float, PlaceMode = CENTER);
void unplace();
void advance(float);
Track *get_track() const { return track_pos.track; }
unsigned get_entry() const { return track_pos.ep; }
float get_offset() const { return track_pos.offs; }
- const Vector &get_position() const { return position; }
- float get_direction() const { return direction; }
const Axle &get_fixed_axle(unsigned) const;
const Bogie &get_bogie(unsigned) const;
const Axle &get_bogie_axle(unsigned, unsigned) const;
void adjust_for_distance(TrackPosition &, TrackPosition &, float, float = 0.5) const;
TrackPoint get_point(const Vector &, const Vector &, float = 0.5) const;
TrackPoint get_point(const TrackPosition &, float, float = 0.5) const;
+
+public:
+ virtual bool collide_ray(const Vector &, const Vector &) const { return false; }
};
} // namespace R2C2
namespace R2C2 {
VehicleType::VehicleType(const ArticleNumber &an):
- art_nr(an),
+ ObjectType(an),
locomotive(false),
swap_direction(false),
length(0),
VehicleType::Loader::Loader(VehicleType &vt):
- DataFile::ObjectLoader<VehicleType>(vt)
+ DataFile::DerivedObjectLoader<VehicleType, ObjectType::Loader>(vt)
{
add("axle", &Loader::axle);
add("bogie", &Loader::bogie);
add("height", &Loader::height);
add("length", &Loader::length);
add("locomotive", &VehicleType::locomotive);
- add("name", &VehicleType::name);
add("object", &VehicleType::object);
add("rod", &Loader::rod);
add("rotate_object", &VehicleType::rotate_object);
#define LIBR2C2_VEHICLETYPE_H_
#include <msp/datafile/objectloader.h>
-#include "articlenumber.h"
#include "geometry.h"
+#include "objecttype.h"
namespace R2C2 {
-class VehicleType
+class VehicleType: public ObjectType
{
public:
- class Loader: public Msp::DataFile::ObjectLoader<VehicleType>
+ class Loader: public Msp::DataFile::DerivedObjectLoader<VehicleType, ObjectType::Loader>
{
private:
std::map<std::string, unsigned> rod_tags;
typedef std::map<unsigned, std::string> FunctionMap;
private:
- ArticleNumber art_nr;
- std::string name;
bool locomotive;
FunctionMap functions;
bool swap_direction;
public:
VehicleType(const ArticleNumber &);
- 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;
const FunctionMap &get_functions() const { return functions; }