turnout_addr(start.get_turnout_address()),
conflict(false),
sensor(0),
- train(0),
- pending_train(0),
- emitting_reserve(false)
+ train(0)
{
add_track(start);
bool Block::reserve(Train *t)
{
- if(!t || !(emitting_reserve ? pending_train : train))
+ if(!t || !train)
{
- pending_train = t;
- if(!emitting_reserve)
- {
- while(pending_train!=train)
- {
- train = pending_train;
- SetFlag setf(emitting_reserve);
- signal_reserved.emit(train);
- }
- }
-
+ train = t;
+ signal_reserved.emit(t);
return true;
}
else
#include <algorithm>
#include <msp/core/maputils.h>
+#include <msp/core/raii.h>
#include <msp/core/refptr.h>
#include <msp/datafile/parser.h>
#include <msp/datafile/writer.h>
Layout::Layout(Catalogue &c, Driver *d):
catalogue(c),
driver(d),
- next_turnout_addr(0x800)
+ next_turnout_addr(0x800),
+ emitting_block_reserved(false)
{
clock.set_rate(60);
}
{
if(track_chains.insert(b))
{
- sigc::connection conn = b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b)));
+ sigc::connection conn = b.signal_reserved.connect(sigc::bind<0>(sigc::mem_fun(this, &Layout::block_reserved), sigc::ref(b)));
try
{
signal_track_chain_added.emit(b);
}
}
+void Layout::block_reserved(Block &block, Train *train)
+{
+ if(emitting_block_reserved)
+ block_reserve_queue.push_back(BlockReservation(block, train));
+ else
+ {
+ SetFlag setf(emitting_block_reserved);
+ signal_block_reserved.emit(block, train);
+ while(!block_reserve_queue.empty())
+ {
+ BlockReservation br = block_reserve_queue.front();
+ block_reserve_queue.pop_front();
+ signal_block_reserved.emit(br.block, br.train);
+ }
+ }
+}
+
template<typename B>
Layout::Storage<B>::~Storage()
}
+Layout::BlockReservation::BlockReservation(Block &b, Train *t):
+ block(b),
+ train(t)
+{ }
+
+
Layout::Loader::Loader(Layout &l):
DataFile::ObjectLoader<Layout>(l)
{
#ifndef LIBR2C2_LAYOUT_H_
#define LIBR2C2_LAYOUT_H_
+#include <deque>
#include <set>
#include <sigc++/sigc++.h>
#include <msp/datafile/objectloader.h>
void del();
};
+ struct BlockReservation
+ {
+ Block █
+ Train *train;
+
+ BlockReservation(Block &, Train *);
+ };
+
public:
typedef std::vector<Zone *> ZoneArray;
std::map<unsigned, Train *> trains;
Msp::Time::TimeStamp last_tick;
unsigned next_turnout_addr;
+ bool emitting_block_reserved;
+ std::deque<BlockReservation> block_reserve_queue;
public:
Layout(Catalogue &, Driver * = 0);
void save_dynamic(const std::string &) const;
private:
void sensor_state_changed(Sensor &, Sensor::State);
+ void block_reserved(Block &, Train *);
};
} // namespace R2C2