<commit_before>/*
Copyright (c) 2009 Sony Pictures Imageworks, et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT
OWNER 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 "oslops.h"
#include "oslexec_pvt.h"

#include "OpenImageIO/sysutil.h"

#ifdef OSL_NAMESPACE
namespace OSL_NAMESPACE {
#endif
namespace OSL {
namespace pvt {

namespace {  // anonymous

inline TextureOptions::Wrap
decode_wrap (ustring w)
{
    if (w == Strings::black)
        return TextureOptions::WrapBlack;
    if (w == Strings::clamp)
        return TextureOptions::WrapClamp;
    if (w == Strings::periodic)
        return TextureOptions::WrapPeriodic;
    if (w == Strings::mirror)
        return TextureOptions::WrapMirror;
    return TextureOptions::WrapDefault;
}

};  // end anonymous namespace

DECLOP (OP_texture)
{
    // Grab the required arguments: result, filename, s, t
    DASSERT (nargs >= 4);
    Symbol &Result (exec->sym (args[0]));
    Symbol &Filename (exec->sym (args[1]));
    DASSERT (Filename.typespec().is_string());
    Symbol &S (exec->sym (args[2]));
    Symbol &T (exec->sym (args[3]));
    DASSERT (S.typespec().is_float() && T.typespec().is_float());

    // Adjust the result's uniform/varying status
    exec->adjust_varying (Result, true /* Assume texture always varies */);

    // FIXME -- we should allow derivs of texture
    if (Result.has_derivs ())
        exec->zero_derivs (Result);

    float zero = 0.0f;
    VaryingRef<float> result ((float *)Result.data(), Result.step());
    VaryingRef<float> s ((float *)S.data(), S.step());
    VaryingRef<float> t ((float *)T.data(), T.step());
    VaryingRef<ustring> filename ((ustring *)Filename.data(), Filename.step());
    VaryingRef<ustring> swrap (NULL), twrap (NULL);
    VaryingRef<int> firstchannel (NULL);
    VaryingRef<float> alpha (NULL);

    TextureSystem *texturesys = exec->texturesys ();
    TextureOptions options;
    options.firstchannel = 0;
    options.nchannels = Result.typespec().simpletype().aggregate;
    options.fill.init (&zero);

    // Set up derivs
    VaryingRef<float> dsdx, dsdy, dtdx, dtdy;
    if (S.has_derivs()) {
        dsdx.init ((float *)S.data() + 1, S.step());
        dsdy.init ((float *)S.data() + 2, S.step());
    } else {
        dsdx.init (&zero);
        dsdy.init (&zero);
    }
    if (T.has_derivs()) {
        dtdx.init ((float *)T.data() + 1, T.step());
        dtdy.init ((float *)T.data() + 2, T.step());
    } else {
        dtdx.init (&zero);
        dtdy.init (&zero);
    }

    // Parse all the optional arguments
    for (int a = 4;  a < nargs;  ++a) {
        Symbol &Name (exec->sym (args[a]));
        DASSERT (Name.typespec().is_string() &&
                 "optional texture token must be a string");
        DASSERT (a+1 < nargs && "malformed argument list for texture");
        if (Name.is_varying()) {
            exec->warning ("optional texture argument is a varying string! Seems pretty fishy.");
        }
        ++a;  // advance to next argument
        Symbol &Val (exec->sym (args[a]));
        TypeDesc valtype = Val.typespec().simpletype ();
        ustring name = * (ustring *) Name.data();
        if (name == Strings::width && valtype == TypeDesc::FLOAT) {
            options.swidth.init ((float *)Val.data(), Val.step());
            options.twidth.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::swidth && valtype == TypeDesc::FLOAT) {
            options.swidth.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::twidth && valtype == TypeDesc::FLOAT) {
            options.twidth.init ((float *)Val.data(), Val.step());

        } else if (name == Strings::blur && valtype == TypeDesc::FLOAT) {
            options.sblur.init ((float *)Val.data(), Val.step());
            options.tblur.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::sblur && valtype == TypeDesc::FLOAT) {
            options.sblur.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::tblur && valtype == TypeDesc::FLOAT) {
            options.tblur.init ((float *)Val.data(), Val.step());

        } else if (name == Strings::wrap && valtype == TypeDesc::STRING) {
            swrap.init ((ustring *)Val.data(), Val.step());
            twrap.init ((ustring *)Val.data(), Val.step());
        } else if (name == Strings::swrap && valtype == TypeDesc::STRING) {
            swrap.init ((ustring *)Val.data(), Val.step());
        } else if (name == Strings::twrap && valtype == TypeDesc::STRING) {
            twrap.init ((ustring *)Val.data(), Val.step());

        } else if (name == Strings::firstchannel && valtype == TypeDesc::INT) {
            firstchannel.init ((int *)Val.data(), Val.step());
        } else if (name == Strings::fill && valtype == TypeDesc::FLOAT) {
            options.fill.init ((float *)Val.data(), Val.step());

        } else if (name == Strings::alpha && valtype == TypeDesc::FLOAT) {
            exec->adjust_varying (Val, true);
            alpha.init ((float *)Val.data(), Val.step());

        } else {
            exec->error ("Unknown texture optional argument: \"%s\", <%s>",
                         name.c_str(), valtype.c_str());
        }
    }

    if (alpha)
        options.nchannels += 1;

    float *r = &result[0];
    bool tempresult = false;
    if (Result.has_derivs() || alpha) {
        tempresult = true;
        r = ALLOCA (float, endpoint*options.nchannels);
    }
    for (int i = beginpoint;  i < endpoint;  ++i) {
        // FIXME -- this calls texture system separately for each point!
        // We really want to batch it into groups that share the same texture
        // filename.
        if (runflags[i]) {
            if (swrap)
                options.swrap = decode_wrap (swrap[i]);
            if (twrap)
                options.twrap = decode_wrap (twrap[i]);
            if (firstchannel)
                options.firstchannel = firstchannel[i];

            bool ok = texturesys->texture (filename[i], options,
                                           runflags, i /*beginpoint*/, i+1 /*endpoint*/,
                                           s, t, dsdx, dtdx, dsdy, dtdy,
                                           r);
            if (! ok) {
                std::string err = texturesys->geterror ();
                exec->error ("%s", err.c_str());
            }
         }
    }

    if (tempresult) {
        // We need to re-copy results back to the right destinations.
        int resultchans = Result.typespec().simpletype().aggregate;
        for (int i = beginpoint;  i < endpoint;  ++i) {
            if (runflags[i])
                for (int c = 0;  c < resultchans;  ++c)
                    (&result[i])[c] = r[i*options.nchannels+c];
        }
        if (alpha) {
            for (int i = beginpoint;  i < endpoint;  ++i)
                if (runflags[i])
                    alpha[i] = r[i*options.nchannels+resultchans];
        }
    }
}

}; // namespace pvt
}; // namespace OSL
#ifdef OSL_NAMESPACE
}; // end namespace OSL_NAMESPACE
#endif
<commit_msg>Supress multiple (per point) empty texture error messages. References:  trac#24   http://reviewboard/r/495/<commit_after>/*
Copyright (c) 2009 Sony Pictures Imageworks, et al.
All Rights Reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of Sony Pictures Imageworks nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT
OWNER 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 "oslops.h"
#include "oslexec_pvt.h"

#include "OpenImageIO/sysutil.h"

