<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: Mark Moll */

#include <ompl/base/SpaceInformation.h>
#include <ompl/base/spaces/SE3StateSpace.h>
#include <ompl/base/samplers/ObstacleBasedValidStateSampler.h>
#include <ompl/geometric/planners/prm/PRM.h>
#include <ompl/geometric/SimpleSetup.h>

#include <ompl/config.h>
#include <boost/thread.hpp>
#include <iostream>

namespace ob = ompl::base;
namespace og = ompl::geometric;

/// @cond IGNORE

// This is a problem-specific sampler that automatically generates valid
// states; it doesn't need to call SpaceInformation::isValid. This is an
// example of constrained sampling. If you can explicitly describe the set valid
// states and can draw samples from it, then this is typically much more
// efficient than generating random samples from the entire state space and
// checking for validity.
class MyValidStateSampler : public ob::ValidStateSampler
{
public:
    MyValidStateSampler(const ob::SpaceInformation *si) : ValidStateSampler(si)
    {
        name_ = "my sampler";
    }
    // Generate a sample in the valid part of the R^3 state space
    // Valid states satisfy the following constraints:
    // -1<= x,y,z <=1
    // if .25 <= z <= .5, then |x|>.8 and |y|>.8
    virtual bool sample(ob::State *state)
    {
        double* val = static_cast<ob::RealVectorStateSpace::StateType*>(state)->values;
        double z = rng_.uniformReal(-1,1);

        if (z>.25 && z<.5)
        {
            double x = rng_.uniformReal(0,1.8), y = rng_.uniformReal(0,.2);
            switch(rng_.uniformInt(0,3))
            {
                case 0: val[0]=x-1;  val[1]=y-1;
                case 1: val[0]=x-.8; val[1]=y+.8;
                case 2: val[0]=y-1;  val[1]=x-1;
                case 3: val[0]=y+.8; val[1]=x-.8;
            }
        }
        else
        {
            val[0] = rng_.uniformReal(-1,1);
            val[1] = rng_.uniformReal(-1,1);
        }
        val[2] = z;
        assert(si_->isValid(state));
        return true;
    }
    // We don't need this in the example below.
    virtual bool sampleNear(ob::State*, const ob::State*, const double)
    {
        throw ompl::Exception("MyValidStateSampler::sampleNear", "not implemented");
        return false;
    }
protected:
    ompl::RNG rng_;
};

/// @endcond

// this function is needed, even when we can write a sampler like the one
// above, because we need to check path segments for validity
bool isStateValid(const ob::State *state)
{
    const ob::RealVectorStateSpace::StateType& pos = *state->as<ob::RealVectorStateSpace::StateType>();
    // Let's pretend that the validity check is computationally relatively
    // expensive to emphasize the benefit of explicitly generating valid
    // samples
    boost::this_thread::sleep(ompl::time::seconds(.0005));
    // Valid states satisfy the following constraints:
    // -1<= x,y,z <=1
    // if .25 <= z <= .5, then |x|>.8 and |y|>.8
    return !(fabs(pos[0])<.8 && fabs(pos[1])<.8 && pos[2]>.25 && pos[2]<.5);
}

// return an obstacle-based sampler
ob::ValidStateSamplerPtr allocOBValidStateSampler(const ob::SpaceInformation *si)
{
    // we can perform any additional setup / configuration of a sampler here,
    // but there is nothing to tweak in case of the ObstacleBasedValidStateSampler.
    return ob::ValidStateSamplerPtr(new ob::ObstacleBasedValidStateSampler(si));
}

// return an instance of my sampler
ob::ValidStateSamplerPtr allocMyValidStateSampler(const ob::SpaceInformation *si)
{
    return ob::ValidStateSamplerPtr(new MyValidStateSampler(si));
}

void plan(int samplerIndex)
{
    // construct the state space we are planning in
    ob::StateSpacePtr space(new ob::RealVectorStateSpace(3));

    // set the bounds
    ob::RealVectorBounds bounds(3);
    bounds.setLow(-1);
    bounds.setHigh(1);
    space->as<ob::RealVectorStateSpace>()->setBounds(bounds);

    // define a simple setup class
    og::SimpleSetup ss(space);

    // set state validity checking for this space
    ss.setStateValidityChecker(boost::bind(&isStateValid, _1));

    // create a start state
    ob::ScopedState<> start(space);
    start[0] = start[1] = start[2] = 0;

    // create a goal state
    ob::ScopedState<> goal(space);
    goal[0] = goal[1] = 0.;
    goal[2] = 1;

    // set the start and goal states
    ss.setStartAndGoalStates(start, goal);

    // set sampler (optional; the default is uniform sampling)
    if (samplerIndex==1)
        // use obstacle-based sampling
        ss.getSpaceInformation()->setValidStateSamplerAllocator(allocOBValidStateSampler);
    else if (samplerIndex==2)
        // use my sampler
        ss.getSpaceInformation()->setValidStateSamplerAllocator(allocMyValidStateSampler);

    // create a planner for the defined space
    ob::PlannerPtr planner(new og::PRM(ss.getSpaceInformation()));
    ss.setPlanner(planner);

    // attempt to solve the problem within ten seconds of planning time
    ob::PlannerStatus solved = ss.solve(10.0);
    if (solved)
    {
        std::cout << "Found solution:" << std::endl;
        // print the path to screen
        ss.getSolutionPath().print(std::cout);
    }
    else
        std::cout << "No solution found" << std::endl;
}

int main(int, char **)
{
    std::cout << "Using default uniform sampler:" << std::endl;
    plan(0);
    std::cout << "\nUsing obstacle-based sampler:" << std::endl;
    plan(1);
    std::cout << "\nUsing my sampler:" << std::endl;
    plan(2);

    return 0;
}
<commit_msg>[modify] add sampleNearbyProbability()<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: Mark Moll */

#include <ompl/base/SpaceInformation.h>
#include <ompl/base/spaces/SE3StateSpace.h>
#include <ompl/base/samplers/ObstacleBasedValidStateSampler.h>
#include <ompl/geometric/planners/prm/PRM.h>
#include <ompl/geometric/SimpleSetup.h>

#include <ompl/config.h>
#include <boost/thread.hpp>
#include <iostream>

namespace ob = ompl::base;
namespace og = ompl::geometric;

/// @cond IGNORE

// This is a problem-specific sampler that automatically generates valid
// states; it doesn't need to call SpaceInformation::isValid. This is an
// example of constrained sampling. If you can explicitly describe the set valid
// states and can draw samples from it, then this is typically much more
// efficient than generating random samples from the entire state space and
// checking for validity.
class MyValidStateSampler : public ob::ValidStateSampler
{
public:
    MyValidStateSampler(const ob::SpaceInformation *si) : ValidStateSampler(si)
    {
        name_ = "my sampler";
    }
    // Generate a sample in the valid part of the R^3 state space
    // Valid states satisfy the following constraints:
    // -1<= x,y,z <=1
    // if .25 <= z <= .5, then |x|>.8 and |y|>.8
    virtual bool sample(ob::State *state)
    {
        double* val = static_cast<ob::RealVectorStateSpace::StateType*>(state)->values;
        double z = rng_.uniformReal(-1,1);

        if (z>.25 && z<.5)
        {
          double x = rng_.uniformReal(0,1.8), y = rng_.uniformReal(0,.2);
            switch(rng_.uniformInt(0,3))
            {
                case 0: val[0]=x-1;  val[1]=y-1;
                case 1: val[0]=x-.8; val[1]=y+.8;
                case 2: val[0]=y-1;  val[1]=x-1;
                case 3: val[0]=y+.8; val[1]=x-.8;
            }
        }
        else
        {
            val[0] = rng_.uniformReal(-1,1);
            val[1] = rng_.uniformReal(-1,1);
        }
        val[2] = z;
        assert(si_->isValid(state));
        return true;
    }
    // We don't need this in the example below.
    virtual bool sampleNear(ob::State*, const ob::State*, const double)
    {
        throw ompl::Exception("MyValidStateSampler::sampleNear", "not implemented");
        return false;
    }

  virtual bool sampleNearbyProbability(ob::State*, const ob::State*, const double)
  {
    std::cout << "You Reached MyvalidStateSampler sampleNearbyProbability" << std::endl;
    throw ompl::Exception("MyValidStateSampler::sampleNear", "not implemented");
    return false;
  }

protected:
    ompl::RNG rng_;
};

/// @endcond

// this function is needed, even when we can write a sampler like the one
// above, because we need to check path segments for validity
bool isStateValid(const ob::State *state)
{
    const ob::RealVectorStateSpace::StateType& pos = *state->as<ob::RealVectorStateSpace::StateType>();
    // Let's pretend that the validity check is computationally relatively
    // expensive to emphasize the benefit of explicitly generating valid
    // samples
    boost::this_thread::sleep(ompl::time::seconds(.0005));
    // Valid states satisfy the following constraints:
    // -1<= x,y,z <=1
    // if .25 <= z <= .5, then |x|>.8 and |y|>.8
    return !(fabs(pos[0])<.8 && fabs(pos[1])<.8 && pos[2]>.25 && pos[2]<.5);
}

// return an obstacle-based sampler
ob::ValidStateSamplerPtr allocOBValidStateSampler(const ob::SpaceInformation *si)
{
    // we can perform any additional setup / configuration of a sampler here,
    // but there is nothing to tweak in case of the ObstacleBasedValidStateSampler.
    return ob::ValidStateSamplerPtr(new ob::ObstacleBasedValidStateSampler(si));
}

// return an instance of my sampler
ob::ValidStateSamplerPtr allocMyValidStateSampler(const ob::SpaceInformation *si)
{
    return ob::ValidStateSamplerPtr(new MyValidStateSampler(si));
}

