<commit_before>#include "SynchronousCameraQueue.hpp"

#include <ros/console.h>

#include "../../matlab/profiling.hpp"

SynchronousCameraQueue::SynchronousCameraQueue(long int arrivalDelay, long int maxDelay, long maxGroupInterval, bool ensureCam0)
{
	this->maxDelay = maxDelay;
	this->arrivalDelay = arrivalDelay;
	this->maxGroupInterval = maxGroupInterval;
	this->ensureCam0 = ensureCam0;
	lastArrivalTime = 0;
	minimumPictureTime = 0;

	ROS_INFO("SynchronousCameraQueue(): arrivalDelay = %.2fms, maxDelay = %.2fms, maxGroupInterval = %.2fms, ensureCam0 = %s", arrivalDelay / 1e6, maxDelay / 1e6, maxGroupInterval / 1e6, ensureCam0 ? "true" : "false");
}

size_t SynchronousCameraQueue::getSize()
{
	return queue.size();
}

bool SynchronousCameraQueue::dataAvailable()
{
	long int currentTime = getNanoTime();

	if (queue.size() == 0) {
		return false;
	}

	if (queue.size() >= camNos.size()) {
		return true;
	}

	for (std::list<Bucket>::reverse_iterator it = queue.rbegin(); it != queue.rend(); it++) {
		if (currentTime - it->arrivalTime > maxDelay) {
			return true;
		}

		if (currentTime - it->arrivalTime > arrivalDelay && queue.size() > 2) {
			return true;
		}
	}

	return false;
}

void SynchronousCameraQueue::enqueueInternal(CameraData data)
{
	// Make it impossible to insert data for a time earlier than the last dequeue() result
	if (data.time <= minimumPictureTime) {
		ROS_DEBUG("Dropped data from cam %d, copter %d because it was too old (time: %ld)", data.camNo, data.quadcopterId, data.time);
		return;
	} else {
		// ROS_DEBUG("Inserting data from cam %d, copter %d (time: %ld)", data.camNo, data.quadcopterId, data.time);
	}

	Bucket b;
	b.data = data;
	b.arrivalTime = getNanoTime();

	if (b.arrivalTime <= lastArrivalTime) {
		lastArrivalTime++;
		b.arrivalTime = lastArrivalTime;
	}

	std::list<Bucket> tmp;
	tmp.push_back(b);
	queue.merge(tmp);

	camNos.insert(data.camNo);
}

std::vector<CameraData> SynchronousCameraQueue::dequeue()
{
	long int currentTime = getNanoTime();

	Group result;

	for (std::list<Bucket>::iterator it = queue.begin(); it != queue.end(); it++) {
		Group tmp = searchGroup(it, currentTime, queue.begin(), --queue.end());

		if (tmp.isValid() && (!result.isValid() || tmp.getValue() > result.getValue())) {
			result = tmp;
		}
	}

	if (result.isValid()) {
		//printQueue();
		cutOffQueue(result.getYoungest());

		if (result.getData().size() < camNos.size()) {
			ROS_WARN("Quadcopter %d is only seen by %ld cameras, but there are %ld entries in the queue", result.getData()[0].quadcopterId, result.getData().size(), queue.size());
		}

		return result.getData();
	} else {
		// Search for element which is older than maxDelay
		for (std::list<Bucket>::iterator it = queue.begin(); it != queue.end(); it++) {
			if (currentTime - it->arrivalTime > maxDelay) {
				ROS_WARN("The only thing to return is old and probably invalid, but better than nothing so we return it anyways.");

				// element is overdue and nothing else was found, so return group, even if it's invalid.
				result = searchGroup(it, currentTime, queue.begin(), --queue.end());
				//printQueue();
				cutOffQueue(result.getYoungest());

				return result.getData();
			}
		}

		return std::vector<CameraData>();
	}
}

SynchronousCameraQueue::Group SynchronousCameraQueue::searchGroup(std::list<Bucket>::iterator it, long int currentTime, std::list<Bucket>::iterator begin, std::list<Bucket>::iterator end)
{
	Group result(it, currentTime, arrivalDelay, maxDelay, maxGroupInterval, camNos.size(), ensureCam0);

	std::set<int> usedCamNos;
	usedCamNos.insert(it->data.camNo);

	// The current rand of the search area
	std::list<Bucket>::iterator left = it;
	std::list<Bucket>::iterator right = it;

	// Temp iterator to reduce the amount of if/else
	std::list<Bucket>::iterator current = it;

	// Which side of the rand to go
	int direction = 0; // -1 left, 1 right, 0 terminate

	do {
		direction = 0;

		// Choose direction
		if (left != begin && right != end) {
			// Both directions are possible

			left--;
			right++;

			// Prioritize the values that'd result in a smaller range
			if (result.getMinTime() - left->data.time > right->data.time - result.getMaxTime()) {
				left++;
				direction = 1;
				current = right;
			} else {
				right--;
				direction = -1;
				current = left;
			}

		// Not both directions are possible
		// Go to the direction that is possible
		} else if (left != begin) {
			direction = -1;
			current = --left;
		} else if (right != end) {
			direction = 1;
			current = ++right;
		}

		// Check if the interval size would still be below maxGroupInterval if the next element would be added
		// Abort if the interval size cannot be enlarged
		if (result.wouldInvalidateGroup(current)) {
			direction = 0;
		}

		if (direction != 0 && usedCamNos.count(current->data.camNo) == 0) {
			// Mark camNo as used and add to result
			usedCamNos.insert(current->data.camNo);
			result.add(current);

			// If no more other cameras available, abort
			if (result.getData().size() == camNos.size()) {
				direction = 0;
			}
		}
	} while (direction != 0);

	result.calculateValue();

	return result;
}

void SynchronousCameraQueue::cutOffQueue(std::list<Bucket>::iterator it)
{
	minimumPictureTime = it->data.time;

	std::list<Bucket> toDelete;
	toDelete.splice(toDelete.begin(), queue, queue.begin(), it);
	queue.pop_front();
}

void SynchronousCameraQueue::printQueue()
{
	ROS_DEBUG("Printing list");

	for (std::list<Bucket>::iterator it = queue.begin(); it != queue.end(); it++) {
		ROS_DEBUG("Cam %d, Copter %d: arrival %ld, snaptime %ld", it->data.camNo, it->data.quadcopterId, it->arrivalTime, it->data.time);
	}
}
<commit_msg>Uncommented warn output<commit_after>#include "SynchronousCameraQueue.hpp"

#include <ros/console.h>

#include "../../matlab/profiling.hpp"

SynchronousCameraQueue::SynchronousCameraQueue(long int arrivalDelay, long int maxDelay, long maxGroupInterval, bool ensureCam0)
{
	this->maxDelay = maxDelay;
	this->arrivalDelay = arrivalDelay;
	this->maxGroupInterval = maxGroupInterval;
	this->ensureCam0 = ensureCam0;
	lastArrivalTime = 0;
	minimumPictureTime = 0;

	ROS_INFO("SynchronousCameraQueue(): arrivalDelay = %.2fms, maxDelay = %.2fms, maxGroupInterval = %.2fms, ensureCam0 = %s", arrivalDelay / 1e6, maxDelay / 1e6, maxGroupInterval / 1e6, ensureCam0 ? "true" : "false");
}

size_t SynchronousCameraQueue::getSize()
{
	return queue.size();
}

bool SynchronousCameraQueue::dataAvailable()
{
	long int currentTime = getNanoTime();

	if (queue.size() == 0) {
		return false;
	}

	if (queue.size() >= camNos.size()) {
		return true;
	}

	for (std::list<Bucket>::reverse_iterator it = queue.rbegin(); it != queue.rend(); it++) {
		if (currentTime - it->arrivalTime > maxDelay) {
			return true;
		}

		if (currentTime - it->arrivalTime > arrivalDelay && queue.size() > 2) {
			return true;
		}
	}

	return false;
}

void SynchronousCameraQueue::enqueueInternal(CameraData data)
{
	// Make it impossible to insert data for a time earlier than the last dequeue() result
	if (data.time <= minimumPictureTime) {
		ROS_DEBUG("Dropped data from cam %d, copter %d because it was too old (time: %ld)", data.camNo, data.quadcopterId, data.time);
		return;
	} else {
		// ROS_DEBUG("Inserting data from cam %d, copter %d (time: %ld)", data.camNo, data.quadcopterId, data.time);
	}

	Bucket b;
	b.data = data;
	b.arrivalTime = getNanoTime();

	if (b.arrivalTime <= lastArrivalTime) {
		lastArrivalTime++;
		b.arrivalTime = lastArrivalTime;
	}

	std::list<Bucket> tmp;
	tmp.push_back(b);
	queue.merge(tmp);

	camNos.insert(data.camNo);
}

std::vector<CameraData> SynchronousCameraQueue::dequeue()
{
	long int currentTime = getNanoTime();

	Group result;

	for (std::list<Bucket>::iterator it = queue.begin(); it != queue.end(); it++) {
		Group tmp = searchGroup(it, currentTime, queue.begin(), --queue.end());

		if (tmp.isValid() && (!result.isValid() || tmp.getValue() > result.getValue())) {
			result = tmp;
		}
	}

	if (result.isValid()) {
		//printQueue();
		cutOffQueue(result.getYoungest());

		if (result.getData().size() < camNos.size()) {
			// TODO uncomment
			//ROS_WARN("Quadcopter %d is only seen by %ld cameras, but there are %ld entries in the queue", result.getData()[0].quadcopterId, result.getData().size(), queue.size());
		}

		return result.getData();
	} else {
		// Search for element which is older than maxDelay
		for (std::list<Bucket>::iterator it = queue.begin(); it != queue.end(); it++) {
			if (currentTime - it->arrivalTime > maxDelay) {
				// TODO uncomment
				//ROS_WARN("The only thing to return is old and probably invalid, but better than nothing so we return it anyways.");

				// element is overdue and nothing else was found, so return group, even if it's invalid.
				result = searchGroup(it, currentTime, queue.begin(), --queue.end());
				//printQueue();
				cutOffQueue(result.getYoungest());

				return result.getData();
			}
		}

		return std::vector<CameraData>();
	}
}

