<commit_before>#include <opengl.hpp>
#include <output.hpp>
#include <core.hpp>
#include <debug.hpp>
#include <render-manager.hpp>
#include <workspace-manager.hpp>

#include <compositor.h>
#include <linux/input-event-codes.h>
#include <config.hpp>
#include <config.h>

#define COEFF_DELTA_NEAR 0.89567f
#define COEFF_DELTA_FAR  2.00000f

#if USE_GLES32
#include <GLES3/gl32.h>
#endif

class wayfire_cube : public wayfire_plugin_t {
    button_callback activate;
    wayfire_button act_button;

    std::vector<wf_workspace_stream*> streams;

    float XVelocity = 0.01;
    float YVelocity = 0.01;
    float ZVelocity = 0.05;
    float MaxFactor = 10;

    float angle;      // angle between sides
    float offset;     // horizontal rotation angle
    float offsetVert; // vertical rotation angle
    float zoomFactor = 1.0;

    int px, py;

    render_hook_t renderer;

    struct {
        GLuint id = -1;
        GLuint modelID, vpID;
        GLuint posID, uvID;
    } program;

    struct duple { float start, end; };

    struct
    {
        duple offset_y;
        duple offset_z;
        duple rotation;
        int current_step, max_steps;

        bool in_exit;
    } animation;

    glm::mat4 vp, model, view, project;
    float coeff;

#if USE_GLES32
    bool use_light;
    int use_deform;
#endif

    wayfire_color backgroud_color;

    public:
    void init(wayfire_config *config)
    {
        grab_interface->name = "cube";
        grab_interface->abilities_mask = WF_ABILITY_CONTROL_WM;

        auto section = config->get_section("cube");

        XVelocity  = section->get_double("speed_spin_horiz", 0.01);
        YVelocity  = section->get_double("speed_spin_vert",  0.01);
        ZVelocity  = section->get_double("speed_zoom",       0.05);

        animation.max_steps  = section->get_duration("initial_animation", 30);

        backgroud_color = section->get_color("background", {0, 0, 0, 1});

        act_button = section->get_button("activate",
                {MODIFIER_ALT | MODIFIER_CTRL, BTN_LEFT});

        if (act_button.button == 0)
            return;

        activate = [=] (weston_pointer *ptr, uint32_t) {
            initiate(wl_fixed_to_int(ptr->x), wl_fixed_to_int(ptr->y));
        };

        output->add_button(act_button.mod, act_button.button, &activate);

        grab_interface->callbacks.pointer.button = [=] (weston_pointer*,
                uint32_t b, uint32_t s)
        {
            if (s == WL_POINTER_BUTTON_STATE_RELEASED)
                input_released();
        };

        grab_interface->callbacks.pointer.motion = [=] (weston_pointer* ptr,
                weston_pointer_motion_event*)
        {
            pointer_moved(wl_fixed_to_int(ptr->x), wl_fixed_to_int(ptr->y));
        };

        grab_interface->callbacks.pointer.axis = [=] (weston_pointer*,
                weston_pointer_axis_event *ev) {
            if (ev->axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
                pointer_scrolled(ev->value);
        };

#if USE_GLES32
        use_light = section->get_int("light", 1);
        use_deform = section->get_int("deform", 1);
#endif

        auto vw = std::get<0>(output->workspace->get_workspace_grid_size());
        angle = 2 * M_PI / float(vw);
        coeff = 0.5 / std::tan(angle / 2);

        renderer = [=] () {render();};
    }

    void load_program()
    {
#if USE_GLES32
            std::string shaderSrcPath =
                INSTALL_PREFIX "/share/wayfire/cube/shaders_3.2";
#else
            std::string shaderSrcPath =
                INSTALL_PREFIX "/share/wayfire/cube/shaders_2.0";
#endif

            program.id = GL_CALL(glCreateProgram());
            GLuint vss, fss, tcs = -1, tes = -1, gss = -1;

            vss = OpenGL::load_shader(std::string(shaderSrcPath)
                        .append("/vertex.glsl").c_str(), GL_VERTEX_SHADER);

            fss = OpenGL::load_shader(std::string(shaderSrcPath)
                        .append("/frag.glsl").c_str(), GL_FRAGMENT_SHADER);

            GL_CALL(glAttachShader(program.id, vss));
            GL_CALL(glAttachShader(program.id, fss));

#if USE_GLES32
            tcs = OpenGL::load_shader(std::string(shaderSrcPath)
                    .append("/tcs.glsl").c_str(),
                    GL_TESS_CONTROL_SHADER);

            tes = OpenGL::load_shader(std::string(shaderSrcPath)
                    .append("/tes.glsl").c_str(),
                    GL_TESS_EVALUATION_SHADER);

            gss = OpenGL::load_shader(std::string(shaderSrcPath)
                    .append("/geom.glsl").c_str(),
                    GL_GEOMETRY_SHADER);
            GL_CALL(glAttachShader(program.id, tcs));
            GL_CALL(glAttachShader(program.id, tes));
            GL_CALL(glAttachShader(program.id, gss));
#endif

            GL_CALL(glLinkProgram(program.id));
            GL_CALL(glUseProgram(program.id));

            program.vpID = GL_CALL(glGetUniformLocation(program.id, "VP"));
            GL_CALL(glUniformMatrix4fv(program.vpID, 1, GL_FALSE, &vp[0][0]));

            program.uvID = GL_CALL(glGetAttribLocation(program.id, "uvPosition"));
            program.posID = GL_CALL(glGetAttribLocation(program.id, "position"));
            program.modelID = GL_CALL(glGetUniformLocation(program.id, "model"));

#if USE_GLES32
            GLuint defID = GL_CALL(glGetUniformLocation(program.id, "deform"));
            glUniform1i(defID, use_deform);

            GLuint lightID = GL_CALL(glGetUniformLocation(program.id, "light"));
            glUniform1i(lightID, use_light);
#endif

            GetTuple(vw, vh, output->workspace->get_workspace_grid_size());
            vh = 0; /* silence compiler warning */

            streams.resize(vw);

            for(int i = 0; i < vw; i++) {
                streams[i] = new wf_workspace_stream;
                streams[i]->fbuff = streams[i]->tex = -1;
            }

            project = glm::perspective(45.0f, 1.f, 0.1f, 100.f);
    }

    void initiate(int x, int y)
    {
        if (!output->activate_plugin(grab_interface))
            return;
        grab_interface->grab();

        output->render->set_renderer(renderer);
        output->render->auto_redraw(true);

        offset = 0;
        offsetVert = 0;
        zoomFactor = 1;
        animation.current_step = 0;
        animation.in_exit = false;
        animation.offset_z = {coeff + COEFF_DELTA_NEAR, coeff + COEFF_DELTA_FAR};

        output->render->auto_redraw(update_animation());

        px = x;
        py = y;
    }

    bool update_animation()
    {
        float z_offset = GetProgress(animation.offset_z.start,
                                     animation.offset_z.end,
                                     animation.current_step,
                                     animation.max_steps);

        /* also update rotation and Y offset */
        if (animation.in_exit)
        {
            offsetVert = GetProgress(animation.offset_y.start,
                                   animation.offset_y.end,
                                   animation.current_step,
                                   animation.max_steps);

            offset = GetProgress(animation.rotation.start,
                                 animation.rotation.end,
                                 animation.current_step,
                                 animation.max_steps);
        }

        view = glm::lookAt(glm::vec3(0., offsetVert, z_offset),
                glm::vec3(0., 0., 0.),
                glm::vec3(0., 1., 0.));

        if (animation.current_step < animation.max_steps)
        {
            ++animation.current_step;
            if (animation.current_step == animation.max_steps)
                return false;
            else
                return true;
        }

        return false;
    }

    void render()
    {
        if (program.id == (uint)-1)
            load_program();

        GL_CALL(glClearColor(backgroud_color.r, backgroud_color.g,
                backgroud_color.b, backgroud_color.a));

        GL_CALL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));

        GetTuple(vx, vy, output->workspace->get_current_workspace());
        for(size_t i = 0; i < streams.size(); i++) {
            if (!streams[i]->running) {
                streams[i]->ws = std::make_tuple(i, vy);
                output->render->workspace_stream_start(streams[i]);
            } else {
                output->render->workspace_stream_update(streams[i]);
            }
        }

        GL_CALL(glUseProgram(program.id));
        GL_CALL(glEnable(GL_DEPTH_TEST));
        GL_CALL(glDepthFunc(GL_LESS));

        vp = project * view;

        GL_CALL(glUniformMatrix4fv(program.vpID, 1, GL_FALSE, &vp[0][0]));

        glm::mat4 base_model = glm::scale(glm::mat4(),
                glm::vec3(1. / zoomFactor, 1. / zoomFactor,
                    1. / zoomFactor));

        GLfloat vertexData[] = {
            -0.5,  0.5,
             0.5,  0.5,
             0.5, -0.5,
            -0.5,  0.5,
             0.5, -0.5,
            -0.5, -0.5
        };

        GLfloat coordData[] = {
            0.0f, 1.0f,
            1.0f, 1.0f,
            1.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            0.0f, 0.0f,
        };

        GL_CALL(glVertexAttribPointer(program.posID, 2, GL_FLOAT, GL_FALSE, 0, vertexData));
        GL_CALL(glEnableVertexAttribArray(program.posID));

        GL_CALL(glVertexAttribPointer(program.uvID, 2, GL_FLOAT, GL_FALSE, 0, coordData));
        GL_CALL(glEnableVertexAttribArray(program.uvID));

        for(size_t i = 0; i < streams.size(); i++) {
            int index = (vx + i) % streams.size();

            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));

            GL_CALL(glBindTexture(GL_TEXTURE_2D, streams[index]->tex));
            GL_CALL(glActiveTexture(GL_TEXTURE0));

            model = glm::rotate(base_model,
                    float(i) * angle + offset, glm::vec3(0, 1, 0));
            model = glm::translate(model, glm::vec3(0, 0, coeff));
           GL_CALL(glUniformMatrix4fv(program.modelID, 1, GL_FALSE, &model[0][0]));

