<commit_before>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <random>

#include "Stroika/Foundation/Characters/String.h"
#include "Stroika/Foundation/Common/Property.h"
#include "Stroika/Foundation/Containers/Set.h"
#include "Stroika/Foundation/Database/SQL/ORM/Schema.h"
#include "Stroika/Foundation/Database/SQL/ORM/TableConnection.h"
#include "Stroika/Foundation/Database/SQL/ORM/Versioning.h"
#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Execution/Sleep.h"
#include "Stroika/Foundation/Execution/Thread.h"
#include "Stroika/Foundation/IO/FileSystem/WellKnownLocations.h"

#include "ORMEmployeesDB.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Common;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Database;
using namespace Stroika::Foundation::Debug;
using namespace Stroika::Foundation::Execution;

using namespace Database::SQL;
using namespace SQL::ORM;

namespace {

    struct Employee {
        optional<int> ID{};
        String        fName;
        int           fAge{};
        String        fAddress;
        double        fSalary{};
        bool          fStillEmployed{};

        static const ConstantProperty<ObjectVariantMapper> kMapper;
    };
    const ConstantProperty<ObjectVariantMapper> Employee::kMapper{[] () {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<optional<int>> ();
        mapper.AddClass<Employee> (initializer_list<ObjectVariantMapper::StructFieldInfo>{
            {L"id", StructFieldMetaInfo{&Employee::ID}},
            {L"Name", StructFieldMetaInfo{&Employee::fName}},
            {L"Age", StructFieldMetaInfo{&Employee::fAge}},
            {L"Address", StructFieldMetaInfo{&Employee::fAddress}},
            {L"Salary", StructFieldMetaInfo{&Employee::fSalary}},
            {L"Still-Employed", StructFieldMetaInfo{&Employee::fStillEmployed}},
        });
        return mapper;
    }};

    struct Paycheck {
        optional<int> ID{};
        int           fEmployeeRef;
        double        fAmount{};
        Time::Date    fDate;

        static const ConstantProperty<ObjectVariantMapper> kMapper;
    };
    const ConstantProperty<ObjectVariantMapper> Paycheck::kMapper{[] () {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<optional<int>> ();
        mapper.AddClass<Paycheck> (initializer_list<ObjectVariantMapper::StructFieldInfo>{
            {L"id", StructFieldMetaInfo{&Paycheck::ID}},
            {L"Employee-Ref", StructFieldMetaInfo{&Paycheck::fEmployeeRef}},
            {L"Amount", StructFieldMetaInfo{&Paycheck::fAmount}},
            {L"Date", StructFieldMetaInfo{&Paycheck::fDate}},
        });
        return mapper;
    }};

    /**
     *  Combine all the ObjectVariantMappers for the objects we use in this database into one, and
     *  AMEND any mappers as needed to accomodate possible changes in the mappings (like represeting
     *  some things as strings vs. BLOBs etc).
     */
    const ConstantProperty<ObjectVariantMapper> kDBObjectMapper_{[] () {
        ObjectVariantMapper mapper;
        mapper += Employee::kMapper;
        mapper += Paycheck::kMapper;
        return mapper;
    }};

    /*
     * Define the schema, and how to map between the VariantValue objects and the database
     * for the EMPLOYEES table.
     */
    const Schema::Table kEmployeesTableSchema_{
        L"EMPLOYEES",
        /*
         *  use the same names as the ObjectVariantMapper for simpler mapping, or specify an alternate name
         *  for ID, just as an example.
         */
        // clang-format off
        Collection<Schema::Field>{
#if __cpp_designated_initializers
        {.fName = L"ID", .fVariantValueFieldName = L"id"sv, .fRequired = true, .fVariantType = VariantValue::eInteger, .fIsKeyField = true, .fAutoIncrement = true}
        , {.fName = L"NAME", .fVariantValueFieldName = L"Name"sv, .fVariantType = VariantValue::eString}
        , {.fName = L"AGE", .fVariantValueFieldName = L"Age"sv, .fVariantType = VariantValue::eInteger}
        , {.fName = L"ADDRESS", .fVariantValueFieldName = L"Address"sv, .fVariantType = VariantValue::eString}
        , {.fName = L"SALARY", .fVariantValueFieldName = L"Salary"sv, .fVariantType = VariantValue::eFloat}
        , {.fName = L"STILL_EMPLOYED", .fVariantValueFieldName = L"Still-Employed"sv, .fVariantType = VariantValue::eInteger}
#else
        {L"ID", L"id"sv, true, VariantValue::eInteger, nullopt, true, nullopt, nullopt, true}
        , {L"name", L"Name"sv, false, VariantValue::eString}
        , {L"AGE", L"Age"sv, false, VariantValue::eInteger}
        , {L"ADDRESS", L"Address"sv, false, VariantValue::eString}
        , {L"SALARY", L"Salary"sv, false, VariantValue::eFloat}
        , {L"STILL_EMPLOYED", L"Still-Employed"sv, false, VariantValue::eInteger}
#endif
        },
        Schema::CatchAllField{}};

    /*
     * Define the schema, and how to map between the VariantValue objects and the database
     * for the PAYCHECKS table.
     */
    const Schema::Table kPaychecksTableSchema_{
        L"PAYCHECKS",
        Collection<Schema::Field>{
#if __cpp_designated_initializers
        {.fName = L"ID", .fVariantValueFieldName = L"id"sv,  .fRequired = true, .fVariantType = VariantValue::eInteger, .fIsKeyField = true, .fAutoIncrement = true}
        , {.fName = L"EMPLOYEEREF", .fVariantValueFieldName = L"Employee-Ref"sv, .fRequired = true, .fVariantType = VariantValue::eInteger}
        , {.fName = L"AMOUNT", .fVariantValueFieldName = L"Amount"sv, .fVariantType = VariantValue::eFloat}
        , {.fName = L"DATE", .fVariantValueFieldName = L"Date"sv, .fVariantType = VariantValue::eDate}
#else
        {L"ID", L"id"sv, true, VariantValue::eInteger, nullopt, true, nullopt, nullopt, true}
        , {L"EMPLOYEEREF", L"Employee-Ref"sv, true, VariantValue::eInteger, nullopt, false, nullopt, nullopt}
        , {L"AMOUNT", L"Amount"sv, false, VariantValue::eFloat}
        , {L"DATE", L"Date"sv, false, VariantValue::eDate}
#endif
        }};
    // clang-format on

    /*
     * Example thread making updates to the employees table.
     */
    void PeriodicallyUpdateEmployeesTable_ (Connection::Ptr conn)
    {
        TraceContextBumper ctx{"{}::PeriodicallyUpdateEmployeesTable_"};

        auto employeeTableConnection = make_unique<SQL::ORM::TableConnection<Employee>> (conn, kEmployeesTableSchema_, kDBObjectMapper_);

        // Add Initial Employees
        // @todo use __cpp_designated_initializers when we can assume it
        employeeTableConnection->AddNew (Employee{nullopt, L"Paul", 32, L"California", 20000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Allen", 25, L"Texas", 15000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Teddy", 23, L"Norway", 20000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Mark", 25, L"Rich-Mond", 65000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"David", 27, L"Texas", 85000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Kim", 22, L"South-Hall", 45000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"James", 24, L"Houston", 10000.00, true});

        default_random_engine         generator;
        uniform_int_distribution<int> distribution{1, 6};

        // then keep adding/removing people randomly (but dont really remove just mark no longer employed so we
        // can REF in paycheck table
        while (true) {
            static const Sequence<String>    kNames_{L"Joe", L"Phred", L"Barny", L"Sue", L"Anne"};
            uniform_int_distribution<int>    namesDistr{0, static_cast<int> (kNames_.size () - 1)};
            uniform_int_distribution<int>    ageDistr{25, 50};
            static const Sequence<String>    kAddresses{L"Houston", L"Pittsburg", L"New York", L"Paris", L"California"};
            uniform_int_distribution<int>    addressesDistr{0, static_cast<int> (kAddresses.size () - 1)};
            uniform_real_distribution<float> salaryDistr{10000.00, 50000.00};

            try {
                uniform_int_distribution<int> whatTodoDistr{0, 3};
                switch (whatTodoDistr (generator)) {
                    case 0:
                    case 1: {
                        String name = kNames_[namesDistr (generator)];
                        DbgTrace (L"Adding employee %s", name.c_str ());
                        employeeTableConnection->AddNew (Employee{nullopt, name, ageDistr (generator), kAddresses[addressesDistr (generator)], salaryDistr (generator), true});
                    } break;
                    case 2: {
                        // Look somebody up, and fire them
                        auto activeEmps = employeeTableConnection->GetAll ();
                        if (not activeEmps.empty ()) {
                            uniform_int_distribution<int> empDistr{0, static_cast<int> (activeEmps.size () - 1)};
                            Employee                      killMe = activeEmps[empDistr (generator)];
                            Assert (killMe.ID.has_value ());
                            DbgTrace (L"Firing employee: %d, %s", *killMe.ID, killMe.fName.c_str ());
                            killMe.fStillEmployed = false;
                            employeeTableConnection->Update (killMe);
                        }
                    } break;
                }
            }
            catch (...) {
                // no need to check for ThreadAbort excepton, since Sleep is a cancelation point
                DbgTrace (L"Exception processing SQL - this should generally not happen: %s", Characters::ToString (current_exception ()).c_str ());
            }

            Sleep (1s); // **cancelation point**
        }
    }

    /*
     * Example thread making updates to the paychecks table (while consulting the employees table).
     */
    void PeriodicallyWriteChecksForEmployeesTable_ (Connection::Ptr conn)
    {
        TraceContextBumper ctx{"{}::PeriodicallyWriteChecksForEmployeesTable_"};
        auto               employeeTableConnection = make_unique<SQL::ORM::TableConnection<Employee>> (conn, kEmployeesTableSchema_, kDBObjectMapper_);
        auto               paycheckTableConnection = make_unique<SQL::ORM::TableConnection<Paycheck>> (conn, kPaychecksTableSchema_, kDBObjectMapper_);
        while (true) {
            try {
                for (auto employee : employeeTableConnection->GetAll ()) {
                    Assert (employee.ID != nullopt);
                    DbgTrace (L"Writing paycheck for employee #%d (%s) amount %f", *employee.ID, employee.fName.c_str (), employee.fSalary);
                    paycheckTableConnection->AddNew (Paycheck{nullopt, *employee.ID, employee.fSalary / 12, DateTime::Now ().GetDate ()});
                }
            }
            catch (...) {
                // no need to check for ThreadAbort excepton, since Sleep is a cancelation point
                DbgTrace (L"Exception processing SQL - this should generally not happen: %s", Characters::ToString (current_exception ()).c_str ());
            }
            Sleep (2s); // **cancelation point**
        }
    }
}

