<commit_before>#include "linedetector.h"
#include <common/logger/logger.h>
#include <sstream>
#include <iostream>
#include <cstdlib>

using namespace std;
using namespace cv;

LineDetector::LineDetector()
    : max_elem(2),
      max_kernel_size(2),
      gaussian_size(7)
{
    erosion_elem = 2;
    erosion_size = 2;
    dilation_elem = 2;
    dilation_size = 1;
}

void LineDetector::onImageEvent(ImageData imgd){
    src = imgd.mat();
    dst = src.clone();
    /** Total Average of the pixels in the screen. Used to account for brightness variability. */
    float totalAvg = getAvg();

    /** Blurs the picture just a little */
    GaussianBlur(dst, dst, Size(gaussian_size,gaussian_size),2,0);
    /** Separates the pixels into black(not lines) and white (lines) */
    blackAndWhite(totalAvg);

    Erosion();
    Dilation();

    transformPoints();
    toPointCloud();

//    pcl::visualization::CloudViewer viewer ("Simple Cloud Viewer");
//    viewer.showCloud(cloud);
//    while (!viewer.wasStopped ())
//    {
//    }

    onNewLines(ImageData(transformDst));
    pcl::io::savePCDFileASCII("line_pcd.pcd", cloud);
}

void LineDetector::transformPoints(){

    int offset = 100;
    int factor = 5;
    //pcam is where the coordinates are in actual space (in inches right now)
    //pcam = (cv::Mat_<float>(4,2) << offset-12,72, offset, 72, offset, 60,offset -12, 60);
    pcam = (cv::Mat_<float>(4,2) << 4,81, -8, 81, -8, 93,4, 93);
    pcam = pcam+offset;
    //p is where they show up as pixels on the camera
    //p = (cv::Mat_<float>(4,2) << 427, 642, 515, 642, 512, 589, 432, 588);
     p= (cv::Mat_<float>(4,2) << 440, 674, 356, 679, 364, 631, 439, 627);
    //pcam = pcam*3+450; //This is just so we can see it on the screen
    //Getting the transform
    transformMat = cv::getPerspectiveTransform(p, pcam);
    //Apply the transform to dst and store result in transformDST
    cv::warpPerspective(dst, transformDst, transformMat, transformDst.size());
}

void LineDetector::toPointCloud(){
    cloud.width = transformDst.rows*transformDst.cols/2; //change later
    cloud.height = 1;
    cloud.points.resize(cloud.width*cloud.height);
    int i =0;

    //Add points to the cloud if they are white (right now only checking the first
    //layer)
    for (int r=0; r<transformDst.rows;r++){
        for (int c=0; c<transformDst.cols; c++){
            if (transformDst.at<cv::Vec3b>(r,c)[0]==255){
                cloud.points[i].x = .0245*(c-100)/2;
                cloud.points[i].y = .0245*(r-100)/2;
                cloud.points[i++].z = 1;
            }
        }
    }

    //Plots one meter long lines on x and y for scale
    for(int r=0; r<21; r++){
        cloud.points[i].x = 0;
        cloud.points[i].y = (float) r/20;
        cloud.points[i++].z = 0;
    }

    for(int r=0; r<21; r++){
        cloud.points[i].x = (float) r/20;
        cloud.points[i].y =0;
        cloud.points[i++].z = 0;
    }

}

void LineDetector::Erosion()
{
  int erosion_type;
  if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }
  else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }
  else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( erosion_type,
                                       Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                       Point( erosion_size, erosion_size ) );
  // Apply the erosion operation
  erode( dst, dst, element );
}

/** Dilation enhances the white lines */
void LineDetector::Dilation()
{
  int dilation_type;
  if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }
  else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }
  else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( dilation_type,
                                       Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       Point( dilation_size, dilation_size ) );
  // Apply the dilation operation
  dilate( dst, dst, element );

}

/**
 *  @brief LineDetector::blackAndWhite converts the image into
 *         black (not lines) and white (lines)
 *  @param totalAvg The average brightness of the picture
 */
