<commit_before>/*
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Gabriel Ebner
*/
#include "util/log_tree.h"
#include "util/task_builder.h"
#include <vector>
#include <string>

namespace lean {

void log_tree::notify_core(std::vector<log_tree::event> const & events) {
    if (events.empty()) return;
    for (auto & l : m_listeners)
        l(events);
}

void log_tree::add_listener(log_tree::listener const & l) {
    unique_lock<mutex> lock(m_mutex);
    m_listeners.push_back(l);
}

log_tree::log_tree() {
    auto cell = new node_cell;
    cell->m_tree = this;
    m_root = node(cell);
}

log_tree::~log_tree() {
    std::vector<event> evs;
    m_root.detach_core(evs);
    m_root = node();
}

void log_tree::print_to(std::ostream & out) const {
    get_root().print_to(out, 0);
}

void log_tree::print() const {
    print_to(std::cerr);
}

void log_tree::node::for_each(std::function<bool(log_tree::node const &)> const & fn) const { // NOLINT
    if (fn(*this)) {
        get_children().for_each([&] (name const &, log_tree::node const & c) {
            c.for_each(fn);
        });
    }
};

void log_tree::for_each(std::function<bool(log_tree::node const &)> const & fn) const { // NOLINT
    m_root.for_each(fn);
};

void log_tree::node::detach_core(std::vector<log_tree::event> & events) const {
    if (m_ptr->m_detached) return;
    m_ptr->m_detached = true;
    m_ptr->m_children.for_each([&] (name const &, node const & c) { c.detach_core(events); });
    for (auto & e : m_ptr->m_entries) events.push_back({ event::EntryRemoved, m_ptr, e });
    if (m_ptr->m_producer) events.push_back({event::Finished, m_ptr, {}});
}

void log_tree::node::notify(std::vector<log_tree::event> const & events, unique_lock<mutex> & l) const {
    if (!m_ptr->m_detached) {
        l.unlock();
        m_ptr->m_tree->notify_core(events);
    }
}

log_tree::node log_tree::node::clone_core() const {
    auto copy = node(new node_cell);
    copy.m_ptr->m_children = m_ptr->m_children;
    m_ptr->m_children.clear();
    copy.m_ptr->m_tree = m_ptr->m_tree;
    copy.m_ptr->m_detached = m_ptr->m_detached;
    copy.m_ptr->m_entries = m_ptr->m_entries;
    m_ptr->m_detached = true;
    return copy;
}

void log_tree::node::clear_entries() const {
    auto l = lock();

    std::vector<event> events;
    for (auto & e : m_ptr->m_entries) {
        events.push_back({event::EntryRemoved, *this, std::move(e)});
    }
    m_ptr->m_entries.clear();

    notify(events, l);
}

void log_tree::node::add(log_entry const & entry) const {
    auto l = lock();
    m_ptr->m_entries.push_back(entry);
    notify({{event::EntryAdded, *this, entry}}, l);
}

log_tree::node log_tree::node::mk_child(name n, std::string const & description, location const & loc,
                                        bool overwrite) {
    auto l = lock();
    std::vector<event> events;

    if (!overwrite && (n.is_anonymous() || m_ptr->m_used_names.contains(n))) {
        for (unsigned i = 0;; i++) {
            name n_(n, i);
            if (!m_ptr->m_used_names.contains(n_)) {
                n = n_;
                break;
            }
        }
    }
    m_ptr->m_used_names.insert(n);

    node child;
    if (auto existing = m_ptr->m_children.find(n)) {
        child = existing->clone_core();
        existing->detach_core(events);
    } else {
        child = node(new node_cell);
        child.m_ptr->m_tree = m_ptr->m_tree;
        child.m_ptr->m_detached = m_ptr->m_detached;
    }
    child.m_ptr->m_description = description;
    child.m_ptr->m_location = loc;
    m_ptr->m_children.insert(n, child);

    notify(events, l);
    return child;
}

void log_tree::node::set_producer(gtask const & prod) {
    auto l = lock();
    m_ptr->m_producer = prod;
    notify({{event::ProducerSet, *this, {}}}, l);
}

void log_tree::node::finish() const {
    auto l = lock();
    std::vector<event> events;
    m_ptr->m_producer.reset();

    buffer<pair<name, node>> to_delete;
    m_ptr->m_children.for_each([&] (name const & n, node const & c) {
        if (!m_ptr->m_used_names.contains(n))
            to_delete.emplace_back(n, c);
    });

    for (auto & c : to_delete) {
        m_ptr->m_children.erase(c.first);
        c.second.detach_core(events);
    }

    events.push_back({event::Finished, *this, {}});
    notify(events, l);
}

std::vector<log_entry> log_tree::node::get_entries() const {
    auto l = lock();
    return m_ptr->m_entries;
}

name_map<lean::log_tree::node> log_tree::node::get_children() const {
    auto l = lock();
    return m_ptr->m_children;
}

void log_tree::node::remove_child(name const & n) const {
    auto l = lock();
    if (auto c = m_ptr->m_children.find(n)) {
        m_ptr->m_children.erase(n);
        std::vector<event> events;
        c->detach_core(events);
        notify(events, l);
    }
}

name_map<log_tree::node> log_tree::node::get_used_children() const {
    auto l = lock();
    name_map<node> used_children;
    m_ptr->m_used_names.for_each([&] (name const & n) {
        if (auto c = m_ptr->m_children.find(n)) {
            used_children.insert(n, *c);
        }
    });
    return used_children;
}

void log_tree::node::reuse(name const & n) const {
    auto l = lock();
    m_ptr->m_used_names.insert(n);
}

name_set log_tree::node::get_used_names() const {
    auto l = lock();
    return m_ptr->m_used_names;
}

gtask log_tree::node::get_producer() const {
    auto l = lock();
    return m_ptr->m_producer;
}

void log_tree::node::print() const {
    print_to(std::cerr, 0);
}

void log_tree::node::print_to(std::ostream & out, unsigned indent) const {
    indent += 2;

    auto l = lock();
    auto begin = m_ptr->m_location.m_range.m_begin, end = m_ptr->m_location.m_range.m_end;
    out << m_ptr->m_location.m_file_name
        << ": " << begin.first << ":" << begin.second << " -- " << end.first << ":" << end.second << ": "
        << m_ptr->m_description << " ("
        << m_ptr->m_entries.size()
        << " entries, producer = "
        << std::hex << reinterpret_cast<uintptr_t>(m_ptr->m_producer.get()) << std::dec
        << ")" << std::endl;

    if (auto prod = m_ptr->m_producer) {
        if (auto ex = prod->peek_exception()) {
            for (unsigned i = 0; i < indent; i++) out << ' ';
            out << "producer threw exception: ";
            try {
                std::rethrow_exception(ex);
            } catch (std::exception & ex) {
                out << ex.what();
            } catch (cancellation_exception) {
                out << "<cancelled>";
            } catch (...) {
                out << "<unknown exception>";
            }
            out << "\n";
        }
    }

    auto children = m_ptr->m_children;
    auto used_names = m_ptr->m_used_names;
    l.unlock();

    children.for_each([&] (name const & n, log_tree::node const & c) {
        for (unsigned i = 0; i < indent; i++) out << ' ';
        out << n;
        if (!used_names.contains(n))
            out << " (unused)";
        out << ": ";
        c.print_to(out, indent);
    });
}

gtask log_tree::node::wait_for_finish() const {
    auto t = *this;
    return mk_dependency_task([t] (buffer<gtask> & deps) {
        t.for_each([&] (node const & n) {
            if (auto prod = n.get_producer())
                deps.push_back(prod);
            return true;
        });
    });
}

bool log_tree::node::has_entry_now(std::function<bool(log_entry const &)> const & fn) const { // NOLINT
    bool res = false;
    for_each([&] (node const & n) {
        if (res) return false;
        for (auto & e : n.get_entries()) {
            if (fn(e)) {
                res = true;
                break;
            }
        }
        return !res;
    });
    return res;
}

task<bool> log_tree::node::has_entry(std::function<bool(log_entry const &)> const & fn) const { // NOLINT
    auto t = *this;
    return task_builder<bool>([t, fn] { return t.has_entry_now(fn); }).depends_on(wait_for_finish()).build();
}

LEAN_THREAD_PTR(log_tree::node, g_log_tree);
scope_log_tree_core::scope_log_tree_core(log_tree::node * lt) : flet<log_tree::node *>(g_log_tree, lt) {}

log_tree::node & logtree() {
    if (g_log_tree) {
        return *g_log_tree;
    } else {
        throw exception("no log tree in scope");
    }
}

scope_log_tree::scope_log_tree(log_tree::node const & lt) : m_node(lt), m_scope(&m_node) {
    m_node.clear_entries();
}

scope_log_tree::~scope_log_tree() {
    logtree().finish();
}

scope_log_tree::scope_log_tree(std::string const & desc, pos_range const & pos) :
        scope_log_tree(logtree().mk_child({}, desc, {logtree().get_location().m_file_name, pos})) {}

scope_log_tree::scope_log_tree(std::string const & desc) :
        scope_log_tree(logtree().mk_child({}, desc, logtree().get_location())) {}

scope_log_tree::scope_log_tree() : scope_log_tree(std::string()) {}

}
<commit_msg>fix(util/log_tree): fix reference cycle between log_tree and tasks<commit_after>/*
Copyright (c) 2017 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Gabriel Ebner
*/
#include "util/log_tree.h"
#include "util/task_builder.h"
#include <vector>
#include <string>

