<commit_before>#include "player.h"
#include "subjectblock.h"
#include "types.h"
#include <iostream>
#include <algorithm>
#include <QDebug>
#include "board.h"
#include <QtGlobal>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>
#include "localgame.h"
#include "sellpopup.h"
#include <QMediaPlayer>
#include <QFileInfo>
#include <QDir>
#define NUMBER_OF_BLOCKS 32
#define NEXT_POS(current_pos) ((current_pos + 1) % 32)

using namespace std;

Player::Player(QGameItem* parent,int _id) : QGameItem(parent)
{
    //randomly determine CharacterType
    switch(rand() % 5){
        case 0:
            character_type = CharacterType::LOL;
            break;
        case 1:
            character_type = CharacterType::GENIUS;
            break;
        case 2:
            character_type = CharacterType::HARD_WORKER;
            break;
        case 3:
            character_type = CharacterType::OUTSIDER;
            break;
        case 4:
            character_type = CharacterType::ALCOHOLIC;
    }

    id = _id;
    name = "";
    position = 0;

    energy = 1000;
    if(character_type == CharacterType::GENIUS)
        energy += 200;

    bankrupt = false;
    mobile = true;
    immobile_penalty = 0;
    plural = false;

    //initialize map
    using namespace SubjectType;
    registered[BIO] = 0;
    registered[CHEM] = 0;
    registered[CSED] = 0;
    registered[EE] = 0;
    registered[MATH] = 0;
    registered[ME] = 0;
    registered[IME] = 0;
    registered[PHYS] = 0;

    switch(_id){
    case 1:
        color = QString("red");
        break;
    case 2:
        color = QString("blue");
        break;
    case 3:
        color = QString("green");
        break;
    case 4:
        color = QString("yellow");
        break;
    }

    using namespace BlockCoords;

    for(int i =0; i < 32; i ++){
        player_coord[i] = block_coord[i];
    }

    for(int i=1; i< 24; i ++){
        player_coord[i] += QPointF(0,-40);
    }

    for(int i=17; i<24; i++){
        player_coord[i] += QPointF(40,0);
    }

    player_coord[8] = block_coord[8];

    setPos(player_coord[0]);

    // step sound load
    mediaplayer = new QMediaPlayer();
    mediaplayer->setMedia(QUrl::fromLocalFile(QFileInfo("sound/piece_move.wav").absoluteFilePath()));
    mediaplayer->setVolume(100);

    // end initialize
    qDebug() << "Player Created" << endl;
}

Player::~Player()
{

    qDebug() << "Player Destroyed" << endl;
}

void Player::setColor(QString color_str){
    color = color_str;
}

QString Player::getColor(){
    return color;
}

// Accessor Methods
int Player::getPosition() const
{
    return position;
}

QPointF Player::adjustCoord(QPointF &coord){
    return coord;
}

bool Player::isBankrupt() const
{
    return bankrupt;
}

bool Player::isMobile() const
{
    return mobile;
}

int Player::getEnergy() const
{
    return energy;
}

int Player::getPenalty() const
{
    return immobile_penalty;
}

bool Player::isPlural() const
{
    return plural;
}

CharacterType::Type Player::getType() const
{
    return character_type;
}

list<Block*> Player::getBlocks() const
{
    return own_blocks;
}

// Methods
void Player::setEnergy(int energy)
{
    this->energy = energy;
    emit energyChanged(this->energy);
}

void Player::setPlural(bool plural)
{
    this->plural = plural;
}

void Player::setBankrupt()
{
    setEnergy(0);
    bankrupt = true;

    for(list<Block*>::iterator itor = own_blocks.begin(); itor != own_blocks.end(); itor++)
       removeBlock(dynamic_cast<SubjectBlock*>(*itor));
}

// set player to stay mouindo
// parm: how long to stay in mouindo
void Player::setMouindo(int penalty)
{
    this->immobile_penalty = penalty;
    mobile = false;
}

void Player::setMobile(bool mobile){
    this->mobile = mobile;
    immobile_penalty = 0;
}

void Player::escapeAttempt(){
    immobile_penalty--;
    if(immobile_penalty==0)
        mobile = true;
}

//probably unused forever...
bool Player::escapeMouindo()
{
    if(mobile)
        return true;

    else {

        if(immobile_penalty == 0) {
            mobile = true;
            return true;
        }

        else {
            // roll a dice
            immobile_penalty--;
            return false;
        }
    }
}

void Player::walkBy(int steps)
{
    using namespace BlockCoords;
    LocalGame::getInst()->setGameState(LocalGameState::PLAYER_MOVING);
    const int step_interval = 300; //0.1 seconds
    int current_pos = position;
    int next_pos;

    QSequentialAnimationGroup * seq_animation_group
            = new QSequentialAnimationGroup;

    //add sleep animation
    QPropertyAnimation * sleep
            = new QPropertyAnimation(this,"pos");
    sleep->setDuration(1800);
    //don't move
    sleep->setStartValue(player_coord[current_pos]);
    sleep->setEndValue(player_coord[current_pos]);
    seq_animation_group->addAnimation(sleep);

    while(steps){
        next_pos = NEXT_POS(current_pos);
        QPropertyAnimation * step_animation
                = new QPropertyAnimation(this,"pos");
        step_animation->setDuration(step_interval);
        step_animation->setStartValue(player_coord[current_pos]);
        step_animation->setEndValue(player_coord[next_pos]);
        step_animation->setEasingCurve(QEasingCurve::InOutQuint);
        connect(step_animation,SIGNAL(finished()),this,SLOT(stepForward()));
        seq_animation_group->addAnimation(step_animation);
        steps--; //decrease one step
        current_pos = next_pos;

    }
    seq_animation_group->start(QAbstractAnimation::DeleteWhenStopped);

    connect(seq_animation_group,SIGNAL(finished()),this,SLOT(arrived()));
    //position = current_pos;
}

void Player::jumpTo(int block_num){
    using namespace BlockCoords;
    LocalGame::getInst()->setGameState(LocalGameState::PLAYER_MOVING);
    QPointF target = player_coord[block_num];
    QPropertyAnimation * step_animation
            = new QPropertyAnimation(this,"pos");
    step_animation->setDuration(2000);
    step_animation->setStartValue(player_coord[getPosition()]);
    step_animation->setEndValue(target);
    step_animation->setEasingCurve(QEasingCurve::InOutQuint);
    step_animation->start(QAbstractAnimation::DeleteWhenStopped);

    connect(step_animation,SIGNAL(finished()),this,SLOT(arrived()));
    position = block_num;
}

void Player::stepForward(){
    position = NEXT_POS(position);
    mediaplayer->play();
    if(position == 0){
        giveSalary();
    }
}

void Player::arrived(){
    qDebug() << "arrived at:"<<position;
    emit playerArrived(this);
}

bool Player::hasBlock(Block* block)
{
    // subject block check
    if(block->getType() != BlockType::SUBJECT) {
        qDebug() << "This is not a Subject Block!";
        return false;
    }

    list<Block*>::iterator finder = own_blocks.end();
    finder = find(own_blocks.begin(), own_blocks.end(), block);

    // no matching
    if(finder == own_blocks.end())
        return false;
    else
        return true;
}

void Player::addBlock(Block *block)
{
    SubjectBlock * subj_block = dynamic_cast<SubjectBlock*>(block);
    subj_block->setOwner(this);
    registered.find(((SubjectBlock*)block)->getDept())->second++;
    own_blocks.push_back(block);
}

void Player::removeBlock(Block *block)
{
    if(!hasBlock(block)) {
        qDebug() << "You don't have that block. Check Again!";
        return;
    }
    SubjectBlock * sblock = dynamic_cast<SubjectBlock*>(block);
    sblock->setGrade(SubjectBlock::NONE);
    sblock->setOwner(NULL);
    registered.find(((SubjectBlock*)block)->getDept())->second--;
    own_blocks.remove(block);
}

void Player::giveSalary()
{
    qDebug() << "Player " << id << " received salary";
    //maybe add animation for gaining energy

    QMediaPlayer* mediaplayer = new QMediaPlayer();
    mediaplayer->setMedia(QUrl::fromLocalFile(QFileInfo("sound/coinsprinkle.mp3").absoluteFilePath()));
    mediaplayer->setVolume(100);
    mediaplayer->play();

    if(character_type == CharacterType::HARD_WORKER)
        energy += 150;
    else
        energy += 100;

    emit energyChanged(this->energy);
}

bool Player::checkWinStatus()
{
    int majored = 0;

    for(map<SubjectType::Type, int>::iterator i = registered.begin(); i != registered.end(); i++) {
        if(i->second == 3)
            majored ++;
    }

    if(plural && majored >= 2)
        return true;
    else if (!plural && majored >= 1)
        return true;
    else
        return false;
}

void Player::payEnergy(int payenergy)
{
    if(energy >= payenergy)
    {
        QMediaPlayer* coinsound = new QMediaPlayer();
        coinsound->setMedia(QUrl::fromLocalFile(QFileInfo("sound/coinspread.mp3").absoluteFilePath()));
        coinsound->setVolume(100);
        coinsound->play();
        energy-=payenergy;
    }
    else{
        if(getAssetValue() >= payenergy){
            Sellpopup * popup = new Sellpopup(QGameItem::getWindow(), this, payenergy);
            popup->show();
        }
        else
            setBankrupt();
    }
    emit energyChanged(this->energy);
}
void Player::giveEnergy(int paidenergy){
    energy+=paidenergy;
    QMediaPlayer* coinsound = new QMediaPlayer();
    coinsound->setMedia(QUrl::fromLocalFile(QFileInfo("sound/coinspread.mp3").absoluteFilePath()));
    coinsound->setVolume(100);
    coinsound->play();
    emit energyChanged(this->energy);
}

int Player::getId() const {
    return id;
}

void Player::setType(CharacterType::Type type) {
    character_type = type;
}

int Player::getAssetValue() {

    int asset = 0;

    if(own_blocks.empty()) {
        qDebug() << "Player has nothing!";
        asset = 0;
    }
    else {
        for(list<Block*>::iterator itor = own_blocks.begin(); itor != own_blocks.end(); itor++) {
           asset += dynamic_cast<SubjectBlock*>(*itor)->getSellCost();
        }
    }
    return asset;
}