void LineDetector::blackAndWhite(float totalAvg){
    Vec3b p;
    int rows = src.rows;
    int cols = src.cols;

    //Turn the top quarter of the screen and bottom sixth of the screen black
    //We can disregard these areas - may extend the bottom of the screen slightly later on
    for (int i = 0; i< rows/3; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
    for (int i = rows*5/6; i< rows; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }

    //Loops through relevant parts of the image and scans for white lines
    //Also tries to detect obstacles
    int tempAvg;
    for (int i = rows/3; i< rows*5/6; i++){
        for(int j=0; j< cols; j++){
            tempAvg = totalAvg*(1.1 - i*.1/768);
            p = dst.at<Vec3b>(i, j); //Current pixel

            //If there is a significant amount of red in the pixel, it's most likely an orange cone
            //Get rid of the obstacle
            if (p[2] > totalAvg*2|| p[2] > 253){
                detectObstacle(i, j);
            }
            //Filters out the white and makes it pure white
            if((p[0]>tempAvg*1.5)&& (p[0] < tempAvg*2.2)&& (p[1] < tempAvg*1.6)&&(p[2]>tempAvg*1.1) &&
                    (p[2]<tempAvg*1.7)&&(p[1]>tempAvg*1.05)&&(abs(p[1] - p[2]) <20)){
                dst.at<Vec3b>(i,j)[0] = 255;
                dst.at<Vec3b>(i,j)[1] = 255;
                dst.at<Vec3b>(i,j)[2] = 255;

            }
            else { //Otherwise, set pixel to black
                dst.at<Vec3b>(i,j)[0] = 0;
                dst.at<Vec3b>(i,j)[1] = 0;
                dst.at<Vec3b>(i,j)[2] = 0;
            }
        }
    }
}

/**
 *  \brief LineDetector::detectObstacle detects orange and bright white obstacles
 *  \param col the column of the left of the obstacle
 */
void LineDetector::detectObstacle(int row, int col){
    Vec3b p = dst.at<Vec3b>(row,col);
    int row2 = row;
    int col2 = col;

    //While the pixel is still orange, turn it black
    //Then on to the next one, by row
    while (p[2]>100){
        dst.at<Vec3b>(row2, col)[0] = 0;
        dst.at<Vec3b>(row2, col)[1] = 0;
        dst.at<Vec3b>(row2, col)[2] = 0;
        p = dst.at<Vec3b>(++row2, col);
    }
    p = dst.at<Vec3b>(row,col);

    //While the pixel is still orange, turn it black
    //Then on to the next one, by column
    while (p[2]>100){
        dst.at<Vec3b>(row, col2)[0] = 0;
        dst.at<Vec3b>(row, col2)[1] = 0;
        dst.at<Vec3b>(row, col2)[2] = 0;
        p = dst.at<Vec3b>(row, ++col2);
    }

    //Turn everything in that block we just found black
    for(int i = row+1; i<row2;i++){
        for (int j = col+1; j<col2; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

/**
 *  \brief LineDetector::getAvg gets the average of the relevant pixels
 *  \return the average as a floating point number
 */
float LineDetector::getAvg(){
    Vec3b p;
    float totalAvg = 0;
    for (int i = src.rows/3; i< 5*src.rows/6; i++){
        for(int j=src.cols/6; j< 5*src.cols/6; j++){
            p = dst.at<Vec3b>(i, j);
            totalAvg += (p[0]+p[1]+p[2])/3;
        }
    }
    totalAvg = (25*totalAvg)/(src.cols*src.rows*8);
    return totalAvg;
}

/**
 *  \brief LineDetector::blackoutSection turns a section of the image black
 *  \param rowl the lower row bound
 *  \param rowu the upper row bound
 *  \param coll the left column bound
 *  \param colu the right column bound
 */
void LineDetector::blackoutSection(int rowl, int rowu, int coll, int colu){

    for (int i=rowl;i<=rowu;i++){
        for (int j = coll; j<=colu; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

<commit_msg>Begin cleanup of line detection code.<commit_after>#include "linedetector.h"
#include <common/logger/logger.h>
#include <sstream>
#include <iostream>
#include <cstdlib>

using namespace std;
using namespace cv;

LineDetector::LineDetector()
    : max_elem(2),
      max_kernel_size(2),
      gaussian_size(7)
{
    erosion_elem = 2;
    erosion_size = 2;
    dilation_elem = 2;
    dilation_size = 1;
}

void LineDetector::onImageEvent(ImageData imgd){
    src = imgd.mat();
    dst = src.clone();
    /** Total Average of the pixels in the screen. Used to account for brightness variability. */
    float totalAvg = getAvg();

    /** Blurs the picture just a little */
    GaussianBlur(dst, dst, Size(gaussian_size,gaussian_size),2,0);
    /** Separates the pixels into black(not lines) and white (lines) */
    blackAndWhite(totalAvg);

    Erosion();
    Dilation();

    transformPoints();
    toPointCloud();

    onNewLines(ImageData(transformDst));
    onNewCloud(cloud);
}

void LineDetector::transformPoints(){

    int offset = 100;
    int factor = 5;
    //pcam is where the coordinates are in actual space (in inches right now)
    //pcam = (cv::Mat_<float>(4,2) << offset-12,72, offset, 72, offset, 60,offset -12, 60);
    pcam = (cv::Mat_<float>(4,2) << 4,81, -8, 81, -8, 93,4, 93);
    pcam = pcam+offset;
    //p is where they show up as pixels on the camera
    //p = (cv::Mat_<float>(4,2) << 427, 642, 515, 642, 512, 589, 432, 588);
     p= (cv::Mat_<float>(4,2) << 440, 674, 356, 679, 364, 631, 439, 627);
    //pcam = pcam*3+450; //This is just so we can see it on the screen
    //Getting the transform
    transformMat = cv::getPerspectiveTransform(p, pcam);
    //Apply the transform to dst and store result in transformDST
    cv::warpPerspective(dst, transformDst, transformMat, transformDst.size());
}

void LineDetector::toPointCloud(){
    cloud.width = transformDst.rows*transformDst.cols/2; //change later
    cloud.height = 1;
    cloud.points.resize(cloud.width*cloud.height);
    int i =0;

    //Add points to the cloud if they are white (right now only checking the first
    //layer)
    for (int r=0; r<transformDst.rows;r++){
        for (int c=0; c<transformDst.cols; c++){
            if (transformDst.at<cv::Vec3b>(r,c)[0]==255){
                cloud.points[i].x = .0245*(c-100)/2;
                cloud.points[i].y = .0245*(r-100)/2;
                cloud.points[i++].z = 1;
            }
        }
    }

    //Plots one meter long lines on x and y for scale
    for(int r=0; r<21; r++){
        cloud.points[i].x = 0;
        cloud.points[i].y = (float) r/20;
        cloud.points[i++].z = 0;
    }

    for(int r=0; r<21; r++){
        cloud.points[i].x = (float) r/20;
        cloud.points[i].y =0;
        cloud.points[i++].z = 0;
    }

}

void LineDetector::Erosion()
{
  int erosion_type;
  if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; }
  else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; }
  else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( erosion_type,
                                       Size( 2*erosion_size + 1, 2*erosion_size+1 ),
                                       Point( erosion_size, erosion_size ) );
  // Apply the erosion operation
  erode( dst, dst, element );
}

/** Dilation enhances the white lines */
void LineDetector::Dilation()
{
  int dilation_type;
  if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; }
  else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; }
  else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }

  Mat element = getStructuringElement( dilation_type,
                                       Size( 2*dilation_size + 1, 2*dilation_size+1 ),
                                       Point( dilation_size, dilation_size ) );
  // Apply the dilation operation
  dilate( dst, dst, element );

}

/**
 *  @brief LineDetector::blackAndWhite converts the image into
 *         black (not lines) and white (lines)
 *  @param totalAvg The average brightness of the picture
 */
void LineDetector::blackAndWhite(float totalAvg){
    Vec3b p;
    int rows = src.rows;
    int cols = src.cols;

    //Turn the top quarter of the screen and bottom sixth of the screen black
    //We can disregard these areas - may extend the bottom of the screen slightly later on
    for (int i = 0; i< rows/3; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
    for (int i = rows*5/6; i< rows; i++){
        for(int j=0; j< cols; j++){
             dst.at<Vec3b>(i,j)[0] = 0;
             dst.at<Vec3b>(i,j)[1] = 0;
             dst.at<Vec3b>(i,j)[2] = 0;
        }
    }

    //Loops through relevant parts of the image and scans for white lines
    //Also tries to detect obstacles
    int tempAvg;
    for (int i = rows/3; i< rows*5/6; i++){
        for(int j=0; j< cols; j++){
            tempAvg = totalAvg*(1.1 - i*.1/768);
            p = dst.at<Vec3b>(i, j); //Current pixel

            //If there is a significant amount of red in the pixel, it's most likely an orange cone
            //Get rid of the obstacle
            if (p[2] > totalAvg*2|| p[2] > 253){
                detectObstacle(i, j);
            }
            //Filters out the white and makes it pure white
            if((p[0]>tempAvg*1.5)&& (p[0] < tempAvg*2.2)&& (p[1] < tempAvg*1.6)&&(p[2]>tempAvg*1.1) &&
                    (p[2]<tempAvg*1.7)&&(p[1]>tempAvg*1.05)&&(abs(p[1] - p[2]) <20)){
                dst.at<Vec3b>(i,j)[0] = 255;
                dst.at<Vec3b>(i,j)[1] = 255;
                dst.at<Vec3b>(i,j)[2] = 255;

            }
            else { //Otherwise, set pixel to black
                dst.at<Vec3b>(i,j)[0] = 0;
                dst.at<Vec3b>(i,j)[1] = 0;
                dst.at<Vec3b>(i,j)[2] = 0;
            }
        }
    }
}

/**
 *  \brief LineDetector::detectObstacle detects orange and bright white obstacles
 *  \param col the column of the left of the obstacle
 */
void LineDetector::detectObstacle(int row, int col){
    Vec3b p = dst.at<Vec3b>(row,col);
    int row2 = row;
    int col2 = col;

    //While the pixel is still orange, turn it black
    //Then on to the next one, by row
    while (p[2]>100){
        dst.at<Vec3b>(row2, col)[0] = 0;
        dst.at<Vec3b>(row2, col)[1] = 0;
        dst.at<Vec3b>(row2, col)[2] = 0;
        p = dst.at<Vec3b>(++row2, col);
    }
    p = dst.at<Vec3b>(row,col);

    //While the pixel is still orange, turn it black
    //Then on to the next one, by column
    while (p[2]>100){
        dst.at<Vec3b>(row, col2)[0] = 0;
        dst.at<Vec3b>(row, col2)[1] = 0;
        dst.at<Vec3b>(row, col2)[2] = 0;
        p = dst.at<Vec3b>(row, ++col2);
    }

    //Turn everything in that block we just found black
    for(int i = row+1; i<row2;i++){
        for (int j = col+1; j<col2; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

/**
 *  \brief LineDetector::getAvg gets the average of the relevant pixels
 *  \return the average as a floating point number
 */
float LineDetector::getAvg(){
    Vec3b p;
    float totalAvg = 0;
    for (int i = src.rows/3; i< 5*src.rows/6; i++){
        for(int j=src.cols/6; j< 5*src.cols/6; j++){
            p = dst.at<Vec3b>(i, j);
            totalAvg += (p[0]+p[1]+p[2])/3;
        }
    }
    totalAvg = (25*totalAvg)/(src.cols*src.rows*8);
    return totalAvg;
}

/**
 *  \brief LineDetector::blackoutSection turns a section of the image black
 *  \param rowl the lower row bound
 *  \param rowu the upper row bound
 *  \param coll the left column bound
 *  \param colu the right column bound
 */
void LineDetector::blackoutSection(int rowl, int rowu, int coll, int colu){

    for (int i=rowl;i<=rowu;i++){
        for (int j = coll; j<=colu; j++){
            dst.at<Vec3b>(i,j)[0] = 0;
            dst.at<Vec3b>(i,j)[1] = 0;
            dst.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

<|endoftext|>


<commit_before>#include "MenuState.h"
#include "PlayState.h"
#include "GameStateAsset.h"
#include "GameEngine.h"
#include <iostream>
#include "AudioSystem.h"
#include "GameState.h"
#include "ResourceHolder.h"
#include "WindowManager.h"
#include "ObjectManager.h"
#include "SFML/Graphics/RenderWindow.hpp"

MenuState::MenuState() :
mLogo(),
mMenu()
{

}

MenuState::~MenuState()
{

}

void MenuState::entering()
{
	mAssets->audioSystem->playMusic("Ambient_1");
	std::cout << "Entering menu state" << std::endl;

	auto windowSize = mAssets->windowManager->getWindow()->getSize();

	// Awesome game logo!
	mLogo.setTexture(mAssets->resourceHolder->getTexture("logo.png"));

	// Centering and moving a little up
	sf::FloatRect rect = mLogo.getLocalBounds();
	mLogo.setOrigin(rect.left + rect.width / 2.0f, rect.top + rect.height / 2.0f);
	mLogo.setPosition(sf::Vector2f(windowSize.x / 2.0f, (windowSize.y / 2.0f) - rect.height));

	mMenu.setFont(mAssets->resourceHolder->getFont("loaded.ttf"));
	mMenu.setPosition(windowSize.x/2.0f, windowSize.y/2.0f);
	mMenu.addItem("Start Game", 0);
	mMenu.addItem("Options", 1);
	mMenu.addItem("Help", 2);
	mMenu.addItem("Quit", 3);
}
void MenuState::leaving()
{
	std::cout << "Leaving menu state" << std::endl;
}

void MenuState::obscuring()
{
}

void MenuState::releaving()
{
}

bool MenuState::update(float dt)
{
	mMenu.update(dt, getActionMap());

	if (getActionMap()->isActive("Menu_Select"))
	{
		switch (mMenu.getCurrentID())
		{
		case 0:
			mAssets->gameEngine->changeState(new PlayState());
			break;
		default:
			break;
		}
		return true;
	}
	if (getActionMap()->isActive("Quit"))
	{
		return false;
	}
	return true;
}

void MenuState::draw()
{
	mAssets->windowManager->getWindow()->draw(mLogo);
	mAssets->windowManager->getWindow()->draw(mMenu);
}

void MenuState::setupActions()
{
	getActionMap()->operator[]("Menu_Select") = thor::Action(sf::Keyboard::Return, thor::Action::PressOnce);
	getActionMap()->operator[]("Menu_Next") = thor::Action(sf::Keyboard::Down, thor::Action::PressOnce);
	getActionMap()->operator[]("Menu_Previous") = thor::Action(sf::Keyboard::Up, thor::Action::PressOnce);
	getActionMap()->operator[]("Quit") = thor::Action(sf::Keyboard::Escape, thor::Action::PressOnce);
}
<commit_msg>Made easier to read on the menu items<commit_after>#include "MenuState.h"
#include "PlayState.h"
#include "GameStateAsset.h"
#include "GameEngine.h"
#include <iostream>
#include "AudioSystem.h"
#include "GameState.h"
#include "ResourceHolder.h"
#include "WindowManager.h"
#include "ObjectManager.h"
#include "SFML/Graphics/RenderWindow.hpp"

// This is a local enum simply to make adding
// items to the Menu easier to read
enum MenuItemIDs
{
	MENU_ITEM_START=0,
	MENU_ITEM_OPTIONS,
	MENU_ITEM_HELP,
	MENU_ITEM_EXIT
};

MenuState::MenuState() :
mLogo(),
mMenu()
{

}

MenuState::~MenuState()
{

}

void MenuState::entering()
{
	mAssets->audioSystem->playMusic("Ambient_1");
	std::cout << "Entering menu state" << std::endl;

	auto windowSize = mAssets->windowManager->getWindow()->getSize();

	// Awesome game logo!
	mLogo.setTexture(mAssets->resourceHolder->getTexture("logo.png"));

	// Centering and moving a little up
	sf::FloatRect rect = mLogo.getLocalBounds();
	mLogo.setOrigin(rect.left + rect.width / 2.0f, rect.top + rect.height / 2.0f);
	mLogo.setPosition(sf::Vector2f(windowSize.x / 2.0f, (windowSize.y / 2.0f) - rect.height));

	mMenu.setFont(mAssets->resourceHolder->getFont("loaded.ttf"));
	mMenu.setPosition(windowSize.x/2.0f, windowSize.y/2.0f);
	mMenu.addItem("Start Game", MENU_ITEM_START);
	mMenu.addItem("Options", MENU_ITEM_OPTIONS);
	mMenu.addItem("Help", MENU_ITEM_HELP);
	mMenu.addItem("Quit", MENU_ITEM_EXIT);
}
void MenuState::leaving()
{
	std::cout << "Leaving menu state" << std::endl;
}

void MenuState::obscuring()
{
}

void MenuState::releaving()
{
}

bool MenuState::update(float dt)
{
	mMenu.update(dt, getActionMap());

	if (getActionMap()->isActive("Menu_Select"))
	{
		switch (mMenu.getCurrentID())
		{
		case MENU_ITEM_START:
			mAssets->gameEngine->changeState(new PlayState());
			break;
		case MENU_ITEM_OPTIONS:
			break;
		case MENU_ITEM_HELP:
			break;
		case MENU_ITEM_EXIT:
			return false;
			break;
		default:
			break;
		}
		return true;
	}
	if (getActionMap()->isActive("Quit"))
	{
		return false;
	}
	return true;
}

void MenuState::draw()
{
	mAssets->windowManager->getWindow()->draw(mLogo);
	mAssets->windowManager->getWindow()->draw(mMenu);
}

void MenuState::setupActions()
{
	getActionMap()->operator[]("Menu_Select") = thor::Action(sf::Keyboard::Return, thor::Action::PressOnce);
	getActionMap()->operator[]("Menu_Next") = thor::Action(sf::Keyboard::Down, thor::Action::PressOnce);
	getActionMap()->operator[]("Menu_Previous") = thor::Action(sf::Keyboard::Up, thor::Action::PressOnce);
	getActionMap()->operator[]("Quit") = thor::Action(sf::Keyboard::Escape, thor::Action::PressOnce);
}
<|endoftext|>


<commit_before>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/freelist.h"

#include <map>
#include <utility>

#include "vm/bit_set.h"
#include "vm/object.h"
#include "vm/raw_object.h"

namespace dart {

FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) {
  ASSERT(size >= kObjectAlignment);
  ASSERT(Utils::IsAligned(size, kObjectAlignment));

  FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);

  uword tags = 0;
  tags = RawObject::FreeBit::update(true, tags);
  tags = RawObject::SizeTag::update(size, tags);
  tags = RawObject::ClassIdTag::update(kFreeListElement, tags);

  result->tags_ = tags;
  if (size > RawObject::SizeTag::kMaxSizeTag) {
    *result->SizeAddress() = size;
  }
  result->set_next(NULL);

  return result;
}

void FreeListElement::InitOnce() {
  ASSERT(sizeof(FreeListElement) == kObjectAlignment);
  ASSERT(OFFSET_OF(FreeListElement, tags_) == Object::tags_offset());
}

FreeList::FreeList() {
  Reset();
}

FreeList::~FreeList() {
  // Nothing to release.
}

uword FreeList::TryAllocate(intptr_t size) {
  int index = IndexForSize(size);
  if ((index != kNumLists) && free_map_.Test(index)) {
    return reinterpret_cast<uword>(DequeueElement(index));
  }

  if ((index + 1) < kNumLists) {
    intptr_t next_index = free_map_.Next(index + 1);
    if (next_index != -1) {
      // Dequeue an element from the list, split and enqueue the remainder in
      // the appropriate list.
      FreeListElement* element = DequeueElement(next_index);
      SplitElementAfterAndEnqueue(element, size);
      return reinterpret_cast<uword>(element);
    }
  }

  FreeListElement* previous = NULL;
  FreeListElement* current = free_lists_[kNumLists];
  while (current != NULL) {
    if (current->Size() >= size) {
      // Found an element large enough to hold the requested size. Dequeue,
      // split and enqueue the remainder.
      if (previous == NULL) {
        free_lists_[kNumLists] = current->next();
      } else {
        previous->set_next(current->next());
      }
      SplitElementAfterAndEnqueue(current, size);
      return reinterpret_cast<uword>(current);
    }
    previous = current;
    current = current->next();
  }
  return 0;
}

void FreeList::Free(uword addr, intptr_t size) {
  intptr_t index = IndexForSize(size);
  FreeListElement* element = FreeListElement::AsElement(addr, size);
  EnqueueElement(element, index);
}

void FreeList::Reset() {
  free_map_.Reset();
  for (int i = 0; i < (kNumLists + 1); i++) {
    free_lists_[i] = NULL;
  }
}

intptr_t FreeList::IndexForSize(intptr_t size) {
  ASSERT(size >= kObjectAlignment);
  ASSERT(Utils::IsAligned(size, kObjectAlignment));

  intptr_t index = size / kObjectAlignment;
  if (index >= kNumLists) {
    index = kNumLists;
  }
  return index;
}

void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) {
  FreeListElement* next = free_lists_[index];
  if (next == NULL && index != kNumLists) {
    free_map_.Set(index, true);
  }
  element->set_next(next);
  free_lists_[index] = element;
}

FreeListElement* FreeList::DequeueElement(intptr_t index) {
  FreeListElement* result = free_lists_[index];
  FreeListElement* next = result->next();
  if (next == NULL && index != kNumLists) {
    free_map_.Set(index, false);
  }
  free_lists_[index] = next;
  return result;
}

intptr_t FreeList::Length(int index) const {
  ASSERT(index >= 0);
  ASSERT(index < kNumLists);
  intptr_t result = 0;
  FreeListElement* element = free_lists_[index];
  while (element != NULL) {
    ++result;
    element = element->next();
  }
  return result;
}

void FreeList::PrintSmall() const {
  int small_sizes = 0;
  int small_objects = 0;
  intptr_t small_bytes = 0;
  for (int i = 0; i < kNumLists; ++i) {
    if (free_lists_[i] == NULL) {
      continue;
    }
    small_sizes += 1;
    intptr_t list_length = Length(i);
    small_objects += list_length;
    intptr_t list_bytes = list_length * i * kObjectAlignment;
    small_bytes += list_bytes;
    OS::Print("small %3d [%8d bytes] : "
              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
              i,
              i * kObjectAlignment,
              list_length,
              list_bytes / static_cast<double>(KB),
              small_bytes / static_cast<double>(KB));
  }
}

void FreeList::PrintLarge() const {
  int large_sizes = 0;
  int large_objects = 0;
  intptr_t large_bytes = 0;
  std::map<intptr_t, intptr_t> sorted;
  std::map<intptr_t, intptr_t>::iterator it;
  FreeListElement* node;
  for (node = free_lists_[kNumLists]; node != NULL; node = node->next()) {
    it = sorted.find(node->Size());
    if (it != sorted.end()) {
      it->second += 1;
    } else {
      large_sizes += 1;
      sorted.insert(std::make_pair(node->Size(), 1));
    }
    large_objects += 1;
  }
  for (it = sorted.begin(); it != sorted.end(); ++it) {
    intptr_t size = it->first;
    int list_length = it->second;
    intptr_t list_bytes = list_length * size;
    large_bytes += list_bytes;
    OS::Print("large %3d [%8d bytes] : "
              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
              size / kObjectAlignment,
              size,
              list_length,
              list_bytes / static_cast<double>(KB),
              large_bytes / static_cast<double>(KB));
  }
}

void FreeList::Print() const {
  PrintSmall();
  PrintLarge();
}

void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element,
                                           intptr_t size) {
  intptr_t remainder_size = element->Size() - size;
  if (remainder_size == 0) return;

  element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size,
                                       remainder_size);
  intptr_t remainder_index = IndexForSize(remainder_size);
  EnqueueElement(element, remainder_index);
}

}  // namespace dart
<commit_msg>Fix format type specifier discrepancies on 64-bit targets.<commit_after>// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/freelist.h"

#include <map>
#include <utility>

#include "vm/bit_set.h"
#include "vm/object.h"
#include "vm/raw_object.h"

namespace dart {

FreeListElement* FreeListElement::AsElement(uword addr, intptr_t size) {
  ASSERT(size >= kObjectAlignment);
  ASSERT(Utils::IsAligned(size, kObjectAlignment));

  FreeListElement* result = reinterpret_cast<FreeListElement*>(addr);

  uword tags = 0;
  tags = RawObject::FreeBit::update(true, tags);
  tags = RawObject::SizeTag::update(size, tags);
  tags = RawObject::ClassIdTag::update(kFreeListElement, tags);

  result->tags_ = tags;
  if (size > RawObject::SizeTag::kMaxSizeTag) {
    *result->SizeAddress() = size;
  }
  result->set_next(NULL);

  return result;
}

void FreeListElement::InitOnce() {
  ASSERT(sizeof(FreeListElement) == kObjectAlignment);
  ASSERT(OFFSET_OF(FreeListElement, tags_) == Object::tags_offset());
}

FreeList::FreeList() {
  Reset();
}

FreeList::~FreeList() {
  // Nothing to release.
}

uword FreeList::TryAllocate(intptr_t size) {
  int index = IndexForSize(size);
  if ((index != kNumLists) && free_map_.Test(index)) {
    return reinterpret_cast<uword>(DequeueElement(index));
  }

  if ((index + 1) < kNumLists) {
    intptr_t next_index = free_map_.Next(index + 1);
    if (next_index != -1) {
      // Dequeue an element from the list, split and enqueue the remainder in
      // the appropriate list.
      FreeListElement* element = DequeueElement(next_index);
      SplitElementAfterAndEnqueue(element, size);
      return reinterpret_cast<uword>(element);
    }
  }

  FreeListElement* previous = NULL;
  FreeListElement* current = free_lists_[kNumLists];
  while (current != NULL) {
    if (current->Size() >= size) {
      // Found an element large enough to hold the requested size. Dequeue,
      // split and enqueue the remainder.
      if (previous == NULL) {
        free_lists_[kNumLists] = current->next();
      } else {
        previous->set_next(current->next());
      }
      SplitElementAfterAndEnqueue(current, size);
      return reinterpret_cast<uword>(current);
    }
    previous = current;
    current = current->next();
  }
  return 0;
}

void FreeList::Free(uword addr, intptr_t size) {
  intptr_t index = IndexForSize(size);
  FreeListElement* element = FreeListElement::AsElement(addr, size);
  EnqueueElement(element, index);
}

void FreeList::Reset() {
  free_map_.Reset();
  for (int i = 0; i < (kNumLists + 1); i++) {
    free_lists_[i] = NULL;
  }
}

intptr_t FreeList::IndexForSize(intptr_t size) {
  ASSERT(size >= kObjectAlignment);
  ASSERT(Utils::IsAligned(size, kObjectAlignment));

  intptr_t index = size / kObjectAlignment;
  if (index >= kNumLists) {
    index = kNumLists;
  }
  return index;
}

void FreeList::EnqueueElement(FreeListElement* element, intptr_t index) {
  FreeListElement* next = free_lists_[index];
  if (next == NULL && index != kNumLists) {
    free_map_.Set(index, true);
  }
  element->set_next(next);
  free_lists_[index] = element;
}

FreeListElement* FreeList::DequeueElement(intptr_t index) {
  FreeListElement* result = free_lists_[index];
  FreeListElement* next = result->next();
  if (next == NULL && index != kNumLists) {
    free_map_.Set(index, false);
  }
  free_lists_[index] = next;
  return result;
}

intptr_t FreeList::Length(int index) const {
  ASSERT(index >= 0);
  ASSERT(index < kNumLists);
  intptr_t result = 0;
  FreeListElement* element = free_lists_[index];
  while (element != NULL) {
    ++result;
    element = element->next();
  }
  return result;
}

void FreeList::PrintSmall() const {
  int small_sizes = 0;
  int small_objects = 0;
  intptr_t small_bytes = 0;
  for (int i = 0; i < kNumLists; ++i) {
    if (free_lists_[i] == NULL) {
      continue;
    }
    small_sizes += 1;
    intptr_t list_length = Length(i);
    small_objects += list_length;
    intptr_t list_bytes = list_length * i * kObjectAlignment;
    small_bytes += list_bytes;
    OS::Print("small %3d [%8d bytes] : "
              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
              i,
              i * kObjectAlignment,
              list_length,
              list_bytes / static_cast<double>(KB),
              small_bytes / static_cast<double>(KB));
  }
}

void FreeList::PrintLarge() const {
  int large_sizes = 0;
  int large_objects = 0;
  intptr_t large_bytes = 0;
  std::map<intptr_t, intptr_t> sorted;
  std::map<intptr_t, intptr_t>::iterator it;
  FreeListElement* node;
  for (node = free_lists_[kNumLists]; node != NULL; node = node->next()) {
    it = sorted.find(node->Size());
    if (it != sorted.end()) {
      it->second += 1;
    } else {
      large_sizes += 1;
      sorted.insert(std::make_pair(node->Size(), 1));
    }
    large_objects += 1;
  }
  for (it = sorted.begin(); it != sorted.end(); ++it) {
    intptr_t size = it->first;
    intptr_t list_length = it->second;
    intptr_t list_bytes = list_length * size;
    large_bytes += list_bytes;
    OS::Print("large %3"Pd" [%8"Pd" bytes] : "
              "%8"Pd" objs; %8.1f KB; %8.1f cum KB\n",
              size / kObjectAlignment,
              size,
              list_length,
              list_bytes / static_cast<double>(KB),
              large_bytes / static_cast<double>(KB));
  }
}

void FreeList::Print() const {
  PrintSmall();
  PrintLarge();
}

void FreeList::SplitElementAfterAndEnqueue(FreeListElement* element,
                                           intptr_t size) {
  intptr_t remainder_size = element->Size() - size;
  if (remainder_size == 0) return;

  element = FreeListElement::AsElement(reinterpret_cast<uword>(element) + size,
                                       remainder_size);
  intptr_t remainder_index = IndexForSize(remainder_size);
  EnqueueElement(element, remainder_index);
}

}  // namespace dart
<|endoftext|>


<commit_before>#include "kernel.h"
#include <QColor>
#include "ilwisdata.h"
#include "domain.h"
#include "colorlookup.h"
#include "range.h"
#include "numericrange.h"
#include "representation.h"
#include "attributevisualproperties.h"

using namespace Ilwis;
using namespace Geodrawer;

AttributeVisualProperties::AttributeVisualProperties()
{
}

AttributeVisualProperties::AttributeVisualProperties(const IDomain &dom) : _domain(dom)
{
    _representation = Representation::defaultRepresentation(dom);
}

AttributeVisualProperties::AttributeVisualProperties(const AttributeVisualProperties &avp)
{
    _representation = avp._representation;
    _actualRange = avp._actualRange;
    _stretchRange = avp._stretchRange;
    _domain = avp._domain;
}

IRepresentation AttributeVisualProperties::representation() const
{
    return _representation;
}

void AttributeVisualProperties::representation(const IRepresentation &rpr)
{
    if ( !_domain.isValid() || !rpr.isValid())
        return;
    if ( rpr->isCompatible(_domain)){
        _representation = rpr;
    }
}

IDomain AttributeVisualProperties::domain() const
{
    return _domain;
}

void AttributeVisualProperties::domain(const IDomain &dom)
{
    if ( _representation.isValid() && !_representation->isCompatible(dom)){
        _representation = IRepresentation();
    }
    _domain = dom;
}

NumericRange AttributeVisualProperties::stretchRange() const
{
    return _stretchRange;
}

void AttributeVisualProperties::stretchRange(const NumericRange &rng)
{
    _stretchRange = rng;
}

QColor AttributeVisualProperties::value2color(const QVariant &var)
{
    return _representation->colors()->value2color(var.toDouble(), _actualRange, _stretchRange) ;
}

NumericRange AttributeVisualProperties::actualRange() const
{
    return _actualRange;
}

void AttributeVisualProperties::actualRange(const NumericRange &rng)
{
    _actualRange = rng;
}

<commit_msg>set some defaults<commit_after>#include "kernel.h"
#include <QColor>
#include "ilwisdata.h"
#include "domain.h"
#include "colorlookup.h"
#include "range.h"
#include "numericrange.h"
#include "representation.h"
#include "attributevisualproperties.h"

using namespace Ilwis;
using namespace Geodrawer;

AttributeVisualProperties::AttributeVisualProperties()
{
}

AttributeVisualProperties::AttributeVisualProperties(const IDomain &dom) : _domain(dom)
{
    _representation = Representation::defaultRepresentation(dom);
    _representation->domain(dom);
    _domain = dom;
}

AttributeVisualProperties::AttributeVisualProperties(const AttributeVisualProperties &avp)
{
    _representation = avp._representation;
    _actualRange = avp._actualRange;
    _stretchRange = avp._stretchRange;
    _domain = avp._domain;
}

IRepresentation AttributeVisualProperties::representation() const
{
    return _representation;
}

void AttributeVisualProperties::representation(const IRepresentation &rpr)
{
    if ( !_domain.isValid() || !rpr.isValid())
        return;
    if ( rpr->isCompatible(_domain)){
        _representation = rpr;
    }
}

IDomain AttributeVisualProperties::domain() const
{
    return _domain;
}

void AttributeVisualProperties::domain(const IDomain &dom)
{
    if ( _representation.isValid() && !_representation->isCompatible(dom)){
        _representation = IRepresentation();
    }
    _domain = dom;
}

NumericRange AttributeVisualProperties::stretchRange() const
{
    return _stretchRange;
}

void AttributeVisualProperties::stretchRange(const NumericRange &rng)
{
    _stretchRange = rng;
}

QColor AttributeVisualProperties::value2color(const QVariant &var)
{
    return _representation->colors()->value2color(var.toDouble(), _actualRange, _stretchRange) ;
}

NumericRange AttributeVisualProperties::actualRange() const
{
    return _actualRange;
}

void AttributeVisualProperties::actualRange(const NumericRange &rng)
{
    _actualRange = rng;
}

<|endoftext|>


<commit_before>#include "pch.h"
#include "AttackState.h"
#include "GameManager.h"
#include "TriggerManager.h"
#include "SeizeFireTrigger.h"
#include "ObserverComponent.h"

bool Arthas::AttackState::init()
{
	if (!StateComponent::init())
	{
		return false;
	}
	m_IsAttacked = false;
	return true;
}

void Arthas::AttackState::enter()
{
	m_InitTime = GET_GAME_MANAGER()->getTime();
	m_IsAttacked = false;
}

void Arthas::AttackState::exit()
{
}

void Arthas::AttackState::update(float dTime)
{
	long currentDelay = GET_GAME_MANAGER()->getTime().tv_sec - m_InitTime.tv_sec;
	if(currentDelay > m_PreDelay && m_IsAttacked == false)
	{
		m_IsAttacked = true;
		//̻ ߽!!!!!!!!!!!!!!!
		CCLOG("balSSA!");
	}
	else if(currentDelay > m_AfterDelay)
	{
		auto endTrigger = GET_TRIGGER_MANAGER()->createTrigger<SeizeFireTrigger>();
		auto observer = (ObserverComponent*) m_Ref->getComponent(CT_OBSERVER);
		observer->addTrigger(endTrigger);
	}
}

void Arthas::AttackState::setAttribute(Component* ref, float preDelay, float afterDelay, int missleType, int attackPoint)
{
	m_Ref = ref;
	m_PreDelay = preDelay;
	m_AfterDelay = afterDelay;
}
<commit_msg>attackState에서 미사일발사<commit_after>#include "pch.h"
#include "AttackState.h"
#include "GameManager.h"
#include "TriggerManager.h"
#include "SeizeFireTrigger.h"
#include "ObserverComponent.h"

bool Arthas::AttackState::init()
{
	if (!StateComponent::init())
	{
		return false;
	}
	m_IsAttacked = false;
	return true;
}

void Arthas::AttackState::enter()
{
	m_InitTime = GET_GAME_MANAGER()->getTime();
	m_IsAttacked = false;
}

void Arthas::AttackState::exit()
{
}

void Arthas::AttackState::update(float dTime)
{
	long currentDelay = GET_GAME_MANAGER()->getTime().tv_sec - m_InitTime.tv_sec;
	if(currentDelay > m_PreDelay && m_IsAttacked == false)
	{
		m_IsAttacked = true;
		GET_MISSLE_MANANGET()
		CCLOG("balSSA!");
	}
	else if(currentDelay > m_AfterDelay)
	{
		auto endTrigger = GET_TRIGGER_MANAGER()->createTrigger<SeizeFireTrigger>();
		auto observer = (ObserverComponent*) m_Ref->getComponent(CT_OBSERVER);
		observer->addTrigger(endTrigger);
	}
}

void Arthas::AttackState::setAttribute(Component* ref, float preDelay, float afterDelay, int missleType, int attackPoint)
{
	m_Ref = ref;
	m_PreDelay = preDelay;
	m_AfterDelay = afterDelay;
}
<|endoftext|>


<commit_before>#include "../test.h"
#include "rxcpp/operators/rx-pairwise.hpp"

SCENARIO("pairwise - enough items to create pairs", "[pairwise][operators]") {
    GIVEN("a cold observable of n ints") {
        auto sc = rxsc::make_test();
        auto w = sc.create_worker();
        const rxsc::test::messages<int> on;
        const rxsc::test::messages<std::tuple<int, int>> on_pairwise;
        long invoked = 0;

        auto xs = sc.make_cold_observable({
            on.next(180, 1),
            on.next(210, 2),
            on.next(240, 3),
            on.next(290, 4),
            on.next(350, 5),
            on.completed(400),
        });

        WHEN("taken pairwise") {

            auto res = w.start(
                [xs]() {
                    return xs
                        | rxo::pairwise()
                        // forget type to workaround lambda deduction bug on msvc 2013
                        | rxo::as_dynamic();
                }
            );

            THEN("the output contains n-1 tuples of ints"){
                auto delay = rxcpp::schedulers::test::subscribed_time;
                auto required = rxu::to_vector({
                    on_pairwise.next(210 + delay, std::make_tuple(1, 2)),
                    on_pairwise.next(240 + delay, std::make_tuple(2, 3)),
                    on_pairwise.next(290 + delay, std::make_tuple(3, 4)),
                    on_pairwise.next(350 + delay, std::make_tuple(4, 5)),
                    on_pairwise.completed(400 + delay)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }
        }
    }
}

SCENARIO("pairwise - not enough items to create a pair", "[pairwise][operators]") {
    GIVEN("a cold observable of 1 ints") {
        auto sc = rxsc::make_test();
        auto w = sc.create_worker();
        const rxsc::test::messages<int> on;
        const rxsc::test::messages<std::tuple<int, int>> on_pairwise;

        auto xs = sc.make_cold_observable({
            on.next(180, 1),
            on.completed(400),
        });

        WHEN("taken pairwise") {

            auto res = w.start(
                [xs]() {
                    return xs
                        .pairwise()
                        // forget type to workaround lambda deduction bug on msvc 2013
                        .as_dynamic();
                }
            );

            THEN("the output contains no tuples of ints"){
                auto delay = rxcpp::schedulers::test::subscribed_time;
                auto required = rxu::to_vector({
                    on_pairwise.completed(400 + delay)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }
        }
    }
}
<commit_msg>remove unused local<commit_after>#include "../test.h"
#include "rxcpp/operators/rx-pairwise.hpp"

SCENARIO("pairwise - enough items to create pairs", "[pairwise][operators]") {
    GIVEN("a cold observable of n ints") {
        auto sc = rxsc::make_test();
        auto w = sc.create_worker();
        const rxsc::test::messages<int> on;
        const rxsc::test::messages<std::tuple<int, int>> on_pairwise;

        auto xs = sc.make_cold_observable({
            on.next(180, 1),
            on.next(210, 2),
            on.next(240, 3),
            on.next(290, 4),
            on.next(350, 5),
            on.completed(400),
        });

        WHEN("taken pairwise") {

            auto res = w.start(
                [xs]() {
                    return xs
                        | rxo::pairwise()
                        // forget type to workaround lambda deduction bug on msvc 2013
                        | rxo::as_dynamic();
                }
            );

            THEN("the output contains n-1 tuples of ints"){
                auto delay = rxcpp::schedulers::test::subscribed_time;
                auto required = rxu::to_vector({
                    on_pairwise.next(210 + delay, std::make_tuple(1, 2)),
                    on_pairwise.next(240 + delay, std::make_tuple(2, 3)),
                    on_pairwise.next(290 + delay, std::make_tuple(3, 4)),
                    on_pairwise.next(350 + delay, std::make_tuple(4, 5)),
                    on_pairwise.completed(400 + delay)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }
        }
    }
}

SCENARIO("pairwise - not enough items to create a pair", "[pairwise][operators]") {
    GIVEN("a cold observable of 1 ints") {
        auto sc = rxsc::make_test();
        auto w = sc.create_worker();
        const rxsc::test::messages<int> on;
        const rxsc::test::messages<std::tuple<int, int>> on_pairwise;

        auto xs = sc.make_cold_observable({
            on.next(180, 1),
            on.completed(400),
        });

        WHEN("taken pairwise") {

            auto res = w.start(
                [xs]() {
                    return xs
                        .pairwise()
                        // forget type to workaround lambda deduction bug on msvc 2013
                        .as_dynamic();
                }
            );

            THEN("the output contains no tuples of ints"){
                auto delay = rxcpp::schedulers::test::subscribed_time;
                auto required = rxu::to_vector({
                    on_pairwise.completed(400 + delay)
                });
                auto actual = res.get_observer().messages();
                REQUIRE(required == actual);
            }
        }
    }
}
<|endoftext|>


<commit_before>/**
 *  Script.cpp
 *
 *  Implementation file for the script class
 *
 *  @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
 *  @copyright 2014 Copernica BV
 */

/**
 *  Dependencies
 */
#include "includes.h"

/**
 *  Open PHP namespace
 */
namespace Php {

/**
 *  Helper function to compile the source code
 *  @param  name        name of the script
 *  @param  script      actual PHP code
 *  @param  size        length of the string
 *  @return opcodes
 */
zend_op_array *Script::compile(const char *name, const char *phpcode, size_t size)
{
    // Sadly, there is not a simple Zend function to compile a string into opcodes,
    // so we basically copy the code that we found in zend_execute_API.c inside
    // the zend_eval_stringl() function into this file here. However, the code
    // found there is full of zval manipulation, for which we can use the much
    // simpler Php::Value object
    Php::Value source(phpcode, size);

    // we need the tsrm_ls variable
    // @todo it would be better if this was passed as param to the compile() method
    TSRMLS_FETCH();

    // remember the old compiler options, and set new compiler options
    CompilerOptions options(ZEND_COMPILE_DEFAULT_FOR_EVAL TSRMLS_CC);

    // compile the string
    return zend_compile_string(source._val, (char *)name TSRMLS_CC);
}

/**
 *  Constructor
 *  @param  name        name of the script
 *  @param  script      actual PHP code
 *  @param  size        length of the string
 */
Script::Script(const char *name, const char *phpcode, size_t size)
{
    // we need the tsrm_ls variable
    TSRMLS_FETCH();

    // construct opcodes
    _opcodes = new Opcodes(compile(name, phpcode, size) TSRMLS_CC);
}

/**
 *  Destructor
 */
Script::~Script()
{
    // remove opcodes
    delete _opcodes;
}

/**
 *  Is the script a valid PHP script without syntax errors?
 *  @return bool
 */
bool Script::valid() const
{
    // check opcodes
    return _opcodes && _opcodes->valid();
}

/**
 *  Execute the script
 *  The return value of the script is returned
 *  @return Value
 */
Value Script::execute() const
{
    // pass on to opcodes
    if (!_opcodes) return nullptr;

    // execute opcodes
    return _opcodes->execute();
}

/**
 *  End of namespace
 */
}

<commit_msg>This should have noexcept in the .cpp file as well<commit_after>/**
 *  Script.cpp
 *
 *  Implementation file for the script class
 *
 *  @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
 *  @copyright 2014 Copernica BV
 */

/**
 *  Dependencies
 */
#include "includes.h"

/**
 *  Open PHP namespace
 */
namespace Php {

/**
 *  Helper function to compile the source code
 *  @param  name        name of the script
 *  @param  script      actual PHP code
 *  @param  size        length of the string
 *  @return opcodes
 */
zend_op_array *Script::compile(const char *name, const char *phpcode, size_t size)
{
    // Sadly, there is not a simple Zend function to compile a string into opcodes,
    // so we basically copy the code that we found in zend_execute_API.c inside
    // the zend_eval_stringl() function into this file here. However, the code
    // found there is full of zval manipulation, for which we can use the much
    // simpler Php::Value object
    Php::Value source(phpcode, size);

    // we need the tsrm_ls variable
    // @todo it would be better if this was passed as param to the compile() method
    TSRMLS_FETCH();

    // remember the old compiler options, and set new compiler options
    CompilerOptions options(ZEND_COMPILE_DEFAULT_FOR_EVAL TSRMLS_CC);

    // compile the string
    return zend_compile_string(source._val, (char *)name TSRMLS_CC);
}

/**
 *  Constructor
 *  @param  name        name of the script
 *  @param  script      actual PHP code
 *  @param  size        length of the string
 */
Script::Script(const char *name, const char *phpcode, size_t size) noexcept
{
    // we need the tsrm_ls variable
    TSRMLS_FETCH();

    // construct opcodes
    _opcodes = new Opcodes(compile(name, phpcode, size) TSRMLS_CC);
}

/**
 *  Destructor
 */
Script::~Script()
{
    // remove opcodes
    delete _opcodes;
}

/**
 *  Is the script a valid PHP script without syntax errors?
 *  @return bool
 */
bool Script::valid() const
{
    // check opcodes
    return _opcodes && _opcodes->valid();
}

/**
 *  Execute the script
 *  The return value of the script is returned
 *  @return Value
 */
Value Script::execute() const
{
    // pass on to opcodes
    if (!_opcodes) return nullptr;

    // execute opcodes
    return _opcodes->execute();
}

/**
 *  End of namespace
 */
}

<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/protocol/content_description.h"

#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/name_value_map.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"

using buzz::QName;
using buzz::XmlElement;

namespace remoting {
namespace protocol {

const char ContentDescription::kChromotingContentName[] = "chromoting";

namespace {

const char kDefaultNs[] = "";

// Following constants are used to format session description in XML.
const char kDescriptionTag[] = "description";
const char kControlTag[] = "control";
const char kEventTag[] = "event";
const char kVideoTag[] = "video";
const char kAudioTag[] = "audio";
const char kDeprecatedResolutionTag[] = "initial-resolution";

const char kTransportAttr[] = "transport";
const char kVersionAttr[] = "version";
const char kCodecAttr[] = "codec";
const char kDeprecatedWidthAttr[] = "width";
const char kDeprecatedHeightAttr[] = "height";

const NameMapElement<ChannelConfig::TransportType> kTransports[] = {
  { ChannelConfig::TRANSPORT_STREAM, "stream" },
  { ChannelConfig::TRANSPORT_MUX_STREAM, "mux-stream" },
  { ChannelConfig::TRANSPORT_DATAGRAM, "datagram" },
  { ChannelConfig::TRANSPORT_NONE, "none" },
};

const NameMapElement<ChannelConfig::Codec> kCodecs[] = {
  { ChannelConfig::CODEC_VERBATIM, "verbatim" },
  { ChannelConfig::CODEC_VP8, "vp8" },
  { ChannelConfig::CODEC_ZIP, "zip" },
  { ChannelConfig::CODEC_OPUS, "opus" },
  { ChannelConfig::CODEC_SPEEX, "speex" },
};

// Format a channel configuration tag for chromotocol session description,
// e.g. for video channel:
//    <video transport="stream" version="1" codec="vp8" />
XmlElement* FormatChannelConfig(const ChannelConfig& config,
                                const std::string& tag_name) {
  XmlElement* result = new XmlElement(
      QName(kChromotingXmlNamespace, tag_name));

  result->AddAttr(QName(kDefaultNs, kTransportAttr),
                  ValueToName(kTransports, config.transport));

  if (config.transport != ChannelConfig::TRANSPORT_NONE) {
    result->AddAttr(QName(kDefaultNs, kVersionAttr),
                    base::IntToString(config.version));

    if (config.codec != ChannelConfig::CODEC_UNDEFINED) {
      result->AddAttr(QName(kDefaultNs, kCodecAttr),
                      ValueToName(kCodecs, config.codec));
    }
  }

  return result;
}

// Returns false if the element is invalid.
bool ParseChannelConfig(const XmlElement* element, bool codec_required,
                        ChannelConfig* config) {
  if (!NameToValue(
          kTransports, element->Attr(QName(kDefaultNs, kTransportAttr)),
          &config->transport)) {
    return false;
  }

  // Version is not required when transport="none".
  if (config->transport != ChannelConfig::TRANSPORT_NONE) {
    if (!base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)),
                           &config->version)) {
      return false;
    }

    // Codec is not required when transport="none".
    if (codec_required) {
      if (!NameToValue(kCodecs, element->Attr(QName(kDefaultNs, kCodecAttr)),
                       &config->codec)) {
        return false;
      }
    } else {
      config->codec = ChannelConfig::CODEC_UNDEFINED;
    }
  } else {
    config->version = 0;
    config->codec = ChannelConfig::CODEC_UNDEFINED;
  }

  return true;
}

}  // namespace

ContentDescription::ContentDescription(
    scoped_ptr<CandidateSessionConfig> config,
    scoped_ptr<buzz::XmlElement> authenticator_message)
    : candidate_config_(config.Pass()),
      authenticator_message_(authenticator_message.Pass()) {
}

ContentDescription::~ContentDescription() { }

ContentDescription* ContentDescription::Copy() const {
  if (!candidate_config_.get() || !authenticator_message_.get()) {
    return NULL;
  }
  scoped_ptr<XmlElement> message(new XmlElement(*authenticator_message_));
  return new ContentDescription(candidate_config_->Clone(), message.Pass());
}

// ToXml() creates content description for chromoting session. The
// description looks as follows:
//   <description xmlns="google:remoting">
//     <control transport="stream" version="1" />
//     <event transport="datagram" version="1" />
//     <video transport="stream" codec="vp8" version="1" />
//     <audio transport="stream" codec="opus" version="1" />
//     <authentication>
//      Message created by Authenticator implementation.
//     </authentication>
//   </description>
//
XmlElement* ContentDescription::ToXml() const {
  XmlElement* root = new XmlElement(
      QName(kChromotingXmlNamespace, kDescriptionTag), true);

  std::vector<ChannelConfig>::const_iterator it;

  for (it = config()->control_configs().begin();
       it != config()->control_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kControlTag));
  }

  for (it = config()->event_configs().begin();
       it != config()->event_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kEventTag));
  }

  for (it = config()->video_configs().begin();
       it != config()->video_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kVideoTag));
  }

  for (it = config()->audio_configs().begin();
       it != config()->audio_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kAudioTag));
  }

  // Older endpoints require an initial-resolution tag, but otherwise ignore it.
  XmlElement* resolution_tag = new XmlElement(
      QName(kChromotingXmlNamespace, kDeprecatedResolutionTag));
  resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedWidthAttr), "640");
  resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedHeightAttr), "480");
  root->AddElement(resolution_tag);

  if (authenticator_message_.get()) {
    DCHECK(Authenticator::IsAuthenticatorMessage(authenticator_message_.get()));
    root->AddElement(new XmlElement(*authenticator_message_));
  }

  return root;
}

