<commit_before>// Theme.cc for FbTk - Fluxbox ToolKit
// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// 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.

// $Id: Theme.cc,v 1.13 2003/08/22 22:17:30 fluxgen Exp $

#include "Theme.hh"

#include "XrmDatabaseHelper.hh"
#include "Font.hh"
#include "Color.hh"
#include "Texture.hh"
#include "App.hh"
#include "Image.hh"
#include "PixmapWithMask.hh"

#include <cstdio>
#include <memory>
#include <iostream>
using namespace std;

namespace FbTk {

// create default handlers for Color, Font, Texture, int and string
template <>
void FbTk::ThemeItem<std::string>::load() { }

template <>
void FbTk::ThemeItem<std::string>::setDefaultValue() {
    *(*this) = "";
}

template <>
void FbTk::ThemeItem<std::string>::setFromString(const char *str) {
    *(*this) = (str ? str : "");
}

template <>
void FbTk::ThemeItem<int>::load() { }

template <>
void FbTk::ThemeItem<int>::setDefaultValue() {
    *(*this) = 0;
}

template <>
void FbTk::ThemeItem<int>::setFromString(const char *str) {
    if (str == 0)
        return;
    sscanf(str, "%d", &m_value);
}

template <>
void ThemeItem<FbTk::Font>::setDefaultValue() {
    if (!m_value.load("fixed")) {
        cerr<<"FbTk::ThemeItem<FbTk::Font>: Warning! Failed to load default value 'fixed'"<<endl;
    }
}

template <>
void ThemeItem<FbTk::Font>::setFromString(const char *str) {
    if (m_value.load(str) == false) {
        cerr<<"FbTk::Theme: Error loading font "<<
            ((m_value.isAntialias() || m_value.utf8()) ? "(" : "")<<

            (m_value.isAntialias() ? "antialias" : "")<<
            (m_value.utf8() ? " utf8" : "")<<

            ((m_value.isAntialias() || m_value.utf8()) ? ") " : "")<<
            "for \""<<name()<<"\" or \""<<altName()<<"\": "<<str<<endl;

        cerr<<"FbTk::Theme: Setting default value"<<endl;
        setDefaultValue();
    }

}

// do nothing
template <>
void ThemeItem<FbTk::Font>::load() {
}

template <>
void ThemeItem<FbTk::Texture>::setDefaultValue() {
    m_value.setType(FbTk::Texture::FLAT | FbTk::Texture::SOLID);
}

template <>
void ThemeItem<FbTk::Texture>::setFromString(const char *str) {
    m_value.setFromString(str);
    if (m_value.type() == 0) // failed to set value
        setDefaultValue();
}

template <>
void ThemeItem<FbTk::Texture>::load() {
    string color_name(ThemeManager::instance().
                      resourceValue(name()+".color", altName()+".Color"));
    string colorto_name(ThemeManager::instance().
                        resourceValue(name()+".colorTo", altName()+".ColorTo"));
    string pixmap_name(ThemeManager::instance().
                       resourceValue(name()+".pixmap", altName()+".Pixmap"));

    // set default value if we failed to load color
    if (!m_value.color().setFromString(color_name.c_str(), m_tm.screenNum()))
        m_value.color().setFromString("darkgray", m_tm.screenNum());

    if (!m_value.colorTo().setFromString(colorto_name.c_str(), m_tm.screenNum()))
        m_value.colorTo().setFromString("white", m_tm.screenNum());

    std::auto_ptr<PixmapWithMask> pm(Image::load(pixmap_name, m_tm.screenNum()));
    if (pm.get() == 0) {
        cerr<<"Resource("<<name()+".pixmap"<<"): Failed to load image: "<<pixmap_name<<endl;
    } else
        m_value.pixmap() = pm->pixmap().release();
}

// not used
template <>
void FbTk::ThemeItem<PixmapWithMask>::
load() { }

template <>
void FbTk::ThemeItem<PixmapWithMask>::
setDefaultValue() {
    // create empty pixmap
    (*this)->pixmap() = FbTk::FbPixmap(); // pixmap
    (*this)->mask() = FbTk::FbPixmap(); // mask
}

template <>
void FbTk::ThemeItem<PixmapWithMask>::
setFromString(const char *str) {
    if (str == 0)
        setDefaultValue();
    else {
        std::auto_ptr<FbTk::PixmapWithMask> pm(Image::load(str, m_tm.screenNum()));
        if (pm.get() == 0)
            setDefaultValue();
        else {
            (*this)->pixmap() = pm->pixmap().release();
            (*this)->mask() = pm->mask().release();
        }
    }
}

template <>
void ThemeItem<FbTk::Color>::setDefaultValue() {
    m_value.setFromString("white", m_tm.screenNum());
}

template <>
void ThemeItem<FbTk::Color>::setFromString(const char *str) {
    if (!m_value.setFromString(str, m_tm.screenNum())) {
        cerr<<"FbTk::Theme: Error loading color value for \""<<name()<<"\" or \""<<altName()<<"\"."<<endl;
        setDefaultValue();
    }
}

// does nothing
template <>
void ThemeItem<FbTk::Color>::load() { }

Theme::Theme(int screen_num):m_screen_num(screen_num) {

    if (!ThemeManager::instance().registerTheme(*this)) {
        // should it be fatal or not?
        cerr<<"FbTk::Theme Warning: Failed to register Theme"<<endl;
    }
}

Theme::~Theme() {
    if (!ThemeManager::instance().unregisterTheme(*this)) {
#ifdef DEBUG
        cerr<<"Warning: Theme not registered!"<<endl;
#endif // DEBUG
    }
}

ThemeManager &ThemeManager::instance() {
    static ThemeManager tm;
    return tm;
}

ThemeManager::ThemeManager():
    m_max_screens(ScreenCount(FbTk::App::instance()->display())) {

}

bool ThemeManager::registerTheme(Theme &tm) {
    // valid screen num?
    if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
        return false;
    // TODO: use find and return false if it's already there
    // instead of unique
    m_themelist.push_back(&tm);
    m_themelist.unique();
    return true;
}

bool ThemeManager::unregisterTheme(Theme &tm) {
    m_themelist.remove(&tm);
    return true;
}

bool ThemeManager::load(const std::string &filename) {

    if (!m_database.load(filename.c_str()))
        return false;

    //get list and go throu all the resources and load them
    ThemeList::iterator theme_it = m_themelist.begin();
    const ThemeList::iterator theme_it_end = m_themelist.end();
    for (; theme_it != theme_it_end; ++theme_it) {
        loadTheme(**theme_it);
    }
    // notify all themes that we reconfigured
    theme_it = m_themelist.begin();
    for (; theme_it != theme_it_end; ++theme_it) {
        // send reconfiguration signal to theme and listeners
        (*theme_it)->reconfigTheme();
        (*theme_it)->reconfigSig().notify();
    }
    return true;
}

void ThemeManager::loadTheme(Theme &tm) {
    std::list<ThemeItem_base *>::iterator i = tm.itemList().begin();
    std::list<ThemeItem_base *>::iterator i_end = tm.itemList().end();
    for (; i != i_end; ++i) {
        ThemeItem_base *resource = *i;
        if (!loadItem(*resource)) {
            // try fallback resource in theme
            if (!tm.fallback(*resource)) {
                cerr<<"Failed to read theme item: "<<resource->name()<<endl;
                cerr<<"Setting default value"<<endl;
                resource->setDefaultValue();
            }
        }
    }
    // send reconfiguration signal to theme and listeners
}

bool ThemeManager::loadItem(ThemeItem_base &resource) {
    return loadItem(resource, resource.name(), resource.altName());
}

/// handles resource item loading with specific name/altname
bool ThemeManager::loadItem(ThemeItem_base &resource, const std::string &name, const std::string &alt_name) {
    XrmValue value;
    char *value_type;

    if (XrmGetResource(*m_database, name.c_str(),
                       alt_name.c_str(), &value_type, &value)) {
        resource.setFromString(value.addr);
        resource.load(); // load additional stuff by the ThemeItem
    } else
        return false;

    return true;
}

std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
    XrmValue value;
    char *value_type;

    if (*m_database != 0 && XrmGetResource(*m_database, name.c_str(),
                                           altname.c_str(), &value_type, &value) && value.addr != 0) {
        return string(value.addr);
    }
    return "";
}

/*
void ThemeManager::listItems() {
    ThemeList::iterator it = m_themelist.begin();
    ThemeList::iterator it_end = m_themelist.end();
    for (; it != it_end; ++it) {
        std::list<ThemeItem_base *>::iterator item = (*it)->itemList().begin();
        std::list<ThemeItem_base *>::iterator item_end = (*it)->itemList().end();
        for (; item != item_end; ++item) {
            cerr<<(*item)->name()<<":"<<endl;
            if (typeid(**item) == typeid(ThemeItem<Texture>)) {
                cerr<<(*item)->name()<<".pixmap:"<<endl;
                cerr<<(*item)->name()<<".color:"<<endl;
                cerr<<(*item)->name()<<".colorTo:"<<endl;
            }
        }
    }

}
*/
}; // end namespace FbTk
<commit_msg>fixed pixmap bug<commit_after>// Theme.cc for FbTk - Fluxbox ToolKit
// Copyright (c) 2002 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// 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.

// $Id: Theme.cc,v 1.14 2003/08/28 14:18:36 fluxgen Exp $

#include "Theme.hh"

#include "XrmDatabaseHelper.hh"
#include "Font.hh"
#include "Color.hh"
#include "Texture.hh"
#include "App.hh"
#include "Image.hh"
#include "PixmapWithMask.hh"

#include <cstdio>
#include <memory>
#include <iostream>
using namespace std;

