<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2015 Scientific Computing and Imaging Institute,
   University of Utah.

   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 <Modules/Legacy/FiniteElements/BuildFESurfRHS.h>
#include <Core/Algorithms/Legacy/FiniteElements/BuildRHS/BuildFESurfRHS.h>
#include <Core/Datatypes/Matrix.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/Legacy/Field/Field.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>

using namespace SCIRun::Modules::FiniteElements;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Algorithms::FiniteElements;
using namespace SCIRun;

BuildFESurfRHS::BuildFESurfRHS()
  : Module(ModuleLookupInfo("BuildFESurfRHS", "FiniteElements", "SCIRun"),false)
{
  INITIALIZE_PORT(InputField);
  INITIALIZE_PORT(BoundaryField);
  INITIALIZE_PORT(RHSMatrix);
}

void BuildFESurfRHS::setStateDefaults()
{

}

void BuildFESurfRHS::execute()
{
 auto input = getRequiredInput(InputField);
 if (needToExecute())
 {
   auto output = algo().run(make_input((InputField, input)));
   sendOutputFromAlgorithm(BoundaryField, output);
   sendOutputFromAlgorithm(RHSMatrix, output);
 }

}

/*
// Include the algorithm
#include <Core/Algorithms/FiniteElements/BuildRHS/BuildFESurfRHS.h>

// The module class
#include <Dataflow/Network/Module.h>

// We need to define the ports used
#include <Dataflow/Network/Ports/FieldPort.h>
#include <Dataflow/Network/Ports/MatrixPort.h>

namespace SCIRun {

class BuildFESurfRHS : public Module {
  public:
    /// constructor and execute function
    BuildFESurfRHS(GuiContext*);
    virtual ~BuildFESurfRHS() {}
    virtual void execute();

  private:
    /// Define algorithms needed
    SCIRunAlgo::BuildFESurfRHSAlgo algo_;
};

DECLARE_MAKER(BuildFESurfRHS)
BuildFESurfRHS::BuildFESurfRHS(GuiContext* ctx)
  : Module("BuildFESurfRHS", ctx, Source, "FiniteElements", "SCIRun")
{
  /// Forward error messages;
  algo_.set_progress_reporter(this);
}

void
BuildFESurfRHS::execute()
{
  // Declare dataflow object
  FieldHandle field;

  // Get data from ports
  get_input_handle("Field",field,true);

  // If parameters changed, do algorithm
  if (inputs_changed_ ||
      !oport_cached("BoundaryField") ||
      !oport_cached("RHSMatrix"))
  {
    update_state(Executing);
    // Output dataflow objects:
    FieldHandle ofield;
    MatrixHandle rhsmatrix;

    // Entry point to algorithm
    if (!(algo_.run(field,ofield,rhsmatrix))) return;

    // Send Data flow objects downstream
    send_output_handle("BoundaryField", ofield);
    send_output_handle("RHSMatrix", rhsmatrix);
  }
}

} // End namespace SCIRun
*/
<commit_msg>first commit<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2015 Scientific Computing and Imaging Institute,
   University of Utah.

   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 <Modules/Legacy/FiniteElements/BuildFESurfRHS.h>
#include <Core/Algorithms/Legacy/FiniteElements/BuildRHS/BuildFESurfRHS.h>
#include <Core/Datatypes/Matrix.h>
#include <Core/Datatypes/DenseMatrix.h>
#include <Core/Datatypes/Legacy/Field/Field.h>
#include <Core/Algorithms/Base/AlgorithmVariableNames.h>

using namespace SCIRun::Modules::FiniteElements;
using namespace SCIRun::Dataflow::Networks;
using namespace SCIRun::Core::Datatypes;
using namespace SCIRun::Core::Algorithms::FiniteElements;
using namespace SCIRun;

MODULE_INFO_DEF(BuildFESurfRHS, FiniteElements, SCIRun)

BuildFESurfRHS::BuildFESurfRHS()
  : Module(ModuleLookupInfo("BuildFESurfRHS", "FiniteElements", "SCIRun"),false)
{
  INITIALIZE_PORT(InputField);
  INITIALIZE_PORT(BoundaryField);
  INITIALIZE_PORT(RHSMatrix);
}

void BuildFESurfRHS::setStateDefaults()
{

}

void BuildFESurfRHS::execute()
{
 auto input = getRequiredInput(InputField);
 if (needToExecute())
 {
   auto output = algo().run(make_input((InputField, input)));
   sendOutputFromAlgorithm(BoundaryField, output);
   sendOutputFromAlgorithm(RHSMatrix, output);
 }

}

/*
// Include the algorithm
#include <Core/Algorithms/FiniteElements/BuildRHS/BuildFESurfRHS.h>

// The module class
#include <Dataflow/Network/Module.h>

// We need to define the ports used
#include <Dataflow/Network/Ports/FieldPort.h>
#include <Dataflow/Network/Ports/MatrixPort.h>

namespace SCIRun {

class BuildFESurfRHS : public Module {
  public:
    /// constructor and execute function
    BuildFESurfRHS(GuiContext*);
    virtual ~BuildFESurfRHS() {}
    virtual void execute();

  private:
    /// Define algorithms needed
    SCIRunAlgo::BuildFESurfRHSAlgo algo_;
};

DECLARE_MAKER(BuildFESurfRHS)
BuildFESurfRHS::BuildFESurfRHS(GuiContext* ctx)
  : Module("BuildFESurfRHS", ctx, Source, "FiniteElements", "SCIRun")
{
  /// Forward error messages;
  algo_.set_progress_reporter(this);
}

void
BuildFESurfRHS::execute()
{
  // Declare dataflow object
  FieldHandle field;

  // Get data from ports
  get_input_handle("Field",field,true);

  // If parameters changed, do algorithm
  if (inputs_changed_ ||
      !oport_cached("BoundaryField") ||
      !oport_cached("RHSMatrix"))
  {
    update_state(Executing);
    // Output dataflow objects:
    FieldHandle ofield;
    MatrixHandle rhsmatrix;

    // Entry point to algorithm
    if (!(algo_.run(field,ofield,rhsmatrix))) return;

    // Send Data flow objects downstream
    send_output_handle("BoundaryField", ofield);
    send_output_handle("RHSMatrix", rhsmatrix);
  }
}

} // End namespace SCIRun
*/
<|endoftext|>


<commit_before>#include "Player.h"
#include "InputHandler.h"
#include <iostream>

void Player::handleInput() {
	int xAxisValue, yAxisValue;
	InputHandler* handlerInstance = InputHandler::Instance();
	if (handlerInstance->joysticksInitialised()) {
		xAxisValue = handlerInstance->stickXValue(0, LEFT_STICK);
		yAxisValue = handlerInstance->stickYValue(0, LEFT_STICK);
		if (xAxisValue > 0 || xAxisValue < 0) {
			m_velocity.setX(1 * xAxisValue);
		}
		if (yAxisValue > 0 || yAxisValue < 0) {
			m_velocity.setY(1 * yAxisValue);
		}
	}
}

void Player::update() {
	m_velocity.setX(0);
	m_velocity.setY(0);

	handleInput();
	SDLDrawable::update();
}
<commit_msg>speed stored in a variable<commit_after>#include "Player.h"
#include "InputHandler.h"
#include <iostream>

void Player::handleInput() {
	int xAxisValue, yAxisValue, velocityBasis = 1;
	InputHandler* handlerInstance = InputHandler::Instance();
	if (handlerInstance->joysticksInitialised()) {
		xAxisValue = handlerInstance->stickXValue(0, LEFT_STICK);
		yAxisValue = handlerInstance->stickYValue(0, LEFT_STICK);
		if (xAxisValue > 0 || xAxisValue < 0) {
			m_velocity.setX(velocityBasis * xAxisValue);
		}
		if (yAxisValue > 0 || yAxisValue < 0) {
			m_velocity.setY(velocityBasis * yAxisValue);
		}
	}
}

void Player::update() {
	m_velocity.setX(0);
	m_velocity.setY(0);

	handleInput();
	SDLDrawable::update();
}
<|endoftext|>


<commit_before>#ifndef CHARACTER_HPP_INCLUDED
#define CHARACTER_HPP_INCLUDED

#include <array>
#include <memory>
#include <string>
#include <unordered_map>

#include <SFML/Graphics.hpp>
#include "object.hpp"

struct CharacterData;

struct CharacterTraits
{
    uint64_t is_player : 1;
    uint64_t intelligent : 1;
    uint64_t needs_food : 1;
    uint64_t can_swim : 1;
    uint64_t beast : 1;
    uint64_t padding : 59;
};

class Character;
typedef std::shared_ptr<Character> CharacterPtr;

enum EquipmentSlot
{
    Slot_First,
    Slot_Weapon = Slot_First,

    Slot_Count
};

class Character
{
    uint32_t strength_;
    uint32_t health_;
    uint32_t max_health_;
    uint32_t radiation_;
    uint32_t food_;
    uint32_t view_range_;
    std::string name_;
    sf::Vector2f position_;
    sf::Vector2f facing_;
    uint32_t inventory_weight_;
    std::unordered_map<uint32_t, Object::Instance> inventory_;

    CharacterTraits traits_;

    uint32_t sprite_id_;

    std::array<ObjectId, Slot_Count> equipement_;

public:
    Character();
    ~Character();

    const std::string&  GetName() const;
    const sf::Vector2f& GetPosition() const;
    const sf::Vector2f& GetFacing() const;
    uint32_t GetHealth() const;
    uint32_t GetMaxHealth() const;
    uint32_t GetRadiation() const;
    CharacterTraits GetTraits() const;
    uint32_t GetFood() const;
    uint32_t GetSpriteId() const;
    uint32_t GetViewRange() const;

    void Move(const sf::Vector2f& vec);

    void SetSpriteId(const uint32_t id);
    void SetName(const std::string& name);
    void SetPosition(const sf::Vector2f& vec);
    void SetFacing(const sf::Vector2f& vec);
    void SetHealth(uint32_t health);
    void SetMaxHealth(uint32_t max);
    void SetRadiation(uint32_t rad);
    void SetTraits(const CharacterTraits& traits);
    void SetFood(uint32_t food);
    void SetViewRange(uint32_t range);
    void ChangeFood(int32_t food);
    void ChangeHealth(int32_t health);

    uint32_t ComputeAttackRoll(bool melee = true);
    uint32_t ComputeDamageRoll(bool melee = true);

    bool AddInventoryObject(Object::Instance object);
    std::vector<Object::Instance> GetInventory();
    std::vector<Object::Instance> GetInventoryObjectsByType(ObjectType type);
    Object::Instance GetInventoryObject(ObjectId uid);
    bool RemoveInventoryObject(ObjectId id, uint32_t qty);

    // equipment
    void EquipItem(EquipmentSlot slot, ObjectId id);
    void UnequipItem(EquipmentSlot slot);
    ObjectId GetEquippedItem(EquipmentSlot slot);
};

#endif
<commit_msg>Updating header that was missed<commit_after>#ifndef CHARACTER_HPP_INCLUDED
#define CHARACTER_HPP_INCLUDED

#include <array>
#include <memory>
#include <string>
#include <unordered_map>

#include <SFML/Graphics.hpp>
#include "object.hpp"

struct CharacterData;

struct CharacterTraits
{
    uint64_t is_player : 1;
    uint64_t intelligent : 1;
    uint64_t needs_food : 1;
    uint64_t can_swim : 1;
    uint64_t beast : 1;
	uint64_t aggro : 1;
    uint64_t padding : 58;
};

class Character;
typedef std::shared_ptr<Character> CharacterPtr;

enum EquipmentSlot
{
    Slot_First,
    Slot_Weapon = Slot_First,

    Slot_Count
};

