<commit_before>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

LICENCE: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "apply_disruption.h"
#include "utils/logger.h"
#include "type/datetime.h"

#include <boost/make_shared.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include "boost/date_time/gregorian/gregorian.hpp"

namespace navitia {

namespace nt = navitia::type;
namespace bt = boost::posix_time;
namespace bg = boost::gregorian;

namespace {

struct apply_impacts_visitor : public boost::static_visitor<> {
    boost::shared_ptr<nt::disruption::Impact> impact;
    nt::PT_Data& pt_data;
    const nt::MetaData& meta;
    std::string action;
    nt::RTLevel rt_level; // level of the impacts
    log4cplus::Logger log = log4cplus::Logger::getInstance("log");

    apply_impacts_visitor(const boost::shared_ptr<nt::disruption::Impact>& impact,
            nt::PT_Data& pt_data, const nt::MetaData& meta, std::string action, nt::RTLevel l) :
        impact(impact), pt_data(pt_data), meta(meta), action(action), rt_level(l) {}

    virtual ~apply_impacts_visitor() {}
    apply_impacts_visitor(const apply_impacts_visitor&) = default;

    virtual void operator()(nt::MetaVehicleJourney*, const nt::Route* = nullptr) = 0;

    void log_start_action(std::string uri) {
        LOG4CPLUS_TRACE(log, "Start to " << action << " impact " << impact.get()->uri << " on object " << uri);
    }

    void log_end_action(std::string uri) {
        LOG4CPLUS_TRACE(log, "Finished to " << action << " impact " << impact.get()->uri << " on object " << uri);
    }

    void operator()(nt::disruption::UnknownPtObj&) { }

    void operator()(nt::Network* network) {
        this->log_start_action(network->uri);
        for (auto line : network->line_list) {
            this->operator()(line);
        }
        this->log_end_action(network->uri);
    }

    void operator()(nt::disruption::LineSection& ls) {
        std::string uri = "line section (" +  ls.line->uri  + ")";
        this->log_start_action(uri);
        this->operator()(ls.line);
        this->log_end_action(uri);
    }

    void operator()(nt::Line* line) {
        this->log_start_action(line->uri);
        for(auto route : line->route_list) {
            this->operator()(route);
        }
        this->log_end_action(line->uri);
    }

    void operator()(nt::Route* route) {
        this->log_start_action(route->uri);

        // we cannot ensure that all VJ of a MetaVJ are on the same route,
        // and since we want all actions to operate on MetaVJ, we collect all MetaVJ of the route
        // (but we'll change only the route's vj)
        std::set<nt::MetaVehicleJourney*> mvjs;
        route->for_each_vehicle_journey([&mvjs](nt::VehicleJourney& vj) {
            mvjs.insert(vj.meta_vj); return true;
        });
        for (auto* mvj: mvjs) {
            this->operator()(mvj, route);
        }
        this->log_end_action(route->uri);
    }
};

struct add_impacts_visitor : public apply_impacts_visitor {
    add_impacts_visitor(const boost::shared_ptr<nt::disruption::Impact>& impact,
            nt::PT_Data& pt_data, const nt::MetaData& meta, nt::RTLevel l) :
        apply_impacts_visitor(impact, pt_data, meta, "add", l) {}

    ~add_impacts_visitor() {}
    add_impacts_visitor(const add_impacts_visitor&) = default;

    using apply_impacts_visitor::operator();

    void operator()(nt::MetaVehicleJourney* mvj, const nt::Route* r = nullptr) {
        log_start_action(mvj->uri);
        if (impact->severity->effect == nt::disruption::Effect::NO_SERVICE) {
            LOG4CPLUS_TRACE(log, "canceling " << mvj->uri);
            mvj->cancel_vj(rt_level, impact->application_periods, pt_data, meta, r);
            mvj->impacted_by.push_back(impact);
        } else if (impact->severity->effect == nt::disruption::Effect::MODIFIED_SERVICE) {
            LOG4CPLUS_TRACE(log, "modifying " << mvj->uri);

        } else {
            LOG4CPLUS_DEBUG(log, "unhandled action on " << mvj->uri);
        }
        log_end_action(mvj->uri);
    }

    void operator()(nt::StopPoint* stop_point) {
        LOG4CPLUS_INFO(log, "Disruption on stop point:" << stop_point->uri << " is not handled");
    }

    void operator()(nt::StopArea* stop_area) {
        LOG4CPLUS_INFO(log, "Disruption on stop area:" << stop_area->uri << " is not handled");
    }
};

static bool is_modifying_effect(nt::disruption::Effect e) {
    // check is the effect needs to modify the model
    return in(e, {nt::disruption::Effect::NO_SERVICE,
                  nt::disruption::Effect::MODIFIED_SERVICE});
}

void apply_impact(boost::shared_ptr<nt::disruption::Impact>impact,
                         nt::PT_Data& pt_data, const nt::MetaData& meta) {
    if (! is_modifying_effect(impact->severity->effect)) {
        return;
    }
    LOG4CPLUS_TRACE(log4cplus::Logger::getInstance("log"),
                    "Adding impact: " << impact.get()->uri);
    add_impacts_visitor v(impact, pt_data, meta, impact->disruption->rt_level);
    boost::for_each(impact->informed_entities, boost::apply_visitor(v));
    LOG4CPLUS_TRACE(log4cplus::Logger::getInstance("log"),
                    impact.get()->uri << " impact added");
}

struct delete_impacts_visitor : public apply_impacts_visitor {
    size_t nb_vj_reassigned = 0;

    delete_impacts_visitor(boost::shared_ptr<nt::disruption::Impact> impact,
            nt::PT_Data& pt_data, const nt::MetaData& meta, nt::RTLevel l) :
        apply_impacts_visitor(impact, pt_data, meta, "delete", l) {}

    ~delete_impacts_visitor() {}

    using apply_impacts_visitor::operator();

    // We set all the validity pattern to the theorical one, we will re-apply
    // other disruptions after
    void operator()(nt::MetaVehicleJourney* mvj, const nt::Route* r = nullptr) {
        if (impact->severity->effect == nt::disruption::Effect::NO_SERVICE) {
            for (auto* vj: mvj->get_vjs_in_period(rt_level, impact->application_periods, meta, r)) {
                vj->validity_patterns[rt_level] = vj->validity_patterns[nt::RTLevel::Base];
                ++ nb_vj_reassigned;
            }
        } else {
            LOG4CPLUS_DEBUG(log, "unhandled delete action on " << mvj->uri);
        }
        const auto& impact = this->impact;
        boost::range::remove_erase_if(mvj->impacted_by,
            [&impact](const boost::weak_ptr<nt::disruption::Impact>& i) {
                auto spt = i.lock();
                return (spt) ? spt == impact : true;
        });

        for (auto i: mvj->impacted_by) {
            if (auto spt = i.lock()) {
                auto v = add_impacts_visitor(spt, pt_data, meta, rt_level);
                v(mvj);
            }
        }
    }

    void operator()(const nt::StopPoint* stop_point) {
        LOG4CPLUS_INFO(log, "Deletion of disruption on stop point:" << stop_point->uri << " is not handled");

    }

    void operator()(const nt::StopArea* stop_area) {
        LOG4CPLUS_INFO(log, "Deletion of disruption on stop point:" << stop_area->uri << " is not handled");
    }
};

void delete_impact(boost::shared_ptr<nt::disruption::Impact>impact,
                          nt::PT_Data& pt_data, const nt::MetaData& meta) {
    if (! is_modifying_effect(impact->severity->effect)) {
        return;
    }
    auto log = log4cplus::Logger::getInstance("log");
    LOG4CPLUS_DEBUG(log, "Deleting impact: " << impact.get()->uri);
    delete_impacts_visitor v(impact, pt_data, meta, impact->disruption->rt_level);
    boost::for_each(impact->informed_entities, boost::apply_visitor(v));
    LOG4CPLUS_DEBUG(log, impact.get()->uri << " deleted");
}

} // anonymous namespace

void delete_disruption(const std::string& disruption_id,
                       nt::PT_Data& pt_data,
                       const nt::MetaData& meta) {
    auto log = log4cplus::Logger::getInstance("log");
    LOG4CPLUS_DEBUG(log, "Deleting disruption: " << disruption_id);
    nt::disruption::DisruptionHolder& holder = pt_data.disruption_holder;

    // the disruption is deleted by RAII
    std::unique_ptr<nt::disruption::Disruption> disruption = holder.pop_disruption(disruption_id);
    if (disruption) {
        std::vector<nt::disruption::PtObj> informed_entities;
        for (const auto& impact : disruption->get_impacts()) {
            informed_entities.insert(informed_entities.end(),
                              impact->informed_entities.begin(),
                              impact->informed_entities.end());
            delete_impact(impact, pt_data, meta);
        }
    }
    LOG4CPLUS_DEBUG(log, disruption_id << " disruption deleted");
}

void apply_disruption(const type::disruption::Disruption& disruption, nt::PT_Data& pt_data,
                    const navitia::type::MetaData &meta) {
    LOG4CPLUS_DEBUG(log4cplus::Logger::getInstance("log"), "applying disruption: " << disruption.uri);
    for (const auto& impact: disruption.get_impacts()) {
        apply_impact(impact, pt_data, meta);
    }
}

} // namespace navitia
<commit_msg>use create_discrete_vj<commit_after>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

LICENCE: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#include "apply_disruption.h"
#include "utils/logger.h"
#include "type/datetime.h"

#include <boost/make_shared.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <boost/range/algorithm/for_each.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/range/algorithm_ext/erase.hpp>
#include "boost/date_time/gregorian/gregorian.hpp"

namespace navitia {

namespace nt = navitia::type;
namespace bt = boost::posix_time;
namespace bg = boost::gregorian;

namespace {

struct apply_impacts_visitor : public boost::static_visitor<> {
    boost::shared_ptr<nt::disruption::Impact> impact;
    nt::PT_Data& pt_data;
    const nt::MetaData& meta;
    std::string action;
    nt::RTLevel rt_level; // level of the impacts
    log4cplus::Logger log = log4cplus::Logger::getInstance("log");

    apply_impacts_visitor(const boost::shared_ptr<nt::disruption::Impact>& impact,
            nt::PT_Data& pt_data, const nt::MetaData& meta, std::string action, nt::RTLevel l) :
        impact(impact), pt_data(pt_data), meta(meta), action(action), rt_level(l) {}

    virtual ~apply_impacts_visitor() {}
    apply_impacts_visitor(const apply_impacts_visitor&) = default;

    virtual void operator()(nt::MetaVehicleJourney*, nt::Route* = nullptr) = 0;

    void log_start_action(std::string uri) {
        LOG4CPLUS_TRACE(log, "Start to " << action << " impact " << impact.get()->uri << " on object " << uri);
    }

    void log_end_action(std::string uri) {
        LOG4CPLUS_TRACE(log, "Finished to " << action << " impact " << impact.get()->uri << " on object " << uri);
    }

    void operator()(nt::disruption::UnknownPtObj&) { }

    void operator()(nt::Network* network) {
        this->log_start_action(network->uri);
        for (auto line : network->line_list) {
            this->operator()(line);
        }
        this->log_end_action(network->uri);
    }

    void operator()(nt::disruption::LineSection& ls) {
        std::string uri = "line section (" +  ls.line->uri  + ")";
        this->log_start_action(uri);
        this->operator()(ls.line);
        this->log_end_action(uri);
    }

    void operator()(nt::Line* line) {
        this->log_start_action(line->uri);
        for(auto route : line->route_list) {
            this->operator()(route);
        }
        this->log_end_action(line->uri);
    }

