]> git.tdb.fi Git - r2c2.git/blobdiff - source/libmarklin/train.cpp
Generate IDs for new turnouts
[r2c2.git] / source / libmarklin / train.cpp
index acf8aa51486de42adb8901b98f9c78f2d0b79ac0..f0a0bf32dcf502c4e6728ed79812a40b90ef5906 100644 (file)
@@ -288,15 +288,32 @@ void Train::place(Block &block, unsigned entry)
                const Block::Endpoint &bep = block.get_endpoints()[exit];
                Track *track = bep.track->get_link(bep.track_ep);
                unsigned ep = track->get_endpoint_by_link(*bep.track);
-               vehicles.front()->place(track, ep, 0, Vehicle::FRONT_BUFFER);
+               vehicles.front()->place(*track, ep, 0, Vehicle::FRONT_BUFFER);
        }
        else
        {
                const Block::Endpoint &bep = block.get_endpoints()[entry];
-               vehicles.back()->place(bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER);
+               vehicles.back()->place(*bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER);
        }
 }
 
+void Train::unplace()
+{
+       if(controller->get_speed())
+               throw InvalidState("Must be stopped before unplacing");
+
+       release_blocks(rsv_blocks);
+       release_blocks(cur_blocks);
+
+       set_active(false);
+       accurate_position = false;
+
+       for(vector<Vehicle *>::iterator i=vehicles.begin(); i!=vehicles.end(); ++i)
+               (*i)->unplace();
+
+       set_status("Unplaced");
+}
+
 bool Train::free_block(Block &block)
 {
        float margin = 10*layout.get_catalogue().get_scale();
@@ -547,10 +564,10 @@ void Train::sensor_event(unsigned addr, bool state)
                                        {
                                                Track *track = bep.track->get_link(bep.track_ep);
                                                unsigned ep = track->get_endpoint_by_link(*bep.track);
-                                               vehicles.back()->place(track, ep, 0, Vehicle::BACK_AXLE);
+                                               vehicles.back()->place(*track, ep, 0, Vehicle::BACK_AXLE);
                                        }
                                        else
-                                               vehicles.front()->place(bep.track, bep.track_ep, 0, Vehicle::FRONT_AXLE);
+                                               vehicles.front()->place(*bep.track, bep.track_ep, 0, Vehicle::FRONT_AXLE);
                                }
                        }
                        last_entry_time = Time::now();
@@ -585,9 +602,14 @@ void Train::sensor_event(unsigned addr, bool state)
        }
        else
        {
+               const Vehicle &veh = *(reverse ? vehicles.front() : vehicles.back());
+
                // Find the first sensor in our current blocks that's still active
                list<BlockRef>::iterator end = cur_blocks.begin();
                for(list<BlockRef>::iterator i=cur_blocks.begin(); i!=cur_blocks.end(); ++i)
+               {
+                       if(i->block->get_tracks().count(veh.get_track()))
+                               break;
                        if(i->block->get_sensor_id())
                        {
                                if(layout.get_driver().get_sensor(i->block->get_sensor_id()))
@@ -598,6 +620,7 @@ void Train::sensor_event(unsigned addr, bool state)
                                        ++end;
                                }
                        }
+               }
                
                if(end!=cur_blocks.begin() && end!=cur_blocks.end())
                        // Free blocks up to the last inactive sensor
@@ -629,7 +652,7 @@ void Train::halt_event(bool h)
 
 void Train::block_reserved(const Block &block, const Train *train)
 {
-       if(&block==pending_block && !train)
+       if(&block==pending_block && !train && !reserving)
                reserve_more();
 }
 
@@ -891,9 +914,17 @@ float Train::get_reserved_distance_until(const Block *until_block, bool back) co
                return 0;
 
        list<BlockRef>::const_iterator block = cur_blocks.begin();
-       while(block!=cur_blocks.end() && !block->block->get_tracks().count(track))
+       while(block!=rsv_blocks.end() && !block->block->get_tracks().count(track))
+       {
                ++block;
-       if(block==cur_blocks.end() || block->block==until_block)
+               if(block==cur_blocks.end())
+               {
+                       if(back)
+                               return 0;
+                       block = rsv_blocks.begin();
+               }
+       }
+       if(block==rsv_blocks.end() || block->block==until_block)
                return 0;
 
        unsigned entry = veh.get_entry();
@@ -979,9 +1010,11 @@ unsigned Train::find_speed(float real) const
 
        unsigned low = 0;
        unsigned high = 0;
+       unsigned last = 0;
        for(unsigned i=0; (!high && i<=14); ++i)
                if(real_speed[i].weight)
                {
+                       last = i;
                        if(real_speed[i].speed<real)
                                low = i;
                        else
@@ -996,7 +1029,7 @@ unsigned Train::find_speed(float real) const
                        else
                                return 0;
                }
-               return min(static_cast<unsigned>(low*real/real_speed[low].speed), 14U);
+               return min(min(static_cast<unsigned>(low*real/real_speed[low].speed), 14U), last+3);
        }
 
        float f = (real-real_speed[low].speed)/(real_speed[high].speed-real_speed[low].speed);
@@ -1091,7 +1124,7 @@ void Train::Loader::finish()
        {
                const BlockRef &blkref = obj.cur_blocks.front();
                const Block::Endpoint &bep = blkref.block->get_endpoints()[blkref.entry];
-               obj.vehicles.back()->place(bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER);
+               obj.vehicles.back()->place(*bep.track, bep.track_ep, 0, Vehicle::BACK_BUFFER);
 
                obj.set_status("Stopped");
        }