<commit_before>#include "gamestates/mapeditorstate.hpp"

#include "gui/texturemanager.hpp"
#include "config/settings.hpp"

#include <iostream>

namespace qrw
{

MapEditorState::MapEditorState(sf::RenderWindow* renderWindow)
	: GameState(renderWindow, EGameStateId::EGSID_MAP_EDITOR_STATE)
{
	// Initialize background
	_background.setTexture(TextureManager::getInstance()->getTexture("plainsquare"));
	_background.setFillColor(sf::Color(255, 255, 255, 255));

	// Initialize toolbar
	_toolBar = new namelessgui::Window();
	_toolBar->setVisible(true);
	_toolBar->setSize({150.0f, (float)Settings::getInstance()->getResolutionY()});
	_toolBar->setAnchor({1.0f, 0.0f});
	_toolBar->setParentAnchor({1.0f, 0.0f});
	_toolBar->setVisible(true);
	_guiUptr->addWidget(_toolBar);

	namelessgui::Label* label = new namelessgui::Label();
	label->setText("Terrain");
	label->setAnchor({0.5f, 0.0f});
	label->setParentAnchor({0.5f, 0.0f});
	_toolBar->addWidget(label);

	sf::Vector2f buttonSize(140.0f, 50.0f);

	namelessgui::Button* button = new namelessgui::Button();
	button->setText("Wood");
	button->setSize(buttonSize);
	button->setRelativePosition({5.0f, buttonSize.y});
	button->setImage(TextureManager::getInstance()->getTexture("wood"));
	_toolBar->addWidget(button);

	button = new namelessgui::Button();
	button->setText("Hill");
	button->setSize(buttonSize);
	button->setRelativePosition({5.0f, 2 * buttonSize.y});
	button->setImage(TextureManager::getInstance()->getTexture("hill"));
	_toolBar->addWidget(button);

	button = new namelessgui::Button();
	button->setText("Wall");
	button->setSize(buttonSize);
	button->setRelativePosition({5.0f, 3 * buttonSize.y});
	button->setImage(TextureManager::getInstance()->getTexture("wall"));
	_toolBar->addWidget(button);

	// Set up back to main menu dialog
	_backToMainMenuDialog = new namelessgui::ConfirmationDialog("Really exit and go back to main menu?");
	_backToMainMenuDialog->signalYesClicked.connect(std::bind(&MapEditorState::slotBackToMainMenu, this));
	_backToMainMenuDialog->setAnchor({0.5f, 0.5f});
	_backToMainMenuDialog->setParentAnchor({0.5f, 0.5f});
	_guiUptr->addWidget(_backToMainMenuDialog);

	// Set visibilities
	_guiUptr->setVisible(true);
	_background.setVisible(true);
	_backToMainMenuDialog->setVisible(false);
}

MapEditorState::~MapEditorState()
{
}

void MapEditorState::init(GameState* previousState)
{
	GameState::init();

	_backToMainMenu = false;
	_spBoard = std::make_shared<Board>(16, 9);

	_cursor.setBoard(_spBoard);

	sf::Vector2u spriteSize = _background.getTexture()->getSize();
	sf::Vector2f backgroundSize = sf::Vector2f(_spBoard->getWidth() * spriteSize.x, _spBoard->getHeight() * spriteSize.y);
	_background.setSize(backgroundSize);
}

EGameStateId MapEditorState::update()
{
	if(_backToMainMenu)
		return EGameStateId::EGSID_MAIN_MENU_STATE;

	return EGameStateId::EGSID_NO_CHANGE;
}

void MapEditorState::draw()
{
	_background.render(*_renderWindow, sf::RenderStates::Default);
	_guiUptr->render(*_renderWindow, sf::RenderStates::Default);
	_renderWindow->draw(_cursor);
}

bool MapEditorState::handleEvent(sf::Event& event)
{
	bool stopEventPropagation = GameState::handleEvent(event);

	if(stopEventPropagation)
		return stopEventPropagation;

	if(event.type == sf::Event::KeyPressed)
		if(event.key.code == sf::Keyboard::Escape)
			_backToMainMenuDialog->setVisible(true);

	// Scene must only handle events that are not consumed by the gui.
	if(!stopEventPropagation)
	{
		if(event.type == sf::Event::MouseMoved)
		{
			sf::Vector2i mousePixelCoordinates(event.mouseMove.x, event.mouseMove.y);

			sf::Vector2f mouseWorldCoordinates = _renderWindow->mapPixelToCoords(mousePixelCoordinates);

			sf::Event mouseMovedWorldCoordinates;
			mouseMovedWorldCoordinates.type = sf::Event::MouseMoved;
			mouseMovedWorldCoordinates.mouseMove.x = mouseWorldCoordinates.x;
			mouseMovedWorldCoordinates.mouseMove.y = mouseWorldCoordinates.y;

			_cursor.handleEvent(mouseMovedWorldCoordinates);
		}
		else
		{
			_cursor.handleEvent(event);
		}
	}

	return stopEventPropagation;
}

void MapEditorState::slotBackToMainMenu()
{
	_backToMainMenu = true;
}

} // namespace qrw
<commit_msg>Fixed render order in map editor.<commit_after>#include "gamestates/mapeditorstate.hpp"

#include "gui/texturemanager.hpp"
#include "config/settings.hpp"

#include <iostream>

namespace qrw
{

MapEditorState::MapEditorState(sf::RenderWindow* renderWindow)
	: GameState(renderWindow, EGameStateId::EGSID_MAP_EDITOR_STATE)
{
	// Initialize background
	_background.setTexture(TextureManager::getInstance()->getTexture("plainsquare"));
	_background.setFillColor(sf::Color(255, 255, 255, 255));

	// Initialize toolbar
	_toolBar = new namelessgui::Window();
	_toolBar->setVisible(true);
	_toolBar->setSize({150.0f, (float)Settings::getInstance()->getResolutionY()});
	_toolBar->setAnchor({1.0f, 0.0f});
	_toolBar->setParentAnchor({1.0f, 0.0f});
	_toolBar->setVisible(true);
	_guiUptr->addWidget(_toolBar);

	namelessgui::Label* label = new namelessgui::Label();
	label->setText("Terrain");
	label->setAnchor({0.5f, 0.0f});
	label->setParentAnchor({0.5f, 0.0f});
	_toolBar->addWidget(label);

	sf::Vector2f buttonSize(140.0f, 50.0f);

	namelessgui::Button* button = new namelessgui::Button();
	button->setText("Wood");
	button->setSize(buttonSize);
	button->setRelativePosition({5.0f, buttonSize.y});
	button->setImage(TextureManager::getInstance()->getTexture("wood"));
	_toolBar->addWidget(button);

	button = new namelessgui::Button();
	button->setText("Hill");
	button->setSize(buttonSize);
	button->setRelativePosition({5.0f, 2 * buttonSize.y});
	button->setImage(TextureManager::getInstance()->getTexture("hill"));
	_toolBar->addWidget(button);

	button = new namelessgui::Button();
	button->setText("Wall");
	button->setSize(buttonSize);
	button->setRelativePosition({5.0f, 3 * buttonSize.y});
	button->setImage(TextureManager::getInstance()->getTexture("wall"));
	_toolBar->addWidget(button);

	// Set up back to main menu dialog
	_backToMainMenuDialog = new namelessgui::ConfirmationDialog("Really exit and go back to main menu?");
	_backToMainMenuDialog->signalYesClicked.connect(std::bind(&MapEditorState::slotBackToMainMenu, this));
	_backToMainMenuDialog->setAnchor({0.5f, 0.5f});
	_backToMainMenuDialog->setParentAnchor({0.5f, 0.5f});
	_guiUptr->addWidget(_backToMainMenuDialog);

	// Set visibilities
	_guiUptr->setVisible(true);
	_background.setVisible(true);
	_backToMainMenuDialog->setVisible(false);
}

MapEditorState::~MapEditorState()
{
}

void MapEditorState::init(GameState* previousState)
{
	GameState::init();

	_backToMainMenu = false;
	_spBoard = std::make_shared<Board>(16, 9);

	_cursor.setBoard(_spBoard);

	sf::Vector2u spriteSize = _background.getTexture()->getSize();
	sf::Vector2f backgroundSize = sf::Vector2f(_spBoard->getWidth() * spriteSize.x, _spBoard->getHeight() * spriteSize.y);
	_background.setSize(backgroundSize);
}

EGameStateId MapEditorState::update()
{
	if(_backToMainMenu)
		return EGameStateId::EGSID_MAIN_MENU_STATE;

	return EGameStateId::EGSID_NO_CHANGE;
}

void MapEditorState::draw()
{
	_background.render(*_renderWindow, sf::RenderStates::Default);
	_renderWindow->draw(_cursor);
	_guiUptr->render(*_renderWindow, sf::RenderStates::Default);
}

bool MapEditorState::handleEvent(sf::Event& event)
{
	bool stopEventPropagation = GameState::handleEvent(event);

	if(stopEventPropagation)
		return stopEventPropagation;

	if(event.type == sf::Event::KeyPressed)
		if(event.key.code == sf::Keyboard::Escape)
			_backToMainMenuDialog->setVisible(true);

	// Scene must only handle events that are not consumed by the gui.
	if(!stopEventPropagation)
	{
		if(event.type == sf::Event::MouseMoved)
		{
			sf::Vector2i mousePixelCoordinates(event.mouseMove.x, event.mouseMove.y);

			sf::Vector2f mouseWorldCoordinates = _renderWindow->mapPixelToCoords(mousePixelCoordinates);

			sf::Event mouseMovedWorldCoordinates;
			mouseMovedWorldCoordinates.type = sf::Event::MouseMoved;
			mouseMovedWorldCoordinates.mouseMove.x = mouseWorldCoordinates.x;
			mouseMovedWorldCoordinates.mouseMove.y = mouseWorldCoordinates.y;

			_cursor.handleEvent(mouseMovedWorldCoordinates);
		}
		else
		{
			_cursor.handleEvent(event);
		}
	}

	return stopEventPropagation;
}

void MapEditorState::slotBackToMainMenu()
{
	_backToMainMenu = true;
}

} // namespace qrw
<|endoftext|>


<commit_before>// Copyright 2016 AUV-IITK
#include <cv.h>
#include <highgui.h>
#include <ros/ros.h>
#include "std_msgs/String.h"
#include "std_msgs/Int8.h"
#include <fstream>
#include <dynamic_reconfigure/server.h>
#include <task_buoy/buoyConfig.h>
#include <vector>
#include <std_msgs/Bool.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv/highgui.h>
#include <image_transport/image_transport.h>
#include "std_msgs/Float64MultiArray.h"
#include <cv_bridge/cv_bridge.h>
#include <sstream>
#include <string>

bool IP = false;
bool flag = false;
bool video = false;
int t1min, t1max, t2min, t2max, t3min, t3max;  // Default Params

cv::Mat frame;
cv::Mat newframe;
int count = 0, count_avg = 0, x = -1;

void callback(task_buoy::buoyConfig &config, uint32_t level)
{
  t1min = config.t1min_param;
  t1max = config.t1max_param;
  t2min = config.t2min_param;
  t2max = config.t2max_param;
  t3min = config.t3min_param;
  t3max = config.t3max_param;
  ROS_INFO("Reconfigure Request : New parameters : %d %d %d %d %d %d", t1min, t1max, t2min, t2max, t3min, t3max);
}

void lineDetectedListener(std_msgs::Bool msg)
{
  IP = msg.data;
}

void imageCallback(const sensor_msgs::ImageConstPtr &msg)
{
  if (x == 32) return;
  try
  {
    count++;
    newframe = cv_bridge::toCvShare(msg, "bgr8")->image;
    cvNamedWindow("newframe", CV_WINDOW_NORMAL);
    ///////////////////////////// DO NOT REMOVE THIS, IT COULD BE INGERIOUS TO HEALTH /////////////////////
    newframe.copyTo(frame);
    cv::imshow("newframe", newframe);
    ////////////////////////// FATAL ///////////////////////////////////////////////////
  }
  catch (cv_bridge::Exception &e)
  {
    ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
  }
}

