<commit_before>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <sstream>
#include <iostream>
#include "halCLParser.h"
#include "hal.h"

using namespace std;
using namespace hal;

size_t CLParser::lineWidth = 85;

CLParser::CLParser() :
  _prefix("--"),
  _maxArgLen(0),
  _maxOptLen(0)
{
  addOptionFlag("help", "dsiplay this help page", false);
}

CLParser::~CLParser()
{
}

void CLParser::setOptionPrefix(const string& prefix)
{
  _prefix = prefix;
}

bool CLParser::hasOption(const string& name) const
{
  map<string, Option>::const_iterator i = _options.find(name);
  return i != _options.end() && i->second._flag == false;
}

void CLParser::addArgument(const string& name,
                           const string& description)
{
  if (hasOption(name) || hasFlag(name) || hasArgument(name))
  {
    throw std::runtime_error(string("name ") + name + "already present");
  }
  Argument arg = {name, description, ""};
  _args.push_back(arg);
  _maxArgLen = max(_maxArgLen, name.length());
}

bool CLParser::hasArgument(const string& name) const
{
  for (size_t i = 0; i < _args.size(); ++i)
  {
    if (_args[i]._name == name)
    {
      return true;
    }
  }
  return false;
}

void CLParser::addOptionFlag(const string& name,
                             const string& description,
                             bool defaultValue)
{
  if (hasOption(name) || hasFlag(name) || hasArgument(name))
  {
    throw std::runtime_error(string("name ") + name + "already present");
  }
  stringstream ss;
  ss << defaultValue;
  Option opt = { description, ss.str(), ss.str(), true };
  map<string, Option>::iterator i = _options.find(name);
  _options.insert(pair<string, Option>(name, opt));
  _maxOptLen = max(_maxOptLen, name.length());
}

bool CLParser::getFlag(const string& name) const
{
  bool value;
  map<string, Option>::const_iterator i = _options.find(name);
  if (i == _options.end() || i->second._flag == false)
  {
    throw hal_exception(string("Option flag") + name + " not recognized");
  }
  stringstream ss;
  try
  {
    ss << i->second._value;
    ss >> value;
  }
  catch (...)
  {
    throw hal_exception(string("type conversion getting flag ") + name);
  }
  return value;
}

bool CLParser::hasFlag(const string& name) const
{
  map<string, Option>::const_iterator i = _options.find(name);
  return i != _options.end() && i->second._flag == true;
}

void CLParser::parseOptions(int argc, char** argv)
{
  if (argc == 0)
  {
    return;
  }
  _exeName = argv[0];
  size_t argNum = 0;
  for (int i = 1; i < argc; ++i)
  {
    string name = argv[i];
    if (name.find(_prefix) == 0)
    {
      name = name.substr(_prefix.length());
      if (name == "help")
      {
        throw hal_exception(" ");
      }
      if (hasOption(name))
      {
        if (i == argc - 1)
        {
          throw hal_exception(string("Missing value for option ") + name);
        }
        map<string, Option>::iterator it = _options.find(name);
        it->second._value = argv[++i];
      }
      else if (hasFlag(name))
      {
        map<string, Option>::iterator it = _options.find(name);
        stringstream ss;
        ss << it->second._defaultValue;
        bool oldValue;
        ss >> oldValue;
        stringstream ss2;
        ss2 << !oldValue;
        it->second._value = ss2.str();
      }
    }
    else
    {
      if (argNum >= _args.size())
      {
        stringstream ss;
        ss << "Too many (" << argNum + 1 << ") arguments reached: " << name;
        throw hal_exception(ss.str());
      }
      _args[argNum++]._value = name;
    }
  }
  if (argNum != _args.size())
  {
    throw hal_exception("Too few (required positional) arguments");
  }
}

void CLParser::printUsage(ostream& os) const
{
  os << endl;
  if (_description.empty() == false)
  {
    stringstream vstring;
    vstring << HAL_VERSION;
    os << _exeName << " v" << vstring.str() << ": "
       << multiLine(_description, _exeName.length() +
                    vstring.str().length() + 4)
       << "\n\n";
  }
  os << "USAGE:\n" << _exeName << " [Options]";
  for (size_t i = 0; i < _args.size(); ++i)
  {
    os << " <" << _args[i]._name << ">";
  }
  os << endl << endl;
  os << "ARGUMENTS:\n";
  for (size_t i = 0; i < _args.size(); ++i)
  {
    string spacer(_maxArgLen - _args[i]._name.length(), ' ');
    os << _args[i]._name << ":   " << spacer
       << multiLine(_args[i]._description, _maxArgLen + 4)
       << endl;
  }
  os << endl;
  os << "OPTIONS:\n";
  for (map<string, Option>::const_iterator i = _options.begin();
       i != _options.end(); ++i)
  {
    os << _prefix << i->first;
    size_t spacerLen = 8 + _maxOptLen - i->first.length();
    if (i->second._flag == false)
    {
      os << " <value>";
      spacerLen -= 8;
    }
    string spacer(spacerLen, ' ');
    os << ":   " << spacer
       << multiLine(i->second._description + " [default = " +
                    i->second._defaultValue + "]", 14 + _maxOptLen)
       << endl;
  }
  os << endl;
  if (_example.empty() == false)
  {
    os << "EXAMPLE:\n" << _exeName << " _example" << endl;
  }
  os << endl;
}

void CLParser::setDescription(const std::string& description)
{
  _description = description;
}

void CLParser::setExample(const std::string& example)
{
  _example = example;
}

string CLParser::multiLine(const string& line, size_t indent)
{
  if (indent >= lineWidth || line.length() + indent <= lineWidth)
  {
    return line;
  }
  string output;
  size_t width = 0;
  for (size_t i = 0; i < line.length(); ++i)
  {
    output += line[i];
    ++width;
    if (i != 0 && i != line.length() - 1 && width >= (lineWidth - indent))
    {
      bool inserted = false;
      if (!isspace(line[i]) && !isspace(line[i+1]))
      {
        for (size_t j = 1; j < (lineWidth - indent) / 2 && !inserted; ++j)
        {
          assert(i > j);
          if (isspace(line[i - j]))
          {
            inserted = true;
            output.insert((i - j) + 1, string("\n") + string(indent, ' '));
            width = j;
          }
        }
      }
      if (!inserted)
      {
        output += '\n';
        output += string(indent, ' ');
        width = 0;
      }
    }
  }
  return output;
}
<commit_msg>add check for unrecognized option without parameter.  cant believe that was missing until now<commit_after>/*
 * Copyright (C) 2012 by Glenn Hickey (hickey@soe.ucsc.edu)
 *
 * Released under the MIT license, see LICENSE.txt
 */
#include <sstream>
#include <iostream>
#include "halCLParser.h"
#include "hal.h"

using namespace std;
using namespace hal;

size_t CLParser::lineWidth = 85;

CLParser::CLParser() :
  _prefix("--"),
  _maxArgLen(0),
  _maxOptLen(0)
{
  addOptionFlag("help", "dsiplay this help page", false);
}

CLParser::~CLParser()
{
}

void CLParser::setOptionPrefix(const string& prefix)
{
  _prefix = prefix;
}

bool CLParser::hasOption(const string& name) const
{
  map<string, Option>::const_iterator i = _options.find(name);
  return i != _options.end() && i->second._flag == false;
}

void CLParser::addArgument(const string& name,
                           const string& description)
{
  if (hasOption(name) || hasFlag(name) || hasArgument(name))
  {
    throw std::runtime_error(string("name ") + name + "already present");
  }
  Argument arg = {name, description, ""};
  _args.push_back(arg);
  _maxArgLen = max(_maxArgLen, name.length());
}

bool CLParser::hasArgument(const string& name) const
{
  for (size_t i = 0; i < _args.size(); ++i)
  {
    if (_args[i]._name == name)
    {
      return true;
    }
  }
  return false;
}

void CLParser::addOptionFlag(const string& name,
                             const string& description,
                             bool defaultValue)
{
  if (hasOption(name) || hasFlag(name) || hasArgument(name))
  {
    throw std::runtime_error(string("name ") + name + "already present");
  }
  stringstream ss;
  ss << defaultValue;
  Option opt = { description, ss.str(), ss.str(), true };
  map<string, Option>::iterator i = _options.find(name);
  _options.insert(pair<string, Option>(name, opt));
  _maxOptLen = max(_maxOptLen, name.length());
}

bool CLParser::getFlag(const string& name) const
{
  bool value;
  map<string, Option>::const_iterator i = _options.find(name);
  if (i == _options.end() || i->second._flag == false)
  {
    throw hal_exception(string("Option flag") + name + " not recognized");
  }
  stringstream ss;
  try
  {
    ss << i->second._value;
    ss >> value;
  }
  catch (...)
  {
    throw hal_exception(string("type conversion getting flag ") + name);
  }
  return value;
}

bool CLParser::hasFlag(const string& name) const
{
  map<string, Option>::const_iterator i = _options.find(name);
  return i != _options.end() && i->second._flag == true;
}

void CLParser::parseOptions(int argc, char** argv)
{
  if (argc == 0)
  {
    return;
  }
  _exeName = argv[0];
  size_t argNum = 0;
  for (int i = 1; i < argc; ++i)
  {
    string name = argv[i];
    if (name.find(_prefix) == 0)
    {
      name = name.substr(_prefix.length());
      if (name == "help")
      {
        throw hal_exception(" ");
      }
      if (hasOption(name))
      {
        if (i == argc - 1)
        {
          throw hal_exception(string("Missing value for option ") + name);
        }
        map<string, Option>::iterator it = _options.find(name);
        it->second._value = argv[++i];
      }
      else if (hasFlag(name))
      {
        map<string, Option>::iterator it = _options.find(name);
        stringstream ss;
        ss << it->second._defaultValue;
        bool oldValue;
        ss >> oldValue;
        stringstream ss2;
        ss2 << !oldValue;
        it->second._value = ss2.str();
      }
      else
      {
        throw hal_exception(string("Unrecognized option: ") + string(argv[i]));
      }
    }
    else
    {
      if (argNum >= _args.size())
      {
        stringstream ss;
        ss << "Too many (" << argNum + 1 << ") arguments reached: " << name;
        throw hal_exception(ss.str());
      }
      _args[argNum++]._value = name;
    }
  }
  if (argNum != _args.size())
  {
    throw hal_exception("Too few (required positional) arguments");
  }
}

void CLParser::printUsage(ostream& os) const
{
  os << endl;
  if (_description.empty() == false)
  {
    stringstream vstring;
    vstring << HAL_VERSION;
    os << _exeName << " v" << vstring.str() << ": "
       << multiLine(_description, _exeName.length() +
                    vstring.str().length() + 4)
       << "\n\n";
  }
  os << "USAGE:\n" << _exeName << " [Options]";
  for (size_t i = 0; i < _args.size(); ++i)
  {
    os << " <" << _args[i]._name << ">";
  }
  os << endl << endl;
  os << "ARGUMENTS:\n";
  for (size_t i = 0; i < _args.size(); ++i)
  {
    string spacer(_maxArgLen - _args[i]._name.length(), ' ');
    os << _args[i]._name << ":   " << spacer
       << multiLine(_args[i]._description, _maxArgLen + 4)
       << endl;
  }
  os << endl;
  os << "OPTIONS:\n";
  for (map<string, Option>::const_iterator i = _options.begin();
       i != _options.end(); ++i)
  {
    os << _prefix << i->first;
    size_t spacerLen = 8 + _maxOptLen - i->first.length();
    if (i->second._flag == false)
    {
      os << " <value>";
      spacerLen -= 8;
    }
    string spacer(spacerLen, ' ');
    os << ":   " << spacer
       << multiLine(i->second._description + " [default = " +
                    i->second._defaultValue + "]", 14 + _maxOptLen)
       << endl;
  }
  os << endl;
  if (_example.empty() == false)
  {
    os << "EXAMPLE:\n" << _exeName << " _example" << endl;
  }
  os << endl;
}