SynchronousCameraQueue::Group SynchronousCameraQueue::searchGroup(std::list<Bucket>::iterator it, long int currentTime, std::list<Bucket>::iterator begin, std::list<Bucket>::iterator end)
{
	Group result(it, currentTime, arrivalDelay, maxDelay, maxGroupInterval, camNos.size(), ensureCam0);

	std::set<int> usedCamNos;
	usedCamNos.insert(it->data.camNo);

	// The current rand of the search area
	std::list<Bucket>::iterator left = it;
	std::list<Bucket>::iterator right = it;

	// Temp iterator to reduce the amount of if/else
	std::list<Bucket>::iterator current = it;

	// Which side of the rand to go
	int direction = 0; // -1 left, 1 right, 0 terminate

	do {
		direction = 0;

		// Choose direction
		if (left != begin && right != end) {
			// Both directions are possible

			left--;
			right++;

			// Prioritize the values that'd result in a smaller range
			if (result.getMinTime() - left->data.time > right->data.time - result.getMaxTime()) {
				left++;
				direction = 1;
				current = right;
			} else {
				right--;
				direction = -1;
				current = left;
			}

		// Not both directions are possible
		// Go to the direction that is possible
		} else if (left != begin) {
			direction = -1;
			current = --left;
		} else if (right != end) {
			direction = 1;
			current = ++right;
		}

		// Check if the interval size would still be below maxGroupInterval if the next element would be added
		// Abort if the interval size cannot be enlarged
		if (result.wouldInvalidateGroup(current)) {
			direction = 0;
		}

		if (direction != 0 && usedCamNos.count(current->data.camNo) == 0) {
			// Mark camNo as used and add to result
			usedCamNos.insert(current->data.camNo);
			result.add(current);

			// If no more other cameras available, abort
			if (result.getData().size() == camNos.size()) {
				direction = 0;
			}
		}
	} while (direction != 0);

	result.calculateValue();

	return result;
}

void SynchronousCameraQueue::cutOffQueue(std::list<Bucket>::iterator it)
{
	minimumPictureTime = it->data.time;

	std::list<Bucket> toDelete;
	toDelete.splice(toDelete.begin(), queue, queue.begin(), it);
	queue.pop_front();
}

