<commit_before>#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#ifndef RADIANS_TO_DEGREES
#define RADIANS_TO_DEGREES(x) (x * 180.0f / PI)
#endif

#include "universe.hpp"
#include "scene.hpp"
#include "shader.hpp"
#include "material.hpp"
#include "species.hpp"
#include "object.hpp"
#include "vector_font.hpp"
#include "glyph.hpp"
#include "text3D.hpp"
#include "ground_level.hpp"
#include "render_templates.hpp"
#include "code/ylikuutio/config/setting.hpp"
#include "code/ylikuutio/config/setting_master.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"
#include "code/ylikuutio/common/global_variables.hpp"
#include "code/ylikuutio/common/any_value.hpp"
#include "code/ylikuutio/common/globals.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <iostream> // std::cout, std::cin, std::cerr
#include <stdint.h> // uint32_t etc.
#include <unordered_map> // std::unordered_map

extern GLFWwindow* window; // The "extern" keyword here is to access the variable "window" declared in tutorialXXX.cpp. This is a hack to keep the tutorials simple. Please avoid this.

namespace ontology
{
    Universe::Universe()
    {
        // constructor.
        this->world_radius = NAN; // world radius is NAN as long it doesn't get `set` by `SettingMaster`.
        this->setting_master_pointer = nullptr;
        this->console_pointer = nullptr;

        // Variables related to the window.
        this->window = nullptr;
        this->window_width = 1600; // default width.
        this->window_height = 900; // default height.

        // Variables related to the camera.
        this->aspect_ratio = static_cast<GLfloat>(this->window_width / this->window_height);
        this->initialFoV = 60.0f;

        this->text_size = 40; // default text size.
        this->font_size = 16; // default font size.

        this->max_FPS = 60; // default value max 60 frames per second.
        this->delta_time = NAN;
        this->last_time_before_reading_keyboard = NAN;
        this->current_time_before_reading_keyboard = NAN;

        this->has_mouse_ever_moved = false;
        this->can_toggle_invert_mouse = false;
        this->is_invert_mouse_in_use = false;
        this->can_toggle_flight_mode = false;
        this->is_flight_mode_in_use = false;
        this->is_first_turbo_pressed = false;
        this->is_second_turbo_pressed = false;

        this->child_vector_pointers_vector.push_back(&this->scene_pointer_vector);
    }

    Universe::~Universe()
    {
        // destructor.
        std::cout << "This world will be destroyed.\n";

        // destroy all scenes of this world.
        std::cout << "All scenes of this world will be destroyed.\n";
        hierarchy::delete_children<ontology::Scene*>(this->scene_pointer_vector);

        std::cout << "The setting master of this universe will be destroyed.\n";
        delete this->setting_master_pointer;
    }

    void Universe::render()
    {
        this->compute_matrices_from_inputs();

        // render this `Universe` by calling `render()` function of the active `Scene`.
        this->active_scene->render();
    }

    void Universe::set_active_scene(ontology::Scene* scene)
    {
        this->active_scene = scene;
    }

    void Universe::set_window(GLFWwindow* window)
    {
        this->window = window;
        glfwSetWindowUserPointer(this->window, this);
    }

    GLFWwindow* Universe::get_window()
    {
        return this->window;
    }

    uint32_t Universe::get_window_width()
    {
        return this->window_width;
    }

    uint32_t Universe::get_window_height()
    {
        return this->window_height;
    }

    uint32_t Universe::get_text_size()
    {
        return this->text_size;
    }

    uint32_t Universe::get_font_size()
    {
        return this->font_size;
    }

    float Universe::compute_delta_time()
    {
        if (std::isnan(this->last_time_before_reading_keyboard))
        {
            // `glfwGetTime()` is called here only once, the first time this function is called.
            this->last_time_before_reading_keyboard = glfwGetTime();
        }

        this->current_time_before_reading_keyboard = glfwGetTime();

        this->delta_time = static_cast<float>(current_time_before_reading_keyboard - last_time_before_reading_keyboard);
        return this->delta_time;
    }

    float Universe::get_delta_time()
    {
        return this->delta_time;
    }

    void Universe::finalize_delta_time_loop()
    {
        this->last_time_before_reading_keyboard = this->current_time_before_reading_keyboard;
    }

    uint32_t Universe::get_max_FPS()
    {
        return this->max_FPS;
    }

    // Public callbacks.

    datatypes::AnyValue* Universe::delete_entity(
            console::Console* console,
            ontology::Universe* universe,
            std::vector<std::string>& command_parameters)
    {
        if (console == nullptr || universe == nullptr || command_parameters.size() == 0)
        {
            return nullptr;
        }

        config::SettingMaster* setting_master = universe->setting_master_pointer;

        if (setting_master == nullptr)
        {
            return nullptr;
        }

        if (command_parameters.size() == 0)
        {
            // No command parameters.
            // Print variable names.
            console->print_text(setting_master->help());
        }
        else if (command_parameters.size() == 1)
        {
            std::string name = command_parameters[0];
            datatypes::AnyValue* any_value = universe->entity_anyvalue_map[name];

            if (any_value == nullptr)
            {
                return nullptr;
            }

            switch (any_value->type)
            {
                case (datatypes::datatype::UNIVERSE_POINTER):
                    // OK, this is an `Universe` to be deleted.
                    delete static_cast<ontology::Universe*>(any_value->universe_pointer);
                case (datatypes::datatype::SCENE_POINTER):
                    // OK, this is a `Scene` to be deleted.
                    delete static_cast<ontology::Scene*>(any_value->scene_pointer);
                case (datatypes::datatype::SHADER_POINTER):
                    // OK, this is a `Shader` to be deleted.
                    delete static_cast<ontology::Shader*>(any_value->shader_pointer);
                case (datatypes::datatype::MATERIAL_POINTER):
                    // OK, this is a `Material` to be deleted.
                    delete static_cast<ontology::Material*>(any_value->material_pointer);
                case (datatypes::datatype::SPECIES_POINTER):
                    // OK, this is a `Species` to be deleted.
                    delete static_cast<ontology::Species*>(any_value->species_pointer);
                case (datatypes::datatype::OBJECT_POINTER):
                    // OK, this is a `Object` to be deleted.
                    delete static_cast<ontology::Object*>(any_value->object_pointer);
                case (datatypes::datatype::VECTORFONT_POINTER):
                    // OK, this is a `VectorFont` to be deleted.
                    delete static_cast<ontology::VectorFont*>(any_value->vector_font_pointer);
                case (datatypes::datatype::GLYPH_POINTER):
                    // OK, this is a `Glyph` to be deleted.
                    delete static_cast<ontology::Glyph*>(any_value->glyph_pointer);
                case (datatypes::datatype::TEXT3D_POINTER):
                    // OK, this is a `Text3D` to be deleted.
                    delete static_cast<ontology::Text3D*>(any_value->text3D_pointer);
                default:
                    return nullptr;
            }
            delete any_value;
        }
        else
        {
            return nullptr;
        }
    }

    datatypes::AnyValue* Universe::info(
            console::Console* console,
            ontology::Universe* universe,
            std::vector<std::string>& command_parameters)
    {
        if (console == nullptr || universe == nullptr || command_parameters.size() == 0)
        {
            return nullptr;
        }

        config::SettingMaster* setting_master = universe->setting_master_pointer;

        if (setting_master == nullptr)
        {
            return nullptr;
        }

        if (command_parameters.size() == 0)
        {
            // No command parameters.
            // Print variable names.
            console->print_text(setting_master->help());
        }
        else if (command_parameters.size() == 1)
        {
            std::string name = command_parameters[0];
            datatypes::AnyValue* any_value = universe->entity_anyvalue_map[name];

            if (any_value == nullptr)
            {
                return nullptr;
            }

            // OK, let's find out information about the entity.

            // TODO: get info about the entity.
            delete any_value;
            return nullptr;
        }
        else
        {
            return nullptr;
        }
    }

    // Public callbacks end here.

    void Universe::set_scene_pointer(uint32_t childID, ontology::Scene* child_pointer)
    {
        hierarchy::set_child_pointer(childID, child_pointer, this->scene_pointer_vector, this->free_sceneID_queue);
    }

    void Universe::set_terrain_species_pointer(ontology::Species* terrain_species_pointer)
    {
        this->terrain_species_pointer = terrain_species_pointer;
    }

    void Universe::compute_matrices_from_inputs()
    {
        if (!globals::is_flight_mode_in_use)
        {
            globals::fallSpeed += globals::gravity;
            globals::position.y -= globals::fallSpeed;
        }

        GLfloat FoV = this->initialFoV;// - 5 * glfwGetMouseWheel(); // Now GLFW 3 requires setting up a callback for this. It's a bit too complicated for this beginner's tutorial, so it's disabled instead.

        // adjust position according to the ground.
        if (!globals::is_flight_mode_in_use)
        {
            if (this->terrain_species_pointer != nullptr)
            {
                GLfloat ground_y = ontology::get_floor_level(static_cast<ontology::Species*>(this->terrain_species_pointer), globals::position);

                if (!std::isnan(ground_y) && globals::position.y < ground_y)
                {
                    globals::position.y = ground_y;
                    globals::fallSpeed = 0.0f;
                }
            }
        }

        if (globals::testing_spherical_world_in_use)
        {
            // compute spherical coordinates.
            globals::spherical_position.rho = sqrt((globals::position.x * globals::position.x) + (globals::position.y * globals::position.y) + (globals::position.z * globals::position.z));
            globals::spherical_position.theta = RADIANS_TO_DEGREES(atan2(sqrt((globals::position.x * globals::position.x) + (globals::position.y * globals::position.y)), globals::position.z));
            globals::spherical_position.phi = RADIANS_TO_DEGREES(atan2(globals::position.y, globals::position.x));
        }

        camera_position = globals::position;
        camera_position.y += 2.0f;

        // Projection matrix : 45° Field of View, aspect ratio, display range : 0.1 unit <-> 100 units
        ProjectionMatrix = glm::perspective(FoV, aspect_ratio, 0.001f, 5000.0f + 2.0f * static_cast<GLfloat>(this->world_radius));
        // Camera matrix
        ViewMatrix = glm::lookAt(
                camera_position,                      // Camera is here
                camera_position + globals::direction, // and looks here : at the same position, plus "direction"
                globals::up                           // Head is up (set to 0,-1,0 to look upside-down)
                );
    }
}
<commit_msg>`void Universe::set_active_scene`: copy variables from `Scene` entity.<commit_after>#ifndef PI
#define PI 3.14159265359f
#endif

