<commit_before>/**
 * \file
 * \brief SortedIntrusiveList template class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-12-20
 */

#ifndef ESTD_SORTEDINTRUSIVELIST_HPP_
#define ESTD_SORTEDINTRUSIVELIST_HPP_

#include "estd/IntrusiveList.hpp"

#include <algorithm>

namespace estd
{

/**
 * \brief SortedIntrusiveList class is an IntrusiveList with sorted elements
 *
 * This class tries to provide an interface similar to std::list.
 *
 * \note The elements are sorted as long as the user does not modify the contents.
 *
 * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
 * ascending order
 * \tparam T is the type that has the IntrusiveListNode variable
 * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
 * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
 * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used
 * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to
 * forward declare \a U - it only needs to be fully defined to use member functions
 */

template<typename Compare, typename T, IntrusiveListNode T::* NodePointer, typename U = T>
class SortedIntrusiveList
{
public:

	/// unsorted intrusive list used internally
	using UnsortedIntrusiveList = IntrusiveList<T, NodePointer, U>;

	/// const iterator of elements on the list
	using const_iterator = typename UnsortedIntrusiveList::const_iterator;

	/// const reverse iterator of elements on the list
	using const_reverse_iterator = typename UnsortedIntrusiveList::const_reverse_iterator;

	/// const pointer to value linked in the list
	using const_pointer = typename UnsortedIntrusiveList::const_pointer;

	/// const reference to value linked in the list
	using const_reference = typename UnsortedIntrusiveList::const_reference;

	/// iterator of elements on the list
	using iterator = typename UnsortedIntrusiveList::iterator;

	/// reverse iterator of elements on the list
	using reverse_iterator = typename UnsortedIntrusiveList::reverse_iterator;

	/// pointer to value linked in the list
	using pointer = typename UnsortedIntrusiveList::pointer;

	/// reference to value linked in the list
	using reference = typename UnsortedIntrusiveList::reference;

	/// value linked in the list
	using value_type = typename UnsortedIntrusiveList::value_type;

	/**
	 * \brief SortedIntrusiveList's constructor
	 *
	 * \param [in] compare is a reference to Compare object used to copy-construct internal comparison functor
	 */

	constexpr SortedIntrusiveList(const Compare& compare = Compare{}) :
			implementation_{compare}
	{

	}

	/**
	 * \return reference to last element on the list
	 */

	reference back()
	{
		return implementation_.intrusiveList.back();
	}

	/**
	 * \return const reference to last element on the list
	 */

	const_reference back() const
	{
		return implementation_.intrusiveList.back();
	}

	/**
	 * \return iterator of first element on the list
	 */

	iterator begin()
	{
		return implementation_.intrusiveList.begin();
	}

	/**
	 * \return const iterator of first element on the list
	 */

	const_iterator begin() const
	{
		return implementation_.intrusiveList.begin();
	}

	/**
	 * \return const iterator of first element on the list
	 */

	const_iterator cbegin() const
	{
		return implementation_.intrusiveList.cbegin();
	}

	/**
	 * \return const iterator of "one past the last" element on the list
	 */

	const_iterator cend() const
	{
		return implementation_.intrusiveList.cend();
	}

	/**
	 * \brief Unlinks all elements from the list.
	 */

	void clear()
	{
		implementation_.intrusiveList.clear();
	}

	/**
	 * \return true is the list is empty, false otherwise
	 */

	bool empty() const
	{
		return implementation_.intrusiveList.empty();
	}

	/**
	 * \return iterator of "one past the last" element on the list
	 */

	iterator end()
	{
		return implementation_.intrusiveList.end();
	}

	/**
	 * \return const iterator of "one past the last" element on the list
	 */

	const_iterator end() const
	{
		return implementation_.intrusiveList.end();
	}

	/**
	 * \return reference to first element on the list
	 */

	reference front()
	{
		return implementation_.intrusiveList.front();
	}

	/**
	 * \return const reference to first element on the list
	 */

	const_reference front() const
	{
		return implementation_.intrusiveList.front();
	}

	/**
	 * \brief Links the element in the list, keeping it sorted.
	 *
	 * \param [in] newElement is a reference to the element that will be linked in the list
	 *
	 * \return iterator of \a newElement
	 */

	iterator insert(reference newElement)
	{
		return UnsortedIntrusiveList::insert(implementation_.findInsertPosition(newElement), newElement);
	}

	/**
	 * \brief Unlinks the last element from the list.
	 */

	void pop_back()
	{
		implementation_.intrusiveList.pop_back();
	}

	/**
	 * \brief Unlinks the first element from the list.
	 */

	void pop_front()
	{
		implementation_.intrusiveList.pop_front();
	}

	/**
	 * \brief Transfers the element from another list to this one, keeping it sorted.
	 *
	 * \param [in] splicedElement is an iterator of the element that will be spliced from another list to this one
	 */

	void splice(const iterator splicedElement)
	{
		UnsortedIntrusiveList::splice(implementation_.findInsertPosition(*splicedElement), splicedElement);
	}

	/**
	 * \brief Swaps contents with another list.
	 *
	 * \param [in] other is a reference to SortedIntrusiveList with which contents of this list will be swapped
	 */

	void swap(SortedIntrusiveList& other)
	{
		std::swap(implementation_, other.implementation_);
	}

	/**
	 * \brief Unlinks the element at \a position from the list.
	 *
	 * \note No instance of the list is needed for this operation.
	 *
	 * \param [in] position is an iterator of the element that will be unlinked from the list
	 *
	 * \return iterator of the element that was following the element which was unlinked
	 */

	static iterator erase(const iterator position)
	{
		return UnsortedIntrusiveList::erase(position);
	}

private:

	/// Implementation struct is used primarily for "Empty Base Optimization" with \a Compare type
	struct Implementation : public Compare
	{
		/**
		 * \brief Implementation's constructor
		 *
		 * \param [in] comparee is a reference to Compare object used to copy-construct internal comparison functor
		 */

		constexpr Implementation(const Compare& comparee) :
				Compare{comparee},
				intrusiveList{}
		{

		}

		/**
		 * \brief Finds insert position that satisfies sorting criteria.
		 *
		 * \param [in] newElement is a const reference to new element that is going to be inserted/spliced
		 *
		 * \return iterator for which Compare's function call operator of dereferenced value and \a newElement returns
		 * true.
		 */

		iterator findInsertPosition(const_reference newElement)
		{
			return std::find_if(intrusiveList.begin(), intrusiveList.end(),
					[this, &newElement](const_reference& element) -> bool
					{
						return this->Compare::operator()(element, newElement);
					}
			);
		}

		/// internal unsorted IntrusiveList
		UnsortedIntrusiveList intrusiveList;
	};

	/// internal Implementation object - unsorted IntrusiveList and Compare instance
	Implementation implementation_;
};

/**
 * \brief Swaps contents of two lists.
 *
 * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
 * ascending order
 * \tparam T is the type that has the IntrusiveListNode variable
 * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
 * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
 * convertible to \a T (so usually a type derived from \a T); default - \a T;
 *
 * \param [in] left is a reference to SortedIntrusiveList with which contents of \a right will be swapped
 * \param [in] right is a reference to SortedIntrusiveList with which contents of \a left will be swapped
 */

template<typename Compare, typename T, IntrusiveListNode T::* NodePointer, typename U = T>
inline void swap(SortedIntrusiveList<Compare, T, NodePointer, U>& left,
		SortedIntrusiveList<Compare, T, NodePointer, U>& right)
{
	left.swap(right);
}

}	// namespace estd

#endif	// ESTD_SORTEDINTRUSIVELIST_HPP_
<commit_msg>SortedIntrusiveList: fix swap() function<commit_after>/**
 * \file
 * \brief SortedIntrusiveList template class header
 *
 * \author Copyright (C) 2015 Kamil Szczygiel http://www.distortec.com http://www.freddiechopin.info
 *
 * \par License
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not
 * distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * \date 2015-12-23
 */

#ifndef ESTD_SORTEDINTRUSIVELIST_HPP_
#define ESTD_SORTEDINTRUSIVELIST_HPP_

#include "estd/IntrusiveList.hpp"

#include <algorithm>

namespace estd
{

/**
 * \brief SortedIntrusiveList class is an IntrusiveList with sorted elements
 *
 * This class tries to provide an interface similar to std::list.
 *
 * \note The elements are sorted as long as the user does not modify the contents.
 *
 * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
 * ascending order
 * \tparam T is the type that has the IntrusiveListNode variable
 * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
 * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
 * convertible to \a T (so usually a type derived from \a T); default - \a T; using different type than \a T can be used
 * to break circular dependencies, because \a T must be fully defined to instantiate this class, but it is enough to
 * forward declare \a U - it only needs to be fully defined to use member functions
 */

template<typename Compare, typename T, IntrusiveListNode T::* NodePointer, typename U = T>
class SortedIntrusiveList
{
public:

	/// unsorted intrusive list used internally
	using UnsortedIntrusiveList = IntrusiveList<T, NodePointer, U>;

	/// const iterator of elements on the list
	using const_iterator = typename UnsortedIntrusiveList::const_iterator;

	/// const reverse iterator of elements on the list
	using const_reverse_iterator = typename UnsortedIntrusiveList::const_reverse_iterator;

	/// const pointer to value linked in the list
	using const_pointer = typename UnsortedIntrusiveList::const_pointer;

	/// const reference to value linked in the list
	using const_reference = typename UnsortedIntrusiveList::const_reference;

	/// iterator of elements on the list
	using iterator = typename UnsortedIntrusiveList::iterator;

	/// reverse iterator of elements on the list
	using reverse_iterator = typename UnsortedIntrusiveList::reverse_iterator;

	/// pointer to value linked in the list
	using pointer = typename UnsortedIntrusiveList::pointer;

	/// reference to value linked in the list
	using reference = typename UnsortedIntrusiveList::reference;

	/// value linked in the list
	using value_type = typename UnsortedIntrusiveList::value_type;

	/**
	 * \brief SortedIntrusiveList's constructor
	 *
	 * \param [in] compare is a reference to Compare object used to copy-construct internal comparison functor
	 */

	constexpr SortedIntrusiveList(const Compare& compare = Compare{}) :
			implementation_{compare}
	{

	}

	/**
	 * \return reference to last element on the list
	 */

	reference back()
	{
		return implementation_.intrusiveList.back();
	}

	/**
	 * \return const reference to last element on the list
	 */

	const_reference back() const
	{
		return implementation_.intrusiveList.back();
	}

	/**
	 * \return iterator of first element on the list
	 */

	iterator begin()
	{
		return implementation_.intrusiveList.begin();
	}

	/**
	 * \return const iterator of first element on the list
	 */

