<commit_before>#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"

#include "named_type.hpp"
#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>

// Usage examples

template<typename T>
decltype(auto) tee(T&& value)
{
    std::cout << value << '\n';
    return std::forward<T>(value);
}

using Meter = fluent::NamedType<double, struct MeterParameter, fluent::Addable, fluent::Comparable>;
Meter operator"" _meter(unsigned long long value) { return Meter(value); }
//Meter operator"" _meter(long double value) { return Meter(value); }

using Width = fluent::NamedType<Meter, struct WidthParameter>;
using Height = fluent::NamedType<Meter, struct HeightParameter>;

class Rectangle
{
public:
    Rectangle(Width width, Height height) : width_(width.get()), height_(height.get()) {}
    Meter getWidth() const { return width_; }
    Meter getHeight() const { return height_; }

private:
    Meter width_;
    Meter height_;
};

TEST_CASE("Basic usage")
{
    Rectangle r(Width(10_meter), Height(12_meter));
    REQUIRE(r.getWidth().get() == 10);
    REQUIRE(r.getHeight().get() == 12);
}

using NameRef = fluent::NamedType<std::string&, struct NameRefParameter>;

void changeValue(const NameRef name)
{
    name.get() = "value2";
}

TEST_CASE("Passing a strong reference")
{
    std::string value = "value1";
    changeValue(NameRef(value));
    REQUIRE(value == "value2");
}

TEST_CASE("Construction of NamedType::ref from the underlying type")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    int i = 42;
    addOne(StrongInt::ref(i));
    REQUIRE(i == 43);
}

TEST_CASE("Implicit conversion of NamedType to NamedType::ref")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    StrongInt i(42);
    addOne(i);
    REQUIRE(i.get() == 43);

    StrongInt j(42);
    addOne(StrongInt::ref(j));
    REQUIRE(j.get() == 43);
}

template<typename Function>
using Comparator = fluent::NamedType<Function, struct ComparatorParameter>;

template <typename Function>
std::string performAction(Comparator<Function> comp)
{
    return comp.get()();
}

TEST_CASE("Strong generic type")
{
    REQUIRE(performAction(fluent::make_named<Comparator>([](){ return std::string("compare"); })) == "compare");
}

TEST_CASE("Addable")
{
    using AddableType = fluent::NamedType<int, struct AddableTag, fluent::Addable>;
    AddableType s1(12);
    AddableType s2(10);
    REQUIRE((s1 + s2).get() == 22);
}

TEST_CASE("Subtractable")
{
    using SubtractableType = fluent::NamedType<int, struct SubtractableTag, fluent::Subtractable>;
    SubtractableType s1(12);
    SubtractableType s2(10);
    REQUIRE((s1 - s2).get() == 2);
    s1 -= s2;
    REQUIRE(s1.get() == 2);
}

TEST_CASE("Multiplicable")
{
    using MultiplicableType = fluent::NamedType<int, struct MultiplicableTag, fluent::Multiplicable>;
    MultiplicableType s1(12);
    MultiplicableType s2(10);
    REQUIRE((s1 * s2).get() == 120);
    s1 *= s2;
    REQUIRE(s1.get() == 120);
}

TEST_CASE("Divisible")
{
    using DivisibleType = fluent::NamedType<int, struct DivisibleTag, fluent::Divisible>;
    DivisibleType s1(120);
    DivisibleType s2(10);
    REQUIRE((s1 / s2).get() == 12);
    s1 /= s2;
    REQUIRE(s1.get() == 12);
}

TEST_CASE("Negatable")
{
  using NegatableType = fluent::NamedType<int, struct NegatableTag, fluent::Negatable>;
  NegatableType value(10);
  REQUIRE((-value).get() == -10);
}

TEST_CASE("Modulable")
{
    using ModulableType = fluent::NamedType<int, struct ModulableTag, fluent::Modulable>;
    ModulableType s1(5);
    ModulableType s2(2);
    CHECK((s1 % s2).get() == 1);
    s1 %= s2;
    CHECK(s1.get() == 1);
}

TEST_CASE("BitWiseInvertable")
{
    using BitWiseInvertableType = fluent::NamedType<int, struct BitWiseInvertableTag, fluent::BitWiseInvertable>;
    BitWiseInvertableType s1(13);
    CHECK((~s1).get() == (~13));
}

TEST_CASE("Comparable")
{
    REQUIRE((10_meter == 10_meter));
    REQUIRE(!(10_meter == 11_meter));
    REQUIRE((10_meter != 11_meter));
    REQUIRE(!(10_meter != 10_meter));
    REQUIRE((10_meter <  11_meter));
    REQUIRE(!(10_meter <  10_meter));
    REQUIRE((10_meter <= 10_meter));
    REQUIRE((10_meter <= 11_meter));
    REQUIRE(!(10_meter <= 9_meter));
    REQUIRE((11_meter >  10_meter));
    REQUIRE(!(10_meter > 11_meter));
    REQUIRE((11_meter >= 10_meter));
    REQUIRE((10_meter >= 10_meter));
    REQUIRE(!(9_meter >= 10_meter));
}

