<commit_before>//
//  cocTimer.h
//  Created by Lukasz Karluk on 10/10/2015.
//  http://codeoncanvas.cc
//

#include "cocSwipe.h"

namespace coc {

using namespace std;
using namespace glm;

//--------------------------------------------------------------
Swipe::Swipe() {

    swipePixelDistanceThreshold = 50;
    swipePixelVelocityThreshold = 100;

    reset();
}

Swipe::~Swipe() {
    //
}

void Swipe::setSwipeArea(const coc::Rect & rect) {
    swipeArea = rect;
}

void Swipe::setSwipeArea(float x, float y, float w, float h) {
    swipeArea.setX(x);
    swipeArea.setY(y);
    swipeArea.setW(w);
    swipeArea.setH(h);
}

void Swipe::setSwipePixelDistanceThreshold(float value) {
    swipePixelDistanceThreshold = value;
}

void Swipe::setSwipePixelVelocityThreshold(float value) {
    swipePixelVelocityThreshold = value;
}

//--------------------------------------------------------------
void Swipe::update(double _optionalTimeElapsedSinceLastUpdateInSeconds) {

    bGestureFoundNew = false; // clear on every new frame.

    //----------------------------------------------------------
    bool bSwipeStopped = false;
    if(points.size() > 0) {
        const SwipePoint & pointLast = points[points.size()-1];
        bSwipeStopped = (pointLast.type == SwipePoint::TypeUp);
        if(bSwipeStopped == true) {
            bool bDownNew = false;
            for(int i=0; i<pointsNew.size(); i++) {
                const SwipePoint & pointNew = pointsNew[i];
                if(pointNew.type == SwipePoint::TypeDown) {
                    bDownNew = true;
                    break;
                }
            }
            if(bDownNew == true) {
                bSwipeStopped = false;
                reset();
            }
        }
    }

    if(bSwipeStopped == true) {
        return;
    }

    bool bSwipeStarted = true;
    bSwipeStarted = bSwipeStarted && (points.size() > 0);

    bool bSwipeStartedNow = true;
    bSwipeStartedNow = bSwipeStartedNow && (bSwipeStarted == false);
    bSwipeStartedNow = bSwipeStartedNow && (pointsNew.size() > 0);
    if(bSwipeStartedNow == true) {
        bSwipeStartedNow = bSwipeStartedNow && (pointsNew[0].type == SwipePoint::TypeDown);
    }

    bool bUpdate = false;
    bUpdate = bUpdate || (bSwipeStarted == true);
    bUpdate = bUpdate || (bSwipeStartedNow == true);
    if(bUpdate == false) {
        return;
    }

    double timeElapsedSinceLastUpdateInSeconds = _optionalTimeElapsedSinceLastUpdateInSeconds;
    if(timeElapsedSinceLastUpdateInSeconds < 0.0) {
        timeElapsedSinceLastUpdateInSeconds = coc::getTimeElapsedSinceLastFrame();
    }

    if(bSwipeStartedNow == true) {
        swipeTime = 0;
    } else {
        swipeTime += timeElapsedSinceLastUpdateInSeconds;
    }

    if(pointsNew.size() == 0) {
        return;
    }

    //----------------------------------------------------------
    bool bFound = false;
    SwipePoint pointNew;

    if(bSwipeStartedNow == true) {

        // look for touch down.

        for(int i=0; i<pointsNew.size(); i++) {
            if(pointsNew[i].type == SwipePoint::TypeDown) {
                pointNew = pointsNew[i];
                bFound = true;
                break;
            }
        }

    } else {

        // look for touch up first.

        for(int i=pointsNew.size()-1; i>=0; i--) {
            if(pointsNew[i].type == SwipePoint::TypeUp) {

                bool bSame = false;
                if(points.size() > 0) {
                    const SwipePoint & pointLast = points[points.size()-1];
                    bSame = true;
                    bSame = bSame && ((int)pointsNew[i].position.x == (int)pointLast.position.x);
                    bSame = bSame && ((int)pointsNew[i].position.y == (int)pointLast.position.y);
                }
                if(bSame == true) {
                    // remove last move point and replace with up point.
                    points.erase(points.begin() + points.size()-1);
                }

                pointNew = pointsNew[i];
                bFound = true;
                break;
            }
        }

        // look for touch moved first.

        if(bFound == false) {
            for(int i=pointsNew.size()-1; i>=0; i--) {
                if(pointsNew[i].type == SwipePoint::TypeMoved) {

                    bool bSame = false;
                    if(points.size() > 0) {
                        const SwipePoint & pointLast = points[points.size()-1];
                        bSame = true;
                        bSame = bSame && ((int)pointsNew[i].position.x == (int)pointLast.position.x);
                        bSame = bSame && ((int)pointsNew[i].position.y == (int)pointLast.position.y);
                    }
                    if(bSame == true) {
                        continue;
                    }

                    pointNew = pointsNew[i];
                    bFound = true;
                    break;
                }
            }
        }
    }

    pointsNew.clear();

    if(bFound == false) {
        return;
    }

    points.push_back(pointNew);
    SwipePoint & point = points.back();
    point.time = swipeTime;

    if(points.size() > 1) {

        const SwipePoint & pointLast = points[points.size()-2];
        point.velocity = (point.position - pointLast.position) / (point.time - pointLast.time);
        point.velocityScale = length(point.velocity) / swipePixelVelocityThreshold;

        point.angleDeg = coc::angleClockwise(point.velocity);
        point.angleDeg = (point.angleDeg / (float)PI) * 180.0;
    }

    //----------------------------------------------------------
    if(gestureStartIndex == -1) {
        gestureStartIndex = points.size() - 1;
    }

    SwipePoint gesturePointStart;
    SwipeDirection gestureDirectionStart;

    for(int i=gestureStartIndex; i<points.size(); i++) {
        if(i == gestureStartIndex) {
            gesturePointStart = points[i];
            gestureDirectionStart = getDirectionFromAngle(gesturePointStart.angleDeg);
        }

        const SwipePoint & gesturePoint = points[i];
        if(gesturePoint.velocityScale < 1.0) {
            gestureDirection = SwipeDirectionUndefined;
            gestureStartIndex = -1;
            break;
        }

        SwipeDirection gestureDirectionNew = getDirectionFromAngle(gesturePoint.angleDeg);
        if(gestureDirectionNew != gestureDirectionStart) {
            gestureDirection = SwipeDirectionUndefined;
            gestureStartIndex = -1;
            break;
        }

        float dist = distance(gesturePoint.position, gesturePointStart.position);
        if(dist >= swipePixelDistanceThreshold) {
            bGestureFoundNew = gestureDirection != gestureDirectionNew;
            gestureDirection = gestureDirectionNew;
        }
    }
}

void Swipe::reset() {

    points.clear();
    swipeTime = 0;

    gestureDirection = SwipeDirectionUndefined;
    gestureStartIndex = -1;
}

//--------------------------------------------------------------
void Swipe::pointDown(float x, float y) {
    pointNew(x, y, SwipePoint::TypeDown);
}

void Swipe::pointMoved(float x, float y) {
    pointNew(x, y, SwipePoint::TypeMoved);
}

void Swipe::pointUp(float x, float y) {
    pointNew(x, y, SwipePoint::TypeUp);
}

void Swipe::pointNew(float x, float y, SwipePoint::Type type) {
    pointsNew.push_back(SwipePoint());
    SwipePoint & point = pointsNew.back();
    point.position = vec2(x, y);
    point.type = type;
}

//--------------------------------------------------------------
bool Swipe::hasFoundSwipeGesture() const {
    return bGestureFoundNew;
}

SwipeDirection Swipe::getSwipeGestureDirection() const {
    return gestureDirection;
}

const std::vector<SwipePoint> & Swipe::getPoints() const {
    return points;
}

float Swipe::getSwipeTime() const {
    return swipeTime;
}

//--------------------------------------------------------------
SwipeDirection Swipe::getDirectionFromAngle(float angleDeg) const {
    SwipeDirection dir;
    if((angleDeg > 315 && angleDeg <= 360) || (angleDeg >= 0 && angleDeg <= 45)) {
        dir = SwipeDirectionUp;
    } else if(angleDeg > 45 && angleDeg <= 135) {
        dir = SwipeDirectionRight;
    } else if(angleDeg > 135 && angleDeg <= 225) {
        dir = SwipeDirectionDown;
    } else if(angleDeg > 225 && angleDeg <= 315) {
        dir = SwipeDirectionLeft;
    }
    return dir;
}

}<commit_msg>PI fix<commit_after>//
//  cocTimer.h
//  Created by Lukasz Karluk on 10/10/2015.
//  http://codeoncanvas.cc
//

#include "cocSwipe.h"

