}
static void lay_train(ErrorCode *ec, TrainNum tran,
- TrackLocation tloc, long distance,
- unsigned detect_now, unsigned detect_future,
- unsigned here_now, unsigned here_future,
- unsigned clash_if_updated) {
+ TrackLocation tloc, long advance,
+ unsigned detect, unsigned clash_if_updated) {
SegmentState *seg;
+ long overall, remain;
if (*ec) return;
+ remain= overall= advance + tra->speed * SPEED_CLEAR_MULT;
+
for (;;) {
seg= s->segs[tloc.segn];
if (clash_if_updated && seg->tr_updated) {
*ec= safety_problem(tloc.segn, tran, tran, "collision with itself");
return;
}
- if (seg->here_future) {
+ if (seg->owned) {
if (seg->owner != tran) {
*ec= safety_problem(tloc.segn, tran, seg->owner, "collision");
return;
}
seg_clear_stale(seg);
}
- seg->tran= tran;
+ seg->owned= 1;
+ seg->owner_backwards= tloc.backwards;
seg->tr_updated= 1;
- seg->tr_here_now |= here_now;
- seg->tr_here_future |= here_future;
- seg->tr_detect_now |= detect_now;
- seg->tr_detect_future |= detect_future;
+ seg->tran= tran;
- if (!distance) break;
-
- trackloc_further(&tloc, &distance);
+ dist_until= (overall - remain) - advance;
+ time_until= (SPEED_FACTOR * dist_until) / tra->speed;
+ *(detect ? &seg->until_detect : &seg->until_here)= time_until;
+
+ if (!remain) break;
+ trackloc_further(&tloc, &remain);
}
}
tloc.into= JUSTARRIVED_DIST;
head= tra->backwards ? trai->tail : trai->head;
- future= tra->speed * SPEED_CLEAR_MULT;
+ lay_train(tran, &ec, tloc, head, 0,1);
ec= 0;
- lay_train(tran, &ec, tloc, head + future, 0,0,0,1);
- lay_train(tran, &ec, tloc, head, 0,0,1,1);
- lay_train(tran, &ec, tloc, future, 0,1,0,1);
- lay_train(tran, &ec, tloc, 0, 1,1,1,1);
+ lay_train(&ec, tran, tloc, head, 0,1);
+ lay_train(&ec, tran, tloc, 0, 1,0);
lay_train_done(tran);
-
if (ec) return ec;
-
-
- (
-
- );
- lay_train(tloc,
- tra->backwards ? trai->tail : trai->head,
-
-
- remain=
- mark segment as being owned by train but not detectable;
-
- for (
- remain
- while (remain) {
- trackloc_further
+
segi= &safety_segis[segn];
typedef unsigned short TrainNum;
typedef unsigned short SegmentNum;
typedef unsigned short LocationNum;
+typedef short TimeInterval;
typedef short Distance;
typedef char Speed; /* non-negative, units of 4mm/s */
typedef struct {
unsigned
- tr_detect_now:1, tr_detect_future:1, /* owning train draws current */
- tr_here_now:1, tr_here_future:1, /* owning train is or will use space */
- tr_backwards:1, /* train's motion is (would be) backwards wrt track */
+ owned:1, /* this track segment is reserved for a train */
+ owner_backwards:1, /* train's motion is (would be) backwards wrt track */
pt_sideways:1, /* points are set to `alternative'. (no points?: 0) */
- tr_autostop:1, /* owning train is slow and wants to stop on detection */
+ autostop:1, /* owning train is slow and wants to stop on detection */
tr_updated:1; /* for use by safety_train_changed etc.; otherwise 0 */
+ TimeInterval until_here, /* ) nonnegative; */ /* ) always valid but */
+ until_detect; /* ) 0 if already */ /* ) only meaningful */
+ TrainNum owner; /* ) iff owned */
/*polarity?*/
- TrainNum tran; /* always valid but only meaningful iff tr_here_future */
} SegmentState;
typedef struct {