<commit_before>/*
 * ===============================================================
 *    Description:  Reachability program.
 *
 *        Created:  Sunday 23 April 2013 11:00:03  EDT
 *
 *         Author:  Ayush Dubey, Greg Hill
 *                  dubey@cs.cornell.edu, gdh39@cornell.edu
 *
 * Copyright (C) 2013, Cornell University, see the LICENSE file
 *                     for licensing agreement
 * ================================================================
 */

#include "reach_program.h"

namespace node_prog
{
    bool
    check_cache_context(cache_response<reach_cache_value> &cr)
    {
        std::vector<node_cache_context>& contexts = cr.get_context();
        if (contexts.size() == 0) {
            return true;
        }
        reach_cache_value &cv = *cr.get_value();
        // path not valid if broken by:
        for (node_cache_context& node_context : contexts)
        {
            if (node_context.node_deleted){  // node deletion
                WDEBUG  << "Cache entry invalid because of node deletion" << std::endl;
                return false;
            }
            // edge deletion, see if path was broken
            for (size_t i = 1; i < cv.path.size(); i++) {
                if (node_context.node == cv.path.at(i)) {
                    db::element::remote_node &path_next_node = cv.path.at(i-1);
                    for(auto &edge : node_context.edges_deleted){
                        if (edge.nbr == path_next_node) {
                            WDEBUG  << "Cache entry invalid because of edge deletion" << std::endl;
                            return false;
                        }
                    }
                    break; // path not broken here, move on
                }
            }
        }
        WDEBUG  << "Cache entry with context size " << contexts.size() << " valid" << std::endl;
        return true;
    }

    std::vector<std::pair<db::element::remote_node, reach_params>>
    reach_node_program(
            node &n,
            db::element::remote_node &rn,
            reach_params &params,
            std::function<reach_node_state&()> state_getter,
            std::function<void(std::shared_ptr<reach_cache_value>, // TODO make const
                std::shared_ptr<std::vector<db::element::remote_node>>, uint64_t)>& add_cache_func,
            cache_response<reach_cache_value>*cache_response)
    {
        reach_node_state &state = state_getter();
        std::vector<std::pair<db::element::remote_node, reach_params>> next;
        bool false_reply = false;
        db::element::remote_node prev_node = params.prev_node;
        params.prev_node = rn;
        if (!params.returning) { // request mode
            if (params.dest == rn.get_id()) {
                // we found the node we are looking for, prepare a reply
                params.returning = true;
                params.reachable = true;
                params.path.emplace_back(rn);
                return {std::make_pair(prev_node, params)};
            } else {
                // have not found it yet so follow all out edges
                if (!state.visited) {
                    state.prev_node = prev_node;
                    state.visited = true;

                    if (MAX_CACHE_ENTRIES)
                    {
                        if (params._search_cache /*&& !params.returning */ && cache_response != NULL){
                            // check context, update cache
                            bool valid = check_cache_context(*cache_response);
                            if (valid) {
                                // we found the node we are looking for, prepare a reply
                                params.returning = true;
                                params.reachable = true;
                                params._search_cache = false; // don't search on way back

                                // context for cached value contains the nodes in the path to the dest_idination from this node
                                params.path = std::dynamic_pointer_cast<reach_cache_value>(cache_response->get_value())->path; // XXX double check this path
                                WDEBUG  << "Cache worked at node " << rn.id << " with path len " << params.path.size() << std::endl;
                                return {std::make_pair(prev_node, params)}; // single length vector
                            } else {
                                cache_response->invalidate();
                            }
                        }
                    }

                    for (edge &e: n.get_edges()) {
                        // checking edge properties
                        if (e.has_all_properties(params.edge_props)) {
                            // e->traverse(); no more traversal recording

                            // propagate reachability request
                            next.emplace_back(std::make_pair(e.get_neighbor(), params));
                            state.out_count++;
                        }
                    }
                    if (state.out_count == 0) {
                        false_reply = true;
                    }
                } else {
                    false_reply = true;
                }
            }
            if (false_reply) {
                params.returning = true;
                params.reachable = false;
                next.emplace_back(std::make_pair(prev_node, params));
            }
        } else { // reply mode
            if (params.reachable) {
                if (state.hops > params.hops) {
                    state.hops = params.hops;
                }
            }
            if (((--state.out_count == 0) || params.reachable) && !state.reachable) {
                state.reachable |= params.reachable;
                if (params.reachable) {
                    params.hops = state.hops + 1;
                    params.path.emplace_back(rn);
                    if (MAX_CACHE_ENTRIES)
                    {
                        // now add to cache
                        WDEBUG << "adding to cache on way back from dest on node " << rn.id << " with path len " << params.path.size() << std::endl;
                        std::shared_ptr<node_prog::reach_cache_value> toCache(new reach_cache_value(params.path));
                        std::shared_ptr<std::vector<db::element::remote_node>> watch_set(new std::vector<db::element::remote_node>(params.path)); // copy return path from params
                        add_cache_func(toCache, watch_set, params.dest);
                    }
                }
                next.emplace_back(std::make_pair(state.prev_node, params));
            }
            if ((int)state.out_count < 0) {
                WDEBUG << "ALERT! Bad state value in reach program" << std::endl;
                next.clear();
            }
        }
        return next;
    }
}
<commit_msg>added more debug statements, small flag fix on reachability prog<commit_after>/*
 * ===============================================================
 *    Description:  Reachability program.
 *
 *        Created:  Sunday 23 April 2013 11:00:03  EDT
 *
 *         Author:  Ayush Dubey, Greg Hill
 *                  dubey@cs.cornell.edu, gdh39@cornell.edu
 *
 * Copyright (C) 2013, Cornell University, see the LICENSE file
 *                     for licensing agreement
 * ================================================================
 */

//#define weaver_debug_
#include "reach_program.h"

namespace node_prog
{
    inline bool
    check_cache_context(cache_response<reach_cache_value> &cr)
    {
        std::vector<node_cache_context>& contexts = cr.get_context();
        if (contexts.size() == 0) {
            return true;
        }
        reach_cache_value &cv = *cr.get_value();
        // path not valid if broken by:
        for (node_cache_context& node_context : contexts)
        {
            if (node_context.node_deleted){  // node deletion
                WDEBUG  << "Cache entry invalid because of node deletion" << std::endl;
                return false;
            }
            // edge deletion, see if path was broken
            for (size_t i = 1; i < cv.path.size(); i++) {
                if (node_context.node == cv.path.at(i)) {
                    db::element::remote_node &path_next_node = cv.path.at(i-1);
                    for(auto &edge : node_context.edges_deleted){
                        if (edge.nbr == path_next_node) {
                            WDEBUG  << "Cache entry invalid because of edge deletion" << std::endl;
                            return false;
                        }
                    }
                    break; // path not broken here, move on
                }
            }
        }
        WDEBUG  << "Cache entry with context size " << contexts.size() << " valid" << std::endl;
        return true;
    }

    std::vector<std::pair<db::element::remote_node, reach_params>>
    reach_node_program(
            node &n,
            db::element::remote_node &rn,
            reach_params &params,
            std::function<reach_node_state&()> state_getter,
            std::function<void(std::shared_ptr<reach_cache_value>, // TODO make const
                std::shared_ptr<std::vector<db::element::remote_node>>, uint64_t)>& add_cache_func,
            cache_response<reach_cache_value>*cache_response)
    {
        WDEBUG  << "REACH AT NODE " << rn.id << std::endl;
        reach_node_state &state = state_getter();
        std::vector<std::pair<db::element::remote_node, reach_params>> next;
        bool false_reply = false;
        db::element::remote_node prev_node = params.prev_node;
        params.prev_node = rn;
        if (!params.returning) { // request mode
            if (params.dest == rn.get_id()) {
                // we found the node we are looking for, prepare a reply
                params.returning = true;
                params.reachable = true;
                params.path.emplace_back(rn);
                params._search_cache = false; // never search on way back
                WDEBUG  << "returning to node " << prev_node.id << " because found " << std::endl;
                return {std::make_pair(prev_node, params)};
            } else {
                // have not found it yet so follow all out edges
                if (!state.visited) {
                    state.prev_node = prev_node;
                    state.visited = true;

                    if (MAX_CACHE_ENTRIES)
                    {
                        WDEBUG  << "in cache section with search cache " << params._search_cache << ", cache key = " << params._cache_key << " and cache response "<< cache_response << std::endl;
                        if (params._search_cache /*&& !params.returning */ && cache_response != NULL){
                            // check context, update cache
                            if (check_cache_context(*cache_response)) { // if context is valid
                                // we found the node we are looking for, prepare a reply
                                params.returning = true;
                                params.reachable = true;
                                params._search_cache = false; // don't search on way back

                                // context for cached value contains the nodes in the path to the dest_idination from this node
                                params.path = std::dynamic_pointer_cast<reach_cache_value>(cache_response->get_value())->path; // XXX double check this path
                                WDEBUG  << "Cache worked at node " << rn.id << " with path len " << params.path.size() << std::endl;
                                WDEBUG << "path is "<< std::endl;
                                for (db::element::remote_node &r : params.path) {
                                    WDEBUG <<  r.id << std::endl;
                                }
                                WDEBUG << std::endl;
                                WDEBUG  << "returning to node " << prev_node.id << " in positive cache response " << std::endl;
                                return {std::make_pair(prev_node, params)}; // single length vector
                            } else {
                                cache_response->invalidate();
                            }
                        }
                    }

                    for (edge &e: n.get_edges()) {
                        // checking edge properties
                        if (e.has_all_properties(params.edge_props)) {
                            // e->traverse(); no more traversal recording

                            // propagate reachability request
                            next.emplace_back(std::make_pair(e.get_neighbor(), params));
                            WDEBUG  << "emplacing " << e.get_neighbor().id << " to next" << std::endl;
                            state.out_count++;
                        }
                    }
                    if (state.out_count == 0) {
                        false_reply = true;
                    }
                } else {
                    false_reply = true;
                }
            }
            if (false_reply) {
                params.returning = true;
                params.reachable = false;
                next.emplace_back(std::make_pair(prev_node, params));
            }
        } else { // reply mode
            if (params.reachable) {
                if (state.hops > params.hops) {
                    state.hops = params.hops;
                }
            }
            if (((--state.out_count == 0) || params.reachable) && !state.reachable) {
                state.reachable |= params.reachable;
                if (params.reachable) {
                    params.hops = state.hops + 1;
                    params.path.emplace_back(rn);
                    if (MAX_CACHE_ENTRIES)
                    {
                        // now add to cache
                        WDEBUG << "adding to cache for key " << params.dest << " on way back from dest on node " << rn.id << " with path len " << params.path.size() << std::endl;
                        WDEBUG << "path is "<< std::endl;
                        for (db::element::remote_node &r : params.path) {
                            WDEBUG <<  r.id<< std::endl;
                        }
                        WDEBUG << std::endl;
                        std::shared_ptr<node_prog::reach_cache_value> toCache(new reach_cache_value(params.path));
                        std::shared_ptr<std::vector<db::element::remote_node>> watch_set(new std::vector<db::element::remote_node>(params.path)); // copy return path from params
                        add_cache_func(toCache, watch_set, params.dest);
                    }
                }
                next.emplace_back(std::make_pair(state.prev_node, params));
            }
            if ((int)state.out_count < 0) {
                WDEBUG << "ALERT! Bad state value in reach program" << std::endl;
                next.clear();
            }
        }
        WDEBUG << "propagating to "<< std::endl;
        for (auto &pair : next) {
            WDEBUG << pair.first.id << std::endl;
        }
        WDEBUG << std::endl;
        return next;
    }
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 *******************************************************************************/
#ifndef GUARD_TENSOR_HOLDER_HPP
#define GUARD_TENSOR_HOLDER_HPP

#include "ford.hpp"
#include "network_data.hpp"
#include <miopen/tensor.hpp>
#include <miopen/functional.hpp>

template <class F>
void visit_tensor_size(std::size_t n, F f)
{
    switch(n)
    {
    case 0:
    {
        f(std::integral_constant<std::size_t, 0>{});
        break;
    }
    case 1:
    {
        f(std::integral_constant<std::size_t, 1>{});
        break;
    }
    case 2:
    {
        f(std::integral_constant<std::size_t, 2>{});
        break;
    }
    case 3:
    {
        f(std::integral_constant<std::size_t, 3>{});
        break;
    }
    case 4:
    {
        f(std::integral_constant<std::size_t, 4>{});
        break;
    }
    case 5:
    {
        f(std::integral_constant<std::size_t, 5>{});
        break;
    }
    default: throw std::runtime_error("Unknown tensor size");
    }
}

template <class T>
struct tensor
{
    miopen::TensorDescriptor desc;
    std::vector<T> data;

