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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#include <mitkContourElement.h>

mitk::ContourElement::ContourElement()
{
  this->m_Vertices = new VertexListType();
  this->m_IsClosed = false;
}

mitk::ContourElement::ContourElement(const mitk::ContourElement &other) :
  m_Vertices(other.m_Vertices), m_IsClosed(other.m_IsClosed)
{
}

mitk::ContourElement::~ContourElement()
{
  delete this->m_Vertices;
}

void mitk::ContourElement::AddVertex(mitk::Point3D &vertex, bool isControlPoint)
{
  this->m_Vertices->push_back(new VertexType(vertex, isControlPoint));
}

void mitk::ContourElement::AddVertex(VertexType &vertex)
{
  this->m_Vertices->push_back(&vertex);
}

void mitk::ContourElement::AddVertexAtFront(mitk::Point3D &vertex, bool isControlPoint)
{
  this->m_Vertices->push_front(new VertexType(vertex, isControlPoint));
}

void mitk::ContourElement::AddVertexAtFront(VertexType &vertex)
{
  this->m_Vertices->push_front(&vertex);
}

void mitk::ContourElement::InsertVertexAtIndex(mitk::Point3D &vertex, bool isControlPoint, int index)
{
  if(index > 0 && this->GetSize() > index)
  {
    VertexIterator _where = this->m_Vertices->begin();
    _where += index;
    this->m_Vertices->insert(_where, new VertexType(vertex, isControlPoint));
  }
}

mitk::ContourElement::VertexType* mitk::ContourElement::GetVertexAt(int index)
{
  return this->m_Vertices->at(index);
}

mitk::ContourElement::VertexType* mitk::ContourElement::GetVertexAt(const mitk::Point3D &point, float eps)
{
  /* current version iterates over the whole deque - should some kind of an octree with spatial query*/

  if(eps > 0)
  {
    if(this->m_Vertices->size() == 1)
    {
      return this->m_Vertices->at(0);
    }

    if(true ) //currently no method with better performance is available
    {
      return BruteForceGetVertexAt(point, eps);
    }
    else
    {
      return OptimizedGetVertexAt(point, eps);
    }
  }//if eps < 0
  return NULL;
}

mitk::ContourElement::VertexType* mitk::ContourElement::BruteForceGetVertexAt(const mitk::Point3D &point, float eps)
{
  if(eps > 0)
  {
    std::deque< std::pair<double, VertexType*> > nearestlist;

    ConstVertexIterator it = this->m_Vertices->begin();

    ConstVertexIterator end = this->m_Vertices->end();

    while(it != end)
    {
      mitk::Point3D currentPoint = (*it)->Coordinates;

      double distance = currentPoint.EuclideanDistanceTo(point);
      if(distance < eps)
      {
        //if list is emtpy, add point to list
        if(nearestlist.size() < 1)
        {
          nearestlist.push_front(std::pair<double, VertexType*>( (*it)->Coordinates.EuclideanDistanceTo(point), (*it) ));
        }
        //found an approximate point - check if current is closer then first in nearestlist
        else if( distance < nearestlist.front().first )
        {
          //found even closer vertex
          nearestlist.push_front(std::pair<double, VertexType*>( (*it)->Coordinates.EuclideanDistanceTo(point), (*it) ));
        }
      }//if distance > eps

      it++;
    }//while
    if(nearestlist.size() > 0)
    {
      /*++++++++++++++++++++ return the nearest active point if one was found++++++++++++++++++*/
      std::deque< std::pair<double, VertexType*> >::iterator it = nearestlist.begin();
      std::deque< std::pair<double, VertexType*> >::iterator end = nearestlist.end();
      while(it != end)
      {
        if( (*it).second->IsControlPoint )
        {
          return (*it).second;
        }
        it++;
      }
      /*---------------------------------------------------------------------------------------*/

      //return closest point
      return nearestlist.front().second;
    }
  }
  return NULL;
}

mitk::ContourElement::VertexType* mitk::ContourElement::OptimizedGetVertexAt(const mitk::Point3D &point, float eps)
{
  if( (eps > 0) && (this->m_Vertices->size()>0) )
  {
      int k = 1;
      int dim = 3;
      int nPoints = this->m_Vertices->size();
      ANNpointArray pointsArray;
      ANNpoint queryPoint;
      ANNidxArray indexArray;
      ANNdistArray distanceArray;
      ANNkd_tree* kdTree;

      queryPoint = annAllocPt(dim);
      pointsArray = annAllocPts(nPoints, dim);
      indexArray = new ANNidx[k];
      distanceArray = new ANNdist[k];

       int i = 0;

      //fill points array with our control points
      for(VertexIterator it = this->m_Vertices->begin(); it != this->m_Vertices->end(); it++, i++)
      {
        mitk::Point3D cur = (*it)->Coordinates;
        pointsArray[i][0]= cur[0];
        pointsArray[i][1]= cur[1];
        pointsArray[i][2]= cur[2];
      }

      //create the kd tree
      kdTree = new ANNkd_tree(pointsArray,nPoints, dim);

      //fill mitk::Point3D into ANN query point
      queryPoint[0] = point[0];
      queryPoint[1] = point[1];
      queryPoint[2] = point[2];

      //k nearest neighbour search
      kdTree->annkSearch(queryPoint, k, indexArray, distanceArray, eps);

      VertexType* ret = NULL;

      try
      {
        ret = this->m_Vertices->at(indexArray[0]);
      }
      catch(std::out_of_range ex)
      {
        //ret stays NULL
        return ret;
      }

      //clean up ANN
      delete [] indexArray;
      delete [] distanceArray;
      delete kdTree;
      annClose();

      return ret;
  }
  return NULL;
}

mitk::ContourElement::VertexListType* mitk::ContourElement::GetVertexList()
{
  return this->m_Vertices;
}

bool mitk::ContourElement::IsClosed()
{
  return this->m_IsClosed;
}

void mitk::ContourElement::Close()
{
  this->m_IsClosed = true;
}

void mitk::ContourElement::Open()
{
  this->m_IsClosed = false;
}

void mitk::ContourElement::SetIsClosed( bool isClosed)
{
  isClosed ? this->Close() : this->Open();
}

void mitk::ContourElement::Concatenate(mitk::ContourElement* other)
{
  if( other->GetSize() > 0)
  {
    ConstVertexIterator it =  other->m_Vertices->begin();
    ConstVertexIterator end =  other->m_Vertices->end();
    //add all vertices of other after last vertex
    while(it != end)
    {
      this->m_Vertices->push_back(*it);
      it++;
    }
  }
}

bool mitk::ContourElement::RemoveVertex(mitk::ContourElement::VertexType* vertex)
{
  VertexIterator it = this->m_Vertices->begin();

  VertexIterator end = this->m_Vertices->end();

  //search for vertex and remove it if exists
  while(it != end)
  {
    if((*it) == vertex)
    {
      this->m_Vertices->erase(it);
      return true;
    }

    it++;
  }

  return false;
}

bool mitk::ContourElement::RemoveVertexAt(int index)
{
  if( index >= 0 && index < this->m_Vertices->size() )
  {
    this->m_Vertices->erase(this->m_Vertices->begin()+index);
    return true;
  }
  else
  {
    return false;
  }
}

bool mitk::ContourElement::RemoveVertexAt(mitk::Point3D &point, float eps)
{
  /* current version iterates over the whole deque - should be some kind of an octree with spatial query*/

  if(eps > 0){
    VertexIterator it = this->m_Vertices->begin();

    VertexIterator end = this->m_Vertices->end();

    while(it != end)
    {
      mitk::Point3D currentPoint = (*it)->Coordinates;

      if(currentPoint.EuclideanDistanceTo(point) < eps)
      {
        //approximate point found
        //now erase it
        this->m_Vertices->erase(it);
        return true;
      }

      it++;
    }
  }
  return false;
}

void mitk::ContourElement::Clear()
{
  this->m_Vertices->clear();
}
<commit_msg>COMP Changed selection method of vertices.<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/
#include <mitkContourElement.h>

mitk::ContourElement::ContourElement()
{
  this->m_Vertices = new VertexListType();
  this->m_IsClosed = false;
}

mitk::ContourElement::ContourElement(const mitk::ContourElement &other) :
  m_Vertices(other.m_Vertices), m_IsClosed(other.m_IsClosed)
{
}

mitk::ContourElement::~ContourElement()
{
  delete this->m_Vertices;
}

void mitk::ContourElement::AddVertex(mitk::Point3D &vertex, bool isControlPoint)
{
  this->m_Vertices->push_back(new VertexType(vertex, isControlPoint));
}

void mitk::ContourElement::AddVertex(VertexType &vertex)
{
  this->m_Vertices->push_back(&vertex);
}

void mitk::ContourElement::AddVertexAtFront(mitk::Point3D &vertex, bool isControlPoint)
{
  this->m_Vertices->push_front(new VertexType(vertex, isControlPoint));
}

void mitk::ContourElement::AddVertexAtFront(VertexType &vertex)
{
  this->m_Vertices->push_front(&vertex);
}

void mitk::ContourElement::InsertVertexAtIndex(mitk::Point3D &vertex, bool isControlPoint, int index)
{
  if(index > 0 && this->GetSize() > index)
  {
    VertexIterator _where = this->m_Vertices->begin();
    _where += index;
    this->m_Vertices->insert(_where, new VertexType(vertex, isControlPoint));
  }
}

mitk::ContourElement::VertexType* mitk::ContourElement::GetVertexAt(int index)
{
  return this->m_Vertices->at(index);
}

mitk::ContourElement::VertexType* mitk::ContourElement::GetVertexAt(const mitk::Point3D &point, float eps)
{
  /* current version iterates over the whole deque - should some kind of an octree with spatial query*/

  if(eps > 0)
  {
    //currently no method with better performance is available
    return BruteForceGetVertexAt(point, eps);
  }//if eps < 0
  return NULL;
}

mitk::ContourElement::VertexType* mitk::ContourElement::BruteForceGetVertexAt(const mitk::Point3D &point, float eps)
{
  if(eps > 0)
  {
    std::deque< std::pair<double, VertexType*> > nearestlist;

    ConstVertexIterator it = this->m_Vertices->begin();

    ConstVertexIterator end = this->m_Vertices->end();

    while(it != end)
    {
      mitk::Point3D currentPoint = (*it)->Coordinates;

      double distance = currentPoint.EuclideanDistanceTo(point);
      if(distance < eps)
      {
        //if list is emtpy, add point to list
        if(nearestlist.size() < 1)
        {
          nearestlist.push_front(std::pair<double, VertexType*>( (*it)->Coordinates.EuclideanDistanceTo(point), (*it) ));
        }
        //found an approximate point - check if current is closer then first in nearestlist
        else if( distance < nearestlist.front().first )
        {
          //found even closer vertex
          nearestlist.push_front(std::pair<double, VertexType*>( (*it)->Coordinates.EuclideanDistanceTo(point), (*it) ));
        }
      }//if distance > eps

      it++;
    }//while
    if(nearestlist.size() > 0)
    {
      /*++++++++++++++++++++ return the nearest active point if one was found++++++++++++++++++*/
      std::deque< std::pair<double, VertexType*> >::iterator it = nearestlist.begin();
      std::deque< std::pair<double, VertexType*> >::iterator end = nearestlist.end();
      while(it != end)
      {
        if( (*it).second->IsControlPoint )
        {
          return (*it).second;
        }
        it++;
      }
      /*---------------------------------------------------------------------------------------*/

      //return closest point
      return nearestlist.front().second;
    }
  }
  return NULL;
}