void Player::animatePlayerImage(int frame){
    QString filename = QString(":/images/ingame/character/");

    int zone = position /8 ;

    if(zone == 0){
        filename += QString("top_up_");
    }
    else if(zone ==1){
        filename += QString("top_right_");
    }
    else if(zone ==2){
        filename += QString("top_down_");
    }
    else {
        filename += QString("top_right_");
    }

    if(id == 1 || id ==3)
        filename += QString("io_");
    else if(id == 2 || id ==4)
        filename += QString("id_");

    filename += color + QString("_");

    LocalGame * game_inst = LocalGame::getInst();

    if(game_inst->getGameState() == LocalGameState::PLAYER_MOVING
            && game_inst->getCurrentPlayer() == this)
        filename += QString("walk_");
    else
        filename += QString("stand_");

    filename += QString::number(frame).rightJustified(3,'0') + QString(".png");

    //qDebug() << filename;

    QImage image(filename);

    QTransform rotate;
    rotate.rotate(180);

    if(zone == 3)
        image = image.mirrored(true,false);

    setPixmap(QPixmap::fromImage(image));
}
<commit_msg>Player: energy set to 500 / checkwinstatus update<commit_after>#include "player.h"
#include "subjectblock.h"
#include "types.h"
#include <iostream>
#include <algorithm>
#include <QDebug>
#include "board.h"
#include <QtGlobal>
#include <QPropertyAnimation>
#include <QSequentialAnimationGroup>
#include "localgame.h"
#include "sellpopup.h"
#include <QMediaPlayer>
#include <QFileInfo>
#include <QDir>
#define NUMBER_OF_BLOCKS 32
#define NEXT_POS(current_pos) ((current_pos + 1) % 32)

using namespace std;

Player::Player(QGameItem* parent,int _id) : QGameItem(parent)
{
    //randomly determine CharacterType
    switch(rand() % 5){
        case 0:
            character_type = CharacterType::LOL;
            break;
        case 1:
            character_type = CharacterType::GENIUS;
            break;
        case 2:
            character_type = CharacterType::HARD_WORKER;
            break;
        case 3:
            character_type = CharacterType::OUTSIDER;
            break;
        case 4:
            character_type = CharacterType::ALCOHOLIC;
    }

    id = _id;
    name = "";
    position = 0;

    energy = 500;
    if(character_type == CharacterType::GENIUS)
        energy += 200;

    bankrupt = false;
    mobile = true;
    immobile_penalty = 0;
    plural = false;

    //initialize map
    using namespace SubjectType;
    registered[BIO] = 0;
    registered[CHEM] = 0;
    registered[CSED] = 0;
    registered[EE] = 0;
    registered[MATH] = 0;
    registered[ME] = 0;
    registered[IME] = 0;
    registered[PHYS] = 0;

    switch(_id){
    case 1:
        color = QString("red");
        break;
    case 2:
        color = QString("blue");
        break;
    case 3:
        color = QString("green");
        break;
    case 4:
        color = QString("yellow");
        break;
    }

    using namespace BlockCoords;

    for(int i =0; i < 32; i ++){
        player_coord[i] = block_coord[i];
    }

    for(int i=1; i< 24; i ++){
        player_coord[i] += QPointF(0,-40);
    }

    for(int i=17; i<24; i++){
        player_coord[i] += QPointF(40,0);
    }

    player_coord[8] = block_coord[8];

    setPos(player_coord[0]);

    // step sound load
    mediaplayer = new QMediaPlayer();
    mediaplayer->setMedia(QUrl::fromLocalFile(QFileInfo("sound/piece_move.wav").absoluteFilePath()));
    mediaplayer->setVolume(100);

    // end initialize
    qDebug() << "Player Created" << endl;
}

Player::~Player()
{

    qDebug() << "Player Destroyed" << endl;
}

void Player::setColor(QString color_str){
    color = color_str;
}

QString Player::getColor(){
    return color;
}

// Accessor Methods
int Player::getPosition() const
{
    return position;
}

QPointF Player::adjustCoord(QPointF &coord){
    return coord;
}

bool Player::isBankrupt() const
{
    return bankrupt;
}

bool Player::isMobile() const
{
    return mobile;
}

int Player::getEnergy() const
{
    return energy;
}

int Player::getPenalty() const
{
    return immobile_penalty;
}

bool Player::isPlural() const
{
    return plural;
}

CharacterType::Type Player::getType() const
{
    return character_type;
}

list<Block*> Player::getBlocks() const
{
    return own_blocks;
}

// Methods
void Player::setEnergy(int energy)
{
    this->energy = energy;
    emit energyChanged(this->energy);
}

void Player::setPlural(bool plural)
{
    this->plural = plural;
}

void Player::setBankrupt()
{
    setEnergy(0);
    bankrupt = true;

    for(list<Block*>::iterator itor = own_blocks.begin(); itor != own_blocks.end(); itor++)
       removeBlock(dynamic_cast<SubjectBlock*>(*itor));
}

// set player to stay mouindo
// parm: how long to stay in mouindo
void Player::setMouindo(int penalty)
{
    this->immobile_penalty = penalty;
    mobile = false;
}

void Player::setMobile(bool mobile){
    this->mobile = mobile;
    immobile_penalty = 0;
}

void Player::escapeAttempt(){
    immobile_penalty--;
    if(immobile_penalty==0)
        mobile = true;
}

//probably unused forever...
bool Player::escapeMouindo()
{
    if(mobile)
        return true;

    else {

        if(immobile_penalty == 0) {
            mobile = true;
            return true;
        }

        else {
            // roll a dice
            immobile_penalty--;
            return false;
        }
    }
}

void Player::walkBy(int steps)
{
    using namespace BlockCoords;
    LocalGame::getInst()->setGameState(LocalGameState::PLAYER_MOVING);
    const int step_interval = 300; //0.1 seconds
    int current_pos = position;
    int next_pos;

    QSequentialAnimationGroup * seq_animation_group
            = new QSequentialAnimationGroup;

    //add sleep animation
    QPropertyAnimation * sleep
            = new QPropertyAnimation(this,"pos");
    sleep->setDuration(1800);
    //don't move
    sleep->setStartValue(player_coord[current_pos]);
    sleep->setEndValue(player_coord[current_pos]);
    seq_animation_group->addAnimation(sleep);

    while(steps){
        next_pos = NEXT_POS(current_pos);
        QPropertyAnimation * step_animation
                = new QPropertyAnimation(this,"pos");
        step_animation->setDuration(step_interval);
        step_animation->setStartValue(player_coord[current_pos]);
        step_animation->setEndValue(player_coord[next_pos]);
        step_animation->setEasingCurve(QEasingCurve::InOutQuint);
        connect(step_animation,SIGNAL(finished()),this,SLOT(stepForward()));
        seq_animation_group->addAnimation(step_animation);
        steps--; //decrease one step
        current_pos = next_pos;

    }
    seq_animation_group->start(QAbstractAnimation::DeleteWhenStopped);

    connect(seq_animation_group,SIGNAL(finished()),this,SLOT(arrived()));
    //position = current_pos;
}

void Player::jumpTo(int block_num){
    using namespace BlockCoords;
    LocalGame::getInst()->setGameState(LocalGameState::PLAYER_MOVING);
    QPointF target = player_coord[block_num];
    QPropertyAnimation * step_animation
            = new QPropertyAnimation(this,"pos");
    step_animation->setDuration(2000);
    step_animation->setStartValue(player_coord[getPosition()]);
    step_animation->setEndValue(target);
    step_animation->setEasingCurve(QEasingCurve::InOutQuint);
    step_animation->start(QAbstractAnimation::DeleteWhenStopped);

    connect(step_animation,SIGNAL(finished()),this,SLOT(arrived()));
    position = block_num;
}

void Player::stepForward(){
    position = NEXT_POS(position);
    mediaplayer->play();
    if(position == 0){
        giveSalary();
    }
}

void Player::arrived(){
    qDebug() << "arrived at:"<<position;
    emit playerArrived(this);
}

bool Player::hasBlock(Block* block)
{
    // subject block check
    if(block->getType() != BlockType::SUBJECT) {
        qDebug() << "This is not a Subject Block!";
        return false;
    }

    list<Block*>::iterator finder = own_blocks.end();
    finder = find(own_blocks.begin(), own_blocks.end(), block);

    // no matching
    if(finder == own_blocks.end())
        return false;
    else
        return true;
}

void Player::addBlock(Block *block)
{
    SubjectBlock * subj_block = dynamic_cast<SubjectBlock*>(block);
    subj_block->setOwner(this);
    registered.find(((SubjectBlock*)block)->getDept())->second++;
    own_blocks.push_back(block);
}

void Player::removeBlock(Block *block)
{
    if(!hasBlock(block)) {
        qDebug() << "You don't have that block. Check Again!";
        return;
    }
    SubjectBlock * sblock = dynamic_cast<SubjectBlock*>(block);
    sblock->setGrade(SubjectBlock::NONE);
    sblock->setOwner(NULL);
    registered.find(((SubjectBlock*)block)->getDept())->second--;
    own_blocks.remove(block);
}

void Player::giveSalary()
{
    qDebug() << "Player " << id << " received salary";
    //maybe add animation for gaining energy

    QMediaPlayer* mediaplayer = new QMediaPlayer();
    mediaplayer->setMedia(QUrl::fromLocalFile(QFileInfo("sound/coinsprinkle.mp3").absoluteFilePath()));
    mediaplayer->setVolume(100);
    mediaplayer->play();

    if(character_type == CharacterType::HARD_WORKER)
        energy += 150;
    else
        energy += 100;

    emit energyChanged(this->energy);
}

