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

#include "config.h"

#include <map>
#include <functional>

#include "ApplicationSamplerImp.hpp"
#include "ApplicationRecordLog.hpp"
#include "ApplicationStatus.hpp"
#include "ProfileSampler.hpp"
#include "ProfileIOSample.hpp"
#include "EpochRuntimeRegulator.hpp"
#include "Exception.hpp"
#include "RecordFilter.hpp"
#include "Environment.hpp"
#include "ValidateRecord.hpp"
#include "SharedMemory.hpp"
#include "PlatformTopo.hpp"
#include "record.hpp"
#include "geopm_debug.hpp"
#include "geopm.h"
#include "geopm_hash.h"

namespace geopm
{
    ApplicationSampler &ApplicationSampler::application_sampler(void)
    {
        static ApplicationSamplerImp instance;
        return instance;
    }

    std::set<uint64_t> ApplicationSampler::region_hash_network(void)
    {
        static std::set <uint64_t> result = region_hash_network_once();
        return result;
    }

    std::set<uint64_t> ApplicationSampler::region_hash_network_once(void)
    {
        std::set<uint64_t> ret;
        std::set<std::string> network_funcs {"MPI_Allgather",
                                             "MPI_Allgatherv",
                                             "MPI_Allreduce",
                                             "MPI_Alltoall",
                                             "MPI_Alltoallv",
                                             "MPI_Alltoallw",
                                             "MPI_Barrier",
                                             "MPI_Bcast"
                                             "MPI_Bsend",
                                             "MPI_Bsend_init",
                                             "MPI_Gather",
                                             "MPI_Gatherv",
                                             "MPI_Neighbor_allgather",
                                             "MPI_Neighbor_allgatherv",
                                             "MPI_Neighbor_alltoall",
                                             "MPI_Neighbor_alltoallv",
                                             "MPI_Neighbor_alltoallw",
                                             "MPI_Reduce",
                                             "MPI_Reduce_scatter",
                                             "MPI_Reduce_scatter_block",
                                             "MPI_Rsend"
                                             "MPI_Rsend_init",
                                             "MPI_Scan",
                                             "MPI_Scatter",
                                             "MPI_Scatterv",
                                             "MPI_Waitall",
                                             "MPI_Waitany",
                                             "MPI_Wait",
                                             "MPI_Waitsome",
                                             "MPI_Exscan",
                                             "MPI_Recv",
                                             "MPI_Send",
                                             "MPI_Sendrecv",
                                             "MPI_Sendrecv_replace",
                                             "MPI_Ssend"};
        for (auto const &func_name : network_funcs) {
            ret.insert(geopm_crc32_str(func_name.c_str()));
        }
        return ret;
    }

    ApplicationSamplerImp::ApplicationSamplerImp()
        : ApplicationSamplerImp(nullptr,
                                platform_topo().num_domain(GEOPM_DOMAIN_CPU),
                                std::map<int, m_process_s> {},
                                environment().do_record_filter(),
                                environment().record_filter())
    {

    }

    const std::map<uint64_t, double> ApplicationSamplerImp::m_hint_time_init = {
        {GEOPM_REGION_HINT_UNKNOWN, 0.0},
        {GEOPM_REGION_HINT_COMPUTE, 0.0},
        {GEOPM_REGION_HINT_MEMORY, 0.0},
        {GEOPM_REGION_HINT_NETWORK, 0.0},
        {GEOPM_REGION_HINT_IO, 0.0},
        {GEOPM_REGION_HINT_SERIAL, 0.0},
        {GEOPM_REGION_HINT_PARALLEL, 0.0},
        {GEOPM_REGION_HINT_IGNORE, 0.0},
    };

    ApplicationSamplerImp::ApplicationSamplerImp(std::shared_ptr<ApplicationStatus> status,
                                                 int num_cpu,
                                                 const std::map<int, m_process_s> &process_map,
                                                 bool is_filtered,
                                                 const std::string &filter_name)
        : m_time_zero(geopm::time_zero())
        , m_status(status)
        , m_num_cpu(num_cpu)
        , m_process_map(process_map)
        , m_is_filtered(is_filtered)
        , m_filter_name(filter_name)
        , m_hint_time(m_num_cpu, m_hint_time_init)
        , m_update_time({{0, 0}})
        , m_is_first_update(true)
    {

    }

    void ApplicationSamplerImp::time_zero(const geopm_time_s &start_time)
    {
        m_time_zero = start_time;
    }

    void ApplicationSamplerImp::update(const geopm_time_s &curr_time)
    {
        m_status->update_cache();
        if (!m_is_first_update) {
            double time_delta = geopm_time_diff(&m_update_time, &curr_time);
            for (int cpu_idx = 0; cpu_idx != m_num_cpu; ++cpu_idx) {
                uint64_t hint = m_status->get_hint(cpu_idx);
                m_hint_time[cpu_idx].at(hint) += time_delta;
            }
        }
        m_is_first_update = false;
        m_update_time = curr_time;
        // Dump the record log from each process, filter the results,
        // and reindex the short region event signals.

        // Clear the buffers that we will be building.
        m_record_buffer.clear();
        m_short_region_buffer.clear();
        // Iterate over the record log for each process
        for (auto &proc_map_it : m_process_map) {
            // Record the location in the record buffer where this
            // process' data begins for updating the short region
            // event signals.
            size_t record_offset = m_record_buffer.size();
            // Get data from the record log
            auto &proc_it = proc_map_it.second;
            proc_it.record_log->dump(proc_it.records, proc_it.short_regions);
            if (m_is_filtered) {
                // Filter and check the records and push them onto
                // m_record_buffer
                for (const auto &record_it : proc_it.records) {
                    for (auto &filtered_it : proc_it.filter->filter(record_it)) {
                        proc_it.valid.check(filtered_it);
                        m_record_buffer.push_back(filtered_it);
                    }
                }
            }
            else {
                // Check the records and push them onto m_record_buffer
                for (const auto &record : proc_it.records) {
                    proc_it.valid.check(record);
                }
                m_record_buffer.insert(m_record_buffer.end(),
                                       proc_it.records.begin(),
                                       proc_it.records.end());
            }
            // Update the "signal" field for all of the short region
            // events to have the right offset.
            size_t short_region_remain = proc_it.short_regions.size();
            for (auto record_it = m_record_buffer.begin() + record_offset;
                 short_region_remain > 0 &&
                 record_it != m_record_buffer.end();
                 ++record_it) {
                if (record_it->event == EVENT_SHORT_REGION) {
                    record_it->signal += m_short_region_buffer.size();
                    --short_region_remain;
                }
            }
            m_short_region_buffer.insert(m_short_region_buffer.end(),
                                         proc_it.short_regions.begin(),
                                         proc_it.short_regions.end());
        }
    }

    std::vector<record_s> ApplicationSamplerImp::get_records(void) const
    {
        return m_record_buffer;
    }