namespace lean {

void log_tree::notify_core(std::vector<log_tree::event> const & events) {
    if (events.empty()) return;
    for (auto & l : m_listeners)
        l(events);
}

void log_tree::add_listener(log_tree::listener const & l) {
    unique_lock<mutex> lock(m_mutex);
    m_listeners.push_back(l);
}

log_tree::log_tree() {
    auto cell = new node_cell;
    cell->m_tree = this;
    m_root = node(cell);
}

log_tree::~log_tree() {
    std::vector<event> evs;
    m_root.detach_core(evs);
    m_root = node();
}

void log_tree::print_to(std::ostream & out) const {
    get_root().print_to(out, 0);
}

void log_tree::print() const {
    print_to(std::cerr);
}

void log_tree::node::for_each(std::function<bool(log_tree::node const &)> const & fn) const { // NOLINT
    if (fn(*this)) {
        get_children().for_each([&] (name const &, log_tree::node const & c) {
            c.for_each(fn);
        });
    }
};

void log_tree::for_each(std::function<bool(log_tree::node const &)> const & fn) const { // NOLINT
    m_root.for_each(fn);
};

void log_tree::node::detach_core(std::vector<log_tree::event> & events) const {
    if (m_ptr->m_detached) return;
    m_ptr->m_detached = true;
    m_ptr->m_children.for_each([&] (name const &, node const & c) { c.detach_core(events); });
    for (auto & e : m_ptr->m_entries) events.push_back({ event::EntryRemoved, m_ptr, e });
    if (m_ptr->m_producer) events.push_back({event::Finished, m_ptr, {}});
    m_ptr->m_producer = nullptr;
}

void log_tree::node::notify(std::vector<log_tree::event> const & events, unique_lock<mutex> & l) const {
    if (!m_ptr->m_detached) {
        l.unlock();
        m_ptr->m_tree->notify_core(events);
    }
}

log_tree::node log_tree::node::clone_core() const {
    auto copy = node(new node_cell);
    copy.m_ptr->m_children = m_ptr->m_children;
    m_ptr->m_children.clear();
    copy.m_ptr->m_tree = m_ptr->m_tree;
    copy.m_ptr->m_detached = m_ptr->m_detached;
    copy.m_ptr->m_entries = m_ptr->m_entries;
    m_ptr->m_detached = true;
    return copy;
}

void log_tree::node::clear_entries() const {
    auto l = lock();

    std::vector<event> events;
    for (auto & e : m_ptr->m_entries) {
        events.push_back({event::EntryRemoved, *this, std::move(e)});
    }
    m_ptr->m_entries.clear();

    notify(events, l);
}

void log_tree::node::add(log_entry const & entry) const {
    auto l = lock();
    m_ptr->m_entries.push_back(entry);
    notify({{event::EntryAdded, *this, entry}}, l);
}

log_tree::node log_tree::node::mk_child(name n, std::string const & description, location const & loc,
                                        bool overwrite) {
    auto l = lock();
    std::vector<event> events;

    if (!overwrite && (n.is_anonymous() || m_ptr->m_used_names.contains(n))) {
        for (unsigned i = 0;; i++) {
            name n_(n, i);
            if (!m_ptr->m_used_names.contains(n_)) {
                n = n_;
                break;
            }
        }
    }
    m_ptr->m_used_names.insert(n);

    node child;
    if (auto existing = m_ptr->m_children.find(n)) {
        child = existing->clone_core();
        existing->detach_core(events);
    } else {
        child = node(new node_cell);
        child.m_ptr->m_tree = m_ptr->m_tree;
        child.m_ptr->m_detached = m_ptr->m_detached;
    }
    child.m_ptr->m_description = description;
    child.m_ptr->m_location = loc;
    m_ptr->m_children.insert(n, child);

    notify(events, l);
    return child;
}

void log_tree::node::set_producer(gtask const & prod) {
    auto l = lock();
    if (m_ptr->m_detached) return;
    m_ptr->m_producer = prod;
    notify({{event::ProducerSet, *this, {}}}, l);
}

void log_tree::node::finish() const {
    auto l = lock();
    std::vector<event> events;
    m_ptr->m_producer.reset();

    buffer<pair<name, node>> to_delete;
    m_ptr->m_children.for_each([&] (name const & n, node const & c) {
        if (!m_ptr->m_used_names.contains(n))
            to_delete.emplace_back(n, c);
    });

    for (auto & c : to_delete) {
        m_ptr->m_children.erase(c.first);
        c.second.detach_core(events);
    }

    events.push_back({event::Finished, *this, {}});
    notify(events, l);
}

std::vector<log_entry> log_tree::node::get_entries() const {
    auto l = lock();
    return m_ptr->m_entries;
}

name_map<lean::log_tree::node> log_tree::node::get_children() const {
    auto l = lock();
    return m_ptr->m_children;
}

void log_tree::node::remove_child(name const & n) const {
    auto l = lock();
    if (auto c = m_ptr->m_children.find(n)) {
        m_ptr->m_children.erase(n);
        std::vector<event> events;
        c->detach_core(events);
        notify(events, l);
    }
}

name_map<log_tree::node> log_tree::node::get_used_children() const {
    auto l = lock();
    name_map<node> used_children;
    m_ptr->m_used_names.for_each([&] (name const & n) {
        if (auto c = m_ptr->m_children.find(n)) {
            used_children.insert(n, *c);
        }
    });
    return used_children;
}

void log_tree::node::reuse(name const & n) const {
    auto l = lock();
    m_ptr->m_used_names.insert(n);
}

name_set log_tree::node::get_used_names() const {
    auto l = lock();
    return m_ptr->m_used_names;
}

gtask log_tree::node::get_producer() const {
    auto l = lock();
    return m_ptr->m_producer;
}

void log_tree::node::print() const {
    print_to(std::cerr, 0);
}

void log_tree::node::print_to(std::ostream & out, unsigned indent) const {
    indent += 2;

    auto l = lock();
    auto begin = m_ptr->m_location.m_range.m_begin, end = m_ptr->m_location.m_range.m_end;
    out << m_ptr->m_location.m_file_name
        << ": " << begin.first << ":" << begin.second << " -- " << end.first << ":" << end.second << ": "
        << m_ptr->m_description << " ("
        << m_ptr->m_entries.size()
        << " entries, producer = "
        << std::hex << reinterpret_cast<uintptr_t>(m_ptr->m_producer.get()) << std::dec
        << ")" << std::endl;

    if (auto prod = m_ptr->m_producer) {
        if (auto ex = prod->peek_exception()) {
            for (unsigned i = 0; i < indent; i++) out << ' ';
            out << "producer threw exception: ";
            try {
                std::rethrow_exception(ex);
            } catch (std::exception & ex) {
                out << ex.what();
            } catch (cancellation_exception) {
                out << "<cancelled>";
            } catch (...) {
                out << "<unknown exception>";
            }
            out << "\n";
        }
    }

    auto children = m_ptr->m_children;
    auto used_names = m_ptr->m_used_names;
    l.unlock();

    children.for_each([&] (name const & n, log_tree::node const & c) {
        for (unsigned i = 0; i < indent; i++) out << ' ';
        out << n;
        if (!used_names.contains(n))
            out << " (unused)";
        out << ": ";
        c.print_to(out, indent);
    });
}

gtask log_tree::node::wait_for_finish() const {
    auto t = *this;
    return mk_dependency_task([t] (buffer<gtask> & deps) {
        t.for_each([&] (node const & n) {
            if (auto prod = n.get_producer())
                deps.push_back(prod);
            return true;
        });
    });
}

bool log_tree::node::has_entry_now(std::function<bool(log_entry const &)> const & fn) const { // NOLINT
    bool res = false;
    for_each([&] (node const & n) {
        if (res) return false;
        for (auto & e : n.get_entries()) {
            if (fn(e)) {
                res = true;
                break;
            }
        }
        return !res;
    });
    return res;
}

task<bool> log_tree::node::has_entry(std::function<bool(log_entry const &)> const & fn) const { // NOLINT
    auto t = *this;
    return task_builder<bool>([t, fn] { return t.has_entry_now(fn); }).depends_on(wait_for_finish()).build();
}

LEAN_THREAD_PTR(log_tree::node, g_log_tree);
scope_log_tree_core::scope_log_tree_core(log_tree::node * lt) : flet<log_tree::node *>(g_log_tree, lt) {}

log_tree::node & logtree() {
    if (g_log_tree) {
        return *g_log_tree;
    } else {
        throw exception("no log tree in scope");
    }
}

scope_log_tree::scope_log_tree(log_tree::node const & lt) : m_node(lt), m_scope(&m_node) {
    m_node.clear_entries();
}

scope_log_tree::~scope_log_tree() {
    logtree().finish();
}

scope_log_tree::scope_log_tree(std::string const & desc, pos_range const & pos) :
        scope_log_tree(logtree().mk_child({}, desc, {logtree().get_location().m_file_name, pos})) {}

scope_log_tree::scope_log_tree(std::string const & desc) :
        scope_log_tree(logtree().mk_child({}, desc, logtree().get_location())) {}

scope_log_tree::scope_log_tree() : scope_log_tree(std::string()) {}

}
<|endoftext|>


<commit_before>#include "rubykokuban/BindImage.hpp"

#include "mruby.h"
#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#include "ofMain.h"

namespace rubykokuban {

namespace {
void free(mrb_state *mrb, void *p)
{
    if (p) {
        delete ((ofImage*)p);
    }
}

struct mrb_data_type data_type = { "rubykokuban_image", free };

mrb_value load(mrb_state *mrb, mrb_value self)
{
    ofImage* obj = new ofImage();

    mrb_value str;
    mrb_get_args(mrb, "S", &str);

    string filename(mrb_string_value_ptr(mrb, str));
    obj->loadImage(filename);

    struct RData *data = mrb_data_object_alloc(mrb, mrb_class_ptr(self), obj, &data_type);
    return mrb_obj_value(data);
}

mrb_value draw(mrb_state *mrb, mrb_value self)
{
    mrb_int x, y;
    mrb_get_args(mrb, "ii", &x, &y);

    ofImage* obj = (ofImage*)DATA_PTR(self);
    obj->draw(x, y);
    return mrb_nil_value();
}
}

//--------------------------------------------------------------------------------
void BindImage::Bind(mrb_state* mrb)
{
    struct RClass *cc = mrb_define_class(mrb, "Image", mrb->object_class);
    mrb_define_class_method(mrb , cc, "load", load, MRB_ARGS_REQ(1));
    mrb_define_method(mrb, cc, "draw", draw, MRB_ARGS_REQ(2));}

}

<commit_msg>Add Image class empty interface<commit_after>#include "rubykokuban/BindImage.hpp"

#include "mruby.h"
#include "mruby/class.h"
#include "mruby/data.h"
#include "mruby/string.h"
#include "ofMain.h"