    void operator()(nt::Route* route) {
        this->log_start_action(route->uri);

        // we cannot ensure that all VJ of a MetaVJ are on the same route,
        // and since we want all actions to operate on MetaVJ, we collect all MetaVJ of the route
        // (but we'll change only the route's vj)
        std::set<nt::MetaVehicleJourney*> mvjs;
        route->for_each_vehicle_journey([&mvjs](nt::VehicleJourney& vj) {
            mvjs.insert(vj.meta_vj); return true;
        });
        for (auto* mvj: mvjs) {
            this->operator()(mvj, route);
        }
        this->log_end_action(route->uri);
    }
};

static type::ValidityPattern compute_vp(const boost::posix_time::time_period& period,
        const boost::gregorian::date_period& production_period) {
        type::ValidityPattern vp; // bitset are all initialised to 0
        // we may impact vj's passed midnight
        bg::day_iterator titr(period.begin().date() - bg::days(1));
        for (; titr <= period.end().date(); ++titr) {
            if (! production_period.contains(*titr)) { continue; }
            auto day = (*titr - production_period.begin()).days();
            vp.add(day);
        }
        return vp;
}

struct add_impacts_visitor : public apply_impacts_visitor {
    add_impacts_visitor(const boost::shared_ptr<nt::disruption::Impact>& impact,
            nt::PT_Data& pt_data, const nt::MetaData& meta, nt::RTLevel l) :
        apply_impacts_visitor(impact, pt_data, meta, "add", l) {}

    ~add_impacts_visitor() {}
    add_impacts_visitor(const add_impacts_visitor&) = default;

    using apply_impacts_visitor::operator();

    void operator()(nt::MetaVehicleJourney* mvj, nt::Route* r = nullptr) {
        log_start_action(mvj->uri);
        if (impact->severity->effect == nt::disruption::Effect::NO_SERVICE) {
            LOG4CPLUS_TRACE(log, "canceling " << mvj->uri);
            mvj->cancel_vj(rt_level, impact->application_periods, pt_data, meta, r);
            mvj->impacted_by.push_back(impact);
        } else if (impact->severity->effect == nt::disruption::Effect::MODIFIED_SERVICE) {
            LOG4CPLUS_TRACE(log, "modifying " << mvj->uri);
            auto vp = compute_vp(impact->disruption->publication_period, meta.production_date);
            mvj->create_discrete_vj(mvj->uri,
                type::RTLevel::RealTime,
                vp,
                r,
                impact->aux_info.stop_times,
                pt_data);

        } else {
            LOG4CPLUS_DEBUG(log, "unhandled action on " << mvj->uri);
        }
        log_end_action(mvj->uri);
    }

    void operator()(nt::StopPoint* stop_point) {
        LOG4CPLUS_INFO(log, "Disruption on stop point:" << stop_point->uri << " is not handled");
    }

    void operator()(nt::StopArea* stop_area) {
        LOG4CPLUS_INFO(log, "Disruption on stop area:" << stop_area->uri << " is not handled");
    }
};

static bool is_modifying_effect(nt::disruption::Effect e) {
    // check is the effect needs to modify the model
    return in(e, {nt::disruption::Effect::NO_SERVICE,
                  nt::disruption::Effect::MODIFIED_SERVICE});
}

void apply_impact(boost::shared_ptr<nt::disruption::Impact>impact,
                         nt::PT_Data& pt_data, const nt::MetaData& meta) {
    if (! is_modifying_effect(impact->severity->effect)) {
        return;
    }
    LOG4CPLUS_TRACE(log4cplus::Logger::getInstance("log"),
                    "Adding impact: " << impact.get()->uri);
    add_impacts_visitor v(impact, pt_data, meta, impact->disruption->rt_level);
    boost::for_each(impact->informed_entities, boost::apply_visitor(v));
    LOG4CPLUS_TRACE(log4cplus::Logger::getInstance("log"),
                    impact.get()->uri << " impact added");
}

struct delete_impacts_visitor : public apply_impacts_visitor {
    size_t nb_vj_reassigned = 0;

    delete_impacts_visitor(boost::shared_ptr<nt::disruption::Impact> impact,
            nt::PT_Data& pt_data, const nt::MetaData& meta, nt::RTLevel l) :
        apply_impacts_visitor(impact, pt_data, meta, "delete", l) {}

    ~delete_impacts_visitor() {}

    using apply_impacts_visitor::operator();

    // We set all the validity pattern to the theorical one, we will re-apply
    // other disruptions after
    void operator()(nt::MetaVehicleJourney* mvj, nt::Route* r = nullptr) {
        if (impact->severity->effect == nt::disruption::Effect::NO_SERVICE) {
            for (auto* vj: mvj->get_vjs_in_period(rt_level, impact->application_periods, meta, r)) {
                vj->validity_patterns[rt_level] = vj->validity_patterns[nt::RTLevel::Base];
                ++ nb_vj_reassigned;
            }
        } else {
            LOG4CPLUS_DEBUG(log, "unhandled delete action on " << mvj->uri);
        }
        const auto& impact = this->impact;
        boost::range::remove_erase_if(mvj->impacted_by,
            [&impact](const boost::weak_ptr<nt::disruption::Impact>& i) {
                auto spt = i.lock();
                return (spt) ? spt == impact : true;
        });

        for (auto i: mvj->impacted_by) {
            if (auto spt = i.lock()) {
                auto v = add_impacts_visitor(spt, pt_data, meta, rt_level);
                v(mvj);
            }
        }
    }

    void operator()(const nt::StopPoint* stop_point) {
        LOG4CPLUS_INFO(log, "Deletion of disruption on stop point:" << stop_point->uri << " is not handled");

    }

    void operator()(const nt::StopArea* stop_area) {
        LOG4CPLUS_INFO(log, "Deletion of disruption on stop point:" << stop_area->uri << " is not handled");
    }
};

void delete_impact(boost::shared_ptr<nt::disruption::Impact>impact,
                          nt::PT_Data& pt_data, const nt::MetaData& meta) {
    if (! is_modifying_effect(impact->severity->effect)) {
        return;
    }
    auto log = log4cplus::Logger::getInstance("log");
    LOG4CPLUS_DEBUG(log, "Deleting impact: " << impact.get()->uri);
    delete_impacts_visitor v(impact, pt_data, meta, impact->disruption->rt_level);
    boost::for_each(impact->informed_entities, boost::apply_visitor(v));
    LOG4CPLUS_DEBUG(log, impact.get()->uri << " deleted");
}

} // anonymous namespace

void delete_disruption(const std::string& disruption_id,
                       nt::PT_Data& pt_data,
                       const nt::MetaData& meta) {
    auto log = log4cplus::Logger::getInstance("log");
    LOG4CPLUS_DEBUG(log, "Deleting disruption: " << disruption_id);
    nt::disruption::DisruptionHolder& holder = pt_data.disruption_holder;

    // the disruption is deleted by RAII
    std::unique_ptr<nt::disruption::Disruption> disruption = holder.pop_disruption(disruption_id);
    if (disruption) {
        std::vector<nt::disruption::PtObj> informed_entities;
        for (const auto& impact : disruption->get_impacts()) {
            informed_entities.insert(informed_entities.end(),
                              impact->informed_entities.begin(),
                              impact->informed_entities.end());
            delete_impact(impact, pt_data, meta);
        }
    }
    LOG4CPLUS_DEBUG(log, disruption_id << " disruption deleted");
}

void apply_disruption(const type::disruption::Disruption& disruption, nt::PT_Data& pt_data,
                    const navitia::type::MetaData &meta) {
    LOG4CPLUS_DEBUG(log4cplus::Logger::getInstance("log"), "applying disruption: " << disruption.uri);
    for (const auto& impact: disruption.get_impacts()) {
        apply_impact(impact, pt_data, meta);
    }
}

} // namespace navitia
<|endoftext|>


<commit_before>#define _USE_MATH_DEFINES

#include <Windows.h>
#include "Game.h"
#include <gl\GL.h>
#include <gl\glut.h>
#include "RGBAColor.h"
#include "SpriteLayer.h"
#include "WallPlayer.h"

#include <math.h>
#include <iostream>

Game::Game() :
    window(800, 600, "Foul Kicker"), level(0)
{
    Layer* background = new Layer();
    background->addImage("resources/img/stadium.ptm");
    background->setX(0);
    background->setY(0);

    Image* bgImg = background->getImage();

    this->scene = new Image(*bgImg);
    this->bgCopy = bgImg;
    this->layers.push_back(background);

    Layer* goalkeeper = new Layer();
    goalkeeper->addImage("resources/img/goalkeeper1.ptm");
    goalkeeper->setX(399);
    goalkeeper->setY(208);

    this->layers.push_back(goalkeeper);

    /*
     * TODO: Level layout initialization should be in
     * another place. Maybe on a file later.
     */
    level.addPlayerOnWall(Position(270, 150));
    loadLevel(level);

    Level l(1);
    l.addPlayerOnWall(Position(490, 150));
    levels.push_back(l);

    Level l2(2);
    l2.addPlayerOnWall(Position(270, 150));
    l2.addPlayerOnWall(Position(320, 150));
    levels.push_back(l2);

    Level l3(3);
    l3.addPlayerOnWall(Position(490, 150));
    l3.addPlayerOnWall(Position(440, 150));
    levels.push_back(l3);

    Level l4(4);
    l4.addPlayerOnWall(Position(270, 150));
    l4.addPlayerOnWall(Position(320, 150));
    l4.addPlayerOnWall(Position(370, 150));
    levels.push_back(l4);

    Level l5(5);
    l5.addPlayerOnWall(Position(490, 150));
    l5.addPlayerOnWall(Position(440, 150));
    l5.addPlayerOnWall(Position(390, 150));
    levels.push_back(l5);

    // set initial speed of the ball
    ball.setSpeedX(0);
    ball.setSpeedY(0);

    ballLayer.setSprite(ball.getCurrentSprite());
    ballLayer.setX(400);
    ballLayer.setY(0);

    this->goalkeeperDirection = 1;

    currentTime = 1;

    this->run();
}

Game::~Game()
{
    delete this->scene;
    delete this->bgCopy;

    // Properly clean the vector
    while (!this->layers.empty()) {
        delete this->layers.back();
        this->layers.pop_back();
    }
}

bool Game::checkForCollision() {

	bool collision = false;

	Layer* goalkeeper = this->layers.at(1);

	// GoalKeeper collision
	if ((ballLayer.getY() >= goalkeeper->getY() && ballLayer.getY() <= 224) &&
		(ballLayer.getX() >= goalkeeper->getX() && ballLayer.getX() <= goalkeeper->getX() + goalkeeper->getWidth())) {
		collision = true;
	}

	Layer wall = wallLayers.at(0);

	// WallLayer collision
	if (ballLayer.getY() == wall.getY() &&
		ballLayer.getX() >= wall.getX() &&
		ballLayer.getX() <= (wall.getX() + wall.getWidth() * (int)wallLayers.size())) {
		collision = true;
	}

	// GoalLine collision
	if (isBallOutOfPlay() && !hasCrossedGoalLine()) {
		collision = true;
	}

	// Sideline collision
	if (ballLayer.getX() > window.getWidth() || ballLayer.getX() < 0) {
		collision = true;
	}

	return collision;
}

int Game::animateBall(int time) {
    ballLayer.saveCurrentPosition();

	//ToDo:: Aplicar calculo de balistica
	if (currentAngleDirection > 0) {
		double v = ball.getSpeedY();
		double a = currentAngleDirection * M_PI / 180.0;
		double z = v * cos(a) * ++time;
		double temp = z / (v * cos(a));
		double w = z * tan(a) - 0.5 * 98 * (temp * temp);

		//ToDo:: Troca de Bola em Funcao do time por "v"
		if (ballLayer.getY() / 60 >= currentTime) {
			ball.nextBall();
			ballLayer.setSprite(ball.getCurrentSprite());
			currentTime++;
		}

		int posY = ballLayer.getY() + v;
		ballLayer.setX(400 + z);
		ballLayer.setY(posY);
	}

	//int t0 = 0,   // t = 0
 //       t1 = 150, // t = 0.666
 //       t2 = 208, // t = 0.924
 //       t3 = 225; // t = 1

	//int posX = ballLayer.getX() + ball.getSpeedX(),
	//	posY = ballLayer.getY() + ball.getSpeedY();

 //   float zTime = (time / (100 / 33)) * 0.1;
 //   if (currentTime <= 11 && zTime >= (float)currentTime/10) {
 //       if (currentTime == 2 || currentTime == 7 || currentTime == 10) {
 //           std::cout << "next ball\n";
 //           ball.nextBall();
 //           ballLayer.setSprite(ball.getCurrentSprite());

 //       }

 //       if (currentTime < 7) {
 //           posY = t1*zTime/0.666;
 //       } else if (currentTime < 10) {
 //           posY = t2*zTime/0.924;
 //       } else if (currentTime > 10) {
 //           posY = t3*zTime;
 //       }
 //       currentTime++;
 //   }

 //   ballLayer.setX(posX);
 //   ballLayer.setY(posY);

    Layer* goalkeeper = this->layers.at(1);

	/* Detectar gol
	 * Linha do Gol y@226
	 */
	if (checkForCollision()) {
		//Goal Defense
		prepare();
		std::cout << "Goal Defense" << "\n";
		time = 0;
	}

	if (isBallOutOfPlay() && hasCrossedGoalLine()) {
		//Goal
		prepare();
		std::cout << "Goal" << "\n";
		time = 0;
		nextLevel();
	}

	/*
     * Trave Esquerda x@286
     * Trave Direita x@490
     */

    if (goalkeeper->getX() >= 490) {
        goalkeeperDirection = -1;
    } else {
        if (goalkeeper->getX() <= 286) {
            goalkeeperDirection = 1;
        }
    }

    goalkeeper->saveCurrentPosition();

    int goalkeeperPos = goalkeeper->getX();
    goalkeeperPos += 5 * goalkeeperDirection;
    goalkeeper->setX(goalkeeperPos);

    this->run();

    return time;
}

