Segment *move;
/* everything beyond here is private for indep */
MovPosComb actual, target;
+ int refcount;
int n_changes;
Change *changes[];
} Indep;
* has been done. The method-independent code will take care of
* updating move->movposcomb. etc.
*
- * REENTRANCY: must NOT be called from within a call to the method's
- * execute() (and of course cannot legally be called from within
- * prepare, consider, check or dispose).
+ * REENTRANCY: May be called from within a call to the method's
+ * execute(). Of course cannot legally be called from within
+ * prepare, consider, check or dispose.
*/
ouprintf("movpos %s position %s moving\n",
move->i->pname, movpos_pname(move, indep->actual));
}
+static void ouposn_stable(const Segment *move) {
+ ouprintf("movpos %s position %s stable\n",
+ move->i->pname, movpos_pname(move, move->movposcomb));
+}
+static void ouposn_feat(const Segment *move, const MovFeatInfo *feati,
+ MovPosComb posn, const Method *m) {
+ ouprintf("movpos %s feat %s %d %s\n", move->i->pname,
+ feati->pname, posn, m->pname);
+}
MovPosComb movposcomb_update_feature(MovPosComb startpoint,
const MovFeatInfo *mfi,
typedef struct {
Method m;
- unsigned eventqueued:1;
NomoveChange *queuehead; /* contains confirmations only */
} NomoveMethod;
static ErrorCode nomove_check(Method *mm) { return 0; }
-static void *nomove_execute_now(oop_source *source, struct timeval tv,
- void *meth_v) {
- NomoveMethod *meth= meth_v;
- meth->eventqueued= 0;
+static void nomove_execute(Method *mm) {
+ NomoveMethod *meth= (void*)mm;
NomoveChange *done;
while ((done= meth->queuehead)) {
DLIST1_REMOVE(meth->queuehead, done, inqueue);
nomove_dispose(&meth->m, &done->h);
}
- return OOP_CONTINUE;
-}
-
-static void nomove_execute(Method *mm) {
- NomoveMethod *meth= (void*)mm;
- if (!meth->eventqueued) {
- meth->eventqueued= 1;
- events->on_time(events, OOP_TIME_NOW, nomove_execute_now, meth);
- }
}
static Method nomove_method= {
#define METH_DPFX_FMT "%s " INDEP_DBG_FMT " "
#define METH_DPFX_ARGS(indep, meth) ((meth).pname), INDEP_DBG_ARGS((indep))
+static void indep_indep_done(Indep *indep);
+
static Method *methods[]= {
[mfk_none] = (Method*)&nomove_method,
[mfk_point] = (Method*)&points_method,
[mfk_relay] = (Method*)&waggle,
+ 0
};
/*---------- entrypoints from methods ----------*/
static void method_update_feature(Method *m, MovPosChange *indep,
const Motion *mo) {
- ouprintf("movpos %s feat %s %d %s\n", indep->move->i->pname,
- mo->i->pname, mo->posn, m->pname);
+ ouposn_feat(indep->move, mo->i, mo->posn, m);
if (SOMEP(indep->actual))
indep->actual=
movposcomb_update_feature(indep->actual, mo->i, mo->posn);
return;
}
+ if (!indep->refcount)
+ indep_indep_done(indep);
+}
+
+static void indep_indep_done(Indep *indep) {
/* all done */
Segment *move= indep->move;
move->moving= 0;
move->motion= 0;
move->movposcomb= indep->target;
- ouprintf("movpos %s position %s stable\n",
- move->i->pname, movpos_pname(move, move->movposcomb));
+ ouposn_stable(move);
free(indep);
}
MovPosComb startpoint, MovPosComb target) {
int r;
r= !SOMEP(startpoint) ||
- (target - startpoint) / feati->weight % feati->posns;
+ (target / feati->weight) % feati->posns -
+ (startpoint / feati->weight) % feati->posns;
if (DEBUGP(movpos,eval))
DPRINTFA(" { %s:%s(%d*%d) %d..%d => %d }",
feature_method(feati)->pname, feati->pname,
int changei;
for (changei=0; changei<indep->n_changes; changei++) {
Change *chg= indep->changes[changei];
+ if (!chg) continue;
+
Method *meth= chg->meth;
- if (chg) {
- DPRINTF(movpos,meth, METH_DPFX_FMT "dispose...\n",
- METH_DPFX_ARGS(indep,*meth));
- meth->dispose(meth, chg);
- }
+ DPRINTF(movpos,meth, METH_DPFX_FMT "dispose...\n",
+ METH_DPFX_ARGS(indep,*meth));
+ meth->dispose(meth, chg);
}
free(indep);
}
indep->actual= startpoint;
indep->target= target;
indep->n_changes= n_meths;
+ indep->refcount= 0;
memset(indep->changes, 0, sizeof(Change*) * n_meths);
}
DPRINTF2("\n");
if (cost_r) *cost_r= totalcost;
if (indep_r)
- DPRINTF(movpos,entry, INDEP_DPFX_FMT "prepare cost=%d ok\n",
+ DPRINTF(movpos,eval, INDEP_DPFX_FMT "prepare cost=%d ok\n",
INDEP_DPFX_ARGS(indep), totalcost);
else
- DPRINTF(movpos,entry, "movpos prepare %s/%s cost=%d ok\n",
+ DPRINTF(movpos,eval, "movpos prepare %s/%s cost=%d ok\n",
move->i->pname, movpos_pname(move,target), totalcost);
return 0;
DPRINTF(movpos,entry, "movpos reserve %s/%s ok\n",
move->i->pname, movpos_pname(move,target));
+ *res_r= indep;
return 0;
x:
int tcost, bestcost=INT_MAX;
const SegPosCombInfo *pci;
+ DPRINTF(movpos,eval, "movpos_findcomb_bysegs %s-%s-%s <-%s\n",
+ back ? back->i->pname : "*", move->i->pname,
+ fwd ? fwd ->i->pname : "*", movpos_pname(move, startpoint));
+
for (tcomb=0, pci=movei->poscombs;
tcomb<movei->n_poscombs;
tcomb++, pci++) {
+ /* these next assignments may generate segments[-1] but we don't
+ * care because that won't compare equal to back or fwd */
Segment *tback= &segments[pci->link[1].next];
Segment *tfwd= &segments[pci->link[0].next];
+
+ DPRINTF(movpos,intern, "movpos_findcomb_bysegs ... %s : %s-%s-%s\n",
+ movpos_pname(move, tcomb),
+ SOMEP(pci->link[1].next) ? tback->i->pname : "#",
+ move->i->pname,
+ SOMEP(pci->link[0].next) ? tfwd->i->pname : "#");
+
if (back && !(back==tback || back==tfwd)) continue;
if (fwd && !(fwd ==tback || fwd ==tfwd)) continue;
bestcomb= tcomb;
bestcost= tcost;
}
+ DPRINTF(movpos,entry, "movpos_findcomb_bysegs %s..%s..%s <-%s => %s/%s\n",
+ back ? back->i->pname : "-", move->i->pname,
+ fwd ? fwd ->i->pname : "-", movpos_pname(move, startpoint),
+ move->i->pname, movpos_pname(move,bestcomb));
+
if (chosen_r) *chosen_r= bestcomb;
return
bestcost==INT_MAX ? EC_MovFeatRouteNotFound :
indep_dispose(move->motion);
move->motion= inst;
+ move->moving= 1;
+
+ inst->refcount++; /* prevents method_change_done from destroying it */
ouposn_moving(inst);
indep_check_execute();
+ inst->refcount--;
+ if (!inst->n_changes)
+ /* oh! */
+ indep_indep_done(inst);
+
DPRINTF(movpos,entry, "movpos change %s/%s ok\n",
move->i->pname, movpos_pname(move, target));
return 0;
MovPosChange *abandon= seg->motion;
indep_remove(abandon);
- indep_dispose(abandon);
seg->movposcomb= abandon->actual;
seg->moving= 0;
+ seg->motion= 0;
+ indep_dispose(abandon);
}
for (meth=methods; *meth; meth++)
(*meth)->all_abandon(*meth);