<commit_before>/*
 * Copyright (c) 2015 - 2022, Intel Corporation
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "config.h"

#include <string>
#include <cstdint>

#include "geopm/Exception.hpp"
#include "geopm/Agg.hpp"
#include "geopm/Helper.hpp"
#include "geopm_sched.h"

#include "LevelZeroDevicePoolImp.hpp"

namespace geopm
{
    const LevelZeroDevicePool &levelzero_device_pool()
    {
        static LevelZeroDevicePoolImp instance(levelzero());
        return instance;
    }

    LevelZeroDevicePoolImp::LevelZeroDevicePoolImp(const LevelZero &levelzero)
        : m_levelzero(levelzero)
    {
    }

    LevelZeroDevicePoolImp::LevelZeroDevicePoolImp()
        : LevelZeroDevicePoolImp(levelzero())
    {
    }

    int LevelZeroDevicePoolImp::num_gpu(int domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU
            && domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) + " is not supported.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return m_levelzero.num_gpu(domain);
    }

    void LevelZeroDevicePoolImp::check_idx_range(int domain, unsigned int domain_idx) const
    {
        if (domain_idx >= (unsigned int) num_gpu(domain)) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) + ": domain "
                            + std::to_string(domain) + " idx " + std::to_string(domain_idx) +
                            " is out of range.", GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
    }

    void LevelZeroDevicePoolImp::check_domain_exists(int size, const char *func, int line) const
    {
        if (size == 0) {
            throw Exception("LevelZeroDevicePool::" + std::string(func) +
                            ": Not supported on this hardware for the specified "
                            "LevelZero domain",
                            GEOPM_ERROR_INVALID, __FILE__, line);
        }
    }

    std::pair<unsigned int, unsigned int> LevelZeroDevicePoolImp::subdevice_device_conversion(unsigned int sub_idx) const
    {
        check_idx_range(GEOPM_DOMAIN_GPU_CHIP, sub_idx);
        unsigned int device_idx = 0;
        int subdevice_idx = 0;

        // TODO: this assumes a simple split of subdevice to device.
        // This may need to be adjusted based upon user preference or use case
        if (num_gpu(GEOPM_DOMAIN_GPU_CHIP) %
            num_gpu(GEOPM_DOMAIN_GPU) != 0) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": GEOPM Requires the number" +
                            " of subdevices to be evenly divisible by the number of devices. ",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        int num_subdevice_per_device = num_gpu(GEOPM_DOMAIN_GPU_CHIP) /
                                       num_gpu(GEOPM_DOMAIN_GPU);

        device_idx = sub_idx / num_subdevice_per_device;
        check_idx_range(GEOPM_DOMAIN_GPU, device_idx);
        subdevice_idx = sub_idx % num_subdevice_per_device;
        return {device_idx, subdevice_idx};
    }

    double LevelZeroDevicePoolImp::frequency_status(int domain, unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        return m_levelzero.frequency_status(dev_subdev_idx_pair.first, l0_domain,
                                            dev_subdev_idx_pair.second);
    }

    double LevelZeroDevicePoolImp::frequency_min(int domain, unsigned int domain_idx,
                                                 int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(dev_subdev_idx_pair.first,
                                        l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_min(dev_subdev_idx_pair.first,
                                         l0_domain, dev_subdev_idx_pair.second);
    }

    double LevelZeroDevicePoolImp::frequency_max(int domain, unsigned int domain_idx,
                                                 int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                             ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_max(dev_subdev_idx_pair.first, l0_domain,
                                         dev_subdev_idx_pair.second);
    }

    uint32_t LevelZeroDevicePoolImp::frequency_throttle_reasons(int domain, unsigned int domain_idx,
                                                              int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                             ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_throttle_reasons(dev_subdev_idx_pair.first, l0_domain,
                                                      dev_subdev_idx_pair.second);
    }

    std::pair<double, double> LevelZeroDevicePoolImp::frequency_range(int domain,
                                                                      unsigned int domain_idx,
                                                                      int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_range(dev_subdev_idx_pair.first, l0_domain,
                                           dev_subdev_idx_pair.second);

    }

    std::pair<uint64_t, uint64_t> LevelZeroDevicePoolImp::active_time_pair(int domain,
                                                                           unsigned int domain_idx,
                                                                           int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the engine domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        // TODO: Some devices may not support ZES_ENGINE_GROUP_COMPUTE/COPY_ALL. In that case this should be a
        //       device level signal that handles aggregation of domains directly here
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.engine_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        return m_levelzero.active_time_pair(dev_subdev_idx_pair.first, l0_domain,
                                            dev_subdev_idx_pair.second);
    }

    uint64_t LevelZeroDevicePoolImp::active_time_timestamp(int domain,
                                                           unsigned int domain_idx,
                                                           int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                             ": domain " + std::to_string(domain) +
                            " is not supported for the engine domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        // TODO: Some devices may not support ZES_ENGINE_GROUP_COMPUTE/COPY_ALL. In that case this should be a
        //       device level signal that handles aggregation of domains directly here
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.engine_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        return m_levelzero.active_time_timestamp(dev_subdev_idx_pair.first, l0_domain,
                                                 dev_subdev_idx_pair.second);
    }

    uint64_t LevelZeroDevicePoolImp::active_time(int domain, unsigned int domain_idx,
                                                 int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " +std::to_string(domain) +
                            " is not supported for the engine domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        //TODO: Some devices may not support ZES_ENGINE_GROUP_COMPUTE/COPY_ALL. In that case this should be a
        //      device level signal that handles aggregation of domains directly here
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.engine_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);
        return m_levelzero.active_time(dev_subdev_idx_pair.first, l0_domain,
                                       dev_subdev_idx_pair.second);
    }

    int32_t LevelZeroDevicePoolImp::power_limit_min(int domain, unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.power_limit_min(domain_idx);
    }

    int32_t LevelZeroDevicePoolImp::power_limit_max(int domain,
                                                    unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.power_limit_max(domain_idx);
    }

    int32_t LevelZeroDevicePoolImp::power_limit_tdp(int domain,
                                                    unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.power_limit_tdp(domain_idx);
    }

    std::pair<uint64_t, uint64_t> LevelZeroDevicePoolImp::energy_pair(int domain,
                                                                      unsigned int domain_idx,
                                                                      int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.energy_pair(domain_idx);
    }

    uint64_t LevelZeroDevicePoolImp::energy_timestamp(int domain,
                                                      unsigned int domain_idx,
                                                      int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.energy_timestamp(domain_idx);
    }

    uint64_t LevelZeroDevicePoolImp::energy(int domain, unsigned int domain_idx,
                                            int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.energy(domain_idx);
    }

    void LevelZeroDevicePoolImp::frequency_control(int domain, unsigned int domain_idx,
                                                   int l0_domain, double range_min,
                                                   double range_max) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        m_levelzero.frequency_control(dev_subdev_idx_pair.first, l0_domain,
                                      dev_subdev_idx_pair.second, range_min,
                                      range_max);
    }
}
<commit_msg>Error message update for clarity.<commit_after>/*
 * Copyright (c) 2015 - 2022, Intel Corporation
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "config.h"

#include <string>
#include <cstdint>

#include "geopm/Exception.hpp"
#include "geopm/Agg.hpp"
#include "geopm/Helper.hpp"
#include "geopm_sched.h"

#include "LevelZeroDevicePoolImp.hpp"

namespace geopm
{
    const LevelZeroDevicePool &levelzero_device_pool()
    {
        static LevelZeroDevicePoolImp instance(levelzero());
        return instance;
    }

    LevelZeroDevicePoolImp::LevelZeroDevicePoolImp(const LevelZero &levelzero)
        : m_levelzero(levelzero)
    {
    }

    LevelZeroDevicePoolImp::LevelZeroDevicePoolImp()
        : LevelZeroDevicePoolImp(levelzero())
    {
    }

    int LevelZeroDevicePoolImp::num_gpu(int domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU
            && domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) + " is not supported.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return m_levelzero.num_gpu(domain);
    }

    void LevelZeroDevicePoolImp::check_idx_range(int domain, unsigned int domain_idx) const
    {
        if (domain_idx >= (unsigned int) num_gpu(domain)) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) + ": domain "
                            + std::to_string(domain) + " idx " + std::to_string(domain_idx) +
                            " is out of range.", GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
    }

    void LevelZeroDevicePoolImp::check_domain_exists(int size, const char *func, int line) const
    {
        if (size == 0) {
            throw Exception("LevelZeroDevicePool::" + std::string(func) +
                            ": Not supported on this hardware for the specified "
                            "LevelZero domain",
                            GEOPM_ERROR_INVALID, __FILE__, line);
        }
    }

    std::pair<unsigned int, unsigned int> LevelZeroDevicePoolImp::subdevice_device_conversion(unsigned int sub_idx) const
    {
        check_idx_range(GEOPM_DOMAIN_GPU_CHIP, sub_idx);
        unsigned int device_idx = 0;
        int subdevice_idx = 0;

        // TODO: this assumes a simple split of subdevice to device.
        // This may need to be adjusted based upon user preference or use case
        if (num_gpu(GEOPM_DOMAIN_GPU_CHIP) %
            num_gpu(GEOPM_DOMAIN_GPU) != 0) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": GEOPM Requires the number" +
                            " of subdevices to be evenly divisible by the number of devices. ",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        int num_subdevice_per_device = num_gpu(GEOPM_DOMAIN_GPU_CHIP) /
                                       num_gpu(GEOPM_DOMAIN_GPU);

        device_idx = sub_idx / num_subdevice_per_device;
        check_idx_range(GEOPM_DOMAIN_GPU, device_idx);
        subdevice_idx = sub_idx % num_subdevice_per_device;
        return {device_idx, subdevice_idx};
    }

    double LevelZeroDevicePoolImp::frequency_status(int domain, unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        return m_levelzero.frequency_status(dev_subdev_idx_pair.first, l0_domain,
                                            dev_subdev_idx_pair.second);
    }

    double LevelZeroDevicePoolImp::frequency_min(int domain, unsigned int domain_idx,
                                                 int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(dev_subdev_idx_pair.first,
                                        l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_min(dev_subdev_idx_pair.first,
                                         l0_domain, dev_subdev_idx_pair.second);
    }

    double LevelZeroDevicePoolImp::frequency_max(int domain, unsigned int domain_idx,
                                                 int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                             ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_max(dev_subdev_idx_pair.first, l0_domain,
                                         dev_subdev_idx_pair.second);
    }

    uint32_t LevelZeroDevicePoolImp::frequency_throttle_reasons(int domain, unsigned int domain_idx,
                                                              int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                             ": domain " + std::to_string(domain) +
                            " is not supported for reading the \"frequency throttle reason\"",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_throttle_reasons(dev_subdev_idx_pair.first, l0_domain,
                                                      dev_subdev_idx_pair.second);
    }

    std::pair<double, double> LevelZeroDevicePoolImp::frequency_range(int domain,
                                                                      unsigned int domain_idx,
                                                                      int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain), __func__, __LINE__);

        return m_levelzero.frequency_range(dev_subdev_idx_pair.first, l0_domain,
                                           dev_subdev_idx_pair.second);

    }

    std::pair<uint64_t, uint64_t> LevelZeroDevicePoolImp::active_time_pair(int domain,
                                                                           unsigned int domain_idx,
                                                                           int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the engine domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        // TODO: Some devices may not support ZES_ENGINE_GROUP_COMPUTE/COPY_ALL. In that case this should be a
        //       device level signal that handles aggregation of domains directly here
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.engine_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        return m_levelzero.active_time_pair(dev_subdev_idx_pair.first, l0_domain,
                                            dev_subdev_idx_pair.second);
    }

    uint64_t LevelZeroDevicePoolImp::active_time_timestamp(int domain,
                                                           unsigned int domain_idx,
                                                           int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                             ": domain " + std::to_string(domain) +
                            " is not supported for the engine domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        // TODO: Some devices may not support ZES_ENGINE_GROUP_COMPUTE/COPY_ALL. In that case this should be a
        //       device level signal that handles aggregation of domains directly here
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.engine_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        return m_levelzero.active_time_timestamp(dev_subdev_idx_pair.first, l0_domain,
                                                 dev_subdev_idx_pair.second);
    }

    uint64_t LevelZeroDevicePoolImp::active_time(int domain, unsigned int domain_idx,
                                                 int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " +std::to_string(domain) +
                            " is not supported for the engine domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        //TODO: Some devices may not support ZES_ENGINE_GROUP_COMPUTE/COPY_ALL. In that case this should be a
        //      device level signal that handles aggregation of domains directly here
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.engine_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);
        return m_levelzero.active_time(dev_subdev_idx_pair.first, l0_domain,
                                       dev_subdev_idx_pair.second);
    }

    int32_t LevelZeroDevicePoolImp::power_limit_min(int domain, unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.power_limit_min(domain_idx);
    }

    int32_t LevelZeroDevicePoolImp::power_limit_max(int domain,
                                                    unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.power_limit_max(domain_idx);
    }

    int32_t LevelZeroDevicePoolImp::power_limit_tdp(int domain,
                                                    unsigned int domain_idx,
                                                    int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.power_limit_tdp(domain_idx);
    }

    std::pair<uint64_t, uint64_t> LevelZeroDevicePoolImp::energy_pair(int domain,
                                                                      unsigned int domain_idx,
                                                                      int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.energy_pair(domain_idx);
    }

    uint64_t LevelZeroDevicePoolImp::energy_timestamp(int domain,
                                                      unsigned int domain_idx,
                                                      int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.energy_timestamp(domain_idx);
    }

    uint64_t LevelZeroDevicePoolImp::energy(int domain, unsigned int domain_idx,
                                            int l0_domain) const
    {
        if (domain != GEOPM_DOMAIN_GPU) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the power domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        check_idx_range(domain, domain_idx);
        return m_levelzero.energy(domain_idx);
    }

    void LevelZeroDevicePoolImp::frequency_control(int domain, unsigned int domain_idx,
                                                   int l0_domain, double range_min,
                                                   double range_max) const
    {
        if (domain != GEOPM_DOMAIN_GPU_CHIP) {
            throw Exception("LevelZeroDevicePool::" + std::string(__func__) +
                            ": domain " + std::to_string(domain) +
                            " is not supported for the frequency domain.",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        std::pair<unsigned int, unsigned int> dev_subdev_idx_pair;
        dev_subdev_idx_pair = subdevice_device_conversion(domain_idx);
        check_domain_exists(m_levelzero.frequency_domain_count(
                                        dev_subdev_idx_pair.first, l0_domain),
                                        __func__, __LINE__);

        m_levelzero.frequency_control(dev_subdev_idx_pair.first, l0_domain,
                                      dev_subdev_idx_pair.second, range_min,
                                      range_max);
    }
}
<|endoftext|>


<commit_before>/**
 * This file is part of libstreamswtich, which belongs to StreamSwitch
 * project.
 *
 * Copyright (C) 2014  OpenSight (www.opensight.cn)
 *
 * StreamSwitch is an extensible and scalable media stream server for
 * multi-protocol environment.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
/**
 * stsw_stream_parser.cc
 *      StreamParser class implementation file, define methods of the StreamParser
 * class.
 *      StreamParser is the default parser for a ffmpeg AV stream, other
 * parser can inherit this class to override its methods for a specified
 * codec. All other streams would be associated this default parser
 *
 * author: OpenSight Team
 * date: 2015-10-27
**/