    tensor() {}

    template <class X>
    tensor(const std::vector<X>& dims)
        : desc(miopenFloat, dims.data(), static_cast<int>(dims.size())), data(desc.GetElementSize())
    {
    }

    tensor(std::size_t n, std::size_t c, std::size_t h, std::size_t w)
        : desc(miopenFloat, {n, c, h, w}), data(n * c * h * w)
    {
    }

    tensor(miopen::TensorDescriptor rhs) : desc(std::move(rhs))
    {
        data.resize(desc.GetElementSize());
    }

    template <class G>
    tensor& generate(G g) &
    {
        this->generate_impl(g);
        return *this;
    }

    template <class G>
    tensor&& generate(G g) &&
    {
        this->generate_impl(g);
        return std::move(*this);
    }

    template <class G>
    void generate_impl(G g)
    {
        auto iterator = data.begin();
        auto assign = [&](T x)
        {
           assert(iterator < data.end());
            *iterator = x;
            ++iterator;
        };
        this->for_each(miopen::compose(assign, std::move(g)));
    }

    template <class Loop, class F>
    struct for_each_unpacked
    {
        Loop loop;
        F f;
        template <class... Ts>
        auto operator()(Ts... xs) const -> decltype(f(xs...), void())
        {
            loop(xs...)(std::move(f));
        }

        void operator()(...) const
        {
            throw std::runtime_error("Arguments to for_each do not match tensor size");
        }
    };

    struct for_each_handler
    {
        template <class Self, class Loop, class F, class Size>
        void operator()(Self* self, Loop loop, F f, Size size) const
        {
            auto dims = miopen::tien<size>(self->desc.GetLengths());
            miopen::unpack(for_each_unpacked<Loop, F>{loop, std::move(f)}, dims);
        }
    };

    template <class F>
    void for_each(F f) const
    {
        visit_tensor_size(
            desc.GetLengths().size(),
            std::bind(for_each_handler{}, this, ford, std::move(f), std::placeholders::_1));
    }

    template <class F>
    void par_for_each(F f) const
    {
        visit_tensor_size(
            desc.GetLengths().size(),
            std::bind(for_each_handler{}, this, par_ford, std::move(f), std::placeholders::_1));
    }

    template <class... Ts>
    T& operator()(Ts... xs)
    {
        assert(this->desc.GetIndex(xs...) < data.size());
        return this->data[this->desc.GetIndex(xs...)];
    }

    template <class... Ts>
    const T& operator()(Ts... xs) const
    {
        assert(this->desc.GetIndex(xs...) < data.size());
        return this->data[this->desc.GetIndex(xs...)];
    }

    T& operator[](std::size_t i) { return data.at(i); }

    const T& operator[](std::size_t i) const { return data.at(i); }

    typename std::vector<T>::iterator begin() { return data.begin(); }

    typename std::vector<T>::iterator end() { return data.end(); }

    typename std::vector<T>::const_iterator begin() const { return data.begin(); }

    typename std::vector<T>::const_iterator end() const { return data.end(); }
};

template <class T, class G>
tensor<T> make_tensor(std::initializer_list<std::size_t> dims, G g)
{
    // TODO: Compute float
    return tensor<T>{miopen::TensorDescriptor{miopenFloat, dims}}.generate(g);
}

template <class T, class X>
tensor<T> make_tensor(const std::vector<X>& dims)
{
    // TODO: Compute float
    return tensor<T>{
        miopen::TensorDescriptor{miopenFloat, dims.data(), static_cast<int>(dims.size())}};
}

template <class T, class X, class G>
tensor<T> make_tensor(const std::vector<X>& dims, G g)
{
    return make_tensor<T>(dims).generate(g);
}

struct tensor_generate
{
    template <class Tensor, class G>
    Tensor&& operator()(Tensor&& t, G g) const
    {
        return std::forward<Tensor>(t.generate(g));
    }
};

template <class F>
struct protect_void_fn
{
    F f;
    protect_void_fn(F x) : f(std::move(x)) {}

    // template<class... Ts>
    // auto operator()(Ts&&... xs) const MIOPEN_RETURNS
    // (f(std::forward<Ts>(xs)...));

    template <class... Ts>
    void operator()(Ts&&... xs) const
    {
        f(std::forward<Ts>(xs)...);
    }
};

template <class F>
protect_void_fn<F> protect_void(F f)
{
    return {std::move(f)};
}

struct cross_args_apply
{
    template <class F, class T, class... Ts>
    void operator()(F f, T&& x, Ts&&... xs) const
    {
        miopen::each_args(std::bind(f, std::forward<T>(x), std::placeholders::_1),
                          std::forward<Ts>(xs)...);
    }
};

template <class F, class... Ts>
void cross_args(F f, Ts&&... xs)
{
    miopen::each_args(std::bind(cross_args_apply{},
                                protect_void(std::move(f)),
                                std::placeholders::_1,
                                std::forward<Ts>(xs)...),
                      std::forward<Ts>(xs)...);
}

template <class T>
struct generate_both_visitation
{
    template <class F, class G1, class G2>
    void operator()(F f, G1 g1, G2 g2) const
    {
        for(auto&& input : get_inputs())
            for(auto&& weights : get_weights())
                if(input.at(1) == weights.at(1)) // channels must match
                    f(make_tensor<T>(input, g1), make_tensor<T>(weights, g2));
    }
};

template <class T, class F, class... Gs>
void generate_binary_all(F f, Gs... gs)
{
    cross_args(std::bind(generate_both_visitation<T>{},
                         protect_void(f),
                         std::placeholders::_1,
                         std::placeholders::_2),
               gs...);
}

template <class T, class F, class G>
void generate_binary_one(F f, std::vector<int> input, std::vector<int> weights, G g)
{
    f(make_tensor<T>(input, g), make_tensor<T>(weights, g));
}

template <class T>
struct generate_activ_visitation
{
    template <class F, class G>
    void operator()(F f, G g) const
    {
        for(auto&& input : get_inputs())
            f(make_tensor<T>(input, g));
    }
};

template <class T, class F, class... Gs>
void generate_unary_all(F f, Gs... gs)
{
    miopen::each_args(
        std::bind(generate_activ_visitation<T>{}, protect_void(f), std::placeholders::_1), gs...);
}

template <class T, class F, class G>
void generate_unary_one(F f, std::vector<int> input, G g)
{
    f(make_tensor<T>(input, g));
}

#endif
<commit_msg>One more try at merge.<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 *******************************************************************************/
#ifndef GUARD_TENSOR_HOLDER_HPP
#define GUARD_TENSOR_HOLDER_HPP

#include "ford.hpp"
#include "network_data.hpp"
#include <miopen/tensor.hpp>
#include <miopen/functional.hpp>

template <class F>
void visit_tensor_size(std::size_t n, F f)
{
    switch(n)
    {
    case 0:
    {
        f(std::integral_constant<std::size_t, 0>{});
        break;
    }
    case 1:
    {
        f(std::integral_constant<std::size_t, 1>{});
        break;
    }
    case 2:
    {
        f(std::integral_constant<std::size_t, 2>{});
        break;
    }
    case 3:
    {
        f(std::integral_constant<std::size_t, 3>{});
        break;
    }
    case 4:
    {
        f(std::integral_constant<std::size_t, 4>{});
        break;
    }
    case 5:
    {
        f(std::integral_constant<std::size_t, 5>{});
        break;
    }
    default: throw std::runtime_error("Unknown tensor size");
    }
}

template <class T>
struct tensor
{
    miopen::TensorDescriptor desc;
    std::vector<T> data;

    tensor() {}

    template <class X>
    tensor(const std::vector<X>& dims)
        : desc(miopenFloat, dims.data(), static_cast<int>(dims.size())), data(desc.GetElementSize())
    {
    }

    tensor(std::size_t n, std::size_t c, std::size_t h, std::size_t w)
        : desc(miopenFloat, {n, c, h, w}), data(n * c * h * w)
    {
    }

    tensor(miopen::TensorDescriptor rhs) : desc(std::move(rhs))
    {
        data.resize(desc.GetElementSize());
    }

    template <class G>
    tensor& generate(G g) &
    {
        this->generate_impl(g);
        return *this;
    }

    template <class G>
    tensor&& generate(G g) &&
    {
        this->generate_impl(g);
        return std::move(*this);
    }

    template <class G>
    void generate_impl(G g)
    {
        auto iterator = data.begin();
        auto assign = [&](T x)
        {
           assert(iterator < data.end());
            *iterator = x;
            ++iterator;
        };
        this->for_each(miopen::compose(assign, std::move(g)));
    }

    template <class Loop, class F>
    struct for_each_unpacked
    {
        Loop loop;
        F f;
        template <class... Ts>
        auto operator()(Ts... xs) const -> decltype(f(xs...), void())
        {
            loop(xs...)(std::move(f));
        }

        void operator()(...) const
        {
            throw std::runtime_error("Arguments to for_each do not match tensor size");
        }
    };

    struct for_each_handler
    {
        template <class Self, class Loop, class F, class Size>
        void operator()(Self* self, Loop loop, F f, Size size) const
        {
            auto dims = miopen::tien<size>(self->desc.GetLengths());
            miopen::unpack(for_each_unpacked<Loop, F>{loop, std::move(f)}, dims);
        }
    };

    template <class F>
    void for_each(F f) const
    {
        visit_tensor_size(
            desc.GetLengths().size(),
            std::bind(for_each_handler{}, this, ford, std::move(f), std::placeholders::_1));
    }

    template <class F>
    void par_for_each(F f) const
    {
        visit_tensor_size(
            desc.GetLengths().size(),
            std::bind(for_each_handler{}, this, par_ford, std::move(f), std::placeholders::_1));
    }

    template <class... Ts>
    T& operator()(Ts... ds)
    {
        assert(this->desc.GetIndex(ds...) < data.size());
        return this->data[this->desc.GetIndex(ds...)];
    }

    template <class... Ts>
    const T& operator()(Ts... xs) const
    {
        assert(this->desc.GetIndex(xs...) < data.size());
        return this->data[this->desc.GetIndex(xs...)];
    }

    T& operator[](std::size_t i) { return data.at(i); }

    const T& operator[](std::size_t i) const { return data.at(i); }

    typename std::vector<T>::iterator begin() { return data.begin(); }

    typename std::vector<T>::iterator end() { return data.end(); }