namespace FbTk {

// create default handlers for Color, Font, Texture, int and string
template <>
void FbTk::ThemeItem<std::string>::load() { }

template <>
void FbTk::ThemeItem<std::string>::setDefaultValue() {
    *(*this) = "";
}

template <>
void FbTk::ThemeItem<std::string>::setFromString(const char *str) {
    *(*this) = (str ? str : "");
}

template <>
void FbTk::ThemeItem<int>::load() { }

template <>
void FbTk::ThemeItem<int>::setDefaultValue() {
    *(*this) = 0;
}

template <>
void FbTk::ThemeItem<int>::setFromString(const char *str) {
    if (str == 0)
        return;
    sscanf(str, "%d", &m_value);
}

template <>
void ThemeItem<FbTk::Font>::setDefaultValue() {
    if (!m_value.load("fixed")) {
        cerr<<"FbTk::ThemeItem<FbTk::Font>: Warning! Failed to load default value 'fixed'"<<endl;
    }
}

template <>
void ThemeItem<FbTk::Font>::setFromString(const char *str) {
    if (m_value.load(str) == false) {
        cerr<<"FbTk::Theme: Error loading font "<<
            ((m_value.isAntialias() || m_value.utf8()) ? "(" : "")<<

            (m_value.isAntialias() ? "antialias" : "")<<
            (m_value.utf8() ? " utf8" : "")<<

            ((m_value.isAntialias() || m_value.utf8()) ? ") " : "")<<
            "for \""<<name()<<"\" or \""<<altName()<<"\": "<<str<<endl;

        cerr<<"FbTk::Theme: Setting default value"<<endl;
        setDefaultValue();
    }

}

// do nothing
template <>
void ThemeItem<FbTk::Font>::load() {
}

template <>
void ThemeItem<FbTk::Texture>::setDefaultValue() {
    m_value.setType(FbTk::Texture::FLAT | FbTk::Texture::SOLID);
}

template <>
void ThemeItem<FbTk::Texture>::setFromString(const char *str) {
    m_value.setFromString(str);
    if (m_value.type() == 0) // failed to set value
        setDefaultValue();
}

template <>
void ThemeItem<FbTk::Texture>::load() {
    string color_name(ThemeManager::instance().
                      resourceValue(name()+".color", altName()+".Color"));
    string colorto_name(ThemeManager::instance().
                        resourceValue(name()+".colorTo", altName()+".ColorTo"));
    string pixmap_name(ThemeManager::instance().
                       resourceValue(name()+".pixmap", altName()+".Pixmap"));

    // set default value if we failed to load color
    if (!m_value.color().setFromString(color_name.c_str(), m_tm.screenNum()))
        m_value.color().setFromString("darkgray", m_tm.screenNum());

    if (!m_value.colorTo().setFromString(colorto_name.c_str(), m_tm.screenNum()))
        m_value.colorTo().setFromString("white", m_tm.screenNum());

    std::auto_ptr<PixmapWithMask> pm(Image::load(pixmap_name, m_tm.screenNum()));
    if (pm.get() == 0) {
        cerr<<"Resource("<<name()+".pixmap"<<"): Failed to load image: "<<pixmap_name<<endl;
        m_value.pixmap() = 0;
    } else
        m_value.pixmap() = pm->pixmap().release();
}

// not used
template <>
void FbTk::ThemeItem<PixmapWithMask>::
load() { }

template <>
void FbTk::ThemeItem<PixmapWithMask>::
setDefaultValue() {
    // create empty pixmap
    (*this)->pixmap() = FbTk::FbPixmap(); // pixmap
    (*this)->mask() = FbTk::FbPixmap(); // mask
}

template <>
void FbTk::ThemeItem<PixmapWithMask>::
setFromString(const char *str) {
    if (str == 0)
        setDefaultValue();
    else {
        std::auto_ptr<FbTk::PixmapWithMask> pm(Image::load(str, m_tm.screenNum()));
        if (pm.get() == 0)
            setDefaultValue();
        else {
            (*this)->pixmap() = pm->pixmap().release();
            (*this)->mask() = pm->mask().release();
        }
    }
}

template <>
void ThemeItem<FbTk::Color>::setDefaultValue() {
    m_value.setFromString("white", m_tm.screenNum());
}

template <>
void ThemeItem<FbTk::Color>::setFromString(const char *str) {
    if (!m_value.setFromString(str, m_tm.screenNum())) {
        cerr<<"FbTk::Theme: Error loading color value for \""<<name()<<"\" or \""<<altName()<<"\"."<<endl;
        setDefaultValue();
    }
}

// does nothing
template <>
void ThemeItem<FbTk::Color>::load() { }

Theme::Theme(int screen_num):m_screen_num(screen_num) {

    if (!ThemeManager::instance().registerTheme(*this)) {
        // should it be fatal or not?
        cerr<<"FbTk::Theme Warning: Failed to register Theme"<<endl;
    }
}

Theme::~Theme() {
    if (!ThemeManager::instance().unregisterTheme(*this)) {
#ifdef DEBUG
        cerr<<"Warning: Theme not registered!"<<endl;
#endif // DEBUG
    }
}

ThemeManager &ThemeManager::instance() {
    static ThemeManager tm;
    return tm;
}

ThemeManager::ThemeManager():
    m_max_screens(ScreenCount(FbTk::App::instance()->display())) {

}

bool ThemeManager::registerTheme(Theme &tm) {
    // valid screen num?
    if (m_max_screens < tm.screenNum() || tm.screenNum() < 0)
        return false;
    // TODO: use find and return false if it's already there
    // instead of unique
    m_themelist.push_back(&tm);
    m_themelist.unique();
    return true;
}

bool ThemeManager::unregisterTheme(Theme &tm) {
    m_themelist.remove(&tm);
    return true;
}

bool ThemeManager::load(const std::string &filename) {

    if (!m_database.load(filename.c_str()))
        return false;

    //get list and go throu all the resources and load them
    ThemeList::iterator theme_it = m_themelist.begin();
    const ThemeList::iterator theme_it_end = m_themelist.end();
    for (; theme_it != theme_it_end; ++theme_it) {
        loadTheme(**theme_it);
    }
    // notify all themes that we reconfigured
    theme_it = m_themelist.begin();
    for (; theme_it != theme_it_end; ++theme_it) {
        // send reconfiguration signal to theme and listeners
        (*theme_it)->reconfigTheme();
        (*theme_it)->reconfigSig().notify();
    }
    return true;
}

void ThemeManager::loadTheme(Theme &tm) {
    std::list<ThemeItem_base *>::iterator i = tm.itemList().begin();
    std::list<ThemeItem_base *>::iterator i_end = tm.itemList().end();
    for (; i != i_end; ++i) {
        ThemeItem_base *resource = *i;
        if (!loadItem(*resource)) {
            // try fallback resource in theme
            if (!tm.fallback(*resource)) {
                cerr<<"Failed to read theme item: "<<resource->name()<<endl;
                cerr<<"Setting default value"<<endl;
                resource->setDefaultValue();
            }
        }
    }
    // send reconfiguration signal to theme and listeners
}

bool ThemeManager::loadItem(ThemeItem_base &resource) {
    return loadItem(resource, resource.name(), resource.altName());
}

/// handles resource item loading with specific name/altname
bool ThemeManager::loadItem(ThemeItem_base &resource, const std::string &name, const std::string &alt_name) {
    XrmValue value;
    char *value_type;

    if (XrmGetResource(*m_database, name.c_str(),
                       alt_name.c_str(), &value_type, &value)) {
        resource.setFromString(value.addr);
        resource.load(); // load additional stuff by the ThemeItem
    } else
        return false;

    return true;
}

std::string ThemeManager::resourceValue(const std::string &name, const std::string &altname) {
    XrmValue value;
    char *value_type;

    if (*m_database != 0 && XrmGetResource(*m_database, name.c_str(),
                                           altname.c_str(), &value_type, &value) && value.addr != 0) {
        return string(value.addr);
    }
    return "";
}

/*
void ThemeManager::listItems() {
    ThemeList::iterator it = m_themelist.begin();
    ThemeList::iterator it_end = m_themelist.end();
    for (; it != it_end; ++it) {
        std::list<ThemeItem_base *>::iterator item = (*it)->itemList().begin();
        std::list<ThemeItem_base *>::iterator item_end = (*it)->itemList().end();
        for (; item != item_end; ++item) {
            cerr<<(*item)->name()<<":"<<endl;
            if (typeid(**item) == typeid(ThemeItem<Texture>)) {
                cerr<<(*item)->name()<<".pixmap:"<<endl;
                cerr<<(*item)->name()<<".color:"<<endl;
                cerr<<(*item)->name()<<".colorTo:"<<endl;
            }
        }
    }

}
*/
}; // end namespace FbTk
<|endoftext|>


<commit_before>//
//  nif_cass_statement.cpp
//  erlcass
//
//  Created by silviu on 5/12/15.
//
//

#include "nif_cass_statement.h"
#include "nif_utils.h"
#include "metadata.h"
#include "nif_collection.h"
#include "uuid_serialization.h"
#include "types.hpp"
#include "execute_request.hpp"

struct enif_cass_statement
{
    CassStatement* statement;
};

ERL_NIF_TERM bind_param_by_index(ErlNifEnv* env, CassStatement* statement, size_t index, const SchemaColumn& type, ERL_NIF_TERM value)
{
    CassError cass_error;

    if(enif_is_identical(value, ATOMS.atomNull))
    {
        cass_error = cass_statement_bind_null(statement, index);
        return ATOMS.atomOk;
    }

    switch (type.type)
    {

        case CASS_VALUE_TYPE_VARCHAR:
        case CASS_VALUE_TYPE_ASCII:
        case CASS_VALUE_TYPE_TEXT:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_string_n(statement, index, str_value.c_str(), str_value.length());
            break;
        }

        case CASS_VALUE_TYPE_INT:
        {
            int int_value = 0;

            if(!enif_get_int(env, value, &int_value ))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_int32(statement, index, int_value);
            break;
        }

        case CASS_VALUE_TYPE_TIMESTAMP:
        case CASS_VALUE_TYPE_COUNTER:
        case CASS_VALUE_TYPE_BIGINT:
        {
            long long_value = 0;

            if(!enif_get_int64(env, value, &long_value ))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_int64(statement, index, long_value);
            break;
        }

        case CASS_VALUE_TYPE_VARINT:
        case CASS_VALUE_TYPE_BLOB:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_bytes(statement, index, reinterpret_cast<const cass_byte_t*>(str_value.data()), str_value.size());
            break;
        }

        case CASS_VALUE_TYPE_BOOLEAN:
        {
            cass_bool_t bool_value = enif_is_identical(ATOMS.atomTrue, value) ? cass_true : cass_false;
            cass_error = cass_statement_bind_bool(statement, index, bool_value);
            break;
        }

        case CASS_VALUE_TYPE_FLOAT:
        case CASS_VALUE_TYPE_DOUBLE:
        {
            double val_double;
            if(!enif_get_double(env, value, &val_double))
                return enif_make_badarg(env);

            if(type.type == CASS_VALUE_TYPE_FLOAT)
                cass_error = cass_statement_bind_float(statement, index, static_cast<float>(val_double));
            else
                cass_error = cass_statement_bind_double(statement, index, val_double);
            break;
        }

        case CASS_VALUE_TYPE_INET:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            CassInet inet;
            if(cass_inet_from_string_n(str_value.c_str(), str_value.length(), &inet) != CASS_OK)
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_inet(statement, index, inet);
            break;
        }

        case CASS_VALUE_TYPE_TIMEUUID:
        case CASS_VALUE_TYPE_UUID:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            CassUuid uuid;
            if(erlcass::cass_uuid_from_string_n(str_value.c_str(), str_value.length(), &uuid) != CASS_OK)
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_uuid(statement, index, uuid);
            break;
        }

        case CASS_VALUE_TYPE_DECIMAL:
        {
            const ERL_NIF_TERM *items;
            int arity;

            if(!enif_get_tuple(env, value, &arity, &items) || arity != 2)
                return enif_make_badarg(env);

            std::string varint;
            int scale;

            if(!get_string(env, items[0], varint) || !enif_get_int(env, items[1], &scale))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_decimal(statement, index, reinterpret_cast<const cass_byte_t*>(varint.data()), varint.size(), scale);
            break;
        }

        case CASS_VALUE_TYPE_MAP:
        case CASS_VALUE_TYPE_LIST:
        case CASS_VALUE_TYPE_SET:
        {
            CassError error = CASS_OK;

            CassCollection* collection = nif_list_to_cass_collection(env, value, type, &error);

            if(!collection)
                return enif_make_badarg(env);

            if(error == CASS_OK)
                cass_error = cass_statement_bind_collection(statement, index, collection);
            else
                cass_error = error;

            cass_collection_free(collection);

            break;
        }

        default:
            cass_error = cass_statement_bind_null(statement, index);
            break;
    }

    return cass_error_to_nif_term(env, cass_error);
}

inline CassValueType uint16_to_cass_value_type(uint16_t v)
{
    return static_cast<CassValueType>(v);
}

ERL_NIF_TERM bind_prepared_statement_params(ErlNifEnv* env, CassStatement* statement, ERL_NIF_TERM list)
{
    ERL_NIF_TERM head;
    const ERL_NIF_TERM *items;
    int arity;

    std::string column_name;
    cass::Statement* stm = static_cast<cass::Statement*>(statement);

    const cass::ResultResponse* result = static_cast<cass::ExecuteRequest*>(stm)->prepared()->result().get();
    cass::ResultMetadata::IndexVec::const_iterator it;
    size_t index = 0;

    while(enif_get_list_cell(env, list, &head, &list))
    {
        if(enif_is_tuple(env, head))
        {
            //bind by name -> {name, value}

            if(!enif_get_tuple(env, head, &arity, &items) || arity != 2)
                return enif_make_badarg(env);

            if(!get_string(env, items[0], column_name))
                return enif_make_badarg(env);

            cass::ResultMetadata::IndexVec indices;
            result->find_column_indices(column_name, &indices);

            for (it = indices.begin(); it != indices.end(); ++it)
            {
                size_t index = *it;
                const cass::ColumnDefinition def = result->metadata()->get(index);

                SchemaColumn column(uint16_to_cass_value_type(def.type),
                                    uint16_to_cass_value_type(def.collection_primary_type),
                                    uint16_to_cass_value_type(def.collection_secondary_type));

                ERL_NIF_TERM result = bind_param_by_index(env, statement, index, column, items[1]);

                if(!enif_is_identical(result, ATOMS.atomOk))
                    return result;
            }

        }
        else
        {
            //bind by index

            if(index > result->metadata()->column_count())
                return enif_make_badarg(env);

            const cass::ColumnDefinition def = result->metadata()->get(index);

            SchemaColumn column(uint16_to_cass_value_type(def.type),
                                uint16_to_cass_value_type(def.collection_primary_type),
                                uint16_to_cass_value_type(def.collection_secondary_type));

            ERL_NIF_TERM result = bind_param_by_index(env, statement, index, column, head);

            if(!enif_is_identical(result, ATOMS.atomOk))
                return result;

            index++;
        }
    }

    return ATOMS.atomOk;
}

CassStatement* get_statement(ErlNifEnv* env, ErlNifResourceType* resource_type, ERL_NIF_TERM arg)
{
    enif_cass_statement * enif_stm = NULL;

    if(!enif_get_resource(env, arg, resource_type, (void**) &enif_stm))
        return NULL;

    return enif_stm->statement;
}

