<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// 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.
//

// Interface header.
#include "constantsurfaceshader.h"

// appleseed.renderer headers.
#include "renderer/kernel/shading/shadingcontext.h"
#include "renderer/kernel/shading/shadingpoint.h"
#include "renderer/kernel/shading/shadingresult.h"
#include "renderer/modeling/input/inputarray.h"
#include "renderer/modeling/input/source.h"
#include "renderer/modeling/surfaceshader/surfaceshader.h"

// appleseed.foundation headers.
#include "foundation/image/colorspace.h"
#include "foundation/utility/containers/dictionaryarray.h"

// Forward declarations.
namespace renderer  { class TextureCache; }

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Constant color surface shader.
    //

    const char* Model = "constant_surface_shader";

    class ConstantSurfaceShader
      : public SurfaceShader
    {
      public:
        ConstantSurfaceShader(
            const char*             name,
            const ParamArray&       params)
          : SurfaceShader(params)
        {
            set_name(name);

            m_inputs.declare("color", InputFormatSpectrum);
        }

        virtual void release()
        {
            delete this;
        }

        virtual const char* get_model() const
        {
            return Model;
        }

        virtual void evaluate(
            SamplingContext&        sampling_context,
            const ShadingContext&   shading_context,
            const ShadingPoint&     shading_point,
            ShadingResult&          shading_result) const
        {
            // Evaluate the inputs.
            InputValues values;
            m_inputs.evaluate(
                shading_context.get_texture_cache(),
                shading_point.get_input_params(),
                &values);

            // Set color space to spectral.
            shading_result.m_color_space = ColorSpaceSpectral;

            // Set color and alpha channels.
            shading_result.m_color = values.m_color;

            // Set alpha channel to full opacity.
            shading_result.m_alpha = Alpha(1.0);
        }

        virtual void evaluate_alpha_mask(
            SamplingContext&        sampling_context,
            TextureCache&           texture_cache,
            const ShadingPoint&     shading_point,
            Alpha&                  alpha) const
        {
            // Evaluate the inputs.
            InputValues values;
            m_inputs.evaluate(
                texture_cache,
                shading_point.get_input_params(),
                &values);

            // Set alpha channel.
            alpha = values.m_alpha;
        }

      private:
        struct InputValues
        {
            Spectrum    m_color;
            Alpha       m_alpha;
        };
    };
}

//
// ConstantSurfaceShaderFactory class implementation.
//

const char* ConstantSurfaceShaderFactory::get_model() const
{
    return Model;
}

const char* ConstantSurfaceShaderFactory::get_human_readable_model() const
{
    return "Constant";
}

DictionaryArray ConstantSurfaceShaderFactory::get_widget_definitions() const
{
    DictionaryArray definitions;

    {
        Dictionary entity_types;
        entity_types.insert("color", "Colors");
        entity_types.insert("texture_instance", "Textures");

        Dictionary widget;
        widget.insert("name", "color");
        widget.insert("label", "Color");
        widget.insert("widget", "entity_picker");
        widget.insert("entity_types", entity_types);
        widget.insert("use", "required");
        widget.insert("default", "");
        definitions.push_back(widget);
    }

    return definitions;
}

auto_release_ptr<SurfaceShader> ConstantSurfaceShaderFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return
        auto_release_ptr<SurfaceShader>(
            new ConstantSurfaceShader(name, params));
}

}   // namespace renderer
<commit_msg>fixed comment.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2011 Francois Beaune
//
// 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.
//

// Interface header.
#include "constantsurfaceshader.h"

// appleseed.renderer headers.
#include "renderer/kernel/shading/shadingcontext.h"
#include "renderer/kernel/shading/shadingpoint.h"
#include "renderer/kernel/shading/shadingresult.h"
#include "renderer/modeling/input/inputarray.h"
#include "renderer/modeling/input/source.h"
#include "renderer/modeling/surfaceshader/surfaceshader.h"

// appleseed.foundation headers.
#include "foundation/image/colorspace.h"
#include "foundation/utility/containers/dictionaryarray.h"

// Forward declarations.
namespace renderer  { class TextureCache; }

using namespace foundation;
using namespace std;

namespace renderer
{

namespace
{
    //
    // Constant color surface shader.
    //

    const char* Model = "constant_surface_shader";

    class ConstantSurfaceShader
      : public SurfaceShader
    {
      public:
        ConstantSurfaceShader(
            const char*             name,
            const ParamArray&       params)
          : SurfaceShader(params)
        {
            set_name(name);

            m_inputs.declare("color", InputFormatSpectrum);
        }

        virtual void release()
        {
            delete this;
        }

        virtual const char* get_model() const
        {
            return Model;
        }

        virtual void evaluate(
            SamplingContext&        sampling_context,
            const ShadingContext&   shading_context,
            const ShadingPoint&     shading_point,
            ShadingResult&          shading_result) const
        {
            // Evaluate the inputs.
            InputValues values;
            m_inputs.evaluate(
                shading_context.get_texture_cache(),
                shading_point.get_input_params(),
                &values);

            // Set color space to spectral.
            shading_result.m_color_space = ColorSpaceSpectral;

            // Set color channel.
            shading_result.m_color = values.m_color;

            // Set alpha channel to full opacity.
            shading_result.m_alpha = Alpha(1.0);
        }

        virtual void evaluate_alpha_mask(
            SamplingContext&        sampling_context,
            TextureCache&           texture_cache,
            const ShadingPoint&     shading_point,
            Alpha&                  alpha) const
        {
            // Evaluate the inputs.
            InputValues values;
            m_inputs.evaluate(
                texture_cache,
                shading_point.get_input_params(),
                &values);

            // Set alpha channel.
            alpha = values.m_alpha;
        }

      private:
        struct InputValues
        {
            Spectrum    m_color;
            Alpha       m_alpha;
        };
    };
}

//
// ConstantSurfaceShaderFactory class implementation.
//

const char* ConstantSurfaceShaderFactory::get_model() const
{
    return Model;
}

const char* ConstantSurfaceShaderFactory::get_human_readable_model() const
{
    return "Constant";
}

DictionaryArray ConstantSurfaceShaderFactory::get_widget_definitions() const
{
    DictionaryArray definitions;

    {
        Dictionary entity_types;
        entity_types.insert("color", "Colors");
        entity_types.insert("texture_instance", "Textures");

        Dictionary widget;
        widget.insert("name", "color");
        widget.insert("label", "Color");
        widget.insert("widget", "entity_picker");
        widget.insert("entity_types", entity_types);
        widget.insert("use", "required");
        widget.insert("default", "");
        definitions.push_back(widget);
    }

    return definitions;
}

auto_release_ptr<SurfaceShader> ConstantSurfaceShaderFactory::create(
    const char*         name,
    const ParamArray&   params) const
{
    return
        auto_release_ptr<SurfaceShader>(
            new ConstantSurfaceShader(name, params));
}

}   // namespace renderer
<|endoftext|>


<commit_before>#include "luaSemanticAnalyzerTest.h"

#include "qrtext/lua/ast/assignment.h"
#include "qrtext/lua/ast/block.h"
#include "qrtext/lua/ast/functionCall.h"
#include "qrtext/lua/ast/unaryMinus.h"

#include "qrtext/lua/types/integer.h"
#include "qrtext/lua/types/float.h"
#include "qrtext/lua/types/string.h"

#include "gtest/gtest.h"

using namespace qrTest;
using namespace qrtext;
using namespace qrtext::lua;
using namespace qrtext::lua::details;
using namespace qrtext::lua::types;

void LuaSemanticAnalyzerTest::SetUp()
{
	mAnalyzer.reset(new LuaSemanticAnalyzer(mErrors));
	mParser.reset(new LuaParser(mErrors));
	mLexer.reset(new LuaLexer(mErrors));
}

QSharedPointer<qrtext::core::ast::Node> LuaSemanticAnalyzerTest::parse(QString const &code)
{
	return mParser->parse(mLexer->tokenize(code));
}

TEST_F(LuaSemanticAnalyzerTest, sanityCheck)
{
	auto tree = parse("123");
	mAnalyzer->analyze(tree);
	EXPECT_TRUE(mErrors.empty());
	EXPECT_TRUE(mAnalyzer->type(tree)->is<Integer>());
	EXPECT_TRUE(mAnalyzer->type(tree)->is<Number>());
}

TEST_F(LuaSemanticAnalyzerTest, assignment)
{
	auto tree = parse("a = 123");

	auto variable = as<ast::Assignment>(tree)->variable();
	auto value = as<ast::Assignment>(tree)->value();

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.empty());
	EXPECT_TRUE(mAnalyzer->type(variable)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(value)->is<types::Integer>());
}

TEST_F(LuaSemanticAnalyzerTest, unaryOperator)
{
	auto tree = parse("-123");

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.empty());
	EXPECT_TRUE(mAnalyzer->type(as<ast::UnaryMinus>(tree))->is<types::Integer>());
}

TEST_F(LuaSemanticAnalyzerTest, propagation)
{
	auto tree = parse("a = -123; b = a");

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.empty());

	auto block = as<ast::Block>(tree);
	auto firstAssignment = as<ast::Assignment>(block->children()[0]);
	auto secondAssignment = as<ast::Assignment>(block->children()[1]);

	auto firstVariable = firstAssignment->variable();
	auto firstValue = firstAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(firstVariable)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(firstValue)->is<types::Integer>());

	auto secondVariable = secondAssignment->variable();
	auto secondValue = secondAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(secondVariable)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(secondValue)->is<types::Integer>());
}

TEST_F(LuaSemanticAnalyzerTest, integerFloatCoercion)
{
	auto tree = parse("a = -123; a = 1.0");

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.isEmpty());

	auto block = as<ast::Block>(tree);
	auto firstAssignment = as<ast::Assignment>(block->children()[0]);
	auto secondAssignment = as<ast::Assignment>(block->children()[1]);

	auto firstVariable = firstAssignment->variable();
	auto firstValue = firstAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(firstVariable)->is<types::Float>());
	EXPECT_TRUE(mAnalyzer->type(firstValue)->is<types::Integer>());

	auto secondVariable = secondAssignment->variable();
	auto secondValue = secondAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(secondVariable)->is<types::Float>());
	EXPECT_TRUE(mAnalyzer->type(secondValue)->is<types::Float>());
}

TEST_F(LuaSemanticAnalyzerTest, functionReturnType)
{
	auto tree = parse("a = f(1)");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())}
			)));

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.isEmpty());

	auto assignment = as<ast::Assignment>(tree);

	auto a = assignment->variable();
	auto f = assignment->value();

	EXPECT_TRUE(mAnalyzer->type(a)->is<types::Float>());
	EXPECT_TRUE(mAnalyzer->type(f)->is<types::Float>());
}

TEST_F(LuaSemanticAnalyzerTest, functionParameters)
{
	auto tree = parse("a = f(b, c)");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())
					, QSharedPointer<core::types::TypeExpression>(new types::String())}
			)));

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.isEmpty());

	auto assignment = as<ast::Assignment>(tree);

	auto f = as<ast::FunctionCall>(assignment->value());

	auto b = f->arguments()[0];
	auto c = f->arguments()[1];

	EXPECT_TRUE(mAnalyzer->type(b)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(c)->is<types::String>());
}

TEST_F(LuaSemanticAnalyzerTest, invalidFunctionParameters)
{
	auto tree = parse("a = f(0.5, 'a')");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())
					, QSharedPointer<core::types::TypeExpression>(new types::String())}
			)));

	mAnalyzer->analyze(tree);

	ASSERT_FALSE(mErrors.isEmpty());
}
<commit_msg>added test for invalid use of integer-float coercion where it breaks existing type constraints<commit_after>#include "luaSemanticAnalyzerTest.h"

#include "qrtext/core/types/any.h"

#include "qrtext/lua/ast/assignment.h"
#include "qrtext/lua/ast/block.h"
#include "qrtext/lua/ast/functionCall.h"
#include "qrtext/lua/ast/unaryMinus.h"

