<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 "entity.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/console/console.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.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 <memory>        // std::make_shared, std::shared_ptr
#include <stdint.h>      // uint32_t etc.
#include <unordered_map> // std::unordered_map
#include <vector>        // std::vector

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()
    {
        this->cartesian_coordinates = nullptr;
        this->spherical_coordinates = nullptr;

        // 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->speed = 5.0f; // 5.0 units / second
        this->mouse_speed = 0.005f;

        this->gravity = 9.81f / 60.0f;
        this->fall_speed = this->gravity;

        this->testing_spherical_world_in_use = false;
        this->is_key_I_released = true;
        this->is_key_F_released = true;
        this->in_help_mode = true;
        this->can_toggle_help_mode = false;
        this->can_display_help_screen = true;

        this->number_of_scenes = 0;

        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, &this->number_of_scenes);

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

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

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

        this->postrender();
    }

    int32_t Universe::get_number_of_children()
    {
        return this->number_of_scenes;
    }

    int32_t Universe::get_number_of_descendants()
    {
        return -1;
    }

    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() const
    {
        return this->window;
    }

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

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

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

    uint32_t Universe::get_font_size() const
    {
        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() const
    {
        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() const
    {
        return this->max_FPS;
    }

    void Universe::set(std::string& setting_name, std::shared_ptr<datatypes::AnyValue> setting_any_value)
    {
        this->setting_master_pointer->set(setting_name, setting_any_value);
    }

    config::Setting* Universe::get(std::string key) const
    {
        return this->setting_master_pointer->get(key);
    }

    std::string Universe::get_entity_names() const
    {
        std::string entity_names = "";

        std::vector<std::string> keys;
        keys.reserve(this->entity_anyvalue_map.size());

        for (auto it : this->entity_anyvalue_map)
        {
            if (!entity_names.empty())
            {
                entity_names += " ";
            }
            std::string key = static_cast<std::string>(it.first);
            entity_names += key;
        }

        return entity_names;
    }

    // Public callbacks.

    std::shared_ptr<datatypes::AnyValue> Universe::delete_entity(
            console::Console* const console,
            ontology::Universe* const 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;
            }
        }
        else
        {
            return nullptr;
        }
    }

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

        if (command_parameters.size() == 0)
        {
            // No command parameters.
            // Print names of named entities.
            console->print_text(universe->get_entity_names());
        }
        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.
            ontology::Entity* entity = any_value->get_entity_pointer();
            uint64_t memory_address = reinterpret_cast<uint64_t>((void*) entity);
            char memory_address_char_array[256];
            snprintf(memory_address_char_array, sizeof(memory_address_char_array), "0x%08x", memory_address);

            std::string entity_info = "memory address: ";
            entity_info += std::string(memory_address_char_array);
            console->print_text(entity_info);

            int32_t number_of_children = entity->get_number_of_children();
            char number_of_children_char_array[256];
            snprintf(number_of_children_char_array, sizeof(number_of_children_char_array), "%d", number_of_children);

            std::string children_info = "number of children: ";
            children_info += std::string(number_of_children_char_array);
            console->print_text(children_info);
        }
        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, &this->number_of_scenes);
    }

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

    bool Universe::compute_matrices_from_inputs()
    {
        if (this->cartesian_coordinates == nullptr)
        {
            return false;
        }

        if (!this->is_flight_mode_in_use)
        {
            this->fall_speed += this->gravity;
            this->cartesian_coordinates->y -= this->fall_speed;
        }

        GLfloat FoV = this->initialFoV;

        // adjust position according to the ground.
        if (!this->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), this->cartesian_coordinates);

                if (!std::isnan(ground_y) && this->cartesian_coordinates->y < ground_y)
                {
                    this->cartesian_coordinates->y = ground_y;
                    this->fall_speed = 0.0f;
                }
            }
        }

        if (this->testing_spherical_world_in_use)
        {
            if (this->spherical_coordinates == nullptr)
            {
                return false;
            }

            // compute spherical coordinates.
            this->spherical_coordinates->rho = sqrt((this->cartesian_coordinates->x * this->cartesian_coordinates->x) + (this->cartesian_coordinates->y * this->cartesian_coordinates->y) + (this->cartesian_coordinates->z * this->cartesian_coordinates->z));
            this->spherical_coordinates->theta = RADIANS_TO_DEGREES(atan2(sqrt((this->cartesian_coordinates->x * this->cartesian_coordinates->x) + (this->cartesian_coordinates->y * this->cartesian_coordinates->y)), this->cartesian_coordinates->z));
            this->spherical_coordinates->phi = RADIANS_TO_DEGREES(atan2(this->cartesian_coordinates->y, this->cartesian_coordinates->x));
        }

        glm::vec3 camera_cartesian_coordinates;
        camera_cartesian_coordinates.x = this->cartesian_coordinates->x;
        camera_cartesian_coordinates.y = this->cartesian_coordinates->y;
        camera_cartesian_coordinates.z = this->cartesian_coordinates->z;
        camera_cartesian_coordinates.y += 2.0f;

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

        return true;
    }
}
<commit_msg>Bugfix: `info` does not add an entity name to `entity_anyvalue_map`.<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 "entity.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/console/console.hpp"
#include "code/ylikuutio/hierarchy/hierarchy_templates.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 <memory>        // std::make_shared, std::shared_ptr
#include <stdint.h>      // uint32_t etc.
#include <unordered_map> // std::unordered_map
#include <vector>        // std::vector

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()
    {
        this->cartesian_coordinates = nullptr;
        this->spherical_coordinates = nullptr;

        // 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->speed = 5.0f; // 5.0 units / second
        this->mouse_speed = 0.005f;

        this->gravity = 9.81f / 60.0f;
        this->fall_speed = this->gravity;

        this->testing_spherical_world_in_use = false;
        this->is_key_I_released = true;
        this->is_key_F_released = true;
        this->in_help_mode = true;
        this->can_toggle_help_mode = false;
        this->can_display_help_screen = true;

        this->number_of_scenes = 0;

        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, &this->number_of_scenes);

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

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

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

        this->postrender();
    }

    int32_t Universe::get_number_of_children()
    {
        return this->number_of_scenes;
    }

    int32_t Universe::get_number_of_descendants()
    {
        return -1;
    }

    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() const
    {
        return this->window;
    }

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

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

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

    uint32_t Universe::get_font_size() const
    {
        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() const
    {
        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() const
    {
        return this->max_FPS;
    }

    void Universe::set(std::string& setting_name, std::shared_ptr<datatypes::AnyValue> setting_any_value)
    {
        this->setting_master_pointer->set(setting_name, setting_any_value);
    }

    config::Setting* Universe::get(std::string key) const
    {
        return this->setting_master_pointer->get(key);
    }

    std::string Universe::get_entity_names() const
    {
        std::string entity_names = "";

        std::vector<std::string> keys;
        keys.reserve(this->entity_anyvalue_map.size());

        for (auto it : this->entity_anyvalue_map)
        {
            if (!entity_names.empty())
            {
                entity_names += " ";
            }
            std::string key = static_cast<std::string>(it.first);
            entity_names += key;
        }

        return entity_names;
    }

    // Public callbacks.

    std::shared_ptr<datatypes::AnyValue> Universe::delete_entity(
            console::Console* const console,
            ontology::Universe* const 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;
            }
        }
        else
        {
            return nullptr;
        }
    }

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

        if (command_parameters.size() == 0)
        {
            // No command parameters.
            // Print names of named entities.
            console->print_text(universe->get_entity_names());
        }
        else if (command_parameters.size() == 1)
        {
            std::string name = command_parameters[0];

            if (universe->entity_anyvalue_map.count(name) != 1)
            {
                return nullptr;
            }

            datatypes::AnyValue* any_value = universe->entity_anyvalue_map[name];

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

            // OK, let's find out information about the entity.
            ontology::Entity* entity = any_value->get_entity_pointer();
            uint64_t memory_address = reinterpret_cast<uint64_t>((void*) entity);
            char memory_address_char_array[256];
            snprintf(memory_address_char_array, sizeof(memory_address_char_array), "0x%08x", memory_address);

            std::string entity_info = "memory address: ";
            entity_info += std::string(memory_address_char_array);
            console->print_text(entity_info);

            int32_t number_of_children = entity->get_number_of_children();
            char number_of_children_char_array[256];
            snprintf(number_of_children_char_array, sizeof(number_of_children_char_array), "%d", number_of_children);

            std::string children_info = "number of children: ";
            children_info += std::string(number_of_children_char_array);
            console->print_text(children_info);
        }
        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, &this->number_of_scenes);
    }

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

    bool Universe::compute_matrices_from_inputs()
    {
        if (this->cartesian_coordinates == nullptr)
        {
            return false;
        }

        if (!this->is_flight_mode_in_use)
        {
            this->fall_speed += this->gravity;
            this->cartesian_coordinates->y -= this->fall_speed;
        }

        GLfloat FoV = this->initialFoV;

        // adjust position according to the ground.
        if (!this->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), this->cartesian_coordinates);

                if (!std::isnan(ground_y) && this->cartesian_coordinates->y < ground_y)
                {
                    this->cartesian_coordinates->y = ground_y;
                    this->fall_speed = 0.0f;
                }
            }
        }

        if (this->testing_spherical_world_in_use)
        {
            if (this->spherical_coordinates == nullptr)
            {
                return false;
            }

            // compute spherical coordinates.
            this->spherical_coordinates->rho = sqrt((this->cartesian_coordinates->x * this->cartesian_coordinates->x) + (this->cartesian_coordinates->y * this->cartesian_coordinates->y) + (this->cartesian_coordinates->z * this->cartesian_coordinates->z));
            this->spherical_coordinates->theta = RADIANS_TO_DEGREES(atan2(sqrt((this->cartesian_coordinates->x * this->cartesian_coordinates->x) + (this->cartesian_coordinates->y * this->cartesian_coordinates->y)), this->cartesian_coordinates->z));
            this->spherical_coordinates->phi = RADIANS_TO_DEGREES(atan2(this->cartesian_coordinates->y, this->cartesian_coordinates->x));
        }

        glm::vec3 camera_cartesian_coordinates;
        camera_cartesian_coordinates.x = this->cartesian_coordinates->x;
        camera_cartesian_coordinates.y = this->cartesian_coordinates->y;
        camera_cartesian_coordinates.z = this->cartesian_coordinates->z;
        camera_cartesian_coordinates.y += 2.0f;

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

        return true;
    }
}
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "condor_common.h"
#include "condor_config.h"
#include "string_list.h"