TEST_CASE("ConvertibleWithOperator")
{
    struct B
    {
        B(int x) : x(x) {}
        int x;
    };

    struct A
    {
        A(int x) : x(x) {}
        operator B () const { return B(x);}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleWithConstructor")
{
    struct A
    {
        A(int x) : x(x) {}
        int x;
    };

    struct B
    {
        B(A a) : x(a.x) {}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleToItself")
{
    using MyInt = fluent::NamedType<int, struct MyIntTag, fluent::ImplicitlyConvertibleTo<int>::templ>;
    MyInt myInt(42);
    int i = myInt;
    REQUIRE(i == 42);
}

TEST_CASE("Hash")
{
    using SerialNumber = fluent::NamedType<std::string, struct SerialNumberTag, fluent::Comparable, fluent::Hashable>;

    std::unordered_map<SerialNumber, int> hashMap = { {SerialNumber{"AA11"}, 10}, {SerialNumber{"BB22"}, 20} };
    SerialNumber cc33{"CC33"};
    hashMap[cc33] = 30;
    REQUIRE(hashMap[SerialNumber{"AA11"}] == 10);
    REQUIRE(hashMap[SerialNumber{"BB22"}] == 20);
    REQUIRE(hashMap[cc33] == 30);
}

struct testFunctionCallable_A
{
    testFunctionCallable_A(int x) : x(x) {}
    testFunctionCallable_A(testFunctionCallable_A const&) = delete; // ensures that passing the argument to a function doesn't make a copy
    testFunctionCallable_A(testFunctionCallable_A&&) = default;
    testFunctionCallable_A& operator+=(testFunctionCallable_A const& other) { x += other.x; return *this; }
    int x;
};

testFunctionCallable_A operator+(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return testFunctionCallable_A(a1.x + a2.x);
}

bool operator==(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return a1.x == a2.x;
}

TEST_CASE("Function callable")
{
    using A = testFunctionCallable_A;
    auto functionTakingA = [](A const& a){ return a.x; };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::FunctionCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A(42));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(functionTakingA(constStrongA) == 42);
    REQUIRE(strongA + strongA == 84);
}

TEST_CASE("Method callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::MethodCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method or function doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    auto functionTakingA = [](A const& a){ return a.constMethod(); };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::Callable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Named arguments")
{
    using FirstName = fluent::NamedType<std::string, struct FirstNameTag>;
    using LastName = fluent::NamedType<std::string, struct LastNameTag>;
    static const FirstName::argument firstName;
    static const LastName::argument lastName;
    auto getFullName = [](FirstName const& firstName, LastName const& lastName)
    {
        return firstName.get() + lastName.get();
    };

    auto fullName = getFullName(firstName = "James", lastName = "Bond");
    REQUIRE(fullName == "JamesBond");
}

TEST_CASE("Empty base class optimization")
{
    REQUIRE(sizeof(Meter) == sizeof(double));
}

using strong_int = fluent::NamedType<int, struct IntTag>;

TEST_CASE("Default constructible")
{
    strong_int i1;
    strong_int i2{};
}

TEST_CASE("constexpr")
{
    using strong_bool = fluent::NamedType<bool, struct BoolTag>;

    static_assert(strong_bool{ true }.get(), "NamedType is not constexpr");
}

struct throw_on_construction
{
    throw_on_construction() { throw 42; }

    throw_on_construction(int) { throw "exception"; }
};

using C = fluent::NamedType<throw_on_construction, struct throwTag>;

TEST_CASE("noexcept")
{
    CHECK(noexcept(strong_int{}));
    CHECK(!noexcept(C{}));

    CHECK(noexcept(strong_int(3)));
    CHECK(!noexcept(C{5}));
}

TEST_CASE("Arithmetic")
{
    using strong_arithmetic = fluent::NamedType<int, struct ArithmeticTag, fluent::Arithmetic>;
    strong_arithmetic a{ 1 };
    strong_arithmetic b{ 2 };

    CHECK((a + b).get() == 3);

    a += b;
    CHECK(a.get() == 3);

    CHECK((a - b).get() == 1);

    a -= b;
    CHECK(a.get() == 1);

    a.get() = 5;
    CHECK((a * b).get() == 10);

    a *= b;
    CHECK(a.get() == 10);

    CHECK((a / b).get() == 5);

    a /= b;
    CHECK(a.get() == 5);
}
<commit_msg>Added test for BitWiseAndable<commit_after>#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"

#include "named_type.hpp"
#include <cmath>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <unordered_map>

// Usage examples

template<typename T>
decltype(auto) tee(T&& value)
{
    std::cout << value << '\n';
    return std::forward<T>(value);
}

using Meter = fluent::NamedType<double, struct MeterParameter, fluent::Addable, fluent::Comparable>;
Meter operator"" _meter(unsigned long long value) { return Meter(value); }
//Meter operator"" _meter(long double value) { return Meter(value); }

using Width = fluent::NamedType<Meter, struct WidthParameter>;
using Height = fluent::NamedType<Meter, struct HeightParameter>;

class Rectangle
{
public:
    Rectangle(Width width, Height height) : width_(width.get()), height_(height.get()) {}
    Meter getWidth() const { return width_; }
    Meter getHeight() const { return height_; }

private:
    Meter width_;
    Meter height_;
};

TEST_CASE("Basic usage")
{
    Rectangle r(Width(10_meter), Height(12_meter));
    REQUIRE(r.getWidth().get() == 10);
    REQUIRE(r.getHeight().get() == 12);
}

using NameRef = fluent::NamedType<std::string&, struct NameRefParameter>;

void changeValue(const NameRef name)
{
    name.get() = "value2";
}

TEST_CASE("Passing a strong reference")
{
    std::string value = "value1";
    changeValue(NameRef(value));
    REQUIRE(value == "value2");
}

TEST_CASE("Construction of NamedType::ref from the underlying type")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    int i = 42;
    addOne(StrongInt::ref(i));
    REQUIRE(i == 43);
}

TEST_CASE("Implicit conversion of NamedType to NamedType::ref")
{
    using StrongInt = fluent::NamedType<int, struct StrongIntTag>;
    auto addOne = [](StrongInt::ref si) { ++(si.get()); };

    StrongInt i(42);
    addOne(i);
    REQUIRE(i.get() == 43);

    StrongInt j(42);
    addOne(StrongInt::ref(j));
    REQUIRE(j.get() == 43);
}

template<typename Function>
using Comparator = fluent::NamedType<Function, struct ComparatorParameter>;

template <typename Function>
std::string performAction(Comparator<Function> comp)
{
    return comp.get()();
}

TEST_CASE("Strong generic type")
{
    REQUIRE(performAction(fluent::make_named<Comparator>([](){ return std::string("compare"); })) == "compare");
}

TEST_CASE("Addable")
{
    using AddableType = fluent::NamedType<int, struct AddableTag, fluent::Addable>;
    AddableType s1(12);
    AddableType s2(10);
    REQUIRE((s1 + s2).get() == 22);
}

TEST_CASE("Subtractable")
{
    using SubtractableType = fluent::NamedType<int, struct SubtractableTag, fluent::Subtractable>;
    SubtractableType s1(12);
    SubtractableType s2(10);
    REQUIRE((s1 - s2).get() == 2);
    s1 -= s2;
    REQUIRE(s1.get() == 2);
}

TEST_CASE("Multiplicable")
{
    using MultiplicableType = fluent::NamedType<int, struct MultiplicableTag, fluent::Multiplicable>;
    MultiplicableType s1(12);
    MultiplicableType s2(10);
    REQUIRE((s1 * s2).get() == 120);
    s1 *= s2;
    REQUIRE(s1.get() == 120);
}

TEST_CASE("Divisible")
{
    using DivisibleType = fluent::NamedType<int, struct DivisibleTag, fluent::Divisible>;
    DivisibleType s1(120);
    DivisibleType s2(10);
    REQUIRE((s1 / s2).get() == 12);
    s1 /= s2;
    REQUIRE(s1.get() == 12);
}

TEST_CASE("Negatable")
{
  using NegatableType = fluent::NamedType<int, struct NegatableTag, fluent::Negatable>;
  NegatableType value(10);
  REQUIRE((-value).get() == -10);
}

TEST_CASE("Modulable")
{
    using ModulableType = fluent::NamedType<int, struct ModulableTag, fluent::Modulable>;
    ModulableType s1(5);
    ModulableType s2(2);
    CHECK((s1 % s2).get() == 1);
    s1 %= s2;
    CHECK(s1.get() == 1);
}

TEST_CASE("BitWiseInvertable")
{
    using BitWiseInvertableType = fluent::NamedType<int, struct BitWiseInvertableTag, fluent::BitWiseInvertable>;
    BitWiseInvertableType s1(13);
    CHECK((~s1).get() == (~13));
}

TEST_CASE("BitWiseAndable")
{
    using BitWiseAndableType = fluent::NamedType<int, struct BitWiseAndableTag, fluent::BitWiseAndable>;
    BitWiseAndableType s1(2);
    BitWiseAndableType s2(64);
    CHECK((s1 & s2).get() == (2 & 64));
    s1 &= s2;
    CHECK(s1.get() == (2 & 64));
}

TEST_CASE("Comparable")
{
    REQUIRE((10_meter == 10_meter));
    REQUIRE(!(10_meter == 11_meter));
    REQUIRE((10_meter != 11_meter));
    REQUIRE(!(10_meter != 10_meter));
    REQUIRE((10_meter <  11_meter));
    REQUIRE(!(10_meter <  10_meter));
    REQUIRE((10_meter <= 10_meter));
    REQUIRE((10_meter <= 11_meter));
    REQUIRE(!(10_meter <= 9_meter));
    REQUIRE((11_meter >  10_meter));
    REQUIRE(!(10_meter > 11_meter));
    REQUIRE((11_meter >= 10_meter));
    REQUIRE((10_meter >= 10_meter));
    REQUIRE(!(9_meter >= 10_meter));
}

TEST_CASE("ConvertibleWithOperator")
{
    struct B
    {
        B(int x) : x(x) {}
        int x;
    };

    struct A
    {
        A(int x) : x(x) {}
        operator B () const { return B(x);}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleWithConstructor")
{
    struct A
    {
        A(int x) : x(x) {}
        int x;
    };

    struct B
    {
        B(A a) : x(a.x) {}
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::ImplicitlyConvertibleTo<B>::templ>;
    StrongA strongA(A(42));
    B b = strongA;
    REQUIRE(b.x == 42);
}

TEST_CASE("ConvertibleToItself")
{
    using MyInt = fluent::NamedType<int, struct MyIntTag, fluent::ImplicitlyConvertibleTo<int>::templ>;
    MyInt myInt(42);
    int i = myInt;
    REQUIRE(i == 42);
}

TEST_CASE("Hash")
{
    using SerialNumber = fluent::NamedType<std::string, struct SerialNumberTag, fluent::Comparable, fluent::Hashable>;

    std::unordered_map<SerialNumber, int> hashMap = { {SerialNumber{"AA11"}, 10}, {SerialNumber{"BB22"}, 20} };
    SerialNumber cc33{"CC33"};
    hashMap[cc33] = 30;
    REQUIRE(hashMap[SerialNumber{"AA11"}] == 10);
    REQUIRE(hashMap[SerialNumber{"BB22"}] == 20);
    REQUIRE(hashMap[cc33] == 30);
}

struct testFunctionCallable_A
{
    testFunctionCallable_A(int x) : x(x) {}
    testFunctionCallable_A(testFunctionCallable_A const&) = delete; // ensures that passing the argument to a function doesn't make a copy
    testFunctionCallable_A(testFunctionCallable_A&&) = default;
    testFunctionCallable_A& operator+=(testFunctionCallable_A const& other) { x += other.x; return *this; }
    int x;
};

testFunctionCallable_A operator+(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return testFunctionCallable_A(a1.x + a2.x);
}

bool operator==(testFunctionCallable_A const& a1, testFunctionCallable_A const& a2)
{
    return a1.x == a2.x;
}

TEST_CASE("Function callable")
{
    using A = testFunctionCallable_A;
    auto functionTakingA = [](A const& a){ return a.x; };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::FunctionCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A(42));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(functionTakingA(constStrongA) == 42);
    REQUIRE(strongA + strongA == 84);
}

TEST_CASE("Method callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::MethodCallable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Callable")
{
    class A
    {
    public:
        A(int x) : x(x) {}
        A(A const&) = delete; // ensures that invoking a method or function doesn't make a copy
        A(A&&) = default;

        int method(){ return x; }
        int constMethod() const{ return x; }
    private:
        int x;
    };

    auto functionTakingA = [](A const& a){ return a.constMethod(); };

    using StrongA = fluent::NamedType<A, struct StrongATag, fluent::Callable>;
    StrongA strongA(A(42));
    const StrongA constStrongA(A((42)));
    REQUIRE(functionTakingA(strongA) == 42);
    REQUIRE(strongA->method() == 42);
    REQUIRE(constStrongA->constMethod() == 42);
}

TEST_CASE("Named arguments")
{
    using FirstName = fluent::NamedType<std::string, struct FirstNameTag>;
    using LastName = fluent::NamedType<std::string, struct LastNameTag>;
    static const FirstName::argument firstName;
    static const LastName::argument lastName;
    auto getFullName = [](FirstName const& firstName, LastName const& lastName)
    {
        return firstName.get() + lastName.get();
    };

    auto fullName = getFullName(firstName = "James", lastName = "Bond");
    REQUIRE(fullName == "JamesBond");
}

TEST_CASE("Empty base class optimization")
{
    REQUIRE(sizeof(Meter) == sizeof(double));
}

using strong_int = fluent::NamedType<int, struct IntTag>;

TEST_CASE("Default constructible")
{
    strong_int i1;
    strong_int i2{};
}

TEST_CASE("constexpr")
{
    using strong_bool = fluent::NamedType<bool, struct BoolTag>;

    static_assert(strong_bool{ true }.get(), "NamedType is not constexpr");
}

struct throw_on_construction
{
    throw_on_construction() { throw 42; }

    throw_on_construction(int) { throw "exception"; }
};

using C = fluent::NamedType<throw_on_construction, struct throwTag>;

TEST_CASE("noexcept")
{
    CHECK(noexcept(strong_int{}));
    CHECK(!noexcept(C{}));

    CHECK(noexcept(strong_int(3)));
    CHECK(!noexcept(C{5}));
}

TEST_CASE("Arithmetic")
{
    using strong_arithmetic = fluent::NamedType<int, struct ArithmeticTag, fluent::Arithmetic>;
    strong_arithmetic a{ 1 };
    strong_arithmetic b{ 2 };

    CHECK((a + b).get() == 3);

    a += b;
    CHECK(a.get() == 3);

    CHECK((a - b).get() == 1);

    a -= b;
    CHECK(a.get() == 1);

    a.get() = 5;
    CHECK((a * b).get() == 10);

    a *= b;
    CHECK(a.get() == 10);

    CHECK((a / b).get() == 5);

    a /= b;
    CHECK(a.get() == 5);
}
<|endoftext|>


<commit_before>#include <ege/engine/engine.hxx>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <thread>

using namespace ege;

class DefaultCanvas: public ege::graphic::Canvas
{
        public:
                DefaultCanvas( size_t width, size_t height ): Canvas( true, width, height )
                {

                }

                ~DefaultCanvas() {}
};

engine::Configuration ege::engine::configuration;
engine::Resources ege::engine::resources;
static GLFWwindow* win;

void ege::engine::initialize()
{
        glfwInit();
        glfwDefaultWindowHints();
        glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
        glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 0 );
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        const GLFWvidmode* videoMode = glfwGetVideoMode( primary );
        win = glfwCreateWindow( videoMode->width, videoMode->height, "", primary, NULL );
        glfwMakeContextCurrent( win );
        glewExperimental = GL_TRUE;
        glewInit();
        glGetError();
        resources.screen = new DefaultCanvas( ( size_t ) videoMode->width, ( size_t ) videoMode->height );
        resources.resourcesManager = new resource::Manager( &configuration.root );
}

void ege::engine::start( Scenario* initialScenario )
{
        Scenario* current = initialScenario;

        while ( true )
        {
                glfwPollEvents();

                if ( glfwWindowShouldClose( win ) )
                {
                        current->shouldClose();

                        if ( current->isNextScenarioAvailable() )
                                goto should_close_jump;
                }

                current->update();

                if ( current->isNextScenarioAvailable() )
                {
                        should_close_jump:
                        current = current->getNextScenario();

                        if ( current == nullptr )
                                break;
                }

                glfwSwapBuffers( win );
                std::this_thread::sleep_for( std::chrono::milliseconds( 30 ) );
        }
}

void ege::engine::destroy()
{
        glfwDestroyWindow( win );
        delete resources.screen;
        glfwTerminate();
}
<commit_msg>vsync enabled<commit_after>#include <ege/engine/engine.hxx>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <thread>

using namespace ege;

class DefaultCanvas: public ege::graphic::Canvas
{
        public:
                DefaultCanvas( size_t width, size_t height ): Canvas( true, width, height )
                {

                }

                ~DefaultCanvas() {}
};

engine::Configuration ege::engine::configuration;
engine::Resources ege::engine::resources;
static GLFWwindow* win;

void ege::engine::initialize()
{
        glfwInit();
        glfwDefaultWindowHints();
        glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
        glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 0 );
        GLFWmonitor* primary = glfwGetPrimaryMonitor();
        const GLFWvidmode* videoMode = glfwGetVideoMode( primary );
        win = glfwCreateWindow( videoMode->width, videoMode->height, "", primary, NULL );
        glfwMakeContextCurrent( win );
        glfwSwapInterval( 1 );
        glewExperimental = GL_TRUE;
        glewInit();
        glGetError();
        resources.screen = new DefaultCanvas( ( size_t ) videoMode->width, ( size_t ) videoMode->height );
        resources.resourcesManager = new resource::Manager( &configuration.root );
}

void ege::engine::start( Scenario* initialScenario )
{
        Scenario* current = initialScenario;

        while ( true )
        {
                glfwPollEvents();

                if ( glfwWindowShouldClose( win ) )
                {
                        current->shouldClose();

                        if ( current->isNextScenarioAvailable() )
                                goto should_close_jump;
                }

                current->update();

                if ( current->isNextScenarioAvailable() )
                {
                        should_close_jump:
                        current = current->getNextScenario();

                        if ( current == nullptr )
                                break;
                }

                glfwSwapBuffers( win );
                std::this_thread::sleep_for( std::chrono::milliseconds( 8 ) );
        }
}

void ege::engine::destroy()
{
        glfwDestroyWindow( win );
        delete resources.screen;
        glfwTerminate();
}
<|endoftext|>


<commit_before>/* AFTER INPUTING THE YEAR USE GETLINE FOR THE REST OF INFO, ALLOWS FOR MULTIPLE STRING VALUES WHILE SIMUTANIOUSLY IGNORING COMMAS

    goal(12/25/2015-12/27/2015)

    //format the output
    //get weekDay, month, day and year using cin()
    //and then compare them to pcWeek, pcMonth, pcDay, pcYear
    //thinking about leaving weekDay, month, day and year under one vairable using getline() and then adding pc string variables AND THEN comparing
    //example: getline(schedule, dates) which would containg something like Thu Oct 27 2015 and then adding pcWeek + pcMonth + pcDay + pcYear and comparing
    //dont really have to get the year since months dont repeat, just keep the file updated per season

    //function: converting system int dates to strings i.e switch case, data input from file

    //problems to fix: need to find a way to update the file via the internet that works on windows too

*/

#include <iostream>
#include <stdlib.h> //for system() function
#include <unistd.h> //for changing directories
#include <sys/stat.h> //for stat() function
#include <fstream>
#include <ctime>
#include <sstream> //for stringstream: convert int to string
#include <vector>

using namespace std;

void weekConvert(int &tempWeek_, string &pcWeek_); //converts tempWeek
void monthConvert(int &tempMonth_, string &pcMonth_); //converts tempMonth
void dataInput(ifstream &schedule_, vector<string> &weekDay_, vector<string> &time_, vector<string> &box_, vector<string> &team1_, vector<string> &team1Score_, vector<string> &team2_,
vector<string> &team2Score_, vector<string> &OT_, vector<string> &notes_, string userString); //gets data from file
int main()
{
    int changeDir, newDir;
    ifstream schedule;
    string a, b, c, userString; //to ignore first three lines
    vector<string> weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes;
    string pcWeek, pcMonth, pcDay, pcYear; //system dates
    string pcDate; //final string for system date
    int tempMonth, tempYear, tempDay, tempWeek, i = 0;
    stringstream convertYear, convertDay;

    time_t t = time(0);   // get time now
    struct tm *now = localtime( &t );

    tempWeek = (now->tm_wday);
    tempMonth = (now->tm_mon + 1);
    tempDay = (now->tm_mday);
    tempYear = (now->tm_year + 1900);

    weekConvert(tempWeek, pcWeek); //converts tempWeek
    monthConvert(tempMonth, pcMonth); //converts tempMonth

    convertYear << tempYear; //converts years to string
    pcYear = convertYear.str();

    convertDay << tempDay; //converts days to string
    pcDay = convertDay.str();

    pcDate = pcWeek + " " + pcMonth + " " + pcDay + " " + pcYear;

    //newDir = system("mkdir NBAschedule"); //linux only command
    //changeDir = chdir("/home/dan/NBAschedule/"); //linux only command

    schedule.open("schedule.csv");

    if (schedule.is_open())
    {

        getline(schedule, a);
        getline(schedule, b);
        getline(schedule, c);

        dataInput(schedule, weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes, userString); //first read of the file

        do
        {
            if (weekDay[i] != pcDate)
            {
                dataInput(schedule, weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes, userString); //calling the function if system date doesnt match
            }
            else
            {
                cout << weekDay[i] << endl;
                cout << times[i] << endl;
                cout << team1[i] << " " << team1Score[i] << endl;
                cout << team2[i] << " " << team2Score[i] << endl;
                cout << OT[i] << endl;
                cout << notes[i] << endl;
                cout << "\n" << endl;

                dataInput(schedule, weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes, userString); //calling the input function

            }
            i++;

        }while(!schedule.eof());

        schedule.close();
    }
    else
    {
        cout << "Couldn't find the file, downloading now...please re-run the program" << endl;
        system("wget https://raw.githubusercontent.com/dm117/NBA-terminal/master/schedule.csv");
    }

    cout << "\nEnd of program" << endl;

    return 0;
}

void weekConvert(int &tempWeek_, string &pcWeek_)
{
    switch ( tempWeek_ )
    {
    case 0:
        pcWeek_ = "Sun";
        break;
    case 1:
        pcWeek_ = "Mon";
        break;
    case 2:
        pcWeek_ = "Tue";
        break;
    case 3:
        pcWeek_ = "Wed";
        break;
    case 4:
        pcWeek_ = "Thu";
        break;
    case 5:
        pcWeek_ = "Fri";
        break;
    case 6:
        pcWeek_ = "Sat";
        break;
    default:
        cout<<"ERROR GETTING DAY OF THE WEEK\n";
        break;
    }
}

void monthConvert(int &tempMonth_, string &pcMonth_)
{
    switch ( tempMonth_ )
    {
    case 1:
        pcMonth_ = "Jan";
        break;
    case 2:
        pcMonth_ = "Feb";
        break;
    case 3:
        pcMonth_ = "March";
        break;
    case 4:
        pcMonth_ = "Apr";
        break;
    case 5:
        pcMonth_ = "May";
        break;
    case 6:
        pcMonth_ = "Jun";
        break;
    case 7:
        pcMonth_ = "Jul";
        break;
    case 8:
        pcMonth_ = "Aug";
        break;
    case 9:
        pcMonth_ = "Sep";
        break;
    case 10:
        pcMonth_ = "Oct";
        break;
    case 11:
        pcMonth_ = "Nov";
        break;
    case 12:
        pcMonth_ = "Dec";
        break;
    default:
        cout<<"ERROR\n";
        break;
    }
}

void dataInput(ifstream &schedule_, vector<string> &weekDay_, vector<string> &time_, vector<string> &box_, vector<string> &team1_, vector<string> &team1Score_, vector<string> &team2_,
vector<string> &team2Score_, vector<string> &OT_, vector<string> &notes_, string userString_) //gets data from file
{

    getline(schedule_, userString_, ',');
    weekDay_.push_back(userString_);

    getline(schedule_, userString_, ',');
    time_.push_back(userString_);

    getline(schedule_, userString_, ',');
    box_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team1_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team1Score_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team2_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team2Score_.push_back(userString_);

    getline(schedule_, userString_, ',');
    OT_.push_back(userString_);

    getline(schedule_, userString_);
    notes_.push_back(userString_);

}

/*--------------------------------------------THIS WILL BE USE LATER TO CHECK IF THE DIRECTORY ALREADY EXISTS------------
struct stat statbuf;
int isDir = 0;
if (stat("/NBAschedule", &statbuf) != -1) {
   if (S_ISDIR(statbuf.st_mode)) {
      isDir = 1;
   }
} else {

       here you might check errno for the reason, ENOENT will mean the path
       was bad, ENOTDIR means part of the path is not a directory, EACCESS
       would mean you can't access the path. Regardless, from the point of
       view of your app, the path is not a directory if stat fails.

}

//Source: https://www.quora.com/How-do-I-check-if-a-directory-exists-in-Linux-using-C++
--------------------------------------------THIS WILL BE USE LATER TO CHECK IF THE DIRECTORY ALREADY EXISTS------------*/

<commit_msg>2x2 formatting! need output function<commit_after>/* AFTER INPUTING THE YEAR USE GETLINE FOR THE REST OF INFO, ALLOWS FOR MULTIPLE STRING VALUES WHILE SIMUTANIOUSLY IGNORING COMMAS

    goal(12/25/2015-12/27/2015)

    //format the output
    //get weekDay, month, day and year using cin()
    //and then compare them to pcWeek, pcMonth, pcDay, pcYear
    //thinking about leaving weekDay, month, day and year under one vairable using getline() and then adding pc string variables AND THEN comparing
    //example: getline(schedule, dates) which would containg something like Thu Oct 27 2015 and then adding pcWeek + pcMonth + pcDay + pcYear and comparing
    //dont really have to get the year since months dont repeat, just keep the file updated per season

    //function: converting system int dates to strings i.e switch case, data input from file

    //problems to fix: need to find a way to update the file via the internet that works on windows too

*/

#include <iostream>
#include <stdlib.h> //for system() function
#include <unistd.h> //for changing directories
#include <sys/stat.h> //for stat() function
#include <fstream>
#include <ctime>
#include <sstream> //for stringstream: convert int to string
#include <vector>
#include <iomanip> //output manipulators

using namespace std;

void weekConvert(int &tempWeek_, string &pcWeek_); //converts tempWeek
void monthConvert(int &tempMonth_, string &pcMonth_); //converts tempMonth
void dataInput(ifstream &schedule_, vector<string> &weekDay_, vector<string> &time_, vector<string> &box_, vector<string> &team1_, vector<string> &team1Score_, vector<string> &team2_,
vector<string> &team2Score_, vector<string> &OT_, vector<string> &notes_, string userString); //gets data from file
int main()
{
    int changeDir, newDir;
    ifstream schedule;
    string a, b, c, userString; //to ignore first three lines
    vector<string> weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes;
    vector<int> placeHolder;
    string pcWeek, pcMonth, pcDay, pcYear; //system dates
    string pcDate; //final string for system date
    int tempMonth, tempYear, tempDay, tempWeek, i = 0;
    stringstream convertYear, convertDay;

    time_t t = time(0);   // get time now
    struct tm *now = localtime( &t );

    tempWeek = (now->tm_wday);
    tempMonth = (now->tm_mon + 1);
    tempDay = (now->tm_mday);
    tempYear = (now->tm_year + 1900);

    weekConvert(tempWeek, pcWeek); //converts tempWeek
    monthConvert(tempMonth, pcMonth); //converts tempMonth

    convertYear << tempYear; //converts years to string
    pcYear = convertYear.str();

    convertDay << tempDay; //converts days to string
    pcDay = convertDay.str();

    pcDate = pcWeek + " " + pcMonth + " " + pcDay + " " + pcYear;

    //newDir = system("mkdir NBAschedule"); //linux only command
    //changeDir = chdir("/home/dan/NBAschedule/"); //linux only command
    int z = 0;

    schedule.open("schedule.csv");

    if (schedule.is_open())
    {

        getline(schedule, a);
        getline(schedule, b);
        getline(schedule, c);

        dataInput(schedule, weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes, userString); //first read of the file

        do
        {
            if (weekDay[i] != pcDate)
            {
                dataInput(schedule, weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes, userString); //calling the function if system date doesnt match
            }
            else
            {
                placeHolder.push_back(i); //holds the location of today's games

                dataInput(schedule, weekDay, times, box, team1, team1Score, team2, team2Score, OT, notes, userString); //calling the input function
            }

            i++; //put this int the else statement and delete the output then print out formatted date after the loop

        }while(!schedule.eof());

        schedule.close();

        int one = 0;
        int two = 0;
        int three = 0;
        int four = 0;
        int five = 0;
        int six = 0;
        int seven = 0;
        int y = 0;
        int i = 0;

        z = 2;

        for(i; i < placeHolder.size(); i++)
        {
            cout << setw(30) << left << weekDay[placeHolder[i]] << setw(5) << " ";//22

            if (i == placeHolder.size() - 1)
                {
                    y = 1;
                }

            if(y == 1)
            {

                cout << endl;
                for(int x = 0; x < z; x++) //need to find a way to continue
                {
                    cout << setw(30) << left << times[placeHolder[one]] << setw(5) << " ";//29
                    one++;
                }
                cout << endl;
                for(int x = 0; x < z; x++)
                {
                    cout << setw(30) << left << team1[placeHolder[two]] << setw(5) << " ";//22
                    two++;
                }

                for(int x = 0; x < z; x++)
                {
                    cout << team1Score[placeHolder[three]];
                    three++;
                }
                cout << endl;
                for(int x = 0; x < z; x++)
                {
                    cout << setw(30) << left << team2[placeHolder[four]] << setw(5) << " ";//23
                    four++;
                }

                for(int x = 0; x < z; x++)
                {
                    cout << team2Score[placeHolder[five]];
                    five++;
                }
                cout << endl;
                for(int x = 0; x < z; x++)
                {
                    cout << OT[placeHolder[six]];
                    six++;
                }
                cout << endl;
                for(int x = 0; x < z; x++)
                {
                    cout << notes[placeHolder[seven]];
                    seven++;
                }

                y = 0;

                cout << "\n\n" << endl;
            }
            else
            {
                y++;
            }
        }

       /* i = 0;

        do
        {
                //going to write for loops to format output into columns and rows. ex: for(){ cout << vectorString << setw() }
                cout << weekDay[placeHolder[i]] << endl;
                cout << times[placeHolder[i]] << endl;
                cout << team1[placeHolder[i]] << " " << team1Score[placeHolder[i]] << endl;
                cout << team2[placeHolder[i]] << " " << team2Score[placeHolder[i]] << endl;
                cout << OT[placeHolder[i]] << endl;
                cout << notes[placeHolder[i]] << endl;

                i++;

        }while(i < placeHolder.size()); */

    }
    else
    {
        cout << "Couldn't find the file, downloading now...please re-run the program" << endl;
        system("wget https://raw.githubusercontent.com/dm117/NBA-terminal/master/schedule.csv");
        cout << "\n\nDownloaded file, re-run the program..." << endl;
    }

    cout << "\nEnd of program" << endl;

    return 0;
}

void weekConvert(int &tempWeek_, string &pcWeek_)
{
    switch ( tempWeek_ )
    {
    case 0:
        pcWeek_ = "Sun";
        break;
    case 1:
        pcWeek_ = "Mon";
        break;
    case 2:
        pcWeek_ = "Tue";
        break;
    case 3:
        pcWeek_ = "Wed";
        break;
    case 4:
        pcWeek_ = "Thu";
        break;
    case 5:
        pcWeek_ = "Fri";
        break;
    case 6:
        pcWeek_ = "Sat";
        break;
    default:
        cout<<"ERROR GETTING DAY OF THE WEEK\n";
        break;
    }
}

void monthConvert(int &tempMonth_, string &pcMonth_)
{
    switch ( tempMonth_ )
    {
    case 1:
        pcMonth_ = "Jan";
        break;
    case 2:
        pcMonth_ = "Feb";
        break;
    case 3:
        pcMonth_ = "March";
        break;
    case 4:
        pcMonth_ = "Apr";
        break;
    case 5:
        pcMonth_ = "May";
        break;
    case 6:
        pcMonth_ = "Jun";
        break;
    case 7:
        pcMonth_ = "Jul";
        break;
    case 8:
        pcMonth_ = "Aug";
        break;
    case 9:
        pcMonth_ = "Sep";
        break;
    case 10:
        pcMonth_ = "Oct";
        break;
    case 11:
        pcMonth_ = "Nov";
        break;
    case 12:
        pcMonth_ = "Dec";
        break;
    default:
        cout<<"ERROR\n";
        break;
    }
}

void dataInput(ifstream &schedule_, vector<string> &weekDay_, vector<string> &time_, vector<string> &box_, vector<string> &team1_, vector<string> &team1Score_, vector<string> &team2_,
vector<string> &team2Score_, vector<string> &OT_, vector<string> &notes_, string userString_) //gets data from file
{

    getline(schedule_, userString_, ',');
    weekDay_.push_back(userString_);

    getline(schedule_, userString_, ',');
    time_.push_back(userString_);

    getline(schedule_, userString_, ',');
    box_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team1_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team1Score_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team2_.push_back(userString_);

    getline(schedule_, userString_, ',');
    team2Score_.push_back(userString_);

    getline(schedule_, userString_, ',');
    OT_.push_back(userString_);

    getline(schedule_, userString_);
    notes_.push_back(userString_);

}

/*--------------------------------------------THIS WILL BE USE LATER TO CHECK IF THE DIRECTORY ALREADY EXISTS------------
struct stat statbuf;
int isDir = 0;
if (stat("/NBAschedule", &statbuf) != -1) {
   if (S_ISDIR(statbuf.st_mode)) {
      isDir = 1;
   }
} else {

       here you might check errno for the reason, ENOENT will mean the path
       was bad, ENOTDIR means part of the path is not a directory, EACCESS
       would mean you can't access the path. Regardless, from the point of
       view of your app, the path is not a directory if stat fails.

}

//Source: https://www.quora.com/How-do-I-check-if-a-directory-exists-in-Linux-using-C++
--------------------------------------------THIS WILL BE USE LATER TO CHECK IF THE DIRECTORY ALREADY EXISTS------------*/

<|endoftext|>


<commit_before>#include <fountain.h>

ftTime::Clock mainClock(60.0);
ftScene::SceneSelector SS;
ftRender::ShaderProgram SP("resources/shader/vs.vert", "resources/shader/fs.frag");
ftType::FontMan fm;

#include "testscene.h"
#include <string>

void fountain::setBasicVarible()
{
	mainWin.setW(800);
	mainWin.setH(600);
	mainWin.title = std::string("fountain-prototype ") + std::string(FOUNTAIN_VERSION);
	mainWin.icon = "fountain.ico";
	mainWin.isFullScreen = false;
//	mainWin.isFullScreen = true;
	mainWin.hideCursor = false;
}

void fountain::gameInit()
{
	mainClock.init();

	SS.registerScene(&startScene, FT_StartScene);
	SS.registerScene(&gameScene, FT_Scene2);
	SS.registerScene(&modelScene, FT_Scene3);

	fm.loadFont("resources/font/wqy-microhei.ttc");
	fm.genAsciiTable();

	SP.init();
	SP.setUniform("time", 0.0f);
	SP.use();
}

void fountain::singleFrame()
{
	//TODO: move this internal(fountainMain)
	mainClock.tick();

	ftVec2 mp = fountain::sysMouse.getPos();
	SP.setUniform("time", mainClock.secondsFromInit());
	SP.setUniform("resolution", fountain::getWinSize());
	SP.setUniform("mouse", mp);

	if (fountain::sysKeyboard.getState(FT_S) == FT_KeyUp)
		SP.use();
	if (fountain::sysKeyboard.getState(FT_F) == FT_KeyUp)
		ftRender::useFFP();
	if (fountain::sysKeyboard.getState(FT_R) == FT_KeyUp)
		SP.reload();

	SS.sceneSolve();
	SS.update();
	SS.draw();

	ftRender::drawAlphaPic(fm.picID);
}
<commit_msg>change font file use<commit_after>#include <fountain.h>

ftTime::Clock mainClock(60.0);
ftScene::SceneSelector SS;
ftRender::ShaderProgram SP("resources/shader/vs.vert", "resources/shader/fs.frag");
ftType::FontMan fm;

#include "testscene.h"
#include <string>

void fountain::setBasicVarible()
{
	mainWin.setW(800);
	mainWin.setH(600);
	mainWin.title = std::string("fountain-prototype ") + std::string(FOUNTAIN_VERSION);
	mainWin.icon = "fountain.ico";
	mainWin.isFullScreen = false;
//	mainWin.isFullScreen = true;
	mainWin.hideCursor = false;
}

void fountain::gameInit()
{
	mainClock.init();

	SS.registerScene(&startScene, FT_StartScene);
	SS.registerScene(&gameScene, FT_Scene2);
	SS.registerScene(&modelScene, FT_Scene3);

	fm.loadFont("/usr/share/fonts/truetype/freefont/FreeSans.ttf");
	fm.genAsciiTable();

	SP.init();
	SP.setUniform("time", 0.0f);
	SP.use();
}

void fountain::singleFrame()
{
	//TODO: move this internal(fountainMain)
	mainClock.tick();

	ftVec2 mp = fountain::sysMouse.getPos();
	SP.setUniform("time", mainClock.secondsFromInit());
	SP.setUniform("resolution", fountain::getWinSize());
	SP.setUniform("mouse", mp);

	if (fountain::sysKeyboard.getState(FT_S) == FT_KeyUp)
		SP.use();
	if (fountain::sysKeyboard.getState(FT_F) == FT_KeyUp)
		ftRender::useFFP();
	if (fountain::sysKeyboard.getState(FT_R) == FT_KeyUp)
		SP.reload();

	SS.sceneSolve();
	SS.update();
	SS.draw();

	ftRender::drawAlphaPic(fm.picID);
}
<|endoftext|>


<commit_before>
#include "DataThread.h"
#include "exception/Base.h"

namespace blitzortung {

  DataThread::DataThread(Queue<data::Event>& sampleQueue, const network::transfer::Base& transfer, output::Base& output) :
    sampleQueue_(sampleQueue),
    transfer_(transfer),
    events_(new data::Events()),
    output_(output),
    logger_("DataThread")
  {
    sleepTime_ = pt::seconds(20);
    eventRateLimit_ = 1.0;

    if (logger_.isDebugEnabled())
      logger_.debugStream() << "initalized( sleep: " << sleepTime_ << ", eventRateLimit: " << eventRateLimit_ << ")";
  }

  DataThread::~DataThread() {
    if (logger_.isDebugEnabled())
      logger_.debugStream() << "deleted";
  }

  void DataThread::setSleepTime(const pt::time_duration& sleepTime) {
    sleepTime_ = sleepTime;
  }

  void DataThread::setEventRateLimit(const double eventRateLimit) {
    eventRateLimit_ = eventRateLimit;
  }

  data::Events::AP DataThread::prepareData(const pt::ptime& now, const pt::ptime& lastSent) {
    data::Events::AP deletedEvents(new data::Events());

    double secondsElapsed = ((now - lastSent).total_milliseconds() / 1000);
    double eventRate = double(events_->size()) / secondsElapsed;

    if (logger_.isDebugEnabled())
      logger_.debugStream() << "prepareData() " << events_->size() << " events (rate " << eventRate << " events/second) at " << now;

    if (eventRate > eventRateLimit_) {
      events_->sort(data::Event::CompareAmplitude());

      int sampleLimit = eventRateLimit_ * secondsElapsed;

      //events_->transfer(events_->begin() + sampleLimit, events_->end());
      deletedEvents->transfer(deletedEvents->end(), events_->begin(), events_->end(), *events_);

      if (logger_.isInfoEnabled()) {
	logger_.infoStream() << "prepareData() limit " << eventRateLimit_ << " reached, interval seconds: " << secondsElapsed << ", erasing to " << sampleLimit << " elements (new # of elements: " << events_->size() << ")";
      }

      // time sort events
      events_->sort();
    }

    return deletedEvents;
  }

  void DataThread::operator()() {

    pt::ptime lastSent = pt::second_clock::universal_time();

    while (true) {
      boost::xtime xt;
      boost::xtime_get(&xt, boost::TIME_UTC);
      xt.sec += 1;

      if (logger_.isDebugEnabled())
	logger_.debugStream() << "() wait for data";

      // wait for next incoming sample
      sampleQueue_.timed_wait(xt);

      pt::ptime now = pt::second_clock::universal_time();

      if (now - lastSent >= sleepTime_) {

	bool sendAgain = false;

	do {
	  // get new events from queue until it is empty
	  while (! sampleQueue_.empty()) {

	    if (events_->size() != 0 && events_->getDate() != sampleQueue_.front().getWaveform().getTime().date()) {
	      if (logger_.isDebugEnabled())
		logger_.debugStream() << "() stopped reading queue at transition to next day";
	      sendAgain = true;
	      break;
	    }

	    if (logger_.isDebugEnabled())
	      logger_.debugStream() << "() pop from queue " << sampleQueue_.front().getWaveform().getTime();
	    events_->add(sampleQueue_.pop());
	  }

	  if (events_->size() > 0) {

	    if (logger_.isDebugEnabled())
	      logger_.debug("() transmitting/saving data");

	    // prepare data for transmission
	    data::Events::AP deletedEvents = prepareData(now, lastSent);

	    logger_.infoStream() << "transmit " << events_->size() << " events";
	    // transmit data
	    transfer_.send(*events_);
	    logger_.infoStream() << "transmit done";

	    if (logger_.isDebugEnabled())
	      logger_.debugStream() << "() recollect events " << events_->size() << " + " << deletedEvents->size();

	    events_->transfer(events_->end(), *deletedEvents);

	    events_->sort();

	    if (logger_.isDebugEnabled())
	      logger_.debugStream() << "() recollected " << events_->size() << " events ";

	    logger_.infoStream() << "output " << events_->size() << " events";
	    output_.output(*events_);

	    // delete all events
	    events_->clear();
	  }
	} while (sendAgain);

	lastSent = now;
      }
    }
  }

}
<commit_msg>logging cleanup<commit_after>
#include "DataThread.h"
#include "exception/Base.h"

namespace blitzortung {

  DataThread::DataThread(Queue<data::Event>& sampleQueue, const network::transfer::Base& transfer, output::Base& output) :
    sampleQueue_(sampleQueue),
    transfer_(transfer),
    events_(new data::Events()),
    output_(output),
    logger_("DataThread")
  {
    sleepTime_ = pt::seconds(20);
    eventRateLimit_ = 1.0;

    if (logger_.isDebugEnabled())
      logger_.debugStream() << "initalized( sleep: " << sleepTime_ << ", eventRateLimit: " << eventRateLimit_ << ")";
  }

  DataThread::~DataThread() {
    if (logger_.isDebugEnabled())
      logger_.debugStream() << "deleted";
  }

  void DataThread::setSleepTime(const pt::time_duration& sleepTime) {
    sleepTime_ = sleepTime;
  }

  void DataThread::setEventRateLimit(const double eventRateLimit) {
    eventRateLimit_ = eventRateLimit;
  }

  data::Events::AP DataThread::prepareData(const pt::ptime& now, const pt::ptime& lastSent) {
    data::Events::AP deletedEvents(new data::Events());

    double secondsElapsed = ((now - lastSent).total_milliseconds() / 1000);
    double eventRate = double(events_->size()) / secondsElapsed;

    if (logger_.isDebugEnabled())
      logger_.debugStream() << "prepareData() " << events_->size() << " events (rate " << eventRate << " events/second) at " << now;

    if (eventRate > eventRateLimit_) {
      events_->sort(data::Event::CompareAmplitude());

      int sampleLimit = eventRateLimit_ * secondsElapsed;

      //events_->transfer(events_->begin() + sampleLimit, events_->end());
      deletedEvents->transfer(deletedEvents->end(), events_->begin(), events_->end(), *events_);

      if (logger_.isInfoEnabled()) {
	logger_.infoStream() << "prepareData() limit " << eventRateLimit_ << " reached, interval seconds: " << secondsElapsed << ", erasing to " << sampleLimit << " elements (new # of elements: " << events_->size() << ")";
      }

      // time sort events
      events_->sort();
    }

    return deletedEvents;
  }

  void DataThread::operator()() {

    pt::ptime lastSent = pt::second_clock::universal_time();

    while (true) {
      boost::xtime xt;
      boost::xtime_get(&xt, boost::TIME_UTC);
      xt.sec += 1;

      if (logger_.isDebugEnabled())
	logger_.debugStream() << "() wait for data";

      // wait for next incoming sample
      sampleQueue_.timed_wait(xt);

      pt::ptime now = pt::second_clock::universal_time();

      if (now - lastSent >= sleepTime_) {

	bool sendAgain = false;

	do {
	  // get new events from queue until it is empty
	  while (! sampleQueue_.empty()) {

	    if (events_->size() != 0 && events_->getDate() != sampleQueue_.front().getWaveform().getTime().date()) {
	      if (logger_.isDebugEnabled())
		logger_.debugStream() << "() stopped reading queue at transition to next day";
	      sendAgain = true;
	      break;
	    }

	    if (logger_.isDebugEnabled())
	      logger_.debugStream() << "() pop from queue " << sampleQueue_.front().getWaveform().getTime();
	    events_->add(sampleQueue_.pop());
	  }

	  if (events_->size() > 0) {

	    if (logger_.isDebugEnabled())
	      logger_.debug("() transmitting/saving data");

	    // prepare data for transmission
	    data::Events::AP deletedEvents = prepareData(now, lastSent);

	    // transmit data
	    transfer_.send(*events_);

	    if (logger_.isDebugEnabled())
	      logger_.debugStream() << "() recollect events " << events_->size() << " + " << deletedEvents->size();

	    events_->transfer(events_->end(), *deletedEvents);

	    events_->sort();

	    if (logger_.isDebugEnabled())
	      logger_.debugStream() << "() recollected " << events_->size() << " events ";

	    output_.output(*events_);

	    // delete all events
	    events_->clear();
	  }
	} while (sendAgain);

	lastSent = now;
      }
    }
  }

}
<|endoftext|>


<commit_before>80d6a8cf-4b02-11e5-95b3-28cfe9171a43<commit_msg>having coffee<commit_after>80e233f8-4b02-11e5-97f3-28cfe9171a43<|endoftext|>


<commit_before>#include <vexcl/devlist.hpp>
#include <vexcl/spmat.hpp>
#include <vexcl/vector.hpp>

#include <blaze/math/CompressedMatrix.h>
#include <blaze/math/DynamicVector.h>
#include <blaze/math/DenseSubvector.h>

#include <blaze/util/serialization/Archive.h>
#include <blaze/math/serialization/MatrixSerializer.h>
#include <blaze/math/serialization/VectorSerializer.h>

#include <vector>
#include <sstream>
#include <string>
#include <iostream>

void ConvertSpMat(std::vector<size_t>& row, std::vector<size_t>& col, std::vector<double>& val, blaze::CompressedMatrix<double>& mat) {
	uint non_zeros = mat.nonZeros();
	row.clear();
	col.clear();
	val.clear();
	uint count = 0;
	for (int i = 0; i < mat.rows(); ++i) {
		row.push_back(count);
		for (blaze::CompressedMatrix<double>::Iterator it = mat.begin(i); it != mat.end(i); ++it) {
			col.push_back(it->index());
			val.push_back(it->value());
			count++;
		}
	}
	row.push_back(count);
}

std::string slurp(std::string fname){
	std::ifstream file(fname.c_str());
	std::string buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
	return buffer;
}

void readSPMAT(std::string & data, blaze::CompressedMatrix<double> & mat){
	std::stringstream ss(data);

	uint rows, cols, nonzeros;
	ss>>rows>>cols>>nonzeros;
	//printf("INFO: rows: %d, columns: %d, non zeros: %d\n",rows, cols, nonzeros);
	mat.resize(rows,cols);
	mat.reserve(nonzeros);
	uint row_nonzeros;
	uint colval;
	double v;

	for(int i=0; i<rows; i++){
		if(i%1000000==0){printf("%d, ",i);}

		ss>>row_nonzeros;

		for(int j=0; j<row_nonzeros; j++){
			ss>>colval>>v;
			mat.append(i,colval,v);
		}
		mat.finalize(i);
	}
	printf("\n");
}
void readVector(std::string & data, std::vector<double> & vec){
	std::stringstream ss(data);

	uint size;
	ss>>size;
	vec.resize(size);

	//printf("INFO: size: %d\n",size);
	double v;
	for(int i=0; i<size; i++){
		ss>>v;
		vec[i] = v;
	}
}
int main(){
	printf("start execution \n");
	vex::Context ctx(vex::Filter::Env && vex::Filter::DoublePrecision);
	std::cout<<ctx<<std::endl;
	printf("create context \n");

	blaze::CompressedMatrix<double> D_T, M_invD;
	std::vector<double> g,b;
	printf("read D^T \n");
	{
		std::string data = slurp("D_T.mat");
		readSPMAT(data, D_T);
	}

	{
		std::string data = slurp("M_invD.mat");
		readSPMAT(data, M_invD);
	}
	{
		std::string data = slurp("gamma.vec");
		readVector(data, g);
	}

	{
		std::string data = slurp("b.vec");
		readVector(data, b);
	}

	printf("D_T: rows: %d, columns: %d, non zeros: %d\n", D_T.rows(), D_T.columns(), D_T.nonZeros());
	printf("M_invD: rows: %d, columns: %d, non zeros: %d\n", M_invD.rows(), M_invD.columns(), M_invD.nonZeros());
	printf("gamma: size: %d\n", g.size());
	printf("b: size: %d\n", b.size());

	std::vector<size_t> row;
	std::vector<size_t> col;
	std::vector<double> val;

	ConvertSpMat(row, col, val, D_T);
	vex::SpMat<double> _D_T(ctx, D_T.rows(), D_T.columns(), row.data(), col.data(), val.data());

	ConvertSpMat(row, col, val, M_invD);
	vex::SpMat<double> _M_invD(ctx, M_invD.rows(), M_invD.columns(), row.data(), col.data(), val.data());

	blaze::DynamicVector<double> gamma(g.size()),rhs(g.size());

	for(int i=0; i<g.size(); i++){
		gamma[i] = g[i];
		rhs[i] = b[i];
	}
	blaze::DynamicVector<double> tmp_cpu(g.size());
	blaze::DynamicVector<double> res_cpu(g.size());
	double start_cpu = omp_get_wtime();
	for(size_t i = 0; i < 100; i++){
		tmp_cpu = M_invD*gamma;
		res_cpu += D_T*tmp_cpu;
	}
	double end_cpu = omp_get_wtime();

	vex::profiler<> prof;

	vex::vector<double> gamma_gpu(ctx,g.size());
	vex::vector<double> b_gpu(ctx,b.size());
	vex::copy(g,gamma_gpu);
	vex::copy(b,b_gpu);
	vex::vector<double> tmp_gpu(ctx,g.size());
	vex::vector<double> res_gpu(ctx,g.size());

	tmp_gpu += _M_invD*gamma_gpu;
	tmp_gpu = 0;
	res_gpu += _D_T*tmp_gpu;
	res_gpu = 0;
	prof.tic_cpu("GPU");
	double start_gpu = omp_get_wtime();
	for(size_t i = 0; i < 100; i++){
		tmp_gpu  = _M_invD*gamma_gpu;
		res_gpu  += _D_T*tmp_gpu;
	}
	ctx.finish();
	double end_gpu = omp_get_wtime();
	double tot_time = prof.toc("GPU");
	printf("CPU took %f sec. time.\n", (end_cpu-start_cpu)/100.0);
	printf("GPU took %f sec. time, %f sec time.\n", (end_gpu-start_gpu)/100.0, tot_time/100.0);
	printf("Speedup: %f\n", (end_cpu-start_cpu) /(end_gpu-start_gpu));

	//std::vector<double> res_host(g.size());

	//vex::copy(res_gpu,res_host);

	//printf("copy\n");
	// for(int i=0; i<g.size(); i++){
	// 	if(res_host[i]!=res_cpu[i]){
	// 		printf("%f\n",res_host[i]-res_cpu[i]);
	// 	}
	// }

	return 0;
}<commit_msg>The number of runs is now a command line argument<commit_after>#include <vexcl/devlist.hpp>
#include <vexcl/spmat.hpp>
#include <vexcl/vector.hpp>

#include <blaze/math/CompressedMatrix.h>
#include <blaze/math/DynamicVector.h>
#include <blaze/math/DenseSubvector.h>

#include <blaze/util/serialization/Archive.h>
#include <blaze/math/serialization/MatrixSerializer.h>
#include <blaze/math/serialization/VectorSerializer.h>

#include <vector>
#include <sstream>
#include <string>
#include <iostream>

void ConvertSpMat(std::vector<size_t>& row, std::vector<size_t>& col, std::vector<double>& val, blaze::CompressedMatrix<double>& mat) {
	uint non_zeros = mat.nonZeros();
	row.clear();
	col.clear();
	val.clear();
	uint count = 0;
	for (int i = 0; i < mat.rows(); ++i) {
		row.push_back(count);
		for (blaze::CompressedMatrix<double>::Iterator it = mat.begin(i); it != mat.end(i); ++it) {
			col.push_back(it->index());
			val.push_back(it->value());
			count++;
		}
	}
	row.push_back(count);
}

std::string slurp(std::string fname){
	std::ifstream file(fname.c_str());
	std::string buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
	return buffer;
}

void readSPMAT(std::string & data, blaze::CompressedMatrix<double> & mat){
	std::stringstream ss(data);

	uint rows, cols, nonzeros;
	ss>>rows>>cols>>nonzeros;
	//printf("INFO: rows: %d, columns: %d, non zeros: %d\n",rows, cols, nonzeros);
	mat.resize(rows,cols);
	mat.reserve(nonzeros);
	uint row_nonzeros;
	uint colval;
	double v;

	for(int i=0; i<rows; i++){
		if(i%1000000==0){printf("%d, ",i);}

		ss>>row_nonzeros;

		for(int j=0; j<row_nonzeros; j++){
			ss>>colval>>v;
			mat.append(i,colval,v);
		}
		mat.finalize(i);
	}
	printf("\n");
}
void readVector(std::string & data, std::vector<double> & vec){
	std::stringstream ss(data);

	uint size;
	ss>>size;
	vec.resize(size);

	//printf("INFO: size: %d\n",size);
	double v;
	for(int i=0; i<size; i++){
		ss>>v;
		vec[i] = v;
	}
}
int main(int argc, char* argv[]){
	printf("start execution \n");
	vex::Context ctx(vex::Filter::Env && vex::Filter::DoublePrecision);
	std::cout<<ctx<<std::endl;
	printf("create context \n");

	blaze::CompressedMatrix<double> D_T, M_invD;
	std::vector<double> g,b;
	printf("read D^T \n");
	{
		std::string data = slurp("D_T.mat");
		readSPMAT(data, D_T);
	}

	{
		std::string data = slurp("M_invD.mat");
		readSPMAT(data, M_invD);
	}
	{
		std::string data = slurp("gamma.vec");
		readVector(data, g);
	}

	{
		std::string data = slurp("b.vec");
		readVector(data, b);
	}

	printf("D_T: rows: %d, columns: %d, non zeros: %d\n", D_T.rows(), D_T.columns(), D_T.nonZeros());
	printf("M_invD: rows: %d, columns: %d, non zeros: %d\n", M_invD.rows(), M_invD.columns(), M_invD.nonZeros());
	printf("gamma: size: %d\n", g.size());
	printf("b: size: %d\n", b.size());

	std::vector<size_t> row;
	std::vector<size_t> col;
	std::vector<double> val;

	ConvertSpMat(row, col, val, D_T);
	vex::SpMat<double> _D_T(ctx, D_T.rows(), D_T.columns(), row.data(), col.data(), val.data());

	ConvertSpMat(row, col, val, M_invD);
	vex::SpMat<double> _M_invD(ctx, M_invD.rows(), M_invD.columns(), row.data(), col.data(), val.data());

	blaze::DynamicVector<double> gamma(g.size()),rhs(g.size());

	for(int i=0; i<g.size(); i++){
		gamma[i] = g[i];
		rhs[i] = b[i];
	}
	blaze::DynamicVector<double> tmp_cpu(g.size());
	blaze::DynamicVector<double> res_cpu(g.size());
	double start_cpu = omp_get_wtime();

	double RUNS = 1;
	if(argc>1){
		RUNS=atoi(argv[1]);
	}
	for(size_t i = 0; i < RUNS; i++){
		tmp_cpu = M_invD*gamma;
		res_cpu += D_T*tmp_cpu;
	}
	double end_cpu = omp_get_wtime();

	vex::profiler<> prof;

	vex::vector<double> gamma_gpu(ctx,g.size());
	vex::vector<double> b_gpu(ctx,b.size());
	vex::copy(g,gamma_gpu);
	vex::copy(b,b_gpu);
	vex::vector<double> tmp_gpu(ctx,g.size());
	vex::vector<double> res_gpu(ctx,g.size());

	tmp_gpu += _M_invD*gamma_gpu;
	tmp_gpu = 0;
	res_gpu += _D_T*tmp_gpu;
	res_gpu = 0;
	prof.tic_cpu("GPU");
	double start_gpu = omp_get_wtime();
	for(size_t i = 0; i < RUNS; i++){
		tmp_gpu  = _M_invD*gamma_gpu;
		res_gpu  += _D_T*tmp_gpu;
	}
	ctx.finish();
	double end_gpu = omp_get_wtime();
	double tot_time = prof.toc("GPU");
	printf("CPU took %f sec. time.\n", (end_cpu-start_cpu)/RUNS);
	printf("GPU took %f sec. time, %f sec time.\n", (end_gpu-start_gpu)/RUNS, tot_time/RUNS);
	printf("Speedup: %f\n", (end_cpu-start_cpu) /(end_gpu-start_gpu));

	//std::vector<double> res_host(g.size());

	//vex::copy(res_gpu,res_host);

	//printf("copy\n");
	// for(int i=0; i<g.size(); i++){
	// 	if(res_host[i]!=res_cpu[i]){
	// 		printf("%f\n",res_host[i]-res_cpu[i]);
	// 	}
	// }

	return 0;
}<|endoftext|>


<commit_before>//
//  main.cpp
//  lda
//
//  Created by WEI YE on 10/7/13.
//  Copyright (c) 2013 WEI YE. All rights reserved.
//

#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/core/core.hpp>
#include "decomposition.hpp"

using namespace std;
using namespace cv;

bool readData(string filename, Mat_<float>& data)
{
    ifstream dfile;
    dfile.open(filename.c_str(), ios::binary);
    if (!dfile.is_open())
        return false;

    int rows, cols, i, j;
    dfile.read((char*)&rows, sizeof(int));
    dfile.read((char*)&cols, sizeof(int));

    if (rows <= 0 || cols <= 0) {
        return false;
    }

    data.create(rows, cols);
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            dfile.read((char*)(data.ptr<float>(i)+j), sizeof(float));
        }
    }
    return true;
}