int main(int argc, char* argv[])
{
  int height, width, step, channels;  // parameters of the image we are working on
  std::string Video_Name = "Random_Video";
  if (argc >= 2)
    flag = true;
  if (argc == 3)
  {
    video = true;
    std::string avi = ".avi";
    Video_Name = (argv[2]) + avi;
  }

  cv::VideoWriter output_cap(Video_Name, CV_FOURCC('D', 'I', 'V', 'X'), 9, cv::Size(640, 480));

  ros::init(argc, argv, "buoy_detection");
  ros::NodeHandle n;
  ros::Publisher pub = n.advertise<std_msgs::Float64MultiArray>("/varun/ip/buoy", 1000);
  ros::Subscriber sub = n.subscribe<std_msgs::Bool>("buoy_detection_switch", 1000, &lineDetectedListener);
  ros::Rate loop_rate(10);
  int t1minParam, t1maxParam, t2minParam, t2maxParam, t3minParam, t3maxParam;

  n.getParam("buoy_detection/t1maxParam", t1maxParam);
  n.getParam("buoy_detection/t1minParam", t1minParam);
  n.getParam("buoy_detection/t2maxParam", t2maxParam);
  n.getParam("buoy_detection/t2minParam", t2minParam);
  n.getParam("buoy_detection/t3maxParam", t3maxParam);
  n.getParam("buoy_detection/t3minParam", t3minParam);

  t1min = t1minParam;
  t1max = t1maxParam;
  t2min = t2minParam;
  t2max = t2maxParam;
  t3min = t3minParam;
  t3max = t3maxParam;

  image_transport::ImageTransport it(n);
  image_transport::Subscriber sub1 = it.subscribe("/varun/sensors/front_camera/image_raw", 1, imageCallback);

  dynamic_reconfigure::Server<task_buoy::buoyConfig> server;
  dynamic_reconfigure::Server<task_buoy::buoyConfig>::CallbackType f;
  f = boost::bind(&callback, _1, _2);
  server.setCallback(f);

  cvNamedWindow("Contours", CV_WINDOW_NORMAL);
  cvNamedWindow("circle", CV_WINDOW_NORMAL);
  cvNamedWindow("After Color Filtering", CV_WINDOW_NORMAL);

  if (flag)
  {
    cvNamedWindow("F1", CV_WINDOW_NORMAL);
    cvNamedWindow("F2", CV_WINDOW_NORMAL);
    cvNamedWindow("F3", CV_WINDOW_NORMAL);
  }

  // capture size -
  CvSize size = cvSize(width, height);

  cv::Mat hsv_frame, thresholded, thresholded1, thresholded2, thresholded3, filtered;  // image converted to HSV plane
  float r[5];

  for (int m=0; m++; m < 5)
    r[m] = 0;

  while (ros::ok())
  {
    std_msgs::Float64MultiArray array;
    loop_rate.sleep();
    if (frame.empty())
    {
      std::cout << "empty frame \n";
      ros::spinOnce();
      continue;
    }

    if (video)
      output_cap.write(frame);
    // get the image data
    height = frame.rows;
    width = frame.cols;
    step = frame.step;

    // Covert color space to HSV as it is much easier to filter colors in the HSV color-space.
    cv::cvtColor(frame, hsv_frame, CV_BGR2HSV);
    cv::Scalar hsv_min = cv::Scalar(t1min, t2min, t3min, 0);
    cv::Scalar hsv_max = cv::Scalar(t1max, t2max, t3max, 0);
    // Filter out colors which are out of range.
    cv::inRange(hsv_frame, hsv_min, hsv_max, thresholded);
    // Split image into its 3 one dimensional images
    cv::Mat thresholded_hsv[3];
    cv::split(hsv_frame, thresholded_hsv);

    // Filter out colors which are out of range.
    cv::inRange(thresholded_hsv[0], cv::Scalar(t1min, 0, 0, 0), cv::Scalar(t1max, 0, 0, 0), thresholded_hsv[0]);
    cv::inRange(thresholded_hsv[1], cv::Scalar(t2min, 0, 0, 0), cv::Scalar(t2max, 0, 0, 0), thresholded_hsv[1]);
    cv::inRange(thresholded_hsv[2], cv::Scalar(t3min, 0, 0, 0), cv::Scalar(t3max, 0, 0, 0), thresholded_hsv[2]);
    cv::GaussianBlur(thresholded, thresholded, cv::Size(9, 9), 0, 0, 0);
    cv::imshow("After Color Filtering", thresholded);  // The stream after color filtering

    if (flag)
    {
      cv::imshow("F1", thresholded_hsv[0]);              // individual filters
      cv::imshow("F2", thresholded_hsv[1]);
      cv::imshow("F3", thresholded_hsv[2]);
    }

    if ((cvWaitKey(10) & 255) == 27)
      break;

    if (!IP)
    {
      // find contours
      std::vector<std::vector<cv::Point> > contours;
      cv::Mat thresholded_Mat = thresholded;
      findContours(thresholded_Mat, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);  // Find the contours
      double largest_area = 0, largest_contour_index = 0;

      if (contours.empty())
      {
        array.data.push_back(0);
        array.data.push_back(0);
        array.data.push_back(0);
        array.data.push_back(0);
        pub.publish(array);
        ros::spinOnce();
        // If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
        // remove higher bits using AND operator
        if ((cvWaitKey(10) & 255) == 27)
          break;
        continue;
      }

      for (int i = 0; i < contours.size(); i++)  // iterate through each contour.
      {
        double a = contourArea(contours[i], false);  //  Find the area of contour
        if (a > largest_area)
        {
          largest_area = a;
          largest_contour_index = i;  // Store the index of largest contour
        }
      }
      // Convex HULL
      std::vector<std::vector<cv::Point> > hull(contours.size());
      convexHull(cv::Mat(contours[largest_contour_index]), hull[largest_contour_index], false);

      std::vector<cv::Point2f> center(1);
      std::vector<float> radius(1);
      std::vector<cv::Point2f> center_ideal(1);
      cv::minEnclosingCircle(contours[largest_contour_index], center[0], radius[0]);

      cv::Point2f pt;
      pt.x = 320;  // size of my screen
      pt.y = 240;

      float r_avg = (r[0] + r[1] + r[2] + r[3] + r[4])/5;
      if ((radius[0] < (r_avg + 10)) && (count_avg >= 5))
      {
         r[4] = r[3];
         r[3] = r[2];
         r[2] = r[1];
         r[1] = r[0];
         r[0] = radius[0];
         count_avg++;
         center_ideal[0] = center[0];
      }
      else if (count_avg <= 5)
      {
        r[count_avg] = radius[0];
         count_avg++;
      }
      else
      {
         count_avg = 0;
      }

      cv::Mat circles = frame;
      circle(circles, center_ideal[0], r[0], cv::Scalar(0, 250, 0), 1, 8, 0);  // minenclosing circle
      circle(circles, center_ideal[0], 4, cv::Scalar(0, 250, 0), -1, 8, 0);         // center is made on the screen
      circle(circles, pt, 4, cv::Scalar(150, 150, 150), -1, 8, 0);            // center of screen

      if (r[0] > 220)
      {
        array.data.push_back(-1);
        array.data.push_back(-1);
        array.data.push_back(-1);
        array.data.push_back(-1);
      }
      else
      {
        float distance;
        distance = pow(radius[0] / 7526.5, -.92678);  // function found using experiment
        array.data.push_back(r[0]);                                        // publish radius
        array.data.push_back((320 - center_ideal[0].x));
        array.data.push_back(-(240 - center_ideal[0].y));
        array.data.push_back(distance);
      }
      cv::imshow("circle", circles);            // Original stream with detected ball overlay
      cv::imshow("Contours", thresholded_Mat);  // The stream after color filtering
      pub.publish(array);

      ros::spinOnce();
      // If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
      // remove higher bits using AND operator
      if ((cvWaitKey(10) & 255) == 27)
        break;
    }
    else if (r[0] > 220)
    {
       array.data.push_back(-1);
       array.data.push_back(-1);
       array.data.push_back(-1);
       array.data.push_back(-1);
    }
    else
    {
      std::cout << "waiting\n";
      if ((cvWaitKey(10) & 255) == 32)
      {
        if (x == 32) x = -1;
        else x = 32;
      }
      if (x == 32) printf("paused\n");
      ros::spinOnce();
    }
  }
  output_cap.release();
  return 0;
}
<commit_msg>sends particular value when out of frame<commit_after>// Copyright 2016 AUV-IITK
#include <cv.h>
#include <highgui.h>
#include <ros/ros.h>
#include "std_msgs/String.h"
#include "std_msgs/Int8.h"
#include <fstream>
#include <dynamic_reconfigure/server.h>
#include <task_buoy/buoyConfig.h>
#include <vector>
#include <std_msgs/Bool.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv/highgui.h>
#include <image_transport/image_transport.h>
#include "std_msgs/Float64MultiArray.h"
#include <cv_bridge/cv_bridge.h>
#include <sstream>
#include <string>

bool IP = false;
bool flag = false;
bool video = false;
int t1min, t1max, t2min, t2max, t3min, t3max;  // Default Params

cv::Mat frame;
cv::Mat newframe;
int count = 0, count_avg = 0, x = -1;

void callback(task_buoy::buoyConfig &config, uint32_t level)
{
  t1min = config.t1min_param;
  t1max = config.t1max_param;
  t2min = config.t2min_param;
  t2max = config.t2max_param;
  t3min = config.t3min_param;
  t3max = config.t3max_param;
  ROS_INFO("Reconfigure Request : New parameters : %d %d %d %d %d %d", t1min, t1max, t2min, t2max, t3min, t3max);
}

void lineDetectedListener(std_msgs::Bool msg)
{
  IP = msg.data;
}

void imageCallback(const sensor_msgs::ImageConstPtr &msg)
{
  if (x == 32) return;
  try
  {
    count++;
    newframe = cv_bridge::toCvShare(msg, "bgr8")->image;
    cvNamedWindow("newframe", CV_WINDOW_NORMAL);
    ///////////////////////////// DO NOT REMOVE THIS, IT COULD BE INGERIOUS TO HEALTH /////////////////////
    newframe.copyTo(frame);
    cv::imshow("newframe", newframe);
    ////////////////////////// FATAL ///////////////////////////////////////////////////
  }
  catch (cv_bridge::Exception &e)
  {
    ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
  }
}