class Character
{
    uint32_t strength_;
    uint32_t health_;
    uint32_t max_health_;
    uint32_t radiation_;
    uint32_t food_;
    uint32_t view_range_;
    std::string name_;
    sf::Vector2f position_;
    sf::Vector2f facing_;
    uint32_t inventory_weight_;
    std::unordered_map<uint32_t, Object::Instance> inventory_;

    CharacterTraits traits_;

    uint32_t sprite_id_;

    std::array<ObjectId, Slot_Count> equipement_;

public:
    Character();
    ~Character();

    const std::string&  GetName() const;
    const sf::Vector2f& GetPosition() const;
    const sf::Vector2f& GetFacing() const;
    uint32_t GetHealth() const;
    uint32_t GetMaxHealth() const;
    uint32_t GetRadiation() const;
    CharacterTraits GetTraits() const;
    uint32_t GetFood() const;
    uint32_t GetSpriteId() const;
    uint32_t GetViewRange() const;

    void Move(const sf::Vector2f& vec);

    void SetSpriteId(const uint32_t id);
    void SetName(const std::string& name);
    void SetPosition(const sf::Vector2f& vec);
    void SetFacing(const sf::Vector2f& vec);
    void SetHealth(uint32_t health);
    void SetMaxHealth(uint32_t max);
    void SetRadiation(uint32_t rad);
    void SetTraits(const CharacterTraits& traits);
    void SetFood(uint32_t food);
    void SetViewRange(uint32_t range);
    void ChangeFood(int32_t food);
    void ChangeHealth(int32_t health);

    uint32_t ComputeAttackRoll(bool melee = true);
    uint32_t ComputeDamageRoll(bool melee = true);

    bool AddInventoryObject(Object::Instance object);
    std::vector<Object::Instance> GetInventory();
    std::vector<Object::Instance> GetInventoryObjectsByType(ObjectType type);
    Object::Instance GetInventoryObject(ObjectId uid);
    bool RemoveInventoryObject(ObjectId id, uint32_t qty);

    // equipment
    void EquipItem(EquipmentSlot slot, ObjectId id);
    void UnequipItem(EquipmentSlot slot);
    ObjectId GetEquippedItem(EquipmentSlot slot);
};

#endif
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "cppvirtualfunctionassistprovider.h"

#include "cppeditorconstants.h"
#include "cppelementevaluator.h"

#include <cplusplus/Icons.h>
#include <cplusplus/Overview.h>

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>

#include <texteditor/codeassist/basicproposalitem.h>
#include <texteditor/codeassist/basicproposalitemlistmodel.h>
#include <texteditor/codeassist/genericproposal.h>
#include <texteditor/codeassist/genericproposalwidget.h>
#include <texteditor/codeassist/iassistinterface.h>
#include <texteditor/codeassist/iassistprocessor.h>
#include <texteditor/codeassist/iassistproposal.h>

#include <utils/qtcassert.h>

using namespace CPlusPlus;
using namespace CppEditor::Internal;
using namespace TextEditor;

class VirtualFunctionProposalItem: public BasicProposalItem {
public:
    VirtualFunctionProposalItem(const BaseTextEditorWidget::Link &link, bool openInSplit = true)
        : m_link(link), m_openInSplit(openInSplit) {}

    void apply(BaseTextEditor * /* editor */, int /* basePosition */) const
    {
        if (!m_link.hasValidTarget())
            return;

        Core::EditorManager::OpenEditorFlags flags;
        if (m_openInSplit)
            flags |= Core::EditorManager::OpenInOtherSplit;
        Core::EditorManager::openEditorAt(m_link.targetFileName,
                                          m_link.targetLine,
                                          m_link.targetColumn,
                                          CppEditor::Constants::CPPEDITOR_ID,
                                          flags);
    }

private:
    BaseTextEditorWidget::Link m_link;
    bool m_openInSplit;
};

/// Activate current item with the same shortcut that is configured for Follow Symbol Under Cursor.
/// This is limited to single-key shortcuts without modifiers.
class VirtualFunctionProposalWidget : public GenericProposalWidget
{
public:
    VirtualFunctionProposalWidget(bool openInSplit)
    {
        const char *id = openInSplit
            ? TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR_IN_NEXT_SPLIT
            : TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR;
        if (Core::Command *command = Core::ActionManager::command(id))
            m_sequence = command->keySequence();
    }

protected:
    bool eventFilter(QObject *o, QEvent *e)
    {
        if (e->type() == QEvent::ShortcutOverride && m_sequence.count() == 1) {
            QKeyEvent *ke = static_cast<QKeyEvent *>(e);
            const QKeySequence seq(ke->key());
            if (seq == m_sequence) {
                activateCurrentProposalItem();
                e->accept();
                return true;
            }
        }
        return GenericProposalWidget::eventFilter(o, e);
    }

private:
    QKeySequence m_sequence;
};

class VirtualFunctionProposal : public GenericProposal
{
public:
    VirtualFunctionProposal(int cursorPos, IGenericProposalModel *model, bool openInSplit)
        : GenericProposal(cursorPos, model)
        , m_openInSplit(openInSplit)
    {}

    bool isFragile() const
    { return true; }

    IAssistProposalWidget *createWidget() const
    { return new VirtualFunctionProposalWidget(m_openInSplit); }

private:
    bool m_openInSplit;
};

class VirtualFunctionsAssistProcessor : public IAssistProcessor
{
public:
    VirtualFunctionsAssistProcessor(const VirtualFunctionAssistProvider *provider)
        : m_startClass(provider->startClass())
        , m_function(provider->function())
        , m_snapshot(provider->snapshot())
        , m_openInNextSplit(provider->openInNextSplit())
    {}

    IAssistProposal *immediateProposal(const TextEditor::IAssistInterface *interface)
    {
        QTC_ASSERT(m_function, return 0);

        BasicProposalItem *hintItem = new VirtualFunctionProposalItem(CPPEditorWidget::Link());
        hintItem->setText(QCoreApplication::translate("VirtualFunctionsAssistProcessor",
                                                      "...searching overrides"));
        hintItem->setOrder(-1000);

        QList<BasicProposalItem *> items;
        items << itemFromSymbol(m_function, m_function);
        items << hintItem;
        return new VirtualFunctionProposal(interface->position(),
                                           new BasicProposalItemListModel(items),
                                           m_openInNextSplit);
    }

    IAssistProposal *perform(const IAssistInterface *interface)
    {
        if (!interface)
            return 0;

        QTC_ASSERT(m_startClass, return 0);
        QTC_ASSERT(m_function, return 0);
        QTC_ASSERT(!m_snapshot.isEmpty(), return 0);

        const QList<Symbol *> overrides = FunctionHelper::overrides(m_startClass, m_function,
                                                                     m_snapshot);
        QList<BasicProposalItem *> items;
        foreach (Symbol *symbol, overrides)
            items << itemFromSymbol(symbol, m_function);

        return new VirtualFunctionProposal(interface->position(),
                                           new BasicProposalItemListModel(items),
                                           m_openInNextSplit);
    }

    BasicProposalItem *itemFromSymbol(Symbol *symbol, Symbol *firstSymbol) const
    {
        const QString text = m_overview.prettyName(LookupContext::fullyQualifiedName(symbol));
        const CPPEditorWidget::Link link = CPPEditorWidget::linkToSymbol(symbol);

        BasicProposalItem *item = new VirtualFunctionProposalItem(link, m_openInNextSplit);
        item->setText(text);
        item->setIcon(m_icons.iconForSymbol(symbol));
        if (symbol == firstSymbol)
            item->setOrder(1000); // Ensure top position for function of static type

        return item;
    }

private:
    Class *m_startClass;
    Function *m_function;
    Snapshot m_snapshot;
    bool m_openInNextSplit;
    Overview m_overview;
    Icons m_icons;
};

VirtualFunctionAssistProvider::VirtualFunctionAssistProvider()
    : m_function(0)
    , m_openInNextSplit(false)
{
}

bool VirtualFunctionAssistProvider::configure(Class *startClass, Function *function,
                                              const Snapshot &snapshot, bool openInNextSplit)
{
    m_startClass = startClass;
    m_function = function;
    m_snapshot = snapshot;
    m_openInNextSplit = openInNextSplit;
    return true;
}

bool VirtualFunctionAssistProvider::isAsynchronous() const
{
    return true;
}

bool VirtualFunctionAssistProvider::supportsEditor(const Core::Id &editorId) const
{
    return editorId == CppEditor::Constants::CPPEDITOR_ID;
}

IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const
{
    return new VirtualFunctionsAssistProcessor(this);
}

enum VirtualType { Virtual, PureVirtual };

static bool isVirtualFunction_helper(const Function *function,
                                     const Snapshot &snapshot,
                                     VirtualType virtualType)
{
    if (!function)
        return false;

    if ((virtualType == Virtual && function->isVirtual())
            || (virtualType == PureVirtual && function->isPureVirtual())) {
        return true;
    }

    const QString filePath = QString::fromUtf8(function->fileName(), function->fileNameLength());
    if (Document::Ptr document = snapshot.document(filePath)) {
        LookupContext context(document, snapshot);
        QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope());
        if (!results.isEmpty()) {
            foreach (const LookupItem &item, results) {
                if (Symbol *symbol = item.declaration()) {
                    if (Function *functionType = symbol->type()->asFunctionType()) {
                        if (!functionType) {
                            if (Template *t = item.type()->asTemplateType())
                                if ((symbol = t->declaration()))
                                    functionType = symbol->type()->asFunctionType();
                        }
                        const bool foundSuitable = virtualType == Virtual
                            ? functionType->isVirtual()
                            : functionType->isPureVirtual();
                        if (foundSuitable)
                            return true;
                    }
                }
            }
        }
    }

    return false;
}

bool FunctionHelper::isVirtualFunction(const Function *function, const Snapshot &snapshot)
{
    return isVirtualFunction_helper(function, snapshot, Virtual);
}

bool FunctionHelper::isPureVirtualFunction(const Function *function, const Snapshot &snapshot)
{
    return isVirtualFunction_helper(function, snapshot, PureVirtual);
}

QList<Symbol *> FunctionHelper::overrides(Class *startClass, Function *function,
                                          const Snapshot &snapshot)
{
    QList<Symbol *> result;
    QTC_ASSERT(startClass && function, return result);

    FullySpecifiedType referenceType = function->type();
    const Name *referenceName = function->name();
    QTC_ASSERT(referenceName && referenceType.isValid(), return result);

    // Add itself
    result << function;

    // Find overrides
    CppEditor::Internal::CppClass cppClass = CppClass(startClass);
    cppClass.lookupDerived(startClass, snapshot);

    QList<CppClass> l;
    l << cppClass;

    while (!l.isEmpty()) {
        // Add derived
        CppClass clazz = l.takeFirst();
        foreach (const CppClass &d, clazz.derived) {
            if (!l.contains(d))
                l << d;
        }

        // Check member functions
        QTC_ASSERT(clazz.declaration, continue);
        Class *c = clazz.declaration->asClass();
        QTC_ASSERT(c, continue);
        for (int i = 0, total = c->memberCount(); i < total; ++i) {
            Symbol *candidate = c->memberAt(i);
            const Name *candidateName = candidate->name();
            const FullySpecifiedType candidateType = candidate->type();
            if (!candidateName || !candidateType.isValid())
                continue;
            if (candidateName->isEqualTo(referenceName) && candidateType.isEqualTo(referenceType))
                result << candidate;
        }
    }

    return result;
}
<commit_msg>CppEditor: Remove template lookup for virtual functions<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/

#include "cppvirtualfunctionassistprovider.h"

#include "cppeditorconstants.h"
#include "cppelementevaluator.h"

#include <cplusplus/Icons.h>
#include <cplusplus/Overview.h>

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>

#include <texteditor/codeassist/basicproposalitem.h>
#include <texteditor/codeassist/basicproposalitemlistmodel.h>
#include <texteditor/codeassist/genericproposal.h>
#include <texteditor/codeassist/genericproposalwidget.h>
#include <texteditor/codeassist/iassistinterface.h>
#include <texteditor/codeassist/iassistprocessor.h>
#include <texteditor/codeassist/iassistproposal.h>