void plan(int samplerIndex)
{
    // construct the state space we are planning in
    ob::StateSpacePtr space(new ob::RealVectorStateSpace(3));

    // set the bounds
    ob::RealVectorBounds bounds(3);
    bounds.setLow(-1);
    bounds.setHigh(1);
    space->as<ob::RealVectorStateSpace>()->setBounds(bounds);

    // define a simple setup class
    og::SimpleSetup ss(space);

    // set state validity checking for this space
    ss.setStateValidityChecker(boost::bind(&isStateValid, _1));

    // create a start state
    ob::ScopedState<> start(space);
    start[0] = start[1] = start[2] = 0;

    // create a goal state
    ob::ScopedState<> goal(space);
    goal[0] = goal[1] = 0.;
    goal[2] = 1;

    // set the start and goal states
    ss.setStartAndGoalStates(start, goal);

    // set sampler (optional; the default is uniform sampling)
    if (samplerIndex==1)
        // use obstacle-based sampling
        ss.getSpaceInformation()->setValidStateSamplerAllocator(allocOBValidStateSampler);
    else if (samplerIndex==2)
        // use my sampler
        ss.getSpaceInformation()->setValidStateSamplerAllocator(allocMyValidStateSampler);

    // create a planner for the defined space
    ob::PlannerPtr planner(new og::PRM(ss.getSpaceInformation()));
    ss.setPlanner(planner);

    // attempt to solve the problem within ten seconds of planning time
    ob::PlannerStatus solved = ss.solve(10.0);
    if (solved)
    {
        std::cout << "Found solution:" << std::endl;
        // print the path to screen
        ss.getSolutionPath().print(std::cout);
    }
    else
        std::cout << "No solution found" << std::endl;
}

int main(int, char **)
{
    std::cout << "Using default uniform sampler:" << std::endl;
    plan(0);
    std::cout << "\nUsing obstacle-based sampler:" << std::endl;
    plan(1);
    std::cout << "\nUsing my sampler:" << std::endl;
    plan(2);

    return 0;
}
<|endoftext|>


<commit_before>/** Implementation of the pqxx::subtransaction class.
 *
 * pqxx::transaction is a nested transaction, i.e. one within a transaction
 *
 * Copyright (c) 2005-2018, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */
#include "pqxx/compiler-internal.hxx"

#include <stdexcept>

#include "pqxx/connection_base"
#include "pqxx/subtransaction"

#include "pqxx/internal/gates/transaction-subtransaction.hxx"

using namespace pqxx::internal;

pqxx::subtransaction::subtransaction(
	dbtransaction &T,
	const std::string &Name) :
  namedclass{"subtransaction", T.conn().adorn_name(Name)},
  transactionfocus{T},
  dbtransaction{T.conn(), false},
  m_parent{T}
{
}

namespace
{
using dbtransaction_ref = pqxx::dbtransaction &;
}

pqxx::subtransaction::subtransaction(
	subtransaction &T,
	const std::string &Name) :
  subtransaction{dbtransaction_ref(T), Name}
{
}

void pqxx::subtransaction::do_begin()
{
  try
  {
    direct_exec(("SAVEPOINT " + quote_name(name())).c_str());
  }
  catch (const sql_error &)
  {
    throw;
  }
}

void pqxx::subtransaction::do_commit()
{
  const int ra = m_reactivation_avoidance.get();
  m_reactivation_avoidance.clear();
  direct_exec(("RELEASE SAVEPOINT " + quote_name(name())).c_str());
  gate::transaction_subtransaction{m_parent}.add_reactivation_avoidance_count(
	ra);
}

void pqxx::subtransaction::do_abort()
{
  direct_exec(("ROLLBACK TO SAVEPOINT " + quote_name(name())).c_str());
}
<commit_msg>Work around same g++-6 issue elsewhere.<commit_after>/** Implementation of the pqxx::subtransaction class.
 *
 * pqxx::transaction is a nested transaction, i.e. one within a transaction
 *
 * Copyright (c) 2005-2018, Jeroen T. Vermeulen.
 *
 * See COPYING for copyright license.  If you did not receive a file called
 * COPYING with this source code, please notify the distributor of this mistake,
 * or contact the author.
 */
#include "pqxx/compiler-internal.hxx"

#include <stdexcept>

#include "pqxx/connection_base"
#include "pqxx/subtransaction"

#include "pqxx/internal/gates/transaction-subtransaction.hxx"

using namespace pqxx::internal;

pqxx::subtransaction::subtransaction(
	dbtransaction &T,
	const std::string &Name) :
  namedclass{"subtransaction", T.conn().adorn_name(Name)},
  transactionfocus{T},
  dbtransaction(T.conn(), false),
  m_parent{T}
{
}

namespace
{
using dbtransaction_ref = pqxx::dbtransaction &;
}

pqxx::subtransaction::subtransaction(
	subtransaction &T,
	const std::string &Name) :
  subtransaction{dbtransaction_ref(T), Name}
{
}

void pqxx::subtransaction::do_begin()
{
  try
  {
    direct_exec(("SAVEPOINT " + quote_name(name())).c_str());
  }
  catch (const sql_error &)
  {
    throw;
  }
}

void pqxx::subtransaction::do_commit()
{
  const int ra = m_reactivation_avoidance.get();
  m_reactivation_avoidance.clear();
  direct_exec(("RELEASE SAVEPOINT " + quote_name(name())).c_str());
  gate::transaction_subtransaction{m_parent}.add_reactivation_avoidance_count(
	ra);
}

void pqxx::subtransaction::do_abort()
{
  direct_exec(("ROLLBACK TO SAVEPOINT " + quote_name(name())).c_str());
}
<|endoftext|>


<commit_before>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

*******************************************************************************/

//==============================================================================
// Plugin manager
//==============================================================================

#include "plugin.h"
#include "pluginmanager.h"

//==============================================================================

#include <QCoreApplication>
#include <QDir>

//==============================================================================

namespace OpenCOR {

//==============================================================================

PluginManager::PluginManager(QCoreApplication *pApp, const bool &pGuiMode) :
    mPlugins(Plugins()),
    mLoadedPlugins(Plugins()),
    mCorePlugin(0)
{
    // Retrieve OpenCOR's plugins directory
    // Note: the plugin's directory is set in main()...

    mPluginsDir = QCoreApplication::libraryPaths().first()+QDir::separator()+pApp->applicationName();

    // Retrieve the list of plugins available for loading

    QFileInfoList fileInfoList = QDir(mPluginsDir).entryInfoList(QStringList("*"+PluginExtension),
                                                                 QDir::Files);

    QStringList fileNames = QStringList();

    foreach (const QFileInfo &file, fileInfoList)
        fileNames << QDir::toNativeSeparators(file.canonicalFilePath());

    // Determine which plugins, if any, are needed by others and which, if any,
    // are selectable

    QMap<QString, PluginInfo *> pluginsInfo = QMap<QString, PluginInfo *>();
    QMap<QString, QString> pluginsError = QMap<QString, QString>();

    QStringList neededPlugins = QStringList();
    QStringList wantedPlugins = QStringList();

    foreach (const QString &fileName, fileNames) {
        QString pluginError;
        PluginInfo *pluginInfo = Plugin::info(fileName, &pluginError);
        // Note: if there is some plugin information, then it will get owned by
        //       the plugin itself. So, it's the plugin's responsibility to
        //       delete it (see Plugin::~Plugin())...
        QString pluginName = Plugin::name(fileName);

        pluginsInfo.insert(pluginName, pluginInfo);
        pluginsError.insert(pluginName, pluginError);

        if (pluginInfo) {
            // Keep track of the plugin's full dependencies

            QStringList pluginFullDependencies = Plugin::fullDependencies(mPluginsDir, pluginName);

            pluginInfo->setFullDependencies(pluginFullDependencies);

            // Keep track of the plugin itself, should it be selectable and
            // requested by the user (if we are in GUI mode) or have CLI support
            // (if we are in CLI mode)

            if (   ( pGuiMode && pluginInfo->isSelectable() && Plugin::load(pluginName))
                || (!pGuiMode && pluginInfo->hasCliSupport())) {
                // Keep track of the plugin's dependencies

                neededPlugins << pluginsInfo.value(pluginName)->fullDependencies();

                // Also keep track of the plugin itself

                wantedPlugins << pluginName;
            }
        }
    }

    // Remove possible duplicates in our list of needed plugins

    neededPlugins.removeDuplicates();

    // We now have all our needed and wanted plugins with our needed plugins
    // nicely sorted based on their dependencies with one another. So, retrieve
    // their file name

    QStringList plugins = neededPlugins+wantedPlugins;
    QStringList pluginFileNames = QStringList();

    plugins.removeDuplicates();
    // Note: we shouldn't have to remove duplicates, but better be safe than
    //       sorry (indeed, a selectable plugin may be (wrongly) needed by
    //       another plugin)...

    foreach (const QString &plugin, plugins)
        pluginFileNames << Plugin::fileName(mPluginsDir, plugin);

    // If we are in GUI mode, then we want to know about all the plugins,
    // including the ones that are not to be loaded (so that we can refer to
    // them, in the plugins window, as either not wanted or not needed)

    if (pGuiMode) {
        pluginFileNames << fileNames;

        pluginFileNames.removeDuplicates();
    }

    // Deal with all the plugins we need and want

    foreach (const QString &pluginFileName, pluginFileNames) {
        QString pluginName = Plugin::name(pluginFileName);

        Plugin *plugin = new Plugin(pluginFileName,
                                    pluginsInfo.value(pluginName),
                                    pluginsError.value(pluginName),
                                    plugins.contains(pluginName), this);

        // Keep track of the plugin and of the Core plugin, in particular, if it
        // is loaded

        mPlugins << plugin;

        if (plugin->status() == Plugin::Loaded) {
            mLoadedPlugins << plugin;

            if (!pluginName.compare(CorePluginName))
                mCorePlugin = plugin;
        }
    }
}

//==============================================================================

PluginManager::~PluginManager()
{
    // Delete all of the plugins

    foreach (Plugin *plugin, mPlugins)
        delete plugin;
}

//==============================================================================

Plugins PluginManager::plugins() const
{
    // Return a list of all our plugins, whether loaded

    return mPlugins;
}

//==============================================================================

Plugins PluginManager::loadedPlugins() const
{
    // Return a list of our loaded plugins

    return mLoadedPlugins;
}

//==============================================================================

QString PluginManager::pluginsDir() const
{
    // Return the plugins directory

    return mPluginsDir;
}

//==============================================================================

Plugin * PluginManager::plugin(const QString &pName) const
{
    // Return the plugin, which name is the one we have been passed, if any

    foreach (Plugin *plugin, mPlugins)
        if (!pName.compare(plugin->name()))
            return plugin;

    return 0;
}

//==============================================================================

Plugin * PluginManager::corePlugin() const
{
    // Return our Core plugin

    return mCorePlugin;
}

//==============================================================================

}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<commit_msg>Some minor cleaning up [ci skip].<commit_after>/*******************************************************************************

Licensed to the OpenCOR team under one or more contributor license agreements.
See the NOTICE.txt file distributed with this work for additional information
regarding copyright ownership. The OpenCOR team licenses this file to you under
the Apache License, Version 2.0 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.

*******************************************************************************/

