<commit_before>#pragma once

#include <sstream>
#include <iod/utils.hh>
#include <silicon/symbols.hh>

namespace sl
{

  using s::_primary_key;
  using s::_auto_increment;
  using s::_read_only;

  namespace sql_orm_internals
  {
    auto remove_members_with_attribute = [] (const auto& o, const auto& a)
    {
      typedef std::decay_t<decltype(a)> A;
      return foreach(o) | [&] (auto& m)
      {
        typedef typename std::decay_t<decltype(m)>::attributes_type attrs;
        return ::iod::static_if<!has_symbol<attrs, A>::value>(
          [&] () { return m; },
          [&] () {});
      };
    };

    auto extract_members_with_attribute = [] (const auto& o, const auto& a)
    {
      typedef std::decay_t<decltype(a)> A;
      return foreach(o) | [&] (auto& m)
      {
        typedef typename std::decay_t<decltype(m)>::attributes_type attrs;
        return ::iod::static_if<has_symbol<attrs, A>::value>(
          [&] () { return m; },
          [&] () {});
      };
    };

    template <typename T>
    using remove_auto_increment_t = decltype(remove_members_with_attribute(std::declval<T>(), _auto_increment));
    template <typename T>
    using remove_read_only_fields_t = decltype(remove_members_with_attribute(std::declval<T>(), _read_only));
    template <typename T>
    using extract_primary_keys_t = decltype(extract_members_with_attribute(std::declval<T>(), _primary_key));

  }

  template <typename C, typename O>
  struct sql_orm
  {
    typedef O object_type;

    // O without auto increment for create procedure.
    typedef sql_orm_internals::remove_auto_increment_t<O> without_auto_inc_type;

    // Object with only the primary keys for the delete and update procedures.
    typedef sql_orm_internals::extract_primary_keys_t<O> PKS;

    static_assert(!std::is_same<PKS, void>::value, "You must set at least one member of the CRUD object as primary key.");

    sql_orm(const std::string& table, C& con) : table_name_(table), con_(con) {}

    int find_by_id(int id, O& o)
    {
      return con_("SELECT * from " + table_name_ + " where id = ?")(id) >> o;
    }

    // save all fields except auto increment.
    // The db will automatically fill auto increment keys.
    template <typename N>
    int insert(const N& o)
    {
      std::stringstream ss;
      std::stringstream vs;
      ss << "INSERT into " << table_name_ << "(";

      bool first = true;
      auto values = foreach(without_auto_inc_type()) | [&] (auto& m) {
        if (!first) { ss << ","; vs << ","; }
        first = false;
        ss << m.symbol().name();
        vs << "?";
        return m.symbol() = m.symbol().member_access(o);
      };

      ss << ") VALUES (" << vs.str() << ")";
      auto req = con_(ss.str());
      apply(values, req);
      return req.last_insert_id();
    };

    // Update N's members except auto increment members.
    // N must have at least one primary key.
    template <typename N>
    int update(const N& o)
    {
      // check if N has at least one member of PKS.
      auto pk = intersect(o, PKS());
      static_assert(decltype(pk)::size() > 0, "You must provide at least one primary key to update an object.");
      std::stringstream ss;
      ss << "UPDATE " << table_name_ << " SET ";

      bool first = true;
      auto values = foreach(o) | [&] (auto& m) {
        if (!first) ss << ",";
        first = false;
        ss << m.symbol().name() << " = ?";
        return m;
      };

      ss << " WHERE ";

      first = true;
      auto pks_values = foreach(pk) | [&] (auto& m) {
        if (!first) ss << " and ";
        first = false;
        ss << m.symbol().name() << " = ? ";
        return m.symbol() = m.value();
      };

      auto stmt = con_(ss.str());
      apply(values, pks_values, stmt);
      return stmt.last_insert_id();
    }

    template <typename T>
    void destroy(const T& o)
    {
      std::stringstream ss;
      ss << "DELETE from " << table_name_ << " WHERE ";

      bool first = true;
      auto values = foreach(PKS()) | [&] (auto& m) {
        if (!first) ss << " and ";
        first = false;
        ss << m.symbol().name() << " = ? ";
        return m.symbol() = o[m.symbol()];
      };

      apply(values, con_(ss.str()));
    }

    std::string table_name_;
    C con_;
  };

  struct sqlite_connection;
  struct mysql_connection;

  template <typename C, typename O>
  struct sql_orm_factory
  {
    typedef O object_type;
    typedef sql_orm<C, O> instance_type;

    sql_orm_factory(const std::string& table_name) : table_name_(table_name) {}

    void initialize(C& c)
    {
      std::stringstream ss;
      ss << "CREATE TABLE if not exists " <<  table_name_ << " (";

      bool first = true;
      foreach(O()) | [&] (auto& m)
      {
        if (!first) ss << ", ";
        ss << m.symbol().name() << " " << c.type_to_string(m.value());

        if (std::is_same<C, sqlite_connection>::value)
        {
          if (m.attributes().has(_auto_increment) || m.attributes().has(_primary_key))
            ss << " PRIMARY KEY ";
        }

        if (std::is_same<C, mysql_connection>::value)
        {
          if (m.attributes().has(_auto_increment))
            ss << " AUTO_INCREMENT NOT NULL";
          if (m.attributes().has(_primary_key))
            ss << " PRIMARY KEY ";
        }

        // To activate when pgsql_connection is implemented.
        // if (std::is_same<C, pgsql_connection>::value and
        //     m.attributes().has(_auto_increment))
        //   ss << " SERIAL ";

        first = false;
      };
      ss << ");";
      c(ss.str())();
    }

    sql_orm<C, O> instantiate(C& con) {
      return sql_orm<C, O>(table_name_, con);
    };

    std::string table_name_;
  };

}
<commit_msg>Add sql_orm::forall.<commit_after>#pragma once

#include <sstream>
#include <iod/utils.hh>
#include <silicon/symbols.hh>

namespace sl
{

  using s::_primary_key;
  using s::_auto_increment;
  using s::_read_only;

  namespace sql_orm_internals
  {
    auto remove_members_with_attribute = [] (const auto& o, const auto& a)
    {
      typedef std::decay_t<decltype(a)> A;
      return foreach(o) | [&] (auto& m)
      {
        typedef typename std::decay_t<decltype(m)>::attributes_type attrs;
        return ::iod::static_if<!has_symbol<attrs, A>::value>(
          [&] () { return m; },
          [&] () {});
      };
    };

    auto extract_members_with_attribute = [] (const auto& o, const auto& a)
    {
      typedef std::decay_t<decltype(a)> A;
      return foreach(o) | [&] (auto& m)
      {
        typedef typename std::decay_t<decltype(m)>::attributes_type attrs;
        return ::iod::static_if<has_symbol<attrs, A>::value>(
          [&] () { return m; },
          [&] () {});
      };
    };

    template <typename T>
    using remove_auto_increment_t = decltype(remove_members_with_attribute(std::declval<T>(), _auto_increment));
    template <typename T>
    using remove_read_only_fields_t = decltype(remove_members_with_attribute(std::declval<T>(), _read_only));
    template <typename T>
    using extract_primary_keys_t = decltype(extract_members_with_attribute(std::declval<T>(), _primary_key));

  }

  template <typename C, typename O>
  struct sql_orm
  {
    typedef O object_type;

    // O without auto increment for create procedure.
    typedef sql_orm_internals::remove_auto_increment_t<O> without_auto_inc_type;

    // Object with only the primary keys for the delete and update procedures.
    typedef sql_orm_internals::extract_primary_keys_t<O> PKS;

    static_assert(!std::is_same<PKS, void>::value, "You must set at least one member of the CRUD object as primary key.");

    sql_orm(const std::string& table, C& con) : table_name_(table), con_(con) {}

    int find_by_id(int id, O& o)
    {
      return con_("SELECT * from " + table_name_ + " where id = ?")(id) >> o;
    }

    // save all fields except auto increment.
    // The db will automatically fill auto increment keys.
    template <typename N>
    int insert(const N& o)
    {
      std::stringstream ss;
      std::stringstream vs;
      ss << "INSERT into " << table_name_ << "(";

      bool first = true;
      auto values = foreach(without_auto_inc_type()) | [&] (auto& m) {
        if (!first) { ss << ","; vs << ","; }
        first = false;
        ss << m.symbol().name();
        vs << "?";
        return m.symbol() = m.symbol().member_access(o);
      };

      ss << ") VALUES (" << vs.str() << ")";
      auto req = con_(ss.str());
      apply(values, req);
      return req.last_insert_id();

    };

    // Iterate on all the rows of the table.
    template <typename F>
    void forall(F f)
    {
      std::stringstream ss;
      ss << "SELECT * from " << table_name_ << ";";
      con_(ss.str()) | f;
    }

    // Update N's members except auto increment members.
    // N must have at least one primary key.
    template <typename N>
    int update(const N& o)
    {
      // check if N has at least one member of PKS.
      auto pk = intersect(o, PKS());
      static_assert(decltype(pk)::size() > 0, "You must provide at least one primary key to update an object.");
      std::stringstream ss;
      ss << "UPDATE " << table_name_ << " SET ";

      bool first = true;
      auto values = foreach(o) | [&] (auto& m) {
        if (!first) ss << ",";
        first = false;
        ss << m.symbol().name() << " = ?";
        return m;
      };

      ss << " WHERE ";

      first = true;
      auto pks_values = foreach(pk) | [&] (auto& m) {
        if (!first) ss << " and ";
        first = false;
        ss << m.symbol().name() << " = ? ";
        return m.symbol() = m.value();
      };

      auto stmt = con_(ss.str());
      apply(values, pks_values, stmt);
      return stmt.last_insert_id();
    }

    template <typename T>
    void destroy(const T& o)
    {
      std::stringstream ss;
      ss << "DELETE from " << table_name_ << " WHERE ";

      bool first = true;
      auto values = foreach(PKS()) | [&] (auto& m) {
        if (!first) ss << " and ";
        first = false;
        ss << m.symbol().name() << " = ? ";
        return m.symbol() = o[m.symbol()];
      };

      apply(values, con_(ss.str()));
    }

    std::string table_name_;
    C con_;
  };

  struct sqlite_connection;
  struct mysql_connection;

  template <typename C, typename O>
  struct sql_orm_factory
  {
    typedef O object_type;
    typedef sql_orm<C, O> instance_type;

    sql_orm_factory(const std::string& table_name) : table_name_(table_name) {}

    void initialize(C& c)
    {
      std::stringstream ss;
      ss << "CREATE TABLE if not exists " <<  table_name_ << " (";

      bool first = true;
      foreach(O()) | [&] (auto& m)
      {
        if (!first) ss << ", ";
        ss << m.symbol().name() << " " << c.type_to_string(m.value());

        if (std::is_same<C, sqlite_connection>::value)
        {
          if (m.attributes().has(_auto_increment) || m.attributes().has(_primary_key))
            ss << " PRIMARY KEY ";
        }

        if (std::is_same<C, mysql_connection>::value)
        {
          if (m.attributes().has(_auto_increment))
            ss << " AUTO_INCREMENT NOT NULL";
          if (m.attributes().has(_primary_key))
            ss << " PRIMARY KEY ";
        }

        // To activate when pgsql_connection is implemented.
        // if (std::is_same<C, pgsql_connection>::value and
        //     m.attributes().has(_auto_increment))
        //   ss << " SERIAL ";

        first = false;
      };
      ss << ");";
      c(ss.str())();
    }

    sql_orm<C, O> instantiate(C& con) {
      return sql_orm<C, O>(table_name_, con);
    };

    std::string table_name_;
  };

}
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRobustAutomaticThresholdImageFilter.h"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"