ERL_NIF_TERM nif_cass_statement_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    cassandra_data* data = static_cast<cassandra_data*>(enif_priv_data(env));

    ERL_NIF_TERM queryTerm;
    std::string query;
    CassConsistency consistencyLevel;

    if(enif_is_tuple(env, argv[0]))
    {
        const ERL_NIF_TERM *items;
        int arity;

        if(!enif_get_tuple(env, argv[0], &arity, &items) || arity != 2)
            return enif_make_badarg(env);

        queryTerm = items[0];
        int cLevel;

        if(!enif_get_int(env, items[1], &cLevel))
            return enif_make_badarg(env);

        consistencyLevel = static_cast<CassConsistency>(cLevel);
    }
    else
    {
        queryTerm = argv[0];
        consistencyLevel = data->defaultConsistencyLevel;
    }

    if(!get_string(env, queryTerm, query))
        return enif_make_badarg(env);

    ERL_NIF_TERM paramslist = argv[1];
    unsigned int params_length;

    if(!enif_get_list_length(env, paramslist, &params_length))
        return enif_make_badarg(env);

    CassStatement* stm = cass_statement_new_n(query.c_str(), query.length(), params_length);

    CassError cass_result = cass_statement_set_consistency(stm, consistencyLevel);

    if(cass_result != CASS_OK)
        return cass_error_to_nif_term(env, cass_result);

    if(params_length)
    {
        ERL_NIF_TERM head;
        const ERL_NIF_TERM *items;
        int arity;

        size_t index = 0;

        while(enif_get_list_cell(env, paramslist, &head, &paramslist))
        {
            if(!enif_get_tuple(env, head, &arity, &items) || arity != 2)
                return enif_make_badarg(env);

            SchemaColumn type = atom_to_schema_column(env, items[0]);

            if(type.valueType == CASS_VALUE_TYPE_UNKNOWN)
                return enif_make_badarg(env);

            ERL_NIF_TERM result = bind_param_by_index(env, stm, index, type, items[1]);

            if(!enif_is_identical(result, ATOMS.atomOk))
                return result;

            index++;
        }
    }

    enif_cass_statement *enif_obj = static_cast<enif_cass_statement*>(enif_alloc_resource(data->resCassStatement, sizeof(enif_cass_statement)));

    if(enif_obj == NULL)
        return make_error(env, "enif_alloc_resource failed");

    enif_obj->statement = stm;

    ERL_NIF_TERM term = enif_make_resource(env, enif_obj);
    enif_release_resource(enif_obj);

    return enif_make_tuple2(env, ATOMS.atomOk, term);
}

ERL_NIF_TERM nif_cass_statement_new(ErlNifEnv* env, ErlNifResourceType* resource_type, const CassPrepared* prep, CassConsistency consistency)
{
    enif_cass_statement *enif_obj = static_cast<enif_cass_statement*>(enif_alloc_resource(resource_type, sizeof(enif_cass_statement)));

    if(enif_obj == NULL)
        return make_error(env, "enif_alloc_resource failed");

    enif_obj->statement = cass_prepared_bind(prep);

    CassError cass_result = cass_statement_set_consistency(enif_obj->statement, consistency);

    if(cass_result != CASS_OK)
        return cass_error_to_nif_term(env, cass_result);

    ERL_NIF_TERM term = enif_make_resource(env, enif_obj);
    enif_release_resource(enif_obj);

    return term;
}

void nif_cass_statement_free(ErlNifEnv* env, void* obj)
{
    enif_cass_statement *data = static_cast<enif_cass_statement*>(obj);

    if(data->statement != NULL)
        cass_statement_free(data->statement);
}

ERL_NIF_TERM nif_cass_statement_bind_parameters(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    cassandra_data* data = static_cast<cassandra_data*>(enif_priv_data(env));

    enif_cass_statement * enif_stm = NULL;

    if(!enif_get_resource(env, argv[0], data->resCassStatement, (void**) &enif_stm) || !enif_is_list(env, argv[1]))
        return enif_make_badarg(env);

    return bind_prepared_statement_params(env, enif_stm->statement, argv[1]);
}
<commit_msg>Fix binding for collections<commit_after>//
//  nif_cass_statement.cpp
//  erlcass
//
//  Created by silviu on 5/12/15.
//
//

#include "nif_cass_statement.h"
#include "nif_utils.h"
#include "metadata.h"
#include "nif_collection.h"
#include "uuid_serialization.h"
#include "types.hpp"
#include "execute_request.hpp"

struct enif_cass_statement
{
    CassStatement* statement;
};

ERL_NIF_TERM bind_param_by_index(ErlNifEnv* env, CassStatement* statement, size_t index, const SchemaColumn& type, ERL_NIF_TERM value)
{
    CassError cass_error;

    if(enif_is_identical(value, ATOMS.atomNull))
    {
        cass_error = cass_statement_bind_null(statement, index);
        return ATOMS.atomOk;
    }

    switch (type.type)
    {

        case CASS_VALUE_TYPE_VARCHAR:
        case CASS_VALUE_TYPE_ASCII:
        case CASS_VALUE_TYPE_TEXT:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_string_n(statement, index, str_value.c_str(), str_value.length());
            break;
        }

        case CASS_VALUE_TYPE_INT:
        {
            int int_value = 0;

            if(!enif_get_int(env, value, &int_value ))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_int32(statement, index, int_value);
            break;
        }

        case CASS_VALUE_TYPE_TIMESTAMP:
        case CASS_VALUE_TYPE_COUNTER:
        case CASS_VALUE_TYPE_BIGINT:
        {
            long long_value = 0;

            if(!enif_get_int64(env, value, &long_value ))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_int64(statement, index, long_value);
            break;
        }

        case CASS_VALUE_TYPE_VARINT:
        case CASS_VALUE_TYPE_BLOB:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_bytes(statement, index, reinterpret_cast<const cass_byte_t*>(str_value.data()), str_value.size());
            break;
        }

        case CASS_VALUE_TYPE_BOOLEAN:
        {
            cass_bool_t bool_value = enif_is_identical(ATOMS.atomTrue, value) ? cass_true : cass_false;
            cass_error = cass_statement_bind_bool(statement, index, bool_value);
            break;
        }

        case CASS_VALUE_TYPE_FLOAT:
        case CASS_VALUE_TYPE_DOUBLE:
        {
            double val_double;
            if(!enif_get_double(env, value, &val_double))
                return enif_make_badarg(env);

            if(type.type == CASS_VALUE_TYPE_FLOAT)
                cass_error = cass_statement_bind_float(statement, index, static_cast<float>(val_double));
            else
                cass_error = cass_statement_bind_double(statement, index, val_double);
            break;
        }

        case CASS_VALUE_TYPE_INET:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            CassInet inet;
            if(cass_inet_from_string_n(str_value.c_str(), str_value.length(), &inet) != CASS_OK)
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_inet(statement, index, inet);
            break;
        }

        case CASS_VALUE_TYPE_TIMEUUID:
        case CASS_VALUE_TYPE_UUID:
        {
            std::string str_value;

            if(!get_string(env, value, str_value))
                return enif_make_badarg(env);

            CassUuid uuid;
            if(erlcass::cass_uuid_from_string_n(str_value.c_str(), str_value.length(), &uuid) != CASS_OK)
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_uuid(statement, index, uuid);
            break;
        }

        case CASS_VALUE_TYPE_DECIMAL:
        {
            const ERL_NIF_TERM *items;
            int arity;

            if(!enif_get_tuple(env, value, &arity, &items) || arity != 2)
                return enif_make_badarg(env);

            std::string varint;
            int scale;

            if(!get_string(env, items[0], varint) || !enif_get_int(env, items[1], &scale))
                return enif_make_badarg(env);

            cass_error = cass_statement_bind_decimal(statement, index, reinterpret_cast<const cass_byte_t*>(varint.data()), varint.size(), scale);
            break;
        }

        case CASS_VALUE_TYPE_MAP:
        case CASS_VALUE_TYPE_LIST:
        case CASS_VALUE_TYPE_SET:
        {
            CassError error = CASS_OK;

            CassCollection* collection = nif_list_to_cass_collection(env, value, type, &error);

            if(!collection)
                return enif_make_badarg(env);

            if(error == CASS_OK)
                cass_error = cass_statement_bind_collection(statement, index, collection);
            else
                cass_error = error;

            cass_collection_free(collection);

            break;
        }

        default:
            cass_error = cass_statement_bind_null(statement, index);
            break;
    }

    return cass_error_to_nif_term(env, cass_error);
}

inline CassValueType uint16_to_cass_value_type(uint16_t v)
{
    return static_cast<CassValueType>(v);
}

ERL_NIF_TERM bind_prepared_statement_params(ErlNifEnv* env, CassStatement* statement, ERL_NIF_TERM list)
{
    ERL_NIF_TERM head;
    const ERL_NIF_TERM *items;
    int arity;

    std::string column_name;
    cass::Statement* stm = static_cast<cass::Statement*>(statement);

    const cass::ResultResponse* result = static_cast<cass::ExecuteRequest*>(stm)->prepared()->result().get();
    cass::ResultMetadata::IndexVec::const_iterator it;
    size_t index = 0;

    while(enif_get_list_cell(env, list, &head, &list))
    {
        if(enif_is_tuple(env, head))
        {
            //bind by name -> {name, value}

            if(!enif_get_tuple(env, head, &arity, &items) || arity != 2)
                return enif_make_badarg(env);

            if(!get_string(env, items[0], column_name))
                return enif_make_badarg(env);

            cass::ResultMetadata::IndexVec indices;
            result->find_column_indices(column_name, &indices);

            for (it = indices.begin(); it != indices.end(); ++it)
            {
                size_t index = *it;
                const cass::ColumnDefinition def = result->metadata()->get(index);

                SchemaColumn column(uint16_to_cass_value_type(def.type));

                if(column.type == CASS_VALUE_TYPE_LIST || column.type == CASS_VALUE_TYPE_SET)
                {
                    column.valueType = uint16_to_cass_value_type(def.collection_primary_type);
                }
                else if(column.type == CASS_VALUE_TYPE_MAP)
                {
                    column.keyType = uint16_to_cass_value_type(def.collection_primary_type);
                    column.valueType = uint16_to_cass_value_type(def.collection_secondary_type);
                }

                ERL_NIF_TERM result = bind_param_by_index(env, statement, index, column, items[1]);

                if(!enif_is_identical(result, ATOMS.atomOk))
                    return result;
            }

        }
        else
        {
            //bind by index

            if(index > result->metadata()->column_count())
                return enif_make_badarg(env);

            const cass::ColumnDefinition def = result->metadata()->get(index);

            SchemaColumn column(uint16_to_cass_value_type(def.type));

            if(column.type == CASS_VALUE_TYPE_LIST || column.type == CASS_VALUE_TYPE_SET)
            {
                column.valueType = uint16_to_cass_value_type(def.collection_primary_type);
            }
            else if(column.type == CASS_VALUE_TYPE_MAP)
            {
                column.keyType = uint16_to_cass_value_type(def.collection_primary_type);
                column.valueType = uint16_to_cass_value_type(def.collection_secondary_type);
            }

            ERL_NIF_TERM result = bind_param_by_index(env, statement, index, column, head);

            if(!enif_is_identical(result, ATOMS.atomOk))
                return result;

            index++;
        }
    }

    return ATOMS.atomOk;
}

CassStatement* get_statement(ErlNifEnv* env, ErlNifResourceType* resource_type, ERL_NIF_TERM arg)
{
    enif_cass_statement * enif_stm = NULL;

    if(!enif_get_resource(env, arg, resource_type, (void**) &enif_stm))
        return NULL;

    return enif_stm->statement;
}

ERL_NIF_TERM nif_cass_statement_new(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    cassandra_data* data = static_cast<cassandra_data*>(enif_priv_data(env));

    ERL_NIF_TERM queryTerm;
    std::string query;
    CassConsistency consistencyLevel;

    if(enif_is_tuple(env, argv[0]))
    {
        const ERL_NIF_TERM *items;
        int arity;

        if(!enif_get_tuple(env, argv[0], &arity, &items) || arity != 2)
            return enif_make_badarg(env);

        queryTerm = items[0];
        int cLevel;

        if(!enif_get_int(env, items[1], &cLevel))
            return enif_make_badarg(env);

        consistencyLevel = static_cast<CassConsistency>(cLevel);
    }
    else
    {
        queryTerm = argv[0];
        consistencyLevel = data->defaultConsistencyLevel;
    }

    if(!get_string(env, queryTerm, query))
        return enif_make_badarg(env);

    ERL_NIF_TERM paramslist = argv[1];
    unsigned int params_length;

    if(!enif_get_list_length(env, paramslist, &params_length))
        return enif_make_badarg(env);

    CassStatement* stm = cass_statement_new_n(query.c_str(), query.length(), params_length);

    CassError cass_result = cass_statement_set_consistency(stm, consistencyLevel);

    if(cass_result != CASS_OK)
        return cass_error_to_nif_term(env, cass_result);

    if(params_length)
    {
        ERL_NIF_TERM head;
        const ERL_NIF_TERM *items;
        int arity;

        size_t index = 0;

        while(enif_get_list_cell(env, paramslist, &head, &paramslist))
        {
            if(!enif_get_tuple(env, head, &arity, &items) || arity != 2)
                return enif_make_badarg(env);

            SchemaColumn type = atom_to_schema_column(env, items[0]);

            if(type.valueType == CASS_VALUE_TYPE_UNKNOWN)
                return enif_make_badarg(env);

            ERL_NIF_TERM result = bind_param_by_index(env, stm, index, type, items[1]);

            if(!enif_is_identical(result, ATOMS.atomOk))
                return result;

            index++;
        }
    }

    enif_cass_statement *enif_obj = static_cast<enif_cass_statement*>(enif_alloc_resource(data->resCassStatement, sizeof(enif_cass_statement)));

    if(enif_obj == NULL)
        return make_error(env, "enif_alloc_resource failed");

    enif_obj->statement = stm;

    ERL_NIF_TERM term = enif_make_resource(env, enif_obj);
    enif_release_resource(enif_obj);

    return enif_make_tuple2(env, ATOMS.atomOk, term);
}

