<commit_before>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2011 Emmanuel Benazera, <ebenazer@seeks-project.info>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "feeds.h"
#include "websearch_configuration.h"
#include "errlog.h"

#include <iostream>

using sp::errlog;

namespace seeks_plugins
{

  /*- feed_parser -*/
  feed_parser::feed_parser(const std::string &name,
                           const std::string &url)
    :_name(name)
  {
    add_url(url);
  }

  feed_parser::feed_parser(const std::string &name)
    :_name(name)
  {
  }

  feed_parser::feed_parser(const feed_parser &fp)
    :_name(fp._name),_urls(fp._urls)
  {
  }

  feed_parser::feed_parser(const std::string &name,
                           const std::set<std::string> &urls)
    :_name(name),_urls(urls)
  {
  }

  feed_parser::feed_parser()
  {
  }

  feed_parser::~feed_parser()
  {
  }

  bool feed_parser::empty() const
  {
    return _urls.empty();
  }

  void feed_parser::add_url(const std::string &url)
  {
    _urls.insert(url);
  }

  std::string feed_parser::get_url() const
  {
    if (_urls.empty())
      {
        errlog::log_error(LOG_LEVEL_ERROR,"feed parser %s has no url attached",_name.c_str());
        return "";
      }
    if (_urls.size()>1)
      errlog::log_error(LOG_LEVEL_INFO,"getting top url from feed parser %s that applies to several urls",
                        _name.c_str());
    return (*_urls.begin());
  }

  size_t feed_parser::size() const
  {
    return _urls.size();
  }

  feed_parser feed_parser::diff(const feed_parser &fp) const
  {
    std::set<std::string> output_diff;
    std::set_symmetric_difference(_urls.begin(),_urls.end(),
                                  fp._urls.begin(),fp._urls.end(),
                                  std::inserter(output_diff,output_diff.begin()));
    feed_parser fps(_name,output_diff);
    return fps;
  }

  feed_parser feed_parser::diff_nosym(const feed_parser &fp) const
  {
    std::set<std::string> output_diff;
    std::set_difference(_urls.begin(),_urls.end(),
                        fp._urls.begin(),fp._urls.end(),
                        std::inserter(output_diff,output_diff.begin()));
    feed_parser fps(_name,output_diff);
    return fps;
  }

  feed_parser feed_parser::sunion(const feed_parser &fp) const
  {
    std::set<std::string> output_union;
    std::set_union(_urls.begin(),_urls.end(),
                   fp._urls.begin(),fp._urls.end(),
                   std::inserter(output_union,output_union.begin()));
    feed_parser fps(_name,output_union);
    return fps;
  }

  feed_parser feed_parser::inter(const feed_parser &fp) const
  {
    std::set<std::string> output_inter;
    std::set_intersection(_urls.begin(),_urls.end(),
                          fp._urls.begin(),fp._urls.end(),
                          std::inserter(output_inter,output_inter.begin()));
    feed_parser fps(_name,output_inter);
    return fps;
  }

  /*- feeds -*/
  feeds::feeds()
  {
  }

  feeds::feeds(std::set<feed_parser,feed_parser::lxn> &feedset)
  {
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = feedset.begin();
    while(it!=feedset.end())
      {
        add_feed((*it));
        ++it;
      }
  }

  feeds::feeds(const std::string &name)
  {
    add_feed(feed_parser(name));
  }

  feeds::feeds(const std::string &name,
               const std::string &url)
  {
    add_feed(feed_parser(name,url));
  }

  feeds::feeds(const feeds &f)
  {
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = f._feedset.begin();
    while(it!=f._feedset.end())
      {
        add_feed((*it));
        ++it;
      }
  }

  feeds::~feeds()
  {
  }

  bool feeds::add_feed(const std::string &name,
                       const std::string &url)
  {
    return add_feed(feed_parser(name,url));
  }

  bool feeds::add_feed(const std::string &name)
  {
    return add_feed(feed_parser(name));
  }

  bool feeds::add_feed(const feed_parser &f)
  {
    if (f.empty())
      return false;
    std::pair<std::set<feed_parser,feed_parser::lxn>::iterator,bool> ret
    = _feedset.insert(f);
    if (!ret.second)
      {
        feed_parser fp = find_feed(f._name);
        feed_parser fdiff = f.diff_nosym(fp);
        if (!fdiff.empty())
          {
            feed_parser funion = fp.sunion(f);
            if (funion.size() == f.size())
              remove_feed(f._name);
            ret.second = add_feed(funion);
          }
      }
    return ret.second;
  }

  bool feeds::add_feed(const std::string &name,
                       websearch_configuration *wconfig)
  {
    if (!wconfig)
      return add_feed(name);
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::iterator it
    = wconfig->_se_enabled._feedset.find(fp);
    if (it == wconfig->_se_enabled._feedset.end())
      {
        errlog::log_error(LOG_LEVEL_ERROR,"Cannot find feed parser %s in configuration",
                          name.c_str());
        return false;
      }
    // copy and feed_parser object.
    feed_parser fp_ptr((*it));
    return add_feed(fp_ptr);
  }

  bool feeds::remove_feed(const std::string &name)
  {
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::iterator it;
    if ((it = _feedset.find(fp))!=_feedset.end())
      {
        _feedset.erase(it);
        return true;
      }
    return false;
  }

  feed_parser feeds::find_feed(const std::string &name) const
  {
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::const_iterator it;
    it = _feedset.find(fp);
    if (it != _feedset.end())
      return (*it);
    else return feed_parser("");
  }

  bool feeds::has_feed(const std::string &name) const
  {
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::const_iterator it;
    it = _feedset.find(fp);
    if (it != _feedset.end())
      return true;
    else return false;
  }

  size_t feeds::size() const
  {
    size_t total_urls = 0;
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = _feedset.begin();
    while(it!=_feedset.end())
      {
        total_urls += (*it).size();
        ++it;
      }
    return total_urls;
  }

  size_t feeds::count() const
  {
    return _feedset.size();
  }

  bool feeds::empty() const
  {
    return _feedset.empty();
  }

  feeds feeds::diff(const feeds &f) const
  {
    //feeds fds;
    /*const feeds *f1 = this, *f2 = &f;
    if (f1->count() < f2->count())
      {
    	f1 = &f;
    	f2 = this;
      }
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
      = f1->_feedset.begin();
    while(it!=f1->_feedset.end())
      {
    	feed_parser fd = f2->find_feed((*it)._name);
    	if (!fd._name.empty())
    {
      feed_parser fdiff = (*it).diff(fd);
      fds.add_feed(fdiff);
    }
    	++it;
    	}*/
    std::set<feed_parser,feed_parser::lxn> output_diff;
    std::set_symmetric_difference(_feedset.begin(),_feedset.end(),
                                  f._feedset.begin(),f._feedset.end(),
                                  std::inserter(output_diff,output_diff.begin()),
                                  feed_parser::lxn());
    feeds fds(output_diff);

    // intersection + diff + add it up to fds.
    feeds common = inter_gen(f);
    std::vector<feed_parser> to_add;
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = common._feedset.begin();
    while(it!=common._feedset.end())
      {
        feed_parser fdo = f.find_feed((*it)._name);
        feed_parser diffd = (*it).diff(fdo);
        if (!fds.add_feed(diffd))
          {
            // should never happen ?
            fds.remove_feed((*it)._name);
            to_add.push_back(diffd);
          }
        ++it;
      }
    for (size_t i=0; i<to_add.size(); i++)
      fds.add_feed(to_add.at(i));

    return fds;
  }

  feeds feeds::sunion(const feeds &f) const
  {
    std::set<feed_parser,feed_parser::lxn> output_union;
    std::set_union(_feedset.begin(),_feedset.end(),
                   f._feedset.begin(),f._feedset.end(),
                   std::inserter(output_union,output_union.begin()),
                   feed_parser::lxn());
    feeds fds(output_union);

    // intersection + union + add it up to fds.
    feeds common = inter_gen(f);
    std::vector<feed_parser> to_add;
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = common._feedset.begin();
    while(it!=common._feedset.end())
      {
        feed_parser fdo = f.find_feed((*it)._name);
        feed_parser uniond = (*it).sunion(fdo);
        if (!fds.add_feed(uniond))
          {
            fds.remove_feed((*it)._name);
            to_add.push_back(uniond);
          }
        ++it;
      }
    for (size_t i=0; i<to_add.size(); i++)
      fds.add_feed(to_add.at(i));
    return fds;
  }

  feeds feeds::inter(const feeds &f) const
  {
    std::set<feed_parser,feed_parser::lxn> output_inter;
    std::set_intersection(_feedset.begin(),_feedset.end(),
                          f._feedset.begin(),f._feedset.end(),
                          std::inserter(output_inter,output_inter.begin()),
                          feed_parser::lxn());
    feeds fds(output_inter);

    // intersection + inter + add it up to output_inter.
    std::vector<feed_parser> to_add;
    std::set<feed_parser,feed_parser::lxn>::iterator it
    = fds._feedset.begin();
    while(it!=fds._feedset.end())
      {
        feed_parser fdo = f.find_feed((*it)._name);
        const feed_parser interd((*it).inter(fdo));
        if (interd.empty())
          {
            std::set<feed_parser,feed_parser::lxn>::iterator it1 = it;
            ++it;
            fds._feedset.erase(it1);
          }
        else
          {
            to_add.push_back(interd);
            ++it;
          }
      }
    for (size_t i=0; i<to_add.size(); i++)
      fds.add_feed(to_add.at(i));
    return fds;
  }

  feeds feeds::inter_gen(const feeds &f) const
  {
    std::set<feed_parser,feed_parser::lxn> output_inter;
    std::set_intersection(_feedset.begin(),_feedset.end(),
                          f._feedset.begin(),f._feedset.end(),
                          std::inserter(output_inter,output_inter.begin()),
                          feed_parser::lxn());
    feeds fds(output_inter);
    return fds;
  }