#include "nordugridresource.h"
#include "nordugridjob.h"
#include "gridmanager.h"

HashTable <std::string, NordugridResource *>
    NordugridResource::ResourcesByName( hashFunction );

const char *NordugridResource::HashName( const char *resource_name,
										 const char *proxy_subject )
{
	static std::string hash_name;

	formatstr( hash_name, "nordugrid %s#%s", resource_name,
					   proxy_subject ? proxy_subject : "NULL" );

	return hash_name.c_str();
}

NordugridResource *NordugridResource::FindOrCreateResource( const char * resource_name,
															const Proxy *proxy )
{
	int rc;
	NordugridResource *resource = NULL;

	rc = ResourcesByName.lookup( HashName( resource_name, proxy->subject->fqan ),
								 resource );
	if ( rc != 0 ) {
		resource = new NordugridResource( resource_name, proxy );
		ASSERT(resource);
		resource->Reconfig();
		ResourcesByName.insert( HashName( resource_name, proxy->subject->fqan ),
								resource );
	} else {
		ASSERT(resource);
	}

	return resource;
}

NordugridResource::NordugridResource( const char *resource_name,
									  const Proxy *proxy )
	: BaseResource( resource_name )
{
	proxySubject = strdup( proxy->subject->subject_name );
	proxyFQAN = strdup( proxy->subject->fqan );

	gahp = NULL;

	std::string buff;
	formatstr( buff, "NORDUGRID/%s", proxyFQAN );

	gahp = new GahpClient( buff.c_str() );
	gahp->setNotificationTimerId( pingTimerId );
	gahp->setMode( GahpClient::normal );
	gahp->setTimeout( NordugridJob::gahpCallTimeout );

	m_jobStatusTid = daemonCore->Register_Timer( 0,
							(TimerHandlercpp)&NordugridResource::DoJobStatus,
							"NordugridResource::DoJobStatus", (Service*)this );

	m_statusGahp = new GahpClient( buff.c_str() );
	m_statusGahp->setNotificationTimerId( m_jobStatusTid );
	m_statusGahp->setMode( GahpClient::normal );
	m_statusGahp->setTimeout( NordugridJob::gahpCallTimeout );

	m_jobStatusActive = false;
}

NordugridResource::~NordugridResource()
{
	ResourcesByName.remove( HashName( resourceName, proxyFQAN ) );
	free( proxyFQAN );
	if ( proxySubject ) {
		free( proxySubject );
	}
	if ( gahp ) {
		delete gahp;
	}
	delete m_statusGahp;
	if ( m_jobStatusTid != TIMER_UNSET ) {
		daemonCore->Cancel_Timer( m_jobStatusTid );
	}
}

void NordugridResource::Reconfig()
{
	BaseResource::Reconfig();

	gahp->setTimeout( NordugridJob::gahpCallTimeout );
}

const char *NordugridResource::ResourceType()
{
	return "nordugrid";
}

const char *NordugridResource::GetHashName()
{
	return HashName( resourceName, proxyFQAN );
}