void Game::run() {
    if (!this->scene) {
        this->scene = new Image(this->window.getWidth(), this->window.getHeight());
    }

    int length = this->layers.size();

    for (int i = 1; i < length; i++) {
        drawLayer(layers.at(i));
    }

    for (unsigned i = 0; i < wallLayers.size(); i++) {
        drawLayer(&wallLayers.at(i));
    }

    drawLayer(&ballLayer);

    // Draw ball
    ballLayer.draw(this->scene, ballLayer.getX(), ballLayer.getY());
}

void Game::drawLayer(Layer* layer) {
    Position* lastPos = layer->getLastPosition();

    /* TODO: Refactor it. This code probably should not be here.
     *
     * Redraw the part where the layer was located in the previous frame
     * so it deletes its trace.
     */
    if (lastPos) {
        int height = lastPos->getPosY() + lastPos->getHeight(),
            width = lastPos->getPosX() + lastPos->getWidth();

        for (int y = lastPos->getPosY(); y < height; y++) {
            if (y >= scene->getHeight()) break;
            if (y < 0) continue;

            for (int x = lastPos->getPosX(); x < width; x++) {
                if (x >= scene->getWidth()) break;
                if (x < 0) continue;

                unsigned pixel = this->bgCopy->getPixel(x, y);
                this->scene->setPixel(pixel, x, y);
            }
        }
    }

    layer->draw(this->scene, layer->getX(), layer->getY());
}

void Game::display(void) {

    glDrawPixels(scene->getWidth(), scene->getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, scene->getPixels());

    glFlush();
}

void Game::loadLevel(Level newLevel) {
    while (!wallLayers.empty()) {
        wallLayers.pop_back();
    }

    for (int a = 0; a < newLevel.getNumberOfPlayersOnWall(); a++) {
        Layer player;
        player.setImage(wallPlayer.getImage());

        const Position* position = level.getPlayerPosition(a);

        if (position) {
            player.setX(position->getPosX());
            player.setY(position->getPosY());
        }

        wallLayers.push_back(player);
    }
}

bool Game::isBallOutOfPlay() {
	return ballLayer.getY() > 225;
}

bool Game::hasCrossedGoalLine() {
	return ballLayer.getX() >= 280 && ballLayer.getX() <= 520;
}

void Game::prepare() {
	ballLayer.setX(400);
	ballLayer.setY(0);
	ball.setSpeedX(0);
	ball.setSpeedY(2.0);
	currentAngleDirection = 0;

    currentTime = 1;
    ball.setCurrentBall(0);
    ballLayer.setSprite(ball.getCurrentSprite());
}

void Game::kick(int x, int y) {
	std::cout << "Kick " << x << "\t" << y << "\n";

	int diffY = window.getHeight() - y;

	int initialX = ballLayer.getX();
	int finalX = initialX + ballLayer.getWidth();

	int initialY = ballLayer.getY();
	int finalY = initialY + ballLayer.getHeight();

	int axisX = finalX - x;
	int axisY = finalY - abs(diffY);

	if ((axisX >= 0 && axisX <= ballLayer.getWidth()) &&
		(axisY >= 0 && axisY <= ballLayer.getHeight())) {
		prepare();
		currentAngleDirection = abs(180 - axisX * 6);
		std::cout << axisX << "\t" << axisY << "\n";
	}
}

bool Game::nextLevel() {
    if (levels.size() > 0) {
        Level l = levels.front();
        levels.erase(levels.begin());
        level = l;
        std::cout << level.getLevel() << "\n";
        // draw background
        drawLayer(layers.at(0));
        loadLevel(l);
    } else {
        std::cout << "Out of levels\n";
        return false;
    }

    return true;
}

<commit_msg>Remove double ball rendering<commit_after>#define _USE_MATH_DEFINES

#include <Windows.h>
#include "Game.h"
#include <gl\GL.h>
#include <gl\glut.h>
#include "RGBAColor.h"
#include "SpriteLayer.h"
#include "WallPlayer.h"

#include <math.h>
#include <iostream>

Game::Game() :
    window(800, 600, "Foul Kicker"), level(0)
{
    Layer* background = new Layer();
    background->addImage("resources/img/stadium.ptm");
    background->setX(0);
    background->setY(0);

    Image* bgImg = background->getImage();

    this->scene = new Image(*bgImg);
    this->bgCopy = bgImg;
    this->layers.push_back(background);

    Layer* goalkeeper = new Layer();
    goalkeeper->addImage("resources/img/goalkeeper1.ptm");
    goalkeeper->setX(399);
    goalkeeper->setY(208);

    this->layers.push_back(goalkeeper);

    /*
     * TODO: Level layout initialization should be in
     * another place. Maybe on a file later.
     */
    level.addPlayerOnWall(Position(270, 150));
    loadLevel(level);

    Level l(1);
    l.addPlayerOnWall(Position(490, 150));
    levels.push_back(l);

    Level l2(2);
    l2.addPlayerOnWall(Position(270, 150));
    l2.addPlayerOnWall(Position(320, 150));
    levels.push_back(l2);

    Level l3(3);
    l3.addPlayerOnWall(Position(490, 150));
    l3.addPlayerOnWall(Position(440, 150));
    levels.push_back(l3);

    Level l4(4);
    l4.addPlayerOnWall(Position(270, 150));
    l4.addPlayerOnWall(Position(320, 150));
    l4.addPlayerOnWall(Position(370, 150));
    levels.push_back(l4);

    Level l5(5);
    l5.addPlayerOnWall(Position(490, 150));
    l5.addPlayerOnWall(Position(440, 150));
    l5.addPlayerOnWall(Position(390, 150));
    levels.push_back(l5);

    // set initial speed of the ball
    ball.setSpeedX(0);
    ball.setSpeedY(0);

    ballLayer.setSprite(ball.getCurrentSprite());
    ballLayer.setX(400);
    ballLayer.setY(0);

    this->goalkeeperDirection = 1;

    currentTime = 1;

    this->run();
}

Game::~Game()
{
    delete this->scene;
    delete this->bgCopy;

    // Properly clean the vector
    while (!this->layers.empty()) {
        delete this->layers.back();
        this->layers.pop_back();
    }
}

bool Game::checkForCollision() {

	bool collision = false;

	Layer* goalkeeper = this->layers.at(1);

	// GoalKeeper collision
	if ((ballLayer.getY() >= goalkeeper->getY() && ballLayer.getY() <= 224) &&
		(ballLayer.getX() >= goalkeeper->getX() && ballLayer.getX() <= goalkeeper->getX() + goalkeeper->getWidth())) {
		collision = true;
	}

	Layer wall = wallLayers.at(0);

	// WallLayer collision
	if (ballLayer.getY() == wall.getY() &&
		ballLayer.getX() >= wall.getX() &&
		ballLayer.getX() <= (wall.getX() + wall.getWidth() * (int)wallLayers.size())) {
		collision = true;
	}

	// GoalLine collision
	if (isBallOutOfPlay() && !hasCrossedGoalLine()) {
		collision = true;
	}

	// Sideline collision
	if (ballLayer.getX() > window.getWidth() || ballLayer.getX() < 0) {
		collision = true;
	}

	return collision;
}

int Game::animateBall(int time) {
    ballLayer.saveCurrentPosition();

	//ToDo:: Aplicar calculo de balistica
	if (currentAngleDirection > 0) {
		double v = ball.getSpeedY();
		double a = currentAngleDirection * M_PI / 180.0;
		double z = v * cos(a) * ++time;
		double temp = z / (v * cos(a));
		double w = z * tan(a) - 0.5 * 98 * (temp * temp);

		//ToDo:: Troca de Bola em Funcao do time por "v"
		if (ballLayer.getY() / 60 >= currentTime) {
			ball.nextBall();
			ballLayer.setSprite(ball.getCurrentSprite());
			currentTime++;
		}

		int posY = ballLayer.getY() + v;
		ballLayer.setX(400 + z);
		ballLayer.setY(posY);
	}

	//int t0 = 0,   // t = 0
 //       t1 = 150, // t = 0.666
 //       t2 = 208, // t = 0.924
 //       t3 = 225; // t = 1

	//int posX = ballLayer.getX() + ball.getSpeedX(),
	//	posY = ballLayer.getY() + ball.getSpeedY();

 //   float zTime = (time / (100 / 33)) * 0.1;
 //   if (currentTime <= 11 && zTime >= (float)currentTime/10) {
 //       if (currentTime == 2 || currentTime == 7 || currentTime == 10) {
 //           std::cout << "next ball\n";
 //           ball.nextBall();
 //           ballLayer.setSprite(ball.getCurrentSprite());

 //       }

 //       if (currentTime < 7) {
 //           posY = t1*zTime/0.666;
 //       } else if (currentTime < 10) {
 //           posY = t2*zTime/0.924;
 //       } else if (currentTime > 10) {
 //           posY = t3*zTime;
 //       }
 //       currentTime++;
 //   }

 //   ballLayer.setX(posX);
 //   ballLayer.setY(posY);

    Layer* goalkeeper = this->layers.at(1);

	/* Detectar gol
	 * Linha do Gol y@226
	 */
	if (checkForCollision()) {
		//Goal Defense
		prepare();
		std::cout << "Goal Defense" << "\n";
		time = 0;
	}

	if (isBallOutOfPlay() && hasCrossedGoalLine()) {
		//Goal
		prepare();
		std::cout << "Goal" << "\n";
		time = 0;
		nextLevel();
	}

	/*
     * Trave Esquerda x@286
     * Trave Direita x@490
     */

    if (goalkeeper->getX() >= 490) {
        goalkeeperDirection = -1;
    } else {
        if (goalkeeper->getX() <= 286) {
            goalkeeperDirection = 1;
        }
    }

    goalkeeper->saveCurrentPosition();

    int goalkeeperPos = goalkeeper->getX();
    goalkeeperPos += 5 * goalkeeperDirection;
    goalkeeper->setX(goalkeeperPos);

    this->run();

    return time;
}

void Game::run() {
    if (!this->scene) {
        this->scene = new Image(this->window.getWidth(), this->window.getHeight());
    }

    int length = this->layers.size();

    for (int i = 1; i < length; i++) {
        drawLayer(layers.at(i));
    }

    for (unsigned i = 0; i < wallLayers.size(); i++) {
        drawLayer(&wallLayers.at(i));
    }

    drawLayer(&ballLayer);
}

void Game::drawLayer(Layer* layer) {
    Position* lastPos = layer->getLastPosition();

    /* TODO: Refactor it. This code probably should not be here.
     *
     * Redraw the part where the layer was located in the previous frame
     * so it deletes its trace.
     */
    if (lastPos) {
        int height = lastPos->getPosY() + lastPos->getHeight(),
            width = lastPos->getPosX() + lastPos->getWidth();

        for (int y = lastPos->getPosY(); y < height; y++) {
            if (y >= scene->getHeight()) break;
            if (y < 0) continue;

            for (int x = lastPos->getPosX(); x < width; x++) {
                if (x >= scene->getWidth()) break;
                if (x < 0) continue;

                unsigned pixel = this->bgCopy->getPixel(x, y);
                this->scene->setPixel(pixel, x, y);
            }
        }
    }

    layer->draw(this->scene, layer->getX(), layer->getY());
}

