Changeset View
Changeset View
Standalone View
Standalone View
src/practice/sessionmanagerfixed.cpp
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Line(s) | 41 | { | |||
---|---|---|---|---|---|
42 | const int MaxEntries = Prefs::sessionMaxSize(); | 42 | const int MaxEntries = Prefs::sessionMaxSize(); | ||
43 | const int MaxNewWords = Prefs::sessionMaxNewWords(); | 43 | const int MaxNewWords = Prefs::sessionMaxNewWords(); | ||
44 | 44 | | |||
45 | // We will never add anything to the session after it's initialized. | 45 | // We will never add anything to the session after it's initialized. | ||
46 | m_notAskedTestEntries.clear(); | 46 | m_notAskedTestEntries.clear(); | ||
47 | 47 | | |||
48 | // Pick N new words if there are any into the active set. | 48 | // Pick N new words if there are any into the active set. | ||
49 | int numNewWords = 0; | 49 | int numNewWords = 0; | ||
50 | int i = 0; | 50 | QList<TestEntry*>::Iterator it = m_allTestEntries.begin(); | ||
51 | while (i < m_allTestEntries.count() | 51 | while (it != m_allTestEntries.end() | ||
52 | && numNewWords < MaxNewWords | 52 | && numNewWords < MaxNewWords | ||
53 | && m_currentEntries.count() < MaxEntries) | 53 | && m_currentEntries.count() < MaxEntries) | ||
54 | { | 54 | { | ||
55 | TestEntry *it = m_allTestEntries.at(i); | 55 | if ((*it)->practiceModeDependentMinGrade() == 0 | ||
56 | if (it->practiceModeDependentMinGrade() == 0 | 56 | && (*it)->practiceModeDependentMinPreGrade() == 0) | ||
57 | && it->practiceModeDependentMinPreGrade() == 0) { | 57 | { | ||
58 | m_currentEntries.append(it); | 58 | m_currentEntries.append(*it); | ||
59 | numNewWords++; | 59 | numNewWords++; | ||
60 | it = m_allTestEntries.erase(it); | ||||
tcanabrava: can we erase an iterator inside a loop? | |||||
Yes, with QList that works. hriesenbeck: Yes, with QList that works.
Erase() removes the list entry the iterator is pointing to and… | |||||
61 | } else { | ||||
62 | ++it; | ||||
60 | } | 63 | } | ||
61 | | ||||
62 | ++i; | | |||
63 | } | 64 | } | ||
64 | 65 | | |||
65 | // Pick the rest of the words from the already practiced ones. | 66 | // Pick the rest of the words from the already practiced ones. | ||
66 | // Use higher graded entries before lower graded ones. | 67 | // Use higher graded entries before lower graded ones. | ||
67 | for (int grade = KV_MAX_GRADE; grade > 0 ; --grade) { | 68 | for (int grade = KV_MAX_GRADE; grade > 0 ; --grade) { | ||
68 | if (m_currentEntries.count() >= MaxEntries) { | 69 | if (m_currentEntries.count() >= MaxEntries) { | ||
69 | break; | 70 | break; | ||
70 | } | 71 | } | ||
71 | 72 | | |||
72 | // Step through all entries and collect those at the current | 73 | // Step through all entries and collect those at the current | ||
73 | // grade until the session is filled. | 74 | // grade until the session is filled. | ||
74 | foreach (TestEntry *entry, m_allTestEntries) { | 75 | it = m_allTestEntries.begin(); | ||
75 | if (entry->practiceModeDependentMaxGrade() == grade) { | 76 | while (it != m_allTestEntries.end() | ||
76 | m_currentEntries.append(entry); | 77 | && m_currentEntries.count() < MaxEntries) | ||
77 | } | 78 | { | ||
78 | if (m_currentEntries.count() >= MaxEntries) { | 79 | if ((*it)->practiceModeDependentMaxGrade() == grade) { | ||
79 | break; | 80 | m_currentEntries.append(*it); | ||
81 | it = m_allTestEntries.erase(it); | ||||
82 | } else { | ||||
83 | ++it; | ||||
80 | } | 84 | } | ||
81 | } | 85 | } | ||
82 | } | 86 | } | ||
83 | 87 | | |||
84 | // If there is still room in the session, pick the rest of the | 88 | // If there is still room in the session, pick the rest of the | ||
85 | // words from the ones with pregrades. Also here, use higher | 89 | // words from the ones with pregrades. Also here, use higher | ||
86 | // graded entries before lower graded ones. | 90 | // graded entries before lower graded ones. | ||
87 | for (int preGrade = KV_MAX_GRADE; preGrade > 0 ; --preGrade) { | 91 | for (int preGrade = KV_MAX_GRADE; preGrade > 0 ; --preGrade) { | ||
88 | if (m_currentEntries.count() >= MaxEntries) { | 92 | if (m_currentEntries.count() >= MaxEntries) { | ||
89 | break; | 93 | break; | ||
90 | } | 94 | } | ||
91 | 95 | | |||
92 | // Step through all entries and collect those at the current | 96 | // Step through all entries and collect those at the current | ||
93 | // grade until the session is filled. | 97 | // grade until the session is filled. | ||
94 | foreach (TestEntry *entry, m_allTestEntries) { | 98 | it = m_allTestEntries.begin(); | ||
95 | if (entry->practiceModeDependentMaxPreGrade() == preGrade) { | 99 | while (it != m_allTestEntries.end() | ||
96 | m_currentEntries.append(entry); | 100 | && m_currentEntries.count() < MaxEntries) | ||
97 | } | 101 | { | ||
98 | if (m_currentEntries.count() >= MaxEntries) { | 102 | if ((*it)->practiceModeDependentMaxPreGrade() == preGrade) { | ||
99 | break; | 103 | m_currentEntries.append(*it); | ||
104 | it = m_allTestEntries.erase(it); | ||||
105 | } else { | ||||
106 | ++it; | ||||
100 | } | 107 | } | ||
101 | } | 108 | } | ||
102 | } | 109 | } | ||
103 | 110 | | |||
111 | // The remaining entries have to be deleted to prevent memory leaking | ||||
112 | qDeleteAll(m_allTestEntries); | ||||
113 | | ||||
104 | // Now we have decided exactly which ones to use. | 114 | // Now we have decided exactly which ones to use. | ||
105 | // We need to keep this for statistics reporting at the end. | 115 | // We need to keep this for statistics reporting at the end. | ||
106 | // | | |||
107 | // FIXME: Seems to be a memory leak here. | | |||
108 | | ||||
109 | // m_allTestEntries owns all test entries and now it | | |||
110 | // suddenly gets assigned a potentially smaller subset. | | |||
111 | // Those which were pointed to by pointers inside | | |||
112 | // m_allTestEntries but not also a pointer inside | | |||
113 | // m_currentEntries are lost. | | |||
114 | m_allTestEntries = m_currentEntries; | 116 | m_allTestEntries = m_currentEntries; | ||
115 | } | 117 | } |
can we erase an iterator inside a loop?