#ifndef GLM_FORCE_RADIANS
#define GLM_FORCE_RADIANS
#define DEGREES_TO_RADIANS(x) (x * PI / 180.0f)
#endif

#ifndef RADIANS_TO_DEGREES
#define RADIANS_TO_DEGREES(x) (x * 180.0f / PI)
#endif

#include "universe.hpp"
#include "scene.hpp"
#include "shader.hpp"
#include "material.hpp"
#include "species.hpp"
#include "object.hpp"
#include "vector_font.hpp"
#include "glyph.hpp"
#include "text3D.hpp"
#include "ground_level.hpp"
#include "render_templates.hpp"
#include "code/ylikuutio/config/setting.hpp"
#include "code/ylikuutio/config/setting_master.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.hpp"
#include "code/ylikuutio/common/global_variables.hpp"
#include "code/ylikuutio/common/any_value.hpp"
#include "code/ylikuutio/common/globals.hpp"

// Include GLEW
#ifndef __GL_GLEW_H_INCLUDED
#define __GL_GLEW_H_INCLUDED
#include <GL/glew.h> // GLfloat, GLuint etc.
#endif

// Include GLFW
#ifndef __GLFW3_H_INCLUDED
#define __GLFW3_H_INCLUDED
#include <glfw3.h>
#endif

// Include standard headers
#include <cmath>    // NAN, std::isnan, std::pow
#include <iostream> // std::cout, std::cin, std::cerr
#include <stdint.h> // uint32_t etc.
#include <unordered_map> // std::unordered_map

extern GLFWwindow* window; // The "extern" keyword here is to access the variable "window" declared in tutorialXXX.cpp. This is a hack to keep the tutorials simple. Please avoid this.

namespace ontology
{
    Universe::Universe()
    {
        // constructor.
        this->world_radius = NAN; // world radius is NAN as long it doesn't get `set` by `SettingMaster`.
        this->setting_master_pointer = nullptr;
        this->console_pointer = nullptr;

        // Variables related to the window.
        this->window = nullptr;
        this->window_width = 1600; // default width.
        this->window_height = 900; // default height.

        // Variables related to the camera.
        this->aspect_ratio = static_cast<GLfloat>(this->window_width / this->window_height);
        this->initialFoV = 60.0f;

        this->text_size = 40; // default text size.
        this->font_size = 16; // default font size.

        this->max_FPS = 60; // default value max 60 frames per second.
        this->delta_time = NAN;
        this->last_time_before_reading_keyboard = NAN;
        this->current_time_before_reading_keyboard = NAN;

        this->has_mouse_ever_moved = false;
        this->can_toggle_invert_mouse = false;
        this->is_invert_mouse_in_use = false;
        this->can_toggle_flight_mode = false;
        this->is_flight_mode_in_use = false;
        this->is_first_turbo_pressed = false;
        this->is_second_turbo_pressed = false;

        this->child_vector_pointers_vector.push_back(&this->scene_pointer_vector);
    }

    Universe::~Universe()
    {
        // destructor.
        std::cout << "This world will be destroyed.\n";

        // destroy all scenes of this world.
        std::cout << "All scenes of this world will be destroyed.\n";
        hierarchy::delete_children<ontology::Scene*>(this->scene_pointer_vector);

        std::cout << "The setting master of this universe will be destroyed.\n";
        delete this->setting_master_pointer;
    }

    void Universe::render()
    {
        this->compute_matrices_from_inputs();

        // render this `Universe` by calling `render()` function of the active `Scene`.
        this->active_scene->render();
    }

    void Universe::set_active_scene(ontology::Scene* scene)
    {
        this->cartesian_coordinates = scene->cartesian_coordinates;
        this->direction = scene->direction;
        this->right = scene->right;
        this->up = scene->up;
        this->spherical_coordinates = scene->spherical_coordinates;
        this->horizontal_angle = scene->horizontal_angle;
        this->vertical_angle = scene->vertical_angle;
        this->active_scene = scene;
    }

    void Universe::set_window(GLFWwindow* window)
    {
        this->window = window;
        glfwSetWindowUserPointer(this->window, this);
    }

    GLFWwindow* Universe::get_window()
    {
        return this->window;
    }

    uint32_t Universe::get_window_width()
    {
        return this->window_width;
    }

    uint32_t Universe::get_window_height()
    {
        return this->window_height;
    }

    uint32_t Universe::get_text_size()
    {
        return this->text_size;
    }

    uint32_t Universe::get_font_size()
    {
        return this->font_size;
    }

    float Universe::compute_delta_time()
    {
        if (std::isnan(this->last_time_before_reading_keyboard))
        {
            // `glfwGetTime()` is called here only once, the first time this function is called.
            this->last_time_before_reading_keyboard = glfwGetTime();
        }

        this->current_time_before_reading_keyboard = glfwGetTime();

        this->delta_time = static_cast<float>(current_time_before_reading_keyboard - last_time_before_reading_keyboard);
        return this->delta_time;
    }

    float Universe::get_delta_time()
    {
        return this->delta_time;
    }

    void Universe::finalize_delta_time_loop()
    {
        this->last_time_before_reading_keyboard = this->current_time_before_reading_keyboard;
    }

    uint32_t Universe::get_max_FPS()
    {
        return this->max_FPS;
    }

    // Public callbacks.

    datatypes::AnyValue* Universe::delete_entity(
            console::Console* console,
            ontology::Universe* universe,
            std::vector<std::string>& command_parameters)
    {
        if (console == nullptr || universe == nullptr || command_parameters.size() == 0)
        {
            return nullptr;
        }

        config::SettingMaster* setting_master = universe->setting_master_pointer;

        if (setting_master == nullptr)
        {
            return nullptr;
        }

        if (command_parameters.size() == 0)
        {
            // No command parameters.
            // Print variable names.
            console->print_text(setting_master->help());
        }
        else if (command_parameters.size() == 1)
        {
            std::string name = command_parameters[0];
            datatypes::AnyValue* any_value = universe->entity_anyvalue_map[name];

            if (any_value == nullptr)
            {
                return nullptr;
            }

            switch (any_value->type)
            {
                case (datatypes::datatype::UNIVERSE_POINTER):
                    // OK, this is an `Universe` to be deleted.
                    delete static_cast<ontology::Universe*>(any_value->universe_pointer);
                case (datatypes::datatype::SCENE_POINTER):
                    // OK, this is a `Scene` to be deleted.
                    delete static_cast<ontology::Scene*>(any_value->scene_pointer);
                case (datatypes::datatype::SHADER_POINTER):
                    // OK, this is a `Shader` to be deleted.
                    delete static_cast<ontology::Shader*>(any_value->shader_pointer);
                case (datatypes::datatype::MATERIAL_POINTER):
                    // OK, this is a `Material` to be deleted.
                    delete static_cast<ontology::Material*>(any_value->material_pointer);
                case (datatypes::datatype::SPECIES_POINTER):
                    // OK, this is a `Species` to be deleted.
                    delete static_cast<ontology::Species*>(any_value->species_pointer);
                case (datatypes::datatype::OBJECT_POINTER):
                    // OK, this is a `Object` to be deleted.
                    delete static_cast<ontology::Object*>(any_value->object_pointer);
                case (datatypes::datatype::VECTORFONT_POINTER):
                    // OK, this is a `VectorFont` to be deleted.
                    delete static_cast<ontology::VectorFont*>(any_value->vector_font_pointer);
                case (datatypes::datatype::GLYPH_POINTER):
                    // OK, this is a `Glyph` to be deleted.
                    delete static_cast<ontology::Glyph*>(any_value->glyph_pointer);
                case (datatypes::datatype::TEXT3D_POINTER):
                    // OK, this is a `Text3D` to be deleted.
                    delete static_cast<ontology::Text3D*>(any_value->text3D_pointer);
                default:
                    return nullptr;
            }
            delete any_value;
        }
        else
        {
            return nullptr;
        }
    }

    datatypes::AnyValue* Universe::info(
            console::Console* console,
            ontology::Universe* universe,
            std::vector<std::string>& command_parameters)
    {
        if (console == nullptr || universe == nullptr || command_parameters.size() == 0)
        {
            return nullptr;
        }

        config::SettingMaster* setting_master = universe->setting_master_pointer;

        if (setting_master == nullptr)
        {
            return nullptr;
        }

        if (command_parameters.size() == 0)
        {
            // No command parameters.
            // Print variable names.
            console->print_text(setting_master->help());
        }
        else if (command_parameters.size() == 1)
        {
            std::string name = command_parameters[0];
            datatypes::AnyValue* any_value = universe->entity_anyvalue_map[name];

            if (any_value == nullptr)
            {
                return nullptr;
            }

            // OK, let's find out information about the entity.

            // TODO: get info about the entity.
            delete any_value;
            return nullptr;
        }
        else
        {
            return nullptr;
        }
    }

    // Public callbacks end here.

    void Universe::set_scene_pointer(uint32_t childID, ontology::Scene* child_pointer)
    {
        hierarchy::set_child_pointer(childID, child_pointer, this->scene_pointer_vector, this->free_sceneID_queue);
    }

    void Universe::set_terrain_species_pointer(ontology::Species* terrain_species_pointer)
    {
        this->terrain_species_pointer = terrain_species_pointer;
    }