    typename std::vector<T>::const_iterator begin() const { return data.begin(); }

    typename std::vector<T>::const_iterator end() const { return data.end(); }
};

template <class T, class G>
tensor<T> make_tensor(std::initializer_list<std::size_t> dims, G g)
{
    // TODO: Compute float
    return tensor<T>{miopen::TensorDescriptor{miopenFloat, dims}}.generate(g);
}

template <class T, class X>
tensor<T> make_tensor(const std::vector<X>& dims)
{
    // TODO: Compute float
    return tensor<T>{
        miopen::TensorDescriptor{miopenFloat, dims.data(), static_cast<int>(dims.size())}};
}

template <class T, class X, class G>
tensor<T> make_tensor(const std::vector<X>& dims, G g)
{
    return make_tensor<T>(dims).generate(g);
}

struct tensor_generate
{
    template <class Tensor, class G>
    Tensor&& operator()(Tensor&& t, G g) const
    {
        return std::forward<Tensor>(t.generate(g));
    }
};

template <class F>
struct protect_void_fn
{
    F f;
    protect_void_fn(F x) : f(std::move(x)) {}

    // template<class... Ts>
    // auto operator()(Ts&&... xs) const MIOPEN_RETURNS
    // (f(std::forward<Ts>(xs)...));

    template <class... Ts>
    void operator()(Ts&&... xs) const
    {
        f(std::forward<Ts>(xs)...);
    }
};

template <class F>
protect_void_fn<F> protect_void(F f)
{
    return {std::move(f)};
}

struct cross_args_apply
{
    template <class F, class T, class... Ts>
    void operator()(F f, T&& x, Ts&&... xs) const
    {
        miopen::each_args(std::bind(f, std::forward<T>(x), std::placeholders::_1),
                          std::forward<Ts>(xs)...);
    }
};

template <class F, class... Ts>
void cross_args(F f, Ts&&... xs)
{
    miopen::each_args(std::bind(cross_args_apply{},
                                protect_void(std::move(f)),
                                std::placeholders::_1,
                                std::forward<Ts>(xs)...),
                      std::forward<Ts>(xs)...);
}

template <class T>
struct generate_both_visitation
{
    template <class F, class G1, class G2>
    void operator()(F f, G1 g1, G2 g2) const
    {
        for(auto&& input : get_inputs())
            for(auto&& weights : get_weights())
                if(input.at(1) == weights.at(1)) // channels must match
                    f(make_tensor<T>(input, g1), make_tensor<T>(weights, g2));
    }
};

template <class T, class F, class... Gs>
void generate_binary_all(F f, Gs... gs)
{
    cross_args(std::bind(generate_both_visitation<T>{},
                         protect_void(f),
                         std::placeholders::_1,
                         std::placeholders::_2),
               gs...);
}

template <class T, class F, class G>
void generate_binary_one(F f, std::vector<int> input, std::vector<int> weights, G g)
{
    f(make_tensor<T>(input, g), make_tensor<T>(weights, g));
}

template <class T>
struct generate_activ_visitation
{
    template <class F, class G>
    void operator()(F f, G g) const
    {
        for(auto&& input : get_inputs())
            f(make_tensor<T>(input, g));
    }
};

template <class T, class F, class... Gs>
void generate_unary_all(F f, Gs... gs)
{
    miopen::each_args(
        std::bind(generate_activ_visitation<T>{}, protect_void(f), std::placeholders::_1), gs...);
}

template <class T, class F, class G>
void generate_unary_one(F f, std::vector<int> input, G g)
{
    f(make_tensor<T>(input, g));
}

#endif
<|endoftext|>


<commit_before>#include <cppcutter.h>
#include "tuishogi.cpp"

namespace tuishogi {

void
test_showState(void)
{
  // Arrange
  using namespace osl;
  std::stringbuf  string_out;
  std::streambuf* std_out = std::cout.rdbuf(&string_out);
  NumEffectState state((SimpleState(HIRATE)));
  const char* expected = "\
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY\n\
P2 * -HI *  *  *  *  * -KA * \n\
P3-FU-FU-FU-FU-FU-FU-FU-FU-FU\n\
P4 *  *  *  *  *  *  *  *  * \n\
P5 *  *  *  *  *  *  *  *  * \n\
P6 *  *  *  *  *  *  *  *  * \n\
P7+FU+FU+FU+FU+FU+FU+FU+FU+FU\n\
P8 * +KA *  *  *  *  * +HI * \n\
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY\n\
+\n\
\n";

  // Act
  showState(state);

  std::cout << std::flush;
  std::cout.rdbuf(std_out);

  // TODO assert it as a std::string
  std::string str = string_out.str();
  const char* actual = str.c_str();

  // Assert
  cut_assert_equal_string(expected, actual);
}

void
test_isMated(void)
{
  using namespace osl;
  NumEffectState state((SimpleState(HIRATE)));
  bool mated = isMated(state);
  cut_assert_false(mated);
}

void
test_computerOperate(void)
{
  using namespace osl;
  // TODO cleanup
  std::stringbuf  string_out;
  std::streambuf* std_out = std::cout.rdbuf(&string_out);
  NumEffectState state((SimpleState(HIRATE)));
  bool ended = computerOperate(state);
  std::cout << std::flush;
  std::cout.rdbuf(std_out);
  cut_assert_false(ended);
}

}  // namespace tuishogi
<commit_msg>Add tests for playerOperate()<commit_after>#include <cppcutter.h>
#include "tuishogi.cpp"

namespace tuishogi {

void
test_showState(void)
{
  // Arrange
  using namespace osl;
  std::stringbuf  string_out;
  std::streambuf* std_out = std::cout.rdbuf(&string_out);
  NumEffectState state((SimpleState(HIRATE)));
  const char* expected = "\
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY\n\
P2 * -HI *  *  *  *  * -KA * \n\
P3-FU-FU-FU-FU-FU-FU-FU-FU-FU\n\
P4 *  *  *  *  *  *  *  *  * \n\
P5 *  *  *  *  *  *  *  *  * \n\
P6 *  *  *  *  *  *  *  *  * \n\
P7+FU+FU+FU+FU+FU+FU+FU+FU+FU\n\
P8 * +KA *  *  *  *  * +HI * \n\
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY\n\
+\n\
\n";

  // Act
  showState(state);

  std::cout << std::flush;
  std::cout.rdbuf(std_out);

  // TODO assert it as a std::string
  std::string str = string_out.str();
  const char* actual = str.c_str();

  // Assert
  cut_assert_equal_string(expected, actual);
}

void
test_isMated(void)
{
  using namespace osl;
  NumEffectState state((SimpleState(HIRATE)));
  bool mated = isMated(state);
  cut_assert_false(mated);
}

void
test_computerOperate(void)
{
  using namespace osl;
  // TODO cleanup
  std::stringbuf  string_out;
  std::streambuf* std_out = std::cout.rdbuf(&string_out);
  NumEffectState state((SimpleState(HIRATE)));
  bool ended = computerOperate(state);
  std::cout << std::flush;
  std::cout.rdbuf(std_out);
  cut_assert_false(ended);
}

void
test_playerOperate_valid(void)
{
  using namespace osl;
  // TODO cleanup
  std::stringbuf  string_out;
  std::streambuf* std_out = std::cout.rdbuf(&string_out);
  NumEffectState state((SimpleState(HIRATE)));
  bool failed = playerOperate(state, "+7776FU");
  std::cout << std::flush;
  std::cout.rdbuf(std_out);
  cut_assert_false(failed);
}

void
test_playerOperate_invalid(void)
{
  using namespace osl;
  // TODO cleanup
  std::stringbuf  string_out;
  std::streambuf* std_out = std::cout.rdbuf(&string_out);
  NumEffectState state((SimpleState(HIRATE)));
  bool failed = playerOperate(state, "+5251FU");
  std::cout << std::flush;
  std::cout.rdbuf(std_out);
  cut_assert_true(failed);
}

}  // namespace tuishogi
<|endoftext|>


<commit_before>#include "testsettings.hpp"

#include <realm/util/optional.hpp>

#include "test.hpp"

using namespace realm::util;

TEST(Optional_DefaultConstructor)
{
    Optional<int> x{};
    CHECK(!bool(x));
}

TEST(Optional_NoneConstructor)
{
    Optional<int> x{realm::none};
    CHECK(!bool(x));
}

TEST(Optional_ValueConstructor)
{
    Optional<std::string> a { "foo" };
    CHECK(bool(a));
}

TEST(Optional_MoveConstructor)
{
    Optional<std::string> a { "foo" };
    Optional<std::string> b { std::move(a) };
    CHECK(bool(a));
    CHECK(bool(b));
    CHECK_EQUAL(*a, "");
    CHECK_EQUAL(*b, "foo");
}

TEST(Optional_CopyConstructor)
{
    Optional<std::string> a { "foo" };
    Optional<std::string> b { a };
    CHECK(bool(a));
    CHECK(bool(b));
    CHECK_EQUAL(*a, "foo");
    CHECK_EQUAL(*b, "foo");
}

TEST(Optional_MoveValueConstructor)
{
    std::string a = "foo";
    Optional<std::string> b { std::move(a) };
    CHECK(bool(b));
    CHECK_EQUAL(*b, "foo");
    CHECK_EQUAL(a, "");
}

struct SetBooleanOnDestroy {
    bool& m_b;
    explicit SetBooleanOnDestroy(bool& b) : m_b(b) {}
    ~SetBooleanOnDestroy() { m_b = true; }
};

TEST(Optional_Destructor)
{
    bool b = false;
    {
        Optional<SetBooleanOnDestroy> x { SetBooleanOnDestroy(b) };
    }
    CHECK(b);
}

TEST(Optional_DestroyOnAssignNone)
{
    bool b = false;
    {
        Optional<SetBooleanOnDestroy> x { SetBooleanOnDestroy(b) };
        x = realm::none;
        CHECK(b);
    }
    CHECK(b);
}

TEST(Optional_References)
{
    int n = 0;
    Optional<int&> x { n };
    fmap(x, [&](int& y) {
        y = 123;
    });
    CHECK(x);
    CHECK_EQUAL(x.value(), 123);
    x = realm::none;
    CHECK(!x);
}

TEST(Optional_PolymorphicReferences)
{
    struct Foo {
        virtual ~Foo() {}
    };
    struct Bar: Foo {
        virtual ~Bar() {}
    };

    Bar bar;
    Optional<Bar&> bar_ref { bar };
    Optional<Foo&> foo_ref { bar_ref };
    CHECK(foo_ref);
    CHECK_EQUAL(&foo_ref.value(), &bar);
 }

namespace {

int make_rvalue()
{
    return 1;
}

}

TEST(Optional_RvalueReferences)
{
    // Should compile:
    const int foo = 1;
    Optional<const int&> x{foo};
    static_cast<void>(x);

    static_cast<void>(make_rvalue);
    // Should not compile (would generate references to temporaries):
    // Optional<const int&> y{1};
    // Optional<const int&> z = 1;
    // Optional<const int&> w = make_rvalue();
}

namespace {

/// See:
/// http://www.boost.org/doc/libs/1_57_0/libs/optional/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html

const int global_i = 0;

struct TestingReferenceBinding {
    TestingReferenceBinding(const int& ii)
    {
        REALM_ASSERT(&ii == &global_i);
    }

    void operator=(const int& ii)
    {
        REALM_ASSERT(&ii == &global_i);
    }

