--- /dev/null
+#include "beamgate.h"
+#include "catalogue.h"
+#include "layout.h"
+
+using namespace std;
+using namespace Msp;
+
+namespace R2C2 {
+
+BeamGate::BeamGate(Layout &l):
+ TrackAttachment(l),
+ Sensor(l)
+{
+ invert = true;
+
+ layout.add(*this);
+}
+
+BeamGate::~BeamGate()
+{
+ layout.remove(*this);
+}
+
+BeamGate *BeamGate::clone(Layout *to_layout) const
+{
+ BeamGate *gate = new BeamGate(to_layout ? *to_layout : layout);
+ gate->set_position(position);
+ gate->set_rotation(rotation);
+ return gate;
+}
+
+const BeamGateType &BeamGate::get_type() const
+{
+ return BeamGateType::instance();
+}
+
+void BeamGate::set_address(unsigned a)
+{
+ address = a;
+}
+
+void BeamGate::set_position(const Vector &p)
+{
+ position = p;
+ update_attachment();
+ signal_moved.emit();
+}
+
+void BeamGate::set_rotation(const Angle &r)
+{
+ rotation = r;
+ update_attachment();
+ signal_moved.emit();
+}
+
+void BeamGate::update_attachment()
+{
+ attach_to_closest(100*layout.get_catalogue().get_gauge());
+
+ if(track)
+ {
+ TrackPoint tp = track->get_point(track.entry(), offset);
+ position = tp.pos;
+ rotation = tp.dir;
+ }
+}
+
+Block *BeamGate::get_block() const
+{
+ if(track)
+ return &track->get_block();
+ else
+ return 0;
+}
+
+void BeamGate::save(list<DataFile::Statement> &st) const
+{
+ st.push_back((DataFile::Statement("position"), position.x, position.y, position.z));
+ st.push_back((DataFile::Statement("rotation"), rotation.radians()));
+ if(address)
+ st.push_back((DataFile::Statement("address"), address));
+}
+
+
+BeamGate::Loader::Loader(BeamGate &g):
+ DataFile::ObjectLoader<BeamGate>(g)
+{
+ add("address", &Loader::address);
+ add("position", &Loader::position);
+ add("rotation", &Loader::rotation);
+}
+
+void BeamGate::Loader::address(unsigned a)
+{
+ obj.set_address(a);
+}
+
+void BeamGate::Loader::position(float x, float y, float z)
+{
+ obj.set_position(Vector(x, y, z));
+}
+
+void BeamGate::Loader::rotation(float r)
+{
+ obj.set_rotation(Angle::from_radians(r));
+}
+
+} // namespace R2C2