int main(int argc, char * argv [] )
{

  if( argc != 4 )
    {
    std::cerr << "usage: " << argv[0] << " inputImage outputImage pow" << std::endl;
    return EXIT_FAILURE;
    }

  const unsigned int Dimension = 2;

  typedef unsigned short                      PixelType;
  typedef itk::Image< PixelType, Dimension >  ImageType;

  typedef float                                   RealPixelType;
  typedef itk::Image< RealPixelType, Dimension >  RealImageType;

  typedef itk::ImageFileReader< ImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  reader->Update();

  ImageType::ConstPointer inputImage = reader->GetOutput();

  ImageType::SpacingType spacing = inputImage->GetSpacing();

  typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, RealImageType > GradientType;
  GradientType::Pointer gradient = GradientType::New();
  gradient->SetInput( reader->GetOutput() );
  gradient->SetSigma( spacing[2] );
  gradient->Update();

  typedef itk::RobustAutomaticThresholdImageFilter< ImageType, RealImageType > FilterType;

  FilterType::Pointer filter = FilterType::New();

  filter->SetInput( reader->GetOutput() );
  filter->SetGradientImage( gradient->GetOutput() );
  filter->SetPow( atof(argv[3]) );

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( filter->GetOutput() );
  writer->SetFileName( argv[2] );

  try
    {
    writer->Update();
    }
  catch ( itk::ExceptionObject & excp )
    {
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  return EXIT_SUCCESS;

}
<commit_msg>BUG: Fixed Sigma.<commit_after>/*=========================================================================
 *
 *  Copyright Insight Software Consortium
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkRobustAutomaticThresholdImageFilter.h"
#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"

int main(int argc, char * argv [] )
{

  if( argc != 4 )
    {
    std::cerr << "usage: " << argv[0] << " inputImage outputImage pow" << std::endl;
    return EXIT_FAILURE;
    }

  const unsigned int Dimension = 2;

  typedef unsigned short                      PixelType;
  typedef itk::Image< PixelType, Dimension >  ImageType;

  typedef float                                   RealPixelType;
  typedef itk::Image< RealPixelType, Dimension >  RealImageType;

  typedef itk::ImageFileReader< ImageType > ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
  reader->Update();

  ImageType::ConstPointer inputImage = reader->GetOutput();

  ImageType::SpacingType spacing = inputImage->GetSpacing();

  const double sigma = spacing[0] * 1.0;

  std::cout << "Sigma = " << sigma << std::endl;

  typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< ImageType, RealImageType > GradientType;
  GradientType::Pointer gradient = GradientType::New();
  gradient->SetInput( reader->GetOutput() );
  gradient->SetSigma( sigma );
  gradient->Update();

  typedef itk::ImageFileWriter< RealImageType > RealWriterType;
  RealWriterType::Pointer realwriter = RealWriterType::New();
  realwriter->SetInput( gradient->GetOutput() );
  realwriter->SetFileName( "gradient.mha" );
  realwriter->Update();

  typedef itk::RobustAutomaticThresholdImageFilter< ImageType, RealImageType > FilterType;

  FilterType::Pointer filter = FilterType::New();

  filter->SetInput( reader->GetOutput() );
  filter->SetGradientImage( gradient->GetOutput() );
  filter->SetPow( atof(argv[3]) );

  typedef itk::ImageFileWriter< ImageType > WriterType;
  WriterType::Pointer writer = WriterType::New();
  writer->SetInput( filter->GetOutput() );
  writer->SetFileName( argv[2] );

  try
    {
    writer->Update();
    }
  catch ( itk::ExceptionObject & excp )
    {
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Computed Threshold = " << filter->GetThreshold() << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>#include "Editor.hpp"

#include <Engine/Util/Input.hpp>
#include "Util/EditorSettings.hpp"
#include <Engine/Hymn.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/MainWindow.hpp>

#include <imgui.h>
#include <GLFW/glfw3.h>

Editor::Editor() {
    // Assign controls.
    Input()->AssignButton(InputHandler::PROFILE, InputHandler::KEYBOARD, GLFW_KEY_F2);
    Input()->AssignButton(InputHandler::PLAYTEST, InputHandler::KEYBOARD, GLFW_KEY_F5);
    Input()->AssignButton(InputHandler::CONTROL, InputHandler::KEYBOARD, GLFW_KEY_LEFT_CONTROL);
    Input()->AssignButton(InputHandler::NEW, InputHandler::KEYBOARD, GLFW_KEY_N);
    Input()->AssignButton(InputHandler::OPEN, InputHandler::KEYBOARD, GLFW_KEY_O);
}

void Editor::Show() {
    bool play = false;

    ImVec2 size(MainWindow::GetInstance()->GetSize().x, MainWindow::GetInstance()->GetSize().y);

    // Main menu bar.
    if (ImGui::BeginMainMenuBar()) {

        // File menu.
        if (ImGui::BeginMenu("File")) {
            if (ImGui::MenuItem("New Hymn", "CTRL+N"))
                NewHymn();

            if (ImGui::MenuItem("Open Hymn", "CTRL+O"))
                OpenHymn();

            ImGui::EndMenu();
        }

        // View menu.
        if (ImGui::BeginMenu("View")) {
            static bool soundSources = EditorSettings::GetInstance().GetBool("Sound Source Icons");
            ImGui::MenuItem("Sound Sources", "", &soundSources);
            EditorSettings::GetInstance().SetBool("Sound Source Icons", soundSources);

            static bool particleEmitters = EditorSettings::GetInstance().GetBool("Particle Emitter Icons");
            ImGui::MenuItem("Particle Emitters", "", &particleEmitters);
            EditorSettings::GetInstance().SetBool("Particle Emitter Icons", particleEmitters);

            static bool lightSources = EditorSettings::GetInstance().GetBool("Light Source Icons");
            ImGui::MenuItem("Light Sources", "", &lightSources);
            EditorSettings::GetInstance().SetBool("Light Source Icons", lightSources);

            ImGui::EndMenu();
        }

        // Play
        if (ImGui::BeginMenu("Play")) {
            if (ImGui::MenuItem("Play", "F5")) {
                Managers().scriptManager->RegisterInput();
                Managers().scriptManager->BuildAllScripts();
                play = true;
            }
            ImGui::EndMenu();
        }

        // Input
        if(Hymn().GetPath() != "") {
            if (ImGui::BeginMenu("Input")) {
                inputWindow.SetVisible(true);

                ImGui::EndMenu();
            }
        }

        ImGui::EndMainMenuBar();
    }

    // Show hymn selection window.
    if (selectHymnWindow.IsVisible()) {
        ImGui::SetNextWindowPosCenter();
        selectHymnWindow.Show();
    }

    if (inputWindow.IsVisible())
        inputWindow.Show();

    // Show resource list.
    if (resourceList.IsVisible()) {
        ImGui::SetNextWindowPos(ImVec2(0, size.y - 250));
        ImGui::SetNextWindowSize(ImVec2(size.x - 250, 250));

        resourceList.Show();
    }

    if (Input()->Triggered(InputHandler::PLAYTEST))
        play = true;

    if (Input()->Triggered(InputHandler::NEW) && Input()->Pressed(InputHandler::CONTROL))
        NewHymn();

    if (Input()->Triggered(InputHandler::OPEN) && Input()->Pressed(InputHandler::CONTROL))
        OpenHymn();

    if (play)
        Play();
}

void Editor::Save() const {
    resourceList.SaveScene();
    Hymn().Save();
}

bool Editor::IsVisible() const {
    return visible;
}

void Editor::SetVisible(bool visible) {
    this->visible = visible;
}

void Editor::Play() {
    Save();
    SetVisible(false);
    resourceList.HideEditors();
    resourceList.ResetScene();
}

void Editor::NewHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::NewHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("New Hymn");
    selectHymnWindow.SetOpenButtonName("Create");
    selectHymnWindow.SetVisible(true);
}

void Editor::NewHymnClosed(const std::string& hymn) {
    // Create new hymn
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Clear();
        Hymn().SetPath(FileSystem::DataPath("Hymn to Beauty", hymn.c_str()));
        resourceList.SetVisible(true);
    }

    selectHymnWindow.SetVisible(false);
}

void Editor::OpenHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::OpenHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("Open Hymn");
    selectHymnWindow.SetOpenButtonName("Open");
    selectHymnWindow.SetVisible(true);
}

void Editor::OpenHymnClosed(const std::string& hymn) {
    // Open hymn.
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Load(FileSystem::DataPath("Hymn to Beauty", hymn.c_str()));
        resourceList.SetVisible(true);
    }

    selectHymnWindow.SetVisible(false);
}
<commit_msg>Fix playing by pressing F5<commit_after>#include "Editor.hpp"

#include <Engine/Util/Input.hpp>
#include "Util/EditorSettings.hpp"
#include <Engine/Hymn.hpp>
#include <Engine/Manager/Managers.hpp>
#include <Engine/Manager/ScriptManager.hpp>
#include <Engine/Util/FileSystem.hpp>
#include <Engine/MainWindow.hpp>

#include <imgui.h>
#include <GLFW/glfw3.h>

Editor::Editor() {
    // Assign controls.
    Input()->AssignButton(InputHandler::PROFILE, InputHandler::KEYBOARD, GLFW_KEY_F2);
    Input()->AssignButton(InputHandler::PLAYTEST, InputHandler::KEYBOARD, GLFW_KEY_F5);
    Input()->AssignButton(InputHandler::CONTROL, InputHandler::KEYBOARD, GLFW_KEY_LEFT_CONTROL);
    Input()->AssignButton(InputHandler::NEW, InputHandler::KEYBOARD, GLFW_KEY_N);
    Input()->AssignButton(InputHandler::OPEN, InputHandler::KEYBOARD, GLFW_KEY_O);
}

void Editor::Show() {
    bool play = false;

    ImVec2 size(MainWindow::GetInstance()->GetSize().x, MainWindow::GetInstance()->GetSize().y);

    // Main menu bar.
    if (ImGui::BeginMainMenuBar()) {

        // File menu.
        if (ImGui::BeginMenu("File")) {
            if (ImGui::MenuItem("New Hymn", "CTRL+N"))
                NewHymn();

            if (ImGui::MenuItem("Open Hymn", "CTRL+O"))
                OpenHymn();

            ImGui::EndMenu();
        }

        // View menu.
        if (ImGui::BeginMenu("View")) {
            static bool soundSources = EditorSettings::GetInstance().GetBool("Sound Source Icons");
            ImGui::MenuItem("Sound Sources", "", &soundSources);
            EditorSettings::GetInstance().SetBool("Sound Source Icons", soundSources);

            static bool particleEmitters = EditorSettings::GetInstance().GetBool("Particle Emitter Icons");
            ImGui::MenuItem("Particle Emitters", "", &particleEmitters);
            EditorSettings::GetInstance().SetBool("Particle Emitter Icons", particleEmitters);

            static bool lightSources = EditorSettings::GetInstance().GetBool("Light Source Icons");
            ImGui::MenuItem("Light Sources", "", &lightSources);
            EditorSettings::GetInstance().SetBool("Light Source Icons", lightSources);

            ImGui::EndMenu();
        }

        // Play
        if (ImGui::BeginMenu("Play")) {
            if (ImGui::MenuItem("Play", "F5"))
                play = true;

            ImGui::EndMenu();
        }

        // Input
        if(Hymn().GetPath() != "") {
            if (ImGui::BeginMenu("Input")) {
                inputWindow.SetVisible(true);

                ImGui::EndMenu();
            }
        }

        ImGui::EndMainMenuBar();
    }

    // Show hymn selection window.
    if (selectHymnWindow.IsVisible()) {
        ImGui::SetNextWindowPosCenter();
        selectHymnWindow.Show();
    }

    if (inputWindow.IsVisible())
        inputWindow.Show();

    // Show resource list.
    if (resourceList.IsVisible()) {
        ImGui::SetNextWindowPos(ImVec2(0, size.y - 250));
        ImGui::SetNextWindowSize(ImVec2(size.x - 250, 250));

        resourceList.Show();
    }

    if (Input()->Triggered(InputHandler::PLAYTEST))
        play = true;

    if (Input()->Triggered(InputHandler::NEW) && Input()->Pressed(InputHandler::CONTROL))
        NewHymn();

    if (Input()->Triggered(InputHandler::OPEN) && Input()->Pressed(InputHandler::CONTROL))
        OpenHymn();

    if (play)
        Play();
}

void Editor::Save() const {
    resourceList.SaveScene();
    Hymn().Save();
}

bool Editor::IsVisible() const {
    return visible;
}

void Editor::SetVisible(bool visible) {
    this->visible = visible;
}

void Editor::Play() {
    Save();
    SetVisible(false);
    resourceList.HideEditors();
    resourceList.ResetScene();
    Managers().scriptManager->RegisterInput();
    Managers().scriptManager->BuildAllScripts();
}

void Editor::NewHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::NewHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("New Hymn");
    selectHymnWindow.SetOpenButtonName("Create");
    selectHymnWindow.SetVisible(true);
}

void Editor::NewHymnClosed(const std::string& hymn) {
    // Create new hymn
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Clear();
        Hymn().SetPath(FileSystem::DataPath("Hymn to Beauty", hymn.c_str()));
        resourceList.SetVisible(true);
    }

    selectHymnWindow.SetVisible(false);
}

void Editor::OpenHymn() {
    selectHymnWindow.Scan();
    selectHymnWindow.SetClosedCallback(std::bind(&Editor::OpenHymnClosed, this, std::placeholders::_1));
    selectHymnWindow.SetTitle("Open Hymn");
    selectHymnWindow.SetOpenButtonName("Open");
    selectHymnWindow.SetVisible(true);
}

void Editor::OpenHymnClosed(const std::string& hymn) {
    // Open hymn.
    if (!hymn.empty()) {
        resourceList.ResetScene();
        Hymn().Load(FileSystem::DataPath("Hymn to Beauty", hymn.c_str()));
        resourceList.SetVisible(true);
    }

    selectHymnWindow.SetVisible(false);
}
<|endoftext|>


<commit_before>/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/

#include "mips_memory.h"
#include "mips_instr.h"

#include <infra/instrcache/instr_cache.h>

#include <iostream>
FuncInstr MIPSMemory::fetch_instr( Addr PC)
{
    auto it = instr_cache.find( PC);

    FuncInstr instr = ( it != instr_cache.end())
                      ? FuncInstr( it->second)
                      : FuncInstr( read( PC), PC);

    if ( it != instr_cache.end())
        instr_cache.update( PC, instr);

    return instr;
}
<commit_msg>Update InstrCache in case of cache miss<commit_after>/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/

#include "mips_memory.h"
#include "mips_instr.h"

#include <infra/instrcache/instr_cache.h>

FuncInstr MIPSMemory::fetch_instr( Addr PC)
{
    auto it = instr_cache.find( PC);

    FuncInstr instr = ( it != instr_cache.end())
                      ? FuncInstr( it->second)
                      : FuncInstr( read( PC), PC);

    instr_cache.update( PC, instr);

    return instr;
}
<|endoftext|>


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

#include <QApplication>
#include <QGraphicsItem>
#include <QGraphicsWidget>
#include <QWidget>
#include <QGraphicsView>
#include <QLocale>

#include "tasuitraverser.h"
#include "taslogger.h"
#include "testabilityutils.h"
#include "tastraverserloader.h"
#include "tasdeviceutils.h"

TasUiTraverser::TasUiTraverser(QList<TasTraverseInterface*> traversers)
{
    mTraversers = traversers;
    mFilter = new TraverseFilter();
}

TasUiTraverser::~TasUiTraverser()
{

    QMutableListIterator<TasTraverseInterface*> i(mTraversers);
    while (i.hasNext()){
        delete i.next();
    }
    mTraversers.clear();
    delete mFilter;
}

void TasUiTraverser::setFilters(TasCommand* command)
{
    if(!command){
        return;
    }
    //if the command contains filtering instructions
    //set the them for all traverser plugins
    QStringList attributeBlackList;
    if(!command->apiParameter("attributeBlackList").isEmpty()){
         attributeBlackList = command->apiParameter("attributeBlackList").split(",");
    }
    QStringList attributeWhiteList;
    if(!command->apiParameter("attributeWhiteList").isEmpty()){
        attributeWhiteList = command->apiParameter("attributeWhiteList").split(",");
    }
    QStringList pluginBlackList;
    if(!command->apiParameter("pluginBlackList").isEmpty()){
        pluginBlackList = command->apiParameter("pluginBlackList").split(",");
    }

    QStringList pluginWhiteList;
    if(!command->apiParameter("pluginWhiteList").isEmpty()){
        pluginWhiteList = command->apiParameter("pluginWhiteList").split(",");
    }

    bool filterProps = false;
    if(command->apiParameter("filterProperties") =="true"){
        filterProps = true;
    }
    mFilter->initialize(filterProps, attributeBlackList, attributeWhiteList, pluginBlackList, pluginWhiteList);
    for (int i = 0; i < mTraversers.size(); i++) {
        mTraversers.at(i)->setFilter(mFilter);
    }

}

TasDataModel* TasUiTraverser::getUiState(TasCommand* command)
{
    setFilters(command);
    TasDataModel* model = new TasDataModel();
    QString qtVersion = "Qt" + QString(qVersion());
    TasObjectContainer& container = model->addNewObjectContainer(1, qtVersion, "qt");

    TasObject& application = container.addNewObject(QString::number(qApp->applicationPid()), getApplicationName(), "application");
    addApplicationDetails(application, command);

    QWidgetList widgetList = qApp->topLevelWidgets();
    if (!widgetList.empty()){
        QListIterator<QWidget*> iter(qApp->topLevelWidgets());
        while(iter.hasNext()){
            QWidget *widget = iter.next();
            //only print widgets if they are visible
            if (!widget->graphicsProxyWidget() &&
                (TestabilityUtils::isCustomTraverse() || widget->isVisible()
                    )) /*&& !wasTraversed(widget)*/{
                traverseObject(application.addObject(), widget, command);
            }
        }
    }
    //reset filters after uistate made so that thet will not be used for
    //any other tasks done by traversers
    for (int i = 0; i < mTraversers.size(); i++) {
        mTraversers.at(i)->resetFilter();
    }
    mFilter->clear();
    return model;
}