void Game::display(void) {

    glDrawPixels(scene->getWidth(), scene->getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, scene->getPixels());

    glFlush();
}

void Game::loadLevel(Level newLevel) {
    while (!wallLayers.empty()) {
        wallLayers.pop_back();
    }

    for (int a = 0; a < newLevel.getNumberOfPlayersOnWall(); a++) {
        Layer player;
        player.setImage(wallPlayer.getImage());

        const Position* position = level.getPlayerPosition(a);

        if (position) {
            player.setX(position->getPosX());
            player.setY(position->getPosY());
        }

        wallLayers.push_back(player);
    }
}

bool Game::isBallOutOfPlay() {
	return ballLayer.getY() > 225;
}

bool Game::hasCrossedGoalLine() {
	return ballLayer.getX() >= 280 && ballLayer.getX() <= 520;
}

void Game::prepare() {
	ballLayer.setX(400);
	ballLayer.setY(0);
	ball.setSpeedX(0);
	ball.setSpeedY(2.0);
	currentAngleDirection = 0;

    currentTime = 1;
    ball.setCurrentBall(0);
    ballLayer.setSprite(ball.getCurrentSprite());
}

void Game::kick(int x, int y) {
	std::cout << "Kick " << x << "\t" << y << "\n";

	int diffY = window.getHeight() - y;

	int initialX = ballLayer.getX();
	int finalX = initialX + ballLayer.getWidth();

	int initialY = ballLayer.getY();
	int finalY = initialY + ballLayer.getHeight();

	int axisX = finalX - x;
	int axisY = finalY - abs(diffY);

	if ((axisX >= 0 && axisX <= ballLayer.getWidth()) &&
		(axisY >= 0 && axisY <= ballLayer.getHeight())) {
		prepare();
		currentAngleDirection = abs(180 - axisX * 6);
		std::cout << axisX << "\t" << axisY << "\n";
	}
}

bool Game::nextLevel() {
    if (levels.size() > 0) {
        Level l = levels.front();
        levels.erase(levels.begin());
        level = l;
        std::cout << level.getLevel() << "\n";
        // draw background
        drawLayer(layers.at(0));
        loadLevel(l);
    } else {
        std::cout << "Out of levels\n";
        return false;
    }

    return true;
}

<|endoftext|>


<commit_before>//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file contains the implementation of the UnwrappedLineParser,
/// which turns a stream of tokens into UnwrappedLines.
///
/// This is EXPERIMENTAL code under heavy development. It is not in a state yet,
/// where it can be used to format real code.
///
//===----------------------------------------------------------------------===//

#include "UnwrappedLineParser.h"
#include "llvm/Support/raw_ostream.h"

namespace clang {
namespace format {

class ScopedMacroState : public FormatTokenSource {
public:
  ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
                   FormatToken &ResetToken)
      : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
        PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
    TokenSource = this;
    // FIXME: Back up all other state (errors, line indent, etc) and reset after
    // parsing the macro.
    Line.Level = 0;
    Line.InPPDirective = true;
  }

  ~ScopedMacroState() {
    TokenSource = PreviousTokenSource;
    ResetToken = Token;
    Line.InPPDirective = false;
    Line.Level = PreviousLineLevel;
  }

  virtual FormatToken getNextToken() {
    // FIXME: Write test that breaks due to a missing
    // if (eof()) return createEOF();
    Token = PreviousTokenSource->getNextToken();
    if (eof())
      return createEOF();
    return Token;
  }

private:
  bool eof() {
    return Token.NewlinesBefore > 0 && Token.HasUnescapedNewline;
  }

  FormatToken createEOF() {
    FormatToken FormatTok;
    FormatTok.Tok.startToken();
    FormatTok.Tok.setKind(tok::eof);
    return FormatTok;
  }

  UnwrappedLine &Line;
  FormatTokenSource *&TokenSource;
  FormatToken &ResetToken;
  unsigned PreviousLineLevel;
  FormatTokenSource *PreviousTokenSource;

  FormatToken Token;
};

UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
                                         FormatTokenSource &Tokens,
                                         UnwrappedLineConsumer &Callback)
    : Style(Style), Tokens(&Tokens), Callback(Callback) {
}

bool UnwrappedLineParser::parse() {
  readToken();
  return parseFile();
}

bool UnwrappedLineParser::parseFile() {
  bool Error = parseLevel(/*HasOpeningBrace=*/false);
  // Make sure to format the remaining tokens.
  addUnwrappedLine();
  return Error;
}

bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
  bool Error = false;
  do {
    switch (FormatTok.Tok.getKind()) {
    case tok::comment:
      nextToken();
      addUnwrappedLine();
      break;
    case tok::l_brace:
      Error |= parseBlock();
      addUnwrappedLine();
      break;
    case tok::r_brace:
      if (HasOpeningBrace) {
        return false;
      } else {
        // Stray '}' is an error.
        Error = true;
        nextToken();
        addUnwrappedLine();
      }
      break;
    default:
      parseStatement();
      break;
    }
  } while (!eof());
  return Error;
}

bool UnwrappedLineParser::parseBlock(unsigned AddLevels) {
  assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
  nextToken();

  addUnwrappedLine();

  Line.Level += AddLevels;
  parseLevel(/*HasOpeningBrace=*/true);
  Line.Level -= AddLevels;

  // FIXME: Add error handling.
  if (!FormatTok.Tok.is(tok::r_brace))
    return true;

  nextToken();
  if (FormatTok.Tok.is(tok::semi))
    nextToken();
  return false;
}

void UnwrappedLineParser::parsePPDirective() {
  assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
  ScopedMacroState MacroState(Line, Tokens, FormatTok);
  nextToken();

  if (FormatTok.Tok.getIdentifierInfo() == NULL) {
    addUnwrappedLine();
    return;
  }

  switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
  case tok::pp_define:
    parsePPDefine();
    break;
  default:
    parsePPUnknown();
    break;
  }
}

void UnwrappedLineParser::parsePPDefine() {
  nextToken();

  if (FormatTok.Tok.getKind() != tok::identifier) {
    parsePPUnknown();
    return;
  }
  nextToken();
  if (FormatTok.Tok.getKind() == tok::l_paren) {
    parseParens();
  }
  addUnwrappedLine();
  Line.Level = 1;
  parseFile();
}

void UnwrappedLineParser::parsePPUnknown() {
  do {
    nextToken();
  } while (!eof());
  addUnwrappedLine();
}

void UnwrappedLineParser::parseComments() {
  // Consume leading line comments, e.g. for branches without compounds.
  while (FormatTok.Tok.is(tok::comment)) {
    nextToken();
    addUnwrappedLine();
  }
}

void UnwrappedLineParser::parseStatement() {
  parseComments();

  int TokenNumber = 0;
  switch (FormatTok.Tok.getKind()) {
  case tok::kw_namespace:
    parseNamespace();
    return;
  case tok::kw_inline:
    nextToken();
    TokenNumber++;
    if (FormatTok.Tok.is(tok::kw_namespace)) {
      parseNamespace();
      return;
    }
    break;
  case tok::kw_public:
  case tok::kw_protected:
  case tok::kw_private:
    parseAccessSpecifier();
    return;
  case tok::kw_if:
    parseIfThenElse();
    return;
  case tok::kw_for:
  case tok::kw_while:
    parseForOrWhileLoop();
    return;
  case tok::kw_do:
    parseDoWhile();
    return;
  case tok::kw_switch:
    parseSwitch();
    return;
  case tok::kw_default:
    nextToken();
    parseLabel();
    return;
  case tok::kw_case:
    parseCaseLabel();
    return;
  default:
    break;
  }
  do {
    ++TokenNumber;
    switch (FormatTok.Tok.getKind()) {
    case tok::kw_enum:
      parseEnum();
      return;
    case tok::semi:
      nextToken();
      addUnwrappedLine();
      return;
    case tok::l_paren:
      parseParens();
      break;
    case tok::l_brace:
      parseBlock();
      addUnwrappedLine();
      return;
    case tok::identifier:
      nextToken();
      if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
        parseLabel();
        return;
      }
      break;
    case tok::equal:
      nextToken();
      // Skip initializers as they will be formatted by a later step.
      if (FormatTok.Tok.is(tok::l_brace))
        nextToken();
      break;
    default:
      nextToken();
      break;
    }
  } while (!eof());
}

void UnwrappedLineParser::parseParens() {
  assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
  nextToken();
  do {
    switch (FormatTok.Tok.getKind()) {
    case tok::l_paren:
      parseParens();
      break;
    case tok::r_paren:
      nextToken();
      return;
    default:
      nextToken();
      break;
    }
  } while (!eof());
}

void UnwrappedLineParser::parseIfThenElse() {
  assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
  nextToken();
  parseParens();
  bool NeedsUnwrappedLine = false;
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
    NeedsUnwrappedLine = true;
  } else {
    addUnwrappedLine();
    ++Line.Level;
    parseStatement();
    --Line.Level;
  }
  if (FormatTok.Tok.is(tok::kw_else)) {
    nextToken();
    if (FormatTok.Tok.is(tok::l_brace)) {
      parseBlock();
      addUnwrappedLine();
    } else if (FormatTok.Tok.is(tok::kw_if)) {
      parseIfThenElse();
    } else {
      addUnwrappedLine();
      ++Line.Level;
      parseStatement();
      --Line.Level;
    }
  } else if (NeedsUnwrappedLine) {
    addUnwrappedLine();
  }
}

void UnwrappedLineParser::parseNamespace() {
  assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
  nextToken();
  if (FormatTok.Tok.is(tok::identifier))
    nextToken();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock(0);
    addUnwrappedLine();
  }
  // FIXME: Add error handling.
}

void UnwrappedLineParser::parseForOrWhileLoop() {
  assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
         "'for' or 'while' expected");
  nextToken();
  parseParens();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
    addUnwrappedLine();
  } else {
    addUnwrappedLine();
    ++Line.Level;
    parseStatement();
    --Line.Level;
  }
}

void UnwrappedLineParser::parseDoWhile() {
  assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
  nextToken();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
  } else {
    addUnwrappedLine();
    ++Line.Level;
    parseStatement();
    --Line.Level;
  }

  // FIXME: Add error handling.
  if (!FormatTok.Tok.is(tok::kw_while)) {
    addUnwrappedLine();
    return;
  }

  nextToken();
  parseStatement();
}

void UnwrappedLineParser::parseLabel() {
  // FIXME: remove all asserts.
  assert(FormatTok.Tok.is(tok::colon) && "':' expected");
  nextToken();
  unsigned OldLineLevel = Line.Level;
  if (Line.Level > 0)
    --Line.Level;
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
  }
  addUnwrappedLine();
  Line.Level = OldLineLevel;
}

void UnwrappedLineParser::parseCaseLabel() {
  assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
  // FIXME: fix handling of complex expressions here.
  do {
    nextToken();
  } while (!eof() && !FormatTok.Tok.is(tok::colon));
  parseLabel();
}

void UnwrappedLineParser::parseSwitch() {
  assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
  nextToken();
  parseParens();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock(Style.IndentCaseLabels ? 2 : 1);
    addUnwrappedLine();
  } else {
    addUnwrappedLine();
    Line.Level += (Style.IndentCaseLabels ? 2 : 1);
    parseStatement();
    Line.Level -= (Style.IndentCaseLabels ? 2 : 1);
  }
}

void UnwrappedLineParser::parseAccessSpecifier() {
  nextToken();
  // Otherwise, we don't know what it is, and we'd better keep the next token.
  if (FormatTok.Tok.is(tok::colon))
    nextToken();
  addUnwrappedLine();
}