// -- Input  --
// x  -  features(N x D)
// y  -  labels  (N x 1)
// w  -  weights (N x 1)
//
// -- Output --
// W  -  transformation matrix;
// Mi -  means of each class
void fisher_lda(const Mat_<float>& x, const Mat_<int>& y, const Mat_<float>& w, Mat_<float>& W, vector<Mat_<float>>& Mi)
{
    int n_point = x.rows;
    int n_dim = x.cols;
    int n_class = *max_element(y.begin(), y.end()) + 1;
    if (n_dim < 1|| n_class < 2 || n_point <= 1 || n_point != y.rows || n_point != w.rows){
        string error_msg = "Invalid training set!";
        CV_Error(CV_StsBadArg, error_msg);
    }

    vector<float> numPoints(n_class, 0);
    Mat_<float> M = Mat_<float>::zeros(1, n_dim); // mean of all points
    Mi = vector<Mat_<float>>(n_class);            // means of each class

    // compute means and covariances
    int p, c;
    for (c = 0; c < n_class; c++)
        Mi[c] = Mat_<float>::zeros(1, n_dim);

    for (p = 0; p < n_point; p++) {
        c = y(p,0);
        numPoints[c] += w(p,0);
        Mi[c] += (x.row(p)*w(p,0));
        M += (x.row(p)*w(p,0));
    }

    for (c = 0; c < n_class; c++)
        Mi[c] /= numPoints[c];
    M /= n_point;

    // compute within-class scatter matrix Sw = sum{ Si }
    Mat_<float> subMean(n_point, n_dim);
    for (p = 0; p < n_point; p++) {
        c = y(p,0);
        subMean.row(p) = x.row(p) - Mi[c];
    }
    Mat_<float> Sw = subMean.t()*subMean;

    // compute between-class scatter matrix Sb
    Mat_<float> Sb(Mat_<float>::zeros(n_dim, n_dim));
    for (c = 0; c < n_class; c++) {
        Mat_<float> diff = Mi[c] - M;
        Sb += numPoints[c]*(diff.t()*diff);
    }

    // compute eigen values/vectors for Sw^-1*Sb
    Mat_<float> eigenValues;
    if (abs(determinant(Sw)) > 1e-3) {
        // eigen(Sw.inv()*Sb, eigenValues, W); // Wrong! OpenCV's "eigen" function only apply for symmetric matrix
        EigenvalueDecomposition eig(Sw.inv()*Sb);
        Mat eigVal = eig.eigenvalues();
        Mat eigVec = eig.eigenvectors();
        eigVal = eigVal.reshape(1, 1);
        Mat order_des;
        sortIdx(eigVal, order_des, CV_SORT_EVERY_ROW + CV_SORT_DESCENDING);
        W = Mat_<float>(n_dim, n_dim);
        for (int i = 0; i < n_dim; i++) {
            eigVec.col(order_des.at<int>(0,i)).copyTo(W.col(i));
        }
    }else{ // Sw is a singular matrix
        string err_msg = "Sw is invertible!";
        CV_Error(CV_StsError, err_msg);
    }
}

