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);
}
indep->actual= startpoint;
indep->target= target;
indep->n_changes= n_meths;
+ indep->refcount= 0;
memset(indep->changes, 0, sizeof(Change*) * n_meths);
}
DPRINTF2("\n");
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);