bool Player::checkWinStatus()
{
    int majored = 0;
    int majored_b = 0;

    map<SubjectType::Type, int> B_grades;
    using namespace SubjectType;
    B_grades[BIO] = 0;
    B_grades[CHEM] = 0;
    B_grades[CSED] = 0;
    B_grades[EE] = 0;
    B_grades[MATH] = 0;
    B_grades[ME] = 0;
    B_grades[IME] = 0;
    B_grades[PHYS] = 0;

    Block* block;
    foreach(block,own_blocks){
        SubjectBlock* sblock = dynamic_cast<SubjectBlock*>(block);
        if(sblock->getGrade() == SubjectBlock::B ||
                sblock->getGrade() == SubjectBlock::A)
            B_grades[sblock->getDept()]++;
    }

    for(map<SubjectType::Type, int>::iterator i =registered.begin(); i != registered.end(); i++) {
        if(i->second == 3)
            majored ++;
    }

    for(map<SubjectType::Type, int>::iterator i = B_grades.begin(); i != B_grades.end(); i++) {
        if(i->second == 3)
            majored_b ++;
    }

    if(plural && majored ==2)
        return true;
    else if(!plural && majored_b == 1)
        return true;
    else
        false;

}

void Player::payEnergy(int payenergy)
{
    if(energy >= payenergy)
    {
        QMediaPlayer* coinsound = new QMediaPlayer();
        coinsound->setMedia(QUrl::fromLocalFile(QFileInfo("sound/coinspread.mp3").absoluteFilePath()));
        coinsound->setVolume(100);
        coinsound->play();
        energy-=payenergy;
    }
    else{
        if(getAssetValue() >= payenergy){
            Sellpopup * popup = new Sellpopup(QGameItem::getWindow(), this, payenergy);
            popup->show();
        }
        else
            setBankrupt();
    }
    emit energyChanged(this->energy);
}
void Player::giveEnergy(int paidenergy){
    energy+=paidenergy;
    QMediaPlayer* coinsound = new QMediaPlayer();
    coinsound->setMedia(QUrl::fromLocalFile(QFileInfo("sound/coinspread.mp3").absoluteFilePath()));
    coinsound->setVolume(100);
    coinsound->play();
    emit energyChanged(this->energy);
}

int Player::getId() const {
    return id;
}

void Player::setType(CharacterType::Type type) {
    character_type = type;
}

int Player::getAssetValue() {

    int asset = 0;

    if(own_blocks.empty()) {
        qDebug() << "Player has nothing!";
        asset = 0;
    }
    else {
        for(list<Block*>::iterator itor = own_blocks.begin(); itor != own_blocks.end(); itor++) {
           asset += dynamic_cast<SubjectBlock*>(*itor)->getSellCost();
        }
    }
    return asset;
}

void Player::animatePlayerImage(int frame){
    QString filename = QString(":/images/ingame/character/");

    int zone = position /8 ;

    if(zone == 0){
        filename += QString("top_up_");
    }
    else if(zone ==1){
        filename += QString("top_right_");
    }
    else if(zone ==2){
        filename += QString("top_down_");
    }
    else {
        filename += QString("top_right_");
    }

    if(id == 1 || id ==3)
        filename += QString("io_");
    else if(id == 2 || id ==4)
        filename += QString("id_");

    filename += color + QString("_");

    LocalGame * game_inst = LocalGame::getInst();

    if(game_inst->getGameState() == LocalGameState::PLAYER_MOVING
            && game_inst->getCurrentPlayer() == this)
        filename += QString("walk_");
    else
        filename += QString("stand_");

    filename += QString::number(frame).rightJustified(3,'0') + QString(".png");

    //qDebug() << filename;

    QImage image(filename);

    QTransform rotate;
    rotate.rotate(180);

    if(zone == 3)
        image = image.mirrored(true,false);

    setPixmap(QPixmap::fromImage(image));
}
<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <streambuf>

#include <3pp/mpc/mpc.h>

std::string readFile(char *fname)
{
    std::ifstream is(fname, std::ifstream::in);
    std::string str(
        (std::istreambuf_iterator<char>(is)),
        std::istreambuf_iterator<char>()
    );
    return str + '\n';
}

int main(int argc, char **argv)
{
    if (argc <= 1) {
        std::cout << "Usage: " << argv[0] << "file\n";
        return 1;
    }
    mpc_parser_t* Comment   = mpc_new("comment");
    mpc_parser_t* Indent   = mpc_new("indent");
    mpc_parser_t* Newline   = mpc_new("newline");
    mpc_parser_t* WhiteSpace = mpc_new("ws");
    mpc_parser_t* OptionalWhiteSpace = mpc_new("ows");
    mpc_parser_t* OptionalWhiteSpaceNewline = mpc_new("owsn");
    mpc_parser_t* Number   = mpc_new("number");
    mpc_parser_t* Operator = mpc_new("operator");
    mpc_parser_t* FactorOperator = mpc_new("factorop");
    mpc_parser_t* TermOperator = mpc_new("termop");
    mpc_parser_t* Expr     = mpc_new("expr");
    mpc_parser_t* Body     = mpc_new("body");
    mpc_parser_t* Identifier = mpc_new("identifier");
    mpc_parser_t* TypeIdent = mpc_new("typeident");
    mpc_parser_t* Import = mpc_new("import");
    mpc_parser_t* MethodRet = mpc_new("methodret");
    mpc_parser_t* MethodDef = mpc_new("methoddef");
    mpc_parser_t* ParamDef = mpc_new("paramdef");
    mpc_parser_t* String = mpc_new("string");
    mpc_parser_t* Args = mpc_new("args");
    mpc_parser_t* Lexp = mpc_new("lexp");
    mpc_parser_t* Factor = mpc_new("factor");
    mpc_parser_t* MethodCall = mpc_new("methodcall");
    mpc_parser_t* MapIndex = mpc_new("mapindex");
    mpc_parser_t* ListItem = mpc_new("listitem");
    mpc_parser_t* MapItem = mpc_new("mapitem");
    mpc_parser_t* TupleMap = mpc_new("tuplemap");
    mpc_parser_t* MapItems = mpc_new("mapitems");
    mpc_parser_t* ListItems = mpc_new("listitems");
    mpc_parser_t* List = mpc_new("list");
    mpc_parser_t* Namespacedef = mpc_new("namespacedef");
    mpc_parser_t* Primitive = mpc_new("primitive");
    mpc_parser_t* Range = mpc_new("range");
    mpc_parser_t* MatchCase = mpc_new("matchcase");
    mpc_parser_t* Match = mpc_new("match");
    mpc_parser_t* Assignment = mpc_new("assignment");
    mpc_parser_t* Stmt = mpc_new("stmt");
    mpc_parser_t* Term = mpc_new("term");
    mpc_parser_t* Const = mpc_new("const");
    mpc_parser_t* Return = mpc_new("return");
    mpc_parser_t* Pure = mpc_new("pure");
    mpc_parser_t* TopLevel = mpc_new("toplevel");
    mpc_parser_t* NolangPure = mpc_new("nolangpure");

    mpc_err_t* err = mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE,
        "comment    : /(#|\\/\\/)[^\\r\\n]*/"
        "           | /\\/\\*[^\\*]*(\\*[^\\/][^\\*]*)*\\*\\// ;"
        "indent     : /\\s\\s+/ ;"
        "newline    : '\\n';"
        "ws         : /[\\s]+/ ;"
        "ows        : /[\\s\\t]*/ ;"
        "owsn       : /[\\s\\t\\n]*/ ;"
        "identifier : /[A-Za-z_][A-Za-z0-9_-]*/ ;"
        "typeident  : <identifier> <ows> ':' <ows> <identifier> ;"
        "number     : /[0-9]+/ ;"
        "string     : /\"(\\\\.|[^\"])*\"/ "
        "           | /\'(\\\\.|[^\'])*\'/ ; "
        "operator   : '+' | '-' | '*' | '/' ;"
        "factorop   : '*'"
        "           | '/'"
        "           | \"div\""
        "           | \"mod\""
        "           | \"rem\";"
        "termop     : '+'"
        "           | '-';"
        "import     : \"import\" <ws> <identifier> <newline>;"
        "const      : \"const\" <ws> <assignment> <newline>;"
        "methodret  : <ows> ':' <ows> <identifier> ;"
        "methoddef  : (<pure> <ws>)? <identifier> <ows> <args>? <methodret>? <ows> \"=>\" (<newline>|<ws>) <body> ;"
        "paramdef   : <typeident>? <ows> (',' <ows> <typeident>)*; "
        "args       : '(' <paramdef>? ')'; "
        "factor     : <namespacedef>"
        "           | '(' <lexp> ')'"
        "           | <number>"
        "           | <string>"
        "           | <identifier>; "
        "term       : <factor> (<ows> <factorop> <ows> <factor>)*;"
        "lexp       : <term> (<ows> <termop> <ows> <term>)* ; "
        "expr       : <list>"
        "           | <lexp>;"
        "methodcall : '(' (<expr> (',' <ows> <expr>)*)? ')';"
        "mapindex   : '[' <expr> ']';"
        "listitem   : <expr>;"
        "mapitem    : <string> <ows> ':' <owsn> <expr> ;"
        "tuplemap   : '(' <string> <owsn> ',' <owsn> <lexp> ')';"
        "mapitems   : (<tuplemap> | <mapitem>) <owsn> (',' <owsn> (<tuplemap> | <mapitem>)) *;"
        "listitems  : <listitem> (<owsn> ',' <owsn> <listitem>) *;"
        "list       : '[' <owsn> (<mapitems> | <listitems>)? <owsn> ']' ;"
        "namespacedef : <identifier> ('.' <identifier>)* (<methodcall> | <mapindex>)?;"
        "primitive  : <identifier> | <number> | <string> ;"
        "range      : <primitive> \"..\" <primitive>?;"
        "assignment : (<typeident>|<namespacedef>) <ws> '=' <ws> <expr>;"
        "matchcase  : <comment> | (<indent> (<range> | <primitive> | '?') <ows> ':' <ows> <stmt> <newline>);"
        "match      : \"match\" <ws> <stmt> <ows> \"=>\" <newline> <matchcase>+;"
        "stmt       : <match>"
        "           | <assignment>"
        "           | <namespacedef>"
        "           | <list>"
        "           | <expr>"
        "           | <return>"
        "           | <comment>;"
        "body       : ((<indent>+ <stmt>)? <newline>)* ;"
        "pure       : \"pure\" ;"
        "return     : \"return \" <stmt>;"
        "toplevel   : <import>"
        "           | <const>"
        "           | <comment>"
        "           | <methoddef>"
        "           | <newline>;"
        "nolangpure : /^/ <toplevel>* /$/;"
      ,
        Comment, Indent, Newline,
        WhiteSpace, OptionalWhiteSpace, OptionalWhiteSpaceNewline,
        Identifier, TypeIdent,
        Number, String,
        Operator, FactorOperator, TermOperator,
        Import, Const,
        MethodRet, MethodDef, ParamDef, Args,
        Factor, Term, Lexp,
        Expr, MethodCall,
        MapIndex, ListItem, MapItem, TupleMap, MapItems, ListItems, List,
        Namespacedef,
        Primitive, Range,
        Assignment, MatchCase, Match,
        Stmt,
        Body, Pure, Return,
        TopLevel, NolangPure, NULL);

    if (err != NULL) {
        mpc_err_print(err);
        mpc_err_delete(err);
        exit(1);
    }

    mpc_result_t r;
    std::string data = readFile(argv[1]);
    int res = 0;
    if (mpc_parse(argv[1], data.c_str(), NolangPure, &r)) {
      mpc_ast_print(static_cast<mpc_ast_t*>(r.output));
      mpc_ast_delete(static_cast<mpc_ast_t*>(r.output));
    } else {
        mpc_err_print(r.error);
        mpc_err_delete(r.error);
        res = 1;
    }

    mpc_cleanup(39,
        Comment, Indent, Newline,
        WhiteSpace, OptionalWhiteSpace, OptionalWhiteSpaceNewline,
        Identifier, TypeIdent,
        Number, String,
        Operator, FactorOperator, TermOperator,
        Import, Const,
        MethodRet, MethodDef, ParamDef, Args,
        Factor, Term, Lexp,
        Expr, MethodCall,
        MapIndex, ListItem, MapItem, TupleMap, MapItems, ListItems, List,
        Namespacedef,
        Primitive, Range,
        Assignment, MatchCase, Match,
        Stmt,
        Body, Pure, Return,
        TopLevel, NolangPure);

    return res;
}
<commit_msg>Reorder expr and return<commit_after>#include <iostream>
#include <fstream>
#include <streambuf>

