protocol(p),
preceding_train(0),
cur_blocks_end(blocks.end()),
- clear_blocks_end(blocks.end()),
pending_block(0),
reserving(false),
advancing(false),
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(pending_block, false)-margin, 0.0f);
}
void Train::tick(const Time::TimeStamp &t, const Time::TimeDelta &dt)
void Train::turnout_path_changed(Track &track)
{
for(list<BlockIter>::iterator i=blocks.begin(); i!=blocks.end(); ++i)
- if((*i)->get_turnout_id()==track.get_turnout_id() && !reserving)
- {
- if(&**i==pending_block)
- reserve_more();
- else
- check_turnout_paths(false);
- }
+ if((*i)->get_turnout_id()==track.get_turnout_id() && !reserving && &**i==pending_block)
+ reserve_more();
}
void Train::halt_event(bool h)
BlockIter start = blocks.back();
if(&*start==stop_at_block)
return;
+ else if(&*start==pending_block)
+ {
+ TrackIter track = start.track_iter();
+ if(!(track.endpoint().paths&(1<<track->get_active_path())))
+ return;
+ }
pending_block = 0;
preceding_train = 0;
if(cur_blocks_end==blocks.end())
--cur_blocks_end;
- if(clear_blocks_end==blocks.end())
- --clear_blocks_end;
TrackIter track = block.track_iter();
if(track->is_path_changing())
pending_block = &*block;
break;
}
+ else
+ {
+ const TrackType::Endpoint &entry_ep = track.endpoint();
+ unsigned path = track->get_active_path();
+ if(!(entry_ep.paths&(1<<path)))
+ {
+ const TrackType::Endpoint &exit_ep = track.reverse().endpoint();
+ if(unsigned mask = entry_ep.paths&exit_ep.paths)
+ {
+ for(path=0; mask>1; ++path, mask>>=1) ;
+
+ track->set_active_path(path);
+ if(track->is_path_changing())
+ {
+ pending_block = &*block;
+ break;
+ }
+ }
+ else
+ // XXX Do something here
+ break;
+ }
+ }
if(&*block==stop_at_block)
break;
dist += block->get_path_length(block.entry());
}
- check_turnout_paths(true);
-
// Make any sensorless blocks at the beginning immediately current
- while(cur_blocks_end!=clear_blocks_end && !(*cur_blocks_end)->get_sensor_id())
+ while(cur_blocks_end!=blocks.end() && !(*cur_blocks_end)->get_sensor_id())
++cur_blocks_end;
}
-void Train::check_turnout_paths(bool set)
-{
- if(clear_blocks_end==blocks.end())
- return;
-
- for(list<BlockIter>::iterator i=clear_blocks_end; i!=blocks.end(); ++i)
- {
- if((*i)->get_turnout_id())
- {
- TrackIter track = i->track_iter();
- const TrackType::Endpoint &track_ep = track.endpoint();
-
- unsigned path = 0;
- list<BlockIter>::iterator j = i;
- if(++j!=blocks.end())
- {
- TrackIter rev = j->track_iter().flip();
- unsigned mask = rev.endpoint().paths&track_ep.paths;
- for(path=0; mask>1; mask>>=1, ++path) ;
- }
- else
- return;
-
- if(path!=track->get_active_path())
- {
- if(set && !track->is_path_changing())
- {
- track->set_active_path(path);
- if(track->is_path_changing())
- continue;
- }
- else
- continue;
- }
- }
-
- if(i==clear_blocks_end)
- ++clear_blocks_end;
- if(i==cur_blocks_end && !(*i)->get_sensor_id())
- ++cur_blocks_end;
- }
-}
-
float Train::get_reserved_distance_until(const Block *until_block, bool back) const
{
if(blocks.empty())
return 0;
BlockList::const_iterator block = blocks.begin();
- while(block!=clear_blocks_end && !(*block)->has_track(*track))
+ while(block!=blocks.end() && !(*block)->has_track(*track))
++block;
- if(block==clear_blocks_end || &**block==until_block)
+ if(block==blocks.end() || &**block==until_block)
return 0;
float result = veh.get_offset();
else
{
++block;
- if(block==clear_blocks_end)
+ if(block==blocks.end())
break;
}
{
if(begin==cur_blocks_end)
cur_blocks_end = end;
- if(begin==clear_blocks_end)
- clear_blocks_end = end;
Block &block = **begin;
blocks.erase(begin++);