    void operator=(int&&)
    {
        REALM_ASSERT(false);
    }
};
}

TEST(Optional_ReferenceBinding)
{
    const int& iref = global_i;
    CHECK_EQUAL(&iref, &global_i);
    TestingReferenceBinding ttt = global_i;
    ttt = global_i;
    TestingReferenceBinding ttt2 = iref;
    ttt2 = iref;
}

TEST(Optional_VoidIsEquivalentToBool)
{
    auto a = some<void>();
    CHECK_EQUAL(sizeof(a), sizeof(bool));
    CHECK(a);
    Optional<void> b = none;
    CHECK_EQUAL(sizeof(b), sizeof(bool));
    CHECK(!b);
}

TEST(Optional_fmap)
{
    Optional<int> a { 123 };
    bool a_called = false;
    auto ar = fmap(a, [&](int) {
        a_called = true;
    });
    CHECK(a_called);
    CHECK(ar);

    Optional<int> b { 123 };
    auto bs = fmap(b, [](int foo) {
        std::stringstream ss;
        ss << foo;
        return ss.str();
    });
    CHECK(bs);
    CHECK_EQUAL(*bs, "123");

    Optional<int> c;
    Optional<int> cx = fmap(c, [](int) { return 0; });
    CHECK(!cx);
}

TEST(Optional_StreamingMap)
{
    Optional<int> a { 123 };

    auto result = a
        >> [](int b) { return b + 200; }
        >> [](int c) {
            std::ostringstream os;
            os << c;
            return os.str();
        };
    CHECK(result);
    CHECK_EQUAL(result.value(), "323");

    Optional<int> b { 500 };
    Optional<int> result2 = b
        >> [](int x) { return x > 300 ? some<int>(x + 300) : none; };
    CHECK(result2);
}
<commit_msg>Added test for optional chaining.<commit_after>#include "testsettings.hpp"

#include <realm/util/optional.hpp>

#include "test.hpp"

using namespace realm::util;

TEST(Optional_DefaultConstructor)
{
    Optional<int> x{};
    CHECK(!bool(x));
}

TEST(Optional_NoneConstructor)
{
    Optional<int> x{realm::none};
    CHECK(!bool(x));
}

TEST(Optional_ValueConstructor)
{
    Optional<std::string> a { "foo" };
    CHECK(bool(a));
}

TEST(Optional_MoveConstructor)
{
    Optional<std::string> a { "foo" };
    Optional<std::string> b { std::move(a) };
    CHECK(bool(a));
    CHECK(bool(b));
    CHECK_EQUAL(*a, "");
    CHECK_EQUAL(*b, "foo");
}

TEST(Optional_CopyConstructor)
{
    Optional<std::string> a { "foo" };
    Optional<std::string> b { a };
    CHECK(bool(a));
    CHECK(bool(b));
    CHECK_EQUAL(*a, "foo");
    CHECK_EQUAL(*b, "foo");
}

TEST(Optional_MoveValueConstructor)
{
    std::string a = "foo";
    Optional<std::string> b { std::move(a) };
    CHECK(bool(b));
    CHECK_EQUAL(*b, "foo");
    CHECK_EQUAL(a, "");
}

struct SetBooleanOnDestroy {
    bool& m_b;
    explicit SetBooleanOnDestroy(bool& b) : m_b(b) {}
    ~SetBooleanOnDestroy() { m_b = true; }
};

TEST(Optional_Destructor)
{
    bool b = false;
    {
        Optional<SetBooleanOnDestroy> x { SetBooleanOnDestroy(b) };
    }
    CHECK(b);
}

TEST(Optional_DestroyOnAssignNone)
{
    bool b = false;
    {
        Optional<SetBooleanOnDestroy> x { SetBooleanOnDestroy(b) };
        x = realm::none;
        CHECK(b);
    }
    CHECK(b);
}

TEST(Optional_References)
{
    int n = 0;
    Optional<int&> x { n };
    fmap(x, [&](int& y) {
        y = 123;
    });
    CHECK(x);
    CHECK_EQUAL(x.value(), 123);
    x = realm::none;
    CHECK(!x);
}

TEST(Optional_PolymorphicReferences)
{
    struct Foo {
        virtual ~Foo() {}
    };
    struct Bar: Foo {
        virtual ~Bar() {}
    };

    Bar bar;
    Optional<Bar&> bar_ref { bar };
    Optional<Foo&> foo_ref { bar_ref };
    CHECK(foo_ref);
    CHECK_EQUAL(&foo_ref.value(), &bar);
 }

namespace {

int make_rvalue()
{
    return 1;
}

}

TEST(Optional_RvalueReferences)
{
    // Should compile:
    const int foo = 1;
    Optional<const int&> x{foo};
    static_cast<void>(x);

    static_cast<void>(make_rvalue);
    // Should not compile (would generate references to temporaries):
    // Optional<const int&> y{1};
    // Optional<const int&> z = 1;
    // Optional<const int&> w = make_rvalue();
}

namespace {

/// See:
/// http://www.boost.org/doc/libs/1_57_0/libs/optional/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html

const int global_i = 0;

struct TestingReferenceBinding {
    TestingReferenceBinding(const int& ii)
    {
        REALM_ASSERT(&ii == &global_i);
    }

    void operator=(const int& ii)
    {
        REALM_ASSERT(&ii == &global_i);
    }

    void operator=(int&&)
    {
        REALM_ASSERT(false);
    }
};
}

TEST(Optional_ReferenceBinding)
{
    const int& iref = global_i;
    CHECK_EQUAL(&iref, &global_i);
    TestingReferenceBinding ttt = global_i;
    ttt = global_i;
    TestingReferenceBinding ttt2 = iref;
    ttt2 = iref;
}

TEST(Optional_VoidIsEquivalentToBool)
{
    auto a = some<void>();
    CHECK_EQUAL(sizeof(a), sizeof(bool));
    CHECK(a);
    Optional<void> b = none;
    CHECK_EQUAL(sizeof(b), sizeof(bool));
    CHECK(!b);
}

TEST(Optional_fmap)
{
    Optional<int> a { 123 };
    bool a_called = false;
    auto ar = fmap(a, [&](int) {
        a_called = true;
    });
    CHECK(a_called);
    CHECK(ar);

    Optional<int> b { 123 };
    auto bs = fmap(b, [](int foo) {
        std::stringstream ss;
        ss << foo;
        return ss.str();
    });
    CHECK(bs);
    CHECK_EQUAL(*bs, "123");

    Optional<int> c;
    Optional<int> cx = fmap(c, [](int) { return 0; });
    CHECK(!cx);
}

TEST(Optional_StreamingMap)
{
    Optional<int> a { 123 };

    auto result = a
        >> [](int b) { return b + 200; }
        >> [](int c) {
            std::ostringstream os;
            os << c;
            return os.str();
        };
    CHECK(result);
    CHECK_EQUAL(result.value(), "323");

    Optional<int> b { 500 };
    Optional<int> result2 = b
        >> [](int x) { return x > 300 ? some<int>(x + 300) : none; };
    CHECK(result2);
}

TEST(Optional_Chaining)
{
    struct Foo {
        int bar() { return 123; }
    };
    Optional<Foo> foo { Foo{} };
    auto r = foo >> std::mem_fn(&Foo::bar);
    CHECK(r);
    CHECK_EQUAL(r.value(), 123);
}
<|endoftext|>


<commit_before>#include <babylon/GL/framebuffer_canvas.h>
#include <babylon/babylon_imgui/babylon_logs_window.h>
#include <babylon/babylon_imgui/babylon_studio.h>
#include <babylon/core/filesystem.h>
#include <babylon/core/system.h>
#include <babylon/inspector/components/actiontabs/action_tabs_component.h>
#include <babylon/interfaces/irenderable_scene_with_hud.h>
#include <imgui.h>
#include <imgui_internal.h>
#include <imgui_utils/app_runner/imgui_runner.h>
#include <imgui_utils/icons_font_awesome_5.h>

#include <babylon/babylon_imgui/babylon_studio_layout.h>
#include <babylon/core/logging.h>
#include <babylon/samples/samples_index.h>

#ifdef _WIN32
#include <windows.h>
#endif

#include <iostream>

namespace BABYLON {

class BabylonStudioApp {
public:
  BabylonStudioApp()
  {
    std::string exePath        = BABYLON::System::getExecutablePath();
    std::string exeFolder      = BABYLON::Filesystem::baseDir(exePath);
    std::string playgroundPath = exeFolder + "/../../../src/BabylonStudio/playground.cpp";
    playgroundPath             = BABYLON::Filesystem::absolutePath(playgroundPath);
    _playgroundCodeEditor.setFiles({playgroundPath});
    _playgroundCodeEditor.setLightPalette();
  }

  void RunApp(std::shared_ptr<BABYLON::IRenderableScene> initialScene,
              const BabylonStudioOptions& options)
  {
    _appContext._options                              = options;
    _appContext._options._appWindowParams.ShowMenuBar = true;

    std::function<bool(void)> showGuiLambda = [this]() -> bool {
      bool r = this->render();
      for (auto f : _appContext._options._heartbeatCallbacks)
        f();
      if (_appContext._options._playgroundCompilerCallback) {
        PlaygroundCompilerStatus playgroundCompilerStatus
          = _appContext._options._playgroundCompilerCallback();
        if (playgroundCompilerStatus._renderableScene)
          setRenderableScene(playgroundCompilerStatus._renderableScene);
        _appContext._isCompiling = playgroundCompilerStatus._isCompiling;
      }
      return r;
    };

    auto initSceneLambda = [&]() {
      this->initScene();
      this->setRenderableScene(initialScene);
    };

    _appContext._options._appWindowParams.InitialDockLayoutFunction = [this](ImGuiID mainDockId) {
      _studioLayout.PrepareLayout(mainDockId);
    };
    ImGuiUtils::ImGuiRunner::RunGui(showGuiLambda, _appContext._options._appWindowParams,
                                    initSceneLambda);
  }

private:
  void registerRenderFunctions()
  {
    static bool registered = false;
    if (registered)
      return;

    // clang-format off
    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::Inspector,
      [this]() {
        if (_appContext._inspector)
          _appContext._inspector->render();
      });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::Logs,
      []() { BABYLON::BabylonLogsWindow::instance().render(); });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::Scene3d,
      [this]() { render3d(); });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::SamplesCodeViewer,
      [this]() { _samplesCodeEditor.render(); });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::SampleBrowser,
      [this]() { _appContext._sampleListComponent.render(); });

#ifdef BABYLON_BUILD_PLAYGROUND
    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::PlaygroundEditor,
      [this]() { renderPlayground(); });
