<commit_before>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "file/path.h"
#include "file/dicom/image.h"
#include "file/dicom/series.h"
#include "file/dicom/study.h"
#include "file/dicom/patient.h"
#include "file/dicom/csa_entry.h"

namespace MR
{
  namespace File
  {
    namespace Dicom
    {

      void Image::parse_item (Element& item, const std::string& dirname)
      {
        switch (item.group) {
          case 0x0004U:
            if (item.element == 0x1500U) {
              assert (dirname.size());
              filename = dirname;
              std::vector<std::string> V (item.get_string());
              for (size_t n = 0; n < V.size(); n++)
                filename = Path::join (filename, V[n]);
            }
            break;
          case 0x0008U:
            if (item.element == 0x0070U) manufacturer = item.get_string() [0];
            return;
          case 0x0018U:
            switch (item.element) {
              case 0x0050U:
                slice_thickness = item.get_float() [0];
                return;
              case 0x0088U:
                slice_spacing = item.get_float() [0];
                return;
              case 0x1310U:
                acq_dim[0] = std::max (item.get_uint() [0], item.get_uint() [1]);
                acq_dim[1] = std::max (item.get_uint() [2], item.get_uint() [3]);

                return;
              case 0x0024U:
                sequence_name = item.get_string() [0];
                if (!sequence_name.size()) return;
                {
                  int c = sequence_name.size()-1;
                  while (c >= 0 && isdigit (sequence_name[c])) c--;
                  c++;
                  sequence = c < int(sequence_name.size()-1) ? to<size_t> (sequence_name.substr (c)) : 0;
                }
                return;
              case 0x9087U:
                bvalue = item.get_float() [0];
                return;
              case 0x9089U:
                G[0] = item.get_float() [0];
                G[1] = item.get_float() [1];
                G[2] = item.get_float() [2];
                return;

            }
            return;
          case 0x0019U:
            switch (item.element) { // GE DW encoding info:
              case 0x10BBU:
                if (item.get_float().size()) G[0] = item.get_float() [0];
                return;
              case 0x10BCU:
                if (item.get_float().size()) G[1] = item.get_float() [0];
                return;
              case 0x10BDU:
                if (item.get_float().size()) G[2] = item.get_float() [0];
                return;
            }
            return;
          case 0x0020U:
            switch (item.element) {
              case 0x0012U:
                acq = item.get_uint() [0];
                return;
              case 0x0013U:
                instance = item.get_uint() [0];
                return;
              case 0x0032U:
                position_vector[0] = item.get_float() [0];
                position_vector[1] = item.get_float() [1];
                position_vector[2] = item.get_float() [2];
                return;
              case 0x0037U:
                orientation_x[0] = item.get_float() [0];
                orientation_x[1] = item.get_float() [1];
                orientation_x[2] = item.get_float() [2];
                orientation_y[0] = item.get_float() [3];
                orientation_y[1] = item.get_float() [4];
                orientation_y[2] = item.get_float() [5];
                Math::normalise (orientation_x);
                Math::normalise (orientation_y);
                return;
            }
            return;
          case 0x0028U:
            switch (item.element) {
              case 0x0010U:
                dim[1] = item.get_uint() [0];
                return;
              case 0x0011U:
                dim[0] = item.get_uint() [0];
                return;
              case 0x0030U:
                pixel_size[0] = item.get_float() [0];
                pixel_size[1] = item.get_float() [1];
                return;
              case 0x0100U:
                bits_alloc = item.get_uint() [0];
                return;
              case 0x1052U:
                scale_intercept = item.get_float() [0];
                return;
              case 0x1053U:
                scale_slope = item.get_float() [0];
                return;
            }
            return;
          case 0x0029U:
            if (item.element == 0x1010U || item.element == 0x1020U) {
              decode_csa (item.data, item.data + item.size);
              return;
            }
            else return;
          case 0x0043U: // GEMS_PARMS_01 block
            if (item.element == 0x1039U) if (item.get_int().size()) bvalue = item.get_int() [0];
            return;
          case 0x2001U: // Philips DW encoding info:
            if (item.element == 0x1003) bvalue = item.get_float() [0];
            return;
          case 0x2005U: // Philips DW encoding info:
            switch (item.element) {
              case 0x10B0U:
                G[0] = item.get_float() [0];
                return;
              case 0x10B1U:
                G[1] = item.get_float() [0];
                return;
              case 0x10B2U:
                G[2] = item.get_float() [0];
                return;
            }
            return;

          case 0x7FE0U:
            if (item.element == 0x0010U) {
              data = item.offset (item.data);
              data_size = item.size;
              is_BE = item.is_big_endian();
              return;
            }
            return;
        }

        return;
      }

      void Image::read ()
      {
        Element item;
        item.set (filename);

        while (item.read())
          if (item.item_number.size() == 0)
            parse_item (item);

        calc_distance();
      }

      void Image::print_fields (bool dcm, bool csa) const
      {
        if (!filename.size()) return;

        Element item;
        item.set (filename);

        fprintf (stdout,
                 "**********************************************************\n"\
                 "  %s\n" \
                 "**********************************************************\n",
                 filename.c_str());

        while (item.read()) {
          if (dcm) item.print();
          if (csa && item.group == 0x0029U) {
            if (item.element == 0x1010U || item.element == 0x1020U) {
              CSAEntry entry (item.data, item.data + item.size, true);
              while (entry.parse() == 0);
            }
          }
        }
      }

      void Image::decode_csa (const uint8_t* start, const uint8_t* end)
      {
        CSAEntry entry (start, end);

        while (entry.parse()) {
          if (strcmp ("B_value", entry.key()) == 0) bvalue = entry.get_float();
          else if (strcmp ("DiffusionGradientDirection", entry.key()) == 0) entry.get_float (G);
          else if (strcmp ("NumberOfImagesInMosaic", entry.key()) == 0) images_in_mosaic = entry.get_int();
          else if (strcmp ("SliceNormalVector", entry.key()) == 0) entry.get_float (orientation_z);
        }

        if (G[0] && bvalue)
          if (Math::abs (G[0]) > 1.0 && Math::abs (G[1]) > 1.0 && Math::abs (G[2]) > 1.0)
            bvalue = G[0] = G[1] = G[2] = 0.0;
      }

      std::ostream& operator<< (std::ostream& stream, const Image& item)
      {
        stream << "            " << (item.instance == std::numeric_limits<size_t>::max() ? 0 : item.instance) << "#"
               << (item.acq == std::numeric_limits<size_t>::max() ? 0 : item.acq) << ":"
               << (item.sequence == std::numeric_limits<size_t>::max() ? 0 : item.sequence) << " ("
               << (item.sequence_name.size() ? item.sequence_name : "?") << "), "
               << item.dim[0] << "x" << item.dim[1] << ", "
               << item.pixel_size[0] << "x" << item.pixel_size[1] << " x "
               << item.slice_thickness << " mm, [ "
               << item.position_vector[0] << " " << item.position_vector[1] << " " << item.position_vector[2] << " ] [ "
               << item.orientation_x[0] << " " << item.orientation_x[1] << " " << item.orientation_x[2] << " ] [ "
               << item.orientation_y[0] << " " << item.orientation_y[1] << " " << item.orientation_y[2] << " ] "
               << (item.filename.size() ? item.filename : "") << "\n";

        return (stream);
      }

    }
  }
}