int main(int argc, char* argv[])
{
  int height, width, step, channels;  // parameters of the image we are working on
  std::string Video_Name = "Random_Video";
  if (argc >= 2)
    flag = true;
  if (argc == 3)
  {
    video = true;
    std::string avi = ".avi";
    Video_Name = (argv[2]) + avi;
  }

  cv::VideoWriter output_cap(Video_Name, CV_FOURCC('D', 'I', 'V', 'X'), 9, cv::Size(640, 480));

  ros::init(argc, argv, "buoy_detection");
  ros::NodeHandle n;
  ros::Publisher pub = n.advertise<std_msgs::Float64MultiArray>("/varun/ip/buoy", 1000);
  ros::Subscriber sub = n.subscribe<std_msgs::Bool>("buoy_detection_switch", 1000, &lineDetectedListener);
  ros::Rate loop_rate(10);
  int t1minParam, t1maxParam, t2minParam, t2maxParam, t3minParam, t3maxParam;

  n.getParam("buoy_detection/t1maxParam", t1maxParam);
  n.getParam("buoy_detection/t1minParam", t1minParam);
  n.getParam("buoy_detection/t2maxParam", t2maxParam);
  n.getParam("buoy_detection/t2minParam", t2minParam);
  n.getParam("buoy_detection/t3maxParam", t3maxParam);
  n.getParam("buoy_detection/t3minParam", t3minParam);

  t1min = t1minParam;
  t1max = t1maxParam;
  t2min = t2minParam;
  t2max = t2maxParam;
  t3min = t3minParam;
  t3max = t3maxParam;

  image_transport::ImageTransport it(n);
  image_transport::Subscriber sub1 = it.subscribe("/varun/sensors/front_camera/image_raw", 1, imageCallback);

  dynamic_reconfigure::Server<task_buoy::buoyConfig> server;
  dynamic_reconfigure::Server<task_buoy::buoyConfig>::CallbackType f;
  f = boost::bind(&callback, _1, _2);
  server.setCallback(f);

  cvNamedWindow("Contours", CV_WINDOW_NORMAL);
  cvNamedWindow("circle", CV_WINDOW_NORMAL);
  cvNamedWindow("After Color Filtering", CV_WINDOW_NORMAL);

  if (flag)
  {
    cvNamedWindow("F1", CV_WINDOW_NORMAL);
    cvNamedWindow("F2", CV_WINDOW_NORMAL);
    cvNamedWindow("F3", CV_WINDOW_NORMAL);
  }

  // capture size -
  CvSize size = cvSize(width, height);
  std::vector<cv::Point2f> center_ideal(5);

  cv::Mat hsv_frame, thresholded, thresholded1, thresholded2, thresholded3, filtered;  // image converted to HSV plane
  float r[5];

  for (int m=0; m++; m < 5)
    r[m] = 0;

  while (ros::ok())
  {
    std_msgs::Float64MultiArray array;
    loop_rate.sleep();
    if (frame.empty())
    {
      std::cout << "empty frame \n";
      ros::spinOnce();
      continue;
    }

    if (video)
      output_cap.write(frame);
    // get the image data
    height = frame.rows;
    width = frame.cols;
    step = frame.step;

    // Covert color space to HSV as it is much easier to filter colors in the HSV color-space.
    cv::cvtColor(frame, hsv_frame, CV_BGR2HSV);
    cv::Scalar hsv_min = cv::Scalar(t1min, t2min, t3min, 0);
    cv::Scalar hsv_max = cv::Scalar(t1max, t2max, t3max, 0);
    // Filter out colors which are out of range.
    cv::inRange(hsv_frame, hsv_min, hsv_max, thresholded);
    // Split image into its 3 one dimensional images
    cv::Mat thresholded_hsv[3];
    cv::split(hsv_frame, thresholded_hsv);

    // Filter out colors which are out of range.
    cv::inRange(thresholded_hsv[0], cv::Scalar(t1min, 0, 0, 0), cv::Scalar(t1max, 0, 0, 0), thresholded_hsv[0]);
    cv::inRange(thresholded_hsv[1], cv::Scalar(t2min, 0, 0, 0), cv::Scalar(t2max, 0, 0, 0), thresholded_hsv[1]);
    cv::inRange(thresholded_hsv[2], cv::Scalar(t3min, 0, 0, 0), cv::Scalar(t3max, 0, 0, 0), thresholded_hsv[2]);
    cv::GaussianBlur(thresholded, thresholded, cv::Size(9, 9), 0, 0, 0);
    cv::imshow("After Color Filtering", thresholded);  // The stream after color filtering

    if (flag)
    {
      cv::imshow("F1", thresholded_hsv[0]);              // individual filters
      cv::imshow("F2", thresholded_hsv[1]);
      cv::imshow("F3", thresholded_hsv[2]);
    }

    if ((cvWaitKey(10) & 255) == 27)
      break;

    if (!IP)
    {
      // find contours
      std::vector<std::vector<cv::Point> > contours;
      cv::Mat thresholded_Mat = thresholded;
      findContours(thresholded_Mat, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);  // Find the contours
      double largest_area = 0, largest_contour_index = 0;
      if (contours.empty())
      {
        int x_cord = 320 - center_ideal[0].x;
        int y_cord = -240 + center_ideal[0].y;
        if (x_cord < -270)
        {
          array.data.push_back(-2);  //top
          array.data.push_back(-2);
          array.data.push_back(-2);
          array.data.push_back(-2);
        }
        else if (x_cord > 270)
        {
          array.data.push_back(-1);   //left_side
          array.data.push_back(-1);
          array.data.push_back(-1);
          array.data.push_back(-1);
        }
        else if (y_cord > 200)
        {
          array.data.push_back(-3);  //bottom
          array.data.push_back(-3);
          array.data.push_back(-3);
          array.data.push_back(-3);
        }
        else if (y_cord < -200)
        {
          array.data.push_back(-4); //right_side
          array.data.push_back(-4);
          array.data.push_back(-4);
          array.data.push_back(-4);
        }
        pub.publish(array);
        ros::spinOnce();
        // If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
        // remove higher bits using AND operator
        if ((cvWaitKey(10) & 255) == 27)
          break;
        continue;
      }

      for (int i = 0; i < contours.size(); i++)  // iterate through each contour.
      {
        double a = contourArea(contours[i], false);  //  Find the area of contour
        if (a > largest_area)
        {
          largest_area = a;
          largest_contour_index = i;  // Store the index of largest contour
        }
      }
      // Convex HULL
      std::vector<std::vector<cv::Point> > hull(contours.size());
      convexHull(cv::Mat(contours[largest_contour_index]), hull[largest_contour_index], false);

      std::vector<cv::Point2f> center(1);
      std::vector<float> radius(1);
      cv::minEnclosingCircle(contours[largest_contour_index], center[0], radius[0]);
      cv::Point2f pt;
      pt.x = 320;  // size of my screen
      pt.y = 240;

      float r_avg = (r[0] + r[1] + r[2] + r[3] + r[4])/5;
      if ((radius[0] < (r_avg + 10)) && (count_avg >= 5))
      {
         r[4] = r[3];
         r[3] = r[2];
         r[2] = r[1];
         r[1] = r[0];
         r[0] = radius[0];
         center_ideal[4] = center_ideal[3];
         center_ideal[3] = center_ideal[2];
         center_ideal[2] = center_ideal[1];
         center_ideal[1] = center_ideal[0];
         center_ideal[0] = center[0];
         count_avg++;
      }
      else if (count_avg <= 5)
      {
        r[count_avg] = radius[0];
        center_ideal[count_avg]=center[0];
         count_avg++;
      }
      else
      {
         count_avg = 0;
      }

      cv::Mat circles = frame;
      circle(circles, center_ideal[0], r[0], cv::Scalar(0, 250, 0), 1, 8, 0);  // minenclosing circle
      circle(circles, center_ideal[0], 4, cv::Scalar(0, 250, 0), -1, 8, 0);         // center is made on the screen
      circle(circles, pt, 4, cv::Scalar(150, 150, 150), -1, 8, 0);            // center of screen

      if (r[0] > 220)
      {
        array.data.push_back(-1);
        array.data.push_back(-1);
        array.data.push_back(-1);
        array.data.push_back(-1);
      }
      else
      {
        float distance;
        distance = pow(radius[0] / 7526.5, -.92678);  // function found using experiment
        array.data.push_back(r[0]);                                        // publish radius
        array.data.push_back((320 - center_ideal[0].x));
        array.data.push_back(-(240 - center_ideal[0].y));
        array.data.push_back(distance);
      }
      cv::imshow("circle", circles);            // Original stream with detected ball overlay
      cv::imshow("Contours", thresholded_Mat);  // The stream after color filtering
      pub.publish(array);

      ros::spinOnce();
      // If ESC key pressed, Key=0x10001B under OpenCV 0.9.7(linux version),
      // remove higher bits using AND operator
      if ((cvWaitKey(10) & 255) == 27)
        break;
    }
    else if (r[0] > 220)
    {
       array.data.push_back(-1);
       array.data.push_back(-1);
       array.data.push_back(-1);
       array.data.push_back(-1);
    }
    else
    {
      std::cout << "waiting\n";
      if ((cvWaitKey(10) & 255) == 32)
      {
        if (x == 32) x = -1;
        else x = 32;
      }
      if (x == 32) printf("paused\n");
      ros::spinOnce();
    }
  }
  output_cap.release();
  return 0;
}
<|endoftext|>


<commit_before>#include "gamestates/mapeditorstate.hpp"

#include "engine/terrain.hpp"
#include "engine/square.hpp"

#include "gui/texturemanager.hpp"

#include <iostream>

namespace qrw
{

MapEditorState::MapEditorState(sf::RenderWindow* renderWindow)
	: SceneState(renderWindow, EGameStateId::EGSID_MAP_EDITOR_STATE),
	  _activeTerrainType(ET_NUMBEROFTERRAINTYPES)
{
	// Initialize toolbar
	namelessgui::Label* label = new namelessgui::Label();
	label->setText("Terrain");
	label->setAnchor({0.5f, 0.0f});
	label->setParentAnchor({0.5f, 0.0f});
	_toolBar->addWidget(label);

	sf::Vector2f buttonSize(140.0f, 50.0f);

	namelessgui::RadioToggleButton* radioButton = new namelessgui::RadioToggleButton();
	std::shared_ptr<namelessgui::ButtonGroup> spTerrainButtonGroup = radioButton->getButtonGroup();
	radioButton->setText("Wood");
	radioButton->setSize(buttonSize);
	radioButton->setRelativePosition({5.0f, buttonSize.y});
	radioButton->setImage(TextureManager::getInstance()->getTexture("wood"));
	radioButton->signalActivated.connect(std::bind(&MapEditorState::slotTerrainButtonChanged, this, std::placeholders::_1));
	_toolBar->addWidget(radioButton);

	radioButton = new namelessgui::RadioToggleButton(spTerrainButtonGroup);
	radioButton->setText("Hill");
	radioButton->setSize(buttonSize);
	radioButton->setRelativePosition({5.0f, 2 * buttonSize.y});
	radioButton->setImage(TextureManager::getInstance()->getTexture("hill"));
	radioButton->signalActivated.connect(std::bind(&MapEditorState::slotTerrainButtonChanged, this, std::placeholders::_1));
	_toolBar->addWidget(radioButton);

	radioButton = new namelessgui::RadioToggleButton(spTerrainButtonGroup);
	radioButton->setText("Wall");
	radioButton->setSize(buttonSize);
	radioButton->setRelativePosition({5.0f, 3 * buttonSize.y});
	radioButton->setImage(TextureManager::getInstance()->getTexture("wall"));
	radioButton->signalActivated.connect(std::bind(&MapEditorState::slotTerrainButtonChanged, this, std::placeholders::_1));
	_toolBar->addWidget(radioButton);

	namelessgui::Button* toDeploymentButton = new namelessgui::Button();
	toDeploymentButton->setText("next step");
	toDeploymentButton->setSize({buttonSize.x, 30.0f});
	toDeploymentButton->setAnchor({0.5f, 1.0f});
	toDeploymentButton->setParentAnchor({0.5f, 1.0f});
	toDeploymentButton->setRelativePosition({0.0f, -50.0f});
	toDeploymentButton->signalclicked.connect(std::bind(&MapEditorState::slotToDeploymentButtonClicked, this));
	_toolBar->addWidget(toDeploymentButton);
}

MapEditorState::~MapEditorState()
{
}

void MapEditorState::init(GameState* previousState)
{
	GameState::init();

	_toDeployment = false;
	_spBoard = std::make_shared<Board>(16, 9);
	_scene = std::unique_ptr<Scene>(new Scene(_renderWindow, _spBoard));

	_scene->signalCursorLeftClicked.connect(std::bind(&MapEditorState::slotCursorLeftClicked, this, std::placeholders::_1));
	_scene->signalCursorRightClicked.connect(std::bind(&MapEditorState::slotCursorRightClicked, this, std::placeholders::_1));
}

EGameStateId MapEditorState::update()
{
	if(_backToMainMenu)
		return EGameStateId::EGSID_MAIN_MENU_STATE;

	if(_toDeployment)
		return EGameStateId::EGSID_DEPLOY_STATE;

	return EGameStateId::EGSID_NO_CHANGE;
}

bool MapEditorState::handleEvent(sf::Event& event)
{
	bool stopEventPropagation = SceneState::handleEvent(event);

	return stopEventPropagation;
}

Board::Ptr MapEditorState::getBoard() const
{
	return _spBoard;
}

void MapEditorState::slotCursorLeftClicked(const Coordinates& boardPosition)
{
	// Do nothing if no terrain type was selected
	if(_activeTerrainType == ET_NUMBEROFTERRAINTYPES)
		return;

	// Create new terrain
	Terrain::Ptr terrain = Terrain::createTerrain(_activeTerrainType);
	if(terrain != nullptr)
	{
		_spBoard->getSquare(boardPosition)->setTerrain(terrain);
		_scene->addTerrainEntity(TerrainEntity::createTerrainEntity(terrain, 32));
	}
}

void MapEditorState::slotCursorRightClicked(const Coordinates& boardPosition)
{
	_spBoard->getSquare(boardPosition)->setTerrain(nullptr);
	_scene->removeTerrainEntityAt(boardPosition);
}

void MapEditorState::slotTerrainButtonChanged(const namelessgui::RadioToggleButton& activeTerrainButton)
{
	const std::string& terrainString = activeTerrainButton.getText();

	if(terrainString == "Wood")
		_activeTerrainType = ET_WOOD;
	else if(terrainString == "Hill")
		_activeTerrainType = ET_HILL;
	else if(terrainString == "Wall")
		_activeTerrainType = ET_WALL;
	else
		_activeTerrainType = ET_NUMBEROFTERRAINTYPES;
}

void MapEditorState::slotToDeploymentButtonClicked()
{
	_toDeployment = true;
}

} // namespace qrw
<commit_msg>Improved MapEditorState's to-deployment button.<commit_after>#include "gamestates/mapeditorstate.hpp"

#include "engine/terrain.hpp"
#include "engine/square.hpp"

#include "gui/texturemanager.hpp"

#include <iostream>

