<commit_before>//==============================================================================
// CellML file RDF triple
//==============================================================================

#include "cellmlfilerdftriple.h"

//==============================================================================

#include <QStringList>

//==============================================================================

namespace OpenCOR {
namespace CellMLSupport {

//==============================================================================

CellmlFileRdfTriple::CellmlFileRdfTriple(iface::rdf_api::Triple *pRdfTriple) :
    mType(Unknown),
    mModelQualifierType(ModelUnknown),
    mBiologyQualifierType(BiologyUnknown),
    mQualifierUrl(QUrl())
{
    // Retrieve the RDF triple's subject, predicate and object information

    ObjRef<iface::rdf_api::Resource> subject = pRdfTriple->subject();
    ObjRef<iface::rdf_api::Resource> predicate = pRdfTriple->predicate();
    ObjRef<iface::rdf_api::Node> object = pRdfTriple->object();

    mSubject   = new CellmlFileRdfTripleElement(subject);
    mPredicate = new CellmlFileRdfTripleElement(predicate);
    mObject    = new CellmlFileRdfTripleElement(object);

    // Determine the type of the RDF triple

    // Note: at this stage, we only recognise model and biology qualifiers as
    //       described at http://biomodels.net/qualifiers/. This means that the
    //       predicate of the RDF triple must have one of the following two
    //       forms:
    //
    //          http://biomodels.net/model-qualifiers/<xxx>
    //          http://biomodels.net/biology-qualifiers/<yyy>
    //
    //       where <xxx> and <yyy> are one of the values in modelQualifiers and
    //       biologyQualifiers below. The object of the RDF triple must also
    //       have the following form:
    //
    //          urn:miriam:<collection>:<identifier>
    //
    //       For example:
    //
    //          urn:miriam:uniprot:P62158

    QStringList modelQualifiers = QStringList() << "is" << "isDerivedFrom"
                                                << "isDescribedBy";
    QStringList biologyQualifiers = QStringList() << "encodes" << "hasPart"
                                                  << "hasProperty"
                                                  << "hasVersion" << "is"
                                                  << "isDescribedBy"
                                                  << "isEncodedBy"
                                                  << "isHomologTo" << "isPartOf"
                                                  << "isPropertyOf"
                                                  << "isVersionOf" << "occursIn"
                                                  << "hasTaxon";

    for (int i = 0, iMax = modelQualifiers.count(); i < iMax; ++i)
        if (!mPredicate->asString().compare(QString("http://biomodels.net/model-qualifiers/%1").arg(modelQualifiers[i]))) {
            // It looks like we might be dealing with a model qualifier

            mType = ModelQualifier;

            mModelQualifierType = (ModelQualifierType) (i+1);

            break;
        }

    if (mType == Unknown)
        for (int i = 0, iMax = biologyQualifiers.count(); i < iMax; ++i)
            if (!mPredicate->asString().compare(QString("http://biomodels.net/biology-qualifiers/%1").arg(biologyQualifiers[i]))){
                // It looks like we might be dealing with a model qualifier

                mType = BiologyQualifier;

                mBiologyQualifierType = (BiologyQualifierType) (i+1);

                break;
            }

    if ((mType == ModelQualifier) || (mType == BiologyQualifier))
        // We seem to be dealing with either a model or a biology qualifier, so
        // check that its object is a valid MIRIAM URN

        if (QRegExp("^urn:miriam:[a-zA-Z0-9\\._%]+:[a-zA-Z0-9\\._%]+").exactMatch(mObject->asString())) {
            // The object is a valid MIRIAM URN, so retrieve its corresponding
            // URL

//---GRY--- TEMPORARY QUALIFIER URL... WE NEED TO RETRIEVE THE PROPER QUALIFIER
//          URL USING http://www.ebi.ac.uk/miriamws/main/rest/resolve/XXX

            mQualifierUrl = QUrl("http://www.opencor.ws/");
        } else {
            // The object is not a valid MIRIAM URN which means that the RDF
            // triple is not a valid model/biology qualifier

            mType = Unknown;

            mModelQualifierType   = ModelUnknown;
            mBiologyQualifierType = BiologyUnknown;
        }
}

//==============================================================================

CellmlFileRdfTriple::~CellmlFileRdfTriple()
{
    // Delete some internal objects

    delete mSubject;
    delete mPredicate;
    delete mObject;
}

//==============================================================================

CellmlFileRdfTripleElement * CellmlFileRdfTriple::subject() const
{
    // Return the RDF triple's subject

    return mSubject;
}

//==============================================================================

CellmlFileRdfTripleElement * CellmlFileRdfTriple::predicate() const
{
    // Return the RDF triple's predicate

    return mPredicate;
}

//==============================================================================

CellmlFileRdfTripleElement * CellmlFileRdfTriple::object() const
{
    // Return the RDF triple's object

    return mObject;
}

//==============================================================================

CellmlFileRdfTriple::Type CellmlFileRdfTriple::type() const
{
    // Return the RDF triple's type

    return mType;
}

//==============================================================================

CellmlFileRdfTriple::ModelQualifierType CellmlFileRdfTriple::modelQualifierType() const
{
    // Return the RDF triple's model qualifier type

    return mModelQualifierType;
}

//==============================================================================

QString CellmlFileRdfTriple::modelQualifierTypeAsString() const
{
    // Return the RDF triple's model qualifier type as a string

    switch (mModelQualifierType) {
    case ModelIs:
        return QObject::tr("is");
    case ModelIsDerivedFrom:
        return QObject::tr("is derived from");
    case ModelIsDescribedBy:
        return QObject::tr("is described by");
    default:
        // ModelUnknown

        return "???";
    }
}

//==============================================================================

CellmlFileRdfTriple::BiologyQualifierType CellmlFileRdfTriple::biologyQualifierType() const
{
    // Return the RDF triple's biology qualifier type

    return mBiologyQualifierType;
}

//==============================================================================

QString CellmlFileRdfTriple::biologyQualifierTypeAsString() const
{
    // Return the RDF triple's biology qualifier type as a string

    switch (mBiologyQualifierType) {
    case BiologyEncodes:
        return QObject::tr("encodes");
    case BiologyHasPart:
        return QObject::tr("has part");
    case BiologyHasProperty:
        return QObject::tr("has property");
    case BiologyHasVersion:
        return QObject::tr("has version");
    case BiologyIs:
        return QObject::tr("is");
    case BiologyIsDescribedBy:
        return QObject::tr("is described by");
    case BiologyIsEncodedBy:
        return QObject::tr("is encoded by");
    case BiologyIsHomologTo:
        return QObject::tr("is homolog to");
    case BiologyIsPartOf:
        return QObject::tr("is part of");
    case BiologyIsPropertyOf:
        return QObject::tr("is property of");
    case BiologyIsVersionOf:
        return QObject::tr("is version of");
    case BiologyOccursIn:
        return QObject::tr("occurs in");
    case BiologyHasTaxon:
        return QObject::tr("has taxon");
    default:
        // BiologyUnknown

        return "???";
    }
}

//==============================================================================

QUrl CellmlFileRdfTriple::qualifierUrl() const
{
    // Return the RDF triple's qualifier URL

    return mQualifierUrl;
}

//==============================================================================

CellmlFileRdfTriple::Type CellmlFileRdfTriples::type() const
{
    // Return the type of the RDF triples
    // Note: if the RDF triples are of different types each then the overall
    //       type is considered to be unknown

    if (isEmpty()) {
        // There are no RDF triples, so...

        return CellmlFileRdfTriple::Unknown;
    } else {
        // There is at least one RDF triple, so retrieve the subject and type of
        // the first RDF triple and consider its type as the default type for
        // all our RDF triples

        CellmlFileRdfTriple *crtRdfTriple = first();

        QString subject = crtRdfTriple->subject()->asString();
        CellmlFileRdfTriple::Type res = crtRdfTriple->type();

        // Go through the remaining RDF triples and make sure that their type
        // is consistent with that of the first one

        for (int i = 2, iMax = count(); i < iMax; ++i) {
            crtRdfTriple = at(i);

            if (   crtRdfTriple->subject()->asString().compare(subject)
                || (crtRdfTriple->type() != res))
                // The subject and/or the type of the current RDF triple is
                // different from that of the first RDF triple, so...

                return CellmlFileRdfTriple::Unknown;
        }

        // All of the RDF triples have the same type, so...

        return res;
    }
}

//==============================================================================

}   // namespace CellMLSupport
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Minor cleaning up to please gcc on Linux (#57).<commit_after>//==============================================================================
// CellML file RDF triple
//==============================================================================

#include "cellmlfilerdftriple.h"

//==============================================================================

#include <QStringList>

//==============================================================================

namespace OpenCOR {
namespace CellMLSupport {

//==============================================================================

CellmlFileRdfTriple::CellmlFileRdfTriple(iface::rdf_api::Triple *pRdfTriple) :
    mType(Unknown),
    mModelQualifierType(ModelUnknown),
    mBiologyQualifierType(BiologyUnknown),
    mQualifierUrl(QUrl())
{
    // Retrieve the RDF triple's subject, predicate and object information

    ObjRef<iface::rdf_api::Resource> subject = pRdfTriple->subject();
    ObjRef<iface::rdf_api::Resource> predicate = pRdfTriple->predicate();
    ObjRef<iface::rdf_api::Node> object = pRdfTriple->object();

    mSubject   = new CellmlFileRdfTripleElement(subject);
    mPredicate = new CellmlFileRdfTripleElement(predicate);
    mObject    = new CellmlFileRdfTripleElement(object);

    // Determine the type of the RDF triple

    // Note: at this stage, we only recognise model and biology qualifiers as
    //       described at http://biomodels.net/qualifiers/. This means that the
    //       predicate of the RDF triple must have one of the following two
    //       forms:
    //
    //          http://biomodels.net/model-qualifiers/<xxx>
    //          http://biomodels.net/biology-qualifiers/<yyy>
    //
    //       where <xxx> and <yyy> are one of the values in modelQualifiers and
    //       biologyQualifiers below. The object of the RDF triple must also
    //       have the following form:
    //
    //          urn:miriam:<collection>:<identifier>
    //
    //       For example:
    //
    //          urn:miriam:uniprot:P62158

    QStringList modelQualifiers = QStringList() << "is" << "isDerivedFrom"
                                                << "isDescribedBy";
    QStringList biologyQualifiers = QStringList() << "encodes" << "hasPart"
                                                  << "hasProperty"
                                                  << "hasVersion" << "is"
                                                  << "isDescribedBy"
                                                  << "isEncodedBy"
                                                  << "isHomologTo" << "isPartOf"
                                                  << "isPropertyOf"
                                                  << "isVersionOf" << "occursIn"
                                                  << "hasTaxon";

    for (int i = 0, iMax = modelQualifiers.count(); i < iMax; ++i)
        if (!mPredicate->asString().compare(QString("http://biomodels.net/model-qualifiers/%1").arg(modelQualifiers[i]))) {
            // It looks like we might be dealing with a model qualifier

            mType = ModelQualifier;

            mModelQualifierType = (ModelQualifierType) (i+1);

            break;
        }

    if (mType == Unknown)
        for (int i = 0, iMax = biologyQualifiers.count(); i < iMax; ++i)
            if (!mPredicate->asString().compare(QString("http://biomodels.net/biology-qualifiers/%1").arg(biologyQualifiers[i]))){
                // It looks like we might be dealing with a model qualifier

                mType = BiologyQualifier;

                mBiologyQualifierType = (BiologyQualifierType) (i+1);

                break;
            }

    if ((mType == ModelQualifier) || (mType == BiologyQualifier)) {
        // We seem to be dealing with either a model or a biology qualifier, so
        // check that its object is a valid MIRIAM URN

        if (QRegExp("^urn:miriam:[a-zA-Z0-9\\._%]+:[a-zA-Z0-9\\._%]+").exactMatch(mObject->asString())) {
            // The object is a valid MIRIAM URN, so retrieve its corresponding
            // URL

//---GRY--- TEMPORARY QUALIFIER URL... WE NEED TO RETRIEVE THE PROPER QUALIFIER
//          URL USING http://www.ebi.ac.uk/miriamws/main/rest/resolve/XXX

            mQualifierUrl = QUrl("http://www.opencor.ws/");
        } else {
            // The object is not a valid MIRIAM URN which means that the RDF
            // triple is not a valid model/biology qualifier

            mType = Unknown;

            mModelQualifierType   = ModelUnknown;
            mBiologyQualifierType = BiologyUnknown;
        }
    }
}

//==============================================================================

CellmlFileRdfTriple::~CellmlFileRdfTriple()
{
    // Delete some internal objects

    delete mSubject;
    delete mPredicate;
    delete mObject;
}

//==============================================================================

CellmlFileRdfTripleElement * CellmlFileRdfTriple::subject() const
{
    // Return the RDF triple's subject

    return mSubject;
}

//==============================================================================

CellmlFileRdfTripleElement * CellmlFileRdfTriple::predicate() const
{
    // Return the RDF triple's predicate

    return mPredicate;
}

//==============================================================================

CellmlFileRdfTripleElement * CellmlFileRdfTriple::object() const
{
    // Return the RDF triple's object

    return mObject;
}

//==============================================================================

CellmlFileRdfTriple::Type CellmlFileRdfTriple::type() const
{
    // Return the RDF triple's type

    return mType;
}

//==============================================================================

CellmlFileRdfTriple::ModelQualifierType CellmlFileRdfTriple::modelQualifierType() const
{
    // Return the RDF triple's model qualifier type

    return mModelQualifierType;
}

//==============================================================================

QString CellmlFileRdfTriple::modelQualifierTypeAsString() const
{
    // Return the RDF triple's model qualifier type as a string

    switch (mModelQualifierType) {
    case ModelIs:
        return QObject::tr("is");
    case ModelIsDerivedFrom:
        return QObject::tr("is derived from");
    case ModelIsDescribedBy:
        return QObject::tr("is described by");
    default:
        // ModelUnknown

        return "???";
    }
}

//==============================================================================

CellmlFileRdfTriple::BiologyQualifierType CellmlFileRdfTriple::biologyQualifierType() const
{
    // Return the RDF triple's biology qualifier type

    return mBiologyQualifierType;
}

//==============================================================================

QString CellmlFileRdfTriple::biologyQualifierTypeAsString() const
{
    // Return the RDF triple's biology qualifier type as a string

    switch (mBiologyQualifierType) {
    case BiologyEncodes:
        return QObject::tr("encodes");
    case BiologyHasPart:
        return QObject::tr("has part");
    case BiologyHasProperty:
        return QObject::tr("has property");
    case BiologyHasVersion:
        return QObject::tr("has version");
    case BiologyIs:
        return QObject::tr("is");
    case BiologyIsDescribedBy:
        return QObject::tr("is described by");
    case BiologyIsEncodedBy:
        return QObject::tr("is encoded by");
    case BiologyIsHomologTo:
        return QObject::tr("is homolog to");
    case BiologyIsPartOf:
        return QObject::tr("is part of");
    case BiologyIsPropertyOf:
        return QObject::tr("is property of");
    case BiologyIsVersionOf:
        return QObject::tr("is version of");
    case BiologyOccursIn:
        return QObject::tr("occurs in");
    case BiologyHasTaxon:
        return QObject::tr("has taxon");
    default:
        // BiologyUnknown

        return "???";
    }
}

//==============================================================================

QUrl CellmlFileRdfTriple::qualifierUrl() const
{
    // Return the RDF triple's qualifier URL

    return mQualifierUrl;
}

//==============================================================================

CellmlFileRdfTriple::Type CellmlFileRdfTriples::type() const
{
    // Return the type of the RDF triples
    // Note: if the RDF triples are of different types each then the overall
    //       type is considered to be unknown

    if (isEmpty()) {
        // There are no RDF triples, so...

        return CellmlFileRdfTriple::Unknown;
    } else {
        // There is at least one RDF triple, so retrieve the subject and type of
        // the first RDF triple and consider its type as the default type for
        // all our RDF triples

        CellmlFileRdfTriple *crtRdfTriple = first();

        QString subject = crtRdfTriple->subject()->asString();
        CellmlFileRdfTriple::Type res = crtRdfTriple->type();

        // Go through the remaining RDF triples and make sure that their type
        // is consistent with that of the first one

        for (int i = 2, iMax = count(); i < iMax; ++i) {
            crtRdfTriple = at(i);

            if (   crtRdfTriple->subject()->asString().compare(subject)
                || (crtRdfTriple->type() != res))
                // The subject and/or the type of the current RDF triple is
                // different from that of the first RDF triple, so...

                return CellmlFileRdfTriple::Unknown;
        }

        // All of the RDF triples have the same type, so...

        return res;
    }
}

//==============================================================================

}   // namespace CellMLSupport
}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>#ifndef ITER_ENUMERATE_H_
#define ITER_ENUMERATE_H_

#include "internal/iterator_wrapper.hpp"
#include "internal/iterbase.hpp"

#include <functional>
#include <initializer_list>
#include <iterator>
#include <type_traits>
#include <utility>

namespace iter {
  namespace impl {
    template <typename Container, typename Index>
    class Enumerable;

    using EnumerateFn = IterToolFnOptionalBindSecond<Enumerable, std::size_t>;
  }
  constexpr impl::EnumerateFn enumerate{};
}

template <typename Container, typename Index>
class iter::impl::Enumerable {
 private:
  Container container;
  const Index start;

  friend EnumerateFn;

  // for IterYield
  using BasePair = std::pair<Index, iterator_deref<Container>>;

  // Value constructor for use only in the enumerate function
  Enumerable(Container&& in_container, Index in_start)
      : container(std::forward<Container>(in_container)), start{in_start} {}

 public:
  Enumerable(Enumerable&&) = default;

  // "yielded" by the Enumerable::Iterator.  Has a .index, and a
  // .element referencing the value yielded by the subiterator
  class IterYield : public BasePair {
   public:
    using BasePair::BasePair;
    typename BasePair::first_type& index = BasePair::first;
    typename BasePair::second_type& element = BasePair::second;
  };

  //  Holds an iterator of the contained type and an Index for the
  //  index.  Each call to ++ increments both of these data members.
  //  Each dereference returns an IterYield.
  class Iterator : public std::iterator<std::input_iterator_tag, IterYield> {
   private:
    IteratorWrapper<Container> sub_iter;
    Index index;

   public:
    Iterator(IteratorWrapper<Container>&& si, Index start)
        : sub_iter{std::move(si)}, index{start} {}

    IterYield operator*() {
      return {this->index, *this->sub_iter};
    }

    ArrowProxy<IterYield> operator->() {
      return {**this};
    }

    Iterator& operator++() {
      ++this->sub_iter;
      ++this->index;
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return this->sub_iter != other.sub_iter;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {std::begin(this->container), start};
  }

  Iterator end() {
    return {std::end(this->container), start};
  }
};

#endif
<commit_msg>trailing _ on data members<commit_after>#ifndef ITER_ENUMERATE_H_
#define ITER_ENUMERATE_H_

#include "internal/iterator_wrapper.hpp"
#include "internal/iterbase.hpp"

#include <functional>
#include <initializer_list>
#include <iterator>
#include <type_traits>
#include <utility>

namespace iter {
  namespace impl {
    template <typename Container, typename Index>
    class Enumerable;

    using EnumerateFn = IterToolFnOptionalBindSecond<Enumerable, std::size_t>;
  }
  constexpr impl::EnumerateFn enumerate{};
}

template <typename Container, typename Index>
class iter::impl::Enumerable {
 private:
  Container container_;
  const Index start_;

  friend EnumerateFn;

  // for IterYield
  using BasePair = std::pair<Index, iterator_deref<Container>>;

  // Value constructor for use only in the enumerate function
  Enumerable(Container&& container, Index start)
      : container_(std::forward<Container>(container)), start_{start} {}

 public:
  Enumerable(Enumerable&&) = default;

  // "yielded" by the Enumerable::Iterator.  Has a .index, and a
  // .element referencing the value yielded by the subiterator
  class IterYield : public BasePair {
   public:
    using BasePair::BasePair;
    typename BasePair::first_type& index = BasePair::first;
    typename BasePair::second_type& element = BasePair::second;
  };

  //  Holds an iterator of the contained type and an Index for the
  //  index_.  Each call to ++ increments both of these data members.
  //  Each dereference returns an IterYield.
  class Iterator : public std::iterator<std::input_iterator_tag, IterYield> {
   private:
    IteratorWrapper<Container> sub_iter_;
    Index index_;

   public:
    Iterator(IteratorWrapper<Container>&& sub_iter, Index start)
        : sub_iter_{std::move(sub_iter)}, index_{start} {}

    IterYield operator*() {
      return {index_, *sub_iter_};
    }

    ArrowProxy<IterYield> operator->() {
      return {**this};
    }

    Iterator& operator++() {
      ++sub_iter_;
      ++index_;
      return *this;
    }

    Iterator operator++(int) {
      auto ret = *this;
      ++*this;
      return ret;
    }

    bool operator!=(const Iterator& other) const {
      return sub_iter_ != other.sub_iter_;
    }

    bool operator==(const Iterator& other) const {
      return !(*this != other);
    }
  };

  Iterator begin() {
    return {std::begin(container_), start_};
  }

  Iterator end() {
    return {std::end(container_), start_};
  }
};

#endif
<|endoftext|>


<commit_before>#include <possumwood_sdk/node_implementation.h>

#include <opencv2/opencv.hpp>

#include "frame.h"
#include "calibration_pattern.h"
#include "calibration_points.h"

namespace {

dependency_graph::InAttr<possumwood::opencv::CalibrationPattern> a_inObjectPattern, a_inCameraPattern;

dependency_graph::InAttr<possumwood::opencv::CalibrationPoints> a_inPoints;
dependency_graph::OutAttr<possumwood::opencv::CalibrationPoints> a_outPoints;

dependency_graph::State compute(dependency_graph::Values& data) {
	possumwood::opencv::CalibrationPoints points = data.get(a_inPoints);

	const cv::Mat& objPattern = *data.get(a_inObjectPattern);
	const cv::Mat& camPattern = *data.get(a_inCameraPattern);

	if(objPattern.rows != camPattern.rows)
		throw std::runtime_error("Number of object points doesn't match number of camera points - " + std::to_string(objPattern.rows) + " vs " + std::to_string(camPattern.rows));

	if(objPattern.size() != camPattern.size())
		throw std::runtime_error("Object and camera pattern sizes don't match!");

	// if empty, initialise
	if(points.empty())
		points = possumwood::opencv::CalibrationPoints(data.get(a_inCameraPattern).imageSize());

	// not empty - check for consistency
	else {
		if(points.imageSize() != data.get(a_inCameraPattern).imageSize())
			throw std::runtime_error("Points image size is not the same as camera pattern image size!");
	}

	// copy all the points
	possumwood::opencv::CalibrationPoints::Layer layer;
	for(int r=0;r<objPattern.rows;++r) {
		cv::Vec3f obj(objPattern.ptr<float>(r)[0], objPattern.ptr<float>(r)[1], 0.0f);
		cv::Vec2f cam(camPattern.ptr<float>(r)[0], camPattern.ptr<float>(r)[1]);

		layer.add(obj, cam);
	}
	points.addLayer(layer);

	std::cout << points << std::endl;

	data.set(a_outPoints, points);

	return dependency_graph::State();
}

void init(possumwood::Metadata& meta) {
	meta.addAttribute(a_inCameraPattern, "camera_pattern", possumwood::opencv::CalibrationPattern(), possumwood::AttrFlags::kVertical);
	meta.addAttribute(a_inObjectPattern, "object_pattern", possumwood::opencv::CalibrationPattern(), possumwood::AttrFlags::kVertical);

	meta.addAttribute(a_inPoints, "in_points");
	meta.addAttribute(a_outPoints, "out_points");

	meta.addInfluence(a_inCameraPattern, a_outPoints);
	meta.addInfluence(a_inObjectPattern, a_outPoints);
	meta.addInfluence(a_inPoints, a_outPoints);

	meta.setCompute(compute);
}

possumwood::NodeImplementation s_impl("opencv/calibration/calibration_points", init);

}
<commit_msg>Removed a missed printout in CalibrationPoints<commit_after>#include <possumwood_sdk/node_implementation.h>

#include <opencv2/opencv.hpp>

#include "frame.h"
#include "calibration_pattern.h"
#include "calibration_points.h"

namespace {

dependency_graph::InAttr<possumwood::opencv::CalibrationPattern> a_inObjectPattern, a_inCameraPattern;

dependency_graph::InAttr<possumwood::opencv::CalibrationPoints> a_inPoints;
dependency_graph::OutAttr<possumwood::opencv::CalibrationPoints> a_outPoints;

dependency_graph::State compute(dependency_graph::Values& data) {
	possumwood::opencv::CalibrationPoints points = data.get(a_inPoints);

	const cv::Mat& objPattern = *data.get(a_inObjectPattern);
	const cv::Mat& camPattern = *data.get(a_inCameraPattern);

	if(objPattern.rows != camPattern.rows)
		throw std::runtime_error("Number of object points doesn't match number of camera points - " + std::to_string(objPattern.rows) + " vs " + std::to_string(camPattern.rows));

	if(objPattern.size() != camPattern.size())
		throw std::runtime_error("Object and camera pattern sizes don't match!");

	// if empty, initialise
	if(points.empty())
		points = possumwood::opencv::CalibrationPoints(data.get(a_inCameraPattern).imageSize());

	// not empty - check for consistency
	else {
		if(points.imageSize() != data.get(a_inCameraPattern).imageSize())
			throw std::runtime_error("Points image size is not the same as camera pattern image size!");
	}

	// copy all the points
	possumwood::opencv::CalibrationPoints::Layer layer;
	for(int r=0;r<objPattern.rows;++r) {
		cv::Vec3f obj(objPattern.ptr<float>(r)[0], objPattern.ptr<float>(r)[1], 0.0f);
		cv::Vec2f cam(camPattern.ptr<float>(r)[0], camPattern.ptr<float>(r)[1]);

		layer.add(obj, cam);
	}
	points.addLayer(layer);

	data.set(a_outPoints, points);

	return dependency_graph::State();
}

void init(possumwood::Metadata& meta) {
	meta.addAttribute(a_inCameraPattern, "camera_pattern", possumwood::opencv::CalibrationPattern(), possumwood::AttrFlags::kVertical);
	meta.addAttribute(a_inObjectPattern, "object_pattern", possumwood::opencv::CalibrationPattern(), possumwood::AttrFlags::kVertical);

	meta.addAttribute(a_inPoints, "in_points");
	meta.addAttribute(a_outPoints, "out_points");

	meta.addInfluence(a_inCameraPattern, a_outPoints);
	meta.addInfluence(a_inObjectPattern, a_outPoints);
	meta.addInfluence(a_inPoints, a_outPoints);

	meta.setCompute(compute);
}

possumwood::NodeImplementation s_impl("opencv/calibration/calibration_points", init);

}
<|endoftext|>


<commit_before>// Copyright (c) 2018, Sergey Abbakumov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "rst/GUID/GUID.h"

#include <chrono>
#include <cstddef>
#include <random>

#include "rst/Check/Check.h"
#include "rst/NoDestructor/NoDestructor.h"

namespace chrono = std::chrono;

namespace rst {
namespace {

constexpr size_t kGUIDLength = 36;

bool IsHexDigit(const char c) {
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
         (c >= 'A' && c <= 'F');
}

bool IsLowerHexDigit(const char c) {
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}

bool IsValidGUIDInternal(const std::string_view guid, const bool strict) {
  if (guid.size() != kGUIDLength)
    return false;

  for (size_t i = 0; i < guid.size(); i++) {
    const auto current = guid[i];
    if (i == 8 || i == 13 || i == 18 || i == 23) {
      if (current != '-')
        return false;
    } else {
      if (strict ? !IsLowerHexDigit(current) : !IsHexDigit(current))
        return false;
    }
  }

  return true;
}

}  // namespace

std::string GenerateGUID() {
  static NoDestructor<std::default_random_engine> generator(
      static_cast<std::default_random_engine::result_type>(
          chrono::system_clock::now().time_since_epoch().count()));

  std::uniform_int_distribution<uint64_t> distribution;
  uint64_t sixteen_bytes[2] = {distribution(*generator),
                               distribution(*generator)};

  // Clear the version bits and set the version to 4:
  sixteen_bytes[0] &= 0xffffffff'ffff0fffULL;
  sixteen_bytes[0] |= 0x00000000'00004000ULL;

  // Set the two most significant bits (bits 6 and 7) of the
  // clock_seq_hi_and_reserved to zero and one, respectively:
  sixteen_bytes[1] &= 0x3fffffff'ffffffffULL;
  sixteen_bytes[1] |= 0x80000000'00000000ULL;

  return internal::RandomDataToGUIDString(sixteen_bytes);
}

bool IsValidGUID(const std::string_view guid) {
  return IsValidGUIDInternal(guid, false);
}

bool IsValidGUIDOutputString(const std::string_view guid) {
  return IsValidGUIDInternal(guid, true);
}

namespace internal {

std::string RandomDataToGUIDString(const uint64_t (&bytes)[2]) {
  char buffer[kGUIDLength + 1];
  const auto ret =
      std::sprintf(buffer, "%08x-%04x-%04x-%04x-%012llx",
                   static_cast<unsigned int>(bytes[0] >> 32),
                   static_cast<unsigned int>((bytes[0] >> 16) & 0x0000ffff),
                   static_cast<unsigned int>(bytes[0] & 0x0000ffff),
                   static_cast<unsigned int>(bytes[1] >> 48),
                   bytes[1] & 0x0000ffff'ffffffffULL);
  RST_DCHECK(ret == kGUIDLength);
  return buffer;
}

}  // namespace internal
}  // namespace rst
<commit_msg>Use true random numbers for GUIDs<commit_after>// Copyright (c) 2018, Sergey Abbakumov
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "rst/GUID/GUID.h"

#include <cstddef>
#include <random>

#include "rst/Check/Check.h"
#include "rst/NoDestructor/NoDestructor.h"

namespace rst {
namespace {

constexpr size_t kGUIDLength = 36;

bool IsHexDigit(const char c) {
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
         (c >= 'A' && c <= 'F');
}

bool IsLowerHexDigit(const char c) {
  return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f');
}

bool IsValidGUIDInternal(const std::string_view guid, const bool strict) {
  if (guid.size() != kGUIDLength)
    return false;

  for (size_t i = 0; i < guid.size(); i++) {
    const auto current = guid[i];
    if (i == 8 || i == 13 || i == 18 || i == 23) {
      if (current != '-')
        return false;
    } else {
      if (strict ? !IsLowerHexDigit(current) : !IsHexDigit(current))
        return false;
    }
  }

  return true;
}

}  // namespace

std::string GenerateGUID() {
  static rst::NoDestructor<std::random_device> random_device;

  std::uniform_int_distribution<uint64_t> distribution;
  uint64_t sixteen_bytes[2] = {distribution(*random_device),
                               distribution(*random_device)};

  // Clear the version bits and set the version to 4:
  sixteen_bytes[0] &= 0xffffffff'ffff0fffULL;
  sixteen_bytes[0] |= 0x00000000'00004000ULL;

  // Set the two most significant bits (bits 6 and 7) of the
  // clock_seq_hi_and_reserved to zero and one, respectively:
  sixteen_bytes[1] &= 0x3fffffff'ffffffffULL;
  sixteen_bytes[1] |= 0x80000000'00000000ULL;

  return internal::RandomDataToGUIDString(sixteen_bytes);
}

bool IsValidGUID(const std::string_view guid) {
  return IsValidGUIDInternal(guid, false);
}

bool IsValidGUIDOutputString(const std::string_view guid) {
  return IsValidGUIDInternal(guid, true);
}

namespace internal {

std::string RandomDataToGUIDString(const uint64_t (&bytes)[2]) {
  char buffer[kGUIDLength + 1];
  const auto ret =
      std::sprintf(buffer, "%08x-%04x-%04x-%04x-%012llx",
                   static_cast<unsigned int>(bytes[0] >> 32),
                   static_cast<unsigned int>((bytes[0] >> 16) & 0x0000ffff),
                   static_cast<unsigned int>(bytes[0] & 0x0000ffff),
                   static_cast<unsigned int>(bytes[1] >> 48),
                   bytes[1] & 0x0000ffff'ffffffffULL);
  RST_DCHECK(ret == kGUIDLength);
  return buffer;
}

}  // namespace internal
}  // namespace rst
<|endoftext|>


<commit_before>//=====================================================================//
/*! @file
    @brief  RX64M UART(SCI1)サンプル @n
			・P07(176) ピンに赤色LED（VF:1.9V）を吸い込みで接続する @n
			Copyright 2017 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/sci_io.hpp"
#include "common/cmt_io.hpp"
#include "common/fifo.hpp"
#include "common/format.hpp"

#include "RX64M/rtc.hpp"
#include "common/delay.hpp"

namespace {

	class cmt_task {
	public:
		void operator() () {
		}
	};

	device::cmt_io<device::CMT0, cmt_task>  cmt_;

	typedef utils::fifo<uint8_t, 128> buffer;
	device::sci_io<device::SCI1, buffer, buffer> sci_;
}

extern "C" {

	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	char sci_getch(void)
	{
		return sci_.getch();
	}
}

int main(int argc, char** argv);

int main(int argc, char** argv)
{
	device::SYSTEM::PRCR = 0xA50B;	// クロック、低消費電力、関係書き込み許可

	device::SYSTEM::MOSCWTCR = 9;	// 1ms wait
	// メインクロック強制発振とドライブ能力設定
	device::SYSTEM::MOFCR = device::SYSTEM::MOFCR.MODRV2.b(0b10)
						  | device::SYSTEM::MOFCR.MOFXIN.b();
	device::SYSTEM::MOSCCR.MOSTP = 0;		// メインクロック発振器動作
	while(device::SYSTEM::OSCOVFSR.MOOVF() == 0) asm("nop");

	device::SYSTEM::PLLCR.STC = 0b010011;		// PLL 10 倍(120MHz)
	device::SYSTEM::PLLCR2.PLLEN = 0;			// PLL 動作
	while(device::SYSTEM::OSCOVFSR.PLOVF() == 0) asm("nop");

	device::SYSTEM::SCKCR = device::SYSTEM::SCKCR.FCK.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.ICK.b(0)		// 1/1 (120/1=120)
						  | device::SYSTEM::SCKCR.BCK.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.PCKA.b(0)		// 1/1 (120/1=120)
						  | device::SYSTEM::SCKCR.PCKB.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.PCKC.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.PCKD.b(1);	// 1/2 (120/2=60)
	device::SYSTEM::SCKCR2.UCK = 0b0100;  // USB Clock: 1/5 (120/5=24)
	device::SYSTEM::SCKCR3.CKSEL = 0b100;	///< PLL 選択

	{  // タイマー設定（６０Ｈｚ）
		uint8_t int_level = 4;
		cmt_.start(60, int_level);
	}

	{  // SCI 設定
		uint8_t int_level = 2;
		sci_.start(115200, int_level);
	}

	utils::format("RX64M start\n");

	device::PORT0::PDR.B5 = 1;
	device::PORT0::PDR.B7 = 1;

	uint32_t cnt = 0;
	uint32_t n = 0;
	while(1) {
		cmt_.sync();

		if(sci_.recv_length()) {
			auto ch = sci_.getch();
			sci_.putch(ch);
		}

		++cnt;
		if(cnt >= 30) {
			cnt = 0;
		}
		device::PORT0::PODR.B7 = (cnt < 10) ? 0 : 1;

		utils::delay::micro_second(1);
		device::PORT0::PODR.B5 = 0;
		utils::delay::micro_second(1);
		device::PORT0::PODR.B5 = 1;

		if((n % 60) == 0) {
			utils::format("%d\n") % (n / 60);
		}
		++n;
	}
}
<commit_msg>update<commit_after>//=====================================================================//
/*! @file
    @brief  RX64M UART(SCI1)サンプル @n
			・P07(176) ピンに赤色LED（VF:1.9V）を吸い込みで接続する @n
			Copyright 2017 Kunihito Hiramatsu
    @author 平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include "common/renesas.hpp"

#include "common/sci_io.hpp"
#include "common/cmt_io.hpp"
#include "common/fifo.hpp"
#include "common/format.hpp"
#include "common/delay.hpp"
#include "common/command.hpp"

namespace {

	class cmt_task {
	public:
		void operator() () {
		}
	};

	device::cmt_io<device::CMT0, cmt_task>  cmt_;

	typedef utils::fifo<uint8_t, 128> buffer;
	device::sci_io<device::SCI1, buffer, buffer> sci_;

	utils::command<256> cmd_;
}

extern "C" {

	void sci_putch(char ch)
	{
		sci_.putch(ch);
	}

	char sci_getch(void)
	{
		return sci_.getch();
	}

	void sci_puts(const char *str)
	{
		sci_.puts(str);
	}

	uint16_t sci_length(void)
	{
		return sci_.recv_length();
	}
}

int main(int argc, char** argv);

int main(int argc, char** argv)
{
	device::SYSTEM::PRCR = 0xA50B;	// クロック、低消費電力、関係書き込み許可

	device::SYSTEM::MOSCWTCR = 9;	// 1ms wait
	// メインクロック強制発振とドライブ能力設定
	device::SYSTEM::MOFCR = device::SYSTEM::MOFCR.MODRV2.b(0b10)
						  | device::SYSTEM::MOFCR.MOFXIN.b();
	device::SYSTEM::MOSCCR.MOSTP = 0;		// メインクロック発振器動作
	while(device::SYSTEM::OSCOVFSR.MOOVF() == 0) asm("nop");

	device::SYSTEM::PLLCR.STC = 0b010011;		// PLL 10 倍(120MHz)
	device::SYSTEM::PLLCR2.PLLEN = 0;			// PLL 動作
	while(device::SYSTEM::OSCOVFSR.PLOVF() == 0) asm("nop");

	device::SYSTEM::SCKCR = device::SYSTEM::SCKCR.FCK.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.ICK.b(0)		// 1/1 (120/1=120)
						  | device::SYSTEM::SCKCR.BCK.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.PCKA.b(0)		// 1/1 (120/1=120)
						  | device::SYSTEM::SCKCR.PCKB.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.PCKC.b(1)		// 1/2 (120/2=60)
						  | device::SYSTEM::SCKCR.PCKD.b(1);	// 1/2 (120/2=60)
	device::SYSTEM::SCKCR2.UCK = 0b0100;  // USB Clock: 1/5 (120/5=24)
	device::SYSTEM::SCKCR3.CKSEL = 0b100;	///< PLL 選択

	{  // タイマー設定（６０Ｈｚ）
		uint8_t int_level = 4;
		cmt_.start(60, int_level);
	}

	{  // SCI 設定
		uint8_t int_level = 2;
		sci_.start(115200, int_level);
	}

	utils::format("RX64M SCI sample start\n");

	cmd_.set_prompt("# ");

	device::PORT0::PDR.B5 = 1;
	device::PORT0::PDR.B7 = 1;

	uint32_t cnt = 0;
	while(1) {
		cmt_.sync();

		if(cmd_.service()) {

		}

		++cnt;
		if(cnt >= 30) {
			cnt = 0;
		}
		device::PORT0::PODR.B7 = (cnt < 10) ? 0 : 1;
	}
}
<|endoftext|>


<commit_before><commit_msg>Added argue<commit_after><|endoftext|>


<commit_before>#pragma once
#include "../geometry/rect2d.hpp"

#include "../base/mutex.hpp"

#include "../std/deque.hpp"
#include "../std/string.hpp"
#include "../std/utility.hpp"
#include "../std/vector.hpp"

// Information about stored mwm.
struct MwmInfo
{
  m2::RectD m_limitRect;    // Limit rect of mwm.
  uint8_t m_minScale;       // Min zoom level of mwm.
  uint8_t m_maxScale;       // Max zoom level of mwm.

  // Does this MwmInfo represent a valid Mwm?
  bool isValid() const { return m_status == STATUS_ACTIVE; }
private:
  friend class MwmSet;

  enum Status { STATUS_ACTIVE = 0, STATUS_TO_REMOVE = 1, STATUS_REMOVED = 2 };
  uint8_t m_lockCount;      // Number of locks.
  uint8_t m_status;         //
};

class MwmSet
{
public:
  typedef size_t MwmId;

  explicit MwmSet(size_t cacheSize = 5);
  virtual ~MwmSet() = 0;

  class MwmValueBase
  {
  public:
    virtual ~MwmValueBase() {}
  };

  // Mwm lock, which is used to lock mwm when its FileContainer is used.
  class MwmLock
  {
  public:
    MwmLock(MwmSet const & mwmSet, MwmId mwmId);
    ~MwmLock();

    inline MwmValueBase * GetValue() const { return m_pValue; }
    string GetCountryName() const;

  private:
    MwmSet const & m_mwmSet;
    MwmId m_id;
    MwmValueBase * m_pValue;
  };

  /// Add new mwm. Returns false, if mwm with given fileName already exists.
  /// @param[in]  fileName  File name (without full path) of country.
  /// @param[out] r         Limit rect of country.
  /// @return Map format version or -1 if not added
  int Add(string const & fileName, m2::RectD & r);
  inline bool Add(string const & fileName)
  {
    m2::RectD dummy;
    return Add(fileName, dummy);
  }

  // Remove mwm.
  void Remove(string const & fileName);

  // Get ids of all mwms. Some of them may be marked to remove.
  void GetMwmInfo(vector<MwmInfo> & info) const;

  // Clear caches.
  void ClearCache();

protected:
  /// @return mwm format version
  virtual int GetInfo(string const & name, MwmInfo & info) const = 0;
  virtual MwmValueBase * CreateValue(string const & name) const = 0;

  void Cleanup();

private:
  static const MwmId INVALID_MWM_ID = static_cast<MwmId>(-1);

  typedef deque<pair<MwmId, MwmValueBase *> > CacheType;

  // Update given MwmInfo.
  inline static void UpdateMwmInfo(MwmInfo & info);

  MwmValueBase * LockValue(MwmId id) const;
  void UnlockValue(MwmId id, MwmValueBase * p) const;

  // Find first removed mwm or add a new one.
  MwmId GetFreeId();

  // Find mwm with a given name.
  MwmId GetIdByName(string const & name);

  // Do the cleaning for [beg, end) without acquiring the mutex.
  void ClearCacheImpl(CacheType::iterator beg, CacheType::iterator end);

  mutable vector<MwmInfo> m_info;
  mutable vector<string> m_name;
  mutable CacheType m_cache;
  size_t m_cacheSize;
  mutable threads::Mutex m_lock;
};
<commit_msg>Make MwmInfo a class, not a struct.<commit_after>#pragma once
#include "../geometry/rect2d.hpp"

#include "../base/mutex.hpp"

#include "../std/deque.hpp"
#include "../std/string.hpp"
#include "../std/utility.hpp"
#include "../std/vector.hpp"

// Information about stored mwm.
class MwmInfo
{
public:
  m2::RectD m_limitRect;    // Limit rect of mwm.
  uint8_t m_minScale;       // Min zoom level of mwm.
  uint8_t m_maxScale;       // Max zoom level of mwm.

  // Does this MwmInfo represent a valid Mwm?
  bool isValid() const { return m_status == STATUS_ACTIVE; }
private:
  friend class MwmSet;

  enum Status { STATUS_ACTIVE = 0, STATUS_TO_REMOVE = 1, STATUS_REMOVED = 2 };
  uint8_t m_lockCount;      // Number of locks.
  uint8_t m_status;         //
};

class MwmSet
{
public:
  typedef size_t MwmId;

  explicit MwmSet(size_t cacheSize = 5);
  virtual ~MwmSet() = 0;

  class MwmValueBase
  {
  public:
    virtual ~MwmValueBase() {}
  };

  // Mwm lock, which is used to lock mwm when its FileContainer is used.
  class MwmLock
  {
  public:
    MwmLock(MwmSet const & mwmSet, MwmId mwmId);
    ~MwmLock();

    inline MwmValueBase * GetValue() const { return m_pValue; }
    string GetCountryName() const;

  private:
    MwmSet const & m_mwmSet;
    MwmId m_id;
    MwmValueBase * m_pValue;
  };

  /// Add new mwm. Returns false, if mwm with given fileName already exists.
  /// @param[in]  fileName  File name (without full path) of country.
  /// @param[out] r         Limit rect of country.
  /// @return Map format version or -1 if not added
  int Add(string const & fileName, m2::RectD & r);
  inline bool Add(string const & fileName)
  {
    m2::RectD dummy;
    return Add(fileName, dummy);
  }

  // Remove mwm.
  void Remove(string const & fileName);

  // Get ids of all mwms. Some of them may be marked to remove.
  void GetMwmInfo(vector<MwmInfo> & info) const;

  // Clear caches.
  void ClearCache();

protected:
  /// @return mwm format version
  virtual int GetInfo(string const & name, MwmInfo & info) const = 0;
  virtual MwmValueBase * CreateValue(string const & name) const = 0;

  void Cleanup();

private:
  static const MwmId INVALID_MWM_ID = static_cast<MwmId>(-1);

  typedef deque<pair<MwmId, MwmValueBase *> > CacheType;

  // Update given MwmInfo.
  inline static void UpdateMwmInfo(MwmInfo & info);

  MwmValueBase * LockValue(MwmId id) const;
  void UnlockValue(MwmId id, MwmValueBase * p) const;

  // Find first removed mwm or add a new one.
  MwmId GetFreeId();

  // Find mwm with a given name.
  MwmId GetIdByName(string const & name);

  // Do the cleaning for [beg, end) without acquiring the mutex.
  void ClearCacheImpl(CacheType::iterator beg, CacheType::iterator end);

  mutable vector<MwmInfo> m_info;
  mutable vector<string> m_name;
  mutable CacheType m_cache;
  size_t m_cacheSize;
  mutable threads::Mutex m_lock;
};
<|endoftext|>


<commit_before>#include "NL_Renderer.h"
#include "NLCore\NL_ISystem.h"
#include "NLCore\NL_IEngine.h"
#include "NL_RenderingEngine.h"
#include "NLCore\NL_SDistributor.h"
#include "NL_SharedContainers.h"
#include "NL_Systems.h"
#include "NL_Allocator.h"
#include "NL_Camera.h"

#include <assert.h>
#include <iostream>
#include <thread>
#include <chrono>

#define _USE_MATH_DEFINES
#include <math.h>

namespace NLE
{
	namespace GRAPHICS
	{
		Renderer::Renderer() :
			_initialized(false),
			_firstMouse(true),
			_screenWidth(0),
			_screenHeight(0)
		{
			_running.fetch_and_store(false);
			_renderingEngine = std::make_unique<RenderingEngine>();
			_camera = nullptr;

			_cameraPos = alloc<DirectX::XMVECTOR>(16);
			_cameraFront = alloc<DirectX::XMVECTOR>(16);
			_cameraUp = alloc<DirectX::XMVECTOR>(16);
			_viewProjection = alloc<DirectX::XMMATRIX>(16);

			*_cameraPos = DirectX::XMVectorSet(0.0f, 0.0f, 3.0f, 0.0f);
			*_cameraFront = DirectX::XMVectorSet(0.0f, 0.0f, -1.0f, 0.0f);
			*_cameraUp = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
			*_viewProjection = DirectX::XMMatrixIdentity();

			_cameraSpeedConst = 0.00005f;
			_sensitivity = 0.5f;
			_yaw = 0;
			_pitch = 0;
			_aspect = 1.0f;

			_lastCursorX = 0.0f;
			_lastCursorY = 0.0f;
			_firstCameraUpdate = true;
		}

		Renderer::~Renderer()
		{

		}

		bool Renderer::initialize(Core::IEngine& engine)
		{
			assert(!_initialized && _screenWidth > 0 && _screenHeight > 0);

			_camera = std::make_unique<Camera>(0.0f, 0.5f, -10.0f, _screenWidth, _screenHeight);

			_cameraCommands = &static_cast<NLE::Core::Data::SDistributor<char>*>(&engine.getSDistributor(CAMERA_COMMANDS))->buildEndpoint(SYS::SYS_RENDERER);
			_cursorCoords = &static_cast<NLE::Core::Data::SDistributor<double>*>(&engine.getSDistributor(CURSOR_COORDINATES))->buildEndpoint(SYS::SYS_RENDERER);
			_scrollOffset = &static_cast<NLE::Core::Data::SDistributor<double>*>(&engine.getSDistributor(SCROLL_OFFSET))->buildEndpoint(SYS::SYS_RENDERER);

			if (!_renderingEngine->initialize())
			{
				std::this_thread::sleep_for(std::chrono::seconds(10));
				return false;
			}

			_procedure = [&](){
				if (!_running)
				{
					printf("Starting Rendering task\n");
					_running.fetch_and_store(true);
					_renderingThread = new std::thread([&](Renderer& renderer, std::unique_ptr<RenderingEngine> const& renderingEngine){
						printf("Rendering Thread running\n");
						while (renderer.isRunning())
						{
							renderingEngine->render(renderer.getViewProjection());
						}
					}, std::ref(*this), std::ref(_renderingEngine));
				}
				computeViewProjection();
			};

			_initialized = true;
			return true;
		}

		void Renderer::computeViewProjection()
		{
			auto cameraCommands = *_cameraCommands;
			auto cursorCoords = *_cursorCoords;
			auto scrollOffset = *_scrollOffset;

			if (cameraCommands[COMMANDS::CAMERA::FORWARD] && !cameraCommands[COMMANDS::CAMERA::REVERSE])
			{
				_camera->moveForward();
			}
			else if (cameraCommands[COMMANDS::CAMERA::REVERSE] && !cameraCommands[COMMANDS::CAMERA::FORWARD])
			{
				_camera->moveBackward();
			}

			if (cameraCommands[COMMANDS::CAMERA::LEFT] && !cameraCommands[COMMANDS::CAMERA::RIGHT])
			{
				_camera->moveLeft();
			}
			else if (cameraCommands[COMMANDS::CAMERA::RIGHT] && !cameraCommands[COMMANDS::CAMERA::LEFT])
			{
				_camera->moveRight();
			}

			float xPos = (float)cursorCoords[0];	// retrieve cursor x coordinate
			float yPos = (float)cursorCoords[1];	// retrieve cursor y coordinate

			if (_firstCameraUpdate)
			{
				_lastCursorX = xPos;
				_lastCursorY = yPos;
				_firstCameraUpdate = false;
			}

			float yaw = xPos - _lastCursorX;
			float pitch = yPos - _lastCursorY;
			_lastCursorX = xPos;
			_lastCursorY = yPos;

			_camera->rotate(yaw * 0.001f, pitch * 0.001f);

			_camera->update();
			setViewProjection(_camera->getViewProjection());
		}

		void Renderer::setViewProjection(DirectX::XMMATRIX& viewProjection)
		{
			tbb::spin_mutex::scoped_lock lock(_viewProjectionLock);
			*_viewProjection = viewProjection;
		}

		DirectX::XMMATRIX Renderer::getViewProjection()
		{
			tbb::spin_mutex::scoped_lock lock(_viewProjectionLock);
			return *_viewProjection;
		}

		float Renderer::toRadians(float degrees)
		{
			const double halfC = M_PI / 180;
			return (float)((double)degrees * halfC);
		}

		bool Renderer::isRunning()
		{
			return _running;
		}

		void Renderer::stop()
		{
			_running.fetch_and_store(false);
		}

		void Renderer::release()
		{
			stop();
			_renderingEngine->release();
			_initialized = false;
		}

		bool Renderer::initialized()
		{
			return _initialized;
		}

		std::function<void()> const& Renderer::getExecutionProcedure()
		{
			return _procedure;
		}

		Core::ISystem& Renderer::getInterface()
		{
			return *this;
		}

		void Renderer::setWindowHandle(void* handle)
		{
			_renderingEngine->setWindowHandle(handle);
		}

		void Renderer::setScreenDimensions(uint_fast32_t width, uint_fast32_t height)
		{
			_screenWidth = width;
			_screenHeight = height;

			_renderingEngine->setScreenDimensions(width, height);
		}

		void Renderer::setFullscreen(bool fullscreen)
		{
			_renderingEngine->setFullscreen(fullscreen);
		}
	}
}<commit_msg>Bug Fix - releasing resources while rendering<commit_after>#include "NL_Renderer.h"
#include "NLCore\NL_ISystem.h"
#include "NLCore\NL_IEngine.h"
#include "NL_RenderingEngine.h"
#include "NLCore\NL_SDistributor.h"
#include "NL_SharedContainers.h"
#include "NL_Systems.h"
#include "NL_Allocator.h"
#include "NL_Camera.h"

#include <assert.h>
#include <iostream>
#include <thread>
#include <chrono>

#define _USE_MATH_DEFINES
#include <math.h>

namespace NLE
{
	namespace GRAPHICS
	{
		Renderer::Renderer() :
			_initialized(false),
			_firstMouse(true),
			_screenWidth(0),
			_screenHeight(0)
		{
			_running.fetch_and_store(false);
			_renderingEngine = std::make_unique<RenderingEngine>();
			_camera = nullptr;

			_cameraPos = alloc<DirectX::XMVECTOR>(16);
			_cameraFront = alloc<DirectX::XMVECTOR>(16);
			_cameraUp = alloc<DirectX::XMVECTOR>(16);
			_viewProjection = alloc<DirectX::XMMATRIX>(16);

			*_cameraPos = DirectX::XMVectorSet(0.0f, 0.0f, 3.0f, 0.0f);
			*_cameraFront = DirectX::XMVectorSet(0.0f, 0.0f, -1.0f, 0.0f);
			*_cameraUp = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
			*_viewProjection = DirectX::XMMatrixIdentity();

			_cameraSpeedConst = 0.00005f;
			_sensitivity = 0.5f;
			_yaw = 0;
			_pitch = 0;
			_aspect = 1.0f;

			_lastCursorX = 0.0f;
			_lastCursorY = 0.0f;
			_firstCameraUpdate = true;
		}

		Renderer::~Renderer()
		{

		}

		bool Renderer::initialize(Core::IEngine& engine)
		{
			assert(!_initialized && _screenWidth > 0 && _screenHeight > 0);

			_camera = std::make_unique<Camera>(0.0f, 0.5f, -10.0f, _screenWidth, _screenHeight);

			_cameraCommands = &static_cast<NLE::Core::Data::SDistributor<char>*>(&engine.getSDistributor(CAMERA_COMMANDS))->buildEndpoint(SYS::SYS_RENDERER);
			_cursorCoords = &static_cast<NLE::Core::Data::SDistributor<double>*>(&engine.getSDistributor(CURSOR_COORDINATES))->buildEndpoint(SYS::SYS_RENDERER);
			_scrollOffset = &static_cast<NLE::Core::Data::SDistributor<double>*>(&engine.getSDistributor(SCROLL_OFFSET))->buildEndpoint(SYS::SYS_RENDERER);

			if (!_renderingEngine->initialize())
			{
				std::this_thread::sleep_for(std::chrono::seconds(10));
				return false;
			}

			_procedure = [&](){
				if (!_running)
				{
					printf("Starting Rendering task\n");
					_running.fetch_and_store(true);
					_renderingThread = new std::thread([&](Renderer& renderer, std::unique_ptr<RenderingEngine> const& renderingEngine){
						printf("Rendering Thread running\n");
						while (renderer.isRunning())
						{
							renderingEngine->render(renderer.getViewProjection());
						}
					}, std::ref(*this), std::ref(_renderingEngine));
				}
				computeViewProjection();
			};

			_initialized = true;
			return true;
		}

		void Renderer::computeViewProjection()
		{
			auto cameraCommands = *_cameraCommands;
			auto cursorCoords = *_cursorCoords;
			auto scrollOffset = *_scrollOffset;

			if (cameraCommands[COMMANDS::CAMERA::FORWARD] && !cameraCommands[COMMANDS::CAMERA::REVERSE])
			{
				_camera->moveForward();
			}
			else if (cameraCommands[COMMANDS::CAMERA::REVERSE] && !cameraCommands[COMMANDS::CAMERA::FORWARD])
			{
				_camera->moveBackward();
			}

			if (cameraCommands[COMMANDS::CAMERA::LEFT] && !cameraCommands[COMMANDS::CAMERA::RIGHT])
			{
				_camera->moveLeft();
			}
			else if (cameraCommands[COMMANDS::CAMERA::RIGHT] && !cameraCommands[COMMANDS::CAMERA::LEFT])
			{
				_camera->moveRight();
			}

			float xPos = (float)cursorCoords[0];	// retrieve cursor x coordinate
			float yPos = (float)cursorCoords[1];	// retrieve cursor y coordinate

			if (_firstCameraUpdate)
			{
				_lastCursorX = xPos;
				_lastCursorY = yPos;
				_firstCameraUpdate = false;
			}

			float yaw = xPos - _lastCursorX;
			float pitch = yPos - _lastCursorY;
			_lastCursorX = xPos;
			_lastCursorY = yPos;

			_camera->rotate(yaw * 0.001f, pitch * 0.001f);

			_camera->update();
			setViewProjection(_camera->getViewProjection());
		}

		void Renderer::setViewProjection(DirectX::XMMATRIX& viewProjection)
		{
			tbb::spin_mutex::scoped_lock lock(_viewProjectionLock);
			*_viewProjection = viewProjection;
		}

		DirectX::XMMATRIX Renderer::getViewProjection()
		{
			tbb::spin_mutex::scoped_lock lock(_viewProjectionLock);
			return *_viewProjection;
		}

		float Renderer::toRadians(float degrees)
		{
			const double halfC = M_PI / 180;
			return (float)((double)degrees * halfC);
		}

		bool Renderer::isRunning()
		{
			return _running;
		}

		void Renderer::stop()
		{
			_running.fetch_and_store(false);
		}

		void Renderer::release()
		{
			stop();
			_renderingThread->join();
			_renderingEngine->release();
			_initialized = false;
		}

		bool Renderer::initialized()
		{
			return _initialized;
		}

		std::function<void()> const& Renderer::getExecutionProcedure()
		{
			return _procedure;
		}

		Core::ISystem& Renderer::getInterface()
		{
			return *this;
		}

		void Renderer::setWindowHandle(void* handle)
		{
			_renderingEngine->setWindowHandle(handle);
		}

		void Renderer::setScreenDimensions(uint_fast32_t width, uint_fast32_t height)
		{
			_screenWidth = width;
			_screenHeight = height;

			_renderingEngine->setScreenDimensions(width, height);
		}

		void Renderer::setFullscreen(bool fullscreen)
		{
			_renderingEngine->setFullscreen(fullscreen);
		}
	}
}<|endoftext|>


<commit_before>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2001, CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI, and Rajesh Raman.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU Lesser General
 * Public License as published by the Free Software Foundation.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 *********************************************************************/

#include "common.h"
#include "lexer.h"
#include "exprTree.h"
#include "collection.h"
#include "collectionBase.h"
#include "classad.h"

BEGIN_NAMESPACE( classad )
//-------------classad templates --------------

template map<string, bool>;

// function table
template map<string, void*, CaseIgnLTStr>;
template map<string, void*, CaseIgnLTStr>::iterator;

// XML attributes
template map<string, string>;
template map<string, string>::iterator;

// attribute list
template hash_map<string, ExprTree*, StringCaseIgnHash, CaseIgnEqStr>;
template hash_map<string, ExprTree*, StringCaseIgnHash, CaseIgnEqStr>::iterator;
template hash_map<string, ExprTree*, StringCaseIgnHash, CaseIgnEqStr>::const_iterator;

// expr evaluation cache
template hash_map<const ExprTree*, Value, ExprHash >;
template hash_map<const ExprTree*, Value, ExprHash >::iterator;

// component stuff
template vector< pair<string, ExprTree*> >;
template vector<ExprTree*>;

template map<string, ClassAd *>;
template map<string, ClassAdCollection *>;

#ifdef CLASSAD_DISTRIBUTION
template vector<string>;
#include "transaction.h"
#include "view.h"

// view content
template multiset<ViewMember, ViewMemberLT>;
template multiset<ViewMember, ViewMemberLT>::iterator;

// list of sub-views
template slist<View*>;

// view registry
template hash_map<string,View*,StringHash>;
template hash_map<string,View*,StringHash>::iterator;

// index
template hash_map<string,multiset<ViewMember,ViewMemberLT>::iterator,
    StringHash>::iterator;
template hash_map<string,multiset<ViewMember,ViewMemberLT>::iterator,
    StringHash>;

// main classad table
template hash_map<string, ClassAdProxy, StringHash>;
template hash_map<string, ClassAdProxy, StringHash>::iterator;

// transaction registry
template hash_map<string, ServerTransaction*, StringHash>;
template hash_map<string, ServerTransaction*, StringHash>::iterator;

// operations in transaction
template list<XactionRecord>;
#endif

class _ClassAdInit
{
	public:
		_ClassAdInit( ) { tzset( ); }
} __ClassAdInit;

END_NAMESPACE
<commit_msg>Added some.<commit_after>/*********************************************************************
 *
 * Condor ClassAd library
 * Copyright (C) 1990-2001, CONDOR Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI, and Rajesh Raman.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of version 2.1 of the GNU Lesser General
 * Public License as published by the Free Software Foundation.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 *********************************************************************/

#include "common.h"
#include "lexer.h"
#include "exprTree.h"
#include "collection.h"
#include "collectionBase.h"
#include "classad.h"

BEGIN_NAMESPACE( classad )
//-------------classad templates --------------

template map<string, bool>;

// function table
template map<string, void*, CaseIgnLTStr>;
template map<string, void*, CaseIgnLTStr>::iterator;

// XML attributes
template map<string, string>;
template map<string, string>::iterator;

// attribute list
template hash_map<string, ExprTree*, StringCaseIgnHash, CaseIgnEqStr>;
template hash_map<string, ExprTree*, StringCaseIgnHash, CaseIgnEqStr>::iterator;
template hash_map<string, ExprTree*, StringCaseIgnHash, CaseIgnEqStr>::const_iterator;

// expr evaluation cache
template hash_map<const ExprTree*, Value, ExprHash >;
template hash_map<const ExprTree*, Value, ExprHash >::iterator;

// component stuff
template vector< pair<string, ExprTree*> >;
template vector<ExprTree*>;

template map<string, ClassAd *>;
template map<string, ClassAdCollection *>;

#ifdef CLASSAD_DISTRIBUTION
template vector<string>;
#include "transaction.h"
#include "view.h"

// view content
template multiset<ViewMember, ViewMemberLT>;
template multiset<ViewMember, ViewMemberLT>::iterator;

// list of sub-views
template slist<View*>;

// view registry
template hash_map<string,View*,StringHash>;
template hash_map<string,View*,StringHash>::iterator;

// index
template hash_map<string,multiset<ViewMember,ViewMemberLT>::iterator,
    StringHash>::iterator;
template hash_map<string,multiset<ViewMember,ViewMemberLT>::iterator,
    StringHash>;

// main classad table
template hash_map<string, ClassAdProxy, StringHash>;
template hash_map<string, ClassAdProxy, StringHash>::iterator;

// index file
template map<string, int>;
template hash_map<string,int,StringHash>;
template hash_map<string,int,StringHash>::iterator;

// transaction registry
template hash_map<string, ServerTransaction*, StringHash>;
template hash_map<string, ServerTransaction*, StringHash>::iterator;

// operations in transaction
template list<XactionRecord>;
#endif

class _ClassAdInit
{
	public:
		_ClassAdInit( ) { tzset( ); }
} __ClassAdInit;

END_NAMESPACE
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
 * License: https://github.com/dbartolini/crown/blob/master/LICENSE
 */

#include "core/thread/condition_variable.h"
#if CROWN_PLATFORM_WINDOWS
	#include <synchapi.h>
#endif

namespace crown
{
ConditionVariable::ConditionVariable()
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_init(&_cond, NULL);
	CE_ASSERT(err == 0, "pthread_cond_init: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	InitializeConditionVariable(&_cv);
#endif
}

ConditionVariable::~ConditionVariable()
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_destroy(&_cond);
	CE_ASSERT(err == 0, "pthread_cond_destroy: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	// Do nothing
#endif
}

void ConditionVariable::wait(Mutex& mutex)
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_wait(&_cond, &mutex._mutex);
	CE_ASSERT(err == 0, "pthread_cond_wait: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	SleepConditionVariableCS(&_cv, &mutex._cs, INFINITE);
#endif
}

void ConditionVariable::signal()
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_signal(&_cond);
	CE_ASSERT(err == 0, "pthread_cond_signal: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	WakeConditionVariable(&_cv);
#endif
}

} // namespace crown
<commit_msg>core: cleanup<commit_after>/*
 * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
 * License: https://github.com/dbartolini/crown/blob/master/LICENSE
 */

#include "core/thread/condition_variable.h"

namespace crown
{
ConditionVariable::ConditionVariable()
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_init(&_cond, NULL);
	CE_ASSERT(err == 0, "pthread_cond_init: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	InitializeConditionVariable(&_cv);
#endif
}

ConditionVariable::~ConditionVariable()
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_destroy(&_cond);
	CE_ASSERT(err == 0, "pthread_cond_destroy: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	// Do nothing
#endif
}

void ConditionVariable::wait(Mutex& mutex)
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_wait(&_cond, &mutex._mutex);
	CE_ASSERT(err == 0, "pthread_cond_wait: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	SleepConditionVariableCS(&_cv, &mutex._cs, INFINITE);
#endif
}

void ConditionVariable::signal()
{
#if CROWN_PLATFORM_POSIX
	int err = pthread_cond_signal(&_cond);
	CE_ASSERT(err == 0, "pthread_cond_signal: errno = %d", err);
	CE_UNUSED(err);
#elif CROWN_PLATFORM_WINDOWS
	WakeConditionVariable(&_cv);
#endif
}

} // namespace crown
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <geometry_msgs/TwistStamped.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl_ros/transforms.h>
#include <multisense_sensor_model/sensor_model.h>
#include <cylbot_mcl/pose_cloud.h>
#include <string>
#include <tf/transform_listener.h>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <pcl/filters/extract_indices.h>

using namespace multisense_sensor_model;
using namespace cylbot_mcl;

void laserCallback(const sensor_msgs::PointCloud2::ConstPtr& laser_points,
				   const tf::TransformListener& tf_listener,
				   PoseCloud2D* pose_cloud)
{
	sensor_msgs::PointCloud2 map_ros_cloud;
	if(!tf_listener.waitForTransform(
		   "/map",
		   "/base_link",
		   laser_points->header.stamp,
		   ros::Duration(1.0)))
	{
		ROS_WARN("Transform from /map to /base_link failed");
		return;
	}
	pcl_ros::transformPointCloud("/map", *laser_points, map_ros_cloud, tf_listener);

	tf::StampedTransform laser_transform;
	if(!tf_listener.waitForTransform(
		   "/map",
		   "/head_hokuyo_frame",
		   laser_points->header.stamp,
		   ros::Duration(1.0)))
	{
		ROS_WARN("Transform from /map to /head_hokuyo_frame failed");
		return;
	}

	tf_listener.lookupTransform("/map", "/head_hokuyo_frame", laser_points->header.stamp, laser_transform);
	tf::Vector3 beam_start = laser_transform.getOrigin();

	pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_raw_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::fromROSMsg(map_ros_cloud, *pcl_raw_cloud);

	pcl::PointIndices::Ptr invalid_indices(new pcl::PointIndices);
	int i=0;
	for(pcl::PointCloud<pcl::PointXYZ>::const_iterator point = pcl_raw_cloud->points.begin();
		point != pcl_raw_cloud->points.end();
		point++)
	{
		// calculate 3D beam length and check for max value
		double x = point->x - beam_start.x();
		double y = point->y - beam_start.y();
		double z = point->z - beam_start.z();
		double beam_length_3d = sqrt(x*x + y*y + z*z);
		if(fabs(beam_length_3d - 30.0) < .04)
		{
			invalid_indices->indices.push_back(i);
			i++;
			continue;
		}

		// check if point is in the plane (or at least close to it)
		if(point->z > 1.2 || point->z < .8)
		{
			invalid_indices->indices.push_back(i);
			i++;
			continue;
		}

		// check if the beam is within the robot's cylinder
		double beam_length_2d = sqrt(x*x + y*y);
		if(fabs(beam_length_2d ) < .5)
		{
			invalid_indices->indices.push_back(i);
			i++;
			continue;
		}
	}

	pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::ExtractIndices<pcl::PointXYZ> invalid_filter;
	invalid_filter.setInputCloud(pcl_raw_cloud);
	invalid_filter.setKeepOrganized(true);
	invalid_filter.setNegative(true);
	invalid_filter.setIndices(invalid_indices);
	invalid_filter.filter(*pcl_cloud);

	beam_start.setZ(0);

	pose_cloud->sensorUpdate(*pcl_cloud, beam_start);
}

void initialPoseCallback(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& initial_pose,
						 PoseCloud2D* pose_cloud,
						 const int num_particles)
{
	pose_cloud->resetCloud(*initial_pose, num_particles);
}

void velocityCallback(const geometry_msgs::TwistStamped::ConstPtr& twist_msg,
					  PoseCloud2D* pose_cloud,
					  geometry_msgs::TwistStamped::ConstPtr& last_cmd)
{
	ros::Duration dt = twist_msg->header.stamp - last_cmd->header.stamp;
	last_cmd = twist_msg;

	pose_cloud->motionUpdate(twist_msg->twist, dt.toSec());
}

void mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& map,
				 PoseCloud2D* pose_cloud)
{
	pose_cloud->mapUpdate(*map);
}

int main(int argc, char** argv)
{
	ros::init(argc, argv, "localization_2d");

	ros::NodeHandle nh;

	tf::TransformListener tf_listener;

	ros::NodeHandle priv_nh("~");
	std::string sensor_params_file = "";
	priv_nh.getParam("sensor_params_file", sensor_params_file);

	IntrinsicParams sensor_params;
	if(sensor_params_file.compare("") == 0)
	{
		ROS_WARN("Sensor params file not provided or not valid");
	}
	else
	{
		readIntrinsicParamsFromFile(sensor_params_file, &sensor_params);
	}

	RobotModel model(sensor_params);
	PoseCloud2D pose_cloud(model);

	ros::Subscriber laser_sub = nh.subscribe<sensor_msgs::PointCloud2>("/laser/points", 1,
																	   boost::bind(laserCallback,
																				   _1,
																				   boost::ref(tf_listener),
																				   &pose_cloud));
	ros::Subscriber initial_pose_sub = nh.subscribe<geometry_msgs::PoseWithCovarianceStamped>("/initial_pose", 1,
																							  boost::bind(initialPoseCallback,
																										  _1,
																										  &pose_cloud,
																										  1000));

	geometry_msgs::TwistStamped::ConstPtr last_velocity;
	ros::Subscriber vel_sub = nh.subscribe<geometry_msgs::TwistStamped>("/cylbot/velocity", 1,
																		boost::bind(velocityCallback,
																					_1,
																					&pose_cloud,
																					boost::ref(last_velocity)));

	ros::Subscriber map_sub = nh.subscribe<nav_msgs::OccupancyGrid>("/map", 1, boost::bind(mapCallback, _1, &pose_cloud));

	ros::Publisher pose_array_pub = nh.advertise<geometry_msgs::PoseArray>("/pose_cloud", 1);

	ros::Rate loop_rate(100);
	while(ros::ok())
	{
		geometry_msgs::PoseArray pose_array = pose_cloud.getPoses();
		pose_array.header.stamp = ros::Time::now();
		pose_array.header.frame_id = "/map";
		pose_array_pub.publish(pose_array);

		ros::spinOnce();
		loop_rate.sleep();
	}
}
<commit_msg>Fixed the initial pose topic name.<commit_after>#include <ros/ros.h>
#include <geometry_msgs/PoseWithCovarianceStamped.h>
#include <geometry_msgs/TwistStamped.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_ros/point_cloud.h>
#include <pcl_ros/transforms.h>
#include <multisense_sensor_model/sensor_model.h>
#include <cylbot_mcl/pose_cloud.h>
#include <string>
#include <tf/transform_listener.h>
#include <boost/bind.hpp>
#include <boost/ref.hpp>
#include <pcl/filters/extract_indices.h>

using namespace multisense_sensor_model;
using namespace cylbot_mcl;

void laserCallback(const sensor_msgs::PointCloud2::ConstPtr& laser_points,
				   const tf::TransformListener& tf_listener,
				   PoseCloud2D* pose_cloud)
{
	sensor_msgs::PointCloud2 map_ros_cloud;
	if(!tf_listener.waitForTransform(
		   "/map",
		   "/base_link",
		   laser_points->header.stamp,
		   ros::Duration(1.0)))
	{
		ROS_WARN("Transform from /map to /base_link failed");
		return;
	}
	pcl_ros::transformPointCloud("/map", *laser_points, map_ros_cloud, tf_listener);

	tf::StampedTransform laser_transform;
	if(!tf_listener.waitForTransform(
		   "/map",
		   "/head_hokuyo_frame",
		   laser_points->header.stamp,
		   ros::Duration(1.0)))
	{
		ROS_WARN("Transform from /map to /head_hokuyo_frame failed");
		return;
	}

	tf_listener.lookupTransform("/map", "/head_hokuyo_frame", laser_points->header.stamp, laser_transform);
	tf::Vector3 beam_start = laser_transform.getOrigin();

	pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_raw_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::fromROSMsg(map_ros_cloud, *pcl_raw_cloud);

	pcl::PointIndices::Ptr invalid_indices(new pcl::PointIndices);
	int i=0;
	for(pcl::PointCloud<pcl::PointXYZ>::const_iterator point = pcl_raw_cloud->points.begin();
		point != pcl_raw_cloud->points.end();
		point++)
	{
		// calculate 3D beam length and check for max value
		double x = point->x - beam_start.x();
		double y = point->y - beam_start.y();
		double z = point->z - beam_start.z();
		double beam_length_3d = sqrt(x*x + y*y + z*z);
		if(fabs(beam_length_3d - 30.0) < .04)
		{
			invalid_indices->indices.push_back(i);
			i++;
			continue;
		}

		// check if point is in the plane (or at least close to it)
		if(point->z > 1.2 || point->z < .8)
		{
			invalid_indices->indices.push_back(i);
			i++;
			continue;
		}

		// check if the beam is within the robot's cylinder
		double beam_length_2d = sqrt(x*x + y*y);
		if(fabs(beam_length_2d ) < .5)
		{
			invalid_indices->indices.push_back(i);
			i++;
			continue;
		}
	}

	pcl::PointCloud<pcl::PointXYZ>::Ptr pcl_cloud(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::ExtractIndices<pcl::PointXYZ> invalid_filter;
	invalid_filter.setInputCloud(pcl_raw_cloud);
	invalid_filter.setKeepOrganized(true);
	invalid_filter.setNegative(true);
	invalid_filter.setIndices(invalid_indices);
	invalid_filter.filter(*pcl_cloud);

	beam_start.setZ(0);

	pose_cloud->sensorUpdate(*pcl_cloud, beam_start);
}

void initialPoseCallback(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& initial_pose,
						 PoseCloud2D* pose_cloud,
						 const int num_particles)
{
	pose_cloud->resetCloud(*initial_pose, num_particles);
}

void velocityCallback(const geometry_msgs::TwistStamped::ConstPtr& twist_msg,
					  PoseCloud2D* pose_cloud,
					  geometry_msgs::TwistStamped::ConstPtr& last_cmd)
{
	if(last_cmd == NULL)
	{
		last_cmd = twist_msg;
		return;
	}
	ros::Duration dt = twist_msg->header.stamp - last_cmd->header.stamp;
	last_cmd = twist_msg;

	pose_cloud->motionUpdate(twist_msg->twist, dt.toSec());
}

void mapCallback(const nav_msgs::OccupancyGrid::ConstPtr& map,
				 PoseCloud2D* pose_cloud)
{
	pose_cloud->mapUpdate(*map);
}

int main(int argc, char** argv)
{
	ros::init(argc, argv, "localization_2d");

	ros::NodeHandle nh;

	tf::TransformListener tf_listener;

	ros::NodeHandle priv_nh("~");
	std::string sensor_params_file = "";
	priv_nh.getParam("sensor_params_file", sensor_params_file);

	IntrinsicParams sensor_params;
	if(sensor_params_file.compare("") == 0)
	{
		ROS_WARN("Sensor params file not provided or not valid");
	}
	else
	{
		readIntrinsicParamsFromFile(sensor_params_file, &sensor_params);
	}

	RobotModel model(sensor_params);
	PoseCloud2D pose_cloud(model);

	ros::Subscriber laser_sub = nh.subscribe<sensor_msgs::PointCloud2>("/laser/points", 1,
																	   boost::bind(laserCallback,
																				   _1,
																				   boost::ref(tf_listener),
																				   &pose_cloud));
	ros::Subscriber initial_pose_sub = nh.subscribe<geometry_msgs::PoseWithCovarianceStamped>("/initialpose", 1,
																							  boost::bind(initialPoseCallback,
																										  _1,
																										  &pose_cloud,
																										  1000));

	geometry_msgs::TwistStamped::ConstPtr last_velocity;
	ros::Subscriber vel_sub = nh.subscribe<geometry_msgs::TwistStamped>("/cylbot/velocity", 1,
																		boost::bind(velocityCallback,
																					_1,
																					&pose_cloud,
																					boost::ref(last_velocity)));

	ros::Subscriber map_sub = nh.subscribe<nav_msgs::OccupancyGrid>("/map", 1, boost::bind(mapCallback, _1, &pose_cloud));

	ros::Publisher pose_array_pub = nh.advertise<geometry_msgs::PoseArray>("/pose_cloud", 1);

	ros::Rate loop_rate(100);
	while(ros::ok())
	{
		geometry_msgs::PoseArray pose_array = pose_cloud.getPoses();
		pose_array.header.stamp = ros::Time::now();
		pose_array.header.frame_id = "/map";
		pose_array_pub.publish(pose_array);

		ros::spinOnce();
		loop_rate.sleep();
	}
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qobject_p.h"
#include "qmlstategroup.h"
#include "qmltransition.h"
#include <QtDeclarative/qmlbinding.h>
#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);

QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,StateGroup,QmlStateGroup)

class QmlStateGroupPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QmlStateGroup)
public:
    QmlStateGroupPrivate(QmlStateGroup *p)
    : nullState(0), states(p), componentComplete(true), ignoreTrans(false) {}

    QString currentState;
    QmlState *nullState;

    struct StateList : public QmlConcreteList<QmlState *>
    {
        StateList(QmlStateGroup *g)
            :group(g) {}
        void append(QmlState *s) {
            QmlConcreteList<QmlState *>::append(s);
            if (s) s->setStateGroup(group);
        }
    private:
        QmlStateGroup *group;
    };
    StateList states;

    QmlConcreteList<QmlTransition *> transitions;
    bool componentComplete;
    bool ignoreTrans;

    QmlTransition *findTransition(const QString &from, const QString &to);
    void setCurrentStateInternal(const QString &state, bool = false);
    void updateAutoState();
};

QmlStateGroup::QmlStateGroup(QObject *parent)
    : QObject(*(new QmlStateGroupPrivate(this)), parent)
{
}

QmlStateGroup::~QmlStateGroup()
{
}

QList<QmlState *> QmlStateGroup::states() const
{
    Q_D(const QmlStateGroup);
    return d->states;
}

QmlList<QmlState *>* QmlStateGroup::statesProperty()
{
    Q_D(QmlStateGroup);
    return &(d->states);
}

QmlList<QmlTransition *>* QmlStateGroup::transitionsProperty()
{
    Q_D(QmlStateGroup);
    return &(d->transitions);
}

QString QmlStateGroup::state() const
{
    Q_D(const QmlStateGroup);
    return d->currentState;
}

void QmlStateGroup::setState(const QString &state)
{
    Q_D(QmlStateGroup);
    if (d->currentState == state)
        return;

    d->setCurrentStateInternal(state);

    d->currentState = state;
    emit stateChanged(d->currentState);
}

void QmlStateGroup::classBegin()
{
    Q_D(QmlStateGroup);
    d->componentComplete = false;
}

void QmlStateGroup::updateAutoState()
{
    Q_D(QmlStateGroup);
    d->updateAutoState();
}

void QmlStateGroupPrivate::updateAutoState()
{
    Q_Q(QmlStateGroup);
    if (!componentComplete)
        return;

    bool revert = false;
    for (int ii = 0; ii < states.count(); ++ii) {
        QmlState *state = states.at(ii);
        if (state->isWhenKnown()) {
            if (!state->name().isEmpty()) {
                if (state->when() && state->when()->value().toBool()) {
                    if (stateChangeDebug())
                        qWarning() << "Setting auto state due to:"
                                   << state->when()->expression();
                    q->setState(state->name());
                    return;
                } else if (state->name() == currentState) {
                    revert = true;
                }
            }
        }
    }
    if (revert)
        q->setState(QString());
}

QmlTransition *QmlStateGroupPrivate::findTransition(const QString &from, const QString &to)
{
    QmlTransition *highest = 0;
    int score = 0;
    bool reversed = false;
    bool done = false;

    for (int ii = 0; !done && ii < transitions.count(); ++ii) {
        QmlTransition *t = transitions.at(ii);
        for (int ii = 0; ii < 2; ++ii)
        {
            if (ii && (!t->reversible() ||
                      (t->fromState() == QLatin1String("*") &&
                       t->toState() == QLatin1String("*"))))
                break;
            QStringList fromState;
            QStringList toState;

            fromState = t->fromState().split(QLatin1Char(','));
            toState = t->toState().split(QLatin1Char(','));
            if (ii == 1)
                qSwap(fromState, toState);
            int tScore = 0;
            if (fromState.contains(from))
                tScore += 2;
            else if (fromState.contains(QLatin1String("*")))
                tScore += 1;
            else
                continue;

            if (toState.contains(to))
                tScore += 2;
            else if (toState.contains(QLatin1String("*")))
                tScore += 1;
            else
                continue;

            if (ii == 1)
                reversed = true;
            else
                reversed = false;

            if (tScore == 4) {
                highest = t;
                done = true;
                break;
            } else if (tScore > score) {
                score = tScore;
                highest = t;
            }
        }
    }

    if (highest)
        highest->setReversed(reversed);

    return highest;
}

void QmlStateGroupPrivate::setCurrentStateInternal(const QString &state,
                                                   bool ignoreTrans)
{
    Q_Q(QmlStateGroup);
    if (!componentComplete)
        return;

    QmlTransition *transition = (ignoreTrans || ignoreTrans) ? 0 : findTransition(currentState, state);
    if (stateChangeDebug()) {
        qWarning() << this << "Changing state.  From" << currentState << ". To" << state;
        if (transition)
            qWarning() << "   using transition" << transition->fromState()
                       << transition->toState();
    }

    QmlState *oldState = 0;
    if (!currentState.isEmpty()) {
        for (int ii = 0; ii < states.count(); ++ii) {
            if (states.at(ii)->name() == currentState) {
                oldState = states.at(ii);
                break;
            }
        }
    }

    currentState = state;

    QmlState *newState = 0;
    for (int ii = 0; ii < states.count(); ++ii) {
        if (states.at(ii)->name() == currentState) {
            newState = states.at(ii);
            break;
        }
    }

    if (oldState == 0 || newState == 0) {
        if (!nullState) { nullState = new QmlState(q); }
        if (!oldState) oldState = nullState;
        if (!newState) newState = nullState;
    }

    newState->apply(q, transition, oldState);
}

void QmlStateGroup::componentComplete()
{
    Q_D(QmlStateGroup);
    d->updateAutoState();
    d->componentComplete = true;
    if (!d->currentState.isEmpty()) {
        QString cs = d->currentState;
        d->currentState = QString();
        d->setCurrentStateInternal(cs, true);
    }
}

QmlState *QmlStateGroup::findState(const QString &name) const
{
    Q_D(const QmlStateGroup);
    for (int i = 0; i < d->states.count(); ++i) {
        QmlState *state = d->states.at(i);
        if (state->name() == name)
            return state;
    }

    return 0;
}

QT_END_NAMESPACE
<commit_msg>Fix regression introduced in classComplete -> componentComplete.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** Contact: Qt Software Information (qt-info@nokia.com)
**
** This file is part of the QtDeclarative module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "private/qobject_p.h"
#include "qmlstategroup.h"
#include "qmltransition.h"
#include <QtDeclarative/qmlbinding.h>
#include <QtCore/qdebug.h>

QT_BEGIN_NAMESPACE

DEFINE_BOOL_CONFIG_OPTION(stateChangeDebug, STATECHANGE_DEBUG);

QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,StateGroup,QmlStateGroup)

class QmlStateGroupPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QmlStateGroup)
public:
    QmlStateGroupPrivate(QmlStateGroup *p)
    : nullState(0), states(p), componentComplete(true), ignoreTrans(false) {}