void UnwrappedLineParser::parseEnum() {
  bool HasContents = false;
  do {
    switch (FormatTok.Tok.getKind()) {
    case tok::l_brace:
      nextToken();
      addUnwrappedLine();
      ++Line.Level;
      parseComments();
      break;
    case tok::l_paren:
      parseParens();
      break;
    case tok::comma:
      nextToken();
      addUnwrappedLine();
      parseComments();
      break;
    case tok::r_brace:
      if (HasContents)
        addUnwrappedLine();
      --Line.Level;
      nextToken();
      break;
    case tok::semi:
      nextToken();
      addUnwrappedLine();
      return;
    default:
      HasContents = true;
      nextToken();
      break;
    }
  } while (!eof());
}

void UnwrappedLineParser::addUnwrappedLine() {
  // Consume trailing comments.
  while (!eof() && FormatTok.NewlinesBefore == 0 &&
         FormatTok.Tok.is(tok::comment)) {
    nextToken();
  }
  Callback.consumeUnwrappedLine(Line);
  Line.Tokens.clear();
}

bool UnwrappedLineParser::eof() const {
  return FormatTok.Tok.is(tok::eof);
}

void UnwrappedLineParser::nextToken() {
  if (eof())
    return;
  Line.Tokens.push_back(FormatTok);
  readToken();
}

void UnwrappedLineParser::readToken() {
  FormatTok = Tokens->getNextToken();
  while (!Line.InPPDirective && FormatTok.Tok.is(tok::hash) &&
         ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
          FormatTok.IsFirst)) {
    // FIXME: This is incorrect - the correct way is to create a
    // data structure that will construct the parts around the preprocessor
    // directive as a structured \c UnwrappedLine.
    addUnwrappedLine();
    parsePPDirective();
  }
}

}  // end namespace format
}  // end namespace clang
<commit_msg>Remove outdated FIXME and add explanation for error handling strategy while parsing #define's.<commit_after>//===--- UnwrappedLineParser.cpp - Format C++ code ------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file contains the implementation of the UnwrappedLineParser,
/// which turns a stream of tokens into UnwrappedLines.
///
/// This is EXPERIMENTAL code under heavy development. It is not in a state yet,
/// where it can be used to format real code.
///
//===----------------------------------------------------------------------===//

#include "UnwrappedLineParser.h"
#include "llvm/Support/raw_ostream.h"

namespace clang {
namespace format {

class ScopedMacroState : public FormatTokenSource {
public:
  ScopedMacroState(UnwrappedLine &Line, FormatTokenSource *&TokenSource,
                   FormatToken &ResetToken)
      : Line(Line), TokenSource(TokenSource), ResetToken(ResetToken),
        PreviousLineLevel(Line.Level), PreviousTokenSource(TokenSource) {
    TokenSource = this;
    Line.Level = 0;
    Line.InPPDirective = true;
  }

  ~ScopedMacroState() {
    TokenSource = PreviousTokenSource;
    ResetToken = Token;
    Line.InPPDirective = false;
    Line.Level = PreviousLineLevel;
  }

  virtual FormatToken getNextToken() {
    // FIXME: Write test that breaks due to a missing
    // if (eof()) return createEOF();
    Token = PreviousTokenSource->getNextToken();
    if (eof())
      return createEOF();
    return Token;
  }

private:
  bool eof() {
    return Token.NewlinesBefore > 0 && Token.HasUnescapedNewline;
  }

  FormatToken createEOF() {
    FormatToken FormatTok;
    FormatTok.Tok.startToken();
    FormatTok.Tok.setKind(tok::eof);
    return FormatTok;
  }

  UnwrappedLine &Line;
  FormatTokenSource *&TokenSource;
  FormatToken &ResetToken;
  unsigned PreviousLineLevel;
  FormatTokenSource *PreviousTokenSource;

  FormatToken Token;
};

UnwrappedLineParser::UnwrappedLineParser(const FormatStyle &Style,
                                         FormatTokenSource &Tokens,
                                         UnwrappedLineConsumer &Callback)
    : Style(Style), Tokens(&Tokens), Callback(Callback) {
}

bool UnwrappedLineParser::parse() {
  readToken();
  return parseFile();
}

bool UnwrappedLineParser::parseFile() {
  bool Error = parseLevel(/*HasOpeningBrace=*/false);
  // Make sure to format the remaining tokens.
  addUnwrappedLine();
  return Error;
}

bool UnwrappedLineParser::parseLevel(bool HasOpeningBrace) {
  bool Error = false;
  do {
    switch (FormatTok.Tok.getKind()) {
    case tok::comment:
      nextToken();
      addUnwrappedLine();
      break;
    case tok::l_brace:
      Error |= parseBlock();
      addUnwrappedLine();
      break;
    case tok::r_brace:
      if (HasOpeningBrace) {
        return false;
      } else {
        // Stray '}' is an error.
        Error = true;
        nextToken();
        addUnwrappedLine();
      }
      break;
    default:
      parseStatement();
      break;
    }
  } while (!eof());
  return Error;
}

bool UnwrappedLineParser::parseBlock(unsigned AddLevels) {
  assert(FormatTok.Tok.is(tok::l_brace) && "'{' expected");
  nextToken();

  addUnwrappedLine();

  Line.Level += AddLevels;
  parseLevel(/*HasOpeningBrace=*/true);
  Line.Level -= AddLevels;

  // FIXME: Add error handling.
  if (!FormatTok.Tok.is(tok::r_brace))
    return true;

  nextToken();
  if (FormatTok.Tok.is(tok::semi))
    nextToken();
  return false;
}

void UnwrappedLineParser::parsePPDirective() {
  assert(FormatTok.Tok.is(tok::hash) && "'#' expected");
  ScopedMacroState MacroState(Line, Tokens, FormatTok);
  nextToken();

  if (FormatTok.Tok.getIdentifierInfo() == NULL) {
    addUnwrappedLine();
    return;
  }

  switch (FormatTok.Tok.getIdentifierInfo()->getPPKeywordID()) {
  case tok::pp_define:
    parsePPDefine();
    break;
  default:
    parsePPUnknown();
    break;
  }
}

void UnwrappedLineParser::parsePPDefine() {
  nextToken();

  if (FormatTok.Tok.getKind() != tok::identifier) {
    parsePPUnknown();
    return;
  }
  nextToken();
  if (FormatTok.Tok.getKind() == tok::l_paren) {
    parseParens();
  }
  addUnwrappedLine();
  Line.Level = 1;

  // Errors during a preprocessor directive can only affect the layout of the
  // preprocessor directive, and thus we ignore them. An alternative approach
  // would be to use the same approach we use on the file level (no
  // re-indentation if there was a structural error) within the macro
  // definition.
  parseFile();
}

void UnwrappedLineParser::parsePPUnknown() {
  do {
    nextToken();
  } while (!eof());
  addUnwrappedLine();
}

void UnwrappedLineParser::parseComments() {
  // Consume leading line comments, e.g. for branches without compounds.
  while (FormatTok.Tok.is(tok::comment)) {
    nextToken();
    addUnwrappedLine();
  }
}

void UnwrappedLineParser::parseStatement() {
  parseComments();

  int TokenNumber = 0;
  switch (FormatTok.Tok.getKind()) {
  case tok::kw_namespace:
    parseNamespace();
    return;
  case tok::kw_inline:
    nextToken();
    TokenNumber++;
    if (FormatTok.Tok.is(tok::kw_namespace)) {
      parseNamespace();
      return;
    }
    break;
  case tok::kw_public:
  case tok::kw_protected:
  case tok::kw_private:
    parseAccessSpecifier();
    return;
  case tok::kw_if:
    parseIfThenElse();
    return;
  case tok::kw_for:
  case tok::kw_while:
    parseForOrWhileLoop();
    return;
  case tok::kw_do:
    parseDoWhile();
    return;
  case tok::kw_switch:
    parseSwitch();
    return;
  case tok::kw_default:
    nextToken();
    parseLabel();
    return;
  case tok::kw_case:
    parseCaseLabel();
    return;
  default:
    break;
  }
  do {
    ++TokenNumber;
    switch (FormatTok.Tok.getKind()) {
    case tok::kw_enum:
      parseEnum();
      return;
    case tok::semi:
      nextToken();
      addUnwrappedLine();
      return;
    case tok::l_paren:
      parseParens();
      break;
    case tok::l_brace:
      parseBlock();
      addUnwrappedLine();
      return;
    case tok::identifier:
      nextToken();
      if (TokenNumber == 1 && FormatTok.Tok.is(tok::colon)) {
        parseLabel();
        return;
      }
      break;
    case tok::equal:
      nextToken();
      // Skip initializers as they will be formatted by a later step.
      if (FormatTok.Tok.is(tok::l_brace))
        nextToken();
      break;
    default:
      nextToken();
      break;
    }
  } while (!eof());
}

void UnwrappedLineParser::parseParens() {
  assert(FormatTok.Tok.is(tok::l_paren) && "'(' expected.");
  nextToken();
  do {
    switch (FormatTok.Tok.getKind()) {
    case tok::l_paren:
      parseParens();
      break;
    case tok::r_paren:
      nextToken();
      return;
    default:
      nextToken();
      break;
    }
  } while (!eof());
}

void UnwrappedLineParser::parseIfThenElse() {
  assert(FormatTok.Tok.is(tok::kw_if) && "'if' expected");
  nextToken();
  parseParens();
  bool NeedsUnwrappedLine = false;
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
    NeedsUnwrappedLine = true;
  } else {
    addUnwrappedLine();
    ++Line.Level;
    parseStatement();
    --Line.Level;
  }
  if (FormatTok.Tok.is(tok::kw_else)) {
    nextToken();
    if (FormatTok.Tok.is(tok::l_brace)) {
      parseBlock();
      addUnwrappedLine();
    } else if (FormatTok.Tok.is(tok::kw_if)) {
      parseIfThenElse();
    } else {
      addUnwrappedLine();
      ++Line.Level;
      parseStatement();
      --Line.Level;
    }
  } else if (NeedsUnwrappedLine) {
    addUnwrappedLine();
  }
}

void UnwrappedLineParser::parseNamespace() {
  assert(FormatTok.Tok.is(tok::kw_namespace) && "'namespace' expected");
  nextToken();
  if (FormatTok.Tok.is(tok::identifier))
    nextToken();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock(0);
    addUnwrappedLine();
  }
  // FIXME: Add error handling.
}

void UnwrappedLineParser::parseForOrWhileLoop() {
  assert((FormatTok.Tok.is(tok::kw_for) || FormatTok.Tok.is(tok::kw_while)) &&
         "'for' or 'while' expected");
  nextToken();
  parseParens();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
    addUnwrappedLine();
  } else {
    addUnwrappedLine();
    ++Line.Level;
    parseStatement();
    --Line.Level;
  }
}

void UnwrappedLineParser::parseDoWhile() {
  assert(FormatTok.Tok.is(tok::kw_do) && "'do' expected");
  nextToken();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
  } else {
    addUnwrappedLine();
    ++Line.Level;
    parseStatement();
    --Line.Level;
  }

  // FIXME: Add error handling.
  if (!FormatTok.Tok.is(tok::kw_while)) {
    addUnwrappedLine();
    return;
  }

  nextToken();
  parseStatement();
}

void UnwrappedLineParser::parseLabel() {
  // FIXME: remove all asserts.
  assert(FormatTok.Tok.is(tok::colon) && "':' expected");
  nextToken();
  unsigned OldLineLevel = Line.Level;
  if (Line.Level > 0)
    --Line.Level;
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock();
  }
  addUnwrappedLine();
  Line.Level = OldLineLevel;
}

void UnwrappedLineParser::parseCaseLabel() {
  assert(FormatTok.Tok.is(tok::kw_case) && "'case' expected");
  // FIXME: fix handling of complex expressions here.
  do {
    nextToken();
  } while (!eof() && !FormatTok.Tok.is(tok::colon));
  parseLabel();
}

void UnwrappedLineParser::parseSwitch() {
  assert(FormatTok.Tok.is(tok::kw_switch) && "'switch' expected");
  nextToken();
  parseParens();
  if (FormatTok.Tok.is(tok::l_brace)) {
    parseBlock(Style.IndentCaseLabels ? 2 : 1);
    addUnwrappedLine();
  } else {
    addUnwrappedLine();
    Line.Level += (Style.IndentCaseLabels ? 2 : 1);
    parseStatement();
    Line.Level -= (Style.IndentCaseLabels ? 2 : 1);
  }
}