void SynchronousCameraQueue::printQueue()
{
	ROS_DEBUG("Printing list");

	for (std::list<Bucket>::iterator it = queue.begin(); it != queue.end(); it++) {
		ROS_DEBUG("Cam %d, Copter %d: arrival %ld, snaptime %ld", it->data.camNo, it->data.quadcopterId, it->arrivalTime, it->data.time);
	}
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_STORAGE_HPP_INCLUDE
#define TORRENT_STORAGE_HPP_INCLUDE

#include <vector>
#include <bitset>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/limits.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/torrent_info.hpp"
#include "libtorrent/config.hpp"

namespace libtorrent
{
	namespace detail
	{
		struct piece_checker_data;
	}

	class session;

	TORRENT_EXPORT std::wstring safe_convert(std::string const& s);

	TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes(
		torrent_info const& t
		, boost::filesystem::path p);

	TORRENT_EXPORT bool match_filesizes(
		torrent_info const& t
		, boost::filesystem::path p
		, std::vector<std::pair<size_type, std::time_t> > const& sizes
		, std::string* error = 0);

	struct TORRENT_EXPORT file_allocation_failed: std::exception
	{
		file_allocation_failed(const char* error_msg): m_msg(error_msg) {}
		virtual const char* what() const throw() { return m_msg.c_str(); }
		virtual ~file_allocation_failed() throw() {}
		std::string m_msg;
	};

	class TORRENT_EXPORT storage
	{
	public:
		storage(
			const torrent_info& info
		  , const boost::filesystem::path& path);

		void swap(storage&);

		// may throw file_error if storage for slot does not exist
		size_type read(char* buf, int slot, int offset, int size);

		// may throw file_error if storage for slot hasn't been allocated
		void write(const char* buf, int slot, int offset, int size);

		bool move_storage(boost::filesystem::path save_path);

		// this will close all open files that are opened for
		// writing. This is called when a torrent has finished
		// downloading.
		void release_files();

#ifndef NDEBUG
		// overwrites some slots with the
		// contents of others
		void storage::shuffle();
#endif

	private:
		class impl;
		boost::shared_ptr<impl> m_pimpl;
	};

	class TORRENT_EXPORT piece_manager : boost::noncopyable
	{
	public:

		piece_manager(
			const torrent_info& info
			, const boost::filesystem::path& path);

		~piece_manager();

		bool check_fastresume(detail::piece_checker_data& d
			, std::vector<bool>& pieces, bool compact_mode);
		std::pair<bool, float> check_files(std::vector<bool>& pieces);

		void release_files();

		bool is_allocating() const;
		void allocate_slots(int num_slots);
		void mark_failed(int index);

		unsigned long piece_crc(
			int slot_index
			, int block_size
			, const std::bitset<256>& bitmask);
		int slot_for_piece(int piece_index) const;

		size_type read(
			char* buf
			, int piece_index
			, int offset
			, int size);

		void write(
			const char* buf
			, int piece_index
			, int offset
			, int size);

		boost::filesystem::path const& save_path() const;
		bool move_storage(boost::filesystem::path const&);

		// fills the vector that maps all allocated
		// slots to the piece that is stored (or
		// partially stored) there. -2 is the index
		// of unassigned pieces and -1 is unallocated
		void export_piece_map(std::vector<int>& pieces) const;

	private:
		class impl;
		std::auto_ptr<impl> m_pimpl;
	};

}

#endif // TORRENT_STORAGE_HPP_INCLUDED

<commit_msg>fixed syntax error found by gcc 4.1<commit_after>/*

Copyright (c) 2003, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_STORAGE_HPP_INCLUDE
#define TORRENT_STORAGE_HPP_INCLUDE

#include <vector>
#include <bitset>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/limits.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/torrent_info.hpp"
#include "libtorrent/config.hpp"

namespace libtorrent
{
	namespace detail
	{
		struct piece_checker_data;
	}

	class session;

	TORRENT_EXPORT std::wstring safe_convert(std::string const& s);

	TORRENT_EXPORT std::vector<std::pair<size_type, std::time_t> > get_filesizes(
		torrent_info const& t
		, boost::filesystem::path p);

	TORRENT_EXPORT bool match_filesizes(
		torrent_info const& t
		, boost::filesystem::path p
		, std::vector<std::pair<size_type, std::time_t> > const& sizes
		, std::string* error = 0);

	struct TORRENT_EXPORT file_allocation_failed: std::exception
	{
		file_allocation_failed(const char* error_msg): m_msg(error_msg) {}
		virtual const char* what() const throw() { return m_msg.c_str(); }
		virtual ~file_allocation_failed() throw() {}
		std::string m_msg;
	};

	class TORRENT_EXPORT storage
	{
	public:
		storage(
			const torrent_info& info
		  , const boost::filesystem::path& path);

		void swap(storage&);

		// may throw file_error if storage for slot does not exist
		size_type read(char* buf, int slot, int offset, int size);

		// may throw file_error if storage for slot hasn't been allocated
		void write(const char* buf, int slot, int offset, int size);

		bool move_storage(boost::filesystem::path save_path);

		// this will close all open files that are opened for
		// writing. This is called when a torrent has finished
		// downloading.
		void release_files();

#ifndef NDEBUG
		// overwrites some slots with the
		// contents of others
		void shuffle();
#endif

	private:
		class impl;
		boost::shared_ptr<impl> m_pimpl;
	};

	class TORRENT_EXPORT piece_manager : boost::noncopyable
	{
	public:

		piece_manager(
			const torrent_info& info
			, const boost::filesystem::path& path);

		~piece_manager();

		bool check_fastresume(detail::piece_checker_data& d
			, std::vector<bool>& pieces, bool compact_mode);
		std::pair<bool, float> check_files(std::vector<bool>& pieces);

		void release_files();

		bool is_allocating() const;
		void allocate_slots(int num_slots);
		void mark_failed(int index);

		unsigned long piece_crc(
			int slot_index
			, int block_size
			, const std::bitset<256>& bitmask);
		int slot_for_piece(int piece_index) const;

		size_type read(
			char* buf
			, int piece_index
			, int offset
			, int size);

		void write(
			const char* buf
			, int piece_index
			, int offset
			, int size);

		boost::filesystem::path const& save_path() const;
		bool move_storage(boost::filesystem::path const&);

		// fills the vector that maps all allocated
		// slots to the piece that is stored (or
		// partially stored) there. -2 is the index
		// of unassigned pieces and -1 is unallocated
		void export_piece_map(std::vector<int>& pieces) const;

	private:
		class impl;
		std::auto_ptr<impl> m_pimpl;
	};

}

#endif // TORRENT_STORAGE_HPP_INCLUDED

<|endoftext|>


<commit_before>//============================================================================
// include/vsmc/core/particle.hpp
//----------------------------------------------------------------------------
//
//                         vSMC: Scalable Monte Carlo
//
// This file is distribured under the 2-clauses BSD License.
// See LICENSE for details.
//============================================================================

#ifndef VSMC_CORE_PARTICLE_HPP
#define VSMC_CORE_PARTICLE_HPP

#include <vsmc/core/single_particle.hpp>
#include <vsmc/core/weight_set.hpp>
#include <vsmc/cxx11/functional.hpp>
#include <vsmc/resample/basic.hpp>
#include <vsmc/rng/rng_set.hpp>
#include <vsmc/rng/seed.hpp>
#include <limits>
#include <utility>

namespace vsmc {

/// \brief Particle class representing the whole particle set
/// \ingroup Core
template <typename T>
class Particle
{
    public :

    typedef typename traits::SizeTypeTrait<T>::type size_type;
    typedef T value_type;
    typedef typename traits::WeightSetTypeTrait<T>::type weight_set_type;
    typedef typename traits::RngSetTypeTrait<T>::type rng_set_type;
    typedef typename traits::ResampleRngTypeTrait<T>::type resample_rng_type;
    typedef typename rng_set_type::rng_type rng_type;

    typedef cxx11::function<void (std::size_t, std::size_t,
            resample_rng_type &, const double *, size_type *)> resample_type;
    typedef typename traits::ResampleCopyFromReplicationTypeTrait<T>::type
        resample_copy_from_replication_type;
    typedef typename traits::ResamplePostCopyTypeTrait<T>::type
        resample_post_copy_type;

    explicit Particle (size_type N) :
        size_(N), value_(N),
        weight_set_(static_cast<typename
                traits::SizeTypeTrait<weight_set_type>::type>(N)),
        rng_set_(static_cast<typename
                traits::SizeTypeTrait<rng_set_type>::type>(N)),
        resample_rng_(Seed::instance().get()) {}

    /// \brief Clone the particle system except the RNG engines
    ///
    /// \param new_rng If true, the new particle system has new-seeded RNG.
    /// Otherwise false, it is exactly the same as the current.
    Particle<T> clone (bool new_rng) const
    {
        Particle<T> particle(*this);
        if (new_rng) {
            particle.rng_set().seed();
            particle.resample_rng().seed(Seed::instance().get());
        }

        return particle;
    }

    /// \brief Clone another particle system except the RNG engines
    ///
    /// \param other The particle system to be cloned
    /// \param retain_rng If true, retain the current system's RNG. Otherwise,
    /// it is exactly the same as the new one.
    Particle<T> &clone (const Particle<T> &other, bool retain_rng)
    {
        if (this != &other) {
            if (retain_rng) {
#if VSMC_HAS_CXX11_RVALUE_REFERENCES
                rng_set_type rset(cxx11::move(rng_set_));
                resample_rng_type rrng(cxx11::move(resample_rng_));
                *this = other;
                rng_set_ = cxx11::move(rset);
                resample_rng_ = cxx11::move(rrng);
#else
                using std::swap;

                rng_set_type rset(0);
                swap(rset, rng_set_);
                resample_rng_type rrng(resample_rng_);
                *this = other;
                swap(rset, rng_set_);
                resample_rng_ = rrng;
#endif
                rng_set_.resize(other.size());
            } else {
                *this = other;
            }
        }

        return *this;
    }

#if VSMC_HAS_CXX11_RVALUE_REFERENCES
    Particle<T> &clone (Particle<T> &&other, bool retain_rng)
    {
        if (this != &other) {
            if (retain_rng) {
                rng_set_type rset(cxx11::move(rng_set_));
                resample_rng_type rrng(cxx11::move(resample_rng_));
                *this = cxx11::move(other);
                rng_set_ = cxx11::move(rset);
                resample_rng_ = cxx11::move(rrng);
                rng_set_.resize(other.size());
            } else {
                *this = cxx11::move(other);
            }
        }

        return *this;
    }
#endif

    /// \brief Number of particles
    size_type size () const {return size_;}

    /// \brief Read and write access to the value collection object
    value_type &value () {return value_;}

    /// \brief Read only access to the value collection object
    const value_type &value () const {return value_;}

    /// \brief Read and write access to the weight collection object
    weight_set_type &weight_set () {return weight_set_;}

    /// \brief Read only access to the weight collection object
    const weight_set_type &weight_set () const {return weight_set_;}

    /// \brief Read and write access to the RNG collection object
    rng_set_type &rng_set () {return rng_set_;}

    /// \brief Read only access to the RNG collection object
    const rng_set_type &rng_set () const {return rng_set_;}

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS
    /// such that each particle has a equal weight
    void set_equal_weight () {weight_set_.set_equal_weight();}

    /// \brief Read normalized weights through an output iterator
    template <typename OutputIter>
    OutputIter read_weight (OutputIter first) const
    {return weight_set_.read_weight(first);}

    /// \brief Get the ESS of the particle collection based on the current
    /// weights
    double ess () const {return weight_set_.ess();}

    /// \brief Get an (parallel) RNG stream for a given particle
    rng_type &rng (size_type id) {return rng_set_[id];}

    /// \brief Get the (sequential) RNG used stream for resampling
    resample_rng_type &resample_rng () {return resample_rng_;}

    /// \brief Performing resampling if ESS/N < threshold
    ///
    /// \param op The resampling operation funcitor
    /// \param threshold The threshold of ESS/N below which resampling will be
    /// performed
    ///
    /// \return true if resampling was performed
    ///
    /// \details
    /// The out of box behavior are suitable for most applications. However,
    /// the user can also gain full control over the internal of this
    /// function by changing the `weight_set_type` and other type traits for
    /// specific value collection type. The sequence of operations of this
    /// function is listed as in the following pseudo-code
    /// 1. Determine if resampling is required
    ///     * Set `N = weight_set.resample_size()`
    ///     * Set `resampled = weight_set.ess() < threshold * N`
    ///     * If `!resampled`, GO TO Step 8. Otherwise, GO TO Step 2
    /// 2. Determine if resampling algorithms shall be performed. This is only
    /// useful for MPI implementations. the boolean value `resampled` ensures
    /// that collective actions like `copy` will be called by all nodes.
    /// However, the resampling replication numbers can be computed by one
    /// node instead of by all. Therefore, the program can actually collect and
    /// read the resampling weights on one node, and do nothing on other nodes.
    /// This difference shall be reflected by the returning iterator of
    /// `read_resample_weight`
    ///     * (Allocate `double *weight` for size `N`)
    ///     * Set `double *end = weight_set.read_resample_weight(weight)`
    ///     * If `end != weight + N`, GO TO step 5. Otherwise, GO TO Step 3
    /// 3. Performing resampling, produce replication number of each particle
    ///     * (Allocate `size_type *replication` for size `N`)
    ///     * (Create RNG engine `resample_rng` according to
    ///     traits::ResampleRngTypeTrait)
    ///     * Call `op(N, resample_rng, weight, replication)`
    /// 4. Transform replication numbers into parent particle indices
    ///     * (Allocat `size_type *copy_from` for size `N`)
    ///     * (Create functor `r2c` according to
    ///     traits::ResampleCopyFromReplicationTypeTrait)
    ///     * Call `r2c(N, replication, copy_from)`
    /// 5. Set `const size_type *cptr` according to results of Step 2.
    ///     * If Step 3 and 4 are skipped according to Step 2, then set
    ///     `cptr = 0`. Otherwise,
    ///     * Set `cptr = copy_from`
    /// 6. Performing copying of particles
    ///     * Call `value.copy(N, cptr)`
    /// 7. Performing post resampling weight manipulation
    ///     * (Create functor `post` according to
    ///     traits::ResamplePostCopyTypeTrait)
    ///     * `post(weight_set)`
    /// 8. `return resampled`
    bool resample (const resample_type &op, double threshold)
    {
        std::size_t N = static_cast<std::size_t>(weight_set_.resample_size());
        bool resampled = weight_set_.ess() < threshold * N;
        if (resampled) {
            resample_copy_from_.resize(N);
            resample_replication_.resize(N);
            resample_weight_.resize(N);
            double *end = weight_set_.read_resample_weight(
                    &resample_weight_[0]);
            const size_type *cptr = VSMC_NULLPTR;
            if (end == &resample_weight_[0] + N) {
                op(N, N, resample_rng_, &resample_weight_[0],
                        &resample_replication_[0]);
                resample_copy_from_replication_(N, N,
                        &resample_replication_[0], &resample_copy_from_[0]);
                cptr = &resample_copy_from_[0];
            }
            value_.copy(N, cptr);
            resample_post_copy_(weight_set_);
        }

        return resampled;
    }

    private :

    size_type size_;
    value_type value_;
    weight_set_type weight_set_;
    rng_set_type rng_set_;
    resample_rng_type resample_rng_;

    std::vector<size_type> resample_copy_from_;
    std::vector<size_type> resample_replication_;
    std::vector<double> resample_weight_;
    resample_copy_from_replication_type resample_copy_from_replication_;
    resample_post_copy_type resample_post_copy_;
}; // class Particle

} // namespace vsmc

#endif // VSMC_CORE_PARTICLE_HPP
<commit_msg>resample no longer copy weight<commit_after>//============================================================================
// include/vsmc/core/particle.hpp
//----------------------------------------------------------------------------
//
//                         vSMC: Scalable Monte Carlo
//
// This file is distribured under the 2-clauses BSD License.
// See LICENSE for details.
//============================================================================

#ifndef VSMC_CORE_PARTICLE_HPP
#define VSMC_CORE_PARTICLE_HPP

#include <vsmc/core/single_particle.hpp>
#include <vsmc/core/weight_set.hpp>
#include <vsmc/cxx11/functional.hpp>
#include <vsmc/resample/basic.hpp>
#include <vsmc/rng/rng_set.hpp>
#include <vsmc/rng/seed.hpp>
#include <limits>
#include <utility>

namespace vsmc {

/// \brief Particle class representing the whole particle set
/// \ingroup Core
template <typename T>
class Particle
{
    public :

    typedef typename traits::SizeTypeTrait<T>::type size_type;
    typedef T value_type;
    typedef typename traits::WeightSetTypeTrait<T>::type weight_set_type;
    typedef typename traits::RngSetTypeTrait<T>::type rng_set_type;
    typedef typename traits::ResampleRngTypeTrait<T>::type resample_rng_type;
    typedef typename rng_set_type::rng_type rng_type;

    typedef cxx11::function<void (std::size_t, std::size_t,
            resample_rng_type &, const double *, size_type *)> resample_type;
    typedef typename traits::ResampleCopyFromReplicationTypeTrait<T>::type
        resample_copy_from_replication_type;
    typedef typename traits::ResamplePostCopyTypeTrait<T>::type
        resample_post_copy_type;

    explicit Particle (size_type N) :
        size_(N), value_(N),
        weight_set_(static_cast<typename
                traits::SizeTypeTrait<weight_set_type>::type>(N)),
        rng_set_(static_cast<typename
                traits::SizeTypeTrait<rng_set_type>::type>(N)),
        resample_rng_(Seed::instance().get()) {}

    /// \brief Clone the particle system except the RNG engines
    ///
    /// \param new_rng If true, the new particle system has new-seeded RNG.
    /// Otherwise false, it is exactly the same as the current.
    Particle<T> clone (bool new_rng) const
    {
        Particle<T> particle(*this);
        if (new_rng) {
            particle.rng_set().seed();
            particle.resample_rng().seed(Seed::instance().get());
        }

        return particle;
    }

    /// \brief Clone another particle system except the RNG engines
    ///
    /// \param other The particle system to be cloned
    /// \param retain_rng If true, retain the current system's RNG. Otherwise,
    /// it is exactly the same as the new one.
    Particle<T> &clone (const Particle<T> &other, bool retain_rng)
    {
        if (this != &other) {
            if (retain_rng) {
#if VSMC_HAS_CXX11_RVALUE_REFERENCES
                rng_set_type rset(cxx11::move(rng_set_));
                resample_rng_type rrng(cxx11::move(resample_rng_));
                *this = other;
                rng_set_ = cxx11::move(rset);
                resample_rng_ = cxx11::move(rrng);
#else
                using std::swap;

                rng_set_type rset(0);
                swap(rset, rng_set_);
                resample_rng_type rrng(resample_rng_);
                *this = other;
                swap(rset, rng_set_);
                resample_rng_ = rrng;
#endif
                rng_set_.resize(other.size());
            } else {
                *this = other;
            }
        }

        return *this;
    }

#if VSMC_HAS_CXX11_RVALUE_REFERENCES
    Particle<T> &clone (Particle<T> &&other, bool retain_rng)
    {
        if (this != &other) {
            if (retain_rng) {
                rng_set_type rset(cxx11::move(rng_set_));
                resample_rng_type rrng(cxx11::move(resample_rng_));
                *this = cxx11::move(other);
                rng_set_ = cxx11::move(rset);
                resample_rng_ = cxx11::move(rrng);
                rng_set_.resize(other.size());
            } else {
                *this = cxx11::move(other);
            }
        }

        return *this;
    }
#endif

    /// \brief Number of particles
    size_type size () const {return size_;}

    /// \brief Read and write access to the value collection object
    value_type &value () {return value_;}

    /// \brief Read only access to the value collection object
    const value_type &value () const {return value_;}

    /// \brief Read and write access to the weight collection object
    weight_set_type &weight_set () {return weight_set_;}

    /// \brief Read only access to the weight collection object
    const weight_set_type &weight_set () const {return weight_set_;}

    /// \brief Read and write access to the RNG collection object
    rng_set_type &rng_set () {return rng_set_;}

    /// \brief Read only access to the RNG collection object
    const rng_set_type &rng_set () const {return rng_set_;}

    /// \brief Set normalized weight, unnormalized logarithm weight and ESS
    /// such that each particle has a equal weight
    void set_equal_weight () {weight_set_.set_equal_weight();}

    /// \brief Read normalized weights through an output iterator
    template <typename OutputIter>
    OutputIter read_weight (OutputIter first) const
    {return weight_set_.read_weight(first);}

    /// \brief Get the ESS of the particle collection based on the current
    /// weights
    double ess () const {return weight_set_.ess();}

    /// \brief Get an (parallel) RNG stream for a given particle
    rng_type &rng (size_type id) {return rng_set_[id];}

    /// \brief Get the (sequential) RNG used stream for resampling
    resample_rng_type &resample_rng () {return resample_rng_;}

    /// \brief Performing resampling if ESS/N < threshold
    ///
    /// \param op The resampling operation funcitor
    /// \param threshold The threshold of ESS/N below which resampling will be
    /// performed
    ///
    /// \return true if resampling was performed
    ///
    /// \details
    /// The out of box behavior are suitable for most applications. However,
    /// the user can also gain full control over the internal of this
    /// function by changing the `weight_set_type` and other type traits for
    /// specific value collection type. The sequence of operations of this
    /// function is listed as in the following pseudo-code
    /// 1. Determine if resampling is required
    ///     * Set `N = weight_set.resample_size()`
    ///     * Set `resampled = weight_set.ess() < threshold * N`
    ///     * If `!resampled`, GO TO Step 8. Otherwise, GO TO Step 2
    /// 2. Determine if resampling algorithms shall be performed. This is only
    /// useful for MPI implementations. the boolean value `resampled` ensures
    /// that collective actions like `copy` will be called by all nodes.
    /// However, the resampling replication numbers can be computed by one
    /// node instead of by all. Therefore, the program can actually collect and
    /// read the resampling weights on one node, and do nothing on other nodes.
    /// This difference shall be reflected by the returning iterator of
    /// `read_resample_weight`
    ///     * (Allocate `double *weight` for size `N`)
    ///     * Set `double *end = weight_set.read_resample_weight(weight)`
    ///     * If `end != weight + N`, GO TO step 5. Otherwise, GO TO Step 3
    /// 3. Performing resampling, produce replication number of each particle
    ///     * (Allocate `size_type *replication` for size `N`)
    ///     * (Create RNG engine `resample_rng` according to
    ///     traits::ResampleRngTypeTrait)
    ///     * Call `op(N, resample_rng, weight, replication)`
    /// 4. Transform replication numbers into parent particle indices
    ///     * (Allocat `size_type *copy_from` for size `N`)
    ///     * (Create functor `r2c` according to
    ///     traits::ResampleCopyFromReplicationTypeTrait)
    ///     * Call `r2c(N, replication, copy_from)`
    /// 5. Set `const size_type *cptr` according to results of Step 2.
    ///     * If Step 3 and 4 are skipped according to Step 2, then set
    ///     `cptr = 0`. Otherwise,
    ///     * Set `cptr = copy_from`
    /// 6. Performing copying of particles
    ///     * Call `value.copy(N, cptr)`
    /// 7. Performing post resampling weight manipulation
    ///     * (Create functor `post` according to
    ///     traits::ResamplePostCopyTypeTrait)
    ///     * `post(weight_set)`
    /// 8. `return resampled`
    bool resample (const resample_type &op, double threshold)
    {
        std::size_t N = static_cast<std::size_t>(weight_set_.resample_size());
        bool resampled = weight_set_.ess() < threshold * N;
        if (resampled) {
            size_type *cptr = VSMC_NULLPTR;
            const double *wptr = weight_set_.resample_weight_data();
            if (wptr != VSMC_NULLPTR) {
                resample_copy_from_.resize(N);
                resample_replication_.resize(N);
                cptr = &resample_copy_from_[0];
                size_type *rptr = &resample_replication_[0];
                op(N, N, resample_rng_, wptr, rptr);
                resample_copy_from_replication_(N, N, rptr, cptr);
            }
            value_.copy(N, cptr);
            resample_post_copy_(weight_set_);
        }

        return resampled;
    }

    private :

    size_type size_;
    value_type value_;
    weight_set_type weight_set_;
    rng_set_type rng_set_;
    resample_rng_type resample_rng_;

    std::vector<size_type> resample_copy_from_;
    std::vector<size_type> resample_replication_;
    resample_copy_from_replication_type resample_copy_from_replication_;
    resample_post_copy_type resample_post_copy_;
}; // class Particle

} // namespace vsmc

#endif // VSMC_CORE_PARTICLE_HPP
<|endoftext|>


<commit_before>#pragma once

namespace xv{

/*!
 * \brief Class used to convert between image formats
 */
class ImageTranslator
{
public:
	ImageTranslator();
	virtual ~ImageTranslator();
};

}<commit_msg>Added ImageTranslator to module<commit_after>#pragma once