    QString currentState;
    QmlState *nullState;

    struct StateList : public QmlConcreteList<QmlState *>
    {
        StateList(QmlStateGroup *g)
            :group(g) {}
        void append(QmlState *s) {
            QmlConcreteList<QmlState *>::append(s);
            if (s) s->setStateGroup(group);
        }
    private:
        QmlStateGroup *group;
    };
    StateList states;

    QmlConcreteList<QmlTransition *> transitions;
    bool componentComplete;
    bool ignoreTrans;

    QmlTransition *findTransition(const QString &from, const QString &to);
    void setCurrentStateInternal(const QString &state, bool = false);
    void updateAutoState();
};

QmlStateGroup::QmlStateGroup(QObject *parent)
    : QObject(*(new QmlStateGroupPrivate(this)), parent)
{
}

QmlStateGroup::~QmlStateGroup()
{
}

QList<QmlState *> QmlStateGroup::states() const
{
    Q_D(const QmlStateGroup);
    return d->states;
}

QmlList<QmlState *>* QmlStateGroup::statesProperty()
{
    Q_D(QmlStateGroup);
    return &(d->states);
}

QmlList<QmlTransition *>* QmlStateGroup::transitionsProperty()
{
    Q_D(QmlStateGroup);
    return &(d->transitions);
}