#include <utils/qtcassert.h>

using namespace CPlusPlus;
using namespace CppEditor::Internal;
using namespace TextEditor;

class VirtualFunctionProposalItem: public BasicProposalItem {
public:
    VirtualFunctionProposalItem(const BaseTextEditorWidget::Link &link, bool openInSplit = true)
        : m_link(link), m_openInSplit(openInSplit) {}

    void apply(BaseTextEditor * /* editor */, int /* basePosition */) const
    {
        if (!m_link.hasValidTarget())
            return;

        Core::EditorManager::OpenEditorFlags flags;
        if (m_openInSplit)
            flags |= Core::EditorManager::OpenInOtherSplit;
        Core::EditorManager::openEditorAt(m_link.targetFileName,
                                          m_link.targetLine,
                                          m_link.targetColumn,
                                          CppEditor::Constants::CPPEDITOR_ID,
                                          flags);
    }

private:
    BaseTextEditorWidget::Link m_link;
    bool m_openInSplit;
};

/// Activate current item with the same shortcut that is configured for Follow Symbol Under Cursor.
/// This is limited to single-key shortcuts without modifiers.
class VirtualFunctionProposalWidget : public GenericProposalWidget
{
public:
    VirtualFunctionProposalWidget(bool openInSplit)
    {
        const char *id = openInSplit
            ? TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR_IN_NEXT_SPLIT
            : TextEditor::Constants::FOLLOW_SYMBOL_UNDER_CURSOR;
        if (Core::Command *command = Core::ActionManager::command(id))
            m_sequence = command->keySequence();
    }

protected:
    bool eventFilter(QObject *o, QEvent *e)
    {
        if (e->type() == QEvent::ShortcutOverride && m_sequence.count() == 1) {
            QKeyEvent *ke = static_cast<QKeyEvent *>(e);
            const QKeySequence seq(ke->key());
            if (seq == m_sequence) {
                activateCurrentProposalItem();
                e->accept();
                return true;
            }
        }
        return GenericProposalWidget::eventFilter(o, e);
    }

private:
    QKeySequence m_sequence;
};

class VirtualFunctionProposal : public GenericProposal
{
public:
    VirtualFunctionProposal(int cursorPos, IGenericProposalModel *model, bool openInSplit)
        : GenericProposal(cursorPos, model)
        , m_openInSplit(openInSplit)
    {}

    bool isFragile() const
    { return true; }

    IAssistProposalWidget *createWidget() const
    { return new VirtualFunctionProposalWidget(m_openInSplit); }

private:
    bool m_openInSplit;
};

class VirtualFunctionsAssistProcessor : public IAssistProcessor
{
public:
    VirtualFunctionsAssistProcessor(const VirtualFunctionAssistProvider *provider)
        : m_startClass(provider->startClass())
        , m_function(provider->function())
        , m_snapshot(provider->snapshot())
        , m_openInNextSplit(provider->openInNextSplit())
    {}

    IAssistProposal *immediateProposal(const TextEditor::IAssistInterface *interface)
    {
        QTC_ASSERT(m_function, return 0);

        BasicProposalItem *hintItem = new VirtualFunctionProposalItem(CPPEditorWidget::Link());
        hintItem->setText(QCoreApplication::translate("VirtualFunctionsAssistProcessor",
                                                      "...searching overrides"));
        hintItem->setOrder(-1000);

        QList<BasicProposalItem *> items;
        items << itemFromSymbol(m_function, m_function);
        items << hintItem;
        return new VirtualFunctionProposal(interface->position(),
                                           new BasicProposalItemListModel(items),
                                           m_openInNextSplit);
    }

    IAssistProposal *perform(const IAssistInterface *interface)
    {
        if (!interface)
            return 0;

        QTC_ASSERT(m_startClass, return 0);
        QTC_ASSERT(m_function, return 0);
        QTC_ASSERT(!m_snapshot.isEmpty(), return 0);

        const QList<Symbol *> overrides = FunctionHelper::overrides(m_startClass, m_function,
                                                                     m_snapshot);
        QList<BasicProposalItem *> items;
        foreach (Symbol *symbol, overrides)
            items << itemFromSymbol(symbol, m_function);

        return new VirtualFunctionProposal(interface->position(),
                                           new BasicProposalItemListModel(items),
                                           m_openInNextSplit);
    }

    BasicProposalItem *itemFromSymbol(Symbol *symbol, Symbol *firstSymbol) const
    {
        const QString text = m_overview.prettyName(LookupContext::fullyQualifiedName(symbol));
        const CPPEditorWidget::Link link = CPPEditorWidget::linkToSymbol(symbol);

        BasicProposalItem *item = new VirtualFunctionProposalItem(link, m_openInNextSplit);
        item->setText(text);
        item->setIcon(m_icons.iconForSymbol(symbol));
        if (symbol == firstSymbol)
            item->setOrder(1000); // Ensure top position for function of static type

        return item;
    }

private:
    Class *m_startClass;
    Function *m_function;
    Snapshot m_snapshot;
    bool m_openInNextSplit;
    Overview m_overview;
    Icons m_icons;
};

VirtualFunctionAssistProvider::VirtualFunctionAssistProvider()
    : m_function(0)
    , m_openInNextSplit(false)
{
}

bool VirtualFunctionAssistProvider::configure(Class *startClass, Function *function,
                                              const Snapshot &snapshot, bool openInNextSplit)
{
    m_startClass = startClass;
    m_function = function;
    m_snapshot = snapshot;
    m_openInNextSplit = openInNextSplit;
    return true;
}

bool VirtualFunctionAssistProvider::isAsynchronous() const
{
    return true;
}

bool VirtualFunctionAssistProvider::supportsEditor(const Core::Id &editorId) const
{
    return editorId == CppEditor::Constants::CPPEDITOR_ID;
}

IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const
{
    return new VirtualFunctionsAssistProcessor(this);
}

enum VirtualType { Virtual, PureVirtual };

static bool isVirtualFunction_helper(const Function *function,
                                     const Snapshot &snapshot,
                                     VirtualType virtualType)
{
    if (!function)
        return false;

    if ((virtualType == Virtual && function->isVirtual())
            || (virtualType == PureVirtual && function->isPureVirtual())) {
        return true;
    }

    const QString filePath = QString::fromUtf8(function->fileName(), function->fileNameLength());
    if (Document::Ptr document = snapshot.document(filePath)) {
        LookupContext context(document, snapshot);
        QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope());
        if (!results.isEmpty()) {
            foreach (const LookupItem &item, results) {
                if (Symbol *symbol = item.declaration()) {
                    if (Function *functionType = symbol->type()->asFunctionType()) {
                        const bool foundSuitable = virtualType == Virtual
                            ? functionType->isVirtual()
                            : functionType->isPureVirtual();
                        if (foundSuitable)
                            return true;
                    }
                }
            }
        }
    }

    return false;
}

bool FunctionHelper::isVirtualFunction(const Function *function, const Snapshot &snapshot)
{
    return isVirtualFunction_helper(function, snapshot, Virtual);
}

bool FunctionHelper::isPureVirtualFunction(const Function *function, const Snapshot &snapshot)
{
    return isVirtualFunction_helper(function, snapshot, PureVirtual);
}