  bool feeds::equal(const feeds &f) const
  {
    /*feeds intersect = inter(f);
      return (intersect.size() == f.size());*/
    if (size() != f.size()
        || count() != f.count())
      return false;
    feeds intersect = inter(f);
    if (intersect.size() == f.size()
        && intersect.size() == size()
        && intersect.count() == f.count()
        && intersect.count() == count())
      return true;
    else return false;
  }

} /* end of namespace. */
<commit_msg>added errlog output when trying to add empty feed to feed list<commit_after>/**
 * The Seeks proxy and plugin framework are part of the SEEKS project.
 * Copyright (C) 2011 Emmanuel Benazera, <ebenazer@seeks-project.info>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "feeds.h"
#include "websearch_configuration.h"
#include "errlog.h"

#include <iostream>

using sp::errlog;

namespace seeks_plugins
{

  /*- feed_parser -*/
  feed_parser::feed_parser(const std::string &name,
                           const std::string &url)
    :_name(name)
  {
    add_url(url);
  }

  feed_parser::feed_parser(const std::string &name)
    :_name(name)
  {
  }

  feed_parser::feed_parser(const feed_parser &fp)
    :_name(fp._name),_urls(fp._urls)
  {
  }

  feed_parser::feed_parser(const std::string &name,
                           const std::set<std::string> &urls)
    :_name(name),_urls(urls)
  {
  }

  feed_parser::feed_parser()
  {
  }

  feed_parser::~feed_parser()
  {
  }

  bool feed_parser::empty() const
  {
    return _urls.empty();
  }

  void feed_parser::add_url(const std::string &url)
  {
    _urls.insert(url);
  }

  std::string feed_parser::get_url() const
  {
    if (_urls.empty())
      {
        errlog::log_error(LOG_LEVEL_ERROR,"feed parser %s has no url attached",_name.c_str());
        return "";
      }
    if (_urls.size()>1)
      errlog::log_error(LOG_LEVEL_INFO,"getting top url from feed parser %s that applies to several urls",
                        _name.c_str());
    return (*_urls.begin());
  }

  size_t feed_parser::size() const
  {
    return _urls.size();
  }

  feed_parser feed_parser::diff(const feed_parser &fp) const
  {
    std::set<std::string> output_diff;
    std::set_symmetric_difference(_urls.begin(),_urls.end(),
                                  fp._urls.begin(),fp._urls.end(),
                                  std::inserter(output_diff,output_diff.begin()));
    feed_parser fps(_name,output_diff);
    return fps;
  }

  feed_parser feed_parser::diff_nosym(const feed_parser &fp) const
  {
    std::set<std::string> output_diff;
    std::set_difference(_urls.begin(),_urls.end(),
                        fp._urls.begin(),fp._urls.end(),
                        std::inserter(output_diff,output_diff.begin()));
    feed_parser fps(_name,output_diff);
    return fps;
  }

  feed_parser feed_parser::sunion(const feed_parser &fp) const
  {
    std::set<std::string> output_union;
    std::set_union(_urls.begin(),_urls.end(),
                   fp._urls.begin(),fp._urls.end(),
                   std::inserter(output_union,output_union.begin()));
    feed_parser fps(_name,output_union);
    return fps;
  }

  feed_parser feed_parser::inter(const feed_parser &fp) const
  {
    std::set<std::string> output_inter;
    std::set_intersection(_urls.begin(),_urls.end(),
                          fp._urls.begin(),fp._urls.end(),
                          std::inserter(output_inter,output_inter.begin()));
    feed_parser fps(_name,output_inter);
    return fps;
  }

  /*- feeds -*/
  feeds::feeds()
  {
  }

  feeds::feeds(std::set<feed_parser,feed_parser::lxn> &feedset)
  {
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = feedset.begin();
    while(it!=feedset.end())
      {
        add_feed((*it));
        ++it;
      }
  }

  feeds::feeds(const std::string &name)
  {
    add_feed(feed_parser(name));
  }

  feeds::feeds(const std::string &name,
               const std::string &url)
  {
    add_feed(feed_parser(name,url));
  }

  feeds::feeds(const feeds &f)
  {
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = f._feedset.begin();
    while(it!=f._feedset.end())
      {
        add_feed((*it));
        ++it;
      }
  }

  feeds::~feeds()
  {
  }

  bool feeds::add_feed(const std::string &name,
                       const std::string &url)
  {
    return add_feed(feed_parser(name,url));
  }

  bool feeds::add_feed(const std::string &name)
  {
    return add_feed(feed_parser(name));
  }

  bool feeds::add_feed(const feed_parser &f)
  {
    if (f.empty())
      {
        errlog::log_error(LOG_LEVEL_ERROR,"Cannot add empty feed parser %s",
                          f._name.c_str());
        return false;
      }
    std::pair<std::set<feed_parser,feed_parser::lxn>::iterator,bool> ret
    = _feedset.insert(f);
    if (!ret.second)
      {
        feed_parser fp = find_feed(f._name);
        feed_parser fdiff = f.diff_nosym(fp);
        if (!fdiff.empty())
          {
            feed_parser funion = fp.sunion(f);
            if (funion.size() == f.size())
              remove_feed(f._name);
            ret.second = add_feed(funion);
          }
      }
    return ret.second;
  }

  bool feeds::add_feed(const std::string &name,
                       websearch_configuration *wconfig)
  {
    if (!wconfig)
      return add_feed(name);
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::iterator it
    = wconfig->_se_enabled._feedset.find(fp);
    if (it == wconfig->_se_enabled._feedset.end())
      {
        errlog::log_error(LOG_LEVEL_ERROR,"Cannot find feed parser %s in configuration",
                          name.c_str());
        return false;
      }
    // copy and feed_parser object.
    feed_parser fp_ptr((*it));
    return add_feed(fp_ptr);
  }

  bool feeds::remove_feed(const std::string &name)
  {
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::iterator it;
    if ((it = _feedset.find(fp))!=_feedset.end())
      {
        _feedset.erase(it);
        return true;
      }
    return false;
  }

  feed_parser feeds::find_feed(const std::string &name) const
  {
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::const_iterator it;
    it = _feedset.find(fp);
    if (it != _feedset.end())
      return (*it);
    else return feed_parser("");
  }

  bool feeds::has_feed(const std::string &name) const
  {
    feed_parser fp(name);
    std::set<feed_parser,feed_parser::lxn>::const_iterator it;
    it = _feedset.find(fp);
    if (it != _feedset.end())
      return true;
    else return false;
  }

  size_t feeds::size() const
  {
    size_t total_urls = 0;
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = _feedset.begin();
    while(it!=_feedset.end())
      {
        total_urls += (*it).size();
        ++it;
      }
    return total_urls;
  }

  size_t feeds::count() const
  {
    return _feedset.size();
  }

  bool feeds::empty() const
  {
    return _feedset.empty();
  }

  feeds feeds::diff(const feeds &f) const
  {
    //feeds fds;
    /*const feeds *f1 = this, *f2 = &f;
    if (f1->count() < f2->count())
      {
    	f1 = &f;
    	f2 = this;
      }
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
      = f1->_feedset.begin();
    while(it!=f1->_feedset.end())
      {
    	feed_parser fd = f2->find_feed((*it)._name);
    	if (!fd._name.empty())
    {
      feed_parser fdiff = (*it).diff(fd);
      fds.add_feed(fdiff);
    }
    	++it;
    	}*/
    std::set<feed_parser,feed_parser::lxn> output_diff;
    std::set_symmetric_difference(_feedset.begin(),_feedset.end(),
                                  f._feedset.begin(),f._feedset.end(),
                                  std::inserter(output_diff,output_diff.begin()),
                                  feed_parser::lxn());
    feeds fds(output_diff);

    // intersection + diff + add it up to fds.
    feeds common = inter_gen(f);
    std::vector<feed_parser> to_add;
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = common._feedset.begin();
    while(it!=common._feedset.end())
      {
        feed_parser fdo = f.find_feed((*it)._name);
        feed_parser diffd = (*it).diff(fdo);
        if (!fds.add_feed(diffd))
          {
            // should never happen ?
            fds.remove_feed((*it)._name);
            to_add.push_back(diffd);
          }
        ++it;
      }
    for (size_t i=0; i<to_add.size(); i++)
      fds.add_feed(to_add.at(i));

    return fds;
  }

  feeds feeds::sunion(const feeds &f) const
  {
    std::set<feed_parser,feed_parser::lxn> output_union;
    std::set_union(_feedset.begin(),_feedset.end(),
                   f._feedset.begin(),f._feedset.end(),
                   std::inserter(output_union,output_union.begin()),
                   feed_parser::lxn());
    feeds fds(output_union);

    // intersection + union + add it up to fds.
    feeds common = inter_gen(f);
    std::vector<feed_parser> to_add;
    std::set<feed_parser,feed_parser::lxn>::const_iterator it
    = common._feedset.begin();
    while(it!=common._feedset.end())
      {
        feed_parser fdo = f.find_feed((*it)._name);
        feed_parser uniond = (*it).sunion(fdo);
        if (!fds.add_feed(uniond))
          {
            fds.remove_feed((*it)._name);
            to_add.push_back(uniond);
          }
        ++it;
      }
    for (size_t i=0; i<to_add.size(); i++)
      fds.add_feed(to_add.at(i));
    return fds;
  }

  feeds feeds::inter(const feeds &f) const
  {
    std::set<feed_parser,feed_parser::lxn> output_inter;
    std::set_intersection(_feedset.begin(),_feedset.end(),
                          f._feedset.begin(),f._feedset.end(),
                          std::inserter(output_inter,output_inter.begin()),
                          feed_parser::lxn());
    feeds fds(output_inter);

    // intersection + inter + add it up to output_inter.
    std::vector<feed_parser> to_add;
    std::set<feed_parser,feed_parser::lxn>::iterator it
    = fds._feedset.begin();
    while(it!=fds._feedset.end())
      {
        feed_parser fdo = f.find_feed((*it)._name);
        const feed_parser interd((*it).inter(fdo));
        if (interd.empty())
          {
            std::set<feed_parser,feed_parser::lxn>::iterator it1 = it;
            ++it;
            fds._feedset.erase(it1);
          }
        else
          {
            to_add.push_back(interd);
            ++it;
          }
      }
    for (size_t i=0; i<to_add.size(); i++)
      fds.add_feed(to_add.at(i));
    return fds;
  }

  feeds feeds::inter_gen(const feeds &f) const
  {
    std::set<feed_parser,feed_parser::lxn> output_inter;
    std::set_intersection(_feedset.begin(),_feedset.end(),
                          f._feedset.begin(),f._feedset.end(),
                          std::inserter(output_inter,output_inter.begin()),
                          feed_parser::lxn());
    feeds fds(output_inter);
    return fds;
  }

  bool feeds::equal(const feeds &f) const
  {
    /*feeds intersect = inter(f);
      return (intersect.size() == f.size());*/
    if (size() != f.size()
        || count() != f.count())
      return false;
    feeds intersect = inter(f);
    if (intersect.size() == f.size()
        && intersect.size() == size()
        && intersect.count() == f.count()
        && intersect.count() == count())
      return true;
    else return false;
  }

} /* end of namespace. */
<|endoftext|>


<commit_before>#include "PositionModule.hpp"

#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <iostream>

#include <ros/console.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "sensor_msgs/Image.h"
#include "api_application/Ping.h"
#include "api_application/Announce.h"

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