namespace coc {

using namespace std;
using namespace glm;

//--------------------------------------------------------------
Swipe::Swipe() {

    swipePixelDistanceThreshold = 50;
    swipePixelVelocityThreshold = 100;

    reset();
}

Swipe::~Swipe() {
    //
}

void Swipe::setSwipeArea(const coc::Rect & rect) {
    swipeArea = rect;
}

void Swipe::setSwipeArea(float x, float y, float w, float h) {
    swipeArea.setX(x);
    swipeArea.setY(y);
    swipeArea.setW(w);
    swipeArea.setH(h);
}

void Swipe::setSwipePixelDistanceThreshold(float value) {
    swipePixelDistanceThreshold = value;
}

void Swipe::setSwipePixelVelocityThreshold(float value) {
    swipePixelVelocityThreshold = value;
}

//--------------------------------------------------------------
void Swipe::update(double _optionalTimeElapsedSinceLastUpdateInSeconds) {

    bGestureFoundNew = false; // clear on every new frame.

    //----------------------------------------------------------
    bool bSwipeStopped = false;
    if(points.size() > 0) {
        const SwipePoint & pointLast = points[points.size()-1];
        bSwipeStopped = (pointLast.type == SwipePoint::TypeUp);
        if(bSwipeStopped == true) {
            bool bDownNew = false;
            for(int i=0; i<pointsNew.size(); i++) {
                const SwipePoint & pointNew = pointsNew[i];
                if(pointNew.type == SwipePoint::TypeDown) {
                    bDownNew = true;
                    break;
                }
            }
            if(bDownNew == true) {
                bSwipeStopped = false;
                reset();
            }
        }
    }

    if(bSwipeStopped == true) {
        return;
    }

    bool bSwipeStarted = true;
    bSwipeStarted = bSwipeStarted && (points.size() > 0);

    bool bSwipeStartedNow = true;
    bSwipeStartedNow = bSwipeStartedNow && (bSwipeStarted == false);
    bSwipeStartedNow = bSwipeStartedNow && (pointsNew.size() > 0);
    if(bSwipeStartedNow == true) {
        bSwipeStartedNow = bSwipeStartedNow && (pointsNew[0].type == SwipePoint::TypeDown);
    }

    bool bUpdate = false;
    bUpdate = bUpdate || (bSwipeStarted == true);
    bUpdate = bUpdate || (bSwipeStartedNow == true);
    if(bUpdate == false) {
        return;
    }

    double timeElapsedSinceLastUpdateInSeconds = _optionalTimeElapsedSinceLastUpdateInSeconds;
    if(timeElapsedSinceLastUpdateInSeconds < 0.0) {
        timeElapsedSinceLastUpdateInSeconds = coc::getTimeElapsedSinceLastFrame();
    }

    if(bSwipeStartedNow == true) {
        swipeTime = 0;
    } else {
        swipeTime += timeElapsedSinceLastUpdateInSeconds;
    }

    if(pointsNew.size() == 0) {
        return;
    }

    //----------------------------------------------------------
    bool bFound = false;
    SwipePoint pointNew;

    if(bSwipeStartedNow == true) {

        // look for touch down.

        for(int i=0; i<pointsNew.size(); i++) {
            if(pointsNew[i].type == SwipePoint::TypeDown) {
                pointNew = pointsNew[i];
                bFound = true;
                break;
            }
        }

    } else {

        // look for touch up first.

        for(int i=pointsNew.size()-1; i>=0; i--) {
            if(pointsNew[i].type == SwipePoint::TypeUp) {

                bool bSame = false;
                if(points.size() > 0) {
                    const SwipePoint & pointLast = points[points.size()-1];
                    bSame = true;
                    bSame = bSame && ((int)pointsNew[i].position.x == (int)pointLast.position.x);
                    bSame = bSame && ((int)pointsNew[i].position.y == (int)pointLast.position.y);
                }
                if(bSame == true) {
                    // remove last move point and replace with up point.
                    points.erase(points.begin() + points.size()-1);
                }

                pointNew = pointsNew[i];
                bFound = true;
                break;
            }
        }

        // look for touch moved first.

        if(bFound == false) {
            for(int i=pointsNew.size()-1; i>=0; i--) {
                if(pointsNew[i].type == SwipePoint::TypeMoved) {

                    bool bSame = false;
                    if(points.size() > 0) {
                        const SwipePoint & pointLast = points[points.size()-1];
                        bSame = true;
                        bSame = bSame && ((int)pointsNew[i].position.x == (int)pointLast.position.x);
                        bSame = bSame && ((int)pointsNew[i].position.y == (int)pointLast.position.y);
                    }
                    if(bSame == true) {
                        continue;
                    }

                    pointNew = pointsNew[i];
                    bFound = true;
                    break;
                }
            }
        }
    }

    pointsNew.clear();

    if(bFound == false) {
        return;
    }

    points.push_back(pointNew);
    SwipePoint & point = points.back();
    point.time = swipeTime;

    if(points.size() > 1) {

        const SwipePoint & pointLast = points[points.size()-2];
        point.velocity = (point.position - pointLast.position) / (point.time - pointLast.time);
        point.velocityScale = length(point.velocity) / swipePixelVelocityThreshold;

        point.angleDeg = coc::angleClockwise(point.velocity);
        point.angleDeg = (point.angleDeg / (float)M_PI) * 180.0;
    }

    //----------------------------------------------------------
    if(gestureStartIndex == -1) {
        gestureStartIndex = points.size() - 1;
    }

    SwipePoint gesturePointStart;
    SwipeDirection gestureDirectionStart;

    for(int i=gestureStartIndex; i<points.size(); i++) {
        if(i == gestureStartIndex) {
            gesturePointStart = points[i];
            gestureDirectionStart = getDirectionFromAngle(gesturePointStart.angleDeg);
        }

        const SwipePoint & gesturePoint = points[i];
        if(gesturePoint.velocityScale < 1.0) {
            gestureDirection = SwipeDirectionUndefined;
            gestureStartIndex = -1;
            break;
        }

        SwipeDirection gestureDirectionNew = getDirectionFromAngle(gesturePoint.angleDeg);
        if(gestureDirectionNew != gestureDirectionStart) {
            gestureDirection = SwipeDirectionUndefined;
            gestureStartIndex = -1;
            break;
        }

        float dist = distance(gesturePoint.position, gesturePointStart.position);
        if(dist >= swipePixelDistanceThreshold) {
            bGestureFoundNew = gestureDirection != gestureDirectionNew;
            gestureDirection = gestureDirectionNew;
        }
    }
}

void Swipe::reset() {

    points.clear();
    swipeTime = 0;

    gestureDirection = SwipeDirectionUndefined;
    gestureStartIndex = -1;
}

//--------------------------------------------------------------
void Swipe::pointDown(float x, float y) {
    pointNew(x, y, SwipePoint::TypeDown);
}

void Swipe::pointMoved(float x, float y) {
    pointNew(x, y, SwipePoint::TypeMoved);
}

void Swipe::pointUp(float x, float y) {
    pointNew(x, y, SwipePoint::TypeUp);
}

void Swipe::pointNew(float x, float y, SwipePoint::Type type) {
    pointsNew.push_back(SwipePoint());
    SwipePoint & point = pointsNew.back();
    point.position = vec2(x, y);
    point.type = type;
}

//--------------------------------------------------------------
bool Swipe::hasFoundSwipeGesture() const {
    return bGestureFoundNew;
}

SwipeDirection Swipe::getSwipeGestureDirection() const {
    return gestureDirection;
}

const std::vector<SwipePoint> & Swipe::getPoints() const {
    return points;
}

float Swipe::getSwipeTime() const {
    return swipeTime;
}

//--------------------------------------------------------------
SwipeDirection Swipe::getDirectionFromAngle(float angleDeg) const {
    SwipeDirection dir;
    if((angleDeg > 315 && angleDeg <= 360) || (angleDeg >= 0 && angleDeg <= 45)) {
        dir = SwipeDirectionUp;
    } else if(angleDeg > 45 && angleDeg <= 135) {
        dir = SwipeDirectionRight;
    } else if(angleDeg > 135 && angleDeg <= 225) {
        dir = SwipeDirectionDown;
    } else if(angleDeg > 225 && angleDeg <= 315) {
        dir = SwipeDirectionLeft;
    }
    return dir;
}

}<|endoftext|>


<commit_before><commit_msg>`yli::load::load_symbiosis`: edit `std::cerr` error output.<commit_after><|endoftext|>


<commit_before>#include <cmath>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include "TCanvas.h"
#include "TFile.h"
#include "TH2.h"
#include "TStyle.h"

int main(int argc, char** argv) {
    // Set ROOT params
    gStyle->SetOptStat(0);
    gStyle->SetNumberContours(999);

    bool print_help = false;
    int return_code = 0;
    if(argc == 1) {
        print_help = true;
        return_code = 1;
    }

    // Read parameters
    std::string file_name;
    std::string output_file_name;
    std::string plane = "yz";
    int slice_index = 0;
    bool flag_cut = false;
    int slice_cut = 0;
    int xdiv = 100;
    int ydiv = 100;
    int zdiv = 100;
    for(int i = 1; i < argc; i++) {
        if(strcmp(argv[i], "-h") == 0) {
            print_help = true;
        } else if(strcmp(argv[i], "-f") == 0 && (i + 1 < argc)) {
            file_name = std::string(argv[++i]);
        } else if(strcmp(argv[i], "-o") == 0 && (i + 1 < argc)) {
            output_file_name = std::string(argv[++i]);
        } else if(strcmp(argv[i], "-p") == 0 && (i + 1 < argc)) {
            plane = std::string(argv[++i]);
        } else if(strcmp(argv[i], "-c") == 0 && (i + 1 < argc)) {
            slice_cut = std::atoi(argv[++i]);
            flag_cut = true;
        } else if(strcmp(argv[i], "-x") == 0 && (i + 1 < argc)) {
            xdiv = std::atoi(argv[++i]);
        } else if(strcmp(argv[i], "-y") == 0 && (i + 1 < argc)) {
            ydiv = std::atoi(argv[++i]);
        } else if(strcmp(argv[i], "-z") == 0 && (i + 1 < argc)) {
            zdiv = std::atoi(argv[++i]);
        } else {
            std::cout << "Unrecognized command line argument or missing value\"" << argv[i] << std::endl;
            print_help = true;
            return_code = 1;
        }
    }

    if(file_name.empty()) {
        print_help = true;
        return_code = 1;
    }

    if(print_help) {
        std::cerr << "Usage: ./tcad_dfise_reader -f <file_name> [<options>]" << std::endl;
        std::cout << "\t -f <file_name>         init file name" << std::endl;
        std::cout << "\t -o <output_file_name>  name of the file to output (default is efield.png)" << std::endl;
        std::cout << "\t -p <plane>             plane to be ploted. xy, yz or zx (default is yz)" << std::endl;
        std::cout << "\t -c <cut>               projection height index (default is mesh_pitch / 2)" << std::endl;
        std::cout << "\t -x <mesh x_pitch>      plot regular mesh X binning (default is 100)" << std::endl;
        std::cout << "\t -y <mesh_y_pitch>      plot regular mesh Y binning (default is 100)" << std::endl;
        std::cout << "\t -z <mesh_z_pitch>      plot regular mesh Z binning (default is 100)" << std::endl;
        return return_code;
    }

    // Read file
    std::cout << "Reading file: " << file_name;

    size_t firstindex = file_name.find_last_of("_");
    size_t lastindex = file_name.find(".");
    output_file_name = file_name.substr(0, lastindex);
    output_file_name += ".png";

    std::string observable = file_name.substr(firstindex + 1, lastindex - (firstindex + 1));

    std::ifstream input_file;
    input_file.open(file_name);
    if(input_file.is_open() != false) {
        std::cout << "  OK" << std::endl;
    } else {
        std::cout << "  FAILED" << std::endl;
        return 1;
    }

    // Find plotting indices
    int x_bin = 0;
    int y_bin = 0;
    int x_bin_index = 0;
    int y_bin_index = 0;
    if(strcmp(plane.c_str(), "xy") == 0) {
        x_bin = xdiv;
        y_bin = ydiv;
        if(!flag_cut) {
            slice_cut = zdiv / 2;
        }
        x_bin_index = 0;
        y_bin_index = 1;
        slice_index = 2;
    }
    if(strcmp(plane.c_str(), "yz") == 0) {
        x_bin = ydiv;
        y_bin = zdiv;
        if(!flag_cut) {
            slice_cut = xdiv / 2;
        }
        x_bin_index = 1;
        y_bin_index = 2;
        slice_index = 0;
    }
    if(strcmp(plane.c_str(), "zx") == 0) {
        x_bin = zdiv;
        y_bin = xdiv;
        if(!flag_cut) {
            slice_cut = ydiv / 2;
        }
        x_bin_index = 2;
        y_bin_index = 0;
        slice_index = 1;
    }

    // Create and fill histogram
    auto efield_map =
        new TH2D(Form("%s", observable.c_str()), Form("%s", observable.c_str()), x_bin, 0, x_bin, y_bin, 0, y_bin);
    auto exfield_map = new TH2D(Form("%s X component", observable.c_str()),
                                Form("%s X component", observable.c_str()),
                                x_bin,
                                0,
                                x_bin,
                                y_bin,
                                0,
                                y_bin);
    auto eyfield_map = new TH2D(Form("%s Y component", observable.c_str()),
                                Form("%s Y component", observable.c_str()),
                                x_bin,
                                0,
                                x_bin,
                                y_bin,
                                0,
                                y_bin);
    auto ezfield_map = new TH2D(Form("%s Z component", observable.c_str()),
                                Form("%s Z component", observable.c_str()),
                                x_bin,
                                0,
                                x_bin,
                                y_bin,
                                0,
                                y_bin);
    auto c1 = new TCanvas();

    double dummy;
    double vector[6];
    int line = 1;
    std::string file_line;
    while(getline(input_file, file_line)) {
        int p = 0;
        if(line < 7) {
            line++;
            continue;
        }
        std::stringstream mystream(file_line);
        while(mystream >> dummy) {
            vector[p] = dummy;
            p++;
        }
        if(vector[slice_index] == slice_cut) {
            efield_map->Fill(
                vector[x_bin_index], vector[y_bin_index], sqrt(pow(vector[3], 2) + pow(vector[4], 2) + pow(vector[5], 2)));
            exfield_map->Fill(vector[x_bin_index], vector[y_bin_index], vector[3]);
            eyfield_map->Fill(vector[x_bin_index], vector[y_bin_index], vector[4]);
            ezfield_map->Fill(vector[x_bin_index], vector[y_bin_index], vector[5]);
        }
        line++;
    }
    std::string root_file_name = file_name.substr(0, lastindex);
    root_file_name += "_Interpolation_plots.root";
    auto* tf = new TFile(root_file_name.c_str(), "RECREATE");
    exfield_map->Write(Form("%s X component", observable.c_str()));
    eyfield_map->Write(Form("%s Y component", observable.c_str()));
    ezfield_map->Write(Form("%s Z component", observable.c_str()));
    efield_map->Write(Form("%s Norm", observable.c_str()));
    c1->cd();
    efield_map->Draw("colz");
    c1->SaveAs(output_file_name.c_str());
    tf->Close();
    return 0;
}
<commit_msg>small CI fix<commit_after>#include <cmath>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
#include "TCanvas.h"
#include "TFile.h"
#include "TH2.h"
#include "TStyle.h"

