<commit_before>

#include <iostream>
#include <iomanip>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>

#include <globjects-base/ref_ptr.h>
#include <globjects-base/formatString.h>

#include <globjects/globjects.h>
#include <globjects/Uniform.h>
#include <globjects/Program.h>
#include <globjects/Shader.h>
#include <globjects/Buffer.h>
#include <globjects/Query.h>
#include <globjects/Framebuffer.h>
#include <globjects/Renderbuffer.h>
#include <globjects/Sampler.h>
#include <globjects/Sync.h>
#include <globjects/Texture.h>
#include <globjects/TransformFeedback.h>
#include <globjects/VertexArray.h>
#include <globjects/logging.h>
#include <globjects/DebugMessage.h>

#include <globjects-window/ContextFormat.h>
#include <globjects-window/Context.h>
#include <globjects-window/Window.h>
#include <globjects-window/WindowEventHandler.h>

#include <ExampleWindowEventHandler.h>

class EventHandler : public ExampleWindowEventHandler
{
public:
    EventHandler()
    {
    }

    virtual ~EventHandler()
    {
    }

    virtual void initialize(glowindow::Window & window) override
    {
        ExampleWindowEventHandler::initialize(window);

        glo::DebugMessage::enable();

        std::cout << "globjects Objects tests" << std::endl;

        glo::ref_ptr<glo::Buffer> buffer(new glo::Buffer());
        std::cout << "glo::Buffer = "; glo::info() << buffer.get();

        std::cout << "glo::FrameBufferObject = "; glo::info() << glo::Framebuffer::defaultFBO();

        glo::ref_ptr<glo::Program> program(new glo::Program());
        std::cout << "glo::Program = "; glo::info() << program.get();

        glo::ref_ptr<glo::Query> query(new glo::Query());
        std::cout << "glo::Query = "; glo::info() << query.get();

        glo::ref_ptr<glo::Renderbuffer> rbo(new glo::Renderbuffer());
        std::cout << "glo::RenderBufferObject = "; glo::info() << rbo.get();

        glo::ref_ptr<glo::Sampler> sampler(new glo::Sampler());
        std::cout << "glo::Sampler = "; glo::info() << sampler.get();

        glo::ref_ptr<glo::Shader> shader(new glo::Shader(gl::GL_VERTEX_SHADER));
        std::cout << "glo::Shader = "; glo::info() << shader.get();

        glo::ref_ptr<glo::Texture> texture(new glo::Texture());
        std::cout << "glo::Texture = "; glo::info() << texture.get();

        glo::ref_ptr<glo::TransformFeedback> tf(new glo::TransformFeedback());
        std::cout << "glo::TransformFeedback = "; glo::info() << tf.get();

        glo::ref_ptr<glo::VertexArray> vao(new glo::VertexArray());
        std::cout << "glo::VertexArray = "; glo::info() << vao.get();

        glo::ref_ptr<glo::Uniform<float>> uniform(new glo::Uniform<float>("Pi", 3.14f));
        std::cout << "glo::Uniform = "; glo::info() << uniform.get();
        std::cout << "glo::AbstractUniform = "; glo::info() << static_cast<glo::AbstractUniform*>(uniform.get());

        std::cout << "glbinding::Version = "; glo::info() << glo::version();

        std::vector<glo::Buffer*> buffers{new glo::Buffer(), new glo::Buffer()};
        std::cout << "std::vector<glo::Buffer*> = "; glo::info() << buffers;

        window.close();
    }
};

/** This example shows ... .
*/
int main(int /*argc*/, char* /*argv*/[])
{
    glowindow::ContextFormat format;
    format.setVersion(3, 2);
    format.setProfile(glowindow::ContextFormat::CoreProfile);

    glowindow::Window window;

    window.setEventHandler(new EventHandler());

    std::cout << "Standard types test" << std::endl;
    std::cout << "const char* \"Hello\" = "; glo::info() << "Hello";
    std::cout << "const std::string& \"Master\" = "; glo::info() << std::string("Master");
    std::cout << "bool true = "; glo::info() << true;
    std::cout << "char 'a' = "; glo::info() << 'a';
    std::cout << "int 42 = "; glo::info() << 42;
    std::cout << "float 3.14 = "; glo::info() << 3.14f;
    std::cout << "double 3.141592654 = "; glo::info() << std::setprecision(10) << 3.141592654;
    std::cout << "long double 2.71828 = "; glo::info() << 2.71828l;
    std::cout << "unsigned integer 23 = "; glo::info() << 23u;
    std::cout << "long integer 1337 = "; glo::info() << 1337l;
    std::cout << "long long integer 1234567890 = "; glo::info() << 1234567890ll;
    std::cout << "unsigned long integer 45123 = "; glo::info() << 45123ul;
    std::cout << "unsigned char 97 = "; glo::info() << 'a';
    std::cout << "void* " << &window << " = "; glo::info() << static_cast<void*>(&window);

    std::cout << std::endl;

    std::cout << "std::array<int, 2> = "; glo::info() << std::array<int, 2>{ { 0, 1 } };
    std::cout << "std::vector<float> = "; glo::info() << std::vector<float>({ 0.1f, 0.2f, 0.3f });

    std::cout << std::endl;

    std::cout << "Format string test" << std::endl;
    std::cout << "Expected: " << "This is a test: 42 pi = +3.14159E+00" << std::endl;
    glo::info("  Actual: This is a test: %; pi = %+0E10.5;", 42, 3.141592653589793);
    std::cout << "Expected: " << "a string - 255 - ______2.72" << std::endl;
    glo::info("  Actual: %; - %X; - %rf?_10.2;", "a string", 255, 2.71828182846);

    std::cout << std::endl;

    if (!window.create(format, "Command Line Output Example"))
    {
        return 1;
    }

    window.show();

    return glowindow::MainLoop::run();
}
<commit_msg>Fix example output<commit_after>

#include <iostream>
#include <iomanip>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/transform.hpp>

#include <globjects-base/ref_ptr.h>
#include <globjects-base/formatString.h>

#include <globjects/globjects.h>
#include <globjects/Uniform.h>
#include <globjects/Program.h>
#include <globjects/Shader.h>
#include <globjects/Buffer.h>
#include <globjects/Query.h>
#include <globjects/Framebuffer.h>
#include <globjects/Renderbuffer.h>
#include <globjects/Sampler.h>
#include <globjects/Sync.h>
#include <globjects/Texture.h>
#include <globjects/TransformFeedback.h>
#include <globjects/VertexArray.h>
#include <globjects/logging.h>
#include <globjects/DebugMessage.h>

#include <globjects-window/ContextFormat.h>
#include <globjects-window/Context.h>
#include <globjects-window/Window.h>
#include <globjects-window/WindowEventHandler.h>

#include <ExampleWindowEventHandler.h>

class EventHandler : public ExampleWindowEventHandler
{
public:
    EventHandler()
    {
    }

    virtual ~EventHandler()
    {
    }

    virtual void initialize(glowindow::Window & window) override
    {
        ExampleWindowEventHandler::initialize(window);

        glo::DebugMessage::enable();

        std::cout << "globjects Objects tests" << std::endl;

        glo::ref_ptr<glo::Buffer> buffer(new glo::Buffer());
        std::cout << "glo::Buffer = "; glo::info() << buffer.get();

        std::cout << "glo::Framebuffer = "; glo::info() << glo::Framebuffer::defaultFBO();

        glo::ref_ptr<glo::Program> program(new glo::Program());
        std::cout << "glo::Program = "; glo::info() << program.get();

        glo::ref_ptr<glo::Query> query(new glo::Query());
        std::cout << "glo::Query = "; glo::info() << query.get();

        glo::ref_ptr<glo::Renderbuffer> rbo(new glo::Renderbuffer());
        std::cout << "glo::Renderbuffer = "; glo::info() << rbo.get();

        glo::ref_ptr<glo::Sampler> sampler(new glo::Sampler());
        std::cout << "glo::Sampler = "; glo::info() << sampler.get();

        glo::ref_ptr<glo::Shader> shader(new glo::Shader(gl::GL_VERTEX_SHADER));
        std::cout << "glo::Shader = "; glo::info() << shader.get();

        glo::ref_ptr<glo::Texture> texture(new glo::Texture());
        std::cout << "glo::Texture = "; glo::info() << texture.get();

        glo::ref_ptr<glo::TransformFeedback> tf(new glo::TransformFeedback());
        std::cout << "glo::TransformFeedback = "; glo::info() << tf.get();

        glo::ref_ptr<glo::VertexArray> vao(new glo::VertexArray());
        std::cout << "glo::VertexArray = "; glo::info() << vao.get();

        glo::ref_ptr<glo::Uniform<float>> uniform(new glo::Uniform<float>("Pi", 3.14f));
        std::cout << "glo::Uniform = "; glo::info() << uniform.get();
        std::cout << "glo::AbstractUniform = "; glo::info() << static_cast<glo::AbstractUniform*>(uniform.get());

        std::cout << "glbinding::Version = "; glo::info() << glo::version();

        std::vector<glo::Buffer*> buffers{new glo::Buffer(), new glo::Buffer()};
        std::cout << "std::vector<glo::Buffer*> = "; glo::info() << buffers;

        window.close();
    }
};

