<commit_before>// apt_signs.cxx -- build airport signs on the fly
//
// Written by Curtis Olson, started July 2001.
//
// Copyright (C) 2001  Curtis L. Olson  - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include <vector>

#include <osg/StateSet>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>

#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>

#include "apt_signs.hxx"

#define SIGN "OBJECT_SIGN: "
#define RWY "OBJECT_RUNWAY_SIGN: "

SG_USING_STD(vector);

// for temporary storage of sign elements
struct element_info {
    element_info(SGMaterial *m, osg::StateSet *s, SGMaterialGlyph *g, double h)
        : material(m), state(s), glyph(g), height(h)
    {
        scale = h * m->get_xsize()
                / (m->get_ysize() < 0.001 ? 1.0 : m->get_ysize());
    }
    SGMaterial *material;
    osg::StateSet *state;
    SGMaterialGlyph *glyph;
    double height;
    double scale;
};

// standard panel height sizes
const double HT[5] = {0.460, 0.610, 0.760, 1.220, 0.760};

// translation table for "command" to "glyph name"
struct pair {
    const char *keyword;
    const char *glyph_name;
} cmds[] = {
    {"@u",       "up"},
    {"@d",       "down"},
    {"@l",       "left"},
    {"@lu",      "left-up"},
    {"@ul",      "left-up"},
    {"@ld",      "left-down"},
    {"@dl",      "left-down"},
    {"@r",       "right"},
    {"@ru",      "right-up"},
    {"@ur",      "right-up"},
    {"@rd",      "right-down"},
    {"@dr",      "right-down"},
    {0, 0},
};

// see $FG_ROOT/Docs/README.scenery
//
osg::Node*
SGMakeSign(SGMaterialLib *matlib, const string& path, const string& content)
{
    double sign_height = 1.0;  // meter
    bool lighted = true;
    string newmat = "BlackSign";

    vector<element_info *> elements;
    element_info *close = 0;
    double total_width = 0.0;
    bool cmd = false;
    int size = -1;
    char oldtype = 0, newtype = 0;

    osg::Group* object = new osg::Group;
    object->setName(content);

    SGMaterial *material;
    osg::StateSet *lighted_state;
    osg::StateSet *unlighted_state;

    // Part I: parse & measure
    for (const char *s = content.data(); *s; s++) {
        string name;
        string value;

        if (*s == '{') {
            if (cmd)
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unexpected { in sign contents");
            cmd = true;
            continue;

        } else if (*s == '}') {
            if (!cmd)
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unexpected } in sign contents");
            cmd = false;
            continue;

        } else if (!cmd) {
            name = *s;

        } else {
            if (*s == ',')
                continue;

            for (; *s; s++) {
                name += *s;
                if (s[1] == ',' || s[1] == '}' || s[1] == '=')
                    break;
            }
            if (!*s) {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
            } else if (s[1] == '=') {
                for (s += 2; *s; s++) {
                    value += *s;
                    if (s[1] == ',' || s[1] == '}')
                        break;
                }
                if (!*s)
                    SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
            }

            if (name == "@size") {
                sign_height = strtod(value.data(), 0);
                continue;
            }

            if (name == "@light") {
                lighted = (value != "0" && value != "no" && value != "off" && value != "false");
                continue;
            }

            if (name == "@material") {
                newmat = value.data();
                continue;

            } else if (name.size() == 2 || name.size() == 3) {
                string n = name;
                if (n.size() == 3 && n[2] >= '1' && n[2] <= '5') {
                    size = n[2] - '1';
                    n = n.substr(0, 2);
                }

                if (n == "@Y") {
                    if (size < 3) {
                        sign_height = HT[size < 0 ? 2 : size];
                        newmat = "YellowSign";
                        newtype = 'Y';
                        continue;
                    }

                } else if (n == "@R") {
                    if (size < 3) {
                        sign_height = HT[size < 0 ? 2 : size];
                        newmat = "RedSign";
                        newtype = 'R';
                        continue;
                    }

                } else if (n == "@L") {
                    if (size < 3) {
                        sign_height = HT[size < 0 ? 2 : size];
                        newmat = "FramedSign";
                        newtype = 'L';
                        continue;
                    }

                } else if (n == "@B") {
                    if (size < 0 || size == 3 || size == 4) {
                        sign_height = HT[size < 0 ? 3 : size];
                        newmat = "BlackSign";
                        newtype = 'B';
                        continue;
                    }
                }
            }

            for (int i = 0; cmds[i].keyword; i++) {
                if (name == cmds[i].keyword) {
                    name = cmds[i].glyph_name;
                    break;
                }
            }

            if (name[0] == '@') {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown command `" << name << '\'');
                continue;
            }
        }

        if (newmat.size()) {
            material = matlib->find(newmat);
            if (!material) {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
                continue;
            }

            // set material states (lighted & unlighted)
            lighted_state = material->get_state();
            string u = newmat + ".unlighted";

            SGMaterial *m = matlib->find(u);
            if (m) {
                unlighted_state = m->get_state();
            } else {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << u << '\'');
                unlighted_state = lighted_state;
            }
            newmat = "";
        }

        SGMaterialGlyph *glyph = material->get_glyph(name);
        if (!glyph) {
            SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph `" << *s << '\'');
            continue;
        }

        // in managed mode push frame stop and frame start first
        osg::StateSet *state = lighted ? lighted_state : unlighted_state;
        element_info *e;
        if (newtype && newtype != oldtype) {
            if (close) {
                elements.push_back(close);
                total_width += close->glyph->get_width() * close->scale;
                close = 0;
            }
            oldtype = newtype;
            SGMaterialGlyph *g = material->get_glyph("stop-frame");
            if (g)
                close = new element_info(material, state, g, sign_height);
            g = material->get_glyph("start-frame");
            if (g) {
                e = new element_info(material, state, g, sign_height);
                elements.push_back(e);
                total_width += e->glyph->get_width() * e->scale;
            }
        }
        // now the actually requested glyph
        e = new element_info(material, state, glyph, sign_height);
        elements.push_back(e);
        total_width += e->glyph->get_width() * e->scale;
    }

    // in managed mode close frame
    if (close) {
        elements.push_back(close);
        total_width += close->glyph->get_width() * close->scale;
        close = 0;
    }

    // Part II: typeset
    double hpos = -total_width / 2;
    const double dist = 0.25;        // hard-code distance from surface for now

    for (unsigned int i = 0; i < elements.size(); i++) {
        element_info *element = elements[i];

        double xoffset = element->glyph->get_left();
        double height = element->height;
        double width = element->glyph->get_width();
        double abswidth = width * element->scale;

        // vertices
        osg::Vec3Array* vl = new osg::Vec3Array;
        vl->push_back(osg::Vec3(0, hpos,            dist));
        vl->push_back(osg::Vec3(0, hpos + abswidth, dist));
        vl->push_back(osg::Vec3(0, hpos,            dist + height));
        vl->push_back(osg::Vec3(0, hpos + abswidth, dist + height));

        // texture coordinates
        osg::Vec2Array* tl = new osg::Vec2Array;
        tl->push_back(osg::Vec2(xoffset,         0));
        tl->push_back(osg::Vec2(xoffset + width, 0));
        tl->push_back(osg::Vec2(xoffset,         1));
        tl->push_back(osg::Vec2(xoffset + width, 1));

        // normals
        osg::Vec3Array* nl = new osg::Vec3Array;
        nl->push_back(osg::Vec3(0, -1, 0));

        // colors
        osg::Vec4Array* cl = new osg::Vec4Array;
        cl->push_back(osg::Vec4(1, 1, 1, 1));

        osg::Geometry* geometry = new osg::Geometry;
        geometry->setVertexArray(vl);
        geometry->setNormalArray(nl);
        geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
        geometry->setColorArray(cl);
        geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
        geometry->setTexCoordArray(0, tl);
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geometry);
        geode->setStateSet(element->state);

        object->addChild(geode);
        hpos += abswidth;
        delete element;
    }

    // minimalistic backside
    osg::Vec3Array* vl = new osg::Vec3Array;
    vl->push_back(osg::Vec3(0, hpos,               dist));
    vl->push_back(osg::Vec3(0, hpos - total_width, dist));
    vl->push_back(osg::Vec3(0, hpos,               dist + sign_height));
    vl->push_back(osg::Vec3(0, hpos - total_width, dist + sign_height));

    osg::Vec3Array* nl = new osg::Vec3Array;
    nl->push_back(osg::Vec3(0, 1, 0));

    osg::Geometry* geometry = new osg::Geometry;
    geometry->setVertexArray(vl);
    geometry->setNormalArray(nl);
    geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
    geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geometry);
    SGMaterial *mat = matlib->find("BlackSign");
    if (mat)
      geode->setStateSet(mat->get_state());
    object->addChild(geode);

    return object;
}

osg::Node*
SGMakeRunwaySign(SGMaterialLib *matlib, const string& path, const string& name)
{
    // for demo purposes we assume each element (letter) is 1x1 meter.
    // Sign is placed 0.25 meters above the ground

    float width = name.length() / 3.0;

    osg::Vec3 corner(-width, 0, 0.25f);
    osg::Vec3 widthVec(2*width + 1, 0, 0);
    osg::Vec3 heightVec(0, 0, 1);
    osg::Geometry* geometry;
    geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);

    SGMaterial *mat = matlib->find(name);
    if (mat)
      geometry->setStateSet(mat->get_state());

    osg::Geode* geode = new osg::Geode;
    geode->setName(name);
    geode->addDrawable(geometry);

    return geode;
}
<commit_msg>use new arrow shortcuts for compatibility reasons (will be removed later)<commit_after>// apt_signs.cxx -- build airport signs on the fly
//
// Written by Curtis Olson, started July 2001.
//
// Copyright (C) 2001  Curtis L. Olson  - http://www.flightgear.org/~curt
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//
// $Id$

#ifdef HAVE_CONFIG_H
#  include <simgear_config.h>
#endif

#include <vector>

#include <osg/StateSet>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>

#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>

#include "apt_signs.hxx"

#define SIGN "OBJECT_SIGN: "
#define RWY "OBJECT_RUNWAY_SIGN: "

SG_USING_STD(vector);

// for temporary storage of sign elements
struct element_info {
    element_info(SGMaterial *m, osg::StateSet *s, SGMaterialGlyph *g, double h)
        : material(m), state(s), glyph(g), height(h)
    {
        scale = h * m->get_xsize()
                / (m->get_ysize() < 0.001 ? 1.0 : m->get_ysize());
    }
    SGMaterial *material;
    osg::StateSet *state;
    SGMaterialGlyph *glyph;
    double height;
    double scale;
};

// standard panel height sizes
const double HT[5] = {0.460, 0.610, 0.760, 1.220, 0.760};