#endif

    // clang-format on

    registered = true;
  }

  void initScene()
  {
    _appContext._sampleListComponent.OnNewRenderableScene
      = [&](std::shared_ptr<IRenderableScene> scene) {
          this->setRenderableScene(scene);
          _studioLayout.FocusWindow(DockableWindowId::Scene3d);
        };

    _appContext._sampleListComponent.OnEditFiles = [&](const std::vector<std::string>& files) {
      _samplesCodeEditor.setFiles(files);
      _studioLayout.setVisible(DockableWindowId::SamplesCodeViewer, true);
      _studioLayout.FocusWindow(DockableWindowId::SamplesCodeViewer);
    };

    _appContext._sampleListComponent.OnLoopSamples = [&](const std::vector<std::string>& samples) {
      _appContext._loopSamples.flagLoop      = true;
      _appContext._loopSamples.samplesToLoop = samples;
      _appContext._loopSamples.currentIdx    = 0;
    };

    _appContext._sceneWidget = std::make_unique<BABYLON::ImGuiSceneWidget>(ImVec2(640.f, 480.f));
    _appContext._sceneWidget->OnBeforeResize.push_back(
      [this]() { _appContext._inspector.release(); });
  }

  void prepareSceneInspector()
  {
    auto currentScene = _appContext._sceneWidget->getScene();
    if ((!_appContext._inspector) || (_appContext._inspector->scene() != currentScene)) {
      _appContext._inspector
        = std::make_unique<BABYLON::Inspector>(nullptr, _appContext._sceneWidget->getScene());
      _appContext._inspector->setScene(currentScene);
    }
  }

  // returns true if exit required
  bool renderMenu()
  {
    ImGui::GetCurrentWindow()->Flags = ImGui::GetCurrentWindow()->Flags | ImGuiWindowFlags_MenuBar;
    bool shallExit                   = false;
    if (ImGui::BeginMenuBar())
    {
      if (ImGui::BeginMenu("File"))
      {
        if (ImGui::MenuItem("Quit"))
          shallExit = true;
        ImGui::EndMenu();
      }
      _studioLayout.renderMenu();

      renderStatus();
      ImGui::EndMenuBar();
    }

    return shallExit;
  }

  void renderStatus()
  {
    ImVec4 statusTextColor{ 0.8f, 0.8f, 0.3f, 1.f };
    if (_studioLayout.isVisible(DockableWindowId::Scene3d))
    {
      ImGui::SameLine(ImGui::GetIO().DisplaySize.x / 2.f);
      std::string sceneName = _appContext._sceneWidget->getRenderableScene()->getName();
      ImGui::TextColored(statusTextColor, "%s", sceneName.c_str());
    }

    ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 70.f);
    ImGui::TextColored(statusTextColor, "FPS: %.1f", ImGui::GetIO().Framerate);
  }

  // renders the GUI. Returns true when exit required
  bool render()
  {
    static bool wasInitialLayoutApplied = false;
    if (!wasInitialLayoutApplied)
    {
      this->_studioLayout.ApplyLayoutMode(LayoutMode::SceneAndBrowser);
      wasInitialLayoutApplied = true;
    }

    prepareSceneInspector();
    registerRenderFunctions();

    bool shallExit = renderMenu();
    _studioLayout.renderGui();

    handleLoopSamples();

    if (_appContext._options._flagScreenshotOneSampleAndExit)
      return saveScreenshot();
    else
      return shallExit;
  }

  void setRenderableScene(std::shared_ptr<BABYLON::IRenderableScene> scene)
  {
    if (_appContext._inspector)
      _appContext._inspector->setScene(nullptr);
    _appContext._sceneWidget->setRenderableScene(scene);
    if (_appContext._inspector)
      _appContext._inspector->setScene(_appContext._sceneWidget->getScene());
  }

  // Saves a screenshot after  few frames (eeturns true when done)
  bool saveScreenshot()
  {
    _appContext._frameCounter++;
    if (_appContext._frameCounter < 30)
      return false;
    int imageWidth = 200;
    int jpgQuality = 75;
    this->_appContext._sceneWidget->getCanvas()->saveScreenshotJpg(
      (_appContext._options._sceneName + ".jpg").c_str(), jpgQuality, imageWidth);
    return true;
  }

  bool ButtonInOverlayWindow(const std::string& label, ImVec2 position, ImVec2 size)
  {
    ImGui::SetNextWindowPos(position);
    ImGui::SetNextWindowSize(size);
    ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground;
    std::string id         = label + "##ButtonInOverlayWindow";
    ImGui::Begin(label.c_str(), nullptr, flags);
    bool clicked = ImGui::Button(label.c_str());
    ImGui::End();
    return clicked;
  }

  void renderHud(ImVec2 cursorScene3dTopLeft)
  {
    auto asSceneWithHud
      = dynamic_cast<IRenderableSceneWithHud*>(_appContext._sceneWidget->getRenderableScene());
    if (!asSceneWithHud)
      return;
    if (!asSceneWithHud->hudGui)
      return;

    static bool showHud = false;

    ImVec2 hudButtonPosition(cursorScene3dTopLeft.x + 2.f, cursorScene3dTopLeft.y + 2.f);
    ImVec2 hudWindowPosition(cursorScene3dTopLeft.x + 2.f, cursorScene3dTopLeft.y + 30.f);
    if (ButtonInOverlayWindow(ICON_FA_COG, hudButtonPosition, ImVec2(30.f, 30.f)))
      showHud = !showHud;

    if (showHud) {
      ImGui::SetNextWindowPos(hudWindowPosition, ImGuiCond_Once);
      ImGui::SetNextWindowBgAlpha(0.5f);
      ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize;
      ImGui::Begin("HUD", &showHud, flags);
      asSceneWithHud->hudGui();
      ImGui::End();
    }
  }

  void render3d()
  {
    ImVec2 sceneSize = ImGui::GetCurrentWindow()->Size;
    sceneSize.y -= 35.f;
    ImVec2 cursorPosBeforeScene3d = ImGui::GetCursorScreenPos();
    _appContext._sceneWidget->render(sceneSize);
    renderHud(cursorPosBeforeScene3d);
  }

  void renderPlayground()
  {
    ImGui::Button(ICON_FA_QUESTION_CIRCLE);
    if (ImGui::IsItemHovered())
      ImGui::SetTooltip(
        "Playground : you can edit the code below! As soon as you save it, the code will be "
        "compiled and the 3D scene "
        "will be updated");
    ImGui::SameLine();

    if (_appContext._isCompiling) {
      ImGui::TextColored(ImVec4(1., 0., 0., 1.), "Compiling");
      _studioLayout.setVisible(DockableWindowId::Logs, true);
    }
    if (ImGui::Button(ICON_FA_PLAY " Run"))
      _playgroundCodeEditor.saveAll();
    ImGui::SameLine();
    _playgroundCodeEditor.render();
  }

private:
  void handleLoopSamples()
  {
    if (!_appContext._loopSamples.flagLoop)
      return;

    static int frame_counter = 0;
    const int max_frames     = 60;

    if (frame_counter > max_frames) {
      std::string sampleName
        = _appContext._loopSamples.samplesToLoop[_appContext._loopSamples.currentIdx];
      BABYLON_LOG_ERROR("LoopSample", sampleName)
      auto scene = Samples::SamplesIndex::Instance().createRenderableScene(sampleName, nullptr);
      this->setRenderableScene(scene);

      if (_appContext._loopSamples.currentIdx < _appContext._loopSamples.samplesToLoop.size() - 2)
        _appContext._loopSamples.currentIdx++;
      else
        _appContext._loopSamples.flagLoop = false;

      frame_counter = 0;
    }
    else
      frame_counter++;
  }

  //
  // BabylonStudioContext
  //
  struct AppContext {
    std::unique_ptr<BABYLON::ImGuiSceneWidget> _sceneWidget;
    std::unique_ptr<BABYLON::Inspector> _inspector;
    BABYLON::SamplesBrowser _sampleListComponent;
    int _frameCounter = 0;
    BabylonStudioOptions _options;
    bool _isCompiling = false;

    struct {
      bool flagLoop     = false;
      size_t currentIdx = 0;
      std::vector<std::string> samplesToLoop;
    } _loopSamples;
  };

  AppContext _appContext;
  BabylonStudioLayout _studioLayout;
  ImGuiUtils::CodeEditor _samplesCodeEditor
    = ImGuiUtils::CodeEditor(true); // true <-> showCheckboxReadOnly
  ImGuiUtils::CodeEditor _playgroundCodeEditor;
}; // end of class BabylonInspectorApp

// public API
void runBabylonStudio(std::shared_ptr<BABYLON::IRenderableScene> scene,
                      BabylonStudioOptions options /* = SceneWithInspectorOptions() */
)
{
  BABYLON::BabylonStudioApp app;
  app.RunApp(scene, options);
}

} // namespace BABYLON
<commit_msg>Repair screenshot feature; readPixel works best with images width divisble by 4<commit_after>#include <babylon/GL/framebuffer_canvas.h>
#include <babylon/babylon_imgui/babylon_logs_window.h>
#include <babylon/babylon_imgui/babylon_studio.h>
#include <babylon/core/filesystem.h>
#include <babylon/core/system.h>
#include <babylon/inspector/components/actiontabs/action_tabs_component.h>
#include <babylon/interfaces/irenderable_scene_with_hud.h>
#include <imgui.h>
#include <imgui_internal.h>
#include <imgui_utils/app_runner/imgui_runner.h>
#include <imgui_utils/icons_font_awesome_5.h>

#include <babylon/babylon_imgui/babylon_studio_layout.h>
#include <babylon/core/logging.h>
#include <babylon/samples/samples_index.h>

#ifdef _WIN32
#include <windows.h>
#endif

#include <iostream>

namespace BABYLON {

class BabylonStudioApp {
public:
  BabylonStudioApp()
  {
    std::string exePath        = BABYLON::System::getExecutablePath();
    std::string exeFolder      = BABYLON::Filesystem::baseDir(exePath);
    std::string playgroundPath = exeFolder + "/../../../src/BabylonStudio/playground.cpp";
    playgroundPath             = BABYLON::Filesystem::absolutePath(playgroundPath);
    _playgroundCodeEditor.setFiles({playgroundPath});
    _playgroundCodeEditor.setLightPalette();
  }

  void RunApp(std::shared_ptr<BABYLON::IRenderableScene> initialScene,
              const BabylonStudioOptions& options)
  {
    _appContext._options                              = options;
    _appContext._options._appWindowParams.ShowMenuBar = true;

    std::function<bool(void)> showGuiLambda = [this]() -> bool {
      bool r = this->render();
      for (auto f : _appContext._options._heartbeatCallbacks)
        f();
      if (_appContext._options._playgroundCompilerCallback) {
        PlaygroundCompilerStatus playgroundCompilerStatus
          = _appContext._options._playgroundCompilerCallback();
        if (playgroundCompilerStatus._renderableScene)
          setRenderableScene(playgroundCompilerStatus._renderableScene);
        _appContext._isCompiling = playgroundCompilerStatus._isCompiling;
      }
      return r;
    };

    auto initSceneLambda = [&]() {
      this->initScene();
      this->setRenderableScene(initialScene);
    };

    _appContext._options._appWindowParams.InitialDockLayoutFunction = [this](ImGuiID mainDockId) {
      _studioLayout.PrepareLayout(mainDockId);
    };
    ImGuiUtils::ImGuiRunner::RunGui(showGuiLambda, _appContext._options._appWindowParams,
                                    initSceneLambda);
  }

private:
  void registerRenderFunctions()
  {
    static bool registered = false;
    if (registered)
      return;

    // clang-format off
    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::Inspector,
      [this]() {
        if (_appContext._inspector)
          _appContext._inspector->render();
      });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::Logs,
      []() { BABYLON::BabylonLogsWindow::instance().render(); });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::Scene3d,
      [this]() { render3d(); });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::SamplesCodeViewer,
      [this]() { _samplesCodeEditor.render(); });

    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::SampleBrowser,
      [this]() { _appContext._sampleListComponent.render(); });

#ifdef BABYLON_BUILD_PLAYGROUND
    _studioLayout.registerGuiRenderFunction(
      DockableWindowId::PlaygroundEditor,
      [this]() { renderPlayground(); });