void Stroika::Samples::SQL::ORMEmployeesDB (const std::function<Connection::Ptr ()>& connectionFactory)
{
    TraceContextBumper ctx{"ORMEmployeesDB"};

    Connection::Ptr conn1 = connectionFactory ();
    Connection::Ptr conn2 = connectionFactory ();

    // setup DB schema (on either connection) before running access threads
    constexpr Configuration::Version kCurrentVersion_ = Configuration::Version{1, 0, Configuration::VersionStage::Alpha, 0};
    ORM::ProvisionForVersion (conn1,
                              kCurrentVersion_,
                              Traversal::Iterable<ORM::Schema::Table>{kEmployeesTableSchema_, kPaychecksTableSchema_});

    /*
     *  Create threads for each of our activities.
     *  When the waitable even times out, the threads will automatically be 'canceled' as they go out of scope.
     */
    Thread::CleanupPtr updateEmpDBThread{Thread::CleanupPtr::eAbortBeforeWaiting, Thread::New ([=] () { PeriodicallyUpdateEmployeesTable_ (conn1); }, Thread::eAutoStart, L"Update Employee Table")};
    Thread::CleanupPtr writeChecks{Thread::CleanupPtr::eAbortBeforeWaiting, Thread::New ([=] () { PeriodicallyWriteChecksForEmployeesTable_ (conn2); }, Thread::eAutoStart, L"Write Checks")};
    Execution::WaitableEvent{}.WaitQuietly (15s);
}
<commit_msg>adjust samples to accomodate recent ORM code change<commit_after>/*
 * Copyright(c) Sophist Solutions, Inc. 1990-2021.  All rights reserved
 */
#include "Stroika/Frameworks/StroikaPreComp.h"

#include <random>

#include "Stroika/Foundation/Characters/String.h"
#include "Stroika/Foundation/Common/Property.h"
#include "Stroika/Foundation/Containers/Set.h"
#include "Stroika/Foundation/Database/SQL/ORM/Schema.h"
#include "Stroika/Foundation/Database/SQL/ORM/TableConnection.h"
#include "Stroika/Foundation/Database/SQL/ORM/Versioning.h"
#include "Stroika/Foundation/Debug/Trace.h"
#include "Stroika/Foundation/Execution/Sleep.h"
#include "Stroika/Foundation/Execution/Thread.h"
#include "Stroika/Foundation/IO/FileSystem/WellKnownLocations.h"

#include "ORMEmployeesDB.h"

using namespace std;

using namespace Stroika::Foundation;
using namespace Stroika::Foundation::Characters;
using namespace Stroika::Foundation::Common;
using namespace Stroika::Foundation::Containers;
using namespace Stroika::Foundation::Database;
using namespace Stroika::Foundation::Debug;
using namespace Stroika::Foundation::Execution;

using namespace Database::SQL;
using namespace SQL::ORM;

namespace {

    struct Employee {
        optional<int> ID{};
        String        fName;
        int           fAge{};
        String        fAddress;
        double        fSalary{};
        bool          fStillEmployed{};

        static const ConstantProperty<ObjectVariantMapper> kMapper;
    };
    const ConstantProperty<ObjectVariantMapper> Employee::kMapper{[] () {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<optional<int>> ();
        mapper.AddClass<Employee> (initializer_list<ObjectVariantMapper::StructFieldInfo>{
            {L"id", StructFieldMetaInfo{&Employee::ID}},
            {L"Name", StructFieldMetaInfo{&Employee::fName}},
            {L"Age", StructFieldMetaInfo{&Employee::fAge}},
            {L"Address", StructFieldMetaInfo{&Employee::fAddress}},
            {L"Salary", StructFieldMetaInfo{&Employee::fSalary}},
            {L"Still-Employed", StructFieldMetaInfo{&Employee::fStillEmployed}},
        });
        return mapper;
    }};

    struct Paycheck {
        optional<int> ID{};
        int           fEmployeeRef;
        double        fAmount{};
        Time::Date    fDate;

        static const ConstantProperty<ObjectVariantMapper> kMapper;
    };
    const ConstantProperty<ObjectVariantMapper> Paycheck::kMapper{[] () {
        ObjectVariantMapper mapper;
        mapper.AddCommonType<optional<int>> ();
        mapper.AddClass<Paycheck> (initializer_list<ObjectVariantMapper::StructFieldInfo>{
            {L"id", StructFieldMetaInfo{&Paycheck::ID}},
            {L"Employee-Ref", StructFieldMetaInfo{&Paycheck::fEmployeeRef}},
            {L"Amount", StructFieldMetaInfo{&Paycheck::fAmount}},
            {L"Date", StructFieldMetaInfo{&Paycheck::fDate}},
        });
        return mapper;
    }};

    /**
     *  Combine all the ObjectVariantMappers for the objects we use in this database into one, and
     *  AMEND any mappers as needed to accomodate possible changes in the mappings (like represeting
     *  some things as strings vs. BLOBs etc).
     */
    const ConstantProperty<ObjectVariantMapper> kDBObjectMapper_{[] () {
        ObjectVariantMapper mapper;
        mapper += Employee::kMapper;
        mapper += Paycheck::kMapper;
        return mapper;
    }};

    /*
     * Define the schema, and how to map between the VariantValue objects and the database
     * for the EMPLOYEES table.
     */
    const Schema::Table kEmployeesTableSchema_{
        L"EMPLOYEES",
        /*
         *  use the same names as the ObjectVariantMapper for simpler mapping, or specify an alternate name
         *  for ID, just as an example.
         */
        // clang-format off
        Collection<Schema::Field>{
#if __cpp_designated_initializers
        {.fName = L"ID", .fVariantValueFieldName = L"id"sv, .fRequired = true, .fVariantType = VariantValue::eInteger, .fIsKeyField = true, .fDefaultExpression = Schema::Field::kDefaultExpression_AutoIncrement}
        , {.fName = L"NAME", .fVariantValueFieldName = L"Name"sv, .fVariantType = VariantValue::eString}
        , {.fName = L"AGE", .fVariantValueFieldName = L"Age"sv, .fVariantType = VariantValue::eInteger}
        , {.fName = L"ADDRESS", .fVariantValueFieldName = L"Address"sv, .fVariantType = VariantValue::eString}
        , {.fName = L"SALARY", .fVariantValueFieldName = L"Salary"sv, .fVariantType = VariantValue::eFloat}
        , {.fName = L"STILL_EMPLOYED", .fVariantValueFieldName = L"Still-Employed"sv, .fVariantType = VariantValue::eInteger}
#else
        {L"ID", L"id"sv, true, VariantValue::eInteger, nullopt, true, nullopt, Schema::Field::kDefaultExpression_AutoIncrement}
        , {L"name", L"Name"sv, false, VariantValue::eString}
        , {L"AGE", L"Age"sv, false, VariantValue::eInteger}
        , {L"ADDRESS", L"Address"sv, false, VariantValue::eString}
        , {L"SALARY", L"Salary"sv, false, VariantValue::eFloat}
        , {L"STILL_EMPLOYED", L"Still-Employed"sv, false, VariantValue::eInteger}
#endif
        },
        Schema::CatchAllField{}};

    /*
     * Define the schema, and how to map between the VariantValue objects and the database
     * for the PAYCHECKS table.
     */
    const Schema::Table kPaychecksTableSchema_{
        L"PAYCHECKS",
        Collection<Schema::Field>{
#if __cpp_designated_initializers
        {.fName = L"ID", .fVariantValueFieldName = L"id"sv,  .fRequired = true, .fVariantType = VariantValue::eInteger, .fIsKeyField = true, .fDefaultExpression = Schema::Field::kDefaultExpression_AutoIncrement}
        , {.fName = L"EMPLOYEEREF", .fVariantValueFieldName = L"Employee-Ref"sv, .fRequired = true, .fVariantType = VariantValue::eInteger}
        , {.fName = L"AMOUNT", .fVariantValueFieldName = L"Amount"sv, .fVariantType = VariantValue::eFloat}
        , {.fName = L"DATE", .fVariantValueFieldName = L"Date"sv, .fVariantType = VariantValue::eDate}
#else
        {L"ID", L"id"sv, true, VariantValue::eInteger, nullopt, true, nullopt, Schema::Field::kDefaultExpression_AutoIncrement}
        , {L"EMPLOYEEREF", L"Employee-Ref"sv, true, VariantValue::eInteger, nullopt, false, nullopt, nullopt}
        , {L"AMOUNT", L"Amount"sv, false, VariantValue::eFloat}
        , {L"DATE", L"Date"sv, false, VariantValue::eDate}
#endif
        }};
    // clang-format on