ERL_NIF_TERM nif_cass_statement_new(ErlNifEnv* env, ErlNifResourceType* resource_type, const CassPrepared* prep, CassConsistency consistency)
{
    enif_cass_statement *enif_obj = static_cast<enif_cass_statement*>(enif_alloc_resource(resource_type, sizeof(enif_cass_statement)));

    if(enif_obj == NULL)
        return make_error(env, "enif_alloc_resource failed");

    enif_obj->statement = cass_prepared_bind(prep);

    CassError cass_result = cass_statement_set_consistency(enif_obj->statement, consistency);

    if(cass_result != CASS_OK)
        return cass_error_to_nif_term(env, cass_result);

    ERL_NIF_TERM term = enif_make_resource(env, enif_obj);
    enif_release_resource(enif_obj);

    return term;
}

void nif_cass_statement_free(ErlNifEnv* env, void* obj)
{
    enif_cass_statement *data = static_cast<enif_cass_statement*>(obj);

    if(data->statement != NULL)
        cass_statement_free(data->statement);
}

ERL_NIF_TERM nif_cass_statement_bind_parameters(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    cassandra_data* data = static_cast<cassandra_data*>(enif_priv_data(env));

    enif_cass_statement * enif_stm = NULL;

    if(!enif_get_resource(env, argv[0], data->resCassStatement, (void**) &enif_stm) || !enif_is_list(env, argv[1]))
        return enif_make_badarg(env);

    return bind_prepared_statement_params(env, enif_stm->statement, argv[1]);
}
<|endoftext|>


<commit_before># pragma once
# include "stdio.h"
#include <iostream>
#include <interface.h>
#include <PrettyPrintVisitor.h>

std::string identt( "   " );//