    void Universe::compute_matrices_from_inputs()
    {
        if (!globals::is_flight_mode_in_use)
        {
            globals::fallSpeed += globals::gravity;
            globals::position.y -= globals::fallSpeed;
        }

        GLfloat FoV = this->initialFoV;// - 5 * glfwGetMouseWheel(); // Now GLFW 3 requires setting up a callback for this. It's a bit too complicated for this beginner's tutorial, so it's disabled instead.

        // adjust position according to the ground.
        if (!globals::is_flight_mode_in_use)
        {
            if (this->terrain_species_pointer != nullptr)
            {
                GLfloat ground_y = ontology::get_floor_level(static_cast<ontology::Species*>(this->terrain_species_pointer), globals::position);

                if (!std::isnan(ground_y) && globals::position.y < ground_y)
                {
                    globals::position.y = ground_y;
                    globals::fallSpeed = 0.0f;
                }
            }
        }

        if (globals::testing_spherical_world_in_use)
        {
            // compute spherical coordinates.
            globals::spherical_position.rho = sqrt((globals::position.x * globals::position.x) + (globals::position.y * globals::position.y) + (globals::position.z * globals::position.z));
            globals::spherical_position.theta = RADIANS_TO_DEGREES(atan2(sqrt((globals::position.x * globals::position.x) + (globals::position.y * globals::position.y)), globals::position.z));
            globals::spherical_position.phi = RADIANS_TO_DEGREES(atan2(globals::position.y, globals::position.x));
        }

        camera_position = globals::position;
        camera_position.y += 2.0f;

        // Projection matrix : 45° Field of View, aspect ratio, display range : 0.1 unit <-> 100 units
        ProjectionMatrix = glm::perspective(FoV, aspect_ratio, 0.001f, 5000.0f + 2.0f * static_cast<GLfloat>(this->world_radius));
        // Camera matrix
        ViewMatrix = glm::lookAt(
                camera_position,                      // Camera is here
                camera_position + globals::direction, // and looks here : at the same position, plus "direction"
                globals::up                           // Head is up (set to 0,-1,0 to look upside-down)
                );
    }
}
<|endoftext|>


<commit_before><commit_msg>Bugfix: `Universe` constructor: initialize member variables.<commit_after><|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/
/* ************************************************************************
 * Copyright 2015 Vratis, Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ************************************************************************ */

#include <miopen/env.hpp>
#include <miopen/errors.hpp>
#include <miopen/kernel_cache.hpp>
#include <miopen/logger.hpp>
#include <miopen/stringutils.hpp>

#include <iostream>
#include <iterator>

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEVICE_ARCH)

namespace miopen {

static void ProcessParams(std::string& params)
{
    if(params.length() > 0)
    {
        // Ensure only one space after the -cl-std.
        // >1 space can cause an Apple compiler bug. See clSPARSE issue #141.
        if(params.at(0) != ' ')
        {
            params = " " + params;
        }
    }
}

const std::vector<Kernel>& KernelCache::GetKernels(const std::string& algorithm,
                                                   const std::string& network_config)
{

    std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);

    const auto it = kernel_map.find(key);
    if(it != kernel_map.end())
    {
        MIOPEN_LOG_I2(it->second.size() << " kernels for key: " << key.first << " \"" << key.second
                                        << '\"');
        return it->second;
    }

    static const std::vector<Kernel> empty{};
    MIOPEN_LOG_I2("0 kernels for key: " << key.first << " \"" << key.second << '\"');
    return empty;
}

bool KernelCache::HasKernels(const std::string& algorithm, const std::string& network_config) const
{
    const auto key = std::make_pair(algorithm, network_config);
#ifndef NDEBUG
    MIOPEN_LOG_I("Key: " << key.first << " \"" << key.second << '\"');
#endif
    const auto it = kernel_map.find(key);
    if(it == kernel_map.end())
        return false;

    if(it->second.empty())
    {
        MIOPEN_THROW("There should be at least one kernel in kernel cache if an entry exists");
    }

    return true;
}

bool KernelCache::HasProgram(const std::string& name, const std::string& params) const
{
    const auto key = std::make_pair(name, params);
    return program_map.count(key) > 0;
}

void KernelCache::AddProgram(Program prog, const std::string& program_name, std::string params)
{
    ProcessParams(params);
    program_map[std::make_pair(program_name, params)] = prog;
}

Kernel KernelCache::AddKernel(const Handle& h,
                              const std::string& algorithm,
                              const std::string& network_config,
                              const std::string& program_name,
                              const std::string& kernel_name,
                              const std::vector<size_t>& vld,
                              const std::vector<size_t>& vgd,
                              std::string params,
                              std::size_t cache_index,
                              bool is_kernel_miopengemm_str,
                              const std::string& kernel_src)
{
    ProcessParams(params);

    const std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
    if(!network_config.empty() || !algorithm.empty()) // Don't log only _empty_ keys.
        MIOPEN_LOG_I2("Key: " << key.first << " \"" << key.second << '\"');

    Program program;

    auto program_it = program_map.find(std::make_pair(program_name, params));
    if(program_it != program_map.end())
    {
        program = program_it->second;
    }
    else
    {
        if(!is_kernel_miopengemm_str) // default value
            is_kernel_miopengemm_str = algorithm.find("ImplicitGEMM") == std::string::npos &&
                                       algorithm.find("GEMM") != std::string::npos;
        program = h.LoadProgram(program_name, params, is_kernel_miopengemm_str, kernel_src);
        program_map[std::make_pair(program_name, params)] = program;
    }

    Kernel kernel{};
    const char* const arch = miopen::GetStringEnv(MIOPEN_DEVICE_ARCH{});
    if(arch != nullptr && strlen(arch) > 0)
    {
        kernel = Kernel{program, kernel_name};
    }
    else
    {
        kernel = Kernel{program, kernel_name, vld, vgd};
    }

    if(!network_config.empty() && !algorithm.empty())
    {
        this->AddKernel(key, kernel, cache_index);
    }
    return kernel;
}

void KernelCache::AddKernel(Key key, Kernel k, std::size_t cache_index)
{
    auto&& v = kernel_map[key];
    if(cache_index >= v.size())
    {
        v.resize(cache_index + 1);
    }
    v[cache_index] = k;
}

void KernelCache::ClearKernels(const std::string& algorithm, const std::string& network_config)
{
    if(network_config.empty() || algorithm.empty())
    {
        MIOPEN_THROW("Network config or algorithm empty.");
    }
    const std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
    auto&& v = this->kernel_map[key];
    if(!v.empty())
    {
        MIOPEN_LOG_I2(v.size() << " kernels for key: " << key.first << " \"" << key.second << '\"');
    }
    v.clear();
}

KernelCache::KernelCache() {}

} // namespace miopen
<commit_msg>Remove outdated (and now wrong & harmful) workaround for apple (#741)<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/
/* ************************************************************************
 * Copyright 2015 Vratis, Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ************************************************************************ */

#include <miopen/env.hpp>
#include <miopen/errors.hpp>
#include <miopen/kernel_cache.hpp>
#include <miopen/logger.hpp>
#include <miopen/stringutils.hpp>

#include <iostream>
#include <iterator>

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEVICE_ARCH)

namespace miopen {

const std::vector<Kernel>& KernelCache::GetKernels(const std::string& algorithm,
                                                   const std::string& network_config)
{

    std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);

    const auto it = kernel_map.find(key);
    if(it != kernel_map.end())
    {
        MIOPEN_LOG_I2(it->second.size() << " kernels for key: " << key.first << " \"" << key.second
                                        << '\"');
        return it->second;
    }

    static const std::vector<Kernel> empty{};
    MIOPEN_LOG_I2("0 kernels for key: " << key.first << " \"" << key.second << '\"');
    return empty;
}

bool KernelCache::HasKernels(const std::string& algorithm, const std::string& network_config) const
{
    const auto key = std::make_pair(algorithm, network_config);
#ifndef NDEBUG
    MIOPEN_LOG_I("Key: " << key.first << " \"" << key.second << '\"');
#endif
    const auto it = kernel_map.find(key);
    if(it == kernel_map.end())
        return false;

    if(it->second.empty())
    {
        MIOPEN_THROW("There should be at least one kernel in kernel cache if an entry exists");
    }

    return true;
}

bool KernelCache::HasProgram(const std::string& name, const std::string& params) const
{
    const auto key = std::make_pair(name, params);
    return program_map.count(key) > 0;
}

void KernelCache::AddProgram(Program prog, const std::string& program_name, std::string params)
{
    program_map[std::make_pair(program_name, params)] = prog;
}

Kernel KernelCache::AddKernel(const Handle& h,
                              const std::string& algorithm,
                              const std::string& network_config,
                              const std::string& program_name,
                              const std::string& kernel_name,
                              const std::vector<size_t>& vld,
                              const std::vector<size_t>& vgd,
                              std::string params,
                              std::size_t cache_index,
                              bool is_kernel_miopengemm_str,
                              const std::string& kernel_src)
{
    const std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
    if(!network_config.empty() || !algorithm.empty()) // Don't log only _empty_ keys.
        MIOPEN_LOG_I2("Key: " << key.first << " \"" << key.second << '\"');

    Program program;

    auto program_it = program_map.find(std::make_pair(program_name, params));
    if(program_it != program_map.end())
    {
        program = program_it->second;
    }
    else
    {
        if(!is_kernel_miopengemm_str) // default value
            is_kernel_miopengemm_str = algorithm.find("ImplicitGEMM") == std::string::npos &&
                                       algorithm.find("GEMM") != std::string::npos;
        program = h.LoadProgram(program_name, params, is_kernel_miopengemm_str, kernel_src);
        program_map[std::make_pair(program_name, params)] = program;
    }

    Kernel kernel{};
    const char* const arch = miopen::GetStringEnv(MIOPEN_DEVICE_ARCH{});
    if(arch != nullptr && strlen(arch) > 0)
    {
        kernel = Kernel{program, kernel_name};
    }
    else
    {
        kernel = Kernel{program, kernel_name, vld, vgd};
    }

    if(!network_config.empty() && !algorithm.empty())
    {
        this->AddKernel(key, kernel, cache_index);
    }
    return kernel;
}