// static
// Adds the channel configs corresponding to |tag_name|,
// found in |element|, to |configs|.
bool ContentDescription::ParseChannelConfigs(
    const XmlElement* const element,
    const char tag_name[],
    bool codec_required,
    bool optional,
    std::vector<ChannelConfig>* const configs) {

  QName tag(kChromotingXmlNamespace, tag_name);
  const XmlElement* child = element->FirstNamed(tag);
  while (child) {
    ChannelConfig channel_config;
    if (ParseChannelConfig(child, codec_required, &channel_config)) {
      configs->push_back(channel_config);
    }
    child = child->NextNamed(tag);
  }
  if (optional && configs->empty()) {
      // If there's no mention of the tag, implicitly assume
      // TRANSPORT_NONE for the channel.
      configs->push_back(ChannelConfig());
  }
  return true;
}

// static
scoped_ptr<ContentDescription> ContentDescription::ParseXml(
    const XmlElement* element) {
  if (element->Name() != QName(kChromotingXmlNamespace, kDescriptionTag)) {
    LOG(ERROR) << "Invalid description: " << element->Str();
    return scoped_ptr<ContentDescription>();
  }
  scoped_ptr<CandidateSessionConfig> config(
      CandidateSessionConfig::CreateEmpty());
  if (!ParseChannelConfigs(element, kControlTag, false, false,
                           config->mutable_control_configs()) ||
      !ParseChannelConfigs(element, kEventTag, false, false,
                           config->mutable_event_configs()) ||
      !ParseChannelConfigs(element, kVideoTag, true, false,
                           config->mutable_video_configs()) ||
      !ParseChannelConfigs(element, kAudioTag, true, true,
                           config->mutable_audio_configs())) {
    return scoped_ptr<ContentDescription>();
  }

  scoped_ptr<XmlElement> authenticator_message;
  const XmlElement* child = Authenticator::FindAuthenticatorMessage(element);
  if (child)
    authenticator_message.reset(new XmlElement(*child));

  return scoped_ptr<ContentDescription>(
      new ContentDescription(config.Pass(), authenticator_message.Pass()));
}

}  // namespace protocol
}  // namespace remoting
<commit_msg>Fix chromoting client compatibility with M22 builds.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "remoting/protocol/content_description.h"