#include <3pp/mpc/mpc.h>

std::string readFile(char *fname)
{
    std::ifstream is(fname, std::ifstream::in);
    std::string str(
        (std::istreambuf_iterator<char>(is)),
        std::istreambuf_iterator<char>()
    );
    return str + '\n';
}

int main(int argc, char **argv)
{
    if (argc <= 1) {
        std::cout << "Usage: " << argv[0] << "file\n";
        return 1;
    }
    mpc_parser_t* Comment   = mpc_new("comment");
    mpc_parser_t* Indent   = mpc_new("indent");
    mpc_parser_t* Newline   = mpc_new("newline");
    mpc_parser_t* WhiteSpace = mpc_new("ws");
    mpc_parser_t* OptionalWhiteSpace = mpc_new("ows");
    mpc_parser_t* OptionalWhiteSpaceNewline = mpc_new("owsn");
    mpc_parser_t* Number   = mpc_new("number");
    mpc_parser_t* Operator = mpc_new("operator");
    mpc_parser_t* FactorOperator = mpc_new("factorop");
    mpc_parser_t* TermOperator = mpc_new("termop");
    mpc_parser_t* Expr     = mpc_new("expr");
    mpc_parser_t* Body     = mpc_new("body");
    mpc_parser_t* Identifier = mpc_new("identifier");
    mpc_parser_t* TypeIdent = mpc_new("typeident");
    mpc_parser_t* Import = mpc_new("import");
    mpc_parser_t* MethodRet = mpc_new("methodret");
    mpc_parser_t* MethodDef = mpc_new("methoddef");
    mpc_parser_t* ParamDef = mpc_new("paramdef");
    mpc_parser_t* String = mpc_new("string");
    mpc_parser_t* Args = mpc_new("args");
    mpc_parser_t* Lexp = mpc_new("lexp");
    mpc_parser_t* Factor = mpc_new("factor");
    mpc_parser_t* MethodCall = mpc_new("methodcall");
    mpc_parser_t* MapIndex = mpc_new("mapindex");
    mpc_parser_t* ListItem = mpc_new("listitem");
    mpc_parser_t* MapItem = mpc_new("mapitem");
    mpc_parser_t* TupleMap = mpc_new("tuplemap");
    mpc_parser_t* MapItems = mpc_new("mapitems");
    mpc_parser_t* ListItems = mpc_new("listitems");
    mpc_parser_t* List = mpc_new("list");
    mpc_parser_t* Namespacedef = mpc_new("namespacedef");
    mpc_parser_t* Primitive = mpc_new("primitive");
    mpc_parser_t* Range = mpc_new("range");
    mpc_parser_t* MatchCase = mpc_new("matchcase");
    mpc_parser_t* Match = mpc_new("match");
    mpc_parser_t* Assignment = mpc_new("assignment");
    mpc_parser_t* Stmt = mpc_new("stmt");
    mpc_parser_t* Term = mpc_new("term");
    mpc_parser_t* Const = mpc_new("const");
    mpc_parser_t* Return = mpc_new("return");
    mpc_parser_t* Pure = mpc_new("pure");
    mpc_parser_t* TopLevel = mpc_new("toplevel");
    mpc_parser_t* NolangPure = mpc_new("nolangpure");

    mpc_err_t* err = mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE,
        "comment    : /(#|\\/\\/)[^\\r\\n]*/"
        "           | /\\/\\*[^\\*]*(\\*[^\\/][^\\*]*)*\\*\\// ;"
        "indent     : /\\s\\s+/ ;"
        "newline    : '\\n';"
        "ws         : /[\\s]+/ ;"
        "ows        : /[\\s\\t]*/ ;"
        "owsn       : /[\\s\\t\\n]*/ ;"
        "identifier : /[A-Za-z_][A-Za-z0-9_-]*/ ;"
        "typeident  : <identifier> <ows> ':' <ows> <identifier> ;"
        "number     : /[0-9]+/ ;"
        "string     : /\"(\\\\.|[^\"])*\"/ "
        "           | /\'(\\\\.|[^\'])*\'/ ; "
        "operator   : '+' | '-' | '*' | '/' ;"
        "factorop   : '*'"
        "           | '/'"
        "           | \"div\""
        "           | \"mod\""
        "           | \"rem\";"
        "termop     : '+'"
        "           | '-';"
        "import     : \"import\" <ws> <identifier> <newline>;"
        "const      : \"const\" <ws> <assignment> <newline>;"
        "methodret  : <ows> ':' <ows> <identifier> ;"
        "methoddef  : (<pure> <ws>)? <identifier> <ows> <args>? <methodret>? <ows> \"=>\" (<newline>|<ws>) <body> ;"
        "paramdef   : <typeident>? <ows> (',' <ows> <typeident>)*; "
        "args       : '(' <paramdef>? ')'; "
        "factor     : <namespacedef>"
        "           | '(' <lexp> ')'"
        "           | <number>"
        "           | <string>"
        "           | <identifier>; "
        "term       : <factor> (<ows> <factorop> <ows> <factor>)*;"
        "lexp       : <term> (<ows> <termop> <ows> <term>)* ; "
        "expr       : <list>"
        "           | <lexp>;"
        "methodcall : '(' (<expr> (',' <ows> <expr>)*)? ')';"
        "mapindex   : '[' <expr> ']';"
        "listitem   : <expr>;"
        "mapitem    : <string> <ows> ':' <owsn> <expr> ;"
        "tuplemap   : '(' <string> <owsn> ',' <owsn> <lexp> ')';"
        "mapitems   : (<tuplemap> | <mapitem>) <owsn> (',' <owsn> (<tuplemap> | <mapitem>)) *;"
        "listitems  : <listitem> (<owsn> ',' <owsn> <listitem>) *;"
        "list       : '[' <owsn> (<mapitems> | <listitems>)? <owsn> ']' ;"
        "namespacedef : <identifier> ('.' <identifier>)* (<methodcall> | <mapindex>)?;"
        "primitive  : <identifier> | <number> | <string> ;"
        "range      : <primitive> \"..\" <primitive>?;"
        "assignment : (<typeident>|<namespacedef>) <ws> '=' <ws> <expr>;"
        "matchcase  : <comment> | (<indent> (<range> | <primitive> | '?') <ows> ':' <ows> <stmt> <newline>);"
        "match      : \"match\" <ws> <stmt> <ows> \"=>\" <newline> <matchcase>+;"
        "stmt       : <match>"
        "           | <return>"
        "           | <assignment>"
        "           | <expr>"
        "           | <namespacedef>"
        "           | <list>"
        "           | <comment>;"
        "body       : ((<indent>+ <stmt>)? <newline>)* ;"
        "pure       : \"pure\" ;"
        "return     : \"return\" <ws> <stmt>;"
        "toplevel   : <import>"
        "           | <const>"
        "           | <comment>"
        "           | <methoddef>"
        "           | <newline>;"
        "nolangpure : /^/ <toplevel>* /$/;"
      ,
        Comment, Indent, Newline,
        WhiteSpace, OptionalWhiteSpace, OptionalWhiteSpaceNewline,
        Identifier, TypeIdent,
        Number, String,
        Operator, FactorOperator, TermOperator,
        Import, Const,
        MethodRet, MethodDef, ParamDef, Args,
        Factor, Term, Lexp,
        Expr, MethodCall,
        MapIndex, ListItem, MapItem, TupleMap, MapItems, ListItems, List,
        Namespacedef,
        Primitive, Range,
        Assignment, MatchCase, Match,
        Stmt,
        Body, Pure, Return,
        TopLevel, NolangPure, NULL);

    if (err != NULL) {
        mpc_err_print(err);
        mpc_err_delete(err);
        exit(1);
    }

    mpc_result_t r;
    std::string data = readFile(argv[1]);
    int res = 0;
    if (mpc_parse(argv[1], data.c_str(), NolangPure, &r)) {
      mpc_ast_print(static_cast<mpc_ast_t*>(r.output));
      mpc_ast_delete(static_cast<mpc_ast_t*>(r.output));
    } else {
        mpc_err_print(r.error);
        mpc_err_delete(r.error);
        res = 1;
    }

    mpc_cleanup(39,
        Comment, Indent, Newline,
        WhiteSpace, OptionalWhiteSpace, OptionalWhiteSpaceNewline,
        Identifier, TypeIdent,
        Number, String,
        Operator, FactorOperator, TermOperator,
        Import, Const,
        MethodRet, MethodDef, ParamDef, Args,
        Factor, Term, Lexp,
        Expr, MethodCall,
        MapIndex, ListItem, MapItem, TupleMap, MapItems, ListItems, List,
        Namespacedef,
        Primitive, Range,
        Assignment, MatchCase, Match,
        Stmt,
        Body, Pure, Return,
        TopLevel, NolangPure);

    return res;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/filerepository.h"
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/random.h"
#include "fnord-base/thread/eventloop.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-base/wallclock.h"
#include "fnord-base/VFS.h"
#include "fnord-rpc/ServerGroup.h"
#include "fnord-rpc/RPC.h"
#include "fnord-rpc/RPCClient.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-json/json.h"
#include "fnord-json/jsonrpc.h"
#include "fnord-http/httprouter.h"
#include "fnord-http/httpserver.h"
#include "fnord-http/VFSFileServlet.h"
#include "fnord-feeds/FeedService.h"
#include "fnord-feeds/RemoteFeedFactory.h"
#include "fnord-feeds/RemoteFeedReader.h"
#include "fnord-base/stats/statsdagent.h"
#include "fnord-sstable/SSTableServlet.h"
#include "fnord-eventdb/EventDBServlet.h"
#include "fnord-eventdb/TableRepository.h"
#include "fnord-eventdb/TableJanitor.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "analytics/AnalyticsServlet.h"
#include "analytics/CTRByPageServlet.h"
#include "analytics/CTRStatsServlet.h"
#include "analytics/CTRByPositionQuery.h"
#include "analytics/CTRByPageQuery.h"
#include "analytics/TopSearchQueriesQuery.h"
#include "analytics/DiscoveryKPIQuery.h"
#include "analytics/DiscoveryCategoryStatsQuery.h"
#include "analytics/AnalyticsQueryEngine.h"
#include "analytics/AnalyticsQueryEngine.h"