void PrettyPrintVisitor::Visit( const CProgram& p ) //MainClass ClassDeclList
{
	p.GetMainClass()->Accept( this );
	if( p.GetClassDeclList() ) {
		p.GetClassDeclList()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CMainClass& p ) //class id { public static void main ( String [] id ) { Statement }}
{
	printf( "class %s { \n%spublic static Void main ( String [] %s ) { \n", p.GetIdFirst().c_str(), identt.c_str(), p.GetIDSecond().c_str() );
	identt += "    ";
	p.GetStm()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
	printf( "%s}\n}\n", identt.c_str() );
}

void PrettyPrintVisitor::Visit( const CClassDecl& p ) //class id { VarDeclList MethodDeclList }
{
	identt = "";
	printf( "\n%sclass %s { \n", identt.c_str(), p.GetId().c_str() );
	identt += "    ";
	if( p.GetVarDeclList() ) {
		p.GetVarDeclList()->Accept( this );
	}
	if( p.GetMethodDeclList() ) {
		p.GetMethodDeclList()->Accept( this );
	}
	printf( "\n}\n" );
}

void PrettyPrintVisitor::Visit( const CExClassDecl& p ) //class id extends id { VarDeclList MethodDeclList }
{
	identt = "";
	printf( "\n%sclass %s extends %s { \n", identt.c_str(), p.GetId().c_str(), p.GetIDExtend().c_str() );
	identt += "    ";
	if( p.GetVarDeclList() ) {
		p.GetVarDeclList()->Accept( this );
	}
	if( p.GetMethodDeclList() ) {
		p.GetMethodDeclList()->Accept( this );
	}
	printf( "\n}\n" );
}

void PrettyPrintVisitor::Visit( const CVarDecl& p ) //Type id
{
	printf( "%s%s %s ;\n", identt.c_str(), p.GetType().c_str(), p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CMethodDecl& p ) //public Type id ( FormalList ) { VarDecl* Statement* return Exp ;}
{
	printf( "%spublic %s %s ( ", identt.c_str(), p.GetType().c_str(), p.GetId().c_str() );
	if( p.GetFormalList() ) {
		p.GetFormalList()->Accept( this );
	}
	printf( ") { \n" );
	identt += "    ";
	if( p.GetVarDeclList() ) {
		p.GetVarDeclList()->Accept( this );
	}
	if( p.GetStmList() ) {
		p.GetStmList()->Accept( this );
	}
	printf( "\n%sreturn ", identt.c_str() );
	p.GetExp()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
	printf( ";\n%s}\n", identt.c_str() );
	//identt = identt.substr(0,identt.length() - 4);
}

void PrettyPrintVisitor::Visit( const CCompStm& p ) //{ Statement* }
{
	printf( "%s{\n", identt.c_str() );
	identt += "    ";
	if( p.GetStmList() ) {
		p.GetStmList()->Accept( this );
	}
	identt = identt.substr( 0, identt.length() - 4 );
	printf( "%s}\n", identt.c_str() );
	identt = identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CIfStm& p ) //if ( Exp ) Statement else Statement
{
	//
	std::string idtCopy( identt );
	printf( "%sif ( ", identt.c_str() );
	p.GetExp()->Accept( this );
	printf( " )\n" );
	identt += "    ";
	p.GetStmFirst()->Accept( this );
	identt = idtCopy;
	printf( "%selse\n", identt.c_str() );
	identt += "    ";
	p.GetlStmSecond()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CWhStm& p )//while ( Exp ) Statement
{
	printf( "%swhile ( ", identt.c_str() );
	p.GetExp()->Accept( this );
	printf( " )\n" );
	identt += "    ";
	p.GetStm()->Accept( this );
	identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CForStm& p )//for ( Statement; Exp; Statement ) Statement
{
	printf( "%sfor ( ", identt.c_str() );
	p.GetInitStm()->Accept( this );
	printf( "; " );
	p.GetCheckExp()->Accept( this );
	printf( "; " );
	p.GetUpdateStm()->Accept( this );
	printf( " )\n" );
	identt += "    ";
	p.GetBodyStm()->Accept( this );
	identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CSOPStm& p )//System.out.println ( Exp ) ;
{
	printf( "%sSystem.out.println ( ", identt.c_str() );
	p.GetExp()->Accept( this );
	printf( " ) ;\n" );
}

void PrettyPrintVisitor::Visit( const CAsStm& p )//id = Exp ;
{
	printf( "%s%s = ", identt.c_str(), p.GetId().c_str() );
	p.GetExp()->Accept( this );
	printf( ";\n" );
}

void PrettyPrintVisitor::Visit( const CAsExpStm& p )//id [ Exp ] = Exp;
{
	printf( "%s%s [ ", identt.c_str(), p.GetId().c_str() );
	p.GetExpFirst()->Accept( this );
	printf( " ] = " );
	p.GetExpSecond()->Accept( this );
	printf( ";\n" );
}

void PrettyPrintVisitor::Visit( const COpExp& p )//Exp op Exp
{
	p.GetExpFirst()->Accept( this );
	if( p.GetOp() == B_Plus ) {
		printf( " + " );
	} else if( p.GetOp() == B_Minus ) {
		printf( " - " );
	} else if( p.GetOp() == B_Mult ) {
		printf( " * " );
	} else if( p.GetOp() == B_Div ) {
		printf( " / " );
	} else if( p.GetOp() == B_And ) {
		printf( " && " );
	} else if( p.GetOp() == B_Less ) {
		printf( " < " );
	}
	p.GetExpSecond()->Accept( this );
}

void PrettyPrintVisitor::Visit( const CPreUnOpExp& p )//++id, --id
{
	if(p.GetValue() == 1) {
		printf( "%s++%s", identt.c_str(), p.GetId().c_str() );
	} else if(p.GetValue() == -1) {
		printf( "%s--%s", identt.c_str(), p.GetId().c_str() );
	}
}

void PrettyPrintVisitor::Visit( const CPostUnOpExp& p )//++id, --id
{
	if(p.GetValue() == 1) {
		printf( "%s%s++", identt.c_str(), p.GetId().c_str() );
	} else if(p.GetValue() == -1) {
		printf( "%s%s--", identt.c_str(), p.GetId().c_str() );
	}
}

void PrettyPrintVisitor::Visit( const CExExp& p )//Exp [ Exp ]
{
	p.GetExpFirst()->Accept( this );
	printf( "[ " );
	p.GetExpSecondn()->Accept( this );
	printf( " ] " );
}

void PrettyPrintVisitor::Visit( const CLenExp& p )//Exp . length
{
	p.GetExp()->Accept( this );
	printf( ". length" );
}

void PrettyPrintVisitor::Visit( const CIdClExp& p )//Exp . id ( ExpList )
{
	p.GetExp()->Accept( this );
	printf( ". %s ( ", p.GetId().c_str() );
	if( p.GetExpList() ) {
		p.GetExpList()->Accept( this );
	}
	printf( " )" );
}

void PrettyPrintVisitor::Visit( const CNExp& p )//num
{
	printf( "%d", p.GetNum() );
}

void PrettyPrintVisitor::Visit( const CStrExp& p )//str
{
	printf( "%s", p.GetStr() );
}

void PrettyPrintVisitor::Visit( const CTrExp& p )//true
{
	printf( "true" );
}

void PrettyPrintVisitor::Visit( const CFExp& p )//false
{
	printf( "false" );
}

void PrettyPrintVisitor::Visit( const CIdExp& p )//id
{
	printf( "%s", p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CThExp& p )//this
{
	printf( "this" );
}

void PrettyPrintVisitor::Visit( const CNewIntExp& p )//new int [ Exp ]
{
	printf( "new int [ " );
	p.GetExp()->Accept( this );
	printf( " ]" );
}

void PrettyPrintVisitor::Visit( const CNewIdExp& p )//new id ()
{
	printf( "new %s ()", p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CNotExp& p )//! Exp
{
	printf( "! " );
	p.GetExp()->Accept( this );
}

void PrettyPrintVisitor::Visit( const CBrExp& p )//( Exp )
{
	printf( "( " );
	p.GetExp()->Accept( this );
	printf( " )" );
}

void PrettyPrintVisitor::Visit( const CTypeId& p )// id
{
	printf( "%s", p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CExpList& p )//Exp , ExpList
{
	p.GetExp()->Accept( this );
	printf( " " );
	if( p.GetExpList() ) {
		printf( ", " );//????????????????????????????????????????
		p.GetExpList()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CFormalList& p )//Type Id FormalRestList
{
	//p.GetType()->Accept(this);
	printf( "%s", p.GetType().c_str() );
	printf( " %s ", p.GetId().c_str() );
	if( p.GetFormalList() ) {
		printf( ", " );
		p.GetFormalList()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CClassDeclList& p )//ClassDeclList
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CVarDeclList& p )
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CMethodDeclList& p )
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CStmList& p )
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CEmptyStm& p )
{
	// do nothing
}

void PrettyPrintVisitor::Visit( const CExpStm& p )
{
	printf( "%s", identt.c_str() );
	p.GetExp()->Accept(this);
	printf( ";" );
}<commit_msg>fix indents in for<commit_after># pragma once
# include "stdio.h"
#include <iostream>
#include <interface.h>
#include <PrettyPrintVisitor.h>

std::string identt( "   " );//

void PrettyPrintVisitor::Visit( const CProgram& p ) //MainClass ClassDeclList
{
	p.GetMainClass()->Accept( this );
	if( p.GetClassDeclList() ) {
		p.GetClassDeclList()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CMainClass& p ) //class id { public static void main ( String [] id ) { Statement }}
{
	printf( "class %s { \n%spublic static Void main ( String [] %s ) { \n", p.GetIdFirst().c_str(), identt.c_str(), p.GetIDSecond().c_str() );
	identt += "    ";
	p.GetStm()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
	printf( "%s}\n}\n", identt.c_str() );
}

void PrettyPrintVisitor::Visit( const CClassDecl& p ) //class id { VarDeclList MethodDeclList }
{
	identt = "";
	printf( "\n%sclass %s { \n", identt.c_str(), p.GetId().c_str() );
	identt += "    ";
	if( p.GetVarDeclList() ) {
		p.GetVarDeclList()->Accept( this );
	}
	if( p.GetMethodDeclList() ) {
		p.GetMethodDeclList()->Accept( this );
	}
	printf( "\n}\n" );
}

void PrettyPrintVisitor::Visit( const CExClassDecl& p ) //class id extends id { VarDeclList MethodDeclList }
{
	identt = "";
	printf( "\n%sclass %s extends %s { \n", identt.c_str(), p.GetId().c_str(), p.GetIDExtend().c_str() );
	identt += "    ";
	if( p.GetVarDeclList() ) {
		p.GetVarDeclList()->Accept( this );
	}
	if( p.GetMethodDeclList() ) {
		p.GetMethodDeclList()->Accept( this );
	}
	printf( "\n}\n" );
}

void PrettyPrintVisitor::Visit( const CVarDecl& p ) //Type id
{
	printf( "%s%s %s ;\n", identt.c_str(), p.GetType().c_str(), p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CMethodDecl& p ) //public Type id ( FormalList ) { VarDecl* Statement* return Exp ;}
{
	printf( "%spublic %s %s ( ", identt.c_str(), p.GetType().c_str(), p.GetId().c_str() );
	if( p.GetFormalList() ) {
		p.GetFormalList()->Accept( this );
	}
	printf( ") { \n" );
	identt += "    ";
	if( p.GetVarDeclList() ) {
		p.GetVarDeclList()->Accept( this );
	}
	if( p.GetStmList() ) {
		p.GetStmList()->Accept( this );
	}
	printf( "\n%sreturn ", identt.c_str() );
	p.GetExp()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
	printf( ";\n%s}\n", identt.c_str() );
	//identt = identt.substr(0,identt.length() - 4);
}

void PrettyPrintVisitor::Visit( const CCompStm& p ) //{ Statement* }
{
	printf( "%s{\n", identt.c_str() );
	identt += "    ";
	if( p.GetStmList() ) {
		p.GetStmList()->Accept( this );
	}
	identt = identt.substr( 0, identt.length() - 4 );
	printf( "%s}\n", identt.c_str() );
	identt = identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CIfStm& p ) //if ( Exp ) Statement else Statement
{
	//
	std::string idtCopy( identt );
	printf( "%sif ( ", identt.c_str() );
	p.GetExp()->Accept( this );
	printf( " )\n" );
	identt += "    ";
	p.GetStmFirst()->Accept( this );
	identt = idtCopy;
	printf( "%selse\n", identt.c_str() );
	identt += "    ";
	p.GetlStmSecond()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CWhStm& p )//while ( Exp ) Statement
{
	printf( "%swhile ( ", identt.c_str() );
	p.GetExp()->Accept( this );
	printf( " )\n" );
	identt += "    ";
	p.GetStm()->Accept( this );
	identt = identt.substr( 0, identt.length() - 4 );
}

void PrettyPrintVisitor::Visit( const CForStm& p )//for ( Statement; Exp; Statement ) Statement
{
	printf( "%sfor ( \n", identt.c_str() );
	identt += "     ";
	p.GetInitStm()->Accept( this );
	printf( "%s", identt.c_str() );
	p.GetCheckExp()->Accept( this );
	printf( "; \n" );
	p.GetUpdateStm()->Accept( this );
	identt = identt.substr( 0, identt.length() - 5 );
	printf( "%s)\n", identt.c_str() );
	p.GetBodyStm()->Accept( this );
}

void PrettyPrintVisitor::Visit( const CSOPStm& p )//System.out.println ( Exp ) ;
{
	printf( "%sSystem.out.println ( ", identt.c_str() );
	p.GetExp()->Accept( this );
	printf( " ) ;\n" );
}

void PrettyPrintVisitor::Visit( const CAsStm& p )//id = Exp ;
{
	printf( "%s%s = ", identt.c_str(), p.GetId().c_str() );
	p.GetExp()->Accept( this );
	printf( ";\n" );
}

void PrettyPrintVisitor::Visit( const CAsExpStm& p )//id [ Exp ] = Exp;
{
	printf( "%s%s [ ", identt.c_str(), p.GetId().c_str() );
	p.GetExpFirst()->Accept( this );
	printf( " ] = " );
	p.GetExpSecond()->Accept( this );
	printf( ";\n" );
}

void PrettyPrintVisitor::Visit( const COpExp& p )//Exp op Exp
{
	p.GetExpFirst()->Accept( this );
	if( p.GetOp() == B_Plus ) {
		printf( " + " );
	} else if( p.GetOp() == B_Minus ) {
		printf( " - " );
	} else if( p.GetOp() == B_Mult ) {
		printf( " * " );
	} else if( p.GetOp() == B_Div ) {
		printf( " / " );
	} else if( p.GetOp() == B_And ) {
		printf( " && " );
	} else if( p.GetOp() == B_Less ) {
		printf( " < " );
	}
	p.GetExpSecond()->Accept( this );
}

void PrettyPrintVisitor::Visit( const CPreUnOpExp& p )//++id, --id
{
	if(p.GetValue() == 1) {
		printf( "++%s", p.GetId().c_str() );
	} else if(p.GetValue() == -1) {
		printf( "--%s", p.GetId().c_str() );
	}
}

void PrettyPrintVisitor::Visit( const CPostUnOpExp& p )//++id, --id
{
	if(p.GetValue() == 1) {
		printf( "%s++", p.GetId().c_str() );
	} else if(p.GetValue() == -1) {
		printf( "%s--", p.GetId().c_str() );
	}
}

void PrettyPrintVisitor::Visit( const CExExp& p )//Exp [ Exp ]
{
	p.GetExpFirst()->Accept( this );
	printf( "[ " );
	p.GetExpSecondn()->Accept( this );
	printf( " ] " );
}

void PrettyPrintVisitor::Visit( const CLenExp& p )//Exp . length
{
	p.GetExp()->Accept( this );
	printf( ". length" );
}

void PrettyPrintVisitor::Visit( const CIdClExp& p )//Exp . id ( ExpList )
{
	p.GetExp()->Accept( this );
	printf( ". %s ( ", p.GetId().c_str() );
	if( p.GetExpList() ) {
		p.GetExpList()->Accept( this );
	}
	printf( " )" );
}

void PrettyPrintVisitor::Visit( const CNExp& p )//num
{
	printf( "%d", p.GetNum() );
}

void PrettyPrintVisitor::Visit( const CStrExp& p )//str
{
	printf( "%s", p.GetStr() );
}

void PrettyPrintVisitor::Visit( const CTrExp& p )//true
{
	printf( "true" );
}

void PrettyPrintVisitor::Visit( const CFExp& p )//false
{
	printf( "false" );
}

void PrettyPrintVisitor::Visit( const CIdExp& p )//id
{
	printf( "%s", p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CThExp& p )//this
{
	printf( "this" );
}

void PrettyPrintVisitor::Visit( const CNewIntExp& p )//new int [ Exp ]
{
	printf( "new int [ " );
	p.GetExp()->Accept( this );
	printf( " ]" );
}

void PrettyPrintVisitor::Visit( const CNewIdExp& p )//new id ()
{
	printf( "new %s ()", p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CNotExp& p )//! Exp
{
	printf( "! " );
	p.GetExp()->Accept( this );
}

void PrettyPrintVisitor::Visit( const CBrExp& p )//( Exp )
{
	printf( "( " );
	p.GetExp()->Accept( this );
	printf( " )" );
}

void PrettyPrintVisitor::Visit( const CTypeId& p )// id
{
	printf( "%s", p.GetId().c_str() );
}

void PrettyPrintVisitor::Visit( const CExpList& p )//Exp , ExpList
{
	p.GetExp()->Accept( this );
	printf( " " );
	if( p.GetExpList() ) {
		printf( ", " );//????????????????????????????????????????
		p.GetExpList()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CFormalList& p )//Type Id FormalRestList
{
	//p.GetType()->Accept(this);
	printf( "%s", p.GetType().c_str() );
	printf( " %s ", p.GetId().c_str() );
	if( p.GetFormalList() ) {
		printf( ", " );
		p.GetFormalList()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CClassDeclList& p )//ClassDeclList
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CVarDeclList& p )
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CMethodDeclList& p )
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CStmList& p )
{
	p.GetTop()->Accept( this );
	if( p.GetTail() ) {
		p.GetTail()->Accept( this );
	}
}

void PrettyPrintVisitor::Visit( const CEmptyStm& p )
{
	// do nothing
}

void PrettyPrintVisitor::Visit( const CExpStm& p )
{
	printf( "%s", identt.c_str() );
	p.GetExp()->Accept(this);
	printf( ";" );
}<|endoftext|>


<commit_before>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <vw/gui/TileGenerator.h>
#include <vw/gui/ImageTileGenerator.h>
#include <vw/gui/PlatefileTileGenerator.h>
#include <vw/gui/TestPatternTileGenerator.h>
#include <vw/gui/WebTileGenerator.h>

#include <vw/Plate/HTTPUtils.h>
#include <vw/Core/Debugging.h>
#include <boost/filesystem/convenience.hpp>

namespace fs = boost::filesystem;
using namespace vw::platefile;

namespace vw { namespace gui {

ConstantSrc::ConstantSrc(const uint8* data, size_t size, const ImageFormat& fmt)
  : m_fmt(fmt), m_size(size), m_data(new uint8[m_size]) {
    VW_ASSERT(size >= fmt.byte_size(), LogicErr() << VW_CURRENT_FUNCTION << ": ImageFormat does not match data");
    std::copy(data+0, data+size, const_cast<uint8*>(&m_data[0]));
}

void ConstantSrc::read( ImageBuffer const& dst, BBox2i const& bbox ) const {
  VW_ASSERT( dst.format.cols == size_t(bbox.width()) && dst.format.rows == size_t(bbox.height()),
             ArgumentErr() << VW_CURRENT_FUNCTION << ": Destination buffer has wrong dimensions!" );
  VW_ASSERT( dst.format.cols == size_t(cols()) && dst.format.rows == size_t(rows()),
             ArgumentErr() << VW_CURRENT_FUNCTION << ": Partial reads are not supported");

  const ImageBuffer src(m_fmt, const_cast<uint8*>(m_data.get()));
  convert(dst, src, true);
}

BBox2i tile_to_bbox(Vector2i tile_size, int col, int row, int level, int max_level) {
  if (col < 0 || row < 0 || col >= (1 << max_level) || row >= (1 << max_level) ) {
    return BBox2i();
  } else {
    BBox2i result(tile_size[0]*col, tile_size[1]*row, tile_size[0], tile_size[1]);
    return result * (1 << (max_level - level));
  }
}

std::list<TileLocator> bbox_to_tiles(Vector2i tile_size, BBox2i bbox, int level, int max_level, int transaction_id, bool exact_transaction_id_match) {
  std::list<TileLocator> results;

  // Compute the bounding box at the current level.
  BBox2i level_bbox = bbox / (1 << (max_level - level));

  // Grow that bounding box to align with tile boundaries
  BBox2i aligned_level_bbox = level_bbox;
  aligned_level_bbox.min().x() = ( (level_bbox.min().x() / tile_size[0]) * tile_size[0] );
  aligned_level_bbox.min().y() = ( (level_bbox.min().y() / tile_size[1]) * tile_size[1] );
  aligned_level_bbox.max().x() = ( int(ceilf( float(level_bbox.max().x()) / float(tile_size[0]) ))
                                   * tile_size[0] );
  aligned_level_bbox.max().y() = ( int(ceilf( float(level_bbox.max().y()) / float(tile_size[1]) ))
                                   * tile_size[1] );

  int tile_y = aligned_level_bbox.min().y() / tile_size[1];
  int dest_row = 0;
  while ( tile_y < aligned_level_bbox.max().y() / tile_size[1] ) {

    int tile_x = aligned_level_bbox.min().x() / tile_size[0];
    int dest_col = 0;
    while ( tile_x < aligned_level_bbox.max().x() / tile_size[0] ) {
      BBox2i tile_bbox(dest_col, dest_row, tile_size[0], tile_size[1]);
      TileLocator loc;
      loc.col = tile_x;
      loc.row = tile_y;
      loc.level = level;
      loc.transaction_id = transaction_id;
      loc.exact_transaction_id_match = exact_transaction_id_match;
      results.push_back(loc);

      ++tile_x;
      dest_col += tile_size[0];
    }
    ++tile_y;
    dest_row += tile_size[1];
  }
  return results;
}

boost::shared_ptr<TileGenerator> TileGenerator::create(std::string filename_) {

  // Remove trailing /
  boost::trim_right_if(filename_, boost::is_any_of("/"));
  Url u(filename_);

  try {
    if (u.scheme() == "http") {
      return boost::shared_ptr<TileGenerator>( new WebTileGenerator(u.string(),17));
    } else if (u.scheme() == "file") {
      if (fs::extension(u.path()) == ".plate")
        return boost::shared_ptr<TileGenerator>( new PlatefileTileGenerator(u.path()) );
      else if (u.path() == "testpattern")
        return boost::shared_ptr<TileGenerator>( new TestPatternTileGenerator(256) );
      else
        return boost::shared_ptr<TileGenerator>( new ImageTileGenerator(u.path()) );
    } else {
      std::cerr << "Could not open " << u << ":\n\t" << "No handler for url scheme " << u.scheme() << std::endl;
    }
  } catch (const vw::Exception& e) {
    std::cerr << "Could not open " << u << ":\n\t" << e.what() << std::endl;
  }
  exit(EXIT_FAILURE);
}

}} // namespace vw::gui
<commit_msg>Add back vwv ability to read local pf:/// urls<commit_after>// __BEGIN_LICENSE__
// Copyright (C) 2006-2010 United States Government as represented by
// the Administrator of the National Aeronautics and Space Administration.
// All Rights Reserved.
// __END_LICENSE__

#include <vw/gui/TileGenerator.h>
#include <vw/gui/ImageTileGenerator.h>
#include <vw/gui/PlatefileTileGenerator.h>
#include <vw/gui/TestPatternTileGenerator.h>
#include <vw/gui/WebTileGenerator.h>

#include <vw/Plate/HTTPUtils.h>
#include <vw/Core/Debugging.h>
#include <boost/filesystem/convenience.hpp>

namespace fs = boost::filesystem;
using namespace vw::platefile;

namespace vw { namespace gui {

ConstantSrc::ConstantSrc(const uint8* data, size_t size, const ImageFormat& fmt)
  : m_fmt(fmt), m_size(size), m_data(new uint8[m_size]) {
    VW_ASSERT(size >= fmt.byte_size(), LogicErr() << VW_CURRENT_FUNCTION << ": ImageFormat does not match data");
    std::copy(data+0, data+size, const_cast<uint8*>(&m_data[0]));
}

void ConstantSrc::read( ImageBuffer const& dst, BBox2i const& bbox ) const {
  VW_ASSERT( dst.format.cols == size_t(bbox.width()) && dst.format.rows == size_t(bbox.height()),
             ArgumentErr() << VW_CURRENT_FUNCTION << ": Destination buffer has wrong dimensions!" );
  VW_ASSERT( dst.format.cols == size_t(cols()) && dst.format.rows == size_t(rows()),
             ArgumentErr() << VW_CURRENT_FUNCTION << ": Partial reads are not supported");

  const ImageBuffer src(m_fmt, const_cast<uint8*>(m_data.get()));
  convert(dst, src, true);
}

BBox2i tile_to_bbox(Vector2i tile_size, int col, int row, int level, int max_level) {
  if (col < 0 || row < 0 || col >= (1 << max_level) || row >= (1 << max_level) ) {
    return BBox2i();
  } else {
    BBox2i result(tile_size[0]*col, tile_size[1]*row, tile_size[0], tile_size[1]);
    return result * (1 << (max_level - level));
  }
}

std::list<TileLocator> bbox_to_tiles(Vector2i tile_size, BBox2i bbox, int level, int max_level, int transaction_id, bool exact_transaction_id_match) {
  std::list<TileLocator> results;

  // Compute the bounding box at the current level.
  BBox2i level_bbox = bbox / (1 << (max_level - level));

  // Grow that bounding box to align with tile boundaries
  BBox2i aligned_level_bbox = level_bbox;
  aligned_level_bbox.min().x() = ( (level_bbox.min().x() / tile_size[0]) * tile_size[0] );
  aligned_level_bbox.min().y() = ( (level_bbox.min().y() / tile_size[1]) * tile_size[1] );
  aligned_level_bbox.max().x() = ( int(ceilf( float(level_bbox.max().x()) / float(tile_size[0]) ))
                                   * tile_size[0] );
  aligned_level_bbox.max().y() = ( int(ceilf( float(level_bbox.max().y()) / float(tile_size[1]) ))
                                   * tile_size[1] );

  int tile_y = aligned_level_bbox.min().y() / tile_size[1];
  int dest_row = 0;
  while ( tile_y < aligned_level_bbox.max().y() / tile_size[1] ) {

    int tile_x = aligned_level_bbox.min().x() / tile_size[0];
    int dest_col = 0;
    while ( tile_x < aligned_level_bbox.max().x() / tile_size[0] ) {
      BBox2i tile_bbox(dest_col, dest_row, tile_size[0], tile_size[1]);
      TileLocator loc;
      loc.col = tile_x;
      loc.row = tile_y;
      loc.level = level;
      loc.transaction_id = transaction_id;
      loc.exact_transaction_id_match = exact_transaction_id_match;
      results.push_back(loc);

      ++tile_x;
      dest_col += tile_size[0];
    }
    ++tile_y;
    dest_row += tile_size[1];
  }
  return results;
}

boost::shared_ptr<TileGenerator> TileGenerator::create(std::string filename_) {

  // Remove trailing /
  boost::trim_right_if(filename_, boost::is_any_of("/"));
  Url u(filename_);

  try {
    if (u.scheme() == "http") {
      return boost::shared_ptr<TileGenerator>( new WebTileGenerator(u.string(),17));
    } else if (u.scheme() == "file") {
      if (fs::extension(u.path()) == ".plate")
        return boost::shared_ptr<TileGenerator>( new PlatefileTileGenerator(u.path()) );
      else if (u.path() == "testpattern")
        return boost::shared_ptr<TileGenerator>( new TestPatternTileGenerator(256) );
      else
        return boost::shared_ptr<TileGenerator>( new ImageTileGenerator(u.path()) );
    } else if (u.scheme() == "pf" && fs::extension(u.path()) == ".plate") {
      std::cout << "Loading: " << u.path() << "\n";
      return boost::shared_ptr<TileGenerator>( new PlatefileTileGenerator(u.string()) );
    } else {
      std::cerr << "Could not open " << u << ":\n\t" << "No handler for url scheme " << u.scheme() << std::endl;
    }
  } catch (const vw::Exception& e) {
    std::cerr << "Could not open " << u << ":\n\t" << e.what() << std::endl;
  }
  exit(EXIT_FAILURE);
}

}} // namespace vw::gui
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------//
//!
//! \file   Utility_TetrahedronHelpers.cpp
//! \author Alex Robinson, Eli Moll
//! \brief  Tetrahedron helper functions
//!
//---------------------------------------------------------------------------//

// Std Lib Includes
#include <math.h>

// Trilinos Includes
#include <Teuchos_ScalarTraits.hpp>

// FRENSIE Includes
#include "Utility_TetrahedronHelpers.hpp"
#include "Utility_ContractException.hpp"
#include <moab/Matrix3.hpp>

namespace Utility{

// Calculate the volume of a tetrahedron
double calculateTetrahedronVolume( const double vertex_a[3],
				   const double vertex_b[3],
				   const double vertex_c[3],
				   const double vertex_d[3] )
{
  double a1 = vertex_a[0] - vertex_d[0];
  double a2 = vertex_a[1] - vertex_d[1];
  double a3 = vertex_a[2] - vertex_d[2];
  double b1 = vertex_b[0] - vertex_d[0];
  double b2 = vertex_b[1] - vertex_d[1];
  double b3 = vertex_b[2] - vertex_d[2];
  double c1 = vertex_c[0] - vertex_d[0];
  double c2 = vertex_c[1] - vertex_d[1];
  double c3 = vertex_c[2] - vertex_d[2];

  double volume =
    fabs( a1*(b2*c3-b3*c2) + a2*(b3*c1-b1*c3) + a3*(b1*c2-b2*c1) )/6.0;

  testPostcondition( !Teuchos::ScalarTraits<double>::isnaninf( volume ) );
  testPostcondition( volume > 0.0 );

  return volume;
}

// Calculate the Barycentric Transform Matrix
double calculateBarycentricTransformMatrix(  const double vertex_a[3],
				              const double vertex_b[3],
				              const double vertex_c[3],
				              const double vertex_d[3] )
{
  double t1 = 1.0;//vertex_a[0] - vertex_d[0];
  double t2 = 5.0;//vertex_b[0] - vertex_d[0];
  double t3 = 1.0;//vertex_c[0] - vertex_d[0];
  double t4 = 1.0;//vertex_a[1] - vertex_d[1];
  double t5 = 1.0;//vertex_b[1] - vertex_d[1];
  double t6 = 1.0;//vertex_c[1] - vertex_d[1];
  double t7 = 1.0;//vertex_a[2] - vertex_d[2];
  double t8 = 1.0;//vertex_b[2] - vertex_d[2];
  double t9 = 1.0;//vertex_c[2] - vertex_d[2];

  moab::Matrix3 T( t1, t2, t3, t4, t5, t6, t7, t8, t9 );
  T = T.inversion();

  double tArray[9]
  tArray[0] = T.operator( 0, 0 );
  tArray[0] = T.operator( 0, 1 );
  tArray[0] = T.operator( 0, 2 );
  tArray[0] = T.operator( 1, 0 );
  tArray[0] = T.operator( 1, 1 );
  tArray[0] = T.operator( 1, 2 );
  tArray[0] = T.operator( 2, 0 );
  tArray[0] = T.operator( 2, 1 );
  tArray[0] = T.operator( 2, 2 );

  return tArray;
}

} // end Utility namespace

//---------------------------------------------------------------------------//
// end Utility_TetrahedronHelpers.cpp
//---------------------------------------------------------------------------//
<commit_msg>inversion -> inverse<commit_after>//---------------------------------------------------------------------------//
//!
//! \file   Utility_TetrahedronHelpers.cpp
//! \author Alex Robinson, Eli Moll
//! \brief  Tetrahedron helper functions
//!
//---------------------------------------------------------------------------//

// Std Lib Includes
#include <math.h>

// Trilinos Includes
#include <Teuchos_ScalarTraits.hpp>

// FRENSIE Includes
#include "Utility_TetrahedronHelpers.hpp"
#include "Utility_ContractException.hpp"
#include <moab/Matrix3.hpp>

namespace Utility{

// Calculate the volume of a tetrahedron
double calculateTetrahedronVolume( const double vertex_a[3],
				   const double vertex_b[3],
				   const double vertex_c[3],
				   const double vertex_d[3] )
{
  double a1 = vertex_a[0] - vertex_d[0];
  double a2 = vertex_a[1] - vertex_d[1];
  double a3 = vertex_a[2] - vertex_d[2];
  double b1 = vertex_b[0] - vertex_d[0];
  double b2 = vertex_b[1] - vertex_d[1];
  double b3 = vertex_b[2] - vertex_d[2];
  double c1 = vertex_c[0] - vertex_d[0];
  double c2 = vertex_c[1] - vertex_d[1];
  double c3 = vertex_c[2] - vertex_d[2];

  double volume =
    fabs( a1*(b2*c3-b3*c2) + a2*(b3*c1-b1*c3) + a3*(b1*c2-b2*c1) )/6.0;

  testPostcondition( !Teuchos::ScalarTraits<double>::isnaninf( volume ) );
  testPostcondition( volume > 0.0 );

  return volume;
}

// Calculate the Barycentric Transform Matrix
double calculateBarycentricTransformMatrix(  const double vertex_a[3],
				              const double vertex_b[3],
				              const double vertex_c[3],
				              const double vertex_d[3] )
{
  double t1 = 1.0;//vertex_a[0] - vertex_d[0];
  double t2 = 5.0;//vertex_b[0] - vertex_d[0];
  double t3 = 1.0;//vertex_c[0] - vertex_d[0];
  double t4 = 1.0;//vertex_a[1] - vertex_d[1];
  double t5 = 1.0;//vertex_b[1] - vertex_d[1];
  double t6 = 1.0;//vertex_c[1] - vertex_d[1];
  double t7 = 1.0;//vertex_a[2] - vertex_d[2];
  double t8 = 1.0;//vertex_b[2] - vertex_d[2];
  double t9 = 1.0;//vertex_c[2] - vertex_d[2];

  moab::Matrix3 T( t1, t2, t3, t4, t5, t6, t7, t8, t9 );
  T = T.inverse();

  double tArray[9]
  tArray[0] = T.operator( 0, 0 );
  tArray[0] = T.operator( 0, 1 );
  tArray[0] = T.operator( 0, 2 );
  tArray[0] = T.operator( 1, 0 );
  tArray[0] = T.operator( 1, 1 );
  tArray[0] = T.operator( 1, 2 );
  tArray[0] = T.operator( 2, 0 );
  tArray[0] = T.operator( 2, 1 );
  tArray[0] = T.operator( 2, 2 );

  return tArray;
}

} // end Utility namespace

//---------------------------------------------------------------------------//
// end Utility_TetrahedronHelpers.cpp
//---------------------------------------------------------------------------//
<|endoftext|>


<commit_before>#include <string.h>
#include "JWModules.hpp"
#include "JWResizableHandle.hpp"

#define BUFFER_SIZE 512

struct FullScope : Module {
	enum ParamIds {
		X_SCALE_PARAM,
		X_POS_PARAM,
		Y_SCALE_PARAM,
		Y_POS_PARAM,
		TIME_PARAM,
		LISSAJOUS_PARAM,
		TRIG_PARAM,
		EXTERNAL_PARAM,
		ROTATION_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		X_INPUT,
		Y_INPUT,
		TRIG_INPUT,
		COLOR_INPUT,
		TIME_INPUT,
		ROTATION_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		NUM_OUTPUTS
	};

	float bufferX[BUFFER_SIZE] = {};
	float bufferY[BUFFER_SIZE] = {};
	int bufferIndex = 0;
	float frameIndex = 0;

	SchmittTrigger sumTrigger;
	SchmittTrigger extTrigger;
	bool lissajous = true;
	bool external = false;
	float lights[4] = {};
	SchmittTrigger resetTrigger;

	FullScope() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {}
	void step() override;

	json_t *dataToJson() override {
		json_t *rootJ = json_object();
		json_object_set_new(rootJ, "lissajous", json_integer((int) lissajous));
		json_object_set_new(rootJ, "external", json_integer((int) external));
		return rootJ;
	}

	void dataFromJson(json_t *rootJ) override {
		json_t *sumJ = json_object_get(rootJ, "lissajous");
		if (sumJ)
			lissajous = json_integer_value(sumJ);

		json_t *extJ = json_object_get(rootJ, "external");
		if (extJ)
			external = json_integer_value(extJ);
	}

	void onReset() override {
		lissajous = true;
		external = false;
	}
};

void FullScope::step() {
	lights[0] = lissajous ? 0.0 : 1.0;
	lights[1] = lissajous ? 1.0 : 0.0;

	if (extTrigger.process(params[EXTERNAL_PARAM].value)) {
		external = !external;
	}
	lights[2] = external ? 0.0 : 1.0;
	lights[3] = external ? 1.0 : 0.0;

	// Compute time
	float deltaTime = powf(2.0, params[TIME_PARAM].value + inputs[TIME_INPUT].value);
	int frameCount = (int)ceilf(deltaTime * engineGetSampleRate());

	// Add frame to buffer
	if (bufferIndex < BUFFER_SIZE) {
		if (++frameIndex > frameCount) {
			frameIndex = 0;
			bufferX[bufferIndex] = inputs[X_INPUT].value;
			bufferY[bufferIndex] = inputs[Y_INPUT].value;
			bufferIndex++;
		}
	}

	// Are we waiting on the next trigger?
	if (bufferIndex >= BUFFER_SIZE) {
		// Trigger immediately if external but nothing plugged in, or in Lissajous mode
		if (lissajous || (external && !inputs[TRIG_INPUT].active)) {
			bufferIndex = 0;
			frameIndex = 0;
			return;
		}

		// Reset the Schmitt trigger so we don't trigger immediately if the input is high
		if (frameIndex == 0) {
			resetTrigger.reset();
		}
		frameIndex++;

		// Must go below 0.1V to trigger
		// resetTrigger.setThresholds(params[TRIG_PARAM].value - 0.1, params[TRIG_PARAM].value);
		float gate = external ? inputs[TRIG_INPUT].value : inputs[X_INPUT].value;

		// Reset if triggered
		float holdTime = 0.1;
		if (resetTrigger.process(gate) || (frameIndex >= engineGetSampleRate() * holdTime)) {
			bufferIndex = 0; frameIndex = 0; return;
		}

		// Reset if we've waited too long
		if (frameIndex >= engineGetSampleRate() * holdTime) {
			bufferIndex = 0; frameIndex = 0; return;
		}
	}
}

struct FullScopeDisplay : TransparentWidget {
	FullScope *module;
	int frame = 0;
	float rot = 0;
	std::shared_ptr<Font> font;

	struct Stats {
		float vrms, vpp, vmin, vmax;
		void calculate(float *values) {
			vrms = 0.0;
			vmax = -INFINITY;
			vmin = INFINITY;
			for (int i = 0; i < BUFFER_SIZE; i++) {
				float v = values[i];
				vrms += v*v;
				vmax = fmaxf(vmax, v);
				vmin = fminf(vmin, v);
			}
			vrms = sqrtf(vrms / BUFFER_SIZE);
			vpp = vmax - vmin;
		}
	};
	Stats statsX, statsY;

	FullScopeDisplay() {
	}

	void drawWaveform(NVGcontext *vg, float *valuesX, float *valuesY) {
		if (!valuesX)
			return;
		nvgSave(vg);
		Rect b = Rect(Vec(0, 0), box.size);
		nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y);

		float rotRate = rescalefjw(module->params[FullScope::ROTATION_PARAM].value + module->inputs[FullScope::ROTATION_INPUT].value, 0, 10, 0, 0.5);
		if(rotRate != 0){
			nvgTranslate(vg, box.size.x/2.0, box.size.y/2.0);
			nvgRotate(vg, rot+=rotRate);
			nvgTranslate(vg, -box.size.x/2.0, -box.size.y/2.0);
		} else {
			nvgRotate(vg, 0);
		}

		nvgBeginPath(vg);
		// Draw maximum display left to right
		for (int i = 0; i < BUFFER_SIZE; i++) {
			float x, y;
			if (valuesY) {
				x = valuesX[i] / 2.0 + 0.5;
				y = valuesY[i] / 2.0 + 0.5;
			}
			else {
				x = (float)i / (BUFFER_SIZE - 1);
				y = valuesX[i] / 2.0 + 0.5;
			}
			Vec p;
			p.x = b.pos.x + b.size.x * x;
			p.y = b.pos.y + b.size.y * (1.0 - y);
			if (i == 0)
				nvgMoveTo(vg, p.x, p.y);
			else
				nvgLineTo(vg, p.x, p.y);
		}
		nvgLineCap(vg, NVG_ROUND);
		nvgMiterLimit(vg, 2.0);
		nvgStrokeWidth(vg, 1.5);
		nvgGlobalCompositeOperation(vg, NVG_LIGHTER);
		nvgStroke(vg);
		nvgResetScissor(vg);
		nvgRestore(vg);
	}

	void draw(NVGcontext *vg) {
		if(module == NULL) return;

		float gainX = powf(2.0, roundf(module->params[FullScope::X_SCALE_PARAM].value));
		float gainY = powf(2.0, roundf(module->params[FullScope::Y_SCALE_PARAM].value));
		float offsetX = module->params[FullScope::X_POS_PARAM].value;
		float offsetY = module->params[FullScope::Y_POS_PARAM].value;

		float valuesX[BUFFER_SIZE];
		float valuesY[BUFFER_SIZE];
		for (int i = 0; i < BUFFER_SIZE; i++) {
			int j = i;
			// Lock display to buffer if buffer update deltaTime <= 2^-11
			if (module->lissajous)
				j = (i + module->bufferIndex) % BUFFER_SIZE;
			valuesX[i] = (module->bufferX[j] + offsetX) * gainX / 10.0;
			valuesY[i] = (module->bufferY[j] + offsetY) * gainY / 10.0;
		}

		//color
		if(module->inputs[FullScope::COLOR_INPUT].active){
			float hue = rescalefjw(module->inputs[FullScope::COLOR_INPUT].value, 0.0, 6.0, 0, 1.0);
			nvgStrokeColor(vg, nvgHSLA(hue, 0.5, 0.5, 0xc0));
		} else {
			nvgStrokeColor(vg, nvgRGBA(25, 150, 252, 0xc0));
		}

		// Draw waveforms
		if (module->lissajous) {
			// X x Y
			if (module->inputs[FullScope::X_INPUT].active || module->inputs[FullScope::Y_INPUT].active) {
				drawWaveform(vg, valuesX, valuesY);
			}
		}
		else {
			// Y
			if (module->inputs[FullScope::Y_INPUT].active) {
				drawWaveform(vg, valuesY, NULL);
			}

			// X
			if (module->inputs[FullScope::X_INPUT].active) {
				nvgStrokeColor(vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xc0));
				drawWaveform(vg, valuesX, NULL);
			}
		}

		// Calculate stats
		if (++frame >= 4) {
			frame = 0;
			statsX.calculate(module->bufferX);
			statsY.calculate(module->bufferY);
		}
	}
};

struct FullScopeWidget : ModuleWidget {
	BGPanel *panel;
	JWModuleResizeHandle *leftHandle;
	JWModuleResizeHandle *rightHandle;
	TransparentWidget *display;
	FullScopeWidget(FullScope *module);
	void step() override;
	json_t *toJson() override;
	void fromJson(json_t *rootJ) override;
	void appendContextMenu(Menu *menu) override;
};

FullScopeWidget::FullScopeWidget(FullScope *module) : ModuleWidget(module) {
	box.size = Vec(RACK_GRID_WIDTH*17, RACK_GRID_HEIGHT);

	{
		panel = new BGPanel(nvgRGB(20, 30, 33));
		panel->box.size = box.size;
		addChild(panel);
	}

//TODO fix resize isn't working
	leftHandle = new JWModuleResizeHandle(box.size.x);
	rightHandle = new JWModuleResizeHandle(box.size.x);
	rightHandle->right = true;
	addChild(leftHandle);
	addChild(rightHandle);

	{
		FullScopeDisplay *display = new FullScopeDisplay();
		display->module = module;
		display->box.pos = Vec(0, 0);
		display->box.size = Vec(box.size.x, box.size.y);
		addChild(display);
		this->display = display;
	}

	int compX = 5, compY = -15, adder = 20;
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::X_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::Y_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::COLOR_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::ROTATION_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::TIME_INPUT));

	//TODO add labels to all params

	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::X_POS_PARAM, -10.0, 10.0, 0.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::Y_POS_PARAM, -10.0, 10.0, 0.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::X_SCALE_PARAM, -2.0, 8.0, 1.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::Y_SCALE_PARAM, -2.0, 8.0, 1.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::ROTATION_PARAM, -10.0, 10.0, 0));
	//last knob isn't turning?????
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::TIME_PARAM, -6.0, -16.0, -14.0));

	addChild(createWidget<Screw_J>(Vec(compX+2, compY+=adder)));
	addChild(createWidget<Screw_W>(Vec(compX+2, compY+=adder-5)));
}