    short_region_s ApplicationSamplerImp::get_short_region(uint64_t event_signal) const
    {
        if (event_signal >= m_short_region_buffer.size()) {
            throw Exception("ApplicationSampler::get_short_region(), event_signal does not match any short region handle",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return m_short_region_buffer[event_signal];
    }

    std::map<uint64_t, std::string> ApplicationSamplerImp::get_name_map(uint64_t name_key) const
    {
        throw Exception("ApplicationSamplerImp::" + std::string(__func__) + "() is not yet implemented",
                        GEOPM_ERROR_NOT_IMPLEMENTED, __FILE__, __LINE__);
        return {};
    }

    uint64_t ApplicationSamplerImp::cpu_hint(int cpu_idx) const
    {
        return m_status->get_hint(cpu_idx);
    }

    double ApplicationSamplerImp::cpu_hint_time(int cpu_idx, uint64_t hint) const
    {
        if (cpu_idx < 0 || cpu_idx >= m_num_cpu) {
            throw Exception("ApplicationSampler::" + std::string(__func__) +
                            "(): cpu_idx is out of range: " + std::to_string(cpu_idx),
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        auto &hint_map = m_hint_time[cpu_idx];
        auto it = hint_map.find(hint);
        if (it == hint_map.end()) {
            throw Exception("ApplicationSampler::" + std::string(__func__) +
                            "(): hint is invalid: " + std::to_string(hint),
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }

    double ApplicationSamplerImp::cpu_progress(int cpu_idx) const
    {
        return m_status->get_progress_cpu(cpu_idx);
    }

    std::vector<int> ApplicationSamplerImp::per_cpu_process(void) const
    {
        std::vector<int> result(m_num_cpu);
        for (int cpu_idx = 0; cpu_idx != m_num_cpu; ++cpu_idx) {
            result[cpu_idx] = m_status->get_process(cpu_idx);
        }
        return result;
    }

    void ApplicationSamplerImp::connect(const std::string &shm_key)
    {
        if (!m_status) {
            std::string shmem_name = shm_key + "-status";
            std::shared_ptr<SharedMemory> status_shmem =
                SharedMemory::make_unique_owner(shmem_name,
                                                ApplicationStatus::buffer_size(m_num_cpu));
            m_status = ApplicationStatus::make_unique(m_num_cpu, status_shmem);
            GEOPM_DEBUG_ASSERT(m_process_map.empty(),
                               "m_process_map is not empty, but we are connecting");
            // Convert per-cpu process to a set of the unique process id's
            std::set<int> proc_set;
            for (const auto &proc_it : per_cpu_process()) {
                proc_set.insert(proc_it);
            }
            // For each unique process id create a record log and
            // insert it into map indexed by process id
            for (const auto &proc_it : proc_set) {
                std::string shmem_name = shm_key + "-record-log-" + std::to_string(proc_it);
                std::shared_ptr<SharedMemory> record_log_shmem =
                    SharedMemory::make_unique_owner(shmem_name,
                                                    ApplicationRecordLog::buffer_size());
                auto emplace_ret = m_process_map.emplace(proc_it, m_process_s {});
                auto &process = emplace_ret.first->second;
                if (m_is_filtered) {
                    process.filter = RecordFilter::make_unique(m_filter_name);
                }
                process.record_log = ApplicationRecordLog::make_unique(record_log_shmem);
                process.records.reserve(ApplicationRecordLog::max_record());
                process.short_regions.reserve(ApplicationRecordLog::max_region());
            }
        }
    }

    void ApplicationSamplerImp::set_sampler(std::shared_ptr<ProfileSampler> sampler)
    {
        m_sampler = sampler;
    }

    std::shared_ptr<ProfileSampler> ApplicationSamplerImp::get_sampler(void)
    {
        return m_sampler;
    }

    void ApplicationSamplerImp::set_regulator(std::shared_ptr<EpochRuntimeRegulator> regulator)
    {
        m_regulator = regulator;
    }

    std::shared_ptr<EpochRuntimeRegulator> ApplicationSamplerImp::get_regulator(void)
    {
        return m_regulator;
    }

    void ApplicationSamplerImp::set_io_sample(std::shared_ptr<ProfileIOSample> io_sample)
    {
        m_io_sample = io_sample;
    }

    std::shared_ptr<ProfileIOSample> ApplicationSamplerImp::get_io_sample(void)
    {
        return m_io_sample;
    }
}
<commit_msg>Add exceptions to AppSampler for using status before connect()<commit_after>/*
 * Copyright (c) 2015, 2016, 2017, 2018, 2019, 2020, Intel Corporation
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in
 *       the documentation and/or other materials provided with the
 *       distribution.
 *
 *     * Neither the name of Intel Corporation nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY LOG OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <map>
#include <functional>

#include "ApplicationSamplerImp.hpp"
#include "ApplicationRecordLog.hpp"
#include "ApplicationStatus.hpp"
#include "ProfileSampler.hpp"
#include "ProfileIOSample.hpp"
#include "EpochRuntimeRegulator.hpp"
#include "Exception.hpp"
#include "RecordFilter.hpp"
#include "Environment.hpp"
#include "ValidateRecord.hpp"
#include "SharedMemory.hpp"
#include "PlatformTopo.hpp"
#include "record.hpp"
#include "geopm_debug.hpp"
#include "geopm.h"
#include "geopm_hash.h"

namespace geopm
{
    ApplicationSampler &ApplicationSampler::application_sampler(void)
    {
        static ApplicationSamplerImp instance;
        return instance;
    }

    std::set<uint64_t> ApplicationSampler::region_hash_network(void)
    {
        static std::set <uint64_t> result = region_hash_network_once();
        return result;
    }

    std::set<uint64_t> ApplicationSampler::region_hash_network_once(void)
    {
        std::set<uint64_t> ret;
        std::set<std::string> network_funcs {"MPI_Allgather",
                                             "MPI_Allgatherv",
                                             "MPI_Allreduce",
                                             "MPI_Alltoall",
                                             "MPI_Alltoallv",
                                             "MPI_Alltoallw",
                                             "MPI_Barrier",
                                             "MPI_Bcast"
                                             "MPI_Bsend",
                                             "MPI_Bsend_init",
                                             "MPI_Gather",
                                             "MPI_Gatherv",
                                             "MPI_Neighbor_allgather",
                                             "MPI_Neighbor_allgatherv",
                                             "MPI_Neighbor_alltoall",
                                             "MPI_Neighbor_alltoallv",
                                             "MPI_Neighbor_alltoallw",
                                             "MPI_Reduce",
                                             "MPI_Reduce_scatter",
                                             "MPI_Reduce_scatter_block",
                                             "MPI_Rsend"
                                             "MPI_Rsend_init",
                                             "MPI_Scan",
                                             "MPI_Scatter",
                                             "MPI_Scatterv",
                                             "MPI_Waitall",
                                             "MPI_Waitany",
                                             "MPI_Wait",
                                             "MPI_Waitsome",
                                             "MPI_Exscan",
                                             "MPI_Recv",
                                             "MPI_Send",
                                             "MPI_Sendrecv",
                                             "MPI_Sendrecv_replace",
                                             "MPI_Ssend"};
        for (auto const &func_name : network_funcs) {
            ret.insert(geopm_crc32_str(func_name.c_str()));
        }
        return ret;
    }

    ApplicationSamplerImp::ApplicationSamplerImp()
        : ApplicationSamplerImp(nullptr,
                                platform_topo().num_domain(GEOPM_DOMAIN_CPU),
                                std::map<int, m_process_s> {},
                                environment().do_record_filter(),
                                environment().record_filter())
    {

    }

    const std::map<uint64_t, double> ApplicationSamplerImp::m_hint_time_init = {
        {GEOPM_REGION_HINT_UNKNOWN, 0.0},
        {GEOPM_REGION_HINT_COMPUTE, 0.0},
        {GEOPM_REGION_HINT_MEMORY, 0.0},
        {GEOPM_REGION_HINT_NETWORK, 0.0},
        {GEOPM_REGION_HINT_IO, 0.0},
        {GEOPM_REGION_HINT_SERIAL, 0.0},
        {GEOPM_REGION_HINT_PARALLEL, 0.0},
        {GEOPM_REGION_HINT_IGNORE, 0.0},
    };

    ApplicationSamplerImp::ApplicationSamplerImp(std::shared_ptr<ApplicationStatus> status,
                                                 int num_cpu,
                                                 const std::map<int, m_process_s> &process_map,
                                                 bool is_filtered,
                                                 const std::string &filter_name)
        : m_time_zero(geopm::time_zero())
        , m_status(status)
        , m_num_cpu(num_cpu)
        , m_process_map(process_map)
        , m_is_filtered(is_filtered)
        , m_filter_name(filter_name)
        , m_hint_time(m_num_cpu, m_hint_time_init)
        , m_update_time({{0, 0}})
        , m_is_first_update(true)
    {

    }

    void ApplicationSamplerImp::time_zero(const geopm_time_s &start_time)
    {
        m_time_zero = start_time;
    }

    void ApplicationSamplerImp::update(const geopm_time_s &curr_time)
    {
        if (!m_status) {
            throw Exception("ApplicationSamplerImp::" + std::string(__func__) + "(): cannot read process info before connect().",
                            GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }
        m_status->update_cache();
        if (!m_is_first_update) {
            double time_delta = geopm_time_diff(&m_update_time, &curr_time);
            for (int cpu_idx = 0; cpu_idx != m_num_cpu; ++cpu_idx) {
                uint64_t hint = m_status->get_hint(cpu_idx);
                m_hint_time[cpu_idx].at(hint) += time_delta;
            }
        }
        m_is_first_update = false;
        m_update_time = curr_time;
        // Dump the record log from each process, filter the results,
        // and reindex the short region event signals.

        // Clear the buffers that we will be building.
        m_record_buffer.clear();
        m_short_region_buffer.clear();
        // Iterate over the record log for each process
        for (auto &proc_map_it : m_process_map) {
            // Record the location in the record buffer where this
            // process' data begins for updating the short region
            // event signals.
            size_t record_offset = m_record_buffer.size();
            // Get data from the record log
            auto &proc_it = proc_map_it.second;
            proc_it.record_log->dump(proc_it.records, proc_it.short_regions);
            if (m_is_filtered) {
                // Filter and check the records and push them onto
                // m_record_buffer
                for (const auto &record_it : proc_it.records) {
                    for (auto &filtered_it : proc_it.filter->filter(record_it)) {
                        proc_it.valid.check(filtered_it);
                        m_record_buffer.push_back(filtered_it);
                    }
                }
            }
            else {
                // Check the records and push them onto m_record_buffer
                for (const auto &record : proc_it.records) {
                    proc_it.valid.check(record);
                }
                m_record_buffer.insert(m_record_buffer.end(),
                                       proc_it.records.begin(),
                                       proc_it.records.end());
            }
            // Update the "signal" field for all of the short region
            // events to have the right offset.
            size_t short_region_remain = proc_it.short_regions.size();
            for (auto record_it = m_record_buffer.begin() + record_offset;
                 short_region_remain > 0 &&
                 record_it != m_record_buffer.end();
                 ++record_it) {
                if (record_it->event == EVENT_SHORT_REGION) {
                    record_it->signal += m_short_region_buffer.size();
                    --short_region_remain;
                }
            }
            m_short_region_buffer.insert(m_short_region_buffer.end(),
                                         proc_it.short_regions.begin(),
                                         proc_it.short_regions.end());
        }
    }

    std::vector<record_s> ApplicationSamplerImp::get_records(void) const
    {
        return m_record_buffer;
    }

    short_region_s ApplicationSamplerImp::get_short_region(uint64_t event_signal) const
    {
        if (event_signal >= m_short_region_buffer.size()) {
            throw Exception("ApplicationSampler::get_short_region(), event_signal does not match any short region handle",
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return m_short_region_buffer[event_signal];
    }

    std::map<uint64_t, std::string> ApplicationSamplerImp::get_name_map(uint64_t name_key) const
    {
        throw Exception("ApplicationSamplerImp::" + std::string(__func__) + "() is not yet implemented",
                        GEOPM_ERROR_NOT_IMPLEMENTED, __FILE__, __LINE__);
        return {};
    }

    uint64_t ApplicationSamplerImp::cpu_hint(int cpu_idx) const
    {
        if (!m_status) {
            throw Exception("ApplicationSamplerImp::" + std::string(__func__) + "(): cannot read process info before connect().",
                            GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }
        return m_status->get_hint(cpu_idx);
    }

    double ApplicationSamplerImp::cpu_hint_time(int cpu_idx, uint64_t hint) const
    {
        if (cpu_idx < 0 || cpu_idx >= m_num_cpu) {
            throw Exception("ApplicationSampler::" + std::string(__func__) +
                            "(): cpu_idx is out of range: " + std::to_string(cpu_idx),
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        auto &hint_map = m_hint_time[cpu_idx];
        auto it = hint_map.find(hint);
        if (it == hint_map.end()) {
            throw Exception("ApplicationSampler::" + std::string(__func__) +
                            "(): hint is invalid: " + std::to_string(hint),
                            GEOPM_ERROR_INVALID, __FILE__, __LINE__);
        }
        return it->second;
    }

    double ApplicationSamplerImp::cpu_progress(int cpu_idx) const
    {
        if (!m_status) {
            throw Exception("ApplicationSamplerImp::" + std::string(__func__) + "(): cannot read process info before connect().",
                            GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }
        return m_status->get_progress_cpu(cpu_idx);
    }

    std::vector<int> ApplicationSamplerImp::per_cpu_process(void) const
    {
        if (!m_status) {
            throw Exception("ApplicationSamplerImp::" + std::string(__func__) + "(): cannot read process info before connect().",
                            GEOPM_ERROR_RUNTIME, __FILE__, __LINE__);
        }
        std::vector<int> result(m_num_cpu);
        for (int cpu_idx = 0; cpu_idx != m_num_cpu; ++cpu_idx) {
            result[cpu_idx] = m_status->get_process(cpu_idx);
        }
        return result;
    }

    void ApplicationSamplerImp::connect(const std::string &shm_key)
    {
        if (!m_status) {
            std::string shmem_name = shm_key + "-status";
            std::shared_ptr<SharedMemory> status_shmem =
                SharedMemory::make_unique_owner(shmem_name,
                                                ApplicationStatus::buffer_size(m_num_cpu));
            m_status = ApplicationStatus::make_unique(m_num_cpu, status_shmem);
            GEOPM_DEBUG_ASSERT(m_process_map.empty(),
                               "m_process_map is not empty, but we are connecting");
            // Convert per-cpu process to a set of the unique process id's
            std::set<int> proc_set;
            for (const auto &proc_it : per_cpu_process()) {
                proc_set.insert(proc_it);
            }
            // For each unique process id create a record log and
            // insert it into map indexed by process id
            for (const auto &proc_it : proc_set) {
                std::string shmem_name = shm_key + "-record-log-" + std::to_string(proc_it);
                std::shared_ptr<SharedMemory> record_log_shmem =
                    SharedMemory::make_unique_owner(shmem_name,
                                                    ApplicationRecordLog::buffer_size());
                auto emplace_ret = m_process_map.emplace(proc_it, m_process_s {});
                auto &process = emplace_ret.first->second;
                if (m_is_filtered) {
                    process.filter = RecordFilter::make_unique(m_filter_name);
                }
                process.record_log = ApplicationRecordLog::make_unique(record_log_shmem);
                process.records.reserve(ApplicationRecordLog::max_record());
                process.short_regions.reserve(ApplicationRecordLog::max_region());
            }
        }
    }

    void ApplicationSamplerImp::set_sampler(std::shared_ptr<ProfileSampler> sampler)
    {
        m_sampler = sampler;
    }

    std::shared_ptr<ProfileSampler> ApplicationSamplerImp::get_sampler(void)
    {
        return m_sampler;
    }

    void ApplicationSamplerImp::set_regulator(std::shared_ptr<EpochRuntimeRegulator> regulator)
    {
        m_regulator = regulator;
    }

    std::shared_ptr<EpochRuntimeRegulator> ApplicationSamplerImp::get_regulator(void)
    {
        return m_regulator;
    }

    void ApplicationSamplerImp::set_io_sample(std::shared_ptr<ProfileIOSample> io_sample)
    {
        m_io_sample = io_sample;
    }

    std::shared_ptr<ProfileIOSample> ApplicationSamplerImp::get_io_sample(void)
    {
        return m_io_sample;
    }
}
<|endoftext|>


<commit_before>/*
 * METISParser.cpp
 *
 *  Created on: 27.11.2012
 *      Author: cls
 */

#include "METISParser.h"

namespace EnsembleClustering {

/**
 * Extract a vector of indices from a line in the file.
 *
 * @param[in]	line		line from input file containing node indices
 *
 * @param[out]	indices		node indices extracted from line
 */
static std::vector<node> parseLine(std::string line) {

	std::stringstream stream(line);
	std::string token;
	char delim = ' ';
	std::vector<node> adjacencies;

	// split string and push adjacent nodes
	while (std::getline(stream, token, delim)) {
		if (token.size() != 0) {
			node v = atoi(token.c_str());
			adjacencies.push_back(v);
		}
	}

	return adjacencies;
}

static inline std::vector<node> parseLineDIY(std::string line) {
	// TODO: is this faster?

	std::string token;
	char delim = ' ';
	std::vector<node> adjacencies;

	for (char& c : line) {
		if (c == delim) {
			node v = atoi(token.c_str());
			adjacencies.push_back(v);
			token.clear();
		} else if (c == '\n') {
			break;
		} else {
			token.push_back(c);
		}
	}

	return adjacencies;
}

METISParser::METISParser(std::string path) : graphFile(path) {
	if (!(this->graphFile)) {
		ERROR("invalid graph file: " << path);
		throw std::runtime_error("invalid graph file");
	}
}

METISParser::~METISParser() {
	// TODO Auto-generated destructor stub
}

std::pair<int, int> METISParser::getHeader() {

	// handle header line
	int n;  // number of nodes
	int m;	// number of edges

	std::string line = "";
	assert (this->graphFile);
	if (std::getline(this->graphFile, line)) {
		std::vector<node> tokens = parseLine(line);
		n = tokens[0];
		m = tokens[1];

		return std::make_pair(n, m);
	} else {
		ERROR("getline not successful");
		throw std::runtime_error("getting METIS file header failed");
		return std::make_pair(0,0);
	}

}

bool METISParser::hasNext() {
	// if graph file has lines left, return true
	return this->graphFile.good();
}

std::vector<node> METISParser::getNext() {

	std::string line;
	bool comment = false;
	do {
		comment = false;
		std::getline(this->graphFile, line);
		// check for comment line starting with '%'
		if (line[0] == '%') {
			comment = true;
		} else {
			return parseLine(line);
		}

	} while (comment);

	throw std::runtime_error("bad METIS file structure");
	std::vector<node> fail;
	return fail;
}

} /* namespace EnsembleClustering */
<commit_msg>fixed: METISParser can read files beginning with comment lines<commit_after>/*
 * METISParser.cpp
 *
 *  Created on: 27.11.2012
 *      Author: cls
 */

#include "METISParser.h"

namespace EnsembleClustering {

/**
 * Extract a vector of indices from a line in the file.
 *
 * @param[in]	line		line from input file containing node indices
 *
 * @param[out]	indices		node indices extracted from line
 */
static std::vector<node> parseLine(std::string line) {

	std::stringstream stream(line);
	std::string token;
	char delim = ' ';
	std::vector<node> adjacencies;

	// split string and push adjacent nodes
	while (std::getline(stream, token, delim)) {
		if (token.size() != 0) {
			node v = atoi(token.c_str());
			adjacencies.push_back(v);
		}
	}

	return adjacencies;
}

static inline std::vector<node> parseLineDIY(std::string line) {
	// TODO: is this faster?

	std::string token;
	char delim = ' ';
	std::vector<node> adjacencies;

	for (char& c : line) {
		if (c == delim) {
			node v = atoi(token.c_str());
			adjacencies.push_back(v);
			token.clear();
		} else if (c == '\n') {
			break;
		} else {
			token.push_back(c);
		}
	}

	return adjacencies;
}

METISParser::METISParser(std::string path) : graphFile(path) {
	if (!(this->graphFile)) {
		ERROR("invalid graph file: " << path);
		throw std::runtime_error("invalid graph file");
	}
}

METISParser::~METISParser() {
	// TODO Auto-generated destructor stub
}

std::pair<int, int> METISParser::getHeader() {

	// handle header line
	int n;  // number of nodes
	int m;	// number of edges

	std::string line = "";
	assert (this->graphFile);

	if (std::getline(this->graphFile, line)) {
		while (line[0] == '%') {
			std::getline(this->graphFile, line);
		}

		std::vector<node> tokens = parseLine(line);
		n = tokens[0];
		m = tokens[1];

		return std::make_pair(n, m);
	} else {
		ERROR("getline not successful");
		throw std::runtime_error("getting METIS file header failed");
		return std::make_pair(0,0);
	}

}

bool METISParser::hasNext() {
	// if graph file has lines left, return true
	return this->graphFile.good();
}

std::vector<node> METISParser::getNext() {

	std::string line;
	bool comment = false;
	do {
		comment = false;
		std::getline(this->graphFile, line);
		// check for comment line starting with '%'
		if (line[0] == '%') {
			comment = true;
		} else {
			return parseLine(line);
		}

	} while (comment);

	throw std::runtime_error("bad METIS file structure");
	std::vector<node> fail;
	return fail;
}

} /* namespace EnsembleClustering */
<|endoftext|>


<commit_before>//
// echo_server.cpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2015 Andrew Hundt
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include "robone/AzmqFlatbuffer.hpp"

/// Send messages between a client and server asynchronously.
///
/// @see overview of zmq socket types https://sachabarbs.wordpress.com/2014/08/21/zeromq-2-the-socket-types-2/
/// @see bounce is based on https://github.com/zeromq/azmq/blob/master/test/socket/main.cpp
/// @see flatbuffers https://google.github.io/flatbuffers/md__cpp_usage.html
void bounce(std::shared_ptr<AzmqFlatbuffer> sendP, std::shared_ptr<AzmqFlatbuffer> receiveP, bool shouldReceive = true) {

	receiveP->start_async_receive_buffers();

	for (int x = 0; x<1000; ++x) {

		/////////////////////////////////////////
		// Client sends to server asynchronously!
		{
			auto fbbP = sendP->GetUnusedBufferBuilder();

			robone::Vector3d rv(x,0,0);
			auto controlPoint = robone::CreateVrepControlPoint(*fbbP,&rv);
			robone::FinishVrepControlPointBuffer(*fbbP, controlPoint);
			sendP->async_send_flatbuffer(fbbP);
		}

		//////////////////////////////////////////////
		// Server receives from client asynchronously!
		while (shouldReceive && !receiveP->receive_buffers_empty()) {
			auto rbP = receiveP->get_back_receive_buffer_with_data();
			auto rbPstart = &(rbP->begin()[0]);
			auto verifier = flatbuffers::Verifier(rbPstart,rbP->size());
			auto bufOK = robone::VerifyVrepControlPointBuffer(verifier);

			if(bufOK){
				const robone::VrepControlPoint* VCPin = robone::GetVrepControlPoint(rbPstart);
				std::cout << "received: " << VCPin->position()->x() << "\n";
			} else {
				std::cout << "Failed verification. bufOk: " <<bufOK << "\n";
			}

		}

		std::this_thread::sleep_for( std::chrono::milliseconds(1) );
    }
}

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

    std::string localhost("127.0.0.1");
    std::string localport("9998");
    std::string remotehost("127.0.0.1");
    std::string remoteport("9998");

    std::cout << "argc: " << argc << "\n";
	  /// @todo add default localhost/localport
    if (argc != 5 && argc != 1 && argc != 3)
    {
      std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
      return 1;
    }

    bool shouldReceive = false;

    if(argc == 3){
      remotehost = std::string(argv[1]);
      remoteport = std::string(argv[2]);
      shouldReceive = false;
    }

    if(argc == 5){
      localhost = std::string(argv[1]);
      localport = std::string(argv[2]);
      remotehost = std::string(argv[3]);
      remoteport = std::string(argv[4]);
      shouldReceive = true;
    }

    std::cout << "using: "  << argv[0] << " ";
    if(shouldReceive) std::cout <<  localhost << " " << localport << " ";
    std::cout <<  remotehost << " " << remoteport << "\n";
    boost::asio::io_service io_service;

    // Register signal handlers so that the daemon may be shut down when a signal is received.
    boost::asio::signal_set signals(io_service, SIGINT, SIGTERM);
    signals.async_wait( std::bind(&boost::asio::io_service::stop, &io_service));
#if 0
	std::shared_ptr<AzmqFlatbuffer> sendP;
	{
		boost::system::error_code ec;
		azmq::socket socket(io_service, ZMQ_DEALER);
		socket.connect("tcp://"+ remotehost + ":" + remoteport);
		sendP = std::make_shared<AzmqFlatbuffer>(std::move(socket));
	}
	std::shared_ptr<AzmqFlatbuffer> receiveP;
	{
		boost::system::error_code ec;
		azmq::socket socket(io_service, ZMQ_DEALER);
		if (shouldReceive) socket.bind("tcp://" + localhost + ":" + localport);
		receiveP = std::make_shared<AzmqFlatbuffer>(std::move(socket));
	}

	// Will run until signal is received, using separate objects for send and receive
    std::thread t(bounce,sendP,receiveP);
#else

	std::shared_ptr<AzmqFlatbuffer> receiveP;
	{
		boost::system::error_code ec;
		azmq::socket socket(io_service, ZMQ_DEALER);
		if(shouldReceive) socket.bind("tcp://" + localhost + ":" + localport);
		socket.connect("tcp://"+ remotehost + ":" + remoteport);
		receiveP = std::make_shared<AzmqFlatbuffer>(std::move(socket));
	}

	// Will run until signal is received, using one object for both send and receive
    std::thread t(bounce,receiveP,receiveP,shouldReceive);
#endif

	io_service.run();

//  }
//  catch (std::exception& e)
//  {
//    std::cerr << "Exception: " << e.what() << "\n";
//  }

  return 0;
}<commit_msg>#51 fixed send to self bug in AzmqFlatbufferTest<commit_after>//
// echo_server.cpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2014 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// Copyright (c) 2015 Andrew Hundt
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//

#include "robone/AzmqFlatbuffer.hpp"

/// Send messages between a client and server asynchronously.
///
/// @see overview of zmq socket types https://sachabarbs.wordpress.com/2014/08/21/zeromq-2-the-socket-types-2/
/// @see bounce is based on https://github.com/zeromq/azmq/blob/master/test/socket/main.cpp
/// @see flatbuffers https://google.github.io/flatbuffers/md__cpp_usage.html
void bounce(std::shared_ptr<AzmqFlatbuffer> sendP, std::shared_ptr<AzmqFlatbuffer> receiveP, bool shouldReceive = true) {

	receiveP->start_async_receive_buffers();

	for (int x = 0; x<1000; ++x) {

		/////////////////////////////////////////
		// Client sends to server asynchronously!
		{
			auto fbbP = sendP->GetUnusedBufferBuilder();

			robone::Vector3d rv(x,0,0);
			auto controlPoint = robone::CreateVrepControlPoint(*fbbP,&rv);
			robone::FinishVrepControlPointBuffer(*fbbP, controlPoint);
			sendP->async_send_flatbuffer(fbbP);
		}

		//////////////////////////////////////////////
		// Server receives from client asynchronously!
		while (shouldReceive && !receiveP->receive_buffers_empty()) {
			auto rbP = receiveP->get_back_receive_buffer_with_data();
			auto rbPstart = &(rbP->begin()[0]);
			auto verifier = flatbuffers::Verifier(rbPstart,rbP->size());
			auto bufOK = robone::VerifyVrepControlPointBuffer(verifier);

			if(bufOK){
				const robone::VrepControlPoint* VCPin = robone::GetVrepControlPoint(rbPstart);
				std::cout << "received: " << VCPin->position()->x() << "\n";
			} else {
				std::cout << "Failed verification. bufOk: " <<bufOK << "\n";
			}

		}

		std::this_thread::sleep_for( std::chrono::milliseconds(1) );
    }
}

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

    std::string localhost("127.0.0.1");
    std::string localport("9998");
    std::string remotehost("127.0.0.1");
    std::string remoteport("9998");

    std::cout << "argc: " << argc << "\n";
	  /// @todo add default localhost/localport
    if (argc != 5 && argc != 1 && argc != 3)
    {
      std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
      return 1;
    }

    bool shouldReceive = true;

    if(argc == 3){
      remotehost = std::string(argv[1]);
      remoteport = std::string(argv[2]);
      shouldReceive = false;
    }

    if(argc == 5){
      localhost = std::string(argv[1]);
      localport = std::string(argv[2]);
      remotehost = std::string(argv[3]);
      remoteport = std::string(argv[4]);
      shouldReceive = true;
    }

    std::cout << "using: "  << argv[0] << " ";
    if(shouldReceive) std::cout <<  localhost << " " << localport << " ";
    std::cout <<  remotehost << " " << remoteport << "\n";
    boost::asio::io_service io_service;

    // Register signal handlers so that the daemon may be shut down when a signal is received.
    boost::asio::signal_set signals(io_service, SIGINT, SIGTERM);
    signals.async_wait( std::bind(&boost::asio::io_service::stop, &io_service));
#if 0
	std::shared_ptr<AzmqFlatbuffer> sendP;
	{
		boost::system::error_code ec;
		azmq::socket socket(io_service, ZMQ_DEALER);
		socket.connect("tcp://"+ remotehost + ":" + remoteport);
		sendP = std::make_shared<AzmqFlatbuffer>(std::move(socket));
	}
	std::shared_ptr<AzmqFlatbuffer> receiveP;
	{
		boost::system::error_code ec;
		azmq::socket socket(io_service, ZMQ_DEALER);
		socket.bind("tcp://" + localhost + ":" + localport);
		receiveP = std::make_shared<AzmqFlatbuffer>(std::move(socket));
	}

	// Will run until signal is received, using separate objects for send and receive
    std::thread t(bounce,sendP,receiveP);
#else

	std::shared_ptr<AzmqFlatbuffer> receiveP;
	{
		boost::system::error_code ec;
		azmq::socket socket(io_service, ZMQ_DEALER);
		socket.bind("tcp://" + localhost + ":" + localport);
		socket.connect("tcp://"+ remotehost + ":" + remoteport);
		receiveP = std::make_shared<AzmqFlatbuffer>(std::move(socket));
	}

	// Will run until signal is received, using one object for both send and receive
    std::thread t(bounce,receiveP,receiveP,shouldReceive);
#endif

	io_service.run();

//  }
//  catch (std::exception& e)
//  {
//    std::cerr << "Exception: " << e.what() << "\n";
//  }

  return 0;
}<|endoftext|>


<commit_before>#include <memory>
#include <vtkDataSet.h>
#include <vtkXMLImageDataReader.h>
#include <vtkXMLStructuredGridReader.h>
#include <vtkImageData.h>
#include <vtkNew.h>

#include "io/path.h"
#include "dataset/abstract_sampling_array.h"

#include "io/gmm_vtk_data_array.h"
#include "io/edda_reader.h"

using namespace std;

namespace edda {

template <typename T>
shared_ptr<Dataset<T> > loadEddaRandomSamplingDataset(const string &edda_file, const string &array_name)
{
  string ext = getFileExtension(edda_file);
  if (ext.compare("vti")==0) {
     vtkNew<vtkXMLImageDataReader> reader;
     reader->SetFileName(edda_file.c_str());
     reader->Update();
     vtkImageData *vtkdata = reader->GetOutput();

     int *dim = vtkdata->GetDimensions();
     printf("dim: %d %d %d\n", dim[0], dim[1], dim[2]);

     // TODO : check if gmm dataset
     shared_ptr<Dataset<T> > dataset = make_Dataset<T>(
                                   new RegularCartesianGrid(dim[0], dim[1], dim[2]),
                                   new AbstractSamplingArray( new GmmVtkDataArray( vtkdata->GetPointData(), array_name.c_str() ) )
         );
     // or is histogram dataset

     return dataset;

  } else if (ext.compare("vts")==0){ // structured grids

    vtkNew<vtkXMLStructuredGridReader> reader;
    reader->SetFileName(edda_file.c_str());
    reader->Update();
    vtkStructuredGrid *vtkdata = reader->GetOutput();

    int *dim = vtkdata->GetDimensions();
    printf("dim: %d %d %d\n", dim[0], dim[1], dim[2]);

    // TODO : check if gmm dataset
		// TODO: check if is Curvilinear grids
	int numPoints = dim[0] * dim[1] * dim[2];
	CVertex* pVertexGeom = new CVertex[numPoints];
	double tempd[3];
	for (int k = 0; k < dim[2]; k++){
		for (int j = 0; j < dim[1]; j++){
			for (int i = 0; i < dim[0]; i++){
				int ind = k*dim[1] * dim[0] + j*dim[0] + i;// !!! need to confirm !!!
				vtkdata->GetPoint(i, j, k, tempd);
				pVertexGeom[ind].position[0] = tempd[0];
				pVertexGeom[ind].position[1] = tempd[1];
				pVertexGeom[ind].position[2] = tempd[2];

			}
		}
	}

    shared_ptr<Dataset<T> > dataset = make_Dataset<T>(
			new CurvilinearGrid(dim, pVertexGeom),
            new AbstractSamplingArray( new GmmVtkDataArray( vtkdata->GetPointData(), array_name.c_str() ) )
        );
		// or is other structured grids
    // or is histogram dataset

    return dataset;
  } else {
    printf("File format of %s not supported\n", edda_file.c_str());
    exit(1);
  }
}

shared_ptr<Dataset<Real> > loadEddaScalarDataset(const string &edda_file, const string &array_name)
{
  return loadEddaRandomSamplingDataset<Real>(edda_file, array_name);
}

shared_ptr<Dataset<VECTOR3> > loadEddaVector3Dataset(const string &edda_file, const string &array_name)
{
  return loadEddaRandomSamplingDataset<VECTOR3>(edda_file, array_name);
}

} // edda
<commit_msg>further solve conflict<commit_after><|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "PlayerInfo.h"

/* system implementation headers */
#include <errno.h>
#include <string>

/* implementation-specific common headers */
#include "TextUtils.h"

WordFilter PlayerInfo::serverSpoofingFilter;
TimeKeeper PlayerInfo::now = TimeKeeper::getCurrent();

PlayerInfo::PlayerInfo(int _playerIndex) :
  playerIndex(_playerIndex), state(PlayerInLimbo), flag(-1),
  spamWarns(0), lastMsgTime(now), paused(false),
  pausedSince(TimeKeeper::getNullTime()), autopilot(false), tracker(0)
{
  notResponding = false;
  memset(email, 0, EmailLen);
  memset(callSign, 0, CallSignLen);
  memset(token, 0, TokenLen);
  memset(clientVersion, 0, VersionLen);
}

void PlayerInfo::resetPlayer(bool ctf) {
  wasRabbit = false;

  lastupdate = now;
  lastmsg    = now;

  replayState = ReplayNone;

  playedEarly = false;

  restartOnBase = ctf;
}

void PlayerInfo::setRestartOnBase(bool on) {
  restartOnBase = on;
};

bool PlayerInfo::shouldRestartAtBase() {
  return restartOnBase;
};

void PlayerInfo::signingOn() {
  state = PlayerDead;
};

bool PlayerInfo::isAlive() {
  return state == PlayerAlive;
};

void PlayerInfo::setAlive() {
  state = PlayerAlive;
  flag = -1;
};

void PlayerInfo::setDead() {
  state = PlayerDead;
};

void *PlayerInfo::packUpdate(void *buf) {
  buf = nboPackUShort(buf, uint16_t(type));
  buf = nboPackUShort(buf, uint16_t(team));
  return buf;
};

void *PlayerInfo::packId(void *buf) {
  buf = nboPackString(buf, callSign, CallSignLen);
  buf = nboPackString(buf, email, EmailLen);
  return buf;
}

bool PlayerInfo::unpackEnter(void *buf, uint16_t &rejectCode, char *rejectMsg)
{
  // data: type, team, name, email
  uint16_t _type;
  int16_t _team;
  buf = nboUnpackUShort(buf, _type);
  buf = nboUnpackShort(buf, _team);
  type = PlayerType(_type);
  team = TeamColor(_team);
  buf = nboUnpackString(buf, callSign, CallSignLen);
  buf = nboUnpackString(buf, email, EmailLen);
  buf = nboUnpackString(buf, token, TokenLen);
  buf = nboUnpackString(buf, clientVersion, VersionLen);
  cleanEMail();

  DEBUG2("Player %s [%d] sent version string: %s\n",
	 callSign, playerIndex, clientVersion);

  // spoof filter holds "SERVER" for robust name comparisons
  if (serverSpoofingFilter.wordCount() == 0) {
    serverSpoofingFilter.addToFilter("SERVER", "");
  }

  if (!isCallSignReadable()) {
    DEBUG2("rejecting unreadable callsign: %s\n", callSign);
    rejectCode   = RejectBadCallsign;
    strcpy(rejectMsg, errorString.c_str());
    return false;
  }
  // no spoofing the server name
  if (serverSpoofingFilter.filter(callSign)) {
    rejectCode   = RejectRepeatCallsign;
    strcpy(rejectMsg, "The callsign specified is already in use.");
    return false;
  }
  if (!isEMailReadable()) {
    DEBUG2("rejecting unreadable player email: %s (%s)\n", callSign, email);
    rejectCode   = RejectBadEmail;
    strcpy(rejectMsg, "The e-mail was rejected.  Try a different e-mail.");
    return false;
  }
  return true;
};

const char *PlayerInfo::getCallSign() const {
  return callSign;
};

bool PlayerInfo::isCallSignReadable() {
  // callsign readability filter, make sure there are more alphanum than non
  // keep a count of alpha-numerics

  int callsignlen = (int)strlen(callSign);
  // reject less than 3 characters
  if (callsignlen < 3) {
    errorString = "Callsigns must be at least 3 characters.";
    return false;
  }

  // reject trailing space
  if (isspace(callSign[strlen(callSign) - 1])) {
    errorString = "Trailing spaces are not allowed in callsigns.";
    return false;
  }

  // start with true to reject leading space
  bool lastWasSpace = true;
  int alnumCount = 0;
  const char *sp = callSign;
  do {
    // reject sequential spaces
    if (lastWasSpace && isspace(*sp)) {
      errorString = "Leading or consecutive spaces are not allowed in callsigns.";
      return false;
    }

    // reject ' and " and any nonprintable
    if ((*sp == '\'') || (*sp == '"') || ((unsigned)*sp > 0x7f)
	|| !isprint(*sp)) {
      errorString = "Non-printable characters and quotes are not allowed in callsigns.";
      return false;
    }
    if (isspace(*sp)) {
      // only space is valid, not tab etc.
      if (*sp != ' ') {
	errorString = "Invalid whitespace in callsign.";
	return false;
      }
      lastWasSpace = true;
    } else {
      lastWasSpace = false;
      if (isalnum(*sp))
	alnumCount++;
    }
  } while (*++sp);

  bool readable = ((float)alnumCount / (float)callsignlen) > 0.5f;
  if (!readable)
    errorString = "Callsign rejected. Please use mostly letters and numbers.";
  return readable;
};

const char *PlayerInfo::getEMail() const {
  return email;
};

void PlayerInfo::cleanEMail() {
  // strip leading whitespace from email
  char *sp = email;
  char *tp = sp;
  while (isspace(*sp))
    sp++;

  // strip any non-printable characters and ' and " from email
  do {
    if (isprint(*sp) && (*sp != '\'') && (*sp != '"')) {
      *tp++ = *sp;
    }
  } while (*++sp);
  *tp = *sp;

  // strip trailing whitespace from email
  while (isspace(*--tp)) {
    *tp=0;
  }
};

bool PlayerInfo::isEMailReadable() {
  // email/"team" readability filter, make sure there are more
  // alphanum than non
  int emailAlnumCount = 0;
  char *sp = email;
  do {
    if (isalnum(*sp)) {
      emailAlnumCount++;
    }
  } while (*++sp);
  int emaillen = (int)strlen(email);
  return (emaillen <= 4) || (((float)emailAlnumCount / (float)emaillen) > 0.5);
};

const char *PlayerInfo::getToken() const {
  return token;
};

void PlayerInfo::clearToken() {
  token[0] = '\0';
};

void *PlayerInfo::packVirtualFlagCapture(void *buf) {
  buf = nboPackUShort(buf, uint16_t(int(team) - 1));
  buf = nboPackUShort(buf, uint16_t(1 + (int(team) % 4)));
  return buf;
};

bool PlayerInfo::isTeam(TeamColor _team) const {
  return team == _team;
};

bool PlayerInfo::isObserver() const {
  return team == ObserverTeam;
};

TeamColor PlayerInfo::getTeam() {
  return team;
};

void PlayerInfo::setTeam(TeamColor _team) {
  team = _team;
};

void PlayerInfo::wasARabbit() {
  team = RogueTeam;
  wasRabbit = true;
};

void PlayerInfo::wasNotARabbit() {
  wasRabbit = false;
};

void PlayerInfo::resetFlag() {
  flag = -1;
  lastFlagDropTime = now;
};

void PlayerInfo::setFlag(int _flag) {
  flag = _flag;
};

bool PlayerInfo::isFlagTransitSafe() {
  return now - lastFlagDropTime >= 2.0f;
};

const char *PlayerInfo::getClientVersion() {
  return clientVersion;
};

std::string PlayerInfo::getIdleStat() {
  std::string reply;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    reply = TextUtils::format("%s\t: %4ds", callSign,
				int(now - lastupdate));
    if (paused) {
      reply += TextUtils::format("  paused %4ds", int(now - pausedSince));
    }
  }
  return reply;
};

bool PlayerInfo::canBeRabbit(bool relaxing) {
  if (paused || notResponding || (team == ObserverTeam))
    return false;
  return relaxing ? (state > PlayerInLimbo) : (state == PlayerAlive);
};

void PlayerInfo::setPaused(bool _paused) {
  paused = _paused;
  pausedSince = now;
};

void PlayerInfo::setAutoPilot(bool _autopilot) {
  autopilot = _autopilot;
};

bool PlayerInfo::isTooMuchIdling(float kickThresh) {
  bool idling = false;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    int idletime = (int)(now - lastupdate);
    int pausetime = 0;
    if (paused && now - pausedSince > idletime)
      pausetime = (int)(now - pausedSince);
    idletime = idletime > pausetime ? idletime : pausetime;
    if (idletime
	> (now - lastmsg < kickThresh ? 3 * kickThresh : kickThresh)) {
      DEBUG1("Kicking player %s [%d] idle %d\n", callSign, playerIndex,
	     idletime);
      idling = true;
    }
  }
  return idling;
};

bool PlayerInfo::hasStartedToNotRespond() {
  float notRespondingTime = BZDB.eval(StateDatabase::BZDB_NOTRESPONDINGTIME);
  bool startingToNotRespond = false;
  if (state > PlayerInLimbo) {
    bool oldnr = notResponding;
    notResponding = (now - lastupdate) > notRespondingTime;
    if (!oldnr && notResponding)
      startingToNotRespond = true;
  }
  return startingToNotRespond;
}

void PlayerInfo::hasSent(char message[]) {
  lastmsg = now;
  DEBUG1("Player %s [%d]: %s\n", callSign, playerIndex, message);
};

bool PlayerInfo::hasPlayedEarly() {
  bool returnValue = playedEarly;
  playedEarly      = false;
  return returnValue;
};

void PlayerInfo::setPlayedEarly(bool early) {
  playedEarly = early;
};

void PlayerInfo::updateIdleTime() {
  lastupdate = now;
};

void	PlayerInfo::setReplayState(PlayerReplayState state) {
  replayState = state;
}

PlayerReplayState PlayerInfo::getReplayState()
{
  return replayState;
}

void PlayerInfo::setTrackerID(unsigned short int t)
{
  tracker = t;
}

unsigned short int PlayerInfo::trackerID()
{
  return tracker;
}

void PlayerInfo::setCurrentTime(TimeKeeper tm)
{
  now = tm;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>When coming alive a player is unpaused. Fix sf BUG 1102836.<commit_after>/* bzflag
 * Copyright (c) 1993 - 2005 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "PlayerInfo.h"

/* system implementation headers */
#include <errno.h>
#include <string>

/* implementation-specific common headers */
#include "TextUtils.h"

WordFilter PlayerInfo::serverSpoofingFilter;
TimeKeeper PlayerInfo::now = TimeKeeper::getCurrent();

PlayerInfo::PlayerInfo(int _playerIndex) :
  playerIndex(_playerIndex), state(PlayerInLimbo), flag(-1),
  spamWarns(0), lastMsgTime(now), paused(false),
  pausedSince(TimeKeeper::getNullTime()), autopilot(false), tracker(0)
{
  notResponding = false;
  memset(email, 0, EmailLen);
  memset(callSign, 0, CallSignLen);
  memset(token, 0, TokenLen);
  memset(clientVersion, 0, VersionLen);
}

void PlayerInfo::resetPlayer(bool ctf) {
  wasRabbit = false;

  lastupdate = now;
  lastmsg    = now;

  replayState = ReplayNone;

  playedEarly = false;

  restartOnBase = ctf;
}

void PlayerInfo::setRestartOnBase(bool on) {
  restartOnBase = on;
};

bool PlayerInfo::shouldRestartAtBase() {
  return restartOnBase;
};

void PlayerInfo::signingOn() {
  state = PlayerDead;
};

bool PlayerInfo::isAlive() {
  return state == PlayerAlive;
};

void PlayerInfo::setAlive() {
  state = PlayerAlive;
  paused = false;
  flag = -1;
};

void PlayerInfo::setDead() {
  state = PlayerDead;
};

void *PlayerInfo::packUpdate(void *buf) {
  buf = nboPackUShort(buf, uint16_t(type));
  buf = nboPackUShort(buf, uint16_t(team));
  return buf;
};

void *PlayerInfo::packId(void *buf) {
  buf = nboPackString(buf, callSign, CallSignLen);
  buf = nboPackString(buf, email, EmailLen);
  return buf;
}

bool PlayerInfo::unpackEnter(void *buf, uint16_t &rejectCode, char *rejectMsg)
{
  // data: type, team, name, email
  uint16_t _type;
  int16_t _team;
  buf = nboUnpackUShort(buf, _type);
  buf = nboUnpackShort(buf, _team);
  type = PlayerType(_type);
  team = TeamColor(_team);
  buf = nboUnpackString(buf, callSign, CallSignLen);
  buf = nboUnpackString(buf, email, EmailLen);
  buf = nboUnpackString(buf, token, TokenLen);
  buf = nboUnpackString(buf, clientVersion, VersionLen);
  cleanEMail();

  DEBUG2("Player %s [%d] sent version string: %s\n",
	 callSign, playerIndex, clientVersion);

  // spoof filter holds "SERVER" for robust name comparisons
  if (serverSpoofingFilter.wordCount() == 0) {
    serverSpoofingFilter.addToFilter("SERVER", "");
  }

  if (!isCallSignReadable()) {
    DEBUG2("rejecting unreadable callsign: %s\n", callSign);
    rejectCode   = RejectBadCallsign;
    strcpy(rejectMsg, errorString.c_str());
    return false;
  }
  // no spoofing the server name
  if (serverSpoofingFilter.filter(callSign)) {
    rejectCode   = RejectRepeatCallsign;
    strcpy(rejectMsg, "The callsign specified is already in use.");
    return false;
  }
  if (!isEMailReadable()) {
    DEBUG2("rejecting unreadable player email: %s (%s)\n", callSign, email);
    rejectCode   = RejectBadEmail;
    strcpy(rejectMsg, "The e-mail was rejected.  Try a different e-mail.");
    return false;
  }
  return true;
};

const char *PlayerInfo::getCallSign() const {
  return callSign;
};

bool PlayerInfo::isCallSignReadable() {
  // callsign readability filter, make sure there are more alphanum than non
  // keep a count of alpha-numerics

  int callsignlen = (int)strlen(callSign);
  // reject less than 3 characters
  if (callsignlen < 3) {
    errorString = "Callsigns must be at least 3 characters.";
    return false;
  }

  // reject trailing space
  if (isspace(callSign[strlen(callSign) - 1])) {
    errorString = "Trailing spaces are not allowed in callsigns.";
    return false;
  }

  // start with true to reject leading space
  bool lastWasSpace = true;
  int alnumCount = 0;
  const char *sp = callSign;
  do {
    // reject sequential spaces
    if (lastWasSpace && isspace(*sp)) {
      errorString = "Leading or consecutive spaces are not allowed in callsigns.";
      return false;
    }

    // reject ' and " and any nonprintable
    if ((*sp == '\'') || (*sp == '"') || ((unsigned)*sp > 0x7f)
	|| !isprint(*sp)) {
      errorString = "Non-printable characters and quotes are not allowed in callsigns.";
      return false;
    }
    if (isspace(*sp)) {
      // only space is valid, not tab etc.
      if (*sp != ' ') {
	errorString = "Invalid whitespace in callsign.";
	return false;
      }
      lastWasSpace = true;
    } else {
      lastWasSpace = false;
      if (isalnum(*sp))
	alnumCount++;
    }
  } while (*++sp);

  bool readable = ((float)alnumCount / (float)callsignlen) > 0.5f;
  if (!readable)
    errorString = "Callsign rejected. Please use mostly letters and numbers.";
  return readable;
};

const char *PlayerInfo::getEMail() const {
  return email;
};

void PlayerInfo::cleanEMail() {
  // strip leading whitespace from email
  char *sp = email;
  char *tp = sp;
  while (isspace(*sp))
    sp++;

  // strip any non-printable characters and ' and " from email
  do {
    if (isprint(*sp) && (*sp != '\'') && (*sp != '"')) {
      *tp++ = *sp;
    }
  } while (*++sp);
  *tp = *sp;

  // strip trailing whitespace from email
  while (isspace(*--tp)) {
    *tp=0;
  }
};

bool PlayerInfo::isEMailReadable() {
  // email/"team" readability filter, make sure there are more
  // alphanum than non
  int emailAlnumCount = 0;
  char *sp = email;
  do {
    if (isalnum(*sp)) {
      emailAlnumCount++;
    }
  } while (*++sp);
  int emaillen = (int)strlen(email);
  return (emaillen <= 4) || (((float)emailAlnumCount / (float)emaillen) > 0.5);
};

const char *PlayerInfo::getToken() const {
  return token;
};

void PlayerInfo::clearToken() {
  token[0] = '\0';
};

void *PlayerInfo::packVirtualFlagCapture(void *buf) {
  buf = nboPackUShort(buf, uint16_t(int(team) - 1));
  buf = nboPackUShort(buf, uint16_t(1 + (int(team) % 4)));
  return buf;
};

bool PlayerInfo::isTeam(TeamColor _team) const {
  return team == _team;
};

bool PlayerInfo::isObserver() const {
  return team == ObserverTeam;
};

TeamColor PlayerInfo::getTeam() {
  return team;
};

void PlayerInfo::setTeam(TeamColor _team) {
  team = _team;
};

void PlayerInfo::wasARabbit() {
  team = RogueTeam;
  wasRabbit = true;
};

void PlayerInfo::wasNotARabbit() {
  wasRabbit = false;
};

void PlayerInfo::resetFlag() {
  flag = -1;
  lastFlagDropTime = now;
};

void PlayerInfo::setFlag(int _flag) {
  flag = _flag;
};

bool PlayerInfo::isFlagTransitSafe() {
  return now - lastFlagDropTime >= 2.0f;
};

const char *PlayerInfo::getClientVersion() {
  return clientVersion;
};

std::string PlayerInfo::getIdleStat() {
  std::string reply;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    reply = TextUtils::format("%s\t: %4ds", callSign,
				int(now - lastupdate));
    if (paused) {
      reply += TextUtils::format("  paused %4ds", int(now - pausedSince));
    }
  }
  return reply;
};

bool PlayerInfo::canBeRabbit(bool relaxing) {
  if (paused || notResponding || (team == ObserverTeam))
    return false;
  return relaxing ? (state > PlayerInLimbo) : (state == PlayerAlive);
};

void PlayerInfo::setPaused(bool _paused) {
  paused = _paused;
  pausedSince = now;
};

void PlayerInfo::setAutoPilot(bool _autopilot) {
  autopilot = _autopilot;
};

bool PlayerInfo::isTooMuchIdling(float kickThresh) {
  bool idling = false;
  if ((state > PlayerInLimbo) && (team != ObserverTeam)) {
    int idletime = (int)(now - lastupdate);
    int pausetime = 0;
    if (paused && now - pausedSince > idletime)
      pausetime = (int)(now - pausedSince);
    idletime = idletime > pausetime ? idletime : pausetime;
    if (idletime
	> (now - lastmsg < kickThresh ? 3 * kickThresh : kickThresh)) {
      DEBUG1("Kicking player %s [%d] idle %d\n", callSign, playerIndex,
	     idletime);
      idling = true;
    }
  }
  return idling;
};

bool PlayerInfo::hasStartedToNotRespond() {
  float notRespondingTime = BZDB.eval(StateDatabase::BZDB_NOTRESPONDINGTIME);
  bool startingToNotRespond = false;
  if (state > PlayerInLimbo) {
    bool oldnr = notResponding;
    notResponding = (now - lastupdate) > notRespondingTime;
    if (!oldnr && notResponding)
      startingToNotRespond = true;
  }
  return startingToNotRespond;
}

void PlayerInfo::hasSent(char message[]) {
  lastmsg = now;
  DEBUG1("Player %s [%d]: %s\n", callSign, playerIndex, message);
};

bool PlayerInfo::hasPlayedEarly() {
  bool returnValue = playedEarly;
  playedEarly      = false;
  return returnValue;
};

void PlayerInfo::setPlayedEarly(bool early) {
  playedEarly = early;
};

void PlayerInfo::updateIdleTime() {
  lastupdate = now;
};

void	PlayerInfo::setReplayState(PlayerReplayState state) {
  replayState = state;
}

PlayerReplayState PlayerInfo::getReplayState()
{
  return replayState;
}

void PlayerInfo::setTrackerID(unsigned short int t)
{
  tracker = t;
}

unsigned short int PlayerInfo::trackerID()
{
  return tracker;
}

void PlayerInfo::setCurrentTime(TimeKeeper tm)
{
  now = tm;
}

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


<commit_before>//
//  CustomAudioUnit.cpp
//  Demo
//
//  Created by Philadelphia Game Lab on 6/11/14.
//  Copyright (c) 2014 Philadelphia Game Lab. All rights reserved.
//

#include "CustomAudioUnit.h"

static OSStatus recordingCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {

    //Please dont remove the following commented code
    //The following code will be used if we use recording callback

    //TODO: Use inRefCon to access our interface object to do stuff
    //Then use inNumberFrames to figure out how much data is available and make that much space available in buffers in AudioBufferList

    //AudioBufferList list;
    //list.mNumberBuffers = 1;
    //list.mBuffers[0].mData = sampleBuffer;
    //list.mBuffers[0].mDataByteSize = 2* inNumberFrames;
    //list.mBuffers[0].mNumberChannels = 1;
    //AudioUnitRender([audioInterface audioUnitInstance], ioActionFlags, inTimeStamp, 1, inNumberFrames, &list);

    return noErr;
}

static OSStatus playbackCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {

    //Please dont remove the following commented code
    //The following code will be used for immediate debugging

    //Notes: ioData contains buffers (may be more than one)
    //Fill them up as much as you can. Remember to set the size value in each buffer to match how much data is in each buffer.

    //ioData->mBuffers[i].mNumberChannels is no. of channels per buffer
    //*ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
    //for (UInt32 i=0; i<ioData->mNumberBuffers; ++i) {
    //    memset(ioData->mBuffers[i].mData, 10000, ioData->mBuffers[i].mDataByteSize);
    //    std::cout<<"\naksjdhka " << ioData->mBuffers[i].mDataByteSize <<" i=" << i <<" "<<inBusNumber;
    //
    //}

    //clock_t t1, t2;
    //t1 = clock();
    mixer3D->performMix((short *)ioData->mBuffers[0].mData, (short *) ioData->mBuffers[1].mData);
    //t2 = clock();
    //cout<<"The time consumption is "<<((double)(t2-t1))/CLOCKS_PER_SEC<<endl;

    return noErr;
}

void CustomAudioUnit::init () {
    mixer3D = new Mixer3D(BUF_SIZE, SAMPLE_RATE, BIT_DEPTH, myWorld);

    AudioComponentDescription desc;

    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;

    AudioComponent component = AudioComponentFindNext(NULL, &desc);
    AudioComponentInstanceNew(component, &audioUnitInstance);

    UInt32 enableIO;
    AudioUnitElement inputBus = 1;
    AudioUnitElement outputBus = 0;

    //Disabling IO for recording
    enableIO = 0;
    AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, inputBus, &enableIO, sizeof(enableIO));

    //Enabling IO for playback
    enableIO = 1;
    AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, outputBus, &enableIO, sizeof(enableIO));