<commit_msg>added support for reading Siemens private DICOM tags (0019,100C) & (0019,100D) to retrieve DW information - needed for some Skyra data<commit_after>/*
    Copyright 2008 Brain Research Institute, Melbourne, Australia

    Written by J-Donald Tournier, 27/06/08.

    This file is part of MRtrix.

    MRtrix is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MRtrix is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MRtrix.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "file/path.h"
#include "file/dicom/image.h"
#include "file/dicom/series.h"
#include "file/dicom/study.h"
#include "file/dicom/patient.h"
#include "file/dicom/csa_entry.h"

namespace MR
{
  namespace File
  {
    namespace Dicom
    {

      void Image::parse_item (Element& item, const std::string& dirname)
      {
        switch (item.group) {
          case 0x0004U:
            if (item.element == 0x1500U) {
              assert (dirname.size());
              filename = dirname;
              std::vector<std::string> V (item.get_string());
              for (size_t n = 0; n < V.size(); n++)
                filename = Path::join (filename, V[n]);
            }
            break;
          case 0x0008U:
            if (item.element == 0x0070U) manufacturer = item.get_string() [0];
            return;
          case 0x0018U:
            switch (item.element) {
              case 0x0050U:
                slice_thickness = item.get_float() [0];
                return;
              case 0x0088U:
                slice_spacing = item.get_float() [0];
                return;
              case 0x1310U:
                acq_dim[0] = std::max (item.get_uint() [0], item.get_uint() [1]);
                acq_dim[1] = std::max (item.get_uint() [2], item.get_uint() [3]);

                return;
              case 0x0024U:
                sequence_name = item.get_string() [0];
                if (!sequence_name.size()) return;
                {
                  int c = sequence_name.size()-1;
                  while (c >= 0 && isdigit (sequence_name[c])) c--;
                  c++;
                  sequence = c < int(sequence_name.size()-1) ? to<size_t> (sequence_name.substr (c)) : 0;
                }
                return;
              case 0x9087U:
                bvalue = item.get_float() [0];
                return;
              case 0x9089U:
                G[0] = item.get_float() [0];
                G[1] = item.get_float() [1];
                G[2] = item.get_float() [2];
                return;

            }
            return;
          case 0x0019U:
            switch (item.element) { // GE DW encoding info:
              case 0x10BBU:
                if (item.get_float().size()) G[0] = item.get_float() [0];
                return;
              case 0x10BCU:
                if (item.get_float().size()) G[1] = item.get_float() [0];
                return;
              case 0x10BDU:
                if (item.get_float().size()) G[2] = item.get_float() [0];
                return;
              case 0x100CU: //Siemens private DW encoding tags:
                if (item.get_int().size()) bvalue = item.get_int()[0];
                return;
              case 0x100EU:
                if (item.get_float().size() == 3) {
                  G[0] = item.get_float()[0];
                  G[1] = item.get_float()[1];
                  G[2] = item.get_float()[2];
                }
                return;
            }
            return;
          case 0x0020U:
            switch (item.element) {
              case 0x0012U:
                acq = item.get_uint() [0];
                return;
              case 0x0013U:
                instance = item.get_uint() [0];
                return;
              case 0x0032U:
                position_vector[0] = item.get_float() [0];
                position_vector[1] = item.get_float() [1];
                position_vector[2] = item.get_float() [2];
                return;
              case 0x0037U:
                orientation_x[0] = item.get_float() [0];
                orientation_x[1] = item.get_float() [1];
                orientation_x[2] = item.get_float() [2];
                orientation_y[0] = item.get_float() [3];
                orientation_y[1] = item.get_float() [4];
                orientation_y[2] = item.get_float() [5];
                Math::normalise (orientation_x);
                Math::normalise (orientation_y);
                return;
            }
            return;
          case 0x0028U:
            switch (item.element) {
              case 0x0010U:
                dim[1] = item.get_uint() [0];
                return;
              case 0x0011U:
                dim[0] = item.get_uint() [0];
                return;
              case 0x0030U:
                pixel_size[0] = item.get_float() [0];
                pixel_size[1] = item.get_float() [1];
                return;
              case 0x0100U:
                bits_alloc = item.get_uint() [0];
                return;
              case 0x1052U:
                scale_intercept = item.get_float() [0];
                return;
              case 0x1053U:
                scale_slope = item.get_float() [0];
                return;
            }
            return;
          case 0x0029U:
            if (item.element == 0x1010U || item.element == 0x1020U) {
              decode_csa (item.data, item.data + item.size);
              return;
            }
            else return;
          case 0x0043U: // GEMS_PARMS_01 block
            if (item.element == 0x1039U) if (item.get_int().size()) bvalue = item.get_int() [0];
            return;
          case 0x2001U: // Philips DW encoding info:
            if (item.element == 0x1003) bvalue = item.get_float() [0];
            return;
          case 0x2005U: // Philips DW encoding info:
            switch (item.element) {
              case 0x10B0U:
                G[0] = item.get_float() [0];
                return;
              case 0x10B1U:
                G[1] = item.get_float() [0];
                return;
              case 0x10B2U:
                G[2] = item.get_float() [0];
                return;
            }
            return;

          case 0x7FE0U:
            if (item.element == 0x0010U) {
              data = item.offset (item.data);
              data_size = item.size;
              is_BE = item.is_big_endian();
              return;
            }
            return;
        }

        return;
      }

      void Image::read ()
      {
        Element item;
        item.set (filename);

        while (item.read())
          if (item.item_number.size() == 0)
            parse_item (item);

        calc_distance();
      }

      void Image::print_fields (bool dcm, bool csa) const
      {
        if (!filename.size()) return;

        Element item;
        item.set (filename);

        fprintf (stdout,
                 "**********************************************************\n"\
                 "  %s\n" \
                 "**********************************************************\n",
                 filename.c_str());

        while (item.read()) {
          if (dcm) item.print();
          if (csa && item.group == 0x0029U) {
            if (item.element == 0x1010U || item.element == 0x1020U) {
              CSAEntry entry (item.data, item.data + item.size, true);
              while (entry.parse() == 0);
            }
          }
        }
      }

      void Image::decode_csa (const uint8_t* start, const uint8_t* end)
      {
        CSAEntry entry (start, end);

        while (entry.parse()) {
          if (strcmp ("B_value", entry.key()) == 0) bvalue = entry.get_float();
          else if (strcmp ("DiffusionGradientDirection", entry.key()) == 0) entry.get_float (G);
          else if (strcmp ("NumberOfImagesInMosaic", entry.key()) == 0) images_in_mosaic = entry.get_int();
          else if (strcmp ("SliceNormalVector", entry.key()) == 0) entry.get_float (orientation_z);
        }

        if (G[0] && bvalue)
          if (Math::abs (G[0]) > 1.0 && Math::abs (G[1]) > 1.0 && Math::abs (G[2]) > 1.0)
            bvalue = G[0] = G[1] = G[2] = 0.0;
      }

      std::ostream& operator<< (std::ostream& stream, const Image& item)
      {
        stream << "            " << (item.instance == std::numeric_limits<size_t>::max() ? 0 : item.instance) << "#"
               << (item.acq == std::numeric_limits<size_t>::max() ? 0 : item.acq) << ":"
               << (item.sequence == std::numeric_limits<size_t>::max() ? 0 : item.sequence) << " ("
               << (item.sequence_name.size() ? item.sequence_name : "?") << "), "
               << item.dim[0] << "x" << item.dim[1] << ", "
               << item.pixel_size[0] << "x" << item.pixel_size[1] << " x "
               << item.slice_thickness << " mm, [ "
               << item.position_vector[0] << " " << item.position_vector[1] << " " << item.position_vector[2] << " ] [ "
               << item.orientation_x[0] << " " << item.orientation_x[1] << " " << item.orientation_x[2] << " ] [ "
               << item.orientation_y[0] << " " << item.orientation_y[1] << " " << item.orientation_y[2] << " ] "
               << (item.filename.size() ? item.filename : "") << "\n";

        return (stream);
      }

    }
  }
}

<|endoftext|>


<commit_before>#include "ProjectManager.hpp"
#include "ViewManager.hpp"
#include "DataSpecRegistry.hpp"
#include "hecl/Blender/Connection.hpp"

namespace urde {
static logvisor::Module Log("URDE::ProjectManager");
ProjectManager* ProjectManager::g_SharedManager = nullptr;

CToken ProjectResourcePool::GetObj(std::string_view name) {
  CToken ret = CSimplePool::GetObj(name);
  if (ret)
    return ret;

  hecl::ProjectPath path(*m_parent.project(), name);
  SObjectTag tag =
      static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
  if (tag)
    return CSimplePool::GetObj(tag);

  return {};
}

CToken ProjectResourcePool::GetObj(std::string_view name, const CVParamTransfer& pvxfer) {
  CToken ret = CSimplePool::GetObj(name, pvxfer);
  if (ret)
    return ret;

  hecl::ProjectPath path(*m_parent.project(), name);
  SObjectTag tag =
      static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
  if (tag)
    return CSimplePool::GetObj(tag, pvxfer);

  return {};
}

bool ProjectManager::m_registeredSpecs = false;
ProjectManager::ProjectManager(ViewManager& vm)
: m_vm(vm), m_clientProc(nullptr), m_factoryMP1(m_clientProc), m_objStore(m_factoryMP1, *this) {
  if (!m_registeredSpecs) {
    HECLRegisterDataSpecs();
    m_registeredSpecs = true;
  }
  g_SharedManager = this;
}

bool ProjectManager::newProject(hecl::SystemStringView path) {
  hecl::ProjectRootPath projPath = hecl::SearchForProject(path);
  if (projPath) {
    Log.report(logvisor::Warning, fmt(_SYS_STR("project already exists at '{}'")), path);
    return false;
  }

  hecl::MakeDir(path.data());
  m_proj.reset(new hecl::Database::Project(path));
  if (!*m_proj) {
    m_proj.reset();
    return false;
  }

  m_vm.ProjectChanged(*m_proj);
  m_vm.SetupEditorView();
  saveProject();

  m_vm.m_mainWindow->setTitle(fmt::format(fmt(_SYS_STR("{} - URDE [{}]")),
    m_proj->getProjectRootPath().getLastComponent(), m_vm.platformName()));
  m_vm.DismissSplash();
  m_vm.FadeInEditors();

  return true;
}

bool ProjectManager::openProject(hecl::SystemStringView path) {
  hecl::SystemString subPath;
  hecl::ProjectRootPath projPath = hecl::SearchForProject(path, subPath);
  if (!projPath) {
    Log.report(logvisor::Warning, fmt(_SYS_STR("project doesn't exist at '{}'")), path);
    return false;
  }

  m_proj.reset(new hecl::Database::Project(projPath));
  if (!*m_proj) {
    m_proj.reset();
    return false;
  }

  hecl::ProjectPath urdeSpacesPath(*m_proj, _SYS_STR(".hecl/urde_spaces.yaml"));
  athena::io::FileReader reader(urdeSpacesPath.getAbsolutePath());

  bool needsSave = false;
  athena::io::YAMLDocReader r;
  if (!reader.isOpen()) {
    needsSave = true;
    goto makeProj;
  }

  yaml_parser_set_input(r.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &reader);
  if (!r.ValidateClassType("UrdeSpacesState")) {
    needsSave = true;
    goto makeProj;
  }

  r.reset();
  reader.seek(0, athena::Begin);
  if (!r.parse(&reader)) {
    needsSave = true;
    goto makeProj;
  }

makeProj:
  m_vm.ProjectChanged(*m_proj);

  if (!needsSave)
    m_vm.SetupEditorView(r);
  else
    m_vm.SetupEditorView();

  bool doRun = hecl::StringUtils::BeginsWith(subPath, _SYS_STR("out"));
  if (doRun) {
    m_mainMP1.emplace(nullptr, nullptr, m_vm.m_mainBooFactory, m_vm.m_mainCommandQueue, m_vm.m_renderTex);
    m_vm.InitMP1(*m_mainMP1);
  }

  if (needsSave)
    saveProject();

  m_vm.m_mainWindow->setTitle(fmt::format(fmt(_SYS_STR("{} - URDE [{}]")),
    m_proj->getProjectRootPath().getLastComponent(), m_vm.platformName()));
  m_vm.DismissSplash();
  m_vm.FadeInEditors();
  m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());
  return true;
}

bool ProjectManager::extractGame(hecl::SystemStringView path) { return false; }

bool ProjectManager::saveProject() {
  if (!m_proj)
    return false;

  hecl::ProjectPath oldSpacesPath(*m_proj, _SYS_STR(".hecl/~urde_spaces.yaml"));
  athena::io::FileWriter writer(oldSpacesPath.getAbsolutePath());
  if (!writer.isOpen())
    return false;

  athena::io::YAMLDocWriter w("UrdeSpacesState");
  m_vm.SaveEditorView(w);
  if (!w.finish(&writer))
    return false;

  hecl::ProjectPath newSpacesPath(*m_proj, _SYS_STR(".hecl/urde_spaces.yaml"));

  hecl::Unlink(newSpacesPath.getAbsolutePath().data());
  hecl::Rename(oldSpacesPath.getAbsolutePath().data(), newSpacesPath.getAbsolutePath().data());

  m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());

  return true;
}

void ProjectManager::mainUpdate() {
  if (m_precooking) {
    if (!m_factoryMP1.IsBusy())
      m_precooking = false;
    else
      return;
  }

  if (m_mainMP1) {
    if (m_mainMP1->Proc()) {
      m_mainMP1->Shutdown();
      m_mainMP1 = std::nullopt;
    }
  }
}

void ProjectManager::mainDraw() {
  if (m_precooking)
    return;

  if (m_mainMP1)
    m_mainMP1->Draw();
}

void ProjectManager::shutdown() {
  if (m_mainMP1)
    m_mainMP1->Shutdown();
  m_clientProc.shutdown();
  m_factoryMP1.Shutdown();
  hecl::blender::Connection::Shutdown();
}

} // namespace urde
<commit_msg>Editor/ProjectManager: Remove use of goto<commit_after>#include "ProjectManager.hpp"
#include "ViewManager.hpp"
#include "DataSpecRegistry.hpp"
#include "hecl/Blender/Connection.hpp"

namespace urde {
static logvisor::Module Log("URDE::ProjectManager");
ProjectManager* ProjectManager::g_SharedManager = nullptr;

CToken ProjectResourcePool::GetObj(std::string_view name) {
  CToken ret = CSimplePool::GetObj(name);
  if (ret)
    return ret;

  hecl::ProjectPath path(*m_parent.project(), name);
  SObjectTag tag =
      static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
  if (tag)
    return CSimplePool::GetObj(tag);

  return {};
}

CToken ProjectResourcePool::GetObj(std::string_view name, const CVParamTransfer& pvxfer) {
  CToken ret = CSimplePool::GetObj(name, pvxfer);
  if (ret)
    return ret;

  hecl::ProjectPath path(*m_parent.project(), name);
  SObjectTag tag =
      static_cast<ProjectResourceFactoryBase&>(x18_factory).TagFromPath(path);
  if (tag)
    return CSimplePool::GetObj(tag, pvxfer);

  return {};
}

bool ProjectManager::m_registeredSpecs = false;
ProjectManager::ProjectManager(ViewManager& vm)
: m_vm(vm), m_clientProc(nullptr), m_factoryMP1(m_clientProc), m_objStore(m_factoryMP1, *this) {
  if (!m_registeredSpecs) {
    HECLRegisterDataSpecs();
    m_registeredSpecs = true;
  }
  g_SharedManager = this;
}

bool ProjectManager::newProject(hecl::SystemStringView path) {
  hecl::ProjectRootPath projPath = hecl::SearchForProject(path);
  if (projPath) {
    Log.report(logvisor::Warning, fmt(_SYS_STR("project already exists at '{}'")), path);
    return false;
  }

  hecl::MakeDir(path.data());
  m_proj.reset(new hecl::Database::Project(path));
  if (!*m_proj) {
    m_proj.reset();
    return false;
  }

  m_vm.ProjectChanged(*m_proj);
  m_vm.SetupEditorView();
  saveProject();

  m_vm.m_mainWindow->setTitle(fmt::format(fmt(_SYS_STR("{} - URDE [{}]")),
    m_proj->getProjectRootPath().getLastComponent(), m_vm.platformName()));
  m_vm.DismissSplash();
  m_vm.FadeInEditors();

  return true;
}

bool ProjectManager::openProject(hecl::SystemStringView path) {
  hecl::SystemString subPath;
  hecl::ProjectRootPath projPath = hecl::SearchForProject(path, subPath);
  if (!projPath) {
    Log.report(logvisor::Warning, fmt(_SYS_STR("project doesn't exist at '{}'")), path);
    return false;
  }

  m_proj.reset(new hecl::Database::Project(projPath));
  if (!*m_proj) {
    m_proj.reset();
    return false;
  }

  athena::io::YAMLDocReader r;
  const auto makeProj = [this, &r, &subPath](bool needsSave) {
    m_vm.ProjectChanged(*m_proj);

    if (needsSave)
      m_vm.SetupEditorView();
    else
      m_vm.SetupEditorView(r);

    const bool doRun = hecl::StringUtils::BeginsWith(subPath, _SYS_STR("out"));
    if (doRun) {
      m_mainMP1.emplace(nullptr, nullptr, m_vm.m_mainBooFactory, m_vm.m_mainCommandQueue, m_vm.m_renderTex);
      m_vm.InitMP1(*m_mainMP1);
    }

    if (needsSave)
      saveProject();

    m_vm.m_mainWindow->setTitle(fmt::format(fmt(_SYS_STR("{} - URDE [{}]")),
                                            m_proj->getProjectRootPath().getLastComponent(), m_vm.platformName()));
    m_vm.DismissSplash();
    m_vm.FadeInEditors();
    m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());
    return true;
  };

  const hecl::ProjectPath urdeSpacesPath(*m_proj, _SYS_STR(".hecl/urde_spaces.yaml"));
  athena::io::FileReader reader(urdeSpacesPath.getAbsolutePath());

  if (!reader.isOpen()) {
    return makeProj(true);
  }

  yaml_parser_set_input(r.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &reader);
  if (!r.ValidateClassType("UrdeSpacesState")) {
    return makeProj(true);
  }

  r.reset();
  reader.seek(0, athena::Begin);
  if (!r.parse(&reader)) {
    return makeProj(true);
  }

  return makeProj(false);
}

bool ProjectManager::extractGame(hecl::SystemStringView path) { return false; }

bool ProjectManager::saveProject() {
  if (!m_proj)
    return false;

  hecl::ProjectPath oldSpacesPath(*m_proj, _SYS_STR(".hecl/~urde_spaces.yaml"));
  athena::io::FileWriter writer(oldSpacesPath.getAbsolutePath());
  if (!writer.isOpen())
    return false;

  athena::io::YAMLDocWriter w("UrdeSpacesState");
  m_vm.SaveEditorView(w);
  if (!w.finish(&writer))
    return false;

  hecl::ProjectPath newSpacesPath(*m_proj, _SYS_STR(".hecl/urde_spaces.yaml"));

  hecl::Unlink(newSpacesPath.getAbsolutePath().data());
  hecl::Rename(oldSpacesPath.getAbsolutePath().data(), newSpacesPath.getAbsolutePath().data());

  m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());

  return true;
}

void ProjectManager::mainUpdate() {
  if (m_precooking) {
    if (!m_factoryMP1.IsBusy())
      m_precooking = false;
    else
      return;
  }

  if (m_mainMP1) {
    if (m_mainMP1->Proc()) {
      m_mainMP1->Shutdown();
      m_mainMP1 = std::nullopt;
    }
  }
}

void ProjectManager::mainDraw() {
  if (m_precooking)
    return;

  if (m_mainMP1)
    m_mainMP1->Draw();
}

void ProjectManager::shutdown() {
  if (m_mainMP1)
    m_mainMP1->Shutdown();
  m_clientProc.shutdown();
  m_factoryMP1.Shutdown();
  hecl::blender::Connection::Shutdown();
}

} // namespace urde
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: testproxyfac.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-13 19:01:04 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "sal/main.h"
#include "osl/diagnose.h"
#include "rtl/alloc.h"
#include "uno/environment.hxx"
#include "cppuhelper/servicefactory.hxx"
#include "cppuhelper/implbase1.hxx"
#include "cppuhelper/implbase3.hxx"
#include "com/sun/star/uno/XCurrentContext.hpp"
#include "com/sun/star/lang/DisposedException.hpp"
#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/registry/XSimpleRegistry.hpp"
#include "com/sun/star/registry/XImplementationRegistration.hpp"
#include "com/sun/star/beans/XPropertySet.hpp"
#include "com/sun/star/reflection/XProxyFactory.hpp"

#include <stdio.h>

using namespace ::rtl;
using namespace ::osl;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

typedef WeakImplHelper3< lang::XServiceInfo,
                         XCurrentContext,
                         reflection::XProxyFactory > t_impl;

//==============================================================================
class TargetObject : public t_impl
{
public:
    static int s_obj;

    virtual ~TargetObject()
        { --s_obj;  OSL_TRACE( "~TargetObject()" ); }
    TargetObject()
        { ++s_obj; }

    Any SAL_CALL queryInterface( Type const & type )
        throw (RuntimeException);

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
        { return OUString::createFromAscii( "target" ); }
    virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
        throw (RuntimeException)
        { return sal_False; }
    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
        throw (RuntimeException)
        { return Sequence< OUString >(); }
    // XProxyFactory
    virtual Reference< XAggregation > SAL_CALL createProxy(
        const Reference< XInterface > & xTarget ) throw (RuntimeException)
        { return Reference< XAggregation >( xTarget, UNO_QUERY ); }
    // XCurrentContext
    virtual Any SAL_CALL getValueByName( OUString const & name )
        throw (RuntimeException)
        { return makeAny( name ); }
};

//______________________________________________________________________________
Any TargetObject::queryInterface( Type const & type )
    throw (RuntimeException)
{
    Any ret( t_impl::queryInterface( type ) );
    if (ret.hasValue())
        return ret;
    throw lang::DisposedException(
        OUString( RTL_CONSTASCII_USTRINGPARAM("my test exception") ),
        static_cast< OWeakObject * >(this) );
}

int TargetObject::s_obj = 0;

//==============================================================================
class TestMaster : public WeakImplHelper1< lang::XServiceInfo >
{
    Reference< XAggregation > m_xProxyTarget;

    inline TestMaster() { ++s_obj; }
public:
    static int s_obj;
    static Reference< XInterface > create(
        Reference< reflection::XProxyFactory > const & xProxyFac );
    static Reference< XInterface > create(
        Reference< XInterface > const & xTarget,
        Reference< reflection::XProxyFactory > const & xProxyFac );

    virtual ~TestMaster()
        { --s_obj;  OSL_TRACE( "~TestMaster()" ); }

    virtual Any SAL_CALL queryInterface( const Type & rType )
        throw (RuntimeException)
    {
        Any aRet(
            WeakImplHelper1< lang::XServiceInfo >::queryInterface( rType ) );
        if (aRet.hasValue())
            return aRet;
        return m_xProxyTarget->queryAggregation( rType );
    }

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
        { return OUString::createFromAscii( "master" ); }
    virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
        throw (RuntimeException)
        { return sal_False; }
    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
        throw (RuntimeException)
        { return Sequence< OUString >(); }
};

int TestMaster::s_obj = 0;

Reference< XInterface > TestMaster::create(
    Reference< XInterface > const & xTarget,
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    Reference< XAggregation > xAgg( xProxyFac->createProxy( xTarget ) );
    TestMaster * that = new TestMaster;
    Reference< XInterface > xRet( static_cast< OWeakObject * >( that ) );
    // ownership take over
    that->m_xProxyTarget.set( xAgg );
    xAgg.clear();
    that->m_xProxyTarget->setDelegator( xRet );
    return xRet;
}

Reference< XInterface > TestMaster::create(
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    return create(
        static_cast< OWeakObject * >( new TargetObject ), xProxyFac );
}

static void test_proxyfac_(
    Reference< XInterface > const & xMaster, OUString const & test,
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    Reference< lang::XServiceInfo > xMaster_XServiceInfo(
        xMaster, UNO_QUERY_THROW );
    OSL_ASSERT( xMaster_XServiceInfo->getImplementationName().equals( test ) );

    Reference< reflection::XProxyFactory > xTarget( xMaster, UNO_QUERY_THROW );
    Reference< XCurrentContext > xTarget_XCurrentContext(
        xTarget, UNO_QUERY_THROW );
    Reference< XCurrentContext > xMaster_XCurrentContext(
        xMaster, UNO_QUERY_THROW );

    OSL_ASSERT(
        xTarget_XCurrentContext->getValueByName( test ) == makeAny( test ) );
    OSL_ASSERT(
        xMaster_XCurrentContext->getValueByName( test ) == makeAny( test ) );

    Reference< XAggregation > xFakeAgg( xTarget->createProxy( xTarget ) );
    if (xFakeAgg.is())
    {
        OSL_ASSERT( xTarget == xFakeAgg );
        OSL_ASSERT( xMaster == xFakeAgg );
    }

    Reference< lang::XServiceInfo > xTarget_XServiceInfo(
        xTarget, UNO_QUERY_THROW );
    OSL_ASSERT( xTarget_XServiceInfo->getImplementationName().equals( test ) );
    Reference< lang::XServiceInfo > xTarget_XServiceInfo2(
        xTarget, UNO_QUERY_THROW );
    OSL_ASSERT( xTarget_XServiceInfo2.get() == xTarget_XServiceInfo.get() );

    OSL_ASSERT( xTarget == xTarget_XCurrentContext );
    OSL_ASSERT( xTarget_XCurrentContext == xMaster );
    OSL_ASSERT(
        xTarget_XCurrentContext.get() == xMaster_XCurrentContext.get() );
    OSL_ASSERT( xTarget_XCurrentContext == xMaster );
    OSL_ASSERT( xTarget == xMaster );
    OSL_ASSERT( xTarget_XServiceInfo.get() == xMaster_XServiceInfo.get() );
    OSL_ASSERT( xTarget_XServiceInfo == xMaster );
    OSL_ASSERT( xMaster_XServiceInfo == xMaster );

    try
    {
        Reference< registry::XRegistryKey >(
            xMaster, UNO_QUERY_THROW );
    }
    catch (lang::DisposedException & exc)
    {
        if (! exc.Message.equalsAsciiL(
                RTL_CONSTASCII_STRINGPARAM("my test exception") ))
            throw;
    }
}

static void test_proxyfac(
    Reference< XInterface > const & xMaster, OUString const & test,
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    test_proxyfac_( xMaster, test, xProxyFac );
    // proxy the proxy...
    Reference< XInterface > xNew( TestMaster::create( xMaster, xProxyFac ) );
    test_proxyfac_(
        xNew, OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), xProxyFac );
}

SAL_IMPLEMENT_MAIN()
{
    bool success = true;

    Environment cpp_env;
    OUString cpp( RTL_CONSTASCII_USTRINGPARAM(
                      CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
    uno_getEnvironment(
        reinterpret_cast< uno_Environment ** >( &cpp_env ),
        cpp.pData, 0 );
    OSL_ENSURE( cpp_env.is(), "### cannot get C++ uno env!" );

    {
        Reference< lang::XMultiServiceFactory > xMgr(
            createRegistryServiceFactory(
                OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) );

        try
        {
            Reference< registry::XImplementationRegistration > xImplReg(
                xMgr->createInstance(
                    OUString(
                        RTL_CONSTASCII_USTRINGPARAM(
                            "com.sun.star.registry.ImplementationRegistration")
                        ) ),
                UNO_QUERY );
            OSL_ENSURE( xImplReg.is(), "### no impl reg!" );

            OUString aLibName(
                RTL_CONSTASCII_USTRINGPARAM("proxyfac.uno" SAL_DLLEXTENSION) );
            xImplReg->registerImplementation(
                OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "com.sun.star.loader.SharedLibrary") ),
                aLibName, Reference< registry::XSimpleRegistry >() );

            Reference< reflection::XProxyFactory > xProxyFac(
                xMgr->createInstance(
                    OUString::createFromAscii(
                        "com.sun.star.reflection.ProxyFactory") ),
                UNO_QUERY_THROW );

            Reference< XAggregation > x(
                xProxyFac->createProxy(
                    static_cast< OWeakObject * >( new TargetObject ) ) );
            // no call

            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            test_proxyfac(
                xMaster,
                OUString( RTL_CONSTASCII_USTRINGPARAM("master") ),
                xProxyFac );
            }
            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            // no call
            }

            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            Reference< reflection::XProxyFactory > xSlave_lives_alone(
                xMaster, UNO_QUERY_THROW );
            xMaster.clear();
            test_proxyfac(
                xSlave_lives_alone,
                OUString( RTL_CONSTASCII_USTRINGPARAM("master") ),
                xProxyFac );
            uno_dumpEnvironment( stdout, cpp_env.get(), 0 );
            }
            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            Reference< reflection::XProxyFactory > xSlave_lives_alone(
                xMaster, UNO_QUERY_THROW );
            // no call
            }

            test_proxyfac(
                xProxyFac->createProxy(
                    static_cast< OWeakObject * >( new TargetObject ) ),
                OUString( RTL_CONSTASCII_USTRINGPARAM("target") ),
                xProxyFac );
            uno_dumpEnvironment( stdout, cpp_env.get(), 0 );
        }
        catch (Exception & rExc)
        {
            OSL_ENSURE(
                ! __FILE__,
                OUStringToOString(
                    rExc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
            success = false;
        }

        Reference< lang::XComponent > xComp;
        Reference< beans::XPropertySet >(
            xMgr, UNO_QUERY_THROW )->getPropertyValue(
                OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) )
                    >>= xComp;
        xComp->dispose();
    }

    if (TestMaster::s_obj != 0)
        fprintf( stderr, "TestMaster objects: %d\n", TestMaster::s_obj );
    if (TargetObject::s_obj != 0)
        fprintf( stderr, "TargetObject objects: %d\n", TargetObject::s_obj );

    uno_dumpEnvironment( stdout, cpp_env.get(), 0 );
    void ** ppInterfaces;
    sal_Int32 len;
    uno_ExtEnvironment * env = cpp_env.get()->pExtEnv;
    (*env->getRegisteredInterfaces)(
        env, &ppInterfaces, &len, rtl_allocateMemory );
    if (len != 0)
        fprintf( stderr, "%d registered C++ interfaces left!\n", len );

    success &= (TestMaster::s_obj == 0 &&
                TargetObject::s_obj == 0 &&
                len == 0);
    if (success)
    {
        printf( "testproxyfac succeeded.\n" );
        return 0;
    }
    else
    {
        fprintf( stderr, "testproxyfac failed!\n" );
        return 1;
    }
}

<commit_msg>INTEGRATION: CWS dba22 (1.8.46); FILE MERGED 2005/01/19 19:24:25 fs 1.8.46.2: RESYNC: (1.8-1.9); FILE MERGED 2004/12/16 13:31:28 dbo 1.8.46.1: #i39037#<commit_after>/*************************************************************************
 *
 *  $RCSfile: testproxyfac.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: kz $ $Date: 2005-01-21 17:30:31 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  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.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include "sal/main.h"
#include "osl/diagnose.h"
#include "rtl/alloc.h"
#include "uno/environment.hxx"
#include "cppuhelper/servicefactory.hxx"
#include "cppuhelper/implbase1.hxx"
#include "cppuhelper/implbase3.hxx"
#include "com/sun/star/uno/XCurrentContext.hpp"
#include "com/sun/star/lang/DisposedException.hpp"
#include "com/sun/star/lang/XComponent.hpp"
#include "com/sun/star/lang/XServiceInfo.hpp"
#include "com/sun/star/registry/XSimpleRegistry.hpp"
#include "com/sun/star/registry/XImplementationRegistration.hpp"
#include "com/sun/star/beans/XPropertySet.hpp"
#include "com/sun/star/reflection/XProxyFactory.hpp"

#include <stdio.h>

using namespace ::rtl;
using namespace ::osl;
using namespace ::cppu;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

typedef WeakImplHelper3< lang::XServiceInfo,
                         XCurrentContext,
                         reflection::XProxyFactory > t_impl;

//==============================================================================
class TargetObject : public t_impl
{
public:
    static int s_obj;

    virtual ~TargetObject() {
        --s_obj;
        OSL_TRACE( "~TargetObject()" );
    }
    TargetObject()
        { ++s_obj; }

    Any SAL_CALL queryInterface( Type const & type )
        throw (RuntimeException);

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
        { return OUString::createFromAscii( "target" ); }
    virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
        throw (RuntimeException)
        { return sal_False; }
    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
        throw (RuntimeException)
        { return Sequence< OUString >(); }
    // XProxyFactory
    virtual Reference< XAggregation > SAL_CALL createProxy(
        const Reference< XInterface > & xTarget ) throw (RuntimeException)
        { return Reference< XAggregation >( xTarget, UNO_QUERY ); }
    // XCurrentContext
    virtual Any SAL_CALL getValueByName( OUString const & name )
        throw (RuntimeException)
        { return makeAny( name ); }
};

//______________________________________________________________________________
Any TargetObject::queryInterface( Type const & type )
    throw (RuntimeException)
{
    Any ret( t_impl::queryInterface( type ) );
    if (ret.hasValue())
        return ret;
    throw lang::DisposedException(
        OUString( RTL_CONSTASCII_USTRINGPARAM("my test exception") ),
        static_cast< OWeakObject * >(this) );
}

int TargetObject::s_obj = 0;

//==============================================================================
class TestMaster : public WeakImplHelper1< lang::XServiceInfo >
{
    Reference< XAggregation > m_xProxyTarget;
    Reference<lang::XServiceInfo> m_xOtherProxyTargetBeforeSetDelegator;

    inline TestMaster() { ++s_obj; }
public:
    static int s_obj;
    static Reference< XInterface > create(
        Reference< reflection::XProxyFactory > const & xProxyFac );
    static Reference< XInterface > create(
        Reference< XInterface > const & xTarget,
        Reference< reflection::XProxyFactory > const & xProxyFac );

    virtual ~TestMaster() {
        --s_obj;
        OSL_TRACE( "~TestMaster()" );
    }

    virtual Any SAL_CALL queryInterface( const Type & rType )
        throw (RuntimeException)
    {
        Any aRet(
            WeakImplHelper1< lang::XServiceInfo >::queryInterface( rType ) );
        if (aRet.hasValue())
            return aRet;
        return m_xProxyTarget->queryAggregation( rType );
    }

    // XServiceInfo
    virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
        { return OUString::createFromAscii( "master" ); }
    virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
        throw (RuntimeException)
        { return sal_False; }
    virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
        throw (RuntimeException)
        { return Sequence< OUString >(); }
};

int TestMaster::s_obj = 0;

Reference< XInterface > TestMaster::create(
    Reference< XInterface > const & xTarget,
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    TestMaster * that = new TestMaster;
    Reference< XInterface > xRet( static_cast< OWeakObject * >( that ) );
    {
        Reference< XAggregation > xAgg( xProxyFac->createProxy( xTarget ) );
        // ownership take over
        that->m_xProxyTarget.set( xAgg, UNO_QUERY_THROW );
        that->m_xOtherProxyTargetBeforeSetDelegator.set(
            that->m_xProxyTarget, UNO_QUERY );
    }
    that->m_xProxyTarget->setDelegator( xRet );
    return xRet;
}

Reference< XInterface > TestMaster::create(
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    return create(
        static_cast< OWeakObject * >( new TargetObject ), xProxyFac );
}

static void test_proxyfac_(
    Reference< XInterface > const & xMaster, OUString const & test,
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    Reference< lang::XServiceInfo > xMaster_XServiceInfo(
        xMaster, UNO_QUERY_THROW );
    OSL_ASSERT( xMaster_XServiceInfo->getImplementationName().equals( test ) );

    Reference< reflection::XProxyFactory > xTarget( xMaster, UNO_QUERY_THROW );
    Reference< XCurrentContext > xTarget_XCurrentContext(
        xTarget, UNO_QUERY_THROW );
    Reference< XCurrentContext > xMaster_XCurrentContext(
        xMaster, UNO_QUERY_THROW );

    OSL_ASSERT(
        xTarget_XCurrentContext->getValueByName( test ) == makeAny( test ) );
    OSL_ASSERT(
        xMaster_XCurrentContext->getValueByName( test ) == makeAny( test ) );

    Reference< XAggregation > xFakeAgg( xTarget->createProxy( xTarget ) );
    if (xFakeAgg.is())
    {
        OSL_ASSERT( xTarget == xFakeAgg );
        OSL_ASSERT( xMaster == xFakeAgg );
    }

    Reference< lang::XServiceInfo > xTarget_XServiceInfo(
        xTarget, UNO_QUERY_THROW );
    OSL_ASSERT( xTarget_XServiceInfo->getImplementationName().equals( test ) );
    Reference< lang::XServiceInfo > xTarget_XServiceInfo2(
        xTarget, UNO_QUERY_THROW );
    OSL_ASSERT( xTarget_XServiceInfo2.get() == xTarget_XServiceInfo.get() );

    OSL_ASSERT( xTarget == xTarget_XCurrentContext );
    OSL_ASSERT( xTarget_XCurrentContext == xMaster );
    OSL_ASSERT(
        xTarget_XCurrentContext.get() == xMaster_XCurrentContext.get() );
    OSL_ASSERT( xTarget_XCurrentContext == xMaster );
    OSL_ASSERT( xTarget == xMaster );
    OSL_ASSERT( xTarget_XServiceInfo.get() == xMaster_XServiceInfo.get() );
    OSL_ASSERT( xTarget_XServiceInfo == xMaster );
    OSL_ASSERT( xMaster_XServiceInfo == xMaster );

    try
    {
        Reference< registry::XRegistryKey >(
            xMaster, UNO_QUERY_THROW );
    }
    catch (lang::DisposedException & exc)
    {
        if (! exc.Message.equalsAsciiL(
                RTL_CONSTASCII_STRINGPARAM("my test exception") ))
            throw;
    }
}

static void test_proxyfac(
    Reference< XInterface > const & xMaster, OUString const & test,
    Reference< reflection::XProxyFactory > const & xProxyFac )
{
    test_proxyfac_( xMaster, test, xProxyFac );
    // proxy the proxy...
    Reference< XInterface > xNew( TestMaster::create( xMaster, xProxyFac ) );
    test_proxyfac_(
        xNew, OUString( RTL_CONSTASCII_USTRINGPARAM("master") ), xProxyFac );
}

SAL_IMPLEMENT_MAIN()
{
    bool success = true;

    Environment cpp_env;
    OUString cpp( RTL_CONSTASCII_USTRINGPARAM(
                      CPPU_CURRENT_LANGUAGE_BINDING_NAME) );
    uno_getEnvironment(
        reinterpret_cast< uno_Environment ** >( &cpp_env ),
        cpp.pData, 0 );
    OSL_ENSURE( cpp_env.is(), "### cannot get C++ uno env!" );

    {
        Reference< lang::XMultiServiceFactory > xMgr(
            createRegistryServiceFactory(
                OUString( RTL_CONSTASCII_USTRINGPARAM("stoctest.rdb") ) ) );

        try
        {
            Reference< registry::XImplementationRegistration > xImplReg(
                xMgr->createInstance(
                    OUString(
                        RTL_CONSTASCII_USTRINGPARAM(
                            "com.sun.star.registry.ImplementationRegistration")
                        ) ),
                UNO_QUERY );
            OSL_ENSURE( xImplReg.is(), "### no impl reg!" );

            OUString aLibName(
                RTL_CONSTASCII_USTRINGPARAM("proxyfac.uno" SAL_DLLEXTENSION) );
            xImplReg->registerImplementation(
                OUString(
                    RTL_CONSTASCII_USTRINGPARAM(
                        "com.sun.star.loader.SharedLibrary") ),
                aLibName, Reference< registry::XSimpleRegistry >() );

            Reference< reflection::XProxyFactory > xProxyFac(
                xMgr->createInstance(
                    OUString::createFromAscii(
                        "com.sun.star.reflection.ProxyFactory") ),
                UNO_QUERY_THROW );

            Reference< XAggregation > x(
                xProxyFac->createProxy(
                    static_cast< OWeakObject * >( new TargetObject ) ) );
            // no call

            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            test_proxyfac(
                xMaster,
                OUString( RTL_CONSTASCII_USTRINGPARAM("master") ),
                xProxyFac );
            }
            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            // no call
            }

            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            Reference< reflection::XProxyFactory > xSlave_lives_alone(
                xMaster, UNO_QUERY_THROW );
            xMaster.clear();
            test_proxyfac(
                xSlave_lives_alone,
                OUString( RTL_CONSTASCII_USTRINGPARAM("master") ),
                xProxyFac );
            uno_dumpEnvironment( stdout, cpp_env.get(), 0 );
            }
            {
            Reference< XInterface > xMaster( TestMaster::create( xProxyFac ) );
            Reference< reflection::XProxyFactory > xSlave_lives_alone(
                xMaster, UNO_QUERY_THROW );
            // no call
            }

            test_proxyfac(
                xProxyFac->createProxy(
                    static_cast< OWeakObject * >( new TargetObject ) ),
                OUString( RTL_CONSTASCII_USTRINGPARAM("target") ),
                xProxyFac );
            uno_dumpEnvironment( stdout, cpp_env.get(), 0 );
        }
        catch (Exception & rExc)
        {
            OSL_ENSURE(
                ! __FILE__,
                OUStringToOString(
                    rExc.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
            success = false;
        }

        Reference< lang::XComponent > xComp;
        Reference< beans::XPropertySet >(
            xMgr, UNO_QUERY_THROW )->getPropertyValue(
                OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) )
                    >>= xComp;
        xComp->dispose();
    }

    if (TestMaster::s_obj != 0)
        fprintf( stderr, "TestMaster objects: %d\n", TestMaster::s_obj );
    if (TargetObject::s_obj != 0)
        fprintf( stderr, "TargetObject objects: %d\n", TargetObject::s_obj );

    uno_dumpEnvironment( stdout, cpp_env.get(), 0 );
    void ** ppInterfaces;
    sal_Int32 len;
    uno_ExtEnvironment * env = cpp_env.get()->pExtEnv;
    (*env->getRegisteredInterfaces)(
        env, &ppInterfaces, &len, rtl_allocateMemory );
    if (len != 0)
        fprintf( stderr, "%d registered C++ interfaces left!\n", len );

    success &= (TestMaster::s_obj == 0 &&
                TargetObject::s_obj == 0 &&
                len == 0);
    if (success)
    {
        printf( "testproxyfac succeeded.\n" );
        return 0;
    }
    else
    {
        fprintf( stderr, "testproxyfac failed!\n" );
        return 1;
    }
}

<|endoftext|>


<commit_before>#pragma once
#include "pin.hpp"

template <unsigned P>
class Led : protected Pin

{
public:

    static constexpr uint8_t pin = P;

    void on()            {Pin
::high();}
    void off()           {Pin
::low();}
    void set(bool value) {Pin
::set(value);}
    bool isOn() const    {return Pin
::isHigh();}
    bool isOff() const   {return Pin
::isLow();}
    bool get() const     {return Pin
::get();}

    Led
& operator=(bool value) { set(value); return *this; }
    bool operator*() { return get(); }

};

template <unsigned P>
class AnalogLed : protected AnalogOutputPin

{
public:

    static constexpr uint8_t pin = P;

    void on(uint8_t brightness)  {AnalogOutputPin
::set(brightness);}
    void off()                   {on(0);}
    void set(uint8_t brightness) {on(brightness);}
    bool isOn() const            {return get() > 0;}
    bool isOff() const           {!isOff();}
    uint8_t get() const          {return AnalogOutputPin
::get();}
    uint8_t brightness() const   {return get();}

    AnalogLed
& operator=(bool value) { set(value); return *this; }
    bool operator*() { return get(); }

};

using BuiltinLed = Led<LED_BUILTIN>;
using BuiltinAnalogLed = AnalogLed<LED_BUILTIN>;
<commit_msg>Add += and -= to AnalogLed.<commit_after>#pragma once
#include "pin.hpp"

template <unsigned P>
class Led : protected Pin

{
public:

    static constexpr uint8_t pin = P;

    void on()            {Pin
::high();}
    void off()           {Pin
::low();}
    void set(bool value) {Pin
::set(value);}
    bool isOn() const    {return Pin
::isHigh();}
    bool isOff() const   {return Pin
::isLow();}
    bool get() const     {return Pin
::get();}

    Led
& operator=(bool value) { set(value); return *this; }
    bool operator*() { return get(); }

};

template <unsigned P>
class AnalogLed : protected AnalogOutputPin

{
public:

    static constexpr uint8_t pin = P;

    void on(uint8_t brightness)  {AnalogOutputPin
::set(brightness);}
    void off()                   {on(0);}
    void set(uint8_t brightness) {on(brightness);}
    bool isOn() const            {return get() > 0;}
    bool isOff() const           {!isOff();}
    uint8_t get() const          {return AnalogOutputPin
::get();}
    uint8_t brightness() const   {return get();}

    AnalogLed
& operator=(uint8_t brightness) { set(value); return *this; }
    bool operator*() { return get(); }

    AnalogLed
& operator+=(int delta) { set(get()+delta); return *this; }
    AnalogLed
& operator-=(int delta) { set(get()-delta); return *this; }

};

using BuiltinLed = Led<LED_BUILTIN>;
using BuiltinAnalogLed = AnalogLed<LED_BUILTIN>;
<|endoftext|>


<commit_before>#include "property_diversity_reranker.h"
#include "group_manager.h"

#include <mining-manager/group-label-logger/GroupLabelLogger.h>
#include <util/ustring/UString.h>
#include <util/ClockTimer.h>

#include <list>
#include <algorithm>
#include <glog/logging.h>

NS_FACETED_BEGIN

bool CompareSecond(const std::pair<size_t, count_t>& r1, const std::pair<size_t, count_t>& r2)
{
    return (r1.second > r2.second);
}

PropertyDiversityReranker::PropertyDiversityReranker(
    const GroupManager* groupManager,
    const std::string& diversityProperty,
    const std::string& boostingProperty
)
    :groupManager_(groupManager)
    ,diversityProperty_(diversityProperty)
    ,boostingProperty_(boostingProperty)
    ,groupLabelLogger_(NULL)
{
}

PropertyDiversityReranker::~PropertyDiversityReranker()
{
}

void PropertyDiversityReranker::rerank(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList,
    const std::string& query
)
{
    bool isBoostLabel = false;
    const PropValueTable* pvTable = NULL;
    PropValueTable::pvid_t labelId = 0;
    izenelib::util::ClockTimer timer;

    if(groupManager_ && groupLabelLogger_ && !boostingProperty_.empty())
    {
        std::vector<PropValueTable::pvid_t> pvIdVec;
        std::vector<int> freqVec;
        groupLabelLogger_->getFreqLabel(query, 1, pvIdVec, freqVec);

        if(!pvIdVec.empty() && (labelId = pvIdVec[0]))
        {
            pvTable = groupManager_->getPropValueTable(boostingProperty_);
            if (pvTable)
            {
                isBoostLabel = true;

                const izenelib::util::UString& labelUStr = pvTable->propValueStr(labelId);
                std::string boostLabel;
                labelUStr.convertString(boostLabel, izenelib::util::UString::UTF_8);

                LOG(INFO) << "boosting property: " << boostingProperty_
                        << ", label: " << boostLabel
                        << ", doc num: " << docIdList.size();
            }
            else
            {
                LOG(ERROR) << "in PropertyDiversityReranker: group index file is not loaded for property " << boostingProperty_;
            }
        }
        else
        {
            LOG(INFO) << "no boosting label for property " << boostingProperty_;
        }
    }

    if (isBoostLabel)
    {
        std::size_t numDoc = docIdList.size();

        std::vector<unsigned int> boostingDocIdList;
        std::vector<float> boostingScoreList;
        boostingDocIdList.reserve(numDoc);;
        boostingScoreList.reserve(numDoc);

        std::vector<unsigned int> leftDocIdList;
        std::vector<float> leftScoreList;
        leftDocIdList.reserve(numDoc);;
        leftScoreList.reserve(numDoc);

        for(std::size_t i = 0; i < numDoc; ++i)
        {
            docid_t docId = docIdList[i];

            if (pvTable->testDoc(docId, labelId))
            {
                boostingDocIdList.push_back(docId);
                boostingScoreList.push_back(rankScoreList[i]);
            }
            else
            {
                leftDocIdList.push_back(docId);
                leftScoreList.push_back(rankScoreList[i]);
            }
        }
        if(!boostingDocIdList.empty())
        {
            rerankImpl_(boostingDocIdList, boostingScoreList);
        }
        if(!leftDocIdList.empty())
        {
            rerankImpl_(leftDocIdList, leftScoreList);
        }
        boostingDocIdList.resize(numDoc);
        boostingScoreList.resize(numDoc);
        std::copy_backward(leftDocIdList.begin(), leftDocIdList.end(), boostingDocIdList.end());
        std::copy_backward(leftScoreList.begin(), leftScoreList.end(), boostingScoreList.end());
        std::swap(docIdList, boostingDocIdList);
        std::swap(rankScoreList, boostingScoreList);
    }
    else
    {
        rerankImpl_(docIdList, rankScoreList);
    }

    LOG(INFO) << "PropertyDiversityReranker::rerank() costs " << timer.elapsed() << " seconds";
}

void PropertyDiversityReranker::rerankImpl_(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList
)
{
    rerankDiversity_(docIdList, rankScoreList);
    rerankCTR_(docIdList, rankScoreList);
}

void PropertyDiversityReranker::rerankDiversity_(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList
)
{
    typedef std::list<std::pair<unsigned int,float> > DocIdList;
    typedef std::map<PropValueTable::pvid_t, DocIdList> DocIdMap;

    const PropValueTable* pvTable = NULL;
    if (groupManager_ && !diversityProperty_.empty())
    {
        pvTable = groupManager_->getPropValueTable(diversityProperty_);
        if (!pvTable)
        {
            LOG(ERROR) << "in PropertyDiversityReranker: group index file is not loaded for group property " << diversityProperty_;
            return;
        }
    }
    else
    {
        return;
    }

    LOG(INFO) << "diversity property: " << diversityProperty_
              << ", doc num: " << docIdList.size();

    const PropValueTable::ValueIdTable& idTable = pvTable->valueIdTable();
    std::size_t numDoc = docIdList.size();
    std::vector<unsigned int> newDocIdList;
    std::vector<float> newScoreList;
    newDocIdList.reserve(numDoc);
    newScoreList.reserve(numDoc);

    DocIdMap docIdMap;
    DocIdList missDocs;
    for (std::size_t i = 0; i < numDoc; ++i)
    {
        docid_t docId = docIdList[i];

        if (docId < idTable.size() && idTable[docId].empty() == false)
        {
            // use 1st group value
            PropValueTable::pvid_t pvId = idTable[docId][0];
            docIdMap[pvId].push_back(std::make_pair(docId, rankScoreList[i]));
        }
        else
        {
            missDocs.push_back(std::make_pair(docId, rankScoreList[i]));
        }
    }

    // single property or empty
    if(docIdMap.size() > 1)
        return;

    do{
        DocIdMap::iterator mapIt = docIdMap.begin();
        while(mapIt != docIdMap.end())
        {
            if(mapIt->second.empty())
            {
                docIdMap.erase(mapIt++);
            }
            else
            {
                std::pair<unsigned int, float> element = mapIt->second.front();
                mapIt->second.pop_front();
                newDocIdList.push_back(element.first);
                newScoreList.push_back(element.second);
                ++mapIt;
            }
        }
    }while(!docIdMap.empty());

    for(DocIdList::iterator missIt = missDocs.begin(); missIt != missDocs.end(); ++missIt)
    {
        newDocIdList.push_back(missIt->first);
        newScoreList.push_back(missIt->second);
    }

    std::swap(docIdList, newDocIdList);
    std::swap(rankScoreList, newScoreList);
}

void PropertyDiversityReranker::rerankCTR_(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList
)
{
    std::vector<std::pair<size_t, count_t> > posClickCountList;
    bool hasClickCount = false;
    if (ctrManager_)
    {
        hasClickCount = ctrManager_->getClickCountListByDocIdList(docIdList, posClickCountList);
    }

    if (!hasClickCount)
        return;

    LOG(INFO) << "CTR rerank, doc num: " << docIdList.size();

    // sort by click-count
    std::stable_sort(posClickCountList.begin(), posClickCountList.end(), CompareSecond);

    std::size_t numDoc = docIdList.size();
    std::vector<unsigned int> newDocIdList(numDoc);
    std::vector<float> newScoreList(numDoc);

    size_t i = 0;
    for (std::vector<std::pair<size_t, count_t> >::iterator it = posClickCountList.begin();
        it != posClickCountList.end(); ++it)
    {
        size_t pos = it->first;
        newDocIdList[i] = docIdList[pos];
        newScoreList[i] = rankScoreList[pos];
        ++i;
    }

    std::swap(docIdList, newDocIdList);
    std::swap(rankScoreList, newScoreList);
}

NS_FACETED_END

<commit_msg>fix a bug that property diversity does not work.<commit_after>#include "property_diversity_reranker.h"
#include "group_manager.h"

#include <mining-manager/group-label-logger/GroupLabelLogger.h>
#include <util/ustring/UString.h>
#include <util/ClockTimer.h>

#include <list>
#include <algorithm>
#include <glog/logging.h>

NS_FACETED_BEGIN

bool CompareSecond(const std::pair<size_t, count_t>& r1, const std::pair<size_t, count_t>& r2)
{
    return (r1.second > r2.second);
}

PropertyDiversityReranker::PropertyDiversityReranker(
    const GroupManager* groupManager,
    const std::string& diversityProperty,
    const std::string& boostingProperty
)
    :groupManager_(groupManager)
    ,diversityProperty_(diversityProperty)
    ,boostingProperty_(boostingProperty)
    ,groupLabelLogger_(NULL)
{
}

PropertyDiversityReranker::~PropertyDiversityReranker()
{
}

void PropertyDiversityReranker::rerank(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList,
    const std::string& query
)
{
    bool isBoostLabel = false;
    const PropValueTable* pvTable = NULL;
    PropValueTable::pvid_t labelId = 0;
    izenelib::util::ClockTimer timer;

    if(groupManager_ && groupLabelLogger_ && !boostingProperty_.empty())
    {
        std::vector<PropValueTable::pvid_t> pvIdVec;
        std::vector<int> freqVec;
        groupLabelLogger_->getFreqLabel(query, 1, pvIdVec, freqVec);

        if(!pvIdVec.empty() && (labelId = pvIdVec[0]))
        {
            pvTable = groupManager_->getPropValueTable(boostingProperty_);
            if (pvTable)
            {
                isBoostLabel = true;

                const izenelib::util::UString& labelUStr = pvTable->propValueStr(labelId);
                std::string boostLabel;
                labelUStr.convertString(boostLabel, izenelib::util::UString::UTF_8);

                LOG(INFO) << "boosting property: " << boostingProperty_
                        << ", label: " << boostLabel
                        << ", doc num: " << docIdList.size();
            }
            else
            {
                LOG(ERROR) << "in PropertyDiversityReranker: group index file is not loaded for property " << boostingProperty_;
            }
        }
        else
        {
            LOG(INFO) << "no boosting label for property " << boostingProperty_;
        }
    }

    if (isBoostLabel)
    {
        std::size_t numDoc = docIdList.size();

        std::vector<unsigned int> boostingDocIdList;
        std::vector<float> boostingScoreList;
        boostingDocIdList.reserve(numDoc);;
        boostingScoreList.reserve(numDoc);

        std::vector<unsigned int> leftDocIdList;
        std::vector<float> leftScoreList;
        leftDocIdList.reserve(numDoc);;
        leftScoreList.reserve(numDoc);

        for(std::size_t i = 0; i < numDoc; ++i)
        {
            docid_t docId = docIdList[i];

            if (pvTable->testDoc(docId, labelId))
            {
                boostingDocIdList.push_back(docId);
                boostingScoreList.push_back(rankScoreList[i]);
            }
            else
            {
                leftDocIdList.push_back(docId);
                leftScoreList.push_back(rankScoreList[i]);
            }
        }
        if(!boostingDocIdList.empty())
        {
            rerankImpl_(boostingDocIdList, boostingScoreList);
        }
        if(!leftDocIdList.empty())
        {
            rerankImpl_(leftDocIdList, leftScoreList);
        }
        boostingDocIdList.resize(numDoc);
        boostingScoreList.resize(numDoc);
        std::copy_backward(leftDocIdList.begin(), leftDocIdList.end(), boostingDocIdList.end());
        std::copy_backward(leftScoreList.begin(), leftScoreList.end(), boostingScoreList.end());
        std::swap(docIdList, boostingDocIdList);
        std::swap(rankScoreList, boostingScoreList);
    }
    else
    {
        rerankImpl_(docIdList, rankScoreList);
    }

    LOG(INFO) << "PropertyDiversityReranker::rerank() costs " << timer.elapsed() << " seconds";
}

void PropertyDiversityReranker::rerankImpl_(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList
)
{
    rerankDiversity_(docIdList, rankScoreList);
    rerankCTR_(docIdList, rankScoreList);
}

void PropertyDiversityReranker::rerankDiversity_(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList
)
{
    typedef std::list<std::pair<unsigned int,float> > DocIdList;
    typedef std::map<PropValueTable::pvid_t, DocIdList> DocIdMap;

    const PropValueTable* pvTable = NULL;
    if (groupManager_ && !diversityProperty_.empty())
    {
        pvTable = groupManager_->getPropValueTable(diversityProperty_);
        if (!pvTable)
        {
            LOG(ERROR) << "in PropertyDiversityReranker: group index file is not loaded for group property " << diversityProperty_;
            return;
        }
    }
    else
    {
        return;
    }

    const PropValueTable::ValueIdTable& idTable = pvTable->valueIdTable();
    std::size_t numDoc = docIdList.size();
    std::vector<unsigned int> newDocIdList;
    std::vector<float> newScoreList;
    newDocIdList.reserve(numDoc);
    newScoreList.reserve(numDoc);

    DocIdMap docIdMap;
    DocIdList missDocs;
    for (std::size_t i = 0; i < numDoc; ++i)
    {
        docid_t docId = docIdList[i];

        if (docId < idTable.size() && idTable[docId].empty() == false)
        {
            // use 1st group value
            PropValueTable::pvid_t pvId = idTable[docId][0];
            docIdMap[pvId].push_back(std::make_pair(docId, rankScoreList[i]));
        }
        else
        {
            missDocs.push_back(std::make_pair(docId, rankScoreList[i]));
        }
    }

    LOG(INFO) << "diversity property: " << diversityProperty_
              << ", group num: " << docIdMap.size()
              << ", doc num: " << docIdList.size();

    // single property or empty
    if(docIdMap.size() <= 1)
    {
        return;
    }

    while (!docIdMap.empty())
    {
        DocIdMap::iterator mapIt = docIdMap.begin();
        while(mapIt != docIdMap.end())
        {
            if(mapIt->second.empty())
            {
                docIdMap.erase(mapIt++);
            }
            else
            {
                std::pair<unsigned int, float> element = mapIt->second.front();
                mapIt->second.pop_front();
                newDocIdList.push_back(element.first);
                newScoreList.push_back(element.second);
                ++mapIt;
            }
        }
    }

    for(DocIdList::iterator missIt = missDocs.begin(); missIt != missDocs.end(); ++missIt)
    {
        newDocIdList.push_back(missIt->first);
        newScoreList.push_back(missIt->second);
    }

    std::swap(docIdList, newDocIdList);
    std::swap(rankScoreList, newScoreList);
}

void PropertyDiversityReranker::rerankCTR_(
    std::vector<unsigned int>& docIdList,
    std::vector<float>& rankScoreList
)
{
    std::vector<std::pair<size_t, count_t> > posClickCountList;
    bool hasClickCount = false;
    if (ctrManager_)
    {
        hasClickCount = ctrManager_->getClickCountListByDocIdList(docIdList, posClickCountList);
    }

    if (!hasClickCount)
        return;

    LOG(INFO) << "CTR rerank, doc num: " << docIdList.size();

    // sort by click-count
    std::stable_sort(posClickCountList.begin(), posClickCountList.end(), CompareSecond);

    std::size_t numDoc = docIdList.size();
    std::vector<unsigned int> newDocIdList(numDoc);
    std::vector<float> newScoreList(numDoc);

    size_t i = 0;
    for (std::vector<std::pair<size_t, count_t> >::iterator it = posClickCountList.begin();
        it != posClickCountList.end(); ++it)
    {
        size_t pos = it->first;
        newDocIdList[i] = docIdList[pos];
        newScoreList[i] = rankScoreList[pos];
        ++i;
    }

    std::swap(docIdList, newDocIdList);
    std::swap(rankScoreList, newScoreList);
}

NS_FACETED_END

<|endoftext|>


<commit_before>/*
 * This code is based off Adam Nielsen's cfgpath C header found at
 * https://github.com/Malvineous/cfgpath
 *
 * Following his code being public domain I have licensed this using the
 * unlicense http://unlicense.org/. Full license text is available in
 * the LICENSE file
 */