void KernelCache::AddKernel(Key key, Kernel k, std::size_t cache_index)
{
    auto&& v = kernel_map[key];
    if(cache_index >= v.size())
    {
        v.resize(cache_index + 1);
    }
    v[cache_index] = k;
}

void KernelCache::ClearKernels(const std::string& algorithm, const std::string& network_config)
{
    if(network_config.empty() || algorithm.empty())
    {
        MIOPEN_THROW("Network config or algorithm empty.");
    }
    const std::pair<std::string, std::string> key = std::make_pair(algorithm, network_config);
    auto&& v = this->kernel_map[key];
    if(!v.empty())
    {
        MIOPEN_LOG_I2(v.size() << " kernels for key: " << key.first << " \"" << key.second << '\"');
    }
    v.clear();
}

KernelCache::KernelCache() {}

} // namespace miopen
<|endoftext|>


<commit_before>#include "kernelrecord.h"

#include "wallet.h"
#include "base58.h"

#ifdef _MSC_VER
#pragma warning( disable : 4345)
#endif

using namespace std;

bool KernelRecord::showTransaction(const CWalletTx &wtx)
{
    if (wtx.IsCoinBase())
    {
        if (wtx.GetDepthInMainChain() < 2)
        {
            return false;
        }
    }

    if(!wtx.IsTrusted())
    {
        return false;
    }

    return true;
}

/*
 * Decompose CWallet transaction to model kernel records.
 */
vector<KernelRecord> KernelRecord::decomposeOutput(const CWallet *wallet, const CWalletTx &wtx)
{
    vector<KernelRecord> parts;
    int64_t nTime = wtx.GetTxTime();
    uint256 hash = wtx.GetHash();
    std::map<std::string, std::string> mapValue = wtx.mapValue;
    int64_t nDayWeight = (min((GetAdjustedTime() - nTime), (int64_t)(nStakeMaxAge+nStakeMinAge)) - nStakeMinAge); // DayWeight * 86400, чтобы был
                                                                                // правильный расчёт CoinAge
    if (showTransaction(wtx))
    {
        for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
        {
            CTxOut txOut = wtx.vout[nOut];
            if( wallet->IsMine(txOut) ) {
                CTxDestination address;
                std::string addrStr;

                uint64_t coinAge = max( (txOut.nValue * nDayWeight) / (COIN * nOneDay), 0LL);

                if (ExtractDestination(txOut.scriptPubKey, address))
                {
                    // Sent to Bitcoin Address
                    addrStr = CBitcoinAddress(address).ToString();
                }
                else
                {
                    // Sent to IP, or other non-address transaction like OP_EVAL
                    addrStr = mapValue["to"];
                }

                parts.push_back(KernelRecord(hash, nTime, addrStr, txOut.nValue, wtx.IsSpent(nOut), coinAge));
            }
        }
    }

    return parts;
}

std::string KernelRecord::getTxID()
{
    return hash.ToString() + strprintf("-%03d", idx);
}

int64_t KernelRecord::getAge() const
{
    return (GetAdjustedTime() - nTime) / nOneDay;
}

uint64_t KernelRecord::getCoinDay() const
{
    int64_t nWeight = GetAdjustedTime() - nTime - nStakeMinAge;
    if( nWeight <  0)
        return 0;
    nWeight = min(nWeight, (int64_t)nStakeMaxAge);
    uint64_t coinAge = (nValue * nWeight ) / (COIN * nOneDay);
    return coinAge;
}

int64_t KernelRecord::getPoSReward(int nBits, int minutes)
{
    int64_t PoSReward;
    int64_t nWeight = GetAdjustedTime() - nTime + minutes * 60;
    if( nWeight <  nStakeMinAge)
        return 0;
    uint64_t coinAge = (nValue * nWeight ) / (COIN * nOneDay);
    PoSReward = GetProofOfStakeReward(coinAge, nBits, GetAdjustedTime() + minutes * 60);
    return PoSReward;
}

double KernelRecord::getProbToMintStake(double difficulty, int timeOffset) const
{
    //double maxTarget = pow(static_cast<double>(2), 224);
    //double target = maxTarget / difficulty;
    //int dayWeight = (min((GetAdjustedTime() - nTime) + timeOffset, (int64_t)(nStakeMinAge+nStakeMaxAge)) - nStakeMinAge) / 86400;
    //uint64_t coinAge = max(nValue * dayWeight / COIN, (int64_t)0);
    //return target * coinAge / pow(static_cast<double>(2), 256);
    int64_t Weight = (min((GetAdjustedTime() - nTime) + timeOffset, (int64_t)(nStakeMinAge+nStakeMaxAge)) - nStakeMinAge);
    uint64_t coinAge = max(nValue * Weight / (COIN * nOneDay), 0LL);
    return coinAge / (pow(static_cast<double>(2),32) * difficulty);
}

double KernelRecord::getProbToMintWithinNMinutes(double difficulty, int minutes)
{
    if(difficulty != prevDifficulty || minutes != prevMinutes)
    {
        double prob = 1;
        double p;
        int d = minutes / (60 * 24); // Number of full days
        int m = minutes % (60 * 24); // Number of minutes in the last day
        int i, timeOffset;

        // Probabilities for the first d days
        for(i = 0; i < d; i++)
        {
            timeOffset = i * nOneDay;
            p = pow(1 - getProbToMintStake(difficulty, timeOffset), nOneDay);
            prob *= p;
        }

        // Probability for the m minutes of the last day
        timeOffset = d * nOneDay;
        p = pow(1 - getProbToMintStake(difficulty, timeOffset), 60 * m);
        prob *= p;

        prob = 1 - prob;
        prevProbability = prob;
        prevDifficulty = difficulty;
        prevMinutes = minutes;
    }
    return prevProbability;
}
<commit_msg>Fix compilation errors.<commit_after>#include "kernelrecord.h"

#include "wallet.h"
#include "base58.h"

#ifdef _MSC_VER
#pragma warning( disable : 4345)
#endif

using namespace std;

bool KernelRecord::showTransaction(const CWalletTx &wtx)
{
    if (wtx.IsCoinBase())
    {
        if (wtx.GetDepthInMainChain() < 2)
        {
            return false;
        }
    }

    if(!wtx.IsTrusted())
    {
        return false;
    }

    return true;
}

/*
 * Decompose CWallet transaction to model kernel records.
 */
vector<KernelRecord> KernelRecord::decomposeOutput(const CWallet *wallet, const CWalletTx &wtx)
{
    vector<KernelRecord> parts;
    int64_t nTime = wtx.GetTxTime();
    uint256 hash = wtx.GetHash();
    std::map<std::string, std::string> mapValue = wtx.mapValue;
    int64_t nDayWeight = (min((GetAdjustedTime() - nTime), (int64_t)(nStakeMaxAge+nStakeMinAge)) - nStakeMinAge); // DayWeight * 86400, чтобы был
                                                                                // правильный расчёт CoinAge
    if (showTransaction(wtx))
    {
        for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
        {
            CTxOut txOut = wtx.vout[nOut];
            if( wallet->IsMine(txOut) ) {
                CTxDestination address;
                std::string addrStr;

                uint64_t coinAge = max( (txOut.nValue * nDayWeight) / (COIN * nOneDay), (int64_t)0);

                if (ExtractDestination(txOut.scriptPubKey, address))
                {
                    // Sent to Bitcoin Address
                    addrStr = CBitcoinAddress(address).ToString();
                }
                else
                {
                    // Sent to IP, or other non-address transaction like OP_EVAL
                    addrStr = mapValue["to"];
                }

                parts.push_back(KernelRecord(hash, nTime, addrStr, txOut.nValue, wtx.IsSpent(nOut), coinAge));
            }
        }
    }

    return parts;
}

std::string KernelRecord::getTxID()
{
    return hash.ToString() + strprintf("-%03d", idx);
}

int64_t KernelRecord::getAge() const
{
    return (GetAdjustedTime() - nTime) / nOneDay;
}

uint64_t KernelRecord::getCoinDay() const
{
    int64_t nWeight = GetAdjustedTime() - nTime - nStakeMinAge;
    if( nWeight <  0)
        return 0;
    nWeight = min(nWeight, (int64_t)nStakeMaxAge);
    uint64_t coinAge = (nValue * nWeight ) / (COIN * nOneDay);
    return coinAge;
}

int64_t KernelRecord::getPoSReward(int nBits, int minutes)
{
    int64_t PoSReward;
    int64_t nWeight = GetAdjustedTime() - nTime + minutes * 60;
    if( nWeight <  nStakeMinAge)
        return 0;
    uint64_t coinAge = (nValue * nWeight ) / (COIN * nOneDay);
    PoSReward = GetProofOfStakeReward(coinAge, nBits, GetAdjustedTime() + minutes * 60);
    return PoSReward;
}

double KernelRecord::getProbToMintStake(double difficulty, int timeOffset) const
{
    //double maxTarget = pow(static_cast<double>(2), 224);
    //double target = maxTarget / difficulty;
    //int dayWeight = (min((GetAdjustedTime() - nTime) + timeOffset, (int64_t)(nStakeMinAge+nStakeMaxAge)) - nStakeMinAge) / 86400;
    //uint64_t coinAge = max(nValue * dayWeight / COIN, (int64_t)0);
    //return target * coinAge / pow(static_cast<double>(2), 256);
    int64_t Weight = (min((GetAdjustedTime() - nTime) + timeOffset, (int64_t)(nStakeMinAge+nStakeMaxAge)) - nStakeMinAge);
    uint64_t coinAge = max(nValue * Weight / (COIN * nOneDay), (int64_t)0);
    return coinAge / (pow(static_cast<double>(2),32) * difficulty);
}