/** This example shows ... .
*/
int main(int /*argc*/, char* /*argv*/[])
{
    glowindow::ContextFormat format;
    format.setVersion(3, 2);
    format.setProfile(glowindow::ContextFormat::CoreProfile);

    glowindow::Window window;

    window.setEventHandler(new EventHandler());

    std::cout << "Standard types test" << std::endl;
    std::cout << "const char* \"Hello\" = "; glo::info() << "Hello";
    std::cout << "const std::string& \"Master\" = "; glo::info() << std::string("Master");
    std::cout << "bool true = "; glo::info() << true;
    std::cout << "char 'a' = "; glo::info() << 'a';
    std::cout << "int 42 = "; glo::info() << 42;
    std::cout << "float 3.14 = "; glo::info() << 3.14f;
    std::cout << "double 3.141592654 = "; glo::info() << std::setprecision(10) << 3.141592654;
    std::cout << "long double 2.71828 = "; glo::info() << 2.71828l;
    std::cout << "unsigned integer 23 = "; glo::info() << 23u;
    std::cout << "long integer 1337 = "; glo::info() << 1337l;
    std::cout << "long long integer 1234567890 = "; glo::info() << 1234567890ll;
    std::cout << "unsigned long integer 45123 = "; glo::info() << 45123ul;
    std::cout << "unsigned char 97 = "; glo::info() << 'a';
    std::cout << "void* " << &window << " = "; glo::info() << static_cast<void*>(&window);

    std::cout << std::endl;

    std::cout << "std::array<int, 2> = "; glo::info() << std::array<int, 2>{ { 0, 1 } };
    std::cout << "std::vector<float> = "; glo::info() << std::vector<float>({ 0.1f, 0.2f, 0.3f });

    std::cout << std::endl;

    std::cout << "Format string test" << std::endl;
    std::cout << "Expected: " << "This is a test: 42 pi = +3.14159E+00" << std::endl;
    glo::info("  Actual: This is a test: %; pi = %+0E10.5;", 42, 3.141592653589793);
    std::cout << "Expected: " << "a string - 255 - ______2.72" << std::endl;
    glo::info("  Actual: %; - %X; - %rf?_10.2;", "a string", 255, 2.71828182846);

    std::cout << std::endl;

    if (!window.create(format, "Command Line Output Example"))
    {
        return 1;
    }

    window.show();

    return glowindow::MainLoop::run();
}
<|endoftext|>


<commit_before>#include <chrono>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <math.h>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>

#include "adios2.h"
#include "mpi.h"

#include "decomp.h"
#include "processConfig.h"
#include "settings.h"
#include "stream.h"

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

    Settings settings;

    /* Check input arguments. Quit if something is wrong. */
    if (settings.processArguments(argc, argv, MPI_COMM_WORLD) ||
        settings.extraArgumentChecks())
    {
        MPI_Finalize();
        return 1;
    }

    adios2::ADIOS adios;
    if (settings.adiosConfigFileName.empty())
    {
        if (!settings.myRank && settings.verbose)
        {
            std::cout << "Use ADIOS without XML configuration " << std::endl;
        }
        adios = adios2::ADIOS(settings.appComm, adios2::DebugON);
    }
    else
    {
        if (!settings.myRank && settings.verbose)
        {
            std::cout << "Use ADIOS xml file " << settings.adiosConfigFileName
                      << std::endl;
        }
        adios = adios2::ADIOS(settings.adiosConfigFileName, settings.appComm,
                              adios2::DebugON);
    }
    Config cfg;
    size_t currentConfigLineNumber = 0;

    try
    {
        cfg = processConfig(settings, &currentConfigLineNumber);
    }
    catch (std::invalid_argument &e) // config file processing errors
    {
        if (!settings.myRank)
        {
            if (!currentConfigLineNumber)
            {
                std::cout << "Config file error: " << e.what() << std::endl;
            }
            else
            {
                std::cout << "Config file error in line "
                          << currentConfigLineNumber << ": " << e.what()
                          << std::endl;
            }
        }

        /* Quit calmly */
        MPI_Finalize();
        return 1;
    }

    try
    {
        /* writing to one stream using two groups is not supported.
         * FIXME: we need to check for this condition and raise error
         */
        /* 1. Assign stream names with group names that appear in
           commands */
        // map of <streamName, groupName>
        std::map<std::string, std::string> groupMap;
        // a vector of streams in the order they appear
        std::vector<std::pair<std::string, Operation>> streamsInOrder;
        for (const auto &cmd : cfg.commands)
        {
            if (cmd->op == Operation::Write)
            {
                auto cmdW = dynamic_cast<CommandWrite *>(cmd.get());
                groupMap[cmdW->streamName] = cmdW->groupName;
                streamsInOrder.push_back(
                    std::make_pair(cmdW->streamName, Operation::Write));
            }
            else if (cmd->op == Operation::Read)
            {
                auto cmdR = dynamic_cast<CommandRead *>(cmd.get());
                groupMap[cmdR->streamName] = cmdR->groupName;
                streamsInOrder.push_back(
                    std::make_pair(cmdR->streamName, Operation::Read));
            }
        }

        std::map<std::string, std::shared_ptr<ioGroup>> ioMap;

        /* 2. Declare/define groups and open streams in the order they
         * appear */
        std::map<std::string, std::shared_ptr<Stream>> readStreamMap;
        std::map<std::string, std::shared_ptr<Stream>> writeStreamMap;

        for (const auto &st : streamsInOrder)
        {
            const std::string &streamName = st.first;
            std::shared_ptr<ioGroup> io;
            auto &groupName = groupMap[streamName];
            auto it = ioMap.find(groupName);
            if (it == ioMap.end())
            {
                io = createGroup(groupName, settings.iolib, adios);
                ioMap[groupName] = io;
            }
            else
            {
                io = it->second;
            }
            const bool isWrite = (st.second == Operation::Write);
            if (isWrite)
            {
                auto it = writeStreamMap.find(streamName);
                if (it == writeStreamMap.end())
                {
                    std::shared_ptr<Stream> writer =
                        openStream(streamName, io, adios2::Mode::Write,
                                   settings.iolib, settings.appComm);
                    writeStreamMap[streamName] = writer;
                }
            }
            else /* Read */
            {
                auto it = readStreamMap.find(streamName);
                if (it == readStreamMap.end())
                {
                    std::shared_ptr<Stream> reader =
                        openStream(streamName, io, adios2::Mode::Read,
                                   settings.iolib, settings.appComm);
                    readStreamMap[streamName] = reader;
                }
            }
        }

        /* Execute commands */
        bool exitLoop = false;
        size_t step = 1;
        while (!exitLoop)
        {
            if (!settings.myRank)
            {
                std::cout << "App " + std::to_string(settings.appId) + " Step "
                          << step << ": " << std::endl;
            }
            for (const auto cmd : cfg.commands)
            {
                if (!cmd->conditionalStream.empty() &&
                    cfg.condMap.at(cmd->conditionalStream) !=
                        adios2::StepStatus::OK)
                {
                    if (!settings.myRank && settings.verbose)
                    {
                        std::cout << "    Skip command because of status "
                                     "of stream "
                                  << cmd->conditionalStream << std::endl;
                    }
                    continue;
                }

                switch (cmd->op)
                {
                case Operation::Sleep:
                {
                    auto cmdS = dynamic_cast<const CommandSleep *>(cmd.get());
                    if (!settings.myRank && settings.verbose)
                    {
                        double t =
                            static_cast<double>(cmdS->sleepTime_us) / 1000000.0;
                        std::cout << "    Sleep for " << t << "  seconds "
                                  << std::endl;
                    }
                    std::this_thread::sleep_for(
                        std::chrono::microseconds(cmdS->sleepTime_us));
                    break;
                }
                case Operation::Busy:
                {
                    auto cmdS = dynamic_cast<const CommandBusy *>(cmd.get());
                    std::chrono::high_resolution_clock::time_point start =
                        std::chrono::high_resolution_clock::now();
                    if (!settings.myRank && settings.verbose)
                    {
                        double t =
                            static_cast<double>(cmdS->busyTime_us) / 1000000.0;
                        std::cout << "    Be busy for " << t << "  seconds "
                                  << std::endl;
                    }
                    while (std::chrono::high_resolution_clock::now() <
                           start + std::chrono::microseconds(cmdS->busyTime_us))
                        ;
                    break;
                }
                case Operation::Write:
                {
                    auto cmdW = dynamic_cast<CommandWrite *>(cmd.get());
                    auto stream = writeStreamMap[cmdW->streamName];
                    // auto io = ioMap[cmdW->groupName];
                    stream->Write(cmdW, cfg, settings, step);
                    break;
                }
                case Operation::Read:
                {
                    auto cmdR = dynamic_cast<CommandRead *>(cmd.get());
                    auto statusIt = cfg.condMap.find(cmdR->streamName);
                    if (statusIt->second == adios2::StepStatus::OK ||
                        statusIt->second == adios2::StepStatus::NotReady)
                    {
                        auto stream = readStreamMap[cmdR->streamName];
                        // auto io = ioMap[cmdR->groupName];
                        adios2::StepStatus status =
                            stream->Read(cmdR, cfg, settings, step);
                        statusIt->second = status;
                        switch (status)
                        {
                        case adios2::StepStatus::OK:
                            break;
                        case adios2::StepStatus::NotReady:
                            if (!settings.myRank && settings.verbose)
                            {
                                std::cout << "    Nonblocking read status: "
                                             "Not Ready "
                                          << std::endl;
                            }
                            break;
                        case adios2::StepStatus::EndOfStream:
                        case adios2::StepStatus::OtherError:
                            cfg.stepOverStreams.erase(cmdR->streamName);
                            if (!settings.myRank && settings.verbose)
                            {
                                std::cout << "    Nonblocking read status: "
                                             "Terminated "
                                          << std::endl;
                            }
                            break;
                        }
                    }
                    break;
                }
                }
                if (!settings.myRank && settings.verbose)
                {
                    std::cout << std::endl;
                }
            }
            if (!cfg.stepOverStreams.size() && step >= cfg.nSteps)
            {
                exitLoop = true;
            }
            ++step;
        }

        /* Close all streams in order of opening */
        for (const auto &st : streamsInOrder)
        {
            const std::string &streamName = st.first;
            const bool isWrite = (st.second == Operation::Write);
            if (isWrite)
            {
                auto writerIt = writeStreamMap.find(streamName);
                if (writerIt != writeStreamMap.end())
                {
                    auto writer = writeStreamMap[streamName];
                    writerIt->second->Close();
                    writeStreamMap.erase(writerIt);
                }
            }
            else /* Read */
            {
                auto readerIt = readStreamMap.find(streamName);
                if (readerIt != readStreamMap.end())
                {
                    auto reader = readStreamMap[streamName];
                    readerIt->second->Close();
                    readStreamMap.erase(readerIt);
                }
            }
        }
    }
    catch (std::exception &e) // if some unknown error occurs
    {
        if (!settings.myRank)
        {
            std::cout << "ADIOS " << e.what() << std::endl;
        }

        /* Yell and quit */
        MPI_Abort(settings.appComm, -1);
    }

    MPI_Finalize();
    return 0;
}
<commit_msg>adios_iotest measure total testing time and print at the end<commit_after>#include <chrono>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <math.h>
#include <stdexcept>
#include <string>
#include <thread>
#include <vector>

#include "adios2.h"
#include "mpi.h"

