<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "service/migration_listener.hh"
#include "db/legacy_schema_tables.hh"
#include "gms/endpoint_state.hh"
#include "core/distributed.hh"
#include "gms/inet_address.hh"
#include "utils/UUID.hh"

#include <vector>

namespace service {

class migration_manager {
#if 0
    private final Logger logger = LoggerFactory.getLogger(MigrationManager.class);

    private final RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
#endif

    std::vector<migration_listener*> _listeners;

    static const std::chrono::milliseconds MIGRATION_DELAY_IN_MS;
public:
    migration_manager();

    /// Register a migration listener on current shard.
    void register_listener(migration_listener* listener);

    /// Unregister a migration listener on current shard.
    void unregister_listener(migration_listener* listener);

    future<> schedule_schema_pull(const gms::inet_address& endpoint, const gms::endpoint_state& state);

    future<> maybe_schedule_schema_pull(service::storage_proxy& proxy, const utils::UUID& their_version, const gms::inet_address& endpoint);

    future<> submit_migration_task(service::storage_proxy& proxy, const gms::inet_address& endpoint);

    static future<> notify_create_keyspace(const lw_shared_ptr<keyspace_metadata>& ksm);

    static future<> notify_create_column_family(schema_ptr cfm);

    static future<> notify_update_keyspace(const lw_shared_ptr<keyspace_metadata>& ksm);

    static future<> notify_update_column_family(schema_ptr cfm);

    static future<> notify_drop_keyspace(const lw_shared_ptr<keyspace_metadata>& ksm);

    static future<> notify_drop_column_family(schema_ptr cfm);

    bool should_pull_schema_from(const gms::inet_address& endpoint);

    future<> announce_new_keyspace(distributed<service::storage_proxy>& proxy, lw_shared_ptr<keyspace_metadata> ksm, bool announce_locally = false);

    future<> announce_new_keyspace(distributed<service::storage_proxy>& proxy, lw_shared_ptr<keyspace_metadata> ksm, api::timestamp_type timestamp, bool announce_locally);

    future<> announce_column_family_update(distributed<service::storage_proxy>& proxy, schema_ptr cfm, bool from_thrift, bool announce_locally = false);

    future<> announce_new_column_family(distributed<service::storage_proxy>& proxy, schema_ptr cfm, bool announce_locally = false);

    future<> announce_keyspace_drop(distributed<service::storage_proxy>& proxy, const sstring& ks_name, bool announce_locally = false);

    future<> announce_column_family_drop(distributed<service::storage_proxy>& proxy, const sstring& ks_name, const sstring& cf_name, bool announce_locally = false);

    /**
     * actively announce a new version to active hosts via rpc
     * @param schema The schema mutation to be applied
     */
    static future<> announce(distributed<service::storage_proxy>& proxy, mutation schema, bool announce_locally);

    static future<> announce(distributed<service::storage_proxy>& proxy, std::vector<mutation> mutations, bool announce_locally);

    static future<> push_schema_mutation(const gms::inet_address& endpoint, const std::vector<mutation>& schema);

    // Returns a future on the local application of the schema
    static future<> announce(distributed<service::storage_proxy>& proxy, std::vector<mutation> schema);

    static future<> passive_announce(utils::UUID version);

    future<> stop();
};

extern distributed<migration_manager> _the_migration_manager;

inline distributed<migration_manager>& get_migration_manager() {
    return _the_migration_manager;
}

inline migration_manager& get_local_migration_manager() {
    return _the_migration_manager.local();
}

}
<commit_msg>service/migration_manager: Remove ifdef'd code<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */

/*
 * Copyright 2015 Cloudius Systems
 *
 * Modified by Cloudius Systems
 */

#pragma once

#include "service/migration_listener.hh"
#include "db/legacy_schema_tables.hh"
#include "gms/endpoint_state.hh"
#include "core/distributed.hh"
#include "gms/inet_address.hh"
#include "utils/UUID.hh"

#include <vector>

namespace service {

class migration_manager {
    std::vector<migration_listener*> _listeners;

    static const std::chrono::milliseconds MIGRATION_DELAY_IN_MS;
public:
    migration_manager();

    /// Register a migration listener on current shard.
    void register_listener(migration_listener* listener);

    /// Unregister a migration listener on current shard.
    void unregister_listener(migration_listener* listener);

    future<> schedule_schema_pull(const gms::inet_address& endpoint, const gms::endpoint_state& state);

    future<> maybe_schedule_schema_pull(service::storage_proxy& proxy, const utils::UUID& their_version, const gms::inet_address& endpoint);

    future<> submit_migration_task(service::storage_proxy& proxy, const gms::inet_address& endpoint);

    static future<> notify_create_keyspace(const lw_shared_ptr<keyspace_metadata>& ksm);

    static future<> notify_create_column_family(schema_ptr cfm);

    static future<> notify_update_keyspace(const lw_shared_ptr<keyspace_metadata>& ksm);

    static future<> notify_update_column_family(schema_ptr cfm);

    static future<> notify_drop_keyspace(const lw_shared_ptr<keyspace_metadata>& ksm);

    static future<> notify_drop_column_family(schema_ptr cfm);

    bool should_pull_schema_from(const gms::inet_address& endpoint);

    future<> announce_new_keyspace(distributed<service::storage_proxy>& proxy, lw_shared_ptr<keyspace_metadata> ksm, bool announce_locally = false);

    future<> announce_new_keyspace(distributed<service::storage_proxy>& proxy, lw_shared_ptr<keyspace_metadata> ksm, api::timestamp_type timestamp, bool announce_locally);

    future<> announce_column_family_update(distributed<service::storage_proxy>& proxy, schema_ptr cfm, bool from_thrift, bool announce_locally = false);

    future<> announce_new_column_family(distributed<service::storage_proxy>& proxy, schema_ptr cfm, bool announce_locally = false);

    future<> announce_keyspace_drop(distributed<service::storage_proxy>& proxy, const sstring& ks_name, bool announce_locally = false);

    future<> announce_column_family_drop(distributed<service::storage_proxy>& proxy, const sstring& ks_name, const sstring& cf_name, bool announce_locally = false);

    /**
     * actively announce a new version to active hosts via rpc
     * @param schema The schema mutation to be applied
     */
    static future<> announce(distributed<service::storage_proxy>& proxy, mutation schema, bool announce_locally);

    static future<> announce(distributed<service::storage_proxy>& proxy, std::vector<mutation> mutations, bool announce_locally);

    static future<> push_schema_mutation(const gms::inet_address& endpoint, const std::vector<mutation>& schema);

    // Returns a future on the local application of the schema
    static future<> announce(distributed<service::storage_proxy>& proxy, std::vector<mutation> schema);

    static future<> passive_announce(utils::UUID version);

    future<> stop();
};

extern distributed<migration_manager> _the_migration_manager;

inline distributed<migration_manager>& get_migration_manager() {
    return _the_migration_manager;
}

inline migration_manager& get_local_migration_manager() {
    return _the_migration_manager.local();
}

}
<|endoftext|>


<commit_before>/*
    mFSM
 */

#include "FSM.hpp"

#include <new>
#include <string>
#include <functional>
#include <algorithm>
#include <type_traits>

#include <iostream>