void CLParser::setDescription(const std::string& description)
{
  _description = description;
}

void CLParser::setExample(const std::string& example)
{
  _example = example;
}

string CLParser::multiLine(const string& line, size_t indent)
{
  if (indent >= lineWidth || line.length() + indent <= lineWidth)
  {
    return line;
  }
  string output;
  size_t width = 0;
  for (size_t i = 0; i < line.length(); ++i)
  {
    output += line[i];
    ++width;
    if (i != 0 && i != line.length() - 1 && width >= (lineWidth - indent))
    {
      bool inserted = false;
      if (!isspace(line[i]) && !isspace(line[i+1]))
      {
        for (size_t j = 1; j < (lineWidth - indent) / 2 && !inserted; ++j)
        {
          assert(i > j);
          if (isspace(line[i - j]))
          {
            inserted = true;
            output.insert((i - j) + 1, string("\n") + string(indent, ' '));
            width = j;
          }
        }
      }
      if (!inserted)
      {
        output += '\n';
        output += string(indent, ' ');
        width = 0;
      }
    }
  }
  return output;
}
<|endoftext|>


<commit_before>#include "Lepton_I2C.h"

#include "leptonSDKEmb32PUB/LEPTON_SDK.h"
#include "leptonSDKEmb32PUB/LEPTON_SYS.h"
#include "leptonSDKEmb32PUB/LEPTON_Types.h"

bool _connected;

LEP_CAMERA_PORT_DESC_T _port;

int lepton_connect() {
	LEP_OpenPort(1, LEP_CCI_TWI, 400, &_port);
	_connected = true;
	return 0;
}

void lepton_perform_ffc() {
	if(!_connected) {
		lepton_connect();
	}
	LEP_RunSysFFCNormalization(&_port);
}

//presumably more commands could go here if desired
<commit_msg>Update Lepton_I2C.cpp<commit_after>#include "Lepton_I2C.h"

#include "leptonSDKEmb32PUB/LEPTON_SDK.h"
#include "leptonSDKEmb32PUB/LEPTON_SYS.h"
#include "leptonSDKEmb32PUB/LEPTON_OEM.h"
#include "leptonSDKEmb32PUB/LEPTON_Types.h"

bool _connected;

LEP_CAMERA_PORT_DESC_T _port;

int lepton_connect() {
	LEP_OpenPort(1, LEP_CCI_TWI, 400, &_port);
	_connected = true;
	return 0;
}

void lepton_perform_ffc() {
	if(!_connected) {
		lepton_connect();
	}
	LEP_RunSysFFCNormalization(&_port);
}

//presumably more commands could go here if desired

void lepton_reboot() {
	if(!_connected) {
		lepton_connect();
	}
	LEP_RunOemReboot(&_port);
}
<|endoftext|>


<commit_before>#ifndef MS_RTC_PAYLOAD_DESCRIPTOR_HANDLER_HPP
#define MS_RTC_PAYLOAD_DESCRIPTOR_HANDLER_HPP

#include "common.hpp"

namespace RTC
{
	namespace Codecs
	{
		// Codec payload descriptor.
		struct PayloadDescriptor
		{
			virtual ~PayloadDescriptor() = default;
			virtual void Dump() const    = 0;
		};

		// Encoding context used by PayloadDescriptorHandler to properly rewrite the
		// PayloadDescriptor.
		class EncodingContext
		{
		public:
			virtual ~EncodingContext() = default;

		public:
			int16_t GetTargetSpatialLayer() const;
			int16_t GetTargetTemporalLayer() const;
			int16_t GetCurrentSpatialLayer() const;
			int16_t GetCurrentTemporalLayer() const;
			void SetTargetSpatialLayer(int16_t spatialLayer);
			void SetTargetTemporalLayer(int16_t temporalLayer);
			void SetCurrentSpatialLayer(int16_t spatialLayer);
			void SetCurrentTemporalLayer(int16_t temporalLayer);
			virtual void SyncRequired() = 0;

		private:
			int16_t targetSpatialLayer{ -1 };
			int16_t targetTemporalLayer{ -1 };
			int16_t currentSpatialLayer{ -1 };
			int16_t currentTemporalLayer{ -1 };
		};

		/* Inline instance methods. */

		inline int16_t EncodingContext::GetTargetSpatialLayer() const
		{
			return this->targetSpatialLayer;
		}

		inline int16_t EncodingContext::GetTargetTemporalLayer() const
		{
			return this->targetTemporalLayer;
		}

		inline int16_t EncodingContext::GetCurrentSpatialLayer() const
		{
			return this->currentSpatialLayer;
		}

		inline int16_t EncodingContext::GetCurrentTemporalLayer() const
		{
			return this->currentTemporalLayer;
		}

		inline void EncodingContext::SetTargetSpatialLayer(int16_t spatialLayer)
		{
			this->targetSpatialLayer = spatialLayer;
		}

		inline void EncodingContext::SetTargetTemporalLayer(int16_t temporalLayer)
		{
			this->targetTemporalLayer = temporalLayer;
		}

		inline void EncodingContext::SetCurrentSpatialLayer(int16_t spatialLayer)
		{
			this->currentSpatialLayer = spatialLayer;
		}

		inline void EncodingContext::SetCurrentTemporalLayer(int16_t temporalLayer)
		{
			this->currentTemporalLayer = temporalLayer;
		}

		class PayloadDescriptorHandler
		{
		public:
			virtual ~PayloadDescriptorHandler() = default;

		public:
			virtual void Dump() const                                                  = 0;
			virtual bool Process(RTC::Codecs::EncodingContext* context, uint8_t* data) = 0;
			virtual void Restore(uint8_t* data)                                        = 0;
			virtual uint8_t GetSpatialLayer() const                                    = 0;
			virtual uint8_t GetTemporalLayer() const                                   = 0;
			virtual bool IsKeyFrame() const                                            = 0;
		};
	} // namespace Codecs
} // namespace RTC

#endif
<commit_msg>C++: make Codacy happy<commit_after>#ifndef MS_RTC_PAYLOAD_DESCRIPTOR_HANDLER_HPP
#define MS_RTC_PAYLOAD_DESCRIPTOR_HANDLER_HPP

#include "common.hpp"

namespace RTC
{
	namespace Codecs
	{
		// Codec payload descriptor.
		struct PayloadDescriptor
		{
			virtual ~PayloadDescriptor() = default;
			virtual void Dump() const    = 0;
		};

		// Encoding context used by PayloadDescriptorHandler to properly rewrite the
		// PayloadDescriptor.
		class EncodingContext
		{
		public:
			EncodingContext()          = default;
			virtual ~EncodingContext() = default;

		public:
			int16_t GetTargetSpatialLayer() const;
			int16_t GetTargetTemporalLayer() const;
			int16_t GetCurrentSpatialLayer() const;
			int16_t GetCurrentTemporalLayer() const;
			void SetTargetSpatialLayer(int16_t spatialLayer);
			void SetTargetTemporalLayer(int16_t temporalLayer);
			void SetCurrentSpatialLayer(int16_t spatialLayer);
			void SetCurrentTemporalLayer(int16_t temporalLayer);
			virtual void SyncRequired() = 0;

		private:
			int16_t targetSpatialLayer{ -1 };
			int16_t targetTemporalLayer{ -1 };
			int16_t currentSpatialLayer{ -1 };
			int16_t currentTemporalLayer{ -1 };
		};

		/* Inline instance methods. */

		inline int16_t EncodingContext::GetTargetSpatialLayer() const
		{
			return this->targetSpatialLayer;
		}

		inline int16_t EncodingContext::GetTargetTemporalLayer() const
		{
			return this->targetTemporalLayer;
		}

		inline int16_t EncodingContext::GetCurrentSpatialLayer() const
		{
			return this->currentSpatialLayer;
		}

		inline int16_t EncodingContext::GetCurrentTemporalLayer() const
		{
			return this->currentTemporalLayer;
		}

		inline void EncodingContext::SetTargetSpatialLayer(int16_t spatialLayer)
		{
			this->targetSpatialLayer = spatialLayer;
		}

		inline void EncodingContext::SetTargetTemporalLayer(int16_t temporalLayer)
		{
			this->targetTemporalLayer = temporalLayer;
		}

		inline void EncodingContext::SetCurrentSpatialLayer(int16_t spatialLayer)
		{
			this->currentSpatialLayer = spatialLayer;
		}

		inline void EncodingContext::SetCurrentTemporalLayer(int16_t temporalLayer)
		{
			this->currentTemporalLayer = temporalLayer;
		}

		class PayloadDescriptorHandler
		{
		public:
			virtual ~PayloadDescriptorHandler() = default;

		public:
			virtual void Dump() const                                                  = 0;
			virtual bool Process(RTC::Codecs::EncodingContext* context, uint8_t* data) = 0;
			virtual void Restore(uint8_t* data)                                        = 0;
			virtual uint8_t GetSpatialLayer() const                                    = 0;
			virtual uint8_t GetTemporalLayer() const                                   = 0;
			virtual bool IsKeyFrame() const                                            = 0;
		};
	} // namespace Codecs
} // namespace RTC

#endif
<|endoftext|>


<commit_before>#pragma once
#ifndef DELEGATE_HPP
# define DELEGATE_HPP

#include <cassert>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

#include "lightptr.hpp"

template <typename T> class delegate;

template<class R, class ...A>
class delegate<R (A...)>
{
  using stub_ptr_type = R (*)(void*, A&&...);

  delegate(void* const o, stub_ptr_type const m) noexcept
    : object_ptr_(o),
      stub_ptr_(m)
  {
  }

public:
  delegate() = default;

  delegate(delegate const&) = default;

  delegate(delegate&&) = default;

  delegate(::std::nullptr_t const) noexcept : delegate() { }

  template <class C>
  explicit delegate(C const* const o) noexcept
    : object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C>
  explicit delegate(C const& o) noexcept
    : object_ptr_(const_cast<C*>(&o))
  {
  }