#include "decomp.h"
#include "processConfig.h"
#include "settings.h"
#include "stream.h"

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

    Settings settings;

    /* Check input arguments. Quit if something is wrong. */
    if (settings.processArguments(argc, argv, MPI_COMM_WORLD) ||
        settings.extraArgumentChecks())
    {
        MPI_Finalize();
        return 1;
    }

    adios2::ADIOS adios;
    if (settings.adiosConfigFileName.empty())
    {
        if (!settings.myRank && settings.verbose)
        {
            std::cout << "Use ADIOS without XML configuration " << std::endl;
        }
        adios = adios2::ADIOS(settings.appComm, adios2::DebugON);
    }
    else
    {
        if (!settings.myRank && settings.verbose)
        {
            std::cout << "Use ADIOS xml file " << settings.adiosConfigFileName
                      << std::endl;
        }
        adios = adios2::ADIOS(settings.adiosConfigFileName, settings.appComm,
                              adios2::DebugON);
    }
    Config cfg;
    size_t currentConfigLineNumber = 0;

    try
    {
        cfg = processConfig(settings, &currentConfigLineNumber);
    }
    catch (std::invalid_argument &e) // config file processing errors
    {
        if (!settings.myRank)
        {
            if (!currentConfigLineNumber)
            {
                std::cout << "Config file error: " << e.what() << std::endl;
            }
            else
            {
                std::cout << "Config file error in line "
                          << currentConfigLineNumber << ": " << e.what()
                          << std::endl;
            }
        }

        /* Quit calmly */
        MPI_Finalize();
        return 1;
    }

    double timeStart, timeEnd;
    MPI_Barrier(settings.appComm);
    timeStart = MPI_Wtime();

    try
    {
        /* writing to one stream using two groups is not supported.
         * FIXME: we need to check for this condition and raise error
         */
        /* 1. Assign stream names with group names that appear in
           commands */
        // map of <streamName, groupName>
        std::map<std::string, std::string> groupMap;
        // a vector of streams in the order they appear
        std::vector<std::pair<std::string, Operation>> streamsInOrder;
        for (const auto &cmd : cfg.commands)
        {
            if (cmd->op == Operation::Write)
            {
                auto cmdW = dynamic_cast<CommandWrite *>(cmd.get());
                groupMap[cmdW->streamName] = cmdW->groupName;
                streamsInOrder.push_back(
                    std::make_pair(cmdW->streamName, Operation::Write));
            }
            else if (cmd->op == Operation::Read)
            {
                auto cmdR = dynamic_cast<CommandRead *>(cmd.get());
                groupMap[cmdR->streamName] = cmdR->groupName;
                streamsInOrder.push_back(
                    std::make_pair(cmdR->streamName, Operation::Read));
            }
        }

        std::map<std::string, std::shared_ptr<ioGroup>> ioMap;

        /* 2. Declare/define groups and open streams in the order they
         * appear */
        std::map<std::string, std::shared_ptr<Stream>> readStreamMap;
        std::map<std::string, std::shared_ptr<Stream>> writeStreamMap;

        for (const auto &st : streamsInOrder)
        {
            const std::string &streamName = st.first;
            std::shared_ptr<ioGroup> io;
            auto &groupName = groupMap[streamName];
            auto it = ioMap.find(groupName);
            if (it == ioMap.end())
            {
                io = createGroup(groupName, settings.iolib, adios);
                ioMap[groupName] = io;
            }
            else
            {
                io = it->second;
            }
            const bool isWrite = (st.second == Operation::Write);
            if (isWrite)
            {
                auto it = writeStreamMap.find(streamName);
                if (it == writeStreamMap.end())
                {
                    std::shared_ptr<Stream> writer =
                        openStream(streamName, io, adios2::Mode::Write,
                                   settings.iolib, settings.appComm);
                    writeStreamMap[streamName] = writer;
                }
            }
            else /* Read */
            {
                auto it = readStreamMap.find(streamName);
                if (it == readStreamMap.end())
                {
                    std::shared_ptr<Stream> reader =
                        openStream(streamName, io, adios2::Mode::Read,
                                   settings.iolib, settings.appComm);
                    readStreamMap[streamName] = reader;
                }
            }
        }

        /* Execute commands */
        bool exitLoop = false;
        size_t step = 1;
        while (!exitLoop)
        {
            if (!settings.myRank)
            {
                std::cout << "App " + std::to_string(settings.appId) + " Step "
                          << step << ": " << std::endl;
            }
            for (const auto cmd : cfg.commands)
            {
                if (!cmd->conditionalStream.empty() &&
                    cfg.condMap.at(cmd->conditionalStream) !=
                        adios2::StepStatus::OK)
                {
                    if (!settings.myRank && settings.verbose)
                    {
                        std::cout << "    Skip command because of status "
                                     "of stream "
                                  << cmd->conditionalStream << std::endl;
                    }
                    continue;
                }

                switch (cmd->op)
                {
                case Operation::Sleep:
                {
                    auto cmdS = dynamic_cast<const CommandSleep *>(cmd.get());
                    if (!settings.myRank && settings.verbose)
                    {
                        double t =
                            static_cast<double>(cmdS->sleepTime_us) / 1000000.0;
                        std::cout << "    Sleep for " << t << "  seconds "
                                  << std::endl;
                    }
                    std::this_thread::sleep_for(
                        std::chrono::microseconds(cmdS->sleepTime_us));
                    break;
                }
                case Operation::Busy:
                {
                    auto cmdS = dynamic_cast<const CommandBusy *>(cmd.get());
                    std::chrono::high_resolution_clock::time_point start =
                        std::chrono::high_resolution_clock::now();
                    if (!settings.myRank && settings.verbose)
                    {
                        double t =
                            static_cast<double>(cmdS->busyTime_us) / 1000000.0;
                        std::cout << "    Be busy for " << t << "  seconds "
                                  << std::endl;
                    }
                    while (std::chrono::high_resolution_clock::now() <
                           start + std::chrono::microseconds(cmdS->busyTime_us))
                        ;
                    break;
                }
                case Operation::Write:
                {
                    auto cmdW = dynamic_cast<CommandWrite *>(cmd.get());
                    auto stream = writeStreamMap[cmdW->streamName];
                    // auto io = ioMap[cmdW->groupName];
                    stream->Write(cmdW, cfg, settings, step);
                    break;
                }
                case Operation::Read:
                {
                    auto cmdR = dynamic_cast<CommandRead *>(cmd.get());
                    auto statusIt = cfg.condMap.find(cmdR->streamName);
                    if (statusIt->second == adios2::StepStatus::OK ||
                        statusIt->second == adios2::StepStatus::NotReady)
                    {
                        auto stream = readStreamMap[cmdR->streamName];
                        // auto io = ioMap[cmdR->groupName];
                        adios2::StepStatus status =
                            stream->Read(cmdR, cfg, settings, step);
                        statusIt->second = status;
                        switch (status)
                        {
                        case adios2::StepStatus::OK:
                            break;
                        case adios2::StepStatus::NotReady:
                            if (!settings.myRank && settings.verbose)
                            {
                                std::cout << "    Nonblocking read status: "
                                             "Not Ready "
                                          << std::endl;
                            }
                            break;
                        case adios2::StepStatus::EndOfStream:
                        case adios2::StepStatus::OtherError:
                            cfg.stepOverStreams.erase(cmdR->streamName);
                            if (!settings.myRank && settings.verbose)
                            {
                                std::cout << "    Nonblocking read status: "
                                             "Terminated "
                                          << std::endl;
                            }
                            break;
                        }
                    }
                    break;
                }
                }
                if (!settings.myRank && settings.verbose)
                {
                    std::cout << std::endl;
                }
            }
            if (!cfg.stepOverStreams.size() && step >= cfg.nSteps)
            {
                exitLoop = true;
            }
            ++step;
        }

        /* Close all streams in order of opening */
        for (const auto &st : streamsInOrder)
        {
            const std::string &streamName = st.first;
            const bool isWrite = (st.second == Operation::Write);
            if (isWrite)
            {
                auto writerIt = writeStreamMap.find(streamName);
                if (writerIt != writeStreamMap.end())
                {
                    auto writer = writeStreamMap[streamName];
                    writerIt->second->Close();
                    writeStreamMap.erase(writerIt);
                }
            }
            else /* Read */
            {
                auto readerIt = readStreamMap.find(streamName);
                if (readerIt != readStreamMap.end())
                {
                    auto reader = readStreamMap[streamName];
                    readerIt->second->Close();
                    readStreamMap.erase(readerIt);
                }
            }
        }
    }
    catch (std::exception &e) // if some unknown error occurs
    {
        if (!settings.myRank)
        {
            std::cout << "ADIOS " << e.what() << std::endl;
        }

        /* Yell and quit */
        MPI_Abort(settings.appComm, -1);
    }

    MPI_Barrier(settings.appComm);
    timeEnd = MPI_Wtime();
    if (!settings.myRank)
    {
        std::cout << "ADIOS IOTEST test loop time " << timeEnd - timeStart
                  << "  seconds " << std::endl;
    }

    MPI_Finalize();
    return 0;
}
<|endoftext|>


<commit_before>#include "Script.hpp"

#include <fstream>
#include <cassert>

#include "../ResourceManager/AssetManager.hpp"
//#include "../GUI/Window.hpp"
//#include "../GUI/Widgets/Button.hpp"
//#include "../GUI/Widgets/Label.hpp"
//#include "../GUI/Widgets/TextBox.hpp"
//#include "../GUI/Widgets/Toggle.hpp"

namespace swift
{
	sf::RenderWindow* Script::window = nullptr;
	AssetManager* Script::assets = nullptr;
	sf::Clock* Script::clock = nullptr;
	Settings* Script::settings = nullptr;

	Script::Script()
			:	gui(nullptr),
				stateReturn(nullptr)
	{
		deleteMe = false;

		// We don't want to give the scripts access to os commands or file writing abilities
		luaState.OpenLib("base", luaopen_base);
		luaState.OpenLib("math", luaopen_math);
		luaState.OpenLib("string", luaopen_string);
		luaState.OpenLib("table", luaopen_table);

		addVariables();
		addClasses();
		addFunctions();
	}

	Script::~Script()
	{
	}

	bool Script::loadFromFile(const std::string& file)
	{
		bool r = luaState.Load(file);	// r will be false if errors, true otherwise

		return r;
	}