using namespace fnord;

std::atomic<bool> shutdown_sig;
fnord::thread::EventLoop ev;

void quit(int n) {
  shutdown_sig = true;
  fnord::logInfo("cm.chunkserver", "Shutting down...");
  // FIXPAUL: wait for http server stop...
  ev.shutdown();
}

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  /* shutdown hook */
  shutdown_sig = false;
  struct sigaction sa;
  memset(&sa, 0, sizeof(struct sigaction));
  sa.sa_handler = quit;
  sigaction(SIGTERM, &sa, NULL);
  sigaction(SIGQUIT, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "http_port",
      fnord::cli::FlagParser::T_INTEGER,
      false,
      NULL,
      "8000",
      "Start the public http server on this port",
      "<port>");

  flags.defineFlag(
      "readonly",
      cli::FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "readonly",
      "readonly");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "datadir path",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  WhitelistVFS vfs;

  /* start http server */
  fnord::thread::ThreadPool tpool;
  fnord::http::HTTPRouter http_router;
  fnord::http::HTTPServer http_server(&http_router, &ev);
  http_server.listen(flags.getInt("http_port"));

  /* sstable servlet */
  sstable::SSTableServlet sstable_servlet("/sstable", &vfs);
  http_router.addRouteByPrefixMatch("/sstable", &sstable_servlet);

  /* file servlet */
  http::VFSFileServlet file_servlet("/file", &vfs);
  http_router.addRouteByPrefixMatch("/file", &file_servlet);

  /* add all files to whitelist vfs */
  auto dir = flags.getString("datadir");
  FileUtil::ls(dir, [&vfs, &dir] (const String& file) -> bool {
    vfs.registerFile(file, FileUtil::joinPaths(dir, file));
    fnord::logInfo("cm.chunkserver", "[VFS] Adding file: $0", file);
    return true;
  });

  /* eventdb */
  auto readonly = flags.isSet("readonly");
  auto replica = flags.getString("replica");

  eventdb::TableRepository table_repo(dir, replica, readonly);
  table_repo.addTable("dawanda_joined_sessions", joinedSessionsSchema());

  eventdb::TableJanitor table_janitor(&table_repo);
  if (!readonly) {
    table_janitor.start();
  }

  eventdb::EventDBServlet eventdb_servlet(&table_repo);

  /* analytics */
  cm::AnalyticsQueryEngine analytics(8, dir, &table_repo);
  cm::AnalyticsServlet analytics_servlet(&analytics);
  http_router.addRouteByPrefixMatch("/analytics", &analytics_servlet, &tpool);
  http_router.addRouteByPrefixMatch("/eventdb", &eventdb_servlet, &tpool);

  analytics.registerQueryFactory("ctr_by_position", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPositionQuery(scan, segments);
  });

  analytics.registerQueryFactory("ctr_by_page", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPageQuery(scan, segments);
  });

  analytics.registerQueryFactory("discovery_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryKPIQuery(
        scan,
        segments,
        query.start_time,
        query.end_time);
  });

  analytics.registerQueryFactory("discovery_category0_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category1",
        params);
  });

  analytics.registerQueryFactory("discovery_category1_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category2",
        params);
  });

  analytics.registerQueryFactory("discovery_category2_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category2",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("discovery_category3_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category3",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("top_search_queries", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::TopSearchQueriesQuery(scan, segments, params);
  });

  ev.run();

  if (!readonly) {
    table_janitor.stop();
    table_janitor.check();
  }

  fnord::logInfo("cm.chunkserver", "Exiting...");

  return 0;
}

<commit_msg>cleaning up<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/filerepository.h"
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/random.h"
#include "fnord-base/thread/eventloop.h"
#include "fnord-base/thread/threadpool.h"
#include "fnord-base/wallclock.h"
#include "fnord-base/VFS.h"
#include "fnord-rpc/ServerGroup.h"
#include "fnord-rpc/RPC.h"
#include "fnord-rpc/RPCClient.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-json/json.h"
#include "fnord-json/jsonrpc.h"
#include "fnord-http/httprouter.h"
#include "fnord-http/httpserver.h"
#include "fnord-http/VFSFileServlet.h"
#include "fnord-feeds/FeedService.h"
#include "fnord-feeds/RemoteFeedFactory.h"
#include "fnord-feeds/RemoteFeedReader.h"
#include "fnord-base/stats/statsdagent.h"
#include "fnord-sstable/SSTableServlet.h"
#include "fnord-eventdb/EventDBServlet.h"
#include "fnord-eventdb/TableRepository.h"
#include "fnord-eventdb/TableJanitor.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "common.h"
#include "schemas.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "analytics/AnalyticsServlet.h"
#include "analytics/CTRByPageServlet.h"
#include "analytics/CTRStatsServlet.h"
#include "analytics/CTRByPositionQuery.h"
#include "analytics/CTRByPageQuery.h"
#include "analytics/TopSearchQueriesQuery.h"
#include "analytics/DiscoveryKPIQuery.h"
#include "analytics/DiscoveryCategoryStatsQuery.h"
#include "analytics/AnalyticsQueryEngine.h"
#include "analytics/AnalyticsQueryEngine.h"

using namespace fnord;

std::atomic<bool> shutdown_sig;
fnord::thread::EventLoop ev;

void quit(int n) {
  shutdown_sig = true;
  fnord::logInfo("cm.chunkserver", "Shutting down...");
  // FIXPAUL: wait for http server stop...
  ev.shutdown();
}

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  /* shutdown hook */
  shutdown_sig = false;
  struct sigaction sa;
  memset(&sa, 0, sizeof(struct sigaction));
  sa.sa_handler = quit;
  sigaction(SIGTERM, &sa, NULL);
  sigaction(SIGQUIT, &sa, NULL);
  sigaction(SIGINT, &sa, NULL);

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "http_port",
      fnord::cli::FlagParser::T_INTEGER,
      false,
      NULL,
      "8000",
      "Start the public http server on this port",
      "<port>");

  flags.defineFlag(
      "readonly",
      cli::FlagParser::T_SWITCH,
      false,
      NULL,
      NULL,
      "readonly",
      "readonly");

  flags.defineFlag(
      "replica",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "replica id",
      "<id>");

  flags.defineFlag(
      "datadir",
      cli::FlagParser::T_STRING,
      true,
      NULL,
      NULL,
      "datadir path",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  /* start http server */
  fnord::thread::ThreadPool tpool;
  fnord::http::HTTPRouter http_router;
  fnord::http::HTTPServer http_server(&http_router, &ev);
  http_server.listen(flags.getInt("http_port"));

  /* eventdb */
  auto dir = flags.getString("datadir");
  auto readonly = flags.isSet("readonly");
  auto replica = flags.getString("replica");

  eventdb::TableRepository table_repo(dir, replica, readonly);
  table_repo.addTable("dawanda_joined_sessions", joinedSessionsSchema());

  eventdb::TableJanitor table_janitor(&table_repo);
  if (!readonly) {
    table_janitor.start();
  }

  eventdb::EventDBServlet eventdb_servlet(&table_repo);

  /* analytics */
  cm::AnalyticsQueryEngine analytics(8, dir, &table_repo);
  cm::AnalyticsServlet analytics_servlet(&analytics);
  http_router.addRouteByPrefixMatch("/analytics", &analytics_servlet, &tpool);
  http_router.addRouteByPrefixMatch("/eventdb", &eventdb_servlet, &tpool);

  analytics.registerQueryFactory("ctr_by_position", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPositionQuery(scan, segments);
  });

  analytics.registerQueryFactory("ctr_by_page", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::CTRByPageQuery(scan, segments);
  });

  analytics.registerQueryFactory("discovery_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryKPIQuery(
        scan,
        segments,
        query.start_time,
        query.end_time);
  });

  analytics.registerQueryFactory("discovery_category0_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category1",
        params);
  });

  analytics.registerQueryFactory("discovery_category1_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category1",
        "queries.category2",
        params);
  });

  analytics.registerQueryFactory("discovery_category2_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category2",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("discovery_category3_kpis", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::DiscoveryCategoryStatsQuery(
        scan,
        segments,
        "queries.category3",
        "queries.category3",
        params);
  });

  analytics.registerQueryFactory("top_search_queries", [] (
      const cm::AnalyticsQuery& query,
      const cm::AnalyticsQuery::SubQueryParams params,
      const Vector<RefPtr<cm::TrafficSegment>>& segments,
      cm::AnalyticsTableScan* scan) {
    return new cm::TopSearchQueriesQuery(scan, segments, params);
  });

  ev.run();

  if (!readonly) {
    table_janitor.stop();
    table_janitor.check();
  }

  fnord::logInfo("cm.chunkserver", "Exiting...");

  return 0;
}