#ifdef OSL_NAMESPACE
namespace OSL_NAMESPACE {
#endif
namespace OSL {
namespace pvt {

namespace {  // anonymous

inline TextureOptions::Wrap
decode_wrap (ustring w)
{
    if (w == Strings::black)
        return TextureOptions::WrapBlack;
    if (w == Strings::clamp)
        return TextureOptions::WrapClamp;
    if (w == Strings::periodic)
        return TextureOptions::WrapPeriodic;
    if (w == Strings::mirror)
        return TextureOptions::WrapMirror;
    return TextureOptions::WrapDefault;
}

};  // end anonymous namespace

DECLOP (OP_texture)
{
    // Grab the required arguments: result, filename, s, t
    DASSERT (nargs >= 4);
    Symbol &Result (exec->sym (args[0]));
    Symbol &Filename (exec->sym (args[1]));
    DASSERT (Filename.typespec().is_string());
    Symbol &S (exec->sym (args[2]));
    Symbol &T (exec->sym (args[3]));
    DASSERT (S.typespec().is_float() && T.typespec().is_float());

    // Adjust the result's uniform/varying status
    exec->adjust_varying (Result, true /* Assume texture always varies */);

    // FIXME -- we should allow derivs of texture
    if (Result.has_derivs ())
        exec->zero_derivs (Result);

    float zero = 0.0f;
    VaryingRef<float> result ((float *)Result.data(), Result.step());
    VaryingRef<float> s ((float *)S.data(), S.step());
    VaryingRef<float> t ((float *)T.data(), T.step());
    VaryingRef<ustring> filename ((ustring *)Filename.data(), Filename.step());
    VaryingRef<ustring> swrap (NULL), twrap (NULL);
    VaryingRef<int> firstchannel (NULL);
    VaryingRef<float> alpha (NULL);

    TextureSystem *texturesys = exec->texturesys ();
    TextureOptions options;
    options.firstchannel = 0;
    options.nchannels = Result.typespec().simpletype().aggregate;
    options.fill.init (&zero);

    // Set up derivs
    VaryingRef<float> dsdx, dsdy, dtdx, dtdy;
    if (S.has_derivs()) {
        dsdx.init ((float *)S.data() + 1, S.step());
        dsdy.init ((float *)S.data() + 2, S.step());
    } else {
        dsdx.init (&zero);
        dsdy.init (&zero);
    }
    if (T.has_derivs()) {
        dtdx.init ((float *)T.data() + 1, T.step());
        dtdy.init ((float *)T.data() + 2, T.step());
    } else {
        dtdx.init (&zero);
        dtdy.init (&zero);
    }

    // Parse all the optional arguments
    for (int a = 4;  a < nargs;  ++a) {
        Symbol &Name (exec->sym (args[a]));
        DASSERT (Name.typespec().is_string() &&
                 "optional texture token must be a string");
        DASSERT (a+1 < nargs && "malformed argument list for texture");
        if (Name.is_varying()) {
            exec->warning ("optional texture argument is a varying string! Seems pretty fishy.");
        }
        ++a;  // advance to next argument
        Symbol &Val (exec->sym (args[a]));
        TypeDesc valtype = Val.typespec().simpletype ();
        ustring name = * (ustring *) Name.data();
        if (name == Strings::width && valtype == TypeDesc::FLOAT) {
            options.swidth.init ((float *)Val.data(), Val.step());
            options.twidth.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::swidth && valtype == TypeDesc::FLOAT) {
            options.swidth.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::twidth && valtype == TypeDesc::FLOAT) {
            options.twidth.init ((float *)Val.data(), Val.step());

        } else if (name == Strings::blur && valtype == TypeDesc::FLOAT) {
            options.sblur.init ((float *)Val.data(), Val.step());
            options.tblur.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::sblur && valtype == TypeDesc::FLOAT) {
            options.sblur.init ((float *)Val.data(), Val.step());
        } else if (name == Strings::tblur && valtype == TypeDesc::FLOAT) {
            options.tblur.init ((float *)Val.data(), Val.step());

        } else if (name == Strings::wrap && valtype == TypeDesc::STRING) {
            swrap.init ((ustring *)Val.data(), Val.step());
            twrap.init ((ustring *)Val.data(), Val.step());
        } else if (name == Strings::swrap && valtype == TypeDesc::STRING) {
            swrap.init ((ustring *)Val.data(), Val.step());
        } else if (name == Strings::twrap && valtype == TypeDesc::STRING) {
            twrap.init ((ustring *)Val.data(), Val.step());

        } else if (name == Strings::firstchannel && valtype == TypeDesc::INT) {
            firstchannel.init ((int *)Val.data(), Val.step());
        } else if (name == Strings::fill && valtype == TypeDesc::FLOAT) {
            options.fill.init ((float *)Val.data(), Val.step());

        } else if (name == Strings::alpha && valtype == TypeDesc::FLOAT) {
            exec->adjust_varying (Val, true);
            alpha.init ((float *)Val.data(), Val.step());

        } else {
            exec->error ("Unknown texture optional argument: \"%s\", <%s>",
                         name.c_str(), valtype.c_str());
        }
    }

    if (alpha)
        options.nchannels += 1;

    float *r = &result[0];
    bool tempresult = false;
    if (Result.has_derivs() || alpha) {
        tempresult = true;
        r = ALLOCA (float, endpoint*options.nchannels);
    }
    for (int i = beginpoint;  i < endpoint;  ++i) {
        // FIXME -- this calls texture system separately for each point!
        // We really want to batch it into groups that share the same texture
        // filename.
        if (runflags[i]) {
            if (swrap)
                options.swrap = decode_wrap (swrap[i]);
            if (twrap)
                options.twrap = decode_wrap (twrap[i]);
            if (firstchannel)
                options.firstchannel = firstchannel[i];

            bool ok = texturesys->texture (filename[i], options,
                                           runflags, i /*beginpoint*/, i+1 /*endpoint*/,
                                           s, t, dsdx, dtdx, dsdy, dtdy,
                                           r);
            if (! ok) {
                std::string err = texturesys->geterror ();
                if (err.length())
                    exec->error ("%s", err.c_str());
            }
         }
    }

    if (tempresult) {
        // We need to re-copy results back to the right destinations.
        int resultchans = Result.typespec().simpletype().aggregate;
        for (int i = beginpoint;  i < endpoint;  ++i) {
            if (runflags[i])
                for (int c = 0;  c < resultchans;  ++c)
                    (&result[i])[c] = r[i*options.nchannels+c];
        }
        if (alpha) {
            for (int i = beginpoint;  i < endpoint;  ++i)
                if (runflags[i])
                    alpha[i] = r[i*options.nchannels+resultchans];
        }
    }
}

}; // namespace pvt
}; // namespace OSL
#ifdef OSL_NAMESPACE
}; // end namespace OSL_NAMESPACE
#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

// conn interface - conn, close, insert ->
// tables + update
// Open the db connection
// prepare the statements
// adjust prepared statements params
// execute the statements
// loop through resultset
// close resultset
// close prepared statement
// close db connection