void TasUiTraverser::traverseObject(TasObject& objectInfo, QObject* object, TasCommand* command)
{
    for (int i = 0; i < mTraversers.size(); i++) {
        if(!mFilter->filterPlugin(mTraversers.at(i)->getPluginName())){
            mTraversers.at(i)->traverseObject(&objectInfo, object, command);
        }
    }
    //check decendants
    //1. is graphicsview
    if(object->inherits("QGraphicsView")){
        traverseGraphicsViewItems(objectInfo, qobject_cast<QGraphicsView*>(object), command);
    }
    //2. is GraphicsWidget
    QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
    if(graphicsWidget){
        traverseGraphicsItemList(objectInfo, graphicsWidget,command);
    }
    //3. Widget children
    else{
        QObjectList children = object->children();
        if (!children.isEmpty()) {
            for (int i = 0; i < children.size(); ++i){
                QObject *obj = children.at(i);
                //only include widgets
                if (obj->isWidgetType() && obj->parent() == object){
                    QWidget *widget = qobject_cast<QWidget*>(obj);
                    // TODO This (and other similar hacks) needs to be moved to plugins once OSS changes are done
                    if (TestabilityUtils::isCustomTraverse() || widget->isVisible() ) /*&& !wasTraversed(widget)*/{
                        traverseObject(objectInfo.addObject(), widget, command);
                    }
                }
            }
        }

    }
}

void TasUiTraverser::traverseGraphicsItem(TasObject& objectInfo, QGraphicsItem* graphicsItem, TasCommand* command)
{
    if (graphicsItem->isWindow() || graphicsItem->isWidget()) {
        QObject * object = (QObject*)((QGraphicsWidget*)graphicsItem);
        traverseObject(objectInfo, object, command);
        // Traverse the actual widget under the proxy, if available
        QGraphicsProxyWidget* proxy = qobject_cast<QGraphicsProxyWidget*>(object);
        if (proxy) {
            traverseObject(objectInfo.addObject(), proxy->widget(), command);
        }
    }
    else{
        objectInfo.setType("QGraphicsItem");
        for (int i = 0; i < mTraversers.size(); i++) {
            if(!mFilter->filterPlugin(mTraversers.at(i)->getPluginName())){
                mTraversers.at(i)->traverseGraphicsItem(&objectInfo, graphicsItem, command);
            }
        }
        traverseGraphicsItemList(objectInfo, graphicsItem, command);
    }
}

void TasUiTraverser::traverseGraphicsItemList(TasObject& parent, QGraphicsItem* graphicsItem, TasCommand* command)
{
    foreach (QGraphicsItem* item, graphicsItem->childItems()){
        if(graphicsItem == item->parentItem()){
            // TODO This needs to be moved to plugins once OSS changes are done
            if(TestabilityUtils::isCustomTraverse()|| item->isVisible() ) {
                traverseGraphicsItem(parent.addObject(), item, command);
            }
        }
    }
}

void TasUiTraverser::traverseGraphicsViewItems(TasObject& parent, QGraphicsView* view, TasCommand* command)
{
    foreach(QGraphicsItem* item, view->items()){
        if(item->parentItem() == 0){
            // TODO This needs to be moved to plugins once OSS changes are done
            if(TestabilityUtils::isCustomTraverse() || item->isVisible()
                ) {
                traverseGraphicsItem(parent.addObject(), item, command);
            }
        }
    }
}

void TasUiTraverser::addApplicationDetails(TasObject& application, TasCommand* command)
{
    traverseObject(application, qApp, command);

    //set these again cause properties overwrite them
    application.setName(getApplicationName());
    application.setId(QString::number(qApp->applicationPid()));
#ifdef Q_OS_SYMBIAN
    quintptr uid = CEikonEnv::Static()->EikAppUi()->Application()->AppDllUid().iUid;
    application.addAttribute("applicationUid", QString::number(uid));
#endif

    application.addAttribute("exepath", qApp->applicationFilePath().toLatin1().data());
    application.addAttribute("FullName", qApp->applicationFilePath().toLatin1().data());
    application.addAttribute("dirpath", qApp->applicationDirPath().toLatin1().data());
    application.addAttribute("processId", QString::number(qApp->applicationPid()).toLatin1().data());
    application.addAttribute("version", qApp->applicationVersion().toLatin1().data());
    application.addAttribute("objectType", TYPE_APPLICATION_VIEW);
    application.addAttribute("objectId", TasCoreUtils::objectId(qApp));

    int mem = TasDeviceUtils::currentProcessHeapSize();
    if(mem != -1){
        application.addAttribute("memUsage", mem);
    }
    QLocale defaultLocale;
    application.addAttribute("localeName", defaultLocale.name());
    application.addAttribute("localeCountry", defaultLocale.countryToString(defaultLocale.country()));
    application.addAttribute("localeLanguage", defaultLocale.languageToString(defaultLocale.language()));
}
<commit_msg>Multiple traverse bug fix. Objects were traversed twice if they appeared in the object tree and under the app (qApp->topLevelWidgets). Fix proposal made so that a widget listed as a top level widget cannot have a parent (unless qApp) for it to be trraversed.<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (testabilitydriver@nokia.com)
**
** This file is part of Testability Driver Qt Agent
**
** If you have questions regarding the use of this file, please contact
** Nokia at testabilitydriver@nokia.com .
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QApplication>
#include <QGraphicsItem>
#include <QGraphicsWidget>
#include <QWidget>
#include <QGraphicsView>
#include <QLocale>

