serialize and deserialize in a way that makes room for changes to file format
andrewrk opened this issue · comments
Currently, serializing and deserializing operates on the fields serially and the code to serialize and deserialize is hard coded. This is problematic for two reasons:
- it's easy to make a mistake when adding or modifying features that results in silent critical errors.
- makes project file format completely backwards incompatible
Instead, each serializable thing should have a list of fields. Each field would have:
- enum value for which field it is (the "key") - this identifies the field in the file
- enum value for what type the field is
- callback which should return the pointer to the field given an instance of the class
- callback for setting the default value. if this is null, then if the field is missing it is considered an invalid format error
To serialize:
- write the number of fields
- iterate over the fields
- save space for 4 bytes to write the length of this field
- write the field identifier enum value (the "key")
- call the callback to get the pointer for the field
- based on the type of the field, call the appropriate serialize function using the field pointer
- go back and write the size in the space saved above
To deserialize:
- read the number of fields
- for as many as there are:
- read the length of this field
- read the field identifier
- if the field identifier is unrecognized, use the field length to skip this field. possibly make note of this situation and warn the user that the file contained unrecognized information.
- call the callback to get the pointer to the field
- based on the type of the field, call the appropriate deserialize function using the field pointer
- mark the field as found
- iterate over the fields
- if the field is not found, call the callback for setting the default value
- if the default value callback is null, then deserializing resulted in an invalid format error