namespace mFSM
{

State::State(const std::string& name, bool final) :
    name_(name), final_(final)
{}

bool State::accept() const
{
    return final_;
}

const std::string& State::name() const
{
    return name_;
}

void State::setFinal(bool final)
{
    final_ = final;
}

// ------------------------------------------

Rule::Rule(const std::string& rule) :
    rule_(rule)
{
    if (rule.length() == 1) {
        setsize_ = 1;
    } else if (rule[0] == '~') {
        setsize_ = 255;
    } else if (rule.compare("any") == 0) {
        setsize_ = 256;
    } else {
        setsize_ = 0;
    }
}

bool Rule::satisfiedBy(int c) const
{
    if (exactMatch()) {
        return rule_[0] == c;
    } else if (matchAll()) {
        return true;
    } else if (rule_[0] == '~') {
        return c != rule_[1];
    }
    // here we should raise an exception; but no exception
    // are used in this code... that's it. Rather, I would
    // set an internal state to "machine is out of service"!
    return false;
}

bool Rule::exactMatch() const
{
    return rule_.length() == 1;
}

bool Rule::matchMany() const
{
    return rule_.length() > 1 &&
        (rule_.compare("any") == 0 || rule_[0] == '~');
}

bool Rule::matchAll() const
{
    return rule_.length() > 1 && rule_.compare("any") == 0;
}

size_t Rule::size() const
{
    return setsize_;
}

// ------------------------------------------

AwareState::AwareState(const std::string& name, bool final) :
    State(name, final)
{}

AwareState& AwareState::onRule(const Rule* rule, const AwareState* dest)
{
    Connection con{rule, dest->name()};
    connections_.push_front(con);
    connections_.sort([](const Connection& a, const Connection& b)->bool {
            return a.rule->size() < b.rule->size();
        });
    return *this;
}

bool AwareState::overConnectionsDo(
    std::function<bool(const Rule*,
                       const std::string& stateName)> action) const
{
    return std::any_of(connections_.begin(),
                       connections_.end(),
                       [&](decltype(connections_.front()) c) {
                           return action(c.rule, c.destState);
                       });
    // the previous piece should work like the following
    /*
    for (auto& c : connections_) {
        if (action(c.rule, c.destState)) {
            return true;
        }
    }
    return false;
    */
}

// ------------------------------------------

FSM::FSM(bool debug) : current_(nullptr),
                       first_(nullptr),
                       strict_(false),
                       debug_(debug)
{}

FSM::~FSM()
{
    for (auto& p : rules_) {
        delete p.second;
    }
    for (auto& p : states_) {
        delete p.second;
    }
}

bool FSM::accepted() const
{
    if (debug_ && current_) {
        std::cerr << "state: " << current_->name() << "\n";
    }
    return current_ ? current_->accept() : false;
}

void FSM::rewind()
{
    current_ = first_;
}

void FSM::first(const std::string& s)
{
    if (states_.count(s) > 0) {
        first_ = states_[s];
    }
}

void FSM::strict(bool b)
{
    strict_ = b;
}

AwareState& FSM::state(const std::string& n, bool final)
{
    if (states_.count(n) > 0) {
        // the name's already taken;
        // return whatever it was created, ignore final arg.
        return *states_[n];
    }
    AwareState* new_state = new AwareState(n, final); // no nothrow...
    states_[n] = new_state;
    if (!first_) {
        first_ = new_state;
    }
    return *new_state;
}

AwareState& FSM::get(const std::string& n)
{
    if (states_.count(n) > 0) {
        return *states_[n];
    }
    return state(n, false);
}

bool FSM::connect(const std::string& s1,
                  const std::string& s2,
                  const std::string& rule)
{
    AwareState* state1 = nullptr;
    AwareState* state2 = nullptr;
    Rule* orule = nullptr;

    if (states_.count(s1) > 0) {
        state1 = states_[s1];
    } else {
        state1 = &state(s1, false);
        if (!state1) {
            return false;
        }
        states_[s1] = state1;
    }

    if (states_.count(s2) > 0) {
        state2 = states_[s2];
    } else {
        state2 = &state(s2, false);
        if (!state2) {
            return false;
        }
        states_[s2] = state2;
    }

    if (rules_.count(rule) > 0) {
        orule = rules_[rule];
    } else {
        orule = new (std::nothrow) Rule(rule);
        if (!orule) {
            return false;
        }
        rules_[rule] = orule;
    }

    state1->onRule(orule, state2);
    return true;
}

bool FSM::feed(int c)
{
    if (!first_) {
        return false;
    }
    if (!current_) {
        current_ = first_;
    }

    const AwareState* next_current = current_;
    bool matched = current_->overConnectionsDo(
        [c,&next_current,this](const Rule* r, const std::string& s)->bool {
            if (r->satisfiedBy(c)) {
                if (this->states_.count(s) > 0) {
                    next_current = states_[s];
                }
                return true;
            }
            return false;
        });

    if (debug_) {
        std::cerr << current_->name() << "(" << c << ")"
                  << next_current->name() << "\n";
    }

    current_ = next_current;

    return matched;
}

bool FSM::run(const std::string& s)
{
    bool matched;
    rewind();
    for (auto& c : s) {
        matched = feed(c);
        if (strict_ && !matched) {
            break;
        }
    }
    return current_->accept() && (!strict_ || matched);
}

} // ns: mFSM
<commit_msg>let's make a line a little bit shorter<commit_after>/*
    mFSM
 */

#include "FSM.hpp"

#include <new>
#include <string>
#include <functional>
#include <algorithm>
#include <type_traits>

#include <iostream>

namespace mFSM
{

State::State(const std::string& name, bool final) :
    name_(name), final_(final)
{}

bool State::accept() const
{
    return final_;
}

const std::string& State::name() const
{
    return name_;
}

void State::setFinal(bool final)
{
    final_ = final;
}

// ------------------------------------------

Rule::Rule(const std::string& rule) :
    rule_(rule)
{
    if (rule.length() == 1) {
        setsize_ = 1;
    } else if (rule[0] == '~') {
        setsize_ = 255;
    } else if (rule.compare("any") == 0) {
        setsize_ = 256;
    } else {
        setsize_ = 0;
    }
}

bool Rule::satisfiedBy(int c) const
{
    if (exactMatch()) {
        return rule_[0] == c;
    } else if (matchAll()) {
        return true;
    } else if (rule_[0] == '~') {
        return c != rule_[1];
    }
    // here we should raise an exception; but no exception
    // are used in this code... that's it. Rather, I would
    // set an internal state to "machine is out of service"!
    return false;
}

bool Rule::exactMatch() const
{
    return rule_.length() == 1;
}

bool Rule::matchMany() const
{
    return rule_.length() > 1 &&
        (rule_.compare("any") == 0 || rule_[0] == '~');
}

bool Rule::matchAll() const
{
    return rule_.length() > 1 && rule_.compare("any") == 0;
}

size_t Rule::size() const
{
    return setsize_;
}

// ------------------------------------------

AwareState::AwareState(const std::string& name, bool final) :
    State(name, final)
{}

AwareState& AwareState::onRule(const Rule* rule, const AwareState* dest)
{
    Connection con{rule, dest->name()};
    connections_.push_front(con);
    connections_.sort([](const Connection& a, const Connection& b)->bool {
            return a.rule->size() < b.rule->size();
        });
    return *this;
}

bool AwareState::overConnectionsDo(
    std::function<bool(const Rule*,
                       const std::string&)> action) const
{
    return std::any_of(connections_.begin(),
                       connections_.end(),
                       [&](decltype(connections_.front()) c) {
                           return action(c.rule, c.destState);
                       });
    // the previous piece should work like the following
    /*
    for (auto& c : connections_) {
        if (action(c.rule, c.destState)) {
            return true;
        }
    }
    return false;
    */
}

// ------------------------------------------

FSM::FSM(bool debug) : current_(nullptr),
                       first_(nullptr),
                       strict_(false),
                       debug_(debug)
{}

FSM::~FSM()
{
    for (auto& p : rules_) {
        delete p.second;
    }
    for (auto& p : states_) {
        delete p.second;
    }
}

bool FSM::accepted() const
{
    if (debug_ && current_) {
        std::cerr << "state: " << current_->name() << "\n";
    }
    return current_ ? current_->accept() : false;
}

void FSM::rewind()
{
    current_ = first_;
}

void FSM::first(const std::string& s)
{
    if (states_.count(s) > 0) {
        first_ = states_[s];
    }
}

void FSM::strict(bool b)
{
    strict_ = b;
}

AwareState& FSM::state(const std::string& n, bool final)
{
    if (states_.count(n) > 0) {
        // the name's already taken;
        // return whatever it was created, ignore final arg.
        return *states_[n];
    }
    AwareState* new_state = new AwareState(n, final); // no nothrow...
    states_[n] = new_state;
    if (!first_) {
        first_ = new_state;
    }
    return *new_state;
}

AwareState& FSM::get(const std::string& n)
{
    if (states_.count(n) > 0) {
        return *states_[n];
    }
    return state(n, false);
}

bool FSM::connect(const std::string& s1,
                  const std::string& s2,
                  const std::string& rule)
{
    AwareState* state1 = nullptr;
    AwareState* state2 = nullptr;
    Rule* orule = nullptr;

    if (states_.count(s1) > 0) {
        state1 = states_[s1];
    } else {
        state1 = &state(s1, false);
        if (!state1) {
            return false;
        }
        states_[s1] = state1;
    }

    if (states_.count(s2) > 0) {
        state2 = states_[s2];
    } else {
        state2 = &state(s2, false);
        if (!state2) {
            return false;
        }
        states_[s2] = state2;
    }

    if (rules_.count(rule) > 0) {
        orule = rules_[rule];
    } else {
        orule = new (std::nothrow) Rule(rule);
        if (!orule) {
            return false;
        }
        rules_[rule] = orule;
    }

    state1->onRule(orule, state2);
    return true;
}

bool FSM::feed(int c)
{
    if (!first_) {
        return false;
    }
    if (!current_) {
        current_ = first_;
    }

    const AwareState* next_current = current_;
    bool matched = current_->overConnectionsDo(
        [c,&next_current,this](const Rule* r, const std::string& s)->bool {
            if (r->satisfiedBy(c)) {
                if (this->states_.count(s) > 0) {
                    next_current = states_[s];
                }
                return true;
            }
            return false;
        });

    if (debug_) {
        std::cerr << current_->name() << "(" << c << ")"
                  << next_current->name() << "\n";
    }

    current_ = next_current;

    return matched;
}

bool FSM::run(const std::string& s)
{
    bool matched;
    rewind();
    for (auto& c : s) {
        matched = feed(c);
        if (strict_ && !matched) {
            break;
        }
    }
    return current_->accept() && (!strict_ || matched);
}

} // ns: mFSM
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (C) 2003 by Hans Karlsson <karlsson.h@home.se>              *
 *   Copyright (C) 2007 Matt Broadstone <mbroadst@gmail.com>               *
 *                                                                         *
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "textlabel.h"
#include "textlabel.moc"

#include <QPainter>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
#include <QCursor>

#include <KRun>

TextLabel::TextLabel(Karamba *k, int x, int y, int w, int h)
        :   Meter(k, x, y, w, h),
        alignment(Qt::AlignLeft),
        clip(0),
        bgColor(0, 0, 0),
        lineHeight(0),
        shadow(0),
        scrollSpeed(0, 0),
        scrollPos(0, 0),
        scrollGap(0),
        scrollPause(0),
        pauseCounter(0),
        scrollType(ScrollNone),
        m_clickable(false)
{
    origPoint = QPoint(x, y);

    calculateTextSize();
    if (h != 0 || w != 0)
        clip = 0;
    else
        clip = Qt::TextDontClip;

    if (h == 0 || w == 0) {
        setWidth(-1);
        setHeight(-1);
    }
}

TextLabel::TextLabel(Karamba *k)
        :   Meter(k, 0, 0, 0, 0),
        alignment(Qt::AlignLeft),
        clip(0),
        bgColor(0, 0, 0),
        lineHeight(0),
        shadow(0),
        scrollSpeed(0, 0),
        scrollPos(0, 0),
        scrollGap(0),
        scrollPause(0),
        pauseCounter(0),
        scrollType(ScrollNone),
        m_clickable(false)
{}

