<commit_before>#include "NodeType.h"
#include "NodeFactory.h"

#include <opencv2/features2d/features2d.hpp>
using std::unique_ptr;

class BriskFeatureDetectorNodeType : public NodeType
{
public:
	BriskFeatureDetectorNodeType()
		: _thresh(30)
		, _nOctaves(3)
		, _patternScale(1.0f)
		, _brisk(new cv::BRISK())
	{
	}

	bool setProperty(PropertyID propId, const QVariant& newValue) override
	{
		if(propId > ID_PatternScale || propId < ID_Threshold)
			return false;

		switch(propId)
		{
		case ID_Threshold:
			_thresh = newValue.toInt();
		case ID_NumOctaves:
			_nOctaves = newValue.toInt();
		case ID_PatternScale:
			_patternScale  = newValue.toFloat();
		}

		// That's a bit cheating here - creating BRISK object takes time (approx. 200ms for PAL)
		// which if done per frame makes it slowish (more than SIFT actually)
		_brisk = unique_ptr<cv::BRISK>(new cv::BRISK(_thresh, _nOctaves, _patternScale));
		return true;
	}

	QVariant property(PropertyID propId) const override
	{
		switch(propId)
		{
		case ID_Threshold: return _thresh;
		case ID_NumOctaves: return _nOctaves;
		case ID_PatternScale: return _patternScale;
		}

		return QVariant();
	}

	ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
	{
		const cv::Mat& src = reader.readSocket(0).getImage();
		cv::KeyPoints& keypoints = writer.acquireSocket(0).getKeypoints();

		if(src.rows == 0 || src.cols == 0)
			return ExecutionStatus(EStatus::Ok);

		_brisk->detect(src, keypoints);

		return ExecutionStatus(EStatus::Ok);
	}

