DescribeIO Manual

About

A custom data type or an implementation of an interface will contain some internal data. A static custom DescribeIO() function describes how this data is written to or from a file.

Note
DescribeIO() does not directly access the file but instructs Cinema 4D how to handle the data.

Data Serialization

A DescribeIO() function handles the given maxon::DataSerializeInterface argument. This object should not be handled directly; only with these macros:

  • PrepareDescribe(): Starts a description. Must happen before any Describe() calls are made.
  • Describe(): Describes a class member for I/O operations.
  • DescribeOther(): Describes a class member for I/O operations. Allows to cast to a different DataType before the description is made.
  • DescribeLegacy(): Describes a legacy element that is no longer needed.

Certain elements may only be handled if a certain condition is fulfilled:

This snippet shows a simple custom data type:

This is the straightforward implementation of DescribeIO().

DescribeIO() is invoked when an instance of the data type is written to or read from a file:

// This example creates an instance of a custom data type that implements DescribeIO().
// The instance is saved to a file using maxon::WriteDocument(). After that,
// maxon::ReadDocument() is used to read the data from the given file.
// define data
SimpleTriplet triplet;
triplet._a = 100;
triplet._b = 200;
triplet._c = 300;
// file URL
const maxon::Url url = (targetFolder + "triplet.txt"_s)iferr_return;
const maxon::Id fileID { "net.maxonexample.simpletriplet" };
// save to file
// read from file
SimpleTriplet loadedTriplet;
maxon::ReadDocument(url, fileID, loadedTriplet) iferr_return;
// display loaded data
DiagnosticOutput("Loaded Triplet: @, @, @", loadedTriplet._a, loadedTriplet._b, loadedTriplet._c);
Definition: apibaseid.h:243
Definition: url.h:945
#define DiagnosticOutput(formatString,...)
Definition: debugdiagnostics.h:170
std::enable_if< GetCollectionKind< T >::value==COLLECTION_KIND::ARRAY, Result< void > >::type ReadDocument(const Url &url, const Id &id, T &object, const DataDictionary &dict=DataDictionary())
Definition: io.h:40
Result< void > WriteDocument(const Url &url, OPENSTREAMFLAGS flags, const Id &id, const T &object, IOFORMAT format=IOFORMAT::DEFAULT, const DataDictionary &dict=DataDictionary())
Definition: io.h:72
@ NONE
No flags set.
#define iferr_return
Definition: resultbase.h:1771

The write-process will result in a file like this:

{
"identification": "net.example.simpletriplet",
"content": {
"_a": 100,
"_b": 200,
"_c": 300
}
}

Helper Classes

A helper class is used to define code that is executed when Cinema 4D handles the data. The helper class is used with these macros:

  • PrepareHelper(): Declares and initializes an I/O helper class.
  • DescribeHelper(): Describes a helper class member for I/O operations
  • DescribeHelperIf(): Describes a helper class member for I/O operations and compares its value.
  • CONSTHASH(): Expression to calculate the hash code of a member name during compile time. Such a hash value is needed in WriteAction() and ReadAction().

This will result in a file like this:

{
"identification": "net.example.helpertriplet",
"content": {
"data": "100::200::300"
}
}

This more complex example uses DescribeHelperIf():

A "compact" file using the same value for each channel will look like this:

{
"identification": "net.example.compacttriplet",
"content": {
"_compact": true,
"_compactValue": 100
}
}

A non-compact file will look like this:

{
"identification": "net.example.compacttriplet",
"content": {
"_compact": false,
"_x": 10,
"_y": 100,
"_z": 1000
}
}

Further Reading