summaryrefslogtreecommitdiffstats
path: root/examples/corelib/serialization/savegame
diff options
context:
space:
mode:
Diffstat (limited to 'examples/corelib/serialization/savegame')
-rw-r--r--examples/corelib/serialization/savegame/character.cpp131
-rw-r--r--examples/corelib/serialization/savegame/character.h92
-rw-r--r--examples/corelib/serialization/savegame/doc/src/savegame.qdoc187
-rw-r--r--examples/corelib/serialization/savegame/game.cpp206
-rw-r--r--examples/corelib/serialization/savegame/game.h85
-rw-r--r--examples/corelib/serialization/savegame/level.cpp117
-rw-r--r--examples/corelib/serialization/savegame/level.h81
-rw-r--r--examples/corelib/serialization/savegame/main.cpp82
-rw-r--r--examples/corelib/serialization/savegame/savegame.pro22
9 files changed, 1003 insertions, 0 deletions
diff --git a/examples/corelib/serialization/savegame/character.cpp b/examples/corelib/serialization/savegame/character.cpp
new file mode 100644
index 0000000000..046cde3091
--- /dev/null
+++ b/examples/corelib/serialization/savegame/character.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "character.h"
+
+#include <QMetaEnum>
+#include <QTextStream>
+
+Character::Character() :
+ mLevel(0),
+ mClassType(Warrior) {
+}
+
+Character::Character(const QString &name,
+ int level,
+ Character::ClassType classType) :
+ mName(name),
+ mLevel(level),
+ mClassType(classType)
+{
+}
+
+QString Character::name() const
+{
+ return mName;
+}
+
+void Character::setName(const QString &name)
+{
+ mName = name;
+}
+
+int Character::level() const
+{
+ return mLevel;
+}
+
+void Character::setLevel(int level)
+{
+ mLevel = level;
+}
+
+Character::ClassType Character::classType() const
+{
+ return mClassType;
+}
+
+void Character::setClassType(Character::ClassType classType)
+{
+ mClassType = classType;
+}
+
+//! [0]
+void Character::read(const QJsonObject &json)
+{
+ if (json.contains("name") && json["name"].isString())
+ mName = json["name"].toString();
+
+ if (json.contains("level") && json["level"].isDouble())
+ mLevel = json["level"].toInt();
+
+ if (json.contains("classType") && json["classType"].isDouble())
+ mClassType = ClassType(json["classType"].toInt());
+}
+//! [0]
+
+//! [1]
+void Character::write(QJsonObject &json) const
+{
+ json["name"] = mName;
+ json["level"] = mLevel;
+ json["classType"] = mClassType;
+}
+//! [1]
+
+void Character::print(int indentation) const
+{
+ const QString indent(indentation * 2, ' ');
+ QTextStream(stdout) << indent << "Name:\t" << mName << "\n";
+ QTextStream(stdout) << indent << "Level:\t" << mLevel << "\n";
+
+ QString className = QMetaEnum::fromType<ClassType>().valueToKey(mClassType);
+ QTextStream(stdout) << indent << "Class:\t" << className << "\n";
+}
diff --git a/examples/corelib/serialization/savegame/character.h b/examples/corelib/serialization/savegame/character.h
new file mode 100644
index 0000000000..cbf06d7fd6
--- /dev/null
+++ b/examples/corelib/serialization/savegame/character.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CHARACTER_H
+#define CHARACTER_H
+
+#include <QJsonObject>
+#include <QObject>
+#include <QString>
+
+//! [0]
+class Character
+{
+ Q_GADGET;
+
+public:
+ enum ClassType {
+ Warrior, Mage, Archer
+ };
+ Q_ENUM(ClassType)
+
+ Character();
+ Character(const QString &name, int level, ClassType classType);
+
+ QString name() const;
+ void setName(const QString &name);
+
+ int level() const;
+ void setLevel(int level);
+
+ ClassType classType() const;
+ void setClassType(ClassType classType);
+
+ void read(const QJsonObject &json);
+ void write(QJsonObject &json) const;
+
+ void print(int indentation = 0) const;
+private:
+ QString mName;
+ int mLevel;
+ ClassType mClassType;
+};
+//! [0]
+
+#endif // CHARACTER_H
diff --git a/examples/corelib/serialization/savegame/doc/src/savegame.qdoc b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc
new file mode 100644
index 0000000000..06e70680c6
--- /dev/null
+++ b/examples/corelib/serialization/savegame/doc/src/savegame.qdoc
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \example json/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 json/savegame/character.h 0
+
+ Of particular interest to us are the read and write function
+ implementations:
+
+ \snippet json/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
+ check if the keys are valid before attempting to read them with
+ QJsonObject::contains().
+
+ \snippet json/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 json/savegame/level.h 0
+
+ We want to have several levels in our game, each with several NPCs, so we
+ keep a QVector of Character objects. We also provide the familiar read() and
+ write() functions.
+
+ \snippet json/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 array.
+
+ \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 json/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 json/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 json/savegame/game.cpp 0
+
+ To setup a new game, we create the player and populate the levels and their
+ NPCs.
+
+ \snippet json/savegame/game.cpp 1
+
+ The first thing we do in the read() function is tell the player to read
+ itself. We then clear the level array so that calling loadGame() on the
+ same Game object twice doesn't result in old levels hanging around.
+
+ We then populate the level array by reading each Level from a QJsonArray.
+
+ \snippet json/savegame/game.cpp 2
+
+ We write the game to JSON similarly to how we write Level.
+
+ \snippet json/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 json/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 json/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. On application start-up we parse
+ the command-line arguments to decide how to start the game. For the first
+ argument the options "new" (default) and "load" are available. When "new"
+ is specified a new game will be generated, and when "load" is specified a
+ previously saved game will be loaded in. For the second argument
+ "json" (default) and "binary" are available as options. This argument will
+ decide which file is saved to and/or loaded from. We then move ahead 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 json/savegame/main.cpp 1
+
+ When the player has finished, we save their game. For demonstration
+ purposes, we can serialize to either JSON or binary. You can examine the
+ contents of the files in the same directory as the executable (or re-run
+ the example, making sure to also specify the "load" option), although the
+ binary save file will contain some garbage characters (which is normal).
+
+ 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}
+*/
diff --git a/examples/corelib/serialization/savegame/game.cpp b/examples/corelib/serialization/savegame/game.cpp
new file mode 100644
index 0000000000..4caec71a03
--- /dev/null
+++ b/examples/corelib/serialization/savegame/game.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "game.h"
+
+#include <QFile>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QRandomGenerator>
+#include <QTextStream>
+
+Character Game::player() const
+{
+ return mPlayer;
+}
+
+QVector<Level> Game::levels() const
+{
+ return mLevels;
+}
+
+//! [0]
+void Game::newGame()
+{
+ mPlayer = Character();
+ mPlayer.setName(QStringLiteral("Hero"));
+ mPlayer.setClassType(Character::Archer);
+ mPlayer.setLevel(QRandomGenerator::global()->bounded(15, 21));
+
+ mLevels.clear();
+ mLevels.reserve(2);
+
+ Level village(QStringLiteral("Village"));
+ QVector<Character> villageNpcs;
+ villageNpcs.reserve(2);
+ villageNpcs.append(Character(QStringLiteral("Barry the Blacksmith"),
+ QRandomGenerator::global()->bounded(8, 11),
+ Character::Warrior));
+ villageNpcs.append(Character(QStringLiteral("Terry the Trader"),
+ QRandomGenerator::global()->bounded(6, 8),
+ Character::Warrior));
+ village.setNpcs(villageNpcs);
+ mLevels.append(village);
+
+ Level dungeon(QStringLiteral("Dungeon"));
+ QVector<Character> dungeonNpcs;
+ dungeonNpcs.reserve(3);
+ dungeonNpcs.append(Character(QStringLiteral("Eric the Evil"),
+ QRandomGenerator::global()->bounded(18, 26),
+ Character::Mage));
+ dungeonNpcs.append(Character(QStringLiteral("Eric's Left Minion"),
+ QRandomGenerator::global()->bounded(5, 7),
+ Character::Warrior));
+ dungeonNpcs.append(Character(QStringLiteral("Eric's Right Minion"),
+ QRandomGenerator::global()->bounded(4, 9),
+ Character::Warrior));
+ dungeon.setNpcs(dungeonNpcs);
+ mLevels.append(dungeon);
+}
+//! [0]
+
+//! [3]
+bool Game::loadGame(Game::SaveFormat saveFormat)
+{
+ QFile loadFile(saveFormat == Json
+ ? QStringLiteral("save.json")
+ : QStringLiteral("save.dat"));
+
+ if (!loadFile.open(QIODevice::ReadOnly)) {
+ qWarning("Couldn't open save file.");
+ return false;
+ }
+
+ QByteArray saveData = loadFile.readAll();
+
+ QJsonDocument loadDoc(saveFormat == Json
+ ? QJsonDocument::fromJson(saveData)
+ : QJsonDocument::fromBinaryData(saveData));
+
+ read(loadDoc.object());
+
+ QTextStream(stdout) << "Loaded save for "
+ << loadDoc["player"]["name"].toString()
+ << " using "
+ << (saveFormat != Json ? "binary " : "") << "JSON...\n";
+ return true;
+}
+//! [3]
+
+//! [4]
+bool Game::saveGame(Game::SaveFormat saveFormat) const
+{
+ QFile saveFile(saveFormat == Json
+ ? QStringLiteral("save.json")
+ : QStringLiteral("save.dat"));
+
+ if (!saveFile.open(QIODevice::WriteOnly)) {
+ qWarning("Couldn't open save file.");
+ return false;
+ }
+
+ QJsonObject gameObject;
+ write(gameObject);
+ QJsonDocument saveDoc(gameObject);
+ saveFile.write(saveFormat == Json
+ ? saveDoc.toJson()
+ : saveDoc.toBinaryData());
+
+ return true;
+}
+//! [4]
+
+//! [1]
+void Game::read(const QJsonObject &json)
+{
+ if (json.contains("player") && json["player"].isObject())
+ mPlayer.read(json["player"].toObject());
+
+ if (json.contains("levels") && json["levels"].isArray()) {
+ QJsonArray levelArray = json["levels"].toArray();
+ mLevels.clear();
+ mLevels.reserve(levelArray.size());
+ for (int levelIndex = 0; levelIndex < levelArray.size(); ++levelIndex) {
+ QJsonObject levelObject = levelArray[levelIndex].toObject();
+ Level level;
+ level.read(levelObject);
+ mLevels.append(level);
+ }
+ }
+}
+//! [1]
+
+//! [2]
+void Game::write(QJsonObject &json) const
+{
+ QJsonObject playerObject;
+ mPlayer.write(playerObject);
+ json["player"] = playerObject;
+
+ QJsonArray levelArray;
+ foreach (const Level level, mLevels) {
+ QJsonObject levelObject;
+ level.write(levelObject);
+ levelArray.append(levelObject);
+ }
+ json["levels"] = levelArray;
+}
+//! [2]
+
+void Game::print(int indentation) const
+{
+ const QString indent(indentation * 2, ' ');
+ QTextStream(stdout) << indent << "Player\n";
+ mPlayer.print(indentation + 1);
+
+ QTextStream(stdout) << indent << "Levels\n";
+ for (Level level : mLevels)
+ level.print(indentation + 1);
+}
diff --git a/examples/corelib/serialization/savegame/game.h b/examples/corelib/serialization/savegame/game.h
new file mode 100644
index 0000000000..3da9c148be
--- /dev/null
+++ b/examples/corelib/serialization/savegame/game.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GAME_H
+#define GAME_H
+
+#include <QJsonObject>
+#include <QVector>
+
+#include "character.h"
+#include "level.h"
+
+//! [0]
+class Game
+{
+public:
+ enum SaveFormat {
+ Json, Binary
+ };
+
+ Character player() const;
+ QVector<Level> levels() const;
+
+ void newGame();
+ bool loadGame(SaveFormat saveFormat);
+ bool saveGame(SaveFormat saveFormat) const;
+
+ void read(const QJsonObject &json);
+ void write(QJsonObject &json) const;
+
+ void print(int indentation = 0) const;
+private:
+ Character mPlayer;
+ QVector<Level> mLevels;
+};
+//! [0]
+
+#endif // GAME_H
diff --git a/examples/corelib/serialization/savegame/level.cpp b/examples/corelib/serialization/savegame/level.cpp
new file mode 100644
index 0000000000..8eda107f46
--- /dev/null
+++ b/examples/corelib/serialization/savegame/level.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "level.h"
+
+#include <QJsonArray>
+#include <QTextStream>
+
+Level::Level(const QString &name) : mName(name)
+{
+}
+
+QString Level::name() const
+{
+ return mName;
+}
+
+QVector<Character> Level::npcs() const
+{
+ return mNpcs;
+}
+
+void Level::setNpcs(const QVector<Character> &npcs)
+{
+ mNpcs = npcs;
+}
+
+//! [0]
+void Level::read(const QJsonObject &json)
+{
+ if (json.contains("name") && json["name"].isString())
+ mName = json["name"].toString();
+
+ if (json.contains("npcs") && json["npcs"].isArray()) {
+ QJsonArray npcArray = json["npcs"].toArray();
+ mNpcs.clear();
+ mNpcs.reserve(npcArray.size());
+ for (int npcIndex = 0; npcIndex < npcArray.size(); ++npcIndex) {
+ QJsonObject npcObject = npcArray[npcIndex].toObject();
+ Character npc;
+ npc.read(npcObject);
+ mNpcs.append(npc);
+ }
+ }
+}
+//! [0]
+
+//! [1]
+void Level::write(QJsonObject &json) const
+{
+ json["name"] = mName;
+ QJsonArray npcArray;
+ foreach (const Character npc, mNpcs) {
+ QJsonObject npcObject;
+ npc.write(npcObject);
+ npcArray.append(npcObject);
+ }
+ json["npcs"] = npcArray;
+}
+//! [1]
+
+void Level::print(int indentation) const
+{
+ const QString indent(indentation * 2, ' ');
+ QTextStream(stdout) << indent << "Name:\t" << mName << "\n";
+
+ QTextStream(stdout) << indent << "NPCs:\n";
+ for (const Character &character : mNpcs)
+ character.print(2);
+}
diff --git a/examples/corelib/serialization/savegame/level.h b/examples/corelib/serialization/savegame/level.h
new file mode 100644
index 0000000000..393524abfd
--- /dev/null
+++ b/examples/corelib/serialization/savegame/level.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LEVEL_H
+#define LEVEL_H
+
+#include <QJsonObject>
+#include <QVector>
+
+#include "character.h"
+
+//! [0]
+class Level
+{
+public:
+ Level() = default;
+ Level(const QString &name);
+
+ QString name() const;
+
+ QVector<Character> npcs() const;
+ void setNpcs(const QVector<Character> &npcs);
+
+ void read(const QJsonObject &json);
+ void write(QJsonObject &json) const;
+
+ void print(int indentation = 0) const;
+private:
+ QString mName;
+ QVector<Character> mNpcs;
+};
+//! [0]
+
+#endif // LEVEL_H
diff --git a/examples/corelib/serialization/savegame/main.cpp b/examples/corelib/serialization/savegame/main.cpp
new file mode 100644
index 0000000000..d091684211
--- /dev/null
+++ b/examples/corelib/serialization/savegame/main.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <QTextStream>
+
+#include "game.h"
+//! [0]
+int main(int argc, char *argv[])
+{
+ QCoreApplication app(argc, argv);
+ QStringList args = QCoreApplication::arguments();
+ bool newGame = true;
+ if (args.length() > 1)
+ newGame = (args[1].toLower() != QStringLiteral("load"));
+ bool json = true;
+ if (args.length() > 2)
+ json = (args[2].toLower() != QStringLiteral("binary"));
+
+ Game game;
+ if (newGame)
+ game.newGame();
+ else if (!game.loadGame(json ? Game::Json : Game::Binary))
+ return 1;
+ // Game is played; changes are made...
+//! [0]
+//! [1]
+ QTextStream(stdout) << "Game ended in the following state:\n";
+ game.print();
+ if (!game.saveGame(json ? Game::Json : Game::Binary))
+ return 1;
+
+ return 0;
+}
+//! [1]
diff --git a/examples/corelib/serialization/savegame/savegame.pro b/examples/corelib/serialization/savegame/savegame.pro
new file mode 100644
index 0000000000..15a38c32ef
--- /dev/null
+++ b/examples/corelib/serialization/savegame/savegame.pro
@@ -0,0 +1,22 @@
+QT += core
+QT -= gui
+
+TARGET = savegame
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+# install
+target.path = $$[QT_INSTALL_EXAMPLES]/corelib/serialization/savegame
+INSTALLS += target
+
+SOURCES += main.cpp \
+ character.cpp \
+ game.cpp \
+ level.cpp
+
+HEADERS += \
+ character.h \
+ game.h \
+ level.h