//==============================================================================
// Plugin manager
//==============================================================================

#include "plugin.h"
#include "pluginmanager.h"

//==============================================================================

#include <QCoreApplication>
#include <QDir>

//==============================================================================

namespace OpenCOR {

//==============================================================================

PluginManager::PluginManager(QCoreApplication *pApp, const bool &pGuiMode) :
    mPlugins(Plugins()),
    mLoadedPlugins(Plugins()),
    mCorePlugin(0)
{
    // Retrieve OpenCOR's plugins directory
    // Note: the plugin's directory is set in main()...

    mPluginsDir = QCoreApplication::libraryPaths().first()+QDir::separator()+pApp->applicationName();

    // Retrieve the list of plugins available for loading

    QFileInfoList fileInfoList = QDir(mPluginsDir).entryInfoList(QStringList("*"+PluginExtension),
                                                                 QDir::Files);

    QStringList fileNames = QStringList();

    foreach (const QFileInfo &file, fileInfoList)
        fileNames << QDir::toNativeSeparators(file.canonicalFilePath());

    // Determine which plugins, if any, are needed by others and which, if any,
    // are selectable

    QMap<QString, PluginInfo *> pluginsInfo = QMap<QString, PluginInfo *>();
    QMap<QString, QString> pluginsError = QMap<QString, QString>();

    QStringList neededPlugins = QStringList();
    QStringList wantedPlugins = QStringList();

    foreach (const QString &fileName, fileNames) {
        QString pluginError;
        PluginInfo *pluginInfo = Plugin::info(fileName, &pluginError);
        // Note: if there is some plugin information, then it will get owned by
        //       the plugin itself. So, it's the plugin's responsibility to
        //       delete it (see Plugin::~Plugin())...
        QString pluginName = Plugin::name(fileName);

        pluginsInfo.insert(pluginName, pluginInfo);
        pluginsError.insert(pluginName, pluginError);

        if (pluginInfo) {
            // Keep track of the plugin's full dependencies

            QStringList pluginFullDependencies = Plugin::fullDependencies(mPluginsDir, pluginName);

            pluginInfo->setFullDependencies(pluginFullDependencies);

            // Keep track of the plugin itself, should it be selectable and
            // requested by the user (if we are in GUI mode) or have CLI support
            // (if we are in CLI mode)

            if (   ( pGuiMode && pluginInfo->isSelectable() && Plugin::load(pluginName))
                || (!pGuiMode && pluginInfo->hasCliSupport())) {
                // Keep track of the plugin's dependencies

                neededPlugins << pluginsInfo.value(pluginName)->fullDependencies();

                // Also keep track of the plugin itself

                wantedPlugins << pluginName;
            }
        }
    }

    // Remove possible duplicates in our list of needed plugins

    neededPlugins.removeDuplicates();

    // We now have all our needed and wanted plugins with our needed plugins
    // nicely sorted based on their dependencies with one another. So, retrieve
    // their file name

    QStringList plugins = neededPlugins+wantedPlugins;
    QStringList pluginFileNames = QStringList();

    plugins.removeDuplicates();
    // Note: we shouldn't have to remove duplicates, but better be safe than
    //       sorry (indeed, a selectable plugin may be (wrongly) needed by
    //       another plugin)...

    foreach (const QString &plugin, plugins)
        pluginFileNames << Plugin::fileName(mPluginsDir, plugin);

    // If we are in GUI mode, then we want to know about all the plugins,
    // including the ones that are not to be loaded (so that we can refer to
    // them, in the plugins window, as either not wanted or not needed)

    if (pGuiMode) {
        pluginFileNames << fileNames;

        pluginFileNames.removeDuplicates();
    }

    // Deal with all the plugins we need and want

    foreach (const QString &pluginFileName, pluginFileNames) {
        QString pluginName = Plugin::name(pluginFileName);

        Plugin *plugin = new Plugin(pluginFileName,
                                    pluginsInfo.value(pluginName),
                                    pluginsError.value(pluginName),
                                    plugins.contains(pluginName), this);

        // Keep track of the plugin and of the Core plugin, in particular, if it
        // is loaded

        mPlugins << plugin;

        if (plugin->status() == Plugin::Loaded) {
            mLoadedPlugins << plugin;

            if (!pluginName.compare(CorePluginName))
                mCorePlugin = plugin;
        }
    }
}

//==============================================================================

PluginManager::~PluginManager()
{
    // Delete all of the plugins

    foreach (Plugin *plugin, mPlugins)
        delete plugin;
}

//==============================================================================

Plugins PluginManager::plugins() const
{
    // Return a list of all our plugins, whether loaded

    return mPlugins;
}

//==============================================================================

Plugins PluginManager::loadedPlugins() const
{
    // Return a list of our loaded plugins

    return mLoadedPlugins;
}

//==============================================================================

QString PluginManager::pluginsDir() const
{
    // Return the plugins directory

    return mPluginsDir;
}

//==============================================================================

Plugin * PluginManager::plugin(const QString &pName) const
{
    // Return the plugin, if any, which name is the one we have been passed

    foreach (Plugin *plugin, mPlugins)
        if (!pName.compare(plugin->name()))
            return plugin;

    return 0;
}

//==============================================================================

Plugin * PluginManager::corePlugin() const
{
    // Return our Core plugin

    return mCorePlugin;
}

//==============================================================================

}   // namespace OpenCOR

//==============================================================================
// End of file
//==============================================================================
<|endoftext|>