double KernelRecord::getProbToMintWithinNMinutes(double difficulty, int minutes)
{
    if(difficulty != prevDifficulty || minutes != prevMinutes)
    {
        double prob = 1;
        double p;
        int d = minutes / (60 * 24); // Number of full days
        int m = minutes % (60 * 24); // Number of minutes in the last day
        int i, timeOffset;

        // Probabilities for the first d days
        for(i = 0; i < d; i++)
        {
            timeOffset = i * nOneDay;
            p = pow(1 - getProbToMintStake(difficulty, timeOffset), nOneDay);
            prob *= p;
        }

        // Probability for the m minutes of the last day
        timeOffset = d * nOneDay;
        p = pow(1 - getProbToMintStake(difficulty, timeOffset), 60 * m);
        prob *= p;

        prob = 1 - prob;
        prevProbability = prob;
        prevDifficulty = difficulty;
        prevMinutes = minutes;
    }
    return prevProbability;
}
<|endoftext|>


<commit_before>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/system_monitor.h"
#include "testing/gtest/include/gtest/gtest.h"

class PowerTest : public base::SystemMonitor::PowerObserver {
 public:
  PowerTest()
    : battery_(false),
      power_state_changes_(0),
      suspends_(0),
      resumes_(0) {};

  // PowerObserver callbacks.
  void OnPowerStateChange(base::SystemMonitor*) { power_state_changes_++; };
  void OnSuspend(base::SystemMonitor*) { suspends_++; };
  void OnResume(base::SystemMonitor*) { resumes_++; };

  // Test status counts.
  bool battery() { return battery_; }
  int power_state_changes() { return power_state_changes_; }
  int suspends() { return suspends_; }
  int resumes() { return resumes_; }

 private:
  bool battery_;   // Do we currently think we're on battery power.
  int power_state_changes_;  // Count of OnPowerStateChange notifications.
  int suspends_;  // Count of OnSuspend notifications.
  int resumes_;  // Count of OnResume notifications.
};

// Disabled as a temporary workaround for http://crbug.com/12187
TEST(SystemMonitor, DISABLED_PowerNotifications) {
  const int kObservers = 5;

  // Initialize a message loop for this to run on.
  MessageLoop loop;
  // Initialize time() since it registers as a SystemMonitor observer.
  base::Time now = base::Time::Now();

  base::SystemMonitor* monitor = base::SystemMonitor::Get();
  PowerTest test[kObservers];
  for (int index = 0; index < kObservers; ++index)
    monitor->AddObserver(&test[index]);

  // Send a bunch of power changes.  Since the battery power hasn't
  // actually changed, we shouldn't get notifications.
  for (int index = 0; index < 5; index++) {
    monitor->ProcessPowerMessage(base::SystemMonitor::POWER_STATE_EVENT);
    EXPECT_EQ(test[0].power_state_changes(), 0);
  }

  // Sending resume when not suspended should have no effect.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 0);

  // Pretend we suspended.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Send a second suspend notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Pretend we were awakened.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);

  // Send a duplicate resume notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);
}
<commit_msg>Re-enable SystemMonitor.* in base_unittests.<commit_after>// Copyright (c) 2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/system_monitor.h"
#include "testing/gtest/include/gtest/gtest.h"

class PowerTest : public base::SystemMonitor::PowerObserver {
 public:
  PowerTest()
    : battery_(false),
      power_state_changes_(0),
      suspends_(0),
      resumes_(0) {};

  // PowerObserver callbacks.
  void OnPowerStateChange(base::SystemMonitor*) { power_state_changes_++; };
  void OnSuspend(base::SystemMonitor*) { suspends_++; };
  void OnResume(base::SystemMonitor*) { resumes_++; };

  // Test status counts.
  bool battery() { return battery_; }
  int power_state_changes() { return power_state_changes_; }
  int suspends() { return suspends_; }
  int resumes() { return resumes_; }

 private:
  bool battery_;   // Do we currently think we're on battery power.
  int power_state_changes_;  // Count of OnPowerStateChange notifications.
  int suspends_;  // Count of OnSuspend notifications.
  int resumes_;  // Count of OnResume notifications.
};

TEST(SystemMonitor, PowerNotifications) {
  const int kObservers = 5;

  // Initialize a message loop for this to run on.
  MessageLoop loop;
  // Initialize time() since it registers as a SystemMonitor observer.
  base::Time now = base::Time::Now();

  base::SystemMonitor* monitor = base::SystemMonitor::Get();
  PowerTest test[kObservers];
  for (int index = 0; index < kObservers; ++index)
    monitor->AddObserver(&test[index]);

  // Send a bunch of power changes.  Since the battery power hasn't
  // actually changed, we shouldn't get notifications.
  for (int index = 0; index < 5; index++) {
    monitor->ProcessPowerMessage(base::SystemMonitor::POWER_STATE_EVENT);
    EXPECT_EQ(test[0].power_state_changes(), 0);
  }

  // Sending resume when not suspended should have no effect.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 0);

  // Pretend we suspended.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Send a second suspend notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::SUSPEND_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].suspends(), 1);

  // Pretend we were awakened.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);

  // Send a duplicate resume notification.  This should be suppressed.
  monitor->ProcessPowerMessage(base::SystemMonitor::RESUME_EVENT);
  loop.RunAllPending();
  EXPECT_EQ(test[0].resumes(), 1);
}
<|endoftext|>


<commit_before>// Ouzel by Elviss Strazdins

#ifndef OUZEL_MATH_VECTOR_HPP
#define OUZEL_MATH_VECTOR_HPP

#include <array>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <limits>
#include <type_traits>
#include <utility>