#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "remoting/base/constants.h"
#include "remoting/protocol/authenticator.h"
#include "remoting/protocol/name_value_map.h"
#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"

using buzz::QName;
using buzz::XmlElement;

namespace remoting {
namespace protocol {

const char ContentDescription::kChromotingContentName[] = "chromoting";

namespace {

const char kDefaultNs[] = "";

// Following constants are used to format session description in XML.
const char kDescriptionTag[] = "description";
const char kControlTag[] = "control";
const char kEventTag[] = "event";
const char kVideoTag[] = "video";
const char kAudioTag[] = "audio";
const char kDeprecatedResolutionTag[] = "initial-resolution";

const char kTransportAttr[] = "transport";
const char kVersionAttr[] = "version";
const char kCodecAttr[] = "codec";
const char kDeprecatedWidthAttr[] = "width";
const char kDeprecatedHeightAttr[] = "height";

const NameMapElement<ChannelConfig::TransportType> kTransports[] = {
  { ChannelConfig::TRANSPORT_STREAM, "stream" },
  { ChannelConfig::TRANSPORT_MUX_STREAM, "mux-stream" },
  { ChannelConfig::TRANSPORT_DATAGRAM, "datagram" },
  { ChannelConfig::TRANSPORT_NONE, "none" },
};

const NameMapElement<ChannelConfig::Codec> kCodecs[] = {
  { ChannelConfig::CODEC_VERBATIM, "verbatim" },
  { ChannelConfig::CODEC_VP8, "vp8" },
  { ChannelConfig::CODEC_ZIP, "zip" },
  { ChannelConfig::CODEC_OPUS, "opus" },
  { ChannelConfig::CODEC_SPEEX, "speex" },
};

// Format a channel configuration tag for chromotocol session description,
// e.g. for video channel:
//    <video transport="stream" version="1" codec="vp8" />
XmlElement* FormatChannelConfig(const ChannelConfig& config,
                                const std::string& tag_name) {
  XmlElement* result = new XmlElement(
      QName(kChromotingXmlNamespace, tag_name));

  result->AddAttr(QName(kDefaultNs, kTransportAttr),
                  ValueToName(kTransports, config.transport));

  // TODO(sergeyu): Here we add version and codec attributes even when transport
  // is set to NONE. This is needed for backward compatibility only. Fix this
  // code once the current stable version is able to cope with missing version
  // and codec attributes.
  // crbug.com/144053

  result->AddAttr(QName(kDefaultNs, kVersionAttr),
                  base::IntToString(config.version));

  if (config.codec != ChannelConfig::CODEC_UNDEFINED) {
    result->AddAttr(QName(kDefaultNs, kCodecAttr),
                    ValueToName(kCodecs, config.codec));
  }

  return result;
}

// Returns false if the element is invalid.
bool ParseChannelConfig(const XmlElement* element, bool codec_required,
                        ChannelConfig* config) {
  if (!NameToValue(
          kTransports, element->Attr(QName(kDefaultNs, kTransportAttr)),
          &config->transport)) {
    return false;
  }

  // Version is not required when transport="none".
  if (config->transport != ChannelConfig::TRANSPORT_NONE) {
    if (!base::StringToInt(element->Attr(QName(kDefaultNs, kVersionAttr)),
                           &config->version)) {
      return false;
    }

    // Codec is not required when transport="none".
    if (codec_required) {
      if (!NameToValue(kCodecs, element->Attr(QName(kDefaultNs, kCodecAttr)),
                       &config->codec)) {
        return false;
      }
    } else {
      config->codec = ChannelConfig::CODEC_UNDEFINED;
    }
  } else {
    config->version = 0;
    config->codec = ChannelConfig::CODEC_UNDEFINED;
  }

  return true;
}

}  // namespace

ContentDescription::ContentDescription(
    scoped_ptr<CandidateSessionConfig> config,
    scoped_ptr<buzz::XmlElement> authenticator_message)
    : candidate_config_(config.Pass()),
      authenticator_message_(authenticator_message.Pass()) {
}

ContentDescription::~ContentDescription() { }

ContentDescription* ContentDescription::Copy() const {
  if (!candidate_config_.get() || !authenticator_message_.get()) {
    return NULL;
  }
  scoped_ptr<XmlElement> message(new XmlElement(*authenticator_message_));
  return new ContentDescription(candidate_config_->Clone(), message.Pass());
}

// ToXml() creates content description for chromoting session. The
// description looks as follows:
//   <description xmlns="google:remoting">
//     <control transport="stream" version="1" />
//     <event transport="datagram" version="1" />
//     <video transport="stream" codec="vp8" version="1" />
//     <audio transport="stream" codec="opus" version="1" />
//     <authentication>
//      Message created by Authenticator implementation.
//     </authentication>
//   </description>
//
XmlElement* ContentDescription::ToXml() const {
  XmlElement* root = new XmlElement(
      QName(kChromotingXmlNamespace, kDescriptionTag), true);

  std::vector<ChannelConfig>::const_iterator it;

  for (it = config()->control_configs().begin();
       it != config()->control_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kControlTag));
  }