void FullScopeWidget::step() {
	// panel->box.size = box.size;
	display->box.size = Vec(box.size.x, box.size.y);
	rightHandle->box.pos.x = box.size.x - rightHandle->box.size.x;
	rightHandle->box.pos.y = box.size.y - rightHandle->box.size.y;
	leftHandle->box.pos.y = box.size.y - leftHandle->box.size.y;
	ModuleWidget::step();
}

json_t *FullScopeWidget::toJson() {
	json_t *rootJ = ModuleWidget::toJson();
	json_object_set_new(rootJ, "width", json_real(box.size.x));
	json_object_set_new(rootJ, "height", json_real(box.size.y));
	return rootJ;
}

void FullScopeWidget::fromJson(json_t *rootJ) {
	ModuleWidget::fromJson(rootJ);
	json_t *widthJ = json_object_get(rootJ, "width");
	if (widthJ)
		box.size.x = json_number_value(widthJ);
	json_t *heightJ = json_object_get(rootJ, "height");
	if (heightJ)
		box.size.y = json_number_value(heightJ);
}

struct FullScopeLissajousModeMenuItem : MenuItem {
	FullScope *fullScope;
	void onAction(const event::Action &e) override {
		fullScope->lissajous = !fullScope->lissajous;
	}
	void step() override {
		rightText = (fullScope->lissajous) ? "✔" : "";
	}
};