	void Script::start()
	{
		luaState["Start"]();

		if(static_cast<bool>(luaState["Done"]) == true)
		{
			deleteMe = true;
		}
	}

	void Script::run()
	{
		luaState["Update"]();

		if(static_cast<bool>(luaState["Done"]) == true)
		{
			deleteMe = true;
		}
	}

	bool Script::toDelete()
	{
		return deleteMe;
	}

	void Script::setWindow(sf::RenderWindow& win)
	{
		window = &win;
	}

	void Script::setAssetManager(AssetManager& am)
	{
		assets = &am;
	}

	void Script::setSettings(Settings& s)
	{
		settings = &s;
	}

	void Script::setGUI(cstr::Window& ui)
	{
		gui = &ui;
	}

	void Script::setKeyboard(KeyboardManager& k)
	{
		keyboard = &k;
	}

	void Script::setStateReturn(State::Type& t)
	{
		stateReturn = &t;
	}

	void Script::setClock(sf::Clock& c)
	{
		clock = &c;
	}

	void Script::addVariables()
	{
		luaState["states"]["MainMenu"] = 0;
		luaState["states"]["Settings"] = 1;
		luaState["states"]["Play"] = 2;
		luaState["states"]["Exit"] = 3;
	}

	void Script::addClasses()
	{

	}

	void Script::addFunctions()
	{
		// utility functions
		luaState["getWindowSize"] = [&]()
		{
			if(window)
				return std::make_tuple(window->getSize().x, window->getSize().y);
			else
				return std::make_tuple(0u, 0u);
		};

		luaState["getTime"] = [&]()
		{
			if(clock)
				return clock->getElapsedTime().asSeconds();
			else
				return 0.f;
		};

		luaState["doKeypress"] = [&](std::string k) -> void
		{
			if(keyboard)
				keyboard->call(k);
		};

		// gui functions
		luaState["setFont"] = [&](std::string f) -> void
		{
			if(gui)
				gui->setFont(assets->getFont(f));
		};

		// State functions
		luaState["setStateReturn"] = [&](unsigned s)
		{
			*stateReturn = static_cast<State::Type>(s);
		};

		// Settings functions
		luaState["getSettingStr"] = [&](std::string n)
		{
			std::string v;
			return std::make_tuple(settings->get(n, v), v);
		};

		luaState["setSettingStr"] = [&](std::string n, std::string v)
		{
			return settings->set(n, v);
		};

		luaState["getSettingBool"] = [&](std::string n)
		{
			bool v;
			return std::make_tuple(settings->get(n, v), v);
		};

		luaState["setSettingBool"] = [&](std::string n, bool v)
		{
			return settings->set(n, v);
		};

		luaState["getSettingNum"] = [&](std::string n)
		{
			int v;
			return std::make_tuple(settings->get(n, v), v);
		};

		luaState["setSettingNum"] = [&](std::string n, int v)
		{
			return settings->set(n, v);
		};
	}
}<commit_msg>added section for EntitySystem functions<commit_after>#include "Script.hpp"

#include <fstream>
#include <cassert>

#include "../ResourceManager/AssetManager.hpp"

/* GUI */
#include "../GUI/Window.hpp"
#include "../GUI/Widgets/Button.hpp"
#include "../GUI/Widgets/Label.hpp"
#include "../GUI/Widgets/TextBox.hpp"
#include "../GUI/Widgets/Toggle.hpp"

/* EntitySystem */
#include "../EntitySystem/Entity.hpp"

namespace swift
{
	sf::RenderWindow* Script::window = nullptr;
	AssetManager* Script::assets = nullptr;
	sf::Clock* Script::clock = nullptr;
	Settings* Script::settings = nullptr;

	Script::Script()
			:	gui(nullptr),
				stateReturn(nullptr)
	{
		deleteMe = false;

		// We don't want to give the scripts access to os commands or file writing abilities
		luaState.OpenLib("base", luaopen_base);
		luaState.OpenLib("math", luaopen_math);
		luaState.OpenLib("string", luaopen_string);
		luaState.OpenLib("table", luaopen_table);

		addVariables();
		addClasses();
		addFunctions();
	}

	Script::~Script()
	{
	}

	bool Script::loadFromFile(const std::string& file)
	{
		bool r = luaState.Load(file);	// r will be false if errors, true otherwise

		return r;
	}

	void Script::start()
	{
		luaState["Start"]();

		if(static_cast<bool>(luaState["Done"]) == true)
		{
			deleteMe = true;
		}
	}

	void Script::run()
	{
		luaState["Update"]();

		if(static_cast<bool>(luaState["Done"]) == true)
		{
			deleteMe = true;
		}
	}

	bool Script::toDelete()
	{
		return deleteMe;
	}

	void Script::setWindow(sf::RenderWindow& win)
	{
		window = &win;
	}

	void Script::setAssetManager(AssetManager& am)
	{
		assets = &am;
	}

	void Script::setSettings(Settings& s)
	{
		settings = &s;
	}

	void Script::setGUI(cstr::Window& ui)
	{
		gui = &ui;
	}

	void Script::setKeyboard(KeyboardManager& k)
	{
		keyboard = &k;
	}

	void Script::setStateReturn(State::Type& t)
	{
		stateReturn = &t;
	}

	void Script::setClock(sf::Clock& c)
	{
		clock = &c;
	}

	void Script::addVariables()
	{
		luaState["states"]["MainMenu"] = 0;
		luaState["states"]["Settings"] = 1;
		luaState["states"]["Play"] = 2;
		luaState["states"]["Exit"] = 3;
	}

	void Script::addClasses()
	{
		luaState["Entity"].SetClass<Entity>();
	}

	void Script::addFunctions()
	{
		// utility functions
		luaState["getWindowSize"] = [&]()
		{
			if(window)
				return std::make_tuple(window->getSize().x, window->getSize().y);
			else
				return std::make_tuple(0u, 0u);
		};

		luaState["getTime"] = [&]()
		{
			if(clock)
				return clock->getElapsedTime().asSeconds();
			else
				return 0.f;
		};

		luaState["doKeypress"] = [&](std::string k)
		{
			if(keyboard)
				keyboard->call(k);
		};

		// EntitySystem functions

		// gui functions
		luaState["setFont"] = [&](std::string f)
		{
			if(gui)
				gui->setFont(assets->getFont(f));
		};

		// State functions
		luaState["setStateReturn"] = [&](unsigned s)
		{
			*stateReturn = static_cast<State::Type>(s);
		};

		// Settings functions
		luaState["getSettingStr"] = [&](std::string n)
		{
			std::string v;
			return std::make_tuple(settings->get(n, v), v);
		};

		luaState["setSettingStr"] = [&](std::string n, std::string v)
		{
			return settings->set(n, v);
		};

		luaState["getSettingBool"] = [&](std::string n)
		{
			bool v;
			return std::make_tuple(settings->get(n, v), v);
		};

		luaState["setSettingBool"] = [&](std::string n, bool v)
		{
			return settings->set(n, v);
		};

		luaState["getSettingNum"] = [&](std::string n)
		{
			int v;
			return std::make_tuple(settings->get(n, v), v);
		};

		luaState["setSettingNum"] = [&](std::string n, int v)
		{
			return settings->set(n, v);
		};
	}
}<|endoftext|>


<commit_before>//
// file : function.hpp
// in : file:///home/tim/projects/nsched/nsched/tools/function.hpp
//
// created by : Timothée Feuillet on linux.site
// date: 17/07/2014 11:59:09
//
//
// Copyright (C) 2014 Timothée Feuillet
//
// 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 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#ifndef __N_2111737739159269973_1204098121__FUNCTION_HPP__
# define __N_2111737739159269973_1204098121__FUNCTION_HPP__

#include <tools/ct_list.hpp>
#include <tools/execute_pack.hpp> // some magic
#include <tools/constructor_call.hpp>
#include <tools/param.hpp>

namespace neam
{
  namespace ct
  {
    // /// ///
    // for a ct function wrapper
    // /// ///

    // the wrappers
    template<typename PtrType, PtrType Ptr, typename... Args> struct function_wrapper {};      // the one that wrap
    template<typename PtrType, PtrType Ptr, typename... Args> struct _sub_function_wrapper {}; // the result one

    // for C functions
    template<typename PtrType, PtrType Ptr, typename Return, typename... FuncArgList>
    struct function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>>
    {
      template<typename... Types>
      static constexpr _sub_function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>, type_list<Types...>> wrap(Types... values)
      {
        return _sub_function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>, type_list<Types...>>(values...);
      }
    };

    template<typename PtrType, PtrType Ptr, typename Return, typename... FuncArgList, typename... ArgList>
    struct _sub_function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>, type_list<ArgList...>>
    {
      static_assert(sizeof...(FuncArgList) == sizeof...(ArgList), "the number of supplied argument does not match the function's arity");

      constexpr _sub_function_wrapper(ArgList... values)

      {
      }
    };

    // /// ///
    // function traits
    // /// ///

    template<typename FunctionType>
    struct function_traits
    {
      static constexpr bool is_function = false;
    };
    template<typename FunctionType>
    constexpr bool function_traits<FunctionType>::is_function;

    // standard function
    template<typename Return, typename... Parameters>
    struct function_traits<Return (Parameters...)>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = false;
      using return_type = Return;
      using ptr_type = Return (*)(Parameters...);
      using arg_list = type_list<Parameters...>;

      template<ptr_type ptr>
      using create_wrapper = function_wrapper<ptr_type, ptr, Return, /*Class,*/ arg_list>;
    };
    template<typename Return, typename... Parameters>
    constexpr bool function_traits<Return (Parameters...)>::is_function;
    template<typename Return, typename... Parameters>
    constexpr bool function_traits<Return (Parameters...)>::is_member;

    // class member function
    template<typename Return, typename Class,typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...)>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = false;
      static constexpr bool is_volatile = false;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...);
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_volatile;

    template<typename Return, typename Class, typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...) const>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = true;
      static constexpr bool is_volatile = false;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...) const;
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_volatile;

    template<typename Return, typename Class, typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...) volatile>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = false;
      static constexpr bool is_volatile = true;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...) volatile;
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_volatile;

    template<typename Return, typename Class, typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...) const volatile>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = false;
      static constexpr bool is_volatile = true;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...) const volatile;
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_volatile;

  } // namespace ct
} // namespace neam

#endif /*__N_2111737739159269973_1204098121__FUNCTION_HPP__*/