    /*
     * Example thread making updates to the employees table.
     */
    void PeriodicallyUpdateEmployeesTable_ (Connection::Ptr conn)
    {
        TraceContextBumper ctx{"{}::PeriodicallyUpdateEmployeesTable_"};

        auto employeeTableConnection = make_unique<SQL::ORM::TableConnection<Employee>> (conn, kEmployeesTableSchema_, kDBObjectMapper_);

        // Add Initial Employees
        // @todo use __cpp_designated_initializers when we can assume it
        employeeTableConnection->AddNew (Employee{nullopt, L"Paul", 32, L"California", 20000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Allen", 25, L"Texas", 15000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Teddy", 23, L"Norway", 20000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Mark", 25, L"Rich-Mond", 65000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"David", 27, L"Texas", 85000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"Kim", 22, L"South-Hall", 45000.00, true});
        employeeTableConnection->AddNew (Employee{nullopt, L"James", 24, L"Houston", 10000.00, true});

        default_random_engine         generator;
        uniform_int_distribution<int> distribution{1, 6};

        // then keep adding/removing people randomly (but dont really remove just mark no longer employed so we
        // can REF in paycheck table
        while (true) {
            static const Sequence<String>    kNames_{L"Joe", L"Phred", L"Barny", L"Sue", L"Anne"};
            uniform_int_distribution<int>    namesDistr{0, static_cast<int> (kNames_.size () - 1)};
            uniform_int_distribution<int>    ageDistr{25, 50};
            static const Sequence<String>    kAddresses{L"Houston", L"Pittsburg", L"New York", L"Paris", L"California"};
            uniform_int_distribution<int>    addressesDistr{0, static_cast<int> (kAddresses.size () - 1)};
            uniform_real_distribution<float> salaryDistr{10000.00, 50000.00};

            try {
                uniform_int_distribution<int> whatTodoDistr{0, 3};
                switch (whatTodoDistr (generator)) {
                    case 0:
                    case 1: {
                        String name = kNames_[namesDistr (generator)];
                        DbgTrace (L"Adding employee %s", name.c_str ());
                        employeeTableConnection->AddNew (Employee{nullopt, name, ageDistr (generator), kAddresses[addressesDistr (generator)], salaryDistr (generator), true});
                    } break;
                    case 2: {
                        // Look somebody up, and fire them
                        auto activeEmps = employeeTableConnection->GetAll ();
                        if (not activeEmps.empty ()) {
                            uniform_int_distribution<int> empDistr{0, static_cast<int> (activeEmps.size () - 1)};
                            Employee                      killMe = activeEmps[empDistr (generator)];
                            Assert (killMe.ID.has_value ());
                            DbgTrace (L"Firing employee: %d, %s", *killMe.ID, killMe.fName.c_str ());
                            killMe.fStillEmployed = false;
                            employeeTableConnection->Update (killMe);
                        }
                    } break;
                }
            }
            catch (...) {
                // no need to check for ThreadAbort excepton, since Sleep is a cancelation point
                DbgTrace (L"Exception processing SQL - this should generally not happen: %s", Characters::ToString (current_exception ()).c_str ());
            }

            Sleep (1s); // **cancelation point**
        }
    }

    /*
     * Example thread making updates to the paychecks table (while consulting the employees table).
     */
    void PeriodicallyWriteChecksForEmployeesTable_ (Connection::Ptr conn)
    {
        TraceContextBumper ctx{"{}::PeriodicallyWriteChecksForEmployeesTable_"};
        auto               employeeTableConnection = make_unique<SQL::ORM::TableConnection<Employee>> (conn, kEmployeesTableSchema_, kDBObjectMapper_);
        auto               paycheckTableConnection = make_unique<SQL::ORM::TableConnection<Paycheck>> (conn, kPaychecksTableSchema_, kDBObjectMapper_);
        while (true) {
            try {
                for (auto employee : employeeTableConnection->GetAll ()) {
                    Assert (employee.ID != nullopt);
                    DbgTrace (L"Writing paycheck for employee #%d (%s) amount %f", *employee.ID, employee.fName.c_str (), employee.fSalary);
                    paycheckTableConnection->AddNew (Paycheck{nullopt, *employee.ID, employee.fSalary / 12, DateTime::Now ().GetDate ()});
                }
            }
            catch (...) {
                // no need to check for ThreadAbort excepton, since Sleep is a cancelation point
                DbgTrace (L"Exception processing SQL - this should generally not happen: %s", Characters::ToString (current_exception ()).c_str ());
            }
            Sleep (2s); // **cancelation point**
        }
    }
}

void Stroika::Samples::SQL::ORMEmployeesDB (const std::function<Connection::Ptr ()>& connectionFactory)
{
    TraceContextBumper ctx{"ORMEmployeesDB"};

    Connection::Ptr conn1 = connectionFactory ();
    Connection::Ptr conn2 = connectionFactory ();

    // setup DB schema (on either connection) before running access threads
    constexpr Configuration::Version kCurrentVersion_ = Configuration::Version{1, 0, Configuration::VersionStage::Alpha, 0};
    ORM::ProvisionForVersion (conn1,
                              kCurrentVersion_,
                              Traversal::Iterable<ORM::Schema::Table>{kEmployeesTableSchema_, kPaychecksTableSchema_});

    /*
     *  Create threads for each of our activities.
     *  When the waitable even times out, the threads will automatically be 'canceled' as they go out of scope.
     */
    Thread::CleanupPtr updateEmpDBThread{Thread::CleanupPtr::eAbortBeforeWaiting, Thread::New ([=] () { PeriodicallyUpdateEmployeesTable_ (conn1); }, Thread::eAutoStart, L"Update Employee Table")};
    Thread::CleanupPtr writeChecks{Thread::CleanupPtr::eAbortBeforeWaiting, Thread::New ([=] () { PeriodicallyWriteChecksForEmployeesTable_ (conn2); }, Thread::eAutoStart, L"Write Checks")};
    Execution::WaitableEvent{}.WaitQuietly (15s);
}
<|endoftext|>


<commit_before>/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the Apache License, Version 2.0, please send an email to
 * vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
 * by the terms of the Apache License, Version 2.0.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * ***************************************************************************/

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <stdio.h>

// Used by debugger to detect when DLL is fully loaded and initialized and TraceFunc can be registered.
extern "C" {
    __declspec(dllexport)
    volatile char isInitialized;

    __declspec(dllexport)
    void OnInitialized() {
        volatile char dummy = 0;
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
        isInitialized = 1;
        OnInitialized();
    }

    return TRUE;
}
<commit_msg>Fix mixed-mode debugging on release PTVS builds.<commit_after>/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation.
 *
 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
 * copy of the license can be found in the License.html file at the root of this distribution. If
 * you cannot locate the Apache License, Version 2.0, please send an email to
 * vspython@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
 * by the terms of the Apache License, Version 2.0.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * ***************************************************************************/

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <stdio.h>

// Used by debugger to detect when DLL is fully loaded and initialized and TraceFunc can be registered.
extern "C" {
    __declspec(dllexport)
    volatile char isInitialized;

    __declspec(dllexport) __declspec(noinline)
    void OnInitialized() {
        volatile char dummy = 0;
    }
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
        isInitialized = 1;
        OnInitialized();
    }

    return TRUE;
}
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Copyright (c) 2012, Sergey Lisitsyn
 */

#ifndef TAPKEE_GENERALIZED_EIGEN_EMBEDDING_H_
#define TAPKEE_GENERALIZED_EIGEN_EMBEDDING_H_

#include <shogun/lib/tapkee/utils/arpack_wrapper.hpp>
#include <shogun/lib/tapkee/routines/matrix_operations.hpp>

namespace tapkee
{
namespace tapkee_internal
{

//! Templated implementation of eigendecomposition-based embedding.
template <class LMatrixType, class RMatrixType, class MatrixTypeOperation, int IMPLEMENTATION>
struct generalized_eigen_embedding_impl
{
	/** Construct embedding
	 * @param wm weight matrix to eigendecompose
	 * @param target_dimension target dimension of embedding (number of eigenvectors to find)
	 * @param skip number of eigenvectors to skip
	 */
	virtual EmbeddingResult embed(const LMatrixType& lhs, const RMatrixType& rhs, unsigned int target_dimension, unsigned int skip);
};

//! ARPACK implementation of eigendecomposition-based embedding
template <class LMatrixType, class RMatrixType, class MatrixTypeOperation>
struct generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation, ARPACK>
{
	EmbeddingResult embed(const LMatrixType& lhs, const RMatrixType& rhs, unsigned int target_dimension, unsigned int skip)
	{
		timed_context context("ARPACK DSXUPD generalized eigendecomposition");

		ArpackGeneralizedSelfAdjointEigenSolver<LMatrixType, RMatrixType, MatrixTypeOperation> arpack(lhs,rhs,target_dimension+skip,"SM");

		DenseMatrix embedding_feature_matrix = (arpack.eigenvectors()).block(0,skip,lhs.cols(),target_dimension);

		return EmbeddingResult(embedding_feature_matrix,arpack.eigenvalues().tail(target_dimension));
	}
};

//! Eigen library dense implementation of eigendecomposition
template <class LMatrixType, class RMatrixType, class MatrixTypeOperation>
struct generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation, EIGEN_DENSE_SELFADJOINT_SOLVER>
{
	EmbeddingResult embed(const LMatrixType& lhs, const RMatrixType& rhs, unsigned int target_dimension, unsigned int skip)
	{
		timed_context context("Eigen dense generalized eigendecomposition");

		DenseMatrix dense_lhs = lhs;
		DenseMatrix dense_rhs = rhs;
		Eigen::GeneralizedSelfAdjointEigenSolver<DenseMatrix> solver(dense_lhs, dense_rhs);

		DenseMatrix embedding_feature_matrix = (solver.eigenvectors()).block(0,skip,lhs.cols(),target_dimension);

		return EmbeddingResult(embedding_feature_matrix,solver.eigenvalues().tail(target_dimension));
	}
};

//! Adapter method for various generalized eigendecomposition methods. Currently
//! supports two methods:
//!

//!
 ARPACK_XSXUPD
//!
 EIGEN_DENSE_SELFADJOINT_SOLVER
//!

template <class LMatrixType, class RMatrixType, class MatrixTypeOperation>
EmbeddingResult generalized_eigen_embedding(TAPKEE_EIGEN_EMBEDDING_METHOD method, const LMatrixType& lhs,
                                            const RMatrixType& rhs,
                                            unsigned int target_dimension, unsigned int skip)
{
	switch (method)
	{
		case ARPACK:
			return generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation,
				ARPACK>().embed(lhs, rhs, target_dimension, skip);
		case EIGEN_DENSE_SELFADJOINT_SOLVER:
			return generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation,
				EIGEN_DENSE_SELFADJOINT_SOLVER>().embed(lhs, rhs, target_dimension, skip);
		case RANDOMIZED:
			// TODO fail here
			return EmbeddingResult();
		default: break;
	}
	return EmbeddingResult();
};

}
}

#endif
<commit_msg>Added missed guard for case when ARPACK is not available<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Copyright (c) 2012, Sergey Lisitsyn
 */

#ifndef TAPKEE_GENERALIZED_EIGEN_EMBEDDING_H_
#define TAPKEE_GENERALIZED_EIGEN_EMBEDDING_H_

#include <shogun/lib/tapkee/utils/arpack_wrapper.hpp>
#include <shogun/lib/tapkee/routines/matrix_operations.hpp>

namespace tapkee
{
namespace tapkee_internal
{

//! Templated implementation of eigendecomposition-based embedding.
template <class LMatrixType, class RMatrixType, class MatrixTypeOperation, int IMPLEMENTATION>
struct generalized_eigen_embedding_impl
{
	/** Construct embedding
	 * @param wm weight matrix to eigendecompose
	 * @param target_dimension target dimension of embedding (number of eigenvectors to find)
	 * @param skip number of eigenvectors to skip
	 */
	virtual EmbeddingResult embed(const LMatrixType& lhs, const RMatrixType& rhs, unsigned int target_dimension, unsigned int skip);
};

//! ARPACK implementation of eigendecomposition-based embedding
template <class LMatrixType, class RMatrixType, class MatrixTypeOperation>
struct generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation, ARPACK>
{
	EmbeddingResult embed(const LMatrixType& lhs, const RMatrixType& rhs, unsigned int target_dimension, unsigned int skip)
	{
		timed_context context("ARPACK DSXUPD generalized eigendecomposition");

#ifndef TAPKEE_NO_ARPACK
		ArpackGeneralizedSelfAdjointEigenSolver<LMatrixType, RMatrixType, MatrixTypeOperation> arpack(lhs,rhs,target_dimension+skip,"SM");

		DenseMatrix embedding_feature_matrix = (arpack.eigenvectors()).block(0,skip,lhs.cols(),target_dimension);

		return EmbeddingResult(embedding_feature_matrix,arpack.eigenvalues().tail(target_dimension));
#else
		return EmbeddingResult();
#endif
	}
};

//! Eigen library dense implementation of eigendecomposition
template <class LMatrixType, class RMatrixType, class MatrixTypeOperation>
struct generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation, EIGEN_DENSE_SELFADJOINT_SOLVER>
{
	EmbeddingResult embed(const LMatrixType& lhs, const RMatrixType& rhs, unsigned int target_dimension, unsigned int skip)
	{
		timed_context context("Eigen dense generalized eigendecomposition");

		DenseMatrix dense_lhs = lhs;
		DenseMatrix dense_rhs = rhs;
		Eigen::GeneralizedSelfAdjointEigenSolver<DenseMatrix> solver(dense_lhs, dense_rhs);

		DenseMatrix embedding_feature_matrix = (solver.eigenvectors()).block(0,skip,lhs.cols(),target_dimension);

		return EmbeddingResult(embedding_feature_matrix,solver.eigenvalues().tail(target_dimension));
	}
};

//! Adapter method for various generalized eigendecomposition methods. Currently
//! supports two methods:
//!

//!
 ARPACK_XSXUPD
//!
 EIGEN_DENSE_SELFADJOINT_SOLVER
//!

template <class LMatrixType, class RMatrixType, class MatrixTypeOperation>
EmbeddingResult generalized_eigen_embedding(TAPKEE_EIGEN_EMBEDDING_METHOD method, const LMatrixType& lhs,
                                            const RMatrixType& rhs,
                                            unsigned int target_dimension, unsigned int skip)
{
	switch (method)
	{
#ifndef TAPKEE_NO_ARPACK
		case ARPACK:
			return generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation,
				ARPACK>().embed(lhs, rhs, target_dimension, skip);
#endif
		case EIGEN_DENSE_SELFADJOINT_SOLVER:
			return generalized_eigen_embedding_impl<LMatrixType, RMatrixType, MatrixTypeOperation,
				EIGEN_DENSE_SELFADJOINT_SOLVER>().embed(lhs, rhs, target_dimension, skip);
		case RANDOMIZED:
			// TODO fail here
			return EmbeddingResult();
		default: break;
	}
	return EmbeddingResult();
};

}
}

#endif
<|endoftext|>


<commit_before>#include <albert/scraper.hpp>

#include <iostream>
#include <deque>
#include <fstream>
#include <boost/locale.hpp>

#include <albert/parsers/category_parser.hpp>
#include <albert/parsers/subcategory_parser.hpp>
#include <albert/parsers/product_parser.hpp>

namespace supermarx
{
	scraper::scraper(callback_t _callback, unsigned int _ratelimit)
	: callback(_callback)
	, dl("supermarx albert/1.0", _ratelimit)
	{}