#include "stsw_stream_parser.h"

#include <stdint.h>

#include "../stsw_ffmpeg_demuxer.h"
#include "../stsw_ffmpeg_source_global.h"
#include "stsw_h264or5_parser.h"
#include "stsw_mpeg4_parser.h"

extern "C"{

#include <libavcodec/avcodec.h>
}

StreamParser::StreamParser()
:is_init_(false), stream_index_(0),  demuxer_(NULL), stream_(NULL), is_live_(true),
gop_started_(false),
last_pts_(AV_NOPTS_VALUE), last_dur_(0)
{
    last_live_ts_.tv_sec = 0;
    last_live_ts_.tv_usec = 0;
}
StreamParser::~StreamParser()
{

}
int StreamParser::Init(FFmpegDemuxer *demuxer, int stream_index)
{
    int ret = 0;
    if(is_init_){
        return 0;
    }
    demuxer_ = demuxer;
    stream_index_ = stream_index;
    stream_ = demuxer->fmt_ctx_->streams[stream_index];
    is_live_ =
        (demuxer->meta_.play_type == stream_switch::STREAM_PLAY_TYPE_LIVE);
    gop_started_ = false;
    last_pts_ = AV_NOPTS_VALUE;
    last_dur_ = 0;

    last_live_ts_.tv_sec = 0;
    last_live_ts_.tv_usec = 0;

    is_init_ = true;
    return 0;
}
void StreamParser::Uninit()
{
    if(!is_init_){
        return;
    }
    is_init_ = false;
    stream_index_ = 0;
    demuxer_ = NULL;
    stream_ = NULL;
    is_live_ = true;
    gop_started_ = false;
    last_pts_ = AV_NOPTS_VALUE;
    last_dur_ = 0;

    last_live_ts_.tv_sec = 0;
    last_live_ts_.tv_usec = 0;

    return;
}
int StreamParser::Parse(stream_switch::MediaFrameInfo *frame_info,
                        AVPacket *pkt,
                        bool* is_meta_changed)
{
    int ret = 0;

    if(pkt->flags & AV_PKT_FLAG_CORRUPT){
        //for corrupt packet, juet ignore and drop
        return FFMPEG_SOURCE_ERR_DROP;
    }

    ret = DoUpdateFrameInfo(frame_info, pkt);
    if(ret){
        return ret;
    }

    ret = DoUpdateMeta(pkt, is_meta_changed);
    if(ret){
        return ret;
    }

    if(frame_info->frame_type == stream_switch::MEDIA_FRAME_TYPE_KEY_FRAME){
        gop_started_ = true;
    }

    if(!gop_started_){
        return FFMPEG_SOURCE_ERR_DROP;
    }

    return 0;
}
void StreamParser::reset()
{
    gop_started_ = false;
    return;
}

bool StreamParser::IsMetaReady()
{
    return true;
}