#if USE_GLES32
           GL_CALL(glDrawArrays(GL_PATCHES, 0, 6));
#else
           GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
#endif
        }
        glDisable(GL_DEPTH_TEST);

        GL_CALL(glDisableVertexAttribArray(program.posID));
        GL_CALL(glDisableVertexAttribArray(program.uvID));

        bool result = update_animation();
        output->render->auto_redraw(result);

        if (animation.in_exit && !result)
            terminate();
    }

    void input_released()
    {
        auto size = streams.size();

        float dx = -(offset) / angle;
        int dvx = std::floor(dx + 0.5);

        GetTuple(vx, vy, output->workspace->get_current_workspace());
        int nvx = (vx + (dvx % size) + size) % size;
        output->workspace->set_workspace(std::make_tuple(nvx, vy));

        animation.in_exit = true;
        animation.current_step = 0;
        animation.offset_z = {coeff + COEFF_DELTA_FAR, coeff + COEFF_DELTA_NEAR};
        animation.offset_y = {offsetVert, 0};
        animation.rotation = {offset + 1.0f * dvx * angle, 0};

        update_animation();
    }

    void terminate()
    {
        output->render->reset_renderer();
        output->deactivate_plugin(grab_interface);

        auto size = streams.size();
        for (uint i = 0; i < size; i++)
            output->render->workspace_stream_stop(streams[i]);
    }

    void pointer_moved(int x, int y)
    {
        if (animation.in_exit)
            return;

        int xdiff = x - px;
        int ydiff = y - py;
        offset += xdiff * XVelocity;
        offsetVert += ydiff * YVelocity;
        px = x, py = y;
    }

    void pointer_scrolled(double amount)
    {
        zoomFactor += ZVelocity * amount;

        if (zoomFactor > MaxFactor)
            zoomFactor = MaxFactor;

        if (zoomFactor <= 0.1)
            zoomFactor = 0.1;
    }
};

extern "C" {
    wayfire_plugin_t *newInstance() {
        return new wayfire_cube();
    }

}
<commit_msg>cube: deactivate plugin on input_released()<commit_after>#include <opengl.hpp>
#include <output.hpp>
#include <core.hpp>
#include <debug.hpp>
#include <render-manager.hpp>
#include <workspace-manager.hpp>

#include <compositor.h>
#include <linux/input-event-codes.h>
#include <config.hpp>
#include <config.h>

#define COEFF_DELTA_NEAR 0.89567f
#define COEFF_DELTA_FAR  2.00000f

#if USE_GLES32
#include <GLES3/gl32.h>
#endif

class wayfire_cube : public wayfire_plugin_t {
    button_callback activate;
    wayfire_button act_button;

    std::vector<wf_workspace_stream*> streams;

    float XVelocity = 0.01;
    float YVelocity = 0.01;
    float ZVelocity = 0.05;
    float MaxFactor = 10;

    float angle;      // angle between sides
    float offset;     // horizontal rotation angle
    float offsetVert; // vertical rotation angle
    float zoomFactor = 1.0;

    int px, py;

    render_hook_t renderer;

    struct {
        GLuint id = -1;
        GLuint modelID, vpID;
        GLuint posID, uvID;
    } program;

    struct duple { float start, end; };

    struct
    {
        duple offset_y;
        duple offset_z;
        duple rotation;
        int current_step, max_steps;

        bool in_exit;
    } animation;

    glm::mat4 vp, model, view, project;
    float coeff;

#if USE_GLES32
    bool use_light;
    int use_deform;
#endif

    wayfire_color backgroud_color;

    public:
    void init(wayfire_config *config)
    {
        grab_interface->name = "cube";
        grab_interface->abilities_mask = WF_ABILITY_CONTROL_WM;

        auto section = config->get_section("cube");

        XVelocity  = section->get_double("speed_spin_horiz", 0.01);
        YVelocity  = section->get_double("speed_spin_vert",  0.01);
        ZVelocity  = section->get_double("speed_zoom",       0.05);

        animation.max_steps  = section->get_duration("initial_animation", 30);

        backgroud_color = section->get_color("background", {0, 0, 0, 1});

        act_button = section->get_button("activate",
                {MODIFIER_ALT | MODIFIER_CTRL, BTN_LEFT});

        if (act_button.button == 0)
            return;

        activate = [=] (weston_pointer *ptr, uint32_t) {
            initiate(wl_fixed_to_int(ptr->x), wl_fixed_to_int(ptr->y));
        };

        output->add_button(act_button.mod, act_button.button, &activate);

        grab_interface->callbacks.pointer.button = [=] (weston_pointer*,
                uint32_t b, uint32_t s)
        {
            if (s == WL_POINTER_BUTTON_STATE_RELEASED)
                input_released();
        };

        grab_interface->callbacks.pointer.motion = [=] (weston_pointer* ptr,
                weston_pointer_motion_event*)
        {
            pointer_moved(wl_fixed_to_int(ptr->x), wl_fixed_to_int(ptr->y));
        };

        grab_interface->callbacks.pointer.axis = [=] (weston_pointer*,
                weston_pointer_axis_event *ev) {
            if (ev->axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
                pointer_scrolled(ev->value);
        };

#if USE_GLES32
        use_light = section->get_int("light", 1);
        use_deform = section->get_int("deform", 1);
#endif

        auto vw = std::get<0>(output->workspace->get_workspace_grid_size());
        angle = 2 * M_PI / float(vw);
        coeff = 0.5 / std::tan(angle / 2);

        renderer = [=] () {render();};
    }

    void load_program()
    {
#if USE_GLES32
            std::string shaderSrcPath =
                INSTALL_PREFIX "/share/wayfire/cube/shaders_3.2";
#else
            std::string shaderSrcPath =
                INSTALL_PREFIX "/share/wayfire/cube/shaders_2.0";
#endif

            program.id = GL_CALL(glCreateProgram());
            GLuint vss, fss, tcs = -1, tes = -1, gss = -1;

            vss = OpenGL::load_shader(std::string(shaderSrcPath)
                        .append("/vertex.glsl").c_str(), GL_VERTEX_SHADER);

            fss = OpenGL::load_shader(std::string(shaderSrcPath)
                        .append("/frag.glsl").c_str(), GL_FRAGMENT_SHADER);

            GL_CALL(glAttachShader(program.id, vss));
            GL_CALL(glAttachShader(program.id, fss));

#if USE_GLES32
            tcs = OpenGL::load_shader(std::string(shaderSrcPath)
                    .append("/tcs.glsl").c_str(),
                    GL_TESS_CONTROL_SHADER);

            tes = OpenGL::load_shader(std::string(shaderSrcPath)
                    .append("/tes.glsl").c_str(),
                    GL_TESS_EVALUATION_SHADER);

            gss = OpenGL::load_shader(std::string(shaderSrcPath)
                    .append("/geom.glsl").c_str(),
                    GL_GEOMETRY_SHADER);
            GL_CALL(glAttachShader(program.id, tcs));
            GL_CALL(glAttachShader(program.id, tes));
            GL_CALL(glAttachShader(program.id, gss));
#endif

            GL_CALL(glLinkProgram(program.id));
            GL_CALL(glUseProgram(program.id));

            program.vpID = GL_CALL(glGetUniformLocation(program.id, "VP"));
            GL_CALL(glUniformMatrix4fv(program.vpID, 1, GL_FALSE, &vp[0][0]));

            program.uvID = GL_CALL(glGetAttribLocation(program.id, "uvPosition"));
            program.posID = GL_CALL(glGetAttribLocation(program.id, "position"));
            program.modelID = GL_CALL(glGetUniformLocation(program.id, "model"));

#if USE_GLES32
            GLuint defID = GL_CALL(glGetUniformLocation(program.id, "deform"));
            glUniform1i(defID, use_deform);

            GLuint lightID = GL_CALL(glGetUniformLocation(program.id, "light"));
            glUniform1i(lightID, use_light);
#endif

            GetTuple(vw, vh, output->workspace->get_workspace_grid_size());
            vh = 0; /* silence compiler warning */

            streams.resize(vw);

            for(int i = 0; i < vw; i++) {
                streams[i] = new wf_workspace_stream;
                streams[i]->fbuff = streams[i]->tex = -1;
            }

            project = glm::perspective(45.0f, 1.f, 0.1f, 100.f);
    }

    void initiate(int x, int y)
    {
        if (!output->activate_plugin(grab_interface))
            return;
        grab_interface->grab();

        output->render->set_renderer(renderer);
        output->render->auto_redraw(true);

        offset = 0;
        offsetVert = 0;
        zoomFactor = 1;
        animation.current_step = 0;
        animation.in_exit = false;
        animation.offset_z = {coeff + COEFF_DELTA_NEAR, coeff + COEFF_DELTA_FAR};

        output->render->auto_redraw(update_animation());

        px = x;
        py = y;
    }

    bool update_animation()
    {
        float z_offset = GetProgress(animation.offset_z.start,
                                     animation.offset_z.end,
                                     animation.current_step,
                                     animation.max_steps);

        /* also update rotation and Y offset */
        if (animation.in_exit)
        {
            offsetVert = GetProgress(animation.offset_y.start,
                                   animation.offset_y.end,
                                   animation.current_step,
                                   animation.max_steps);

            offset = GetProgress(animation.rotation.start,
                                 animation.rotation.end,
                                 animation.current_step,
                                 animation.max_steps);
        }

        view = glm::lookAt(glm::vec3(0., offsetVert, z_offset),
                glm::vec3(0., 0., 0.),
                glm::vec3(0., 1., 0.));

        if (animation.current_step < animation.max_steps)
        {
            ++animation.current_step;
            if (animation.current_step == animation.max_steps)
                return false;
            else
                return true;
        }

        return false;
    }

    void render()
    {
        if (program.id == (uint)-1)
            load_program();

        GL_CALL(glClearColor(backgroud_color.r, backgroud_color.g,
                backgroud_color.b, backgroud_color.a));

        GL_CALL(glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT));

        GetTuple(vx, vy, output->workspace->get_current_workspace());
        for(size_t i = 0; i < streams.size(); i++) {
            if (!streams[i]->running) {
                streams[i]->ws = std::make_tuple(i, vy);
                output->render->workspace_stream_start(streams[i]);
            } else {
                output->render->workspace_stream_update(streams[i]);
            }
        }

        GL_CALL(glUseProgram(program.id));
        GL_CALL(glEnable(GL_DEPTH_TEST));
        GL_CALL(glDepthFunc(GL_LESS));

        vp = project * view;

        GL_CALL(glUniformMatrix4fv(program.vpID, 1, GL_FALSE, &vp[0][0]));

        glm::mat4 base_model = glm::scale(glm::mat4(),
                glm::vec3(1. / zoomFactor, 1. / zoomFactor,
                    1. / zoomFactor));

        GLfloat vertexData[] = {
            -0.5,  0.5,
             0.5,  0.5,
             0.5, -0.5,
            -0.5,  0.5,
             0.5, -0.5,
            -0.5, -0.5
        };

        GLfloat coordData[] = {
            0.0f, 1.0f,
            1.0f, 1.0f,
            1.0f, 0.0f,
            0.0f, 1.0f,
            1.0f, 0.0f,
            0.0f, 0.0f,
        };

        GL_CALL(glVertexAttribPointer(program.posID, 2, GL_FLOAT, GL_FALSE, 0, vertexData));
        GL_CALL(glEnableVertexAttribArray(program.posID));

        GL_CALL(glVertexAttribPointer(program.uvID, 2, GL_FLOAT, GL_FALSE, 0, coordData));
        GL_CALL(glEnableVertexAttribArray(program.uvID));

        for(size_t i = 0; i < streams.size(); i++) {
            int index = (vx + i) % streams.size();

            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));

            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
            GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));

            GL_CALL(glBindTexture(GL_TEXTURE_2D, streams[index]->tex));
            GL_CALL(glActiveTexture(GL_TEXTURE0));

            model = glm::rotate(base_model,
                    float(i) * angle + offset, glm::vec3(0, 1, 0));
            model = glm::translate(model, glm::vec3(0, 0, coeff));
           GL_CALL(glUniformMatrix4fv(program.modelID, 1, GL_FALSE, &model[0][0]));