    UInt32 bytesPerSample = sizeof(short) ;  //sizeof(AudioUnitSampleType);
    AudioStreamBasicDescription stereoStreamFormat = {0};
    stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample;
    stereoStreamFormat.mBytesPerFrame = bytesPerSample;
    stereoStreamFormat.mBytesPerPacket = bytesPerSample;
    stereoStreamFormat.mChannelsPerFrame = 2;   // 2 incdicates stereo
    stereoStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger |
    kAudioFormatFlagsNativeEndian |
    kAudioFormatFlagIsPacked |
    kAudioFormatFlagIsNonInterleaved;
    stereoStreamFormat.mFormatID = kAudioFormatLinearPCM;
    stereoStreamFormat.mFramesPerPacket = 1;
    stereoStreamFormat.mReserved = 0;
    stereoStreamFormat.mSampleRate = SAMPLE_RATE;

    AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, inputBus, &stereoStreamFormat, sizeof(AudioStreamBasicDescription));
    AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, outputBus, &stereoStreamFormat, sizeof(AudioStreamBasicDescription));

    //Setting input callback
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = &recordingCallback;    //////Should there be an ampersand
    callbackStruct.inputProcRefCon = audioUnitInstance;
    AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, inputBus, &callbackStruct, sizeof(callbackStruct));   /////Not sure of scope and bus/element

    //Setting output callback
    callbackStruct.inputProc = &playbackCallback;
    callbackStruct.inputProcRefCon = audioUnitInstance;
    AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, outputBus, &callbackStruct, sizeof(callbackStruct));

    AudioUnitInitialize(audioUnitInstance);

}