// kate: indent-mode cstyle; indent-width 2; replace-tabs on;

<commit_msg>[NEAM/TOOLS]: added back some function traits in function.hpp for YagGLer<commit_after>//
// file : function.hpp
// in : file:///home/tim/projects/nsched/nsched/tools/function.hpp
//
// created by : Timothée Feuillet on linux.site
// date: 17/07/2014 11:59:09
//
//
// Copyright (C) 2014 Timothée Feuillet
//
// 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 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//

#ifndef __N_2111737739159269973_1204098121__FUNCTION_HPP__
# define __N_2111737739159269973_1204098121__FUNCTION_HPP__

#include <tools/ct_list.hpp>
#include <tools/execute_pack.hpp> // some magic
#include <tools/constructor_call.hpp>
#include <tools/param.hpp>

namespace neam
{
  namespace ct
  {
    template<typename Ptr>
    struct is_function_pointer
    {
      static constexpr bool value = false;
    };
    template<typename Ret, typename... Params>
    struct is_function_pointer<Ret(*)(Params...)>
    {
      static constexpr bool value = true;
    };
    template<typename Ret, typename... Params>
    struct is_function_pointer<Ret(*)(Params......)>
    {
      static constexpr bool value = true;
    };
    template<typename Ret, typename... Params>
    struct is_function_pointer<Ret(&)(Params...)>
    {
      static constexpr bool value = true;
    };
    template<typename Ret, typename... Params>
    struct is_function_pointer<Ret(&)(Params......)>
    {
      static constexpr bool value = true;
    };

    // /// ///
    // for a ct function wrapper
    // /// ///

    // the wrappers
    template<typename PtrType, PtrType Ptr, typename... Args> struct function_wrapper {};      // the one that wrap
    template<typename PtrType, PtrType Ptr, typename... Args> struct _sub_function_wrapper {}; // the result one

    // for C functions
    template<typename PtrType, PtrType Ptr, typename Return, typename... FuncArgList>
    struct function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>>
    {
      template<typename... Types>
      static constexpr _sub_function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>, type_list<Types...>> wrap(Types... values)
      {
        return _sub_function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>, type_list<Types...>>(values...);
      }
    };

    template<typename PtrType, PtrType Ptr, typename Return, typename... FuncArgList, typename... ArgList>
    struct _sub_function_wrapper<PtrType, Ptr, Return, type_list<FuncArgList...>, type_list<ArgList...>>
    {
      static_assert(sizeof...(FuncArgList) == sizeof...(ArgList), "the number of supplied argument does not match the function's arity");

      constexpr _sub_function_wrapper(ArgList... values)

      {
      }
    };

    // /// ///
    // function traits
    // /// ///

    template<typename FunctionType>
    struct function_traits
    {
      static constexpr bool is_function = false;
    };
    template<typename FunctionType>
    constexpr bool function_traits<FunctionType>::is_function;

    // standard function
    template<typename Return, typename... Parameters>
    struct function_traits<Return (Parameters...)>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = false;
      using return_type = Return;
      using ptr_type = Return (*)(Parameters...);
      using arg_list = type_list<Parameters...>;

      template<ptr_type ptr>
      using create_wrapper = function_wrapper<ptr_type, ptr, Return, /*Class,*/ arg_list>;
    };
    template<typename Return, typename... Parameters>
    constexpr bool function_traits<Return (Parameters...)>::is_function;
    template<typename Return, typename... Parameters>
    constexpr bool function_traits<Return (Parameters...)>::is_member;

    // class member function
    template<typename Return, typename Class,typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...)>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = false;
      static constexpr bool is_volatile = false;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...);
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...)>::is_volatile;

    template<typename Return, typename Class, typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...) const>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = true;
      static constexpr bool is_volatile = false;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...) const;
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const>::is_volatile;

    template<typename Return, typename Class, typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...) volatile>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = false;
      static constexpr bool is_volatile = true;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...) volatile;
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) volatile>::is_volatile;

    template<typename Return, typename Class, typename... Parameters>
    struct function_traits<Return (Class::*)(Parameters...) const volatile>
    {
      static constexpr bool is_function = true;
      static constexpr bool is_member = true;
      static constexpr bool is_const = false;
      static constexpr bool is_volatile = true;
      using return_type = Return;
      using class_type = Class;
      using ptr_type = Return (Class::*)(Parameters...) const volatile;
      using arg_list = type_list<Parameters...>;
    };
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_function;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_member;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_const;
    template<typename Return, typename Class, typename... Parameters>
    constexpr bool function_traits<Return (Class::*)(Parameters...) const volatile>::is_volatile;

  } // namespace ct
} // namespace neam

#endif /*__N_2111737739159269973_1204098121__FUNCTION_HPP__*/

// kate: indent-mode cstyle; indent-width 2; replace-tabs on;

<|endoftext|>


<commit_before>#include "functions.h"

NAN_METHOD(nothing) {
}

NAN_METHOD(aString) {
    info.GetReturnValue().Set(Nan::New("This is a thing.").ToLocalChecked());
}

NAN_METHOD(aBoolean) {
    info.GetReturnValue().Set(false);
}

NAN_METHOD(aNumber) {
    info.GetReturnValue().Set(1.75);
}

NAN_METHOD(anObject) {
    v8::Local<v8::Object> obj = Nan::New<v8::Object>();
    Nan::Set(obj, Nan::New("key").ToLocalChecked(), Nan::New("value").ToLocalChecked());
    info.GetReturnValue().Set(obj);
}

NAN_METHOD(anArray) {
    v8::Local<v8::Array> arr = Nan::New<v8::Array>(3);
    Nan::Set(arr, 0, Nan::New(1));
    Nan::Set(arr, 1, Nan::New(2));
    Nan::Set(arr, 2, Nan::New(3));
    info.GetReturnValue().Set(arr);
}

NAN_METHOD(callback) {
    v8::Local<v8::Function> callbackHandle = info[0].As<v8::Function>();
    Nan::MakeCallback(Nan::GetCurrentContext()->Global(), callbackHandle, 0, 0);
}

// Wrapper Impl

Nan::Persistent<v8::Function> MyObject::constructor;

NAN_MODULE_INIT(MyObject::Init) {
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("MyObject").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  Nan::SetPrototypeMethod(tpl, "plusOne", PlusOne);

  constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
  Nan::Set(target, Nan::New("MyObject").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

NAN_METHOD(MyObject::New) {
  if (info.IsConstructCall()) {
    double value = info[0]->IsUndefined() ? 0 : Nan::To<double>(info[0]).FromJust();
    MyObject *obj = new MyObject(value);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = {info[0]};
    v8::Local<v8::Function> cons = Nan::New(constructor);
    info.GetReturnValue().Set(cons->NewInstance(argc, argv));
  }
}

NAN_METHOD(MyObject::PlusOne) {
  MyObject* obj = Nan::ObjectWrap::Unwrap<MyObject>(info.This());
  obj->value_ += 1;
  info.GetReturnValue().Set(obj->value_);
}
<commit_msg>Fixed deprecated calls to MakeCallback and obj->NewInstance<commit_after>#include "functions.h"

NAN_METHOD(nothing) {
}

NAN_METHOD(aString) {
    info.GetReturnValue().Set(Nan::New("This is a thing.").ToLocalChecked());
}

NAN_METHOD(aBoolean) {
    info.GetReturnValue().Set(false);
}

NAN_METHOD(aNumber) {
    info.GetReturnValue().Set(1.75);
}

NAN_METHOD(anObject) {
    v8::Local<v8::Object> obj = Nan::New<v8::Object>();
    Nan::Set(obj, Nan::New("key").ToLocalChecked(), Nan::New("value").ToLocalChecked());
    info.GetReturnValue().Set(obj);
}

NAN_METHOD(anArray) {
    v8::Local<v8::Array> arr = Nan::New<v8::Array>(3);
    Nan::Set(arr, 0, Nan::New(1));
    Nan::Set(arr, 1, Nan::New(2));
    Nan::Set(arr, 2, Nan::New(3));
    info.GetReturnValue().Set(arr);
}

NAN_METHOD(callback) {
    v8::Local<v8::Function> callbackHandle = info[0].As<v8::Function>();
    Nan::AsyncResource* resource = new Nan::AsyncResource(Nan::New<v8::String>("MyObject:CallCallback").ToLocalChecked());
    resource->runInAsyncScope(Nan::GetCurrentContext()->Global(), callbackHandle, 0, 0);
}

// Wrapper Impl

Nan::Persistent<v8::Function> MyObject::constructor;

NAN_MODULE_INIT(MyObject::Init) {
  v8::Local<v8::FunctionTemplate> tpl = Nan::New<v8::FunctionTemplate>(New);
  tpl->SetClassName(Nan::New("MyObject").ToLocalChecked());
  tpl->InstanceTemplate()->SetInternalFieldCount(1);

  Nan::SetPrototypeMethod(tpl, "plusOne", PlusOne);

  constructor.Reset(Nan::GetFunction(tpl).ToLocalChecked());
  Nan::Set(target, Nan::New("MyObject").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}

MyObject::MyObject(double value) : value_(value) {
}

MyObject::~MyObject() {
}

NAN_METHOD(MyObject::New) {
  if (info.IsConstructCall()) {
    double value = info[0]->IsUndefined() ? 0 : Nan::To<double>(info[0]).FromJust();
    MyObject *obj = new MyObject(value);
    obj->Wrap(info.This());
    info.GetReturnValue().Set(info.This());
  } else {
    const int argc = 1;
    v8::Local<v8::Value> argv[argc] = {info[0]};
    v8::Local<v8::Function> cons = Nan::New(constructor);
    info.GetReturnValue().Set(Nan::NewInstance(cons, argc, argv).ToLocalChecked());
  }
}

NAN_METHOD(MyObject::PlusOne) {
  MyObject* obj = Nan::ObjectWrap::Unwrap<MyObject>(info.This());
  obj->value_ += 1;
  info.GetReturnValue().Set(obj->value_);
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2005-2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

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

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

*/
#include "audiooutput.h"
#include "audiooutput_p.h"
#include "factory_p.h"
#include "objectdescription.h"
#include "audiooutputadaptor_p.h"
#include "globalconfig_p.h"
#include "audiooutputinterface.h"
#include "phononnamespace_p.h"
#include "platform_p.h"

#include <QtCore/qmath.h>

#define PHONON_CLASSNAME AudioOutput
#define IFACES2 AudioOutputInterface42
#define IFACES1 IFACES2
#define IFACES0 AudioOutputInterface40, IFACES1
#define PHONON_INTERFACENAME IFACES0

QT_BEGIN_NAMESPACE

namespace Phonon
{

static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(AudioOutputDevice::fromIndex(index));
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(index);
}

static inline bool callSetOutputDevice(MediaNodePrivate *const d, const AudioOutputDevice &dev)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(dev);
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(dev.index());
}

AudioOutput::AudioOutput(Phonon::Category category, QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(category);
}

AudioOutput::AudioOutput(QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(NoCategory);
}

void AudioOutputPrivate::init(Phonon::Category c)
{
    Q_Q(AudioOutput);
#ifndef QT_NO_DBUS
    adaptor = new AudioOutputAdaptor(q);
    static unsigned int number = 0;
    const QString &path = QLatin1String("/AudioOutputs/") + QString::number(number++);
    QDBusConnection con = QDBusConnection::sessionBus();
    con.registerObject(path, q);
    emit adaptor->newOutputAvailable(con.baseService(), path);
    q->connect(q, SIGNAL(volumeChanged(qreal)), adaptor, SIGNAL(volumeChanged(qreal)));
    q->connect(q, SIGNAL(mutedChanged(bool)), adaptor, SIGNAL(mutedChanged(bool)));
#endif

    category = c;

    // select hardware device according to the category
    device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices));

    createBackendObject();

    q->connect(Factory::sender(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(_k_deviceListChanged()));
}

void AudioOutputPrivate::createBackendObject()
{
    if (m_backendObject)
        return;
    Q_Q(AudioOutput);
    m_backendObject = Factory::createAudioOutput(q);
    if (m_backendObject) {
        setupBackendObject();
    }
}

QString AudioOutput::name() const
{
    K_D(const AudioOutput);
    return d->name;
}

void AudioOutput::setName(const QString &newName)
{
    K_D(AudioOutput);
    if (d->name == newName) {
        return;
    }
    d->name = newName;
    setVolume(Platform::loadVolume(newName));
#ifndef QT_NO_DBUS
    emit d->adaptor->nameChanged(newName);
#endif
}

static const qreal LOUDNESS_TO_VOLTAGE_EXPONENT = qreal(0.67);
static const qreal VOLTAGE_TO_LOUDNESS_EXPONENT = qreal(1.0/LOUDNESS_TO_VOLTAGE_EXPONENT);

void AudioOutput::setVolume(qreal volume)
{
    K_D(AudioOutput);
    d->volume = volume;
    if (k_ptr->backendObject() && !d->muted) {
        // using Stevens' power law loudness is proportional to (sound pressure)^0.67
        // sound pressure is proportional to voltage:
        // p² \prop P \prop V²
        // => if a factor for loudness of x is requested
        INTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
    } else {
        emit volumeChanged(volume);
    }
    Platform::saveVolume(d->name, volume);
}

qreal AudioOutput::volume() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return d->volume;
    }
    return pow(INTERFACE_CALL(volume()), LOUDNESS_TO_VOLTAGE_EXPONENT);
}