	const_iterator begin() const
	{
		return implementation_.intrusiveList.begin();
	}

	/**
	 * \return const iterator of first element on the list
	 */

	const_iterator cbegin() const
	{
		return implementation_.intrusiveList.cbegin();
	}

	/**
	 * \return const iterator of "one past the last" element on the list
	 */

	const_iterator cend() const
	{
		return implementation_.intrusiveList.cend();
	}

	/**
	 * \brief Unlinks all elements from the list.
	 */

	void clear()
	{
		implementation_.intrusiveList.clear();
	}

	/**
	 * \return true is the list is empty, false otherwise
	 */

	bool empty() const
	{
		return implementation_.intrusiveList.empty();
	}

	/**
	 * \return iterator of "one past the last" element on the list
	 */

	iterator end()
	{
		return implementation_.intrusiveList.end();
	}

	/**
	 * \return const iterator of "one past the last" element on the list
	 */

	const_iterator end() const
	{
		return implementation_.intrusiveList.end();
	}

	/**
	 * \return reference to first element on the list
	 */

	reference front()
	{
		return implementation_.intrusiveList.front();
	}

	/**
	 * \return const reference to first element on the list
	 */

	const_reference front() const
	{
		return implementation_.intrusiveList.front();
	}

	/**
	 * \brief Links the element in the list, keeping it sorted.
	 *
	 * \param [in] newElement is a reference to the element that will be linked in the list
	 *
	 * \return iterator of \a newElement
	 */

	iterator insert(reference newElement)
	{
		return UnsortedIntrusiveList::insert(implementation_.findInsertPosition(newElement), newElement);
	}

	/**
	 * \brief Unlinks the last element from the list.
	 */

	void pop_back()
	{
		implementation_.intrusiveList.pop_back();
	}

	/**
	 * \brief Unlinks the first element from the list.
	 */

	void pop_front()
	{
		implementation_.intrusiveList.pop_front();
	}

	/**
	 * \brief Transfers the element from another list to this one, keeping it sorted.
	 *
	 * \param [in] splicedElement is an iterator of the element that will be spliced from another list to this one
	 */

	void splice(const iterator splicedElement)
	{
		UnsortedIntrusiveList::splice(implementation_.findInsertPosition(*splicedElement), splicedElement);
	}

	/**
	 * \brief Swaps contents with another list.
	 *
	 * \param [in] other is a reference to SortedIntrusiveList with which contents of this list will be swapped
	 */

	void swap(SortedIntrusiveList& other)
	{
		implementation_.swap(other.implementation_);
	}

	/**
	 * \brief Unlinks the element at \a position from the list.
	 *
	 * \note No instance of the list is needed for this operation.
	 *
	 * \param [in] position is an iterator of the element that will be unlinked from the list
	 *
	 * \return iterator of the element that was following the element which was unlinked
	 */

	static iterator erase(const iterator position)
	{
		return UnsortedIntrusiveList::erase(position);
	}

private:

	/// Implementation struct is used primarily for "Empty Base Optimization" with \a Compare type
	struct Implementation : public Compare
	{
		/**
		 * \brief Implementation's constructor
		 *
		 * \param [in] comparee is a reference to Compare object used to copy-construct internal comparison functor
		 */

		constexpr Implementation(const Compare& comparee) :
				Compare{comparee},
				intrusiveList{}
		{

		}

		/**
		 * \brief Finds insert position that satisfies sorting criteria.
		 *
		 * \param [in] newElement is a const reference to new element that is going to be inserted/spliced
		 *
		 * \return iterator for which Compare's function call operator of dereferenced value and \a newElement returns
		 * true.
		 */

		iterator findInsertPosition(const_reference newElement)
		{
			return std::find_if(intrusiveList.begin(), intrusiveList.end(),
					[this, &newElement](const_reference& element) -> bool
					{
						return this->Compare::operator()(element, newElement);
					}
			);
		}

		/**
		 * \brief Swaps contents with another instance.
		 *
		 * \param [in] other is a reference to Implementation with which contents of this instance will be swapped
		 */

		void swap(Implementation& other)
		{
			intrusiveList.swap(other.intrusiveList);
			using std::swap;
			swap(static_cast<Compare&>(*this), static_cast<Compare&>(other));
		}

		/// internal unsorted IntrusiveList
		UnsortedIntrusiveList intrusiveList;
	};

	/// internal Implementation object - unsorted IntrusiveList and Compare instance
	Implementation implementation_;
};

/**
 * \brief Swaps contents of two lists.
 *
 * \tparam Compare is a type of functor used for comparison, std::less results in descending order, std::greater - in
 * ascending order
 * \tparam T is the type that has the IntrusiveListNode variable
 * \tparam NodePointer is a pointer-to-member to IntrusiveListNode variable in \a T
 * \tparam U is the type that will be stored on the list; it can be different from \a T, but must be implicitly
 * convertible to \a T (so usually a type derived from \a T); default - \a T;
 *
 * \param [in] left is a reference to SortedIntrusiveList with which contents of \a right will be swapped
 * \param [in] right is a reference to SortedIntrusiveList with which contents of \a left will be swapped
 */

template<typename Compare, typename T, IntrusiveListNode T::* NodePointer, typename U = T>
inline void swap(SortedIntrusiveList<Compare, T, NodePointer, U>& left,
		SortedIntrusiveList<Compare, T, NodePointer, U>& right)
{
	left.swap(right);
}

}	// namespace estd

#endif	// ESTD_SORTEDINTRUSIVELIST_HPP_
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

#ifndef __IGN_TRANSPORT_PACKET_HH_INCLUDED__
#define __IGN_TRANSPORT_PACKET_HH_INCLUDED__

#include <uuid/uuid.h>
#include <cstdint>
#include <string>
#include <vector>

namespace ignition
{
  namespace transport
  {
    /// \brief Length of a GUID.
    #define GUID_STR_LEN (sizeof(uuid_t) * 2) + 4 + 1

    //  This is the version of Gazebo transport we implement
    static const int Version        = 1;

    // Message types
    static const int AdvType        = 0;
    static const int SubType        = 1;
    static const int AdvSvcType     = 2;
    static const int SubSvcType     = 3;
    static const int PubType        = 4;
    static const int ReqType        = 5;
    static const int RepType        = 6;
    static const int RepErrorType   = 7;

    /// \brief Used for debugging the message type received/send.
    static const std::vector<std::string> MsgTypesStr =
    {
      "ADVERTISE", "SUBSCRIBE", "ADV_SRV", "SUB_SVC",
      "PUB", "REQ", "SRV_REP_OK", "SRV_REP_ERROR"
    };

    /// \brief Get the string representation of the GUID.
    /// \param[in] _uuid UUID to be converted to string.
    /// \return A string representation of the GUID.
    std::string GetGuidStr(const uuid_t &_uuid);

    class Header
    {
      /// \brief Constructor.
      public: Header();

      /// \brief Constructor.
      /// \param[in] _version Version of the transport library.
      /// \param[in] _guid Global identifier. Every process has a unique guid.
      /// \param[in] _topic Topic
      /// \param[in] _type Message type (ADVERTISE, SUBSCRIPTION, ...)
      /// \param[in] _flags Optional flags included in the header.
      public: Header(const uint16_t _version,
                     const uuid_t &_guid,
                     const std::string &_topic,
                     const uint8_t _type,
                     const uint16_t _flags);

      /// \brief Get the transport library version.
      /// \return Transport library version.
      public: uint16_t GetVersion() const;

      /// \brief Get the guid.
      /// \return A unique global identifier for every process.
      public: uuid_t& GetGuid();

      /// \brief Get the topic length.
      /// \return Topic length in bytes.
      public: uint16_t GetTopicLength() const;

      /// \brief Get the topic.
      /// \return Topic name.
      public: std::string GetTopic() const;

      /// \brief Get the message type.
      /// \return Message type (ADVERTISE, SUBSCRIPTION, ...)
      public: uint8_t GetType() const;

      /// \brief Get the message flags.
      /// \return Message flags used for compression or other optional features.
      public: uint16_t GetFlags() const;

      /// \brief Set the transport library version.
      /// \param[in] Transport library version.
      public: void SetVersion(const uint16_t _version);

      /// \brief Set the guid.
      /// \param[in] _guid A unique global identifier for every process.
      public: void SetGuid(const uuid_t &_guid);

      /// \brief Set the topic.
      /// \param[in] _topic Topic name.
      public: void SetTopic(const std::string &_topic);

      /// \brief Set the message type.
      /// \param[in] _type Message type (ADVERTISE, SUBSCRIPTION, ...)
      public: void SetType(const uint8_t _type);

      /// \brief Set the message flags.
      /// \param[in] _flags Used for enable optional features.
      public: void SetFlags(const uint16_t _flags);

      /// \brief Get the header length.
      /// \return The header length in bytes.
      public: int GetHeaderLength();

      /// \brief Print the header.
      public: void Print();

      /// \brief Serialize the header. The caller has ownership of the
      /// buffer and is responsible for its [de]allocation.
      /// \param[out] _buffer Destination buffer in which the header
      /// will be serialized.
      /// \return Number of bytes serialized.
      public: size_t Pack(char *_buffer);

      /// \brief Unserialize the header.
      /// \param[in] _buffer Input buffer with the data to be unserialized.
      public: size_t Unpack(const char *_buffer);

      /// \brief Calculate the header length.
      private: void UpdateHeaderLength();

      /// \brief Version of the transport library.
      private: uint16_t version;

      /// \brief Global identifier. Every process has a unique guid.
      private: uuid_t guid;

      /// \brief Topic length in bytes.
      private: uint16_t topicLength;

      /// \brief Topic.
      private:std::string topic;

      /// \brief Message type (ADVERTISE, SUBSCRIPTION, ...).
      private: uint8_t type;

      /// \brief Optional flags that you want to include in the header.
      private: uint16_t flags;

      /// \brief Header length.
      private: int headerLength;
    };

    class AdvMsg
    {
      /// \brief Constructor.
      public: AdvMsg();

      /// \brief Constructor.
      /// \param[in] _header Message header
      /// \param[in] _address ZeroMQ address (e.g., "tcp://10.0.0.1:6000").
      public: AdvMsg(const Header &_header, const std::string &_address);

      /// \brief Get the message header.
      /// \return Reference to the message header.
      public: Header& GetHeader();

      /// \brief Get the address length.
      /// \brief Return the ZMQ address length (num of bytes).
      public: uint16_t GetAddressLength() const;

      /// \brief Get the ZMQ address.
      /// \return Return the ZMQ address.
      public: std::string GetAddress() const;

      /// \brief Set the header of the message.
      /// \param[in] _header Message header.
      public: void SetHeader(const Header &_header);