#endif

    // clang-format on

    registered = true;
  }

  void initScene()
  {
    _appContext._sampleListComponent.OnNewRenderableScene
      = [&](std::shared_ptr<IRenderableScene> scene) {
          this->setRenderableScene(scene);
          _studioLayout.FocusWindow(DockableWindowId::Scene3d);
        };

    _appContext._sampleListComponent.OnEditFiles = [&](const std::vector<std::string>& files) {
      _samplesCodeEditor.setFiles(files);
      _studioLayout.setVisible(DockableWindowId::SamplesCodeViewer, true);
      _studioLayout.FocusWindow(DockableWindowId::SamplesCodeViewer);
    };

    _appContext._sampleListComponent.OnLoopSamples = [&](const std::vector<std::string>& samples) {
      _appContext._loopSamples.flagLoop      = true;
      _appContext._loopSamples.samplesToLoop = samples;
      _appContext._loopSamples.currentIdx    = 0;
    };

    _appContext._sceneWidget = std::make_unique<BABYLON::ImGuiSceneWidget>(ImVec2(640.f, 480.f));
    _appContext._sceneWidget->OnBeforeResize.push_back(
      [this]() { _appContext._inspector.release(); });
  }

  void prepareSceneInspector()
  {
    auto currentScene = _appContext._sceneWidget->getScene();
    if ((!_appContext._inspector) || (_appContext._inspector->scene() != currentScene)) {
      _appContext._inspector
        = std::make_unique<BABYLON::Inspector>(nullptr, _appContext._sceneWidget->getScene());
      _appContext._inspector->setScene(currentScene);
    }
  }

  // returns true if exit required
  bool renderMenu()
  {
    ImGui::GetCurrentWindow()->Flags = ImGui::GetCurrentWindow()->Flags | ImGuiWindowFlags_MenuBar;
    bool shallExit                   = false;
    if (ImGui::BeginMenuBar())
    {
      if (ImGui::BeginMenu("File"))
      {
        if (ImGui::MenuItem("Quit"))
          shallExit = true;
        ImGui::EndMenu();
      }
      _studioLayout.renderMenu();

      renderStatus();
      ImGui::EndMenuBar();
    }

    return shallExit;
  }

  void renderStatus()
  {
    ImVec4 statusTextColor{ 0.8f, 0.8f, 0.3f, 1.f };
    if (_studioLayout.isVisible(DockableWindowId::Scene3d))
    {
      ImGui::SameLine(ImGui::GetIO().DisplaySize.x / 2.f);
      std::string sceneName = _appContext._sceneWidget->getRenderableScene()->getName();
      ImGui::TextColored(statusTextColor, "%s", sceneName.c_str());
    }

    ImGui::SameLine(ImGui::GetIO().DisplaySize.x - 70.f);
    ImGui::TextColored(statusTextColor, "FPS: %.1f", ImGui::GetIO().Framerate);
  }

  // renders the GUI. Returns true when exit required
  bool render()
  {
    static bool wasInitialLayoutApplied = false;
    if (!wasInitialLayoutApplied)
    {
      this->_studioLayout.ApplyLayoutMode(LayoutMode::SceneAndBrowser);
      wasInitialLayoutApplied = true;
    }

    prepareSceneInspector();
    registerRenderFunctions();

    bool shallExit = renderMenu();
    _studioLayout.renderGui();

    handleLoopSamples();

    if (_appContext._options._flagScreenshotOneSampleAndExit)
      return saveScreenshot();
    else
      return shallExit;
  }

  void setRenderableScene(std::shared_ptr<BABYLON::IRenderableScene> scene)
  {
    if (_appContext._inspector)
      _appContext._inspector->setScene(nullptr);
    _appContext._sceneWidget->setRenderableScene(scene);
    if (_appContext._inspector)
      _appContext._inspector->setScene(_appContext._sceneWidget->getScene());
  }

  // Saves a screenshot after  few frames (returns true when done)
  bool saveScreenshot()
  {
    _appContext._frameCounter++;
    if (_appContext._frameCounter < 30)
      return false;
    int imageWidth = 200;
    int jpgQuality = 75;
    this->_appContext._sceneWidget->getCanvas()->saveScreenshotJpg(
      (_appContext._options._sceneName + ".jpg").c_str(), jpgQuality, imageWidth);
    return true;
  }

  bool ButtonInOverlayWindow(const std::string& label, ImVec2 position, ImVec2 size)
  {
    ImGui::SetNextWindowPos(position);
    ImGui::SetNextWindowSize(size);
    ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoBackground;
    std::string id         = label + "##ButtonInOverlayWindow";
    ImGui::Begin(label.c_str(), nullptr, flags);
    bool clicked = ImGui::Button(label.c_str());
    ImGui::End();
    return clicked;
  }

  void renderHud(ImVec2 cursorScene3dTopLeft)
  {
    auto asSceneWithHud
      = dynamic_cast<IRenderableSceneWithHud*>(_appContext._sceneWidget->getRenderableScene());
    if (!asSceneWithHud)
      return;
    if (!asSceneWithHud->hudGui)
      return;

    static bool showHud = false;

    ImVec2 hudButtonPosition(cursorScene3dTopLeft.x + 2.f, cursorScene3dTopLeft.y + 2.f);
    ImVec2 hudWindowPosition(cursorScene3dTopLeft.x + 2.f, cursorScene3dTopLeft.y + 30.f);
    if (ButtonInOverlayWindow(ICON_FA_COG, hudButtonPosition, ImVec2(30.f, 30.f)))
      showHud = !showHud;

    if (showHud) {
      ImGui::SetNextWindowPos(hudWindowPosition, ImGuiCond_Once);
      ImGui::SetNextWindowBgAlpha(0.5f);
      ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize;
      ImGui::Begin("HUD", &showHud, flags);
      asSceneWithHud->hudGui();
      ImGui::End();
    }
  }

  void render3d()
  {
    ImVec2 sceneSize = ImGui::GetCurrentWindow()->Size;
    sceneSize.y -= 35.f;
    sceneSize.x = (float)((int)((sceneSize.x) / 4) * 4);
    ImVec2 cursorPosBeforeScene3d = ImGui::GetCursorScreenPos();
    _appContext._sceneWidget->render(sceneSize);
    renderHud(cursorPosBeforeScene3d);
  }

  void renderPlayground()
  {
    ImGui::Button(ICON_FA_QUESTION_CIRCLE);
    if (ImGui::IsItemHovered())
      ImGui::SetTooltip(
        "Playground : you can edit the code below! As soon as you save it, the code will be "
        "compiled and the 3D scene "
        "will be updated");
    ImGui::SameLine();

    if (_appContext._isCompiling) {
      ImGui::TextColored(ImVec4(1., 0., 0., 1.), "Compiling");
      _studioLayout.setVisible(DockableWindowId::Logs, true);
    }
    if (ImGui::Button(ICON_FA_PLAY " Run"))
      _playgroundCodeEditor.saveAll();
    ImGui::SameLine();
    _playgroundCodeEditor.render();
  }

private:
  void handleLoopSamples()
  {
    if (!_appContext._loopSamples.flagLoop)
      return;

    static int frame_counter = 0;
    const int max_frames     = 60;

    if (frame_counter > max_frames) {
      std::string sampleName
        = _appContext._loopSamples.samplesToLoop[_appContext._loopSamples.currentIdx];
      BABYLON_LOG_ERROR("LoopSample", sampleName)
      auto scene = Samples::SamplesIndex::Instance().createRenderableScene(sampleName, nullptr);
      this->setRenderableScene(scene);

      if (_appContext._loopSamples.currentIdx < _appContext._loopSamples.samplesToLoop.size() - 2)
        _appContext._loopSamples.currentIdx++;
      else
        _appContext._loopSamples.flagLoop = false;

      frame_counter = 0;
    }
    else
      frame_counter++;
  }

  //
  // BabylonStudioContext
  //
  struct AppContext {
    std::unique_ptr<BABYLON::ImGuiSceneWidget> _sceneWidget;
    std::unique_ptr<BABYLON::Inspector> _inspector;
    BABYLON::SamplesBrowser _sampleListComponent;
    int _frameCounter = 0;
    BabylonStudioOptions _options;
    bool _isCompiling = false;

    struct {
      bool flagLoop     = false;
      size_t currentIdx = 0;
      std::vector<std::string> samplesToLoop;
    } _loopSamples;
  };

  AppContext _appContext;
  BabylonStudioLayout _studioLayout;
  ImGuiUtils::CodeEditor _samplesCodeEditor
    = ImGuiUtils::CodeEditor(true); // true <-> showCheckboxReadOnly
  ImGuiUtils::CodeEditor _playgroundCodeEditor;
}; // end of class BabylonInspectorApp

// public API
void runBabylonStudio(std::shared_ptr<BABYLON::IRenderableScene> scene,
                      BabylonStudioOptions options /* = SceneWithInspectorOptions() */
)
{
  BABYLON::BabylonStudioApp app;
  app.RunApp(scene, options);
}

} // namespace BABYLON
<|endoftext|>


<commit_before>/**
 * @file NaoController.cpp
 *
 * @author Xu, Yuan
 * @author Mellmann, Heinrich
 * @breief Interface for the real robot for both cognition and motion
 *
 */

#include "NaoController.h"

#include <algorithm>

using namespace std;
using namespace naoth;