<commit_before>/*

Copyright (c) 2008, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_BITFIELD_HPP_INCLUDED
#define TORRENT_BITFIELD_HPP_INCLUDED

#include "libtorrent/assert.hpp"
#include "libtorrent/config.hpp"
#include <cstring> // for memset and memcpy

namespace libtorrent
{
	struct TORRENT_EXPORT bitfield
	{
		bitfield(): m_bytes(0), m_size(0), m_own(false) {}
		bitfield(int bits): m_bytes(0), m_size(0)
		{ resize(bits); }
		bitfield(int bits, bool val): m_bytes(0), m_size(0)
		{ resize(bits, val); }
		bitfield(char const* b, int bits): m_bytes(0), m_size(0)
		{ assign(b, bits); }
		bitfield(bitfield const& rhs): m_bytes(0), m_size(0), m_own(false)
		{ assign(rhs.bytes(), rhs.size()); }

		void borrow_bytes(char* b, int bits)
		{
			dealloc();
			m_bytes = (unsigned char*)b;
			m_size = bits;
			m_own = false;
		}
		~bitfield() { dealloc(); }

		void assign(char const* b, int bits)
		{ resize(bits); std::memcpy(m_bytes, b, (bits + 7) / 8); clear_trailing_bits(); }

		bool operator[](int index) const
		{ return get_bit(index); }

		bool get_bit(int index) const
		{
			TORRENT_ASSERT(index >= 0);
			TORRENT_ASSERT(index < m_size);
			return (m_bytes[index / 8] & (0x80 >> (index & 7))) != 0;
		}

		void clear_bit(int index)
		{
			TORRENT_ASSERT(index >= 0);
			TORRENT_ASSERT(index < m_size);
			m_bytes[index / 8] &= ~(0x80 >> (index & 7));
		}

		void set_bit(int index)
		{
			TORRENT_ASSERT(index >= 0);
			TORRENT_ASSERT(index < m_size);
			m_bytes[index / 8] |= (0x80 >> (index & 7));
		}

		std::size_t size() const { return m_size; }
		bool empty() const { return m_size == 0; }

		char const* bytes() const { return (char*)m_bytes; }

		bitfield& operator=(bitfield const& rhs)
		{
			assign(rhs.bytes(), rhs.size());
			return *this;
		}

		int count() const
		{
			// 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111,
			// 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111
			const static char num_bits[] =
			{
				0, 1, 1, 2, 1, 2, 2, 3,
				1, 2, 2, 3, 2, 3, 3, 4
			};

			int ret = 0;
			const int num_bytes = m_size / 8;
			for (int i = 0; i < num_bytes; ++i)
			{
				ret += num_bits[m_bytes[i] & 0xf] + num_bits[m_bytes[i] >> 4];
			}

			int rest = m_size - num_bytes * 8;
			for (int i = 0; i < rest; ++i)
			{
				ret += (m_bytes[num_bytes] >> (7-i)) & 1;
			}
			TORRENT_ASSERT(ret <= m_size);
			TORRENT_ASSERT(ret >= 0);
			return ret;
		}

		struct const_iterator
		{
		friend struct bitfield;

			typedef bool value_type;
			typedef ptrdiff_t difference_type;
			typedef bool const* pointer;
			typedef bool& reference;
			typedef std::forward_iterator_tag iterator_category;

			bool operator*() { return (*byte & bit) != 0; }
			const_iterator& operator++() { inc(); return *this; }
			const_iterator operator++(int)
			{ const_iterator ret(*this); inc(); return ret; }
			const_iterator& operator--() { dec(); return *this; }
			const_iterator operator--(int)
			{ const_iterator ret(*this); dec(); return ret; }

			const_iterator(): byte(0), bit(0x80) {}
			bool operator==(const_iterator const& rhs) const
			{ return byte == rhs.byte && bit == rhs.bit; }

			bool operator!=(const_iterator const& rhs) const
			{ return byte != rhs.byte || bit != rhs.bit; }

		private:
			void inc()
			{
				TORRENT_ASSERT(byte);
				if (bit == 0x01)
				{
					bit = 0x80;
					++byte;
				}
				else
				{
					bit >>= 1;
				}
			}
			void dec()
			{
				TORRENT_ASSERT(byte);
				if (bit == 0x80)
				{
					bit = 0x01;
					--byte;
				}
				else
				{
					bit <<= 1;
				}
			}
			const_iterator(unsigned char const* ptr, int offset)
				: byte(ptr), bit(0x80 >> offset) {}
			unsigned char const* byte;
			int bit;
		};

		const_iterator begin() const { return const_iterator(m_bytes, 0); }
		const_iterator end() const { return const_iterator(m_bytes + m_size / 8, m_size & 7); }

		void resize(int bits, bool val)
		{
			int s = m_size;
			int b = m_size & 7;
			resize(bits);
			if (s >= m_size) return;
			int old_size_bytes = (s + 7) / 8;
			int new_size_bytes = (m_size + 7) / 8;
			if (val)
			{
				if (old_size_bytes && b) m_bytes[old_size_bytes - 1] |= (0xff >> b);
				if (old_size_bytes < new_size_bytes)
					std::memset(m_bytes + old_size_bytes, 0xff, new_size_bytes - old_size_bytes);
				clear_trailing_bits();
			}
			else
			{
				if (old_size_bytes < new_size_bytes)
					std::memset(m_bytes + old_size_bytes, 0x00, new_size_bytes - old_size_bytes);
			}
		}

		void set_all()
		{
			std::memset(m_bytes, 0xff, (m_size + 7) / 8);
			clear_trailing_bits();
		}

		void clear_all()
		{
			std::memset(m_bytes, 0x00, (m_size + 7) / 8);
		}

		void resize(int bits)
		{
			const int b = (bits + 7) / 8;
			if (m_bytes)
			{
				if (m_own)
				{
					m_bytes = (unsigned char*)std::realloc(m_bytes, b);
					m_own = true;
				}
				else if (bits > m_size)
				{
					unsigned char* tmp = (unsigned char*)std::malloc(b);
					std::memcpy(tmp, m_bytes, (std::min)(int(m_size + 7)/ 8, b));
					m_bytes = tmp;
					m_own = true;
				}
			}
			else
			{
				m_bytes = (unsigned char*)std::malloc(b);
				m_own = true;
			}
			m_size = bits;
			clear_trailing_bits();
		}

		void free() { dealloc(); m_size = 0; }

	private:

		void clear_trailing_bits()
		{
			// clear the tail bits in the last byte
			if (m_size & 7) m_bytes[(m_size + 7) / 8 - 1] &= 0xff << (8 - (m_size & 7));
		}

		void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; }
		unsigned char* m_bytes;
		int m_size:31; // in bits
		bool m_own:1;
	};

}

#endif // TORRENT_BITFIELD_HPP_INCLUDED

<commit_msg>added missing include<commit_after>/*

Copyright (c) 2008, Arvid Norberg
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 author 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.

*/

#ifndef TORRENT_BITFIELD_HPP_INCLUDED
#define TORRENT_BITFIELD_HPP_INCLUDED

#include "libtorrent/assert.hpp"
#include "libtorrent/config.hpp"
#include <cstring> // for memset and memcpy
#include <cstdlib> // for malloc, free and realloc

namespace libtorrent
{
	struct TORRENT_EXPORT bitfield
	{
		bitfield(): m_bytes(0), m_size(0), m_own(false) {}
		bitfield(int bits): m_bytes(0), m_size(0)
		{ resize(bits); }
		bitfield(int bits, bool val): m_bytes(0), m_size(0)
		{ resize(bits, val); }
		bitfield(char const* b, int bits): m_bytes(0), m_size(0)
		{ assign(b, bits); }
		bitfield(bitfield const& rhs): m_bytes(0), m_size(0), m_own(false)
		{ assign(rhs.bytes(), rhs.size()); }

		void borrow_bytes(char* b, int bits)
		{
			dealloc();
			m_bytes = (unsigned char*)b;
			m_size = bits;
			m_own = false;
		}
		~bitfield() { dealloc(); }

		void assign(char const* b, int bits)
		{ resize(bits); std::memcpy(m_bytes, b, (bits + 7) / 8); clear_trailing_bits(); }

		bool operator[](int index) const
		{ return get_bit(index); }

		bool get_bit(int index) const
		{
			TORRENT_ASSERT(index >= 0);
			TORRENT_ASSERT(index < m_size);
			return (m_bytes[index / 8] & (0x80 >> (index & 7))) != 0;
		}

		void clear_bit(int index)
		{
			TORRENT_ASSERT(index >= 0);
			TORRENT_ASSERT(index < m_size);
			m_bytes[index / 8] &= ~(0x80 >> (index & 7));
		}

		void set_bit(int index)
		{
			TORRENT_ASSERT(index >= 0);
			TORRENT_ASSERT(index < m_size);
			m_bytes[index / 8] |= (0x80 >> (index & 7));
		}

		std::size_t size() const { return m_size; }
		bool empty() const { return m_size == 0; }

		char const* bytes() const { return (char*)m_bytes; }

		bitfield& operator=(bitfield const& rhs)
		{
			assign(rhs.bytes(), rhs.size());
			return *this;
		}

		int count() const
		{
			// 0000, 0001, 0010, 0011, 0100, 0101, 0110, 0111,
			// 1000, 1001, 1010, 1011, 1100, 1101, 1110, 1111
			const static char num_bits[] =
			{
				0, 1, 1, 2, 1, 2, 2, 3,
				1, 2, 2, 3, 2, 3, 3, 4
			};

			int ret = 0;
			const int num_bytes = m_size / 8;
			for (int i = 0; i < num_bytes; ++i)
			{
				ret += num_bits[m_bytes[i] & 0xf] + num_bits[m_bytes[i] >> 4];
			}

			int rest = m_size - num_bytes * 8;
			for (int i = 0; i < rest; ++i)
			{
				ret += (m_bytes[num_bytes] >> (7-i)) & 1;
			}
			TORRENT_ASSERT(ret <= m_size);
			TORRENT_ASSERT(ret >= 0);
			return ret;
		}

		struct const_iterator
		{
		friend struct bitfield;

			typedef bool value_type;
			typedef ptrdiff_t difference_type;
			typedef bool const* pointer;
			typedef bool& reference;
			typedef std::forward_iterator_tag iterator_category;

			bool operator*() { return (*byte & bit) != 0; }
			const_iterator& operator++() { inc(); return *this; }
			const_iterator operator++(int)
			{ const_iterator ret(*this); inc(); return ret; }
			const_iterator& operator--() { dec(); return *this; }
			const_iterator operator--(int)
			{ const_iterator ret(*this); dec(); return ret; }

			const_iterator(): byte(0), bit(0x80) {}
			bool operator==(const_iterator const& rhs) const
			{ return byte == rhs.byte && bit == rhs.bit; }

			bool operator!=(const_iterator const& rhs) const
			{ return byte != rhs.byte || bit != rhs.bit; }

		private:
			void inc()
			{
				TORRENT_ASSERT(byte);
				if (bit == 0x01)
				{
					bit = 0x80;
					++byte;
				}
				else
				{
					bit >>= 1;
				}
			}
			void dec()
			{
				TORRENT_ASSERT(byte);
				if (bit == 0x80)
				{
					bit = 0x01;
					--byte;
				}
				else
				{
					bit <<= 1;
				}
			}
			const_iterator(unsigned char const* ptr, int offset)
				: byte(ptr), bit(0x80 >> offset) {}
			unsigned char const* byte;
			int bit;
		};

		const_iterator begin() const { return const_iterator(m_bytes, 0); }
		const_iterator end() const { return const_iterator(m_bytes + m_size / 8, m_size & 7); }

		void resize(int bits, bool val)
		{
			int s = m_size;
			int b = m_size & 7;
			resize(bits);
			if (s >= m_size) return;
			int old_size_bytes = (s + 7) / 8;
			int new_size_bytes = (m_size + 7) / 8;
			if (val)
			{
				if (old_size_bytes && b) m_bytes[old_size_bytes - 1] |= (0xff >> b);
				if (old_size_bytes < new_size_bytes)
					std::memset(m_bytes + old_size_bytes, 0xff, new_size_bytes - old_size_bytes);
				clear_trailing_bits();
			}
			else
			{
				if (old_size_bytes < new_size_bytes)
					std::memset(m_bytes + old_size_bytes, 0x00, new_size_bytes - old_size_bytes);
			}
		}

		void set_all()
		{
			std::memset(m_bytes, 0xff, (m_size + 7) / 8);
			clear_trailing_bits();
		}

		void clear_all()
		{
			std::memset(m_bytes, 0x00, (m_size + 7) / 8);
		}

		void resize(int bits)
		{
			const int b = (bits + 7) / 8;
			if (m_bytes)
			{
				if (m_own)
				{
					m_bytes = (unsigned char*)std::realloc(m_bytes, b);
					m_own = true;
				}
				else if (bits > m_size)
				{
					unsigned char* tmp = (unsigned char*)std::malloc(b);
					std::memcpy(tmp, m_bytes, (std::min)(int(m_size + 7)/ 8, b));
					m_bytes = tmp;
					m_own = true;
				}
			}
			else
			{
				m_bytes = (unsigned char*)std::malloc(b);
				m_own = true;
			}
			m_size = bits;
			clear_trailing_bits();
		}