int main(int argc, char* argv[])
{
   char * sql;

   try{
      connection C("dbname=benchcare user=synod password= \
      hostaddr=127.0.0.1 port=5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }
      /* Create SQL statement */
      sql = "CREATE TABLE COMPANY("  \
      "ID INT PRIMARY KEY     NOT NULL," \
      "NAME           TEXT    NOT NULL," \
      "AGE            INT     NOT NULL," \
      "ADDRESS        CHAR(50)," \
      "SALARY         REAL );";

      /* Create a transactional object. */
      work W(C);

      /* Execute SQL query */
      W.exec( sql );
      W.commit();
      cout << "Table created successfully" << endl;
      C.disconnect ();
   }catch (const std::exception &e){
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}
<commit_msg>argc removed<commit_after>#include <iostream>
#include <pqxx/pqxx>

using namespace std;
using namespace pqxx;

// conn interface - conn, close, insert ->
// tables + update
// Open the db connection
// prepare the statements
// adjust prepared statements params
// execute the statements
// loop through resultset
// close resultset
// close prepared statement
// close db connection

int main() {
   const char * sql;

   try{
      connection C("dbname=benchcare user=synod password= \
      hostaddr=127.0.0.1 port=5432");
      if (C.is_open()) {
         cout << "Opened database successfully: " << C.dbname() << endl;
      } else {
         cout << "Can't open database" << endl;
         return 1;
      }
      /* Create SQL statement */
      sql = "CREATE TABLE COMPANY("  \
      "ID INT PRIMARY KEY     NOT NULL," \
      "NAME           TEXT    NOT NULL," \
      "AGE            INT     NOT NULL," \
      "ADDRESS        CHAR(50)," \
      "SALARY         REAL );";

      /* Create a transactional object. */
      work W(C);

      /* Execute SQL query */
      W.exec( sql );
      W.commit();
      cout << "Table created successfully" << endl;
      C.disconnect ();
   }catch (const std::exception &e){
      cerr << e.what() << std::endl;
      return 1;
   }

   return 0;
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "input_state.h"

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    auto& io = ImGui::GetIO();
    if (key >= 0 && key < 512)
    {
        if (action == GLFW_PRESS)
        {
            io.KeysDown[key] = true;
        }
        if (action == GLFW_RELEASE)
        {
            io.KeysDown[key] = false;
        }
    }
    io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
    io.KeyAlt = (mods & GLFW_MOD_ALT) != 0;
    io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
    io.KeySuper = (mods & GLFW_MOD_SUPER) != 0;
}

static void character_callback(GLFWwindow* window, unsigned int codepoint)
{
    if (codepoint < UINT16_MAX)
    {
        ImGui::GetIO().AddInputCharacter(ImWchar(codepoint));
    }
}

static void cursor_position_callback(GLFWwindow* window, double x_position, double y_position)
{
    auto input = static_cast<input_state*>(glfwGetWindowUserPointer(window));
    assert(input);

    input->current_mouse_position = glm::vec2(float(x_position), float(y_position));
    ImGui::GetIO().MousePos = ImVec2(float(x_position), float(y_position));
}

static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
    auto input = static_cast<input_state*>(glfwGetWindowUserPointer(window));
    assert(input);
    auto& io = ImGui::GetIO();

    if (button == GLFW_MOUSE_BUTTON_LEFT)
    {
        if (action == GLFW_PRESS)
        {
            input->left_mouse_button_down = true;
            io.MouseDown[0] = true;
        }
        if (action == GLFW_RELEASE)
        {
            input->left_mouse_button_down = false;
            io.MouseDown[0] = false;
        }
    }
    if (button == GLFW_MOUSE_BUTTON_RIGHT)
    {
        if (action == GLFW_PRESS)
        {
            input->right_mouse_button_down = true;
            io.MouseDown[1] = true;
        }
        if (action == GLFW_RELEASE)
        {
            input->right_mouse_button_down = false;
            io.MouseDown[1] = false;
        }
    }
}

static void scroll_callback(GLFWwindow* window, double x_offset, double y_offset)
{
    auto input = static_cast<input_state*>(glfwGetWindowUserPointer(window));
    assert(input);
    input->scroll_amount = y_offset;
    ImGui::GetIO().MouseWheel = float(y_offset);
}

input_state::input_state(GLFWwindow* window)
    : scroll_amount(0.), time(0.), left_mouse_button_down(false), right_mouse_button_down(false), ui_want_capture_mouse(false)
{
    glfwSetWindowUserPointer(window, this);
    glfwSetKeyCallback(window, key_callback);
    glfwSetCharCallback(window, character_callback);
    glfwSetCursorPosCallback(window, cursor_position_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetScrollCallback(window, scroll_callback);
    time = glfwGetTime();
}

void input_state::update()
{
    scroll_amount = 0.;
    previous_mouse_position = current_mouse_position;
    glfwPollEvents();

    auto& io = ImGui::GetIO();
    auto new_time = glfwGetTime();
    io.DeltaTime = float(new_time - time);
    time = new_time;

    ImGui::NewFrame();
    ui_want_capture_mouse = io.WantCaptureMouse;
}
<commit_msg>Let ImGui know about more mouse buttons<commit_after>#include "stdafx.h"
#include "input_state.h"

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    auto& io = ImGui::GetIO();
    if (key >= 0 && key < 512)
    {
        if (action == GLFW_PRESS)
        {
            io.KeysDown[key] = true;
        }
        if (action == GLFW_RELEASE)
        {
            io.KeysDown[key] = false;
        }
    }
    io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0;
    io.KeyAlt = (mods & GLFW_MOD_ALT) != 0;
    io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0;
    io.KeySuper = (mods & GLFW_MOD_SUPER) != 0;
}

static void character_callback(GLFWwindow* window, unsigned int codepoint)
{
    if (codepoint < UINT16_MAX)
    {
        ImGui::GetIO().AddInputCharacter(ImWchar(codepoint));
    }
}

static void cursor_position_callback(GLFWwindow* window, double x_position, double y_position)
{
    auto input = static_cast<input_state*>(glfwGetWindowUserPointer(window));
    assert(input);

    input->current_mouse_position = glm::vec2(float(x_position), float(y_position));
    ImGui::GetIO().MousePos = ImVec2(float(x_position), float(y_position));
}

static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
{
    auto input = static_cast<input_state*>(glfwGetWindowUserPointer(window));
    assert(input);

    if (button == GLFW_MOUSE_BUTTON_LEFT)
    {
        if (action == GLFW_PRESS)
        {
            input->left_mouse_button_down = true;
        }
        if (action == GLFW_RELEASE)
        {
            input->left_mouse_button_down = false;
        }
    }
    if (button == GLFW_MOUSE_BUTTON_RIGHT)
    {
        if (action == GLFW_PRESS)
        {
            input->right_mouse_button_down = true;
        }
        if (action == GLFW_RELEASE)
        {
            input->right_mouse_button_down = false;
        }
    }

    auto& io = ImGui::GetIO();
    if (button >= 0 && button < 5)
    {
        if (action == GLFW_PRESS)
        {
            io.MouseDown[button] = true;
        }
        if (action == GLFW_RELEASE)
        {
            io.MouseDown[button] = false;
        }
    }
}

static void scroll_callback(GLFWwindow* window, double x_offset, double y_offset)
{
    auto input = static_cast<input_state*>(glfwGetWindowUserPointer(window));
    assert(input);
    input->scroll_amount = y_offset;
    ImGui::GetIO().MouseWheel = float(y_offset);
}

input_state::input_state(GLFWwindow* window)
    : scroll_amount(0.), time(0.), left_mouse_button_down(false), right_mouse_button_down(false), ui_want_capture_mouse(false)
{
    glfwSetWindowUserPointer(window, this);
    glfwSetKeyCallback(window, key_callback);
    glfwSetCharCallback(window, character_callback);
    glfwSetCursorPosCallback(window, cursor_position_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);
    glfwSetScrollCallback(window, scroll_callback);
    time = glfwGetTime();
}

void input_state::update()
{
    scroll_amount = 0.;
    previous_mouse_position = current_mouse_position;
    glfwPollEvents();

    auto& io = ImGui::GetIO();
    auto new_time = glfwGetTime();
    io.DeltaTime = float(new_time - time);
    time = new_time;

    ImGui::NewFrame();
    ui_want_capture_mouse = io.WantCaptureMouse;
}
<|endoftext|>


<commit_before>#include <fennekin_treemodel.h>

#include <stack>
#include <deque>

namespace fennekin
{

  // These functions are used in 'fennekin_treemode_get_type()'

  static void fennekin_treemodel_init(FennekinTreemodel* pkg_tree);
  static void fennekin_treemodel_class_init(FennekinTreemodelClass* klass);
  static void fennekin_treemodel_tree_model_init (GtkTreeModelIface* iface);
  static void fennekin_treemodel_finalize(GObject* object); // the class destructor

  static GObjectClass *parent_class = NULL;

  //
  // Implementation of basic functions used in 'fennekin_treemode_get_type()'
  //

  // Init callback for the type system, called once when our new class is created.
  static void fennekin_treemodel_class_init(FennekinTreemodelClass* klass)
  {
    GObjectClass *object_class;

    parent_class = (GObjectClass*) g_type_class_peek_parent (klass);
    object_class = (GObjectClass*) klass;

    object_class->finalize = fennekin_treemodel_finalize;
  }

  // This is called when an instance is created
  static void fennekin_treemodel_init(FennekinTreemodel* treemodel)
  {
    treemodel->stamp = g_random_int();
  }

  // This is called just before a treemodel is destroyed. Free dynamically allocated memory here.
  static void fennekin_treemodel_finalize(GObject* object)
  {
    // TODO: free all memory used by the object

    (* parent_class->finalize) (object); // must chain up - finalize parent
  }

  //
  // Public functions
  //

  GType fennekin_treemodel_get_type(void)
  {
    static GType fennekin_treemodel_type = 0;

    /* Some boilerplate type registration stuff */
    if (fennekin_treemodel_type == 0)
      {
	static const GTypeInfo fennekin_treemodel_info =
	  {
	    sizeof (FennekinTreemodelClass),
	    NULL,                                         /* base_init */
	    NULL,                                         /* base_finalize */
	    (GClassInitFunc) fennekin_treemodel_class_init,
	    NULL,                                         /* class finalize */
	    NULL,                                         /* class_data */
	    sizeof (FennekinTreemodel),
	    0,                                           /* n_preallocs */
	    (GInstanceInitFunc) fennekin_treemodel_init
	  };
	static const GInterfaceInfo tree_model_info =
	  {
	    (GInterfaceInitFunc) fennekin_treemodel_tree_model_init,
	    NULL,
	    NULL
	  };

	/* First register the new derived type with the GObject type system */
	fennekin_treemodel_type = g_type_register_static (G_TYPE_OBJECT,  "FennekinTreemodel",
							  &fennekin_treemodel_info, (GTypeFlags)0);

	/* Now register our GtkTreeModel interface with the type system */
	g_type_add_interface_static (fennekin_treemodel_type, GTK_TYPE_TREE_MODEL, &tree_model_info);
      }

    return fennekin_treemodel_type;
  }

  FennekinTreemodel* fennekin_treemodel_new(void)
  {
    FennekinTreemodel* new_treemodel;

    new_treemodel = (FennekinTreemodel*) g_object_new (FENNEKIN_TREEMODEL_TYPE, NULL);

    g_assert( new_treemodel != NULL );

    return new_treemodel;
  }

  //
  // Member functions for the GtkTreeModelIface interface
  //

  static GtkTreeModelFlags fennekin_treemodel_get_flags(GtkTreeModel* tree_model);
  static gint fennekin_treemodel_get_n_columns(GtkTreeModel* tree_model);
  static GType fennekin_treemodel_get_column_type(GtkTreeModel* tree_model, gint index);
  static gboolean fennekin_treemodel_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path);
  static GtkTreePath* fennekin_treemodel_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static void fennekin_treemodel_get_value(GtkTreeModel* tree_model, GtkTreeIter *iter, gint column, GValue* value);
  static gboolean fennekin_treemodel_iter_next(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static gboolean fennekin_treemodel_iter_children(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent);
  static gboolean fennekin_treemodel_iter_has_child(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static gint fennekin_treemodel_iter_n_children(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static gboolean fennekin_treemodel_iter_nth_child(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent, gint n);
  static gboolean fennekin_treemodel_iter_parent(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* child);

  // Assign interface member functions
  static void fennekin_treemodel_tree_model_init (GtkTreeModelIface* iface)
  {
    iface->get_flags = fennekin_treemodel_get_flags;
    iface->get_n_columns = fennekin_treemodel_get_n_columns;
    iface->get_column_type = fennekin_treemodel_get_column_type;
    iface->get_iter = fennekin_treemodel_get_iter;
    iface->get_path = fennekin_treemodel_get_path;
    iface->get_value = fennekin_treemodel_get_value;
    iface->iter_next = fennekin_treemodel_iter_next;
    iface->iter_children = fennekin_treemodel_iter_children;
    iface->iter_has_child  = fennekin_treemodel_iter_has_child;
    iface->iter_n_children = fennekin_treemodel_iter_n_children;
    iface->iter_parent = fennekin_treemodel_iter_parent;
  }

  //
  // Implement the interface member functions
  //

  static GtkTreeModelFlags fennekin_treemodel_get_flags(GtkTreeModel* tree_model)
  {
    // we're not a list and our iterators might not survive signals. so let's return 0;
    return static_cast<GtkTreeModelFlags>(0);
  }
  static gint fennekin_treemodel_get_n_columns(GtkTreeModel* tree_model)
  {
    return 1;			// yep, we have only one column
  }
  static GType fennekin_treemodel_get_column_type(GtkTreeModel* tree_model, gint index)
  {
    g_assert(index == 0);		// because we have only one column
    return G_TYPE_STRING;
  }
  static gboolean fennekin_treemodel_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* root = Application::app->doc->root;

    // the length of the 'indices' array is 'depth'.
    gint* indices = gtk_tree_path_get_indices(path);
    gint depth = gtk_tree_path_get_depth(path);

    // TreeModelNodes are MIXED DATA so we will not only have to walk the tree, we also have to keep
    // checking the node is of the right type. There could only be search engines and no search terms!

    TreeModelNode* p = root, *q = NULL;

    for (int i = 0; i < depth; i++)
      {
	gint pos = indices[i], n = 0;
	q = p;

	while (n < pos)
	  {
	    if (q == NULL) break;
	    if (q->node_type == TreeModelNode::search_term) {
	      ++n;
	    }
	    q = q->next;
	  }
	if (n != pos) return FALSE;
	p = q->children;
      }

    if (!q) return FALSE;

    // now 'q' holds the pointer we want
    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = q;
    iter->user_data2 = iter->user_data3 = NULL;

    return TRUE;
  }
  // this struct is for implementing the fennekin_treemodel_get_path() interface member below
  struct fennekin_treemodel_get_path_algo {
    std::stack<gint> stack;

    GtkTreePath* path;
    TreeModelNode* target_node;

    // constructor
    fennekin_treemodel_get_path_algo(GtkTreePath* path, TreeModelNode* target_node)
    {
      this->path = path; this->target_node = target_node;
    }

    // return false if the target_node cannot be found
    bool calculate(TreeModelNode* p)
    {
      stack.push(0);

      while (p) {
	if (p == target_node) {
	  // whoooo! we found it.
	  return true;
	}

	if (p->node_type == TreeModelNode::search_term) {
	  if (p->children)  {
	    if (calculate(p->children) == true) return true;
	  }
	  ++ stack.top();
	}

	p=p->next;
      }

      stack.pop();
      return false;
    }
  };
  static GtkTreePath* fennekin_treemodel_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* root = Application::app->doc->root;
    TreeModelNode* target_node = static_cast<TreeModelNode*>(iter->user_data);

    GtkTreePath* path;
    path = gtk_tree_path_new();

    // OMG This is horrible!
    //
    // To find where target_node is, we basically have zero knowledge and all we can do
    // is walk the entire tree recursively and compare pointers to figure out if we found it.

    fennekin_treemodel_get_path_algo algo(path,target_node);
    if (algo.calculate(root) == true)
      {
	// oh, i forgot: std::stack<> has no iterators :o(
	std::deque<gint> tmp;
	while (!algo.stack.empty()) {
	  tmp.push_front( algo.stack.top() );
	  algo.stack.pop();
	}

	for (std::deque<gint>::iterator i = tmp.begin(); i != tmp.end(); i++)
	  gtk_tree_path_append_index(path, *i);
      }

    return path;
  }
  static void fennekin_treemodel_get_value(GtkTreeModel* tree_model, GtkTreeIter *iter, gint column, GValue* value)
  {
    g_value_init(value, G_TYPE_STRING);
    g_value_set_string(value,
		       static_cast<TreeModelNode*>(iter->user_data)->search_term_value.c_str());
  }
  static gboolean fennekin_treemodel_iter_next(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* node = static_cast<TreeModelNode*>(iter->user_data);

    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = node->next;
    return TRUE;
  }
  static gboolean fennekin_treemodel_iter_children(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* node = static_cast<TreeModelNode*>(parent->user_data);

    if (node == NULL) {		// special case: if parent is null, return root node
      TreeModelNode* root = Application::app->doc->root;
      iter->stamp = fennekin_treemodel->stamp;
      iter->user_data = root;
      return TRUE;
    }

    if (node->children == NULL) return FALSE;

    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = node->children;
    return TRUE;
  }
  static gboolean fennekin_treemodel_iter_has_child(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* node = static_cast<TreeModelNode*>(iter->user_data);

    if (node->children == NULL)
      return FALSE;
    else
      return TRUE;
  }
  static gint fennekin_treemodel_iter_n_children(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
  }
  static gboolean fennekin_treemodel_iter_nth_child(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent, gint n)
  {
  }
  static gboolean fennekin_treemodel_iter_parent(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* child)
  {
  }

} // end namespace fennekin

<commit_msg>bugfixes<commit_after>#include <fennekin_treemodel.h>

#include <stack>
#include <deque>

namespace fennekin
{

  // These functions are used in 'fennekin_treemode_get_type()'

  static void fennekin_treemodel_init(FennekinTreemodel* pkg_tree);
  static void fennekin_treemodel_class_init(FennekinTreemodelClass* klass);
  static void fennekin_treemodel_tree_model_init (GtkTreeModelIface* iface);
  static void fennekin_treemodel_finalize(GObject* object); // the class destructor

  static GObjectClass *parent_class = NULL;

  //
  // Implementation of basic functions used in 'fennekin_treemode_get_type()'
  //

  // Init callback for the type system, called once when our new class is created.
  static void fennekin_treemodel_class_init(FennekinTreemodelClass* klass)
  {
    GObjectClass *object_class;

    parent_class = (GObjectClass*) g_type_class_peek_parent (klass);
    object_class = (GObjectClass*) klass;

    object_class->finalize = fennekin_treemodel_finalize;
  }

  // This is called when an instance is created
  static void fennekin_treemodel_init(FennekinTreemodel* treemodel)
  {
    treemodel->stamp = g_random_int();
  }

  // This is called just before a treemodel is destroyed. Free dynamically allocated memory here.
  static void fennekin_treemodel_finalize(GObject* object)
  {
    // TODO: free all memory used by the object

    (* parent_class->finalize) (object); // must chain up - finalize parent
  }

  //
  // Public functions
  //

  GType fennekin_treemodel_get_type(void)
  {
    static GType fennekin_treemodel_type = 0;

    /* Some boilerplate type registration stuff */
    if (fennekin_treemodel_type == 0)
      {
	static const GTypeInfo fennekin_treemodel_info =
	  {
	    sizeof (FennekinTreemodelClass),
	    NULL,                                         /* base_init */
	    NULL,                                         /* base_finalize */
	    (GClassInitFunc) fennekin_treemodel_class_init,
	    NULL,                                         /* class finalize */
	    NULL,                                         /* class_data */
	    sizeof (FennekinTreemodel),
	    0,                                           /* n_preallocs */
	    (GInstanceInitFunc) fennekin_treemodel_init
	  };
	static const GInterfaceInfo tree_model_info =
	  {
	    (GInterfaceInitFunc) fennekin_treemodel_tree_model_init,
	    NULL,
	    NULL
	  };

	/* First register the new derived type with the GObject type system */
	fennekin_treemodel_type = g_type_register_static (G_TYPE_OBJECT,  "FennekinTreemodel",
							  &fennekin_treemodel_info, (GTypeFlags)0);

	/* Now register our GtkTreeModel interface with the type system */
	g_type_add_interface_static (fennekin_treemodel_type, GTK_TYPE_TREE_MODEL, &tree_model_info);
      }

    return fennekin_treemodel_type;
  }

  FennekinTreemodel* fennekin_treemodel_new(void)
  {
    FennekinTreemodel* new_treemodel;

    new_treemodel = (FennekinTreemodel*) g_object_new (FENNEKIN_TREEMODEL_TYPE, NULL);

    g_assert( new_treemodel != NULL );

    return new_treemodel;
  }

  //
  // Member functions for the GtkTreeModelIface interface
  //

  static GtkTreeModelFlags fennekin_treemodel_get_flags(GtkTreeModel* tree_model);
  static gint fennekin_treemodel_get_n_columns(GtkTreeModel* tree_model);
  static GType fennekin_treemodel_get_column_type(GtkTreeModel* tree_model, gint index);
  static gboolean fennekin_treemodel_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path);
  static GtkTreePath* fennekin_treemodel_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static void fennekin_treemodel_get_value(GtkTreeModel* tree_model, GtkTreeIter *iter, gint column, GValue* value);
  static gboolean fennekin_treemodel_iter_next(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static gboolean fennekin_treemodel_iter_children(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent);
  static gboolean fennekin_treemodel_iter_has_child(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static gint fennekin_treemodel_iter_n_children(GtkTreeModel* tree_model, GtkTreeIter* iter);
  static gboolean fennekin_treemodel_iter_nth_child(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent, gint n);
  static gboolean fennekin_treemodel_iter_parent(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* child);

  // Assign interface member functions
  static void fennekin_treemodel_tree_model_init (GtkTreeModelIface* iface)
  {
    iface->get_flags = fennekin_treemodel_get_flags;
    iface->get_n_columns = fennekin_treemodel_get_n_columns;
    iface->get_column_type = fennekin_treemodel_get_column_type;
    iface->get_iter = fennekin_treemodel_get_iter;
    iface->get_path = fennekin_treemodel_get_path;
    iface->get_value = fennekin_treemodel_get_value;
    iface->iter_next = fennekin_treemodel_iter_next;
    iface->iter_children = fennekin_treemodel_iter_children;
    iface->iter_has_child  = fennekin_treemodel_iter_has_child;
    iface->iter_n_children = fennekin_treemodel_iter_n_children;
    iface->iter_parent = fennekin_treemodel_iter_parent;
  }

  //
  // Implement the interface member functions
  //

  static GtkTreeModelFlags fennekin_treemodel_get_flags(GtkTreeModel* tree_model)
  {
    // we're not a list and our iterators might not survive signals. so let's return 0;
    return static_cast<GtkTreeModelFlags>(0);
  }
  static gint fennekin_treemodel_get_n_columns(GtkTreeModel* tree_model)
  {
    return 1;			// yep, we have only one column
  }
  static GType fennekin_treemodel_get_column_type(GtkTreeModel* tree_model, gint index)
  {
    g_assert(index == 0);		// because we have only one column
    return G_TYPE_STRING;
  }
  static gboolean fennekin_treemodel_get_iter(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreePath* path)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* root = Application::app->doc->root;

    // the length of the 'indices' array is 'depth'.
    gint* indices = gtk_tree_path_get_indices(path);
    gint depth = gtk_tree_path_get_depth(path);

    // TreeModelNodes are MIXED DATA so we will not only have to walk the tree, we also have to keep
    // checking the node is of the right type. There could only be search engines and no search terms!

    TreeModelNode* p = root, *q = NULL;

    for (int i = 0; i < depth; i++)
      {
	gint pos = indices[i], n = 0;
	q = p;

	while (n < pos)
	  {
	    if (q == NULL) break;
	    if (q->node_type == TreeModelNode::search_term) {
	      ++n;
	    }
	    q = q->next;
	  }
	if (n != pos) return FALSE;
	p = q->children;
      }

    if (!q) return FALSE;

    // now 'q' holds the pointer we want
    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = q;
    iter->user_data2 = iter->user_data3 = NULL;

    return TRUE;
  }
  // this struct is for implementing the fennekin_treemodel_get_path() interface member below
  struct fennekin_treemodel_get_path_algo {
    std::stack<gint> stack;

    GtkTreePath* path;
    TreeModelNode* target_node;

    // constructor
    fennekin_treemodel_get_path_algo(GtkTreePath* path, TreeModelNode* target_node)
    {
      this->path = path; this->target_node = target_node;
    }

    // return false if the target_node cannot be found
    bool calculate(TreeModelNode* p)
    {
      stack.push(0);

      while (p) {
	if (p == target_node) {
	  // whoooo! we found it.
	  return true;
	}

	if (p->node_type == TreeModelNode::search_term) {
	  if (p->children)  {
	    if (calculate(p->children) == true) return true;
	  }
	  ++ stack.top();
	}

	p=p->next;
      }

      stack.pop();
      return false;
    }
  };
  static GtkTreePath* fennekin_treemodel_get_path(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* root = Application::app->doc->root;
    TreeModelNode* target_node = static_cast<TreeModelNode*>(iter->user_data);

    GtkTreePath* path;
    path = gtk_tree_path_new();

    // OMG This is horrible!
    //
    // To find where target_node is, we basically have zero knowledge and all we can do
    // is walk the entire tree recursively and compare pointers to figure out if we found it.

    fennekin_treemodel_get_path_algo algo(path,target_node);
    if (algo.calculate(root) == true)
      {
	// oh, i forgot: std::stack<> has no iterators :o(
	std::deque<gint> tmp;
	while (!algo.stack.empty()) {
	  tmp.push_front( algo.stack.top() );
	  algo.stack.pop();
	}

	for (std::deque<gint>::iterator i = tmp.begin(); i != tmp.end(); i++)
	  gtk_tree_path_append_index(path, *i);
      }

    return path;
  }
  static void fennekin_treemodel_get_value(GtkTreeModel* tree_model, GtkTreeIter *iter, gint column, GValue* value)
  {
    g_value_init(value, G_TYPE_STRING);
    g_value_set_string(value,
		       static_cast<TreeModelNode*>(iter->user_data)->search_term_value.c_str());
  }
  static gboolean fennekin_treemodel_iter_next(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* node = static_cast<TreeModelNode*>(iter->user_data);

    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = node->next;
    return TRUE;
  }
  static gboolean fennekin_treemodel_iter_children(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* parent)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);

    if (parent == NULL) {		// special case: if parent is null, return root node
      TreeModelNode* root = Application::app->doc->root;
      iter->stamp = fennekin_treemodel->stamp;
      iter->user_data = root;
      return TRUE;
    }

    TreeModelNode* node = static_cast<TreeModelNode*>(parent->user_data);

    if (node->children == NULL)
      return FALSE;

    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = node->children;
    return TRUE;
  }
  static gboolean fennekin_treemodel_iter_has_child(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* node = static_cast<TreeModelNode*>(iter->user_data);

    if (node->children == NULL)
      return FALSE;
    else
      return TRUE;
  }
  static gint fennekin_treemodel_iter_n_children(GtkTreeModel* tree_model, GtkTreeIter* iter)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);

    if (iter == NULL)
      {
	// return the number of top-level elements
	TreeModelNode* p = Application::app->doc->root;
	gint retval = 0;

	while (p) {
	  if (p->node_type == TreeModelNode::search_term) {
	    ++retval;
	  }
	  p = p->next;
	}

	return retval;
      }

    // now we basically copy and paste the whole thing above for the general case
    TreeModelNode* node = static_cast<TreeModelNode*>(iter->user_data);
    TreeModelNode* p = node->children;
    gint retval = 0;

    while (p) {
      if (p->node_type == TreeModelNode::search_term) {
	++retval;
      }
      p = p->next;
    }

    return retval;
  }
  /* If the row specified by 'parent' has any
   *                              children, set 'iter' to the n-th child and
   *                              return TRUE if it exists, otherwise FALSE.
   *                              A special case is when 'parent' is NULL, in
   *                              which case we need to set 'iter' to the n-th
   *                              row if it exists.
   */
  static gboolean fennekin_treemodel_iter_nth_child(GtkTreeModel* tree_model,
						    GtkTreeIter* iter, GtkTreeIter* parent, gint n)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);

    if (parent == NULL)
      {
	// return the number of top-level elements
	TreeModelNode* p = Application::app->doc->root;
	gint count = 0;

	while (p && count < n) {
	  if (p->node_type == TreeModelNode::search_term) {
	    ++count;
	  }
	  p = p->next;
	}
	if (p) {
	  if (count == n) {
	    iter->stamp = fennekin_treemodel->stamp;
	    iter->user_data = p;
	    return TRUE;
	  }
	}
      }

    // now we basically copy and paste the whole thing above for the general case
    TreeModelNode* p = static_cast<TreeModelNode*>(parent->user_data);
    gint count = 0;

    while (p && count < n) {
      if (p->node_type == TreeModelNode::search_term) {
	++count;
      }
      p = p->next;
    }
    if (p) {
      if (count == n) {
	iter->stamp = fennekin_treemodel->stamp;
	iter->user_data = p;
	return TRUE;
      }
    }
    return FALSE;
  }
  // Point 'iter' to the parent node of 'child'.
  static gboolean fennekin_treemodel_iter_parent(GtkTreeModel* tree_model, GtkTreeIter* iter, GtkTreeIter* child)
  {
    FennekinTreemodel* fennekin_treemodel = FENNEKIN_TREEMODEL(tree_model);
    TreeModelNode* node = static_cast<TreeModelNode*>(child->user_data);
    if (!node->parent) return FALSE;
    TreeModelNode* parent = node->parent;
    iter->stamp = fennekin_treemodel->stamp;
    iter->user_data = parent;
    return TRUE;
  }

} // end namespace fennekin