namespace ouzel
{
    template <typename T, std::size_t N> class Vector final
    {
    public:
#if defined(__SSE__)
        alignas(N == 4 ? 4 * sizeof(T) : alignof(T))
#endif
        std::array<T, N> v{};

        constexpr Vector() noexcept {}

        template <typename ...A>
        explicit constexpr Vector(const A... args) noexcept:
            v{args...}
        {
        }

        template <auto X = N, std::size_t M, std::enable_if_t<(X != M)>* = nullptr>
        explicit Vector(const Vector<T, M>& vec) noexcept
        {
            for (std::size_t i = 0; i < N && i < M; ++i)
                v[i] = vec.v[i];
        }

        auto& operator[](const std::size_t index) noexcept { return v[index]; }
        constexpr auto operator[](const std::size_t index) const noexcept { return v[index]; }

        template <auto X = N, std::enable_if_t<(X >= 1)>* = nullptr>
        auto& x() noexcept { return v[0]; }

        template <auto X = N, std::enable_if_t<(X >= 1)>* = nullptr>
        constexpr auto x() const noexcept { return v[0]; }

        template <auto X = N, std::enable_if_t<(X >= 2)>* = nullptr>
        auto& y() noexcept { return v[1]; }

        template <auto X = N, std::enable_if_t<(X >= 2)>* = nullptr>
        constexpr auto y() const noexcept { return v[1]; }

        template <auto X = N, std::enable_if_t<(X >= 3)>* = nullptr>
        auto& z() noexcept { return v[2]; }

        template <auto X = N, std::enable_if_t<(X >= 3)>* = nullptr>
        constexpr auto z() const noexcept { return v[2]; }

        template <auto X = N, std::enable_if_t<(X >= 4)>* = nullptr>
        auto& w() noexcept { return v[3]; }

        template <auto X = N, std::enable_if_t<(X >= 4)>* = nullptr>
        constexpr auto w() const noexcept { return v[3]; }

        template <auto X = N, std::enable_if_t<(X == 2)>* = nullptr>
        auto getAngle() const noexcept
        {
            return std::atan2(v[1], v[0]);
        }

        template <auto X = N, std::enable_if_t<(X == 3)>* = nullptr>
        auto getAngle(const Vector& axis) const noexcept
        {
            constexpr T dx = axis.v[0] - v[0] - v[1] * axis.v[2] + v[2] * axis.v[1];
            constexpr T dy = axis.v[1] - v[1] - v[2] * axis.v[0] + v[0] * axis.v[2];
            constexpr T dz = axis.v[2] - v[2] - v[0] * axis.v[1] + v[1] * axis.v[0];

            return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz), dot(axis));
        }

        template <auto X = N, std::enable_if_t<(X == 4)>* = nullptr>
        auto getAngle(const Vector& axis) const noexcept
        {
            constexpr T dx = v[3] * axis.v[0] - v[0] * axis.v[3] - v[1] * axis.v[2] + v[2] * axis.v[1];
            constexpr T dy = v[3] * axis.v[1] - v[1] * axis.v[3] - v[2] * axis.v[0] + v[0] * axis.v[2];
            constexpr T dz = v[3] * axis.v[2] - v[2] * axis.v[3] - v[0] * axis.v[1] + v[1] * axis.v[0];

            return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz), dot(axis));
        }

        void clamp(const Vector& min, const Vector& max) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] < min.v[i]) v[i] = min.v[i];
                else if (v[i] > max.v[i]) v[i] = max.v[i];
        }

        template <auto X = N, std::enable_if_t<(X == 3)>* = nullptr>
        constexpr auto cross(const Vector& vec) const noexcept
        {
            return Vector{
                (v[1] * vec.v[2]) - (v[2] * vec.v[1]),
                (v[2] * vec.v[0]) - (v[0] * vec.v[2]),
                (v[0] * vec.v[1]) - (v[1] * vec.v[0])
            };
        }

        auto distance(const Vector& vec) const noexcept
        {
            T d = T(0);
            for (std::size_t i = 0; i < N; ++i)
                d += (vec.v[i] - v[i]) * (vec.v[i] - v[i]);
            return std::sqrt(d);
        }

        auto distanceSquared(const Vector& vec) const noexcept
        {
            T d = T(0);
            for (std::size_t i = 0; i < N; ++i)
                d += (vec.v[i] - v[i]) * (vec.v[i] - v[i]);
            return d;
        }

        auto dot(const Vector& vec) const noexcept
        {
            T d = T(0);
            for (std::size_t i = 0; i < N; ++i)
                d += v[i] * vec.v[i];
            return d;
        }

        auto length() const noexcept
        {
            T l = T(0);
            for (const auto& c : v)
                l += c * c;
            return std::sqrt(l);
        }

        auto lengthSquared() const noexcept
        {
            T l = T(0);
            for (const auto& c : v)
                l += c * c;
            return l;
        }

        void negate() noexcept
        {
            for (auto& c : v)
                c = -c;
        }

        auto isNormalized(const T tolerance = std::numeric_limits<T>::min()) const noexcept
        {
            return std::abs(T(1) - lengthSquared()) < tolerance;
        }

        void normalize() noexcept
        {
            T squared = T(0);
            for (const auto& c : v)
                squared += c * c;

            if (squared == T(1)) // already normalized
                return;

            const auto length = std::sqrt(squared);
            if (length <= std::numeric_limits<T>::min()) // too close to zero
                return;

            const auto multiplier = T(1) / length;
            for (auto& c : v)
                c *= multiplier;
        }

        auto normalized() const noexcept
        {
            T squared = T(0);
            for (const auto& c : v)
                squared += c * c;

            if (squared == T(1)) // already normalized
                return *this;

            const auto length = std::sqrt(squared);
            if (length <= std::numeric_limits<T>::min()) // too close to zero
                return *this;

            const auto multiplier = T(1) / length;
            return *this * multiplier;
        }

        void scale(const T scalar) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] *= scalar;
        }

        void scale(const Vector& scale) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] *= scale.v[i];
        }

        template <auto X = N, std::enable_if_t<(X == 2)>* = nullptr>
        void rotate(const T angle) noexcept
        {
            const auto sinAngle = std::sin(angle);
            const auto cosAngle = std::cos(angle);

            const auto tempX = v[0] * cosAngle - v[1] * sinAngle;
            v[1] = v[1] * cosAngle + v[0] * sinAngle;
            v[0] = tempX;
        }

        template <auto X = N, std::enable_if_t<(X == 2)>* = nullptr>
        void rotate(const Vector<T, 2>& point, T angle) noexcept
        {
            const float sinAngle = std::sin(angle);
            const float cosAngle = std::cos(angle);

            if (point.isZero())
            {
                const auto tempX = v[0] * cosAngle - v[1] * sinAngle;
                v[1] = v[1] * cosAngle + v[0] * sinAngle;
                v[0] = tempX;
            }
            else
            {
                const auto tempX = v[0] - point.v[0];
                const auto tempY = v[1] - point.v[1];

                v[0] = tempX * cosAngle - tempY * sinAngle + point.v[0];
                v[1] = tempY * cosAngle + tempX * sinAngle + point.v[1];
            }
        }

        void smooth(const Vector& target, const T elapsedTime, const T responseTime) noexcept
        {
            if (elapsedTime > T(0))
                *this += (target - *this) * (elapsedTime / (elapsedTime + responseTime));
        }

        auto getMin() const noexcept
        {
            T result = v[0];

            for (std::size_t i = 1; i < N; ++i)
                if (v[i] < result)
                    result = v[i];

            return result;
        }

        auto getMax() const noexcept
        {
            T result = v[0];

            for (std::size_t i = 1; i < N; ++i)
                if (v[i] > result)
                    result = v[i];

            return result;
        }

        constexpr const auto operator-() const noexcept
        {
            return generateInverse(std::make_index_sequence<N>{});
        }

        constexpr const auto operator+(const Vector& vec) const noexcept
        {
            return generateSum(std::make_index_sequence<N>{}, vec);
        }

        auto& operator+=(const Vector& vec) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] += vec.v[i];
            return *this;
        }

        constexpr const auto operator-(const Vector& vec) const noexcept
        {
            return generateDiff(std::make_index_sequence<N>{}, vec);
        }

        auto& operator-=(const Vector& vec) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] -= vec.v[i];
            return *this;
        }

        constexpr const auto operator*(const T scalar) const noexcept
        {
            return generateMul(std::make_index_sequence<N>{}, scalar);
        }

        auto& operator*=(const T scalar) noexcept
        {
            for (auto& c : v)
                c *= scalar;
            return *this;
        }

        constexpr const auto operator/(const T scalar) const noexcept
        {
            return generateDiv(std::make_index_sequence<N>{}, scalar);
        }

        auto& operator/=(const T scalar) noexcept
        {
            for (auto& c : v)
                c /= scalar;
            return *this;
        }

        auto operator<(const Vector& vec) const noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] < vec.v[i]) return true;
                else if (vec.v[i] < v[i]) return false;

            return false;
        }

        auto operator==(const Vector& vec) const noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] != vec.v[i]) return false;
            return true;
        }

        auto operator!=(const Vector& vec) const noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] != vec.v[i]) return true;
            return false;
        }

        auto isZero() const noexcept
        {
            for (const auto& c : v)
                if (c != T(0)) return false;
            return true;
        }

    private:
        template <std::size_t...I>
        constexpr auto generateInverse(const std::index_sequence<I...>) const
        {
            return Vector{-v[I]...};
        }

        template <std::size_t...I>
        constexpr auto generateSum(const std::index_sequence<I...>, const Vector& vec) const
        {
            return Vector{(v[I] + vec.v[I])...};
        }

        template <std::size_t...I>
        constexpr auto generateDiff(const std::index_sequence<I...>, const Vector& vec) const
        {
            return Vector{(v[I] - vec.v[I])...};
        }

        template <std::size_t...I>
        constexpr auto generateMul(const std::index_sequence<I...>, T scalar) const
        {
            return Vector{(v[I] * scalar)...};
        }

        template <std::size_t...I>
        constexpr auto generateDiv(const std::index_sequence<I...>, T scalar) const
        {
            return Vector{(v[I] / scalar)...};
        }
    };

    template <typename T, std::size_t N>
    const auto operator*(const T scalar, const Vector<T, N>& vec) noexcept
    {
        return vec * scalar;
    }
}

#endif // OUZEL_MATH_VECTOR_HPP
<commit_msg>Make dot constexpr<commit_after>// Ouzel by Elviss Strazdins

#ifndef OUZEL_MATH_VECTOR_HPP
#define OUZEL_MATH_VECTOR_HPP

#include <array>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <limits>
#include <type_traits>
#include <utility>

