<commit_before>#include "IR.h"
#include "Util.h"
#include <sstream>

/** \file
 * Utilities on halide types
 */

namespace Halide {

using std::ostringstream;

/** Return an integer which is the maximum value of this type. */
int Type::imax() const {
    if (is_uint()) {
        if (bits == 32) {
            return 0xffffffff;
        } else if (bits < 32) {
            return (int) ((1 << bits) - 1);
        } else {
            assert(0 && "max of Type: Type is too large");
            return 0;
        }
    } else if (is_int()) {
        if (bits == 32) {
            return 0x7fffffff;
        } else if (bits < 32) {
            return (int) ((1 << (bits-1)) - 1);
        } else {
            assert(0 && "max of Type: Type is too large");
            return 0;
        }
    } else {
        assert(0 && "max of Type: Not available for floating point types");
        return 0;
    }
}

/** Return an expression which is the maximum value of this type */
Halide::Expr Type::max() const {
    if (is_int() && bits == 32) {
        return imax(); // No explicit cast of i32.
    } else if ((is_int() || is_uint()) && bits <= 32) {
        return Internal::Cast::make(*this, imax());
    } else {
        // Use a run-time call to a math intrinsic (see posix_math.cpp)
        ostringstream ss;
        ss << "maxval_";
        if (is_int()) ss << "s";
        else if (is_uint()) ss << "u";
        else ss << "f";
        ss << bits;
        return Internal::Call::make(*this, ss.str(), std::vector<Expr>(), Internal::Call::Extern);
    }
}

/** Return an integer which is the minimum value of this type */
int Type::imin() const {
    if (is_uint()) {
        return 0;
    } else if (is_int()) {
        if (bits == 32) {
            return 0x80000000;
        } else if (bits < 32) {
            return -(1 << (bits-1));
        } else {
            assert(0 && "min of Type: Type is too large");
            return 0;
        }
    } else {
        // Use a run-time call to a math intrinsic
        assert(0 && "min of Type: Not available for floating point types");
        return 0;
    }
}

/** Return an expression which is the minimum value of this type */
Expr Type::min() const {
    if (is_int() && bits == 32) {
        return imin(); // No explicit cast of i32.
    } else if ((is_int() || is_uint()) && bits <= 32) {
        return Internal::Cast::make(*this, imin());
    } else {
        // Use a run-time call to a math intrinsic (see posix_math.cpp)
        ostringstream ss;
        ss << "minval_";
        if (is_int()) ss << "s";
        else if (is_uint()) ss << "u";
        else ss << "f";
        ss << bits;
        return Internal::Call::make(*this, ss.str(), std::vector<Expr>(), Internal::Call::Extern);
    }

}

}
<commit_msg>Type::max and Type::min now return the correct thing for vector types.<commit_after>#include "IR.h"
#include "Util.h"
#include <sstream>

/** \file
 * Utilities on halide types
 */

namespace Halide {

using std::ostringstream;

/** Return an integer which is the maximum value of this type. */
int Type::imax() const {
    if (is_uint()) {
        if (bits == 32) {
            return 0xffffffff;
        } else if (bits < 32) {
            return (int) ((1 << bits) - 1);
        } else {
            assert(0 && "max of Type: Type is too large");
            return 0;
        }
    } else if (is_int()) {
        if (bits == 32) {
            return 0x7fffffff;
        } else if (bits < 32) {
            return (int) ((1 << (bits-1)) - 1);
        } else {
            assert(0 && "max of Type: Type is too large");
            return 0;
        }
    } else {
        assert(0 && "max of Type: Not available for floating point types");
        return 0;
    }
}

/** Return an expression which is the maximum value of this type */
Halide::Expr Type::max() const {
    if (width > 1) {
        return Internal::Broadcast::make(element_of().max(), width);
    }
    if (is_int() && bits == 32) {
        return imax(); // No explicit cast of scalar i32.
    } else if ((is_int() || is_uint()) && bits <= 32) {
        return Internal::Cast::make(*this, imax());
    } else {
        // Use a run-time call to a math intrinsic (see posix_math.cpp)
        ostringstream ss;
        ss << "maxval_";
        if (is_int()) ss << "s";
        else if (is_uint()) ss << "u";
        else ss << "f";
        ss << bits;
        return Internal::Call::make(*this, ss.str(), std::vector<Expr>(), Internal::Call::Extern);
    }
}

/** Return an integer which is the minimum value of this type */
int Type::imin() const {
    if (is_uint()) {
        return 0;
    } else if (is_int()) {
        if (bits == 32) {
            return 0x80000000;
        } else if (bits < 32) {
            return -(1 << (bits-1));
        } else {
            assert(0 && "min of Type: Type is too large");
            return 0;
        }
    } else {
        // Use a run-time call to a math intrinsic
        assert(0 && "min of Type: Not available for floating point types");
        return 0;
    }
}

/** Return an expression which is the minimum value of this type */
Expr Type::min() const {
    if (width > 1) {
        return Internal::Broadcast::make(element_of().min(), width);
    }
    if (is_int() && bits == 32) {
        return imin(); // No explicit cast of scalar i32.
    } else if ((is_int() || is_uint()) && bits <= 32) {
        return Internal::Cast::make(*this, imin());
    } else {
        // Use a run-time call to a math intrinsic (see posix_math.cpp)
        ostringstream ss;
        ss << "minval_";
        if (is_int()) ss << "s";
        else if (is_uint()) ss << "u";
        else ss << "f";
        ss << bits;
        return Internal::Call::make(*this, ss.str(), std::vector<Expr>(), Internal::Call::Extern);
    }

}

}
<|endoftext|>


<commit_before>#include <Rcpp.h>
using namespace Rcpp;
#include "rapidxml.h"
using namespace rapidxml;

// [[Rcpp::export]]
std::vector<std::string> xlsx_sheets_(RawVector xml) {
  std::string buffer;
  buffer.resize(xml.size() + 1);
  memcpy(&buffer[0], RAW(xml), xml.size());
  buffer[buffer.size() - 1] = '\0';

  xml_document<> doc;
  doc.parse<0>(&buffer[0]);

  std::vector<std::string> sheetNames;
  xml_node<>* sheets = doc.first_node()->first_node("sheets");

  for (xml_node<>* sheet = sheets->first_node(); sheet;
       sheet = sheet->next_sibling()) {
    std::string value(sheet->first_attribute("name")->value());
    sheetNames.push_back(value);
  }

  return sheetNames;
}
<commit_msg>Mild refactoring of xlsx_sheets<commit_after>#include <Rcpp.h>
using namespace Rcpp;
#include "rapidxml.h"
using namespace rapidxml;

void parse_raw(xml_document<>* pDoc, RawVector xml) {
  std::string buffer;
  buffer.resize(xml.size() + 1);
  memcpy(&buffer[0], RAW(xml), xml.size());
  buffer[buffer.size() - 1] = '\0';

  pDoc->parse<0>(&buffer[0]);
}

// [[Rcpp::export]]
std::vector<std::string> xlsx_sheets_(RawVector xml) {
  xml_document<> doc;
  parse_raw(&doc, xml);

  std::vector<std::string> sheetNames;
  xml_node<>* sheets = doc.first_node()->first_node("sheets");

  if (sheets == NULL)
    stop("Invalid xlsx file: no workbook/sheets tag found");

  for (xml_node<>* sheet = sheets->first_node(); sheet;
       sheet = sheet->next_sibling()) {
    std::string value(sheet->first_attribute("name")->value());
    sheetNames.push_back(value);
  }

  return sheetNames;
}

<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <vector>
#include <string>
#include <cstring>

#include "args.hpp"
#include "budget_exception.hpp"

std::vector<std::wstring> budget::parse_args(int argc, const char* argv[]){
    std::vector<std::wstring> args;

    for(int i = 0; i < argc - 1; ++i){
        wchar_t* buf = new wchar_t[strlen(argv[i+1])];
        size_t num_chars = mbstowcs(buf, argv[i+1], strlen(argv[i+1]));
        args.push_back(std::wstring(buf, num_chars));
        delete buf;
    }

    return std::move(args);
}

void budget::enough_args(const std::vector<std::wstring>& args, std::size_t min){
    if(args.size() < min){
        throw budget_exception(L"Not enough args for this command. Use budget help to see how the command should be used.");
    }
}
<commit_msg>Try another way to parsing command line arguments<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <vector>
#include <string>
#include <cstring>
#include <iostream>

#include "args.hpp"
#include "budget_exception.hpp"

std::vector<std::wstring> budget::parse_args(int argc, const char* argv[]){
    std::vector<std::wstring> args;

    for(int i = 0; i < argc - 1; ++i){
        auto raw = argv[i+1];

        wchar_t* buf = new wchar_t[1025];
        auto size = mbstowcs(buf, raw, 1024);

        args.push_back(std::wstring(buf, size));
        delete[] buf;
    }

    return std::move(args);
}