#include "tasuitraverser.h"
#include "taslogger.h"
#include "testabilityutils.h"
#include "tastraverserloader.h"
#include "tasdeviceutils.h"

TasUiTraverser::TasUiTraverser(QList<TasTraverseInterface*> traversers)
{
    mTraversers = traversers;
    mFilter = new TraverseFilter();
}

TasUiTraverser::~TasUiTraverser()
{

    QMutableListIterator<TasTraverseInterface*> i(mTraversers);
    while (i.hasNext()){
        delete i.next();
    }
    mTraversers.clear();
    delete mFilter;
}

void TasUiTraverser::setFilters(TasCommand* command)
{
    if(!command){
        return;
    }
    //if the command contains filtering instructions
    //set the them for all traverser plugins
    QStringList attributeBlackList;
    if(!command->apiParameter("attributeBlackList").isEmpty()){
         attributeBlackList = command->apiParameter("attributeBlackList").split(",");
    }
    QStringList attributeWhiteList;
    if(!command->apiParameter("attributeWhiteList").isEmpty()){
        attributeWhiteList = command->apiParameter("attributeWhiteList").split(",");
    }
    QStringList pluginBlackList;
    if(!command->apiParameter("pluginBlackList").isEmpty()){
        pluginBlackList = command->apiParameter("pluginBlackList").split(",");
    }

    QStringList pluginWhiteList;
    if(!command->apiParameter("pluginWhiteList").isEmpty()){
        pluginWhiteList = command->apiParameter("pluginWhiteList").split(",");
    }

    bool filterProps = false;
    if(command->apiParameter("filterProperties") =="true"){
        filterProps = true;
    }
    mFilter->initialize(filterProps, attributeBlackList, attributeWhiteList, pluginBlackList, pluginWhiteList);
    for (int i = 0; i < mTraversers.size(); i++) {
        mTraversers.at(i)->setFilter(mFilter);
    }

}

TasDataModel* TasUiTraverser::getUiState(TasCommand* command)
{
    setFilters(command);
    TasDataModel* model = new TasDataModel();
    QString qtVersion = "Qt" + QString(qVersion());
    TasObjectContainer& container = model->addNewObjectContainer(1, qtVersion, "qt");

    TasObject& application = container.addNewObject(QString::number(qApp->applicationPid()), getApplicationName(), "application");
    addApplicationDetails(application, command);

    QWidgetList widgetList = qApp->topLevelWidgets();
    if (!widgetList.empty()){
        QListIterator<QWidget*> iter(qApp->topLevelWidgets());
        while(iter.hasNext()){
            QWidget *widget = iter.next();
            //only print widgets if they are visible
            if (!widget->graphicsProxyWidget() &&  (TestabilityUtils::isCustomTraverse() || widget->isVisible())){
                //widgets that have a parent will not be traversed unless the parent is the app
                //this is done to avoid objects being traversed more than once
                if(!widget->parent() || widget->parent() == qApp){
                    traverseObject(application.addObject(), widget, command);
                }
            }
        }
    }
    //reset filters after uistate made so that thet will not be used for
    //any other tasks done by traversers
    for (int i = 0; i < mTraversers.size(); i++) {
        mTraversers.at(i)->resetFilter();
    }
    mFilter->clear();
    return model;
}

void TasUiTraverser::traverseObject(TasObject& objectInfo, QObject* object, TasCommand* command)
{
    for (int i = 0; i < mTraversers.size(); i++) {
        if(!mFilter->filterPlugin(mTraversers.at(i)->getPluginName())){
            mTraversers.at(i)->traverseObject(&objectInfo, object, command);
        }
    }
    //check decendants
    //1. is graphicsview
    if(object->inherits("QGraphicsView")){
        traverseGraphicsViewItems(objectInfo, qobject_cast<QGraphicsView*>(object), command);
    }
    //2. is GraphicsWidget
    QGraphicsWidget* graphicsWidget = qobject_cast<QGraphicsWidget*>(object);
    if(graphicsWidget){
        traverseGraphicsItemList(objectInfo, graphicsWidget,command);
    }
    //3. Widget children
    else{
        QObjectList children = object->children();
        if (!children.isEmpty()) {
            for (int i = 0; i < children.size(); ++i){
                QObject *obj = children.at(i);
                //only include widgets
                if (obj->isWidgetType() && obj->parent() == object){
                    QWidget *widget = qobject_cast<QWidget*>(obj);
                    // TODO This (and other similar hacks) needs to be moved to plugins once OSS changes are done
                    if (TestabilityUtils::isCustomTraverse() || widget->isVisible() ) /*&& !wasTraversed(widget)*/{
                        traverseObject(objectInfo.addObject(), widget, command);
                    }
                }
            }
        }

    }
}

void TasUiTraverser::traverseGraphicsItem(TasObject& objectInfo, QGraphicsItem* graphicsItem, TasCommand* command)
{
    if (graphicsItem->isWindow() || graphicsItem->isWidget()) {
        QObject * object = (QObject*)((QGraphicsWidget*)graphicsItem);
        traverseObject(objectInfo, object, command);
        // Traverse the actual widget under the proxy, if available
        QGraphicsProxyWidget* proxy = qobject_cast<QGraphicsProxyWidget*>(object);
        if (proxy) {
            traverseObject(objectInfo.addObject(), proxy->widget(), command);
        }
    }
    else{
        objectInfo.setType("QGraphicsItem");
        for (int i = 0; i < mTraversers.size(); i++) {
            if(!mFilter->filterPlugin(mTraversers.at(i)->getPluginName())){
                mTraversers.at(i)->traverseGraphicsItem(&objectInfo, graphicsItem, command);
            }
        }
        traverseGraphicsItemList(objectInfo, graphicsItem, command);
    }
}

void TasUiTraverser::traverseGraphicsItemList(TasObject& parent, QGraphicsItem* graphicsItem, TasCommand* command)
{
    foreach (QGraphicsItem* item, graphicsItem->childItems()){
        if(graphicsItem == item->parentItem()){
            // TODO This needs to be moved to plugins once OSS changes are done
            if(TestabilityUtils::isCustomTraverse()|| item->isVisible() ) {
                traverseGraphicsItem(parent.addObject(), item, command);
            }
        }
    }
}

void TasUiTraverser::traverseGraphicsViewItems(TasObject& parent, QGraphicsView* view, TasCommand* command)
{
    foreach(QGraphicsItem* item, view->items()){
        if(item->parentItem() == 0){
            // TODO This needs to be moved to plugins once OSS changes are done
            if(TestabilityUtils::isCustomTraverse() || item->isVisible()
                ) {
                traverseGraphicsItem(parent.addObject(), item, command);
            }
        }
    }
}

void TasUiTraverser::addApplicationDetails(TasObject& application, TasCommand* command)
{
    traverseObject(application, qApp, command);

    //set these again cause properties overwrite them
    application.setName(getApplicationName());
    application.setId(QString::number(qApp->applicationPid()));
#ifdef Q_OS_SYMBIAN
    quintptr uid = CEikonEnv::Static()->EikAppUi()->Application()->AppDllUid().iUid;
    application.addAttribute("applicationUid", QString::number(uid));
#endif

    application.addAttribute("exepath", qApp->applicationFilePath().toLatin1().data());
    application.addAttribute("FullName", qApp->applicationFilePath().toLatin1().data());
    application.addAttribute("dirpath", qApp->applicationDirPath().toLatin1().data());
    application.addAttribute("processId", QString::number(qApp->applicationPid()).toLatin1().data());
    application.addAttribute("version", qApp->applicationVersion().toLatin1().data());
    application.addAttribute("objectType", TYPE_APPLICATION_VIEW);
    application.addAttribute("objectId", TasCoreUtils::objectId(qApp));

    int mem = TasDeviceUtils::currentProcessHeapSize();
    if(mem != -1){
        application.addAttribute("memUsage", mem);
    }
    QLocale defaultLocale;
    application.addAttribute("localeName", defaultLocale.name());
    application.addAttribute("localeCountry", defaultLocale.countryToString(defaultLocale.country()));
    application.addAttribute("localeLanguage", defaultLocale.languageToString(defaultLocale.language()));
}
<|endoftext|>


<commit_before>// Copyright (c) 2018 Intel Corporation
//
// 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 "umc_deinterlacing.h"
#include "umc_video_data.h"
#include "ippi.h"
#include "ippvc.h"

using namespace UMC;

Deinterlacing::Deinterlacing()
{
  mMethod = DEINTERLACING_DUPLICATE;
}

Status Deinterlacing::SetMethod(DeinterlacingMethod method)
{
  mMethod = method;
  return UMC_OK;
}

static void DeinterlacingEdgeDetect(uint8_t *psrc,
                                    int32_t iSrcPitch,
                                    uint8_t *pdst,
                                    int32_t iDstPitch,
                                    int32_t w,
                                    int32_t h);

Status Deinterlacing::GetFrame(MediaData *input, MediaData *output)
{
  VideoData *in = DynamicCast<VideoData>(input);
  VideoData *out = DynamicCast<VideoData>(output);
  DeinterlacingMethod method = mMethod;
  int k;

  if (NULL == in || NULL == out) {
    return UMC_ERR_NULL_PTR;
  }

  ColorFormat cFormat = in->GetColorFormat();
  if (out->GetColorFormat() != cFormat) {
    return UMC_ERR_INVALID_PARAMS;
  }
  int32_t in_Width = in->GetWidth();
  int32_t in_Height = in->GetHeight();
  int32_t out_Width = out->GetWidth();
  int32_t out_Height = out->GetHeight();
  if ( (in_Width != out_Width) || (in_Height != out_Height) ) {
    return UMC_ERR_INVALID_PARAMS;
  }

  for (k = 0; k < in->GetNumPlanes(); k++) {
    VideoData::PlaneInfo srcPlane;
    const uint8_t *pSrc0; //, *pSrc1;
    uint8_t *pDst0, *pDst1;
    int srcPitch, dstPitch;
    mfxSize size;

    in->GetPlaneInfo(&srcPlane, k);
    pSrc0 = (const uint8_t*)in->GetPlanePointer(k);
    srcPitch = (int32_t)in->GetPlanePitch(k);
    pDst0 = (uint8_t*)out->GetPlanePointer(k);
    dstPitch = (int32_t)out->GetPlanePitch(k);
    size.width = srcPlane.m_ippSize.width * srcPlane.m_iSamples * srcPlane.m_iSampleSize;
    size.height = srcPlane.m_ippSize.height;

    if (method == DEINTERLACING_BLEND) {
      if (srcPlane.m_iSampleSize != 1) {
        //return UMC_ERR_UNSUPPORTED;
        method = DEINTERLACING_DUPLICATE;
      }
      mfxiDeinterlaceFilterTriangle_8u_C1R(pSrc0, srcPitch,
                                           pDst0, dstPitch,
                                           size,
                                           128,
                                           IPP_LOWER | IPP_UPPER | IPP_CENTER);
      continue;
    }

    if (method == DEINTERLACING_SPATIAL) {
      if (k == 0) { // Y
        if (srcPlane.m_iSampleSize != 1 || srcPlane.m_iSamples != 1) {
          //return UMC_ERR_UNSUPPORTED;
          method = DEINTERLACING_DUPLICATE;
        }
        DeinterlacingEdgeDetect((uint8_t*)pSrc0, srcPitch,
                                pDst0, dstPitch,
                                size.width, size.height);
        continue;
      } else { // U,V
        method = DEINTERLACING_DUPLICATE;
      }
    }

    // DEINTERLACING_DUPLICATE
    //pSrc1 = pSrc0 += srcPitch;
    pSrc0 += srcPitch;
    srcPitch *= 2;
    pDst1 = pDst0 + dstPitch;
    dstPitch *= 2;
    size.height /= 2;
    mfxiCopy_8u_C1R(pSrc0, srcPitch, pDst0, dstPitch, size);
    mfxiCopy_8u_C1R(pSrc0, srcPitch, pDst1, dstPitch, size);
  }

  return UMC_OK;
}