namespace rubykokuban {

namespace {
void free(mrb_state *mrb, void *p)
{
    if (p) {
        delete ((ofImage*)p);
    }
}

struct mrb_data_type data_type = { "rubykokuban_image", free };

mrb_value load(mrb_state *mrb, mrb_value self)
{
    ofImage* obj = new ofImage();

    mrb_value str;
    mrb_get_args(mrb, "S", &str);

    string filename(mrb_string_value_ptr(mrb, str));
    obj->loadImage(filename);

    struct RData *data = mrb_data_object_alloc(mrb, mrb_class_ptr(self), obj, &data_type);
    return mrb_obj_value(data);
}

mrb_value grab_screen(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value save(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value color(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value set_color(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value resize(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value set_image_type(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value crop_bang(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value crop(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value rotate90(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value mirror(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value update(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value set_anchor_percent(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value set_anchor_point(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value reset_anchor(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value draw(mrb_state *mrb, mrb_value self)
{
    mrb_int x, y;
    mrb_get_args(mrb, "ii", &x, &y);

    ofImage* obj = (ofImage*)DATA_PTR(self);
    obj->draw(x, y);

    return mrb_nil_value();
}

mrb_value draw_sub(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value height(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

mrb_value width(mrb_state *mrb, mrb_value self)
{
    return mrb_nil_value();
}

}

//--------------------------------------------------------------------------------
void BindImage::Bind(mrb_state* mrb)
{
    struct RClass *cc = mrb_define_class(mrb, "Image", mrb->object_class);

    mrb_define_class_method(mrb , cc, "load",               load,               MRB_ARGS_REQ(1));
    mrb_define_class_method(mrb , cc, "grab_screen",        grab_screen,        MRB_ARGS_REQ(4));

    mrb_define_method(mrb, cc,        "save",               save,               MRB_ARGS_ARG(2, 1));
    mrb_define_method(mrb, cc,        "color",              color,              MRB_ARGS_REQ(2));
    mrb_define_method(mrb, cc,        "set_color",          set_color,          MRB_ARGS_REQ(3));
    mrb_define_method(mrb, cc,        "resize",             resize,             MRB_ARGS_REQ(2));
    mrb_define_method(mrb, cc,        "set_image_type",     set_image_type,     MRB_ARGS_REQ(1));
    mrb_define_method(mrb, cc,        "crop",               crop,               MRB_ARGS_REQ(5));
    mrb_define_method(mrb, cc,        "crop!",              crop_bang,          MRB_ARGS_REQ(4));
    mrb_define_method(mrb, cc,        "rotate90",           rotate90,           MRB_ARGS_REQ(1));
    mrb_define_method(mrb, cc,        "mirror",             mirror,             MRB_ARGS_REQ(2));
    mrb_define_method(mrb, cc,        "update",             update,             MRB_ARGS_NONE());
    mrb_define_method(mrb, cc,        "set_anchor_percent", set_anchor_percent, MRB_ARGS_REQ(2));
    mrb_define_method(mrb, cc,        "set_anchor_point",   set_anchor_point,   MRB_ARGS_REQ(2));
    mrb_define_method(mrb, cc,        "reset_anchor",       reset_anchor,       MRB_ARGS_REQ(2));
    mrb_define_method(mrb, cc,        "draw",               draw,               MRB_ARGS_ARG(2, 3));
    mrb_define_method(mrb, cc,        "draw_sub",           draw_sub,           MRB_ARGS_ARG(6, 2));
    mrb_define_method(mrb, cc,        "height",             height,             MRB_ARGS_NONE());
    mrb_define_method(mrb, cc,        "width",              width,              MRB_ARGS_NONE());
}

}
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <algorithm>                    /* for lower_bound() */
#include <cstring>
#include <fstream>

#include <curl/curl.h>

#include <zorba/config.h>

#ifdef WIN32
#include "system/globalenv.h"
#endif /* WIN32 */

#ifndef ZORBA_WITH_REST
#include "zorbaerrors/error_manager.h"
#endif
#include "zorbatypes/zstring.h"

#include "fs_util.h"
#include "less.h"
#include "string_util.h"
#include "uri_util.h"

using namespace std;

namespace zorba {
namespace uri {

///////////////////////////////////////////////////////////////////////////////

// This MUST be sorted.
char const *const scheme_string[] = {
  "#none",
  "#unknown",
  "file",
  "ftp",
  "http",
  "https",
  "mailto"
};

///////////////////////////////////////////////////////////////////////////////

ZORBA_DLL_PUBLIC extern signed char const hex2dec[] = {
  /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */
  /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,

  /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,

  /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,

  /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
};

/**
 * Characters that need not be percent-encoded (%xx) in URIs.  See RFC 3986.
 */
ZORBA_DLL_PUBLIC extern char const uri_safe[256] = {
  /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F   */
  /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
  /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,

  /*        ! " #  $ % & '  ( ) * +  , - . /   */
  /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,1,1,0,

  /*      0 1 2 3  4 5 6 7  8 9 : ;  < = > ?   */
  /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,

  /*      @ A B C  D E F G  H I J K  L M N O   */
  /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,

  /*      P Q R S  T U V W  X Y Z [  \ ] ^ _   */
  /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1,

  /*      ` a b c  d e f g  h i j k  l m n o   */
  /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,

  /*      p q r s  t u v w  x y z {  | } ~     */
  /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,1,0,
};

///////////////////////////////////////////////////////////////////////////////

static size_t curl_write_fn( void *ptr, size_t size, size_t nmemb,
                             void *data ) {
  char const *const char_buf = static_cast<char const*>( ptr );
  size_t const real_size = size * nmemb;
  iostream &stream = *static_cast<iostream*>( data );

  stream.write( char_buf, static_cast<streamsize>( real_size ) );
  // TODO: should check to see if write() failed
  return real_size;
}

void fetch( char const *uri, iostream &result ) {
#ifdef ZORBA_WITH_REST
  //
  // Having cURL initialization wrapped by a class and using a singleton static
  // instance guarantees that cURL is initialized exactly once before use and
  // and also is cleaned-up at program termination (when destructors for static
  // objects are called).
  //
  struct curl_initializer {
    curl_initializer() {
      if ( CURLcode curl_code = curl_global_init( CURL_GLOBAL_ALL ) )
        throw fetch_exception( curl_easy_strerror( curl_code ) );
    }
    ~curl_initializer() {
      curl_global_cleanup();
    }
  };
  static curl_initializer initializer;

  CURL *curl = curl_easy_init();
  curl_easy_setopt( curl, CURLOPT_URL, uri );
  curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curl_write_fn );
  curl_easy_setopt( curl, CURLOPT_WRITEDATA, static_cast<void*>( &result ) );

  // Tells cURL to fail silently if the HTTP code returned >= 400.
  curl_easy_setopt( curl, CURLOPT_FAILONERROR, 1 );

  // Tells cURL to follow redirects. CURLOPT_MAXREDIRS is by default set to -1
  // thus cURL will do an infinite number of redirects.
  curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1 );

#ifndef ZORBA_VERIFY_PEER_SSL_CERTIFICATE
  curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 0 );
  //
  // CURLOPT_SSL_VERIFYHOST is left default, value 2, meaning verify that the
  // Common Name or Subject Alternate Name field in the certificate matches the
  // name of the server.
  //
  // tested with https://www.npr.org/rss/rss.php?id=1001
  // about using ssl certs in curl: http://curl.haxx.se/docs/sslcerts.html
#else
# ifdef WIN32
  // set the root CA certificates file path
  if ( GENV.g_curl_root_CA_certificates_path[0] )
    curl_easy_setopt(
      curl, CURLOPT_CAINFO, GENV.g_curl_root_CA_certificates_path
    );
# endif /* WIN32 */
#endif /* ZORBA_VERIFY_PEER_SSL_CERTIFICATE */

  //
  // Some servers don't like requests that are made without a user-agent field,
  // so we provide one.
  //
  curl_easy_setopt( curl, CURLOPT_USERAGENT, "libcurl-agent/1.0" );

  CURLcode const curl_code = curl_easy_perform( curl );
  if ( curl_code ) {
    //
    // Workaround for a problem in cURL: curl_easy_cleanup() fails if
    // curl_easy_perform() returned an error.
    //
    curl_easy_reset( curl );
  }
  curl_easy_cleanup( curl );
  if ( curl_code )
    throw fetch_exception( curl_easy_strerror( curl_code ) );
#else
  ZORBA_ERROR_PARAM( XQP0004_SYSTEM_NOT_SUPPORTED, "HTTP GET" , "" );
#endif /* ZORBA_WITH_REST */
}

void fetch_to_path_impl( char const *uri, char *path, bool *is_temp ) {
  zstring zpath;
  bool temp = false;
  switch ( get_scheme( uri ) ) {
    case file:
    case none:
      zpath = fs::get_normalized_path( uri );
      break;
    default:
      fs::get_temp_file( &zpath );
      fstream stream( zpath.c_str() );
      fetch( uri, stream );
      temp = true;
      break;
  }
  ::strncpy( path, zpath.c_str(), MAX_PATH );
  path[ MAX_PATH - 1 ] = '\0';
  if ( is_temp )
    *is_temp = temp;
}

scheme get_scheme( char const *uri ) {
  zstring scheme_name;
  if ( split( uri, ':', &scheme_name, NULL ) ) {
    static char const *const *const begin = scheme_string;
    static char const *const *const end =
      scheme_string + sizeof( scheme_string ) / sizeof( char* );

    char const *const s = scheme_name.c_str();
    char const *const *const entry =
      ::lower_bound( begin, end, s, less<char const*>() );
    return entry != end && ::strcmp( s, *entry ) == 0 ?
      static_cast<scheme>( entry - begin ) : unknown;
  }
  return none;
}

///////////////////////////////////////////////////////////////////////////////

} // namespace uri
} // namespace zorba
/* vim:set et sw=2 ts=2: */
<commit_msg>Added #ifdef ZORBA_WITH_REST.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <algorithm>                    /* for lower_bound() */
#include <cstring>
#include <fstream>

#include <zorba/config.h>

#ifdef ZORBA_WITH_REST
#include <curl/curl.h>
#endif

#ifdef WIN32
#include "system/globalenv.h"
#endif /* WIN32 */

#ifndef ZORBA_WITH_REST
#include "zorbaerrors/error_manager.h"
#endif
#include "zorbatypes/zstring.h"

#include "fs_util.h"
#include "less.h"
#include "string_util.h"
#include "uri_util.h"

using namespace std;

namespace zorba {
namespace uri {

///////////////////////////////////////////////////////////////////////////////

// This MUST be sorted.
char const *const scheme_string[] = {
  "#none",
  "#unknown",
  "file",
  "ftp",
  "http",
  "https",
  "mailto"
};

///////////////////////////////////////////////////////////////////////////////

ZORBA_DLL_PUBLIC extern signed char const hex2dec[] = {
  /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */
  /* 0 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 1 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 2 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 3 */  0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,

  /* 4 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 5 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 6 */ -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 7 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,

  /* 8 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* 9 */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* A */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* B */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,

  /* C */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* D */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* E */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
  /* F */ -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
};

/**
 * Characters that need not be percent-encoded (%xx) in URIs.  See RFC 3986.
 */
ZORBA_DLL_PUBLIC extern char const uri_safe[256] = {
  /*      0 1 2 3  4 5 6 7  8 9 A B  C D E F   */
  /* 0 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
  /* 1 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,

  /*        ! " #  $ % & '  ( ) * +  , - . /   */
  /* 2 */ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,1,1,0,

  /*      0 1 2 3  4 5 6 7  8 9 : ;  < = > ?   */
  /* 3 */ 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0,

  /*      @ A B C  D E F G  H I J K  L M N O   */
  /* 4 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,

  /*      P Q R S  T U V W  X Y Z [  \ ] ^ _   */
  /* 5 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1,

  /*      ` a b c  d e f g  h i j k  l m n o   */
  /* 6 */ 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,

  /*      p q r s  t u v w  x y z {  | } ~     */
  /* 7 */ 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,1,0,
};

///////////////////////////////////////////////////////////////////////////////

static size_t curl_write_fn( void *ptr, size_t size, size_t nmemb,
                             void *data ) {
  char const *const char_buf = static_cast<char const*>( ptr );
  size_t const real_size = size * nmemb;
  iostream &stream = *static_cast<iostream*>( data );

  stream.write( char_buf, static_cast<streamsize>( real_size ) );
  // TODO: should check to see if write() failed
  return real_size;
}

void fetch( char const *uri, iostream &result ) {
#ifdef ZORBA_WITH_REST
  //
  // Having cURL initialization wrapped by a class and using a singleton static
  // instance guarantees that cURL is initialized exactly once before use and
  // and also is cleaned-up at program termination (when destructors for static
  // objects are called).
  //
  struct curl_initializer {
    curl_initializer() {
      if ( CURLcode curl_code = curl_global_init( CURL_GLOBAL_ALL ) )
        throw fetch_exception( curl_easy_strerror( curl_code ) );
    }
    ~curl_initializer() {
      curl_global_cleanup();
    }
  };
  static curl_initializer initializer;

  CURL *curl = curl_easy_init();
  curl_easy_setopt( curl, CURLOPT_URL, uri );
  curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, curl_write_fn );
  curl_easy_setopt( curl, CURLOPT_WRITEDATA, static_cast<void*>( &result ) );

  // Tells cURL to fail silently if the HTTP code returned >= 400.
  curl_easy_setopt( curl, CURLOPT_FAILONERROR, 1 );

  // Tells cURL to follow redirects. CURLOPT_MAXREDIRS is by default set to -1
  // thus cURL will do an infinite number of redirects.
  curl_easy_setopt( curl, CURLOPT_FOLLOWLOCATION, 1 );

#ifndef ZORBA_VERIFY_PEER_SSL_CERTIFICATE
  curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 0 );
  //
  // CURLOPT_SSL_VERIFYHOST is left default, value 2, meaning verify that the
  // Common Name or Subject Alternate Name field in the certificate matches the
  // name of the server.
  //
  // tested with https://www.npr.org/rss/rss.php?id=1001
  // about using ssl certs in curl: http://curl.haxx.se/docs/sslcerts.html
#else
# ifdef WIN32
  // set the root CA certificates file path
  if ( GENV.g_curl_root_CA_certificates_path[0] )
    curl_easy_setopt(
      curl, CURLOPT_CAINFO, GENV.g_curl_root_CA_certificates_path
    );
# endif /* WIN32 */
#endif /* ZORBA_VERIFY_PEER_SSL_CERTIFICATE */

  //
  // Some servers don't like requests that are made without a user-agent field,
  // so we provide one.
  //
  curl_easy_setopt( curl, CURLOPT_USERAGENT, "libcurl-agent/1.0" );

  CURLcode const curl_code = curl_easy_perform( curl );
  if ( curl_code ) {
    //
    // Workaround for a problem in cURL: curl_easy_cleanup() fails if
    // curl_easy_perform() returned an error.
    //
    curl_easy_reset( curl );
  }
  curl_easy_cleanup( curl );
  if ( curl_code )
    throw fetch_exception( curl_easy_strerror( curl_code ) );
#else
  ZORBA_ERROR_PARAM( XQP0004_SYSTEM_NOT_SUPPORTED, "HTTP GET" , "" );
#endif /* ZORBA_WITH_REST */
}

void fetch_to_path_impl( char const *uri, char *path, bool *is_temp ) {
  zstring zpath;
  bool temp = false;
  switch ( get_scheme( uri ) ) {
    case file:
    case none:
      zpath = fs::get_normalized_path( uri );
      break;
    default:
      fs::get_temp_file( &zpath );
      fstream stream( zpath.c_str() );
      fetch( uri, stream );
      temp = true;
      break;
  }
  ::strncpy( path, zpath.c_str(), MAX_PATH );
  path[ MAX_PATH - 1 ] = '\0';
  if ( is_temp )
    *is_temp = temp;
}

scheme get_scheme( char const *uri ) {
  zstring scheme_name;
  if ( split( uri, ':', &scheme_name, NULL ) ) {
    static char const *const *const begin = scheme_string;
    static char const *const *const end =
      scheme_string + sizeof( scheme_string ) / sizeof( char* );

    char const *const s = scheme_name.c_str();
    char const *const *const entry =
      ::lower_bound( begin, end, s, less<char const*>() );
    return entry != end && ::strcmp( s, *entry ) == 0 ?
      static_cast<scheme>( entry - begin ) : unknown;
  }
  return none;
}

///////////////////////////////////////////////////////////////////////////////

} // namespace uri
} // namespace zorba
/* vim:set et sw=2 ts=2: */
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "PressureAction.h"
#include "Factory.h"
#include "FEProblem.h"
#include "Conversion.h"

registerMooseAction("TensorMechanicsApp", PressureAction, "add_bc");

InputParameters
PressureAction::validParams()
{
  InputParameters params = Action::validParams();
  params.addClassDescription("Set up Pressure boundary conditions");

  params.addRequiredParam<std::vector<BoundaryName>>(
      "boundary", "The list of boundary IDs from the mesh where the pressure will be applied");

  params.addParam<std::vector<VariableName>>(
      "displacements",
      "The displacements appropriate for the simulation geometry and coordinate system");

  params.addParam<std::vector<AuxVariableName>>("save_in_disp_x",
                                                "The save_in variables for x displacement");
  params.addParam<std::vector<AuxVariableName>>("save_in_disp_y",
                                                "The save_in variables for y displacement");
  params.addParam<std::vector<AuxVariableName>>("save_in_disp_z",
                                                "The save_in variables for z displacement");

  params.addParam<Real>("factor", 1.0, "The factor to use in computing the pressure");
  params.addParam<bool>("use_displaced_mesh", true, "Whether to use the displaced mesh.");
  params.addParam<Real>("hht_alpha",
                        0,
                        "alpha parameter for mass dependent numerical damping induced "
                        "by HHT time integration scheme");
  params.addDeprecatedParam<Real>(
      "alpha", "alpha parameter for HHT time integration", "Please use hht_alpha");
  params.addParam<FunctionName>("function", "The function that describes the pressure");
  params.addParam<bool>("use_automatic_differentiation",
                        false,
                        "Flag to use automatic differentiation (AD) objects when possible");
  return params;
}

PressureAction::PressureAction(const InputParameters & params)
  : Action(params), _use_ad(getParam<bool>("use_automatic_differentiation"))
{
  _save_in_vars.push_back(getParam<std::vector<AuxVariableName>>("save_in_disp_x"));
  _save_in_vars.push_back(getParam<std::vector<AuxVariableName>>("save_in_disp_y"));
  _save_in_vars.push_back(getParam<std::vector<AuxVariableName>>("save_in_disp_z"));

  _has_save_in_vars.push_back(params.isParamValid("save_in_disp_x"));
  _has_save_in_vars.push_back(params.isParamValid("save_in_disp_y"));
  _has_save_in_vars.push_back(params.isParamValid("save_in_disp_z"));
}

void
PressureAction::act()
{
  std::string ad_prepend = "";
  if (_use_ad)
    ad_prepend = "AD";

  std::string kernel_name = ad_prepend + "Pressure";

  std::vector<VariableName> displacements = getParam<std::vector<VariableName>>("displacements");

  // Create pressure BCs
  for (unsigned int i = 0; i < displacements.size(); ++i)
  {
    // Create unique kernel name for each of the components
    std::string unique_kernel_name = kernel_name + "_" + _name + "_" + Moose::stringify(i);

    InputParameters params = _factory.getValidParams(kernel_name);
    params.applyParameters(parameters(), {"factor"});
    params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
    params.set<Real>("alpha") =
        isParamValid("alpha") ? getParam<Real>("alpha") : getParam<Real>("hht_alpha");

    if (_use_ad)
      params.set<unsigned int>("component") = i;
    params.set<NonlinearVariableName>("variable") = displacements[i];

    if (_has_save_in_vars[i])
      params.set<std::vector<AuxVariableName>>("save_in") = _save_in_vars[i];

    if (_use_ad)
      params.set<Real>("constant") = getParam<Real>("factor");
    else
      params.set<Real>("factor") = getParam<Real>("factor");
    _problem->addBoundaryCondition(kernel_name, unique_kernel_name, params);
  }
}
<commit_msg>'component' is a deprecated parameter in Pressure BC (#15915)<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "PressureAction.h"
#include "Factory.h"
#include "FEProblem.h"
#include "Conversion.h"

registerMooseAction("TensorMechanicsApp", PressureAction, "add_bc");

InputParameters
PressureAction::validParams()
{
  InputParameters params = Action::validParams();
  params.addClassDescription("Set up Pressure boundary conditions");

  params.addRequiredParam<std::vector<BoundaryName>>(
      "boundary", "The list of boundary IDs from the mesh where the pressure will be applied");

  params.addParam<std::vector<VariableName>>(
      "displacements",
      "The displacements appropriate for the simulation geometry and coordinate system");

  params.addParam<std::vector<AuxVariableName>>("save_in_disp_x",
                                                "The save_in variables for x displacement");
  params.addParam<std::vector<AuxVariableName>>("save_in_disp_y",
                                                "The save_in variables for y displacement");
  params.addParam<std::vector<AuxVariableName>>("save_in_disp_z",
                                                "The save_in variables for z displacement");

  params.addParam<Real>("factor", 1.0, "The factor to use in computing the pressure");
  params.addParam<bool>("use_displaced_mesh", true, "Whether to use the displaced mesh.");
  params.addParam<Real>("hht_alpha",
                        0,
                        "alpha parameter for mass dependent numerical damping induced "
                        "by HHT time integration scheme");
  params.addDeprecatedParam<Real>(
      "alpha", "alpha parameter for HHT time integration", "Please use hht_alpha");
  params.addParam<FunctionName>("function", "The function that describes the pressure");
  params.addParam<bool>("use_automatic_differentiation",
                        false,
                        "Flag to use automatic differentiation (AD) objects when possible");
  return params;
}

PressureAction::PressureAction(const InputParameters & params)
  : Action(params), _use_ad(getParam<bool>("use_automatic_differentiation"))
{
  _save_in_vars.push_back(getParam<std::vector<AuxVariableName>>("save_in_disp_x"));
  _save_in_vars.push_back(getParam<std::vector<AuxVariableName>>("save_in_disp_y"));
  _save_in_vars.push_back(getParam<std::vector<AuxVariableName>>("save_in_disp_z"));

  _has_save_in_vars.push_back(params.isParamValid("save_in_disp_x"));
  _has_save_in_vars.push_back(params.isParamValid("save_in_disp_y"));
  _has_save_in_vars.push_back(params.isParamValid("save_in_disp_z"));
}

void
PressureAction::act()
{
  std::string ad_prepend = "";
  if (_use_ad)
    ad_prepend = "AD";

  std::string kernel_name = ad_prepend + "Pressure";

  std::vector<VariableName> displacements = getParam<std::vector<VariableName>>("displacements");

  // Create pressure BCs
  for (unsigned int i = 0; i < displacements.size(); ++i)
  {
    // Create unique kernel name for each of the components
    std::string unique_kernel_name = kernel_name + "_" + _name + "_" + Moose::stringify(i);

    InputParameters params = _factory.getValidParams(kernel_name);
    params.applyParameters(parameters(), {"factor"});
    params.set<bool>("use_displaced_mesh") = getParam<bool>("use_displaced_mesh");
    params.set<Real>("alpha") =
        isParamValid("alpha") ? getParam<Real>("alpha") : getParam<Real>("hht_alpha");

    params.set<NonlinearVariableName>("variable") = displacements[i];

    if (_has_save_in_vars[i])
      params.set<std::vector<AuxVariableName>>("save_in") = _save_in_vars[i];

    if (_use_ad)
      params.set<Real>("constant") = getParam<Real>("factor");
    else
      params.set<Real>("factor") = getParam<Real>("factor");
    _problem->addBoundaryCondition(kernel_name, unique_kernel_name, params);
  }
}
<|endoftext|>


<commit_before>#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <srt/srt.h>

#define DEBUG

#ifdef DEBUG
#include <android/log.h>
#define LOG_TAG "SRT-JNI"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#else
#define LOGI(...)
#define LOGD(...)
#define LOGE(...)
#define LOGW(...)
#endif

/**
* JNI のパッケージ名、クラス名を定義.
*/
#define JNI_METHOD_NAME(name) Java_org_deviceconnect_android_libsrt_NdkHelper_##name

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL
JNI_METHOD_NAME(startup)(JNIEnv *env, jclass clazz) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_startup()");
    srt_startup();
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(cleanup)(JNIEnv *env, jclass clazz) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_cleanup()");
    srt_cleanup();
}

JNIEXPORT jlong JNICALL
JNI_METHOD_NAME(createSrtSocket)(JNIEnv *env, jclass clazz, jstring address, jint port, jint backlog) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_createSrtSocket()");

    int yes = 1;
    int st;
    int ss = srt_create_socket();
    if (ss == SRT_ERROR) {
        LOGE("srt_socket: %s", srt_getlasterror_str());
        return -1;
    }

    const char *addressString = env->GetStringUTFChars(address, nullptr);
    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    if (inet_pton(AF_INET, addressString, &sa.sin_addr) != 1) {
        LOGE("inet_pton error.");
        env->ReleaseStringUTFChars(address, addressString);
        return -1;
    }
    env->ReleaseStringUTFChars(address, addressString);

    srt_setsockflag(ss, SRTO_RCVSYN, &yes, sizeof yes);

    st = srt_bind(ss, (struct sockaddr*)&sa, sizeof sa);
    if (st == SRT_ERROR) {
        LOGE("srt_bind: %s", srt_getlasterror_str());
        return -1;
    }

    st = srt_listen(ss, backlog);
    if (st == SRT_ERROR) {
        LOGE("srt_listen: %s\n", srt_getlasterror_str());
        return -1;
    }

    return ss;
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(closeSrtSocket)(JNIEnv *env, jclass clazz, jlong ptr) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_closeSrtSocket()");

    int st = srt_close((int) ptr);
    if (st == SRT_ERROR) {
        LOGE("srt_close: %s\n", srt_getlasterror_str());
    }
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(accept)(JNIEnv *env, jclass clazz, jlong ptr, jobject socket) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_accept()");

    struct sockaddr addr;
    int addrlen;
    int st = srt_accept((int) ptr, &addr, &addrlen);
    if (st == SRT_ERROR) {
        LOGE("srt_accept: %s\n", srt_getlasterror_str());
        return;
    }

    // クライアント側のソケットへのポインタ
    jclass socketCls = env->FindClass("org/deviceconnect/android/libsrt/SRTSocket");
    jfieldID socketPtr = env->GetFieldID(socketCls, "mNativePtr", "J");
    env->SetLongField(socket, socketPtr, st);

    // クライアントのIPアドレス
    char format[] = "%d.%d.%d.%d";
    char buf[15];
    sprintf(buf, format, addr.sa_data[2], addr.sa_data[3], addr.sa_data[4], addr.sa_data[5]);
    jstring address = env->NewStringUTF(buf);
    jfieldID addressField = env->GetFieldID(socketCls, "mSocketAddress", "Ljava/lang/String;");
    env->SetObjectField(socket, addressField, address);
}

JNIEXPORT int JNICALL
JNI_METHOD_NAME(sendMessage)(JNIEnv *env, jclass clazz, jlong ptr, jbyteArray byteArray, jint offset, jint length) {
    jboolean isCopy;
    jbyte* data = env->GetByteArrayElements(byteArray, &isCopy);
    if (data == nullptr) {
        return -1;
    }

    int result = srt_sendmsg((int) ptr, (const char *) &data[offset], length, -1, 0);
    if (result < SRT_ERROR) {
        LOGE("srt_send: %s\n", srt_getlasterror_str());
    }
    env->ReleaseByteArrayElements(byteArray, data, 0);
    return result;
}

JNIEXPORT int JNICALL
JNI_METHOD_NAME(recvMessage)(JNIEnv *env, jclass clazz, jlong ptr, jbyteArray byteArray, jint length) {
    jboolean isCopy;
    jbyte* data = env->GetByteArrayElements(byteArray, &isCopy);
    if (data == nullptr) {
        return -1;
    }

    int result = srt_recvmsg((int) ptr, (char *) data, length);
    if (result < SRT_ERROR) {
        LOGE("srt_send: %s\n", srt_getlasterror_str());
    }
    env->ReleaseByteArrayElements(byteArray, data, 0);
    return result;
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(dumpStats)(JNIEnv *env, jclass clazz, jlong ptr) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_dumpStats(): ptr=%d", ptr);

    SRT_TRACEBSTATS stats;
    int result = srt_bstats((int) ptr, &stats, 0);
    if (result == SRT_ERROR) {
        return;
    }
    LOGD("dumpStats: pktSentTotal=%ld, pktRetransTotal=%d, pktSndLossTotal=%d", stats.pktSentTotal, stats.pktRetransTotal, stats.pktSndLossTotal);
    LOGD("dumpStats: mbpsBandwidth=%f, mbpsMaxBW=%f, byteAvailSndBuf=%d", stats.mbpsBandwidth, stats.mbpsMaxBW, stats.byteAvailSndBuf);
}

#ifdef __cplusplus
}
#endif
<commit_msg>SRTO_MAXBW の値を 0 に設定し、SRTO_INPUTBW と SRTO_OHEADBW の値でBandwidth の値を設定するように修正<commit_after>#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <srt/srt.h>

#define DEBUG

#ifdef DEBUG
#include <android/log.h>
#define LOG_TAG "SRT-JNI"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#else
#define LOGI(...)
#define LOGD(...)
#define LOGE(...)
#define LOGW(...)
#endif

/**
* JNI のパッケージ名、クラス名を定義.
*/
#define JNI_METHOD_NAME(name) Java_org_deviceconnect_android_libsrt_NdkHelper_##name

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL
JNI_METHOD_NAME(startup)(JNIEnv *env, jclass clazz) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_startup()");
    srt_startup();
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(cleanup)(JNIEnv *env, jclass clazz) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_cleanup()");
    srt_cleanup();
}

JNIEXPORT jlong JNICALL
JNI_METHOD_NAME(createSrtSocket)(JNIEnv *env, jclass clazz, jstring address, jint port, jint backlog) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_createSrtSocket()");

    int result;
    int server_socket = srt_create_socket();
    if (server_socket == SRT_INVALID_SOCK) {
        LOGE("srt_socket: %s", srt_getlasterror_str());
        return -1;
    }

    const char *addressString = env->GetStringUTFChars(address, nullptr);
    struct sockaddr_in sa;
    sa.sin_family = AF_INET;
    sa.sin_port = htons(port);
    if (inet_pton(AF_INET, addressString, &sa.sin_addr) != 1) {
        LOGE("inet_pton error.");
        env->ReleaseStringUTFChars(address, addressString);
        srt_close(server_socket);
        return -1;
    }
    env->ReleaseStringUTFChars(address, addressString);

    int64_t maxBW = 0;
    srt_setsockflag(server_socket, SRTO_MAXBW, &maxBW, sizeof maxBW);

    result = srt_bind(server_socket, (struct sockaddr *) &sa, sizeof sa);
    if (result == SRT_ERROR) {
        LOGE("srt_bind: %s", srt_getlasterror_str());
        srt_close(server_socket);
        return -1;
    }

    result = srt_listen(server_socket, backlog);
    if (result == SRT_ERROR) {
        LOGE("srt_listen: %s\n", srt_getlasterror_str());
        srt_close(server_socket);
        return -1;
    }

    return server_socket;
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(closeSrtSocket)(JNIEnv *env, jclass clazz, jlong ptr) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_closeSrtSocket()");

    int result = srt_close((int) ptr);
    if (result == SRT_ERROR) {
        LOGE("srt_close: %s\n", srt_getlasterror_str());
    }
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(accept)(JNIEnv *env, jclass clazz, jlong ptr, jobject socket) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_accept()");

    struct sockaddr addr;
    int addrlen;
    int accepted_socket = srt_accept((int) ptr, &addr, &addrlen);
    if (accepted_socket == SRT_INVALID_SOCK) {
        LOGE("srt_accept: %s\n", srt_getlasterror_str());
        return;
    }

    int64_t inputBW = 2 * 1024 * 1024;
    int ohdadBW = 50;
    srt_setsockflag(accepted_socket, SRTO_INPUTBW, &inputBW, sizeof inputBW);
    srt_setsockflag(accepted_socket, SRTO_OHEADBW, &ohdadBW, sizeof ohdadBW);

    // クライアント側のソケットへのポインタ
    jclass socketCls = env->FindClass("org/deviceconnect/android/libsrt/SRTSocket");
    jfieldID socketPtr = env->GetFieldID(socketCls, "mNativePtr", "J");
    env->SetLongField(socket, socketPtr, accepted_socket);

    // クライアントのIPアドレス
    char buf[15];
    sprintf(buf, "%d.%d.%d.%d", addr.sa_data[2], addr.sa_data[3], addr.sa_data[4], addr.sa_data[5]);
    jstring address = env->NewStringUTF(buf);
    jfieldID addressField = env->GetFieldID(socketCls, "mSocketAddress", "Ljava/lang/String;");
    env->SetObjectField(socket, addressField, address);
}

JNIEXPORT jint JNICALL
JNI_METHOD_NAME(sendMessage)(JNIEnv *env, jclass clazz, jlong ptr, jbyteArray byteArray, jint offset, jint length) {
    jboolean isCopy;
    jbyte* data = env->GetByteArrayElements(byteArray, &isCopy);
    if (data == nullptr) {
        return -1;
    }

    SRT_MSGCTRL mc = srt_msgctrl_default;
    int result = srt_sendmsg2((int) ptr, (const char *) &data[offset], length, &mc);
    if (result <= SRT_ERROR) {
        LOGE("srt_send: %s\n", srt_getlasterror_str());
    }
    env->ReleaseByteArrayElements(byteArray, data, 0);
    return result;
}

JNIEXPORT jint JNICALL
JNI_METHOD_NAME(recvMessage)(JNIEnv *env, jclass clazz, jlong ptr, jbyteArray byteArray, jint length) {
    jboolean isCopy;
    jbyte* data = env->GetByteArrayElements(byteArray, &isCopy);
    if (data == nullptr) {
        return -1;
    }

    int result = srt_recvmsg((int) ptr, (char *) data, length);
    if (result <= SRT_ERROR) {
        LOGE("srt_send: %s\n", srt_getlasterror_str());
    }
    env->ReleaseByteArrayElements(byteArray, data, 0);
    return result;
}

JNIEXPORT void JNICALL
JNI_METHOD_NAME(dumpStats)(JNIEnv *env, jclass clazz, jlong ptr) {
    LOGI("Java_org_deviceconnect_android_libsrt_NdkHelper_dumpStats(): ptr=%d", ptr);

    SRT_TRACEBSTATS stats;
    int result = srt_bstats((int) ptr, &stats, 0);
    if (result == SRT_ERROR) {
        return;
    }
    LOGD("dumpStats: pktSentTotal=%ld, pktSndLossTotal=%d, pktSndDropTotal=%d, pktRetransTotal=%d", stats.pktSentTotal, stats.pktSndLossTotal, stats.pktSndDropTotal, stats.pktRetransTotal);
    LOGD("dumpStats: mbpsBandwidth=%f, mbpsMaxBW=%f, byteAvailSndBuf=%d", stats.mbpsBandwidth, stats.mbpsMaxBW, stats.byteAvailSndBuf);
}

#ifdef __cplusplus
}
#endif
<|endoftext|>


<commit_before>/* vi:set ts=8 sts=8 sw=8 noet:
 *
 * Practical Music Search
 * Copyright (c) 2006-2011  Kim Tore Jensen
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "window.h"
#include "curses.h"
#include "config.h"

extern Windowmanager * wm;
extern Curses * curses;
extern Config * config;

void Window::draw()
{
	unsigned int i, h;

	if (!rect || !visible())
		return;

	need_draw = false;

	h = height();

	for (i = 0; i <= h; i++)
		drawline(i);
}

inline void Window::qdraw()
{
	need_draw = true;
}

void Window::clear()
{
	curses->wipe(rect, config->colors.standard);
}

unsigned int Window::height()
{
	if (!rect) return 0;
	return rect->bottom - rect->top;
}

Wmain::Wmain()
{
	position = 0;
	cursor = 0;
}

unsigned int Wmain::height()
{
	if (!rect) return 0;
	return rect->bottom - rect->top - (config->show_window_title ? 1 : 0);
}

void Wmain::draw()
{
	if (!rect || !visible())
		return;

	if (config->show_window_title)
	{
		curses->clearline(rect, 0, config->colors.windowtitle);
		curses->print(rect, config->colors.windowtitle, 0, 0, title.c_str());
	}

	Window::draw();
	wm->readout->draw();
}

void Wmain::scroll_window(int offset)
{
	int limit = static_cast<int>(content_size() - height() - 1);

	if (limit < 0)
		limit = 0;

	offset = position + offset;

	if (offset < 0)
	{
		offset = 0;
		curses->bell();
	}
	if (offset > limit)
	{
		offset = limit;
		curses->bell();
	}

	if ((int)position == offset)
		return;

	position = offset;

	if (config->scroll_mode == SCROLL_MODE_NORMAL)
	{
		if (cursor < position)
			cursor = position;
		else if (cursor > position + height())
			cursor = position + height();
	}
	else if (config->scroll_mode == SCROLL_MODE_CENTERED)
	{
		cursor = position + (height() / 2);
	}

	qdraw();
}

void Wmain::set_position(unsigned int absolute)
{
	scroll_window(absolute - position);
}

void Wmain::move_cursor(int offset)
{
	offset = cursor + offset;

	if (offset < 0)
	{
		offset = 0;
		curses->bell();
	}
	else if (offset > (int)content_size() - 1)
	{
		offset = content_size() - 1;
		curses->bell();
	}

	if ((int)cursor == offset)
		return;

	cursor = offset;

	if (config->scroll_mode == SCROLL_MODE_NORMAL)
	{
		if (cursor < position)
			set_position(cursor);
		else if (cursor > position + height())
			set_position(cursor - height());
	}
	else if (config->scroll_mode == SCROLL_MODE_CENTERED)
	{
		offset = height() / 2;
		if ((int)cursor < offset)
			position = 0;
		else if (cursor + offset >= content_size())
		{
			if (content_size() > height())
				position = content_size() - height() - 1;
			else
				position = 0;
		}
		else
			position = cursor - offset;
	}

	qdraw();
}

void Wmain::set_cursor(unsigned int absolute)
{
	move_cursor(absolute - cursor);
}

bool Wmain::visible()
{
	return wm->active == this;
}
<commit_msg>Fix centered scroll mode scroll bug.<commit_after>/* vi:set ts=8 sts=8 sw=8 noet:
 *
 * Practical Music Search
 * Copyright (c) 2006-2011  Kim Tore Jensen
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <math.h>
#include "window.h"
#include "curses.h"
#include "config.h"

extern Windowmanager * wm;
extern Curses * curses;
extern Config * config;

void Window::draw()
{
	unsigned int i, h;

	if (!rect || !visible())
		return;

	need_draw = false;

	h = height();

	for (i = 0; i <= h; i++)
		drawline(i);
}

inline void Window::qdraw()
{
	need_draw = true;
}

void Window::clear()
{
	curses->wipe(rect, config->colors.standard);
}

unsigned int Window::height()
{
	if (!rect) return 0;
	return rect->bottom - rect->top;
}

Wmain::Wmain()
{
	position = 0;
	cursor = 0;
}

unsigned int Wmain::height()
{
	if (!rect) return 0;
	return rect->bottom - rect->top - (config->show_window_title ? 1 : 0);
}

void Wmain::draw()
{
	if (!rect || !visible())
		return;

	if (config->show_window_title)
	{
		curses->clearline(rect, 0, config->colors.windowtitle);
		curses->print(rect, config->colors.windowtitle, 0, 0, title.c_str());
	}

	Window::draw();
	wm->readout->draw();
}

void Wmain::scroll_window(int offset)
{
	int limit = static_cast<int>(content_size() - height() - 1);

	if (limit < 0)
		limit = 0;

	offset = position + offset;

	if (offset < 0)
	{
		offset = 0;
		curses->bell();
	}
	if (offset > limit)
	{
		offset = limit;
		curses->bell();
	}

	if ((int)position == offset)
		return;

	position = offset;

	if (config->scroll_mode == SCROLL_MODE_NORMAL)
	{
		if (cursor < position)
			cursor = position;
		else if (cursor > position + height())
			cursor = position + height();
	}
	else if (config->scroll_mode == SCROLL_MODE_CENTERED)
	{
		cursor = position + (height() / 2);
	}

	qdraw();
}

void Wmain::set_position(unsigned int absolute)
{
	scroll_window(absolute - position);
}

void Wmain::move_cursor(int offset)
{
	offset = cursor + offset;

	if (offset < 0)
	{
		offset = 0;
		curses->bell();
	}
	else if (offset > (int)content_size() - 1)
	{
		offset = content_size() - 1;
		curses->bell();
	}

	if ((int)cursor == offset)
		return;

	cursor = offset;

	if (config->scroll_mode == SCROLL_MODE_NORMAL)
	{
		if (cursor < position)
			set_position(cursor);
		else if (cursor > position + height())
			set_position(cursor - height());
	}
	else if (config->scroll_mode == SCROLL_MODE_CENTERED)
	{
		offset = floorl(height() / 2);
		if ((int)cursor < offset) {
			position = 0;
		} else if (cursor + offset + 1 >= content_size()) {
			if (content_size() > height())
				position = content_size() - height() - 1;
			else
				position = 0;
		} else {
			position = cursor - offset;
		}
	}

	qdraw();
}

void Wmain::set_cursor(unsigned int absolute)
{
	move_cursor(absolute - cursor);
}

bool Wmain::visible()
{
	return wm->active == this;
}
<|endoftext|>


<commit_before>#include "Updater.h"

#pragma comment(lib, "Version.lib")
#pragma comment(lib, "wininet.lib")
#include <Windows.h>
#include <WinInet.h>
#include <sstream>

#include "Settings.h"
#include "StringUtils.h"
#include "Logger.h"

const std::wstring Updater::LATEST_URL
    = L"https://3rvx.com/releases/latest_version";

const std::wstring Updater::DOWNLOAD_URL
    = L"https://3rvx.com/releases/";

bool Updater::NewerVersionAvailable() {
    std::pair<int, int> remote = RemoteVersion();
    std::pair<int, int> local = MainAppVersion();
    CLOG(L"Remote version: %d.%d\n Local version: %d.%d",
        remote.first, remote.second,
        local.first, local.second);

    if (remote.first == 0 && remote.second == 0
        || local.first == 0 && local.second == 0) {
        /* One of the version checks failed, so say that there is no new
         * version. No need to bother the user with (hopefully) temporary
         * errors. */
        return false;
    }

    if (remote.first > local.first || remote.second > local.second) {
        return true;
    }

    return false;
}

std::pair<int, int> Updater::MainAppVersion() {
    std::wstring mainExe = Settings::Instance()->MainApp();
    BOOL result;
    std::pair<int, int> version = std::pair<int, int>(0, 0);

    DWORD size = GetFileVersionInfoSize(mainExe.c_str(), NULL);
    if (size == 0) {
        CLOG(L"Could not determine version info size");
        return version;
    }

    unsigned char *block = new unsigned char[size];
    result = GetFileVersionInfo(mainExe.c_str(), NULL, size, block);
    if (result == 0) {
        CLOG(L"Failed to retrieve file version info");
        delete[] block;
        return version;
    }

    unsigned int dataSz;
    VS_FIXEDFILEINFO *vers;
    result = VerQueryValue(block, L"\\", (void **) &vers, &dataSz);
    if (result == 0) {
        CLOG(L"Could not query root block for version info");
        delete[] block;
        return version;
    }

    if (vers->dwSignature != 0xFEEF04BD) {
        CLOG(L"Invalid version signature");
        delete[] block;
        return version;
    }

    unsigned long verl = vers->dwProductVersionMS;
    int hi = (verl >> 16) & 0xFF;
    int lo = verl & 0xFF;
    version = std::pair<int, int>(hi, lo);

    delete[] block;
    return version;
}

std::wstring Updater::MainAppVersionString() {
    std::pair<int, int> vers = MainAppVersion();
    return std::to_wstring(vers.first) + L"." + std::to_wstring(vers.second);
}

std::pair<int, int> Updater::RemoteVersion() {
    HINTERNET internet = InternetOpen(
        L"3RVX Updater",
        INTERNET_OPEN_TYPE_PRECONFIG,
        NULL,
        NULL,
        NULL);

    HINTERNET connection = InternetOpenUrl(
        internet,
        LATEST_URL.c_str(),
        NULL,
        0,
        INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE,
        0);

    if (connection == NULL) {
        CLOG(L"Could not connect to URL!");
        return std::pair<int, int>(0, 0);
    }

    std::string str("");
    char buf[32];
    DWORD read;
    while (InternetReadFile(connection, buf, 16, &read) == TRUE && read != 0) {
        str.append(buf);
    }

    /* Only consider the first line */
    str.erase(str.find('\n'), str.size() - 1);

    int dot = str.find('.');
    std::string major = str.substr(0, dot);
    std::string minor = str.substr(dot + 1, str.size());

    std::pair<int, int> version;
    std::istringstream ss;

    ss = std::istringstream(major);
    ss >> version.first;
    ss = std::istringstream(minor);
    ss >> version.second;

    return version;
}<commit_msg>Redefine the latest version URL<commit_after>#include "Updater.h"

#pragma comment(lib, "Version.lib")
#pragma comment(lib, "wininet.lib")
#include <Windows.h>
#include <WinInet.h>
#include <sstream>

#include "Settings.h"
#include "StringUtils.h"
#include "Logger.h"

const std::wstring Updater::LATEST_URL
    = DOWNLOAD_URL + L"latest_version";

const std::wstring Updater::DOWNLOAD_URL
    = L"https://3rvx.com/releases/";

bool Updater::NewerVersionAvailable() {
    std::pair<int, int> remote = RemoteVersion();
    std::pair<int, int> local = MainAppVersion();
    CLOG(L"Remote version: %d.%d\n Local version: %d.%d",
        remote.first, remote.second,
        local.first, local.second);

    if (remote.first == 0 && remote.second == 0
        || local.first == 0 && local.second == 0) {
        /* One of the version checks failed, so say that there is no new
         * version. No need to bother the user with (hopefully) temporary
         * errors. */
        return false;
    }

    if (remote.first > local.first || remote.second > local.second) {
        return true;
    }

    return false;
}

std::pair<int, int> Updater::MainAppVersion() {
    std::wstring mainExe = Settings::Instance()->MainApp();
    BOOL result;
    std::pair<int, int> version = std::pair<int, int>(0, 0);

    DWORD size = GetFileVersionInfoSize(mainExe.c_str(), NULL);
    if (size == 0) {
        CLOG(L"Could not determine version info size");
        return version;
    }

    unsigned char *block = new unsigned char[size];
    result = GetFileVersionInfo(mainExe.c_str(), NULL, size, block);
    if (result == 0) {
        CLOG(L"Failed to retrieve file version info");
        delete[] block;
        return version;
    }

    unsigned int dataSz;
    VS_FIXEDFILEINFO *vers;
    result = VerQueryValue(block, L"\\", (void **) &vers, &dataSz);
    if (result == 0) {
        CLOG(L"Could not query root block for version info");
        delete[] block;
        return version;
    }

    if (vers->dwSignature != 0xFEEF04BD) {
        CLOG(L"Invalid version signature");
        delete[] block;
        return version;
    }

    unsigned long verl = vers->dwProductVersionMS;
    int hi = (verl >> 16) & 0xFF;
    int lo = verl & 0xFF;
    version = std::pair<int, int>(hi, lo);

    delete[] block;
    return version;
}

std::wstring Updater::MainAppVersionString() {
    std::pair<int, int> vers = MainAppVersion();
    return std::to_wstring(vers.first) + L"." + std::to_wstring(vers.second);
}

std::pair<int, int> Updater::RemoteVersion() {
    HINTERNET internet = InternetOpen(
        L"3RVX Updater",
        INTERNET_OPEN_TYPE_PRECONFIG,
        NULL,
        NULL,
        NULL);

    HINTERNET connection = InternetOpenUrl(
        internet,
        LATEST_URL.c_str(),
        NULL,
        0,
        INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE,
        0);

    if (connection == NULL) {
        CLOG(L"Could not connect to URL!");
        return std::pair<int, int>(0, 0);
    }

    std::string str("");
    char buf[32];
    DWORD read;
    while (InternetReadFile(connection, buf, 16, &read) == TRUE && read != 0) {
        str.append(buf);
    }

    /* Only consider the first line */
    str.erase(str.find('\n'), str.size() - 1);

    int dot = str.find('.');
    std::string major = str.substr(0, dot);
    std::string minor = str.substr(dot + 1, str.size());

    std::pair<int, int> version;
    std::istringstream ss;

    ss = std::istringstream(major);
    ss >> version.first;
    ss = std::istringstream(minor);
    ss >> version.second;

    return version;
}<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/tab_contents/chrome_tab_contents_view_wrapper_gtk.h"

#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/tab_contents/render_view_context_menu_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_view_gtk.h"
#include "chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h"
#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/interstitial_page.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "ui/base/gtk/gtk_floating_container.h"

ChromeTabContentsViewWrapperGtk::ChromeTabContentsViewWrapperGtk()
    : floating_(gtk_floating_container_new()),
      view_(NULL),
      constrained_window_(NULL) {
  gtk_widget_set_name(floating_.get(), "chrome-tab-contents-wrapper-view");
  g_signal_connect(floating_.get(), "set-floating-position",
                   G_CALLBACK(OnSetFloatingPositionThunk), this);
}

ChromeTabContentsViewWrapperGtk::~ChromeTabContentsViewWrapperGtk() {
  floating_.Destroy();
}

void ChromeTabContentsViewWrapperGtk::AttachConstrainedWindow(
    ConstrainedWindowGtk* constrained_window) {
  DCHECK(constrained_window_ == NULL);

  constrained_window_ = constrained_window;
  gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
                                      constrained_window->widget());
}

void ChromeTabContentsViewWrapperGtk::RemoveConstrainedWindow(
    ConstrainedWindowGtk* constrained_window) {
  DCHECK(constrained_window == constrained_window_);

  constrained_window_ = NULL;
  gtk_container_remove(GTK_CONTAINER(floating_.get()),
                       constrained_window->widget());
}

void ChromeTabContentsViewWrapperGtk::WrapView(TabContentsViewGtk* view) {
  view_ = view;

  gtk_container_add(GTK_CONTAINER(floating_.get()),
                    view_->expanded_container());
  gtk_widget_show(floating_.get());
}

gfx::NativeView ChromeTabContentsViewWrapperGtk::GetNativeView() const {
  return floating_.get();
}

void ChromeTabContentsViewWrapperGtk::OnCreateViewForWidget() {
  // We install a chrome specific handler to intercept bookmark drags for the
  // bookmark manager/extension API.
  bookmark_handler_gtk_.reset(new WebDragBookmarkHandlerGtk);
  view_->SetDragDestDelegate(bookmark_handler_gtk_.get());
}

void ChromeTabContentsViewWrapperGtk::Focus() {
  if (!constrained_window_) {
    GtkWidget* widget = view_->GetContentNativeView();
    if (widget)
      gtk_widget_grab_focus(widget);
  }
}

gboolean ChromeTabContentsViewWrapperGtk::OnNativeViewFocusEvent(
    GtkWidget* widget,
    GtkDirectionType type,
    gboolean* return_value) {
  // If we are showing a constrained window, don't allow the native view to take
  // focus.
  if (constrained_window_) {
    // If we return false, it will revert to the default handler, which will
    // take focus. We don't want that. But if we return true, the event will
    // stop being propagated, leaving focus wherever it is currently. That is
    // also bad. So we return false to let the default handler run, but take
    // focus first so as to trick it into thinking the view was already focused
    // and allowing the event to propagate.
    gtk_widget_grab_focus(widget);
    *return_value = FALSE;
    return TRUE;
  }

  // Let the default TabContentsViewGtk::OnFocus() behaviour run.
  return FALSE;
}

void ChromeTabContentsViewWrapperGtk::ShowContextMenu(
    const ContextMenuParams& params) {
  // Find out the RenderWidgetHostView that corresponds to the render widget on
  // which this context menu is showed, so that we can retrieve the last mouse
  // down event on the render widget and use it as the timestamp of the
  // activation event to show the context menu.
  RenderWidgetHostView* view = NULL;
  if (params.custom_context.render_widget_id !=
      webkit_glue::CustomContextMenuContext::kCurrentRenderWidget) {
    IPC::Channel::Listener* listener =
        view_->tab_contents()->render_view_host()->process()->GetListenerByID(
            params.custom_context.render_widget_id);
    if (!listener) {
      NOTREACHED();
      return;
    }
    view = static_cast<RenderWidgetHost*>(listener)->view();
  } else {
    view = view_->tab_contents()->GetRenderWidgetHostView();
  }
  if (!view)
    return;

  context_menu_.reset(new RenderViewContextMenuGtk(
      view_->tab_contents(), params, GDK_CURRENT_TIME));
  context_menu_->Init();

  gfx::Rect bounds;
  view_->GetContainerBounds(&bounds);
  gfx::Point point = bounds.origin();
  point.Offset(params.x, params.y);
  context_menu_->Popup(point);
}

void ChromeTabContentsViewWrapperGtk::OnSetFloatingPosition(
    GtkWidget* floating_container, GtkAllocation* allocation) {
  if (!constrained_window_)
    return;

  // Place each ConstrainedWindow in the center of the view.
  GtkWidget* widget = constrained_window_->widget();
  DCHECK(widget->parent == floating_.get());

  GtkRequisition requisition;
  gtk_widget_size_request(widget, &requisition);

  GValue value = { 0, };
  g_value_init(&value, G_TYPE_INT);

  int child_x = std::max((allocation->width - requisition.width) / 2, 0);
  g_value_set_int(&value, child_x);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget, "x", &value);

  int child_y = std::max((allocation->height - requisition.height) / 2, 0);
  g_value_set_int(&value, child_y);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget, "y", &value);
  g_value_unset(&value);
}
<commit_msg>GTK: Speculative revert of r109465 to fix right clicking.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/tab_contents/chrome_tab_contents_view_wrapper_gtk.h"

#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/tab_contents/render_view_context_menu_gtk.h"
#include "chrome/browser/tab_contents/tab_contents_view_gtk.h"
#include "chrome/browser/tab_contents/web_drag_bookmark_handler_gtk.h"
#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/renderer_host/render_widget_host_view_gtk.h"
#include "content/browser/tab_contents/interstitial_page.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "ui/base/gtk/gtk_floating_container.h"

ChromeTabContentsViewWrapperGtk::ChromeTabContentsViewWrapperGtk()
    : floating_(gtk_floating_container_new()),
      view_(NULL),
      constrained_window_(NULL) {
  gtk_widget_set_name(floating_.get(), "chrome-tab-contents-wrapper-view");
  g_signal_connect(floating_.get(), "set-floating-position",
                   G_CALLBACK(OnSetFloatingPositionThunk), this);
}

ChromeTabContentsViewWrapperGtk::~ChromeTabContentsViewWrapperGtk() {
  floating_.Destroy();
}

void ChromeTabContentsViewWrapperGtk::AttachConstrainedWindow(
    ConstrainedWindowGtk* constrained_window) {
  DCHECK(constrained_window_ == NULL);

  constrained_window_ = constrained_window;
  gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
                                      constrained_window->widget());
}