#ifndef PHONON_LOG10OVER20
#define PHONON_LOG10OVER20
static const qreal log10over20 = qreal(0.1151292546497022842); // ln(10) / 20
#endif // PHONON_LOG10OVER20

qreal AudioOutput::volumeDecibel() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return log(d->volume) / log10over20;
    }
    return 0.67 * log(INTERFACE_CALL(volume())) / log10over20;
}

void AudioOutput::setVolumeDecibel(qreal newVolumeDecibel)
{
    setVolume(exp(newVolumeDecibel * log10over20));
}

bool AudioOutput::isMuted() const
{
    K_D(const AudioOutput);
    return d->muted;
}

void AudioOutput::setMuted(bool mute)
{
    K_D(AudioOutput);
    if (d->muted != mute) {
        if (mute) {
            d->muted = mute;
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(0.0));
            }
        } else {
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(pow(d->volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
            }
            d->muted = mute;
        }
        emit mutedChanged(mute);
    }
}

Category AudioOutput::category() const
{
    K_D(const AudioOutput);
    return d->category;
}

AudioOutputDevice AudioOutput::outputDevice() const
{
    K_D(const AudioOutput);
    return d->device;
}

bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice)
{
    K_D(AudioOutput);
    if (!newAudioOutputDevice.isValid()) {
        d->outputDeviceOverridden = false;
        const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category);
        if (newIndex == d->device.index()) {
            return true;
        }
        d->device = AudioOutputDevice::fromIndex(newIndex);
    } else {
        d->outputDeviceOverridden = true;
        if (d->device == newAudioOutputDevice) {
            return true;
        }
        d->device = newAudioOutputDevice;
    }
    if (k_ptr->backendObject()) {
        return callSetOutputDevice(k_ptr, d->device.index());
    }
    return true;
}

bool AudioOutputPrivate::aboutToDeleteBackendObject()
{
    if (m_backendObject) {
        volume = pINTERFACE_CALL(volume());
    }
    return AbstractAudioOutputPrivate::aboutToDeleteBackendObject();
}

void AudioOutputPrivate::setupBackendObject()
{
    Q_Q(AudioOutput);
    Q_ASSERT(m_backendObject);
    AbstractAudioOutputPrivate::setupBackendObject();

    QObject::connect(m_backendObject, SIGNAL(volumeChanged(qreal)), q, SLOT(_k_volumeChanged(qreal)));
    QObject::connect(m_backendObject, SIGNAL(audioDeviceFailed()), q, SLOT(_k_audioDeviceFailed()));

    // set up attributes
    pINTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));

    // if the output device is not available and the device was not explicitly set
    if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) {
        // fall back in the preference list of output devices
        QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
        if (deviceList.isEmpty()) {
            return;
        }
        for (int i = 0; i < deviceList.count(); ++i) {
            const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(deviceList.at(i));
            if (callSetOutputDevice(this, dev)) {
                handleAutomaticDeviceChange(dev, AudioOutputPrivate::FallbackChange);
                return; // found one that works
            }
        }
        // if we get here there is no working output device. Tell the backend.
        const AudioOutputDevice none;
        callSetOutputDevice(this, none);
        handleAutomaticDeviceChange(none, FallbackChange);
    }
}

void AudioOutputPrivate::_k_volumeChanged(qreal newVolume)
{
    if (!muted) {
        Q_Q(AudioOutput);
        emit q->volumeChanged(pow(newVolume, qreal(0.67)));
    }
}

void AudioOutputPrivate::_k_revertFallback()
{
    if (deviceBeforeFallback == -1) {
        return;
    }
    device = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    callSetOutputDevice(this, device);
    Q_Q(AudioOutput);
    emit q->outputDeviceChanged(device);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
}

void AudioOutputPrivate::_k_audioDeviceFailed()
{
    pDebug() << Q_FUNC_INFO;
    // outputDeviceIndex identifies a failing device
    // fall back in the preference list of output devices
    const QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
    for (int i = 0; i < deviceList.count(); ++i) {
        const int devIndex = deviceList.at(i);
        // if it's the same device as the one that failed, ignore it
        if (device.index() != devIndex) {
            const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
            if (callSetOutputDevice(this, info)) {
                handleAutomaticDeviceChange(info, FallbackChange);
                return; // found one that works
            }
        }
    }
    // if we get here there is no working output device. Tell the backend.
    const AudioOutputDevice none;
    callSetOutputDevice(this, none);
    handleAutomaticDeviceChange(none, FallbackChange);
}

void AudioOutputPrivate::_k_deviceListChanged()
{
    pDebug() << Q_FUNC_INFO;
    // let's see if there's a usable device higher in the preference list
    const QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings);
    DeviceChangeType changeType = HigherPreferenceChange;
    for (int i = 0; i < deviceList.count(); ++i) {
        const int devIndex = deviceList.at(i);
        const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
        if (!info.property("available").toBool()) {
            if (device.index() == devIndex) {
                // we've reached the currently used device and it's not available anymore, so we
                // fallback to the next available device
                changeType = FallbackChange;
            }
            pDebug() << devIndex << "is not available";
            continue;
        }
        pDebug() << devIndex << "is available";
        if (device.index() == devIndex) {
            // we've reached the currently used device, nothing to change
            break;
        }
        if (callSetOutputDevice(this, info)) {
            handleAutomaticDeviceChange(info, changeType);
            break; // found one with higher preference that works
        }
    }
}

static struct
{
    int first;
    int second;
} g_lastFallback = { 0, 0 };

void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &device2, DeviceChangeType type)
{
    Q_Q(AudioOutput);
    deviceBeforeFallback = device.index();
    device = device2;
    emit q->outputDeviceChanged(device2);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
    const AudioOutputDevice &device1 = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    switch (type) {
    case FallbackChange:
        if (g_lastFallback.first != device1.index() || g_lastFallback.second != device2.index()) {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
            const QString &text = //device2.isValid() ?
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "Falling back to %2.").arg(device1.name()).arg(device2.name()) /*:
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "No other device available.").arg(device1.name())*/;
            Platform::notification("AudioDeviceFallback", text);
#endif //QT_NO_PHONON_PLATFORMPLUGIN
            g_lastFallback.first = device1.index();
            g_lastFallback.second = device2.index();
        }
        break;
    case HigherPreferenceChange:
        {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
        const QString text = AudioOutput::tr("Switching to the audio playback device %1
"
                "which just became available and has higher preference.").arg(device2.name());
        Platform::notification("AudioDeviceFallback", text,
                QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())),
                q, SLOT(_k_revertFallback()));
#endif //QT_NO_PHONON_PLATFORMPLUGIN
        g_lastFallback.first = 0;
        g_lastFallback.second = 0;
        }
        break;
    }
}

AudioOutputPrivate::~AudioOutputPrivate()
{
#ifndef QT_NO_DBUS
    emit adaptor->outputDestroyed();
#endif
}

} //namespace Phonon

QT_END_NAMESPACE

#include "moc_audiooutput.cpp"

#undef PHONON_CLASSNAME
#undef PHONON_INTERFACENAME
#undef IFACES2
#undef IFACES1
#undef IFACES0
<commit_msg>Import change 924855 from phonon-svn.<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2005-2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) version 3, or any
    later version accepted by the membership of KDE e.V. (or its
    successor approved by the membership of KDE e.V.), Nokia Corporation
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
    act as a proxy defined in Section 6 of version 3 of the license.

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

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