#if USE_GLES32
           GL_CALL(glDrawArrays(GL_PATCHES, 0, 6));
#else
           GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 6));
#endif
        }
        glDisable(GL_DEPTH_TEST);

        GL_CALL(glDisableVertexAttribArray(program.posID));
        GL_CALL(glDisableVertexAttribArray(program.uvID));

        bool result = update_animation();
        output->render->auto_redraw(result);

        if (animation.in_exit && !result)
            terminate();
    }

    void input_released()
    {
        auto size = streams.size();

        float dx = -(offset) / angle;
        int dvx = std::floor(dx + 0.5);

        GetTuple(vx, vy, output->workspace->get_current_workspace());
        int nvx = (vx + (dvx % size) + size) % size;
        output->workspace->set_workspace(std::make_tuple(nvx, vy));

        animation.in_exit = true;
        animation.current_step = 0;
        animation.offset_z = {coeff + COEFF_DELTA_FAR, coeff + COEFF_DELTA_NEAR};
        animation.offset_y = {offsetVert, 0};
        animation.rotation = {offset + 1.0f * dvx * angle, 0};

        update_animation();
        output->deactivate_plugin(grab_interface);
    }

    void terminate()
    {
        output->render->reset_renderer();
        auto size = streams.size();
        for (uint i = 0; i < size; i++)
            output->render->workspace_stream_stop(streams[i]);
    }

    void pointer_moved(int x, int y)
    {
        if (animation.in_exit)
            return;

        int xdiff = x - px;
        int ydiff = y - py;
        offset += xdiff * XVelocity;
        offsetVert += ydiff * YVelocity;
        px = x, py = y;
    }

    void pointer_scrolled(double amount)
    {
        zoomFactor += ZVelocity * amount;

        if (zoomFactor > MaxFactor)
            zoomFactor = MaxFactor;

        if (zoomFactor <= 0.1)
            zoomFactor = 0.1;
    }
};

extern "C" {
    wayfire_plugin_t *newInstance() {
        return new wayfire_cube();
    }

}
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * Copyright (C) 2002-2022 Németh László
 *
 * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