<|endoftext|>


<commit_before>#include "ConversationReconstructor.h"
#include "types.h"
#include "TcpConnection.h"
#include "UdpConversation.h"
#include "IcmpConversation.h"
#include <assert.h>
#include <algorithm>

namespace FeatureExtractor {
	using namespace std;

	ConversationReconstructor::ConversationReconstructor()
		: timeouts()
		, timeout_interval(timeouts.get_conversation_check_interval_ms())
	{
	}

	ConversationReconstructor::ConversationReconstructor(Config &timeouts)
		: timeouts(timeouts)
		, timeout_interval(timeouts.get_conversation_check_interval_ms())
	{
	}

	ConversationReconstructor::~ConversationReconstructor()
	{
		// Deallocate leftover conversations in output queue
		while (!output_queue.empty()) {
			delete output_queue.front();
			output_queue.pop();
		}

		// Deallocate leftover active conversations
		for (ConversationMap::iterator it = conv_map.begin(); it != conv_map.end(); ++it) {
			delete it->second;
		}
	}

	void ConversationReconstructor::add_packet(const Packet *packet)
	{
		// Remove timed out reassembly conversations
		Timestamp now = packet->get_end_ts();
		check_timeouts(now);

		FiveTuple key = packet->get_five_tuple();
		Conversation *conversation = nullptr;
		ip_field_protocol_t ip_proto = key.get_ip_proto();

		// Find or insert with single lookup:
		// http://stackoverflow.com/a/101980/3503528
		// - iterator can will also used to remove finished connection from map
		// - if connection not found, try with swapped src & dst (opposite direction)
		ConversationMap::iterator it = conv_map.lower_bound(key);
		if (it != conv_map.end() && !(conv_map.key_comp()(key, it->first)))
		{
			// Key (connection) already exists
			conversation = it->second;
		}
		else {
			// If not found, try with opposite direction for TCP & UDP (bidirectional)
			if (ip_proto == TCP || ip_proto == UDP) {
				FiveTuple rev_key = key.get_reversed();
				ConversationMap::iterator rev_it = conv_map.lower_bound(rev_key);
				if (rev_it != conv_map.end() && !(conv_map.key_comp()(rev_key, rev_it->first)))
				{
					// Key for opposite direction already exists
					conversation = rev_it->second;
					it = rev_it;	// Remember iterator if connection should be erased below
				}
			}
		}

		// The key (connection) does not exist in the map
		if (!conversation) {
			switch (ip_proto)
			{
			case TCP:
				conversation = new TcpConnection(packet);
				break;

			case UDP:
				conversation = new UdpConversation(packet);
				break;

			case ICMP:
				conversation = new IcmpConversation(packet);
				break;

			default:
				break;
			}
			assert(conversation != nullptr && "Attempt to add NULL "
				"conversation to conversation map. Possible unhadnled IP protocol value");

			it = conv_map.insert(it, ConversationMap::value_type(key, conversation));
		}

		// Pass new packet to conversation
		bool is_finished = conversation->add_packet(packet);

		// If connection is in final state, remove it from map & enqueue to output
		if (is_finished) {
			conv_map.erase(it);
			output_queue.push(conversation);
		}
	}