mitk::ContourElement::VertexType* mitk::ContourElement::OptimizedGetVertexAt(const mitk::Point3D &point, float eps)
{
  if( (eps > 0) && (this->m_Vertices->size()>0) )
  {
      int k = 1;
      int dim = 3;
      int nPoints = this->m_Vertices->size();
      ANNpointArray pointsArray;
      ANNpoint queryPoint;
      ANNidxArray indexArray;
      ANNdistArray distanceArray;
      ANNkd_tree* kdTree;

      queryPoint = annAllocPt(dim);
      pointsArray = annAllocPts(nPoints, dim);
      indexArray = new ANNidx[k];
      distanceArray = new ANNdist[k];

       int i = 0;

      //fill points array with our control points
      for(VertexIterator it = this->m_Vertices->begin(); it != this->m_Vertices->end(); it++, i++)
      {
        mitk::Point3D cur = (*it)->Coordinates;
        pointsArray[i][0]= cur[0];
        pointsArray[i][1]= cur[1];
        pointsArray[i][2]= cur[2];
      }

      //create the kd tree
      kdTree = new ANNkd_tree(pointsArray,nPoints, dim);

      //fill mitk::Point3D into ANN query point
      queryPoint[0] = point[0];
      queryPoint[1] = point[1];
      queryPoint[2] = point[2];

      //k nearest neighbour search
      kdTree->annkSearch(queryPoint, k, indexArray, distanceArray, eps);

      VertexType* ret = NULL;

      try
      {
        ret = this->m_Vertices->at(indexArray[0]);
      }
      catch(std::out_of_range ex)
      {
        //ret stays NULL
        return ret;
      }

      //clean up ANN
      delete [] indexArray;
      delete [] distanceArray;
      delete kdTree;
      annClose();

      return ret;
  }
  return NULL;
}

mitk::ContourElement::VertexListType* mitk::ContourElement::GetVertexList()
{
  return this->m_Vertices;
}

bool mitk::ContourElement::IsClosed()
{
  return this->m_IsClosed;
}

void mitk::ContourElement::Close()
{
  this->m_IsClosed = true;
}

void mitk::ContourElement::Open()
{
  this->m_IsClosed = false;
}

void mitk::ContourElement::SetIsClosed( bool isClosed)
{
  isClosed ? this->Close() : this->Open();
}

void mitk::ContourElement::Concatenate(mitk::ContourElement* other)
{
  if( other->GetSize() > 0)
  {
    ConstVertexIterator it =  other->m_Vertices->begin();
    ConstVertexIterator end =  other->m_Vertices->end();
    //add all vertices of other after last vertex
    while(it != end)
    {
      this->m_Vertices->push_back(*it);
      it++;
    }
  }
}

bool mitk::ContourElement::RemoveVertex(mitk::ContourElement::VertexType* vertex)
{
  VertexIterator it = this->m_Vertices->begin();

  VertexIterator end = this->m_Vertices->end();

  //search for vertex and remove it if exists
  while(it != end)
  {
    if((*it) == vertex)
    {
      this->m_Vertices->erase(it);
      return true;
    }

    it++;
  }

  return false;
}

bool mitk::ContourElement::RemoveVertexAt(int index)
{
  if( index >= 0 && index < this->m_Vertices->size() )
  {
    this->m_Vertices->erase(this->m_Vertices->begin()+index);
    return true;
  }
  else
  {
    return false;
  }
}

bool mitk::ContourElement::RemoveVertexAt(mitk::Point3D &point, float eps)
{
  /* current version iterates over the whole deque - should be some kind of an octree with spatial query*/

  if(eps > 0){
    VertexIterator it = this->m_Vertices->begin();

    VertexIterator end = this->m_Vertices->end();

    while(it != end)
    {
      mitk::Point3D currentPoint = (*it)->Coordinates;

      if(currentPoint.EuclideanDistanceTo(point) < eps)
      {
        //approximate point found
        //now erase it
        this->m_Vertices->erase(it);
        return true;
      }

      it++;
    }
  }
  return false;
}

void mitk::ContourElement::Clear()
{
  this->m_Vertices->clear();
}
<|endoftext|>


<commit_before>//
#include <bela/pe.hpp>
#include <bela/subsitute.hpp>
#include <bela/finaly.hpp>
#include <bela/path.hpp>
#include "baulk.hpp"
#include "fs.hpp"
#include "rcwriter.hpp"

namespace baulk {
// make launcher
namespace internal {
constexpr std::wstring_view consoletemplete = LR"(#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnt.h>
inline constexpr size_t StringLength(const wchar_t *s) {
  const wchar_t *a = s;
  for (; *a != 0; a++) {
    ;
  }
  return a - s;
}
inline void StringZero(wchar_t *p, size_t len) {
  for (size_t i = 0; i < len; i++) {
    p[i] = 0;
  }
}
inline void *StringCopy(wchar_t *dest, const wchar_t *src, size_t n) {
  auto d = dest;
  for (; n; n--) {
    *d++ = *src++;
  }
  return dest;
}
inline wchar_t *StringAllocate(size_t count) {
  return reinterpret_cast<wchar_t *>(
      HeapAlloc(GetProcessHeap(), 0, sizeof(wchar_t) * count));
}
inline wchar_t *StringDup(const wchar_t *s) {
  auto l = StringLength(s);
  auto ds = StringAllocate(l + 1);
  StringCopy(ds, s, l);
  ds[l] = 0;
  return ds;
}
inline void StringFree(wchar_t *p) { HeapFree(GetProcessHeap(), 0, p); }
int wmain() {
  constexpr const wchar_t *target = L"$0";
  STARTUPINFOW si;
  PROCESS_INFORMATION pi;
  SecureZeroMemory(&si, sizeof(si));
  SecureZeroMemory(&pi, sizeof(pi));
  si.cb = sizeof(si);
  auto cmdline = StringDup(GetCommandLineW());
  if (!CreateProcessW(target, cmdline, nullptr, nullptr, FALSE,
                      CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &si, &pi)) {
    StringFree(cmdline);
    return -1;
  }
  StringFree(cmdline);
  CloseHandle(pi.hThread);
  SetConsoleCtrlHandler(nullptr, TRUE);
  WaitForSingleObject(pi.hProcess, INFINITE);
  SetConsoleCtrlHandler(nullptr, FALSE);
  DWORD exitCode;
  GetExitCodeProcess(pi.hProcess, &exitCode);
  CloseHandle(pi.hProcess);
  return exitCode;
}
)";

constexpr std::wstring_view windowstemplate = LR"(#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cstddef>
inline constexpr size_t StringLength(const wchar_t *s) {
  const wchar_t *a = s;
  for (; *a != 0; a++) {
    ;
  }
  return a - s;
}
inline void StringZero(wchar_t *p, size_t len) {
  for (size_t i = 0; i < len; i++) {
    p[i] = 0;
  }
}
inline void *StringCopy(wchar_t *dest, const wchar_t *src, size_t n) {
  auto d = dest;
  for (; n; n--) {
    *d++ = *src++;
  }
  return dest;
}
inline wchar_t *StringAllocate(size_t count) {
  return reinterpret_cast<wchar_t *>(
      HeapAlloc(GetProcessHeap(), 0, sizeof(wchar_t) * count));
}
inline wchar_t *StringDup(const wchar_t *s) {
  auto l = StringLength(s);
  auto ds = StringAllocate(l + 1);
  StringCopy(ds, s, l);
  ds[l] = 0;
  return ds;
}
inline void StringFree(wchar_t *p) { HeapFree(GetProcessHeap(), 0, p); }
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
  constexpr const wchar_t *target = L"$0";
  STARTUPINFOW si;
  PROCESS_INFORMATION pi;
  SecureZeroMemory(&si, sizeof(si));
  SecureZeroMemory(&pi, sizeof(pi));
  si.cb = sizeof(si);
  auto cmdline = StringDup(GetCommandLineW());
  if (!CreateProcessW(target, cmdline, nullptr, nullptr, FALSE,
                      CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &si, &pi)) {
    StringFree(cmdline);
    return -1;
  }
  StringFree(cmdline);
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  return 0;
}
)";
} // namespace internal

// GenerateLinkSource generate link sources
std::wstring GenerateLinkSource(std::wstring_view target,
                                bela::pe::Subsystem subs) {
  std::wstring escapetarget;
  escapetarget.reserve(target.size() + 10);
  for (auto c : target) {
    if (c == '\\') {
      escapetarget.append(L"\\\\");
      continue;
    }
    escapetarget.push_back(c);
  }
  if (subs == bela::pe::Subsystem::CUI) {
    return bela::Substitute(internal::consoletemplete, escapetarget);
  }
  return bela::Substitute(internal::windowstemplate, escapetarget);
}

// write UTF8
bool LinkSourceStore(std::wstring_view path, std::string_view source,
                     bela::error_code &ec) {
  auto FileHandle = ::CreateFileW(
      path.data(), FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ,
      nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
  if (FileHandle == INVALID_HANDLE_VALUE) {
    ec = bela::make_system_error_code();
    return false;
  }
  DWORD written = 0;
  auto p = source.data();
  auto size = source.size();
  while (size > 0) {
    auto len = (std::min)(size, static_cast<size_t>(4096));
    if (WriteFile(FileHandle, p, static_cast<DWORD>(len), &written, nullptr) !=
        TRUE) {
      ec = bela::make_system_error_code();
      break;
    }
    size -= written;
    p += written;
  }
  CloseHandle(FileHandle);
  return size == 0;
}

// ConvertToUTF8
bool LinkSourceStore(std::wstring_view path, std::wstring_view source,
                     bela::error_code &ec) {
  auto u8source = bela::ToNarrow(source);
  return LinkSourceStore(path, u8source, ec);
}

bool MakeLaunchers(std::wstring_view root, const baulk::Package &pkg,
                   bool forceoverwrite, bela::error_code &ec) {
  auto pkgroot = bela::StringCat(root, L"\\pkg\\", pkg.name);
  return false;
}

// create symlink
bool MakeSymlinks(std::wstring_view root, const baulk::Package &pkg,
                  bool forceoverwrite, bela::error_code &ec) {
  auto pkgroot = bela::StringCat(root, L"\\bin\\pkg\\", pkg.name);
  auto linked = bela::StringCat(root, L"\\bin\\pkg\\.linked\\");
  for (const auto &lnk : pkg.links) {
    auto src = bela::PathCat(pkgroot, lnk);
    auto fn = baulk::fs::FileName(src);
    auto lnk = bela::StringCat(linked, fn);
    if (bela::PathExists(lnk)) {
      if (forceoverwrite) {
        baulk::fs::PathRemove(lnk, ec);
      }
    }
    if (!baulk::fs::SymLink(src, lnk, ec)) {
      return false;
    }
  }
  return false;
}

bool MakeLinks(std::wstring_view root, const baulk::Package &pkg,
               bool forceoverwrite, bela::error_code &ec) {
  if (!pkg.links.empty() && !MakeSymlinks(root, pkg, forceoverwrite, ec)) {
    return false;
  }
  if (!pkg.launchers.empty() && !MakeLaunchers(root, pkg, forceoverwrite, ec)) {
    return false;
  }
  return true;
}
} // namespace baulk
<commit_msg>[baulk] LinkExecutor::Initialize<commit_after>//
#include <bela/pe.hpp>
#include <bela/subsitute.hpp>
#include <bela/finaly.hpp>
#include <bela/path.hpp>
#include "baulk.hpp"
#include "fs.hpp"
#include "rcwriter.hpp"