      /// \brief Set the ZMQ address.
      /// \param[in] _address ZMQ address to be contained in the message.
      public: void SetAddress(const std::string &_address);

      /// \brief Get the total length of the message.
      /// \return Return the length of the message in bytes.
      public: size_t GetMsgLength();

      /// \brief Print the message.
      public: void PrintBody();

      /// \brief Serialize the AdvMsg.
      /// \param[out] _buffer Buffer where the message will be serialized.
      /// \return The length of the serialized message in bytes.
      public: size_t Pack(char *_buffer);

      /// \brief Unserialize a stream of bytes into a AdvMsg.
      /// \param[out] _buffer Unpack the body from the buffer.
      /// \return The number of bytes from the body.
      public: size_t UnpackBody(char *_buffer);

      /// \brief Update the ADV message length.
      private: void UpdateMsgLength();

      /// \brief Message header
      private: Header header;

      /// \brief Length of the address contained in this message (bytes).
      private: uint16_t addressLength;

      /// \brief ZMQ valid address (e.g., "tcp://10.0.0.1:6000").
      private: std::string address;

      /// \brief Length of the message in bytes.
      private: int msgLength;
    };
  }
}

#endif
<commit_msg>[include/ignition/transport/Packet.hh] Adding doxygen to the classes Packet and AdvMsg.<commit_after>/*
 * Copyright (C) 2014 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

#ifndef __IGN_TRANSPORT_PACKET_HH_INCLUDED__
#define __IGN_TRANSPORT_PACKET_HH_INCLUDED__

#include <uuid/uuid.h>
#include <cstdint>
#include <string>
#include <vector>

namespace ignition
{
  namespace transport
  {
    /// \brief Length of a GUID.
    #define GUID_STR_LEN (sizeof(uuid_t) * 2) + 4 + 1

    //  This is the version of Gazebo transport we implement
    static const int Version        = 1;

    // Message types
    static const int AdvType        = 0;
    static const int SubType        = 1;
    static const int AdvSvcType     = 2;
    static const int SubSvcType     = 3;
    static const int PubType        = 4;
    static const int ReqType        = 5;
    static const int RepType        = 6;
    static const int RepErrorType   = 7;

    /// \brief Used for debugging the message type received/send.
    static const std::vector<std::string> MsgTypesStr =
    {
      "ADVERTISE", "SUBSCRIBE", "ADV_SRV", "SUB_SVC",
      "PUB", "REQ", "SRV_REP_OK", "SRV_REP_ERROR"
    };

    /// \brief Get the string representation of the GUID.
    /// \param[in] _uuid UUID to be converted to string.
    /// \return A string representation of the GUID.
    std::string GetGuidStr(const uuid_t &_uuid);

    /// \class Header Packet.hh
    /// \brief Header included in each discovery message containing the version
    /// of the discovery protocol, the UUID of the sender node, the topic
    /// contained in the message, the type of message (ADV, SUB, ... ) and
    /// optional flags.
    class Header
    {
      /// \brief Constructor.
      public: Header();

      /// \brief Constructor.
      /// \param[in] _version Version of the transport library.
      /// \param[in] _guid Global identifier. Every process has a unique guid.
      /// \param[in] _topic Topic
      /// \param[in] _type Message type (ADVERTISE, SUBSCRIPTION, ...)
      /// \param[in] _flags Optional flags included in the header.
      public: Header(const uint16_t _version,
                     const uuid_t &_guid,
                     const std::string &_topic,
                     const uint8_t _type,
                     const uint16_t _flags);

      /// \brief Get the transport library version.
      /// \return Transport library version.
      public: uint16_t GetVersion() const;

      /// \brief Get the guid.
      /// \return A unique global identifier for every process.
      public: uuid_t& GetGuid();

      /// \brief Get the topic length.
      /// \return Topic length in bytes.
      public: uint16_t GetTopicLength() const;

      /// \brief Get the topic.
      /// \return Topic name.
      public: std::string GetTopic() const;

      /// \brief Get the message type.
      /// \return Message type (ADVERTISE, SUBSCRIPTION, ...)
      public: uint8_t GetType() const;

      /// \brief Get the message flags.
      /// \return Message flags used for compression or other optional features.
      public: uint16_t GetFlags() const;

      /// \brief Set the transport library version.
      /// \param[in] Transport library version.
      public: void SetVersion(const uint16_t _version);

      /// \brief Set the guid.
      /// \param[in] _guid A unique global identifier for every process.
      public: void SetGuid(const uuid_t &_guid);

      /// \brief Set the topic.
      /// \param[in] _topic Topic name.
      public: void SetTopic(const std::string &_topic);

      /// \brief Set the message type.
      /// \param[in] _type Message type (ADVERTISE, SUBSCRIPTION, ...)
      public: void SetType(const uint8_t _type);

      /// \brief Set the message flags.
      /// \param[in] _flags Used for enable optional features.
      public: void SetFlags(const uint16_t _flags);

      /// \brief Get the header length.
      /// \return The header length in bytes.
      public: int GetHeaderLength();

      /// \brief Print the header.
      public: void Print();

      /// \brief Serialize the header. The caller has ownership of the
      /// buffer and is responsible for its [de]allocation.
      /// \param[out] _buffer Destination buffer in which the header
      /// will be serialized.
      /// \return Number of bytes serialized.
      public: size_t Pack(char *_buffer);

      /// \brief Unserialize the header.
      /// \param[in] _buffer Input buffer with the data to be unserialized.
      public: size_t Unpack(const char *_buffer);

      /// \brief Calculate the header length.
      private: void UpdateHeaderLength();

      /// \brief Version of the transport library.
      private: uint16_t version;

      /// \brief Global identifier. Every process has a unique guid.
      private: uuid_t guid;

      /// \brief Topic length in bytes.
      private: uint16_t topicLength;

      /// \brief Topic.
      private:std::string topic;

      /// \brief Message type (ADVERTISE, SUBSCRIPTION, ...).
      private: uint8_t type;

      /// \brief Optional flags that you want to include in the header.
      private: uint16_t flags;

      /// \brief Header length.
      private: int headerLength;
    };

    /// \class AdvMsg Packet.hh
    /// \brief Advertise message used in the discovery protocol to broadcast
    /// information about the node advertising a topic. The information sent
    /// is the ZeroMQ end point addressy where the node will be receiving
    /// subscription requests.
    class AdvMsg
    {
      /// \brief Constructor.
      public: AdvMsg();

      /// \brief Constructor.
      /// \param[in] _header Message header
      /// \param[in] _address ZeroMQ address (e.g., "tcp://10.0.0.1:6000").
      public: AdvMsg(const Header &_header, const std::string &_address);

      /// \brief Get the message header.
      /// \return Reference to the message header.
      public: Header& GetHeader();

      /// \brief Get the address length.
      /// \brief Return the ZMQ address length (num of bytes).
      public: uint16_t GetAddressLength() const;

      /// \brief Get the ZMQ address.
      /// \return Return the ZMQ address.
      public: std::string GetAddress() const;

      /// \brief Set the header of the message.
      /// \param[in] _header Message header.
      public: void SetHeader(const Header &_header);

      /// \brief Set the ZMQ address.
      /// \param[in] _address ZMQ address to be contained in the message.
      public: void SetAddress(const std::string &_address);

      /// \brief Get the total length of the message.
      /// \return Return the length of the message in bytes.
      public: size_t GetMsgLength();

      /// \brief Print the message.
      public: void PrintBody();

      /// \brief Serialize the AdvMsg.
      /// \param[out] _buffer Buffer where the message will be serialized.
      /// \return The length of the serialized message in bytes.
      public: size_t Pack(char *_buffer);

      /// \brief Unserialize a stream of bytes into a AdvMsg.
      /// \param[out] _buffer Unpack the body from the buffer.
      /// \return The number of bytes from the body.
      public: size_t UnpackBody(char *_buffer);

      /// \brief Update the ADV message length.
      private: void UpdateMsgLength();

      /// \brief Message header
      private: Header header;

      /// \brief Length of the address contained in this message (bytes).
      private: uint16_t addressLength;

      /// \brief ZMQ valid address (e.g., "tcp://10.0.0.1:6000").
      private: std::string address;

      /// \brief Length of the message in bytes.
      private: int msgLength;
    };
  }
}

#endif
<|endoftext|>


<commit_before>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_constant.hpp
 * @brief		iris unit test 定数 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_
#define INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_

//======================================================================
// include

namespace iutest {
namespace detail
{

namespace helper
{

namespace
{

/**
 * @brief	文字列定数
*/
template<typename DMY>
struct kStringsT
{
	static const char* const DefaultXmlReportFileName;	//!< デフォルト xml 出力ファイル名
	static const char* const UnknownFile;				//!< unknown file
	static const char* const Null;						//!< NULL
};

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template struct kStringsT<void>;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#else

template<typename DMY>
const char* const kStringsT<DMY>::DefaultXmlReportFileName = "test_detail.xml";
template<typename DMY>
const char* const kStringsT<DMY>::UnknownFile = "unknown file";
template<typename DMY>
const char* const kStringsT<DMY>::Null = "(null)";

template struct kStringsT<void>;

#endif

}
}	// end of namespace helper

/** @internal */
typedef helper::kStringsT<void> kStrings;