/*
 * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
 * And Contributors.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. All modifications to the source code must be clearly marked as
 *    such.  Binary redistributions based on modified source code
 *    must be clearly marked as modified versions in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <limits>

#include "replist.hxx"
#include "csutil.hxx"

RepList::RepList(int n) {
  dat.reserve(std::min(n, 16384));
}

RepList::~RepList() {
  for (size_t i = 0, pos = dat.size(); i < pos; ++i) {
    delete dat[i];
  }
}

int RepList::find(const char* word) {
  int p1 = 0;
  int p2 = dat.size() - 1;
  int ret = -1;
  while (p1 <= p2) {
    int m = ((unsigned)p1 + (unsigned)p2) >> 1;
    int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size());
    if (c < 0)
      p2 = m - 1;
    else if (c > 0)
      p1 = m + 1;
    else {      // scan in the right half for a longer match
      ret = m;
      p1 = m + 1;
    }
  }
  return ret;
}

std::string RepList::replace(const size_t wordlen, int ind, bool atstart) {
  int type = atstart ? 1 : 0;
  if (wordlen == dat[ind]->pattern.size())
    type = atstart ? 3 : 2;
  while (type && dat[ind]->outstrings[type].empty())
    type = (type == 2 && !atstart) ? 0 : type - 1;
  return dat[ind]->outstrings[type];
}

int RepList::add(const std::string& in_pat1, const std::string& pat2) {
  if (in_pat1.empty() || pat2.empty()) {
    return 1;
  }
  // analyse word context
  int type = 0;
  std::string pat1(in_pat1);
  if (pat1[0] == '_') {
    pat1.erase(0, 1);
    type = 1;
  }
  if (!pat1.empty() && pat1[pat1.size() - 1] == '_') {
    type = type + 2;
    pat1.erase(pat1.size() - 1);
  }
  mystrrep(pat1, "_", " ");

  // find existing entry
  int m = find(pat1.c_str());
  if (m >= 0 && dat[m]->pattern == pat1) {
    // since already used
    dat[m]->outstrings[type] = pat2;
    mystrrep(dat[m]->outstrings[type], "_", " ");
    return 0;
  }

  // make a new entry if none exists
  replentry* r = new replentry;
  if (r == NULL)
    return 1;
  r->pattern = pat1;
  r->outstrings[type] = pat2;
  mystrrep(r->outstrings[type], "_", " ");
  dat.push_back(r);
  // sort to the right place in the list
  size_t i;
  for (i = dat.size() - 1; i > 0; --i) {
    if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) {
      dat[i] = dat[i - 1];
    } else
      break;
  }
  dat[i] = r;
  return 0;
}

bool RepList::conv(const std::string& in_word, std::string& dest) {
  dest.clear();

  size_t wordlen = in_word.size();
  const char* word = in_word.c_str();

  bool change = false;
  for (size_t i = 0; i < wordlen; ++i) {
    int n = find(word + i);

    bool empty = n < 0;
    if (empty) {
      dest.push_back(word[i]);
      continue;
    }

    std::string l = replace(wordlen - i, n, i == 0);
    if (l.empty()) {
      dest.push_back(word[i]);
      continue;
    }

    dest.append(l);
    i += dat[n]->pattern.size() - 1;
    change = true;
  }

  return change;
}

<commit_msg>ofz#51129 OOM<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * Copyright (C) 2002-2022 Németh László
 *
 * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Hunspell is based on MySpell which is Copyright (C) 2002 Kevin Hendricks.
 *
 * Contributor(s): David Einstein, Davide Prina, Giuseppe Modugno,
 * Gianluca Turconi, Simon Brouwer, Noll János, Bíró Árpád,
 * Goldman Eleonóra, Sarlós Tamás, Bencsáth Boldizsár, Halácsy Péter,
 * Dvornik László, Gefferth András, Nagy Viktor, Varga Dániel, Chris Halls,
 * Rene Engelhard, Bram Moolenaar, Dafydd Jones, Harri Pitkänen
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
/*
 * Copyright 2002 Kevin B. Hendricks, Stratford, Ontario, Canada
 * And Contributors.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. All modifications to the source code must be clearly marked as
 *    such.  Binary redistributions based on modified source code
 *    must be clearly marked as modified versions in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY KEVIN B. HENDRICKS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * KEVIN B. HENDRICKS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <limits>

#include "replist.hxx"
#include "csutil.hxx"

RepList::RepList(int n) {
  dat.reserve(std::min(n, 16384));
}

RepList::~RepList() {
  for (size_t i = 0, pos = dat.size(); i < pos; ++i) {
    delete dat[i];
  }
}

int RepList::find(const char* word) {
  int p1 = 0;
  int p2 = dat.size() - 1;
  int ret = -1;
  while (p1 <= p2) {
    int m = ((unsigned)p1 + (unsigned)p2) >> 1;
    int c = strncmp(word, dat[m]->pattern.c_str(), dat[m]->pattern.size());
    if (c < 0)
      p2 = m - 1;
    else if (c > 0)
      p1 = m + 1;
    else {      // scan in the right half for a longer match
      ret = m;
      p1 = m + 1;
    }
  }
  return ret;
}

std::string RepList::replace(const size_t wordlen, int ind, bool atstart) {
  int type = atstart ? 1 : 0;
  if (wordlen == dat[ind]->pattern.size())
    type = atstart ? 3 : 2;
  while (type && dat[ind]->outstrings[type].empty())
    type = (type == 2 && !atstart) ? 0 : type - 1;
  return dat[ind]->outstrings[type];
}

int RepList::add(const std::string& in_pat1, const std::string& pat2) {
  if (in_pat1.empty() || pat2.empty()) {
    return 1;
  }
  // analyse word context
  int type = 0;
  std::string pat1(in_pat1);
  if (pat1[0] == '_') {
    pat1.erase(0, 1);
    type = 1;
  }
  if (!pat1.empty() && pat1[pat1.size() - 1] == '_') {
    type = type + 2;
    pat1.erase(pat1.size() - 1);
  }
  mystrrep(pat1, "_", " ");

  // find existing entry
  int m = find(pat1.c_str());
  if (m >= 0 && dat[m]->pattern == pat1) {
    // since already used
    dat[m]->outstrings[type] = pat2;
    mystrrep(dat[m]->outstrings[type], "_", " ");
    return 0;
  }

  // make a new entry if none exists
  replentry* r = new replentry;
  if (r == NULL)
    return 1;
  r->pattern = pat1;
  r->outstrings[type] = pat2;
  mystrrep(r->outstrings[type], "_", " ");
  dat.push_back(r);
  // sort to the right place in the list
  size_t i;
  for (i = dat.size() - 1; i > 0; --i) {
    if (strcmp(r->pattern.c_str(), dat[i - 1]->pattern.c_str()) < 0) {
      dat[i] = dat[i - 1];
    } else
      break;
  }
  dat[i] = r;
  return 0;
}

bool RepList::conv(const std::string& in_word, std::string& dest) {
  dest.clear();

  size_t wordlen = in_word.size();
  const char* word = in_word.c_str();

  bool change = false;
  for (size_t i = 0; i < wordlen; ++i) {
    int n = find(word + i);

    bool empty = n < 0;
    if (empty) {
      dest.push_back(word[i]);
      continue;
    }

    std::string l = replace(wordlen - i, n, i == 0);
    if (l.empty()) {
      dest.push_back(word[i]);
      continue;
    }

    dest.append(l);
    if (!dat[n]->pattern.empty()) {
      i += dat[n]->pattern.size() - 1;
    }
    change = true;
  }

  return change;
}

<|endoftext|>


<commit_before>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "query_parser.h"

namespace You {
namespace NLP {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace phoenix = boost::phoenix;

QUERY QueryParser::parse(const StringType& string) {
	QUERY result;

	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool QueryParser::parse(const StringType& string, QUERY& result) {
	return qi::parse(
		begin(string),
		end(string),
		QueryParser() > qi::eoi,
		result);
}

QueryParser::QueryParser() : QueryParser::base_type(start) {
	start %= (
		(qi::lit('/') > explicitCommand) |
		addCommand
	);
	BOOST_SPIRIT_DEBUG_NODE(start);

	explicitCommand %= (
		(qi::lit("add") > space > addCommand) |
		(qi::lit("show") > *space > showCommand) |
		(qi::lit("edit") > space > editCommand) |
		(qi::lit("delete") > space > deleteCommand) |
		(qi::lit("undo") > *space > undoCommand)
	);
	BOOST_SPIRIT_DEBUG_NODE(explicitCommand);

	#pragma region Adding tasks
	addCommand = (
		addCommandDescription >
		-(*space >> qi::lit("->") > *space > addCommand) >
		-(*space >> qi::lit(':') > *space > addCommandSubtasks)
	)[qi::_val = phoenix::bind(
		&constructAddQuery,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(addCommand);

	addCommandDescription = (
		ParserCharTraits::char_ > addCommandDescriptionTail
	)[qi::_val = phoenix::bind(
		&constructAddQueryFromDescription,
		qi::_1,
		qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescription);

	addCommandDescriptionTail %= (
		addCommandPriority |
		addCommandDescription
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionTail);

	addCommandPriority %= (
		(-space >> qi::lit('!') >> addCommandDeadlineOptional)
			[qi::_val = phoenix::bind(&constructAddQueryWithPriority, qi::_1)] |
		addCommandDeadlineOptional
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandPriority);

	addCommandDeadline = (
		space >> (qi::lit("by") | qi::lit("before")) >> space >>
		utilityTime >> *space
	)[qi::_val = phoenix::bind(&constructAddQueryWithDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadline);

	addCommandDeadlineOptional = (
		addCommandDeadline || (
			*space >> &(qi::char_(":;") | qi::lit("->") | qi::eoi))
	)[qi::_val = phoenix::bind(&constructAddQueryWithOptionalDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadlineOptional);

	addCommandSubtasks %= (
		addCommand % (*space >> qi::lit(';') >> *space)
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandSubtasks);
	#pragma endregion

	#pragma region Showing tasks
	showCommand = (
		-showCommandFiltering >
		-(-space >> (qi::lit("sorted by") | qi::lit("order by")) > space >
		showCommandSorting)
	)[qi::_val = phoenix::bind(&constructShowQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommand);

	showCommandFiltering %=
		showCommandFilteringColumn % (
			(-space >> qi::lit(',') >> -space) |
			(space >> qi::lit("and") >> space));
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringColumn = (
		showCommandFields >
		-space > showCommandFilteringPredicate > -space >
		utilityValue
	)[qi::_val = phoenix::bind(&constructShowQueryFilteringColumn,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringPredicate.add
		(L"=", SHOW_QUERY::Predicate::EQ)
		(L"!=", SHOW_QUERY::Predicate::NOT_EQ)
		(L"<", SHOW_QUERY::Predicate::LESS_THAN)
		(L"<=", SHOW_QUERY::Predicate::LESS_THAN_EQ)
		(L">", SHOW_QUERY::Predicate::GREATER_THAN)
		(L">=", SHOW_QUERY::Predicate::GREATER_THAN_EQ);

	showCommandSorting %= (
		showCommandSortingColumn % (
			(-space >> qi::lit(",") >> -space) |
			(space >> qi::lit("then") >> space)));
	BOOST_SPIRIT_DEBUG_NODE(showCommandSorting);

	showCommandSortingColumn = (
		showCommandFields >> -(space >> showCommandSortingOrders)
	)[qi::_val = phoenix::bind(&constructShowQuerySortColumn, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandSortingColumn);

	showCommandSortingOrders.add
		(L"asc", SHOW_QUERY::Order::ASCENDING)
		(L"ascending", SHOW_QUERY::Order::ASCENDING)
		(L"desc", SHOW_QUERY::Order::DESCENDING)
		(L"descending", SHOW_QUERY::Order::DESCENDING);

	showCommandFields.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE)
		(L"priority", TaskField::PRIORITY)
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Editing tasks
	editCommand = (
		qi::uint_ > (
			(space >> qi::lit("set") > space > editCommandRule) |
			(qi::lit(":") > *space > editSetSubtask) |
			(qi::lit("->") > *space > editSetDependent) |
			(space >> qi::lit("attach") > space >
				editAttachmentCommandRule(true)) |
			(space >> qi::lit("detach") > space >
				editAttachmentCommandRule(false)))
	)[qi::_val = phoenix::bind(&constructEditQuery,
		qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommand);

	editCommandRule %= (
		editCommandRuleNullary |
		editCommandRuleUnary |
		editCommandRulePriorities
	);
	BOOST_SPIRIT_DEBUG_NODE(editCommandRule);

	editCommandRuleNullary = (
		editCommandFieldsNullary
	)[qi::_val = phoenix::bind(&constructEditQueryNullary, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleNullary);

	editCommandRuleUnary = (
		editCommandFieldsUnary >
		*space > qi::lit('=') > *space >
		utilityValue)
	[qi::_val = phoenix::bind(&constructEditQueryUnary, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleUnary);

	editCommandRulePriorities = (
		qi::lit("priority") >
		*space > qi::lit('=') > *space >
		utilityTaskPriority
	)[qi::_val = phoenix::bind(&constructEditQueryPriority, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRulePriorities);

	editCommandFieldsUnary.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE);

	editCommandFieldsNullary.add
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);

	editSetSubtask = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQuerySubtask, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetSubtask);

	editSetDependent = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQueryDependent, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetDependent);

	editAttachmentCommandRule = (
		utilityLexeme
	)[qi::_val = phoenix::bind(&constructEditQueryAttachment, qi::_r1, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editAttachmentCommandRule);
	#pragma endregion

	#pragma region Deleting tasks
	deleteCommand = (
		qi::uint_
	)[qi::_val = phoenix::bind(&constructDeleteQuery, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(deleteCommand);
	#pragma endregion

	#pragma region Undoing tasks
	undoCommand = (
		qi::eps
	)[qi::_val = phoenix::construct<UNDO_QUERY>()];
	BOOST_SPIRIT_DEBUG_NODE(undoCommand);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	utilityValue = (
		(qi::int_) |
		(qi::bool_) |
		utilityTaskPriority |
		utilityLexeme
	)[qi::_val = phoenix::bind(&constructValue, qi::_1)];

	utilityTaskPriority.add
		(L"normal", TaskPriority::NORMAL)
		(L"high", TaskPriority::HIGH);

	utilityLexeme %= qi::as_wstring[(
		qi::lit('\'') > *utilityLexemeContents > qi::lit('\'')
	)];
	BOOST_SPIRIT_DEBUG_NODE(utilityLexeme);

	utilityLexemeContents %= (
		qi::lit("\\'")[qi::_val = '\''] |
		qi::lit("\\\\")[qi::_val = '\\'] |
		(ParserCharTraits::char_ - qi::lit('\''))
	);
	BOOST_SPIRIT_DEBUG_NODE(utilityLexemeContents);

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void QueryParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<commit_msg>Fixes #311.<commit_after>//@author A0097630B
#include "stdafx.h"
#include "exceptions/parse_error_exception.h"
#include "query_parser.h"

namespace You {
namespace NLP {

namespace spirit = boost::spirit;
namespace qi = spirit::qi;
namespace phoenix = boost::phoenix;

QUERY QueryParser::parse(const StringType& string) {
	QUERY result;

	if (parse(string, result)) {
		return result;
	} else {
		throw ParserException();
	}
}

bool QueryParser::parse(const StringType& string, QUERY& result) {
	return qi::parse(
		begin(string),
		end(string),
		QueryParser() > qi::eoi,
		result);
}

QueryParser::QueryParser() : QueryParser::base_type(start) {
	start %= (
		(qi::lit('/') > explicitCommand) |
		addCommand
	);
	BOOST_SPIRIT_DEBUG_NODE(start);

	explicitCommand %= (
		(qi::lit("add") > space > addCommand) |
		(qi::lit("show") > *space > showCommand) |
		(qi::lit("edit") > space > editCommand) |
		(qi::lit("delete") > space > deleteCommand) |
		(qi::lit("undo") > *space > undoCommand)
	);
	BOOST_SPIRIT_DEBUG_NODE(explicitCommand);

	#pragma region Adding tasks
	addCommand = (
		addCommandDescription >
		-(*space >> qi::lit("->") > *space > addCommand) >
		-(*space >> qi::lit(':') > *space > addCommandSubtasks)
	)[qi::_val = phoenix::bind(
		&constructAddQuery,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(addCommand);

	addCommandDescription = (
		ParserCharTraits::char_ > addCommandDescriptionTail
	)[qi::_val = phoenix::bind(
		&constructAddQueryFromDescription,
		qi::_1,
		qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescription);

	addCommandDescriptionTail %= (
		addCommandPriority |
		addCommandDescription
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandDescriptionTail);

	addCommandPriority %= (
		(-space >> qi::lit('!') >> addCommandDeadlineOptional)
			[qi::_val = phoenix::bind(&constructAddQueryWithPriority, qi::_1)] |
		addCommandDeadlineOptional
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandPriority);

	addCommandDeadline = (
		space >> (qi::lit("by") | qi::lit("before")) >> space >>
		utilityTime >> *space
	)[qi::_val = phoenix::bind(&constructAddQueryWithDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadline);

	addCommandDeadlineOptional = (
		addCommandDeadline || (
			*space >> &(qi::char_(":;") | qi::lit("->") | qi::eoi))
	)[qi::_val = phoenix::bind(&constructAddQueryWithOptionalDeadline, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(addCommandDeadlineOptional);

	addCommandSubtasks %= (
		addCommand % (*space >> qi::lit(';') >> *space)
	);
	BOOST_SPIRIT_DEBUG_NODE(addCommandSubtasks);
	#pragma endregion

	#pragma region Showing tasks
	showCommand = (
		-showCommandFiltering >
		-(-space >> (qi::lit("sorted by") | qi::lit("order by")) > space >
		showCommandSorting)
	)[qi::_val = phoenix::bind(&constructShowQuery, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommand);

	showCommandFiltering %=
		showCommandFilteringColumn % (
			(-space >> qi::lit(',') >> -space) |
			(space >> qi::lit("and") >> space));
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringColumn = (
		showCommandFields >
		-space > showCommandFilteringPredicate > -space >
		utilityValue
	)[qi::_val = phoenix::bind(&constructShowQueryFilteringColumn,
		qi::_1,
		qi::_2,
		qi::_3)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandFiltering);

	showCommandFilteringPredicate.add
		(L"=", SHOW_QUERY::Predicate::EQ)
		(L"!=", SHOW_QUERY::Predicate::NOT_EQ)
		(L"<", SHOW_QUERY::Predicate::LESS_THAN)
		(L"<=", SHOW_QUERY::Predicate::LESS_THAN_EQ)
		(L">", SHOW_QUERY::Predicate::GREATER_THAN)
		(L">=", SHOW_QUERY::Predicate::GREATER_THAN_EQ);

	showCommandSorting %= (
		showCommandSortingColumn % (
			(-space >> qi::lit(",") >> -space) |
			(space >> qi::lit("then") >> space)));
	BOOST_SPIRIT_DEBUG_NODE(showCommandSorting);

	showCommandSortingColumn = (
		showCommandFields >> -(space >> showCommandSortingOrders)
	)[qi::_val = phoenix::bind(&constructShowQuerySortColumn, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(showCommandSortingColumn);

	showCommandSortingOrders.add
		(L"asc", SHOW_QUERY::Order::ASCENDING)
		(L"ascending", SHOW_QUERY::Order::ASCENDING)
		(L"desc", SHOW_QUERY::Order::DESCENDING)
		(L"descending", SHOW_QUERY::Order::DESCENDING);

	showCommandFields.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE)
		(L"priority", TaskField::PRIORITY)
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);
	#pragma endregion

	#pragma region Editing tasks
	editCommand = (
		qi::uint_ > (
			(space >> qi::lit("set") > space > editCommandRule) |
			(*space >> qi::lit(":") > *space > editSetSubtask) |
			(*space >> qi::lit("->") > *space > editSetDependent) |
			(space >> qi::lit("attach") > space >
				editAttachmentCommandRule(true)) |
			(space >> qi::lit("detach") > space >
				editAttachmentCommandRule(false)))
	)[qi::_val = phoenix::bind(&constructEditQuery,
		qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommand);

	editCommandRule %= (
		editCommandRuleNullary |
		editCommandRuleUnary |
		editCommandRulePriorities
	);
	BOOST_SPIRIT_DEBUG_NODE(editCommandRule);

	editCommandRuleNullary = (
		editCommandFieldsNullary
	)[qi::_val = phoenix::bind(&constructEditQueryNullary, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleNullary);

	editCommandRuleUnary = (
		editCommandFieldsUnary >
		*space > qi::lit('=') > *space >
		utilityValue)
	[qi::_val = phoenix::bind(&constructEditQueryUnary, qi::_1, qi::_2)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRuleUnary);

	editCommandRulePriorities = (
		qi::lit("priority") >
		*space > qi::lit('=') > *space >
		utilityTaskPriority
	)[qi::_val = phoenix::bind(&constructEditQueryPriority, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editCommandRulePriorities);

	editCommandFieldsUnary.add
		(L"description", TaskField::DESCRIPTION)
		(L"deadline", TaskField::DEADLINE);

	editCommandFieldsNullary.add
		(L"done", TaskField::COMPLETE)
		(L"complete", TaskField::COMPLETE);

	editSetSubtask = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQuerySubtask, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetSubtask);

	editSetDependent = (
		qi::int_
	)[qi::_val = phoenix::bind(&constructEditQueryDependent, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editSetDependent);

	editAttachmentCommandRule = (
		utilityLexeme
	)[qi::_val = phoenix::bind(&constructEditQueryAttachment, qi::_r1, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(editAttachmentCommandRule);
	#pragma endregion

	#pragma region Deleting tasks
	deleteCommand = (
		qi::uint_
	)[qi::_val = phoenix::bind(&constructDeleteQuery, qi::_1)];
	BOOST_SPIRIT_DEBUG_NODE(deleteCommand);
	#pragma endregion

	#pragma region Undoing tasks
	undoCommand = (
		qi::eps
	)[qi::_val = phoenix::construct<UNDO_QUERY>()];
	BOOST_SPIRIT_DEBUG_NODE(undoCommand);
	#pragma endregion

	space = qi::omit[+ParserCharTraits::blank];

	utilityValue = (
		(qi::int_) |
		(qi::bool_) |
		utilityTaskPriority |
		utilityLexeme
	)[qi::_val = phoenix::bind(&constructValue, qi::_1)];

	utilityTaskPriority.add
		(L"normal", TaskPriority::NORMAL)
		(L"high", TaskPriority::HIGH);

	utilityLexeme %= qi::as_wstring[(
		qi::lit('\'') > *utilityLexemeContents > qi::lit('\'')
	)];
	BOOST_SPIRIT_DEBUG_NODE(utilityLexeme);

	utilityLexemeContents %= (
		qi::lit("\\'")[qi::_val = '\''] |
		qi::lit("\\\\")[qi::_val = '\\'] |
		(ParserCharTraits::char_ - qi::lit('\''))
	);
	BOOST_SPIRIT_DEBUG_NODE(utilityLexemeContents);

	qi::on_error<qi::fail>(start,
		phoenix::bind(&onFailure, qi::_1, qi::_2, qi::_3, qi::_4));
}

void QueryParser::onFailure(
	ParserIteratorType /*begin*/,
	ParserIteratorType end,
	ParserIteratorType errorPos,
	const spirit::info& message) {
	StringType lexeme(errorPos, end);
	throw ParseErrorException(message, lexeme);
}

}  // namespace NLP
}  // namespace You
<|endoftext|>