void ChromeTabContentsViewWrapperGtk::RemoveConstrainedWindow(
    ConstrainedWindowGtk* constrained_window) {
  DCHECK(constrained_window == constrained_window_);

  constrained_window_ = NULL;
  gtk_container_remove(GTK_CONTAINER(floating_.get()),
                       constrained_window->widget());
}

void ChromeTabContentsViewWrapperGtk::WrapView(TabContentsViewGtk* view) {
  view_ = view;

  gtk_container_add(GTK_CONTAINER(floating_.get()),
                    view_->expanded_container());
  gtk_widget_show(floating_.get());
}

gfx::NativeView ChromeTabContentsViewWrapperGtk::GetNativeView() const {
  return floating_.get();
}

void ChromeTabContentsViewWrapperGtk::OnCreateViewForWidget() {
  // We install a chrome specific handler to intercept bookmark drags for the
  // bookmark manager/extension API.
  bookmark_handler_gtk_.reset(new WebDragBookmarkHandlerGtk);
  view_->SetDragDestDelegate(bookmark_handler_gtk_.get());
}

void ChromeTabContentsViewWrapperGtk::Focus() {
  if (!constrained_window_) {
    GtkWidget* widget = view_->GetContentNativeView();
    if (widget)
      gtk_widget_grab_focus(widget);
  }
}