PositionModule::PositionModule(IPositionReceiver* receiver) :
	trackingWorker(receiver)
{
	ROS_DEBUG("Initializing PositionModule");

	_isInitialized = true;
	isCalibrating = false;
	isCalibrated = false;
	isRunning = false;

	ros::NodeHandle n;

	this->pictureSendingActivationPublisher = n.advertise<camera_application::PictureSendingActivation>("PictureSendingActivation", 4);
	this->pingPublisher = n.advertise<api_application::Ping>("Ping", 4);
	this->cameraCalibrationDataPublisher = n.advertise<camera_application::CameraCalibrationData>("CameraCalibrationData", 10);

	this->pictureSubscriber = n.subscribe("Picture", 12, &PositionModule::pictureCallback, this);
	this->systemSubscriber = n.subscribe("System", 4, &PositionModule::systemCallback, this);
	this->rawPositionSubscriber = n.subscribe("RawPosition", 32, &PositionModule::rawPositionCallback, this);

	this->startCalibrationService = n.advertiseService("StartCalibration", &PositionModule::startCalibrationCallback, this);
	this->takeCalibrationPictureService = n.advertiseService("TakeCalibrationPicture", &PositionModule::takeCalibrationPictureCallback, this);
	this->calculateCalibrationService = n.advertiseService("CalculateCalibration", &PositionModule::calculateCalibrationCallback, this);

	// Advertise myself to API
	ros::ServiceClient announceClient = n.serviceClient<api_application::Announce>("announce");

	api_application::Announce announce;
	announce.request.type = 3; // 3 means position module

	if (announceClient.call(announce))
	{
		rosId = announce.response.id;

		if (rosId == ~0 /* -1 */)
		{
			ROS_ERROR("Error! Got id -1");
			_isInitialized = false;
		}
		else
		{
			ROS_INFO("Position module successfully announced. Got id %d", rosId);
		}
	}
	else
	{
		ROS_ERROR("Error! Could not announce myself to API!");
		_isInitialized = false;
	}

	msg = new KitrokopterMessages(rosId);

	if (_isInitialized)
	{
		ROS_DEBUG("PositionModule initialized");
	} else {
		ROS_ERROR("Could not initialize PositionModule!");
	}

	log.open("position_module.log");

	if (!log.is_open()) {
		ROS_ERROR("Could not open log file!");
	}
}

PositionModule::~PositionModule()
{
	msg->~KitrokopterMessages();
	log.close();

	// TODO: Free picture cache.

	ROS_DEBUG("PositionModule destroyed");
}

// Service
bool PositionModule::startCalibrationCallback(control_application::StartCalibration::Request &req, control_application::StartCalibration::Response &res)
{
	res.ok = !isCalibrating;

	if (!isCalibrating)
	{
		ROS_INFO("Starting multi camera calibration process");

		isCalibrated = false;

		// Delete old calibration data.
		system("rm -rf /tmp/calibrationResult/*");
		system("rm -rf /tmp/calibrationImages/*");
		setPictureSendingActivated(true);
		calibrationPictureCount = 0;
		boardSize = cv::Size(req.chessboardWidth, req.chessboardHeight);
		realSize = cv::Size(req.chessboardRealWidth, req.chessboardRealHeight);
	}

	isCalibrating = true;
	return true;
}

// Service
bool PositionModule::takeCalibrationPictureCallback(control_application::TakeCalibrationPicture::Request &req, control_application::TakeCalibrationPicture::Response &res)
{
	ROS_DEBUG("Taking calibration picture. Have %d cameras.", idDict.size());

	if (!idDict.isTranslated()) {
		idDict.translateIds();
	}

	pictureCacheMutex.lock();

	std::map<int, cv::Mat*> pictureMap;
	int goodPictures = 0;

	for (std::map<int, cv::Mat*>::iterator it = pictureCache.begin(); it != pictureCache.end(); it++)
	{
		if (it->second != 0)
		{
			std::vector<cv::Point2f> corners;
			bool foundAllCorners = cv::findChessboardCorners(*(it->second), boardSize, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);

			if (!foundAllCorners)
			{
				ROS_INFO("Took bad picture (id %d)", it->first);
			}
			else
			{
				ROS_INFO("Took good picture (id %d)", it->first);
				goodPictures++;
			}

			pictureMap[it->first] = it->second;

			// Remove image from image cache.
			it->second = 0;
		}
	}

	ROS_DEBUG("Got %d good pictures.", goodPictures);

	pictureCacheMutex.unlock();

	if (goodPictures >= 1) {
		// Create directory for images.
		int error = mkdir("/tmp/calibrationImages", 0777);

		if (error != 0 && errno != EEXIST)
		{
			ROS_ERROR("Could not create directory for calibration images (/tmp/calibrationImages): %d", errno);

			// Delete images.
			for (std::map<int, cv::Mat*>::iterator it = pictureMap.begin(); it != pictureMap.end(); it++) {
				delete it->second;
			}

			return false;
		}

		error = mkdir("/tmp/calibrationResult", 0777);

		if (error != 0 && errno != EEXIST)
		{
			ROS_ERROR("Could not create directory for calibration images (/tmp/calibrationResult): %d", errno);

			// Delete images.
			for (std::map<int, cv::Mat*>::iterator it = pictureMap.begin(); it != pictureMap.end(); it++) {
				delete it->second;
			}

			return false;
		}

		for (std::map<int, cv::Mat*>::iterator it = pictureMap.begin(); it != pictureMap.end(); it++) {
			std::stringstream ss;
			ss << "/tmp/calibrationImages/cam" << idDict.getForward(it->first) << "_image" << calibrationPictureCount << ".png";

			// Save picture on disk for amcctoolbox.
			std::cout << "Saving picture: " << cv::imwrite(ss.str(), *(it->second)) << std::endl;

			sensor_msgs::Image img;
			img.width = 640;
			img.height = 480;
			img.step = 3 * 640;
			img.data.reserve(img.step * img.height);

			for (int i = 0; i < 640 * 480 * 3; i++)
			{
				img.data[i] = it->second->data[i];
			}

			res.images.push_back(img);
			res.ids.push_back(it->first);

			delete it->second;
		}

		calibrationPictureCount++;
	}

	return true;
}

// Service
bool PositionModule::calculateCalibrationCallback(control_application::CalculateCalibration::Request &req, control_application::CalculateCalibration::Response &res)
{
	/*if (!isCalibrating) {
		ROS_ERROR("Cannot calculate calibration! Start calibration first!");
		return false;
	}*/

	if (!idDict.isTranslated()) {
		ROS_WARN("Dictionary was not translated! Translating now.");
		idDict.translateIds();
	}

	if (idDict.size() < 2) {
		ROS_ERROR("Have not enough cameras for calibration (Have %d)!", idDict.size());
		isCalibrating = false;
		return false;
	}

	if (idDict.size() < 3) {
		ROS_WARN("Have not enough cameras for a useful setup! Have %d, but should be at least 3.", idDict.size());
	}

	ROS_INFO("Calculating multi camera calibration. This could take up to 2 hours");
	//ChessboardData data(boardSize.width, boardSize.height, realSize.width, realSize.height);
	ChessboardData data(7, 7, 57, 57);

	int camNumber = idDict.size();
	bool ok = trackingWorker.calibrate(&data, camNumber);

	if (ok) {
		ROS_INFO("Finished multi camera calibration");
		isCalibrated = true;
	} else {
		ROS_ERROR("Calibration failed!");
	}

	for (int i = 0; i < camNumber; i++) {
		Vector position = trackingWorker.getCameraPosition(i);
		res.cameraXPositions.push_back(position.getV1());
		res.cameraYPositions.push_back(position.getV2());
		res.cameraZPositions.push_back(position.getV3());

		Matrix rotationMatrix = trackingWorker.getRotationMatrix(i);

		res.cameraRotationMatrices.push_back(rotationMatrix.getM11());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM12());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM13());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM21());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM22());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM23());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM31());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM32());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM33());

		res.IDs.push_back(idDict.getBackward(i));

		// Send calibration data to cameras
		intrinsicsMatrices[idDict.getBackward(i)] = trackingWorker.getIntrinsicsMatrix(i);
		distortionCoefficients[idDict.getBackward(i)] = trackingWorker.getDistortionCoefficients(i);

		camera_application::CameraCalibrationData msg;
		msg.ID = idDict.getBackward(i);
		msg.createdByCamera = false;

		for (int j = 0; j < 9; j++) {
			msg.intrinsics[j] = intrinsicsMatrices[idDict.getBackward(i)].at<double>(j);
		}

		for (int j = 0; j < 4; j++) {
			msg.distortion[j] = distortionCoefficients[idDict.getBackward(i)].at<double>(j);
		}

		cameraCalibrationDataPublisher.publish(msg);

		// DEBUG: Show calibration results visually
		std::stringstream ss;
		ss << "Calib Results CamId " << idDict.getBackward(i);
		windowNames[idDict.getBackward(i)] = ss.str();
		imageDisplayed[idDict.getBackward(i)] = false;

		cv::startWindowThread();
		cv::namedWindow(ss.str());
	}

	trackingWorker.updateTrackingArea();

	isCalibrating = false;

	return ok;
}

// Topic
void PositionModule::pictureCallback(const camera_application::Picture &msg)
{
	// Insert camera id, if not already there.
	idDict.insert(msg.ID);

	// DEBUG: Show calibration results visually
	if (imageDisplayed.count(msg.ID) && !imageDisplayed[msg.ID] && intrinsicsMatrices.count(msg.ID) > 0
		&& distortionCoefficients.count(msg.ID) > 0 && windowNames.count(msg.ID) > 0) {
		cv::Mat image(cv::Size(640, 480), CV_8UC3);

		for (int i = 0; i < 640 * 480 * 3; i++)	{
			image.data[i] = msg.image[i];
		}

		cv::Mat undistorted(cv::Size(640, 480), CV_8UC3);
		cv::undistort(image, undistorted, intrinsicsMatrices[msg.ID], distortionCoefficients[msg.ID]);
		cv::imshow(windowNames[msg.ID], undistorted);
		imageDisplayed[msg.ID] = true;
	}

	pictureCacheMutex.lock();

	if (isCalibrating) {
		if (pictureCache[msg.ID] != 0) {
			delete pictureCache[msg.ID];
			pictureCache[msg.ID] = 0;
		}

		cv::Mat* image = new cv::Mat(cv::Size(640, 480), CV_8UC3);

		for (int i = 0; i < 640 * 480 * 3; i++)	{
			image->data[i] = msg.image[i];
		}

		pictureCache[msg.ID] = image;
		pictureTimes[msg.ID] = msg.timestamp;
	}

	pictureCacheMutex.unlock();
}

// Topic
void PositionModule::systemCallback(const api_application::System &msg)
{
	isRunning = msg.command == 1;

	if (isRunning) {
		ROS_INFO("Tracking started");
	} else {
		ROS_INFO("Tracking stopped");
	}

	if (!isRunning) {
		int counter = 0;

		for (std::vector<long int>::iterator it = timeLog.begin(); it != timeLog.end(); it++) {
			log << counter++ << ", " << *it << std::endl;
		}

		cv::destroyAllWindows();
		ros::shutdown();
	}
}