QString QmlStateGroup::state() const
{
    Q_D(const QmlStateGroup);
    return d->currentState;
}

void QmlStateGroup::setState(const QString &state)
{
    Q_D(QmlStateGroup);
    if (d->currentState == state)
        return;

    d->setCurrentStateInternal(state);

    d->currentState = state;
    emit stateChanged(d->currentState);
}

void QmlStateGroup::classBegin()
{
    Q_D(QmlStateGroup);
    d->componentComplete = false;
}

void QmlStateGroup::componentComplete()
{
    Q_D(QmlStateGroup);
    d->componentComplete = true;
    d->updateAutoState();
    if (!d->currentState.isEmpty()) {
        QString cs = d->currentState;
        d->currentState = QString();
        d->setCurrentStateInternal(cs, true);
    }
}

void QmlStateGroup::updateAutoState()
{
    Q_D(QmlStateGroup);
    d->updateAutoState();
}

void QmlStateGroupPrivate::updateAutoState()
{
    Q_Q(QmlStateGroup);
    if (!componentComplete)
        return;

    bool revert = false;
    for (int ii = 0; ii < states.count(); ++ii) {
        QmlState *state = states.at(ii);
        if (state->isWhenKnown()) {
            if (!state->name().isEmpty()) {
                if (state->when() && state->when()->value().toBool()) {
                    if (stateChangeDebug())
                        qWarning() << "Setting auto state due to:"
                                   << state->when()->expression();
                    q->setState(state->name());
                    return;
                } else if (state->name() == currentState) {
                    revert = true;
                }
            }
        }
    }
    if (revert)
        q->setState(QString());
}