	void ConversationReconstructor::report_time(const Timestamp &now)
	{
		check_timeouts(now);
	}

	Conversation *ConversationReconstructor::get_next_conversation()
	{
		if (output_queue.empty())
			return nullptr;

		Conversation *conv = output_queue.front();
		output_queue.pop();
		return conv;
	}

	void ConversationReconstructor::check_timeouts(const Timestamp &now)
	{
		// find, sort, add to queue
		// Run no more often than once per timeout check interval
		if (!timeout_interval.is_timedout(now)) {
			timeout_interval.update_time(now);
			return;
		}
		timeout_interval.update_time(now);

		// Maximal timestamp that timedout connection can have
		Timestamp max_tcp_syn = now - (timeouts.get_tcp_syn_timeout() * 1000000);
		Timestamp max_tcp_estab = now - (timeouts.get_tcp_estab_timeout() * 1000000);
		Timestamp max_tcp_rst = now - (timeouts.get_tcp_rst_timeout() * 1000000);
		Timestamp max_tcp_fin = now - (timeouts.get_tcp_fin_timeout() * 1000000);
		Timestamp max_tcp_last_ack = now - (timeouts.get_tcp_last_ack_timeout() * 1000000);
		Timestamp max_udp = now - (timeouts.get_udp_timeout() * 1000000);
		Timestamp max_icmp = now - (timeouts.get_icmp_timeout() * 1000000);

		// Temporary list of timed out conversations
		vector<Conversation *> timedout_convs;

		// Erasing during iteration available since C++11
		// http://stackoverflow.com/a/263958/3503528
		ConversationMap::iterator it = conv_map.begin();
		while (it != conv_map.end()) {
			bool is_timedout = false;
			Conversation *conv = it->second;
			ip_field_protocol_t ip_proto = conv->get_five_tuple_ptr()->get_ip_proto();

			// Check if conversation is timedout
			if (ip_proto == UDP) {
				is_timedout = (conv->get_last_ts() <= max_udp);
			}
			else if (ip_proto == ICMP) {
				is_timedout = (conv->get_last_ts() <= max_icmp);
			}
			else if (ip_proto == TCP) {
				switch (conv->get_internal_state()) {
				case S0:
				case S1:
					is_timedout = (conv->get_last_ts() <= max_tcp_syn);
					break;

				case ESTAB:
					is_timedout = (conv->get_last_ts() <= max_tcp_estab);
					break;

				case REJ:
				case RSTO:
				case RSTOS0:
				case RSTR:
					is_timedout = (conv->get_last_ts() <= max_tcp_rst);
					break;

				case S2:
				case S3:
					is_timedout = (conv->get_last_ts() <= max_tcp_fin);
					break;

				case S2F:
				case S3F:
					is_timedout = (conv->get_last_ts() <= max_tcp_last_ack);
					break;

				default:
					break;
				}
				break;
			}

			// If buffer is timed out, remove conversation from active conversations
			// and to temporary list of timed out conversations
			if (is_timedout) {
				timedout_convs.push_back(conv);
				conv_map.erase(it++);
			}
			else {
				++it;
			}
		} // end of while(it..

		// Sort timed out conversations by timestamp of last fragmet seen
		// Overriden operator '<' of class Conversation is used
		sort(timedout_convs.begin(), timedout_convs.end());

		// Add timedout conversation to output queue in order of their last timestamp
		for (vector<Conversation *>::iterator it = timedout_convs.begin(); it != timedout_convs.end(); ++it) {
			output_queue.push(*it);
		}
	}