int StreamParser::DoUpdateFrameInfo(stream_switch::MediaFrameInfo *frame_info,
                                    AVPacket *pkt)
{
    frame_info->ssrc = 0;
    frame_info->sub_stream_index = stream_index_;
    if(pkt->flags & AV_PKT_FLAG_KEY){
        frame_info->frame_type = stream_switch::MEDIA_FRAME_TYPE_KEY_FRAME;
    }else{
        frame_info->frame_type = stream_switch::MEDIA_FRAME_TYPE_DATA_FRAME;
    }
    //calculate timestamp
    if(is_live_){
        if(last_pts_ == AV_NOPTS_VALUE){
            //this is the first (has pts) packet to parse, use it as base
            last_pts_ = pkt->pts;
            last_dur_ = pkt->duration;
            gettimeofday(&last_live_ts_, NULL);
            frame_info->timestamp = last_live_ts_;

        }else{
            if(pkt->pts == AV_NOPTS_VALUE){
                // no pts for this packet, may be because of B frame situation,
                // which is not support for live stream, use the last packt time
                frame_info->timestamp = last_live_ts_;
                last_dur_ += pkt->duration;

            }else {
                int64_t pts_delta = 0;
                if(pkt->pts < last_pts_ ||
                   (pkt->pts - last_pts_) * stream_->time_base.num / stream_->time_base.den > 60) {
                    //this pts lose sync with the last pts, try to guess their delta
                    if(last_dur_ > 0){
                        //if duration is known, used last duration as delta
                        pts_delta = last_dur_;
                    }else if (stream_->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                              stream_->avg_frame_rate.den &&
                              stream_->avg_frame_rate.num){
                        //make use of average fps to calculate delta
                        pts_delta = (stream_->avg_frame_rate.den * stream_->time_base.den) /
                                    (stream_->avg_frame_rate.num * stream_->time_base.num);
                    }else{
                        //no any way to know delta
                        pts_delta = 0;
                    }
                }else{
                    //normal case
                    pts_delta = pkt->pts - last_pts_;

                }

                frame_info->timestamp.tv_sec =
                    (pts_delta * stream_->time_base.num) / stream_->time_base.den +
                    last_live_ts_.tv_sec;
                frame_info->timestamp.tv_usec =
                    ((pts_delta * stream_->time_base.num) % stream_->time_base.den)
                    * 1000000 / stream_->time_base.den +
                    last_live_ts_.tv_usec;
                while(frame_info->timestamp.tv_usec >= 1000000){
                    frame_info->timestamp.tv_sec ++;
                    frame_info->timestamp.tv_usec -= 1000000;
                }

                last_pts_ = pkt->pts;
                last_dur_ = pkt->duration;
                last_live_ts_ = frame_info->timestamp;

            }//if(pkt->pts == AV_NOPTS_VALUE){

        }//if(pkt->pts == AV_NOPTS_VALUE){

    }else{ // replay

        int64_t pts;
        //for non-live mode, use pts directly
        if(pkt->pts == AV_NOPTS_VALUE){
            if(last_pts_ != AV_NOPTS_VALUE){
                pts = last_pts_;
            }else{
                pts = 0;
            }
        }else{
            pts = pkt->pts;
            last_pts_ = pts;
            last_dur_ = pkt->duration;
        }

        frame_info->timestamp.tv_sec =
            (pts * stream_->time_base.num) / stream_->time_base.den;
        frame_info->timestamp.tv_usec =
            ((pts * stream_->time_base.num) % stream_->time_base.den)
            * 1000000 / stream_->time_base.den;
    }
    return 0;
}

int StreamParser::DoUpdateMeta(AVPacket *pkt, bool* is_meta_changed)
{

    if(is_meta_changed != NULL){
        (*is_meta_changed) = false;
    }
    return 0;
}

template<class T>
StreamParser* StreamParserFatcory()
{
	return new T;
}

struct ParserInfo {
    const int codec_id;
    StreamParser* (*factory)();
    const char name[32];
};

//FIXME this should be simplified!
static const ParserInfo parser_infos[] = {
   { AV_CODEC_ID_H264, StreamParserFatcory<H264or5Parser>, "H264" },
   { AV_CODEC_ID_H265, StreamParserFatcory<H264or5Parser>, "H265" },
   { AV_CODEC_ID_MPEG4, StreamParserFatcory<Mpeg4Parser>, "MP4V-ES" },
   { AV_CODEC_ID_AAC, NULL, "MPEG4-GENERIC" },
   { AV_CODEC_ID_AMR_NB, NULL, "AMR" },
   { AV_CODEC_ID_PCM_MULAW, NULL, "PCMU"},
   { AV_CODEC_ID_PCM_ALAW, NULL, "PCMA"},
   { AV_CODEC_ID_NONE, NULL, "NONE"}//XXX ...
};

const char * CodecNameFromId(int codec_id)
{
    const ParserInfo *parser_info = parser_infos;
    while (parser_info->codec_id != AV_CODEC_ID_NONE) {
        if (parser_info->codec_id == codec_id){
            if(parser_info->name != NULL){
                return parser_info->name;
            }else{
                return avcodec_get_name((enum AVCodecID)codec_id);
            }
        }
        parser_info++;
    }
    return avcodec_get_name((enum AVCodecID)codec_id);
}
StreamParser * NewStreamParser(int codec_id)
{
    const ParserInfo *parser_info = parser_infos;
    while (parser_info->codec_id != AV_CODEC_ID_NONE) {
        if (parser_info->codec_id == codec_id){
            if(parser_info->factory != NULL){
                return parser_info->factory();
            }else{
                return new StreamParser();
            }
        }
        parser_info++;
    }
    return new StreamParser();
}
<commit_msg>change AAC codec name<commit_after>/**
 * This file is part of libstreamswtich, which belongs to StreamSwitch
 * project.
 *
 * Copyright (C) 2014  OpenSight (www.opensight.cn)
 *
 * StreamSwitch is an extensible and scalable media stream server for
 * multi-protocol environment.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
**/
/**
 * stsw_stream_parser.cc
 *      StreamParser class implementation file, define methods of the StreamParser
 * class.
 *      StreamParser is the default parser for a ffmpeg AV stream, other
 * parser can inherit this class to override its methods for a specified
 * codec. All other streams would be associated this default parser
 *
 * author: OpenSight Team
 * date: 2015-10-27
**/

#include "stsw_stream_parser.h"

#include <stdint.h>

#include "../stsw_ffmpeg_demuxer.h"
#include "../stsw_ffmpeg_source_global.h"
#include "stsw_h264or5_parser.h"
#include "stsw_mpeg4_parser.h"

extern "C"{

#include <libavcodec/avcodec.h>
}

StreamParser::StreamParser()
:is_init_(false), stream_index_(0),  demuxer_(NULL), stream_(NULL), is_live_(true),
gop_started_(false),
last_pts_(AV_NOPTS_VALUE), last_dur_(0)
{
    last_live_ts_.tv_sec = 0;
    last_live_ts_.tv_usec = 0;
}
StreamParser::~StreamParser()
{

}
int StreamParser::Init(FFmpegDemuxer *demuxer, int stream_index)
{
    int ret = 0;
    if(is_init_){
        return 0;
    }
    demuxer_ = demuxer;
    stream_index_ = stream_index;
    stream_ = demuxer->fmt_ctx_->streams[stream_index];
    is_live_ =
        (demuxer->meta_.play_type == stream_switch::STREAM_PLAY_TYPE_LIVE);
    gop_started_ = false;
    last_pts_ = AV_NOPTS_VALUE;
    last_dur_ = 0;

    last_live_ts_.tv_sec = 0;
    last_live_ts_.tv_usec = 0;

    is_init_ = true;
    return 0;
}
void StreamParser::Uninit()
{
    if(!is_init_){
        return;
    }
    is_init_ = false;
    stream_index_ = 0;
    demuxer_ = NULL;
    stream_ = NULL;
    is_live_ = true;
    gop_started_ = false;
    last_pts_ = AV_NOPTS_VALUE;
    last_dur_ = 0;

    last_live_ts_.tv_sec = 0;
    last_live_ts_.tv_usec = 0;

    return;
}
int StreamParser::Parse(stream_switch::MediaFrameInfo *frame_info,
                        AVPacket *pkt,
                        bool* is_meta_changed)
{
    int ret = 0;

    if(pkt->flags & AV_PKT_FLAG_CORRUPT){
        //for corrupt packet, juet ignore and drop
        return FFMPEG_SOURCE_ERR_DROP;
    }

    ret = DoUpdateFrameInfo(frame_info, pkt);
    if(ret){
        return ret;
    }

    ret = DoUpdateMeta(pkt, is_meta_changed);
    if(ret){
        return ret;
    }

    if(frame_info->frame_type == stream_switch::MEDIA_FRAME_TYPE_KEY_FRAME){
        gop_started_ = true;
    }

    if(!gop_started_){
        return FFMPEG_SOURCE_ERR_DROP;
    }

    return 0;
}
void StreamParser::reset()
{
    gop_started_ = false;
    return;
}

bool StreamParser::IsMetaReady()
{
    return true;
}

int StreamParser::DoUpdateFrameInfo(stream_switch::MediaFrameInfo *frame_info,
                                    AVPacket *pkt)
{
    frame_info->ssrc = 0;
    frame_info->sub_stream_index = stream_index_;
    if(pkt->flags & AV_PKT_FLAG_KEY){
        frame_info->frame_type = stream_switch::MEDIA_FRAME_TYPE_KEY_FRAME;
    }else{
        frame_info->frame_type = stream_switch::MEDIA_FRAME_TYPE_DATA_FRAME;
    }
    //calculate timestamp
    if(is_live_){
        if(last_pts_ == AV_NOPTS_VALUE){
            //this is the first (has pts) packet to parse, use it as base
            last_pts_ = pkt->pts;
            last_dur_ = pkt->duration;
            gettimeofday(&last_live_ts_, NULL);
            frame_info->timestamp = last_live_ts_;

        }else{
            if(pkt->pts == AV_NOPTS_VALUE){
                // no pts for this packet, may be because of B frame situation,
                // which is not support for live stream, use the last packt time
                frame_info->timestamp = last_live_ts_;
                last_dur_ += pkt->duration;

            }else {
                int64_t pts_delta = 0;
                if(pkt->pts < last_pts_ ||
                   (pkt->pts - last_pts_) * stream_->time_base.num / stream_->time_base.den > 60) {
                    //this pts lose sync with the last pts, try to guess their delta
                    if(last_dur_ > 0){
                        //if duration is known, used last duration as delta
                        pts_delta = last_dur_;
                    }else if (stream_->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
                              stream_->avg_frame_rate.den &&
                              stream_->avg_frame_rate.num){
                        //make use of average fps to calculate delta
                        pts_delta = (stream_->avg_frame_rate.den * stream_->time_base.den) /
                                    (stream_->avg_frame_rate.num * stream_->time_base.num);
                    }else{
                        //no any way to know delta
                        pts_delta = 0;
                    }
                }else{
                    //normal case
                    pts_delta = pkt->pts - last_pts_;

                }

                frame_info->timestamp.tv_sec =
                    (pts_delta * stream_->time_base.num) / stream_->time_base.den +
                    last_live_ts_.tv_sec;
                frame_info->timestamp.tv_usec =
                    ((pts_delta * stream_->time_base.num) % stream_->time_base.den)
                    * 1000000 / stream_->time_base.den +
                    last_live_ts_.tv_usec;
                while(frame_info->timestamp.tv_usec >= 1000000){
                    frame_info->timestamp.tv_sec ++;
                    frame_info->timestamp.tv_usec -= 1000000;
                }

                last_pts_ = pkt->pts;
                last_dur_ = pkt->duration;
                last_live_ts_ = frame_info->timestamp;

            }//if(pkt->pts == AV_NOPTS_VALUE){

        }//if(pkt->pts == AV_NOPTS_VALUE){

    }else{ // replay

        int64_t pts;
        //for non-live mode, use pts directly
        if(pkt->pts == AV_NOPTS_VALUE){
            if(last_pts_ != AV_NOPTS_VALUE){
                pts = last_pts_;
            }else{
                pts = 0;
            }
        }else{
            pts = pkt->pts;
            last_pts_ = pts;
            last_dur_ = pkt->duration;
        }

        frame_info->timestamp.tv_sec =
            (pts * stream_->time_base.num) / stream_->time_base.den;
        frame_info->timestamp.tv_usec =
            ((pts * stream_->time_base.num) % stream_->time_base.den)
            * 1000000 / stream_->time_base.den;
    }
    return 0;
}