QList<Symbol *> FunctionHelper::overrides(Class *startClass, Function *function,
                                          const Snapshot &snapshot)
{
    QList<Symbol *> result;
    QTC_ASSERT(startClass && function, return result);

    FullySpecifiedType referenceType = function->type();
    const Name *referenceName = function->name();
    QTC_ASSERT(referenceName && referenceType.isValid(), return result);

    // Add itself
    result << function;

    // Find overrides
    CppEditor::Internal::CppClass cppClass = CppClass(startClass);
    cppClass.lookupDerived(startClass, snapshot);

    QList<CppClass> l;
    l << cppClass;

    while (!l.isEmpty()) {
        // Add derived
        CppClass clazz = l.takeFirst();
        foreach (const CppClass &d, clazz.derived) {
            if (!l.contains(d))
                l << d;
        }

        // Check member functions
        QTC_ASSERT(clazz.declaration, continue);
        Class *c = clazz.declaration->asClass();
        QTC_ASSERT(c, continue);
        for (int i = 0, total = c->memberCount(); i < total; ++i) {
            Symbol *candidate = c->memberAt(i);
            const Name *candidateName = candidate->name();
            const FullySpecifiedType candidateType = candidate->type();
            if (!candidateName || !candidateType.isValid())
                continue;
            if (candidateName->isEqualTo(referenceName) && candidateType.isEqualTo(referenceType))
                result << candidate;
        }
    }

    return result;
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 * Copyright (c) 2016-2017 metaverse core developers (see MVS-AUTHORS)
 *
 * This file is part of metaverse-explorer.
 *
 * metaverse-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/explorer/commands/mnemonic-to-seed.hpp>

#include <iostream>
#include <metaverse/bitcoin.hpp>
#include <metaverse/explorer/define.hpp>

namespace libbitcoin {
namespace explorer {
namespace commands {
using namespace bc::config;
using namespace bc::wallet;

console_result mnemonic_to_seed::invoke(std::ostream& output,
    std::ostream& error)
{
    // Bound parameters.
    const dictionary_list& language = get_language_option();
    const auto& passphrase = get_passphrase_option();
    const auto& words = get_words_argument();

    const auto word_count = words.size();

    if ((word_count % bc::wallet::mnemonic_word_multiple) != 0)
    {
        error << BX_EC_MNEMONIC_TO_SEED_LENGTH_INVALID_SENTENCE << std::flush;
        return console_result::failure;
    }

    const auto valid = validate_mnemonic(words, language);

    if (!valid && language.size() == 1)
    {
        // This is fatal because a dictionary was specified explicitly.
        error << BX_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGE << std::flush;
        return console_result::failure;
    }

    if (!valid && language.size() > 1)
        error << BX_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGES << std::flush;

#ifdef WITH_ICU
    // Any word set divisible by 3 works regardless of language validation.
    const auto seed = decode_mnemonic(words, passphrase);
#else
    if (!passphrase.empty())
    {
        error << BX_EC_MNEMONIC_TO_SEED_PASSPHRASE_UNSUPPORTED << std::flush;
        return console_result::failure;
    }

    // The passphrase requires ICU normalization.
    const auto seed = decode_mnemonic(words);
#endif

    output << base16(seed) << std::flush;
    return console_result::okay;
}

} //namespace commands
} //namespace explorer
} //namespace libbitcoin
<commit_msg>#173 mnemonic to seed command error<commit_after>/**
 * Copyright (c) 2011-2015 libbitcoin developers (see AUTHORS)
 * Copyright (c) 2016-2017 metaverse core developers (see MVS-AUTHORS)
 *
 * This file is part of metaverse-explorer.
 *
 * metaverse-explorer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License with
 * additional permissions to the one published by the Free Software
 * Foundation, either version 3 of the License, or (at your option)
 * any later version. For more information see LICENSE.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
#include <metaverse/explorer/commands/mnemonic-to-seed.hpp>

#include <iostream>
#include <metaverse/bitcoin.hpp>
#include <metaverse/explorer/define.hpp>

namespace libbitcoin {
namespace explorer {
namespace commands {
using namespace bc::config;
using namespace bc::wallet;

console_result mnemonic_to_seed::invoke(std::ostream& output,
    std::ostream& error)
{
    // Bound parameters.
    const dictionary_list& language = get_language_option();
    const auto& passphrase = get_passphrase_option();
    const auto& words = get_words_argument();

    const auto word_count = words.size();

    if ((word_count % bc::wallet::mnemonic_word_multiple) != 0)
    {
        error << BX_EC_MNEMONIC_TO_SEED_LENGTH_INVALID_SENTENCE << std::flush;
        return console_result::failure;
    }

    const auto valid = validate_mnemonic(words, language);

    if (!valid && language.size() == 1)
    {
        // This is fatal because a dictionary was specified explicitly.
        error << BX_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGE << std::flush;
        return console_result::failure;
    }

    if (!valid && language.size() > 1)
    {
        error << BX_EC_MNEMONIC_TO_SEED_INVALID_IN_LANGUAGES << std::flush;
        return console_result::failure;
    }

#ifdef WITH_ICU
    // Any word set divisible by 3 works regardless of language validation.
    const auto seed = decode_mnemonic(words, passphrase);
#else
    if (!passphrase.empty())
    {
        error << BX_EC_MNEMONIC_TO_SEED_PASSPHRASE_UNSUPPORTED << std::flush;
        return console_result::failure;
    }

    // The passphrase requires ICU normalization.
    const auto seed = decode_mnemonic(words);
#endif

    output << base16(seed) << std::flush;
    return console_result::okay;
}

} //namespace commands
} //namespace explorer
} //namespace libbitcoin
<|endoftext|>


<commit_before>/***************************************************************************
 *  @file       main.cpp
 *  @author     Alan.W
 *  @date       15  Mar 2014
 *  @remark     This code is for Introduction to Algorithms
 *  @note
 ***************************************************************************/
//!
//! ex 2.2-2 Selection-Sort
//!

//! Pseudocode:
/*  Selection_Sort(A)
 *  1   for i = 1 to n-1
 *  2       key = i
 *  3       for j = i to n
 *  4           if (A[key] > A[j])  key = j
 *  5       swap A[i] and A[key]
 */

//! loop invariant:
/*  At the start of each iteration of line 1 - 5
 *  A[i-1] is no greater than any value from subarray A[i...n]
 */

#include <iostream>
#include <vector>

/**
 *  selection_sort
 */
template<typename T>
void selection_sort(std::vector<T>& v);
int main()
{
    //! test:
    std::vector<int> vi = {8,6,3,9,11,77,2};
    std::vector<std::string> vs = {"zzaaa","zzz888","1a","444","44","zzzzzzzzzzz"};
    std::vector<char> vc = {'a','s','1','2','0'};
    std::vector<int> test ={999};

    selection_sort(test);

    //! print
    for(const auto i : test)
        std::cout << i << std::endl;

    return 0;
}

//! Pseudocode:
/*  Selection_Sort(A)
 *  1   for i = 1 to n-1
 *  2       key = i
 *  3       for j = i to n
 *  4           if (A[key] > A[j])  key = j
 *  5       swap A[i] and A[key]
 */
template<typename T>
void selection_sort(std::vector<T>& v)
{
    //! Boundary condition handling
    if(v.size() < 2)    return;

    for(auto i = v.begin(); i != v.end() - 1; ++i)
    {
        auto key = i;
        for(auto j = i; j != v.end(); ++j)
            if(*key > *j)   key=j;
        std::swap(*i,*key);
    }
}
<commit_msg>	deleted:    seletion_sort_ex22_2.cpp<commit_after><|endoftext|>


<commit_before>#include <string>
#include <cstdlib>
#include <cassert>

#include "Reader.h"
#include "NullReader.h"
#include "HdfReader.h"
#include "TextReader.h"
#include "VtkReader.h"

using namespace cigma;

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

cigma::Reader* NewReader(const char *fileext)
{
    std::string ext = fileext;

    if (ext == ".h5")
    {
        return new HdfReader();
    }

    if (ext == ".txt")
    {
        return new TextReader();
    }

    if ((ext == ".vtk") || (ext == ".vts") || (ext == ".vtu"))
    {
        return new VtkReader();
    }

    return new NullReader(fileext);
}

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

cigma::Reader::Reader()
{
}

cigma::Reader::~Reader()
{
}

// ---------------------------------------------------------------------------
<commit_msg>Use PathUtils functions in NewReader() factory method<commit_after>#include <string>
#include <cstdlib>
#include <cassert>

#include "Reader.h"
#include "NullReader.h"
#include "HdfReader.h"
#include "TextReader.h"
#include "VtkReader.h"

#include "PathUtils.h"

using namespace cigma;

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

Reader* NewReader(const char *fileext)
{
    //
    // XXX: Need to pass filename to this function, not just the extension.
    // This way, we could use the IsHdfFile() and IsVtkFile() functions
    // which can read the corresponding file headers to verify.
    // Another thing to verify here is whether the file exists or not.
    //

    if (HdfExtension(fileext))
    {
        return new HdfReader();
    }

    if (TextExtension(fileext))
    {
        return new TextReader();
    }

    if (VtkExtension(fileext))
    {
        return new VtkReader();
    }

    return new NullReader(fileext);
}

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

Reader::Reader()
{
}

Reader::~Reader()
{
}

// ---------------------------------------------------------------------------
<|endoftext|>


<commit_before>// This file is part of the AliceVision project.
// Copyright (c) 2016 AliceVision contributors.
// Copyright (c) 2012 openMVG contributors.
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#include "io.hpp"
#include <aliceVision/matching/IndMatch.hpp>
#include <aliceVision/config.hpp>
#include <aliceVision/system/Logger.hpp>

#include <boost/filesystem.hpp>

#include <map>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>

namespace fs = boost::filesystem;

namespace aliceVision {
namespace matching {

bool LoadMatchFile(PairwiseMatches& matches, const std::string& filepath)
{
  const std::string ext = fs::extension(filepath);

  if(!fs::exists(filepath))
    return false;

  if(ext == ".txt")
  {
    std::ifstream stream(filepath.c_str());
    if (!stream.is_open())
      return false;

    // Read from the text file
    // I J
    // nbDescType
    // descType matchesCount
    // idx idx
    // ...
    // descType matchesCount
    // idx idx
    // ...
    std::size_t I = 0;
    std::size_t J = 0;
    std::size_t nbDescType = 0;
    while(stream >> I >> J >> nbDescType)
    {
      for(std::size_t i = 0; i < nbDescType; ++i)
      {
        std::string descTypeStr;
        std::size_t nbMatches = 0;
        // Read descType and number of matches
        stream >> descTypeStr >> nbMatches;

        feature::EImageDescriberType descType = feature::EImageDescriberType_stringToEnum(descTypeStr);
        std::vector<IndMatch> matchesPerDesc(nbMatches);
        // Read all matches
        for(std::size_t i = 0; i < nbMatches; ++i)
        {
          stream >> matchesPerDesc[i];
        }
        matches[std::make_pair(I,J)][descType] = std::move(matchesPerDesc);
      }
    }
    stream.close();
    return true;
  }
  else
  {
    ALICEVISION_LOG_WARNING("Unknown matching file format: " << ext);
  }
  return false;
}

void filterMatchesByViews(
  PairwiseMatches & matches,
  const std::set<IndexT> & viewsKeys)
{
  matching::PairwiseMatches filteredMatches;
  for (matching::PairwiseMatches::const_iterator iter = matches.begin();
    iter != matches.end();
    ++iter)
  {
    if(viewsKeys.find(iter->first.first) != viewsKeys.end() &&
       viewsKeys.find(iter->first.second) != viewsKeys.end())
    {
      filteredMatches.insert(*iter);
    }
  }
  matches.swap(filteredMatches);
}

void filterTopMatches(
  PairwiseMatches & allMatches,
  const int limitNum)
{
  if (limitNum <= 0)
    return;

  for(auto& matchesPerDesc: allMatches)
  {
    for(auto& matches: matchesPerDesc.second)
    {
      IndMatches& m = matches.second;
      if (m.size() > limitNum)
        m.erase(m.begin()+limitNum, m.end());
    }
  }
}

void filterMatchesByDesc(
  PairwiseMatches & allMatches,
  const std::vector<feature::EImageDescriberType>& descTypesFilter)
{
  matching::PairwiseMatches filteredMatches;
  for(const auto& matchesPerDesc: allMatches)
  {
    for(const auto& matches: matchesPerDesc.second)
    {
      const IndMatches& m = matches.second;
      // if current descType in descTypesFilter
      if(std::find(descTypesFilter.begin(), descTypesFilter.end(), matches.first) != descTypesFilter.end())
        filteredMatches[matchesPerDesc.first][matches.first] = m;
    }
  }
  allMatches.swap(filteredMatches);
}

bool LoadMatchFilePerImage(
  PairwiseMatches& matches,
  const std::set<IndexT>& viewsKeys,
  const std::string& folder,
  const std::string& basename)
{
  int nbLoadedMatchFiles = 0;
  // Load one match file per image
  #pragma omp parallel for num_threads(3)
  for(ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(viewsKeys.size()); ++i)
  {
    std::set<IndexT>::const_iterator it = viewsKeys.begin();
    std::advance(it, i);
    const IndexT idView = *it;
    const std::string matchFilename = std::to_string(idView) + "." + basename;
    PairwiseMatches fileMatches;
    if(!LoadMatchFile(fileMatches, (fs::path(folder) / matchFilename).string() ))
    {
      #pragma omp critical
      {
        ALICEVISION_LOG_DEBUG("Unable to load match file: " << matchFilename << " in: " << folder);
      }
      continue;
    }
    #pragma omp critical
    {
      ++nbLoadedMatchFiles;
      // merge the loaded matches into the output
      for(const auto& v: fileMatches)
      {
        matches[v.first] = v.second;
      }
    }
  }
  if(nbLoadedMatchFiles == 0)
  {
    ALICEVISION_LOG_WARNING("No matches file loaded in: " << folder);
    return false;
  }
  ALICEVISION_LOG_TRACE("Matches per image pair");
  for(const auto& imagePairIt: matches)
  {
    std::stringstream ss;
    ss << " * " << imagePairIt.first.first << "-" << imagePairIt.first.second << ": " << imagePairIt.second.getNbAllMatches() << "    ";
    for(const auto& matchesPerDeskIt: imagePairIt.second)
       ss << " [" << feature::EImageDescriberType_enumToString(matchesPerDeskIt.first) << ": " << matchesPerDeskIt.second.size() << "]";
    ALICEVISION_LOG_TRACE(ss.str());
  }
  return true;
}

bool Load(
  PairwiseMatches& matches,
  const std::set<IndexT>& viewsKeysFilter,
  const std::vector<std::string>& folders,
  const std::vector<feature::EImageDescriberType>& descTypesFilter,
  const int maxNbMatches)
{
  bool res = false;
  const std::string fileName = "matches.txt";

  for(const std::string& folder : folders)
  {
    const fs::path filePath = fs::path(folder) / fileName;

    if(fs::exists(filePath))
      res = LoadMatchFile(matches, filePath.string());
    else
      res = LoadMatchFilePerImage(matches, viewsKeysFilter, folder, fileName);
  }

  if(!res)
    return false;

  if(!viewsKeysFilter.empty())
    filterMatchesByViews(matches, viewsKeysFilter);

  if(!descTypesFilter.empty())
    filterMatchesByDesc(matches, descTypesFilter);

  if(maxNbMatches > 0)
    filterTopMatches(matches, maxNbMatches);

  ALICEVISION_LOG_TRACE("Matches per image pair");
  for(const auto& imagePairIt: matches)
  {
    std::stringstream ss;
    ss << " * " << imagePairIt.first.first << "-" << imagePairIt.first.second << ": " << imagePairIt.second.getNbAllMatches() << "    ";
    for(const auto& matchesPerDeskIt: imagePairIt.second)
    {
       ss << " [" << feature::EImageDescriberType_enumToString(matchesPerDeskIt.first) << ": " << matchesPerDeskIt.second.size() << "]";
    }
    ALICEVISION_LOG_TRACE(ss.str());
  }

  return res;
}

class MatchExporter
{
private:
  void saveTxt(
    const std::string& filepath,
    const PairwiseMatches::const_iterator& matchBegin,
    const PairwiseMatches::const_iterator& matchEnd)
  {
    const fs::path bPath = fs::path(filepath);
    const std::string tmpPath = (bPath.parent_path() / bPath.stem()).string() + "." + fs::unique_path().string() + bPath.extension().string();

    // write temporary file
    {
      std::ofstream stream(tmpPath.c_str(), std::ios::out);
      for(PairwiseMatches::const_iterator match = matchBegin;
        match != matchEnd;
        ++match)
      {
        const std::size_t I = match->first.first;
        const std::size_t J = match->first.second;
        const MatchesPerDescType & matchesPerDesc = match->second;
        stream << I << " " << J << '\n'
               << matchesPerDesc.size() << '\n';
        for(const auto& m: matchesPerDesc)
        {
          stream << feature::EImageDescriberType_enumToString(m.first) << " " << m.second.size() << '\n';
          copy(m.second.begin(), m.second.end(), std::ostream_iterator<IndMatch>(stream, "\n"));
        }
      }
    }

    // rename temporary file
    fs::rename(tmpPath, filepath);
  }

public:
  MatchExporter(
    const PairwiseMatches& matches,
    const std::string& folder,
    const std::string& filename)
    : m_matches(matches)
    , m_directory(folder)
    , m_filename(filename)
    , m_ext(fs::extension(filename))
  {}

  ~MatchExporter()
  {}

  void saveGlobalFile()
  {
    const std::string filepath = (fs::path(m_directory) / m_filename).string();

    if(m_ext == ".txt")
      saveTxt(filepath, m_matches.begin(), m_matches.end());
    else
      throw std::runtime_error(std::string("Unknown matching file format: ") + m_ext);
  }

  /// Export matches into separate files, one for each image.
  void saveOneFilePerImage()
  {
    std::set<IndexT> keys;
    std::transform(
        m_matches.begin(), m_matches.end(),
        std::inserter(keys, keys.begin()),
        [](const PairwiseMatches::value_type &v) { return v.first.first; });

    PairwiseMatches::const_iterator matchBegin = m_matches.begin();
    PairwiseMatches::const_iterator matchEnd = m_matches.end();
    for(IndexT key: keys)
    {
      PairwiseMatches::const_iterator match = matchBegin;
      while(match->first.first == key && match != matchEnd)
        ++match;
      const std::string filepath = (fs::path(m_directory) / (std::to_string(key) + "." + m_filename)).string();
      ALICEVISION_LOG_DEBUG("Export Matches in: " << filepath);

      if(m_ext == ".txt")
        saveTxt(filepath, matchBegin, match);
      else
        throw std::runtime_error(std::string("Unknown matching file format: ") + m_ext);

      matchBegin = match;
    }
  }

public:
  const PairwiseMatches& m_matches;
  const std::string m_ext;
  std::string m_directory;
  std::string m_filename;
};

bool Save(
  const PairwiseMatches & matches,
  const std::string & folder,
  const std::string & extension,
  bool matchFilePerImage)
{
  const std::string filename = "matches." + extension;
  MatchExporter exporter(matches, folder, filename);

  if(matchFilePerImage)
    exporter.saveOneFilePerImage();
  else
    exporter.saveGlobalFile();

  return true;
}

}  // namespace matching
}  // namespace aliceVision
<commit_msg>[matching] do not dereference end iterator<commit_after>// This file is part of the AliceVision project.
// Copyright (c) 2016 AliceVision contributors.
// Copyright (c) 2012 openMVG contributors.
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

#include "io.hpp"
#include <aliceVision/matching/IndMatch.hpp>
#include <aliceVision/config.hpp>
#include <aliceVision/system/Logger.hpp>

#include <boost/filesystem.hpp>

#include <map>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>

namespace fs = boost::filesystem;

namespace aliceVision {
namespace matching {

bool LoadMatchFile(PairwiseMatches& matches, const std::string& filepath)
{
  const std::string ext = fs::extension(filepath);

  if(!fs::exists(filepath))
    return false;

  if(ext == ".txt")
  {
    std::ifstream stream(filepath.c_str());
    if (!stream.is_open())
      return false;

    // Read from the text file
    // I J
    // nbDescType
    // descType matchesCount
    // idx idx
    // ...
    // descType matchesCount
    // idx idx
    // ...
    std::size_t I = 0;
    std::size_t J = 0;
    std::size_t nbDescType = 0;
    while(stream >> I >> J >> nbDescType)
    {
      for(std::size_t i = 0; i < nbDescType; ++i)
      {
        std::string descTypeStr;
        std::size_t nbMatches = 0;
        // Read descType and number of matches
        stream >> descTypeStr >> nbMatches;

        feature::EImageDescriberType descType = feature::EImageDescriberType_stringToEnum(descTypeStr);
        std::vector<IndMatch> matchesPerDesc(nbMatches);
        // Read all matches
        for(std::size_t i = 0; i < nbMatches; ++i)
        {
          stream >> matchesPerDesc[i];
        }
        matches[std::make_pair(I,J)][descType] = std::move(matchesPerDesc);
      }
    }
    stream.close();
    return true;
  }
  else
  {
    ALICEVISION_LOG_WARNING("Unknown matching file format: " << ext);
  }
  return false;
}

void filterMatchesByViews(
  PairwiseMatches & matches,
  const std::set<IndexT> & viewsKeys)
{
  matching::PairwiseMatches filteredMatches;
  for (matching::PairwiseMatches::const_iterator iter = matches.begin();
    iter != matches.end();
    ++iter)
  {
    if(viewsKeys.find(iter->first.first) != viewsKeys.end() &&
       viewsKeys.find(iter->first.second) != viewsKeys.end())
    {
      filteredMatches.insert(*iter);
    }
  }
  matches.swap(filteredMatches);
}

void filterTopMatches(
  PairwiseMatches & allMatches,
  const int limitNum)
{
  if (limitNum <= 0)
    return;

  for(auto& matchesPerDesc: allMatches)
  {
    for(auto& matches: matchesPerDesc.second)
    {
      IndMatches& m = matches.second;
      if (m.size() > limitNum)
        m.erase(m.begin()+limitNum, m.end());
    }
  }
}

void filterMatchesByDesc(
  PairwiseMatches & allMatches,
  const std::vector<feature::EImageDescriberType>& descTypesFilter)
{
  matching::PairwiseMatches filteredMatches;
  for(const auto& matchesPerDesc: allMatches)
  {
    for(const auto& matches: matchesPerDesc.second)
    {
      const IndMatches& m = matches.second;
      // if current descType in descTypesFilter
      if(std::find(descTypesFilter.begin(), descTypesFilter.end(), matches.first) != descTypesFilter.end())
        filteredMatches[matchesPerDesc.first][matches.first] = m;
    }
  }
  allMatches.swap(filteredMatches);
}

bool LoadMatchFilePerImage(
  PairwiseMatches& matches,
  const std::set<IndexT>& viewsKeys,
  const std::string& folder,
  const std::string& basename)
{
  int nbLoadedMatchFiles = 0;
  // Load one match file per image
  #pragma omp parallel for num_threads(3)
  for(ptrdiff_t i = 0; i < static_cast<ptrdiff_t>(viewsKeys.size()); ++i)
  {
    std::set<IndexT>::const_iterator it = viewsKeys.begin();
    std::advance(it, i);
    const IndexT idView = *it;
    const std::string matchFilename = std::to_string(idView) + "." + basename;
    PairwiseMatches fileMatches;
    if(!LoadMatchFile(fileMatches, (fs::path(folder) / matchFilename).string() ))
    {
      #pragma omp critical
      {
        ALICEVISION_LOG_DEBUG("Unable to load match file: " << matchFilename << " in: " << folder);
      }
      continue;
    }
    #pragma omp critical
    {
      ++nbLoadedMatchFiles;
      // merge the loaded matches into the output
      for(const auto& v: fileMatches)
      {
        matches[v.first] = v.second;
      }
    }
  }
  if(nbLoadedMatchFiles == 0)
  {
    ALICEVISION_LOG_WARNING("No matches file loaded in: " << folder);
    return false;
  }
  ALICEVISION_LOG_TRACE("Matches per image pair");
  for(const auto& imagePairIt: matches)
  {
    std::stringstream ss;
    ss << " * " << imagePairIt.first.first << "-" << imagePairIt.first.second << ": " << imagePairIt.second.getNbAllMatches() << "    ";
    for(const auto& matchesPerDeskIt: imagePairIt.second)
       ss << " [" << feature::EImageDescriberType_enumToString(matchesPerDeskIt.first) << ": " << matchesPerDeskIt.second.size() << "]";
    ALICEVISION_LOG_TRACE(ss.str());
  }
  return true;
}

bool Load(
  PairwiseMatches& matches,
  const std::set<IndexT>& viewsKeysFilter,
  const std::vector<std::string>& folders,
  const std::vector<feature::EImageDescriberType>& descTypesFilter,
  const int maxNbMatches)
{
  bool res = false;
  const std::string fileName = "matches.txt";

  for(const std::string& folder : folders)
  {
    const fs::path filePath = fs::path(folder) / fileName;

    if(fs::exists(filePath))
      res = LoadMatchFile(matches, filePath.string());
    else
      res = LoadMatchFilePerImage(matches, viewsKeysFilter, folder, fileName);
  }

  if(!res)
    return false;

  if(!viewsKeysFilter.empty())
    filterMatchesByViews(matches, viewsKeysFilter);

  if(!descTypesFilter.empty())
    filterMatchesByDesc(matches, descTypesFilter);

  if(maxNbMatches > 0)
    filterTopMatches(matches, maxNbMatches);

  ALICEVISION_LOG_TRACE("Matches per image pair");
  for(const auto& imagePairIt: matches)
  {
    std::stringstream ss;
    ss << " * " << imagePairIt.first.first << "-" << imagePairIt.first.second << ": " << imagePairIt.second.getNbAllMatches() << "    ";
    for(const auto& matchesPerDeskIt: imagePairIt.second)
    {
       ss << " [" << feature::EImageDescriberType_enumToString(matchesPerDeskIt.first) << ": " << matchesPerDeskIt.second.size() << "]";
    }
    ALICEVISION_LOG_TRACE(ss.str());
  }

  return res;
}

class MatchExporter
{
private:
  void saveTxt(
    const std::string& filepath,
    const PairwiseMatches::const_iterator& matchBegin,
    const PairwiseMatches::const_iterator& matchEnd)
  {
    const fs::path bPath = fs::path(filepath);
    const std::string tmpPath = (bPath.parent_path() / bPath.stem()).string() + "." + fs::unique_path().string() + bPath.extension().string();

    // write temporary file
    {
      std::ofstream stream(tmpPath.c_str(), std::ios::out);
      for(PairwiseMatches::const_iterator match = matchBegin;
        match != matchEnd;
        ++match)
      {
        const std::size_t I = match->first.first;
        const std::size_t J = match->first.second;
        const MatchesPerDescType & matchesPerDesc = match->second;
        stream << I << " " << J << '\n'
               << matchesPerDesc.size() << '\n';
        for(const auto& m: matchesPerDesc)
        {
          stream << feature::EImageDescriberType_enumToString(m.first) << " " << m.second.size() << '\n';
          copy(m.second.begin(), m.second.end(), std::ostream_iterator<IndMatch>(stream, "\n"));
        }
      }
    }

    // rename temporary file
    fs::rename(tmpPath, filepath);
  }

public:
  MatchExporter(
    const PairwiseMatches& matches,
    const std::string& folder,
    const std::string& filename)
    : m_matches(matches)
    , m_directory(folder)
    , m_filename(filename)
    , m_ext(fs::extension(filename))
  {}

  ~MatchExporter()
  {}

  void saveGlobalFile()
  {
    const std::string filepath = (fs::path(m_directory) / m_filename).string();

    if(m_ext == ".txt")
      saveTxt(filepath, m_matches.begin(), m_matches.end());
    else
      throw std::runtime_error(std::string("Unknown matching file format: ") + m_ext);
  }

  /// Export matches into separate files, one for each image.
  void saveOneFilePerImage()
  {
    std::set<IndexT> keys;
    std::transform(
        m_matches.begin(), m_matches.end(),
        std::inserter(keys, keys.begin()),
        [](const PairwiseMatches::value_type &v) { return v.first.first; });

    PairwiseMatches::const_iterator matchBegin = m_matches.begin();
    PairwiseMatches::const_iterator matchEnd = m_matches.end();
    for(IndexT key: keys)
    {
      PairwiseMatches::const_iterator match = matchBegin;
      while(match != matchEnd && match->first.first == key)
        ++match;
      const std::string filepath = (fs::path(m_directory) / (std::to_string(key) + "." + m_filename)).string();
      ALICEVISION_LOG_DEBUG("Export Matches in: " << filepath);

      if(m_ext == ".txt")
        saveTxt(filepath, matchBegin, match);
      else
        throw std::runtime_error(std::string("Unknown matching file format: ") + m_ext);

      matchBegin = match;
    }
  }

public:
  const PairwiseMatches& m_matches;
  const std::string m_ext;
  std::string m_directory;
  std::string m_filename;
};

bool Save(
  const PairwiseMatches & matches,
  const std::string & folder,
  const std::string & extension,
  bool matchFilePerImage)
{
  const std::string filename = "matches." + extension;
  MatchExporter exporter(matches, folder, filename);

  if(matchFilePerImage)
    exporter.saveOneFilePerImage();
  else
    exporter.saveGlobalFile();

  return true;
}

}  // namespace matching
}  // namespace aliceVision
<|endoftext|>


<commit_before>#include "timing.h"
#include "Logger.h"

logger::LogChannel timinglog("timinglog", "[TimingStatistics] ");

TimingStatistics TimingStatistics::_instance;

double
Timer::elapsed() const {

	boost::chrono::nanoseconds ns(_timer.elapsed().wall);
	boost::chrono::duration<double> s = ns;

	return s.count();
}
TimingStatistics::TimingStatistics() :
	_longestIdentifierLength(0) {}

void
TimingStatistics::addTimer(const Timer& timer) {

	_instance.add(timer);
}

TimingStatistics::~TimingStatistics() {

	if (_timers.size() == 0)
		return;

	const std::string spacer("   ");

	LOG_USER(timinglog)
			<< "timing summary in seconds (wall time):"
			<< std::endl << std::endl;

	for (int i = 0; i < _longestIdentifierLength; i++)
		LOG_USER(timinglog) << " ";
	LOG_USER(timinglog) << spacer;
	LOG_USER(timinglog) << "   # runs" << spacer;
	LOG_USER(timinglog) << "mean     " << spacer;
	LOG_USER(timinglog) << "min      " << spacer;
	LOG_USER(timinglog) << "max      " << spacer;
	LOG_USER(timinglog) << "median   " << spacer;
	LOG_USER(timinglog) << "total" << std::endl << std::endl;

	for (const Timers::value_type& p : _timers) {

		const std::string&        identifier = p.first;
		const std::vector<Timer>& timers     = p.second;

		int numRuns = timers.size();
		double total = 0;
		std::vector<double> times;

		for (const Timer& t : timers) {

			total += t.elapsed();
			times.push_back(t.elapsed());
		}

		double mean = total/numRuns;

		std::nth_element(times.begin(), times.end(), times.begin());
		std::nth_element(times.begin(), times.end(), times.begin() + numRuns - 1);
		std::nth_element(times.begin(), times.end(), times.begin() + numRuns/2);

		double min    = times[0];
		double max    = times[numRuns - 1];
		double median = times[numRuns/2];

		LOG_USER(timinglog) << identifier;
		for (int i = 0; i < _longestIdentifierLength - identifier.size(); i++)
			LOG_USER(timinglog) << " ";
		LOG_USER(timinglog) << spacer;
		LOG_USER(timinglog) << std::setw(9) << std::setfill(' ');
		LOG_USER(timinglog) << numRuns << spacer;
		LOG_USER(timinglog) << std::scientific << std::setprecision(3);
		LOG_USER(timinglog) << mean << spacer;
		LOG_USER(timinglog) << min << spacer;
		LOG_USER(timinglog) << max << spacer;
		LOG_USER(timinglog) << median << spacer;
		LOG_USER(timinglog) << total;
		LOG_USER(timinglog) << std::endl;
	}
}

void
TimingStatistics::add(const Timer& timer) {

	_timers[timer.getIdentifier()].push_back(timer);
	_longestIdentifierLength = std::max(_longestIdentifierLength, timer.getIdentifier().size());
}
<commit_msg>fixed min, max, median times in TimingStatistics<commit_after>#include "timing.h"
#include "Logger.h"

logger::LogChannel timinglog("timinglog", "[TimingStatistics] ");

TimingStatistics TimingStatistics::_instance;

double
Timer::elapsed() const {

	boost::chrono::nanoseconds ns(_timer.elapsed().wall);
	boost::chrono::duration<double> s = ns;

	return s.count();
}
TimingStatistics::TimingStatistics() :
	_longestIdentifierLength(0) {}

void
TimingStatistics::addTimer(const Timer& timer) {

	_instance.add(timer);
}

TimingStatistics::~TimingStatistics() {

	if (_timers.size() == 0)
		return;

	const std::string spacer("   ");

	LOG_USER(timinglog)
			<< "timing summary in seconds (wall time):"
			<< std::endl << std::endl;

	for (int i = 0; i < _longestIdentifierLength; i++)
		LOG_USER(timinglog) << " ";
	LOG_USER(timinglog) << spacer;
	LOG_USER(timinglog) << "   # runs" << spacer;
	LOG_USER(timinglog) << "mean     " << spacer;
	LOG_USER(timinglog) << "min      " << spacer;
	LOG_USER(timinglog) << "max      " << spacer;
	LOG_USER(timinglog) << "median   " << spacer;
	LOG_USER(timinglog) << "total" << std::endl << std::endl;

	for (const Timers::value_type& p : _timers) {

		const std::string&        identifier = p.first;
		const std::vector<Timer>& timers     = p.second;

		int numRuns = timers.size();
		double total = 0;
		std::vector<double> times;

		for (const Timer& t : timers) {

			total += t.elapsed();
			times.push_back(t.elapsed());
		}

		double mean = total/numRuns;

		std::nth_element(times.begin(), times.begin(), times.end());
		double min    = times[0];
		std::nth_element(times.begin(), times.begin() + numRuns - 1, times.end());
		double max    = times[numRuns - 1];
		std::nth_element(times.begin(), times.begin() + numRuns/2, times.end());
		double median = times[numRuns/2];

		LOG_USER(timinglog) << identifier;
		for (int i = 0; i < _longestIdentifierLength - identifier.size(); i++)
			LOG_USER(timinglog) << " ";
		LOG_USER(timinglog) << spacer;
		LOG_USER(timinglog) << std::setw(9) << std::setfill(' ');
		LOG_USER(timinglog) << numRuns << spacer;
		LOG_USER(timinglog) << std::scientific << std::setprecision(3);
		LOG_USER(timinglog) << mean << spacer;
		LOG_USER(timinglog) << min << spacer;
		LOG_USER(timinglog) << max << spacer;
		LOG_USER(timinglog) << median << spacer;
		LOG_USER(timinglog) << total;
		LOG_USER(timinglog) << std::endl;
	}
}

void
TimingStatistics::add(const Timer& timer) {

	_timers[timer.getIdentifier()].push_back(timer);
	_longestIdentifierLength = std::max(_longestIdentifierLength, timer.getIdentifier().size());
}
<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//$Id$

#ifndef MECHANICTRANSLATIONALMASS_HPP_INCLUDED
#define MECHANICTRANSLATIONALMASS_HPP_INCLUDED

#include <sstream>
#include <math.h>

#include "../../ComponentEssentials.h"
#include "../../ComponentUtilities.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicTranslationalMass : public ComponentQ
    {

    private:
        double m, B, k, xMin, xMax;
        double mLength;         //This length is not accesible by the user,
                                //it is set from the start values by the c-components in the ends
        double *mpND_f1, *mpND_x1, *mpND_v1, *mpND_c1, *mpND_Zx1, *mpND_f2, *mpND_x2, *mpND_v2, *mpND_c2, *mpND_Zx2;  //Node data pointers
        double f1, x1, v1, c1, Zx1, f2, x2, v2, c2, Zx2;                                                    //Node data variables
        double mNumX[3], mNumV[2];
        double mDenX[3], mDenV[2];
        SecondOrderTransferFunction mFilterX;
        FirstOrderTransferFunction mFilterV;
        Port *mpP1, *mpP2;

    public:
        static Component *Creator()
        {
            return new MechanicTranslationalMass("TranslationalMass");
        }

        MechanicTranslationalMass(const std::string name) : ComponentQ(name)
        {
            //Set member attributes
            m = 100.0;
            B = 10;
            k = 0.0;
            xMin = 0.0;
            xMax = 1.0;

            //Add ports to the component
            mpP1 = addPowerPort("P1", "NodeMechanic");
            mpP2 = addPowerPort("P2", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            registerParameter("m", "Mass", "[kg]",                  m);
            registerParameter("B", "Viscous Friction", "[Ns/m]",    B);
            registerParameter("k", "Spring Coefficient", "[N/m]",   k);
            registerParameter("x_min", "Minimum Position", "[m]",   xMin);
            registerParameter("x_max", "Maximum Position", "[m]",   xMax);
        }

        void initialize()
        {
            //Assign node data pointers
            mpND_f1 = getSafeNodeDataPtr(mpP1, NodeMechanic::FORCE);
            mpND_x1 = getSafeNodeDataPtr(mpP1, NodeMechanic::POSITION);
            mpND_v1 = getSafeNodeDataPtr(mpP1, NodeMechanic::VELOCITY);
            mpND_c1 = getSafeNodeDataPtr(mpP1, NodeMechanic::WAVEVARIABLE);
            mpND_Zx1 = getSafeNodeDataPtr(mpP1, NodeMechanic::CHARIMP);

            mpND_f2 = getSafeNodeDataPtr(mpP2, NodeMechanic::FORCE);
            mpND_x2 = getSafeNodeDataPtr(mpP2, NodeMechanic::POSITION);
            mpND_v2 = getSafeNodeDataPtr(mpP2, NodeMechanic::VELOCITY);
            mpND_c2 = getSafeNodeDataPtr(mpP2, NodeMechanic::WAVEVARIABLE);
            mpND_Zx2 = getSafeNodeDataPtr(mpP2, NodeMechanic::CHARIMP);

            //Initialization
            f1 = (*mpND_f1);
            f2 = (*mpND_f2);
            x1 = (*mpND_x1);
            v1 = (*mpND_v1);
            x2 = (*mpND_x2);

            mLength = x1+x2;

            mNumX[0] = 1.0;
            mNumX[1] = 0.0;
            mNumX[2] = 0.0;
            mDenX[0] = k;
            mDenX[1] = B;
            mDenX[2] = m;
            mNumV[0] = 1.0;
            mNumV[1] = 0.0;
            mDenV[0] = B;
            mDenV[1] = m;

            mFilterX.initialize(mTimestep, mNumX, mDenX, f1-f2, -x1);
            mFilterV.initialize(mTimestep, mNumV, mDenV, f1-f2 - k*x2, -v1);

            //Print debug message if velocities do not match
            if((*mpND_v1) != -(*mpND_v2))
            {
                std::stringstream ss;
                ss << "Start velocities does not match, {" << getName() << "::" << mpP1->getPortName() <<
                        "} and {" << getName() << "::" << mpP2->getPortName() << "}.";
                this->addDebugMessage(ss.str());
            }
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            c1 = (*mpND_c1);
            Zx1 = (*mpND_Zx1);
            c2 = (*mpND_c2);
            Zx2 = (*mpND_Zx2);

            //Mass equations
            mDenX[1] = B+Zx1+Zx2;
            mDenV[0] = B+Zx1+Zx2;
            mFilterX.setDen(mDenX);
            mFilterV.setDen(mDenV);

            x2 = mFilterX.update(c1-c2);
            v2 = mFilterV.update(c1-c2 - k*x2);

            if((mTime > 6) && (mTime < 6.01))
            {
                double apa = c1-c2;
                stringstream ss;
                ss << "t: " << mTime << "   c1-c2 = " << apa << "   v2 = " << v2;
                addDebugMessage(ss.str());
            }

            if(x2<xMin)
            {
                x2=xMin;
                v2=0.0;
                mFilterX.initializeValues(c1-c2, x2);
                mFilterV.initializeValues(c1-c2, 0.0);
            }
            if(x2>xMax)
            {
                x2=xMax;
                v2=0.0;
                mFilterX.initializeValues(c1-c2, x2);
                mFilterV.initializeValues(c1-c2, 0.0);
            }

            v1 = -v2;
            x1 = -x2 + mLength;
            f1 = c1 + Zx1*v1;
            f2 = c2 + Zx2*v2;

            //Write new values to nodes
            (*mpND_f1) = f1;
            (*mpND_x1) = x1;
            (*mpND_v1) = v1;
            (*mpND_f2) = f2;
            (*mpND_x2) = x2;
            (*mpND_v2) = v2;

//            if((mTime>.5) && (mTime<.5001))
//            {
//                std::stringstream ss;
//                ss << "mTime: " << mTime << "     c1-c2: " << c1-c2 << "    v2: " << v2 << std::endl;
//                addInfoMessage(ss.str());
//            }
        }
    };
}

#endif // MECHANICTRANSLATIONALMASS_HPP_INCLUDED

<commit_msg>Commented out debug message form simulateOneTimeStep in mass component<commit_after>/*-----------------------------------------------------------------------------
 This source file is part of Hopsan NG

 Copyright (c) 2011
    Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
    Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

 This file is provided "as is", with no guarantee or warranty for the
 functionality or reliability of the contents. All contents in this file is
 the original work of the copyright holders at the Division of Fluid and
 Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
 redistributing any part of this file is prohibited without explicit
 permission from the copyright holders.
-----------------------------------------------------------------------------*/

//$Id$

#ifndef MECHANICTRANSLATIONALMASS_HPP_INCLUDED
#define MECHANICTRANSLATIONALMASS_HPP_INCLUDED

#include <sstream>
#include <math.h>

#include "../../ComponentEssentials.h"
#include "../../ComponentUtilities.h"

namespace hopsan {

    //!
    //! @brief
    //! @ingroup MechanicalComponents
    //!
    class MechanicTranslationalMass : public ComponentQ
    {

    private:
        double m, B, k, xMin, xMax;
        double mLength;         //This length is not accesible by the user,
                                //it is set from the start values by the c-components in the ends
        double *mpND_f1, *mpND_x1, *mpND_v1, *mpND_c1, *mpND_Zx1, *mpND_f2, *mpND_x2, *mpND_v2, *mpND_c2, *mpND_Zx2;  //Node data pointers
        double f1, x1, v1, c1, Zx1, f2, x2, v2, c2, Zx2;                                                    //Node data variables
        double mNumX[3], mNumV[2];
        double mDenX[3], mDenV[2];
        SecondOrderTransferFunction mFilterX;
        FirstOrderTransferFunction mFilterV;
        Port *mpP1, *mpP2;

    public:
        static Component *Creator()
        {
            return new MechanicTranslationalMass("TranslationalMass");
        }

        MechanicTranslationalMass(const std::string name) : ComponentQ(name)
        {
            //Set member attributes
            m = 100.0;
            B = 10;
            k = 0.0;
            xMin = 0.0;
            xMax = 1.0;

            //Add ports to the component
            mpP1 = addPowerPort("P1", "NodeMechanic");
            mpP2 = addPowerPort("P2", "NodeMechanic");

            //Register changable parameters to the HOPSAN++ core
            registerParameter("m", "Mass", "[kg]",                  m);
            registerParameter("B", "Viscous Friction", "[Ns/m]",    B);
            registerParameter("k", "Spring Coefficient", "[N/m]",   k);
            registerParameter("x_min", "Minimum Position", "[m]",   xMin);
            registerParameter("x_max", "Maximum Position", "[m]",   xMax);
        }

        void initialize()
        {
            //Assign node data pointers
            mpND_f1 = getSafeNodeDataPtr(mpP1, NodeMechanic::FORCE);
            mpND_x1 = getSafeNodeDataPtr(mpP1, NodeMechanic::POSITION);
            mpND_v1 = getSafeNodeDataPtr(mpP1, NodeMechanic::VELOCITY);
            mpND_c1 = getSafeNodeDataPtr(mpP1, NodeMechanic::WAVEVARIABLE);
            mpND_Zx1 = getSafeNodeDataPtr(mpP1, NodeMechanic::CHARIMP);

            mpND_f2 = getSafeNodeDataPtr(mpP2, NodeMechanic::FORCE);
            mpND_x2 = getSafeNodeDataPtr(mpP2, NodeMechanic::POSITION);
            mpND_v2 = getSafeNodeDataPtr(mpP2, NodeMechanic::VELOCITY);
            mpND_c2 = getSafeNodeDataPtr(mpP2, NodeMechanic::WAVEVARIABLE);
            mpND_Zx2 = getSafeNodeDataPtr(mpP2, NodeMechanic::CHARIMP);

            //Initialization
            f1 = (*mpND_f1);
            f2 = (*mpND_f2);
            x1 = (*mpND_x1);
            v1 = (*mpND_v1);
            x2 = (*mpND_x2);

            mLength = x1+x2;

            mNumX[0] = 1.0;
            mNumX[1] = 0.0;
            mNumX[2] = 0.0;
            mDenX[0] = k;
            mDenX[1] = B;
            mDenX[2] = m;
            mNumV[0] = 1.0;
            mNumV[1] = 0.0;
            mDenV[0] = B;
            mDenV[1] = m;

            mFilterX.initialize(mTimestep, mNumX, mDenX, f1-f2, -x1);
            mFilterV.initialize(mTimestep, mNumV, mDenV, f1-f2 - k*x2, -v1);

            //Print debug message if velocities do not match
            if((*mpND_v1) != -(*mpND_v2))
            {
                std::stringstream ss;
                ss << "Start velocities does not match, {" << getName() << "::" << mpP1->getPortName() <<
                        "} and {" << getName() << "::" << mpP2->getPortName() << "}.";
                this->addDebugMessage(ss.str());
            }
        }

        void simulateOneTimestep()
        {
            //Get variable values from nodes
            c1 = (*mpND_c1);
            Zx1 = (*mpND_Zx1);
            c2 = (*mpND_c2);
            Zx2 = (*mpND_Zx2);

            //Mass equations
            mDenX[1] = B+Zx1+Zx2;
            mDenV[0] = B+Zx1+Zx2;
            mFilterX.setDen(mDenX);
            mFilterV.setDen(mDenV);

            x2 = mFilterX.update(c1-c2);
            v2 = mFilterV.update(c1-c2 - k*x2);

//            if((mTime > 6) && (mTime < 6.01))
//            {
//                double apa = c1-c2;
//                stringstream ss;
//                ss << "t: " << mTime << "   c1-c2 = " << apa << "   v2 = " << v2;
//                addDebugMessage(ss.str());
//            }

            if(x2<xMin)
            {
                x2=xMin;
                v2=0.0;
                mFilterX.initializeValues(c1-c2, x2);
                mFilterV.initializeValues(c1-c2, 0.0);
            }
            if(x2>xMax)
            {
                x2=xMax;
                v2=0.0;
                mFilterX.initializeValues(c1-c2, x2);
                mFilterV.initializeValues(c1-c2, 0.0);
            }

            v1 = -v2;
            x1 = -x2 + mLength;
            f1 = c1 + Zx1*v1;
            f2 = c2 + Zx2*v2;

            //Write new values to nodes
            (*mpND_f1) = f1;
            (*mpND_x1) = x1;
            (*mpND_v1) = v1;
            (*mpND_f2) = f2;
            (*mpND_x2) = x2;
            (*mpND_v2) = v2;

//            if((mTime>.5) && (mTime<.5001))
//            {
//                std::stringstream ss;
//                ss << "mTime: " << mTime << "     c1-c2: " << c1-c2 << "    v2: " << v2 << std::endl;
//                addInfoMessage(ss.str());
//            }
        }
    };
}

#endif // MECHANICTRANSLATIONALMASS_HPP_INCLUDED

<|endoftext|>


<commit_before>#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Engine/SceneGraph/SceneGraphUi.h"
#include "Vajra/Framework/Core/Framework.h"
#include "Vajra/Framework/Logging/Logger.h"
#include "Vajra/Framework/OpenGL/OpenGLCounter/OpenGLCounter.h"
#include "Vajra/Framework/OpenGL/OpenGLWrapper/OpenGLWrapper.h"
#include "Vajra/Framework/OpenGL/ShaderSet/ShaderSet.h"
#include "Vajra/Framework/OpenGL/ShaderSet/ShaderSetCreationHelper/ShaderSetCreationHelper.h"
#include "Vajra/Utilities/Utilities.h"

OpenGLWrapper::OpenGLWrapper() {
	// Do not call init() here
}

OpenGLWrapper::~OpenGLWrapper() {
    this->destroy();
}

void OpenGLWrapper::PrintGLVersion() {
    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);
    printGLString("Extensions", GL_EXTENSIONS);
#ifndef PLATFORM_IOS
    // TODO [Implement] Get GLSL Version on ios
    printGLString("GLSL Version", GL_SHADING_LANGUAGE_VERSION);
#endif // PLATFORM_IOS
}