#include "qrtext/lua/types/integer.h"
#include "qrtext/lua/types/float.h"
#include "qrtext/lua/types/string.h"

#include "gtest/gtest.h"

using namespace qrTest;
using namespace qrtext;
using namespace qrtext::lua;
using namespace qrtext::lua::details;
using namespace qrtext::lua::types;

void LuaSemanticAnalyzerTest::SetUp()
{
	mAnalyzer.reset(new LuaSemanticAnalyzer(mErrors));
	mParser.reset(new LuaParser(mErrors));
	mLexer.reset(new LuaLexer(mErrors));
}

QSharedPointer<qrtext::core::ast::Node> LuaSemanticAnalyzerTest::parse(QString const &code)
{
	return mParser->parse(mLexer->tokenize(code));
}

TEST_F(LuaSemanticAnalyzerTest, sanityCheck)
{
	auto tree = parse("123");
	mAnalyzer->analyze(tree);
	EXPECT_TRUE(mErrors.empty());
	EXPECT_TRUE(mAnalyzer->type(tree)->is<Integer>());
	EXPECT_TRUE(mAnalyzer->type(tree)->is<Number>());
}

TEST_F(LuaSemanticAnalyzerTest, assignment)
{
	auto tree = parse("a = 123");

	auto variable = as<ast::Assignment>(tree)->variable();
	auto value = as<ast::Assignment>(tree)->value();

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.empty());
	EXPECT_TRUE(mAnalyzer->type(variable)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(value)->is<types::Integer>());
}

TEST_F(LuaSemanticAnalyzerTest, unaryOperator)
{
	auto tree = parse("-123");

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.empty());
	EXPECT_TRUE(mAnalyzer->type(as<ast::UnaryMinus>(tree))->is<types::Integer>());
}

TEST_F(LuaSemanticAnalyzerTest, propagation)
{
	auto tree = parse("a = -123; b = a");

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.empty());

	auto block = as<ast::Block>(tree);
	auto firstAssignment = as<ast::Assignment>(block->children()[0]);
	auto secondAssignment = as<ast::Assignment>(block->children()[1]);

	auto firstVariable = firstAssignment->variable();
	auto firstValue = firstAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(firstVariable)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(firstValue)->is<types::Integer>());

	auto secondVariable = secondAssignment->variable();
	auto secondValue = secondAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(secondVariable)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(secondValue)->is<types::Integer>());
}

TEST_F(LuaSemanticAnalyzerTest, integerFloatCoercion)
{
	auto tree = parse("a = -123; a = 1.0");

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.isEmpty());

	auto block = as<ast::Block>(tree);
	auto firstAssignment = as<ast::Assignment>(block->children()[0]);
	auto secondAssignment = as<ast::Assignment>(block->children()[1]);

	auto firstVariable = firstAssignment->variable();
	auto firstValue = firstAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(firstVariable)->is<types::Float>());
	EXPECT_TRUE(mAnalyzer->type(firstValue)->is<types::Integer>());

	auto secondVariable = secondAssignment->variable();
	auto secondValue = secondAssignment->value();

	EXPECT_TRUE(mAnalyzer->type(secondVariable)->is<types::Float>());
	EXPECT_TRUE(mAnalyzer->type(secondValue)->is<types::Float>());
}

TEST_F(LuaSemanticAnalyzerTest, functionReturnType)
{
	auto tree = parse("a = f(1)");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())}
			)));

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.isEmpty());

	auto assignment = as<ast::Assignment>(tree);

	auto a = assignment->variable();
	auto f = assignment->value();

	EXPECT_TRUE(mAnalyzer->type(a)->is<types::Float>());
	EXPECT_TRUE(mAnalyzer->type(f)->is<types::Float>());
}

TEST_F(LuaSemanticAnalyzerTest, functionParameters)
{
	auto tree = parse("a = f(b, c)");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())
					, QSharedPointer<core::types::TypeExpression>(new types::String())}
			)));

	mAnalyzer->analyze(tree);

	EXPECT_TRUE(mErrors.isEmpty());

	auto assignment = as<ast::Assignment>(tree);

	auto f = as<ast::FunctionCall>(assignment->value());

	auto b = f->arguments()[0];
	auto c = f->arguments()[1];

	EXPECT_TRUE(mAnalyzer->type(b)->is<types::Integer>());
	EXPECT_TRUE(mAnalyzer->type(c)->is<types::String>());
}

TEST_F(LuaSemanticAnalyzerTest, invalidFunctionParameters)
{
	auto tree = parse("a = f(0.5, 'a')");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())
					, QSharedPointer<core::types::TypeExpression>(new types::String())}
			)));

	mAnalyzer->analyze(tree);

	ASSERT_FALSE(mErrors.isEmpty());
}

TEST_F(LuaSemanticAnalyzerTest, invalidCoercion)
{
	auto tree = parse("a = f(b, c); b = 0.5");

	mAnalyzer->addIntrinsicFunction("f", QSharedPointer<types::Function>(new types::Function(
			QSharedPointer<core::types::TypeExpression>(new types::Float()),
			{QSharedPointer<core::types::TypeExpression>(new types::Integer())
					, QSharedPointer<core::types::TypeExpression>(new types::String())}
			)));

	mAnalyzer->analyze(tree);

	EXPECT_FALSE(mErrors.isEmpty());

	auto block = as<ast::Block>(tree);
	auto firstAssignment = as<ast::Assignment>(block->children()[0]);

	auto a = firstAssignment->variable();
	auto f = as<ast::FunctionCall>(firstAssignment->value());

	EXPECT_TRUE(mAnalyzer->type(a)->is<types::Float>());

	auto b = f->arguments()[0];
	auto c = f->arguments()[1];

	EXPECT_TRUE(mAnalyzer->type(b)->is<qrtext::core::types::Any>());
	EXPECT_TRUE(mAnalyzer->type(c)->is<types::String>());
}
<|endoftext|>