CustomAudioUnit::CustomAudioUnit() {
    myWorld = new World;
    init();
    std::cout<<"\nConstructor";
}

CustomAudioUnit::~CustomAudioUnit() {
    AudioUnitUninitialize(audioUnitInstance);
    AudioComponentInstanceDispose(audioUnitInstance);
    std::cout<<"\nDestructor";
}

void CustomAudioUnit::play() {
    //init();
    myWorld->createWriteThread();
    AudioOutputUnitStart(audioUnitInstance);
    std::cout<<"\nPlay";
}

void CustomAudioUnit::stop() {
    AudioOutputUnitStop(audioUnitInstance);
    //AudioUnitUninitialize(audioUnitInstance);
    //AudioComponentInstanceDispose(audioUnitInstance);
    std::cout<<"\nStop";
}

AudioObj* CustomAudioUnit::addAudioObjectInWorld(string wavFile, VariableForLocation x, VariableForLocation y, VariableForLocation z)
{
    if(myWorld != nullptr)
    {
        Location loc = Location(x, y, z);
        Velocity vel = Velocity();
        return myWorld->addAudioObj(loc,vel,wavFile);
    }
    else
    {
        throw("World has to be created before adding audio objects");
        return nullptr;
    }

}

void CustomAudioUnit::setPlayerPosition(VariableForLocation x, VariableForLocation y, VariableForLocation z)
{
    myWorld->setPlayerPosition(x, y, z);
}