#include "cfgpath.hpp"

#include <sstream>
#include <stdexcept>
#include <cstdlib>

\
#ifdef _WIN32
#include <shlobj.h>
#include <direct.h>
const char _pathSep = '\\';
#endif

#ifdef __unix__
#include <sys/stat.h>
const char _pathSep = '/';
#endif

using std::stringstream;

bool createDirectoryIfNotExist(const string& path) {
#ifdef WIN32
    return (_mkdir(path.c_str()) == 0 || errno == EEXIST);
#elif defined(__APPLE__)
#elif defined(__unix__)
    return (mkdir(path.c_str(), 0700) == 0 || errno == EEXIST);
#else
    throw std::logic_error("Incompatible OS");
#endif
}

string get_standard_config_path() {
    stringstream cfgPath;
    //Windows first, then Apple, then other *nixes
#ifdef WIN32
    //using ansi windows for now
    //assume appdata directory exists
    char _confPath[MAX_PATH];
    if (!SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, _confPath))) {
        throw std::runtime_error("Unable to get standard config path from system");
    }
    cfgPath<< _confPath;
    cfgPath<< _pathSep;
#elif defined(__APPLE__)
#elif defined(__unix__)
    //Follow XDG Specification
    //Assume $XDG_CONFIG_HOME exists if it's set
    //Assume $HOME exists if it's set
    const char * _confHome = getenv("XDG_CONFIG_HOME");
    if (!_confHome) {
        //XDG_CONFIG_HOME isn't set. USE $HOME/.config
        _confHome = getenv("HOME");
        if (!_confHome) throw std::runtime_error("Unable to find home directory");
        cfgPath << _confHome;
        cfgPath << _pathSep;
        cfgPath << ".config";
        if (!createDirectoryIfNotExist(cfgPath.str()))
            throw std::runtime_error("Unable to create .config in user home");
    } else {
        cfgPath << _confHome;
    }
    cfgPath << _pathSep;