// Topic
void PositionModule::rawPositionCallback(const camera_application::RawPosition &msg)
{
	if (!isCalibrated) {
		return;
	}

 	// TODO: Calculate position in our coordinate system.
	// TODO: Is this coordinate change correct for amcctoolbox?
	Vector cameraVector(msg.xPosition, msg.yPosition, 1);
	// ROS_DEBUG("Received position: msg.ID: %d idDict.getForward(msg.ID): %d msg.quadcopterId: %d", msg.ID, idDict.getForward(msg.ID), msg.quadcopterId);

	trackingWorker.updatePosition(cameraVector, idDict.getForward(msg.ID), msg.quadcopterId, msg.timestamp);

	/*#ifdef QC_PROFILE
	long int trackingClock = getNanoTime();
	#endif
	Vector result = tracker.updatePosition(cameraVector, netIdToCamNo[msg.ID], msg.quadcopterId);
	#ifdef QC_PROFILE
	timeLog.push_back(getNanoTime() - trackingClock);
	#endif

	std::vector<Vector> positions;
	std::vector<int> ids;
	std::vector<int> updates;
	positions.push_back(result);
	ids.push_back(msg.quadcopterId);
	updates.push_back(1);

	if (result.isValid()) {
		receiver->updatePositions(positions, ids, updates);
	} else {
		ROS_DEBUG("Not enough information to get position of quadcopter %d", msg.quadcopterId);
	}*/
}

void PositionModule::setPictureSendingActivated(bool activated)
{
	camera_application::PictureSendingActivation msg;
	msg.ID = 0;
	msg.active = activated;

	pictureSendingActivationPublisher.publish(msg);
}

void PositionModule::sendPing()
{
	api_application::Ping msg;
	msg.ID = rosId;
	pingPublisher.publish(msg);
}

bool PositionModule::isInitialized()
{
	return _isInitialized;
}
<commit_msg>Changed picture sending activation method.<commit_after>#include "PositionModule.hpp"

#include <assert.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdlib.h>
#include <string>
#include <algorithm>
#include <iostream>

#include <ros/console.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "sensor_msgs/Image.h"
#include "api_application/Ping.h"
#include "api_application/Announce.h"

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

PositionModule::PositionModule(IPositionReceiver* receiver) :
	trackingWorker(receiver)
{
	ROS_DEBUG("Initializing PositionModule");

	_isInitialized = true;
	isCalibrating = false;
	isCalibrated = false;
	isRunning = false;

	ros::NodeHandle n;

	this->pictureSendingActivationPublisher = n.advertise<camera_application::PictureSendingActivation>("PictureSendingActivation", 4);
	this->pingPublisher = n.advertise<api_application::Ping>("Ping", 4);
	this->cameraCalibrationDataPublisher = n.advertise<camera_application::CameraCalibrationData>("CameraCalibrationData", 10);

	this->pictureSubscriber = n.subscribe("Picture", 12, &PositionModule::pictureCallback, this);
	this->systemSubscriber = n.subscribe("System", 4, &PositionModule::systemCallback, this);
	this->rawPositionSubscriber = n.subscribe("RawPosition", 32, &PositionModule::rawPositionCallback, this);

	this->startCalibrationService = n.advertiseService("StartCalibration", &PositionModule::startCalibrationCallback, this);
	this->takeCalibrationPictureService = n.advertiseService("TakeCalibrationPicture", &PositionModule::takeCalibrationPictureCallback, this);
	this->calculateCalibrationService = n.advertiseService("CalculateCalibration", &PositionModule::calculateCalibrationCallback, this);

	// Advertise myself to API
	ros::ServiceClient announceClient = n.serviceClient<api_application::Announce>("announce");

	api_application::Announce announce;
	announce.request.type = 3; // 3 means position module

	if (announceClient.call(announce))
	{
		rosId = announce.response.id;

		if (rosId == ~0 /* -1 */)
		{
			ROS_ERROR("Error! Got id -1");
			_isInitialized = false;
		}
		else
		{
			ROS_INFO("Position module successfully announced. Got id %d", rosId);
		}
	}
	else
	{
		ROS_ERROR("Error! Could not announce myself to API!");
		_isInitialized = false;
	}

	msg = new KitrokopterMessages(rosId);

	if (_isInitialized)
	{
		ROS_DEBUG("PositionModule initialized");
	} else {
		ROS_ERROR("Could not initialize PositionModule!");
	}

	log.open("position_module.log");

	if (!log.is_open()) {
		ROS_ERROR("Could not open log file!");
	}
}

PositionModule::~PositionModule()
{
	msg->~KitrokopterMessages();
	log.close();

	// TODO: Free picture cache.

	ROS_DEBUG("PositionModule destroyed");
}

// Service
bool PositionModule::startCalibrationCallback(control_application::StartCalibration::Request &req, control_application::StartCalibration::Response &res)
{
	res.ok = !isCalibrating;

	if (!isCalibrating)
	{
		ROS_INFO("Starting multi camera calibration process");

		isCalibrated = false;

		// Delete old calibration data.
		system("rm -rf /tmp/calibrationResult/*");
		system("rm -rf /tmp/calibrationImages/*");
		setPictureSendingActivated(true);
		calibrationPictureCount = 0;
		boardSize = cv::Size(req.chessboardWidth, req.chessboardHeight);
		realSize = cv::Size(req.chessboardRealWidth, req.chessboardRealHeight);
	}

	isCalibrating = true;
	return true;
}

// Service
bool PositionModule::takeCalibrationPictureCallback(control_application::TakeCalibrationPicture::Request &req, control_application::TakeCalibrationPicture::Response &res)
{
	ROS_DEBUG("Taking calibration picture. Have %d cameras.", idDict.size());

	if (!idDict.isTranslated()) {
		idDict.translateIds();
	}

	pictureCacheMutex.lock();

	std::map<int, cv::Mat*> pictureMap;
	int goodPictures = 0;

	for (std::map<int, cv::Mat*>::iterator it = pictureCache.begin(); it != pictureCache.end(); it++)
	{
		if (it->second != 0)
		{
			std::vector<cv::Point2f> corners;
			bool foundAllCorners = cv::findChessboardCorners(*(it->second), boardSize, corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS | CV_CALIB_CB_FAST_CHECK | CV_CALIB_CB_NORMALIZE_IMAGE);

			if (!foundAllCorners)
			{
				ROS_INFO("Took bad picture (id %d)", it->first);
			}
			else
			{
				ROS_INFO("Took good picture (id %d)", it->first);
				goodPictures++;
			}

			pictureMap[it->first] = it->second;

			// Remove image from image cache.
			it->second = 0;
		}
	}

	ROS_DEBUG("Got %d good pictures.", goodPictures);

	pictureCacheMutex.unlock();

	if (goodPictures >= 1) {
		// Create directory for images.
		int error = mkdir("/tmp/calibrationImages", 0777);

		if (error != 0 && errno != EEXIST)
		{
			ROS_ERROR("Could not create directory for calibration images (/tmp/calibrationImages): %d", errno);

			// Delete images.
			for (std::map<int, cv::Mat*>::iterator it = pictureMap.begin(); it != pictureMap.end(); it++) {
				delete it->second;
			}

			return false;
		}

		error = mkdir("/tmp/calibrationResult", 0777);

		if (error != 0 && errno != EEXIST)
		{
			ROS_ERROR("Could not create directory for calibration images (/tmp/calibrationResult): %d", errno);

			// Delete images.
			for (std::map<int, cv::Mat*>::iterator it = pictureMap.begin(); it != pictureMap.end(); it++) {
				delete it->second;
			}

			return false;
		}

		for (std::map<int, cv::Mat*>::iterator it = pictureMap.begin(); it != pictureMap.end(); it++) {
			std::stringstream ss;
			ss << "/tmp/calibrationImages/cam" << idDict.getForward(it->first) << "_image" << calibrationPictureCount << ".png";

			// Save picture on disk for amcctoolbox.
			std::cout << "Saving picture: " << cv::imwrite(ss.str(), *(it->second)) << std::endl;

			sensor_msgs::Image img;
			img.width = 640;
			img.height = 480;
			img.step = 3 * 640;
			img.data.reserve(img.step * img.height);

			for (int i = 0; i < 640 * 480 * 3; i++)
			{
				img.data[i] = it->second->data[i];
			}

			res.images.push_back(img);
			res.ids.push_back(it->first);

			delete it->second;
		}

		calibrationPictureCount++;
	}

	return true;
}

// Service
bool PositionModule::calculateCalibrationCallback(control_application::CalculateCalibration::Request &req, control_application::CalculateCalibration::Response &res)
{
	/*if (!isCalibrating) {
		ROS_ERROR("Cannot calculate calibration! Start calibration first!");
		return false;
	}*/

	if (!idDict.isTranslated()) {
		ROS_WARN("Dictionary was not translated! Translating now.");
		idDict.translateIds();
	}

	if (idDict.size() < 2) {
		ROS_ERROR("Have not enough cameras for calibration (Have %d)!", idDict.size());
		isCalibrating = false;
		return false;
	}

	if (idDict.size() < 3) {
		ROS_WARN("Have not enough cameras for a useful setup! Have %d, but should be at least 3.", idDict.size());
	}

	ROS_INFO("Calculating multi camera calibration. This could take up to 2 hours");
	//ChessboardData data(boardSize.width, boardSize.height, realSize.width, realSize.height);
	ChessboardData data(7, 7, 57, 57);

	int camNumber = idDict.size();
	bool ok = trackingWorker.calibrate(&data, camNumber);

	if (ok) {
		ROS_INFO("Finished multi camera calibration");
		isCalibrated = true;
	} else {
		ROS_ERROR("Calibration failed!");
	}

	for (int i = 0; i < camNumber; i++) {
		Vector position = trackingWorker.getCameraPosition(i);
		res.cameraXPositions.push_back(position.getV1());
		res.cameraYPositions.push_back(position.getV2());
		res.cameraZPositions.push_back(position.getV3());

		Matrix rotationMatrix = trackingWorker.getRotationMatrix(i);

		res.cameraRotationMatrices.push_back(rotationMatrix.getM11());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM12());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM13());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM21());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM22());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM23());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM31());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM32());
		res.cameraRotationMatrices.push_back(rotationMatrix.getM33());

		res.IDs.push_back(idDict.getBackward(i));

		// Send calibration data to cameras
		intrinsicsMatrices[idDict.getBackward(i)] = trackingWorker.getIntrinsicsMatrix(i);
		distortionCoefficients[idDict.getBackward(i)] = trackingWorker.getDistortionCoefficients(i);

		camera_application::CameraCalibrationData msg;
		msg.ID = idDict.getBackward(i);
		msg.createdByCamera = false;

		for (int j = 0; j < 9; j++) {
			msg.intrinsics[j] = intrinsicsMatrices[idDict.getBackward(i)].at<double>(j);
		}

		for (int j = 0; j < 4; j++) {
			msg.distortion[j] = distortionCoefficients[idDict.getBackward(i)].at<double>(j);
		}

		cameraCalibrationDataPublisher.publish(msg);

		// DEBUG: Show calibration results visually
		std::stringstream ss;
		ss << "Calib Results CamId " << idDict.getBackward(i);
		windowNames[idDict.getBackward(i)] = ss.str();
		imageDisplayed[idDict.getBackward(i)] = false;

		cv::startWindowThread();
		cv::namedWindow(ss.str());
	}

	trackingWorker.updateTrackingArea();

	isCalibrating = false;

	return ok;
}