	void scraper::scrape()
	{
		static const std::string domain_uri = "http://www.ah.nl";
		std::deque<std::string> todo;

		category_parser c_p(
			[&](const category_parser::category_uri_t c)
		{
			subcategory_parser sc_p(
				[&](const subcategory_parser::subcategory_uri_t sc)
			{
				todo.push_back(sc);
			});

			sc_p.parse(dl.fetch(domain_uri + c));
		});

		c_p.parse(dl.fetch(domain_uri + "/producten"));

		while(!todo.empty())
		{
			std::string current_uri = todo.front();
			todo.pop_front();

			product_parser p_p(
			[&](const std::string uri)
			{
				todo.push_front(uri);
			},
			callback);

			p_p.parse(dl.fetch(domain_uri + current_uri));
		}
	}
}
<commit_msg>Fixed scraper to use deep hierarchies<commit_after>#include <albert/scraper.hpp>

#include <iostream>
#include <deque>
#include <fstream>
#include <boost/locale.hpp>

#include <albert/parsers/category_parser.hpp>
#include <albert/parsers/subcategory_parser.hpp>
#include <albert/parsers/product_parser.hpp>

namespace supermarx
{
	scraper::scraper(callback_t _callback, unsigned int _ratelimit)
	: callback(_callback)
	, dl("supermarx albert/1.0", _ratelimit)
	{}