<|endoftext|>


<commit_before>#include "command.h"
#include "../CommandHandler.h"
#include "../OptionParser.h"

/* full name of the command */
CMDNAME("8ball");
/* description of the command */
CMDDESCR("respond to questions");
/* command usage synopsis */
CMDUSAGE("$8ball QUESTION");

/* 8ball: respond to questions */
std::string CommandHandler::eightball(char *out, struct command *c)
{
	int opt;
	OptionParser op(c->fullCmd, "");
	static struct OptionParser::option long_opts[] = {
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	while ((opt = op.getopt_long(long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			return HELPMSG(CMDNAME, CMDUSAGE, CMDDESCR);
		case '?':
			return std::string(op.opterr());
		default:
			return "";
		}
	}

	if (op.optind() == c->fullCmd.length())
		return USAGEMSG(CMDNAME, CMDUSAGE);

	if (c->fullCmd[c->fullCmd.length() - 1] != '?')
		return "[8 BALL] Ask me a question.";

	std::uniform_int_distribution<> dis(0, m_eightball.size());
	return "[8 BALL] @" + std::string(c->nick) + ", " + m_eightball[dis(m_gen)] + ".";
}
<commit_msg>Update eightball<commit_after>#include <string.h>
#include "command.h"
#include "../CommandHandler.h"
#include "../option.h"

/* full name of the command */
_CMDNAME("8ball");
/* description of the command */
_CMDDESCR("respond to questions");
/* command usage synopsis */
_CMDUSAGE("$8ball QUESTION");

/* 8ball: respond to questions */
std::string CommandHandler::eightball(char *out, struct command *c)
{
	int opt;
	char *last;
	static struct option long_opts[] = {
		{ "help", NO_ARG, 'h' },
		{ 0, 0, 0 }
	};

	opt_init();
	while ((opt = getopt_long(c->argc, c->argv, "", long_opts)) != EOF) {
		switch (opt) {
		case 'h':
			_HELPMSG(out, _CMDNAME, _CMDUSAGE, _CMDDESCR);
			return "";
		case '?':
			_sprintf(out, MAX_MSG, "%s", opterr());
			return "";
		default:
			return "";
		}
	}

	last = c->argv[c->argc - 1];
	last += strlen(last) - 1;
	if (optind == c->argc) {
		_USAGEMSG(out, _CMDNAME, _CMDUSAGE);
	} else if (*last != '?') {
		_sprintf(out, MAX_MSG, "[8 BALL] Ask me a question.");
	} else {
		std::uniform_int_distribution<> dis(0, m_eightball.size());
		_sprintf(out, MAX_MSG, "[8 BALL] @%s, %s.", c->nick,
				m_eightball[dis(m_gen)].c_str());
	}
	return "";
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: object.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 16:12:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SAMPLE_OBJECT_HXX
#define _SAMPLE_OBJECT_HXX

#ifndef __SBX_SBX_FACTORY_HXX //autogen
#include <svtools/sbxfac.hxx>
#endif
#ifndef __SBX_SBXVARIABLE_HXX //autogen
#include <svtools/sbxvar.hxx>
#endif
#ifndef _SBX_SBXOBJECT_HXX //autogen
#include <svtools/sbxobj.hxx>
#endif

// 1) Properties:
//    Name      der Name, R/O
//    Value     ein double-Wert, R/W
// 2) Methoden:
//    Display   Ausgabe eines Textes
//    Square    Argument * Argument
//    Event     Aufruf eines Basic-Programms
// 3) Unterobjekte:
//    eine Collection names "Elements". Der Zugriff ist sowohl als
//    Property (fuer das gesamte Objekt) als auch als Methode (fuer
//    einzelne Elemente, wird durchgereicht) implementiert.
// Diese Implementation ist ein Beispiel fuer eine tabellengesteuerte
// Version, die sehr viele Elemente enthalten kann.
// Die Collection findet sich in COLLECTN.*, die in der Collection
// enthaltenen Objekte in COLLELEM.*

class SampleObject : public SbxObject
{
    // Definition eines Tabelleneintrags. Dies wird hier gemacht,
    // da dadurch die Methoden und Properties als private deklariert
    // werden koennen.
#if defined ( ICC ) || defined ( HPUX ) || defined ( C50 )
public:
#endif
    typedef void( SampleObject::*pMeth )
        ( SbxVariable* pThis, SbxArray* pArgs, BOOL bWrite );
#if defined ( ICC ) || defined ( HPUX )
private:
#endif

    struct Methods {
        const char* pName;      // Name des Eintrags
        SbxDataType eType;      // Datentyp
        short nArgs;            // Argumente und Flags
        pMeth pFunc;            // Function Pointer
    };
    static Methods aMethods[];  // Methodentabelle

    // Methoden
    void Display( SbxVariable*, SbxArray*, BOOL );
    void Event( SbxVariable*, SbxArray*, BOOL );
    void Square( SbxVariable*, SbxArray*, BOOL );
    void Create( SbxVariable*, SbxArray*, BOOL );
    // Infoblock auffuellen
    SbxInfo* GetInfo( short nIdx );
    // Broadcaster Notification
    virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
                             const SfxHint& rHint, const TypeId& rHintType );
public:
    SampleObject( const String& );
    // Suchen eines Elements
    virtual SbxVariable* Find( const String&, SbxClassType );
};

// Die dazugehoerige Factory:

class SampleObjectFac : public SbxFactory
{
public:
    virtual SbxObject* CreateObject( const String& );
};

#endif
<commit_msg>#65293#: add C52<commit_after>/*************************************************************************
 *
 *  $RCSfile: object.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hr $ $Date: 2000-10-26 14:59:10 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SAMPLE_OBJECT_HXX
#define _SAMPLE_OBJECT_HXX

#ifndef __SBX_SBX_FACTORY_HXX //autogen
#include <svtools/sbxfac.hxx>
#endif
#ifndef __SBX_SBXVARIABLE_HXX //autogen
#include <svtools/sbxvar.hxx>
#endif
#ifndef _SBX_SBXOBJECT_HXX //autogen
#include <svtools/sbxobj.hxx>
#endif

// 1) Properties:
//    Name      der Name, R/O
//    Value     ein double-Wert, R/W
// 2) Methoden:
//    Display   Ausgabe eines Textes
//    Square    Argument * Argument
//    Event     Aufruf eines Basic-Programms
// 3) Unterobjekte:
//    eine Collection names "Elements". Der Zugriff ist sowohl als
//    Property (fuer das gesamte Objekt) als auch als Methode (fuer
//    einzelne Elemente, wird durchgereicht) implementiert.
// Diese Implementation ist ein Beispiel fuer eine tabellengesteuerte
// Version, die sehr viele Elemente enthalten kann.
// Die Collection findet sich in COLLECTN.*, die in der Collection
// enthaltenen Objekte in COLLELEM.*

class SampleObject : public SbxObject
{
    // Definition eines Tabelleneintrags. Dies wird hier gemacht,
    // da dadurch die Methoden und Properties als private deklariert
    // werden koennen.
#if defined ( ICC ) || defined ( HPUX ) || defined ( C50 ) || defined ( C52 )
public:
#endif
    typedef void( SampleObject::*pMeth )
        ( SbxVariable* pThis, SbxArray* pArgs, BOOL bWrite );
#if defined ( ICC ) || defined ( HPUX )
private:
#endif

    struct Methods {
        const char* pName;      // Name des Eintrags
        SbxDataType eType;      // Datentyp
        short nArgs;            // Argumente und Flags
        pMeth pFunc;            // Function Pointer
    };
    static Methods aMethods[];  // Methodentabelle

    // Methoden
    void Display( SbxVariable*, SbxArray*, BOOL );
    void Event( SbxVariable*, SbxArray*, BOOL );
    void Square( SbxVariable*, SbxArray*, BOOL );
    void Create( SbxVariable*, SbxArray*, BOOL );
    // Infoblock auffuellen
    SbxInfo* GetInfo( short nIdx );
    // Broadcaster Notification
    virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
                             const SfxHint& rHint, const TypeId& rHintType );
public:
    SampleObject( const String& );
    // Suchen eines Elements
    virtual SbxVariable* Find( const String&, SbxClassType );
};

// Die dazugehoerige Factory:

class SampleObjectFac : public SbxFactory
{
public:
    virtual SbxObject* CreateObject( const String& );
};

#endif
<|endoftext|>


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

#ifndef _SBSTDOBJ_HXX
#define _SBSTDOBJ_HXX

#ifndef _SBX_SBXOBJECT_HXX //autogen
#include <sbxobj.hxx>
#endif

class StarBASIC;
class SbStdFactory;

class SbiStdObject : public SbxObject
{
    SbStdFactory* pStdFactory;

   ~SbiStdObject();
    SbxInfo* GetInfo( short );
    virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
                             const SfxHint& rHint, const TypeId& rHintType );
public:
    SbiStdObject( const String&, StarBASIC* );
    virtual SbxVariable* Find( const String&, SbxClassType );
    virtual void SetModified( BOOL );
};

#endif
<commit_msg>INTEGRATION: CWS warnings01 (1.3.30); FILE MERGED 2005/12/01 14:56:08 ab 1.3.30.1: #i53898# Removed warnings for unxlngi6<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: stdobj.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 17:44:43 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SBSTDOBJ_HXX
#define _SBSTDOBJ_HXX

#ifndef _SBX_SBXOBJECT_HXX //autogen
#include <sbxobj.hxx>
#endif

class StarBASIC;
class SbStdFactory;

class SbiStdObject : public SbxObject
{
    SbStdFactory* pStdFactory;

   ~SbiStdObject();
    using SbxVariable::GetInfo;
    SbxInfo* GetInfo( short );
    virtual void SFX_NOTIFY( SfxBroadcaster& rBC, const TypeId& rBCType,
                             const SfxHint& rHint, const TypeId& rHintType );
public:
    SbiStdObject( const String&, StarBASIC* );
    virtual SbxVariable* Find( const String&, SbxClassType );
    virtual void SetModified( BOOL );
};

