use of com.ichi2.libanki.sched.Counts.Queue in project AnkiChinaAndroid by ankichinateam.
the class Sched method _answerLrnCard.
/**
* @param ease 1=no, 2=yes, 3=remove
*/
@Override
protected void _answerLrnCard(@NonNull Card card, @Consts.BUTTON_TYPE int ease) {
JSONObject conf = _lrnConf(card);
@Consts.CARD_TYPE int type;
if (card.getODid() != 0 && !card.getWasNew()) {
type = Consts.CARD_TYPE_RELEARNING;
} else if (card.getType() == Consts.CARD_TYPE_REV) {
type = Consts.CARD_TYPE_REV;
} else {
type = Consts.CARD_TYPE_NEW;
}
boolean leaving = false;
// lrnCount was decremented once when card was fetched
int lastLeft = card.getLeft();
// immediate graduate?
if (ease == Consts.BUTTON_THREE) {
_rescheduleAsRev(card, conf, true);
leaving = true;
// graduation time?
} else if (ease == Consts.BUTTON_TWO && (card.getLeft() % 1000) - 1 <= 0) {
_rescheduleAsRev(card, conf, false);
leaving = true;
} else {
// one step towards graduation
if (ease == Consts.BUTTON_TWO) {
// decrement real left count and recalculate left today
int left = (card.getLeft() % 1000) - 1;
card.setLeft(_leftToday(conf.getJSONArray("delays"), left) * 1000 + left);
// failed
} else {
card.setLeft(_startingLeft(card));
boolean resched = _resched(card);
if (conf.has("mult") && resched) {
// review that's lapsed
card.setIvl(Math.max(Math.max(1, (int) (card.getIvl() * conf.getDouble("mult"))), conf.getInt("minInt")));
} else {
// new card; no ivl adjustment
// pass
}
if (resched && card.getODid() != 0) {
card.setODue(mToday + 1);
}
}
int delay = _delayForGrade(conf, card.getLeft());
if (card.getDue() < getTime().intTime()) {
// not collapsed; add some randomness
delay *= Utils.randomFloatInRange(1f, 1.25f);
}
card.setDue(getTime().intTime() + delay);
// due today?
if (card.getDue() < mDayCutoff) {
mLrnCount += card.getLeft() / 1000;
// if the queue is not empty and there's nothing else to do, make
// sure we don't put it at the head of the queue and end up showing
// it twice in a row
card.setQueue(Consts.QUEUE_TYPE_LRN);
if (!mLrnQueue.isEmpty() && revCount() == 0 && newCount() == 0) {
long smallestDue = mLrnQueue.getFirstDue();
card.setDue(Math.max(card.getDue(), smallestDue + 1));
}
_sortIntoLrn(card.getDue(), card.getId());
} else {
// the card is due in one or more days, so we need to use the day learn queue
long ahead = ((card.getDue() - mDayCutoff) / SECONDS_PER_DAY) + 1;
card.setDue(mToday + ahead);
card.setQueue(Consts.QUEUE_TYPE_DAY_LEARN_RELEARN);
}
}
_logLrn(card, ease, conf, leaving, type, lastLeft);
}
use of com.ichi2.libanki.sched.Counts.Queue in project AnkiChinaAndroid by ankichinateam.
the class Sched method _rescheduleLapse.
@Override
protected int _rescheduleLapse(@NonNull Card card) {
JSONObject conf;
conf = _lapseConf(card);
card.setLastIvl(card.getIvl());
if (_resched(card)) {
card.setLapses(card.getLapses() + 1);
card.setIvl(_nextLapseIvl(card, conf));
card.setFactor(Math.max(1300, card.getFactor() - 200));
card.setDue(mToday + card.getIvl());
// if it's a filtered deck, update odue as well
if (card.getODid() != 0) {
card.setODue(card.getDue());
}
}
// if suspended as a leech, nothing to do
int delay = 0;
if (_checkLeech(card, conf) && card.getQueue() == Consts.QUEUE_TYPE_SUSPENDED) {
return delay;
}
// if no relearning steps, nothing to do
if (conf.getJSONArray("delays").length() == 0) {
return delay;
}
// record rev due date for later
if (card.getODue() == 0) {
card.setODue(card.getDue());
}
delay = _delayForGrade(conf, 0);
card.setDue(delay + getTime().intTime());
card.setLeft(_startingLeft(card));
// queue 1
if (card.getDue() < mDayCutoff) {
mLrnCount += card.getLeft() / 1000;
card.setQueue(Consts.QUEUE_TYPE_LRN);
_sortIntoLrn(card.getDue(), card.getId());
} else {
// day learn queue
long ahead = ((card.getDue() - mDayCutoff) / SECONDS_PER_DAY) + 1;
card.setDue(mToday + ahead);
card.setQueue(Consts.QUEUE_TYPE_DAY_LEARN_RELEARN);
}
return delay;
}
use of com.ichi2.libanki.sched.Counts.Queue in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method undoReview.
@Override
public void undoReview(@NonNull Card oldCardData, boolean wasLeech) {
// remove leech tag if it didn't have it before
if (!wasLeech && oldCardData.note().hasTag("leech")) {
oldCardData.note().delTag("leech");
oldCardData.note().flush();
}
Timber.i("Undo Review of card %d, leech: %b", oldCardData.getId(), wasLeech);
// write old data
oldCardData.flush(false);
DeckConfig conf = _cardConf(oldCardData);
boolean previewing = conf.getInt("dyn") != 0 && !conf.getBoolean("resched");
if (!previewing) {
// and delete revlog entry
long last = mCol.getDb().queryLongScalar("SELECT id FROM revlog WHERE cid = ? ORDER BY id DESC LIMIT 1", oldCardData.getId());
mCol.getDb().execute("DELETE FROM revlog WHERE id = " + last);
}
// restore any siblings
mCol.getDb().execute("update cards set queue=type,mod=?,usn=? where queue=" + Consts.QUEUE_TYPE_SIBLING_BURIED + " and nid=?", getTime().intTime(), mCol.usn(), oldCardData.getNid());
// and finally, update daily count
@Consts.CARD_QUEUE int n = oldCardData.getQueue() == Consts.QUEUE_TYPE_DAY_LEARN_RELEARN ? Consts.QUEUE_TYPE_LRN : oldCardData.getQueue();
String type = (new String[] { "new", "lrn", "rev" })[n];
_updateStats(oldCardData, type, -1);
decrReps();
}
use of com.ichi2.libanki.sched.Counts.Queue in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method setCurrentCard.
/**
* This imitate the action of the method answerCard, except that it does not change the state of any card.
*
* It means in particular that: + it removes the siblings of card from all queues + change the next card if required
* it also set variables, so that when querying the next card, the current card can be taken into account.
*/
public void setCurrentCard(@NonNull Card card) {
mCurrentCard = card;
long did = card.getDid();
List<Deck> parents = mCol.getDecks().parents(did);
List<Long> currentCardParentsDid = new ArrayList<>(parents.size() + 1);
for (JSONObject parent : parents) {
currentCardParentsDid.add(parent.getLong("id"));
}
currentCardParentsDid.add(did);
// We set the member only once it is filled, to ensure we avoid null pointer exception if `discardCurrentCard`
// were called during `setCurrentCard`.
mCurrentCardParentsDid = currentCardParentsDid;
_burySiblings(card);
// if current card is next card or in the queue
mRevQueue.remove(card.getId());
mNewQueue.remove(card.getId());
}
use of com.ichi2.libanki.sched.Counts.Queue in project AnkiChinaAndroid by ankichinateam.
the class SchedV2 method getCard.
/**
* Pop the next card from the queue. null if finished.
*/
@Nullable
public Card getCard() {
_checkDay();
// check day deal with cutoff if required. No need to do it in resets
if (!mHaveCounts) {
resetCounts(false);
}
if (!mHaveQueues) {
resetQueues(false);
}
@Nullable Card card = _getCard();
if (card != null) {
mCol.log(card);
incrReps();
// In upstream, counts are decremented when the card is
// gotten; i.e. in _getLrnCard, _getRevCard and
// _getNewCard. This can not be done anymore since we use
// those methods to pre-fetch the next card. Instead we
// decrement the counts here, when the card is returned to
// the reviewer.
decrementCounts(card);
setCurrentCard(card);
card.startTimer();
} else {
discardCurrentCard();
}
return card;
}
Aggregations