TextLabel::~TextLabel()
{}

void TextLabel::show()
{
    Meter::show();
    setEnabled(true);
}

void TextLabel::hide()
{
    Meter::hide();
    setEnabled(false);
}

void TextLabel::setTextProps(TextField *field)
{
    if (field) {
        text = *field;
        //lineHeight = t->getLineHeight();
        shadow = field->getShadow();
        alignment = field->getAlignment();
        setFontSize(field->getFontSize());
        setFont(field->getFont());

        setColor(field->getColor());
        setBGColor(field->getBGColor());
    }

    calculateTextSize();
}

void TextLabel::calculateTextSize()
{
    int tmp;

    prepareGeometryChange();

    QFontMetrics fm(font);
    lineHeight = fm.height();
    textSize.setWidth(0);
    textSize.setHeight(lineHeight * value.count());
    QStringList::Iterator it = value.begin();

    while (it != value.end()) {
        tmp = fm.width(*it);
        if (tmp > textSize.width())
            textSize.setWidth(tmp);

        ++it;
    }

    if (getWidth() <= 0) {
        Meter::setWidth(textSize.width());
    }

    if (getHeight() <= 0) {
       Meter::setHeight(textSize.height());
    }

    if (alignment == Qt::AlignLeft)
        Meter::setX(origPoint.x());
    else if (alignment == Qt::AlignRight)
        Meter::setX(origPoint.x() - textSize.width());
    else if (alignment == Qt::AlignCenter)
        Meter::setX(origPoint.x() - textSize.width() / 2);
}

void TextLabel::setValue(const QString &text)
{
    value = text.split('\n');

    calculateTextSize();
    update();
}

void TextLabel::setValue(int v)
{
    value = QStringList(QString::number(v));

    calculateTextSize();
    update();
}

void TextLabel::setBGColor(QColor clr)
{
    bgColor = clr;
}

QColor TextLabel::getBGColor() const
{
    return bgColor;
}

void TextLabel::setFont(const QString &f)
{
    font.setFamily(f);
    calculateTextSize();
}

QString TextLabel::getFont() const
{
    return font.family();
}

void TextLabel::setFontSize(int size)
{
    font.setPixelSize(size);
    calculateTextSize();
}

int TextLabel::getFontSize() const
{
    return font.pixelSize();
}

void TextLabel::setAlignment(const QString &align)
{
    QString a = align.toUpper();
    if (a == "LEFT" || a.isEmpty())
        alignment = Qt::AlignLeft;
    if (a == "RIGHT")
        alignment = Qt::AlignRight;
    if (a == "CENTER")
        alignment = Qt::AlignHCenter;

    calculateTextSize();
}

QString TextLabel::getAlignment() const
{
    if (alignment == Qt::AlignHCenter)
        return "CENTER";
    else if (alignment == Qt::AlignRight)
        return "RIGHT";
    else
        return "LEFT";
}

void TextLabel::setFixedPitch(bool fp)
{
    font.setFixedPitch(fp);
}

bool TextLabel::getFixedPitch() const
{
    return font.fixedPitch();
}

void TextLabel::setShadow(int s)
{
    shadow = s;
}

int TextLabel::getShadow() const
{
    return shadow;
}

void TextLabel::setScroll(const QString &a, const QPoint &speed, int gap, int pause)
{
    ScrollType t = TextLabel::ScrollNone;
    QString scroll = a.toUpper();

    if (scroll == "NONE")
        scroll = TextLabel::ScrollNone;
    else if (a == "NORMAL")
        scroll = TextLabel::ScrollNormal;
    else if (a == "BACKANDFORTH")
        scroll = TextLabel::ScrollBackAndForth;
    else if (a == "ONEPASS")
        scroll = TextLabel::ScrollOnePass;

    setScroll(t, speed, gap, pause);
}

void TextLabel::setScroll(ScrollType type, QPoint speed, int gap, int pause)
{
    scrollType = type;
    scrollSpeed = speed;

    switch (scrollType) {
    case ScrollNormal:
    case ScrollOnePass: {
        int x = 0, y = 0;

        if (speed.x() > 0)
            x = -1 * textSize.width();
        else if (speed.x() < 0)
            x = getWidth() - 1;

        if (speed.y() > 0)
            x = -1 * textSize.height();
        else if (speed.y() < 0)
            x = getHeight() - 1;

        scrollPos = QPoint(x, y);
        break;
    }

    case ScrollNone:
    case ScrollBackAndForth:
    default:
        scrollPos = QPoint(0, 0);
        break;
    }

    scrollGap = gap;
    scrollPause = pause;
    pauseCounter = 1;
}

int TextLabel::drawText(QPainter *p, int x, int y, int width, int height,
                        const QString &text)
{
    if (shadow != 0) {
        p->setPen(getBGColor());
        p->drawText(x + shadow, y + shadow, width, height,
                    alignment | clip | Qt::TextExpandTabs, text);
    }

    p->setPen(getColor());
    p->drawText(x, y, width, height, alignment | clip |
                Qt::TextExpandTabs, text);

    return 0;
}

bool TextLabel::calculateScrollCoords(const QRect &meterRect, QRect &textRect,
                                      QPoint &next, int x, int y)
{
    if (scrollType == ScrollBackAndForth &&
            (scrollSpeed.x() != 0 && textSize.width() < getWidth() ||
             scrollSpeed.y() != 0 && textSize.height() < getHeight()))
        return true;

    x += scrollPos.x();
    y += scrollPos.y();

    if (pauseCounter < 1) {
        scrollPos += scrollSpeed;

        // -1 | 0 | 1
        QPoint direction(scrollSpeed.x() / abs((scrollSpeed.x() == 0) ?
                                               1 : scrollSpeed.x()),
                         scrollSpeed.y() / abs((scrollSpeed.y() == 0) ?
                                               1 : scrollSpeed.y()));
        next = QPoint(-1 * direction.x() * (scrollGap + textSize.width()),
                      -1 * direction.y() * (scrollGap + textSize.height()));
        textRect.setCoords(x, y, x + textSize.width(), y + textSize.height());

        if (scrollType == ScrollBackAndForth) {
            if (direction.x() < 0 && textRect.right() <= meterRect.right() ||
                    direction.x() > 0 && textRect.left() >= meterRect.left()) {
                scrollSpeed.setX(scrollSpeed.x() * -1);
                pauseCounter = scrollPause;
            }
            if (direction.y() < 0 && textRect.bottom() <= meterRect.bottom() ||
                    direction.y() > 0 && textRect.top() >= meterRect.top()) {
                scrollSpeed.setY(scrollSpeed.y() * -1);
                pauseCounter = scrollPause;
            }
        } else if (!textRect.intersects(meterRect)) {
            if (scrollType == ScrollNormal)
                scrollPos += next;
            else if (scrollType == ScrollOnePass)
                return false;
        }
    } else
        --pauseCounter;

    return true;
}

void TextLabel::paint(QPainter *p, const QStyleOptionGraphicsItem *option,
                      QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    if (!m_hidden) {
        int i = 0; // lineHeight;
        int row = 1;
        int width = getWidth();
        int height = getHeight();
        QRect meterRect(0, 0, width, height);
        QRect textRect;
        QPoint next;

        p->setFont(font);
        if (scrollType != ScrollNone) {
            p->setClipRect(0, 0, width, height);
            if (!calculateScrollCoords(meterRect, textRect, next, 0, 0)) {
                p->setClipping(false);
                return;
            }
            width = textSize.width();
            height = textSize.height();
        }

        QStringList::Iterator it = value.begin();
        while (it != value.end() && (row <= height || height == -1)) {
            drawText(p, 0, 0 + i, width, height, *it);

            // Draw more instances of text if scroll type is normal scroll
            if (scrollType == ScrollNormal) {
                textRect.adjust(next.x(), next.y(), next.x(), next.y());
                while (textRect.intersects(meterRect)) {
                    drawText(p, textRect.x(), textRect.y() + i, width, height, *it);
                    textRect.adjust(next.x(), next.y(), next.x(), next.y());
                }
            }

            i += lineHeight;
            it++;
            row++;
        }

        if (scrollType != ScrollNone)
            p->setClipping(false);
    }
}

bool TextLabel::mouseEvent(QEvent* e)
{
    if (isEnabled()) {
        Qt::MouseButtons button;
        if (QGraphicsSceneMouseEvent *event = dynamic_cast<QGraphicsSceneMouseEvent*>(e)) {
            button = event->button();
        } else if (QGraphicsSceneWheelEvent *event = dynamic_cast<QGraphicsSceneWheelEvent*>(e)) {
            button = event->buttons();
        }

        QString program;
        if (button == Qt::LeftButton)
            program = m_leftMouseButtonAction;
        else if (button == Qt::MidButton)
            program = m_middleMouseButtonAction;
        else if (button == Qt::RightButton)
            program = m_rightMouseButtonAction;

        if (!program.isEmpty())
            KRun::runCommand(program);
        else
            return true;
    }

    return false;
}

void TextLabel::allowClick(bool enable)
{
    m_clickable = enable;
}

bool TextLabel::clickable()
{
    return m_clickable;
}

void TextLabel::attachClickArea(const QString &leftMouseButton,
                                const QString &middleMouseButton,
                                const QString &rightMouseButton)
{
    m_leftMouseButtonAction = leftMouseButton;
    m_middleMouseButtonAction = middleMouseButton;
    m_rightMouseButtonAction = rightMouseButton;

    QGraphicsItem::setCursor(QCursor(Qt::PointingHandCursor));
}