namespace xv{

/*!
 * \brief Class used to convert between image formats
 * \ingroup ImageRepresentation
 */
class ImageTranslator
{
public:
	ImageTranslator();
	virtual ~ImageTranslator();
};

}<|endoftext|>


<commit_before>#include "sitkExtractImageFilter.h"
#include "sitkMacro.h"

#include "itkVectorImage.h"

namespace itk {
namespace simple {

//----------------------------------------------------------------------------

//
// Default constructor that initializes parameters
//
ExtractImageFilter::ExtractImageFilter ()
  {
  this->m_Slice = 0;
  this->m_MemberFactory.reset( new detail::MemberFunctionFactory<MemberFunctionType>( this ) );
  this->m_MemberFactory->RegisterMemberFunctions< PixelIDTypeList, 3 > ();
  }

//
// ToString
//
std::string ExtractImageFilter::ToString() const
  {
  std::ostringstream out;
  out << "itk::simple::ExtractImageFilter\n"
      << "\tSlice: " << this->m_Slice << "\n";
  return out.str();
  }

  Image* ExtractImageFilter::Execute ( Image* image, size_t s )
  {
  this->m_Slice = s;
  return Execute ( image );
  }

//
// Execute
//
Image* ExtractImageFilter::Execute ( Image* image )
  {

    PixelIDValueType type = image->GetPixelIDValue();
    unsigned int dimension = image->GetDimension();
    if ( dimension != 3 ) {
      sitkExceptionMacro ( << "ExtractImageFilter operates on 3 dimensional images only" );
    }
    return this->m_MemberFactory->GetMemberFunction( type, dimension )( image );
  }

//----------------------------------------------------------------------------

//
// ExecuteInternal
//
template <class TImageType>
Image* ExtractImageFilter::ExecuteInternal ( Image* inImage )
  {
  typename TImageType::Pointer image =
    dynamic_cast <TImageType*> ( inImage->GetImageBase().GetPointer() );

  if ( image.IsNull() )
    {
    sitkExceptionMacro( << "Could not cast input image to proper type" );
    }

  typedef itk::ExtractImageFilter<TImageType, TImageType> FilterType;
  typename FilterType::Pointer filter = FilterType::New();

  filter->SetInput ( image );

  typename TImageType::IndexType index;
  typename TImageType::SizeType size;
  index.Fill ( 0 );
  index[2] = this->m_Slice;
  size = image->GetLargestPossibleRegion().GetSize();
  size[2] = 1;
  typename TImageType::RegionType region ( index, size );

  filter->SetExtractionRegion ( region );

  filter->Update();
  typename TImageType::Pointer filterOutput = filter->GetOutput();

  // Make the index 0,0,0
  index.Fill ( 0 );
  region.SetIndex ( index );
  filterOutput->SetRegions ( region );
  Image* out = new Image( filterOutput );

  filterOutput->DisconnectPipeline();
  return out;
  }

} // end namespace simple
} // end namespace itk
<commit_msg>ENH: Specified collapse model<commit_after>#include "sitkExtractImageFilter.h"
#include "sitkMacro.h"

#include "itkVectorImage.h"

namespace itk {
namespace simple {

//----------------------------------------------------------------------------

//
// Default constructor that initializes parameters
//
ExtractImageFilter::ExtractImageFilter ()
  {
  this->m_Slice = 0;
  this->m_MemberFactory.reset( new detail::MemberFunctionFactory<MemberFunctionType>( this ) );
  this->m_MemberFactory->RegisterMemberFunctions< PixelIDTypeList, 3 > ();
  }

//
// ToString
//
std::string ExtractImageFilter::ToString() const
  {
  std::ostringstream out;
  out << "itk::simple::ExtractImageFilter\n"
      << "\tSlice: " << this->m_Slice << "\n";
  return out.str();
  }