void UnwrappedLineParser::parseAccessSpecifier() {
  nextToken();
  // Otherwise, we don't know what it is, and we'd better keep the next token.
  if (FormatTok.Tok.is(tok::colon))
    nextToken();
  addUnwrappedLine();
}

void UnwrappedLineParser::parseEnum() {
  bool HasContents = false;
  do {
    switch (FormatTok.Tok.getKind()) {
    case tok::l_brace:
      nextToken();
      addUnwrappedLine();
      ++Line.Level;
      parseComments();
      break;
    case tok::l_paren:
      parseParens();
      break;
    case tok::comma:
      nextToken();
      addUnwrappedLine();
      parseComments();
      break;
    case tok::r_brace:
      if (HasContents)
        addUnwrappedLine();
      --Line.Level;
      nextToken();
      break;
    case tok::semi:
      nextToken();
      addUnwrappedLine();
      return;
    default:
      HasContents = true;
      nextToken();
      break;
    }
  } while (!eof());
}

void UnwrappedLineParser::addUnwrappedLine() {
  // Consume trailing comments.
  while (!eof() && FormatTok.NewlinesBefore == 0 &&
         FormatTok.Tok.is(tok::comment)) {
    nextToken();
  }
  Callback.consumeUnwrappedLine(Line);
  Line.Tokens.clear();
}

bool UnwrappedLineParser::eof() const {
  return FormatTok.Tok.is(tok::eof);
}

void UnwrappedLineParser::nextToken() {
  if (eof())
    return;
  Line.Tokens.push_back(FormatTok);
  readToken();
}

void UnwrappedLineParser::readToken() {
  FormatTok = Tokens->getNextToken();
  while (!Line.InPPDirective && FormatTok.Tok.is(tok::hash) &&
         ((FormatTok.NewlinesBefore > 0 && FormatTok.HasUnescapedNewline) ||
          FormatTok.IsFirst)) {
    // FIXME: This is incorrect - the correct way is to create a
    // data structure that will construct the parts around the preprocessor
    // directive as a structured \c UnwrappedLine.
    addUnwrappedLine();
    parsePPDirective();
  }
}

}  // end namespace format
}  // end namespace clang
<|endoftext|>


<commit_before>/*ckwg +5
 * Copyright 2011-2012 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "homography.h"

#include "plane_ref.h"
#include "timestamp.h"
#include "utm.h"

/**
 * \file homography.cxx
 *
 * \brief Implementation of the homography classes.
 */

namespace vistk
{

homography_base
::homography_base(homography_base const& h)
  : m_transform(h.m_transform)
  , m_valid(h.m_valid)
  , m_new_reference(h.m_new_reference)
{
}

homography_base
::~homography_base()
{
}

homography_base::transform_t const&
homography_base
::transform() const
{
  return m_transform;
}

bool
homography_base
::is_valid() const
{
  return m_valid;
}

bool
homography_base
::is_new_reference() const
{
  return m_new_reference;
}

void
homography_base
::set_transform(transform_t const& trans)
{
  m_transform = trans;
}

void
homography_base
::set_identity()
{
  m_transform.set_identity();
}

void
homography_base
::set_valid(bool valid)
{
  m_valid = valid;
}

void
homography_base
::set_new_reference(bool new_reference)
{
  m_new_reference = new_reference;
}

bool
homography_base
::operator == (homography_base const& h) const
{
  return ((m_valid == h.m_valid) &&
          (m_new_reference == h.m_new_reference) &&
          (m_transform == h.m_transform));
}

homography_base
::homography_base()
  : m_valid(false)
  , m_new_reference(false)
{
  set_identity();
}

template <typename Source, typename Dest>
homography<Source, Dest>
::homography()
{
}

template <typename Source, typename Dest>
homography<Source, Dest>
::homography(self_t const& h)
  : homography_base(h)
  , m_source(h.m_source)
  , m_dest(h.m_dest)
{
}

template <typename Source, typename Dest>
homography<Source, Dest>
::~homography()
{
}

template <typename Source, typename Dest>
typename homography<Source, Dest>::source_t
homography<Source, Dest>
::source() const
{
  return m_source;
}

template <typename Source, typename Dest>
typename homography<Source, Dest>::dest_t
homography<Source, Dest>
::destination() const
{
  return m_dest;
}

template <typename Source, typename Dest>
void
homography<Source, Dest>
::set_source(source_t const& src)
{
  m_source = src;
}

template <typename Source, typename Dest>
void
homography<Source, Dest>
::set_destination(dest_t const& dest)
{
  m_dest = dest;
}

template <typename Source, typename Dest>
typename homography<Source, Dest>::inverse_t
homography<Source, Dest>
::inverse() const
{
  inverse_t result;

  result.set_transform(transform().get_inverse());
  result.set_source(m_dest);
  result.set_destination(m_source);
  result.set_valid(is_valid());
  result.set_new_reference(is_new_reference());

  return result;
}

template <typename Source, typename Dest>
bool
homography<Source, Dest>
::operator == (self_t const& h) const
{
  return ((homography_base::operator == (h)) &&
          (m_source == h.m_source) &&
          (m_dest == h.m_dest));
}

}

// Keep in sync with homography_types.h
template class vistk::homography<vistk::timestamp, vistk::timestamp>;
template class vistk::homography<vistk::timestamp, vistk::plane_ref_t>;
template class vistk::homography<vistk::plane_ref_t, vistk::timestamp>;
template class vistk::homography<vistk::timestamp, vistk::utm_zone_t>;
template class vistk::homography<vistk::utm_zone_t, vistk::timestamp>;
template class vistk::homography<vistk::plane_ref_t, vistk::utm_zone_t>;
template class vistk::homography<vistk::utm_zone_t, vistk::plane_ref_t>;

template <typename Source, typename Shared, typename Dest>
vistk::homography<Source, Dest>
vistk::operator * (vistk::homography<Shared, Dest> const& l, vistk::homography<Source, Shared> const& r)
{
  vistk::homography<Source, Dest> result;

  result.set_transform(l.transform() * r.transform());
  result.set_source(r.source());
  result.set_destination(l.dest());
  result.set_valid(l.is_valid() && r.is_valid());

  return result;
}

#ifndef DOXYGEN_IGNORE

/**
 * \def INSTANTIATE_MULT_RAW
 *
 * \brief Instantiates multiplication with three distinct types.
 *
 * \param X The source type in the multiplication.
 * \param Y The shared type in the multiplication.
 * \param Z The destination type in the multiplication.
 */
#define INSTANTIATE_MULT_RAW(X, Y, Z) \
  template <> homography<X, Z> operator * <X, Y, Z>(homography<Y, Z> const&, homography<X, Y> const&)

/**
 * \def INSTANTIATE_SELF_MULT
 *
 * \brief Instantiates multiplication with homogeneous types.
 *
 * \param X The reference plane for the multiplication.
 */
#define INSTANTIATE_SELF_MULT(X) \
  INSTANTIATE_MULT_RAW(X, X, X)

/**
 * \def INSTANTIATE_DUAL_MULT_RAW
 *
 * \brief Instantiates multiplication with two distinct types.
 *
 * \param X The first type in the multiplication.
 * \param Y The second type in the multiplication.
 */
#define INSTANTIATE_DUAL_MULT_RAW(X, Y) \
  INSTANTIATE_MULT_RAW(X, Y, X);        \
  INSTANTIATE_MULT_RAW(X, X, Y);        \
  INSTANTIATE_MULT_RAW(X, Y, Y)

/**
 * \def INSTANTIATE_DUAL_MULT
 *
 * \brief Instantiates multiplication with two distinct types.
 *
 * This instantiates all permutations between the two types.
 *
 * \param X The first type in the multiplication.
 * \param Y The second type in the multiplication.
 */
#define INSTANTIATE_DUAL_MULT(X, Y) \
  INSTANTIATE_DUAL_MULT_RAW(X, Y);  \
  INSTANTIATE_DUAL_MULT_RAW(Y, X)

/**
 * \def INSTANTIATE_TRIP_MULT
 *
 * \brief Instantiates multiplication with three distinct types.
 *
 * This instantiates all permutations between the three types.
 *
 * \param X The first type in the multiplication.
 * \param Y The second type in the multiplication.
 * \param Z The third type in the multiplication.
 */
#define INSTANTIATE_TRIP_MULT(X,Y,Z)  \
  INSTANTIATE_MULT_RAW(X, Y, Z);      \
  INSTANTIATE_MULT_RAW(X, Z, Y);      \
  INSTANTIATE_MULT_RAW(Y, X, Z);      \
  INSTANTIATE_MULT_RAW(Y, Z, X);      \
  INSTANTIATE_MULT_RAW(Z, X, Y);      \
  INSTANTIATE_MULT_RAW(Z, Y, X)

namespace vistk
{

// Instantiate all allowable types
INSTANTIATE_SELF_MULT(vistk::timestamp);
INSTANTIATE_SELF_MULT(vistk::plane_ref_t);
INSTANTIATE_SELF_MULT(vistk::utm_zone_t);

INSTANTIATE_DUAL_MULT(vistk::timestamp,   vistk::plane_ref_t);
INSTANTIATE_DUAL_MULT(vistk::timestamp,   vistk::utm_zone_t);
INSTANTIATE_DUAL_MULT(vistk::plane_ref_t, vistk::utm_zone_t);

INSTANTIATE_TRIP_MULT(vistk::timestamp,   vistk::plane_ref_t, vistk::utm_zone_t);

}

#undef INSTANTIATE_MULT_RAW
#undef INSTANTIATE_SELF_MULT
#undef INSTANTIATE_DUAL_MULT_RAW
#undef INSTANTIATE_DUAL_MULT
#undef INSTANTIATE_TRIP_MULT

#endif // DOXYGEN_IGNORE
<commit_msg>Remove unnecessary <> template argument list<commit_after>/*ckwg +5
 * Copyright 2011-2012 by Kitware, Inc. All Rights Reserved. Please refer to
 * KITWARE_LICENSE.TXT for licensing information, or contact General Counsel,
 * Kitware, Inc., 28 Corporate Drive, Clifton Park, NY 12065.
 */

#include "homography.h"

#include "plane_ref.h"
#include "timestamp.h"
#include "utm.h"

/**
 * \file homography.cxx
 *
 * \brief Implementation of the homography classes.
 */

namespace vistk
{

homography_base
::homography_base(homography_base const& h)
  : m_transform(h.m_transform)
  , m_valid(h.m_valid)
  , m_new_reference(h.m_new_reference)
{
}

homography_base
::~homography_base()
{
}

homography_base::transform_t const&
homography_base
::transform() const
{
  return m_transform;
}

bool
homography_base
::is_valid() const
{
  return m_valid;
}

bool
homography_base
::is_new_reference() const
{
  return m_new_reference;
}

void
homography_base
::set_transform(transform_t const& trans)
{
  m_transform = trans;
}

void
homography_base
::set_identity()
{
  m_transform.set_identity();
}

void
homography_base
::set_valid(bool valid)
{
  m_valid = valid;
}

void
homography_base
::set_new_reference(bool new_reference)
{
  m_new_reference = new_reference;
}

bool
homography_base
::operator == (homography_base const& h) const
{
  return ((m_valid == h.m_valid) &&
          (m_new_reference == h.m_new_reference) &&
          (m_transform == h.m_transform));
}

homography_base
::homography_base()
  : m_valid(false)
  , m_new_reference(false)
{
  set_identity();
}

template <typename Source, typename Dest>
homography<Source, Dest>
::homography()
{
}

template <typename Source, typename Dest>
homography<Source, Dest>
::homography(self_t const& h)
  : homography_base(h)
  , m_source(h.m_source)
  , m_dest(h.m_dest)
{
}

template <typename Source, typename Dest>
homography<Source, Dest>
::~homography()
{
}

template <typename Source, typename Dest>
typename homography<Source, Dest>::source_t
homography<Source, Dest>
::source() const
{
  return m_source;
}

template <typename Source, typename Dest>
typename homography<Source, Dest>::dest_t
homography<Source, Dest>
::destination() const
{
  return m_dest;
}

template <typename Source, typename Dest>
void
homography<Source, Dest>
::set_source(source_t const& src)
{
  m_source = src;
}

template <typename Source, typename Dest>
void
homography<Source, Dest>
::set_destination(dest_t const& dest)
{
  m_dest = dest;
}

template <typename Source, typename Dest>
typename homography<Source, Dest>::inverse_t
homography<Source, Dest>
::inverse() const
{
  inverse_t result;

  result.set_transform(transform().get_inverse());
  result.set_source(m_dest);
  result.set_destination(m_source);
  result.set_valid(is_valid());
  result.set_new_reference(is_new_reference());

  return result;
}

template <typename Source, typename Dest>
bool
homography<Source, Dest>
::operator == (self_t const& h) const
{
  return ((homography_base::operator == (h)) &&
          (m_source == h.m_source) &&
          (m_dest == h.m_dest));
}

}