void NordugridResource::PublishResourceAd( ClassAd *resource_ad )
{
	BaseResource::PublishResourceAd( resource_ad );

	resource_ad->Assign( ATTR_X509_USER_PROXY_SUBJECT, proxySubject );
	resource_ad->Assign( ATTR_X509_USER_PROXY_FQAN, proxyFQAN );

	gahp->PublishStats( resource_ad );
}

void NordugridResource::DoPing( unsigned& ping_delay, bool& ping_complete,
								bool& ping_succeeded )
{
	int rc;

	if ( gahp->isInitialized() == false ) {
		dprintf( D_ALWAYS,"gahp server not up yet, delaying ping\n" );
		ping_delay = 5;
		return;
	}
	gahp->setNormalProxy( gahp->getMasterProxy() );
	if ( PROXY_IS_EXPIRED( gahp->getMasterProxy() ) ) {
		dprintf( D_ALWAYS,"proxy near expiration or invalid, delaying ping\n" );
		ping_delay = TIMER_NEVER;
		return;
	}

	ping_delay = 0;

	rc = gahp->nordugrid_ping( resourceName );

	if ( rc == GAHPCLIENT_COMMAND_PENDING ) {
		ping_complete = false;
	} else if ( rc != 0 ) {
		ping_complete = true;
		ping_succeeded = false;
	} else {
		ping_complete = true;
		ping_succeeded = true;
	}
}

void NordugridResource::DoJobStatus()
{
	if ( ( registeredJobs.IsEmpty() || resourceDown ) &&
		 m_jobStatusActive == false ) {
			// No jobs or we can't talk to the resource, so no point
			// in polling
		daemonCore->Reset_Timer( m_jobStatusTid, m_paramJobPollInterval );
		return;
	}

	if ( m_statusGahp->isStarted() == false ) {
		// The gahp isn't started yet. Wait a few seconds for a Job
		// object to start it and initialize x509 credentials.
		daemonCore->Reset_Timer( m_jobStatusTid, 5 );
		return;
	}

	daemonCore->Reset_Timer( m_jobStatusTid, TIMER_NEVER );

	StringList results;

	if ( m_jobStatusActive == false ) {

			// start ldap status command
		dprintf( D_FULLDEBUG, "Starting ldap poll: %s\n", resourceName );

		std::string ldap_server = resourceName;
		size_t pos = ldap_server.find_first_of( ':' );
		if ( pos != std::string::npos ) {
			ldap_server.erase( pos );
		}

		std::string filter;
		formatstr( filter, "(&(objectclass=nordugrid-job)(nordugrid-job-globalowner=%s))", proxySubject );
		int rc = m_statusGahp->nordugrid_ldap_query( ldap_server.c_str(), "mds-vo-name=local,o=grid", filter.c_str(), "nordugrid-job-globalid,nordugrid-job-status",
													 results );
		if ( rc != GAHPCLIENT_COMMAND_PENDING ) {
			dprintf( D_ALWAYS,
					 "gahp->nordugrid_ldap_query returned %d for resource %s\n",
					 rc, resourceName );
			EXCEPT( "nordugrid_ldap_query failed!" );
		}
		m_jobStatusActive = true;

	} else {

			// finish ldap status command
		int rc = m_statusGahp->nordugrid_ldap_query( NULL, NULL, NULL, NULL, results );

		if ( rc == GAHPCLIENT_COMMAND_PENDING ) {
			return;
		} else if ( rc != 0 ) {
			dprintf( D_ALWAYS,
					 "gahp->nordugrid_ldap_query returned %d for resource %s: %s\n",
					 rc, resourceName, m_statusGahp->getErrorString() );
			dprintf( D_ALWAYS, "Requesting ping of resource\n" );
			RequestPing( NULL );
		}

		if ( rc == 0 ) {
			const char *next_job_id = NULL;
			const char *next_status = NULL;
			const char *next_attr;
			std::string key;

			results.rewind();
			do {
				next_attr = results.next();

				if ( next_attr != NULL && *next_attr != '\0' ) {
						// Save the attributes we're interested in
					if ( !strncmp( next_attr, "nordugrid-job-globalid: ", 24 ) ) {
						next_job_id = next_attr;
					} else if ( !strncmp( next_attr, "nordugrid-job-status: ", 22 ) ) {
						next_status = next_attr;
					}
					continue;
				}
					// We just reached the end of a record. Process it.
					// If we don't have the attributes we expect, skip it.
				if ( next_job_id && next_status ) {
					int rc2;
					const char *id;
					BaseJob *base_job = NULL;
					NordugridJob *job = NULL;
					id = strrchr( next_job_id, '/' );
					id = (id != NULL) ? (id + 1) : "";
					formatstr( key, "nordugrid %s %s", resourceName, id );
					rc2 = BaseJob::JobsByRemoteId.lookup( key, base_job );
					if ( rc2 == 0 && (job = dynamic_cast<NordugridJob*>(base_job)) ) {
						job->NotifyNewRemoteStatus( strchr( next_status, ' ' ) + 1 );
					}
				}
				next_job_id = NULL;
				next_status = NULL;
			} while ( next_attr );

		}

		m_jobStatusActive = false;

		dprintf( D_FULLDEBUG, "ldap poll complete: %s\n", resourceName );

		daemonCore->Reset_Timer( m_jobStatusTid, m_paramJobPollInterval );
	}
}
<commit_msg>Support hashed DNs for NorduGrid ARC LDAP query. HTCONDOR-281<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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 "condor_common.h"
#include "condor_config.h"
#include "string_list.h"
#include <openssl/sha.h>

#include "nordugridresource.h"
#include "nordugridjob.h"
#include "gridmanager.h"

HashTable <std::string, NordugridResource *>
    NordugridResource::ResourcesByName( hashFunction );

const char *NordugridResource::HashName( const char *resource_name,
										 const char *proxy_subject )
{
	static std::string hash_name;

	formatstr( hash_name, "nordugrid %s#%s", resource_name,
					   proxy_subject ? proxy_subject : "NULL" );

	return hash_name.c_str();
}

NordugridResource *NordugridResource::FindOrCreateResource( const char * resource_name,
															const Proxy *proxy )
{
	int rc;
	NordugridResource *resource = NULL;

	rc = ResourcesByName.lookup( HashName( resource_name, proxy->subject->fqan ),
								 resource );
	if ( rc != 0 ) {
		resource = new NordugridResource( resource_name, proxy );
		ASSERT(resource);
		resource->Reconfig();
		ResourcesByName.insert( HashName( resource_name, proxy->subject->fqan ),
								resource );
	} else {
		ASSERT(resource);
	}

	return resource;
}