gboolean ChromeTabContentsViewWrapperGtk::OnNativeViewFocusEvent(
    GtkWidget* widget,
    GtkDirectionType type,
    gboolean* return_value) {
  // If we are showing a constrained window, don't allow the native view to take
  // focus.
  if (constrained_window_) {
    // If we return false, it will revert to the default handler, which will
    // take focus. We don't want that. But if we return true, the event will
    // stop being propagated, leaving focus wherever it is currently. That is
    // also bad. So we return false to let the default handler run, but take
    // focus first so as to trick it into thinking the view was already focused
    // and allowing the event to propagate.
    gtk_widget_grab_focus(widget);
    *return_value = FALSE;
    return TRUE;
  }

  // Let the default TabContentsViewGtk::OnFocus() behaviour run.
  return FALSE;
}

void ChromeTabContentsViewWrapperGtk::ShowContextMenu(
    const ContextMenuParams& params) {
  // Find out the RenderWidgetHostView that corresponds to the render widget on
  // which this context menu is showed, so that we can retrieve the last mouse
  // down event on the render widget and use it as the timestamp of the
  // activation event to show the context menu.
  RenderWidgetHostView* view = NULL;
  if (params.custom_context.render_widget_id !=
      webkit_glue::CustomContextMenuContext::kCurrentRenderWidget) {
    IPC::Channel::Listener* listener =
        view_->tab_contents()->render_view_host()->process()->GetListenerByID(
            params.custom_context.render_widget_id);
    if (!listener) {
      NOTREACHED();
      return;
    }
    view = static_cast<RenderWidgetHost*>(listener)->view();
  } else {
    view = view_->tab_contents()->GetRenderWidgetHostView();
  }
  RenderWidgetHostViewGtk* view_gtk =
      static_cast<RenderWidgetHostViewGtk*>(view);
  if (!view_gtk)
    return;

  context_menu_.reset(new RenderViewContextMenuGtk(
      view_->tab_contents(), params, view_gtk->last_mouse_down() ?
      view_gtk->last_mouse_down()->time : GDK_CURRENT_TIME));
  context_menu_->Init();

  gfx::Rect bounds;
  view_->GetContainerBounds(&bounds);
  gfx::Point point = bounds.origin();
  point.Offset(params.x, params.y);
  context_menu_->Popup(point);
}

void ChromeTabContentsViewWrapperGtk::OnSetFloatingPosition(
    GtkWidget* floating_container, GtkAllocation* allocation) {
  if (!constrained_window_)
    return;

  // Place each ConstrainedWindow in the center of the view.
  GtkWidget* widget = constrained_window_->widget();
  DCHECK(widget->parent == floating_.get());

  GtkRequisition requisition;
  gtk_widget_size_request(widget, &requisition);

  GValue value = { 0, };
  g_value_init(&value, G_TYPE_INT);

  int child_x = std::max((allocation->width - requisition.width) / 2, 0);
  g_value_set_int(&value, child_x);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget, "x", &value);

  int child_y = std::max((allocation->height - requisition.height) / 2, 0);
  g_value_set_int(&value, child_y);
  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
                                   widget, "y", &value);
  g_value_unset(&value);
}
<|endoftext|>