// Keep in sync with homography_types.h
template class vistk::homography<vistk::timestamp, vistk::timestamp>;
template class vistk::homography<vistk::timestamp, vistk::plane_ref_t>;
template class vistk::homography<vistk::plane_ref_t, vistk::timestamp>;
template class vistk::homography<vistk::timestamp, vistk::utm_zone_t>;
template class vistk::homography<vistk::utm_zone_t, vistk::timestamp>;
template class vistk::homography<vistk::plane_ref_t, vistk::utm_zone_t>;
template class vistk::homography<vistk::utm_zone_t, vistk::plane_ref_t>;

template <typename Source, typename Shared, typename Dest>
vistk::homography<Source, Dest>
vistk::operator * (vistk::homography<Shared, Dest> const& l, vistk::homography<Source, Shared> const& r)
{
  vistk::homography<Source, Dest> result;

  result.set_transform(l.transform() * r.transform());
  result.set_source(r.source());
  result.set_destination(l.dest());
  result.set_valid(l.is_valid() && r.is_valid());

  return result;
}

#ifndef DOXYGEN_IGNORE

/**
 * \def INSTANTIATE_MULT_RAW
 *
 * \brief Instantiates multiplication with three distinct types.
 *
 * \param X The source type in the multiplication.
 * \param Y The shared type in the multiplication.
 * \param Z The destination type in the multiplication.
 */
#define INSTANTIATE_MULT_RAW(X, Y, Z) \
  template homography<X, Z> operator * <X, Y, Z>(homography<Y, Z> const&, homography<X, Y> const&)

/**
 * \def INSTANTIATE_SELF_MULT
 *
 * \brief Instantiates multiplication with homogeneous types.
 *
 * \param X The reference plane for the multiplication.
 */
#define INSTANTIATE_SELF_MULT(X) \
  INSTANTIATE_MULT_RAW(X, X, X)

/**
 * \def INSTANTIATE_DUAL_MULT_RAW
 *
 * \brief Instantiates multiplication with two distinct types.
 *
 * \param X The first type in the multiplication.
 * \param Y The second type in the multiplication.
 */
#define INSTANTIATE_DUAL_MULT_RAW(X, Y) \
  INSTANTIATE_MULT_RAW(X, Y, X);        \
  INSTANTIATE_MULT_RAW(X, X, Y);        \
  INSTANTIATE_MULT_RAW(X, Y, Y)

/**
 * \def INSTANTIATE_DUAL_MULT
 *
 * \brief Instantiates multiplication with two distinct types.
 *
 * This instantiates all permutations between the two types.
 *
 * \param X The first type in the multiplication.
 * \param Y The second type in the multiplication.
 */
#define INSTANTIATE_DUAL_MULT(X, Y) \
  INSTANTIATE_DUAL_MULT_RAW(X, Y);  \
  INSTANTIATE_DUAL_MULT_RAW(Y, X)

/**
 * \def INSTANTIATE_TRIP_MULT
 *
 * \brief Instantiates multiplication with three distinct types.
 *
 * This instantiates all permutations between the three types.
 *
 * \param X The first type in the multiplication.
 * \param Y The second type in the multiplication.
 * \param Z The third type in the multiplication.
 */
#define INSTANTIATE_TRIP_MULT(X,Y,Z)  \
  INSTANTIATE_MULT_RAW(X, Y, Z);      \
  INSTANTIATE_MULT_RAW(X, Z, Y);      \
  INSTANTIATE_MULT_RAW(Y, X, Z);      \
  INSTANTIATE_MULT_RAW(Y, Z, X);      \
  INSTANTIATE_MULT_RAW(Z, X, Y);      \
  INSTANTIATE_MULT_RAW(Z, Y, X)

namespace vistk
{

// Instantiate all allowable types
INSTANTIATE_SELF_MULT(vistk::timestamp);
INSTANTIATE_SELF_MULT(vistk::plane_ref_t);
INSTANTIATE_SELF_MULT(vistk::utm_zone_t);

INSTANTIATE_DUAL_MULT(vistk::timestamp,   vistk::plane_ref_t);
INSTANTIATE_DUAL_MULT(vistk::timestamp,   vistk::utm_zone_t);
INSTANTIATE_DUAL_MULT(vistk::plane_ref_t, vistk::utm_zone_t);

INSTANTIATE_TRIP_MULT(vistk::timestamp,   vistk::plane_ref_t, vistk::utm_zone_t);

}

#undef INSTANTIATE_MULT_RAW
#undef INSTANTIATE_SELF_MULT
#undef INSTANTIATE_DUAL_MULT_RAW
#undef INSTANTIATE_DUAL_MULT
#undef INSTANTIATE_TRIP_MULT

#endif // DOXYGEN_IGNORE
<|endoftext|>


<commit_before>#include "pixelboost/graphics/camera/camera.h"

#include "command/manager.h"
#include "project/entity.h"
#include "project/record.h"
#include "project/project.h"
#include "project/property.h"
#include "view/manipulator/create.h"
#include "core.h"
#include "view.h"

using namespace pixeleditor;

CreateManipulator::CreateManipulator()
{

}

CreateManipulator::~CreateManipulator()
{

}

std::string CreateManipulator::GetName()
{
    return "create";
}

void CreateManipulator::SetEntityType(const std::string& entity)
{
    _EntityType = entity;
    _Fields.clear();
    _Values.clear();
}

void CreateManipulator::SetCreationData(const std::vector<std::string>& fields, const std::vector<std::string>& values)
{
    _Fields = fields;
    _Values = values;
}

bool CreateManipulator::OnMouseDown(pb::MouseButton button, pb::ModifierKeys modifierKeys, glm::vec2 position)
{
    if (button == pb::kMouseButtonLeft)
    {
        glm::vec2 start = View::Instance()->GetLevelCamera()->ConvertScreenToWorld(position);

        char commandArgs[1024];
        sprintf(commandArgs, "-r %d -t %s -p %f,%f,%f", View::Instance()->GetRecord()->GetUid(), _EntityType.c_str(), start.x, start.y, 0.f);
        std::string entityIdString = Core::Instance()->GetCommandManager()->Exec("createEntity", commandArgs);
        Uid entityId = atoi(entityIdString.c_str());
        Entity* entity = Core::Instance()->GetProject()->GetEntity(entityId);

        for (int i=0; i<_Fields.size(); i++)
        {
            entity->AcquireAtom(_Fields[i])->SetStringValue(_Values[i]);
        }

        Core::Instance()->GetCommandManager()->Exec("select", "-u " + entityIdString);

        return true;
    } else if (button == pb::kMouseButtonRight)
    {
        View::Instance()->GetManipulatorManager()->SetActiveManipulator("select");
        return true;
    }

    return false;
}

bool CreateManipulator::OnMouseUp(pb::MouseButton button, pb::ModifierKeys modifierKeys, glm::vec2 position)
{
    return false;
}

bool CreateManipulator::OnMouseMove(glm::vec2 position)
{
    return false;
}

bool CreateManipulator::OnKeyDown(pb::KeyboardKey key, char character)
{
    return false;
}

bool CreateManipulator::OnKeyUp(pb::KeyboardKey key, char character)
{
    return false;
}
<commit_msg>Fix crash when trying to create entity while no record is loaded<commit_after>#include "pixelboost/graphics/camera/camera.h"

#include "command/manager.h"
#include "project/entity.h"
#include "project/record.h"
#include "project/project.h"
#include "project/property.h"
#include "view/manipulator/create.h"
#include "core.h"
#include "view.h"

using namespace pixeleditor;

CreateManipulator::CreateManipulator()
{

}

CreateManipulator::~CreateManipulator()
{

}

std::string CreateManipulator::GetName()
{
    return "create";
}

void CreateManipulator::SetEntityType(const std::string& entity)
{
    _EntityType = entity;
    _Fields.clear();
    _Values.clear();
}

void CreateManipulator::SetCreationData(const std::vector<std::string>& fields, const std::vector<std::string>& values)
{
    _Fields = fields;
    _Values = values;
}

bool CreateManipulator::OnMouseDown(pb::MouseButton button, pb::ModifierKeys modifierKeys, glm::vec2 position)
{
    if (button == pb::kMouseButtonLeft)
    {
        if (View::Instance()->GetRecord())
        {
            glm::vec2 start = View::Instance()->GetLevelCamera()->ConvertScreenToWorld(position);

            char commandArgs[1024];
            sprintf(commandArgs, "-r %d -t %s -p %f,%f,%f", View::Instance()->GetRecord()->GetUid(), _EntityType.c_str(), start.x, start.y, 0.f);
            std::string entityIdString = Core::Instance()->GetCommandManager()->Exec("createEntity", commandArgs);
            Uid entityId = atoi(entityIdString.c_str());
            Entity* entity = Core::Instance()->GetProject()->GetEntity(entityId);

            for (int i=0; i<_Fields.size(); i++)
            {
                entity->AcquireAtom(_Fields[i])->SetStringValue(_Values[i]);
            }

            Core::Instance()->GetCommandManager()->Exec("select", "-u " + entityIdString);

            return true;
        }
    } else if (button == pb::kMouseButtonRight)
    {
        View::Instance()->GetManipulatorManager()->SetActiveManipulator("select");
        return true;
    }

    return false;
}

bool CreateManipulator::OnMouseUp(pb::MouseButton button, pb::ModifierKeys modifierKeys, glm::vec2 position)
{
    return false;
}

bool CreateManipulator::OnMouseMove(glm::vec2 position)
{
    return false;
}

bool CreateManipulator::OnKeyDown(pb::KeyboardKey key, char character)
{
    return false;
}

