2 * Copyright (c) 2021, S. Gilles <sgilles@sgilles.net>
4 * Permission to use, copy, modify, and/or distribute this software
5 * for any purpose with or without fee is hereby granted, provided
6 * that the above copyright notice and this permission notice appear
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
13 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
14 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29 /* What's currently going on */
30 enum class Currently_doing
{ Viewing_A
, Viewing_B
, Finished
, Trivial
};
33 * This holds the abstract information about a review session: a list of
34 * cards scheduled for review and what action has been taken on each card.
36 * Thankfully rule-of-zero-compliant.
40 Session(const std::filesystem::path
& data_dir
);
42 /* A changing (but not strongly random) value per-run. Used by Card in shuffled ordering */
43 static std::string salt
;
46 * A card at level j takes between timing_data[j].first
47 * and timing_data[j].second days to review next. Not
48 * computed because I might want to fiddle with it.
50 static constexpr std::pair
<int, int> timing_data
[13] = {
52 std::make_pair(0, 0), /* */
53 std::make_pair(1, 1), /* */
54 std::make_pair(1, 2), /* */
55 std::make_pair(2, 3), /* */
56 std::make_pair(3, 5), /* */
57 std::make_pair(5, 8), /* */
58 std::make_pair(8, 13), /* */
59 std::make_pair(13, 21), /* */
60 std::make_pair(21, 34), /* */
61 std::make_pair(34, 55), /* */
62 std::make_pair(55, 89), /* */
63 std::make_pair(89, 144), /* */
64 std::make_pair(144, 233), /* */
67 /* Are the any cards to review in this session? */
68 bool have_cards_to_review() const;
70 /* What's going on right now? */
71 Currently_doing
get_current_action() const;
73 /* Get the A-side of the card that's being looked at */
74 std::optional
<const std::string
> get_current_A_side() const;
76 /* Get the B-side of the card that's being looked at */
77 std::optional
<const std::string
> get_current_B_side() const;
79 /* Get something like "19/23" */
80 const std::string
get_progress_string() const;
82 /* Get something like "Finished. 10 passed, 3 failed" */
83 const std::string
get_statistics() const;
85 /* Get something like "Already marked as passed" */
86 const std::string
get_previously_seen_string() const;
88 /* Are there cards after this one? */
89 bool have_next_card() const;
91 /* Are there cards before this one? */
92 bool have_prev_card() const;
94 /* Flip the current card over */
95 void flip_current_card();
97 /* Mark the current card as having had some review action taken */
98 void mark_current_card_as(Review_status review_status
);
100 /* Move to the next card */
101 void move_next_card();
103 /* Move to the previous card */
104 void move_prev_card();
106 /* Write out new levels and schedule files according to this session's progress */
107 void update_cards_on_disk();
110 /* Something like "~/.data/sispare" */
111 const std::filesystem::path data_dir
;
113 /* When this session was started */
114 std::chrono::system_clock::time_point session_start
;
116 /* What the UI should show right now */
117 Currently_doing current_action
;
119 /* All the cards that are due for review this session. */
120 std::set
<Card
> cards
;
122 /* Our iterator into cards */
123 std::set
<Card
>::iterator cards_it
;
125 /* ... and the actual index */
126 std::size_t it_index
;
128 /* What happened to each card? Indexed by path for use by update_cards_on_disk. */
129 std::map
<std::filesystem::path
, Review_status
> card_status
;
131 /* The schedule files that may need to be updated if we review some cards */
132 std::vector
<std::filesystem::path
> schedule_files_to_clean
;