void CustomAudioUnit::setPlayerBearing(float bearing)
{
    myWorld->setPlayerBearing(bearing);
}

<commit_msg>moved #defines to .h file<commit_after>//
//  CustomAudioUnit.cpp
//  Demo
//
//  Created by Philadelphia Game Lab on 6/11/14.
//  Copyright (c) 2014 Philadelphia Game Lab. All rights reserved.
//

#include "CustomAudioUnit.h"

static OSStatus recordingCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {

    //Please dont remove the following commented code
    //The following code will be used if we use recording callback

    //TODO: Use inRefCon to access our interface object to do stuff
    //Then use inNumberFrames to figure out how much data is available and make that much space available in buffers in AudioBufferList

    //AudioBufferList list;
    //list.mNumberBuffers = 1;
    //list.mBuffers[0].mData = sampleBuffer;
    //list.mBuffers[0].mDataByteSize = 2* inNumberFrames;
    //list.mBuffers[0].mNumberChannels = 1;
    //AudioUnitRender([audioInterface audioUnitInstance], ioActionFlags, inTimeStamp, 1, inNumberFrames, &list);

    return noErr;
}

static OSStatus playbackCallback (void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {

    //Please dont remove the following commented code
    //The following code will be used for immediate debugging

    //Notes: ioData contains buffers (may be more than one)
    //Fill them up as much as you can. Remember to set the size value in each buffer to match how much data is in each buffer.

    //ioData->mBuffers[i].mNumberChannels is no. of channels per buffer
    //*ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
    //for (UInt32 i=0; i<ioData->mNumberBuffers; ++i) {
    //    memset(ioData->mBuffers[i].mData, 10000, ioData->mBuffers[i].mDataByteSize);
    //    std::cout<<"\naksjdhka " << ioData->mBuffers[i].mDataByteSize <<" i=" << i <<" "<<inBusNumber;
    //
    //}

    //clock_t t1, t2;
    //t1 = clock();
    mixer3D->performMix((short *)ioData->mBuffers[0].mData, (short *) ioData->mBuffers[1].mData);
    //t2 = clock();
    //cout<<"The time consumption is "<<((double)(t2-t1))/CLOCKS_PER_SEC<<endl;

    return noErr;
}

void CustomAudioUnit::init () {
    mixer3D = new Mixer3D(BUF_SIZE, SAMPLE_RATE, BIT_DEPTH, myWorld);

    AudioComponentDescription desc;

    desc.componentType = kAudioUnitType_Output;
    desc.componentSubType = kAudioUnitSubType_RemoteIO;
    desc.componentFlags = 0;
    desc.componentFlagsMask = 0;
    desc.componentManufacturer = kAudioUnitManufacturer_Apple;

    AudioComponent component = AudioComponentFindNext(NULL, &desc);
    AudioComponentInstanceNew(component, &audioUnitInstance);

    UInt32 enableIO;
    AudioUnitElement inputBus = 1;
    AudioUnitElement outputBus = 0;

    //Disabling IO for recording
    enableIO = 0;
    AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, inputBus, &enableIO, sizeof(enableIO));

    //Enabling IO for playback
    enableIO = 1;
    AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, outputBus, &enableIO, sizeof(enableIO));

    UInt32 bytesPerSample = sizeof(short) ;  //sizeof(AudioUnitSampleType);
    AudioStreamBasicDescription stereoStreamFormat = {0};
    stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample;
    stereoStreamFormat.mBytesPerFrame = bytesPerSample;
    stereoStreamFormat.mBytesPerPacket = bytesPerSample;
    stereoStreamFormat.mChannelsPerFrame = 2;   // 2 incdicates stereo
    stereoStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger |
    kAudioFormatFlagsNativeEndian |
    kAudioFormatFlagIsPacked |
    kAudioFormatFlagIsNonInterleaved;
    stereoStreamFormat.mFormatID = kAudioFormatLinearPCM;
    stereoStreamFormat.mFramesPerPacket = 1;
    stereoStreamFormat.mReserved = 0;
    stereoStreamFormat.mSampleRate = SAMPLE_RATE;

    AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, inputBus, &stereoStreamFormat, sizeof(AudioStreamBasicDescription));
    AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, outputBus, &stereoStreamFormat, sizeof(AudioStreamBasicDescription));

    //Setting input callback
    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = &recordingCallback;    //////Should there be an ampersand
    callbackStruct.inputProcRefCon = audioUnitInstance;
    AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, inputBus, &callbackStruct, sizeof(callbackStruct));   /////Not sure of scope and bus/element

    //Setting output callback
    callbackStruct.inputProc = &playbackCallback;
    callbackStruct.inputProcRefCon = audioUnitInstance;
    AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, outputBus, &callbackStruct, sizeof(callbackStruct));

    AudioUnitInitialize(audioUnitInstance);

}