		void free() { dealloc(); m_size = 0; }

	private:

		void clear_trailing_bits()
		{
			// clear the tail bits in the last byte
			if (m_size & 7) m_bytes[(m_size + 7) / 8 - 1] &= 0xff << (8 - (m_size & 7));
		}

		void dealloc() { if (m_own) std::free(m_bytes); m_bytes = 0; }
		unsigned char* m_bytes;
		int m_size:31; // in bits
		bool m_own:1;
	};

}

#endif // TORRENT_BITFIELD_HPP_INCLUDED

<|endoftext|>


<commit_before>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014-2018                                                               *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#include <openspace/rendering/transferfunction.h>

#include <ghoul/filesystem/cachemanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/texture.h>

#include <cstring>
#include <iterator>
#include <fstream>
#include <string>

#include <iostream>

namespace {
    constexpr const char* _loggerCat = "TransferFunction";

    // @TODO Replace with Filesystem::File extension
    bool hasExtension(const std::string& filepath, const std::string& extension) {
        std::string ending = "." + extension;
        if (filepath.length() > ending.length()) {
            return (0 == filepath.compare(
                filepath.length() - ending.length(),
                ending.length(), ending));
        } else {
            return false;
        }
    }
} // namespace

namespace openspace {

TransferFunction::TransferFunction(const std::string& filepath,
                                   TfChangedCallback tfChangedCallback)
    : _filepath(filepath)
{
    setPath(filepath);
    setCallback(tfChangedCallback);
}

void TransferFunction::setPath(const std::string& filepath) {
    if (_file) {
        _file = nullptr;
    }
    std::string f = absPath(filepath);
    if (!FileSys.fileExists(f)) {
        LERROR("Could not find transfer function file.");
        _file = nullptr;
        return;
    }
    _filepath = f;
    _file = std::make_unique<ghoul::filesystem::File>(
        _filepath,
        ghoul::filesystem::File::RawPath::Yes
    );
    _needsUpdate = true;
    _file->setCallback([this](const ghoul::filesystem::File&) {
        _needsUpdate = true;
    });
}

ghoul::opengl::Texture& TransferFunction::getTexture() {
    ghoul_assert(_texture != nullptr, "Transfer function is null");
    update();
    return *_texture.get();
}

void TransferFunction::update() {
  /*  if (_needsUpdate) {
        if (hasExtension(_filepath, "txt")) {
            setTextureFromTxt();
        } else {
            setTextureFromImage();
        }
        _texture->uploadTexture();
        _needsUpdate = false;
        if (_tfChangedCallback) {
            _tfChangedCallback(*this);
        }
    }*/
}

void TransferFunction::setCallback(TfChangedCallback callback) {
    _tfChangedCallback = std::move(callback);
}

void TransferFunction::setTextureFromTxt(std::shared_ptr<ghoul::opengl::Texture> ptr) {
    std::ifstream in;
    in.open(_filepath.c_str());

    if (!in.is_open()) {
        throw ghoul::FileNotFoundError(_filepath);
    }

    int width = 512;
    float lower = 0.0f;
    float upper = 1.0f;

    std::vector<MappingKey> mappingKeys;

    std::string line;

    while (std::getline(in, line)) {
        std::istringstream iss(line);
        std::string key;
        iss >> key;

        if(key == "width") {
            iss >> width;
        } else if(key == "lower") {
            iss >> lower;
            lower = glm::clamp(lower, 0.0f, 1.0f);
        } else if(key == "upper") {
            iss >> upper;
            upper = glm::clamp(upper, lower, 1.0f);
        } else if(key == "mappingkey") {
            float intensity;
            glm::vec4 rgba = glm::vec4(0.0f);
            iss >> intensity;
            for(int i = 0; i < 4; ++i) {
                iss >> rgba[i];
            }
            mappingKeys.push_back({intensity, rgba});
        }
    }
    in.close();

    if (mappingKeys.size() < 1) {
        return;
    }

    if (mappingKeys.front().position > lower) {
        mappingKeys.insert(mappingKeys.begin(), {lower,mappingKeys.front().color});
    }

    if (mappingKeys.back().position < upper) {
        mappingKeys.push_back({upper,mappingKeys.back().color});
    }

    // allocate new float array with zeros
    float* transferFunction = new float[width * 4];
    for (int i = 0; i < 4 * width; ++i) {
        transferFunction[i] = 0.f;
    }

    size_t lowerIndex = static_cast<size_t>(floorf(lower * static_cast<float>(width-1)));
    size_t upperIndex = static_cast<size_t>(floorf(upper * static_cast<float>(width-1)));

    auto prevKey = mappingKeys.begin();
    auto currentKey = prevKey + 1;
    auto lastKey = mappingKeys.end() -1;

    for (size_t i = lowerIndex; i <= upperIndex; ++i) {
        float fpos = static_cast<float>(i) / static_cast<float>(width-1);
        if (fpos > currentKey->position) {
            prevKey = currentKey;
            currentKey++;
            if (currentKey == mappingKeys.end()) {
                currentKey = lastKey;
            }
        }

        float dist = fpos - prevKey->position;
        float weight = dist / (currentKey->position - prevKey->position);

        for (size_t channel = 0; channel < 4; ++channel) {
            size_t position = 4 * i + channel;
            // Interpolate linearly between prev and next mapping key
            float value = (prevKey->color[channel] * (1.f - weight) +
                          currentKey->color[channel] * weight) / 255.f;
            if (channel < 3) {
                // Premultiply with alpha
                value *= (prevKey->color[3] * (1.f - weight) +
                         currentKey->color[3] * weight) / 255.f;
            }
            transferFunction[position] = value;
        }
    }

    // no need to deallocate transferFunction. Ownership is transferred to the Texture.

    _texture = std::make_unique<ghoul::opengl::Texture>(
        transferFunction,
        glm::size3_t(width, 1, 1),
        ghoul::opengl::Texture::Format::RGBA,
        GL_RGBA,
        GL_FLOAT,
        ghoul::opengl::Texture::FilterMode::Linear,
        ghoul::opengl::Texture::WrappingMode::ClampToEdge
    );
}

void TransferFunction::setTextureFromImage() {
    _texture = ghoul::io::TextureReader::ref().loadTexture(_filepath);
    _texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToEdge);
}

glm::vec4 TransferFunction::sample(size_t offset) {
    if (!_texture) {
        return glm::vec4(0.f);
    }

    int nPixels = _texture->width();

    // Clamp to range.
    if (offset >= nPixels) {
        offset = nPixels - 1;
    }
    if (offset < 0) {
        offset = 0;
    }

    return _texture->texelAsFloat(offset);
}

size_t TransferFunction::width() {
    update();
    return _texture->width();
}

void TransferFunction::bind() {
    update();
    _texture->bind();
}
}
<commit_msg>Add missing include<commit_after>/*****************************************************************************************
 *                                                                                *
 * OpenSpace                                                                             *
 *                                                                                *
 * Copyright (c) 2014-2018                                                               *
 *                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#include <openspace/rendering/transferfunction.h>

#include <ghoul/filesystem/cachemanager.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/filesystem/file.h>
#include <ghoul/io/texture/texturereader.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/opengl/texture.h>

#include <cstring>
#include <iterator>
#include <fstream>
#include <string>

#include <iostream>

namespace {
    constexpr const char* _loggerCat = "TransferFunction";

    // @TODO Replace with Filesystem::File extension
    bool hasExtension(const std::string& filepath, const std::string& extension) {
        std::string ending = "." + extension;
        if (filepath.length() > ending.length()) {
            return (0 == filepath.compare(
                filepath.length() - ending.length(),
                ending.length(), ending));
        } else {
            return false;
        }
    }
} // namespace

namespace openspace {

TransferFunction::TransferFunction(const std::string& filepath,
                                   TfChangedCallback tfChangedCallback)
    : _filepath(filepath)
{
    setPath(filepath);
    setCallback(tfChangedCallback);
}

void TransferFunction::setPath(const std::string& filepath) {
    if (_file) {
        _file = nullptr;
    }
    std::string f = absPath(filepath);
    if (!FileSys.fileExists(f)) {
        LERROR("Could not find transfer function file.");
        _file = nullptr;
        return;
    }
    _filepath = f;
    _file = std::make_unique<ghoul::filesystem::File>(
        _filepath,
        ghoul::filesystem::File::RawPath::Yes
    );
    _needsUpdate = true;
    _file->setCallback([this](const ghoul::filesystem::File&) {
        _needsUpdate = true;
    });
}

ghoul::opengl::Texture& TransferFunction::getTexture() {
    ghoul_assert(_texture != nullptr, "Transfer function is null");
    update();
    return *_texture.get();
}

void TransferFunction::update() {
  /*  if (_needsUpdate) {
        if (hasExtension(_filepath, "txt")) {
            setTextureFromTxt();
        } else {
            setTextureFromImage();
        }
        _texture->uploadTexture();
        _needsUpdate = false;
        if (_tfChangedCallback) {
            _tfChangedCallback(*this);
        }
    }*/
}

void TransferFunction::setCallback(TfChangedCallback callback) {
    _tfChangedCallback = std::move(callback);
}