#endif
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior_decider/signal_light_scenario.h"

#include <limits>
#include <string>
#include <vector>

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::common::util::WithinBound;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;

void SignalLightScenario::Reset() {}

bool SignalLightScenario::Init() {
  exist_ = true;
  return exist_;
}

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  if (!FindValidSignalLight(reference_line_info)) {
    ADEBUG << "No valid signal light along reference line";
    return 0;
  }
  ReadSignals();

  for (const hdmap::PathOverlap* signal_light :
       signal_lights_along_reference_line_) {
    const TrafficLight signal = GetSignal(signal_light->object_id);
    double stop_deceleration =
        GetStopDeceleration(reference_line_info, signal_light);

    if ((signal.color() == TrafficLight::RED &&
         stop_deceleration < FLAGS_max_stop_deceleration) ||
        (signal.color() == TrafficLight::UNKNOWN &&
         stop_deceleration < FLAGS_max_stop_deceleration) ||
        (signal.color() == TrafficLight::YELLOW &&
         stop_deceleration < FLAGS_max_stop_deacceleration_for_yellow_light)) {
      CreateStopObstacle(frame, reference_line_info, signal_light);
    }
  }

  return 0;
}

bool SignalLightScenario::FindValidSignalLight(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() <= 0) {
    ADEBUG << "No signal lights from reference line.";
    return false;
  } else {
    ADEBUG << "Found signal_lights size=" << signal_lights.size();
  }
  signal_lights_along_reference_line_.clear();
  for (const hdmap::PathOverlap& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_max_stop_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line_.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line_.size() > 0;
}

void SignalLightScenario::ReadSignals() {
  detected_signals_.clear();
  detected_signals_.clear();
  if (AdapterManager::GetTrafficLightDetection()->Empty()) {
    return;
  }
  if (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
      FLAGS_signal_expire_time_sec) {
    AWARN << "traffic signals msg is expired: "
          << AdapterManager::GetTrafficLightDetection()->GetDelaySec();
    return;
  }
  const TrafficLightDetection& detection =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();
  for (int j = 0; j < detection.traffic_light_size(); j++) {
    const TrafficLight& signal = detection.traffic_light(j);
    detected_signals_[signal.id()] = &signal;
  }
}

TrafficLight SignalLightScenario::GetSignal(const std::string& signal_id) {
  const auto* result =
      apollo::common::util::FindPtrOrNull(detected_signals_, signal_id);
  if (result == nullptr) {
    TrafficLight traffic_light;
    traffic_light.set_id(signal_id);
    traffic_light.set_color(TrafficLight::UNKNOWN);
    traffic_light.set_confidence(0.0);
    traffic_light.set_tracking_time(0.0);
    return traffic_light;
  }
  return *result;
}

