<commit_before>/*
 * (C) Copyright 2014 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#ifndef __CACHE_ENTRY_H__
#define __CACHE_ENTRY_H__

#include <glibmm.h>
#include <mutex>

namespace kurento
{

class CacheEntry
{
public:
  CacheEntry (unsigned int timeout, std::string sessionId, int requestId,
              std::string response);
  std::string getResponse (void);
  ~CacheEntry ();

  sigc::signal<void> signalTimeout;

private:
  Glib::RefPtr<Glib::TimeoutSource> source;
  std::recursive_mutex mutex;
  std::string sessionId;
  int requestId;
  std::string response;
  bool timedout;

  class StaticConstructor
  {
  public:
    StaticConstructor();
  };

  static StaticConstructor staticConstructor;
};

} // kurento

#endif /* __CACHE_ENTRY_H__ */
<commit_msg>CacheEntry: Fix valgrind warning due to an access to an uninitialized memory<commit_after>/*
 * (C) Copyright 2014 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 */

#ifndef __CACHE_ENTRY_H__
#define __CACHE_ENTRY_H__

#include <glibmm.h>
#include <mutex>

namespace kurento
{

class CacheEntry
{
public:
  CacheEntry (unsigned int timeout, std::string sessionId, int requestId,
              std::string response);
  std::string getResponse (void);
  ~CacheEntry ();

  sigc::signal<void> signalTimeout;

private:
  Glib::RefPtr<Glib::TimeoutSource> source;
  std::recursive_mutex mutex;
  std::string sessionId;
  int requestId;
  std::string response;
  bool timedout = false;

  class StaticConstructor
  {
  public:
    StaticConstructor();
  };

  static StaticConstructor staticConstructor;
};

} // kurento

#endif /* __CACHE_ENTRY_H__ */
<|endoftext|>


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

#ifndef included_6603F051_ED25_4096_8DCF_0F4A5829CACD
#define included_6603F051_ED25_4096_8DCF_0F4A5829CACD

#include <type_traits>
#include <utility>

namespace acm {
    namespace detail  {

        namespace adl_swap_ns {
            using std::swap;

            template<typename T>
            class is_swappable_test {

                struct swap_not_found_type {};

                template<typename U>
                static auto test(U& u) -> decltype(swap(u, u));

                template<typename U>
                static auto test(...) -> swap_not_found_type;

                using test_type = decltype(test<T>(std::declval<T&>()));

            public:
                static constexpr bool value = !std::is_same<test_type, swap_not_found_type>::value;
            };

            template<bool, typename T>
            struct is_nothrow_swappable_test :
                std::integral_constant<bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))> {
            };

            template<typename T>
            struct is_nothrow_swappable_test<false, T> :
                std::false_type {
            };

        } // namespace adl_swap_ns

        template<typename T>
        struct is_swappable :
            std::integral_constant<bool, adl_swap_ns::is_swappable_test<T>::value> {
        };

        // This really should be part of C++
        template<typename T>
        struct is_nothrow_swappable
            : std::integral_constant<bool, adl_swap_ns::is_nothrow_swappable_test<is_swappable<T>::value, T>::value> {
        };

    } // namespace detail
} // namespace acm

#endif // included_6603F051_ED25_4096_8DCF_0F4A5829CACD
<commit_msg>Remove extra level of indentation<commit_after>// Copyright 2013 Andrew C. Morrow
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef included_6603F051_ED25_4096_8DCF_0F4A5829CACD
#define included_6603F051_ED25_4096_8DCF_0F4A5829CACD

#include <type_traits>
#include <utility>

namespace acm {
namespace detail  {

    namespace adl_swap_ns {
        using std::swap;

        template<typename T>
        class is_swappable_test {

            struct swap_not_found_type {};

            template<typename U>
            static auto test(U& u) -> decltype(swap(u, u));

            template<typename U>
            static auto test(...) -> swap_not_found_type;

            using test_type = decltype(test<T>(std::declval<T&>()));

        public:
            static constexpr bool value = !std::is_same<test_type, swap_not_found_type>::value;
        };

        template<bool, typename T>
        struct is_nothrow_swappable_test :
            std::integral_constant<bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))> {
        };

        template<typename T>
        struct is_nothrow_swappable_test<false, T> :
            std::false_type {
        };

    } // namespace adl_swap_ns

    template<typename T>
    struct is_swappable :
        std::integral_constant<bool, adl_swap_ns::is_swappable_test<T>::value> {
    };

    // This really should be part of C++
    template<typename T>
    struct is_nothrow_swappable
        : std::integral_constant<bool, adl_swap_ns::is_nothrow_swappable_test<is_swappable<T>::value, T>::value> {
    };

} // namespace detail
} // namespace acm

#endif // included_6603F051_ED25_4096_8DCF_0F4A5829CACD
<|endoftext|>


<commit_before>#include <boost/program_options.hpp>
#include <iostream>
#include "data/GraphSerializer.hpp"
#include "data/PathSerializer.hpp"
#include "data/ConfigSerializer.hpp"
#include "data/StatisticsSerializer.hpp"
#include "genetic/GeneticSolver.hpp"
#include "genetic/GeneticAnalyser.hpp"
#include "net/PopulationExchanger.hpp"
#include "utils/Random.hpp"
#include "utils/StopWatch.hpp"

#define IS_MASTER (ex == NULL || ex->isMaster())
#define LOG_MAST if(IS_MASTER) std::cout << "[MAST] "
#define LOG_ALWS std::cout << "[ALWS] "
#define LOG_INFO if(!logQuiet) std::cout << "[INFO] "
#define LOG_ERR std::cerr << "[ERROR] "

namespace po = boost::program_options;

tsp::Graph graph;
tsp::GeneticSolver solver(graph);
tsp::Config cfg;
tsp::PopulationExchanger *ex = NULL;
bool logQuiet = false;
tsp::StopWatch watch;
unsigned int currentGen = 0;
tsp::Statistics stats;
boost::posix_time::time_duration duration;

static int parseArguments(int argc, char **argv)
{
    po::variables_map vm;
    po::options_description desc("Allowed Options");
    desc.add_options()
    ("help,h", "show help text")
    ("quiet,q", "activate quiet mode")
    ("config,c", po::value<std::string>(), "config file")
    ("infile,i", po::value<std::string>(), "graph definition file")
    ("outfile,o", po::value<std::string>(), "path output file")
    ("generations,g", po::value<unsigned int>(),
     "amount of generations to be calculated")
    ("population,p", po::value<unsigned int>(), "population size")
    ("start,s", po::value<unsigned int>(), "start node")
    ("elitism,e", po::value<double>(), "elitism rate")
    ("mutation,m", po::value<double>(), "mutation chance")
    ("fitness,f", po::value<unsigned int>(), "fitness power")
    ("exchange,x", po::value<double>(), "exchange rate")
    ("time,t", po::value<std::string>(), "time limit for execution")
    ("network,n", "activate MPI network mode")
    ;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    } catch(std::exception &e) {
        std::cout << e.what() << "\n";
        return 1;
    }

    // check if required options were given
    bool hasConfig = vm.count("config");
    bool hasOpt = vm.count("infile") &&
                  vm.count("outfile") &&
                  vm.count("population") &&
                  vm.count("start") &&
                  vm.count("elitism") &&
                  vm.count("mutation") &&
                  vm.count("fitness");
    bool hasTermCond = vm.count("generations") || (vm.count("time")
                       && tsp::checkDurationStr(vm["time"].as<std::string>()));
    bool hasHelp = vm.count("help");
    if(hasHelp || !(hasConfig || (hasOpt && hasTermCond))) {
        std::cout << desc << "\n";
        return 1;
    }

    logQuiet = vm.count("quiet") > 0;

    // create network component if we are in network mode
    if(vm.count("network")) {
        LOG_INFO << "Network mode activated.\n";
        ex = new tsp::PopulationExchanger(argc, argv);

        // seed the random number generator with our rank and time
        int seed = (ex->getRank() + 1) * std::time(0);
        tsp::Random::shakeRNG(seed);

        // if we are not master then return here and
        // receive config through network
        if(!ex->isMaster())
            return 0;
    }

    // load config file if specified
    if(hasConfig) {
        LOG_INFO << "Loading Config from '" << vm["config"].as<std::string>() <<
                 "' ...\n";
        if(!tsp::ConfigSerializer::load(cfg, vm["config"].as<std::string>())) {
            LOG_ERR << " Failed\n";
            return 1;
        }
    }

    // set all config parameters
    if(vm.count("exchange"))
        cfg.exchangeRate = vm["exchange"].as<double>();
    if(vm.count("infile"))
        cfg.graphFile = vm["infile"].as<std::string>();
    if(vm.count("outfile"))
        cfg.pathFile = vm["outfile"].as<std::string>();
    if(vm.count("generations")) {
        cfg.terminateType = tsp::TerminateType::GENERATIONS;
        cfg.generationCount = vm["generations"].as<unsigned int>();
    }
    if(vm.count("population"))
        cfg.gaSettings.populationSize = vm["population"].as<unsigned int>();
    if(vm.count("start"))
        cfg.gaSettings.startNode = vm["start"].as<unsigned int>();
    if(vm.count("elitism"))
        cfg.gaSettings.elitismRate = vm["elitism"].as<double>();
    if(vm.count("mutation"))
        cfg.gaSettings.mutationChance = vm["mutation"].as<double>();
    if(vm.count("fitness"))
        cfg.gaSettings.fitnessPow = vm["fitness"].as<unsigned int>();
    if(vm.count("time")) {
        cfg.terminateType = tsp::TerminateType::TIME;
        cfg.duration = tsp::durationFromStr(vm["time"].as<std::string>());
    }

    return 0;
}

static void exchangeConfig()
{
    if(ex == NULL)
        return;

    LOG_ALWS << "Process " << ex->getRank() << " READY\n";

    ex->broadcastConfig(cfg);
    ex->setExchangeCount(cfg.exchangeRate * cfg.gaSettings.populationSize);

    return;
}

static void printParameters()
{
    LOG_INFO << "Parameters\n";
    LOG_INFO << "  graph file: " << cfg.graphFile << "\n";
    LOG_INFO << "  path file: " << cfg.pathFile << "\n";
    LOG_INFO << "  generation count: " << cfg.generationCount << "\n";
    LOG_INFO << "  duration: " << boost::posix_time::to_simple_string(
                 cfg.duration) << "\n";
    LOG_INFO << "  population size: " << cfg.gaSettings.populationSize << "\n";
    LOG_INFO << "  start node: " << cfg.gaSettings.startNode << "\n";
    LOG_INFO << "  elitism rate: " << cfg.gaSettings.elitismRate << "\n";
    LOG_INFO << "  mutation chance: " << cfg.gaSettings.mutationChance << "\n";
    LOG_INFO << "  fitness power: " << cfg.gaSettings.fitnessPow << "\n";
    LOG_INFO << "  exchange rate: " << cfg.exchangeRate << "\n";
}