// Topic
void PositionModule::pictureCallback(const camera_application::Picture &msg)
{
	// Insert camera id, if not already there.
	idDict.insert(msg.ID);

	// DEBUG: Show calibration results visually
	if (imageDisplayed.count(msg.ID) && !imageDisplayed[msg.ID] && intrinsicsMatrices.count(msg.ID) > 0
		&& distortionCoefficients.count(msg.ID) > 0 && windowNames.count(msg.ID) > 0) {
		cv::Mat image(cv::Size(640, 480), CV_8UC3);

		for (int i = 0; i < 640 * 480 * 3; i++)	{
			image.data[i] = msg.image[i];
		}

		cv::Mat undistorted(cv::Size(640, 480), CV_8UC3);
		cv::undistort(image, undistorted, intrinsicsMatrices[msg.ID], distortionCoefficients[msg.ID]);
		cv::imshow(windowNames[msg.ID], undistorted);
		imageDisplayed[msg.ID] = true;
	}

	pictureCacheMutex.lock();

	if (isCalibrating) {
		if (pictureCache[msg.ID] != 0) {
			delete pictureCache[msg.ID];
			pictureCache[msg.ID] = 0;
		}

		cv::Mat* image = new cv::Mat(cv::Size(640, 480), CV_8UC3);

		for (int i = 0; i < 640 * 480 * 3; i++)	{
			image->data[i] = msg.image[i];
		}

		pictureCache[msg.ID] = image;
		pictureTimes[msg.ID] = msg.timestamp;
	}

	pictureCacheMutex.unlock();
}

// Topic
void PositionModule::systemCallback(const api_application::System &msg)
{
	isRunning = msg.command == 1;

	if (isRunning) {
		ROS_INFO("Tracking started");
	} else {
		ROS_INFO("Tracking stopped");
	}

	if (!isRunning) {
		int counter = 0;

		for (std::vector<long int>::iterator it = timeLog.begin(); it != timeLog.end(); it++) {
			log << counter++ << ", " << *it << std::endl;
		}

		cv::destroyAllWindows();
		ros::shutdown();
	}
}

// Topic
void PositionModule::rawPositionCallback(const camera_application::RawPosition &msg)
{
	if (!isCalibrated) {
		return;
	}

 	// TODO: Calculate position in our coordinate system.
	// TODO: Is this coordinate change correct for amcctoolbox?
	Vector cameraVector(msg.xPosition, msg.yPosition, 1);
	// ROS_DEBUG("Received position: msg.ID: %d idDict.getForward(msg.ID): %d msg.quadcopterId: %d", msg.ID, idDict.getForward(msg.ID), msg.quadcopterId);

	trackingWorker.updatePosition(cameraVector, idDict.getForward(msg.ID), msg.quadcopterId, msg.timestamp);

	/*#ifdef QC_PROFILE
	long int trackingClock = getNanoTime();
	#endif
	Vector result = tracker.updatePosition(cameraVector, netIdToCamNo[msg.ID], msg.quadcopterId);
	#ifdef QC_PROFILE
	timeLog.push_back(getNanoTime() - trackingClock);
	#endif

	std::vector<Vector> positions;
	std::vector<int> ids;
	std::vector<int> updates;
	positions.push_back(result);
	ids.push_back(msg.quadcopterId);
	updates.push_back(1);

	if (result.isValid()) {
		receiver->updatePositions(positions, ids, updates);
	} else {
		ROS_DEBUG("Not enough information to get position of quadcopter %d", msg.quadcopterId);
	}*/
}

void PositionModule::setPictureSendingActivated(bool activated)
{
	camera_application::PictureSendingActivation msg;
	msg.ID = 0;
	msg.active = activated;
	msg.global = true;

	pictureSendingActivationPublisher.publish(msg);
}

void PositionModule::sendPing()
{
	api_application::Ping msg;
	msg.ID = rosId;
	pingPublisher.publish(msg);
}

bool PositionModule::isInitialized()
{
	return _isInitialized;
}
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/modules.h>

#include <boost/python.hpp>

/**
 * \file modules.cxx
 *
 * \brief Python bindings for module loading.
 */

using namespace boost::python;

BOOST_PYTHON_MODULE(modules)
{
  def("load_known_modules", &vistk::load_known_modules);
}
<commit_msg>Add docstrings to module bindings<commit_after>/*ckwg +5
 * Copyright 2011 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include <vistk/pipeline/modules.h>

#include <boost/python.hpp>

/**
 * \file modules.cxx
 *
 * \brief Python bindings for module loading.
 */

using namespace boost::python;

BOOST_PYTHON_MODULE(modules)
{
  def("load_known_modules", &vistk::load_known_modules
    , "Loads vistk modules to populate the process and schedule registries.");
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

// this hack is needed to make this file compiles with -pedantic (gcc)
#ifdef __GNUC__
#define throw(X)
#endif
// discard stack allocation as that too bypasses malloc
#define EIGEN_STACK_ALLOCATION_LIMIT 0
// any heap allocation will raise an assert
#define EIGEN_NO_MALLOC

#include "main.h"
#include <Eigen/Cholesky>
#include <Eigen/Eigenvalues>
#include <Eigen/LU>
#include <Eigen/QR>
#include <Eigen/SVD>

template<typename MatrixType> void nomalloc(const MatrixType& m)
{
  /* this test check no dynamic memory allocation are issued with fixed-size matrices
  */
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
                              ::Identity(rows, rows),
             square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
                              ::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar s1 = internal::random<Scalar>();

  Index r = internal::random<Index>(0, rows-1),
        c = internal::random<Index>(0, cols-1);

  VERIFY_IS_APPROX((m1+m2)*s1,              s1*m1+s1*m2);
  VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));
  VERIFY_IS_APPROX(m1.cwiseProduct(m1.block(0,0,rows,cols)), (m1.array()*m1.array()).matrix());
  VERIFY_IS_APPROX((m1*m1.transpose())*m2,  m1*(m1.transpose()*m2));

  m2.col(0).noalias() = m1 * m1.col(0);
  m2.col(0).noalias() -= m1.adjoint() * m1.col(0);
  m2.col(0).noalias() -= m1 * m1.row(0).adjoint();
  m2.col(0).noalias() -= m1.adjoint() * m1.row(0).adjoint();

  m2.row(0).noalias() = m1.row(0) * m1;
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1;
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint();
  VERIFY_IS_APPROX(m2,m2);

  m2.col(0).noalias() = m1.template triangularView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.template triangularView<Upper>() * m1.row(0).adjoint();
  m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.row(0).adjoint();

  m2.row(0).noalias() = m1.row(0) * m1.template triangularView<Upper>();
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template triangularView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template triangularView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template triangularView<Upper>();
  VERIFY_IS_APPROX(m2,m2);

  m2.col(0).noalias() = m1.template selfadjointView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.template selfadjointView<Upper>() * m1.row(0).adjoint();
  m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.row(0).adjoint();

  m2.row(0).noalias() = m1.row(0) * m1.template selfadjointView<Upper>();
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template selfadjointView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template selfadjointView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template selfadjointView<Upper>();
  VERIFY_IS_APPROX(m2,m2);

  // The following fancy matrix-matrix products are not safe yet regarding static allocation
//   m1 += m1.template triangularView<Upper>() * m2.col(;
//   m1.template selfadjointView<Lower>().rankUpdate(m2);
//   m1 += m1.template triangularView<Upper>() * m2;
//   m1 += m1.template selfadjointView<Lower>() * m2;
//   VERIFY_IS_APPROX(m1,m1);
}

template<typename Scalar>
void ctms_decompositions()
{
  const int maxSize = 16;
  const int size    = 12;

  typedef Eigen::Matrix<Scalar,
                        Eigen::Dynamic, Eigen::Dynamic,
                        0,
                        maxSize, maxSize> Matrix;

  typedef Eigen::Matrix<Scalar,
                        Eigen::Dynamic, 1,
                        0,
                        maxSize, 1> Vector;

  typedef Eigen::Matrix<std::complex<Scalar>,
                        Eigen::Dynamic, Eigen::Dynamic,
                        0,
                        maxSize, maxSize> ComplexMatrix;

  const Matrix A(Matrix::Random(size, size));
  const ComplexMatrix complexA(ComplexMatrix::Random(size, size));
  const Matrix saA = A.adjoint() * A;

  // Cholesky module
  Eigen::LLT<Matrix>  LLT;  LLT.compute(A);
  Eigen::LDLT<Matrix> LDLT; LDLT.compute(A);

  // Eigenvalues module
  Eigen::HessenbergDecomposition<ComplexMatrix> hessDecomp;        hessDecomp.compute(complexA);
  Eigen::ComplexSchur<ComplexMatrix>            cSchur(size);      cSchur.compute(complexA);
  Eigen::ComplexEigenSolver<ComplexMatrix>      cEigSolver;        cEigSolver.compute(complexA);
  Eigen::EigenSolver<Matrix>                    eigSolver;         eigSolver.compute(A);
  Eigen::SelfAdjointEigenSolver<Matrix>         saEigSolver(size); saEigSolver.compute(saA);
  Eigen::Tridiagonalization<Matrix>             tridiag;           tridiag.compute(saA);

  // LU module
  Eigen::PartialPivLU<Matrix> ppLU; ppLU.compute(A);
  Eigen::FullPivLU<Matrix>    fpLU; fpLU.compute(A);

  // QR module
  Eigen::HouseholderQR<Matrix>        hQR;  hQR.compute(A);
  Eigen::ColPivHouseholderQR<Matrix>  cpQR; cpQR.compute(A);
  Eigen::FullPivHouseholderQR<Matrix> fpQR; fpQR.compute(A);

  // SVD module
  Eigen::JacobiSVD<Matrix> jSVD; jSVD.compute(A, ComputeFullU | ComputeFullV);
}

void test_nomalloc()
{
  // check that our operator new is indeed called:
  VERIFY_RAISES_ASSERT(MatrixXd dummy(MatrixXd::Random(3,3)));
  CALL_SUBTEST_1(nomalloc(Matrix<float, 1, 1>()) );
  CALL_SUBTEST_2(nomalloc(Matrix4d()) );
  CALL_SUBTEST_3(nomalloc(Matrix<float,32,32>()) );

  // Check decomposition modules with dynamic matrices that have a known compile-time max size (ctms)
  CALL_SUBTEST_4(ctms_decompositions<float>());

}
<commit_msg>extend nomalloc test<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen 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 or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.