*/
#include "audiooutput.h"
#include "audiooutput_p.h"
#include "factory_p.h"
#include "objectdescription.h"
#include "audiooutputadaptor_p.h"
#include "globalconfig_p.h"
#include "audiooutputinterface.h"
#include "phononnamespace_p.h"
#include "platform_p.h"

#include <QtCore/qmath.h>

#define PHONON_CLASSNAME AudioOutput
#define IFACES2 AudioOutputInterface42
#define IFACES1 IFACES2
#define IFACES0 AudioOutputInterface40, IFACES1
#define PHONON_INTERFACENAME IFACES0

QT_BEGIN_NAMESPACE

namespace Phonon
{

static inline bool callSetOutputDevice(MediaNodePrivate *const d, int index)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(AudioOutputDevice::fromIndex(index));
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(index);
}

static inline bool callSetOutputDevice(MediaNodePrivate *const d, const AudioOutputDevice &dev)
{
    Iface<IFACES2> iface(d);
    if (iface) {
        return iface->setOutputDevice(dev);
    }
    return Iface<IFACES0>::cast(d)->setOutputDevice(dev.index());
}

AudioOutput::AudioOutput(Phonon::Category category, QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(category);
}

AudioOutput::AudioOutput(QObject *parent)
    : AbstractAudioOutput(*new AudioOutputPrivate, parent)
{
    K_D(AudioOutput);
    d->init(NoCategory);
}

void AudioOutputPrivate::init(Phonon::Category c)
{
    Q_Q(AudioOutput);
#ifndef QT_NO_DBUS
    adaptor = new AudioOutputAdaptor(q);
    static unsigned int number = 0;
    const QString &path = QLatin1String("/AudioOutputs/") + QString::number(number++);
    QDBusConnection con = QDBusConnection::sessionBus();
    con.registerObject(path, q);
    emit adaptor->newOutputAvailable(con.baseService(), path);
    q->connect(q, SIGNAL(volumeChanged(qreal)), adaptor, SIGNAL(volumeChanged(qreal)));
    q->connect(q, SIGNAL(mutedChanged(bool)), adaptor, SIGNAL(mutedChanged(bool)));
#endif

    category = c;

    // select hardware device according to the category
    device = AudioOutputDevice::fromIndex(GlobalConfig().audioOutputDeviceFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices));

    createBackendObject();

    q->connect(Factory::sender(), SIGNAL(availableAudioOutputDevicesChanged()), SLOT(_k_deviceListChanged()));
}

void AudioOutputPrivate::createBackendObject()
{
    if (m_backendObject)
        return;
    Q_Q(AudioOutput);
    m_backendObject = Factory::createAudioOutput(q);
    if (m_backendObject) {
        setupBackendObject();
    }
}

QString AudioOutput::name() const
{
    K_D(const AudioOutput);
    return d->name;
}

void AudioOutput::setName(const QString &newName)
{
    K_D(AudioOutput);
    if (d->name == newName) {
        return;
    }
    d->name = newName;
    setVolume(Platform::loadVolume(newName));
#ifndef QT_NO_DBUS
    if (d->adaptor) {
        emit d->adaptor->nameChanged(newName);
    }
#endif
}

static const qreal LOUDNESS_TO_VOLTAGE_EXPONENT = qreal(0.67);
static const qreal VOLTAGE_TO_LOUDNESS_EXPONENT = qreal(1.0/LOUDNESS_TO_VOLTAGE_EXPONENT);

void AudioOutput::setVolume(qreal volume)
{
    K_D(AudioOutput);
    d->volume = volume;
    if (k_ptr->backendObject() && !d->muted) {
        // using Stevens' power law loudness is proportional to (sound pressure)^0.67
        // sound pressure is proportional to voltage:
        // p² \prop P \prop V²
        // => if a factor for loudness of x is requested
        INTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
    } else {
        emit volumeChanged(volume);
    }
    Platform::saveVolume(d->name, volume);
}

qreal AudioOutput::volume() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return d->volume;
    }
    return pow(INTERFACE_CALL(volume()), LOUDNESS_TO_VOLTAGE_EXPONENT);
}

#ifndef PHONON_LOG10OVER20
#define PHONON_LOG10OVER20
static const qreal log10over20 = qreal(0.1151292546497022842); // ln(10) / 20
#endif // PHONON_LOG10OVER20

qreal AudioOutput::volumeDecibel() const
{
    K_D(const AudioOutput);
    if (d->muted || !d->m_backendObject) {
        return log(d->volume) / log10over20;
    }
    return 0.67 * log(INTERFACE_CALL(volume())) / log10over20;
}

void AudioOutput::setVolumeDecibel(qreal newVolumeDecibel)
{
    setVolume(exp(newVolumeDecibel * log10over20));
}

bool AudioOutput::isMuted() const
{
    K_D(const AudioOutput);
    return d->muted;
}

void AudioOutput::setMuted(bool mute)
{
    K_D(AudioOutput);
    if (d->muted != mute) {
        if (mute) {
            d->muted = mute;
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(0.0));
            }
        } else {
            if (k_ptr->backendObject()) {
                INTERFACE_CALL(setVolume(pow(d->volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));
            }
            d->muted = mute;
        }
        emit mutedChanged(mute);
    }
}

Category AudioOutput::category() const
{
    K_D(const AudioOutput);
    return d->category;
}

AudioOutputDevice AudioOutput::outputDevice() const
{
    K_D(const AudioOutput);
    return d->device;
}

bool AudioOutput::setOutputDevice(const AudioOutputDevice &newAudioOutputDevice)
{
    K_D(AudioOutput);
    if (!newAudioOutputDevice.isValid()) {
        d->outputDeviceOverridden = false;
        const int newIndex = GlobalConfig().audioOutputDeviceFor(d->category);
        if (newIndex == d->device.index()) {
            return true;
        }
        d->device = AudioOutputDevice::fromIndex(newIndex);
    } else {
        d->outputDeviceOverridden = true;
        if (d->device == newAudioOutputDevice) {
            return true;
        }
        d->device = newAudioOutputDevice;
    }
    if (k_ptr->backendObject()) {
        return callSetOutputDevice(k_ptr, d->device.index());
    }
    return true;
}

bool AudioOutputPrivate::aboutToDeleteBackendObject()
{
    if (m_backendObject) {
        volume = pINTERFACE_CALL(volume());
    }
    return AbstractAudioOutputPrivate::aboutToDeleteBackendObject();
}

void AudioOutputPrivate::setupBackendObject()
{
    Q_Q(AudioOutput);
    Q_ASSERT(m_backendObject);
    AbstractAudioOutputPrivate::setupBackendObject();

    QObject::connect(m_backendObject, SIGNAL(volumeChanged(qreal)), q, SLOT(_k_volumeChanged(qreal)));
    QObject::connect(m_backendObject, SIGNAL(audioDeviceFailed()), q, SLOT(_k_audioDeviceFailed()));

    // set up attributes
    pINTERFACE_CALL(setVolume(pow(volume, VOLTAGE_TO_LOUDNESS_EXPONENT)));

    // if the output device is not available and the device was not explicitly set
    if (!callSetOutputDevice(this, device) && !outputDeviceOverridden) {
        // fall back in the preference list of output devices
        QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
        if (deviceList.isEmpty()) {
            return;
        }
        for (int i = 0; i < deviceList.count(); ++i) {
            const AudioOutputDevice &dev = AudioOutputDevice::fromIndex(deviceList.at(i));
            if (callSetOutputDevice(this, dev)) {
                handleAutomaticDeviceChange(dev, AudioOutputPrivate::FallbackChange);
                return; // found one that works
            }
        }
        // if we get here there is no working output device. Tell the backend.
        const AudioOutputDevice none;
        callSetOutputDevice(this, none);
        handleAutomaticDeviceChange(none, FallbackChange);
    }
}

void AudioOutputPrivate::_k_volumeChanged(qreal newVolume)
{
    if (!muted) {
        Q_Q(AudioOutput);
        emit q->volumeChanged(pow(newVolume, qreal(0.67)));
    }
}

void AudioOutputPrivate::_k_revertFallback()
{
    if (deviceBeforeFallback == -1) {
        return;
    }
    device = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    callSetOutputDevice(this, device);
    Q_Q(AudioOutput);
    emit q->outputDeviceChanged(device);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
}

void AudioOutputPrivate::_k_audioDeviceFailed()
{
    pDebug() << Q_FUNC_INFO;
    // outputDeviceIndex identifies a failing device
    // fall back in the preference list of output devices
    const QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings | GlobalConfig::HideUnavailableDevices);
    for (int i = 0; i < deviceList.count(); ++i) {
        const int devIndex = deviceList.at(i);
        // if it's the same device as the one that failed, ignore it
        if (device.index() != devIndex) {
            const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
            if (callSetOutputDevice(this, info)) {
                handleAutomaticDeviceChange(info, FallbackChange);
                return; // found one that works
            }
        }
    }
    // if we get here there is no working output device. Tell the backend.
    const AudioOutputDevice none;
    callSetOutputDevice(this, none);
    handleAutomaticDeviceChange(none, FallbackChange);
}

void AudioOutputPrivate::_k_deviceListChanged()
{
    pDebug() << Q_FUNC_INFO;
    // let's see if there's a usable device higher in the preference list
    const QList<int> deviceList = GlobalConfig().audioOutputDeviceListFor(category, GlobalConfig::AdvancedDevicesFromSettings);
    DeviceChangeType changeType = HigherPreferenceChange;
    for (int i = 0; i < deviceList.count(); ++i) {
        const int devIndex = deviceList.at(i);
        const AudioOutputDevice &info = AudioOutputDevice::fromIndex(devIndex);
        if (!info.property("available").toBool()) {
            if (device.index() == devIndex) {
                // we've reached the currently used device and it's not available anymore, so we
                // fallback to the next available device
                changeType = FallbackChange;
            }
            pDebug() << devIndex << "is not available";
            continue;
        }
        pDebug() << devIndex << "is available";
        if (device.index() == devIndex) {
            // we've reached the currently used device, nothing to change
            break;
        }
        if (callSetOutputDevice(this, info)) {
            handleAutomaticDeviceChange(info, changeType);
            break; // found one with higher preference that works
        }
    }
}