void TransferFunction::setTextureFromTxt(std::shared_ptr<ghoul::opengl::Texture> ptr) {
    std::ifstream in;
    in.open(_filepath.c_str());

    if (!in.is_open()) {
        throw ghoul::FileNotFoundError(_filepath);
    }

    int width = 512;
    float lower = 0.0f;
    float upper = 1.0f;

    std::vector<MappingKey> mappingKeys;

    std::string line;

    while (std::getline(in, line)) {
        std::istringstream iss(line);
        std::string key;
        iss >> key;

        if(key == "width") {
            iss >> width;
        } else if(key == "lower") {
            iss >> lower;
            lower = glm::clamp(lower, 0.0f, 1.0f);
        } else if(key == "upper") {
            iss >> upper;
            upper = glm::clamp(upper, lower, 1.0f);
        } else if(key == "mappingkey") {
            float intensity;
            glm::vec4 rgba = glm::vec4(0.0f);
            iss >> intensity;
            for(int i = 0; i < 4; ++i) {
                iss >> rgba[i];
            }
            mappingKeys.push_back({intensity, rgba});
        }
    }
    in.close();

    if (mappingKeys.size() < 1) {
        return;
    }

    if (mappingKeys.front().position > lower) {
        mappingKeys.insert(mappingKeys.begin(), {lower,mappingKeys.front().color});
    }

    if (mappingKeys.back().position < upper) {
        mappingKeys.push_back({upper,mappingKeys.back().color});
    }

    // allocate new float array with zeros
    float* transferFunction = new float[width * 4];
    for (int i = 0; i < 4 * width; ++i) {
        transferFunction[i] = 0.f;
    }

    size_t lowerIndex = static_cast<size_t>(floorf(lower * static_cast<float>(width-1)));
    size_t upperIndex = static_cast<size_t>(floorf(upper * static_cast<float>(width-1)));

    auto prevKey = mappingKeys.begin();
    auto currentKey = prevKey + 1;
    auto lastKey = mappingKeys.end() -1;

    for (size_t i = lowerIndex; i <= upperIndex; ++i) {
        float fpos = static_cast<float>(i) / static_cast<float>(width-1);
        if (fpos > currentKey->position) {
            prevKey = currentKey;
            currentKey++;
            if (currentKey == mappingKeys.end()) {
                currentKey = lastKey;
            }
        }

        float dist = fpos - prevKey->position;
        float weight = dist / (currentKey->position - prevKey->position);

        for (size_t channel = 0; channel < 4; ++channel) {
            size_t position = 4 * i + channel;
            // Interpolate linearly between prev and next mapping key
            float value = (prevKey->color[channel] * (1.f - weight) +
                          currentKey->color[channel] * weight) / 255.f;
            if (channel < 3) {
                // Premultiply with alpha
                value *= (prevKey->color[3] * (1.f - weight) +
                         currentKey->color[3] * weight) / 255.f;
            }
            transferFunction[position] = value;
        }
    }

    // no need to deallocate transferFunction. Ownership is transferred to the Texture.

    _texture = std::make_unique<ghoul::opengl::Texture>(
        transferFunction,
        glm::size3_t(width, 1, 1),
        ghoul::opengl::Texture::Format::RGBA,
        GL_RGBA,
        GL_FLOAT,
        ghoul::opengl::Texture::FilterMode::Linear,
        ghoul::opengl::Texture::WrappingMode::ClampToEdge
    );
}

void TransferFunction::setTextureFromImage() {
    _texture = ghoul::io::TextureReader::ref().loadTexture(_filepath);
    _texture->setWrapping(ghoul::opengl::Texture::WrappingMode::ClampToEdge);
}

glm::vec4 TransferFunction::sample(size_t offset) {
    if (!_texture) {
        return glm::vec4(0.f);
    }

    int nPixels = _texture->width();

    // Clamp to range.
    if (offset >= nPixels) {
        offset = nPixels - 1;
    }
    if (offset < 0) {
        offset = 0;
    }

    return _texture->texelAsFloat(offset);
}

size_t TransferFunction::width() {
    update();
    return _texture->width();
}

void TransferFunction::bind() {
    update();
    _texture->bind();
}
}
<|endoftext|>


<commit_before>#include "path.hpp"
#include "path_posix.hpp"
#include "ifilereg.hpp"
#include "system_error.hpp"
#include <errno.h>
#include <sys/stat.h>

struct path_dir {
    const char *path;
    unsigned len;
};

static path_dir gDirs[2];

#if defined(__APPLE__)
#include "sys/autocf_osx.hpp"
#include <CoreFoundation/CFBundle.h>

static void getExeDir()
{
    std::string resources, bundle;
    CFBundleRef main = CFBundleGetMainBundle();
    AutoCF<CFURLRef> bundleURL(CFBundleCopyBundleURL(main));
    char buf[1024]; // FIXME maximum?
    bool r;
    r = CFURLGetFileSystemRepresentation(
        bundleURL, true, reinterpret_cast<UInt8 *>(buf), sizeof(buf));
    if (!r)
        return;
    unsigned l = strlen(buf);
    while (l && buf[l - 1] != '/')
        l--;
    if (l <= 1)
        return;
    l--;
    char *ptr = (char *) malloc(l);
    if (!ptr)
        abort();
    memcpy(ptr, buf, l);
    gDirs[0].path = ptr;
    gDirs[0].len = l;
}

#elif defined(__linux__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void getExeDir()
{
    char buf[512];
    ssize_t sz = readlink("/proc/self/exe", buf, sizeof(buf));
    if (sz > 0) {
        unsigned int p = sz;
        while (p && buf[p - 1] != '/')
            --p;
        if (p) {
            if (p > 1)
                --p;
            char *ptr = (char *) malloc(p);
            if (!ptr)
                abort();
            memcpy(ptr, buf, p);
            gDirs[0].path = ptr;
            gDirs[0].len = p;
        }
    }
}

#else

#error "Can't find executable on this platform"

#endif

void pathInit(const char *altpath)
{
    getExeDir();
    if (altpath) {
        gDirs[1].path = altpath;
        gDirs[1].len = strlen(altpath);
    }
}

IFile *Path::openIFile(std::string const &path)
{
    std::string abspath;
    for (int i = 0; i < 2; ++i) {
        if (!gDirs[i].path)
            continue;
        abspath = std::string(gDirs[i].path, gDirs[i].len);
        abspath += '/';
        abspath += path;
        try {
            return IFileReg::open(abspath);
        } catch (system_error &e) {
            if (e.code() != ENOENT)
                throw;
        }
    }
    throw system_error(ENOENT);
}

FILE *Path::openOFile(std::string const &path)
{
    if (!gDirs[0].path)
        abort();
    char buf[512];
    if (gDirs[0].len > 510 || path.size() > 510 - gDirs[0].len) {
        fputs("File name too long\n", stderr);
        abort();
    }
    int i = 0, r;
    memcpy(buf, gDirs[0].path, gDirs[0].len);
    i += gDirs[0].len;
    buf[i++] = '/';
    std::string::const_iterator p = path.begin(), e = path.end();
    for (; p != e; ++p) {
        if (*p == '/') {
            buf[i] = '\0';
            r = mkdir(buf, 0777);
            if (r) {
                perror("mkdir");
                abort();
            }
        }
        buf[i++] = *p;
    }
    buf[i] = '\0';
    FILE *f = fopen(buf, "w");
    if (!f) {
        perror("fopen");
        abort();
    }
    return f;
}
<commit_msg>Fix error handling in Path::openOFile<commit_after>#include "path.hpp"
#include "path_posix.hpp"
#include "ifilereg.hpp"
#include "system_error.hpp"
#include <errno.h>
#include <sys/stat.h>

struct path_dir {
    const char *path;
    unsigned len;
};

static path_dir gDirs[2];

#if defined(__APPLE__)
#include "sys/autocf_osx.hpp"
#include <CoreFoundation/CFBundle.h>

static void getExeDir()
{
    std::string resources, bundle;
    CFBundleRef main = CFBundleGetMainBundle();
    AutoCF<CFURLRef> bundleURL(CFBundleCopyBundleURL(main));
    char buf[1024]; // FIXME maximum?
    bool r;
    r = CFURLGetFileSystemRepresentation(
        bundleURL, true, reinterpret_cast<UInt8 *>(buf), sizeof(buf));
    if (!r)
        return;
    unsigned l = strlen(buf);
    while (l && buf[l - 1] != '/')
        l--;
    if (l <= 1)
        return;
    l--;
    char *ptr = (char *) malloc(l);
    if (!ptr)
        abort();
    memcpy(ptr, buf, l);
    gDirs[0].path = ptr;
    gDirs[0].len = l;
}

#elif defined(__linux__)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static void getExeDir()
{
    char buf[512];
    ssize_t sz = readlink("/proc/self/exe", buf, sizeof(buf));
    if (sz > 0) {
        unsigned int p = sz;
        while (p && buf[p - 1] != '/')
            --p;
        if (p) {
            if (p > 1)
                --p;
            char *ptr = (char *) malloc(p);
            if (!ptr)
                abort();
            memcpy(ptr, buf, p);
            gDirs[0].path = ptr;
            gDirs[0].len = p;
        }
    }
}

#else

#error "Can't find executable on this platform"

#endif

void pathInit(const char *altpath)
{
    getExeDir();
    if (altpath) {
        gDirs[1].path = altpath;
        gDirs[1].len = strlen(altpath);
    }
}

IFile *Path::openIFile(std::string const &path)
{
    std::string abspath;
    for (int i = 0; i < 2; ++i) {
        if (!gDirs[i].path)
            continue;
        abspath = std::string(gDirs[i].path, gDirs[i].len);
        abspath += '/';
        abspath += path;
        try {
            return IFileReg::open(abspath);
        } catch (system_error &e) {
            if (e.code() != ENOENT)
                throw;
        }
    }
    throw system_error(ENOENT);
}

FILE *Path::openOFile(std::string const &path)
{
    if (!gDirs[0].path)
        abort();
    char buf[512];
    if (gDirs[0].len > 510 || path.size() > 510 - gDirs[0].len) {
        fputs("File name too long\n", stderr);
        abort();
    }
    int i = 0, r;
    memcpy(buf, gDirs[0].path, gDirs[0].len);
    i += gDirs[0].len;
    buf[i++] = '/';
    std::string::const_iterator p = path.begin(), e = path.end();
    for (; p != e; ++p) {
        if (*p == '/') {
            buf[i] = '\0';
            r = mkdir(buf, 0777);
            if (r && errno != EEXIST) {
                perror("mkdir");
                abort();
            }
        }
        buf[i++] = *p;
    }
    buf[i] = '\0';
    FILE *f = fopen(buf, "w");
    if (!f) {
        perror("fopen");
        abort();
    }
    return f;
}
<|endoftext|>