void OpenGLWrapper::CreateShaderSet(std::string shaderName, std::string shaderSpecificationName, bool hasTransperancy, bool isOverlay, bool isDepthPass) {

    ShaderSet* shaderSet = new ShaderSet(shaderSpecificationName, hasTransperancy, isOverlay, isDepthPass);

    VERIFY(this->shaderSets.find(shaderName) == this->shaderSets.end(), "Not duplicate shader set");
    this->shaderSets[shaderName] = shaderSet;

    if (this->currentShaderSet == nullptr) {
        this->currentShaderSet = shaderSet;
    }
}

void OpenGLWrapper::SetCurrentShaderSet(std::string shaderName) {
	VERIFY(this->shaderSets.find(shaderName) != this->shaderSets.end(), "Shader set %s has been created", shaderName.c_str());
    this->currentShaderSet = this->shaderSets[shaderName];
    //
    GLCALL(glUseProgram, this->currentShaderSet->GetShaderProgram());
}

ShaderSet* OpenGLWrapper::GetShaderSetByName(std::string shaderName) {
	auto it = this->shaderSets.find(shaderName);
	VERIFY(it != this->shaderSets.end(), "Shader set %s found", shaderName.c_str());
	return it->second;
}

void OpenGLWrapper::GetAllAvailableShaderNames(std::vector<std::string>& out_shaderNames) {
	// Return these in the loosely sorted order of opaque first, transperant next, ui last:

	// Consider only the shader sets that are completely opaque and are not an overlay:
	for (auto shaderSet_it = this->shaderSets.begin(); shaderSet_it != this->shaderSets.end(); ++shaderSet_it) {
		ShaderSet* shaderSet = shaderSet_it->second;
		if (!shaderSet->HasTransperancy() && !shaderSet->IsOverlay()) {
			out_shaderNames.push_back(shaderSet_it->first);
		}
	}
	// Consider only the shader sets that have transperancy and are not an overlay:
	for (auto shaderSet_it = this->shaderSets.begin(); shaderSet_it != this->shaderSets.end(); ++shaderSet_it) {
		ShaderSet* shaderSet = shaderSet_it->second;
		if (shaderSet->HasTransperancy() && !shaderSet->IsOverlay()) {
			out_shaderNames.push_back(shaderSet_it->first);
		}
	}
	// Consider only the shader sets that are overlays:
	for (auto shaderSet_it = this->shaderSets.begin(); shaderSet_it != this->shaderSets.end(); ++shaderSet_it) {
		ShaderSet* shaderSet = shaderSet_it->second;
		if (shaderSet->IsOverlay()) {
			out_shaderNames.push_back(shaderSet_it->first);
		}
	}

	ASSERT(out_shaderNames.size() == this->shaderSets.size(), "Did not miss any shader names");
}