  for (it = config()->event_configs().begin();
       it != config()->event_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kEventTag));
  }

  for (it = config()->video_configs().begin();
       it != config()->video_configs().end(); ++it) {
    root->AddElement(FormatChannelConfig(*it, kVideoTag));
  }

  for (it = config()->audio_configs().begin();
       it != config()->audio_configs().end(); ++it) {
    ChannelConfig config = *it;
    if (config.transport == ChannelConfig::TRANSPORT_NONE) {
      // Older client and host may expect the following values for for the
      // version and codec for the NONE audio config.
      // TODO(sergeyu): Remove this code once the current version supports.
      // crbug.com/144053
      config.version = 2;
      config.codec = ChannelConfig::CODEC_VERBATIM;
    }
    root->AddElement(FormatChannelConfig(config, kAudioTag));
  }

  // Older endpoints require an initial-resolution tag, but otherwise ignore it.
  XmlElement* resolution_tag = new XmlElement(
      QName(kChromotingXmlNamespace, kDeprecatedResolutionTag));
  resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedWidthAttr), "640");
  resolution_tag->AddAttr(QName(kDefaultNs, kDeprecatedHeightAttr), "480");
  root->AddElement(resolution_tag);

  if (authenticator_message_.get()) {
    DCHECK(Authenticator::IsAuthenticatorMessage(authenticator_message_.get()));
    root->AddElement(new XmlElement(*authenticator_message_));
  }

  return root;
}