namespace baulk {
// make launcher
namespace internal {
constexpr std::wstring_view consoletemplete = LR"(#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winnt.h>
inline constexpr size_t StringLength(const wchar_t *s) {
  const wchar_t *a = s;
  for (; *a != 0; a++) {
    ;
  }
  return a - s;
}
inline void StringZero(wchar_t *p, size_t len) {
  for (size_t i = 0; i < len; i++) {
    p[i] = 0;
  }
}
inline void *StringCopy(wchar_t *dest, const wchar_t *src, size_t n) {
  auto d = dest;
  for (; n; n--) {
    *d++ = *src++;
  }
  return dest;
}
inline wchar_t *StringAllocate(size_t count) {
  return reinterpret_cast<wchar_t *>(
      HeapAlloc(GetProcessHeap(), 0, sizeof(wchar_t) * count));
}
inline wchar_t *StringDup(const wchar_t *s) {
  auto l = StringLength(s);
  auto ds = StringAllocate(l + 1);
  StringCopy(ds, s, l);
  ds[l] = 0;
  return ds;
}
inline void StringFree(wchar_t *p) { HeapFree(GetProcessHeap(), 0, p); }
int wmain() {
  constexpr const wchar_t *target = L"$0";
  STARTUPINFOW si;
  PROCESS_INFORMATION pi;
  SecureZeroMemory(&si, sizeof(si));
  SecureZeroMemory(&pi, sizeof(pi));
  si.cb = sizeof(si);
  auto cmdline = StringDup(GetCommandLineW());
  if (!CreateProcessW(target, cmdline, nullptr, nullptr, FALSE,
                      CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &si, &pi)) {
    StringFree(cmdline);
    return -1;
  }
  StringFree(cmdline);
  CloseHandle(pi.hThread);
  SetConsoleCtrlHandler(nullptr, TRUE);
  WaitForSingleObject(pi.hProcess, INFINITE);
  SetConsoleCtrlHandler(nullptr, FALSE);
  DWORD exitCode;
  GetExitCodeProcess(pi.hProcess, &exitCode);
  CloseHandle(pi.hProcess);
  return exitCode;
}
)";

constexpr std::wstring_view windowstemplate = LR"(#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <cstddef>
inline constexpr size_t StringLength(const wchar_t *s) {
  const wchar_t *a = s;
  for (; *a != 0; a++) {
    ;
  }
  return a - s;
}
inline void StringZero(wchar_t *p, size_t len) {
  for (size_t i = 0; i < len; i++) {
    p[i] = 0;
  }
}
inline void *StringCopy(wchar_t *dest, const wchar_t *src, size_t n) {
  auto d = dest;
  for (; n; n--) {
    *d++ = *src++;
  }
  return dest;
}
inline wchar_t *StringAllocate(size_t count) {
  return reinterpret_cast<wchar_t *>(
      HeapAlloc(GetProcessHeap(), 0, sizeof(wchar_t) * count));
}
inline wchar_t *StringDup(const wchar_t *s) {
  auto l = StringLength(s);
  auto ds = StringAllocate(l + 1);
  StringCopy(ds, s, l);
  ds[l] = 0;
  return ds;
}
inline void StringFree(wchar_t *p) { HeapFree(GetProcessHeap(), 0, p); }
int WINAPI wWinMain(HINSTANCE, HINSTANCE, LPWSTR, int) {
  constexpr const wchar_t *target = L"$0";
  STARTUPINFOW si;
  PROCESS_INFORMATION pi;
  SecureZeroMemory(&si, sizeof(si));
  SecureZeroMemory(&pi, sizeof(pi));
  si.cb = sizeof(si);
  auto cmdline = StringDup(GetCommandLineW());
  if (!CreateProcessW(target, cmdline, nullptr, nullptr, FALSE,
                      CREATE_UNICODE_ENVIRONMENT, nullptr, nullptr, &si, &pi)) {
    StringFree(cmdline);
    return -1;
  }
  StringFree(cmdline);
  CloseHandle(pi.hThread);
  CloseHandle(pi.hProcess);
  return 0;
}
)";
} // namespace internal

// GenerateLinkSource generate link sources
std::wstring GenerateLinkSource(std::wstring_view target,
                                bela::pe::Subsystem subs) {
  std::wstring escapetarget;
  escapetarget.reserve(target.size() + 10);
  for (auto c : target) {
    if (c == '\\') {
      escapetarget.append(L"\\\\");
      continue;
    }
    escapetarget.push_back(c);
  }
  if (subs == bela::pe::Subsystem::CUI) {
    return bela::Substitute(internal::consoletemplete, escapetarget);
  }
  return bela::Substitute(internal::windowstemplate, escapetarget);
}

// write UTF8
bool LinkSourceStore(std::wstring_view path, std::string_view source,
                     bela::error_code &ec) {
  auto FileHandle = ::CreateFileW(
      path.data(), FILE_GENERIC_READ | FILE_GENERIC_WRITE, FILE_SHARE_READ,
      nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
  if (FileHandle == INVALID_HANDLE_VALUE) {
    ec = bela::make_system_error_code();
    return false;
  }
  DWORD written = 0;
  auto p = source.data();
  auto size = source.size();
  while (size > 0) {
    auto len = (std::min)(size, static_cast<size_t>(4096));
    if (WriteFile(FileHandle, p, static_cast<DWORD>(len), &written, nullptr) !=
        TRUE) {
      ec = bela::make_system_error_code();
      break;
    }
    size -= written;
    p += written;
  }
  CloseHandle(FileHandle);
  return size == 0;
}

// ConvertToUTF8
bool LinkSourceStore(std::wstring_view path, std::wstring_view source,
                     bela::error_code &ec) {
  auto u8source = bela::ToNarrow(source);
  return LinkSourceStore(path, u8source, ec);
}

class LinkExecutor {
public:
  LinkExecutor() = default;
  LinkExecutor(const LinkExecutor &) = delete;
  LinkExecutor &operator=(const LinkExecutor &) = delete;
  ~LinkExecutor() {
    //
  }
  bool Initialize(const baulk::Package &pkg, bela::error_code &ec);
  bool Execute(std::wstring_view root, bela::error_code &ec);

private:
  std::wstring baulktemp;
};

std::wstring MakeTempDir(bela::error_code ec) {
  std::error_code e;
  auto tmppath = std::filesystem::temp_directory_path(e);
  if (e) {
    ec = bela::from_std_error_code(e);
    return L"";
  }
  auto tmpdir = tmppath.wstring();
  auto len = tmpdir.size();
  wchar_t X = 'A';
  bela::AlphaNum an(GetCurrentThreadId());
  for (wchar_t X = 'A'; X < 'Z'; X++) {
    bela::StrAppend(&tmpdir, L"\\BaulkTemp", X, an);
    if (std::filesystem::exists(tmpdir, e)) {
      return tmpdir;
    }
    tmpdir.resize(len);
  }
  ec = bela::make_error_code(1, L"cannot create tempdir");
  return L"";
}

bool LinkExecutor::Initialize(const baulk::Package &pkg, bela::error_code &ec) {
  if (baulktemp = MakeTempDir(ec); baulktemp.empty()) {
    return false;
  }
  if (!baulk::fs::MakeDir(baulktemp, ec)) {
    return false;
  }
  // --------------> write
  return false;
}

bool MakeLaunchers(std::wstring_view root, const baulk::Package &pkg,
                   bool forceoverwrite, bela::error_code &ec) {
  auto pkgroot = bela::StringCat(root, L"\\pkg\\", pkg.name);
  return false;
}

// create symlink
bool MakeSymlinks(std::wstring_view root, const baulk::Package &pkg,
                  bool forceoverwrite, bela::error_code &ec) {
  auto pkgroot = bela::StringCat(root, L"\\bin\\pkg\\", pkg.name);
  auto linked = bela::StringCat(root, L"\\bin\\pkg\\.linked\\");
  for (const auto &lnk : pkg.links) {
    auto src = bela::PathCat(pkgroot, lnk);
    auto fn = baulk::fs::FileName(src);
    auto lnk = bela::StringCat(linked, fn);
    if (bela::PathExists(lnk)) {
      if (forceoverwrite) {
        baulk::fs::PathRemove(lnk, ec);
      }
    }
    if (!baulk::fs::SymLink(src, lnk, ec)) {
      return false;
    }
  }
  return false;
}

bool MakeLinks(std::wstring_view root, const baulk::Package &pkg,
               bool forceoverwrite, bela::error_code &ec) {
  if (!pkg.links.empty() && !MakeSymlinks(root, pkg, forceoverwrite, ec)) {
    return false;
  }
  if (!pkg.launchers.empty() && !MakeLaunchers(root, pkg, forceoverwrite, ec)) {
    return false;
  }
  return true;
}
} // namespace baulk
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: AccessibleEditObject.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: sab $ $Date: 2002-08-29 13:05:05 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SC_ACCESSIBLEEDITOBJECT_HXX
#include "AccessibleEditObject.hxx"
#endif

#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#include <svx/eeitem.hxx>
#define ITEMID_FIELD EE_FEATURE_FIELD
#ifndef SC_UNOGUARD_HXX
#include "unoguard.hxx"
#endif

#ifndef _SC_ACCESSIBLETEXT_HXX
#include "AccessibleText.hxx"
#endif
#ifndef SC_EDITSRC_HXX
#include "editsrc.hxx"
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
#include <unotools/accessiblestatesethelper.hxx>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleRole.hpp>
#endif
#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
#include <drafts/com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SVX_ACCESSILE_TEXT_HELPER_HXX_
#include <svx/AccessibleTextHelper.hxx>
#endif
#ifndef _MyEDITVIEW_HXX
#include <svx/editview.hxx>
#endif
#ifndef _MyEDITENG_HXX
#include <svx/editeng.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::drafts::com::sun::star::accessibility;

//=====  internal  ============================================================

