summaryrefslogtreecommitdiffstats
path: root/examples/json/savegame/doc/src/savegame.qdoc
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2013-08-19 16:29:29 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-22 19:14:03 +0200
commitc7c3a78075eb05db6714b21c61aad722b275ec8c (patch)
tree715f8a9d634c06d6a2927693ee81798c4e7ffde7 /examples/json/savegame/doc/src/savegame.qdoc
parent4e043026725b1dfd201bf432bdd0b28ba8867196 (diff)
Add json/savegame example.
There wasn't any example documentation besides json.html, which doesn't actually describe usage of the various QJson* classes. This also makes each QJson* class page link back to json.html. Change-Id: If5ad6493d2728df0cec7bdbbc5790f0b755f816c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Jerome Pasion <jerome.pasion@digia.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'examples/json/savegame/doc/src/savegame.qdoc')
-rw-r--r--examples/json/savegame/doc/src/savegame.qdoc184
1 files changed, 184 insertions, 0 deletions
diff --git a/examples/json/savegame/doc/src/savegame.qdoc b/examples/json/savegame/doc/src/savegame.qdoc
new file mode 100644
index 0000000000..586c100399
--- /dev/null
+++ b/examples/json/savegame/doc/src/savegame.qdoc
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example savegame
+ \title JSON Save Game Example
+
+ \brief The JSON Save Game example demonstrates how to save and load a
+ small game using QJsonDocument, QJsonObject and QJsonArray.
+
+ Many games provide save functionality, so that the player's progress through
+ the game can be saved and loaded at a later time. The process of saving a
+ game generally involves serializing each game object's member variables
+ to a file. Many formats can be used for this purpose, one of which is JSON.
+ With QJsonDocument, you also have the ability to serialize a document in a
+ binary format, which is great if you don't want the save file to be
+ readable, or if you need to keep the file size down.
+
+ In this example, we'll demonstrate how to save and load a simple game to
+ and from JSON and binary formats.
+
+ \section1 The Character class
+
+ The Character class represents a non-player character (NPC) in our game, and
+ stores the player's name, level, and class type.
+
+ It provides read() and write() functions to serialise its member variables.
+
+ \snippet savegame/character.h 0
+
+ Of particular interest to us are the read and write function
+ implementations:
+
+ \snippet savegame/character.cpp 0
+
+ In the read() function, we assign Character's members values from the
+ QJsonObject argument. You can use either \l QJsonObject::operator[]() or
+ QJsonObject::value() to access values within the JSON object; both are
+ const functions and return QJsonValue::Undefined if the key is invalid. We
+ could check if the keys are valid before attempting to read them with
+ QJsonObject::contains(), but we assume that they are.
+
+ \snippet savegame/character.cpp 1
+
+ In the write() function, we do the reverse of the read() function; assign
+ values from the Character object to the JSON object. As with accessing
+ values, there are two ways to set values on a QJsonObject:
+ \l QJsonObject::operator[]() and QJsonObject::insert(). Both will override
+ any existing value at the given key.
+
+ Next up is the Level class:
+
+ \snippet savegame/level.h 0
+
+ We want to have several levels in our game, each with several NPCs, so we
+ keep a QList of Character objects. We also provide the familiar read() and
+ write() functions.
+
+ \snippet savegame/level.cpp 0
+
+ Containers can be written and read to and from JSON using QJsonArray. In our
+ case, we construct a QJsonArray from the value associated with the key
+ \c "npcs". Then, for each QJsonValue element in the array, we call
+ toObject() to get the Character's JSON object. The Character object can then
+ read their JSON and be appended to our NPC list.
+
+ \note \l{Container Classes}{Associate containers} can be written by storing
+ the key in each value object (if it's not already). With this approach, the
+ container is stored as a regular array of objects, but the index of each
+ element is used as the key to construct the container when reading it back
+ in.
+
+ \snippet savegame/level.cpp 1
+
+ Again, the write() function is similar to the read() function, except
+ reversed.
+
+ Having established the Character and Level classes, we can move on to
+ the Game class:
+
+ \snippet savegame/game.h 0
+
+ First of all, we define the \c SaveFormat enum. This will allow us to
+ specify the format in which the game should be saved: \c Json or \c Binary.
+
+ Next, we provide accessors for the player and levels. We then expose three
+ functions: newGame(), saveGame() and loadGame().
+
+ The read() and write() functions are used by saveGame() and loadGame().
+
+ \snippet savegame/game.cpp 0
+
+ To setup a new game, we create the player and populate the levels and their
+ NPCs.
+
+ \snippet savegame/game.cpp 1
+
+ The first thing we do in the read() function is tell the player to read
+ itself. We then clear the levels list so that calling loadGame() on the same
+ Game object twice doesn't result in old levels hanging around.
+
+ We then populate the level list by reading each Level from a QJsonArray.
+
+ \snippet savegame/game.cpp 2
+
+ We write the game to JSON similarly to how we write Level.
+
+ \snippet savegame/game.cpp 3
+
+ When loading a saved game in loadGame(), the first thing we do is open the
+ save file based on which format it was saved to; \c "save.json" for JSON,
+ and \c "save.dat" for binary. We print a warning and return \c false if the
+ file couldn't be opened.
+
+ Since QJsonDocument's \l{QJsonDocument::fromJson()}{fromJson()} and
+ \l{QJsonDocument::fromBinaryData()}{fromBinaryData()} functions both take a
+ QByteArray, we can read the entire contents of the save file into one,
+ regardless of the save format.
+
+ After constructing the QJsonDocument, we instruct the Game object to read
+ itself and then return \c true to indicate success.
+
+ \snippet savegame/game.cpp 4
+
+ Not surprisingly, saveGame() looks very much like loadGame(). We determine
+ the file extension based on the format, print a warning and return \c false
+ if the opening of the file fails. We then write the Game object to a
+ QJsonDocument, and call either QJsonDocument::toJson() or to
+ QJsonDocument::toBinaryData() to save the game, depending on which format
+ was specified.
+
+ We are now ready to enter main():
+
+ \snippet savegame/main.cpp 0
+
+ Since we're only interested in demonstrating \e serialization of a game with
+ JSON, our game is not actually playable. Therefore, we only need
+ QCoreApplication and have no event loop. We create our game and assume that
+ the player had a great time and made lots of progress, altering the internal
+ state of our Character, Level and Game objects.
+
+ \snippet savegame/main.cpp 1
+
+ When the player has finished, we save their game. For demonstration
+ purposes, we serialize to both JSON and binary. You can examine the contents
+ of the files in the same directory as the executable, although the binary
+ save file will contain some garbage characters (which is normal).
+
+ To show that the saved files can be loaded again, we call loadGame() for
+ each format, returning \c 1 on failure. Assuming everything went well, we
+ return \c 0 to indicate success.
+
+ That concludes our example. As you can see, serialization with Qt's JSON
+ classes is very simple and convenient. The advantages of using QJsonDocument
+ and friends over QDataStream, for example, is that you not only get
+ human-readable JSON files, but you also have the option to use a binary
+ format if it's required, \e without rewriting any code.
+
+ \sa {JSON Support in Qt}, {Data Storage}
+*/