<commit_before>          // can be just the necessary schema
  class {{tupletypename}} {
    // Invariant: data stored in _fields is always in the representation
    // specified by _scheme.

    public:
    {% for ft in fieldtypes %}
        {{ft}} f{{loop.index - 1}};
    {% endfor %}

    static constexpr int numFields() {
      return {{numfields}};
    }

    // size of all fields in struct removing only end padding
    static size_t fieldsSize() {
        const {{tupletypename}} _t;
        return

        {% if numfields == 1 %}
            sizeof(_t.f0);
         {% else %}
            ((char*)&_t.f{{numfields-1}}) + sizeof(_t.f{{numfields-1}}) - ((char*)&_t);
         {% endif %}
    }

    // debugging function to get storage sizes
    static void print_representation() {
        const {{tupletypename}} _t;

        {% for i in range(1, numfields-1) %}
        std::cout << (((char*)&_t.f{{i}}) - ((char*)&_t.f{{i-1}})) << ",";
        {% endfor %}
        std::cout << (_t.fieldsSize() - (((char*)&_t.f{{numfields-2}}) - ((char*)&_t)));
        std::cout << std::endl;

    }

    {{tupletypename}} () {
      // no-op
    }

    //template <typename OT>
    //{{tupletypename}} (const OT& other) {
    //  std::memcpy(this, &other, sizeof({{tupletypename}}));
    //}
    {{tupletypename}} ({% for ft in fieldtypes %}
                               const {{ft}}& a{{loop.index-1}}
                               {% if not loop.last %},{% endif %}
                       {% endfor %}
                       ) {
        {% for i in range(numfields) %}
            f{{i}} = a{{i}};
        {% endfor %}
    }

    {# list of types comma separated #}
    {# TODO: uncomment when jinja 2.8 is released with support for set blocks
    {% set types_comma %}
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
    {% endset %}
    #}

    {{tupletypename}}(const std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
            >& o) {
        {% for i in range(numfields) %}
            f{{i}} = std::get<{{i}}>(o);
        {% endfor %}
     }

     std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
     > to_tuple() {

        std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
        > r;
        {% for i in range(numfields) %}
            std::get<{{i}}>(r) = f{{i}};
        {% endfor %}
        return r;
     }

    // shamelessly terrible disambiguation: one solution is named factory methods
    //{{tupletypename}} (std::vector<int64_t> vals, bool ignore1, bool ignore2) {
    //    {% for i in range(numfields) %}
    //        f{{i}} = vals[{{i}}];
    //    {% endfor %}
    //}

    // use the tuple schema to interpret the input stream
    static {{tupletypename}} fromIStream(std::istream& ss, char delim=' ') {
        {{tupletypename}} _ret;

        {% for i in range(numfields) %}
            {% if fieldtypes[i] == string_type_name %}
               {
               std::string _temp;
               std::getline(ss, _temp, delim);
               // beware; truncate= true, so unckecked truncation for stringlen >= MAX_STR_LEN!
               _ret.f{{i}} = to_array<MAX_STR_LEN, std::string, true>(_temp);
               }
            {% else %}
               {
               // use operator>> to parse into proper numeric type
               ss >> _ret.f{{i}};
               //throw away the next delimiter
               std::string _temp;
               std::getline(ss, _temp, delim);
               }
            {% endif %}
        {% endfor %}

        return _ret;
    }

    void toOStream(std::ostream& os) const {
        os.write((char*)this, this->fieldsSize());
    }

    void toOStreamAscii(std::ostream& os) const {
        os
        {% for i in range(numfields-1) %}
        << f{{i}} << " "
        {% endfor %}
        << f{{numfields-1}} << std::endl;
    }

    //template <typename Tuple, typename T>
    //{{tupletypename}} (const Tuple& v0, const T& from) {
    //    constexpr size_t v0_size = std::tuple_size<Tuple>::value;
    //    constexpr int from_size = T::numFields();
    //    static_assert({{tupletypename}}::numFields() == (v0_size + from_size), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //    std::memcpy(((char*)&_fields)+v0_size*sizeof(int64_t), &(from._fields), from_size*sizeof(int64_t));
    //}

    //template <typename Tuple>
    //{{tupletypename}} (const Tuple& v0) {
    //    static_assert({{tupletypename}}::numFields() == (std::tuple_size<Tuple>::value), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //}

    std::ostream& dump(std::ostream& o) const {
      o << "Materialized(";

      {% for i in range(numfields) %}
        o << f{{i}} << ",";
      {% endfor %}

      o << ")";
      return o;
    }

    {{additional_code}}
  } {{after_def_code}};

  std::ostream& operator<< (std::ostream& o, const {{tupletypename}}& t) {
    return t.dump(o);
  }

<commit_msg>range is exclusive?<commit_after>          // can be just the necessary schema
  class {{tupletypename}} {
    // Invariant: data stored in _fields is always in the representation
    // specified by _scheme.

    public:
    {% for ft in fieldtypes %}
        {{ft}} f{{loop.index - 1}};
    {% endfor %}

    static constexpr int numFields() {
      return {{numfields}};
    }

    // size of all fields in struct removing only end padding
    static size_t fieldsSize() {
        const {{tupletypename}} _t;
        return

        {% if numfields == 1 %}
            sizeof(_t.f0);
         {% else %}
            ((char*)&_t.f{{numfields-1}}) + sizeof(_t.f{{numfields-1}}) - ((char*)&_t);
         {% endif %}
    }

    // debugging function to get storage sizes
    static void print_representation() {
        const {{tupletypename}} _t;

        {% for i in range(1, numfields) %}
        std::cout << (((char*)&_t.f{{i}}) - ((char*)&_t.f{{i-1}})) << ",";
        {% endfor %}
        std::cout << (_t.fieldsSize() - (((char*)&_t.f{{numfields-2}}) - ((char*)&_t)));
        std::cout << std::endl;

    }

    {{tupletypename}} () {
      // no-op
    }

    //template <typename OT>
    //{{tupletypename}} (const OT& other) {
    //  std::memcpy(this, &other, sizeof({{tupletypename}}));
    //}
    {{tupletypename}} ({% for ft in fieldtypes %}
                               const {{ft}}& a{{loop.index-1}}
                               {% if not loop.last %},{% endif %}
                       {% endfor %}
                       ) {
        {% for i in range(numfields) %}
            f{{i}} = a{{i}};
        {% endfor %}
    }

    {# list of types comma separated #}
    {# TODO: uncomment when jinja 2.8 is released with support for set blocks
    {% set types_comma %}
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
    {% endset %}
    #}

    {{tupletypename}}(const std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
            >& o) {
        {% for i in range(numfields) %}
            f{{i}} = std::get<{{i}}>(o);
        {% endfor %}
     }

     std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
     > to_tuple() {

        std::tuple<
        {% for ft in fieldtypes %}
        {{ft}}
        {% if not loop.last %},{% endif %}
        {% endfor %}
        > r;
        {% for i in range(numfields) %}
            std::get<{{i}}>(r) = f{{i}};
        {% endfor %}
        return r;
     }

    // shamelessly terrible disambiguation: one solution is named factory methods
    //{{tupletypename}} (std::vector<int64_t> vals, bool ignore1, bool ignore2) {
    //    {% for i in range(numfields) %}
    //        f{{i}} = vals[{{i}}];
    //    {% endfor %}
    //}

    // use the tuple schema to interpret the input stream
    static {{tupletypename}} fromIStream(std::istream& ss, char delim=' ') {
        {{tupletypename}} _ret;

        {% for i in range(numfields) %}
            {% if fieldtypes[i] == string_type_name %}
               {
               std::string _temp;
               std::getline(ss, _temp, delim);
               // beware; truncate= true, so unckecked truncation for stringlen >= MAX_STR_LEN!
               _ret.f{{i}} = to_array<MAX_STR_LEN, std::string, true>(_temp);
               }
            {% else %}
               {
               // use operator>> to parse into proper numeric type
               ss >> _ret.f{{i}};
               //throw away the next delimiter
               std::string _temp;
               std::getline(ss, _temp, delim);
               }
            {% endif %}
        {% endfor %}

        return _ret;
    }

    void toOStream(std::ostream& os) const {
        os.write((char*)this, this->fieldsSize());
    }

    void toOStreamAscii(std::ostream& os) const {
        os
        {% for i in range(numfields-1) %}
        << f{{i}} << " "
        {% endfor %}
        << f{{numfields-1}} << std::endl;
    }

    //template <typename Tuple, typename T>
    //{{tupletypename}} (const Tuple& v0, const T& from) {
    //    constexpr size_t v0_size = std::tuple_size<Tuple>::value;
    //    constexpr int from_size = T::numFields();
    //    static_assert({{tupletypename}}::numFields() == (v0_size + from_size), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //    std::memcpy(((char*)&_fields)+v0_size*sizeof(int64_t), &(from._fields), from_size*sizeof(int64_t));
    //}

    //template <typename Tuple>
    //{{tupletypename}} (const Tuple& v0) {
    //    static_assert({{tupletypename}}::numFields() == (std::tuple_size<Tuple>::value), "constructor only works on same number of total fields");
    //    TupleUtils::assign<0, decltype(_scheme)>(_fields, v0);
    //}

    std::ostream& dump(std::ostream& o) const {
      o << "Materialized(";

      {% for i in range(numfields) %}
        o << f{{i}} << ",";
      {% endfor %}

      o << ")";
      return o;
    }

    {{additional_code}}
  } {{after_def_code}};

  std::ostream& operator<< (std::ostream& o, const {{tupletypename}}& t) {
    return t.dump(o);
  }

<|endoftext|>


<commit_before>#include "check-for-valid-identifier-name.h"
#include "details/ast/ast.h"
#include "details/reporting/report.h"
#include "details/fwd.h"
#include <yuni/io/file.h>
#include <unordered_set>
#include <unordered_map>

using namespace Yuni;

namespace Nany
{

	static const std::unordered_set<AnyString> reservedKeywords =
	{
		"assert", "self", "override", "new", "is",
		"func", "class", "typedef",
		"for", "while", "do", "in", "each", "if", "then", "else", "switch",
		"return", "raise",
		"const", "var", "ref", "cref",
		"and", "or", "mod", "xor", "not",
		// boolean types
		"true", "false",
		"i8", "i6", "i32", "i64", "i128", "i256", "i512",
		"u8", "u16", "u32", "u64", "u128", "u256", "u512",
		"f32", "f64",
		"bool", "string", "pointer",
		// null keyword
		"null", "void"
	};

	static const std::unordered_set<AnyString> operatorKeywords =
	{
		"new", "dispose",
		"and", "or", "mod", "xor", "not",
		"+", "-", "*", "/", "^", "--", "++"
		"<<", ">>", "!=", "==", "<", ">", "<=", ">=",
		// "=", operator copy should be used instead
		"+=", "-=", "*=", "/=", "^=",
		"()", "[]"
	};

	static const std::unordered_map<AnyString, AnyString> opnormalize =
	{
		{ "and", "^and" },
		{ "or",  "^or"  },
		{ "mod", "^mod" },
		{ "xor", "^xor" },
		{ "not", "^not" },
		{ "+",   "^+"   }, { "++",  "^++"  },
		{ "-",   "^-"   }, { "--",  "^--"  },
		{ "*",   "^*"   }, { "/",   "^/"   },
		{ "^",   "^^"   },
		{ "<<",  "^<<"  }, { ">>",  "^>>"  },
		{ "<=",  "^<="  }, { ">=",  "^>="  },
		{ "<",   "^<"   }, { ">",   "^>"   },
		{ "==",  "^=="  }, { "!=",  "^!="  },
		{ "+=",  "^+="  }, { "-=",  "^-="  },
		{ "*=",  "^*="  }, { "/=",  "^/="  },
		{ "^=",  "^^="  },
		{ "()",  "^()"  }, { "[]",  "^[]"  }
	};

	AnyString normalizeOperatorName(AnyString name)
	{
		// to deal with grammar's potential glitches when eating tokens
		// (it would considerably slow down the parsing to improve it)
		name.trimRight();

		if (YUNI_UNLIKELY(name.empty())) // bug within the AST parser for + -
			return "^+";

		// TODO normalize operator name: find a mecanism to not rely on a map
		auto tit = opnormalize.find(name);
		if (YUNI_LIKELY(tit != opnormalize.end()))
			return tit->second;

		assert(false and "unknown identifier for normalization");
		return name;
	}

	bool checkForValidIdentifierName(Logs::Report& report, const Nany::Node& node, const AnyString& name, bool isOperator)
	{
		// do never accept empty names
		if (unlikely(name.empty()))
		{
			report.error() << "invalid empty name";
			return false;
		}

		// the name is always valid if the node comes from internal AST transformations
		if (node.metadata and AST::metadata(node).fromASTTransformation)
			return true;

		if (YUNI_LIKELY(not isOperator))
		{
			// names with '_' as prefix are for internal uses only
			if (unlikely(name.first() == '_'))
			{
				auto err = report.error() << "invalid identifier name '" << name << "': underscore as a prefix is not allowed";
				err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
				return false;
			}

			// warning - ascii only chars
			if (false)
			{
				auto end = name.utf8end();
				for (auto i = name.utf8begin(); i != end; ++i)
				{
					if (not i->isAscii())
					{
						auto wrn = report.warning() << "invalid identifier name: the name contains non-ascii characters";
						wrn.message.origins.location.pos.offsetEnd = wrn.message.origins.location.pos.offset + name.size();
						break;
					}
				}
			}

			// checking if the id name is not from one of reserved keywords
			if (unlikely(reservedKeywords.count(name) != 0))
			{
				auto err = report.error() << "'" << name << "' is a reserved keyword";
				err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
				return false;
			}
		}
		else
		{
			// checking if the operator name is one from the list
			if (unlikely(operatorKeywords.count(name) == 0)) // not found
			{
				auto err = report.error() << "invalid identifier name: '" << name << "' is not a valid operator";
				err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
				return false;
			}
		}

		if (unlikely(name.size() > 127u))
		{
			auto err = report.error() << "identifier name too long";
			err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
			return false;
		}
		return true;
	}

} // namespace Nany

<commit_msg>accept operators `self++`, `++self`, `self--`, `--self`<commit_after>#include "check-for-valid-identifier-name.h"
#include "details/ast/ast.h"
#include "details/reporting/report.h"
#include "details/fwd.h"
#include <yuni/io/file.h>
#include <unordered_set>
#include <unordered_map>

using namespace Yuni;

namespace Nany
{

	static const std::unordered_set<AnyString> reservedKeywords =
	{
		"assert", "self", "override", "new", "is",
		"func", "class", "typedef",
		"for", "while", "do", "in", "each", "if", "then", "else", "switch",
		"return", "raise",
		"const", "var", "ref", "cref",
		"and", "or", "mod", "xor", "not",
		// boolean types
		"true", "false",
		"i8", "i6", "i32", "i64", "i128", "i256", "i512",
		"u8", "u16", "u32", "u64", "u128", "u256", "u512",
		"f32", "f64",
		"bool", "string", "pointer",
		// null keyword
		"null", "void"
	};

	static const std::unordered_set<AnyString> operatorKeywords =
	{
		"new", "dispose",
		"and", "or", "mod", "xor", "not",
		"+", "-", "*", "/", "^",
		"<<", ">>", "!=", "==", "<", ">", "<=", ">=",
		// "=", operator copy should be used instead
		"+=", "-=", "*=", "/=", "^=",
		"()", "[]",
		"++self", "self++", "--self", "self--"
	};

	static const std::unordered_map<AnyString, AnyString> opnormalize =
	{
		{ "and", "^and" },
		{ "or",  "^or"  },
		{ "mod", "^mod" },
		{ "xor", "^xor" },
		{ "not", "^not" },
		{ "+",   "^+"   }, { "++",  "^++"  },
		{ "-",   "^-"   }, { "--",  "^--"  },
		{ "*",   "^*"   }, { "/",   "^/"   },
		{ "^",   "^^"   },
		{ "<<",  "^<<"  }, { ">>",  "^>>"  },
		{ "<=",  "^<="  }, { ">=",  "^>="  },
		{ "<",   "^<"   }, { ">",   "^>"   },
		{ "==",  "^=="  }, { "!=",  "^!="  },
		{ "+=",  "^+="  }, { "-=",  "^-="  },
		{ "*=",  "^*="  }, { "/=",  "^/="  },
		{ "^=",  "^^="  },
		{ "()",  "^()"  }, { "[]",  "^[]"  },
		{ "self++", "^self++" }, { "++self", "^++self" },
		{ "self--", "^self--" }, { "--self", "^--self" },
	};

	AnyString normalizeOperatorName(AnyString name)
	{
		// to deal with grammar's potential glitches when eating tokens
		// (it would considerably slow down the parsing to improve it)
		name.trimRight();

		if (YUNI_UNLIKELY(name.empty())) // bug within the AST parser for + -
			return "^+";

		// TODO normalize operator name: find a mecanism to not rely on a map
		auto tit = opnormalize.find(name);
		if (YUNI_LIKELY(tit != opnormalize.end()))
			return tit->second;

		assert(false and "unknown identifier for normalization");
		return name;
	}

	bool checkForValidIdentifierName(Logs::Report& report, const Nany::Node& node, const AnyString& name, bool isOperator)
	{
		// do never accept empty names
		if (unlikely(name.empty()))
		{
			report.error() << "invalid empty name";
			return false;
		}

		// the name is always valid if the node comes from internal AST transformations
		if (node.metadata and AST::metadata(node).fromASTTransformation)
			return true;

		if (YUNI_LIKELY(not isOperator))
		{
			// names with '_' as prefix are for internal uses only
			if (unlikely(name.first() == '_'))
			{
				auto err = report.error() << "invalid identifier name '" << name << "': underscore as a prefix is not allowed";
				err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
				return false;
			}

			// warning - ascii only chars
			if (false)
			{
				auto end = name.utf8end();
				for (auto i = name.utf8begin(); i != end; ++i)
				{
					if (not i->isAscii())
					{
						auto wrn = report.warning() << "invalid identifier name: the name contains non-ascii characters";
						wrn.message.origins.location.pos.offsetEnd = wrn.message.origins.location.pos.offset + name.size();
						break;
					}
				}
			}

			// checking if the id name is not from one of reserved keywords
			if (unlikely(reservedKeywords.count(name) != 0))
			{
				auto err = report.error() << "'" << name << "' is a reserved keyword";
				err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
				return false;
			}
		}
		else
		{
			// checking if the operator name is one from the list
			if (unlikely(operatorKeywords.count(name) == 0)) // not found
			{
				auto err = report.error() << "invalid identifier name: '" << name << "' is not a valid operator";
				err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
				return false;
			}
		}

		if (unlikely(name.size() > 127u))
		{
			auto err = report.error() << "identifier name too long";
			err.message.origins.location.pos.offsetEnd = err.message.origins.location.pos.offset + name.size();
			return false;
		}
		return true;
	}

} // namespace Nany

<|endoftext|>


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

/*! \file gather.inl
 *  \brief Inline file for gather.h
 */

#pragma once

#include <thrust/distance.h>

#include <thrust/detail/device/for_each.h>
#include <thrust/detail/device/dereference.h>

namespace thrust
{
namespace detail
{
namespace device
{
namespace generic
{
namespace detail
{

template <typename RandomAccessIterator>
struct gather_functor
{
  RandomAccessIterator input;

  gather_functor(RandomAccessIterator _input)
    : input(_input) {}

  template <typename Tuple>
  __host__ __device__
  void operator()(Tuple t)
  {
    thrust::get<0>(t) = thrust::detail::device::dereference(input, thrust::get<1>(t));
  }
}; // end gather_functor

template <typename RandomAccessIterator, typename Predicate>
struct gather_if_functor
{
  RandomAccessIterator input;
  Predicate pred;

  gather_if_functor(RandomAccessIterator _input, Predicate _pred)
    : input(_input), pred(_pred) {}

  template <typename Tuple>
  __host__ __device__
  void operator()(Tuple t)
  {
    if(pred(thrust::get<2>(t)))
      thrust::get<0>(t) = thrust::detail::device::dereference(input, thrust::get<1>(t));
  }
}; // end gather_functor

} // end detail

template<typename ForwardIterator,
         typename InputIterator,
         typename RandomAccessIterator>
  void gather(ForwardIterator first,
              ForwardIterator last,
              InputIterator  map,
              RandomAccessIterator input)
{
  detail::gather_functor<RandomAccessIterator> func(input);
  thrust::detail::device::for_each(thrust::make_zip_iterator(thrust::make_tuple(first, map)),
                                   thrust::make_zip_iterator(thrust::make_tuple(last,  map + thrust::distance(first, last))),
                                   func);
} // end gather()

template<typename ForwardIterator,
         typename InputIterator1,
         typename InputIterator2,
         typename RandomAccessIterator,
         typename Predicate>
  void gather_if(ForwardIterator first,
                 ForwardIterator last,
                 InputIterator1 map,
                 InputIterator2 stencil,
                 RandomAccessIterator input,
                 Predicate pred)
{
  detail::gather_if_functor<RandomAccessIterator, Predicate> func(input, pred);
  thrust::detail::device::for_each(thrust::make_zip_iterator(thrust::make_tuple(first, map, stencil)),
                                   thrust::make_zip_iterator(thrust::make_tuple(last,  map + thrust::distance(first, last), stencil + thrust::distance(first, last))),
                                   func);
} // end gather_if()

} // end namespace generic
} // end namespace device
} // end namespace detail
} // end namespace thrust

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

/*! \file gather.inl
 *  \brief Inline file for gather.h
 */

#pragma once

#include <thrust/distance.h>

#include <thrust/detail/device/for_each.h>
#include <thrust/detail/device/dereference.h>

namespace thrust
{
namespace detail
{
namespace device
{
namespace generic
{
namespace detail
{

template <typename RandomAccessIterator>
struct gather_functor
{
  RandomAccessIterator input;

  gather_functor(RandomAccessIterator _input)
    : input(_input) {}

  template <typename Tuple>
  __host__ __device__
  void operator()(Tuple t)
  {
    thrust::get<0>(t) = thrust::detail::device::dereference(input, thrust::get<1>(t));
  }
}; // end gather_functor

template <typename RandomAccessIterator, typename Predicate>
struct gather_if_functor
{
  RandomAccessIterator input;
  Predicate pred;

  gather_if_functor(RandomAccessIterator _input, Predicate _pred)
    : input(_input), pred(_pred) {}

  template <typename Tuple>
  __host__ __device__
  void operator()(Tuple t)
  {
    if(pred(thrust::get<2>(t)))
      thrust::get<0>(t) = thrust::detail::device::dereference(input, thrust::get<1>(t));
  }
}; // end gather_functor

} // end detail

template<typename ForwardIterator,
         typename InputIterator,
         typename RandomAccessIterator>
  void gather(ForwardIterator first,
              ForwardIterator last,
              InputIterator  map,
              RandomAccessIterator input)
{
  detail::gather_functor<RandomAccessIterator> func(input);
  thrust::detail::device::for_each(thrust::make_zip_iterator(thrust::make_tuple(first, map)),
                                   thrust::make_zip_iterator(thrust::make_tuple(first, map)) + thrust::distance(first, last),
                                   func);
} // end gather()

template<typename ForwardIterator,
         typename InputIterator1,
         typename InputIterator2,
         typename RandomAccessIterator,
         typename Predicate>
  void gather_if(ForwardIterator first,
                 ForwardIterator last,
                 InputIterator1 map,
                 InputIterator2 stencil,
                 RandomAccessIterator input,
                 Predicate pred)
{
  detail::gather_if_functor<RandomAccessIterator, Predicate> func(input, pred);
  thrust::detail::device::for_each(thrust::make_zip_iterator(thrust::make_tuple(first, map, stencil)),
                                   thrust::make_zip_iterator(thrust::make_tuple(first, map, stencil)) + thrust::distance(first, last),
                                   func);
} // end gather_if()

} // end namespace generic
} // end namespace device
} // end namespace detail
} // end namespace thrust

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: glob.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2004-07-13 13:38:50 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_GLOB_HXX
#define SD_GLOB_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

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

#define DIA_SLOW    0
#define DIA_MEDIUM  1
#define DIA_FAST    2

#define SD_IF_SDAPP                     SFX_INTERFACE_SD_START + 0
#define SD_IF_SDDRAWDOCSHELL            SFX_INTERFACE_SD_START + 1
#define SD_IF_SDVIEWSHELL               SFX_INTERFACE_SD_START + 2
#define SD_IF_SDDRAWVIEWSHELL           SFX_INTERFACE_SD_START + 3
#define SD_IF_SDSLIDEVIEWSHELL          SFX_INTERFACE_SD_START + 4
#define SD_IF_SDOUTLINEVIEWSHELL        SFX_INTERFACE_SD_START + 5
#define SD_IF_SDDRAWSTDOBJECTBAR        SFX_INTERFACE_SD_START + 6
#define SD_IF_SDDRAWTEXTOBJECTBAR       SFX_INTERFACE_SD_START + 7
#define SD_IF_SDDRAWBEZIEROBJECTBAR     SFX_INTERFACE_SD_START + 8
#define SD_IF_SDDRAWGLUEPOINTSOBJECTBAR SFX_INTERFACE_SD_START + 9
#define SD_IF_SDGRAPHICDOCSHELL         SFX_INTERFACE_SD_START + 10
#define SD_IF_SDGRAPHICVIEWSHELL        SFX_INTERFACE_SD_START + 11
#define SD_IF_SDGRAPHICSTDOBJECTBAR     SFX_INTERFACE_SD_START + 12
#define SD_IF_SDDRAWGRAFOBJECTBAR       SFX_INTERFACE_SD_START + 13
#define SD_IF_SDPRESVIEWSHELL           SFX_INTERFACE_SD_START + 14
#define SD_IF_SDPREVIEWVIEWSHELL        SFX_INTERFACE_SD_START + 15
#define SD_IF_SDVIEWSHELLBASE           SFX_INTERFACE_SD_START + 16
#define SD_IF_SD3DOBJECTBAR             SFX_INTERFACE_SD_START + 17
#define SD_IF_SDFONTWORKOBJECTBAR       SFX_INTERFACE_SD_START + 18
#define SD_IF_SDSLIDESORTERVIEWSHELL    SFX_INTERFACE_SD_START + 19
#define SD_IF_SDTASKPANEVIEWSHELL       SFX_INTERFACE_SD_START + 20
#define SD_IF_SDMASTERPAGESSELECTOR     SFX_INTERFACE_SD_START + 21
#define SD_IF_SDLAYOUTMENU              SFX_INTERFACE_SD_START + 22

// Inventor-Id fuer StarDraw UserData
const UINT32 SdUDInventor=UINT32('S')*0x00000001+
                          UINT32('D')*0x00000100+
                          UINT32('U')*0x00010000+
                          UINT32('D')*0x01000000;

// Object-Ids fuer StarDraw UserData
#define SD_ANIMATIONINFO_ID 1
#define SD_IMAPINFO_ID      2

// FamilyId der Praesentationsvorlagen
#define SD_LT_FAMILY (SfxStyleFamily)0xaffe

// Trennzeichen zwischen Layoutname und Vorlagenname der Praesentationsvorlagen
#define SD_LT_SEPARATOR "~LT~"

// Optionsstream-Identifier
#define SD_OPTION_MORPHING  "Morph"
#define SD_OPTION_VECTORIZE "Vectorize"

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

#endif // _SD_GLOB_HXX

<commit_msg>INTEGRATION: CWS jmf2 (1.6.64); FILE MERGED 2004/07/23 23:21:06 ka 1.6.64.2: RESYNC: (1.6-1.7); FILE MERGED 2004/07/11 19:56:31 ka 1.6.64.1: media support<commit_after>/*************************************************************************
 *
 *  $RCSfile: glob.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: obo $ $Date: 2004-08-12 09:12:09 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef SD_GLOB_HXX
#define SD_GLOB_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

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

#define DIA_SLOW    0
#define DIA_MEDIUM  1
#define DIA_FAST    2

#define SD_IF_SDAPP                     SFX_INTERFACE_SD_START + 0
#define SD_IF_SDDRAWDOCSHELL            SFX_INTERFACE_SD_START + 1
#define SD_IF_SDVIEWSHELL               SFX_INTERFACE_SD_START + 2
#define SD_IF_SDDRAWVIEWSHELL           SFX_INTERFACE_SD_START + 3
#define SD_IF_SDSLIDEVIEWSHELL          SFX_INTERFACE_SD_START + 4
#define SD_IF_SDOUTLINEVIEWSHELL        SFX_INTERFACE_SD_START + 5
#define SD_IF_SDDRAWSTDOBJECTBAR        SFX_INTERFACE_SD_START + 6
#define SD_IF_SDDRAWTEXTOBJECTBAR       SFX_INTERFACE_SD_START + 7
#define SD_IF_SDDRAWBEZIEROBJECTBAR     SFX_INTERFACE_SD_START + 8
#define SD_IF_SDDRAWGLUEPOINTSOBJECTBAR SFX_INTERFACE_SD_START + 9
#define SD_IF_SDGRAPHICDOCSHELL         SFX_INTERFACE_SD_START + 10
#define SD_IF_SDGRAPHICVIEWSHELL        SFX_INTERFACE_SD_START + 11
#define SD_IF_SDGRAPHICSTDOBJECTBAR     SFX_INTERFACE_SD_START + 12
#define SD_IF_SDDRAWGRAFOBJECTBAR       SFX_INTERFACE_SD_START + 13
#define SD_IF_SDPRESVIEWSHELL           SFX_INTERFACE_SD_START + 14
#define SD_IF_SDPREVIEWVIEWSHELL        SFX_INTERFACE_SD_START + 15
#define SD_IF_SDVIEWSHELLBASE           SFX_INTERFACE_SD_START + 16
#define SD_IF_SD3DOBJECTBAR             SFX_INTERFACE_SD_START + 17
#define SD_IF_SDFONTWORKOBJECTBAR       SFX_INTERFACE_SD_START + 18
#define SD_IF_SDSLIDESORTERVIEWSHELL    SFX_INTERFACE_SD_START + 19
#define SD_IF_SDTASKPANEVIEWSHELL       SFX_INTERFACE_SD_START + 20
#define SD_IF_SDMASTERPAGESSELECTOR     SFX_INTERFACE_SD_START + 21
#define SD_IF_SDLAYOUTMENU              SFX_INTERFACE_SD_START + 22
#define SD_IF_SDDRAWMEDIAOBJECTBAR      SFX_INTERFACE_SD_START + 23

// Inventor-Id fuer StarDraw UserData
const UINT32 SdUDInventor=UINT32('S')*0x00000001+
                          UINT32('D')*0x00000100+
                          UINT32('U')*0x00010000+
                          UINT32('D')*0x01000000;

// Object-Ids fuer StarDraw UserData
#define SD_ANIMATIONINFO_ID 1
#define SD_IMAPINFO_ID      2

// FamilyId der Praesentationsvorlagen
#define SD_LT_FAMILY (SfxStyleFamily)0xaffe

// Trennzeichen zwischen Layoutname und Vorlagenname der Praesentationsvorlagen
#define SD_LT_SEPARATOR "~LT~"

// Optionsstream-Identifier
#define SD_OPTION_MORPHING  "Morph"
#define SD_OPTION_VECTORIZE "Vectorize"

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

#endif // _SD_GLOB_HXX

<|endoftext|>


<commit_before>#include "guis/GuiInputConfig.h"

#include "components/ButtonComponent.h"
#include "components/MenuComponent.h"
#include "guis/GuiMsgBox.h"
#include "InputManager.h"
#include "Log.h"
#include "Window.h"

struct InputConfigStructure
{
	const char* name;
	const bool  skippable;
	const char* dispName;
	const char* icon;
};

static const int inputCount = 25;
static const InputConfigStructure GUI_INPUT_CONFIG_LIST[inputCount] =
{
	{ "Up",               false, "D-PAD UP",           ":/help/dpad_up.svg" },
	{ "Down",             false, "D-PAD DOWN",         ":/help/dpad_down.svg" },
	{ "Left",             false, "D-PAD LEFT",         ":/help/dpad_left.svg" },
	{ "Right",            false, "D-PAD RIGHT",        ":/help/dpad_right.svg" },
	{ "Start",            true,  "START",              ":/help/button_start.svg" },
	{ "Select",           true,  "SELECT",             ":/help/button_select.svg" },
	{ "A",                false, "BUTTON A / EAST",    ":/help/buttons_east.svg" },
	{ "B",                true,  "BUTTON B / SOUTH",   ":/help/buttons_south.svg" },
	{ "X",                true,  "BUTTON X / NORTH",   ":/help/buttons_north.svg" },
	{ "Y",                true,  "BUTTON Y / WEST",    ":/help/buttons_west.svg" },
	{ "LeftShoulder",     true,  "LEFT SHOULDER",      ":/help/button_l.svg" },
	{ "RightShoulder",    true,  "RIGHT SHOULDER",     ":/help/button_r.svg" },
	{ "LeftTrigger",      true,  "LEFT TRIGGER",       ":/help/button_lt.svg" },
	{ "RightTrigger",     true,  "RIGHT TRIGGER",      ":/help/button_rt.svg" },
	{ "LeftThumb",        true,  "LEFT THUMB",         ":/help/analog_thumb.svg" },
	{ "RightThumb",       true,  "RIGHT THUMB",        ":/help/analog_thumb.svg" },
	{ "LeftAnalogUp",     true,  "LEFT ANALOG UP",     ":/help/analog_up.svg" },
	{ "LeftAnalogDown",   true,  "LEFT ANALOG DOWN",   ":/help/analog_down.svg" },
	{ "LeftAnalogLeft",   true,  "LEFT ANALOG LEFT",   ":/help/analog_left.svg" },
	{ "LeftAnalogRight",  true,  "LEFT ANALOG RIGHT",  ":/help/analog_right.svg" },
	{ "RightAnalogUp",    true,  "RIGHT ANALOG UP",    ":/help/analog_up.svg" },
	{ "RightAnalogDown",  true,  "RIGHT ANALOG DOWN",  ":/help/analog_down.svg" },
	{ "RightAnalogLeft",  true,  "RIGHT ANALOG LEFT",  ":/help/analog_left.svg" },
	{ "RightAnalogRight", true,  "RIGHT ANALOG RIGHT", ":/help/analog_right.svg" },
	{ "HotKeyEnable",     true,  "HOTKEY ENABLE",      ":/help/button_hotkey.svg" }
};

//MasterVolUp and MasterVolDown are also hooked up, but do not appear on this screen.
//If you want, you can manually add them to es_input.cfg.

#define HOLD_TO_SKIP_MS 1000

GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfigureAll, const std::function<void()>& okCallback) : GuiComponent(window),
	mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 7)),
	mTargetConfig(target), mHoldingInput(false), mBusyAnim(window)
{
	LOG(LogInfo) << "Configuring device " << target->getDeviceId() << " (" << target->getDeviceName() << ").";

	if(reconfigureAll)
		target->clear();

	mConfiguringAll = reconfigureAll;
	mConfiguringRow = mConfiguringAll;

	addChild(&mBackground);
	addChild(&mGrid);

	// 0 is a spacer row
	mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(0, 0), false);

	mTitle = std::make_shared<TextComponent>(mWindow, "CONFIGURING", Font::get(FONT_SIZE_LARGE), 0x555555FF, ALIGN_CENTER);
	mGrid.setEntry(mTitle, Vector2i(0, 1), false, true);

	std::stringstream ss;
	if(target->getDeviceId() == DEVICE_KEYBOARD)
		ss << "KEYBOARD";
	else if(target->getDeviceId() == DEVICE_CEC)
		ss << "CEC";
	else
		ss << "GAMEPAD " << (target->getDeviceId() + 1);
	mSubtitle1 = std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(ss.str()), Font::get(FONT_SIZE_MEDIUM), 0x555555FF, ALIGN_CENTER);
	mGrid.setEntry(mSubtitle1, Vector2i(0, 2), false, true);

	mSubtitle2 = std::make_shared<TextComponent>(mWindow, "HOLD ANY BUTTON TO SKIP", Font::get(FONT_SIZE_SMALL), 0x99999900, ALIGN_CENTER);
	mGrid.setEntry(mSubtitle2, Vector2i(0, 3), false, true);

	// 4 is a spacer row

	mList = std::make_shared<ComponentList>(mWindow);
	mGrid.setEntry(mList, Vector2i(0, 5), true, true);
	for(int i = 0; i < inputCount; i++)
	{
		ComponentListRow row;

		// icon
		auto icon = std::make_shared<ImageComponent>(mWindow);
		icon->setImage(GUI_INPUT_CONFIG_LIST[i].icon);
		icon->setColorShift(0x777777FF);
		icon->setResize(0, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight() * 1.25f);
		row.addElement(icon, false);

		// spacer between icon and text
		auto spacer = std::make_shared<GuiComponent>(mWindow);
		spacer->setSize(16, 0);
		row.addElement(spacer, false);

		auto text = std::make_shared<TextComponent>(mWindow, GUI_INPUT_CONFIG_LIST[i].dispName, Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
		row.addElement(text, true);

		auto mapping = std::make_shared<TextComponent>(mWindow, "-NOT DEFINED-", Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT), 0x999999FF, ALIGN_RIGHT);
		setNotDefined(mapping); // overrides text and color set above
		row.addElement(mapping, true);
		mMappings.push_back(mapping);

		row.input_handler = [this, i, mapping](InputConfig* config, Input input) -> bool
		{
			// ignore input not from our target device
			if(config != mTargetConfig)
				return false;

			// if we're not configuring, start configuring when A is pressed
			if(!mConfiguringRow)
			{
				if(config->isMappedTo("a", input) && input.value)
				{
					mList->stopScrolling();
					mConfiguringRow = true;
					setPress(mapping);
					return true;
				}

				// we're not configuring and they didn't press A to start, so ignore this
				return false;
			}

			// we are configuring
			if(input.value != 0)
			{
				// input down
				// if we're already holding something, ignore this, otherwise plan to map this input
				if(mHoldingInput)
					return true;

				mHoldingInput = true;
				mHeldInput = input;
				mHeldTime = 0;
				mHeldInputId = i;

				return true;
			}else{
				// input up
				// make sure we were holding something and we let go of what we were previously holding
				if(!mHoldingInput || mHeldInput.device != input.device || mHeldInput.id != input.id || mHeldInput.type != input.type)
					return true;

				mHoldingInput = false;

				if(assign(mHeldInput, i))
					rowDone(); // if successful, move cursor/stop configuring - if not, we'll just try again

				return true;
			}
		};

		mList->addRow(row);
	}

	// only show "HOLD TO SKIP" if this input is skippable
	mList->setCursorChangedCallback([this](CursorState /*state*/) {
		bool skippable = GUI_INPUT_CONFIG_LIST[mList->getCursorId()].skippable;
		mSubtitle2->setOpacity(skippable * 255);
	});

	// make the first one say "PRESS ANYTHING" if we're re-configuring everything
	if(mConfiguringAll)
		setPress(mMappings.front());

	// buttons
	std::vector< std::shared_ptr<ButtonComponent> > buttons;
	std::function<void()> okFunction = [this, okCallback] {
		InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // save
		if(okCallback)
			okCallback();
		delete this;
	};
	buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "OK", "ok", [this, okFunction] {
		// check if the hotkey enable button is set. if not prompt the user to use select or nothing.
		Input input;
		if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) {
			mWindow->pushGui(new GuiMsgBox(mWindow,
				"YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING GAMES WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? PLEASE ANSWER YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.",
				"YES", [this, okFunction] {
					Input input;
					mTargetConfig->getInputByName("Select", &input);
					mTargetConfig->mapInput("HotKeyEnable", input);
					okFunction();
					},
				"NO", [this, okFunction] {
					// for a disabled hotkey enable button, set to a key with id 0,
					// so the input configuration script can be backwards compatible.
					mTargetConfig->mapInput("HotKeyEnable", Input(DEVICE_KEYBOARD, TYPE_KEY, 0, 1, true));
					okFunction();
				}
			));
		} else {
			okFunction();
		}
	}));
	mButtonGrid = makeButtonGrid(mWindow, buttons);
	mGrid.setEntry(mButtonGrid, Vector2i(0, 6), true, false);

	setSize(Renderer::getScreenWidth() * 0.6f, Renderer::getScreenHeight() * 0.75f);
	setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, (Renderer::getScreenHeight() - mSize.y()) / 2);
}