	void scraper::scrape()
	{
		static const std::string domain_uri = "http://www.ah.nl";
		std::deque<std::string> todo;

		category_parser c_p(
			[&](const category_parser::category_uri_t c)
		{
			todo.emplace_back(domain_uri + c);
		});

		c_p.parse(dl.fetch(domain_uri + "/producten"));

		while(!todo.empty())
		{
			subcategory_parser sc_p(
				[&](const subcategory_parser::subcategory_uri_t sc)
			{
				todo.push_back(domain_uri + sc);
			});

			product_parser p_p(
			[&](const std::string uri)
			{
				todo.push_front(domain_uri + uri);
			},
			callback);

			std::string current_uri = todo.front();
			todo.pop_front();

			std::cerr << current_uri << std::endl;

			std::string src = dl.fetch(current_uri);

			sc_p.parse(src);
			p_p.parse(src);
		}
	}
}
<|endoftext|>


<commit_before>#include "instrument.h"

Instrument::Instrument()
{
    name[0] = 'i';
    name[1] = 'n';
    name[2] = 's';
    name[3] = 't';
    waveIndex = 0;
    volEntries=1;
    volTable = new unsigned short[256];//64 integers worth
    for(int i = 0; i < 256; i++)
        volTable[i]=0;
    volTable[0] = 0x3F00;
}

Instrument::~Instrument()
{
    delete [] volTable;
}

Instrument::Instrument(std::istream &in)
{
    volTable = NULL;
    input(in);
}
Instrument::Instrument(const Instrument &other)
{
    waveIndex        = other.waveIndex;
    volEntries       = other.volEntries;
    volTable = new unsigned short[256];//64 integers worth
    for(int i = 0; i < 255; i++)
        volTable[i] = other.volTable[i];

}

std::ostream &Instrument::output(std::ostream &out) const
{
    out.write(name, 23);
    out.write((char*)&waveIndex, sizeof(short));

    out.write((char*)&volEntries,1);
    out.write((char*)volTable, volEntries*2);
    //out.write((char*)volDurTable, volEntries);

    return out;
}

std::istream &Instrument::input(std::istream &in)
{
    if(volTable)
        delete [] volTable;

    in.read(name,23);
    in.read((char*)&waveIndex, sizeof(short));
    in.read((char*)&volEntries, 1);
    volTable = new unsigned short[256];
    in.read((char*)volTable, volEntries*2);
    for(int i = volEntries; i < 256; i++)
        volTable[i] = 0;

    return in;
}

void Instrument::setVolTable(unsigned short *table)
{
    for(int i = 0; i < 256; i++)
        volTable[i] = table[i];
}

unsigned char Instrument::getVolume(unsigned char &cur, unsigned char &seg, unsigned char &jump, unsigned char &last)
{
    float desttime = (volTable[cur] &0x00FF);
    unsigned char dest = (volTable[cur] &0xFF00) >> 8;

    if(dest==0xFB || dest == 0xFD)
    {
        jump = desttime;
        if(cur < volEntries-1)
        {
            cur++;
            desttime = (volTable[cur] &0x00FF);
            dest = (volTable[cur] &0xFF00) >> 8;
        }
    }

    unsigned char depth = 0;

    while(dest==0xFF || dest == 0xFC || dest == 0xFE)
    {
        depth++;
        if(depth > 64)
        {
            last = 0;
            return 0;
        }
        if(dest == 0xFF)
        {
            cur = desttime;
        } else if (dest == 0xFC)
        {
            jump--;
            if(jump == 0 && cur < volEntries-1)
                cur++;
            else
                cur = desttime;
        } else if (dest == 0xFE)
        {
            cur = desttime+jump;
        }

        desttime = (volTable[cur] &0x00FF);
        dest = (volTable[cur] &0xFF00) >> 8;
        seg = 0;
    }

    if(seg >= desttime)
    {
        seg= 0;
        if(cur < volEntries-1)
            cur++;
        last = dest;
        return last;
    }

    //Interpolate between the last volume and next over the duration
    if(cur >0)
    {
        //interpolate
        last = last + ((static_cast<float>(dest) - last) * (seg/desttime));
        return  last;
    }
    last = dest;
    return last;
}

void Instrument::fixVolJumps(const unsigned char &index, short difference)
{
    if(difference == 0)
        return;
    for(unsigned short i = 0; i < volEntries; i++)
        if((volTable[i] & 0xFF00) == 0xFF00)//is jump, correct it
        {
            if(difference > 0)
            {
                unsigned char dest = volTable[i] & 0x00FF;
                if(dest >= index)
                {
                    if(dest < 0xFF-difference)
                        volTable[i] += difference;

                }
            }
            else
            {
                unsigned char dest = volTable[i] & 0xFF;
                if(dest >= index)
                {
                    if(dest >= -difference)
                        volTable[i] += difference;
                    else volTable[i] = 0xFF00;

                }

            }
        }
}

bool Instrument::insertVolEntry(unsigned char index, unsigned short entry)
{
    if(volEntries == 0xFFFF)
        return false;
    for(unsigned short last = ++volEntries; last > index; last--)
        volTable[last] = volTable[last-1];
    fixVolJumps(index, 1);
    volTable[index] = entry;
    return true;
}

bool Instrument::removeVolEntry(unsigned char index)
{
    if(volEntries == 0)
        return false;

    for(unsigned short i = index+1; i < volEntries; i++)
        volTable[i-1] = volTable[i];
    fixVolJumps(index, -1);
    volTable[--volEntries] = 0;
    return true;
}

<commit_msg>Implemented pulse index changes<commit_after>#include "instrument.h"

Instrument::Instrument()
{
    name[0] = 'i';
    name[1] = 'n';
    name[2] = 's';
    name[3] = 't';
    waveIndex = 0;
    volEntries=1;
    volTable = new unsigned short[256];//64 integers worth
    for(int i = 0; i < 256; i++)
        volTable[i]=0;
    volTable[0] = 0x3F00;
    pulseIndex = -1;
}

Instrument::~Instrument()
{
    delete [] volTable;
}

Instrument::Instrument(std::istream &in)
{
    volTable = NULL;
    input(in);
}
Instrument::Instrument(const Instrument &other)
{
    waveIndex        = other.waveIndex;
    volEntries       = other.volEntries;
    volTable = new unsigned short[256];//64 integers worth
    for(int i = 0; i < 255; i++)
        volTable[i] = other.volTable[i];

}

std::ostream &Instrument::output(std::ostream &out) const
{
    out.write(name, 23);
    out.write((char*)&waveIndex, sizeof(short));
    out.write((char*)&pulseIndex, sizeof(short));

    out.write((char*)&volEntries,1);
    out.write((char*)volTable, volEntries*2);

    return out;
}

std::istream &Instrument::input(std::istream &in)
{
    if(volTable)
        delete [] volTable;

    in.read(name,23);
    in.read((char*)&waveIndex, sizeof(short));
    in.read((char*)&pulseIndex, sizeof(short));
    in.read((char*)&volEntries, 1);
    volTable = new unsigned short[256];
    in.read((char*)volTable, volEntries*2);
    for(int i = volEntries; i < 256; i++)
        volTable[i] = 0;

    return in;
}

void Instrument::setVolTable(unsigned short *table)
{
    for(int i = 0; i < 256; i++)
        volTable[i] = table[i];
}

unsigned char Instrument::getVolume(unsigned char &cur, unsigned char &seg, unsigned char &jump, unsigned char &last)
{
    float desttime = (volTable[cur] &0x00FF);
    unsigned char dest = (volTable[cur] &0xFF00) >> 8;

    if(dest==0xFB || dest == 0xFD)
    {
        jump = desttime;
        if(cur < volEntries-1)
        {
            cur++;
            desttime = (volTable[cur] &0x00FF);
            dest = (volTable[cur] &0xFF00) >> 8;
        }
    }

    unsigned char depth = 0;

    while(dest==0xFF || dest == 0xFC || dest == 0xFE)
    {
        depth++;
        if(depth > 64)
        {
            last = 0;
            return 0;
        }
        if(dest == 0xFF)
        {
            cur = desttime;
        } else if (dest == 0xFC)
        {
            jump--;
            if(jump == 0 && cur < volEntries-1)
                cur++;
            else
                cur = desttime;
        } else if (dest == 0xFE)
        {
            cur = desttime+jump;
        }

        desttime = (volTable[cur] &0x00FF);
        dest = (volTable[cur] &0xFF00) >> 8;
        seg = 0;
    }

    if(seg >= desttime)
    {
        seg= 0;
        if(cur < volEntries-1)
            cur++;
        last = dest;
        return last;
    }

    //Interpolate between the last volume and next over the duration
    if(cur >0)
    {
        //interpolate
        last = last + ((static_cast<float>(dest) - last) * (seg/desttime));
        return  last;
    }
    last = dest;
    return last;
}

void Instrument::fixVolJumps(const unsigned char &index, short difference)
{
    if(difference == 0)
        return;
    for(unsigned short i = 0; i < volEntries; i++)
        if((volTable[i] & 0xFF00) == 0xFF00)//is jump, correct it
        {
            if(difference > 0)
            {
                unsigned char dest = volTable[i] & 0x00FF;
                if(dest >= index)
                {
                    if(dest < 0xFF-difference)
                        volTable[i] += difference;

                }
            }
            else
            {
                unsigned char dest = volTable[i] & 0xFF;
                if(dest >= index)
                {
                    if(dest >= -difference)
                        volTable[i] += difference;
                    else volTable[i] = 0xFF00;

                }

            }
        }
}

bool Instrument::insertVolEntry(unsigned char index, unsigned short entry)
{
    if(volEntries == 0xFFFF)
        return false;
    for(unsigned short last = ++volEntries; last > index; last--)
        volTable[last] = volTable[last-1];
    fixVolJumps(index, 1);
    volTable[index] = entry;
    return true;
}

bool Instrument::removeVolEntry(unsigned char index)
{
    if(volEntries == 0)
        return false;

    for(unsigned short i = index+1; i < volEntries; i++)
        volTable[i-1] = volTable[i];
    fixVolJumps(index, -1);
    volTable[--volEntries] = 0;
    return true;
}

<|endoftext|>


<commit_before>#ifndef __se3_crba2_hpp__
#define __se3_crba_hpp__

#include "pinocchio/multibody/visitor.hpp"
#include "pinocchio/multibody/model.hpp"
#include <iostream>

namespace se3
{
  inline const Eigen::MatrixXd&
  crba(const Model & model, Data& data,
       const Eigen::VectorXd & q);

} // namespace se3

/* --- Details -------------------------------------------------------------------- */
namespace se3
{
  struct CrbaForwardStep : public fusion::JointVisitor<CrbaForwardStep>
  {
    typedef boost::fusion::vector< const se3::Model&,
				   se3::Data&,
				   const Eigen::VectorXd &
				   > ArgsType;

    JOINT_VISITOR_INIT(CrbaForwardStep);

    template<typename JointModel>
    static void algo(const se3::JointModelBase<JointModel> & jmodel,
		     se3::JointDataBase<typename JointModel::JointData> & jdata,
		     const se3::Model& model,
		     se3::Data& data,
		     const Eigen::VectorXd & q)
    {
      using namespace Eigen;
      using namespace se3;

      const typename JointModel::Index & i = jmodel.id();
      jmodel.calc(jdata.derived(),q);

      data.liMi[i] = model.jointPlacements[i]*jdata.M();
      data.Ycrb[i] = model.inertias[i];
    }

  };

  namespace internal
  {

    template<typename Mat,typename MatRet, int NCOLS>
    struct ForceSetSe3Action
    {
      /* Compute jF = jXi * iF, where jXi is the dual action matrix associated
       * with m, and iF, jF are matrices whose columns are forces. The resolution
       * is done by block operation. It is less efficient than the colwise
       * operation and should not be used. */
      static void run( const SE3 & m,
		       const Eigen::MatrixBase<Mat> & iF,
		       Eigen::MatrixBase<MatRet> & jF );
      // {
      //   typename Mat::template ConstNRowsBlockXpr<3>::Type linear  = iF.template topRows<3>();
      //   typename MatRet::template ConstNRowsBlockXpr<3>::Type angular = iF.template bottomRows<3>();

      //   jF.template topRows   <3>().noalias() = m.rotation()*linear;
      //   jF.template bottomRows<3>().noalias()
      // 	= skew(m.translation())*jF.template topRows<3>() +
      //      m.rotation()*angular;
      // }

    };

    template<typename Mat,typename MatRet>
    struct ForceSetSe3Action<Mat,MatRet,1>
    {
      /* Compute jF = jXi * iF, where jXi is the dual action matrix associated with m,
       * and iF, jF are vectors. */
      static void run( const SE3 & m,
		       const Eigen::MatrixBase<Mat> & iF,
		       Eigen::MatrixBase<MatRet> & jF )
      {
	EIGEN_STATIC_ASSERT_VECTOR_ONLY(Mat);
	EIGEN_STATIC_ASSERT_VECTOR_ONLY(MatRet);
	Eigen::VectorBlock<const Mat,3> linear = iF.template head<3>();
	Eigen::VectorBlock<const Mat,3> angular = iF.template tail<3>();

	jF.template head <3>() = m.rotation()*linear;
	jF.template tail <3>() = (m.translation().cross(jF.template head<3>())
				  + m.rotation()*angular);
      }
    };

    template<typename Mat,typename MatRet>
    static void se3Action( const SE3 & m,
			   const Eigen::MatrixBase<Mat> & iF,
			   Eigen::MatrixBase<MatRet> & jF )
    {
      ForceSetSe3Action<Mat,MatRet,Mat::ColsAtCompileTime>::run(m,iF,jF);
    }

    template<typename Mat,typename MatRet,int NCOLS>
    void ForceSetSe3Action<Mat,MatRet,NCOLS>::
    run( const SE3 & m,
	 const Eigen::MatrixBase<Mat> & iF,
	 Eigen::MatrixBase<MatRet> & jF )
    {
      for(int col=0;col<jF.cols();++col)
	{
	  typename MatRet::ColXpr jFc = jF.col(col);
	  se3Action(m,iF.col(col),jFc);
	}
    }

  } // namespace internal

  struct CrbaBackwardStep : public fusion::JointVisitor<CrbaBackwardStep>
  {
    typedef boost::fusion::vector<const Model&,
				  Data&>  ArgsType;

    JOINT_VISITOR_INIT(CrbaBackwardStep);

