mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
CAF: Support class keyword aliases and a scriptable feature
* Also store class keyword in fields so they can be assigned to the correct Python object even if the class itself is abstract.
This commit is contained in:
parent
83a7ceb204
commit
c63c7f2eac
@ -67,6 +67,33 @@ bool PdmFieldHandle::matchesKeyword(const QString& keyword) const
|
||||
return matchesKeywordAlias(keyword);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The class of the ownerObject() can be different to ownerClass().
|
||||
/// This is because the ownerClass() may be a super-class to the instantiated owner object.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmObjectHandle* PdmFieldHandle::ownerObject()
|
||||
{
|
||||
return m_ownerObject;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Get the class in the class hierarchy the field actually belongs to.
|
||||
/// This can be different to ownerObject's class, which may be a sub-class.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmFieldHandle::ownerClass() const
|
||||
{
|
||||
return m_ownerClass;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// Set the class in the class hierarchy the field actually belongs to.
|
||||
/// This can be different to ownerObject's class, which may be a sub-class.
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void PdmFieldHandle::setOwnerClass(const QString& ownerClass)
|
||||
{
|
||||
m_ownerClass = ownerClass;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -24,12 +24,14 @@ public:
|
||||
|
||||
QString keyword() const { return m_keyword; }
|
||||
bool matchesKeyword(const QString& keyword) const;
|
||||
PdmObjectHandle* ownerObject() { return m_ownerObject; }
|
||||
PdmObjectHandle* ownerObject();
|
||||
QString ownerClass() const;
|
||||
|
||||
// Child objects
|
||||
bool hasChildObjects();
|
||||
virtual void childObjects(std::vector<PdmObjectHandle*>*) { }
|
||||
virtual void removeChildObject(PdmObjectHandle*) { }
|
||||
void setOwnerClass(const QString& ownerClass);
|
||||
|
||||
// Ptr referenced objects
|
||||
bool hasPtrReferencedObjects();
|
||||
@ -58,6 +60,7 @@ private:
|
||||
friend class PdmObjectHandle; // Give access to m_ownerObject and set Keyword
|
||||
void setKeyword(const QString& keyword);
|
||||
PdmObjectHandle* m_ownerObject;
|
||||
QString m_ownerClass;
|
||||
|
||||
QString m_keyword;
|
||||
|
||||
|
@ -17,6 +17,22 @@ PdmObjectHandle::~PdmObjectHandle()
|
||||
this->prepareForDelete();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString PdmObjectHandle::classKeywordStatic()
|
||||
{
|
||||
return classKeywordAliases().front();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> PdmObjectHandle::classKeywordAliases()
|
||||
{
|
||||
return { QString("PdmObjectHandle") };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include "cafAssert.h"
|
||||
#include "cafPdmBase.h"
|
||||
|
||||
class QString;
|
||||
#include <QString>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
@ -26,6 +26,9 @@ public:
|
||||
PdmObjectHandle() { m_parentField = nullptr; }
|
||||
virtual ~PdmObjectHandle();
|
||||
|
||||
static QString classKeywordStatic(); // For PdmXmlFieldCap to be able to handle fields of PdmObjectHandle directly
|
||||
static std::vector<QString> classKeywordAliases();
|
||||
|
||||
/// The registered fields contained in this PdmObject.
|
||||
void fields(std::vector<PdmFieldHandle*>& fields) const;
|
||||
PdmFieldHandle* findField(const QString& keyword) const;
|
||||
@ -112,8 +115,6 @@ private:
|
||||
template < class T > friend class PdmField; // For backwards compatibility layer
|
||||
|
||||
template < class T > friend class PdmFieldXmlCap;
|
||||
|
||||
static const char* classKeywordStatic() { return "PdmObjectHandle";} // For PdmXmlFieldCap to be able to handle fields of PdmObjectHandle directly
|
||||
|
||||
// Support system for PdmPointer
|
||||
friend class PdmPointerImpl;
|
||||
|
@ -79,7 +79,7 @@ void PdmDocument::readFile(QIODevice* xmlFile)
|
||||
xmlStream.readNext();
|
||||
if (xmlStream.isStartElement())
|
||||
{
|
||||
if (xmlStream.name() != classKeyword())
|
||||
if (!matchesClassKeyword(xmlStream.name().toString()))
|
||||
{
|
||||
// Error: This is not a Ceetron Pdm based xml document
|
||||
return;
|
||||
|
@ -2,6 +2,17 @@
|
||||
|
||||
using namespace caf;
|
||||
|
||||
CAF_PDM_ABSTRACT_SOURCE_INIT(PdmObject, "PdmObject");
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmObject::PdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false), PdmUiObjectHandle(this, false)
|
||||
{
|
||||
CAF_PDM_InitObject("Base PDM Object", "", "", "The Abstract Base Class for the Project Data Model");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -89,35 +100,10 @@ void PdmObject::childrenFromClassKeyword(
|
||||
for (auto childObject : childObjects)
|
||||
{
|
||||
PdmObject* pdmObjectChild = dynamic_cast<PdmObject*>(childObject);
|
||||
if (pdmObjectChild && pdmObjectChild->classKeyword() == classKeyword)
|
||||
if (pdmObjectChild && pdmObjectChild->matchesClassKeyword(classKeyword))
|
||||
{
|
||||
children.push_back(pdmObjectChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmObject::PdmObject() : PdmObjectHandle(), PdmXmlObjectHandle(this, false), PdmUiObjectHandle(this, false)
|
||||
, m_scriptable(false)
|
||||
{
|
||||
registerClassKeyword(classKeywordStatic());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString caf::PdmObject::classKeywordStatic()
|
||||
{
|
||||
return classKeywordAliases().front();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> caf::PdmObject::classKeywordAliases()
|
||||
{
|
||||
return { QString("PdmObject") };
|
||||
}
|
||||
|
@ -77,9 +77,12 @@ class PdmObjectCapability;
|
||||
#define CAF_PDM_SOURCE_INIT CAF_PDM_XML_SOURCE_INIT
|
||||
#define CAF_PDM_ABSTRACT_SOURCE_INIT CAF_PDM_XML_ABSTRACT_SOURCE_INIT
|
||||
|
||||
#define CAF_PDM_SCRIPTABLE_SOURCE_INIT CAF_PDM_XML_SCRIPTABLE_SOURCE_INIT
|
||||
|
||||
/// InitObject sets up the user interface related information for the object
|
||||
/// Placed in the constructor of your PdmObject
|
||||
/// Note that classKeyword() is not virtual in the constructor of the PdmObject
|
||||
/// This is expected and fine.
|
||||
|
||||
#define CAF_PDM_InitObject(uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
@ -95,6 +98,8 @@ class PdmObjectCapability;
|
||||
/// adds the field to the internal data structure in the PdmObject,
|
||||
/// sets the default value for the field,
|
||||
/// and sets up the static user interface related information for the field
|
||||
/// Note that classKeyword() is not virtual in the constructor of the PdmObject
|
||||
/// This is expected and fine.
|
||||
|
||||
#define CAF_PDM_InitField(field, keyword, default, uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
@ -107,12 +112,15 @@ class PdmObjectCapability;
|
||||
\
|
||||
AddXmlCapabilityToField(field); \
|
||||
AddUiCapabilityToField(field); \
|
||||
RegisterClassWithField(classKeyword(), field); \
|
||||
\
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QString(iconResourceName), toolTip, whatsThis, keyword); \
|
||||
addFieldUi(field, keyword, default, &objDescr); \
|
||||
}
|
||||
|
||||
/// InitFieldNoDefault does the same as InitField but omits the default value.
|
||||
/// Note that classKeyword() is not virtual in the constructor of the PdmObject
|
||||
/// This is expected and fine.
|
||||
|
||||
#define CAF_PDM_InitFieldNoDefault(field, keyword, uiName, iconResourceName, toolTip, whatsThis) \
|
||||
{ \
|
||||
@ -125,6 +133,7 @@ class PdmObjectCapability;
|
||||
\
|
||||
AddXmlCapabilityToField(field); \
|
||||
AddUiCapabilityToField(field); \
|
||||
RegisterClassWithField(classKeyword(), field); \
|
||||
\
|
||||
static caf::PdmUiItemInfo objDescr(uiName, QString(iconResourceName), toolTip, whatsThis, keyword); \
|
||||
addFieldUiNoDefault(field, keyword, &objDescr); \
|
||||
@ -141,12 +150,11 @@ namespace caf
|
||||
class PdmObject : public PdmObjectHandle, public PdmXmlObjectHandle, public PdmUiObjectHandle
|
||||
{
|
||||
public:
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
PdmObject();
|
||||
~PdmObject() override {}
|
||||
|
||||
static QString classKeywordStatic();
|
||||
static std::vector<QString> classKeywordAliases();
|
||||
|
||||
/// Adds field to the internal data structure and sets the file keyword and Ui information
|
||||
/// Consider this method private. Please use the CAF_PDM_InitField() macro instead
|
||||
template< typename FieldDataType >
|
||||
@ -186,6 +194,7 @@ public:
|
||||
void childrenFromClassKeyword(
|
||||
const QString& classKeyword,
|
||||
std::vector<PdmObject*>& children) const;
|
||||
|
||||
};
|
||||
|
||||
} // End of namespace caf
|
||||
|
@ -134,6 +134,13 @@ void AddXmlCapabilityToField(FieldType* field)
|
||||
}
|
||||
|
||||
|
||||
template<typename FieldType>
|
||||
void RegisterClassWithField(const QString& classKeyword, FieldType* field)
|
||||
{
|
||||
field->setOwnerClass(classKeyword);
|
||||
}
|
||||
|
||||
|
||||
} // End of namespace caf
|
||||
|
||||
#include "cafInternalPdmXmlFieldCapability.inl"
|
||||
|
@ -247,7 +247,7 @@ void caf::PdmFieldXmlCap< caf::PdmChildField<DataType*> >::readFieldData(QXmlStr
|
||||
else
|
||||
{
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(obj);
|
||||
if (!xmlObject || xmlObject->classKeyword() != className)
|
||||
if (!xmlObject || !xmlObject->matchesClassKeyword(className))
|
||||
{
|
||||
CAF_ASSERT(false); // Inconsistency in the factory. It creates objects of wrong type from the ClassKeyword
|
||||
|
||||
@ -267,7 +267,7 @@ void caf::PdmFieldXmlCap< caf::PdmChildField<DataType*> >::readFieldData(QXmlStr
|
||||
}
|
||||
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(obj);
|
||||
if (!xmlObject || xmlObject->classKeyword() != className)
|
||||
if (!xmlObject || !xmlObject->matchesClassKeyword(className))
|
||||
{
|
||||
// Error: Field contains different class type than on file
|
||||
std::cout << "Line " << xmlStream.lineNumber() << ": Warning: Unknown object type with class name: " << className.toLatin1().data() << " found while reading the field : " << m_field->keyword().toLatin1().data() << std::endl;
|
||||
@ -382,7 +382,7 @@ void caf::PdmFieldXmlCap< caf::PdmChildArrayField<DataType*> >::readFieldData(QX
|
||||
}
|
||||
|
||||
PdmXmlObjectHandle* xmlObject = xmlObj(obj);
|
||||
if (!xmlObject || xmlObject->classKeyword() != className)
|
||||
if (!xmlObject || !xmlObject->matchesClassKeyword(className))
|
||||
{
|
||||
CAF_ASSERT(false); // There is an inconsistency in the factory. It creates objects of type not matching the ClassKeyword
|
||||
|
||||
|
@ -67,22 +67,24 @@ public:
|
||||
template< typename PdmObjectBaseDerivative >
|
||||
bool registerCreator()
|
||||
{
|
||||
std::map<QString, PdmObjectCreatorBase*>::iterator entryIt;
|
||||
std::vector<QString> classNameKeywords = PdmObjectBaseDerivative::classKeywordAliases();
|
||||
|
||||
QString classNameKeyword = PdmObjectBaseDerivative::classKeywordStatic();
|
||||
|
||||
entryIt = m_factoryMap.find(classNameKeyword);
|
||||
if (entryIt == m_factoryMap.end())
|
||||
for (QString classNameKeyword : classNameKeywords)
|
||||
{
|
||||
m_factoryMap[classNameKeyword] = new PdmObjectCreator<PdmObjectBaseDerivative>();
|
||||
return true;
|
||||
auto entryIt = m_factoryMap.find(classNameKeyword);
|
||||
if (entryIt != m_factoryMap.end())
|
||||
{
|
||||
CAF_ASSERT(classNameKeyword != entryIt->first); // classNameKeyword has already been used
|
||||
CAF_ASSERT(false); // To be sure ..
|
||||
return false; // never hit;
|
||||
}
|
||||
}
|
||||
else
|
||||
auto object = new PdmObjectCreator<PdmObjectBaseDerivative>();
|
||||
for (QString classNameKeyword : classNameKeywords)
|
||||
{
|
||||
CAF_ASSERT(classNameKeyword != entryIt->first); // classNameKeyword has already been used
|
||||
CAF_ASSERT(false); // To be sure ..
|
||||
return false; // never hit;
|
||||
m_factoryMap[classNameKeyword] = object;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<QString> classKeywords() const;
|
||||
|
@ -35,6 +35,7 @@ public:
|
||||
|
||||
/// The classKeyword method is overridden in subclasses by the CAF_PDM_XML_HEADER_INIT macro
|
||||
virtual QString classKeyword() const = 0;
|
||||
virtual bool matchesClassKeyword(const QString& classKeyword) const = 0;
|
||||
|
||||
/// Convenience methods to serialize/de-serialize this particular object (with children)
|
||||
void readObjectFromXmlString(const QString& xmlString, PdmObjectFactory* objectFactory);
|
||||
|
@ -27,35 +27,84 @@
|
||||
|
||||
// To be renamed CAF_PDM_XML_HEADER_INIT
|
||||
#define CAF_PDM_XML_HEADER_INIT \
|
||||
private: \
|
||||
static bool classIsScriptable(); \
|
||||
public: \
|
||||
virtual QString classKeyword() const { return classKeywordStatic(); } \
|
||||
static QString classKeywordStatic(); \
|
||||
virtual QString classKeyword() const; \
|
||||
static QString classKeywordStatic(); \
|
||||
static std::vector<QString> classKeywordAliases(); \
|
||||
virtual bool isScriptable() const; \
|
||||
virtual bool matchesClassKeyword(const QString& keyword) const; \
|
||||
\
|
||||
static bool Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class()
|
||||
|
||||
#define CAF_PDM_XML_NON_SCRIPTABLE_INIT(ClassName) \
|
||||
bool ClassName::classIsScriptable() \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
|
||||
#define CAF_PDM_XML_SCRIPTABLE_INIT(ClassName) \
|
||||
bool ClassName::classIsScriptable() \
|
||||
{ \
|
||||
return true; \
|
||||
} \
|
||||
|
||||
#define CAF_PDM_XML_ABSTRACT_BASE_SOURCE_INIT(ClassName, keyword, ...) \
|
||||
bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \
|
||||
\
|
||||
QString ClassName::classKeyword() const \
|
||||
{ \
|
||||
return classKeywordStatic(); \
|
||||
} \
|
||||
QString ClassName::classKeywordStatic() \
|
||||
{ \
|
||||
return classKeywordAliases().front(); \
|
||||
} \
|
||||
std::vector<QString> ClassName::classKeywordAliases() \
|
||||
{ \
|
||||
CAF_PDM_VERIFY_XML_KEYWORD(keyword) \
|
||||
return {keyword, ##__VA_ARGS__}; \
|
||||
} \
|
||||
bool ClassName::isScriptable() const \
|
||||
{ \
|
||||
return ClassName::classIsScriptable(); \
|
||||
} \
|
||||
bool ClassName::matchesClassKeyword(const QString& matchKeyword) const\
|
||||
{ \
|
||||
auto aliases = classKeywordAliases(); \
|
||||
for (auto alias : aliases) \
|
||||
{ \
|
||||
if (alias == matchKeyword) return true; \
|
||||
} \
|
||||
return false; \
|
||||
} \
|
||||
|
||||
/// CAF_PDM_XML_ABSTRACT_SOURCE_INIT associates the file keyword used for storage with the class
|
||||
/// Place this in the cpp file, preferably above the constructor
|
||||
#define CAF_PDM_XML_ABSTRACT_SOURCE_INIT(ClassName, keyword, ...) \
|
||||
CAF_PDM_XML_ABSTRACT_BASE_SOURCE_INIT(ClassName, keyword, ##__VA_ARGS__) \
|
||||
CAF_PDM_XML_NON_SCRIPTABLE_INIT(ClassName) \
|
||||
|
||||
/// CAF_PDM_XML_ABSTRACT_SOURCE_INIT associates the file keyword used for storage with the *scriptable* class
|
||||
/// Place this in the cpp file, preferably above the constructor
|
||||
#define CAF_PDM_XML_ABSTRACT_SCRIPTABLE_SOURCE_INIT(ClassName, keyword, ...) \
|
||||
CAF_PDM_XML_ABSTRACT_BASE_SOURCE_INIT(ClassName, keyword, ##__VA_ARGS__) \
|
||||
CAF_PDM_XML_SCRIPTABLE_INIT(ClassName) \
|
||||
|
||||
/// CAF_PDM_XML_SOURCE_INIT associates the file keyword used for storage with the class and
|
||||
// initializes the factory
|
||||
/// Place this in the cpp file, preferably above the constructor
|
||||
|
||||
#define CAF_PDM_XML_SOURCE_INIT(ClassName, keyword) \
|
||||
bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \
|
||||
\
|
||||
QString ClassName::classKeywordStatic() \
|
||||
{ \
|
||||
CAF_PDM_VERIFY_XML_KEYWORD(keyword) \
|
||||
return keyword; \
|
||||
} \
|
||||
#define CAF_PDM_XML_SOURCE_INIT(ClassName, keyword, ...) \
|
||||
CAF_PDM_XML_ABSTRACT_SOURCE_INIT(ClassName, keyword, ##__VA_ARGS__) \
|
||||
static bool PDM_OBJECT_STRING_CONCATENATE(my##ClassName, __LINE__) = caf::PdmDefaultObjectFactory::instance()->registerCreator<ClassName>()
|
||||
|
||||
#define CAF_PDM_XML_ABSTRACT_SOURCE_INIT(ClassName, keyword) \
|
||||
bool ClassName::Error_You_forgot_to_add_the_macro_CAF_PDM_XML_HEADER_INIT_and_or_CAF_PDM_XML_SOURCE_INIT_to_your_cpp_file_for_this_class() { return false;} \
|
||||
\
|
||||
QString ClassName::classKeywordStatic() \
|
||||
{ \
|
||||
CAF_PDM_VERIFY_XML_KEYWORD(keyword) \
|
||||
return keyword; \
|
||||
} \
|
||||
/// CAF_PDM_XML_SCRIPTABLE_SOURCE_INIT associates the file keyword used for storage with the *scriptable* class and
|
||||
// initializes the factory
|
||||
/// Place this in the cpp file, preferably above the constructor
|
||||
#define CAF_PDM_XML_SCRIPTABLE_SOURCE_INIT(ClassName, keyword, ...) \
|
||||
CAF_PDM_XML_ABSTRACT_SCRIPTABLE_SOURCE_INIT(ClassName, keyword, ##__VA_ARGS__) \
|
||||
static bool PDM_OBJECT_STRING_CONCATENATE(my##ClassName, __LINE__) = caf::PdmDefaultObjectFactory::instance()->registerCreator<ClassName>()
|
||||
|
||||
#define CAF_PDM_XML_InitField(field, keyword) \
|
||||
{ \
|
||||
|
Loading…
Reference in New Issue
Block a user