void GuiInputConfig::onSizeChanged()
{
	mBackground.fitTo(mSize, Vector3f::Zero(), Vector2f(-32, -32));

	// update grid
	mGrid.setSize(mSize);

	//mGrid.setRowHeightPerc(0, 0.025f);
	mGrid.setRowHeightPerc(1, mTitle->getFont()->getHeight()*0.75f / mSize.y());
	mGrid.setRowHeightPerc(2, mSubtitle1->getFont()->getHeight() / mSize.y());
	mGrid.setRowHeightPerc(3, mSubtitle2->getFont()->getHeight() / mSize.y());
	//mGrid.setRowHeightPerc(4, 0.03f);
	mGrid.setRowHeightPerc(5, (mList->getRowHeight(0) * 5 + 2) / mSize.y());
	mGrid.setRowHeightPerc(6, mButtonGrid->getSize().y() / mSize.y());

	mBusyAnim.setSize(mSize);
}

void GuiInputConfig::update(int deltaTime)
{
	if(mConfiguringRow && mHoldingInput && GUI_INPUT_CONFIG_LIST[mHeldInputId].skippable)
	{
		int prevSec = mHeldTime / 1000;
		mHeldTime += deltaTime;
		int curSec = mHeldTime / 1000;

		if(mHeldTime >= HOLD_TO_SKIP_MS)
		{
			setNotDefined(mMappings.at(mHeldInputId));
			clearAssignment(mHeldInputId);
			mHoldingInput = false;
			rowDone();
		}else{
			if(prevSec != curSec)
			{
				// crossed the second boundary, update text
				const auto& text = mMappings.at(mHeldInputId);
				std::stringstream ss;
				ss << "HOLD FOR " << HOLD_TO_SKIP_MS/1000 - curSec << "S TO SKIP";
				text->setText(ss.str());
				text->setColor(0x777777FF);
			}
		}
	}
}