QmlTransition *QmlStateGroupPrivate::findTransition(const QString &from, const QString &to)
{
    QmlTransition *highest = 0;
    int score = 0;
    bool reversed = false;
    bool done = false;

    for (int ii = 0; !done && ii < transitions.count(); ++ii) {
        QmlTransition *t = transitions.at(ii);
        for (int ii = 0; ii < 2; ++ii)
        {
            if (ii && (!t->reversible() ||
                      (t->fromState() == QLatin1String("*") &&
                       t->toState() == QLatin1String("*"))))
                break;
            QStringList fromState;
            QStringList toState;

            fromState = t->fromState().split(QLatin1Char(','));
            toState = t->toState().split(QLatin1Char(','));
            if (ii == 1)
                qSwap(fromState, toState);
            int tScore = 0;
            if (fromState.contains(from))
                tScore += 2;
            else if (fromState.contains(QLatin1String("*")))
                tScore += 1;
            else
                continue;

            if (toState.contains(to))
                tScore += 2;
            else if (toState.contains(QLatin1String("*")))
                tScore += 1;
            else
                continue;

            if (ii == 1)
                reversed = true;
            else
                reversed = false;

            if (tScore == 4) {
                highest = t;
                done = true;
                break;
            } else if (tScore > score) {
                score = tScore;
                highest = t;
            }
        }
    }

    if (highest)
        highest->setReversed(reversed);

    return highest;
}