namespace qrw
{

MapEditorState::MapEditorState(sf::RenderWindow* renderWindow)
	: SceneState(renderWindow, EGameStateId::EGSID_MAP_EDITOR_STATE),
	  _activeTerrainType(ET_NUMBEROFTERRAINTYPES)
{
	// Initialize toolbar
	namelessgui::Label* label = new namelessgui::Label();
	label->setText("Terrain");
	label->setAnchor({0.5f, 0.0f});
	label->setParentAnchor({0.5f, 0.0f});
	_toolBar->addWidget(label);

	sf::Vector2f buttonSize(140.0f, 50.0f);

	namelessgui::RadioToggleButton* radioButton = new namelessgui::RadioToggleButton();
	std::shared_ptr<namelessgui::ButtonGroup> spTerrainButtonGroup = radioButton->getButtonGroup();
	radioButton->setText("Wood");
	radioButton->setSize(buttonSize);
	radioButton->setRelativePosition({5.0f, buttonSize.y});
	radioButton->setImage(TextureManager::getInstance()->getTexture("wood"));
	radioButton->signalActivated.connect(std::bind(&MapEditorState::slotTerrainButtonChanged, this, std::placeholders::_1));
	_toolBar->addWidget(radioButton);

	radioButton = new namelessgui::RadioToggleButton(spTerrainButtonGroup);
	radioButton->setText("Hill");
	radioButton->setSize(buttonSize);
	radioButton->setRelativePosition({5.0f, 2 * buttonSize.y});
	radioButton->setImage(TextureManager::getInstance()->getTexture("hill"));
	radioButton->signalActivated.connect(std::bind(&MapEditorState::slotTerrainButtonChanged, this, std::placeholders::_1));
	_toolBar->addWidget(radioButton);

	radioButton = new namelessgui::RadioToggleButton(spTerrainButtonGroup);
	radioButton->setText("Wall");
	radioButton->setSize(buttonSize);
	radioButton->setRelativePosition({5.0f, 3 * buttonSize.y});
	radioButton->setImage(TextureManager::getInstance()->getTexture("wall"));
	radioButton->signalActivated.connect(std::bind(&MapEditorState::slotTerrainButtonChanged, this, std::placeholders::_1));
	_toolBar->addWidget(radioButton);

	namelessgui::Button* toDeploymentButton = new namelessgui::Button();
	toDeploymentButton->setText("Deploy Troops");
	toDeploymentButton->setSize({buttonSize.x, 30.0f});
	toDeploymentButton->setAnchor({0.5f, 1.0f});
	toDeploymentButton->setParentAnchor({0.5f, 1.0f});
	toDeploymentButton->setRelativePosition({0.0f, -5.0f});
	toDeploymentButton->signalclicked.connect(std::bind(&MapEditorState::slotToDeploymentButtonClicked, this));
	_toolBar->addWidget(toDeploymentButton);
}

MapEditorState::~MapEditorState()
{
}

void MapEditorState::init(GameState* previousState)
{
	GameState::init();

	_toDeployment = false;
	_spBoard = std::make_shared<Board>(16, 9);
	_scene = std::unique_ptr<Scene>(new Scene(_renderWindow, _spBoard));

	_scene->signalCursorLeftClicked.connect(std::bind(&MapEditorState::slotCursorLeftClicked, this, std::placeholders::_1));
	_scene->signalCursorRightClicked.connect(std::bind(&MapEditorState::slotCursorRightClicked, this, std::placeholders::_1));
}

EGameStateId MapEditorState::update()
{
	if(_backToMainMenu)
		return EGameStateId::EGSID_MAIN_MENU_STATE;

	if(_toDeployment)
		return EGameStateId::EGSID_DEPLOY_STATE;

	return EGameStateId::EGSID_NO_CHANGE;
}

bool MapEditorState::handleEvent(sf::Event& event)
{
	bool stopEventPropagation = SceneState::handleEvent(event);

	return stopEventPropagation;
}

Board::Ptr MapEditorState::getBoard() const
{
	return _spBoard;
}

void MapEditorState::slotCursorLeftClicked(const Coordinates& boardPosition)
{
	// Do nothing if no terrain type was selected
	if(_activeTerrainType == ET_NUMBEROFTERRAINTYPES)
		return;

	// Create new terrain
	Terrain::Ptr terrain = Terrain::createTerrain(_activeTerrainType);
	if(terrain != nullptr)
	{
		_spBoard->getSquare(boardPosition)->setTerrain(terrain);
		_scene->addTerrainEntity(TerrainEntity::createTerrainEntity(terrain, 32));
	}
}

void MapEditorState::slotCursorRightClicked(const Coordinates& boardPosition)
{
	_spBoard->getSquare(boardPosition)->setTerrain(nullptr);
	_scene->removeTerrainEntityAt(boardPosition);
}

void MapEditorState::slotTerrainButtonChanged(const namelessgui::RadioToggleButton& activeTerrainButton)
{
	const std::string& terrainString = activeTerrainButton.getText();

	if(terrainString == "Wood")
		_activeTerrainType = ET_WOOD;
	else if(terrainString == "Hill")
		_activeTerrainType = ET_HILL;
	else if(terrainString == "Wall")
		_activeTerrainType = ET_WALL;
	else
		_activeTerrainType = ET_NUMBEROFTERRAINTYPES;
}

void MapEditorState::slotToDeploymentButtonClicked()
{
	_toDeployment = true;
}

} // namespace qrw
<|endoftext|>


<commit_before>#include <QMetaOrm/QormExceptions.h>

#include <QMetaOrm/QormSqlQueryBuilder.h>
#include "QormDefaultSession.h"
#include "QormEntityMapper.h"

#include <QSqlQuery>
#include <QUuid>

class QormOnDemandRecordMapperImpl : public QormOnDemandRecordMapper {
public:
    QormOnDemandRecordMapperImpl(
        std::function<QSharedPointer<QObject>(const QormMetaEntity::Ptr&, const QString&)> callback)
        :m_callback(callback)
    {
    }

    virtual QSharedPointer<QObject>
    mapToEntity(const QormMetaEntity::Ptr& mapping, const QString& prefix) const override
    {
        return m_callback(mapping, prefix);
    }

private:
    std::function<QSharedPointer<QObject>(const QormMetaEntity::Ptr&, const QString&)> m_callback;
};

QString GetThreadIdentifier()
{
    return QUuid::createUuid().toString();
}

QormDefaultSession::QormDefaultSession(const QormDatabaseFactory::Ptr& databaseFactory, const QormLogger::Ptr& logger)
    : m_database(databaseFactory->createDatabase(GetThreadIdentifier()))
     , m_entityMapper(QormEntityMapper::Ptr(new QormEntityMapper(logger)))
     , m_entitySqlBuilder(databaseFactory->createSqlQueryBuilder())
{
}

QormDefaultSession::~QormDefaultSession()
{
    rollback();
}

void QormDefaultSession::commit()
{
    m_database.commit();
}

void QormDefaultSession::rollback()
{
    m_database.rollback();
}

void QormDefaultSession::setupSession()
{
    if (!m_database.isOpen() && !m_database.open())
        throw QormConnectToDatabaseException(m_database.lastError());

    m_database.transaction();
}

QSharedPointer<QObject> QormDefaultSession::save(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();
    return mapping->hasValidKey(entity) ?
           update(entity, mapping) :
           create(entity, mapping);
}

void QormDefaultSession::save(const QormSql& sqlQuery)
{
    remove(sqlQuery);
}

void QormDefaultSession::remove(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();
    Q_ASSERT_X(mapping->hasValidKey(entity), "remove", "entity has no valid key, removing not possible.");

    QSqlQuery query(m_database);

    if (!query.prepare(m_entitySqlBuilder->buildRemove(mapping)))
        throw QormCouldNotPrepareQueryException(query.lastError());

    query.bindValue(0, mapping->getProperty(entity, mapping->getKeyProperty()));

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());
}

void QormDefaultSession::remove(const QormSql& sqlQuery)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());
}

QSharedPointer<QObject> QormDefaultSession::create(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();

    QSqlQuery query(m_database);
    auto result = entity;

    QStringList properties;
    auto keyStrategy = mapping->getKeyGenerationStrategy();

    if (keyStrategy==KeyGenerationStrategy::Sequence) {
        QSqlQuery keyQuery(m_database);
        if (!keyQuery.exec(m_entitySqlBuilder->buildSequenceSelect(mapping)))
            throw QormCouldNotQueryNextSequenceValueException(query.lastError());

        if (!keyQuery.first())
            throw QormCouldNotQueryNextSequenceValueException(query.lastError());

        mapping->setProperty(result, mapping->getKeyProperty(), keyQuery.value(0));

        if (!query.prepare(m_entitySqlBuilder->buildInsertForSequence(mapping, properties)))
            throw QormCouldNotPrepareQueryException(query.lastError());
    }
    else if (keyStrategy==KeyGenerationStrategy::Identity) {
        if (!query.prepare(m_entitySqlBuilder->buildInsertForIdentity(mapping, properties)))
            throw QormCouldNotPrepareQueryException(query.lastError());
    }
    else
        Q_ASSERT(false);

    query.bindValue(0, mapping->getFlatPropertyValue(entity, mapping->getKeyProperty()));
    for (int propertyIndex = 0; propertyIndex < properties.size(); ++propertyIndex)
    {
        auto boundedValueIndex = propertyIndex + 1;
        query.bindValue(boundedValueIndex, mapping->getFlatPropertyValue(entity, properties[propertyIndex]));
    }

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    if (keyStrategy==KeyGenerationStrategy::Identity)
        mapping->setProperty(result, mapping->getKeyProperty(), query.lastInsertId());

    if (query.first())
        mapping->setProperty(result, mapping->getKeyProperty(), query.value(0));
    return result;
}

QSharedPointer<QObject> QormDefaultSession::update(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();

    QSqlQuery query(m_database);

    QStringList properties;

    if (!query.prepare(m_entitySqlBuilder->buildUpdate(mapping, properties)))
        throw QormCouldNotPrepareQueryException(query.lastError());

    for (int i = 0; i<properties.size(); i++)
        query.bindValue(i, mapping->getFlatPropertyValue(entity, properties[i]));
    query.bindValue(properties.size(), mapping->getProperty(entity, mapping->getKeyProperty()));

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    return entity;
}

QSharedPointer<QObject> QormDefaultSession::selectOne(const QVariant& key, QormMetaEntity::Ptr mapping)
{
    return selectOne(QormSql(m_entitySqlBuilder->buildSelect(mapping), QVariantList() << key), mapping);
}

QSharedPointer<QObject> QormDefaultSession::selectOne(const QormSql& sqlQuery, QormMetaEntity::Ptr mapping)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    auto result = query.next() ?
                  m_entityMapper->mapToEntity(mapping, query.record()) :
                  QSharedPointer<QObject>();

    if (query.next())
        throw QormMoreThanOneResultException();

    return result;
}

void QormDefaultSession::selectMany(
    QormMetaEntity::Ptr mapping,
    std::function<bool(const QSharedPointer<QObject>&)> callback,
    int skip,
    int pageSize)
{
    QVariantList conditions;
    auto sql = m_entitySqlBuilder->buildSelectMany(mapping, skip, pageSize, conditions);
    selectMany(
        QormSql(sql, conditions),
        mapping,
        callback);
}

void QormDefaultSession::selectMany(
    const QormSql& sqlQuery,
    QormMetaEntity::Ptr mapping,
    std::function<bool(const QSharedPointer<QObject>&)> callback)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    bool continueWork = true;
    while (query.next() && continueWork)
        continueWork = callback(m_entityMapper->mapToEntity(mapping, query.record()));
}

QList<QSharedPointer<QObject>> QormDefaultSession::selectMany(QormMetaEntity::Ptr mapping, int skip, int pageSize)
{
    QList<QSharedPointer<QObject>> result;
    auto func = [&result](const QSharedPointer<QObject>& item) -> bool {
        result.append(item);
        return true;
    };
    selectMany(mapping, func, skip, pageSize);
    return result;
}

QList<QSharedPointer<QObject>> QormDefaultSession::selectMany(const QormSql& sqlQuery, QormMetaEntity::Ptr mapping)
{
    QList<QSharedPointer<QObject>> result;
    auto func = [&result](const QSharedPointer<QObject>& item) -> bool {
        result.append(item);
        return true;
    };
    selectMany(sqlQuery, mapping, func);
    return result;
}