// move cursor to the next thing if we're configuring all,
// or come out of "configure mode" if we were only configuring one row
void GuiInputConfig::rowDone()
{
	if(mConfiguringAll)
	{
		if(!mList->moveCursor(1)) // try to move to the next one
		{
			// at bottom of list, done
			mConfiguringAll = false;
			mConfiguringRow = false;
			mGrid.moveCursor(Vector2i(0, 1));
		}else{
			// on another one
			setPress(mMappings.at(mList->getCursorId()));
		}
	}else{
		// only configuring one row, so stop
		mConfiguringRow = false;
	}
}

void GuiInputConfig::setPress(const std::shared_ptr<TextComponent>& text)
{
	text->setText("PRESS ANYTHING");
	text->setColor(0x656565FF);
}

void GuiInputConfig::setNotDefined(const std::shared_ptr<TextComponent>& text)
{
	text->setText("-NOT DEFINED-");
	text->setColor(0x999999FF);
}

void GuiInputConfig::setAssignedTo(const std::shared_ptr<TextComponent>& text, Input input)
{
	text->setText(Utils::String::toUpper(input.string()));
	text->setColor(0x777777FF);
}

void GuiInputConfig::error(const std::shared_ptr<TextComponent>& text, const std::string& /*msg*/)
{
	text->setText("ALREADY TAKEN");
	text->setColor(0x656565FF);
}