namespace ouzel
{
    template <typename T, std::size_t N> class Vector final
    {
    public:
#if defined(__SSE__)
        alignas(N == 4 ? 4 * sizeof(T) : alignof(T))
#endif
        std::array<T, N> v{};

        constexpr Vector() noexcept {}

        template <typename ...A>
        explicit constexpr Vector(const A... args) noexcept:
            v{args...}
        {
        }

        template <auto X = N, std::size_t M, std::enable_if_t<(X != M)>* = nullptr>
        explicit Vector(const Vector<T, M>& vec) noexcept
        {
            for (std::size_t i = 0; i < N && i < M; ++i)
                v[i] = vec.v[i];
        }

        auto& operator[](const std::size_t index) noexcept { return v[index]; }
        constexpr auto operator[](const std::size_t index) const noexcept { return v[index]; }

        template <auto X = N, std::enable_if_t<(X >= 1)>* = nullptr>
        auto& x() noexcept { return v[0]; }

        template <auto X = N, std::enable_if_t<(X >= 1)>* = nullptr>
        constexpr auto x() const noexcept { return v[0]; }

        template <auto X = N, std::enable_if_t<(X >= 2)>* = nullptr>
        auto& y() noexcept { return v[1]; }

        template <auto X = N, std::enable_if_t<(X >= 2)>* = nullptr>
        constexpr auto y() const noexcept { return v[1]; }

        template <auto X = N, std::enable_if_t<(X >= 3)>* = nullptr>
        auto& z() noexcept { return v[2]; }

        template <auto X = N, std::enable_if_t<(X >= 3)>* = nullptr>
        constexpr auto z() const noexcept { return v[2]; }

        template <auto X = N, std::enable_if_t<(X >= 4)>* = nullptr>
        auto& w() noexcept { return v[3]; }

        template <auto X = N, std::enable_if_t<(X >= 4)>* = nullptr>
        constexpr auto w() const noexcept { return v[3]; }

        template <auto X = N, std::enable_if_t<(X == 2)>* = nullptr>
        auto getAngle() const noexcept
        {
            return std::atan2(v[1], v[0]);
        }

        template <auto X = N, std::enable_if_t<(X == 3)>* = nullptr>
        auto getAngle(const Vector& axis) const noexcept
        {
            constexpr T dx = axis.v[0] - v[0] - v[1] * axis.v[2] + v[2] * axis.v[1];
            constexpr T dy = axis.v[1] - v[1] - v[2] * axis.v[0] + v[0] * axis.v[2];
            constexpr T dz = axis.v[2] - v[2] - v[0] * axis.v[1] + v[1] * axis.v[0];

            return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz), dot(axis));
        }

        template <auto X = N, std::enable_if_t<(X == 4)>* = nullptr>
        auto getAngle(const Vector& axis) const noexcept
        {
            constexpr T dx = v[3] * axis.v[0] - v[0] * axis.v[3] - v[1] * axis.v[2] + v[2] * axis.v[1];
            constexpr T dy = v[3] * axis.v[1] - v[1] * axis.v[3] - v[2] * axis.v[0] + v[0] * axis.v[2];
            constexpr T dz = v[3] * axis.v[2] - v[2] * axis.v[3] - v[0] * axis.v[1] + v[1] * axis.v[0];

            return std::atan2(std::sqrt(dx * dx + dy * dy + dz * dz), dot(axis));
        }

        void clamp(const Vector& min, const Vector& max) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] < min.v[i]) v[i] = min.v[i];
                else if (v[i] > max.v[i]) v[i] = max.v[i];
        }

        template <auto X = N, std::enable_if_t<(X == 3)>* = nullptr>
        constexpr auto cross(const Vector& vec) const noexcept
        {
            return Vector{
                (v[1] * vec.v[2]) - (v[2] * vec.v[1]),
                (v[2] * vec.v[0]) - (v[0] * vec.v[2]),
                (v[0] * vec.v[1]) - (v[1] * vec.v[0])
            };
        }

        auto distance(const Vector& vec) const noexcept
        {
            T d = T(0);
            for (std::size_t i = 0; i < N; ++i)
                d += (vec.v[i] - v[i]) * (vec.v[i] - v[i]);
            return std::sqrt(d);
        }

        auto distanceSquared(const Vector& vec) const noexcept
        {
            T d = T(0);
            for (std::size_t i = 0; i < N; ++i)
                d += (vec.v[i] - v[i]) * (vec.v[i] - v[i]);
            return d;
        }

        constexpr auto dot(const Vector& vec) const noexcept
        {
            return generateDot(std::make_index_sequence<N>{}, vec);
        }

        auto length() const noexcept
        {
            T l = T(0);
            for (const auto& c : v)
                l += c * c;
            return std::sqrt(l);
        }

        auto lengthSquared() const noexcept
        {
            T l = T(0);
            for (const auto& c : v)
                l += c * c;
            return l;
        }

        void negate() noexcept
        {
            for (auto& c : v)
                c = -c;
        }

        auto isNormalized(const T tolerance = std::numeric_limits<T>::min()) const noexcept
        {
            return std::abs(T(1) - lengthSquared()) < tolerance;
        }

        void normalize() noexcept
        {
            T squared = T(0);
            for (const auto& c : v)
                squared += c * c;

            if (squared == T(1)) // already normalized
                return;

            const auto length = std::sqrt(squared);
            if (length <= std::numeric_limits<T>::min()) // too close to zero
                return;

            const auto multiplier = T(1) / length;
            for (auto& c : v)
                c *= multiplier;
        }

        auto normalized() const noexcept
        {
            T squared = T(0);
            for (const auto& c : v)
                squared += c * c;

            if (squared == T(1)) // already normalized
                return *this;

            const auto length = std::sqrt(squared);
            if (length <= std::numeric_limits<T>::min()) // too close to zero
                return *this;

            const auto multiplier = T(1) / length;
            return *this * multiplier;
        }

        void scale(const T scalar) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] *= scalar;
        }

        void scale(const Vector& scale) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] *= scale.v[i];
        }

        template <auto X = N, std::enable_if_t<(X == 2)>* = nullptr>
        void rotate(const T angle) noexcept
        {
            const auto sinAngle = std::sin(angle);
            const auto cosAngle = std::cos(angle);

            const auto tempX = v[0] * cosAngle - v[1] * sinAngle;
            v[1] = v[1] * cosAngle + v[0] * sinAngle;
            v[0] = tempX;
        }

        template <auto X = N, std::enable_if_t<(X == 2)>* = nullptr>
        void rotate(const Vector<T, 2>& point, T angle) noexcept
        {
            const float sinAngle = std::sin(angle);
            const float cosAngle = std::cos(angle);

            if (point.isZero())
            {
                const auto tempX = v[0] * cosAngle - v[1] * sinAngle;
                v[1] = v[1] * cosAngle + v[0] * sinAngle;
                v[0] = tempX;
            }
            else
            {
                const auto tempX = v[0] - point.v[0];
                const auto tempY = v[1] - point.v[1];

                v[0] = tempX * cosAngle - tempY * sinAngle + point.v[0];
                v[1] = tempY * cosAngle + tempX * sinAngle + point.v[1];
            }
        }

        void smooth(const Vector& target, const T elapsedTime, const T responseTime) noexcept
        {
            if (elapsedTime > T(0))
                *this += (target - *this) * (elapsedTime / (elapsedTime + responseTime));
        }

        auto getMin() const noexcept
        {
            T result = v[0];

            for (std::size_t i = 1; i < N; ++i)
                if (v[i] < result)
                    result = v[i];

            return result;
        }

        auto getMax() const noexcept
        {
            T result = v[0];

            for (std::size_t i = 1; i < N; ++i)
                if (v[i] > result)
                    result = v[i];

            return result;
        }

        constexpr const auto operator-() const noexcept
        {
            return generateInverse(std::make_index_sequence<N>{});
        }

        constexpr const auto operator+(const Vector& vec) const noexcept
        {
            return generateSum(std::make_index_sequence<N>{}, vec);
        }

        auto& operator+=(const Vector& vec) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] += vec.v[i];
            return *this;
        }

        constexpr const auto operator-(const Vector& vec) const noexcept
        {
            return generateDiff(std::make_index_sequence<N>{}, vec);
        }

        auto& operator-=(const Vector& vec) noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                v[i] -= vec.v[i];
            return *this;
        }

        constexpr const auto operator*(const T scalar) const noexcept
        {
            return generateMul(std::make_index_sequence<N>{}, scalar);
        }

        auto& operator*=(const T scalar) noexcept
        {
            for (auto& c : v)
                c *= scalar;
            return *this;
        }

        constexpr const auto operator/(const T scalar) const noexcept
        {
            return generateDiv(std::make_index_sequence<N>{}, scalar);
        }

        auto& operator/=(const T scalar) noexcept
        {
            for (auto& c : v)
                c /= scalar;
            return *this;
        }

        auto operator<(const Vector& vec) const noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] < vec.v[i]) return true;
                else if (vec.v[i] < v[i]) return false;

            return false;
        }

        auto operator==(const Vector& vec) const noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] != vec.v[i]) return false;
            return true;
        }

        auto operator!=(const Vector& vec) const noexcept
        {
            for (std::size_t i = 0; i < N; ++i)
                if (v[i] != vec.v[i]) return true;
            return false;
        }

        auto isZero() const noexcept
        {
            for (const auto& c : v)
                if (c != T(0)) return false;
            return true;
        }

    private:
        template <std::size_t...I>
        constexpr auto generateInverse(const std::index_sequence<I...>) const
        {
            return Vector{-v[I]...};
        }

        template <std::size_t...I>
        constexpr auto generateSum(const std::index_sequence<I...>, const Vector& vec) const
        {
            return Vector{(v[I] + vec.v[I])...};
        }

        template <std::size_t...I>
        constexpr auto generateDiff(const std::index_sequence<I...>, const Vector& vec) const
        {
            return Vector{(v[I] - vec.v[I])...};
        }

        template <std::size_t...I>
        constexpr auto generateMul(const std::index_sequence<I...>, T scalar) const
        {
            return Vector{(v[I] * scalar)...};
        }

        template <std::size_t...I>
        constexpr auto generateDiv(const std::index_sequence<I...>, T scalar) const
        {
            return Vector{(v[I] / scalar)...};
        }

        template<typename... Args>
        static constexpr auto sum(Args... args) noexcept
        {
            return (args + ...);
        }

        template <std::size_t...I>
        constexpr auto generateDot(const std::index_sequence<I...>, const Vector& vec) const
        {
            return sum((v[I] * vec.v[I])...);
        }
    };

    template <typename T, std::size_t N>
    const auto operator*(const T scalar, const Vector<T, N>& vec) noexcept
    {
        return vec * scalar;
    }
}

#endif // OUZEL_MATH_VECTOR_HPP
<|endoftext|>


<commit_before>#include "ospray_test_fixture.h"

using OSPRayTestScenes::Base;
using OSPRayTestScenes::SingleObject;
using OSPRayTestScenes::Box;
using OSPRayTestScenes::Sierpinski;
using OSPRayTestScenes::Pipes;