#else
    throw std::logic_error("Incompatible OS");
#endif
    return cfgPath.str();
}

bool createFileIfNotExist(const string& path) {
    return true;
}

string cfgpath::get_user_config_folder(const string& appname) {
    stringstream cfgPath;
    cfgPath << get_standard_config_path();
    cfgPath << appname;
    if (!createDirectoryIfNotExist(cfgPath.str()))
        throw std::runtime_error("Unable to create application config directory");
    cfgPath << _pathSep;
    return cfgPath.str();
}

string cfgpath::get_user_config_file(const string& appname, const std::__cxx11::string &extension) {
    stringstream cfgPath;
    cfgPath << get_standard_config_path() << appname << extension;
    return cfgPath.str();
}

string cfgpath::get_user_data_folder(const string& appname) {
    stringstream cfgPath;
    //Windows first, then Apple, then other *nixes
#ifdef WIN32
    //same path as config
    cfgPath << get_user_config_folder(appname);
#elif defined(__APPLE__)
#elif defined(__unix__)
    //Follow XDG Specification
    //Assume $XDG_DATA_HOME exists if it's set
    //Assume $HOME exists if it's set
    const char * _dataHome = getenv("XDG_DATA_HOME");
    if (!_dataHome) {
        //XDG_DATA_HOME isn't set. USE $HOME/.local/share
        _dataHome = getenv("HOME");
        if (!_dataHome) throw std::runtime_error("Unable to find home directory");
        cfgPath << _dataHome << _pathSep << ".local";
        if (!createDirectoryIfNotExist(cfgPath.str()))
            throw std::runtime_error("Unable to create .local in user home");
        cfgPath << _pathSep << "share";
        if (!createDirectoryIfNotExist(cfgPath.str()))
            throw std::runtime_error("Unable to create share in user home/.local");
    } else {
        cfgPath << _dataHome;
    }
    cfgPath << _pathSep << appname;
    if (!createDirectoryIfNotExist(cfgPath.str()))
        throw std::runtime_error("Unable to create application data directory");
    cfgPath << _pathSep;
#else
    throw std::logic_error("Incompatible OS");
#endif
    return cfgPath.str();
}
<commit_msg>Fixed params in get_user_config_file<commit_after>/*
 * This code is based off Adam Nielsen's cfgpath C header found at
 * https://github.com/Malvineous/cfgpath
 *
 * Following his code being public domain I have licensed this using the
 * unlicense http://unlicense.org/. Full license text is available in
 * the LICENSE file
 */