int main(int argc, char** argv) {
    // Set ROOT params
    gStyle->SetOptStat(0);
    gStyle->SetNumberContours(999);

    bool print_help = false;
    int return_code = 0;
    if(argc == 1) {
        print_help = true;
        return_code = 1;
    }

    // Read parameters
    std::string file_name;
    std::string output_file_name;
    std::string plane = "yz";
    int slice_index = 0;
    bool flag_cut = false;
    int slice_cut = 0;
    int xdiv = 100;
    int ydiv = 100;
    int zdiv = 100;
    for(int i = 1; i < argc; i++) {
        if(strcmp(argv[i], "-h") == 0) {
            print_help = true;
        } else if(strcmp(argv[i], "-f") == 0 && (i + 1 < argc)) {
            file_name = std::string(argv[++i]);
        } else if(strcmp(argv[i], "-o") == 0 && (i + 1 < argc)) {
            output_file_name = std::string(argv[++i]);
        } else if(strcmp(argv[i], "-p") == 0 && (i + 1 < argc)) {
            plane = std::string(argv[++i]);
        } else if(strcmp(argv[i], "-c") == 0 && (i + 1 < argc)) {
            slice_cut = std::atoi(argv[++i]);
            flag_cut = true;
        } else if(strcmp(argv[i], "-x") == 0 && (i + 1 < argc)) {
            xdiv = std::atoi(argv[++i]);
        } else if(strcmp(argv[i], "-y") == 0 && (i + 1 < argc)) {
            ydiv = std::atoi(argv[++i]);
        } else if(strcmp(argv[i], "-z") == 0 && (i + 1 < argc)) {
            zdiv = std::atoi(argv[++i]);
        } else {
            std::cout << "Unrecognized command line argument or missing value\"" << argv[i] << std::endl;
            print_help = true;
            return_code = 1;
        }
    }

    if(file_name.empty()) {
        print_help = true;
        return_code = 1;
    }

    if(print_help) {
        std::cerr << "Usage: ./tcad_dfise_reader -f <file_name> [<options>]" << std::endl;
        std::cout << "\t -f <file_name>         init file name" << std::endl;
        std::cout << "\t -o <output_file_name>  name of the file to output (default is efield.png)" << std::endl;
        std::cout << "\t -p <plane>             plane to be ploted. xy, yz or zx (default is yz)" << std::endl;
        std::cout << "\t -c <cut>               projection height index (default is mesh_pitch / 2)" << std::endl;
        std::cout << "\t -x <mesh x_pitch>      plot regular mesh X binning (default is 100)" << std::endl;
        std::cout << "\t -y <mesh_y_pitch>      plot regular mesh Y binning (default is 100)" << std::endl;
        std::cout << "\t -z <mesh_z_pitch>      plot regular mesh Z binning (default is 100)" << std::endl;
        return return_code;
    }

    // Read file
    std::cout << "Reading file: " << file_name;

    size_t firstindex = file_name.find_last_of('_');
    size_t lastindex = file_name.find('.');
    output_file_name = file_name.substr(0, lastindex);
    output_file_name += ".png";

    std::string observable = file_name.substr(firstindex + 1, lastindex - (firstindex + 1));

    std::ifstream input_file;
    input_file.open(file_name);
    if(input_file.is_open() != false) {
        std::cout << "  OK" << std::endl;
    } else {
        std::cout << "  FAILED" << std::endl;
        return 1;
    }

    // Find plotting indices
    int x_bin = 0;
    int y_bin = 0;
    int x_bin_index = 0;
    int y_bin_index = 0;
    if(strcmp(plane.c_str(), "xy") == 0) {
        x_bin = xdiv;
        y_bin = ydiv;
        if(!flag_cut) {
            slice_cut = zdiv / 2;
        }
        x_bin_index = 0;
        y_bin_index = 1;
        slice_index = 2;
    }
    if(strcmp(plane.c_str(), "yz") == 0) {
        x_bin = ydiv;
        y_bin = zdiv;
        if(!flag_cut) {
            slice_cut = xdiv / 2;
        }
        x_bin_index = 1;
        y_bin_index = 2;
        slice_index = 0;
    }
    if(strcmp(plane.c_str(), "zx") == 0) {
        x_bin = zdiv;
        y_bin = xdiv;
        if(!flag_cut) {
            slice_cut = ydiv / 2;
        }
        x_bin_index = 2;
        y_bin_index = 0;
        slice_index = 1;
    }

    // Create and fill histogram
    auto efield_map =
        new TH2D(Form("%s", observable.c_str()), Form("%s", observable.c_str()), x_bin, 0, x_bin, y_bin, 0, y_bin);
    auto exfield_map = new TH2D(Form("%s X component", observable.c_str()),
                                Form("%s X component", observable.c_str()),
                                x_bin,
                                0,
                                x_bin,
                                y_bin,
                                0,
                                y_bin);
    auto eyfield_map = new TH2D(Form("%s Y component", observable.c_str()),
                                Form("%s Y component", observable.c_str()),
                                x_bin,
                                0,
                                x_bin,
                                y_bin,
                                0,
                                y_bin);
    auto ezfield_map = new TH2D(Form("%s Z component", observable.c_str()),
                                Form("%s Z component", observable.c_str()),
                                x_bin,
                                0,
                                x_bin,
                                y_bin,
                                0,
                                y_bin);
    auto c1 = new TCanvas();

    double dummy;
    double vector[6];
    int line = 1;
    std::string file_line;
    while(getline(input_file, file_line)) {
        int p = 0;
        if(line < 7) {
            line++;
            continue;
        }
        std::stringstream mystream(file_line);
        while(mystream >> dummy) {
            vector[p] = dummy;
            p++;
        }
        if(vector[slice_index] == slice_cut) {
            efield_map->Fill(
                vector[x_bin_index], vector[y_bin_index], sqrt(pow(vector[3], 2) + pow(vector[4], 2) + pow(vector[5], 2)));
            exfield_map->Fill(vector[x_bin_index], vector[y_bin_index], vector[3]);
            eyfield_map->Fill(vector[x_bin_index], vector[y_bin_index], vector[4]);
            ezfield_map->Fill(vector[x_bin_index], vector[y_bin_index], vector[5]);
        }
        line++;
    }
    std::string root_file_name = file_name.substr(0, lastindex);
    root_file_name += "_Interpolation_plots.root";
    auto* tf = new TFile(root_file_name.c_str(), "RECREATE");
    exfield_map->Write(Form("%s X component", observable.c_str()));
    eyfield_map->Write(Form("%s Y component", observable.c_str()));
    ezfield_map->Write(Form("%s Z component", observable.c_str()));
    efield_map->Write(Form("%s Norm", observable.c_str()));
    c1->cd();
    efield_map->Draw("colz");
    c1->SaveAs(output_file_name.c_str());
    tf->Close();
    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: bibmod.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: rt $ $Date: 2007-04-26 08:05:22 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#include <tools/resmgr.hxx>
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef SVTOOLS_URIHELPER_HXX
#include <svtools/urihelper.hxx>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XLOCALIZEDALIASES_HPP_
#include <com/sun/star/util/XLocalizedAliases.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XLOCALIZABLE_HPP_
#include <com/sun/star/lang/XLocalizable.hpp>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#include "bibmod.hxx"
#include "bibresid.hxx"
#include "datman.hxx"
#include "bibconfig.hxx"
static PtrBibModul pBibModul=NULL;
static sal_uInt32 nBibModulCount=0;

#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::ucb;

#define C2U(cChar) OUString::createFromAscii(cChar)
#define C2S(cChar) String::CreateFromAscii(cChar)

HdlBibModul OpenBibModul()
{
    if(pBibModul==NULL)
    {
        pBibModul=new BibModul();
    }
    nBibModulCount++;
    return &pBibModul;
}

void CloseBibModul(HdlBibModul ppBibModul)
{
    nBibModulCount--;
    if(nBibModulCount==0 && ppBibModul!=NULL)
    {
        delete pBibModul;
        pBibModul=NULL;
    }
}

BibResId::BibResId( sal_uInt16 nId ) :
    ResId( nId, *pBibModul->GetResMgr() )
{
}
BibConfig* BibModul::pBibConfig = 0;
BibModul::BibModul()
{
    pResMgr = ResMgr::CreateResMgr( "bib" MAKE_NUMSTR(SUPD) );
}

BibModul::~BibModul()
{
    delete pResMgr;
    delete pBibConfig;
    pBibConfig = 0;
}

BibDataManager*  BibModul::createDataManager()
{
    return new BibDataManager();
}
//-----------------------------------------------------------------------------
BibConfig*  BibModul::GetConfig()
{
    if(! pBibConfig)
        pBibConfig = new BibConfig;
    return pBibConfig;
}

// PropertyNames
#define STATIC_USTRING(a,b) rtl::OUString a(b)
STATIC_USTRING(FM_PROP_LABEL,C2U("Label"));
STATIC_USTRING(FM_PROP_CONTROLSOURCE,C2U("DataField"));
STATIC_USTRING(FM_PROP_NAME,C2U("Name"));
STATIC_USTRING(FM_PROP_FORMATKEY,C2U("FormatKey"));
#ifdef TF_SDBAPI
#else // !TF_SDBAPI
STATIC_USTRING(FM_PROP_EDITMODE,C2U("RecordMode"));
STATIC_USTRING(FM_PROP_CURSORSOURCETYPE,C2U("DataSelectionType"));
STATIC_USTRING(FM_PROP_CURSORSOURCE,C2U("DataSelection"));
STATIC_USTRING(FM_PROP_DATASOURCE, C2U("DataSource"));
#endif // !TF_SDBAPI
STATIC_USTRING(FM_PROP_VALUE,C2U("Value"));
STATIC_USTRING(FM_PROP_TEXT,C2U("Text"));
<commit_msg>INTEGRATION: CWS supdremove02 (1.10.142); FILE MERGED 2008/01/31 13:46:32 rt 1.10.142.1: #i85482# Remove UPD from resource name.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: bibmod.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-25 15:32:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"

#include <tools/resmgr.hxx>
#ifndef _URLOBJ_HXX
#include <tools/urlobj.hxx>
#endif
#ifndef SVTOOLS_URIHELPER_HXX
#include <svtools/urihelper.hxx>
#endif

#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
#include <com/sun/star/container/XNameAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_UTIL_XLOCALIZEDALIASES_HPP_
#include <com/sun/star/util/XLocalizedAliases.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XLOCALIZABLE_HPP_
#include <com/sun/star/lang/XLocalizable.hpp>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif

#include "bibmod.hxx"
#include "bibresid.hxx"
#include "datman.hxx"
#include "bibconfig.hxx"
static PtrBibModul pBibModul=NULL;
static sal_uInt32 nBibModulCount=0;

#ifndef _UCBHELPER_CONTENT_HXX
#include <ucbhelper/content.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::ucb;

#define C2U(cChar) OUString::createFromAscii(cChar)
#define C2S(cChar) String::CreateFromAscii(cChar)

HdlBibModul OpenBibModul()
{
    if(pBibModul==NULL)
    {
        pBibModul=new BibModul();
    }
    nBibModulCount++;
    return &pBibModul;
}

void CloseBibModul(HdlBibModul ppBibModul)
{
    nBibModulCount--;
    if(nBibModulCount==0 && ppBibModul!=NULL)
    {
        delete pBibModul;
        pBibModul=NULL;
    }
}

BibResId::BibResId( sal_uInt16 nId ) :
    ResId( nId, *pBibModul->GetResMgr() )
{
}
BibConfig* BibModul::pBibConfig = 0;
BibModul::BibModul()
{
    pResMgr = ResMgr::CreateResMgr( "bib" );
}

BibModul::~BibModul()
{
    delete pResMgr;
    delete pBibConfig;
    pBibConfig = 0;
}

BibDataManager*  BibModul::createDataManager()
{
    return new BibDataManager();
}
//-----------------------------------------------------------------------------
BibConfig*  BibModul::GetConfig()
{
    if(! pBibConfig)
        pBibConfig = new BibConfig;
    return pBibConfig;
}

// PropertyNames
#define STATIC_USTRING(a,b) rtl::OUString a(b)
STATIC_USTRING(FM_PROP_LABEL,C2U("Label"));
STATIC_USTRING(FM_PROP_CONTROLSOURCE,C2U("DataField"));
STATIC_USTRING(FM_PROP_NAME,C2U("Name"));
STATIC_USTRING(FM_PROP_FORMATKEY,C2U("FormatKey"));
#ifdef TF_SDBAPI
#else // !TF_SDBAPI
STATIC_USTRING(FM_PROP_EDITMODE,C2U("RecordMode"));
STATIC_USTRING(FM_PROP_CURSORSOURCETYPE,C2U("DataSelectionType"));
STATIC_USTRING(FM_PROP_CURSORSOURCE,C2U("DataSelection"));
STATIC_USTRING(FM_PROP_DATASOURCE, C2U("DataSource"));
#endif // !TF_SDBAPI
STATIC_USTRING(FM_PROP_VALUE,C2U("Value"));
STATIC_USTRING(FM_PROP_TEXT,C2U("Text"));
<|endoftext|>


<commit_before><commit_msg>Treat "Ascender Sans" and "Ascender Serif" as equivalent to  "Arial" and "Times New Roman" as Liberation Sans/Serif are.<commit_after><|endoftext|>


<commit_before>#include "codecmanager.h"
#include "ui_codecmanager.h"

CodecManager::CodecManager(QWidget *parent, QString encoder)
    : QWidget(parent), ui(new Ui::CodecManager),
      streamingParameters(new QMap<QString, QString>), layoutCounter(0) {
    ui->setupUi(this);

    streamingParameters->insert("c:v", encoder);
    addParameter("FPS", "r", "");
    addParameter("Bitrate", "b:v", "");
    addParameter("Minrate", "minrate", "");
    addParameter("Maxrate", "maxrate", "");
    addParameter("Buffer size", "bufsize", "");
    addParameter("Aspect ratio", "aspect", "");
    addParameter("Qscale", "qscale:v", "");
    addParameter("Costant Rate Factor", "crf", "");
}

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

QMap<QString, QString> *CodecManager::getStreamingParameters() {
    QMap<QString, QString> *parameters(streamingParameters);
    // Add final parameters
    parameters->insert("f", "matroska");
    parameters->insert("an", "");
    return parameters;
}

void CodecManager::addParameter(QString label, QString parameter,
                                QString value) {
    // Create a new layout for the parameter
    QVBoxLayout *layout = new QVBoxLayout(this);

    // Add a QLabel
    QLabel *labelWidget = new QLabel(label, this);
    layout->addWidget(labelWidget);

    // Add a QLineEdit
    QLineEdit *lineEdit = new QLineEdit(value, this);
    layout->addWidget(lineEdit);

    // Make the form interactive
    streamingParameters->insert(parameter, value);
    connect(lineEdit, &QLineEdit::editingFinished, [=] {
        QString newValue = lineEdit->text();
        if (newValue != streamingParameters->value(parameter)) {
            streamingParameters->insert(parameter, newValue);
            emit parametersChanged();
        }
    });

    insertParameter(layout);
}

void CodecManager::addParameter(QString label, QString parameter,
                                QList<QString> values) {
    // Create a new layout for the parameter
    QVBoxLayout *layout = new QVBoxLayout(this);

    // Add a QLabel
    QLabel *labelWidget = new QLabel(label, this);
    layout->addWidget(labelWidget);

    // Add a QComboBox
    QComboBox *comboBox = new QComboBox(this);
    comboBox->insertItems(0, values);
    layout->addWidget(comboBox);

    // Make the form interactive
    streamingParameters->insert(parameter, values[0]);
    connect(comboBox, &QComboBox::currentTextChanged,
            [=](const QString &newValue) {
                if (newValue != streamingParameters->value(parameter)) {
                    streamingParameters->insert(parameter, newValue);
                    emit parametersChanged();
                }
            });

    insertParameter(layout);
}

void CodecManager::insertParameter(QLayout *layout) {
    // Calculate position
    int row = layoutCounter / 7;
    int column = layoutCounter % 7;

    // Insert the layout
    ui->mainLayout->addLayout(layout, row, column);
    layoutCounter++;
}
<commit_msg>Do not add parent objects to layout elements (that was a bug)<commit_after>#include "codecmanager.h"
#include "ui_codecmanager.h"

CodecManager::CodecManager(QWidget *parent, QString encoder)
    : QWidget(parent), ui(new Ui::CodecManager),
      streamingParameters(new QMap<QString, QString>), layoutCounter(0) {
    ui->setupUi(this);

    streamingParameters->insert("c:v", encoder);
    addParameter("FPS", "r", "");
    addParameter("Bitrate", "b:v", "");
    addParameter("Minrate", "minrate", "");
    addParameter("Maxrate", "maxrate", "");
    addParameter("Buffer size", "bufsize", "");
    addParameter("Aspect ratio", "aspect", "");
    addParameter("Qscale", "qscale:v", "");
    addParameter("Costant Rate Factor", "crf", "");
}

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

QMap<QString, QString> *CodecManager::getStreamingParameters() {
    QMap<QString, QString> *parameters(streamingParameters);
    // Add final parameters
    parameters->insert("f", "matroska");
    parameters->insert("an", "");
    return parameters;
}

void CodecManager::addParameter(QString label, QString parameter,
                                QString value) {
    // Create a new layout for the parameter
    QVBoxLayout *layout = new QVBoxLayout();

    // Add a QLabel
    QLabel *labelWidget = new QLabel(label, this);
    layout->addWidget(labelWidget);

    // Add a QLineEdit
    QLineEdit *lineEdit = new QLineEdit(value, this);
    layout->addWidget(lineEdit);

    // Make the form interactive
    streamingParameters->insert(parameter, value);
    connect(lineEdit, &QLineEdit::editingFinished, [=] {
        QString newValue = lineEdit->text();
        if (newValue != streamingParameters->value(parameter)) {
            streamingParameters->insert(parameter, newValue);
            emit parametersChanged();
        }
    });

    insertParameter(layout);
}

void CodecManager::addParameter(QString label, QString parameter,
                                QList<QString> values) {
    // Create a new layout for the parameter
    QVBoxLayout *layout = new QVBoxLayout();

    // Add a QLabel
    QLabel *labelWidget = new QLabel(label, this);
    layout->addWidget(labelWidget);

    // Add a QComboBox
    QComboBox *comboBox = new QComboBox(this);
    comboBox->insertItems(0, values);
    layout->addWidget(comboBox);

    // Make the form interactive
    streamingParameters->insert(parameter, values[0]);
    connect(comboBox, &QComboBox::currentTextChanged,
            [=](const QString &newValue) {
                if (newValue != streamingParameters->value(parameter)) {
                    streamingParameters->insert(parameter, newValue);
                    emit parametersChanged();
                }
            });

    insertParameter(layout);
}

void CodecManager::insertParameter(QLayout *layout) {
    // Calculate position
    int row = layoutCounter / 7;
    int column = layoutCounter % 7;

    // Insert the layout
    ui->mainLayout->addLayout(layout, row, column);
    layoutCounter++;
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkFontHost.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkSfntUtils.h"
#include "SkString.h"
#include "SkTemplates.h"

/*  Some considerations for performance:
        short -vs- long strings (measuring overhead)
        tiny -vs- large pointsize (measure blit -vs- overhead)
        1 -vs- many point sizes (measure cache lookup)
        normal -vs- subpixel -vs- lineartext (minor)
        force purge after each draw to measure scaler
        textencoding?
        text -vs- postext - pathtext
 */
class TextBench : public SkBenchmark {
    SkPaint     fPaint;
    int         fCount;
    SkPoint*    fPos;
    SkString    fText;
    SkString    fName;
    enum { N = 600 };
public:
    TextBench(void* param, const char text[], int ps, bool linearText,
              bool posText, SkColor color = SK_ColorBLACK) : INHERITED(param) {
        fText.set(text);

        fPaint.setAntiAlias(true);
        fPaint.setTextSize(SkIntToScalar(ps));
        fPaint.setLinearText(linearText);
        fPaint.setColor(color);

        if (posText) {
            SkAutoTArray<SkScalar> storage(fText.size());
            SkScalar* widths = storage.get();
            fCount = fPaint.getTextWidths(fText.c_str(), fText.size(), widths);
            fPos = new SkPoint[fCount];
            SkScalar x = 0;
            for (int i = 0; i < fCount; i++) {
                fPos[i].set(x, 0);
                x += widths[i];
            }
        } else {
            fCount = 0;
            fPos = NULL;
        }
    }

    virtual ~TextBench() {
        delete[] fPos;
    }

protected:
    virtual const char* onGetName() {
        fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize()));
        if (fPaint.isLinearText()) {
            fName.append("_linear");
        }
        if (fPos) {
            fName.append("_pos");
        }

        if (SK_ColorBLACK != fPaint.getColor()) {
            fName.appendf("_%02X", fPaint.getAlpha());
        }
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) {
        const SkIPoint dim = this->getSize();
        SkRandom rand;

        SkPaint paint(fPaint);
        this->setupPaint(&paint);
        paint.setColor(fPaint.getColor());  // need our specified color

        const SkScalar x0 = SkIntToScalar(-10);
        const SkScalar y0 = SkIntToScalar(-10);

        for (int i = 0; i < N; i++) {
            SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
            SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
            if (fPos) {
                canvas->save(SkCanvas::kMatrix_SaveFlag);
                canvas->translate(x, y);
                canvas->drawPosText(fText.c_str(), fText.size(), fPos, paint);
                canvas->restore();
            } else {
                canvas->drawText(fText.c_str(), fText.size(), x, y, paint);
            }
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

#define STR     "Hamburgefons"
#define SMALL   9
#define BIG     48

static SkBenchmark* Fact0(void* p) { return new TextBench(p, STR, SMALL, false, false); }
static SkBenchmark* Fact01(void* p) { return new TextBench(p, STR, SMALL, false, false, 0xFFFF0000); }
static SkBenchmark* Fact02(void* p) { return new TextBench(p, STR, SMALL, false, false, 0x88FF0000); }

static SkBenchmark* Fact1(void* p) { return new TextBench(p, STR, SMALL, false, true); }
static SkBenchmark* Fact2(void* p) { return new TextBench(p, STR, SMALL, true, false); }
static SkBenchmark* Fact3(void* p) { return new TextBench(p, STR, SMALL, true, true); }

static SkBenchmark* Fact4(void* p) { return new TextBench(p, STR, BIG, false, false); }
static SkBenchmark* Fact41(void* p) { return new TextBench(p, STR, BIG, false, false, 0xFFFF0000); }
static SkBenchmark* Fact42(void* p) { return new TextBench(p, STR, BIG, false, false, 0x88FF0000); }

static SkBenchmark* Fact5(void* p) { return new TextBench(p, STR, BIG, false, true); }
static SkBenchmark* Fact6(void* p) { return new TextBench(p, STR, BIG, true, false); }
static SkBenchmark* Fact7(void* p) { return new TextBench(p, STR, BIG, true, true); }

static BenchRegistry gReg0(Fact0);
static BenchRegistry gReg01(Fact01);
static BenchRegistry gReg02(Fact02);
static BenchRegistry gReg1(Fact1);
static BenchRegistry gReg2(Fact2);
static BenchRegistry gReg3(Fact3);
static BenchRegistry gReg4(Fact4);
static BenchRegistry gReg41(Fact41);
static BenchRegistry gReg42(Fact42);
static BenchRegistry gReg5(Fact5);
static BenchRegistry gReg6(Fact6);
static BenchRegistry gReg7(Fact7);

<commit_msg>change text bench to measure text blit speed<commit_after>
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkFontHost.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkSfntUtils.h"
#include "SkString.h"
#include "SkTemplates.h"

enum FontQuality {
    kBW,
    kAA,
    kLCD
};

static const char* fontQualityName(const SkPaint& paint) {
    if (!paint.isAntiAlias()) {
        return "BW";
    }
    if (paint.isLCDRenderText()) {
        return "LCD";
    }
    return "AA";
}

/*  Some considerations for performance:
        short -vs- long strings (measuring overhead)
        tiny -vs- large pointsize (measure blit -vs- overhead)
        1 -vs- many point sizes (measure cache lookup)
        normal -vs- subpixel -vs- lineartext (minor)
        force purge after each draw to measure scaler
        textencoding?
        text -vs- postext - pathtext
 */
class TextBench : public SkBenchmark {
    SkPaint     fPaint;
    SkString    fText;
    SkString    fName;
    FontQuality fFQ;
    enum { N = 800 };
public:
    TextBench(void* param, const char text[], int ps,
              SkColor color, FontQuality fq) : INHERITED(param) {
        fFQ = fq;
        fText.set(text);

        fPaint.setAntiAlias(kBW != fq);
        fPaint.setLCDRenderText(kLCD == fq);
        fPaint.setTextSize(SkIntToScalar(ps));
        fPaint.setColor(color);
    }

protected:
    virtual const char* onGetName() {
        fName.printf("text_%g", SkScalarToFloat(fPaint.getTextSize()));
        fName.appendf("_%s", fontQualityName(fPaint));
        if (SK_ColorBLACK != fPaint.getColor()) {
            fName.appendf("_%02X", fPaint.getAlpha());
        } else {
            fName.appendf("_BK");
        }
        return fName.c_str();
    }

    virtual void onDraw(SkCanvas* canvas) {
        const SkIPoint dim = this->getSize();
        SkRandom rand;

        SkPaint paint(fPaint);
        this->setupPaint(&paint);
        // explicitly need these
        paint.setColor(fPaint.getColor());
        paint.setAntiAlias(kBW != fFQ);
        paint.setLCDRenderText(kLCD == fFQ);

        const SkScalar x0 = SkIntToScalar(-10);
        const SkScalar y0 = SkIntToScalar(-10);

        for (int i = 0; i < N; i++) {
            SkScalar x = x0 + rand.nextUScalar1() * dim.fX;
            SkScalar y = y0 + rand.nextUScalar1() * dim.fY;
            canvas->drawText(fText.c_str(), fText.size(), x, y, paint);
        }
    }

private:
    typedef SkBenchmark INHERITED;
};

///////////////////////////////////////////////////////////////////////////////

#define STR     "Hamburgefons"

static SkBenchmark* Fact01(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kBW); }
static SkBenchmark* Fact02(void* p) { return new TextBench(p, STR, 16, 0xFFFF0000, kBW); }
static SkBenchmark* Fact03(void* p) { return new TextBench(p, STR, 16, 0x88FF0000, kBW); }

static SkBenchmark* Fact11(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kAA); }
static SkBenchmark* Fact12(void* p) { return new TextBench(p, STR, 16, 0xFFFF0000, kAA); }
static SkBenchmark* Fact13(void* p) { return new TextBench(p, STR, 16, 0x88FF0000, kAA); }

static SkBenchmark* Fact21(void* p) { return new TextBench(p, STR, 16, 0xFF000000, kLCD); }
static SkBenchmark* Fact22(void* p) { return new TextBench(p, STR, 16, 0xFFFF0000, kLCD); }
static SkBenchmark* Fact23(void* p) { return new TextBench(p, STR, 16, 0x88FF0000, kLCD); }

static BenchRegistry gReg01(Fact01);
static BenchRegistry gReg02(Fact02);
static BenchRegistry gReg03(Fact03);

static BenchRegistry gReg11(Fact11);
static BenchRegistry gReg12(Fact12);
static BenchRegistry gReg13(Fact13);

static BenchRegistry gReg21(Fact21);
static BenchRegistry gReg22(Fact22);
static BenchRegistry gReg23(Fact23);

<|endoftext|>


<commit_before>#include <benchmark/benchmark.h>

#include <blackhole/attribute.hpp>

#include "mod.hpp"

namespace blackhole {
namespace benchmark {

static void view_ctor_get_int64(::benchmark::State& state) {
    while (state.KeepRunning()) {
        blackhole::attribute::view_t v(42);
        blackhole::attribute::get<std::int64_t>(v);
    }

    state.SetItemsProcessed(state.iterations());
}

static void from_owned(::benchmark::State& state) {
    blackhole::attribute::value_t owned(42);

    while (state.KeepRunning()) {
        blackhole::attribute::view_t view(owned);
        ::benchmark::DoNotOptimize(view);
    }

    state.SetItemsProcessed(state.iterations());
}

NBENCHMARK("attribute.view_t[ctor + get<i64>]", view_ctor_get_int64);
NBENCHMARK("attribute.view_t[ctor + from owned]", from_owned);

}  // namespace benchmark
}  // namespace blackhole
<commit_msg>feat(bench): measure different values<commit_after>#include <benchmark/benchmark.h>

#include <blackhole/attribute.hpp>

#include "mod.hpp"

namespace blackhole {
namespace benchmark {

static void view_ctor_get_int64(::benchmark::State& state) {
    while (state.KeepRunning()) {
        blackhole::attribute::view_t v(42);
        blackhole::attribute::get<std::int64_t>(v);
    }

    state.SetItemsProcessed(state.iterations());
}

static void from_owned(::benchmark::State& state) {
    blackhole::attribute::value_t owned(42);

    while (state.KeepRunning()) {
        blackhole::attribute::view_t view(owned);
        ::benchmark::DoNotOptimize(view);
    }

    state.SetItemsProcessed(state.iterations());
}

static void from_owned_string(::benchmark::State& state) {
    blackhole::attribute::value_t owned("le message");

    while (state.KeepRunning()) {
        blackhole::attribute::view_t view(owned);
        ::benchmark::DoNotOptimize(view);
    }

    state.SetItemsProcessed(state.iterations());
}

NBENCHMARK("attribute.view_t[ctor + get<i64>]", view_ctor_get_int64);
NBENCHMARK("attribute.view_t[ctor + from owned]", from_owned);
NBENCHMARK("attribute.view_t[ctor + from owned string]", from_owned_string);

}  // namespace benchmark
}  // namespace blackhole
<|endoftext|>


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

#include "perfetto/ext/base/watchdog.h"

#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)

#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>

#include <fstream>
#include <thread>

#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/thread_utils.h"
#include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace base {

namespace {

constexpr uint32_t kDefaultPollingInterval = 30 * 1000;

bool IsMultipleOf(uint32_t number, uint32_t divisor) {
  return number >= divisor && number % divisor == 0;
}

double MeanForArray(const uint64_t array[], size_t size) {
  uint64_t total = 0;
  for (size_t i = 0; i < size; i++) {
    total += array[i];
  }
  return total / size;
}

}  //  namespace

Watchdog::Watchdog(uint32_t polling_interval_ms)
    : polling_interval_ms_(polling_interval_ms) {}

Watchdog::~Watchdog() {
  if (!thread_.joinable()) {
    PERFETTO_DCHECK(!enabled_);
    return;
  }
  PERFETTO_DCHECK(enabled_);
  enabled_ = false;
  exit_signal_.notify_one();
  thread_.join();
}

Watchdog* Watchdog::GetInstance() {
  static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
  return watchdog;
}

Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
  if (!enabled_.load(std::memory_order_relaxed))
    return Watchdog::Timer(0);

  return Watchdog::Timer(ms);
}

