<commit_before>#include <QLabel>
#include <QStringList>
#include <QListView>
#include <QStringListModel>
#include <QAction>
#include <QScopedPointer>

class LabelWithHistory : public QLabel {
    Q_OBJECT
    Q_PROPERTY(QString text READ text WRITE setText)
    QStringList m_history;
    QStringListModel m_model;
    QScopedPointer<QListView> m_view;
    void init() {
        QAction * showHistory = new QAction("History", this);
        connect(showHistory, SIGNAL(triggered()), SLOT(showHistory()));
        addAction(showHistory);
        setContextMenuPolicy(Qt::ActionsContextMenu);
    }
    void initView() {
        m_view.reset(new QListView);
        m_view->setModel(&m_model);
        m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
        m_view->setSelectionMode(QAbstractItemView::NoSelection);
        m_view->setWordWrap(true);
        m_view->setAlternatingRowColors(true);
    }
    Q_SLOT void showHistory() {
        if (! m_view) initView();
        if (m_view->isVisible()) return;
        m_model.setStringList(m_history);
        m_view->move(mapToGlobal(QPoint(0, height())));
        QModelIndex lastRow(m_model.index(m_history.size()-1));
        int bottomY = m_view->visualRect(lastRow).bottom();
        int widthHint = m_view->sizeHint().width();
        if (bottomY < m_view->sizeHint().height())
            m_view->resize(widthHint, bottomY + 1);
        m_view->show();
    }
    void hideEvent(QHideEvent *) {
        if (m_view) m_view->hide();
    }
public:
    LabelWithHistory(QWidget * parent = 0, Qt::WindowFlags f = 0) : QLabel(parent,f) {
        init();
    }
    LabelWithHistory(const QString & text, QWidget * parent = 0, Qt::WindowFlags f = 0) :
        QLabel(text, parent, f) { init(); }
    Q_SLOT void setText(const QString & text) {
        if (text == this->text()) return;
        m_history.prepend(text);
        if (m_view && m_view->isVisible())
            m_model.setStringList(m_history);
        QLabel::setText(text);
    }
};

#include <QApplication>
#include <QHBoxLayout>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QWidget w;
    QLayout * layout = new QHBoxLayout(&w);
    LabelWithHistory * label = new LabelWithHistory;
    QPushButton * button = new QPushButton("Add Item");
    QObject::connect(button, &QPushButton::clicked, [=](){
        static QString items[3] = { "Foo", "Bar", "Baz"};
        label->setText(items[qrand() % 3]);
    });
    layout->addWidget(label);
    layout->addWidget(button);

    label->setText("Foo");
    label->setText("Bar");
    label->setText("Baz");
    w.setMinimumSize(200, 50);
    w.show();
    return a.exec();
}

#include "main.moc"
<commit_msg>Slight cleanup/C++11-ization.<commit_after>#include <QLabel>
#include <QStringList>
#include <QListView>
#include <QStringListModel>
#include <QAction>

class LabelWithHistory : public QLabel {
   Q_OBJECT
   Q_PROPERTY(QString text READ text WRITE setText)
   QStringList m_history;
   QStringListModel* m_model;
   QListView* m_view;
   void init() {
      QAction * showHistory = new QAction("History", this);
      connect(showHistory, SIGNAL(triggered()), SLOT(showHistory()));
      addAction(showHistory);
      setContextMenuPolicy(Qt::ActionsContextMenu);
   }
   void initView() {
      m_model = new QStringListModel(this);
      m_view = new QListView(this);
      m_view->setWindowFlags(Qt::Window);
      m_view->setModel(m_model);
      m_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
      m_view->setSelectionMode(QAbstractItemView::NoSelection);
      m_view->setWordWrap(true);
      m_view->setAlternatingRowColors(true);
   }
   Q_SLOT void showHistory() {
      if (! m_view) initView();
      if (m_view->isVisible()) return;
      m_model->setStringList(m_history);
      m_view->move(mapToGlobal(QPoint(0, height())));
      QModelIndex lastRow(m_model->index(m_history.size()-1));
      int bottomY = m_view->visualRect(lastRow).bottom();
      int widthHint = m_view->sizeHint().width();
      if (bottomY < m_view->sizeHint().height())
         m_view->resize(widthHint, bottomY + 1);
      m_view->show();
   }
   void hideEvent(QHideEvent *) {
      if (m_view) m_view->hide();
   }
public:
   LabelWithHistory(QWidget * parent = 0, Qt::WindowFlags f = 0) :
      QLabel(parent,f), m_model(0), m_view(0) { init(); }
   LabelWithHistory(const QString & text, QWidget * parent = 0, Qt::WindowFlags f = 0) :
      QLabel(text, parent, f), m_model(0), m_view(0) { init(); }
   Q_SLOT void setText(const QString & text) {
      if (text == this->text()) return;
      m_history.prepend(text);
      if (m_view && m_view->isVisible())
         m_model->setStringList(m_history);
      QLabel::setText(text);
   }
};

#include <QApplication>
#include <QHBoxLayout>
#include <QPushButton>

int main(int argc, char ** argv)
{
   auto items = QStringList() << "Foo" << "Bar" << "Baz" << "Ban";
   QApplication a(argc, argv);
   QWidget w;
   QHBoxLayout layout(&w);
   LabelWithHistory label;
   QPushButton button("Add Item");
   QObject::connect(&button, &QPushButton::clicked, [&label, &items](){
      label.setText(items[qrand() % items.size()]);
   });
   layout.addWidget(&label);
   layout.addWidget(&button);
   for (auto item : items) label.setText(item);
   w.setMinimumSize(200, 50);
   w.show();
   return a.exec();
}

#include "main.moc"
<|endoftext|>


<commit_before>//===--- PrintASTTests.cpp ----------------------------------------- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "AST.h"
#include "Annotations.h"
#include "Protocol.h"
#include "SourceCode.h"
#include "TestTU.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "gmock/gmock.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-param-util-generated.h"

namespace clang {
namespace clangd {
namespace {

using ::testing::ElementsAreArray;

struct Case {
  const char *AnnotatedCode;
  std::vector<const char *> Expected;
};
class ASTUtils : public ::testing::Test,
                 public ::testing::WithParamInterface<Case> {};

TEST_P(ASTUtils, PrintTemplateArgs) {
  auto Pair = GetParam();
  Annotations Test(Pair.AnnotatedCode);
  auto AST = TestTU::withCode(Test.code()).build();
  struct Visitor : RecursiveASTVisitor<Visitor> {
    Visitor(std::vector<Position> Points) : Points(std::move(Points)) {}
    bool VisitNamedDecl(const NamedDecl *ND) {
      if (TemplateArgsAtPoints.size() == Points.size())
        return true;
      auto Pos = sourceLocToPosition(ND->getASTContext().getSourceManager(),
                                     ND->getLocation());
      if (Pos != Points[TemplateArgsAtPoints.size()])
        return true;
      TemplateArgsAtPoints.push_back(printTemplateSpecializationArgs(*ND));
      return true;
    }
    std::vector<std::string> TemplateArgsAtPoints;
    const std::vector<Position> Points;
  };
  Visitor V(Test.points());
  V.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
  EXPECT_THAT(V.TemplateArgsAtPoints, ElementsAreArray(Pair.Expected));
}

INSTANTIATE_TEST_CASE_P(ASTUtilsTests, ASTUtils,
                        ::testing::ValuesIn(std::vector<Case>({
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <> class ^Bar<double> {};)cpp",
                                {"<double>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <class T, class U,
                                  template<typename> class Z, int Q>
                                  struct Foo {};
                                  template struct ^Foo<int, bool, Bar, 8>;
                                  template <typename T>
                                  struct ^Foo<T *, T, Bar, 3> {};)cpp",
                                {"<int, bool, Bar, 8>", "<T *, T, Bar, 3>"}},
                            {
                                R"cpp(
                                  template <int ...> void Foz() {};
                                  template <> void ^Foz<3, 5, 8>() {};)cpp",
                                {"<3, 5, 8>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <template <class> class ...>
                                  class Aux {};
                                  template <> class ^Aux<Bar, Bar> {};
                                  template <template <class> T>
                                  class ^Aux<T, T> {};)cpp",
                                {"<Bar, Bar>", "<T, T>"}},
                            {
                                R"cpp(
                                  template <typename T> T var = 1234;
                                  template <> int ^var<int> = 1;)cpp",
                                {"<int>"}},
                            {
                                R"cpp(
                                  template <typename T> struct Foo;
                                  struct Bar { friend class Foo<int>; };
                                  template <> struct ^Foo<int> {};)cpp",
                                {"<int>"}},
                        })),);
} // namespace
} // namespace clangd
} // namespace clang
<commit_msg>[clangd] Don't include internal gtest header.<commit_after>//===--- PrintASTTests.cpp ----------------------------------------- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "AST.h"
#include "Annotations.h"
#include "Protocol.h"
#include "SourceCode.h"
#include "TestTU.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "gmock/gmock.h"
#include "gtest/gtest-param-test.h"
#include "gtest/gtest.h"

