You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
378 lines
12 KiB
C
378 lines
12 KiB
C
1 year ago
|
/***************************************************************************
|
||
|
* Copyright (C) gempa GmbH *
|
||
|
* All rights reserved. *
|
||
|
* Contact: gempa GmbH (seiscomp-dev@gempa.de) *
|
||
|
* *
|
||
|
* GNU Affero General Public License Usage *
|
||
|
* This file may be used under the terms of the GNU Affero *
|
||
|
* Public License version 3.0 as published by the Free Software Foundation *
|
||
|
* and appearing in the file LICENSE included in the packaging of this *
|
||
|
* file. Please review the following information to ensure the GNU Affero *
|
||
|
* Public License version 3.0 requirements will be met: *
|
||
|
* https://www.gnu.org/licenses/agpl-3.0.html. *
|
||
|
* *
|
||
|
* Other Usage *
|
||
|
* Alternatively, this file may be used in accordance with the terms and *
|
||
|
* conditions contained in a signed written agreement between you and *
|
||
|
* gempa GmbH. *
|
||
|
***************************************************************************/
|
||
|
|
||
|
|
||
|
#ifndef SEISCOMP_CORE_METAOBJECT_H
|
||
|
#define SEISCOMP_CORE_METAOBJECT_H
|
||
|
|
||
|
#include <seiscomp/core/rtti.h>
|
||
|
#include <seiscomp/core/datetime.h>
|
||
|
#include <seiscomp/core/exceptions.h>
|
||
|
|
||
|
#include <boost/any.hpp>
|
||
|
|
||
|
#include <complex>
|
||
|
#include <vector>
|
||
|
#include <memory>
|
||
|
#include <type_traits>
|
||
|
#include <map>
|
||
|
|
||
|
|
||
|
namespace Seiscomp {
|
||
|
namespace Core {
|
||
|
|
||
|
class BaseObject;
|
||
|
|
||
|
typedef boost::any MetaValue;
|
||
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
class SC_SYSTEM_CORE_API PropertyNotFoundException : public GeneralException {
|
||
|
public:
|
||
|
PropertyNotFoundException();
|
||
|
PropertyNotFoundException(const std::string& str);
|
||
|
};
|
||
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
class SC_SYSTEM_CORE_API MetaEnum {
|
||
|
// ------------------------------------------------------------------
|
||
|
// Xstruction
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
MetaEnum();
|
||
|
virtual ~MetaEnum();
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Public interface
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
//! Returns the number of keys in the enumeration
|
||
|
virtual int keyCount() const = 0;
|
||
|
|
||
|
//! Returns the key name at a given index
|
||
|
virtual const char *key(int index) const = 0;
|
||
|
|
||
|
virtual const char *valueToKey(int value) const = 0;
|
||
|
virtual int keyToValue(const char *key) const = 0;
|
||
|
};
|
||
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
class SC_SYSTEM_CORE_API MetaProperty {
|
||
|
// ------------------------------------------------------------------
|
||
|
// Xstruction
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
MetaProperty();
|
||
|
MetaProperty(const std::string& name,
|
||
|
const std::string& type,
|
||
|
bool isArray,
|
||
|
bool isClass,
|
||
|
bool isIndex,
|
||
|
bool isReference,
|
||
|
bool isOptional,
|
||
|
bool isEnum,
|
||
|
const MetaEnum *enumeration = nullptr);
|
||
|
|
||
|
virtual ~MetaProperty();
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Initialization
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
void setInfo(const std::string& name,
|
||
|
const std::string& type,
|
||
|
bool isArray,
|
||
|
bool isClass,
|
||
|
bool isIndex,
|
||
|
bool isReference,
|
||
|
bool isOptional,
|
||
|
bool isEnum,
|
||
|
const MetaEnum *enumeration = nullptr);
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Getters
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
const std::string& name() const;
|
||
|
const std::string& type() const;
|
||
|
|
||
|
//! Returns a meta enum description if this property
|
||
|
//! is an enumeration
|
||
|
const MetaEnum *enumerator() const;
|
||
|
|
||
|
bool isArray() const;
|
||
|
bool isClass() const;
|
||
|
bool isIndex() const;
|
||
|
bool isReference() const;
|
||
|
bool isEnum() const;
|
||
|
bool isOptional() const;
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Public interface
|
||
|
// ------------------------------------------------------------------
|
||
|
public:
|
||
|
//! Creates an instance of the properties class type
|
||
|
virtual BaseObject *createClass() const;
|
||
|
|
||
|
//! Returns the number of elements in the array if isArray() is
|
||
|
//! true, -1 otherwise
|
||
|
virtual size_t arrayElementCount(const BaseObject *object) const;
|
||
|
|
||
|
//! Returns the object at position i, nullptr otherwise
|
||
|
virtual BaseObject *arrayObject(BaseObject *object, int i) const;
|
||
|
|
||
|
//! Adds a child to an object.
|
||
|
//! If the property is not an array type, nothing will be done
|
||
|
//! and 'false' will be returned.
|
||
|
virtual bool arrayAddObject(BaseObject *object, BaseObject *child) const;
|
||
|
|
||
|
//! Removes a child from an object at a given index.
|
||
|
virtual bool arrayRemoveObject(BaseObject *object, int i) const;
|
||
|
|
||
|
//! Removes a child from an object.
|
||
|
virtual bool arrayRemoveObject(BaseObject *object, BaseObject *child) const;
|
||
|
|
||
|
//! Writes a value to an objects property.
|
||
|
//! Returns true when the value has been written, false otherwise
|
||
|
//! Throws:
|
||
|
//! PropertyNotFoundException: The property does not exist
|
||
|
//! TypeException: The type of the property is not compatible with value
|
||
|
virtual bool write(BaseObject *object, MetaValue value) const;
|
||
|
|
||
|
//! Writes a value (as string representation) to an objects property.
|
||
|
//! Returns true when the value has been written, false otherwise
|
||
|
//! Throws:
|
||
|
//! PropertyNotFoundException: The property does not exist
|
||
|
//! TypeException: The type of the property is not compatible with value
|
||
|
virtual bool writeString(BaseObject *object, const std::string &value) const;
|
||
|
|
||
|
//! Reads a value from an objects property.
|
||
|
//! The returned value can be empty (empty()) if the object
|
||
|
//! does not have a corresponding property or the property
|
||
|
//! is not set.
|
||
|
//! Throws:
|
||
|
//! PropertyNotFoundException: The property does not exist
|
||
|
virtual MetaValue read(const BaseObject *object) const;
|
||
|
|
||
|
//! Reads a value from an objects property as string representation.
|
||
|
//! The returned value can be empty (empty()) if the object
|
||
|
//! does not have a corresponding property or the property
|
||
|
//! is not set or the datatype does not support string conversion
|
||
|
//! Throws:
|
||
|
//! PropertyNotFoundException: The property does not exist
|
||
|
virtual std::string readString(const BaseObject *object) const;
|
||
|
|
||
|
|
||
|
// ------------------------------------------------------------------
|
||
|
// Implementation
|
||
|
// ------------------------------------------------------------------
|
||
|
private:
|
||
|
std::string _name;
|
||
|
std::string _type;
|
||
|
bool _isArray;
|
||
|
bool _isClass;
|
||
|
bool _isIndex;
|
||
|
bool _isReference;
|
||
|
bool _isEnum;
|
||
|
bool _isOptional;
|
||
|
|
||
|
const MetaEnum *_enumeration;
|
||
|
};
|
||
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
/** \brief A metaobject (class information and access) class
|
||
|
|
||
|
To implement it into custom classes, use the supported METAOBJECT
|
||
|
macros.
|
||
|
|
||
|
\code
|
||
|
class MyClass {
|
||
|
DECLARE_METAOBJECT;
|
||
|
...
|
||
|
public:
|
||
|
MyClass();
|
||
|
...
|
||
|
};
|
||
|
\endcode
|
||
|
|
||
|
To implement the metaobject interface, another macro has to be used.
|
||
|
\code
|
||
|
IMPLEMENT_METAOBJECT(MyClass);
|
||
|
\endcode
|
||
|
*/
|
||
|
typedef std::shared_ptr<MetaProperty> MetaPropertyHandle;
|
||
|
|
||
|
class SC_SYSTEM_CORE_API MetaObject {
|
||
|
// ----------------------------------------------------------------------
|
||
|
// Xstruction
|
||
|
// ----------------------------------------------------------------------
|
||
|
public:
|
||
|
//! Constructor
|
||
|
MetaObject(const RTTI *rtti, const MetaObject *base = nullptr);
|
||
|
~MetaObject();
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
// Public interface
|
||
|
// ----------------------------------------------------------------------
|
||
|
public:
|
||
|
//! Returns the corresponding RTTI object
|
||
|
const RTTI *rtti() const;
|
||
|
|
||
|
//! Returns the base MetaObject if available
|
||
|
const MetaObject *base() const;
|
||
|
|
||
|
//! Returns the number of properties set
|
||
|
size_t propertyCount() const;
|
||
|
|
||
|
//! Returns the property at a given position
|
||
|
const MetaProperty *property(size_t index) const;
|
||
|
|
||
|
//! Returns the property with a given name
|
||
|
const MetaProperty *property(const std::string &name) const;
|
||
|
|
||
|
static const MetaObject *Find(const std::string &className);
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
// Protected interface
|
||
|
// ----------------------------------------------------------------------
|
||
|
protected:
|
||
|
void clearProperties();
|
||
|
|
||
|
bool addProperty(const std::string &name, const std::string &type,
|
||
|
bool isArray, bool isClass, bool isIndex,
|
||
|
bool isReference, bool isOptional, bool isEnum,
|
||
|
const MetaEnum *enumeration = nullptr);
|
||
|
|
||
|
bool addProperty(MetaPropertyHandle);
|
||
|
|
||
|
bool removeProperty(size_t index);
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------
|
||
|
// Implementation
|
||
|
// ----------------------------------------------------------------------
|
||
|
private:
|
||
|
const RTTI *_rtti;
|
||
|
const MetaObject *_base;
|
||
|
std::vector<MetaPropertyHandle> _properties;
|
||
|
|
||
|
using MetaObjectMap = std::map<std::string, const MetaObject*>;
|
||
|
static MetaObjectMap _map;
|
||
|
};
|
||
|
|
||
|
typedef std::shared_ptr<MetaObject> MetaObjectHandle;
|
||
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
#define DECLARE_METAOBJECT_INTERFACE \
|
||
|
public: \
|
||
|
static const Seiscomp::Core::MetaObject *Meta(); \
|
||
|
\
|
||
|
virtual const Seiscomp::Core::MetaObject *meta() const
|
||
|
|
||
|
#define DECLARE_METAOBJECT_DERIVED_INTERFACE \
|
||
|
public: \
|
||
|
static const Seiscomp::Core::MetaObject *Meta(); \
|
||
|
\
|
||
|
virtual const Seiscomp::Core::MetaObject *meta() const override
|
||
|
|
||
|
#define DECLARE_METAOBJECT \
|
||
|
DECLARE_METAOBJECT_DERIVED_INTERFACE; \
|
||
|
protected: \
|
||
|
class MetaObject : public Seiscomp::Core::MetaObject { \
|
||
|
public: \
|
||
|
MetaObject(const Seiscomp::Core::RTTI* rtti); \
|
||
|
}
|
||
|
|
||
|
#define DECLARE_METAOBJECT_DERIVED \
|
||
|
DECLARE_METAOBJECT_DERIVED_INTERFACE; \
|
||
|
protected: \
|
||
|
class MetaObject : public Seiscomp::Core::MetaObject { \
|
||
|
public: \
|
||
|
MetaObject(const Seiscomp::Core::RTTI* rtti, const Seiscomp::Core::MetaObject *base = nullptr); \
|
||
|
}
|
||
|
|
||
|
#define IMPLEMENT_METAOBJECT_EMPTY_METHODS(CLASS) \
|
||
|
const Seiscomp::Core::MetaObject *CLASS::Meta() { \
|
||
|
return nullptr; \
|
||
|
} \
|
||
|
\
|
||
|
const Seiscomp::Core::MetaObject *CLASS::meta() const { \
|
||
|
return nullptr; \
|
||
|
}
|
||
|
|
||
|
#define IMPLEMENT_METAOBJECT_METHODS(CLASS) \
|
||
|
const Seiscomp::Core::MetaObject *CLASS::meta() const { \
|
||
|
return Meta(); \
|
||
|
}
|
||
|
|
||
|
|
||
|
#define IMPLEMENT_METAOBJECT(CLASS) \
|
||
|
IMPLEMENT_METAOBJECT_METHODS(CLASS) \
|
||
|
const Seiscomp::Core::MetaObject *CLASS::Meta() { \
|
||
|
static CLASS::MetaObject classMetaObject(&CLASS::TypeInfo()); \
|
||
|
return &classMetaObject; \
|
||
|
}
|
||
|
|
||
|
|
||
|
#define IMPLEMENT_METAOBJECT_DERIVED(CLASS, BASECLASS) \
|
||
|
IMPLEMENT_METAOBJECT_METHODS(CLASS) \
|
||
|
const Seiscomp::Core::MetaObject *CLASS::Meta() { \
|
||
|
static CLASS::MetaObject classMetaObject(&CLASS::TypeInfo(), BASECLASS::Meta()); \
|
||
|
return &classMetaObject; \
|
||
|
}
|
||
|
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|