// -- Input  --
// X    -  single test data point
// Mi_p -  projected means of each class
//
// -- Return --
// label of X

int predict(const Mat_<float>& X, const vector<Mat_<float>>& Mi_p)
{
    double min_dist = norm(X - Mi_p[0]);
    int label = 0;
    for (int c = 1; c < Mi_p.size(); c++) {
        double dist = norm(X - Mi_p[c]);
        if (dist < min_dist) {
            min_dist = dist;
            label = c;
        }
    }
    return label;
}

int main()
{
    Mat_<float> data, W;
    vector<Mat_<float>> Mi;
    if (!readData("/Users/weiye/Documents/YEWEI/practice/LDA/0_CEHOG1-B16.featbin", data))
        return 1;
//    data = (Mat_<float>(11,2) << 1,2,2,3,3,3,4,5,5,5,1,0,2,1,3,1,3,2,5,3,6,5);

    Mat_<int> labels(data.rows, 1);
    labels.rowRange(0, 1816).setTo(0);
    labels.rowRange(1816, data.rows).setTo(1);

    Mat_<float> weights(Mat_<float>::ones(data.rows, 1));

    fisher_lda(data, labels, weights, W, Mi);

    vector<Mat_<float>> Mi_p(2);
    int N = 1;
    Mat_<float> w = W.colRange(0, N);
    for (int c = 0; c < Mi.size(); c++)
        Mi_p[c] = Mi[c]*w;

    double n_correct = 0.0;
    for (int p = 0; p < data.rows; p++)
        if (predict(data.row(p)*w, Mi_p) == labels(p,0))
            n_correct++;

    cout<<Mi_p[0]<<Mi_p[1]<<endl;
    double accuracy = n_correct/data.rows;
    cout<<"Accuracy = "<<accuracy*100.0<<"%"<<endl;
    return 0;
}
<commit_msg>Minor fix<commit_after>//
//  main.cpp
//  lda
//
//  Created by WEI YE on 10/7/13.
//  Copyright (c) 2013 WEI YE. All rights reserved.
//