static void DeinterlacingEdgeDetect(uint8_t *psrc,
                                    int32_t iSrcPitch,
                                    uint8_t *pdst,
                                    int32_t iDstPitch,
                                    int32_t w,
                                    int32_t h)
{
  int32_t /*hi, lo,*/ x, y;
  int32_t res;
  uint8_t *pInA, *pInB, *pInC, *pInD, *pInE, *pInF;
  int32_t dif1, dif2, dif3;
  mfxSize roi = {w, h/2};

  // copy even lines
  mfxiCopy_8u_C1R(psrc, 2*iSrcPitch, pdst, 2*iDstPitch, roi);

  // then line #1 and line before last
  std::copy(psrc + iSrcPitch, psrc + 2*iSrcPitch, pdst + iDstPitch);
  std::copy(psrc + (h - 2) * iSrcPitch, psrc + (h - 2) * iSrcPitch + w, pdst + (h - 1)*iDstPitch);

  psrc += 3*iSrcPitch;
  pdst += 3*iDstPitch;
  pInB = psrc - iSrcPitch;
  pInA = pInB - 1;
  pInC = pInB + 1;
  pInE = psrc + iSrcPitch;
  pInD = pInE - 1;
  pInF = pInE + 1;

  for (y = 3; y <= h - 3; y += 2) {
    pdst[0] = psrc[0];
    pdst[w - 1] = psrc[w - 1];

    for (x = 1; x < w - 1; x++)
    {
      dif1 = abs((int32_t)pInA[x] - (int32_t)pInF[x]);
      dif2 = abs((int32_t)pInC[x] - (int32_t)pInD[x]);
      dif3 = abs((int32_t)pInB[x] - (int32_t)pInE[x]);

      if (dif1 < dif2) {
        if (dif1 < dif3) {
          res = ((int32_t)pInA[x] + (int32_t)pInF[x]) >> 1; //1
        } else {
          res = ((int32_t)pInB[x] + (int32_t)pInE[x]) >> 1; //3
        }
      } else {
        if (dif2 < dif3) {
          res = ((int32_t)pInC[x] + (int32_t)pInD[x]) >> 1; //2
        } else {
          res = ((int32_t)pInB[x] + (int32_t)pInE[x]) >> 1; //3
        }
      }
      pdst[x] = (uint8_t)res;
    }
    psrc += 2*iSrcPitch;
    pdst += 2*iDstPitch;
    pInA += 2*iSrcPitch;
    pInB += 2*iSrcPitch;
    pInC += 2*iSrcPitch;
    pInD += 2*iSrcPitch;
    pInE += 2*iSrcPitch;
    pInF += 2*iSrcPitch;
  }
}
<commit_msg>initialize the variable in umc_deinterlacing<commit_after>// Copyright (c) 2018-2020 Intel Corporation
//
// 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 "umc_deinterlacing.h"
#include "umc_video_data.h"
#include "ippi.h"
#include "ippvc.h"

using namespace UMC;

Deinterlacing::Deinterlacing()
{
  mMethod = DEINTERLACING_DUPLICATE;
}

Status Deinterlacing::SetMethod(DeinterlacingMethod method)
{
  mMethod = method;
  return UMC_OK;
}

static void DeinterlacingEdgeDetect(uint8_t *psrc,
                                    int32_t iSrcPitch,
                                    uint8_t *pdst,
                                    int32_t iDstPitch,
                                    int32_t w,
                                    int32_t h);

Status Deinterlacing::GetFrame(MediaData *input, MediaData *output)
{
  VideoData *in = DynamicCast<VideoData>(input);
  VideoData *out = DynamicCast<VideoData>(output);
  DeinterlacingMethod method = mMethod;
  int k;

  if (NULL == in || NULL == out) {
    return UMC_ERR_NULL_PTR;
  }

  ColorFormat cFormat = in->GetColorFormat();
  if (out->GetColorFormat() != cFormat) {
    return UMC_ERR_INVALID_PARAMS;
  }
  int32_t in_Width = in->GetWidth();
  int32_t in_Height = in->GetHeight();
  int32_t out_Width = out->GetWidth();
  int32_t out_Height = out->GetHeight();
  if ( (in_Width != out_Width) || (in_Height != out_Height) ) {
    return UMC_ERR_INVALID_PARAMS;
  }

  for (k = 0; k < in->GetNumPlanes(); k++) {
    VideoData::PlaneInfo srcPlane = {};
    const uint8_t *pSrc0; //, *pSrc1;
    uint8_t *pDst0, *pDst1;
    int srcPitch, dstPitch;
    mfxSize size;

    in->GetPlaneInfo(&srcPlane, k);
    pSrc0 = (const uint8_t*)in->GetPlanePointer(k);
    srcPitch = (int32_t)in->GetPlanePitch(k);
    pDst0 = (uint8_t*)out->GetPlanePointer(k);
    dstPitch = (int32_t)out->GetPlanePitch(k);
    size.width = srcPlane.m_ippSize.width * srcPlane.m_iSamples * srcPlane.m_iSampleSize;
    size.height = srcPlane.m_ippSize.height;

    if (method == DEINTERLACING_BLEND) {
      if (srcPlane.m_iSampleSize != 1) {
        //return UMC_ERR_UNSUPPORTED;
        method = DEINTERLACING_DUPLICATE;
      }
      mfxiDeinterlaceFilterTriangle_8u_C1R(pSrc0, srcPitch,
                                           pDst0, dstPitch,
                                           size,
                                           128,
                                           IPP_LOWER | IPP_UPPER | IPP_CENTER);
      continue;
    }

    if (method == DEINTERLACING_SPATIAL) {
      if (k == 0) { // Y
        if (srcPlane.m_iSampleSize != 1 || srcPlane.m_iSamples != 1) {
          //return UMC_ERR_UNSUPPORTED;
          method = DEINTERLACING_DUPLICATE;
        }
        DeinterlacingEdgeDetect((uint8_t*)pSrc0, srcPitch,
                                pDst0, dstPitch,
                                size.width, size.height);
        continue;
      } else { // U,V
        method = DEINTERLACING_DUPLICATE;
      }
    }

    // DEINTERLACING_DUPLICATE
    //pSrc1 = pSrc0 += srcPitch;
    pSrc0 += srcPitch;
    srcPitch *= 2;
    pDst1 = pDst0 + dstPitch;
    dstPitch *= 2;
    size.height /= 2;
    mfxiCopy_8u_C1R(pSrc0, srcPitch, pDst0, dstPitch, size);
    mfxiCopy_8u_C1R(pSrc0, srcPitch, pDst1, dstPitch, size);
  }

  return UMC_OK;
}

static void DeinterlacingEdgeDetect(uint8_t *psrc,
                                    int32_t iSrcPitch,
                                    uint8_t *pdst,
                                    int32_t iDstPitch,
                                    int32_t w,
                                    int32_t h)
{
  int32_t /*hi, lo,*/ x, y;
  int32_t res;
  uint8_t *pInA, *pInB, *pInC, *pInD, *pInE, *pInF;
  int32_t dif1, dif2, dif3;
  mfxSize roi = {w, h/2};

  // copy even lines
  mfxiCopy_8u_C1R(psrc, 2*iSrcPitch, pdst, 2*iDstPitch, roi);

  // then line #1 and line before last
  std::copy(psrc + iSrcPitch, psrc + 2*iSrcPitch, pdst + iDstPitch);
  std::copy(psrc + (h - 2) * iSrcPitch, psrc + (h - 2) * iSrcPitch + w, pdst + (h - 1)*iDstPitch);

  psrc += 3*iSrcPitch;
  pdst += 3*iDstPitch;
  pInB = psrc - iSrcPitch;
  pInA = pInB - 1;
  pInC = pInB + 1;
  pInE = psrc + iSrcPitch;
  pInD = pInE - 1;
  pInF = pInE + 1;

  for (y = 3; y <= h - 3; y += 2) {
    pdst[0] = psrc[0];
    pdst[w - 1] = psrc[w - 1];

    for (x = 1; x < w - 1; x++)
    {
      dif1 = abs((int32_t)pInA[x] - (int32_t)pInF[x]);
      dif2 = abs((int32_t)pInC[x] - (int32_t)pInD[x]);
      dif3 = abs((int32_t)pInB[x] - (int32_t)pInE[x]);

      if (dif1 < dif2) {
        if (dif1 < dif3) {
          res = ((int32_t)pInA[x] + (int32_t)pInF[x]) >> 1; //1
        } else {
          res = ((int32_t)pInB[x] + (int32_t)pInE[x]) >> 1; //3
        }
      } else {
        if (dif2 < dif3) {
          res = ((int32_t)pInC[x] + (int32_t)pInD[x]) >> 1; //2
        } else {
          res = ((int32_t)pInB[x] + (int32_t)pInE[x]) >> 1; //3
        }
      }
      pdst[x] = (uint8_t)res;
    }
    psrc += 2*iSrcPitch;
    pdst += 2*iDstPitch;
    pInA += 2*iSrcPitch;
    pInB += 2*iSrcPitch;
    pInC += 2*iSrcPitch;
    pInD += 2*iSrcPitch;
    pInE += 2*iSrcPitch;
    pInF += 2*iSrcPitch;
  }
}
<|endoftext|>


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

/// \author Masaru Morita

// NOTE: The contents of this file have been taken largely from the ros_control wiki tutorials

// ROS
#include <ros/ros.h>

// ros_control
#include <controller_manager/controller_manager.h>

#include "./../include/ackermann_steering_bot.h"