// translation table for "command" to "glyph name"
struct pair {
    const char *keyword;
    const char *glyph_name;
} cmds[] = {
    {"@u",       "^u"},
    {"@d",       "^d"},
    {"@l",       "^l"},
    {"@lu",      "^lu"},
    {"@ul",      "^lu"},
    {"@ld",      "^ld"},
    {"@dl",      "^ld"},
    {"@r",       "^r"},
    {"@ru",      "^ru"},
    {"@ur",      "^ru"},
    {"@rd",      "^rd"},
    {"@dr",      "^rd"},
    {0, 0},
};

// see $FG_ROOT/Docs/README.scenery
//
osg::Node*
SGMakeSign(SGMaterialLib *matlib, const string& path, const string& content)
{
    double sign_height = 1.0;  // meter
    bool lighted = true;
    string newmat = "BlackSign";

    vector<element_info *> elements;
    element_info *close = 0;
    double total_width = 0.0;
    bool cmd = false;
    int size = -1;
    char oldtype = 0, newtype = 0;

    osg::Group* object = new osg::Group;
    object->setName(content);

    SGMaterial *material;
    osg::StateSet *lighted_state;
    osg::StateSet *unlighted_state;

    // Part I: parse & measure
    for (const char *s = content.data(); *s; s++) {
        string name;
        string value;

        if (*s == '{') {
            if (cmd)
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unexpected { in sign contents");
            cmd = true;
            continue;

        } else if (*s == '}') {
            if (!cmd)
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unexpected } in sign contents");
            cmd = false;
            continue;

        } else if (!cmd) {
            name = *s;

        } else {
            if (*s == ',')
                continue;

            for (; *s; s++) {
                name += *s;
                if (s[1] == ',' || s[1] == '}' || s[1] == '=')
                    break;
            }
            if (!*s) {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
            } else if (s[1] == '=') {
                for (s += 2; *s; s++) {
                    value += *s;
                    if (s[1] == ',' || s[1] == '}')
                        break;
                }
                if (!*s)
                    SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
            }

            if (name == "@size") {
                sign_height = strtod(value.data(), 0);
                continue;
            }

            if (name == "@light") {
                lighted = (value != "0" && value != "no" && value != "off" && value != "false");
                continue;
            }

            if (name == "@material") {
                newmat = value.data();
                continue;

            } else if (name.size() == 2 || name.size() == 3) {
                string n = name;
                if (n.size() == 3 && n[2] >= '1' && n[2] <= '5') {
                    size = n[2] - '1';
                    n = n.substr(0, 2);
                }

                if (n == "@Y") {
                    if (size < 3) {
                        sign_height = HT[size < 0 ? 2 : size];
                        newmat = "YellowSign";
                        newtype = 'Y';
                        continue;
                    }

                } else if (n == "@R") {
                    if (size < 3) {
                        sign_height = HT[size < 0 ? 2 : size];
                        newmat = "RedSign";
                        newtype = 'R';
                        continue;
                    }

                } else if (n == "@L") {
                    if (size < 3) {
                        sign_height = HT[size < 0 ? 2 : size];
                        newmat = "FramedSign";
                        newtype = 'L';
                        continue;
                    }

                } else if (n == "@B") {
                    if (size < 0 || size == 3 || size == 4) {
                        sign_height = HT[size < 0 ? 3 : size];
                        newmat = "BlackSign";
                        newtype = 'B';
                        continue;
                    }
                }
            }

            for (int i = 0; cmds[i].keyword; i++) {
                if (name == cmds[i].keyword) {
                    name = cmds[i].glyph_name;
                    break;
                }
            }

            if (name[0] == '@') {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown command `" << name << '\'');
                continue;
            }
        }

        if (newmat.size()) {
            material = matlib->find(newmat);
            if (!material) {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << newmat << '\'');
                continue;
            }

            // set material states (lighted & unlighted)
            lighted_state = material->get_state();
            string u = newmat + ".unlighted";

            SGMaterial *m = matlib->find(u);
            if (m) {
                unlighted_state = m->get_state();
            } else {
                SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "ignoring unknown material `" << u << '\'');
                unlighted_state = lighted_state;
            }
            newmat = "";
        }

        SGMaterialGlyph *glyph = material->get_glyph(name);
        if (!glyph) {
            SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph `" << *s << '\'');
            continue;
        }

        // in managed mode push frame stop and frame start first
        osg::StateSet *state = lighted ? lighted_state : unlighted_state;
        element_info *e;
        if (newtype && newtype != oldtype) {
            if (close) {
                elements.push_back(close);
                total_width += close->glyph->get_width() * close->scale;
                close = 0;
            }
            oldtype = newtype;
            SGMaterialGlyph *g = material->get_glyph("stop-frame");
            if (g)
                close = new element_info(material, state, g, sign_height);
            g = material->get_glyph("start-frame");
            if (g) {
                e = new element_info(material, state, g, sign_height);
                elements.push_back(e);
                total_width += e->glyph->get_width() * e->scale;
            }
        }
        // now the actually requested glyph
        e = new element_info(material, state, glyph, sign_height);
        elements.push_back(e);
        total_width += e->glyph->get_width() * e->scale;
    }

    // in managed mode close frame
    if (close) {
        elements.push_back(close);
        total_width += close->glyph->get_width() * close->scale;
        close = 0;
    }

    // Part II: typeset
    double hpos = -total_width / 2;
    const double dist = 0.25;        // hard-code distance from surface for now

    for (unsigned int i = 0; i < elements.size(); i++) {
        element_info *element = elements[i];

        double xoffset = element->glyph->get_left();
        double height = element->height;
        double width = element->glyph->get_width();
        double abswidth = width * element->scale;

        // vertices
        osg::Vec3Array* vl = new osg::Vec3Array;
        vl->push_back(osg::Vec3(0, hpos,            dist));
        vl->push_back(osg::Vec3(0, hpos + abswidth, dist));
        vl->push_back(osg::Vec3(0, hpos,            dist + height));
        vl->push_back(osg::Vec3(0, hpos + abswidth, dist + height));

        // texture coordinates
        osg::Vec2Array* tl = new osg::Vec2Array;
        tl->push_back(osg::Vec2(xoffset,         0));
        tl->push_back(osg::Vec2(xoffset + width, 0));
        tl->push_back(osg::Vec2(xoffset,         1));
        tl->push_back(osg::Vec2(xoffset + width, 1));

        // normals
        osg::Vec3Array* nl = new osg::Vec3Array;
        nl->push_back(osg::Vec3(0, -1, 0));

        // colors
        osg::Vec4Array* cl = new osg::Vec4Array;
        cl->push_back(osg::Vec4(1, 1, 1, 1));

        osg::Geometry* geometry = new osg::Geometry;
        geometry->setVertexArray(vl);
        geometry->setNormalArray(nl);
        geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
        geometry->setColorArray(cl);
        geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
        geometry->setTexCoordArray(0, tl);
        geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
        osg::Geode* geode = new osg::Geode;
        geode->addDrawable(geometry);
        geode->setStateSet(element->state);

        object->addChild(geode);
        hpos += abswidth;
        delete element;
    }

    // minimalistic backside
    osg::Vec3Array* vl = new osg::Vec3Array;
    vl->push_back(osg::Vec3(0, hpos,               dist));
    vl->push_back(osg::Vec3(0, hpos - total_width, dist));
    vl->push_back(osg::Vec3(0, hpos,               dist + sign_height));
    vl->push_back(osg::Vec3(0, hpos - total_width, dist + sign_height));

    osg::Vec3Array* nl = new osg::Vec3Array;
    nl->push_back(osg::Vec3(0, 1, 0));

    osg::Geometry* geometry = new osg::Geometry;
    geometry->setVertexArray(vl);
    geometry->setNormalArray(nl);
    geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
    geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
    osg::Geode* geode = new osg::Geode;
    geode->addDrawable(geometry);
    SGMaterial *mat = matlib->find("BlackSign");
    if (mat)
      geode->setStateSet(mat->get_state());
    object->addChild(geode);

    return object;
}

osg::Node*
SGMakeRunwaySign(SGMaterialLib *matlib, const string& path, const string& name)
{
    // for demo purposes we assume each element (letter) is 1x1 meter.
    // Sign is placed 0.25 meters above the ground

    float width = name.length() / 3.0;

    osg::Vec3 corner(-width, 0, 0.25f);
    osg::Vec3 widthVec(2*width + 1, 0, 0);
    osg::Vec3 heightVec(0, 0, 1);
    osg::Geometry* geometry;
    geometry = osg::createTexturedQuadGeometry(corner, widthVec, heightVec);

    SGMaterial *mat = matlib->find(name);
    if (mat)
      geometry->setStateSet(mat->get_state());

    osg::Geode* geode = new osg::Geode;
    geode->setName(name);
    geode->addDrawable(geometry);

    return geode;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 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 "src/trace_processor/importers/proto/android_probes_module.h"

#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/string_writer.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "src/trace_processor/importers/proto/android_probes_parser.h"
#include "src/trace_processor/importers/proto/android_probes_tracker.h"
#include "src/trace_processor/timestamped_trace_piece.h"
#include "src/trace_processor/trace_sorter.h"

#include "protos/perfetto/config/trace_config.pbzero.h"
#include "protos/perfetto/trace/power/power_rails.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {
namespace trace_processor {
namespace {

const char* MapToFriendlyPowerRailName(base::StringView raw) {
  if (raw == "S4M_VDD_CPUCL0") {
    return "cpu.little";
  } else if (raw == "S3M_VDD_CPUCL1") {
    return "cpu.mid";
  } else if (raw == "S2M_VDD_CPUCL2") {
    return "cpu.big";
  } else if (raw == "S5M_VDD_INT") {
    return "system.fabric";
  } else if (raw == "PPVAR_VSYS_PWR_DISP") {
    return "display";
  } else if (raw == "VSYS_PWR_MODEM") {
    return "modem";
  } else if (raw == "S1M_VDD_MIF") {
    return "memory.interface";
  } else if (raw == "VSYS_PWR_WLAN_BT") {
    return "wifi.bt";
  } else if (raw == "L2S_VDD_AOC_RET") {
    return "aoc.memory";
  } else if (raw == "S9S_VDD_AOC") {
    return "aoc.logic";
  } else if (raw == "S5S_VDDQ_MEM") {
    return "ddr.a";
  } else if (raw == "S10S_VDD2L") {
    return "ddr.b";
  } else if (raw == "S4S_VDD2H_MEM") {
    return "ddr.c";
  } else if (raw == "S2S_VDD_G3D") {
    return "gpu";
  } else if (raw == "L9S_GNSS_CORE") {
    return "gps";
  } else if (raw == "VSYS_PWR_RFFE") {
    return "radio.frontend";
  }
  return nullptr;
}

}  // namespace

using perfetto::protos::pbzero::TracePacket;

AndroidProbesModule::AndroidProbesModule(TraceProcessorContext* context)
    : parser_(context), context_(context) {
  RegisterForField(TracePacket::kBatteryFieldNumber, context);
  RegisterForField(TracePacket::kPowerRailsFieldNumber, context);
  RegisterForField(TracePacket::kAndroidLogFieldNumber, context);
  RegisterForField(TracePacket::kPackagesListFieldNumber, context);
  RegisterForField(TracePacket::kInitialDisplayStateFieldNumber, context);
}

ModuleResult AndroidProbesModule::TokenizePacket(
    const protos::pbzero::TracePacket_Decoder&,
    TraceBlobView* packet,
    int64_t packet_timestamp,
    PacketSequenceState* state,
    uint32_t field_id) {
  if (field_id != TracePacket::kPowerRailsFieldNumber)
    return ModuleResult::Ignored();

  // Power rails are similar to ftrace in that they have many events, each with
  // their own timestamp, packed inside a single TracePacket. This means that,
  // similar to ftrace, we need to unpack them and individually sort them.

  // However, as these events are not perf sensitive, it's not worth adding
  // a lot of machinery to shepherd these events through the sorting queues
  // in a special way. Therefore, we just forge new packets and sort them as if
  // they came from the underlying trace.

  protos::pbzero::TracePacket::Decoder decoder(packet->data(),
                                               packet->length());
  auto power_rails = decoder.power_rails();
  protos::pbzero::PowerRails::Decoder evt(power_rails.data, power_rails.size);

  for (auto it = evt.rail_descriptor(); it; ++it) {
    protos::pbzero::PowerRails::RailDescriptor::Decoder desc(*it);
    uint32_t idx = desc.index();
    if (PERFETTO_UNLIKELY(idx > 256)) {
      PERFETTO_DLOG("Skipping excessively large power_rail index %" PRIu32,
                    idx);
      continue;
    }
    char counter_name[255];
    base::StringWriter writer(counter_name, base::ArraySize(counter_name));
    const char* friendly_name = MapToFriendlyPowerRailName(desc.rail_name());
    if (friendly_name) {
      writer.AppendStringView("power.rails.");
      writer.AppendStringView(friendly_name);
    } else {
      writer.AppendStringView("power.");
      writer.AppendStringView(desc.rail_name());
      writer.AppendStringView("_uws");
    }
    AndroidProbesTracker::GetOrCreate(context_)->SetPowerRailName(
        desc.index(), context_->storage->InternString(writer.GetStringView()));
  }

  // For each energy data message, turn it into its own trace packet
  // making sure its timestamp is consistent between the packet level and
  // the EnergyData level.
  for (auto it = evt.energy_data(); it; ++it) {
    protozero::ConstBytes bytes = *it;
    protos::pbzero::PowerRails_EnergyData_Decoder data(bytes.data, bytes.size);
    int64_t actual_ts =
        data.has_timestamp_ms()
            ? static_cast<int64_t>(data.timestamp_ms()) * 1000000
            : packet_timestamp;

    protozero::HeapBuffered<protos::pbzero::TracePacket> data_packet;
    data_packet->set_timestamp(static_cast<uint64_t>(actual_ts));

    auto* energy = data_packet->set_power_rails()->add_energy_data();
    energy->set_energy(data.energy());
    energy->set_index(data.index());
    energy->set_timestamp_ms(static_cast<uint64_t>(actual_ts / 1000000));

    std::vector<uint8_t> vec = data_packet.SerializeAsArray();
    TraceBlob blob = TraceBlob::CopyFrom(vec.data(), vec.size());
    context_->sorter->PushTracePacket(actual_ts, state,
                                      TraceBlobView(std::move(blob)));
  }

  return ModuleResult::Handled();
}

void AndroidProbesModule::ParsePacket(const TracePacket::Decoder& decoder,
                                      const TimestampedTracePiece& ttp,
                                      uint32_t field_id) {
  switch (field_id) {
    case TracePacket::kBatteryFieldNumber:
      parser_.ParseBatteryCounters(ttp.timestamp, decoder.battery());
      return;
    case TracePacket::kPowerRailsFieldNumber:
      parser_.ParsePowerRails(ttp.timestamp, decoder.power_rails());
      return;
    case TracePacket::kAndroidLogFieldNumber:
      parser_.ParseAndroidLogPacket(decoder.android_log());
      return;
    case TracePacket::kPackagesListFieldNumber:
      parser_.ParseAndroidPackagesList(decoder.packages_list());
      return;
    case TracePacket::kInitialDisplayStateFieldNumber:
      parser_.ParseInitialDisplayState(ttp.timestamp,
                                       decoder.initial_display_state());
      return;
  }
}

void AndroidProbesModule::ParseTraceConfig(
    const protos::pbzero::TraceConfig::Decoder& decoder) {
  if (decoder.has_statsd_metadata()) {
    parser_.ParseStatsdMetadata(decoder.statsd_metadata());
  }
}

}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>[Trace processor] Add 2 new power rail names<commit_after>/*
 * Copyright (C) 2019 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 "src/trace_processor/importers/proto/android_probes_module.h"

#include "perfetto/base/build_config.h"
#include "perfetto/ext/base/string_writer.h"
#include "perfetto/protozero/scattered_heap_buffer.h"
#include "src/trace_processor/importers/proto/android_probes_parser.h"
#include "src/trace_processor/importers/proto/android_probes_tracker.h"
#include "src/trace_processor/timestamped_trace_piece.h"
#include "src/trace_processor/trace_sorter.h"

#include "protos/perfetto/config/trace_config.pbzero.h"
#include "protos/perfetto/trace/power/power_rails.pbzero.h"
#include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {
namespace trace_processor {
namespace {

const char* MapToFriendlyPowerRailName(base::StringView raw) {
  if (raw == "S4M_VDD_CPUCL0") {
    return "cpu.little";
  } else if (raw == "S3M_VDD_CPUCL1") {
    return "cpu.mid";
  } else if (raw == "S2M_VDD_CPUCL2") {
    return "cpu.big";
  } else if (raw == "S5M_VDD_INT") {
    return "system.fabric";
  } else if (raw == "S10M_VDD_TPU") {
    return "tpu";
  } else if (raw == "PPVAR_VSYS_PWR_DISP" || raw == "VSYS_PWR_DISPLAY") {
    return "display";
  } else if (raw == "VSYS_PWR_MODEM") {
    return "modem";
  } else if (raw == "S1M_VDD_MIF") {
    return "memory.interface";
  } else if (raw == "VSYS_PWR_WLAN_BT") {
    return "wifi.bt";
  } else if (raw == "L2S_VDD_AOC_RET") {
    return "aoc.memory";
  } else if (raw == "S9S_VDD_AOC") {
    return "aoc.logic";
  } else if (raw == "S5S_VDDQ_MEM") {
    return "ddr.a";
  } else if (raw == "S10S_VDD2L") {
    return "ddr.b";
  } else if (raw == "S4S_VDD2H_MEM") {
    return "ddr.c";
  } else if (raw == "S2S_VDD_G3D") {
    return "gpu";
  } else if (raw == "L9S_GNSS_CORE") {
    return "gps";
  } else if (raw == "VSYS_PWR_RFFE") {
    return "radio.frontend";
  }
  return nullptr;
}

}  // namespace

using perfetto::protos::pbzero::TracePacket;

AndroidProbesModule::AndroidProbesModule(TraceProcessorContext* context)
    : parser_(context), context_(context) {
  RegisterForField(TracePacket::kBatteryFieldNumber, context);
  RegisterForField(TracePacket::kPowerRailsFieldNumber, context);
  RegisterForField(TracePacket::kAndroidLogFieldNumber, context);
  RegisterForField(TracePacket::kPackagesListFieldNumber, context);
  RegisterForField(TracePacket::kInitialDisplayStateFieldNumber, context);
}

ModuleResult AndroidProbesModule::TokenizePacket(
    const protos::pbzero::TracePacket_Decoder&,
    TraceBlobView* packet,
    int64_t packet_timestamp,
    PacketSequenceState* state,
    uint32_t field_id) {
  if (field_id != TracePacket::kPowerRailsFieldNumber)
    return ModuleResult::Ignored();

  // Power rails are similar to ftrace in that they have many events, each with
  // their own timestamp, packed inside a single TracePacket. This means that,
  // similar to ftrace, we need to unpack them and individually sort them.

  // However, as these events are not perf sensitive, it's not worth adding
  // a lot of machinery to shepherd these events through the sorting queues
  // in a special way. Therefore, we just forge new packets and sort them as if
  // they came from the underlying trace.

  protos::pbzero::TracePacket::Decoder decoder(packet->data(),
                                               packet->length());
  auto power_rails = decoder.power_rails();
  protos::pbzero::PowerRails::Decoder evt(power_rails.data, power_rails.size);

  for (auto it = evt.rail_descriptor(); it; ++it) {
    protos::pbzero::PowerRails::RailDescriptor::Decoder desc(*it);
    uint32_t idx = desc.index();
    if (PERFETTO_UNLIKELY(idx > 256)) {
      PERFETTO_DLOG("Skipping excessively large power_rail index %" PRIu32,
                    idx);
      continue;
    }
    char counter_name[255];
    base::StringWriter writer(counter_name, base::ArraySize(counter_name));
    const char* friendly_name = MapToFriendlyPowerRailName(desc.rail_name());
    if (friendly_name) {
      writer.AppendStringView("power.rails.");
      writer.AppendStringView(friendly_name);
    } else {
      writer.AppendStringView("power.");
      writer.AppendStringView(desc.rail_name());
      writer.AppendStringView("_uws");
    }
    AndroidProbesTracker::GetOrCreate(context_)->SetPowerRailName(
        desc.index(), context_->storage->InternString(writer.GetStringView()));
  }

  // For each energy data message, turn it into its own trace packet
  // making sure its timestamp is consistent between the packet level and
  // the EnergyData level.
  for (auto it = evt.energy_data(); it; ++it) {
    protozero::ConstBytes bytes = *it;
    protos::pbzero::PowerRails_EnergyData_Decoder data(bytes.data, bytes.size);
    int64_t actual_ts =
        data.has_timestamp_ms()
            ? static_cast<int64_t>(data.timestamp_ms()) * 1000000
            : packet_timestamp;

    protozero::HeapBuffered<protos::pbzero::TracePacket> data_packet;
    data_packet->set_timestamp(static_cast<uint64_t>(actual_ts));

    auto* energy = data_packet->set_power_rails()->add_energy_data();
    energy->set_energy(data.energy());
    energy->set_index(data.index());
    energy->set_timestamp_ms(static_cast<uint64_t>(actual_ts / 1000000));

    std::vector<uint8_t> vec = data_packet.SerializeAsArray();
    TraceBlob blob = TraceBlob::CopyFrom(vec.data(), vec.size());
    context_->sorter->PushTracePacket(actual_ts, state,
                                      TraceBlobView(std::move(blob)));
  }

  return ModuleResult::Handled();
}

void AndroidProbesModule::ParsePacket(const TracePacket::Decoder& decoder,
                                      const TimestampedTracePiece& ttp,
                                      uint32_t field_id) {
  switch (field_id) {
    case TracePacket::kBatteryFieldNumber:
      parser_.ParseBatteryCounters(ttp.timestamp, decoder.battery());
      return;
    case TracePacket::kPowerRailsFieldNumber:
      parser_.ParsePowerRails(ttp.timestamp, decoder.power_rails());
      return;
    case TracePacket::kAndroidLogFieldNumber:
      parser_.ParseAndroidLogPacket(decoder.android_log());
      return;
    case TracePacket::kPackagesListFieldNumber:
      parser_.ParseAndroidPackagesList(decoder.packages_list());
      return;
    case TracePacket::kInitialDisplayStateFieldNumber:
      parser_.ParseInitialDisplayState(ttp.timestamp,
                                       decoder.initial_display_state());
      return;
  }
}

void AndroidProbesModule::ParseTraceConfig(
    const protos::pbzero::TraceConfig::Decoder& decoder) {
  if (decoder.has_statsd_metadata()) {
    parser_.ParseStatsdMetadata(decoder.statsd_metadata());
  }
}

}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>#ifndef NYAAPI_HPP
#define NYAAPI_HPP

#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <nya.hpp>
#include <nya/exception.hpp>
#include <nya/log.hpp>

#endif //NYAAPI_HPP
<commit_msg>+noncopyable<commit_after>#ifndef NYAAPI_HPP
#define NYAAPI_HPP

#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <nya.hpp>
#include <nya/exception.hpp>
#include <nya/log.hpp>
#include <boost/core/noncopyable.hpp>

#endif //NYAAPI_HPP
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 "otbCommandLineArgumentParser.h"

#include <assert.h>
#include <iostream>

#include "itkMacro.h"
#include "otbConfigure.h" // For OTB_VERSION_STRING generated by ccmake

namespace otb
{

// --------- CommandLineArgumentParseResult
// --------- ----------------------------------------
CommandLineArgumentParseResult::CommandLineArgumentParseResult() {}

CommandLineArgumentParseResult::~CommandLineArgumentParseResult() {}

void CommandLineArgumentParseResult
::PrintSelf(std::ostream& itkNotUsed(os), itk::Indent itkNotUsed(indent)) const
{

}

bool CommandLineArgumentParseResult
::IsOptionPresent(const std::string& option) const
{
  return (m_OptionMap.find(option) != m_OptionMap.end());
}

bool CommandLineArgumentParseResult
::IsOptionInputImagePresent(void) const
{
  return (this->IsOptionPresent("--InputImage"));
}
bool CommandLineArgumentParseResult
::IsOptionOutputImagePresent(void) const
{
  return (this->IsOptionPresent("--OutputImage"));
}

bool CommandLineArgumentParseResult
::IsOptionOTBTestingPresent(void) const
{
  return (this->IsOptionPresent("--OTBTesting"));
}

std::string CommandLineArgumentParseResult
::GetParameterString(const std::string& option, unsigned int number) const
{
  if (this->IsOptionPresent(option) == false)
    {
    std::ostringstream msg;
    msg << "GetParameterString(): The following '" << option << "' option is unknown !!";
    CommandLineArgumentParserArgumentErrorException e(__FILE__, __LINE__);
    e.SetDescription(msg.str().c_str());
    throw e;
    }
  OptionMapType::const_iterator it = m_OptionMap.begin();
  it = m_OptionMap.find(option);
  ParameterArrayType pat = (*it).second;
  std::string        lString = pat[number];
  return (lString);
}

std::string CommandLineArgumentParseResult
::GetInputImage(void) const
{
  return (GetParameterString("--InputImage"));
}

std::string CommandLineArgumentParseResult
::GetOutputImage(void) const
{
  return (GetParameterString("--OutputImage"));
}

int CommandLineArgumentParseResult
::GetNumberOfParameters(const std::string& option)
{
  assert(IsOptionPresent(option));
  return (m_OptionMap[option].size());
}

void CommandLineArgumentParseResult
::Clear()
{
  m_OptionMap.clear();
}

void CommandLineArgumentParseResult
::AddOption(const std::string& option)
{
  ParameterArrayType pat;
//  pat.reserve(nParms);
  m_OptionMap[option] = pat;
}

void CommandLineArgumentParseResult
::AddParameter(const std::string& option, const std::string& parameter)
{
  m_OptionMap[option].push_back(parameter);
}

// --------- CommandLineArgumentParser  ----------------------------------------

CommandLineArgumentParser
::CommandLineArgumentParser()
{
  AddOption("--help", "Help", "-h", 0, false);
  AddOption("--version", "Version", "-v", 0, false);
  AddOptionNParams("--OTBTesting", "Testing purposes only.", "-OTBTesting", false);
  m_ProgramDescription.clear();
}

CommandLineArgumentParser
::~CommandLineArgumentParser() {}

void CommandLineArgumentParser
::AddInputImage(bool obligatory)
{
  AddOption("--InputImage", "input image file name ", "-in", 1, obligatory);
}

void CommandLineArgumentParser
::AddOutputImage(bool obligatory)
{
  AddOption("--OutputImage", "output image file name ", "-out", 1, obligatory);
}

void CommandLineArgumentParser
::AddOption(const std::string& name, const std::string& comment, const std::string& synonym, int nParameters, bool obligatory)
{
  // Create a structure for the command
  OptionType option;
  option.CommonName  = name;
  option.Description = comment;
  option.Synonym     = synonym;
  option.NumberOfParameters = nParameters;
  option.NumberOfParametersFixed = true;
  option.Obligatory = obligatory;
  option.Finded = false;

  // Add the option to the map
  m_OptionList.push_back(option);

}

void CommandLineArgumentParser
::AddOptionNParams(const std::string& name, const std::string& comment, const std::string& synonym, bool obligatory)
{
  // Create a structure for the command
  OptionType option;
  option.CommonName  = name;
  option.Description = comment;
  option.Synonym     = synonym;
  option.NumberOfParameters = -1;
  option.NumberOfParametersFixed = false;
  option.Obligatory = obligatory;
  option.Finded = false;

  // Add the option to the map
  m_OptionList.push_back(option);

}

void CommandLineArgumentParser
::ParseCommandLine(int argc, char *argv[],
                   CommandLineArgumentParseResult * outResult,
                   bool failOnUnknownTrailingParameters)
{
  bool tryParse = TryParseCommandLine(argc, argv, outResult, false, failOnUnknownTrailingParameters);

  bool IsHelp = outResult->IsOptionPresent("--help");
  if (IsHelp)
    {
    PrintUsage(std::cout);
    CommandLineArgumentParserHelpException e(__FILE__, __LINE__);
    e.SetDescription("ParseCommandLine(): Help Parser");
    throw e;
    }
  bool IsVersion = outResult->IsOptionPresent("--version");
  if (IsVersion)
    {
    PrintVersion(std::cout);
    CommandLineArgumentParserHelpException e(__FILE__, __LINE__);
    e.SetDescription("ParseCommandLine(): Version Parser");
    throw e;
    }
  tryParse = TryParseCommandLine(argc, argv, outResult, true, failOnUnknownTrailingParameters);
  if (!tryParse)
    {
    PrintUsage(std::cerr);
    CommandLineArgumentParserArgumentErrorException e(__FILE__, __LINE__);
    e.SetDescription("ParseCommandLine() argument Error");
    throw e;
    }
}

bool CommandLineArgumentParser::TryParseCommandLine(int argc, char *argv[],
                                                    CommandLineArgumentParseResult * outResult,
                                                    bool reportFailedMsg,
                                                    bool failOnUnknownTrailingParameters)
{
// Clear the result
  outResult->Clear();

  int i;
  m_ProgramName = std::string(argv[0]);
  int index(0);

// Go through the arguments
  for (i = 1; i < argc; ++i)
    {
// Get the next argument
    std::string arg(argv[i]);

    // Check if the argument is known
    bool findOption = FindOption(arg, index);
    if (findOption == false)
      {
      if (failOnUnknownTrailingParameters)
        {
        // Unknown argument found
        if (reportFailedMsg == true)
          {
          std::cerr << "The following '" << arg << "' option is unknown !!" << std::endl;
          }
        return false;
        }
      else return true;
      }
    //Check the option
    m_OptionList[index].Finded = true;
    // If the number of parameters is predefined
    if (m_OptionList[index].NumberOfParametersFixed == true)
      {
      // Check if the number of parameters is correct
      int nParameters = m_OptionList[index].NumberOfParameters;
      if (i + nParameters >= argc)
        {
        // Too few parameters
        if (reportFailedMsg == true)
          {
          std::cerr << "Missing one (or more) parameter(s) for the following '" << arg << "' option." << std::endl;
          }
        return false;
        }
      // Tell the result that the option has been encountered
      outResult->AddOption(m_OptionList[index].CommonName);

      // Pass in the parameters
      for (int j = 0; j < nParameters; ++j, ++i)
        {
        outResult->AddParameter(m_OptionList[index].CommonName, std::string(argv[i + 1]));
        }
      }
// If the number of parameters is not defined, read until the next option or the end of argv
    else
      {
// Tell the result that the option has been encountered
      outResult->AddOption(m_OptionList[index].CommonName);
      bool goOnFlag(true);
      while (goOnFlag == true)
        {
        if (argv[i + 1] != nullptr)
          {
          std::string strArgv = std::string(argv[i + 1]);
          if (strArgv[0] == '-' )
            {
            // Test if the string is an argument or a real
            if(!this->IsNumber(strArgv))
              {
              goOnFlag = false;
              }
            else // If not an argument add it to the option list
              {
              outResult->AddParameter(m_OptionList[index].CommonName, strArgv);
              ++i;
              }
            }
          else
            {
            outResult->AddParameter(m_OptionList[index].CommonName, strArgv);
            ++i;
            }
          }
        else goOnFlag = false;
        //         ++i;
        }
      }

    }

// Check that all required arguments are specified
  for (unsigned int cpt = 0; cpt < m_OptionList.size(); ++cpt)
    {
    if ((m_OptionList[cpt].Obligatory == true) && (m_OptionList[cpt].Finded == false))
      {
      // Too few parameters
      if (reportFailedMsg == true)
        {
        std::cerr << "'" << m_OptionList[cpt].CommonName << "' argument is required !!!" << std::endl;
        }
      return false;
      }
    }

// Everything is correct
  return true;
}

bool CommandLineArgumentParser::IsNumber(const std::string& text)
{
  if(text.empty())
    return false;

  // Don't test the sign (-)
  unsigned int i = 1;
  while (text[i])
    {
    if( text[i] != '.' && text[i] != ',')
      {
      if(!isdigit(text[i]))
        {
        return false;
        }
      }
    ++i;
    }
  return true;
}

bool CommandLineArgumentParser::FindOption(const std::string& option, int& index)
{
  //Look through the option list
  bool         optionFoundFlag(false);
  bool         goOnFlag(true);
  unsigned int cpt(0);
  std::string  strOption(option);
  while (goOnFlag == true)
    {
    if ((m_OptionList[cpt].CommonName == strOption) || (m_OptionList[cpt].Synonym == strOption))
      {
      index = cpt;
      goOnFlag = false;
      optionFoundFlag = true;
      }
    ++cpt;
    if (cpt >= m_OptionList.size())
      {
      goOnFlag = false;
      }
    }
  return (optionFoundFlag);
}

void CommandLineArgumentParser::PrintUsage(std::ostream& os) const
{
  os << std::endl;

  if (!m_ProgramDescription.empty())
    {
    os << m_ProgramDescription << std::endl << std::endl;
    }

  os << " Usage : " << m_ProgramName << std::endl;
  // Compute the max width for option display
  int          largeurmax(-1);
  unsigned int i;

  for (i = 0; i < m_OptionList.size(); ++i)
    {
    int largeur = m_OptionList[i].CommonName.size() + m_OptionList[i].Synonym.size();
    if (largeur > largeurmax) largeurmax = largeur;
    }

  // Check that all required arguments are present on the command line
  for (i = 0; i < m_OptionList.size(); ++i)
    {
    if (m_OptionList[i].CommonName != "--OTBTesting")
      {
      int largeur = m_OptionList[i].CommonName.size() + m_OptionList[i].Synonym.size();
      os << "      ";
      if (m_OptionList[i].Obligatory == false) os << "[";
      else os << " ";
      os << m_OptionList[i].CommonName;
      if (m_OptionList[i].Synonym.empty() == false)
        {
        os << "|" << m_OptionList[i].Synonym;
        }
      if (m_OptionList[i].Obligatory == false) os << "]";
      else os << " ";
//Align the text
      for (int b = largeur; b < largeurmax; b++)
        os << " ";
      os <<   "  :  " << m_OptionList[i].Description;
      if (m_OptionList[i].NumberOfParametersFixed == true)
        {
        switch (m_OptionList[i].NumberOfParameters)
          {
          case 0:
            break;
          case 1:
            os << "  (" << m_OptionList[i].NumberOfParameters << " parameter)";
            break;
          default:
            os << "  (" << m_OptionList[i].NumberOfParameters << " parameters)";
            break;
          }
        }
      else
        {
        os << "  (N parameters)";
        }
      os << std::endl;
      }
    }
  os << std::endl;
}

void CommandLineArgumentParser::PrintVersion(std::ostream& os) const
{
  os << " OTB Version : " << OTB_VERSION_STRING << std::endl;
}

}
<commit_msg>REFAC: include-what-you-use in Modules/Core/CommandLineParser<commit_after>/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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 <string>

#include "otbCommandLineArgumentParser.h"

#include <assert.h>
#include <iostream>

#include "itkMacro.h"
#include "otbConfigure.h" // For OTB_VERSION_STRING generated by ccmake

namespace otb
{

// --------- CommandLineArgumentParseResult
// --------- ----------------------------------------
CommandLineArgumentParseResult::CommandLineArgumentParseResult() {}

CommandLineArgumentParseResult::~CommandLineArgumentParseResult() {}

void CommandLineArgumentParseResult
::PrintSelf(std::ostream& itkNotUsed(os), itk::Indent itkNotUsed(indent)) const
{

}

bool CommandLineArgumentParseResult
::IsOptionPresent(const std::string& option) const
{
  return (m_OptionMap.find(option) != m_OptionMap.end());
}

bool CommandLineArgumentParseResult
::IsOptionInputImagePresent(void) const
{
  return (this->IsOptionPresent("--InputImage"));
}
bool CommandLineArgumentParseResult
::IsOptionOutputImagePresent(void) const
{
  return (this->IsOptionPresent("--OutputImage"));
}

bool CommandLineArgumentParseResult
::IsOptionOTBTestingPresent(void) const
{
  return (this->IsOptionPresent("--OTBTesting"));
}

std::string CommandLineArgumentParseResult
::GetParameterString(const std::string& option, unsigned int number) const
{
  if (this->IsOptionPresent(option) == false)
    {
    std::ostringstream msg;
    msg << "GetParameterString(): The following '" << option << "' option is unknown !!";
    CommandLineArgumentParserArgumentErrorException e(__FILE__, __LINE__);
    e.SetDescription(msg.str().c_str());
    throw e;
    }
  OptionMapType::const_iterator it = m_OptionMap.begin();
  it = m_OptionMap.find(option);
  ParameterArrayType pat = (*it).second;
  std::string        lString = pat[number];
  return (lString);
}

std::string CommandLineArgumentParseResult
::GetInputImage(void) const
{
  return (GetParameterString("--InputImage"));
}

std::string CommandLineArgumentParseResult
::GetOutputImage(void) const
{
  return (GetParameterString("--OutputImage"));
}

int CommandLineArgumentParseResult
::GetNumberOfParameters(const std::string& option)
{
  assert(IsOptionPresent(option));
  return (m_OptionMap[option].size());
}

void CommandLineArgumentParseResult
::Clear()
{
  m_OptionMap.clear();
}

void CommandLineArgumentParseResult
::AddOption(const std::string& option)
{
  ParameterArrayType pat;
//  pat.reserve(nParms);
  m_OptionMap[option] = pat;
}

void CommandLineArgumentParseResult
::AddParameter(const std::string& option, const std::string& parameter)
{
  m_OptionMap[option].push_back(parameter);
}

// --------- CommandLineArgumentParser  ----------------------------------------

CommandLineArgumentParser
::CommandLineArgumentParser()
{
  AddOption("--help", "Help", "-h", 0, false);
  AddOption("--version", "Version", "-v", 0, false);
  AddOptionNParams("--OTBTesting", "Testing purposes only.", "-OTBTesting", false);
  m_ProgramDescription.clear();
}

CommandLineArgumentParser
::~CommandLineArgumentParser() {}

void CommandLineArgumentParser
::AddInputImage(bool obligatory)
{
  AddOption("--InputImage", "input image file name ", "-in", 1, obligatory);
}

void CommandLineArgumentParser
::AddOutputImage(bool obligatory)
{
  AddOption("--OutputImage", "output image file name ", "-out", 1, obligatory);
}

void CommandLineArgumentParser
::AddOption(const std::string& name, const std::string& comment, const std::string& synonym, int nParameters, bool obligatory)
{
  // Create a structure for the command
  OptionType option;
  option.CommonName  = name;
  option.Description = comment;
  option.Synonym     = synonym;
  option.NumberOfParameters = nParameters;
  option.NumberOfParametersFixed = true;
  option.Obligatory = obligatory;
  option.Finded = false;

  // Add the option to the map
  m_OptionList.push_back(option);

}

void CommandLineArgumentParser
::AddOptionNParams(const std::string& name, const std::string& comment, const std::string& synonym, bool obligatory)
{
  // Create a structure for the command
  OptionType option;
  option.CommonName  = name;
  option.Description = comment;
  option.Synonym     = synonym;
  option.NumberOfParameters = -1;
  option.NumberOfParametersFixed = false;
  option.Obligatory = obligatory;
  option.Finded = false;

  // Add the option to the map
  m_OptionList.push_back(option);

}

void CommandLineArgumentParser
::ParseCommandLine(int argc, char *argv[],
                   CommandLineArgumentParseResult * outResult,
                   bool failOnUnknownTrailingParameters)
{
  bool tryParse = TryParseCommandLine(argc, argv, outResult, false, failOnUnknownTrailingParameters);

  bool IsHelp = outResult->IsOptionPresent("--help");
  if (IsHelp)
    {
    PrintUsage(std::cout);
    CommandLineArgumentParserHelpException e(__FILE__, __LINE__);
    e.SetDescription("ParseCommandLine(): Help Parser");
    throw e;
    }
  bool IsVersion = outResult->IsOptionPresent("--version");
  if (IsVersion)
    {
    PrintVersion(std::cout);
    CommandLineArgumentParserHelpException e(__FILE__, __LINE__);
    e.SetDescription("ParseCommandLine(): Version Parser");
    throw e;
    }
  tryParse = TryParseCommandLine(argc, argv, outResult, true, failOnUnknownTrailingParameters);
  if (!tryParse)
    {
    PrintUsage(std::cerr);
    CommandLineArgumentParserArgumentErrorException e(__FILE__, __LINE__);
    e.SetDescription("ParseCommandLine() argument Error");
    throw e;
    }
}

bool CommandLineArgumentParser::TryParseCommandLine(int argc, char *argv[],
                                                    CommandLineArgumentParseResult * outResult,
                                                    bool reportFailedMsg,
                                                    bool failOnUnknownTrailingParameters)
{
// Clear the result
  outResult->Clear();

  int i;
  m_ProgramName = std::string(argv[0]);
  int index(0);

// Go through the arguments
  for (i = 1; i < argc; ++i)
    {
// Get the next argument
    std::string arg(argv[i]);

    // Check if the argument is known
    bool findOption = FindOption(arg, index);
    if (findOption == false)
      {
      if (failOnUnknownTrailingParameters)
        {
        // Unknown argument found
        if (reportFailedMsg == true)
          {
          std::cerr << "The following '" << arg << "' option is unknown !!" << std::endl;
          }
        return false;
        }
      else return true;
      }
    //Check the option
    m_OptionList[index].Finded = true;
    // If the number of parameters is predefined
    if (m_OptionList[index].NumberOfParametersFixed == true)
      {
      // Check if the number of parameters is correct
      int nParameters = m_OptionList[index].NumberOfParameters;
      if (i + nParameters >= argc)
        {
        // Too few parameters
        if (reportFailedMsg == true)
          {
          std::cerr << "Missing one (or more) parameter(s) for the following '" << arg << "' option." << std::endl;
          }
        return false;
        }
      // Tell the result that the option has been encountered
      outResult->AddOption(m_OptionList[index].CommonName);

      // Pass in the parameters
      for (int j = 0; j < nParameters; ++j, ++i)
        {
        outResult->AddParameter(m_OptionList[index].CommonName, std::string(argv[i + 1]));
        }
      }
// If the number of parameters is not defined, read until the next option or the end of argv
    else
      {
// Tell the result that the option has been encountered
      outResult->AddOption(m_OptionList[index].CommonName);
      bool goOnFlag(true);
      while (goOnFlag == true)
        {
        if (argv[i + 1] != nullptr)
          {
          std::string strArgv = std::string(argv[i + 1]);
          if (strArgv[0] == '-' )
            {
            // Test if the string is an argument or a real
            if(!this->IsNumber(strArgv))
              {
              goOnFlag = false;
              }
            else // If not an argument add it to the option list
              {
              outResult->AddParameter(m_OptionList[index].CommonName, strArgv);
              ++i;
              }
            }
          else
            {
            outResult->AddParameter(m_OptionList[index].CommonName, strArgv);
            ++i;
            }
          }
        else goOnFlag = false;
        //         ++i;
        }
      }

    }

// Check that all required arguments are specified
  for (unsigned int cpt = 0; cpt < m_OptionList.size(); ++cpt)
    {
    if ((m_OptionList[cpt].Obligatory == true) && (m_OptionList[cpt].Finded == false))
      {
      // Too few parameters
      if (reportFailedMsg == true)
        {
        std::cerr << "'" << m_OptionList[cpt].CommonName << "' argument is required !!!" << std::endl;
        }
      return false;
      }
    }

// Everything is correct
  return true;
}

bool CommandLineArgumentParser::IsNumber(const std::string& text)
{
  if(text.empty())
    return false;

  // Don't test the sign (-)
  unsigned int i = 1;
  while (text[i])
    {
    if( text[i] != '.' && text[i] != ',')
      {
      if(!isdigit(text[i]))
        {
        return false;
        }
      }
    ++i;
    }
  return true;
}

bool CommandLineArgumentParser::FindOption(const std::string& option, int& index)
{
  //Look through the option list
  bool         optionFoundFlag(false);
  bool         goOnFlag(true);
  unsigned int cpt(0);
  std::string  strOption(option);
  while (goOnFlag == true)
    {
    if ((m_OptionList[cpt].CommonName == strOption) || (m_OptionList[cpt].Synonym == strOption))
      {
      index = cpt;
      goOnFlag = false;
      optionFoundFlag = true;
      }
    ++cpt;
    if (cpt >= m_OptionList.size())
      {
      goOnFlag = false;
      }
    }
  return (optionFoundFlag);
}

void CommandLineArgumentParser::PrintUsage(std::ostream& os) const
{
  os << std::endl;

  if (!m_ProgramDescription.empty())
    {
    os << m_ProgramDescription << std::endl << std::endl;
    }

  os << " Usage : " << m_ProgramName << std::endl;
  // Compute the max width for option display
  int          largeurmax(-1);
  unsigned int i;

  for (i = 0; i < m_OptionList.size(); ++i)
    {
    int largeur = m_OptionList[i].CommonName.size() + m_OptionList[i].Synonym.size();
    if (largeur > largeurmax) largeurmax = largeur;
    }

  // Check that all required arguments are present on the command line
  for (i = 0; i < m_OptionList.size(); ++i)
    {
    if (m_OptionList[i].CommonName != "--OTBTesting")
      {
      int largeur = m_OptionList[i].CommonName.size() + m_OptionList[i].Synonym.size();
      os << "      ";
      if (m_OptionList[i].Obligatory == false) os << "[";
      else os << " ";
      os << m_OptionList[i].CommonName;
      if (m_OptionList[i].Synonym.empty() == false)
        {
        os << "|" << m_OptionList[i].Synonym;
        }
      if (m_OptionList[i].Obligatory == false) os << "]";
      else os << " ";
//Align the text
      for (int b = largeur; b < largeurmax; b++)
        os << " ";
      os <<   "  :  " << m_OptionList[i].Description;
      if (m_OptionList[i].NumberOfParametersFixed == true)
        {
        switch (m_OptionList[i].NumberOfParameters)
          {
          case 0:
            break;
          case 1:
            os << "  (" << m_OptionList[i].NumberOfParameters << " parameter)";
            break;
          default:
            os << "  (" << m_OptionList[i].NumberOfParameters << " parameters)";
            break;
          }
        }
      else
        {
        os << "  (N parameters)";
        }
      os << std::endl;
      }
    }
  os << std::endl;
}

void CommandLineArgumentParser::PrintVersion(std::ostream& os) const
{
  os << " OTB Version : " << OTB_VERSION_STRING << std::endl;
}

}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTimeStampTest.cxx
  Language:  C++

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include <iostream>
#include "itkTimeStamp.h"
#include "itkMultiThreader.h"

ITK_THREAD_RETURN_TYPE modified_function( void *ptr )
{
  itk::TimeStamp *tsp = static_cast<itk::TimeStamp *>(
     ( (itk::MultiThreader::ThreadInfoStruct *)(ptr) )->UserData );

  tsp->Modified();

  return ITK_THREAD_RETURN_VALUE;
}

int itkTimeStampTest(int, char*[])
{
  bool success = true;

  try
    {
    itk::TimeStamp ts;

    itk::MultiThreader::Pointer multithreader = itk::MultiThreader::New();
    multithreader->SetNumberOfThreads(ITK_MAX_THREADS+10);// this will be clamped
    multithreader->SetSingleMethod( modified_function, &ts);

    // call modified once to make it up-to-date;
    ts.Modified();

    const unsigned long init_mtime = ts.GetMTime();
    std::cout << "init_mtime: "<<init_mtime<< std::endl;

    unsigned long prev_mtime = init_mtime;

    const unsigned int num_exp = 2000;
    for (unsigned int i = 0; i < num_exp; i++)
      {
      multithreader->SingleMethodExecute();

      const unsigned long current_mtime = ts.GetMTime();

      if ( (current_mtime-prev_mtime)>static_cast<unsigned long>(multithreader->GetNumberOfThreads()) )
        {
        // This might be a normal case since the modified time of a time stamp
        // is global If a new itk object is created this will also increment
        // the time
        std::cout << "[Iteration " << i << "]" << std::endl;
        std::cout << "current_mtime   : " << current_mtime << std::endl;
        std::cout << "prev_mtime      : " << prev_mtime << std::endl;
        std::cout << "num_threads     : " << multithreader->GetNumberOfThreads() << std::endl;
        std::cout << "cur - prev mtime: " << current_mtime-prev_mtime << std::endl;
        std::cout << std::endl;
        }
      else if ( (current_mtime-prev_mtime)<static_cast<unsigned long>(multithreader->GetNumberOfThreads()) )
        {
        // This is a failure
        std::cout << "[Iteration " << i << " FAILED]" << std::endl;
        std::cout << "current_mtime   : " << current_mtime << std::endl;
        std::cout << "prev_mtime      : " << prev_mtime << std::endl;
        std::cout << "num_threads     : " << multithreader->GetNumberOfThreads() << std::endl;
        std::cout << "cur - prev mtime: " << current_mtime-prev_mtime << std::endl;
        std::cout << std::endl;
        success = false;
        }

      prev_mtime = current_mtime;
      }
    }
  catch (itk::ExceptionObject &e)
    {
    std::cout << "[TEST FAILED]" << std::endl;
    std::cerr << "Exception caught: "<< e << std::endl;
    return EXIT_FAILURE;
    }

  if (!success)
    {
    std::cout << "[TEST FAILED]" << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "[TEST PASSED]" << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>ENH: Reorganizing the test and adding information print outs to track test failures.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkTimeStampTest.cxx
  Language:  C++

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#include <iostream>
#include "itkTimeStamp.h"
#include "itkMultiThreader.h"

ITK_THREAD_RETURN_TYPE modified_function( void *ptr )
{
  itk::TimeStamp *tsp = static_cast<itk::TimeStamp *>(
     ( (itk::MultiThreader::ThreadInfoStruct *)(ptr) )->UserData );

  tsp->Modified();

  return ITK_THREAD_RETURN_VALUE;
}

int itkTimeStampTest(int, char*[])
{
  bool success = true;

  try
    {
    itk::TimeStamp ts;

    itk::MultiThreader::Pointer multithreader = itk::MultiThreader::New();
    multithreader->SetNumberOfThreads(ITK_MAX_THREADS+10);// this will be clamped

    const unsigned long numberOfThreads =
      static_cast<unsigned long>( multithreader->GetNumberOfThreads() );

    if( numberOfThreads > ITK_MAX_THREADS )
      {
      std::cerr << "numberOfThreads > ITK_MAX_THREADS" << std::endl;
      return EXIT_FAILURE;
      }

    std::cout << "Number of Threads = " << numberOfThreads << std::endl;

    multithreader->SetSingleMethod( modified_function, &ts);

    // call modified once to make it up-to-date;
    ts.Modified();

    const unsigned long init_mtime = ts.GetMTime();
    std::cout << "init_mtime: " << init_mtime << std::endl;

    unsigned long prev_mtime = init_mtime;

    const unsigned int num_exp = 2000;

    for( unsigned int i = 0; i < num_exp; i++ )
      {
      multithreader->SingleMethodExecute();

      const unsigned long current_mtime = ts.GetMTime();

      if( ( current_mtime - prev_mtime ) > numberOfThreads )
        {
        // This might be a normal case since the modified time of a time stamp
        // is global If a new itk object is created this will also increment
        // the time
        std::cout << "[Iteration " << i << "]" << std::endl;
        std::cout << "current_mtime   : " << current_mtime << std::endl;
        std::cout << "prev_mtime      : " << prev_mtime << std::endl;
        std::cout << "num_threads     : " << numberOfThreads << std::endl;
        std::cout << "cur - prev mtime: " << current_mtime - prev_mtime << std::endl;
        std::cout << std::endl;
        }
      else
        {
        if( ( current_mtime - prev_mtime ) < numberOfThreads )
          {
          // This is a failure
          std::cout << "[Iteration " << i << " FAILED]" << std::endl;
          std::cout << "current_mtime   : " << current_mtime << std::endl;
          std::cout << "prev_mtime      : " << prev_mtime << std::endl;
          std::cout << "num_threads     : " << numberOfThreads << std::endl;
          std::cout << "cur - prev mtime: " << current_mtime - prev_mtime << std::endl;
          std::cout << std::endl;
          success = false;
          }
        }

      prev_mtime = current_mtime;
      }
    }
  catch (itk::ExceptionObject &e)
    {
    std::cout << "[TEST FAILED]" << std::endl;
    std::cerr << "Exception caught: "<< e << std::endl;
    return EXIT_FAILURE;
    }

  if (!success)
    {
    std::cout << "[TEST FAILED]" << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "[TEST PASSED]" << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * REALM CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2015] Realm Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Realm Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Realm Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Realm Incorporated.
 *
 **************************************************************************/

#ifndef REALM_UTIL_INSPECT_HPP
#define REALM_UTIL_INSPECT_HPP

namespace realm {
namespace util {

template<class OS, class T>
void inspect_value(OS& os, const T& value)
{
    os << value;
}

template<class OS>
void inspect_value(OS& os, const std::string& value)
{
    // FIXME: Escape the string.
    os << "\"" << value << "\"";
}

template<class OS>
void inspect_value(OS& os, const char* value)
{
    // FIXME: Escape the string.
    os << "\"" << value << "\"";
}

template<class OS>
void inspect_all(OS&)
{
    // No-op
}

/// Convert all arguments to strings, and quote string arguments.
template<class OS, class First, class... Args>
void inspect_all(OS& os, First&& first, Args&&... args)
{
    inspect_value(os, std::forward<First>(first));
    if (sizeof...(Args) != 0) {
        os << ", ";
    }
    inspect_all(os, std::forward<Args>(args)...);
}

}
}

#endif // REALM_UTIL_INSPECT_HPP
<commit_msg>comment end of namespace<commit_after>/*************************************************************************
 *
 * REALM CONFIDENTIAL
 * __________________
 *
 *  [2011] - [2015] Realm Inc
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Realm Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Realm Incorporated
 * and its suppliers and may be covered by U.S. and Foreign Patents,
 * patents in process, and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Realm Incorporated.
 *
 **************************************************************************/

#ifndef REALM_UTIL_INSPECT_HPP
#define REALM_UTIL_INSPECT_HPP

namespace realm {
namespace util {

template<class OS, class T>
void inspect_value(OS& os, const T& value)
{
    os << value;
}

template<class OS>
void inspect_value(OS& os, const std::string& value)
{
    // FIXME: Escape the string.
    os << "\"" << value << "\"";
}

template<class OS>
void inspect_value(OS& os, const char* value)
{
    // FIXME: Escape the string.
    os << "\"" << value << "\"";
}

template<class OS>
void inspect_all(OS&)
{
    // No-op
}

/// Convert all arguments to strings, and quote string arguments.
template<class OS, class First, class... Args>
void inspect_all(OS& os, First&& first, Args&&... args)
{
    inspect_value(os, std::forward<First>(first));
    if (sizeof...(Args) != 0) {
        os << ", ";
    }
    inspect_all(os, std::forward<Args>(args)...);
}

} // namespace util
} // namespace realm

#endif // REALM_UTIL_INSPECT_HPP
<|endoftext|>


<commit_before>#include "SettingsWindow.hpp"

#include <imgui.h>
#include "../ImGui/Theme.hpp"

using namespace GUI;

SettingsWindow::SettingsWindow() {
    themes.push_back("Default");
}

void SettingsWindow::Show() {
    if (ImGui::Begin("Settings", &visible)) {
        // Show drop down list to select theme.
        if (dropDownItems != nullptr)
            delete[] dropDownItems;
        dropDownItems = new const char*[themes.size()];
        for (std::size_t i=0; i < themes.size(); ++i) {
            dropDownItems[i] = themes[i].c_str();
        }

        ImGui::Combo("Theme", &theme, dropDownItems, themes.size());

        // Clone current theme to create a new theme.
        if (ImGui::Button("Clone")) {
            ImGui::OpenPopup("Theme Name");
            themeName[0] = '\0';
        }

        if (ImGui::BeginPopupModal("Theme Name", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::InputText("Name", themeName, 128);

            if (ImGui::Button("Create")) {
                ImGui::SaveTheme(themeName);
                themes.push_back(themeName);
                ImGui::CloseCurrentPopup();
            }
            ImGui::SameLine();
            if (ImGui::Button("Cancel"))
                ImGui::CloseCurrentPopup();

            ImGui::EndPopup();
        }

        ImGui::ShowStyleEditor();
    }

    ImGui::End();
}

bool SettingsWindow::IsVisible() const {
    return visible;
}

void SettingsWindow::SetVisible(bool visible) {
    this->visible = visible;
}
<commit_msg>Don't allow user to edit default theme<commit_after>#include "SettingsWindow.hpp"

#include <imgui.h>
#include "../ImGui/Theme.hpp"

using namespace GUI;

SettingsWindow::SettingsWindow() {
    themes.push_back("Default");
}

void SettingsWindow::Show() {
    if (ImGui::Begin("Settings", &visible)) {
        // Show drop down list to select theme.
        if (dropDownItems != nullptr)
            delete[] dropDownItems;
        dropDownItems = new const char*[themes.size()];
        for (std::size_t i=0; i < themes.size(); ++i) {
            dropDownItems[i] = themes[i].c_str();
        }

        ImGui::Combo("Theme", &theme, dropDownItems, themes.size());

        // Clone current theme to create a new theme.
        if (ImGui::Button("Clone")) {
            ImGui::OpenPopup("Theme Name");
            themeName[0] = '\0';
        }

        if (ImGui::BeginPopupModal("Theme Name", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
            ImGui::InputText("Name", themeName, 128);

            if (ImGui::Button("Create")) {
                ImGui::SaveTheme(themeName);
                themes.push_back(themeName);
                ImGui::CloseCurrentPopup();
            }
            ImGui::SameLine();
            if (ImGui::Button("Cancel"))
                ImGui::CloseCurrentPopup();

            ImGui::EndPopup();
        }

        if (theme != 0)
            ImGui::ShowStyleEditor();
    }

    ImGui::End();
}

bool SettingsWindow::IsVisible() const {
    return visible;
}

void SettingsWindow::SetVisible(bool visible) {
    this->visible = visible;
}
<|endoftext|>


<commit_before>#include "runtime_internal.h"
#include "HalideRuntime.h"
#include "printer.h"

namespace Halide { namespace Runtime { namespace Internal {
struct old_dev_wrapper {
    uint64_t device;
    const halide_device_interface_t *interface;
};

int guess_type_and_dimensionality(void *user_context, buffer_t *old_buf, halide_buffer_t *new_buf) {
    new_buf->dimensions = 4;
    for (int i = 0; i < 4; i++) {
        if (old_buf->extent[i] == 0) {
            new_buf->dimensions = i;
            break;
        }
    }

    switch (old_buf->elem_size) {
    case 1: new_buf->type = halide_type_of<uint8_t>(); break;
    case 2: new_buf->type = halide_type_of<uint16_t>(); break;
    case 4: new_buf->type = halide_type_of<uint32_t>(); break;
    case 8: new_buf->type = halide_type_of<uint64_t>(); break;
    default:
        return halide_error_failed_to_upgrade_buffer_t(user_context, "",
                                                       "elem_size of buffer was not in [1, 2, 4, 8]");
    }
    return 0;
}

}}}

extern "C" {

WEAK int halide_upgrade_buffer_t(void *user_context, const char *name,
                                 const buffer_t *old_buf, halide_buffer_t *new_buf) {
    if ((old_buf->host || old_buf->dev) &&
        (old_buf->elem_size != new_buf->type.bytes())) {
        // Unless we're doing a bounds query, we expect the elem_size to match the type.
        stringstream sstr(user_context);
        sstr << "buffer has incorrect elem_size (" << old_buf->elem_size << ") "
             << "for expected type (" << new_buf->type << ")";
        return halide_error_failed_to_upgrade_buffer_t(user_context, name, sstr.str());
    }
    new_buf->host = old_buf->host;
    if (old_buf->dev) {
        old_dev_wrapper *wrapper = (old_dev_wrapper *)(old_buf->dev);
        new_buf->device = wrapper->device;
        new_buf->device_interface = wrapper->interface;
    } else {
        new_buf->device = 0;
        new_buf->device_interface = NULL;
    }
    for (int i = 0; i < new_buf->dimensions; i++) {
        new_buf->dim[i].min = old_buf->min[i];
        new_buf->dim[i].extent = old_buf->extent[i];
        new_buf->dim[i].stride = old_buf->stride[i];
    }
    new_buf->flags = 0;
    new_buf->set_host_dirty(old_buf->host_dirty);
    new_buf->set_device_dirty(old_buf->dev_dirty);
    return 0;
}

WEAK int halide_downgrade_buffer_t(void *user_context, const char *name,
                                   const halide_buffer_t *new_buf, buffer_t *old_buf) {
    memset(old_buf, 0, sizeof(buffer_t));
    if (new_buf->dimensions > 4) {
        return halide_error_failed_to_downgrade_buffer_t(user_context, name,
                                                         "buffer has more than four dimensions");
    }
    old_buf->host = new_buf->host;
    if (new_buf->device) {
        old_dev_wrapper *wrapper = (old_dev_wrapper *)malloc(sizeof(old_dev_wrapper));
        wrapper->device = new_buf->device;
        wrapper->interface = new_buf->device_interface;
        old_buf->dev = (uint64_t)wrapper;
    }
    for (int i = 0; i < new_buf->dimensions; i++) {
        old_buf->min[i] = new_buf->dim[i].min;
        old_buf->extent[i] = new_buf->dim[i].extent;
        old_buf->stride[i] = new_buf->dim[i].stride;
    }
    old_buf->elem_size = new_buf->type.bytes();
    old_buf->host_dirty = new_buf->host_dirty();
    old_buf->dev_dirty = new_buf->device_dirty();
    return 0;
}

WEAK int halide_copy_to_host_legacy(void *user_context, struct buffer_t *old_buf) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_copy_to_host(user_context, &new_buf);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_copy_to_device_legacy(void *user_context, struct buffer_t *old_buf,
                               const struct halide_device_interface_t *device_interface) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_copy_to_device(user_context, &new_buf, device_interface);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_device_sync_legacy(void *user_context, struct buffer_t *old_buf) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_device_sync(user_context, &new_buf);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_device_malloc_legacy(void *user_context, struct buffer_t *old_buf,
                              const struct halide_device_interface_t *device_interface) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_device_malloc(user_context, &new_buf, device_interface);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_device_free_legacy(void *user_context, struct buffer_t *old_buf) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_device_free(user_context, &new_buf);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

}  // extern "C"
<commit_msg>Add missing weak<commit_after>#include "runtime_internal.h"
#include "HalideRuntime.h"
#include "printer.h"

namespace Halide { namespace Runtime { namespace Internal {
struct old_dev_wrapper {
    uint64_t device;
    const halide_device_interface_t *interface;
};

WEAK int guess_type_and_dimensionality(void *user_context, buffer_t *old_buf, halide_buffer_t *new_buf) {
    new_buf->dimensions = 4;
    for (int i = 0; i < 4; i++) {
        if (old_buf->extent[i] == 0) {
            new_buf->dimensions = i;
            break;
        }
    }

    switch (old_buf->elem_size) {
    case 1: new_buf->type = halide_type_of<uint8_t>(); break;
    case 2: new_buf->type = halide_type_of<uint16_t>(); break;
    case 4: new_buf->type = halide_type_of<uint32_t>(); break;
    case 8: new_buf->type = halide_type_of<uint64_t>(); break;
    default:
        return halide_error_failed_to_upgrade_buffer_t(user_context, "",
                                                       "elem_size of buffer was not in [1, 2, 4, 8]");
    }
    return 0;
}

}}}

extern "C" {

WEAK int halide_upgrade_buffer_t(void *user_context, const char *name,
                                 const buffer_t *old_buf, halide_buffer_t *new_buf) {
    if ((old_buf->host || old_buf->dev) &&
        (old_buf->elem_size != new_buf->type.bytes())) {
        // Unless we're doing a bounds query, we expect the elem_size to match the type.
        stringstream sstr(user_context);
        sstr << "buffer has incorrect elem_size (" << old_buf->elem_size << ") "
             << "for expected type (" << new_buf->type << ")";
        return halide_error_failed_to_upgrade_buffer_t(user_context, name, sstr.str());
    }
    new_buf->host = old_buf->host;
    if (old_buf->dev) {
        old_dev_wrapper *wrapper = (old_dev_wrapper *)(old_buf->dev);
        new_buf->device = wrapper->device;
        new_buf->device_interface = wrapper->interface;
    } else {
        new_buf->device = 0;
        new_buf->device_interface = NULL;
    }
    for (int i = 0; i < new_buf->dimensions; i++) {
        new_buf->dim[i].min = old_buf->min[i];
        new_buf->dim[i].extent = old_buf->extent[i];
        new_buf->dim[i].stride = old_buf->stride[i];
    }
    new_buf->flags = 0;
    new_buf->set_host_dirty(old_buf->host_dirty);
    new_buf->set_device_dirty(old_buf->dev_dirty);
    return 0;
}

WEAK int halide_downgrade_buffer_t(void *user_context, const char *name,
                                   const halide_buffer_t *new_buf, buffer_t *old_buf) {
    memset(old_buf, 0, sizeof(buffer_t));
    if (new_buf->dimensions > 4) {
        return halide_error_failed_to_downgrade_buffer_t(user_context, name,
                                                         "buffer has more than four dimensions");
    }
    old_buf->host = new_buf->host;
    if (new_buf->device) {
        old_dev_wrapper *wrapper = (old_dev_wrapper *)malloc(sizeof(old_dev_wrapper));
        wrapper->device = new_buf->device;
        wrapper->interface = new_buf->device_interface;
        old_buf->dev = (uint64_t)wrapper;
    }
    for (int i = 0; i < new_buf->dimensions; i++) {
        old_buf->min[i] = new_buf->dim[i].min;
        old_buf->extent[i] = new_buf->dim[i].extent;
        old_buf->stride[i] = new_buf->dim[i].stride;
    }
    old_buf->elem_size = new_buf->type.bytes();
    old_buf->host_dirty = new_buf->host_dirty();
    old_buf->dev_dirty = new_buf->device_dirty();
    return 0;
}

WEAK int halide_copy_to_host_legacy(void *user_context, struct buffer_t *old_buf) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_copy_to_host(user_context, &new_buf);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_copy_to_device_legacy(void *user_context, struct buffer_t *old_buf,
                               const struct halide_device_interface_t *device_interface) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_copy_to_device(user_context, &new_buf, device_interface);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_device_sync_legacy(void *user_context, struct buffer_t *old_buf) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_device_sync(user_context, &new_buf);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_device_malloc_legacy(void *user_context, struct buffer_t *old_buf,
                              const struct halide_device_interface_t *device_interface) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_device_malloc(user_context, &new_buf, device_interface);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

WEAK int halide_device_free_legacy(void *user_context, struct buffer_t *old_buf) {
    halide_buffer_t new_buf = {0};
    halide_dimension_t shape[4];
    new_buf.dim = shape;
    int err = guess_type_and_dimensionality(user_context, old_buf, &new_buf);
    err = err || halide_upgrade_buffer_t(user_context, "", old_buf, &new_buf);
    err = err || halide_device_free(user_context, &new_buf);
    free((void *)old_buf->dev);
    err = err || halide_downgrade_buffer_t(user_context, "", &new_buf, old_buf);
    return err;
}

}  // extern "C"
<|endoftext|>


<commit_before>#include "drivers/h3lis331dl.hpp"

#include "unit_config.hpp"
#include "chprintf.h"

void H3LIS331DL::init() {
  // Configure (DS p. 24-28)
  txbuf[0] = h3lis331dl::CTRL_REG1 | (1<<6);   // Auto-increment write address
  txbuf[1] = 0b00111111;   // PM: normal mode, DR: 1000Hz, XYZ: enabled
  txbuf[2] = 0b00000000;   // Defaults
  txbuf[3] = 0b00000000;   // Defaults
  txbuf[4] = 0b11000000;   // BDU: on, BLE: data MSB at lower addr, FS: 100g
  txbuf[5] = 0b00000011;   // Turned on
  exchange(6);
}

AccelerometerReading H3LIS331DL::readAccel() {
  AccelerometerReading reading;

  // Poll status
  // TODO(yoos): Do something useful with this
  txbuf[0] = h3lis331dl::STATUS_REG | (1<<7);
  exchange(2);
  uint8_t status = rxbuf[1];

  // Poll accel
  txbuf[0] = h3lis331dl::OUT_X_L | (1<<7) | (1<<6);   // Auto-increment read address
  exchange(7);

  // X and Y flipped for canard rocket.
  reading.axes[0] = -((int16_t) ((rxbuf[1]<<8) | rxbuf[2]))/16 * 0.049 + accOffsets[0];
  reading.axes[1] = -((int16_t) ((rxbuf[3]<<8) | rxbuf[4]))/16 * 0.049 + accOffsets[1];
  reading.axes[2] = ((int16_t) ((rxbuf[5]<<8) | rxbuf[6]))/16 * 0.049 + accOffsets[2];

  // DEBUG
  //BaseSequentialStream* chp = (BaseSequentialStream*)&SD4;
  //static int i=0;
  //if ((i++)%10 == 0) {
  //  chprintf(chp, "H3: %8f %8f %8f\r\n", reading.axes[0], reading.axes[1], reading.axes[2]);
  //}

  return reading;
}

bool H3LIS331DL::healthy() {
  txbuf[0] = h3lis331dl::WHO_AM_I | (1<<7);
  txbuf[1] = 0x00;
  exchange(2);

  if (rxbuf[1] != 0x32) {
    return false;
  }

  return true;
}
<commit_msg>Revert "Flip X and Y for canard rocket."<commit_after>#include "drivers/h3lis331dl.hpp"

#include "unit_config.hpp"
#include "chprintf.h"

void H3LIS331DL::init() {
  // Configure (DS p. 24-28)
  txbuf[0] = h3lis331dl::CTRL_REG1 | (1<<6);   // Auto-increment write address
  txbuf[1] = 0b00111111;   // PM: normal mode, DR: 1000Hz, XYZ: enabled
  txbuf[2] = 0b00000000;   // Defaults
  txbuf[3] = 0b00000000;   // Defaults
  txbuf[4] = 0b11000000;   // BDU: on, BLE: data MSB at lower addr, FS: 100g
  txbuf[5] = 0b00000011;   // Turned on
  exchange(6);
}

AccelerometerReading H3LIS331DL::readAccel() {
  AccelerometerReading reading;

  // Poll status
  // TODO(yoos): Do something useful with this
  txbuf[0] = h3lis331dl::STATUS_REG | (1<<7);
  exchange(2);
  uint8_t status = rxbuf[1];

  // Poll accel
  txbuf[0] = h3lis331dl::OUT_X_L | (1<<7) | (1<<6);   // Auto-increment read address
  exchange(7);

  reading.axes[0] = ((int16_t) ((rxbuf[1]<<8) | rxbuf[2]))/16 * 0.049 + accOffsets[0];
  reading.axes[1] = ((int16_t) ((rxbuf[3]<<8) | rxbuf[4]))/16 * 0.049 + accOffsets[1];
  reading.axes[2] = ((int16_t) ((rxbuf[5]<<8) | rxbuf[6]))/16 * 0.049 + accOffsets[2];

  // DEBUG
  //BaseSequentialStream* chp = (BaseSequentialStream*)&SD4;
  //static int i=0;
  //if ((i++)%10 == 0) {
  //  chprintf(chp, "H3: %8f %8f %8f\r\n", reading.axes[0], reading.axes[1], reading.axes[2]);
  //}

  return reading;
}

bool H3LIS331DL::healthy() {
  txbuf[0] = h3lis331dl::WHO_AM_I | (1<<7);
  txbuf[1] = 0x00;
  exchange(2);

  if (rxbuf[1] != 0x32) {
    return false;
  }

  return true;
}
<|endoftext|>


<commit_before>#include "Genes/Piece_Strength_Gene.h"

#include <cmath>

#include "Utility.h"
#include "Pieces/Piece.h"

Piece_Strength_Gene::Piece_Strength_Gene() : Gene(0.0)
{
    for(auto c : std::string("PRNBQ"))
    {
        piece_strength[c] = 0.0;
    }
    renormalize();
}

void Piece_Strength_Gene::reset_properties() const
{
    for(const auto& piece_score : piece_strength)
    {
        properties[std::string(1, piece_score.first)] = piece_score.second;
    }
}

void Piece_Strength_Gene::load_properties()
{
    for(const auto& piece_score : properties)
    {
        piece_strength[piece_score.first[0]] = piece_score.second;
    }
}

void Piece_Strength_Gene::mutate()
{
    for(auto& key_value : piece_strength)
    {
        key_value.second += Random::random_normal(1.0);
    }
    renormalize();
}

double Piece_Strength_Gene::piece_value(char symbol) const
{
    if(symbol == 'K')
    {
        return 0;
    }

    return piece_strength.at(symbol)/normalizing_factor;
}

double Piece_Strength_Gene::piece_value(const std::shared_ptr<const Piece>& piece) const
{
    return piece_value(toupper(piece->fen_symbol()));
}

Piece_Strength_Gene* Piece_Strength_Gene::duplicate() const
{
    return new Piece_Strength_Gene(*this);
}

std::string Piece_Strength_Gene::name() const
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, Color) const
{
    return 0.0;
}

void Piece_Strength_Gene::renormalize()
{
    // Sum is equal to the total strength of a player's starting pieces
    // (8 pawns, 2 rooks, 2 knights, 2 bishops, 1 queen, 1 king).
    normalizing_factor = 8*piece_strength['P'] +
                         2*piece_strength['R'] +
                         2*piece_strength['N'] +
                         2*piece_strength['B'] +
                           piece_strength['Q'];

    if(normalizing_factor == 0)
    {
        normalizing_factor = 1;
    }
    else if(normalizing_factor < 0)
    {
        for(auto& piece_score : piece_strength)
        {
            piece_score.second *= -1;
        }
        normalizing_factor *= -1;
    }
}
<commit_msg>Use absolute value for normalizing Piece Strengths<commit_after>#include "Genes/Piece_Strength_Gene.h"

#include <cmath>

#include "Utility.h"
#include "Pieces/Piece.h"

Piece_Strength_Gene::Piece_Strength_Gene() : Gene(0.0)
{
    for(auto c : std::string("PRNBQ"))
    {
        piece_strength[c] = 0.0;
    }
    renormalize();
}

void Piece_Strength_Gene::reset_properties() const
{
    for(const auto& piece_score : piece_strength)
    {
        properties[std::string(1, piece_score.first)] = piece_score.second;
    }
}

void Piece_Strength_Gene::load_properties()
{
    for(const auto& piece_score : properties)
    {
        piece_strength[piece_score.first[0]] = piece_score.second;
    }
}

void Piece_Strength_Gene::mutate()
{
    for(auto& key_value : piece_strength)
    {
        key_value.second += Random::random_normal(1.0);
    }
    renormalize();
}

double Piece_Strength_Gene::piece_value(char symbol) const
{
    if(symbol == 'K')
    {
        return 0;
    }

    return piece_strength.at(symbol)/normalizing_factor;
}

double Piece_Strength_Gene::piece_value(const std::shared_ptr<const Piece>& piece) const
{
    return piece_value(toupper(piece->fen_symbol()));
}

Piece_Strength_Gene* Piece_Strength_Gene::duplicate() const
{
    return new Piece_Strength_Gene(*this);
}

std::string Piece_Strength_Gene::name() const
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, Color) const
{
    return 0.0;
}

void Piece_Strength_Gene::renormalize()
{
    // Sum is equal to the total strength of a player's starting pieces
    // (8 pawns, 2 rooks, 2 knights, 2 bishops, 1 queen).
    //
    // Use absolute value so there aren't discontinuous jumps in the
    // returned piece values when they suddenly switch sign.
    normalizing_factor = std::abs(8*piece_strength['P'] +
                                  2*piece_strength['R'] +
                                  2*piece_strength['N'] +
                                  2*piece_strength['B'] +
                                    piece_strength['Q']);

    if(normalizing_factor == 0)
    {
        normalizing_factor = 1;
    }
}
<|endoftext|>