#include <iostream>
#include <fstream>
#include <string>
#include <opencv2/core/core.hpp>
#include "decomposition.hpp"

using namespace std;
using namespace cv;

bool readData(string filename, Mat_<float>& data)
{
    ifstream dfile;
    dfile.open(filename.c_str(), ios::binary);
    if (!dfile.is_open())
        return false;

    int rows, cols, i, j;
    dfile.read((char*)&rows, sizeof(int));
    dfile.read((char*)&cols, sizeof(int));

    if (rows <= 0 || cols <= 0) {
        return false;
    }

    data.create(rows, cols);
    for (i = 0; i < rows; i++) {
        for (j = 0; j < cols; j++) {
            dfile.read((char*)(data.ptr<float>(i)+j), sizeof(float));
        }
    }
    return true;
}

// -- Input  --
// x  -  features(N x D)
// y  -  labels  (N x 1)
// w  -  weights (N x 1)
//
// -- Output --
// W  -  transformation matrix;
// Mi -  means of each class
void fisher_lda(const Mat_<float>& x, const Mat_<int>& y, const Mat_<float>& w, Mat_<float>& W, vector<Mat_<float>>& Mi)
{
    int n_point = x.rows;
    int n_dim = x.cols;
    int n_class = *max_element(y.begin(), y.end()) + 1;
    if (n_dim < 1|| n_class < 2 || n_point <= 1 || n_point != y.rows || n_point != w.rows){
        string error_msg = "Invalid training set!";
        CV_Error(CV_StsBadArg, error_msg);
    }

    vector<float> numPoints(n_class, 0);
    Mat_<float> M = Mat_<float>::zeros(1, n_dim); // mean of all points
    Mi = vector<Mat_<float>>(n_class);            // means of each class

    // compute means and covariances
    int p, c;
    for (c = 0; c < n_class; c++)
        Mi[c] = Mat_<float>::zeros(1, n_dim);

    for (p = 0; p < n_point; p++) {
        c = y(p,0);
        numPoints[c] += w(p,0);
        Mi[c] += (x.row(p)*w(p,0));
        M += (x.row(p)*w(p,0));
    }

    for (c = 0; c < n_class; c++)
        Mi[c] /= numPoints[c];
    M /= n_point;

    // compute within-class scatter matrix Sw = sum{ Si }
    Mat_<float> subMean(n_point, n_dim);
    for (p = 0; p < n_point; p++) {
        c = y(p,0);
        subMean.row(p) = x.row(p) - Mi[c];
    }
    Mat_<float> Sw = subMean.t()*subMean;

    // compute between-class scatter matrix Sb
    Mat_<float> Sb(Mat_<float>::zeros(n_dim, n_dim));
    for (c = 0; c < n_class; c++) {
        Mat_<float> diff = Mi[c] - M;
        Sb += numPoints[c]*(diff.t()*diff);
    }

    // compute eigen values/vectors for Sw^-1*Sb
    Mat_<float> eigenValues;
    if (abs(determinant(Sw)) > 1e-3) {
        // eigen(Sw.inv()*Sb, eigenValues, W); // Wrong! OpenCV's "eigen" function only apply for symmetric matrix
        EigenvalueDecomposition eig(Sw.inv()*Sb);
        Mat eigVal = eig.eigenvalues();
        Mat eigVec = eig.eigenvectors();
        eigVal = eigVal.reshape(1, 1);
        Mat order_des;
        sortIdx(eigVal, order_des, CV_SORT_EVERY_ROW + CV_SORT_DESCENDING);
        W = Mat_<float>(n_dim, n_dim);
        for (int i = 0; i < n_dim; i++) {
            eigVec.col(order_des.at<int>(0,i)).copyTo(W.col(i));
        }
    }else{ // Sw is a singular matrix
        string err_msg = "Sw is invertible!";
        CV_Error(CV_StsError, err_msg);
    }
}