ScAccessibleEditObject::ScAccessibleEditObject(
        const uno::Reference<XAccessible>& rxParent,
        EditView* pEditView, Window* pWin, const rtl::OUString& rName,
        const rtl::OUString& rDescription, EditObjectType eObjectType)
    :
    ScAccessibleContextBase(rxParent, AccessibleRole::PANEL),
    mpTextHelper(NULL),
    mpEditView(pEditView),
    mpWindow(pWin),
    meObjectType(eObjectType),
    mbHasFocus(sal_False)
{
    CreateTextHelper();
    SetName(rName);
    SetDescription(rDescription);
}

ScAccessibleEditObject::~ScAccessibleEditObject()
{
    if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
    {
        // increment refcount to prevent double call off dtor
        osl_incrementInterlockedCount( &m_refCount );
        // call dispose to inform object wich have a weak reference to this object
        dispose();
    }
}

void SAL_CALL ScAccessibleEditObject::disposing()
{
    ScUnoGuard aGuard;
    if (mpTextHelper)
        DELETEZ(mpTextHelper);

    ScAccessibleContextBase::disposing();
}

void ScAccessibleEditObject::LostFocus()
{
    if (mpTextHelper)
        mpTextHelper->SetFocus(sal_False);
    mbHasFocus = sal_False;
}

void ScAccessibleEditObject::GotFocus()
{
    if (mpTextHelper)
        mpTextHelper->SetFocus(sal_True);
    mbHasFocus = sal_True;
}

    //=====  XAccessibleComponent  ============================================

uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAt(
        const awt::Point& rPoint )
        throw (uno::RuntimeException)
{
    uno::Reference<XAccessible> xRet;
    if (contains(rPoint))
    {
         ScUnoGuard aGuard;
        IsObjectValid();

        if(!mpTextHelper)
            CreateTextHelper();

        xRet = mpTextHelper->GetAt(rPoint);
    }

    return xRet;
}

Rectangle ScAccessibleEditObject::GetBoundingBoxOnScreen(void) const
        throw (uno::RuntimeException)
{
    Rectangle aCellRect(GetBoundingBox());
    if (mpWindow)
    {
        Point aLoc;
        aCellRect.getLocation(aLoc);
        Rectangle aRect = mpWindow->GetWindowExtentsRelative(NULL);
        Point aLoc2;
        aRect.getLocation(aLoc2);
        aCellRect.setLocation(Point(aLoc.getX() + aLoc2.getX(), aLoc.getY() + aLoc2.getY()));
        //aCellRect.setX(aCellRect.getX() + aRect.getX());
        //aCellRect.setY(aCellRect.getY() + aRect.getY());
    }
    return aCellRect;
}

Rectangle ScAccessibleEditObject::GetBoundingBox(void) const
        throw (uno::RuntimeException)
{
    Rectangle aCellRect;
    if (meObjectType == CellInEditMode)
    {
        if (mpEditView && mpWindow && mpEditView->GetEditEngine())
        {
            MapMode aMapMode(mpEditView->GetEditEngine()->GetRefMapMode());

            aCellRect = mpWindow->LogicToPixel( mpEditView->GetOutputArea() , aMapMode );
        }
    }
    else
    {
        if (mpWindow)
        {
            aCellRect = mpWindow->GetWindowExtentsRelative(mpWindow->GetAccessibleParentWindow());
        }
    }
    return aCellRect;
}

    //=====  XAccessibleContext  ==============================================

sal_Int32 SAL_CALL
    ScAccessibleEditObject::getAccessibleChildCount(void)
                    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    if (!mpTextHelper)
        CreateTextHelper();
    return mpTextHelper->GetChildCount();
}

uno::Reference< XAccessible > SAL_CALL
    ScAccessibleEditObject::getAccessibleChild(sal_Int32 nIndex)
        throw (uno::RuntimeException,
        lang::IndexOutOfBoundsException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    if (!mpTextHelper)
        CreateTextHelper();
    return mpTextHelper->GetChild(nIndex);
}

uno::Reference<XAccessibleStateSet> SAL_CALL
    ScAccessibleEditObject::getAccessibleStateSet(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessibleStateSet> xParentStates;
    if (getAccessibleParent().is())
    {
        uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
        xParentStates = xParentContext->getAccessibleStateSet();
    }
    utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
    if (IsDefunc(xParentStates))
        pStateSet->AddState(AccessibleStateType::DEFUNC);
    else
    {
        // all states are const, because this object exists only in one state
        pStateSet->AddState(AccessibleStateType::EDITABLE);
        pStateSet->AddState(AccessibleStateType::ENABLED);
        pStateSet->AddState(AccessibleStateType::MULTILINE);
        pStateSet->AddState(AccessibleStateType::MULTISELECTABLE);
        pStateSet->AddState(AccessibleStateType::SHOWING);
        pStateSet->AddState(AccessibleStateType::VISIBLE);
    }
    return pStateSet;
}

::rtl::OUString SAL_CALL
    ScAccessibleEditObject::createAccessibleDescription(void)
    throw (uno::RuntimeException)
{
//    DBG_ERRORFILE("Should never be called, because is set in the constructor.")
    return rtl::OUString();
}

::rtl::OUString SAL_CALL
    ScAccessibleEditObject::createAccessibleName(void)
    throw (uno::RuntimeException)
{
    DBG_ERRORFILE("Should never be called, because is set in the constructor.");
    return rtl::OUString();
}

    ///=====  XAccessibleEventBroadcaster  =====================================

void SAL_CALL
    ScAccessibleEditObject::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
        throw (uno::RuntimeException)
{
    if (!mpTextHelper)
        CreateTextHelper();

    mpTextHelper->AddEventListener(xListener);

    ScAccessibleContextBase::addEventListener(xListener);
}

void SAL_CALL
    ScAccessibleEditObject::removeEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
        throw (uno::RuntimeException)
{
    if (!mpTextHelper)
        CreateTextHelper();

    mpTextHelper->RemoveEventListener(xListener);

    ScAccessibleContextBase::removeEventListener(xListener);
}

    //=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL ScAccessibleEditObject::getImplementationName(void)
        throw (uno::RuntimeException)
{
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleEditObject"));
}

//=====  XTypeProvider  =======================================================

uno::Sequence<sal_Int8> SAL_CALL
    ScAccessibleEditObject::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    static uno::Sequence<sal_Int8> aId;
    if (aId.getLength() == 0)
    {
        aId.realloc (16);
        rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
    }
    return aId;
}

    //====  internal  =========================================================

sal_Bool ScAccessibleEditObject::IsDefunc(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
}

void ScAccessibleEditObject::CreateTextHelper()
{
    if (!mpTextHelper)
    {
        if (meObjectType == CellInEditMode || meObjectType == EditControl)
        {
            ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData
                (new ScAccessibleEditObjectTextData(mpEditView, mpWindow));
            ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));

            mpTextHelper = new accessibility::AccessibleTextHelper(pEditSource );
            mpTextHelper->SetEventSource(this);
        }
        else
        {
            ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData
                (new ScAccessibleEditLineTextData(NULL, mpWindow));
            ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));

            mpTextHelper = new accessibility::AccessibleTextHelper(pEditSource );
            mpTextHelper->SetEventSource(this);
        }
        mpTextHelper->SetFocus(mbHasFocus);
    }
}

<commit_msg>INTEGRATION: CWS uaa02 (1.10.132); FILE MERGED 2003/04/22 08:14:50 mt 1.10.132.1: #108656# Moved Accessibility from drafts to final<commit_after>/*************************************************************************
 *
 *  $RCSfile: AccessibleEditObject.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-24 17:11:35 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SC_ACCESSIBLEEDITOBJECT_HXX
#include "AccessibleEditObject.hxx"
#endif

#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#include <svx/eeitem.hxx>
#define ITEMID_FIELD EE_FEATURE_FIELD
#ifndef SC_UNOGUARD_HXX
#include "unoguard.hxx"
#endif

#ifndef _SC_ACCESSIBLETEXT_HXX
#include "AccessibleText.hxx"
#endif
#ifndef SC_EDITSRC_HXX
#include "editsrc.hxx"
#endif

#ifndef _UTL_ACCESSIBLESTATESETHELPER_HXX
#include <unotools/accessiblestatesethelper.hxx>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SVX_ACCESSILE_TEXT_HELPER_HXX_
#include <svx/AccessibleTextHelper.hxx>
#endif
#ifndef _MyEDITVIEW_HXX
#include <svx/editview.hxx>
#endif
#ifndef _MyEDITENG_HXX
#include <svx/editeng.hxx>
#endif

using namespace ::com::sun::star;
using namespace ::com::sun::star::accessibility;

//=====  internal  ============================================================

ScAccessibleEditObject::ScAccessibleEditObject(
        const uno::Reference<XAccessible>& rxParent,
        EditView* pEditView, Window* pWin, const rtl::OUString& rName,
        const rtl::OUString& rDescription, EditObjectType eObjectType)
    :
    ScAccessibleContextBase(rxParent, AccessibleRole::PANEL),
    mpTextHelper(NULL),
    mpEditView(pEditView),
    mpWindow(pWin),
    meObjectType(eObjectType),
    mbHasFocus(sal_False)
{
    CreateTextHelper();
    SetName(rName);
    SetDescription(rDescription);
}

ScAccessibleEditObject::~ScAccessibleEditObject()
{
    if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
    {
        // increment refcount to prevent double call off dtor
        osl_incrementInterlockedCount( &m_refCount );
        // call dispose to inform object wich have a weak reference to this object
        dispose();
    }
}

void SAL_CALL ScAccessibleEditObject::disposing()
{
    ScUnoGuard aGuard;
    if (mpTextHelper)
        DELETEZ(mpTextHelper);

    ScAccessibleContextBase::disposing();
}

void ScAccessibleEditObject::LostFocus()
{
    if (mpTextHelper)
        mpTextHelper->SetFocus(sal_False);
    mbHasFocus = sal_False;
}

void ScAccessibleEditObject::GotFocus()
{
    if (mpTextHelper)
        mpTextHelper->SetFocus(sal_True);
    mbHasFocus = sal_True;
}

    //=====  XAccessibleComponent  ============================================

uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAtPoint(
        const awt::Point& rPoint )
        throw (uno::RuntimeException)
{
    uno::Reference<XAccessible> xRet;
    if (containsPoint(rPoint))
    {
         ScUnoGuard aGuard;
        IsObjectValid();

        if(!mpTextHelper)
            CreateTextHelper();

        xRet = mpTextHelper->GetAt(rPoint);
    }

    return xRet;
}

Rectangle ScAccessibleEditObject::GetBoundingBoxOnScreen(void) const
        throw (uno::RuntimeException)
{
    Rectangle aCellRect(GetBoundingBox());
    if (mpWindow)
    {
        Point aLoc;
        aCellRect.getLocation(aLoc);
        Rectangle aRect = mpWindow->GetWindowExtentsRelative(NULL);
        Point aLoc2;
        aRect.getLocation(aLoc2);
        aCellRect.setLocation(Point(aLoc.getX() + aLoc2.getX(), aLoc.getY() + aLoc2.getY()));
        //aCellRect.setX(aCellRect.getX() + aRect.getX());
        //aCellRect.setY(aCellRect.getY() + aRect.getY());
    }
    return aCellRect;
}