namespace clang {
namespace clangd {
namespace {

using ::testing::ElementsAreArray;

struct Case {
  const char *AnnotatedCode;
  std::vector<const char *> Expected;
};
class ASTUtils : public ::testing::Test,
                 public ::testing::WithParamInterface<Case> {};

TEST_P(ASTUtils, PrintTemplateArgs) {
  auto Pair = GetParam();
  Annotations Test(Pair.AnnotatedCode);
  auto AST = TestTU::withCode(Test.code()).build();
  struct Visitor : RecursiveASTVisitor<Visitor> {
    Visitor(std::vector<Position> Points) : Points(std::move(Points)) {}
    bool VisitNamedDecl(const NamedDecl *ND) {
      if (TemplateArgsAtPoints.size() == Points.size())
        return true;
      auto Pos = sourceLocToPosition(ND->getASTContext().getSourceManager(),
                                     ND->getLocation());
      if (Pos != Points[TemplateArgsAtPoints.size()])
        return true;
      TemplateArgsAtPoints.push_back(printTemplateSpecializationArgs(*ND));
      return true;
    }
    std::vector<std::string> TemplateArgsAtPoints;
    const std::vector<Position> Points;
  };
  Visitor V(Test.points());
  V.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
  EXPECT_THAT(V.TemplateArgsAtPoints, ElementsAreArray(Pair.Expected));
}

INSTANTIATE_TEST_CASE_P(ASTUtilsTests, ASTUtils,
                        ::testing::ValuesIn(std::vector<Case>({
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <> class ^Bar<double> {};)cpp",
                                {"<double>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <class T, class U,
                                  template<typename> class Z, int Q>
                                  struct Foo {};
                                  template struct ^Foo<int, bool, Bar, 8>;
                                  template <typename T>
                                  struct ^Foo<T *, T, Bar, 3> {};)cpp",
                                {"<int, bool, Bar, 8>", "<T *, T, Bar, 3>"}},
                            {
                                R"cpp(
                                  template <int ...> void Foz() {};
                                  template <> void ^Foz<3, 5, 8>() {};)cpp",
                                {"<3, 5, 8>"}},
                            {
                                R"cpp(
                                  template <class X> class Bar {};
                                  template <template <class> class ...>
                                  class Aux {};
                                  template <> class ^Aux<Bar, Bar> {};
                                  template <template <class> T>
                                  class ^Aux<T, T> {};)cpp",
                                {"<Bar, Bar>", "<T, T>"}},
                            {
                                R"cpp(
                                  template <typename T> T var = 1234;
                                  template <> int ^var<int> = 1;)cpp",
                                {"<int>"}},
                            {
                                R"cpp(
                                  template <typename T> struct Foo;
                                  struct Bar { friend class Foo<int>; };
                                  template <> struct ^Foo<int> {};)cpp",
                                {"<int>"}},
                        })),);
} // namespace
} // namespace clangd
} // namespace clang
<|endoftext|>


<commit_before>#include "scientistservice.h"

using namespace std;

//operator overloading functions for scientistSort.
bool sortByNameAsc (const Scientist &a, const Scientist &b)
{   // also makes the sort case insensitive
    string aName = a.getName(), bName = b.getName();
    transform(aName.begin(), aName.end(), aName.begin(), ::tolower);
    transform(bName.begin(), bName.end(), bName.begin(), ::tolower);
    return aName < bName;
}
bool sortByNameDesc(const Scientist &a, const Scientist &b)
{   // also makes the sort case insensitive
    string aName = a.getName(), bName = b.getName();
    transform(aName.begin(), aName.end(), aName.begin(), ::tolower);
    transform(bName.begin(), bName.end(), bName.begin(), ::tolower);
    return aName > bName;
}
bool sortByGender  (const Scientist &a, const Scientist &b) { return a.getGender() <  b.getGender(); }
bool sortByBirth   (const Scientist &a, const Scientist &b) { return a.getBirth()  <  b.getBirth();  }
bool sortByDeath   (const Scientist &a, const Scientist &b) { return a.getDeath()  <  b.getDeath();  }
bool sortByAge     (const Scientist &a, const Scientist &b) { return a.getAge()    <  b.getAge();    }

ScientistService::ScientistService()
{

}

vector<Scientist> ScientistService::getScientists()
{   // Uploads the list of scientists from file.
    DataAccess data;

    _scientists = data.loadScientists();

    return _scientists;
}

bool ScientistService::addScientist(string name, char gender, int birth, int death, int age)
{   // Adds a scientist to the list and updates the file.
    // returns true if adding succeded, false otherwise.
    Scientist scientist(name, gender, birth, death, age);
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        return false;
    }

    else
    {
        _scientists.push_back(scientist);
        data.saveScientists(_scientists);
        return true;
    }
}

bool ScientistService::removeScientist(string name)
{   // removes a scientist with that name from the vector.
    // returns true if removeing succeded, false otherwise.
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        Scientist toRemove = findScientistByName(name).at(0);

        _scientists.erase(remove(_scientists.begin(), _scientists.end(), toRemove), _scientists.end());

        data.saveScientists(_scientists);

        return true;
    }

    return false;
}

void ScientistService::scientistSort(int sortType)
{    // Sort by parameter, 1 = name(A-Z), 2 = name(Z-A), 3 = gender, 4 = birth, 5 = death, 6 = age
     // change to switch case?

    DataAccess data;

    if (sortType == 1)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameAsc);
    }
    else if (sortType == 2)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameDesc);
    }
    else if (sortType == 3)
    {
        sort(_scientists.begin(), _scientists.end(), sortByGender);
    }
    else if (sortType == 4)
    {
        sort(_scientists.begin(), _scientists.end(), sortByBirth);
    }
    else if (sortType == 5)
    {
        sort(_scientists.begin(), _scientists.end(), sortByDeath);
    }
    else if (sortType == 6)
    {
        sort(_scientists.begin(), _scientists.end(), sortByAge);
    }

    data.saveScientists(_scientists);
}