int StreamParser::DoUpdateMeta(AVPacket *pkt, bool* is_meta_changed)
{

    if(is_meta_changed != NULL){
        (*is_meta_changed) = false;
    }
    return 0;
}

template<class T>
StreamParser* StreamParserFatcory()
{
	return new T;
}

struct ParserInfo {
    const int codec_id;
    StreamParser* (*factory)();
    const char name[32];
};

//FIXME this should be simplified!
static const ParserInfo parser_infos[] = {
   { AV_CODEC_ID_H264, StreamParserFatcory<H264or5Parser>, "H264" },
   { AV_CODEC_ID_H265, StreamParserFatcory<H264or5Parser>, "H265" },
   { AV_CODEC_ID_MPEG4, StreamParserFatcory<Mpeg4Parser>, "MP4V-ES" },
   { AV_CODEC_ID_AAC, NULL, "AAC" },
   { AV_CODEC_ID_AMR_NB, NULL, "AMR" },
   { AV_CODEC_ID_PCM_MULAW, NULL, "PCMU"},
   { AV_CODEC_ID_PCM_ALAW, NULL, "PCMA"},
   { AV_CODEC_ID_NONE, NULL, "NONE"}//XXX ...
};

const char * CodecNameFromId(int codec_id)
{
    const ParserInfo *parser_info = parser_infos;
    while (parser_info->codec_id != AV_CODEC_ID_NONE) {
        if (parser_info->codec_id == codec_id){
            if(parser_info->name != NULL){
                return parser_info->name;
            }else{
                return avcodec_get_name((enum AVCodecID)codec_id);
            }
        }
        parser_info++;
    }
    return avcodec_get_name((enum AVCodecID)codec_id);
}
StreamParser * NewStreamParser(int codec_id)
{
    const ParserInfo *parser_info = parser_infos;
    while (parser_info->codec_id != AV_CODEC_ID_NONE) {
        if (parser_info->codec_id == codec_id){
            if(parser_info->factory != NULL){
                return parser_info->factory();
            }else{
                return new StreamParser();
            }
        }
        parser_info++;
    }
    return new StreamParser();
}
<|endoftext|>


<commit_before>/**
 * @project zqrpc
 * @file include/zqrpc/ZSocket.hpp
 * @author  S Roychowdhury <sroycode @ gmail DOT com>
 * @version 0.1
 *
 * @section LICENSE
 *
 * Copyright (c) 2014 S Roychowdhury
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @section DESCRIPTION
 *
 *  ZSocket.hpp : Send and Recv
 *
 */
#ifndef _ZQRPC_ZSOCKET_HPP_
#define _ZQRPC_ZSOCKET_HPP_

#include <stdint.h>
#include <cstring>
#include <boost/thread.hpp>
#include "zmq.hpp"
#include "ZError.hpp"
#include "RpcHeaders.hh"

namespace zqrpc {
class ZSocket {

friend class RpcServer;

public:
	ZSocket(zmq::context_t* context, int type, const std::string& id)
		: socket_(*context,type)
	{
		if (id.length()>0)
			socket_.setsockopt(ZMQ_IDENTITY, id.c_str(), id.length());
	}

	~ZSocket() {
	}

	void connect(const char* url) {
		socket_.connect(url);
	}

	void disconnect(const char* url) {
		if ( socket_.connected() ) socket_.disconnect(url);
	}

	void bind(const char* url) {
		socket_.bind(url);
	}
	void unbind(const char* url) {
		if (strncmp(url,"inproc",6)!=0) socket_.unbind(url);
	}

	void close() {
		socket_.close();
	}

	void SetOption(int type,std::string opt) {
		socket_.setsockopt(type, opt.c_str(), opt.length());
	}

	void SetLinger(int linger = -1) {
		socket_.setsockopt(ZMQ_LINGER, &linger, sizeof(int));
	}

	template<typename T>
	bool Send(const T& frames) {
		std::size_t fleft= frames.size();
		if(!fleft) return true;
		for (typename T::const_iterator it = frames.begin(); it!=frames.end(); ++it,--fleft) {
			zmq::message_t msg (it->length());
    	memcpy ((void *) msg.data (), it->c_str(), it->length());
			// DLOG(INFO) << std::string(static_cast<char*>(msg.data()), msg.size()) << std::endl;
			if (! socket_.send(msg, (fleft==1) ? 0 : ZMQ_SNDMORE) )
				throw ZError(ZEC_CONNECTIONERROR,"cannot send data frame");
		}
		return true;
	}

	template<typename T>
	T BlockingRecv() {
		T frames;
		bool more=false;
		do {
			zmq::message_t msg(0);
			if (!socket_.recv(&msg, 0)) throw zqrpc::RetryException();
			frames.push_back(std::string(static_cast<char*>(msg.data()), msg.size()));
			// DLOG(INFO) << std::string(static_cast<char*>(msg.data()), msg.size()) << std::endl;
			more = msg.more();
		} while(more);

		return frames;
	}

	template<typename T>
	T NonBlockingRecv() {
		T frames;
		zmq::message_t msg(0);
		bool more=false;
		do {
			if (!socket_.recv(&msg, ZMQ_DONTWAIT)) throw zqrpc::RetryException();
			frames.push_back(std::string(static_cast<char*>(msg.data()), msg.size()));
			more = msg.more();
		} while(more);

		return frames;
	}

	bool Poll(long timeout) {
		zmq::pollitem_t items[] = { { socket_, 0, ZMQ_POLLIN, 0 } };
		zmq::poll (&items[0], 1, timeout);
		return (items[0].revents & ZMQ_POLLIN);
		// DLOG(INFO) << "Polling End" << std::endl;
	}

private:
	zmq::socket_t socket_;

	ZSocket(const ZSocket&);
	void operator=(const ZSocket&);

};
} // namespace

#endif
<commit_msg>Wed Aug 13 10:06:16 IST 2014<commit_after>/**
 * @project zqrpc
 * @file include/zqrpc/ZSocket.hpp
 * @author  S Roychowdhury <sroycode @ gmail DOT com>
 * @version 0.1
 *
 * @section LICENSE
 *
 * Copyright (c) 2014 S Roychowdhury
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @section DESCRIPTION
 *
 *  ZSocket.hpp : Send and Recv
 *
 */
#ifndef _ZQRPC_ZSOCKET_HPP_
#define _ZQRPC_ZSOCKET_HPP_

#include <stdint.h>
#include <cstring>
#include <boost/thread.hpp>
#include "zmq.hpp"
#include "ZError.hpp"
#include "RpcHeaders.hh"

namespace zqrpc {
class ZSocket {

friend class RpcServer;

public:
	ZSocket(zmq::context_t* context, int type, const std::string& id)
		: socket_(*context,type)
	{
		if (id.length()>0)
			socket_.setsockopt(ZMQ_IDENTITY, id.c_str(), id.length());
	}

	~ZSocket() {
	}

	void connect(const char* url) {
		socket_.connect(url);
	}

	void disconnect(const char* url) {
		if ( socket_.connected() ) socket_.disconnect(url);
	}

	void bind(const char* url) {
		socket_.bind(url);
	}
	void unbind(const char* url) {
		if (strncmp(url,"inproc",6)!=0) socket_.unbind(url);
	}

	void close() {
		socket_.close();
	}

	void SetOption(int type,std::string opt) {
		socket_.setsockopt(type, opt.c_str(), opt.length());
	}

	void SetLinger(int linger = -1) {
		socket_.setsockopt(ZMQ_LINGER, &linger, sizeof(int));
	}

	template<typename T>
	bool Send(const T& frames) {
		std::size_t fleft= frames.size();
		if(!fleft) return true;
		for (typename T::const_iterator it = frames.begin(); it!=frames.end(); ++it,--fleft) {
			zmq::message_t msg (it->length());
    	memcpy ((void *) msg.data (), it->c_str(), it->length());
			// DLOG(INFO) << std::string(static_cast<char*>(msg.data()), msg.size()) << std::endl;
			if (! socket_.send(msg, (fleft==1) ? 0 : ZMQ_SNDMORE) )
				throw ZError(ZEC_CONNECTIONERROR,"cannot send data frame");
		}
		return true;
	}