void QormDefaultSession::selectManyWithCustomMapping(
    const QormSql& sqlQuery,
    std::function<bool(const QormOnDemandRecordMapper*)> callback)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    QormOnDemandRecordMapperImpl recordMapper([&](const QormMetaEntity::Ptr& mapping, const QString& prefix) {
        return m_entityMapper->mapToEntity(mapping, query.record(), prefix);
    });

    bool continueWork = true;
    while (query.next() && continueWork)
        continueWork = callback(&recordMapper);
}
<commit_msg>Bugfix: Id value must not be bound within create statements for identitiy-based key generation<commit_after>#include <QMetaOrm/QormExceptions.h>

#include <QMetaOrm/QormSqlQueryBuilder.h>
#include "QormDefaultSession.h"
#include "QormEntityMapper.h"

#include <QSqlQuery>
#include <QUuid>

class QormOnDemandRecordMapperImpl : public QormOnDemandRecordMapper {
public:
    QormOnDemandRecordMapperImpl(
        std::function<QSharedPointer<QObject>(const QormMetaEntity::Ptr&, const QString&)> callback)
        :m_callback(callback)
    {
    }

    virtual QSharedPointer<QObject>
    mapToEntity(const QormMetaEntity::Ptr& mapping, const QString& prefix) const override
    {
        return m_callback(mapping, prefix);
    }

private:
    std::function<QSharedPointer<QObject>(const QormMetaEntity::Ptr&, const QString&)> m_callback;
};

QString GetThreadIdentifier()
{
    return QUuid::createUuid().toString();
}

QormDefaultSession::QormDefaultSession(const QormDatabaseFactory::Ptr& databaseFactory, const QormLogger::Ptr& logger)
    : m_database(databaseFactory->createDatabase(GetThreadIdentifier()))
     , m_entityMapper(QormEntityMapper::Ptr(new QormEntityMapper(logger)))
     , m_entitySqlBuilder(databaseFactory->createSqlQueryBuilder())
{
}

QormDefaultSession::~QormDefaultSession()
{
    rollback();
}

void QormDefaultSession::commit()
{
    m_database.commit();
}

void QormDefaultSession::rollback()
{
    m_database.rollback();
}

void QormDefaultSession::setupSession()
{
    if (!m_database.isOpen() && !m_database.open())
        throw QormConnectToDatabaseException(m_database.lastError());

    m_database.transaction();
}

QSharedPointer<QObject> QormDefaultSession::save(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();
    return mapping->hasValidKey(entity) ?
           update(entity, mapping) :
           create(entity, mapping);
}

void QormDefaultSession::save(const QormSql& sqlQuery)
{
    remove(sqlQuery);
}

void QormDefaultSession::remove(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();
    Q_ASSERT_X(mapping->hasValidKey(entity), "remove", "entity has no valid key, removing not possible.");

    QSqlQuery query(m_database);

    if (!query.prepare(m_entitySqlBuilder->buildRemove(mapping)))
        throw QormCouldNotPrepareQueryException(query.lastError());

    query.bindValue(0, mapping->getProperty(entity, mapping->getKeyProperty()));

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());
}

void QormDefaultSession::remove(const QormSql& sqlQuery)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());
}

QSharedPointer<QObject> QormDefaultSession::create(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();

    QSqlQuery query(m_database);
    auto result = entity;

    QStringList properties;
    auto keyStrategy = mapping->getKeyGenerationStrategy();

    if (keyStrategy==KeyGenerationStrategy::Sequence) {
        QSqlQuery keyQuery(m_database);
        if (!keyQuery.exec(m_entitySqlBuilder->buildSequenceSelect(mapping)))
            throw QormCouldNotQueryNextSequenceValueException(query.lastError());

        if (!keyQuery.first())
            throw QormCouldNotQueryNextSequenceValueException(query.lastError());

        mapping->setProperty(result, mapping->getKeyProperty(), keyQuery.value(0));

        if (!query.prepare(m_entitySqlBuilder->buildInsertForSequence(mapping, properties)))
            throw QormCouldNotPrepareQueryException(query.lastError());
    }
    else if (keyStrategy==KeyGenerationStrategy::Identity) {
        if (!query.prepare(m_entitySqlBuilder->buildInsertForIdentity(mapping, properties)))
            throw QormCouldNotPrepareQueryException(query.lastError());
    }
    else
        Q_ASSERT(false);

    auto boundedValueIndex = 0;
    if (keyStrategy == KeyGenerationStrategy::Sequence)
    {
        query.bindValue(boundedValueIndex, mapping->getFlatPropertyValue(entity, mapping->getKeyProperty()));
        ++boundedValueIndex;
    }
    for (int propertyIndex = 0; propertyIndex < properties.size(); ++propertyIndex, ++boundedValueIndex)
        query.bindValue(boundedValueIndex, mapping->getFlatPropertyValue(entity, properties[propertyIndex]));

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    if (keyStrategy==KeyGenerationStrategy::Identity)
        mapping->setProperty(result, mapping->getKeyProperty(), query.lastInsertId());

    if (query.first())
        mapping->setProperty(result, mapping->getKeyProperty(), query.value(0));
    return result;
}

QSharedPointer<QObject> QormDefaultSession::update(const QSharedPointer<QObject>& entity, QormMetaEntity::Ptr mapping)
{
    setupSession();

    QSqlQuery query(m_database);

    QStringList properties;

    if (!query.prepare(m_entitySqlBuilder->buildUpdate(mapping, properties)))
        throw QormCouldNotPrepareQueryException(query.lastError());

    for (int i = 0; i<properties.size(); i++)
        query.bindValue(i, mapping->getFlatPropertyValue(entity, properties[i]));
    query.bindValue(properties.size(), mapping->getProperty(entity, mapping->getKeyProperty()));

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    return entity;
}

QSharedPointer<QObject> QormDefaultSession::selectOne(const QVariant& key, QormMetaEntity::Ptr mapping)
{
    return selectOne(QormSql(m_entitySqlBuilder->buildSelect(mapping), QVariantList() << key), mapping);
}

QSharedPointer<QObject> QormDefaultSession::selectOne(const QormSql& sqlQuery, QormMetaEntity::Ptr mapping)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    auto result = query.next() ?
                  m_entityMapper->mapToEntity(mapping, query.record()) :
                  QSharedPointer<QObject>();

    if (query.next())
        throw QormMoreThanOneResultException();

    return result;
}

void QormDefaultSession::selectMany(
    QormMetaEntity::Ptr mapping,
    std::function<bool(const QSharedPointer<QObject>&)> callback,
    int skip,
    int pageSize)
{
    QVariantList conditions;
    auto sql = m_entitySqlBuilder->buildSelectMany(mapping, skip, pageSize, conditions);
    selectMany(
        QormSql(sql, conditions),
        mapping,
        callback);
}

void QormDefaultSession::selectMany(
    const QormSql& sqlQuery,
    QormMetaEntity::Ptr mapping,
    std::function<bool(const QSharedPointer<QObject>&)> callback)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    bool continueWork = true;
    while (query.next() && continueWork)
        continueWork = callback(m_entityMapper->mapToEntity(mapping, query.record()));
}

QList<QSharedPointer<QObject>> QormDefaultSession::selectMany(QormMetaEntity::Ptr mapping, int skip, int pageSize)
{
    QList<QSharedPointer<QObject>> result;
    auto func = [&result](const QSharedPointer<QObject>& item) -> bool {
        result.append(item);
        return true;
    };
    selectMany(mapping, func, skip, pageSize);
    return result;
}

QList<QSharedPointer<QObject>> QormDefaultSession::selectMany(const QormSql& sqlQuery, QormMetaEntity::Ptr mapping)
{
    QList<QSharedPointer<QObject>> result;
    auto func = [&result](const QSharedPointer<QObject>& item) -> bool {
        result.append(item);
        return true;
    };
    selectMany(sqlQuery, mapping, func);
    return result;
}

void QormDefaultSession::selectManyWithCustomMapping(
    const QormSql& sqlQuery,
    std::function<bool(const QormOnDemandRecordMapper*)> callback)
{
    setupSession();

    QSqlQuery query(m_database);

    if (!query.prepare(sqlQuery.sql))
        throw QormCouldNotPrepareQueryException(query.lastError());

    auto parameters = sqlQuery.parameters;
    for (int i = 0; i<parameters.size(); i++)
        query.bindValue(i, parameters[i]);

    if (!query.exec())
        throw QormCouldNotExecuteQueryException(query.lastError());

    QormOnDemandRecordMapperImpl recordMapper([&](const QormMetaEntity::Ptr& mapping, const QString& prefix) {
        return m_entityMapper->mapToEntity(mapping, query.record(), prefix);
    });

    bool continueWork = true;
    while (query.next() && continueWork)
        continueWork = callback(&recordMapper);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of signon
 *
 * Copyright (C) 2009-2010 Nokia Corporation.
 *
 * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
 * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <QBuffer>
#include <QDBusConnection>
#include <QDBusConnectionInterface>

#include "accesscontrolmanager.h"
#include "signond-common.h"
#include "credentialsaccessmanager.h"
#include "signonidentity.h"

#define SSO_AEGIS_PACKAGE_ID_TOKEN_PREFIX QLatin1String("AID::")
#define SSO_DEFAULT_CREDS_STR_BUFFER_SIZE 256

#ifdef SIGNON_DISABLE_ACCESS_CONTROL
#define RETURN_IF_AC_DISABLED(val)  return (val)
#else
#define RETURN_IF_AC_DISABLED(val)
#endif

namespace SignonDaemonNS {

    static const char keychainToken[] = "signond::keychain-access";

    bool AccessControlManager::isPeerAllowedToUseIdentity(const QDBusContext &peerContext,
                                                          const quint32 identityId)
    {
        RETURN_IF_AC_DISABLED(true);

        // TODO - improve this, the error handling and more precise behaviour

        CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
        if (db == 0) {
            TRACE() << "NULL db pointer, secure storage might be unavailable,";
            return false;
        }
        QStringList acl = db->accessControlList(identityId);

        TRACE() << QString(QLatin1String("Access control list of identity: "
                                         "%1: [%2].Tokens count: %3\t"))
            .arg(identityId)
            .arg(acl.join(QLatin1String(", ")))
            .arg(acl.size());

        if (db->errorOccurred())
            return false;

        if (acl.isEmpty())
            return true;

        return peerHasOneOfTokens(peerContext, acl);
    }

    AccessControlManager::IdentityOwnership AccessControlManager::isPeerOwnerOfIdentity(
                                                                       const QDBusContext &peerContext,
                                                                       const quint32 identityId)
    {
        RETURN_IF_AC_DISABLED(ApplicationIsOwner);

        CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
        if (db == 0) {
            TRACE() << "NULL db pointer, secure storage might be unavailable,";
            return ApplicationIsNotOwner;
        }
        QString ownerToken = db->credentialsOwnerSecurityToken(identityId);

        if (db->errorOccurred())
            return ApplicationIsNotOwner;

        if (!ownerToken.isNull())
            return IdentityDoesNotHaveOwner;

        QStringList acl = accessTokens(peerContext);
        return acl.contains(ownerToken) ? ApplicationIsOwner : ApplicationIsNotOwner;
    }

    bool AccessControlManager::isPeerKeychainWidget(const QDBusContext &peerContext)
    {
        RETURN_IF_AC_DISABLED(true);

        static QString keychainWidgetToken = QLatin1String(keychainToken);
        return peerHasToken(peerContext, keychainWidgetToken);
    }

    QString AccessControlManager::idTokenOfPeer(const QDBusContext &peerContext)
    {
        RETURN_IF_AC_DISABLED(QString());

        QStringList peerTokens = accessTokens(peerContext);
        foreach(QString token, peerTokens) {
            if (token.startsWith(SSO_AEGIS_PACKAGE_ID_TOKEN_PREFIX))
                return token;
        }
        return QString();
    }

    QString AccessControlManager::idTokenOfPid(pid_t pid)
    {
        RETURN_IF_AC_DISABLED(QString());

        QStringList peerTokens = accessTokens(pid);
        foreach(QString token, peerTokens) {
            if (token.startsWith(SSO_AEGIS_PACKAGE_ID_TOKEN_PREFIX))
                return token;
        }
        return QString();
    }

    bool AccessControlManager::peerHasOneOfTokens(const QDBusContext &peerContext,
                                                  const QStringList &tokens)
    {
        QStringList peerTokens = accessTokens(peerContext);

        TRACE() << peerTokens << " vs. " << tokens;

        foreach(QString token, tokens)
            if (peerTokens.contains(token))
                return true;

        BLAME() << "given peer does not have needed permissions";

        /*
         * TODO: remove this later, as soon as NB#196033 will be resolved
         * */
        if (1)
            return true;

        return false;
    }

    QStringList AccessControlManager::accessTokens(const pid_t peerPid)
    {
        creds_t ccreds = creds_gettask(peerPid);

        creds_value_t value;
        creds_type_t type;
        QStringList tokens;

        char buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE];
        for (int i = 0; (type = creds_list(ccreds, i,  &value)) != CREDS_BAD; ++i) {
            long actualSize = creds_creds2str(type, value, buf, SSO_DEFAULT_CREDS_STR_BUFFER_SIZE);

            if (actualSize >= SSO_DEFAULT_CREDS_STR_BUFFER_SIZE) {
                qWarning() << "Size limit exceeded for aegis token as string.";
                buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE-1] = 0;
            } else {
                buf[actualSize] = 0;
            }

            tokens << QString(QString::fromLatin1(buf));
        }

        creds_free(ccreds);
        return tokens;
    }

    QStringList AccessControlManager::accessTokens(const QDBusContext &peerContext)
    {
        return accessTokens(pidOfPeer(peerContext));
    }

    bool AccessControlManager::peerHasToken(const QDBusContext &context, const QString &token)
    {
        return peerHasToken(pidOfPeer(context), token);
    }

    bool AccessControlManager::peerHasToken(const pid_t processPid, const QString &token)
    {
        creds_type_t require_type;
        creds_value_t require_value;
        creds_t ccreds;

        /* Translate credential string into binary */
        require_type = creds_str2creds(token.toUtf8().data(), &require_value);
        if (require_type == CREDS_BAD) {
            TRACE() << "The string " << token << " does not translate into credentials value";
            return false;
        }

        ccreds = creds_gettask(processPid);
        bool hasAccess = creds_have_p(ccreds, require_type, require_value);

        TRACE() << "Process ACCESS:" << (hasAccess ? "TRUE" : "FALSE");
        creds_free(ccreds);

        return hasAccess;
    }

    pid_t AccessControlManager::pidOfPeer(const QDBusContext &peerContext)
    {
        QString service = peerContext.message().service();
        return peerContext.connection().interface()->servicePid(service).value();
    }

    void AccessControlManager::listCredentials(QIODevice *device, creds_t creds, const QString &ownerInfo)
    {
        //TODO - this method will have to disappear at some point.
        if (!device)
            return;

        if (!device->isOpen())
            device->open(QIODevice::WriteOnly);

        device->reset();

        if (!ownerInfo.isNull())
           device->write(ownerInfo.toUtf8().data(), strlen(ownerInfo.toUtf8().data()));

        creds_value_t value;
        creds_type_t type;

        device->write("\n");

        char buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE];
        for (int i = 0; (type = creds_list(creds, i,  &value)) != CREDS_BAD; ++i) {
            long actualSize = creds_creds2str(type, value, buf, SSO_DEFAULT_CREDS_STR_BUFFER_SIZE);

            if (actualSize >= SSO_DEFAULT_CREDS_STR_BUFFER_SIZE) {
                qWarning() << "Size limit exceeded for aegis token as string.";
                buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE-1] = 0;
            } else {
                buf[actualSize] = 0;
            }

            device->write("\t");
            device->write(buf, strlen(buf));
            device->write("\n");
        }
        device->write("\n");
        device->close();
    }
} //namespace SignonDaemonNS
<commit_msg>Corrected logic of checking ownerToken<commit_after>/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of signon
 *
 * Copyright (C) 2009-2010 Nokia Corporation.
 *
 * Contact: Aurel Popirtac <ext-aurel.popirtac@nokia.com>
 * Contact: Alberto Mardegan <alberto.mardegan@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 */

