8 /*---------- constructors/initialisers ----------*/
10 void trackloc_set_maxinto(TrackLocation *tloc, Segment *seg, int backwards) {
12 tloc->backwards= backwards;
16 int trackloc_set_exactinto(TrackLocation *t, TrackAdvanceContext *c,
17 Segment *seg, int backwards, int into) {
18 const SegPosCombInfo *pci;
22 t->backwards= backwards;
25 r= trackloc_getlink(t,c,&pci,0,-1);
29 t->remain= pci->dist - into;
33 /*---------- enquirers ----------*/
35 int trackloc_getlink(TrackLocation *t, TrackAdvanceContext *c,
36 const SegPosCombInfo **pci_r,
37 const SegmentLinkInfo **link_r,
39 const SegPosCombInfo *pci;
43 mpc= t->seg->movposcomb;
45 if (c && c->getmovpos) {
46 r= c->getmovpos(t,c,&mpc);
51 if (link_r) *link_r=0;
55 assert(mpc < t->seg->i->n_poscombs);
56 //fprintf(stderr,"trackloc_getlink returning %s %d %d\n",t->seg->i->pname,mpc,
58 pci= &t->seg->i->poscombs[mpc];
59 //fprintf(stderr,"trackloc_getlink returning %s\n",pci->pname);
60 if (pci_r) *pci_r= pci;
61 if (link_r) *link_r= &pci->link[t->backwards];
65 /*---------- mutator ----------*/
67 static int nextseg(TrackLocation *t, TrackAdvanceContext *c,
68 const SegPosCombInfo **pci_r,
69 const SegmentLinkInfo **link_r,
70 const TrackLocation *leaving) {
74 mpc_nego= t->seg->movposcomb;
77 r= c->nextseg(t,c, &mpc_nego, leaving);
81 r= trackloc_getlink(t,c, pci_r,link_r, mpc_nego);
85 int trackloc_advance(TrackLocation *t, TrackAdvanceContext *c) {
88 const SegPosCombInfo *pci;
89 const SegmentLinkInfo *link;
90 TrackLocation leaving;
93 r= nextseg(t,c, &pci,&link, 0);
96 //fprintf(stderr,"advance start getlink %s%s/%s -> %s\n",
97 // t->backwards?"-":"", t->seg->i->pname,
98 // pci ? pci->pname : "?",
99 // link && SOMEP(link->next) ? info_segments[link->next].pname : "?");
102 if (!c->distance) return 0;
105 int use= t->remain < c->distance ? t->remain : c->distance;
113 if (!SOMEP(nextnum)) {
114 if (c->trackend) return c->trackend(t,c);
117 next= &segments[nextnum];
122 t->backwards ^= link->next_backwards;
125 r= nextseg(t,c, &pci,&link, &leaving);
126 if (r) { *t= leaving; return r; }
128 //fprintf(stderr,"advance ran getlink %s/%s -> %s\n",leaving->i->pname,
129 // pci ? pci->pname : "?",
130 // link && SOMEP(link->next) ? info_segments[link->next].pname : "?");
132 t->remain= pci->dist;
136 Segment *segment_interferer(Segment *base) {
137 SegmentNum intern= base->i->interferes;
138 if (!SOMEP(intern)) return 0;
139 return &segments[intern];
142 static ErrorCode interfering_movposcomb(TrackAdvanceContext *c, Segment *seg,
147 mpc= seg->movposcomb;
148 if (c && c->getmovpos) {
154 r= c->getmovpos(&t,c,&mpc);
158 *does_r= !SOMEP(mpc) || seg->i->interferes_movposcomb_map & (1u << mpc);
162 ErrorCode segment_interferer_does(TrackAdvanceContext *c, Segment *base,
163 Segment *inter, int *does_r) {
167 if (!inter) goto doesnt;
169 ec= interfering_movposcomb(c,base, &does); if (ec) return ec;
170 if (!does) goto doesnt;
172 assert(base->i == &info_segments[inter->i->interferes]);
173 ec= interfering_movposcomb(c,inter, &does); if (ec) return ec;
174 if (!does) goto doesnt;
184 Segment *segment_interferes_simple(TrackAdvanceContext *c, Segment *base) {
185 Segment *inter= segment_interferer(base);
186 if (!inter) return 0;
189 ErrorCode ec= segment_interferer_does(c,base,inter,&does);
192 return does ? inter : 0;
195 int trackloc_reverse_exact(TrackLocation *t, TrackAdvanceContext *c) {
196 const SegPosCombInfo *pci;
199 r= trackloc_getlink(t,c,&pci,0,-1);
202 t->remain= pci->dist - t->remain;