|
|||||||||||
• Files |
Properties The idea behind the TProperty class involved creating a way for applets to exchange information at runtime. This generally occurs as the result of passing an event to the dispatcher via the Guildhall side of the event queue. I wanted that information to be reasonably extensible, so I decided I would use the TDictionary class (an array of named strings) as a member of every property. While this worked just fine, it put a lot of burden on code that used it to convert to other data types, most often boolean, integers, and floating point values. So I expanded it to a mix-in class of its own, MValues, and gave it four such members, TDictionary (as Snippet), TNamedNBoolArray (as Boolean), TNamedSHugeArray (as Integer), and TNamedFDualArray (as Floater). Note that none of these classes has a large footprint if not used, so it isn't a terribly expensive mix-in to add to a constructible class. And these four gave me a lot of extensibility. Then to make sure I had all the bases covered, I added a fifth array, the TDataFieldArray (as Manager), which names and stores any applet data type (subclasses of ADataType) that Guildhall understands. Thus far I have found at least one instance where it was a critical addition. To make that work the definition of ADataType had to be moved into the properties section. That seems a little out of place but it works. The implementation is still co-located with other archive object related classes. Each of the array types offers getters and setters of the following sort.
The Get functions (other than GetManager) will never throw exceptions if there is no value stored under the name provided. They just return zero or the empty string. That is sufficient for most callers but if not, the caller can check to see if a value is actually stored using the Has function. The Set function adds or modifies the value and the Nix function removes it, and both calls modify the update time maintained by the MValues object. It is also possible to link any MValues object to another MValues object as its time master. Any call to any of the Set or Get functions for any of the five array types will notify the time master that data has changed. In common usage, this process ultimately records any change to an applet's data, allowing it to be saved when the object is closed, including any time Guildhall quits normally. As I started to use the MValues class, its utility surprised me. I found it was often easier to store things like the elements of a point in the MValues section of an object as opposed to adding an explicit TPoint member, especially so since I didn't have to separately manage the update time. To make that easier, I added calls to MValue to support such additions, for example the following for TPoint values.
Extensions like this one operate by calling similar operations for each of the scalars in the object with the name extended with a suffix to describe each member. So GetPoint(const TString& name) would look for GetFloater(name + "_x") and GetFloater(name + "_y"). Over time I kept adding more and more such extensions, and the list has grown to include the following scalar types and classes.
And ultimately, MValues proved so useful that there were instances where I needed to include it as a member as opposed to a mix-in class. The TValues class is just a wrapper around MValues that makes it constructible. Now on to TProperty. As suggested earlier, its main purpose is to convey information from one Guildhall applet to another, including the Filer. It encapsulates a property name, subclasses from MValues, and contains a pointer to an anonymous persistent object as an AObject pointer. With the advent of the MValues architecture the AObject pointer is almost never used, but it's properly handled if needed. In some cases the name of the property is sufficient. For example, when the user changes the language using the flag menu, a specifically named property is propagated to all applets which causes them to update accordingly. For almost all other cases, the combination of the property name plus the data in the MValues mix-in allows for richly extensible inter-applet communication. Abstract Classes
Mix-in Classes
Constructible Classes
|