#include "cfgpath.hpp"

#include <sstream>
#include <stdexcept>
#include <cstdlib>

\
#ifdef _WIN32
#include <shlobj.h>
#include <direct.h>
const char _pathSep = '\\';
#endif

#ifdef __unix__
#include <sys/stat.h>
const char _pathSep = '/';
#endif

using std::stringstream;

bool createDirectoryIfNotExist(const string& path) {
#ifdef WIN32
    return (_mkdir(path.c_str()) == 0 || errno == EEXIST);
#elif defined(__APPLE__)
#elif defined(__unix__)
    return (mkdir(path.c_str(), 0700) == 0 || errno == EEXIST);
#else
    throw std::logic_error("Incompatible OS");
#endif
}

string get_standard_config_path() {
    stringstream cfgPath;
    //Windows first, then Apple, then other *nixes
#ifdef WIN32
    //using ansi windows for now
    //assume appdata directory exists
    char _confPath[MAX_PATH];
    if (!SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, _confPath))) {
        throw std::runtime_error("Unable to get standard config path from system");
    }
    cfgPath<< _confPath;
    cfgPath<< _pathSep;
#elif defined(__APPLE__)
#elif defined(__unix__)
    //Follow XDG Specification
    //Assume $XDG_CONFIG_HOME exists if it's set
    //Assume $HOME exists if it's set
    const char * _confHome = getenv("XDG_CONFIG_HOME");
    if (!_confHome) {
        //XDG_CONFIG_HOME isn't set. USE $HOME/.config
        _confHome = getenv("HOME");
        if (!_confHome) throw std::runtime_error("Unable to find home directory");
        cfgPath << _confHome;
        cfgPath << _pathSep;
        cfgPath << ".config";
        if (!createDirectoryIfNotExist(cfgPath.str()))
            throw std::runtime_error("Unable to create .config in user home");
    } else {
        cfgPath << _confHome;
    }
    cfgPath << _pathSep;