void OpenGLWrapper::FreeUnusedGLResources() {
	this->freeUnusedGLBuffers();
	this->freeUnusedGLTextures();
}

void OpenGLWrapper::freeUnusedGLBuffers() {
	if (this->glBuffersToBeFreed.empty()) {
	} else {

		ENGINE->GetSceneGraph3D()->UnbindAllBuffers();
		ENGINE->GetSceneGraphUi()->UnbindAllBuffers();

		for (GLuint unusedGLBuffer : this->glBuffersToBeFreed) {
			VERIFY(glIsBuffer(unusedGLBuffer), "Buffer to be deleted is an opengl buffer object: %d", unusedGLBuffer);
			FRAMEWORK->GetLogger()->dbglog("\nDeleting gl buffer %d", unusedGLBuffer);
			GLCALL(glDeleteBuffers, 1, &unusedGLBuffer);
		}
		this->glBuffersToBeFreed.clear();
	}
}

void OpenGLWrapper::freeUnusedGLTextures() {
	if (this->glTexturesToBeFreed.empty()) {
	} else {

		for (GLuint unusedGLTexture : this->glTexturesToBeFreed) {
			VERIFY(glIsTexture(unusedGLTexture), "Handle to be deleted is an opengl texture object: %d", unusedGLTexture);
			FRAMEWORK->GetLogger()->dbglog("\nDeleting gl texture %d", unusedGLTexture);
			GLCALL(glDeleteTextures, 1, &unusedGLTexture);
		}
		this->glTexturesToBeFreed.clear();
	}
}

