<commit_before>///
//
// LibSourcey
// Copyright (c) 2005, Sourcey <http://sourcey.com>
//
// SPDX-License-Identifier: LGPL-2.1+
//
/// @addtogroup net
/// @{

#include "scy/net/socketadapter.h"
#include "scy/net/socket.h"

#include <iterator>

using std::endl;

namespace scy {
namespace net {

SocketAdapter::SocketAdapter(SocketAdapter* sender)
    : priority(0)
    , _sender(sender)
    , _dirty(false)
{
    // TraceS(this) << "Create" << endl;
    assert(sender != this);
}

SocketAdapter::~SocketAdapter()
{
    // TraceS(this) << "Destroy" << endl;
    // assert(_receivers.empty());
}

ssize_t SocketAdapter::send(const char* data, size_t len, int flags)
{
    assert(_sender); // should have output adapter if default impl is used
    if (!_sender)
        return -1;
    return _sender->send(data, len, flags);
}

ssize_t SocketAdapter::send(const char* data, size_t len, const Address& peerAddress, int flags)
{
    assert(_sender); // should have output adapter if default impl is used
    if (!_sender)
        return -1;
    return _sender->send(data, len, peerAddress, flags);
}

ssize_t SocketAdapter::sendPacket(const IPacket& packet, int flags)
{
    // Try to cast as RawPacket so we can send without copying any data.
    auto raw = dynamic_cast<const RawPacket*>(&packet);
    if (raw)
        return send((const char*)raw->data(), raw->size(), flags);

    // Dynamically generated packets need to be written to a
    // temp buffer for sending.
    else {
        Buffer buf;
        packet.write(buf);
        return send(buf.data(), buf.size(), flags);
    }
}

ssize_t SocketAdapter::sendPacket(const IPacket& packet, const Address& peerAddress, int flags)
{
    // Try to cast as RawPacket so we can send without copying any data.
    auto raw = dynamic_cast<const RawPacket*>(&packet);
    if (raw)
        return send((const char*)raw->data(), raw->size(), peerAddress, flags);

    // Dynamically generated packets need to be written to a
    // temp buffer for sending.
    else {
        Buffer buf;
        buf.reserve(2048);
        packet.write(buf);
        return send(buf.data(), buf.size(), peerAddress, flags);
    }
}

void SocketAdapter::sendPacket(IPacket& packet)
{
    size_t res = sendPacket(packet, 0);
    if (res < 0)
        throw std::runtime_error("Invalid socket operation");
}

void SocketAdapter::onSocketConnect(Socket& socket)
{
    try {
        cleanupReceivers();
        size_t current = _receivers.size() - 1;
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive)
                ref->ptr->onSocketConnect(socket);
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::onSocketRecv(Socket& socket, const MutableBuffer& buffer, const Address& peerAddress)
{
    try {
        cleanupReceivers();
        size_t current = _receivers.size() - 1;
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive)
                ref->ptr->onSocketRecv(socket, buffer, peerAddress);
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::onSocketError(Socket& socket, const scy::Error& error)
{
    try {
        cleanupReceivers();
        size_t current = _receivers.size() - 1;
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive)
                ref->ptr->onSocketError(socket, error);
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::onSocketClose(Socket& socket)
{
    try {
        cleanupReceivers();
        size_t current = _receivers.size() - 1;
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive) {
                ref->ptr->onSocketClose(socket);
            }
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::setSender(SocketAdapter* adapter)
{
    assert(adapter != this);
    if (_sender == adapter)
        return;
    _sender = adapter;
}

bool SocketAdapter::hasReceiver(SocketAdapter* adapter)
{
    for (auto& receiver : _receivers) {
        if (receiver->ptr == adapter)
            return true;
    }
    return false;
}

void SocketAdapter::addReceiver(SocketAdapter* adapter)
{
    assert(adapter->priority <= 100);
    assert(adapter != this);
    if (hasReceiver(adapter))
        return;

    // Note that we insert new adapters in the back of the queue,
    // and iterate in reverse to ensure calling order is preserved.
    _dirty = true;
    _receivers.push_back(new Ref{ adapter, true });
    // _receivers.insert(_receivers.begin(), new Ref{ adapter, false }); // insert front
    // std::sort(_receivers.begin(), _receivers.end(),
    //     [](SocketAdapter const& l, SocketAdapter const& r) {
    //     return l.priority > r.priority; });
}

void SocketAdapter::removeReceiver(SocketAdapter* adapter)
{
    assert(adapter != this);
    auto it = std::find_if(_receivers.begin(), _receivers.end(),
        [&](const Ref* ref) { return ref->ptr == adapter; });
    if (it != _receivers.end()) { (*it)->alive = false; }
}

void SocketAdapter::cleanupReceivers()
{
    if (!_dirty) return;
    for (auto it = _receivers.begin(); it != _receivers.end();) {
        auto ref = *it;
        if (!ref->alive) {
            delete ref;
            it = _receivers.erase(it);
        }
        else ++it;
    }
    _dirty = false;
}

SocketAdapter* SocketAdapter::sender()
{
    return _sender;
}

std::vector<SocketAdapter*> SocketAdapter::receivers()
{
    std::vector<SocketAdapter*> items;
    std::transform(_receivers.begin(), _receivers.end(), std::back_inserter(items),
        [](const Ref* ref) { return ref->ptr; });
    return items;
}

} // namespace net
} // namespace scy

/// @\}
<commit_msg>Update the use of signed/unsigned integers<commit_after>///
//
// LibSourcey
// Copyright (c) 2005, Sourcey <http://sourcey.com>
//
// SPDX-License-Identifier: LGPL-2.1+
//
/// @addtogroup net
/// @{

#include "scy/net/socketadapter.h"
#include "scy/net/socket.h"

#include <iterator>

using std::endl;

namespace scy {
namespace net {

SocketAdapter::SocketAdapter(SocketAdapter* sender)
    : priority(0)
    , _sender(sender)
    , _dirty(false)
{
    // TraceS(this) << "Create" << endl;
    assert(sender != this);
}

SocketAdapter::~SocketAdapter()
{
    // TraceS(this) << "Destroy" << endl;
    // assert(_receivers.empty());
}

ssize_t SocketAdapter::send(const char* data, size_t len, int flags)
{
    assert(_sender); // should have output adapter if default impl is used
    if (!_sender)
        return -1;
    return _sender->send(data, len, flags);
}

ssize_t SocketAdapter::send(const char* data, size_t len, const Address& peerAddress, int flags)
{
    assert(_sender); // should have output adapter if default impl is used
    if (!_sender)
        return -1;
    return _sender->send(data, len, peerAddress, flags);
}

ssize_t SocketAdapter::sendPacket(const IPacket& packet, int flags)
{
    // Try to cast as RawPacket so we can send without copying any data.
    auto raw = dynamic_cast<const RawPacket*>(&packet);
    if (raw)
        return send((const char*)raw->data(), raw->size(), flags);

    // Dynamically generated packets need to be written to a
    // temp buffer for sending.
    else {
        Buffer buf;
        packet.write(buf);
        return send(buf.data(), buf.size(), flags);
    }
}

ssize_t SocketAdapter::sendPacket(const IPacket& packet, const Address& peerAddress, int flags)
{
    // Try to cast as RawPacket so we can send without copying any data.
    auto raw = dynamic_cast<const RawPacket*>(&packet);
    if (raw)
        return send((const char*)raw->data(), raw->size(), peerAddress, flags);

    // Dynamically generated packets need to be written to a
    // temp buffer for sending.
    else {
        Buffer buf;
        buf.reserve(2048);
        packet.write(buf);
        return send(buf.data(), buf.size(), peerAddress, flags);
    }
}

void SocketAdapter::sendPacket(IPacket& packet)
{
    size_t res = sendPacket(packet, 0);
    if (res < 0)
        throw std::runtime_error("Invalid socket operation");
}

void SocketAdapter::onSocketConnect(Socket& socket)
{
    try {
        cleanupReceivers();
        int current = int(_receivers.size() - 1);
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive)
                ref->ptr->onSocketConnect(socket);
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::onSocketRecv(Socket& socket, const MutableBuffer& buffer, const Address& peerAddress)
{
    try {
        cleanupReceivers();
        int current = int(_receivers.size() - 1);
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive)
                ref->ptr->onSocketRecv(socket, buffer, peerAddress);
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::onSocketError(Socket& socket, const scy::Error& error)
{
    try {
        cleanupReceivers();
        int current = int(_receivers.size() - 1);
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive)
                ref->ptr->onSocketError(socket, error);
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::onSocketClose(Socket& socket)
{
    try {
        cleanupReceivers();
        int current = int(_receivers.size() - 1);
        while (current >= 0) {
            auto ref = _receivers[current--];
            if (ref->alive) {
                ref->ptr->onSocketClose(socket);
            }
        }
    }
    catch (StopPropagation&) {
    }
}

void SocketAdapter::setSender(SocketAdapter* adapter)
{
    assert(adapter != this);
    if (_sender == adapter)
        return;
    _sender = adapter;
}

bool SocketAdapter::hasReceiver(SocketAdapter* adapter)
{
    for (auto& receiver : _receivers) {
        if (receiver->ptr == adapter)
            return true;
    }
    return false;
}

void SocketAdapter::addReceiver(SocketAdapter* adapter)
{
    assert(adapter->priority <= 100);
    assert(adapter != this);
    if (hasReceiver(adapter))
        return;

    // Note that we insert new adapters in the back of the queue,
    // and iterate in reverse to ensure calling order is preserved.
    _dirty = true;
    _receivers.push_back(new Ref{ adapter, true });
    // _receivers.insert(_receivers.begin(), new Ref{ adapter, false }); // insert front
    // std::sort(_receivers.begin(), _receivers.end(),
    //     [](SocketAdapter const& l, SocketAdapter const& r) {
    //     return l.priority > r.priority; });
}

void SocketAdapter::removeReceiver(SocketAdapter* adapter)
{
    assert(adapter != this);
    auto it = std::find_if(_receivers.begin(), _receivers.end(),
        [&](const Ref* ref) { return ref->ptr == adapter; });
    if (it != _receivers.end()) { (*it)->alive = false; }
}

void SocketAdapter::cleanupReceivers()
{
    if (!_dirty) return;
    for (auto it = _receivers.begin(); it != _receivers.end();) {
        auto ref = *it;
        if (!ref->alive) {
            delete ref;
            it = _receivers.erase(it);
        }
        else ++it;
    }
    _dirty = false;
}

SocketAdapter* SocketAdapter::sender()
{
    return _sender;
}

std::vector<SocketAdapter*> SocketAdapter::receivers()
{
    std::vector<SocketAdapter*> items;
    std::transform(_receivers.begin(), _receivers.end(), std::back_inserter(items),
        [](const Ref* ref) { return ref->ptr; });
    return items;
}

} // namespace net
} // namespace scy

/// @\}
<|endoftext|>


<commit_before>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2010, Rice University
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Rice University nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Ioan Sucan */

#include "ompl/base/Planner.h"
#include "ompl/util/Exception.h"
#include "ompl/base/GoalSampleableRegion.h"
#include <boost/thread.hpp>

ompl::base::Planner::Planner(const SpaceInformationPtr &si, const std::string &name) :
    si_(si), pis_(this), name_(name), setup_(false), msg_(name)
{
    if (!si_)
        throw Exception(name_, "Invalid space information instance for planner");
}

const ompl::base::PlannerSpecs& ompl::base::Planner::getSpecs(void) const
{
    return specs_;
}

const std::string& ompl::base::Planner::getName(void) const
{
    return name_;
}

void ompl::base::Planner::setName(const std::string &name)
{
    name_ = name;
    msg_.setPrefix(name_);
}

const ompl::base::SpaceInformationPtr&  ompl::base::Planner::getSpaceInformation(void) const
{
    return si_;
}

const ompl::base::ProblemDefinitionPtr& ompl::base::Planner::getProblemDefinition(void) const
{
    return pdef_;
}

void ompl::base::Planner::setProblemDefinition(const ProblemDefinitionPtr &pdef)
{
    pdef_ = pdef;
    pis_.update();
}

const ompl::base::PlannerInputStates& ompl::base::Planner::getPlannerInputStates(void) const
{
    return pis_;
}

void ompl::base::Planner::setup(void)
{
    if (!si_->isSetup())
    {
        msg_.inform("Space information setup was not yet called. Calling now.");
        si_->setup();
    }

    if (setup_)
        msg_.warn("Planner setup called multiple times");
    else
        setup_ = true;
}

void ompl::base::Planner::checkValidity(void)
{
    if (!isSetup())
        setup();
    pis_.checkValidity();
}

bool ompl::base::Planner::isSetup(void) const
{
    return setup_;
}

void ompl::base::Planner::clear(void)
{
    pis_.clear();
    pis_.update();
}

void ompl::base::Planner::getPlannerData(PlannerData &data) const
{
}

ompl::base::PlannerStatus ompl::base::Planner::solve(const PlannerTerminationConditionFn &ptc, double checkInterval)
{
    return solve(PlannerThreadedTerminationCondition(ptc, checkInterval));
}

ompl::base::PlannerStatus ompl::base::Planner::solve(double solveTime)
{
    if (solveTime < 1.0)
        return solve(timedPlannerTerminationCondition(solveTime));
    else
        return solve(timedPlannerTerminationCondition(solveTime, std::min(solveTime / 100.0, 0.1)));
}

void ompl::base::Planner::printProperties(std::ostream &out) const
{
    out << "Planner " + getName() + " specs:" << std::endl;
    out << "Multithreaded:                 " << (getSpecs().multithreaded ? "Yes" : "No") << std::endl;
    out << "Reports approximate solutions: " << (getSpecs().approximateSolutions ? "Yes" : "No") << std::endl;
    out << "Can optimize solutions:        " << (getSpecs().optimizingPaths ? "Yes" : "No") << std::endl;
    out << "Aware of the following parameters:";
    std::vector<std::string> params;
    params_.getParamNames(params);
    for (unsigned int i = 0 ; i < params.size() ; ++i)
        out << " " << params[i];
    out << std::endl;
}

void ompl::base::Planner::printSettings(std::ostream &out) const
{
    out << "Declared parameters for planner " << getName() << ":" << std::endl;
    params_.print(out);
}

void ompl::base::PlannerInputStates::clear(void)
{
    if (tempState_)
    {
        si_->freeState(tempState_);
        tempState_ = NULL;
    }
    addedStartStates_ = 0;
    sampledGoalsCount_ = 0;
    pdef_ = NULL;
    si_ = NULL;
}

void ompl::base::PlannerInputStates::restart(void)
{
    addedStartStates_ = 0;
    sampledGoalsCount_ = 0;
}

bool ompl::base::PlannerInputStates::update(void)
{
    if (!planner_)
        throw Exception("No planner set for PlannerInputStates");
    return use(planner_->getSpaceInformation(), planner_->getProblemDefinition());
}

void ompl::base::PlannerInputStates::checkValidity(void) const
{
    std::string error;

    if (!pdef_)
        error = "Problem definition not specified";
    else
    {
        if (pdef_->getStartStateCount() <= 0)
            error = "No start states specified";
        else
            if (!pdef_->getGoal())
                error = "No goal specified";
    }

    if (!error.empty())
    {
        if (planner_)
            throw Exception(planner_->getName(), error);
        else
            throw Exception(error);
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformationPtr &si, const ProblemDefinitionPtr &pdef)
{
    if (si && pdef)
        return use(si.get(), pdef.get());
    else
    {
        clear();
        return true;
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformation *si, const ProblemDefinition *pdef)
{
    if (pdef_ != pdef || si_ != si)
    {
        clear();
        pdef_ = pdef;
        si_ = si;
        return true;
    }
    return false;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextStart(void)
{
    if (pdef_ == NULL || si_ == NULL)
    {
        std::string error = "Missing space information or problem definition";
        if (planner_)
            throw Exception(planner_->getName(), error);
        else
            throw Exception(error);
    }

    while (addedStartStates_ < pdef_->getStartStateCount())
    {
        const base::State *st = pdef_->getStartState(addedStartStates_);
        addedStartStates_++;
        bool bounds = si_->satisfiesBounds(st);
        bool valid = bounds ? si_->isValid(st) : false;
        if (bounds && valid)
            return st;
        else
        {
            msg::Interface msg(planner_ ? planner_->getName() : "");
            msg.warn("Skipping invalid start state (invalid %s)", bounds ? "state": "bounds");
        }
    }
    return NULL;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(void)
{
    static PlannerAlwaysTerminatingCondition ptc;
    return nextGoal(ptc);
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(const PlannerTerminationCondition &ptc)
{
    if (pdef_ == NULL || si_ == NULL)
    {
        std::string error = "Missing space information or problem definition";
        if (planner_)
            throw Exception(planner_->getName(), error);
        else
            throw Exception(error);
    }

    const GoalSampleableRegion *goal = pdef_->getGoal()->hasType(GOAL_SAMPLEABLE_REGION) ? pdef_->getGoal()->as<GoalSampleableRegion>() : NULL;

    if (goal)
    {
        time::point start_wait;
        bool first = true;
        bool attempt = true;
        while (attempt)
        {
            attempt = false;

            if (sampledGoalsCount_ < goal->maxSampleCount() && goal->canSample())
            {
                if (tempState_ == NULL)
                    tempState_ = si_->allocState();
                do
                {
                    goal->sampleGoal(tempState_);
                    sampledGoalsCount_++;
                    bool bounds = si_->satisfiesBounds(tempState_);
                    bool valid = bounds ? si_->isValid(tempState_) : false;
                    if (bounds && valid)
                    {
                        if (!first) // if we waited, show how long
                        {
                            msg::Interface msg(planner_ ? planner_->getName() : "");
                            msg.debug("Waited %lf seconds for the first goal sample.", time::seconds(time::now() - start_wait));
                        }
                        return tempState_;
                    }
                    else
                    {
                        msg::Interface msg(planner_ ? planner_->getName() : "");
                        msg.warn("Skipping invalid goal state (invalid %s)", bounds ? "state": "bounds");
                    }
                }
                while (!ptc() && sampledGoalsCount_ < goal->maxSampleCount() && goal->canSample());
            }
            if (goal->couldSample() && !ptc())
            {
                if (first)
                {
                    first = false;
                    start_wait = time::now();
                    msg::Interface msg(planner_ ? planner_->getName() : "");
                    msg.debug("Waiting for goal region samples ...");
                }
                boost::this_thread::sleep(time::seconds(0.01));
                attempt = !ptc();
            }
        }
    }

    return NULL;
}

bool ompl::base::PlannerInputStates::haveMoreStartStates(void) const
{
    if (pdef_)
        return addedStartStates_ < pdef_->getStartStateCount();
    return false;
}

bool ompl::base::PlannerInputStates::haveMoreGoalStates(void) const
{
    if (pdef_ && pdef_->getGoal())
        if (pdef_->getGoal()->hasType(GOAL_SAMPLEABLE_REGION))
            return sampledGoalsCount_ < pdef_->getGoal()->as<GoalSampleableRegion>()->maxSampleCount();
    return false;
}
<commit_msg>more debug info<commit_after>/*********************************************************************
* Software License Agreement (BSD License)
*
*  Copyright (c) 2010, Rice University
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*   * Redistributions of source code must retain the above copyright
*     notice, this list of conditions and the following disclaimer.
*   * Redistributions in binary form must reproduce the above
*     copyright notice, this list of conditions and the following
*     disclaimer in the documentation and/or other materials provided
*     with the distribution.
*   * Neither the name of the Rice University nor the names of its
*     contributors may be used to endorse or promote products derived
*     from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
*  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
*  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
*  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
*  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
*  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
*  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
*  POSSIBILITY OF SUCH DAMAGE.
*********************************************************************/

/* Author: Ioan Sucan */

#include "ompl/base/Planner.h"
#include "ompl/util/Exception.h"
#include "ompl/base/GoalSampleableRegion.h"
#include <sstream>
#include <boost/thread.hpp>

ompl::base::Planner::Planner(const SpaceInformationPtr &si, const std::string &name) :
    si_(si), pis_(this), name_(name), setup_(false), msg_(name)
{
    if (!si_)
        throw Exception(name_, "Invalid space information instance for planner");
}

const ompl::base::PlannerSpecs& ompl::base::Planner::getSpecs(void) const
{
    return specs_;
}

const std::string& ompl::base::Planner::getName(void) const
{
    return name_;
}

void ompl::base::Planner::setName(const std::string &name)
{
    name_ = name;
    msg_.setPrefix(name_);
}

const ompl::base::SpaceInformationPtr&  ompl::base::Planner::getSpaceInformation(void) const
{
    return si_;
}

const ompl::base::ProblemDefinitionPtr& ompl::base::Planner::getProblemDefinition(void) const
{
    return pdef_;
}

void ompl::base::Planner::setProblemDefinition(const ProblemDefinitionPtr &pdef)
{
    pdef_ = pdef;
    pis_.update();
}

const ompl::base::PlannerInputStates& ompl::base::Planner::getPlannerInputStates(void) const
{
    return pis_;
}

void ompl::base::Planner::setup(void)
{
    if (!si_->isSetup())
    {
        msg_.inform("Space information setup was not yet called. Calling now.");
        si_->setup();
    }

    if (setup_)
        msg_.warn("Planner setup called multiple times");
    else
        setup_ = true;
}

void ompl::base::Planner::checkValidity(void)
{
    if (!isSetup())
        setup();
    pis_.checkValidity();
}

bool ompl::base::Planner::isSetup(void) const
{
    return setup_;
}

void ompl::base::Planner::clear(void)
{
    pis_.clear();
    pis_.update();
}

void ompl::base::Planner::getPlannerData(PlannerData &data) const
{
}

ompl::base::PlannerStatus ompl::base::Planner::solve(const PlannerTerminationConditionFn &ptc, double checkInterval)
{
    return solve(PlannerThreadedTerminationCondition(ptc, checkInterval));
}

ompl::base::PlannerStatus ompl::base::Planner::solve(double solveTime)
{
    if (solveTime < 1.0)
        return solve(timedPlannerTerminationCondition(solveTime));
    else
        return solve(timedPlannerTerminationCondition(solveTime, std::min(solveTime / 100.0, 0.1)));
}

void ompl::base::Planner::printProperties(std::ostream &out) const
{
    out << "Planner " + getName() + " specs:" << std::endl;
    out << "Multithreaded:                 " << (getSpecs().multithreaded ? "Yes" : "No") << std::endl;
    out << "Reports approximate solutions: " << (getSpecs().approximateSolutions ? "Yes" : "No") << std::endl;
    out << "Can optimize solutions:        " << (getSpecs().optimizingPaths ? "Yes" : "No") << std::endl;
    out << "Aware of the following parameters:";
    std::vector<std::string> params;
    params_.getParamNames(params);
    for (unsigned int i = 0 ; i < params.size() ; ++i)
        out << " " << params[i];
    out << std::endl;
}

void ompl::base::Planner::printSettings(std::ostream &out) const
{
    out << "Declared parameters for planner " << getName() << ":" << std::endl;
    params_.print(out);
}

void ompl::base::PlannerInputStates::clear(void)
{
    if (tempState_)
    {
        si_->freeState(tempState_);
        tempState_ = NULL;
    }
    addedStartStates_ = 0;
    sampledGoalsCount_ = 0;
    pdef_ = NULL;
    si_ = NULL;
}

void ompl::base::PlannerInputStates::restart(void)
{
    addedStartStates_ = 0;
    sampledGoalsCount_ = 0;
}

bool ompl::base::PlannerInputStates::update(void)
{
    if (!planner_)
        throw Exception("No planner set for PlannerInputStates");
    return use(planner_->getSpaceInformation(), planner_->getProblemDefinition());
}

void ompl::base::PlannerInputStates::checkValidity(void) const
{
    std::string error;

    if (!pdef_)
        error = "Problem definition not specified";
    else
    {
        if (pdef_->getStartStateCount() <= 0)
            error = "No start states specified";
        else
            if (!pdef_->getGoal())
                error = "No goal specified";
    }

    if (!error.empty())
    {
        if (planner_)
            throw Exception(planner_->getName(), error);
        else
            throw Exception(error);
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformationPtr &si, const ProblemDefinitionPtr &pdef)
{
    if (si && pdef)
        return use(si.get(), pdef.get());
    else
    {
        clear();
        return true;
    }
}

bool ompl::base::PlannerInputStates::use(const SpaceInformation *si, const ProblemDefinition *pdef)
{
    if (pdef_ != pdef || si_ != si)
    {
        clear();
        pdef_ = pdef;
        si_ = si;
        return true;
    }
    return false;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextStart(void)
{
    if (pdef_ == NULL || si_ == NULL)
    {
        std::string error = "Missing space information or problem definition";
        if (planner_)
            throw Exception(planner_->getName(), error);
        else
            throw Exception(error);
    }

    while (addedStartStates_ < pdef_->getStartStateCount())
    {
        const base::State *st = pdef_->getStartState(addedStartStates_);
        addedStartStates_++;
        bool bounds = si_->satisfiesBounds(st);
        bool valid = bounds ? si_->isValid(st) : false;
        if (bounds && valid)
            return st;
        else
        {
            msg::Interface msg(planner_ ? planner_->getName() : "");
            msg.warn("Skipping invalid start state (invalid %s)", bounds ? "state": "bounds");
            std::stringstream ss;
            si_->printState(st, ss);
            msg.debug("Discarded start state %s", ss.str().c_str());
        }
    }
    return NULL;
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(void)
{
    static PlannerAlwaysTerminatingCondition ptc;
    return nextGoal(ptc);
}

const ompl::base::State* ompl::base::PlannerInputStates::nextGoal(const PlannerTerminationCondition &ptc)
{
    if (pdef_ == NULL || si_ == NULL)
    {
        std::string error = "Missing space information or problem definition";
        if (planner_)
            throw Exception(planner_->getName(), error);
        else
            throw Exception(error);
    }

    const GoalSampleableRegion *goal = pdef_->getGoal()->hasType(GOAL_SAMPLEABLE_REGION) ? pdef_->getGoal()->as<GoalSampleableRegion>() : NULL;

    if (goal)
    {
        time::point start_wait;
        bool first = true;
        bool attempt = true;
        while (attempt)
        {
            attempt = false;

            if (sampledGoalsCount_ < goal->maxSampleCount() && goal->canSample())
            {
                if (tempState_ == NULL)
                    tempState_ = si_->allocState();
                do
                {
                    goal->sampleGoal(tempState_);
                    sampledGoalsCount_++;
                    bool bounds = si_->satisfiesBounds(tempState_);
                    bool valid = bounds ? si_->isValid(tempState_) : false;
                    if (bounds && valid)
                    {
                        if (!first) // if we waited, show how long
                        {
                            msg::Interface msg(planner_ ? planner_->getName() : "");
                            msg.debug("Waited %lf seconds for the first goal sample.", time::seconds(time::now() - start_wait));
                        }
                        return tempState_;
                    }
                    else
                    {
                        msg::Interface msg(planner_ ? planner_->getName() : "");
                        msg.warn("Skipping invalid goal state (invalid %s)", bounds ? "state": "bounds");
                        std::stringstream ss;
                        si_->printState(tempState_, ss);
                        msg.debug("Discarded goal state %s", ss.str().c_str());
                    }
                }
                while (!ptc() && sampledGoalsCount_ < goal->maxSampleCount() && goal->canSample());
            }
            if (goal->couldSample() && !ptc())
            {
                if (first)
                {
                    first = false;
                    start_wait = time::now();
                    msg::Interface msg(planner_ ? planner_->getName() : "");
                    msg.debug("Waiting for goal region samples ...");
                }
                boost::this_thread::sleep(time::seconds(0.01));
                attempt = !ptc();
            }
        }
    }

    return NULL;
}

bool ompl::base::PlannerInputStates::haveMoreStartStates(void) const
{
    if (pdef_)
        return addedStartStates_ < pdef_->getStartStateCount();
    return false;
}

bool ompl::base::PlannerInputStates::haveMoreGoalStates(void) const
{
    if (pdef_ && pdef_->getGoal())
        if (pdef_->getGoal()->hasType(GOAL_SAMPLEABLE_REGION))
            return sampledGoalsCount_ < pdef_->getGoal()->as<GoalSampleableRegion>()->maxSampleCount();
    return false;
}
<|endoftext|>


<commit_before>#include <float.h>
#include <math.h>
#include <stdio.h>

#include "simple_label.h"
#include "cache.h"
#include "rand48.h"
#include "vw.h"

using namespace std;

char* bufread_simple_label(shared_data* sd, label_data* ld, char* c)
{
  ld->label = *(float *)c;
  c += sizeof(ld->label);
  if (sd->binary_label && fabs(ld->label) != 1.f && ld->label != FLT_MAX)
    cout << "You are using a label not -1 or 1 with a loss function expecting that!" << endl;
  ld->weight = *(float *)c;
  c += sizeof(ld->weight);
  ld->initial = *(float *)c;
  c += sizeof(ld->initial);
  return c;
}

size_t read_cached_simple_label(shared_data* sd, void* v, io_buf& cache)
{
  label_data* ld = (label_data*) v;
  char *c;
  size_t total = sizeof(ld->label)+sizeof(ld->weight)+sizeof(ld->initial);
  if (buf_read(cache, c, total) < total)
    return 0;
  c = bufread_simple_label(sd, ld,c);

  return total;
}

float get_weight(void* v)
{
  label_data* ld = (label_data*) v;
  return ld->weight;
}

float get_initial(void* v)
{
  label_data* ld = (label_data*) v;
  return ld->initial;
}

char* bufcache_simple_label(label_data* ld, char* c)
{
  *(float *)c = ld->label;
  c += sizeof(ld->label);
  *(float *)c = ld->weight;
  c += sizeof(ld->weight);
  *(float *)c = ld->initial;
  c += sizeof(ld->initial);
  return c;
}

void cache_simple_label(void* v, io_buf& cache)
{
  char *c;
  label_data* ld = (label_data*) v;
  buf_write(cache, c, sizeof(ld->label)+sizeof(ld->weight)+sizeof(ld->initial));
  c = bufcache_simple_label(ld,c);
}

void default_simple_label(void* v)
{
  label_data* ld = (label_data*) v;
  ld->label = FLT_MAX;
  ld->weight = 1.;
  ld->initial = 0.;
}

void delete_simple_label(void* v)
{
}

void parse_simple_label(parser* p, shared_data* sd, void* v, v_array<substring>& words)
{
  label_data* ld = (label_data*)v;

  switch(words.size()) {
  case 0:
    break;
  case 1:
    ld->label = float_of_substring(words[0]);
    break;
  case 2:
    ld->label = float_of_substring(words[0]);
    ld->weight = float_of_substring(words[1]);
    break;
  case 3:
    ld->label = float_of_substring(words[0]);
    ld->weight = float_of_substring(words[1]);
    ld->initial = float_of_substring(words[2]);
    break;
  default:
    cerr << "malformed example!\n";
    cerr << "words.size() = " << words.size() << endl;
  }
  if (words.size() > 0 && sd->binary_label && fabs(ld->label) != 1.f)
    cout << "You are using a label not -1 or 1 with a loss function expecting that!" << endl;
}

float get_active_coin_bias(float k, float l, float g, float c0)
{
  float b,sb,rs,sl;
  b=(float)(c0*(log(k+1.)+0.0001)/(k+0.0001));
  sb=sqrt(b);
  if (l > 1.0) { l = 1.0; } else if (l < 0.0) { l = 0.0; } //loss should be in [0,1]
  sl=sqrt(l)+sqrt(l+g);
  if (g<=sb*sl+b)
    return 1;
  rs = (sl+sqrt(sl*sl+4*g))/(2*g);
  return b*rs*rs;
}

float query_decision(vw& all, example* ec, float k)
{
  float bias, avg_loss, weighted_queries;
  if (k<=1.)
    bias=1.;
  else{
    weighted_queries = (float)(all.initial_t + all.sd->weighted_examples - all.sd->weighted_unlabeled_examples);
    avg_loss = (float)(all.sd->sum_loss/k + sqrt((1.+0.5*log(k))/(weighted_queries+0.0001)));
    bias = get_active_coin_bias(k, avg_loss, ec->revert_weight/k, all.active_c0);
  }
  if(frand48()<bias)
    return 1.f/bias;
  else
    return -1.;
}

void print_update(vw& all, example *ec)
{
  if (all.sd->weighted_examples > all.sd->dump_interval && !all.quiet && !all.bfgs)
    {
      label_data* ld = (label_data*) ec->ld;
      char label_buf[32];
      if (ld->label == FLT_MAX)
	strcpy(label_buf," unknown");
      else
	sprintf(label_buf,"%8.4f",ld->label);

      if(!all.holdout_set_off && all.current_pass >= 1){

        fprintf(stderr, "%-6.5fh   %-6.5fh   %10ld %11.1f %s %8.4f %8lu\n",
	      all.sd->holdout_sum_loss/all.sd->weighted_holdout_examples,
	      all.sd->holdout_sum_loss_since_last_dump / all.sd->weighted_holdout_examples_since_last_dump,
	      (long int)all.sd->example_number,
	      all.sd->weighted_examples,
	      label_buf,
	      ec->final_prediction,
	      (long unsigned int)ec->num_features);

        all.sd->weighted_holdout_examples_since_last_dump = 0;
        all.sd->holdout_sum_loss_since_last_dump = 0.0;
      }
      else
        fprintf(stderr, "%-10.6f %-10.6f %10ld %11.1f %s %8.4f %8lu\n",
	      all.sd->sum_loss/all.sd->weighted_examples,
	      all.sd->sum_loss_since_last_dump / (all.sd->weighted_examples - all.sd->old_weighted_examples),
	      (long int)all.sd->example_number,
	      all.sd->weighted_examples,
	      label_buf,
	      ec->final_prediction,
	      (long unsigned int)ec->num_features);

      all.sd->sum_loss_since_last_dump = 0.0;
      all.sd->old_weighted_examples = all.sd->weighted_examples;
      all.sd->dump_interval *= 2;
    }
}

void output_and_account_example(vw& all, example* ec)
{
  label_data* ld = (label_data*)ec->ld;

  if(ec->test_only)
  {
    all.sd->weighted_holdout_examples += ec->global_weight;//test weight seen
    all.sd->weighted_holdout_examples_since_last_dump += ec->global_weight;
  }
  else
  {
  all.sd->weighted_examples += ld->weight;
  all.sd->weighted_labels += ld->label == FLT_MAX ? 0 : ld->label * ld->weight;
  all.sd->total_features += ec->num_features;
  all.sd->sum_loss += ec->loss;
  all.sd->sum_loss_since_last_dump += ec->loss;
  all.sd->example_number++;
  }
  all.print(all.raw_prediction, ec->partial_prediction, -1, ec->tag);

  float ai=-1;
  if(all.active && ld->label == FLT_MAX)
    ai=query_decision(all, ec, (float)all.sd->weighted_unlabeled_examples);
  all.sd->weighted_unlabeled_examples += ld->label == FLT_MAX ? ld->weight : 0;

  for (size_t i = 0; i<all.final_prediction_sink.size(); i++)
    {
      int f = (int)all.final_prediction_sink[i];
      if(all.active)
	active_print_result(f, ec->final_prediction, ai, ec->tag);
      else if (all.lda > 0)
	print_lda_result(all, f,ec->topic_predictions.begin,0.,ec->tag);
      else
	all.print(f, ec->final_prediction, 0, ec->tag);
    }

  print_update(all, ec);
}

void return_simple_example(vw& all, example* ec)
{
  if (!command_example(&all, ec))
    output_and_account_example(all, ec);
  VW::finish_example(all,ec);
}

<commit_msg>add h to the end of each line<commit_after>#include <float.h>
#include <math.h>
#include <stdio.h>

#include "simple_label.h"
#include "cache.h"
#include "rand48.h"
#include "vw.h"

using namespace std;

char* bufread_simple_label(shared_data* sd, label_data* ld, char* c)
{
  ld->label = *(float *)c;
  c += sizeof(ld->label);
  if (sd->binary_label && fabs(ld->label) != 1.f && ld->label != FLT_MAX)
    cout << "You are using a label not -1 or 1 with a loss function expecting that!" << endl;
  ld->weight = *(float *)c;
  c += sizeof(ld->weight);
  ld->initial = *(float *)c;
  c += sizeof(ld->initial);
  return c;
}

size_t read_cached_simple_label(shared_data* sd, void* v, io_buf& cache)
{
  label_data* ld = (label_data*) v;
  char *c;
  size_t total = sizeof(ld->label)+sizeof(ld->weight)+sizeof(ld->initial);
  if (buf_read(cache, c, total) < total)
    return 0;
  c = bufread_simple_label(sd, ld,c);

  return total;
}

float get_weight(void* v)
{
  label_data* ld = (label_data*) v;
  return ld->weight;
}

float get_initial(void* v)
{
  label_data* ld = (label_data*) v;
  return ld->initial;
}

char* bufcache_simple_label(label_data* ld, char* c)
{
  *(float *)c = ld->label;
  c += sizeof(ld->label);
  *(float *)c = ld->weight;
  c += sizeof(ld->weight);
  *(float *)c = ld->initial;
  c += sizeof(ld->initial);
  return c;
}

void cache_simple_label(void* v, io_buf& cache)
{
  char *c;
  label_data* ld = (label_data*) v;
  buf_write(cache, c, sizeof(ld->label)+sizeof(ld->weight)+sizeof(ld->initial));
  c = bufcache_simple_label(ld,c);
}

void default_simple_label(void* v)
{
  label_data* ld = (label_data*) v;
  ld->label = FLT_MAX;
  ld->weight = 1.;
  ld->initial = 0.;
}

void delete_simple_label(void* v)
{
}

void parse_simple_label(parser* p, shared_data* sd, void* v, v_array<substring>& words)
{
  label_data* ld = (label_data*)v;

  switch(words.size()) {
  case 0:
    break;
  case 1:
    ld->label = float_of_substring(words[0]);
    break;
  case 2:
    ld->label = float_of_substring(words[0]);
    ld->weight = float_of_substring(words[1]);
    break;
  case 3:
    ld->label = float_of_substring(words[0]);
    ld->weight = float_of_substring(words[1]);
    ld->initial = float_of_substring(words[2]);
    break;
  default:
    cerr << "malformed example!\n";
    cerr << "words.size() = " << words.size() << endl;
  }
  if (words.size() > 0 && sd->binary_label && fabs(ld->label) != 1.f)
    cout << "You are using a label not -1 or 1 with a loss function expecting that!" << endl;
}

float get_active_coin_bias(float k, float l, float g, float c0)
{
  float b,sb,rs,sl;
  b=(float)(c0*(log(k+1.)+0.0001)/(k+0.0001));
  sb=sqrt(b);
  if (l > 1.0) { l = 1.0; } else if (l < 0.0) { l = 0.0; } //loss should be in [0,1]
  sl=sqrt(l)+sqrt(l+g);
  if (g<=sb*sl+b)
    return 1;
  rs = (sl+sqrt(sl*sl+4*g))/(2*g);
  return b*rs*rs;
}

float query_decision(vw& all, example* ec, float k)
{
  float bias, avg_loss, weighted_queries;
  if (k<=1.)
    bias=1.;
  else{
    weighted_queries = (float)(all.initial_t + all.sd->weighted_examples - all.sd->weighted_unlabeled_examples);
    avg_loss = (float)(all.sd->sum_loss/k + sqrt((1.+0.5*log(k))/(weighted_queries+0.0001)));
    bias = get_active_coin_bias(k, avg_loss, ec->revert_weight/k, all.active_c0);
  }
  if(frand48()<bias)
    return 1.f/bias;
  else
    return -1.;
}

void print_update(vw& all, example *ec)
{
  if (all.sd->weighted_examples > all.sd->dump_interval && !all.quiet && !all.bfgs)
    {
      label_data* ld = (label_data*) ec->ld;
      char label_buf[32];
      if (ld->label == FLT_MAX)
	strcpy(label_buf," unknown");
      else
	sprintf(label_buf,"%8.4f",ld->label);

      if(!all.holdout_set_off && all.current_pass >= 1){

        fprintf(stderr, "%-10.6f %-10.6f %10ld %11.1f %s %8.4f %8luh\n",
	      all.sd->holdout_sum_loss/all.sd->weighted_holdout_examples,
	      all.sd->holdout_sum_loss_since_last_dump / all.sd->weighted_holdout_examples_since_last_dump,
	      (long int)all.sd->example_number,
	      all.sd->weighted_examples,
	      label_buf,
	      ec->final_prediction,
	      (long unsigned int)ec->num_features);

        all.sd->weighted_holdout_examples_since_last_dump = 0;
        all.sd->holdout_sum_loss_since_last_dump = 0.0;
      }
      else
        fprintf(stderr, "%-10.6f %-10.6f %10ld %11.1f %s %8.4f %8lu\n",
	      all.sd->sum_loss/all.sd->weighted_examples,
	      all.sd->sum_loss_since_last_dump / (all.sd->weighted_examples - all.sd->old_weighted_examples),
	      (long int)all.sd->example_number,
	      all.sd->weighted_examples,
	      label_buf,
	      ec->final_prediction,
	      (long unsigned int)ec->num_features);

      all.sd->sum_loss_since_last_dump = 0.0;
      all.sd->old_weighted_examples = all.sd->weighted_examples;
      all.sd->dump_interval *= 2;
    }
}

void output_and_account_example(vw& all, example* ec)
{
  label_data* ld = (label_data*)ec->ld;

  if(ec->test_only)
  {
    all.sd->weighted_holdout_examples += ec->global_weight;//test weight seen
    all.sd->weighted_holdout_examples_since_last_dump += ec->global_weight;
  }
  else
  {
  all.sd->weighted_examples += ld->weight;
  all.sd->weighted_labels += ld->label == FLT_MAX ? 0 : ld->label * ld->weight;
  all.sd->total_features += ec->num_features;
  all.sd->sum_loss += ec->loss;
  all.sd->sum_loss_since_last_dump += ec->loss;
  all.sd->example_number++;
  }
  all.print(all.raw_prediction, ec->partial_prediction, -1, ec->tag);

  float ai=-1;
  if(all.active && ld->label == FLT_MAX)
    ai=query_decision(all, ec, (float)all.sd->weighted_unlabeled_examples);
  all.sd->weighted_unlabeled_examples += ld->label == FLT_MAX ? ld->weight : 0;

  for (size_t i = 0; i<all.final_prediction_sink.size(); i++)
    {
      int f = (int)all.final_prediction_sink[i];
      if(all.active)
	active_print_result(f, ec->final_prediction, ai, ec->tag);
      else if (all.lda > 0)
	print_lda_result(all, f,ec->topic_predictions.begin,0.,ec->tag);
      else
	all.print(f, ec->final_prediction, 0, ec->tag);
    }

  print_update(all, ec);
}

void return_simple_example(vw& all, example* ec)
{
  if (!command_example(&all, ec))
    output_and_account_example(all, ec);
  VW::finish_example(all,ec);
}

<|endoftext|>


<commit_before>/* * This file is part of m-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mkeyboardsettings.h"
#include "mkeyboardsettingswidget.h"
#include "keyboarddata.h"

#include <QObject>
#include <QGraphicsWidget>
#include <QDir>
#include <QFileInfo>
#include <QDebug>

namespace {
    const QString SettingsIMCorrectionSetting("/meegotouch/inputmethods/correctionenabled");
    const QString InputMethodLanguages("/meegotouch/inputmethods/languages");
    const QString VKBConfigurationPath("/usr/share/meegotouch/virtual-keyboard/layouts/");
    const QString VKBLayoutsFilterRule("*.xml");
    const QString VKBLayoutsIgnoreRules("number|test"); // use as regexp to ignore number and test layouts
};

MKeyboardSettings::MKeyboardSettings()
    : keyboardErrorCorrectionConf(SettingsIMCorrectionSetting, this),
      selectedKeyboardsConf(InputMethodLanguages, this)
{
    readAvailableKeyboards();
    connect(&keyboardErrorCorrectionConf, SIGNAL(valueChanged()),
            this, SIGNAL(errorCorrectionChanged()));
    connect(&selectedKeyboardsConf, SIGNAL(valueChanged()),
            this, SIGNAL(selectedKeyboardsChanged()));
}

MKeyboardSettings::~MKeyboardSettings()
{
}

QGraphicsWidget *MKeyboardSettings::createContentWidget(QGraphicsWidget *parent)
{
    // the pointer of returned QGraphicsWidget is owned by the caller,
    // so we just always create a new containerWidget.
    return new MKeyboardSettingsWidget(this, parent);
}

QString MKeyboardSettings::title()
{
    //% "Virtual keyboards";
    return qtTrId("qtn_txts_virtual_keyboards");;
}

QString MKeyboardSettings::icon()
{
    return "";
}

void MKeyboardSettings::readAvailableKeyboards()
{
    availableKeyboardInfos.clear();
    // available keyboard languages are determined by xml layouts that can be found
    const QDir layoutsDir(VKBConfigurationPath, VKBLayoutsFilterRule);
    QRegExp ignoreExp(VKBLayoutsIgnoreRules, Qt::CaseInsensitive);

    foreach (QFileInfo keyboardFileInfo, layoutsDir.entryInfoList()) {
        if (keyboardFileInfo.fileName().contains(ignoreExp))
            continue;
        KeyboardData keyboard;
        if (keyboard.loadNokiaKeyboard(keyboardFileInfo.fileName())) {
            bool duplicated = false;
            foreach (const KeyboardInfo &info, availableKeyboardInfos) {
                if (info.language == keyboard.language()) {
                    duplicated = true;
                    break;
                }
            }
            if (!duplicated) {
                KeyboardInfo keyboardInfo;
                keyboardInfo.fileName = keyboardFileInfo.fileName();
                keyboardInfo.language = keyboard.language();
                keyboardInfo.title = keyboard.title();
                availableKeyboardInfos.append(keyboardInfo);
            }
        }
    }
}

QMap<QString, QString> MKeyboardSettings::availableKeyboards() const
{
    QMap<QString, QString> keyboards;
    foreach (const KeyboardInfo &keyboardInfo, availableKeyboardInfos) {
        keyboards.insert(keyboardInfo.language, keyboardInfo.title);
    }
    return keyboards;
}

QMap<QString, QString> MKeyboardSettings::selectedKeyboards() const
{
    QMap<QString, QString> keyboards;
    foreach (const QString language, selectedKeyboardsConf.value().toStringList()) {
        keyboards.insert(language, keyboardTitle(language));
    }
    return keyboards;
}

void MKeyboardSettings::setSelectedKeyboards(const QStringList &keyboardTitles)
{
    QStringList languages;
    foreach (const QString &title, keyboardTitles) {
        QString language = keyboardLanguage(title);
        if (!language.isEmpty() && !languages.contains(language)) {
            languages.append(language);
        }
    }
    selectedKeyboardsConf.set(languages);
}

QString MKeyboardSettings::keyboardTitle(const QString &language) const
{
    QString title;
    foreach (const KeyboardInfo &keyboardInfo, availableKeyboardInfos) {
        if (keyboardInfo.language == language) {
            title = keyboardInfo.title;
            break;
        }
    }
    return title;
}

QString MKeyboardSettings::keyboardLanguage(const QString &title) const
{
    QString language;
    foreach (const KeyboardInfo &keyboardInfo, availableKeyboardInfos) {
        if (keyboardInfo.title == title) {
            language = keyboardInfo.language;
            break;
        }
    }
    return language;
}

bool  MKeyboardSettings::errorCorrection() const
{
    return keyboardErrorCorrectionConf.value().toBool();
}

void  MKeyboardSettings::setErrorCorrection(bool enabled)
{
    if (keyboardErrorCorrectionConf.value().toBool() != enabled)
        keyboardErrorCorrectionConf.set(enabled);
}
<commit_msg>Fixes: keyboard settings should filter invalid layouts<commit_after>/* * This file is part of m-keyboard *
 *
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved.
 * Contact: Nokia Corporation (directui@nokia.com)
 *
 * If you have questions regarding the use of this file, please contact
 * Nokia at directui@nokia.com.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation
 * and appearing in the file LICENSE.LGPL included in the packaging
 * of this file.
 */

#include "mkeyboardsettings.h"
#include "mkeyboardsettingswidget.h"
#include "keyboarddata.h"

#include <QObject>
#include <QGraphicsWidget>
#include <QDir>
#include <QFileInfo>
#include <QDebug>

namespace {
    const QString SettingsIMCorrectionSetting("/meegotouch/inputmethods/correctionenabled");
    const QString InputMethodLanguages("/meegotouch/inputmethods/languages");
    const QString VKBConfigurationPath("/usr/share/meegotouch/virtual-keyboard/layouts/");
    const QString VKBLayoutsFilterRule("*.xml");
    const QString VKBLayoutsIgnoreRules("number|test"); // use as regexp to ignore number and test layouts
};

MKeyboardSettings::MKeyboardSettings()
    : keyboardErrorCorrectionConf(SettingsIMCorrectionSetting, this),
      selectedKeyboardsConf(InputMethodLanguages, this)
{
    readAvailableKeyboards();
    connect(&keyboardErrorCorrectionConf, SIGNAL(valueChanged()),
            this, SIGNAL(errorCorrectionChanged()));
    connect(&selectedKeyboardsConf, SIGNAL(valueChanged()),
            this, SIGNAL(selectedKeyboardsChanged()));
}

MKeyboardSettings::~MKeyboardSettings()
{
}

QGraphicsWidget *MKeyboardSettings::createContentWidget(QGraphicsWidget *parent)
{
    // the pointer of returned QGraphicsWidget is owned by the caller,
    // so we just always create a new containerWidget.
    return new MKeyboardSettingsWidget(this, parent);
}

QString MKeyboardSettings::title()
{
    //% "Virtual keyboards";
    return qtTrId("qtn_txts_virtual_keyboards");;
}

QString MKeyboardSettings::icon()
{
    return "";
}

void MKeyboardSettings::readAvailableKeyboards()
{
    availableKeyboardInfos.clear();
    // available keyboard languages are determined by xml layouts that can be found
    const QDir layoutsDir(VKBConfigurationPath, VKBLayoutsFilterRule);
    QRegExp ignoreExp(VKBLayoutsIgnoreRules, Qt::CaseInsensitive);

    foreach (QFileInfo keyboardFileInfo, layoutsDir.entryInfoList()) {
        if (keyboardFileInfo.fileName().contains(ignoreExp))
            continue;
        KeyboardData keyboard;
        if (keyboard.loadNokiaKeyboard(keyboardFileInfo.fileName())) {
            if (keyboard.language().isEmpty() || keyboard.title().isEmpty())
                continue;
            bool duplicated = false;
            foreach (const KeyboardInfo &info, availableKeyboardInfos) {
                if (info.language == keyboard.language()) {
                    duplicated = true;
                    break;
                }
            }
            if (!duplicated) {
                KeyboardInfo keyboardInfo;
                keyboardInfo.fileName = keyboardFileInfo.fileName();
                keyboardInfo.language = keyboard.language();
                keyboardInfo.title = keyboard.title();
                availableKeyboardInfos.append(keyboardInfo);
            }
        }
    }
}

QMap<QString, QString> MKeyboardSettings::availableKeyboards() const
{
    QMap<QString, QString> keyboards;
    foreach (const KeyboardInfo &keyboardInfo, availableKeyboardInfos) {
        keyboards.insert(keyboardInfo.language, keyboardInfo.title);
    }
    return keyboards;
}

QMap<QString, QString> MKeyboardSettings::selectedKeyboards() const
{
    QMap<QString, QString> keyboards;
    foreach (const QString language, selectedKeyboardsConf.value().toStringList()) {
        keyboards.insert(language, keyboardTitle(language));
    }
    return keyboards;
}

void MKeyboardSettings::setSelectedKeyboards(const QStringList &keyboardTitles)
{
    QStringList languages;
    foreach (const QString &title, keyboardTitles) {
        QString language = keyboardLanguage(title);
        if (!language.isEmpty() && !languages.contains(language)) {
            languages.append(language);
        }
    }
    selectedKeyboardsConf.set(languages);
}

QString MKeyboardSettings::keyboardTitle(const QString &language) const
{
    QString title;
    foreach (const KeyboardInfo &keyboardInfo, availableKeyboardInfos) {
        if (keyboardInfo.language == language) {
            title = keyboardInfo.title;
            break;
        }
    }
    return title;
}

QString MKeyboardSettings::keyboardLanguage(const QString &title) const
{
    QString language;
    foreach (const KeyboardInfo &keyboardInfo, availableKeyboardInfos) {
        if (keyboardInfo.title == title) {
            language = keyboardInfo.language;
            break;
        }
    }
    return language;
}

bool  MKeyboardSettings::errorCorrection() const
{
    return keyboardErrorCorrectionConf.value().toBool();
}

void  MKeyboardSettings::setErrorCorrection(bool enabled)
{
    if (keyboardErrorCorrectionConf.value().toBool() != enabled)
        keyboardErrorCorrectionConf.set(enabled);
}
<|endoftext|>


<commit_before>// @(#)root/tree:$Id$
// Author: Marek Biskup   07/06/2005

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//
// A Chain Index
//
//////////////////////////////////////////////////////////////////////////

#include "TChainIndex.h"
#include "TChain.h"
#include "TTreeFormula.h"
#include "TTreeIndex.h"
#include "TFile.h"
#include "TError.h"

ClassImp(TChainIndex)

//______________________________________________________________________________
TChainIndex::TChainIndex(): TVirtualIndex()
{
// Default constructor for TChainIndex

   fTree = 0;
   fMajorFormulaParent = fMinorFormulaParent = 0;
}

//______________________________________________________________________________
TChainIndex::TChainIndex(const TTree *T, const char *majorname, const char *minorname)
           : TVirtualIndex()
{
   // Normal constructor for TChainIndex. See TTreeIndex::TTreeIndex for the description of the
   // parameters.
   // The tree must be a TChain.
   // All the index values in the first tree of the chain must be
   // less then any index value in the second one, and so on.
   // If any of those requirements isn't met the object becomes a zombie.
   // If some subtrees don't have indices the indices are created and stored inside this
   // TChainIndex.

   fTree = 0;
   fMajorFormulaParent = fMinorFormulaParent = 0;

   TChain *chain = dynamic_cast<TChain*>(const_cast<TTree*>(T));
   if (!chain) {
      MakeZombie();
      Error("TChainIndex", "Cannot create a TChainIndex."
            " The Tree passed as an argument is not a TChain");
      return;
   }

   fTree               = (TTree*)T;
   fMajorName          = majorname;
   fMinorName          = minorname;
   Int_t i = 0;

   // Go through all the trees and check if they have indeces. If not then build them.
   for (i = 0; i < chain->GetNtrees(); i++) {
      chain->LoadTree((chain->GetTreeOffset())[i]);
      TVirtualIndex *index = chain->GetTree()->GetTreeIndex();

      TChainIndexEntry entry;
      entry.fTreeIndex = 0;

      //if an index already exists, we must check if major/minorname correspond
      //to the major/minor names in this function call
      if (index) {
         if (strcmp(majorname,index->GetMajorName()) || strcmp(minorname,index->GetMinorName())) {
            MakeZombie();
            Error("TChainIndex","Tree in file %s has an index built with majorname=%s and minorname=%s",chain->GetTree()->GetCurrentFile()->GetName(),index->GetMajorName(),index->GetMinorName());
            return;
         }
      }
      if (!index) {
         chain->GetTree()->BuildIndex(majorname, minorname);
         index = chain->GetTree()->GetTreeIndex();
         chain->GetTree()->SetTreeIndex(0);
         entry.fTreeIndex = index;
      }
      if (!index || index->IsZombie() || index->GetN() == 0) {
         DeleteIndices();
         MakeZombie();
         Error("TChainIndex", "Error creating a tree index on a tree in the chain");
         return;
      }

      TTreeIndex *ti_index = dynamic_cast<TTreeIndex*>(index);
      if (ti_index == 0) {
         Error("TChainIndex", "The underlying TTree must have a TTreeIndex but has a %s.",
               index->IsA()->GetName());
         return;
      }

      entry.fMinIndexValue = ti_index->GetIndexValues()[0];
      entry.fMaxIndexValue = ti_index->GetIndexValues()[index->GetN() - 1];
      fEntries.push_back(entry);
   }

   // Check if the indices of different trees are in order. If not then return an error.
   for (i = 0; i < Int_t(fEntries.size() - 1); i++) {
      if (fEntries[i].fMaxIndexValue > fEntries[i+1].fMinIndexValue) {
         DeleteIndices();
         MakeZombie();
         Error("TChainIndex", "The indices in files of this chain aren't sorted.");
      }
   }

}

//______________________________________________________________________________
void TChainIndex::Append(const TVirtualIndex *index, Bool_t delaySort )
{
   // add an index to this chain
   // if delaySort is kFALSE (default) check if the indices of different trees are in order.
   if (index) {
      const TTreeIndex *ti_index = dynamic_cast<const TTreeIndex*>(index);
      if (ti_index == 0) {
         Error("Append", "The given index is not a TTreeIndex but a %s",
               index->IsA()->GetName());
      }

      TChainIndexEntry entry;
      entry.fTreeIndex = 0;
      entry.fMinIndexValue = ti_index->GetIndexValues()[0];
      entry.fMaxIndexValue = ti_index->GetIndexValues()[index->GetN() - 1];
      fEntries.push_back(entry);
   }

   if (!delaySort) {
      // Check if the indices of different trees are in order. If not then return an error.
      for (Int_t i = 0; i < Int_t(fEntries.size() - 1); i++) {
         if (fEntries[i].fMaxIndexValue > fEntries[i+1].fMinIndexValue) {
            DeleteIndices();
            MakeZombie();
            Error("Append", "The indices in files of this chain aren't sorted.");
         }
      }
   }
}

//______________________________________________________________________________
void TChainIndex::DeleteIndices()
{
   // Delete all the indices which were built by this object
   for (unsigned int i = 0; i < fEntries.size(); i++) {
      if (fEntries[i].fTreeIndex) {
         if (fTree->GetTree() && fTree->GetTree()->GetTreeIndex() == fEntries[i].fTreeIndex) {
            fTree->GetTree()->SetTreeIndex(0);
            SafeDelete(fEntries[i].fTreeIndex);
         }
         SafeDelete(fEntries[i].fTreeIndex);
      }
   }
}

//______________________________________________________________________________
TChainIndex::~TChainIndex()
{
   // The destructor.
   DeleteIndices();
   if (fTree && fTree->GetTreeIndex() == this)
      fTree->SetTreeIndex(0);
}

//______________________________________________________________________________
std::pair<TVirtualIndex*, Int_t> TChainIndex::GetSubTreeIndex(Int_t major, Int_t minor) const
{
   // Returns a TVirtualIndex for a tree which holds the entry with the specified
   // major and minor values and the number of that tree.
   // If the index for that tree was created by this object it's set to the tree.
   // The tree index should be later released using ReleaseSubTreeIndex();

   using namespace std;
   if (fEntries.size() == 0) {
      Warning("GetSubTreeIndex", "No subindices in the chain. The chain is probably empty");
      return make_pair(static_cast<TVirtualIndex*>(0), 0);
   }

   Long64_t indexValue = (Long64_t(major) << 31) + minor;

   if (indexValue < fEntries[0].fMinIndexValue) {
      Warning("GetSubTreeIndex", "The index value is less than the smallest index values in subtrees");
      return make_pair(static_cast<TVirtualIndex*>(0), 0);
   }

   Int_t treeNo = fEntries.size() - 1;
   for (unsigned int i = 0; i < fEntries.size() - 1; i++) {
      if (indexValue < fEntries[i+1].fMinIndexValue) {
         treeNo = i;
         break;
      }
   }
   // Double check we found the right range.
   if (0 && indexValue > fEntries[treeNo].fMaxIndexValue) {
      return make_pair(static_cast<TVirtualIndex*>(0), 0);
   }
   TChain* chain = dynamic_cast<TChain*> (fTree);
   R__ASSERT(chain);
   chain->LoadTree(chain->GetTreeOffset()[treeNo]);
   TVirtualIndex* index =  fTree->GetTree()->GetTreeIndex();
   if (index)
      return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
   else {
      index = fEntries[treeNo].fTreeIndex;
      if (!index) {
         Warning("GetSubTreeIndex", "The tree has no index and the chain index"
                  " doesn't store an index for that tree");
         return make_pair(static_cast<TVirtualIndex*>(0), 0);
      }
      else {
         fTree->GetTree()->SetTreeIndex(index);
         return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
      }
   }
}

//______________________________________________________________________________
void TChainIndex::ReleaseSubTreeIndex(TVirtualIndex* index, int treeNo) const
{
   // Releases the tree index got using GetSubTreeIndex. If the index was
   // created by this object it is removed from the current tree, so that it isn't
   // deleted in its destructor.

   if (fEntries[treeNo].fTreeIndex == index) {
      R__ASSERT(fTree->GetTree()->GetTreeIndex() == index);
      fTree->GetTree()->SetTreeIndex(0);
   }
}

//______________________________________________________________________________
Long64_t TChainIndex::GetEntryNumberFriend(const TTree *parent)
{
   // see TTreeIndex::GetEntryNumberFriend for description

   if (!parent) return -3;
   GetMajorFormulaParent(parent);
   GetMinorFormulaParent(parent);
   if (!fMajorFormulaParent || !fMinorFormulaParent) return -1;
   if (!fMajorFormulaParent->GetNdim() || !fMinorFormulaParent->GetNdim()) {
      // The Tree Index in the friend has a pair majorname,minorname
      // not available in the parent Tree T.
      // if the friend Tree has less entries than the parent, this is an error
      Long64_t pentry = parent->GetReadEntry();
      if (pentry >= fTree->GetEntries()) return -2;
      // otherwise we ignore the Tree Index and return the entry number
      // in the parent Tree.
      return pentry;
   }

   // majorname, minorname exist in the parent Tree
   // we find the current values pair majorv,minorv in the parent Tree
   Double_t majord = fMajorFormulaParent->EvalInstance();
   Double_t minord = fMinorFormulaParent->EvalInstance();
   Long64_t majorv = (Long64_t)majord;
   Long64_t minorv = (Long64_t)minord;
   // we check if this pair exist in the index.
   // if yes, we return the corresponding entry number
   // if not the function returns -1
   return fTree->GetEntryNumberWithIndex(majorv,minorv);
}

//______________________________________________________________________________
Long64_t TChainIndex::GetEntryNumberWithBestIndex(Int_t major, Int_t minor) const
{
   // See TTreeIndex::GetEntryNumberWithBestIndex for details.

   std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
   if (!indexAndNumber.first) {
      Error("GetEntryNumberWithBestIndex","no index found");
      return -1;
   }
   else {
      Long64_t rv = indexAndNumber.first->GetEntryNumberWithBestIndex(major, minor);
      ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
      TChain* chain = dynamic_cast<TChain*> (fTree);
      R__ASSERT(chain);
      return rv + chain->GetTreeOffset()[indexAndNumber.second];
   }
}

//______________________________________________________________________________
Long64_t TChainIndex::GetEntryNumberWithIndex(Int_t major, Int_t minor) const
{
   // Returns the entry number with given index values.
   // See TTreeIndex::GetEntryNumberWithIndex for details.

   std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
   if (!indexAndNumber.first) {
      Error("GetEntryNumberWithIndex","no index found");
      return -1;
   }
   else {
      Long64_t rv = indexAndNumber.first->GetEntryNumberWithIndex(major, minor);
      ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
      TChain* chain = dynamic_cast<TChain*> (fTree);
      R__ASSERT(chain);
      if (rv > 0) {
         return rv + chain->GetTreeOffset()[indexAndNumber.second];
      } else {
         return rv;
      }
   }
}

//______________________________________________________________________________
TTreeFormula *TChainIndex::GetMajorFormulaParent(const TTree *parent)
{
   // return a pointer to the TreeFormula corresponding to the majorname in parent tree T

   if (!fMajorFormulaParent) {
      TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
      fMajorFormulaParent = new TTreeFormula("MajorP",fMajorName.Data(),const_cast<TTree*>(parent));
      fMajorFormulaParent->SetQuickLoad(kTRUE);
   }
   if (fMajorFormulaParent->GetTree() != parent) {
      fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
      fMajorFormulaParent->UpdateFormulaLeaves();
   }
   return fMajorFormulaParent;
}

//______________________________________________________________________________
TTreeFormula *TChainIndex::GetMinorFormulaParent(const TTree *parent)
{
   // return a pointer to the TreeFormula corresponding to the minorname in parent tree T

   if (!fMinorFormulaParent) {
      // Prevent TTreeFormula from finding any of the branches in our TTree even if it
      // is a friend of the parent TTree.
      TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
      fMinorFormulaParent = new TTreeFormula("MinorP",fMinorName.Data(),const_cast<TTree*>(parent));
      fMinorFormulaParent->SetQuickLoad(kTRUE);
   }
   if (fMinorFormulaParent->GetTree() != parent) {
      fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
      fMinorFormulaParent->UpdateFormulaLeaves();
   }

   return fMinorFormulaParent;
}

//______________________________________________________________________________
void TChainIndex::UpdateFormulaLeaves(const TTree *parent)
{
   // Updates the parent formulae.
   // Called by TChain::LoadTree when the parent chain changes it's tree.
   if (fMajorFormulaParent) {
      // Prevent TTreeFormula from finding any of the branches in our TTree even if it
      // is a friend of the parent TTree.
      TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
      if (parent) fMajorFormulaParent->SetTree((TTree*)parent);
      fMajorFormulaParent->UpdateFormulaLeaves();
   }
   if (fMinorFormulaParent) {
      if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
      fMinorFormulaParent->UpdateFormulaLeaves();
   }
}

//______________________________________________________________________________
void TChainIndex::SetTree(const TTree *T)
{
   // See TTreeIndex::SetTree.

   R__ASSERT(fTree == 0 || fTree == T || T==0);
}

<commit_msg>GetEntryNumberWith[Best]Index is not suppose to complain on stderr/stdout when the index is out of range, just return -1. (also remove debug '0' in if statement)<commit_after>// @(#)root/tree:$Id$
// Author: Marek Biskup   07/06/2005

/*************************************************************************
 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//
// A Chain Index
//
//////////////////////////////////////////////////////////////////////////

#include "TChainIndex.h"
#include "TChain.h"
#include "TTreeFormula.h"
#include "TTreeIndex.h"
#include "TFile.h"
#include "TError.h"

ClassImp(TChainIndex)

//______________________________________________________________________________
TChainIndex::TChainIndex(): TVirtualIndex()
{
// Default constructor for TChainIndex

   fTree = 0;
   fMajorFormulaParent = fMinorFormulaParent = 0;
}

//______________________________________________________________________________
TChainIndex::TChainIndex(const TTree *T, const char *majorname, const char *minorname)
           : TVirtualIndex()
{
   // Normal constructor for TChainIndex. See TTreeIndex::TTreeIndex for the description of the
   // parameters.
   // The tree must be a TChain.
   // All the index values in the first tree of the chain must be
   // less then any index value in the second one, and so on.
   // If any of those requirements isn't met the object becomes a zombie.
   // If some subtrees don't have indices the indices are created and stored inside this
   // TChainIndex.

   fTree = 0;
   fMajorFormulaParent = fMinorFormulaParent = 0;

   TChain *chain = dynamic_cast<TChain*>(const_cast<TTree*>(T));
   if (!chain) {
      MakeZombie();
      Error("TChainIndex", "Cannot create a TChainIndex."
            " The Tree passed as an argument is not a TChain");
      return;
   }

   fTree               = (TTree*)T;
   fMajorName          = majorname;
   fMinorName          = minorname;
   Int_t i = 0;

   // Go through all the trees and check if they have indeces. If not then build them.
   for (i = 0; i < chain->GetNtrees(); i++) {
      chain->LoadTree((chain->GetTreeOffset())[i]);
      TVirtualIndex *index = chain->GetTree()->GetTreeIndex();

      TChainIndexEntry entry;
      entry.fTreeIndex = 0;

      //if an index already exists, we must check if major/minorname correspond
      //to the major/minor names in this function call
      if (index) {
         if (strcmp(majorname,index->GetMajorName()) || strcmp(minorname,index->GetMinorName())) {
            MakeZombie();
            Error("TChainIndex","Tree in file %s has an index built with majorname=%s and minorname=%s",chain->GetTree()->GetCurrentFile()->GetName(),index->GetMajorName(),index->GetMinorName());
            return;
         }
      }
      if (!index) {
         chain->GetTree()->BuildIndex(majorname, minorname);
         index = chain->GetTree()->GetTreeIndex();
         chain->GetTree()->SetTreeIndex(0);
         entry.fTreeIndex = index;
      }
      if (!index || index->IsZombie() || index->GetN() == 0) {
         DeleteIndices();
         MakeZombie();
         Error("TChainIndex", "Error creating a tree index on a tree in the chain");
         return;
      }

      TTreeIndex *ti_index = dynamic_cast<TTreeIndex*>(index);
      if (ti_index == 0) {
         Error("TChainIndex", "The underlying TTree must have a TTreeIndex but has a %s.",
               index->IsA()->GetName());
         return;
      }

      entry.fMinIndexValue = ti_index->GetIndexValues()[0];
      entry.fMaxIndexValue = ti_index->GetIndexValues()[index->GetN() - 1];
      fEntries.push_back(entry);
   }

   // Check if the indices of different trees are in order. If not then return an error.
   for (i = 0; i < Int_t(fEntries.size() - 1); i++) {
      if (fEntries[i].fMaxIndexValue > fEntries[i+1].fMinIndexValue) {
         DeleteIndices();
         MakeZombie();
         Error("TChainIndex", "The indices in files of this chain aren't sorted.");
      }
   }

}

//______________________________________________________________________________
void TChainIndex::Append(const TVirtualIndex *index, Bool_t delaySort )
{
   // add an index to this chain
   // if delaySort is kFALSE (default) check if the indices of different trees are in order.
   if (index) {
      const TTreeIndex *ti_index = dynamic_cast<const TTreeIndex*>(index);
      if (ti_index == 0) {
         Error("Append", "The given index is not a TTreeIndex but a %s",
               index->IsA()->GetName());
      }

      TChainIndexEntry entry;
      entry.fTreeIndex = 0;
      entry.fMinIndexValue = ti_index->GetIndexValues()[0];
      entry.fMaxIndexValue = ti_index->GetIndexValues()[index->GetN() - 1];
      fEntries.push_back(entry);
   }

   if (!delaySort) {
      // Check if the indices of different trees are in order. If not then return an error.
      for (Int_t i = 0; i < Int_t(fEntries.size() - 1); i++) {
         if (fEntries[i].fMaxIndexValue > fEntries[i+1].fMinIndexValue) {
            DeleteIndices();
            MakeZombie();
            Error("Append", "The indices in files of this chain aren't sorted.");
         }
      }
   }
}

//______________________________________________________________________________
void TChainIndex::DeleteIndices()
{
   // Delete all the indices which were built by this object
   for (unsigned int i = 0; i < fEntries.size(); i++) {
      if (fEntries[i].fTreeIndex) {
         if (fTree->GetTree() && fTree->GetTree()->GetTreeIndex() == fEntries[i].fTreeIndex) {
            fTree->GetTree()->SetTreeIndex(0);
            SafeDelete(fEntries[i].fTreeIndex);
         }
         SafeDelete(fEntries[i].fTreeIndex);
      }
   }
}

//______________________________________________________________________________
TChainIndex::~TChainIndex()
{
   // The destructor.
   DeleteIndices();
   if (fTree && fTree->GetTreeIndex() == this)
      fTree->SetTreeIndex(0);
}

//______________________________________________________________________________
std::pair<TVirtualIndex*, Int_t> TChainIndex::GetSubTreeIndex(Int_t major, Int_t minor) const
{
   // Returns a TVirtualIndex for a tree which holds the entry with the specified
   // major and minor values and the number of that tree.
   // If the index for that tree was created by this object it's set to the tree.
   // The tree index should be later released using ReleaseSubTreeIndex();

   using namespace std;
   if (fEntries.size() == 0) {
      Warning("GetSubTreeIndex", "No subindices in the chain. The chain is probably empty");
      return make_pair(static_cast<TVirtualIndex*>(0), 0);
   }

   Long64_t indexValue = (Long64_t(major) << 31) + minor;

   if (indexValue < fEntries[0].fMinIndexValue) {
      Warning("GetSubTreeIndex", "The index value is less than the smallest index values in subtrees");
      return make_pair(static_cast<TVirtualIndex*>(0), 0);
   }

   Int_t treeNo = fEntries.size() - 1;
   for (unsigned int i = 0; i < fEntries.size() - 1; i++) {
      if (indexValue < fEntries[i+1].fMinIndexValue) {
         treeNo = i;
         break;
      }
   }
   // Double check we found the right range.
   if (indexValue > fEntries[treeNo].fMaxIndexValue) {
      return make_pair(static_cast<TVirtualIndex*>(0), 0);
   }
   TChain* chain = dynamic_cast<TChain*> (fTree);
   R__ASSERT(chain);
   chain->LoadTree(chain->GetTreeOffset()[treeNo]);
   TVirtualIndex* index =  fTree->GetTree()->GetTreeIndex();
   if (index)
      return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
   else {
      index = fEntries[treeNo].fTreeIndex;
      if (!index) {
         Warning("GetSubTreeIndex", "The tree has no index and the chain index"
                  " doesn't store an index for that tree");
         return make_pair(static_cast<TVirtualIndex*>(0), 0);
      }
      else {
         fTree->GetTree()->SetTreeIndex(index);
         return make_pair(static_cast<TVirtualIndex*>(index), treeNo);
      }
   }
}

//______________________________________________________________________________
void TChainIndex::ReleaseSubTreeIndex(TVirtualIndex* index, int treeNo) const
{
   // Releases the tree index got using GetSubTreeIndex. If the index was
   // created by this object it is removed from the current tree, so that it isn't
   // deleted in its destructor.

   if (fEntries[treeNo].fTreeIndex == index) {
      R__ASSERT(fTree->GetTree()->GetTreeIndex() == index);
      fTree->GetTree()->SetTreeIndex(0);
   }
}

//______________________________________________________________________________
Long64_t TChainIndex::GetEntryNumberFriend(const TTree *parent)
{
   // see TTreeIndex::GetEntryNumberFriend for description

   if (!parent) return -3;
   GetMajorFormulaParent(parent);
   GetMinorFormulaParent(parent);
   if (!fMajorFormulaParent || !fMinorFormulaParent) return -1;
   if (!fMajorFormulaParent->GetNdim() || !fMinorFormulaParent->GetNdim()) {
      // The Tree Index in the friend has a pair majorname,minorname
      // not available in the parent Tree T.
      // if the friend Tree has less entries than the parent, this is an error
      Long64_t pentry = parent->GetReadEntry();
      if (pentry >= fTree->GetEntries()) return -2;
      // otherwise we ignore the Tree Index and return the entry number
      // in the parent Tree.
      return pentry;
   }

   // majorname, minorname exist in the parent Tree
   // we find the current values pair majorv,minorv in the parent Tree
   Double_t majord = fMajorFormulaParent->EvalInstance();
   Double_t minord = fMinorFormulaParent->EvalInstance();
   Long64_t majorv = (Long64_t)majord;
   Long64_t minorv = (Long64_t)minord;
   // we check if this pair exist in the index.
   // if yes, we return the corresponding entry number
   // if not the function returns -1
   return fTree->GetEntryNumberWithIndex(majorv,minorv);
}

//______________________________________________________________________________
Long64_t TChainIndex::GetEntryNumberWithBestIndex(Int_t major, Int_t minor) const
{
   // See TTreeIndex::GetEntryNumberWithBestIndex for details.

   std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
   if (!indexAndNumber.first) {
      // Error("GetEntryNumberWithBestIndex","no index found");
      return -1;
   }
   else {
      Long64_t rv = indexAndNumber.first->GetEntryNumberWithBestIndex(major, minor);
      ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
      TChain* chain = dynamic_cast<TChain*> (fTree);
      R__ASSERT(chain);
      return rv + chain->GetTreeOffset()[indexAndNumber.second];
   }
}

//______________________________________________________________________________
Long64_t TChainIndex::GetEntryNumberWithIndex(Int_t major, Int_t minor) const
{
   // Returns the entry number with given index values.
   // See TTreeIndex::GetEntryNumberWithIndex for details.

   std::pair<TVirtualIndex*, Int_t> indexAndNumber = GetSubTreeIndex(major, minor);
   if (!indexAndNumber.first) {
      // Error("GetEntryNumberWithIndex","no index found");
      return -1;
   }
   else {
      Long64_t rv = indexAndNumber.first->GetEntryNumberWithIndex(major, minor);
      ReleaseSubTreeIndex(indexAndNumber.first, indexAndNumber.second);
      TChain* chain = dynamic_cast<TChain*> (fTree);
      R__ASSERT(chain);
      if (rv > 0) {
         return rv + chain->GetTreeOffset()[indexAndNumber.second];
      } else {
         return rv;
      }
   }
}

//______________________________________________________________________________
TTreeFormula *TChainIndex::GetMajorFormulaParent(const TTree *parent)
{
   // return a pointer to the TreeFormula corresponding to the majorname in parent tree T

   if (!fMajorFormulaParent) {
      TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
      fMajorFormulaParent = new TTreeFormula("MajorP",fMajorName.Data(),const_cast<TTree*>(parent));
      fMajorFormulaParent->SetQuickLoad(kTRUE);
   }
   if (fMajorFormulaParent->GetTree() != parent) {
      fMajorFormulaParent->SetTree(const_cast<TTree*>(parent));
      fMajorFormulaParent->UpdateFormulaLeaves();
   }
   return fMajorFormulaParent;
}

//______________________________________________________________________________
TTreeFormula *TChainIndex::GetMinorFormulaParent(const TTree *parent)
{
   // return a pointer to the TreeFormula corresponding to the minorname in parent tree T

   if (!fMinorFormulaParent) {
      // Prevent TTreeFormula from finding any of the branches in our TTree even if it
      // is a friend of the parent TTree.
      TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
      fMinorFormulaParent = new TTreeFormula("MinorP",fMinorName.Data(),const_cast<TTree*>(parent));
      fMinorFormulaParent->SetQuickLoad(kTRUE);
   }
   if (fMinorFormulaParent->GetTree() != parent) {
      fMinorFormulaParent->SetTree(const_cast<TTree*>(parent));
      fMinorFormulaParent->UpdateFormulaLeaves();
   }

   return fMinorFormulaParent;
}

//______________________________________________________________________________
void TChainIndex::UpdateFormulaLeaves(const TTree *parent)
{
   // Updates the parent formulae.
   // Called by TChain::LoadTree when the parent chain changes it's tree.
   if (fMajorFormulaParent) {
      // Prevent TTreeFormula from finding any of the branches in our TTree even if it
      // is a friend of the parent TTree.
      TTree::TFriendLock friendlock(fTree, TTree::kFindLeaf | TTree::kFindBranch | TTree::kGetBranch | TTree::kGetLeaf);
      if (parent) fMajorFormulaParent->SetTree((TTree*)parent);
      fMajorFormulaParent->UpdateFormulaLeaves();
   }
   if (fMinorFormulaParent) {
      if (parent) fMinorFormulaParent->SetTree((TTree*)parent);
      fMinorFormulaParent->UpdateFormulaLeaves();
   }
}

//______________________________________________________________________________
void TChainIndex::SetTree(const TTree *T)
{
   // See TTreeIndex::SetTree.

   R__ASSERT(fTree == 0 || fTree == T || T==0);
}

<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2014 Intel Corporation                                    //
//                                                                          //
// 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 "tutorial/tutorial.h"
#include "tutorial/obj_loader.h"
#include "sys/taskscheduler.h"
#include "image/image.h"

namespace embree
{
  /* name of the tutorial */
  const char* tutorialName = "tutorial03";

  /* configuration */
  static std::string g_rtcore = "";
  static size_t g_numThreads = 0;

  /* output settings */
  static size_t g_width = 512;
  static size_t g_height = 512;
  static bool g_fullscreen = false;
  static FileName outFilename = "";
  static int g_skipBenchmarkFrames = 0;
  static int g_numBenchmarkFrames = 0;
  static bool g_interactive = true;

  /* scene */
  OBJScene g_obj_scene;
  static FileName filename = "";

  static void parseCommandLine(Ref<ParseStream> cin, const FileName& path)
  {
    while (true)
    {
      std::string tag = cin->getString();
      if (tag == "") return;

      /* parse command line parameters from a file */
      else if (tag == "-c") {
        FileName file = path + cin->getFileName();
        parseCommandLine(new ParseStream(new LineCommentFilter(file, "#")), file.path());
      }

      /* load OBJ model*/
      else if (tag == "-i") {
        filename = path + cin->getFileName();
      }

      /* parse camera parameters */
      else if (tag == "-vp") g_camera.from = cin->getVec3fa();
      else if (tag == "-vi") g_camera.to = cin->getVec3fa();
      else if (tag == "-vd") g_camera.to = g_camera.from + cin->getVec3fa();
      else if (tag == "-vu") g_camera.up = cin->getVec3fa();
      else if (tag == "-fov") g_camera.fov = cin->getFloat();

      /* frame buffer size */
      else if (tag == "-size") {
        g_width = cin->getInt();
        g_height = cin->getInt();
      }

      /* full screen mode */
      else if (tag == "-fullscreen")
        g_fullscreen = true;

      /* output filename */
      else if (tag == "-o") {
        outFilename = cin->getFileName();
	g_interactive = false;
      }

      /* number of frames to render in benchmark mode */
      else if (tag == "-benchmark") {
        g_skipBenchmarkFrames = cin->getInt();
        g_numBenchmarkFrames  = cin->getInt();
	g_interactive = false;
      }

      /* rtcore configuration */
      else if (tag == "-rtcore")
        g_rtcore = cin->getString();

      /* number of threads to use */
      else if (tag == "-threads")
        g_numThreads = cin->getInt();

      /* skip unknown command line parameter */
      else {
        std::cerr << "unknown command line parameter: " << tag << " ";
        while (cin->peek() != "" && cin->peek()[0] != '-') std::cerr << cin->getString() << " ";
        std::cerr << std::endl;
      }
    }
  }

  void renderBenchmark(const FileName& fileName)
  {
    resize(g_width,g_height);
    AffineSpace3fa pixel2world = g_camera.pixel2world(g_width,g_height);

    double dt = 0.0f;
    size_t numTotalFrames = g_skipBenchmarkFrames + g_numBenchmarkFrames;
    for (size_t i=0; i<numTotalFrames; i++)
    {
      double t0 = getSeconds();
      render(0.0f,pixel2world.l.vx,pixel2world.l.vy,pixel2world.l.vz,pixel2world.p);
      double t1 = getSeconds();
      std::cout << "frame [" << i << " / " << numTotalFrames << "] ";
      std::cout << 1.0/(t1-t0) << "fps ";
      if (i < g_skipBenchmarkFrames) std::cout << "(skipped)";
      std::cout << std::endl;
      if (i >= g_skipBenchmarkFrames) dt += t1-t0;
    }
    std::cout << "frame [" << g_skipBenchmarkFrames << " - " << numTotalFrames << "] " << std::flush;
    std::cout << double(g_numBenchmarkFrames)/dt << "fps " << std::endl;
    std::cout << "BENCHMARK_RENDER " << double(g_numBenchmarkFrames)/dt << std::endl;
  }

  void renderToFile(const FileName& fileName)
  {
    resize(g_width,g_height);
    AffineSpace3fa pixel2world = g_camera.pixel2world(g_width,g_height);
    render(0.0f,pixel2world.l.vx,pixel2world.l.vy,pixel2world.l.vz,pixel2world.p);
    void* ptr = map();
    Ref<Image> image = new Image4c(g_width, g_height, (Col4c*)ptr);
    storeImage(image, fileName);
    unmap();
  }

  /* main function in embree namespace */
  int main(int argc, char** argv)
  {
    /* create stream for parsing */
    Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv));

    /* parse command line */
    parseCommandLine(stream, FileName());
    if (g_numThreads)
      g_rtcore += ",threads=" + std::stringOf(g_numThreads);
    if (g_numBenchmarkFrames)
      g_rtcore += ",benchmark=1";

    /* initialize task scheduler */
#if !defined(__EXPORT_ALL_SYMBOLS__)
    TaskScheduler::create(g_numThreads);
#endif

    /* load scene */
    if (filename.str() != "")
      loadOBJ(filename,g_obj_scene);

    /* initialize ray tracing core */
    init(g_rtcore.c_str());

    /* send model */
    set_scene(&g_obj_scene);

    /* benchmark mode */
    if (g_numBenchmarkFrames)
      renderBenchmark(outFilename);

    /* render to disk */
    if (outFilename.str() != "")
      renderToFile(outFilename);

    /* interactive mode */
    if (g_interactive) {
      initWindowState(tutorialName, g_width, g_height, g_fullscreen);
      enterWindowRunLoop();
    }

    return 0;
  }
}

int main(int argc, char** argv)
{
  try {
    return embree::main(argc, argv);
  }
  catch (const std::exception& e) {
    std::cout << "Error: " << e.what() << std::endl;
    return 1;
  }
  catch (...) {
    std::cout << "Error: unknown exception caught." << std::endl;
    return 1;
  }
}
<commit_msg>added light parsing to tutorial03<commit_after>// ======================================================================== //
// Copyright 2009-2014 Intel Corporation                                    //
//                                                                          //
// 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 "tutorial/tutorial.h"
#include "tutorial/obj_loader.h"
#include "sys/taskscheduler.h"
#include "image/image.h"

namespace embree
{
  /* name of the tutorial */
  const char* tutorialName = "tutorial03";

  /* configuration */
  static std::string g_rtcore = "";
  static size_t g_numThreads = 0;

  /* output settings */
  static size_t g_width = 512;
  static size_t g_height = 512;
  static bool g_fullscreen = false;
  static FileName outFilename = "";
  static int g_skipBenchmarkFrames = 0;
  static int g_numBenchmarkFrames = 0;
  static bool g_interactive = true;

  /* scene */
  OBJScene g_obj_scene;
  static FileName filename = "";

  static void parseCommandLine(Ref<ParseStream> cin, const FileName& path)
  {
    while (true)
    {
      std::string tag = cin->getString();
      if (tag == "") return;

      /* parse command line parameters from a file */
      else if (tag == "-c") {
        FileName file = path + cin->getFileName();
        parseCommandLine(new ParseStream(new LineCommentFilter(file, "#")), file.path());
      }

      /* load OBJ model*/
      else if (tag == "-i") {
        filename = path + cin->getFileName();
      }

      /* parse camera parameters */
      else if (tag == "-vp") g_camera.from = cin->getVec3fa();
      else if (tag == "-vi") g_camera.to = cin->getVec3fa();
      else if (tag == "-vd") g_camera.to = g_camera.from + cin->getVec3fa();
      else if (tag == "-vu") g_camera.up = cin->getVec3fa();
      else if (tag == "-fov") g_camera.fov = cin->getFloat();

      /* frame buffer size */
      else if (tag == "-size") {
        g_width = cin->getInt();
        g_height = cin->getInt();
      }

      /* full screen mode */
      else if (tag == "-fullscreen")
        g_fullscreen = true;

      /* output filename */
      else if (tag == "-o") {
        outFilename = cin->getFileName();
	g_interactive = false;
      }

      /* number of frames to render in benchmark mode */
      else if (tag == "-benchmark") {
        g_skipBenchmarkFrames = cin->getInt();
        g_numBenchmarkFrames  = cin->getInt();
	g_interactive = false;
      }

      /* rtcore configuration */
      else if (tag == "-rtcore")
        g_rtcore = cin->getString();

      /* number of threads to use */
      else if (tag == "-threads")
        g_numThreads = cin->getInt();

       /* ambient light source */
      else if (tag == "-ambientlight")
      {
        const Vec3fa L = cin->getVec3fa();
        g_obj_scene.ambientLights.push_back(OBJScene::AmbientLight(L));
      }

      /* point light source */
      else if (tag == "-pointlight")
      {
        const Vec3fa P = cin->getVec3fa();
        const Vec3fa I = cin->getVec3fa();
        g_obj_scene.pointLights.push_back(OBJScene::PointLight(P,I));
      }

      /* directional light source */
      else if (tag == "-directionallight" || tag == "-dirlight")
      {
        const Vec3fa D = cin->getVec3fa();
        const Vec3fa E = cin->getVec3fa();
        g_obj_scene.directionalLights.push_back(OBJScene::DirectionalLight(D,E));
      }

      /* distant light source */
      else if (tag == "-distantlight")
      {
        const Vec3fa D = cin->getVec3fa();
        const Vec3fa L = cin->getVec3fa();
        const float halfAngle = cin->getFloat();
        g_obj_scene.distantLights.push_back(OBJScene::DistantLight(D,L,halfAngle));
      }

      /* skip unknown command line parameter */
      else {
        std::cerr << "unknown command line parameter: " << tag << " ";
        while (cin->peek() != "" && cin->peek()[0] != '-') std::cerr << cin->getString() << " ";
        std::cerr << std::endl;
      }
    }
  }

  void renderBenchmark(const FileName& fileName)
  {
    resize(g_width,g_height);
    AffineSpace3fa pixel2world = g_camera.pixel2world(g_width,g_height);

    double dt = 0.0f;
    size_t numTotalFrames = g_skipBenchmarkFrames + g_numBenchmarkFrames;
    for (size_t i=0; i<numTotalFrames; i++)
    {
      double t0 = getSeconds();
      render(0.0f,pixel2world.l.vx,pixel2world.l.vy,pixel2world.l.vz,pixel2world.p);
      double t1 = getSeconds();
      std::cout << "frame [" << i << " / " << numTotalFrames << "] ";
      std::cout << 1.0/(t1-t0) << "fps ";
      if (i < g_skipBenchmarkFrames) std::cout << "(skipped)";
      std::cout << std::endl;
      if (i >= g_skipBenchmarkFrames) dt += t1-t0;
    }
    std::cout << "frame [" << g_skipBenchmarkFrames << " - " << numTotalFrames << "] " << std::flush;
    std::cout << double(g_numBenchmarkFrames)/dt << "fps " << std::endl;
    std::cout << "BENCHMARK_RENDER " << double(g_numBenchmarkFrames)/dt << std::endl;
  }

  void renderToFile(const FileName& fileName)
  {
    resize(g_width,g_height);
    AffineSpace3fa pixel2world = g_camera.pixel2world(g_width,g_height);
    render(0.0f,pixel2world.l.vx,pixel2world.l.vy,pixel2world.l.vz,pixel2world.p);
    void* ptr = map();
    Ref<Image> image = new Image4c(g_width, g_height, (Col4c*)ptr);
    storeImage(image, fileName);
    unmap();
  }

  /* main function in embree namespace */
  int main(int argc, char** argv)
  {
    /* create stream for parsing */
    Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv));

    /* parse command line */
    parseCommandLine(stream, FileName());
    if (g_numThreads)
      g_rtcore += ",threads=" + std::stringOf(g_numThreads);
    if (g_numBenchmarkFrames)
      g_rtcore += ",benchmark=1";

    /* initialize task scheduler */
#if !defined(__EXPORT_ALL_SYMBOLS__)
    TaskScheduler::create(g_numThreads);
#endif

    /* load scene */
    if (filename.str() != "")
      loadOBJ(filename,g_obj_scene);

    /* initialize ray tracing core */
    init(g_rtcore.c_str());

    /* send model */
    set_scene(&g_obj_scene);

    /* benchmark mode */
    if (g_numBenchmarkFrames)
      renderBenchmark(outFilename);

    /* render to disk */
    if (outFilename.str() != "")
      renderToFile(outFilename);

    /* interactive mode */
    if (g_interactive) {
      initWindowState(tutorialName, g_width, g_height, g_fullscreen);
      enterWindowRunLoop();
    }

    return 0;
  }
}

int main(int argc, char** argv)
{
  try {
    return embree::main(argc, argv);
  }
  catch (const std::exception& e) {
    std::cout << "Error: " << e.what() << std::endl;
    return 1;
  }
  catch (...) {
    std::cout << "Error: unknown exception caught." << std::endl;
    return 1;
  }
}
<|endoftext|>