NordugridResource::NordugridResource( const char *resource_name,
									  const Proxy *proxy )
	: BaseResource( resource_name )
{
	proxySubject = strdup( proxy->subject->subject_name );
	proxyFQAN = strdup( proxy->subject->fqan );

	gahp = NULL;

	std::string buff;
	formatstr( buff, "NORDUGRID/%s", proxyFQAN );

	gahp = new GahpClient( buff.c_str() );
	gahp->setNotificationTimerId( pingTimerId );
	gahp->setMode( GahpClient::normal );
	gahp->setTimeout( NordugridJob::gahpCallTimeout );

	m_jobStatusTid = daemonCore->Register_Timer( 0,
							(TimerHandlercpp)&NordugridResource::DoJobStatus,
							"NordugridResource::DoJobStatus", (Service*)this );

	m_statusGahp = new GahpClient( buff.c_str() );
	m_statusGahp->setNotificationTimerId( m_jobStatusTid );
	m_statusGahp->setMode( GahpClient::normal );
	m_statusGahp->setTimeout( NordugridJob::gahpCallTimeout );

	m_jobStatusActive = false;
}

NordugridResource::~NordugridResource()
{
	ResourcesByName.remove( HashName( resourceName, proxyFQAN ) );
	free( proxyFQAN );
	if ( proxySubject ) {
		free( proxySubject );
	}
	if ( gahp ) {
		delete gahp;
	}
	delete m_statusGahp;
	if ( m_jobStatusTid != TIMER_UNSET ) {
		daemonCore->Cancel_Timer( m_jobStatusTid );
	}
}

void NordugridResource::Reconfig()
{
	BaseResource::Reconfig();

	gahp->setTimeout( NordugridJob::gahpCallTimeout );
}

const char *NordugridResource::ResourceType()
{
	return "nordugrid";
}

const char *NordugridResource::GetHashName()
{
	return HashName( resourceName, proxyFQAN );
}

void NordugridResource::PublishResourceAd( ClassAd *resource_ad )
{
	BaseResource::PublishResourceAd( resource_ad );

	resource_ad->Assign( ATTR_X509_USER_PROXY_SUBJECT, proxySubject );
	resource_ad->Assign( ATTR_X509_USER_PROXY_FQAN, proxyFQAN );

	gahp->PublishStats( resource_ad );
}

void NordugridResource::DoPing( unsigned& ping_delay, bool& ping_complete,
								bool& ping_succeeded )
{
	int rc;

	if ( gahp->isInitialized() == false ) {
		dprintf( D_ALWAYS,"gahp server not up yet, delaying ping\n" );
		ping_delay = 5;
		return;
	}
	gahp->setNormalProxy( gahp->getMasterProxy() );
	if ( PROXY_IS_EXPIRED( gahp->getMasterProxy() ) ) {
		dprintf( D_ALWAYS,"proxy near expiration or invalid, delaying ping\n" );
		ping_delay = TIMER_NEVER;
		return;
	}

	ping_delay = 0;

	rc = gahp->nordugrid_ping( resourceName );

	if ( rc == GAHPCLIENT_COMMAND_PENDING ) {
		ping_complete = false;
	} else if ( rc != 0 ) {
		ping_complete = true;
		ping_succeeded = false;
	} else {
		ping_complete = true;
		ping_succeeded = true;
	}
}

void NordugridResource::DoJobStatus()
{
	if ( ( registeredJobs.IsEmpty() || resourceDown ) &&
		 m_jobStatusActive == false ) {
			// No jobs or we can't talk to the resource, so no point
			// in polling
		daemonCore->Reset_Timer( m_jobStatusTid, m_paramJobPollInterval );
		return;
	}

	if ( m_statusGahp->isStarted() == false ) {
		// The gahp isn't started yet. Wait a few seconds for a Job
		// object to start it and initialize x509 credentials.
		daemonCore->Reset_Timer( m_jobStatusTid, 5 );
		return;
	}

	daemonCore->Reset_Timer( m_jobStatusTid, TIMER_NEVER );

	StringList results;

	if ( m_jobStatusActive == false ) {

			// start ldap status command
		dprintf( D_FULLDEBUG, "Starting ldap poll: %s\n", resourceName );

		std::string ldap_server = resourceName;
		size_t pos = ldap_server.find_first_of( ':' );
		if ( pos != std::string::npos ) {
			ldap_server.erase( pos );
		}

		// In newer releases of NorduGrid ARC, nordugrid-job-globalowner
		// is the SHA512 hash of the proxy subject, instead of the proxy
		// subject itself.
		char proxy_hash[SHA512_DIGEST_LENGTH];
		char proxy_hash_str[2*SHA512_DIGEST_LENGTH+1];
		SHA512((unsigned char*)proxySubject, strlen(proxySubject), (unsigned char*)proxy_hash);
		debug_hex_dump(proxy_hash_str, proxy_hash, sizeof(proxy_hash), true);
		std::string filter;
		formatstr( filter, "(&(objectclass=nordugrid-job)(|(nordugrid-job-globalowner=%s)(nordugrid-job-globalowner=%s)))", proxySubject, proxy_hash_str );
		int rc = m_statusGahp->nordugrid_ldap_query( ldap_server.c_str(), "mds-vo-name=local,o=grid", filter.c_str(), "nordugrid-job-globalid,nordugrid-job-status",
													 results );
		if ( rc != GAHPCLIENT_COMMAND_PENDING ) {
			dprintf( D_ALWAYS,
					 "gahp->nordugrid_ldap_query returned %d for resource %s\n",
					 rc, resourceName );
			EXCEPT( "nordugrid_ldap_query failed!" );
		}
		m_jobStatusActive = true;

	} else {

			// finish ldap status command
		int rc = m_statusGahp->nordugrid_ldap_query( NULL, NULL, NULL, NULL, results );

		if ( rc == GAHPCLIENT_COMMAND_PENDING ) {
			return;
		} else if ( rc != 0 ) {
			dprintf( D_ALWAYS,
					 "gahp->nordugrid_ldap_query returned %d for resource %s: %s\n",
					 rc, resourceName, m_statusGahp->getErrorString() );
			dprintf( D_ALWAYS, "Requesting ping of resource\n" );
			RequestPing( NULL );
		}

		if ( rc == 0 ) {
			const char *next_job_id = NULL;
			const char *next_status = NULL;
			const char *next_attr;
			std::string key;

			results.rewind();
			do {
				next_attr = results.next();

				if ( next_attr != NULL && *next_attr != '\0' ) {
						// Save the attributes we're interested in
					if ( !strncmp( next_attr, "nordugrid-job-globalid: ", 24 ) ) {
						next_job_id = next_attr;
					} else if ( !strncmp( next_attr, "nordugrid-job-status: ", 22 ) ) {
						next_status = next_attr;
					}
					continue;
				}
					// We just reached the end of a record. Process it.
					// If we don't have the attributes we expect, skip it.
				if ( next_job_id && next_status ) {
					int rc2;
					const char *id;
					BaseJob *base_job = NULL;
					NordugridJob *job = NULL;
					id = strrchr( next_job_id, '/' );
					id = (id != NULL) ? (id + 1) : "";
					formatstr( key, "nordugrid %s %s", resourceName, id );
					rc2 = BaseJob::JobsByRemoteId.lookup( key, base_job );
					if ( rc2 == 0 && (job = dynamic_cast<NordugridJob*>(base_job)) ) {
						job->NotifyNewRemoteStatus( strchr( next_status, ' ' ) + 1 );
					}
				}
				next_job_id = NULL;
				next_status = NULL;
			} while ( next_attr );

		}

		m_jobStatusActive = false;

		dprintf( D_FULLDEBUG, "ldap poll complete: %s\n", resourceName );

		daemonCore->Reset_Timer( m_jobStatusTid, m_paramJobPollInterval );
	}
}
<|endoftext|>