NaoController::NaoController()
    :
    PlatformInterface("Nao", 10),
    theSoundHandler(NULL),
    theBroadCaster(NULL),
    theBroadCastListener(NULL),
    theDebugServer(NULL),
    theRCTCBroadCaster(NULL),
    theRCTCBroadCastListener(NULL)
{
  // init shared memory
  // sensor data
  const std::string naoSensorDataPath = "/nao_sensor_data";
  // command data
  const std::string naoCommandMotorJointDataPath = "/nao_command.MotorJointData";
  const std::string naoCommandUltraSoundSendDataPath = "/nao_command.UltraSoundSendData";
  const std::string naoCommandIRSendDataPath = "/nao_command.IRSendData";
  const std::string naoCommandLEDDataPath = "/nao_command.LEDData";

  naoSensorData.open(naoSensorDataPath);

  naoCommandMotorJointData.open(naoCommandMotorJointDataPath);
  naoCommandUltraSoundSendData.open(naoCommandUltraSoundSendDataPath);
  naoCommandIRSendData.open(naoCommandIRSendDataPath);
  naoCommandLEDData.open(naoCommandLEDDataPath);
  // end init shared memory

  // read the theBodyID and the theBodyNickName from file "nao.info"
  const std::string naoInfoPath = Platform::getInstance().theConfigDirectory + "nao.info";
  ifstream is(naoInfoPath.c_str());
  if(!is.good())
  {
    // exit the program
    THROW("is.good() failed. No Configs found. Do you call ../bin/naoth from ~/naoqi?");
  }
  else
  {
    is >> theBodyID >> theBodyNickName;
    cout << "bodyID: " << theBodyID << endl;
    cout << "bodyNickName: " << theBodyNickName << endl;
  }

  // read the mac address of the LAN adaptor
  ifstream isEthMac("/sys/class/net/eth0/address");
  isEthMac >> theHeadNickName;
  std::replace(theHeadNickName.begin(), theHeadNickName.end(), ':', '_');
  cout << "headNickName: " << theHeadNickName << endl;

  /*  REGISTER IO  */
  // camera
  registerInput<Image>(*this);
  registerInput<Image2>(*this);
  registerInput<CurrentCameraSettings>(*this);
  registerInput<CurrentCameraSettings2>(*this);
  registerOutput<const CameraSettingsRequest>(*this);
  registerOutput<const CameraSettingsRequest2>(*this);

  // sound
  registerOutput<const SoundPlayData>(*this);

  // gamecontroller
  registerInput<GameData>(*this);
  registerOutput<const GameReturnData>(*this);

  // teamcomm
  registerInput<TeamMessageDataIn>(*this);
  registerOutput<const TeamMessageDataOut>(*this);

  // rctc teamcomm
  registerInput<RCTCTeamMessageDataIn>(*this);
  registerOutput<const RCTCTeamMessageDataOut>(*this);

  // debug comm
  registerInput<DebugMessageIn>(*this);
  registerOutput<const DebugMessageOut>(*this);

  // time
  registerInput<FrameInfo>(*this);

  // register sensor input
  registerInput<AccelerometerData>(*this);
  registerInput<SensorJointData>(*this);
  registerInput<FSRData>(*this);
  registerInput<GyrometerData>(*this);
  registerInput<InertialSensorData>(*this);
  registerInput<IRReceiveData>(*this);
  registerInput<ButtonData>(*this);
  registerInput<BatteryData>(*this);
  registerInput<UltraSoundReceiveData>(*this);

  // register command output
  registerOutput<const MotorJointData>(*this);
  registerOutput<const LEDData>(*this);
  registerOutput<const IRSendData>(*this);
  registerOutput<const UltraSoundSendData>(*this);

  /*  INIT DEVICES  */
  std::cout << "Init Platform" << endl;
  Platform::getInstance().init(this);

  std::cout << "Init SoundHandler" <<endl;
  //theSoundPlayer.play("penalized");
  theSoundHandler = new SoundControl();

  // create the teamcomm
  std::cout << "Init TeamComm" << endl;
  naoth::Configuration& config = naoth::Platform::getInstance().theConfiguration;
  string interfaceName = "wlan0";
  if(config.hasKey("teamcomm", "interface"))
  {
    interfaceName = config.getString("teamcomm", "interface");
  }
  int teamcomm_port = 10700; // default port
  config.get("teamcomm", "port", teamcomm_port);
  theBroadCaster = new BroadCaster(interfaceName, teamcomm_port);
  theBroadCastListener = new BroadCastListener(teamcomm_port, TEAMCOMM_MAX_MSG_SIZE);

  // create RCTC connections
  int rctc_port = 22022; // default port
  config.get("teamcomm", "rctc_port", rctc_port);
  theRCTCBroadCaster = new BroadCaster(interfaceName, rctc_port);
  theRCTCBroadCastListener = new BroadCastListener(rctc_port, rctc::PACKET_SIZE);

  // start the debug server at the default debug port
  std::cout << "Init DebugServer" << endl;
  int debug_port = 5401; // default port
  config.get("network", "debug_port", debug_port);
  theDebugServer = new DebugServer();
  theDebugServer->start(debug_port, true);

  std::cout<< "Init SPLGameController"<<endl;
  theGameController = new SPLGameController();

  std::cout << "Init CameraHandler (bottom)" << std::endl;
  theBottomCameraHandler.init("/dev/video1", CameraInfo::Bottom, true);
  std::cout << "Init CameraHandler (top)" << std::endl;
  theTopCameraHandler.init("/dev/video0", CameraInfo::Bottom, false);
}

NaoController::~NaoController()
{
  delete theSoundHandler;
  delete theBroadCaster;
  delete theBroadCastListener;
  delete theGameController;
  delete theDebugServer;
  delete theRCTCBroadCaster;
  delete theRCTCBroadCastListener;
}

void NaoController::setCameraSettingsInternal(const CameraSettingsRequest &data,
                        CameraInfo::CameraID camID)
{
  V4lCameraHandler& cameraHandler = camID == CameraInfo::Bottom
      ? theBottomCameraHandler : theTopCameraHandler;

  bool somethingChanged = false;
  if(cameraHandler.isRunning())
  {
    CurrentCameraSettings current;
    cameraHandler.getCameraSettings(current, data.queryCameraSettings);

    if(data.queryCameraSettings)
    {
      somethingChanged = false;
    }
    else
    {
      for(int i=0; i < CameraSettings::numOfCameraSetting; i++)
      {
        if(current.data[i] != data.data[i])
        {
          std::cout << "CameraParameter " <<
                        CameraSettings::getCameraSettingsName((CameraSettings::CameraSettingID) i)
                    << " was requested to change from " << current.data[i]
                    << " to " << data.data[i] << std::endl;
          somethingChanged = true;
//           break;
        }
      }
    }
  }
  if(somethingChanged)
  {
    std::cout << "Settting camera settings ("
              << (camID == CameraInfo::Bottom ? "bottom" : "top") << ")" << endl;
    cameraHandler.setAllCameraParams(data);
  }
}//end set CameraSettingsRequest

void NaoController::set(const CameraSettingsRequest &data)
{
  setCameraSettingsInternal(data, CameraInfo::Bottom);
}

void NaoController::set(const CameraSettingsRequest2 &data)
{
//  setCameraSettingsInternal(data, CameraInfo::Top);
}

void NaoController::get(RCTCTeamMessageDataIn& data)
{
  data.data.clear();
  std::vector<std::string> msg_vector;
  theRCTCBroadCastListener->receive(msg_vector);
  for(unsigned int i = 0; i < msg_vector.size(); i++)
  {
    const char* bin_msg = msg_vector[i].c_str();
    rctc::Message msg;
    if(rctc::binaryToMessage((const uint8_t*)bin_msg, msg))
    {
      data.data.push_back(msg);
    }
  }
}//end get RCTCTeamMessageDataIn

void NaoController::set(const RCTCTeamMessageDataOut& data)
{
  if(data.valid)
  {
    uint8_t bin_msg[rctc::PACKET_SIZE];
    rctc::messageToBinary(data.data, bin_msg);
    std::string msg((char*)bin_msg, rctc::PACKET_SIZE);
//      std::cout << "sending RCTC " <<theRCTCBroadCaster->broadcastAddress << " (bcast adress) " << std::endl;
    theRCTCBroadCaster->send(msg);
  }
}//end set RCTCTeamMessageDataOut
<commit_msg>re-activating the second camera<commit_after>/**
 * @file NaoController.cpp
 *
 * @author Xu, Yuan
 * @author Mellmann, Heinrich
 * @breief Interface for the real robot for both cognition and motion
 *
 */

#include "NaoController.h"

#include <algorithm>

using namespace std;
using namespace naoth;

NaoController::NaoController()
    :
    PlatformInterface("Nao", 10),
    theSoundHandler(NULL),
    theBroadCaster(NULL),
    theBroadCastListener(NULL),
    theDebugServer(NULL),
    theRCTCBroadCaster(NULL),
    theRCTCBroadCastListener(NULL)
{
  // init shared memory
  // sensor data
  const std::string naoSensorDataPath = "/nao_sensor_data";
  // command data
  const std::string naoCommandMotorJointDataPath = "/nao_command.MotorJointData";
  const std::string naoCommandUltraSoundSendDataPath = "/nao_command.UltraSoundSendData";
  const std::string naoCommandIRSendDataPath = "/nao_command.IRSendData";
  const std::string naoCommandLEDDataPath = "/nao_command.LEDData";

  naoSensorData.open(naoSensorDataPath);

  naoCommandMotorJointData.open(naoCommandMotorJointDataPath);
  naoCommandUltraSoundSendData.open(naoCommandUltraSoundSendDataPath);
  naoCommandIRSendData.open(naoCommandIRSendDataPath);
  naoCommandLEDData.open(naoCommandLEDDataPath);
  // end init shared memory

  // read the theBodyID and the theBodyNickName from file "nao.info"
  const std::string naoInfoPath = Platform::getInstance().theConfigDirectory + "nao.info";
  ifstream is(naoInfoPath.c_str());
  if(!is.good())
  {
    // exit the program
    THROW("is.good() failed. No Configs found. Do you call ../bin/naoth from ~/naoqi?");
  }
  else
  {
    is >> theBodyID >> theBodyNickName;
    cout << "bodyID: " << theBodyID << endl;
    cout << "bodyNickName: " << theBodyNickName << endl;
  }

  // read the mac address of the LAN adaptor
  ifstream isEthMac("/sys/class/net/eth0/address");
  isEthMac >> theHeadNickName;
  std::replace(theHeadNickName.begin(), theHeadNickName.end(), ':', '_');
  cout << "headNickName: " << theHeadNickName << endl;

  /*  REGISTER IO  */
  // camera
  registerInput<Image>(*this);
  registerInput<Image2>(*this);
  registerInput<CurrentCameraSettings>(*this);
  registerInput<CurrentCameraSettings2>(*this);
  registerOutput<const CameraSettingsRequest>(*this);
  registerOutput<const CameraSettingsRequest2>(*this);

  // sound
  registerOutput<const SoundPlayData>(*this);

  // gamecontroller
  registerInput<GameData>(*this);
  registerOutput<const GameReturnData>(*this);

  // teamcomm
  registerInput<TeamMessageDataIn>(*this);
  registerOutput<const TeamMessageDataOut>(*this);

  // rctc teamcomm
  registerInput<RCTCTeamMessageDataIn>(*this);
  registerOutput<const RCTCTeamMessageDataOut>(*this);

  // debug comm
  registerInput<DebugMessageIn>(*this);
  registerOutput<const DebugMessageOut>(*this);

  // time
  registerInput<FrameInfo>(*this);

  // register sensor input
  registerInput<AccelerometerData>(*this);
  registerInput<SensorJointData>(*this);
  registerInput<FSRData>(*this);
  registerInput<GyrometerData>(*this);
  registerInput<InertialSensorData>(*this);
  registerInput<IRReceiveData>(*this);
  registerInput<ButtonData>(*this);
  registerInput<BatteryData>(*this);
  registerInput<UltraSoundReceiveData>(*this);

  // register command output
  registerOutput<const MotorJointData>(*this);
  registerOutput<const LEDData>(*this);
  registerOutput<const IRSendData>(*this);
  registerOutput<const UltraSoundSendData>(*this);

  /*  INIT DEVICES  */
  std::cout << "Init Platform" << endl;
  Platform::getInstance().init(this);

  std::cout << "Init SoundHandler" <<endl;
  //theSoundPlayer.play("penalized");
  theSoundHandler = new SoundControl();

  // create the teamcomm
  std::cout << "Init TeamComm" << endl;
  naoth::Configuration& config = naoth::Platform::getInstance().theConfiguration;
  string interfaceName = "wlan0";
  if(config.hasKey("teamcomm", "interface"))
  {
    interfaceName = config.getString("teamcomm", "interface");
  }
  int teamcomm_port = 10700; // default port
  config.get("teamcomm", "port", teamcomm_port);
  theBroadCaster = new BroadCaster(interfaceName, teamcomm_port);
  theBroadCastListener = new BroadCastListener(teamcomm_port, TEAMCOMM_MAX_MSG_SIZE);

  // create RCTC connections
  int rctc_port = 22022; // default port
  config.get("teamcomm", "rctc_port", rctc_port);
  theRCTCBroadCaster = new BroadCaster(interfaceName, rctc_port);
  theRCTCBroadCastListener = new BroadCastListener(rctc_port, rctc::PACKET_SIZE);

  // start the debug server at the default debug port
  std::cout << "Init DebugServer" << endl;
  int debug_port = 5401; // default port
  config.get("network", "debug_port", debug_port);
  theDebugServer = new DebugServer();
  theDebugServer->start(debug_port, true);

  std::cout<< "Init SPLGameController"<<endl;
  theGameController = new SPLGameController();

  std::cout << "Init CameraHandler (bottom)" << std::endl;
  theBottomCameraHandler.init("/dev/video1", CameraInfo::Bottom, true);
  std::cout << "Init CameraHandler (top)" << std::endl;
  theTopCameraHandler.init("/dev/video0", CameraInfo::Bottom, false);
}