<commit_before>/*

    .. hwt-schematic::

*/

#include <systemc.h>

SC_MODULE(FsmExample) {
    //interfaces
    sc_in<sc_uint<1>> a;
    sc_in<sc_uint<1>> b;
    sc_in_clk clk;
    sc_out<sc_uint<3>> dout;
    sc_in<sc_uint<1>> rst_n;

    //internal signals
    sc_uint<2> st = 0;
    sc_signal<sc_uint<2>> st_next;

    //processes inside this component
    void assig_process_dout() {
        switch(st) {
        case 0:
            dout.write(sc_uint<3>("001"));
            break;
        case 1:
            dout.write(sc_uint<3>("010"));
            break;
        default:
            dout.write(sc_uint<3>("011"));
            break;
        }
    }
    void assig_process_st() {
        if (rst_n.read() == 0) {
            st = 0;
        } else {
            st = st_next.read();
        }
    }
    void assig_process_st_next() {
        switch(st) {
        case 0:
            if ((a.read() & b.read()) == 1) {
                st_next.write(2);
            } else if (b.read() == 1) {
                st_next.write(1);
            } else {
                st_next.write(st);
            }
            break;
        case 1:
            if ((a.read() & b.read()) == 1) {
                st_next.write(2);
            } else if (a.read() == 1) {
                st_next.write(0);
            } else {
                st_next.write(st);
            }
            break;
        default:
            if ((a.read() & ~b.read()) == 1) {
                st_next.write(0);
            } else if ((~a.read() & b.read()) == 1) {
                st_next.write(1);
            } else {
                st_next.write(st);
            }
            break;
        }
    }

    SC_CTOR(FsmExample) {
        SC_METHOD(assig_process_dout);
        sensitive << st;
        SC_METHOD(assig_process_st);
        sensitive << clk.pos();
        SC_METHOD(assig_process_st_next);
        sensitive << a << b << st;
    }
};
<commit_msg>update systemc examples<commit_after>#include <systemc.h>