bool GuiInputConfig::assign(Input input, int inputId)
{
	// input is from InputConfig* mTargetConfig

	// if this input is mapped to something other than "nothing" or the current row, error
	// (if it's the same as what it was before, allow it)
	if(mTargetConfig->getMappedTo(input).size() > 0 && !mTargetConfig->isMappedTo(GUI_INPUT_CONFIG_LIST[inputId].name, input) && strcmp(GUI_INPUT_CONFIG_LIST[inputId].name, "HotKeyEnable") != 0)
	{
		error(mMappings.at(inputId), "Already mapped!");
		return false;
	}

	setAssignedTo(mMappings.at(inputId), input);

	input.configured = true;
	mTargetConfig->mapInput(GUI_INPUT_CONFIG_LIST[inputId].name, input);

	LOG(LogInfo) << "  Mapping [" << input.string() << "] -> " << GUI_INPUT_CONFIG_LIST[inputId].name;

	return true;
}

void GuiInputConfig::clearAssignment(int inputId)
{
	mTargetConfig->unmapInput(GUI_INPUT_CONFIG_LIST[inputId].name);
}
<commit_msg>Fix the `opacity` for the hold-to-skip message.<commit_after>#include "guis/GuiInputConfig.h"

#include "components/ButtonComponent.h"
#include "components/MenuComponent.h"
#include "guis/GuiMsgBox.h"
#include "InputManager.h"
#include "Log.h"
#include "Window.h"

struct InputConfigStructure
{
	const char* name;
	const bool  skippable;
	const char* dispName;
	const char* icon;
};

static const int inputCount = 25;
static const InputConfigStructure GUI_INPUT_CONFIG_LIST[inputCount] =
{
	{ "Up",               false, "D-PAD UP",           ":/help/dpad_up.svg" },
	{ "Down",             false, "D-PAD DOWN",         ":/help/dpad_down.svg" },
	{ "Left",             false, "D-PAD LEFT",         ":/help/dpad_left.svg" },
	{ "Right",            false, "D-PAD RIGHT",        ":/help/dpad_right.svg" },
	{ "Start",            true,  "START",              ":/help/button_start.svg" },
	{ "Select",           true,  "SELECT",             ":/help/button_select.svg" },
	{ "A",                false, "BUTTON A / EAST",    ":/help/buttons_east.svg" },
	{ "B",                true,  "BUTTON B / SOUTH",   ":/help/buttons_south.svg" },
	{ "X",                true,  "BUTTON X / NORTH",   ":/help/buttons_north.svg" },
	{ "Y",                true,  "BUTTON Y / WEST",    ":/help/buttons_west.svg" },
	{ "LeftShoulder",     true,  "LEFT SHOULDER",      ":/help/button_l.svg" },
	{ "RightShoulder",    true,  "RIGHT SHOULDER",     ":/help/button_r.svg" },
	{ "LeftTrigger",      true,  "LEFT TRIGGER",       ":/help/button_lt.svg" },
	{ "RightTrigger",     true,  "RIGHT TRIGGER",      ":/help/button_rt.svg" },
	{ "LeftThumb",        true,  "LEFT THUMB",         ":/help/analog_thumb.svg" },
	{ "RightThumb",       true,  "RIGHT THUMB",        ":/help/analog_thumb.svg" },
	{ "LeftAnalogUp",     true,  "LEFT ANALOG UP",     ":/help/analog_up.svg" },
	{ "LeftAnalogDown",   true,  "LEFT ANALOG DOWN",   ":/help/analog_down.svg" },
	{ "LeftAnalogLeft",   true,  "LEFT ANALOG LEFT",   ":/help/analog_left.svg" },
	{ "LeftAnalogRight",  true,  "LEFT ANALOG RIGHT",  ":/help/analog_right.svg" },
	{ "RightAnalogUp",    true,  "RIGHT ANALOG UP",    ":/help/analog_up.svg" },
	{ "RightAnalogDown",  true,  "RIGHT ANALOG DOWN",  ":/help/analog_down.svg" },
	{ "RightAnalogLeft",  true,  "RIGHT ANALOG LEFT",  ":/help/analog_left.svg" },
	{ "RightAnalogRight", true,  "RIGHT ANALOG RIGHT", ":/help/analog_right.svg" },
	{ "HotKeyEnable",     true,  "HOTKEY ENABLE",      ":/help/button_hotkey.svg" }
};

//MasterVolUp and MasterVolDown are also hooked up, but do not appear on this screen.
//If you want, you can manually add them to es_input.cfg.

#define HOLD_TO_SKIP_MS 1000

GuiInputConfig::GuiInputConfig(Window* window, InputConfig* target, bool reconfigureAll, const std::function<void()>& okCallback) : GuiComponent(window),
	mBackground(window, ":/frame.png"), mGrid(window, Vector2i(1, 7)),
	mTargetConfig(target), mHoldingInput(false), mBusyAnim(window)
{
	LOG(LogInfo) << "Configuring device " << target->getDeviceId() << " (" << target->getDeviceName() << ").";

	if(reconfigureAll)
		target->clear();

	mConfiguringAll = reconfigureAll;
	mConfiguringRow = mConfiguringAll;

	addChild(&mBackground);
	addChild(&mGrid);

	// 0 is a spacer row
	mGrid.setEntry(std::make_shared<GuiComponent>(mWindow), Vector2i(0, 0), false);

	mTitle = std::make_shared<TextComponent>(mWindow, "CONFIGURING", Font::get(FONT_SIZE_LARGE), 0x555555FF, ALIGN_CENTER);
	mGrid.setEntry(mTitle, Vector2i(0, 1), false, true);

	std::stringstream ss;
	if(target->getDeviceId() == DEVICE_KEYBOARD)
		ss << "KEYBOARD";
	else if(target->getDeviceId() == DEVICE_CEC)
		ss << "CEC";
	else
		ss << "GAMEPAD " << (target->getDeviceId() + 1);
	mSubtitle1 = std::make_shared<TextComponent>(mWindow, Utils::String::toUpper(ss.str()), Font::get(FONT_SIZE_MEDIUM), 0x555555FF, ALIGN_CENTER);
	mGrid.setEntry(mSubtitle1, Vector2i(0, 2), false, true);

	mSubtitle2 = std::make_shared<TextComponent>(mWindow, "HOLD ANY BUTTON TO SKIP", Font::get(FONT_SIZE_SMALL), 0x999999FF, ALIGN_CENTER);
	mGrid.setEntry(mSubtitle2, Vector2i(0, 3), false, true);

	// 4 is a spacer row

	mList = std::make_shared<ComponentList>(mWindow);
	mGrid.setEntry(mList, Vector2i(0, 5), true, true);
	for(int i = 0; i < inputCount; i++)
	{
		ComponentListRow row;

		// icon
		auto icon = std::make_shared<ImageComponent>(mWindow);
		icon->setImage(GUI_INPUT_CONFIG_LIST[i].icon);
		icon->setColorShift(0x777777FF);
		icon->setResize(0, Font::get(FONT_SIZE_MEDIUM)->getLetterHeight() * 1.25f);
		row.addElement(icon, false);

		// spacer between icon and text
		auto spacer = std::make_shared<GuiComponent>(mWindow);
		spacer->setSize(16, 0);
		row.addElement(spacer, false);

		auto text = std::make_shared<TextComponent>(mWindow, GUI_INPUT_CONFIG_LIST[i].dispName, Font::get(FONT_SIZE_MEDIUM), 0x777777FF);
		row.addElement(text, true);

		auto mapping = std::make_shared<TextComponent>(mWindow, "-NOT DEFINED-", Font::get(FONT_SIZE_MEDIUM, FONT_PATH_LIGHT), 0x999999FF, ALIGN_RIGHT);
		setNotDefined(mapping); // overrides text and color set above
		row.addElement(mapping, true);
		mMappings.push_back(mapping);

		row.input_handler = [this, i, mapping](InputConfig* config, Input input) -> bool
		{
			// ignore input not from our target device
			if(config != mTargetConfig)
				return false;

			// if we're not configuring, start configuring when A is pressed
			if(!mConfiguringRow)
			{
				if(config->isMappedTo("a", input) && input.value)
				{
					mList->stopScrolling();
					mConfiguringRow = true;
					setPress(mapping);
					return true;
				}

				// we're not configuring and they didn't press A to start, so ignore this
				return false;
			}

			// we are configuring
			if(input.value != 0)
			{
				// input down
				// if we're already holding something, ignore this, otherwise plan to map this input
				if(mHoldingInput)
					return true;

				mHoldingInput = true;
				mHeldInput = input;
				mHeldTime = 0;
				mHeldInputId = i;

				return true;
			}else{
				// input up
				// make sure we were holding something and we let go of what we were previously holding
				if(!mHoldingInput || mHeldInput.device != input.device || mHeldInput.id != input.id || mHeldInput.type != input.type)
					return true;

				mHoldingInput = false;

				if(assign(mHeldInput, i))
					rowDone(); // if successful, move cursor/stop configuring - if not, we'll just try again

				return true;
			}
		};

		mList->addRow(row);
	}

	// only show "HOLD TO SKIP" if this input is skippable
	mList->setCursorChangedCallback([this](CursorState /*state*/) {
		bool skippable = GUI_INPUT_CONFIG_LIST[mList->getCursorId()].skippable;
		mSubtitle2->setOpacity(skippable * 255);
	});

	// make the first one say "PRESS ANYTHING" if we're re-configuring everything
	if(mConfiguringAll)
		setPress(mMappings.front());

	// buttons
	std::vector< std::shared_ptr<ButtonComponent> > buttons;
	std::function<void()> okFunction = [this, okCallback] {
		InputManager::getInstance()->writeDeviceConfig(mTargetConfig); // save
		if(okCallback)
			okCallback();
		delete this;
	};
	buttons.push_back(std::make_shared<ButtonComponent>(mWindow, "OK", "ok", [this, okFunction] {
		// check if the hotkey enable button is set. if not prompt the user to use select or nothing.
		Input input;
		if (!mTargetConfig->getInputByName("HotKeyEnable", &input)) {
			mWindow->pushGui(new GuiMsgBox(mWindow,
				"YOU DIDN'T CHOOSE A HOTKEY ENABLE BUTTON. THIS IS REQUIRED FOR EXITING GAMES WITH A CONTROLLER. DO YOU WANT TO USE THE SELECT BUTTON DEFAULT ? PLEASE ANSWER YES TO USE SELECT OR NO TO NOT SET A HOTKEY ENABLE BUTTON.",
				"YES", [this, okFunction] {
					Input input;
					mTargetConfig->getInputByName("Select", &input);
					mTargetConfig->mapInput("HotKeyEnable", input);
					okFunction();
					},
				"NO", [this, okFunction] {
					// for a disabled hotkey enable button, set to a key with id 0,
					// so the input configuration script can be backwards compatible.
					mTargetConfig->mapInput("HotKeyEnable", Input(DEVICE_KEYBOARD, TYPE_KEY, 0, 1, true));
					okFunction();
				}
			));
		} else {
			okFunction();
		}
	}));
	mButtonGrid = makeButtonGrid(mWindow, buttons);
	mGrid.setEntry(mButtonGrid, Vector2i(0, 6), true, false);

	setSize(Renderer::getScreenWidth() * 0.6f, Renderer::getScreenHeight() * 0.75f);
	setPosition((Renderer::getScreenWidth() - mSize.x()) / 2, (Renderer::getScreenHeight() - mSize.y()) / 2);
}