QRectF TextLabel::boundingRect() const
{
    return Meter::boundingRect();
}

int TextLabel::getTextWidth() const
{
    QFontMetrics fm(font);
    return fm.width(value[0]);
}
<commit_msg>Fix centered text<commit_after>/***************************************************************************
 *   Copyright (C) 2003 by Hans Karlsson <karlsson.h@home.se>              *
 *   Copyright (C) 2007 Matt Broadstone <mbroadst@gmail.com>               *
 *                                                                         *
 *                                                                         *
 *   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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#include "textlabel.h"
#include "textlabel.moc"

#include <QPainter>
#include <QMouseEvent>
#include <QGraphicsSceneMouseEvent>
#include <QCursor>

#include <KRun>

TextLabel::TextLabel(Karamba *k, int x, int y, int w, int h)
        :   Meter(k, x, y, w, h),
        alignment(Qt::AlignLeft),
        clip(0),
        bgColor(0, 0, 0),
        lineHeight(0),
        shadow(0),
        scrollSpeed(0, 0),
        scrollPos(0, 0),
        scrollGap(0),
        scrollPause(0),
        pauseCounter(0),
        scrollType(ScrollNone),
        m_clickable(false)
{
    origPoint = QPoint(x, y);

    calculateTextSize();
    if (h != 0 || w != 0)
        clip = 0;
    else
        clip = Qt::TextDontClip;

    if (h == 0 || w == 0) {
        setWidth(-1);
        setHeight(-1);
    }
}

TextLabel::TextLabel(Karamba *k)
        :   Meter(k, 0, 0, 0, 0),
        alignment(Qt::AlignLeft),
        clip(0),
        bgColor(0, 0, 0),
        lineHeight(0),
        shadow(0),
        scrollSpeed(0, 0),
        scrollPos(0, 0),
        scrollGap(0),
        scrollPause(0),
        pauseCounter(0),
        scrollType(ScrollNone),
        m_clickable(false)
{}

TextLabel::~TextLabel()
{}

void TextLabel::show()
{
    Meter::show();
    setEnabled(true);
}

void TextLabel::hide()
{
    Meter::hide();
    setEnabled(false);
}

void TextLabel::setTextProps(TextField *field)
{
    if (field) {
        text = *field;
        //lineHeight = t->getLineHeight();
        shadow = field->getShadow();
        alignment = field->getAlignment();
        setFontSize(field->getFontSize());
        setFont(field->getFont());

        setColor(field->getColor());
        setBGColor(field->getBGColor());
    }

    calculateTextSize();
}

void TextLabel::calculateTextSize()
{
    int tmp;

    prepareGeometryChange();

    QFontMetrics fm(font);
    lineHeight = fm.height();
    textSize.setWidth(0);
    textSize.setHeight(lineHeight * value.count());
    QStringList::Iterator it = value.begin();

    while (it != value.end()) {
        tmp = fm.width(*it);
        if (tmp > textSize.width())
            textSize.setWidth(tmp);

        ++it;
    }

    if (getWidth() <= 0) {
        Meter::setWidth(textSize.width());
    }

    if (getHeight() <= 0) {
       Meter::setHeight(textSize.height());
    }

    if (alignment == Qt::AlignLeft) {
        Meter::setX(origPoint.x());
    }
    else if (alignment == Qt::AlignRight) {
        Meter::setX(origPoint.x() - textSize.width());
    }
    else if (alignment == Qt::AlignHCenter) {
        Meter::setX(origPoint.x() - textSize.width() / 2);
    }
}

void TextLabel::setValue(const QString &text)
{
    value = text.split('\n');

    calculateTextSize();
    update();
}

void TextLabel::setValue(int v)
{
    value = QStringList(QString::number(v));

    calculateTextSize();
    update();
}

void TextLabel::setBGColor(QColor clr)
{
    bgColor = clr;
}

QColor TextLabel::getBGColor() const
{
    return bgColor;
}

void TextLabel::setFont(const QString &f)
{
    font.setFamily(f);
    calculateTextSize();
}

QString TextLabel::getFont() const
{
    return font.family();
}

void TextLabel::setFontSize(int size)
{
    font.setPixelSize(size);
    calculateTextSize();
}

int TextLabel::getFontSize() const
{
    return font.pixelSize();
}

void TextLabel::setAlignment(const QString &align)
{
    QString a = align.toUpper();
    if (a == "LEFT" || a.isEmpty())
        alignment = Qt::AlignLeft;
    if (a == "RIGHT")
        alignment = Qt::AlignRight;
    if (a == "CENTER")
        alignment = Qt::AlignHCenter;

    calculateTextSize();
}

QString TextLabel::getAlignment() const
{
    if (alignment == Qt::AlignHCenter)
        return "CENTER";
    else if (alignment == Qt::AlignRight)
        return "RIGHT";
    else
        return "LEFT";
}

void TextLabel::setFixedPitch(bool fp)
{
    font.setFixedPitch(fp);
}

bool TextLabel::getFixedPitch() const
{
    return font.fixedPitch();
}

void TextLabel::setShadow(int s)
{
    shadow = s;
}

int TextLabel::getShadow() const
{
    return shadow;
}

void TextLabel::setScroll(const QString &a, const QPoint &speed, int gap, int pause)
{
    ScrollType t = TextLabel::ScrollNone;
    QString scroll = a.toUpper();

    if (scroll == "NONE")
        scroll = TextLabel::ScrollNone;
    else if (a == "NORMAL")
        scroll = TextLabel::ScrollNormal;
    else if (a == "BACKANDFORTH")
        scroll = TextLabel::ScrollBackAndForth;
    else if (a == "ONEPASS")
        scroll = TextLabel::ScrollOnePass;

    setScroll(t, speed, gap, pause);
}

void TextLabel::setScroll(ScrollType type, QPoint speed, int gap, int pause)
{
    scrollType = type;
    scrollSpeed = speed;

    switch (scrollType) {
    case ScrollNormal:
    case ScrollOnePass: {
        int x = 0, y = 0;

        if (speed.x() > 0)
            x = -1 * textSize.width();
        else if (speed.x() < 0)
            x = getWidth() - 1;

        if (speed.y() > 0)
            x = -1 * textSize.height();
        else if (speed.y() < 0)
            x = getHeight() - 1;

        scrollPos = QPoint(x, y);
        break;
    }

    case ScrollNone:
    case ScrollBackAndForth:
    default:
        scrollPos = QPoint(0, 0);
        break;
    }

    scrollGap = gap;
    scrollPause = pause;
    pauseCounter = 1;
}

int TextLabel::drawText(QPainter *p, int x, int y, int width, int height,
                        const QString &text)
{
    if (shadow != 0) {
        p->setPen(getBGColor());
        p->drawText(x + shadow, y + shadow, width, height,
                    alignment | clip | Qt::TextExpandTabs, text);
    }

    p->setPen(getColor());
    p->drawText(x, y, width, height, alignment | clip |
                Qt::TextExpandTabs, text);

    return 0;
}

bool TextLabel::calculateScrollCoords(const QRect &meterRect, QRect &textRect,
                                      QPoint &next, int x, int y)
{
    if (scrollType == ScrollBackAndForth &&
            (scrollSpeed.x() != 0 && textSize.width() < getWidth() ||
             scrollSpeed.y() != 0 && textSize.height() < getHeight()))
        return true;

    x += scrollPos.x();
    y += scrollPos.y();

    if (pauseCounter < 1) {
        scrollPos += scrollSpeed;

        // -1 | 0 | 1
        QPoint direction(scrollSpeed.x() / abs((scrollSpeed.x() == 0) ?
                                               1 : scrollSpeed.x()),
                         scrollSpeed.y() / abs((scrollSpeed.y() == 0) ?
                                               1 : scrollSpeed.y()));
        next = QPoint(-1 * direction.x() * (scrollGap + textSize.width()),
                      -1 * direction.y() * (scrollGap + textSize.height()));
        textRect.setCoords(x, y, x + textSize.width(), y + textSize.height());

        if (scrollType == ScrollBackAndForth) {
            if (direction.x() < 0 && textRect.right() <= meterRect.right() ||
                    direction.x() > 0 && textRect.left() >= meterRect.left()) {
                scrollSpeed.setX(scrollSpeed.x() * -1);
                pauseCounter = scrollPause;
            }
            if (direction.y() < 0 && textRect.bottom() <= meterRect.bottom() ||
                    direction.y() > 0 && textRect.top() >= meterRect.top()) {
                scrollSpeed.setY(scrollSpeed.y() * -1);
                pauseCounter = scrollPause;
            }
        } else if (!textRect.intersects(meterRect)) {
            if (scrollType == ScrollNormal)
                scrollPos += next;
            else if (scrollType == ScrollOnePass)
                return false;
        }
    } else
        --pauseCounter;

    return true;
}

void TextLabel::paint(QPainter *p, const QStyleOptionGraphicsItem *option,
                      QWidget *widget)
{
    Q_UNUSED(option);
    Q_UNUSED(widget);

    if (!m_hidden) {
        int i = 0; // lineHeight;
        int row = 1;
        int width = getWidth();
        int height = getHeight();
        QRect meterRect(0, 0, width, height);
        QRect textRect;
        QPoint next;

        p->setFont(font);
        if (scrollType != ScrollNone) {
            p->setClipRect(0, 0, width, height);
            if (!calculateScrollCoords(meterRect, textRect, next, 0, 0)) {
                p->setClipping(false);
                return;
            }
            width = textSize.width();
            height = textSize.height();
        }

        QStringList::Iterator it = value.begin();
        while (it != value.end() && (row <= height || height == -1)) {
            drawText(p, 0, 0 + i, width, height, *it);

            // Draw more instances of text if scroll type is normal scroll
            if (scrollType == ScrollNormal) {
                textRect.adjust(next.x(), next.y(), next.x(), next.y());
                while (textRect.intersects(meterRect)) {
                    drawText(p, textRect.x(), textRect.y() + i, width, height, *it);
                    textRect.adjust(next.x(), next.y(), next.x(), next.y());
                }
            }

            i += lineHeight;
            it++;
            row++;
        }

        if (scrollType != ScrollNone)
            p->setClipping(false);
    }
}

bool TextLabel::mouseEvent(QEvent* e)
{
    if (isEnabled()) {
        Qt::MouseButtons button;
        if (QGraphicsSceneMouseEvent *event = dynamic_cast<QGraphicsSceneMouseEvent*>(e)) {
            button = event->button();
        } else if (QGraphicsSceneWheelEvent *event = dynamic_cast<QGraphicsSceneWheelEvent*>(e)) {
            button = event->buttons();
        }

        QString program;
        if (button == Qt::LeftButton)
            program = m_leftMouseButtonAction;
        else if (button == Qt::MidButton)
            program = m_middleMouseButtonAction;
        else if (button == Qt::RightButton)
            program = m_rightMouseButtonAction;

        if (!program.isEmpty())
            KRun::runCommand(program);
        else
            return true;
    }

    return false;
}

void TextLabel::allowClick(bool enable)
{
    m_clickable = enable;
}

bool TextLabel::clickable()
{
    return m_clickable;
}

void TextLabel::attachClickArea(const QString &leftMouseButton,
                                const QString &middleMouseButton,
                                const QString &rightMouseButton)
{
    m_leftMouseButtonAction = leftMouseButton;
    m_middleMouseButtonAction = middleMouseButton;
    m_rightMouseButtonAction = rightMouseButton;

    QGraphicsItem::setCursor(QCursor(Qt::PointingHandCursor));
}

QRectF TextLabel::boundingRect() const
{
    return Meter::boundingRect();
}

int TextLabel::getTextWidth() const
{
    QFontMetrics fm(font);
    return fm.width(value[0]);
}
<|endoftext|>


<commit_before>#include <exodus/library.h>
libraryinit()

#include <sysmsg.h>

var id;

function main(in mode, io tx, in arg3, io arg4, in arg5) {
	//c sys in,io,in,io,in

	if (mode == "INITMENUS") {

		tx = "<!DOCTYPE html>";
		tx ^= FM ^ "";
		tx ^= FM ^ "";
		tx ^= FM ^ "";
		tx ^= FM ^ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
		tx ^= FM ^ "";
		tx ^= FM ^ "";
		tx ^= FM ^ "
";

	} else if (mode == "ADDMENU") {

		#define menu arg3
		if (arg4.unassigned()) {
			id = "";
		}else{
			id = arg4;
		}

		//_Support
		//

		//use menu title as menu id
		if (not id) {
			id = var(menu).ucase();
			id.converter("_", "");
		}

		//convert _x to x to indicate keyboard shortcut
		var tt = var(menu).index("_");
		if (tt) {
			var(menu).splicer(tt, 2, "" ^ var(menu)[tt + 1] ^ "");
		}

		tx ^= FM ^ "" ^ menu ^ "";
		tx ^= FM ^ "
";

		id = "";

	} else if (mode == "SUBMENU") {

		//_Reports
		//

		var submenu = arg3;

		//convert _x to x to indicate keyboard shortcut
		var tt = submenu.index("_");
		if (tt) {
			submenu.splicer(tt, 2, "" ^ submenu[tt + 1] ^ "");
		}

		tx ^= FM ^ "" ^ submenu ^ "";
		//submenus are same class as menus
		tx ^= FM ^ "
";

	} else if (mode == "ADDITEM") {

		var item = arg3;
		#define href arg4
		//equate onclick to arg5

		//Month Plan File

		var props = "";
		//if unassigned(id) else props:=' id=':quote(id)
		//if unassigned(onclick) else props:=' onclick = ':quote(onclick)
		if (not(arg5.unassigned())) {
			props ^= " arg5 = " ^ (arg5.quote());
		}

		//convert _x to x to indicate keyboard shortcut
		var tt = item.index("_");
		if (tt) {
			item.splicer(tt, 2, "" ^ item[tt + 1] ^ "");
		}

		tx ^= FM ^ " " ^ item ^ "
";

	} else if (mode == "ADDSEP") {

		tx ^= FM ^ "
";

	} else if (mode == "ENDSUBMENU") {

		tx ^= FM ^ "
";
		tx ^= FM ^ "
";

	} else if (mode == "ENDMENU") {

		tx ^= FM ^ "
";

	} else if (mode == "EXITMENUS") {

		tx ^= FM ^ "<button tabindex=\"-1\" style=\"background-color: white; height: 1px; width: 1px; border-style: none; margin: 0; padding: 0\" accesskey=\"M\"";
		var onclickx = "javascript:if (typeof menuonmouseover!=\'undefined\') menuonmouseover(\'click\')";
		tx ^= FM ^ " onclick=" ^ (onclickx.quote()) ^ ">";
		tx ^= FM ^ "</button>";
		tx ^= FM ^ "";

	} else {
		call sysmsg(mode.quote() ^ " invalid mode in MENU.SUBS");
	}

	//prevent href being carried forwards to ADDITEM which use onclick instead
	arg4 = "";

	return 0;
}

libraryexit()
<commit_msg>ditto<commit_after>#include <exodus/library.h>
libraryinit()

#include <sysmsg.h>

var id;

function main(in mode, io tx, in arg3, io arg4, in arg5) {
	//c sys in,io,in,io,in

	if (mode == "INITMENUS") {

		tx = "<!DOCTYPE html>";
		tx ^= FM ^ "";
		tx ^= FM ^ "";
		tx ^= FM ^ "";
		tx ^= FM ^ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
		tx ^= FM ^ "";
		tx ^= FM ^ "";
		tx ^= FM ^ "
";

	} else if (mode == "ADDMENU") {

		#define menu arg3
		if (arg4.unassigned()) {
			id = "";
		}else{
			id = arg4;
		}

		//_Support
		//

		//use menu title as menu id
		if (not id) {
			id = var(menu).ucase();
			id.converter("_", "");
		}

		//convert _x to x to indicate keyboard shortcut
		var tt = var(menu).index("_");
		if (tt) {
			var(menu).splicer(tt, 2, "" ^ var(menu)[tt + 1] ^ "");
		}

		tx ^= FM ^ "" ^ menu ^ "";
		tx ^= FM ^ "
";

		id = "";

	} else if (mode == "SUBMENU") {

		//_Reports
		//

		var submenu = arg3;

		//convert _x to x to indicate keyboard shortcut
		var tt = submenu.index("_");
		if (tt) {
			submenu.splicer(tt, 2, "" ^ submenu[tt + 1] ^ "");
		}

		tx ^= FM ^ "" ^ submenu ^ "";
		//submenus are same class as menus
		tx ^= FM ^ "
";

	} else if (mode == "ADDITEM") {

		var item = arg3;
		#define href arg4
		//equate onclick to arg5

		//Month Plan File

		var props = "";
		//if unassigned(id) else props:=' id=':quote(id)
		//if unassigned(onclick) else props:=' onclick = ':quote(onclick)
		if (not(arg5.unassigned())) {
			props ^= " onclick = " ^ (arg5.quote());
		}

		//convert _x to x to indicate keyboard shortcut
		var tt = item.index("_");
		if (tt) {
			item.splicer(tt, 2, "" ^ item[tt + 1] ^ "");
		}

		tx ^= FM ^ " " ^ item ^ "
";

	} else if (mode == "ADDSEP") {

		tx ^= FM ^ "
";

	} else if (mode == "ENDSUBMENU") {

		tx ^= FM ^ "
";
		tx ^= FM ^ "
";

	} else if (mode == "ENDMENU") {

		tx ^= FM ^ "
";

	} else if (mode == "EXITMENUS") {

		tx ^= FM ^ "<button tabindex=\"-1\" style=\"background-color: white; height: 1px; width: 1px; border-style: none; margin: 0; padding: 0\" accesskey=\"M\"";
		var onclickx = "javascript:if (typeof menuonmouseover!=\'undefined\') menuonmouseover(\'click\')";
		tx ^= FM ^ " onclick=" ^ (onclickx.quote()) ^ ">";
		tx ^= FM ^ "</button>";
		tx ^= FM ^ "";

	} else {
		call sysmsg(mode.quote() ^ " invalid mode in MENU.SUBS");
	}

	//prevent href being carried forwards to ADDITEM which use onclick instead
	arg4 = "";

	return 0;
}

libraryexit()
<|endoftext|>


<commit_before>/***********************************************************************
    filename:   CEGuiOgreBaseApplication.cpp
    created:    9/3/2004
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
 *
 *   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 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.
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#   include "config.h"
#endif

#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
# include <unistd.h>
#endif

// this controls conditional compile of file for Apple
#include "CEGUISamplesConfig.h"
#ifdef CEGUI_SAMPLES_USE_OGRE

#include <OgreWindowEventUtilities.h>
#include "CEGuiOgreBaseApplication.h"
#include "SamplesFrameworkBase.h"
#include "CEGUI/RendererModules/Ogre/ImageCodec.h"
#include "CEGUI/RendererModules/Ogre/ResourceProvider.h"

//----------------------------------------------------------------------------//
CEGuiOgreBaseApplication::CEGuiOgreBaseApplication() :
    d_ogreRoot(0),
    d_initialised(false),
    d_frameListener(0),
    d_windowEventListener(0)
{
    using namespace Ogre;

#ifdef DEBUG
    Ogre::String pluginsFileName = "plugins_d.cfg";
#else
    Ogre::String pluginsFileName = "plugins.cfg";
#endif

    d_ogreRoot = new Root(pluginsFileName);

    if (d_ogreRoot->showConfigDialog())
    {
        // initialise system according to user options.
        d_window = d_ogreRoot->initialise(true);

        // Create the scene manager
        SceneManager* sm = d_ogreRoot->
            createSceneManager(ST_GENERIC, "SampleSceneMgr");
        // Create and initialise the camera
        d_camera = sm->createCamera("SampleCam");
        d_camera->setPosition(Vector3(0,0,500));
        d_camera->lookAt(Vector3(0,0,-300));
        d_camera->setNearClipDistance(5);

        // Create a viewport covering whole window
        Viewport* vp = d_window->addViewport(d_camera);
        vp->setBackgroundColour(ColourValue(1.0f, 1.0f, 1.0f, 1.0f));
        // Update the camera aspect ratio to that of the viewport
        d_camera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));

        // create ogre renderer, image codec and resource provider.
        CEGUI::OgreRenderer& renderer = CEGUI::OgreRenderer::create();
        d_renderer = &renderer;
        d_imageCodec = &renderer.createOgreImageCodec();
        d_resourceProvider = &renderer.createOgreResourceProvider();

        // create frame listener
        d_frameListener= new CEGuiDemoFrameListener(this, d_sampleApp, d_window, d_camera);
        d_ogreRoot->addFrameListener(d_frameListener);

        // add a listener for OS framework window events (for resizing)
        d_windowEventListener = new WndEvtListener(d_frameListener->getOISMouse());
        WindowEventUtilities::addWindowEventListener(d_window,
                                                     d_windowEventListener);

        d_ogreRoot->addFrameListener(this);
        renderer.setRenderingEnabled(false);

        d_initialised = true;
    }
    else
    {
        // aborted.  Clean up and set root to 0 so when app attempts to run it
        // knows what happened here.
        delete d_ogreRoot;
        d_ogreRoot = 0;
    }
}

//----------------------------------------------------------------------------//
CEGuiOgreBaseApplication::~CEGuiOgreBaseApplication()
{
    delete d_frameListener;

    CEGUI::OgreRenderer& renderer =
        *static_cast<CEGUI::OgreRenderer*>(d_renderer);
    renderer.destroyOgreResourceProvider(
        *static_cast<CEGUI::OgreResourceProvider*>(d_resourceProvider));
    renderer.destroyOgreImageCodec(
        *static_cast<CEGUI::OgreImageCodec*>(d_imageCodec));
    CEGUI::OgreRenderer::destroy(renderer);

    delete d_ogreRoot;
    delete d_windowEventListener;
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::run()
{
    // if base initialisation failed or app was cancelled by user, bail out now.
    if (!d_ogreRoot || !d_initialised)
        return;

    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    d_sampleApp->initialise();

    // start rendering via Ogre3D engine.
    CEGUI_TRY
    {
        d_ogreRoot->startRendering();
    }
    CEGUI_CATCH(...)
    {}
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::destroyWindow()
{

}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::beginRendering(const float elapsed)
{
    // this is nover called under Ogre, since we're not in control of the
    // rendering process.
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::endRendering()
{
    // this is nover called under Ogre, since we're not in control of the
    // rendering process.
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::initialiseResourceGroupDirectories()
{
    using namespace Ogre;
    ResourceGroupManager& rgm = ResourceGroupManager::getSingleton();

    // add resource groups that we use
    rgm.createResourceGroup("animations");
    rgm.createResourceGroup("imagesets");
    rgm.createResourceGroup("fonts");
    rgm.createResourceGroup("layouts");
    rgm.createResourceGroup("schemes");
    rgm.createResourceGroup("looknfeels");
    rgm.createResourceGroup("lua_scripts");
    rgm.createResourceGroup("schemas");

    // add CEGUI sample framework datafile dirs as resource locations
    ResourceGroupManager::getSingleton().addResourceLocation("./", "FileSystem");

    const char* dataPathPrefix = getDataPathPrefix();
    char resourcePath[PATH_MAX];

    // for each resource type, set a resource group directory
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "schemes/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "schemes");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "imagesets/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "imagesets");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "fonts/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "fonts");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "layouts/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "layouts");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "looknfeel/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "looknfeels");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "lua_scripts/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "lua_scripts");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "animations/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "animations");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "xml_schemas/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "schemas");
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::doFrameUpdate(const float elapsed)
{
    CEGUI::System& gui_system(CEGUI::System::getSingleton());

    gui_system.injectTimePulse(elapsed);
    d_sampleApp->update(static_cast<float>(elapsed));

    updateFPS(elapsed);
    updateLogo(elapsed);
}
//----------------------------------------------------------------------------//
bool CEGuiOgreBaseApplication::frameRenderingQueued(const Ogre::FrameEvent& args)
{
    renderSingleFrame(static_cast<float>(args.timeSinceLastFrame));

    return true;
}

//----------------------------------------------------------------------------//

bool CEGuiOgreBaseApplication::isInitialised()
{
    return d_initialised;
}

//----------------------------------------------------------------------------//

////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
    Start of CEGuiDemoFrameListener mehods
*******************************************************************************/
////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------//
CEGuiDemoFrameListener::CEGuiDemoFrameListener(CEGuiOgreBaseApplication* baseApp, SamplesFrameworkBase*& sampleApp,
    Ogre::RenderWindow* window, Ogre::Camera* camera, bool useBufferedInputKeys, bool useBufferedInputMouse)
    : d_baseApp(baseApp),
    d_sampleApp(sampleApp)
{
    // OIS setup
    OIS::ParamList paramList;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;

    // get window handle
    window->getCustomAttribute("WINDOW", &windowHnd);

    // fill param list
    windowHndStr << (unsigned int)windowHnd;
    paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX && defined (DEBUG)
    paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), "false"));
    paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "false"));
    paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "false"));