  delegate(R (* const function_ptr)(A...))
  {
    *this = from(function_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate(T&& f)
    : store_(operator new(sizeof(T)),
        functor_deleter<typename ::std::decay<T>::type>),
      store_size_(sizeof(T))
  {
    using functor_type = typename ::std::decay<T>::type;

    new (store_.get()) functor_type(::std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = destructor_stub<functor_type>;
  }

  delegate& operator=(delegate const&) = default;

  delegate& operator=(delegate&& rhs) = default;

  delegate& operator=(R (* const rhs)(A...))
  {
    return *this = from(rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate& operator=(T&& f)
  {
    using functor_type = typename ::std::decay<T>::type;

    if ((sizeof(T) > store_size_) || !store_.unique())
    {
      store_.reset(operator new(sizeof(T)), functor_deleter<functor_type>);

      store_size_ = sizeof(T);
    }
    else
    {
      deleter_(store_.get());
    }

    new (store_.get()) functor_type(::std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = destructor_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C* const object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const* const object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static delegate from(T&& f)
  {
    return ::std::forward<T>(f);
  }

  static delegate from(R (* const function_ptr)(A...))
  {
    return [function_ptr](A&&... args) {
      return (*function_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(::std::forward<A>(args)...); };
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void reset_stub() noexcept { stub_ptr_ = nullptr; }

  void swap(delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) ||
      ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !stub_ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return stub_ptr_;
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
  }

private:
  friend class ::std::hash<delegate>;

  using deleter_type = void (*)(void*);

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  deleter_type deleter_;

  light_ptr<void> store_;
  ::std::size_t store_size_;

  template <class T>
  static void destructor_stub(void* const p)
  {
    static_cast<T*>(p)->~T();
  }

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_cast<T*>(p)->~T();

    operator delete(p);
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <typename T>
  static R functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(::std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<delegate<R (A...)> >
  {
    size_t operator()(delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_));

      return hash<typename delegate<R (A...)>::stub_ptr_type>()(d.stub_ptr_) +
        0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP
<commit_msg>some fixes<commit_after>#pragma once
#ifndef DELEGATE_HPP
# define DELEGATE_HPP

#include <cassert>

#include <memory>

#include <new>

#include <type_traits>

#include <utility>

#include "lightptr.hpp"

template <typename T> class delegate;

template<class R, class ...A>
class delegate<R (A...)>
{
  using stub_ptr_type = R (*)(void*, A&&...);

  delegate(void* const o, stub_ptr_type const m) noexcept
    : object_ptr_(o),
      stub_ptr_(m)
  {
  }

public:
  delegate() = default;

  delegate(delegate const&) = default;

  delegate(delegate&&) = default;

  delegate(::std::nullptr_t const) noexcept : delegate() { }

  template <class C>
  explicit delegate(C const* const o) noexcept
    : object_ptr_(const_cast<C*>(o))
  {
  }

  template <class C>
  explicit delegate(C const& o) noexcept
    : object_ptr_(const_cast<C*>(&o))
  {
  }

  delegate(R (* const function_ptr)(A...))
  {
    *this = from(function_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...))
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C* const object_ptr, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object_ptr, method_ptr);
  }

  template <class C>
  delegate(C& object, R (C::* const method_ptr)(A...))
  {
    *this = from(object, method_ptr);
  }

  template <class C>
  delegate(C const& object, R (C::* const method_ptr)(A...) const)
  {
    *this = from(object, method_ptr);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate(T&& f)
    : store_(operator new(sizeof(T)),
        functor_deleter<typename ::std::decay<T>::type>),
      store_size_(sizeof(T))
  {
    using functor_type = typename ::std::decay<T>::type;

    new (store_.get()) functor_type(::std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = deleter_stub<functor_type>;
  }

  delegate& operator=(delegate const&) = default;

  delegate& operator=(delegate&& rhs) = default;

  delegate& operator=(R (* const rhs)(A...))
  {
    return *this = from(rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...))
  {
    return *this = from(static_cast<C*>(object_ptr_), rhs);
  }

  template <class C>
  delegate& operator=(R (C::* const rhs)(A...) const)
  {
    return *this = from(static_cast<C const*>(object_ptr_), rhs);
  }

  template <
    typename T,
    typename = typename ::std::enable_if<
      !::std::is_same<delegate, typename ::std::decay<T>::type>{}
    >::type
  >
  delegate& operator=(T&& f)
  {
    using functor_type = typename ::std::decay<T>::type;

    if ((sizeof(T) > store_size_) || !store_.unique())
    {
      store_.reset(operator new(sizeof(T)), functor_deleter<functor_type>);

      store_size_ = sizeof(T);
    }
    else
    {
      deleter_(store_.get());
    }

    new (store_.get()) functor_type(::std::forward<T>(f));

    object_ptr_ = store_.get();

    stub_ptr_ = functor_stub<functor_type>;

    deleter_ = deleter_stub<functor_type>;

    return *this;
  }

  template <R (* const function_ptr)(A...)>
  static delegate from() noexcept
  {
    return { nullptr, function_stub<function_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C* const object_ptr) noexcept
  {
    return { object_ptr, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const* const object_ptr) noexcept
  {
    return { const_cast<C*>(object_ptr), const_method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...)>
  static delegate from(C& object) noexcept
  {
    return { &object, method_stub<C, method_ptr> };
  }

  template <class C, R (C::* const method_ptr)(A...) const>
  static delegate from(C const& object) noexcept
  {
    return { const_cast<C*>(&object), const_method_stub<C, method_ptr> };
  }

  template <typename T>
  static delegate from(T&& f)
  {
    return ::std::forward<T>(f);
  }

  static delegate from(R (* const function_ptr)(A...))
  {
    return [function_ptr](A&&... args) {
      return (*function_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C* const object_ptr,
    R (C::* const method_ptr)(A...))
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const* const object_ptr,
    R (C::* const method_ptr)(A...) const)
  {
    return [object_ptr, method_ptr](A&&... args) {
      return (object_ptr->*method_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C& object, R (C::* const method_ptr)(A...))
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(::std::forward<A>(args)...); };
  }

  template <class C>
  static delegate from(C const& object,
    R (C::* const method_ptr)(A...) const)
  {
    return [&object, method_ptr](A&&... args) {
      return (object.*method_ptr)(::std::forward<A>(args)...); };
  }

  void reset() { stub_ptr_ = nullptr; store_.reset(); }

  void reset_stub() noexcept { stub_ptr_ = nullptr; }

  void swap(delegate& other) noexcept { ::std::swap(*this, other); }

  bool operator==(delegate const& rhs) const noexcept
  {
    return (object_ptr_ == rhs.object_ptr_) && (stub_ptr_ == rhs.stub_ptr_);
  }

  bool operator!=(delegate const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator<(delegate const& rhs) const noexcept
  {
    return (object_ptr_ < rhs.object_ptr_) ||
      ((object_ptr_ == rhs.object_ptr_) && (stub_ptr_ < rhs.stub_ptr_));
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !stub_ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return stub_ptr_;
  }

  explicit operator bool() const noexcept { return stub_ptr_; }

  R operator()(A... args) const
  {
//  assert(stub_ptr);
    return stub_ptr_(object_ptr_, ::std::forward<A>(args)...);
  }

private:
  friend class ::std::hash<delegate>;

  using deleter_type = void (*)(void*);

  void* object_ptr_;
  stub_ptr_type stub_ptr_{};

  deleter_type deleter_;

  light_ptr<void> store_;
  ::std::size_t store_size_;

  template <class T>
  static void deleter_stub(void* const p)
  {
    static_cast<T*>(p)->~T();
  }

  template <class T>
  static void functor_deleter(void* const p)
  {
    static_cast<T*>(p)->~T();

    operator delete(p);
  }

  template <R (*function_ptr)(A...)>
  static R function_stub(void* const, A&&... args)
  {
    return function_ptr(::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...)>
  static R method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <class C, R (C::*method_ptr)(A...) const>
  static R const_method_stub(void* const object_ptr, A&&... args)
  {
    return (static_cast<C const*>(object_ptr)->*method_ptr)(
      ::std::forward<A>(args)...);
  }

  template <typename T>
  static R functor_stub(void* const object_ptr, A&&... args)
  {
    return (*static_cast<T*>(object_ptr))(::std::forward<A>(args)...);
  }
};

namespace std
{
  template <typename R, typename ...A>
  struct hash<delegate<R (A...)> >
  {
    size_t operator()(delegate<R (A...)> const& d) const noexcept
    {
      auto const seed(hash<void*>()(d.object_ptr_));

      return hash<typename delegate<R (A...)>::stub_ptr_type>()(d.stub_ptr_) +
        0x9e3779b9 + (seed << 6) + (seed >> 2);
    }
  };
}

#endif // DELEGATE_HPP
<|endoftext|>


<commit_before><commit_msg>Added option to create LINEs instead of 3DFACEs.<commit_after><|endoftext|>


<commit_before>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Physics 2D module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Physics2D/RigidBody2D.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Physics2D/Config.hpp>
#include <Nazara/Physics2D/PhysWorld2D.hpp>
#include <chipmunk/chipmunk.h>
#include <chipmunk/chipmunk_private.h>
#include <algorithm>
#include <Nazara/Physics3D/Debug.hpp>

namespace Nz
{
	RigidBody2D::RigidBody2D(PhysWorld2D* world, float mass) :
	RigidBody2D(world, mass, nullptr)
	{
	}

	RigidBody2D::RigidBody2D(PhysWorld2D* world, float mass, Collider2DRef geom) :
	m_geom(),
	m_world(world),
	m_gravityFactor(1.f),
	m_mass(0.f)
	{
		NazaraAssert(m_world, "Invalid world");

		Create();

		SetGeom(geom);
		SetMass(mass);
	}

	RigidBody2D::RigidBody2D(const RigidBody2D& object) :
	m_geom(object.m_geom),
	m_world(object.m_world),
	m_gravityFactor(object.m_gravityFactor),
	m_mass(0.f)
	{
		NazaraAssert(m_world, "Invalid world");
		NazaraAssert(m_geom, "Invalid geometry");

		Create();

		SetGeom(object.GetGeom());
		SetMass(object.GetMass());
	}

	RigidBody2D::RigidBody2D(RigidBody2D&& object) :
	m_shapes(std::move(object.m_shapes)),
	m_geom(std::move(object.m_geom)),
	m_handle(object.m_handle),
	m_world(object.m_world),
	m_gravityFactor(object.m_gravityFactor),
	m_mass(object.m_mass)
	{
		object.m_handle = nullptr;
	}

	RigidBody2D::~RigidBody2D()
	{
		Destroy();
	}

	void RigidBody2D::AddForce(const Vector2f& force, CoordSys coordSys)
	{
		return AddForce(force, GetCenterOfGravity(coordSys), coordSys);
	}

	void RigidBody2D::AddForce(const Vector2f& force, const Vector2f& point, CoordSys coordSys)
	{
		switch (coordSys)
		{
			case CoordSys_Global:
				cpBodyApplyForceAtWorldPoint(m_handle, cpv(force.x, force.y), cpv(force.x, force.y));
				break;

			case CoordSys_Local:
				cpBodyApplyForceAtLocalPoint(m_handle, cpv(force.x, force.y), cpv(point.x, point.y));
				break;
		}
	}

	void RigidBody2D::AddTorque(float torque)
	{
		cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + torque);
	}

	Rectf RigidBody2D::GetAABB() const
	{
		cpBB bb = cpBBNew(0.f, 0.f, 0.f, 0.f);
		for (cpShape* shape : m_shapes)
			bb = cpBBMerge(bb, cpShapeGetBB(shape));

		return Rectf(Rect<cpFloat>(bb.l, bb.t, bb.r - bb.l, bb.b - bb.t));
	}

	float RigidBody2D::GetAngularVelocity() const
	{
		return static_cast<float>(cpBodyGetAngularVelocity(m_handle));
	}

	const Collider2DRef& RigidBody2D::GetGeom() const
	{
		return m_geom;
	}

	cpBody* RigidBody2D::GetHandle() const
	{
		return m_handle;
	}

	float RigidBody2D::GetMass() const
	{
		return m_mass;
	}

	Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
	{
		cpVect cog = cpBodyGetCenterOfGravity(m_handle);

		switch (coordSys)
		{
			case CoordSys_Global:
				cog = cpBodyLocalToWorld(m_handle, cog);
				break;

			case CoordSys_Local:
				break; // Nothing to do
		}

		return Vector2f(static_cast<float>(cog.x), static_cast<float>(cog.y));
	}

	Vector2f RigidBody2D::GetPosition() const
	{
		cpVect pos = cpBodyGetPosition(m_handle);
		return Vector2f(static_cast<float>(pos.x), static_cast<float>(pos.y));
	}

	float RigidBody2D::GetRotation() const
	{
		return static_cast<float>(cpBodyGetAngle(m_handle));
	}

	Vector2f RigidBody2D::GetVelocity() const
	{
		cpVect vel = cpBodyGetVelocity(m_handle);
		return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
	}

	bool RigidBody2D::IsMoveable() const
	{
		return m_mass > 0.f;
	}

	bool RigidBody2D::IsSleeping() const
	{
		return cpBodyIsSleeping(m_handle) != 0;
	}

	void RigidBody2D::SetAngularVelocity(float angularVelocity)
	{
		cpBodySetAngularVelocity(m_handle, angularVelocity);
	}

	void RigidBody2D::SetGeom(Collider2DRef geom)
	{
		// We have no public way of getting rid of an existing geom without removing the whole body
		// So let's save some attributes of the body, destroy it and rebuild it
		if (m_geom)
		{
			cpVect pos = cpBodyGetPosition(m_handle);
			cpFloat mass = cpBodyGetMass(m_handle);
			cpFloat moment = cpBodyGetMoment(m_handle);
			cpFloat rot = cpBodyGetAngle(m_handle);
			cpVect vel = cpBodyGetVelocity(m_handle);

			Destroy();
			Create(mass, moment);

			cpBodySetAngle(m_handle, rot);
			cpBodySetPosition(m_handle, pos);
			cpBodySetVelocity(m_handle, vel);
		}

		if (geom)
			m_geom = geom;
		else
			m_geom = NullCollider2D::New();

		m_shapes = m_geom->CreateShapes(this);
	}

	void RigidBody2D::SetMass(float mass)
	{
		if (m_mass > 0.f)
		{
			if (mass > 0.f)
				cpBodySetMass(m_handle, mass);
			else
				cpBodySetType(m_handle, CP_BODY_TYPE_STATIC);
		}
		else if (mass > 0.f)
		{
			if (cpBodyGetType(m_handle) == CP_BODY_TYPE_STATIC)
				cpBodySetType(m_handle, CP_BODY_TYPE_DYNAMIC);
		}

		m_mass = mass;
	}

	void RigidBody2D::SetMassCenter(const Vector2f& center)
	{
		if (m_mass > 0.f)
			cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y));
	}

	void RigidBody2D::SetPosition(const Vector2f& position)
	{
		cpBodySetPosition(m_handle, cpv(position.x, position.y));
	}

	void RigidBody2D::SetRotation(float rotation)
	{
		cpBodySetAngle(m_handle, rotation);
	}

	void RigidBody2D::SetVelocity(const Vector2f& velocity)
	{
		cpBodySetVelocity(m_handle, cpv(velocity.x, velocity.y));
	}

	RigidBody2D& RigidBody2D::operator=(const RigidBody2D& object)
	{
		RigidBody2D physObj(object);
		return operator=(std::move(physObj));
	}

	RigidBody2D& RigidBody2D::operator=(RigidBody2D&& object)
	{
		Destroy();

		m_handle             = object.m_handle;
		m_geom               = std::move(object.m_geom);
		m_gravityFactor      = object.m_gravityFactor;
		m_mass               = object.m_mass;
		m_shapes             = std::move(object.m_shapes);
		m_world              = object.m_world;

		object.m_handle = nullptr;

		return *this;
	}

	void RigidBody2D::Create(float mass, float moment)
	{
		m_handle = cpBodyNew(mass, moment);
		cpBodySetUserData(m_handle, this);
		cpSpaceAddBody(m_world->GetHandle(), m_handle);
	}

	void RigidBody2D::Destroy()
	{
		for (cpShape* shape : m_shapes)
			cpShapeFree(shape);

		if (m_handle)
			cpBodyFree(m_handle);
	}
}
<commit_msg>Physics2D/RigidBody2D: Fix SetMass need to be called twice<commit_after>// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine - Physics 2D module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Physics2D/RigidBody2D.hpp>
#include <Nazara/Math/Algorithm.hpp>
#include <Nazara/Physics2D/Config.hpp>
#include <Nazara/Physics2D/PhysWorld2D.hpp>
#include <chipmunk/chipmunk.h>
#include <chipmunk/chipmunk_private.h>
#include <algorithm>
#include <Nazara/Physics3D/Debug.hpp>

namespace Nz
{
	RigidBody2D::RigidBody2D(PhysWorld2D* world, float mass) :
	RigidBody2D(world, mass, nullptr)
	{
	}

	RigidBody2D::RigidBody2D(PhysWorld2D* world, float mass, Collider2DRef geom) :
	m_geom(),
	m_world(world),
	m_gravityFactor(1.f),
	m_mass(0.f)
	{
		NazaraAssert(m_world, "Invalid world");

		Create();

		SetGeom(geom);
		SetMass(mass);
	}

	RigidBody2D::RigidBody2D(const RigidBody2D& object) :
	m_geom(object.m_geom),
	m_world(object.m_world),
	m_gravityFactor(object.m_gravityFactor),
	m_mass(0.f)
	{
		NazaraAssert(m_world, "Invalid world");
		NazaraAssert(m_geom, "Invalid geometry");

		Create();

		SetGeom(object.GetGeom());
		SetMass(object.GetMass());
	}

	RigidBody2D::RigidBody2D(RigidBody2D&& object) :
	m_shapes(std::move(object.m_shapes)),
	m_geom(std::move(object.m_geom)),
	m_handle(object.m_handle),
	m_world(object.m_world),
	m_gravityFactor(object.m_gravityFactor),
	m_mass(object.m_mass)
	{
		object.m_handle = nullptr;
	}

	RigidBody2D::~RigidBody2D()
	{
		Destroy();
	}

	void RigidBody2D::AddForce(const Vector2f& force, CoordSys coordSys)
	{
		return AddForce(force, GetCenterOfGravity(coordSys), coordSys);
	}

	void RigidBody2D::AddForce(const Vector2f& force, const Vector2f& point, CoordSys coordSys)
	{
		switch (coordSys)
		{
			case CoordSys_Global:
				cpBodyApplyForceAtWorldPoint(m_handle, cpv(force.x, force.y), cpv(force.x, force.y));
				break;

			case CoordSys_Local:
				cpBodyApplyForceAtLocalPoint(m_handle, cpv(force.x, force.y), cpv(point.x, point.y));
				break;
		}
	}

	void RigidBody2D::AddTorque(float torque)
	{
		cpBodySetTorque(m_handle, cpBodyGetTorque(m_handle) + torque);
	}

	Rectf RigidBody2D::GetAABB() const
	{
		cpBB bb = cpBBNew(0.f, 0.f, 0.f, 0.f);
		for (cpShape* shape : m_shapes)
			bb = cpBBMerge(bb, cpShapeGetBB(shape));

		return Rectf(Rect<cpFloat>(bb.l, bb.t, bb.r - bb.l, bb.b - bb.t));
	}

	float RigidBody2D::GetAngularVelocity() const
	{
		return static_cast<float>(cpBodyGetAngularVelocity(m_handle));
	}

	const Collider2DRef& RigidBody2D::GetGeom() const
	{
		return m_geom;
	}

	cpBody* RigidBody2D::GetHandle() const
	{
		return m_handle;
	}

	float RigidBody2D::GetMass() const
	{
		return m_mass;
	}

	Vector2f RigidBody2D::GetCenterOfGravity(CoordSys coordSys) const
	{
		cpVect cog = cpBodyGetCenterOfGravity(m_handle);

		switch (coordSys)
		{
			case CoordSys_Global:
				cog = cpBodyLocalToWorld(m_handle, cog);
				break;

			case CoordSys_Local:
				break; // Nothing to do
		}

		return Vector2f(static_cast<float>(cog.x), static_cast<float>(cog.y));
	}

	Vector2f RigidBody2D::GetPosition() const
	{
		cpVect pos = cpBodyGetPosition(m_handle);
		return Vector2f(static_cast<float>(pos.x), static_cast<float>(pos.y));
	}

	float RigidBody2D::GetRotation() const
	{
		return static_cast<float>(cpBodyGetAngle(m_handle));
	}

	Vector2f RigidBody2D::GetVelocity() const
	{
		cpVect vel = cpBodyGetVelocity(m_handle);
		return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
	}

	bool RigidBody2D::IsMoveable() const
	{
		return m_mass > 0.f;
	}

	bool RigidBody2D::IsSleeping() const
	{
		return cpBodyIsSleeping(m_handle) != 0;
	}

	void RigidBody2D::SetAngularVelocity(float angularVelocity)
	{
		cpBodySetAngularVelocity(m_handle, angularVelocity);
	}

	void RigidBody2D::SetGeom(Collider2DRef geom)
	{
		// We have no public way of getting rid of an existing geom without removing the whole body
		// So let's save some attributes of the body, destroy it and rebuild it
		if (m_geom)
		{
			cpVect pos = cpBodyGetPosition(m_handle);
			cpFloat mass = cpBodyGetMass(m_handle);
			cpFloat moment = cpBodyGetMoment(m_handle);
			cpFloat rot = cpBodyGetAngle(m_handle);
			cpVect vel = cpBodyGetVelocity(m_handle);

			Destroy();
			Create(mass, moment);

			cpBodySetAngle(m_handle, rot);
			cpBodySetPosition(m_handle, pos);
			cpBodySetVelocity(m_handle, vel);
		}

		if (geom)
			m_geom = geom;
		else
			m_geom = NullCollider2D::New();

		m_shapes = m_geom->CreateShapes(this);
	}

	void RigidBody2D::SetMass(float mass)
	{
		if (m_mass > 0.f)
		{
			if (mass > 0.f)
				cpBodySetMass(m_handle, mass);
			else
				cpBodySetType(m_handle, CP_BODY_TYPE_STATIC);
		}
		else if (mass > 0.f)
		{
			if (cpBodyGetType(m_handle) == CP_BODY_TYPE_STATIC)
			{
				cpBodySetType(m_handle, CP_BODY_TYPE_DYNAMIC);
				cpBodySetMass(m_handle, mass);
			}
		}

		m_mass = mass;
	}

	void RigidBody2D::SetMassCenter(const Vector2f& center)
	{
		if (m_mass > 0.f)
			cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y));
	}

	void RigidBody2D::SetPosition(const Vector2f& position)
	{
		cpBodySetPosition(m_handle, cpv(position.x, position.y));
	}

	void RigidBody2D::SetRotation(float rotation)
	{
		cpBodySetAngle(m_handle, rotation);
	}

	void RigidBody2D::SetVelocity(const Vector2f& velocity)
	{
		cpBodySetVelocity(m_handle, cpv(velocity.x, velocity.y));
	}

	RigidBody2D& RigidBody2D::operator=(const RigidBody2D& object)
	{
		RigidBody2D physObj(object);
		return operator=(std::move(physObj));
	}

	RigidBody2D& RigidBody2D::operator=(RigidBody2D&& object)
	{
		Destroy();

		m_handle             = object.m_handle;
		m_geom               = std::move(object.m_geom);
		m_gravityFactor      = object.m_gravityFactor;
		m_mass               = object.m_mass;
		m_shapes             = std::move(object.m_shapes);
		m_world              = object.m_world;

		object.m_handle = nullptr;

		return *this;
	}

	void RigidBody2D::Create(float mass, float moment)
	{
		m_handle = cpBodyNew(mass, moment);
		cpBodySetUserData(m_handle, this);
		cpSpaceAddBody(m_world->GetHandle(), m_handle);
	}

	void RigidBody2D::Destroy()
	{
		for (cpShape* shape : m_shapes)
			cpShapeFree(shape);

		if (m_handle)
			cpBodyFree(m_handle);
	}
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	FFmpeg Library/decoder クラス（ヘッダー）
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <string>
extern "C" {
	#include <libavcodec/avcodec.h>
	#include <libavfilter/avfilter.h>
	#include <libavformat/avformat.h>
	#include <libswscale/swscale.h>
};

namespace av {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	decoder クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class decoder {

		std::string			path_;
		AVFormatContext*	format_ctx_;
		AVCodecContext*		codec_ctx_;
		AVFrame* 			frame_;
		AVFrame* 			image_;
		unsigned char*		buffer_;
		int					w_;
		int					h_;
		struct SwsContext*	sws_ctx_;
		uint32_t			count_;
		int					state_;
	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		decoder() : path_(), format_ctx_(nullptr), codec_ctx_(nullptr),
					frame_(nullptr), image_(nullptr), buffer_(nullptr),
					w_(0), h_(0), sws_ctx_(nullptr),
					count_(0), state_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() {
			avcodec_register_all();
			av_register_all();
			avfilter_register_all();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	ストリーム情報の表示
		*/
		//-----------------------------------------------------------------//
		void info() {
			av_dump_format(format_ctx_, 0, path_.c_str(), 0);
			fflush(stderr);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	オープン
			@param[in]	path	ファイル名パス
			@return エラーなら「false」
		*/
		//-----------------------------------------------------------------//
		bool open(const std::string& path) {
			if(path.empty()) return false;

			path_ = path;

			// ビデオファイルを開く
			if(avformat_open_input(&format_ctx_, path.c_str(), NULL, NULL) != 0) {
				// std::cerr << "ERROR: avformat_open_input(): '" << file_name << '\'' << std::endl;
				return false;
			}

			// ストリーム情報の取得
			if(avformat_find_stream_info(format_ctx_, NULL) < 0) {
				// std::cerr << "ERROR: avformat_find_stream_info(): '" << file_name << '\'' << std::endl;
				close();
				return false;
			}

			// コーデックの検索
			codec_ctx_ = format_ctx_->streams[0]->codec;
			AVCodec* codec = avcodec_find_decoder(codec_ctx_->codec_id);

			// コーデックを開く
			if(avcodec_open2(codec_ctx_, codec, NULL) < 0) {
				// std::cerr << "ERROR: avcodec_open2(): '" << file_name << '\'' << std::endl;
				close();
				return false;
			}

			// ログ・レベルの設定
			av_log_set_level(1);

			// フレームの確保
			frame_ = avcodec_alloc_frame();
			// イメージの確保
			image_ = avcodec_alloc_frame();

			w_ = codec_ctx_->width;
			h_ = codec_ctx_->height;
			// イメージ用バッファの確保
			unsigned char* buffer = (unsigned char *)av_malloc(avpicture_get_size(PIX_FMT_RGB24, w_, h_));
			// バッファとフレームを関連付ける
			avpicture_fill((AVPicture*)image_, buffer_, PIX_FMT_RGB24, w_, h_);

			// スケーリング用コンテキストの取得
			sws_ctx_ = sws_getContext(w_, h_, codec_ctx_->pix_fmt, w_, h_,
				PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL);

			count_ = 0;

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
			@return フレーム終端なら「true」
		*/
		//-----------------------------------------------------------------//
		bool update() {
			if(format_ctx_ == nullptr || codec_ctx_ == nullptr) return true;

			// フレーム読み込みループ
			AVPacket packet;
			if(av_read_frame(format_ctx_, &packet) < 0) {
				return true;
			}

			// デコード
			avcodec_decode_video2(codec_ctx_, frame_, &state_, &packet);

			// 各フレーム、デコード完了
			if(state_) {
				// フレームを切り出し
//				int bsize = w_ * h_ * 4;
				sws_scale(sws_ctx_, (const uint8_t **)frame_->data, frame_->linesize, 0,
					codec_ctx_->height, image_->data, image_->linesize);
				++count_;
			}

			return false;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	現在のフレームを取得
			@return デコードされたフレームイメージ
		*/
		//-----------------------------------------------------------------//
		const unsigned char* get_frame() const {
			if(format_ctx_ == nullptr || codec_ctx_ == nullptr) return nullptr;
			if(state_) return buffer_;
			else return nullptr;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	現在のフレーム数を取得
		*/
		//-----------------------------------------------------------------//
		uint32_t get_frame_no() const { return count_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	クローズ
		*/
		//-----------------------------------------------------------------//
		void close() {
			sws_freeContext(sws_ctx_);
			sws_ctx_ = nullptr;

			av_free(buffer_);
			buffer_ = nullptr;

			av_free(image_);
			image_ = nullptr;

			av_free(frame_);
			frame_ = nullptr;

			avcodec_close(codec_ctx_);
			codec_ctx_ = nullptr;

			avformat_close_input(&format_ctx_);
			format_ctx_ = nullptr;
		}
	};
}
<commit_msg>Update<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	FFmpeg Library/decoder クラス（ヘッダー）
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <string>
extern "C" {
	#include <libavcodec/avcodec.h>
	#include <libavfilter/avfilter.h>
	#include <libavformat/avformat.h>
	#include <libswscale/swscale.h>
};
#include "utils/vtx.hpp"

namespace av {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	decoder クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	class decoder {

		std::string			path_;
		AVFormatContext*	format_ctx_;
		AVCodecContext*		codec_ctx_;
		AVFrame* 			frame_;
		AVFrame* 			image_;
		unsigned char*		buffer_;
		vtx::ipos			size_;
		struct SwsContext*	sws_ctx_;
		uint32_t			count_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		decoder() : path_(), format_ctx_(nullptr), codec_ctx_(nullptr),
					frame_(nullptr), image_(nullptr), buffer_(nullptr),
					size_(0), sws_ctx_(nullptr),
					count_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		~decoder() {
			close();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() {
			avcodec_register_all();
			av_register_all();
			avfilter_register_all();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	ストリーム情報の表示
		*/
		//-----------------------------------------------------------------//
		void info() {
			av_dump_format(format_ctx_, 0, path_.c_str(), 1);
//			fflush(stderr);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	オープン
			@param[in]	path	ファイル名パス
			@return エラーなら「false」
		*/
		//-----------------------------------------------------------------//
		bool open(const std::string& path) {
			if(path.empty()) return false;

			path_ = path;

			// ビデオファイルを開く
			if(avformat_open_input(&format_ctx_, path.c_str(), NULL, NULL) != 0) {
				// std::cerr << "ERROR: avformat_open_input(): '" << file_name << '\'' << std::endl;
				return false;
			}

			// ストリーム情報の取得
			if(avformat_find_stream_info(format_ctx_, NULL) < 0) {
				// std::cerr << "ERROR: avformat_find_stream_info(): '" << file_name << '\'' << std::endl;
				close();
				return false;
			}

			// コーデックの検索
			codec_ctx_ = format_ctx_->streams[0]->codec;
			AVCodec* codec = avcodec_find_decoder(codec_ctx_->codec_id);

			// コーデックを開く
			if(avcodec_open2(codec_ctx_, codec, NULL) < 0) {
				// std::cerr << "ERROR: avcodec_open2(): '" << file_name << '\'' << std::endl;
				close();
				return false;
			}

			// ログ・レベルの設定
			av_log_set_level(1);

			// フレームの確保
			frame_ = avcodec_alloc_frame();
			// イメージの確保
			image_ = avcodec_alloc_frame();

			size_.x = codec_ctx_->width;
			size_.y = codec_ctx_->height;
			// イメージ用バッファの確保
			buffer_ = (unsigned char *)av_malloc(avpicture_get_size(PIX_FMT_RGB24, size_.x, size_.y));
			// バッファとフレームを関連付ける
			avpicture_fill((AVPicture*)image_, buffer_, PIX_FMT_RGB24, size_.x, size_.y);

			// スケーリング用コンテキストの取得
			sws_ctx_ = sws_getContext(size_.x, size_.y, codec_ctx_->pix_fmt, size_.x, size_.y,
				PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL);

			count_ = 0;

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
			@return フレーム終端なら「true」
		*/
		//-----------------------------------------------------------------//
		bool update() {
			if(format_ctx_ == nullptr || codec_ctx_ == nullptr) return true;

			// フレーム読み込みループ
			AVPacket packet;
			while(av_read_frame(format_ctx_, &packet) >= 0) {

				// デコード
				int state;
				avcodec_decode_video2(codec_ctx_, frame_, &state, &packet);

				// 各フレーム、デコード完了
				if(state) {
					// フレームを切り出し
//					int bsize = w_ * h_ * 4;
					sws_scale(sws_ctx_, (const uint8_t **)frame_->data, frame_->linesize, 0,
						codec_ctx_->height, image_->data, image_->linesize);
					++count_;
					return false;
				}
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	フレームサイズを取得
			@return フレームサイズ
		*/
		//-----------------------------------------------------------------//
		const vtx::ipos& get_frame_size() const { return size_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	現在のフレームを取得
			@return デコードされたフレームイメージ
		*/
		//-----------------------------------------------------------------//
		const unsigned char* get_frame() const {
			if(format_ctx_ == nullptr || codec_ctx_ == nullptr) return nullptr;
			return buffer_;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	現在のフレーム数を取得
		*/
		//-----------------------------------------------------------------//
		uint32_t get_frame_no() const { return count_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	クローズ
		*/
		//-----------------------------------------------------------------//
		void close() {
			sws_freeContext(sws_ctx_);
			sws_ctx_ = nullptr;

			av_free(buffer_);
			buffer_ = nullptr;

			av_free(image_);
			image_ = nullptr;

			av_free(frame_);
			frame_ = nullptr;

			avcodec_close(codec_ctx_);
			codec_ctx_ = nullptr;

			avformat_close_input(&format_ctx_);
			format_ctx_ = nullptr;
		}
	};
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: Hidden.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: fs $ $Date: 2002-12-02 09:56:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FORMS_HIDDEN_HXX_
#define _FORMS_HIDDEN_HXX_

#ifndef _FORMS_FORMCOMPONENT_HXX_
#include "FormComponent.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
// OHiddenModel
//==================================================================
class OHiddenModel
        :public OControlModel
        ,public ::comphelper::OAggregationArrayUsageHelper< OHiddenModel >
{
    ::rtl::OUString     m_sHiddenValue;

public:
    DECLARE_DEFAULT_LEAF_XTOR( OHiddenModel );

    // OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
                throw (::com::sun::star::uno::Exception);
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
                throw (::com::sun::star::lang::IllegalArgumentException);

    // XPropertySetRef
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XServiceInfo
    IMPLEMENTATION_NAME(OHiddenModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    DECLARE_XCLONEABLE( );
};

#endif // _FORMS_HIDDEN_HXX_

//.........................................................................
}
//.........................................................................

<commit_msg>INTEGRATION: CWS ooo19126 (1.4.326); FILE MERGED 2005/09/05 13:50:23 rt 1.4.326.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: Hidden.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 22:43:45 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _FORMS_HIDDEN_HXX_
#define _FORMS_HIDDEN_HXX_

#ifndef _FORMS_FORMCOMPONENT_HXX_
#include "FormComponent.hxx"
#endif

//.........................................................................
namespace frm
{

//==================================================================
// OHiddenModel
//==================================================================
class OHiddenModel
        :public OControlModel
        ,public ::comphelper::OAggregationArrayUsageHelper< OHiddenModel >
{
    ::rtl::OUString     m_sHiddenValue;

public:
    DECLARE_DEFAULT_LEAF_XTOR( OHiddenModel );

    // OPropertySetHelper
    virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const;
    virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
                throw (::com::sun::star::uno::Exception);
    virtual sal_Bool SAL_CALL convertFastPropertyValue(
                ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
                throw (::com::sun::star::lang::IllegalArgumentException);

    // XPropertySetRef
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(::com::sun::star::uno::RuntimeException);
    virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();

    // XServiceInfo
    IMPLEMENTATION_NAME(OHiddenModel);
    virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);

    // XPersistObject
    virtual ::rtl::OUString SAL_CALL    getServiceName() throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        write(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL
        read(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);

// OAggregationArrayUsageHelper
    virtual void fillProperties(
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps,
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
        ) const;
    IMPLEMENT_INFO_SERVICE()

protected:
    DECLARE_XCLONEABLE( );
};

#endif // _FORMS_HIDDEN_HXX_

//.........................................................................
}
//.........................................................................

<|endoftext|>


<commit_before>#include "IGTLinkStreamer.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/AffineTransformation.hpp"
#include <igtl/igtlOSUtil.h>
#include <igtl/igtlMessageHeader.h>
#include <igtl/igtlTransformMessage.h>
#include <igtl/igtlPositionMessage.h>
#include <igtl/igtlImageMessage.h>
#include <igtl/igtlStatusMessage.h>
#include <igtl/igtlStringMessage.h>

namespace fast {

void IGTLinkStreamer::setConnectionAddress(std::string address) {
    mAddress = address;
    mIsModified = true;
}

void IGTLinkStreamer::setConnectionPort(uint port) {
    mPort = port;
    mIsModified = true;
}

DataPort::pointer IGTLinkStreamer::getOutputPort() {
	uint portID;
	if (mOutputPortDeviceNames.count("") == 0) {
		portID = getNrOfOutputPorts();
		createOutputPort<Image>(portID);
		getOutputData<Image>(portID); // This initializes the output data
		mOutputPortDeviceNames[""] = portID;
	}
	else {
		portID = mOutputPortDeviceNames[""];
	}
	return ProcessObject::getOutputPort(portID);
}

bool IGTLinkStreamer::hasReachedEnd() {
    return mHasReachedEnd;
}

uint IGTLinkStreamer::getNrOfFrames() const {
    return mNrOfFrames;
}

std::set<std::string> IGTLinkStreamer::getImageStreamNames() {
    return mImageStreamNames;
}

std::set<std::string> IGTLinkStreamer::getTransformStreamNames() {
    return mTransformStreamNames;
}

std::string IGTLinkStreamer::getStreamDescription(std::string streamName) {
    return mStreamDescriptions.at(streamName);
}

std::vector<std::string> IGTLinkStreamer::getActiveImageStreamNames() {
    std::vector<std::string> activeStreams;
    for(auto stream : mOutputPortDeviceNames) {
        if(mImageStreamNames.count(stream.first) > 0)
            activeStreams.push_back(stream.first);
    }
    return activeStreams;
}

std::vector<std::string> IGTLinkStreamer::getActiveTransformStreamNames() {
    std::vector<std::string> activeStreams;
    for(auto stream : mOutputPortDeviceNames) {
        if(mTransformStreamNames.count(stream.first) > 0)
            activeStreams.push_back(stream.first);
    }
    return activeStreams;
}

static Image::pointer createFASTImageFromMessage(igtl::ImageMessage::Pointer message, ExecutionDevice::pointer device) {
    Image::pointer image = Image::New();
    int width, height, depth;
    message->GetDimensions(width, height, depth);
    void* data = message->GetScalarPointer();
    DataType type;
    switch(message->GetScalarType()) {
        case igtl::ImageMessage::TYPE_INT8:
            type = TYPE_INT8;
            break;
        case igtl::ImageMessage::TYPE_UINT8:
            type = TYPE_UINT8;
            break;
        case igtl::ImageMessage::TYPE_INT16:
            type = TYPE_INT16;
            break;
        case igtl::ImageMessage::TYPE_UINT16:
            type = TYPE_UINT16;
            break;
        case igtl::ImageMessage::TYPE_FLOAT32:
            type = TYPE_FLOAT;
            break;
        default:
            throw Exception("Unsupported image data type.");
            break;
    }

    if(depth == 1) {
        image->create(width, height, type, message->GetNumComponents(), device, data);
    } else {
        image->create(width, height, depth, type, message->GetNumComponents(), device, data);
    }

    auto spacing = std::make_unique<float[]>(3);
    auto offset = std::make_unique<float[]>(3);
    message->GetSpacing(spacing.get());
    message->GetOrigin(offset.get());
    igtl::Matrix4x4 matrix;
    message->GetMatrix(matrix);
    image->setSpacing(Vector3f(spacing[0], spacing[1], spacing[2]));
    AffineTransformation::pointer T = AffineTransformation::New();
    T->getTransform().translation() = Vector3f(offset[0], offset[1], offset[2]);
    Matrix3f fastMatrix;
    for(int i = 0; i < 3; i++) {
    for(int j = 0; j < 3; j++) {
        fastMatrix(i,j) = matrix[i][j];
    }}
    T->getTransform().linear() = fastMatrix;
    image->getSceneGraphNode()->setTransformation(T);

    return image;
}

void IGTLinkStreamer::updateFirstFrameSetFlag() {
    // Check that all output ports have got their first frame
    bool allHaveGotData = true;
    for(auto port : mOutputConnections) {
        for(auto output : port.second) {
            if(output.lock()->getSize() == 0)
                allHaveGotData = false;
        }
    }

    if(allHaveGotData) {
        {
            std::lock_guard<std::mutex> lock(mFirstFrameMutex);
            mFirstFrameIsInserted = true;
        }
        mFirstFrameCondition.notify_one();
    } else {
        reportInfo() << "ALL HAVE NOT GOT DATA" << Reporter::end();
    }
}

void IGTLinkStreamer::producerStream() {

    reportInfo() << "Connected to Open IGT Link server" << Reporter::end();;

    // Create a message buffer to receive header
    igtl::MessageHeader::Pointer headerMsg;
    headerMsg = igtl::MessageHeader::New();

    // Allocate a time stamp
    igtl::TimeStamp::Pointer ts;
    ts = igtl::TimeStamp::New();
    uint statusMessageCounter = 0;

    while(true) {
        {
            std::unique_lock<std::mutex> lock(mStopMutex);
            if(mStop) {
                mStreamIsStarted = false;
                mFirstFrameIsInserted = false;
                mHasReachedEnd = false;
                break;
            }
        }

        // Initialize receive buffer
        headerMsg->InitPack();

        // Receive generic header from the socket
        int r = mSocket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize());
        if(r == 0) {
            //connectionLostSignal();
            mSocket->CloseSocket();
            break;
        }
        if(r != headerMsg->GetPackSize()) {
           continue;
        }

        // Deserialize the header
        headerMsg->Unpack();

        // Get time stamp
        headerMsg->GetTimeStamp(ts);

        std::string deviceName = headerMsg->GetDeviceName();
        reportInfo() << "Device name: " << deviceName << Reporter::end();
        bool ignore = false;
        if(mOutputPortDeviceNames.count(deviceName) == 0) {
            if(mOutputPortDeviceNames.count("") > 0 && strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0) {
                // If no specific output ports have been specified, choose this first one
                mOutputPortDeviceNames[headerMsg->GetDeviceName()] = mOutputPortDeviceNames[""];
                mOutputPortDeviceNames.erase("");
            } else {
                // Ignore this device stream if it doesn't exist
                ignore = true;
            }
        }

        unsigned long timestamp = round(ts->GetTimeStamp()*1000); // convert to milliseconds
        reportInfo() << "TIMESTAMP converted: " << timestamp << reportEnd();
        if(strcmp(headerMsg->GetDeviceType(), "TRANSFORM") == 0 && !ignore) {
            mTransformStreamNames.insert(headerMsg->GetDeviceName());
            mStreamDescriptions[headerMsg->GetDeviceName()] = "Transform";
            if(mInFreezeMode) {
                //unfreezeSignal();
                mInFreezeMode = false;
            }
            statusMessageCounter = 0;
            igtl::TransformMessage::Pointer transMsg;
            transMsg = igtl::TransformMessage::New();
            transMsg->SetMessageHeader(headerMsg);
            transMsg->AllocatePack();
            // Receive transform data from the socket
            mSocket->Receive(transMsg->GetPackBodyPointer(), transMsg->GetPackBodySize());
            // Deserialize the transform data
            // If you want to skip CRC check, call Unpack() without argument.
            int c = transMsg->Unpack(1);

            if(c & igtl::MessageHeader::UNPACK_BODY) { // if CRC check is OK
                // Retrive the transform data
                igtl::Matrix4x4 matrix;
                transMsg->GetMatrix(matrix);
                Matrix4f fastMatrix;
                for(int i = 0; i < 4; i++) {
                for(int j = 0; j < 4; j++) {
                    fastMatrix(i,j) = matrix[i][j];
                }}
                reportInfo() << fastMatrix << Reporter::end();

                try {
                    AffineTransformation::pointer T = AffineTransformation::New();
                    T->getTransform().matrix() = fastMatrix;
                    T->setCreationTimestamp(timestamp);
                    addOutputData(mOutputPortDeviceNames[deviceName], T);
                } catch(NoMoreFramesException &e) {
                    throw e;
                } catch(Exception &e) {
                    reportInfo() << "streamer has been deleted, stop" << Reporter::end();
                    break;
                }
                if(!mFirstFrameIsInserted) {
                    updateFirstFrameSetFlag();
                }
                mNrOfFrames++;
            }
        } else if(strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0 && !ignore) {
            mImageStreamNames.insert(headerMsg->GetDeviceName());
            if(mInFreezeMode) {
                //unfreezeSignal();
                mInFreezeMode = false;
            }
            statusMessageCounter = 0;
            reportInfo() << "Receiving IMAGE data type from device " << headerMsg->GetDeviceName() << Reporter::end();

            // Create a message buffer to receive transform data
            igtl::ImageMessage::Pointer imgMsg;
            imgMsg = igtl::ImageMessage::New();
            imgMsg->SetMessageHeader(headerMsg);
            imgMsg->AllocatePack();

            // Receive transform data from the socket
            mSocket->Receive(imgMsg->GetPackBodyPointer(), imgMsg->GetPackBodySize());

            // Deserialize the transform data
            // If you want to skip CRC check, call Unpack() without argument.
            int c = imgMsg->Unpack(1);
            if(c & igtl::MessageHeader::UNPACK_BODY) { // if CRC check is OK

                // Retrive the image data
                int size[3]; // image dimension
                float spacing[3]; // spacing (mm/pixel)
                int svsize[3]; // sub-volume size
                int svoffset[3]; // sub-volume offset
                int scalarType; // scalar type
                scalarType = imgMsg->GetScalarType();
                imgMsg->GetDimensions(size);
                imgMsg->GetSpacing(spacing);
                imgMsg->GetSubVolume(svsize, svoffset);

                std::string description = "";
                if(size[2] == 1) {
                    description = "2D, " + std::to_string(size[0]) + "x" + std::to_string(size[1]);
                } else {
                    description = "3D, " + std::to_string(size[0]) + "x" + std::to_string(size[1]) + "x" + std::to_string(size[2]);
                }
                description += ", " + std::to_string(imgMsg->GetNumComponents()) + " channels, " + std::to_string(imgMsg->GetScalarSize()*8) + "bit";
                mStreamDescriptions[headerMsg->GetDeviceName()] = description;

                try {
                    Image::pointer image = createFASTImageFromMessage(imgMsg, getMainDevice());
                    image->setCreationTimestamp(timestamp);
                    addOutputData(mOutputPortDeviceNames[deviceName], image);
                } catch(NoMoreFramesException &e) {
                    throw e;
                } catch(Exception &e) {
                    reportInfo() << "streamer has been deleted, stop" << Reporter::end();
                    break;
                }
                if(!mFirstFrameIsInserted) {
                    updateFirstFrameSetFlag();
                }
                mNrOfFrames++;
            }
        } else if(strcmp(headerMsg->GetDeviceType(), "STATUS") == 0) {
            ++statusMessageCounter;
            reportInfo() << "STATUS MESSAGE recieved" << Reporter::end();
            // Receive generic message
            igtl::MessageBase::Pointer message;
            message = igtl::MessageBase::New();
            message->SetMessageHeader(headerMsg);
            message->AllocatePack();

            // Receive transform data from the socket
            mSocket->Receive(message->GetPackBodyPointer(), message->GetPackBodySize());
            if(statusMessageCounter > 3 && !mInFreezeMode) {
                reportInfo() << "3 STATUS MESSAGE received, freeze detected" << Reporter::end();
                mInFreezeMode = true;
                //freezeSignal();

                // If no frames has been inserted, stop
                if(!mFirstFrameIsInserted) {
					{
						std::lock_guard<std::mutex> lock(mFirstFrameMutex);
						mFirstFrameIsInserted = true;
					}
					mStop = true;
					mFirstFrameCondition.notify_one();
                }
            }
       } else {
           // Receive generic message
          igtl::MessageBase::Pointer message;
          message = igtl::MessageBase::New();
          message->SetMessageHeader(headerMsg);
          message->AllocatePack();

          // Receive transform data from the socket
          mSocket->Receive(message->GetPackBodyPointer(), message->GetPackBodySize());

          // Deserialize the transform data
          // If you want to skip CRC check, call Unpack() without argument.
          int c = message->Unpack();
       }
    }
    // Make sure we end the waiting thread if first frame has not been inserted
    {
        std::lock_guard<std::mutex> lock(mFirstFrameMutex);
        if(!mFirstFrameIsInserted)
            mFirstFrameIsInserted = true;
    }
    mFirstFrameCondition.notify_one();
    mSocket->CloseSocket();
    reportInfo() << "OpenIGTLink socket closed" << reportEnd();
}

IGTLinkStreamer::~IGTLinkStreamer() {
    if(mStreamIsStarted) {
        stop();
        stopPipeline();
        if(thread->get_id() != std::this_thread::get_id()) { // avoid deadlock
            thread->join();
        }
        delete thread;
    }
}

IGTLinkStreamer::IGTLinkStreamer() {
    mStreamIsStarted = false;
    mIsModified = true;
    thread = NULL;
    mFirstFrameIsInserted = false;
    mHasReachedEnd = false;
    mStop = false;
    mNrOfFrames = 0;
    mAddress = "localhost";
    mPort = 18944;
    mMaximumNrOfFramesSet = false;
    mInFreezeMode = false;
}

void IGTLinkStreamer::stop() {
    std::unique_lock<std::mutex> lock(mStopMutex);
    mStop = true;
}

void IGTLinkStreamer::execute() {

    if(!mStreamIsStarted) {

        mSocket = igtl::ClientSocket::New();
        reportInfo() << "Trying to connect to Open IGT Link server " << mAddress << ":" << std::to_string(mPort) << Reporter::end();
        int r = mSocket->ConnectToServer(mAddress.c_str(), mPort);
        if(r != 0) {
            throw Exception("Failed to connect to Open IGT Link server " + mAddress + ":" + std::to_string(mPort));
        }

        mStreamIsStarted = true;
        thread = new std::thread(std::bind(&IGTLinkStreamer::producerStream, this));
    }

    // Wait here for first frame
    std::unique_lock<std::mutex> lock(mFirstFrameMutex);
    while(!mFirstFrameIsInserted) {
        mFirstFrameCondition.wait(lock);
    }
    {
        std::unique_lock<std::mutex> lock(mStopMutex);
        //if(!mStop)
        //    connectionEstablishedSignal(); // send signal
    }
}

} // end namespace fast
<commit_msg>fixed creation timestamp for OpenIGTLink streamer<commit_after>#include "IGTLinkStreamer.hpp"
#include "FAST/Data/Image.hpp"
#include "FAST/AffineTransformation.hpp"
#include <igtl/igtlOSUtil.h>
#include <igtl/igtlMessageHeader.h>
#include <igtl/igtlTransformMessage.h>
#include <igtl/igtlPositionMessage.h>
#include <igtl/igtlImageMessage.h>
#include <igtl/igtlStatusMessage.h>
#include <igtl/igtlStringMessage.h>
#include <chrono>

namespace fast {

void IGTLinkStreamer::setConnectionAddress(std::string address) {
    mAddress = address;
    mIsModified = true;
}

void IGTLinkStreamer::setConnectionPort(uint port) {
    mPort = port;
    mIsModified = true;
}

DataPort::pointer IGTLinkStreamer::getOutputPort() {
	uint portID;
	if (mOutputPortDeviceNames.count("") == 0) {
		portID = getNrOfOutputPorts();
		createOutputPort<Image>(portID);
		getOutputData<Image>(portID); // This initializes the output data
		mOutputPortDeviceNames[""] = portID;
	}
	else {
		portID = mOutputPortDeviceNames[""];
	}
	return ProcessObject::getOutputPort(portID);
}

bool IGTLinkStreamer::hasReachedEnd() {
    return mHasReachedEnd;
}

uint IGTLinkStreamer::getNrOfFrames() const {
    return mNrOfFrames;
}

std::set<std::string> IGTLinkStreamer::getImageStreamNames() {
    return mImageStreamNames;
}

std::set<std::string> IGTLinkStreamer::getTransformStreamNames() {
    return mTransformStreamNames;
}

std::string IGTLinkStreamer::getStreamDescription(std::string streamName) {
    return mStreamDescriptions.at(streamName);
}

std::vector<std::string> IGTLinkStreamer::getActiveImageStreamNames() {
    std::vector<std::string> activeStreams;
    for(auto stream : mOutputPortDeviceNames) {
        if(mImageStreamNames.count(stream.first) > 0)
            activeStreams.push_back(stream.first);
    }
    return activeStreams;
}

std::vector<std::string> IGTLinkStreamer::getActiveTransformStreamNames() {
    std::vector<std::string> activeStreams;
    for(auto stream : mOutputPortDeviceNames) {
        if(mTransformStreamNames.count(stream.first) > 0)
            activeStreams.push_back(stream.first);
    }
    return activeStreams;
}

static Image::pointer createFASTImageFromMessage(igtl::ImageMessage::Pointer message, ExecutionDevice::pointer device) {
    Image::pointer image = Image::New();
    int width, height, depth;
    message->GetDimensions(width, height, depth);
    void* data = message->GetScalarPointer();
    DataType type;
    switch(message->GetScalarType()) {
        case igtl::ImageMessage::TYPE_INT8:
            type = TYPE_INT8;
            break;
        case igtl::ImageMessage::TYPE_UINT8:
            type = TYPE_UINT8;
            break;
        case igtl::ImageMessage::TYPE_INT16:
            type = TYPE_INT16;
            break;
        case igtl::ImageMessage::TYPE_UINT16:
            type = TYPE_UINT16;
            break;
        case igtl::ImageMessage::TYPE_FLOAT32:
            type = TYPE_FLOAT;
            break;
        default:
            throw Exception("Unsupported image data type.");
            break;
    }

    if(depth == 1) {
        image->create(width, height, type, message->GetNumComponents(), device, data);
    } else {
        image->create(width, height, depth, type, message->GetNumComponents(), device, data);
    }

    auto spacing = std::make_unique<float[]>(3);
    auto offset = std::make_unique<float[]>(3);
    message->GetSpacing(spacing.get());
    message->GetOrigin(offset.get());
    igtl::Matrix4x4 matrix;
    message->GetMatrix(matrix);
    image->setSpacing(Vector3f(spacing[0], spacing[1], spacing[2]));
    AffineTransformation::pointer T = AffineTransformation::New();
    T->getTransform().translation() = Vector3f(offset[0], offset[1], offset[2]);
    Matrix3f fastMatrix;
    for(int i = 0; i < 3; i++) {
    for(int j = 0; j < 3; j++) {
        fastMatrix(i,j) = matrix[i][j];
    }}
    T->getTransform().linear() = fastMatrix;
    image->getSceneGraphNode()->setTransformation(T);

    return image;
}

void IGTLinkStreamer::updateFirstFrameSetFlag() {
    // Check that all output ports have got their first frame
    bool allHaveGotData = true;
    for(auto port : mOutputConnections) {
        for(auto output : port.second) {
            if(output.lock()->getSize() == 0)
                allHaveGotData = false;
        }
    }

    if(allHaveGotData) {
        {
            std::lock_guard<std::mutex> lock(mFirstFrameMutex);
            mFirstFrameIsInserted = true;
        }
        mFirstFrameCondition.notify_one();
    } else {
        reportInfo() << "ALL HAVE NOT GOT DATA" << Reporter::end();
    }
}

void IGTLinkStreamer::producerStream() {

    reportInfo() << "Connected to Open IGT Link server" << Reporter::end();;

    // Create a message buffer to receive header
    igtl::MessageHeader::Pointer headerMsg;
    headerMsg = igtl::MessageHeader::New();

    // Allocate a time stamp
    igtl::TimeStamp::Pointer ts;
    ts = igtl::TimeStamp::New();
    uint statusMessageCounter = 0;

    auto start = std::chrono::high_resolution_clock::now();

    while(true) {
        {
            std::unique_lock<std::mutex> lock(mStopMutex);
            if(mStop) {
                mStreamIsStarted = false;
                mFirstFrameIsInserted = false;
                mHasReachedEnd = false;
                break;
            }
        }

        // Initialize receive buffer
        headerMsg->InitPack();

        // Receive generic header from the socket
        int r = mSocket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize());
        if(r == 0) {
            //connectionLostSignal();
            mSocket->CloseSocket();
            break;
        }
        if(r != headerMsg->GetPackSize()) {
           continue;
        }

        // Deserialize the header
        headerMsg->Unpack();

        // Get time stamp
        headerMsg->GetTimeStamp(ts);

        std::string deviceName = headerMsg->GetDeviceName();
        reportInfo() << "Device name: " << deviceName << Reporter::end();
        bool ignore = false;
        if(mOutputPortDeviceNames.count(deviceName) == 0) {
            if(mOutputPortDeviceNames.count("") > 0 && strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0) {
                // If no specific output ports have been specified, choose this first one
                mOutputPortDeviceNames[headerMsg->GetDeviceName()] = mOutputPortDeviceNames[""];
                mOutputPortDeviceNames.erase("");
            } else {
                // Ignore this device stream if it doesn't exist
                ignore = true;
            }
        }

        //unsigned long timestamp = round(ts->GetTimeStamp()*1000); // convert to milliseconds
        auto now = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double, std::milli> duration = now - start;
        uint64_t timestamp = duration.count();
        reportInfo() << "TIMESTAMP converted: " << timestamp << reportEnd();
        if(strcmp(headerMsg->GetDeviceType(), "TRANSFORM") == 0 && !ignore) {
            mTransformStreamNames.insert(headerMsg->GetDeviceName());
            mStreamDescriptions[headerMsg->GetDeviceName()] = "Transform";
            if(mInFreezeMode) {
                //unfreezeSignal();
                mInFreezeMode = false;
            }
            statusMessageCounter = 0;
            igtl::TransformMessage::Pointer transMsg;
            transMsg = igtl::TransformMessage::New();
            transMsg->SetMessageHeader(headerMsg);
            transMsg->AllocatePack();
            // Receive transform data from the socket
            mSocket->Receive(transMsg->GetPackBodyPointer(), transMsg->GetPackBodySize());
            // Deserialize the transform data
            // If you want to skip CRC check, call Unpack() without argument.
            int c = transMsg->Unpack(1);

            if(c & igtl::MessageHeader::UNPACK_BODY) { // if CRC check is OK
                // Retrive the transform data
                igtl::Matrix4x4 matrix;
                transMsg->GetMatrix(matrix);
                Matrix4f fastMatrix;
                for(int i = 0; i < 4; i++) {
                for(int j = 0; j < 4; j++) {
                    fastMatrix(i,j) = matrix[i][j];
                }}
                reportInfo() << fastMatrix << Reporter::end();

                try {
                    AffineTransformation::pointer T = AffineTransformation::New();
                    T->getTransform().matrix() = fastMatrix;
                    T->setCreationTimestamp(timestamp);
                    addOutputData(mOutputPortDeviceNames[deviceName], T);
                } catch(NoMoreFramesException &e) {
                    throw e;
                } catch(Exception &e) {
                    reportInfo() << "streamer has been deleted, stop" << Reporter::end();
                    break;
                }
                if(!mFirstFrameIsInserted) {
                    updateFirstFrameSetFlag();
                }
                mNrOfFrames++;
            }
        } else if(strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0 && !ignore) {
            mImageStreamNames.insert(headerMsg->GetDeviceName());
            if(mInFreezeMode) {
                //unfreezeSignal();
                mInFreezeMode = false;
            }
            statusMessageCounter = 0;
            reportInfo() << "Receiving IMAGE data type from device " << headerMsg->GetDeviceName() << Reporter::end();

            // Create a message buffer to receive transform data
            igtl::ImageMessage::Pointer imgMsg;
            imgMsg = igtl::ImageMessage::New();
            imgMsg->SetMessageHeader(headerMsg);
            imgMsg->AllocatePack();

            // Receive transform data from the socket
            mSocket->Receive(imgMsg->GetPackBodyPointer(), imgMsg->GetPackBodySize());

            // Deserialize the transform data
            // If you want to skip CRC check, call Unpack() without argument.
            int c = imgMsg->Unpack(1);
            if(c & igtl::MessageHeader::UNPACK_BODY) { // if CRC check is OK

                // Retrive the image data
                int size[3]; // image dimension
                float spacing[3]; // spacing (mm/pixel)
                int svsize[3]; // sub-volume size
                int svoffset[3]; // sub-volume offset
                int scalarType; // scalar type
                scalarType = imgMsg->GetScalarType();
                imgMsg->GetDimensions(size);
                imgMsg->GetSpacing(spacing);
                imgMsg->GetSubVolume(svsize, svoffset);

                std::string description = "";
                if(size[2] == 1) {
                    description = "2D, " + std::to_string(size[0]) + "x" + std::to_string(size[1]);
                } else {
                    description = "3D, " + std::to_string(size[0]) + "x" + std::to_string(size[1]) + "x" + std::to_string(size[2]);
                }
                description += ", " + std::to_string(imgMsg->GetNumComponents()) + " channels, " + std::to_string(imgMsg->GetScalarSize()*8) + "bit";
                mStreamDescriptions[headerMsg->GetDeviceName()] = description;

                try {
                    Image::pointer image = createFASTImageFromMessage(imgMsg, getMainDevice());
                    image->setCreationTimestamp(timestamp);
                    addOutputData(mOutputPortDeviceNames[deviceName], image);
                } catch(NoMoreFramesException &e) {
                    throw e;
                } catch(Exception &e) {
                    reportInfo() << "streamer has been deleted, stop" << Reporter::end();
                    break;
                }
                if(!mFirstFrameIsInserted) {
                    updateFirstFrameSetFlag();
                }
                mNrOfFrames++;
            }
        } else if(strcmp(headerMsg->GetDeviceType(), "STATUS") == 0) {
            ++statusMessageCounter;
            reportInfo() << "STATUS MESSAGE recieved" << Reporter::end();
            // Receive generic message
            igtl::MessageBase::Pointer message;
            message = igtl::MessageBase::New();
            message->SetMessageHeader(headerMsg);
            message->AllocatePack();

            // Receive transform data from the socket
            mSocket->Receive(message->GetPackBodyPointer(), message->GetPackBodySize());
            if(statusMessageCounter > 3 && !mInFreezeMode) {
                reportInfo() << "3 STATUS MESSAGE received, freeze detected" << Reporter::end();
                mInFreezeMode = true;
                //freezeSignal();

                // If no frames has been inserted, stop
                if(!mFirstFrameIsInserted) {
					{
						std::lock_guard<std::mutex> lock(mFirstFrameMutex);
						mFirstFrameIsInserted = true;
					}
					mStop = true;
					mFirstFrameCondition.notify_one();
                }
            }
       } else {
           // Receive generic message
          igtl::MessageBase::Pointer message;
          message = igtl::MessageBase::New();
          message->SetMessageHeader(headerMsg);
          message->AllocatePack();

          // Receive transform data from the socket
          mSocket->Receive(message->GetPackBodyPointer(), message->GetPackBodySize());

          // Deserialize the transform data
          // If you want to skip CRC check, call Unpack() without argument.
          int c = message->Unpack();
       }
    }
    // Make sure we end the waiting thread if first frame has not been inserted
    {
        std::lock_guard<std::mutex> lock(mFirstFrameMutex);
        if(!mFirstFrameIsInserted)
            mFirstFrameIsInserted = true;
    }
    mFirstFrameCondition.notify_one();
    mSocket->CloseSocket();
    reportInfo() << "OpenIGTLink socket closed" << reportEnd();
}

IGTLinkStreamer::~IGTLinkStreamer() {
    if(mStreamIsStarted) {
        stop();
        stopPipeline();
        if(thread->get_id() != std::this_thread::get_id()) { // avoid deadlock
            thread->join();
        }
        delete thread;
    }
}

IGTLinkStreamer::IGTLinkStreamer() {
    mStreamIsStarted = false;
    mIsModified = true;
    thread = NULL;
    mFirstFrameIsInserted = false;
    mHasReachedEnd = false;
    mStop = false;
    mNrOfFrames = 0;
    mAddress = "localhost";
    mPort = 18944;
    mMaximumNrOfFramesSet = false;
    mInFreezeMode = false;
}

void IGTLinkStreamer::stop() {
    std::unique_lock<std::mutex> lock(mStopMutex);
    mStop = true;
}

void IGTLinkStreamer::execute() {

    if(!mStreamIsStarted) {

        mSocket = igtl::ClientSocket::New();
        reportInfo() << "Trying to connect to Open IGT Link server " << mAddress << ":" << std::to_string(mPort) << Reporter::end();
        int r = mSocket->ConnectToServer(mAddress.c_str(), mPort);
        if(r != 0) {
            throw Exception("Failed to connect to Open IGT Link server " + mAddress + ":" + std::to_string(mPort));
        }

        mStreamIsStarted = true;
        thread = new std::thread(std::bind(&IGTLinkStreamer::producerStream, this));
    }

    // Wait here for first frame
    std::unique_lock<std::mutex> lock(mFirstFrameMutex);
    while(!mFirstFrameIsInserted) {
        mFirstFrameCondition.wait(lock);
    }
    {
        std::unique_lock<std::mutex> lock(mStopMutex);
        //if(!mStop)
        //    connectionEstablishedSignal(); // send signal
    }
}

} // end namespace fast
<|endoftext|>


<commit_before>/**
  The majority element is the element that occurs more
  than half of the size of the array.
  How to find the majority element in an array in O(n)?
  There is a guarantee that it exists.
*/
<commit_msg>frequent_element implementation<commit_after>/*
 * Copyright (C) 2015-2016 Pavel Dolgov
 *
 * See the LICENSE file for terms of use.
 */

/**
  The majority element is the element that occurs more
  than half of the size of the array.
  How to find the majority element in an array in O(n)?
  There is a guarantee that it exists.
*/

#include <bits/stdc++.h>

#define MAX_SIZE 100500

int main() {
    int array[MAX_SIZE];
    int size;
    std::cin >> size;
    for (int i = 0; i < size; i++) {
        std::cin >> array[i];
    }
    int count = 0, ans;
    for (int i = 0; i < size; i++) {
        if (count == 0) {
            ans = array[i];
        }
        if (array[i] == ans) {
            count++;
        } else {
            count--;
        }
    }
    std::cout << ans << std::endl;
    return 0;
}
<|endoftext|>