#else
    throw std::logic_error("Incompatible OS");
#endif
    return cfgPath.str();
}

bool createFileIfNotExist(const string& path) {
    return true;
}

string cfgpath::get_user_config_folder(const string& appname) {
    stringstream cfgPath;
    cfgPath << get_standard_config_path();
    cfgPath << appname;
    if (!createDirectoryIfNotExist(cfgPath.str()))
        throw std::runtime_error("Unable to create application config directory");
    cfgPath << _pathSep;
    return cfgPath.str();
}

string cfgpath::get_user_config_file(const string& appname, const string& extension) {
    stringstream cfgPath;
    cfgPath << get_standard_config_path() << appname << extension;
    return cfgPath.str();
}

string cfgpath::get_user_data_folder(const string& appname) {
    stringstream cfgPath;
    //Windows first, then Apple, then other *nixes
#ifdef WIN32
    //same path as config
    cfgPath << get_user_config_folder(appname);
#elif defined(__APPLE__)
#elif defined(__unix__)
    //Follow XDG Specification
    //Assume $XDG_DATA_HOME exists if it's set
    //Assume $HOME exists if it's set
    const char * _dataHome = getenv("XDG_DATA_HOME");
    if (!_dataHome) {
        //XDG_DATA_HOME isn't set. USE $HOME/.local/share
        _dataHome = getenv("HOME");
        if (!_dataHome) throw std::runtime_error("Unable to find home directory");
        cfgPath << _dataHome << _pathSep << ".local";
        if (!createDirectoryIfNotExist(cfgPath.str()))
            throw std::runtime_error("Unable to create .local in user home");
        cfgPath << _pathSep << "share";
        if (!createDirectoryIfNotExist(cfgPath.str()))
            throw std::runtime_error("Unable to create share in user home/.local");
    } else {
        cfgPath << _dataHome;
    }
    cfgPath << _pathSep << appname;
    if (!createDirectoryIfNotExist(cfgPath.str()))
        throw std::runtime_error("Unable to create application data directory");
    cfgPath << _pathSep;
#else
    throw std::logic_error("Incompatible OS");
#endif
    return cfgPath.str();
}
<|endoftext|>


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