#endif

    // create input system
    d_inputManager = OIS::InputManager::createInputSystem(paramList);

    // create buffered keyboard
#ifdef CEGUI_OLD_OIS_API
    if (d_inputManager->numKeyboards() > 0)
#else
    if (d_inputManager->getNumberOfDevices(OIS::OISKeyboard) > 0)
#endif
    {
        d_keyboard = static_cast<OIS::Keyboard*>(d_inputManager->createInputObject(OIS::OISKeyboard, true));
        d_keyboard->setEventCallback(this);
    }

    // create buffered mouse
#ifdef CEGUI_OLD_OIS_API
    if (d_inputManager->numMice() > 0)
#else
    if (d_inputManager->getNumberOfDevices(OIS::OISMouse) > 0)
#endif
    {
        d_mouse = static_cast<OIS::Mouse*>(d_inputManager->createInputObject(OIS::OISMouse, true));
        d_mouse->setEventCallback(this);

        unsigned int width, height, depth;
        int left, top;

        window->getMetrics(width, height, depth, left, top);
        const OIS::MouseState& mouseState = d_mouse->getMouseState();
        mouseState.width = width;
        mouseState.height = height;
    }

    // store inputs we want to make use of
    d_camera = camera;
    d_window = window;
}

//----------------------------------------------------------------------------//
CEGuiDemoFrameListener::~CEGuiDemoFrameListener()
{
    if (d_inputManager)
    {
        d_inputManager->destroyInputObject(d_mouse);
        d_inputManager->destroyInputObject(d_keyboard);
        OIS::InputManager::destroyInputSystem(d_inputManager);
    }
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::frameStarted(const Ogre::FrameEvent& evt)
{
    if(d_window->isClosed() || d_sampleApp->isQuitting())
        return false;

    static_cast<CEGuiOgreBaseApplication*>(d_baseApp)->
        doFrameUpdate(static_cast<float>(evt.timeSinceLastFrame));

    // update input system
    if (d_mouse)
        d_mouse->capture();
    if (d_keyboard)
        d_keyboard->capture();

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::frameEnded(const Ogre::FrameEvent& evt)
{
    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::mouseMoved(const OIS::MouseEvent &e)
{
    d_sampleApp->injectMousePosition(e.state.X.abs, e.state.Y.abs);
    d_sampleApp->injectMouseWheelChange(e.state.Z.rel / 120.0f);

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::keyPressed(const OIS::KeyEvent &e)
{
    d_sampleApp->injectKeyDown(static_cast<CEGUI::Key::Scan>(e.key));
    d_sampleApp->injectChar(e.text);

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::keyReleased(const OIS::KeyEvent &e)
{
    d_sampleApp->injectKeyUp(static_cast<CEGUI::Key::Scan>(e.key));

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
    d_sampleApp->injectMouseButtonDown(convertOISButtonToCegui(id));

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
   d_sampleApp->injectMouseButtonUp(convertOISButtonToCegui(id));

    return true;
}

//----------------------------------------------------------------------------//
CEGUI::MouseButton CEGuiDemoFrameListener::convertOISButtonToCegui(int buttonID)
{
   using namespace OIS;

   switch (buttonID)
    {
   case OIS::MB_Left:
        return CEGUI::LeftButton;
   case OIS::MB_Right:
        return CEGUI::RightButton;
   case OIS::MB_Middle:
        return CEGUI::MiddleButton;
    default:
        return CEGUI::LeftButton;
   }
}

//----------------------------------------------------------------------------//
OIS::Mouse* CEGuiDemoFrameListener::getOISMouse()
{
    return d_mouse;
}

//----------------------------------------------------------------------------//

////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
    Start of WndEvtListener member functions
*******************************************************************************/
////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------//
WndEvtListener::WndEvtListener(OIS::Mouse* mouse) :
    d_mouse(mouse)
{
}

//----------------------------------------------------------------------------//
void WndEvtListener::windowResized(Ogre::RenderWindow* rw)
{
    CEGUI::System* const sys = CEGUI::System::getSingletonPtr();
    if (sys)
        sys->notifyDisplaySizeChanged(
        CEGUI::Sizef(static_cast<float>(rw->getWidth()),
        static_cast<float>(rw->getHeight())));

    const OIS::MouseState& mouseState = d_mouse->getMouseState();
    mouseState.width = rw->getWidth();
    mouseState.height = rw->getHeight();
}

//----------------------------------------------------------------------------//

#endif

<commit_msg>FIX: OgreBaseAPP update fix<commit_after>/***********************************************************************
    filename:   CEGuiOgreBaseApplication.cpp
    created:    9/3/2004
    author:     Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
 *
 *   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 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.
 ***************************************************************************/
#ifdef HAVE_CONFIG_H
#   include "config.h"
#endif

#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__HAIKU__)
# include <unistd.h>
#endif

// this controls conditional compile of file for Apple
#include "CEGUISamplesConfig.h"
#ifdef CEGUI_SAMPLES_USE_OGRE

#include <OgreWindowEventUtilities.h>
#include "CEGuiOgreBaseApplication.h"
#include "SamplesFrameworkBase.h"
#include "CEGUI/RendererModules/Ogre/ImageCodec.h"
#include "CEGUI/RendererModules/Ogre/ResourceProvider.h"

//----------------------------------------------------------------------------//
CEGuiOgreBaseApplication::CEGuiOgreBaseApplication() :
    d_ogreRoot(0),
    d_initialised(false),
    d_frameListener(0),
    d_windowEventListener(0)
{
    using namespace Ogre;

#ifdef DEBUG
    Ogre::String pluginsFileName = "plugins_d.cfg";
#else
    Ogre::String pluginsFileName = "plugins.cfg";
#endif

    d_ogreRoot = new Root(pluginsFileName);

    if (d_ogreRoot->showConfigDialog())
    {
        // initialise system according to user options.
        d_window = d_ogreRoot->initialise(true);

        // Create the scene manager
        SceneManager* sm = d_ogreRoot->
            createSceneManager(ST_GENERIC, "SampleSceneMgr");
        // Create and initialise the camera
        d_camera = sm->createCamera("SampleCam");
        d_camera->setPosition(Vector3(0,0,500));
        d_camera->lookAt(Vector3(0,0,-300));
        d_camera->setNearClipDistance(5);

        // Create a viewport covering whole window
        Viewport* vp = d_window->addViewport(d_camera);
        vp->setBackgroundColour(ColourValue(1.0f, 1.0f, 1.0f, 1.0f));
        // Update the camera aspect ratio to that of the viewport
        d_camera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));

        // create ogre renderer, image codec and resource provider.
        CEGUI::OgreRenderer& renderer = CEGUI::OgreRenderer::create();
        d_renderer = &renderer;
        d_imageCodec = &renderer.createOgreImageCodec();
        d_resourceProvider = &renderer.createOgreResourceProvider();

        // create frame listener
        d_frameListener= new CEGuiDemoFrameListener(this, d_sampleApp, d_window, d_camera);
        d_ogreRoot->addFrameListener(d_frameListener);

        // add a listener for OS framework window events (for resizing)
        d_windowEventListener = new WndEvtListener(d_frameListener->getOISMouse());
        WindowEventUtilities::addWindowEventListener(d_window,
                                                     d_windowEventListener);

        d_ogreRoot->addFrameListener(this);
        renderer.setRenderingEnabled(false);

        d_initialised = true;
    }
    else
    {
        // aborted.  Clean up and set root to 0 so when app attempts to run it
        // knows what happened here.
        delete d_ogreRoot;
        d_ogreRoot = 0;
    }
}

//----------------------------------------------------------------------------//
CEGuiOgreBaseApplication::~CEGuiOgreBaseApplication()
{
    delete d_frameListener;

    CEGUI::OgreRenderer& renderer =
        *static_cast<CEGUI::OgreRenderer*>(d_renderer);
    renderer.destroyOgreResourceProvider(
        *static_cast<CEGUI::OgreResourceProvider*>(d_resourceProvider));
    renderer.destroyOgreImageCodec(
        *static_cast<CEGUI::OgreImageCodec*>(d_imageCodec));
    CEGUI::OgreRenderer::destroy(renderer);

    delete d_ogreRoot;
    delete d_windowEventListener;
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::run()
{
    // if base initialisation failed or app was cancelled by user, bail out now.
    if (!d_ogreRoot || !d_initialised)
        return;

    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    d_sampleApp->initialise();

    // start rendering via Ogre3D engine.
    CEGUI_TRY
    {
        d_ogreRoot->startRendering();
    }
    CEGUI_CATCH(...)
    {}
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::destroyWindow()
{

}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::beginRendering(const float elapsed)
{
    // this is nover called under Ogre, since we're not in control of the
    // rendering process.
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::endRendering()
{
    // this is nover called under Ogre, since we're not in control of the
    // rendering process.
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::initialiseResourceGroupDirectories()
{
    using namespace Ogre;
    ResourceGroupManager& rgm = ResourceGroupManager::getSingleton();

    // add resource groups that we use
    rgm.createResourceGroup("animations");
    rgm.createResourceGroup("imagesets");
    rgm.createResourceGroup("fonts");
    rgm.createResourceGroup("layouts");
    rgm.createResourceGroup("schemes");
    rgm.createResourceGroup("looknfeels");
    rgm.createResourceGroup("lua_scripts");
    rgm.createResourceGroup("schemas");

    // add CEGUI sample framework datafile dirs as resource locations
    ResourceGroupManager::getSingleton().addResourceLocation("./", "FileSystem");

    const char* dataPathPrefix = getDataPathPrefix();
    char resourcePath[PATH_MAX];

    // for each resource type, set a resource group directory
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "schemes/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "schemes");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "imagesets/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "imagesets");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "fonts/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "fonts");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "layouts/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "layouts");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "looknfeel/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "looknfeels");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "lua_scripts/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "lua_scripts");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "animations/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "animations");
    sprintf(resourcePath, "%s/%s", dataPathPrefix, "xml_schemas/");
    ResourceGroupManager::getSingleton().addResourceLocation(resourcePath, "FileSystem", "schemas");
}

//----------------------------------------------------------------------------//
void CEGuiOgreBaseApplication::doFrameUpdate(const float elapsed)
{
}
//----------------------------------------------------------------------------//
bool CEGuiOgreBaseApplication::frameRenderingQueued(const Ogre::FrameEvent& args)
{
    renderSingleFrame(static_cast<float>(args.timeSinceLastFrame));

    return true;
}

//----------------------------------------------------------------------------//

bool CEGuiOgreBaseApplication::isInitialised()
{
    return d_initialised;
}

//----------------------------------------------------------------------------//

////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
    Start of CEGuiDemoFrameListener mehods
*******************************************************************************/
////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------//
CEGuiDemoFrameListener::CEGuiDemoFrameListener(CEGuiOgreBaseApplication* baseApp, SamplesFrameworkBase*& sampleApp,
    Ogre::RenderWindow* window, Ogre::Camera* camera, bool useBufferedInputKeys, bool useBufferedInputMouse)
    : d_baseApp(baseApp),
    d_sampleApp(sampleApp)
{
    // OIS setup
    OIS::ParamList paramList;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;

    // get window handle
    window->getCustomAttribute("WINDOW", &windowHnd);

    // fill param list
    windowHndStr << (unsigned int)windowHnd;
    paramList.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));

#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX && defined (DEBUG)
    paramList.insert(std::make_pair(std::string("x11_keyboard_grab"), "false"));
    paramList.insert(std::make_pair(std::string("x11_mouse_grab"), "false"));
    paramList.insert(std::make_pair(std::string("x11_mouse_hide"), "false"));
#endif

    // create input system
    d_inputManager = OIS::InputManager::createInputSystem(paramList);

    // create buffered keyboard
#ifdef CEGUI_OLD_OIS_API
    if (d_inputManager->numKeyboards() > 0)
#else
    if (d_inputManager->getNumberOfDevices(OIS::OISKeyboard) > 0)
#endif
    {
        d_keyboard = static_cast<OIS::Keyboard*>(d_inputManager->createInputObject(OIS::OISKeyboard, true));
        d_keyboard->setEventCallback(this);
    }

    // create buffered mouse
#ifdef CEGUI_OLD_OIS_API
    if (d_inputManager->numMice() > 0)
#else
    if (d_inputManager->getNumberOfDevices(OIS::OISMouse) > 0)
#endif
    {
        d_mouse = static_cast<OIS::Mouse*>(d_inputManager->createInputObject(OIS::OISMouse, true));
        d_mouse->setEventCallback(this);

        unsigned int width, height, depth;
        int left, top;

        window->getMetrics(width, height, depth, left, top);
        const OIS::MouseState& mouseState = d_mouse->getMouseState();
        mouseState.width = width;
        mouseState.height = height;
    }

    // store inputs we want to make use of
    d_camera = camera;
    d_window = window;
}

//----------------------------------------------------------------------------//
CEGuiDemoFrameListener::~CEGuiDemoFrameListener()
{
    if (d_inputManager)
    {
        d_inputManager->destroyInputObject(d_mouse);
        d_inputManager->destroyInputObject(d_keyboard);
        OIS::InputManager::destroyInputSystem(d_inputManager);
    }
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::frameStarted(const Ogre::FrameEvent& evt)
{
    if(d_window->isClosed() || d_sampleApp->isQuitting())
        return false;

    static_cast<CEGuiOgreBaseApplication*>(d_baseApp)->
        doFrameUpdate(static_cast<float>(evt.timeSinceLastFrame));

    // update input system
    if (d_mouse)
        d_mouse->capture();
    if (d_keyboard)
        d_keyboard->capture();

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::frameEnded(const Ogre::FrameEvent& evt)
{
    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::mouseMoved(const OIS::MouseEvent &e)
{
    d_sampleApp->injectMousePosition(e.state.X.abs, e.state.Y.abs);
    d_sampleApp->injectMouseWheelChange(e.state.Z.rel / 120.0f);

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::keyPressed(const OIS::KeyEvent &e)
{
    d_sampleApp->injectKeyDown(static_cast<CEGUI::Key::Scan>(e.key));
    d_sampleApp->injectChar(e.text);

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::keyReleased(const OIS::KeyEvent &e)
{
    d_sampleApp->injectKeyUp(static_cast<CEGUI::Key::Scan>(e.key));

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::mousePressed(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
    d_sampleApp->injectMouseButtonDown(convertOISButtonToCegui(id));

    return true;
}

//----------------------------------------------------------------------------//
bool CEGuiDemoFrameListener::mouseReleased(const OIS::MouseEvent &e, OIS::MouseButtonID id)
{
   d_sampleApp->injectMouseButtonUp(convertOISButtonToCegui(id));

    return true;
}

//----------------------------------------------------------------------------//
CEGUI::MouseButton CEGuiDemoFrameListener::convertOISButtonToCegui(int buttonID)
{
   using namespace OIS;

   switch (buttonID)
    {
   case OIS::MB_Left:
        return CEGUI::LeftButton;
   case OIS::MB_Right:
        return CEGUI::RightButton;
   case OIS::MB_Middle:
        return CEGUI::MiddleButton;
    default:
        return CEGUI::LeftButton;
   }
}

//----------------------------------------------------------------------------//
OIS::Mouse* CEGuiDemoFrameListener::getOISMouse()
{
    return d_mouse;
}

//----------------------------------------------------------------------------//

////////////////////////////////////////////////////////////////////////////////
/*******************************************************************************
    Start of WndEvtListener member functions
*******************************************************************************/
////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------//
WndEvtListener::WndEvtListener(OIS::Mouse* mouse) :
    d_mouse(mouse)
{
}

//----------------------------------------------------------------------------//
void WndEvtListener::windowResized(Ogre::RenderWindow* rw)
{
    CEGUI::System* const sys = CEGUI::System::getSingletonPtr();
    if (sys)
        sys->notifyDisplaySizeChanged(
        CEGUI::Sizef(static_cast<float>(rw->getWidth()),
        static_cast<float>(rw->getHeight())));

    const OIS::MouseState& mouseState = d_mouse->getMouseState();
    mouseState.width = rw->getWidth();
    mouseState.height = rw->getHeight();
}

//----------------------------------------------------------------------------//

#endif

<|endoftext|>


<commit_before>/*
 * Copyright 2008 by Tommi Rantala <tt.rantala@gmail.com>
 *
 * 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.
 */

/* Implements a multi-way mergesort based on the loser tree.
 */

#include "routine.h"
#include "util/debug.h"
#include <cassert>
#include <cstring>
#include <boost/array.hpp>

static inline int
cmp(const unsigned char* a, const unsigned char* b)
{
	assert(a != 0);
	assert(b != 0);
	return strcmp(reinterpret_cast<const char*>(a),
	              reinterpret_cast<const char*>(b));
}

#include "losertree.h"

void mergesort_4way(unsigned char**, size_t, unsigned char**);

template <unsigned K>
static void
mergesort_losertree(unsigned char** strings, size_t n, unsigned char** tmp)
{
	if (n < 0x10000) {
		mergesort_4way(strings, n, tmp);
		return;
	}
	debug() << __func__ << "(), n="<<n<<"\n";
	const size_t split = size_t(double(n) / double(K));
	boost::array<std::pair<unsigned char**, size_t>, K> ranges;
	for (unsigned i=0; i < K-1; ++i) {
		ranges[i] = std::make_pair(strings+i*split, split);
	}
	ranges[K-1] = std::make_pair(strings+(K-1)*split, n-(K-1)*split);
	for (unsigned i=0; i < K; ++i) {
		mergesort_losertree<K>(ranges[i].first, ranges[i].second,
				tmp+(ranges[i].first-strings));
	}
	unsigned char** result = tmp;
	loser_tree<unsigned char*> tree(ranges.begin(), ranges.end());
	while (tree._nonempty_streams) { *result++ = tree.min(); }
	(void) memcpy(strings, tmp, n*sizeof(unsigned char*));
}

void mergesort_losertree_64way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<64>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_128way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<128>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_256way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<256>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_512way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<512>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_1024way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<1024>(strings, n, tmp);
	free(tmp);
}

ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_64way,
		"64way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_128way,
		"128way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_256way,
		"256way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_512way,
		"512way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_1024way,
		"1024way loser tree based mergesort")
<commit_msg>Parallel losertree based mergesort routines<commit_after>/*
 * Copyright 2008 by Tommi Rantala <tt.rantala@gmail.com>
 *
 * 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.
 */

/* Implements a multi-way mergesort based on the loser tree.
 */

#include "routine.h"
#include "util/debug.h"
#include <cassert>
#include <cstring>
#include <boost/array.hpp>

static inline int
cmp(const unsigned char* a, const unsigned char* b)
{
	assert(a != 0);
	assert(b != 0);
	return strcmp(reinterpret_cast<const char*>(a),
	              reinterpret_cast<const char*>(b));
}

#include "losertree.h"

void mergesort_4way(unsigned char**, size_t, unsigned char**);

template <unsigned K>
static void
mergesort_losertree(unsigned char** strings, size_t n, unsigned char** tmp)
{
	if (n < 0x10000) {
		mergesort_4way(strings, n, tmp);
		return;
	}
	debug() << __func__ << "(), n="<<n<<"\n";
	const size_t split = size_t(double(n) / double(K));
	boost::array<std::pair<unsigned char**, size_t>, K> ranges;
	for (unsigned i=0; i < K-1; ++i) {
		ranges[i] = std::make_pair(strings+i*split, split);
	}
	ranges[K-1] = std::make_pair(strings+(K-1)*split, n-(K-1)*split);
	for (unsigned i=0; i < K; ++i) {
		mergesort_losertree<K>(ranges[i].first, ranges[i].second,
				tmp+(ranges[i].first-strings));
	}
	unsigned char** result = tmp;
	loser_tree<unsigned char*> tree(ranges.begin(), ranges.end());
	while (tree._nonempty_streams) { *result++ = tree.min(); }
	(void) memcpy(strings, tmp, n*sizeof(unsigned char*));
}

void mergesort_losertree_64way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<64>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_128way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<128>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_256way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<256>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_512way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<512>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_1024way(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree<1024>(strings, n, tmp);
	free(tmp);
}

ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_64way,
		"64way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_128way,
		"128way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_256way,
		"256way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_512way,
		"512way loser tree based mergesort")
ROUTINE_REGISTER_SINGLECORE(mergesort_losertree_1024way,
		"1024way loser tree based mergesort")

void mergesort_4way_parallel(unsigned char**, size_t, unsigned char**);

template <unsigned K>
static void
mergesort_losertree_parallel(unsigned char** strings, size_t n, unsigned char** tmp)
{
	if (n < 0x10000) {
		mergesort_4way_parallel(strings, n, tmp);
		return;
	}
	debug() << __func__ << "(), n="<<n<<"\n";
	const size_t split = size_t(double(n) / double(K));
	boost::array<std::pair<unsigned char**, size_t>, K> ranges;
	for (unsigned i=0; i < K-1; ++i) {
		ranges[i] = std::make_pair(strings+i*split, split);
	}
	ranges[K-1] = std::make_pair(strings+(K-1)*split, n-(K-1)*split);
#pragma omp parallel for
	for (unsigned i=0; i < K; ++i) {
		mergesort_losertree_parallel<K>(ranges[i].first, ranges[i].second,
				tmp+(ranges[i].first-strings));
	}
	unsigned char** result = tmp;
	loser_tree<unsigned char*> tree(ranges.begin(), ranges.end());
	while (tree._nonempty_streams) { *result++ = tree.min(); }
	(void) memcpy(strings, tmp, n*sizeof(unsigned char*));
}

void mergesort_losertree_64way_parallel(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree_parallel<64>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_128way_parallel(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree_parallel<128>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_256way_parallel(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree_parallel<256>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_512way_parallel(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree_parallel<512>(strings, n, tmp);
	free(tmp);
}
void mergesort_losertree_1024way_parallel(unsigned char** strings, size_t n)
{
	unsigned char** tmp = static_cast<unsigned char**>(
			malloc(n*sizeof(unsigned char*)));
	mergesort_losertree_parallel<1024>(strings, n, tmp);
	free(tmp);
}

ROUTINE_REGISTER_MULTICORE(mergesort_losertree_64way_parallel,
		"Parallel 64way loser tree based mergesort")
ROUTINE_REGISTER_MULTICORE(mergesort_losertree_128way_parallel,
		"Parallel 128way loser tree based mergesort")
ROUTINE_REGISTER_MULTICORE(mergesort_losertree_256way_parallel,
		"Parallel 256way loser tree based mergesort")
ROUTINE_REGISTER_MULTICORE(mergesort_losertree_512way_parallel,
		"Parallel 512way loser tree based mergesort")
ROUTINE_REGISTER_MULTICORE(mergesort_losertree_1024way_parallel,
		"Parallel 1024way loser tree based mergesort")
<|endoftext|>