//
//    .. hwt-schematic::
//
SC_MODULE(FsmExample) {
    // ports
    sc_in<sc_uint<1>> a;
    sc_in<sc_uint<1>> b;
    sc_in_clk clk;
    sc_out<sc_uint<3>> dout;
    sc_in<sc_uint<1>> rst_n;
    // component instances
    // internal signals
    sc_uint<2> st(0);
    sc_signal<sc_uint<2>> st_next;
    void assig_process_dout() {
        switch(st) {
        case 0: {
                dout.write(sc_uint<3>(0b001));
                break;
            }
        case 1: {
                dout.write(sc_uint<3>(0b010));
                break;
            }
        default:
                dout.write(sc_uint<3>(0b011));
        }
    }

    void assig_process_st() {
        if (rst_n.read() == sc_uint<1>(0b0))
            st = 0;
        else
            st = st_next.read();
    }

    void assig_process_st_next() {
        switch(st) {
        case 0: {
                if ((a.read() & b.read()) == sc_uint<1>(0b1))
                    st_next.write(2);
                else if (b.read() == sc_uint<1>(0b1))
                    st_next.write(1);
                else
                    st_next.write(st);
                break;
            }
        case 1: {
                if ((a.read() & b.read()) == sc_uint<1>(0b1))
                    st_next.write(2);
                else if (a.read() == sc_uint<1>(0b1))
                    st_next.write(0);
                else
                    st_next.write(st);
                break;
            }
        default:
                if ((a.read() & ~(b.read())) == sc_uint<1>(0b1))
                    st_next.write(0);
                else if ((~(a.read()) & b.read()) == sc_uint<1>(0b1))
                    st_next.write(1);
                else
                    st_next.write(st);
        }
    }

    SC_CTOR(FsmExample) {
        SC_METHOD(assig_process_dout);
        sensitive << st;
        SC_METHOD(assig_process_st);
        sensitive << clk.pos();
        SC_METHOD(assig_process_st_next);
        sensitive << a << b << st;
    }
};
<|endoftext|>


<commit_before>#include <cmath>

#include <vector>
#include <algorithm>

#include "Python.h"
#include "numpy/arrayobject.h"

#include "kdtree.h"
#include "geometry.h"

typedef geometry::Point<double, 3> Point;

static char module_docstring[] = "Discrete natural neighbor interpolation in 3D.";

static char griddata_docstring[] = "Calculate the natural neighbor interpolation of a dataset.";

static PyObject* cnaturalneighbor_griddata(PyObject* self, PyObject* args);

static PyMethodDef module_methods[] = {
    {"griddata", cnaturalneighbor_griddata, METH_VARARGS, griddata_docstring},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
   PyModuleDef_HEAD_INIT,
   "cnaturalneighbor",
   module_docstring,
   -1,  // TODO: investigate whether we can support sub-interpreters
   module_methods
};

PyMODINIT_FUNC PyInit_cnaturalneighbor(void) {
    PyObject* m = PyModule_Create(&module);
    if (m == NULL) {
        return NULL;
    }

    import_array();  // Enable numpy functionality
    return m;
}

std::size_t clamp(std::size_t val, std::size_t min, std::size_t max) {
    if (val < min) {
        return min;
    } else if (val > max) {
        return max;
    } else {
        return val;
    }
}

static PyObject* cnaturalneighbor_griddata(PyObject* self, PyObject* args) {
    PyArrayObject *known_coords, *known_values, *interp_values;

    if (!PyArg_ParseTuple(args, "O!O!O!",
                &PyArray_Type, &known_coords,
                &PyArray_Type, &known_values,
                &PyArray_Type, &interp_values)) {
        return NULL;
    }

    npy_intp* known_coordinates_dims = PyArray_DIMS(known_coords);
    npy_intp* interp_values_shape = PyArray_DIMS(interp_values);
    double* interp_values_ptr = (double*)PyArray_GETPTR1(interp_values, 0);

    std::size_t num_known_points = known_coordinates_dims[0];

    // TODO: think of a way to avoid using these intermediate vectors
    auto known_coords_vec = new std::vector<Point>(num_known_points);
    auto known_values_vec = new std::vector<double>(num_known_points);

    for (std::size_t i = 0; i < num_known_points; i++) {
        (*known_coords_vec)[i] = Point(
                *(double*)PyArray_GETPTR2(known_coords, i, 0),
                *(double*)PyArray_GETPTR2(known_coords, i, 1),
                *(double*)PyArray_GETPTR2(known_coords, i, 2));

        (*known_values_vec)[i] = *(double*)PyArray_GETPTR1(known_values, i);
    }

    kdtree::kdtree<double> *tree = new kdtree::kdtree<double>();
    for (std::size_t i = 0; i < num_known_points; i++) {
        tree->add(&(*known_coords_vec)[i], &(*known_values_vec)[i]);
    }
    tree->build();

    std::size_t ni = interp_values_shape[0];
    std::size_t nj = interp_values_shape[1];
    std::size_t nk = interp_values_shape[2];

    auto contribution_counter = new double[ni*nj*nk];

    for (std::size_t i = 0; i < ni; i++) {
        for (std::size_t j = 0; j < nj; j++) {
            for (std::size_t k = 0; k < nk; k++) {
                auto query_point = Point(i, j, k);
                auto nearest_known_point = tree->nearest_iterative(query_point);

                double distance_sq_query_to_known = nearest_known_point->distance;
                int roi_radius = ceil(sqrt(distance_sq_query_to_known));

                auto i_roi_min = clamp(i - roi_radius, 0, ni - 1);
                auto i_roi_max = clamp(i + roi_radius, 0, ni - 1);
                auto j_roi_min = clamp(j - roi_radius, 0, nj - 1);
                auto j_roi_max = clamp(j + roi_radius, 0, nj - 1);
                auto k_roi_min = clamp(k - roi_radius, 0, nk - 1);
                auto k_roi_max = clamp(k + roi_radius, 0, nk - 1);

                for (std::size_t i_roi = i_roi_min; i_roi <= i_roi_max; i_roi++) {
                    for (std::size_t j_roi = j_roi_min; j_roi <= j_roi_max; j_roi++) {
                        for (std::size_t k_roi = k_roi_min; k_roi <= k_roi_max; k_roi++) {
                            double deltai_2 = (i - i_roi)*(i - i_roi);
                            double deltaj_2 = (j - j_roi)*(j - j_roi);
                            double deltak_2 = (k - k_roi)*(k - k_roi);
                            double distance_sq_roi_to_known = deltai_2 + deltaj_2 + deltak_2;

                            if (distance_sq_roi_to_known <= distance_sq_query_to_known) {
                                std::size_t indice = nj*nk*i + nk*j + k;
                                interp_values_ptr[indice] += nearest_known_point->value;
                                contribution_counter[indice] += 1;
                            }
                        }
                    }
                }
            }
        }
    }

    for (std::size_t i = 0; i < ni; i++) {
        for (std::size_t j = 0; j < nj; j++) {
            for (std::size_t k = 0; k < nk; k++) {
                auto indice = nj*nk*i + nk*j + k;
                if (contribution_counter[indice] != 0) {
                    interp_values_ptr[indice] /= contribution_counter[indice];
                }
            }
        }
    }

    delete contribution_counter;
    delete tree;
    delete known_coords_vec;
    delete known_values_vec;

    Py_RETURN_NONE;
}
<commit_msg>Remove unnecessary TODO<commit_after>#include <cmath>

#include <vector>
#include <algorithm>

#include "Python.h"
#include "numpy/arrayobject.h"

#include "kdtree.h"
#include "geometry.h"

typedef geometry::Point<double, 3> Point;

static char module_docstring[] = "Discrete natural neighbor interpolation in 3D.";

static char griddata_docstring[] = "Calculate the natural neighbor interpolation of a dataset.";

static PyObject* cnaturalneighbor_griddata(PyObject* self, PyObject* args);