#include <QBuffer>
#include <QDBusConnection>
#include <QDBusConnectionInterface>

#include "accesscontrolmanager.h"
#include "signond-common.h"
#include "credentialsaccessmanager.h"
#include "signonidentity.h"

#define SSO_AEGIS_PACKAGE_ID_TOKEN_PREFIX QLatin1String("AID::")
#define SSO_DEFAULT_CREDS_STR_BUFFER_SIZE 256

#ifdef SIGNON_DISABLE_ACCESS_CONTROL
#define RETURN_IF_AC_DISABLED(val)  return (val)
#else
#define RETURN_IF_AC_DISABLED(val)
#endif

namespace SignonDaemonNS {

    static const char keychainToken[] = "signond::keychain-access";

    bool AccessControlManager::isPeerAllowedToUseIdentity(const QDBusContext &peerContext,
                                                          const quint32 identityId)
    {
        RETURN_IF_AC_DISABLED(true);

        // TODO - improve this, the error handling and more precise behaviour

        CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
        if (db == 0) {
            TRACE() << "NULL db pointer, secure storage might be unavailable,";
            return false;
        }
        QStringList acl = db->accessControlList(identityId);

        TRACE() << QString(QLatin1String("Access control list of identity: "
                                         "%1: [%2].Tokens count: %3\t"))
            .arg(identityId)
            .arg(acl.join(QLatin1String(", ")))
            .arg(acl.size());

        if (db->errorOccurred())
            return false;

        if (acl.isEmpty())
            return true;

        return peerHasOneOfTokens(peerContext, acl);
    }

    AccessControlManager::IdentityOwnership AccessControlManager::isPeerOwnerOfIdentity(
                                                                       const QDBusContext &peerContext,
                                                                       const quint32 identityId)
    {
        RETURN_IF_AC_DISABLED(ApplicationIsOwner);

        CredentialsDB *db = CredentialsAccessManager::instance()->credentialsDB();
        if (db == 0) {
            TRACE() << "NULL db pointer, secure storage might be unavailable,";
            return ApplicationIsNotOwner;
        }
        QString ownerToken = db->credentialsOwnerSecurityToken(identityId);

        if (db->errorOccurred())
            return ApplicationIsNotOwner;

        if (ownerToken.isNull())
            return IdentityDoesNotHaveOwner;

        QStringList acl = accessTokens(peerContext);
        return acl.contains(ownerToken) ? ApplicationIsOwner : ApplicationIsNotOwner;
    }

    bool AccessControlManager::isPeerKeychainWidget(const QDBusContext &peerContext)
    {
        RETURN_IF_AC_DISABLED(true);

        static QString keychainWidgetToken = QLatin1String(keychainToken);
        return peerHasToken(peerContext, keychainWidgetToken);
    }

    QString AccessControlManager::idTokenOfPeer(const QDBusContext &peerContext)
    {
        RETURN_IF_AC_DISABLED(QString());

        QStringList peerTokens = accessTokens(peerContext);
        foreach(QString token, peerTokens) {
            if (token.startsWith(SSO_AEGIS_PACKAGE_ID_TOKEN_PREFIX))
                return token;
        }
        return QString();
    }

    QString AccessControlManager::idTokenOfPid(pid_t pid)
    {
        RETURN_IF_AC_DISABLED(QString());

        QStringList peerTokens = accessTokens(pid);
        foreach(QString token, peerTokens) {
            if (token.startsWith(SSO_AEGIS_PACKAGE_ID_TOKEN_PREFIX))
                return token;
        }
        return QString();
    }

    bool AccessControlManager::peerHasOneOfTokens(const QDBusContext &peerContext,
                                                  const QStringList &tokens)
    {
        QStringList peerTokens = accessTokens(peerContext);

        TRACE() << peerTokens << " vs. " << tokens;

        foreach(QString token, tokens)
            if (peerTokens.contains(token))
                return true;

        BLAME() << "given peer does not have needed permissions";

        /*
         * TODO: remove this later, as soon as NB#196033 will be resolved
         * */
        if (1)
            return true;

        return false;
    }

    QStringList AccessControlManager::accessTokens(const pid_t peerPid)
    {
        creds_t ccreds = creds_gettask(peerPid);

        creds_value_t value;
        creds_type_t type;
        QStringList tokens;

        char buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE];
        for (int i = 0; (type = creds_list(ccreds, i,  &value)) != CREDS_BAD; ++i) {
            long actualSize = creds_creds2str(type, value, buf, SSO_DEFAULT_CREDS_STR_BUFFER_SIZE);

            if (actualSize >= SSO_DEFAULT_CREDS_STR_BUFFER_SIZE) {
                qWarning() << "Size limit exceeded for aegis token as string.";
                buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE-1] = 0;
            } else {
                buf[actualSize] = 0;
            }

            tokens << QString(QString::fromLatin1(buf));
        }

        creds_free(ccreds);
        return tokens;
    }

    QStringList AccessControlManager::accessTokens(const QDBusContext &peerContext)
    {
        return accessTokens(pidOfPeer(peerContext));
    }

    bool AccessControlManager::peerHasToken(const QDBusContext &context, const QString &token)
    {
        return peerHasToken(pidOfPeer(context), token);
    }

    bool AccessControlManager::peerHasToken(const pid_t processPid, const QString &token)
    {
        creds_type_t require_type;
        creds_value_t require_value;
        creds_t ccreds;

        /* Translate credential string into binary */
        require_type = creds_str2creds(token.toUtf8().data(), &require_value);
        if (require_type == CREDS_BAD) {
            TRACE() << "The string " << token << " does not translate into credentials value";
            return false;
        }

        ccreds = creds_gettask(processPid);
        bool hasAccess = creds_have_p(ccreds, require_type, require_value);

        TRACE() << "Process ACCESS:" << (hasAccess ? "TRUE" : "FALSE");
        creds_free(ccreds);

        return hasAccess;
    }

    pid_t AccessControlManager::pidOfPeer(const QDBusContext &peerContext)
    {
        QString service = peerContext.message().service();
        return peerContext.connection().interface()->servicePid(service).value();
    }

    void AccessControlManager::listCredentials(QIODevice *device, creds_t creds, const QString &ownerInfo)
    {
        //TODO - this method will have to disappear at some point.
        if (!device)
            return;

        if (!device->isOpen())
            device->open(QIODevice::WriteOnly);

        device->reset();

        if (!ownerInfo.isNull())
           device->write(ownerInfo.toUtf8().data(), strlen(ownerInfo.toUtf8().data()));

        creds_value_t value;
        creds_type_t type;

        device->write("\n");

        char buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE];
        for (int i = 0; (type = creds_list(creds, i,  &value)) != CREDS_BAD; ++i) {
            long actualSize = creds_creds2str(type, value, buf, SSO_DEFAULT_CREDS_STR_BUFFER_SIZE);

            if (actualSize >= SSO_DEFAULT_CREDS_STR_BUFFER_SIZE) {
                qWarning() << "Size limit exceeded for aegis token as string.";
                buf[SSO_DEFAULT_CREDS_STR_BUFFER_SIZE-1] = 0;
            } else {
                buf[actualSize] = 0;
            }

            device->write("\t");
            device->write(buf, strlen(buf));
            device->write("\n");
        }
        device->write("\n");
        device->close();
    }
} //namespace SignonDaemonNS
<|endoftext|>


<commit_before>#ifdef GRAVITY
#ifdef PFFT

#include "potential_PFFT_3D.h"
#include<iostream>
#include "../io.h"

Potential_PFFT_3D::Potential_PFFT_3D( void ){}