CustomAudioUnit::CustomAudioUnit() {
    myWorld = new World;
    init();
    std::cout<<"\nConstructor";
}

CustomAudioUnit::~CustomAudioUnit() {
    AudioUnitUninitialize(audioUnitInstance);
    AudioComponentInstanceDispose(audioUnitInstance);
    std::cout<<"\nDestructor";
}

void CustomAudioUnit::play() {
    //init();
    myWorld->createWriteThread();
    AudioOutputUnitStart(audioUnitInstance);
    std::cout<<"\nPlay";
}

void CustomAudioUnit::stop() {
    AudioOutputUnitStop(audioUnitInstance);
    //AudioUnitUninitialize(audioUnitInstance);
    //AudioComponentInstanceDispose(audioUnitInstance);
    std::cout<<"\nStop";
}

AudioObj* CustomAudioUnit::addAudioObjectInWorld(string wavFile, VariableForLocation x, VariableForLocation y, VariableForLocation z)
{
    if(myWorld != nullptr)
    {
        Location loc = Location(x, y, z);
        Velocity vel = Velocity();
        return myWorld->addAudioObj(loc,vel,wavFile);
    }
    else
    {
        throw("World has to be created before adding audio objects");
        return nullptr;
    }

}

void CustomAudioUnit::setPlayerPosition(VariableForLocation x, VariableForLocation y, VariableForLocation z)
{
    myWorld->setPlayerPosition(x, y, z);
}