void GuiInputConfig::onSizeChanged()
{
	mBackground.fitTo(mSize, Vector3f::Zero(), Vector2f(-32, -32));

	// update grid
	mGrid.setSize(mSize);

	//mGrid.setRowHeightPerc(0, 0.025f);
	mGrid.setRowHeightPerc(1, mTitle->getFont()->getHeight()*0.75f / mSize.y());
	mGrid.setRowHeightPerc(2, mSubtitle1->getFont()->getHeight() / mSize.y());
	mGrid.setRowHeightPerc(3, mSubtitle2->getFont()->getHeight() / mSize.y());
	//mGrid.setRowHeightPerc(4, 0.03f);
	mGrid.setRowHeightPerc(5, (mList->getRowHeight(0) * 5 + 2) / mSize.y());
	mGrid.setRowHeightPerc(6, mButtonGrid->getSize().y() / mSize.y());

	mBusyAnim.setSize(mSize);
}

void GuiInputConfig::update(int deltaTime)
{
	if(mConfiguringRow && mHoldingInput && GUI_INPUT_CONFIG_LIST[mHeldInputId].skippable)
	{
		int prevSec = mHeldTime / 1000;
		mHeldTime += deltaTime;
		int curSec = mHeldTime / 1000;

		if(mHeldTime >= HOLD_TO_SKIP_MS)
		{
			setNotDefined(mMappings.at(mHeldInputId));
			clearAssignment(mHeldInputId);
			mHoldingInput = false;
			rowDone();
		}else{
			if(prevSec != curSec)
			{
				// crossed the second boundary, update text
				const auto& text = mMappings.at(mHeldInputId);
				std::stringstream ss;
				ss << "HOLD FOR " << HOLD_TO_SKIP_MS/1000 - curSec << "S TO SKIP";
				text->setText(ss.str());
				text->setColor(0x777777FF);
			}
		}
	}
}

// move cursor to the next thing if we're configuring all,
// or come out of "configure mode" if we were only configuring one row
void GuiInputConfig::rowDone()
{
	if(mConfiguringAll)
	{
		if(!mList->moveCursor(1)) // try to move to the next one
		{
			// at bottom of list, done
			mConfiguringAll = false;
			mConfiguringRow = false;
			mGrid.moveCursor(Vector2i(0, 1));
		}else{
			// on another one
			setPress(mMappings.at(mList->getCursorId()));
		}
	}else{
		// only configuring one row, so stop
		mConfiguringRow = false;
	}
}

void GuiInputConfig::setPress(const std::shared_ptr<TextComponent>& text)
{
	text->setText("PRESS ANYTHING");
	text->setColor(0x656565FF);
}

void GuiInputConfig::setNotDefined(const std::shared_ptr<TextComponent>& text)
{
	text->setText("-NOT DEFINED-");
	text->setColor(0x999999FF);
}

void GuiInputConfig::setAssignedTo(const std::shared_ptr<TextComponent>& text, Input input)
{
	text->setText(Utils::String::toUpper(input.string()));
	text->setColor(0x777777FF);
}

void GuiInputConfig::error(const std::shared_ptr<TextComponent>& text, const std::string& /*msg*/)
{
	text->setText("ALREADY TAKEN");
	text->setColor(0x656565FF);
}

bool GuiInputConfig::assign(Input input, int inputId)
{
	// input is from InputConfig* mTargetConfig

	// if this input is mapped to something other than "nothing" or the current row, error
	// (if it's the same as what it was before, allow it)
	if(mTargetConfig->getMappedTo(input).size() > 0 && !mTargetConfig->isMappedTo(GUI_INPUT_CONFIG_LIST[inputId].name, input) && strcmp(GUI_INPUT_CONFIG_LIST[inputId].name, "HotKeyEnable") != 0)
	{
		error(mMappings.at(inputId), "Already mapped!");
		return false;
	}

	setAssignedTo(mMappings.at(inputId), input);

	input.configured = true;
	mTargetConfig->mapInput(GUI_INPUT_CONFIG_LIST[inputId].name, input);

	LOG(LogInfo) << "  Mapping [" << input.string() << "] -> " << GUI_INPUT_CONFIG_LIST[inputId].name;

	return true;
}

void GuiInputConfig::clearAssignment(int inputId)
{
	mTargetConfig->unmapInput(GUI_INPUT_CONFIG_LIST[inputId].name);
}
<|endoftext|>


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

#pragma once

struct Options
{
    // Debug mode
    bool debug = false;
    // Print messages to standard output
    bool print = false;
    // Use subband dedispersion
    bool subbandDedispersion = false;
    // Avoid merging batches of dispersed data into contiguous memory
    bool splitBatchesDedispersion = false;
    // Compact the triggered events in time and DM dimensions
    bool compactResults = false;
    // Threshold for triggering
    float threshold = 0.0f;
    // SNR mode
    SNRMode snrMode;
};

struct DeviceOptions
{
    // OpenCL synchronized operations
    bool synchronized = false;
    // OpenCL platform ID
    unsigned int platformID = 0;
    // OpenCL device ID
    unsigned int deviceID = 0;
    // OpenCL device name
    std::string deviceName{};
    // Padding of OpenCL devices
    AstroData::paddingConf padding{};
};

struct DataOptions
{
    // Use LOFAR file as input
    bool dataLOFAR = false;
    // Use SIGPROC file as input
    bool dataSIGPROC = false;
    // Use PSRDADA buffer as input
    bool dataPSRDADA = false;
    // SIGPROC streaming mode
    bool streamingMode = false;
    // Size (in bytes) of the SIGPROC file header
    unsigned int headerSizeSIGPROC = 0;
    // Name of the input file
    std::string dataFile{};
    // Basename for the output files
    std::string outputFile{};
    // Name of the file containing the zapped channels
    std::string channelsFile{};
    // Name of the file containing the integration steps
    std::string integrationFile{};
#ifdef HAVE_HDF5
    // Limit the number of batches processed from a LOFAR file
    bool limit = false;
    // Name of the LOFAR header file
    std::string headerFile{};
#endif // HAVE_HDF5
#ifdef HAVE_PSRDADA
    // PSRDADA buffer key
    key_t dadaKey = 0;
#endif // HAVE_PSRDADA
};

struct GeneratorOptions
{
    // Use random numbers in generated data
    bool random = false;
    // Width of random generated pulse
    unsigned int width = 0;
    // DM of random generated pulse
    float DM = 0.0f;
};

struct HostMemory
{
    // Input data when reading a whole input file
    std::vector<std::vector<std::vector<inputDataType> *> *> input;
    // Input data when in streaming mode
    std::vector<std::vector<inputDataType> *> inputStream;
    // Zapped channels
    std::vector<unsigned int> zappedChannels;
    // Integration steps
    std::set<unsigned int> integrationSteps;
    // Map to create synthesized beams
    std::vector<unsigned int> beamMapping;
    // Dispersed data
    std::vector<inputDataType> dispersedData;
    // Subbanded data
    std::vector<outputDataType> subbandedData;
    // Dedispersed data
    std::vector<outputDataType> dedispersedData;
    // Integrated data
    std::vector<outputDataType> integratedData;
    // SNR data (SNR mode)
    std::vector<float> snrData;
    // Index of the sample with highest SNR value (SNR mode)
    std::vector<unsigned int> snrSamples;
    // Value of max sample (MOMAD mode)
    std::vector<outputDataType> maxValues;
    // Index of max sample (MOMAD MODE)
    std::vector<unsigned int> maxIndices;
    // Medians of medians (MOMAD mode)
    std::vector<outputDataType> mediansOfMedians;
    // Medians of medians absolute deviation (MOMAD mode)
    std::vector<outputDataType> medianOfMediansAbsoluteDeviation;
    // Shifts single step dedispersion
    std::vector<float> *shiftsSingleStep = nullptr;
    // Shifts step one subbanding dedispersion
    std::vector<float> *shiftsStepOne = nullptr;
    // Shifts step two subbanding dedispersion
    std::vector<float> *shiftsStepTwo = nullptr;
#ifdef HAVE_PSRDADA
    // PSRDADA ring buffer
    dada_hdu_t *ringBuffer = nullptr;
#endif // HAVE_PSRDADA
};

struct DeviceMemory
{
    // Shifts single step dedispersion
    cl::Buffer shiftsSingleStep;
    // Shifts step one subbanding dedispersion
    cl::Buffer shiftsStepOne;
    // Shifts step two subbanding dedispersion
    cl::Buffer shiftsStepTwo;
    // Zapped channels
    cl::Buffer zappedChannels;
    // Map to create synthesized beams
    cl::Buffer beamMapping;
    // Dispersed dada
    cl::Buffer dispersedData;
    // Subbanded data
    cl::Buffer subbandedData;
    // Dedispersed data
    cl::Buffer dedispersedData;
    // Integrated data
    cl::Buffer integratedData;
    // SNR data (SNR mode)
    cl::Buffer snrData;
    // Index of the sample with highest SNR value (SNR mode)
    cl::Buffer snrSamples;
    // Value of max sample (MOMAD mode)
    cl::Buffer maxValues;
    // Index of max sample (MOMAD mode)
    cl::Buffer maxIndices;
    // Median of medians first step (MOMAD mode)
    cl::Buffer medianOfMediansStepOne;
    // Median of medians second step (MOMAD mode)
    cl::Buffer medianOfMediansSecondStep;
};

struct KernelConfigurations
{
    // Configuration of single step dedispersion kernel
    Dedispersion::tunedDedispersionConf dedispersionSingleStepParameters;
    // Configuration of subband dedispersion kernel, step one
    Dedispersion::tunedDedispersionConf dedispersionStepOneParameters;
    // Configuration of subband dedispersion kernel, step two
    Dedispersion::tunedDedispersionConf dedispersionStepTwoParameters;
    // Configuration of integration kernel
    Integration::tunedIntegrationConf integrationParameters;
    // Configuration of SNR kernel
    SNR::tunedSNRConf snrParameters;
};