void Potential_PFFT_3D::Initialize( Real Lx, Real Ly, Real Lz, Real x_min, Real y_min, Real z_min, int nx, int ny, int nz, int nx_real, int ny_real, int nz_real, Real dx_real, Real dy_real, Real dz_real){

  Lbox_x = Lx;
  Lbox_y = Ly;
  Lbox_z = Lz;

  xMin = x_min;
  yMin = y_min;
  zMin = z_min;

  nx_total = nx;
  ny_total = ny;
  nz_total = nz;

  nx_local = nx_real;
  ny_local = ny_real;
  nz_local = nz_real;

  dx = dx_real;
  dy = dy_real;
  dz = dz_real;

  index_0 = -1;

  n_cells_local = nx_local*ny_local*nz_local;
  n_cells_total = nx_total*ny_total*nz_total;

  chprintf( " Using Poisson Solver: PFFT\n");

  nproc_pfft = nproc;

  chprintf(" Initializing PFFT:  %d processes\n", nproc_pfft );
  pfft_init();

  chprintf( "  PFFT: L[ %f %f %f ] N_local[ %d %d %d ] dx[ %f %f %f ]\n", Lbox_x, Lbox_y, Lbox_z, nx_local, ny_local, nz_local, dx, dy, dz );

  nprocs_grid_pfft[0] = nproc_z;
  nprocs_grid_pfft[1] = nproc_y;
  nprocs_grid_pfft[2] = nproc_x;

  n_pfft[0] = nz_total;
  n_pfft[1] = ny_total;
  n_pfft[2] = nx_total;

  // /* Create 3-dimensional process grid of size np_pfft[0] x np_pfft[1] x np_pfft[2] */
  pfft_create_procmesh(3, MPI_COMM_WORLD, nprocs_grid_pfft, &comm_pfft);
  MPI_Comm_rank( comm_pfft, &procID_pfft );
  MPI_Cart_coords( comm_pfft, procID_pfft, 3, pcoords_pfft);

  /* Get parameters of data distribution */
  alloc_local = pfft_local_size_dft_r2c_3d(
      n_pfft, comm_pfft, PFFT_TRANSPOSED_OUT ,
      local_ni_pfft, local_i_start_pfft, local_ntrans_pfft, local_trans_start_pfft);

  chprintf("  PFFT process: nx:%d ny:%d nz:%d \n", nprocs_grid_pfft[2], nprocs_grid_pfft[1], nprocs_grid_pfft[0]);
  chprintf("  PFFT cells:   nx:%d ny:%d nz:%d \n", n_pfft[2], n_pfft[1], n_pfft[0]);
  chprintf("  PFFT local:   nx:%d ny:%d nz:%d \n", local_ni_pfft[2], local_ni_pfft[1], local_ni_pfft[0] );

  if ( local_ni_pfft[2] != nx_local ||  local_ni_pfft[1] != ny_local ||  local_ni_pfft[0] != nz_local ){
    std::cout << " ERROR: PFFT domain is not the same as Cholla domain\n" << std::endl;
    std::cout << " PFFT   Domain: [ " << local_ni_pfft[2] << " , " << local_ni_pfft[1] << " , " << local_ni_pfft[0] << " ]" << std::endl;
    std::cout << " Cholla Domain: [ " << nx_local << " , " << ny_local << " , " << nz_local << " ]" << std::endl;
    exit(-1);
  }

  AllocateMemory_CPU();

  chprintf( "  PFFT: Creating FFT plan...\n");
  // /* Plan parallel  FFTs */
  plan_fwd = pfft_plan_dft_r2c_3d(n_pfft, F.input, F.transform, comm_pfft,
      PFFT_FORWARD, PFFT_TRANSPOSED_OUT | PFFT_MEASURE);

  plan_bwd = pfft_plan_dft_c2r_3d(n_pfft, F.transform, F.output, comm_pfft,
      PFFT_BACKWARD, PFFT_TRANSPOSED_IN | PFFT_MEASURE);
  chprintf( "  PFFT: Computing K for Gravity Green Funtion\n");
  Get_K_for_Green_function();

  #ifdef GRAVITY_LONG_INTS
  chprintf( "  PFFT: Using Long ints for potential calculation.\n");
  #endif

  MPI_Barrier( world );
  chprintf( " PFFT Initialized Successfully. \n");
}

void Potential_PFFT_3D::AllocateMemory_CPU( void ){
  /* Allocate memory */
  F.input  = pfft_alloc_real(2*alloc_local);
  F.transform = pfft_alloc_complex(alloc_local);
  F.output = pfft_alloc_real(2*alloc_local);
  F.G = (Real *) malloc(n_cells_local*sizeof(Real));
}

void Potential_PFFT_3D::Reset( void ){
  free( F.input );
  free( F.output );
  free( F.transform );
  free( F.G );
}

void Potential_PFFT_3D::Copy_Input( Real *input_density, Real Grav_Constant, Real dens_avrg, Real current_a ){
  int i, k, j, id;
  for (k=0; k<nz_local; k++) {
    for (j=0; j<ny_local; j++) {
      for (i=0; i<nx_local; i++) {
        id = i + j*nx_local + k*nx_local*ny_local;
        #ifdef COSMOLOGY
        F.input[id] = 4 * M_PI * Grav_Constant * (input_density[id] - dens_avrg ) / current_a ;
        #else
        F.input[id] = 4 * M_PI * Grav_Constant * input_density[id] ;
        #endif //COSMOLOGY
      }
    }
  }
}

void Potential_PFFT_3D::Copy_Output( Real *output_potential ){
  int id, id_pot;
  int i, k, j;
  for (k=0; k<nz_local; k++) {
    for (j=0; j<ny_local; j++) {
      for (i=0; i<nx_local; i++) {
        id = i + j*nx_local + k*nx_local*ny_local;
        id_pot = (i+N_GHOST_POTENTIAL) + (j+N_GHOST_POTENTIAL)*(nx_local+2*N_GHOST_POTENTIAL) + (k+N_GHOST_POTENTIAL)*(nx_local+2*N_GHOST_POTENTIAL)*(ny_local+2*N_GHOST_POTENTIAL);
        output_potential[id_pot] = F.output[id] / n_cells_total;
      }
    }
  }
}

void Potential_PFFT_3D::Get_K_for_Green_function( void){
  grav_int_t m = 0;
  grav_int_t k_0, k_1, k_2;
  Real k_x, k_y, k_z, G_x, G_y, G_z, G;

  double ksqrd;
  for(ptrdiff_t k1=local_trans_start_pfft[1]; k1<local_trans_start_pfft[1]+local_ntrans_pfft[1]; k1++){
    for(ptrdiff_t k2=local_trans_start_pfft[2]; k2<local_trans_start_pfft[2]+local_ntrans_pfft[2]; k2++){
      for(ptrdiff_t k0=local_trans_start_pfft[0]; k0<local_trans_start_pfft[0]+local_ntrans_pfft[0]; k0++){
        //  printf("out[%td, %td, %td] = %.2f + I * %.2f\n", k0, k1, k2, transf[m][0],transf[m][1]);
        k_0 = k0;
        k_1 = k1;
        k_2 = k2;
        if ( k_2 >= nx_total/2) k_2 -= nx_total;
        if ( k_0 >= nz_total/2) k_0 -= nz_total;
        if ( k_1 >= ny_total/2) k_1 -= ny_total;
        k_x = 2*M_PI*k_2/nx_total;
        k_z = 2*M_PI*k_0/nz_total;
        k_y = 2*M_PI*k_1/nx_total;
        G_x = sin( k_x/2  );
        G_y = sin( k_y/2 );
        G_z = sin( k_z/2 );
        if ( k_0==0 && k_1==0 && k_2 == 0 ){
          index_0 = m ;
          G = 1;
          std::cout << "  K=0   index: " << index_0 << std::endl;
        }
        else{
          G = -1 / ( G_x*G_x + G_y*G_y + G_z*G_z ) * dx * dx /4 ;
        }
        F.G[m] = G;
        m += 1;
      }
    }
  }
}

void Potential_PFFT_3D::Get_Index_Global(int i, int j, int k, int *i_global, int *j_global, int *k_global){

  int i_g, j_g, k_g;
  i_g = xMin/dx + i;
  j_g = yMin/dy + j;
  k_g = zMin/dz + k;

  *i_global = i_g;
  *j_global = j_g;
  *k_global = k_g;
}

void Potential_PFFT_3D::Apply_K2_Funtion( void ){
  Real kx, ky, kz, k2;
  int i_g, j_g, k_g;
  int id;
  for (int k=0; k<nz_local; k++){
    for (int j=0; j<ny_local; j++){
      for ( int i=0; i<nx_local; i++){
        id = i + j*nx_local + k*nx_local*ny_local;
        Get_Index_Global( i, j, k, &i_g, &j_g, &k_g );
        if ( i_g >= nx_total/2) i_g -= nz_total;
        if ( j_g >= ny_total/2) j_g -= ny_total;
        if ( k_g >= nz_total/2) k_g -= nz_total;
        kx =  2 * M_PI * i_g / Lbox_x;
        ky =  2 * M_PI * j_g / Lbox_y;
        kz =  2 * M_PI * k_g / Lbox_z;
        if ( i_g==0 && j_g==0 && k_g== 0){
          k2=1;
        }
        else{
          k2  =  kx*kx + ky*ky + kz*kz ;
        }

        F.transform[id][0] *= -1/k2;
        F.transform[id][1] *= -1/k2;
      }
    }
  }
  if (index_0 > -1){
    F.transform[index_0][0] = 0;
    F.transform[index_0][1] = 0;
  }
}

void Potential_PFFT_3D::Apply_G_Funtion( void ){
  Real G_val;
  for ( int i=0; i<n_cells_local; i++ ){
    G_val = F.G[i];
    F.transform[i][0] *= G_val;
    F.transform[i][1] *= G_val;
  }
  if (index_0 > -1){
    F.transform[index_0][0] = 0;
    F.transform[index_0][1] = 0;
  }
}

Real Potential_PFFT_3D::Get_Potential( Real *input_density,  Real *output_potential, Real Grav_Constant, Real dens_avrg, Real current_a ){

  Copy_Input( input_density, Grav_Constant, dens_avrg, current_a );

  pfft_execute( plan_fwd );
  Apply_G_Funtion();
  // Apply_K2_Funtion();
  pfft_execute( plan_bwd );
  Copy_Output( output_potential );

  return 0;
}

#endif //PFFT
#endif //GRAVITY<commit_msg>added OMP pragmas to PFFT potential ( didn't see a permermance increase )<commit_after>#ifdef GRAVITY
#ifdef PFFT

#include "potential_PFFT_3D.h"
#include<iostream>
#include "../io.h"

Potential_PFFT_3D::Potential_PFFT_3D( void ){}

void Potential_PFFT_3D::Initialize( Real Lx, Real Ly, Real Lz, Real x_min, Real y_min, Real z_min, int nx, int ny, int nz, int nx_real, int ny_real, int nz_real, Real dx_real, Real dy_real, Real dz_real){

  Lbox_x = Lx;
  Lbox_y = Ly;
  Lbox_z = Lz;

  xMin = x_min;
  yMin = y_min;
  zMin = z_min;

  nx_total = nx;
  ny_total = ny;
  nz_total = nz;

  nx_local = nx_real;
  ny_local = ny_real;
  nz_local = nz_real;

  dx = dx_real;
  dy = dy_real;
  dz = dz_real;

  index_0 = -1;

  n_cells_local = nx_local*ny_local*nz_local;
  n_cells_total = nx_total*ny_total*nz_total;

  chprintf( " Using Poisson Solver: PFFT\n");

  nproc_pfft = nproc;

  chprintf(" Initializing PFFT:  %d processes\n", nproc_pfft );
  pfft_init();

  chprintf( "  PFFT: L[ %f %f %f ] N_local[ %d %d %d ] dx[ %f %f %f ]\n", Lbox_x, Lbox_y, Lbox_z, nx_local, ny_local, nz_local, dx, dy, dz );

  nprocs_grid_pfft[0] = nproc_z;
  nprocs_grid_pfft[1] = nproc_y;
  nprocs_grid_pfft[2] = nproc_x;

  n_pfft[0] = nz_total;
  n_pfft[1] = ny_total;
  n_pfft[2] = nx_total;

  // /* Create 3-dimensional process grid of size np_pfft[0] x np_pfft[1] x np_pfft[2] */
  pfft_create_procmesh(3, MPI_COMM_WORLD, nprocs_grid_pfft, &comm_pfft);
  MPI_Comm_rank( comm_pfft, &procID_pfft );
  MPI_Cart_coords( comm_pfft, procID_pfft, 3, pcoords_pfft);

  /* Get parameters of data distribution */
  alloc_local = pfft_local_size_dft_r2c_3d(
      n_pfft, comm_pfft, PFFT_TRANSPOSED_OUT ,
      local_ni_pfft, local_i_start_pfft, local_ntrans_pfft, local_trans_start_pfft);

  chprintf("  PFFT process: nx:%d ny:%d nz:%d \n", nprocs_grid_pfft[2], nprocs_grid_pfft[1], nprocs_grid_pfft[0]);
  chprintf("  PFFT cells:   nx:%d ny:%d nz:%d \n", n_pfft[2], n_pfft[1], n_pfft[0]);
  chprintf("  PFFT local:   nx:%d ny:%d nz:%d \n", local_ni_pfft[2], local_ni_pfft[1], local_ni_pfft[0] );

  if ( local_ni_pfft[2] != nx_local ||  local_ni_pfft[1] != ny_local ||  local_ni_pfft[0] != nz_local ){
    std::cout << " ERROR: PFFT domain is not the same as Cholla domain\n" << std::endl;
    std::cout << " PFFT   Domain: [ " << local_ni_pfft[2] << " , " << local_ni_pfft[1] << " , " << local_ni_pfft[0] << " ]" << std::endl;
    std::cout << " Cholla Domain: [ " << nx_local << " , " << ny_local << " , " << nz_local << " ]" << std::endl;
    exit(-1);
  }

  AllocateMemory_CPU();

  chprintf( "  PFFT: Creating FFT plan...\n");
  // /* Plan parallel  FFTs */
  plan_fwd = pfft_plan_dft_r2c_3d(n_pfft, F.input, F.transform, comm_pfft,
      PFFT_FORWARD, PFFT_TRANSPOSED_OUT | PFFT_MEASURE);

  plan_bwd = pfft_plan_dft_c2r_3d(n_pfft, F.transform, F.output, comm_pfft,
      PFFT_BACKWARD, PFFT_TRANSPOSED_IN | PFFT_MEASURE);
  chprintf( "  PFFT: Computing K for Gravity Green Funtion\n");
  Get_K_for_Green_function();

  #ifdef GRAVITY_LONG_INTS
  chprintf( "  PFFT: Using Long ints for potential calculation.\n");
  #endif

  MPI_Barrier( world );
  chprintf( " PFFT Initialized Successfully. \n");
}