void Watchdog::Start() {
  std::lock_guard<std::mutex> guard(mutex_);
  if (thread_.joinable()) {
    PERFETTO_DCHECK(enabled_);
  } else {
    PERFETTO_DCHECK(!enabled_);

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
    // Kick the thread to start running but only on Android or Linux.
    enabled_ = true;
    thread_ = std::thread(&Watchdog::ThreadMain, this);
#endif
  }
}

void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
  // Update the fields under the lock.
  std::lock_guard<std::mutex> guard(mutex_);

  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);

  size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
  memory_window_bytes_.Reset(size);
  memory_limit_bytes_ = bytes;
}

void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
  std::lock_guard<std::mutex> guard(mutex_);

  PERFETTO_CHECK(percentage <= 100);
  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
                 percentage == 0);

  size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
  cpu_window_time_ticks_.Reset(size);
  cpu_limit_percentage_ = percentage;
}

void Watchdog::ThreadMain() {
  base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
  if (!stat_fd) {
    PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
    return;
  }

  std::unique_lock<std::mutex> guard(mutex_);
  for (;;) {
    exit_signal_.wait_for(guard,
                          std::chrono::milliseconds(polling_interval_ms_));
    if (!enabled_)
      return;

    lseek(stat_fd.get(), 0, SEEK_SET);

    char c[512];
    if (read(stat_fd.get(), c, sizeof(c)) < 0) {
      PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
      return;
    }
    c[sizeof(c) - 1] = '\0';

    unsigned long int utime = 0l;
    unsigned long int stime = 0l;
    long int rss_pages = -1l;
    PERFETTO_CHECK(
        sscanf(c,
               "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu"
               "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
               &utime, &stime, &rss_pages) == 3);

    uint64_t cpu_time = utime + stime;
    uint64_t rss_bytes = static_cast<uint64_t>(rss_pages) * base::kPageSize;

    CheckMemory(rss_bytes);
    CheckCpu(cpu_time);
  }
}