double SignalLightScenario::GetStopDeceleration(
    ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  double adc_speed =
      common::VehicleStateProvider::instance()->linear_velocity();
  if (adc_speed < FLAGS_max_stop_speed) {
    return 0.0;
  }
  double stop_distance = 0.0;
  double adc_front_s = reference_line_info->AdcSlBoundary().end_s();
  double stop_line_s = signal_light->start_s;

  if (stop_line_s > adc_front_s) {
    stop_distance = stop_line_s - adc_front_s;
  } else {
    stop_distance = stop_line_s + FLAGS_max_stop_distance_buffer - adc_front_s;
  }
  if (stop_distance < 1e-5) {
    // longitudinal_acceleration_lower_bound is a negative value.
    return -FLAGS_longitudinal_acceleration_lower_bound;
  }
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

void SignalLightScenario::CreateStopObstacle(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  // check
  const auto& reference_line = reference_line_info->reference_line();
  const double stop_s =
      signal_light->start_s - FLAGS_traffic_light_stop_distance;
  const double box_center_s =
      signal_light->start_s + FLAGS_virtual_stop_wall_length / 2.0;
  if (!WithinBound(0.0, reference_line.Length(), stop_s) ||
      !WithinBound(0.0, reference_line.Length(), box_center_s)) {
    ADEBUG << "signal " << signal_light->object_id
           << " is not on reference line";
    return;
  }

  // create virtual stop wall
  std::string virtual_obstacle_id =
      FLAGS_signal_light_virtual_obstacle_id_prefix + signal_light->object_id;
  auto* obstacle = frame->CreateVirtualStopObstacle(
      reference_line_info, virtual_obstacle_id, signal_light->start_s);
  if (!obstacle) {
    AERROR << "Failed to create obstacle [" << virtual_obstacle_id << "]";
    return;
  }
  PathObstacle* stop_wall = reference_line_info->AddObstacle(obstacle);
  if (!stop_wall) {
    AERROR << "Failed to create path_obstacle for: " << virtual_obstacle_id;
    return;
  }

  return;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: fixed a bug of colliding with traffic light virtual obstacle<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior_decider/signal_light_scenario.h"

#include <limits>
#include <string>
#include <vector>

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::common::util::WithinBound;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;

void SignalLightScenario::Reset() {}

bool SignalLightScenario::Init() {
  exist_ = true;
  return exist_;
}

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  if (!FindValidSignalLight(reference_line_info)) {
    ADEBUG << "No valid signal light along reference line";
    return 0;
  }
  ReadSignals();

  for (const hdmap::PathOverlap* signal_light :
       signal_lights_along_reference_line_) {
    const TrafficLight signal = GetSignal(signal_light->object_id);
    double stop_deceleration =
        GetStopDeceleration(reference_line_info, signal_light);

    if ((signal.color() == TrafficLight::RED &&
         stop_deceleration < FLAGS_max_stop_deceleration) ||
        // (signal.color() == TrafficLight::UNKNOWN &&
        //  stop_deceleration < FLAGS_max_stop_deceleration) ||
        (signal.color() == TrafficLight::YELLOW &&
         stop_deceleration < FLAGS_max_stop_deacceleration_for_yellow_light)) {
      CreateStopObstacle(frame, reference_line_info, signal_light);
    }
  }

  return 0;
}

bool SignalLightScenario::FindValidSignalLight(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() <= 0) {
    ADEBUG << "No signal lights from reference line.";
    return false;
  } else {
    ADEBUG << "Found signal_lights size=" << signal_lights.size();
  }
  signal_lights_along_reference_line_.clear();
  for (const hdmap::PathOverlap& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_max_stop_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line_.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line_.size() > 0;
}

void SignalLightScenario::ReadSignals() {
  detected_signals_.clear();
  detected_signals_.clear();
  if (AdapterManager::GetTrafficLightDetection()->Empty()) {
    return;
  }
  if (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
      FLAGS_signal_expire_time_sec) {
    AWARN << "traffic signals msg is expired: "
          << AdapterManager::GetTrafficLightDetection()->GetDelaySec();
    return;
  }
  const TrafficLightDetection& detection =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();
  for (int j = 0; j < detection.traffic_light_size(); j++) {
    const TrafficLight& signal = detection.traffic_light(j);
    detected_signals_[signal.id()] = &signal;
  }
}

TrafficLight SignalLightScenario::GetSignal(const std::string& signal_id) {
  const auto* result =
      apollo::common::util::FindPtrOrNull(detected_signals_, signal_id);
  if (result == nullptr) {
    TrafficLight traffic_light;
    traffic_light.set_id(signal_id);
    traffic_light.set_color(TrafficLight::UNKNOWN);
    traffic_light.set_confidence(0.0);
    traffic_light.set_tracking_time(0.0);
    return traffic_light;
  }
  return *result;
}

double SignalLightScenario::GetStopDeceleration(
    ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  double adc_speed =
      common::VehicleStateProvider::instance()->linear_velocity();
  if (adc_speed < FLAGS_max_stop_speed) {
    return 0.0;
  }
  double stop_distance = 0.0;
  double adc_front_s = reference_line_info->AdcSlBoundary().end_s();
  double stop_line_s = signal_light->start_s;

  if (stop_line_s > adc_front_s) {
    stop_distance = stop_line_s - adc_front_s;
  } else {
    stop_distance = stop_line_s + FLAGS_max_stop_distance_buffer - adc_front_s;
  }
  if (stop_distance < 1e-5) {
    // longitudinal_acceleration_lower_bound is a negative value.
    return -FLAGS_longitudinal_acceleration_lower_bound;
  }
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

void SignalLightScenario::CreateStopObstacle(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  // check
  const auto& reference_line = reference_line_info->reference_line();
  const double stop_s =
      signal_light->start_s - FLAGS_traffic_light_stop_distance;
  const double box_center_s =
      signal_light->start_s + FLAGS_virtual_stop_wall_length / 2.0;
  if (!WithinBound(0.0, reference_line.Length(), stop_s) ||
      !WithinBound(0.0, reference_line.Length(), box_center_s)) {
    ADEBUG << "signal " << signal_light->object_id
           << " is not on reference line";
    return;
  }

  // create virtual stop wall
  std::string virtual_obstacle_id =
      FLAGS_signal_light_virtual_obstacle_id_prefix + signal_light->object_id;
  auto* obstacle = frame->CreateVirtualStopObstacle(
      reference_line_info, virtual_obstacle_id, signal_light->start_s);
  if (!obstacle) {
    AERROR << "Failed to create obstacle [" << virtual_obstacle_id << "]";
    return;
  }
  PathObstacle* stop_wall = reference_line_info->AddObstacle(obstacle);
  if (!stop_wall) {
    AERROR << "Failed to create path_obstacle for: " << virtual_obstacle_id;
    return;
  }

  return;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior_decider/signal_light_scenario.h"

#include <limits>
#include <string>
#include <vector>

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;
using apollo::common::util::WithinBound;

void SignalLightScenario::Reset() {}

bool SignalLightScenario::Init() {
  exist_ = true;
  return exist_;
}

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  if (!FindValidSignalLight(reference_line_info)) {
    AINFO << "No valid signal light along reference line";
    return 0;
  }
  ReadSignals();

  for (const hdmap::PathOverlap* signal_light :
       signal_lights_along_reference_line_) {
    const TrafficLight signal = GetSignal(signal_light->object_id);
    double stop_deceleration =
        GetStopDeceleration(reference_line_info, signal_light);

    if ((signal.color() == TrafficLight::RED &&
         stop_deceleration < FLAGS_stop_max_deceleration) ||
        (signal.color() == TrafficLight::UNKNOWN &&
         stop_deceleration < FLAGS_stop_max_deceleration) ||
        (signal.color() == TrafficLight::YELLOW &&
         stop_deceleration < FLAGS_max_deacceleration_for_yellow_light_stop)) {
      CreateStopObstacle(frame, reference_line_info, signal_light);
    }
  }

  return 0;
}

bool SignalLightScenario::FindValidSignalLight(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() <= 0) {
    ADEBUG << "No signal lights from reference line.";
    return false;
  } else {
    AINFO << "Found signal_lights size=" << signal_lights.size();
  }
  signal_lights_along_reference_line_.clear();
  for (const hdmap::PathOverlap& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_stop_max_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line_.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line_.size() > 0;
}

void SignalLightScenario::ReadSignals() {
  detected_signals_.clear();
  detected_signals_.clear();
  if (AdapterManager::GetTrafficLightDetection()->Empty()) {
    return;
  }
  if (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
      FLAGS_signal_expire_time_sec) {
    AWARN << "traffic signals msg is expired: "
          << AdapterManager::GetTrafficLightDetection()->GetDelaySec();
    return;
  }
  const TrafficLightDetection& detection =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();
  for (int j = 0; j < detection.traffic_light_size(); j++) {
    const TrafficLight& signal = detection.traffic_light(j);
    detected_signals_[signal.id()] = &signal;
  }
}

TrafficLight SignalLightScenario::GetSignal(const std::string& signal_id) {
  const auto* result =
      apollo::common::util::FindPtrOrNull(detected_signals_, signal_id);
  if (result == nullptr) {
    TrafficLight traffic_light;
    traffic_light.set_id(signal_id);
    traffic_light.set_color(TrafficLight::UNKNOWN);
    traffic_light.set_confidence(0.0);
    traffic_light.set_tracking_time(0.0);
    return traffic_light;
  }
  return *result;
}

double SignalLightScenario::GetStopDeceleration(
    ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  double adc_speed =
      common::VehicleStateProvider::instance()->linear_velocity();
  if (adc_speed < FLAGS_stop_min_speed) {
    return 0.0;
  }
  double stop_distance = 0.0;
  double adc_front_s = reference_line_info->AdcSlBoundary().end_s();
  double stop_line_s = signal_light->start_s;

  if (stop_line_s > adc_front_s) {
    stop_distance = stop_line_s - adc_front_s;
  } else {
    stop_distance = stop_line_s + FLAGS_stop_max_distance_buffer - adc_front_s;
  }
  if (stop_distance < 1e-5) {
    // longitudinal_acceleration_lower_bound is a negative value.
    return -FLAGS_longitudinal_acceleration_lower_bound;
  }
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

void SignalLightScenario::CreateStopObstacle(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  const auto& reference_line = reference_line_info->reference_line();
  const double stop_s =
      signal_light->start_s - FLAGS_stop_distance_traffic_light;
  const double box_center_s =
      signal_light->start_s + FLAGS_virtual_stop_wall_length / 2.0;
  if (!WithinBound(0.0, reference_line.Length(), stop_s) ||
      !WithinBound(0.0, reference_line.Length(), box_center_s)) {
    ADEBUG << "signal " << signal_light->object_id
           << " is not on reference line";
    return;
  }
  // double heading = reference_line.GetReferencePoint(stop_s).heading();
  double left_lane_width = 0.0;
  double right_lane_width = 0.0;
  reference_line.GetLaneWidth(signal_light->start_s, &left_lane_width,
                              &right_lane_width);

  /*
  auto box_center = reference_line.GetReferencePoint(box_center_s);
  common::math::Box2d stop_box{box_center, heading,
                               FLAGS_virtual_stop_wall_length,
                               left_lane_width + right_lane_width};
  PathObstacle* stop_wall =
      reference_line_info->AddObstacle(frame->AddStaticVirtualObstacle(
          FLAGS_signal_light_virtual_object_id_prefix + signal_light->object_id,
          stop_box));
  */
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: [lattice] recover stop fence for red traffic light<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior_decider/signal_light_scenario.h"

#include <limits>
#include <string>
#include <vector>

#include "gflags/gflags.h"
#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/log.h"
#include "modules/common/util/map_util.h"
#include "modules/common/vehicle_state/vehicle_state_provider.h"
#include "modules/planning/common/planning_gflags.h"
#include "modules/planning/proto/planning_internal.pb.h"

namespace apollo {
namespace planning {

using apollo::common::adapter::AdapterManager;
using apollo::perception::TrafficLight;
using apollo::perception::TrafficLightDetection;
using apollo::common::util::WithinBound;

void SignalLightScenario::Reset() {}

bool SignalLightScenario::Init() {
  exist_ = true;
  return exist_;
}

int SignalLightScenario::ComputeScenarioDecision(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    PlanningTarget* planning_target) {
  CHECK(frame != nullptr);

  if (!FindValidSignalLight(reference_line_info)) {
    AINFO << "No valid signal light along reference line";
    return 0;
  }
  ReadSignals();

  for (const hdmap::PathOverlap* signal_light :
       signal_lights_along_reference_line_) {
    const TrafficLight signal = GetSignal(signal_light->object_id);
    double stop_deceleration =
        GetStopDeceleration(reference_line_info, signal_light);

    if ((signal.color() == TrafficLight::RED &&
         stop_deceleration < FLAGS_stop_max_deceleration) ||
        (signal.color() == TrafficLight::UNKNOWN &&
         stop_deceleration < FLAGS_stop_max_deceleration) ||
        (signal.color() == TrafficLight::YELLOW &&
         stop_deceleration < FLAGS_max_deacceleration_for_yellow_light_stop)) {
      CreateStopObstacle(frame, reference_line_info, signal_light);
    }
  }

  return 0;
}

bool SignalLightScenario::FindValidSignalLight(
    ReferenceLineInfo* const reference_line_info) {
  const std::vector<hdmap::PathOverlap>& signal_lights =
      reference_line_info->reference_line().map_path().signal_overlaps();
  if (signal_lights.size() <= 0) {
    ADEBUG << "No signal lights from reference line.";
    return false;
  } else {
    AINFO << "Found signal_lights size=" << signal_lights.size();
  }
  signal_lights_along_reference_line_.clear();
  for (const hdmap::PathOverlap& signal_light : signal_lights) {
    if (signal_light.start_s + FLAGS_stop_max_distance_buffer >
        reference_line_info->AdcSlBoundary().end_s()) {
      signal_lights_along_reference_line_.push_back(&signal_light);
    }
  }
  return signal_lights_along_reference_line_.size() > 0;
}

void SignalLightScenario::ReadSignals() {
  detected_signals_.clear();
  detected_signals_.clear();
  if (AdapterManager::GetTrafficLightDetection()->Empty()) {
    return;
  }
  if (AdapterManager::GetTrafficLightDetection()->GetDelaySec() >
      FLAGS_signal_expire_time_sec) {
    AWARN << "traffic signals msg is expired: "
          << AdapterManager::GetTrafficLightDetection()->GetDelaySec();
    return;
  }
  const TrafficLightDetection& detection =
      AdapterManager::GetTrafficLightDetection()->GetLatestObserved();
  for (int j = 0; j < detection.traffic_light_size(); j++) {
    const TrafficLight& signal = detection.traffic_light(j);
    detected_signals_[signal.id()] = &signal;
  }
}

TrafficLight SignalLightScenario::GetSignal(const std::string& signal_id) {
  const auto* result =
      apollo::common::util::FindPtrOrNull(detected_signals_, signal_id);
  if (result == nullptr) {
    TrafficLight traffic_light;
    traffic_light.set_id(signal_id);
    traffic_light.set_color(TrafficLight::UNKNOWN);
    traffic_light.set_confidence(0.0);
    traffic_light.set_tracking_time(0.0);
    return traffic_light;
  }
  return *result;
}

double SignalLightScenario::GetStopDeceleration(
    ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  double adc_speed =
      common::VehicleStateProvider::instance()->linear_velocity();
  if (adc_speed < FLAGS_stop_min_speed) {
    return 0.0;
  }
  double stop_distance = 0.0;
  double adc_front_s = reference_line_info->AdcSlBoundary().end_s();
  double stop_line_s = signal_light->start_s;

  if (stop_line_s > adc_front_s) {
    stop_distance = stop_line_s - adc_front_s;
  } else {
    stop_distance = stop_line_s + FLAGS_stop_max_distance_buffer - adc_front_s;
  }
  if (stop_distance < 1e-5) {
    // longitudinal_acceleration_lower_bound is a negative value.
    return -FLAGS_longitudinal_acceleration_lower_bound;
  }
  return (adc_speed * adc_speed) / (2 * stop_distance);
}

void SignalLightScenario::CreateStopObstacle(
    Frame* frame, ReferenceLineInfo* const reference_line_info,
    const hdmap::PathOverlap* signal_light) {
  const auto& reference_line = reference_line_info->reference_line();
  const double stop_s =
      signal_light->start_s - FLAGS_stop_distance_traffic_light;
  const double box_center_s =
      signal_light->start_s + FLAGS_virtual_stop_wall_length / 2.0;
  if (!WithinBound(0.0, reference_line.Length(), stop_s) ||
      !WithinBound(0.0, reference_line.Length(), box_center_s)) {
    ADEBUG << "signal " << signal_light->object_id
           << " is not on reference line";
    return;
  }
  double heading = reference_line.GetReferencePoint(stop_s).heading();
  double left_lane_width = 0.0;
  double right_lane_width = 0.0;
  reference_line.GetLaneWidth(signal_light->start_s, &left_lane_width,
                              &right_lane_width);

  auto box_center = reference_line.GetReferencePoint(box_center_s);
  common::math::Box2d stop_box{box_center, heading,
                               FLAGS_virtual_stop_wall_length,
                               left_lane_width + right_lane_width};
  reference_line_info->AddObstacle(frame->AddStaticVirtualObstacle(
      FLAGS_signal_light_virtual_object_id_prefix + signal_light->object_id,
      stop_box));
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>