Rectangle ScAccessibleEditObject::GetBoundingBox(void) const
        throw (uno::RuntimeException)
{
    Rectangle aCellRect;
    if (meObjectType == CellInEditMode)
    {
        if (mpEditView && mpWindow && mpEditView->GetEditEngine())
        {
            MapMode aMapMode(mpEditView->GetEditEngine()->GetRefMapMode());

            aCellRect = mpWindow->LogicToPixel( mpEditView->GetOutputArea() , aMapMode );
        }
    }
    else
    {
        if (mpWindow)
        {
            aCellRect = mpWindow->GetWindowExtentsRelative(mpWindow->GetAccessibleParentWindow());
        }
    }
    return aCellRect;
}

    //=====  XAccessibleContext  ==============================================

sal_Int32 SAL_CALL
    ScAccessibleEditObject::getAccessibleChildCount(void)
                    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    if (!mpTextHelper)
        CreateTextHelper();
    return mpTextHelper->GetChildCount();
}

uno::Reference< XAccessible > SAL_CALL
    ScAccessibleEditObject::getAccessibleChild(sal_Int32 nIndex)
        throw (uno::RuntimeException,
        lang::IndexOutOfBoundsException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    if (!mpTextHelper)
        CreateTextHelper();
    return mpTextHelper->GetChild(nIndex);
}

uno::Reference<XAccessibleStateSet> SAL_CALL
    ScAccessibleEditObject::getAccessibleStateSet(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Reference<XAccessibleStateSet> xParentStates;
    if (getAccessibleParent().is())
    {
        uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
        xParentStates = xParentContext->getAccessibleStateSet();
    }
    utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
    if (IsDefunc(xParentStates))
        pStateSet->AddState(AccessibleStateType::DEFUNC);
    else
    {
        // all states are const, because this object exists only in one state
        pStateSet->AddState(AccessibleStateType::EDITABLE);
        pStateSet->AddState(AccessibleStateType::ENABLED);
        pStateSet->AddState(AccessibleStateType::MULTI_LINE);
        pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
        pStateSet->AddState(AccessibleStateType::SHOWING);
        pStateSet->AddState(AccessibleStateType::VISIBLE);
    }
    return pStateSet;
}

::rtl::OUString SAL_CALL
    ScAccessibleEditObject::createAccessibleDescription(void)
    throw (uno::RuntimeException)
{
//    DBG_ERRORFILE("Should never be called, because is set in the constructor.")
    return rtl::OUString();
}

::rtl::OUString SAL_CALL
    ScAccessibleEditObject::createAccessibleName(void)
    throw (uno::RuntimeException)
{
    DBG_ERRORFILE("Should never be called, because is set in the constructor.");
    return rtl::OUString();
}

    ///=====  XAccessibleEventBroadcaster  =====================================

void SAL_CALL
    ScAccessibleEditObject::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
        throw (uno::RuntimeException)
{
    if (!mpTextHelper)
        CreateTextHelper();

    mpTextHelper->AddEventListener(xListener);

    ScAccessibleContextBase::addEventListener(xListener);
}

void SAL_CALL
    ScAccessibleEditObject::removeEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
        throw (uno::RuntimeException)
{
    if (!mpTextHelper)
        CreateTextHelper();

    mpTextHelper->RemoveEventListener(xListener);

    ScAccessibleContextBase::removeEventListener(xListener);
}

    //=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL ScAccessibleEditObject::getImplementationName(void)
        throw (uno::RuntimeException)
{
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleEditObject"));
}

//=====  XTypeProvider  =======================================================

uno::Sequence<sal_Int8> SAL_CALL
    ScAccessibleEditObject::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    static uno::Sequence<sal_Int8> aId;
    if (aId.getLength() == 0)
    {
        aId.realloc (16);
        rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
    }
    return aId;
}

    //====  internal  =========================================================

sal_Bool ScAccessibleEditObject::IsDefunc(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
}

void ScAccessibleEditObject::CreateTextHelper()
{
    if (!mpTextHelper)
    {
        if (meObjectType == CellInEditMode || meObjectType == EditControl)
        {
            ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData
                (new ScAccessibleEditObjectTextData(mpEditView, mpWindow));
            ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));

            mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
            mpTextHelper->SetEventSource(this);
        }
        else
        {
            ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData
                (new ScAccessibleEditLineTextData(NULL, mpWindow));
            ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));

            mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
            mpTextHelper->SetEventSource(this);
        }
        mpTextHelper->SetFocus(mbHasFocus);
    }
}

<|endoftext|>