void Watchdog::CheckMemory(uint64_t rss_bytes) {
  if (memory_limit_bytes_ == 0)
    return;

  // Add the current stat value to the ring buffer and check that the mean
  // remains under our threshold.
  if (memory_window_bytes_.Push(rss_bytes)) {
    if (memory_window_bytes_.Mean() > memory_limit_bytes_) {
      PERFETTO_ELOG(
          "Memory watchdog trigger. Memory window of %f bytes is above the "
          "%" PRIu64 " bytes limit.",
          memory_window_bytes_.Mean(), memory_limit_bytes_);
      kill(getpid(), SIGABRT);
    }
  }
}

void Watchdog::CheckCpu(uint64_t cpu_time) {
  if (cpu_limit_percentage_ == 0)
    return;

  // Add the cpu time to the ring buffer.
  if (cpu_window_time_ticks_.Push(cpu_time)) {
    // Compute the percentage over the whole window and check that it remains
    // under the threshold.
    uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
                                cpu_window_time_ticks_.OldestWhenFull();
    double window_interval_ticks =
        (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
         1000.0) *
        sysconf(_SC_CLK_TCK);
    double percentage = static_cast<double>(difference_ticks) /
                        static_cast<double>(window_interval_ticks) * 100;
    if (percentage > cpu_limit_percentage_) {
      PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
                    "%% CPU limit.",
                    percentage, cpu_limit_percentage_);
      kill(getpid(), SIGABRT);
    }
  }
}

uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
  return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
}

bool Watchdog::WindowedInterval::Push(uint64_t sample) {
  // Add the sample to the current position in the ring buffer.
  buffer_[position_] = sample;

  // Update the position with next one circularily.
  position_ = (position_ + 1) % size_;

  // Set the filled flag the first time we wrap.
  filled_ = filled_ || position_ == 0;
  return filled_;
}

double Watchdog::WindowedInterval::Mean() const {
  return MeanForArray(buffer_.get(), size_);
}

void Watchdog::WindowedInterval::Clear() {
  position_ = 0;
  buffer_.reset(new uint64_t[size_]());
}

void Watchdog::WindowedInterval::Reset(size_t new_size) {
  position_ = 0;
  size_ = new_size;
  buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
}

Watchdog::Timer::Timer(uint32_t ms) {
  if (!ms)
    return;  // No-op timer created when the watchdog is disabled.

  struct sigevent sev = {};
  sev.sigev_notify = SIGEV_THREAD_ID;
  sev._sigev_un._tid = base::GetThreadId();
  sev.sigev_signo = SIGABRT;
  PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid_) != -1);
  struct itimerspec its = {};
  its.it_value.tv_sec = ms / 1000;
  its.it_value.tv_nsec = 1000000L * (ms % 1000);
  PERFETTO_CHECK(timer_settime(timerid_, 0, &its, nullptr) != -1);
}

Watchdog::Timer::~Timer() {
  if (timerid_ != nullptr) {
    timer_delete(timerid_);
  }
}

Watchdog::Timer::Timer(Timer&& other) noexcept {
  timerid_ = other.timerid_;
  other.timerid_ = nullptr;
}

}  // namespace base
}  // namespace perfetto

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

#include "perfetto/ext/base/watchdog.h"

#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)

#include <fcntl.h>
#include <inttypes.h>
#include <signal.h>
#include <stdint.h>

#include <fstream>
#include <thread>

#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/thread_utils.h"
#include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace base {

namespace {

constexpr uint32_t kDefaultPollingInterval = 30 * 1000;

bool IsMultipleOf(uint32_t number, uint32_t divisor) {
  return number >= divisor && number % divisor == 0;
}

double MeanForArray(const uint64_t array[], size_t size) {
  uint64_t total = 0;
  for (size_t i = 0; i < size; i++) {
    total += array[i];
  }
  return static_cast<double>(total / size);

}

}  //  namespace

Watchdog::Watchdog(uint32_t polling_interval_ms)
    : polling_interval_ms_(polling_interval_ms) {}

Watchdog::~Watchdog() {
  if (!thread_.joinable()) {
    PERFETTO_DCHECK(!enabled_);
    return;
  }
  PERFETTO_DCHECK(enabled_);
  enabled_ = false;
  exit_signal_.notify_one();
  thread_.join();
}

Watchdog* Watchdog::GetInstance() {
  static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
  return watchdog;
}

Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms) {
  if (!enabled_.load(std::memory_order_relaxed))
    return Watchdog::Timer(0);

  return Watchdog::Timer(ms);
}

void Watchdog::Start() {
  std::lock_guard<std::mutex> guard(mutex_);
  if (thread_.joinable()) {
    PERFETTO_DCHECK(enabled_);
  } else {
    PERFETTO_DCHECK(!enabled_);

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
    // Kick the thread to start running but only on Android or Linux.
    enabled_ = true;
    thread_ = std::thread(&Watchdog::ThreadMain, this);
#endif
  }
}

void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
  // Update the fields under the lock.
  std::lock_guard<std::mutex> guard(mutex_);

  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);

  size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
  memory_window_bytes_.Reset(size);
  memory_limit_bytes_ = bytes;
}

void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
  std::lock_guard<std::mutex> guard(mutex_);

  PERFETTO_CHECK(percentage <= 100);
  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
                 percentage == 0);

  size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
  cpu_window_time_ticks_.Reset(size);
  cpu_limit_percentage_ = percentage;
}

void Watchdog::ThreadMain() {
  base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
  if (!stat_fd) {
    PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
    return;
  }

  std::unique_lock<std::mutex> guard(mutex_);
  for (;;) {
    exit_signal_.wait_for(guard,
                          std::chrono::milliseconds(polling_interval_ms_));
    if (!enabled_)
      return;

    lseek(stat_fd.get(), 0, SEEK_SET);

    char c[512];
    if (read(stat_fd.get(), c, sizeof(c)) < 0) {
      PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
      return;
    }
    c[sizeof(c) - 1] = '\0';

    unsigned long int utime = 0l;
    unsigned long int stime = 0l;
    long int rss_pages = -1l;
    PERFETTO_CHECK(
        sscanf(c,
               "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu"
               "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
               &utime, &stime, &rss_pages) == 3);

    uint64_t cpu_time = utime + stime;
    uint64_t rss_bytes = static_cast<uint64_t>(rss_pages) * base::kPageSize;

    CheckMemory(rss_bytes);
    CheckCpu(cpu_time);
  }
}

void Watchdog::CheckMemory(uint64_t rss_bytes) {
  if (memory_limit_bytes_ == 0)
    return;

  // Add the current stat value to the ring buffer and check that the mean
  // remains under our threshold.
  if (memory_window_bytes_.Push(rss_bytes)) {
    if (memory_window_bytes_.Mean() > static_cast<double>(memory_limit_bytes_)) {
      PERFETTO_ELOG(
          "Memory watchdog trigger. Memory window of %f bytes is above the "
          "%" PRIu64 " bytes limit.",
          memory_window_bytes_.Mean(), memory_limit_bytes_);
      kill(getpid(), SIGABRT);
    }
  }
}

void Watchdog::CheckCpu(uint64_t cpu_time) {
  if (cpu_limit_percentage_ == 0)
    return;

  // Add the cpu time to the ring buffer.
  if (cpu_window_time_ticks_.Push(cpu_time)) {
    // Compute the percentage over the whole window and check that it remains
    // under the threshold.
    uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
                                cpu_window_time_ticks_.OldestWhenFull();
    double window_interval_ticks =
        (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
         1000.0) *
        static_cast<double>(sysconf(_SC_CLK_TCK));
    double percentage = static_cast<double>(difference_ticks) /
                        static_cast<double>(window_interval_ticks) * 100;
    if (percentage > cpu_limit_percentage_) {
      PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
                    "%% CPU limit.",
                    percentage, cpu_limit_percentage_);
      kill(getpid(), SIGABRT);
    }
  }
}

uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
  return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
}

bool Watchdog::WindowedInterval::Push(uint64_t sample) {
  // Add the sample to the current position in the ring buffer.
  buffer_[position_] = sample;

  // Update the position with next one circularily.
  position_ = (position_ + 1) % size_;

  // Set the filled flag the first time we wrap.
  filled_ = filled_ || position_ == 0;
  return filled_;
}

double Watchdog::WindowedInterval::Mean() const {
  return MeanForArray(buffer_.get(), size_);
}

void Watchdog::WindowedInterval::Clear() {
  position_ = 0;
  buffer_.reset(new uint64_t[size_]());
}

void Watchdog::WindowedInterval::Reset(size_t new_size) {
  position_ = 0;
  size_ = new_size;
  buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
}

Watchdog::Timer::Timer(uint32_t ms) {
  if (!ms)
    return;  // No-op timer created when the watchdog is disabled.

  struct sigevent sev = {};
  sev.sigev_notify = SIGEV_THREAD_ID;
  sev._sigev_un._tid = base::GetThreadId();
  sev.sigev_signo = SIGABRT;
  PERFETTO_CHECK(timer_create(CLOCK_MONOTONIC, &sev, &timerid_) != -1);
  struct itimerspec its = {};
  its.it_value.tv_sec = ms / 1000;
  its.it_value.tv_nsec = 1000000L * (ms % 1000);
  PERFETTO_CHECK(timer_settime(timerid_, 0, &its, nullptr) != -1);
}

Watchdog::Timer::~Timer() {
  if (timerid_ != nullptr) {
    timer_delete(timerid_);
  }
}

Watchdog::Timer::Timer(Timer&& other) noexcept {
  timerid_ = other.timerid_;
  other.timerid_ = nullptr;
}

}  // namespace base
}  // namespace perfetto

#endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
<|endoftext|>


<commit_before>#include "lua_class.h"
#include "../table/table.h"
#include "../util/string_enum.h"

namespace saki
{

bool isValidSuitStr(const std::string &s)
{
    return s.size() == 1 && T34::isValidSuit(s[0]);
}

std::string toLower(const char *s)
{
    std::string res(s);
    std::for_each(res.begin(), res.end(), [](char &c) {
        c = static_cast<char>(std::tolower(c));
    });
    return res;
}

std::pair<Mount::Exit, bool> parseMountExit(const std::string &s)
{
    std::pair<Mount::Exit, bool> res;

    res.second = true;
    if (s == "pii")
        res.first = Mount::Exit::PII;
    else if (s == "rinshan")
        res.first = Mount::Exit::RINSHAN;
    else if (s == "dorahyou")
        res.first = Mount::Exit::DORAHYOU;
    else if (s == "urahyou")
        res.first = Mount::Exit::URAHYOU;
    else
        res.second = false;

    return res;
}

template<typename Class, typename Ret, typename... Args>
class AsTable
{
public:
    using Method = Ret (Class::*)(Args...) const;
    using Table = sol::as_table_t<sol::meta::unqualified_t<Ret>>;

    explicit AsTable(Method method)
        : mMethod(method)
    {
    }

