cyphesis/rulesets/entityfilter/Providers.h
Erik Ogenvik 002e1ca728 Expose const fields.
Thus no need to redefine private and protected.
2018-05-01 22:15:29 +02:00

375 lines
12 KiB
C++

/*
Copyright (C) 2014 Erik Ogenvik
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef PROVIDERS_H_
#define PROVIDERS_H_
#include "Predicates.h"
#include "../LocatedEntity.h"
#include <Atlas/Message/Element.h>
#include <list>
#include <utility>
class OutfitProperty;
class TypeNode;
class BBoxProperty;
namespace EntityFilter
{
class Predicate;
struct QueryContext {
LocatedEntity& entity;
std::map<std::string, Atlas::Message::Element> memory;
//This field can be used by client code to specify entity for "self.*" query
LocatedEntity* self_entity;
};
class TypedProvider {
public:
virtual ~TypedProvider() = default;
/**
* @brief Gets the type of the pointer provided by this instance, if that can be determined.
*
* This will only return a valid value if
* 1) An Element containing a pointer will always be returned.
* 2) The exact same type always will be returned.
* @return Null, or a type info instance defining the type returned as a pointer Element.
*/
virtual const std::type_info* getType() const = 0;
};
template <typename T>
class Consumer : public TypedProvider
{
public:
~Consumer() override = default;
virtual void value(Atlas::Message::Element& value, const T& parent_value) const = 0;
const std::type_info* getType() const override;
};
template <typename T>
const std::type_info* Consumer<T>::getType() const
{
return nullptr;
}
template <typename T>
class ProviderBase {
public:
explicit ProviderBase(Consumer<T>* consumer);
virtual ~ProviderBase();
protected:
Consumer<T>* m_consumer;
};
template <typename T>
inline ProviderBase<T>::ProviderBase(Consumer<T>* consumer)
: m_consumer(consumer)
{
}
template <typename T>
inline ProviderBase<T>::~ProviderBase()
{
delete m_consumer;
}
template <typename TProviding, typename TConsuming>
class ConsumingProviderBase : public ProviderBase<TProviding>, public Consumer<TConsuming>
{
public:
explicit ConsumingProviderBase(Consumer<TProviding>* consumer);
~ConsumingProviderBase() override = default;;
const std::type_info* getType() const override;
};
template <typename TProviding, typename TConsuming>
inline ConsumingProviderBase<TProviding, TConsuming>::ConsumingProviderBase(Consumer<TProviding>* consumer)
: ProviderBase<TProviding>(consumer)
{
}
template <typename TProviding, typename TConsuming>
inline const std::type_info* ConsumingProviderBase<TProviding, TConsuming>::getType() const
{
if (this->m_consumer) {
return this->m_consumer->getType();
}
return nullptr;
}
template <typename T>
class NamedAttributeProviderBase : public ProviderBase<T> {
public:
NamedAttributeProviderBase(Consumer<T>* consumer, std::string attribute_name);
protected:
const std::string m_attribute_name;
};
template <typename T>
inline NamedAttributeProviderBase<T>::NamedAttributeProviderBase(Consumer<T>* consumer, std::string attribute_name)
: ProviderBase<T>(consumer), m_attribute_name(std::move(attribute_name))
{
}
template <typename TProviding, typename TConsuming>
class ConsumingNamedAttributeProviderBase : public NamedAttributeProviderBase<TProviding>, public Consumer<TConsuming>
{
public:
ConsumingNamedAttributeProviderBase(Consumer<TProviding>* consumer, const std::string& attribute_name);
~ConsumingNamedAttributeProviderBase() override = default;;
const std::type_info* getType() const override;
};
template <typename TProviding, typename TConsuming>
inline ConsumingNamedAttributeProviderBase<TProviding, TConsuming>::ConsumingNamedAttributeProviderBase(Consumer<TProviding>* consumer, const std::string& attribute_name)
: NamedAttributeProviderBase<TProviding>(consumer, attribute_name)
{
}
template <typename TProviding, typename TConsuming>
inline const std::type_info* ConsumingNamedAttributeProviderBase<TProviding, TConsuming>::getType() const
{
if (this->m_consumer) {
return this->m_consumer->getType();
}
return nullptr;
}
class FixedElementProvider : public Consumer<QueryContext> {
public:
explicit FixedElementProvider(const Atlas::Message::Element& element);
void value(Atlas::Message::Element& value, const QueryContext& context) const override;
const Atlas::Message::Element m_element;
};
class FixedTypeNodeProvider : public ConsumingProviderBase<TypeNode, QueryContext> {
public:
FixedTypeNodeProvider(Consumer<TypeNode>* consumer, const TypeNode& type);
void value(Atlas::Message::Element& value, const QueryContext& context) const override;
const std::type_info* getType() const override;
const TypeNode& m_type;
};
class MemoryProvider: public ConsumingProviderBase<Atlas::Message::Element, QueryContext>{
public:
explicit MemoryProvider(Consumer<Atlas::Message::Element>* consumer);
void value(Atlas::Message::Element& value, const QueryContext&) const override;
};
class EntityProvider : public ConsumingProviderBase<LocatedEntity, QueryContext> {
public:
explicit EntityProvider(Consumer<LocatedEntity>* consumer);
void value(Atlas::Message::Element& value, const QueryContext& context) const override;
const std::type_info* getType() const override;
};
class SelfEntityProvider : public ConsumingProviderBase<LocatedEntity, QueryContext> {
public:
explicit SelfEntityProvider(Consumer<LocatedEntity>* consumer);
void value(Atlas::Message::Element& value, const QueryContext& context) const override;
const std::type_info* getType() const override;
};
class EntityTypeProvider : public ConsumingProviderBase<TypeNode, LocatedEntity> {
public:
explicit EntityTypeProvider(Consumer<TypeNode>* consumer);
void value(Atlas::Message::Element& value, const LocatedEntity& entity) const override;
const std::type_info* getType() const override;
};
//Provides integer ID of an entity
class EntityIdProvider : public Consumer<LocatedEntity>{
public:
void value(Atlas::Message::Element& value, const LocatedEntity& entity) const override;
};
class TypeNodeProvider : public Consumer<TypeNode>
{
public:
explicit TypeNodeProvider(const std::string& attribute_name);
void value(Atlas::Message::Element& value, const TypeNode& type) const override;
const std::string m_attribute_name;
};
class OutfitEntityProvider : public ConsumingNamedAttributeProviderBase<LocatedEntity, OutfitProperty>
{
public:
OutfitEntityProvider(Consumer<LocatedEntity>* consumer, const std::string& attribute_name);
void value(Atlas::Message::Element& value, const OutfitProperty& prop) const override;
};
class BBoxProvider : public ConsumingProviderBase<Atlas::Message::Element, BBoxProperty>
{
public:
enum class Measurement {
HEIGHT, WIDTH, DEPTH, VOLUME, AREA
};
BBoxProvider(Consumer<Atlas::Message::Element>* consumer, Measurement measurement);
void value(Atlas::Message::Element& value, const BBoxProperty& prop) const override;
protected:
Measurement m_measurement;
};
template <typename TProperty>
class PropertyProvider : public ConsumingNamedAttributeProviderBase<TProperty, LocatedEntity>
{
public:
PropertyProvider(Consumer<TProperty>* consumer, const std::string& attribute_name);
virtual ~PropertyProvider() = default;
virtual void value(Atlas::Message::Element& value, const LocatedEntity& entity) const;
};
template <typename TProperty>
inline PropertyProvider<TProperty>::PropertyProvider(Consumer<TProperty>* consumer, const std::string& attribute_name)
: ConsumingNamedAttributeProviderBase<TProperty, LocatedEntity>(consumer, attribute_name)
{
}
template <typename TProperty>
inline void PropertyProvider<TProperty>::value(Atlas::Message::Element& value, const LocatedEntity& entity) const
{
const TProperty* prop = entity.getPropertyClass<TProperty>(this->m_attribute_name);
if (!prop) {
return;
}
if (this->m_consumer) {
this->m_consumer->value(value, *prop);
} else {
value = (void*)prop;
}
}
class SoftPropertyProvider : public ConsumingNamedAttributeProviderBase<Atlas::Message::Element, LocatedEntity>
{
public:
SoftPropertyProvider(Consumer<Atlas::Message::Element>* consumer, const std::string& attribute_name);
void value(Atlas::Message::Element& value, const LocatedEntity& entity) const override;
};
class MapProvider : public ConsumingNamedAttributeProviderBase<Atlas::Message::Element, Atlas::Message::Element>
{
public:
MapProvider(Consumer<Atlas::Message::Element>* consumer, const std::string& attribute_name);
void value(Atlas::Message::Element& value, const Atlas::Message::Element& parent_element) const override;
};
class EntityRefProvider : public ConsumingNamedAttributeProviderBase<LocatedEntity, LocatedEntity>
{
public:
EntityRefProvider(Consumer<LocatedEntity>* consumer, const std::string& attribute_name);
void value(Atlas::Message::Element& value, const LocatedEntity& entity) const override;
const std::type_info* getType() const override;
};
///\brief This class retrieves a pointer to the m_contains property of a given entity
class ContainsProvider : public Consumer<LocatedEntity> {
public:
void value(Atlas::Message::Element& value, const LocatedEntity& entity) const override;
const std::type_info* getType() const override;
};
///\brief This class uses container Consumer to retrieve a container and condition Predicate
///to check whether there exists an entity within the container that matches the given condition
class ContainsRecursiveFunctionProvider : public Consumer<QueryContext> {
public:
ContainsRecursiveFunctionProvider(Consumer<QueryContext>* container,
Predicate* condition);
void value(Atlas::Message::Element& value,
const QueryContext& context) const override;
private:
///\brief Condition used to match entities within the container
Predicate* m_condition;
///\brief A Consumer which must return LocatedEntitySet* i.e. entity.contains
Consumer<QueryContext>* m_consumer;
bool checkContainer(LocatedEntitySet* container) const;
};
class ProviderFactory {
public:
struct Segment {
std::string delimiter;
std::string attribute;
};
typedef std::list<Segment> SegmentsList;
virtual ~ProviderFactory() = default;
virtual Consumer<QueryContext>* createProviders(SegmentsList segments) const;
protected:
FixedTypeNodeProvider* createFixedTypeNodeProvider(SegmentsList segments) const;
EntityProvider* createEntityProvider(SegmentsList segments) const;
SelfEntityProvider* createSelfEntityProvider(SegmentsList segments) const;
OutfitEntityProvider* createOutfitEntityProvider(SegmentsList segments) const;
BBoxProvider* createBBoxProvider(SegmentsList segments) const;
Consumer<LocatedEntity>* createPropertyProvider(SegmentsList segments) const;
MapProvider* createMapProvider(SegmentsList segments) const;
TypeNodeProvider* createTypeNodeProvider(SegmentsList segments) const;
};
class MindProviderFactory: public ProviderFactory{
public:
~MindProviderFactory() override = default;
Consumer<QueryContext>* createProviders(SegmentsList segments) const override;
protected:
MemoryProvider* createMemoryProvider(SegmentsList segments) const;
};
}
#endif /* PROVIDERS_H_ */