/**
 * @brief	定数群
*/
struct kValues
{
#if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	enum
	{
		MaxPrintContainerCount = 32
		, PrintArrayThreshold = 16
		, PrintArrayChunksize = PrintArrayThreshold/2
	};
#else
	static const size_t MaxPrintContainerCount = 32;
	static const size_t PrintArrayThreshold = 18;
	static const size_t PrintArrayChunksize = PrintArrayThreshold/2;
#endif
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_
<commit_msg>update r1054 fix cpplint<commit_after>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_constant.hpp
 * @brief		iris unit test 定数 定義 ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_
#define INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_

//======================================================================
// include

namespace iutest {
namespace detail
{

namespace helper
{

namespace
{

/**
 * @brief	文字列定数
*/
template<typename DMY>
struct kStringsT
{
	static const char* const DefaultXmlReportFileName;	//!< デフォルト xml 出力ファイル名
	static const char* const UnknownFile;				//!< unknown file
	static const char* const Null;						//!< NULL
};

#if IUTEST_HAS_LIB && IUTEST_HAS_EXTERN_TEMPLATE

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_BEGIN()

extern template struct kStringsT<void>;

IUTEST_PRAGMA_EXTERN_TEMPLATE_WARN_DISABLE_END()

#else

template<typename DMY>
const char* const kStringsT<DMY>::DefaultXmlReportFileName = "test_detail.xml";
template<typename DMY>
const char* const kStringsT<DMY>::UnknownFile = "unknown file";
template<typename DMY>
const char* const kStringsT<DMY>::Null = "(null)";

template struct kStringsT<void>;

#endif

}	// namespace
}	// end of namespace helper

/** @internal */
typedef helper::kStringsT<void> kStrings;

/**
 * @brief	定数群
*/
struct kValues
{
#if defined(IUTEST_NO_INCLASS_MEMBER_INITIALIZATION)
	enum
	{
		MaxPrintContainerCount = 32
		, PrintArrayThreshold = 16
		, PrintArrayChunksize = PrintArrayThreshold/2
	};
#else
	static const size_t MaxPrintContainerCount = 32;
	static const size_t PrintArrayThreshold = 18;
	static const size_t PrintArrayChunksize = PrintArrayThreshold/2;
#endif
};

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_CONSTANT_HPP_37DDDC13_3259_42E0_A648_47B064DED4BA_
<|endoftext|>


<commit_before>#ifndef KGR_INCLUDE_KANGARU_OPERATOR_SERVICE
#define KGR_INCLUDE_KANGARU_OPERATOR_SERVICE

#include "container.hpp"
#include "operator.hpp"

namespace kgr {

template<typename Predicate = All>
struct ForkService {
	explicit ForkService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	inline Container forward() {
		return std::move(_container);
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

template<template<typename> class Map>
struct InvokerService {
	explicit InvokerService(in_place_t, Container& container) : _container{container} {}

	Invoker<Map> forward() {
		return Invoker<Map>{_container};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container& _container;
};

template<template<typename> class Map, typename Predicate = All>
struct ForkedInvokerService {
	explicit ForkedInvokerService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	ForkedInvoker<Map> forward() {
		return ForkedInvoker<Map>{std::move(_container)};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

template<typename T>
struct GeneratorService {
	explicit GeneratorService(in_place_t, Container& container) : _container{container} {}

	Generator<T> forward() {
		return Generator<T>{_container};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container& _container;
};

template<typename T, typename Predicate = All>
struct ForkedGeneratorService {
	explicit ForkedGeneratorService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	ForkedGenerator<T> forward() {
		return ForkedGenerator<T>{std::move(_container)};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

template<typename T>
struct LazyService {
	explicit LazyService(in_place_t, Container& container) : _container{container} {}

	Lazy<T> forward() {
		return Lazy<T>{_container};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container& _container;
};

template<typename T, typename Predicate = All>
struct ForkedLazyService {
	explicit ForkedLazyService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	ForkedLazy<T> forward() {
		return ForkedLazy<T>{std::move(_container)};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

} // namespace kgr

#endif // KGR_INCLUDE_KANGARU_OPERATOR_SERVICE
<commit_msg>added DefaultForkService to mimic the old behaviour<commit_after>#ifndef KGR_INCLUDE_KANGARU_OPERATOR_SERVICE
#define KGR_INCLUDE_KANGARU_OPERATOR_SERVICE

#include "container.hpp"
#include "operator.hpp"

namespace kgr {

template<typename Predicate>
struct ForkService {
	explicit ForkService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	inline Container forward() {
		return std::move(_container);
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

using DefaultForkService = ForkService<All>;

template<template<typename> class Map>
struct InvokerService {
	explicit InvokerService(in_place_t, Container& container) : _container{container} {}

	Invoker<Map> forward() {
		return Invoker<Map>{_container};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container& _container;
};

template<template<typename> class Map, typename Predicate = All>
struct ForkedInvokerService {
	explicit ForkedInvokerService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	ForkedInvoker<Map> forward() {
		return ForkedInvoker<Map>{std::move(_container)};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

template<typename T>
struct GeneratorService {
	explicit GeneratorService(in_place_t, Container& container) : _container{container} {}

	Generator<T> forward() {
		return Generator<T>{_container};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container& _container;
};

template<typename T, typename Predicate = All>
struct ForkedGeneratorService {
	explicit ForkedGeneratorService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	ForkedGenerator<T> forward() {
		return ForkedGenerator<T>{std::move(_container)};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

template<typename T>
struct LazyService {
	explicit LazyService(in_place_t, Container& container) : _container{container} {}

	Lazy<T> forward() {
		return Lazy<T>{_container};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container& _container;
};

template<typename T, typename Predicate = All>
struct ForkedLazyService {
	explicit ForkedLazyService(in_place_t, Container& container) : _container{container.fork<Predicate>()} {}

	ForkedLazy<T> forward() {
		return ForkedLazy<T>{std::move(_container)};
	}

	static auto construct(Inject<ContainerService> cs) -> decltype(inject(cs.forward())) {
		return inject(cs.forward());
	}

private:
	Container _container;
};

} // namespace kgr

#endif // KGR_INCLUDE_KANGARU_OPERATOR_SERVICE
<|endoftext|>


<commit_before>#ifdef NN_ACCEL_GPU
#ifndef NVBLAS_TPP
#define NVBLAS_TPP

#include <nvblas.h>

namespace nnlib
{

template <>
void Math<float>::mAdd_mm(size_t M, size_t N, size_t K, const float *A, size_t lda, const float *B, size_t ldb, float *C, size_t ldc, float alpha, float beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("N", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<double>::mAdd_mm(size_t M, size_t N, size_t K, const double *A, size_t lda, const double *B, size_t ldb, double *C, size_t ldc, double alpha, double beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	dgemm("N", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<float>::mAdd_mtm(size_t M, size_t N, size_t K, const float *A, size_t lda, const float *B, size_t ldb, float *C, size_t ldc, float alpha, float beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("N", "T", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<double>::mAdd_mtm(size_t M, size_t N, size_t K, const double *A, size_t lda, const double *B, size_t ldb, double *C, size_t ldc, double alpha, double beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	dgemm("N", "T", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<float>::mAdd_mmt(size_t M, size_t N, size_t K, const float *A, size_t lda, const float *B, size_t ldb, float *C, size_t ldc, float alpha, float beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("T", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<float>::mAdd_mmt(size_t M, size_t N, size_t K, const double *A, size_t lda, const double *B, size_t ldb, double *C, size_t ldc, double alpha, double beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("T", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

}

#endif
#endif
<commit_msg>Fixed a problem with nvblas.<commit_after>#ifdef NN_ACCEL_GPU
#ifndef NVBLAS_TPP
#define NVBLAS_TPP

#include <nvblas.h>

namespace nnlib
{

template <>
void Math<float>::mAdd_mm(size_t M, size_t N, size_t K, const float *A, size_t lda, const float *B, size_t ldb, float *C, size_t ldc, float alpha, float beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("N", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<double>::mAdd_mm(size_t M, size_t N, size_t K, const double *A, size_t lda, const double *B, size_t ldb, double *C, size_t ldc, double alpha, double beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	dgemm("N", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<float>::mAdd_mtm(size_t M, size_t N, size_t K, const float *A, size_t lda, const float *B, size_t ldb, float *C, size_t ldc, float alpha, float beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("N", "T", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<double>::mAdd_mtm(size_t M, size_t N, size_t K, const double *A, size_t lda, const double *B, size_t ldb, double *C, size_t ldc, double alpha, double beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	dgemm("N", "T", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<float>::mAdd_mmt(size_t M, size_t N, size_t K, const float *A, size_t lda, const float *B, size_t ldb, float *C, size_t ldc, float alpha, float beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	sgemm("T", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

template <>
void Math<double>::mAdd_mmt(size_t M, size_t N, size_t K, const double *A, size_t lda, const double *B, size_t ldb, double *C, size_t ldc, double alpha, double beta)
{
	int m = (int) M, n = (int) N, k = (int) K, a = (int) lda, b = (int) ldb, c = (int) ldc;
	dgemm("T", "N", &n, &m, &k, &alpha, B, &b, A, &a, &beta, C, &c);
}

}

#endif
#endif
<|endoftext|>


<commit_before>#pragma once
#include <memory>
#include <functional>

namespace th
{
template<typename BaseType>
class PolymorphicWrapper
{
    public:
    template<typename DerivedType>
    PolymorphicWrapper(DerivedType&& derived)
    {
        using DecayedType = typename std::decay<DerivedType>::type;
        static_assert(std::is_base_of<BaseType, DecayedType>::value, "Can only be constructed from types that inherit BaseType");

        mCopyFunction = [] (const std::unique_ptr<BaseType>& derivedToCopy)
        {
            const auto originalPtr = static_cast<DecayedType*>(derivedToCopy.get());
            return std::unique_ptr<BaseType>(new DecayedType(*originalPtr)); //uses the normal copy mechanics of the DecayedType class
        };

        mValue.reset(new DecayedType(derived));
    }

    PolymorphicWrapper(const PolymorphicWrapper& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
    }

    PolymorphicWrapper(PolymorphicWrapper&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
    }

    PolymorphicWrapper& operator=(const PolymorphicWrapper& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
        return *this;
    }

    PolymorphicWrapper& operator=(PolymorphicWrapper&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
        return *this;
    }

    const BaseType& operator*() const
    {
        return *mValue;
    }

    BaseType& operator*()
    {
        return *mValue;
    }

    const BaseType* operator->() const
    {
        return mValue.get();
    }

    BaseType* operator->()
    {
        return mValue.get();
    }

    private:
    std::function<std::unique_ptr<BaseType>(const std::unique_ptr<BaseType>&)> mCopyFunction;
    std::unique_ptr<BaseType> mValue;
};
}
<commit_msg>Now uses std::forward<commit_after>#pragma once
#include <memory>
#include <functional>

namespace th
{
template<typename BaseType>
class PolymorphicWrapper
{
    public:
    template<typename DerivedType>
    PolymorphicWrapper(DerivedType&& derived)
    {
        using DecayedType = typename std::decay<DerivedType>::type;
        static_assert(std::is_base_of<BaseType, DecayedType>::value, "Can only be constructed from types that inherit BaseType");

        mCopyFunction = [] (const std::unique_ptr<BaseType>& derivedToCopy)
        {
            const auto originalPtr = static_cast<DecayedType*>(derivedToCopy.get());
            return std::unique_ptr<BaseType>(new DecayedType(*originalPtr)); //uses the normal copy mechanics of the DecayedType class
        };

        mValue.reset(new DecayedType(std::forward<DerivedType>(derived)));
    }

    PolymorphicWrapper(const PolymorphicWrapper& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
    }

    PolymorphicWrapper(PolymorphicWrapper&& other)
    {
        mCopyFunction = std::move(other.mCopyFunction);
        mValue = std::move(other.mValue);
    }

    PolymorphicWrapper& operator=(const PolymorphicWrapper& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = mCopyFunction(other.mValue); //uses stored lambda to copy
        return *this;
    }

    PolymorphicWrapper& operator=(PolymorphicWrapper&& other)
    {
        mCopyFunction = other.mCopyFunction;
        mValue = std::move(other.mValue);
        return *this;
    }

    const BaseType& operator*() const
    {
        return *mValue;
    }

    BaseType& operator*()
    {
        return *mValue;
    }

    const BaseType* operator->() const
    {
        return mValue.get();
    }

    BaseType* operator->()
    {
        return mValue.get();
    }

    private:
    std::function<std::unique_ptr<BaseType>(const std::unique_ptr<BaseType>&)> mCopyFunction;
    std::unique_ptr<BaseType> mValue;
};
}
<|endoftext|>


<commit_before>#include "model.h"
#include "modelwidget.h"
#include "figurepainter.h"
#include "recognition.h"
#include "layouting.h"
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QTimer>
#include <iostream>

Ui::ModelWidget::ModelWidget(QWidget *parent) :
    QWidget(parent), trackIsCancelled(false), _gridStep(0) {
    setFocusPolicy(Qt::FocusPolicy::StrongFocus);
}

void drawTrack(QPainter &painter, FigurePainter &fpainter, const Track &track) {
    for (size_t i = 0; i + 1 < track.size(); i++) {
        painter.drawLine(fpainter.scale(track[i]), fpainter.scale(track[i + 1]));
    }
}

int Ui::ModelWidget::gridStep() {
    return _gridStep;
}

void Ui::ModelWidget::setGridStep(int newGridStep) {
    if (newGridStep < 0) {
        throw std::runtime_error("Grid step should be >= 0");
    }
    _gridStep = newGridStep;
}

void Ui::ModelWidget::setModel(Model model) {
    commitedModel = std::move(model);
    previousModels.clear();
    redoModels.clear();
    emit canUndoChanged();
    emit canRedoChanged();
}
Model &Ui::ModelWidget::getModel() {
    return commitedModel;
}

bool Ui::ModelWidget::canUndo() {
    return !previousModels.empty();
}

void Ui::ModelWidget::undo() {
    if (!canUndo()) {
        throw std::runtime_error("Cannot undo");
    }
    redoModels.push_front(std::move(commitedModel));
    commitedModel = std::move(previousModels.back());
    previousModels.pop_back();
    if (!canUndo()) {
        emit canUndoChanged();
    }
    emit canRedoChanged();
    repaint();
}

bool Ui::ModelWidget::canRedo() {
    return !redoModels.empty();
}

void Ui::ModelWidget::redo() {
    if (!canRedo()) {
        throw std::runtime_error("Cannot redo");
    }
    previousModels.push_back(std::move(commitedModel));
    commitedModel = std::move(redoModels.front());
    redoModels.pop_front();
    if (!canRedo()) {
        canRedoChanged();
    }
    canUndoChanged();
    repaint();
}

double roundUpToMultiple(double x, double multiple) {
    return ceil(x / multiple) * multiple;
}

void Ui::ModelWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.fillRect(QRect(QPoint(), size()), Qt::white);

    painter.setPen(Qt::black);

    FigurePainter fpainter(painter);
    if (gridStep() > 0) {
        int step = gridStep();
        // Calculating visible area
        Point p1 = fpainter.unscale(QPointF(0, 0));
        Point p2 = fpainter.unscale(QPointF(width(), height()));
        if (p1.x > p2.x) { std::swap(p1.x, p2.x); }
        if (p1.y > p2.y) { std::swap(p1.y, p2.y); }

        // Finding starting point for the grid
        p1.x = roundUpToMultiple(p1.x, step);
        p1.y = roundUpToMultiple(p1.y, step);

        // Drawing
        QPen pen(QColor(192, 192, 192, 255));
        pen.setStyle(Qt::DashLine);
        painter.setPen(pen);
        for (int x = p1.x; x <= p2.x; x += step) {
            painter.drawLine(fpainter.scale(Point(x, p1.y)), fpainter.scale(Point(x, p2.y)));
        }
        for (int y = p1.y; y <= p2.y; y += step) {
            painter.drawLine(fpainter.scale(Point(p1.x, y)), fpainter.scale(Point(p2.x, y)));
        }
    }

    Model modelToDraw = commitedModel;
    PFigure modified = recognize(lastTrack, modelToDraw);
    for (PFigure fig : modelToDraw) {
        if (fig == modified) {
            painter.setPen(Qt::magenta);
        } else if (fig == modelToDraw.selectedFigure) {
            painter.setPen(Qt::blue);
        } else {
            painter.setPen(Qt::black);
        }
        fig->visit(fpainter);
    }

    QPen pen(QColor(255, 0, 0, 16));
    pen.setWidth(3);
    painter.setPen(pen);
    drawTrack(painter, fpainter, lastTrack);
    for (const Track &track : visibleTracks) {
        drawTrack(painter, fpainter, track);
    }
}

void Ui::ModelWidget::mousePressEvent(QMouseEvent *event) {
    lastTrack = Track();
    trackIsCancelled = false;
    lastTrack.points.push_back(Point(event->pos().x(), event->pos().y()));
    repaint();
}
void Ui::ModelWidget::mouseMoveEvent(QMouseEvent *event) {
    lastTrack.points.push_back(Point(event->pos().x(), event->pos().y()));
    repaint();
}
void Ui::ModelWidget::mouseReleaseEvent(QMouseEvent *event) {
    if (trackIsCancelled) {
        return;
    }
    lastTrack.points.push_back(Point(event->pos().x(), event->pos().y()));
    Model previousModel = commitedModel;
    PFigure modifiedFigure = recognize(lastTrack, commitedModel);
    if (_gridStep > 0 && modifiedFigure) {
        GridAlignLayouter layouter(_gridStep);
        layouter.updateLayout(commitedModel, modifiedFigure);
    }

    visibleTracks.push_back(lastTrack);
    auto iterator = --visibleTracks.end();
    QTimer *timer = new QTimer(this);

    connect(timer, &QTimer::timeout, [this, iterator, timer]() {
        visibleTracks.erase(iterator);
        delete timer;
        repaint();
    });
    timer->setInterval(1500);
    timer->setSingleShot(true);
    timer->start();

    lastTrack = Track();
    if (modifiedFigure) {
        previousModels.push_back(previousModel);
        redoModels.clear();
        emit canUndoChanged();
        emit canRedoChanged();
    }
    repaint();
}
void Ui::ModelWidget::keyReleaseEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Escape) {
        lastTrack = Track();
        trackIsCancelled = true;
        repaint();
    }
    if (event->key() == Qt::Key_Delete) {
        if (commitedModel.selectedFigure) {
            previousModels.push_back(commitedModel);
            redoModels.clear();
            for (auto it = commitedModel.begin(); it != commitedModel.end(); it++) {
                if (*it == commitedModel.selectedFigure) {
                    commitedModel.removeFigure(it);
                    break;
                }
            }
            emit canUndoChanged();
            emit canRedoChanged();
            repaint();
        }
    }
}
<commit_msg>modelwidget.paint: now it does not copy model if there is no active track to recognize<commit_after>#include "model.h"
#include "modelwidget.h"
#include "figurepainter.h"
#include "recognition.h"
#include "layouting.h"
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QTimer>
#include <iostream>

Ui::ModelWidget::ModelWidget(QWidget *parent) :
    QWidget(parent), trackIsCancelled(false), _gridStep(0) {
    setFocusPolicy(Qt::FocusPolicy::StrongFocus);
}

void drawTrack(QPainter &painter, FigurePainter &fpainter, const Track &track) {
    for (size_t i = 0; i + 1 < track.size(); i++) {
        painter.drawLine(fpainter.scale(track[i]), fpainter.scale(track[i + 1]));
    }
}

int Ui::ModelWidget::gridStep() {
    return _gridStep;
}

void Ui::ModelWidget::setGridStep(int newGridStep) {
    if (newGridStep < 0) {
        throw std::runtime_error("Grid step should be >= 0");
    }
    _gridStep = newGridStep;
}

void Ui::ModelWidget::setModel(Model model) {
    commitedModel = std::move(model);
    previousModels.clear();
    redoModels.clear();
    emit canUndoChanged();
    emit canRedoChanged();
}
Model &Ui::ModelWidget::getModel() {
    return commitedModel;
}

bool Ui::ModelWidget::canUndo() {
    return !previousModels.empty();
}

void Ui::ModelWidget::undo() {
    if (!canUndo()) {
        throw std::runtime_error("Cannot undo");
    }
    redoModels.push_front(std::move(commitedModel));
    commitedModel = std::move(previousModels.back());
    previousModels.pop_back();
    if (!canUndo()) {
        emit canUndoChanged();
    }
    emit canRedoChanged();
    repaint();
}

bool Ui::ModelWidget::canRedo() {
    return !redoModels.empty();
}

void Ui::ModelWidget::redo() {
    if (!canRedo()) {
        throw std::runtime_error("Cannot redo");
    }
    previousModels.push_back(std::move(commitedModel));
    commitedModel = std::move(redoModels.front());
    redoModels.pop_front();
    if (!canRedo()) {
        canRedoChanged();
    }
    canUndoChanged();
    repaint();
}

double roundUpToMultiple(double x, double multiple) {
    return ceil(x / multiple) * multiple;
}

void Ui::ModelWidget::paintEvent(QPaintEvent *) {
    QPainter painter(this);
    painter.fillRect(QRect(QPoint(), size()), Qt::white);

    painter.setPen(Qt::black);

    FigurePainter fpainter(painter);
    if (gridStep() > 0) {
        int step = gridStep();
        // Calculating visible area
        Point p1 = fpainter.unscale(QPointF(0, 0));
        Point p2 = fpainter.unscale(QPointF(width(), height()));
        if (p1.x > p2.x) { std::swap(p1.x, p2.x); }
        if (p1.y > p2.y) { std::swap(p1.y, p2.y); }

        // Finding starting point for the grid
        p1.x = roundUpToMultiple(p1.x, step);
        p1.y = roundUpToMultiple(p1.y, step);

        // Drawing
        QPen pen(QColor(192, 192, 192, 255));
        pen.setStyle(Qt::DashLine);
        painter.setPen(pen);
        for (int x = p1.x; x <= p2.x; x += step) {
            painter.drawLine(fpainter.scale(Point(x, p1.y)), fpainter.scale(Point(x, p2.y)));
        }
        for (int y = p1.y; y <= p2.y; y += step) {
            painter.drawLine(fpainter.scale(Point(p1.x, y)), fpainter.scale(Point(p2.x, y)));
        }
    }

    Model copiedModel;
    Model &modelToDraw = lastTrack.empty() ? commitedModel : (copiedModel = commitedModel);
    PFigure modified = recognize(lastTrack, modelToDraw);
    for (PFigure fig : modelToDraw) {
        if (fig == modified) {
            painter.setPen(Qt::magenta);
        } else if (fig == modelToDraw.selectedFigure) {
            painter.setPen(Qt::blue);
        } else {
            painter.setPen(Qt::black);
        }
        fig->visit(fpainter);
    }

    QPen pen(QColor(255, 0, 0, 16));
    pen.setWidth(3);
    painter.setPen(pen);
    drawTrack(painter, fpainter, lastTrack);
    for (const Track &track : visibleTracks) {
        drawTrack(painter, fpainter, track);
    }
}

void Ui::ModelWidget::mousePressEvent(QMouseEvent *event) {
    lastTrack = Track();
    trackIsCancelled = false;
    lastTrack.points.push_back(Point(event->pos().x(), event->pos().y()));
    repaint();
}
void Ui::ModelWidget::mouseMoveEvent(QMouseEvent *event) {
    lastTrack.points.push_back(Point(event->pos().x(), event->pos().y()));
    repaint();
}
void Ui::ModelWidget::mouseReleaseEvent(QMouseEvent *event) {
    if (trackIsCancelled) {
        return;
    }
    lastTrack.points.push_back(Point(event->pos().x(), event->pos().y()));
    Model previousModel = commitedModel;
    PFigure modifiedFigure = recognize(lastTrack, commitedModel);
    if (_gridStep > 0 && modifiedFigure) {
        GridAlignLayouter layouter(_gridStep);
        layouter.updateLayout(commitedModel, modifiedFigure);
    }

    visibleTracks.push_back(lastTrack);
    auto iterator = --visibleTracks.end();
    QTimer *timer = new QTimer(this);

    connect(timer, &QTimer::timeout, [this, iterator, timer]() {
        visibleTracks.erase(iterator);
        delete timer;
        repaint();
    });
    timer->setInterval(1500);
    timer->setSingleShot(true);
    timer->start();

    lastTrack = Track();
    if (modifiedFigure) {
        previousModels.push_back(previousModel);
        redoModels.clear();
        emit canUndoChanged();
        emit canRedoChanged();
    }
    repaint();
}
void Ui::ModelWidget::keyReleaseEvent(QKeyEvent *event) {
    if (event->key() == Qt::Key_Escape) {
        lastTrack = Track();
        trackIsCancelled = true;
        repaint();
    }
    if (event->key() == Qt::Key_Delete) {
        if (commitedModel.selectedFigure) {
            previousModels.push_back(commitedModel);
            redoModels.clear();
            for (auto it = commitedModel.begin(); it != commitedModel.end(); it++) {
                if (*it == commitedModel.selectedFigure) {
                    commitedModel.removeFigure(it);
                    break;
                }
            }
            emit canUndoChanged();
            emit canRedoChanged();
            repaint();
        }
    }
}
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: %cling %s "args(42)" -Xclang -verify 2>&1 | FileCheck %s

//CHECK-NOT: {{.*error|warning|note:.*}}

extern "C" int printf(const char* fmt, ...);
void args(int I, const char* S = "ArgString") {
   printf("I=%d\n", I); // CHECK: I=42
   printf("S=%s\n", S); // CHECK: S=ArgString
}
// expected-no-diagnostics
<commit_msg>We cannot pass in a 'proper' source location, thus we cannot use -verify.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// RUN: %cling %s "args(42)" 2>&1 | FileCheck %s

//CHECK-NOT: {{.*error|note:.*}}
//CHECK: warning: function 'args' cannot be called with no arguments.
extern "C" int printf(const char* fmt, ...);
void args(int I, const char* S = "ArgString") {
   printf("I=%d\n", I); // CHECK: I=42
   printf("S=%s\n", S); // CHECK: S=ArgString
}
<|endoftext|>


<commit_before>#include "codeccomparisonwindow.h"
#include "ui_codeccomparisonwindow.h"

CodecComparisonWindow::CodecComparisonWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::CodecComparisonWindow) {
    ui->setupUi(this);

    initCodecs();
    initVlc();
    connectSlots();

    // prints probe output to standard output
    //probeProcess.setProcessChannelMode(QProcess::ForwardedChannels);

    ui->frameTypes->setReadOnly(true);
    ui->tabWidget->setCurrentIndex(0);
}

CodecComparisonWindow::~CodecComparisonWindow() { delete ui; }

void CodecComparisonWindow::closeEvent(QCloseEvent *event) {
    (void)event; // silence annoying warning
    streamingProcess.kill();
    probeProcess.kill();

    streamingProcess.waitForFinished();
    probeProcess.waitForFinished();
}

void CodecComparisonWindow::readOutput() {
    while (probeProcess.canReadLine()) {
        QString output = probeProcess.readLine();

        if (output.startsWith("pict_type=")) {
            typesOfFrames.enqueue(output.toUtf8().constData()[10]);
            if (typesOfFrames.size() > 16)
                typesOfFrames.dequeue();

            QString currentFrameTypes;

            QListIterator<char> i(typesOfFrames);

            while (i.hasNext()) {
                currentFrameTypes.append(i.next());
            }

            ui->frameTypes->setText(currentFrameTypes);
        }
    }
}

QString CodecComparisonWindow::buildStreamingCommand(
    QString inputParameters, QString inputLocation,
    QVector<QString> outputPrameters, QVector<QString> outputLocations) {
    QStringList list;
    list << FFMPEG;
    list << inputParameters;
    list << "-i " << inputLocation;
    for (int i = 0;
         i < outputPrameters.length() && i < outputLocations.length(); i++) {
        list << outputPrameters[i] << outputLocations[i];
    }

    QString command = list.join(" ");
    qDebug() << "Produced the following encoding command:\n"
             << command.toUtf8().constData();
    return command;
}

QString CodecComparisonWindow::buildProbeCommand(QString location) {
    QStringList list;
    list << FFPROBE;
    list << location;
    list << "-show_frames";

    QString command = list.join(" ");
    qDebug() << "Produced the following probe command:\n"
             << command.toUtf8().constData();
    return command;
}

void CodecComparisonWindow::broadcast() {
    if (inputLocation.isEmpty()) {
        qDebug() << "Input location is missing! Not starting player.";
        return;
    }
    if (inputParameters.isEmpty()) {
        qDebug() << "Input parameters are missing! Not starting player.";
        return;
    }
    QString streamingParameters =
        codecManagers.at(ui->tabWidget->currentIndex())
            ->getStreamingParameters();
    if (streamingParameters.isEmpty()) {
        qDebug() << "Encoding parameters are missing! Not starting player.";
        return;
    }

    typesOfFrames.clear();
    ui->frameTypes->setText("");

    qDebug() << "Stopping the players...";
    vlcPlayerRaw->stop();
    vlcPlayerEncoded->stop();

    qDebug() << "Killing current encoding and probe processes...";
    streamingProcess.kill();
    probeProcess.kill();

    streamingProcess.waitForFinished();
    probeProcess.waitForFinished();

    qDebug() << "Starting the encoding process...";
    QString streamingCommand = buildStreamingCommand(
        inputParameters, inputLocation,
        {"-c:v copy -f nut -an", streamingParameters},
        {RAW_VIDEO_PROTOCOL + "://" + RAW_VIDEO_HOST + ":" + RAW_VIDEO_PORT,
         ENCODED_VIDEO_PROTOCOL + "://" + ENCODED_VIDEO_HOST + ":" +
             ENCODED_VIDEO_PORT, VIDEO_PROBE_PROTOCOL + "://" + VIDEO_PROBE_HOST + ":" + VIDEO_PROBE_PORT});
    streamingProcess.start(streamingCommand);

    qDebug() << "Starting the probe process...";
    QString probeCommand =
        buildProbeCommand(VIDEO_PROBE_PROTOCOL + "://" + VIDEO_PROBE_HOST +
                          ":" + VIDEO_PROBE_PORT);
    probeProcess.start(probeCommand);

    qDebug() << "Starting the players...";
    vlcPlayerRaw->setTime(0);
    vlcPlayerEncoded->setTime(0);
    vlcPlayerRaw->play();
    vlcPlayerEncoded->play();
}

void CodecComparisonWindow::on_actionOpenFile_triggered() {
    QString filePath = QFileDialog::getOpenFileName(
        this, tr("Open file"), QDir::homePath(), tr("Multimedia files (*)"),
        Q_NULLPTR, QFileDialog::DontUseNativeDialog);
    if (!filePath.isEmpty()) {
        inputParameters = "-re";
        inputLocation = "\"" + filePath + "\"";
        settingsChanged();
    }
}

void CodecComparisonWindow::on_actionOpenCamera_triggered() {
#ifdef Q_OS_WIN
    inputParameters = "-f dshow";
    inputLocation = "video=\"Lenovo EasyCamera\"";
    settingsChanged();
#else
    inputParameters = "-f v4l2";
    inputLocation = "/dev/video0";
    settingsChanged();
#endif
}

void CodecComparisonWindow::initCodecs() {
    codecManagers.push_back(new MJPEGManager());
    codecManagers.push_back(new H261Manager());
    codecManagers.push_back(new MPEG1Manager());
    codecManagers.push_back(new MPEG2Manager());
    codecManagers.push_back(new H264Manager());
    codecManagers.push_back(new H265Manager());
}

void CodecComparisonWindow::initVlc() {
    vlcInstance = new VlcInstance(VlcCommon::args(), NULL);
    // vlcInstance->setLogLevel(Vlc::DisabledLevel);

    // Initialise raw video display
    vlcPlayerRaw = new VlcMediaPlayer(vlcInstance);
    vlcPlayerRaw->setVideoWidget(ui->rawVideo);
    vlcPlayerRaw->audio()->setMute(true);
    ui->rawVideo->setMediaPlayer(vlcPlayerRaw);
    vlcMediaRaw = new VlcMedia(RAW_VIDEO_PROTOCOL + "://@" + RAW_VIDEO_HOST +
                                   ":" + RAW_VIDEO_PORT,
                               false, vlcInstance);
    vlcPlayerRaw->openOnly(vlcMediaRaw);

    // Initialise encoded video display
    vlcPlayerEncoded = new VlcMediaPlayer(vlcInstance);
    vlcPlayerEncoded->setVideoWidget(ui->encodedVideo);
    vlcPlayerEncoded->audio()->setMute(true);
    ui->encodedVideo->setMediaPlayer(vlcPlayerEncoded);
    vlcMediaEncoded =
        new VlcMedia(ENCODED_VIDEO_PROTOCOL + "://@" + ENCODED_VIDEO_HOST +
                         ":" + ENCODED_VIDEO_PORT,
                     false, vlcInstance);
    vlcPlayerEncoded->openOnly(vlcMediaEncoded);
}

void CodecComparisonWindow::connectSlots() {

    connect(this, &CodecComparisonWindow::settingsChanged, this,
            &CodecComparisonWindow::broadcast);
    connect(ui->tabWidget, &QTabWidget::currentChanged, this,
            &CodecComparisonWindow::broadcast);

    // Provide debug info for raw player
    connect(vlcPlayerRaw, &VlcMediaPlayer::stopped,
            []() { qDebug() << "vlcPlayerRaw stopped"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::playing,
            []() { qDebug() << "vlcPlayerRaw playing"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::paused,
            []() { qDebug() << "vlcPlayerRaw paused"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::end,
            []() { qDebug() << "vlcPlayerRaw end"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::error,
            []() { qDebug() << "vlcPlayerRaw error"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::opening,
            []() { qDebug() << "vlcPlayerRaw opening"; });

    // Provide debug info for encoded player
    connect(vlcPlayerEncoded, &VlcMediaPlayer::stopped,
            []() { qDebug() << "vlcPlayerEncoded stopped"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::playing,
            []() { qDebug() << "vlcPlayerEncoded playing"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::paused,
            []() { qDebug() << "vlcPlayerEncoded paused"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::end,
            []() { qDebug() << "vlcPlayerEncoded end"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::error,
            []() { qDebug() << "vlcPlayerEncoded error"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::opening,
            []() { qDebug() << "vlcPlayerEncoded opening"; });

    connect(&probeProcess, &QProcess::readyRead, this,
            &CodecComparisonWindow::readOutput);
}
<commit_msg>fixed frame types<commit_after>#include "codeccomparisonwindow.h"
#include "ui_codeccomparisonwindow.h"

CodecComparisonWindow::CodecComparisonWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::CodecComparisonWindow) {
    ui->setupUi(this);

    initCodecs();
    initVlc();
    connectSlots();

    // prints probe output to standard output
    //probeProcess.setProcessChannelMode(QProcess::ForwardedChannels);

    ui->frameTypes->setReadOnly(true);
    ui->tabWidget->setCurrentIndex(0);
}

CodecComparisonWindow::~CodecComparisonWindow() { delete ui; }

void CodecComparisonWindow::closeEvent(QCloseEvent *event) {
    (void)event; // silence annoying warning
    streamingProcess.kill();
    probeProcess.kill();

    streamingProcess.waitForFinished();
    probeProcess.waitForFinished();
}

void CodecComparisonWindow::readOutput() {
    while (probeProcess.canReadLine()) {
        QString output = probeProcess.readLine();

        if (output.startsWith("pict_type=")) {
            typesOfFrames.enqueue(output.toUtf8().constData()[10]);
            if (typesOfFrames.size() > 16)
                typesOfFrames.dequeue();

            QString currentFrameTypes;

            QListIterator<char> i(typesOfFrames);

            while (i.hasNext()) {
                currentFrameTypes.append(i.next());
            }

            ui->frameTypes->setText(currentFrameTypes);
        }
    }
}

QString CodecComparisonWindow::buildStreamingCommand(
    QString inputParameters, QString inputLocation,
    QVector<QString> outputPrameters, QVector<QString> outputLocations) {
    QStringList list;
    list << FFMPEG;
    list << inputParameters;
    list << "-i " << inputLocation;
    for (int i = 0;
         i < outputPrameters.length() && i < outputLocations.length(); i++) {
        list << outputPrameters[i] << outputLocations[i];
    }

    QString command = list.join(" ");
    qDebug() << "Produced the following encoding command:\n"
             << command.toUtf8().constData();
    return command;
}

QString CodecComparisonWindow::buildProbeCommand(QString location) {
    QStringList list;
    list << FFPROBE;
    list << location;
    list << "-show_frames";

    QString command = list.join(" ");
    qDebug() << "Produced the following probe command:\n"
             << command.toUtf8().constData();
    return command;
}

void CodecComparisonWindow::broadcast() {
    if (inputLocation.isEmpty()) {
        qDebug() << "Input location is missing! Not starting player.";
        return;
    }
    if (inputParameters.isEmpty()) {
        qDebug() << "Input parameters are missing! Not starting player.";
        return;
    }
    QString streamingParameters =
        codecManagers.at(ui->tabWidget->currentIndex())
            ->getStreamingParameters();
    if (streamingParameters.isEmpty()) {
        qDebug() << "Encoding parameters are missing! Not starting player.";
        return;
    }

    typesOfFrames.clear();
    ui->frameTypes->setText("");

    qDebug() << "Stopping the players...";
    vlcPlayerRaw->stop();
    vlcPlayerEncoded->stop();

    qDebug() << "Killing current encoding and probe processes...";
    streamingProcess.kill();
    probeProcess.kill();

    streamingProcess.waitForFinished();
    probeProcess.waitForFinished();

    qDebug() << "Starting the encoding process...";
    QString streamingCommand = buildStreamingCommand(
        inputParameters, inputLocation,
        {"-c:v copy -f nut -an", streamingParameters, streamingParameters},
        {RAW_VIDEO_PROTOCOL + "://" + RAW_VIDEO_HOST + ":" + RAW_VIDEO_PORT,
         ENCODED_VIDEO_PROTOCOL + "://" + ENCODED_VIDEO_HOST + ":" + ENCODED_VIDEO_PORT,
         VIDEO_PROBE_PROTOCOL + "://" + VIDEO_PROBE_HOST + ":" + VIDEO_PROBE_PORT});
    streamingProcess.start(streamingCommand);

    qDebug() << "Starting the probe process...";
    QString probeCommand =
        buildProbeCommand(VIDEO_PROBE_PROTOCOL + "://" + VIDEO_PROBE_HOST +
                          ":" + VIDEO_PROBE_PORT);
    probeProcess.start(probeCommand);

    qDebug() << "Starting the players...";
    vlcPlayerRaw->setTime(0);
    vlcPlayerEncoded->setTime(0);
    vlcPlayerRaw->play();
    vlcPlayerEncoded->play();
}

void CodecComparisonWindow::on_actionOpenFile_triggered() {
    QString filePath = QFileDialog::getOpenFileName(
        this, tr("Open file"), QDir::homePath(), tr("Multimedia files (*)"),
        Q_NULLPTR, QFileDialog::DontUseNativeDialog);
    if (!filePath.isEmpty()) {
        inputParameters = "-re";
        inputLocation = "\"" + filePath + "\"";
        settingsChanged();
    }
}

void CodecComparisonWindow::on_actionOpenCamera_triggered() {
#ifdef Q_OS_WIN
    inputParameters = "-f dshow";
    inputLocation = "video=\"Lenovo EasyCamera\"";
    settingsChanged();
#else
    inputParameters = "-f v4l2";
    inputLocation = "/dev/video0";
    settingsChanged();
#endif
}

void CodecComparisonWindow::initCodecs() {
    codecManagers.push_back(new MJPEGManager());
    codecManagers.push_back(new H261Manager());
    codecManagers.push_back(new MPEG1Manager());
    codecManagers.push_back(new MPEG2Manager());
    codecManagers.push_back(new H264Manager());
    codecManagers.push_back(new H265Manager());
}

void CodecComparisonWindow::initVlc() {
    vlcInstance = new VlcInstance(VlcCommon::args(), NULL);
    // vlcInstance->setLogLevel(Vlc::DisabledLevel);

    // Initialise raw video display
    vlcPlayerRaw = new VlcMediaPlayer(vlcInstance);
    vlcPlayerRaw->setVideoWidget(ui->rawVideo);
    vlcPlayerRaw->audio()->setMute(true);
    ui->rawVideo->setMediaPlayer(vlcPlayerRaw);
    vlcMediaRaw = new VlcMedia(RAW_VIDEO_PROTOCOL + "://@" + RAW_VIDEO_HOST +
                                   ":" + RAW_VIDEO_PORT,
                               false, vlcInstance);
    vlcPlayerRaw->openOnly(vlcMediaRaw);

    // Initialise encoded video display
    vlcPlayerEncoded = new VlcMediaPlayer(vlcInstance);
    vlcPlayerEncoded->setVideoWidget(ui->encodedVideo);
    vlcPlayerEncoded->audio()->setMute(true);
    ui->encodedVideo->setMediaPlayer(vlcPlayerEncoded);
    vlcMediaEncoded =
        new VlcMedia(ENCODED_VIDEO_PROTOCOL + "://@" + ENCODED_VIDEO_HOST +
                         ":" + ENCODED_VIDEO_PORT,
                     false, vlcInstance);
    vlcPlayerEncoded->openOnly(vlcMediaEncoded);
}

void CodecComparisonWindow::connectSlots() {

    connect(this, &CodecComparisonWindow::settingsChanged, this,
            &CodecComparisonWindow::broadcast);
    connect(ui->tabWidget, &QTabWidget::currentChanged, this,
            &CodecComparisonWindow::broadcast);

    // Provide debug info for raw player
    connect(vlcPlayerRaw, &VlcMediaPlayer::stopped,
            []() { qDebug() << "vlcPlayerRaw stopped"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::playing,
            []() { qDebug() << "vlcPlayerRaw playing"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::paused,
            []() { qDebug() << "vlcPlayerRaw paused"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::end,
            []() { qDebug() << "vlcPlayerRaw end"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::error,
            []() { qDebug() << "vlcPlayerRaw error"; });
    connect(vlcPlayerRaw, &VlcMediaPlayer::opening,
            []() { qDebug() << "vlcPlayerRaw opening"; });

    // Provide debug info for encoded player
    connect(vlcPlayerEncoded, &VlcMediaPlayer::stopped,
            []() { qDebug() << "vlcPlayerEncoded stopped"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::playing,
            []() { qDebug() << "vlcPlayerEncoded playing"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::paused,
            []() { qDebug() << "vlcPlayerEncoded paused"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::end,
            []() { qDebug() << "vlcPlayerEncoded end"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::error,
            []() { qDebug() << "vlcPlayerEncoded error"; });
    connect(vlcPlayerEncoded, &VlcMediaPlayer::opening,
            []() { qDebug() << "vlcPlayerEncoded opening"; });

    connect(&probeProcess, &QProcess::readyRead, this,
            &CodecComparisonWindow::readOutput);
}
<|endoftext|>


<commit_before>
#ifndef Entity_HH_
#define Entity_HH_

#include <map>

#include "Core/Input.hh"
#include "Core/Timer.hh"
#include "Utils/SmartPointer.hh"
#include "OpenGL/Shader.hh"
#include "Utils/Barcode.h"
#include "Utils/PubSub.hpp"
#include "glm/glm.hpp"
#include <Components/Component.hh>

class AScene;
class EntityManager;
class Entity;

class EntityData : public PubSub
{
private:
	static size_t 					_currentId;
	Entity                          _handle;
public:
	enum	GetFlags
	{
		ONLY_THIS_FLAGS,
		THIS_FLAGS,
		NOT_THIS_FLAGS
	};

	enum	EntityFlags
	{
		HAS_MOVED = 1,
		ACTIVE = 2,

	};

	typedef std::vector<SmartPointer<Component::Base> >	t_ComponentsList;

	Entity &getHandle();
	void setHandle(Entity &handle);

private:
	AScene              *_scene;
	size_t 				_flags;

	glm::mat4 			_localTransform;
	glm::mat4 			_globalTransform;

	glm::vec3           _localRotation;
	glm::vec3           _localScale;
	glm::vec3           _localTranslation;

	glm::vec3           _globalRotation;
	glm::vec3           _globalScale;
	glm::vec3           _globalTranslation;

	t_ComponentsList	_components;

	Barcode _code;
public:
	EntityData(AScene *scene);
	virtual ~EntityData();

	AScene                  *getScene() const;
	void                    translate(const glm::vec3 &v);
	void                    setTranslation(const glm::vec3 &v);
	glm::vec3 const         &getTranslation() const;
	void                    rotate(const glm::vec3 &v);
	void                    setRotation(const glm::vec3 &v);
	glm::vec3 const         &getRotation() const;
	void                    scale(const glm::vec3 &v);
	void                    setScale(const glm::vec3 &v);
	glm::vec3 const         &getScale() const;

	glm::mat4 const  		&getLocalTransform();
	// TO DELETE
	glm::mat4   			&setLocalTransform();  // <-- //

	glm::mat4 const			&getGlobalTransform() const;
	// TO DELETE
	void 					computeGlobalTransform(glm::mat4 const &fatherTransform);  // <-- //
	void                    computeGlobalTransform(const Entity &parent);

	size_t 					getFlags() const;
	void 					setFlags(size_t flags);
	void 					addFlags(size_t flags);
	void 					removeFlags(size_t flags);

	Barcode &getCode();
	void reset();

	////////////////////////////
	//
	//
	// COMPONENTS OPERATIONS
	//
	//
	//
	bool hasComponent(unsigned int componentId) const;

	template <typename T>
	bool hasComponent() const
	{
		return _code.isSet<T>();
	}

	template <typename T, typename... Args>
	SmartPointer<T> addComponent(Args ...args)
	{
		// get the component type ID
		unsigned int id = T::getTypeId();

		auto a = _code.isEmpty();

		// if entity already have component, return it
		if (hasComponent(id))
		{
			return static_cast<SmartPointer<T> >(_components[id]);
		}
		// else if entity components array is to small, resize it
		else if (_components.size() <= id)
		{
			_components.resize(id + 1);
		}
		// if component has never been created, create one
		if (!_components[id].get())
		{
			_components[id] = new T();
			assert(_components[id].get() != nullptr && "Memory error : Component creation failed.");
			_components[id]->setEntity(getHandle());
		}
		//init component
		static_cast<SmartPointer<T> >(_components[id])->init(args...);
		_code.add(id);
		broadCast(std::string("componentAdded" + std::to_string(id)), _handle);
		return static_cast<SmartPointer<T> >(_components[id]);
	}

	template <typename T>
	SmartPointer<T> getComponent() const
	{
		unsigned int id = T::getTypeId();
		if (!hasComponent(id))
			return nullptr;
		return static_cast<SmartPointer<T> >(_components[id]);
	}

	template <typename T>
	void removeComponent()
	{
		unsigned int id = T::getTypeId();
		if (!hasComponent(id))
			return;
		_code.remove(id);
//		_components[id]	= nullptr;
		_components[id].get()->reset();
		broadCast(std::string("componentRemoved" + std::to_string(id)), _handle);
		// component remove -> signal to system
	}

	template <class Archive>
	void save(Archive &ar) const
	{
		unsigned int cptNumber = 0;
		for (auto &e : _components)
		{
			if (!e.get())
				continue;
			++cptNumber;
		}
		ar(cereal::make_nvp("component_number", cptNumber));
		for (auto &e : _components)
		{
			if (!e.get())
				continue;
//			ar(*e.get());
			e->serialize(ar);
		}
	}

	template <class Archive>
	void load(Archive &ar) const
	{
		unsigned int cptNumber = 0;
		ar(cptNumber);
		for (unsigned int i = 0; i < cptNumber; ++i)
		{
			std::size_t type = 0;
			unsigned int typeId;
			ar(type);
			unsigned int position;
			Component::Base *cpt = _scene->createFromType(type, ar, _handle, typeId);
			cpt->setEntity(_handle);
			if (_handle.get()->_components.size() <= typeId)
				_handle.get()->_components.resize(typeId + 1);
			_handle.get()->_components[typeId] = SmartPointer<Component::Base>(cpt);
			_handle.get()->_code.add(typeId);
			broadCast(std::string("componentAdded" + std::to_string(typeId)), _handle);
		}
		std::cout << "lol" << std::endl;
	}

};

#endif<commit_msg>Flags and transformations added to Entity serialization #37 # 38<commit_after>
#ifndef Entity_HH_
#define Entity_HH_

#include <map>

#include "Core/Input.hh"
#include "Core/Timer.hh"
#include "Utils/SmartPointer.hh"
#include "OpenGL/Shader.hh"
#include "Utils/Barcode.h"
#include "Utils/PubSub.hpp"
#include "glm/glm.hpp"
#include <Components/Component.hh>
#include <Utils/GlmSerialization.hpp>

class AScene;
class EntityManager;
class Entity;

class EntityData : public PubSub
{
private:
	static size_t 					_currentId;
	Entity                          _handle;
public:
	enum	GetFlags
	{
		ONLY_THIS_FLAGS,
		THIS_FLAGS,
		NOT_THIS_FLAGS
	};

	enum	EntityFlags
	{
		HAS_MOVED = 1,
		ACTIVE = 2,

	};

	typedef std::vector<SmartPointer<Component::Base> >	t_ComponentsList;

	Entity &getHandle();
	void setHandle(Entity &handle);

private:
	AScene              *_scene;
	size_t 				_flags;

	glm::mat4 			_localTransform;
	glm::mat4 			_globalTransform;

	glm::vec3           _localRotation;
	glm::vec3           _localScale;
	glm::vec3           _localTranslation;

	glm::vec3           _globalRotation;
	glm::vec3           _globalScale;
	glm::vec3           _globalTranslation;

	t_ComponentsList	_components;

	Barcode _code;
public:
	EntityData(AScene *scene);
	virtual ~EntityData();

	AScene                  *getScene() const;
	void                    translate(const glm::vec3 &v);
	void                    setTranslation(const glm::vec3 &v);
	glm::vec3 const         &getTranslation() const;
	void                    rotate(const glm::vec3 &v);
	void                    setRotation(const glm::vec3 &v);
	glm::vec3 const         &getRotation() const;
	void                    scale(const glm::vec3 &v);
	void                    setScale(const glm::vec3 &v);
	glm::vec3 const         &getScale() const;

	glm::mat4 const  		&getLocalTransform();
	// TO DELETE
	glm::mat4   			&setLocalTransform();  // <-- //

	glm::mat4 const			&getGlobalTransform() const;
	// TO DELETE
	void 					computeGlobalTransform(glm::mat4 const &fatherTransform);  // <-- //
	void                    computeGlobalTransform(const Entity &parent);

	size_t 					getFlags() const;
	void 					setFlags(size_t flags);
	void 					addFlags(size_t flags);
	void 					removeFlags(size_t flags);

	Barcode &getCode();
	void reset();

	////////////////////////////
	//
	//
	// COMPONENTS OPERATIONS
	//
	//
	//
	bool hasComponent(unsigned int componentId) const;

	template <typename T>
	bool hasComponent() const
	{
		return _code.isSet<T>();
	}

	template <typename T, typename... Args>
	SmartPointer<T> addComponent(Args ...args)
	{
		// get the component type ID
		unsigned int id = T::getTypeId();

		auto a = _code.isEmpty();

		// if entity already have component, return it
		if (hasComponent(id))
		{
			return static_cast<SmartPointer<T> >(_components[id]);
		}
		// else if entity components array is to small, resize it
		else if (_components.size() <= id)
		{
			_components.resize(id + 1);
		}
		// if component has never been created, create one
		if (!_components[id].get())
		{
			_components[id] = new T();
			assert(_components[id].get() != nullptr && "Memory error : Component creation failed.");
			_components[id]->setEntity(getHandle());
		}
		//init component
		static_cast<SmartPointer<T> >(_components[id])->init(args...);
		_code.add(id);
		broadCast(std::string("componentAdded" + std::to_string(id)), _handle);
		return static_cast<SmartPointer<T> >(_components[id]);
	}

	template <typename T>
	SmartPointer<T> getComponent() const
	{
		unsigned int id = T::getTypeId();
		if (!hasComponent(id))
			return nullptr;
		return static_cast<SmartPointer<T> >(_components[id]);
	}

	template <typename T>
	void removeComponent()
	{
		unsigned int id = T::getTypeId();
		if (!hasComponent(id))
			return;
		_code.remove(id);
//		_components[id]	= nullptr;
		_components[id].get()->reset();
		broadCast(std::string("componentRemoved" + std::to_string(id)), _handle);
		// component remove -> signal to system
	}

	template <class Archive>
	void save(Archive &ar) const
	{
		// Save Entity informations
		ar(cereal::make_nvp("flags", _flags),
			cereal::make_nvp("localTransform", _localTransform),
			cereal::make_nvp("globalTransform", _globalTransform));

		// Save Entity Components
		unsigned int cptNumber = 0;
		for (auto &e : _components)
		{
			if (!e.get())
				continue;
			++cptNumber;
		}
		ar(cereal::make_nvp("component_number", cptNumber));
		for (auto &e : _components)
		{
			if (!e.get())
				continue;
//			ar(*e.get());
			e->serialize(ar);
		}
	}

	template <class Archive>
	void load(Archive &ar)
	{
		// load Entity informations
		ar(_flags, _localTransform, _globalTransform);
		unsigned int cptNumber = 0;
		ar(cptNumber);
		for (unsigned int i = 0; i < cptNumber; ++i)
		{
			std::size_t type = 0;
			unsigned int typeId;
			ar(type);
			unsigned int position;
			Component::Base *cpt = _scene->createFromType(type, ar, _handle, typeId);
			cpt->setEntity(_handle);
			if (_components.size() <= typeId)
				_components.resize(typeId + 1);
			_components[typeId] = SmartPointer<Component::Base>(cpt);
			_code.add(typeId);
			broadCast(std::string("componentAdded" + std::to_string(typeId)), _handle);
		}
		std::cout << "lol" << std::endl;
	}

};

#endif<|endoftext|>