    Table operator()(Class &thiz, Args... args)
    {
        return sol::as_table((thiz.*mMethod)(args...));
    }

private:
    Method mMethod;
};

void setupLuaClasses(const sol::environment &env, LuaUserErrorHandler &error)
{
    setupLuaTile(env, error);
    setupLuaWho(env);
    setupLuaMeld(env, error);
    setupLuaExist(env, error);
    setupLuaMount(env, error);
    setupLuaTileCount(env, error);
    setupLuaHand(env);
    setupLuaGame(env);
}

void setupLuaTile(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<T34>(
        "T34",
        sol::meta_function::construct, sol::factories(
            [&error](int ti) {
                if (ti < 0 || ti >= 34) {
                    error.handleUserError("invalid T34 id");
                    return T34();
                }

                return T34(ti);
            },
            [&error](const std::string s) {
                static const std::array<std::string, 34> dict {
                    "1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m",
                    "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p",
                    "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s",
                    "1f", "2f", "3f", "4f", "1y", "2y", "3y"
                };

                auto it = std::find(dict.begin(), dict.end(), s);
                if (it == dict.end()) {
                    error.handleUserError("invalid T34 string");
                    return T34();
                }

                return T34(static_cast<int>(it - dict.begin()));
            }
        ),
        "id34", &T34::id34,
        "suit", [](T34 t) { return T34::charOf(t.suit()); },
        "val", &T34::val,
        "str34", &T34::str34,
        "isyakuhai", &T34::isYakuhai,
        sol::meta_function::to_string, &T34::str34,
        "all", sol::var(std::vector<T34>(tiles34::ALL34.begin(), tiles34::ALL34.end()))
    );

    env.new_usertype<T37>(
        "T37",
        sol::meta_function::construct, sol::factories(
            [&error](int ti) {
                if (ti < 0 || ti >= 34) {
                    error.handleUserError("invalid T34 id");
                    return T37();
                }

                return T37(ti);
            },
            [&error](const std::string s) {
                if (!T37::isValidStr(s.c_str())) {
                    error.handleUserError("invalid T37 suit");
                    return T37();
                }
                return T37(s.c_str());
            }
        ),
        "isaka5", &T37::isAka5,
        "str37", &T37::str37,
        sol::meta_function::to_string, &T37::str37,
        sol::base_classes, sol::bases<T34>()
    );
}

void setupLuaWho(sol::environment env)
{
    env.new_usertype<Who>(
        "Who",
        "right", &Who::right,
        "cross", &Who::cross,
        "left", &Who::left,
        sol::meta_function::to_string, &Who::index,
        sol::meta_function::equal_to, &Who::operator==
    );
}

void setupLuaMeld(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<M37>(
        "M37",
        "type", [](const M37 &m) {
            return toLower(util::stringOf(m.type()));
        },
        sol::meta_function::index, [&error](const M37 &m, int index) {
            int zeroIndex = index - 1;
            int size = static_cast<int>(m.tiles().size());
            if (zeroIndex < 0 || zeroIndex > size) {
                error.handleUserError("invalid meld index");
                return T37();
            }

            return m[index];
        }
    );
}

void setupLuaExist(sol::environment env, LuaUserErrorHandler &error)
{
    (void) error;
    env.new_usertype<Exist>(
        "Exist",
        "incmk", sol::overload(
            [](Exist &exist, T34 t, int delta) {
                exist.incMk(t, delta);
            },
            [](Exist &exist, const T37 &t, int delta) {
                exist.incMk(t, delta);
            }
        )
    );
}

void setupLuaMount(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<Mount>(
        "Mount",
        "remainpii", &Mount::remainPii,
        "remainrinshan", &Mount::remainRinshan,
        "remaina", sol::overload(
            [](Mount &mount, T34 t) {
                mount.remainA(t);
            },
            [](Mount &mount, const T37 &t) {
                mount.remainA(t);
            }
        ),
        "getdrids", AsTable(&Mount::getDrids),
        "geturids", AsTable(&Mount::getUrids),
        "lighta", sol::overload(
            [](Mount &mount, T34 t, int mk, bool rin) {
                mount.lightA(t, mk, rin);
            },
            [](Mount &mount, T34 t, int mk) {
                mount.lightA(t, mk);
            }
        ),
        "lightb", sol::overload(
            [](Mount &mount, T34 t, int mk, bool rin) {
                mount.lightB(t, mk, rin);
            },
            [](Mount &mount, T34 t, int mk) {
                mount.lightB(t, mk);
            }
        ),
        "incmk", sol::overload(
            [&error](Mount &mount, std::string exit, size_t pos, T34 t, int delta, bool bSpace) {
                auto [e, ok] = parseMountExit(exit);
                if (!ok) {
                    error.handleUserError("invalid mount exit");
                    return;
                }
                mount.incMk(e, pos, t, delta, bSpace);
            },
            [&error](Mount &mount, std::string exit, size_t pos, const T37 &t, int delta, bool bSpace) {
                auto [e, ok] = parseMountExit(exit);
                if (!ok) {
                    error.handleUserError("invalid mount exit");
                    return;
                }
                mount.incMk(e, pos, t, delta, bSpace);
            }
        ),
        "loadb", &Mount::loadB
    );
}

void setupLuaTileCount(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<TileCount>(
        "Tilecount",
        "ct", sol::overload(
            [](const TileCount &tc, T34 t) {
                return tc.ct(t);
            },
            [&error](const TileCount &tc, std::string suit) {
                if (!isValidSuitStr(suit)) {
                    error.handleUserError("invalid suit");
                    return 0;
                }

                return tc.ct(T34::suitOf(suit[0]));
            }
        )
    );
}

void setupLuaHand(sol::environment env)
{
    env.new_usertype<Hand>(
        "Hand",
        "closed", &Hand::closed,
        "ct", &Hand::ct,
        "ctaka5", &Hand::ctAka5,
        "ready", &Hand::ready,
        "step", &Hand::step,
        "step4", &Hand::step4,
        "step7", &Hand::step7,
        "step13", &Hand::step13,
        "effa", AsTable(&Hand::effA),
        "effa4", AsTable(&Hand::effA4),
        "ismenzen", &Hand::isMenzen,
        "barks", AsTable(&Hand::barks),
        "canchii", &Hand::canChii,
        "canchiiasleft", &Hand::canChiiAsLeft,
        "canchiiasmiddle", &Hand::canChiiAsMiddle,
        "canchiiasright", &Hand::canChiiAsRight,
        "canpon", &Hand::canPon,
        "candaiminkan", &Hand::canDaiminkan,
        sol::meta_function::modulus, sol::overload(
            [](const util::Stactor<T37, 5> &ids, const Hand &hand) {
                return ids % hand;
            },
            [](T34 indic, const Hand &hand) {
                return indic % hand;
            }
        )
    );
}

void setupLuaGame(sol::environment env)
{
    env.new_usertype<Table>(
        "Game",
        "gethand", &Table::getHand,
        "getround", &Table::getRound,
        "getextraround", &Table::getExtraRound,
        "getdealer", &Table::getDealer,
        "getselfwind", &Table::getSelfWind,
        "getroundwind", &Table::getRoundWind,
        "getriver", AsTable(&Table::getRiver),
        "riichiestablished", &Table::riichiEstablished
    );
}

sol::table toLuaTable(sol::environment env, const TableEvent &event)
{
    using TE = TableEvent;

    sol::table args = env.create();

    switch (event.type()) {
    case TE::Type::TABLE_STARTED:
        args["seed"] = event.as<TE::TableStarted>().seed;
        break;
    case TE::Type::FIRST_DEALER_CHOSEN:
        args["who"] = event.as<TE::FirstDealerChosen>().who;
        break;
    case TE::Type::ROUND_STARTED: {
        const auto &a = event.as<TE::RoundStarted>();
        args["round"] = a.round;
        args["extraround"] = a.extraRound;
        args["dealer"] = a.dealer;
        args["alllast"] = a.allLast;
        args["deposit"] = a.deposit;
        args["seed"] = a.seed;
        break;
    }
    case TE::Type::DICED: {
        const auto &a = event.as<TE::Diced>();
        args["die1"] = a.die1;
        args["die2"] = a.die2;
        break;
    }
    case TE::Type::DRAWN:
        args["who"] = event.as<TE::Drawn>().who;
        break;
    case TE::Type::DISCARDED:
        args["spin"] = event.as<TE::Discarded>().spin;
        break;
    case TE::Type::RIICHI_CALLED:
        args["who"] = event.as<TE::RiichiCalled>().who;
        break;
    case TE::Type::RIICHI_ESTABLISHED:
        args["who"] = event.as<TE::RiichiEstablished>().who;
        break;
    case TE::Type::BARKED: {
        const auto &a = event.as<TE::Barked>();
        args["who"] = a.who;
        args["bark"] = a.bark;
        args["spin"] = a.spin;
        break;
    }
    case TE::Type::ROUND_ENDED: {
        const auto &a = event.as<TE::RoundEnded>();
        args["result"] = util::stringOf(a.result);
        args["openers"] = a.openers;
        args["gunner"] = a.gunner;
        args["forms"] = a.forms;
        break;
    }
    case TE::Type::TABLE_ENDED: {
        const auto &a = event.as<TE::TableEnded>();
        args["ranks"] = a.ranks;
        args["scores"] = a.scores;
        break;
    }
    case TE::Type::POPPED_UP:
        args["who"] = event.as<TE::PoppedUp>().who;
        break;
    default:
        break;
    }

    return env.create_with(
        "type", util::stringOf(event.type()),
        "args", args
                );
}

} // namespace saki
<commit_msg>add several T34, T37, M37, Who lua api<commit_after>#include "lua_class.h"
#include "../table/table.h"
#include "../util/string_enum.h"

namespace saki
{

bool isValidSuitStr(const std::string &s)
{
    return s.size() == 1 && T34::isValidSuit(s[0]);
}

std::string toLower(const char *s)
{
    std::string res(s);
    std::for_each(res.begin(), res.end(), [](char &c) {
        c = static_cast<char>(std::tolower(c));
    });
    return res;
}

std::pair<Mount::Exit, bool> parseMountExit(const std::string &s)
{
    std::pair<Mount::Exit, bool> res;

    res.second = true;
    if (s == "pii")
        res.first = Mount::Exit::PII;
    else if (s == "rinshan")
        res.first = Mount::Exit::RINSHAN;
    else if (s == "dorahyou")
        res.first = Mount::Exit::DORAHYOU;
    else if (s == "urahyou")
        res.first = Mount::Exit::URAHYOU;
    else
        res.second = false;

    return res;
}

template<typename Class, typename Ret, typename... Args>
class AsTable
{
public:
    using Method = Ret (Class::*)(Args...) const;
    using Table = sol::as_table_t<sol::meta::unqualified_t<Ret>>;

    explicit AsTable(Method method)
        : mMethod(method)
    {
    }