<commit_before>
/**
 * @file TeamBallLocator.h
 *
 * Implementation of class TeamBallLocator
 */

#include "TeamBallLocator.h"

TeamBallLocator::TeamBallLocator()
{
  DEBUG_REQUEST_REGISTER("TeamBallLocator:draw_ball_on_field", "draw the team ball model on the field", false);
}

void TeamBallLocator::execute()
{
  msgData = getTeamMessage().data;

  for(std::map<unsigned int, TeamMessage::Data>::const_iterator i=msgData.begin(); i != msgData.end(); ++i)
  {
    const TeamMessage::Data& msg = i->second;
    const unsigned int& playerNumber = i->first;

    // set time and legacy stuff
    if(msg.ballAge >= 0) // -1 means invalid ball
    {
      // collect messages
      Vector2dTS ballPosTS;
      ballPosTS.vec = msg.pose * msg.ballPosition;
      ballPosTS.t = msg.frameInfo.getTimeInSeconds(); // maybe +msg.BallAge ?
      ballPosHist.push_back(ballPosTS);

      if (msg.frameInfo.getTimeInSeconds() > getTeamBallModel().time )
      {
        ASSERT(msg.frameInfo.getTimeInSeconds() >= 0);
        getTeamBallModel().time = (unsigned int)msg.frameInfo.getTimeInSeconds();
      }

      // goalie
      if(playerNumber == 1)
      {
        getTeamBallModel().goaliePositionOnField = ballPos;
        getTeamBallModel().goaliePosition = getRobotPose() / getTeamBallModel().goaliePositionOnField;
        getTeamBallModel().goalieTime = msg.frameInfo.getTime();
      }

      // striker
      if (msg.wasStriker)
      {
        getTeamBallModel().strikerPositionOnField = ballPos;
        getTeamBallModel().strikerPosition = getRobotPose() / getTeamBallModel().strikerPositionOnField;
        getTeamBallModel().strikerTime = msg.frameInfo.getTime();
      }
    }
  }

  // find oldest messages and erase them
  double maxTimeOffset = 1.0;
  sort(ballPosHist.begin(), ballPosHist.end());
  std::vector<Vector2dTS>::iterator cutOff;
  size_t cutOff = 0;
  for(cutOff = ballPosHist.begin(); cutOff != ballPosHist.end(); cutOff++)
  {
    if(cutOff->t >= getTeamBallModel().time - maxTimeOffset)
    {
      break;
    }
  }
  ballPosHist.erase(ballPosHist.begin(), cutOff);

  // median in x and y
  std::vector<double> x(ballPosHist.size());
  std::vector<double> y(ballPosHist.size());
  for(size_t i = 0; i < ballPosHist.size(); i++)
  {
    x.push_back(ballPosHist.vec.x);
    y.push_back(ballPosHist.vec.y);
  }
  sort(x.begin(), x.end());
  sort(y.begin(), y.end());
  Vector2d teamball;
  teamball.x = x[x.size()/2];
  teamball.y = y[y.size()/2];

  // write result and transform
  getTeamBallModel().positionOnField = teamball;
  getTeamBallModel().position = getRobotPose() / getTeamBallModel().positionOnField;

  DEBUG_REQUEST("TeamBallLocator:draw_ball_on_field",
    FIELD_DRAWING_CONTEXT;
    PEN("FF0000", 20);
    CIRCLE(getTeamBallModel().positionOnField.x, getTeamBallModel().positionOnField.y, 45);
    TEXT_DRAWING(getTeamBallModel().positionOnField.x, getTeamBallModel().positionOnField.y, ballPosHist.size());
  );
}
<commit_msg>some more comments<commit_after>
/**
 * @file TeamBallLocator.h
 *
 * Implementation of class TeamBallLocator
 */

#include "TeamBallLocator.h"

TeamBallLocator::TeamBallLocator()
{
  DEBUG_REQUEST_REGISTER("TeamBallLocator:draw_ball_on_field", "draw the team ball model on the field", false);
}

void TeamBallLocator::execute()
{
  msgData = getTeamMessage().data;

  for(std::map<unsigned int, TeamMessage::Data>::const_iterator i=msgData.begin(); i != msgData.end(); ++i)
  {
    const TeamMessage::Data& msg = i->second;
    const unsigned int& playerNumber = i->first;

    // -1 means invalid ball
    if(msg.ballAge >= 0)
    {
      // collect messages
      Vector2dTS ballPosTS;
      ballPosTS.vec = msg.pose * msg.ballPosition;
      ballPosTS.t = msg.frameInfo.getTimeInSeconds(); // maybe +msg.BallAge ?
      ballPosHist.push_back(ballPosTS);

      // set time
      if (msg.frameInfo.getTimeInSeconds() > getTeamBallModel().time )
      {
        ASSERT(msg.frameInfo.getTimeInSeconds() >= 0);
        // are full seconds really the way to go?
        getTeamBallModel().time = (unsigned int)msg.frameInfo.getTimeInSeconds();
      }

      // goalie
      if(playerNumber == 1)
      {
        getTeamBallModel().goaliePositionOnField = ballPos;
        getTeamBallModel().goaliePosition = getRobotPose() / getTeamBallModel().goaliePositionOnField;
        getTeamBallModel().goalieTime = msg.frameInfo.getTime();
      }

      // striker
      if (msg.wasStriker)
      {
        getTeamBallModel().strikerPositionOnField = ballPos;
        getTeamBallModel().strikerPosition = getRobotPose() / getTeamBallModel().strikerPositionOnField;
        getTeamBallModel().strikerTime = msg.frameInfo.getTime();
      }
    }
  }

  // find oldest messages and erase them
  double maxTimeOffset = 1.0;
  sort(ballPosHist.begin(), ballPosHist.end());
  std::vector<Vector2dTS>::iterator cutOff;
  size_t cutOff = 0;
  // we are iterating through the sorted array from small (old) to high (new) times
  for(cutOff = ballPosHist.begin(); cutOff != ballPosHist.end(); cutOff++)
  {
    // take care: getTeamBallModel().time are unsigned int seconds
    if(cutOff->t >= getTeamBallModel().time - maxTimeOffset)
    {
      break;
    }
  }
  ballPosHist.erase(ballPosHist.begin(), cutOff);

  // median in x and y
  std::vector<double> xHist(ballPosHist.size());
  std::vector<double> yHist(ballPosHist.size());
  for(size_t i = 0; i < ballPosHist.size(); i++)
  {
    xHist.push_back(ballPosHist.vec.x);
    yHist.push_back(ballPosHist.vec.y);
  }
  sort(xHist.begin(), xHist.end());
  sort(yHist.begin(), yHist.end());
  Vector2d teamball;
  teamball.x = xHist[xHist.size()/2];
  teamball.y = yHist[yHist.size()/2];

  // write result and transform
  getTeamBallModel().positionOnField = teamball;
  getTeamBallModel().position = getRobotPose() / getTeamBallModel().positionOnField;

  DEBUG_REQUEST("TeamBallLocator:draw_ball_on_field",
    FIELD_DRAWING_CONTEXT;
    PEN("FF0000", 20);
    CIRCLE(getTeamBallModel().positionOnField.x, getTeamBallModel().positionOnField.y, 45);
    TEXT_DRAWING(getTeamBallModel().positionOnField.x, getTeamBallModel().positionOnField.y, ballPosHist.size());
  );
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "debuggeragents.h"
#include "debuggerstringutils.h"
#include "idebuggerengine.h"

#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>

#include <utils/qtcassert.h>

#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextCursor>
#include <QtGui/QSyntaxHighlighter>

#include <limits.h>

namespace Debugger {
namespace Internal {

///////////////////////////////////////////////////////////////////////
//
// MemoryViewAgent
//
///////////////////////////////////////////////////////////////////////

/*!
    \class MemoryViewAgent

    Objects form this class are created in response to user actions in
    the Gui for showing raw memory from the inferior. After creation
    it handles communication between the engine and the bineditor.
*/

MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
    : QObject(manager), m_engine(manager->currentEngine())
{
    init(addr);
}

MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
    : QObject(manager), m_engine(manager->currentEngine())
{
    bool ok = true;
    init(addr.toULongLong(&ok, 0));
    //qDebug() <<  " ADDRESS: " << addr <<  addr.toUInt(&ok, 0);
}

MemoryViewAgent::~MemoryViewAgent()
{
    if (m_editor)
        m_editor->deleteLater();
}

void MemoryViewAgent::init(quint64 addr)
{
    Core::EditorManager *editorManager = Core::EditorManager::instance();
    QString titlePattern = tr("Memory $");
    m_editor = editorManager->openEditorWithContents(
        Core::Constants::K_DEFAULT_BINARY_EDITOR,
        &titlePattern);
    connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
        this, SLOT(fetchLazyData(quint64,bool)));
    editorManager->activateEditor(m_editor);
    QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
        Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
}

void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
{
    Q_UNUSED(sync); // FIXME: needed support for incremental searching
    if (m_engine)
        m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
}

void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
{
    if (m_editor && m_editor->widget())
        QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
            Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
}

///////////////////////////////////////////////////////////////////////
//
// DisassemblerViewAgent
//
///////////////////////////////////////////////////////////////////////

static QIcon locationMarkIcon()
{
    static const QIcon icon(":/debugger/images/location.svg");
    return icon;
}

// Used for the disassembler view
class LocationMark2 : public TextEditor::ITextMark
{
public:
    LocationMark2() {}

    QIcon icon() const { return locationMarkIcon(); }
    void updateLineNumber(int /*lineNumber*/) {}
    void updateBlock(const QTextBlock & /*block*/) {}
    void removedFromEditor() {}
    void documentClosing() {}
};

struct DisassemblerViewAgentPrivate
{
    QPointer<TextEditor::ITextEditor> editor;
    StackFrame frame;
    QPointer<DebuggerManager> manager;
    LocationMark2 *locationMark;
    QHash<QString, QString> cache;
};

/*!
    \class DisassemblerSyntaxHighlighter

     Simple syntax highlighter to make the disassembler text less prominent.
*/

class DisassemblerHighlighter : public QSyntaxHighlighter
{
public:
    DisassemblerHighlighter(QPlainTextEdit *parent)
        : QSyntaxHighlighter(parent->document())
    {}

private:
    void highlightBlock(const QString &text)
    {
        if (!text.isEmpty() && text.at(0) != ' ') {
            QTextCharFormat format;
            format.setForeground(QColor(128, 128, 128));
            setFormat(0, text.size(), format);
        }
    }
};

/*!
    \class DisassemblerViewAgent

     Objects from this class are created in response to user actions in
     the Gui for showing disassembled memory from the inferior. After creation
     it handles communication between the engine and the editor.
*/

DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager)
    : QObject(manager), d(new DisassemblerViewAgentPrivate)
{
    d->editor = 0;
    d->locationMark = new LocationMark2();
    d->manager = manager;
}

DisassemblerViewAgent::~DisassemblerViewAgent()
{
    if (d->editor)
        d->editor->deleteLater();
    d->editor = 0;
    delete d;
    d = 0;
}

void DisassemblerViewAgent::cleanup()
{
    d->cache.clear();
    //if (d->editor)
    //    d->editor->deleteLater();
    //d->editor = 0;
}

void DisassemblerViewAgent::setFrame(const StackFrame &frame)
{
    d->frame = frame;
    if (!frame.function.isEmpty()) {
        QHash<QString, QString>::ConstIterator it =
            d->cache.find(frame.function + frame.file);
        if (it != d->cache.end()) {
            setContents(*it);
            return;
        }
    }
    IDebuggerEngine *engine = d->manager->currentEngine();
    QTC_ASSERT(engine, return);
    engine->fetchDisassembler(this, frame);
}

void DisassemblerViewAgent::setContents(const QString &contents)
{
    QTC_ASSERT(d, return);
    using namespace Core;
    using namespace TextEditor;

    d->cache.insert(d->frame.function + d->frame.file, contents);
    QPlainTextEdit *plainTextEdit = 0;
    EditorManager *editorManager = EditorManager::instance();
    if (!d->editor) {
        QString titlePattern = "Disassembler";
        d->editor = qobject_cast<ITextEditor *>(
            editorManager->openEditorWithContents(
                Core::Constants::K_DEFAULT_TEXT_EDITOR,
                &titlePattern));
        QTC_ASSERT(d->editor, return);
        if ((plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget())))
            (void) new DisassemblerHighlighter(plainTextEdit);
    }

    editorManager->activateEditor(d->editor);

    plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget());
    if (plainTextEdit)
        plainTextEdit->setPlainText(contents);

    d->editor->markableInterface()->removeMark(d->locationMark);
    d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function));

    for (int pos = 0, line = 0; ; ++line, ++pos) {
        if (contents.midRef(pos, d->frame.address.size()) == d->frame.address) {
            d->editor->markableInterface()->addMark(d->locationMark, line + 1);
            if (plainTextEdit) {
                QTextCursor tc = plainTextEdit->textCursor();
                tc.setPosition(pos);
                plainTextEdit->setTextCursor(tc);
            }
            break;
        }
        pos = contents.indexOf('\n', pos + 1);
        if (pos == -1)
            break;
    }
}