<commit_before>/*
 * TTBlue (Linked) List Class
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTList.h"
#include "TTObject.h"
#include "TTEnvironment.h"

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

TTList::TTList()
	:mThreadProtection(YES)
{
	mMutex = new TTMutex(false);
}

TTList::~TTList()
{
	delete mMutex;
}

TTList::TTList(TTList& that) :
	mThreadProtection(YES)
{
	mMutex = new TTMutex(false);

	theList = that.theList;
}

TTUInt32 TTList::getSize()
{
	return theList.size();
}

TTValue& TTList::getHead()
{
	return theList.front();
}

TTValue& TTList::getTail()
{
	return theList.back();
}

void TTList::begin()
{
	theIter = theList.begin();
}

bool TTList::end()
{
	return theIter != theList.end();
}

void TTList::next()
{
	theIter++;
}

void TTList::prev()
{
	theIter--;
}

TTValue& TTList::current()
{
	return *theIter;
}

TTBoolean TTList::isEmpty()
{
	return theList.empty();
}

TTErr TTList::getIndex(TTUInt32 index, TTValue& returnedValue)
{
	TTErr		err = kTTErrValueNotFound;
	TTUInt32	i=0;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		if (i==index) {
			err = kTTErrNone;
			returnedValue = *iter;
			break;
		}
		i++;
	}
	unlock();

	return err;
}

void TTList::append(const TTValue& newValue)
{
	lock();
//	theList.insert(theList.end(), (TTValue*)&newValue);
	theList.insert(theList.end(), newValue);
	unlock();
}

void TTList::appendUnique(const TTValue& newValue)
{
	TTErr	err;
	TTValue	foundValue;

	err = findEquals(newValue, foundValue);
	if (err == kTTErrValueNotFound)
		append(newValue);
}

void TTList::insert(TTUInt32 index, const TTValue& newValue)
{
	TTListIter	iter;
	TTUInt32	i=0;

	lock();
	for (iter = theList.begin(); iter != theList.end(); ++iter) {
		if (i==index) {
			break;
		}
		i++;
	}

	theList.insert(iter, newValue);
	unlock();
}

void TTList::merge(TTList& newList)
{
	lock();
	theList.merge(newList.theList);
	unlock();
}

void TTList::sort(TTBoolean(comparisonFunction)(TTValue&, TTValue&))
{
	lock();

	// If a comparison fonction is given : use it
	if (comparisonFunction)
		theList.sort(comparisonFunction);

	// else use the < operator of TTValue to sort the list
	else
		theList.sort();
	unlock();
}

TTErr TTList::find(TTFunctionMatch aMatchFunction, TTPtr aBaton, TTValue& returnedValue)
{
	TTErr		err = kTTErrGeneric;
	TTBoolean	found = NO;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		TTValue& v = *iter;

		aMatchFunction(v, aBaton, found);
		if (found) {
			returnedValue = v;
			err = kTTErrNone;
			break;
		}
	}
	unlock();
	return err;
}

TTErr TTList::findEquals(const TTValue& valueToCompareAgainst, TTValue& foundValue)
{
	TTErr err = kTTErrValueNotFound;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		if ((*iter) == valueToCompareAgainst) {
			foundValue = *iter;
			err = kTTErrNone;
			break;
		}
	}
	unlock();

	return err;
}

void TTList::remove(const TTValue& aValue)
{
	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		TTValue v = *iter;

		if (v == aValue) {
			theList.remove(v);
			break;
		}
	}
	unlock();
}

void TTList::clear()
{
	lock();
	theList.clear();
	unlock();
}

void TTList::free()
{
//	lock();

// TTValue takes care of memory management of member objects now, so we don't have to worry about it.
//	for (TTListIter iter = theList.begin(); iter != theList.end(); iter++) {
//		TTValue& v = *iter;
//		if (v[0].type() == kTypeObject) {
// TTValue
//			TTObjectBasePtr o = NULL;
//			v.get(0, &o);
//			o = v;
//			TTObjectBaseRelease(&o);
//		}
//		delete *iter;
//	}
//	theList.clear();
//	unlock();
	clear();
}

void TTList::assignToValue(TTValue& value)
{
	TTListIter	iter;

	value.clear();

	lock();
	for (iter = theList.begin(); iter != theList.end(); ++iter) {
		value.append(*iter);
	}
	unlock();
}

TTErr TTList::iterate(const TTObjectBasePtr target, const TTFunctionWithBatonAndValue callback)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		callback(target, *iter);
	}
	unlock();
	return kTTErrNone;
}

TTErr TTList::iterate(const TTObjectBasePtr target, const TTSymbol messageName)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		TTValue v;
		target->sendMessage(messageName, *iter, v);
	}
	unlock();
	return kTTErrNone;
}

TTErr TTList::iterateObjectsSendingMessage(const TTSymbol messageName)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
#ifdef OLD
		TTObjectBasePtr obj = NULL;

		//(iter)->get(0, &obj);
		obj = iter->at(0);
		if (obj && obj->valid)
			obj->sendMessage(messageName);
#else // NEW
		TTObject o = iter->at(0);

		if (o.valid())
			o.send(messageName);
#endif
	}
	unlock();
	return kTTErrNone;
}

TTErr TTList::iterateObjectsSendingMessage(const TTSymbol messageName, TTValue& aValue)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
#ifdef OLD
		TTObjectBasePtr obj = NULL;

		//(iter)->get(0, &obj);
		obj = iter->at(0);
		if (obj && obj->valid) {
			TTValue v;
			obj->sendMessage(messageName, aValue, v);
		}
#else // NEW
		TTObject	o = iter->at(0);
		TTValue		unusedReturnValue;

		if (o.valid())
			o.send(messageName, aValue, unusedReturnValue);
#endif
	}
	unlock();
	return kTTErrNone;
}

void TTList::lock()
{
	if (mThreadProtection)
		mMutex->lock();
}

void TTList::unlock()
{
	if (mThreadProtection)
		mMutex->unlock();
}

<commit_msg>sort lists before merge them, OVERVIEW.maxpat totally work on windows<commit_after>/*
 * TTBlue (Linked) List Class
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTList.h"
#include "TTObject.h"
#include "TTEnvironment.h"

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

TTList::TTList()
	:mThreadProtection(YES)
{
	mMutex = new TTMutex(false);
}

TTList::~TTList()
{
	delete mMutex;
}

TTList::TTList(TTList& that) :
	mThreadProtection(YES)
{
	mMutex = new TTMutex(false);

	theList = that.theList;
}

TTUInt32 TTList::getSize()
{
	return theList.size();
}

TTValue& TTList::getHead()
{
	return theList.front();
}

TTValue& TTList::getTail()
{
	return theList.back();
}

void TTList::begin()
{
	theIter = theList.begin();
}

bool TTList::end()
{
	return theIter != theList.end();
}

void TTList::next()
{
	theIter++;
}

void TTList::prev()
{
	theIter--;
}

TTValue& TTList::current()
{
	return *theIter;
}

TTBoolean TTList::isEmpty()
{
	return theList.empty();
}

TTErr TTList::getIndex(TTUInt32 index, TTValue& returnedValue)
{
	TTErr		err = kTTErrValueNotFound;
	TTUInt32	i=0;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		if (i==index) {
			err = kTTErrNone;
			returnedValue = *iter;
			break;
		}
		i++;
	}
	unlock();

	return err;
}

void TTList::append(const TTValue& newValue)
{
	lock();
//	theList.insert(theList.end(), (TTValue*)&newValue);
	theList.insert(theList.end(), newValue);
	unlock();
}

void TTList::appendUnique(const TTValue& newValue)
{
	TTErr	err;
	TTValue	foundValue;

	err = findEquals(newValue, foundValue);
	if (err == kTTErrValueNotFound)
		append(newValue);
}

void TTList::insert(TTUInt32 index, const TTValue& newValue)
{
	TTListIter	iter;
	TTUInt32	i=0;

	lock();
	for (iter = theList.begin(); iter != theList.end(); ++iter) {
		if (i==index) {
			break;
		}
		i++;
	}

	theList.insert(iter, newValue);
	unlock();
}

void TTList::merge(TTList& newList)
{
	lock();
	theList.sort();
	newList.theList.sort();
	theList.merge(newList.theList);
	unlock();
}

void TTList::sort(TTBoolean(comparisonFunction)(TTValue&, TTValue&))
{
	lock();

	// If a comparison fonction is given : use it
	if (comparisonFunction)
		theList.sort(comparisonFunction);

	// else use the < operator of TTValue to sort the list
	else
		theList.sort();
	unlock();
}

TTErr TTList::find(TTFunctionMatch aMatchFunction, TTPtr aBaton, TTValue& returnedValue)
{
	TTErr		err = kTTErrGeneric;
	TTBoolean	found = NO;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		TTValue& v = *iter;

		aMatchFunction(v, aBaton, found);
		if (found) {
			returnedValue = v;
			err = kTTErrNone;
			break;
		}
	}
	unlock();
	return err;
}

TTErr TTList::findEquals(const TTValue& valueToCompareAgainst, TTValue& foundValue)
{
	TTErr err = kTTErrValueNotFound;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		if ((*iter) == valueToCompareAgainst) {
			foundValue = *iter;
			err = kTTErrNone;
			break;
		}
	}
	unlock();

	return err;
}

void TTList::remove(const TTValue& aValue)
{
	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		TTValue v = *iter;

		if (v == aValue) {
			theList.remove(v);
			break;
		}
	}
	unlock();
}

void TTList::clear()
{
	lock();
	theList.clear();
	unlock();
}

void TTList::free()
{
//	lock();

// TTValue takes care of memory management of member objects now, so we don't have to worry about it.
//	for (TTListIter iter = theList.begin(); iter != theList.end(); iter++) {
//		TTValue& v = *iter;
//		if (v[0].type() == kTypeObject) {
// TTValue
//			TTObjectBasePtr o = NULL;
//			v.get(0, &o);
//			o = v;
//			TTObjectBaseRelease(&o);
//		}
//		delete *iter;
//	}
//	theList.clear();
//	unlock();
	clear();
}

void TTList::assignToValue(TTValue& value)
{
	TTListIter	iter;

	value.clear();

	lock();
	for (iter = theList.begin(); iter != theList.end(); ++iter) {
		value.append(*iter);
	}
	unlock();
}

TTErr TTList::iterate(const TTObjectBasePtr target, const TTFunctionWithBatonAndValue callback)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		callback(target, *iter);
	}
	unlock();
	return kTTErrNone;
}

TTErr TTList::iterate(const TTObjectBasePtr target, const TTSymbol messageName)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
		TTValue v;
		target->sendMessage(messageName, *iter, v);
	}
	unlock();
	return kTTErrNone;
}

TTErr TTList::iterateObjectsSendingMessage(const TTSymbol messageName)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
#ifdef OLD
		TTObjectBasePtr obj = NULL;

		//(iter)->get(0, &obj);
		obj = iter->at(0);
		if (obj && obj->valid)
			obj->sendMessage(messageName);
#else // NEW
		TTObject o = iter->at(0);

		if (o.valid())
			o.send(messageName);
#endif
	}
	unlock();
	return kTTErrNone;
}

TTErr TTList::iterateObjectsSendingMessage(const TTSymbol messageName, TTValue& aValue)
{
	if (theList.empty())
		return kTTErrNone;

	lock();
	for (TTListIter iter = theList.begin(); iter != theList.end(); ++iter) {
#ifdef OLD
		TTObjectBasePtr obj = NULL;

		//(iter)->get(0, &obj);
		obj = iter->at(0);
		if (obj && obj->valid) {
			TTValue v;
			obj->sendMessage(messageName, aValue, v);
		}
#else // NEW
		TTObject	o = iter->at(0);
		TTValue		unusedReturnValue;

		if (o.valid())
			o.send(messageName, aValue, unusedReturnValue);
#endif
	}
	unlock();
	return kTTErrNone;
}

void TTList::lock()
{
	if (mThreadProtection)
		mMutex->lock();
}

void TTList::unlock()
{
	if (mThreadProtection)
		mMutex->unlock();
}

<|endoftext|>


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

#include "modules/perception/obstacle/onboard/lidar_process.h"

#include <string>

#include "Eigen/Core"
#include "eigen_conversions/eigen_msg.h"
#include "pcl_conversions/pcl_conversions.h"
#include "ros/include/ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "tf/transform_broadcaster.h"
#include "tf/transform_listener.h"
#include "tf_conversions/tf_eigen.h"

#include "modules/common/log.h"
#include "modules/perception/common/perception_gflags.h"
#include "modules/perception/lib/base/timer.h"
#include "modules/perception/lib/config_manager/config_manager.h"
#include "modules/perception/obstacle/lidar/dummy/dummy_algorithms.h"
#include "modules/perception/obstacle/lidar/object_builder/min_box/min_box.h"
#include "modules/perception/obstacle/lidar/roi_filter/hdmap_roi_filter/hdmap_roi_filter.h"
#include "modules/perception/obstacle/lidar/segmentation/cnnseg/cnn_segmentation.h"
#include "modules/perception/obstacle/lidar/tracker/hm_tracker/hm_tracker.h"

namespace apollo {
namespace perception {

using pcl_util::Point;
using pcl_util::PointD;
using pcl_util::PointCloud;
using pcl_util::PointCloudPtr;
using pcl_util::PointIndices;
using pcl_util::PointIndicesPtr;
using Eigen::Matrix4d;
using Eigen::Affine3d;
using std::string;

bool LidarProcess::Init() {
  if (inited_) {
    return true;
  }

  RegistAllAlgorithm();

  if (!InitFrameDependence()) {
    AERROR << "failed to init frame dependence.";
    return false;
  }

  if (!InitAlgorithmPlugin()) {
    AERROR << "failed to init algorithm plugin.";
    return false;
  }

  inited_ = true;
  return true;
}

bool LidarProcess::Process(const sensor_msgs::PointCloud2& message) {
  PERF_FUNCTION("LidarProcess");
  objects_.clear();
  const double kTimeStamp = message.header.stamp.toSec();
  timestamp_ = kTimeStamp;
  seq_num_++;

  AINFO << "process the " << seq_num_ << " frame. timestamp: " << timestamp_;

  PERF_BLOCK_START();
  /// get velodyne2world transfrom
  std::shared_ptr<Matrix4d> velodyne_trans = std::make_shared<Matrix4d>();
  if (!GetVelodyneTrans(kTimeStamp, velodyne_trans.get())) {
    AERROR << "failed to get trans at timestamp: " << kTimeStamp;
    error_code_ = apollo::common::PERCEPTION_ERROR_TF;
    return false;
  }
  ADEBUG << "get trans pose succ.";
  PERF_BLOCK_END("lidar_get_velodyne2world_transfrom");

  PointCloudPtr point_cloud(new PointCloud);
  TransPointCloudToPCL(message, &point_cloud);
  ADEBUG << "transform pointcloud success. points num is: "
         << point_cloud->points.size();
  PERF_BLOCK_END("lidar_transform_poindcloud");

  if (!Process(timestamp_, point_cloud, velodyne_trans)) {
    AERROR << "faile to process msg at timestamp: " << kTimeStamp;
    return false;
  }
  error_code_ = apollo::common::OK;
  return true;
}

bool LidarProcess::Process(double timestamp, PointCloudPtr point_cloud,
                           std::shared_ptr<Matrix4d> velodyne_trans) {
  PERF_BLOCK_START();
  /// call hdmap to get ROI
  HdmapStructPtr hdmap = nullptr;
  if (hdmap_input_) {
    PointD velodyne_pose = {0.0, 0.0, 0.0, 0};  // (0,0,0)
    Affine3d temp_trans(*velodyne_trans);
    PointD velodyne_pose_world = pcl::transformPoint(velodyne_pose, temp_trans);
    hdmap.reset(new HdmapStruct);
    hdmap_input_->GetROI(velodyne_pose_world, &hdmap);
    PERF_BLOCK_END("lidar_get_roi_from_hdmap");
  }

  /// call roi_filter
  PointCloudPtr roi_cloud(new PointCloud);
  if (roi_filter_ != nullptr) {
    PointIndicesPtr roi_indices(new PointIndices);
    ROIFilterOptions roi_filter_options;
    roi_filter_options.velodyne_trans = velodyne_trans;
    roi_filter_options.hdmap = hdmap;
    if (roi_filter_->Filter(point_cloud, roi_filter_options,
                            roi_indices.get())) {
      pcl::copyPointCloud(*point_cloud, *roi_indices, *roi_cloud);
      roi_indices_ = roi_indices;
    } else {
      AERROR << "failed to call roi filter.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }
  ADEBUG << "call roi_filter succ. The num of roi_cloud is: "
         << roi_cloud->points.size();
  PERF_BLOCK_END("lidar_roi_filter");

  /// call segmentor
  std::vector<ObjectPtr> objects;
  if (segmentor_ != nullptr) {
    SegmentationOptions segmentation_options;
    segmentation_options.origin_cloud = point_cloud;
    PointIndices non_ground_indices;
    // non_ground_indices.indices.resize(roi_cloud->points.size());
    non_ground_indices.indices.resize(point_cloud->points.size());

    std::iota(non_ground_indices.indices.begin(),
              non_ground_indices.indices.end(), 0);
    if (!segmentor_->Segment(point_cloud, non_ground_indices,
                             segmentation_options, &objects)) {
      AERROR << "failed to call segmention.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }
  AERROR << "call segmentation succ. The num of objects is: " << objects.size();
  PERF_BLOCK_END("lidar_segmentation");

  /// call object builder
  if (object_builder_ != nullptr) {
    ObjectBuilderOptions object_builder_options;
    if (!object_builder_->Build(object_builder_options, &objects)) {
      AERROR << "failed to call object builder.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }
  AERROR << "call object_builder succ.";
  PERF_BLOCK_END("lidar_object_builder");

  /// call tracker
  if (tracker_ != nullptr) {
    TrackerOptions tracker_options;
    tracker_options.velodyne_trans = velodyne_trans;
    tracker_options.hdmap = hdmap;
    if (!tracker_->Track(objects, timestamp, tracker_options, &objects_)) {
      AERROR << "failed to call tracker.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }

  if (visualizer_ != nullptr) {
      FrameContent content;
      content.set_lidar_pose(*velodyne_trans);
      content.set_lidar_cloud(point_cloud);
      content.set_tracked_objects(objects_);
      visualizer_->update_camera_system(&content);
      visualizer_->render(content);
  }

  PERF_BLOCK_END("lidar_tracker");
  AINFO << "lidar process succ, there are " << objects_.size()
        << " tracked objects.";
  return true;
}

void LidarProcess::RegistAllAlgorithm() {
  RegisterFactoryDummyROIFilter();
  RegisterFactoryDummySegmentation();
  RegisterFactoryDummyObjectBuilder();
  RegisterFactoryDummyTracker();

  RegisterFactoryHdmapROIFilter();
  RegisterFactoryCNNSegmentation();
  RegisterFactoryMinBoxObjectBuilder();
  RegisterFactoryHmObjectTracker();
}

bool LidarProcess::InitFrameDependence() {
  /// init config manager
  ConfigManager* config_manager = Singleton<ConfigManager>::Get();
  if (!config_manager) {
    AERROR << "failed to get ConfigManager instance.";
    return false;
  }
  if (!config_manager->Init()) {
    AERROR << "failed to init ConfigManager";
    return false;
  }
  AINFO << "Init config manager successfully, work_root: "
        << config_manager->work_root();

  /// init hdmap
  if (FLAGS_enable_hdmap_input) {
    hdmap_input_ = Singleton<HDMapInput>::Get();
    if (!hdmap_input_) {
      AERROR << "failed to get HDMapInput instance.";
      return false;
    }
    if (!hdmap_input_->Init()) {
      AERROR << "failed to init HDMapInput";
      return false;
    }

    AINFO << "get and init hdmap_input succ.";
  }

  if (FLAGS_enable_visualization) {
    visualizer_.reset(new OpenglVisualizer());
    if(!visualizer_->init()) {
      AERROR<<"init visialuzer failed";
      return false;
    };
  }
  return true;
}

bool LidarProcess::InitAlgorithmPlugin() {
  /// init roi filter
  roi_filter_.reset(
      BaseROIFilterRegisterer::GetInstanceByName(FLAGS_onboard_roi_filter));
  if (!roi_filter_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_roi_filter;
    return false;
  }
  if (!roi_filter_->Init()) {
    AERROR << "Failed to init roi filter: " << roi_filter_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, roi_filter_: "
        << roi_filter_->name();

  /// init segmentation
  segmentor_.reset(
      BaseSegmentationRegisterer::GetInstanceByName(FLAGS_onboard_segmentor));
  if (!segmentor_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_segmentor;
    return false;
  }
  if (!segmentor_->Init()) {
    AERROR << "Failed to init segmentor: " << segmentor_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, segmentor: "
        << segmentor_->name();

  /// init object build
  object_builder_.reset(BaseObjectBuilderRegisterer::GetInstanceByName(
      FLAGS_onboard_object_builder));
  if (!object_builder_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_object_builder;
    return false;
  }
  if (!object_builder_->Init()) {
    AERROR << "Failed to init object builder: " << object_builder_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, object builder: "
        << object_builder_->name();

  /// init tracker
  tracker_.reset(
      BaseTrackerRegisterer::GetInstanceByName(FLAGS_onboard_tracker));
  if (!tracker_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_tracker;
    return false;
  }
  if (!tracker_->Init()) {
    AERROR << "Failed to init tracker: " << tracker_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, tracker: " << tracker_->name();

  return true;
}

void LidarProcess::TransPointCloudToPCL(const sensor_msgs::PointCloud2& in_msg,
                                        PointCloudPtr* out_cloud) {
  // transform from ros to pcl
  pcl::PointCloud<pcl_util::PointXYZIT> in_cloud;
  pcl::fromROSMsg(in_msg, in_cloud);
  // transform from xyzit to xyzi
  PointCloudPtr& cloud = *out_cloud;
  cloud->header = in_cloud.header;
  cloud->width = in_cloud.width;
  cloud->height = in_cloud.height;
  cloud->is_dense = in_cloud.is_dense;
  cloud->sensor_origin_ = in_cloud.sensor_origin_;
  cloud->sensor_orientation_ = in_cloud.sensor_orientation_;
  cloud->points.resize(in_cloud.points.size());
  for (size_t idx = 0; idx < in_cloud.size(); ++idx) {
    cloud->points[idx].x = in_cloud.points[idx].x;
    cloud->points[idx].y = in_cloud.points[idx].y;
    cloud->points[idx].z = in_cloud.points[idx].z;
    cloud->points[idx].intensity = in_cloud.points[idx].intensity;
  }
}

bool LidarProcess::GetVelodyneTrans(const double query_time, Matrix4d* trans) {
  if (!trans) {
    AERROR << "failed to get trans, the trans ptr can not be NULL";
    return false;
  }

  ros::Time query_stamp(query_time);
  static tf2_ros::Buffer tf2_buffer;
  static tf2_ros::TransformListener tf2Listener(tf2_buffer);

  const double kTf2BuffSize = FLAGS_tf2_buff_in_ms / 1000.0;
  string err_msg;
  if (!tf2_buffer.canTransform(FLAGS_lidar_tf2_frame_id,
                               FLAGS_lidar_tf2_child_frame_id, query_stamp,
                               ros::Duration(kTf2BuffSize), &err_msg)) {
    AERROR << "Cannot transform frame: " << FLAGS_lidar_tf2_frame_id
           << " to frame " << FLAGS_lidar_tf2_child_frame_id
           << " , err: " << err_msg
           << ". Frames: " << tf2_buffer.allFramesAsString();
    return false;
  }

  geometry_msgs::TransformStamped transform_stamped;
  try {
    transform_stamped = tf2_buffer.lookupTransform(
        FLAGS_lidar_tf2_frame_id, FLAGS_lidar_tf2_child_frame_id, query_stamp);
  } catch (tf2::TransformException& ex) {
    AERROR << "Exception: " << ex.what();
    return false;
  }
  Affine3d affine_3d;
  tf::transformMsgToEigen(transform_stamped.transform, affine_3d);
  *trans = affine_3d.matrix();

  AINFO << "get " << FLAGS_lidar_tf2_frame_id << " to "
        << FLAGS_lidar_tf2_child_frame_id << " trans: " << *trans;
  return true;
}

bool LidarProcess::GeneratePbMsg(PerceptionObstacles* obstacles) {
  // double publish_time = ros::Time::now().toSec();
  double publish_time = timestamp_;
  try {
    publish_time = ros::Time::now().toSec();
  } catch (ros::Exception& ex) {
    AERROR << "Exception: " << ex.what();
  }
  apollo::common::Header* header = obstacles->mutable_header();
  header->set_timestamp_sec(publish_time);
  header->set_module_name(FLAGS_obstacle_module_name);
  header->set_sequence_num(seq_num_);
  header->set_lidar_timestamp(timestamp_ * 1e9);  // in ns
  header->set_camera_timestamp(0);
  header->set_radar_timestamp(0);

  obstacles->set_error_code(error_code_);

  for (const auto& obj : objects_) {
    PerceptionObstacle* obstacle = obstacles->add_perception_obstacle();
    if (!obj->Serialize(obstacle)) {
      AERROR << "Failed gen PerceptionObstacle. Object:" << obj->ToString();
      return false;
    }
    obstacle->set_timestamp(obstacle->timestamp() * 1000);
  }

  ADEBUG << "PerceptionObstacles: " << obstacles->ShortDebugString();
  return true;
}

}  // namespace perception
}  // namespace apollo
<commit_msg>fix compile bugs (#745)<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/onboard/lidar_process.h"

#include <string>

#include "Eigen/Core"
#include "eigen_conversions/eigen_msg.h"
#include "pcl_conversions/pcl_conversions.h"
#include "ros/include/ros/ros.h"
#include "sensor_msgs/PointCloud2.h"
#include "tf/transform_broadcaster.h"
#include "tf/transform_listener.h"
#include "tf_conversions/tf_eigen.h"

#include "modules/common/log.h"
#include "modules/perception/common/perception_gflags.h"
#include "modules/perception/lib/base/timer.h"
#include "modules/perception/lib/config_manager/config_manager.h"
#include "modules/perception/obstacle/lidar/dummy/dummy_algorithms.h"
#include "modules/perception/obstacle/lidar/object_builder/min_box/min_box.h"
#include "modules/perception/obstacle/lidar/roi_filter/hdmap_roi_filter/hdmap_roi_filter.h"
#include "modules/perception/obstacle/lidar/segmentation/cnnseg/cnn_segmentation.h"
#include "modules/perception/obstacle/lidar/tracker/hm_tracker/hm_tracker.h"

namespace apollo {
namespace perception {

using pcl_util::Point;
using pcl_util::PointD;
using pcl_util::PointCloud;
using pcl_util::PointCloudPtr;
using pcl_util::PointIndices;
using pcl_util::PointIndicesPtr;
using Eigen::Matrix4d;
using Eigen::Affine3d;
using std::string;

bool LidarProcess::Init() {
  if (inited_) {
    return true;
  }

  RegistAllAlgorithm();

  if (!InitFrameDependence()) {
    AERROR << "failed to init frame dependence.";
    return false;
  }

  if (!InitAlgorithmPlugin()) {
    AERROR << "failed to init algorithm plugin.";
    return false;
  }

  inited_ = true;
  return true;
}

bool LidarProcess::Process(const sensor_msgs::PointCloud2& message) {
  PERF_FUNCTION("LidarProcess");
  objects_.clear();
  const double kTimeStamp = message.header.stamp.toSec();
  timestamp_ = kTimeStamp;
  seq_num_++;

  AINFO << "process the " << seq_num_ << " frame. timestamp: " << timestamp_;

  PERF_BLOCK_START();
  /// get velodyne2world transfrom
  std::shared_ptr<Matrix4d> velodyne_trans = std::make_shared<Matrix4d>();
  if (!GetVelodyneTrans(kTimeStamp, velodyne_trans.get())) {
    AERROR << "failed to get trans at timestamp: " << kTimeStamp;
    error_code_ = apollo::common::PERCEPTION_ERROR_TF;
    return false;
  }
  ADEBUG << "get trans pose succ.";
  PERF_BLOCK_END("lidar_get_velodyne2world_transfrom");

  PointCloudPtr point_cloud(new PointCloud);
  TransPointCloudToPCL(message, &point_cloud);
  ADEBUG << "transform pointcloud success. points num is: "
         << point_cloud->points.size();
  PERF_BLOCK_END("lidar_transform_poindcloud");

  if (!Process(timestamp_, point_cloud, velodyne_trans)) {
    AERROR << "faile to process msg at timestamp: " << kTimeStamp;
    return false;
  }
  error_code_ = apollo::common::OK;
  return true;
}

bool LidarProcess::Process(double timestamp, PointCloudPtr point_cloud,
                           std::shared_ptr<Matrix4d> velodyne_trans) {
  PERF_BLOCK_START();
  /// call hdmap to get ROI
  HdmapStructPtr hdmap = nullptr;
  if (hdmap_input_) {
    PointD velodyne_pose = {0.0, 0.0, 0.0, 0};  // (0,0,0)
    Affine3d temp_trans(*velodyne_trans);
    PointD velodyne_pose_world = pcl::transformPoint(velodyne_pose, temp_trans);
    hdmap.reset(new HdmapStruct);
    hdmap_input_->GetROI(velodyne_pose_world, &hdmap);
    PERF_BLOCK_END("lidar_get_roi_from_hdmap");
  }

  /// call roi_filter
  PointCloudPtr roi_cloud(new PointCloud);
  if (roi_filter_ != nullptr) {
    PointIndicesPtr roi_indices(new PointIndices);
    ROIFilterOptions roi_filter_options;
    roi_filter_options.velodyne_trans = velodyne_trans;
    roi_filter_options.hdmap = hdmap;
    if (roi_filter_->Filter(point_cloud, roi_filter_options,
                            roi_indices.get())) {
      pcl::copyPointCloud(*point_cloud, *roi_indices, *roi_cloud);
      roi_indices_ = roi_indices;
    } else {
      AERROR << "failed to call roi filter.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }
  ADEBUG << "call roi_filter succ. The num of roi_cloud is: "
         << roi_cloud->points.size();
  PERF_BLOCK_END("lidar_roi_filter");

  /// call segmentor
  std::vector<ObjectPtr> objects;
  if (segmentor_ != nullptr) {
    SegmentationOptions segmentation_options;
    segmentation_options.origin_cloud = point_cloud;
    PointIndices non_ground_indices;
    // non_ground_indices.indices.resize(roi_cloud->points.size());
    non_ground_indices.indices.resize(point_cloud->points.size());

    std::iota(non_ground_indices.indices.begin(),
              non_ground_indices.indices.end(), 0);
    if (!segmentor_->Segment(point_cloud, non_ground_indices,
                             segmentation_options, &objects)) {
      AERROR << "failed to call segmention.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }
  AERROR << "call segmentation succ. The num of objects is: " << objects.size();
  PERF_BLOCK_END("lidar_segmentation");

  /// call object builder
  if (object_builder_ != nullptr) {
    ObjectBuilderOptions object_builder_options;
    if (!object_builder_->Build(object_builder_options, &objects)) {
      AERROR << "failed to call object builder.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }
  AERROR << "call object_builder succ.";
  PERF_BLOCK_END("lidar_object_builder");

  /// call tracker
  if (tracker_ != nullptr) {
    TrackerOptions tracker_options;
    tracker_options.velodyne_trans = velodyne_trans;
    tracker_options.hdmap = hdmap;
    if (!tracker_->Track(objects, timestamp, tracker_options, &objects_)) {
      AERROR << "failed to call tracker.";
      error_code_ = apollo::common::PERCEPTION_ERROR_PROCESS;
      return false;
    }
  }

  if (visualizer_ != nullptr) {
      FrameContent content;
      content.set_lidar_pose(*velodyne_trans);
      content.set_lidar_cloud(point_cloud);
      content.set_tracked_objects(objects_);
      visualizer_->UpdateCameraSystem(&content);
      visualizer_->Render(content);
  }

  PERF_BLOCK_END("lidar_tracker");
  AINFO << "lidar process succ, there are " << objects_.size()
        << " tracked objects.";
  return true;
}

void LidarProcess::RegistAllAlgorithm() {
  RegisterFactoryDummyROIFilter();
  RegisterFactoryDummySegmentation();
  RegisterFactoryDummyObjectBuilder();
  RegisterFactoryDummyTracker();

  RegisterFactoryHdmapROIFilter();
  RegisterFactoryCNNSegmentation();
  RegisterFactoryMinBoxObjectBuilder();
  RegisterFactoryHmObjectTracker();
}

bool LidarProcess::InitFrameDependence() {
  /// init config manager
  ConfigManager* config_manager = Singleton<ConfigManager>::Get();
  if (!config_manager) {
    AERROR << "failed to get ConfigManager instance.";
    return false;
  }
  if (!config_manager->Init()) {
    AERROR << "failed to init ConfigManager";
    return false;
  }
  AINFO << "Init config manager successfully, work_root: "
        << config_manager->work_root();

  /// init hdmap
  if (FLAGS_enable_hdmap_input) {
    hdmap_input_ = Singleton<HDMapInput>::Get();
    if (!hdmap_input_) {
      AERROR << "failed to get HDMapInput instance.";
      return false;
    }
    if (!hdmap_input_->Init()) {
      AERROR << "failed to init HDMapInput";
      return false;
    }

    AINFO << "get and init hdmap_input succ.";
  }

  if (FLAGS_enable_visualization) {
    visualizer_.reset(new OpenglVisualizer());
    if(!visualizer_->Init()) {
      AERROR<<"init visialuzer failed";
      return false;
    };
  }
  return true;
}

bool LidarProcess::InitAlgorithmPlugin() {
  /// init roi filter
  roi_filter_.reset(
      BaseROIFilterRegisterer::GetInstanceByName(FLAGS_onboard_roi_filter));
  if (!roi_filter_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_roi_filter;
    return false;
  }
  if (!roi_filter_->Init()) {
    AERROR << "Failed to init roi filter: " << roi_filter_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, roi_filter_: "
        << roi_filter_->name();

  /// init segmentation
  segmentor_.reset(
      BaseSegmentationRegisterer::GetInstanceByName(FLAGS_onboard_segmentor));
  if (!segmentor_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_segmentor;
    return false;
  }
  if (!segmentor_->Init()) {
    AERROR << "Failed to init segmentor: " << segmentor_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, segmentor: "
        << segmentor_->name();

  /// init object build
  object_builder_.reset(BaseObjectBuilderRegisterer::GetInstanceByName(
      FLAGS_onboard_object_builder));
  if (!object_builder_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_object_builder;
    return false;
  }
  if (!object_builder_->Init()) {
    AERROR << "Failed to init object builder: " << object_builder_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, object builder: "
        << object_builder_->name();

  /// init tracker
  tracker_.reset(
      BaseTrackerRegisterer::GetInstanceByName(FLAGS_onboard_tracker));
  if (!tracker_) {
    AERROR << "Failed to get instance: " << FLAGS_onboard_tracker;
    return false;
  }
  if (!tracker_->Init()) {
    AERROR << "Failed to init tracker: " << tracker_->name();
    return false;
  }
  AINFO << "Init algorithm plugin successfully, tracker: " << tracker_->name();

  return true;
}

void LidarProcess::TransPointCloudToPCL(const sensor_msgs::PointCloud2& in_msg,
                                        PointCloudPtr* out_cloud) {
  // transform from ros to pcl
  pcl::PointCloud<pcl_util::PointXYZIT> in_cloud;
  pcl::fromROSMsg(in_msg, in_cloud);
  // transform from xyzit to xyzi
  PointCloudPtr& cloud = *out_cloud;
  cloud->header = in_cloud.header;
  cloud->width = in_cloud.width;
  cloud->height = in_cloud.height;
  cloud->is_dense = in_cloud.is_dense;
  cloud->sensor_origin_ = in_cloud.sensor_origin_;
  cloud->sensor_orientation_ = in_cloud.sensor_orientation_;
  cloud->points.resize(in_cloud.points.size());
  for (size_t idx = 0; idx < in_cloud.size(); ++idx) {
    cloud->points[idx].x = in_cloud.points[idx].x;
    cloud->points[idx].y = in_cloud.points[idx].y;
    cloud->points[idx].z = in_cloud.points[idx].z;
    cloud->points[idx].intensity = in_cloud.points[idx].intensity;
  }
}

bool LidarProcess::GetVelodyneTrans(const double query_time, Matrix4d* trans) {
  if (!trans) {
    AERROR << "failed to get trans, the trans ptr can not be NULL";
    return false;
  }

  ros::Time query_stamp(query_time);
  static tf2_ros::Buffer tf2_buffer;
  static tf2_ros::TransformListener tf2Listener(tf2_buffer);

  const double kTf2BuffSize = FLAGS_tf2_buff_in_ms / 1000.0;
  string err_msg;
  if (!tf2_buffer.canTransform(FLAGS_lidar_tf2_frame_id,
                               FLAGS_lidar_tf2_child_frame_id, query_stamp,
                               ros::Duration(kTf2BuffSize), &err_msg)) {
    AERROR << "Cannot transform frame: " << FLAGS_lidar_tf2_frame_id
           << " to frame " << FLAGS_lidar_tf2_child_frame_id
           << " , err: " << err_msg
           << ". Frames: " << tf2_buffer.allFramesAsString();
    return false;
  }

  geometry_msgs::TransformStamped transform_stamped;
  try {
    transform_stamped = tf2_buffer.lookupTransform(
        FLAGS_lidar_tf2_frame_id, FLAGS_lidar_tf2_child_frame_id, query_stamp);
  } catch (tf2::TransformException& ex) {
    AERROR << "Exception: " << ex.what();
    return false;
  }
  Affine3d affine_3d;
  tf::transformMsgToEigen(transform_stamped.transform, affine_3d);
  *trans = affine_3d.matrix();

  AINFO << "get " << FLAGS_lidar_tf2_frame_id << " to "
        << FLAGS_lidar_tf2_child_frame_id << " trans: " << *trans;
  return true;
}

bool LidarProcess::GeneratePbMsg(PerceptionObstacles* obstacles) {
  // double publish_time = ros::Time::now().toSec();
  double publish_time = timestamp_;
  try {
    publish_time = ros::Time::now().toSec();
  } catch (ros::Exception& ex) {
    AERROR << "Exception: " << ex.what();
  }
  apollo::common::Header* header = obstacles->mutable_header();
  header->set_timestamp_sec(publish_time);
  header->set_module_name(FLAGS_obstacle_module_name);
  header->set_sequence_num(seq_num_);
  header->set_lidar_timestamp(timestamp_ * 1e9);  // in ns
  header->set_camera_timestamp(0);
  header->set_radar_timestamp(0);

  obstacles->set_error_code(error_code_);

  for (const auto& obj : objects_) {
    PerceptionObstacle* obstacle = obstacles->add_perception_obstacle();
    if (!obj->Serialize(obstacle)) {
      AERROR << "Failed gen PerceptionObstacle. Object:" << obj->ToString();
      return false;
    }
    obstacle->set_timestamp(obstacle->timestamp() * 1000);
  }

  ADEBUG << "PerceptionObstacles: " << obstacles->ShortDebugString();
  return true;
}

}  // namespace perception
}  // namespace apollo
<|endoftext|>