void FullScopeWidget::appendContextMenu(Menu *menu) {
	MenuLabel *spacerLabel = new MenuLabel();
	menu->addChild(spacerLabel);

	FullScope *fullScope = dynamic_cast<FullScope*>(module);
	assert(fullScope);

	FullScopeLissajousModeMenuItem *lissMenuItem = new FullScopeLissajousModeMenuItem();
	lissMenuItem->text = "Lissajous Mode";
	lissMenuItem->fullScope = fullScope;
	menu->addChild(lissMenuItem);
}

Model *modelFullScope = createModel<FullScope, FullScopeWidget>("FullScope");
<commit_msg>removed comment<commit_after>#include <string.h>
#include "JWModules.hpp"
#include "JWResizableHandle.hpp"

#define BUFFER_SIZE 512

struct FullScope : Module {
	enum ParamIds {
		X_SCALE_PARAM,
		X_POS_PARAM,
		Y_SCALE_PARAM,
		Y_POS_PARAM,
		TIME_PARAM,
		LISSAJOUS_PARAM,
		TRIG_PARAM,
		EXTERNAL_PARAM,
		ROTATION_PARAM,
		NUM_PARAMS
	};
	enum InputIds {
		X_INPUT,
		Y_INPUT,
		TRIG_INPUT,
		COLOR_INPUT,
		TIME_INPUT,
		ROTATION_INPUT,
		NUM_INPUTS
	};
	enum OutputIds {
		NUM_OUTPUTS
	};

