Search in sources :

Example 41 with DECK

use of com.ichi2.anki.CardBrowser.Column.DECK in project AnkiChinaAndroid by ankichinateam.

the class Sched method _fillRev.

@Override
protected boolean _fillRev(boolean allowSibling) {
    if (!mRevQueue.isEmpty()) {
        return true;
    }
    if (mRevCount == 0) {
        return false;
    }
    SupportSQLiteDatabase db = mCol.getDb().getDatabase();
    while (!mRevDids.isEmpty()) {
        long did = mRevDids.getFirst();
        int lim = Math.min(mQueueLimit, _deckRevLimit(did));
        Cursor cur = null;
        if (lim != 0) {
            mRevQueue.clear();
            // fill the queue with the current did
            try {
                /* Difference with upstream: we take current card into account.
                     *
                     * When current card is answered, the card is not due anymore, so does not belong to the queue.
                     * Furthermore, _burySiblings ensure that the siblings of the current cards are removed from the
                     * queue to ensure same day spacing. We simulate this action by ensuring that those siblings are not
                     * filled, except if we know there are cards and we didn't find any non-sibling card. This way, the
                     * queue is not empty if it should not be empty (important for the conditional belows), but the
                     * front of the queue contains distinct card.
                     */
                String idName = (allowSibling) ? "id" : "nid";
                long id = (allowSibling) ? currentCardId() : currentCardNid();
                cur = db.query("SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ?" + " AND " + idName + " != ? LIMIT ?", new Object[] { did, mToday, id, lim });
                while (cur.moveToNext()) {
                    mRevQueue.add(cur.getLong(0));
                }
            } finally {
                if (cur != null && !cur.isClosed()) {
                    cur.close();
                }
            }
            if (!mRevQueue.isEmpty()) {
                // ordering
                if (mCol.getDecks().get(did).getInt("dyn") != 0) {
                // dynamic decks need due order preserved
                // Note: libanki reverses mRevQueue and returns the last element in _getRevCard().
                // AnkiDroid differs by leaving the queue intact and returning the *first* element
                // in _getRevCard().
                } else {
                    Random r = new Random();
                    r.setSeed(mToday);
                    mRevQueue.shuffle(r);
                }
                // is the current did empty?
                if (mRevQueue.size() < lim) {
                    mRevDids.remove();
                }
                return true;
            }
        }
        // nothing left in the deck; move to next
        mRevDids.remove();
    }
    // Since we didn't get a card and the count is non-zero, we
    // need to check again for any cards that were removed from
    // the queue but not buried
    _resetRev();
    return _fillRev(true);
}
Also used : SupportSQLiteDatabase(androidx.sqlite.db.SupportSQLiteDatabase) Random(java.util.Random) JSONObject(com.ichi2.utils.JSONObject) Cursor(android.database.Cursor)

Example 42 with DECK

use of com.ichi2.anki.CardBrowser.Column.DECK in project AnkiChinaAndroid by ankichinateam.

the class Sched method _deckRevLimitSingle.

/**
 * Maximal number of rev card still to see today in deck d. It's computed as:
 * the number of rev card to see by day according
 * minus the number of rev cards seen today in deck d or a descendant
 * plus the number of extra cards to see today in deck d, a parent or a descendant.
 *
 * Limits of its ancestors are not applied.  Current card is treated the same way as other cards.
 */
@Override
protected int _deckRevLimitSingle(@NonNull Deck d) {
    if (d.getInt("dyn") != 0) {
        return mReportLimit;
    }
    long did = d.getLong("id");
    DeckConfig c = mCol.getDecks().confForDid(did);
    int lim = Math.max(0, c.getJSONObject("rev").getInt("perDay") - d.getJSONArray("revToday").getInt(1));
    if (currentCardIsInQueueWithDeck(Consts.QUEUE_TYPE_REV, did)) {
        lim--;
    }
    // So currentCard does not have to be taken into consideration in this method
    return lim;
}
Also used : DeckConfig(com.ichi2.libanki.DeckConfig)

Example 43 with DECK

use of com.ichi2.anki.CardBrowser.Column.DECK in project AnkiChinaAndroid by ankichinateam.

the class Sched method _lapseConf.

@Override
@NonNull
protected JSONObject _lapseConf(@NonNull Card card) {
    DeckConfig conf = _cardConf(card);
    // normal deck
    if (card.getODid() == 0) {
        return conf.getJSONObject("lapse");
    }
    // dynamic deck; override some attributes, use original deck for others
    DeckConfig oconf = mCol.getDecks().confForDid(card.getODid());
    JSONArray delays = conf.optJSONArray("delays");
    if (delays == null) {
        delays = oconf.getJSONObject("lapse").getJSONArray("delays");
    }
    JSONObject dict = new JSONObject();
    // original deck
    dict.put("minInt", oconf.getJSONObject("lapse").getInt("minInt"));
    dict.put("leechFails", oconf.getJSONObject("lapse").getInt("leechFails"));
    dict.put("leechAction", oconf.getJSONObject("lapse").getInt("leechAction"));
    dict.put("mult", oconf.getJSONObject("lapse").getDouble("mult"));
    // overrides
    dict.put("delays", delays);
    dict.put("resched", conf.getBoolean("resched"));
    return dict;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) DeckConfig(com.ichi2.libanki.DeckConfig) NonNull(androidx.annotation.NonNull)