void OpenGLWrapper::init() {
    FRAMEWORK->GetLogger()->dbglog("In OpenGLWrapper::init()\n");

    this->glCounter = new OpenGLCounter();

    this->currentShaderSet = nullptr;

    ShaderSetCreationHelper::LoadPreprocessorVariables();

	this->CreateShaderSet("simshdr", "SimplestShader.shaderspec", false, false, false);
	this->CreateShaderSet("txrshdr", "TextureShader.shaderspec", false, false, false);
	this->CreateShaderSet("clrshdr", "ColorShader.shaderspec", true, false, false);
	this->CreateShaderSet("bncshdr", "BoneColorShader.shaderspec", false, false, false);
	this->CreateShaderSet("bntshdr", "BoneTextureShader.shaderspec", false, false, false);
	this->CreateShaderSet("sptshdr", "SpriteTextureShader.shaderspec", true, true, false);
	this->CreateShaderSet("spcshdr", "SpriteColorShader.shaderspec", false, false, false);
	this->CreateShaderSet("ustshdr", "UiSpriteTextureShader.shaderspec", true, true, false);
	this->CreateShaderSet("uscshdr", "UiSpriteColorShader.shaderspec", false, false, false);
	this->CreateShaderSet("prtshdr", "ParticleSystem.shaderspec", true, false, false);
	this->CreateShaderSet("wtrshdr", "Water.shaderspec", false, false, false);
	this->CreateShaderSet("fntshdr", "FontShader.shaderspec", true, true, false);
	//
	// Depth pass shaders:
	this->CreateShaderSet("dbtshdr", "DepthBoneTexturePass.shaderspec", false, false, true);
	this->CreateShaderSet("dbcshdr", "DepthBoneColorPass.shaderspec", false, false, true);
	this->CreateShaderSet("dpcshdr", "DepthColorPass.shaderspec", false, false, true);
	this->CreateShaderSet("dptshdr", "DepthTexturePass.shaderspec", false, false, true);
}