	void ConversationReconstructor::finish_all_conversations()
	{
		// Temporary list of timed out conversations
		vector<Conversation *> timedout_convs;

		// Erasing during iteration available since C++11
		// http://stackoverflow.com/a/263958/3503528
		ConversationMap::iterator it = conv_map.begin();
		while (it != conv_map.end()) {
			Conversation *conv = it->second;
			timedout_convs.push_back(conv);
			conv_map.erase(it++);
		}

		// Sort timed out conversations by timestamp of last fragmet seen
		// Overriden operator '<' of class Conversation is used
		sort(timedout_convs.begin(), timedout_convs.end());

		// Add timeout conversation to output queue in order of their last timestamp
		for (vector<Conversation *>::iterator it = timedout_convs.begin(); it != timedout_convs.end(); ++it) {
			output_queue.push(*it);
		}
	}
}<commit_msg>fix #1<commit_after>#include "ConversationReconstructor.h"
#include "types.h"
#include "TcpConnection.h"
#include "UdpConversation.h"
#include "IcmpConversation.h"
#include <assert.h>
#include <algorithm>

namespace FeatureExtractor {
	using namespace std;

	ConversationReconstructor::ConversationReconstructor()
		: timeouts()
		, timeout_interval(timeouts.get_conversation_check_interval_ms())
	{
	}

	ConversationReconstructor::ConversationReconstructor(Config &timeouts)
		: timeouts(timeouts)
		, timeout_interval(timeouts.get_conversation_check_interval_ms())
	{
	}

	ConversationReconstructor::~ConversationReconstructor()
	{
		// Deallocate leftover conversations in output queue
		while (!output_queue.empty()) {
			delete output_queue.front();
			output_queue.pop();
		}

		// Deallocate leftover active conversations
		for (ConversationMap::iterator it = conv_map.begin(); it != conv_map.end(); ++it) {
			delete it->second;
		}
	}

	void ConversationReconstructor::add_packet(const Packet *packet)
	{
		// Remove timed out reassembly conversations
		Timestamp now = packet->get_end_ts();
		check_timeouts(now);

		FiveTuple key = packet->get_five_tuple();
		Conversation *conversation = nullptr;
		ip_field_protocol_t ip_proto = key.get_ip_proto();

		// Find or insert with single lookup:
		// http://stackoverflow.com/a/101980/3503528
		// - iterator can will also used to remove finished connection from map
		// - if connection not found, try with swapped src & dst (opposite direction)
		ConversationMap::iterator it = conv_map.lower_bound(key);
		if (it != conv_map.end() && !(conv_map.key_comp()(key, it->first)))
		{
			// Key (connection) already exists
			conversation = it->second;
		}
		else {
			// If not found, try with opposite direction for TCP & UDP (bidirectional)
			if (ip_proto == TCP || ip_proto == UDP) {
				FiveTuple rev_key = key.get_reversed();
				ConversationMap::iterator rev_it = conv_map.lower_bound(rev_key);
				if (rev_it != conv_map.end() && !(conv_map.key_comp()(rev_key, rev_it->first)))
				{
					// Key for opposite direction already exists
					conversation = rev_it->second;
					it = rev_it;	// Remember iterator if connection should be erased below
				}
			}
		}

		// The key (connection) does not exist in the map
		if (!conversation) {
			switch (ip_proto)
			{
			case TCP:
				conversation = new TcpConnection(packet);
				break;

			case UDP:
				conversation = new UdpConversation(packet);
				break;

			case ICMP:
				conversation = new IcmpConversation(packet);
				break;

			default:
				break;
			}
			assert(conversation != nullptr && "Attempt to add NULL "
				"conversation to conversation map. Possible unhadnled IP protocol value");

			it = conv_map.insert(it, ConversationMap::value_type(key, conversation));
		}

		// Pass new packet to conversation
		bool is_finished = conversation->add_packet(packet);

		// If connection is in final state, remove it from map & enqueue to output
		if (is_finished) {
			conv_map.erase(it);
			output_queue.push(conversation);
		}
	}