  Image* ExtractImageFilter::Execute ( Image* image, size_t s )
  {
  this->m_Slice = s;
  return Execute ( image );
  }

//
// Execute
//
Image* ExtractImageFilter::Execute ( Image* image )
  {

    PixelIDValueType type = image->GetPixelIDValue();
    unsigned int dimension = image->GetDimension();
    if ( dimension != 3 ) {
      sitkExceptionMacro ( << "ExtractImageFilter operates on 3 dimensional images only" );
    }
    return this->m_MemberFactory->GetMemberFunction( type, dimension )( image );
  }

//----------------------------------------------------------------------------

//
// ExecuteInternal
//
template <class TImageType>
Image* ExtractImageFilter::ExecuteInternal ( Image* inImage )
  {
  typename TImageType::Pointer image =
    dynamic_cast <TImageType*> ( inImage->GetImageBase().GetPointer() );

  if ( image.IsNull() )
    {
    sitkExceptionMacro( << "Could not cast input image to proper type" );
    }

  typedef itk::ExtractImageFilter<TImageType, TImageType> FilterType;
  typename FilterType::Pointer filter = FilterType::New();

  filter->SetInput ( image );

  typename TImageType::IndexType index;
  typename TImageType::SizeType size;
  index.Fill ( 0 );
  index[2] = this->m_Slice;
  size = image->GetLargestPossibleRegion().GetSize();
  size[2] = 1;
  typename TImageType::RegionType region ( index, size );

  filter->SetDirectionCollapseToSubmatrix();
  filter->SetExtractionRegion ( region );

  filter->Update();
  typename TImageType::Pointer filterOutput = filter->GetOutput();

  // Make the index 0,0,0
  index.Fill ( 0 );
  region.SetIndex ( index );
  filterOutput->SetRegions ( region );
  Image* out = new Image( filterOutput );

  filterOutput->DisconnectPipeline();
  return out;
  }

} // end namespace simple
} // end namespace itk
<|endoftext|>


<commit_before>//
//  Copyright (C) 2015 Greg Landrum
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#define PY_ARRAY_UNIQUE_SYMBOL rdmoldraw2d_array_API
#include <boost/python.hpp>
#include <GraphMol/ROMol.h>
#include <RDBoost/Wrap.h>
#include <GraphMol/MolDraw2D/MolDraw2D.h>
#include <GraphMol/MolDraw2D/MolDraw2DSVG.h>
#include <Geometry/point.h>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#ifdef RDK_CAIRO_BUILD
#include <cairo.h>
#include <GraphMol/MolDraw2D/MolDraw2DCairo.h>
#endif

namespace python = boost::python;

namespace RDKit {
  namespace {
    std::map<int,DrawColour> *pyDictToColourMap(python::object pyo){
      std::map<int,DrawColour> *res=NULL;
      if(pyo){
        res = new std::map<int,DrawColour>;
        python::dict tDict = python::extract<python::dict>(pyo);
        for(unsigned int i=0;i<python::extract<unsigned int>(tDict.keys().attr("__len__")());++i){
          python::tuple tpl=python::extract<python::tuple>(tDict.values()[i]);
          float r=python::extract<float>(tpl[0]);
          float g=python::extract<float>(tpl[1]);
          float b=python::extract<float>(tpl[2]);
          DrawColour clr(r,g,b);
          (*res)[python::extract<int>(tDict.keys()[i])]=clr;
        }
      }
      return res;
    }
    std::map<int,double> *pyDictToDoubleMap(python::object pyo){
      std::map<int,double> *res=NULL;
      if(pyo){
        res = new std::map<int,double>;
        python::dict tDict = python::extract<python::dict>(pyo);
        for(unsigned int i=0;i<python::extract<unsigned int>(tDict.keys().attr("__len__")());++i){
          double r = python::extract<double>(tDict.values()[i]);
          (*res)[python::extract<int>(tDict.keys()[i])]=r;
        }
      }
      return res;
    }
  }
  void drawMoleculeHelper1(MolDraw2D &self,
                          const ROMol &mol ,
                          python::object highlight_atoms,
                          python::object highlight_atom_map,
                          python::object highlight_atom_radii,
                          int confId=-1){
    std::vector<int> *highlightAtoms=pythonObjectToVect(highlight_atoms,static_cast<int>(mol.getNumAtoms()));
    std::map<int,DrawColour> *ham=pyDictToColourMap(highlight_atom_map);
    std::map<int,double> *har=pyDictToDoubleMap(highlight_atom_radii);

    self.drawMolecule(mol,highlightAtoms,ham,har,confId);

    delete highlightAtoms;
    delete ham;
    delete har;
  }
  void drawMoleculeHelper2(MolDraw2D &self,
                          const ROMol &mol ,
                          python::object highlight_atoms,
                          python::object highlight_bonds,
                          python::object highlight_atom_map,
                          python::object highlight_bond_map,
                          python::object highlight_atom_radii,
                          int confId=-1){
    std::vector<int> *highlightAtoms=pythonObjectToVect(highlight_atoms,static_cast<int>(mol.getNumAtoms()));
    std::vector<int> *highlightBonds=pythonObjectToVect(highlight_bonds,static_cast<int>(mol.getNumBonds()));
    // FIX: support these
    std::map<int,DrawColour> *ham=pyDictToColourMap(highlight_atom_map);
    std::map<int,DrawColour> *hbm=pyDictToColourMap(highlight_bond_map);
    std::map<int,double> *har=pyDictToDoubleMap(highlight_atom_radii);

    self.drawMolecule(mol,highlightAtoms,highlightBonds,ham,hbm,har,confId);

    delete highlightAtoms;
    delete highlightBonds;
    delete ham;
    delete hbm;
    delete har;
  }

#ifdef RDK_CAIRO_BUILD
  python::object getCairoDrawingText(const RDKit::MolDraw2DCairo &self){
    std::string res=self.getDrawingText();
    python::object retval = python::object(python::handle<>(PyBytes_FromStringAndSize(res.c_str(),res.length())));
    return retval;
  }
#endif

}

BOOST_PYTHON_MODULE(rdMolDraw2D) {

  python::scope().attr("__doc__") =
    "Module containing a C++ implementation of 2D molecule drawing";

  std::string docString;

  python::class_<std::map<int,std::string> >("IntStringMap")
    .def(python::map_indexing_suite<std::map<int,std::string>, true >())
    ;

  docString="Drawing options";
  python::class_<RDKit::MolDrawOptions,boost::noncopyable>("MolDrawOptions",docString.c_str())
    .def_readwrite("dummiesAreAttachments",&RDKit::MolDrawOptions::dummiesAreAttachments)
    .def_readwrite("circleAtoms",&RDKit::MolDrawOptions::circleAtoms)
    //.def_readwrite("highlightColour",&RDKit::MolDrawOptions::highlightColour)
    .def_readwrite("atomLabels",&RDKit::MolDrawOptions::atomLabels,"maps indices to atom labels")
    .def_readwrite("continuousHighlight",&RDKit::MolDrawOptions::continuousHighlight)
    .def_readwrite("flagCloseContactsDist",&RDKit::MolDrawOptions::flagCloseContactsDist)
    .def_readwrite("atomRegions",&RDKit::MolDrawOptions::atomRegions,"regions to outline")
    .def_readwrite("includeAtomTags",&RDKit::MolDrawOptions::includeAtomTags,"include atom tags in output")

    ;
  docString="Drawer abstract base class";
  python::class_<RDKit::MolDraw2D,boost::noncopyable>("MolDraw2D",docString.c_str(),python::no_init)
    .def("DrawMolecule",RDKit::drawMoleculeHelper1,
         (python::arg("self"),python::arg("mol"),
          python::arg("highlightAtoms")=python::object(),
          python::arg("highlightAtomColors")=python::object(),
          python::arg("highlightAtomRadii")=python::object(),
          python::arg("confId")=-1
          ),
         "renders a molecule\n")
    .def("DrawMolecule",RDKit::drawMoleculeHelper2,
         (python::arg("self"),python::arg("mol"),
          python::arg("highlightAtoms"),
          python::arg("highlightBonds"),
          python::arg("highlightAtomColors")=python::object(),
          python::arg("highlightBondColors")=python::object(),
          python::arg("highlightAtomRadii")=python::object(),
          python::arg("confId")=-1
          ),
         "renders a molecule\n")
    .def("drawOptions",(RDKit::MolDrawOptions &(RDKit::MolDraw2D::*)())&RDKit::MolDraw2D::drawOptions,
         python::return_internal_reference<1,
         python::with_custodian_and_ward_postcall<0,1> >(),
         "Returns a modifiable version of the current drawing options"
         )
    ;
  docString="SVG molecule drawer";
  python::class_<RDKit::MolDraw2DSVG, python::bases<RDKit::MolDraw2D>, boost::noncopyable >("MolDraw2DSVG",docString.c_str(),
                                                                                python::init<int,int>())
    .def("FinishDrawing",&RDKit::MolDraw2DSVG::finishDrawing,
         "add the last bits of SVG to finish the drawing")
    .def("GetDrawingText",&RDKit::MolDraw2DSVG::getDrawingText,
         "return the SVG")
    ;

#ifdef RDK_CAIRO_BUILD
  docString="Cairo molecule drawer";
  python::class_<RDKit::MolDraw2DCairo, python::bases<RDKit::MolDraw2D>, boost::noncopyable >("MolDraw2DCairo",
                                                                                docString.c_str(),
                                                                                python::init<int,int>())
    .def("FinishDrawing",&RDKit::MolDraw2DCairo::finishDrawing,
         "add the last bits to finish the drawing")
    .def("GetDrawingText",&RDKit::getCairoDrawingText,
         "return the PNG data as a string")
    .def("WriteDrawingText",&RDKit::MolDraw2DCairo::writeDrawingText,
         "write the PNG data to the named file")
    ;
#endif
}
<commit_msg>add SetFontSize() to MolDraw2D c++ api<commit_after>//
//  Copyright (C) 2015 Greg Landrum
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#define PY_ARRAY_UNIQUE_SYMBOL rdmoldraw2d_array_API
#include <boost/python.hpp>
#include <GraphMol/ROMol.h>
#include <RDBoost/Wrap.h>
#include <GraphMol/MolDraw2D/MolDraw2D.h>
#include <GraphMol/MolDraw2D/MolDraw2DSVG.h>
#include <Geometry/point.h>
#include <boost/python/suite/indexing/map_indexing_suite.hpp>
#ifdef RDK_CAIRO_BUILD
#include <cairo.h>
#include <GraphMol/MolDraw2D/MolDraw2DCairo.h>
#endif