void OpenGLWrapper::destroy() {
	this->FreeUnusedGLResources();
	delete this->glCounter;
}

<commit_msg>Fix freeing gl buffers on the simulator.<commit_after>#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Engine/SceneGraph/SceneGraphUi.h"
#include "Vajra/Framework/Core/Framework.h"
#include "Vajra/Framework/Logging/Logger.h"
#include "Vajra/Framework/OpenGL/OpenGLCounter/OpenGLCounter.h"
#include "Vajra/Framework/OpenGL/OpenGLWrapper/OpenGLWrapper.h"
#include "Vajra/Framework/OpenGL/ShaderSet/ShaderSet.h"
#include "Vajra/Framework/OpenGL/ShaderSet/ShaderSetCreationHelper/ShaderSetCreationHelper.h"
#include "Vajra/Utilities/Utilities.h"

#ifdef __APPLE__
#include "TargetConditionals.h"
#endif

OpenGLWrapper::OpenGLWrapper() {
	// Do not call init() here
}

OpenGLWrapper::~OpenGLWrapper() {
    this->destroy();
}

void OpenGLWrapper::PrintGLVersion() {
    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);
    printGLString("Extensions", GL_EXTENSIONS);
#ifndef PLATFORM_IOS
    // TODO [Implement] Get GLSL Version on ios
    printGLString("GLSL Version", GL_SHADING_LANGUAGE_VERSION);
#endif // PLATFORM_IOS
}

void OpenGLWrapper::CreateShaderSet(std::string shaderName, std::string shaderSpecificationName, bool hasTransperancy, bool isOverlay, bool isDepthPass) {

    ShaderSet* shaderSet = new ShaderSet(shaderSpecificationName, hasTransperancy, isOverlay, isDepthPass);

    VERIFY(this->shaderSets.find(shaderName) == this->shaderSets.end(), "Not duplicate shader set");
    this->shaderSets[shaderName] = shaderSet;

    if (this->currentShaderSet == nullptr) {
        this->currentShaderSet = shaderSet;
    }
}

void OpenGLWrapper::SetCurrentShaderSet(std::string shaderName) {
	VERIFY(this->shaderSets.find(shaderName) != this->shaderSets.end(), "Shader set %s has been created", shaderName.c_str());
    this->currentShaderSet = this->shaderSets[shaderName];
    //
    GLCALL(glUseProgram, this->currentShaderSet->GetShaderProgram());
}

ShaderSet* OpenGLWrapper::GetShaderSetByName(std::string shaderName) {
	auto it = this->shaderSets.find(shaderName);
	VERIFY(it != this->shaderSets.end(), "Shader set %s found", shaderName.c_str());
	return it->second;
}

void OpenGLWrapper::GetAllAvailableShaderNames(std::vector<std::string>& out_shaderNames) {
	// Return these in the loosely sorted order of opaque first, transperant next, ui last:

	// Consider only the shader sets that are completely opaque and are not an overlay:
	for (auto shaderSet_it = this->shaderSets.begin(); shaderSet_it != this->shaderSets.end(); ++shaderSet_it) {
		ShaderSet* shaderSet = shaderSet_it->second;
		if (!shaderSet->HasTransperancy() && !shaderSet->IsOverlay()) {
			out_shaderNames.push_back(shaderSet_it->first);
		}
	}
	// Consider only the shader sets that have transperancy and are not an overlay:
	for (auto shaderSet_it = this->shaderSets.begin(); shaderSet_it != this->shaderSets.end(); ++shaderSet_it) {
		ShaderSet* shaderSet = shaderSet_it->second;
		if (shaderSet->HasTransperancy() && !shaderSet->IsOverlay()) {
			out_shaderNames.push_back(shaderSet_it->first);
		}
	}
	// Consider only the shader sets that are overlays:
	for (auto shaderSet_it = this->shaderSets.begin(); shaderSet_it != this->shaderSets.end(); ++shaderSet_it) {
		ShaderSet* shaderSet = shaderSet_it->second;
		if (shaderSet->IsOverlay()) {
			out_shaderNames.push_back(shaderSet_it->first);
		}
	}

	ASSERT(out_shaderNames.size() == this->shaderSets.size(), "Did not miss any shader names");
}

void OpenGLWrapper::FreeUnusedGLResources() {
	this->freeUnusedGLBuffers();
	this->freeUnusedGLTextures();
}

void OpenGLWrapper::freeUnusedGLBuffers() {
	// TODO [Hack] For some reason the simulator crashes in glDrawElements() when we do this
#ifdef __APPLE__
#if TARGET_IPHONE_SIMULATOR
	return;
#endif
#endif

	if (this->glBuffersToBeFreed.empty()) {
	} else {

		ENGINE->GetSceneGraph3D()->UnbindAllBuffers();
		ENGINE->GetSceneGraphUi()->UnbindAllBuffers();

		for (GLuint unusedGLBuffer : this->glBuffersToBeFreed) {
			VERIFY(glIsBuffer(unusedGLBuffer), "Buffer to be deleted is an opengl buffer object: %d", unusedGLBuffer);
			FRAMEWORK->GetLogger()->dbglog("\nDeleting gl buffer %d", unusedGLBuffer);
			GLCALL(glDeleteBuffers, 1, &unusedGLBuffer);
		}
		this->glBuffersToBeFreed.clear();
	}
}

void OpenGLWrapper::freeUnusedGLTextures() {
	if (this->glTexturesToBeFreed.empty()) {
	} else {

		for (GLuint unusedGLTexture : this->glTexturesToBeFreed) {
			VERIFY(glIsTexture(unusedGLTexture), "Handle to be deleted is an opengl texture object: %d", unusedGLTexture);
			FRAMEWORK->GetLogger()->dbglog("\nDeleting gl texture %d", unusedGLTexture);
			GLCALL(glDeleteTextures, 1, &unusedGLTexture);
		}
		this->glTexturesToBeFreed.clear();
	}
}

void OpenGLWrapper::init() {
    FRAMEWORK->GetLogger()->dbglog("In OpenGLWrapper::init()\n");

    this->glCounter = new OpenGLCounter();

    this->currentShaderSet = nullptr;

    ShaderSetCreationHelper::LoadPreprocessorVariables();

	this->CreateShaderSet("simshdr", "SimplestShader.shaderspec", false, false, false);
	this->CreateShaderSet("txrshdr", "TextureShader.shaderspec", false, false, false);
	this->CreateShaderSet("clrshdr", "ColorShader.shaderspec", true, false, false);
	this->CreateShaderSet("bncshdr", "BoneColorShader.shaderspec", false, false, false);
	this->CreateShaderSet("bntshdr", "BoneTextureShader.shaderspec", false, false, false);
	this->CreateShaderSet("sptshdr", "SpriteTextureShader.shaderspec", true, true, false);
	this->CreateShaderSet("spcshdr", "SpriteColorShader.shaderspec", false, false, false);
	this->CreateShaderSet("ustshdr", "UiSpriteTextureShader.shaderspec", true, true, false);
	this->CreateShaderSet("uscshdr", "UiSpriteColorShader.shaderspec", false, false, false);
	this->CreateShaderSet("prtshdr", "ParticleSystem.shaderspec", true, false, false);
	this->CreateShaderSet("wtrshdr", "Water.shaderspec", false, false, false);
	this->CreateShaderSet("fntshdr", "FontShader.shaderspec", true, true, false);
	//
	// Depth pass shaders:
	this->CreateShaderSet("dbtshdr", "DepthBoneTexturePass.shaderspec", false, false, true);
	this->CreateShaderSet("dbcshdr", "DepthBoneColorPass.shaderspec", false, false, true);
	this->CreateShaderSet("dpcshdr", "DepthColorPass.shaderspec", false, false, true);
	this->CreateShaderSet("dptshdr", "DepthTexturePass.shaderspec", false, false, true);
}

void OpenGLWrapper::destroy() {
	this->FreeUnusedGLResources();
	delete this->glCounter;
}

<|endoftext|>