<commit_before>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2022 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "variable.hpp"
#include "entity.hpp"
#include "universe.hpp"
#include "console.hpp"
#include "code/ylikuutio/data/any_value.hpp"

// Include standard headers
#include <cstddef>  // std::size_t
#include <iostream> // std::cout, std::cin, std::cerr
#include <optional> // std::optional
#include <string>   // std::string

namespace yli::ontology
{
    class Entity;
    class Scene;

    void Variable::bind_to_parent()
    {
        // Requirements:
        // `this->parent` must not be `nullptr`.

        yli::ontology::Entity* const entity = this->parent;

        if (entity == nullptr)
        {
            std::cerr << "ERROR: `Variable::bind_to_parent`: `entity` is `nullptr`!\n";
            return;
        }

        // Get `childID` from `Entity` and set pointer to this `Variable`.
        entity->bind_variable(this);
    }

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

        if (this->parent == nullptr)
        {
            return;
        }

        this->parent->unbind_variable(this->childID);
    }

    yli::ontology::Entity* Variable::get_parent() const
    {
        return this->parent;
    }

    yli::ontology::Scene* Variable::get_scene() const
    {
        yli::ontology::Entity* const parent = this->get_parent();

        if (parent != nullptr)
        {
            return parent->get_scene();
        }

        return nullptr;
    }

    std::size_t Variable::get_number_of_children() const
    {
        return 0; // `Variable` has no children.
    }

    std::size_t Variable::get_number_of_descendants() const
    {
        return 0; // `Variable` has no children.
    }

    std::string Variable::help() const
    {
        // this function returns the help string for this variable.
        std::string help_string = this->local_name + " TODO: create helptext for " + this->local_name;
        return help_string;
    }

    std::optional<yli::data::AnyValue> Variable::get() const
    {
        if (this->parent == nullptr)
        {
            std::cerr << "ERROR: `Variable::get`: the parent of a `Variable` must not be `nullptr`!";
            return std::nullopt;
        }

        if (this->read_callback == nullptr)
        {
            return this->variable_value;
        }

        return this->read_callback(*this->parent);
    }

    void Variable::set(const yli::data::AnyValue& new_value)
    {
        if (this->parent == nullptr)
        {
            return;
        }

        this->variable_value = new_value;

        if (this->activate_callback != nullptr)
        {
            this->activate_callback(*this->parent, *this);
        }
    }

    void Variable::set(const std::string& new_value)
    {
        if (this->parent == nullptr)
        {
            return;
        }

        this->variable_value.set_new_value(new_value);

        if (this->activate_callback != nullptr)
        {
            this->activate_callback(*this->parent, *this);
        }
    }

    // Public callbacks.

    std::optional<yli::data::AnyValue> Variable::set_variable_const_std_string(
            yli::ontology::Variable& variable,
            const std::string& new_value)
    {
        // Usage:
        // to set variable: set2 <variable-name> <variable-value>

        // Set a new value and call activate callback if there is such.
        variable.set(new_value);
        return std::nullopt;
    }

    std::optional<yli::data::AnyValue> Variable::set_variable_variable(
            yli::ontology::Variable& dest_variable,
            const yli::ontology::Universe&,              // A context is needed so that correct `Variable` is bound to the function call.
            const yli::ontology::Variable& src_variable)
    {
        // Usage:
        // to set variable: set <dest-variable-name> <src-variable-name>

        // Set a new value and call activate callback if there is such.

        std::optional<yli::data::AnyValue> any_value = src_variable.get();

        if (any_value)
        {
            dest_variable.set(*any_value);
        }

        return std::nullopt;
    }

    std::optional<yli::data::AnyValue> Variable::print_value1(
            yli::ontology::Console& console,
            const yli::ontology::Universe&,          // A context is needed so that correct `Variable` is bound to the function call.
            const yli::ontology::Variable& variable)
    {
        // Usage:
        // to get variable value: get1 <variable-name>

        std::optional<yli::data::AnyValue> variable_value = variable.get();

        if (variable_value)
        {
            console.print_text((*variable_value).get_string());
        }

        return std::nullopt;
    }

    // Public callbacks end here.

    void Variable::activate()
    {
        if (this->activate_callback != nullptr)
        {
            this->activate_callback(*this->parent, *this);
        }
    }
}
<commit_msg>Replace `#include` line with a forward declaration.<commit_after>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2022 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "variable.hpp"
#include "entity.hpp"
#include "console.hpp"
#include "code/ylikuutio/data/any_value.hpp"

// Include standard headers
#include <cstddef>  // std::size_t
#include <iostream> // std::cout, std::cin, std::cerr
#include <optional> // std::optional
#include <string>   // std::string

namespace yli::ontology
{
    class Entity;
    class Universe;
    class Scene;

    void Variable::bind_to_parent()
    {
        // Requirements:
        // `this->parent` must not be `nullptr`.

        yli::ontology::Entity* const entity = this->parent;

        if (entity == nullptr)
        {
            std::cerr << "ERROR: `Variable::bind_to_parent`: `entity` is `nullptr`!\n";
            return;
        }

        // Get `childID` from `Entity` and set pointer to this `Variable`.
        entity->bind_variable(this);
    }

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

        if (this->parent == nullptr)
        {
            return;
        }