// -- Input  --
// X    -  single test data point
// Mi_p -  projected means of each class
//
// -- Return --
// label of X

int predict(const Mat_<float>& X, const vector<Mat_<float>>& Mi_p)
{
    double min_dist = norm(X - Mi_p[0]);
    int label = 0;
    for (int c = 1; c < Mi_p.size(); c++) {
        double dist = norm(X - Mi_p[c]);
        if (dist < min_dist) {
            min_dist = dist;
            label = c;
        }
    }
    return label;
}

int main()
{
    Mat_<float> data, W;
    vector<Mat_<float>> Mi;
    if (!readData("~/Documents/LDA/0_CEHOG1-B16.featbin", data))
        return 1;
//    data = (Mat_<float>(11,2) << 1,2,2,3,3,3,4,5,5,5,1,0,2,1,3,1,3,2,5,3,6,5);

    Mat_<int> labels(data.rows, 1);
    labels.rowRange(0, 1816).setTo(0);
    labels.rowRange(1816, data.rows).setTo(1);

    Mat_<float> weights(Mat_<float>::ones(data.rows, 1));

    fisher_lda(data, labels, weights, W, Mi);

    vector<Mat_<float>> Mi_p(2);
    int N = 1;
    Mat_<float> w = W.colRange(0, N);
    for (int c = 0; c < Mi.size(); c++)
        Mi_p[c] = Mi[c]*w;

    double n_correct = 0.0;
    for (int p = 0; p < data.rows; p++)
        if (predict(data.row(p)*w, Mi_p) == labels(p,0))
            n_correct++;

    cout<<Mi_p[0]<<Mi_p[1]<<endl;
    double accuracy = n_correct/data.rows;
    cout<<"Accuracy = "<<accuracy*100.0<<"%"<<endl;
    return 0;
}
<|endoftext|>


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