static PyMethodDef module_methods[] = {
    {"griddata", cnaturalneighbor_griddata, METH_VARARGS, griddata_docstring},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef module = {
   PyModuleDef_HEAD_INIT,
   "cnaturalneighbor",
   module_docstring,
   -1,
   module_methods
};

PyMODINIT_FUNC PyInit_cnaturalneighbor(void) {
    PyObject* m = PyModule_Create(&module);
    if (m == NULL) {
        return NULL;
    }

    import_array();  // Enable numpy functionality
    return m;
}

std::size_t clamp(std::size_t val, std::size_t min, std::size_t max) {
    if (val < min) {
        return min;
    } else if (val > max) {
        return max;
    } else {
        return val;
    }
}

static PyObject* cnaturalneighbor_griddata(PyObject* self, PyObject* args) {
    PyArrayObject *known_coords, *known_values, *interp_values;

    if (!PyArg_ParseTuple(args, "O!O!O!",
                &PyArray_Type, &known_coords,
                &PyArray_Type, &known_values,
                &PyArray_Type, &interp_values)) {
        return NULL;
    }

    npy_intp* known_coordinates_dims = PyArray_DIMS(known_coords);
    npy_intp* interp_values_shape = PyArray_DIMS(interp_values);
    double* interp_values_ptr = (double*)PyArray_GETPTR1(interp_values, 0);

    std::size_t num_known_points = known_coordinates_dims[0];

    // TODO: think of a way to avoid using these intermediate vectors
    auto known_coords_vec = new std::vector<Point>(num_known_points);
    auto known_values_vec = new std::vector<double>(num_known_points);

    for (std::size_t i = 0; i < num_known_points; i++) {
        (*known_coords_vec)[i] = Point(
                *(double*)PyArray_GETPTR2(known_coords, i, 0),
                *(double*)PyArray_GETPTR2(known_coords, i, 1),
                *(double*)PyArray_GETPTR2(known_coords, i, 2));

        (*known_values_vec)[i] = *(double*)PyArray_GETPTR1(known_values, i);
    }

    kdtree::kdtree<double> *tree = new kdtree::kdtree<double>();
    for (std::size_t i = 0; i < num_known_points; i++) {
        tree->add(&(*known_coords_vec)[i], &(*known_values_vec)[i]);
    }
    tree->build();

    std::size_t ni = interp_values_shape[0];
    std::size_t nj = interp_values_shape[1];
    std::size_t nk = interp_values_shape[2];

    auto contribution_counter = new double[ni*nj*nk];

    for (std::size_t i = 0; i < ni; i++) {
        for (std::size_t j = 0; j < nj; j++) {
            for (std::size_t k = 0; k < nk; k++) {
                auto query_point = Point(i, j, k);
                auto nearest_known_point = tree->nearest_iterative(query_point);

                double distance_sq_query_to_known = nearest_known_point->distance;
                int roi_radius = ceil(sqrt(distance_sq_query_to_known));

                auto i_roi_min = clamp(i - roi_radius, 0, ni - 1);
                auto i_roi_max = clamp(i + roi_radius, 0, ni - 1);
                auto j_roi_min = clamp(j - roi_radius, 0, nj - 1);
                auto j_roi_max = clamp(j + roi_radius, 0, nj - 1);
                auto k_roi_min = clamp(k - roi_radius, 0, nk - 1);
                auto k_roi_max = clamp(k + roi_radius, 0, nk - 1);

                for (std::size_t i_roi = i_roi_min; i_roi <= i_roi_max; i_roi++) {
                    for (std::size_t j_roi = j_roi_min; j_roi <= j_roi_max; j_roi++) {
                        for (std::size_t k_roi = k_roi_min; k_roi <= k_roi_max; k_roi++) {
                            double deltai_2 = (i - i_roi)*(i - i_roi);
                            double deltaj_2 = (j - j_roi)*(j - j_roi);
                            double deltak_2 = (k - k_roi)*(k - k_roi);
                            double distance_sq_roi_to_known = deltai_2 + deltaj_2 + deltak_2;

                            if (distance_sq_roi_to_known <= distance_sq_query_to_known) {
                                std::size_t indice = nj*nk*i + nk*j + k;
                                interp_values_ptr[indice] += nearest_known_point->value;
                                contribution_counter[indice] += 1;
                            }
                        }
                    }
                }
            }
        }
    }

    for (std::size_t i = 0; i < ni; i++) {
        for (std::size_t j = 0; j < nj; j++) {
            for (std::size_t k = 0; k < nk; k++) {
                auto indice = nj*nk*i + nk*j + k;
                if (contribution_counter[indice] != 0) {
                    interp_values_ptr[indice] /= contribution_counter[indice];
                }
            }
        }
    }

    delete contribution_counter;
    delete tree;
    delete known_coords_vec;
    delete known_values_vec;

    Py_RETURN_NONE;
}
<|endoftext|>


<commit_before>#include<fstream>
#include<iostream>
#include<sstream>
#include<iomanip>
#include<string.h>
using namespace std;

struct Aluno {
    string nome;
    int matricula;
    float media;
    char aprovado; // A-Aprovado, R-Reprovado
    bool existe;

    static const int nome_size = 20;

    Aluno(){
        nome = "null";
        matricula = 0;
        media = 0.0;
        aprovado = 'R';
        existe = true;
    }

    //formata a string pra ela ter exatos size chars
    //se for maior, corta
    //se for menor, completa
    string format(string str, int size){
        if((int) str.size() > size)
            return str.substr(0, size);
        stringstream ss;
        ss << setw(size) << str;
        return ss.str();
    }

    string get_string(){
        stringstream ss;
        ss << format(nome, nome_size) << setw(10) << matricula << setw(10) << media
            << setw(2) << aprovado << setw(2) << existe << '\n';
        return ss.str();
    }

    size_t size(){
        return this->get_string().size();
    }

    bool write(fstream &ofs){
        string str = get_string();
        ofs << str.c_str();
        return ofs.good();
    }

    bool read(fstream &ifs){
        int size = get_string().size();
        char *linha = new char[size];
        ifs.read(linha, size);
        stringstream(linha) >> nome >> matricula >> media >> aprovado >> existe;
        return ifs.good();
    }

    static Aluno ler_do_teclado(){
        Aluno aluno;
        while(true){
            cout << "Nome Matricula Media" << endl;
            cin >> aluno.nome >> aluno.matricula >> aluno.media;

            if(cin.fail()){
                cin.clear();
                cin.ignore(1000, '\n');
            }else{
                break;
            }
        }
        if(aluno.media >= 7.0)
            aluno.aprovado = 'A';
        else
            aluno.aprovado = 'R';
        return aluno;
    }

    void show(int ind = -1){
        if(ind != -1)
            cout << ind << " ";
        cout << "Nome: " << setw(nome_size) <<  nome
            << " Mat: " << matricula
            << " Media: " << media
            << " Situacao: " << aprovado << endl;
    }
};

struct Registro{
    string path;

    Registro(string path){
        this->path = path;
    }

    //adiciona um registro
    void add() {
        Aluno aluno =  Aluno::ler_do_teclado();
        fstream file(path.c_str(), ios::out | ios::in | ios::app);
        aluno.write(file);
    }

    //mostra os registros validos
    void show() {
        fstream file(path.c_str(), ios::in);
        if(file.fail() || this->qtd() == 0)
            return;
        Aluno aluno;
        int ind = 0;
        while(aluno.read(file)) {
            if(aluno.existe)
                aluno.show(ind);
            ind++;
        }
    }

    //mostra um registro pelo indice
    void show(int ind) {
        Aluno aluno;
        if(ind < 0 or ind >= qtd())
            return;
        fstream file(path.c_str(), ios::in);
        file.seekg(ind * aluno.size());
        aluno.read(file);
        aluno.show(ind);
    }

    //informa quantos registro existem, contando válidos e invalidos
    int qtd(){
        fstream file(path.c_str(), ios::in);
        if(file.fail())
            return 0;
        file.seekg(0, ios::end);
        int pos = file.tellg();
        Aluno alu;
        return pos/alu.size();
    }

    //altera um registro
    void change(int ind) {
        Aluno aluno = Aluno::ler_do_teclado();
        fstream file(path.c_str(),  ios::in | ios::out);
        if(ind >= 0 && ind < qtd()){
            file.seekp(ind * aluno.size());
            aluno.write(file);
        }
    }

    //remove um registro setando existe pra falso
    void remove(int ind) {
        fstream file(path.c_str(), ios::in | ios::out);
        Aluno aluno;
        if(ind >= 0 && ind < qtd()){
            file.seekg(ind * aluno.size());
            aluno.read(file);
            aluno.existe = false;
            file.seekp(-aluno.size(), ios::cur);
            aluno.write(file);
        }
    }

    //apaga o arquivo todo
    void del() {
        fstream file(path.c_str(), ios::out | ios::trunc);
    }

    void show_help(){
        cout << endl
            << "\tH   -  Help   - mostra esse help" << endl
            << "\tS   -  Show   - mostra todos" << endl
            << "\tA   -  Add    - adiciona um novo aluno" << endl
            << "\tD   -  Del    - deleta a lista toda" << endl
            << "\tQ   -  Qtd    - informa quantidade" << endl
            << "\tO n -  One    - mostra o aluno indice n" << endl
            << "\tC n -  Change - altera o aluno indice n" << endl
            << "\tR n -  Remove - apaga o aluno indice n" << endl
            << "\tX   -  eXit   - termina o programa" << endl << endl;
    }

    int getInt(){
        int pos;
        while(true){
            cin >> pos;
            if(cin.fail()){
                cin.clear();
                cin.ignore(1000, '\n');
                cout << "Digite um numero" << endl;
            }else{
                break;
            }
        }
        return pos;
    }

    void menu(){
        char op = ' ';
        show_help();
        while(op != 'X'){
            string nome;
            cout << ">> ";
            cin >> op;
            switch(op) {
                case 'H': show_help(); break;
                case 'D': del(); break;
                case 'A': add(); break;
                case 'S': show(); break;
                case 'Q': cout << qtd() << endl; break;
                case 'C': change(getInt()); break;
                case 'O': show(getInt()); break;
                case 'R': remove(getInt()); break;
                case 'X': break;
                default :
                          cout << "Comando inválido" << endl;
            }
        }
    }
};

int main () {
    Registro registro("registro.txt");

    registro.menu();
    return 0;
}
<commit_msg>registro<commit_after>#include<fstream>
#include<iostream>
#include<sstream>
#include<iomanip>
#include<string.h>
using namespace std;

template <class T>
T get_valor(string msg = ""){
    T valor;
    while(true){
        cout << msg << endl;
        cin >> valor;
        if(cin.fail()){
            cin.clear();
            cin.ignore(1000, '\n');
            continue;
        }
        return valor;
    }
}

struct Aluno {
    string nome;
    int matricula;
    float media;
    char aprovado; // A-Aprovado, R-Reprovado
    bool existe;

    static const int nome_size = 20;

    Aluno(){
        nome = "null";
        matricula = 0;
        media = 0.0;
        aprovado = 'R';
        existe = true;
    }

    //formata a string pra ela ter exatos size chars
    //se for maior, corta
    //se for menor, completa
    string format(string str, int size){
        if((int) str.size() > size)
            return str.substr(0, size);
        stringstream ss;
        ss << setw(size) << str;
        return ss.str();
    }

    string get_string(){
        stringstream ss;
        ss << format(nome, nome_size) << setw(10) << matricula << setw(10) << media
            << setw(2) << aprovado << setw(2) << existe << '\n';
        return ss.str();
    }

    size_t size(){
        return this->get_string().size();
    }

    bool write(fstream &ofs){
        string str = get_string();
        ofs << str.c_str();
        return ofs.good();
    }

    bool read(fstream &ifs){
        int size = get_string().size();
        char *linha = new char[size];
        ifs.read(linha, size);
        stringstream(linha) >> nome >> matricula >> media >> aprovado >> existe;
        return ifs.good();
    }

    static Aluno ler_do_teclado(){
        Aluno aluno;
        while(true){
            cout << "Nome Matricula Media" << endl;
            cin >> aluno.nome >> aluno.matricula >> aluno.media;

            if(cin.fail()){
                cin.clear();
                cin.ignore(1000, '\n');
            }else{
                break;
            }
        }
        if(aluno.media >= 7.0)
            aluno.aprovado = 'A';
        else
            aluno.aprovado = 'R';
        return aluno;
    }

    void show(int ind = -1){
        if(ind != -1)
            cout << ind << " ";
        cout << "Nome: " << setw(nome_size) <<  nome
            << " Mat: " << matricula
            << " Media: " << media
            << " Situacao: " << aprovado << endl;
    }
};

struct Registro{
    string path;

    Registro(string path){
        this->path = path;
    }

    //adiciona um registro
    void add() {
        Aluno aluno =  Aluno::ler_do_teclado();
        fstream file(path.c_str(), ios::out | ios::in | ios::app);
        aluno.write(file);
    }

    //mostra os registros validos
    void show() {
        fstream file(path.c_str(), ios::in);
        if(file.fail() || this->qtd() == 0)
            return;
        Aluno aluno;
        int ind = 0;
        while(aluno.read(file)) {
            if(aluno.existe)
                aluno.show(ind);
            ind++;
        }
    }

    //mostra um registro pelo indice
    void show(int ind) {
        Aluno aluno;
        if(ind < 0 or ind >= qtd())
            return;
        fstream file(path.c_str(), ios::in);
        file.seekg(ind * aluno.size());
        aluno.read(file);
        aluno.show(ind);
    }

    //informa quantos registro existem, contando válidos e invalidos
    int qtd(){
        fstream file(path.c_str(), ios::in);
        if(file.fail())
            return 0;
        file.seekg(0, ios::end);
        int pos = file.tellg();
        Aluno alu;
        return pos/alu.size();
    }

    //altera um registro
    void change(int ind) {
        Aluno aluno = Aluno::ler_do_teclado();
        fstream file(path.c_str(),  ios::in | ios::out);
        if(ind >= 0 && ind < qtd()){
            file.seekp(ind * aluno.size());
            aluno.write(file);
        }
    }

    //remove um registro setando existe pra falso
    void remove(int ind) {
        fstream file(path.c_str(), ios::in | ios::out);
        Aluno aluno;
        if(ind >= 0 && ind < qtd()){
            file.seekg(ind * aluno.size());
            aluno.read(file);
            aluno.existe = false;
            file.seekp(-aluno.size(), ios::cur);
            aluno.write(file);
        }
    }

    //apaga o arquivo todo
    void del() {
        fstream file(path.c_str(), ios::out | ios::trunc);
    }

    void show_help(){
        cout << endl
            << "\tH   -  Help   - mostra esse help" << endl
            << "\tS   -  Show   - mostra todos" << endl
            << "\tA   -  Add    - adiciona um novo aluno" << endl
            << "\tD   -  Del    - deleta a lista toda" << endl
            << "\tQ   -  Qtd    - informa quantidade" << endl
            << "\tO n -  One    - mostra o aluno indice n" << endl
            << "\tC n -  Change - altera o aluno indice n" << endl
            << "\tR n -  Remove - apaga o aluno indice n" << endl
            << "\tX   -  eXit   - termina o programa" << endl << endl;
    }

    void menu(){
        char op = ' ';
        show_help();
        while(op != 'X'){
            string nome;
            cout << ">> ";
            cin >> op;
            switch(op) {
                case 'H': show_help(); break;
                case 'D': del(); break;
                case 'A': add(); break;
                case 'S': show(); break;
                case 'Q': cout << qtd() << endl; break;
                case 'C': change(get_valor<int>("Indice ")); break;
                case 'O': show(get_valor<int>("Indice ")); break;
                case 'R': remove(get_valor<int>("Indice ")); break;
                case 'X': break;
                default :
                          cout << "Comando inválido" << endl;
            }
        }
    }
};

int main () {
    Registro registro("registro.txt");

    registro.menu();
    return 0;
}
<|endoftext|>


<commit_before>/*
 * ty, a collection of GUI and command-line tools to manage Teensy devices
 *
 * Distributed under the MIT license (see LICENSE.txt or http://opensource.org/licenses/MIT)
 * Copyright (c) 2015 Niels Martignène <niels.martignene@gmail.com>
 */

#include <QApplication>
#include <QMessageBox>
#include <QTranslator>

#include "hs/common.h"
#include "ty/common.h"
#include "tyqt/log_dialog.hpp"
#include "tyqt/monitor.hpp"
#include "updater_window.hpp"
#include "upty.hpp"

#ifdef QT_STATIC
    #include <QtPlugin>
    #if defined(_WIN32)
        Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
    #elif defined(__APPLE__)
        Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
    #endif
#endif

using namespace std;

UpTy::UpTy(int &argc, char *argv[])
    : QApplication(argc, argv)
{
    setOrganizationName("ty");
    setApplicationName(TY_CONFIG_UPTY_NAME);
    setApplicationVersion(ty_version_string());

    ty_message_redirect([](ty_task *task, ty_message_type type, const void *data, void *udata) {
        ty_message_default_handler(task, type, data, udata);

        if (type == TY_MESSAGE_LOG) {
            auto print = static_cast<const ty_log_message *>(data);
            if (print->level <= TY_LOG_WARNING) {
                upTy->reportError(print->msg);
            } else {
                upTy->reportDebug(print->msg);
            }
        }
    }, nullptr);

    log_dialog_ = unique_ptr<LogDialog>(new LogDialog());
    log_dialog_->setAttribute(Qt::WA_QuitOnClose, false);
    log_dialog_->setWindowIcon(QIcon(":/upty"));
    connect(this, &UpTy::globalError, log_dialog_.get(), &LogDialog::appendError);
    connect(this, &UpTy::globalDebug, log_dialog_.get(), &LogDialog::appendDebug);
}

UpTy::~UpTy()
{
    ty_message_redirect(ty_message_default_handler, nullptr);
}

void UpTy::showLogWindow()
{
    log_dialog_->show();
}

void UpTy::reportError(const QString &msg)
{
    emit globalError(msg);
}

void UpTy::reportDebug(const QString &msg)
{
    emit globalDebug(msg);
}

int UpTy::exec()
{
    return upTy->run();
}

int UpTy::run()
{
    monitor_.reset(new Monitor());
    if (!monitor_->start()) {
        QMessageBox::critical(nullptr, tr("%1 (error)").arg(applicationName()),
                              ty_error_last_message());
        return EXIT_FAILURE;
    }

    UpdaterWindow win;
    win.show();

    return QApplication::exec();
}

int main(int argc, char *argv[])
{
    hs_log_set_handler(ty_libhs_log_handler, NULL);

    // FIXME: move to libtyqt function
    Q_INIT_RESOURCE(libtyqt);
    qRegisterMetaType<ty_log_level>("ty_log_level");
    qRegisterMetaType<std::shared_ptr<void>>("std::shared_ptr<void>");
    qRegisterMetaType<ty_descriptor>("ty_descriptor");

    UpTy app(argc, argv);
    return app.exec();
}
<commit_msg>Disable unused serial connection in UpTy<commit_after>/*
 * ty, a collection of GUI and command-line tools to manage Teensy devices
 *
 * Distributed under the MIT license (see LICENSE.txt or http://opensource.org/licenses/MIT)
 * Copyright (c) 2015 Niels Martignène <niels.martignene@gmail.com>
 */

#include <QApplication>
#include <QMessageBox>
#include <QTranslator>

#include "hs/common.h"
#include "ty/common.h"
#include "tyqt/log_dialog.hpp"
#include "tyqt/monitor.hpp"
#include "updater_window.hpp"
#include "upty.hpp"

#ifdef QT_STATIC
    #include <QtPlugin>
    #if defined(_WIN32)
        Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
    #elif defined(__APPLE__)
        Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)
    #endif