int main(int argc, char **argv)
{
  ros::init(argc, argv, "ackermann_steering_bot");
  ros::NodeHandle nh;

  AckermannSteeringBot robot;
  ROS_WARN_STREAM("period: " << robot.getPeriod().toSec());
  controller_manager::ControllerManager cm(&robot, nh);

  ros::Rate rate(1.0 / robot.getPeriod().toSec());
  ros::AsyncSpinner spinner(1);
  spinner.start();
  while(ros::ok())
  {
    ROS_WARN_STREAM("period: " << robot.getPeriod().toSec());
    robot.read();
    cm.update(robot.getTime(), robot.getPeriod());
    robot.write();
    rate.sleep();
  }
  spinner.stop();

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

/// \author Masaru Morita

// NOTE: The contents of this file have been taken largely from the ros_control wiki tutorials

// ROS
#include <ros/ros.h>

// ros_control
#include <controller_manager/controller_manager.h>

#include "./../include/ackermann_steering_bot.h"

int main(int argc, char **argv)
{
  ros::init(argc, argv, "ackermann_steering_bot");
  ros::NodeHandle nh;

  AckermannSteeringBot robot;
  ROS_WARN_STREAM("period: " << robot.getPeriod().toSec());
  controller_manager::ControllerManager cm(&robot, nh);

  ros::Rate rate(1.0 / robot.getPeriod().toSec());
  ros::AsyncSpinner spinner(1);
  spinner.start();
  while(ros::ok())
  {
    robot.read();
    cm.update(robot.getTime(), robot.getPeriod());
    robot.write();
    rate.sleep();
  }
  spinner.stop();

  return 0;
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep13/call_mss_draminit_mc.C $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2016                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

//Error handling and tracing
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
#include <isteps/hwpisteperror.H>
#include <initservice/isteps_trace.H>

//  targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>

// Istep 13 framework
#include "istep13consts.H"

// fapi2 HWP invoker
#include  <fapi2/plat_hwp_invoker.H>

//From Import Directory (EKB Repository)
#include  <config.h>
#include  <fapi2.H>
#include  <p9_mss_draminit_mc.H>

using namespace ERRORLOG;
using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace TARGETING;

namespace ISTEP_13
{
void* call_mss_draminit_mc (void *io_pArgs)
{
    errlHndl_t l_err = NULL;

    IStepError l_stepError;

    TARGETING::Target * sys = NULL;
    TARGETING::targetService().getTopLevelTarget( sys );

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,"call_mss_draminit_mc entry" );

    // Get all MCBIST
    TARGETING::TargetHandleList l_mcbistTargetList;
    getAllChiplets(l_mcbistTargetList, TYPE_MCBIST);

    for (const auto & l_mcbist_target : l_mcbistTargetList)
    {
        // Dump current run on target
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                "Running p9_mss_draminit_mc HWP on "
                "target HUID %.8X", TARGETING::get_huid(l_mcbist_target));

        fapi2::Target<fapi2::TARGET_TYPE_MCBIST> l_fapi_mcbist_target
            (l_mcbist_target);
        FAPI_INVOKE_HWP(l_err, p9_mss_draminit_mc, l_fapi_mcbist_target);

        if (l_err)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "ERROR 0x%.8X : p9_mss_draminit_mc HWP returns error",
                    l_err->reasonCode());

            // capture the target data in the elog
            ErrlUserDetailsTarget(l_mcbist_target).addToLog( l_err );

            // Create IStep error log and cross reference to error that occurred
            l_stepError.addErrorDetails( l_err );

            // Commit Error
            errlCommit( l_err, HWPF_COMP_ID );
        }
        else
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "SUCCESS running p9_mss_draminit_mc HWP on "
                       "target HUID %.8X", TARGETING::get_huid(l_mcbist_target));
        }

    } // End; memBuf loop

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit_mc exit" );

    return l_stepError.getErrorHandle();
}

};
<commit_msg>Insert workaround for issue with memdiags<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/isteps/istep13/call_mss_draminit_mc.C $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

//Error handling and tracing
#include <errl/errlentry.H>
#include <errl/errlmanager.H>
#include <errl/errludtarget.H>
#include <isteps/hwpisteperror.H>
#include <initservice/isteps_trace.H>

//  targeting support
#include <targeting/common/commontargeting.H>
#include <targeting/common/util.H>
#include <targeting/common/utilFilter.H>

// Istep 13 framework
#include "istep13consts.H"

// fapi2 HWP invoker
#include  <fapi2/plat_hwp_invoker.H>

//From Import Directory (EKB Repository)
#include  <config.h>
#include  <fapi2.H>
#include  <p9_mss_draminit_mc.H>

using namespace ERRORLOG;
using namespace ISTEP;
using namespace ISTEP_ERROR;
using namespace TARGETING;

namespace ISTEP_13
{
void* call_mss_draminit_mc (void *io_pArgs)
{
    errlHndl_t l_err = NULL;

    IStepError l_stepError;

    TARGETING::Target * sys = NULL;
    TARGETING::targetService().getTopLevelTarget( sys );

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,"call_mss_draminit_mc entry" );

    // Get all MCBIST
    TARGETING::TargetHandleList l_mcbistTargetList;
    getAllChiplets(l_mcbistTargetList, TYPE_MCBIST);

    for (const auto & l_mcbist_target : l_mcbistTargetList)
    {
        // Dump current run on target
        TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                "Running p9_mss_draminit_mc HWP on "
                "target HUID %.8X", TARGETING::get_huid(l_mcbist_target));

        fapi2::Target<fapi2::TARGET_TYPE_MCBIST> l_fapi_mcbist_target
            (l_mcbist_target);
        FAPI_INVOKE_HWP(l_err, p9_mss_draminit_mc, l_fapi_mcbist_target);

        if (l_err)
        {
            TRACFCOMP(ISTEPS_TRACE::g_trac_isteps_trace,
                    "ERROR 0x%.8X : p9_mss_draminit_mc HWP returns error",
                    l_err->reasonCode());

            // capture the target data in the elog
            ErrlUserDetailsTarget(l_mcbist_target).addToLog( l_err );

            // Create IStep error log and cross reference to error that occurred
            l_stepError.addErrorDetails( l_err );

            // Commit Error
            errlCommit( l_err, HWPF_COMP_ID );
        }
        else
        {
            TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
                       "SUCCESS running p9_mss_draminit_mc HWP on "
                       "target HUID %.8X", TARGETING::get_huid(l_mcbist_target));
        }

    } // End; memBuf loop

    //TODO RTC:167292 Remove this workaround that is clearing this scom register
    fapi2::buffer<uint64_t> l_data64;
    l_data64.flush<0>();
    // Get all MCAs
    TARGETING::TargetHandleList l_mcaTargetList;
    getAllChiplets(l_mcaTargetList, TYPE_MCA);

    //Clear out the MBA_FARB3Q reg(0x7010916) on all MCAs
    for (const auto & l_mca_target : l_mcaTargetList)
    {
        fapi2::Target<fapi2::TARGET_TYPE_MCA> l_fapi_mca_target
        (l_mca_target);
        fapi2::putScom(l_fapi_mca_target, 0x7010916, l_data64);
    }

    TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "call_mss_draminit_mc exit" );

    return l_stepError.getErrorHandle();
}

};
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "ITOStorage.h"

//--- standard modules used ----------------------------------------------------
#include "SysLog.h"
#include "System.h"
#include "MemHeader.h"
#include "InitFinisManagerFoundation.h"

//--- c-library modules used ---------------------------------------------------
#include <string.h>

#ifdef __370__
extern "C" void finalize();
#endif

#include <stdio.h>
#if defined(WIN32)
#define snprintf	_snprintf
#endif

//#define TRACK_USED_MEMORYBLOCKS 1

MemChecker::MemChecker(const char *scope, Allocator *a)
	: fAllocator(a)
	, fSizeAllocated(fAllocator->CurrentlyAllocated())
	, fScope(scope)
{
}

MemChecker::~MemChecker()
{
	if ( CheckDelta() > 0 ) {
		TraceDelta("MemChecker.~MemChecker: ");
	}
}

void MemChecker::TraceDelta(const char *message)
{
	char msgbuf[1024] = {'\0'};
	if (message) {
		SysLog::WriteToStderr( message, strlen(message));
	}
	l_long delta = CheckDelta();
	int bufsz = snprintf(msgbuf, sizeof(msgbuf), "\nMem Usage change by %.0f bytes in %s\n", (double)delta, fScope);
	SysLog::WriteToStderr( msgbuf, bufsz );
}

l_long MemChecker::CheckDelta()
{
	return fAllocator->CurrentlyAllocated() - fSizeAllocated;
}

//------------- Utilities for Memory Tracking --------------
MemTracker::MemTracker(const char *name)
	: fAllocated(0)
	, fMaxAllocated(0)
	, fNumAllocs(0)
	, fSizeAllocated(0)
	, fNumFrees(0)
	, fSizeFreed(0)
	, fId(-1)
	, fpName(strdup(name))	// copy string to be more flexible when using temporary param objects like Strings
{
}

void *MemTracker::operator new(size_t size)
{
	// never allocate on allocator, because we are tracking exactly the one...
	void *vp = ::calloc(1, sizeof(MemTracker));
	return vp;
}

void *MemTracker::operator new(size_t size, Allocator *)
{
	// never allocate on allocator, because we are tracking exactly the one...
	void *vp = ::calloc(1, sizeof(MemTracker));
	return vp;
}

void MemTracker::operator delete(void *vp)
{
	if (vp) {
		::operator delete(vp);
	}
}

void MemTracker::Init(MemTracker *t)
{
	fAllocated = t->fAllocated;
	fNumAllocs = t->fNumAllocs;
	fSizeAllocated = t->fSizeAllocated;
	fNumFrees = t->fNumFrees;
	fSizeFreed = t->fSizeFreed;
	fId = t->fId;
	fMaxAllocated = t->fMaxAllocated;
}

MemTracker::~MemTracker()
{
	delete fpName;
}

void MemTracker::SetId(long id)
{
	fId = id;
}

void MemTracker::TrackAlloc(MemoryHeader *mh)
{
	fAllocated += mh->fSize;
	++fNumAllocs;
	fSizeAllocated += mh->fSize;
	fMaxAllocated = itoMAX(fMaxAllocated, fAllocated);
#if defined(TRACK_USED_MEMORYBLOCKS)
	fUsedList.push_front(mh);
#endif
}

void MemTracker::TrackFree(MemoryHeader *mh)
{
	fAllocated -= mh->fSize;
	++fNumFrees;
	fSizeFreed += mh->fSize;
#if defined(TRACK_USED_MEMORYBLOCKS)
	UsedListType::iterator aUsedIterator;
	for ( aUsedIterator = fUsedList.begin(); aUsedIterator != fUsedList.end(); ++aUsedIterator ) {
		if ( *aUsedIterator == mh ) {
			fUsedList.erase(aUsedIterator);
			break;
		}
	}
#endif
}

void MemTracker::DumpUsedBlocks()
{
	if ( fUsedList.size() ) {
		SysLog::Error("Following memory blocks are still in use:");
		UsedListType::const_iterator aUsedIterator;
		long lIdx = 0;
		for ( aUsedIterator = fUsedList.begin(); aUsedIterator != fUsedList.end(); ++lIdx, ++aUsedIterator) {
			MemoryHeader *pMH = *aUsedIterator;
			String strBuf((void *)pMH, ( pMH->fSize + MemoryHeader::AlignedSize() ), Storage::Global());
			SysLog::WriteToStderr(String(Storage::Global()).Append("Block ").Append(lIdx).Append('\n'));
			SysLog::WriteToStderr(strBuf.DumpAsHex());
			SysLog::WriteToStderr("\n");
		}
	}
}

void MemTracker::PrintStatistic(long lLevel)
{
	if ( lLevel >= 2 ) {
		char buf[2048] = { 0 }; // safety margin for bytes
		snprintf(buf, sizeof(buf), "\nAllocator [%02ld] [%s]\n"
#if defined(WIN32)
				 "Peek Allocated  %20I64d bytes\n"
				 "Total Allocated %20I64d bytes in %15I64d runs (%ld/run)\n"
				 "Total Freed     %20I64d bytes in %15I64d runs (%ld/run)\n"
				 "------------------------------------------\n"
				 "Difference      %20I64d bytes\n",
#else
				 "Peek Allocated  %20lld bytes\n"
				 "Total Allocated %20lld bytes in %15lld runs (%ld/run)\n"
				 "Total Freed     %20lld bytes in %15lld runs (%ld/run)\n"
				 "------------------------------------------\n"
				 "Difference      %20lld bytes\n",
#endif
				 fId, fpName, fMaxAllocated,
				 fSizeAllocated , fNumAllocs, (long)(fSizeAllocated / ((fNumAllocs) ? fNumAllocs : 1)),
				 fSizeFreed, fNumFrees, (long)(fSizeFreed / ((fNumFrees) ? fNumFrees : 1)),
				 fAllocated
				);
		SysLog::WriteToStderr(buf, strlen(buf));
	}
}

MemTracker *Storage::DoMakeMemTracker(const char *name)
{
	return new MemTracker(name);
}