#include "operatingsystem.h"
#include "clipcursor.h"
#include "qmlfile.h"

#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

#if defined(Q_OS_MAC)
    //Mac OS X 用のパスを作成する
    QString dir = QString("%1/i18n")
            .arg(QCoreApplication::applicationDirPath());
#else
    //Windows とLinux 用のパスを作成する
    QString dir("i18n");
#endif
    QTranslator translator;
    //言語ファイルの読み込み
    translator.load(QString("qt_%1" ).arg(QLocale::system().name()), dir);
    //言語データを登録する
    app.installTranslator(&translator);
    //Qt標準機能の日本語化(QWebPageとか)
    QTranslator translator2;
    translator2.load(QString("qt_ja" ), dir);
    app.installTranslator(&translator2);

    qmlRegisterType<OperatingSystem>("jp.relog.plugin.operatingsystem"
                                     , 1, 0, "OperatingSystem");
    qmlRegisterType<ClipCursor>("jp.relog.plugin.clipcursor"
                                , 1, 0, "ClipCursor");
    qmlRegisterType<QMLFile>("jp.relog.plugin.qmlfile", 1, 0, "QMLFile");

    MainWindow w;
    w.show();

    return app.exec();
}
<commit_msg>Updated to pre-create the save folder of user data<commit_after>/*
 * Copyright 2013 KanMemo Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mainwindow.h"
#include <QApplication>
#include <QtCore/QTranslator>
#include <QtCore/QLocale>
#include <QQmlEngine>
#include <QStandardPaths>
#include <QDir>

#include "operatingsystem.h"
#include "clipcursor.h"
#include "qmlfile.h"

#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

#if defined(Q_OS_MAC)
    //Mac OS X 用のパスを作成する
    QString dir = QString("%1/i18n")
            .arg(QCoreApplication::applicationDirPath());
#else
    //Windows とLinux 用のパスを作成する
    QString dir("i18n");
#endif
    QTranslator translator;
    //言語ファイルの読み込み
    translator.load(QString("qt_%1" ).arg(QLocale::system().name()), dir);
    //言語データを登録する
    app.installTranslator(&translator);
    //Qt標準機能の日本語化(QWebPageとか)
    QTranslator translator2;
    translator2.load(QString("qt_ja" ), dir);
    app.installTranslator(&translator2);

    qmlRegisterType<OperatingSystem>("jp.relog.plugin.operatingsystem"
                                     , 1, 0, "OperatingSystem");
    qmlRegisterType<ClipCursor>("jp.relog.plugin.clipcursor"
                                , 1, 0, "ClipCursor");
    qmlRegisterType<QMLFile>("jp.relog.plugin.qmlfile", 1, 0, "QMLFile");

    //ダウンロードデータなどの保存場所のディレクトリを作成しておく
    QDir location(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
    if(!location.exists()){
        location.mkdir(QStandardPaths::writableLocation(QStandardPaths::DataLocation));
    }

    MainWindow w;
    w.show();

    return app.exec();
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
#include <map>

#include "vm/context.hpp"
#include "renderer/sdl2_renderer.hpp"
#include "serializer/serializer.hpp"

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
using namespace yagbe;

context ctx;
sdl2_renderer renderer(gpu::screen_size());

#ifdef __EMSCRIPTEN__
emscripten_serializer saves(ctx);
#else
filesave_serializer saves(ctx);
#endif

bool loaded_rom = false;

void one_iter()
{
	if (!loaded_rom)
		return;
	renderer.next_frame();
	while (renderer.step() && !renderer.frame_drawn())
	{
		for(int i = 0; i < 10; i ++)
			ctx.cpu_step();
	}
}

int main(int argc, char * argv[])
{

	std::map<SDL_Keycode, key_handler::key> keys = {
		{ SDLK_LEFT, key_handler::key::Left },
		{ SDLK_RIGHT, key_handler::key::Right },
		{ SDLK_UP, key_handler::key::Up },
		{ SDLK_DOWN, key_handler::key::Down },

		{ SDLK_a, key_handler::key::Select },
		{ SDLK_s, key_handler::key::Start },
		{ SDLK_z, key_handler::key::A },
		{ SDLK_x, key_handler::key::B },
	};

	std::string path = YAGBE_ROMS;

	//path += "../test_roms/individual/01-special.gb"; //PASSED
	//path += "../test_roms/individual/02-interrupts.gb"; //PASSED
	//path += "../test_roms/individual/03-op sp,hl.gb"; //PASSED

	//path += "../test_roms/individual/04-op r,imm.gb"; //PASSED
	//path += "../test_roms/individual/05-op rp.gb"; //PASSED
	//path += "../test_roms/individual/06-ld r,r.gb"; //PASSED

	//path += "../test_roms/individual/07-jr,jp,call,ret,rst.gb"; //PASSED

	//path += "../test_roms/individual/08-misc instrs.gb"; //PASSED

	//path += "../test_roms/individual/09-op r,r.gb"; //PASSED

	//path += "../test_roms/individual/10-bit ops.gb"; //PASSED

	//path += "../test_roms/individual/11-op a,(hl).gb"; //PASSED
	//path += "../test_roms/instr_timing.gb"; //FAILED, timer doesn't work properly

	//path += "hangman.gb";
	//path += "sml.gb";

	path += "adjtris.gb";

	renderer.initialize(ctx);

	renderer.onKeyChanged = [&](SDL_Keycode c, bool v, const sdl2_renderer::key_info& info)
	{
		if (c >= SDLK_0 && c <= SDLK_9 && v)
		{
			int index = c - SDLK_0;
			if (info.shift)
				saves.save_state(index);
			else
				saves.load_state(index);
		}

		auto it = keys.find(c);
		if (it != keys.end())
			ctx.key_handler.set_key(it->second, v);
	};

#ifdef __EMSCRIPTEN__
	int raw_url = EM_ASM_INT({
		var getQueryString = function(field, url) {
			var href = url ? url : window.location.href;
			var reg = new RegExp('[?&]' + field + '=([^&#]*)', 'i');
			var string = reg.exec(href);
			return string ? string[1] : null;
		};

		var url = getQueryString("url") || "";
		return allocate(intArrayFromString(url), 'i8', ALLOC_NORMAL);
	});

	std::cout << "Starting emulator..." << std::endl;
	std::string url = (const char*)raw_url;
	free(raw_url);
	if (!url.empty())
	{
		std::cout << "Getting rom from: " << url << std::endl;

		auto onLoad = [](void*, void* b, int s)
		{
			std::cout << "Done." << std::endl;
			auto rom_info = ctx.load_rom((uint8_t*)b, s);
			if (rom_info)
			{
				loaded_rom = true;
				std::cout << "Loaded OK, name: " << rom_info->game_title() << std::endl;
				return;
			}
			std::cout << "Loading failed" << std::endl;
		};

		auto onError = [](void*)
		{
			std::cout << "Error." << std::endl;
		};

		emscripten_async_wget_data(url.c_str(), nullptr, onLoad, onError);
	}
	else
	{
		std::cout << "Loading built-in rom" << std::endl;
		auto rom_info = ctx.load_rom(path);
		if (!rom_info)
			return -1;
		std::cout << "Loaded built-in OK, name: " << rom_info->game_title() << std::endl;
		loaded_rom = ctx.load_rom(path);
	}

	emscripten_set_main_loop(one_iter, 0, 1);
#else
	auto rom_info = ctx.load_rom(path);
	if (!rom_info)
		return -1;
	loaded_rom = true;

	while (renderer.running())
		one_iter();
#endif

	return 0;
}

/*
Left to do:
- 16h sprites
- RAM & timers in MBC1-3

-sound
*/<commit_msg>Fix compilation.<commit_after>#include <iostream>
#include <stdexcept>
#include <sstream>
#include <string>
#include <map>

#include "vm/context.hpp"
#include "renderer/sdl2_renderer.hpp"
#include "serializer/serializer.hpp"

#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
using namespace yagbe;

context ctx;
sdl2_renderer renderer(gpu::screen_size());

#ifdef __EMSCRIPTEN__
emscripten_serializer saves(ctx);
#else
filesave_serializer saves(ctx);
#endif

bool loaded_rom = false;

void one_iter()
{
	if (!loaded_rom)
		return;
	renderer.next_frame();
	while (renderer.step() && !renderer.frame_drawn())
	{
		for(int i = 0; i < 10; i ++)
			ctx.cpu_step();
	}
}