QString DisassemblerViewAgent::address() const
{
    return d->frame.address;
}

} // namespace Internal
} // namespace Debugger
<commit_msg>debugger: remove disassembler view location marker when cleaning up views<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used 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.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "debuggeragents.h"
#include "debuggerstringutils.h"
#include "idebuggerengine.h"

#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <coreplugin/icore.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>

#include <utils/qtcassert.h>

#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextCursor>
#include <QtGui/QSyntaxHighlighter>

#include <limits.h>

namespace Debugger {
namespace Internal {

///////////////////////////////////////////////////////////////////////
//
// MemoryViewAgent
//
///////////////////////////////////////////////////////////////////////

/*!
    \class MemoryViewAgent

    Objects form this class are created in response to user actions in
    the Gui for showing raw memory from the inferior. After creation
    it handles communication between the engine and the bineditor.
*/

MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, quint64 addr)
    : QObject(manager), m_engine(manager->currentEngine())
{
    init(addr);
}

MemoryViewAgent::MemoryViewAgent(DebuggerManager *manager, const QString &addr)
    : QObject(manager), m_engine(manager->currentEngine())
{
    bool ok = true;
    init(addr.toULongLong(&ok, 0));
    //qDebug() <<  " ADDRESS: " << addr <<  addr.toUInt(&ok, 0);
}

MemoryViewAgent::~MemoryViewAgent()
{
    if (m_editor)
        m_editor->deleteLater();
}

void MemoryViewAgent::init(quint64 addr)
{
    Core::EditorManager *editorManager = Core::EditorManager::instance();
    QString titlePattern = tr("Memory $");
    m_editor = editorManager->openEditorWithContents(
        Core::Constants::K_DEFAULT_BINARY_EDITOR,
        &titlePattern);
    connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
        this, SLOT(fetchLazyData(quint64,bool)));
    editorManager->activateEditor(m_editor);
    QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
        Q_ARG(quint64, addr), Q_ARG(int, 1024 * 1024), Q_ARG(int, BinBlockSize));
}

void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
{
    Q_UNUSED(sync); // FIXME: needed support for incremental searching
    if (m_engine)
        m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
}

void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
{
    if (m_editor && m_editor->widget())
        QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
            Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
}

///////////////////////////////////////////////////////////////////////
//
// DisassemblerViewAgent
//
///////////////////////////////////////////////////////////////////////

static QIcon locationMarkIcon()
{
    static const QIcon icon(":/debugger/images/location.svg");
    return icon;
}

// Used for the disassembler view
class LocationMark2 : public TextEditor::ITextMark
{
public:
    LocationMark2() {}

    QIcon icon() const { return locationMarkIcon(); }
    void updateLineNumber(int /*lineNumber*/) {}
    void updateBlock(const QTextBlock & /*block*/) {}
    void removedFromEditor() {}
    void documentClosing() {}
};

struct DisassemblerViewAgentPrivate
{
    QPointer<TextEditor::ITextEditor> editor;
    StackFrame frame;
    QPointer<DebuggerManager> manager;
    LocationMark2 *locationMark;
    QHash<QString, QString> cache;
};

/*!
    \class DisassemblerSyntaxHighlighter

     Simple syntax highlighter to make the disassembler text less prominent.
*/

class DisassemblerHighlighter : public QSyntaxHighlighter
{
public:
    DisassemblerHighlighter(QPlainTextEdit *parent)
        : QSyntaxHighlighter(parent->document())
    {}

private:
    void highlightBlock(const QString &text)
    {
        if (!text.isEmpty() && text.at(0) != ' ') {
            QTextCharFormat format;
            format.setForeground(QColor(128, 128, 128));
            setFormat(0, text.size(), format);
        }
    }
};

/*!
    \class DisassemblerViewAgent

     Objects from this class are created in response to user actions in
     the Gui for showing disassembled memory from the inferior. After creation
     it handles communication between the engine and the editor.
*/

DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager)
    : QObject(manager), d(new DisassemblerViewAgentPrivate)
{
    d->editor = 0;
    d->locationMark = new LocationMark2();
    d->manager = manager;
}

DisassemblerViewAgent::~DisassemblerViewAgent()
{
    if (d->editor)
        d->editor->deleteLater();
    d->editor = 0;
    delete d;
    d = 0;
}

void DisassemblerViewAgent::cleanup()
{
    d->cache.clear();
    if (d->editor)
        d->editor->markableInterface()->removeMark(d->locationMark);
    //if (d->editor)
    //    d->editor->deleteLater();
    //d->editor = 0;
}

void DisassemblerViewAgent::setFrame(const StackFrame &frame)
{
    d->frame = frame;
    if (!frame.function.isEmpty()) {
        QHash<QString, QString>::ConstIterator it =
            d->cache.find(frame.function + frame.file);
        if (it != d->cache.end()) {
            setContents(*it);
            return;
        }
    }
    IDebuggerEngine *engine = d->manager->currentEngine();
    QTC_ASSERT(engine, return);
    engine->fetchDisassembler(this, frame);
}

void DisassemblerViewAgent::setContents(const QString &contents)
{
    QTC_ASSERT(d, return);
    using namespace Core;
    using namespace TextEditor;

    d->cache.insert(d->frame.function + d->frame.file, contents);
    QPlainTextEdit *plainTextEdit = 0;
    EditorManager *editorManager = EditorManager::instance();
    if (!d->editor) {
        QString titlePattern = "Disassembler";
        d->editor = qobject_cast<ITextEditor *>(
            editorManager->openEditorWithContents(
                Core::Constants::K_DEFAULT_TEXT_EDITOR,
                &titlePattern));
        QTC_ASSERT(d->editor, return);
        if ((plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget())))
            (void) new DisassemblerHighlighter(plainTextEdit);
    }

    editorManager->activateEditor(d->editor);

    plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget());
    if (plainTextEdit)
        plainTextEdit->setPlainText(contents);

    d->editor->markableInterface()->removeMark(d->locationMark);
    d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function));

    for (int pos = 0, line = 0; ; ++line, ++pos) {
        if (contents.midRef(pos, d->frame.address.size()) == d->frame.address) {
            d->editor->markableInterface()->addMark(d->locationMark, line + 1);
            if (plainTextEdit) {
                QTextCursor tc = plainTextEdit->textCursor();
                tc.setPosition(pos);
                plainTextEdit->setTextCursor(tc);
            }
            break;
        }
        pos = contents.indexOf('\n', pos + 1);
        if (pos == -1)
            break;
    }
}

QString DisassemblerViewAgent::address() const
{
    return d->frame.address;
}

} // namespace Internal
} // namespace Debugger
<|endoftext|>