static void printCurrentGen(tsp::GeneticAnalyser &analyser)
{
    LOG_INFO << "  Best Distance: " << analyser.getBestDistance(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Mean Distance: " << analyser.getMeanDistance(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Best Fitness: " << analyser.getBestFitness(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Mean Fitness: " << analyser.getMeanFitness(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Best Norm. Fitness: " << analyser.getBestNormalizedFitness(
                 solver.getPopulation()) << "\n";
}

static int loadGraph()
{
    LOG_INFO << "Loading Graph ...\n";
    if(!tsp::GraphSerializer::load(graph, cfg.graphFile)) {
        LOG_ERR << " Failed\n";
        return 1;
    }

    return 0;
}

static void initStats()
{
    stats.nodeCount = graph.size();
    if(cfg.terminateType == tsp::TerminateType::GENERATIONS) {
        stats.genCount = cfg.generationCount;
        stats.timePerGen.resize(stats.genCount);
        stats.distancePerGen.resize(stats.genCount);
    } else {
        stats.genCount = 0;
        stats.timePerGen.resize(512);
        stats.distancePerGen.resize(512);
    }
}

static bool checkTermCond()
{
    bool terminate = true;
    switch(cfg.terminateType) {
    case tsp::TerminateType::GENERATIONS:
        terminate = currentGen >= cfg.generationCount;
        break;
    case tsp::TerminateType::TIME:
        terminate = watch.interim() >= cfg.duration;
        if(ex != NULL) {
            terminate = ex->broadcastTermCond(terminate);
        }
        break;
    default:
        assert(false);
    }

    return terminate;
}

static void catchStats(tsp::GeneticAnalyser &analyser)
{
    // keep vectors large enough
    if(currentGen >= stats.timePerGen.size()) {
        stats.timePerGen.resize(stats.timePerGen.size() * 2);
        stats.distancePerGen.resize(stats.distancePerGen.size() * 2);
    }

    stats.timePerGen[currentGen] = watch.interim();
    stats.distancePerGen[currentGen] = analyser.getBestDistance(solver.getPopulation());
}

static void finalizeStats(tsp::GeneticAnalyser &analyser)
{
    stats.genCount = currentGen;
    stats.timePerGen.resize(currentGen);
    stats.distancePerGen.resize(currentGen);
    stats.finalDistance = analyser.getBestDistance(solver.getPopulation());
    stats.totalTime = duration;

    //exchange stats
    if (ex != NULL)
    {
        std::vector<std::vector<double>> distlist;
        ex->gatherDistPerGen(stats.distancePerGen, distlist);

        // find the minimal distance for each generation
        for(unsigned i = 0; i < stats.genCount; ++i)
        {
            double min = -1;
            for(unsigned int j = 0; j < distlist.size(); ++j)
            {
                if(min < 0 || distlist[j][i] < min)
                    min = distlist[j][i];
            }
            stats.distancePerGen[i] = min;
        }
    }

    tsp::StatisticsSerializer::save(stats, "statistics.json");
}

static void runAlgorithm()
{
    LOG_MAST << "Solving TSP ...\n";
    LOG_INFO << "Initializing solver...";
    solver.setSettings(cfg.gaSettings);
    solver.init();

    tsp::GeneticAnalyser analyser(graph);
    watch.start();

    while(!checkTermCond()) {

        LOG_INFO << "Calculating Generation " << currentGen + 1 << "...\n";
        solver.nextGeneration();

        if(ex != NULL) {
            LOG_INFO << "Exchanging individuals ...\n";
            ex->exchangePopulation(solver.getPopulation());
        }

        LOG_INFO << "Updating fitness ...\n";
        solver.updateFitness();

        catchStats(analyser);
        printCurrentGen(analyser);
        ++currentGen;

        if(IS_MASTER) {
            std::cout << ".";
            std::cout.flush();
        }
    }

    std::cout << "\n";

    if(ex != NULL) {
        LOG_INFO << "Gathering best individuals ...\n";
        ex->gatherPopulation(solver.getPopulation());

        if(ex->isMaster()) {
            solver.updateFitness();
            LOG_MAST << "Received " << solver.getPopulation().getIndividuals().size() <<
                     " solutions\n";
            for(unsigned int i = 0; i < solver.getPopulation().getIndividuals().size(); ++i)
                LOG_MAST << "  solution " << i << ": " << analyser.getDistance(
                             solver.getPopulation().getIndividuals()[i]) << "\n";
        }
    }

    duration = watch.stop();
    finalizeStats(analyser);

    LOG_MAST << "=============================\n";
    LOG_MAST << "Final Results\n";
    LOG_MAST << "  Best Distance: " <<  analyser.getBestDistance(
                 solver.getPopulation()) << "\n";
    LOG_MAST << "  Time: " << boost::posix_time::to_simple_string(duration) << "\n";
    LOG_MAST << "  Generations: " << currentGen << "\n";
}

static int savePath()
{

    if(ex != NULL && !ex->isMaster())
        return 0;

    LOG_MAST << "Saving Path ...\n";
    if(!tsp::PathSerializer::save(
                solver.getPopulation().getBestIndividual().getPath(),
                cfg.pathFile)) {
        LOG_ERR << " Failed\n";
        return 1;
    }

    return 0;
}

int main(int argc, char **argv)
{
    tsp::Random::shakeRNG();

    int ret = parseArguments(argc, argv);
    if(ret)
        return ret;

    exchangeConfig();
    printParameters();

    ret = loadGraph();
    if(ret)
        return ret;

    initStats();
    runAlgorithm();

    ret = savePath();
    if(ret)
        return ret;

    if(ex != NULL)
        delete ex;

    return 0;
}
<commit_msg>Fix that only master saves statistics<commit_after>#include <boost/program_options.hpp>
#include <iostream>
#include "data/GraphSerializer.hpp"
#include "data/PathSerializer.hpp"
#include "data/ConfigSerializer.hpp"
#include "data/StatisticsSerializer.hpp"
#include "genetic/GeneticSolver.hpp"
#include "genetic/GeneticAnalyser.hpp"
#include "net/PopulationExchanger.hpp"
#include "utils/Random.hpp"
#include "utils/StopWatch.hpp"

#define IS_MASTER (ex == NULL || ex->isMaster())
#define LOG_MAST if(IS_MASTER) std::cout << "[MAST] "
#define LOG_ALWS std::cout << "[ALWS] "
#define LOG_INFO if(!logQuiet) std::cout << "[INFO] "
#define LOG_ERR std::cerr << "[ERROR] "

namespace po = boost::program_options;

tsp::Graph graph;
tsp::GeneticSolver solver(graph);
tsp::Config cfg;
tsp::PopulationExchanger *ex = NULL;
bool logQuiet = false;
tsp::StopWatch watch;
unsigned int currentGen = 0;
tsp::Statistics stats;
boost::posix_time::time_duration duration;

static int parseArguments(int argc, char **argv)
{
    po::variables_map vm;
    po::options_description desc("Allowed Options");
    desc.add_options()
    ("help,h", "show help text")
    ("quiet,q", "activate quiet mode")
    ("config,c", po::value<std::string>(), "config file")
    ("infile,i", po::value<std::string>(), "graph definition file")
    ("outfile,o", po::value<std::string>(), "path output file")
    ("generations,g", po::value<unsigned int>(),
     "amount of generations to be calculated")
    ("population,p", po::value<unsigned int>(), "population size")
    ("start,s", po::value<unsigned int>(), "start node")
    ("elitism,e", po::value<double>(), "elitism rate")
    ("mutation,m", po::value<double>(), "mutation chance")
    ("fitness,f", po::value<unsigned int>(), "fitness power")
    ("exchange,x", po::value<double>(), "exchange rate")
    ("time,t", po::value<std::string>(), "time limit for execution")
    ("network,n", "activate MPI network mode")
    ;
    try {
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    } catch(std::exception &e) {
        std::cout << e.what() << "\n";
        return 1;
    }

    // check if required options were given
    bool hasConfig = vm.count("config");
    bool hasOpt = vm.count("infile") &&
                  vm.count("outfile") &&
                  vm.count("population") &&
                  vm.count("start") &&
                  vm.count("elitism") &&
                  vm.count("mutation") &&
                  vm.count("fitness");
    bool hasTermCond = vm.count("generations") || (vm.count("time")
                       && tsp::checkDurationStr(vm["time"].as<std::string>()));
    bool hasHelp = vm.count("help");
    if(hasHelp || !(hasConfig || (hasOpt && hasTermCond))) {
        std::cout << desc << "\n";
        return 1;
    }

    logQuiet = vm.count("quiet") > 0;

    // create network component if we are in network mode
    if(vm.count("network")) {
        LOG_INFO << "Network mode activated.\n";
        ex = new tsp::PopulationExchanger(argc, argv);

        // seed the random number generator with our rank and time
        int seed = (ex->getRank() + 1) * std::time(0);
        tsp::Random::shakeRNG(seed);

        // if we are not master then return here and
        // receive config through network
        if(!ex->isMaster())
            return 0;
    }

    // load config file if specified
    if(hasConfig) {
        LOG_INFO << "Loading Config from '" << vm["config"].as<std::string>() <<
                 "' ...\n";
        if(!tsp::ConfigSerializer::load(cfg, vm["config"].as<std::string>())) {
            LOG_ERR << " Failed\n";
            return 1;
        }
    }

    // set all config parameters
    if(vm.count("exchange"))
        cfg.exchangeRate = vm["exchange"].as<double>();
    if(vm.count("infile"))
        cfg.graphFile = vm["infile"].as<std::string>();
    if(vm.count("outfile"))
        cfg.pathFile = vm["outfile"].as<std::string>();
    if(vm.count("generations")) {
        cfg.terminateType = tsp::TerminateType::GENERATIONS;
        cfg.generationCount = vm["generations"].as<unsigned int>();
    }
    if(vm.count("population"))
        cfg.gaSettings.populationSize = vm["population"].as<unsigned int>();
    if(vm.count("start"))
        cfg.gaSettings.startNode = vm["start"].as<unsigned int>();
    if(vm.count("elitism"))
        cfg.gaSettings.elitismRate = vm["elitism"].as<double>();
    if(vm.count("mutation"))
        cfg.gaSettings.mutationChance = vm["mutation"].as<double>();
    if(vm.count("fitness"))
        cfg.gaSettings.fitnessPow = vm["fitness"].as<unsigned int>();
    if(vm.count("time")) {
        cfg.terminateType = tsp::TerminateType::TIME;
        cfg.duration = tsp::durationFromStr(vm["time"].as<std::string>());
    }

    return 0;
}

static void exchangeConfig()
{
    if(ex == NULL)
        return;

    LOG_ALWS << "Process " << ex->getRank() << " READY\n";

    ex->broadcastConfig(cfg);
    ex->setExchangeCount(cfg.exchangeRate * cfg.gaSettings.populationSize);

    return;
}

static void printParameters()
{
    LOG_INFO << "Parameters\n";
    LOG_INFO << "  graph file: " << cfg.graphFile << "\n";
    LOG_INFO << "  path file: " << cfg.pathFile << "\n";
    LOG_INFO << "  generation count: " << cfg.generationCount << "\n";
    LOG_INFO << "  duration: " << boost::posix_time::to_simple_string(
                 cfg.duration) << "\n";
    LOG_INFO << "  population size: " << cfg.gaSettings.populationSize << "\n";
    LOG_INFO << "  start node: " << cfg.gaSettings.startNode << "\n";
    LOG_INFO << "  elitism rate: " << cfg.gaSettings.elitismRate << "\n";
    LOG_INFO << "  mutation chance: " << cfg.gaSettings.mutationChance << "\n";
    LOG_INFO << "  fitness power: " << cfg.gaSettings.fitnessPow << "\n";
    LOG_INFO << "  exchange rate: " << cfg.exchangeRate << "\n";
}

static void printCurrentGen(tsp::GeneticAnalyser &analyser)
{
    LOG_INFO << "  Best Distance: " << analyser.getBestDistance(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Mean Distance: " << analyser.getMeanDistance(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Best Fitness: " << analyser.getBestFitness(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Mean Fitness: " << analyser.getMeanFitness(
                 solver.getPopulation()) << "\n";
    LOG_INFO << "  Best Norm. Fitness: " << analyser.getBestNormalizedFitness(
                 solver.getPopulation()) << "\n";
}

static int loadGraph()
{
    LOG_INFO << "Loading Graph ...\n";
    if(!tsp::GraphSerializer::load(graph, cfg.graphFile)) {
        LOG_ERR << " Failed\n";
        return 1;
    }

    return 0;
}

static void initStats()
{
    stats.nodeCount = graph.size();
    if(cfg.terminateType == tsp::TerminateType::GENERATIONS) {
        stats.genCount = cfg.generationCount;
        stats.timePerGen.resize(stats.genCount);
        stats.distancePerGen.resize(stats.genCount);
    } else {
        stats.genCount = 0;
        stats.timePerGen.resize(512);
        stats.distancePerGen.resize(512);
    }
}

static bool checkTermCond()
{
    bool terminate = true;
    switch(cfg.terminateType) {
    case tsp::TerminateType::GENERATIONS:
        terminate = currentGen >= cfg.generationCount;
        break;
    case tsp::TerminateType::TIME:
        terminate = watch.interim() >= cfg.duration;
        if(ex != NULL) {
            terminate = ex->broadcastTermCond(terminate);
        }
        break;
    default:
        assert(false);
    }

    return terminate;
}

static void catchStats(tsp::GeneticAnalyser &analyser)
{
    // keep vectors large enough
    if(currentGen >= stats.timePerGen.size()) {
        stats.timePerGen.resize(stats.timePerGen.size() * 2);
        stats.distancePerGen.resize(stats.distancePerGen.size() * 2);
    }

    stats.timePerGen[currentGen] = watch.interim();
    stats.distancePerGen[currentGen] = analyser.getBestDistance(solver.getPopulation());
}

static void finalizeStats(tsp::GeneticAnalyser &analyser)
{
    stats.genCount = currentGen;
    stats.timePerGen.resize(currentGen);
    stats.distancePerGen.resize(currentGen);
    stats.finalDistance = analyser.getBestDistance(solver.getPopulation());
    stats.totalTime = duration;

    //exchange stats
    if (ex != NULL)
    {
        std::vector<std::vector<double>> distlist;
        ex->gatherDistPerGen(stats.distancePerGen, distlist);

        // find the minimal distance for each generation
        for(unsigned i = 0; i < stats.genCount; ++i)
        {
            double min = -1;
            for(unsigned int j = 0; j < distlist.size(); ++j)
            {
                if(min < 0 || distlist[j][i] < min)
                    min = distlist[j][i];
            }
            stats.distancePerGen[i] = min;
        }
    }

    if (IS_MASTER)
        tsp::StatisticsSerializer::save(stats, "statistics.json");
}

static void runAlgorithm()
{
    LOG_MAST << "Solving TSP ...\n";
    LOG_INFO << "Initializing solver...";
    solver.setSettings(cfg.gaSettings);
    solver.init();

    tsp::GeneticAnalyser analyser(graph);
    watch.start();

    while(!checkTermCond()) {

        LOG_INFO << "Calculating Generation " << currentGen + 1 << "...\n";
        solver.nextGeneration();

        if(ex != NULL) {
            LOG_INFO << "Exchanging individuals ...\n";
            ex->exchangePopulation(solver.getPopulation());
        }

        LOG_INFO << "Updating fitness ...\n";
        solver.updateFitness();

        catchStats(analyser);
        printCurrentGen(analyser);
        ++currentGen;

        if(IS_MASTER) {
            std::cout << ".";
            std::cout.flush();
        }
    }

    std::cout << "\n";

    if(ex != NULL) {
        LOG_INFO << "Gathering best individuals ...\n";
        ex->gatherPopulation(solver.getPopulation());

        if(ex->isMaster()) {
            solver.updateFitness();
            LOG_MAST << "Received " << solver.getPopulation().getIndividuals().size() <<
                     " solutions\n";
            for(unsigned int i = 0; i < solver.getPopulation().getIndividuals().size(); ++i)
                LOG_MAST << "  solution " << i << ": " << analyser.getDistance(
                             solver.getPopulation().getIndividuals()[i]) << "\n";
        }
    }

    duration = watch.stop();
    finalizeStats(analyser);

    LOG_MAST << "=============================\n";
    LOG_MAST << "Final Results\n";
    LOG_MAST << "  Best Distance: " <<  analyser.getBestDistance(
                 solver.getPopulation()) << "\n";
    LOG_MAST << "  Time: " << boost::posix_time::to_simple_string(duration) << "\n";
    LOG_MAST << "  Generations: " << currentGen << "\n";
}

static int savePath()
{

    if(ex != NULL && !ex->isMaster())
        return 0;

    LOG_MAST << "Saving Path ...\n";
    if(!tsp::PathSerializer::save(
                solver.getPopulation().getBestIndividual().getPath(),
                cfg.pathFile)) {
        LOG_ERR << " Failed\n";
        return 1;
    }

    return 0;
}

int main(int argc, char **argv)
{
    tsp::Random::shakeRNG();

    int ret = parseArguments(argc, argv);
    if(ret)
        return ret;

    exchangeConfig();
    printParameters();

    ret = loadGraph();
    if(ret)
        return ret;

    initStats();
    runAlgorithm();

    ret = savePath();
    if(ret)
        return ret;

    if(ex != NULL)
        delete ex;

    return 0;
}
<|endoftext|>


<commit_before>// 4.exercise.17.cpp
//
// Write a program that finds the min, max and the mode of a sequence of
// strings.

#include "std_lib_facilities.h"

int main()
{
    vector<string> sample;

    cout << "Write a series of strings (end the input with Ctrl+D): ";
    string element {""};
    while (cin >> element)
        sample.push_back(element);

    if (sample.size() != 0) {
        // Vector to store different values from sample
        vector<string> values;
        // Vector to store the times each element from values appears in sample
        vector<int> times;

        // A sort sample simplifies the problem
        sort(sample);
        // First element in sample
        values.push_back(sample[0]);
        times.push_back(1);
        // Get every unique element and the times ir appears in sample
        for (size_t i=1; i<sample.size(); ++i) {
            if (sample[i] == sample[i-1]) {
                ++times[times.size()-1];
            } else {
                values.push_back(sample[i]);
                times.push_back(1);
            }
        }

        // min nad max
        string min {sample[0]};
        string max {sample[0]};
        for ( string s : sample ) {
            if ( s < min ) min = s;
            if ( s > max ) max = s;
        }
        // Time to get the max in times
        // What if there are more than a mode (various elements that appers
        // the same amount of times, and that amount is the maximum)? I think
        // that we still don't know enough to solve that situation in
        // an efficent way.
        int max_times {0};
        int idx {0};
        for (size_t i=0; i<times.size(); ++i) {
            if (times[i] > max_times) {
                max_times = times[i];
                idx = i;
            }
        }

        cout << "The min string in the sample is: " << min << '\n';
        cout << "The max string in the sample is: " << max << '\n';
        cout << "The mode of the sample is " << values[idx] << " with "
            << times[idx] << " appareances.\n";

    } else {
        cout << "No data introduced.\n";
    }

    return 0;
}

<commit_msg>Slight changes on exercise 17 from chapter 4<commit_after>// 4.exercise.17.cpp
//
// Write a program that finds the min, max and the mode of a sequence of
// strings.

#include "std_lib_facilities.h"

int main()
{
    vector<string> sample;

    cout << "Write a series of strings (end the input with Ctrl+D): ";
    string element {""};
    while (cin >> element)
        sample.push_back(element);

    if (sample.size() != 0) {
        // Vector to store different values from sample
        vector<string> values;
        // Vector to store the times each element from values appears in sample
        vector<int> times;

        // A sort sample simplifies the problem
        sort(sample);
        // First element in sample
        values.push_back(sample[0]);
        times.push_back(1);
        // Get every unique element and the times ir appears in sample
        for (size_t i=1; i<sample.size(); ++i) {
            if (sample[i] == sample[i-1]) {
                ++times[times.size()-1];
            } else {
                values.push_back(sample[i]);
                times.push_back(1);
            }
        }

        // min nad max
        string min {sample[0]};
        string max {sample[0]};
        for (string s : sample) {
            if (s < min) min = s;
            if (s > max) max = s;
        }
        // Time to get the max in times
        // What if there are more than a mode (various elements that appers
        // the same amount of times, and that amount is the maximum)? I think
        // that we still don't know enough to solve that situation in
        // an efficent way.
        int max_times {0};
        int idx {0};
        for (size_t i=0; i<times.size(); ++i) {
            if (times[i] > max_times) {
                max_times = times[i];
                idx = i;
            }
        }

        cout << "The min string in the sample is: \"" << min << "\"\n";
        cout << "The max string in the sample is: \"" << max << "\"\n";
        cout << "The mode of the sample is \"" << values[idx] << "\" with "
            << times[idx] << " appareances.\n";

    } else {
        cout << "No data introduced.\n";
    }

    return 0;
}

<|endoftext|>


<commit_before>/******************************************************************************\
* File:          lexers.cpp
* Purpose:       Implementation of exLexers classes
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2008 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/stdpaths.h>
#include <wx/tokenzr.h>
#include <wx/stc/stc.h>
#include <wx/textfile.h>
#include <wx/extension/extension.h>

exLexers::exLexers()
  : m_FileName(
#ifdef EX_PORTABLE
      wxPathOnly(wxStandardPaths::Get().GetExecutablePath()),
#else
      wxStandardPaths::Get().GetUserDataDir(),
#endif
      "lexers.xml",
      false)
{
}

const exLexer exLexers::FindByFileName(const wxFileName& filename) const
{
  if (!filename.IsOk() || m_Lexers.empty())
  {
    return exLexer();
  }

  for (
    std::vector<exLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (exMatchesOneOf(filename, it->GetAssociations()))
    {
      return *it;
    }
  }

  return exLexer();
}

const exLexer exLexers::FindByName(const wxString& name) const
{
  if (!m_Lexers.empty())
  {
    for (
      std::vector<exLexer>::const_iterator it = m_Lexers.begin();
      it != m_Lexers.end();
      ++it)
    {
      if (name == it->GetScintillaLexer())
      {
        return *it;
      }
    }

    // We did not find a lexer, so give an error.
    // The same error is shown in exSTC::SetLexer as well.
    wxLogError("Lexer is not known: " + name);
  }

  return exLexer();
}

// TODO: Styles and Styles hex parse them here instead of at stc.
const wxString exLexers::ParseTagColourings(const wxXmlNode* node)
{
  wxString text;

  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colouring")
    {
      text +=
        child->GetAttribute("name", "0") + "=" + child->GetNodeContent() + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined colourings tag: %s on: %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void exLexers::ParseTagGlobal(const wxXmlNode* node)
{
  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "marker")
    {
      const exMarker marker(ParseTagMarker(
        child->GetAttribute("no", "0"),
        child->GetNodeContent()));

      if (marker.GetMarkerNumber() < wxSTC_STYLE_MAX &&
          marker.GetMarkerSymbol() < wxSTC_STYLE_MAX)
      {
        m_Markers.push_back(marker);
      }
      else
      {
        wxLogError("Illegal marker number: %d or symbol: %d on: %d",
          marker.GetMarkerNumber(),
          marker.GetMarkerSymbol(),
          child->GetLineNumber());
      }
    }
    else if (child->GetName() == "style")
    {
      m_Styles.push_back(child->GetAttribute("no", "0") + "=" + child->GetNodeContent());
    }
    else if (child->GetName() == "hex")
    {
      m_StylesHex.push_back(child->GetAttribute("no", "0") + "=" + child->GetNodeContent());
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined global tag: %s on: %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }
}

const exLexer exLexers::ParseTagLexer(const wxXmlNode* node)
{
  exLexer lexer;
  lexer.m_ScintillaLexer = node->GetAttribute("name", "cpp");
  lexer.m_Associations = node->GetAttribute("extensions", "*.cpp");

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colourings")
    {
      lexer.m_Colourings = ParseTagColourings(child);
    }
    else if (child->GetName() == "keywords")
    {
      lexer.SetKeywords(child->GetNodeContent());
    }
    else if (child->GetName() == "properties")
    {
      lexer.m_Properties = ParseTagProperties(child);
    }
    else if (child->GetName() == "comments")
    {
      lexer.m_CommentBegin = child->GetAttribute("begin", "");
      lexer.m_CommentBegin2 = child->GetAttribute("begin2", "");
      lexer.m_CommentEnd = child->GetAttribute("end", "");
      lexer.m_CommentEnd2 = child->GetAttribute("end2", "\n");
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined lexer tag: %s on: %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return lexer;
}

const exMarker exLexers::ParseTagMarker(const wxString& number, const wxString& props)
{
  wxStringTokenizer prop_fields(props, ",");

  const wxString symbol = prop_fields.GetNextToken();

  wxColour foreground;
  wxColour background;

  if (prop_fields.HasMoreTokens())
  {
    foreground = prop_fields.GetNextToken();

    if (prop_fields.HasMoreTokens())
    {
      background = prop_fields.GetNextToken();
    }
  }

  const exMarker marker(
    atoi(number.c_str()),
    atoi(symbol.c_str()),
    foreground,
    background);

  return marker;
}

const wxString exLexers::ParseTagProperties(const wxXmlNode* node)
{
  wxString text;

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "property")
    {
      text +=
        child->GetAttribute("name", "0") + "=" + child->GetNodeContent() + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined properties tag: %s on %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

bool exLexers::Read()
{
  if (!m_FileName.FileExists())
  {
    return false;
  }

  // Initialize members.
  m_Lexers.clear();
  m_Markers.clear();
  m_Styles.clear();
  m_StylesHex.clear();

  wxXmlDocument doc;

  if (!doc.Load(m_FileName.GetFullPath()))
  {
    return false;
  }

  wxXmlNode* child = doc.GetRoot()->GetChildren();

  while (child)
  {
    if (child->GetName() == "global")
    {
      ParseTagGlobal(child);
    }
    else if (child->GetName() == "lexer")
    {
      const exLexer& lexer = ParseTagLexer(child);

      if (!lexer.GetScintillaLexer().empty())
      {
        m_Lexers.push_back(lexer);
      }
    }

    child = child->GetNext();
  }

  return true;
}
<commit_msg>there was small error in colourings attribute<commit_after>/******************************************************************************\
* File:          lexers.cpp
* Purpose:       Implementation of exLexers classes
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 2008 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/stdpaths.h>
#include <wx/tokenzr.h>
#include <wx/stc/stc.h>
#include <wx/textfile.h>
#include <wx/extension/extension.h>

exLexers::exLexers()
  : m_FileName(
#ifdef EX_PORTABLE
      wxPathOnly(wxStandardPaths::Get().GetExecutablePath()),
#else
      wxStandardPaths::Get().GetUserDataDir(),
#endif
      "lexers.xml",
      false)
{
}

const exLexer exLexers::FindByFileName(const wxFileName& filename) const
{
  if (!filename.IsOk() || m_Lexers.empty())
  {
    return exLexer();
  }

  for (
    std::vector<exLexer>::const_iterator it = m_Lexers.begin();
    it != m_Lexers.end();
    ++it)
  {
    if (exMatchesOneOf(filename, it->GetAssociations()))
    {
      return *it;
    }
  }

  return exLexer();
}

const exLexer exLexers::FindByName(const wxString& name) const
{
  if (!m_Lexers.empty())
  {
    for (
      std::vector<exLexer>::const_iterator it = m_Lexers.begin();
      it != m_Lexers.end();
      ++it)
    {
      if (name == it->GetScintillaLexer())
      {
        return *it;
      }
    }

    // We did not find a lexer, so give an error.
    // The same error is shown in exSTC::SetLexer as well.
    wxLogError("Lexer is not known: " + name);
  }

  return exLexer();
}

// TODO: Styles and Styles hex parse them here instead of at stc.
const wxString exLexers::ParseTagColourings(const wxXmlNode* node)
{
  wxString text;

  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colouring")
    {
      text +=
        child->GetAttribute("no", "0") + "=" + child->GetNodeContent() + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined colourings tag: %s on: %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

void exLexers::ParseTagGlobal(const wxXmlNode* node)
{
  wxXmlNode* child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "marker")
    {
      const exMarker marker(ParseTagMarker(
        child->GetAttribute("no", "0"),
        child->GetNodeContent()));

      if (marker.GetMarkerNumber() < wxSTC_STYLE_MAX &&
          marker.GetMarkerSymbol() < wxSTC_STYLE_MAX)
      {
        m_Markers.push_back(marker);
      }
      else
      {
        wxLogError("Illegal marker number: %d or symbol: %d on: %d",
          marker.GetMarkerNumber(),
          marker.GetMarkerSymbol(),
          child->GetLineNumber());
      }
    }
    else if (child->GetName() == "style")
    {
      m_Styles.push_back(child->GetAttribute("no", "0") + "=" + child->GetNodeContent());
    }
    else if (child->GetName() == "hex")
    {
      m_StylesHex.push_back(child->GetAttribute("no", "0") + "=" + child->GetNodeContent());
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined global tag: %s on: %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }
}

const exLexer exLexers::ParseTagLexer(const wxXmlNode* node)
{
  exLexer lexer;
  lexer.m_ScintillaLexer = node->GetAttribute("name", "cpp");
  lexer.m_Associations = node->GetAttribute("extensions", "*.cpp");

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "colourings")
    {
      lexer.m_Colourings = ParseTagColourings(child);
    }
    else if (child->GetName() == "keywords")
    {
      lexer.SetKeywords(child->GetNodeContent());
    }
    else if (child->GetName() == "properties")
    {
      lexer.m_Properties = ParseTagProperties(child);
    }
    else if (child->GetName() == "comments")
    {
      lexer.m_CommentBegin = child->GetAttribute("begin", "");
      lexer.m_CommentBegin2 = child->GetAttribute("begin2", "");
      lexer.m_CommentEnd = child->GetAttribute("end", "");
      lexer.m_CommentEnd2 = child->GetAttribute("end2", "\n");
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined lexer tag: %s on: %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return lexer;
}

const exMarker exLexers::ParseTagMarker(const wxString& number, const wxString& props)
{
  wxStringTokenizer prop_fields(props, ",");

  const wxString symbol = prop_fields.GetNextToken();

  wxColour foreground;
  wxColour background;

  if (prop_fields.HasMoreTokens())
  {
    foreground = prop_fields.GetNextToken();

    if (prop_fields.HasMoreTokens())
    {
      background = prop_fields.GetNextToken();
    }
  }

  const exMarker marker(
    atoi(number.c_str()),
    atoi(symbol.c_str()),
    foreground,
    background);

  return marker;
}

const wxString exLexers::ParseTagProperties(const wxXmlNode* node)
{
  wxString text;

  wxXmlNode *child = node->GetChildren();

  while (child)
  {
    if (child->GetName() == "property")
    {
      text +=
        child->GetAttribute("name", "0") + "=" + child->GetNodeContent() + wxTextFile::GetEOL();
    }
    else if (child->GetName() == "comment")
    {
      // Ignore comments.
    }
    else
    {
      wxLogError("Undefined properties tag: %s on %d", child->GetName().c_str(), child->GetLineNumber());
    }

    child = child->GetNext();
  }

  return text;
}

bool exLexers::Read()
{
  if (!m_FileName.FileExists())
  {
    return false;
  }

  // Initialize members.
  m_Lexers.clear();
  m_Markers.clear();
  m_Styles.clear();
  m_StylesHex.clear();

  wxXmlDocument doc;

  if (!doc.Load(m_FileName.GetFullPath()))
  {
    return false;
  }

  wxXmlNode* child = doc.GetRoot()->GetChildren();

  while (child)
  {
    if (child->GetName() == "global")
    {
      ParseTagGlobal(child);
    }
    else if (child->GetName() == "lexer")
    {
      const exLexer& lexer = ParseTagLexer(child);

      if (!lexer.GetScintillaLexer().empty())
      {
        m_Lexers.push_back(lexer);
      }
    }

    child = child->GetNext();
  }

  return true;
}
<|endoftext|>


<commit_before>/*
 * This program is a Proof of Concept for enhancement of Futures in order to:
 * - support Future dependencies (callbacks)
 * - support Futures grouping
 *
 * The constraints:
 * - limit extra code
 * - limit extra time
 * - support both Future and FakeFuture
 * - compatibility with current usage of futures
 *
 * It just uses an Arduino UNO with USB console.
 */

// Possible ways for callbacks:
// - one or more listener ABC with virtual method(s) for various future changes
//		- provided at construction time (additional args with default nullptr)
//	+ easy to implement
//	- virtual overhead of code size and speed (particularly from inside ISR)
// - one functor on all Future and FakeFuture templates
//		- default functor type (empty)
//		- default arg value
//	+ impact size/speed only when not empty and to the strict minimum
//	- much harder to implement properly

#include <fastarduino/future.h>
#include <fastarduino/array.h>

#include <fastarduino/time.h>
#include <fastarduino/uart.h>
#include <fastarduino/iomanip.h>
#include <fastarduino/flash.h>

#include <fastarduino/tests/assertions.h>

// Register vector for UART (used for debug)
REGISTER_UATX_ISR(0)

#define REAL_FUTURE

// Example starts here
//=====================

using namespace future;
using namespace streams;
using namespace containers;

static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128;
static char output_buffer[OUTPUT_BUFFER_SIZE];

#ifdef REAL_FUTURE
#define ABSTRACTFUTURE AbstractFuture
#define FUTURE Future
#else
#define ABSTRACTFUTURE AbstractFakeFuture
#define FUTURE FakeFuture
#endif

struct FutureListener : FutureStatusListener<ABSTRACTFUTURE>, FutureOutputListener<ABSTRACTFUTURE>
{
	explicit FutureListener(ostream& out) : out_{out} {}

	void on_status_change(UNUSED const ABSTRACTFUTURE& future, FutureStatus new_status) override
	{
		out_ << F("on_status_change() status = ") << new_status << endl;
	}
	void on_output_change(UNUSED const ABSTRACTFUTURE& future, uint8_t* output_data, uint8_t* output_current) override
	{
		out_	<< F("on_output_change() data = ") << hex << output_data << F(", current = ")
				<< hex << output_current << endl;
	}

	ostream& out_;
};

class MyFuture : public FUTURE<uint32_t, uint8_t>
{
	using PARENT = FUTURE<uint32_t, uint8_t>;
	static constexpr uint8_t REG_INDEX = 0x34;

public:
	MyFuture(FutureListener& listener) : PARENT{REG_INDEX, &listener, &listener} {}
	MyFuture(MyFuture&&) = default;
	MyFuture& operator=(MyFuture&&) = default;
};

struct UpdateRegister
{
	UpdateRegister(uint8_t reg_index)
	{
		data[0] = data[1] = reg_index;
	}

	uint8_t data[3] = {0 ,0, 0};
};
class UpdateRegisterFuture : public FUTURE<uint8_t, UpdateRegister>, public FutureOutputListener<ABSTRACTFUTURE>
{
	using PARENT = FUTURE<uint8_t, UpdateRegister>;

public:
	UpdateRegisterFuture(uint8_t reg_index, uint8_t set_mask)
		:	PARENT{UpdateRegister{reg_index}, nullptr, this}, set_mask_{set_mask} {}
	UpdateRegisterFuture(UpdateRegisterFuture&&) = default;
	UpdateRegisterFuture& operator=(UpdateRegisterFuture&&) = default;

private:
	void on_output_change(
		UNUSED const ABSTRACTFUTURE& future, UNUSED uint8_t* output_data, uint8_t* output_current) override
	{
		// Only one call expected, directly get output value and change it
		uint8_t value = *(output_current - 1);
		value |= set_mask_;
		get_input().data[2] = value;
	}

	uint8_t set_mask_;
};

template<uint8_t SIZE> using GROUP = FuturesGroup<ABSTRACTFUTURE, SIZE>;

class MyGroup : public GROUP<2>
{
	using PARENT = GROUP<2>;
public:
	MyGroup(FutureListener& listener) : PARENT{{&f1_, &f2_}}, f1_{listener}, f2_{listener} {}

	MyFuture& get_f1()
	{
		return f1_;
	}

	MyFuture& get_f2()
	{
		return f2_;
	}

private:
	MyFuture f1_;
	MyFuture f2_;
};

int main() __attribute__((OS_main));
int main()
{
	board::init();
	// Enable interrupts at startup time
	sei();

	// Initialize debugging output
	serial::hard::UATX<board::USART::USART0> uart{output_buffer};
	uart.begin(115200);
	ostream out = uart.out();
	out << boolalpha << showbase;

	FutureListener listener{out};

	// Start feeding future and check output
	MyFuture f1{listener};
	out << F("set_future_value(0x11)") << endl;
	f1.set_future_value_(uint8_t(0x11));

	out << F("set_future_value(0x22)") << endl;
	f1.set_future_value_(uint8_t(0x22));

	out << F("set_future_value(0x33)") << endl;
	f1.set_future_value_(uint8_t(0x33));

	out << F("set_future_value(0x44)") << endl;
	f1.set_future_value_(uint8_t(0x44));

	out << F("f1.status() = ") << f1.status() << endl;
	uint32_t result = 0;
	out << F("f1.get(result) = ") << f1.get(result) << endl;
	out << F("result = ") << hex << result << endl;

	// Start feeding future, force error and check output
	MyFuture f2{listener};
	f2.set_future_value_(uint8_t(0x55));
	f2.set_future_finish_();
	f2.set_future_error_(-10);
	out << F("f2.status() = ") << f2.status() << endl;
	out << F("f2.error() = ") << dec << f2.error() << endl;

	UpdateRegisterFuture f3{0xF7, 0x12};
	uint8_t data = 0;
	out << F("f3.get_storage_value_(data) = ") << f3.get_storage_value_(data) << endl;
	out << F("data = ") << hex << data << endl;
	out << F("f3.set_future_value_(0x40) = ") << f3.set_future_value_(uint8_t(0x40)) << endl;
	out << F("f3.get_storage_value_(data) = ") << f3.get_storage_value_(data) << endl;
	out << F("data = ") << hex << data << endl;
	out << F("f3.get_storage_value_(data) = ") << f3.get_storage_value_(data) << endl;
	out << F("data = ") << hex << data << endl;
	out << F("f3.status() = ") << f3.status() << endl;

	// Group of futures
	out << F("Testing group of futures #1") << endl;
	MyGroup group{listener};
	out << F("group.status() = ") << group.status() << endl;
	out << F("set_future_value(0x11)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x11));
	out << F("group.status() = ") << group.status() << endl;

	out << F("set_future_value(0x22)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x22));
	out << F("group.status() = ") << group.status() << endl;

	out << F("set_future_value(0x33)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x33));
	out << F("group.status() = ") << group.status() << endl;

	out << F("set_future_value(0x44)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x44));
	out << F("group.status() = ") << group.status() << endl;

	out << F("f1.status() = ") << group.get_f1().status() << endl;
	result = 0;
	out << F("f1.get(result) = ") << group.get_f1().get(result) << endl;
	out << F("result = ") << hex << result << endl;

	out << F("Testing group of futures #2") << endl;
	group.get_f2().set_future_value_(uint8_t(0x55));
	out << F("group.status() = ") << group.status() << endl;
	group.get_f2().set_future_finish_();
	out << F("group.status() = ") << group.status() << endl;
	group.get_f2().set_future_error_(-10);
	out << F("group.status() = ") << group.status() << endl;
	out << F("f2.status() = ") << group.get_f2().status() << endl;
	out << F("f2.error() = ") << dec << group.get_f2().error() << endl;
	out << F("group.error() = ") << group.error() << endl;
}
<commit_msg>Remove useless includes<commit_after>/*
 * This program is a Proof of Concept for enhancement of Futures in order to:
 * - support Future dependencies (callbacks)
 * - support Futures grouping
 *
 * The constraints:
 * - limit extra code
 * - limit extra time
 * - support both Future and FakeFuture
 * - compatibility with current usage of futures
 *
 * It just uses an Arduino UNO with USB console.
 */

// Possible ways for callbacks:
// - one or more listener ABC with virtual method(s) for various future changes
//		- provided at construction time (additional args with default nullptr)
//	+ easy to implement
//	- virtual overhead of code size and speed (particularly from inside ISR)
// - one functor on all Future and FakeFuture templates
//		- default functor type (empty)
//		- default arg value
//	+ impact size/speed only when not empty and to the strict minimum
//	- much harder to implement properly

#include <fastarduino/future.h>

#include <fastarduino/uart.h>
#include <fastarduino/iomanip.h>
#include <fastarduino/flash.h>

// Register vector for UART (used for debug)
REGISTER_UATX_ISR(0)

#define REAL_FUTURE

// Example starts here
//=====================

using namespace future;
using namespace streams;
using namespace containers;

static constexpr const uint8_t OUTPUT_BUFFER_SIZE = 128;
static char output_buffer[OUTPUT_BUFFER_SIZE];

#ifdef REAL_FUTURE
#define ABSTRACTFUTURE AbstractFuture
#define FUTURE Future
#else
#define ABSTRACTFUTURE AbstractFakeFuture
#define FUTURE FakeFuture
#endif

struct FutureListener : FutureStatusListener<ABSTRACTFUTURE>, FutureOutputListener<ABSTRACTFUTURE>
{
	explicit FutureListener(ostream& out) : out_{out} {}

	void on_status_change(UNUSED const ABSTRACTFUTURE& future, FutureStatus new_status) override
	{
		out_ << F("on_status_change() status = ") << new_status << endl;
	}
	void on_output_change(UNUSED const ABSTRACTFUTURE& future, uint8_t* output_data, uint8_t* output_current) override
	{
		out_	<< F("on_output_change() data = ") << hex << output_data << F(", current = ")
				<< hex << output_current << endl;
	}

	ostream& out_;
};

class MyFuture : public FUTURE<uint32_t, uint8_t>
{
	using PARENT = FUTURE<uint32_t, uint8_t>;
	static constexpr uint8_t REG_INDEX = 0x34;

public:
	MyFuture(FutureListener& listener) : PARENT{REG_INDEX, &listener, &listener} {}
	MyFuture(MyFuture&&) = default;
	MyFuture& operator=(MyFuture&&) = default;
};

struct UpdateRegister
{
	UpdateRegister(uint8_t reg_index)
	{
		data[0] = data[1] = reg_index;
	}

	uint8_t data[3] = {0 ,0, 0};
};
class UpdateRegisterFuture : public FUTURE<uint8_t, UpdateRegister>, public FutureOutputListener<ABSTRACTFUTURE>
{
	using PARENT = FUTURE<uint8_t, UpdateRegister>;

public:
	UpdateRegisterFuture(uint8_t reg_index, uint8_t set_mask)
		:	PARENT{UpdateRegister{reg_index}, nullptr, this}, set_mask_{set_mask} {}
	UpdateRegisterFuture(UpdateRegisterFuture&&) = default;
	UpdateRegisterFuture& operator=(UpdateRegisterFuture&&) = default;

private:
	void on_output_change(
		UNUSED const ABSTRACTFUTURE& future, UNUSED uint8_t* output_data, uint8_t* output_current) override
	{
		// Only one call expected, directly get output value and change it
		uint8_t value = *(output_current - 1);
		value |= set_mask_;
		get_input().data[2] = value;
	}

	uint8_t set_mask_;
};

template<uint8_t SIZE> using GROUP = FuturesGroup<ABSTRACTFUTURE, SIZE>;

class MyGroup : public GROUP<2>
{
	using PARENT = GROUP<2>;
public:
	MyGroup(FutureListener& listener) : PARENT{{&f1_, &f2_}}, f1_{listener}, f2_{listener} {}

	MyFuture& get_f1()
	{
		return f1_;
	}

	MyFuture& get_f2()
	{
		return f2_;
	}

private:
	MyFuture f1_;
	MyFuture f2_;
};

int main() __attribute__((OS_main));
int main()
{
	board::init();
	// Enable interrupts at startup time
	sei();

	// Initialize debugging output
	serial::hard::UATX<board::USART::USART0> uart{output_buffer};
	uart.begin(115200);
	ostream out = uart.out();
	out << boolalpha << showbase;

	FutureListener listener{out};

	// Start feeding future and check output
	MyFuture f1{listener};
	out << F("set_future_value(0x11)") << endl;
	f1.set_future_value_(uint8_t(0x11));

	out << F("set_future_value(0x22)") << endl;
	f1.set_future_value_(uint8_t(0x22));

	out << F("set_future_value(0x33)") << endl;
	f1.set_future_value_(uint8_t(0x33));

	out << F("set_future_value(0x44)") << endl;
	f1.set_future_value_(uint8_t(0x44));

	out << F("f1.status() = ") << f1.status() << endl;
	uint32_t result = 0;
	out << F("f1.get(result) = ") << f1.get(result) << endl;
	out << F("result = ") << hex << result << endl;

	// Start feeding future, force error and check output
	MyFuture f2{listener};
	f2.set_future_value_(uint8_t(0x55));
	f2.set_future_finish_();
	f2.set_future_error_(-10);
	out << F("f2.status() = ") << f2.status() << endl;
	out << F("f2.error() = ") << dec << f2.error() << endl;

	UpdateRegisterFuture f3{0xF7, 0x12};
	uint8_t data = 0;
	out << F("f3.get_storage_value_(data) = ") << f3.get_storage_value_(data) << endl;
	out << F("data = ") << hex << data << endl;
	out << F("f3.set_future_value_(0x40) = ") << f3.set_future_value_(uint8_t(0x40)) << endl;
	out << F("f3.get_storage_value_(data) = ") << f3.get_storage_value_(data) << endl;
	out << F("data = ") << hex << data << endl;
	out << F("f3.get_storage_value_(data) = ") << f3.get_storage_value_(data) << endl;
	out << F("data = ") << hex << data << endl;
	out << F("f3.status() = ") << f3.status() << endl;

	// Group of futures
	out << F("Testing group of futures #1") << endl;
	MyGroup group{listener};
	out << F("group.status() = ") << group.status() << endl;
	out << F("set_future_value(0x11)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x11));
	out << F("group.status() = ") << group.status() << endl;

	out << F("set_future_value(0x22)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x22));
	out << F("group.status() = ") << group.status() << endl;

	out << F("set_future_value(0x33)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x33));
	out << F("group.status() = ") << group.status() << endl;

	out << F("set_future_value(0x44)") << endl;
	group.get_f1().set_future_value_(uint8_t(0x44));
	out << F("group.status() = ") << group.status() << endl;

	out << F("f1.status() = ") << group.get_f1().status() << endl;
	result = 0;
	out << F("f1.get(result) = ") << group.get_f1().get(result) << endl;
	out << F("result = ") << hex << result << endl;

	out << F("Testing group of futures #2") << endl;
	group.get_f2().set_future_value_(uint8_t(0x55));
	out << F("group.status() = ") << group.status() << endl;
	group.get_f2().set_future_finish_();
	out << F("group.status() = ") << group.status() << endl;
	group.get_f2().set_future_error_(-10);
	out << F("group.status() = ") << group.status() << endl;
	out << F("f2.status() = ") << group.get_f2().status() << endl;
	out << F("f2.error() = ") << dec << group.get_f2().error() << endl;
	out << F("group.error() = ") << group.error() << endl;
}
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS dbodf11 (1.14.76); FILE MERGED 2008/04/01 11:11:30 oj 1.14.76.7: RESYNC: (1.17-1.18); FILE MERGED 2008/01/31 07:47:45 oj 1.14.76.6: #i85757# as odf 1.2 form 2008/01/28 12:29:33 oj 1.14.76.5: namespace corrected 2007/12/19 12:49:15 oj 1.14.76.4: RESYNC: (1.16-1.17); FILE MERGED 2007/10/23 11:47:07 oj 1.14.76.3: merge 2007/10/22 13:03:06 oj 1.14.76.2: RESYNC: (1.14-1.16); FILE MERGED 2007/02/02 12:09:13 oj 1.14.76.1: export ODF format<commit_after><|endoftext|>


<commit_before><commit_msg>An important distinction...<commit_after><|endoftext|>


<commit_before><commit_msg>Update threshold in qbvh hit test loop.<commit_after><|endoftext|>


<commit_before>// $Id$
/*
 * Macro to overlay the histograms produced by
 * HLT/QA/tasks/macros/drawTHnSparse.C
 *
 * It assumes a file where the input is specified in
 * the following format:
 *
 * number of files
 * file1 legend1
 * file2 legend2
 * ...
 * ...
 *
 * @ingroup alihlt_qa
 * @author Kalliopi.Kanaki@ift.uib.no
 */
void overlayPlots(const char* option="HLT"/* or "OFF" */, string fi="files.txt"){

  gROOT->SetStyle("Plain");
  gStyle->SetPalette(1);
  gStyle->SetTitleX(gStyle->GetPadLeftMargin());

  char filenames[100];
  sprintf(filenames,"%s",fi.c_str());
  ifstream in(filenames);
  if(!in){
    printf("File %s does not exist", fi.Data());
    break;
  }
  string c;
  TString f;
  int nr_textfile = 0;

  in>>nr_textfile;
  if(!in.good()) break;
  printf("Number of files: %d\n", nr_textfile);

  const int nr_files = nr_textfile;
  TString file[nr_files];
  string cutnames[nr_files];

  nr_textfile=0;
  while(nr_textfile < nr_files){
    in >> f >> c;
    if(!in.good()) break;
    file[nr_textfile] = f;
    cutnames[nr_textfile] = c;
    Printf("\nfile %d : %s", nr_textfile, f.Data());
    nr_textfile++;

  }
  in.close();

  TCanvas *ca;
  TFile   *ff;
  TPad    *pad;
  TH1D    *g[nr_files];

  TCanvas *d = new TCanvas("d",Form("%s cut studies",option),1200,800);
  d->Divide(4,2);
  //d->Divide(3,2);

  TLegend *l = new TLegend(0.6,0.6,0.8,0.8);
  l->SetFillColor(10);
  l->SetLineColor(10);

  char cut[100];

  //for(int j=1; j<7; j++){
  for(int j=1; j<9; j++){
     for(int i=0; i<nr_files; i++){

        ff = TFile::Open(file[i].Data());
        if(!ff || ff->IsZombie()){
           printf("Non-existent, corrupted or zombie file %s\n", file[i].Data());
           return;
        }
        //ca  = (TCanvas*)ff->GetObjectUnchecked("can0");
        ca  = (TCanvas*)ff->GetObjectUnchecked("can3");
	if(!ca){
	   printf("Empty canvas in file %s.\n", file[i].Data());
	   continue;
	}
        //pad = (TPad*)ca->GetListOfPrimitives()->FindObject(Form("can0_%d",j));
        pad = (TPad*)ca->GetListOfPrimitives()->FindObject(Form("can3_%d",j));
        if(!pad){
           printf("Empty pad in canvas %s.\n", ca->GetName());
           continue;
        }
        //g[i] =(TH1D*)pad->FindObject(Form("fEvent%s_proj_%d",option,j-1));
        g[i] =(TH1D*)pad->FindObject(Form("fTrack%s_proj_%d",option,j-1));
	if(!g[i]){
	   printf("Empty histogram for i=%d, file %s.\n", i, file[i].Data());
	   continue;
	}

        d->cd(j);
        if(i==0){
	  g[i]->SetLineColor(kBlack);
	  TPaveStats *st = (TPaveStats*)g[i]->FindObject("stats");
	  st->SetTextColor(kBlack);
	  g[i]->Draw();
	}
        else {
	  g[i]->SetLineColor(i+1);
	  defineYaxisMax(g[0], g[i]);
	  g[i]->Draw("sames");
	}
        if(i>0) printStats(g[i-1], g[i]);

        ff->Close();
        sprintf( cut,"%s",cutnames[i].c_str() );
	if(j==1) l->AddEntry(g[i],cut,"l");
	else continue;
    }
    if(j==1) l->Draw("same");
  }
  return;
}

void printStats(TH1D *h1, TH1D *h2){
  gPad->Update();
  TPaveStats *st1 = (TPaveStats*)h1->FindObject("stats");
  st1->SetLineColor(0);

  gPad->Update();
  TPaveStats *st2 = (TPaveStats*)h2->FindObject("stats");
  st2->SetY2NDC(st1->GetY1NDC()-0.05);
  st2->SetY1NDC(st2->GetY2NDC()-TMath::Abs(st1->GetY1NDC()-st1->GetY2NDC()));
  st2->SetLineColor(0);
  st2->SetTextColor(h2->GetLineColor());
  st2->SetFillStyle(0);
  st2->Draw();
  return;
}

void defineYaxisMax(TH1D *h1, TH1D *h2){
  //Y axis
  if(h1->GetMaximum() > h2->GetMaximum()) h2->SetMaximum(1.1*h1->GetMaximum());
  else h1->SetMaximum(1.1*h2->GetMaximum());

  h1->SetMinimum(0);
  h2->SetMinimum(0);

  // X axis
  double xmin, xmax;
  if(h1->GetBinLowEdge(1) > h2->GetBinLowEdge(1)) xmin = h1->GetBinLowEdge(1);
  else xmin = h2->GetBinLowEdge(1);
  if(h1->GetBinLowEdge(h1->GetNbinsX()+1) > h2->GetBinLowEdge(h1->GetNbinsX()+1)) xmax = h1->GetBinLowEdge(h1->GetNbinsX()+1);
  else xmax = h2->GetBinLowEdge(h2->GetNbinsX()+1);

  h2->SetAxisRange(xmin, xmax, "X");
  return;
}
<commit_msg>- fixed a bug that didn't allow the overlaid histograms to be plotted because of a 0x0 TPaveStats pointer.   The TPaveStats object was calling functions before the respective histogram was filled. - implemented the option to comment out files in the input *txt by adding // in front of their name.   The macro checks the name of the file and skips it, if it begins with //.<commit_after>// $Id$
//
//  Macro to overlay the histograms produced by
//  HLT/QA/tasks/macros/drawTHnSparse.C
//
//  It assumes a txt file where the input is specified in
//  the following format:
//
//   number of files
//   file1 legend1
//   file2 legend2
//  //file3 legend3
//  //file4 legend4
//  ...
//  So it is possible to "comment out" a file by a // in the beginning of the name. While reading the
//  the names of the input files, the macro skips the ones that have the // in front of them.
//
//  @ingroup alihlt_qa
//  @author Kalliopi.Kanaki@ift.uib.no

void overlayPlots(const char* option="HLT"/* or "OFF" */, string fi="files.txt"){

  gROOT->SetStyle("Plain");
  gStyle->SetPalette(1);
  gStyle->SetOptStat("emr");
  gStyle->SetTitleX(gStyle->GetPadLeftMargin());

  char filenames[100];
  sprintf(filenames,"%s",fi.c_str());
  ifstream in(filenames);
  if(!in){
    printf("File %s does not exist", fi.Data());
    break;
  }
  string c;
  TString f;
  int nr_textfile = 0;

  in>>nr_textfile;
  if(!in.good()) break;
  printf("Number of files: %d\n", nr_textfile);

  const int nr_files = nr_textfile;
  TString file[nr_files];
  string cutnames[nr_files];

  nr_textfile=0;
  while(nr_textfile < nr_files){
    in >> f >> c;
    if(!in.good()) break;
    file[nr_textfile] = f;
    cutnames[nr_textfile] = c;
    if(f.BeginsWith("//")) continue;
    printf("\nfile %d : %s\n", nr_textfile, f.Data());
    nr_textfile++;
  }
  in.close();

  TCanvas *ca;
  TFile   *ff;
  TPad    *pad;
  TH1D    *g[nr_files];

  TCanvas *d = new TCanvas("d",Form("%s cut studies",option),1200,800);
  d->Divide(4,2);
  //d->Divide(3,2);

  TLegend *l = new TLegend(0.6,0.6,0.8,0.8);
  l->SetFillColor(10);
  l->SetLineColor(10);

  char cut[100];

  //for(int j=1; j<7; j++){
  for(int j=1; j<9; j++){
     for(int i=0; i<nr_files; i++){

        ff = TFile::Open(file[i].Data());
        if(!ff || ff->IsZombie()){
           printf("Non-existent, corrupted or zombie file %s\n", file[i].Data());
           return;
        }
        //ca  = (TCanvas*)ff->GetObjectUnchecked("can0");
        ca  = (TCanvas*)ff->GetObjectUnchecked("can3");
	if(!ca){
	   printf("Empty canvas in file %s.\n", file[i].Data());
	   continue;
	}
        //pad = (TPad*)ca->GetListOfPrimitives()->FindObject(Form("can0_%d",j));
        pad = (TPad*)ca->GetListOfPrimitives()->FindObject(Form("can3_%d",j));
        if(!pad){
           printf("Empty pad in canvas %s.\n", ca->GetName());
           continue;
        }
        //g[i] =(TH1D*)pad->FindObject(Form("fEvent%s_proj_%d",option,j-1));
        g[i] =(TH1D*)pad->FindObject(Form("fTrack%s_proj_%d",option,j-1));
	if(!g[i]){
	   printf("Empty histogram for i=%d, file %s.\n", i, file[i].Data());
	   continue;
	}

        d->cd(j);

        if(i==0){
	  g[i]->SetLineColor(kBlack);
	  g[i]->Draw();
	  if(option=="OFF"){
	     TPaveStats *st = (TPaveStats*)g[i]->FindObject("stats");
	     st->SetTextColor(kBlack);
	     d->Update();
	  }
	}
        else {
	  g[i]->SetLineColor(i+1);
	  defineYaxisMax(g[0], g[i]);
	  g[i]->Draw("sames");
	}
        if(i>0) printStats(g[i-1], g[i]);

        ff->Close();
        sprintf( cut,"%s",cutnames[i].c_str() );
	if(j==1) l->AddEntry(g[i],cut,"l");
	else continue;
    }
    if(j==1) l->Draw("same");
  }
  return;
}

void printStats(TH1D *h1, TH1D *h2){
  gPad->Update();
  TPaveStats *st1 = (TPaveStats*)h1->FindObject("stats");
  st1->SetLineColor(0);

  gPad->Update();
  TPaveStats *st2 = (TPaveStats*)h2->FindObject("stats");
  st2->SetY2NDC(st1->GetY1NDC()-0.05);
  st2->SetY1NDC(st2->GetY2NDC()-TMath::Abs(st1->GetY1NDC()-st1->GetY2NDC()));
  st2->SetLineColor(0);
  st2->SetTextColor(h2->GetLineColor());
  st2->SetFillStyle(0);
  st2->Draw();
  return;
}

void defineYaxisMax(TH1D *h1, TH1D *h2){
  //Y axis
  if(h1->GetMaximum() > h2->GetMaximum()) h2->SetMaximum(1.1*h1->GetMaximum());
  else h1->SetMaximum(1.1*h2->GetMaximum());

  h1->SetMinimum(0);
  h2->SetMinimum(0);

  // X axis
  double xmin, xmax;
  if(h1->GetBinLowEdge(1) > h2->GetBinLowEdge(1)) xmin = h1->GetBinLowEdge(1);
  else xmin = h2->GetBinLowEdge(1);
  if(h1->GetBinLowEdge(h1->GetNbinsX()+1) > h2->GetBinLowEdge(h1->GetNbinsX()+1)) xmax = h1->GetBinLowEdge(h1->GetNbinsX()+1);
  else xmax = h2->GetBinLowEdge(h2->GetNbinsX()+1);

  h2->SetAxisRange(xmin, xmax, "X");
  return;
}
<|endoftext|>


<commit_before>#include "core/system/imgui/performance_display.h"
#include "core/system/imgui/plot_var.h"
#include "core/utility/time/print.h"

#include <imgui/imgui.h>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/max_element.hpp>

namespace eversim { namespace core { namespace system { namespace imgui {
	using namespace utility;

	performance_display::performance_display(std::string const& name, bool visible)
		: base_window(name, visible)
	{
		flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize;
	}

	void performance_display::compact_display(bool enable)
	{
		compact = enable;
	}

	void performance_display::register_time(std::string const& name, clock::duration time)
	{
		timings[name] = time;
	}

	scoped_timer::reporter_function performance_display::get_reporter(std::string name)
	{
		return [this, name = move(name)](clock::duration time)
		{
			register_time(name, time);
		};
	}

	void performance_display::draw_content()
	{
		clock::duration sum{};

		for (auto& p : timings)
		{
			auto& name = p.first;
			auto& time = p.second;

			sum += time;

			draw_time(name, time);
		}
		ImGui::Separator();
		draw_time("sum", sum);

		timings.clear();
	}

	void performance_display::draw_time(std::string const& name, clock::duration time) const
	{
		using namespace std::chrono;
		if (compact)
		{
			ImGui::Text("%s: %s", name.c_str(), to_string(time).c_str());
		} else
		{
			const auto float_time = float(duration_cast<microseconds>(time).count())/1000.f;

			ImGui::PlotVar(name.c_str(), float_time);
		}
	}
}}}}
<commit_msg>more fancy visualisation in performance display<commit_after>#include "core/system/imgui/performance_display.h"
#include "core/system/imgui/plot_var.h"
#include "core/utility/time/print.h"

#include <imgui/imgui.h>
#include <boost/range/adaptor/map.hpp>
#include <boost/range/algorithm/max_element.hpp>
#include "core/system/imgui/bar_graph.h"
#include <vector>

namespace eversim { namespace core { namespace system { namespace imgui {
	using namespace utility;

	performance_display::performance_display(std::string const& name, bool visible)
		: base_window(name, visible)
	{
		flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize;
	}

	void performance_display::compact_display(bool enable)
	{
		compact = enable;
	}

	void performance_display::register_time(std::string const& name, clock::duration time)
	{
		timings[name] = time;
	}

	scoped_timer::reporter_function performance_display::get_reporter(std::string name)
	{
		return [this, name = move(name)](clock::duration time)
		{
			register_time(name, time);
		};
	}

	void performance_display::draw_content()
	{
		using namespace std::chrono;
		clock::duration sum{};

		if(!compact)
			ImGui::BeginBarGraph();

		std::vector<ImVec4> colors = {
			{ 1,0,0,1 },
			{ 0,1,0,1 },
			{ 1,1,0,1 },
			{ 0,0,1,1 },
			{ 1,0,1,1 },
			{ 0,1,1,1 },
			{ 1,1,1,1 }
		};

		int idx = 0;
		for (auto& p : timings)
		{
			auto& name = p.first;
			auto& time = p.second;

			sum += time;

			const auto float_time = float(duration_cast<microseconds>(time).count()) / 1000.f;

			if(!compact)
			{
				ImGui::PushStyleColor(ImGuiCol_Text, colors[idx % colors.size()]);
				ImGui::BarGraphInputValue(float_time, name);
			}

			draw_time(name, time);
			if(!compact)
			{
				ImGui::PopStyleColor();
			}

			++idx;
		}
		ImGui::Separator();
		draw_time("sum", sum);
		if (!compact)
			ImGui::EndBarGraph();

		timings.clear();
	}

	void performance_display::draw_time(std::string const& name, clock::duration time) const
	{
		using namespace std::chrono;
		if (compact)
		{
			ImGui::Text("%s: %s", name.c_str(), to_string(time).c_str());
		} else
		{
			const auto float_time = float(duration_cast<microseconds>(time).count())/1000.f;

			ImGui::PlotVar(name.c_str(), float_time);
		}
	}
}}}}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Fondazione Istituto Italiano di Tecnologia
 * Authors: Silvio Traversaro
 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
 *
 */

#include <iDynTree/Core/EigenSparseHelpers.h>
#include <iDynTree/Core/TestUtils.h>
#include <iDynTree/Core/SparseMatrix.h>
#include <cstdlib>
#include <iostream>

using namespace iDynTree;

template <iDynTree::MatrixStorageOrdering iDynTreeOrdering, Eigen::StorageOptions storageOptions>
void sparseMatrixTest()
{
    Triplets triplets;
    triplets.pushTriplet(iDynTree::Triplet(2, 0, 7));
    triplets.pushTriplet(iDynTree::Triplet(0, 1, 3));
    triplets.pushTriplet(iDynTree::Triplet(1, 0, 22));
    triplets.pushTriplet(iDynTree::Triplet(1, 4, 17));
    triplets.pushTriplet(iDynTree::Triplet(2, 1, 5));
    triplets.pushTriplet(iDynTree::Triplet(2, 3, 1));
    triplets.pushTriplet(iDynTree::Triplet(4, 2, 14));
    triplets.pushTriplet(iDynTree::Triplet(4, 4, 8));

    SparseMatrix<iDynTreeOrdering> matrix(5, 5);
    Eigen::SparseMatrix<double, storageOptions> eig(5, 5);
    for (Triplets::const_iterator it(triplets.begin()); it != triplets.end(); ++it) {
        matrix(it->row, it->column) = it->value;
        eig.coeffRef(it->row, it->column) = it->value;
    }

    eig.makeCompressed();

    Eigen::Map<Eigen::SparseMatrix<double, storageOptions> > mapped = toEigen(matrix);

    ASSERT_IS_TRUE(mapped.rows() == eig.rows());
    ASSERT_IS_TRUE(mapped.cols() == eig.cols());
    ASSERT_IS_TRUE(mapped.nonZeros() == eig.nonZeros());

    auto mappedCoefficients = mapped.coeffs();
    auto coefficients = eig.coeffs();

    for (unsigned i = 0; i < mappedCoefficients.size(); ++i) {
        ASSERT_EQUAL_DOUBLE(mappedCoefficients.coeff(i), coefficients.coeff(i));
    }

}

int main()
{
    sparseMatrixTest<iDynTree::RowMajor, Eigen::RowMajor>();
    sparseMatrixTest<iDynTree::ColumnMajor, Eigen::ColMajor>();

    return 0;
}

<commit_msg>Fix compilation with Eigen3.3-beta2<commit_after>/*
 * Copyright (C) 2016 Fondazione Istituto Italiano di Tecnologia
 * Authors: Silvio Traversaro
 * CopyPolicy: Released under the terms of the LGPLv2.1 or later, see LGPL.TXT
 *
 */

#include <iDynTree/Core/EigenSparseHelpers.h>
#include <iDynTree/Core/TestUtils.h>
#include <iDynTree/Core/SparseMatrix.h>
#include <cstdlib>
#include <iostream>

using namespace iDynTree;

// Coeffs is not available in Eigen3.3-beta2
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1271
// Remove when we do need to support Eigen 3.3-beta2 (i.e. Ubuntu 16.04)
// anymore
template<typename ScalarType, typename SparseMatrixType>
const Eigen::Map<const Eigen::Array<ScalarType, Eigen::Dynamic, 1> > coeffs(const SparseMatrixType& mat)
{
    return Eigen::Array<ScalarType, Eigen::Dynamic, 1>::Map(mat.valuePtr(), mat.nonZeros());
}
template<typename ScalarType, typename SparseMatrixType>
Eigen::Map<Eigen::Array<ScalarType, Eigen::Dynamic, 1> > coeffs(SparseMatrixType& mat)
{
    return Eigen::Array<ScalarType, Eigen::Dynamic, 1>::Map(mat.valuePtr(), mat.nonZeros());
}

template <iDynTree::MatrixStorageOrdering iDynTreeOrdering, int storageOptions>
void sparseMatrixTest()
{
    Triplets triplets;
    triplets.pushTriplet(iDynTree::Triplet(2, 0, 7));
    triplets.pushTriplet(iDynTree::Triplet(0, 1, 3));
    triplets.pushTriplet(iDynTree::Triplet(1, 0, 22));
    triplets.pushTriplet(iDynTree::Triplet(1, 4, 17));
    triplets.pushTriplet(iDynTree::Triplet(2, 1, 5));
    triplets.pushTriplet(iDynTree::Triplet(2, 3, 1));
    triplets.pushTriplet(iDynTree::Triplet(4, 2, 14));
    triplets.pushTriplet(iDynTree::Triplet(4, 4, 8));

    SparseMatrix<iDynTreeOrdering> matrix(5, 5);
    Eigen::SparseMatrix<double, storageOptions> eig(5, 5);
    for (Triplets::const_iterator it(triplets.begin()); it != triplets.end(); ++it) {
        matrix(it->row, it->column) = it->value;
        eig.coeffRef(it->row, it->column) = it->value;
    }

    eig.makeCompressed();

    Eigen::Map<Eigen::SparseMatrix<double, storageOptions> > mapped = toEigen(matrix);

    ASSERT_IS_TRUE(mapped.rows() == eig.rows());
    ASSERT_IS_TRUE(mapped.cols() == eig.cols());
    ASSERT_IS_TRUE(mapped.nonZeros() == eig.nonZeros());

    auto mappedCoefficients = coeffs<double, Eigen::Map<Eigen::SparseMatrix<double, storageOptions>>>(mapped);
    auto coefficients = coeffs<double, Eigen::SparseMatrix<double, storageOptions> >(eig);

    for (unsigned i = 0; i < mappedCoefficients.size(); ++i) {
        ASSERT_EQUAL_DOUBLE(mappedCoefficients.coeff(i), coefficients.coeff(i));
    }

}

int main()
{
    sparseMatrixTest<iDynTree::RowMajor, Eigen::RowMajor>();
    sparseMatrixTest<iDynTree::ColumnMajor, Eigen::ColMajor>();

    return 0;
}

<|endoftext|>


<commit_before>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2017 Roman Lebedev

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef PARSER
#error PARSER must be defined
#endif

#ifndef GETDECODER
#error GETDECODER must be defined as bool
#endif

#include "decoders/RawDecoderException.h" // for RawDecoderException, ThrowRDE
#include "io/Buffer.h"                    // for Buffer, DataBuffer
#include "io/IOException.h"               // for IOException
#include "parsers/CiffParser.h"           // IWYU pragma: keep
#include "parsers/CiffParserException.h"  // IWYU pragma: keep
#include "parsers/FiffParser.h"           // IWYU pragma: keep
#include "parsers/FiffParserException.h"  // IWYU pragma: keep
#include "parsers/RawParser.h"            // IWYU pragma: keep
#include "parsers/RawParserException.h"   // IWYU pragma: keep
#include "parsers/TiffParser.h"           // IWYU pragma: keep
#include "parsers/TiffParserException.h"  // IWYU pragma: keep
#include "parsers/X3fParser.h"            // IWYU pragma: keep
#include "parsers/X3fParserException.h"   // IWYU pragma: keep
#include "tiff/TiffEntry.h"               // IWYU pragma: keep
#include <cassert>                        // for assert
#include <cstdint>                        // for uint8_t
#include <cstdio>                         // for size_t

#if GETDECODER
#include "decoders/RawDecoder.h" // IWYU pragma: keep
#endif

#define TOKENPASTE2(x, y) x##y
#define TOKENPASTE(x, y) TOKENPASTE2(x, y)

// define this function, it is only declared in rawspeed:
// for fuzzing, do not want any threading.
extern "C" int __attribute__((const)) rawspeed_get_number_of_processor_cores() {
  return 1;
}

using PARSERException = TOKENPASTE(rawspeed::PARSER, Exception);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
  assert(Data);

  const rawspeed::Buffer buffer(Data, Size);

  try {
    rawspeed::PARSER parser(&buffer);

#if GETDECODER
    parser.getDecoder();
#endif
  } catch (PARSERException&) {
    return 0;
  } catch (rawspeed::RawDecoderException&) {
    return 0;
  } catch (rawspeed::IOException&) {
    return 0;
  }

  return 0;
}
<commit_msg>Parser fuzzer: adjust caught exceptions once again :/<commit_after>/*
    RawSpeed - RAW file decoder.

    Copyright (C) 2017 Roman Lebedev

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

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

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef PARSER
#error PARSER must be defined
#endif

#ifndef GETDECODER
#error GETDECODER must be defined as bool
#endif

#include "io/Buffer.h"                  // for Buffer, DataBuffer
#include "io/IOException.h"             // for IOException
#include "parsers/CiffParser.h"         // IWYU pragma: keep
#include "parsers/FiffParser.h"         // IWYU pragma: keep
#include "parsers/RawParser.h"          // IWYU pragma: keep
#include "parsers/RawParserException.h" // for RawParserException
#include "parsers/TiffParser.h"         // IWYU pragma: keep
#include "parsers/X3fParser.h"          // IWYU pragma: keep
#include "tiff/TiffEntry.h"             // IWYU pragma: keep
#include <cassert>                      // for assert
#include <cstdint>                      // for uint8_t
#include <cstdio>                       // for size_t

#if GETDECODER
#include "decoders/RawDecoder.h"          // IWYU pragma: keep
#include "decoders/RawDecoderException.h" // for RawDecoderException, ThrowRDE
#endif

// define this function, it is only declared in rawspeed:
// for fuzzing, do not want any threading.
extern "C" int __attribute__((const)) rawspeed_get_number_of_processor_cores() {
  return 1;
}

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size);

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
  assert(Data);

  const rawspeed::Buffer buffer(Data, Size);

  try {
    rawspeed::PARSER parser(&buffer);

#if GETDECODER
    parser.getDecoder();
#endif
  } catch (rawspeed::RawParserException&) {
    return 0;
#if GETDECODER
  } catch (rawspeed::RawDecoderException&) {
    return 0;
#endif
  } catch (rawspeed::IOException&) {
    return 0;
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "catch.hpp"

#include <array>
#include <type_traits>

#include "GC/construct_array.hpp"

TEST_CASE( "Single dimension array to std::array", "[gc][construct_array]" )
{
    using arr = construct_array<int[10], std::rank<int[10]>::value >::type;
    bool result = typeid(arr) == typeid(std::array<int, 10>);

    REQUIRE(result);
}

TEST_CASE( "Multi-dimensional array to nested std::array", "[gc][construct_array]" )
{
    using arr = construct_array<int[10][10][10], std::rank<int[10][10][10]>::value >::type;

    REQUIRE(typeid(arr) == typeid(std::array<std::array<std::array<int, 10>, 10>, 10>));
}

TEST_CASE( "Non-array type to T", "[gc][construct_array]" )
{
    using arr = construct_array<int, std::rank<int>::value >::type;

    REQUIRE(typeid(arr) == typeid(int));
}

TEST_CASE( "construct_array helper type", "[gc][construct_array]" )
{
    using arr = construct_array_t<int[10]>;

    REQUIRE(typeid(arr) == typeid(std::array<int, 10>));
}
<commit_msg>Added typeinfo header to construct_array test<commit_after>#include "catch.hpp"

#include <array>
#include <type_traits>
#include <typeinfo>

#include "GC/construct_array.hpp"

TEST_CASE( "Single dimension array to std::array", "[gc][construct_array]" )
{
    using arr = construct_array<int[10], std::rank<int[10]>::value >::type;
    bool result = typeid(arr) == typeid(std::array<int, 10>);

    REQUIRE(result);
}

TEST_CASE( "Multi-dimensional array to nested std::array", "[gc][construct_array]" )
{
    using arr = construct_array<int[10][10][10], std::rank<int[10][10][10]>::value >::type;

    REQUIRE(typeid(arr) == typeid(std::array<std::array<std::array<int, 10>, 10>, 10>));
}

TEST_CASE( "Non-array type to T", "[gc][construct_array]" )
{
    using arr = construct_array<int, std::rank<int>::value >::type;

    REQUIRE(typeid(arr) == typeid(int));
}

TEST_CASE( "construct_array helper type", "[gc][construct_array]" )
{
    using arr = construct_array_t<int[10]>;

    REQUIRE(typeid(arr) == typeid(std::array<int, 10>));
}
<|endoftext|>


<commit_before><commit_msg>[NichingStrategy]: Refactored the one niching strategy<commit_after><|endoftext|>


<commit_before>#include"PlayState.h"
#include"MenuState.h"
#include"Game.h"
#include"MenuButton.h"
#include"TextureManager.h"

const std::string MenuState::menuId = "MENU";

void MenuState::update()
{
    for (int x = 0; x < gameObjects.size(); x++) {
        gameObjects[x]->update();
    }
}

void MenuState::render()
{
    for (int x = 0; x < gameObjects.size(); x++) {
        gameObjects[x]->draw();
    }
}

bool MenuState::onEnter()
{
    std::cout << "entering MenuState" << std::endl;

    if (!TheTextureManager::getInstance()->load("assets/button.png", "playbutton", TheGame::getInstance()->getRenderer())) {
        return false;
    }

    if (!TheTextureManager::getInstance()->load("assets/exit.png", "exitbutton", TheGame::getInstance()->getRenderer())) {
        return false;
    }

    GameObject *buttonPlay = new MenuButton(new LoaderParams(100, 100, 400, 100, "playbutton"), menuToPlay);
    GameObject *buttonExit = new MenuButton(new LoaderParams(100, 300, 400, 100, "exitbutton"), exitFromMenu);

    gameObjects.push_back(buttonPlay);
    gameObjects.push_back(buttonExit);

    return true;
}

bool MenuState::onExit()
{
    std::cout << "exiting MenuState" << std::endl;

    for (int x = 0; x < gameObjects.size(); x++) {
        gameObjects[x]->clean();
    }

    gameObjects.clear();
    TheTextureManager::getInstance()->clearFromTextureMap("playbutton");
    TheTextureManager::getInstance()->clearFromTextureMap("exitbutton");

    return true;
}

void MenuState::menuToPlay()
{
    TheGame::getInstance()->getStateMachine()->changeState(new PlayState());
    std::cout << "Play button clicked" << std::endl;
}

void MenuState::exitFromMenu()
{
    std::cout << "Exit button clicked" << std::endl;
}
<commit_msg>Included event to Play button, this button change to PlayState.<commit_after>#include"PlayState.h"
#include"MenuState.h"
#include"Game.h"
#include"MenuButton.h"
#include"TextureManager.h"

const std::string MenuState::menuId = "MENU";

void MenuState::update()
{
    for (int x = 0; x < gameObjects.size(); x++) {
        gameObjects[x]->update();
    }
}

void MenuState::render()
{
    for (int x = 0; x < gameObjects.size(); x++) {
        gameObjects[x]->draw();
    }
}

bool MenuState::onEnter()
{
    std::cout << "entering MenuState" << std::endl;

    if (!TheTextureManager::getInstance()->load("assets/button.png", "playbutton", TheGame::getInstance()->getRenderer())) {
        return false;
    }

    if (!TheTextureManager::getInstance()->load("assets/exit.png", "exitbutton", TheGame::getInstance()->getRenderer())) {
        return false;
    }

    GameObject *buttonPlay = new MenuButton(new LoaderParams(100, 100, 400, 100, "playbutton"), menuToPlay);
    GameObject *buttonExit = new MenuButton(new LoaderParams(100, 300, 400, 100, "exitbutton"), exitFromMenu);

    gameObjects.push_back(buttonPlay);
    gameObjects.push_back(buttonExit);

    return true;
}

bool MenuState::onExit()
{
    std::cout << "exiting MenuState" << std::endl;

    for (int x = 0; x < gameObjects.size(); x++) {
        gameObjects[x]->clean();
    }

    gameObjects.clear();
    TheTextureManager::getInstance()->clearFromTextureMap("playbutton");
    TheTextureManager::getInstance()->clearFromTextureMap("exitbutton");

    return true;
}

void MenuState::menuToPlay()
{
    std::cout << "Play button clicked" << std::endl;
}

void MenuState::exitFromMenu()
{
    std::cout << "Exit button clicked" << std::endl;
}
<|endoftext|>


<commit_before>#include <libspotify/api.h>
#include "Player.h"
#include "Track.h"
#include "PlaylistContainer.h"
#include "../SpotifyService/SpotifyService.h"

#include <glog/logging.h>

extern SpotifyService* spotifyService;
extern PlaylistContainer* playlistContainer;

Handle<Value> Player::pause(const Arguments& args) {
	return Player::simpleCall(args, &Player::spotifyPause);
}

Handle<Value> Player::stop(const Arguments& args) {
	return Player::simpleCall(args, &Player::spotifyStop);
}

Handle<Value> Player::resume(const Arguments& args) {
	return Player::simpleCall(args, &Player::spotifyResume);
}

Handle<Value> Player::play(const Arguments& args) {
	Player* player = node::ObjectWrap::Unwrap<Player>(args.This());

	int playlistId = args[0]->ToInteger()->Value();
	player->currentTrack = args[1]->ToInteger()->Value();

  player->playlist = playlistContainer->getPlaylists()[playlistId];
	return Player::simpleCall(args, &Player::spotifyPlay);
}

Handle<Value> Player::getCurrentTrack(const Arguments& args) {
  HandleScope scope;
  Player* player = node::ObjectWrap::Unwrap<Player>(args.This());
  return scope.Close(player->playlist->getTracks()[player->currentTrack]->getV8Object());
}

void Player::spotifyPause() {
	sp_session_player_play(spotifyService->spotifySession, 0);
	isPaused = true;
}

void Player::spotifyResume() {
	if(isPaused) {
		sp_session_player_play(spotifyService->spotifySession, 1);
		isPaused = false;
	}
}

void Player::spotifyStop() {
	sp_session_player_unload(spotifyService->spotifySession);
}

void Player::spotifyPlay() {
  sp_session_player_unload(spotifyService->spotifySession);
  Track* track = playlist->getTracks()[currentTrack];
  sp_session_player_load(spotifyService->spotifySession, track->spotifyTrack);
  sp_session_player_play(spotifyService->spotifySession, 1);
}

void Player::nextTrack() {
	if(playlist != 0) {
		currentTrack++;
		Track* track = playlist->getTracks()[currentTrack];
		if( currentTrack < (int)playlist->getTracks().size()) {
			sp_session_player_unload(spotifyService->spotifySession);
			sp_session_player_load(spotifyService->spotifySession, track->spotifyTrack);
    	sp_session_player_play(spotifyService->spotifySession, 1);
		}
	}
}

void Player::init(Handle<Object> target) {
	HandleScope scope;
	Local<FunctionTemplate> constructorTemplate = FunctionTemplate::New();
	constructorTemplate->SetClassName(String::NewSymbol("Player"));
	constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);

	NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "play", play);
	NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "pause", pause);
	NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "resume", resume);
	NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "stop", stop);
  NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "getCurrentTrack", getCurrentTrack);
  constructor = Persistent<Function>::New(constructorTemplate->GetFunction());
  scope.Close(Undefined());
}
<commit_msg>Retabbing, removing unecessary null checks<commit_after>#include <libspotify/api.h>
#include "Player.h"
#include "Track.h"
#include "PlaylistContainer.h"
#include "../SpotifyService/SpotifyService.h"

#include <glog/logging.h>

extern SpotifyService* spotifyService;
extern PlaylistContainer* playlistContainer;

Handle<Value> Player::pause(const Arguments& args) {
	return Player::simpleCall(args, &Player::spotifyPause);
}

Handle<Value> Player::stop(const Arguments& args) {
	return Player::simpleCall(args, &Player::spotifyStop);
}

Handle<Value> Player::resume(const Arguments& args) {
	return Player::simpleCall(args, &Player::spotifyResume);
}

Handle<Value> Player::play(const Arguments& args) {
  Player* player = node::ObjectWrap::Unwrap<Player>(args.This());

  int playlistId = args[0]->ToInteger()->Value();
  player->currentTrack = args[1]->ToInteger()->Value();

  player->playlist = playlistContainer->getPlaylists()[playlistId];
  return Player::simpleCall(args, &Player::spotifyPlay);
}

Handle<Value> Player::getCurrentTrack(const Arguments& args) {
  HandleScope scope;
  Player* player = node::ObjectWrap::Unwrap<Player>(args.This());
  return scope.Close(player->playlist->getTracks()[player->currentTrack]->getV8Object());
}

void Player::spotifyPause() {
  sp_session_player_play(spotifyService->spotifySession, 0);
  isPaused = true;
}

void Player::spotifyResume() {
  if(isPaused) {
    sp_session_player_play(spotifyService->spotifySession, 1);
	isPaused = false;
  }
}

void Player::spotifyStop() {
  sp_session_player_unload(spotifyService->spotifySession);
}

void Player::spotifyPlay() {
  sp_session_player_unload(spotifyService->spotifySession);
  Track* track = playlist->getTracks()[currentTrack];
  sp_session_player_load(spotifyService->spotifySession, track->spotifyTrack);
  sp_session_player_play(spotifyService->spotifySession, 1);
}

void Player::nextTrack() {
  currentTrack++;
  Track* track = playlist->getTracks()[currentTrack];
  if( currentTrack < (int)playlist->getTracks().size()) {
    sp_session_player_unload(spotifyService->spotifySession);
    sp_session_player_load(spotifyService->spotifySession, track->spotifyTrack);
    sp_session_player_play(spotifyService->spotifySession, 1);
  }
}

void Player::init(Handle<Object> target) {
  HandleScope scope;
  Local<FunctionTemplate> constructorTemplate = FunctionTemplate::New();
  constructorTemplate->SetClassName(String::NewSymbol("Player"));
  constructorTemplate->InstanceTemplate()->SetInternalFieldCount(1);

  NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "play", play);
  NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "pause", pause);
  NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "resume", resume);
  NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "stop", stop);
  NODE_SET_PROTOTYPE_METHOD(constructorTemplate, "getCurrentTrack", getCurrentTrack);
  constructor = Persistent<Function>::New(constructorTemplate->GetFunction());
  scope.Close(Undefined());
}
<|endoftext|>