/* Copyright (C) 2018 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 CYPHESIS_CYPY_LOCATEDENTITY_IMPL_H #define CYPHESIS_CYPY_LOCATEDENTITY_IMPL_H #include "CyPy_LocatedEntity.h" #include "CyPy_Point3D.h" #include "CyPy_Operation.h" #include "CyPy_EntityLocation.h" #include "CyPy_Props.h" #include "CyPy_Location.h" #include "CyPy_Element.h" #include "common/Inheritance.h" template CyPy_LocatedEntityBase::CyPy_LocatedEntityBase(Py::PythonClassInstance* self, Py::Tuple& args, Py::Dict& kwds) : WrapperBase::WrapperBase(self, args, kwds) { } template CyPy_LocatedEntityBase::CyPy_LocatedEntityBase(Py::PythonClassInstance* self, TValue value) : WrapperBase::WrapperBase(self, std::move(value)) { } template CyPy_LocatedEntityBase::~CyPy_LocatedEntityBase() = default; template Py::Object CyPy_LocatedEntityBase::getattro(const Py::String& name) { auto nameStr = name.as_string(); if (nameStr == "id") { return Py::String(this->m_value->getId()); } if (nameStr == "props") { return CyPy_Props::wrap(this->m_value); } if (nameStr == "type") { if (!this->m_value->getType()) { throw Py::AttributeError(name); } return Py::String(this->m_value->getType()->name()); } if (nameStr == "location") { return CyPy_Location::wrap(this->m_value->m_location); } if (nameStr == "contains") { if (!this->m_value->m_contains) { return Py::None(); } Py::List list; for (auto& child : *this->m_value->m_contains) { list.append(CyPy_LocatedEntity::wrap(child)); } return list; } if (nameStr == "visible") { return Py::Boolean(this->m_value->isVisible()); } return Py::PythonExtensionBase::getattro(name); } template int CyPy_LocatedEntityBase::setattro(const Py::String& name, const Py::Object& attr) { auto nameStr = name.as_string(); if (nameStr == "type") { if (this->m_value->getType()) { throw Py::RuntimeError("Cannot mutate entity type"); } const TypeNode* type = Inheritance::instance().getType(verifyString(attr)); if (!type) { throw Py::ValueError("Entity type unknown"); } this->m_value->setType(type); return 0; } return Py::PythonExtensionBase::setattro(name, attr); } template Py::Object CyPy_LocatedEntityBase::rich_compare(const Py::Object& other, int op) { if (CyPy_LocatedEntity::check(other)) { auto otherEntity = CyPy_LocatedEntity::value(other); if (op == Py_EQ) { return (this->m_value == otherEntity) ? Py::True() : Py::False(); } else if (op == Py_NE) { return (this->m_value != otherEntity) ? Py::True() : Py::False(); } } else { if (op == Py_EQ) { return Py::False(); } else if (op == Py_NE) { return Py::True(); } } throw Py::NotImplementedError("Not implemented"); } template Py::Object CyPy_LocatedEntityBase::as_entity() { Atlas::Message::MapType element; this->m_value->addToMessage(element); return CyPy_Element::wrap(element); } template Py::Object CyPy_LocatedEntityBase::can_reach(const Py::Tuple& args) { args.verify_length(1, 2); float extraReach = 0; if (args.length() == 2) { extraReach = verifyNumeric(args[1]); } return Py::Boolean(this->m_value->canReach(verifyObject(args.front()), extraReach)); } template Py::Object CyPy_LocatedEntityBase::describe_entity() { return Py::String(this->m_value->describeEntity()); } template Py::Object CyPy_LocatedEntityBase::client_error(const Py::Tuple& args) { args.verify_length(2); OpVector res; this->m_value->clientError(verifyObject(args[0]), verifyString(args[1]), res, this->m_value->getId()); if (!res.empty()) { return CyPy_Operation::wrap(res.front()); } return Py::None(); } template Py::Object CyPy_LocatedEntityBase::getPropertyFromFirstArg(const Py::Tuple& args, const std::function& checkFn) const { Py::Object defaultValue = Py::None(); if (args.length() > 1) { defaultValue = args.getItem(1); } args.verify_length(1); const PropertyBase* prop = this->m_value->getProperty(verifyString(args.front())); if (prop) { Atlas::Message::Element element; prop->get(element); return checkFn(element, defaultValue); } return defaultValue; } template Py::Object CyPy_LocatedEntityBase::hasPropertyFromFirstArg(const Py::Tuple& args, const std::function& checkFn) const { args.verify_length(1); const PropertyBase* prop = this->m_value->getProperty(verifyString(args.front())); if (prop) { Atlas::Message::Element element; prop->get(element); return Py::Boolean(checkFn(element)); } return Py::False(); } template Py::Object CyPy_LocatedEntityBase::get_prop_num(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isInt()) { return Py::Long(element.Int()); } else if (element.isFloat()) { return Py::Float(element.Float()); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_num(const Py::Tuple& args) { return this->hasPropertyFromFirstArg(args, [](const Atlas::Message::Element& element) { return element.isNum(); }); } template Py::Object CyPy_LocatedEntityBase::get_prop_float(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isFloat()) { return Py::Float(element.Float()); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_float(const Py::Tuple& args) { return this->hasPropertyFromFirstArg(args, [](const Atlas::Message::Element& element) { return element.isFloat(); }); } template Py::Object CyPy_LocatedEntityBase::get_prop_int(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isInt()) { return Py::Long(element.Int()); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_int(const Py::Tuple& args) { return this->hasPropertyFromFirstArg(args, [](const Atlas::Message::Element& element) { return element.isInt(); }); } template Py::Object CyPy_LocatedEntityBase::get_prop_string(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isString()) { return Py::String(element.String()); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_string(const Py::Tuple& args) { return this->hasPropertyFromFirstArg(args, [](const Atlas::Message::Element& element) { return element.isString(); }); } template Py::Object CyPy_LocatedEntityBase::get_prop_bool(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isInt()) { return Py::Boolean(element.Int() != 0); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_bool(const Py::Tuple& args) { return this->has_prop_int(args); } template Py::Object CyPy_LocatedEntityBase::get_prop_map(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isMap()) { return CyPy_ElementMap::wrap(element.Map()); // return Py::Dict(element.Map()); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_map(const Py::Tuple& args) { return this->hasPropertyFromFirstArg(args, [](const Atlas::Message::Element& element) { return element.isMap(); }); } template Py::Object CyPy_LocatedEntityBase::get_prop_list(const Py::Tuple& args) { return this->getPropertyFromFirstArg(args, [](const Atlas::Message::Element& element, Py::Object defaultValue) -> Py::Object { if (element.isList()) { return CyPy_ElementList::wrap(element.List()); // return Py::Dict(element.Map()); } else { return defaultValue; } }); } template Py::Object CyPy_LocatedEntityBase::has_prop_list(const Py::Tuple& args) { return this->hasPropertyFromFirstArg(args, [](const Atlas::Message::Element& element) { return element.isList(); }); } template Py::Object CyPy_LocatedEntityBase::wrap(LocatedEntity* value) { return wrapLocatedEntity(value); } template Py::Object CyPy_LocatedEntityBase::str() { return describe_entity(); } #endif //CYPHESIS_CYPY_LOCATEDENTITY_IMPL_H