this.windTo(where.phi);
350 | }
351 | } else if (where.isError) {
352 | if (this.state.err) {
353 | this.state.currentErrorStep = where;
354 | this.goTo(where.step);
355 | } else {
356 | nextTick(this.boundUnwind);
357 | }
358 | } else {
359 | if (where.fn) {
360 | where.fn();
361 | nextTick(this.boundUnwind);
362 | } else {
363 | this.beginCleanup(where.state);
364 | this.goTo(where.step);
365 | }
366 | }
367 | } else if (!this.state.isFinished) {
368 | this.state.waiting = 0;
369 | this.state.isFinished = true;
370 | this.finalCallback && this.finalCallback.apply(this.context, this.state.args);
371 | }
372 | };
373 |
374 | StateMachine.prototype.pushCleanupAction = function (context, fn, args) {
375 | var self = this;
376 | self.state.unwinding.push({
377 | cleanup: true,
378 | fn: function () {
379 | fn.apply(context, args);
380 | }
381 | });
382 | };
383 |
384 | StateMachine.prototype.pushCleanupStep = function (id, afterID) {
385 | this.state.unwinding.push({cleanup: true, step: id, state: this.captureStateVars()});
386 | this.goTo(afterID);
387 | };
388 |
389 | StateMachine.prototype.pushErrorStep = function (id, retryID) {
390 | this.state.unwinding.push({isError: true, step: id, retryStep: retryID, unwindPoint: this.state.unwinding.length});
391 | this.goTo(retryID);
392 | };
393 |
394 | StateMachine.prototype.beginCleanup = function (state) {
395 | this.state.unwinding.push({restoreState: this.captureStateVars()});
396 | this.restoreStateVars(state);
397 | };
398 |
399 |