MemTracker *Storage::MakeMemTracker(const char *name, bool bThreadSafe)
{
	if  (fgHooks && !fgForceGlobal) {
		return fgHooks->MakeMemTracker(name, bThreadSafe);
	}
	return Storage::DoMakeMemTracker(name);
}

#if (defined(__GNUG__)  && __GNUC__ < 3)|| defined (__370__)
#include <new.h>
#elif (defined(__GNUG__)  && __GNUC__ >=3) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500) || (defined(WIN32) && defined(ONLY_STD_IOSTREAM))
#include <new>
#else
void *operator new(size_t size, void *vp)
{
	Assert(size > 0);
	if (vp == 0) {
		return ::calloc(size, sizeof(char));
	}
	return vp;
}
#endif

#if defined(WIN32) && (_MSC_VER >= 1200) && !defined(ONLY_STD_IOSTREAM)// VC6 or greater
void operator delete(void *ptr, void *vp)
{
	if (ptr) {
		::free(ptr);
	}
}
#endif

#if !defined (WIN32)
void operator delete(void *ptr)
{
	if (ptr) {
		::free(ptr);
	}
}
#endif

//---- Storage ------------------------------------------
Allocator *Storage::fgGlobalPool = 0;
StorageHooks *Storage::fgHooks = 0; // exchange this object when MT_Storage is used
bool Storage::fgForceGlobal = false;
long Storage::fglStatisticLevel = 0L;

class EXPORTDECL_FOUNDATION StorageInitializer : public InitFinisManagerFoundation
{
public:
	StorageInitializer(unsigned int uiPriority)
		: InitFinisManagerFoundation(uiPriority) {
		IFMTrace("StorageInitializer created\n");
	}
	~StorageInitializer()
	{}

	virtual void DoInit() {
		IFMTrace("Storage::Initialize\n");
		Storage::Initialize();
	}
	virtual void DoFinis() {
		IFMTrace("Storage::Finalize\n");
		Storage::Finalize();
	}
};

static StorageInitializer *psgStorageInitializer = new StorageInitializer(0);

Allocator *Storage::Current()
{
	if (fgHooks && !fgForceGlobal) {
		return fgHooks->Current();
	}
	return Storage::DoGlobal();
}

Allocator *Storage::Global()
{
	if (fgHooks && !fgForceGlobal) {
		return fgHooks->Global();
	}
	return Storage::DoGlobal();
}

void Storage::Initialize()
{
	Storage::DoInitialize();
	if (fgHooks && !fgForceGlobal) {
		fgHooks->Initialize();
	}
}

void Storage::Finalize()
{
	if (fgHooks && !fgForceGlobal) {
		fgHooks->Finalize();
	}
	Storage::DoFinalize();
}

void Storage::DoInitialize()
{
	static bool once = true;
	if (once) {
		const char *pEnvVar = getenv("TRACE_STORAGE");
		long lLevel = ( ( pEnvVar != 0 ) ? atol(pEnvVar) : 0 );
		fglStatisticLevel = lLevel;
		once = false;
	}
}

void Storage::DoFinalize()
{
	// terminate global allocator and force printing statistics above level 1
	if ( fglStatisticLevel >= 1 ) {
		Storage::DoGlobal()->PrintStatistic(2);
	}
}

void Storage::PrintStatistic(long lLevel)
{
	DoGlobal()->PrintStatistic(lLevel);
}

Allocator *Storage::DoGlobal()
{
	if (!Storage::fgGlobalPool) {
		Storage::fgGlobalPool = new GlobalAllocator();
	}
	return Storage::fgGlobalPool;
}

StorageHooks *Storage::SetHooks(StorageHooks *h)
{
	StorageHooks *pOldHook = fgHooks;
	if ( fgHooks ) {
		fgHooks->Finalize();
	}
	if ( h == NULL && fgHooks ) {
		fgHooks = fgHooks->GetOldHook();
		pOldHook = fgHooks;
	} else {
		fgHooks = h;
		if ( fgHooks != NULL ) {
			fgHooks->Initialize();
			fgHooks->SetOldHook(pOldHook);
		}
	}
	return pOldHook;
}

//--- Allocator -------------------------------------------------
Allocator::Allocator(long allocatorid)
	: fAllocatorId(allocatorid)
	, fRefCnt(0)
{
}

Allocator::~Allocator()
{
	Assert(0 == fRefCnt);
}

void *Allocator::Calloc(int n, size_t size)
{
	void *ret = Alloc(AllocSize(n, size));
	if (ret && n * size > 0) {
		memset(ret, 0, n * size);
	}
	return ret;
}

void *Allocator::Malloc(size_t size)
{
	return Alloc(AllocSize(size, 1));
}

void Allocator::Refresh()
{
	// give the allocator opportunity to reorganize
}

u_long Allocator::AllocSize(u_long n, size_t size)
{
	return (n * size) + MemoryHeader::AlignedSize();
}

void *Allocator::ExtMemStart(void *vp)
{
	if (vp) {
		Assert(((MemoryHeader *)vp)->fMagic == MemoryHeader::gcMagic);
		void *s = (((char *)(vp)) + MemoryHeader::AlignedSize()); // fSize does *not* include header
		// superfluous, Calloc takes care: memset(s, '\0', mh->fSize);
		return s;
	}
	return 0;
}

MemoryHeader *Allocator::RealMemStart(void *vp)
{
	if ( vp ) {
		MemoryHeader *mh = (MemoryHeader *) (((char *)(vp)) - MemoryHeader::AlignedSize());
		if (mh->fMagic == MemoryHeader::gcMagic) {
			return mh;
		}
	}
	return 0;
}

//---- GlobalAllocator ------------------------------------------
GlobalAllocator::GlobalAllocator() : Allocator(11223344L)
{
	fTracker = Storage::MakeMemTracker("GlobalAllocator", false);
	fTracker->SetId(fAllocatorId);
}

GlobalAllocator::~GlobalAllocator()
{
	if ( fTracker ) {
		delete fTracker;
	}
}

MemTracker *GlobalAllocator::ReplaceMemTracker(MemTracker *t)
{
	MemTracker *pOld = fTracker;
	if ( fTracker ) {
		fTracker = t;
	}
	return pOld;
}

l_long GlobalAllocator::CurrentlyAllocated()
{
	return fTracker->CurrentlyAllocated();
}
void GlobalAllocator::PrintStatistic(long lLevel)
{
	fTracker->PrintStatistic(lLevel);
}

void *GlobalAllocator::Alloc(u_long allocSize)
{
	void *vp = ::malloc(allocSize);
	if (vp) {
		MemoryHeader *mh = new(vp) MemoryHeader(allocSize - MemoryHeader::AlignedSize(), MemoryHeader::eUsedNotPooled);
		fTracker->TrackAlloc(mh);
		return ExtMemStart(mh);
	} else {
		static const char crashmsg[] = "FATAL: GlobalAllocator::Alloc malloc failed. I will crash :-(\n";
		SysLog::WriteToStderr(crashmsg, sizeof(crashmsg));
	}
	return NULL;
}

void  GlobalAllocator::Free(void *vp)
{
	if ( vp ) {
		MemoryHeader *header = RealMemStart(vp);
		if (header && header->fMagic == MemoryHeader::gcMagic) {
			Assert(header->fMagic == MemoryHeader::gcMagic); // should combine magic with state
			Assert(header->fState & MemoryHeader::eUsed);
			fTracker->TrackFree(header);
			vp = header;
		}
		::free(vp);
	}
}

#ifdef __370__
// need a C-function as the linker cannot resolve C++ here
void finalize()
{
	Storage::Finalize();
}
#endif

Allocator *TestStorageHooks::Global()
{
	return Storage::DoGlobal();
}

Allocator *TestStorageHooks::Current()
{
	if (fAllocator) {
		return fAllocator;
	}

	return Storage::DoGlobal();
}

void TestStorageHooks::Initialize()
{
}

void TestStorageHooks::Finalize()
{
}

TestStorageHooks::TestStorageHooks(Allocator *wdallocator)
	: fAllocator(wdallocator)
	, fpOldHook(NULL)
{
	fpOldHook = Storage::SetHooks(this);
}

TestStorageHooks::~TestStorageHooks()
{
	StorageHooks *pHook = Storage::SetHooks(NULL);
	Assert( pHook == fpOldHook && "another Storage::SetHook() was called without restoring old Hook!");
}

MemTracker *TestStorageHooks::MakeMemTracker(const char *name, bool)
{
	return new MemTracker(name);
}
<commit_msg>MemChecker will only print out when memory was consumed and not freed MemTracker will only get created when TRACE_STORAGE >=1 added Storage::Initialize() before creating GlobalAllocator to have a correct value in GetStatisticLevel()<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "ITOStorage.h"

//--- standard modules used ----------------------------------------------------
#include "SysLog.h"
#include "System.h"
#include "MemHeader.h"
#include "InitFinisManagerFoundation.h"

//--- c-library modules used ---------------------------------------------------
#include <string.h>

#ifdef __370__
extern "C" void finalize();
#endif

#include <stdio.h>
#if defined(WIN32)
#define snprintf	_snprintf
#endif

//#define TRACK_USED_MEMORYBLOCKS 1

MemChecker::MemChecker(const char *scope, Allocator *a)
	: fAllocator(a)
	, fSizeAllocated(fAllocator->CurrentlyAllocated())
	, fScope(scope)
{
}

MemChecker::~MemChecker()
{
	TraceDelta("MemChecker.~MemChecker: ");
}

void MemChecker::TraceDelta(const char *message)
{
	l_long delta = CheckDelta();
	if ( delta > 0 ) {
		char msgbuf[1024] = {'\0'};
		if (message) {
			SysLog::WriteToStderr( message, strlen(message));
		}
		int bufsz = snprintf(msgbuf, sizeof(msgbuf), "\nMem Usage change by %.0f bytes in %s\n", (double)delta, fScope);
		SysLog::WriteToStderr( msgbuf, bufsz );
	}
}

l_long MemChecker::CheckDelta()
{
	return fAllocator->CurrentlyAllocated() - fSizeAllocated;
}

//------------- Utilities for Memory Tracking --------------
MemTracker::MemTracker(const char *name)
	: fAllocated(0)
	, fMaxAllocated(0)
	, fNumAllocs(0)
	, fSizeAllocated(0)
	, fNumFrees(0)
	, fSizeFreed(0)
	, fId(-1)
	, fpName(strdup(name))	// copy string to be more flexible when using temporary param objects like Strings
{
}

void *MemTracker::operator new(size_t size)
{
	// never allocate on allocator, because we are tracking exactly the one...
	void *vp = ::calloc(1, sizeof(MemTracker));
	return vp;
}

void *MemTracker::operator new(size_t size, Allocator *)
{
	// never allocate on allocator, because we are tracking exactly the one...
	void *vp = ::calloc(1, sizeof(MemTracker));
	return vp;
}

void MemTracker::operator delete(void *vp)
{
	if (vp) {
		::operator delete(vp);
	}
}

void MemTracker::Init(MemTracker *t)
{
	fAllocated = t->fAllocated;
	fNumAllocs = t->fNumAllocs;
	fSizeAllocated = t->fSizeAllocated;
	fNumFrees = t->fNumFrees;
	fSizeFreed = t->fSizeFreed;
	fId = t->fId;
	fMaxAllocated = t->fMaxAllocated;
}

MemTracker::~MemTracker()
{
	delete fpName;
}

void MemTracker::SetId(long id)
{
	fId = id;
}

void MemTracker::TrackAlloc(MemoryHeader *mh)
{
	fAllocated += mh->fSize;
	++fNumAllocs;
	fSizeAllocated += mh->fSize;
	fMaxAllocated = itoMAX(fMaxAllocated, fAllocated);
#if defined(TRACK_USED_MEMORYBLOCKS)
	fUsedList.push_front(mh);
#endif
}