This file is part of the elastix software.

Copyright (c) University Medical Center Utrecht. All rights reserved.
See src/CopyrightElastix.txt or http://elastix.isi.uu.nl/legal.php for
details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.

======================================================================*/

#include <iomanip>

#ifdef _ELASTIX_USE_MEVISDICOMTIFF
  #include "itkUseMevisDicomTiff.h"
#endif

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkImageIOBase.h"
#include <string>
#include "itkMath.h"
#include "itkDifferenceImageFilter.h"

//-------------------------------------------------------------------------------------
// This test tests the itkMevisDicomTiffImageIO library. The test is performed
// in 2D, 3D, and 4D, for a unsigned char image. An artificial image is generated,
// written to disk, read from disk, and compared to the original.

template< unsigned int Dimension >
int testMevis( void )
{
  //const unsigned int Dimension = 2;

  std::cerr << "Testing write/read of " << Dimension << "D image..." << std::endl;

  /** Some basic type definitions. */
  typedef unsigned char PixelType;

  typedef itk::Image< PixelType, Dimension > ImageType;
  typedef itk::ImageFileWriter< ImageType > WriterType;
  typedef itk::ImageFileReader< ImageType > ReaderType;
  typedef itk::DifferenceImageFilter< ImageType, ImageType > DiffType;
  typedef typename ImageType::SizeType SizeType;
  typedef typename ImageType::SpacingType SpacingType;
  typedef typename ImageType::PointType OriginType;
  typedef typename ImageType::DirectionType DirectionType;
  typedef itk::ImageRegionIterator< ImageType > IteratorType;

  typename WriterType::Pointer writer = WriterType::New();
  typename ReaderType::Pointer reader = ReaderType::New();
  typename ImageType::Pointer inputImage = ImageType::New();
  SizeType size;
  SpacingType spacing;
  OriginType origin;
  DirectionType direction;

  direction.Fill(0.0);
  for (unsigned int i = 0; i < Dimension; ++i )
  {
    size[i] = 20+i;
    spacing[i] = 0.5 + 0.1*i;
    origin[i] = 5 + 3*i;
    direction[i][i] = 1.0; // default, will be changed below
  }
  // Difficult direction cosines:
  if ( Dimension == 2 )
  {
    // Test flips
    direction[0][0] = 1; direction[0][1] = 0;
    direction[1][0] = 0; direction[1][1] = -1;
  }
  else if ( Dimension == 3 )
  {
    // Test axis permutations
    direction[0][0] = 1; direction[0][1] = 0; direction[0][2] = 0;
    direction[1][0] = 0; direction[1][1] = 0; direction[1][2] = 1;
    direction[2][0] = 0; direction[2][1] = 1; direction[2][2] = 0;
  }
  else if ( Dimension == 4 )
  {
    // Test 4D.
    direction[0][0] = 1; direction[0][1] = 0; direction[0][2] = 0; direction[0][3] = 0;
    direction[1][0] = 0; direction[1][1] = 0; direction[1][2] = 1; direction[1][3] = 0;
    direction[2][0] = 0; direction[2][1] = 1; direction[2][2] = 0; direction[2][3] = 0;
    direction[3][0] = 0; direction[3][1] = 0; direction[3][2] = 0; direction[3][3] = 1;
  }

  /** Generate image with gradually increasing pixel values. */
  inputImage->SetRegions( size );
  inputImage->SetSpacing( spacing );
  inputImage->SetOrigin( origin );
  inputImage->SetDirection( direction );

  try
  {
    inputImage->Allocate();
  }
  catch ( itk::ExceptionObject & err )
  {
    std::cerr << "ERROR: Failed to allocate test image" << std::endl;
    std::cerr << err << std::endl;
    return 1;
  }

  IteratorType it( inputImage, inputImage->GetLargestPossibleRegion() );
  unsigned long nrPixels = inputImage->GetLargestPossibleRegion().GetNumberOfPixels();
  double factor = itk::NumericTraits<PixelType>::max() / static_cast<double>(nrPixels);

  PixelType pixval = 0;
  unsigned long pixnr = 0;
  for ( it.GoToBegin(); !it.IsAtEnd(); ++it )
  {
    pixval = static_cast<PixelType>(
      itk::Math::Floor( static_cast<double>( pixnr * factor ) )  );
    it.Set( pixval );
  }

  std::string testfile("testimageMevisDicomTiff.dcm");
  writer->SetFileName( testfile );
  writer->SetInput( inputImage );
  reader->SetFileName( testfile );

  std::string task("");
  try
  {
    task = "Writing";
    writer->Update();
    task = "Reading";
    reader->Update();
  }
  catch ( itk::ExceptionObject & err )
  {
    std::cerr << "ERROR: " << task << " mevis dicomtiff failed in . " << std::endl;
    std::cerr << err << std::endl;
    return 1;
  }

  std::cerr << "\nPrintSelf():\n" << std::endl;
  typename itk::ImageIOBase::Pointer mevisIO = reader->GetImageIO();
  mevisIO->Print( std::cerr, 2 );

  typename ImageType::Pointer outputImage = reader->GetOutput();
  bool same = true;
  same &= size != outputImage->GetLargestPossibleRegion().GetSize();
  same &= spacing != outputImage->GetSpacing();
  same &= origin != outputImage->GetOrigin();
  same &= direction != outputImage->GetDirection();

  if ( ! same )
  {
    std::cerr << "ERROR: image properties are not preserved" << std::endl;
    std::cerr << "Original properties:" << std::endl;
    inputImage->Print( std::cerr, 0);
    std::cerr << "After write/read:" << std::endl;
    outputImage->Print( std::cerr, 0);
    return 1;
  }

  typename DiffType::Pointer diff = DiffType::New();
  diff->SetValidInput( inputImage );
  diff->SetTestInput( outputImage );
  diff->Update();
  unsigned long nrDiffPixels = diff->GetNumberOfPixelsWithDifferences();

  if ( nrDiffPixels > 0 )
  {
    std::cerr << "ERROR: the pixel values are not correct after write/read" << std::endl;
    return 1;
  }

  return 0;

} // end templated function

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

