Small posn;
} Motion;
-typedef struct KindInfo KindInfo;
+typedef struct Method Method;
/* Kind-independent code is responsible for determining
* the method, doing a bit of cleanup, and adjusting the flow
*/
typedef struct MovPosChange { /* valid in: filled in by and when: */
- const KindInfo **ki; /* ARCDE indep after allocate() */
+ Method *meth; /* ARCDE indep after allocate() */
Segment *move; /* ARCDE indep after allocate() */
MovPosComb actual; /* CD see below */
MovPosComb intent; /* RCD indep after allocate() */
* the indep code never untangles it so the kind can manage the
* proper transition. */
-struct KindInfo {
+struct Method {
const char *pname;
- Change *(*allocate)(int alloc_motions); /* U->A (always succeeds) */
- ErrorCode (*reserve)(Change*, Segment*, int ms); /* A->R; error: A->E */
- ErrorCode (*confirm)(Change*, Segment*, int n_motions,
- const Motion*, int ms); /* [AR]->C; error; [AR]->E */
- void (*destroy)(Change*); /* [ARCE]->U */
+ MovFeatKind kind;
+ Change *(*allocate)(Method *m, int alloc_motions); /* U->A (never err) */
+ ErrorCode (*reserve)(Method *m, Change*, Segment*, /* A->R */
+ int ms); /* error: A->E */
+ ErrorCode (*confirm)(Method *m, Change*, Segment*, /* [AR]->C */
+ int n_motions, const Motion*, int ms); /* err:[AR]->E */
+ void (*destroy)(Method *m, Change*); /* [ARCE]->U */
+ void (*all_abandon)(Method *m);
/* indep guarantees that
* alloc_motions >= move->i->n_motions on reserve
* alloc_motions >= n_motions on confirm
move->i->pname, posnpname(move, move->movposcomb));
}
-/*========== points ==========*/
+/*========== points and other fixed timeslot movfeats ==========*/
/*
* We maintain two queues, one for reserved one for actually confirmed
* currently next in after
* changing line that
*
- * We increment cslot when we issue a POINT command to the PIC.
+ * We increment cslot when we consider the movfeat to move;
+ * for points and relays this is when we issue the command to the PIC.
* In a request, the deadline represents the latest allowable value
* of cslot just before that increment.
*/
-typedef unsigned PtSlot;
-typedef int PtSlotSigned;
+typedef unsigned FsqSlot;
+typedef int FsqSlotSigned;
/* We think there are three states: Allocated, Reserved and Confirmed.
* (plus of course Unallocated where we don't have a request at all).
typedef struct { /* Allocated Reserved Confirmed */
/* in queue? absent reserved confirmed */
Change h;
- PtSlot deadline; /* ~0 relative absolute <- */
+ FsqSlot deadline; /* ~0 relative absolute <- */
MovPosComb actual; /* undef undef see below */
int n_motions; /* alloc'd alloc'd undone */
Motion motions[]; /* [0].i: 0 0 non-0 <- */
/* [..].i: undef undef non-0 */
/* .posn: undef undef defined */
-} PointReq;
+} FsqReq;
/* We can determine the the state by looking at the two
* `statedet' fields, marked <- above.
* There are also intermediate states where the req's
* statedet fields do not agree with the queue it's on.
* We write these as, for example,
- * AR to mean statedet says Allocated, but queued on pt_reserved
+ * AR to mean statedet says Allocated, but queued on fsq_reserved
* A? to mean statedet says Allocated, but may be queued
- * etc. They are only allowed while we are in a pt_... method function.
+ * etc. They are only allowed while we are in a fsq_... method function.
*/
- /* PointReq.actual is subtly differnet to MovPosChange.actual,
+ /* FsqReq.actual is subtly differnet to MovPosChange.actual,
* as follows:
- * in MovPosChange in PointReq
+ * in MovPosChange in FsqReq
* Position unknown -1 0
* Position partly known -1 unknown feats are 0
* Position completely known exact exact
* we lose the partial knowledge.
*/
-#define CDU_RECHARGE 250 /*ms*/
-#define POINT_MOVEMENT 50 /*ms*/
-#define PT_MAX_QUEUE 15
+#define FSQ_MAX_QUEUE 15
typedef struct {
int n;
- PointReq *l[PT_MAX_QUEUE];
-} PointQueue;
+ FsqReq *l[FSQ_MAX_QUEUE];
+} FsqQueue;
-/*
- * CDU and point queue states:
- *
- *
- * ____________ pt_cdu_ conf'd
- * / points_ \ charged .n
- * | all_ |
- * | abaondon |
- * | V
- * |from INACTIVE -1 0
- * |any <=Sta_Settling
- * ^^^^^^^^ (start)
- * |
- * ___________ |turning
- * / \| _on
- * | V
- * | CHARGING 0 any
- * | >=Sta_Resolving
- * | |
- * | |on_pic
- * | |_charged
- * | V
- * ^ READY 1 any
- * | |
- * | |pt_check_action
- * | | fires a point
- * \___________/
- *
- */
+typedef struct FsqMethod FsqMethod;
-static PtSlot pt_cslot;
-static int pt_cdu_charged;
-static PointQueue pt_confirmed, pt_reserved;
+typedef struct {
+ /* set by fsq's client before fsq_init */
+ int slot_ms, lag_ms;
+ void (*move)(FsqMethod *m, const MovFeatInfo *mfi, int movfeatposn);
+ /* shared */
+ int ready; /* >0 means ready; set to 0 by fsq just before move */
+ /* fsq's client must arrange that these start out at all-bits-zero */
+ FsqSlot cslot;
+ FsqQueue confirmed, reserved;
+} FsqState;
+
+struct FsqMethod {
+ Method m;
+ FsqState f;
+ /* client may put things here */
+};
-static void pt_check_action(void);
-static ErrorCode pt_check_plan(void);
+static void fsq_check_action(FsqMethod *m);
+static ErrorCode fsq_check_plan(FsqMethod *m);
-static PtSlotSigned pt_maxdelay_reldeadline(int maxdelay_ms, int n_motions) {
- if (maxdelay_ms==-1) return PT_MAX_QUEUE*16;
- return (maxdelay_ms - POINT_MOVEMENT) / CDU_RECHARGE - n_motions;
+static FsqSlotSigned fsq_maxdelay_reldeadline(FsqMethod *m,
+ int maxdelay_ms, int n_motions) {
+ if (maxdelay_ms==-1) return FSQ_MAX_QUEUE*16;
+ return (maxdelay_ms - m->f.lag_ms) / m->f.slot_ms - n_motions;
}
-static void pt_queue_remove_index(PointQueue *q, int index) {
+static void fsq_queue_remove_index(FsqQueue *q, int index) {
q->n--;
memmove(&q->l[index], &q->l[index+1], sizeof(q->l[0]) * (q->n - index));
}
-static int pt_req_compar(const void *av, const void *bv) {
- PointReq *const *a= av;
- PointReq *const *b= av;
- return (PtSlotSigned)((*b)->deadline - (*a)->deadline);
+static int fsq_req_compar(const void *av, const void *bv) {
+ FsqReq *const *a= av;
+ FsqReq *const *b= av;
+ return (FsqSlotSigned)((*b)->deadline - (*a)->deadline);
}
-static void pt_queue_remove_item(PointQueue *q, PointReq *r) {
- PointReq **entry;
- entry= bsearch(r, q->l, q->n, sizeof(q->l[0]), pt_req_compar);
+static void fsq_queue_remove_item(FsqQueue *q, FsqReq *r) {
+ FsqReq **entry;
+ entry= bsearch(r, q->l, q->n, sizeof(q->l[0]), fsq_req_compar);
assert(entry);
- pt_queue_remove_index(q, entry - q->l);
+ fsq_queue_remove_index(q, entry - q->l);
}
-static void pt_dequeue(PointReq *r) { /* X->XA */
+static void fsq_dequeue(FsqMethod *m, FsqReq *r) { /* X->XA */
if (r->motions[0].i) {
- pt_queue_remove_item(&pt_confirmed, r);
+ fsq_queue_remove_item(&m->f.confirmed, r);
} else if (~r->deadline) {
- pt_queue_remove_item(&pt_reserved, r);
+ fsq_queue_remove_item(&m->f.reserved, r);
} else {
return;
}
- pt_check_plan();
+ fsq_check_plan(m);
}
-static void pt_mark_as_allocated(PointReq *r) { /* AX->X */
+static void fsq_mark_as_allocated(FsqReq *r) { /* AX->X */
/* Sets statedet fields for Allocated */
- r->deadline= ~(PtSlot)0;
+ r->deadline= ~(FsqSlot)0;
r->motions[0].i=0;
}
whichwhen= wh##when, \
wh++)
-static ErrorCode pt_check_plan(void) {
+static ErrorCode fsq_check_plan(FsqMethod *m) {
/* Checks whether we can meet the currently queued commitments */
int future, conf, resv, whichwhen;
- PointReq *whichr;
+ FsqReq *whichr;
conf=resv=0;
future=0;
- oprintf(DUPO("movpos/point") " plan");
+ oprintf(DUPO("movpos/fsq") "%s plan", m->m.pname);
/* If CDU is charged we can't do one right away */
- if (!pt_cdu_charged) {
+ if (m->f.ready<0) {
oprintf(UPO, " +");
future++;
}
for (;;) {
- PointReq *confr= conf < pt_confirmed.n ? pt_confirmed.l[conf] : 0;
- PointReq *resvr= resv < pt_reserved .n ? pt_reserved .l[resv] : 0;
+ FsqReq *confr= conf < m->f.confirmed.n ? m->f.confirmed.l[conf] : 0;
+ FsqReq *resvr= resv < m->f.reserved .n ? m->f.reserved .l[resv] : 0;
if (!confr && !resvr) break;
oprintf(UPO," %d:",future);
- int confwhen= confr ? confr->deadline - pt_cslot : INT_MAX;
- int resvwhen= resvr ? resvr->deadline : INT_MAX;
+ int confwhen= confr ? confr->deadline - m->f.cslot : INT_MAX;
+ int resvwhen= resvr ? resvr->deadline : INT_MAX;
if (future && resvwhen < confwhen) {
WHICH(resv);
oprintf(UPO,"~");
#undef WHICH
-static ErrorCode pt_enqueue(PointQueue *q, PointReq *r) { /* XA -> X */
+static ErrorCode fsq_enqueue(FsqMethod *m, FsqQueue *q, /* XA -> X */
+ FsqReq *r) { /* or on error, XA -> A */
int insat; /* ... where X is R or C and corresponds to q */
- /* or on error, XA -> A */
- if (q->n == PT_MAX_QUEUE) {
+ if (q->n == FSQ_MAX_QUEUE)
return EC_BufferFull;
- }
for (insat= q->n;
- insat>0 && (PtSlotSigned)(r->deadline - q->l[insat-1]->deadline) < 0;
+ insat>0 && (FsqSlotSigned)(r->deadline - q->l[insat-1]->deadline) < 0;
insat--)
q->l[insat]= q->l[insat-1];
q->l[insat]= r;
q->n++;
- return pt_check_plan();
- /* if this fails, indep machinery calls pt_destroy which dequeues */
+ return fsq_check_plan(m);
+ /* if this fails, indep machinery calls fsq_destroy which dequeues */
}
-/*---------- kind method entrypoints ----------*/
+/*---------- method entrypoints ----------*/
-static Change *point_allocate(int alloc_motions) {
- PointReq *r;
+static Change *fsq_allocate(Method *mm, int alloc_motions) {
+ FsqReq *r;
- assert(pt_cdu_charged>=0);
if (!alloc_motions)
/* we need at least one motion in the table so we can tell
* the difference between the states by looking at motions[0].i */
alloc_motions= 1;
r= mmalloc(sizeof(*r) + alloc_motions * sizeof(r->motions[0]));
- r->deadline= ~(PtSlot)0;
+ r->deadline= ~(FsqSlot)0;
r->n_motions= alloc_motions;
r->motions[0].i= 0;
return (Change*)r;
}
-static ErrorCode point_reserve(Change *chg, Segment *move,
- int maxdelay_ms) {
- PointReq *r= (PointReq*)chg;
- PtSlotSigned reldeadline;
+static ErrorCode fsq_reserve(Method *mm, Change *chg,
+ Segment *move, int maxdelay_ms) {
+ FsqMethod *m= (void*)mm;
+ FsqReq *r= (FsqReq*)chg;
+ FsqSlotSigned reldeadline;
- reldeadline= pt_maxdelay_reldeadline(maxdelay_ms, r->n_motions);
- if (reldeadline <= 0) { pt_mark_as_allocated(r); return EC_MovFeatTooLate; }
+ reldeadline= fsq_maxdelay_reldeadline(m, maxdelay_ms, r->n_motions);
+ if (reldeadline <= 0) { fsq_mark_as_allocated(r); return EC_MovFeatTooLate; }
r->deadline= reldeadline;
- return pt_enqueue(&pt_reserved, r);
+ return fsq_enqueue(m, &m->f.reserved, r);
}
-static ErrorCode point_confirm(Change *chg, Segment *move,
- int n_motions, const Motion *motions,
- int maxdelay_ms) {
- PointReq *r= (PointReq*)chg;
- PtSlotSigned reldeadline;
+static ErrorCode fsq_confirm(Method *mm, Change *chg, Segment *move,
+ int n_motions, const Motion *motions,
+ int maxdelay_ms) {
+ FsqMethod *m= (void*)mm;
+ FsqReq *r= (FsqReq*)chg;
+ FsqSlotSigned reldeadline;
int allow_failure;
ErrorCode ec;
- oprintf(DUPO("movpos/point") "confirm %s n=%d maxdelay=%dms"
+ oprintf(DUPO("movpos/fsq") "%s confirm %s n=%d maxdelay=%dms"
" (res: [%d@t+%d])\n",
- move->i->pname, n_motions, maxdelay_ms,
+ m->m.pname, move->i->pname, n_motions, maxdelay_ms,
r->n_motions, r->deadline);
/* If the segment is moving, these motions are already based on the
assert(n_motions <= r->n_motions);
if (maxdelay_ms == -1) {
reldeadline= r->deadline;
- if (!~r->deadline) reldeadline= pt_maxdelay_reldeadline(-1, n_motions);
+ if (!~r->deadline) reldeadline= fsq_maxdelay_reldeadline(m, -1, n_motions);
} else {
- reldeadline= pt_maxdelay_reldeadline(maxdelay_ms, n_motions);
+ reldeadline= fsq_maxdelay_reldeadline(m, maxdelay_ms, n_motions);
}
- allow_failure= reldeadline < (PtSlotSigned)r->deadline;
- oprintf(DUPO("movpos/point") " reldeadline=[%d@t+%d] allow_failure=%d\n",
- n_motions, reldeadline, allow_failure);
+ allow_failure= reldeadline < (FsqSlotSigned)r->deadline;
+ oprintf(DUPO("movpos/fsq") "%s reldeadline=[%d@t+%d] allow_failure=%d\n",
+ m->m.pname, n_motions, reldeadline, allow_failure);
/* state A or R */
- pt_dequeue(r);
+ fsq_dequeue(m, r);
/* states of existing: */
- PointReq *existing=
- move->moving ? (PointReq*)move->motion : 0; /* U or C */
+ FsqReq *existing=
+ move->moving ? (FsqReq*)move->motion : 0; /* U or C */
if (existing) {
- oprintf(DUPO("movpos/point")
- " existing %s n=%d deadline=t+%d\n",
+ oprintf(DUPO("movpos/fsq")
+ "%s existing %s n=%d deadline=t+%d\n",
+ m->m.pname,
existing->h.move->i->pname,
existing->n_motions,
- existing->deadline - pt_cslot);
- pt_dequeue(existing); /* U or CA */
+ existing->deadline - m->f.cslot);
+ fsq_dequeue(m, existing); /* U or CA */
}
/* state A or RA */
if (!n_motions) r->motions[0].i= move->i->movfeats;
assert(r->motions[0].i);
r->n_motions= n_motions;
- r->deadline= reldeadline + pt_cslot;
+ r->deadline= reldeadline + m->f.cslot;
if (n_motions == move->i->n_movfeats)
r->actual= 0;
assert(r->actual >= 0);
/* state CA */
- ec= pt_enqueue(&pt_confirmed, r);
- oprintf(DUPO("movpos/point") " pt_enqueue=%s\n", ec2str(ec));
+ ec= fsq_enqueue(m, &m->f.confirmed, r);
+ oprintf(DUPO("movpos/fsq") "%s pt_enqueue=%s\n", m->m.pname, ec2str(ec));
assert(allow_failure || !ec);
if (existing) { /* CA */
if (ec) { /* state C but bad */
- pt_dequeue(r); /* state CA */
- pt_mark_as_allocated(r); /* state A */
- ErrorCode ec_putback= pt_enqueue(&pt_confirmed, existing);
+ fsq_dequeue(m,r); /* state CA */
+ fsq_mark_as_allocated(r); /* state A */
+ ErrorCode ec_putback= fsq_enqueue(m,&m->f.confirmed, existing);
assert(!ec_putback); /* C */
} else { /* state C and good */
free(existing); /* U */
move->motion= chg;
move->movposcomb= -1;
ouposn_moving(chg);
- pt_check_action();
+ fsq_check_action(m);
return 0;
}
-static void point_destroy(Change *chg) { /* X->XA and then free it */
- PointReq *r= (PointReq*)chg;
- pt_dequeue(r);
+static void fsq_destroy(Method *mm, Change *chg) { /* X->XA and then freed */
+ FsqMethod *m= (void*)mm;
+ FsqReq *r= (FsqReq*)chg;
+ fsq_dequeue(m,r);
free(r);
}
-/*---------- actually firing points, yay! ----------*/
+/*---------- something to do ? ----------*/
-static void pt_check_action(void) {
- PicInsn piob;
+static void fsq_check_action(FsqMethod *m) {
+ /* client should call this after it sets ready */
ErrorCode ec;
- if (!pt_confirmed.n) {
+ if (!m->f.confirmed.n) {
if (sta_state == Sta_Finalising) resolve_motioncheck();
return;
}
- PointReq *r= pt_confirmed.l[0];
+ FsqReq *r= m->f.confirmed.l[0];
- if (r->n_motions && pt_cdu_charged) {
- /* look for something to fire */
- Motion *m= &r->motions[--r->n_motions];
- assert(m->posn < m->i->posns);
- enco_pic_point(&piob, m->i->boob[m->posn]);
- serial_transmit(&piob);
- oprintf(UPO, "movpos %s point %s%d\n", r->h.move->i->pname,
- m->i->pname, m->posn);
- pt_cdu_charged= 0;
- pt_cslot++;
+ if (r->n_motions && m->f.ready>0) {
+ /* look for something to move */
+ Motion *mo= &r->motions[--r->n_motions];
+ assert(mo->posn < mo->i->posns);
+ m->f.ready= 0;
+ m->f.move(m, mo->i, mo->posn);
+ oprintf(UPO, "movpos %s feat %s%d %s\n", r->h.move->i->pname,
+ mo->i->pname, mo->posn, m->m.pname);
+ m->f.cslot++;
- MovPosComb above_weight= m->i->weight * m->i->posns;
+ MovPosComb above_weight= mo->i->weight * mo->i->posns;
MovPosComb above= r->actual / above_weight;
- MovPosComb below= r->actual % m->i->weight;
- r->actual= above*above_weight + m->posn*m->i->weight + below;
+ MovPosComb below= r->actual % mo->i->weight;
+ r->actual= above*above_weight + mo->posn*mo->i->weight + below;
if (r->h.actual >= 0 || !r->n_motions)
r->h.actual= r->actual;
ouposn_moving(&r->h);
*/
Segment *move= r->h.move;
assert(move->moving && move->motion == (Change*)r);
- pt_queue_remove_index(&pt_confirmed,0);
- pt_mark_as_allocated(r); /* now state A aka Done */
+ fsq_queue_remove_index(&m->f.confirmed,0);
+ fsq_mark_as_allocated(r); /* now state A aka Done */
motion_done(move,r->h.actual);
free(r);
- ec= pt_check_plan(); assert(!ec);
- pt_check_action();
+ ec= fsq_check_plan(m); assert(!ec);
+ fsq_check_action(m);
}
}
/*---------- entrypoints from rest of program ----------*/
-void points_all_abandon(void) {
+static void fsq_all_abandon(Method *mm) {
+ FsqMethod *m= (void*)mm;
int i;
- assert(!pt_reserved.n);
+ assert(!m->f.reserved.n);
- for (i=0; i<pt_confirmed.n; i++) {
- PointReq *r= pt_confirmed.l[i];
+ for (i=0; i<m->f.confirmed.n; i++) {
+ FsqReq *r= m->f.confirmed.l[i];
Segment *move= r->h.move;
assert(move->motion == (Change*)r);
motion_done(move,r->h.actual);
free(r);
}
- pt_confirmed.n= 0;
- pt_cdu_charged= -1;
+ m->f.confirmed.n= 0;
}
-void points_turning_on(void) {
- pt_cdu_charged= 0;
+/*========== points ==========*/
+
+/*
+ * CDU and point queue states:
+ *
+ *
+ * ____________ conf'd
+ * / points_ \ ready .n
+ * | all_ |
+ * | abandon |
+ * | V
+ * |from INACTIVE -1 0
+ * |any <=Sta_Settling
+ * ^^^^^^^^ (start)
+ * |
+ * ___________ |turning
+ * / \| _on
+ * | V
+ * | CHARGING 0 any
+ * | >=Sta_Resolving
+ * | |
+ * | |on_pic
+ * | |_charged
+ * | V
+ * ^ READY 1 any
+ * | |
+ * | |fsq_check_action
+ * | | calls point_move which fires a point
+ * \___________/
+ *
+ */
+
+#define CDU_RECHARGE 250 /*ms*/
+#define POINT_MOVEMENT 50 /*ms*/
+
+static Change *point_allocate(Method *mm, int alloc_motions) {
+ FsqMethod *m= (void*)mm;
+ assert(m->f.ready>=0);
+ return fsq_allocate(mm, alloc_motions);
+}
+
+static void point_move(FsqMethod *m, const MovFeatInfo *mfi, int posn) {
+ /* actually firing points, yay! */
+ PicInsn piob;
+ enco_pic_point(&piob, mfi->boob[posn]);
+ serial_transmit(&piob);
}
+static void points_all_abandon(Method *mm) {
+ FsqMethod *m= (void*)mm;
+ m->f.ready= -1;
+ fsq_all_abandon(mm);
+}
+
+static FsqMethod points_method;
+
+void points_turning_on(void) {
+ FsqMethod *m= &points_method;
+ m->f.ready= 0;
+}
void on_pic_charged(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
- if (pt_cdu_charged<0) return;
- pt_cdu_charged= 1;
- pt_check_action();
+ FsqMethod *m= &points_method;
+ if (m->f.ready<0) return;
+ m->f.ready= 1;
+ fsq_check_action(m);
}
-static const KindInfo point_method= {
- "point", point_allocate, point_reserve, point_confirm, point_destroy
+static FsqMethod points_method= {
+ { "point", mfk_point,
+ point_allocate, fsq_reserve, fsq_confirm,
+ fsq_destroy, points_all_abandon },
+ { .lag_ms= POINT_MOVEMENT, .slot_ms= CDU_RECHARGE, .move= point_move }
};
/*========== dummy `nomove' kind ==========*/
-static Change *nomove_allocate(int alloc_motions) {
+static Change *nomove_allocate(Method *m, int alloc_motions) {
oprintf(DUPO("movfeatkind-momove") "allocate %d\n",alloc_motions);
return mmalloc(sizeof(Change));
}
-static void nomove_destroy(Change *chg) {
- free(chg);
-}
-
-static ErrorCode nomove_reserve(Change *chg, Segment *move, int ms) {
+static ErrorCode nomove_reserve(Method *m, Change *c, Segment *move, int ms) {
oprintf(DUPO("movfeatkind-nomove") "reserve\n");
return 0;
}
-static ErrorCode nomove_confirm(Change *chg, Segment *move, int n_motions,
+static void nomove_destroy(Method *m, Change *c) { free(c); }
+static ErrorCode nomove_confirm(Method *m, Change *c, Segment *move, int n,
const Motion *motions, int ms) {
oprintf(DUPO("movfeatkind-nomove") "confirm\n");
- nomove_destroy(chg);
+ nomove_destroy(m,c);
return 0;
}
+static void nomove_all_abandon(Method *m) { }
-static const KindInfo nomove_method= {
- "nomove", nomove_allocate, nomove_reserve, nomove_confirm, nomove_destroy
+static Method nomove_method= {
+ "nomove", mfk_none, nomove_allocate, nomove_reserve, nomove_confirm,
+ nomove_destroy, nomove_all_abandon
};
/*========== method-independent machinery ==========*/
-static const KindInfo *methodinfos[]= {
+static Method *methods[]= {
&nomove_method,
- &point_method,
- 0,
+ (Method*)&points_method,
+ 0, /* relay */
0
};
-static Change *mp_allocate(const KindInfo **ki, Segment *move,
+static Change *mp_allocate(Method *meth, Segment *move,
int alloc_motions, MovPosComb target) {
assert(sta_state >= Sta_Resolving);
- Change *chg= (*ki)->allocate(alloc_motions);
- chg->ki= ki;
+ Change *chg= meth->allocate(meth, alloc_motions);
+ chg->meth= meth;
chg->move= move;
chg->intent= target;
return chg;
r= startpoint<0 ||
(target - startpoint) / feati->weight % feati->posns;
oprintf(DUPO("movpos/change-needed") "%s:%s(%d*%d) %d..%d => %d\n",
- methodinfos[feati->kind]->pname, feati->pname,
+ methods[feati->kind]->pname, feati->pname,
feati->posns, feati->weight,
startpoint, target, r);
return r;
if (kind_r) *kind_r= kind;
oprintf(DUPO("movpos/eval") "changes=%d kind=%s\n",
- tchanges, methodinfos[kind]->pname);
+ tchanges, methods[kind]->pname);
return tchanges;
}
actual= move->movposcomb;
assert(!move->motion);
} else {
- kind= move->motion->ki - methodinfos;
+ kind= move->motion->meth->kind;
actual= move->motion->actual;
}
move->i->pname, posnpname(move,target),
maxdelay_ms, posnpname(move, actual));
if (chg) oprintf(DUPO("movpos/change") " chg=%s:%s/%s\n",
- (*chg->ki)->pname, chg->move->i->pname,
+ chg->meth->pname, chg->move->i->pname,
posnpname(chg->move, chg->intent));
{ /* provide horizon for visibility of motions[] */
n_motions++;
}
- const KindInfo **ki= &methodinfos[kind];
+ Method *meth= methods[kind];
if (chg) {
- if (chg->ki != ki ||
+ if (chg->meth != meth ||
chg->move != move ||
chg->intent != target)
return EC_MovFeatReservationInapplicable;
} else {
- chg= mp_allocate(ki,move,n_motions,target);
+ chg= mp_allocate(meth,move,n_motions,target);
}
chg->actual= actual;
oprintf(DUPO("movpos/change") "confirm %s:%d...\n",
- (*ki)->pname, n_motions);
- ec= (*ki)->confirm(chg, move, n_motions, motions, maxdelay_ms);
+ meth->pname, n_motions);
+ ec= meth->confirm(meth, chg, move, n_motions, motions, maxdelay_ms);
oprintf(DUPO("movpos/change") "confirm => %s\n",errorcodelist[ec]);
if (ec) goto x;
}
nchanges= evaluate_target(move,target,startpoint,&kind);
if (nchanges==-1) return EC_MovFeatKindsCombination;
- const KindInfo **ki= &methodinfos[kind];
+ Method *meth= methods[kind];
oprintf(DUPO("movpos/reserve") "allocate %s:%d...\n",
- (*ki)->pname, nchanges);
- Change *chg= mp_allocate(ki, move, nchanges, target);
- ec= (*ki)->reserve(chg, move, maxdelay_ms);
+ meth->pname, nchanges);
+ Change *chg= mp_allocate(meth, move, nchanges, target);
+ ec= meth->reserve(meth, chg, move, maxdelay_ms);
oprintf(DUPO("movpos/reserve") "reserve => %s\n",errorcodelist[ec]);
if (ec) goto x;
void movpos_unreserve(MovPosChange *res) {
if (!res) return;
oprintf(DUPO("movpos/unreserve") "%s:%s/%s\n",
- (*res->ki)->pname, res->move->i->pname,
+ res->meth->pname, res->move->i->pname,
posnpname(res->move, res->intent));
- (*res->ki)->destroy(res);
+ res->meth->destroy(res->meth, res);
}
MovPosComb movpos_poscomb_actual(Segment *seg) {
MovPosComb movpos_change_intent(MovPosChange *chg) {
return chg->intent;
}
+
+void motions_all_abandon(void) {
+ Method **meth;
+ for (meth=methods; *meth; meth++)
+ (*meth)->all_abandon(*meth);
+}