	template<typename T>
	T BlockingRecv() {
		T frames;
		bool more=false;
		do {
			zmq::message_t msg(0);
			if (!socket_.recv(&msg, 0)) throw zqrpc::RetryException();
			frames.push_back(std::string(static_cast<char*>(msg.data()), msg.size()));
			// DLOG(INFO) << std::string(static_cast<char*>(msg.data()), msg.size()) << std::endl;
			more = msg.more();
		} while(more);

		return frames;
	}

	template<typename T>
	T NonBlockingRecv() {
		T frames;
		zmq::message_t msg(0);
		bool more=false;
		do {
			if (!socket_.recv(&msg, ZMQ_DONTWAIT)) throw zqrpc::RetryException();
			frames.push_back(std::string(static_cast<char*>(msg.data()), msg.size()));
			more = msg.more();
		} while(more);

		return frames;
	}

	bool Poll(long timeout) {
		zmq::pollitem_t items[] = { { socket_, 0, ZMQ_POLLIN, 0 } };
		zmq::poll (&items[0], 1, timeout);
		return (items[0].revents & ZMQ_POLLIN);
		// DLOG(INFO) << "Polling End" << std::endl;
	}

private:
	zmq::socket_t socket_;

	ZSocket(const ZSocket&);
	void operator=(const ZSocket&);

};
} // namespace

#endif
<|endoftext|>


<commit_before>#include "types_mapping.hpp"
#include "classificator.hpp"

#include "../base/string_utils.hpp"
#include "../base/stl_add.hpp"

void IndexAndTypeMapping::Load(istream & s)
{
  Classificator const & c = classif();

  string v;
  vector<string> path;

  uint32_t ind = 0;
  while (s.good())
  {
    v.clear();
    s >> v;

    if (!v.empty())
    {
      path.clear();
      strings::Tokenize(v, "|", MakeBackInsertFunctor(path));

      Add(ind++, c.GetTypeByPath(path));
    }
  }
}

void IndexAndTypeMapping::Add(uint32_t ind, uint32_t type)
{
  ASSERT_EQUAL ( ind, m_types.size(), () );
  m_types.push_back(type);

  m_map.insert(make_pair(type, ind));
}

uint32_t IndexAndTypeMapping::GetIndex(uint32_t t) const
{
  MapT::const_iterator i = m_map.find(t);
  CHECK ( i != m_map.end(), (t, classif().GetFullObjectName(t)) );
  return i->second;
}
<commit_msg>readded check for duplicate style names<commit_after>#include "types_mapping.hpp"
#include "classificator.hpp"

#include "../base/string_utils.hpp"
#include "../base/stl_add.hpp"

void IndexAndTypeMapping::Load(istream & s)
{
  Classificator const & c = classif();

  string v;
  vector<string> path;

  uint32_t ind = 0;
  while (s.good())
  {
    v.clear();
    s >> v;

    if (!v.empty())
    {
      path.clear();
      strings::Tokenize(v, "|", MakeBackInsertFunctor(path));

      Add(ind++, c.GetTypeByPath(path));
    }
  }
}

void IndexAndTypeMapping::Add(uint32_t ind, uint32_t type)
{
  ASSERT_EQUAL ( ind, m_types.size(), () );
  m_types.push_back(type);

  if (!m_map.insert(make_pair(type, ind)).second)
  {
    string const name = classif().GetFullObjectName(type);
    CHECK_EQUAL(name, "mapswithme|", ());
  }
}

uint32_t IndexAndTypeMapping::GetIndex(uint32_t t) const
{
  MapT::const_iterator i = m_map.find(t);
  CHECK ( i != m_map.end(), (t, classif().GetFullObjectName(t)) );
  return i->second;
}
<|endoftext|>


