do not crash on malformed schedule files
[sispare-qt.git] / session.hh
blob4e6caa15850c3e8cbc93305b0b5ca51e4dee21d9
1 /*
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
7 * in all copies.
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.
18 #ifndef SESSION_H
19 #define SESSION_H
21 #include <filesystem>
22 #include <optional>
23 #include <map>
24 #include <set>
25 #include <variant>
26 #include <vector>
28 #include "card.hh"
30 /* What's currently going on */
31 enum class Currently_doing { Viewing_A, Viewing_B, Finished, Trivial };
34 * This holds the abstract information about a review session: a list of
35 * cards scheduled for review and what action has been taken on each card.
37 * Thankfully rule-of-zero-compliant.
39 class Session {
40 public:
41 Session(const std::filesystem::path& data_dir);
43 /* A changing (but not strongly random) value per-run. Used by Card in shuffled ordering */
44 static std::string salt;
47 * A card at level j takes between timing_data[j].first
48 * and timing_data[j].second days to review next. Not
49 * computed because I might want to fiddle with it.
51 static constexpr std::pair<int, int> timing_data[13] = {
52 /* */
53 std::make_pair(0, 0), /* */
54 std::make_pair(1, 1), /* */
55 std::make_pair(1, 2), /* */
56 std::make_pair(2, 3), /* */
57 std::make_pair(3, 5), /* */
58 std::make_pair(5, 8), /* */
59 std::make_pair(8, 13), /* */
60 std::make_pair(13, 21), /* */
61 std::make_pair(21, 34), /* */
62 std::make_pair(34, 55), /* */
63 std::make_pair(55, 89), /* */
64 std::make_pair(89, 144), /* */
65 std::make_pair(144, 233), /* */
68 /* Are the any cards to review in this session? */
69 bool have_cards_to_review() const;
71 /* What's going on right now? */
72 Currently_doing get_current_action() const;
74 /* Get the A-side of the card that's being looked at */
75 std::optional<const std::string> get_current_A_side() const;
77 /* Get the B-side of the card that's being looked at */
78 std::optional<const std::string> get_current_B_side() const;
80 /* Get something like "19/23" */
81 const std::string get_progress_string() const;
83 /* Get something like "Finished. 10 passed, 3 failed" */
84 const std::string get_statistics() const;
86 /* Get something like "Already marked as passed" */
87 const std::string get_previously_seen_string() const;
89 /* Are there cards after this one? */
90 bool have_next_card() const;
92 /* Are there cards before this one? */
93 bool have_prev_card() const;
95 /* Flip the current card over */
96 void flip_current_card();
98 /* Mark the current card as having had some review action taken */
99 void mark_current_card_as(Review_status review_status);
101 /* Move to the next card */
102 void move_next_card();
104 /* Move to the previous card */
105 void move_prev_card();
107 /* Write out new levels and schedule files according to this session's progress */
108 void update_cards_on_disk();
110 private:
111 /* Something like "~/.data/sispare" */
112 const std::filesystem::path data_dir;
114 /* When this session was started */
115 std::chrono::system_clock::time_point session_start;
117 /* What the UI should show right now */
118 Currently_doing current_action;
120 /* All the cards that are due for review this session. */
121 std::set<Card> cards;
123 /* Our iterator into cards */
124 std::set<Card>::iterator cards_it;
126 /* ... and the actual index */
127 std::size_t it_index;
129 /* What happened to each card? Indexed by path for use by update_cards_on_disk. */
130 std::map<std::filesystem::path, Review_status> card_status;
132 /* The schedule files that may need to be updated if we review some cards */
133 std::vector<std::filesystem::path> schedule_files_to_clean;
135 /* The cards which we failed reading; therefore cards we should delete */
136 std::set<std::filesystem::path> cards_to_delete;
139 #endif