// this hack is needed to make this file compiles with -pedantic (gcc)
#ifdef __GNUC__
#define throw(X)
#endif
// discard stack allocation as that too bypasses malloc
#define EIGEN_STACK_ALLOCATION_LIMIT 0
// any heap allocation will raise an assert
#define EIGEN_NO_MALLOC

#include "main.h"
#include <Eigen/Cholesky>
#include <Eigen/Eigenvalues>
#include <Eigen/LU>
#include <Eigen/QR>
#include <Eigen/SVD>

template<typename MatrixType> void nomalloc(const MatrixType& m)
{
  /* this test check no dynamic memory allocation are issued with fixed-size matrices
  */
  typedef typename MatrixType::Index Index;
  typedef typename MatrixType::Scalar Scalar;
  typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;

  Index rows = m.rows();
  Index cols = m.cols();

  MatrixType m1 = MatrixType::Random(rows, cols),
             m2 = MatrixType::Random(rows, cols),
             m3(rows, cols),
             mzero = MatrixType::Zero(rows, cols),
             identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
                              ::Identity(rows, rows),
             square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
                              ::Random(rows, rows);
  VectorType v1 = VectorType::Random(rows),
             v2 = VectorType::Random(rows),
             vzero = VectorType::Zero(rows);

  Scalar s1 = internal::random<Scalar>();

  Index r = internal::random<Index>(0, rows-1),
        c = internal::random<Index>(0, cols-1);

  VERIFY_IS_APPROX((m1+m2)*s1,              s1*m1+s1*m2);
  VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));
  VERIFY_IS_APPROX(m1.cwiseProduct(m1.block(0,0,rows,cols)), (m1.array()*m1.array()).matrix());
  VERIFY_IS_APPROX((m1*m1.transpose())*m2,  m1*(m1.transpose()*m2));

  m2.col(0).noalias() = m1 * m1.col(0);
  m2.col(0).noalias() -= m1.adjoint() * m1.col(0);
  m2.col(0).noalias() -= m1 * m1.row(0).adjoint();
  m2.col(0).noalias() -= m1.adjoint() * m1.row(0).adjoint();

  m2.row(0).noalias() = m1.row(0) * m1;
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1;
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint();
  VERIFY_IS_APPROX(m2,m2);

  m2.col(0).noalias() = m1.template triangularView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.template triangularView<Upper>() * m1.row(0).adjoint();
  m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.row(0).adjoint();

  m2.row(0).noalias() = m1.row(0) * m1.template triangularView<Upper>();
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template triangularView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template triangularView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template triangularView<Upper>();
  VERIFY_IS_APPROX(m2,m2);

  m2.col(0).noalias() = m1.template selfadjointView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.col(0);
  m2.col(0).noalias() -= m1.template selfadjointView<Upper>() * m1.row(0).adjoint();
  m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.row(0).adjoint();

  m2.row(0).noalias() = m1.row(0) * m1.template selfadjointView<Upper>();
  m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template selfadjointView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template selfadjointView<Upper>();
  m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template selfadjointView<Upper>();
  VERIFY_IS_APPROX(m2,m2);

  m2.template selfadjointView<Lower>().rankUpdate(m1.col(0),-1);
  m2.template selfadjointView<Lower>().rankUpdate(m1.row(0),-1);

  // The following fancy matrix-matrix products are not safe yet regarding static allocation
//   m1 += m1.template triangularView<Upper>() * m2.col(;
//   m1.template selfadjointView<Lower>().rankUpdate(m2);
//   m1 += m1.template triangularView<Upper>() * m2;
//   m1 += m1.template selfadjointView<Lower>() * m2;
//   VERIFY_IS_APPROX(m1,m1);
}

template<typename Scalar>
void ctms_decompositions()
{
  const int maxSize = 16;
  const int size    = 12;

  typedef Eigen::Matrix<Scalar,
                        Eigen::Dynamic, Eigen::Dynamic,
                        0,
                        maxSize, maxSize> Matrix;

  typedef Eigen::Matrix<Scalar,
                        Eigen::Dynamic, 1,
                        0,
                        maxSize, 1> Vector;

  typedef Eigen::Matrix<std::complex<Scalar>,
                        Eigen::Dynamic, Eigen::Dynamic,
                        0,
                        maxSize, maxSize> ComplexMatrix;

  const Matrix A(Matrix::Random(size, size));
  const ComplexMatrix complexA(ComplexMatrix::Random(size, size));
  const Matrix saA = A.adjoint() * A;

  // Cholesky module
  Eigen::LLT<Matrix>  LLT;  LLT.compute(A);
  Eigen::LDLT<Matrix> LDLT; LDLT.compute(A);

  // Eigenvalues module
  Eigen::HessenbergDecomposition<ComplexMatrix> hessDecomp;        hessDecomp.compute(complexA);
  Eigen::ComplexSchur<ComplexMatrix>            cSchur(size);      cSchur.compute(complexA);
  Eigen::ComplexEigenSolver<ComplexMatrix>      cEigSolver;        cEigSolver.compute(complexA);
  Eigen::EigenSolver<Matrix>                    eigSolver;         eigSolver.compute(A);
  Eigen::SelfAdjointEigenSolver<Matrix>         saEigSolver(size); saEigSolver.compute(saA);
  Eigen::Tridiagonalization<Matrix>             tridiag;           tridiag.compute(saA);

  // LU module
  Eigen::PartialPivLU<Matrix> ppLU; ppLU.compute(A);
  Eigen::FullPivLU<Matrix>    fpLU; fpLU.compute(A);

  // QR module
  Eigen::HouseholderQR<Matrix>        hQR;  hQR.compute(A);
  Eigen::ColPivHouseholderQR<Matrix>  cpQR; cpQR.compute(A);
  Eigen::FullPivHouseholderQR<Matrix> fpQR; fpQR.compute(A);

  // SVD module
  Eigen::JacobiSVD<Matrix> jSVD; jSVD.compute(A, ComputeFullU | ComputeFullV);
}

void test_nomalloc()
{
  // check that our operator new is indeed called:
  VERIFY_RAISES_ASSERT(MatrixXd dummy(MatrixXd::Random(3,3)));
  CALL_SUBTEST_1(nomalloc(Matrix<float, 1, 1>()) );
  CALL_SUBTEST_2(nomalloc(Matrix4d()) );
  CALL_SUBTEST_3(nomalloc(Matrix<float,32,32>()) );

  // Check decomposition modules with dynamic matrices that have a known compile-time max size (ctms)
  CALL_SUBTEST_4(ctms_decompositions<float>());

}
<|endoftext|>


<commit_before>// Copyright (c) 2011-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/receiverequestdialog.h>
#include <qt/forms/ui_receiverequestdialog.h>

#include <qt/bitcoinunits.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/qrimagewidget.h>
#include <qt/walletmodel.h>
#include <qt/styleSheet.h>
#include <qt/platformstyle.h>
#include <qt/addresstablemodel.h>
#include <qt/recentrequeststablemodel.h>
#include <qt/receivecoinsdialog.h>

#include <QDialog>
#include <QString>

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h> /* for USE_QRCODE */
#endif

ReceiveRequestDialog::ReceiveRequestDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
    QDialog(parent, GUIUtil::dialog_flags),
    ui(new Ui::ReceiveRequestDialog),
    model(nullptr),
    platformStyle(_platformStyle),
    requestPaymentDialog(0)
{
    ui->setupUi(this);
    GUIUtil::handleCloseWindowShortcut(this);

    requestPaymentDialog = new ReceiveCoinsDialog(platformStyle, this);

    SetObjectStyleSheet(ui->btnRefreshAddress, StyleSheetNames::ButtonLight);
    ui->btnCopyAddress->setIcon(platformStyle->MultiStatesIcon(":/icons/editcopy", PlatformStyle::PushButtonIcon));
    ui->btnCopyURI->setIcon(platformStyle->MultiStatesIcon(":/icons/editcopy", PlatformStyle::PushButtonIcon));

#ifndef USE_QRCODE
    ui->widgetQRMargin->setVisible(false);
#endif
}

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

void ReceiveRequestDialog::setModel(WalletModel *_model)
{
    this->model = _model;

    if (_model && _model->getOptionsModel())
    {
        connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveRequestDialog::update);

        // Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
        ui->btnRefreshAddress->setEnabled(model->wallet().canGetAddresses());

        // Enable/disable the receive button if the wallet is now able/unable to give out new addresses.
        connect(model, &WalletModel::canGetAddressesChanged, [this] {
            ui->btnRefreshAddress->setEnabled(model->wallet().canGetAddresses());
        });
    }

    requestPaymentDialog->setModel(model);

    // update the display unit if necessary
    update();
}

void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info)
{
    this->info = _info;
    update();
}

bool ReceiveRequestDialog::refreshAddress()
{
    if(!model || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
        return false;

    /* Generate new receiving address */
    OutputType address_type = model->wallet().getDefaultAddressType();
    info.address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, info.label, "", address_type);

    /* Store request for later reference */
    model->getRecentRequestsTableModel()->addNewRequest(info);

    return true;
}

bool ReceiveRequestDialog::getDefaultAddress()
{
    if(!model || !model->getRecentRequestsTableModel())
        return false;

    // Get the last address from the request history list that have empty label, message and amount
    const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
    bool foundDefault = false;
    for(int i = submodel->rowCount(QModelIndex()) -1; i >= 0; i--)
    {
        SendCoinsRecipient entry = submodel->entry(i).recipient;
        if(entry.label.isEmpty() && entry.message.isEmpty() && entry.amount == 0)
        {
            info = entry;
            foundDefault = true;
            break;
        }
    }

    // Generate new address if no default found
    if(!foundDefault)
    {
        info = SendCoinsRecipient();
        refreshAddress();
    }

    return !info.address.isEmpty();
}

void ReceiveRequestDialog::update()
{
    setWindowTitle(tr("Request payment to %1").arg(info.label.isEmpty() ? info.address : info.label));
    QString uri = GUIUtil::formatBitcoinURI(info);

    if(!info.address.isEmpty())
    {
        QString uri = GUIUtil::formatBitcoinURI(info);
#ifdef USE_QRCODE
        if(ui->qr_code->setQR(uri))
        {
            ui->qr_code->setScaledContents(true);
        }
#endif

        ui->widgetPaymentInformation->setEnabled(true);

        ui->address_content->setText(info.address);
        SendCoinsRecipient _info;
        _info.address = info.address;
        QString _uri = GUIUtil::formatBitcoinURI(_info);
        ui->uri_content->setText(_uri);
        ui->uri_content->setToolTip(uri);
    }
    else
    {
        clear();
    }

    QWidget::update();
}

void ReceiveRequestDialog::on_btnCopyURI_clicked()
{
    GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(info));
}