int main(int argc, char * argv[])
{

	std::map<SDL_Keycode, key_handler::key> keys = {
		{ SDLK_LEFT, key_handler::key::Left },
		{ SDLK_RIGHT, key_handler::key::Right },
		{ SDLK_UP, key_handler::key::Up },
		{ SDLK_DOWN, key_handler::key::Down },

		{ SDLK_a, key_handler::key::Select },
		{ SDLK_s, key_handler::key::Start },
		{ SDLK_z, key_handler::key::A },
		{ SDLK_x, key_handler::key::B },
	};

	std::string path = YAGBE_ROMS;

	//path += "../test_roms/individual/01-special.gb"; //PASSED
	//path += "../test_roms/individual/02-interrupts.gb"; //PASSED
	//path += "../test_roms/individual/03-op sp,hl.gb"; //PASSED

	//path += "../test_roms/individual/04-op r,imm.gb"; //PASSED
	//path += "../test_roms/individual/05-op rp.gb"; //PASSED
	//path += "../test_roms/individual/06-ld r,r.gb"; //PASSED

	//path += "../test_roms/individual/07-jr,jp,call,ret,rst.gb"; //PASSED

	//path += "../test_roms/individual/08-misc instrs.gb"; //PASSED

	//path += "../test_roms/individual/09-op r,r.gb"; //PASSED

	//path += "../test_roms/individual/10-bit ops.gb"; //PASSED

	//path += "../test_roms/individual/11-op a,(hl).gb"; //PASSED
	//path += "../test_roms/instr_timing.gb"; //FAILED, timer doesn't work properly

	//path += "hangman.gb";
	//path += "sml.gb";

	path += "adjtris.gb";

	renderer.initialize(ctx);

	renderer.onKeyChanged = [&](SDL_Keycode c, bool v, const sdl2_renderer::key_info& info)
	{
		if (c >= SDLK_0 && c <= SDLK_9 && v)
		{
			int index = c - SDLK_0;
			if (info.shift)
				saves.save_state(index);
			else
				saves.load_state(index);
		}

		auto it = keys.find(c);
		if (it != keys.end())
			ctx.key_handler.set_key(it->second, v);
	};

#ifdef __EMSCRIPTEN__
	int raw_url = EM_ASM_INT({
		var getQueryString = function(field, url) {
			var href = url ? url : window.location.href;
			var reg = new RegExp('[?&]' + field + '=([^&#]*)', 'i');
			var string = reg.exec(href);
			return string ? string[1] : null;
		};

		var url = getQueryString("url") || "";
		return allocate(intArrayFromString(url), 'i8', ALLOC_NORMAL);
	});

	std::cout << "Starting emulator..." << std::endl;
	std::string url = (const char*)raw_url;
	free((void*)raw_url);
	if (!url.empty())
	{
		std::cout << "Getting rom from: " << url << std::endl;

		auto onLoad = [](void*, void* b, int s)
		{
			std::cout << "Done." << std::endl;
			auto rom_info = ctx.load_rom((uint8_t*)b, s);
			if (rom_info)
			{
				loaded_rom = true;
				std::cout << "Loaded OK, name: " << rom_info->game_title() << std::endl;
				return;
			}
			std::cout << "Loading failed" << std::endl;
		};

		auto onError = [](void*)
		{
			std::cout << "Error." << std::endl;
		};

		emscripten_async_wget_data(url.c_str(), nullptr, onLoad, onError);
	}
	else
	{
		std::cout << "Loading built-in rom" << std::endl;
		auto rom_info = ctx.load_rom(path);
		if (!rom_info)
			return -1;
		std::cout << "Loaded built-in OK, name: " << rom_info->game_title() << std::endl;
		loaded_rom = ctx.load_rom(path);
	}

	emscripten_set_main_loop(one_iter, 0, 1);
#else
	auto rom_info = ctx.load_rom(path);
	if (!rom_info)
		return -1;
	loaded_rom = true;

	while (renderer.running())
		one_iter();
#endif

	return 0;
}

/*
Left to do:
- 16h sprites
- RAM & timers in MBC1-3

-sound
*/<|endoftext|>


<commit_before>#include <cstdio>
#include "Signal.hpp"

class Foo
{
    public:

	Foo() {}

    void bar(int x, int y)
    {
        printf("Foo::bar(%d, %d)\n", x, y);
    }
};

void foobar(int x, int y)
{
    printf("foobar(%d, %d)\n", x, y);
}

int main(void)
{
	Foo foo;
    Signal<int, int> s;

	// Connect a function
    s.connect(foobar);

    // Connect a class method
    s.connect(&foo, &Foo::bar);

    // Create and connect some lambda expression
    s.connect([&foo](int x, int y){
        printf("lambda::"); foo.bar(x, y);
    });

    // Emit the signal !
    s.emit(4, 2);

    return 0;
}
<commit_msg>correct indentation<commit_after>#include <cstdio>
#include "Signal.hpp"

class Foo
{
    public:

	Foo() {}

    void bar(int x, int y)
    {
        printf("Foo::bar(%d, %d)\n", x, y);
    }
};

void foobar(int x, int y)
{
    printf("foobar(%d, %d)\n", x, y);
}

int main(void)
{
    Foo foo;
    Signal<int, int> s;

    // Connect a function
    s.connect(foobar);

    // Connect a class method
    s.connect(&foo, &Foo::bar);

    // Create and connect some lambda expression
    s.connect([&foo](int x, int y){
        printf("lambda::"); foo.bar(x, y);
    });

    // Emit the signal !
    s.emit(4, 2);

    return 0;
}
<|endoftext|>


<commit_before>#include <algorithm>
#include <map>
#include <iostream>
#include <fstream>
#include <cstdio>
#include "document.h"

extern FILE * xmlin;
extern int xmlparse(Document **);

static std::string help_message = "Available commands are:\n\
../xmltool -p file.xml : parse and display the xml file\n\
../xmltool -v file.xml file.xsd : parse both xml and xsd files and display the validation result\n\
../xmltool -t file.xml file.xsl : parse both xml and xsl files and display de transformation result of file.xml by the stylesheet file.xsl\n\
../xmltool -h : displays this help\n";

static int handle_help(int, const char **);
static int handle_validate(int, const char **);
static int handle_process(int, const char **);
static int handle_transform(int, const char **);

// Valid commands (no dash character)
typedef int (*command_handler)(int, const char **) ;
static std::map<std::string, command_handler> command_map = {
  { "h", handle_help},
  { "v", handle_validate },
  { "p", handle_process },
  { "t", handle_transform }
};

int main(int argc, const char ** argv)
{
  // Command must be given
  if (argc < 2)
  {
    std::cerr << "Missing option parameter!" << std::endl
      //<< help_message << std::endl
    ;
    return EXIT_FAILURE;
  }

  // Command must be handled
  std::string cmd(argv[1] + 1);
  std::map<std::string, command_handler>::const_iterator it;
  if ((it = command_map.find(cmd)) == command_map.end())
  {
    std::cerr << "Bad option parameter!" << std::endl
      << help_message << std::endl;
    return EXIT_FAILURE;
  }

  // Call command handler, making argc and argv correspond
  int nb_ignored = 2;
  argc -= nb_ignored;
  argv += nb_ignored;
  return it->second(argc, argv);
}

int handle_help(int, const char **)
{
  std::cerr << help_message;
  return 1;
}

static Document * read_document(const char * fname)
{
  // Change xmlparse input
  FILE * fp = fopen(fname, "r");
  if (fp == nullptr)
  {
    return nullptr;
  }
  xmlin = fp;

  // Construct document
  Document * doc = nullptr;
  xmlparse(&doc); // who gives a f**k about the return code ?

  // TODO semantic analysis

  return doc;
}

int handle_process(int argc, const char ** argv)
{
  if (argc < 1)
  {
    std::cerr << "Filename argument required" << std::endl;
    return EXIT_FAILURE;
  }

  // XML
  Document * doc = read_document(argv[0]);
  if (doc == nullptr) { return EXIT_FAILURE; }
  std::cout << doc->str() << std::endl;
  delete doc;

  return EXIT_SUCCESS;
}

int handle_validate(int argc, const char ** argv)
{
  if (argc < 1)
  {
    std::cerr << "XML filename argument required" << std::endl;
    return EXIT_FAILURE;
  }
  else if (argc < 2)
  {
    std::cerr << "XSD filename argument required" << std::endl;
    return EXIT_FAILURE;
  }

  // XML/XSD
  Document * xml_doc = read_document(argv[0]);
  Document * xsd_doc = read_document(argv[1]);

  // TODO

  delete xml_doc;
  delete xsd_doc;

  return EXIT_SUCCESS;
}

int handle_transform(int argc, const char ** argv)
{
  if (argc < 1)
  {
    std::cerr << "XML filename argument required" << std::endl;
    return EXIT_FAILURE;
  }
  else if (argc < 2)
  {
    std::cerr << "XSL filename argument required" << std::endl;
    return EXIT_FAILURE;
  }

  // XML/XSL
  Document * xml_doc = read_document(argv[0]);
  Document * xsl_doc = read_document(argv[1]);

  // TODO

  delete xsl_doc;
  delete xml_doc;

  return EXIT_FAILURE;
}

// vim:ft=cpp et sw=2 sts=2:
<commit_msg>2 tests !<commit_after>#include <algorithm>
#include <map>
#include <iostream>
#include <fstream>
#include <cstdio>
#include "document.h"

extern FILE * xmlin;
extern int xmlparse(Document **);

static std::string help_message = "Available commands are:\n\
../xmltool -p file.xml : parse and display the xml file\n\
../xmltool -v file.xml file.xsd : parse both xml and xsd files and display the validation result\n\
../xmltool -t file.xml file.xsl : parse both xml and xsl files and display de transformation result of file.xml by the stylesheet file.xsl\n\
../xmltool -h : displays this help\n";

static int handle_help(int, const char **);
static int handle_validate(int, const char **);
static int handle_process(int, const char **);
static int handle_transform(int, const char **);

// Valid commands (no dash character)
typedef int (*command_handler)(int, const char **) ;
static std::map<std::string, command_handler> command_map = {
  { "h", handle_help},
  { "v", handle_validate },
  { "p", handle_process },
  { "t", handle_transform }
};

int main(int argc, const char ** argv)
{
  // Command must be given
  if (argc < 2)
  {
    std::cerr << "No argument given" << std::endl;
    return handle_help(argc, argv);
  }

  // Command must be handled
  std::string cmd(argv[1] + 1);
  std::map<std::string, command_handler>::const_iterator it;
  if ((it = command_map.find(cmd)) == command_map.end())
  {
    return handle_help(argc, argv);
  }

  // Call command handler, making argc and argv correspond
  int nb_ignored = 2;
  argc -= nb_ignored;
  argv += nb_ignored;
  return it->second(argc, argv);
}

int handle_help(int, const char **)
{
  std::cerr << help_message;
  return 1;
}

static Document * read_document(const char * fname)
{
  // Change xmlparse input
  FILE * fp = fopen(fname, "r");
  if (fp == nullptr)
  {
    return nullptr;
  }
  xmlin = fp;

  // Construct document
  Document * doc = nullptr;
  xmlparse(&doc); // who gives a f**k about the return code ?

  // TODO semantic analysis

  return doc;
}

int handle_process(int argc, const char ** argv)
{
  if (argc < 1)
  {
    std::cerr << "Filename argument required" << std::endl;
    return EXIT_FAILURE;
  }

  // XML
  Document * doc = read_document(argv[0]);
  if (doc == nullptr) { return EXIT_FAILURE; }
  std::cout << doc->str() << std::endl;
  delete doc;

  return EXIT_SUCCESS;
}

int handle_validate(int argc, const char ** argv)
{
  if (argc < 1)
  {
    std::cerr << "XML filename argument required" << std::endl;
    return EXIT_FAILURE;
  }
  else if (argc < 2)
  {
    std::cerr << "XSD filename argument required" << std::endl;
    return EXIT_FAILURE;
  }

  // XML/XSD
  Document * xml_doc = read_document(argv[0]);
  Document * xsd_doc = read_document(argv[1]);

  // TODO

  delete xml_doc;
  delete xsd_doc;

  return EXIT_SUCCESS;
}

int handle_transform(int argc, const char ** argv)
{
  if (argc < 1)
  {
    std::cerr << "XML filename argument required" << std::endl;
    return EXIT_FAILURE;
  }
  else if (argc < 2)
  {
    std::cerr << "XSL filename argument required" << std::endl;
    return EXIT_FAILURE;
  }

  // XML/XSL
  Document * xml_doc = read_document(argv[0]);
  Document * xsl_doc = read_document(argv[1]);

  // TODO

  delete xsl_doc;
  delete xml_doc;

  return EXIT_FAILURE;
}

// vim:ft=cpp et sw=2 sts=2:
<|endoftext|>


<commit_before>5899de8a-ad59-11e7-a4d4-ac87a332f658<commit_msg>Did ANOTHER thing<commit_after>590b76e3-ad59-11e7-8a6c-ac87a332f658<|endoftext|>


<commit_before>3e740175-ad5d-11e7-8ca6-ac87a332f658<commit_msg>Fixed that one bug<commit_after>3ef4c799-ad5d-11e7-87f8-ac87a332f658<|endoftext|>


<commit_before>7c451bf8-4b02-11e5-887d-28cfe9171a43<commit_msg>Did ANOTHER thing<commit_after>7c598907-4b02-11e5-bf34-28cfe9171a43<|endoftext|>