        this->parent->unbind_variable(this->childID);
    }

    yli::ontology::Entity* Variable::get_parent() const
    {
        return this->parent;
    }

    yli::ontology::Scene* Variable::get_scene() const
    {
        yli::ontology::Entity* const parent = this->get_parent();

        if (parent != nullptr)
        {
            return parent->get_scene();
        }

        return nullptr;
    }

    std::size_t Variable::get_number_of_children() const
    {
        return 0; // `Variable` has no children.
    }

    std::size_t Variable::get_number_of_descendants() const
    {
        return 0; // `Variable` has no children.
    }

    std::string Variable::help() const
    {
        // this function returns the help string for this variable.
        std::string help_string = this->local_name + " TODO: create helptext for " + this->local_name;
        return help_string;
    }

    std::optional<yli::data::AnyValue> Variable::get() const
    {
        if (this->parent == nullptr)
        {
            std::cerr << "ERROR: `Variable::get`: the parent of a `Variable` must not be `nullptr`!";
            return std::nullopt;
        }

        if (this->read_callback == nullptr)
        {
            return this->variable_value;
        }

        return this->read_callback(*this->parent);
    }

    void Variable::set(const yli::data::AnyValue& new_value)
    {
        if (this->parent == nullptr)
        {
            return;
        }

        this->variable_value = new_value;

        if (this->activate_callback != nullptr)
        {
            this->activate_callback(*this->parent, *this);
        }
    }

    void Variable::set(const std::string& new_value)
    {
        if (this->parent == nullptr)
        {
            return;
        }

        this->variable_value.set_new_value(new_value);

        if (this->activate_callback != nullptr)
        {
            this->activate_callback(*this->parent, *this);
        }
    }

    // Public callbacks.

    std::optional<yli::data::AnyValue> Variable::set_variable_const_std_string(
            yli::ontology::Variable& variable,
            const std::string& new_value)
    {
        // Usage:
        // to set variable: set2 <variable-name> <variable-value>

        // Set a new value and call activate callback if there is such.
        variable.set(new_value);
        return std::nullopt;
    }

    std::optional<yli::data::AnyValue> Variable::set_variable_variable(
            yli::ontology::Variable& dest_variable,
            const yli::ontology::Universe&,              // A context is needed so that correct `Variable` is bound to the function call.
            const yli::ontology::Variable& src_variable)
    {
        // Usage:
        // to set variable: set <dest-variable-name> <src-variable-name>

        // Set a new value and call activate callback if there is such.

        std::optional<yli::data::AnyValue> any_value = src_variable.get();

        if (any_value)
        {
            dest_variable.set(*any_value);
        }

        return std::nullopt;
    }

    std::optional<yli::data::AnyValue> Variable::print_value1(
            yli::ontology::Console& console,
            const yli::ontology::Universe&,          // A context is needed so that correct `Variable` is bound to the function call.
            const yli::ontology::Variable& variable)
    {
        // Usage:
        // to get variable value: get1 <variable-name>

        std::optional<yli::data::AnyValue> variable_value = variable.get();

        if (variable_value)
        {
            console.print_text((*variable_value).get_string());
        }

        return std::nullopt;
    }

    // Public callbacks end here.

    void Variable::activate()
    {
        if (this->activate_callback != nullptr)
        {
            this->activate_callback(*this->parent, *this);
        }
    }
}
<|endoftext|>


<commit_before>/*
 * StepParameters.hpp
 *
 *  Created on: Feb 18, 2016
 *      Author: Péter Fankhauser
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#pragma once

#include "free_gait_core/TypeDefs.hpp"
#include "free_gait_core/step/StepCompleter.hpp"

namespace free_gait {

class StepParameters
{
 public:
  StepParameters() {}
  virtual ~StepParameters() {};

  friend class StepCompleter;

 protected:

  struct FootstepParameters
  {
    std::string profileType = "triangle";
    double profileHeight = 0.05;
    double averageVelocity = 0.1;
    double liftOffVelocity = 0.05;
    double touchdownVelocity = -0.05;
    double minimumDuration_ = 0.5;
  } footTargetParameters;

  struct LegModeParameters
  {
    double duration = 0.5;
    std::string frameId = "base";
  } legModeParameters;

  struct BaseAutoParameters
  {
    double averageLinearVelocity = 0.05;
    double averageAngularVelocity = 0.1;
    double supportMargin = 0.06;
    double minimumDuration = 0.7;
    PlanarStance nominalPlanarStanceInBaseFrame;

    BaseAutoParameters()
    {
      Position2 position;
      position << 0.385, 0.25;
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::LF_LEG, position);
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::RF_LEG, Position2(Eigen::Vector2d(position(0), -position(1))));
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::LH_LEG, Position2(Eigen::Vector2d(-position(0), position(1))));
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::RH_LEG, Position2(Eigen::Vector2d(-position(0), -position(1))));
    }

  } baseAutoParameters;

  struct BaseTargetParameters
  {
    double averageLinearVelocity = 0.05;
    double averageAngularVelocity = 0.1;
    double minimumDuration = 0.7;
  } baseTargetParameters;

  struct BaseTrajectoryParameters
  {
    BaseTrajectoryParameters()
    {
    }

  } baseTrajectoryParameters;
};

} /* namespace */
<commit_msg>parameter tuning<commit_after>/*
 * StepParameters.hpp
 *
 *  Created on: Feb 18, 2016
 *      Author: Péter Fankhauser
 *   Institute: ETH Zurich, Autonomous Systems Lab
 */

#pragma once

#include "free_gait_core/TypeDefs.hpp"
#include "free_gait_core/step/StepCompleter.hpp"

namespace free_gait {

class StepParameters
{
 public:
  StepParameters() {}
  virtual ~StepParameters() {};

  friend class StepCompleter;

 protected:

  struct FootstepParameters
  {
    std::string profileType = "triangle";
    double profileHeight = 0.05;
    double averageVelocity = 0.15;
    double liftOffVelocity = 0.05;
    double touchdownVelocity = -0.07;
    double minimumDuration_ = 0.5;
  } footTargetParameters;

  struct LegModeParameters
  {
    double duration = 0.5;
    std::string frameId = "base";
  } legModeParameters;

  struct BaseAutoParameters
  {
    double averageLinearVelocity = 0.07;
    double averageAngularVelocity = 0.12;
    double supportMargin = 0.05;
    double minimumDuration = 0.7;
    PlanarStance nominalPlanarStanceInBaseFrame;

    BaseAutoParameters()
    {
      Position2 position;
      position << 0.385, 0.25;
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::LF_LEG, position);
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::RF_LEG, Position2(Eigen::Vector2d(position(0), -position(1))));
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::LH_LEG, Position2(Eigen::Vector2d(-position(0), position(1))));
      nominalPlanarStanceInBaseFrame.emplace(LimbEnum::RH_LEG, Position2(Eigen::Vector2d(-position(0), -position(1))));
    }

  } baseAutoParameters;

  struct BaseTargetParameters
  {
    double averageLinearVelocity = 0.05;
    double averageAngularVelocity = 0.1;
    double minimumDuration = 0.7;
  } baseTargetParameters;

  struct BaseTrajectoryParameters
  {
    BaseTrajectoryParameters()
    {
    }

  } baseTrajectoryParameters;
};

} /* namespace */
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: Reference.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: jbu $ $Date: 2001-03-20 15:14:58 $
 *
 *  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 _COM_SUN_STAR_UNO_REFERENCE_HXX_
#define _COM_SUN_STAR_UNO_REFERENCE_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HDL_
#include <com/sun/star/uno/XInterface.hdl>
#endif
#ifndef _COM_SUN_STAR_UNO_GENFUNC_HXX_
#include <com/sun/star/uno/genfunc.hxx>
#endif