namespace python = boost::python;

namespace RDKit {
  namespace {
    std::map<int,DrawColour> *pyDictToColourMap(python::object pyo){
      std::map<int,DrawColour> *res=NULL;
      if(pyo){
        res = new std::map<int,DrawColour>;
        python::dict tDict = python::extract<python::dict>(pyo);
        for(unsigned int i=0;i<python::extract<unsigned int>(tDict.keys().attr("__len__")());++i){
          python::tuple tpl=python::extract<python::tuple>(tDict.values()[i]);
          float r=python::extract<float>(tpl[0]);
          float g=python::extract<float>(tpl[1]);
          float b=python::extract<float>(tpl[2]);
          DrawColour clr(r,g,b);
          (*res)[python::extract<int>(tDict.keys()[i])]=clr;
        }
      }
      return res;
    }
    std::map<int,double> *pyDictToDoubleMap(python::object pyo){
      std::map<int,double> *res=NULL;
      if(pyo){
        res = new std::map<int,double>;
        python::dict tDict = python::extract<python::dict>(pyo);
        for(unsigned int i=0;i<python::extract<unsigned int>(tDict.keys().attr("__len__")());++i){
          double r = python::extract<double>(tDict.values()[i]);
          (*res)[python::extract<int>(tDict.keys()[i])]=r;
        }
      }
      return res;
    }
  }
  void drawMoleculeHelper1(MolDraw2D &self,
                          const ROMol &mol ,
                          python::object highlight_atoms,
                          python::object highlight_atom_map,
                          python::object highlight_atom_radii,
                          int confId=-1){
    std::vector<int> *highlightAtoms=pythonObjectToVect(highlight_atoms,static_cast<int>(mol.getNumAtoms()));
    std::map<int,DrawColour> *ham=pyDictToColourMap(highlight_atom_map);
    std::map<int,double> *har=pyDictToDoubleMap(highlight_atom_radii);

    self.drawMolecule(mol,highlightAtoms,ham,har,confId);

    delete highlightAtoms;
    delete ham;
    delete har;
  }
  void drawMoleculeHelper2(MolDraw2D &self,
                          const ROMol &mol ,
                          python::object highlight_atoms,
                          python::object highlight_bonds,
                          python::object highlight_atom_map,
                          python::object highlight_bond_map,
                          python::object highlight_atom_radii,
                          int confId=-1){
    std::vector<int> *highlightAtoms=pythonObjectToVect(highlight_atoms,static_cast<int>(mol.getNumAtoms()));
    std::vector<int> *highlightBonds=pythonObjectToVect(highlight_bonds,static_cast<int>(mol.getNumBonds()));
    // FIX: support these
    std::map<int,DrawColour> *ham=pyDictToColourMap(highlight_atom_map);
    std::map<int,DrawColour> *hbm=pyDictToColourMap(highlight_bond_map);
    std::map<int,double> *har=pyDictToDoubleMap(highlight_atom_radii);

    self.drawMolecule(mol,highlightAtoms,highlightBonds,ham,hbm,har,confId);

    delete highlightAtoms;
    delete highlightBonds;
    delete ham;
    delete hbm;
    delete har;
  }

#ifdef RDK_CAIRO_BUILD
  python::object getCairoDrawingText(const RDKit::MolDraw2DCairo &self){
    std::string res=self.getDrawingText();
    python::object retval = python::object(python::handle<>(PyBytes_FromStringAndSize(res.c_str(),res.length())));
    return retval;
  }
#endif

}

