Game Programming Using Qt Beginner's Guide
上QQ阅读APP看书,第一时间看更新

Time for action – serialization of a custom structure

Let's perform another small exercise by implementing functions that are required to use QDataStream to serialize the same simple structure that contains the player information that we used for text streaming:

struct Player {
  QString name;
  qint64 experience;
  QPoint position;
  char direction;
};

For this, two functions need to be implemented, both returning a QDataStream reference that was taken earlier as an argument to the call. Apart from the stream itself, the serialization operator accepts a constant reference to the class that is being saved. The most simple implementation just streams each member into the stream and returns the stream afterwards:

QDataStream& operator<<(QDataStream &stream, const Player &p) {
  stream << p.name;
  stream << p.experience;
  stream << p.position;
  stream << p.direction;
  return stream;
}

Complementary to this, deserializing is done by implementing a redirection operator that accepts a mutable reference to the structure that is filled by data that is read from the stream:

QDataStream& operator>>(QDataStream &stream, Player &p) {
   stream >> p.name;
   stream >> p.experience;
   stream >> p.position;
   stream >> p.direction;
   return stream;
}

Again, at the end, the stream itself is returned.

What just happened?

We provided two standalone functions that define redirection operators for the Player class to and from a QDataStream instance. This lets your class be serialized and deserialized using mechanisms offered and used by Qt.

XML streams

XML has become one of the most popular standards that is used to store hierarchical data. Despite its verbosity and difficulty to read by human eye, it is used in virtually any domain where data persistency is required, as it is very easy to read by machines. Qt provides support for reading and writing XML documents in two modules. First, the QtXml module provides access using the Document Object Model (DOM) standard with classes such as QDomDocument, QDomElement, and others. We will not discuss this approach here, as now the recommended approach is to use streaming classes from the QtCore module. One of the downsides of QDomDocument is that it requires us to load the whole XML tree into the memory before parsing it. In some situations, this is compensated for by the ease of use of the DOM approach as compared to a streamed approach, so you can consider using it if you feel you have found the right task for it.

Tip

If you want to use the DOM access to XML in Qt, remember to enable the QtXml module in your applications by adding a QT += xml line in the project configuration files.

As already said, we will focus on the stream approach implemented by the QXmlStreamReader and QXmlStreamWriter classes.