	void configuration(NodeConfig& nodeConfig) const override
	{
		static const InputSocketConfig in_config[] = {
			{ ENodeFlowDataType::Image, "image", "Image", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};
		static const OutputSocketConfig out_config[] = {
			{ ENodeFlowDataType::Keypoints, "keypoints", "Keypoints", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};
		static const PropertyConfig prop_config[] = {
			{ EPropertyType::Integer, "FAST/AGAST detection threshold score", "min:1" },
			{ EPropertyType::Integer, "Number of octaves", "min:0" },
			{ EPropertyType::Double, "Pattern scale", "min:0.0" },
			{ EPropertyType::Unknown, "", "" }
		};

		nodeConfig.description = "";
		nodeConfig.pInputSockets = in_config;
		nodeConfig.pOutputSockets = out_config;
		nodeConfig.pProperties = prop_config;
	}

protected:
	enum EPropertyID
	{
		ID_Threshold,
		ID_NumOctaves,
		ID_PatternScale
	};

	int _thresh;
	int _nOctaves;
	float _patternScale;
	// Must be pointer since BRISK doesn't implement copy/move operator (they should have)
	unique_ptr<cv::BRISK> _brisk;
};

class BriskFeatureExtractorNodeType : public NodeType
{
public:
	BriskFeatureExtractorNodeType()
		: _brisk(new cv::BRISK())
	{
	}

	ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
	{
		const cv::Mat& imageSrc = reader.readSocket(0).getImage();
		const cv::KeyPoints& keypoints = reader.readSocket(1).getKeypoints();

		if(keypoints.empty() || imageSrc.cols == 0 || imageSrc.rows == 0)
			return ExecutionStatus(EStatus::Ok);

		cv::Mat& outDescriptors = writer.acquireSocket(0).getArray();
		cv::KeyPoints& outKeypoints = writer.acquireSocket(1).getKeypoints();

		outKeypoints = keypoints;
		_brisk->compute(imageSrc, outKeypoints, outDescriptors);

		return ExecutionStatus(EStatus::Ok);
	}

	void configuration(NodeConfig& nodeConfig) const override
	{
		static const InputSocketConfig in_config[] = {
			{ ENodeFlowDataType::Image, "source", "Image", "" },
			{ ENodeFlowDataType::Keypoints, "keypoints", "Keypoints", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};
		static const OutputSocketConfig out_config[] = {
			{ ENodeFlowDataType::Array, "output", "Descriptors", "" },
			{ ENodeFlowDataType::Keypoints, "output", "Keypoints", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};

		nodeConfig.description = "";
		nodeConfig.pInputSockets = in_config;
		nodeConfig.pOutputSockets = out_config;
	}

private:
	// Must be pointer since BRISK doesn't implement copy/move operator (they should have)
	unique_ptr<cv::BRISK> _brisk;
};

class BriskNodeType : public BriskFeatureDetectorNodeType
{
public:

	ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
	{
		const cv::Mat& src = reader.readSocket(0).getImage();
		cv::KeyPoints& keypoints = writer.acquireSocket(0).getKeypoints();
		cv::Mat& descriptors = writer.acquireSocket(1).getArray();

		if(src.rows == 0 || src.cols == 0)
			return ExecutionStatus(EStatus::Ok);

		//cv::BRISK(_thresh, _nOctaves, _patternScale)
		(*_brisk)(src, cv::noArray(), keypoints, descriptors);

		return ExecutionStatus(EStatus::Ok);
	}

	void configuration(NodeConfig& nodeConfig) const override
	{
		BriskFeatureDetectorNodeType::configuration(nodeConfig);

		static const OutputSocketConfig out_config[] = {
			{ ENodeFlowDataType::Keypoints, "keypoints", "Keypoints", "" },
			{ ENodeFlowDataType::Array, "output", "Descriptors", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};

		nodeConfig.description = "";
		nodeConfig.pOutputSockets = out_config;
	}
};

REGISTER_NODE("Features/BRISK Extractor", BriskFeatureExtractorNodeType)
REGISTER_NODE("Features/BRISK Detector", BriskFeatureDetectorNodeType)
REGISTER_NODE("Features/BRISK", BriskNodeType)<commit_msg>fixed brisk property setter<commit_after>#include "NodeType.h"
#include "NodeFactory.h"

#include <opencv2/features2d/features2d.hpp>
using std::unique_ptr;

class BriskFeatureDetectorNodeType : public NodeType
{
public:
	BriskFeatureDetectorNodeType()
		: _thresh(30)
		, _nOctaves(3)
		, _patternScale(1.0f)
		, _brisk(new cv::BRISK())
	{
	}

	bool setProperty(PropertyID propId, const QVariant& newValue) override
	{
		if(propId > ID_PatternScale || propId < ID_Threshold)
			return false;

		switch(propId)
		{
		case ID_Threshold:
			_thresh = newValue.toInt();
			break;
		case ID_NumOctaves:
			_nOctaves = newValue.toInt();
			break;
		case ID_PatternScale:
			_patternScale  = newValue.toFloat();
			break;
		}

		// That's a bit cheating here - creating BRISK object takes time (approx. 200ms for PAL)
		// which if done per frame makes it slowish (more than SIFT actually)
		_brisk = unique_ptr<cv::BRISK>(new cv::BRISK(_thresh, _nOctaves, _patternScale));
		return true;
	}

	QVariant property(PropertyID propId) const override
	{
		switch(propId)
		{
		case ID_Threshold: return _thresh;
		case ID_NumOctaves: return _nOctaves;
		case ID_PatternScale: return _patternScale;
		}

		return QVariant();
	}

	ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
	{
		const cv::Mat& src = reader.readSocket(0).getImage();
		cv::KeyPoints& keypoints = writer.acquireSocket(0).getKeypoints();

		if(src.rows == 0 || src.cols == 0)
			return ExecutionStatus(EStatus::Ok);

		_brisk->detect(src, keypoints);

		return ExecutionStatus(EStatus::Ok);
	}

	void configuration(NodeConfig& nodeConfig) const override
	{
		static const InputSocketConfig in_config[] = {
			{ ENodeFlowDataType::Image, "image", "Image", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};
		static const OutputSocketConfig out_config[] = {
			{ ENodeFlowDataType::Keypoints, "keypoints", "Keypoints", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};
		static const PropertyConfig prop_config[] = {
			{ EPropertyType::Integer, "FAST/AGAST detection threshold score", "min:1" },
			{ EPropertyType::Integer, "Number of octaves", "min:0" },
			{ EPropertyType::Double, "Pattern scale", "min:0.0" },
			{ EPropertyType::Unknown, "", "" }
		};

		nodeConfig.description = "";
		nodeConfig.pInputSockets = in_config;
		nodeConfig.pOutputSockets = out_config;
		nodeConfig.pProperties = prop_config;
	}

protected:
	enum EPropertyID
	{
		ID_Threshold,
		ID_NumOctaves,
		ID_PatternScale
	};

	int _thresh;
	int _nOctaves;
	float _patternScale;
	// Must be pointer since BRISK doesn't implement copy/move operator (they should have)
	unique_ptr<cv::BRISK> _brisk;
};

class BriskFeatureExtractorNodeType : public NodeType
{
public:
	BriskFeatureExtractorNodeType()
		: _brisk(new cv::BRISK())
	{
	}

	ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
	{
		const cv::Mat& imageSrc = reader.readSocket(0).getImage();
		const cv::KeyPoints& keypoints = reader.readSocket(1).getKeypoints();

		if(keypoints.empty() || imageSrc.cols == 0 || imageSrc.rows == 0)
			return ExecutionStatus(EStatus::Ok);

		cv::Mat& outDescriptors = writer.acquireSocket(0).getArray();
		cv::KeyPoints& outKeypoints = writer.acquireSocket(1).getKeypoints();

		outKeypoints = keypoints;
		_brisk->compute(imageSrc, outKeypoints, outDescriptors);

		return ExecutionStatus(EStatus::Ok);
	}

	void configuration(NodeConfig& nodeConfig) const override
	{
		static const InputSocketConfig in_config[] = {
			{ ENodeFlowDataType::Image, "source", "Image", "" },
			{ ENodeFlowDataType::Keypoints, "keypoints", "Keypoints", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};
		static const OutputSocketConfig out_config[] = {
			{ ENodeFlowDataType::Array, "output", "Descriptors", "" },
			{ ENodeFlowDataType::Keypoints, "output", "Keypoints", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};

		nodeConfig.description = "";
		nodeConfig.pInputSockets = in_config;
		nodeConfig.pOutputSockets = out_config;
	}

private:
	// Must be pointer since BRISK doesn't implement copy/move operator (they should have)
	unique_ptr<cv::BRISK> _brisk;
};

class BriskNodeType : public BriskFeatureDetectorNodeType
{
public:

	ExecutionStatus execute(NodeSocketReader& reader, NodeSocketWriter& writer) override
	{
		const cv::Mat& src = reader.readSocket(0).getImage();
		cv::KeyPoints& keypoints = writer.acquireSocket(0).getKeypoints();
		cv::Mat& descriptors = writer.acquireSocket(1).getArray();

		if(src.rows == 0 || src.cols == 0)
			return ExecutionStatus(EStatus::Ok);

		//cv::BRISK(_thresh, _nOctaves, _patternScale)
		(*_brisk)(src, cv::noArray(), keypoints, descriptors);

		return ExecutionStatus(EStatus::Ok);
	}

	void configuration(NodeConfig& nodeConfig) const override
	{
		BriskFeatureDetectorNodeType::configuration(nodeConfig);

		static const OutputSocketConfig out_config[] = {
			{ ENodeFlowDataType::Keypoints, "keypoints", "Keypoints", "" },
			{ ENodeFlowDataType::Array, "output", "Descriptors", "" },
			{ ENodeFlowDataType::Invalid, "", "", "" }
		};

		nodeConfig.description = "";
		nodeConfig.pOutputSockets = out_config;
	}
};

REGISTER_NODE("Features/BRISK Extractor", BriskFeatureExtractorNodeType)
REGISTER_NODE("Features/BRISK Detector", BriskFeatureDetectorNodeType)
REGISTER_NODE("Features/BRISK", BriskNodeType)<|endoftext|>


<commit_before>/*
 * KeyValueTable.hpp
 *
 *  Created on: Jun 14, 2015
 *      Author: jcassidy
 */

#ifndef KEYVALUETABLE_HPP_
#define KEYVALUETABLE_HPP_

#include <string>
#include <vector>
#include <boost/serialization/serialization.hpp>

class KeyValueTable {
public:
	unsigned addKey(const std::string k){ return keys_.addValue(k); }
	unsigned addValue(const std::string v){ return values_.addValue(v); }

	const std::string& getKey(unsigned ki){ return keys_.getValue(ki); }
	const std::string& getValue(unsigned vi){ return values_.getValue(vi); }

	bool keyValid(unsigned ki) const { return keys_.valueValid(ki); }
	bool valueValid(unsigned vi) const { return values_.valueValid(vi); }

	std::function<const std::string&(unsigned)> keyLookup() const { return [this](unsigned i){ return cref(keys_.getValue(i)); }; }
	std::function<const std::string&(unsigned)> valueLookup() const { return [this](unsigned i){ return cref(values_.getValue(i)); }; }
	std::function<std::pair<const std::string&,const std::string&>(std::pair<unsigned,unsigned>)> pairLookup() const
			{ return [this](const std::pair<unsigned,unsigned> p){ return std::make_pair(cref(keys_.getValue(p.first)),cref(values_.getValue(p.second))); }; }

	const std::vector<std::string>& keys() const 	{ return keys_.values(); }
	const std::vector<std::string>& values() const 	{ return values_.values(); }

private:
	ValueTable keys_;
	ValueTable values_;

	template<class Archive>void serialize(Archive& ar,const unsigned ver){ ar & keys_ & values_; }
	friend class boost::serialization::access;
};

/** A key-value table which is bound to a specific set of tags.
 *
 */

class BoundKeyValueTable : public KeyValueTable {
public:
	BoundKeyValueTable(OSMEntity* e=nullptr) : entity_(e){}

	void addTag(unsigned ki,unsigned vi)
	{
		assert(entity_);
		assert(keyValid(ki));
		assert(valueValid(vi));

		entity_->addTag(ki,vi);
	}

	void activeEntity(OSMEntity* e){ entity_=e; }
	OSMEntity* activeEntity() const { return entity_; }

private:
	OSMEntity* entity_=nullptr;
};

#endif /* KEYVALUETABLE_HPP_ */
<commit_msg>Fixed missing const in KeyValueTable<commit_after>/*
 * KeyValueTable.hpp
 *
 *  Created on: Jun 14, 2015
 *      Author: jcassidy
 */

#ifndef KEYVALUETABLE_HPP_
#define KEYVALUETABLE_HPP_

#include <string>
#include <vector>
#include <boost/serialization/serialization.hpp>

class KeyValueTable {
public:
	unsigned addKey(const std::string k){ return keys_.addValue(k); }
	unsigned addValue(const std::string v){ return values_.addValue(v); }

	const std::string& getKey(unsigned ki) const { return keys_.getValue(ki); }
	const std::string& getValue(unsigned vi) const { return values_.getValue(vi); }

	bool keyValid(unsigned ki) const { return keys_.valueValid(ki); }
	bool valueValid(unsigned vi) const { return values_.valueValid(vi); }

	std::function<const std::string&(unsigned)> keyLookup() const { return [this](unsigned i){ return cref(keys_.getValue(i)); }; }
	std::function<const std::string&(unsigned)> valueLookup() const { return [this](unsigned i){ return cref(values_.getValue(i)); }; }
	std::function<std::pair<const std::string&,const std::string&>(std::pair<unsigned,unsigned>)> pairLookup() const
			{ return [this](const std::pair<unsigned,unsigned> p){ return std::make_pair(cref(keys_.getValue(p.first)),cref(values_.getValue(p.second))); }; }

	const std::vector<std::string>& keys() const 	{ return keys_.values(); }
	const std::vector<std::string>& values() const 	{ return values_.values(); }

private:
	ValueTable keys_;
	ValueTable values_;

	template<class Archive>void serialize(Archive& ar,const unsigned ver){ ar & keys_ & values_; }
	friend class boost::serialization::access;
};

/** A key-value table which is bound to a specific set of tags.
 *
 */

class BoundKeyValueTable : public KeyValueTable {
public:
	BoundKeyValueTable(OSMEntity* e=nullptr) : entity_(e){}

	void addTag(unsigned ki,unsigned vi)
	{
		assert(entity_);
		assert(keyValid(ki));
		assert(valueValid(vi));

		entity_->addTag(ki,vi);
	}

	void activeEntity(OSMEntity* e){ entity_=e; }
	OSMEntity* activeEntity() const { return entity_; }

private:
	OSMEntity* entity_=nullptr;
};

#endif /* KEYVALUETABLE_HPP_ */
<|endoftext|>


<commit_before>#include "../kontsevich_graph_series.hpp"
#include "../kontsevich_graph_operator.hpp"
#include "../util/poisson_structure.hpp" // for poisson_structures
#include <ginac/ginac.h>
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
using namespace GiNaC;

int main(int argc, char* argv[])
{
    if (argc != 3 || poisson_structures.find(argv[2]) == poisson_structures.end())
    {
        cerr << "Usage: " << argv[0] << " <graph-series-filename> <poisson-structure>\n\n"
             << "Poisson structures can be chosen from the following list:\n";
        for (auto const& entry : poisson_structures)
        {
            cerr << "- " << entry.first << "\n";
        }
        return 1;
    }

    PoissonStructure const& poisson = poisson_structures[argv[2]];

    cout << "Coordinates: ";
    for (symbol coordinate : poisson.coordinates)
        cout << coordinate << " ";
    cout << "\n";
    cout << "Poisson structure matrix:\n";
    cout << "[";
    for (auto row = poisson.bivector.begin(); row != poisson.bivector.end(); ++row)
    {
        cout << "[";
        for (auto entry = row->begin(); entry != row->end(); ++entry)
        {
            cout << *entry;
            if (entry + 1 != row->end())
                cout << ", ";
        }
        cout << "]";
        if (row + 1 != poisson.bivector.end())
            cout << "\n";
    }
    cout << "]\n\n";

    // Reading in graph series:
    string graph_series_filename(argv[1]);
    ifstream graph_series_file(graph_series_filename);
    parser coefficient_reader;
    KontsevichGraphSeries<ex> graph_series = KontsevichGraphSeries<ex>::from_istream(graph_series_file, [&coefficient_reader](std::string s) -> ex { return coefficient_reader(s); });
    size_t order = graph_series.precision();

    for (size_t n = 0; n <= order; ++n)
    {
        cout << "h^" << n << ":\n";
        for (std::vector<size_t> indegrees : graph_series[n].in_degrees(true))
        {
            cout << "# ";
            for (size_t j = 0; j != indegrees.size(); ++j)
                cout << indegrees[j] << " ";
            cout << "\n";

            map< multi_indexes, ex > coefficients;
            for (auto& term : graph_series[n][indegrees])
            {
                map_operator_coefficients_from_graph(term.second, poisson, [&coefficients, &term](multi_indexes arg_derivatives, GiNaC::ex summand) {
                    ex result = (term.first * summand).expand();
                    coefficients[arg_derivatives] += result;
                });
            }
            for (auto& entry : coefficients)
            {
                cout << "# ";
                for (auto mindex = entry.first.begin(); mindex != entry.first.end(); mindex++)
                {
                    cout << "[ ";
                    for (auto &index : *mindex)
                    {
                        cout << poisson.coordinates[index] << " ";
                    }
                    cout << "]";
                    if (mindex + 1 != entry.first.end())
                        cout << " ";
                }
                cout << "\n";
                ex result = entry.second;
                cout << result << "\n";
            }
            cout.flush();
        }
    }
}
<commit_msg>Print fewer exponents in poisson_evaluate<commit_after>#include "../kontsevich_graph_series.hpp"
#include "../kontsevich_graph_operator.hpp"
#include "../util/poisson_structure.hpp" // for poisson_structures
#include <ginac/ginac.h>
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
using namespace GiNaC;

int main(int argc, char* argv[])
{
    if (argc != 3 || poisson_structures.find(argv[2]) == poisson_structures.end())
    {
        cerr << "Usage: " << argv[0] << " <graph-series-filename> <poisson-structure>\n\n"
             << "Poisson structures can be chosen from the following list:\n";
        for (auto const& entry : poisson_structures)
        {
            cerr << "- " << entry.first << "\n";
        }
        return 1;
    }

    PoissonStructure const& poisson = poisson_structures[argv[2]];

    cout << "Coordinates: ";
    for (symbol coordinate : poisson.coordinates)
        cout << coordinate << " ";
    cout << "\n";
    cout << "Poisson structure matrix:\n";
    cout << "[";
    for (auto row = poisson.bivector.begin(); row != poisson.bivector.end(); ++row)
    {
        cout << "[";
        for (auto entry = row->begin(); entry != row->end(); ++entry)
        {
            cout << *entry;
            if (entry + 1 != row->end())
                cout << ", ";
        }
        cout << "]";
        if (row + 1 != poisson.bivector.end())
            cout << "\n";
    }
    cout << "]\n\n";

    // Reading in graph series:
    string graph_series_filename(argv[1]);
    ifstream graph_series_file(graph_series_filename);
    parser coefficient_reader;
    KontsevichGraphSeries<ex> graph_series = KontsevichGraphSeries<ex>::from_istream(graph_series_file, [&coefficient_reader](std::string s) -> ex { return coefficient_reader(s); });
    size_t order = graph_series.precision();

    for (size_t n = 0; n <= order; ++n)
    {
        if (graph_series[n] != 0 || n == order)
            cout << "h^" << n << ":\n";
        for (std::vector<size_t> indegrees : graph_series[n].in_degrees(true))
        {
            cout << "# ";
            for (size_t j = 0; j != indegrees.size(); ++j)
                cout << indegrees[j] << " ";
            cout << "\n";

            map< multi_indexes, ex > coefficients;
            for (auto& term : graph_series[n][indegrees])
            {
                map_operator_coefficients_from_graph(term.second, poisson, [&coefficients, &term](multi_indexes arg_derivatives, GiNaC::ex summand) {
                    ex result = (term.first * summand).expand();
                    coefficients[arg_derivatives] += result;
                });
            }
            for (auto& entry : coefficients)
            {
                cout << "# ";
                for (auto mindex = entry.first.begin(); mindex != entry.first.end(); mindex++)
                {
                    cout << "[ ";
                    for (auto &index : *mindex)
                    {
                        cout << poisson.coordinates[index] << " ";
                    }
                    cout << "]";
                    if (mindex + 1 != entry.first.end())
                        cout << " ";
                }
                cout << "\n";
                ex result = entry.second;
                cout << result << "\n";
            }
            cout.flush();
        }
    }
}
<|endoftext|>


<commit_before>#include "../search/search.hpp"
#include "../utils/pool.hpp"

void fatal(const char*, ...);	// utils.hpp

template <class D> struct Wastar : public SearchAlgorithm<D> {

	typedef typename D::State State;
	typedef typename D::PackedState PackedState;
	typedef typename D::Cost Cost;
	typedef typename D::Oper Oper;

	struct Node : SearchNode<D> {
		double f, fprime;

		static bool pred(Node *a, Node *b) {
			if (a->fprime == b->fprime) {
				if (a->f == b->f)
					return a->g > b->g;
				return a->f < b->f;
			}
			return a->fprime < b->fprime;
		}
	};

	Wastar(int argc, const char *argv[]) :
			SearchAlgorithm<D>(argc, argv), dropdups(false),
			wt(-1.0), closed(30000001) {
		for (int i = 0; i < argc; i++) {
			if (i < argc - 1 && strcmp(argv[i], "-wt") == 0)
				wt = strtod(argv[++i], NULL);
			if (strcmp(argv[i], "-dropdups") == 0)
				dropdups = true;
		}

		if (wt < 1)
			fatal("Must specify a weight ≥1 weight using -wt");

		nodes = new Pool<Node>();
	}

	~Wastar() {
		delete nodes;
	}

	void search(D &d, typename D::State &s0) {
		this->start();
		closed.init(d);

		Node *n0 = init(d, s0);
		closed.add(n0);
		open.push(n0);

		while (!open.empty() && !SearchAlgorithm<D>::limit()) {
			Node *n = *open.pop();
			State buf, &state = d.unpack(buf, n->packed);

			if (d.isgoal(state)) {
				SearchAlgorithm<D>::res.goal(d, n);
				break;
			}

			expand(d, n, state);
		}
		this->finish();
	}

	virtual void reset() {
		SearchAlgorithm<D>::reset();
		open.clear();
		closed.clear();
		delete nodes;
		nodes = new Pool<Node>();
	}

	virtual void output(FILE *out) {
		SearchAlgorithm<D>::output(out);
		closed.prstats(stdout, "closed ");
		dfpair(stdout, "open list type", "%s", "binary heap");
		dfpair(stdout, "node size", "%u", sizeof(Node));
		dfpair(stdout, "weight", "%g", wt);
	}

private:

	void expand(D &d, Node *n, State &state) {
		SearchAlgorithm<D>::res.expd++;

		typename D::Operators ops(d, state);
		for (unsigned int i = 0; i < ops.size(); i++) {
			if (ops[i] == n->pop)
				continue;
			SearchAlgorithm<D>::res.gend++;
			considerkid(d, n, state, ops[i]);
		}
	}

	void considerkid(D &d, Node *parent, State &state, Oper op) {
		Node *kid = nodes->construct();
		typename D::Edge e(d, state, op);
		kid->g = parent->g + e.cost;
		d.pack(kid->packed, e.state);

		unsigned long hash = d.hash(kid->packed);
		Node *dup = static_cast<Node*>(closed.find(kid->packed, hash));
		if (dup) {
			this->res.dups++;
			if (dropdups && kid->g < dup->g)
				dup->parent = parent;
			if (dropdups || kid->g >= dup->g) {
				nodes->destruct(kid);
				return;
			}
			this->res.reopnd++;
			dup->fprime = dup->fprime - dup->g + kid->g;
			dup->f = dup->f - dup->g + kid->g;
			dup->update(kid->g, parent, op, e.revop);
			open.pushupdate(dup, dup->ind);
			nodes->destruct(kid);
		} else {
			typename D::Cost h = d.h(e.state);
			kid->f = kid->g + h;
			kid->fprime = kid->g + wt * h;
			kid->update(kid->g, parent, op, e.revop);
			closed.add(kid, hash);
			open.push(kid);
		}
	}

	Node *init(D &d, State &s0) {
		Node *n0 = nodes->construct();
		d.pack(n0->packed, s0);
		n0->g = Cost(0);
		typename D::Cost h = d.h(s0);
		n0->f = h;
		n0->fprime = wt * h;
		n0->op = n0->pop = D::Nop;
		n0->parent = NULL;
		return n0;
	}

	bool dropdups;
	double wt;
	BinHeap<Node, Node*> open;
 	ClosedList<SearchNode<D>, SearchNode<D>, D> closed;
	Pool<Node> *nodes;
};
<commit_msg>Revert the wA* parent pointer change. This breaks a bunch of things.<commit_after>#include "../search/search.hpp"
#include "../utils/pool.hpp"

void fatal(const char*, ...);	// utils.hpp

template <class D> struct Wastar : public SearchAlgorithm<D> {

	typedef typename D::State State;
	typedef typename D::PackedState PackedState;
	typedef typename D::Cost Cost;
	typedef typename D::Oper Oper;

	struct Node : SearchNode<D> {
		double f, fprime;

		static bool pred(Node *a, Node *b) {
			if (a->fprime == b->fprime) {
				if (a->f == b->f)
					return a->g > b->g;
				return a->f < b->f;
			}
			return a->fprime < b->fprime;
		}
	};

	Wastar(int argc, const char *argv[]) :
			SearchAlgorithm<D>(argc, argv), dropdups(false),
			wt(-1.0), closed(30000001) {
		for (int i = 0; i < argc; i++) {
			if (i < argc - 1 && strcmp(argv[i], "-wt") == 0)
				wt = strtod(argv[++i], NULL);
			if (strcmp(argv[i], "-dropdups") == 0)
				dropdups = true;
		}

		if (wt < 1)
			fatal("Must specify a weight ≥1 weight using -wt");

		nodes = new Pool<Node>();
	}

	~Wastar() {
		delete nodes;
	}

	void search(D &d, typename D::State &s0) {
		this->start();
		closed.init(d);

		Node *n0 = init(d, s0);
		closed.add(n0);
		open.push(n0);

		while (!open.empty() && !SearchAlgorithm<D>::limit()) {
			Node *n = *open.pop();
			State buf, &state = d.unpack(buf, n->packed);

			if (d.isgoal(state)) {
				SearchAlgorithm<D>::res.goal(d, n);
				break;
			}

			expand(d, n, state);
		}
		this->finish();
	}

	virtual void reset() {
		SearchAlgorithm<D>::reset();
		open.clear();
		closed.clear();
		delete nodes;
		nodes = new Pool<Node>();
	}

	virtual void output(FILE *out) {
		SearchAlgorithm<D>::output(out);
		closed.prstats(stdout, "closed ");
		dfpair(stdout, "open list type", "%s", "binary heap");
		dfpair(stdout, "node size", "%u", sizeof(Node));
		dfpair(stdout, "weight", "%g", wt);
	}

private:

	void expand(D &d, Node *n, State &state) {
		SearchAlgorithm<D>::res.expd++;

		typename D::Operators ops(d, state);
		for (unsigned int i = 0; i < ops.size(); i++) {
			if (ops[i] == n->pop)
				continue;
			SearchAlgorithm<D>::res.gend++;
			considerkid(d, n, state, ops[i]);
		}
	}

	void considerkid(D &d, Node *parent, State &state, Oper op) {
		Node *kid = nodes->construct();
		typename D::Edge e(d, state, op);
		kid->g = parent->g + e.cost;
		d.pack(kid->packed, e.state);

		unsigned long hash = d.hash(kid->packed);
		Node *dup = static_cast<Node*>(closed.find(kid->packed, hash));
		if (dup) {
			this->res.dups++;
			if (dropdups || kid->g >= dup->g) {
				nodes->destruct(kid);
				return;
			}
			this->res.reopnd++;
			dup->fprime = dup->fprime - dup->g + kid->g;
			dup->f = dup->f - dup->g + kid->g;
			dup->update(kid->g, parent, op, e.revop);
			open.pushupdate(dup, dup->ind);
			nodes->destruct(kid);
		} else {
			typename D::Cost h = d.h(e.state);
			kid->f = kid->g + h;
			kid->fprime = kid->g + wt * h;
			kid->update(kid->g, parent, op, e.revop);
			closed.add(kid, hash);
			open.push(kid);
		}
	}

	Node *init(D &d, State &s0) {
		Node *n0 = nodes->construct();
		d.pack(n0->packed, s0);
		n0->g = Cost(0);
		typename D::Cost h = d.h(s0);
		n0->f = h;
		n0->fprime = wt * h;
		n0->op = n0->pop = D::Nop;
		n0->parent = NULL;
		return n0;
	}

	bool dropdups;
	double wt;
	BinHeap<Node, Node*> open;
 	ClosedList<SearchNode<D>, SearchNode<D>, D> closed;
	Pool<Node> *nodes;
};
<|endoftext|>


<commit_before>// $Id: AGeoBezierPgon.cxx 3 2010-11-26 17:17:31Z oxon $
// Author: Akira Okumura 2011/07/08

/******************************************************************************
 * Copyright (C) 2006-, Akira Okumura                                         *
 * All rights reserved.                                                       *
 *****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//
// AGeoBezierPgon
//
// Geometry class for Pgon-like volume, but the side surfaces are defined by
// a Bezier curve (http://en.wikipedia.org/wiki/Bzier_curve)
//
///////////////////////////////////////////////////////////////////////////////

#include "AGeoBezierPgon.h"

ClassImp(AGeoBezierPgon)

//_____________________________________________________________________________
AGeoBezierPgon::AGeoBezierPgon() : TGeoPgon()
{
  // Default constructor
}

//_____________________________________________________________________________
AGeoBezierPgon::AGeoBezierPgon(Double_t phi, Double_t dphi, Int_t nedges,
                               Int_t nz, Double_t r1, Double_t r2, Double_t dz)
  : TGeoPgon(phi, dphi, nedges, nz), fLength(dz*2), fR1(r1), fR2(r2)
{
  fNcontrol = 0;
}

//_____________________________________________________________________________
AGeoBezierPgon::AGeoBezierPgon(const char* name, Double_t phi, Double_t dphi,
                               Int_t nedges, Int_t nz, Double_t r1, Double_t r2,
                               Double_t dz)
  : TGeoPgon(name, phi, dphi, nedges, nz), fLength(dz*2), fR1(r1), fR2(r2)
{
  fNcontrol = 0;
}

//_____________________________________________________________________________
AGeoBezierPgon::~AGeoBezierPgon()
{
  // destructor
}
//_____________________________________________________________________________
void AGeoBezierPgon::Bezier(Double_t t, Double_t& r, Double_t& z)
{
  TVector2 P0(0, 0);
  TVector2 B;
  if(fNcontrol == 0){
    TVector2 P1(1, 1);
    B = (1 - t)*P0 + t*P1;
  } else if(fNcontrol == 1){
    TVector2 P2(1, 1);
    B = (1 - t)*(1 - t)*P0 + 2*(1 - t)*t*fP1 + t*t*P2;
  } else if(fNcontrol == 2){
    TVector2 P3(1, 1);
    B = (1 - t)*(1 - t)*(1 - t)*P0 + 3*(1 - t)*(1 - t)*t*fP1 + 3*(1 - t)*t*t*fP2 + t*t*t*P3;
  } // if

  r = fR2 + B.X()*(fR1 - fR2);
  z = -fLength/2. + B.Y()*fLength;
}

//_____________________________________________________________________________
void AGeoBezierPgon::SetControlPoints(Double_t r1, Double_t z1)
{
  // Set the relative coordinates of control point 1
  // (r1, z1) must be given in relative coordinates against P0 and P2
  // For example, when (r1, z1) = (0.6, 0.7), the coordinates of P1 is
  // (R, Z) = (R2 + 0.6*(R1 - R2), -DZ + 0.7*(+DZ - (-DZ)))
  // The Bezier curve becomes quadratic
  //
  // Z
  // ^
  // |<--R1-->P2 (R1, +DZ)
  // |        /
  // |       /  P1
  // |      /
  // +-----P0---------> R
  // |<-R2-> (R2, -DZ)
  fNcontrol = 1;
  fP1.Set(r1, z1);
  fP2.Set(0., 0.);
  SetSections();
}

//_____________________________________________________________________________
void AGeoBezierPgon::SetControlPoints(Double_t r1, Double_t z1, Double_t r2, Double_t z2)
{
  // Set the relative coordinates of control points 1 and 2
  // The Bezier curve becomes cubic
  fNcontrol = 2;
  fP1.Set(r1, z1);
  fP2.Set(r2, z2);
  SetSections();
}

//_____________________________________________________________________________
void AGeoBezierPgon::SetSections()
{
  for(Int_t i = 0; i < fNz; i++){
    Double_t t = Double_t(i)/(fNz - 1);
    Double_t r, z;
    Bezier(t, r, z);
    DefineSection(i, z, 0, r);
    Error("SetSections", "%d %f %f %f", i, t, z, r);
  } // i
}
<commit_msg>Removed debugging message<commit_after>// $Id: AGeoBezierPgon.cxx 3 2010-11-26 17:17:31Z oxon $
// Author: Akira Okumura 2011/07/08

/******************************************************************************
 * Copyright (C) 2006-, Akira Okumura                                         *
 * All rights reserved.                                                       *
 *****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//
// AGeoBezierPgon
//
// Geometry class for Pgon-like volume, but the side surfaces are defined by
// a Bezier curve (http://en.wikipedia.org/wiki/Bzier_curve)
//
///////////////////////////////////////////////////////////////////////////////

#include "AGeoBezierPgon.h"

ClassImp(AGeoBezierPgon)

//_____________________________________________________________________________
AGeoBezierPgon::AGeoBezierPgon() : TGeoPgon()
{
  // Default constructor
}

//_____________________________________________________________________________
AGeoBezierPgon::AGeoBezierPgon(Double_t phi, Double_t dphi, Int_t nedges,
                               Int_t nz, Double_t r1, Double_t r2, Double_t dz)
  : TGeoPgon(phi, dphi, nedges, nz), fLength(dz*2), fR1(r1), fR2(r2)
{
  fNcontrol = 0;
}

//_____________________________________________________________________________
AGeoBezierPgon::AGeoBezierPgon(const char* name, Double_t phi, Double_t dphi,
                               Int_t nedges, Int_t nz, Double_t r1, Double_t r2,
                               Double_t dz)
  : TGeoPgon(name, phi, dphi, nedges, nz), fLength(dz*2), fR1(r1), fR2(r2)
{
  fNcontrol = 0;
}

//_____________________________________________________________________________
AGeoBezierPgon::~AGeoBezierPgon()
{
  // destructor
}
//_____________________________________________________________________________
void AGeoBezierPgon::Bezier(Double_t t, Double_t& r, Double_t& z)
{
  TVector2 P0(0, 0);
  TVector2 B;
  if(fNcontrol == 0){
    TVector2 P1(1, 1);
    B = (1 - t)*P0 + t*P1;
  } else if(fNcontrol == 1){
    TVector2 P2(1, 1);
    B = (1 - t)*(1 - t)*P0 + 2*(1 - t)*t*fP1 + t*t*P2;
  } else if(fNcontrol == 2){
    TVector2 P3(1, 1);
    B = (1 - t)*(1 - t)*(1 - t)*P0 + 3*(1 - t)*(1 - t)*t*fP1 + 3*(1 - t)*t*t*fP2 + t*t*t*P3;
  } // if

  r = fR2 + B.X()*(fR1 - fR2);
  z = -fLength/2. + B.Y()*fLength;
}

//_____________________________________________________________________________
void AGeoBezierPgon::SetControlPoints(Double_t r1, Double_t z1)
{
  // Set the relative coordinates of control point 1
  // (r1, z1) must be given in relative coordinates against P0 and P2
  // For example, when (r1, z1) = (0.6, 0.7), the coordinates of P1 is
  // (R, Z) = (R2 + 0.6*(R1 - R2), -DZ + 0.7*(+DZ - (-DZ)))
  // The Bezier curve becomes quadratic
  //
  // Z
  // ^
  // |<--R1-->P2 (R1, +DZ)
  // |        /
  // |       /  P1
  // |      /
  // +-----P0---------> R
  // |<-R2-> (R2, -DZ)
  fNcontrol = 1;
  fP1.Set(r1, z1);
  fP2.Set(0., 0.);
  SetSections();
}

//_____________________________________________________________________________
void AGeoBezierPgon::SetControlPoints(Double_t r1, Double_t z1, Double_t r2, Double_t z2)
{
  // Set the relative coordinates of control points 1 and 2
  // The Bezier curve becomes cubic
  fNcontrol = 2;
  fP1.Set(r1, z1);
  fP2.Set(r2, z2);
  SetSections();
}

//_____________________________________________________________________________
void AGeoBezierPgon::SetSections()
{
  for(Int_t i = 0; i < fNz; i++){
    Double_t t = Double_t(i)/(fNz - 1);
    Double_t r, z;
    Bezier(t, r, z);
    DefineSection(i, z, 0, r);
  } // i
}
<|endoftext|>


<commit_before>#include "broker.hpp"
#include <base/message_any.hpp>

namespace cossb {
namespace broker {

unsigned int component_broker::publish(const char* service_name, cossb::message& msg)
{
	unsigned int times = 0;

	if(_service_map.find(service_name)!=_service_map.end()) {
		auto range = _topic_map.equal_range(_service_map[service_name].topic);
		msg.msg_frame.topic = _service_map[service_name].topic;
		for(topic_map::iterator itr = range.first; itr!=range.second; ++itr) {
			driver::component_driver* _drv = cossb_component_manager->get_driver(itr->second.c_str());
			if(_drv)
			{
				if(!_drv->mine(msg.get_from())) {
					_drv->request(&msg);
					times++;
				}
			}
			else {
				cossb_log->log(log::loglevel::ERROR, fmt::format("{} service has no component driver. it will be removed.", service_name));
				_service_map.erase(service_name);
				//throw broker::exception(cossb::broker::excode::DRIVER_NOT_FOUND);
			}
		}
	}
	else
		cossb_log->log(log::loglevel::ERROR, fmt::format("No Services({}) found", service_name));

	return times;
}

//template<typename... Args>
//unsigned int component_broker::publish(interface::icomponent* to_component, const char* topic, const char* api, const Args&... args)
//{
//	auto range = _topic_map.equal_range(topic);
//	unsigned int times = 0;
//	for(topic_map::iterator itr = range.first; itr!=range.second; ++itr) {
//		if(itr->second.compare(to_component->get_name())!=0) {
//			driver::component_driver* _drv = cossb_component_manager->get_driver(itr->second.c_str());
//			if(_drv) {
//				_drv->request(api, args...);
//				times++;
//			}
//			else {
//				cossb_log->log(log::loglevel::ERROR, fmt::format("<{}> has no component driver.", to_component->get_name()));
//				//throw broker::exception(cossb::broker::excode::DRIVER_NOT_FOUND);
//			}
//		}
//	}
//
//	return times;
//}

bool component_broker::regist(cossb::service::_service_desc* const service)
{
	if(service) {
		if(_service_map.find(service->name)==_service_map.end()) {
			_service_map.insert(service_map::value_type(service->name, *service));
			_topic_map.insert(topic_map::value_type(service->topic, service->component_name));
			cossb_log->log(log::loglevel::INFO, fmt::format("Service Registration : topic {} / Service {}", service->topic, service->name));
			return true;
		}
		else
			cossb_log->log(log::loglevel::WARN, fmt::format("Already registered service : Topic {} / Service {}", service->topic, service->name));
	}

	return false;
}

} /* namespace broker */
} /* namespace cossb */
<commit_msg>- update for test<commit_after>#include "broker.hpp"
#include <base/message_any.hpp>

namespace cossb {
namespace broker {

unsigned int component_broker::publish(const char* service_name, cossb::message& msg)
{
	unsigned int times = 0;

	if(_service_map.find(service_name)!=_service_map.end()) {
		auto range = _topic_map.equal_range(_service_map[service_name].topic);
		msg.msg_frame.topic = _service_map[service_name].topic;
		for(topic_map::iterator itr = range.first; itr!=range.second; ++itr) {
			driver::component_driver* _drv = cossb_component_manager->get_driver(itr->second.c_str());
			if(_drv)
			{
				if(!_drv->mine(msg.get_from())) {
					cossb_log->log(log::loglevel::INFO, "Request Message");
					_drv->request(&msg);
					times++;
				}
			}
			else {
				cossb_log->log(log::loglevel::ERROR, fmt::format("{} service has no component driver. it will be removed.", service_name));
				_service_map.erase(service_name);
				//throw broker::exception(cossb::broker::excode::DRIVER_NOT_FOUND);
			}
		}
	}
	else
		cossb_log->log(log::loglevel::ERROR, fmt::format("No Services({}) found", service_name));

	return times;
}

//template<typename... Args>
//unsigned int component_broker::publish(interface::icomponent* to_component, const char* topic, const char* api, const Args&... args)
//{
//	auto range = _topic_map.equal_range(topic);
//	unsigned int times = 0;
//	for(topic_map::iterator itr = range.first; itr!=range.second; ++itr) {
//		if(itr->second.compare(to_component->get_name())!=0) {
//			driver::component_driver* _drv = cossb_component_manager->get_driver(itr->second.c_str());
//			if(_drv) {
//				_drv->request(api, args...);
//				times++;
//			}
//			else {
//				cossb_log->log(log::loglevel::ERROR, fmt::format("<{}> has no component driver.", to_component->get_name()));
//				//throw broker::exception(cossb::broker::excode::DRIVER_NOT_FOUND);
//			}
//		}
//	}
//
//	return times;
//}

bool component_broker::regist(cossb::service::_service_desc* const service)
{
	if(service) {
		if(_service_map.find(service->name)==_service_map.end()) {
			_service_map.insert(service_map::value_type(service->name, *service));
			_topic_map.insert(topic_map::value_type(service->topic, service->component_name));
			cossb_log->log(log::loglevel::INFO, fmt::format("Service Registration : topic {} / Service {}", service->topic, service->name));
			return true;
		}
		else
			cossb_log->log(log::loglevel::WARN, fmt::format("Already registered service : Topic {} / Service {}", service->topic, service->name));
	}

	return false;
}

} /* namespace broker */
} /* namespace cossb */
<|endoftext|>


<commit_before>/*
 * CategoryStream.cpp
 *
 * Copyright 2001, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2001, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#include "PortabilityImpl.hh"

#ifdef LOG4CPP_HAVE_UNISTD_H
#    include <unistd.h>
#endif

#include <log4cpp/CategoryStream.hh>
#include <log4cpp/Category.hh>

namespace log4cpp {

    CategoryStream::CategoryStream(Category& category, Priority::Value priority) :
        _category(category),
        _priority(priority),
        _buffer(NULL) {
    }

    CategoryStream::~CategoryStream() {
        flush();
    }

    CategoryStream& CategoryStream::operator<<(CategoryStream::Separator separator) {
        flush();
        return *this;
    }

    void CategoryStream::flush() {
        if (_buffer) {
            getCategory().log(getPriority(), _buffer->str());
            delete _buffer;
            _buffer = NULL;
        }
    }
     std::streamsize CategoryStream::width(std::streamsize wide ) {
        if (getPriority() != Priority::NOTSET) {
            if (!_buffer) {
                if (!(_buffer = new std::ostringstream)) {
                    // XXX help help help
                }
            }
        }
        return _buffer->width(wide);
    }
    CategoryStream& CategoryStream::operator<< (cspf) {
		cspf(this);
		return *this;
    }
    CategoryStream& eol (CategoryStream& os) {
        if  (os._buffer->good()) {
            os._buffer->put(os._buffer->widen('\n'));os._buffer->flush();
        }
        return os;
    }
    CategoryStream& left (CategoryStream& os) {
        if  (os._buffer->good()) {
            os._buffer->setf(std::ios::left);
        }
        return os;
    }
}
<commit_msg>Fix CategoryStream::eol(CategoryStream&)<commit_after>/*
 * CategoryStream.cpp
 *
 * Copyright 2001, LifeLine Networks BV (www.lifeline.nl). All rights reserved.
 * Copyright 2001, Bastiaan Bakker. All rights reserved.
 *
 * See the COPYING file for the terms of usage and distribution.
 */

#include "PortabilityImpl.hh"

#ifdef LOG4CPP_HAVE_UNISTD_H
#    include <unistd.h>
#endif

#include <log4cpp/CategoryStream.hh>
#include <log4cpp/Category.hh>

namespace log4cpp {

    CategoryStream::CategoryStream(Category& category, Priority::Value priority) :
        _category(category),
        _priority(priority),
        _buffer(NULL) {
    }

    CategoryStream::~CategoryStream() {
        flush();
    }

    CategoryStream& CategoryStream::operator<<(CategoryStream::Separator separator) {
        flush();
        return *this;
    }

    void CategoryStream::flush() {
        if (_buffer) {
            getCategory().log(getPriority(), _buffer->str());
            delete _buffer;
            _buffer = NULL;
        }
    }
     std::streamsize CategoryStream::width(std::streamsize wide ) {
        if (getPriority() != Priority::NOTSET) {
            if (!_buffer) {
                if (!(_buffer = new std::ostringstream)) {
                    // XXX help help help
                }
            }
        }
        return _buffer->width(wide);
    }
    CategoryStream& CategoryStream::operator<< (cspf pf) {
		return (*pf)(*this);
    }
    CategoryStream& eol (CategoryStream& os) {
        if  (os._buffer->good()) {
			os.flush();
        }
        return os;
    }
    CategoryStream& left (CategoryStream& os) {
        if  (os._buffer->good()) {
            os._buffer->setf(std::ios::left);
        }
        return os;
    }
}
<|endoftext|>


<commit_before>#include <map>
#include <string>
#include <IniLoader.h>
#include <algorithm>
#include <string>

static std::string emptyString;

//static std::map<std::string, std::string> handlers;
namespace IniLoader {
	static std::string toLower(const char* str) {
		std::string tmp(str);
		std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
		return tmp; //RVO
//		return std::move(tmp);
	}

	int sectionHandler(void* user, const char* _section, const char* _name, const char* value) {
		ini_contents* contents = (ini_contents*)user;
		std::string sec_name = toLower(_section);
		std::string name = toLower(_name);

		auto tmp = contents->find(sec_name);
		if (tmp != contents->end()) {
			ini_section& s = tmp->second;
			s.pairs.erase(name);
			s.pairs.insert(std::make_pair(std::move(name), std::string(value)));
		}
		else {
			ini_section s;
			s.header = sec_name;
			s.pairs.insert(std::make_pair(std::move(name), std::string(value)));
			contents->insert(std::make_pair(std::move(sec_name), std::move(s)));
		}
		return 0;
	}

	Contents parse(const std::string &filename) {
		Contents contents;
		ini_parse(filename.c_str(), &sectionHandler, &contents.m_ini);
		return contents; //std::move is not a good idea here, prevents RVO
	}

	const std::string& getValue(const ini_contents& c, const std::string& sec, const std::string& name) {
		auto t1 = c.find(sec);
		if (t1 == c.end()) return emptyString;

		const ini_section& section = t1->second;
		auto t2 = section.pairs.find(name);
		if (t2 == section.pairs.end()) return emptyString;

		return t2->second;
	}
}
//
//IniRegistrar::IniRegistrar(std::string tag, std::string value) {
//	auto t = std::make_pair(tag, value);
//	handlers.insert(t);
//}<commit_msg>better ini file error handling<commit_after>#include <map>
#include <string>
#include <IniLoader.h>
#include <algorithm>
#include <string>

static std::string emptyString;

namespace IniLoader {
	static std::string toLower(const char* str) {
		std::string tmp(str);
		std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
		return tmp; //RVO
	}

	int sectionHandler(void* user, const char* _section, const char* _name, const char* value) {
		ini_contents* contents = (ini_contents*)user;
		std::string sec_name = toLower(_section);
		std::string name = toLower(_name);

		auto tmp = contents->find(sec_name);
		if (tmp != contents->end()) {
			ini_section& s = tmp->second;
			s.pairs.erase(name);
			s.pairs.insert(std::make_pair(std::move(name), std::string(value)));
		}
		else {
			ini_section s;
			s.header = sec_name;
			s.pairs.insert(std::make_pair(std::move(name), std::string(value)));
			contents->insert(std::make_pair(std::move(sec_name), std::move(s)));
		}
		return 1; //non-zero on success
	}

	Contents parse(const std::string &filename) {
		Contents contents;
		int r = ini_parse(filename.c_str(), &sectionHandler, &contents.m_ini);
		if (r == -1) {
			fprintf(stderr, "Error opening file \"%s\"\n", filename.c_str());
		}
		else if (r == -2) {
			fprintf(stderr, "Memory alignment error opening file \"%s\"\n", filename.c_str());
		}
		else if (r > 0) {
			fprintf(stderr, "Error on line %d in file \"%s\"\n", r, filename.c_str());
		}
		else if (r != 0) {
			fprintf(stderr, "Unknown error opening file \"%s\"\n", filename.c_str() );
		}
		return contents; //std::move is not a good idea here, prevents RVO
	}

	const std::string& getValue(const ini_contents& c, const std::string& sec, const std::string& name) {
		auto t1 = c.find(sec);
		if (t1 == c.end()) return emptyString;

		const ini_section& section = t1->second;
		auto t2 = section.pairs.find(name);
		if (t2 == section.pairs.end()) return emptyString;

		return t2->second;
	}
}<|endoftext|>


<commit_before>/* hasher.hh -- k-mer hash functions
 *
 * Copyright (C) 2018 Camille Scott
 * All rights reserved.
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

#include "boink.hh"
#include "oxli/alphabets.hh"
#include "oxli/kmer_hash.hh"

namespace boink {

typedef uint64_t hash_t;
typedef std::pair<hash_t, hash_t> full_hash_t;

class KmerClient {
protected:
    const uint16_t _K;
public:
    explicit KmerClient(uint16_t K) : _K(K) {}
    const uint16_t K() const { return _K; }
};

template <class Derived,
          const std::string& Alphabet>
class HashShifter : public KmerClient {
public:
    std::deque<char> symbol_deque;
    using KmerClient::KmerClient;

    hash_t reset(const std::string& sequence) {
        if (sequence.length() < _K) {
            throw BoinkException("Sequence must be length K");
        }
        symbol_deque.clear();
        for (size_t i = 0; i < _K; ++i) {
            symbol_deque.push_back(sequence[i]);
        }
        return derived().reset();
    }

    hash_t reset() {
        return derived().reset();
    }

    hash_t hash() {
        return derived().hash();
    }

    hash_t hash(std::string& sequence) {
        return derived().hash(sequence);
    }

    std::vector<hash_t> shift_left() {
        return derived().shift_left();
    }

    hash_t shift_left(const char c) {
        symbol_deque.push_front(c);
        hash_t h = derived().shift_left(c);
        symbol_deque.pop_back();
        return h;
    }

    std::vector<hash_t> shift_right() {
        return derived().shift_right();
    }

    hash_t shift_right(const char c) {
        symbol_deque.push_back(c);
        hash_t h = derived().shift_right(c);
        symbol_deque.pop_front();
        return h;
    }

    std::string get_cursor() {
        std::string sequence;
        for (auto c : symbol_deque) {
            sequence.append(c);
        }
        return sequence;
    }

private:

    Derived& derived() {
        return *static_cast<Derived*>(this);
    }

};

template <const std::string& Alphabet>
class RollingHashShifter : public HashShifter<RollingHashShifter<Alphabet>,
                                              Alphabet> {
    CyclicHash<hash_t> hasher;

public:

    using HashShifter<RollingHashShifter<Alphabet>, Alphabet>::HashShifter;
    typedef HashShifter<RollingHashShifter<Alphabet>, Alphabet> BaseShifter;

    RollingHashShifter(uint16_t K) :
        BaseShifter(K), hasher(K) {

    }

    hash_t reset() {
        hasher = CyclicHash<hash_t>(this->_K);
        for (auto c : this->symbol_deque) {
            hasher.eat(c);
        }
        return hasher.hashvalue;
    }

    hash_t hash() {
        return hasher.hashvalue;
    }

    hash_t hash(std::string& sequence) {
        return _hash_cyclic_forward(sequence, this->_K);
    }

    hash_t shift_left(const char c) {
        hasher.reverse_update(c, this->symbol_deque.back());
        return hasher.hashvalue;
    }

    std::vector<hash_t> shift_right() {
        std::vector<hash_t> hashes;
        const char front = this->symbol_deque.front();
        for (auto symbol : Alphabet) {
            hasher.update(front, symbol);
            hashes.push_back(hasher.hashvalue);
            hasher.reverse_update(front, symbol);
        }
        return hashes;
    }

    hash_t shift_right(const char c) {
        hasher.update(this->symbol_deque.front(), c);
        return hash();
    }

    std::vector<hash_t> shift_left() {
        std::vector<hash_t> hashes;
        const char back = this->symbol_deque.back();
        for (auto symbol : Alphabet) {
            hasher.reverse_update(symbol, back);
            hashes.push_back(hasher.hashvalue);
            hasher.update(symbol, back);
        }
    }
};

typedef RollingHashShifter<oxli::alphabets::DNA_SIMPLE> DefaultShifter;

template <class Shifter>
class KmerIterator : public KmerClient {
    const std::string _seq;
    unsigned int index;
    unsigned int length;
    bool _initialized;
    Shifter shifter;

public:
    KmerIterator(const std::string seq, uint16_t K) :
        KmerClient(K), shifter(K), _seq(seq),
        index(0), _initialized(false) {

    }

    hash_t first() {
        _initialized = true;

        shifter.reset(_seq);
        index += 1;
        return shifter.hash();
    }

    hash_t next() {
        if (!_initialized) {
            return first();
        }

        if (done()) {
            throw BoinkException("past end of iterator");
        }

        shifter.shift_right(_seq[index + _K - 1]);
        index += 1;

        return shifter.hash();
    }

    bool done() const {
        return (index + _K > _seq.length());
    }

    unsigned int get_start_pos() const {
        if (!_initialized) { return 0; }
        return index - 1;
    }

    unsigned int get_end_pos() const {
        if (!_initialized) { return _K; }
        return index + _K - 1;
    }
};

/*
class FullRollingHasher {
    const char * _seq;
    const std::string _rev;
    const char _ksize;
    unsigned int index;
    unsigned int length;
    bool _initialized;
    oxli::CyclicHash<uint64_t> fwd_hasher;
    oxli::CyclicHash<uint64_t> bwd_hasher;

public:
    FullRollingHasher(const char * seq, unsigned char k) :
        _seq(seq), _rev(oxli::_revcomp(seq)), _ksize(k), index(0),
        _initialized(false), fwd_hasher(k), bwd_hasher(k)
    {
        length = strlen(_seq);
    };

    full_hash_t first() {
        _initialized = true;

        for (char i = 0; i < _ksize; ++i) {
            fwd_hasher.eat(*(_seq + i));
            bwd_hasher.eat(_rev[length - _ksize + i]);
        }
        index += 1;
        return std::make_pair(fwd_hasher.hashvalue, bwd_hasher.hashvalue);
    }

    full_hash_t next() {
        if (!_initialized) {
            return first();
        }

        if (done()) {
            throw oxli_exception("past end of iterator");
        }
        fwd_hasher.update(*(_seq + index - 1), *(_seq + index + _ksize - 1));

        // first argument is added, second is removed from the hash
        bwd_hasher.reverse_update(
          _rev[length - _ksize - index], _rev[length - index]);

        index += 1;

        return std::make_pair(fwd_hasher.hashvalue, bwd_hasher.hashvalue);
    }

    bool done() const {
        return (index + _ksize > length);
    }

    unsigned int get_start_pos() const {
        if (!_initialized) { return 0; }
        return index - 1;
    }

    unsigned int get_end_pos() const {
        if (!_initialized) { return _ksize; }
        return index + _ksize - 1;
    }
};
*/

};
<commit_msg>Fix string append, fix object reset pattern<commit_after>/* hasher.hh -- k-mer hash functions
 *
 * Copyright (C) 2018 Camille Scott
 * All rights reserved.
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

#include "boink.hh"
#include "oxli/alphabets.hh"
#include "oxli/kmer_hash.hh"

namespace boink {

typedef uint64_t hash_t;
typedef std::pair<hash_t, hash_t> full_hash_t;

class KmerClient {
protected:
    const uint16_t _K;
public:
    explicit KmerClient(uint16_t K) : _K(K) {}
    const uint16_t K() const { return _K; }
};

template <class Derived,
          const std::string& Alphabet>
class HashShifter : public KmerClient {
public:
    std::deque<char> symbol_deque;
    using KmerClient::KmerClient;

    hash_t reset(const std::string& sequence) {
        if (sequence.length() < _K) {
            throw BoinkException("Sequence must be length K");
        }
        symbol_deque.clear();
        for (size_t i = 0; i < _K; ++i) {
            symbol_deque.push_back(sequence[i]);
        }
        return derived().reset();
    }

    hash_t reset() {
        return derived().reset();
    }

    hash_t hash() {
        return derived().hash();
    }

    hash_t hash(std::string& sequence) {
        return derived().hash(sequence);
    }

    std::vector<hash_t> shift_left() {
        return derived().shift_left();
    }

    hash_t shift_left(const char c) {
        symbol_deque.push_front(c);
        hash_t h = derived().shift_left(c);
        symbol_deque.pop_back();
        return h;
    }

    std::vector<hash_t> shift_right() {
        return derived().shift_right();
    }

    hash_t shift_right(const char c) {
        symbol_deque.push_back(c);
        hash_t h = derived().shift_right(c);
        symbol_deque.pop_front();
        return h;
    }

    std::string get_cursor() {
        std::string sequence = "";
        for (auto c : symbol_deque) {
            sequence += c;
        }
        return sequence;
    }

private:

    Derived& derived() {
        return *static_cast<Derived*>(this);
    }

};

template <const std::string& Alphabet>
class RollingHashShifter : public HashShifter<RollingHashShifter<Alphabet>,
                                              Alphabet> {
    CyclicHash<hash_t> hasher;

public:

    using HashShifter<RollingHashShifter<Alphabet>, Alphabet>::HashShifter;
    using HashShifter<RollingHashShifter<Alphabet>, Alphabet>::reset;
    typedef HashShifter<RollingHashShifter<Alphabet>, Alphabet> BaseShifter;

    RollingHashShifter(uint16_t K) :
        BaseShifter(K), hasher(K) {

    }

    hash_t reset() {
        // This pattern "resets" a stack object
        // by calling its destructor and reallocating
        (&hasher)->~CyclicHash<hash_t>();
        new (&hasher) CyclicHash<hash_t>(this->_K);

        for (auto c : this->symbol_deque) {
            hasher.eat(c);
        }
        return hasher.hashvalue;
    }

    hash_t hash() {
        return hasher.hashvalue;
    }

    hash_t hash(std::string& sequence) {
        return _hash_cyclic_forward(sequence, this->_K);
    }

    hash_t shift_left(const char c) {
        hasher.reverse_update(c, this->symbol_deque.back());
        return hasher.hashvalue;
    }

    std::vector<hash_t> shift_right() {
        std::vector<hash_t> hashes;
        const char front = this->symbol_deque.front();
        for (auto symbol : Alphabet) {
            hasher.update(front, symbol);
            hashes.push_back(hasher.hashvalue);
            hasher.reverse_update(front, symbol);
        }
        return hashes;
    }

    hash_t shift_right(const char c) {
        hasher.update(this->symbol_deque.front(), c);
        return hash();
    }

    std::vector<hash_t> shift_left() {
        std::vector<hash_t> hashes;
        const char back = this->symbol_deque.back();
        for (auto symbol : Alphabet) {
            hasher.reverse_update(symbol, back);
            hashes.push_back(hasher.hashvalue);
            hasher.update(symbol, back);
        }

        return hashes;
    }
};

typedef RollingHashShifter<oxli::alphabets::DNA_SIMPLE> DefaultShifter;

template <class Shifter>
class KmerIterator : public KmerClient {
    const std::string _seq;
    unsigned int index;
    unsigned int length;
    bool _initialized;
    Shifter shifter;

public:
    KmerIterator(const std::string seq, uint16_t K) :
        KmerClient(K), _seq(seq), shifter(K),
        index(0), _initialized(false) {

    }

    hash_t first() {
        _initialized = true;

        shifter.reset(_seq);
        index += 1;
        return shifter.hash();
    }

    hash_t next() {
        if (!_initialized) {
            return first();
        }

        if (done()) {
            throw BoinkException("past end of iterator");
        }

        shifter.shift_right(_seq[index + _K - 1]);
        index += 1;

        return shifter.hash();
    }

    bool done() const {
        return (index + _K > _seq.length());
    }

    unsigned int get_start_pos() const {
        if (!_initialized) { return 0; }
        return index - 1;
    }

    unsigned int get_end_pos() const {
        if (!_initialized) { return _K; }
        return index + _K - 1;
    }
};

/*
class FullRollingHasher {
    const char * _seq;
    const std::string _rev;
    const char _ksize;
    unsigned int index;
    unsigned int length;
    bool _initialized;
    oxli::CyclicHash<uint64_t> fwd_hasher;
    oxli::CyclicHash<uint64_t> bwd_hasher;

public:
    FullRollingHasher(const char * seq, unsigned char k) :
        _seq(seq), _rev(oxli::_revcomp(seq)), _ksize(k), index(0),
        _initialized(false), fwd_hasher(k), bwd_hasher(k)
    {
        length = strlen(_seq);
    };

    full_hash_t first() {
        _initialized = true;

        for (char i = 0; i < _ksize; ++i) {
            fwd_hasher.eat(*(_seq + i));
            bwd_hasher.eat(_rev[length - _ksize + i]);
        }
        index += 1;
        return std::make_pair(fwd_hasher.hashvalue, bwd_hasher.hashvalue);
    }

    full_hash_t next() {
        if (!_initialized) {
            return first();
        }

        if (done()) {
            throw oxli_exception("past end of iterator");
        }
        fwd_hasher.update(*(_seq + index - 1), *(_seq + index + _ksize - 1));

        // first argument is added, second is removed from the hash
        bwd_hasher.reverse_update(
          _rev[length - _ksize - index], _rev[length - index]);

        index += 1;

        return std::make_pair(fwd_hasher.hashvalue, bwd_hasher.hashvalue);
    }

    bool done() const {
        return (index + _ksize > length);
    }

    unsigned int get_start_pos() const {
        if (!_initialized) { return 0; }
        return index - 1;
    }

    unsigned int get_end_pos() const {
        if (!_initialized) { return _ksize; }
        return index + _ksize - 1;
    }
};
*/

};
<|endoftext|>


<commit_before>#include <QDebug>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QThread>

#include <coreplugin/messagemanager.h>

#include "CppcheckRunner.h"
#include "Settings.h"

using namespace QtcCppcheck::Internal;

namespace
{
  enum ErrorField
  {
    ErrorFieldFile = 0, ErrorFieldLine, ErrorFieldSeverity, ErrorFieldId,
    ErrorFieldMessage
  };
}

CppcheckRunner::CppcheckRunner(Settings *settings, QObject *parent) :
  QObject(parent), settings_ (settings), showOutput_ (false)
{
  Q_ASSERT (settings_ != NULL);

  connect (&process_, SIGNAL (readyReadStandardOutput()),
           SLOT (readOutput()));
  connect (&process_, SIGNAL (readyReadStandardError()),
           SLOT (readError()));
  connect (&process_, SIGNAL (started()),
           SLOT (started()));
  connect (&process_, SIGNAL (error(QProcess::ProcessError)),
           SLOT (error(QProcess::ProcessError)));
  connect (&process_, SIGNAL (finished(int, QProcess::ExitStatus)),
           SLOT (finished(int, QProcess::ExitStatus)));

  // Restart checking if got queue.
  connect (&process_, SIGNAL (finished(int, QProcess::ExitStatus)),
           SLOT (checkQueuedFiles ()));
}

CppcheckRunner::~CppcheckRunner()
{
  queueTimer_.stop ();
  settings_ = NULL;
}

void CppcheckRunner::updateSettings()
{
  Q_ASSERT (settings_ != NULL);
  showOutput_ = settings_->showBinaryOutput ();
  runArguments_.clear ();
  runArguments_ << QLatin1String ("-q");
  // Pass custom params BEFORE most of runner's to shadow if some repeat.
  runArguments_ += settings_->customParameters ().split (QLatin1Char (' '));
  QString enabled = QLatin1String ("--enable=warning,style,performance,"
                                   "portability,information,missingInclude");
  if (settings_->checkUnused ())
  {
      enabled += QLatin1String (",unusedFunction");
  }
  else //TODO always check with threads but rescan for unused after finish?
  {
    runArguments_ << (QLatin1String ("-j ") +
                      QString::number (QThread::idealThreadCount ()));
  }
  runArguments_ << enabled;
  if (settings_->checkInconclusive ())
  {
    runArguments_ << QLatin1String ("--inconclusive");
  }
  runArguments_ << QLatin1String ("--template={file},{line},{severity},{id},{message}");
}

void CppcheckRunner::checkFiles(const QStringList &fileNames)
{
  Q_ASSERT (!fileNames.isEmpty ());
  fileCheckQueue_ += fileNames;
  fileCheckQueue_.removeDuplicates ();
  fileCheckQueue_.sort ();
  if (process_.isOpen ())
  {
    if (fileCheckQueue_ == currentlyCheckingFiles_)
    {
      process_.kill ();
      // Rechecking will be restarted on finish signal.
    }
    return;
  }
  // Delay helps to avoid double checking same file on editor change.
  const int checkDelayInMs = 200;
  if (!queueTimer_.isActive ())
  {
    queueTimer_.singleShot (checkDelayInMs, this, SLOT (checkQueuedFiles ()));
  }
}

void CppcheckRunner::stopCheckhig()
{
  fileCheckQueue_.clear ();
  if (process_.isOpen ())
  {
    process_.kill ();
  }
}

void CppcheckRunner::checkQueuedFiles()
{
  if (fileCheckQueue_.isEmpty ())
  {
    return;
  }
  QString binary = settings_->binaryFile ();
  Q_ASSERT (!binary.isEmpty ());
  QStringList arguments (runArguments_);
  arguments += fileCheckQueue_;
  currentlyCheckingFiles_ = fileCheckQueue_;
  fileCheckQueue_.clear ();
  process_.start (binary, arguments);
}

void CppcheckRunner::readOutput()
{
  if (!showOutput_)
  {
    return;
  }
  process_.setReadChannel (QProcess::StandardOutput);

  while (!process_.atEnd ())
  {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ())
    {
      continue;
    }
    Core::MessageManager::write (line, Core::MessageManager::Silent);
  }
}

void CppcheckRunner::readError()
{
  process_.setReadChannel (QProcess::StandardError);

  while (!process_.atEnd ())
  {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ())
    {
      continue;
    }
    if (showOutput_)
    {
      Core::MessageManager::write (line, Core::MessageManager::Silent);
    }
    QStringList details = line.split (QLatin1Char (','));
    if (details.size () <= ErrorFieldMessage)
    {
      continue;
    }
    QString file = QDir::fromNativeSeparators(details.at (ErrorFieldFile));
    int lineNumber = details.at (ErrorFieldLine).toInt ();
    char type = details.at (ErrorFieldSeverity).at (0).toAscii ();
    QString description = line.mid (line.indexOf (details.at (ErrorFieldMessage)));
    emit newTask (type, description, file, lineNumber);
  }
}

void CppcheckRunner::started()
{
  if (showOutput_)
  {
    Core::MessageManager::write (tr ("Cppcheck started"), Core::MessageManager::Silent);
  }
}

void CppcheckRunner::error(QProcess::ProcessError error)
{
  Q_UNUSED (error);
  if (showOutput_)
  {
    Core::MessageManager::write (tr ("Cppcheck error occured"), Core::MessageManager::Silent);
  }
}

void CppcheckRunner::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
  Q_UNUSED (exitCode);
  Q_UNUSED (exitStatus);
  process_.close ();
  if (showOutput_)
  {
    Core::MessageManager::write (tr("Cppcheck finished"), Core::MessageManager::Silent);
  }
}
<commit_msg>User now can override --enable cppcheck options<commit_after>#include <QDebug>
#include <QSettings>
#include <QFileInfo>
#include <QDir>
#include <QThread>

#include <coreplugin/messagemanager.h>

#include "CppcheckRunner.h"
#include "Settings.h"

using namespace QtcCppcheck::Internal;

namespace
{
  enum ErrorField
  {
    ErrorFieldFile = 0, ErrorFieldLine, ErrorFieldSeverity, ErrorFieldId,
    ErrorFieldMessage
  };
}

CppcheckRunner::CppcheckRunner(Settings *settings, QObject *parent) :
  QObject(parent), settings_ (settings), showOutput_ (false)
{
  Q_ASSERT (settings_ != NULL);

  connect (&process_, SIGNAL (readyReadStandardOutput()),
           SLOT (readOutput()));
  connect (&process_, SIGNAL (readyReadStandardError()),
           SLOT (readError()));
  connect (&process_, SIGNAL (started()),
           SLOT (started()));
  connect (&process_, SIGNAL (error(QProcess::ProcessError)),
           SLOT (error(QProcess::ProcessError)));
  connect (&process_, SIGNAL (finished(int, QProcess::ExitStatus)),
           SLOT (finished(int, QProcess::ExitStatus)));

  // Restart checking if got queue.
  connect (&process_, SIGNAL (finished(int, QProcess::ExitStatus)),
           SLOT (checkQueuedFiles ()));
}

CppcheckRunner::~CppcheckRunner()
{
  queueTimer_.stop ();
  settings_ = NULL;
}

void CppcheckRunner::updateSettings()
{
  Q_ASSERT (settings_ != NULL);
  showOutput_ = settings_->showBinaryOutput ();
  runArguments_.clear ();
  runArguments_ << QLatin1String ("-q");
  // Pass custom params BEFORE most of runner's to shadow if some repeat.
  runArguments_ += settings_->customParameters ().split (
                     QLatin1Char (' '), QString::SkipEmptyParts);
  QString enabled = QLatin1String ("--enable=warning,style,performance,"
                                   "portability,information,missingInclude");
  // Overwrite enable with user parameters if present
  for(int i = runArguments_.size () - 1; i >= 0; --i)
  {
    if (runArguments_.at (i).startsWith (QLatin1String ("--enable")))
    {
      enabled = runArguments_.takeAt (i);
      break;
    }
  }
  if (settings_->checkUnused ())
  {
      enabled += QLatin1String (",unusedFunction");
  }
  else //TODO always check with threads but rescan for unused after finish?
  {
    runArguments_ << (QLatin1String ("-j ") +
                      QString::number (QThread::idealThreadCount ()));
  }
  runArguments_ << enabled;
  if (settings_->checkInconclusive ())
  {
    runArguments_ << QLatin1String ("--inconclusive");
  }
  runArguments_ << QLatin1String ("--template={file},{line},{severity},{id},{message}");
}

void CppcheckRunner::checkFiles(const QStringList &fileNames)
{
  Q_ASSERT (!fileNames.isEmpty ());
  fileCheckQueue_ += fileNames;
  fileCheckQueue_.removeDuplicates ();
  fileCheckQueue_.sort ();
  if (process_.isOpen ())
  {
    if (fileCheckQueue_ == currentlyCheckingFiles_)
    {
      process_.kill ();
      // Rechecking will be restarted on finish signal.
    }
    return;
  }
  // Delay helps to avoid double checking same file on editor change.
  const int checkDelayInMs = 200;
  if (!queueTimer_.isActive ())
  {
    queueTimer_.singleShot (checkDelayInMs, this, SLOT (checkQueuedFiles ()));
  }
}

void CppcheckRunner::stopCheckhig()
{
  fileCheckQueue_.clear ();
  if (process_.isOpen ())
  {
    process_.kill ();
  }
}

void CppcheckRunner::checkQueuedFiles()
{
  if (fileCheckQueue_.isEmpty ())
  {
    return;
  }
  QString binary = settings_->binaryFile ();
  Q_ASSERT (!binary.isEmpty ());
  QStringList arguments (runArguments_);
  arguments += fileCheckQueue_;
  currentlyCheckingFiles_ = fileCheckQueue_;
  fileCheckQueue_.clear ();
  process_.start (binary, arguments);
}

void CppcheckRunner::readOutput()
{
  if (!showOutput_)
  {
    return;
  }
  process_.setReadChannel (QProcess::StandardOutput);

  while (!process_.atEnd ())
  {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ())
    {
      continue;
    }
    Core::MessageManager::write (line, Core::MessageManager::Silent);
  }
}

void CppcheckRunner::readError()
{
  process_.setReadChannel (QProcess::StandardError);

  while (!process_.atEnd ())
  {
    QByteArray rawLine = process_.readLine ();
    QString line = QString::fromUtf8 (rawLine).trimmed ();
    if (line.isEmpty ())
    {
      continue;
    }
    if (showOutput_)
    {
      Core::MessageManager::write (line, Core::MessageManager::Silent);
    }
    QStringList details = line.split (QLatin1Char (','));
    if (details.size () <= ErrorFieldMessage)
    {
      continue;
    }
    QString file = QDir::fromNativeSeparators(details.at (ErrorFieldFile));
    int lineNumber = details.at (ErrorFieldLine).toInt ();
    char type = details.at (ErrorFieldSeverity).at (0).toAscii ();
    QString description = line.mid (line.indexOf (details.at (ErrorFieldMessage)));
    emit newTask (type, description, file, lineNumber);
  }
}

void CppcheckRunner::started()
{
  if (showOutput_)
  {
    Core::MessageManager::write (tr ("Cppcheck started"), Core::MessageManager::Silent);
  }
}

void CppcheckRunner::error(QProcess::ProcessError error)
{
  Q_UNUSED (error);
  if (showOutput_)
  {
    Core::MessageManager::write (tr ("Cppcheck error occured"), Core::MessageManager::Silent);
  }
}

void CppcheckRunner::finished(int exitCode, QProcess::ExitStatus exitStatus)
{
  Q_UNUSED (exitCode);
  Q_UNUSED (exitStatus);
  process_.close ();
  if (showOutput_)
  {
    Core::MessageManager::write (tr("Cppcheck finished"), Core::MessageManager::Silent);
  }
}
<|endoftext|>


<commit_before>#include <QApplication>
#include <QDebug>
#include <QLineEdit>
#include <QComboBox>

#include "DactMacrosMenu.hh"

DactMacrosMenu::DactMacrosMenu(QWidget *parent)
:
	QMenu(parent)
{}

void DactMacrosMenu::setModel(QSharedPointer<DactMacrosModel> model)
{
	if (d_model)
		disconnect(d_model.data(), 0, this, 0);

	d_model = model;

	connect(d_model.data(), SIGNAL(dataChanged(QModelIndex const &, QModelIndex const &)), SLOT(reload()));

	reload();
}

void DactMacrosMenu::reload()
{
	// Remove all our dynamically added menu items.
	foreach (QAction *action, d_macroActions)
		removeAction(action);

	// All menus have been removed, now forget them.
	d_macroActions.clear();

	// For each macro:
	for (int m_row = 0, m_end = d_model->rowCount(QModelIndex()); m_row < m_end; ++m_row)
	{
		QModelIndex patternIndex(d_model->index(m_row, 0));
		QModelIndex replacementIndex(d_model->index(m_row, 1));

		// Label the menu item.
		QAction *action = addAction(patternIndex.data(Qt::DisplayRole).toString());
		d_macroActions.append(action);

		// And show the replacement in the tooltip.
		action->setToolTip(replacementIndex.data(Qt::DisplayRole).toString());

		// And remember the pattern in the data section, for easy use later on.
		action->setData(patternIndex.data(Qt::UserRole).toString());

		// And connect the action to the method that inserts the pattern in the focussed widget.
		connect(action, SIGNAL(triggered()), SLOT(macroActionTriggered()));
	}

	addSeparator();

	// A force-reload menu action, which reloads the macro file.
	QAction *reloadAction = addAction("Reload file");
	d_macroActions.append(reloadAction);
	connect(reloadAction, SIGNAL(triggered()), SLOT(reloadActionTriggered()));
}

void DactMacrosMenu::macroActionTriggered()
{
	QAction *action = qobject_cast<QAction *>(sender());

	if (!action)
	{
		qDebug() << "Could not cast the sender of the macroActionTriggered event to a QAction pointer";
		return;
	}

	if (QLineEdit *focussedLineEdit = qobject_cast<QLineEdit *>(QApplication::focusWidget()))
		focussedLineEdit->insert(action->data().toString());

	else if (QComboBox *focussedComboBox = qobject_cast<QComboBox *>(QApplication::focusWidget()))
		focussedComboBox->lineEdit()->insert(action->data().toString());
}

void DactMacrosMenu::reloadActionTriggered()
{
	d_model->reloadFile();
}
<commit_msg>Reindent DactMacrosMenu.cpp.<commit_after>#include <QApplication>
#include <QDebug>
#include <QLineEdit>
#include <QComboBox>

#include "DactMacrosMenu.hh"

DactMacrosMenu::DactMacrosMenu(QWidget *parent)
:
    QMenu(parent)
{}

void DactMacrosMenu::setModel(QSharedPointer<DactMacrosModel> model)
{
    if (d_model)
        disconnect(d_model.data(), 0, this, 0);

    d_model = model;

    connect(d_model.data(), SIGNAL(dataChanged(QModelIndex const &, QModelIndex const &)), SLOT(reload()));

    reload();
}

void DactMacrosMenu::reload()
{
    // Remove all our dynamically added menu items.
    foreach (QAction *action, d_macroActions)
        removeAction(action);

    // All menus have been removed, now forget them.
    d_macroActions.clear();

    // For each macro:
    for (int m_row = 0, m_end = d_model->rowCount(QModelIndex()); m_row < m_end; ++m_row)
    {
        QModelIndex patternIndex(d_model->index(m_row, 0));
        QModelIndex replacementIndex(d_model->index(m_row, 1));

        // Label the menu item.
        QAction *action = addAction(patternIndex.data(Qt::DisplayRole).toString());
        d_macroActions.append(action);

        // And show the replacement in the tooltip.
        action->setToolTip(replacementIndex.data(Qt::DisplayRole).toString());

        // And remember the pattern in the data section, for easy use later on.
        action->setData(patternIndex.data(Qt::UserRole).toString());

        // And connect the action to the method that inserts the pattern in the focussed widget.
        connect(action, SIGNAL(triggered()), SLOT(macroActionTriggered()));
    }

    addSeparator();

    // A force-reload menu action, which reloads the macro file.
    QAction *reloadAction = addAction("Reload file");
    d_macroActions.append(reloadAction);
    connect(reloadAction, SIGNAL(triggered()), SLOT(reloadActionTriggered()));
}

void DactMacrosMenu::macroActionTriggered()
{
    QAction *action = qobject_cast<QAction *>(sender());

    if (!action)
    {
        qDebug() << "Could not cast the sender of the macroActionTriggered event to a QAction pointer";
        return;
    }

    if (QLineEdit *focussedLineEdit = qobject_cast<QLineEdit *>(QApplication::focusWidget()))
        focussedLineEdit->insert(action->data().toString());

    else if (QComboBox *focussedComboBox = qobject_cast<QComboBox *>(QApplication::focusWidget()))
        focussedComboBox->lineEdit()->insert(action->data().toString());
}

void DactMacrosMenu::reloadActionTriggered()
{
    d_model->reloadFile();
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "DijkstraDrawer.h"
#include "Options.h"

#include <algorithm>

void DijkstraDrawer::prepareNewState()
{
    auto state = states[animationState];
    setChanged();
}

void DijkstraDrawer::createLegend()
{
    legend.clear();
    auto &cs = Options::instance().currentColorScheme;
    legend.add(LegendType::highlightedArrow, cs.highlightedEdgeColor2, "Minimal paths");
    legend.add(LegendType::highlightedArrow, cs.highlightedEdgeColor1, "Inspected");
    legend.add(LegendType::arrow, cs.edgeColor, "Not processed yet");
    legend.add(LegendType::node, cs.highlightedNodeColor3, "Finished");
    legend.add(LegendType::node, cs.highlightedNodeColor2, "Reached");
    legend.add(LegendType::node, cs.highlightedNodeColor1, "Inspected");
    legend.add(LegendType::node, cs.nodeColor, "Not reached yet");
}

void DijkstraDrawer::prepareAnimation()
{
    GraphAnimationDrawer::prepareAnimation();
    states = graph_algorithm_capture::edgeWeightDijkstraCaptureStates(*g, Options::instance().startNode - 1, -1);
    animationLastState = states.size();
}

void DijkstraDrawer::drawAlgorithmState()
{
    if (animationState >= int(states.size()))
        return;
    startDrawing();
    auto state = states[animationState];
    const auto &cs = Options::instance().currentColorScheme;
    // Edges -----
    // preparing edge parameters before drawing
    std::map<std::shared_ptr<GraphEdge>, std::pair<ci::Color, float>> edgeParams;
    // by default edges are drawn with edgeColor and edgeWidth (no highlighting)
    for (int nodeIdx = 0; nodeIdx < g->getNodeCount(); ++nodeIdx)
    {
        auto &node = g->getNode(nodeIdx);
        for (auto edgePtr : node)
        {
            edgeParams[edgePtr] = std::make_pair(cs.edgeColor, Options::instance().edgeWidth);
        }
    }

    // now the params for all dropped edges are overwritten
    for (auto &edgePtr : state.processedEdges)
    {
        edgeParams[edgePtr] = std::make_pair(cs.darkEdgeColor, Options::instance().edgeWidth);
    }

    // overwriting the edges of the current best paths
    for (auto &p : state.path)
    {
        if (p.second == nullptr)
            continue;
        edgeParams[p.second] = std::make_pair(cs.highlightedEdgeColor2, Options::instance().highlighedEdgeWidth);
    }

    // and finally the currently inspected edge
    if (state.inspectedEdge != nullptr)
        edgeParams[state.inspectedEdge] = std::make_pair(cs.highlightedEdgeColor1, Options::instance().highlighedEdgeWidth);

    for (auto &p : edgeParams)
    {
        drawEdge(p.first->from, p.first->to, p.second.first, p.second.second);
    }

    // Nodes ---------
    // Preparing open nodes
    std::vector<ci::Color> nodeHighlight(g->getNodeCount(), cs.nodeColor);
    for (auto &p : state.openNodes)
    {
        nodeHighlight[p.second] = cs.highlightedNodeColor2;
    }

    // Preparing closed nodes
    for (auto &p : state.closedNodes)
    {
        nodeHighlight[p.second] = cs.highlightedNodeColor3;
    }

    // Preparing current node
    if (state.inspectedNode != -1)
    {
        nodeHighlight[state.inspectedNode] = cs.highlightedNodeColor1;
    }

    // Drawing nodes
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        nodeHandlers[i]->draw(nodeHighlight[i]);
    }

    // Labels -----
    // preparing edge label colors
    std::map<std::shared_ptr<GraphEdge>, ci::ColorA> edgeLabelColors;
    for (auto &edgePtr : edgeParams)
    {
        edgeLabelColors[edgePtr.first] = edgePtr.second.first;
    }
    drawLabels(edgeLabelColors);

    drawStepDescription(state.description);
}

void DijkstraDrawer::drawAlgorithmResult()
{
    startDrawing();
    drawEdges();
    auto tree = edgeWeightDijkstra(*g, Options::instance().startNode - 1, -1);
    for (int i = 0; i < int(tree.size()); ++i)
    {
        auto edgePtr = tree[i].second;
        if (edgePtr == nullptr)
            continue;
        drawEdge(edgePtr->from, edgePtr->to, Options::instance().currentColorScheme.highlightedEdgeColor2, Options::instance().highlighedEdgeWidth);
    }
    drawNodes();
    drawLabels();
}<commit_msg>Added dropped edges to Dijsktra's legend<commit_after>#include "stdafx.h"
#include "DijkstraDrawer.h"
#include "Options.h"

#include <algorithm>

void DijkstraDrawer::prepareNewState()
{
    auto state = states[animationState];
    setChanged();
}

void DijkstraDrawer::createLegend()
{
    legend.clear();
    auto &cs = Options::instance().currentColorScheme;
    legend.add(LegendType::highlightedArrow, cs.highlightedEdgeColor2, "Minimal paths");
    legend.add(LegendType::highlightedArrow, cs.highlightedEdgeColor1, "Currently inspected");
    legend.add(LegendType::arrow, cs.darkEdgeColor, "Processed and ignored");
    legend.add(LegendType::arrow, cs.edgeColor, "Not processed");
    legend.add(LegendType::node, cs.highlightedNodeColor3, "Finished");
    legend.add(LegendType::node, cs.highlightedNodeColor2, "Reached but not processed");
    legend.add(LegendType::node, cs.highlightedNodeColor1, "Currently inspected");
    legend.add(LegendType::node, cs.nodeColor, "Not reached");
}

void DijkstraDrawer::prepareAnimation()
{
    GraphAnimationDrawer::prepareAnimation();
    states = graph_algorithm_capture::edgeWeightDijkstraCaptureStates(*g, Options::instance().startNode - 1, -1);
    animationLastState = states.size();
}

void DijkstraDrawer::drawAlgorithmState()
{
    if (animationState >= int(states.size()))
        return;
    startDrawing();
    auto state = states[animationState];
    const auto &cs = Options::instance().currentColorScheme;
    // Edges -----
    // preparing edge parameters before drawing
    std::map<std::shared_ptr<GraphEdge>, std::pair<ci::Color, float>> edgeParams;
    // by default edges are drawn with edgeColor and edgeWidth (no highlighting)
    for (int nodeIdx = 0; nodeIdx < g->getNodeCount(); ++nodeIdx)
    {
        auto &node = g->getNode(nodeIdx);
        for (auto edgePtr : node)
        {
            edgeParams[edgePtr] = std::make_pair(cs.edgeColor, Options::instance().edgeWidth);
        }
    }

    // now the params for all dropped edges are overwritten
    for (auto &edgePtr : state.processedEdges)
    {
        edgeParams[edgePtr] = std::make_pair(cs.darkEdgeColor, Options::instance().edgeWidth);
    }

    // overwriting the edges of the current best paths
    for (auto &p : state.path)
    {
        if (p.second == nullptr)
            continue;
        edgeParams[p.second] = std::make_pair(cs.highlightedEdgeColor2, Options::instance().highlighedEdgeWidth);
    }

    // and finally the currently inspected edge
    if (state.inspectedEdge != nullptr)
        edgeParams[state.inspectedEdge] = std::make_pair(cs.highlightedEdgeColor1, Options::instance().highlighedEdgeWidth);

    for (auto &p : edgeParams)
    {
        drawEdge(p.first->from, p.first->to, p.second.first, p.second.second);
    }

    // Nodes ---------
    // Preparing open nodes
    std::vector<ci::Color> nodeHighlight(g->getNodeCount(), cs.nodeColor);
    for (auto &p : state.openNodes)
    {
        nodeHighlight[p.second] = cs.highlightedNodeColor2;
    }

    // Preparing closed nodes
    for (auto &p : state.closedNodes)
    {
        nodeHighlight[p.second] = cs.highlightedNodeColor3;
    }

    // Preparing current node
    if (state.inspectedNode != -1)
    {
        nodeHighlight[state.inspectedNode] = cs.highlightedNodeColor1;
    }

    // Drawing nodes
    for (int i = 0; i < g->getNodeCount(); ++i)
    {
        nodeHandlers[i]->draw(nodeHighlight[i]);
    }

    // Labels -----
    // preparing edge label colors
    std::map<std::shared_ptr<GraphEdge>, ci::ColorA> edgeLabelColors;
    for (auto &edgePtr : edgeParams)
    {
        edgeLabelColors[edgePtr.first] = edgePtr.second.first;
    }
    drawLabels(edgeLabelColors);

    drawStepDescription(state.description);
}

void DijkstraDrawer::drawAlgorithmResult()
{
    startDrawing();
    drawEdges();
    auto tree = edgeWeightDijkstra(*g, Options::instance().startNode - 1, -1);
    for (int i = 0; i < int(tree.size()); ++i)
    {
        auto edgePtr = tree[i].second;
        if (edgePtr == nullptr)
            continue;
        drawEdge(edgePtr->from, edgePtr->to, Options::instance().currentColorScheme.highlightedEdgeColor2, Options::instance().highlighedEdgeWidth);
    }
    drawNodes();
    drawLabels();
}<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 Kolibre
 *
 * This file is part of kolibre-clientcore.
 *
 * Kolibre-clientcore is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Kolibre-clientcore 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 kolibre-clientcore. If not, see <http://www.gnu.org/licenses/>.
 */

#include "FileSystemNode.h"
#include "DaisyBookNode.h"
#include "Defines.h"
#include "config.h"
#include "CommandQueue2/CommandQueue.h"
#include "Commands/InternalCommands.h"
#include "Utils.h"

#include <Narrator.h>
#include <NaviEngine.h>

#include <sstream>
#include <log4cxx/logger.h>

// create logger which will become a child to logger kolibre.clientcore
log4cxx::LoggerPtr fsNodeLog(log4cxx::Logger::getLogger("kolibre.clientcore.filesystemnode"));

using namespace naviengine;

FileSystemNode::FileSystemNode(const std::string name, const std::string path)
{
    LOG4CXX_TRACE(fsNodeLog, "Constructor");
    name_ = "FileSystem_" + name;
    fsName_ = name;
    fsPath_ = path;
}

FileSystemNode::~FileSystemNode()
{
    LOG4CXX_TRACE(fsNodeLog, "Destructor");
}

// NaviEngine functions

bool FileSystemNode::next(NaviEngine& navi)
{
    bool ret = MenuNode::next(navi);
    currentChild_ = navi.getCurrentChoice();
    announceSelection();
    return ret;
}

bool FileSystemNode::prev(NaviEngine& navi)
{
    bool ret = MenuNode::prev(navi);
    currentChild_ = navi.getCurrentChoice();
    announceSelection();
    return ret;
}

bool FileSystemNode::menu(NaviEngine& navi)
{
    return navi.openMenu(navi.buildContextMenu());
}

bool FileSystemNode::up(NaviEngine& navi)
{
    bool ret = MenuNode::up(navi);
    return ret;
}

bool FileSystemNode::onOpen(NaviEngine& navi)
{
    navi.setCurrentChoice(NULL);
    clearNodes();
    navilist_.items.clear();

    // Create sources defined in MediaSourceManager
    LOG4CXX_INFO(fsNodeLog, "Searching for supported content in path '" << fsPath_ << "'");

    std::vector<std::string> uris = Utils::recursiveSearchByFilename(fsPath_, "ncc.html");
    for (int i = 0; i < uris.size(); i++)
    {
        // create book node
        LOG4CXX_DEBUG(fsNodeLog, "Creating book node: '" <<  uris[i] << "'");
        DaisyBookNode* node = new DaisyBookNode(uris[0]);

        // invent a name for it
        ostringstream oss;
        oss << (i+1);
        node->name_ = "title_" + oss.str();

        // add node
        addNode(node);

        // create a NaviListItem and store it in list for the NaviList signal
        NaviListItem item(node->uri_, node->name_);
        navilist_.items.push_back(item);

    }

    if (navi.getCurrentChoice() == NULL && numberOfChildren() > 0)
    {
        navi.setCurrentChoice(firstChild());
        currentChild_ = firstChild();
    }

    currentChild_ = navi.getCurrentChoice();
    announce();

    if (numberOfChildren() == 1)
    {
        LOG4CXX_INFO(fsNodeLog, "Opening the only child");
        // wait for narrator before sending command
        usleep(500000); while (Narrator::Instance()->isSpeaking()) usleep(100000);
        cq2::Command<INTERNAL_COMMAND> c(COMMAND_DOWN);
        c();
    }

    return true;
}

void FileSystemNode::beforeOnOpen()
{
    Narrator::Instance()->play(_N("updating device"));
}

bool FileSystemNode::process(NaviEngine& navi, int command, void* data)
{
    return false;
}

bool FileSystemNode::narrateName()
{
    const bool isSelfNarrated = true;
    std::string lcName = Utils::toLower(fsName_);
    if (Utils::contains(lcName, "usb"))
        Narrator::Instance()->play(_N("usb device"));
    else if (Utils::contains(lcName, "sd"))
        Narrator::Instance()->play(_N("sd device"));
    else if (Utils::contains(lcName, "cdrom"))
        Narrator::Instance()->play(_N("cdrom device"));
    else
        Narrator::Instance()->play(_N("local device"));
    return isSelfNarrated;
}

bool FileSystemNode::narrateInfo()
{
    const bool isSelfNarrated = true;
    Narrator::Instance()->play(_N("choose option using left and right arrows, open using play button"));
    Narrator::Instance()->playLongpause();
    announceSelection();
    return isSelfNarrated;
}

bool FileSystemNode::onNarrate()
{
    const bool isSelfNarrated = true;
    return isSelfNarrated;
}

bool FileSystemNode::onRender()
{
    const bool isSelfRendered = true;
    return isSelfRendered;
}

void FileSystemNode::announce()
{
    cq2::Command<NaviList> naviList(navilist_);
    naviList();

    int numItems = numberOfChildren();

    if (numItems == 0)
    {
        Narrator::Instance()->play(_N("device contains no publications"));
    }
    else if (numItems == 1)
    {
        Narrator::Instance()->setParameter("1", numItems);
        Narrator::Instance()->play(_N("device contains {1} publication"));
    }
    else if (numItems > 1)
    {
        Narrator::Instance()->setParameter("2", numItems);
        Narrator::Instance()->play(_N("device contains {2} publications"));
    }
    Narrator::Instance()->playLongpause();

    announceSelection();
}

void FileSystemNode::announceSelection()
{
    int currentChoice = 0;
    AnyNode* current = currentChild_;

    if ((firstChild() != NULL) && (current != NULL))
    {
        while (firstChild() != current)
        {
            currentChoice++;
            current = current->prev_;
        }

        Narrator::Instance()->setParameter("1", currentChoice + 1);
        Narrator::Instance()->play(_N("publication no. {1}"));
        //Narrator::Instance()->play(currentChild_->name_.c_str());

        NaviListItem item = navilist_.items[currentChoice];
        cq2::Command<NaviListItem> naviItem(item);
        naviItem();
    }
}
<commit_msg>Create DaisyBookNode with correct uri<commit_after>/*
 * Copyright (C) 2012 Kolibre
 *
 * This file is part of kolibre-clientcore.
 *
 * Kolibre-clientcore is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Kolibre-clientcore 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 kolibre-clientcore. If not, see <http://www.gnu.org/licenses/>.
 */

#include "FileSystemNode.h"
#include "DaisyBookNode.h"
#include "Defines.h"
#include "config.h"
#include "CommandQueue2/CommandQueue.h"
#include "Commands/InternalCommands.h"
#include "Utils.h"

#include <Narrator.h>
#include <NaviEngine.h>

#include <sstream>
#include <log4cxx/logger.h>

// create logger which will become a child to logger kolibre.clientcore
log4cxx::LoggerPtr fsNodeLog(log4cxx::Logger::getLogger("kolibre.clientcore.filesystemnode"));

using namespace naviengine;

FileSystemNode::FileSystemNode(const std::string name, const std::string path)
{
    LOG4CXX_TRACE(fsNodeLog, "Constructor");
    name_ = "FileSystem_" + name;
    fsName_ = name;
    fsPath_ = path;
}

FileSystemNode::~FileSystemNode()
{
    LOG4CXX_TRACE(fsNodeLog, "Destructor");
}

// NaviEngine functions

bool FileSystemNode::next(NaviEngine& navi)
{
    bool ret = MenuNode::next(navi);
    currentChild_ = navi.getCurrentChoice();
    announceSelection();
    return ret;
}

bool FileSystemNode::prev(NaviEngine& navi)
{
    bool ret = MenuNode::prev(navi);
    currentChild_ = navi.getCurrentChoice();
    announceSelection();
    return ret;
}

bool FileSystemNode::menu(NaviEngine& navi)
{
    return navi.openMenu(navi.buildContextMenu());
}

bool FileSystemNode::up(NaviEngine& navi)
{
    bool ret = MenuNode::up(navi);
    return ret;
}

bool FileSystemNode::onOpen(NaviEngine& navi)
{
    navi.setCurrentChoice(NULL);
    clearNodes();
    navilist_.items.clear();

    // Create sources defined in MediaSourceManager
    LOG4CXX_INFO(fsNodeLog, "Searching for supported content in path '" << fsPath_ << "'");

    std::vector<std::string> uris = Utils::recursiveSearchByFilename(fsPath_, "ncc.html");
    for (int i = 0; i < uris.size(); i++)
    {
        // create book node
        LOG4CXX_DEBUG(fsNodeLog, "Creating book node: '" <<  uris[i] << "'");
        DaisyBookNode* node = new DaisyBookNode(uris[i]);

        // invent a name for it
        ostringstream oss;
        oss << (i+1);
        node->name_ = "title_" + oss.str();

        // add node
        addNode(node);

        // create a NaviListItem and store it in list for the NaviList signal
        NaviListItem item(node->uri_, node->name_);
        navilist_.items.push_back(item);

    }

    if (navi.getCurrentChoice() == NULL && numberOfChildren() > 0)
    {
        navi.setCurrentChoice(firstChild());
        currentChild_ = firstChild();
    }

    currentChild_ = navi.getCurrentChoice();
    announce();

    if (numberOfChildren() == 1)
    {
        LOG4CXX_INFO(fsNodeLog, "Opening the only child");
        // wait for narrator before sending command
        usleep(500000); while (Narrator::Instance()->isSpeaking()) usleep(100000);
        cq2::Command<INTERNAL_COMMAND> c(COMMAND_DOWN);
        c();
    }

    return true;
}

void FileSystemNode::beforeOnOpen()
{
    Narrator::Instance()->play(_N("updating device"));
}

bool FileSystemNode::process(NaviEngine& navi, int command, void* data)
{
    return false;
}

bool FileSystemNode::narrateName()
{
    const bool isSelfNarrated = true;
    std::string lcName = Utils::toLower(fsName_);
    if (Utils::contains(lcName, "usb"))
        Narrator::Instance()->play(_N("usb device"));
    else if (Utils::contains(lcName, "sd"))
        Narrator::Instance()->play(_N("sd device"));
    else if (Utils::contains(lcName, "cdrom"))
        Narrator::Instance()->play(_N("cdrom device"));
    else
        Narrator::Instance()->play(_N("local device"));
    return isSelfNarrated;
}

bool FileSystemNode::narrateInfo()
{
    const bool isSelfNarrated = true;
    Narrator::Instance()->play(_N("choose option using left and right arrows, open using play button"));
    Narrator::Instance()->playLongpause();
    announceSelection();
    return isSelfNarrated;
}

bool FileSystemNode::onNarrate()
{
    const bool isSelfNarrated = true;
    return isSelfNarrated;
}

bool FileSystemNode::onRender()
{
    const bool isSelfRendered = true;
    return isSelfRendered;
}

void FileSystemNode::announce()
{
    cq2::Command<NaviList> naviList(navilist_);
    naviList();

    int numItems = numberOfChildren();

    if (numItems == 0)
    {
        Narrator::Instance()->play(_N("device contains no publications"));
    }
    else if (numItems == 1)
    {
        Narrator::Instance()->setParameter("1", numItems);
        Narrator::Instance()->play(_N("device contains {1} publication"));
    }
    else if (numItems > 1)
    {
        Narrator::Instance()->setParameter("2", numItems);
        Narrator::Instance()->play(_N("device contains {2} publications"));
    }
    Narrator::Instance()->playLongpause();

    announceSelection();
}

void FileSystemNode::announceSelection()
{
    int currentChoice = 0;
    AnyNode* current = currentChild_;

    if ((firstChild() != NULL) && (current != NULL))
    {
        while (firstChild() != current)
        {
            currentChoice++;
            current = current->prev_;
        }

        Narrator::Instance()->setParameter("1", currentChoice + 1);
        Narrator::Instance()->play(_N("publication no. {1}"));
        //Narrator::Instance()->play(currentChild_->name_.c_str());

        NaviListItem item = navilist_.items[currentChoice];
        cq2::Command<NaviListItem> naviItem(item);
        naviItem();
    }
}
<|endoftext|>