// static
// Adds the channel configs corresponding to |tag_name|,
// found in |element|, to |configs|.
bool ContentDescription::ParseChannelConfigs(
    const XmlElement* const element,
    const char tag_name[],
    bool codec_required,
    bool optional,
    std::vector<ChannelConfig>* const configs) {

  QName tag(kChromotingXmlNamespace, tag_name);
  const XmlElement* child = element->FirstNamed(tag);
  while (child) {
    ChannelConfig channel_config;
    if (ParseChannelConfig(child, codec_required, &channel_config)) {
      configs->push_back(channel_config);
    }
    child = child->NextNamed(tag);
  }
  if (optional && configs->empty()) {
      // If there's no mention of the tag, implicitly assume
      // TRANSPORT_NONE for the channel.
      configs->push_back(ChannelConfig());
  }
  return true;
}

// static
scoped_ptr<ContentDescription> ContentDescription::ParseXml(
    const XmlElement* element) {
  if (element->Name() != QName(kChromotingXmlNamespace, kDescriptionTag)) {
    LOG(ERROR) << "Invalid description: " << element->Str();
    return scoped_ptr<ContentDescription>();
  }
  scoped_ptr<CandidateSessionConfig> config(
      CandidateSessionConfig::CreateEmpty());
  if (!ParseChannelConfigs(element, kControlTag, false, false,
                           config->mutable_control_configs()) ||
      !ParseChannelConfigs(element, kEventTag, false, false,
                           config->mutable_event_configs()) ||
      !ParseChannelConfigs(element, kVideoTag, true, false,
                           config->mutable_video_configs()) ||
      !ParseChannelConfigs(element, kAudioTag, true, true,
                           config->mutable_audio_configs())) {
    return scoped_ptr<ContentDescription>();
  }

  scoped_ptr<XmlElement> authenticator_message;
  const XmlElement* child = Authenticator::FindAuthenticatorMessage(element);
  if (child)
    authenticator_message.reset(new XmlElement(*child));

  return scoped_ptr<ContentDescription>(
      new ContentDescription(config.Pass(), authenticator_message.Pass()));
}

}  // namespace protocol
}  // namespace remoting
<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_LA_SOLVER_EIGEN_HH
#define DUNE_STUFF_LA_SOLVER_EIGEN_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAVE_EIGEN

