320 lines
13 KiB
C++
320 lines
13 KiB
C++
|
|
// -*- C++ -*-
|
|
|
|
|
|
namespace Hurricane {
|
|
|
|
|
|
/*! \defgroup inspectorManagment Inspector : Live Database Explorator (internal)
|
|
*
|
|
*
|
|
* \section sInspectorIntro Introduction
|
|
*
|
|
* The Hurricane Database provide a generic mechanism to allow
|
|
* the inspection of the whole data structure at run-time.
|
|
* The associated window/tool is called "The Inspector".
|
|
*
|
|
* In this section, we will describe how the inspection
|
|
* mechanism to new objects.
|
|
*
|
|
*
|
|
* \subsection ssSlotAdapter The SlotAdapter
|
|
*
|
|
* First, we introduce the SlotAdapter object. Any inspectable
|
|
* object has to be associated (see the next section) with a
|
|
* SlotAdapter. It's providing the following methods :
|
|
\code
|
|
class SlotAdapter {
|
|
public:
|
|
virtual string _GetTypename () const;
|
|
virtual string _GetString () const;
|
|
virtual Record* _GetRecord () const;
|
|
inline virtual Slot* _GetSlot ( const string& name ) const;
|
|
};
|
|
\endcode
|
|
*
|
|
*
|
|
* Thoses methods correspond to :
|
|
* <ul>
|
|
* <li>\b _GetTypeName() : the inspected object's type.
|
|
* <li>\b _GetString() : a synthetic string description of the
|
|
* object's state.
|
|
* <li>\b _GetRecord() : the complete description of all object's
|
|
* attributes (a list of Slot).
|
|
* <li>\b _GetSlot() : a Slot build from this SlotAdapter. As this
|
|
* function is supplied by default with the right implementation
|
|
* we will not detail it here.
|
|
* </ul>
|
|
*
|
|
*
|
|
* \subsection ssObjectTypology Typology of inspectables objects
|
|
*
|
|
* We distinguish three kind of objects, corresponding to three
|
|
* different ways of association to a SlotAdapter.
|
|
* <ul>
|
|
* <li><b>User defined, with virtual methods</b> : those objects
|
|
* must inherit from the NestedSlotAdapter class.
|
|
* <li><b>User defined, without virtual methods</b> : thoses
|
|
* objects must provides (as ordinary methods)
|
|
* \b _GetTypeName() , \b _GetString() , \b _GetRecord() .
|
|
* But \b not \b _GetSlot().
|
|
* <li><b>External objects</b> : that is, we cannot modify.
|
|
* In this case we have to provide a specialised template
|
|
* overload for \b ProxyTypeName<>() , \b ProxyString<>() ,
|
|
* and \b ProxyRecord<>() (see \ref ssExternalObjects).
|
|
* </ul>
|
|
*
|
|
*
|
|
* \subsection ssUserDefinedVirtual User Defined Object with virtual methods
|
|
*
|
|
* This approach should be preferrred for complex objects
|
|
* that are persistents in memory.
|
|
*
|
|
* Example of implementation :
|
|
\code
|
|
namespace MyTool {
|
|
class MyClass : public NestedSlotAdapter {
|
|
protected:
|
|
int _value;
|
|
public:
|
|
int GetValue () const { return _value; }
|
|
virtual string _GetTypeName() const { return "MyClass"; };
|
|
virtual string _GetString () const { return "<MyClass"+GetString(_value)+">"; };
|
|
virtual Record* _GetRecord () const;
|
|
};
|
|
|
|
Record* MyClass::GetRecord () const {
|
|
Record* record = new Record(_GetString());
|
|
record->Add ( GetSlot("_value",&_value) );
|
|
return record;
|
|
}
|
|
} // End of MyTool namespace.
|
|
|
|
SetNestedSlotAdapter(MyTool::MyClass)
|
|
\endcode
|
|
*
|
|
* \e MyClass derives from NestedSlotAdapter. Any derived class of
|
|
* \e MyClass will inherit of it, so you do not have to (and musn't)
|
|
* repeat the inheritance from NestedSlotAdapter.
|
|
*
|
|
* \e SetNestedSlotAdapter() must be put outside any namespace.
|
|
*
|
|
* \e SetNestedSlotAdapter() must never be called on objects that do
|
|
* not derives from NestedSlotAdapter. There's builtin safety :
|
|
* a \c static_cast into NestedSlotAdapter that will make the
|
|
* compiler fail.
|
|
*
|
|
* \e SetNestedSlotAdapter() may be omitted, at the cost of generating
|
|
* a intermediary SlotAdapter (that will cost two pointers). Nevertheless
|
|
* it will work.
|
|
*
|
|
*
|
|
* \subsection ssUserDefinedWithoutVirtual User Defined Object without virtual methods
|
|
*
|
|
* This implementation should be preferred for light objects
|
|
* that are instanciated in vast amounts (we gain the \e vtable
|
|
* pointer over the previous approach).
|
|
*
|
|
* Example of implementation :
|
|
\code
|
|
namespace MyTool {
|
|
class MyLightClass {
|
|
protected:
|
|
int _value;
|
|
public:
|
|
int GetValue () const { return _value; }
|
|
string _GetTypeName() const { return "MyLightClass"; };
|
|
string _GetString () const { return "<MyLightClass"+GetString(_value)+">"; };
|
|
Record* _GetRecord () const;
|
|
};
|
|
|
|
Record* MyLightClass::GetRecord () const {
|
|
Record* record = new Record(_GetString());
|
|
record->Add ( GetSlot("_value",&_value) );
|
|
return record;
|
|
}
|
|
} // End of MyTool namespace.
|
|
\endcode
|
|
*
|
|
* The methods \b _GetTypeName() , \b _GetString() and \b GetRecord()
|
|
* are now non-virtual and there's no call to \b SetNestedSlotAdapter() .
|
|
*
|
|
*
|
|
* \subsection ssExternalObjects External Objects
|
|
*
|
|
* This is the implementation to uses for managing objects
|
|
* from other libraries that we should want to browse in the
|
|
* Inspector. In this case we have to provide three overload
|
|
* of template functions, as shown below (for boolean type) :
|
|
\code
|
|
template<>
|
|
inline string ProxyTypeName<bool> ( const bool* object ) { return "<PointerSlotAdapter<bool>>"; }
|
|
|
|
template<>
|
|
inline string ProxyString<bool> ( const bool* object ) { return (*object)?"True":"False" ; }
|
|
|
|
template<>
|
|
inline Record* ProxyRecord<bool> ( const bool* object ) { return NULL; }
|
|
\endcode
|
|
*
|
|
*
|
|
* \section sGetStringAndGetSlot GetString() and GetSlot() functions
|
|
*
|
|
* When a class or type is provided with Inspector support,
|
|
* you may uses the two generic functions below :
|
|
\code
|
|
template<typename T> inline string GetString ( T* t );
|
|
template<typename T> inline string GetString ( T t );
|
|
template<typename T> inline Hurricane::Slot* GetSlot ( const string& name, T* t );
|
|
template<typename T> inline Hurricane::Slot* GetSlot ( const string& name, T t );
|
|
\endcode
|
|
*
|
|
* GetString() may be used to print some debugging informations
|
|
* on \stdout.
|
|
*
|
|
* GetSlot() used to built the various entries in a \b _GetRecord()
|
|
* method.
|
|
*
|
|
* <b>Argument type policy</b>
|
|
*
|
|
* As you noticed there are two overload for each function,
|
|
* one with pointer argument, the other with a value argument.
|
|
* This is meaningful :
|
|
* <ul>
|
|
* <li>Passing by pointer means that the data being inspected
|
|
* is persistent, and should not be deleted once the
|
|
* inspector is closed. This is the case of all DBo
|
|
* objects and, for example, Box objects when they are
|
|
* attributes of another object.
|
|
* <li>Passing by value, means that the data is volatile and
|
|
* should be deleted at the inspector closing. As an
|
|
* example, the bounding box of an instance which is
|
|
* computed on the fly, we must copy the result into
|
|
* the SlotAdapter but no longer need it afterwards.
|
|
* An important consequence is that thoses objects
|
|
* must have a valid copy constructor.
|
|
* </ul>
|
|
*
|
|
* <b>Default type support</b>
|
|
*
|
|
* Hurricane provide support for the following types :
|
|
* <ul>
|
|
* <li><b>const char</b>
|
|
* <li><b>const char*</b>
|
|
* <li><b>const string*</b>
|
|
* <li><b>const bool*</b>
|
|
* <li><b>const void*</b>
|
|
* <li><b>const int*</b>
|
|
* <li><b>const long*</b>
|
|
* <li><b>const unsigned int*</b>
|
|
* <li><b>const unsigned long*</b>
|
|
* <li><b>const unsigned long long*</b>
|
|
* <li><b>const unsigned short int*</b>
|
|
* <li><b>const float*</b>
|
|
* <li><b>const double*</b>
|
|
* </ul>
|
|
* Note that, as long as the pointer type is supported, the value
|
|
* is also (except for the \b char type which has a somewhat more
|
|
* complex behavior).
|
|
*
|
|
* It also provide support for the following \STL containers :
|
|
* <ul>
|
|
* <li><b>const vector<Element>*</b>
|
|
* <li><b>const list<Element>*</b>
|
|
* <li><b>const map<Key,Element,Compare>*</b>
|
|
* <li><b>const set<Element,Compare>*</b>
|
|
* <li><b>const multiset<Element,Compare>*</b>
|
|
* </ul>
|
|
*
|
|
*
|
|
* \section sIOStreamSupport Support for iostream
|
|
*
|
|
* If an object (with inspector support) is often printed into
|
|
* a stream, you may define an overload of \b operator<<() with
|
|
* either the \b PointerIOStreamSupport() or \b ValueIOStreamSupport()
|
|
* macros. The macros must in the top-level namespace.
|
|
*
|
|
*
|
|
* \section sLastNote A note for myself
|
|
*
|
|
* About the deletion mechanism : there are two level of deletion,
|
|
* the SlotAdapter deletion and the object deletion.
|
|
*
|
|
* Object deletion is managed by the SlotAdapter : if the SlotAdapter
|
|
* is nested in the object, do not delete, otherwise delete.
|
|
*
|
|
* SlotAdapter deletion is managed at Slot level : if the object
|
|
* is passed by pointer, do not delete the SlotAdapter. if the object
|
|
* is passed by value, delete the SlotAdapter.
|
|
*/
|
|
|
|
|
|
//! \addtogroup inspectorManagment
|
|
//! \{
|
|
|
|
/*! \class SlotAdapter
|
|
* \brief Root class. Provide support for duplicatable objects (\b internal).
|
|
*/
|
|
|
|
/*! \class NestedSlotAdapter
|
|
* \brief Provide Inspector support for non-duplicatable (\b internal).
|
|
*/
|
|
|
|
/*! \class PointerSlotAdapter
|
|
* \brief Provide Inspector support for external persistant objects (\b internal).
|
|
*/
|
|
|
|
/*! \class ValueSlotAdapter
|
|
* \brief Provide Inspector support for external volatile objects (\b internal).
|
|
*/
|
|
|
|
// \}
|
|
|
|
/*! \name Accessors
|
|
*/
|
|
// \{
|
|
|
|
/*! \function string SlotAdapter::_GetTypeName () const;
|
|
* \Return a string representing the object type. May be used by
|
|
* SlotAdapter::_GetString().
|
|
*
|
|
* \note No default implementation is supplied.
|
|
*/
|
|
|
|
/*! \function string SlotAdapter::_GetString () const;
|
|
* \Return a string representing the object name and characteristics
|
|
* in a synthetic way. Used, among other things, as title
|
|
* for the Inspector Record browser.
|
|
*
|
|
* \note Default implementation is supplied, which returns the
|
|
* string \c "SlotAdapter::_GetString()" .
|
|
*/
|
|
|
|
/*! \function Record* SlotAdapter::_GetRecord () const;
|
|
* \Return a Record representing the object current state.
|
|
*
|
|
* \note Default implementation is supplied, which returns \NULL.
|
|
*/
|
|
|
|
/*! \function Slot* SlotAdapter::_GetSlot ( const string& name ) const;
|
|
* \param name the name to give to the Slot. Usually the class attribute
|
|
* name.
|
|
* \return a Slot associated to this object to insert into another Record.
|
|
* As SlotAdapter is for user-defined objects without virtual
|
|
* method the SlotAdapter is created aside to the inspected
|
|
* object and must be removed afterwards, so we uses a ValueSlot.
|
|
*/
|
|
|
|
|
|
/*! \function Slot* NestedSlotAdapter::_GetSlot ( const string& name ) const;
|
|
* \param name the name to give to the Slot. Usually the class attribute
|
|
* name.
|
|
* \return a Slot associated to this object to insert into another Record.
|
|
* NestedSlotAdapter is for user-defined objects with virtual
|
|
* method, it must be a base class of the object, and as such
|
|
* the object \e is the SlotAdapter. So the removal of the Slot
|
|
* must left the SlotAdapter, for this we uses a PointerSlot.
|
|
*/
|
|
|
|
}
|