static struct
{
    int first;
    int second;
} g_lastFallback = { 0, 0 };

void AudioOutputPrivate::handleAutomaticDeviceChange(const AudioOutputDevice &device2, DeviceChangeType type)
{
    Q_Q(AudioOutput);
    deviceBeforeFallback = device.index();
    device = device2;
    emit q->outputDeviceChanged(device2);
#ifndef QT_NO_DBUS
    emit adaptor->outputDeviceIndexChanged(device.index());
#endif
    const AudioOutputDevice &device1 = AudioOutputDevice::fromIndex(deviceBeforeFallback);
    switch (type) {
    case FallbackChange:
        if (g_lastFallback.first != device1.index() || g_lastFallback.second != device2.index()) {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
            const QString &text = //device2.isValid() ?
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "Falling back to %2.").arg(device1.name()).arg(device2.name()) /*:
                AudioOutput::tr("The audio playback device %1 does not work.
"
                        "No other device available.").arg(device1.name())*/;
            Platform::notification("AudioDeviceFallback", text);
#endif //QT_NO_PHONON_PLATFORMPLUGIN
            g_lastFallback.first = device1.index();
            g_lastFallback.second = device2.index();
        }
        break;
    case HigherPreferenceChange:
        {
#ifndef QT_NO_PHONON_PLATFORMPLUGIN
        const QString text = AudioOutput::tr("Switching to the audio playback device %1
"
                "which just became available and has higher preference.").arg(device2.name());
        Platform::notification("AudioDeviceFallback", text,
                QStringList(AudioOutput::tr("Revert back to device '%1'").arg(device1.name())),
                q, SLOT(_k_revertFallback()));
#endif //QT_NO_PHONON_PLATFORMPLUGIN
        g_lastFallback.first = 0;
        g_lastFallback.second = 0;
        }
        break;
    }
}

AudioOutputPrivate::~AudioOutputPrivate()
{
#ifndef QT_NO_DBUS
    if (adaptor) {
        emit adaptor->outputDestroyed();
    }
#endif
}

} //namespace Phonon

QT_END_NAMESPACE

#include "moc_audiooutput.cpp"

#undef PHONON_CLASSNAME
#undef PHONON_INTERFACENAME
#undef IFACES2
#undef IFACES1
#undef IFACES0
<|endoftext|>


<commit_before>/** @file Defines miscellaneous general purpose functor types.
 * @author Ralph Tandetzky
 */

#pragma once

#include <utility>

namespace cu
{

/// A functor class whose function call operator does nothing.
///
/// This is a class that is needed to work around the gcc bug, that the
/// lambda @c [](auto&&...){} required at least one argument.
struct NoOpFunctor
{
  template <typename ...Ts>
  void operator()( Ts&&... ) const
  {
  }
};

struct ForwardingFunctor
{
  template <typename T>
  decltype(auto) operator()( T && x ) const
  {
    return std::forward<T>(x);
  }
};

template <typename Signature>
class Lambda;

template <typename Result, typename ... Args>
class Lambda<Result(Args...)>
{
public:
  template <typename F>
  Lambda( const F & functor )
    : workLoad( &functor )
    , f( []( const void * workLoad, Args &&... args ) -> Result
         {
            return (*(static_cast<const F*>(workLoad)))( std::forward<Args>(args)... );
         } )
  {
  }

  // disable copying
  Lambda( const Lambda & ) = delete;
  Lambda & operator=( Lambda ) = delete;

  Result operator()( Args &&... args ) const
  {
    return f( workLoad, std::forward<Args>(args)... );
  }

private:
  const void * workLoad = nullptr;
  Result (*f)(const void*,Args&&...) = nullptr;
};

namespace detail
{

  template <typename ...Fs>
  class OverloadedFunctor;

  template <>
  class OverloadedFunctor<>
  {
  public:
    template <typename ...Ts,
              typename = std::enable_if_t<false,std::tuple<Ts...>>> // always disabled.
    void operator()( Ts &&... );
  };

  template <typename F, typename ...Fs>
  class OverloadedFunctor<F,Fs...>
      : public OverloadedFunctor<Fs...>
  {
  private:
    F f;
    using Base = OverloadedFunctor<Fs...>;

  public:
    OverloadedFunctor( F && f_, Fs &&... fs )
      : Base( std::forward<Fs>(fs)... )
      , f( std::forward<F>(f_) )
    {}

    using Base::operator();

    template <typename ...Ts>
    auto operator()( Ts &&... args )
      -> decltype( f( std::forward<Ts>(args)... ) )
    {
      return f( std::forward<Ts>(args)... );
    }

    template <typename ...Ts>
    auto operator()( Ts &&... args ) const
      -> decltype( f( std::forward<Ts>(args)... ) )
    {
      return f( std::forward<Ts>(args)... );
    }
  };

} // namespace detail

template <typename ...Fs>
auto makeOverloadedFunctor( Fs &&... fs )
{
  return detail::OverloadedFunctor<Fs...>( std::forward<Fs>(fs)... );
}

} // namespace cu
<commit_msg>Implemented function_move_only class.<commit_after>/** @file Defines miscellaneous general purpose functor types.
 * @author Ralph Tandetzky
 */

#pragma once

#include "swap.hpp"

#include <utility>

namespace cu
{

/// A functor class whose function call operator does nothing.
///
/// This is a class that is needed to work around the gcc bug, that the
/// lambda @c [](auto&&...){} required at least one argument.
struct NoOpFunctor
{
  template <typename ...Ts>
  void operator()( Ts&&... ) const
  {
  }
};

struct ForwardingFunctor
{
  template <typename T>
  decltype(auto) operator()( T && x ) const
  {
    return std::forward<T>(x);
  }
};

template <typename Signature>
class Lambda;

template <typename Result, typename ... Args>
class Lambda<Result(Args...)>
{
public:
  template <typename F>
  Lambda( const F & functor )
    : workLoad( &functor )
    , f( []( const void * workLoad, Args &&... args ) -> Result
         {
            return (*(static_cast<const F*>(workLoad)))( std::forward<Args>(args)... );
         } )
  {
  }

  // disable copying
  Lambda( const Lambda & ) = delete;
  Lambda & operator=( Lambda ) = delete;

  Result operator()( Args &&... args ) const
  {
    return f( workLoad, std::forward<Args>(args)... );
  }

private:
  const void * workLoad = nullptr;
  Result (*f)(const void*,Args&&...) = nullptr;
};

namespace detail
{

  template <typename ...Fs>
  class OverloadedFunctor;

  template <>
  class OverloadedFunctor<>
  {
  public:
    template <typename ...Ts,
              typename = std::enable_if_t<false,std::tuple<Ts...>>> // always disabled.
    void operator()( Ts &&... );
  };

  template <typename F, typename ...Fs>
  class OverloadedFunctor<F,Fs...>
      : public OverloadedFunctor<Fs...>
  {
  private:
    F f;
    using Base = OverloadedFunctor<Fs...>;

  public:
    OverloadedFunctor( F && f_, Fs &&... fs )
      : Base( std::forward<Fs>(fs)... )
      , f( std::forward<F>(f_) )
    {}

    using Base::operator();

    template <typename ...Ts>
    auto operator()( Ts &&... args )
      -> decltype( f( std::forward<Ts>(args)... ) )
    {
      return f( std::forward<Ts>(args)... );
    }

    template <typename ...Ts>
    auto operator()( Ts &&... args ) const
      -> decltype( f( std::forward<Ts>(args)... ) )
    {
      return f( std::forward<Ts>(args)... );
    }
  };

} // namespace detail

template <typename ...Fs>
auto makeOverloadedFunctor( Fs &&... fs )
{
  return detail::OverloadedFunctor<Fs...>( std::forward<Fs>(fs)... );
}

/// This class mimics the behaviour of std::function, except that it
/// does not require the assigned functors to be copyable, but to be
/// movable only. Consequently, @c function_move_only objects are
/// MoveOnly as well.
template <typename T>
class function_move_only;

template <typename Res,
          typename ...Args>
class function_move_only<Res(Args...)>
{
public:
  function_move_only() noexcept
  {}

  function_move_only( std::nullptr_t ) noexcept
  {}

  function_move_only( function_move_only && other ) noexcept
  {
    swap( other );
  }

  template <typename F>
  function_move_only( F && f )
    : callPtr( makeCallPtr<F>() )
    , cleanUpPtr( makeCleanUpPtr<F>() )
    , payLoad( makePayLoad( CU_FWD(f) ) )
  {}

  ~function_move_only()
  {
    cleanUp();
  }

  function_move_only & operator=( std::nullptr_t ) noexcept
  {
    cleanUp();
  }

  function_move_only & operator=( function_move_only && other ) noexcept
  {
    cleanUp();
    swap( other );
  }

  template <typename F>
  function_move_only & operator=( F && f )
  {
    function_move_only( CU_FWD(f) ).swap( *this );
  }

  void swap( function_move_only & other ) noexcept
  {
    cu::swap( callPtr   , other.callPtr    );
    cu::swap( cleanUpPtr, other.cleanUpPtr );
    cu::swap( payLoad   , other.payLoad    );
  }

  explicit operator bool() const noexcept;
  Res operator()( Args...args ) const
  {
    callPtr( payLoad, CU_FWD(args)... );
  }

private:
  template <typename F>
  static Res (*makeCallPtr())( void *, Args&&... )
  {
    return []( void * payLoad, Args&&...args )
    {
      (*static_cast<typename std::decay<F>::type*>(payLoad))( CU_FWD(args)... );
    };
  }

  template <typename F>
  static void (*makeCleanUpPtr())( void* )
  {
    return []( void * payLoad )
    {
      delete static_cast<typename std::decay<F>::type*>(payLoad);
    };
  }

  template <typename F>
  static void * makePayLoad( F && f )
  {
    return new typename std::decay<F>::type( CU_FWD(f) );
  }

  void cleanUp() noexcept
  {
    if ( cleanUpPtr )
      cleanUpPtr( payLoad );
    callPtr    = nullptr;
    cleanUpPtr = nullptr;
    payLoad    = nullptr;
  }

  Res (*callPtr)( void *, Args&&... ) = nullptr;
  void (*cleanUpPtr)( void * ) = nullptr;
  void * payLoad = nullptr;
};

} // namespace cu
<|endoftext|>