<commit_before>/**
 * @file lltoast.cpp
 * @brief This class implements a placeholder for any notification panel.
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 *
 * Copyright (c) 2000-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "lltoast.h"

#include "llbutton.h"
#include "llfocusmgr.h"
#include "llnotifications.h"
#include "llviewercontrol.h"

using namespace LLNotificationsUI;

//--------------------------------------------------------------------------
LLToast::Params::Params()
:	can_fade("can_fade", true),
	can_be_stored("can_be_stored", true),
	is_modal("is_modal", false),
	is_tip("is_tip", false),
	enable_hide_btn("enable_hide_btn", true),
	force_show("force_show", false),
	force_store("force_store", false),
	fading_time_secs("fading_time_secs", gSavedSettings.getS32("ToastFadingTime")),
	lifetime_secs("lifetime_secs", gSavedSettings.getS32("NotificationToastLifeTime"))
{};

LLToast::LLToast(const LLToast::Params& p)
:	LLModalDialog(LLSD(), p.is_modal),
	mPanel(p.panel),
	mToastLifetime(p.lifetime_secs),
	mToastFadingTime(p.fading_time_secs),
	mNotificationID(p.notif_id),
	mSessionID(p.session_id),
	mCanFade(p.can_fade),
	mCanBeStored(p.can_be_stored),
	mHideBtnEnabled(p.enable_hide_btn),
	mHideBtn(NULL),
	mNotification(p.notification),
	mIsHidden(false),
	mHideBtnPressed(false),
	mIsTip(p.is_tip)
{
	LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL);

	setCanDrag(FALSE);

	if(mPanel)
	{
		insertPanel(mPanel);
	}

	if(mHideBtnEnabled)
	{
		mHideBtn = getChild<LLButton>("hide_btn");
		mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
	}

	// init callbacks if present
	if(!p.on_delete_toast().empty())
		mOnDeleteToastSignal.connect(p.on_delete_toast());

	if(!p.on_mouse_enter().empty())
		mOnMouseEnterSignal.connect(p.on_mouse_enter());
}

//--------------------------------------------------------------------------
BOOL LLToast::postBuild()
{
	if(!mCanFade)
	{
		mTimer.stop();
	}

	if (mIsTip)
	{
		mTextEditor = mPanel->getChild<LLTextEditor>("text_editor_box");

		if (mTextEditor)
		{
			mTextEditor->setMouseUpCallback(boost::bind(&LLToast::hide,this));
			mPanel->setMouseUpCallback(boost::bind(&LLToast::handleTipToastClick, this, _2, _3, _4));
		}
	}

	return TRUE;
}

//--------------------------------------------------------------------------
void LLToast::handleTipToastClick(S32 x, S32 y, MASK mask)
{
	if (!mTextEditor->getRect().pointInRect(x, y))
	{
		hide();
	}
}

//--------------------------------------------------------------------------
void LLToast::setHideButtonEnabled(bool enabled)
{
	if(mHideBtn)
		mHideBtn->setEnabled(enabled);
}

//--------------------------------------------------------------------------
LLToast::~LLToast()
{
	mOnToastDestroyedSignal(this);
}

//--------------------------------------------------------------------------
void LLToast::setAndStartTimer(F32 period)
{
	if(mCanFade)
	{
		mToastLifetime = period;
		mTimer.start();
	}
}

//--------------------------------------------------------------------------
bool LLToast::lifetimeHasExpired()
{
	if (mTimer.getStarted())
	{
		F32 elapsed_time = mTimer.getElapsedTimeF32();
		if ((mToastLifetime - elapsed_time) <= mToastFadingTime)
		{
			setBackgroundOpaque(FALSE);
		}
		if (elapsed_time > mToastLifetime)
		{
			return true;
		}
	}
	return false;
}

//--------------------------------------------------------------------------
void LLToast::hide()
{
	setVisible(FALSE);
	mTimer.stop();
	mIsHidden = true;
	mOnFadeSignal(this);
}

//--------------------------------------------------------------------------
void LLToast::setCanFade(bool can_fade)
{
	mCanFade = can_fade;
	if(!mCanFade)
		mTimer.stop();
}

//--------------------------------------------------------------------------
void LLToast::tick()
{
	if(mCanFade)
	{
		hide();
	}
}

//--------------------------------------------------------------------------

void LLToast::reshapeToPanel()
{
	LLPanel* panel = getPanel();
	if(!panel)
		return;

	LLRect panel_rect;

	panel_rect = panel->getRect();
	reshape(panel_rect.getWidth(), panel_rect.getHeight());
	panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
	panel->setRect(panel_rect);

	LLRect toast_rect = getRect();
	toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
	setRect(toast_rect);

}

void LLToast::insertPanel(LLPanel* panel)
{
	addChild(panel);
	reshapeToPanel();
}

//--------------------------------------------------------------------------
void LLToast::draw()
{
	if(lifetimeHasExpired())
	{
		tick();
	}

	LLFloater::draw();
}

//--------------------------------------------------------------------------
void LLToast::setVisible(BOOL show)
{
	if(mIsHidden)
	{
		// this toast is invisible after fade until its ScreenChannel will allow it
		//
		// (EXT-1849) according to this bug a toast can be resurrected from
		// invisible state if it faded during a teleportation
		// then it fades a second time and causes a crash
		return;
	}

	if(show)
	{
		setBackgroundOpaque(TRUE);
		if(!mTimer.getStarted() && mCanFade)
		{
			mTimer.start();
		}
		LLModalDialog::setFrontmost(FALSE);
	}
	LLFloater::setVisible(show);
	if(mPanel)
	{
		if(!mPanel->isDead())
		{
			mPanel->setVisible(show);
		}
	}
}

//--------------------------------------------------------------------------
void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
{
	mOnToastHoverSignal(this, MOUSE_ENTER);

	//toasts fading is management by Screen Channel

	sendChildToFront(mHideBtn);
	if(mHideBtn && mHideBtn->getEnabled())
		mHideBtn->setVisible(TRUE);
	mOnMouseEnterSignal(this);

	LLModalDialog::onMouseEnter(x, y, mask);
}

//--------------------------------------------------------------------------
void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
{
	mOnToastHoverSignal(this, MOUSE_LEAVE);

	//toasts fading is management by Screen Channel

	if(mHideBtn && mHideBtn->getEnabled())
	{
		if( mHideBtnPressed )
		{
			mHideBtnPressed = false;
			return;
		}
		mHideBtn->setVisible(FALSE);
	}

	LLModalDialog::onMouseLeave(x, y, mask);
}

void LLNotificationsUI::LLToast::stopFading()
{
	if(mCanFade)
	{
		stopTimer();
	}
}

void LLNotificationsUI::LLToast::startFading()
{
	if(mCanFade)
	{
		resetTimer();
	}
}

//--------------------------------------------------------------------------

BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
{
	if(mHideBtn && mHideBtn->getEnabled())
	{
		mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y);
	}

	return LLFloater::handleMouseDown(x, y, mask);
}

//--------------------------------------------------------------------------
bool LLToast::isNotificationValid()
{
	if(mNotification)
	{
		return !mNotification->isCancelled();
	}
	return false;
}

//--------------------------------------------------------------------------

<commit_msg>fixed EXT-3374 “[BSI] Notifications and dialogs are semi-transparent (not opaque) even when in focus”, made toast opaque when became hovered;<commit_after>/**
 * @file lltoast.cpp
 * @brief This class implements a placeholder for any notification panel.
 *
 * $LicenseInfo:firstyear=2000&license=viewergpl$
 *
 * Copyright (c) 2000-2009, Linden Research, Inc.
 *
 * Second Life Viewer Source Code
 * The source code in this file ("Source Code") is provided by Linden Lab
 * to you under the terms of the GNU General Public License, version 2.0
 * ("GPL"), unless you have obtained a separate licensing agreement
 * ("Other License"), formally executed by you and Linden Lab.  Terms of
 * the GPL can be found in doc/GPL-license.txt in this distribution, or
 * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
 *
 * There are special exceptions to the terms and conditions of the GPL as
 * it is applied to this Source Code. View the full text of the exception
 * in the file doc/FLOSS-exception.txt in this software distribution, or
 * online at
 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
 *
 * By copying, modifying or distributing this software, you acknowledge
 * that you have read and understood your obligations described above,
 * and agree to abide by those obligations.
 *
 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
 * COMPLETENESS OR PERFORMANCE.
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h" // must be first include

#include "lltoast.h"

#include "llbutton.h"
#include "llfocusmgr.h"
#include "llnotifications.h"
#include "llviewercontrol.h"

using namespace LLNotificationsUI;

//--------------------------------------------------------------------------
LLToast::Params::Params()
:	can_fade("can_fade", true),
	can_be_stored("can_be_stored", true),
	is_modal("is_modal", false),
	is_tip("is_tip", false),
	enable_hide_btn("enable_hide_btn", true),
	force_show("force_show", false),
	force_store("force_store", false),
	fading_time_secs("fading_time_secs", gSavedSettings.getS32("ToastFadingTime")),
	lifetime_secs("lifetime_secs", gSavedSettings.getS32("NotificationToastLifeTime"))
{};

LLToast::LLToast(const LLToast::Params& p)
:	LLModalDialog(LLSD(), p.is_modal),
	mPanel(p.panel),
	mToastLifetime(p.lifetime_secs),
	mToastFadingTime(p.fading_time_secs),
	mNotificationID(p.notif_id),
	mSessionID(p.session_id),
	mCanFade(p.can_fade),
	mCanBeStored(p.can_be_stored),
	mHideBtnEnabled(p.enable_hide_btn),
	mHideBtn(NULL),
	mNotification(p.notification),
	mIsHidden(false),
	mHideBtnPressed(false),
	mIsTip(p.is_tip)
{
	LLUICtrlFactory::getInstance()->buildFloater(this, "panel_toast.xml", NULL);

	setCanDrag(FALSE);

	if(mPanel)
	{
		insertPanel(mPanel);
	}

	if(mHideBtnEnabled)
	{
		mHideBtn = getChild<LLButton>("hide_btn");
		mHideBtn->setClickedCallback(boost::bind(&LLToast::hide,this));
	}

	// init callbacks if present
	if(!p.on_delete_toast().empty())
		mOnDeleteToastSignal.connect(p.on_delete_toast());

	if(!p.on_mouse_enter().empty())
		mOnMouseEnterSignal.connect(p.on_mouse_enter());
}

//--------------------------------------------------------------------------
BOOL LLToast::postBuild()
{
	if(!mCanFade)
	{
		mTimer.stop();
	}

	if (mIsTip)
	{
		mTextEditor = mPanel->getChild<LLTextEditor>("text_editor_box");

		if (mTextEditor)
		{
			mTextEditor->setMouseUpCallback(boost::bind(&LLToast::hide,this));
			mPanel->setMouseUpCallback(boost::bind(&LLToast::handleTipToastClick, this, _2, _3, _4));
		}
	}

	return TRUE;
}

//--------------------------------------------------------------------------
void LLToast::handleTipToastClick(S32 x, S32 y, MASK mask)
{
	if (!mTextEditor->getRect().pointInRect(x, y))
	{
		hide();
	}
}

//--------------------------------------------------------------------------
void LLToast::setHideButtonEnabled(bool enabled)
{
	if(mHideBtn)
		mHideBtn->setEnabled(enabled);
}

//--------------------------------------------------------------------------
LLToast::~LLToast()
{
	mOnToastDestroyedSignal(this);
}

//--------------------------------------------------------------------------
void LLToast::setAndStartTimer(F32 period)
{
	if(mCanFade)
	{
		mToastLifetime = period;
		mTimer.start();
	}
}

//--------------------------------------------------------------------------
bool LLToast::lifetimeHasExpired()
{
	if (mTimer.getStarted())
	{
		F32 elapsed_time = mTimer.getElapsedTimeF32();
		if ((mToastLifetime - elapsed_time) <= mToastFadingTime)
		{
			setBackgroundOpaque(FALSE);
		}
		if (elapsed_time > mToastLifetime)
		{
			return true;
		}
	}
	return false;
}

//--------------------------------------------------------------------------
void LLToast::hide()
{
	setVisible(FALSE);
	mTimer.stop();
	mIsHidden = true;
	mOnFadeSignal(this);
}

//--------------------------------------------------------------------------
void LLToast::setCanFade(bool can_fade)
{
	mCanFade = can_fade;
	if(!mCanFade)
		mTimer.stop();
}

//--------------------------------------------------------------------------
void LLToast::tick()
{
	if(mCanFade)
	{
		hide();
	}
}

//--------------------------------------------------------------------------

void LLToast::reshapeToPanel()
{
	LLPanel* panel = getPanel();
	if(!panel)
		return;

	LLRect panel_rect;

	panel_rect = panel->getRect();
	reshape(panel_rect.getWidth(), panel_rect.getHeight());
	panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
	panel->setRect(panel_rect);

	LLRect toast_rect = getRect();
	toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
	setRect(toast_rect);

}

void LLToast::insertPanel(LLPanel* panel)
{
	addChild(panel);
	reshapeToPanel();
}

//--------------------------------------------------------------------------
void LLToast::draw()
{
	if(lifetimeHasExpired())
	{
		tick();
	}

	LLFloater::draw();
}

//--------------------------------------------------------------------------
void LLToast::setVisible(BOOL show)
{
	if(mIsHidden)
	{
		// this toast is invisible after fade until its ScreenChannel will allow it
		//
		// (EXT-1849) according to this bug a toast can be resurrected from
		// invisible state if it faded during a teleportation
		// then it fades a second time and causes a crash
		return;
	}

	if(show)
	{
		setBackgroundOpaque(TRUE);
		if(!mTimer.getStarted() && mCanFade)
		{
			mTimer.start();
		}
		LLModalDialog::setFrontmost(FALSE);
	}
	LLFloater::setVisible(show);
	if(mPanel)
	{
		if(!mPanel->isDead())
		{
			mPanel->setVisible(show);
		}
	}
}

//--------------------------------------------------------------------------
void LLToast::onMouseEnter(S32 x, S32 y, MASK mask)
{
	mOnToastHoverSignal(this, MOUSE_ENTER);

	setBackgroundOpaque(TRUE);

	//toasts fading is management by Screen Channel

	sendChildToFront(mHideBtn);
	if(mHideBtn && mHideBtn->getEnabled())
		mHideBtn->setVisible(TRUE);
	mOnMouseEnterSignal(this);

	LLModalDialog::onMouseEnter(x, y, mask);
}

//--------------------------------------------------------------------------
void LLToast::onMouseLeave(S32 x, S32 y, MASK mask)
{
	mOnToastHoverSignal(this, MOUSE_LEAVE);

	//toasts fading is management by Screen Channel

	if(mHideBtn && mHideBtn->getEnabled())
	{
		if( mHideBtnPressed )
		{
			mHideBtnPressed = false;
			return;
		}
		mHideBtn->setVisible(FALSE);
	}

	LLModalDialog::onMouseLeave(x, y, mask);
}

void LLNotificationsUI::LLToast::stopFading()
{
	if(mCanFade)
	{
		stopTimer();
	}
}

void LLNotificationsUI::LLToast::startFading()
{
	if(mCanFade)
	{
		resetTimer();
	}
}

//--------------------------------------------------------------------------

BOOL LLToast::handleMouseDown(S32 x, S32 y, MASK mask)
{
	if(mHideBtn && mHideBtn->getEnabled())
	{
		mHideBtnPressed = mHideBtn->getRect().pointInRect(x, y);
	}

	return LLFloater::handleMouseDown(x, y, mask);
}

//--------------------------------------------------------------------------
bool LLToast::isNotificationValid()
{
	if(mNotification)
	{
		return !mNotification->isCancelled();
	}
	return false;
}

//--------------------------------------------------------------------------

<|endoftext|>


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

#include "watchdogd.hpp"
#include "sub.hpp"
#include "init.hpp"
#include "pidfile.hpp"
#include "daemon.hpp"
#include "logutils.hpp"

int Daemonize(struct cfgoptions *const s)
{
	assert(s != NULL);

	if (s == NULL) {
		return -1;
	}

	if (IsDaemon(s) == 0) { //shall we daemonize?
		return 0;
	}

	kill(getppid(), SIGUSR1);
	SetLogTarget(SYSTEM_LOG);
	return 0;
}
<commit_msg>change log level before daemonizing<commit_after>/*
 * Copyright 2013-2016 Christian Lockley
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may obtain
 * a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

#include "watchdogd.hpp"
#include "sub.hpp"
#include "init.hpp"
#include "pidfile.hpp"
#include "daemon.hpp"
#include "logutils.hpp"

int Daemonize(struct cfgoptions *const s)
{
	assert(s != NULL);

	if (s == NULL) {
		return -1;
	}

	if (IsDaemon(s) == 0) { //shall we daemonize?
		return 0;
	}

	SetLogTarget(SYSTEM_LOG);
	kill(getppid(), SIGUSR1);
	return 0;
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperQtWidgetView.h"

#include "otbWrapperQtWidgetParameterGroup.h"
#include "otbWrapperQtWidgetParameterFactory.h"
#include "otbWrapperQtWidgetProgressReport.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperParameterGroup.h"
#include "otbWrapperQtWidgetSimpleProgressReport.h"

#include "itksys/SystemTools.hxx"

namespace otb
{
namespace Wrapper
{

QtWidgetView::QtWidgetView(Application* app)
{
  m_Model = new QtWidgetModel(app);
  m_Application = app;
}

QtWidgetView::~QtWidgetView()
{

}

void QtWidgetView::CreateGui()
{
  // Create a VBoxLayout with the header, the input widgets, and the footer
  QVBoxLayout *mainLayout = new QVBoxLayout();
  QTabWidget *tab = new QTabWidget();

  tab->addTab(CreateInputWidgets(), "Parameters");
  QTextEdit *log = new QTextEdit();
  connect( m_Model->GetLogOutput(), SIGNAL(NewContentLog(QString)), log, SLOT(append(QString) ) );
  tab->addTab(log, "Logs");
  QtWidgetProgressReport* prog =  new QtWidgetProgressReport(m_Model);
  prog->SetApplication(m_Application);
  tab->addTab(prog, "Progress");
  tab->addTab(CreateDoc(), "Documentation");
  mainLayout->addWidget(tab);

  m_Message = new QLabel("Select parameters");
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), this, SLOT(UpdateMessageAfterApplicationReady(bool)) );
  mainLayout->addWidget(m_Message);

  QtWidgetSimpleProgressReport * progressReport =  new QtWidgetSimpleProgressReport(m_Model);
  progressReport->SetApplication(m_Application);

  QHBoxLayout *footLayout = new QHBoxLayout;
  footLayout->addWidget(progressReport);
  footLayout->addWidget(CreateFooter());
  mainLayout->addLayout(footLayout);

  QGroupBox *mainGroup = new QGroupBox();
  mainGroup->setLayout(mainLayout);

  QVBoxLayout  *finalLayout = new QVBoxLayout();
  finalLayout->addWidget(mainGroup);

  // Make the final layout to the widget
  this->setLayout(finalLayout);
}

void QtWidgetView::UpdateMessageAfterExcuteClicked()
{
  m_Message->setText("Running");
}

void QtWidgetView::UpdateMessageAfterApplicationReady( bool val )
{
  if(val == true)
    m_Message->setText("Ready to run");
  else
    m_Message->setText("Select parameters");
}

QWidget* QtWidgetView::CreateInputWidgets()
{
  QScrollArea *scrollArea = new QScrollArea;
  // Put the main group inside a scroll area
  scrollArea->setWidget(QtWidgetParameterFactory::CreateQtWidget(m_Model->GetApplication()->GetParameterList(), m_Model));
  scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setWidgetResizable(true);

  return scrollArea;
}

QWidget* QtWidgetView::CreateFooter()
{
  // an HLayout with two buttons : Execute and Quit
  QGroupBox *footerGroup = new QGroupBox;
  QHBoxLayout *footerLayout = new QHBoxLayout;

  footerGroup->setFixedHeight(40);
  footerGroup->setContentsMargins(0, 0, 0, 0);
  footerLayout->setContentsMargins(5, 5, 5, 5);

  m_ExecButton = new QPushButton(footerGroup);
  m_ExecButton->setDefault(true);
  m_ExecButton->setEnabled(false);
  m_ExecButton->setText(QObject::tr("Execute"));
  connect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) );
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), m_ExecButton, SLOT(setEnabled(bool)) );
  connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExcuteClicked() ) );

  m_QuitButton = new QPushButton(footerGroup);
  m_QuitButton->setText(QObject::tr("Quit"));
  connect( m_QuitButton, SIGNAL(clicked()), this, SLOT(CloseSlot()) );

  // Put the buttons on the right
  footerLayout->addStretch();
  footerLayout->addWidget(m_ExecButton);
  footerLayout->addWidget(m_QuitButton);

  footerGroup->setLayout(footerLayout);

  return footerGroup;
}

QWidget* QtWidgetView::CreateDoc()
{
  QTextEdit *text = new QTextEdit;
  text->setReadOnly(true);

  QTextDocument * doc = new QTextDocument();
  itk::OStringStream oss;
  oss << "
" << m_Application->GetDocName() << "
";
  oss << "
Brief Description
";
  oss << "" << m_Application->GetDescription() << "";
  oss << "
Tags
";
  oss << "";
  if (m_Application->GetDocTags().size() > 0)
    {
    for (unsigned int i = 0; i < m_Application->GetDocTags().size() - 1; i++)
      {
      oss << m_Application->GetDocTags()[i] << ", ";
   ;
      }
    oss << m_Application->GetDocTags()[m_Application->GetDocTags().size() - 1];
    }
  oss << "";

  oss << "
Long Description
";
  oss << "" << m_Application->GetDocLongDescription() << "";

  std::string val;
  this->SetDocParameters(val);
  oss << val;

  oss << "
Limitations
";
  oss << "" << m_Application->GetDocLimitations() << "";
  oss << "
Authors
";
  oss << "" << m_Application->GetDocAuthors() << "";
  oss << "
See also
";
  oss << "" << m_Application->GetDocSeeAlso() << "";
  oss << "
Command line example
";
  oss << "" << m_Application->GetDocCLExample() << "";

  doc->setHtml(oss.str().c_str());

  text->setDocument(doc);

  //std::cout<<text->toHtml().toStdString()<<std::endl;

  return text;
}

void QtWidgetView::SetDocParameters( std::string & val )
{
  const std::vector<std::string> appKeyList = m_Application->GetParametersKeys( false );
  const unsigned int nbOfParam = appKeyList.size();

  itk::OStringStream oss;
  oss << "
Parameters
";

  // Mandatory parameters
  oss << "
Mandatory parameters
";
  std::string paramDocs("");

  this->GetDocParameters( paramDocs, true );
  oss<<paramDocs;

  paramDocs  ="";

  // Optional parameters
  oss << "
Optional parameters
";
  oss << "
";

  this->GetDocParameters( paramDocs, false );

  oss<<paramDocs;

  val.append(oss.str());
}

void QtWidgetView::GetDocParameters( std::string & val, bool mandatory)
{
  itk::OStringStream oss;
  const std::vector<std::string> appKeyList = m_Application->GetParametersKeys( false );
  const unsigned int nbOfParam = appKeyList.size();

  std::string paramDocs("");
   for( unsigned int i=0; i<nbOfParam; i++ )
     {
     const std::string key(appKeyList[i]);
     Parameter::Pointer param =  m_Application->GetParameterByKey( key );
     if( param->GetMandatory() == mandatory )
       {
       if( m_Application->GetParameterType(key) !=  ParameterType_Group )
         {
         oss << "" << param->GetName() << ":
";
         oss << param->GetDescription()<< "
";
         oss << "
";
         }
       else
         {
         oss << "=== "<<param->GetName()<<" ("<<param->GetDescription()<<"):
";
         std::string grDoc;
         GetDocParameterGroup( grDoc, key, 1);
         oss<<grDoc;
         }
       }
     }

   if( oss.str() == "" )
     oss << "None";

   val = oss.str();
}

void QtWidgetView::GetDocParameterGroup( std::string & val, const std::string & key, int level )
{
  std::string spaces, equals;
  for(unsigned int i=0; i<level; i++)
    {
    spaces.append("           ");
    equals.append("===");
    }
  equals.append("===");

  Parameter * paramGr  = m_Application->GetParameterByKey( key );
  if( !dynamic_cast<ParameterGroup *>(paramGr) )
    {
    itkGenericExceptionMacro("Invlaid parameter type for key "<<key<<", wait for ParameterGroup...");
    }

  ParameterGroup * group = dynamic_cast<ParameterGroup *>(paramGr);
  const std::vector<std::string> appKeyList = group->GetParametersKeys( false );
  unsigned int nbOfParam = appKeyList.size();
  itk::OStringStream oss;
  for( unsigned int i=0; i<nbOfParam; i++ )
    {
    const std::string fullKey(std::string(key).append(".").append(appKeyList[i]));
    Parameter::Pointer param =  m_Application->GetParameterByKey( fullKey );
    if( m_Application->GetParameterType(fullKey) !=  ParameterType_Group )
      {
      oss << "" << spaces << param->GetName()<< ":
";
      oss  << spaces << param->GetDescription()<<"
";
      oss << "
";
      }
    else
      {
      oss << "" << equals << param->GetName()<<" ("<<param->GetDescription()<<")
";
      std::string grDoc;
      GetDocParameterGroup( grDoc, fullKey, level+1);
      oss<<grDoc;
      }
    }
  val.append(oss.str());
}

void QtWidgetView::CloseSlot()
{
  // Close the widget
  this->close();

  // Emit a signal to close any widget that this gui belonging to
  emit QuitSignal();
}

}
}
<commit_msg>WRG: remove warning.<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperQtWidgetView.h"

#include "otbWrapperQtWidgetParameterGroup.h"
#include "otbWrapperQtWidgetParameterFactory.h"
#include "otbWrapperQtWidgetProgressReport.h"
#include "otbWrapperOutputImageParameter.h"
#include "otbWrapperParameterGroup.h"
#include "otbWrapperQtWidgetSimpleProgressReport.h"

#include "itksys/SystemTools.hxx"

namespace otb
{
namespace Wrapper
{

QtWidgetView::QtWidgetView(Application* app)
{
  m_Model = new QtWidgetModel(app);
  m_Application = app;
}

QtWidgetView::~QtWidgetView()
{

}

void QtWidgetView::CreateGui()
{
  // Create a VBoxLayout with the header, the input widgets, and the footer
  QVBoxLayout *mainLayout = new QVBoxLayout();
  QTabWidget *tab = new QTabWidget();

  tab->addTab(CreateInputWidgets(), "Parameters");
  QTextEdit *log = new QTextEdit();
  connect( m_Model->GetLogOutput(), SIGNAL(NewContentLog(QString)), log, SLOT(append(QString) ) );
  tab->addTab(log, "Logs");
  QtWidgetProgressReport* prog =  new QtWidgetProgressReport(m_Model);
  prog->SetApplication(m_Application);
  tab->addTab(prog, "Progress");
  tab->addTab(CreateDoc(), "Documentation");
  mainLayout->addWidget(tab);

  m_Message = new QLabel("Select parameters");
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), this, SLOT(UpdateMessageAfterApplicationReady(bool)) );
  mainLayout->addWidget(m_Message);

  QtWidgetSimpleProgressReport * progressReport =  new QtWidgetSimpleProgressReport(m_Model);
  progressReport->SetApplication(m_Application);

  QHBoxLayout *footLayout = new QHBoxLayout;
  footLayout->addWidget(progressReport);
  footLayout->addWidget(CreateFooter());
  mainLayout->addLayout(footLayout);

  QGroupBox *mainGroup = new QGroupBox();
  mainGroup->setLayout(mainLayout);

  QVBoxLayout  *finalLayout = new QVBoxLayout();
  finalLayout->addWidget(mainGroup);

  // Make the final layout to the widget
  this->setLayout(finalLayout);
}

void QtWidgetView::UpdateMessageAfterExcuteClicked()
{
  m_Message->setText("Running");
}

void QtWidgetView::UpdateMessageAfterApplicationReady( bool val )
{
  if(val == true)
    m_Message->setText("Ready to run");
  else
    m_Message->setText("Select parameters");
}

QWidget* QtWidgetView::CreateInputWidgets()
{
  QScrollArea *scrollArea = new QScrollArea;
  // Put the main group inside a scroll area
  scrollArea->setWidget(QtWidgetParameterFactory::CreateQtWidget(m_Model->GetApplication()->GetParameterList(), m_Model));
  scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  scrollArea->setWidgetResizable(true);

  return scrollArea;
}

QWidget* QtWidgetView::CreateFooter()
{
  // an HLayout with two buttons : Execute and Quit
  QGroupBox *footerGroup = new QGroupBox;
  QHBoxLayout *footerLayout = new QHBoxLayout;

  footerGroup->setFixedHeight(40);
  footerGroup->setContentsMargins(0, 0, 0, 0);
  footerLayout->setContentsMargins(5, 5, 5, 5);

  m_ExecButton = new QPushButton(footerGroup);
  m_ExecButton->setDefault(true);
  m_ExecButton->setEnabled(false);
  m_ExecButton->setText(QObject::tr("Execute"));
  connect( m_ExecButton, SIGNAL(clicked()), m_Model, SLOT(ExecuteAndWriteOutputSlot() ) );
  connect( m_Model, SIGNAL(SetApplicationReady(bool)), m_ExecButton, SLOT(setEnabled(bool)) );
  connect( m_ExecButton, SIGNAL(clicked()), this, SLOT(UpdateMessageAfterExcuteClicked() ) );

  m_QuitButton = new QPushButton(footerGroup);
  m_QuitButton->setText(QObject::tr("Quit"));
  connect( m_QuitButton, SIGNAL(clicked()), this, SLOT(CloseSlot()) );

  // Put the buttons on the right
  footerLayout->addStretch();
  footerLayout->addWidget(m_ExecButton);
  footerLayout->addWidget(m_QuitButton);

  footerGroup->setLayout(footerLayout);

  return footerGroup;
}

QWidget* QtWidgetView::CreateDoc()
{
  QTextEdit *text = new QTextEdit;
  text->setReadOnly(true);

  QTextDocument * doc = new QTextDocument();
  itk::OStringStream oss;
  oss << "
" << m_Application->GetDocName() << "
";
  oss << "
Brief Description
";
  oss << "" << m_Application->GetDescription() << "";
  oss << "
Tags
";
  oss << "";
  if (m_Application->GetDocTags().size() > 0)
    {
    for (unsigned int i = 0; i < m_Application->GetDocTags().size() - 1; i++)
      {
      oss << m_Application->GetDocTags()[i] << ", ";
   ;
      }
    oss << m_Application->GetDocTags()[m_Application->GetDocTags().size() - 1];
    }
  oss << "";

  oss << "
Long Description
";
  oss << "" << m_Application->GetDocLongDescription() << "";

  std::string val;
  this->SetDocParameters(val);
  oss << val;

  oss << "
Limitations
";
  oss << "" << m_Application->GetDocLimitations() << "";
  oss << "
Authors
";
  oss << "" << m_Application->GetDocAuthors() << "";
  oss << "
See also
";
  oss << "" << m_Application->GetDocSeeAlso() << "";
  oss << "
Command line example
";
  oss << "" << m_Application->GetDocCLExample() << "";

  doc->setHtml(oss.str().c_str());

  text->setDocument(doc);

  //std::cout<<text->toHtml().toStdString()<<std::endl;

  return text;
}

void QtWidgetView::SetDocParameters( std::string & val )
{
  const std::vector<std::string> appKeyList = m_Application->GetParametersKeys( false );
  const unsigned int nbOfParam = appKeyList.size();

  itk::OStringStream oss;
  oss << "
Parameters
";

  // Mandatory parameters
  oss << "
Mandatory parameters
";
  std::string paramDocs("");

  this->GetDocParameters( paramDocs, true );
  oss<<paramDocs;

  paramDocs  ="";

  // Optional parameters
  oss << "
Optional parameters
";
  oss << "
";

  this->GetDocParameters( paramDocs, false );

  oss<<paramDocs;

  val.append(oss.str());
}

void QtWidgetView::GetDocParameters( std::string & val, bool mandatory)
{
  itk::OStringStream oss;
  const std::vector<std::string> appKeyList = m_Application->GetParametersKeys( false );
  const unsigned int nbOfParam = appKeyList.size();

  std::string paramDocs("");
   for( unsigned int i=0; i<nbOfParam; i++ )
     {
     const std::string key(appKeyList[i]);
     Parameter::Pointer param =  m_Application->GetParameterByKey( key );
     if( param->GetMandatory() == mandatory )
       {
       if( m_Application->GetParameterType(key) !=  ParameterType_Group )
         {
         oss << "" << param->GetName() << ":
";
         oss << param->GetDescription()<< "
";
         oss << "
";
         }
       else
         {
         oss << "=== "<<param->GetName()<<" ("<<param->GetDescription()<<"):
";
         std::string grDoc;
         GetDocParameterGroup( grDoc, key, 1);
         oss<<grDoc;
         }
       }
     }

   if( oss.str() == "" )
     oss << "None";

   val = oss.str();
}

void QtWidgetView::GetDocParameterGroup( std::string & val, const std::string & key, int level )
{
  std::string spaces, equals;
  for(int i=0; i<level; i++)
    {
    spaces.append("           ");
    equals.append("===");
    }
  equals.append("===");

  Parameter * paramGr  = m_Application->GetParameterByKey( key );
  if( !dynamic_cast<ParameterGroup *>(paramGr) )
    {
    itkGenericExceptionMacro("Invlaid parameter type for key "<<key<<", wait for ParameterGroup...");
    }

  ParameterGroup * group = dynamic_cast<ParameterGroup *>(paramGr);
  const std::vector<std::string> appKeyList = group->GetParametersKeys( false );
  unsigned int nbOfParam = appKeyList.size();
  itk::OStringStream oss;
  for( unsigned int i=0; i<nbOfParam; i++ )
    {
    const std::string fullKey(std::string(key).append(".").append(appKeyList[i]));
    Parameter::Pointer param =  m_Application->GetParameterByKey( fullKey );
    if( m_Application->GetParameterType(fullKey) !=  ParameterType_Group )
      {
      oss << "" << spaces << param->GetName()<< ":
";
      oss  << spaces << param->GetDescription()<<"
";
      oss << "
";
      }
    else
      {
      oss << "" << equals << param->GetName()<<" ("<<param->GetDescription()<<")
";
      std::string grDoc;
      GetDocParameterGroup( grDoc, fullKey, level+1);
      oss<<grDoc;
      }
    }
  val.append(oss.str());
}

void QtWidgetView::CloseSlot()
{
  // Close the widget
  this->close();

  // Emit a signal to close any widget that this gui belonging to
  emit QuitSignal();
}

}
}
<|endoftext|>