void CustomAudioUnit::setPlayerBearing(float bearing)
{
    myWorld->setPlayerBearing(bearing);
}

<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#endif

/* interface header */
#include "TextChunkManager.h"

/* system implementation headers */
#include <fstream>

/* common implementation headers */
#include "global.h"

/******************************************************************************/

TextChunk::TextChunk()
{
  // for the <map>[] operator
}

TextChunk::TextChunk(const std::string& _fileName)
{
  fileName = _fileName;
  theVector = parse();
  return;
}

TextChunk::TextChunk(const TextChunk& tc)
{
  fileName = tc.fileName;
  theVector = tc.theVector;
  return;
}

StringVector TextChunk::parse()
{
  StringVector strings;
  char buffer[MessageLen];
  std::ifstream in(fileName.c_str());
  if (in) {
    for(int i = 0; (i < 20) && in.good(); i++) {
      in.getline(buffer, MessageLen);
      if(!in.fail()){ // really read something
	strings.push_back(buffer);
      }
    }
  }
  return strings;
}

bool TextChunk::reload()
{
  StringVector newVec = parse();
  if (newVec.size() > 0) {
    theVector = newVec;
  }
  return (theVector.size() > 0);
}

size_t TextChunk::size() const
{
  return theVector.size();
}

const StringVector& TextChunk::getVector() const
{
  return theVector;
}