namespace {

OSPGeometry getMesh() {
  // triangle mesh data
  float vertices[] = { -2.0f, -1.0f, 3.5f,
                       2.0f, -1.0f, 3.0f,
                       2.0f,  1.0f, 3.5f,
                       -2.0f,  1.0f, 3.0f
                     };
  // triangle color data
  float color[] =  { 1.0f, 0.0f, 0.0f, 1.0f,
                     0.0f, 1.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f, 1.0f,
                     0.7f, 0.7f, 0.7f, 1.0f
                   };
  int32_t indices[] = { 0, 1, 2,
                        0, 1, 3,
                        0, 2, 3,
                        1, 2, 3
                      };
  // create and setup model and mesh
  OSPGeometry mesh = ospNewGeometry("triangles");
  EXPECT_TRUE(mesh);
  OSPData data = ospNewData(4, OSP_FLOAT3, vertices);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(mesh, "vertex", data);
  data = ospNewData(4, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(mesh, "vertex.color", data);
  data = ospNewData(4, OSP_INT3, indices);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(mesh, "index", data);
  ospCommit(mesh);

  return mesh;
}

OSPGeometry getCylinder() {
  //  cylinder vertex data
  float vertex[] = { 0.0f, -1.0f, 3.0f,
                     0.0f, 1.0f, 3.0f
                   };
  //  cylinder color
  float color[] =  { 1.0f, 0.0f, 0.0f, 1.0f};
  // create and setup model and cylinder
  OSPGeometry cylinder = ospNewGeometry("cylinders");
  EXPECT_TRUE(cylinder);
  OSPData data = ospNewData(2, OSP_FLOAT3, vertex);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(cylinder, "cylinders", data);
  data = ospNewData(1, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(cylinder, "color", data);
  ospSet1f(cylinder, "radius", 1.0f);
  ospCommit(cylinder);

  return cylinder;
}

OSPGeometry getSphere() {
  // sphere vertex data
  float vertex[] = { 0.0f, 0.0f, 3.0f, 0.0f};
  float color[] =  { 1.0f, 0.0f, 0.0f, 1.0f};
  // create and setup model and sphere
  OSPGeometry sphere = ospNewGeometry("spheres");
  EXPECT_TRUE(sphere);
  OSPData data = ospNewData(1, OSP_FLOAT4, vertex);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(sphere, "spheres", data);
  data = ospNewData(1, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(sphere, "color", data);
  ospSet1f(sphere, "radius", 1.0f);
  ospCommit(sphere);

  return sphere;
}

OSPGeometry getStreamline() {
  float vertex[] = { 2.0f, -1.0f, 3.0f, 0.0f,
                     0.4f, 0.5f, 8.0f, -2.0f,
                     0.0f, 1.0f, 3.0f, 0.0f
                   };
  float color[] =  { 0.0f, 1.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f, 1.0f,
                     1.0f, 0.0f, 0.0f, 1.0f
                   };
  int index[] =  { 0, 1, 2};
  OSPGeometry streamlines = ospNewGeometry("streamlines");
  EXPECT_TRUE(streamlines);
  OSPData data = ospNewData(3, OSP_FLOAT3A, vertex);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(streamlines, "vertex", data);
  data = ospNewData(3, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(streamlines, "vertex.color", data);
  data = ospNewData(1, OSP_INT3, index);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(streamlines, "index", data);
  ospSet1f(streamlines, "radius", 0.5f);
  ospCommit(streamlines);

  return streamlines;
}

} // anonymous namespace

// an empty scene
TEST_P(SingleObject, emptyScene) {
  PerformRenderTest();
}

// a simple mesh
TEST_P(SingleObject, simpleMesh) {
  OSPGeometry mesh = ::getMesh();
  ospSetMaterial(mesh, GetMaterial());
  ospCommit(mesh);
  AddGeometry(mesh);
  PerformRenderTest();
}

// single red sphere
TEST_P(SingleObject, simpleSphere) {
  OSPGeometry sphere = ::getSphere();
  ospSetMaterial(sphere, GetMaterial());
  ospCommit(sphere);
  AddGeometry(sphere);
  PerformRenderTest();
}

// single red cylinder
TEST_P(SingleObject, simpleCylinder) {
  OSPGeometry cylinder = ::getCylinder();
  ospSetMaterial(cylinder, GetMaterial());
  ospCommit(cylinder);
  AddGeometry(cylinder);
  PerformRenderTest();
}

// single tube
TEST_P(SingleObject, simpleStreamlines) {
  OSPGeometry streamlines = ::getStreamline();
  ospSetMaterial(streamlines, GetMaterial());
  ospCommit(streamlines);
  AddGeometry(streamlines);
  PerformRenderTest();
}

INSTANTIATE_TEST_CASE_P(Scivis, SingleObject, ::testing::Combine(::testing::Values("scivis"), ::testing::Values("OBJMaterial")));
INSTANTIATE_TEST_CASE_P(Pathtracer, SingleObject, ::testing::Combine(::testing::Values("pathtracer"), ::testing::Values("OBJMaterial", "Glass", "Luminous")));

TEST_P(Box, basicScene) {
  PerformRenderTest();
}

INSTANTIATE_TEST_CASE_P(MaterialPairs, Box, ::testing::Combine(::testing::Values("OBJMaterial", "Glass", "Luminous"), ::testing::Values("OBJMaterial", "Glass", "Luminous")));

TEST_P(Pipes, simple) {
  PerformRenderTest();
}

INSTANTIATE_TEST_CASE_P(Scivis, Pipes, ::testing::Combine(::testing::Values("scivis"), ::testing::Values("OBJMaterial"), ::testing::Values(0.1f, 0.4f)));

// Tests disabled due to issues for pathtracer renderer with streamlines
INSTANTIATE_TEST_CASE_P(DISABLED_Pathtracer, Pipes, ::testing::Combine(::testing::Values("pathtracer"), ::testing::Values("OBJMaterial", "Glass", "Luminous"), ::testing::Values(0.1f, 0.4f)));
<commit_msg>Disabled segfaulting tests in CI<commit_after>#include "ospray_test_fixture.h"

using OSPRayTestScenes::Base;
using OSPRayTestScenes::SingleObject;
using OSPRayTestScenes::Box;
using OSPRayTestScenes::Sierpinski;
using OSPRayTestScenes::Pipes;

namespace {

OSPGeometry getMesh() {
  // triangle mesh data
  float vertices[] = { -2.0f, -1.0f, 3.5f,
                       2.0f, -1.0f, 3.0f,
                       2.0f,  1.0f, 3.5f,
                       -2.0f,  1.0f, 3.0f
                     };
  // triangle color data
  float color[] =  { 1.0f, 0.0f, 0.0f, 1.0f,
                     0.0f, 1.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f, 1.0f,
                     0.7f, 0.7f, 0.7f, 1.0f
                   };
  int32_t indices[] = { 0, 1, 2,
                        0, 1, 3,
                        0, 2, 3,
                        1, 2, 3
                      };
  // create and setup model and mesh
  OSPGeometry mesh = ospNewGeometry("triangles");
  EXPECT_TRUE(mesh);
  OSPData data = ospNewData(4, OSP_FLOAT3, vertices);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(mesh, "vertex", data);
  data = ospNewData(4, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(mesh, "vertex.color", data);
  data = ospNewData(4, OSP_INT3, indices);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(mesh, "index", data);
  ospCommit(mesh);

  return mesh;
}

OSPGeometry getCylinder() {
  //  cylinder vertex data
  float vertex[] = { 0.0f, -1.0f, 3.0f,
                     0.0f, 1.0f, 3.0f
                   };
  //  cylinder color
  float color[] =  { 1.0f, 0.0f, 0.0f, 1.0f};
  // create and setup model and cylinder
  OSPGeometry cylinder = ospNewGeometry("cylinders");
  EXPECT_TRUE(cylinder);
  OSPData data = ospNewData(2, OSP_FLOAT3, vertex);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(cylinder, "cylinders", data);
  data = ospNewData(1, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(cylinder, "color", data);
  ospSet1f(cylinder, "radius", 1.0f);
  ospCommit(cylinder);

  return cylinder;
}

OSPGeometry getSphere() {
  // sphere vertex data
  float vertex[] = { 0.0f, 0.0f, 3.0f, 0.0f};
  float color[] =  { 1.0f, 0.0f, 0.0f, 1.0f};
  // create and setup model and sphere
  OSPGeometry sphere = ospNewGeometry("spheres");
  EXPECT_TRUE(sphere);
  OSPData data = ospNewData(1, OSP_FLOAT4, vertex);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(sphere, "spheres", data);
  data = ospNewData(1, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(sphere, "color", data);
  ospSet1f(sphere, "radius", 1.0f);
  ospCommit(sphere);

  return sphere;
}

OSPGeometry getStreamline() {
  float vertex[] = { 2.0f, -1.0f, 3.0f, 0.0f,
                     0.4f, 0.5f, 8.0f, -2.0f,
                     0.0f, 1.0f, 3.0f, 0.0f
                   };
  float color[] =  { 0.0f, 1.0f, 0.0f, 1.0f,
                     0.0f, 0.0f, 1.0f, 1.0f,
                     1.0f, 0.0f, 0.0f, 1.0f
                   };
  int index[] =  { 0, 1, 2};
  OSPGeometry streamlines = ospNewGeometry("streamlines");
  EXPECT_TRUE(streamlines);
  OSPData data = ospNewData(3, OSP_FLOAT3A, vertex);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(streamlines, "vertex", data);
  data = ospNewData(3, OSP_FLOAT4, color);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(streamlines, "vertex.color", data);
  data = ospNewData(1, OSP_INT3, index);
  EXPECT_TRUE(data);
  ospCommit(data);
  ospSetData(streamlines, "index", data);
  ospSet1f(streamlines, "radius", 0.5f);
  ospCommit(streamlines);

  return streamlines;
}

} // anonymous namespace

// an empty scene
TEST_P(SingleObject, emptyScene) {
  PerformRenderTest();
}

// a simple mesh
TEST_P(SingleObject, simpleMesh) {
  OSPGeometry mesh = ::getMesh();
  ospSetMaterial(mesh, GetMaterial());
  ospCommit(mesh);
  AddGeometry(mesh);
  PerformRenderTest();
}

// single red sphere
TEST_P(SingleObject, simpleSphere) {
  OSPGeometry sphere = ::getSphere();
  ospSetMaterial(sphere, GetMaterial());
  ospCommit(sphere);
  AddGeometry(sphere);
  PerformRenderTest();
}

// single red cylinder
TEST_P(SingleObject, simpleCylinder) {
  OSPGeometry cylinder = ::getCylinder();
  ospSetMaterial(cylinder, GetMaterial());
  ospCommit(cylinder);
  AddGeometry(cylinder);
  PerformRenderTest();
}

// single tube
TEST_P(SingleObject, DISABLED_simpleStreamlines) {
  OSPGeometry streamlines = ::getStreamline();
  ospSetMaterial(streamlines, GetMaterial());
  ospCommit(streamlines);
  AddGeometry(streamlines);
  PerformRenderTest();
}

INSTANTIATE_TEST_CASE_P(Scivis, SingleObject, ::testing::Combine(::testing::Values("scivis"), ::testing::Values("OBJMaterial")));
INSTANTIATE_TEST_CASE_P(Pathtracer, SingleObject, ::testing::Combine(::testing::Values("pathtracer"), ::testing::Values("OBJMaterial", "Glass", "Luminous")));

TEST_P(Box, basicScene) {
  PerformRenderTest();
}

INSTANTIATE_TEST_CASE_P(MaterialPairs, Box, ::testing::Combine(::testing::Values("OBJMaterial", "Glass", "Luminous"), ::testing::Values("OBJMaterial", "Glass", "Luminous")));

TEST_P(Pipes, simple) {
  PerformRenderTest();
}

INSTANTIATE_TEST_CASE_P(Scivis, Pipes, ::testing::Combine(::testing::Values("scivis"), ::testing::Values("OBJMaterial"), ::testing::Values(0.1f, 0.4f)));

// Tests disabled due to issues for pathtracer renderer with streamlines
INSTANTIATE_TEST_CASE_P(DISABLED_Pathtracer, Pipes, ::testing::Combine(::testing::Values("pathtracer"), ::testing::Values("OBJMaterial", "Glass", "Luminous"), ::testing::Values(0.1f, 0.4f)));
<|endoftext|>