void ReceiveRequestDialog::on_btnCopyAddress_clicked()
{
    GUIUtil::setClipboard(info.address);
}
void ReceiveRequestDialog::on_btnRefreshAddress_clicked()
{
    // Refresh address
    if(refreshAddress())
        update();
}

void ReceiveRequestDialog::on_btnRequestPayment_clicked()
{
    if(requestPaymentDialog->exec() == QDialog::Accepted)
    {
        setInfo(requestPaymentDialog->getInfo());
    }
}

void ReceiveRequestDialog::on_btnClear_clicked()
{
    clear();
}

void ReceiveRequestDialog::clear()
{
    if(getDefaultAddress())
    {
        update();
    }
    else
    {
        setWindowTitle(tr("Request payment to %1").arg(""));
        info = SendCoinsRecipient();
#ifdef USE_QRCODE
        ui->qr_code->clear();
#endif
        ui->uri_content->clear();
        ui->address_content->clear();
        ui->widgetPaymentInformation->setEnabled(false);
    }
}

void ReceiveRequestDialog::reject()
{
    clear();
    QDialog::reject();
}

void ReceiveRequestDialog::accept()
{
    clear();
    QDialog::accept();
}
<commit_msg>Fix refresh address<commit_after>// Copyright (c) 2011-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qt/receiverequestdialog.h>
#include <qt/forms/ui_receiverequestdialog.h>

#include <qt/bitcoinunits.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/qrimagewidget.h>
#include <qt/walletmodel.h>
#include <qt/styleSheet.h>
#include <qt/platformstyle.h>
#include <qt/addresstablemodel.h>
#include <qt/recentrequeststablemodel.h>
#include <qt/receivecoinsdialog.h>

#include <QDialog>
#include <QString>

#if defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h> /* for USE_QRCODE */
#endif

ReceiveRequestDialog::ReceiveRequestDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
    QDialog(parent, GUIUtil::dialog_flags),
    ui(new Ui::ReceiveRequestDialog),
    model(nullptr),
    platformStyle(_platformStyle),
    requestPaymentDialog(0)
{
    ui->setupUi(this);
    GUIUtil::handleCloseWindowShortcut(this);

    requestPaymentDialog = new ReceiveCoinsDialog(platformStyle, this);

    SetObjectStyleSheet(ui->btnRefreshAddress, StyleSheetNames::ButtonLight);
    ui->btnCopyAddress->setIcon(platformStyle->MultiStatesIcon(":/icons/editcopy", PlatformStyle::PushButtonIcon));
    ui->btnCopyURI->setIcon(platformStyle->MultiStatesIcon(":/icons/editcopy", PlatformStyle::PushButtonIcon));

#ifndef USE_QRCODE
    ui->widgetQRMargin->setVisible(false);
#endif
}

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

void ReceiveRequestDialog::setModel(WalletModel *_model)
{
    this->model = _model;

    if (_model && _model->getOptionsModel())
    {
        connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveRequestDialog::update);

        // Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
        ui->btnRefreshAddress->setEnabled(model->wallet().canGetAddresses());

        // Enable/disable the receive button if the wallet is now able/unable to give out new addresses.
        connect(model, &WalletModel::canGetAddressesChanged, [this] {
            ui->btnRefreshAddress->setEnabled(model->wallet().canGetAddresses());
        });
    }

    requestPaymentDialog->setModel(model);

    // update the display unit if necessary
    update();
}

void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &_info)
{
    this->info = _info;
    update();
}

bool ReceiveRequestDialog::refreshAddress()
{
    if(!model || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
        return false;

    /* Generate new receiving address */
    OutputType address_type = model->wallet().getDefaultAddressType();
    info.address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, info.label, "", address_type);

    /* Store request for later reference */
    if(!info.address.isEmpty())
        model->getRecentRequestsTableModel()->addNewRequest(info);

    return true;
}

bool ReceiveRequestDialog::getDefaultAddress()
{
    if(!model || !model->getRecentRequestsTableModel())
        return false;

    // Get the last address from the request history list that have empty label, message and amount
    const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
    bool foundDefault = false;
    for(int i = submodel->rowCount(QModelIndex()) -1; i >= 0; i--)
    {
        SendCoinsRecipient entry = submodel->entry(i).recipient;
        if(entry.label.isEmpty() && entry.message.isEmpty() && entry.amount == 0)
        {
            info = entry;
            foundDefault = true;
            break;
        }
    }

    // Generate new address if no default found
    if(!foundDefault)
    {
        info = SendCoinsRecipient();
        refreshAddress();
    }

    return !info.address.isEmpty();
}

void ReceiveRequestDialog::update()
{
    setWindowTitle(tr("Request payment to %1").arg(info.label.isEmpty() ? info.address : info.label));
    QString uri = GUIUtil::formatBitcoinURI(info);

    if(!info.address.isEmpty())
    {
        QString uri = GUIUtil::formatBitcoinURI(info);
#ifdef USE_QRCODE
        if(ui->qr_code->setQR(uri))
        {
            ui->qr_code->setScaledContents(true);
        }
#endif

        ui->widgetPaymentInformation->setEnabled(true);

        ui->address_content->setText(info.address);
        SendCoinsRecipient _info;
        _info.address = info.address;
        QString _uri = GUIUtil::formatBitcoinURI(_info);
        ui->uri_content->setText(_uri);
        ui->uri_content->setToolTip(uri);
    }
    else
    {
        clear();
    }

    QWidget::update();
}

void ReceiveRequestDialog::on_btnCopyURI_clicked()
{
    GUIUtil::setClipboard(GUIUtil::formatBitcoinURI(info));
}

void ReceiveRequestDialog::on_btnCopyAddress_clicked()
{
    GUIUtil::setClipboard(info.address);
}
void ReceiveRequestDialog::on_btnRefreshAddress_clicked()
{
    // Refresh address
    if(refreshAddress())
        update();
}

void ReceiveRequestDialog::on_btnRequestPayment_clicked()
{
    if(requestPaymentDialog->exec() == QDialog::Accepted)
    {
        setInfo(requestPaymentDialog->getInfo());
    }
}

void ReceiveRequestDialog::on_btnClear_clicked()
{
    clear();
}

void ReceiveRequestDialog::clear()
{
    if(getDefaultAddress())
    {
        update();
    }
    else
    {
        setWindowTitle(tr("Request payment to %1").arg(""));
        info = SendCoinsRecipient();
#ifdef USE_QRCODE
        ui->qr_code->clear();
#endif
        ui->uri_content->clear();
        ui->address_content->clear();
        ui->widgetPaymentInformation->setEnabled(false);
    }
}

void ReceiveRequestDialog::reject()
{
    clear();
    QDialog::reject();
}

void ReceiveRequestDialog::accept()
{
    clear();
    QDialog::accept();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: svtuno.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: dv $ $Date: 2001-06-28 07:04:44 $
 *
 *  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 _SVTOOLS_SVTUNO_HXX
#define _SVTOOLS_SVTUNO_HXX

// Macro to define const unicode a'la "..."
// It's better then "OUString::createFromAscii(...)" !!!
#define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
#define DEFINE_CONST_OUSTRING(CONSTASCII)       OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))

// defines ---------------------------------------------------------------
#define UNOANY                          ::com::sun::star::uno::Any
#define UNOEXCEPTION                    ::com::sun::star::uno::Exception
#define UNOMUTEX                        ::osl::Mutex
#define UNOMUTEXGUARD                   ::osl::MutexGuard
#define UNOOIMPLEMENTATIONID            ::cppu::OImplementationId
#define UNOOTYPECOLLECTION              ::cppu::OTypeCollection
#define UNOOUSTRING                     ::rtl::OUString
#define UNOPROPERTYVALUE                ::com::sun::star::beans::PropertyValue
#define UNOREFERENCE                    ::com::sun::star::uno::Reference
#define UNORUNTIMEEXCEPTION             ::com::sun::star::uno::RuntimeException
#define UNOINVALIDREGISTRYEXCEPTION     ::com::sun::star::registry::InvalidRegistryException
#define UNOSEQUENCE                     ::com::sun::star::uno::Sequence
#define UNOTYPE                         ::com::sun::star::uno::Type
#define UNOURL                          ::com::sun::star::util::URL
#define UNOXINTERFACE                   ::com::sun::star::uno::XInterface
#define UNOXMULTISERVICEFACTORY         ::com::sun::star::lang::XMultiServiceFactory
#define UNOXSINGLESERVICEFACTORY        ::com::sun::star::lang::XSingleServiceFactory
#define UNOXTYPEPROVIDER                ::com::sun::star::lang::XTypeProvider
#define UNOILLEGALARGUMENTEXCEPTION     ::com::sun::star::lang::IllegalArgumentException

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

#endif
<commit_msg>#91894# +UNOSTRINGPAIR<commit_after>/*************************************************************************
 *
 *  $RCSfile: svtuno.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: fs $ $Date: 2001-09-18 14:45:44 $
 *
 *  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 _SVTOOLS_SVTUNO_HXX
#define _SVTOOLS_SVTUNO_HXX

// Macro to define const unicode a'la "..."
// It's better then "OUString::createFromAscii(...)" !!!
#define DEFINE_CONST_UNICODE(CONSTASCII)        UniString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))
#define DEFINE_CONST_OUSTRING(CONSTASCII)       OUString(RTL_CONSTASCII_USTRINGPARAM(CONSTASCII))

// defines ---------------------------------------------------------------
#define UNOANY                          ::com::sun::star::uno::Any
#define UNOEXCEPTION                    ::com::sun::star::uno::Exception
#define UNOMUTEX                        ::osl::Mutex
#define UNOMUTEXGUARD                   ::osl::MutexGuard
#define UNOOIMPLEMENTATIONID            ::cppu::OImplementationId
#define UNOOTYPECOLLECTION              ::cppu::OTypeCollection
#define UNOOUSTRING                     ::rtl::OUString
#define UNOPROPERTYVALUE                ::com::sun::star::beans::PropertyValue
#define UNOSTRINGPAIR                   ::com::sun::star::beans::StringPair
#define UNOREFERENCE                    ::com::sun::star::uno::Reference
#define UNORUNTIMEEXCEPTION             ::com::sun::star::uno::RuntimeException
#define UNOINVALIDREGISTRYEXCEPTION     ::com::sun::star::registry::InvalidRegistryException
#define UNOSEQUENCE                     ::com::sun::star::uno::Sequence
#define UNOTYPE                         ::com::sun::star::uno::Type
#define UNOURL                          ::com::sun::star::util::URL
#define UNOXINTERFACE                   ::com::sun::star::uno::XInterface
#define UNOXMULTISERVICEFACTORY         ::com::sun::star::lang::XMultiServiceFactory
#define UNOXSINGLESERVICEFACTORY        ::com::sun::star::lang::XSingleServiceFactory
#define UNOXTYPEPROVIDER                ::com::sun::star::lang::XTypeProvider
#define UNOILLEGALARGUMENTEXCEPTION     ::com::sun::star::lang::IllegalArgumentException

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

#endif
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012 Desire Nuentsa Wakam <desire.nuentsa_wakam@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
#include "sparse.h"
#include <Eigen/SparseQR>

template<typename MatrixType,typename DenseMat>
int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300, int maxCols = 300)
{
  eigen_assert(maxRows >= maxCols);
  typedef typename MatrixType::Scalar Scalar;
  int rows = internal::random<int>(1,maxRows);
  int cols = internal::random<int>(1,rows);
  double density = (std::max)(8./(rows*cols), 0.01);

  A.resize(rows,rows);
  dA.resize(rows,rows);
  initSparse<Scalar>(density, dA, A,ForceNonZeroDiag);
  A.makeCompressed();
  return rows;
}