    template<typename JointModel>
    static void algo(const JointModelBase<JointModel> & jmodel,
		     JointDataBase<typename JointModel::JointData> & jdata,
		     const Model& model,
		     Data& data)
    {
      /*
       * F[1:6,i] = Y*S
       * M[i,SUBTREE] = S'*F[1:6,SUBTREE]
       * if li>0
       *   Yli += liXi Yi
       *   F[1:6,SUBTREE] = liXi F[1:6,SUBTREE]
       */
      const Model::Index & i = jmodel.id();

      /* F[1:6,i] = Y*S */
      data.Fcrb[i].block<6,JointModel::NV>(0,jmodel.idx_v()) = data.Ycrb[i] * jdata.S();

      /* M[i,SUBTREE] = S'*F[1:6,SUBTREE] */
      data.M.block(jmodel.idx_v(),jmodel.idx_v(),jmodel.nv(),data.nvSubtree[i])
	= jdata.S().transpose()*data.Fcrb[i].block(0,jmodel.idx_v(),6,data.nvSubtree[i]);

      const Model::Index & parent   = model.parents[i];
      if(parent>0)
	{
	  /*   Yli += liXi Yi */
 	  data.Ycrb[parent] += data.liMi[i].act(data.Ycrb[i]);

	  /*   F[1:6,SUBTREE] = liXi F[1:6,SUBTREE] */
	  Eigen::Block<typename Data::Matrix6x> jF
	    = data.Fcrb[parent].block(0,jmodel.idx_v(),6,data.nvSubtree[i]);
 	  internal::se3Action(data.liMi[i],
			      data.Fcrb[i].block(0,jmodel.idx_v(),6,data.nvSubtree[i]),
			      jF);
	}

      // std::cout << "iYi = " << (Inertia::Matrix6)data.Ycrb[i] << std::endl;
      // std::cout << "iSi = " << ConstraintXd(jdata.S()).matrix() << std::endl;
      // std::cout << "liFi = " << jdata.F() << std::endl;
      // std::cout << "M = " <<  data.M << std::endl;
    }
  };

  inline const Eigen::MatrixXd&
  crba(const Model & model, Data& data,
       const Eigen::VectorXd & q)
  {
    for( int i=1;i<model.nbody;++i )
      {
	CrbaForwardStep::run(model.joints[i],data.joints[i],
			     CrbaForwardStep::ArgsType(model,data,q));
      }

    for( int i=model.nbody-1;i>0;--i )
      {
	CrbaBackwardStep::run(model.joints[i],data.joints[i],
			      CrbaBackwardStep::ArgsType(model,data));
      }

    return data.M;
  }
} // namespace se3

#endif // ifndef __se3_crba_hpp__

<commit_msg>Modified CRBA to link properly with the new act-on-set. Timings untouched (4.5us).<commit_after>#ifndef __se3_crba_hpp__
#define __se3_crba_hpp__

#include "pinocchio/multibody/visitor.hpp"
#include "pinocchio/multibody/model.hpp"
#include "pinocchio/spatial/act-on-set.hpp"

#include <iostream>

namespace se3
{
  inline const Eigen::MatrixXd&
  crba(const Model & model, Data& data,
       const Eigen::VectorXd & q);

} // namespace se3

/* --- Details -------------------------------------------------------------------- */
namespace se3
{
  struct CrbaForwardStep : public fusion::JointVisitor<CrbaForwardStep>
  {
    typedef boost::fusion::vector< const se3::Model&,
				   se3::Data&,
				   const Eigen::VectorXd &
				   > ArgsType;

    JOINT_VISITOR_INIT(CrbaForwardStep);

    template<typename JointModel>
    static void algo(const se3::JointModelBase<JointModel> & jmodel,
		     se3::JointDataBase<typename JointModel::JointData> & jdata,
		     const se3::Model& model,
		     se3::Data& data,
		     const Eigen::VectorXd & q)
    {
      using namespace Eigen;
      using namespace se3;

      const typename JointModel::Index & i = jmodel.id();
      jmodel.calc(jdata.derived(),q);

      data.liMi[i] = model.jointPlacements[i]*jdata.M();
      data.Ycrb[i] = model.inertias[i];
    }

  };

  struct CrbaBackwardStep : public fusion::JointVisitor<CrbaBackwardStep>
  {
    typedef boost::fusion::vector<const Model&,
				  Data&>  ArgsType;

    JOINT_VISITOR_INIT(CrbaBackwardStep);

    template<typename JointModel>
    static void algo(const JointModelBase<JointModel> & jmodel,
		     JointDataBase<typename JointModel::JointData> & jdata,
		     const Model& model,
		     Data& data)
    {
      /*
       * F[1:6,i] = Y*S
       * M[i,SUBTREE] = S'*F[1:6,SUBTREE]
       * if li>0
       *   Yli += liXi Yi
       *   F[1:6,SUBTREE] = liXi F[1:6,SUBTREE]
       */
      const Model::Index & i = jmodel.id();

      /* F[1:6,i] = Y*S */
      data.Fcrb[i].block<6,JointModel::NV>(0,jmodel.idx_v()) = data.Ycrb[i] * jdata.S();

      /* M[i,SUBTREE] = S'*F[1:6,SUBTREE] */
      data.M.block(jmodel.idx_v(),jmodel.idx_v(),jmodel.nv(),data.nvSubtree[i])
	= jdata.S().transpose()*data.Fcrb[i].block(0,jmodel.idx_v(),6,data.nvSubtree[i]);

      const Model::Index & parent   = model.parents[i];
      if(parent>0)
	{
	  /*   Yli += liXi Yi */
 	  data.Ycrb[parent] += data.liMi[i].act(data.Ycrb[i]);

	  /*   F[1:6,SUBTREE] = liXi F[1:6,SUBTREE] */
	  Eigen::Block<typename Data::Matrix6x> jF
	    = data.Fcrb[parent].block(0,jmodel.idx_v(),6,data.nvSubtree[i]);
 	  forceSet::se3Action(data.liMi[i],
			      data.Fcrb[i].block(0,jmodel.idx_v(),6,data.nvSubtree[i]),
			      jF);
	}

      // std::cout << "iYi = " << (Inertia::Matrix6)data.Ycrb[i] << std::endl;
      // std::cout << "iSi = " << ConstraintXd(jdata.S()).matrix() << std::endl;
      // std::cout << "liFi = " << jdata.F() << std::endl;
      // std::cout << "M = " <<  data.M << std::endl;
    }
  };

  inline const Eigen::MatrixXd&
  crba(const Model & model, Data& data,
       const Eigen::VectorXd & q)
  {
    for( int i=1;i<model.nbody;++i )
      {
	CrbaForwardStep::run(model.joints[i],data.joints[i],
			     CrbaForwardStep::ArgsType(model,data,q));
      }

    for( int i=model.nbody-1;i>0;--i )
      {
	CrbaBackwardStep::run(model.joints[i],data.joints[i],
			      CrbaBackwardStep::ArgsType(model,data));
      }

    return data.M;
  }
} // namespace se3

#endif // ifndef __se3_crba_hpp__

<|endoftext|>


<commit_before>//
//  i8255.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 01/08/2017.
//  Copyright © 2017 Thomas Harte. All rights reserved.
//

#ifndef i8255_hpp
#define i8255_hpp

namespace Intel {
namespace i8255 {

class PortHandler {
	public:
		void set_value(int port, uint8_t value) {}
		uint8_t get_value(int port) { return 0xff; }
};

// TODO: most of the implementation below. Right now it just blindly passes data in all directions,
// ignoring operation mode. But at least it establishes proper ownership and hand-off of decision making.
template <class T> class i8255 {
	public:
		i8255(T &port_handler) : control_(0), outputs_{0, 0, 0}, port_handler_(port_handler) {}

		void set_register(int address, uint8_t value) {
			switch(address & 3) {
				case 0:	outputs_[0] = value; port_handler_.set_value(0, value);	break;
				case 1:	outputs_[1] = value; port_handler_.set_value(1, value);	break;
				case 2:	outputs_[2] = value; port_handler_.set_value(2, value);	break;
				case 3:
					if(value & 0x80) {
						control_ = value;
					} else {
						if(value & 1) {
							outputs_[2] |= 1 << ((value >> 1)&7);
						} else {
							outputs_[2] &= ~(1 << ((value >> 1)&7));
						}
					}
					update_outputs();
				break;
			}
		}

		uint8_t get_register(int address) {
			switch(address & 3) {
				case 0:	return port_handler_.get_value(0);
				case 1:	return port_handler_.get_value(1);
				case 2:	return port_handler_.get_value(2);
				case 3:	return control_;
			}
			return 0xff;
		}

	private:
		void update_outputs() {
			port_handler_.set_value(0, outputs_[0]);
			port_handler_.set_value(1, outputs_[1]);
			port_handler_.set_value(2, outputs_[2]);
		}

		uint8_t control_;
		uint8_t outputs_[3];
		T &port_handler_;
};

}
}

#endif /* i8255_hpp */
<commit_msg>Added port direction tests.<commit_after>//
//  i8255.hpp
//  Clock Signal
//
//  Created by Thomas Harte on 01/08/2017.
//  Copyright © 2017 Thomas Harte. All rights reserved.
//

#ifndef i8255_hpp
#define i8255_hpp

namespace Intel {
namespace i8255 {

class PortHandler {
	public:
		void set_value(int port, uint8_t value) {}
		uint8_t get_value(int port) { return 0xff; }
};

// TODO: most of the implementation below. Right now it just blindly passes data in all directions,
// ignoring operation mode. But at least it establishes proper ownership and hand-off of decision making.
template <class T> class i8255 {
	public:
		i8255(T &port_handler) : control_(0), outputs_{0, 0, 0}, port_handler_(port_handler) {}

		void set_register(int address, uint8_t value) {
			switch(address & 3) {
				case 0:	outputs_[0] = value; port_handler_.set_value(0, value);	break;
				case 1:	outputs_[1] = value; port_handler_.set_value(1, value);	break;
				case 2:	outputs_[2] = value; port_handler_.set_value(2, value);	break;
				case 3:
					if(value & 0x80) {
						control_ = value;
					} else {
						if(value & 1) {
							outputs_[2] |= 1 << ((value >> 1)&7);
						} else {
							outputs_[2] &= ~(1 << ((value >> 1)&7));
						}
					}
					update_outputs();
				break;
			}
		}

		uint8_t get_register(int address) {
			switch(address & 3) {
				case 0:	return (control_ & 0x10) ? port_handler_.get_value(0) : outputs_[0];
				case 1:	return (control_ & 0x02) ? port_handler_.get_value(1) : outputs_[1];
				case 2:	{
					if(!(control_ & 0x09)) return outputs_[2];
					uint8_t input = port_handler_.get_value(2);
					return ((control_ & 0x01) ? (input & 0x0f) : (outputs_[2] & 0x0f)) | ((control_ & 0x08) ? (input & 0xf0) : (outputs_[2] & 0xf0));
				}
				case 3:	return control_;
			}
			return 0xff;
		}

	private:
		void update_outputs() {
			port_handler_.set_value(0, outputs_[0]);
			port_handler_.set_value(1, outputs_[1]);
			port_handler_.set_value(2, outputs_[2]);
		}

		uint8_t control_;
		uint8_t outputs_[3];
		T &port_handler_;
};

}
}

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


<commit_before>#include "VMusic.h"
#include "VInterpolate.h"

VMusic::VMusic() {}
VMusic::~VMusic() {}

/**
* Opens music data from file.
*/
VMusic* VMusic::OpenMusicFile(const sf::String& filename)
{
	if (music.openFromFile(filename))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return nullptr;
}

/**
* Opens music data from memory.
*/
VMusic* VMusic::OpenMusicMemory(const void* data, size_t size)
{
	if (music.openFromMemory(data, size))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return NULL;
}

/**
* Opens music data from a stream.
*/
VMusic* VMusic::OpenMusicStream(sf::InputStream& stream)
{
	if (music.openFromStream(stream))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return NULL;
}

void VMusic::Update(float dt)
{
	if (!valid)
		return;

	if (Status() == music.Playing)
	{
		if (fadein)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadein = false;
				fadeTimer = 0;
			}
		}

