The module general is used by all other modules. It contains classes etc. that can be used in all other modules. a2dObject and its derived dynamic property classes are in this module. While the class a2dPropObject can hold dynamic properties in a property list. Another one is a2dSmrtPtr, which is a smart pointer template class. It works for classes with a Release and Own mechanism, which are all a2dObject derived classes. The Special a2dEvtHandler is defined here. It is almost equal to wxWidget its wxEvtHandler, only this one is derived from a2dObject instead. This makes it possible to serialize event handling classes. Serialization is done via wxDocviewIOHandlerXmlSer, which is in principle an XML parser, which uses wxWidget RTTI for creation of objects from classname strings. All in and output to and from objects can be implemented using a2dIOHandler. A special one is using the visitor design pattern a2dWalkerIOHandler, which can be used to iterate through hierarchies of a2dObject's.
This class implements reference counting and serialization. In many wxArt2D classes, pointer reference counting is used, it uses an Own and Release principle. The last objectX which owns an objectY will really delete the objectY when it releases that object. All the other Objects owning objectY will just lower the reference count when they release it. The class a2dSmrtPtr, which is a smart pointer template class, makes it very easy to use pointer reference counting. All Own and Release calls will be done automatically. For serialization of a2dObject hierarchies, there are Save and Load methods. This uses Serialisation for parsing and writing XML class data. In order to give classes serialization, you derive them from a2dObject.
The dynamic properties are very important in wxArt2D, they are used to store data into classes which is not always there. And as such a prefect way to add data to classes without extending its memory usage permanently. For instance when editing a graphical object, all data that is needed temporarely to edit such an object, is stored as dynamic properties. Finishing the editing will free all dynamic properties, and brings back the object to its low memory usage. Another use is adding data to existing objects by user a program, without extending the class ( which is inside the library ). The last use is for storing undo data. The data that is modified inside a class is wrapped inside a property. So for class members it is wrapped into a a2dNamedProperty derived class. But when it is already a dynamic property on the object, its is simply refcounted once more. The data collected like a property is stored inside a property command. The command is containing the data before the change and after the change of the class. This command is placed on the undo stack. By storing changed data into a property class, and using this as an interface towards objects, it is sufficient to have only one command class. If not using such a system, one would need to define a specific command class for all different types of data changes to an object. In order to cope with many types of data, there is a range of a2dNamedProperty derived classes, each used for a different type of data. You can also define your own types, using complex internal data structure if needed. When setting a property to a class, the class itself is responsible for translating the property contents back to its internal data.
All classes with the ability to have dynamic properties attached to it, are derived from this class. Dynamic properties are a2dObject's derived, which are added to a a2dObjectList within the a2dPropObject. Serialization to or from a file for those properties is automatic. The properties can be used to stored almost any kind of data. In wxArt2D stroke and fill properties are stored as dynamic properties in a drawable canvas object. But also for user data or temporary data the properties can be used. The a2dPropObject has a range of functions to add, remove, modify, find etc. a property.
For event handling object, which or not wxWindow derived, this is used as a base class. This class is almost a direct copy of the wxWidget wxEvtHandler. This last is directly derived from wxObject, while a2dEvtHandler is derived from a2dObject. Therefore all those event handling classes in wxArt2D can be reference counted and serialized. The defenitions of an event table, is equal to the wxWidget normal event table, but instead of EVT_ you need to use A2D_EVT_ like this:
a2dIOHandlerXmlSerIn and a2dIOHandlerXmlSerOut
Class a2dIOHandlerXmlSerIn and a2dIOHandlerXmlSerOut are used by a2dObject and derived classes to load and save class data to an XML serialization format. Since these classes input and output to a a2dDocument, the classes are derived from a2dIOHandlerStrIn and a2dIOHandlerStrOut at the bottom. The class a2dIOHandlerXmlSerIn internal uses expat for parsing XML data, and a2dIOHandlerXmlSerOut has functionality to easily write XML data to a file. The serialization format is using wxWidget RTTI to create classes based on the classname string. Your own classes can easily be serialized in the same form. An important feature is that it supports hierarchies of class data, including reference counted objects. So one object can be used by several parent objects. When reading from a file those references are resolved automatically. Parsing of the XML data is directly from a stream, and no DOM structure is used in between, this way of parsing XML data is called Pull parsing. The functions to save and load data are integrated with the classes itself. Hierarchies of classes via child objects, are easily reconstructed from a file, also multiple child branches ( one in the base class, one in a derived class ), are reloaded properly.
Design considerations of the general and docview module
(MS: Moved here from DocviewModule, need to integrate)
* Why is there a a2dObject
The a2dObject class is derived from wxObject.
Smart pointers are used all over the wxArt2D library. They have many advantages, but the main one is that deletion is done when the last smart pointer holding on to an object is getting out of scope. In other words, deletion is automatic. And this helps a lot in designing a robust docview framework. To name a simple one: a document is deleted only when all smart pointer to it are deleted.
For using smart pointers one needs in the object that the smart pointer is pointing to a reference count. When it reaches zero the object will be deleted. That is why there is a2dObject. Next to this a2dObject is the base class for almost all objects in the library, and the serialization using XML needs it. Especially since wxArt2D its graphical documents, contain multiple references to graphical canvas objects, and this requires a special approach when saving to save such objects.
No the bad thing. If a derived a2dObject class needs event handling, wxEvtHandler is not possible anymore. And so all event handling in wxWidgets itself, needs to be copied but this time with a2dObject in between.
This holds all need to store dynamic properties, in is in between a2dObject and a2dEvtHandler, because i wanted to prevent that all object needing properties would automatically get event handling.
A light wait event handler for canvas object was needed. It is normal to store thousands of objects in a canvas document, doing this using wxEvtHandler is no good. But even if anted, it would not be possible, because a2dObject is needed for its reference counting for smart pointers, and the serialization. As said a2dObject is used as base class for almost all classes. Therefore if such a class needs event handling it nees to derive from a2dEvtHandler. This is why most classes in the docview framework use a2dEvtHandler as base, and its event tables are defined accordingly. Still the whole wxEvtHandler code is very simular to the a2dEvtHandler code.