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 static int interfering_movposcomb(TrackAdvanceContext *c, Segment *seg) {
140 mpc= seg->movposcomb;
141 if (c && c->getmovpos) {
147 r= c->getmovpos(&t,c,&mpc);
151 if (mpc < 0) return 1;
152 return seg->i->interferes_movposcomb_map & (1u << mpc);
155 Segment *segment_interferes(TrackAdvanceContext *c, Segment *base) {
159 intern= base->i->interferes;
161 if (!SOMEP(intern)) return 0;
162 if (!interfering_movposcomb(c,base)) return 0;
164 inter= &segments[intern];
166 assert(base->i == &info_segments[inter->i->interferes]);
167 if (!interfering_movposcomb(c,inter)) return 0;
172 int trackloc_reverse_exact(TrackLocation *t, TrackAdvanceContext *c) {
173 const SegPosCombInfo *pci;
176 r= trackloc_getlink(t,c,&pci,0,-1);
179 t->remain= pci->dist - t->remain;