Example 44 with DECK

use of com.ichi2.anki.CardBrowser.Column.DECK in project AnkiChinaAndroid by ankichinateam.

the class Sched method _newConf.

/**
 * Tools ******************************************************************** ***************************
 */
@Override
@NonNull
protected JSONObject _newConf(@NonNull Card card) {
    DeckConfig conf = _cardConf(card);
    // normal deck
    if (card.getODid() == 0) {
        return conf.getJSONObject("new");
    }
    // dynamic deck; override some attributes, use original deck for others
    DeckConfig oconf = mCol.getDecks().confForDid(card.getODid());
    JSONArray delays = conf.optJSONArray("delays");
    if (delays == null) {
        delays = oconf.getJSONObject("new").getJSONArray("delays");
    }
    JSONObject dict = new JSONObject();
    // original deck
    dict.put("ints", oconf.getJSONObject("new").getJSONArray("ints"));
    dict.put("initialFactor", oconf.getJSONObject("new").getInt("initialFactor"));
    dict.put("bury", oconf.getJSONObject("new").optBoolean("bury", true));
    // overrides
    dict.put("delays", delays);
    dict.put("separate", conf.getBoolean("separate"));
    dict.put("order", Consts.NEW_CARDS_DUE);
    dict.put("perDay", mReportLimit);
    return dict;
}
Also used : JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) DeckConfig(com.ichi2.libanki.DeckConfig) NonNull(androidx.annotation.NonNull)

Example 45 with DECK

use of com.ichi2.anki.CardBrowser.Column.DECK in project AnkiChinaAndroid by ankichinateam.

the class Sched method deckDueList.

/**
 * Returns [deckname, did, rev, lrn, new]
 */
@Override
@Nullable
public List<DeckDueTreeNode> deckDueList(@Nullable CollectionTask collectionTask, long did) {
    _checkDay();
    mCol.getDecks().checkIntegrity();
    ArrayList<Deck> decks = deckLimitWithParent(did, mCol);
    // ArrayList<Deck> decks = mCol.getDecks().allSorted();
    Timber.i("show decks" + did + " size:" + decks.size());
    HashMap<String, Integer[]> lims = new HashMap<>();
    ArrayList<DeckDueTreeNode> data = new ArrayList<>();
    long time = SystemClock.elapsedRealtime();
    for (Deck deck : decks) {
        if (collectionTask != null && collectionTask.isCancelled()) {
            return null;
        }
        String deckName = deck.getString("name");
        String p = Decks.parent(deckName);
        // new
        int nlim = _deckNewLimitSingle(deck);
        int rlim = _deckRevLimitSingle(deck);
        if (!TextUtils.isEmpty(p)) {
            Integer[] parentLims = lims.get(Decks.normalizeName(p));
            // 'temporary for diagnosis of bug #6383'
            Assert.that(parentLims != null, "Deck %s is supposed to have parent %s. It has not be found.", deckName, p);
            nlim = Math.min(nlim, parentLims[0]);
            // review
            rlim = Math.min(rlim, parentLims[1]);
        }
        // long time = SystemClock.elapsedRealtime();
        int _new = _newForDeck(deck.getLong("id"), nlim);
        // Timber.i("cost time for new:"+(SystemClock.elapsedRealtime()-time));
        // learning
        int lrn = _lrnForDeck(deck.getLong("id"));
        // Timber.i("cost time for lrn:"+(SystemClock.elapsedRealtime()-time));
        // reviews
        int rev = _revForDeck(deck.getLong("id"), rlim);
        // Timber.i("cost time for rev:"+(SystemClock.elapsedRealtime()-time));
        // save to list
        double[] datas = did == ALL_DECKS_ID ? _getCardDataCount(deck.getLong("id")) : new double[] { 0, 0, 0 };
        // Timber.i("cost time for datas:"+(SystemClock.elapsedRealtime()-time));
        // Timber.i("add deck in tree:%s", deckName);
        data.add(new DeckDueTreeNode(mCol, deck.getString("name"), deck.getLong("id"), rev, lrn, _new, datas));
        // add deck as a parent
        lims.put(Decks.normalizeName(deck.getString("name")), new Integer[] { nlim, rlim });
    }
    Timber.i("cost time for datas:" + (SystemClock.elapsedRealtime() - time));
    return data;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Deck(com.ichi2.libanki.Deck) Nullable(androidx.annotation.Nullable)

Aggregations

Deck (com.ichi2.libanki.Deck)100 Collection (com.ichi2.libanki.Collection)97 JSONObject (com.ichi2.utils.JSONObject)88 Test (org.junit.Test)80 JSONArray (com.ichi2.utils.JSONArray)55 Card (com.ichi2.libanki.Card)53 Note (com.ichi2.libanki.Note)50 ArrayList (java.util.ArrayList)47 RobolectricTest (com.ichi2.anki.RobolectricTest)44 DeckConfig (com.ichi2.libanki.DeckConfig)37 JSONException (com.ichi2.utils.JSONException)34 NonNull (androidx.annotation.NonNull)30 HashMap (java.util.HashMap)29 Model (com.ichi2.libanki.Model)23 Map (java.util.Map)22 Intent (android.content.Intent)21 Resources (android.content.res.Resources)18 TextView (android.widget.TextView)18 SharedPreferences (android.content.SharedPreferences)17 Cursor (android.database.Cursor)17