From: ian Date: Sun, 11 May 2008 10:29:19 +0000 (+0000) Subject: split points into mfq and points core, so we can have relays X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=87f515403730fa618238aeff043298426599c39b;p=trains.git split points into mfq and points core, so we can have relays --- diff --git a/hostside/README.commands b/hostside/README.commands index b10c1b5..f249a82 100644 --- a/hostside/README.commands +++ b/hostside/README.commands @@ -53,7 +53,7 @@ POSSIBLY-ASYNCHRONOUS REPORTING OF MESSAGES TO/FROM (MASTER) PIC ! for foredetect @ for det_ignore - U< movpos point + U< movpos feat point|relay U< movpos position moving U< movpos position stable may be ? for unknown diff --git a/hostside/movpos.c b/hostside/movpos.c index a81abd0..efac841 100644 --- a/hostside/movpos.c +++ b/hostside/movpos.c @@ -11,7 +11,7 @@ typedef struct { 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 @@ -30,7 +30,7 @@ typedef struct KindInfo KindInfo; */ 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() */ @@ -49,13 +49,16 @@ typedef struct MovPosChange { /* valid in: filled in by and when: */ * 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 @@ -82,7 +85,7 @@ static void motion_done(Segment *move, MovPosComb actual) { 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 @@ -95,13 +98,14 @@ static void motion_done(Segment *move, MovPosComb actual) { * 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). @@ -121,25 +125,25 @@ typedef int PtSlotSigned; 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 @@ -153,89 +157,73 @@ typedef struct { /* Allocated Reserved Confirmed */ * 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; } @@ -244,29 +232,29 @@ static void pt_mark_as_allocated(PointReq *r) { /* AX->X */ 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,"~"); @@ -292,65 +280,65 @@ static ErrorCode pt_check_plan(void) { #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 @@ -364,26 +352,27 @@ static ErrorCode point_confirm(Change *chg, Segment *move, 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 */ @@ -391,7 +380,7 @@ static ErrorCode point_confirm(Change *chg, Segment *move, 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; @@ -400,15 +389,15 @@ static ErrorCode point_confirm(Change *chg, Segment *move, 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 */ @@ -425,44 +414,44 @@ static ErrorCode point_confirm(Change *chg, Segment *move, 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); @@ -475,86 +464,145 @@ static void pt_check_action(void) { */ 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; if.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; @@ -566,7 +614,7 @@ static int change_needed(const MovFeatInfo *feati, 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; @@ -601,7 +649,7 @@ static int evaluate_target(Segment *move, MovPosComb target, 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; } @@ -653,7 +701,7 @@ ErrorCode movpos_change(Segment *move, MovPosComb target, actual= move->movposcomb; assert(!move->motion); } else { - kind= move->motion->ki - methodinfos; + kind= move->motion->meth->kind; actual= move->motion->actual; } @@ -661,7 +709,7 @@ ErrorCode movpos_change(Segment *move, MovPosComb target, 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[] */ @@ -684,21 +732,21 @@ ErrorCode movpos_change(Segment *move, MovPosComb target, 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; } @@ -723,11 +771,11 @@ movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange **res_r, 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; @@ -742,9 +790,9 @@ movpos_reserve(Segment *move, int maxdelay_ms, MovPosChange **res_r, 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) { @@ -754,3 +802,9 @@ 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); +} diff --git a/hostside/realtime.h b/hostside/realtime.h index 7bb1540..3a573d2 100644 --- a/hostside/realtime.h +++ b/hostside/realtime.h @@ -185,7 +185,7 @@ int picinsn_polarity_testbit(const PicInsn *pi, const SegmentInfo *segi); /*---------- from movpos.c ----------*/ void points_turning_on(void); -void points_all_abandon(void); +void motions_all_abandon(void); /*---------- from eventhelp.c ----------*/ diff --git a/hostside/startup.c b/hostside/startup.c index 6b457dd..0fdcfcb 100644 --- a/hostside/startup.c +++ b/hostside/startup.c @@ -77,7 +77,7 @@ static void sta_goto(StartupState new_state) { if (new_state < Sta_Run) choreographers_all_abandon(); if (new_state < Sta_Finalising) - points_all_abandon(); + motions_all_abandon(); piob.l= 0; switch (new_state) { diff --git a/layout/layout-data.h b/layout/layout-data.h index c45ab8a..03b8772 100644 --- a/layout/layout-data.h +++ b/layout/layout-data.h @@ -28,7 +28,7 @@ typedef enum { mfk_none, mfk_point, mfk_relay - /* must also add new entries to movpos.c:methodinfos */ + /* must also add new entries to movpos.c:methods[] */ } MovFeatKind; /*========== data from config files and layout cad/cam ==========*/