#include <Eigen/SparseCore>
#include <Eigen/IterativeLinearSolvers>
#include <Eigen/SparseCholesky>

#include <dune/stuff/common/color.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/la/container/eigen.hh>

#include "interface.hh"

namespace Dune {
namespace Stuff {
namespace LA {

template <class MatrixImp, class VectorImp>
struct IsEigenMV {
  typedef typename std::is_base_of< Dune::Stuff::LA::EigenMatrixInterface<typename MatrixImp::Traits>, MatrixImp>::type Mtype;
  typedef typename std::is_base_of< Dune::Stuff::LA::EigenVectorInterface<typename VectorImp::Traits>, VectorImp>::type Vtype;
  static constexpr bool value = Mtype::value && Vtype::value;
};

//! \attention Slow!
//! \todo Implement via Eigen::CG and identity preconditioner!
template< class MatrixImp, class VectorImp >
class CgSolver< MatrixImp, VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type>
  : public SolverInterface< MatrixImp, VectorImp>
{
public:
  typedef SolverInterface< MatrixImp, VectorImp>
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  CgSolver()
  {
    DSC_LOG_DEBUG << "\n" << Dune::Stuff::Common::colorString("WARNING:")
                  << " this solver is believed to be slow! " << std::flush;
  }

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    auto& x_i = solutionVector.backend();
    const auto& b = rhsVector.backend();
    const auto& A = systemMatrix.backend();
    const int cols = A.cols();
    size_type iteration(1);
    const size_type maxIter = description.get<size_type>("maxIter");
    const ElementType precision = description.get<ElementType>("precision");
    ElementType rho(0), rho_prev(1), beta, alpha;
    const ElementType tolerance = precision * precision * b.squaredNorm();
    typedef typename DSL::EigenDenseVector<typename VectorType::ElementType>::BackendType RealEigenVector;
    RealEigenVector residuum = b - A * x_i;
    RealEigenVector correction_p(cols);
    RealEigenVector correction_q(cols);
    rho = residuum.squaredNorm();
    while (iteration <= maxIter) {
      if (iteration == 1) {
          correction_p = residuum;
      }
      else {
          beta = rho / rho_prev;
          correction_p = residuum + beta * correction_p;
      }
      correction_q.noalias() = A * correction_p;
      alpha = rho / correction_p.dot(correction_q);
      x_i += alpha * correction_p;
      residuum -= alpha * correction_q;
      rho = residuum.squaredNorm();
      if (rho < tolerance)
          return 0;
      rho_prev = rho;
    }
    return 1;
  } // virtual bool apply(...)
}; // class Cg

template< class MatrixImp, class VectorImp >
class CgDiagonalSolver< MatrixImp, VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type>
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  CgDiagonalSolver()
  {
    DSC_LOG_DEBUG << "\n" << Dune::Stuff::Common::colorString("WARNING:", Dune::Stuff::Common::Colors::red)
                  << " this solver is believed to produce utterly wrong results! " << std::flush;
  }

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    typedef ::Eigen::ConjugateGradient< typename MatrixType::BackendType,
                                        ::Eigen::Lower,
                                        ::Eigen::DiagonalPreconditioner< ElementType > > EigenSolverType;
    EigenSolverType eigenSolver(systemMatrix.backend());
    eigenSolver.setMaxIterations(description.get<size_type>("maxIter"));
    eigenSolver.setTolerance(description.get<ElementType>("precision"));
    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
    return BaseType::translateInfo(eigenSolver.info());
  } // virtual bool apply(...)
}; // class CgDiagonal

template< class MatrixImp, class VectorImp >
class BicgstabSolver< MatrixImp,
                VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    typedef ::Eigen::BiCGSTAB< typename MatrixType::BackendType, ::Eigen::IdentityPreconditioner > EigenSolverType;
    EigenSolverType eigenSolver(systemMatrix.backend());
    eigenSolver.setMaxIterations(description.get<size_type>("maxIter"));
    eigenSolver.setTolerance(description.get<ElementType>("precision"));
    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
    return BaseType::translateInfo(eigenSolver.info());
  } // virtual bool apply(...)
}; // class Bicgstab

template< class MatrixImp, class VectorImp >
class BicgstabDiagonalSolver< MatrixImp,
                        VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    typedef ::Eigen::BiCGSTAB< typename MatrixType::BackendType, ::Eigen::DiagonalPreconditioner< ElementType > > EigenSolverType;
    EigenSolverType eigenSolver(systemMatrix.backend());
    eigenSolver.setMaxIterations(description.get<size_type>("maxIter"));
    eigenSolver.setTolerance(description.get<ElementType>("precision"));
    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
    return BaseType::translateInfo(eigenSolver.info());
  } // virtual bool apply(...)static_assert
}; // class BicgstabDiagonal

template< class MatrixImp, class VectorImp >
class BicgstabILUTSolver< MatrixImp,
                    VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  static Dune::ParameterTree defaultSettings()
  {
    Dune::ParameterTree description = BaseType::defaultIterativeSettings();
    description["precision"] = "1.0e-8";
    description["preconditioner.dropTol"] = Eigen::NumTraits< double >::dummy_precision();
    description["preconditioner.fillFactor"] = 10;
    return description;
  } // Dune::ParameterTree defaultSettings()

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = defaultSettings()) const
  {
    typedef ::Eigen::BiCGSTAB< typename MatrixType::BackendType, ::Eigen::IncompleteLUT< ElementType > > EigenSolverType;
    EigenSolverType solver(systemMatrix.backend());
    // configure solver and preconditioner
    solver.setTolerance(description.get<double>("precision"));
    solver.setMaxIterations(description.get<size_type>("maxIter", solutionVector.size()));
    solver.preconditioner().setDroptol(description.get<double>("preconditioner.dropTol"));
    solver.preconditioner().setFillfactor(description.get<double>("preconditioner.fillFactor"));

    solutionVector.backend() = solver.solve(rhsVector.backend());
    return BaseType::translateInfo(solver.info());
  } // virtual bool apply(...)
}; // class BicgstabILUT

/** Direct solvers seem below are broken, throwing weird compiler errors on solution assignment.
  */

//template< class MatrixImp, class VectorImp >
//class SimplicialLLT< MatrixImp,
//                      VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
//  : public Interface< MatrixImp,
//                      VectorImp >
//{
//public:
//  typedef Interface<  MatrixImp,
//                      VectorImp >
//      BaseType;

//  typedef typename BaseType::MatrixType MatrixType;
//  typedef typename BaseType::VectorType VectorType;
//  typedef typename BaseType::ElementType ElementType;
//  typedef typename BaseType::size_type size_type;

//  SimplicialLLT()
//  {}

//  virtual size_type apply(const MatrixType& systemMatrix,
//                          const VectorType& rhsVector,
//                          VectorType& solutionVector,
//                          const size_type /*maxIter*/ = 5000,
//                          const ElementType /*precision*/ = 1e-12,
//                          const Dune::ParameterTree /*description*/ = Dune::ParameterTree()) const
//  {
//    typedef ::Eigen::SimplicialLLT< typename MatrixType::BackendType, ::Eigen::Lower > EigenSolverType;
//    EigenSolverType eigenSolver(systemMatrix.backend());
//    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
//    const ::Eigen::ComputationInfo info = eigenSolver.info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)
//}; // class SimplicialLLT

//template< class MatrixImp, class VectorImp >
//class SimplicialLDLTSolver< MatrixImp,
//                      VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
//  : public SolverInterface< MatrixImp,
//                      VectorImp >
//{
//public:
//  typedef SolverInterface<  MatrixImp,
//                      VectorImp >
//      BaseType;

//  typedef typename BaseType::MatrixType MatrixType;
//  typedef typename BaseType::VectorType VectorType;
//  typedef typename BaseType::ElementType ElementType;
//  typedef typename BaseType::size_type size_type;

//  SimplicialLDLTSolver()
//  {}

//  virtual size_type apply(const MatrixType& systemMatrix,
//                          const VectorType& rhsVector,
//                          VectorType& solutionVector,
//                          const Dune::ParameterTree /*description*/ = Dune::ParameterTree()) const
//  {
//    auto ko = const_cast<typename MatrixType::BackendType&>(systemMatrix.backend());
////    typedef ::Eigen::SimplicialLDLT< typename MatrixType::BackendType> EigenSolverType;
//    typedef ::Eigen::SimplicialCholesky<const typename MatrixType::BackendType> EigenSolverType;
//    EigenSolverType eigenSolver;
//    eigenSolver.compute(ko);
//    typename DSL::EigenDenseVector<typename VectorType::ElementType>::BackendType retval = eigenSolver.solve(rhsVector.backend());