void MemTracker::TrackFree(MemoryHeader *mh)
{
	fAllocated -= mh->fSize;
	++fNumFrees;
	fSizeFreed += mh->fSize;
#if defined(TRACK_USED_MEMORYBLOCKS)
	UsedListType::iterator aUsedIterator;
	for ( aUsedIterator = fUsedList.begin(); aUsedIterator != fUsedList.end(); ++aUsedIterator ) {
		if ( *aUsedIterator == mh ) {
			fUsedList.erase(aUsedIterator);
			break;
		}
	}
#endif
}

void MemTracker::DumpUsedBlocks()
{
	if ( fUsedList.size() ) {
		SysLog::Error("Following memory blocks are still in use:");
		UsedListType::const_iterator aUsedIterator;
		long lIdx = 0;
		for ( aUsedIterator = fUsedList.begin(); aUsedIterator != fUsedList.end(); ++lIdx, ++aUsedIterator) {
			MemoryHeader *pMH = *aUsedIterator;
			String strBuf((void *)pMH, ( pMH->fSize + MemoryHeader::AlignedSize() ), Storage::Global());
			SysLog::WriteToStderr(String(Storage::Global()).Append("Block ").Append(lIdx).Append('\n'));
			SysLog::WriteToStderr(strBuf.DumpAsHex());
			SysLog::WriteToStderr("\n");
		}
	}
}

void MemTracker::PrintStatistic(long lLevel)
{
	if ( lLevel >= 2 ) {
		char buf[2048] = { 0 }; // safety margin for bytes
		snprintf(buf, sizeof(buf), "\nAllocator [%02ld] [%s]\n"
#if defined(WIN32)
				 "Peek Allocated  %20I64d bytes\n"
				 "Total Allocated %20I64d bytes in %15I64d runs (%ld/run)\n"
				 "Total Freed     %20I64d bytes in %15I64d runs (%ld/run)\n"
				 "------------------------------------------\n"
				 "Difference      %20I64d bytes\n",
#else
				 "Peek Allocated  %20lld bytes\n"
				 "Total Allocated %20lld bytes in %15lld runs (%ld/run)\n"
				 "Total Freed     %20lld bytes in %15lld runs (%ld/run)\n"
				 "------------------------------------------\n"
				 "Difference      %20lld bytes\n",
#endif
				 fId, fpName, fMaxAllocated,
				 fSizeAllocated , fNumAllocs, (long)(fSizeAllocated / ((fNumAllocs) ? fNumAllocs : 1)),
				 fSizeFreed, fNumFrees, (long)(fSizeFreed / ((fNumFrees) ? fNumFrees : 1)),
				 fAllocated
				);
		SysLog::WriteToStderr(buf, strlen(buf));
	}
}

MemTracker *Storage::DoMakeMemTracker(const char *name)
{
	return new MemTracker(name);
}

MemTracker *Storage::MakeMemTracker(const char *name, bool bThreadSafe)
{
	if  (fgHooks && !fgForceGlobal) {
		return fgHooks->MakeMemTracker(name, bThreadSafe);
	}
	return Storage::DoMakeMemTracker(name);
}

#if (defined(__GNUG__)  && __GNUC__ < 3)|| defined (__370__)
#include <new.h>
#elif (defined(__GNUG__)  && __GNUC__ >=3) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x500) || (defined(WIN32) && defined(ONLY_STD_IOSTREAM))
#include <new>
#else
void *operator new(size_t size, void *vp)
{
	Assert(size > 0);
	if (vp == 0) {
		return ::calloc(size, sizeof(char));
	}
	return vp;
}
#endif

#if defined(WIN32) && (_MSC_VER >= 1200) && !defined(ONLY_STD_IOSTREAM)// VC6 or greater
void operator delete(void *ptr, void *vp)
{
	if (ptr) {
		::free(ptr);
	}
}
#endif

#if !defined (WIN32)
void operator delete(void *ptr)
{
	if (ptr) {
		::free(ptr);
	}
}
#endif

//---- Storage ------------------------------------------
Allocator *Storage::fgGlobalPool = 0;
StorageHooks *Storage::fgHooks = 0; // exchange this object when MT_Storage is used
bool Storage::fgForceGlobal = false;
long Storage::fglStatisticLevel = 0L;

class EXPORTDECL_FOUNDATION StorageInitializer : public InitFinisManagerFoundation
{
public:
	StorageInitializer(unsigned int uiPriority)
		: InitFinisManagerFoundation(uiPriority) {
		IFMTrace("StorageInitializer created\n");
	}
	~StorageInitializer()
	{}

	virtual void DoInit() {
		IFMTrace("Storage::Initialize\n");
		Storage::Initialize();
	}
	virtual void DoFinis() {
		IFMTrace("Storage::Finalize\n");
		Storage::Finalize();
	}
};

static StorageInitializer *psgStorageInitializer = new StorageInitializer(0);

Allocator *Storage::Current()
{
	if (fgHooks && !fgForceGlobal) {
		return fgHooks->Current();
	}
	return Storage::DoGlobal();
}

Allocator *Storage::Global()
{
	if (fgHooks && !fgForceGlobal) {
		return fgHooks->Global();
	}
	return Storage::DoGlobal();
}

void Storage::Initialize()
{
	Storage::DoInitialize();
	if ( fgHooks && !fgForceGlobal ) {
		fgHooks->Initialize();
	}
}

void Storage::Finalize()
{
	if (fgHooks && !fgForceGlobal) {
		fgHooks->Finalize();
	}
	Storage::DoFinalize();
}

void Storage::DoInitialize()
{
	static bool once = true;
	if (once) {
		const char *pEnvVar = getenv("TRACE_STORAGE");
		long lLevel = ( ( pEnvVar != 0 ) ? atol(pEnvVar) : 0 );
		fglStatisticLevel = lLevel;
		once = false;
	}
}

void Storage::DoFinalize()
{
	// terminate global allocator and force printing statistics above level 1
	if ( GetStatisticLevel() >= 1 ) {
		Storage::DoGlobal()->PrintStatistic(2);
	}
}

void Storage::PrintStatistic(long lLevel)
{
	DoGlobal()->PrintStatistic(lLevel);
}

Allocator *Storage::DoGlobal()
{
	if ( !Storage::fgGlobalPool ) {
		Storage::Initialize();
		Storage::fgGlobalPool = new GlobalAllocator();
	}
	return Storage::fgGlobalPool;
}

StorageHooks *Storage::SetHooks(StorageHooks *h)
{
	StorageHooks *pOldHook = fgHooks;
	if ( fgHooks ) {
		fgHooks->Finalize();
	}
	if ( h == NULL && fgHooks ) {
		fgHooks = fgHooks->GetOldHook();
		pOldHook = fgHooks;
	} else {
		fgHooks = h;
		if ( fgHooks != NULL ) {
			fgHooks->Initialize();
			fgHooks->SetOldHook(pOldHook);
		}
	}
	return pOldHook;
}

//--- Allocator -------------------------------------------------
Allocator::Allocator(long allocatorid)
	: fAllocatorId(allocatorid)
	, fRefCnt(0)
{
}

Allocator::~Allocator()
{
	Assert(0 == fRefCnt);
}

void *Allocator::Calloc(int n, size_t size)
{
	void *ret = Alloc(AllocSize(n, size));
	if (ret && n * size > 0) {
		memset(ret, 0, n * size);
	}
	return ret;
}

void *Allocator::Malloc(size_t size)
{
	return Alloc(AllocSize(size, 1));
}

void Allocator::Refresh()
{
	// give the allocator opportunity to reorganize
}

u_long Allocator::AllocSize(u_long n, size_t size)
{
	return (n * size) + MemoryHeader::AlignedSize();
}

void *Allocator::ExtMemStart(void *vp)
{
	if (vp) {
		Assert(((MemoryHeader *)vp)->fMagic == MemoryHeader::gcMagic);
		void *s = (((char *)(vp)) + MemoryHeader::AlignedSize()); // fSize does *not* include header
		// superfluous, Calloc takes care: memset(s, '\0', mh->fSize);
		return s;
	}
	return 0;
}

MemoryHeader *Allocator::RealMemStart(void *vp)
{
	if ( vp ) {
		MemoryHeader *mh = (MemoryHeader *) (((char *)(vp)) - MemoryHeader::AlignedSize());
		if (mh->fMagic == MemoryHeader::gcMagic) {
			return mh;
		}
	}
	return 0;
}

//---- GlobalAllocator ------------------------------------------
GlobalAllocator::GlobalAllocator()
	: Allocator(11223344L)
	, fTracker(NULL)
{
	if ( Storage::GetStatisticLevel() >= 1 ) {
		fTracker = Storage::MakeMemTracker("GlobalAllocator", false);
		fTracker->SetId(fAllocatorId);
	}
}

GlobalAllocator::~GlobalAllocator()
{
	if ( fTracker ) {
		delete fTracker;
		fTracker = NULL;
	}
}

MemTracker *GlobalAllocator::ReplaceMemTracker(MemTracker *t)
{
	MemTracker *pOld = fTracker;
	if ( fTracker ) {
		fTracker = t;
	}
	return pOld;
}

l_long GlobalAllocator::CurrentlyAllocated()
{
	if ( fTracker ) {
		return fTracker->CurrentlyAllocated();
	}
	return 0LL;
}

void GlobalAllocator::PrintStatistic(long lLevel)
{
	if ( fTracker ) {
		fTracker->PrintStatistic(lLevel);
	}
}

void *GlobalAllocator::Alloc(u_long allocSize)
{
	void *vp = ::malloc(allocSize);
	if (vp) {
		MemoryHeader *mh = new(vp) MemoryHeader(allocSize - MemoryHeader::AlignedSize(), MemoryHeader::eUsedNotPooled);
		if ( fTracker ) {
			fTracker->TrackAlloc(mh);
		}
		return ExtMemStart(mh);
	} else {
		static const char crashmsg[] = "FATAL: GlobalAllocator::Alloc malloc failed. I will crash :-(\n";
		SysLog::WriteToStderr(crashmsg, sizeof(crashmsg));
	}
	return NULL;
}

void  GlobalAllocator::Free(void *vp)
{
	if ( vp ) {
		MemoryHeader *header = RealMemStart(vp);
		if (header && header->fMagic == MemoryHeader::gcMagic) {
			Assert(header->fMagic == MemoryHeader::gcMagic); // should combine magic with state
			Assert(header->fState & MemoryHeader::eUsed);
			if ( fTracker ) {
				fTracker->TrackFree(header);
			}
			vp = header;
		}
		::free(vp);
	}
}

#ifdef __370__
// need a C-function as the linker cannot resolve C++ here
void finalize()
{
	Storage::Finalize();
}
#endif

Allocator *TestStorageHooks::Global()
{
	return Storage::DoGlobal();
}

Allocator *TestStorageHooks::Current()
{
	if (fAllocator) {
		return fAllocator;
	}

	return Storage::DoGlobal();
}

void TestStorageHooks::Initialize()
{
}

void TestStorageHooks::Finalize()
{
}

TestStorageHooks::TestStorageHooks(Allocator *wdallocator)
	: fAllocator(wdallocator)
	, fpOldHook(NULL)
{
	fpOldHook = Storage::SetHooks(this);
}

TestStorageHooks::~TestStorageHooks()
{
	StorageHooks *pHook = Storage::SetHooks(NULL);
	Assert( pHook == fpOldHook && "another Storage::SetHook() was called without restoring old Hook!");
}

MemTracker *TestStorageHooks::MakeMemTracker(const char *name, bool)
{
	return new MemTracker(name);
}
<|endoftext|>