KDEGames

kgamehighscore.h
1/*
2 This file is part of the KDE games library
3 SPDX-FileCopyrightText: 2001 Andreas Beckermann <b_mann@gmx.de>
4 SPDX-FileCopyrightText: 2003 Nicolas Hadacek <hadacek@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#ifndef KGAMEHIGHSCORE_H
10#define KGAMEHIGHSCORE_H
11
12// own
13#include <kdegames_export.h>
14// Qt
15#include <QObject>
16// Std
17#include <memory>
18
19class KConfig;
20
21/**
22 * \class KGameHighscore kgamehighscore.h <KGameHighscore>
23 *
24 * @short Class for managing highscore tables
25 *
26 * This is the KDE class for saving and reading highscore tables. It offers the
27 * possibility for system-wide highscore tables (cmake with e.g.
28 * -DHIGHSCORE_DIRECTORY=/var/games) and a theoretically unlimited number of
29 * entries.
30 *
31 * You can specify different "keys" for an entry - just like the KConfig
32 * keys. But it will be prefixed with the number of the entry. For example you
33 * will probably use something like this to save the name of the player on the
34 * top of the list (ie the winner):
35 * \code
36 * highscore->writeEntry(1, "name", myPlayer->name());
37 * \endcode
38 * Note that it does not really matter if you use "0" or "1" as the first entry
39 * of the list as long as your program always uses the same for the first
40 * entry. I recommend to use "1", as several convenience methods use this.
41 *
42 * You can also specify different groups using setHighscoreGroup. Just
43 * like the keys mentioned above the groups behave like groups in KConfig
44 * but are prefixed with "KHighscore_". The default group is just "KHighscore".
45 * You might use this e.g. to create different highscore tables like
46 * \code
47 * table->setHighscoreGroup("Easy");
48 * // write the highscores for level "easy" to the table
49 * writeEasyHighscores(table);
50 *
51 * table->setHighscore("Player_1");
52 * // write player specific highscores to the table
53 * writePlayerHighscores(table);
54 * \endcode
55 * As you can see above you can also use this to write the highscores of a
56 * single player, so the "best times" of a player. To write highscores for a
57 * specific player in a specific level you will have to use a more complex way:
58 * \code
59 * QString group = QStringLiteral("%1_%2").arg(player).arg(level);
60 * table->setGroup(group);
61 * writeHighscore(table, player, level);
62 * \endcode
63 *
64 * Also note that you MUST NOT mark the key or the group for translation! I.e.
65 * don't use i18n() for the keys or groups! Here is the code to read the above
66 * written entry:
67 * \code
68 * QString firstName = highscore->readEntry(0, "name");
69 * \endcode
70 * Easy, what?
71 * @author Andreas Beckermann <b_mann@gmx.de>
72 */
73class KDEGAMES_EXPORT KGameHighscore : public QObject
74{
75 Q_OBJECT
76
77public:
78 /**
79 * Constructor.
80 *
81 * @param forceLocal if true, the local highscore file is used even
82 * when the configuration has been set to use a system-wide file. This
83 * is convenient for converting highscores from legacy applications.
84 * @param parent parent widget for this widget
85 */
86 explicit KGameHighscore(bool forceLocal = true, QObject *parent = nullptr);
87
88 /**
89 * Read the current state of the highscore file. Remember that when
90 * it's not locked for writing, this file can change at any time.
91 * (This method is only useful for a system-wide highscore file).
92 */
93 void readCurrentConfig();
94
95 /**
96 * This method open the system-wide highscore file using the effective
97 * group id of the game executable (which should be "games"). The
98 * effective group id is completely dropped afterwards.
99 *
100 * Note: this method should be called in main() before creating a
101 * KApplication and doing anything else (KApplication checks that the
102 * program is not suid/sgid and will exit the program for security
103 * reason if it is the case).
104 */
105 static void init(const char *appname);
106
107 /**
108 * Lock the system-wide highscore file for writing (does nothing and
109 * return true if the local file is used).
110 * You should perform writing without GUI interaction to avoid
111 * blocking and don't forget to unlock the file as soon as possible
112 * with writeAndUnlock().
113 *
114 * If the config file cannot be locked,
115 * the method waits for 1 second and, if it failed again, displays
116 * a message box asking for retry or cancel.
117 * @param widget used as the parent of the message box.
118 *
119 * @return false on error or if the config file is locked by another
120 * process. In such case, the config stays read-only.
121 */
122 bool lockForWriting(QWidget *widget = nullptr);
123
124 /**
125 * Effectively write and unlock the system-wide highscore file
126 * (@see lockForWriting).
127 * If using a local highscore file, it will sync the config.
128 */
129 void writeAndUnlock();
130
131 /**
132 * @return true if the highscore file is locked or if a local
133 * file is used.
134 */
135 bool isLocked() const;
136
137 /**
138 * Destructor.
139 * If necessary, write and unlock the highscore file.
140 */
141 ~KGameHighscore() override;
142
143 /**
144 * @param entry The number of the entry / the placing of the player
145 * @param key A key for this entry. E.g. "name" for the name of the
146 * player. Nearly the same as the usual keys in KConfig - but they
147 * are prefixed with the entry number
148 * @param value The value of this entry
149 */
150 void writeEntry(int entry, const QString &key, const QString &value);
151
152 /**
153 * This is an overloaded member function, provided for convenience.
154 * It differs from the above function only in what argument(s) it accepts.
155 */
156 void writeEntry(int entry, const QString &key, int value);
157
158 /**
159 * This is an overloaded member function, provided for convenience.
160 * It differs from the above function only in what argument(s) it accepts.
161 * See KConfigBase documentation for allowed QVariant::Type.
162 */
163 void writeEntry(int entry, const QString &key, const QVariant &value);
164
165 /**
166 * Reads an entry from the highscore table.
167 * @param entry The number of the entry / the placing to be read
168 * @param key The key of the entry. E.g. "name" for the name of the
169 * player. Nearly the same as the usual keys in KConfig - but they
170 * are prefixed with the entry number
171 * @param pDefault This will be used as default value if the key+pair
172 * entry can't be found.
173 * @return The value of this entry+key pair or pDefault if the entry+key
174 * pair doesn't exist
175 */
176 QString readEntry(int entry, const QString &key, const QString &pDefault = QString()) const;
177
178 /**
179 * Read a numeric value.
180 * @param entry The number of the entry / the placing to be read
181 * @param key The key of the entry. E.g. "name" for the name of the
182 * player. Nearly the same as the usual keys in KConfig - but they
183 * are prefixed with the entry number
184 * @param pDefault This will be used as default value if the key+pair
185 * entry can't be found.
186 * @return The value of this entry+key pair or pDefault if the entry+key
187 * pair doesn't exist
188 */
189 int readNumEntry(int entry, const QString &key, int pDefault = -1) const;
190
191 /**
192 * Read a QVariant entry.
193 * See KConfigBase documentation for allowed QVariant::Type.
194 *
195 * @return the value of this entry+key pair or pDefault if the entry+key
196 * pair doesn't exist or
197 */
198 QVariant readPropertyEntry(int entry, const QString &key, const QVariant &pDefault) const;
199
200 /**
201 * @return True if the highscore table contains the entry/key pair,
202 * otherwise false
203 */
204 bool hasEntry(int entry, const QString &key) const;
205
206 /**
207 * Reads a list of entries from the highscore table starting at 1 until
208 * lastEntry. If an entry between those numbers doesn't exist the
209 * function aborts reading even if after the missing entry is an
210 * existing one. The first entry of the list is the first placing, the
211 * last on is the last placing.
212 * @return A list of the entries of this key. You could also call
213 * readEntry(i, key) where i is from 1 to 20. Note that this function
214 * depends on "1" as the first entry!
215 * @param key The key of the entry. E.g. "name" for the name of the
216 * player. Nearly the same as the usual keys in KConfig - but they
217 * are prefixed with the entry number
218 * @param lastEntry the last entry which will be includes into the list.
219 * 1 will include a list with maximal 1 entry - 20 a list with maximal
220 * 20 entries. If lastEntry is <= 0 then rading is only stopped when
221 * when an entry does not exist.
222 */
223 QStringList readList(const QString &key, int lastEntry = 20) const;
224
225 /**
226 * Writes a list of entries to the highscore table.
227 *
228 * The first entry is prefixed with "1". Using this method is a short
229 * way of calling writeEntry(i, key, list[i]) from i = 1 to
230 * list.count()
231 * @param key A key for the entry. E.g. "name" for the name of the
232 * player. Nearly the same as the usual keys in KConfig - but they
233 * are prefixed with the entry number
234 * @param list The list of values
235 */
236 void writeList(const QString &key, const QStringList &list);
237
238 /**
239 * You can use this function to indicate whether KGameHighscore created a
240 * highscore table before and - if not - read your old (non-KGameHighscore)
241 * table instead.
242 * This way you can safely read an old table and save it using
243 * KGameHighscore without losing any data
244 * @return Whether a highscore table exists.
245 */
246 bool hasTable() const;
247
248 /**
249 * Set the new highscore group. The group is being prefixed with
250 * "KHighscore_" in the table.
251 * @param groupname The new groupname. E.g. use "easy" for the easy
252 * level of your game. If you use QString() (the default) the
253 * default group is used.
254 */
255 void setHighscoreGroup(const QString &groupname = QString());
256
257 /**
258 * Returns a list of group names without the KHighscore_ prexix.
259 * E.g, "KHighscore", "KHighscore_Easy", "KHighscore_Medium"
260 * will return "", "Easy", "Medium"
261 *
262 * @return A list of highscore groups.
263 */
264 QStringList groupList() const;
265
266 /**
267 * @return The currently used group. This doesn't contain the prefix
268 * ("KHighscore_") but the same as setHighscoreGroup uses. The
269 * default is QString()
270 */
271 QString highscoreGroup() const;
272
273protected:
274 /**
275 * @return A groupname to be used in KConfig. Used internally to
276 * prefix the value from highscoreGroup() with "KHighscore_"
277 */
278 QString group() const;
279
280 /**
281 * @return A pointer to the KConfig object to be used. This is
282 * either KGlobal::config() (default) or a KSimpleConfig object for
283 * a system-wide highscore file.
284 */
285 KConfig *config() const;
286
287 void init(bool forceLocal);
288
289private:
290 std::unique_ptr<class KGameHighscorePrivate> const d_ptr;
291 Q_DECLARE_PRIVATE(KGameHighscore)
292};
293
294#endif
Class for managing highscore tables.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:13:43 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.