	void ConversationReconstructor::report_time(const Timestamp &now)
	{
		check_timeouts(now);
	}

	Conversation *ConversationReconstructor::get_next_conversation()
	{
		if (output_queue.empty())
			return nullptr;

		Conversation *conv = output_queue.front();
		output_queue.pop();
		return conv;
	}

	void ConversationReconstructor::check_timeouts(const Timestamp &now)
	{
		// find, sort, add to queue
		// Run no more often than once per timeout check interval
		if (!timeout_interval.is_timedout(now)) {
			timeout_interval.update_time(now);
			return;
		}
		timeout_interval.update_time(now);

		// Maximal timestamp that timedout connection can have
		Timestamp max_tcp_syn = now - (timeouts.get_tcp_syn_timeout() * 1000000);
		Timestamp max_tcp_estab = now - (timeouts.get_tcp_estab_timeout() * 1000000);
		Timestamp max_tcp_rst = now - (timeouts.get_tcp_rst_timeout() * 1000000);
		Timestamp max_tcp_fin = now - (timeouts.get_tcp_fin_timeout() * 1000000);
		Timestamp max_tcp_last_ack = now - (timeouts.get_tcp_last_ack_timeout() * 1000000);
		Timestamp max_udp = now - (timeouts.get_udp_timeout() * 1000000);
		Timestamp max_icmp = now - (timeouts.get_icmp_timeout() * 1000000);

		// Temporary list of timed out conversations
		vector<Conversation *> timedout_convs;

		// Erasing during iteration available since C++11
		// http://stackoverflow.com/a/263958/3503528
		ConversationMap::iterator it = conv_map.begin();
		while (it != conv_map.end()) {
			bool is_timedout = false;
			Conversation *conv = it->second;
			ip_field_protocol_t ip_proto = conv->get_five_tuple_ptr()->get_ip_proto();

			// Check if conversation is timedout
			if (ip_proto == UDP) {
				is_timedout = (conv->get_last_ts() <= max_udp);
			}
			else if (ip_proto == ICMP) {
				is_timedout = (conv->get_last_ts() <= max_icmp);
			}
			else if (ip_proto == TCP) {
				switch (conv->get_internal_state()) {
				case S0:
				case S1:
					is_timedout = (conv->get_last_ts() <= max_tcp_syn);
					break;

				case ESTAB:
					is_timedout = (conv->get_last_ts() <= max_tcp_estab);
					break;

				case REJ:
				case RSTO:
				case RSTOS0:
				case RSTR:
					is_timedout = (conv->get_last_ts() <= max_tcp_rst);
					break;

				case S2:
				case S3:
					is_timedout = (conv->get_last_ts() <= max_tcp_fin);
					break;

				case S2F:
				case S3F:
					is_timedout = (conv->get_last_ts() <= max_tcp_last_ack);
					break;

				default:
					break;
				}
			}

			// If buffer is timed out, remove conversation from active conversations
			// and to temporary list of timed out conversations
			if (is_timedout) {
				timedout_convs.push_back(conv);
				conv_map.erase(it++);
			}
			else {
				++it;
			}
		} // end of while(it..

		// Sort timed out conversations by timestamp of last fragmet seen
		// Overriden operator '<' of class Conversation is used
		sort(timedout_convs.begin(), timedout_convs.end());

		// Add timedout conversation to output queue in order of their last timestamp
		for (vector<Conversation *>::iterator it = timedout_convs.begin(); it != timedout_convs.end(); ++it) {
			output_queue.push(*it);
		}
	}

	void ConversationReconstructor::finish_all_conversations()
	{
		// Temporary list of timed out conversations
		vector<Conversation *> timedout_convs;

		// Erasing during iteration available since C++11
		// http://stackoverflow.com/a/263958/3503528
		ConversationMap::iterator it = conv_map.begin();
		while (it != conv_map.end()) {
			Conversation *conv = it->second;
			timedout_convs.push_back(conv);
			conv_map.erase(it++);
		}

		// Sort timed out conversations by timestamp of last fragmet seen
		// Overriden operator '<' of class Conversation is used
		sort(timedout_convs.begin(), timedout_convs.end());

		// Add timeout conversation to output queue in order of their last timestamp
		for (vector<Conversation *>::iterator it = timedout_convs.begin(); it != timedout_convs.end(); ++it) {
			output_queue.push(*it);
		}
	}
}
<|endoftext|>


<commit_before>#include <iostream>
#define GLM_FORCE_RADIANS
#include <glm/gtc/type_ptr.hpp>
#include "DebugRenderer.hpp"

DebugRenderer::DebugRenderer():
  debug_shader(),
  line_shader(),
  line({0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {0}, {3}),
  quad(
      {
      -0.5, -0.5, 0.0,
       0.0,  0.0,
      -0.5,  0.5, 0.0,
       0.0,  1.0,
       0.5, -0.5, 0.0,
       1.0,  0.0,
       0.5,  0.5, 0.0,
       1.0,  1.0,
      },
      {0, 3, 1, 0, 2, 3}, {3, 2})
{

}

void DebugRenderer::draw_lines(const std::vector<std::pair<glm::vec3, glm::vec3>>& lines, const glm::mat4& vp_mat, const glm::vec3& color) {
  line_shader();
  line_shader.set_color(color);
  line_shader.set_MVP(vp_mat);
  line.bind();
  for(const auto& line: lines) {
    line_shader.set_from(std::get<0>(line));
    line_shader.set_to(std::get<1>(line));
    glDrawArrays(GL_POINTS, 0, 1);
  }
  line.unbind();
  line_shader.stop();
}

void DebugRenderer::draw_line(const glm::vec3& from, const glm::vec3& to, const glm::mat4& vp_mat, const glm::vec3& color) {
  //Optimization opportunity: No need to rebind shader every line
  //Also, vertex_buffer binding might be reusable between line and point
  line_shader();
  line_shader.set_color(color);
  line_shader.set_MVP(vp_mat);
  line_shader.set_from(from);
  line_shader.set_to(to);
  line.bind();
  glDrawArrays(GL_POINTS, 0, 1);
  line.unbind();
  line_shader.stop();
}

void DebugRenderer::draw_point(const glm::vec3& pos, const glm::mat4& vp_mat) {
  debug_shader();
  debug_shader.set_color({1,1,1});
  debug_shader.set_MVP(vp_mat);
  debug_shader.set_pos(pos);
  line.bind();
  glDrawArrays(GL_POINTS, 0, 1);
  line.unbind();
  debug_shader.stop();
}

void DebugRenderer::render_fbo(const GLuint fbo_tex) {
  fbo_shader.use_shader();
  quad.bind();
  fbo_shader.set_framebuffer_sampler(0);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, fbo_tex);
  quad.render_elements(GL_TRIANGLES, 6);
  quad.unbind();
  fbo_shader.stop();
}
<commit_msg>Fixed issue where lines are half as long<commit_after>#include <iostream>
#define GLM_FORCE_RADIANS
#include <glm/gtc/type_ptr.hpp>
#include "DebugRenderer.hpp"

DebugRenderer::DebugRenderer():
  debug_shader(),
  line_shader(),
  line({0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}, {0}, {3}),
  quad(
      {
      -0.5, -0.5, 0.0,
       0.0,  0.0,
      -0.5,  0.5, 0.0,
       0.0,  1.0,
       0.5, -0.5, 0.0,
       1.0,  0.0,
       0.5,  0.5, 0.0,
       1.0,  1.0,
      },
      {0, 3, 1, 0, 2, 3}, {3, 2})
{

}

void DebugRenderer::draw_lines(const std::vector<std::pair<glm::vec3, glm::vec3>>& lines, const glm::mat4& vp_mat, const glm::vec3& color) {
  line_shader();
  line_shader.set_color(color);
  line_shader.set_MVP(vp_mat);
  line.bind();
  for(const auto& line: lines) {
    line_shader.set_from(std::get<0>(line));
    line_shader.set_to(std::get<1>(line));
    glDrawArrays(GL_POINTS, 0, 1);
    line_shader.set_from(std::get<1>(line));
    line_shader.set_to(std::get<0>(line));
    glDrawArrays(GL_POINTS, 0, 1);
  }
  line.unbind();
  line_shader.stop();
}

void DebugRenderer::draw_line(const glm::vec3& from, const glm::vec3& to, const glm::mat4& vp_mat, const glm::vec3& color) {
  //Optimization opportunity: No need to rebind shader every line
  //Also, vertex_buffer binding might be reusable between line and point
  line_shader();
  line_shader.set_color(color);
  line_shader.set_MVP(vp_mat);
  line_shader.set_from(from);
  line_shader.set_to(to);
  line.bind();
  glDrawArrays(GL_POINTS, 0, 1);
  line_shader.set_from(to);
  line_shader.set_to(from);
  glDrawArrays(GL_POINTS, 0, 1);
  line.unbind();
  line_shader.stop();
}