BOOST_PYTHON_MODULE(rdMolDraw2D) {

  python::scope().attr("__doc__") =
    "Module containing a C++ implementation of 2D molecule drawing";

  std::string docString;

  python::class_<std::map<int,std::string> >("IntStringMap")
    .def(python::map_indexing_suite<std::map<int,std::string>, true >())
    ;

  docString="Drawing options";
  python::class_<RDKit::MolDrawOptions,boost::noncopyable>("MolDrawOptions",docString.c_str())
    .def_readwrite("dummiesAreAttachments",&RDKit::MolDrawOptions::dummiesAreAttachments)
    .def_readwrite("circleAtoms",&RDKit::MolDrawOptions::circleAtoms)
    //.def_readwrite("highlightColour",&RDKit::MolDrawOptions::highlightColour)
    .def_readwrite("atomLabels",&RDKit::MolDrawOptions::atomLabels,"maps indices to atom labels")
    .def_readwrite("continuousHighlight",&RDKit::MolDrawOptions::continuousHighlight)
    .def_readwrite("flagCloseContactsDist",&RDKit::MolDrawOptions::flagCloseContactsDist)
    .def_readwrite("atomRegions",&RDKit::MolDrawOptions::atomRegions,"regions to outline")
    .def_readwrite("includeAtomTags",&RDKit::MolDrawOptions::includeAtomTags,"include atom tags in output")

    ;
  docString="Drawer abstract base class";
  python::class_<RDKit::MolDraw2D,boost::noncopyable>("MolDraw2D",docString.c_str(),python::no_init)
    .def("SetFontSize",&RDKit::MolDraw2D::setFontSize,"change the default font size")
    .def("DrawMolecule",RDKit::drawMoleculeHelper1,
         (python::arg("self"),python::arg("mol"),
          python::arg("highlightAtoms")=python::object(),
          python::arg("highlightAtomColors")=python::object(),
          python::arg("highlightAtomRadii")=python::object(),
          python::arg("confId")=-1
          ),
         "renders a molecule\n")
    .def("DrawMolecule",RDKit::drawMoleculeHelper2,
         (python::arg("self"),python::arg("mol"),
          python::arg("highlightAtoms"),
          python::arg("highlightBonds"),
          python::arg("highlightAtomColors")=python::object(),
          python::arg("highlightBondColors")=python::object(),
          python::arg("highlightAtomRadii")=python::object(),
          python::arg("confId")=-1
          ),
         "renders a molecule\n")
    .def("drawOptions",(RDKit::MolDrawOptions &(RDKit::MolDraw2D::*)())&RDKit::MolDraw2D::drawOptions,
         python::return_internal_reference<1,
         python::with_custodian_and_ward_postcall<0,1> >(),
         "Returns a modifiable version of the current drawing options"
         )
    ;
  docString="SVG molecule drawer";
  python::class_<RDKit::MolDraw2DSVG, python::bases<RDKit::MolDraw2D>, boost::noncopyable >("MolDraw2DSVG",docString.c_str(),
                                                                                python::init<int,int>())
    .def("FinishDrawing",&RDKit::MolDraw2DSVG::finishDrawing,
         "add the last bits of SVG to finish the drawing")
    .def("GetDrawingText",&RDKit::MolDraw2DSVG::getDrawingText,
         "return the SVG")
    ;

#ifdef RDK_CAIRO_BUILD
  docString="Cairo molecule drawer";
  python::class_<RDKit::MolDraw2DCairo, python::bases<RDKit::MolDraw2D>, boost::noncopyable >("MolDraw2DCairo",
                                                                                docString.c_str(),
                                                                                python::init<int,int>())
    .def("FinishDrawing",&RDKit::MolDraw2DCairo::finishDrawing,
         "add the last bits to finish the drawing")
    .def("GetDrawingText",&RDKit::getCairoDrawingText,
         "return the PNG data as a string")
    .def("WriteDrawingText",&RDKit::MolDraw2DCairo::writeDrawingText,
         "write the PNG data to the named file")
    ;
#endif
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2012 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreWindowEventUtilities.h"
#include "OgreRenderWindow.h"
#include "OgreLogManager.h"
#include "OgreRoot.h"
#include "OgreException.h"
#include "OgreStringConverter.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <X11/Xlib.h>
void GLXProc( Ogre::RenderWindow *win, const XEvent &event );
#endif

//using namespace Ogre;

Ogre::WindowEventUtilities::WindowEventListeners Ogre::WindowEventUtilities::_msListeners;
Ogre::WindowEventUtilities::Windows Ogre::WindowEventUtilities::_msWindows;

namespace Ogre {
//--------------------------------------------------------------------------------//
void WindowEventUtilities::messagePump()
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	// Windows Message Loop (NULL means check all HWNDs belonging to this context)
	MSG  msg;
	while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
	{
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
	//GLX Message Pump
	Windows::iterator win = _msWindows.begin();
	Windows::iterator end = _msWindows.end();

	Display* xDisplay = 0; // same for all windows

	for (; win != end; win++)
	{
	    XID xid;
	    XEvent event;

	    if (!xDisplay)
		(*win)->getCustomAttribute("XDISPLAY", &xDisplay);

	    (*win)->getCustomAttribute("WINDOW", &xid);

	    while (XCheckWindowEvent (xDisplay, xid, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event))
	    {
		GLXProc(*win, event);
	    }

	    // The ClientMessage event does not appear under any Event Mask
	    while (XCheckTypedWindowEvent (xDisplay, xid, ClientMessage, &event))
	    {
		GLXProc(*win, event);
	    }
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
	// OSX Message Pump
	EventRef event = NULL;
	EventTargetRef targetWindow;
	targetWindow = GetEventDispatcherTarget();

    // If we are unable to get the target then we no longer care about events.
    if( !targetWindow ) return;

    // Grab the next event, process it if it is a window event
	if( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
	{
        // Dispatch the event
		SendEventToEventTarget( event, targetWindow );
   		ReleaseEvent( event );
	}
#endif
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::addWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	_msListeners.insert(std::make_pair(window, listener));
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::removeWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	WindowEventListeners::iterator i = _msListeners.begin(), e = _msListeners.end();

	for( ; i != e; ++i )
	{
		if( i->first == window && i->second == listener )
		{
			_msListeners.erase(i);
			break;
		}
	}
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_addRenderWindow(RenderWindow* window)
{
	_msWindows.push_back(window);
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_removeRenderWindow(RenderWindow* window)
{
	Windows::iterator i = std::find(_msWindows.begin(), _msWindows.end(), window);
	if( i != _msWindows.end() )
		_msWindows.erase( i );
}

}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//--------------------------------------------------------------------------------//
namespace Ogre {
LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_CREATE)
	{	// Store pointer to Win32Window in user data area
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
		return 0;
	}

	// look up window instance
	// note: it is possible to get a WM_SIZE before WM_CREATE
	RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (!win)
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	//LogManager* log = LogManager::getSingletonPtr();
	//Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(win),
        end = _msListeners.upper_bound(win);

	switch( uMsg )
	{
	case WM_ACTIVATE:
	{
        bool active = (LOWORD(wParam) != WA_INACTIVE);
        if( active )
        {
		    win->setActive( true );
        }
        else
        {
            if( win->isDeactivatedOnFocusChange() )
            {
    		    win->setActive( false );
            }
        }

	    for( ; start != end; ++start )
		    (start->second)->windowFocusChange(win);
		break;
	}
	case WM_SYSKEYDOWN:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSKEYUP:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
		case VK_F10:
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSCHAR:
		// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
		if (wParam != VK_SPACE)
			return 0;
		break;
	case WM_ENTERSIZEMOVE:
		//log->logMessage("WM_ENTERSIZEMOVE");
		break;
	case WM_EXITSIZEMOVE:
		//log->logMessage("WM_EXITSIZEMOVE");
		break;
	case WM_MOVE:
		//log->logMessage("WM_MOVE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowMoved(win);
		break;
	case WM_DISPLAYCHANGE:
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_SIZE:
		//log->logMessage("WM_SIZE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_GETMINMAXINFO:
		// Prevent the window from going smaller than some minimu size
		((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
		((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
		break;
	case WM_CLOSE:
	{
		//log->logMessage("WM_CLOSE");
		bool close = true;
		for(index = start; index != end; ++index)
		{
			if (!(index->second)->windowClosing(win))
				close = false;
		}
		if (!close) return 0;

		for(index = _msListeners.lower_bound(win); index != end; ++index)
			(index->second)->windowClosed(win);
		win->destroy();
		return 0;
	}
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
//--------------------------------------------------------------------------------//
void GLXProc( Ogre::RenderWindow *win, const XEvent &event )
{
	//An iterator for the window listeners
  Ogre::WindowEventUtilities::WindowEventListeners::iterator index,
		start = Ogre::WindowEventUtilities::_msListeners.lower_bound(win),
		end   = Ogre::WindowEventUtilities::_msListeners.upper_bound(win);

	switch(event.type)
	{
	case ClientMessage:
	{
		::Atom atom;
		win->getCustomAttribute("ATOM", &atom);
		if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom)
		{	//Window closed by window manager
			//Send message first, to allow app chance to unregister things that need done before
			//window is shutdown
			bool close = true;
            for(index = start ; index != end; ++index)
			{
				if (!(index->second)->windowClosing(win))
					close = false;
			}
			if (!close) return;

            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case DestroyNotify:
	{
		if (!win->isClosed())
		{
			// Window closed without window manager warning.
            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case ConfigureNotify:
	{
        // This could be slightly more efficient if windowMovedOrResized took arguments:
		unsigned int oldWidth, oldHeight, oldDepth;
		int oldLeft, oldTop;
		win->getMetrics(oldWidth, oldHeight, oldDepth, oldLeft, oldTop);
		win->windowMovedOrResized();

		unsigned int newWidth, newHeight, newDepth;
		int newLeft, newTop;
		win->getMetrics(newWidth, newHeight, newDepth, newLeft, newTop);

		if (newLeft != oldLeft || newTop != oldTop)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowMoved(win);
		}

		if (newWidth != oldWidth || newHeight != oldHeight)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowResized(win);
		}
		break;
	}
	case FocusIn:     // Gained keyboard focus
	case FocusOut:    // Lost keyboard focus
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case MapNotify:   //Restored
		win->setActive( true );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case UnmapNotify: //Minimised
		win->setActive( false );
		win->setVisible( false );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case VisibilityNotify:
		switch(event.xvisibility.state)
		{
		case VisibilityUnobscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityPartiallyObscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityFullyObscured:
			win->setActive( false );
			win->setVisible( false );
			break;
		}
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	default:
		break;
	} //End switch event.type
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
//--------------------------------------------------------------------------------//
namespace Ogre {
OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHandler, EventRef event, void* wnd)
{
    OSStatus status = noErr;

    // Only events from our window should make it here
    // This ensures that our user data is our WindowRef
    RenderWindow* curWindow = (RenderWindow*)wnd;
    if(!curWindow) return eventNotHandledErr;

    //Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(curWindow),
        end = _msListeners.upper_bound(curWindow);

    // We only get called if a window event happens
    UInt32 eventKind = GetEventKind( event );

    switch( eventKind )
    {
        case kEventWindowActivated:
            curWindow->setActive( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDeactivated:
            if( curWindow->isDeactivatedOnFocusChange() )
            {
                curWindow->setActive( false );
            }

            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);

            break;
        case kEventWindowShown:
        case kEventWindowExpanded:
            curWindow->setActive( true );
            curWindow->setVisible( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowHidden:
        case kEventWindowCollapsed:
            curWindow->setActive( false );
            curWindow->setVisible( false );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDragCompleted:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowMoved(curWindow);
            break;
        case kEventWindowBoundsChanged:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowResized(curWindow);
            break;
		case kEventWindowClose:
		{
			bool close = true;
			for( ; start != end; ++start )
			{
				if (!(start->second)->windowClosing(curWindow))
					close = false;
			}
			if (close)
				// This will cause event handling to continue on to the standard handler, which calls
				// DisposeWindow(), which leads to the 'kEventWindowClosed' event
				status = eventNotHandledErr;
			break;
		}
        case kEventWindowClosed:
            curWindow->destroy();
            for( ; start != end; ++start )
				(start->second)->windowClosed(curWindow);
            break;
        default:
            status = eventNotHandledErr;
            break;
    }

    return status;
}
}
#endif
<commit_msg>Patch to fix bug #562<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2012 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/
#include "OgreStableHeaders.h"
#include "OgreWindowEventUtilities.h"
#include "OgreRenderWindow.h"
#include "OgreLogManager.h"
#include "OgreRoot.h"
#include "OgreException.h"
#include "OgreStringConverter.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#include <X11/Xlib.h>
void GLXProc( Ogre::RenderWindow *win, const XEvent &event );
#endif

//using namespace Ogre;

Ogre::WindowEventUtilities::WindowEventListeners Ogre::WindowEventUtilities::_msListeners;
Ogre::WindowEventUtilities::Windows Ogre::WindowEventUtilities::_msWindows;

namespace Ogre {
//--------------------------------------------------------------------------------//
void WindowEventUtilities::messagePump()
{
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
	// Windows Message Loop (NULL means check all HWNDs belonging to this context)
	MSG  msg;
	while( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
	{
		TranslateMessage( &msg );
		DispatchMessage( &msg );
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
	//GLX Message Pump
	Windows::iterator win = _msWindows.begin();
	Windows::iterator end = _msWindows.end();

	Display* xDisplay = 0; // same for all windows

	for (; win != end; win++)
	{
	    XID xid;
	    XEvent event;

	    if (!xDisplay)
		(*win)->getCustomAttribute("XDISPLAY", &xDisplay);

	    (*win)->getCustomAttribute("WINDOW", &xid);

	    while (XCheckWindowEvent (xDisplay, xid, StructureNotifyMask | VisibilityChangeMask | FocusChangeMask, &event))
	    {
		GLXProc(*win, event);
	    }

	    // The ClientMessage event does not appear under any Event Mask
	    while (XCheckTypedWindowEvent (xDisplay, xid, ClientMessage, &event))
	    {
		GLXProc(*win, event);
	    }
	}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
	// OSX Message Pump
	EventRef event = NULL;
	EventTargetRef targetWindow;
	targetWindow = GetEventDispatcherTarget();

    // If we are unable to get the target then we no longer care about events.
    if( !targetWindow ) return;

    // Grab the next event, process it if it is a window event
	while( ReceiveNextEvent( 0, NULL, kEventDurationNoWait, true, &event ) == noErr )
	{
        // Dispatch the event
		SendEventToEventTarget( event, targetWindow );
   		ReleaseEvent( event );
	}
#endif
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::addWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	_msListeners.insert(std::make_pair(window, listener));
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::removeWindowEventListener( RenderWindow* window, WindowEventListener* listener )
{
	WindowEventListeners::iterator i = _msListeners.begin(), e = _msListeners.end();

	for( ; i != e; ++i )
	{
		if( i->first == window && i->second == listener )
		{
			_msListeners.erase(i);
			break;
		}
	}
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_addRenderWindow(RenderWindow* window)
{
	_msWindows.push_back(window);
}

//--------------------------------------------------------------------------------//
void WindowEventUtilities::_removeRenderWindow(RenderWindow* window)
{
	Windows::iterator i = std::find(_msWindows.begin(), _msWindows.end(), window);
	if( i != _msWindows.end() )
		_msWindows.erase( i );
}

}
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
//--------------------------------------------------------------------------------//
namespace Ogre {
LRESULT CALLBACK WindowEventUtilities::_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	if (uMsg == WM_CREATE)
	{	// Store pointer to Win32Window in user data area
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)(((LPCREATESTRUCT)lParam)->lpCreateParams));
		return 0;
	}

	// look up window instance
	// note: it is possible to get a WM_SIZE before WM_CREATE
	RenderWindow* win = (RenderWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
	if (!win)
		return DefWindowProc(hWnd, uMsg, wParam, lParam);

	//LogManager* log = LogManager::getSingletonPtr();
	//Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(win),
        end = _msListeners.upper_bound(win);

	switch( uMsg )
	{
	case WM_ACTIVATE:
	{
        bool active = (LOWORD(wParam) != WA_INACTIVE);
        if( active )
        {
		    win->setActive( true );
        }
        else
        {
            if( win->isDeactivatedOnFocusChange() )
            {
    		    win->setActive( false );
            }
        }

	    for( ; start != end; ++start )
		    (start->second)->windowFocusChange(win);
		break;
	}
	case WM_SYSKEYDOWN:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSKEYUP:
		switch( wParam )
		{
		case VK_CONTROL:
		case VK_SHIFT:
		case VK_MENU: //ALT
		case VK_F10:
			//return zero to bypass defProc and signal we processed the message
			return 0;
		}
		break;
	case WM_SYSCHAR:
		// return zero to bypass defProc and signal we processed the message, unless it's an ALT-space
		if (wParam != VK_SPACE)
			return 0;
		break;
	case WM_ENTERSIZEMOVE:
		//log->logMessage("WM_ENTERSIZEMOVE");
		break;
	case WM_EXITSIZEMOVE:
		//log->logMessage("WM_EXITSIZEMOVE");
		break;
	case WM_MOVE:
		//log->logMessage("WM_MOVE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowMoved(win);
		break;
	case WM_DISPLAYCHANGE:
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_SIZE:
		//log->logMessage("WM_SIZE");
		win->windowMovedOrResized();
		for(index = start; index != end; ++index)
			(index->second)->windowResized(win);
		break;
	case WM_GETMINMAXINFO:
		// Prevent the window from going smaller than some minimu size
		((MINMAXINFO*)lParam)->ptMinTrackSize.x = 100;
		((MINMAXINFO*)lParam)->ptMinTrackSize.y = 100;
		break;
	case WM_CLOSE:
	{
		//log->logMessage("WM_CLOSE");
		bool close = true;
		for(index = start; index != end; ++index)
		{
			if (!(index->second)->windowClosing(win))
				close = false;
		}
		if (!close) return 0;

		for(index = _msListeners.lower_bound(win); index != end; ++index)
			(index->second)->windowClosed(win);
		win->destroy();
		return 0;
	}
	}

	return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
//--------------------------------------------------------------------------------//
void GLXProc( Ogre::RenderWindow *win, const XEvent &event )
{
	//An iterator for the window listeners
  Ogre::WindowEventUtilities::WindowEventListeners::iterator index,
		start = Ogre::WindowEventUtilities::_msListeners.lower_bound(win),
		end   = Ogre::WindowEventUtilities::_msListeners.upper_bound(win);

	switch(event.type)
	{
	case ClientMessage:
	{
		::Atom atom;
		win->getCustomAttribute("ATOM", &atom);
		if(event.xclient.format == 32 && event.xclient.data.l[0] == (long)atom)
		{	//Window closed by window manager
			//Send message first, to allow app chance to unregister things that need done before
			//window is shutdown
			bool close = true;
            for(index = start ; index != end; ++index)
			{
				if (!(index->second)->windowClosing(win))
					close = false;
			}
			if (!close) return;

            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case DestroyNotify:
	{
		if (!win->isClosed())
		{
			// Window closed without window manager warning.
            for(index = start ; index != end; ++index)
                (index->second)->windowClosed(win);
			win->destroy();
		}
		break;
	}
	case ConfigureNotify:
	{
        // This could be slightly more efficient if windowMovedOrResized took arguments:
		unsigned int oldWidth, oldHeight, oldDepth;
		int oldLeft, oldTop;
		win->getMetrics(oldWidth, oldHeight, oldDepth, oldLeft, oldTop);
		win->windowMovedOrResized();

		unsigned int newWidth, newHeight, newDepth;
		int newLeft, newTop;
		win->getMetrics(newWidth, newHeight, newDepth, newLeft, newTop);

		if (newLeft != oldLeft || newTop != oldTop)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowMoved(win);
		}

		if (newWidth != oldWidth || newHeight != oldHeight)
		{
            for(index = start ; index != end; ++index)
                (index->second)->windowResized(win);
		}
		break;
	}
	case FocusIn:     // Gained keyboard focus
	case FocusOut:    // Lost keyboard focus
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case MapNotify:   //Restored
		win->setActive( true );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case UnmapNotify: //Minimised
		win->setActive( false );
		win->setVisible( false );
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	case VisibilityNotify:
		switch(event.xvisibility.state)
		{
		case VisibilityUnobscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityPartiallyObscured:
			win->setActive( true );
			win->setVisible( true );
			break;
		case VisibilityFullyObscured:
			win->setActive( false );
			win->setVisible( false );
			break;
		}
        for(index = start ; index != end; ++index)
            (index->second)->windowFocusChange(win);
		break;
	default:
		break;
	} //End switch event.type
}
#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE && !defined __OBJC__ && !defined __LP64__
//--------------------------------------------------------------------------------//
namespace Ogre {
OSStatus WindowEventUtilities::_CarbonWindowHandler(EventHandlerCallRef nextHandler, EventRef event, void* wnd)
{
    OSStatus status = noErr;

    // Only events from our window should make it here
    // This ensures that our user data is our WindowRef
    RenderWindow* curWindow = (RenderWindow*)wnd;
    if(!curWindow) return eventNotHandledErr;

    //Iterator of all listeners registered to this RenderWindow
	WindowEventListeners::iterator index,
        start = _msListeners.lower_bound(curWindow),
        end = _msListeners.upper_bound(curWindow);

    // We only get called if a window event happens
    UInt32 eventKind = GetEventKind( event );

    switch( eventKind )
    {
        case kEventWindowActivated:
            curWindow->setActive( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDeactivated:
            if( curWindow->isDeactivatedOnFocusChange() )
            {
                curWindow->setActive( false );
            }

            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);

            break;
        case kEventWindowShown:
        case kEventWindowExpanded:
            curWindow->setActive( true );
            curWindow->setVisible( true );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowHidden:
        case kEventWindowCollapsed:
            curWindow->setActive( false );
            curWindow->setVisible( false );
            for( ; start != end; ++start )
                (start->second)->windowFocusChange(curWindow);
            break;
        case kEventWindowDragCompleted:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowMoved(curWindow);
            break;
        case kEventWindowBoundsChanged:
            curWindow->windowMovedOrResized();
            for( ; start != end; ++start )
				(start->second)->windowResized(curWindow);
            break;
		case kEventWindowClose:
		{
			bool close = true;
			for( ; start != end; ++start )
			{
				if (!(start->second)->windowClosing(curWindow))
					close = false;
			}
			if (close)
				// This will cause event handling to continue on to the standard handler, which calls
				// DisposeWindow(), which leads to the 'kEventWindowClosed' event
				status = eventNotHandledErr;
			break;
		}
        case kEventWindowClosed:
            curWindow->destroy();
            for( ; start != end; ++start )
				(start->second)->windowClosed(curWindow);
            break;
        default:
            status = eventNotHandledErr;
            break;
    }

    return status;
}
}
#endif
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "TestVector.h"

TestVector::TestVector()
{
}

TestVector::~TestVector()
{
}

TEST_F(TestVector, VectorReserveMemoryTest)
{
	std::vector<int> values;
	std::vector<int>::size_type count = 5;
	values.reserve(count);

	EXPECT_EQ(count, values.capacity());
	EXPECT_TRUE(values.empty());
	EXPECT_EQ(0, values.size());

	// Capacity remains == count until more than count numbers are added
	values.push_back(0);
	EXPECT_EQ(count, values.capacity());
	EXPECT_EQ(1, values.size());

	for (int i = 1; i < 6; ++i)
	{
		values.push_back(i);
	}

	EXPECT_GT(values.capacity(), (count));
}

TEST_F(TestVector, VectorAssignTest)
{
	std::vector<int> values;
	EXPECT_TRUE(values.empty());

	values.assign({ 1, 2 });
	EXPECT_FALSE(values.empty());
	EXPECT_EQ(2, values.size());

	values.assign(3, 0);
	EXPECT_EQ(3, values.size());
	EXPECT_EQ(values[0], 0);
	EXPECT_EQ(values[1], 0);
	EXPECT_EQ(values[2], 0);

	const unsigned int count = 4;
	int valuesArray[count] = { 10, 20, 30, 40 };
	values.assign(valuesArray, valuesArray + count);
	EXPECT_EQ(count, values.size());
	EXPECT_EQ(values[0], 10);
	EXPECT_EQ(values[3], 40);

}
<commit_msg>added some new vector tests<commit_after>#include "stdafx.h"
#include "TestVector.h"

TestVector::TestVector()
{
}

TestVector::~TestVector()
{
}

TEST_F(TestVector, VectorReserveMemoryTest)
{
	std::vector<int> values;
	std::vector<int>::size_type count = 5;
	values.reserve(count);

	EXPECT_EQ(count, values.capacity());
	EXPECT_TRUE(values.empty());
	EXPECT_EQ(0, values.size());

	// Capacity remains == count until more than count numbers are added
	values.push_back(0);
	EXPECT_EQ(count, values.capacity());
	EXPECT_EQ(1, values.size());

	for (int i = 1; i < 6; ++i)
	{
		values.push_back(i);
	}

	EXPECT_GT(values.capacity(), (count));
}

TEST_F(TestVector, VectorAssignTest)
{
	std::vector<int> values;
	EXPECT_TRUE(values.empty());

	values.assign({ 1, 2 });
	EXPECT_FALSE(values.empty());
	EXPECT_EQ(2, values.size());

	values.assign(3, 0);
	EXPECT_EQ(3, values.size());
	EXPECT_EQ(values[0], 0);
	EXPECT_EQ(values[1], 0);
	EXPECT_EQ(values[2], 0);

	const unsigned int count = 4;
	int valuesArray[count] = { 10, 20, 30, 40 };
	values.assign(valuesArray, valuesArray + count);
	EXPECT_EQ(count, values.size());
	EXPECT_EQ(values[0], 10);
	EXPECT_EQ(values[3], 40);
}

TEST_F(TestVector, ExceptionsTest)
{
	std::vector<int> values = { 1, 2, 3, 4, 5 };
	EXPECT_THROW(values.at(5), std::out_of_range);
	EXPECT_NO_THROW(values.at(4));
}

TEST_F(TestVector, Iterators)
{
	std::vector<std::string> words = { "the", "cow", "jumped", "over", "the", "moon" };
	EXPECT_EQ("the", *(words.begin()));
	EXPECT_EQ("moon", *(words.end() - 1));
	EXPECT_EQ("the", *(words.rend() - 1));
	EXPECT_EQ("moon", *(words.rbegin()));

	std::string expected = "the cow jumped over the moon";
	std::string actual;
	for (auto str : words)
	{
		actual += str;
		actual += " ";
	}
	actual.erase(actual.end() - 1);
	EXPECT_EQ(actual, expected);
}
<|endoftext|>