void QmlStateGroupPrivate::setCurrentStateInternal(const QString &state,
                                                   bool ignoreTrans)
{
    Q_Q(QmlStateGroup);
    if (!componentComplete)
        return;

    QmlTransition *transition = (ignoreTrans || ignoreTrans) ? 0 : findTransition(currentState, state);
    if (stateChangeDebug()) {
        qWarning() << this << "Changing state.  From" << currentState << ". To" << state;
        if (transition)
            qWarning() << "   using transition" << transition->fromState()
                       << transition->toState();
    }

    QmlState *oldState = 0;
    if (!currentState.isEmpty()) {
        for (int ii = 0; ii < states.count(); ++ii) {
            if (states.at(ii)->name() == currentState) {
                oldState = states.at(ii);
                break;
            }
        }
    }

    currentState = state;

    QmlState *newState = 0;
    for (int ii = 0; ii < states.count(); ++ii) {
        if (states.at(ii)->name() == currentState) {
            newState = states.at(ii);
            break;
        }
    }

    if (oldState == 0 || newState == 0) {
        if (!nullState) { nullState = new QmlState(q); }
        if (!oldState) oldState = nullState;
        if (!newState) newState = nullState;
    }

    newState->apply(q, transition, oldState);
}

QmlState *QmlStateGroup::findState(const QString &name) const
{
    Q_D(const QmlStateGroup);
    for (int i = 0; i < d->states.count(); ++i) {
        QmlState *state = d->states.at(i);
        if (state->name() == name)
            return state;
    }

    return 0;
}

QT_END_NAMESPACE
<|endoftext|>