void DebugRenderer::draw_point(const glm::vec3& pos, const glm::mat4& vp_mat) {
  debug_shader();
  debug_shader.set_color({1,1,1});
  debug_shader.set_MVP(vp_mat);
  debug_shader.set_pos(pos);
  line.bind();
  glDrawArrays(GL_POINTS, 0, 1);
  line.unbind();
  debug_shader.stop();
}

void DebugRenderer::render_fbo(const GLuint fbo_tex) {
  fbo_shader.use_shader();
  quad.bind();
  fbo_shader.set_framebuffer_sampler(0);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, fbo_tex);
  quad.render_elements(GL_TRIANGLES, 6);
  quad.unbind();
  fbo_shader.stop();
}
<|endoftext|>


<commit_before>#ifndef INSANITY_IMPLEMENTATION_GENERIC_BYTE_ARRAY
#define INSANITY_IMPLEMENTATION_GENERIC_BYTE_ARRAY

#include <Constants.hpp>

#include <IByteArray.hpp>
#include <vector>

#include <Default.hpp>

namespace Insanity
{
	class CGenericByteArray final : public IByteArray, public Default::Object
	{
		//TODO: test this workaround on GCC and XCode
		std::vector<u8> _vec{};
		u64 _offset{ 0 };
	public:
		CGenericByteArray();
		~CGenericByteArray();

		//=================================================
		//Interface: IByteArray
		//=================================================
		void Write(u8 val) override;
		void Write(u16 val) override;
		void Write(u32 val) override;
		void Write(u64 val) override;
		void Write(s8 val) override;
		void Write(s16 val) override;
		void Write(s32 val) override;
		void Write(s64 val) override;
		void Write(bool val) override;
		void Write(float val) override;
		void Write(double val) override;
		void Write(long double val) override;
		void Write(IByteArray const * val) override;
		void Write(u8 const * val, u64 length) override;

		void Read(u8 & val) override;
		void Read(u16 & val) override;
		void Read(u32 & val) override;
		void Read(u64 & val) override;
		void Read(s8 & val) override;
		void Read(s16 & val) override;
		void Read(s32 & val) override;
		void Read(s64 & val) override;
		void Read(bool & val) override;
		void Read(float & val) override;
		void Read(double & val) override;
		void Read(long double & val) override;
		void Read(u8 * val, u64 length) override;

		u8 const * Array() const override;
		u64 Size() const override;
		void Clip() override;
		void Clear() override;
	};
}

#endif
<commit_msg>Remove obsolete comment<commit_after>#ifndef INSANITY_IMPLEMENTATION_GENERIC_BYTE_ARRAY
#define INSANITY_IMPLEMENTATION_GENERIC_BYTE_ARRAY

#include <Constants.hpp>

#include <IByteArray.hpp>
#include <vector>

#include <Default.hpp>

namespace Insanity
{
	class CGenericByteArray final : public IByteArray, public Default::Object
	{
		std::vector<u8> _vec{};
		u64 _offset{ 0 };
	public:
		CGenericByteArray();
		~CGenericByteArray();

		//=================================================
		//Interface: IByteArray
		//=================================================
		void Write(u8 val) override;
		void Write(u16 val) override;
		void Write(u32 val) override;
		void Write(u64 val) override;
		void Write(s8 val) override;
		void Write(s16 val) override;
		void Write(s32 val) override;
		void Write(s64 val) override;
		void Write(bool val) override;
		void Write(float val) override;
		void Write(double val) override;
		void Write(long double val) override;
		void Write(IByteArray const * val) override;
		void Write(u8 const * val, u64 length) override;

		void Read(u8 & val) override;
		void Read(u16 & val) override;
		void Read(u32 & val) override;
		void Read(u64 & val) override;
		void Read(s8 & val) override;
		void Read(s16 & val) override;
		void Read(s32 & val) override;
		void Read(s64 & val) override;
		void Read(bool & val) override;
		void Read(float & val) override;
		void Read(double & val) override;
		void Read(long double & val) override;
		void Read(u8 * val, u64 length) override;

		u8 const * Array() const override;
		u64 Size() const override;
		void Clip() override;
		void Clear() override;
	};
}

#endif
<|endoftext|>


<commit_before>#include "Genes/Piece_Strength_Gene.h"

#include <string>
#include <array>
#include <memory>
#include <map>

#include "Genes/Gene.h"
#include "Game/Piece.h"
#include "Game/Color.h"

#include "Utility/Random.h"

class Board;

Piece_Strength_Gene::Piece_Strength_Gene() : piece_strength{}
{
    recalculate_normalizing_value();
}

std::map<std::string, double> Piece_Strength_Gene::list_properties() const
{
    std::map<std::string, double> properties;
    for(auto piece_type : {PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING})
    {
        auto piece = Piece{WHITE, piece_type};
        properties[std::string(1, piece.fen_symbol())] = piece_value(piece);
    }
    return properties;
}

void Piece_Strength_Gene::load_properties(const std::map<std::string, double>& properties)
{
    piece_value(PAWN)   = properties.at("P");
    piece_value(ROOK)   = properties.at("R");
    piece_value(KNIGHT) = properties.at("N");
    piece_value(BISHOP) = properties.at("B");
    piece_value(QUEEN)  = properties.at("Q");
    piece_value(KING)   = properties.at("K");

    recalculate_normalizing_value();
}

void Piece_Strength_Gene::gene_specific_mutation()
{
    Random::random_element(piece_strength) += Random::random_laplace(1.0);
    recalculate_normalizing_value();
}

void Piece_Strength_Gene::recalculate_normalizing_value()
{
    normalizing_value = 8*std::abs(piece_value(PAWN)) +
                        2*std::abs(piece_value(ROOK)) +
                        2*std::abs(piece_value(KNIGHT)) +
                        2*std::abs(piece_value(BISHOP)) +
                        1*std::abs(piece_value(QUEEN)) +
                        1*std::abs(piece_value(KING));
}

double Piece_Strength_Gene::piece_value(Piece_Type type) const
{
    return piece_strength[type];
}

double& Piece_Strength_Gene::piece_value(Piece_Type type)
{
    return piece_strength[type];
}

double Piece_Strength_Gene::piece_value(Piece piece) const
{
    if( ! piece)
    {
        return 0.0;
    }
    else
    {
        return piece_value(piece.type());
    }
}

const std::array<double, 6>& Piece_Strength_Gene::piece_values() const
{
    return piece_strength;
}

double Piece_Strength_Gene::normalizer() const
{
    return normalizing_value;
}

std::unique_ptr<Gene> Piece_Strength_Gene::duplicate() const
{
    return std::make_unique<Piece_Strength_Gene>(*this);
}

std::string Piece_Strength_Gene::name() const
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, Color, size_t) const
{
    return 0.0;
}
<commit_msg>Loop over all piece types when loading strengths<commit_after>#include "Genes/Piece_Strength_Gene.h"

#include <string>
#include <array>
#include <memory>
#include <map>

#include "Genes/Gene.h"
#include "Game/Piece.h"
#include "Game/Color.h"

#include "Utility/Random.h"

class Board;

Piece_Strength_Gene::Piece_Strength_Gene() : piece_strength{}
{
    recalculate_normalizing_value();
}

std::map<std::string, double> Piece_Strength_Gene::list_properties() const
{
    std::map<std::string, double> properties;
    for(auto piece_type : {PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING})
    {
        auto piece = Piece{WHITE, piece_type};
        properties[std::string(1, piece.fen_symbol())] = piece_value(piece);
    }
    return properties;
}

void Piece_Strength_Gene::load_properties(const std::map<std::string, double>& properties)
{
    for(auto piece_type : {PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING})
    {
        auto piece = Piece{WHITE, piece_type};
        piece_value(piece_type) = properties.at(std::string(1, piece.fen_symbol()));
    }

    recalculate_normalizing_value();
}

void Piece_Strength_Gene::gene_specific_mutation()
{
    Random::random_element(piece_strength) += Random::random_laplace(1.0);
    recalculate_normalizing_value();
}

void Piece_Strength_Gene::recalculate_normalizing_value()
{
    normalizing_value = 8*std::abs(piece_value(PAWN)) +
                        2*std::abs(piece_value(ROOK)) +
                        2*std::abs(piece_value(KNIGHT)) +
                        2*std::abs(piece_value(BISHOP)) +
                        1*std::abs(piece_value(QUEEN)) +
                        1*std::abs(piece_value(KING));
}

double Piece_Strength_Gene::piece_value(Piece_Type type) const
{
    return piece_strength[type];
}

double& Piece_Strength_Gene::piece_value(Piece_Type type)
{
    return piece_strength[type];
}

double Piece_Strength_Gene::piece_value(Piece piece) const
{
    if( ! piece)
    {
        return 0.0;
    }
    else
    {
        return piece_value(piece.type());
    }
}

const std::array<double, 6>& Piece_Strength_Gene::piece_values() const
{
    return piece_strength;
}

double Piece_Strength_Gene::normalizer() const
{
    return normalizing_value;
}

std::unique_ptr<Gene> Piece_Strength_Gene::duplicate() const
{
    return std::make_unique<Piece_Strength_Gene>(*this);
}

std::string Piece_Strength_Gene::name() const
{
    return "Piece Strength Gene";
}

double Piece_Strength_Gene::score_board(const Board&, Color, size_t) const
{
    return 0.0;
}
<|endoftext|>