vector<Scientist> ScientistService::findScientistByName(string name)
{   // Returns all scientists with the full name specified.
    // TODO leita eftir part úr nafni?
    vector<Scientist> scientist;
    string databaseName;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        databaseName = _scientists[i].getName();
        transform(databaseName.begin(), databaseName.end(), databaseName.begin(), ::tolower);
        transform(name.begin(), name.end(), name.begin(), ::tolower);

        if (databaseName == name)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByGender(char gender)
{   // Returns all scientists of that gender.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getGender() == gender)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirth(int birth)
{   // Returns all scientists born that year.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() == birth)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirthRange(int birth1, int birth2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(birth1 > birth2)
    {
        temp = birth1;
        birth1 = birth2;
        birth2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() >= birth1 && _scientists[i].getBirth() <= birth2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeath(int death)
{   // Returns all scientists that died that year, or death = 0 for still alive..
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() == death)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeathRange(int death1, int death2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(death1 > death2)
    {
        temp = death1;
        death1 = death2;
        death2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() >= death1 && _scientists[i].getDeath() <= death2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAge(int age)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() == age)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAgeRange(int age1, int age2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(age1 > age2)
    {
        temp = age1;
        age1 = age2;
        age2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() >= age1 && _scientists[i].getAge() <= age2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

<commit_msg>now possible to search using only a part of a name<commit_after>#include "scientistservice.h"

using namespace std;

//operator overloading functions for scientistSort.
bool sortByNameAsc (const Scientist &a, const Scientist &b)
{   // also makes the sort case insensitive
    string aName = a.getName(), bName = b.getName();
    transform(aName.begin(), aName.end(), aName.begin(), ::tolower);
    transform(bName.begin(), bName.end(), bName.begin(), ::tolower);
    return aName < bName;
}
bool sortByNameDesc(const Scientist &a, const Scientist &b)
{   // also makes the sort case insensitive
    string aName = a.getName(), bName = b.getName();
    transform(aName.begin(), aName.end(), aName.begin(), ::tolower);
    transform(bName.begin(), bName.end(), bName.begin(), ::tolower);
    return aName > bName;
}
bool sortByGender  (const Scientist &a, const Scientist &b) { return a.getGender() <  b.getGender(); }
bool sortByBirth   (const Scientist &a, const Scientist &b) { return a.getBirth()  <  b.getBirth();  }
bool sortByDeath   (const Scientist &a, const Scientist &b) { return a.getDeath()  <  b.getDeath();  }
bool sortByAge     (const Scientist &a, const Scientist &b) { return a.getAge()    <  b.getAge();    }

ScientistService::ScientistService()
{

}

vector<Scientist> ScientistService::getScientists()
{   // Uploads the list of scientists from file.
    DataAccess data;

    _scientists = data.loadScientists();

    return _scientists;
}

bool ScientistService::addScientist(string name, char gender, int birth, int death, int age)
{   // Adds a scientist to the list and updates the file.
    // returns true if adding succeded, false otherwise.
    Scientist scientist(name, gender, birth, death, age);
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        return false;
    }

    else
    {
        _scientists.push_back(scientist);
        data.saveScientists(_scientists);
        return true;
    }
}

bool ScientistService::removeScientist(string name)
{   // removes a scientist with that name from the vector.
    // returns true if removeing succeded, false otherwise.
    DataAccess data;

    if (findScientistByName(name).size() > 0)
    {
        Scientist toRemove = findScientistByName(name).at(0);

        _scientists.erase(remove(_scientists.begin(), _scientists.end(), toRemove), _scientists.end());

        data.saveScientists(_scientists);

        return true;
    }

    return false;
}

void ScientistService::scientistSort(int sortType)
{    // Sort by parameter, 1 = name(A-Z), 2 = name(Z-A), 3 = gender, 4 = birth, 5 = death, 6 = age

    DataAccess data;

    if (sortType == 1)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameAsc);
    }
    else if (sortType == 2)
    {
        sort(_scientists.begin(), _scientists.end(), sortByNameDesc);
    }
    else if (sortType == 3)
    {
        sort(_scientists.begin(), _scientists.end(), sortByGender);
    }
    else if (sortType == 4)
    {
        sort(_scientists.begin(), _scientists.end(), sortByBirth);
    }
    else if (sortType == 5)
    {
        sort(_scientists.begin(), _scientists.end(), sortByDeath);
    }
    else if (sortType == 6)
    {
        sort(_scientists.begin(), _scientists.end(), sortByAge);
    }

    data.saveScientists(_scientists);
}

vector<Scientist> ScientistService::findScientistByName(string name)
{   // Returns all scientists with the full name specified.

    vector<Scientist> scientist;
    string databaseName;
    int pos = -1;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        databaseName = _scientists[i].getName();
        transform(databaseName.begin(), databaseName.end(), databaseName.begin(), ::tolower);
        transform(name.begin(), name.end(), name.begin(), ::tolower);

        pos = databaseName.find(name);

        if (pos > -1)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByGender(char gender)
{   // Returns all scientists of that gender.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getGender() == gender)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirth(int birth)
{   // Returns all scientists born that year.
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() == birth)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByBirthRange(int birth1, int birth2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(birth1 > birth2)
    {
        temp = birth1;
        birth1 = birth2;
        birth2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getBirth() >= birth1 && _scientists[i].getBirth() <= birth2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeath(int death)
{   // Returns all scientists that died that year, or death = 0 for still alive..
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() == death)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByDeathRange(int death1, int death2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(death1 > death2)
    {
        temp = death1;
        death1 = death2;
        death2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getDeath() >= death1 && _scientists[i].getDeath() <= death2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAge(int age)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;

    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() == age)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

vector<Scientist> ScientistService::findScientistByAgeRange(int age1, int age2)
{   // Returns all scientists with same age as parameter ( int age )
    vector<Scientist> scientist;
    int temp;
    if(age1 > age2)
    {
        temp = age1;
        age1 = age2;
        age2 = temp;
    }
    for (size_t i = 0; i < _scientists.size(); i++)
    {
        if (_scientists[i].getAge() >= age1 && _scientists[i].getAge() <= age2)
        {
            scientist.push_back(_scientists[i]);
        }
    }

    return scientist;
}

<|endoftext|>


<commit_before>//===- lib/Driver/LinkerInvocation.cpp - Linker Invocation ----------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Driver/LinkerInvocation.h"

#include "lld/Core/InputFiles.h"
#include "lld/Core/Resolver.h"
#include "lld/Driver/Target.h"

#include "llvm/Support/raw_ostream.h"

using namespace lld;

void LinkerInvocation::operator()() {
    // Create target.
    std::unique_ptr<Target> target(Target::create(_options));

    if (!target) {
      llvm::errs() << "Failed to create target for " << _options._target
                   << "\n";
      return;
    }

    // Read inputs
    InputFiles inputs;
    for (const auto &input : _options._input) {
      auto reader = target->getReader(input);
      if (error_code ec = reader) {
        llvm::errs() << "Failed to get reader for: " << input.getPath() << ": "
                     << ec.message() << "\n";
        return;
      }

      auto buffer = input.getBuffer();
      if (error_code ec = buffer) {
        llvm::errs() << "Failed to read file: " << input.getPath() << ": "
                     << ec.message() << "\n";
        return;
      }

      std::vector<std::unique_ptr<File>> files;
      if (llvm::error_code ec = reader->readFile(
            buffer->getBufferIdentifier(), files)) {
        llvm::errs() << "Failed to read file: " << input.getPath() << ": "
                     << ec.message() << "\n";
        return;
      }
      inputs.appendFiles(files);
    }

    ResolverOptions ro;
    Resolver resolver(ro, inputs);
    resolver.resolve();
    File &merged = resolver.resultFile();

    auto writer = target->getWriter();
    if (error_code ec = writer) {
      llvm::errs() << "Failed to get writer: " << ec.message() << ".\n";
      return;
    }

    if (error_code ec = writer->writeFile(merged, _options._outputPath))
      llvm::errs() << "Failed to write file: " << ec.message() << "\n";
  }
<commit_msg>[Driver] Error on undefined.<commit_after>//===- lib/Driver/LinkerInvocation.cpp - Linker Invocation ----------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lld/Driver/LinkerInvocation.h"

#include "lld/Core/InputFiles.h"
#include "lld/Core/Resolver.h"
#include "lld/Driver/Target.h"

#include "llvm/Support/raw_ostream.h"

using namespace lld;

void LinkerInvocation::operator()() {
    // Create target.
    std::unique_ptr<Target> target(Target::create(_options));

    if (!target) {
      llvm::errs() << "Failed to create target for " << _options._target
                   << "\n";
      return;
    }

    // Read inputs
    InputFiles inputs;
    for (const auto &input : _options._input) {
      auto reader = target->getReader(input);
      if (error_code ec = reader) {
        llvm::errs() << "Failed to get reader for: " << input.getPath() << ": "
                     << ec.message() << "\n";
        return;
      }

      auto buffer = input.getBuffer();
      if (error_code ec = buffer) {
        llvm::errs() << "Failed to read file: " << input.getPath() << ": "
                     << ec.message() << "\n";
        return;
      }

      std::vector<std::unique_ptr<File>> files;
      if (llvm::error_code ec = reader->readFile(
            buffer->getBufferIdentifier(), files)) {
        llvm::errs() << "Failed to read file: " << input.getPath() << ": "
                     << ec.message() << "\n";
        return;
      }
      inputs.appendFiles(files);
    }

    struct Blah : ResolverOptions {
      Blah()
        : ResolverOptions() {
        _undefinesAreErrors = true;
      }
    } ro;
    Resolver resolver(ro, inputs);
    resolver.resolve();
    File &merged = resolver.resultFile();

    auto writer = target->getWriter();
    if (error_code ec = writer) {
      llvm::errs() << "Failed to get writer: " << ec.message() << ".\n";
      return;
    }

    if (error_code ec = writer->writeFile(merged, _options._outputPath))
      llvm::errs() << "Failed to write file: " << ec.message() << "\n";
  }
<|endoftext|>


<commit_before>#include <babylon/inspector/components/sceneexplorer/scene_graph_component.h>

#include <imgui.h>

#include <babylon/cameras/camera.h>
#include <babylon/engine/node.h>
#include <babylon/engine/scene.h>
#include <babylon/lights/light.h>
#include <babylon/materials/material.h>
#include <babylon/mesh/mesh.h>

#include <babylon/imgui/imgui_utils.h>

#include <babylon/inspector/components/global_state.h>
#include <babylon/inspector/components/sceneexplorer/entities/camera_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/light_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/material_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/mesh_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/scene_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/tree_item_expandable_header_component.h>
#include <babylon/inspector/components/sceneexplorer/tree_item_root_header_component.h>

namespace BABYLON {

SceneGraphComponent::SceneGraphComponent(const SceneGraphComponentProps& iProps)
    : props{iProps}
    , _sceneGraph{_createSceneTreeItem(iProps.scene)}
    , _initialized{false}
{
  _treeItemComparator = [](const TreeItem& a, const TreeItem& b) -> bool {
    const auto labelA = std::string(a.label);
    const auto labelB = std::string(b.label);
    return labelA < labelB;
  };
}

SceneGraphComponent::SceneGraphComponent::~SceneGraphComponent()
{
}

void SceneGraphComponent::reinitialize()
{
  // Nodes
  const auto& rootNodes = props.scene->rootNodes;
  auto& nodesTreeItem   = _sceneGraph.root().addChild(_createTreeItem("Nodes"));
  for (const auto& rootNode : rootNodes) {
    _initializeNodesTreeItem(nodesTreeItem, rootNode->getAsNodePtr());
  }
  // Materials
  const auto& materials = props.scene->materials;
  auto& materialsTreeItem
    = _sceneGraph.root().addChild(_createTreeItem("Materials"));
  for (const auto& material : materials) {
    _initializeTreeItem(materialsTreeItem, material);
  }
  // Textures
  _sceneGraph.root().addChild(_createTreeItem("Textures"));
  // Rendering pipelines
  _sceneGraph.root().addChild(_createTreeItem("Rendering pipelines"));

  // Set the offset
  Tree<TreeItem>::recursive_visit(
    _sceneGraph.root(), [this](TreeNode<TreeItem>& node) {
      node.data().offset = _calculateOffset(node.depth());
    });

  _initialized = true;
}

void SceneGraphComponent::DeSelectAll(TreeNode<TreeItem>& node)
{
  {
    Tree<TreeItem>::recursive_visit(
      node, [](TreeNode<TreeItem>& node) { node.data().isSelected = false; });
  }
}

void SceneGraphComponent::_initializeNodesTreeItem(
  TreeNode<TreeItem>& parentTreeItem, const NodePtr& node)
{
  // Create TreeItem
  auto& treeItem = parentTreeItem.addChildSorted(_createNodeTreeItem(node),
                                                 _treeItemComparator);

  // Create Children
  for (const auto& child : node->getChildren()) {
    if (child) {
      _initializeNodesTreeItem(treeItem, child);
    }
  }
}

TreeItem SceneGraphComponent::_createTreeItem(const char* label)
{
  TreeItem treeItem;
  sprintf(treeItem.label, "%s", label);

  return treeItem;
}

TreeItem
SceneGraphComponent::_createMaterialTreeItem(const MaterialPtr& material)
{
  TreeItem treeItem;
  std::string label;
  size_t key;

  if (material) {
    IMaterialTreeItemComponentProps props;
    props.material     = material;
    label              = props.material->name;
    key                = props.material->uniqueId;
    treeItem.component = std::make_shared<MaterialTreeItemComponent>(props);
  }

  sprintf(treeItem.label, "%s", label.c_str());
  sprintf(treeItem.key, "%ld", key);

  return treeItem;
}

TreeItem SceneGraphComponent::_createNodeTreeItem(const NodePtr& node)
{
  TreeItem treeItem;
  std::string label;
  size_t key;

  if (node) {
    if (String::contains(node->getClassName(), "Bone")) {
    }
    else if (String::contains(node->getClassName(), "Camera")) {
      ICameraTreeItemComponentProps props;
      props.camera       = std::static_pointer_cast<Camera>(node);
      label              = props.camera->name;
      key                = props.camera->uniqueId;
      treeItem.component = std::make_shared<CameraTreeItemComponent>(props);
    }
    else if (String::contains(node->getClassName(), "Light")) {
      ILightTreeItemComponentProps props;
      props.light        = std::static_pointer_cast<Light>(node);
      label              = props.light->name;
      key                = props.light->uniqueId;
      treeItem.component = std::make_shared<LightTreeItemComponent>(props);
    }
    else if (String::contains(node->getClassName(), "Mesh")) {
      auto mesh = std::static_pointer_cast<Mesh>(node);
      if (mesh->getTotalVertices() > 0) {
        IMeshTreeItemComponentProps props;
        props.mesh         = std::static_pointer_cast<Mesh>(node);
        label              = props.mesh->name;
        key                = props.mesh->uniqueId;
        treeItem.component = std::make_shared<MeshTreeItemComponent>(props);
      }
    }
  }

  sprintf(treeItem.label, "%s", label.c_str());
  sprintf(treeItem.key, "%ld", key);

  return treeItem;
}

TreeItem SceneGraphComponent::_createSceneTreeItem(Scene* scene)
{
  TreeItem treeItem;

  if (scene) {
    ISceneTreeItemComponentProps props;
    props.scene = scene;
    sprintf(treeItem.key, "%s", "Scene");
    treeItem.component = std::make_shared<SceneTreeItemComponent>(props);
  }

  return treeItem;
}

float SceneGraphComponent::_calculateOffset(unsigned int nodeLevel)
{
  if (nodeLevel < 2) {
    return ImGui::IconSize;
  }

  return (10.f * (nodeLevel - 2.f + 0.5f));
}

void SceneGraphComponent::notifySelectionChange(EntityInfo& entityInfo)
{
  if (props.globalState->onSelectionChangedObservable.hasObservers()) {
    props.globalState->onSelectionChangedObservable.notifyObservers(
      &entityInfo);
  }
}

void SceneGraphComponent::_renderSelectableTreeItem(TreeNode<TreeItem>& node)
{
  auto& nodeData = node.data();

  if (nodeData.component) {
    if (node.isRoot()) {
      ImGui::Unindent(nodeData.offset);
    }
    // Make tree item selectable
    ImGui::PushID(nodeData.key);
    if (ImGui::Selectable("", nodeData.isSelected)) {
      DeSelectAll(_sceneGraph.root());
      nodeData.isSelected = !nodeData.isSelected;
      if (nodeData.isSelected) {
        notifySelectionChange(nodeData.component->entityInfo);
      }
    }
    ImGui::PopID();
    // Expandable children
    ImGui::SetItemAllowOverlap();
    if (!node.isRoot() && node.arity() > 0) {
      ImGui::PushID("TreeItemChildren");
      ImGui::TextWrapped("%s", nodeData.isExpanded ? faMinus : faPlus);
      ImGui::PopID();
      if (ImGui::IsItemHovered()) {
        ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
      }
      if (ImGui::IsItemClicked(0)) {
        // Switch expanded state
        nodeData.isExpanded = !nodeData.isExpanded;
      }
      ImGui::SameLine();
    }
    ImGui::SameLine();
    // Render specialized tree item
    ImGui::SetItemAllowOverlap();
    nodeData.component->render();
    if (node.isRoot()) {
      ImGui::Indent(nodeData.offset);
    }
  }
}

void SceneGraphComponent::_renderChildren(TreeNode<TreeItem>& node)
{
  // Render the specialized tree item selectable component
  _renderSelectableTreeItem(node);

  auto& nodeData = node.data();
  if (node.arity() == 0 || !nodeData.isExpanded) {
    return;
  }

  ImGui::Indent(nodeData.offset);
  for (const auto& child : node.children()) {
    child->data().mustExpand = nodeData.mustExpand;
    _renderChildren(*child);
  }
  ImGui::Unindent(nodeData.offset);
}

void SceneGraphComponent::_renderTree(TreeNode<TreeItem>& node)
{
  auto& nodeData = node.data();

  if (node.depth() == 1) {
    ImGui::Indent(nodeData.offset);
    if (node.isLeaf()) { // Render group containers
      TreeItemRootHeaderComponent::render(nodeData.label);
    }
    else if (!nodeData.isExpanded) { // Render expandable header
      TreeItemExpandableHeaderComponent::render(
        nodeData.isExpanded, nodeData.label, nodeData.mustExpand);
    }
    else {
      // Render expandable header
      TreeItemExpandableHeaderComponent::render(
        nodeData.isExpanded, nodeData.label, nodeData.mustExpand);
      for (const auto& child : node.children()) {
        child->data().mustExpand = nodeData.mustExpand;
      }
      // Render tree item specialized components
      _renderChildren(node);
    }
    ImGui::Unindent(nodeData.offset);
  }
  else {
    // Render the scene tree item selectable component
    _renderSelectableTreeItem(node);

    // Render the scene graph
    for (const auto& child : node.children()) {
      child->data().mustExpand = nodeData.mustExpand;
      _renderTree(*child);
    }
  }
}

void SceneGraphComponent::render()
{
  if (!_initialized) {
    reinitialize();
  }

  _renderTree(_sceneGraph.root());
}

} // namespace BABYLON
<commit_msg>scene_graph_component.cpp : initialize potentialy uninitialized size_t vars<commit_after>#include <babylon/inspector/components/sceneexplorer/scene_graph_component.h>

#include <imgui.h>

#include <babylon/cameras/camera.h>
#include <babylon/engine/node.h>
#include <babylon/engine/scene.h>
#include <babylon/lights/light.h>
#include <babylon/materials/material.h>
#include <babylon/mesh/mesh.h>

#include <babylon/imgui/imgui_utils.h>

#include <babylon/inspector/components/global_state.h>
#include <babylon/inspector/components/sceneexplorer/entities/camera_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/light_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/material_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/mesh_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/entities/scene_tree_item_component.h>
#include <babylon/inspector/components/sceneexplorer/tree_item_expandable_header_component.h>
#include <babylon/inspector/components/sceneexplorer/tree_item_root_header_component.h>

namespace BABYLON {

SceneGraphComponent::SceneGraphComponent(const SceneGraphComponentProps& iProps)
    : props{iProps}
    , _sceneGraph{_createSceneTreeItem(iProps.scene)}
    , _initialized{false}
{
  _treeItemComparator = [](const TreeItem& a, const TreeItem& b) -> bool {
    const auto labelA = std::string(a.label);
    const auto labelB = std::string(b.label);
    return labelA < labelB;
  };
}

SceneGraphComponent::SceneGraphComponent::~SceneGraphComponent()
{
}

void SceneGraphComponent::reinitialize()
{
  // Nodes
  const auto& rootNodes = props.scene->rootNodes;
  auto& nodesTreeItem   = _sceneGraph.root().addChild(_createTreeItem("Nodes"));
  for (const auto& rootNode : rootNodes) {
    _initializeNodesTreeItem(nodesTreeItem, rootNode->getAsNodePtr());
  }
  // Materials
  const auto& materials = props.scene->materials;
  auto& materialsTreeItem
    = _sceneGraph.root().addChild(_createTreeItem("Materials"));
  for (const auto& material : materials) {
    _initializeTreeItem(materialsTreeItem, material);
  }
  // Textures
  _sceneGraph.root().addChild(_createTreeItem("Textures"));
  // Rendering pipelines
  _sceneGraph.root().addChild(_createTreeItem("Rendering pipelines"));

  // Set the offset
  Tree<TreeItem>::recursive_visit(
    _sceneGraph.root(), [this](TreeNode<TreeItem>& node) {
      node.data().offset = _calculateOffset(node.depth());
    });

  _initialized = true;
}

void SceneGraphComponent::DeSelectAll(TreeNode<TreeItem>& node)
{
  {
    Tree<TreeItem>::recursive_visit(
      node, [](TreeNode<TreeItem>& node) { node.data().isSelected = false; });
  }
}

void SceneGraphComponent::_initializeNodesTreeItem(
  TreeNode<TreeItem>& parentTreeItem, const NodePtr& node)
{
  // Create TreeItem
  auto& treeItem = parentTreeItem.addChildSorted(_createNodeTreeItem(node),
                                                 _treeItemComparator);

  // Create Children
  for (const auto& child : node->getChildren()) {
    if (child) {
      _initializeNodesTreeItem(treeItem, child);
    }
  }
}

TreeItem SceneGraphComponent::_createTreeItem(const char* label)
{
  TreeItem treeItem;
  sprintf(treeItem.label, "%s", label);

  return treeItem;
}

TreeItem
SceneGraphComponent::_createMaterialTreeItem(const MaterialPtr& material)
{
  TreeItem treeItem;
  std::string label;
  size_t key = 0;

  if (material) {
    IMaterialTreeItemComponentProps props;
    props.material     = material;
    label              = props.material->name;
    key                = props.material->uniqueId;
    treeItem.component = std::make_shared<MaterialTreeItemComponent>(props);
  }

  sprintf(treeItem.label, "%s", label.c_str());
  sprintf(treeItem.key, "%ld", key);

  return treeItem;
}

TreeItem SceneGraphComponent::_createNodeTreeItem(const NodePtr& node)
{
  TreeItem treeItem;
  std::string label;
  size_t key = 0;

  if (node) {
    if (String::contains(node->getClassName(), "Bone")) {
    }
    else if (String::contains(node->getClassName(), "Camera")) {
      ICameraTreeItemComponentProps props;
      props.camera       = std::static_pointer_cast<Camera>(node);
      label              = props.camera->name;
      key                = props.camera->uniqueId;
      treeItem.component = std::make_shared<CameraTreeItemComponent>(props);
    }
    else if (String::contains(node->getClassName(), "Light")) {
      ILightTreeItemComponentProps props;
      props.light        = std::static_pointer_cast<Light>(node);
      label              = props.light->name;
      key                = props.light->uniqueId;
      treeItem.component = std::make_shared<LightTreeItemComponent>(props);
    }
    else if (String::contains(node->getClassName(), "Mesh")) {
      auto mesh = std::static_pointer_cast<Mesh>(node);
      if (mesh->getTotalVertices() > 0) {
        IMeshTreeItemComponentProps props;
        props.mesh         = std::static_pointer_cast<Mesh>(node);
        label              = props.mesh->name;
        key                = props.mesh->uniqueId;
        treeItem.component = std::make_shared<MeshTreeItemComponent>(props);
      }
    }
  }

  sprintf(treeItem.label, "%s", label.c_str());
  sprintf(treeItem.key, "%ld", key);

  return treeItem;
}

TreeItem SceneGraphComponent::_createSceneTreeItem(Scene* scene)
{
  TreeItem treeItem;

  if (scene) {
    ISceneTreeItemComponentProps props;
    props.scene = scene;
    sprintf(treeItem.key, "%s", "Scene");
    treeItem.component = std::make_shared<SceneTreeItemComponent>(props);
  }

  return treeItem;
}

float SceneGraphComponent::_calculateOffset(unsigned int nodeLevel)
{
  if (nodeLevel < 2) {
    return ImGui::IconSize;
  }

  return (10.f * (nodeLevel - 2.f + 0.5f));
}

void SceneGraphComponent::notifySelectionChange(EntityInfo& entityInfo)
{
  if (props.globalState->onSelectionChangedObservable.hasObservers()) {
    props.globalState->onSelectionChangedObservable.notifyObservers(
      &entityInfo);
  }
}

void SceneGraphComponent::_renderSelectableTreeItem(TreeNode<TreeItem>& node)
{
  auto& nodeData = node.data();

  if (nodeData.component) {
    if (node.isRoot()) {
      ImGui::Unindent(nodeData.offset);
    }
    // Make tree item selectable
    ImGui::PushID(nodeData.key);
    if (ImGui::Selectable("", nodeData.isSelected)) {
      DeSelectAll(_sceneGraph.root());
      nodeData.isSelected = !nodeData.isSelected;
      if (nodeData.isSelected) {
        notifySelectionChange(nodeData.component->entityInfo);
      }
    }
    ImGui::PopID();
    // Expandable children
    ImGui::SetItemAllowOverlap();
    if (!node.isRoot() && node.arity() > 0) {
      ImGui::PushID("TreeItemChildren");
      ImGui::TextWrapped("%s", nodeData.isExpanded ? faMinus : faPlus);
      ImGui::PopID();
      if (ImGui::IsItemHovered()) {
        ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
      }
      if (ImGui::IsItemClicked(0)) {
        // Switch expanded state
        nodeData.isExpanded = !nodeData.isExpanded;
      }
      ImGui::SameLine();
    }
    ImGui::SameLine();
    // Render specialized tree item
    ImGui::SetItemAllowOverlap();
    nodeData.component->render();
    if (node.isRoot()) {
      ImGui::Indent(nodeData.offset);
    }
  }
}

void SceneGraphComponent::_renderChildren(TreeNode<TreeItem>& node)
{
  // Render the specialized tree item selectable component
  _renderSelectableTreeItem(node);

  auto& nodeData = node.data();
  if (node.arity() == 0 || !nodeData.isExpanded) {
    return;
  }

  ImGui::Indent(nodeData.offset);
  for (const auto& child : node.children()) {
    child->data().mustExpand = nodeData.mustExpand;
    _renderChildren(*child);
  }
  ImGui::Unindent(nodeData.offset);
}

void SceneGraphComponent::_renderTree(TreeNode<TreeItem>& node)
{
  auto& nodeData = node.data();

  if (node.depth() == 1) {
    ImGui::Indent(nodeData.offset);
    if (node.isLeaf()) { // Render group containers
      TreeItemRootHeaderComponent::render(nodeData.label);
    }
    else if (!nodeData.isExpanded) { // Render expandable header
      TreeItemExpandableHeaderComponent::render(
        nodeData.isExpanded, nodeData.label, nodeData.mustExpand);
    }
    else {
      // Render expandable header
      TreeItemExpandableHeaderComponent::render(
        nodeData.isExpanded, nodeData.label, nodeData.mustExpand);
      for (const auto& child : node.children()) {
        child->data().mustExpand = nodeData.mustExpand;
      }
      // Render tree item specialized components
      _renderChildren(node);
    }
    ImGui::Unindent(nodeData.offset);
  }
  else {
    // Render the scene tree item selectable component
    _renderSelectableTreeItem(node);

    // Render the scene graph
    for (const auto& child : node.children()) {
      child->data().mustExpand = nodeData.mustExpand;
      _renderTree(*child);
    }
  }
}

void SceneGraphComponent::render()
{
  if (!_initialized) {
    reinitialize();
  }

  _renderTree(_sceneGraph.root());
}

} // namespace BABYLON
<|endoftext|>


<commit_before>#include "cluster.h"
#include "cluster_store.h"
#include "key_range.h"
#include "node.h"
#include "spliter.h"
#include "node.h"
#include "../ssdb/ssdb.h"
#include "../util/log.h"

static const int MOVE_BATCH_SIZE = 2;

Cluster::Cluster(){
	this->last_node_id = 0;
	this->db = NULL;
	this->store = NULL;
}

Cluster::~Cluster(){
	delete store;
}

int Cluster::init(SSDB *db){
	this->db = db;
	this->store = new ClusterStore(this);
	this->store->load_node_list();
	return 0;
}

Node* Cluster::connect_node(const std::string &ip, int port){
	Node *node = new Node();
	if(node->init(ip, port) == -1){
		delete node;
		return NULL;
	}
	log_info("connected to [%s:%d]", node->ip.c_str(), node->port);
	return node;
}

void Cluster::print_node_list(){
	std::map<std::string, Node *>::iterator it;
	for(it = kv_node_list.begin(); it != kv_node_list.end(); it++){
		Node *n = it->second;
		printf("%s\n", n->str().c_str());
	}
}

Node* Cluster::get_node(int id){
	std::map<int, Node *>::iterator it;
	it = kv_nodes_by_id.find(id);
	if(it != kv_nodes_by_id.end()){
		return it->second;
	}
	return NULL;
}

int Cluster::add_kv_node(Node *node){
	if(!node->id){
		// TODO: 在别的地方分配 id
		node->id = ++last_node_id;
	}
	log_debug("%s: %s", __FUNCTION__, node->str().c_str());
	std::map<std::string, Node *>::iterator it;
	for(it = kv_node_list.begin(); it != kv_node_list.end(); it++){
		Node *n = it->second;
		if(node->kv_range.check_overlapped(n->kv_range)){
			log_error("overlapped with %s!", n->str().c_str());
			return -1;
		}
	}

	// log
	if(store->save_node(node) == -1){
		return -1;
	}

	kv_node_list[node->kv_range.start] = node;
	kv_nodes_by_id[node->id] = node;
	return 0;
}

int Cluster::del_kv_node(Node *node){
	log_debug("%s: %s", __FUNCTION__, node->str().c_str());
	if(store->del_node(node) == -1){
		return -1;
	}
	kv_node_list.erase(node->kv_range.start);
	kv_nodes_by_id.erase(node->id);
	return 1;
}

int64_t Cluster::split_kv_node(Node *src, Node *dst){
	log_debug("%s: %s => %s", __FUNCTION__, src->str().c_str(), dst->str().c_str());
	dst->kv_range = KeyRange();
	int64_t ret = _migrate_kv_data(src, dst);
	// 没有数据可分裂也返回错误
	return ret > 0? ret : -1;
}

int64_t Cluster::migrate_kv_data(Node *src, Node *dst){
	log_debug("%s: %s => %s", __FUNCTION__, src->str().c_str(), dst->str().c_str());
	return _migrate_kv_data(src, dst);
}

int64_t Cluster::_migrate_kv_data(Node *src, Node *dst){
	Spliter spliter(this->db, src, dst);
	int64_t size = spliter.move_some(MOVE_BATCH_SIZE);
	if(size == -1){
		log_error("error!");
		return -1;
	}
	if(size == 0){
		log_info("no data to move, end.");
		return 0;
	}
	log_debug("moved: %" PRId64 " bytes", size);

	int ret;
	ret = del_kv_node(src);
	if(ret == -1){
		log_error("error!");
		return -1;
	}
	if(dst->id){
		ret = del_kv_node(dst);
		if(ret == -1){
			log_error("error!");
			return -1;
		}
	}

	ret = spliter.finish();
	if(ret == -1){
		log_error("error!");
		return -1;
	}

	if(!src->kv_range.empty()){
		ret = add_kv_node(src);
		if(ret == -1){
			log_error("error!");
			return -1;
		}
	}

	if(!dst->kv_range.empty()){
		ret = add_kv_node(dst);
		if(ret == -1){
			log_error("error!");
			return -1;
		}
	}

	return size;
}
<commit_msg>update<commit_after>#include "cluster.h"
#include "cluster_store.h"
#include "key_range.h"
#include "node.h"
#include "spliter.h"
#include "node.h"
#include "../ssdb/ssdb.h"
#include "../util/log.h"

static const int MOVE_BATCH_SIZE = 2;

Cluster::Cluster(){
	this->last_node_id = 0;
	this->db = NULL;
	this->store = NULL;
}

Cluster::~Cluster(){
	delete store;
}

int Cluster::init(SSDB *db){
	this->db = db;
	this->store = new ClusterStore(this);
	this->store->load_node_list();
	return 0;
}

Node* Cluster::connect_node(const std::string &ip, int port){
	Node *node = new Node();
	if(node->init(ip, port) == -1){
		delete node;
		return NULL;
	}
	log_info("connected to [%s:%d]", node->ip.c_str(), node->port);
	return node;
}

void Cluster::print_node_list(){
	std::map<std::string, Node *>::iterator it;
	for(it = kv_node_list.begin(); it != kv_node_list.end(); it++){
		Node *n = it->second;
		printf("%s\n", n->str().c_str());
	}
}

Node* Cluster::get_node(int id){
	std::map<int, Node *>::iterator it;
	it = kv_nodes_by_id.find(id);
	if(it != kv_nodes_by_id.end()){
		return it->second;
	}
	return NULL;
}

int Cluster::add_kv_node(Node *node){
	if(!node->id){
		// TODO: 在别的地方分配 id
		node->id = ++last_node_id;
	}
	log_debug("%s: %s", __FUNCTION__, node->str().c_str());
	std::map<std::string, Node *>::iterator it;
	for(it = kv_node_list.begin(); it != kv_node_list.end(); it++){
		Node *n = it->second;
		if(node->kv_range.check_overlapped(n->kv_range)){
			log_error("overlapped with %s!", n->str().c_str());
			return -1;
		}
	}

	// log
	if(store->save_node(node) == -1){
		return -1;
	}

	kv_node_list[node->kv_range.start] = node;
	kv_nodes_by_id[node->id] = node;
	return 0;
}

int Cluster::del_kv_node(Node *node){
	log_debug("%s: %s", __FUNCTION__, node->str().c_str());
	if(store->del_node(node) == -1){
		return -1;
	}
	kv_node_list.erase(node->kv_range.start);
	kv_nodes_by_id.erase(node->id);
	return 1;
}

int64_t Cluster::split_kv_node(Node *src, Node *dst){
	log_debug("%s: %s => %s", __FUNCTION__, src->str().c_str(), dst->str().c_str());
	dst->kv_range = KeyRange();
	int64_t ret = _migrate_kv_data(src, dst);
	// 没有数据可分裂也返回错误
	return ret > 0? ret : -1;
}

int64_t Cluster::migrate_kv_data(Node *src, Node *dst){
	log_debug("%s: %s => %s", __FUNCTION__, src->str().c_str(), dst->str().c_str());
	return _migrate_kv_data(src, dst);
}

int64_t Cluster::_migrate_kv_data(Node *src, Node *dst){
	Spliter spliter(this->db, src, dst);
	int64_t size = spliter.move_some(MOVE_BATCH_SIZE);
	if(size == -1){
		log_error("error!");
		return -1;
	}
	if(size == 0){
		log_info("no data to move, end.");
		return 0;
	}
	log_debug("moved: %" PRId64 " bytes", size);

	int ret;
	if(del_kv_node(src) == -1){
		log_error("error!");
		return -1;
	}
	if(dst->id){
		if(del_kv_node(dst) == -1){
			log_error("error!");
			return -1;
		}
	}
	if(spliter.finish() == -1){
		log_error("error!");
		return -1;
	}
	if(!src->kv_range.empty()){
		if(add_kv_node(src) == -1){
			log_error("error!");
			return -1;
		}
	}
	if(!dst->kv_range.empty()){
		if(add_kv_node(dst) == -1){
			log_error("error!");
			return -1;
		}
	}
	return size;
}
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName      :    NFCLogicClassModule.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2012-12-15
//    @Module           :    NFCLogicClassModule
//
// -------------------------------------------------------------------------

////#include "stdafx.h"
#include <algorithm>
#include "NFConfigPlugin.h"
#include "NFCElementInfoModule.h"
#include "NFCLogicClassModule.h"

////

bool NFCLogicClassModule::Init()
{
    m_pElementInfoModule = dynamic_cast<NFCElementInfoModule*>(pPluginManager->FindModule("NFCElementInfoModule"));

    assert(NULL != m_pElementInfoModule);

    Load();

    return true;
}

bool NFCLogicClassModule::Shut()
{
    NFILogicClass* pLogicClass = First();
    while (pLogicClass)
    {
        pLogicClass->ClearAll();

        delete pLogicClass;
        pLogicClass = NULL;
        pLogicClass = Next();
    }

    ClearAll();

    return true;
}

NFCLogicClassModule::NFCLogicClassModule(NFIPluginManager* p)
{
    mnPropertyIndex = GetTickCount() % 10 + 1;
    pPluginManager = p;
    msConfigFileName = "../../NFDataCfg/Struct/LogicClass.xml";
}

NFCLogicClassModule::~NFCLogicClassModule()
{

}

TDATA_TYPE NFCLogicClassModule::ComputerType(const char* pstrTypeName, NFIValueList::TData& var)
{
    if (0 == strcmp(pstrTypeName, "int"))
    {
        var.nType = TDATA_INT;
        var.variantData = (int)0;
        return TDATA_INT;
    }
    else if (0 == strcmp(pstrTypeName, "float"))
    {
        var.nType = TDATA_FLOAT;
        var.variantData = (float)0.0f;
        return TDATA_FLOAT;
    }
    else if (0 == strcmp(pstrTypeName, "string"))
    {
        var.nType = TDATA_STRING;
        var.variantData = NULL_STR;
        return TDATA_STRING;
    }
    else if (0 == strcmp(pstrTypeName, "double"))
    {
        var.nType = TDATA_DOUBLE;
        var.variantData = (double)0.0f;
        return TDATA_DOUBLE;
    }
    else if (0 == strcmp(pstrTypeName, "object"))
    {
        var.nType = TDATA_OBJECT;
        var.variantData = NFINT64(0);
        return TDATA_OBJECT;
    }

    return TDATA_UNKNOWN;
}

bool NFCLogicClassModule::AddPropertys(rapidxml::xml_node<>* pPropertyRootNode, NFCLogicClass* pClass)
{
    for (rapidxml::xml_node<>* pPropertyNode = pPropertyRootNode->first_node(); pPropertyNode; pPropertyNode = pPropertyNode->next_sibling())
    {
        if (pPropertyNode)
        {
            const char* strPropertyName = pPropertyNode->first_attribute("Id")->value();
            if (pClass->GetPropertyManager()->GetElement(strPropertyName))
            {
                //error
                NFASSERT(0, strPropertyName, __FILE__, __FUNCTION__);
                continue;
            }

            const char* pstrType = pPropertyNode->first_attribute("Type")->value();
            const char* pstrPublic = pPropertyNode->first_attribute("Public")->value();
            const char* pstrPrivate = pPropertyNode->first_attribute("Private")->value();
            const char* pstrPropertyIndex = pPropertyNode->first_attribute("Index")->value();

            const char* pstrSave = pPropertyNode->first_attribute("Save")->value();
            const char* pstrRelationValue = NULL_STR.c_str();
            if (pPropertyNode->first_attribute("RelationValue"))
            {
                pstrRelationValue = pPropertyNode->first_attribute("RelationValue")->value();
            }

            bool bPublic = boost::lexical_cast<int>(pstrPublic);
            bool bPrivate = boost::lexical_cast<int>(pstrPrivate);
            bool bSave = boost::lexical_cast<int>(pstrSave);
            int nIndex = boost::lexical_cast<int>(pstrPropertyIndex);

            if (bPublic || bPrivate)
            {
                ++mnPropertyIndex;

                nIndex = mnPropertyIndex;
                mxPropertyIndexMap.insert(std::map<std::string, int>::value_type(strPropertyName, mnPropertyIndex));
            }

            NFIValueList::TData varProperty;
            if (TDATA_UNKNOWN == ComputerType(pstrType, varProperty))
            {
                //std::cout << "error:" << pClass->GetTypeName() << "  " << pClass->GetInstancePath() << ": " << strPropertyName << " type error!!!" << std::endl;

                NFASSERT(0, strPropertyName, __FILE__, __FUNCTION__);
            }

            //printf( " Property:%s[%s]\n", pstrPropertyName, pstrType );

            pClass->GetPropertyManager()->AddProperty(0, strPropertyName,  varProperty.nType, bPublic,  bPrivate, bSave, nIndex, pstrRelationValue);
        }
    }

    return true;
}

bool NFCLogicClassModule::AddRecords(rapidxml::xml_node<>* pRecordRootNode, NFCLogicClass* pClass)
{
    for (rapidxml::xml_node<>* pRecordNode = pRecordRootNode->first_node(); pRecordNode;  pRecordNode = pRecordNode->next_sibling())
    {
        if (pRecordNode)
        {
            const char* pstrRecordName = pRecordNode->first_attribute("Id")->value();

            if (pClass->GetRecordManager()->GetElement(pstrRecordName))
            {
                //error
                //file << pClass->mstrType << ":" << pstrRecordName << std::endl;
                //assert(0);
                NFASSERT(0, pstrRecordName, __FILE__, __FUNCTION__);
                continue;
            }

            const char* pstrRow = pRecordNode->first_attribute("Row")->value();
            const char* pstrCol = pRecordNode->first_attribute("Col")->value();

            const char* pstrPublic = pRecordNode->first_attribute("Public")->value();
            const char* pstrPrivate = pRecordNode->first_attribute("Private")->value();
            const char* pstrSave = pRecordNode->first_attribute("Save")->value();
            const char* pstrIndex = pRecordNode->first_attribute("Index")->value();

            bool bPublic = boost::lexical_cast<int>(pstrPublic);
            bool bPrivate = boost::lexical_cast<int>(pstrPrivate);
            bool bSave = boost::lexical_cast<int>(pstrSave);
            int nIndex = boost::lexical_cast<int>(pstrIndex);

            NFCValueList recordVar;
            NFCValueList recordKey;
            NFCValueList recordDesc;
            NFCValueList recordTag;
            NFCValueList recordRelation;
            for (rapidxml::xml_node<>* recordColNode = pRecordNode->first_node(); recordColNode;  recordColNode = recordColNode->next_sibling())
            {
                //const char* pstrColName = recordColNode->first_attribute( "Id" )->value();
                NFIValueList::TData TData;
                const char* pstrColType = recordColNode->first_attribute("Type")->value();
                if (TDATA_UNKNOWN == ComputerType(pstrColType, TData))
                {
                    //assert(0);
                    NFASSERT(0, pstrRecordName, __FILE__, __FUNCTION__);
                }

                recordVar.Append(TData);
                //////////////////////////////////////////////////////////////////////////
                if (recordColNode->first_attribute("Key") != NULL)
                {
                    const char* pstrKey = recordColNode->first_attribute("Key")->value();
                    bool bKey = boost::lexical_cast<int>(pstrKey);
                    if (bKey)
                    {
                        recordKey.AddInt(1);
                    }
                    else
                    {
                        recordKey.AddInt(0);
                    }
                }

                if (recordColNode->first_attribute("Tag") != NULL)
                {
                    const char* pstrTag = recordColNode->first_attribute("Tag")->value();
                    recordTag.AddString(pstrTag);
                }
                else
                {
                    recordTag.AddString("");
                }

                if (recordColNode->first_attribute("RelateRecord") != NULL)
                {
                    std::string strRelationRecord = recordColNode->first_attribute("RelatedRecord")->value();
                    recordRelation.AddString(strRelationRecord.c_str());
                }
                else
                {
                    recordRelation.AddString("");
                }

                //////////////////////////////////////////////////////////////////////////
                if (recordColNode->first_attribute("Desc"))
                {
                    const char* pstrColDesc = recordColNode->first_attribute("Desc")->value();
                    recordDesc.AddString(pstrColDesc);
                }
                else
                {
                    recordDesc.AddString("");
                }

                //////////////////////////////////////////////////////////////////////////
            }

            pClass->GetRecordManager()->AddRecord(0, pstrRecordName, recordVar, recordKey, recordDesc, recordTag, recordRelation, atoi(pstrRow), bPublic, bPrivate, bSave, nIndex);
        }
    }

    return true;
}

bool NFCLogicClassModule::AddComponents( rapidxml::xml_node<>* pComponentRootNode, NFCLogicClass* pClass )
{
    for (rapidxml::xml_node<>* pComponentNode = pComponentRootNode->first_node(); pComponentNode; pComponentNode = pComponentNode->next_sibling())
    {
        if (pComponentNode)
        {
            const char* strComponentName = pComponentNode->first_attribute("Name")->value();
            const char* strLanguage = pComponentNode->first_attribute("Language")->value();
            const char* strEnable = pComponentNode->first_attribute("Enable")->value();
            bool bEnable = boost::lexical_cast<int>(strEnable);
            if(bEnable)
            {
                if (pClass->GetComponentManager()->GetElement(strComponentName))
                {
                    //error
                    NFASSERT(0, strComponentName, __FILE__, __FUNCTION__);
                    continue;
                }

                pClass->GetComponentManager()->AddComponent(std::string(strComponentName), std::string(strLanguage));
            }
        }
    }

    return true;
}

bool NFCLogicClassModule::AddClassInclude(const char* pstrClassFilePath, NFCLogicClass* pClass)
{
    if (pClass->Find(pstrClassFilePath))
    {
        return false;
    }

    rapidxml::file<> fdoc(pstrClassFilePath);
    //std::cout << fdoc.data() << std::endl;
    rapidxml::xml_document<>  doc;
    doc.parse<0>(fdoc.data());

    //support for unlimited layer class inherits
    rapidxml::xml_node<>* root = doc.first_node();

    rapidxml::xml_node<>* pRropertyRootNode = root->first_node("Propertys");
    if (pRropertyRootNode)
    {
        AddPropertys(pRropertyRootNode, pClass);
    }

    //////////////////////////////////////////////////////////////////////////
    //and record
    rapidxml::xml_node<>* pRecordRootNode = root->first_node("Records");
    if (pRecordRootNode)
    {
        AddRecords(pRecordRootNode, pClass);
    }

    rapidxml::xml_node<>* pComponentRootNode = root->first_node("Components");
    if (pComponentRootNode)
    {
        AddComponents(pComponentRootNode, pClass);
    }

    //pClass->mvIncludeFile.push_back( pstrClassFilePath );
    //and include file
    rapidxml::xml_node<>* pIncludeRootNode = root->first_node("Includes");
    if (pIncludeRootNode)
    {
        for (rapidxml::xml_node<>* includeNode = pIncludeRootNode->first_node(); includeNode; includeNode = includeNode->next_sibling())
        {
            const char* pstrIncludeFile = includeNode->first_attribute("Id")->value();
            //std::vector<std::string>::iterator it = std::find( pClass->mvIncludeFile.begin(), pClass->mvIncludeFile..end(), pstrIncludeFile );

            if (AddClassInclude(pstrIncludeFile, pClass))
            {
                pClass->Add(pstrIncludeFile);
            }
        }
    }

    return true;
}

bool NFCLogicClassModule::AddClass(const char* pstrClassFilePath, NFCLogicClass* pClass)
{

    std::ofstream file;
    file.open("./Log/NFLogicClass.log");

    NFILogicClass* pParent = pClass->GetParent();
    while (pParent)
    {
        //inherited some properties form class of parent
        std::string strFileName = "";
        pParent->First(strFileName);
        while (!strFileName.empty())
        {
            if (pClass->Find(strFileName))
            {
                strFileName.clear();
                continue;
            }

            if (AddClassInclude(strFileName.c_str(), pClass))
            {
                pClass->Add(strFileName);
            }

            strFileName.clear();
            pParent->Next(strFileName);
        }

        pParent = pParent->GetParent();
    }

    //////////////////////////////////////////////////////////////////////////
    if (AddClassInclude(pstrClassFilePath, pClass))
    {
        pClass->Add(pstrClassFilePath);
    }

    file.close();

    return true;
}

bool NFCLogicClassModule::AddClass(const std::string& strClassName, const std::string& strParentName)
{
    NFILogicClass* pParentClass = GetElement(strParentName);
    NFILogicClass* pChildClass = GetElement(strClassName);
    if (!pChildClass)
    {
        pChildClass = new NFCLogicClass(strClassName);
        AddElement(strClassName, pChildClass);
        //pChildClass = CreateElement( strClassName );

        pChildClass->SetTypeName("");
        pChildClass->SetInstancePath("");

        if (pParentClass)
        {
            pChildClass->SetParent(pParentClass);
        }

    }

    return true;
}

bool NFCLogicClassModule::Load(rapidxml::xml_node<>* attrNode, NFCLogicClass* pParentClass)
{

    const char* pstrLogicClassName = attrNode->first_attribute("Id")->value();
    const char* pstrType = attrNode->first_attribute("Type")->value();
    const char* pstrPath = attrNode->first_attribute("Path")->value();
    const char* pstrInstancePath = attrNode->first_attribute("InstancePath")->value();

    //printf( "-----------------------------------------------------\n");
    //printf( "%s:\n", pstrLogicClassName );

    NFCLogicClass* pClass = new NFCLogicClass(pstrLogicClassName);
    AddElement(pstrLogicClassName, pClass);
    pClass->SetParent(pParentClass);
    pClass->SetTypeName(pstrType);
    pClass->SetInstancePath(pstrInstancePath);

    AddClass(pstrPath, pClass);

    for (rapidxml::xml_node<>* pDataNode = attrNode->first_node(); pDataNode; pDataNode = pDataNode->next_sibling())
    {
        //her children
        Load(pDataNode, pClass);
    }
    //printf( "-----------------------------------------------------\n");
    return true;
}

bool NFCLogicClassModule::Load()
{
    rapidxml::file<> fdoc(msConfigFileName.c_str());
    //std::cout << fdoc.data() << std::endl;
    rapidxml::xml_document<>  doc;
    doc.parse<0>(fdoc.data());

    //support for unlimited layer class inherits
    rapidxml::xml_node<>* root = doc.first_node();
    for (rapidxml::xml_node<>* attrNode = root->first_node(); attrNode; attrNode = attrNode->next_sibling())
    {
        Load(attrNode, NULL);
    }

    m_pElementInfoModule->Load();
    return true;
}

bool NFCLogicClassModule::Save()
{
    return true;
}

NFIPropertyManager* NFCLogicClassModule::GetClassPropertyManager(const std::string& strClassName)
{
    NFILogicClass* pClass = GetElement(strClassName);
    if (pClass)
    {
        return pClass->GetPropertyManager();
    }

    return NULL;
}

NFIRecordManager* NFCLogicClassModule::GetClassRecordManager(const std::string& strClassName)
{
    NFILogicClass* pClass = GetElement(strClassName);
    if (pClass)
    {
        return pClass->GetRecordManager();
    }

    return NULL;
}

NFIComponentManager* NFCLogicClassModule::GetClassComponentManager( const std::string& strClassName )
{
    NFILogicClass* pClass = GetElement(strClassName);
    if (pClass)
    {
        return pClass->GetComponentManager();
    }

    return NULL;
}

bool NFCLogicClassModule::Clear()
{
	return true;

}<commit_msg>modify boost::lexical_cast error type<commit_after>// -------------------------------------------------------------------------
//    @FileName      :    NFCLogicClassModule.h
//    @Author           :    LvSheng.Huang
//    @Date             :    2012-12-15
//    @Module           :    NFCLogicClassModule
//
// -------------------------------------------------------------------------

////#include "stdafx.h"
#include <algorithm>
#include "NFConfigPlugin.h"
#include "NFCElementInfoModule.h"
#include "NFCLogicClassModule.h"

////

bool NFCLogicClassModule::Init()
{
    m_pElementInfoModule = dynamic_cast<NFCElementInfoModule*>(pPluginManager->FindModule("NFCElementInfoModule"));

    assert(NULL != m_pElementInfoModule);

    Load();

    return true;
}

bool NFCLogicClassModule::Shut()
{
    NFILogicClass* pLogicClass = First();
    while (pLogicClass)
    {
        pLogicClass->ClearAll();

        delete pLogicClass;
        pLogicClass = NULL;
        pLogicClass = Next();
    }

    ClearAll();

    return true;
}

NFCLogicClassModule::NFCLogicClassModule(NFIPluginManager* p)
{
    mnPropertyIndex = GetTickCount() % 10 + 1;
    pPluginManager = p;
    msConfigFileName = "../../NFDataCfg/Struct/LogicClass.xml";
}

NFCLogicClassModule::~NFCLogicClassModule()
{

}

TDATA_TYPE NFCLogicClassModule::ComputerType(const char* pstrTypeName, NFIValueList::TData& var)
{
    if (0 == strcmp(pstrTypeName, "int"))
    {
        var.nType = TDATA_INT;
        var.variantData = (int)0;
        return TDATA_INT;
    }
    else if (0 == strcmp(pstrTypeName, "float"))
    {
        var.nType = TDATA_FLOAT;
        var.variantData = (float)0.0f;
        return TDATA_FLOAT;
    }
    else if (0 == strcmp(pstrTypeName, "string"))
    {
        var.nType = TDATA_STRING;
        var.variantData = NULL_STR;
        return TDATA_STRING;
    }
    else if (0 == strcmp(pstrTypeName, "double"))
    {
        var.nType = TDATA_DOUBLE;
        var.variantData = (double)0.0f;
        return TDATA_DOUBLE;
    }
    else if (0 == strcmp(pstrTypeName, "object"))
    {
        var.nType = TDATA_OBJECT;
        var.variantData = NFINT64(0);
        return TDATA_OBJECT;
    }

    return TDATA_UNKNOWN;
}

bool NFCLogicClassModule::AddPropertys(rapidxml::xml_node<>* pPropertyRootNode, NFCLogicClass* pClass)
{
    for (rapidxml::xml_node<>* pPropertyNode = pPropertyRootNode->first_node(); pPropertyNode; pPropertyNode = pPropertyNode->next_sibling())
    {
        if (pPropertyNode)
        {
            const char* strPropertyName = pPropertyNode->first_attribute("Id")->value();
            if (pClass->GetPropertyManager()->GetElement(strPropertyName))
            {
                //error
                NFASSERT(0, strPropertyName, __FILE__, __FUNCTION__);
                continue;
            }

            const char* pstrType = pPropertyNode->first_attribute("Type")->value();
            const char* pstrPublic = pPropertyNode->first_attribute("Public")->value();
            const char* pstrPrivate = pPropertyNode->first_attribute("Private")->value();
            const char* pstrPropertyIndex = pPropertyNode->first_attribute("Index")->value();

            const char* pstrSave = pPropertyNode->first_attribute("Save")->value();
            const char* pstrRelationValue = NULL_STR.c_str();
            if (pPropertyNode->first_attribute("RelationValue"))
            {
                pstrRelationValue = pPropertyNode->first_attribute("RelationValue")->value();
            }

            bool bPublic = boost::lexical_cast<bool>(pstrPublic);
            bool bPrivate = boost::lexical_cast<bool>(pstrPrivate);
            bool bSave = boost::lexical_cast<bool>(pstrSave);
            int nIndex = boost::lexical_cast<int>(pstrPropertyIndex);

            if (bPublic || bPrivate)
            {
                ++mnPropertyIndex;

                nIndex = mnPropertyIndex;
                mxPropertyIndexMap.insert(std::map<std::string, int>::value_type(strPropertyName, mnPropertyIndex));
            }

            NFIValueList::TData varProperty;
            if (TDATA_UNKNOWN == ComputerType(pstrType, varProperty))
            {
                //std::cout << "error:" << pClass->GetTypeName() << "  " << pClass->GetInstancePath() << ": " << strPropertyName << " type error!!!" << std::endl;

                NFASSERT(0, strPropertyName, __FILE__, __FUNCTION__);
            }

            //printf( " Property:%s[%s]\n", pstrPropertyName, pstrType );

            pClass->GetPropertyManager()->AddProperty(0, strPropertyName,  varProperty.nType, bPublic,  bPrivate, bSave, nIndex, pstrRelationValue);
        }
    }

    return true;
}

bool NFCLogicClassModule::AddRecords(rapidxml::xml_node<>* pRecordRootNode, NFCLogicClass* pClass)
{
    for (rapidxml::xml_node<>* pRecordNode = pRecordRootNode->first_node(); pRecordNode;  pRecordNode = pRecordNode->next_sibling())
    {
        if (pRecordNode)
        {
            const char* pstrRecordName = pRecordNode->first_attribute("Id")->value();

            if (pClass->GetRecordManager()->GetElement(pstrRecordName))
            {
                //error
                //file << pClass->mstrType << ":" << pstrRecordName << std::endl;
                //assert(0);
                NFASSERT(0, pstrRecordName, __FILE__, __FUNCTION__);
                continue;
            }

            const char* pstrRow = pRecordNode->first_attribute("Row")->value();
            const char* pstrCol = pRecordNode->first_attribute("Col")->value();

            const char* pstrPublic = pRecordNode->first_attribute("Public")->value();
            const char* pstrPrivate = pRecordNode->first_attribute("Private")->value();
            const char* pstrSave = pRecordNode->first_attribute("Save")->value();
            const char* pstrIndex = pRecordNode->first_attribute("Index")->value();

            bool bPublic = boost::lexical_cast<bool>(pstrPublic);
            bool bPrivate = boost::lexical_cast<bool>(pstrPrivate);
            bool bSave = boost::lexical_cast<bool>(pstrSave);
            int nIndex = boost::lexical_cast<int>(pstrIndex);

            NFCValueList recordVar;
            NFCValueList recordKey;
            NFCValueList recordDesc;
            NFCValueList recordTag;
            NFCValueList recordRelation;
            for (rapidxml::xml_node<>* recordColNode = pRecordNode->first_node(); recordColNode;  recordColNode = recordColNode->next_sibling())
            {
                //const char* pstrColName = recordColNode->first_attribute( "Id" )->value();
                NFIValueList::TData TData;
                const char* pstrColType = recordColNode->first_attribute("Type")->value();
                if (TDATA_UNKNOWN == ComputerType(pstrColType, TData))
                {
                    //assert(0);
                    NFASSERT(0, pstrRecordName, __FILE__, __FUNCTION__);
                }

                recordVar.Append(TData);
                //////////////////////////////////////////////////////////////////////////
                if (recordColNode->first_attribute("Key") != NULL)
                {
                    const char* pstrKey = recordColNode->first_attribute("Key")->value();
                    bool bKey = boost::lexical_cast<int>(pstrKey);
                    if (bKey)
                    {
                        recordKey.AddInt(1);
                    }
                    else
                    {
                        recordKey.AddInt(0);
                    }
                }

                if (recordColNode->first_attribute("Tag") != NULL)
                {
                    const char* pstrTag = recordColNode->first_attribute("Tag")->value();
                    recordTag.AddString(pstrTag);
                }
                else
                {
                    recordTag.AddString("");
                }

                if (recordColNode->first_attribute("RelateRecord") != NULL)
                {
                    std::string strRelationRecord = recordColNode->first_attribute("RelatedRecord")->value();
                    recordRelation.AddString(strRelationRecord.c_str());
                }
                else
                {
                    recordRelation.AddString("");
                }

                //////////////////////////////////////////////////////////////////////////
                if (recordColNode->first_attribute("Desc"))
                {
                    const char* pstrColDesc = recordColNode->first_attribute("Desc")->value();
                    recordDesc.AddString(pstrColDesc);
                }
                else
                {
                    recordDesc.AddString("");
                }

                //////////////////////////////////////////////////////////////////////////
            }

            pClass->GetRecordManager()->AddRecord(0, pstrRecordName, recordVar, recordKey, recordDesc, recordTag, recordRelation, atoi(pstrRow), bPublic, bPrivate, bSave, nIndex);
        }
    }

    return true;
}

bool NFCLogicClassModule::AddComponents( rapidxml::xml_node<>* pComponentRootNode, NFCLogicClass* pClass )
{
    for (rapidxml::xml_node<>* pComponentNode = pComponentRootNode->first_node(); pComponentNode; pComponentNode = pComponentNode->next_sibling())
    {
        if (pComponentNode)
        {
            const char* strComponentName = pComponentNode->first_attribute("Name")->value();
            const char* strLanguage = pComponentNode->first_attribute("Language")->value();
            const char* strEnable = pComponentNode->first_attribute("Enable")->value();
            bool bEnable = boost::lexical_cast<int>(strEnable);
            if(bEnable)
            {
                if (pClass->GetComponentManager()->GetElement(strComponentName))
                {
                    //error
                    NFASSERT(0, strComponentName, __FILE__, __FUNCTION__);
                    continue;
                }

                pClass->GetComponentManager()->AddComponent(std::string(strComponentName), std::string(strLanguage));
            }
        }
    }

    return true;
}

bool NFCLogicClassModule::AddClassInclude(const char* pstrClassFilePath, NFCLogicClass* pClass)
{
    if (pClass->Find(pstrClassFilePath))
    {
        return false;
    }

    rapidxml::file<> fdoc(pstrClassFilePath);
    //std::cout << fdoc.data() << std::endl;
    rapidxml::xml_document<>  doc;
    doc.parse<0>(fdoc.data());

    //support for unlimited layer class inherits
    rapidxml::xml_node<>* root = doc.first_node();

    rapidxml::xml_node<>* pRropertyRootNode = root->first_node("Propertys");
    if (pRropertyRootNode)
    {
        AddPropertys(pRropertyRootNode, pClass);
    }

    //////////////////////////////////////////////////////////////////////////
    //and record
    rapidxml::xml_node<>* pRecordRootNode = root->first_node("Records");
    if (pRecordRootNode)
    {
        AddRecords(pRecordRootNode, pClass);
    }

    rapidxml::xml_node<>* pComponentRootNode = root->first_node("Components");
    if (pComponentRootNode)
    {
        AddComponents(pComponentRootNode, pClass);
    }

    //pClass->mvIncludeFile.push_back( pstrClassFilePath );
    //and include file
    rapidxml::xml_node<>* pIncludeRootNode = root->first_node("Includes");
    if (pIncludeRootNode)
    {
        for (rapidxml::xml_node<>* includeNode = pIncludeRootNode->first_node(); includeNode; includeNode = includeNode->next_sibling())
        {
            const char* pstrIncludeFile = includeNode->first_attribute("Id")->value();
            //std::vector<std::string>::iterator it = std::find( pClass->mvIncludeFile.begin(), pClass->mvIncludeFile..end(), pstrIncludeFile );

            if (AddClassInclude(pstrIncludeFile, pClass))
            {
                pClass->Add(pstrIncludeFile);
            }
        }
    }

    return true;
}

bool NFCLogicClassModule::AddClass(const char* pstrClassFilePath, NFCLogicClass* pClass)
{

    std::ofstream file;
    file.open("./Log/NFLogicClass.log");

    NFILogicClass* pParent = pClass->GetParent();
    while (pParent)
    {
        //inherited some properties form class of parent
        std::string strFileName = "";
        pParent->First(strFileName);
        while (!strFileName.empty())
        {
            if (pClass->Find(strFileName))
            {
                strFileName.clear();
                continue;
            }

            if (AddClassInclude(strFileName.c_str(), pClass))
            {
                pClass->Add(strFileName);
            }

            strFileName.clear();
            pParent->Next(strFileName);
        }

        pParent = pParent->GetParent();
    }

    //////////////////////////////////////////////////////////////////////////
    if (AddClassInclude(pstrClassFilePath, pClass))
    {
        pClass->Add(pstrClassFilePath);
    }

    file.close();

    return true;
}

bool NFCLogicClassModule::AddClass(const std::string& strClassName, const std::string& strParentName)
{
    NFILogicClass* pParentClass = GetElement(strParentName);
    NFILogicClass* pChildClass = GetElement(strClassName);
    if (!pChildClass)
    {
        pChildClass = new NFCLogicClass(strClassName);
        AddElement(strClassName, pChildClass);
        //pChildClass = CreateElement( strClassName );

        pChildClass->SetTypeName("");
        pChildClass->SetInstancePath("");

        if (pParentClass)
        {
            pChildClass->SetParent(pParentClass);
        }

    }

    return true;
}

bool NFCLogicClassModule::Load(rapidxml::xml_node<>* attrNode, NFCLogicClass* pParentClass)
{

    const char* pstrLogicClassName = attrNode->first_attribute("Id")->value();
    const char* pstrType = attrNode->first_attribute("Type")->value();
    const char* pstrPath = attrNode->first_attribute("Path")->value();
    const char* pstrInstancePath = attrNode->first_attribute("InstancePath")->value();

    //printf( "-----------------------------------------------------\n");
    //printf( "%s:\n", pstrLogicClassName );

    NFCLogicClass* pClass = new NFCLogicClass(pstrLogicClassName);
    AddElement(pstrLogicClassName, pClass);
    pClass->SetParent(pParentClass);
    pClass->SetTypeName(pstrType);
    pClass->SetInstancePath(pstrInstancePath);

    AddClass(pstrPath, pClass);

    for (rapidxml::xml_node<>* pDataNode = attrNode->first_node(); pDataNode; pDataNode = pDataNode->next_sibling())
    {
        //her children
        Load(pDataNode, pClass);
    }
    //printf( "-----------------------------------------------------\n");
    return true;
}

bool NFCLogicClassModule::Load()
{
    rapidxml::file<> fdoc(msConfigFileName.c_str());
    //std::cout << fdoc.data() << std::endl;
    rapidxml::xml_document<>  doc;
    doc.parse<0>(fdoc.data());

    //support for unlimited layer class inherits
    rapidxml::xml_node<>* root = doc.first_node();
    for (rapidxml::xml_node<>* attrNode = root->first_node(); attrNode; attrNode = attrNode->next_sibling())
    {
        Load(attrNode, NULL);
    }

    m_pElementInfoModule->Load();
    return true;
}

bool NFCLogicClassModule::Save()
{
    return true;
}

NFIPropertyManager* NFCLogicClassModule::GetClassPropertyManager(const std::string& strClassName)
{
    NFILogicClass* pClass = GetElement(strClassName);
    if (pClass)
    {
        return pClass->GetPropertyManager();
    }

    return NULL;
}

NFIRecordManager* NFCLogicClassModule::GetClassRecordManager(const std::string& strClassName)
{
    NFILogicClass* pClass = GetElement(strClassName);
    if (pClass)
    {
        return pClass->GetRecordManager();
    }

    return NULL;
}

NFIComponentManager* NFCLogicClassModule::GetClassComponentManager( const std::string& strClassName )
{
    NFILogicClass* pClass = GetElement(strClassName);
    if (pClass)
    {
        return pClass->GetComponentManager();
    }

    return NULL;
}

bool NFCLogicClassModule::Clear()
{
	return true;

}<|endoftext|>