/******************************************************************************/

bool TextChunkManager::parseFile(const std::string &fileName,
				 const std::string &chunkName)
{
  TextChunk textChunk(fileName);

  if (textChunk.size() <= 0) {
    return false;
  }

  // add a new chunk name if it isn't already listed
  if (theChunks.find(chunkName) == theChunks.end()) {
    chunkNames.push_back(chunkName);
  }

  // add or replace the chunk
  theChunks[chunkName] = textChunk;

  return true;
}

const StringVector* TextChunkManager::getTextChunk(const std::string &chunkName) const
{
  TextChunkMap::const_iterator it;
  it = theChunks.find(chunkName);
  if (it != theChunks.end()){
    return &it->second.getVector();
  } else {
    return NULL;
  }
}

const StringVector& TextChunkManager::getChunkNames() const
{
  return chunkNames;
}

void TextChunkManager::reload()
{
  TextChunkMap::iterator it;
  for (it = theChunks.begin(); it != theChunks.end(); it++) {
    it->second.reload();
  }
  return;
}

/******************************************************************************/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<commit_msg>allow for longer help files (50 lines)<commit_after>/* bzflag
 * Copyright (c) 1993 - 2006 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#ifdef _MSC_VER
#pragma warning( 4: 4786)
#endif

/* interface header */
#include "TextChunkManager.h"

/* system implementation headers */
#include <fstream>

/* common implementation headers */
#include "global.h"

/******************************************************************************/

TextChunk::TextChunk()
{
  // for the <map>[] operator
}

TextChunk::TextChunk(const std::string& _fileName)
{
  fileName = _fileName;
  theVector = parse();
  return;
}

TextChunk::TextChunk(const TextChunk& tc)
{
  fileName = tc.fileName;
  theVector = tc.theVector;
  return;
}

StringVector TextChunk::parse()
{
  StringVector strings;
  char buffer[MessageLen];
  std::ifstream in(fileName.c_str());
  if (in) {
    for(int i = 0; (i < 50) && in.good(); i++) {
      in.getline(buffer, MessageLen);
      if(!in.fail()){ // really read something
	strings.push_back(buffer);
      }
    }
  }
  return strings;
}

bool TextChunk::reload()
{
  StringVector newVec = parse();
  if (newVec.size() > 0) {
    theVector = newVec;
  }
  return (theVector.size() > 0);
}

size_t TextChunk::size() const
{
  return theVector.size();
}

const StringVector& TextChunk::getVector() const
{
  return theVector;
}

/******************************************************************************/

bool TextChunkManager::parseFile(const std::string &fileName,
				 const std::string &chunkName)
{
  TextChunk textChunk(fileName);

  if (textChunk.size() <= 0) {
    return false;
  }

  // add a new chunk name if it isn't already listed
  if (theChunks.find(chunkName) == theChunks.end()) {
    chunkNames.push_back(chunkName);
  }

  // add or replace the chunk
  theChunks[chunkName] = textChunk;

  return true;
}

const StringVector* TextChunkManager::getTextChunk(const std::string &chunkName) const
{
  TextChunkMap::const_iterator it;
  it = theChunks.find(chunkName);
  if (it != theChunks.end()){
    return &it->second.getVector();
  } else {
    return NULL;
  }
}

const StringVector& TextChunkManager::getChunkNames() const
{
  return chunkNames;
}

void TextChunkManager::reload()
{
  TextChunkMap::iterator it;
  for (it = theChunks.begin(); it != theChunks.end(); it++) {
    it->second.reload();
  }
  return;
}

/******************************************************************************/

// Local Variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8

<|endoftext|>