bool CreateManipulator::OnKeyUp(pb::KeyboardKey key, char character)
{
    return false;
}
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2014, Bradley J Chambers (brad.chambers@gmail.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include "View.hpp"
#include <pdal/kernel/KernelFactory.hpp>

CREATE_KERNEL_PLUGIN(view, pdal::kernel::View)

namespace pdal
{
namespace kernel
{

// Support for parsing point numbers.  Points can be specified singly or as
// dash-separated ranges.  i.e. 6-7,8,19-20
namespace {

using namespace std;

vector<string> tokenize(const string s, char c)
{
    string::const_iterator begin;
    string::const_iterator end;
    vector<string> strings;
    begin = s.begin();
    while (true)
    {
        end = find(begin, s.end(), c);
        strings.push_back(string(begin, end));
        if (end == s.end())
            break;
        begin = end + 1;
    }
    return strings;
}

uint32_t parseInt(const string& s)
{
    try
    {
        return boost::lexical_cast<uint32_t>(s);
    }
    catch (boost::bad_lexical_cast)
    {
        throw app_runtime_error(string("Invalid integer: ") + s);
    }
}

void addSingle(const string& s, vector<uint32_t>& points)
{
    points.push_back(parseInt(s));
}

void addRange(const string& begin, const string& end,
    vector<uint32_t>& points)
{
    uint32_t low = parseInt(begin);
    uint32_t high = parseInt(end);
    if (low > high)
        throw app_runtime_error(string("Range invalid: ") + begin + "-" + end);
    while (low <= high)
        points.push_back(low++);
}

vector<boost::uint32_t> getListOfPoints(std::string p)
{
    vector<boost::uint32_t> output;

    //Remove whitespace from string with awful remove/erase idiom.
    p.erase(remove_if(p.begin(), p.end(), ::isspace), p.end());

    vector<string> ranges = tokenize(p, ',');
    for (string s : ranges)
    {
        vector<string> limits = tokenize(s, '-');
        if (limits.size() == 1)
            addSingle(limits[0], output);
        else if (limits.size() == 2)
            addRange(limits[0], limits[1], output);
        else
            throw app_runtime_error(string("Invalid point range: ") + s);
    }
    return output;
}

} //namespace

View::View()
    : Kernel()
    , m_inputFile("")
{
    return;
}

void View::validateSwitches()
{
    if (m_inputFile == "")
    {
        throw app_usage_error("--input/-i required");
    }

    return;
}

void View::addSwitches()
{
    po::options_description* file_options = new po::options_description("file options");

    file_options->add_options()
    ("input,i", po::value<std::string>(&m_inputFile)->default_value(""), "input file name")
    ("point,p", po::value<std::string >(&m_pointIndexes), "point to dump")
    ;

    addSwitchSet(file_options);

    addPositionalSwitch("input", 1);
}

std::unique_ptr<Stage> View::makeReader(Options readerOptions)
{
    if (isDebug())
    {
        readerOptions.add<bool>("debug", true);
        boost::uint32_t verbosity(getVerboseLevel());
        if (!verbosity)
            verbosity = 1;

        readerOptions.add<boost::uint32_t>("verbose", verbosity);
        readerOptions.add<std::string>("log", "STDERR");
    }

    Stage* stage = AppSupport::makeReader(m_inputFile);
    stage->setOptions(readerOptions);
    std::unique_ptr<Stage> reader_stage(stage);

    return reader_stage;
}

int View::execute()
{
    Options readerOptions;
    readerOptions.add<std::string>("filename", m_inputFile);
    readerOptions.add<bool>("debug", isDebug());
    readerOptions.add<boost::uint32_t>("verbose", getVerboseLevel());

    std::unique_ptr<Stage> readerStage = makeReader(readerOptions);
    PointContext ctx;
    readerStage->prepare(ctx);
    PointBufferSet pbSetIn = readerStage->execute(ctx);
    //visualize(*pbSetIn.begin());

    PointBufferPtr buf = *pbSetIn.begin();
    PointBufferPtr outbuf = buf->makeNew();

    std::vector<uint32_t> points = getListOfPoints(m_pointIndexes);
    for (size_t i = 0; i < points.size(); ++i)
    {
        PointId id = (PointId)points[i];
        if (id < buf->size())
            outbuf->appendPoint(*buf, id);
    }

    visualize(outbuf);
    return 0;
}

} // kernel
} // pdal
<commit_msg>if no point indices provided in view kernel, visualize all points<commit_after>/******************************************************************************
* Copyright (c) 2014, Bradley J Chambers (brad.chambers@gmail.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include "View.hpp"
#include <pdal/kernel/KernelFactory.hpp>

CREATE_KERNEL_PLUGIN(view, pdal::kernel::View)

namespace pdal
{
namespace kernel
{

// Support for parsing point numbers.  Points can be specified singly or as
// dash-separated ranges.  i.e. 6-7,8,19-20
namespace {

using namespace std;

vector<string> tokenize(const string s, char c)
{
    string::const_iterator begin;
    string::const_iterator end;
    vector<string> strings;
    begin = s.begin();
    while (true)
    {
        end = find(begin, s.end(), c);
        strings.push_back(string(begin, end));
        if (end == s.end())
            break;
        begin = end + 1;
    }
    return strings;
}

uint32_t parseInt(const string& s)
{
    try
    {
        return boost::lexical_cast<uint32_t>(s);
    }
    catch (boost::bad_lexical_cast)
    {
        throw app_runtime_error(string("Invalid integer: ") + s);
    }
}

void addSingle(const string& s, vector<uint32_t>& points)
{
    points.push_back(parseInt(s));
}

void addRange(const string& begin, const string& end,
    vector<uint32_t>& points)
{
    uint32_t low = parseInt(begin);
    uint32_t high = parseInt(end);
    if (low > high)
        throw app_runtime_error(string("Range invalid: ") + begin + "-" + end);
    while (low <= high)
        points.push_back(low++);
}

vector<boost::uint32_t> getListOfPoints(std::string p)
{
    vector<boost::uint32_t> output;

    //Remove whitespace from string with awful remove/erase idiom.
    p.erase(remove_if(p.begin(), p.end(), ::isspace), p.end());

    vector<string> ranges = tokenize(p, ',');
    for (string s : ranges)
    {
        vector<string> limits = tokenize(s, '-');
        if (limits.size() == 1)
            addSingle(limits[0], output);
        else if (limits.size() == 2)
            addRange(limits[0], limits[1], output);
        else
            throw app_runtime_error(string("Invalid point range: ") + s);
    }
    return output;
}

} //namespace

View::View()
    : Kernel()
    , m_inputFile("")
{
    return;
}

void View::validateSwitches()
{
    if (m_inputFile == "")
    {
        throw app_usage_error("--input/-i required");
    }

    return;
}

void View::addSwitches()
{
    po::options_description* file_options = new po::options_description("file options");

    file_options->add_options()
    ("input,i", po::value<std::string>(&m_inputFile)->default_value(""), "input file name")
    ("point,p", po::value<std::string >(&m_pointIndexes), "point to dump")
    ;

    addSwitchSet(file_options);

    addPositionalSwitch("input", 1);
}

std::unique_ptr<Stage> View::makeReader(Options readerOptions)
{
    if (isDebug())
    {
        readerOptions.add<bool>("debug", true);
        boost::uint32_t verbosity(getVerboseLevel());
        if (!verbosity)
            verbosity = 1;

        readerOptions.add<boost::uint32_t>("verbose", verbosity);
        readerOptions.add<std::string>("log", "STDERR");
    }

    Stage* stage = AppSupport::makeReader(m_inputFile);
    stage->setOptions(readerOptions);
    std::unique_ptr<Stage> reader_stage(stage);

    return reader_stage;
}

int View::execute()
{
    Options readerOptions;
    readerOptions.add<std::string>("filename", m_inputFile);
    readerOptions.add<bool>("debug", isDebug());
    readerOptions.add<boost::uint32_t>("verbose", getVerboseLevel());

    std::unique_ptr<Stage> readerStage = makeReader(readerOptions);
    PointContext ctx;
    readerStage->prepare(ctx);
    PointBufferSet pbSetIn = readerStage->execute(ctx);
    //visualize(*pbSetIn.begin());

    PointBufferPtr buf = *pbSetIn.begin();

    if (m_pointIndexes.size())
    {
        PointBufferPtr outbuf = buf->makeNew();

        std::vector<uint32_t> points = getListOfPoints(m_pointIndexes);
        for (size_t i = 0; i < points.size(); ++i)
        {
            PointId id = (PointId)points[i];
            if (id < buf->size())
                outbuf->appendPoint(*buf, id);
        }

        visualize(outbuf);
    }
    else
    {
        visualize(buf);
    }
    return 0;
}

} // kernel
} // pdal
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id: ValuePrinter.cpp 46307 2012-10-04 06:53:23Z axel $
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/StoredValueRef.h"
#include "cling/Interpreter/ValuePrinter.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/raw_ostream.h"

using namespace cling;
using namespace clang;
using namespace llvm;

StoredValueRef::StoredValue::StoredValue(const ASTContext& ctx,
                                         QualType clangTy,
                                         const llvm::Type* llvm_Ty)
   :Value(GenericValue(), clangTy, llvm_Ty), m_Mem(0) {
  if (!(clangTy->isIntegralOrEnumerationType()
        || clangTy->isRealFloatingType()
        || clangTy->hasPointerRepresentation())) {
    const uint64_t size = (uint64_t)getAllocSizeInBytes(ctx);
    if (size > sizeof(m_Buf))
      m_Mem = new char[size];
    else m_Mem = m_Buf;
    setGV(llvm::PTOGV(m_Mem));
  };
}

StoredValueRef::StoredValue::~StoredValue() {
  if (m_Mem != m_Buf)
    delete [] m_Mem;
}

long long StoredValueRef::StoredValue::getAllocSizeInBytes(
                                                  const ASTContext& ctx) const {
   return (long long) ctx.getTypeSizeInChars(getClangType()).getQuantity();
}

void StoredValueRef::dump(ASTContext& ctx) const {
  valuePrinterInternal::StreamStoredValueRef(llvm::errs(), this, ctx);
}

StoredValueRef StoredValueRef::allocate(const ASTContext& ctx, QualType t,
                                        const llvm::Type* llvmTy) {
  return new StoredValue(ctx, t, llvmTy);
}

StoredValueRef StoredValueRef::bitwiseCopy(const ASTContext& ctx,
                                           const Value& value) {
  StoredValue* SValue
    = new StoredValue(ctx, value.getClangType(), value.getLLVMType());
  if (SValue->m_Mem) {
    const char* src = (const char*)value.getGV().PointerVal;
    // It's not a pointer. LLVM stores a char[5] (i.e. 5 x i8) as an i40,
    // so use that instead. We don't keep it as an int; instead, we "allocate"
    // it as a "proper" char[5] in the m_Mem. "Allocate" because it uses the
    // m_Buf, so no actual allocation happens.
    uint64_t IntVal = value.getGV().IntVal.getSExtValue();
    if (!src) src = (const char*)&IntVal;
    memcpy(SValue->m_Mem, src,
           SValue->getAllocSizeInBytes(ctx));
  } else {
    SValue->setGV(value.getGV());
  }
  return SValue;
}
<commit_msg>Add support for member data pointer type.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id: ValuePrinter.cpp 46307 2012-10-04 06:53:23Z axel $
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/StoredValueRef.h"
#include "cling/Interpreter/ValuePrinter.h"
#include "clang/AST/ASTContext.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/raw_ostream.h"

using namespace cling;
using namespace clang;
using namespace llvm;

StoredValueRef::StoredValue::StoredValue(const ASTContext& ctx,
                                         QualType clangTy,
                                         const llvm::Type* llvm_Ty)
    : Value(GenericValue(), clangTy, llvm_Ty), m_Mem(0) {
  if (clangTy->isIntegralOrEnumerationType() ||
      clangTy->isRealFloatingType() ||
      clangTy->hasPointerRepresentation()) {
    return;
  };
  if (const MemberPointerType* MPT = clangTy->getAs<MemberPointerType>()) {
    if (MPT->isMemberDataPointer()) {
      return;
    }
  }
  m_Mem = m_Buf;
  const uint64_t size = (uint64_t) getAllocSizeInBytes(ctx);
  if (size > sizeof(m_Buf)) {
    m_Mem = new char[size];
  }
  setGV(llvm::PTOGV(m_Mem));
}

StoredValueRef::StoredValue::~StoredValue() {
  if (m_Mem != m_Buf)
    delete [] m_Mem;
}

long long StoredValueRef::StoredValue::getAllocSizeInBytes(
                                                  const ASTContext& ctx) const {
   return (long long) ctx.getTypeSizeInChars(getClangType()).getQuantity();
}

void StoredValueRef::dump(ASTContext& ctx) const {
  valuePrinterInternal::StreamStoredValueRef(llvm::errs(), this, ctx);
}

StoredValueRef StoredValueRef::allocate(const ASTContext& ctx, QualType t,
                                        const llvm::Type* llvmTy) {
  return new StoredValue(ctx, t, llvmTy);
}

StoredValueRef StoredValueRef::bitwiseCopy(const ASTContext& ctx,
                                           const Value& value) {
  StoredValue* SValue
    = new StoredValue(ctx, value.getClangType(), value.getLLVMType());
  if (SValue->m_Mem) {
    const char* src = (const char*)value.getGV().PointerVal;
    // It's not a pointer. LLVM stores a char[5] (i.e. 5 x i8) as an i40,
    // so use that instead. We don't keep it as an int; instead, we "allocate"
    // it as a "proper" char[5] in the m_Mem. "Allocate" because it uses the
    // m_Buf, so no actual allocation happens.
    uint64_t IntVal = value.getGV().IntVal.getSExtValue();
    if (!src) src = (const char*)&IntVal;
    memcpy(SValue->m_Mem, src,
           SValue->getAllocSizeInBytes(ctx));
  } else {
    SValue->setGV(value.getGV());
  }
  return SValue;
}
<|endoftext|>