void budget::enough_args(const std::vector<std::wstring>& args, std::size_t min){
    if(args.size() < min){
        throw budget_exception(L"Not enough args for this command. Use budget help to see how the command should be used.");
    }
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <set>
#include <string>
#include <iostream>
#include <unistd.h>
#include "Compile.h"
#include "Parser.h"

void run_on_bash(std::istream &is) {
    FILE *bash = popen("bash", "w");
    char buf[4096];

    do {
        is.read(buf, sizeof(buf));
        fwrite(buf, 1, is.gcount(), bash);
    } while (is.gcount() > 0);

    fflush(bash);
    pclose(bash);
}

void usage(char *argv0) {
    std::cerr << "USAGE: " << argv0 << " [-r] <INPUT>\n";
    std::cerr << "  Compiles Bish file <INPUT> to bash.\n";
    std::cerr << "\nOPTIONS:\n";
    std::cerr << "  -r: compiles and runs the file.\n";
}

int main(int argc, char **argv) {
    if (argc < 2) {
        usage(argv[0]);
        return 1;
    }

    int c;
    bool run_after_compile = false;
    while ((c = getopt(argc,argv, "r")) != -1) {
        switch (c) {
        case 'r':
            run_after_compile = true;
            break;
        default:
            break;
        }
    }

    if (optind == argc && run_after_compile) {
        std::cerr << "-r needs a filename" << std::endl;
        return 1;
    }

    std::string path(argv[optind]);
    Bish::Parser p;
    Bish::Module *m = p.parse(path);

    std::stringstream s;
    Bish::compile_to_bash(run_after_compile ? s : std::cout, m);
    if (run_after_compile) {
        run_on_bash(s);
    }

    return 0;
}
<commit_msg>Return with the exit status of a run file.<commit_after>#include <stdio.h>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <set>
#include <string>
#include <iostream>
#include <unistd.h>
#include "Compile.h"
#include "Parser.h"

int run_on_bash(std::istream &is) {
    FILE *bash = popen("bash", "w");
    char buf[4096];

    do {
        is.read(buf, sizeof(buf));
        fwrite(buf, 1, is.gcount(), bash);
    } while (is.gcount() > 0);

    fflush(bash);

    int e = pclose(bash)/256;
    return e;
}

void usage(char *argv0) {
    std::cerr << "USAGE: " << argv0 << " [-r] <INPUT>\n";
    std::cerr << "  Compiles Bish file <INPUT> to bash.\n";
    std::cerr << "\nOPTIONS:\n";
    std::cerr << "  -r: compiles and runs the file.\n";
}

int main(int argc, char **argv) {
    if (argc < 2) {
        usage(argv[0]);
        return 1;
    }

    int c;
    bool run_after_compile = false;
    while ((c = getopt(argc,argv, "r")) != -1) {
        switch (c) {
        case 'r':
            run_after_compile = true;
            break;
        default:
            break;
        }
    }

    if (optind == argc && run_after_compile) {
        std::cerr << "-r needs a filename" << std::endl;
        return 1;
    }

    std::string path(argv[optind]);
    Bish::Parser p;
    Bish::Module *m = p.parse(path);

    std::stringstream s;
    Bish::compile_to_bash(run_after_compile ? s : std::cout, m);
    if (run_after_compile) {
        int exit_status = 0;
        exit_status = run_on_bash(s);
        exit(exit_status);
    }

    return 0;
}
<|endoftext|>


<commit_before>#include "EntityEditor.hpp"

#include <Engine/Component/Animation.hpp>
#include <Engine/Component/Physics.hpp>
#include <Engine/Component/Mesh.hpp>
#include <Engine/Component/Lens.hpp>
#include <Engine/Component/Material.hpp>
#include <Engine/Component/DirectionalLight.hpp>
#include <Engine/Component/PointLight.hpp>
#include <Engine/Component/SpotLight.hpp>
#include <Engine/Component/Listener.hpp>
#include <Engine/Component/Script.hpp>
#include <Engine/Component/SoundSource.hpp>
#include <Engine/Component/ParticleEmitter.hpp>
#include <Engine/Hymn.hpp>
#include <Engine/Geometry/Model.hpp>
#include <Engine/Geometry/RiggedModel.hpp>
#include <Engine/Texture/Texture2D.hpp>
#include <Engine/Audio/SoundBuffer.hpp>
#include <Engine/Script/ScriptFile.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>

#include "../../Util/EditorSettings.hpp"
#include "../FileSelector.hpp"
#include "../../ImGui/GuiHelpers.hpp"

using namespace GUI;

EntityEditor::EntityEditor() {
    name[0] = '\0';
    AddEditor<Component::Animation>("Animation", std::bind(&EntityEditor::AnimationEditor, this, std::placeholders::_1));
    AddEditor<Component::Physics>("Physics", std::bind(&EntityEditor::PhysicsEditor, this, std::placeholders::_1));
    AddEditor<Component::Mesh>("Mesh", std::bind(&EntityEditor::MeshEditor, this, std::placeholders::_1));
    AddEditor<Component::Lens>("Lens", std::bind(&EntityEditor::LensEditor, this, std::placeholders::_1));
    AddEditor<Component::Material>("Material", std::bind(&EntityEditor::MaterialEditor, this, std::placeholders::_1));
    AddEditor<Component::DirectionalLight>("Directional light", std::bind(&EntityEditor::DirectionalLightEditor, this, std::placeholders::_1));
    AddEditor<Component::PointLight>("Point light", std::bind(&EntityEditor::PointLightEditor, this, std::placeholders::_1));
    AddEditor<Component::SpotLight>("Spot light", std::bind(&EntityEditor::SpotLightEditor, this, std::placeholders::_1));
    AddEditor<Component::Listener>("Listener", std::bind(&EntityEditor::ListenerEditor, this, std::placeholders::_1));
    AddEditor<Component::Script>("Script", std::bind(&EntityEditor::ScriptEditor, this, std::placeholders::_1));
    AddEditor<Component::SoundSource>("Sound source", std::bind(&EntityEditor::SoundSourceEditor, this, std::placeholders::_1));
    AddEditor<Component::ParticleEmitter>("Particle emitter", std::bind(&EntityEditor::ParticleEmitterEditor, this, std::placeholders::_1));
}

EntityEditor::~EntityEditor() {

}

void EntityEditor::Show() {
    if (ImGui::Begin(("Entity: " + entity->name + "###" + std::to_string(reinterpret_cast<uintptr_t>(entity))).c_str(), &visible, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_ShowBorders)) {
        ImGui::InputText("Name", name, 128);
        entity->name = name;
        ImGui::Text("Transform");
        ImGui::ShowHelpMarker("The entity's position, rotation and scale.", 75.f);
        ImGui::Indent();
        ImGui::DraggableVec3("Position", entity->position);
        ImGui::DraggableVec3("Rotation", entity->rotation);
        ImGui::DraggableVec3("Scale", entity->scale);
        ImGui::Unindent();
        if (!entity->IsScene()) {
            if (ImGui::Button("Add component"))
                ImGui::OpenPopup("Add component");

            if (ImGui::BeginPopup("Add component")) {
                ImGui::Text("Components");
                ImGui::Separator();

                for (Editor& editor : editors) {
                    editor.addFunction();
                }

                ImGui::EndPopup();
            }

            for (Editor& editor : editors) {
                editor.editFunction();
            }
        }
    }

    ImGui::End();
}

void EntityEditor::SetEntity(Entity* entity) {
    this->entity = entity;
    strcpy(name, entity->name.c_str());
}

bool EntityEditor::ShowsEntity(Entity* entity) {
    return this->entity == entity;
}

bool EntityEditor::IsVisible() const {
    return visible;
}

void EntityEditor::SetVisible(bool visible) {
    this->visible = visible;
}

void EntityEditor::AnimationEditor(Component::Animation* animation) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Animation"))
        ImGui::OpenPopup("Select model##Animation");

    if (ImGui::BeginPopup("Select model##Animation")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                animation->riggedModel = dynamic_cast<Geometry::RiggedModel*>(model);
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::PhysicsEditor(Component::Physics* physics) {
    ImGui::Text("Positional");
    ImGui::Indent();
    ImGui::DraggableVec3("Velocity", physics->velocity);
    ImGui::DraggableFloat("Max velocity", physics->maxVelocity, 0.0f);
    ImGui::DraggableVec3("Acceleration", physics->acceleration);
    ImGui::DraggableFloat("Velocity drag factor", physics->velocityDragFactor);
    ImGui::DraggableFloat("Gravity factor", physics->gravityFactor);
    ImGui::Unindent();
    ImGui::Text("Angular");
    ImGui::Indent();
    ImGui::DraggableVec3("Angular velocity", physics->angularVelocity);
    ImGui::DraggableFloat("Max angular velocity", physics->maxAngularVelocity, 0.0f);
    ImGui::DraggableVec3("Angular acceleration", physics->angularAcceleration);
    ImGui::DraggableFloat("Angular drag factor", physics->angularDragFactor);
    ImGui::DraggableVec3("Moment of inertia", physics->momentOfInertia);
    ImGui::Unindent();

}

void EntityEditor::MeshEditor(Component::Mesh* mesh) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Mesh"))
        ImGui::OpenPopup("Select model##Mesh");

    if (ImGui::BeginPopup("Select model##Mesh")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                mesh->geometry = model;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::LensEditor(Component::Lens* lens) {
    ImGui::Indent();
    ImGui::DraggableFloat("Field of view", lens->fieldOfView, 0.0f, 180.f);
    ImGui::DraggableFloat("Z near", lens->zNear, 0.0f);
    ImGui::DraggableFloat("Z far", lens->zFar, 0.0f);
    ImGui::Unindent();
}

void EntityEditor::MaterialEditor(Component::Material* material) {
    // Diffuse
    ImGui::Text("Diffuse");
    ImGui::Indent();
    if (material->diffuse->IsLoaded())
        ImGui::Image((void*) material->diffuse->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select diffuse texture"))
        ImGui::OpenPopup("Select diffuse texture");

    if (ImGui::BeginPopup("Select diffuse texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->diffuse = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Normal
    ImGui::Text("Normal");
    ImGui::Indent();
    if (material->normal->IsLoaded())
        ImGui::Image((void*) material->normal->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select normal texture"))
        ImGui::OpenPopup("Select normal texture");

    if (ImGui::BeginPopup("Select normal texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->normal = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Specular
    ImGui::Text("Specular");
    ImGui::Indent();
    if (material->specular->IsLoaded())
        ImGui::Image((void*) material->specular->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select specular texture"))
        ImGui::OpenPopup("Select specular texture");

    if (ImGui::BeginPopup("Select specular texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->specular = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Glow
    ImGui::Text("Glow");
    ImGui::Indent();
    if (material->glow->IsLoaded())
        ImGui::Image((void*) material->glow->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select glow texture"))
        ImGui::OpenPopup("Select glow texture");

    if (ImGui::BeginPopup("Select glow texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->glow = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::DirectionalLightEditor(Component::DirectionalLight* directionalLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &directionalLight->color[0]);
    ImGui::DraggableFloat("Ambient coefficient", directionalLight->ambientCoefficient, 0.0f);
    ImGui::Unindent();
}

void EntityEditor::PointLightEditor(Component::PointLight* pointLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &pointLight->color[0]);
    ImGui::DraggableFloat("Ambient coefficient", pointLight->ambientCoefficient, 0.0f);
    ImGui::DraggableFloat("Attenuation", pointLight->attenuation, 0.0f);
    ImGui::DraggableFloat("Intensity", pointLight->intensity, 0.0f);
    ImGui::Unindent();
}

void EntityEditor::SpotLightEditor(Component::SpotLight* spotLight) {
    ImGui::Indent();
    ImGui::InputFloat3("Color", &spotLight->color[0]);
    ImGui::DraggableFloat("Ambient coefficient", spotLight->ambientCoefficient, 0.0f);
    ImGui::DraggableFloat("Attenuation", spotLight->attenuation, 0.0f);
    ImGui::DraggableFloat("Intensity", spotLight->intensity, 0.0f);
    ImGui::DraggableFloat("Cone angle", spotLight->coneAngle, 0.0f, 180.f);
    ImGui::Unindent();
}

void EntityEditor::ListenerEditor(Component::Listener* listener) {

}

void EntityEditor::ScriptEditor(Component::Script* script) {
    ImGui::Indent();
    if(script->scriptFile != nullptr)
        ImGui::Text(script->scriptFile->name.c_str());
    else
        ImGui::Text("No script loaded");

    if (ImGui::Button("Select script"))
        ImGui::OpenPopup("Select script");

    if (ImGui::BeginPopup("Select script")) {
        ImGui::Text("Scripts");
        ImGui::Separator();

        for (ScriptFile* scriptFile : Hymn().scripts) {
            if (ImGui::Selectable(scriptFile->name.c_str()))
                script->scriptFile = scriptFile;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::SoundSourceEditor(Component::SoundSource* soundSource) {
    ImGui::Text("Sound");
    ImGui::Indent();
    if (ImGui::Button("Select sound"))
        ImGui::OpenPopup("Select sound");

    if (ImGui::BeginPopup("Select sound")) {
        ImGui::Text("Sounds");
        ImGui::Separator();

        for (Audio::SoundBuffer* sound : Hymn().sounds) {
            if (ImGui::Selectable(sound->name.c_str()))
                soundSource->soundBuffer = sound;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
    ImGui::Text("Sound properties");
    ImGui::Indent();
    ImGui::DraggableFloat("Pitch", soundSource->pitch, 0.0f);
    ImGui::DraggableFloat("Gain", soundSource->gain, 0.0f);
    ImGui::Checkbox("Loop", &soundSource->loop);
    ImGui::Unindent();
}

void EntityEditor::ParticleEmitterEditor(Component::ParticleEmitter* particleEmitter) {
    ImGui::Text("Particle");
    ImGui::Indent();
    int rows = Managers().particleManager->GetTextureAtlasRows();
    float column = static_cast<float>(particleEmitter->particleType.textureIndex % rows);
    float row = static_cast<float>(particleEmitter->particleType.textureIndex / rows);
    ImGui::Image((void*) Managers().particleManager->GetTextureAtlas()->GetTextureID(), ImVec2(128, 128), ImVec2(column / rows, row / rows), ImVec2((column + 1.f) / rows, (row + 1.f) / rows));
    ImGui::InputInt("Texture index", &particleEmitter->particleType.textureIndex);
    ImGui::ColorEdit3("Color", &particleEmitter->particleType.color[0]);
    ImGui::DraggableVec3("Min velocity", particleEmitter->particleType.minVelocity);
    ImGui::DraggableVec3("Max velocity", particleEmitter->particleType.maxVelocity);
    ImGui::DraggableFloat("Average lifetime", particleEmitter->particleType.averageLifetime, 0.0f);
    ImGui::DraggableFloat("Lifetime variance", particleEmitter->particleType.lifetimeVariance, 0.0f);
    ImGui::DraggableVec2("Average size", particleEmitter->particleType.averageSize, 0.0f);
    ImGui::DraggableVec2("Size variance", particleEmitter->particleType.sizeVariance, 0.0f);
    ImGui::Checkbox("Uniform scaling", &particleEmitter->particleType.uniformScaling);
    ImGui::DraggableFloat("Start alpha", particleEmitter->particleType.startAlpha, 0.0f, 1.0f);
    ImGui::DraggableFloat("Mid alpha", particleEmitter->particleType.midAlpha, 0.0f, 1.0f);
    ImGui::DraggableFloat("End alpha", particleEmitter->particleType.endAlpha, 0.0f, 1.0f);
    ImGui::Unindent();

    ImGui::Text("Emitter");
    ImGui::Indent();
    ImGui::DraggableFloat("Average emit time", particleEmitter->averageEmitTime, 0.0f);
    ImGui::DraggableFloat("Emit time variance", particleEmitter->emitTimeVariance, 0.0f);

    const char* items[] = { "Point", "Cuboid" };
    int item = static_cast<int>(particleEmitter->emitterType);
    if (ImGui::Combo("Emitter type", &item, items, 2))
        particleEmitter->emitterType = static_cast<Component::ParticleEmitter::EmitterType>(item);

    if (particleEmitter->emitterType == Component::ParticleEmitter::CUBOID)
        ImGui::DraggableVec3("Size", particleEmitter->size);

    ImGui::Unindent();

    ImGui::Text("Preview");
    ImGui::Indent();
    ImGui::Checkbox("Simulate", &particleEmitter->preview);
    ImGui::Unindent();
}
<commit_msg>Use color edit for light colors<commit_after>#include "EntityEditor.hpp"

#include <Engine/Component/Animation.hpp>
#include <Engine/Component/Physics.hpp>
#include <Engine/Component/Mesh.hpp>
#include <Engine/Component/Lens.hpp>
#include <Engine/Component/Material.hpp>
#include <Engine/Component/DirectionalLight.hpp>
#include <Engine/Component/PointLight.hpp>
#include <Engine/Component/SpotLight.hpp>
#include <Engine/Component/Listener.hpp>
#include <Engine/Component/Script.hpp>
#include <Engine/Component/SoundSource.hpp>
#include <Engine/Component/ParticleEmitter.hpp>
#include <Engine/Hymn.hpp>
#include <Engine/Geometry/Model.hpp>
#include <Engine/Geometry/RiggedModel.hpp>
#include <Engine/Texture/Texture2D.hpp>
#include <Engine/Audio/SoundBuffer.hpp>
#include <Engine/Script/ScriptFile.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>

#include "../../Util/EditorSettings.hpp"
#include "../FileSelector.hpp"
#include "../../ImGui/GuiHelpers.hpp"

using namespace GUI;

EntityEditor::EntityEditor() {
    name[0] = '\0';
    AddEditor<Component::Animation>("Animation", std::bind(&EntityEditor::AnimationEditor, this, std::placeholders::_1));
    AddEditor<Component::Physics>("Physics", std::bind(&EntityEditor::PhysicsEditor, this, std::placeholders::_1));
    AddEditor<Component::Mesh>("Mesh", std::bind(&EntityEditor::MeshEditor, this, std::placeholders::_1));
    AddEditor<Component::Lens>("Lens", std::bind(&EntityEditor::LensEditor, this, std::placeholders::_1));
    AddEditor<Component::Material>("Material", std::bind(&EntityEditor::MaterialEditor, this, std::placeholders::_1));
    AddEditor<Component::DirectionalLight>("Directional light", std::bind(&EntityEditor::DirectionalLightEditor, this, std::placeholders::_1));
    AddEditor<Component::PointLight>("Point light", std::bind(&EntityEditor::PointLightEditor, this, std::placeholders::_1));
    AddEditor<Component::SpotLight>("Spot light", std::bind(&EntityEditor::SpotLightEditor, this, std::placeholders::_1));
    AddEditor<Component::Listener>("Listener", std::bind(&EntityEditor::ListenerEditor, this, std::placeholders::_1));
    AddEditor<Component::Script>("Script", std::bind(&EntityEditor::ScriptEditor, this, std::placeholders::_1));
    AddEditor<Component::SoundSource>("Sound source", std::bind(&EntityEditor::SoundSourceEditor, this, std::placeholders::_1));
    AddEditor<Component::ParticleEmitter>("Particle emitter", std::bind(&EntityEditor::ParticleEmitterEditor, this, std::placeholders::_1));
}

EntityEditor::~EntityEditor() {

}

void EntityEditor::Show() {
    if (ImGui::Begin(("Entity: " + entity->name + "###" + std::to_string(reinterpret_cast<uintptr_t>(entity))).c_str(), &visible, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_ShowBorders)) {
        ImGui::InputText("Name", name, 128);
        entity->name = name;
        ImGui::Text("Transform");
        ImGui::ShowHelpMarker("The entity's position, rotation and scale.", 75.f);
        ImGui::Indent();
        ImGui::DraggableVec3("Position", entity->position);
        ImGui::DraggableVec3("Rotation", entity->rotation);
        ImGui::DraggableVec3("Scale", entity->scale);
        ImGui::Unindent();
        if (!entity->IsScene()) {
            if (ImGui::Button("Add component"))
                ImGui::OpenPopup("Add component");

            if (ImGui::BeginPopup("Add component")) {
                ImGui::Text("Components");
                ImGui::Separator();

                for (Editor& editor : editors) {
                    editor.addFunction();
                }

                ImGui::EndPopup();
            }

            for (Editor& editor : editors) {
                editor.editFunction();
            }
        }
    }

    ImGui::End();
}

void EntityEditor::SetEntity(Entity* entity) {
    this->entity = entity;
    strcpy(name, entity->name.c_str());
}

bool EntityEditor::ShowsEntity(Entity* entity) {
    return this->entity == entity;
}

bool EntityEditor::IsVisible() const {
    return visible;
}

void EntityEditor::SetVisible(bool visible) {
    this->visible = visible;
}

void EntityEditor::AnimationEditor(Component::Animation* animation) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Animation"))
        ImGui::OpenPopup("Select model##Animation");

    if (ImGui::BeginPopup("Select model##Animation")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                animation->riggedModel = dynamic_cast<Geometry::RiggedModel*>(model);
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::PhysicsEditor(Component::Physics* physics) {
    ImGui::Text("Positional");
    ImGui::Indent();
    ImGui::DraggableVec3("Velocity", physics->velocity);
    ImGui::DraggableFloat("Max velocity", physics->maxVelocity, 0.0f);
    ImGui::DraggableVec3("Acceleration", physics->acceleration);
    ImGui::DraggableFloat("Velocity drag factor", physics->velocityDragFactor);
    ImGui::DraggableFloat("Gravity factor", physics->gravityFactor);
    ImGui::Unindent();
    ImGui::Text("Angular");
    ImGui::Indent();
    ImGui::DraggableVec3("Angular velocity", physics->angularVelocity);
    ImGui::DraggableFloat("Max angular velocity", physics->maxAngularVelocity, 0.0f);
    ImGui::DraggableVec3("Angular acceleration", physics->angularAcceleration);
    ImGui::DraggableFloat("Angular drag factor", physics->angularDragFactor);
    ImGui::DraggableVec3("Moment of inertia", physics->momentOfInertia);
    ImGui::Unindent();

}

void EntityEditor::MeshEditor(Component::Mesh* mesh) {
    ImGui::Indent();
    if (ImGui::Button("Select model##Mesh"))
        ImGui::OpenPopup("Select model##Mesh");

    if (ImGui::BeginPopup("Select model##Mesh")) {
        ImGui::Text("Models");
        ImGui::Separator();

        for (Geometry::Model* model : Hymn().models) {
            if (ImGui::Selectable(model->name.c_str()))
                mesh->geometry = model;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::LensEditor(Component::Lens* lens) {
    ImGui::Indent();
    ImGui::DraggableFloat("Field of view", lens->fieldOfView, 0.0f, 180.f);
    ImGui::DraggableFloat("Z near", lens->zNear, 0.0f);
    ImGui::DraggableFloat("Z far", lens->zFar, 0.0f);
    ImGui::Unindent();
}

void EntityEditor::MaterialEditor(Component::Material* material) {
    // Diffuse
    ImGui::Text("Diffuse");
    ImGui::Indent();
    if (material->diffuse->IsLoaded())
        ImGui::Image((void*) material->diffuse->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select diffuse texture"))
        ImGui::OpenPopup("Select diffuse texture");

    if (ImGui::BeginPopup("Select diffuse texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->diffuse = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Normal
    ImGui::Text("Normal");
    ImGui::Indent();
    if (material->normal->IsLoaded())
        ImGui::Image((void*) material->normal->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select normal texture"))
        ImGui::OpenPopup("Select normal texture");

    if (ImGui::BeginPopup("Select normal texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->normal = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Specular
    ImGui::Text("Specular");
    ImGui::Indent();
    if (material->specular->IsLoaded())
        ImGui::Image((void*) material->specular->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select specular texture"))
        ImGui::OpenPopup("Select specular texture");

    if (ImGui::BeginPopup("Select specular texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->specular = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();

    // Glow
    ImGui::Text("Glow");
    ImGui::Indent();
    if (material->glow->IsLoaded())
        ImGui::Image((void*) material->glow->GetTextureID(), ImVec2(128, 128));

    if (ImGui::Button("Select glow texture"))
        ImGui::OpenPopup("Select glow texture");

    if (ImGui::BeginPopup("Select glow texture")) {
        ImGui::Text("Textures");
        ImGui::Separator();

        for (Texture2D* texture : Hymn().textures) {
            if (ImGui::Selectable(texture->name.c_str()))
                material->glow = texture;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::DirectionalLightEditor(Component::DirectionalLight* directionalLight) {
    ImGui::Indent();
    ImGui::ColorEdit3("Color", &directionalLight->color[0]);
    ImGui::DraggableFloat("Ambient coefficient", directionalLight->ambientCoefficient, 0.0f);
    ImGui::Unindent();
}

void EntityEditor::PointLightEditor(Component::PointLight* pointLight) {
    ImGui::Indent();
    ImGui::ColorEdit3("Color", &pointLight->color[0]);
    ImGui::DraggableFloat("Ambient coefficient", pointLight->ambientCoefficient, 0.0f);
    ImGui::DraggableFloat("Attenuation", pointLight->attenuation, 0.0f);
    ImGui::DraggableFloat("Intensity", pointLight->intensity, 0.0f);
    ImGui::Unindent();
}

void EntityEditor::SpotLightEditor(Component::SpotLight* spotLight) {
    ImGui::Indent();
    ImGui::ColorEdit3("Color", &spotLight->color[0]);
    ImGui::DraggableFloat("Ambient coefficient", spotLight->ambientCoefficient, 0.0f);
    ImGui::DraggableFloat("Attenuation", spotLight->attenuation, 0.0f);
    ImGui::DraggableFloat("Intensity", spotLight->intensity, 0.0f);
    ImGui::DraggableFloat("Cone angle", spotLight->coneAngle, 0.0f, 180.f);
    ImGui::Unindent();
}

void EntityEditor::ListenerEditor(Component::Listener* listener) {

}

void EntityEditor::ScriptEditor(Component::Script* script) {
    ImGui::Indent();
    if(script->scriptFile != nullptr)
        ImGui::Text(script->scriptFile->name.c_str());
    else
        ImGui::Text("No script loaded");

    if (ImGui::Button("Select script"))
        ImGui::OpenPopup("Select script");

    if (ImGui::BeginPopup("Select script")) {
        ImGui::Text("Scripts");
        ImGui::Separator();

        for (ScriptFile* scriptFile : Hymn().scripts) {
            if (ImGui::Selectable(scriptFile->name.c_str()))
                script->scriptFile = scriptFile;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
}

void EntityEditor::SoundSourceEditor(Component::SoundSource* soundSource) {
    ImGui::Text("Sound");
    ImGui::Indent();
    if (ImGui::Button("Select sound"))
        ImGui::OpenPopup("Select sound");

    if (ImGui::BeginPopup("Select sound")) {
        ImGui::Text("Sounds");
        ImGui::Separator();

        for (Audio::SoundBuffer* sound : Hymn().sounds) {
            if (ImGui::Selectable(sound->name.c_str()))
                soundSource->soundBuffer = sound;
        }

        ImGui::EndPopup();
    }
    ImGui::Unindent();
    ImGui::Text("Sound properties");
    ImGui::Indent();
    ImGui::DraggableFloat("Pitch", soundSource->pitch, 0.0f);
    ImGui::DraggableFloat("Gain", soundSource->gain, 0.0f);
    ImGui::Checkbox("Loop", &soundSource->loop);
    ImGui::Unindent();
}

void EntityEditor::ParticleEmitterEditor(Component::ParticleEmitter* particleEmitter) {
    ImGui::Text("Particle");
    ImGui::Indent();
    int rows = Managers().particleManager->GetTextureAtlasRows();
    float column = static_cast<float>(particleEmitter->particleType.textureIndex % rows);
    float row = static_cast<float>(particleEmitter->particleType.textureIndex / rows);
    ImGui::Image((void*) Managers().particleManager->GetTextureAtlas()->GetTextureID(), ImVec2(128, 128), ImVec2(column / rows, row / rows), ImVec2((column + 1.f) / rows, (row + 1.f) / rows));
    ImGui::InputInt("Texture index", &particleEmitter->particleType.textureIndex);
    ImGui::ColorEdit3("Color", &particleEmitter->particleType.color[0]);
    ImGui::DraggableVec3("Min velocity", particleEmitter->particleType.minVelocity);
    ImGui::DraggableVec3("Max velocity", particleEmitter->particleType.maxVelocity);
    ImGui::DraggableFloat("Average lifetime", particleEmitter->particleType.averageLifetime, 0.0f);
    ImGui::DraggableFloat("Lifetime variance", particleEmitter->particleType.lifetimeVariance, 0.0f);
    ImGui::DraggableVec2("Average size", particleEmitter->particleType.averageSize, 0.0f);
    ImGui::DraggableVec2("Size variance", particleEmitter->particleType.sizeVariance, 0.0f);
    ImGui::Checkbox("Uniform scaling", &particleEmitter->particleType.uniformScaling);
    ImGui::DraggableFloat("Start alpha", particleEmitter->particleType.startAlpha, 0.0f, 1.0f);
    ImGui::DraggableFloat("Mid alpha", particleEmitter->particleType.midAlpha, 0.0f, 1.0f);
    ImGui::DraggableFloat("End alpha", particleEmitter->particleType.endAlpha, 0.0f, 1.0f);
    ImGui::Unindent();

    ImGui::Text("Emitter");
    ImGui::Indent();
    ImGui::DraggableFloat("Average emit time", particleEmitter->averageEmitTime, 0.0f);
    ImGui::DraggableFloat("Emit time variance", particleEmitter->emitTimeVariance, 0.0f);

    const char* items[] = { "Point", "Cuboid" };
    int item = static_cast<int>(particleEmitter->emitterType);
    if (ImGui::Combo("Emitter type", &item, items, 2))
        particleEmitter->emitterType = static_cast<Component::ParticleEmitter::EmitterType>(item);

    if (particleEmitter->emitterType == Component::ParticleEmitter::CUBOID)
        ImGui::DraggableVec3("Size", particleEmitter->size);

    ImGui::Unindent();

    ImGui::Text("Preview");
    ImGui::Indent();
    ImGui::Checkbox("Simulate", &particleEmitter->preview);
    ImGui::Unindent();
}
<|endoftext|>


<commit_before>#include "macros.h"
#pragma warning(push,1) // disable warnings within system headers
#include <psapi.h>
#pragma warning(pop)

IMPLEMENT_THUNK( psapi, WINDOWS, DWORD, WINAPI, GetModuleFileNameExW, (HANDLE hProcess, HMODULE hModule, LPWSTR lpFileNameW, DWORD nSize ) )
{
    AUTO_STR( lpFileName, 2 * nSize );

    if ( GetModuleFileNameExA( hProcess, hModule, lpFileNameA, 2 * nSize ) )
        return (DWORD) STR2WSTR( lpFileName, nSize );
    else
        return 0;
}<commit_msg>INTEGRATION: CWS mingwport06 (1.4.138); FILE MERGED 2007/08/24 13:06:54 vg 1.4.138.1: #i75499# pragma is for MSVC<commit_after>#include "macros.h"
#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#include <psapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

IMPLEMENT_THUNK( psapi, WINDOWS, DWORD, WINAPI, GetModuleFileNameExW, (HANDLE hProcess, HMODULE hModule, LPWSTR lpFileNameW, DWORD nSize ) )
{
    AUTO_STR( lpFileName, 2 * nSize );

    if ( GetModuleFileNameExA( hProcess, hModule, lpFileNameA, 2 * nSize ) )
        return (DWORD) STR2WSTR( lpFileName, nSize );
    else
        return 0;
}<|endoftext|>


<commit_before>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED

#include <type_traits>
#include <string>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/call_traits.hpp>
#include <luabind/lua_include.hpp>

#if LUA_VERSION_NUM < 502
# define lua_rawlen lua_objlen
#endif

namespace luabind {

	template <class T, class Derived = default_converter<T> >
	struct native_converter_base
	{
		typedef std::true_type is_native;
		typedef typename detail::call_traits<T>::value_type value_type;
		typedef typename detail::call_traits<T>::param_type param_type;

		enum { consumed_args = 1 };

		template <class U>
		void converter_postcall(lua_State*, U const&, int)
		{}

		int match(lua_State* L, detail::by_value<T>, int index)
		{
			return Derived::compute_score(L, index);
		}

		int match(lua_State* L, detail::by_value<T const>, int index)
		{
			return Derived::compute_score(L, index);
		}

		int match(lua_State* L, detail::by_const_reference<T>, int index)
		{
			return Derived::compute_score(L, index);
		}

		value_type to_cpp(lua_State* L, detail::by_value<T>, int index)
		{
			return derived().to_cpp_deferred(L, index);
		}

		value_type to_cpp(lua_State* L, detail::by_const_reference<T>, int index)
		{
			return derived().to_cpp_deferred(L, index);
		}

		void to_lua(lua_State* L, param_type value)
		{
			derived().to_lua_deferred(L, value);
		}

		Derived& derived()
		{
			return static_cast<Derived&>(*this);
		}
	};

	template <typename QualifiedT>
	struct integer_converter
		: native_converter_base<typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type>
	{
		typedef typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type T;
		typedef typename native_converter_base<T>::param_type param_type;
		typedef typename native_converter_base<T>::value_type value_type;

		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
		}

		static value_type to_cpp_deferred(lua_State* L, int index)
		{
			if((std::is_unsigned<value_type>::value && sizeof(value_type)>=sizeof(lua_Integer))||(sizeof(value_type)>sizeof(lua_Integer))) {
				return static_cast<T>(lua_tonumber(L, index));
			} else {
				return static_cast<T>(lua_tointeger(L, index));
			}
		}

		void to_lua_deferred(lua_State* L, param_type value)
		{
			if((std::is_unsigned<value_type>::value && sizeof(value_type)>=sizeof(lua_Integer))||(sizeof(value_type)>sizeof(lua_Integer)))
			{
				lua_pushnumber(L, value);
			} else {
				lua_pushinteger(L, static_cast<lua_Integer>(value));
			}
		}
	};

	template <typename QualifiedT>
	struct number_converter
		: native_converter_base<typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type>
	{
		typedef typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type T;
		typedef typename native_converter_base<T>::param_type param_type;
		typedef typename native_converter_base<T>::value_type value_type;

		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index)==LUA_TNUMBER ? 0 : no_match;
		}

		static value_type to_cpp_deferred(lua_State* L, int index)
		{
			return static_cast<T>(lua_tonumber(L, index));
		}

		static void to_lua_deferred(lua_State* L, param_type value)
		{
			lua_pushnumber(L, static_cast<lua_Number>(value));
		}
	};

	template <>
	struct default_converter<bool>
		: native_converter_base<bool>
	{
		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index)==LUA_TBOOLEAN ? 0 : no_match;
		}

		static bool to_cpp_deferred(lua_State* L, int index)
		{
			return lua_toboolean(L, index) == 1;
		}

		static void to_lua_deferred(lua_State* L, bool value)
		{
			lua_pushboolean(L, value);
		}
	};

	template <>
	struct default_converter<bool const>
		: default_converter<bool>
	{};

	template <>
	struct default_converter<bool const&>
		: default_converter<bool>
	{};

	template <>
	struct default_converter<std::string>
		: native_converter_base<std::string>
	{
		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index)==LUA_TSTRING ? 0 : no_match;
		}

		static std::string to_cpp_deferred(lua_State* L, int index)
		{
			return std::string(lua_tostring(L, index), lua_rawlen(L, index));
		}

		static void to_lua_deferred(lua_State* L, std::string const& value)
		{
			lua_pushlstring(L, value.data(), value.size());
		}
	};

	template <>
	struct default_converter<std::string&>
		: default_converter<std::string>
	{};

	template <>
	struct default_converter<std::string const>
		: default_converter<std::string>
	{};

	template <>
	struct default_converter<std::string const&>
		: default_converter<std::string>
	{};

	template <>
	struct default_converter<char const*>
	{
		typedef std::true_type is_native;

		enum { consumed_args = 1 };

		template <class U>
		static int match(lua_State* L, U, int index)
		{
			int type = lua_type(L, index);
			return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : no_match;
		}

		template <class U>
		static char const* to_cpp(lua_State* L, U, int index)
		{
			return lua_tostring(L, index);
		}

		static void to_lua(lua_State* L, char const* str)
		{
			lua_pushstring(L, str);
		}

		template <class U>
		void converter_postcall(lua_State*, U, int)
		{}
	};

	template <>
	struct default_converter<const char* const>
		: default_converter<char const*>
	{};

	template <>
	struct default_converter<const char* const&>
		: default_converter<char const*>
	{};

	template <>
	struct default_converter<char*>
		: default_converter<char const*>
	{};

	template <std::size_t N>
	struct default_converter<char const[N]>
		: default_converter<char const*>
	{};

	template <std::size_t N>
	struct default_converter<char[N]>
		: default_converter<char const*>
	{};

	template <std::size_t N>
	struct default_converter <const char(&)[N]>
		: default_converter<char const*>
	{};

	template <typename T>
	struct default_converter < T, typename std::enable_if< std::is_integral<typename std::remove_reference<T>::type>::value >::type >
		: integer_converter<T>
	{
	};

	template <typename T>
	struct default_converter < T, typename std::enable_if< std::is_floating_point<typename std::remove_reference<T>::type>::value >::type >
		: number_converter<T>
	{
	};

}

#if LUA_VERSION_NUM < 502
# undef lua_rawlen
#endif

#endif

<commit_msg>added missing converter overload for "const char*&"<commit_after>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
// ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef LUABIND_NATIVE_CONVERTER_HPP_INCLUDED
#define LUABIND_NATIVE_CONVERTER_HPP_INCLUDED

#include <type_traits>
#include <string>
#include <luabind/detail/conversion_policies/conversion_base.hpp>
#include <luabind/detail/call_traits.hpp>
#include <luabind/lua_include.hpp>

#if LUA_VERSION_NUM < 502
# define lua_rawlen lua_objlen
#endif

namespace luabind {

	template <class T, class Derived = default_converter<T> >
	struct native_converter_base
	{
		typedef std::true_type is_native;
		typedef typename detail::call_traits<T>::value_type value_type;
		typedef typename detail::call_traits<T>::param_type param_type;

		enum { consumed_args = 1 };

		template <class U>
		void converter_postcall(lua_State*, U const&, int)
		{}

		int match(lua_State* L, detail::by_value<T>, int index)
		{
			return Derived::compute_score(L, index);
		}

		int match(lua_State* L, detail::by_value<T const>, int index)
		{
			return Derived::compute_score(L, index);
		}

		int match(lua_State* L, detail::by_const_reference<T>, int index)
		{
			return Derived::compute_score(L, index);
		}

		value_type to_cpp(lua_State* L, detail::by_value<T>, int index)
		{
			return derived().to_cpp_deferred(L, index);
		}

		value_type to_cpp(lua_State* L, detail::by_const_reference<T>, int index)
		{
			return derived().to_cpp_deferred(L, index);
		}

		void to_lua(lua_State* L, param_type value)
		{
			derived().to_lua_deferred(L, value);
		}

		Derived& derived()
		{
			return static_cast<Derived&>(*this);
		}
	};

	template <typename QualifiedT>
	struct integer_converter
		: native_converter_base<typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type>
	{
		typedef typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type T;
		typedef typename native_converter_base<T>::param_type param_type;
		typedef typename native_converter_base<T>::value_type value_type;

		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index) == LUA_TNUMBER ? 0 : no_match;
		}

		static value_type to_cpp_deferred(lua_State* L, int index)
		{
			if((std::is_unsigned<value_type>::value && sizeof(value_type)>=sizeof(lua_Integer))||(sizeof(value_type)>sizeof(lua_Integer))) {
				return static_cast<T>(lua_tonumber(L, index));
			} else {
				return static_cast<T>(lua_tointeger(L, index));
			}
		}

		void to_lua_deferred(lua_State* L, param_type value)
		{
			if((std::is_unsigned<value_type>::value && sizeof(value_type)>=sizeof(lua_Integer))||(sizeof(value_type)>sizeof(lua_Integer)))
			{
				lua_pushnumber(L, value);
			} else {
				lua_pushinteger(L, static_cast<lua_Integer>(value));
			}
		}
	};

	template <typename QualifiedT>
	struct number_converter
		: native_converter_base<typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type>
	{
		typedef typename std::remove_const<typename std::remove_reference<QualifiedT>::type>::type T;
		typedef typename native_converter_base<T>::param_type param_type;
		typedef typename native_converter_base<T>::value_type value_type;

		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index)==LUA_TNUMBER ? 0 : no_match;
		}

		static value_type to_cpp_deferred(lua_State* L, int index)
		{
			return static_cast<T>(lua_tonumber(L, index));
		}

		static void to_lua_deferred(lua_State* L, param_type value)
		{
			lua_pushnumber(L, static_cast<lua_Number>(value));
		}
	};

	template <>
	struct default_converter<bool>
		: native_converter_base<bool>
	{
		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index)==LUA_TBOOLEAN ? 0 : no_match;
		}

		static bool to_cpp_deferred(lua_State* L, int index)
		{
			return lua_toboolean(L, index) == 1;
		}

		static void to_lua_deferred(lua_State* L, bool value)
		{
			lua_pushboolean(L, value);
		}
	};

	template <>
	struct default_converter<bool const>
		: default_converter<bool>
	{};

	template <>
	struct default_converter<bool const&>
		: default_converter<bool>
	{};

	template <>
	struct default_converter<std::string>
		: native_converter_base<std::string>
	{
		static int compute_score(lua_State* L, int index)
		{
			return lua_type(L, index)==LUA_TSTRING ? 0 : no_match;
		}

		static std::string to_cpp_deferred(lua_State* L, int index)
		{
			return std::string(lua_tostring(L, index), lua_rawlen(L, index));
		}

		static void to_lua_deferred(lua_State* L, std::string const& value)
		{
			lua_pushlstring(L, value.data(), value.size());
		}
	};

	template <>
	struct default_converter<std::string&>
		: default_converter<std::string>
	{};

	template <>
	struct default_converter<std::string const>
		: default_converter<std::string>
	{};

	template <>
	struct default_converter<std::string const&>
		: default_converter<std::string>
	{};

	template <>
	struct default_converter<char const*>
	{
		typedef std::true_type is_native;

		enum { consumed_args = 1 };

		template <class U>
		static int match(lua_State* L, U, int index)
		{
			int type = lua_type(L, index);
			return (type == LUA_TSTRING || type == LUA_TNIL) ? 0 : no_match;
		}

		template <class U>
		static char const* to_cpp(lua_State* L, U, int index)
		{
			return lua_tostring(L, index);
		}

		static void to_lua(lua_State* L, char const* str)
		{
			lua_pushstring(L, str);
		}

		template <class U>
		void converter_postcall(lua_State*, U, int)
		{}
	};

	template <>
	struct default_converter<const char* const>
		: default_converter<char const*>
	{};

	template <>
	struct default_converter<const char* const&>
		: default_converter<char const*>
	{};

	template <>
	struct default_converter<const char*&>
		: default_converter<char const*>
	{};

	template <>
	struct default_converter<char*>
		: default_converter<char const*>
	{};

	template <std::size_t N>
	struct default_converter<char const[N]>
		: default_converter<char const*>
	{};

	template <std::size_t N>
	struct default_converter<char[N]>
		: default_converter<char const*>
	{};

	template <std::size_t N>
	struct default_converter <const char(&)[N]>
		: default_converter<char const*>
	{};

	template <typename T>
	struct default_converter < T, typename std::enable_if< std::is_integral<typename std::remove_reference<T>::type>::value >::type >
		: integer_converter<T>
	{
	};

	template <typename T>
	struct default_converter < T, typename std::enable_if< std::is_floating_point<typename std::remove_reference<T>::type>::value >::type >
		: number_converter<T>
	{
	};

}

#if LUA_VERSION_NUM < 502
# undef lua_rawlen
#endif

#endif

<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2016 WandererFan <wandererfan@gmail.com>                *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <QPainter>
#include <QPainterPathStroker>
#include <QStyleOptionGraphicsItem>
#endif

#include <App/Application.h>
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>

#include <Mod/TechDraw/App/DrawUtil.h>

#include <qmath.h>
#include "Rez.h"
#include "QGIView.h"
#include "QGISectionLine.h"

using namespace TechDrawGui;

QGISectionLine::QGISectionLine()
{
    m_symbol = "";
    m_symSize = 0.0;

    m_extLen = 1.5 * Rez::guiX(QGIArrow::getPrefArrowSize());
    m_arrowSize = QGIArrow::getPrefArrowSize();

    m_line = new QGraphicsPathItem();
    addToGroup(m_line);
    m_arrow1 = new QGIArrow();
    addToGroup(m_arrow1);
    m_arrow2 = new QGIArrow();
    addToGroup(m_arrow2);
    m_symbol1 = new QGCustomText();
    addToGroup(m_symbol1);
    m_symbol2 = new QGCustomText();
    addToGroup(m_symbol2);

    setWidth(Rez::guiX(0.75));
    setStyle(getSectionStyle());
    setColor(getSectionColor());

}

void QGISectionLine::draw()
{
    prepareGeometryChange();
    makeLine();
    makeArrows();
    makeSymbols();
    update();
}

void QGISectionLine::makeLine()
{
    QPainterPath pp;
    QPointF beginExtLine1,beginExtLine2;   //ext line start pts for measure Start side and measure End side
    QPointF endExtLine1, endExtLine2;
    QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y);
    int format = getPrefSectionFormat();
    if (format == 0) {                           //"ASME"
        //draw from section line endpoint
        QPointF offsetBegin = m_extLen * offsetDir;
        beginExtLine1 = m_start;           //from
        beginExtLine2 = m_end;             //to
        endExtLine1 = m_start + offsetBegin;
        endExtLine2   = m_end + offsetBegin;
        pp.moveTo(beginExtLine1);
        pp.lineTo(endExtLine1);
        pp.moveTo(beginExtLine2);
        pp.lineTo(endExtLine2);
    } else {                                     //"ISO"
        //draw from just short of section line away from section line
        QPointF offsetBegin = Rez::guiX(QGIArrow::getOverlapAdjust(0,QGIArrow::getPrefArrowSize())) * offsetDir;
        QPointF offsetEnd   = offsetBegin + (m_extLen * offsetDir);
        beginExtLine1 = m_start - offsetBegin;
        beginExtLine2 = m_end - offsetBegin;
        endExtLine1 = m_start - offsetEnd;
        endExtLine2   = m_end - offsetEnd;
        pp.moveTo(beginExtLine1);
        pp.lineTo(endExtLine1);
        pp.moveTo(beginExtLine2);
        pp.lineTo(endExtLine2);
    }

    pp.moveTo(m_end);
    pp.lineTo(m_start);          //sectionLine
    m_line->setPath(pp);
}

void QGISectionLine::makeArrows()
{
    int format = getPrefSectionFormat();
    if (format == 0) {
        makeArrowsTrad();
    } else {
        makeArrowsISO();
    }
}

//make Euro (ISO) Arrows
void QGISectionLine::makeArrowsISO()
{
    double arrowRotation = 0.0;
    m_arrowDir.Normalize();
    double angle = atan2f(m_arrowDir.y,m_arrowDir.x);
    if (angle < 0.0) {
        angle = 2 * M_PI + angle;
    }
    arrowRotation = 360.0 - angle * (180.0/M_PI);   //convert to Qt rotation (clockwise degrees)

    m_arrow1->setStyle(0);
    m_arrow1->setSize(QGIArrow::getPrefArrowSize());
    m_arrow1->setPos(m_start);
    m_arrow1->draw();
    m_arrow1->setRotation(arrowRotation);                   //rotation = 0  ==>  ->  horizontal, pointing right

    m_arrow2->setStyle(0);
    m_arrow2->setSize(QGIArrow::getPrefArrowSize());
    m_arrow2->setPos(m_end);
    m_arrow2->draw();
    m_arrow2->setRotation(arrowRotation);
}

//make traditional (ASME) section arrows
void QGISectionLine::makeArrowsTrad()
{
    double arrowRotation = 0.0;
    m_arrowDir.Normalize();
    double angle = atan2f(m_arrowDir.y,m_arrowDir.x);
    if (angle < 0.0) {
        angle = 2 * M_PI + angle;
    }
    arrowRotation = 360.0 - angle * (180.0/M_PI);   //convert to Qt rotation (clockwise degrees)

    QPointF posArrow1,posArrow2;
    QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y);              //remember Y dir is flipped
    double offsetLength = m_extLen + Rez::guiX(QGIArrow::getOverlapAdjust(0,QGIArrow::getPrefArrowSize()));
    QPointF offsetVec = offsetLength * offsetDir;
    posArrow1 = m_start + offsetVec;
    posArrow2 = m_end + offsetVec;

    m_arrow1->setStyle(0);
    m_arrow1->setSize(QGIArrow::getPrefArrowSize());
    m_arrow1->setPos(posArrow1);
    m_arrow1->draw();
    m_arrow1->setRotation(arrowRotation);                   //rotation = 0  ==>  ->  horizontal, pointing right

    m_arrow2->setStyle(0);
    m_arrow2->setSize(QGIArrow::getPrefArrowSize());
    m_arrow2->setPos(posArrow2);
    m_arrow2->draw();
    m_arrow2->setRotation(arrowRotation);
}

void QGISectionLine::makeSymbols()
{
    int format = getPrefSectionFormat();
    if (format == 0) {
        makeSymbolsTrad();
    } else {
        makeSymbolsISO();
    }
}

void QGISectionLine::makeSymbolsTrad()
{
    QPointF extLineStart,extLineEnd;
    QPointF offset(m_arrowDir.x,-m_arrowDir.y);
    offset = 1.5 * m_extLen * offset;
    extLineStart = m_start + offset;
    extLineEnd = m_end + offset;
    prepareGeometryChange();
    m_symFont.setPixelSize(QGIView::calculateFontPixelSize(m_symSize));
    m_symbol1->setFont(m_symFont);
    m_symbol1->setPlainText(QString::fromUtf8(m_symbol));
    if (m_arrowDir.y < 0.0) {         //pointing down
        extLineStart  += QPointF (0.0, m_symSize);  //move text down a bit
    } else if (m_arrowDir.y >  0.0) {  //pointing up
        extLineStart  -= QPointF (0.0, m_symSize);  //move text up a bit
    }
    if (m_arrowDir.x < 0.0) {         //pointing left
        extLineStart  -= QPointF (m_symSize, 0.0);  //move text left a bit
    } else if (m_arrowDir.x >  0.0) {  //pointing rightup
        extLineStart  += QPointF (m_symSize, 0.0);  //move text right a bit
    }
    m_symbol1->centerAt(extLineStart);

    m_symbol2->setFont(m_symFont);
    m_symbol2->setPlainText(QString::fromUtf8(m_symbol));
    if (m_arrowDir.y < 0.0) {         //pointing down
        extLineEnd  += QPointF (0.0, m_symSize);  //move text down a bit
    } else if (m_arrowDir.y > 0.0) {  //pointing up
        extLineEnd  -= QPointF (0.0, m_symSize);  //move text up a bit
    }
     if (m_arrowDir.x < 0.0) {         //pointing left
        extLineEnd  -= QPointF (m_symSize, 0.0);  //move text left a bit
    } else if (m_arrowDir.x >  0.0) {  //pointing rightup
        extLineEnd  += QPointF (m_symSize, 0.0);  //move text right a bit
    }
    m_symbol2->centerAt(extLineEnd);

}

void QGISectionLine::makeSymbolsISO()
{
    QPointF symPosStart, symPosEnd;
    QPointF dist = (m_start - m_end);
    double lenDist = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
    QPointF distDir = dist / lenDist;

    QPointF offset = m_extLen * distDir;
    symPosStart = m_start + offset;
    symPosEnd = m_end - offset;

    prepareGeometryChange();
    m_symFont.setPixelSize(QGIView::calculateFontPixelSize(m_symSize));
    m_symbol1->setFont(m_symFont);
    m_symbol1->setPlainText(QString::fromUtf8(m_symbol));
    m_symbol1->centerAt(symPosStart);

    m_symbol2->setFont(m_symFont);
    m_symbol2->setPlainText(QString::fromUtf8(m_symbol));
    m_symbol2->centerAt(symPosEnd);

}

void QGISectionLine::setBounds(double x1,double y1,double x2,double y2)
{
    m_start = QPointF(x1,y1);
    m_end = QPointF(x2,y2);
}

void QGISectionLine::setSymbol(char* sym)
{
    m_symbol = sym;
}

void QGISectionLine::setDirection(double xDir,double yDir)
{
    Base::Vector3d newDir(xDir,yDir,0.0);
    setDirection(newDir);
}

void QGISectionLine::setDirection(Base::Vector3d dir)
{
    m_arrowDir = dir;
}

void QGISectionLine::setFont(QFont f, double fsize)
{
    m_symFont = f;
    m_symSize = fsize;
}

QColor QGISectionLine::getSectionColor()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
        .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
    App::Color fcColor = App::Color((uint32_t) hGrp->GetUnsigned("SectionColor", 0x00000000));
    return fcColor.asValue<QColor>();
}

//SectionLineStyle
Qt::PenStyle QGISectionLine::getSectionStyle()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                         GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    Qt::PenStyle sectStyle = static_cast<Qt::PenStyle> (hGrp->GetInt("SectionLine", 2));
    return sectStyle;
}

//ASME("traditional") vs ISO("reference arrow method") arrows
int QGISectionLine::getPrefSectionFormat()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().
                                         GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Format");
    int format = hGrp->GetInt("SectionFormat", 0);
    return format;
}

void QGISectionLine::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
    QStyleOptionGraphicsItem myOption(*option);
    myOption.state &= ~QStyle::State_Selected;

    setTools();
    QGIDecoration::paint (painter, &myOption, widget);
}

void QGISectionLine::setTools()
{
    // Use our own style
    if (m_styleCurrent == Qt::DashDotLine) {
        QVector<qreal> dashes;
        // the stroke width is double the one of center lines, but we like to
        // have the same spacing. thus these values must be half as large
        qreal space = 2;  // in unit r_width
        qreal dash = 8;
        // dot must be really small when using CapStyle RoundCap but > 0
        // for CapStyle FlatCap you would need to set it to 1
        qreal dot = 0.000001;

        dashes << dot << space << dash << space;

        // TODO for fanciness: calculate the offset so both arrows start with a
        // dash!

        m_pen.setDashPattern(dashes);

        m_pen.setDashOffset(2);
    }
    else {
        m_pen.setStyle(m_styleCurrent);
    }
    m_pen.setWidthF(m_width);
    m_pen.setColor(m_colCurrent);
    m_pen.setCapStyle(Qt::RoundCap);
    m_brush.setStyle(m_brushCurrent);
    m_brush.setColor(m_colCurrent);

    m_line->setPen(m_pen);

//    m_arrow1->setPen(m_pen);
//    m_arrow2->setPen(m_pen);
//    m_arrow1->setBrush(m_brush);
//    m_arrow2->setBrush(m_brush);
    m_arrow1->setPrettyNormal();
    m_arrow2->setPrettyNormal();

    m_symbol1->setDefaultTextColor(m_colCurrent);
    m_symbol2->setDefaultTextColor(m_colCurrent);
}
<commit_msg>[TD]adjust symbol location for font and text<commit_after>/***************************************************************************
 *   Copyright (c) 2016 WandererFan <wandererfan@gmail.com>                *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"
#ifndef _PreComp_
#include <QPainter>
#include <QPainterPathStroker>
#include <QStyleOptionGraphicsItem>
#endif

#include <App/Application.h>
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Parameter.h>

#include <Mod/TechDraw/App/DrawUtil.h>

#include <qmath.h>
#include "Rez.h"
#include "QGIView.h"
#include "QGISectionLine.h"

using namespace TechDrawGui;
using namespace TechDraw;

QGISectionLine::QGISectionLine()
{
    m_symbol = "";
    m_symSize = 0.0;

    m_extLen = 1.5 * Rez::guiX(QGIArrow::getPrefArrowSize());
    m_arrowSize = QGIArrow::getPrefArrowSize();

    m_line = new QGraphicsPathItem();
    addToGroup(m_line);
    m_arrow1 = new QGIArrow();
    addToGroup(m_arrow1);
    m_arrow2 = new QGIArrow();
    addToGroup(m_arrow2);
    m_symbol1 = new QGCustomText();
    addToGroup(m_symbol1);
    m_symbol2 = new QGCustomText();
    addToGroup(m_symbol2);

    setWidth(Rez::guiX(0.75));
    setStyle(getSectionStyle());
    setColor(getSectionColor());

}

void QGISectionLine::draw()
{
    prepareGeometryChange();
    makeLine();
    makeArrows();
    makeSymbols();
    update();
}

void QGISectionLine::makeLine()
{
    QPainterPath pp;
    QPointF beginExtLine1,beginExtLine2;   //ext line start pts for measure Start side and measure End side
    QPointF endExtLine1, endExtLine2;
    QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y);
    int format = getPrefSectionFormat();
    if (format == 0) {                           //"ASME"
        //draw from section line endpoint
        QPointF offsetBegin = m_extLen * offsetDir;
        beginExtLine1 = m_start;           //from
        beginExtLine2 = m_end;             //to
        endExtLine1 = m_start + offsetBegin;
        endExtLine2   = m_end + offsetBegin;
        pp.moveTo(beginExtLine1);
        pp.lineTo(endExtLine1);
        pp.moveTo(beginExtLine2);
        pp.lineTo(endExtLine2);
    } else {                                     //"ISO"
        //draw from just short of section line away from section line
        QPointF offsetBegin = Rez::guiX(QGIArrow::getOverlapAdjust(0,QGIArrow::getPrefArrowSize())) * offsetDir;
        QPointF offsetEnd   = offsetBegin + (m_extLen * offsetDir);
        beginExtLine1 = m_start - offsetBegin;
        beginExtLine2 = m_end - offsetBegin;
        endExtLine1 = m_start - offsetEnd;
        endExtLine2   = m_end - offsetEnd;
        pp.moveTo(beginExtLine1);
        pp.lineTo(endExtLine1);
        pp.moveTo(beginExtLine2);
        pp.lineTo(endExtLine2);
    }

    pp.moveTo(m_end);
    pp.lineTo(m_start);          //sectionLine
    m_line->setPath(pp);
}

void QGISectionLine::makeArrows()
{
    int format = getPrefSectionFormat();
    if (format == 0) {
        makeArrowsTrad();
    } else {
        makeArrowsISO();
    }
}

//make Euro (ISO) Arrows
void QGISectionLine::makeArrowsISO()
{
    double arrowRotation = 0.0;
    m_arrowDir.Normalize();
    double angle = atan2f(m_arrowDir.y,m_arrowDir.x);
    if (angle < 0.0) {
        angle = 2 * M_PI + angle;
    }
    arrowRotation = 360.0 - angle * (180.0/M_PI);   //convert to Qt rotation (clockwise degrees)

    m_arrow1->setStyle(0);
    m_arrow1->setSize(QGIArrow::getPrefArrowSize());
    m_arrow1->setPos(m_start);
    m_arrow1->draw();
    m_arrow1->setRotation(arrowRotation);                   //rotation = 0  ==>  ->  horizontal, pointing right

    m_arrow2->setStyle(0);
    m_arrow2->setSize(QGIArrow::getPrefArrowSize());
    m_arrow2->setPos(m_end);
    m_arrow2->draw();
    m_arrow2->setRotation(arrowRotation);
}

//make traditional (ASME) section arrows
void QGISectionLine::makeArrowsTrad()
{
    double arrowRotation = 0.0;
    m_arrowDir.Normalize();
    double angle = atan2f(m_arrowDir.y,m_arrowDir.x);
    if (angle < 0.0) {
        angle = 2 * M_PI + angle;
    }
    arrowRotation = 360.0 - angle * (180.0/M_PI);   //convert to Qt rotation (clockwise degrees)

    QPointF posArrow1,posArrow2;
    QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y);              //remember Y dir is flipped
    double offsetLength = m_extLen + Rez::guiX(QGIArrow::getOverlapAdjust(0,QGIArrow::getPrefArrowSize()));
    QPointF offsetVec = offsetLength * offsetDir;
    posArrow1 = m_start + offsetVec;
    posArrow2 = m_end + offsetVec;

    m_arrow1->setStyle(0);
    m_arrow1->setSize(QGIArrow::getPrefArrowSize());
    m_arrow1->setPos(posArrow1);
    m_arrow1->draw();
    m_arrow1->setRotation(arrowRotation);                   //rotation = 0  ==>  ->  horizontal, pointing right

    m_arrow2->setStyle(0);
    m_arrow2->setSize(QGIArrow::getPrefArrowSize());
    m_arrow2->setPos(posArrow2);
    m_arrow2->draw();
    m_arrow2->setRotation(arrowRotation);
}

void QGISectionLine::makeSymbols()
{
    int format = getPrefSectionFormat();
    if (format == 0) {
        makeSymbolsTrad();
    } else {
        makeSymbolsISO();
    }
}

void QGISectionLine::makeSymbolsTrad()
{
    QPointF extLineStart,extLineEnd;
    QPointF offset(m_arrowDir.x,-m_arrowDir.y);
    offset = 1.5 * m_extLen * offset;
    extLineStart = m_start + offset;
    extLineEnd = m_end + offset;
    prepareGeometryChange();
    m_symFont.setPixelSize(QGIView::calculateFontPixelSize(m_symSize));
    m_symbol1->setFont(m_symFont);
    m_symbol1->setPlainText(QString::fromUtf8(m_symbol));

    QRectF symRect = m_symbol1->boundingRect();
    double symWidth = symRect.width();
    double symHeight = symRect.height();
    double symbolFudge = 1.0;
    double angle = atan2f(m_arrowDir.y,m_arrowDir.x);
    if (angle < 0.0) {
        angle = 2 * M_PI + angle;
    }
    Base::Vector3d adjustVector(cos(angle) * symWidth, sin(angle) * symHeight, 0.0);
    adjustVector = (DrawUtil::invertY(adjustVector) / 2.0) * symbolFudge;
    QPointF qAdjust(adjustVector.x, adjustVector.y);

    extLineStart += qAdjust;
    m_symbol1->centerAt(extLineStart);

    m_symbol2->setFont(m_symFont);
    m_symbol2->setPlainText(QString::fromUtf8(m_symbol));
    extLineEnd += qAdjust;
    m_symbol2->centerAt(extLineEnd);
}

void QGISectionLine::makeSymbolsISO()
{
    QPointF symPosStart, symPosEnd;
    QPointF dist = (m_start - m_end);
    double lenDist = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
    QPointF distDir = dist / lenDist;

    QPointF offset = m_extLen * distDir;
    symPosStart = m_start + offset;
    symPosEnd = m_end - offset;

    prepareGeometryChange();
    m_symFont.setPixelSize(QGIView::calculateFontPixelSize(m_symSize));
    m_symbol1->setFont(m_symFont);
    m_symbol1->setPlainText(QString::fromUtf8(m_symbol));
    m_symbol1->centerAt(symPosStart);

    m_symbol2->setFont(m_symFont);
    m_symbol2->setPlainText(QString::fromUtf8(m_symbol));
    m_symbol2->centerAt(symPosEnd);

}

void QGISectionLine::setBounds(double x1,double y1,double x2,double y2)
{
    m_start = QPointF(x1,y1);
    m_end = QPointF(x2,y2);
}

void QGISectionLine::setSymbol(char* sym)
{
    m_symbol = sym;
}

void QGISectionLine::setDirection(double xDir,double yDir)
{
    Base::Vector3d newDir(xDir,yDir,0.0);
    setDirection(newDir);
}

void QGISectionLine::setDirection(Base::Vector3d dir)
{
    m_arrowDir = dir;
}

void QGISectionLine::setFont(QFont f, double fsize)
{
    m_symFont = f;
    m_symSize = fsize;
}

QColor QGISectionLine::getSectionColor()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
        .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
    App::Color fcColor = App::Color((uint32_t) hGrp->GetUnsigned("SectionColor", 0x00000000));
    return fcColor.asValue<QColor>();
}

//SectionLineStyle
Qt::PenStyle QGISectionLine::getSectionStyle()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().GetGroup("BaseApp")->
                                         GetGroup("Preferences")->GetGroup("Mod/TechDraw/Decorations");
    Qt::PenStyle sectStyle = static_cast<Qt::PenStyle> (hGrp->GetInt("SectionLine", 2));
    return sectStyle;
}

//ASME("traditional") vs ISO("reference arrow method") arrows
int QGISectionLine::getPrefSectionFormat()
{
    Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter().
                                         GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Format");
    int format = hGrp->GetInt("SectionFormat", 0);
    return format;
}

void QGISectionLine::paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {
    QStyleOptionGraphicsItem myOption(*option);
    myOption.state &= ~QStyle::State_Selected;

    setTools();
    QGIDecoration::paint (painter, &myOption, widget);
}

void QGISectionLine::setTools()
{
    // Use our own style
    if (m_styleCurrent == Qt::DashDotLine) {
        QVector<qreal> dashes;
        // the stroke width is double the one of center lines, but we like to
        // have the same spacing. thus these values must be half as large
        qreal space = 2;  // in unit r_width
        qreal dash = 8;
        // dot must be really small when using CapStyle RoundCap but > 0
        // for CapStyle FlatCap you would need to set it to 1
        qreal dot = 0.000001;

        dashes << dot << space << dash << space;

        // TODO for fanciness: calculate the offset so both arrows start with a
        // dash!

        m_pen.setDashPattern(dashes);

        m_pen.setDashOffset(2);
    }
    else {
        m_pen.setStyle(m_styleCurrent);
    }
    m_pen.setWidthF(m_width);
    m_pen.setColor(m_colCurrent);
    m_pen.setCapStyle(Qt::RoundCap);
    m_brush.setStyle(m_brushCurrent);
    m_brush.setColor(m_colCurrent);

    m_line->setPen(m_pen);

//    m_arrow1->setPen(m_pen);
//    m_arrow2->setPen(m_pen);
//    m_arrow1->setBrush(m_brush);
//    m_arrow2->setBrush(m_brush);
    m_arrow1->setPrettyNormal();
    m_arrow2->setPrettyNormal();

    m_symbol1->setDefaultTextColor(m_colCurrent);
    m_symbol2->setDefaultTextColor(m_colCurrent);
}
<|endoftext|>


<commit_before>#include <string>
#include <map>
#include <sys/types.h>
#include <sys/stat.h>

#include "macros.h"
#include "cache.h"
#include "common.h"

#ifndef windows
#   include <dlfcn.h>
#else
#   include <windows.h>
#   define dlopen(x,y) (void*)LoadLibrary(x)
#   define dlclose(x) FreeLibrary((HMODULE)x)
#endif

/**
 * Is this file already cached?
 */
bool Cache::isCached(std::string filename) {
	struct stat st;
	int result = stat(filename.c_str(), &st);
	if (result != 0) { return false; }

	TimeValue::iterator it = modified.find(filename);
	if (it == modified.end()) { return false; } /* not seen yet */

	if (it->second != st.st_mtime) { /* was modified */
		erase(filename);
		return false;
	}
	return true;
}

/**
 * Mark filename as "cached"
 * */
void Cache::mark(std::string filename) {
	struct stat st;
	stat(filename.c_str(), &st);
	modified[filename] = st.st_mtime;
}

/**
 * Remove file from all available caches
 */
void Cache::erase(std::string filename) {
	HandleValue::iterator it2 = handles.find(filename);
	if (it2 != handles.end()) {
		dlclose(it2->second);
		handles.erase(it2);
	}

	ScriptValue::iterator it3 = scripts.find(filename);
	if (it3 != scripts.end()) {
		it3->second.Dispose();
		scripts.erase(it3);
	}
}

/**
 * Return source code for a given file
 */
std::string Cache::getSource(std::string filename) {
	FILE * file = fopen(filename.c_str(), "rb");
	if (file == NULL) {
		std::string s = "Error reading '";
		s += filename;
		s += "'";
		throw s;
	}

	fseek(file, 0, SEEK_END);
	size_t size = ftell(file);
	rewind(file);
	char* chars = new char[size + 1];
	chars[size] = '\0';
	for (unsigned int i = 0; i < size;) {
		size_t read = fread(&chars[i], 1, size - i, file);
		i += read;
	}
	fclose(file);
	std::string source = chars;
	delete[] chars;

	/* remove shebang line */
	if (source.find('#',0) == 0 && source.find('!',1) == 1 ) {
		unsigned int pfix = source.find('\n',0);
		source.erase(0,pfix);
	};

	source = this->wrapExports(source);
	return source;
}

/**
 * Return dlopen handle for a given file
 */
void * Cache::getHandle(std::string filename) {
#ifdef VERBOSE
	printf("[getHandle] cache try for '%s' .. ", filename.c_str());
#endif
	if (this->isCached(filename)) {
#ifdef VERBOSE
		printf("cache hit\n");
#endif
		HandleValue::iterator it = handles.find(filename);
		return it->second;
	} else {
#ifdef VERBOSE
		printf("cache miss\n");
#endif
		void * handle = dlopen(filename.c_str(), RTLD_LAZY);
		if (!handle) {
			std::string error = "Error opening shared library '";
			error += filename;
			error += "'";
			throw error;
		}
		this->mark(filename); /* mark as cached */
		handles[filename] = handle;
		return handle;
	}
}

/**
 * Return compiled script from a given file
 */
v8::Handle<v8::Script> Cache::getScript(std::string filename) {
#ifdef VERBOSE
	printf("[getScript] cache try for '%s' .. ", filename.c_str());
#endif
	if (this->isCached(filename)) {
#ifdef VERBOSE
		printf("[getScript] cache hit\n");
#endif
		ScriptValue::iterator it = scripts.find(filename);
		return it->second;
	} else {
#ifdef VERBOSE
		printf("[getScript] cache miss\n");
#endif
		std::string source = this->getSource(filename);
		/* context-independent compiled script */
		v8::Handle<v8::Script> script = v8::Script::New(JS_STR(source.c_str()), JS_STR(filename.c_str()));
		if (!script.IsEmpty()) {
			this->mark(filename); /* mark as cached */
			v8::Persistent<v8::Script> result = v8::Persistent<v8::Script>::New(script);
			scripts[filename] = result;
			return result;
		}
		return script;
	}
}

/**
 * Return exports object for a given file
 */
v8::Handle<v8::Object> Cache::getExports(std::string filename) {
	ExportsValue::iterator it = exports.find(filename);
	if (it != exports.end()) {
#ifdef VERBOSE
		printf("[getExports] using cached exports for '%s'\n", filename.c_str());
#endif
		return it->second;
	} else {
#ifdef VERBOSE
		printf("[getExports] '%s' has no cached exports\n", filename.c_str());
#endif
		return v8::Handle<v8::Object>::Handle();
	}
}

/**
 * Add a single item to exports cache
 */
void Cache::addExports(std::string filename, v8::Handle<v8::Object> obj) {
#ifdef VERBOSE
		printf("[addExports] caching exports for '%s'\n", filename.c_str());
#endif
	exports[filename] = v8::Persistent<v8::Object>::New(obj);
}

/**
 * Remove a cached exports object
 */
void Cache::removeExports(std::string filename) {
#ifdef VERBOSE
		printf("[removeExports] removing exports for '%s'\n", filename.c_str());
#endif
	ExportsValue::iterator it = exports.find(filename);
	if (it != exports.end()) {
		it->second.Dispose();
		it->second.Clear();
		exports.erase(it);
	}
}

/**
 * Remove all cached exports
 */
void Cache::clearExports() {
	ExportsValue::iterator it;
	for (it=exports.begin(); it != exports.end(); it++) {
		it->second.Dispose();
		it->second.Clear();
	}
	exports.clear();
}

/**
 * Wrap a string with exports envelope
 */
std::string Cache::wrapExports(std::string code) {
	std::string result = "";
	result += "(function(require,include,exports,module){";
	result += code;
	result += "})";
	return result;
}
<commit_msg>removed redundant cache handle<commit_after>#include <string>
#include <map>
#include <sys/types.h>
#include <sys/stat.h>

#include "macros.h"
#include "cache.h"
#include "common.h"

#ifndef windows
#   include <dlfcn.h>
#else
#   include <windows.h>
#   define dlopen(x,y) (void*)LoadLibrary(x)
#   define dlclose(x) FreeLibrary((HMODULE)x)
#endif

/**
 * Is this file already cached?
 */
bool Cache::isCached(std::string filename) {
	struct stat st;
	int result = stat(filename.c_str(), &st);
	if (result != 0) { return false; }

	TimeValue::iterator it = modified.find(filename);
	if (it == modified.end()) { return false; } /* not seen yet */

	if (it->second != st.st_mtime) { /* was modified */
		erase(filename);
		return false;
	}
	return true;
}

/**
 * Mark filename as "cached"
 * */
void Cache::mark(std::string filename) {
	struct stat st;
	stat(filename.c_str(), &st);
	modified[filename] = st.st_mtime;
}

/**
 * Remove file from all available caches
 */
void Cache::erase(std::string filename) {
	HandleValue::iterator it2 = handles.find(filename);
	if (it2 != handles.end()) {
		dlclose(it2->second);
		handles.erase(it2);
	}

	ScriptValue::iterator it3 = scripts.find(filename);
	if (it3 != scripts.end()) {
		it3->second.Dispose();
		scripts.erase(it3);
	}
}

/**
 * Return source code for a given file
 */
std::string Cache::getSource(std::string filename) {
	FILE * file = fopen(filename.c_str(), "rb");
	if (file == NULL) {
		std::string s = "Error reading '";
		s += filename;
		s += "'";
		throw s;
	}

	fseek(file, 0, SEEK_END);
	size_t size = ftell(file);
	rewind(file);
	char* chars = new char[size + 1];
	chars[size] = '\0';
	for (unsigned int i = 0; i < size;) {
		size_t read = fread(&chars[i], 1, size - i, file);
		i += read;
	}
	fclose(file);
	std::string source = chars;
	delete[] chars;

	/* remove shebang line */
	if (source.find('#',0) == 0 && source.find('!',1) == 1 ) {
		unsigned int pfix = source.find('\n',0);
		source.erase(0,pfix);
	};

	source = this->wrapExports(source);
	return source;
}

/**
 * Return dlopen handle for a given file
 */
void * Cache::getHandle(std::string filename) {
#ifdef VERBOSE
	printf("[getHandle] cache try for '%s' .. ", filename.c_str());
#endif
	if (this->isCached(filename)) {
#ifdef VERBOSE
		printf("cache hit\n");
#endif
		HandleValue::iterator it = handles.find(filename);
		return it->second;
	} else {
#ifdef VERBOSE
		printf("cache miss\n");
#endif
		void * handle = dlopen(filename.c_str(), RTLD_LAZY);
		if (!handle) {
			std::string error = "Error opening shared library '";
			error += filename;
			error += "'";
			throw error;
		}
		this->mark(filename); /* mark as cached */
		handles[filename] = handle;
		return handle;
	}
}

/**
 * Return compiled script from a given file
 */
v8::Handle<v8::Script> Cache::getScript(std::string filename) {
#ifdef VERBOSE
	printf("[getScript] cache try for '%s' .. ", filename.c_str());
#endif
	if (this->isCached(filename)) {
#ifdef VERBOSE
		printf("[getScript] cache hit\n");
#endif
		ScriptValue::iterator it = scripts.find(filename);
		return it->second;
	} else {
#ifdef VERBOSE
		printf("[getScript] cache miss\n");
#endif
		std::string source = this->getSource(filename);
		/* context-independent compiled script */
		v8::Handle<v8::Script> script = v8::Script::New(JS_STR(source.c_str()), JS_STR(filename.c_str()));
		if (!script.IsEmpty()) {
			this->mark(filename); /* mark as cached */
			v8::Persistent<v8::Script> result = v8::Persistent<v8::Script>::New(script);
			scripts[filename] = result;
			return result;
		}
		return script;
	}
}

/**
 * Return exports object for a given file
 */
v8::Handle<v8::Object> Cache::getExports(std::string filename) {
	ExportsValue::iterator it = exports.find(filename);
	if (it != exports.end()) {
#ifdef VERBOSE
		printf("[getExports] using cached exports for '%s'\n", filename.c_str());
#endif
		return it->second;
	} else {
#ifdef VERBOSE
		printf("[getExports] '%s' has no cached exports\n", filename.c_str());
#endif
		return v8::Handle<v8::Object>();
	}
}

/**
 * Add a single item to exports cache
 */
void Cache::addExports(std::string filename, v8::Handle<v8::Object> obj) {
#ifdef VERBOSE
		printf("[addExports] caching exports for '%s'\n", filename.c_str());
#endif
	exports[filename] = v8::Persistent<v8::Object>::New(obj);
}

/**
 * Remove a cached exports object
 */
void Cache::removeExports(std::string filename) {
#ifdef VERBOSE
		printf("[removeExports] removing exports for '%s'\n", filename.c_str());
#endif
	ExportsValue::iterator it = exports.find(filename);
	if (it != exports.end()) {
		it->second.Dispose();
		it->second.Clear();
		exports.erase(it);
	}
}

/**
 * Remove all cached exports
 */
void Cache::clearExports() {
	ExportsValue::iterator it;
	for (it=exports.begin(); it != exports.end(); it++) {
		it->second.Dispose();
		it->second.Clear();
	}
	exports.clear();
}

/**
 * Wrap a string with exports envelope
 */
std::string Cache::wrapExports(std::string code) {
	std::string result = "";
	result += "(function(require,include,exports,module){";
	result += code;
	result += "})";
	return result;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "leveldbwrapper.h"

#include "util.h"

#include <boost/filesystem.hpp>
#include <leveldb/cache.h>
#include <leveldb/env.h>
#include <leveldb/filter_policy.h>
#include <memenv.h>

void HandleError(const leveldb::Status &status) throw(leveldb_error) {
    if (status.ok())
        return;
    LogPrintf("%s\n", status.ToString());
    if (status.IsCorruption())
        throw leveldb_error("Database corrupted");
    if (status.IsIOError())
        throw leveldb_error("Database I/O error");
    if (status.IsNotFound())
        throw leveldb_error("Database entry missing");
    throw leveldb_error("Unknown database error");
}

static leveldb::Options GetOptions(size_t nCacheSize) {
    leveldb::Options options;
    options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
    options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
    options.filter_policy = leveldb::NewBloomFilterPolicy(10);
    options.compression = leveldb::kNoCompression;
    options.max_open_files = 64;
    return options;
}

CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe) {
    penv = NULL;
    readoptions.verify_checksums = true;
    iteroptions.verify_checksums = true;
    iteroptions.fill_cache = false;
    syncoptions.sync = true;
    options = GetOptions(nCacheSize);
    options.create_if_missing = true;
    if (fMemory) {
        penv = leveldb::NewMemEnv(leveldb::Env::Default());
        options.env = penv;
    } else {
        if (fWipe) {
            LogPrintf("Wiping LevelDB in %s\n", path.string());
            leveldb::DestroyDB(path.string(), options);
        }
        TryCreateDirectory(path);
        LogPrintf("Opening LevelDB in %s\n", path.string());
    }
    leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
    HandleError(status);
    LogPrintf("Opened LevelDB successfully\n");
}

CLevelDBWrapper::~CLevelDBWrapper() {
    delete pdb;
    pdb = NULL;
    delete options.filter_policy;
    options.filter_policy = NULL;
    delete options.block_cache;
    options.block_cache = NULL;
    delete penv;
    options.env = NULL;
}

bool CLevelDBWrapper::WriteBatch(CLevelDBBatch &batch, bool fSync) throw(leveldb_error) {
    leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
    HandleError(status);
    return true;
}
<commit_msg>Enable paranoid corruption checks in LevelDB >= 1.16<commit_after>// Copyright (c) 2012-2014 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "leveldbwrapper.h"

#include "util.h"

#include <boost/filesystem.hpp>
#include <leveldb/cache.h>
#include <leveldb/env.h>
#include <leveldb/filter_policy.h>
#include <memenv.h>

void HandleError(const leveldb::Status &status) throw(leveldb_error) {
    if (status.ok())
        return;
    LogPrintf("%s\n", status.ToString());
    if (status.IsCorruption())
        throw leveldb_error("Database corrupted");
    if (status.IsIOError())
        throw leveldb_error("Database I/O error");
    if (status.IsNotFound())
        throw leveldb_error("Database entry missing");
    throw leveldb_error("Unknown database error");
}

static leveldb::Options GetOptions(size_t nCacheSize) {
    leveldb::Options options;
    options.block_cache = leveldb::NewLRUCache(nCacheSize / 2);
    options.write_buffer_size = nCacheSize / 4; // up to two write buffers may be held in memory simultaneously
    options.filter_policy = leveldb::NewBloomFilterPolicy(10);
    options.compression = leveldb::kNoCompression;
    options.max_open_files = 64;
    if (leveldb::kMajorVersion > 1 || (leveldb::kMajorVersion == 1 && leveldb::kMinorVersion >= 16)) {
        // LevelDB versions before 1.16 consider short writes to be corruption. Only trigger error
        // on corruption in later versions.
        options.paranoid_checks = true;
    }
    return options;
}

CLevelDBWrapper::CLevelDBWrapper(const boost::filesystem::path &path, size_t nCacheSize, bool fMemory, bool fWipe) {
    penv = NULL;
    readoptions.verify_checksums = true;
    iteroptions.verify_checksums = true;
    iteroptions.fill_cache = false;
    syncoptions.sync = true;
    options = GetOptions(nCacheSize);
    options.create_if_missing = true;
    if (fMemory) {
        penv = leveldb::NewMemEnv(leveldb::Env::Default());
        options.env = penv;
    } else {
        if (fWipe) {
            LogPrintf("Wiping LevelDB in %s\n", path.string());
            leveldb::DestroyDB(path.string(), options);
        }
        TryCreateDirectory(path);
        LogPrintf("Opening LevelDB in %s\n", path.string());
    }
    leveldb::Status status = leveldb::DB::Open(options, path.string(), &pdb);
    HandleError(status);
    LogPrintf("Opened LevelDB successfully\n");
}

CLevelDBWrapper::~CLevelDBWrapper() {
    delete pdb;
    pdb = NULL;
    delete options.filter_policy;
    options.filter_policy = NULL;
    delete options.block_cache;
    options.block_cache = NULL;
    delete penv;
    options.env = NULL;
}

bool CLevelDBWrapper::WriteBatch(CLevelDBBatch &batch, bool fSync) throw(leveldb_error) {
    leveldb::Status status = pdb->Write(fSync ? syncoptions : writeoptions, &batch.batch);
    HandleError(status);
    return true;
}
<|endoftext|>