		if (fadeout)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadeout = false;
				fadeTimer = 0;
			}
		}
	}
	else
	{
		fadein = false;
		fadeout = false;
	}
}

void VMusic::Play()
{
	if (!valid)
		return;

	music.play();
}

void VMusic::Pause()
{
	if (!valid)
		return;

	music.pause();
}

void VMusic::Stop()
{
	if (!valid)
		return;

	music.stop();
}

void VMusic::Fade(bool fadeIn, float fadeLength, float maxVolume, float minVolume)
{
	if ((fadeIn && !fadein) || (!fadeIn && !fadeout))
	{
		fadeTime = fadeLength;
		fadeTimer = 0;

		if (fadeIn)
		{
			startVolume = minVolume;
			finishVolume = maxVolume;
			fadein = true;
			fadeout = false;
			music.setVolume(minVolume * (masterVolume / 100.0f));
		}
		else
		{
			startVolume = maxVolume;
			finishVolume = minVolume;
			fadein = false;
			fadeout = true;
			music.setVolume(maxVolume * (masterVolume / 100.0f));
		}
	}
}

sf::Time VMusic::Duration()
{
	if (!valid)
		return sf::Time::Zero;

	return music.getDuration();
}

unsigned int VMusic::ChannelCount()
{
	if (!valid)
		return 0;

	return music.getChannelCount();
}

unsigned int VMusic::SampleRate()
{
	if (!valid)
		return 0;

	return music.getSampleRate();
}

sf::SoundStream::Status VMusic::Status()
{
	if (!valid)
		return sf::SoundStream::Stopped;

	return music.getStatus();
}

float VMusic::Attenuation()
{
	if (!valid)
		return 0;

	return music.getAttenuation();
}

bool VMusic::Loop()
{
	if (!valid)
		return false;

	return music.getLoop();
}

float VMusic::Pitch()
{
	if (!valid)
		return 0;

	return music.getPitch();
}

float VMusic::Volume()
{
	if (!valid)
		return 0;

	return masterVolume;
}

sf::Vector3f VMusic::Position()
{
	if (!valid)
		return sf::Vector3f();

	return music.getPosition();
}

bool VMusic::RelativeToListener()
{
	if (!valid)
		return false;

	return music.isRelativeToListener();
}

float VMusic::MinDistance()
{
	if (!valid)
		return 0;

	return music.getMinDistance();
}

float VMusic::PlayOffset()
{
	if (!valid)
		return 0;

	return music.getPlayingOffset().asSeconds();
}

void VMusic::SetAttenuation(float attenuation)
{
	if (!valid)
		return;

	music.setAttenuation(attenuation);
}

void VMusic::SetLoop(bool loop, float loopStart, float loopEnd)
{
	if (!valid)
		return;

	/*looping = loop;
	loopStartPoint = loopStart;
	if (loopEnd == 0)
		loopEndPoint = music.getDuration().asSeconds();*/

	sf::Music::TimeSpan timespan = sf::Music::TimeSpan(sf::seconds(loopStart), sf::seconds(loopEnd - loopStart));
	music.setLoopPoints(timespan);
	music.setLoop(loop);
}

void VMusic::SetPitch(float pitch)
{
	if (!valid)
		return;

	music.setPitch(pitch);
}

void VMusic::SetVolume(float volume)
{
	if (volume < 0)
		volume = 0;

	masterVolume = volume;

	if (!valid)
		return;

	music.setVolume(masterVolume);
}

void VMusic::SetPosition(float x, float y, float z)
{
	if (!valid)
		return;

	music.setPosition(x, y, z);
}

void VMusic::SetPosition(const sf::Vector3f& position)
{
	if (!valid)
		return;

	music.setPosition(position);
}

void VMusic::SetRelativeToListener(bool relative)
{
	if (!valid)
		return;

	music.setRelativeToListener(relative);
}

void VMusic::SetMinDistance(float distance)
{
	if (!valid)
		return;

	music.setMinDistance(distance);
}

void VMusic::SetPlayOffset(float offset)
{
	if (!valid)
		return;

	music.setPlayingOffset(sf::seconds(offset));
}<commit_msg>Prevent loop points if end point is zero.<commit_after>#include "VMusic.h"
#include "VInterpolate.h"

VMusic::VMusic() {}
VMusic::~VMusic() {}

/**
* Opens music data from file.
*/
VMusic* VMusic::OpenMusicFile(const sf::String& filename)
{
	if (music.openFromFile(filename))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return nullptr;
}

/**
* Opens music data from memory.
*/
VMusic* VMusic::OpenMusicMemory(const void* data, size_t size)
{
	if (music.openFromMemory(data, size))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return NULL;
}

/**
* Opens music data from a stream.
*/
VMusic* VMusic::OpenMusicStream(sf::InputStream& stream)
{
	if (music.openFromStream(stream))
	{
		music.setVolume(masterVolume);
		valid = true;
		return this;
	}

	valid = false;
	return NULL;
}

void VMusic::Update(float dt)
{
	if (!valid)
		return;

	if (Status() == music.Playing)
	{
		if (fadein)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadein = false;
				fadeTimer = 0;
			}
		}

		if (fadeout)
		{
			fadeTimer += dt / fadeTime;
			music.setVolume(VInterpolate::Float(startVolume, finishVolume, fadeTimer) * (masterVolume / 100.0f));

			if (fadeTimer > 1.0f)
			{
				fadeout = false;
				fadeTimer = 0;
			}
		}
	}
	else
	{
		fadein = false;
		fadeout = false;
	}
}

void VMusic::Play()
{
	if (!valid)
		return;

	music.play();
}

void VMusic::Pause()
{
	if (!valid)
		return;

	music.pause();
}

void VMusic::Stop()
{
	if (!valid)
		return;

	music.stop();
}

void VMusic::Fade(bool fadeIn, float fadeLength, float maxVolume, float minVolume)
{
	if ((fadeIn && !fadein) || (!fadeIn && !fadeout))
	{
		fadeTime = fadeLength;
		fadeTimer = 0;

		if (fadeIn)
		{
			startVolume = minVolume;
			finishVolume = maxVolume;
			fadein = true;
			fadeout = false;
			music.setVolume(minVolume * (masterVolume / 100.0f));
		}
		else
		{
			startVolume = maxVolume;
			finishVolume = minVolume;
			fadein = false;
			fadeout = true;
			music.setVolume(maxVolume * (masterVolume / 100.0f));
		}
	}
}

sf::Time VMusic::Duration()
{
	if (!valid)
		return sf::Time::Zero;

	return music.getDuration();
}

unsigned int VMusic::ChannelCount()
{
	if (!valid)
		return 0;

	return music.getChannelCount();
}

unsigned int VMusic::SampleRate()
{
	if (!valid)
		return 0;

	return music.getSampleRate();
}

sf::SoundStream::Status VMusic::Status()
{
	if (!valid)
		return sf::SoundStream::Stopped;

	return music.getStatus();
}

float VMusic::Attenuation()
{
	if (!valid)
		return 0;

	return music.getAttenuation();
}

bool VMusic::Loop()
{
	if (!valid)
		return false;

	return music.getLoop();
}

float VMusic::Pitch()
{
	if (!valid)
		return 0;

	return music.getPitch();
}

float VMusic::Volume()
{
	if (!valid)
		return 0;

	return masterVolume;
}

sf::Vector3f VMusic::Position()
{
	if (!valid)
		return sf::Vector3f();

	return music.getPosition();
}

bool VMusic::RelativeToListener()
{
	if (!valid)
		return false;

	return music.isRelativeToListener();
}

float VMusic::MinDistance()
{
	if (!valid)
		return 0;

	return music.getMinDistance();
}

float VMusic::PlayOffset()
{
	if (!valid)
		return 0;

	return music.getPlayingOffset().asSeconds();
}

void VMusic::SetAttenuation(float attenuation)
{
	if (!valid)
		return;

	music.setAttenuation(attenuation);
}

void VMusic::SetLoop(bool loop, float loopStart, float loopEnd)
{
	if (!valid)
		return;

	/*looping = loop;
	loopStartPoint = loopStart;
	if (loopEnd == 0)
		loopEndPoint = music.getDuration().asSeconds();*/

	if (loopEnd != 0)
	{
		sf::Music::TimeSpan timespan = sf::Music::TimeSpan(sf::seconds(loopStart), sf::seconds(loopEnd - loopStart));
		music.setLoopPoints(timespan);
	}

	music.setLoop(loop);
}

void VMusic::SetPitch(float pitch)
{
	if (!valid)
		return;

	music.setPitch(pitch);
}

void VMusic::SetVolume(float volume)
{
	if (volume < 0)
		volume = 0;

	masterVolume = volume;

	if (!valid)
		return;

	music.setVolume(masterVolume);
}

void VMusic::SetPosition(float x, float y, float z)
{
	if (!valid)
		return;

	music.setPosition(x, y, z);
}

void VMusic::SetPosition(const sf::Vector3f& position)
{
	if (!valid)
		return;

	music.setPosition(position);
}

void VMusic::SetRelativeToListener(bool relative)
{
	if (!valid)
		return;

	music.setRelativeToListener(relative);
}

void VMusic::SetMinDistance(float distance)
{
	if (!valid)
		return;

	music.setMinDistance(distance);
}

void VMusic::SetPlayOffset(float offset)
{
	if (!valid)
		return;

	music.setPlayingOffset(sf::seconds(offset));
}<|endoftext|>


<commit_before>#include "VectorDefiner.h"
#include <algorithm>
#include <cctype>

