Code I've started writing almost year ago (new configuration API) have grown to whole new layer of code. Now it is called Kadu Storage API and this is the first thing that will get documentation (by Doxygen) for new release.
This API has some really nice features:
Some classes, like Contact or Chat, have data that depends on some plugins (like XMPP/Jabber contact data, or Gadu-Gadu contact data, or IRC chatroom data, or ...). We want to give user view to this data even if plugin is not loaded/unavailable for some reason. So as much data as possible were extracted to generic classes like Contact, Chat, or Account (see how much extra data Gadu-Gadu needs for Account).This data can be loaded from Storage at any moment and be displayed to user and manipulated.
But that data cannot be used to do anything useful: you can't talk with someone on XMPP account if Jabber plugin is not loaded (but you can view this chat history). So when the plugin is loaded every object that depends on it loads extra data by using specific Details class. This class uses the same StoragePoint as main class so it can load extra data from the same configuration node. After extra data is loaded, the object can be used (to connect to server, make some chat and so on).
Shared classes bring some Java-like API to Kadu. It is just a trick to hide that given class is really a pointer. Just a good usage of QExplicitlySharedDataPointer and QSharedData. But with lazy-loading and StorableObject support ;)
Kadu has now two generic (template-based) managers: Manager and SimpleManager. The first one has built-in support for classes that use Details (like DetailsHolder subclasses) - it only exposes object without Details loaded when code explicitly asks for that. Just look for ChatManager implementation to see how little code is now needed to implement manager that fully supports loading/storing and many more features using these generics:
Simple constructors and intuitive behavior of StorableObject
StorableObject class (and all subclasses) has now only one constructor (instead of 4). Passing parent objects, node names and so on in constructors was replaced with nice virtual functions.
This class has now State field. It can has three values: StateLoaded, StateNotLoaded, StateNew. Code of load method is executed only if the state is StateNotLoaded. By default object is treated as "new" (so no need to load, but only default data is available). To make object "not loaded" (so it will be eventually "loaded") you need to set up its StoragePoint using setStorage method.
All that simple changes give more natural and intuitive feel of how this object behave. It also allows us to remove some code, because these new default are what we need in most of our code.
What is next?
After Doxygen documentation for Storage is written, I'll focus myself on little higher layers: Buddy Storage, Chat Storage, anything Storage to make sure everything is nice and clean ;)