    Table operator()(Class &thiz, Args... args)
    {
        return sol::as_table((thiz.*mMethod)(args...));
    }

private:
    Method mMethod;
};

void setupLuaClasses(const sol::environment &env, LuaUserErrorHandler &error)
{
    setupLuaTile(env, error);
    setupLuaWho(env);
    setupLuaMeld(env, error);
    setupLuaExist(env, error);
    setupLuaMount(env, error);
    setupLuaTileCount(env, error);
    setupLuaHand(env);
    setupLuaGame(env);
}

void setupLuaTile(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<T34>(
        "T34",
        sol::meta_function::construct, sol::factories(
            [&error](int ti) {
                if (ti < 0 || ti >= 34) {
                    error.handleUserError("invalid T34 id");
                    return T34();
                }

                return T34(ti);
            },
            [&error](const std::string s) {
                static const std::array<std::string, 34> dict {
                    "1m", "2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m",
                    "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p",
                    "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s",
                    "1f", "2f", "3f", "4f", "1y", "2y", "3y"
                };

                auto it = std::find(dict.begin(), dict.end(), s);
                if (it == dict.end()) {
                    error.handleUserError("invalid T34 string");
                    return T34();
                }

                return T34(static_cast<int>(it - dict.begin()));
            }
        ),
        "id34", &T34::id34,
        "suit", [](T34 t) { return T34::charOf(t.suit()); },
        "val", &T34::val,
        "str34", &T34::str34,
        "isz", &T34::isZ,
        "isnum", &T34::isNum,
        "isnum19", &T34::isNum19,
        "isyao", &T34::isYao,
        "isyakuhai", &T34::isYakuhai,
        "dora", &T34::dora,
        "indicator", &T34::indicator,
        sol::meta_function::to_string, &T34::str34,
        sol::meta_function::equal_to, &T34::operator==,
        sol::meta_function::less_than, &T34::operator<,
        sol::meta_function::modulus, &T34::operator%,
        "all", sol::var(std::vector<T34>(tiles34::ALL34.begin(), tiles34::ALL34.end()))
    );

    env.new_usertype<T37>(
        "T37",
        sol::meta_function::construct, sol::factories(
            [&error](int ti) {
                if (ti < 0 || ti >= 34) {
                    error.handleUserError("invalid T34 id");
                    return T37();
                }

                return T37(ti);
            },
            [&error](const std::string s) {
                if (!T37::isValidStr(s.c_str())) {
                    error.handleUserError("invalid T37 suit");
                    return T37();
                }
                return T37(s.c_str());
            }
        ),
        "isaka5", &T37::isAka5,
        "lookssame", &T37::looksSame,
        "str37", &T37::str37,
        sol::meta_function::to_string, &T37::str37,
        sol::base_classes, sol::bases<T34>()
    );
}

void setupLuaWho(sol::environment env)
{
    env.new_usertype<Who>(
        "Who",
        "right", &Who::right,
        "cross", &Who::cross,
        "left", &Who::left,
        "bydice", &Who::byDice,
        "byturn", &Who::byTurn,
        "looksat", &Who::looksAt,
        "turnfrom", &Who::turnFrom,
        "index", [](Who w) { return w.index() + 1; },
        sol::meta_function::to_string, [](Who w) { return w.index() + 1; },
        sol::meta_function::equal_to, &Who::operator==
    );
}

void setupLuaMeld(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<M37>(
        "M37",
        "type", [](const M37 &m) {
            return toLower(util::stringOf(m.type()));
        },
        "has", &M37::has,
        sol::meta_function::index, [&error](const M37 &m, int index) {
            int zeroIndex = index - 1;
            int size = static_cast<int>(m.tiles().size());
            if (zeroIndex < 0 || zeroIndex > size) {
                error.handleUserError("invalid meld index");
                return T37();
            }

            return m[index];
        }
    );
}

void setupLuaExist(sol::environment env, LuaUserErrorHandler &error)
{
    (void) error;
    env.new_usertype<Exist>(
        "Exist",
        "incmk", sol::overload(
            [](Exist &exist, T34 t, int delta) {
                exist.incMk(t, delta);
            },
            [](Exist &exist, const T37 &t, int delta) {
                exist.incMk(t, delta);
            }
        )
    );
}

void setupLuaMount(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<Mount>(
        "Mount",
        "remainpii", &Mount::remainPii,
        "remainrinshan", &Mount::remainRinshan,
        "remaina", sol::overload(
            [](Mount &mount, T34 t) {
                mount.remainA(t);
            },
            [](Mount &mount, const T37 &t) {
                mount.remainA(t);
            }
        ),
        "getdrids", AsTable(&Mount::getDrids),
        "geturids", AsTable(&Mount::getUrids),
        "lighta", sol::overload(
            [](Mount &mount, T34 t, int mk, bool rin) {
                mount.lightA(t, mk, rin);
            },
            [](Mount &mount, T34 t, int mk) {
                mount.lightA(t, mk);
            }
        ),
        "lightb", sol::overload(
            [](Mount &mount, T34 t, int mk, bool rin) {
                mount.lightB(t, mk, rin);
            },
            [](Mount &mount, T34 t, int mk) {
                mount.lightB(t, mk);
            }
        ),
        "incmk", sol::overload(
            [&error](Mount &mount, std::string exit, size_t pos, T34 t, int delta, bool bSpace) {
                auto [e, ok] = parseMountExit(exit);
                if (!ok) {
                    error.handleUserError("invalid mount exit");
                    return;
                }
                mount.incMk(e, pos, t, delta, bSpace);
            },
            [&error](Mount &mount, std::string exit, size_t pos, const T37 &t, int delta, bool bSpace) {
                auto [e, ok] = parseMountExit(exit);
                if (!ok) {
                    error.handleUserError("invalid mount exit");
                    return;
                }
                mount.incMk(e, pos, t, delta, bSpace);
            }
        ),
        "loadb", &Mount::loadB
    );
}

void setupLuaTileCount(sol::environment env, LuaUserErrorHandler &error)
{
    env.new_usertype<TileCount>(
        "Tilecount",
        "ct", sol::overload(
            [](const TileCount &tc, T34 t) {
                return tc.ct(t);
            },
            [&error](const TileCount &tc, std::string suit) {
                if (!isValidSuitStr(suit)) {
                    error.handleUserError("invalid suit");
                    return 0;
                }

                return tc.ct(T34::suitOf(suit[0]));
            }
        )
    );
}

void setupLuaHand(sol::environment env)
{
    env.new_usertype<Hand>(
        "Hand",
        "closed", &Hand::closed,
        "ct", &Hand::ct,
        "ctaka5", &Hand::ctAka5,
        "ready", &Hand::ready,
        "step", &Hand::step,
        "step4", &Hand::step4,
        "step7", &Hand::step7,
        "step13", &Hand::step13,
        "effa", AsTable(&Hand::effA),
        "effa4", AsTable(&Hand::effA4),
        "ismenzen", &Hand::isMenzen,
        "barks", AsTable(&Hand::barks),
        "canchii", &Hand::canChii,
        "canchiiasleft", &Hand::canChiiAsLeft,
        "canchiiasmiddle", &Hand::canChiiAsMiddle,
        "canchiiasright", &Hand::canChiiAsRight,
        "canpon", &Hand::canPon,
        "candaiminkan", &Hand::canDaiminkan,
        sol::meta_function::modulus, sol::overload(
            [](const util::Stactor<T37, 5> &ids, const Hand &hand) {
                return ids % hand;
            },
            [](T34 indic, const Hand &hand) {
                return indic % hand;
            }
        )
    );
}

void setupLuaGame(sol::environment env)
{
    env.new_usertype<Table>(
        "Game",
        "gethand", &Table::getHand,
        "getround", &Table::getRound,
        "getextraround", &Table::getExtraRound,
        "getdealer", &Table::getDealer,
        "getselfwind", &Table::getSelfWind,
        "getroundwind", &Table::getRoundWind,
        "getriver", AsTable(&Table::getRiver),
        "riichiestablished", &Table::riichiEstablished
    );
}

sol::table toLuaTable(sol::environment env, const TableEvent &event)
{
    using TE = TableEvent;

    sol::table args = env.create();

    switch (event.type()) {
    case TE::Type::TABLE_STARTED:
        args["seed"] = event.as<TE::TableStarted>().seed;
        break;
    case TE::Type::FIRST_DEALER_CHOSEN:
        args["who"] = event.as<TE::FirstDealerChosen>().who;
        break;
    case TE::Type::ROUND_STARTED: {
        const auto &a = event.as<TE::RoundStarted>();
        args["round"] = a.round;
        args["extraround"] = a.extraRound;
        args["dealer"] = a.dealer;
        args["alllast"] = a.allLast;
        args["deposit"] = a.deposit;
        args["seed"] = a.seed;
        break;
    }
    case TE::Type::DICED: {
        const auto &a = event.as<TE::Diced>();
        args["die1"] = a.die1;
        args["die2"] = a.die2;
        break;
    }
    case TE::Type::DRAWN:
        args["who"] = event.as<TE::Drawn>().who;
        break;
    case TE::Type::DISCARDED:
        args["spin"] = event.as<TE::Discarded>().spin;
        break;
    case TE::Type::RIICHI_CALLED:
        args["who"] = event.as<TE::RiichiCalled>().who;
        break;
    case TE::Type::RIICHI_ESTABLISHED:
        args["who"] = event.as<TE::RiichiEstablished>().who;
        break;
    case TE::Type::BARKED: {
        const auto &a = event.as<TE::Barked>();
        args["who"] = a.who;
        args["bark"] = a.bark;
        args["spin"] = a.spin;
        break;
    }
    case TE::Type::ROUND_ENDED: {
        const auto &a = event.as<TE::RoundEnded>();
        args["result"] = util::stringOf(a.result);
        args["openers"] = a.openers;
        args["gunner"] = a.gunner;
        args["forms"] = a.forms;
        break;
    }
    case TE::Type::TABLE_ENDED: {
        const auto &a = event.as<TE::TableEnded>();
        args["ranks"] = a.ranks;
        args["scores"] = a.scores;
        break;
    }
    case TE::Type::POPPED_UP:
        args["who"] = event.as<TE::PoppedUp>().who;
        break;
    default:
        break;
    }

    return env.create_with(
        "type", util::stringOf(event.type()),
        "args", args
                );
}

} // namespace saki
<|endoftext|>


<commit_before>#include <benchmark/benchmark.h>
#include <iostream>
#include <boost/optional/optional.hpp>

namespace
{
    struct TestReporter : benchmark::BenchmarkReporter
    {
        boost::optional<bool> ok;
        benchmark::ConsoleReporter display;

        bool ReportContext(const Context &context) override
        {
            return display.ReportContext(context);
        }

        void ReportRuns(const std::vector<Run> &report) override
        {
            for (const Run &run : report)
            {
                if (run.benchmark_name == "MediumRequestAndResponseOverInProcessPipe/4k")
                {
                    // These values should be about right for the super slow processors on travis-ci.
                    const double required_bytes =
#ifdef NDEBUG
                        1200000
#else
                        26000
#endif
                        ;
                    if (run.bytes_per_second >= required_bytes)
                    {
                        if (run.bytes_per_second < (required_bytes * 2))
                        {
                            ok = true;
                        }
                        else
                        {
                            std::cerr << run.benchmark_name
                                      << " is much faster than required which is suspicious: " << run.bytes_per_second
                                      << " bytes/s (" << required_bytes << " required)\n";
                            ok = false;
                        }
                    }
                    else
                    {
                        std::cerr << run.benchmark_name << " is too slow: " << run.bytes_per_second << " bytes/s ("
                                  << required_bytes << " required)\n";
                        ok = false;
                    }
                }
            }
            return display.ReportRuns(report);
        }
    };
}

int main(int argc, char **argv)
{
    benchmark::Initialize(&argc, argv);
    TestReporter reporter;
    benchmark::RunSpecifiedBenchmarks(&reporter);
    if (!reporter.ok)
    {
        std::cerr << "At least one of the required test benchmarks did not run\n";
        return 1;
    }
    return (*reporter.ok ? 0 : 1);
}
<commit_msg>benchmark: debug is even slower now<commit_after>#include <benchmark/benchmark.h>
#include <iostream>
#include <boost/optional/optional.hpp>

namespace
{
    struct TestReporter : benchmark::BenchmarkReporter
    {
        boost::optional<bool> ok;
        benchmark::ConsoleReporter display;

        bool ReportContext(const Context &context) override
        {
            return display.ReportContext(context);
        }

        void ReportRuns(const std::vector<Run> &report) override
        {
            for (const Run &run : report)
            {
                if (run.benchmark_name == "MediumRequestAndResponseOverInProcessPipe/4k")
                {
                    // These values should be about right for the super slow processors on travis-ci.
                    const double required_bytes =
#ifdef NDEBUG
                        1200000
#else
                        19500
#endif
                        ;
                    if (run.bytes_per_second >= required_bytes)
                    {
                        if (run.bytes_per_second < (required_bytes * 2))
                        {
                            ok = true;
                        }
                        else
                        {
                            std::cerr << run.benchmark_name
                                      << " is much faster than required which is suspicious: " << run.bytes_per_second
                                      << " bytes/s (" << required_bytes << " required)\n";
                            ok = false;
                        }
                    }
                    else
                    {
                        std::cerr << run.benchmark_name << " is too slow: " << run.bytes_per_second << " bytes/s ("
                                  << required_bytes << " required)\n";
                        ok = false;
                    }
                }
            }
            return display.ReportRuns(report);
        }
    };
}

int main(int argc, char **argv)
{
    benchmark::Initialize(&argc, argv);
    TestReporter reporter;
    benchmark::RunSpecifiedBenchmarks(&reporter);
    if (!reporter.ok)
    {
        std::cerr << "At least one of the required test benchmarks did not run\n";
        return 1;
    }
    return (*reporter.ok ? 0 : 1);
}
<|endoftext|>