#include <iostream>
#include <fstream>

//yes
VectorDefiner::VectorDefiner()
{
	this->eqr = NULL;
	this->vectors = NULL;
}

VectorDefiner::~VectorDefiner()
{
	delete this->eqr;
	delete this->vectors;
}

void VectorDefiner::give_input(std::string str){
	//supposedly removes whitespace from the string, effectively trimming it
	std::string* mystr = new std::string(str);
	mystr->erase(std::remove_if(mystr->begin(), mystr->end(), isspace), mystr->end());
	this->is_file = false;
	switch(str[0]){
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '~':
		case '/':
			this->is_file = true;
	}

	if(this->is_file){
		this->filename = mystr;
	}else{
		equation_factory eqrf;
		this->eqr = eqrf.vector_equation(str);
	}

}

void VectorDefiner::populate(std::vector<vector3d*>* space){
	if(this->is_file){
		//I mean, Ideally, the file would be formatted as: x_space,y_space,z_space,x_vector,y_vector,z_vector\n
		//I can deal with whitespace, actually
		//std::string the_file = *(this->filename);
		std::string line;
		std::ifstream csv(this->filename->c_str());
		if(csv.is_open()){
			while(std::getline(csv, line)){
				//line has the data inside of it now. like a civilized language and library should

			}
			csv.close();//be polite
		}
	}else{
		float* f = new float[3];

		if(this->vectors != NULL){
			delete this->vectors;
		}
		this->vectors = new std::vector<vector3d*>();

		for(unsigned int i=0; i<space->size(); ++i){
			float* temp = space->at(i)->xyz(); // get the spacial point
			f = eqr->eval(temp[0],temp[1],temp[2],f); //eval field at that point
			vector3d* vvv = new vector3d(f[0],f[1],f[2]); //make new vector to represent vector at that point in field
			this->vectors->push_back(vvv); //add it to out list of vectors
		}

		delete f;
	}
}

std::vector<vector3d*>* VectorDefiner::cull_vectors(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax){
	std::vector<vector3d*>* vec = new std::vector<vector3d*>();

	for(unsigned int i=0; i<this->vectors->size(); ++i){
		vector3d* v = this->vectors->at(i);
		float* f = v->xyz();
		if(xmin < f[0] && f[0] < xmax){
			if(ymin < f[1] && f[1] < ymax){
				if(zmin < f[2] && f[2] < zmax){
					vec->push_back(v); //vector is in bounds, yay!
				}
			}
		}
	}

	return vec;
}

std::vector<vector3d*>* VectorDefiner::cull_space(std::vector<vector3d*>* space, float xmin, float xmax, float ymin, float ymax, float zmin, float zmax){
	std::vector<vector3d*>* vec = new std::vector<vector3d*>();

	for(unsigned int i=0; i<this->vectors->size(); ++i){
		vector3d* v = this->vectors->at(i);
		vector3d* space_v = space->at(i);
		float* f = v->xyz();
		if(xmin < f[0] && f[0] < xmax){
			if(ymin < f[1] && f[1] < ymax){
				if(zmin < f[2] && f[2] < zmax){
					vec->push_back(space_v); //vector is in bounds, yay!
				}
			}
		}
	}
	return vec;
}

/*void VectorDefiner::Define(char input[50], struct node nodes[NODE_MAX][NODE_MAX][NODE_MAX])
{

}*/
<commit_msg>So, VectorDefiner no longer has a memory leak. But same time, still needs to read from CSV file properly.<commit_after>#include "VectorDefiner.h"
#include <algorithm>
#include <cctype>

#include <iostream>
#include <fstream>

//yes
VectorDefiner::VectorDefiner()
{
	this->eqr = NULL;
	this->vectors = NULL;
	this->is_file = false;
}

VectorDefiner::~VectorDefiner()
{
	delete this->eqr;
	delete this->vectors;
}

void VectorDefiner::give_input(std::string str){
	//supposedly removes whitespace from the string, effectively trimming it
	std::string* mystr = new std::string(str);
	mystr->erase(std::remove_if(mystr->begin(), mystr->end(), isspace), mystr->end());
	this->is_file = false;
	switch(str[0]){
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
		case 'g':
		case 'h':
		case 'i':
		case 'j':
		case 'k':
		case 'l':
		case 'm':
		case 'n':
		case 'o':
		case 'p':
		case 'q':
		case 'r':
		case 's':
		case 't':
		case 'u':
		case 'v':
		case 'w':
		case 'x':
		case 'y':
		case 'z':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '~':
		case '/':
			this->is_file = true;
	}

	if(this->is_file){
		this->filename = mystr;
	}else{
		delete mystr;
		equation_factory eqrf;
		this->eqr = eqrf.vector_equation(str);
	}

}

void VectorDefiner::populate(std::vector<vector3d*>* space){
	if(this->is_file){
		//I mean, Ideally, the file would be formatted as: x_space,y_space,z_space,x_vector,y_vector,z_vector\n
		//I can deal with whitespace, actually
		//std::string the_file = *(this->filename);
		std::string line;
		std::ifstream csv(this->filename->c_str());
		if(csv.is_open()){
			while(std::getline(csv, line)){
				//line has the data inside of it now. like a civilized language and library should

			}
			csv.close();//be polite
		}
	}else{
		float* f = new float[3];

		if(this->vectors != NULL){
			delete this->vectors;
		}
		this->vectors = new std::vector<vector3d*>();

		for(unsigned int i=0; i<space->size(); ++i){
			float* temp = space->at(i)->xyz(); // get the spacial point
			f = eqr->eval(temp[0],temp[1],temp[2],f); //eval field at that point
			vector3d* vvv = new vector3d(f[0],f[1],f[2]); //make new vector to represent vector at that point in field
			this->vectors->push_back(vvv); //add it to out list of vectors
		}

		delete f;
	}
}

std::vector<vector3d*>* VectorDefiner::cull_vectors(float xmin, float xmax, float ymin, float ymax, float zmin, float zmax){
	std::vector<vector3d*>* vec = new std::vector<vector3d*>();

	for(unsigned int i=0; i<this->vectors->size(); ++i){
		vector3d* v = this->vectors->at(i);
		float* f = v->xyz();
		if(xmin < f[0] && f[0] < xmax){
			if(ymin < f[1] && f[1] < ymax){
				if(zmin < f[2] && f[2] < zmax){
					vec->push_back(v); //vector is in bounds, yay!
				}
			}
		}
	}

	return vec;
}

std::vector<vector3d*>* VectorDefiner::cull_space(std::vector<vector3d*>* space, float xmin, float xmax, float ymin, float ymax, float zmin, float zmax){
	std::vector<vector3d*>* vec = new std::vector<vector3d*>();

	for(unsigned int i=0; i<this->vectors->size(); ++i){
		vector3d* v = this->vectors->at(i);
		vector3d* space_v = space->at(i);
		float* f = v->xyz();
		if(xmin < f[0] && f[0] < xmax){
			if(ymin < f[1] && f[1] < ymax){
				if(zmin < f[2] && f[2] < zmax){
					vec->push_back(space_v); //vector is in bounds, yay!
				}
			}
		}
	}
	return vec;
}

/*void VectorDefiner::Define(char input[50], struct node nodes[NODE_MAX][NODE_MAX][NODE_MAX])
{

}*/
<|endoftext|>


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

#include <json/json.h>
#include <iostream>
#include <exception>

#include "JsonSerializer.h"

namespace skywarp {

    JsonSerializer::JsonSerializer() {
    }

    JsonSerializer::~JsonSerializer() {
    }

    string JsonSerializer::serializeRPCResult(string requestId, Json::Value appMessage) {
        try {
            Json::Value JsonRPCResult = generateResultEnvelope(requestId, appMessage);
            Json::FastWriter writer;
            string serializedJsonRPCResult = writer.write(JsonRPCResult);
            return serializedJsonRPCResult;
        } catch (std::exception& e) {
            cout << "Exception serializing: " << e.what() << endl;
            std::cerr << "Exception serializing: " << e.what();
        }

    }

    Json::Value JsonSerializer::generateResultEnvelope(string requestId, Json::Value appMessage) {
        try {
            Json::Value JsonRPCResult;
            JsonRPCResult["jsonrpc"] = "2.0";
            JsonRPCResult["result"] = appMessage;
            JsonRPCResult["id"] = requestId;
            return JsonRPCResult;
        } catch (...) {
            // pending exception handling
        }
    }
}<commit_msg>introduction of serializeRPCError<commit_after>/*
 * Copyright (c) 2014, Juan Carlos Rueda (juancarlosrueda@icloud.com) All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the skywarp++ or skywarp_cpp  Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL JUAN CARLOS RUEDA BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <json/json.h>
#include <iostream>
#include <exception>

#include "JsonSerializer.h"

namespace skywarp {

    JsonSerializer::JsonSerializer() {
    }

    JsonSerializer::~JsonSerializer() {
    }

    string JsonSerializer::serializeRPCResult(string requestId, Json::Value appMessage) {
        try {
            Json::Value JsonRPCResult = generateResultEnvelope(requestId, appMessage);
            Json::FastWriter writer;
            string serializedJsonRPCResult = writer.write(JsonRPCResult);
            return serializedJsonRPCResult;
        } catch (std::exception& e) {
            cout << "Exception serializing: " << e.what() << endl;
            std::cerr << "Exception serializing: " << e.what();
        }

    }

    string JsonSerializer::serializeRPCError(string requestId, int errCode, string errMessage) {
        try {
            Json::Value jsonRPCError;
            Json::Value errorData;

            errorData["code"] = errCode;
            errorData["message"] = errMessage;

            jsonRPCError["jsonrpc"] = "2.0";
            jsonRPCError["error"] = errorData;
            jsonRPCError["id"] = requestId;

            Json::FastWriter writer;
            string serializedJsonRPCError = writer.write(jsonRPCError);
            return serializedJsonRPCError;
        } catch (...) {
            // pending exception handling
        }
    }

    Json::Value JsonSerializer::generateResultEnvelope(string requestId, Json::Value appMessage) {
        try {
            Json::Value JsonRPCResult;
            JsonRPCResult["jsonrpc"] = "2.0";
            JsonRPCResult["result"] = appMessage;
            JsonRPCResult["id"] = requestId;
            return JsonRPCResult;
        } catch (...) {
            // pending exception handling
        }
    }
}<|endoftext|>