#endif

using namespace std;

UpTy::UpTy(int &argc, char *argv[])
    : QApplication(argc, argv)
{
    setOrganizationName("ty");
    setApplicationName(TY_CONFIG_UPTY_NAME);
    setApplicationVersion(ty_version_string());

    ty_message_redirect([](ty_task *task, ty_message_type type, const void *data, void *udata) {
        ty_message_default_handler(task, type, data, udata);

        if (type == TY_MESSAGE_LOG) {
            auto print = static_cast<const ty_log_message *>(data);
            if (print->level <= TY_LOG_WARNING) {
                upTy->reportError(print->msg);
            } else {
                upTy->reportDebug(print->msg);
            }
        }
    }, nullptr);

    log_dialog_ = unique_ptr<LogDialog>(new LogDialog());
    log_dialog_->setAttribute(Qt::WA_QuitOnClose, false);
    log_dialog_->setWindowIcon(QIcon(":/upty"));
    connect(this, &UpTy::globalError, log_dialog_.get(), &LogDialog::appendError);
    connect(this, &UpTy::globalDebug, log_dialog_.get(), &LogDialog::appendDebug);
}

UpTy::~UpTy()
{
    ty_message_redirect(ty_message_default_handler, nullptr);
}

void UpTy::showLogWindow()
{
    log_dialog_->show();
}

void UpTy::reportError(const QString &msg)
{
    emit globalError(msg);
}

void UpTy::reportDebug(const QString &msg)
{
    emit globalDebug(msg);
}

int UpTy::exec()
{
    return upTy->run();
}

int UpTy::run()
{
    monitor_.reset(new Monitor());
    monitor_->setSerialByDefault(false);
    if (!monitor_->start()) {
        QMessageBox::critical(nullptr, tr("%1 (error)").arg(applicationName()),
                              ty_error_last_message());
        return EXIT_FAILURE;
    }

    UpdaterWindow win;
    win.show();

    return QApplication::exec();
}

int main(int argc, char *argv[])
{
    hs_log_set_handler(ty_libhs_log_handler, NULL);

    // FIXME: move to libtyqt function
    Q_INIT_RESOURCE(libtyqt);
    qRegisterMetaType<ty_log_level>("ty_log_level");
    qRegisterMetaType<std::shared_ptr<void>>("std::shared_ptr<void>");
    qRegisterMetaType<ty_descriptor>("ty_descriptor");

    UpTy app(argc, argv);
    return app.exec();
}
<|endoftext|>