NaoController::~NaoController()
{
  delete theSoundHandler;
  delete theBroadCaster;
  delete theBroadCastListener;
  delete theGameController;
  delete theDebugServer;
  delete theRCTCBroadCaster;
  delete theRCTCBroadCastListener;
}

void NaoController::setCameraSettingsInternal(const CameraSettingsRequest &data,
                        CameraInfo::CameraID camID)
{
  V4lCameraHandler& cameraHandler = camID == CameraInfo::Bottom
      ? theBottomCameraHandler : theTopCameraHandler;

  bool somethingChanged = false;
  if(cameraHandler.isRunning())
  {
    CurrentCameraSettings current;
    cameraHandler.getCameraSettings(current, data.queryCameraSettings);

    if(data.queryCameraSettings)
    {
      somethingChanged = false;
    }
    else
    {
      for(int i=0; i < CameraSettings::numOfCameraSetting; i++)
      {
        if(current.data[i] != data.data[i])
        {
          std::cout << "CameraParameter " <<
                        CameraSettings::getCameraSettingsName((CameraSettings::CameraSettingID) i)
                    << " was requested to change from " << current.data[i]
                    << " to " << data.data[i] << std::endl;
          somethingChanged = true;
//           break;
        }
      }
    }
  }
  if(somethingChanged)
  {
    std::cout << "Settting camera settings ("
              << (camID == CameraInfo::Bottom ? "bottom" : "top") << ")" << endl;
    cameraHandler.setAllCameraParams(data);
  }
}//end set CameraSettingsRequest

void NaoController::set(const CameraSettingsRequest &data)
{
  setCameraSettingsInternal(data, CameraInfo::Bottom);
}

void NaoController::set(const CameraSettingsRequest2 &data)
{
  setCameraSettingsInternal(data, CameraInfo::Top);
}

void NaoController::get(RCTCTeamMessageDataIn& data)
{
  data.data.clear();
  std::vector<std::string> msg_vector;
  theRCTCBroadCastListener->receive(msg_vector);
  for(unsigned int i = 0; i < msg_vector.size(); i++)
  {
    const char* bin_msg = msg_vector[i].c_str();
    rctc::Message msg;
    if(rctc::binaryToMessage((const uint8_t*)bin_msg, msg))
    {
      data.data.push_back(msg);
    }
  }
}//end get RCTCTeamMessageDataIn

void NaoController::set(const RCTCTeamMessageDataOut& data)
{
  if(data.valid)
  {
    uint8_t bin_msg[rctc::PACKET_SIZE];
    rctc::messageToBinary(data.data, bin_msg);
    std::string msg((char*)bin_msg, rctc::PACKET_SIZE);
//      std::cout << "sending RCTC " <<theRCTCBroadCaster->broadcastAddress << " (bcast adress) " << std::endl;
    theRCTCBroadCaster->send(msg);
  }
}//end set RCTCTeamMessageDataOut
<|endoftext|>


<commit_before>#include <MicroBit.h>
#include "CalliopeDemo.h"

extern MicroBit uBit;

void onButtonA(MicroBitEvent event) {
    (void) event;
    uBit.display.print("A");
}

void onButtonB(MicroBitEvent event) {
    (void) event;
    uBit.display.print("B");
}

void onButtonAB(MicroBitEvent event) {
    (void) event;
    uBit.display.print("A+B");
}

void onButton0(MicroBitEvent event) {
    (void) event;
    uBit.display.print("0");
}

void onButton1(MicroBitEvent event) {
    (void) event;
    uBit.display.print("1");
}

void onButton2(MicroBitEvent event) {
    (void) event;
    uBit.display.print("2");
}

void onButton3(MicroBitEvent event) {
    (void) event;
    uBit.display.print("3");
}

void onShake(MicroBitEvent event) {
    (void) event;
    uBit.display.print("S");
}

void onFaceUp(MicroBitEvent event) {
    (void) event;
    uBit.display.print("+");
}

void onFaceDown(MicroBitEvent event) {
    (void) event;
    uBit.display.print("-");
}

void onTiltUp(MicroBitEvent event) {
    (void) event;
    uBit.display.print("U");
}

void onTiltDown(MicroBitEvent event) {
    (void) event;
    uBit.display.print("D");
}

void onTiltLeft(MicroBitEvent event) {
    (void) event;
    uBit.display.print("L");
}

void onTiltRight(MicroBitEvent event) {
    (void) event;
    uBit.display.print("R");
}

void testBoard() {
    KeyValuePair *firstTime = uBit.storage.get("initial");

    if (firstTime != NULL) return;
    uint8_t done = 1;
    uBit.storage.put("initial", &done, sizeof(int));

    uBit.serial.send("display\r\n");
    uBit.display.clear();
    uBit.display.print(Full);
    for (int i = 255; i > 0; i -= 2) {
        uBit.display.setBrightness(i);
        uBit.sleep(3);
    }
    uBit.sleep(3);
    for (int i = 0; i < 255; i += 2) {
        uBit.display.setBrightness(i);
        uBit.sleep(3);
    }

    uBit.serial.send("accelerometer\r\n");
    for (int i = 0; i < 10; i++) {
        uBit.accelerometer.getX();
        uBit.accelerometer.getY();
        uBit.accelerometer.getZ();
    }
    uBit.display.print(Tick);
    uBit.sleep(80);

    uBit.serial.send("RGB led\r\n");
    uBit.rgb.off();
    uBit.rgb.setColour(255, 0, 0, 0);
    uBit.sleep(200);
    uBit.rgb.off();
    uBit.rgb.setColour(0, 255, 0, 0);
    uBit.sleep(200);
    uBit.rgb.off();
    uBit.rgb.setColour(0, 0, 255, 0);
    uBit.sleep(200);
    uBit.rgb.off();

    uBit.serial.send("sound\r\n");
    uBit.soundmotor.setSoundSilentMode(true);
    uBit.soundmotor.soundOn(500);
    uBit.sleep(100);
    uBit.soundmotor.soundOn(2000);
    uBit.sleep(100);
    uBit.soundmotor.soundOn(3000);
    uBit.sleep(100);
    uBit.soundmotor.soundOff();

    uBit.display.clear();

    // we need to trigger touch sensing
    uBit.io.P12.isTouched();
    uBit.io.P0.isTouched();
    uBit.io.P1.isTouched();
    uBit.io.P16.isTouched();

    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB);
    uBit.messageBus.listen(MICROBIT_ID_IO_P12, MICROBIT_EVT_ANY, onButton0);
    uBit.messageBus.listen(MICROBIT_ID_IO_P0, MICROBIT_EVT_ANY, onButton1);
    uBit.messageBus.listen(MICROBIT_ID_IO_P1, MICROBIT_EVT_ANY, onButton2);
    uBit.messageBus.listen(MICROBIT_ID_IO_P16, MICROBIT_EVT_ANY, onButton3);

    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, onShake);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_FACE_UP, onFaceUp);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_FACE_DOWN, onFaceDown);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_UP, onTiltUp);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_DOWN, onTiltDown);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_LEFT, onTiltLeft);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT, onTiltRight);

    while (1) uBit.sleep(100);
}<commit_msg>change board test according to tester feedback<commit_after>#include <MicroBit.h>
#include "CalliopeDemo.h"

extern MicroBit uBit;

void onButtonA(MicroBitEvent event) {
    (void) event;
    uBit.display.print("A");
}

void onButtonB(MicroBitEvent event) {
    (void) event;
    uBit.display.print("B");
}

void onButtonAB(MicroBitEvent event) {
    (void) event;
    uBit.display.print("A+B");
}

void onButton0(MicroBitEvent event) {
    (void) event;
    uBit.display.print("0");
}

void onButton1(MicroBitEvent event) {
    (void) event;
    uBit.display.print("1");
}

void onButton2(MicroBitEvent event) {
    (void) event;
    uBit.display.print("2");
}

void onButton3(MicroBitEvent event) {
    (void) event;
    uBit.display.print("3");
}

void onShake(MicroBitEvent event) {
    (void) event;
    uBit.display.print("S");
}

void onFaceUp(MicroBitEvent event) {
    (void) event;
    uBit.display.print("+");
}

void onFaceDown(MicroBitEvent event) {
    (void) event;
    uBit.display.print("-");
}

void onTiltUp(MicroBitEvent event) {
    (void) event;
    uBit.display.print("U");
}

void onTiltDown(MicroBitEvent event) {
    (void) event;
    uBit.display.print("D");
}

void onTiltLeft(MicroBitEvent event) {
    (void) event;
    uBit.display.print("L");
}

void onTiltRight(MicroBitEvent event) {
    (void) event;
    uBit.display.print("R");
}

void testBoard() {
    KeyValuePair *firstTime = uBit.storage.get("initial");

    if (firstTime != NULL) return;
    uint8_t done = 1;
    uBit.storage.put("initial", &done, sizeof(int));

    uBit.serial.send("sound\r\n");
    uBit.soundmotor.setSoundSilentMode(true);
    uBit.soundmotor.soundOn(500);
    uBit.sleep(100);
    uBit.soundmotor.soundOn(2000);
    uBit.sleep(100);
    uBit.soundmotor.soundOn(3000);
    uBit.sleep(100);
    uBit.soundmotor.soundOff();
    uBit.sleep(500);

    uBit.serial.send("display\r\n");
    uBit.display.clear();
    uBit.display.print(Full);
    for (int i = 255; i > 0; i -= 2) {
        uBit.display.setBrightness(i);
        uBit.sleep(3);
    }
    uBit.sleep(3);
    for (int i = 0; i < 255; i += 2) {
        uBit.display.setBrightness(i);
        uBit.sleep(3);
    }

    uBit.serial.send("RGB led\r\n");
    uBit.rgb.off();
    uBit.rgb.setColour(255, 0, 0, 0);
    uBit.sleep(200);
    uBit.rgb.off();
    uBit.rgb.setColour(0, 255, 0, 0);
    uBit.sleep(200);
    uBit.rgb.off();
    uBit.rgb.setColour(0, 0, 255, 0);
    uBit.sleep(200);
    uBit.rgb.off();

    uBit.serial.send("accelerometer\r\n");
    for (int i = 0; i < 10; i++) {
        uBit.accelerometer.getX();
        uBit.accelerometer.getY();
        uBit.accelerometer.getZ();
    }
    uBit.display.print(Tick);

    // we need to trigger touch sensing
    uBit.io.P12.isTouched();
    uBit.io.P0.isTouched();
    uBit.io.P1.isTouched();
    uBit.io.P16.isTouched();

    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, onButtonA);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, onButtonB);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, onButtonAB);
    uBit.messageBus.listen(MICROBIT_ID_IO_P12, MICROBIT_EVT_ANY, onButton0);
    uBit.messageBus.listen(MICROBIT_ID_IO_P0, MICROBIT_EVT_ANY, onButton1);
    uBit.messageBus.listen(MICROBIT_ID_IO_P1, MICROBIT_EVT_ANY, onButton2);
    uBit.messageBus.listen(MICROBIT_ID_IO_P16, MICROBIT_EVT_ANY, onButton3);

    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, onShake);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_FACE_UP, onFaceUp);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_FACE_DOWN, onFaceDown);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_UP, onTiltUp);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_DOWN, onTiltDown);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_LEFT, onTiltLeft);
    uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT, onTiltRight);

    while (1) uBit.sleep(100);
}<|endoftext|>