	float bufferX[BUFFER_SIZE] = {};
	float bufferY[BUFFER_SIZE] = {};
	int bufferIndex = 0;
	float frameIndex = 0;

	SchmittTrigger sumTrigger;
	SchmittTrigger extTrigger;
	bool lissajous = true;
	bool external = false;
	float lights[4] = {};
	SchmittTrigger resetTrigger;

	FullScope() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {}
	void step() override;

	json_t *dataToJson() override {
		json_t *rootJ = json_object();
		json_object_set_new(rootJ, "lissajous", json_integer((int) lissajous));
		json_object_set_new(rootJ, "external", json_integer((int) external));
		return rootJ;
	}

	void dataFromJson(json_t *rootJ) override {
		json_t *sumJ = json_object_get(rootJ, "lissajous");
		if (sumJ)
			lissajous = json_integer_value(sumJ);

		json_t *extJ = json_object_get(rootJ, "external");
		if (extJ)
			external = json_integer_value(extJ);
	}

	void onReset() override {
		lissajous = true;
		external = false;
	}
};

void FullScope::step() {
	lights[0] = lissajous ? 0.0 : 1.0;
	lights[1] = lissajous ? 1.0 : 0.0;

	if (extTrigger.process(params[EXTERNAL_PARAM].value)) {
		external = !external;
	}
	lights[2] = external ? 0.0 : 1.0;
	lights[3] = external ? 1.0 : 0.0;

	// Compute time
	float deltaTime = powf(2.0, params[TIME_PARAM].value + inputs[TIME_INPUT].value);
	int frameCount = (int)ceilf(deltaTime * engineGetSampleRate());

	// Add frame to buffer
	if (bufferIndex < BUFFER_SIZE) {
		if (++frameIndex > frameCount) {
			frameIndex = 0;
			bufferX[bufferIndex] = inputs[X_INPUT].value;
			bufferY[bufferIndex] = inputs[Y_INPUT].value;
			bufferIndex++;
		}
	}

	// Are we waiting on the next trigger?
	if (bufferIndex >= BUFFER_SIZE) {
		// Trigger immediately if external but nothing plugged in, or in Lissajous mode
		if (lissajous || (external && !inputs[TRIG_INPUT].active)) {
			bufferIndex = 0;
			frameIndex = 0;
			return;
		}

		// Reset the Schmitt trigger so we don't trigger immediately if the input is high
		if (frameIndex == 0) {
			resetTrigger.reset();
		}
		frameIndex++;

		// Must go below 0.1V to trigger
		// resetTrigger.setThresholds(params[TRIG_PARAM].value - 0.1, params[TRIG_PARAM].value);
		float gate = external ? inputs[TRIG_INPUT].value : inputs[X_INPUT].value;

		// Reset if triggered
		float holdTime = 0.1;
		if (resetTrigger.process(gate) || (frameIndex >= engineGetSampleRate() * holdTime)) {
			bufferIndex = 0; frameIndex = 0; return;
		}

		// Reset if we've waited too long
		if (frameIndex >= engineGetSampleRate() * holdTime) {
			bufferIndex = 0; frameIndex = 0; return;
		}
	}
}

struct FullScopeDisplay : TransparentWidget {
	FullScope *module;
	int frame = 0;
	float rot = 0;
	std::shared_ptr<Font> font;

	struct Stats {
		float vrms, vpp, vmin, vmax;
		void calculate(float *values) {
			vrms = 0.0;
			vmax = -INFINITY;
			vmin = INFINITY;
			for (int i = 0; i < BUFFER_SIZE; i++) {
				float v = values[i];
				vrms += v*v;
				vmax = fmaxf(vmax, v);
				vmin = fminf(vmin, v);
			}
			vrms = sqrtf(vrms / BUFFER_SIZE);
			vpp = vmax - vmin;
		}
	};
	Stats statsX, statsY;

	FullScopeDisplay() {
	}

	void drawWaveform(NVGcontext *vg, float *valuesX, float *valuesY) {
		if (!valuesX)
			return;
		nvgSave(vg);
		Rect b = Rect(Vec(0, 0), box.size);
		nvgScissor(vg, b.pos.x, b.pos.y, b.size.x, b.size.y);

		float rotRate = rescalefjw(module->params[FullScope::ROTATION_PARAM].value + module->inputs[FullScope::ROTATION_INPUT].value, 0, 10, 0, 0.5);
		if(rotRate != 0){
			nvgTranslate(vg, box.size.x/2.0, box.size.y/2.0);
			nvgRotate(vg, rot+=rotRate);
			nvgTranslate(vg, -box.size.x/2.0, -box.size.y/2.0);
		} else {
			nvgRotate(vg, 0);
		}

		nvgBeginPath(vg);
		// Draw maximum display left to right
		for (int i = 0; i < BUFFER_SIZE; i++) {
			float x, y;
			if (valuesY) {
				x = valuesX[i] / 2.0 + 0.5;
				y = valuesY[i] / 2.0 + 0.5;
			}
			else {
				x = (float)i / (BUFFER_SIZE - 1);
				y = valuesX[i] / 2.0 + 0.5;
			}
			Vec p;
			p.x = b.pos.x + b.size.x * x;
			p.y = b.pos.y + b.size.y * (1.0 - y);
			if (i == 0)
				nvgMoveTo(vg, p.x, p.y);
			else
				nvgLineTo(vg, p.x, p.y);
		}
		nvgLineCap(vg, NVG_ROUND);
		nvgMiterLimit(vg, 2.0);
		nvgStrokeWidth(vg, 1.5);
		nvgGlobalCompositeOperation(vg, NVG_LIGHTER);
		nvgStroke(vg);
		nvgResetScissor(vg);
		nvgRestore(vg);
	}

	void draw(NVGcontext *vg) {
		if(module == NULL) return;

		float gainX = powf(2.0, roundf(module->params[FullScope::X_SCALE_PARAM].value));
		float gainY = powf(2.0, roundf(module->params[FullScope::Y_SCALE_PARAM].value));
		float offsetX = module->params[FullScope::X_POS_PARAM].value;
		float offsetY = module->params[FullScope::Y_POS_PARAM].value;

		float valuesX[BUFFER_SIZE];
		float valuesY[BUFFER_SIZE];
		for (int i = 0; i < BUFFER_SIZE; i++) {
			int j = i;
			// Lock display to buffer if buffer update deltaTime <= 2^-11
			if (module->lissajous)
				j = (i + module->bufferIndex) % BUFFER_SIZE;
			valuesX[i] = (module->bufferX[j] + offsetX) * gainX / 10.0;
			valuesY[i] = (module->bufferY[j] + offsetY) * gainY / 10.0;
		}

		//color
		if(module->inputs[FullScope::COLOR_INPUT].active){
			float hue = rescalefjw(module->inputs[FullScope::COLOR_INPUT].value, 0.0, 6.0, 0, 1.0);
			nvgStrokeColor(vg, nvgHSLA(hue, 0.5, 0.5, 0xc0));
		} else {
			nvgStrokeColor(vg, nvgRGBA(25, 150, 252, 0xc0));
		}

		// Draw waveforms
		if (module->lissajous) {
			// X x Y
			if (module->inputs[FullScope::X_INPUT].active || module->inputs[FullScope::Y_INPUT].active) {
				drawWaveform(vg, valuesX, valuesY);
			}
		}
		else {
			// Y
			if (module->inputs[FullScope::Y_INPUT].active) {
				drawWaveform(vg, valuesY, NULL);
			}

			// X
			if (module->inputs[FullScope::X_INPUT].active) {
				nvgStrokeColor(vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xc0));
				drawWaveform(vg, valuesX, NULL);
			}
		}

		// Calculate stats
		if (++frame >= 4) {
			frame = 0;
			statsX.calculate(module->bufferX);
			statsY.calculate(module->bufferY);
		}
	}
};

struct FullScopeWidget : ModuleWidget {
	BGPanel *panel;
	JWModuleResizeHandle *leftHandle;
	JWModuleResizeHandle *rightHandle;
	TransparentWidget *display;
	FullScopeWidget(FullScope *module);
	void step() override;
	json_t *toJson() override;
	void fromJson(json_t *rootJ) override;
	void appendContextMenu(Menu *menu) override;
};

FullScopeWidget::FullScopeWidget(FullScope *module) : ModuleWidget(module) {
	box.size = Vec(RACK_GRID_WIDTH*17, RACK_GRID_HEIGHT);

	{
		panel = new BGPanel(nvgRGB(20, 30, 33));
		panel->box.size = box.size;
		addChild(panel);
	}

//TODO fix resize isn't working
	leftHandle = new JWModuleResizeHandle(box.size.x);
	rightHandle = new JWModuleResizeHandle(box.size.x);
	rightHandle->right = true;
	addChild(leftHandle);
	addChild(rightHandle);

	{
		FullScopeDisplay *display = new FullScopeDisplay();
		display->module = module;
		display->box.pos = Vec(0, 0);
		display->box.size = Vec(box.size.x, box.size.y);
		addChild(display);
		this->display = display;
	}

	int compX = 5, compY = -15, adder = 20;
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::X_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::Y_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::COLOR_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::ROTATION_INPUT));
	addInput(createPort<TinyPJ301MPort>(Vec(compX, compY+=adder), PortWidget::INPUT, module, FullScope::TIME_INPUT));

	//TODO add labels to all params

	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::X_POS_PARAM, -10.0, 10.0, 0.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::Y_POS_PARAM, -10.0, 10.0, 0.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::X_SCALE_PARAM, -2.0, 8.0, 1.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::Y_SCALE_PARAM, -2.0, 8.0, 1.0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::ROTATION_PARAM, -10.0, 10.0, 0));
	addParam(createParam<JwTinyKnob>(Vec(compX, compY+=adder), module, FullScope::TIME_PARAM, -6.0, -16.0, -14.0));

	addChild(createWidget<Screw_J>(Vec(compX+2, compY+=adder)));
	addChild(createWidget<Screw_W>(Vec(compX+2, compY+=adder-5)));
}

void FullScopeWidget::step() {
	// panel->box.size = box.size;
	display->box.size = Vec(box.size.x, box.size.y);
	rightHandle->box.pos.x = box.size.x - rightHandle->box.size.x;
	rightHandle->box.pos.y = box.size.y - rightHandle->box.size.y;
	leftHandle->box.pos.y = box.size.y - leftHandle->box.size.y;
	ModuleWidget::step();
}

json_t *FullScopeWidget::toJson() {
	json_t *rootJ = ModuleWidget::toJson();
	json_object_set_new(rootJ, "width", json_real(box.size.x));
	json_object_set_new(rootJ, "height", json_real(box.size.y));
	return rootJ;
}

void FullScopeWidget::fromJson(json_t *rootJ) {
	ModuleWidget::fromJson(rootJ);
	json_t *widthJ = json_object_get(rootJ, "width");
	if (widthJ)
		box.size.x = json_number_value(widthJ);
	json_t *heightJ = json_object_get(rootJ, "height");
	if (heightJ)
		box.size.y = json_number_value(heightJ);
}

struct FullScopeLissajousModeMenuItem : MenuItem {
	FullScope *fullScope;
	void onAction(const event::Action &e) override {
		fullScope->lissajous = !fullScope->lissajous;
	}
	void step() override {
		rightText = (fullScope->lissajous) ? "✔" : "";
	}
};

void FullScopeWidget::appendContextMenu(Menu *menu) {
	MenuLabel *spacerLabel = new MenuLabel();
	menu->addChild(spacerLabel);

	FullScope *fullScope = dynamic_cast<FullScope*>(module);
	assert(fullScope);

	FullScopeLissajousModeMenuItem *lissMenuItem = new FullScopeLissajousModeMenuItem();
	lissMenuItem->text = "Lissajous Mode";
	lissMenuItem->fullScope = fullScope;
	menu->addChild(lissMenuItem);
}

Model *modelFullScope = createModel<FullScope, FullScopeWidget>("FullScope");
<|endoftext|>