template<typename Scalar> void test_sparseqr_scalar()
{
  typedef SparseMatrix<Scalar,ColMajor> MatrixType;
  MatrixType A;
  Matrix<Scalar,Dynamic,Dynamic> dA;
  typedef Matrix<Scalar,Dynamic,1> DenseVector;
  DenseVector refX,x,b;
  SparseQR<MatrixType, AMDOrdering<int> > solver;
  generate_sparse_rectangular_problem(A,dA);

  int n = A.cols();
  b = DenseVector::Random(n);
  solver.compute(A);
  if (solver.info() != Success)
  {
    std::cerr << "sparse QR factorization failed\n";
    exit(0);
    return;
  }
  x = solver.solve(b);
  if (solver.info() != Success)
  {
    std::cerr << "sparse QR factorization failed\n";
    exit(0);
    return;
  }
  //Compare with a dense QR solver
  refX = dA.colPivHouseholderQr().solve(b);
  VERIFY(x.isApprox(refX,test_precision<Scalar>()));
}
void test_sparseqr()
{
  CALL_SUBTEST_1(test_sparseqr_scalar<double>());
  CALL_SUBTEST_2(test_sparseqr_scalar<std::complex<double> >());
}<commit_msg>Extend sparseqr unit test to check linearly dependent columns<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2012 Desire Nuentsa Wakam <desire.nuentsa_wakam@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
#include "sparse.h"
#include <Eigen/SparseQR>

template<typename MatrixType,typename DenseMat>
int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300, int maxCols = 300)
{
  eigen_assert(maxRows >= maxCols);
  typedef typename MatrixType::Scalar Scalar;
  int rows = internal::random<int>(1,maxRows);
  int cols = internal::random<int>(1,rows);
  double density = (std::max)(8./(rows*cols), 0.01);

  A.resize(rows,rows);
  dA.resize(rows,rows);
  initSparse<Scalar>(density, dA, A,ForceNonZeroDiag);
  A.makeCompressed();
  int nop = internal::random<int>(0, internal::random<double>(0,1) > 0.5 ? cols/2 : 0);
  for(int k=0; k<nop; ++k)
  {
    int j0 = internal::random<int>(0,cols-1);
    int j1 = internal::random<int>(0,cols-1);
    Scalar s = internal::random<Scalar>();
    A.col(j0)  = s * A.col(j1);
    dA.col(j0) = s * dA.col(j1);
  }
  return rows;
}

template<typename Scalar> void test_sparseqr_scalar()
{
  typedef SparseMatrix<Scalar,ColMajor> MatrixType;
  typedef Matrix<Scalar,Dynamic,Dynamic> DenseMat;
  typedef Matrix<Scalar,Dynamic,1> DenseVector;
  MatrixType A;
  DenseMat dA;
  DenseVector refX,x,b;
  SparseQR<MatrixType, AMDOrdering<int> > solver;
  generate_sparse_rectangular_problem(A,dA);

  int n = A.cols();
  b = DenseVector::Random(n);
  solver.compute(A);
  if (solver.info() != Success)
  {
    std::cerr << "sparse QR factorization failed\n";
    exit(0);
    return;
  }
  x = solver.solve(b);
  if (solver.info() != Success)
  {
    std::cerr << "sparse QR factorization failed\n";
    exit(0);
    return;
  }
  //Compare with a dense QR solver
  ColPivHouseholderQR<DenseMat> dqr(dA);
  refX = dqr.solve(b);

  VERIFY_IS_EQUAL(dqr.rank(), solver.rank());

  if(solver.rank()<A.cols())
    VERIFY((dA * refX - b).norm() * 2 > (A * x - b).norm() );
  else
    VERIFY_IS_APPROX(x, refX);
}
void test_sparseqr()
{
  for(int i=0; i<g_repeat; ++i)
  {
    CALL_SUBTEST_1(test_sparseqr_scalar<double>());
    CALL_SUBTEST_2(test_sparseqr_scalar<std::complex<double> >());
  }
}<|endoftext|>


<commit_before>#include "Persons.h"

#include <ioccpp/ioc.h>

#include <testcpp/testcpp.h>

#include <boost/make_shared.hpp>

class TestIoC : public Test::Suite
{
public:
    TESTCPP_TYPEDEF_TESTMETHOD(TestIoC)

    void test()
    {
        testSingleton();
        testLazySingleton();
        testScopedRegistration();
        testInvalidUsage();
    }

    void testSingleton()
    {
        IoCContainer<IPerson>::Register(
                boost::make_shared<Developer>());

        IPerson& person = IoCContainer<IPerson>::Resolve();

        assertEqual(person.role(), "Developer");
    }

    void testLazySingleton()
    {
        IoCContainer<IPerson>::RegisterFactory(managerFactory);

        IoCContainer<IPerson>::Reset();
        assertFalse(IoCContainer<IPerson>::DoesInstanceExist());

        IPerson& person = IoCContainer<IPerson>::Resolve();

        assertTrue(IoCContainer<IPerson>::DoesInstanceExist());
        assertEqual(person.role(), "Manager");
    }

    void testFactory()
    {
        IoCContainer<IPerson>::RegisterFactory(testerFactory);

        Tester::ResetCreationCount();
        assertEqual(Tester::CreationCount(), 0u);

        IoCContainer<IPerson>::ResolveNew();
        boost::shared_ptr<IPerson> person = IoCContainer<IPerson>::ResolveNew();

        assertEqual(person->role(), "Tester");
        assertEqual(Tester::CreationCount(), 2u);
    }

    void testScopedRegistration()
    {

    }

    void testInvalidUsage()
    {

    }
};

int main()
{
    Test::Controller &controller = Test::Controller::instance();
    controller.addTestSuite("ioc-cpp tests", Test::Suite::instance<TestIoC>);
    return controller.run();
}
<commit_msg>Add tests for invalid usage.<commit_after>#include "Persons.h"

#include <ioccpp/ioc.h>

#include <testcpp/testcpp.h>

#include <boost/make_shared.hpp>

class TestIoC : public Test::Suite
{
public:
    TESTCPP_TYPEDEF_TESTMETHOD(TestIoC)

    void test()
    {
        testSingleton();
        testLazySingleton();
        testScopedRegistration();
        testInvalidUsage();
    }

    void testSingleton()
    {
        IoCContainer<IPerson>::Register(boost::make_shared<Developer>());

        IPerson& person = IoCContainer<IPerson>::Resolve();

        assertEqual(person.role(), "Developer");
    }

    void testLazySingleton()
    {
        IoCContainer<IPerson>::RegisterFactory(managerFactory);

        IoCContainer<IPerson>::Reset();
        assertFalse(IoCContainer<IPerson>::DoesInstanceExist());

        IPerson& person = IoCContainer<IPerson>::Resolve();

        assertTrue(IoCContainer<IPerson>::DoesInstanceExist());
        assertEqual(person.role(), "Manager");
    }

    void testFactory()
    {
        IoCContainer<IPerson>::RegisterFactory(testerFactory);

        Tester::ResetCreationCount();
        assertEqual(Tester::CreationCount(), 0u);

        IoCContainer<IPerson>::ResolveNew();
        boost::shared_ptr<IPerson> person = IoCContainer<IPerson>::ResolveNew();

        assertEqual(person->role(), "Tester");
        assertEqual(Tester::CreationCount(), 2u);
    }

    void testScopedRegistration()
    {

    }

    void testInvalidUsage()
    {
        assertThrows(TestIoC, TestMethod, IoCError,
            *this, &TestIoC::resolveFromUninitializedContainer);

        assertThrows(TestIoC, TestMethod, IoCError,
            *this, &TestIoC::resolveFromUninitializedFactory);

        assertThrows(TestIoC, TestMethod, IoCError,
            *this, &TestIoC::registerNullObject);

        assertThrows(TestIoC, TestMethod, IoCError,
            *this, &TestIoC::registerNullFactory);
    }

    void resolveFromUninitializedContainer()
    {
        IoCContainer<IPerson>::Reset();
        IoCContainer<IPerson>::ResetFactory();

        IoCContainer<IPerson>::Resolve();
    }

    void resolveFromUninitializedFactory()
    {
        IoCContainer<IPerson>::ResetFactory();

        IoCContainer<IPerson>::ResolveNew();
    }

    void registerNullObject()
    {
        IoCContainer<IPerson>::Register(boost::shared_ptr<IPerson>());
    }

    void registerNullFactory()
    {
        IoCContainer<IPerson>::RegisterFactory(NULL);
    }
};

int main()
{
    Test::Controller &controller = Test::Controller::instance();
    controller.addTestSuite("ioc-cpp tests", Test::Suite::instance<TestIoC>);
    return controller.run();
}
<|endoftext|>


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

#include <utility>

namespace generic
{

namespace
{

template <typename F, int I, typename L, typename R, typename ...A>
inline F cify(L&& l, R (*)(A...))
{
  static L l_(::std::forward<L>(l));
  static bool full;

  if (full)
  {
    l_.~L();

    new (static_cast<void*>(&l_)) L(::std::forward<L>(l));
  }
  else
  {
    full = true;
  }

  struct S
  {
    static R f(A... args) noexcept(noexcept(l_(::std::forward<A>(args)...)))
    {
      return l_(::std::forward<A>(args)...);
    }
  };

  return &S::f;
}

}

template <typename F, int I = 0, typename L>
inline F cify(L&& l)
{
  return cify<F, I>(::std::forward<L>(l), F());
}

}

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

#include <utility>

namespace generic
{

namespace
{

template <typename F, int I, typename L, typename R, typename ...A>
inline F cify(L&& l, R (*)(A...))
{
  static L l_(::std::forward<L>(l));
  static bool full;

  if (full)
  {
    l_.~L();

    new (static_cast<void*>(&l_)) L(::std::forward<L>(l));
  }
  else
  {
    full = true;
  }

  return [](A... args) noexcept(noexcept(l_(::std::forward<A>(args)...)))
    {
      return l_(::std::forward<A>(args)...);
    };
}

template <typename F, int I = 0, typename L>
inline F cify(L&& l)
{
  return cify<F, I>(::std::forward<L>(l), F());
}

}

#endif // GENERIC_CIFY_HPP
<|endoftext|>