void Potential_PFFT_3D::AllocateMemory_CPU( void ){
  /* Allocate memory */
  F.input  = pfft_alloc_real(2*alloc_local);
  F.transform = pfft_alloc_complex(alloc_local);
  F.output = pfft_alloc_real(2*alloc_local);
  F.G = (Real *) malloc(n_cells_local*sizeof(Real));
}

void Potential_PFFT_3D::Reset( void ){
  free( F.input );
  free( F.output );
  free( F.transform );
  free( F.G );
}

void Potential_PFFT_3D::Copy_Input( Real *input_density, Real Grav_Constant, Real dens_avrg, Real current_a ){
  int i, k, j, id;

  // #ifdef PARALLEL_OMP
  // #pragma omp parallel for num_threads(N_OMP_THREADS)
  // #endif
  for (k=0; k<nz_local; k++) {
    for (j=0; j<ny_local; j++) {
      for (i=0; i<nx_local; i++) {
        id = i + j*nx_local + k*nx_local*ny_local;
        #ifdef COSMOLOGY
        F.input[id] = 4 * M_PI * Grav_Constant * (input_density[id] - dens_avrg ) / current_a ;
        #else
        F.input[id] = 4 * M_PI * Grav_Constant * input_density[id] ;
        #endif //COSMOLOGY
      }
    }
  }
}

void Potential_PFFT_3D::Copy_Output( Real *output_potential ){
  int id, id_pot;
  int i, k, j;

  // #ifdef PARALLEL_OMP
  // #pragma omp parallel for num_threads(N_OMP_THREADS)
  // #endif
  for (k=0; k<nz_local; k++) {
    for (j=0; j<ny_local; j++) {
      for (i=0; i<nx_local; i++) {
        id = i + j*nx_local + k*nx_local*ny_local;
        id_pot = (i+N_GHOST_POTENTIAL) + (j+N_GHOST_POTENTIAL)*(nx_local+2*N_GHOST_POTENTIAL) + (k+N_GHOST_POTENTIAL)*(nx_local+2*N_GHOST_POTENTIAL)*(ny_local+2*N_GHOST_POTENTIAL);
        output_potential[id_pot] = F.output[id] / n_cells_total;
      }
    }
  }
}

void Potential_PFFT_3D::Get_K_for_Green_function( void){
  grav_int_t m = 0;
  grav_int_t k_0, k_1, k_2;
  Real k_x, k_y, k_z, G_x, G_y, G_z, G;

  double ksqrd;
  for(ptrdiff_t k1=local_trans_start_pfft[1]; k1<local_trans_start_pfft[1]+local_ntrans_pfft[1]; k1++){
    for(ptrdiff_t k2=local_trans_start_pfft[2]; k2<local_trans_start_pfft[2]+local_ntrans_pfft[2]; k2++){
      for(ptrdiff_t k0=local_trans_start_pfft[0]; k0<local_trans_start_pfft[0]+local_ntrans_pfft[0]; k0++){
        //  printf("out[%td, %td, %td] = %.2f + I * %.2f\n", k0, k1, k2, transf[m][0],transf[m][1]);
        k_0 = k0;
        k_1 = k1;
        k_2 = k2;
        if ( k_2 >= nx_total/2) k_2 -= nx_total;
        if ( k_0 >= nz_total/2) k_0 -= nz_total;
        if ( k_1 >= ny_total/2) k_1 -= ny_total;
        k_x = 2*M_PI*k_2/nx_total;
        k_z = 2*M_PI*k_0/nz_total;
        k_y = 2*M_PI*k_1/nx_total;
        G_x = sin( k_x/2  );
        G_y = sin( k_y/2 );
        G_z = sin( k_z/2 );
        if ( k_0==0 && k_1==0 && k_2 == 0 ){
          index_0 = m ;
          G = 1;
          std::cout << "  K=0   index: " << index_0 << std::endl;
        }
        else{
          G = -1 / ( G_x*G_x + G_y*G_y + G_z*G_z ) * dx * dx /4 ;
        }
        F.G[m] = G;
        m += 1;
      }
    }
  }
}

void Potential_PFFT_3D::Get_Index_Global(int i, int j, int k, int *i_global, int *j_global, int *k_global){

  int i_g, j_g, k_g;
  i_g = xMin/dx + i;
  j_g = yMin/dy + j;
  k_g = zMin/dz + k;

  *i_global = i_g;
  *j_global = j_g;
  *k_global = k_g;
}

void Potential_PFFT_3D::Apply_K2_Funtion( void ){
  Real kx, ky, kz, k2;
  int i_g, j_g, k_g;
  int id;
  int k, j, i;

  // #ifdef PARALLEL_OMP
  // #pragma omp parallel for num_threads(N_OMP_THREADS)
  // #endif
  for (k=0; k<nz_local; k++){
    for (j=0; j<ny_local; j++){
      for (i=0; i<nx_local; i++){
        id = i + j*nx_local + k*nx_local*ny_local;
        Get_Index_Global( i, j, k, &i_g, &j_g, &k_g );
        if ( i_g >= nx_total/2) i_g -= nz_total;
        if ( j_g >= ny_total/2) j_g -= ny_total;
        if ( k_g >= nz_total/2) k_g -= nz_total;
        kx =  2 * M_PI * i_g / Lbox_x;
        ky =  2 * M_PI * j_g / Lbox_y;
        kz =  2 * M_PI * k_g / Lbox_z;
        if ( i_g==0 && j_g==0 && k_g== 0){
          k2=1;
        }
        else{
          k2  =  kx*kx + ky*ky + kz*kz ;
        }

        F.transform[id][0] *= -1/k2;
        F.transform[id][1] *= -1/k2;
      }
    }
  }
  if (index_0 > -1){
    F.transform[index_0][0] = 0;
    F.transform[index_0][1] = 0;
  }
}

void Potential_PFFT_3D::Apply_G_Funtion( void ){
  Real G_val;
  int i;

  // #ifdef PARALLEL_OMP
  // #pragma omp parallel for num_threads(N_OMP_THREADS)
  // #endif
  for ( i=0; i<n_cells_local; i++ ){
    G_val = F.G[i];
    F.transform[i][0] *= G_val;
    F.transform[i][1] *= G_val;
  }
  if (index_0 > -1){
    F.transform[index_0][0] = 0;
    F.transform[index_0][1] = 0;
  }
}

Real Potential_PFFT_3D::Get_Potential( Real *input_density,  Real *output_potential, Real Grav_Constant, Real dens_avrg, Real current_a ){

  Copy_Input( input_density, Grav_Constant, dens_avrg, current_a );

  pfft_execute( plan_fwd );
  Apply_G_Funtion();
  // Apply_K2_Funtion();
  pfft_execute( plan_bwd );
  Copy_Output( output_potential );

  return 0;
}

#endif //PFFT
#endif //GRAVITY<|endoftext|>


<commit_before>#include <OGL/OGLGpuBuffer.h>

std::vector<GLBufferId> OGLHgGPUBuffer::m_useableBufferIds;

GLBufferId::~GLBufferId()
{
	if (buffId > 0) {
		glDeleteBuffers(1, &buffId);
		glDeleteTextures(1, &texId);
	}
	texId = 0;
	buffId = 0;
}

void GLBufferId::AllocateOnGPU()
{
	if (texId == 0) {
		glGenBuffers(1, &buffId);
		glGenTextures(1, &texId);
	}
}

GLBufferId::GLBufferId(GLBufferId&& rhs)
{
	*this = std::move(rhs);
}

const GLBufferId& GLBufferId::operator=(GLBufferId&& rhs)
{
	this->buffId = rhs.buffId;
	this->texId = rhs.texId;

	rhs.buffId = 0;
	rhs.texId = 0;

	return *this;
}

GLBufferId OGLHgGPUBuffer::getGLBufferId()
{
	if (m_useableBufferIds.size() > 0)
	{
		auto r = std::move(m_useableBufferIds.back());
		m_useableBufferIds.pop_back();
		return r;
	}

	GLBufferId ids;
	ids.AllocateOnGPU();
	return ids;
}

void  OGLHgGPUBuffer::freeGLBufferId(GLBufferId& rhs)
{
	m_useableBufferIds.emplace_back(std::move(rhs));
}

OGLHgGPUBuffer::~OGLHgGPUBuffer()
{
	freeGLBufferId(m_bufferIds);
}

void OGLHgGPUBuffer::SendToGPU(const IHgGPUBuffer* bufferObject) {
	m_bufferIds = getGLBufferId();

	glBindBuffer(GL_TEXTURE_BUFFER, m_bufferIds.buffId);

	const size_t size = bufferObject->sizeBytes();

	if (m_lastSize < size) {
		//grow buffer and load all data
		glBufferData(GL_TEXTURE_BUFFER, size, bufferObject->getBufferPtr(), GL_DYNAMIC_DRAW);
	}
	else {
		//load all data
		glBufferSubData(GL_TEXTURE_BUFFER, 0, size, bufferObject->getBufferPtr());
	}
	m_lastSize = size;
}

void OGLHgGPUBuffer::Bind() {
	glBindTexture(GL_TEXTURE_BUFFER, m_bufferIds.texId);
	glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_bufferIds.buffId);
}<commit_msg>use swap here to gain automatic cleaup of buffId and texId<commit_after>#include <OGL/OGLGpuBuffer.h>

std::vector<GLBufferId> OGLHgGPUBuffer::m_useableBufferIds;

GLBufferId::~GLBufferId()
{
	if (buffId > 0) {
		glDeleteBuffers(1, &buffId);
		glDeleteTextures(1, &texId);
	}
	texId = 0;
	buffId = 0;
}

void GLBufferId::AllocateOnGPU()
{
	if (texId == 0) {
		glGenBuffers(1, &buffId);
		glGenTextures(1, &texId);
	}
}

GLBufferId::GLBufferId(GLBufferId&& rhs)
{
	*this = std::move(rhs);
}

const GLBufferId& GLBufferId::operator=(GLBufferId&& rhs)
{
	std::swap(buffId, rhs.buffId);
	std::swap(texId, rhs.texId);
	return *this;
}

GLBufferId OGLHgGPUBuffer::getGLBufferId()
{
	if (m_useableBufferIds.size() > 0)
	{
		auto r = std::move(m_useableBufferIds.back());
		m_useableBufferIds.pop_back();
		return r;
	}

	GLBufferId ids;
	ids.AllocateOnGPU();
	return ids;
}

void  OGLHgGPUBuffer::freeGLBufferId(GLBufferId& rhs)
{
	m_useableBufferIds.emplace_back(std::move(rhs));
}

OGLHgGPUBuffer::~OGLHgGPUBuffer()
{
	freeGLBufferId(m_bufferIds);
}

void OGLHgGPUBuffer::SendToGPU(const IHgGPUBuffer* bufferObject) {
	m_bufferIds = getGLBufferId();

	glBindBuffer(GL_TEXTURE_BUFFER, m_bufferIds.buffId);

	const size_t size = bufferObject->sizeBytes();

	if (m_lastSize < size) {
		//grow buffer and load all data
		glBufferData(GL_TEXTURE_BUFFER, size, bufferObject->getBufferPtr(), GL_DYNAMIC_DRAW);
	}
	else {
		//load all data
		glBufferSubData(GL_TEXTURE_BUFFER, 0, size, bufferObject->getBufferPtr());
	}
	m_lastSize = size;
}

void OGLHgGPUBuffer::Bind() {
	glBindTexture(GL_TEXTURE_BUFFER, m_bufferIds.texId);
	glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_bufferIds.buffId);
}<|endoftext|>