struct Kernels
{
    // Single step dedispersion kernel
    cl::Kernel *dedispersionSingleStep = nullptr;
    // Step one subbanding dedispersion kernel
    cl::Kernel *dedispersionStepOne = nullptr;
    // Step two subbanding dedispersion kernel
    cl::Kernel *dedispersionStepTwo = nullptr;
    // Integration kernels, one for each integration step
    std::vector<cl::Kernel *> integration;
    // SNR kernels, one for the original data and one for each integration step
    std::vector<cl::Kernel *> snr;
};

struct KernelRunTimeConfigurations
{
    // Global NDrange for single step dedispersion
    cl::NDRange dedispersionSingleStepGlobal;
    // Local NDRange for single step dedispersion
    cl::NDRange dedispersionSingleStepLocal;
    // Global NDRange for subbanding dedispersion step one
    cl::NDRange dedispersionStepOneGlobal;
    // Local NDRange for subbanding dedispersion step one
    cl::NDRange dedispersionStepOneLocal;
    // Global NDRange for subbanding dedispersion step two
    cl::NDRange dedispersionStepTwoGlobal;
    // Local NDRange for subbanding dedispersion step two
    cl::NDRange dedispersionStepTwoLocal;
    // Global NDRange for integration
    std::vector<cl::NDRange> integrationGlobal;
    // Local NDRange for integration
    std::vector<cl::NDRange> integrationLocal;
    // Global NDRange for SNR
    std::vector<cl::NDRange> snrGlobal;
    // Local NDRange for SNR
    std::vector<cl::NDRange> snrLocal;
};

struct Timers
{
    isa::utils::Timer inputLoad;
    isa::utils::Timer search;
    isa::utils::Timer inputHandling;
    isa::utils::Timer inputCopy;
    isa::utils::Timer dedispersionSingleStep;
    isa::utils::Timer dedispersionStepOne;
    isa::utils::Timer dedispersionStepTwo;
    isa::utils::Timer integration;
    isa::utils::Timer snr;
    isa::utils::Timer outputCopy;
    isa::utils::Timer trigger;
};

struct TriggeredEvent
{
    unsigned int beam = 0;
    unsigned int sample = 0;
    unsigned int integration = 0;
    float DM = 0.0f;
    float SNR = 0.0f;
};

struct CompactedEvent : TriggeredEvent
{
    unsigned int compactedIntegration = 1;
    unsigned int compactedDMs = 1;
};

using TriggeredEvents = std::vector<std::map<unsigned int, std::vector<TriggeredEvent>>>;
using CompactedEvents = std::vector<std::vector<CompactedEvent>>;

struct OpenCLRunTime
{
    cl::Context *context = nullptr;
    std::vector<cl::Platform> *platforms = nullptr;
    std::vector<cl::Device> *devices = nullptr;
    std::vector<std::vector<cl::CommandQueue>> *queues = nullptr;
};

enum SNRMode
{
    Standard,
    Momad
};
<commit_msg>Update on data types.<commit_after>// Copyright 2017 Netherlands Institute for Radio Astronomy (ASTRON)
// Copyright 2017 Netherlands eScience Center
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

struct Options
{
    // Debug mode
    bool debug = false;
    // Print messages to standard output
    bool print = false;
    // Use subband dedispersion
    bool subbandDedispersion = false;
    // Avoid merging batches of dispersed data into contiguous memory
    bool splitBatchesDedispersion = false;
    // Compact the triggered events in time and DM dimensions
    bool compactResults = false;
    // Threshold for triggering
    float threshold = 0.0f;
    // SNR mode
    SNRMode snrMode;
    // Step size for median of medians (MOMAD mode)
    unsigned int stepSize = 5;
};

struct DeviceOptions
{
    // OpenCL synchronized operations
    bool synchronized = false;
    // OpenCL platform ID
    unsigned int platformID = 0;
    // OpenCL device ID
    unsigned int deviceID = 0;
    // OpenCL device name
    std::string deviceName{};
    // Padding of OpenCL devices
    AstroData::paddingConf padding{};
};

struct DataOptions
{
    // Use LOFAR file as input
    bool dataLOFAR = false;
    // Use SIGPROC file as input
    bool dataSIGPROC = false;
    // Use PSRDADA buffer as input
    bool dataPSRDADA = false;
    // SIGPROC streaming mode
    bool streamingMode = false;
    // Size (in bytes) of the SIGPROC file header
    unsigned int headerSizeSIGPROC = 0;
    // Name of the input file
    std::string dataFile{};
    // Basename for the output files
    std::string outputFile{};
    // Name of the file containing the zapped channels
    std::string channelsFile{};
    // Name of the file containing the integration steps
    std::string integrationFile{};
#ifdef HAVE_HDF5
    // Limit the number of batches processed from a LOFAR file
    bool limit = false;
    // Name of the LOFAR header file
    std::string headerFile{};
#endif // HAVE_HDF5
#ifdef HAVE_PSRDADA
    // PSRDADA buffer key
    key_t dadaKey = 0;
#endif // HAVE_PSRDADA
};

struct GeneratorOptions
{
    // Use random numbers in generated data
    bool random = false;
    // Width of random generated pulse
    unsigned int width = 0;
    // DM of random generated pulse
    float DM = 0.0f;
};

struct HostMemory
{
    // Input data when reading a whole input file
    std::vector<std::vector<std::vector<inputDataType> *> *> input;
    // Input data when in streaming mode
    std::vector<std::vector<inputDataType> *> inputStream;
    // Zapped channels
    std::vector<unsigned int> zappedChannels;
    // Integration steps
    std::set<unsigned int> integrationSteps;
    // Map to create synthesized beams
    std::vector<unsigned int> beamMapping;
    // Dispersed data
    std::vector<inputDataType> dispersedData;
    // Subbanded data
    std::vector<outputDataType> subbandedData;
    // Dedispersed data
    std::vector<outputDataType> dedispersedData;
    // Integrated data
    std::vector<outputDataType> integratedData;
    // SNR data (SNR mode)
    std::vector<float> snrData;
    // Index of the sample with highest SNR value (SNR mode)
    std::vector<unsigned int> snrSamples;
    // Value of max sample (MOMAD mode)
    std::vector<outputDataType> maxValues;
    // Index of max sample (MOMAD MODE)
    std::vector<unsigned int> maxIndices;
    // Medians of medians (MOMAD mode)
    std::vector<outputDataType> mediansOfMedians;
    // Medians of medians absolute deviation (MOMAD mode)
    std::vector<outputDataType> medianOfMediansAbsoluteDeviation;
    // Shifts single step dedispersion
    std::vector<float> *shiftsSingleStep = nullptr;
    // Shifts step one subbanding dedispersion
    std::vector<float> *shiftsStepOne = nullptr;
    // Shifts step two subbanding dedispersion
    std::vector<float> *shiftsStepTwo = nullptr;
#ifdef HAVE_PSRDADA
    // PSRDADA ring buffer
    dada_hdu_t *ringBuffer = nullptr;
#endif // HAVE_PSRDADA
};

struct DeviceMemory
{
    // Shifts single step dedispersion
    cl::Buffer shiftsSingleStep;
    // Shifts step one subbanding dedispersion
    cl::Buffer shiftsStepOne;
    // Shifts step two subbanding dedispersion
    cl::Buffer shiftsStepTwo;
    // Zapped channels
    cl::Buffer zappedChannels;
    // Map to create synthesized beams
    cl::Buffer beamMapping;
    // Dispersed dada
    cl::Buffer dispersedData;
    // Subbanded data
    cl::Buffer subbandedData;
    // Dedispersed data
    cl::Buffer dedispersedData;
    // Integrated data
    cl::Buffer integratedData;
    // SNR data (SNR mode)
    cl::Buffer snrData;
    // Index of the sample with highest SNR value (SNR mode)
    cl::Buffer snrSamples;
    // Value of max sample (MOMAD mode)
    cl::Buffer maxValues;
    // Index of max sample (MOMAD mode)
    cl::Buffer maxIndices;
    // Median of medians first step (MOMAD mode)
    cl::Buffer medianOfMediansStepOne;
    // Median of medians second step (MOMAD mode)
    cl::Buffer medianOfMediansStepTwo;
};

struct KernelConfigurations
{
    // Configuration of single step dedispersion kernel
    Dedispersion::tunedDedispersionConf dedispersionSingleStepParameters;
    // Configuration of subband dedispersion kernel, step one
    Dedispersion::tunedDedispersionConf dedispersionStepOneParameters;
    // Configuration of subband dedispersion kernel, step two
    Dedispersion::tunedDedispersionConf dedispersionStepTwoParameters;
    // Configuration of integration kernel
    Integration::tunedIntegrationConf integrationParameters;
    // Configuration of SNR kernel
    SNR::tunedSNRConf snrParameters;
};

struct Kernels
{
    // Single step dedispersion kernel
    cl::Kernel *dedispersionSingleStep = nullptr;
    // Step one subbanding dedispersion kernel
    cl::Kernel *dedispersionStepOne = nullptr;
    // Step two subbanding dedispersion kernel
    cl::Kernel *dedispersionStepTwo = nullptr;
    // Integration kernels, one for each integration step
    std::vector<cl::Kernel *> integration;
    // SNR kernels, one for the original data and one for each integration step
    std::vector<cl::Kernel *> snr;
};

struct KernelRunTimeConfigurations
{
    // Global NDrange for single step dedispersion
    cl::NDRange dedispersionSingleStepGlobal;
    // Local NDRange for single step dedispersion
    cl::NDRange dedispersionSingleStepLocal;
    // Global NDRange for subbanding dedispersion step one
    cl::NDRange dedispersionStepOneGlobal;
    // Local NDRange for subbanding dedispersion step one
    cl::NDRange dedispersionStepOneLocal;
    // Global NDRange for subbanding dedispersion step two
    cl::NDRange dedispersionStepTwoGlobal;
    // Local NDRange for subbanding dedispersion step two
    cl::NDRange dedispersionStepTwoLocal;
    // Global NDRange for integration
    std::vector<cl::NDRange> integrationGlobal;
    // Local NDRange for integration
    std::vector<cl::NDRange> integrationLocal;
    // Global NDRange for SNR
    std::vector<cl::NDRange> snrGlobal;
    // Local NDRange for SNR
    std::vector<cl::NDRange> snrLocal;
};

struct Timers
{
    isa::utils::Timer inputLoad;
    isa::utils::Timer search;
    isa::utils::Timer inputHandling;
    isa::utils::Timer inputCopy;
    isa::utils::Timer dedispersionSingleStep;
    isa::utils::Timer dedispersionStepOne;
    isa::utils::Timer dedispersionStepTwo;
    isa::utils::Timer integration;
    isa::utils::Timer snr;
    isa::utils::Timer outputCopy;
    isa::utils::Timer trigger;
};

struct TriggeredEvent
{
    unsigned int beam = 0;
    unsigned int sample = 0;
    unsigned int integration = 0;
    float DM = 0.0f;
    float SNR = 0.0f;
};

struct CompactedEvent : TriggeredEvent
{
    unsigned int compactedIntegration = 1;
    unsigned int compactedDMs = 1;
};

using TriggeredEvents = std::vector<std::map<unsigned int, std::vector<TriggeredEvent>>>;
using CompactedEvents = std::vector<std::vector<CompactedEvent>>;

struct OpenCLRunTime
{
    cl::Context *context = nullptr;
    std::vector<cl::Platform> *platforms = nullptr;
    std::vector<cl::Device> *devices = nullptr;
    std::vector<std::vector<cl::CommandQueue>> *queues = nullptr;
};

enum SNRMode
{
    Standard,
    Momad
};
<|endoftext|>