* A Allocated memory allocation done
* R Reserved reservation was successful
* C Confirmed motion queued and will occur
+ * D Done motion is complete and callback just needs to be made
* E Erroneous indep must call destroy straight away
+ * seg->moving is in one of the states UCD
*/
typedef struct MovPosChange { /* valid in: filled in by and when: */
- const KindInfo *ki; /* ARCE indep after allocate() */
- Segment *move; /* ARCE indep after allocate() */
- MovPosCallback *on_done; /* C indep before confirm() */
- void *u; /* C indep before confirm() */
- MovPosComb actual; /* C see below */
+ const KindInfo *ki; /* ARCDE indep after allocate() */
+ Segment *move; /* ARCDE indep after allocate() */
+ MovPosCallback *on_done; /* CD indep before confirm() */
+ void *u; /* CD indep before confirm() */
+ MovPosComb actual; /* CD see below */
/* kind-specific data follows */ /* varies kind-specific code, varies */
} Change;
/* `actual' contains the kind's record of the physical state. It is
* Allocated Allocated yes
* Reserved Reserved yes
* Confirmed Confirmed yes
+ * Done Allocated yes
* Erroneous A/R/C no
*
* Erroneous exists only after a failed reserve() or confirm() so it's
* CDU and point queue states:
*
*
- * ____________ pt_cdu_ conf'd conf'd pt_
- * / points_ \ charged .n .l[0]-> motion
- * | all_ | n_motions timeout
+ * ____________ pt_cdu_ conf'd
+ * / points_ \ charged .n
+ * | all_ |
* | abaondon |
* | V
- * |from INACTIVE -1 0 n/a Idle
+ * |from INACTIVE -1 0
* |any <=Sta_Settling
* ^^^^^^^^ (start)
* |
- * ____________ |turning
- * / \| _on
+ * ___________ |turning
+ * / \| _on
* | V
- * | CHARGING 0 any any or n/a Idle
+ * | CHARGING 0 any
* | >=Sta_Resolving
- * | _________ |
- * | / \|
- * | | |on_pic
- * | | |_charged
- * | | V
- * ^ ^ READY 1 any any or n/a Idle
- * | | |
- * | | |pt_check_action
- * | ^ |fires a point
- * |\___________/|
- * | more |last motion
- * | ^ motions |
- * | | |
- * | | V
- * | | MOVING 0 >0 0 Running
- * | \_________/|
* | |
- * \____________/
- * motion_done
+ * | |on_pic
+ * | |_charged
+ * | V
+ * ^ READY 1 any
+ * | |
+ * | |pt_check_action
+ * | | fires a point
+ * \___________/
+ *
*/
static PtSlot pt_cslot;
static int pt_cdu_charged;
static PointQueue pt_confirmed, pt_reserved;
-static TimeoutEvent pt_motion_timeout;
static pt_maxdelay_reldeadline(int maxdelay_ms) {
return (maxdelay_ms - POINT_MOVEMENT + CDU_RECHARGE) / CDU_RECHARGE;
* So we try removing the existing request from the queue and put
* it back if it doesn't work.
*/
-
+
assert(n_motions <= r->n_motions);
newdeadline= pt_reldeadline(maxdelay_ms) + cslot;
allow_failure= newdeadline < r->deadline;
* or ec!=0 state A C
* or ec!=0 state C but bad C
*/
-
+
if (!ec) pt_check_action();
return ec;
static void pt_check_action(void) {
PicInsn piob;
-
- if (!pt_confirmed.n) {
- toev_stop(&pt_motion_timeout);
- return;
- }
- PointReq *r= pt_confirmed.l[0];
+ if (!pt_confirmed.n) return;
- if (r->n_motions) {
- if (!pt_cdu_charged) {
-
+ PointReq *r= pt_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]);
r->actual= above*above_weight + m->posn*m->i->weight + below;
}
- if (!r->n_motions)
- toev_start(&pt_motion_timeout);
-}
-
-static void pt_motion_done(TimeoutEvent *toev) {
- assert(pt_confirmed.n);
- PointReq *r= pt_confirmed.l[0];
- assert(!r->n_motions);
- Segment *move= r->h.move;
- assert(move->moving == r);
- move->movposcomb= r->actual;
- move->moving= 0;
- pt_queue_remove_index(&pt_confirmed,0);
- r->h.on_done(move, r->h.u);
- free(r);
-
- pt_check_action();
+ if (!r->n_motions) {
+ /* look for something to report
+ * we can get things here other than from the above
+ * eg if we are asked to move the
+ */
+ Segment *move= r->h.move;
+ assert(move->moving == r);
+ pt_queue_remove_index(&pt_confirmed,0);
+ pt_mark_as_allocated(r); /* now state A aka Done */
+ movpos_done((Change*)r);
+ pt_check_action();
+ }
}
/*---------- entrypoints from rest of program ----------*/
0
};
+static void movpos_done(Change *chg) {
+ Segment *move= chg->move;
+ events_
+ move->movposcomb= r->actual;
+ move->moving= 0;
+ r->h.on_done(move, r->h.u);
+ free(r);
+}
+
ChangeHeader *mp_allocate(const KindInfo *ki, Segment *move,
int alloc_motions) {
assert(sta_state >= Sta_Resolving);