Reflect Object Class Hierarchy
From Nocturnal Initiative
Contents |
Object Class Hierarchy
The most user-facing class hierarchy in Reflect is the Object Class Hierarchy. It provides the base classes that client APIs will subclass to implement its desired purpose.
Reflect::Object
Object is the base class of objects that Reflect can manipulate and introspect into. It implements some of the most basic virtual API in Reflect:
Reference Counting:
int GetRefCount() const; void IncrRefCount() const; void DecrRefCount() const;
Type Checking:
virtual i32 GetType() const; virtual bool HasType(i32 type) const;
Reflection:
virtual const Reflect::Class* GetClass() const; static void EnumerateClass( Reflect::Compositor<Element>& comp );
Reflect::Element : public Reflect::Object
Element is the base class for any object that can be serialized. Element declares more virtual API for handling serialization to and from Archive files. Beyond serialization Element declares the base virtual API used for introspection:
virtual void Host(Visitor& visitor);
Host is the entry point for the visitor API. By default the visitor visits all fields of this Element, and hosts all the Elements it references.
virtual bool Equals(const ElementPtr& rhs) const;
Equals performs and equality check with another base class pointer. The equality checking can be deep or shallow depending on what flags exist on individual fields in the Element.
virtual void CopyTo(const ElementPtr& destination);
CopyTo performs a member-wise copy of compatible data from this Element to the destination. Typically this is used to copy data of a base class from one derived class to another polymorphic derived class.
virtual ElementPtr Clone() const;
Finally, Clone creates a copy of this Element. Based on the same information that Equals uses, this can be shallow or deep at different stages depending on field flags.
Reflect::Serializer : public Reflect::Element
Serializer is worker base class that is used by Archive to do serialization and comparison logic. Serializer derived classes are meant to know intimate details of a given data type, and hence it encapsulates the logic to serialize and compare that data type. Archive will create instances of Serializers to do the actual work of authoring and parsing flat files. Serializers can hold their own instance of the data type they encapsulate as well as work with an address in memory where an instance of its data type is located. Because of this Serializers can be connected to the fields of Elements to do serialization and comparison logic.
Serializers can also notify objects when they are changed, and this is used extensively within Nocturnal's data-driven UI framework Inspect and InspectReflect to cause interesting things to happen when data is changed through UI.
Serializer contains the casting API used by Archive to do automatic casting of compatible data types:
static bool CastValue(const Serializer* src, Serializer* dest, SerializerFlag flags);
Internally it utilizes boost::numeric_cast to do range-checked casting. Reflect supports casting convertible types directly as well as casting between containers types that use convertible types. This means that Reflect can cast a std::set<i32> to a std::set<float>.
Reflect::Version : public Reflect::Element
Version is a simple derived class of Element, and is a good example of a simple Element that has field-level reflection information. As a convention, Archive will store a Version-derived instance at the front of every file it writes. This is done to aid analysis of any broken files that will not load correctly, and to track which application authored any given file.