/** */ //for docpp
namespace com
{
/** */ //for docpp
namespace sun
{
/** */ //for docpp
namespace star
{
/** */ //for docpp
namespace uno
{

//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( XInterface * pInterface ) const SAL_THROW( () )
{
    if (_pInterface == pInterface)
        return sal_True;
    // only the query to XInterface must return the same pointer if they belong to same objects
    Reference< XInterface > x1( _pInterface, UNO_QUERY );
    Reference< XInterface > x2( pInterface, UNO_QUERY );
    return (x1.get() == x2.get());
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( XInterface * pInterface ) const SAL_THROW( () )
{
    return (! operator == ( pInterface ));
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return operator == ( rRef.get() );
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return (! operator == ( rRef.get() ));
}

//##################################################################################################

//__________________________________________________________________________________________________
template< class interface_type >
inline interface_type * Reference< interface_type >::__query(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    if (pInterface)
    {
        const Type & rType = ::getCppuType( (const Reference< interface_type > *)0 );
        Any aRet( pInterface->queryInterface( rType ) );
        if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass)
        {
            interface_type * pRet = * reinterpret_cast< interface_type ** >( aRet.pData );
            * reinterpret_cast< interface_type ** >( aRet.pData ) = 0;
            return pRet;
        }
    }
    return 0;
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::~Reference() SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference() SAL_THROW( () )
{
    _pInterface = 0;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    _pInterface = rRef._pInterface;
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface ) SAL_THROW( () )
{
    _pInterface = pInterface;
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    _pInterface = pInterface;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, __UnoReference_NoAcquire ) SAL_THROW( () )
{
    _pInterface = pInterface;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const BaseReference & rRef, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = __query( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( XInterface * pInterface, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = __query( pInterface );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::clear() SAL_THROW( () )
{
    if (_pInterface)
    {
        _pInterface->release();
        _pInterface = 0;
    }
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface ) SAL_THROW( () )
{
    if (pInterface != _pInterface)
    {
        if (pInterface)
            pInterface->acquire();
        if (_pInterface)
            _pInterface->release();
        _pInterface = pInterface;
    }
    return (pInterface != 0);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
    _pInterface = pInterface;
    return (pInterface != 0);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, __UnoReference_NoAcquire ) SAL_THROW( () )
{
    return set( pInterface, SAL_NO_ACQUIRE );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    return set( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    XInterface * pInterface, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set( __query( pInterface ), SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const BaseReference & rRef, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set( __query( rRef.get() ), SAL_NO_ACQUIRE );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    interface_type * pInterface ) SAL_THROW( () )
{
    set( pInterface );
    return *this;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    set( rRef.get() );
    return *this;
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    const BaseReference & rRef ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >( __query( rRef.get() ), SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >( __query( pInterface ), SAL_NO_ACQUIRE );
}

}
}
}
}

#endif
<commit_msg>minor inlining<commit_after>/*************************************************************************
 *
 *  $RCSfile: Reference.hxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: dbo $ $Date: 2001-03-21 12:42:59 $
 *
 *  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 _COM_SUN_STAR_UNO_REFERENCE_HXX_
#define _COM_SUN_STAR_UNO_REFERENCE_HXX_

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HDL_
#include <com/sun/star/uno/XInterface.hdl>
#endif
#ifndef _COM_SUN_STAR_UNO_GENFUNC_HXX_
#include <com/sun/star/uno/genfunc.hxx>
#endif

/** */ //for docpp
namespace com
{
/** */ //for docpp
namespace sun
{
/** */ //for docpp
namespace star
{
/** */ //for docpp
namespace uno
{

//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( XInterface * pInterface ) const SAL_THROW( () )
{
    if (_pInterface == pInterface)
        return sal_True;
    // only the query to XInterface must return the same pointer if they belong to same objects
    Reference< XInterface > x1( _pInterface, UNO_QUERY );
    Reference< XInterface > x2( pInterface, UNO_QUERY );
    return (x1._pInterface == x2._pInterface);
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( XInterface * pInterface ) const SAL_THROW( () )
{
    return (! operator == ( pInterface ));
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator == ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return operator == ( rRef._pInterface );
}
//__________________________________________________________________________________________________
inline sal_Bool BaseReference::operator != ( const BaseReference & rRef ) const SAL_THROW( () )
{
    return (! operator == ( rRef._pInterface ));
}

//##################################################################################################

//__________________________________________________________________________________________________
template< class interface_type >
inline interface_type * Reference< interface_type >::__query(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    if (pInterface)
    {
        const Type & rType = ::getCppuType( (const Reference< interface_type > *)0 );
        Any aRet( pInterface->queryInterface( rType ) );
        if (typelib_TypeClass_INTERFACE == aRet.pType->eTypeClass)
        {
            interface_type * pRet = * reinterpret_cast< interface_type ** >( aRet.pData );
            * reinterpret_cast< interface_type ** >( aRet.pData ) = 0;
            return pRet;
        }
    }
    return 0;
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::~Reference() SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference() SAL_THROW( () )
{
    _pInterface = 0;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    _pInterface = rRef._pInterface;
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface ) SAL_THROW( () )
{
    _pInterface = pInterface;
    if (_pInterface)
        _pInterface->acquire();
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    _pInterface = pInterface;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( interface_type * pInterface, __UnoReference_NoAcquire ) SAL_THROW( () )
{
    _pInterface = pInterface;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( const BaseReference & rRef, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = __query( rRef.get() );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type >::Reference( XInterface * pInterface, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    _pInterface = __query( pInterface );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline void Reference< interface_type >::clear() SAL_THROW( () )
{
    if (_pInterface)
    {
        _pInterface->release();
        _pInterface = 0;
    }
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface ) SAL_THROW( () )
{
    if (pInterface)
        pInterface->acquire();
    if (_pInterface)
        _pInterface->release();
    _pInterface = pInterface;
    return (pInterface != 0);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, __sal_NoAcquire ) SAL_THROW( () )
{
    if (_pInterface)
        _pInterface->release();
    _pInterface = pInterface;
    return (pInterface != 0);
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    interface_type * pInterface, __UnoReference_NoAcquire ) SAL_THROW( () )
{
    return set( pInterface, SAL_NO_ACQUIRE );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    return set( static_cast< interface_type * >( rRef._pInterface ) );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    XInterface * pInterface, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set( __query( pInterface ), SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline sal_Bool Reference< interface_type >::set(
    const BaseReference & rRef, __UnoReference_Query ) SAL_THROW( (RuntimeException) )
{
    return set( __query( rRef.get() ), SAL_NO_ACQUIRE );
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    interface_type * pInterface ) SAL_THROW( () )
{
    set( pInterface );
    return *this;
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
    const Reference< interface_type > & rRef ) SAL_THROW( () )
{
    set( static_cast< interface_type * >( rRef._pInterface ) );
    return *this;
}

//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    const BaseReference & rRef ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >( __query( rRef.get() ), SAL_NO_ACQUIRE );
}
//__________________________________________________________________________________________________
template< class interface_type >
inline Reference< interface_type > Reference< interface_type >::query(
    XInterface * pInterface ) SAL_THROW( (RuntimeException) )
{
    return Reference< interface_type >( __query( pInterface ), SAL_NO_ACQUIRE );
}

}
}
}
}

#endif
<|endoftext|>


<commit_before>#pragma once

#include "node.hpp"

namespace wrd {

    class ref : public node, public tbindable<node> {
        WRD(CLASS(ref, node))

    public:
        ref() {}
        explicit ref(const node& new1): _str(new1) {}
        explicit ref(const node* new1): _str(new1) {}
        ref(const me& rhs): super(rhs) {
            bind(*rhs);
        }

        node* operator->() { return &get(); }
        node& operator*() { return get(); }
        const node* operator->() const WRD_UNCONST_FUNC(operator->())
        const node& operator*() const WRD_UNCONST_FUNC(operator*())

        // node:
        ncontainer& subs() override {
            if (!_str) return nulOf<ncontainer>();
            return _str->subs();
        }

        using super::canRun;
        wbool canRun(const wtypes& types) const override {
            if (!_str) return false;
            return _str->canRun(types);
        }

        str run(const containable& args) override {
            if (!_str) return str();
            return _str->run(args);
        }

        // tbindable:
        using tbindable::bind;
        wbool bind(const node& it) override {
            if(!it.getType().isImmutable())
                return _str.bind(it);
            return _str.bind((node*) it.clone());
        }

        using tbindable::rel;
        void rel() override {
            _str.rel();
        }

        node& get() {
            return _str.get();
        }
        const node& get() const WRD_UNCONST_FUNC(get())
        template <typename E>
        E& get() {
            node& got = get();
            if(nul(got)) return nulOf<E>();

            return got.template cast<E>();
        }
        template <typename E>
        const E& get() const WRD_UNCONST_FUNC(get<E>())

        using tbindable::canBind;
        wbool canBind(const type& it) const override {
            return _str.canBind(it);
        }

        wbool isBind() const override {
            return _str.isBind();
        }

    private:
        str _str;
    };
}
<commit_msg>wrd: fix: ref should be like a immutable type<commit_after>#pragma once

#include "node.hpp"

namespace wrd {

    class ref : public node, public tbindable<node> {

        struct refType : public wtype {
            wbool isImmutable() const override { return true; }

        protected:
            const ases& _getImpliAses() const override {
                static ases inner;
                return inner;
            }
        };
        WRD(CLASS(ref, node, refType))

    public:
        ref() {}
        explicit ref(const node& new1): _str(new1) {}
        explicit ref(const node* new1): _str(new1) {}
        ref(const me& rhs): super(rhs) {
            bind(*rhs);
        }

        node* operator->() { return &get(); }
        node& operator*() { return get(); }
        const node* operator->() const WRD_UNCONST_FUNC(operator->())
        const node& operator*() const WRD_UNCONST_FUNC(operator*())

        // node:
        ncontainer& subs() override {
            if (!_str) return nulOf<ncontainer>();
            return _str->subs();
        }

        using super::canRun;
        wbool canRun(const wtypes& types) const override {
            if (!_str) return false;
            return _str->canRun(types);
        }

        str run(const containable& args) override {
            if (!_str) return str();
            return _str->run(args);
        }

        // tbindable:
        using tbindable::bind;
        wbool bind(const node& it) override {
            if(!it.getType().isImmutable())
                return _str.bind(it);
            return _str.bind((node*) it.clone());
        }

        using tbindable::rel;
        void rel() override {
            _str.rel();
        }

        node& get() {
            return _str.get();
        }
        const node& get() const WRD_UNCONST_FUNC(get())
        template <typename E>
        E& get() {
            node& got = get();
            if(nul(got)) return nulOf<E>();

            return got.template cast<E>();
        }
        template <typename E>
        const E& get() const WRD_UNCONST_FUNC(get<E>())

        using tbindable::canBind;
        wbool canBind(const type& it) const override {
            return _str.canBind(it);
        }

        wbool isBind() const override {
            return _str.isBind();
        }

    private:
        str _str;
    };
}
<|endoftext|>


<commit_before>#include <MutilaDebug.h>
#include "CountdownMode.h"
#include "Matrix.h"

CountdownMode_ CountdownMode;

void CountdownMode_::start(const char* data)
{
    startMs = millis();
    n = String(data).toInt();
    i = 0;
    DB(F("CountdownMode::start "));
    DBLN(data);
    Matrix.clear();
    Matrix.paint();
    Matrix.setFont(5);
}

void CountdownMode_::update()
{
    unsigned long next = startMs + (i*2);
    if (millis() >= next && i < 18) {
        i+=1;
        Matrix.rectangle(MATRIX_RED, 17-i, 15+i, 30+(i*2), i*2);
        Matrix.rectangle(MATRIX_BLACK, 17-(i-3), 15+(i-3), 30+((i-3)*2), (i-3)*2);
        if (n==0) {
            Matrix.text(MATRIX_ORANGE, 20, 23, "Go!");
        } else {
            Matrix.text(MATRIX_ORANGE, 27, 23, String(n));
        }
        Matrix.paint();
    }
}

<commit_msg>do traffic light colors for CountdownMode<commit_after>#include <MutilaDebug.h>
#include "CountdownMode.h"
#include "Matrix.h"

CountdownMode_ CountdownMode;

void CountdownMode_::start(const char* data)
{
    startMs = millis();
    n = String(data).toInt();
    i = 0;
    DB(F("CountdownMode::start "));
    DBLN(data);
    Matrix.clear();
    Matrix.paint();
    Matrix.setFont(5);
}

void CountdownMode_::update()
{
    unsigned long next = startMs + (i*2);
    if (millis() >= next && i < 18) {
        uint8_t bgCol[3] = { MATRIX_GREEN, MATRIX_ORANGE, MATRIX_RED };
        uint8_t txCol[3] = { MATRIX_RED, MATRIX_GREEN, MATRIX_ORANGE };
        uint8_t colIdx = n % 3;
        i+=1;
        Matrix.rectangle(bgCol[colIdx], 17-i, 15+i, 30+(i*2), i*2);

        // At the end of the sequence, draw the text
        if (i==17) {
            if (n==0) {
                Matrix.text(txCol[colIdx], 20, 23, "Go!");
            } else if (n==1) {
                // digit '1' is narrower than other digits
                Matrix.text(txCol[colIdx], 29, 23, String(n));
            } else {
                Matrix.text(txCol[colIdx], 27, 23, String(n));
            }
        }
        Matrix.paint();
    }
}

<|endoftext|>