Remove opportunistic freeing of blocks from behind the train and counting
of noncritical blocks from the simulated vehicle position. Both features
are now implemented in terms of what can be ascertained from sensors. I'm
developing infrared gates which will provide similar functionality with
actual physical (or simulated) feedback.
-void BlockAllocator::release_until(const Block &block)
-{
- for(BlockList::iterator i=blocks.begin(); i!=cur_blocks_end; ++i)
- if(i->block()==&block)
- {
- if(++i!=cur_blocks_end)
- release_blocks_begin(i);
- return;
- }
-}
-
bool BlockAllocator::release_from(const Block &block)
{
bool have_sensor = false;
bool BlockAllocator::release_from(const Block &block)
{
bool have_sensor = false;
private:
bool reserve_block(const BlockIter &);
public:
private:
bool reserve_block(const BlockIter &);
public:
- void release_until(const Block &);
bool release_from(const Block &);
void release_noncurrent();
private:
bool release_from(const Block &);
void release_noncurrent();
private:
bool Train::free_block(Block &block)
{
bool Train::free_block(Block &block)
{
- if(get_reserved_distance_until(&block, false)<controller->get_braking_distance()*1.3)
+ if(get_reserved_distance_until(&block)<controller->get_braking_distance()*1.3)
return false;
return allocator.release_from(block);
return false;
return allocator.release_from(block);
float margin = 10*layout.get_catalogue().get_scale();
float min_dist = controller->get_braking_distance()*1.3+margin;
float margin = 10*layout.get_catalogue().get_scale();
float min_dist = controller->get_braking_distance()*1.3+margin;
- Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front());
-
- TrackIter track = veh.get_track_iter();
- BlockIter block = allocator.first();
- const BlockIter &last_cur = allocator.last_current();
- const BlockIter &last = allocator.last();
- bool in_rsv = false;
- while(!block->has_track(*track))
- {
- if(&*block==&*last_cur)
- in_rsv = true;
- if(&*block==&*last)
- break;
- block = block.next();
- }
-
- float dist = veh.get_offset();
- if(reverse)
- track.reverse();
- else
- dist = track->get_type().get_path_length(track->get_active_path())-dist;
- dist -= veh.get_type().get_length()/2;
-
- bool nsens = 0;
- while(1)
+ BlockIter i = allocator.last_current().next();
+ float dist = 0;
+ bool sensor_seen = false;
+ for(; i->get_train()==this; i=i.next())
- track = track.next();
-
- if(!block->has_track(*track))
+ if(dist>min_dist && sensor_seen)
- if(&*block==&*last_cur)
- in_rsv = true;
- if(&*block==&*last)
- return;
- block = block.next();
-
- if(dist>min_dist && nsens>0)
- {
- allocator.release_from(*block);
- return;
- }
-
- if(in_rsv && block->get_sensor_id())
- ++nsens;
+ allocator.release_from(*i);
+ return;
- dist += track->get_type().get_path_length(track->get_active_path());
+ dist += i->get_path_length(i.entry());
+
+ if(i->get_sensor_id())
+ sensor_seen = true;
if(next && next->get_type().is_turnout())
margin = 15*layout.get_catalogue().get_scale();
if(next && next->get_type().is_turnout())
margin = 15*layout.get_catalogue().get_scale();
- return max(get_reserved_distance_until(0, false)-margin, 0.0f);
+ return max(get_reserved_distance_until(0)-margin, 0.0f);
}
void Train::reserve_more()
}
void Train::reserve_more()
-
- if(!allocator.empty() && !allocator.first()->get_sensor_id())
- {
- float dist = get_reserved_distance_until(&*allocator.first(), true);
-
- if(dist>10*layout.get_catalogue().get_scale())
- allocator.release_until(*allocator.first());
- }
}
void Train::save(list<DataFile::Statement> &st) const
}
void Train::save(list<DataFile::Statement> &st) const
accurate_position = false;
}
accurate_position = false;
}
-float Train::get_reserved_distance_until(const Block *until_block, bool back) const
+float Train::get_reserved_distance_until(const Block *until_block) const
{
if(allocator.empty())
return 0;
{
if(allocator.empty())
return 0;
- Vehicle &veh = *(reverse!=back ? vehicles.back() : vehicles.front());
- const VehicleType &vtype = veh.get_type();
+ Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front());
TrackIter track = veh.get_track_iter();
if(!track) // XXX Probably unnecessary
return 0;
TrackIter track = veh.get_track_iter();
if(!track) // XXX Probably unnecessary
return 0;
- const BlockIter &first = allocator.first();
- const BlockIter &last = allocator.last();
- BlockIter block = first;
- while(!block->has_track(*track))
- {
- if(&*block==&*last)
- return 0;
- block = block.next();
- }
+ BlockIter block = track.block_iter();
if(&*block==until_block)
return 0;
if(&*block==until_block)
return 0;
- if(back)
- block = block.reverse();
-
+ // Account for the vehicle's offset on its current track
float result = veh.get_offset();
float result = veh.get_offset();
track = track.reverse();
else
result = track->get_type().get_path_length(track->get_active_path())-result;
track = track.reverse();
else
result = track->get_type().get_path_length(track->get_active_path())-result;
- result -= vtype.get_length()/2;
+ result -= veh.get_type().get_length()/2;
- while(1)
- {
- track = track.next();
- if(!track)
- break;
+ // Count remaining distance in the vehicle's current block
+ for(track=track.next(); &track->get_block()==&*block; track=track.next())
+ result += track->get_type().get_path_length(track->get_active_path());
- if(!block->has_track(*track))
- {
- if(back)
- {
- if(&*block==&*first)
- break;
- }
- else
- {
- if(&*block==&*last)
- break;
- }
- block = block.next();
+ const BlockIter &last = allocator.last();
+ if(&*block==&*last)
+ return result;
- if(&*block==until_block)
- break;
- }
+ // Count any remaining blocks
+ for(block=block.next(); (&*block!=until_block && block->get_train()==this); block=block.next())
+ {
+ result += block->get_path_length(block.entry());
- result += track->get_type().get_path_length(track->get_active_path());
+ if(&*block==&*last)
+ break;
void block_state_changed(Block &, Block::State);
void halt_event(bool);
void block_reserved(const Block &, const Train *);
void block_state_changed(Block &, Block::State);
void halt_event(bool);
void block_reserved(const Block &, const Train *);
- float get_reserved_distance_until(const Block *, bool) const;
+ float get_reserved_distance_until(const Block *) const;