#ifdef _ELASTIX_USE_MEVISDICOMTIFF

  /** Test for 2d, 3d, and 4d images */
  int ret2d = testMevis<2>();
  int ret3d = testMevis<3>();
  int ret4d = testMevis<4>();

  /** Return a value. */
  return (ret2d | ret3d | ret4d);

#else

  std::cerr << "Elastix was not built with Mevis DicomTiff support, so this test is not relevant." << std::endl;
  return 0;

#endif

} // end main
<commit_msg>-BUG: test results were combined in the wrong way, resulting in always testfailure (but there is still a real bug in the mevis lib)<commit_after>/*======================================================================

This file is part of the elastix software.

Copyright (c) University Medical Center Utrecht. All rights reserved.
See src/CopyrightElastix.txt or http://elastix.isi.uu.nl/legal.php for
details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.

======================================================================*/

#include <iomanip>

#ifdef _ELASTIX_USE_MEVISDICOMTIFF
  #include "itkUseMevisDicomTiff.h"
#endif

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkImageRegionIterator.h"
#include "itkImageIOBase.h"
#include <string>
#include "itkMath.h"
#include "itkDifferenceImageFilter.h"

//-------------------------------------------------------------------------------------
// This test tests the itkMevisDicomTiffImageIO library. The test is performed
// in 2D, 3D, and 4D, for a unsigned char image. An artificial image is generated,
// written to disk, read from disk, and compared to the original.

template< unsigned int Dimension >
int testMevis( void )
{
  //const unsigned int Dimension = 2;

  std::cerr << "Testing write/read of " << Dimension << "D image..." << std::endl;

  /** Some basic type definitions. */
  typedef unsigned char PixelType;

  typedef itk::Image< PixelType, Dimension > ImageType;
  typedef itk::ImageFileWriter< ImageType > WriterType;
  typedef itk::ImageFileReader< ImageType > ReaderType;
  typedef itk::DifferenceImageFilter< ImageType, ImageType > DiffType;
  typedef typename ImageType::SizeType SizeType;
  typedef typename ImageType::SpacingType SpacingType;
  typedef typename ImageType::PointType OriginType;
  typedef typename ImageType::DirectionType DirectionType;
  typedef itk::ImageRegionIterator< ImageType > IteratorType;

  typename WriterType::Pointer writer = WriterType::New();
  typename ReaderType::Pointer reader = ReaderType::New();
  typename ImageType::Pointer inputImage = ImageType::New();
  SizeType size;
  SpacingType spacing;
  OriginType origin;
  DirectionType direction;

  direction.Fill(0.0);
  for (unsigned int i = 0; i < Dimension; ++i )
  {
    size[i] = 20+i;
    spacing[i] = 0.5 + 0.1*i;
    origin[i] = 5 + 3*i;
    direction[i][i] = 1.0; // default, will be changed below
  }
  // Difficult direction cosines:
  if ( Dimension == 2 )
  {
    // Test flips
    direction[0][0] = 1; direction[0][1] = 0;
    direction[1][0] = 0; direction[1][1] = -1;
  }
  else if ( Dimension == 3 )
  {
    // Test axis permutations
    direction[0][0] = 1; direction[0][1] = 0; direction[0][2] = 0;
    direction[1][0] = 0; direction[1][1] = 0; direction[1][2] = 1;
    direction[2][0] = 0; direction[2][1] = 1; direction[2][2] = 0;
  }
  else if ( Dimension == 4 )
  {
    // Test 4D.
    direction[0][0] = 1; direction[0][1] = 0; direction[0][2] = 0; direction[0][3] = 0;
    direction[1][0] = 0; direction[1][1] = 0; direction[1][2] = 1; direction[1][3] = 0;
    direction[2][0] = 0; direction[2][1] = 1; direction[2][2] = 0; direction[2][3] = 0;
    direction[3][0] = 0; direction[3][1] = 0; direction[3][2] = 0; direction[3][3] = 1;
  }

  /** Generate image with gradually increasing pixel values. */
  inputImage->SetRegions( size );
  inputImage->SetSpacing( spacing );
  inputImage->SetOrigin( origin );
  inputImage->SetDirection( direction );

  try
  {
    inputImage->Allocate();
  }
  catch ( itk::ExceptionObject & err )
  {
    std::cerr << "ERROR: Failed to allocate test image" << std::endl;
    std::cerr << err << std::endl;
    return 1;
  }

  IteratorType it( inputImage, inputImage->GetLargestPossibleRegion() );
  unsigned long nrPixels = inputImage->GetLargestPossibleRegion().GetNumberOfPixels();
  double factor = itk::NumericTraits<PixelType>::max() / static_cast<double>(nrPixels);

  PixelType pixval = 0;
  unsigned long pixnr = 0;
  for ( it.GoToBegin(); !it.IsAtEnd(); ++it )
  {
    pixval = static_cast<PixelType>(
      itk::Math::Floor( static_cast<double>( pixnr * factor ) )  );
    it.Set( pixval );
  }

  std::string testfile("testimageMevisDicomTiff.dcm");
  writer->SetFileName( testfile );
  writer->SetInput( inputImage );
  reader->SetFileName( testfile );

  std::string task("");
  try
  {
    task = "Writing";
    writer->Update();
    task = "Reading";
    reader->Update();
  }
  catch ( itk::ExceptionObject & err )
  {
    std::cerr << "ERROR: " << task << " mevis dicomtiff failed in . " << std::endl;
    std::cerr << err << std::endl;
    return 1;
  }

  std::cerr << "\nPrintSelf():\n" << std::endl;
  typename itk::ImageIOBase::Pointer mevisIO = reader->GetImageIO();
  mevisIO->Print( std::cerr, 2 );

  typename ImageType::Pointer outputImage = reader->GetOutput();
  bool same = true;
  same &= size == outputImage->GetLargestPossibleRegion().GetSize();
  same &= spacing == outputImage->GetSpacing();
  same &= origin == outputImage->GetOrigin();
  same &= direction == outputImage->GetDirection();

  if ( ! same )
  {
    std::cerr << "ERROR: image properties are not preserved" << std::endl;
    std::cerr << "Original properties:" << std::endl;
    inputImage->Print( std::cerr, 0);
    std::cerr << "After write/read:" << std::endl;
    outputImage->Print( std::cerr, 0);
    return 1;
  }

  typename DiffType::Pointer diff = DiffType::New();
  diff->SetValidInput( inputImage );
  diff->SetTestInput( outputImage );
  diff->Update();
  unsigned long nrDiffPixels = diff->GetNumberOfPixelsWithDifferences();

  if ( nrDiffPixels > 0 )
  {
    std::cerr << "ERROR: the pixel values are not correct after write/read" << std::endl;
    return 1;
  }

  return 0;

} // end templated function

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

#ifdef _ELASTIX_USE_MEVISDICOMTIFF

  /** Test for 2d, 3d, and 4d images */
  int ret2d = testMevis<2>();
  int ret3d = testMevis<3>();
  int ret4d = testMevis<4>();

  /** Return a value. */
  return (ret2d | ret3d | ret4d);

#else

  std::cerr << "Elastix was not built with Mevis DicomTiff support, so this test is not relevant." << std::endl;
  return 0;

#endif

} // end main
<|endoftext|>