////    retval.evalTo(solutionVector.backend());
////    solutionVector.backend() = retval;
//    const ::Eigen::ComputationInfo info = eigenSolver.info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)
//}; // class SimplicialLDLT

} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_STUFF_LA_SOLVER_EIGEN_HH
<commit_msg>[la.solver] fixes default bicg settings<commit_after>#ifndef DUNE_STUFF_LA_SOLVER_EIGEN_HH
#define DUNE_STUFF_LA_SOLVER_EIGEN_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAVE_EIGEN

#include <Eigen/SparseCore>
#include <Eigen/IterativeLinearSolvers>
#include <Eigen/SparseCholesky>

#include <dune/stuff/common/color.hh>
#include <dune/stuff/common/parameter/configcontainer.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/aliases.hh>
#include <dune/stuff/la/container/eigen.hh>

#include "interface.hh"

namespace Dune {
namespace Stuff {
namespace LA {

template <class MatrixImp, class VectorImp>
struct IsEigenMV {
  typedef typename std::is_base_of< Dune::Stuff::LA::EigenMatrixInterface<typename MatrixImp::Traits>, MatrixImp>::type Mtype;
  typedef typename std::is_base_of< Dune::Stuff::LA::EigenVectorInterface<typename VectorImp::Traits>, VectorImp>::type Vtype;
  static constexpr bool value = Mtype::value && Vtype::value;
};

//! \attention Slow!
//! \todo Implement via Eigen::CG and identity preconditioner!
template< class MatrixImp, class VectorImp >
class CgSolver< MatrixImp, VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type>
  : public SolverInterface< MatrixImp, VectorImp>
{
public:
  typedef SolverInterface< MatrixImp, VectorImp>
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  CgSolver()
  {
    DSC_LOG_DEBUG << "\n" << Dune::Stuff::Common::colorString("WARNING:")
                  << " this solver is believed to be slow! " << std::flush;
  }

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    auto& x_i = solutionVector.backend();
    const auto& b = rhsVector.backend();
    const auto& A = systemMatrix.backend();
    const int cols = A.cols();
    size_type iteration(1);
    const size_type maxIter = description.get<size_type>("maxIter");
    const ElementType precision = description.get<ElementType>("precision");
    ElementType rho(0), rho_prev(1), beta, alpha;
    const ElementType tolerance = precision * precision * b.squaredNorm();
    typedef typename DSL::EigenDenseVector<typename VectorType::ElementType>::BackendType RealEigenVector;
    RealEigenVector residuum = b - A * x_i;
    RealEigenVector correction_p(cols);
    RealEigenVector correction_q(cols);
    rho = residuum.squaredNorm();
    while (iteration <= maxIter) {
      if (iteration == 1) {
          correction_p = residuum;
      }
      else {
          beta = rho / rho_prev;
          correction_p = residuum + beta * correction_p;
      }
      correction_q.noalias() = A * correction_p;
      alpha = rho / correction_p.dot(correction_q);
      x_i += alpha * correction_p;
      residuum -= alpha * correction_q;
      rho = residuum.squaredNorm();
      if (rho < tolerance)
          return 0;
      rho_prev = rho;
    }
    return 1;
  } // virtual bool apply(...)
}; // class Cg

template< class MatrixImp, class VectorImp >
class CgDiagonalSolver< MatrixImp, VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type>
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  CgDiagonalSolver()
  {
    DSC_LOG_DEBUG << "\n" << Dune::Stuff::Common::colorString("WARNING:", Dune::Stuff::Common::Colors::red)
                  << " this solver is believed to produce utterly wrong results! " << std::flush;
  }

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    typedef ::Eigen::ConjugateGradient< typename MatrixType::BackendType,
                                        ::Eigen::Lower,
                                        ::Eigen::DiagonalPreconditioner< ElementType > > EigenSolverType;
    EigenSolverType eigenSolver(systemMatrix.backend());
    eigenSolver.setMaxIterations(description.get<size_type>("maxIter"));
    eigenSolver.setTolerance(description.get<ElementType>("precision"));
    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
    return BaseType::translateInfo(eigenSolver.info());
  } // virtual bool apply(...)
}; // class CgDiagonal

template< class MatrixImp, class VectorImp >
class BicgstabSolver< MatrixImp,
                VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    typedef ::Eigen::BiCGSTAB< typename MatrixType::BackendType, ::Eigen::IdentityPreconditioner > EigenSolverType;
    EigenSolverType eigenSolver(systemMatrix.backend());
    eigenSolver.setMaxIterations(description.get<size_type>("maxIter"));
    eigenSolver.setTolerance(description.get<ElementType>("precision"));
    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
    return BaseType::translateInfo(eigenSolver.info());
  } // virtual bool apply(...)
}; // class Bicgstab

template< class MatrixImp, class VectorImp >
class BicgstabDiagonalSolver< MatrixImp,
                        VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = BaseType::defaultIterativeSettings()) const
  {
    typedef ::Eigen::BiCGSTAB< typename MatrixType::BackendType, ::Eigen::DiagonalPreconditioner< ElementType > > EigenSolverType;
    EigenSolverType eigenSolver(systemMatrix.backend());
    eigenSolver.setMaxIterations(description.get<size_type>("maxIter"));
    eigenSolver.setTolerance(description.get<ElementType>("precision"));
    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
    return BaseType::translateInfo(eigenSolver.info());
  } // virtual bool apply(...)static_assert
}; // class BicgstabDiagonal

template< class MatrixImp, class VectorImp >
class BicgstabILUTSolver< MatrixImp,
                    VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
  : public SolverInterface< MatrixImp,
                      VectorImp >
{
public:
  typedef SolverInterface<  MatrixImp,
                      VectorImp >
      BaseType;

  typedef typename BaseType::MatrixType MatrixType;
  typedef typename BaseType::VectorType VectorType;
  typedef typename BaseType::ElementType ElementType;
  typedef typename BaseType::size_type size_type;

  static Dune::ParameterTree defaultSettings()
  {
    Dune::ParameterTree description = BaseType::defaultIterativeSettings();
    description["precision"] = "1.0e-8";
    description["preconditioner.dropTol"] = "1e-4";
    description["preconditioner.fillFactor"] = "10";
    return description;
  } // Dune::ParameterTree defaultSettings()

  virtual size_type apply(const MatrixType& systemMatrix,
                          const VectorType& rhsVector,
                          VectorType& solutionVector,
                          const Dune::ParameterTree description = defaultSettings()) const
  {
    typedef ::Eigen::BiCGSTAB< typename MatrixType::BackendType, ::Eigen::IncompleteLUT< ElementType > > EigenSolverType;
    EigenSolverType solver(systemMatrix.backend());
    // configure solver and preconditioner
    solver.setTolerance(description.get<double>("precision"));
    solver.setMaxIterations(description.get<size_type>("maxIter", solutionVector.size()));
    solver.preconditioner().setDroptol(description.get<double>("preconditioner.dropTol"));
    solver.preconditioner().setFillfactor(description.get<double>("preconditioner.fillFactor"));

    solutionVector.backend() = solver.solve(rhsVector.backend());
    return BaseType::translateInfo(solver.info());
  } // virtual bool apply(...)
}; // class BicgstabILUT

/** Direct solvers seem below are broken, throwing weird compiler errors on solution assignment.
  */

//template< class MatrixImp, class VectorImp >
//class SimplicialLLT< MatrixImp,
//                      VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
//  : public Interface< MatrixImp,
//                      VectorImp >
//{
//public:
//  typedef Interface<  MatrixImp,
//                      VectorImp >
//      BaseType;

//  typedef typename BaseType::MatrixType MatrixType;
//  typedef typename BaseType::VectorType VectorType;
//  typedef typename BaseType::ElementType ElementType;
//  typedef typename BaseType::size_type size_type;

//  SimplicialLLT()
//  {}

//  virtual size_type apply(const MatrixType& systemMatrix,
//                          const VectorType& rhsVector,
//                          VectorType& solutionVector,
//                          const size_type /*maxIter*/ = 5000,
//                          const ElementType /*precision*/ = 1e-12,
//                          const Dune::ParameterTree /*description*/ = Dune::ParameterTree()) const
//  {
//    typedef ::Eigen::SimplicialLLT< typename MatrixType::BackendType, ::Eigen::Lower > EigenSolverType;
//    EigenSolverType eigenSolver(systemMatrix.backend());
//    solutionVector.backend() = eigenSolver.solve(rhsVector.backend());
//    const ::Eigen::ComputationInfo info = eigenSolver.info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)
//}; // class SimplicialLLT

//template< class MatrixImp, class VectorImp >
//class SimplicialLDLTSolver< MatrixImp,
//                      VectorImp, typename std::enable_if<IsEigenMV<MatrixImp, VectorImp>::value>::type >
//  : public SolverInterface< MatrixImp,
//                      VectorImp >
//{
//public:
//  typedef SolverInterface<  MatrixImp,
//                      VectorImp >
//      BaseType;

//  typedef typename BaseType::MatrixType MatrixType;
//  typedef typename BaseType::VectorType VectorType;
//  typedef typename BaseType::ElementType ElementType;
//  typedef typename BaseType::size_type size_type;

//  SimplicialLDLTSolver()
//  {}

//  virtual size_type apply(const MatrixType& systemMatrix,
//                          const VectorType& rhsVector,
//                          VectorType& solutionVector,
//                          const Dune::ParameterTree /*description*/ = Dune::ParameterTree()) const
//  {
//    auto ko = const_cast<typename MatrixType::BackendType&>(systemMatrix.backend());
////    typedef ::Eigen::SimplicialLDLT< typename MatrixType::BackendType> EigenSolverType;
//    typedef ::Eigen::SimplicialCholesky<const typename MatrixType::BackendType> EigenSolverType;
//    EigenSolverType eigenSolver;
//    eigenSolver.compute(ko);
//    typename DSL::EigenDenseVector<typename VectorType::ElementType>::BackendType retval = eigenSolver.solve(rhsVector.backend());

////    retval.evalTo(solutionVector.backend());
////    solutionVector.backend() = retval;
//    const ::Eigen::ComputationInfo info = eigenSolver.info();
//    return (info == ::Eigen::Success);
//  } // virtual bool apply(...)
//}; // class SimplicialLDLT

} // namespace LA
} // namespace Stuff
} // namespace Dune

#endif // HAVE_EIGEN

#endif // DUNE_STUFF_LA_SOLVER_EIGEN_HH
<|endoftext|>