On 13/12/2015 at 04:59, xxxxxxxx wrote:
Well, changing the description IDs is the one thing you should never do if you want the new version to load old scenes. The description IDs are the connection between the GUI, the internationalized text files, and the values in a BaseContainer, so if you move IDs around, all the saved values in your old files get jumbled.
For example, if you originally saved the value MY_PLUGIN_POSITION_X as ID 1001, and now it's 1002 and the ID 1001 is re-used for MY_PLUGIN_POSITION_Y, then all your old X values appear as Y, and the current X gets the defaults. (Even worse if the data types of the saved IDs do not match the data types that the new version expects.)
So, once you have released a plugin ("released" meaning: you or other people have actual scenes saved with that plugin in it), you must not ever assign a new ID to an existing description. You can "retire" a description by simply not using it any more, but the ID of that description must not be reused (keep it in your .h definition with a comment). You can also add a new description which then will be assigned the default value for all old scenes, but it must have a new ID that has not been used in old versions of the plugin.
The advantage of the BaseContainer is that it is semantically agnostic; it just saves a set of values with certain numeric IDs and certain data types which are known to C4D. That means as long as you use a BaseContainer to store values, you cannot break the file loading process. You also do not need to bother about reading, writing, or copying a BaseContainer since the container itself knows how to.
(A different case would be if you use custom data types; since C4D does not know how these are structured, you need to implement ReadData, WriteData, CopyData and Compare functions. In this case you use the disklevel to determine whether a file was written by an old version of the plugin, and implement the appropriate read functionality for each disklevel.)
However, "semantically agnostic" also means that the responsibility of the interpretation of the contained values is left to the higher levels - the plugin itself, or the standard C4D functions that it calls (like showing a description). And that in turn means you cannot just redefine an ID to have a different semantics.
An update to a plugin that is already used needs careful planning to keep as much data from old versions as possible (which means keeping the IDs for these values intact).
If there is no meaningful reuse for these values, it might be prudent to simply treat the new plugin as something completely different, get a new PluginID for it, and perform the migration from the old plugin manually.
If you think that your old scenes are worth saving, you may try the following (but be aware that I never did something like this, so it's speculative...) :
1. Overwrite the Read() function of your Node. This should work since the method is virtual.
2. In that overwrite, first call the parent class's Read(), so all the actual disk access is done.
3. Then try to recognize whether the data in the just-read BaseContainer is from the old or the new version (for example, by reading a value that is only present in the new version, or maybe you have defined a Disklevel for the container already...)
4. If the data is from the old version, create a new BaseContainer and perform a mapping from the old values with their old IDs to the new values with their new IDs. Store all the new values with the new IDs in the new container.
If the data is from the new version, you don't need to do anything.
5. Replace the container in the NodeData with the new container which is now adapted to the new IDs and values.
... 6. Tell me if that worked, so I don't have to test it myself ;-)