<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_implementation.h"

namespace gfx {
namespace {

// TODO(piman): it should be Desktop GL marshalling from double to float. Today
// on native GLES, we do float->double->float.
void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
  glClearDepthf(static_cast<GLclampf>(depth));
}

void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
                                                    GLclampd z_far) {
  glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
}

// Load a library, printing an error message on failure.
base::NativeLibrary LoadLibrary(const char* filename) {
  std::string error;
  base::NativeLibrary library = base::LoadNativeLibrary(FilePath(filename),
                                                        &error);
  if (!library) {
    VLOG(1) << "Failed to load " << filename << ": " << error;
    return NULL;
  }
  return library;
}

}  // namespace anonymous

bool InitializeGLBindings(GLImplementation implementation) {
  // Prevent reinitialization with a different implementation. Once the gpu
  // unit tests have initialized with kGLImplementationMock, we don't want to
  // later switch to another GL implementation.
  if (GetGLImplementation() != kGLImplementationNone)
    return true;

  switch (implementation) {
    case kGLImplementationOSMesaGL: {
      FilePath module_path;
      if (!PathService::Get(base::DIR_MODULE, &module_path)) {
        LOG(ERROR) << "PathService::Get failed.";
        return false;
      }

      base::NativeLibrary library = LoadLibrary("libosmesa.so");
      if (!library)
        return false;

      GLGetProcAddressProc get_proc_address =
          reinterpret_cast<GLGetProcAddressProc>(
              base::GetFunctionPointerFromNativeLibrary(
                  library, "OSMesaGetProcAddress"));
      if (!get_proc_address) {
        LOG(ERROR) << "OSMesaGetProcAddress not found.";
        base::UnloadNativeLibrary(library);
        return false;
      }

      SetGLGetProcAddressProc(get_proc_address);
      AddGLNativeLibrary(library);
      SetGLImplementation(kGLImplementationOSMesaGL);

      InitializeGLBindingsGL();
      InitializeGLBindingsOSMESA();
      break;
    }
    case kGLImplementationDesktopGL: {
      base::NativeLibrary library = LoadLibrary("libGL.so.1");
      if (!library)
        return false;

      GLGetProcAddressProc get_proc_address =
          reinterpret_cast<GLGetProcAddressProc>(
              base::GetFunctionPointerFromNativeLibrary(
                  library, "glXGetProcAddress"));
      if (!get_proc_address) {
        LOG(ERROR) << "glxGetProcAddress not found.";
        base::UnloadNativeLibrary(library);
        return false;
      }

      SetGLGetProcAddressProc(get_proc_address);
      AddGLNativeLibrary(library);
      SetGLImplementation(kGLImplementationDesktopGL);

      InitializeGLBindingsGL();
      InitializeGLBindingsGLX();
      break;
    }
    case kGLImplementationEGLGLES2: {
      base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so");
      if (!gles_library)
        return false;
      base::NativeLibrary egl_library = LoadLibrary("libEGL.so");
      if (!egl_library)
        return false;

      GLGetProcAddressProc get_proc_address =
          reinterpret_cast<GLGetProcAddressProc>(
              base::GetFunctionPointerFromNativeLibrary(
                  egl_library, "eglGetProcAddress"));
      if (!get_proc_address) {
        LOG(ERROR) << "eglGetProcAddress not found.";
        base::UnloadNativeLibrary(egl_library);
        base::UnloadNativeLibrary(gles_library);
        return false;
      }

      SetGLGetProcAddressProc(get_proc_address);
      AddGLNativeLibrary(egl_library);
      AddGLNativeLibrary(gles_library);
      SetGLImplementation(kGLImplementationEGLGLES2);

      InitializeGLBindingsGL();
      InitializeGLBindingsEGL();

      // These two functions take single precision float rather than double
      // precision float parameters in GLES.
      ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
      ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
      break;
    }
    case kGLImplementationMockGL: {
      SetGLGetProcAddressProc(GetMockGLProcAddress);
      SetGLImplementation(kGLImplementationMockGL);
      InitializeGLBindingsGL();
      break;
    }
    default:
      return false;
  }

  return true;
}

void InitializeDebugGLBindings() {
  InitializeDebugGLBindingsEGL();
  InitializeDebugGLBindingsGL();
  InitializeDebugGLBindingsGLX();
  InitializeDebugGLBindingsOSMESA();
}

}  // namespace gfx
<commit_msg>Fix osmesa lib path regression in Linux introduced in r82008.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "ui/gfx/gl/gl_bindings.h"
#include "ui/gfx/gl/gl_implementation.h"

namespace gfx {
namespace {

// TODO(piman): it should be Desktop GL marshalling from double to float. Today
// on native GLES, we do float->double->float.
void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
  glClearDepthf(static_cast<GLclampf>(depth));
}

void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
                                                    GLclampd z_far) {
  glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
}

// Load a library, printing an error message on failure.
base::NativeLibrary LoadLibrary(const FilePath& filename) {
  std::string error;
  base::NativeLibrary library = base::LoadNativeLibrary(filename,
                                                        &error);
  if (!library) {
    VLOG(1) << "Failed to load " << filename.MaybeAsASCII() << ": " << error;
    return NULL;
  }
  return library;
}

base::NativeLibrary LoadLibrary(const char* filename) {
  return LoadLibrary(FilePath(filename));
}

}  // namespace anonymous

bool InitializeGLBindings(GLImplementation implementation) {
  // Prevent reinitialization with a different implementation. Once the gpu
  // unit tests have initialized with kGLImplementationMock, we don't want to
  // later switch to another GL implementation.
  if (GetGLImplementation() != kGLImplementationNone)
    return true;

  switch (implementation) {
    case kGLImplementationOSMesaGL: {
      FilePath module_path;
      if (!PathService::Get(base::DIR_MODULE, &module_path)) {
        LOG(ERROR) << "PathService::Get failed.";
        return false;
      }

      base::NativeLibrary library = LoadLibrary(
          module_path.Append("libosmesa.so"));
      if (!library)
        return false;

      GLGetProcAddressProc get_proc_address =
          reinterpret_cast<GLGetProcAddressProc>(
              base::GetFunctionPointerFromNativeLibrary(
                  library, "OSMesaGetProcAddress"));
      if (!get_proc_address) {
        LOG(ERROR) << "OSMesaGetProcAddress not found.";
        base::UnloadNativeLibrary(library);
        return false;
      }

      SetGLGetProcAddressProc(get_proc_address);
      AddGLNativeLibrary(library);
      SetGLImplementation(kGLImplementationOSMesaGL);

      InitializeGLBindingsGL();
      InitializeGLBindingsOSMESA();
      break;
    }
    case kGLImplementationDesktopGL: {
      base::NativeLibrary library = LoadLibrary("libGL.so.1");
      if (!library)
        return false;

      GLGetProcAddressProc get_proc_address =
          reinterpret_cast<GLGetProcAddressProc>(
              base::GetFunctionPointerFromNativeLibrary(
                  library, "glXGetProcAddress"));
      if (!get_proc_address) {
        LOG(ERROR) << "glxGetProcAddress not found.";
        base::UnloadNativeLibrary(library);
        return false;
      }

      SetGLGetProcAddressProc(get_proc_address);
      AddGLNativeLibrary(library);
      SetGLImplementation(kGLImplementationDesktopGL);

      InitializeGLBindingsGL();
      InitializeGLBindingsGLX();
      break;
    }
    case kGLImplementationEGLGLES2: {
      base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so");
      if (!gles_library)
        return false;
      base::NativeLibrary egl_library = LoadLibrary("libEGL.so");
      if (!egl_library)
        return false;

      GLGetProcAddressProc get_proc_address =
          reinterpret_cast<GLGetProcAddressProc>(
              base::GetFunctionPointerFromNativeLibrary(
                  egl_library, "eglGetProcAddress"));
      if (!get_proc_address) {
        LOG(ERROR) << "eglGetProcAddress not found.";
        base::UnloadNativeLibrary(egl_library);
        base::UnloadNativeLibrary(gles_library);
        return false;
      }

      SetGLGetProcAddressProc(get_proc_address);
      AddGLNativeLibrary(egl_library);
      AddGLNativeLibrary(gles_library);
      SetGLImplementation(kGLImplementationEGLGLES2);

      InitializeGLBindingsGL();
      InitializeGLBindingsEGL();

      // These two functions take single precision float rather than double
      // precision float parameters in GLES.
      ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
      ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
      break;
    }
    case kGLImplementationMockGL: {
      SetGLGetProcAddressProc(GetMockGLProcAddress);
      SetGLImplementation(kGLImplementationMockGL);
      InitializeGLBindingsGL();
      break;
    }
    default:
      return false;
  }

  return true;
}

void InitializeDebugGLBindings() {
  InitializeDebugGLBindingsEGL();
  InitializeDebugGLBindingsGL();
  InitializeDebugGLBindingsGLX();
  InitializeDebugGLBindingsOSMESA();
}

}  // namespace gfx
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: intlwrapper.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2006-04-07 16:29:14 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#pragma hdrstop

#include "unotools/intlwrapper.hxx"

#ifndef _COM_SUN_STAR_I18N_COLLATOROPTIONS_HPP_
#include <com/sun/star/i18n/CollatorOptions.hpp>
#endif

#ifndef INCLUDED_I18NPOOL_MSLANGID_HXX
#include <i18npool/mslangid.hxx>
#endif

IntlWrapper::IntlWrapper(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
            const ::com::sun::star::lang::Locale& rLocale )
        :
        xSMgr( xSF ),
        aLocale( rLocale ),
        pCharClass( NULL ),
        pLocaleData( NULL ),
        pCalendar( NULL ),
        pCollator( NULL ),
        pCaseCollator( NULL )
{
    eLanguage = MsLangId::convertLocaleToLanguage( aLocale );
}

IntlWrapper::IntlWrapper(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
            LanguageType eLang )
        :
        xSMgr( xSF ),
        eLanguage( eLang ),
        pCharClass( NULL ),
        pLocaleData( NULL ),
        pCalendar( NULL ),
        pCollator( NULL ),
        pCaseCollator( NULL )
{
    MsLangId::convertLanguageToLocale( eLanguage, aLocale );
}

IntlWrapper::~IntlWrapper()
{
    delete pCharClass;
    delete pLocaleData;
    delete pCalendar;
    delete pCollator;
    delete pCaseCollator;
}

void IntlWrapper::ImplNewCharClass() const
{
    ((IntlWrapper*)this)->pCharClass = new CharClass( xSMgr, aLocale );
}

void IntlWrapper::ImplNewLocaleData() const
{
    ((IntlWrapper*)this)->pLocaleData = new LocaleDataWrapper( xSMgr, aLocale );
}

void IntlWrapper::ImplNewCalendar() const
{
    CalendarWrapper* p = new CalendarWrapper( xSMgr );
    p->loadDefaultCalendar( aLocale );
    ((IntlWrapper*)this)->pCalendar = p;
}

void IntlWrapper::ImplNewCollator( BOOL bCaseSensitive ) const
{
    CollatorWrapper* p = new CollatorWrapper( xSMgr );
    if ( bCaseSensitive )
    {
        p->loadDefaultCollator( aLocale, 0 );
        ((IntlWrapper*)this)->pCaseCollator = p;
    }
    else
    {
        p->loadDefaultCollator( aLocale, ::com::sun::star::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
        ((IntlWrapper*)this)->pCollator = p;
    }
}
<commit_msg>INTEGRATION: CWS warnings01 (1.3.16); FILE MERGED 2006/05/23 18:03:52 sb 1.3.16.2: RESYNC: (1.3-1.4); FILE MERGED 2005/10/21 09:48:56 dbo 1.3.16.1: #i53898# warning free code<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: intlwrapper.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 14:06:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#include "unotools/intlwrapper.hxx"

#ifndef _COM_SUN_STAR_I18N_COLLATOROPTIONS_HPP_
#include <com/sun/star/i18n/CollatorOptions.hpp>
#endif

#ifndef INCLUDED_I18NPOOL_MSLANGID_HXX
#include <i18npool/mslangid.hxx>
#endif

IntlWrapper::IntlWrapper(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
            const ::com::sun::star::lang::Locale& rLocale )
        :
        aLocale( rLocale ),
        xSMgr( xSF ),
        pCharClass( NULL ),
        pLocaleData( NULL ),
        pCalendar( NULL ),
        pCollator( NULL ),
        pCaseCollator( NULL )
{
    eLanguage = MsLangId::convertLocaleToLanguage( aLocale );
}

IntlWrapper::IntlWrapper(
            const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & xSF,
            LanguageType eLang )
        :
        xSMgr( xSF ),
        pCharClass( NULL ),
        pLocaleData( NULL ),
        pCalendar( NULL ),
        pCollator( NULL ),
        pCaseCollator( NULL ),
        eLanguage( eLang )
{
    MsLangId::convertLanguageToLocale( eLanguage, aLocale );
}

IntlWrapper::~IntlWrapper()
{
    delete pCharClass;
    delete pLocaleData;
    delete pCalendar;
    delete pCollator;
    delete pCaseCollator;
}

void IntlWrapper::ImplNewCharClass() const
{
    ((IntlWrapper*)this)->pCharClass = new CharClass( xSMgr, aLocale );
}

void IntlWrapper::ImplNewLocaleData() const
{
    ((IntlWrapper*)this)->pLocaleData = new LocaleDataWrapper( xSMgr, aLocale );
}

void IntlWrapper::ImplNewCalendar() const
{
    CalendarWrapper* p = new CalendarWrapper( xSMgr );
    p->loadDefaultCalendar( aLocale );
    ((IntlWrapper*)this)->pCalendar = p;
}

void IntlWrapper::ImplNewCollator( BOOL bCaseSensitive ) const
{
    CollatorWrapper* p = new CollatorWrapper( xSMgr );
    if ( bCaseSensitive )
    {
        p->loadDefaultCollator( aLocale, 0 );
        ((IntlWrapper*)this)->pCaseCollator = p;
    }
    else
    {
        p->loadDefaultCollator( aLocale, ::com::sun::star::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
        ((IntlWrapper*)this)->pCollator = p;
    }
}
<|endoftext|>


<commit_before>#ifndef FILES_HPP
#define FILES_HPP

#define NUMBER_OF_FILES 12

const char* src_file_names[NUMBER_OF_FILES] = {"/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/avatar.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/cameleon.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/frozen.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/giraffe.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/snow_leopard.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/tmnt_1.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/tmnt_2.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/transformers.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/tree_1.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/tree_2.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/tree_3.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/binary/zebra.bmp"};

const char* dst_file_names[NUMBER_OF_FILES] = {"/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/avatar.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/cameleon.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/frozen.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/giraffe.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/snow_leopard.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/tmnt_1.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/tmnt_2.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/transformers.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/tree_1.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/tree_2.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/tree_3.bmp",
                                               "/home/sahand/Documents/EPFL/Courses/Master/MA1/Program Parallelization on PC Clusters/Project/images/skeletonized/zebra.bmp"};

#endif
<commit_msg>modified file names to relative for them to work on lacalgpu2.<commit_after>#ifndef FILES_HPP
#define FILES_HPP

#define NUMBER_OF_FILES 12

const char* src_file_names[NUMBER_OF_FILES] = {"../../../../images/binary/avatar.bmp",
                                               "../../../../images/binary/cameleon.bmp",
                                               "../../../../images/binary/frozen.bmp",
                                               "../../../../images/binary/giraffe.bmp",
                                               "../../../../images/binary/snow_leopard.bmp",
                                               "../../../../images/binary/tmnt_1.bmp",
                                               "../../../../images/binary/tmnt_2.bmp",
                                               "../../../../images/binary/transformers.bmp",
                                               "../../../../images/binary/tree_1.bmp",
                                               "../../../../images/binary/tree_2.bmp",
                                               "../../../../images/binary/tree_3.bmp",
                                               "../../../../images/binary/zebra.bmp"};

const char* dst_file_names[NUMBER_OF_FILES] = {"../../../../images/skeletonized/avatar.bmp",
                                               "../../../../images/skeletonized/cameleon.bmp",
                                               "../../../../images/skeletonized/frozen.bmp",
                                               "../../../../images/skeletonized/giraffe.bmp",
                                               "../../../../images/skeletonized/snow_leopard.bmp",
                                               "../../../../images/skeletonized/tmnt_1.bmp",
                                               "../../../../images/skeletonized/tmnt_2.bmp",
                                               "../../../../images/skeletonized/transformers.bmp",
                                               "../../../../images/skeletonized/tree_1.bmp",
                                               "../../../../images/skeletonized/tree_2.bmp",
                                               "../../../../images/skeletonized/tree_3.bmp",
                                               "../../../../images/skeletonized/zebra.bmp"};

#endif
<|endoftext|>


<commit_before>#include "common/params.h"

#include <dirent.h>
#include <sys/file.h>

#include <csignal>
#include <unordered_map>

#include "common/swaglog.h"
#include "common/util.h"
#include "system/hardware/hw.h"

namespace {

volatile sig_atomic_t params_do_exit = 0;
void params_sig_handler(int signal) {
  params_do_exit = 1;
}

int fsync_dir(const std::string &path) {
  int result = -1;
  int fd = HANDLE_EINTR(open(path.c_str(), O_RDONLY, 0755));
  if (fd >= 0) {
    result = fsync(fd);
    close(fd);
  }
  return result;
}

bool create_params_path(const std::string &param_path, const std::string &key_path) {
  // Make sure params path exists
  if (!util::file_exists(param_path) && !util::create_directories(param_path, 0775)) {
    return false;
  }

  // See if the symlink exists, otherwise create it
  if (!util::file_exists(key_path)) {
    // 1) Create temp folder
    // 2) Symlink it to temp link
    // 3) Move symlink to <params>/d

    std::string tmp_path = param_path + "/.tmp_XXXXXX";
    // this should be OK since mkdtemp just replaces characters in place
    char *tmp_dir = mkdtemp((char *)tmp_path.c_str());
    if (tmp_dir == NULL) {
      return false;
    }

    std::string link_path = std::string(tmp_dir) + ".link";
    if (symlink(tmp_dir, link_path.c_str()) != 0) {
      return false;
    }

    // don't return false if it has been created by other
    if (rename(link_path.c_str(), key_path.c_str()) != 0 && errno != EEXIST) {
      return false;
    }
  }

  return true;
}

std::string ensure_params_path(const std::string &prefix, const std::string &path = {}) {
  std::string params_path = path.empty() ? Path::params() : path;
  if (!create_params_path(params_path, params_path + prefix)) {
    throw std::runtime_error(util::string_format("Failed to ensure params path, errno=%d", errno));
  }
  return params_path;
}

class FileLock {
public:
  FileLock(const std::string &fn) {
    fd_ = HANDLE_EINTR(open(fn.c_str(), O_CREAT, 0775));
    if (fd_ < 0 || HANDLE_EINTR(flock(fd_, LOCK_EX)) < 0) {
      LOGE("Failed to lock file %s, errno=%d", fn.c_str(), errno);
    }
  }
  ~FileLock() { close(fd_); }

private:
  int fd_ = -1;
};

std::unordered_map<std::string, uint32_t> keys = {
    {"AccessToken", CLEAR_ON_MANAGER_START | DONT_LOG},
    {"AthenadPid", PERSISTENT},
    {"AthenadUploadQueue", PERSISTENT},
    {"CalibrationParams", PERSISTENT},
    {"CarBatteryCapacity", PERSISTENT},
    {"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"CarParamsCache", CLEAR_ON_MANAGER_START},
    {"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"CompletedTrainingVersion", PERSISTENT},
    {"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"DashcamOverride", PERSISTENT},
    {"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"DisablePowerDown", PERSISTENT},
    {"DisableRadar_Allow", PERSISTENT},
    {"DisableRadar", PERSISTENT}, // WARNING: THIS DISABLES AEB
    {"DisableUpdates", PERSISTENT},
    {"DisengageOnAccelerator", PERSISTENT},
    {"DongleId", PERSISTENT},
    {"DoReboot", CLEAR_ON_MANAGER_START},
    {"DoShutdown", CLEAR_ON_MANAGER_START},
    {"DoUninstall", CLEAR_ON_MANAGER_START},
    {"ForcePowerDown", CLEAR_ON_MANAGER_START},
    {"GitBranch", PERSISTENT},
    {"GitCommit", PERSISTENT},
    {"GitDiff", PERSISTENT},
    {"GithubSshKeys", PERSISTENT},
    {"GithubUsername", PERSISTENT},
    {"GitRemote", PERSISTENT},
    {"GsmApn", PERSISTENT},
    {"GsmRoaming", PERSISTENT},
    {"HardwareSerial", PERSISTENT},
    {"HasAcceptedTerms", PERSISTENT},
    {"IMEI", PERSISTENT},
    {"InstallDate", PERSISTENT},
    {"IsDriverViewEnabled", CLEAR_ON_MANAGER_START},
    {"IsEngaged", PERSISTENT},
    {"IsLdwEnabled", PERSISTENT},
    {"IsMetric", PERSISTENT},
    {"IsOffroad", CLEAR_ON_MANAGER_START},
    {"IsOnroad", PERSISTENT},
    {"IsRHD", PERSISTENT},
    {"IsTakingSnapshot", CLEAR_ON_MANAGER_START},
    {"IsUpdateAvailable", CLEAR_ON_MANAGER_START},
    {"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"LaikadEphemeris", PERSISTENT},
    {"LastAthenaPingTime", CLEAR_ON_MANAGER_START},
    {"LastGPSPosition", PERSISTENT},
    {"LastManagerExitReason", CLEAR_ON_MANAGER_START},
    {"LastPowerDropDetected", CLEAR_ON_MANAGER_START},
    {"LastSystemShutdown", CLEAR_ON_MANAGER_START},
    {"LastUpdateException", CLEAR_ON_MANAGER_START},
    {"LastUpdateTime", PERSISTENT},
    {"LiveParameters", PERSISTENT},
    {"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"NavSettingTime24h", PERSISTENT},
    {"NavdRender", PERSISTENT},
    {"OpenpilotEnabledToggle", PERSISTENT},
    {"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"PandaSignatures", CLEAR_ON_MANAGER_START},
    {"Passive", PERSISTENT},
    {"PrimeType", PERSISTENT},
    {"RecordFront", PERSISTENT},
    {"RecordFrontLock", PERSISTENT},  // for the internal fleet
    {"ReleaseNotes", PERSISTENT},
    {"ShouldDoUpdate", CLEAR_ON_MANAGER_START},
    {"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"SshEnabled", PERSISTENT},
    {"SubscriberInfo", PERSISTENT},
    {"TermsVersion", PERSISTENT},
    {"Timezone", PERSISTENT},
    {"TrainingVersion", PERSISTENT},
    {"UpdateAvailable", CLEAR_ON_MANAGER_START},
    {"UpdateFailedCount", CLEAR_ON_MANAGER_START},
    {"Version", PERSISTENT},
    {"VisionRadarToggle", PERSISTENT},
    {"WideCameraOnly", PERSISTENT},
    {"ApiCache_Device", PERSISTENT},
    {"ApiCache_DriveStats", PERSISTENT},
    {"ApiCache_NavDestinations", PERSISTENT},
    {"ApiCache_Owner", PERSISTENT},
    {"Offroad_BadNvme", CLEAR_ON_MANAGER_START},
    {"Offroad_CarUnrecognized", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"Offroad_ConnectivityNeeded", CLEAR_ON_MANAGER_START},
    {"Offroad_ConnectivityNeededPrompt", CLEAR_ON_MANAGER_START},
    {"Offroad_InvalidTime", CLEAR_ON_MANAGER_START},
    {"Offroad_IsTakingSnapshot", CLEAR_ON_MANAGER_START},
    {"Offroad_NeosUpdate", CLEAR_ON_MANAGER_START},
    {"Offroad_NoFirmware", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"Offroad_StorageMissing", CLEAR_ON_MANAGER_START},
    {"Offroad_TemperatureTooHigh", CLEAR_ON_MANAGER_START},
    {"Offroad_UnofficialHardware", CLEAR_ON_MANAGER_START},
    {"Offroad_UpdateFailed", CLEAR_ON_MANAGER_START},
};

} // namespace

Params::Params(const std::string &path) {
  const char* env = std::getenv("OPENPILOT_PREFIX");
  prefix = env ? "/" + std::string(env) : "/d";
  std::string default_param_path = ensure_params_path(prefix);
  params_path = path.empty() ? default_param_path : ensure_params_path(prefix, path);
}

bool Params::checkKey(const std::string &key) {
  return keys.find(key) != keys.end();
}

ParamKeyType Params::getKeyType(const std::string &key) {
  return static_cast<ParamKeyType>(keys[key]);
}

int Params::put(const char* key, const char* value, size_t value_size) {
  // Information about safely and atomically writing a file: https://lwn.net/Articles/457667/
  // 1) Create temp file
  // 2) Write data to temp file
  // 3) fsync() the temp file
  // 4) rename the temp file to the real name
  // 5) fsync() the containing directory
  std::string tmp_path = params_path + "/.tmp_value_XXXXXX";
  int tmp_fd = mkstemp((char*)tmp_path.c_str());
  if (tmp_fd < 0) return -1;

  int result = -1;
  do {
    // Write value to temp.
    ssize_t bytes_written = HANDLE_EINTR(write(tmp_fd, value, value_size));
    if (bytes_written < 0 || (size_t)bytes_written != value_size) {
      result = -20;
      break;
    }

    // fsync to force persist the changes.
    if ((result = fsync(tmp_fd)) < 0) break;

    FileLock file_lock(params_path + "/.lock");

    // Move temp into place.
    if ((result = rename(tmp_path.c_str(), getParamPath(key).c_str())) < 0) break;

    // fsync parent directory
    result = fsync_dir(getParamPath());
  } while (false);

  close(tmp_fd);
  ::unlink(tmp_path.c_str());
  return result;
}

int Params::remove(const std::string &key) {
  FileLock file_lock(params_path + "/.lock");
  int result = unlink(getParamPath(key).c_str());
  if (result != 0) {
    return result;
  }
  return fsync_dir(getParamPath());
}

std::string Params::get(const std::string &key, bool block) {
  if (!block) {
    return util::read_file(getParamPath(key));
  } else {
    // blocking read until successful
    params_do_exit = 0;
    void (*prev_handler_sigint)(int) = std::signal(SIGINT, params_sig_handler);
    void (*prev_handler_sigterm)(int) = std::signal(SIGTERM, params_sig_handler);

    std::string value;
    while (!params_do_exit) {
      if (value = util::read_file(getParamPath(key)); !value.empty()) {
        break;
      }
      util::sleep_for(100);  // 0.1 s
    }

    std::signal(SIGINT, prev_handler_sigint);
    std::signal(SIGTERM, prev_handler_sigterm);
    return value;
  }
}

std::map<std::string, std::string> Params::readAll() {
  FileLock file_lock(params_path + "/.lock");
  return util::read_files_in_dir(getParamPath());
}

void Params::clearAll(ParamKeyType key_type) {
  FileLock file_lock(params_path + "/.lock");

  std::string path;
  for (auto &[key, type] : keys) {
    if (type & key_type) {
      unlink(getParamPath(key).c_str());
    }
  }

  fsync_dir(getParamPath());
}
<commit_msg>don't log LaikadEphemeris in initData<commit_after>#include "common/params.h"

#include <dirent.h>
#include <sys/file.h>

#include <csignal>
#include <unordered_map>

#include "common/swaglog.h"
#include "common/util.h"
#include "system/hardware/hw.h"

namespace {

volatile sig_atomic_t params_do_exit = 0;
void params_sig_handler(int signal) {
  params_do_exit = 1;
}

int fsync_dir(const std::string &path) {
  int result = -1;
  int fd = HANDLE_EINTR(open(path.c_str(), O_RDONLY, 0755));
  if (fd >= 0) {
    result = fsync(fd);
    close(fd);
  }
  return result;
}

bool create_params_path(const std::string &param_path, const std::string &key_path) {
  // Make sure params path exists
  if (!util::file_exists(param_path) && !util::create_directories(param_path, 0775)) {
    return false;
  }

  // See if the symlink exists, otherwise create it
  if (!util::file_exists(key_path)) {
    // 1) Create temp folder
    // 2) Symlink it to temp link
    // 3) Move symlink to <params>/d

    std::string tmp_path = param_path + "/.tmp_XXXXXX";
    // this should be OK since mkdtemp just replaces characters in place
    char *tmp_dir = mkdtemp((char *)tmp_path.c_str());
    if (tmp_dir == NULL) {
      return false;
    }

    std::string link_path = std::string(tmp_dir) + ".link";
    if (symlink(tmp_dir, link_path.c_str()) != 0) {
      return false;
    }

    // don't return false if it has been created by other
    if (rename(link_path.c_str(), key_path.c_str()) != 0 && errno != EEXIST) {
      return false;
    }
  }

  return true;
}

std::string ensure_params_path(const std::string &prefix, const std::string &path = {}) {
  std::string params_path = path.empty() ? Path::params() : path;
  if (!create_params_path(params_path, params_path + prefix)) {
    throw std::runtime_error(util::string_format("Failed to ensure params path, errno=%d", errno));
  }
  return params_path;
}

class FileLock {
public:
  FileLock(const std::string &fn) {
    fd_ = HANDLE_EINTR(open(fn.c_str(), O_CREAT, 0775));
    if (fd_ < 0 || HANDLE_EINTR(flock(fd_, LOCK_EX)) < 0) {
      LOGE("Failed to lock file %s, errno=%d", fn.c_str(), errno);
    }
  }
  ~FileLock() { close(fd_); }

private:
  int fd_ = -1;
};

std::unordered_map<std::string, uint32_t> keys = {
    {"AccessToken", CLEAR_ON_MANAGER_START | DONT_LOG},
    {"AthenadPid", PERSISTENT},
    {"AthenadUploadQueue", PERSISTENT},
    {"CalibrationParams", PERSISTENT},
    {"CarBatteryCapacity", PERSISTENT},
    {"CarParams", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"CarParamsCache", CLEAR_ON_MANAGER_START},
    {"CarVin", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"CompletedTrainingVersion", PERSISTENT},
    {"ControlsReady", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"CurrentRoute", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"DashcamOverride", PERSISTENT},
    {"DisableLogging", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"DisablePowerDown", PERSISTENT},
    {"DisableRadar_Allow", PERSISTENT},
    {"DisableRadar", PERSISTENT}, // WARNING: THIS DISABLES AEB
    {"DisableUpdates", PERSISTENT},
    {"DisengageOnAccelerator", PERSISTENT},
    {"DongleId", PERSISTENT},
    {"DoReboot", CLEAR_ON_MANAGER_START},
    {"DoShutdown", CLEAR_ON_MANAGER_START},
    {"DoUninstall", CLEAR_ON_MANAGER_START},
    {"ForcePowerDown", CLEAR_ON_MANAGER_START},
    {"GitBranch", PERSISTENT},
    {"GitCommit", PERSISTENT},
    {"GitDiff", PERSISTENT},
    {"GithubSshKeys", PERSISTENT},
    {"GithubUsername", PERSISTENT},
    {"GitRemote", PERSISTENT},
    {"GsmApn", PERSISTENT},
    {"GsmRoaming", PERSISTENT},
    {"HardwareSerial", PERSISTENT},
    {"HasAcceptedTerms", PERSISTENT},
    {"IMEI", PERSISTENT},
    {"InstallDate", PERSISTENT},
    {"IsDriverViewEnabled", CLEAR_ON_MANAGER_START},
    {"IsEngaged", PERSISTENT},
    {"IsLdwEnabled", PERSISTENT},
    {"IsMetric", PERSISTENT},
    {"IsOffroad", CLEAR_ON_MANAGER_START},
    {"IsOnroad", PERSISTENT},
    {"IsRHD", PERSISTENT},
    {"IsTakingSnapshot", CLEAR_ON_MANAGER_START},
    {"IsUpdateAvailable", CLEAR_ON_MANAGER_START},
    {"JoystickDebugMode", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"LaikadEphemeris", PERSISTENT | DONT_LOG},
    {"LastAthenaPingTime", CLEAR_ON_MANAGER_START},
    {"LastGPSPosition", PERSISTENT},
    {"LastManagerExitReason", CLEAR_ON_MANAGER_START},
    {"LastPowerDropDetected", CLEAR_ON_MANAGER_START},
    {"LastSystemShutdown", CLEAR_ON_MANAGER_START},
    {"LastUpdateException", CLEAR_ON_MANAGER_START},
    {"LastUpdateTime", PERSISTENT},
    {"LiveParameters", PERSISTENT},
    {"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"NavSettingTime24h", PERSISTENT},
    {"NavdRender", PERSISTENT},
    {"OpenpilotEnabledToggle", PERSISTENT},
    {"PandaHeartbeatLost", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"PandaSignatures", CLEAR_ON_MANAGER_START},
    {"Passive", PERSISTENT},
    {"PrimeType", PERSISTENT},
    {"RecordFront", PERSISTENT},
    {"RecordFrontLock", PERSISTENT},  // for the internal fleet
    {"ReleaseNotes", PERSISTENT},
    {"ShouldDoUpdate", CLEAR_ON_MANAGER_START},
    {"SnoozeUpdate", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},
    {"SshEnabled", PERSISTENT},
    {"SubscriberInfo", PERSISTENT},
    {"TermsVersion", PERSISTENT},
    {"Timezone", PERSISTENT},
    {"TrainingVersion", PERSISTENT},
    {"UpdateAvailable", CLEAR_ON_MANAGER_START},
    {"UpdateFailedCount", CLEAR_ON_MANAGER_START},
    {"Version", PERSISTENT},
    {"VisionRadarToggle", PERSISTENT},
    {"WideCameraOnly", PERSISTENT},
    {"ApiCache_Device", PERSISTENT},
    {"ApiCache_DriveStats", PERSISTENT},
    {"ApiCache_NavDestinations", PERSISTENT},
    {"ApiCache_Owner", PERSISTENT},
    {"Offroad_BadNvme", CLEAR_ON_MANAGER_START},
    {"Offroad_CarUnrecognized", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"Offroad_ConnectivityNeeded", CLEAR_ON_MANAGER_START},
    {"Offroad_ConnectivityNeededPrompt", CLEAR_ON_MANAGER_START},
    {"Offroad_InvalidTime", CLEAR_ON_MANAGER_START},
    {"Offroad_IsTakingSnapshot", CLEAR_ON_MANAGER_START},
    {"Offroad_NeosUpdate", CLEAR_ON_MANAGER_START},
    {"Offroad_NoFirmware", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_ON},
    {"Offroad_StorageMissing", CLEAR_ON_MANAGER_START},
    {"Offroad_TemperatureTooHigh", CLEAR_ON_MANAGER_START},
    {"Offroad_UnofficialHardware", CLEAR_ON_MANAGER_START},
    {"Offroad_UpdateFailed", CLEAR_ON_MANAGER_START},
};

} // namespace

Params::Params(const std::string &path) {
  const char* env = std::getenv("OPENPILOT_PREFIX");
  prefix = env ? "/" + std::string(env) : "/d";
  std::string default_param_path = ensure_params_path(prefix);
  params_path = path.empty() ? default_param_path : ensure_params_path(prefix, path);
}

bool Params::checkKey(const std::string &key) {
  return keys.find(key) != keys.end();
}

ParamKeyType Params::getKeyType(const std::string &key) {
  return static_cast<ParamKeyType>(keys[key]);
}

int Params::put(const char* key, const char* value, size_t value_size) {
  // Information about safely and atomically writing a file: https://lwn.net/Articles/457667/
  // 1) Create temp file
  // 2) Write data to temp file
  // 3) fsync() the temp file
  // 4) rename the temp file to the real name
  // 5) fsync() the containing directory
  std::string tmp_path = params_path + "/.tmp_value_XXXXXX";
  int tmp_fd = mkstemp((char*)tmp_path.c_str());
  if (tmp_fd < 0) return -1;

  int result = -1;
  do {
    // Write value to temp.
    ssize_t bytes_written = HANDLE_EINTR(write(tmp_fd, value, value_size));
    if (bytes_written < 0 || (size_t)bytes_written != value_size) {
      result = -20;
      break;
    }

    // fsync to force persist the changes.
    if ((result = fsync(tmp_fd)) < 0) break;

    FileLock file_lock(params_path + "/.lock");

    // Move temp into place.
    if ((result = rename(tmp_path.c_str(), getParamPath(key).c_str())) < 0) break;

    // fsync parent directory
    result = fsync_dir(getParamPath());
  } while (false);

  close(tmp_fd);
  ::unlink(tmp_path.c_str());
  return result;
}

int Params::remove(const std::string &key) {
  FileLock file_lock(params_path + "/.lock");
  int result = unlink(getParamPath(key).c_str());
  if (result != 0) {
    return result;
  }
  return fsync_dir(getParamPath());
}

std::string Params::get(const std::string &key, bool block) {
  if (!block) {
    return util::read_file(getParamPath(key));
  } else {
    // blocking read until successful
    params_do_exit = 0;
    void (*prev_handler_sigint)(int) = std::signal(SIGINT, params_sig_handler);
    void (*prev_handler_sigterm)(int) = std::signal(SIGTERM, params_sig_handler);

    std::string value;
    while (!params_do_exit) {
      if (value = util::read_file(getParamPath(key)); !value.empty()) {
        break;
      }
      util::sleep_for(100);  // 0.1 s
    }

    std::signal(SIGINT, prev_handler_sigint);
    std::signal(SIGTERM, prev_handler_sigterm);
    return value;
  }
}

std::map<std::string, std::string> Params::readAll() {
  FileLock file_lock(params_path + "/.lock");
  return util::read_files_in_dir(getParamPath());
}

void Params::clearAll(ParamKeyType key_type) {
  FileLock file_lock(params_path + "/.lock");

  std::string path;
  for (auto &[key, type] : keys) {
    if (type & key_type) {
      unlink(getParamPath(key).c_str());
    }
  }

  fsync_dir(getParamPath());
}
<|endoftext|>


<commit_before>#include "space.hpp"
#include "string.hpp"

namespace space {
namespace exception {
    base::base(const std::string& s) : std::runtime_error(s) {}
    base::base(const char* s) : std::runtime_error(s) {}

    base::~base() noexcept {}

    cell_occupied::cell_occupied() :
        base("this cell already contains an object") {}

    invalid_direction::invalid_direction() :
        base("invalid direction provided") {}

    invalid_position::invalid_position(const vec_t& pos) :
        base("invalid position, goes out of the universe's boundaries: "+string::convert(pos)) {}
}

namespace impl {
    bool get_cell_id(std::size_t id, direction dir, std::size_t& next_id) {
        switch (id) {
        case sub_cell::TL :
            switch (dir) {
            case direction::LEFT  : next_id = sub_cell::TR; return false;
            case direction::UP    : next_id = sub_cell::BL; return false;
            case direction::RIGHT : next_id = sub_cell::TR; return true;
            case direction::DOWN  : next_id = sub_cell::BL; return true;
            }
        case sub_cell::TR :
            switch (dir) {
            case direction::LEFT  : next_id = sub_cell::TL; return true;
            case direction::UP    : next_id = sub_cell::BR; return false;
            case direction::RIGHT : next_id = sub_cell::TL; return false;
            case direction::DOWN  : next_id = sub_cell::BR; return true;
            }
        case sub_cell::BR :
            switch (dir) {
            case direction::LEFT  : next_id = sub_cell::BL; return true;
            case direction::UP    : next_id = sub_cell::TR; return true;
            case direction::RIGHT : next_id = sub_cell::BL; return false;
            case direction::DOWN  : next_id = sub_cell::TR; return false;
            }
        case sub_cell::BL :
            switch (dir) {
            case direction::LEFT  : next_id = sub_cell::BR; return false;
            case direction::UP    : next_id = sub_cell::TL; return true;
            case direction::RIGHT : next_id = sub_cell::BR; return true;
            case direction::DOWN  : next_id = sub_cell::TL; return false;
            }
        default : throw exception::invalid_direction();
        }
    }
}
}
<commit_msg>Fixed missing refactoring in space.cpp<commit_after>#include "space.hpp"
#include "string.hpp"

namespace space {
namespace exception {
    base::base(const std::string& s) : std::runtime_error(s) {}
    base::base(const char* s) : std::runtime_error(s) {}

    base::~base() noexcept {}

    cell_occupied::cell_occupied() :
        base("this cell already contains an object") {}

    invalid_direction::invalid_direction() :
        base("invalid direction provided") {}

    invalid_position::invalid_position(const vec_t& pos) :
        base("invalid position, goes out of the universe's boundaries: "+string::convert(pos)) {}
}

namespace impl {
    bool get_cell_id(std::size_t id, direction dir, std::size_t& next_id) {
        switch (id) {
        case sub_cell::TL :
            switch (dir) {
            case direction::left  : next_id = sub_cell::TR; return false;
            case direction::up    : next_id = sub_cell::BL; return false;
            case direction::right : next_id = sub_cell::TR; return true;
            case direction::down  : next_id = sub_cell::BL; return true;
            }
        case sub_cell::TR :
            switch (dir) {
            case direction::left  : next_id = sub_cell::TL; return true;
            case direction::up    : next_id = sub_cell::BR; return false;
            case direction::right : next_id = sub_cell::TL; return false;
            case direction::down  : next_id = sub_cell::BR; return true;
            }
        case sub_cell::BR :
            switch (dir) {
            case direction::left  : next_id = sub_cell::BL; return true;
            case direction::up    : next_id = sub_cell::TR; return true;
            case direction::right : next_id = sub_cell::BL; return false;
            case direction::down  : next_id = sub_cell::TR; return false;
            }
        case sub_cell::BL :
            switch (dir) {
            case direction::left  : next_id = sub_cell::BR; return false;
            case direction::up    : next_id = sub_cell::TL; return true;
            case direction::right : next_id = sub_cell::BR; return true;
            case direction::down  : next_id = sub_cell::TL; return false;
            }
        default : throw exception::invalid_direction();
        }
    }
}
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_FAULTS_HH__
#define __ARCH_X86_FAULTS_HH__

#include "base/misc.hh"
#include "sim/faults.hh"

namespace X86ISA
{
    class X86Fault : public FaultBase
    {
      protected:
        const char * name()
        {
            return "generic_x86_fault";
        }

        void invoke(ThreadContext * tc)
        {
            panic("X86 faults are not implemented!");
        }
    };

    class UnimpInstFault : public FaultBase
    {
      public:
        const char * name()
        {
            return "unimplemented_micro";
        }

        void invoke(ThreadContext * tc)
        {
            panic("Unimplemented instruction!");
        }
    };

    static inline Fault genPageTableFault(Addr va)
    {
        panic("Page table fault not implemented in x86!\n");
    }

    static inline Fault genMachineCheckFault()
    {
        panic("Machine check fault not implemented in x86!\n");
    }

    static inline Fault genAlignmentFault()
    {
        panic("Alignment fault not implemented (or for the most part existant) in x86!\n");
    }
};

#endif // __ARCH_X86_FAULTS_HH__
<commit_msg>Make the "name" function const.<commit_after>/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#ifndef __ARCH_X86_FAULTS_HH__
#define __ARCH_X86_FAULTS_HH__

#include "base/misc.hh"
#include "sim/faults.hh"

namespace X86ISA
{
    class X86Fault : public FaultBase
    {
      protected:
        const char * name() const
        {
            return "generic_x86_fault";
        }

        void invoke(ThreadContext * tc)
        {
            panic("X86 faults are not implemented!");
        }
    };

    class UnimpInstFault : public FaultBase
    {
      public:
        const char * name() const
        {
            return "unimplemented_micro";
        }

        void invoke(ThreadContext * tc)
        {
            panic("Unimplemented instruction!");
        }
    };

    static inline Fault genPageTableFault(Addr va)
    {
        panic("Page table fault not implemented in x86!\n");
    }

    static inline Fault genMachineCheckFault()
    {
        panic("Machine check fault not implemented in x86!\n");
    }

    static inline Fault genAlignmentFault()
    {
        panic("Alignment fault not implemented (or for the most part existant) in x86!\n");
    }
};

#endif // __ARCH_X86_FAULTS_HH__
<|endoftext|>


<commit_before><commit_msg>Add EnsureUnion patch op conformance test for union structs<commit_after><|endoftext|>


<commit_before>/*
Copyright (C) 2016-2018 Rodrigo Jose Hernandez Cordoba

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.
*/
#define _USE_MATH_DEFINES
#include <QResizeEvent>
#include <QString>
#include <QStringList>
#include <cassert>
#include <cmath>
#include <iostream>
#include <exception>
#include <stdexcept>
#include "WorldEditor.h"
#include "EngineWindow.h"
#include "aeongames/Renderer.h"
#include "aeongames/Model.h"
#include "aeongames/ModelInstance.h"
#include "aeongames/Animation.h"
#include "aeongames/Mesh.h"
#include "aeongames/ResourceCache.h"
#include "aeongames/Window.h"
#include "aeongames/Frustum.h"
#include "aeongames/CRC.h"
#include "aeongames/Node.h"

namespace AeonGames
{
    EngineWindow::EngineWindow ( QWindow *parent ) :
        QWindow ( parent ),
        mTimer(),
        mStopWatch(),
        mWindow(),
        mFrustumVerticalHalfAngle ( 0 ), mStep ( 10 ),
        mCameraRotation ( QQuaternion::fromAxisAndAngle ( 0.0f, 0.0f, 1.0f, 45.0f ) * QQuaternion::fromAxisAndAngle ( 1.0f, 0.0f, 0.0f, -30.0f ) ),
        // Stand back 3 meters.
        mCameraLocation ( -QVector3D ( mCameraRotation.rotatedVector ( forward ) * 300.0f ), 1 ),
        mProjectionMatrix(),
        mViewMatrix()
    {
        // Hopefully these settings are optimal for Vulkan as well as OpenGL
        setSurfaceType ( QSurface::OpenGLSurface );

        /* On Windows we want the window to own its device context.
        This code works on Qt 5.6.0, but if it does not
        or a new non Qt application needs to set it,
        a window class style seems to be mutable by using
        SetClassLongPtr( ..., GCL_STYLE, ... );
        instead.
        https://msdn.microsoft.com/en-us/library/windows/desktop/ms633589%28v=vs.85%29.aspx
        http://www.gamedev.net/topic/319124-ogl-and-windows/#entry3055268

        This flag is Windows specific, so Linux or Mac implementations
        will probably just ignore it, I have not verified this though.
        UPDATE: Linux compilation does not complain about this code.
        */
        auto current_flags = flags();
        if ( ! ( current_flags & Qt::MSWindowsOwnDC ) )
        {
            setFlags ( current_flags | Qt::MSWindowsOwnDC );
        }
        mWindow = qWorldEditorApp->GetRenderer()->CreateWindowProxy ( reinterpret_cast<void*> ( winId() ) );
        if ( !mWindow )
        {
            throw std::runtime_error ( "Window creation failed." );
        }
        connect ( &mTimer, SIGNAL ( timeout() ), this, SLOT ( requestUpdate() ) );
        updateViewMatrix();
        float half_radius = ( static_cast<float> ( geometry().size().width() ) / static_cast<float> ( geometry().size().height() ) ) / 2;
        float v1[2] = { 1, 0 };
        float v2[2] = { 1, half_radius };
        float length = sqrtf ( ( v2[0] * v2[0] ) + ( v2[1] * v2[1] ) );
        v2[0] /= length;
        v2[1] /= length;
        mFrustumVerticalHalfAngle = acosf ( ( v1[0] * v2[0] ) + ( v1[1] * v2[1] ) );
    }

    EngineWindow::~EngineWindow()
    {
        mWindow.reset();
        stop();
    }

    void EngineWindow::stop()
    {
        if ( mStopWatch.isValid() && mTimer.isActive() )
        {
            mTimer.stop();
            mStopWatch.invalidate();
        }
    }

    void EngineWindow::start()
    {
        if ( !mStopWatch.isValid() && !mTimer.isActive() )
        {
            mTimer.start ( 0 );
            mStopWatch.start();
        }
    }

    void EngineWindow::setScene ( const Scene* aScene )
    {
        mScene = aScene;
    }
#if 0
    // Commented pending Refactor
    void EngineWindow::setModel ( const QString & filename )
    {
        /**@todo We probably don't want to expose the Resource Cache this way to avoid misuse.*/
        mNode->AttachComponent ( ModelInstance::TypeId, {},
                                 std::make_shared<ModelInstance> (
                                     Get<Model> ( filename.toUtf8().constData(),
                                             filename.toUtf8().constData() ) ) );
        assert ( mNode->GetComponent ( ModelInstance::TypeId ) && "ModelInstance is a nullptr" );
        mRenderer->Unload ( *mNode );
        mRenderer->Load ( *mNode );
        if ( ModelInstance* model_instance = reinterpret_cast<ModelInstance*> ( mNode->GetComponent ( ModelInstance::TypeId ) ) )
        {
            // Adjust camera position so model fits the frustum tightly.
            float diameter = model_instance->GetModel()->GetCenterRadii().GetRadii().GetMaxAxisLenght() * 2;
            std::cout << "Diameter: " << diameter << std::endl;
            // Add the near value to the radius just in case the actual object contains the eye position.
            float half_radius = ( static_cast<float> ( geometry().size().width() ) / static_cast<float> ( geometry().size().height() ) ) / 2;
            float v1[2] = { 1, 0 };
            float v2[2] = { 1, half_radius };
            float length = sqrtf ( ( v2[0] * v2[0] ) + ( v2[1] * v2[1] ) );
            v2[0] /= length;
            v2[1] /= length;
            mFrustumVerticalHalfAngle = acosf ( ( v1[0] * v2[0] ) + ( v1[1] * v2[1] ) );

            if ( mFrustumVerticalHalfAngle == 0.0f )
            {
                throw std::runtime_error ( "mFrustumVerticalHalfAngle is zero." );
            }

            float eye_length = ( diameter ) / std::tan ( mFrustumVerticalHalfAngle );
            mCameraLocation = QVector4D (
                                  QVector3D (
                                      model_instance->GetModel()->GetCenterRadii().GetCenter() [0],
                                      model_instance->GetModel()->GetCenterRadii().GetCenter() [1],
                                      model_instance->GetModel()->GetCenterRadii().GetCenter() [2] ) +
                                  ( mCameraRotation.rotatedVector ( -forward ) * eye_length ), 1 );
            updateViewMatrix();
            mStep = eye_length / 100.0f;
        }
    }
#endif

    void EngineWindow::resizeEvent ( QResizeEvent * aResizeEvent )
    {
        if ( mWindow && aResizeEvent->size().width() && aResizeEvent->size().height() )
        {
            QMargins frame_margins{frameMargins() };
            mWindow->ResizeViewport ( frame_margins.left(), frame_margins.top(), aResizeEvent->size().width(), aResizeEvent->size().height() );
            static const QMatrix4x4 flipMatrix (
                1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, -1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f );
            mProjectionMatrix.setToIdentity();
            float half_radius = ( static_cast<float> ( aResizeEvent->size().width() ) / static_cast<float> ( aResizeEvent->size().height() ) ) / 2;
            mProjectionMatrix.frustum ( -half_radius, half_radius, 0.5, -0.5, 1, 1600 );
            mProjectionMatrix = mProjectionMatrix * flipMatrix;
            mWindow->SetProjectionMatrix ( mProjectionMatrix.constData() );
            // Calculate frustum half vertical angle (for fitting nodes into frustum)
            float v1[2] = { 1, 0 };
            float v2[2] = { 1, half_radius };
            float length = sqrtf ( ( v2[0] * v2[0] ) + ( v2[1] * v2[1] ) );
            v2[0] /= length;
            v2[1] /= length;
            mFrustumVerticalHalfAngle = acosf ( ( v1[0] * v2[0] ) + ( v1[1] * v2[1] ) );
            start();
        }
        else
        {
            stop();
        }
    }

    void EngineWindow::exposeEvent ( QExposeEvent * aExposeEvent )
    {
        Q_UNUSED ( aExposeEvent );
        if ( isExposed() )
        {
            start();
        }
        else
        {
            stop();
        }
    }

    bool EngineWindow::event ( QEvent * aEvent )
    {
        switch ( aEvent->type() )
        {
        case QEvent::UpdateRequest:
            if ( geometry().width() && geometry().height() )
            {
                double delta = 0.0;
                if ( mStopWatch.isValid() )
                {
                    delta = mStopWatch.restart() * 1e-3f;
                    if ( delta > 1e-1f )
                    {
                        delta = 1.0 / 30.0;
                    }
                }
                mWindow->BeginRender();
                mWindow->Render ( Transform{},
                                  qWorldEditorApp->GetGridMesh(),
                                  qWorldEditorApp->GetGridPipeline(),
                                  &qWorldEditorApp->GetXGridMaterial(), 0, 2,
                                  qWorldEditorApp->GetGridSettings().horizontalSpacing() + 1 );
                mWindow->Render ( Transform{},
                                  qWorldEditorApp->GetGridMesh(),
                                  qWorldEditorApp->GetGridPipeline(),
                                  &qWorldEditorApp->GetYGridMaterial(), 2, 2,
                                  qWorldEditorApp->GetGridSettings().verticalSpacing() + 1 );
                if ( mScene )
                {
                    Matrix4x4 view_matrix { mWindow->GetViewTransform().GetInverted().GetMatrix() };
                    Frustum frustum ( mWindow->GetProjectionMatrix() * view_matrix );
                    mScene->LoopTraverseDFSPreOrder ( [this, &frustum, &view_matrix] ( const Node & aNode )
                    {
                        if ( frustum.Intersects ( aNode.GetGlobalTransform() * qWorldEditorApp->GetAABBWireMesh().GetAABB() ) )
                        {
                            mWindow->Render ( aNode.GetGlobalTransform(),
                                              qWorldEditorApp->GetAABBWireMesh(),
                                              qWorldEditorApp->GetWirePipeline(),
                                              &qWorldEditorApp->GetWirePipeline().GetDefaultMaterial() );
                        }
                    } );
                }
                mWindow->EndRender();
                return true;
            }
        default:
            return QWindow::event ( aEvent );
        }
    }

    void EngineWindow::updateViewMatrix()
    {
        Transform view_transform;
        view_transform.SetTranslation ( Vector3 ( mCameraLocation.x(), mCameraLocation.y(), mCameraLocation.z() ) );
        view_transform.SetRotation ( Quaternion ( mCameraRotation.scalar(), mCameraRotation.x(), mCameraRotation.y(), mCameraRotation.z() ) );
        mWindow->SetViewTransform ( view_transform );
    }

    void EngineWindow::keyPressEvent ( QKeyEvent * event )
    {
        switch ( event->key() )
        {
        case Qt::Key_W:
            mCameraLocation += ( mCameraRotation.rotatedVector ( forward ) * mStep );
            break;
        case Qt::Key_S:
            mCameraLocation -= ( mCameraRotation.rotatedVector ( forward ) * mStep );
            break;
        case Qt::Key_D:
            mCameraLocation += ( mCameraRotation.rotatedVector ( right ) * mStep );
            break;
        case Qt::Key_A:
            mCameraLocation -= ( mCameraRotation.rotatedVector ( right ) * mStep );
            break;
        }
        updateViewMatrix();
        event->accept();
    }

    void EngineWindow::keyReleaseEvent ( QKeyEvent * event )
    {
        event->accept();
    }

    void EngineWindow::mouseMoveEvent ( QMouseEvent * event )
    {
#if 1
        if ( event->buttons() & Qt::LeftButton )
        {
            QPoint movement = event->globalPos() - mLastCursorPosition;
            mLastCursorPosition = event->globalPos();
            mCameraRotation = QQuaternion::fromAxisAndAngle ( 0, 0, 1, - ( static_cast<float> ( movement.x() ) / 2.0f ) ) * mCameraRotation;
            mCameraRotation = mCameraRotation * QQuaternion::fromAxisAndAngle ( 1, 0, 0, - ( static_cast<float> ( movement.y() ) / 2.0f ) );
            updateViewMatrix();
        }
#endif
        event->accept();
    }

    void EngineWindow::mousePressEvent ( QMouseEvent * event )
    {
        if ( event->button() & Qt::LeftButton )
        {
            mLastCursorPosition = event->globalPos();
        }
        event->accept();
    }

    void EngineWindow::mouseReleaseEvent ( QMouseEvent * event )
    {
        event->accept();
    }

    void EngineWindow::wheelEvent ( QWheelEvent *event )
    {
        mCameraLocation += ( ( mCameraRotation.rotatedVector ( forward ) * mStep ) *
                             ( event->angleDelta().y() / std::abs ( event->angleDelta().y() ) ) );
        updateViewMatrix();
        event->accept();
    }
}
<commit_msg>Changed Engine Window to use the window geometry ...<commit_after>/*
Copyright (C) 2016-2018 Rodrigo Jose Hernandez Cordoba

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.
*/
#define _USE_MATH_DEFINES
#include <QResizeEvent>
#include <QString>
#include <QStringList>
#include <cassert>
#include <cmath>
#include <iostream>
#include <exception>
#include <stdexcept>
#include "WorldEditor.h"
#include "EngineWindow.h"
#include "aeongames/Renderer.h"
#include "aeongames/Model.h"
#include "aeongames/ModelInstance.h"
#include "aeongames/Animation.h"
#include "aeongames/Mesh.h"
#include "aeongames/ResourceCache.h"
#include "aeongames/Window.h"
#include "aeongames/Frustum.h"
#include "aeongames/CRC.h"
#include "aeongames/Node.h"

namespace AeonGames
{
    EngineWindow::EngineWindow ( QWindow *parent ) :
        QWindow ( parent ),
        mTimer(),
        mStopWatch(),
        mWindow(),
        mFrustumVerticalHalfAngle ( 0 ), mStep ( 10 ),
        mCameraRotation ( QQuaternion::fromAxisAndAngle ( 0.0f, 0.0f, 1.0f, 45.0f ) * QQuaternion::fromAxisAndAngle ( 1.0f, 0.0f, 0.0f, -30.0f ) ),
        // Stand back 3 meters.
        mCameraLocation ( -QVector3D ( mCameraRotation.rotatedVector ( forward ) * 300.0f ), 1 ),
        mProjectionMatrix(),
        mViewMatrix()
    {
        // Hopefully these settings are optimal for Vulkan as well as OpenGL
        setSurfaceType ( QSurface::OpenGLSurface );

        /* On Windows we want the window to own its device context.
        This code works on Qt 5.6.0, but if it does not
        or a new non Qt application needs to set it,
        a window class style seems to be mutable by using
        SetClassLongPtr( ..., GCL_STYLE, ... );
        instead.
        https://msdn.microsoft.com/en-us/library/windows/desktop/ms633589%28v=vs.85%29.aspx
        http://www.gamedev.net/topic/319124-ogl-and-windows/#entry3055268

        This flag is Windows specific, so Linux or Mac implementations
        will probably just ignore it, I have not verified this though.
        UPDATE: Linux compilation does not complain about this code.
        */
        auto current_flags = flags();
        if ( ! ( current_flags & Qt::MSWindowsOwnDC ) )
        {
            setFlags ( current_flags | Qt::MSWindowsOwnDC );
        }
        mWindow = qWorldEditorApp->GetRenderer()->CreateWindowProxy ( reinterpret_cast<void*> ( winId() ) );
        if ( !mWindow )
        {
            throw std::runtime_error ( "Window creation failed." );
        }
        connect ( &mTimer, SIGNAL ( timeout() ), this, SLOT ( requestUpdate() ) );
        updateViewMatrix();
        float half_radius = ( static_cast<float> ( geometry().size().width() ) / static_cast<float> ( geometry().size().height() ) ) / 2;
        float v1[2] = { 1, 0 };
        float v2[2] = { 1, half_radius };
        float length = sqrtf ( ( v2[0] * v2[0] ) + ( v2[1] * v2[1] ) );
        v2[0] /= length;
        v2[1] /= length;
        mFrustumVerticalHalfAngle = acosf ( ( v1[0] * v2[0] ) + ( v1[1] * v2[1] ) );
    }

    EngineWindow::~EngineWindow()
    {
        mWindow.reset();
        stop();
    }

    void EngineWindow::stop()
    {
        if ( mStopWatch.isValid() && mTimer.isActive() )
        {
            mTimer.stop();
            mStopWatch.invalidate();
        }
    }

    void EngineWindow::start()
    {
        if ( !mStopWatch.isValid() && !mTimer.isActive() )
        {
            mTimer.start ( 0 );
            mStopWatch.start();
        }
    }

    void EngineWindow::setScene ( const Scene* aScene )
    {
        mScene = aScene;
    }
#if 0
    // Commented pending Refactor
    void EngineWindow::setModel ( const QString & filename )
    {
        /**@todo We probably don't want to expose the Resource Cache this way to avoid misuse.*/
        mNode->AttachComponent ( ModelInstance::TypeId, {},
                                 std::make_shared<ModelInstance> (
                                     Get<Model> ( filename.toUtf8().constData(),
                                             filename.toUtf8().constData() ) ) );
        assert ( mNode->GetComponent ( ModelInstance::TypeId ) && "ModelInstance is a nullptr" );
        mRenderer->Unload ( *mNode );
        mRenderer->Load ( *mNode );
        if ( ModelInstance* model_instance = reinterpret_cast<ModelInstance*> ( mNode->GetComponent ( ModelInstance::TypeId ) ) )
        {
            // Adjust camera position so model fits the frustum tightly.
            float diameter = model_instance->GetModel()->GetCenterRadii().GetRadii().GetMaxAxisLenght() * 2;
            std::cout << "Diameter: " << diameter << std::endl;
            // Add the near value to the radius just in case the actual object contains the eye position.
            float half_radius = ( static_cast<float> ( geometry().size().width() ) / static_cast<float> ( geometry().size().height() ) ) / 2;
            float v1[2] = { 1, 0 };
            float v2[2] = { 1, half_radius };
            float length = sqrtf ( ( v2[0] * v2[0] ) + ( v2[1] * v2[1] ) );
            v2[0] /= length;
            v2[1] /= length;
            mFrustumVerticalHalfAngle = acosf ( ( v1[0] * v2[0] ) + ( v1[1] * v2[1] ) );

            if ( mFrustumVerticalHalfAngle == 0.0f )
            {
                throw std::runtime_error ( "mFrustumVerticalHalfAngle is zero." );
            }

            float eye_length = ( diameter ) / std::tan ( mFrustumVerticalHalfAngle );
            mCameraLocation = QVector4D (
                                  QVector3D (
                                      model_instance->GetModel()->GetCenterRadii().GetCenter() [0],
                                      model_instance->GetModel()->GetCenterRadii().GetCenter() [1],
                                      model_instance->GetModel()->GetCenterRadii().GetCenter() [2] ) +
                                  ( mCameraRotation.rotatedVector ( -forward ) * eye_length ), 1 );
            updateViewMatrix();
            mStep = eye_length / 100.0f;
        }
    }
#endif

    void EngineWindow::resizeEvent ( QResizeEvent * aResizeEvent )
    {
        if ( mWindow && aResizeEvent->size().width() && aResizeEvent->size().height() )
        {
            QRect rect{ geometry() };
            mWindow->ResizeViewport ( rect.x(), rect.y(), rect.width(), rect.height() );
            static const QMatrix4x4 flipMatrix (
                1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, -1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f );
            mProjectionMatrix.setToIdentity();
            float half_radius = ( static_cast<float> ( aResizeEvent->size().width() ) / static_cast<float> ( aResizeEvent->size().height() ) ) / 2;
            mProjectionMatrix.frustum ( -half_radius, half_radius, 0.5, -0.5, 1, 1600 );
            mProjectionMatrix = mProjectionMatrix * flipMatrix;
            mWindow->SetProjectionMatrix ( mProjectionMatrix.constData() );
            // Calculate frustum half vertical angle (for fitting nodes into frustum)
            float v1[2] = { 1, 0 };
            float v2[2] = { 1, half_radius };
            float length = sqrtf ( ( v2[0] * v2[0] ) + ( v2[1] * v2[1] ) );
            v2[0] /= length;
            v2[1] /= length;
            mFrustumVerticalHalfAngle = acosf ( ( v1[0] * v2[0] ) + ( v1[1] * v2[1] ) );
            start();
        }
        else
        {
            stop();
        }
    }

    void EngineWindow::exposeEvent ( QExposeEvent * aExposeEvent )
    {
        Q_UNUSED ( aExposeEvent );
        if ( isExposed() )
        {
            start();
        }
        else
        {
            stop();
        }
    }

    bool EngineWindow::event ( QEvent * aEvent )
    {
        switch ( aEvent->type() )
        {
        case QEvent::UpdateRequest:
            if ( geometry().width() && geometry().height() )
            {
                double delta = 0.0;
                if ( mStopWatch.isValid() )
                {
                    delta = mStopWatch.restart() * 1e-3f;
                    if ( delta > 1e-1f )
                    {
                        delta = 1.0 / 30.0;
                    }
                }
                mWindow->BeginRender();
                mWindow->Render ( Transform{},
                                  qWorldEditorApp->GetGridMesh(),
                                  qWorldEditorApp->GetGridPipeline(),
                                  &qWorldEditorApp->GetXGridMaterial(), 0, 2,
                                  qWorldEditorApp->GetGridSettings().horizontalSpacing() + 1 );
                mWindow->Render ( Transform{},
                                  qWorldEditorApp->GetGridMesh(),
                                  qWorldEditorApp->GetGridPipeline(),
                                  &qWorldEditorApp->GetYGridMaterial(), 2, 2,
                                  qWorldEditorApp->GetGridSettings().verticalSpacing() + 1 );
                if ( mScene )
                {
                    Matrix4x4 view_matrix { mWindow->GetViewTransform().GetInverted().GetMatrix() };
                    Frustum frustum ( mWindow->GetProjectionMatrix() * view_matrix );
                    mScene->LoopTraverseDFSPreOrder ( [this, &frustum, &view_matrix] ( const Node & aNode )
                    {
                        if ( frustum.Intersects ( aNode.GetGlobalTransform() * qWorldEditorApp->GetAABBWireMesh().GetAABB() ) )
                        {
                            mWindow->Render ( aNode.GetGlobalTransform(),
                                              qWorldEditorApp->GetAABBWireMesh(),
                                              qWorldEditorApp->GetWirePipeline(),
                                              &qWorldEditorApp->GetWirePipeline().GetDefaultMaterial() );
                        }
                    } );
                }
                mWindow->EndRender();
                return true;
            }
        default:
            return QWindow::event ( aEvent );
        }
    }

    void EngineWindow::updateViewMatrix()
    {
        Transform view_transform;
        view_transform.SetTranslation ( Vector3 ( mCameraLocation.x(), mCameraLocation.y(), mCameraLocation.z() ) );
        view_transform.SetRotation ( Quaternion ( mCameraRotation.scalar(), mCameraRotation.x(), mCameraRotation.y(), mCameraRotation.z() ) );
        mWindow->SetViewTransform ( view_transform );
    }

    void EngineWindow::keyPressEvent ( QKeyEvent * event )
    {
        switch ( event->key() )
        {
        case Qt::Key_W:
            mCameraLocation += ( mCameraRotation.rotatedVector ( forward ) * mStep );
            break;
        case Qt::Key_S:
            mCameraLocation -= ( mCameraRotation.rotatedVector ( forward ) * mStep );
            break;
        case Qt::Key_D:
            mCameraLocation += ( mCameraRotation.rotatedVector ( right ) * mStep );
            break;
        case Qt::Key_A:
            mCameraLocation -= ( mCameraRotation.rotatedVector ( right ) * mStep );
            break;
        }
        updateViewMatrix();
        event->accept();
    }

    void EngineWindow::keyReleaseEvent ( QKeyEvent * event )
    {
        event->accept();
    }

    void EngineWindow::mouseMoveEvent ( QMouseEvent * event )
    {
#if 1
        if ( event->buttons() & Qt::LeftButton )
        {
            QPoint movement = event->globalPos() - mLastCursorPosition;
            mLastCursorPosition = event->globalPos();
            mCameraRotation = QQuaternion::fromAxisAndAngle ( 0, 0, 1, - ( static_cast<float> ( movement.x() ) / 2.0f ) ) * mCameraRotation;
            mCameraRotation = mCameraRotation * QQuaternion::fromAxisAndAngle ( 1, 0, 0, - ( static_cast<float> ( movement.y() ) / 2.0f ) );
            updateViewMatrix();
        }
#endif
        event->accept();
    }

    void EngineWindow::mousePressEvent ( QMouseEvent * event )
    {
        if ( event->button() & Qt::LeftButton )
        {
            mLastCursorPosition = event->globalPos();
        }
        event->accept();
    }

    void EngineWindow::mouseReleaseEvent ( QMouseEvent * event )
    {
        event->accept();
    }

    void EngineWindow::wheelEvent ( QWheelEvent *event )
    {
        mCameraLocation += ( ( mCameraRotation.rotatedVector ( forward ) * mStep ) *
                             ( event->angleDelta().y() / std::abs ( event->angleDelta().y() ) ) );
        updateViewMatrix();
        event->accept();
    }
}
<|endoftext|>


<commit_before>//===--- TestTU.cpp - Scratch source files for testing --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "TestTU.h"
#include "TestFS.h"
#include "index/FileIndex.h"
#include "index/MemIndex.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Frontend/Utils.h"

using namespace llvm;
namespace clang {
namespace clangd {

ParsedAST TestTU::build() const {
  std::string FullFilename = testPath(Filename),
              FullHeaderName = testPath(HeaderFilename);
  std::vector<const char *> Cmd = {"clang", FullFilename.c_str()};
  // FIXME: this shouldn't need to be conditional, but it breaks a
  // GoToDefinition test for some reason (getMacroArgExpandedLocation fails).
  if (!HeaderCode.empty()) {
    Cmd.push_back("-include");
    Cmd.push_back(FullHeaderName.c_str());
  }
  Cmd.insert(Cmd.end(), ExtraArgs.begin(), ExtraArgs.end());
  ParseInputs Inputs;
  Inputs.CompileCommand.Filename = FullFilename;
  Inputs.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()};
  Inputs.CompileCommand.Directory = testRoot();
  Inputs.Contents = Code;
  Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}});
  auto PCHs = std::make_shared<PCHContainerOperations>();
  auto Preamble =
      buildPreamble(FullFilename, *createInvocationFromCommandLine(Cmd),
                    /*OldPreamble=*/nullptr,
                    /*OldCompileCommand=*/Inputs.CompileCommand, Inputs, PCHs,
                    /*StoreInMemory=*/true, /*PreambleCallback=*/nullptr);
  auto AST = buildAST(FullFilename, createInvocationFromCommandLine(Cmd),
                      Inputs, Preamble, PCHs);
  if (!AST.hasValue()) {
    ADD_FAILURE() << "Failed to build code:\n" << Code;
    llvm_unreachable("Failed to build TestTU!");
  }
  return std::move(*AST);
}

SymbolSlab TestTU::headerSymbols() const {
  auto AST = build();
  return indexHeaderSymbols(AST.getASTContext(), AST.getPreprocessorPtr());
}

std::unique_ptr<SymbolIndex> TestTU::index() const {
  auto AST = build();
  auto Idx = llvm::make_unique<FileIndex>(/*UseDex=*/true);
  Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr());
  Idx->updateMain(Filename, AST);
  return std::move(Idx);
}

const Symbol &findSymbol(const SymbolSlab &Slab, StringRef QName) {
  const Symbol *Result = nullptr;
  for (const Symbol &S : Slab) {
    if (QName != (S.Scope + S.Name).str())
      continue;
    if (Result) {
      ADD_FAILURE() << "Multiple symbols named " << QName << ":\n"
                    << *Result << "\n---\n"
                    << S;
      assert(false && "QName is not unique");
    }
    Result = &S;
  }
  if (!Result) {
    ADD_FAILURE() << "No symbol named " << QName << " in "
                  << ::testing::PrintToString(Slab);
    assert(false && "No symbol with QName");
  }
  return *Result;
}

const NamedDecl &findDecl(ParsedAST &AST, StringRef QName) {
  SmallVector<StringRef, 4> Components;
  QName.split(Components, "::");

  auto &Ctx = AST.getASTContext();
  auto LookupDecl = [&Ctx](const DeclContext &Scope,
                           StringRef Name) -> const NamedDecl & {
    auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name)));
    assert(!LookupRes.empty() && "Lookup failed");
    assert(LookupRes.size() == 1 && "Lookup returned multiple results");
    return *LookupRes.front();
  };

  const DeclContext *Scope = Ctx.getTranslationUnitDecl();
  for (auto NameIt = Components.begin(), End = Components.end() - 1;
       NameIt != End; ++NameIt) {
    Scope = &cast<DeclContext>(LookupDecl(*Scope, *NameIt));
  }
  return LookupDecl(*Scope, Components.back());
}

const NamedDecl &findDecl(ParsedAST &AST,
                          std::function<bool(const NamedDecl &)> Filter) {
  struct Visitor : RecursiveASTVisitor<Visitor> {
    decltype(Filter) F;
    SmallVector<const NamedDecl *, 1> Decls;
    bool VisitNamedDecl(const NamedDecl *ND) {
      if (F(*ND))
        Decls.push_back(ND);
      return true;
    }
  } Visitor;
  Visitor.F = Filter;
  Visitor.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
  if (Visitor.Decls.size() != 1) {
    ADD_FAILURE() << Visitor.Decls.size() << " symbols matched.";
    assert(Visitor.Decls.size() == 1);
  }
  return *Visitor.Decls.front();
}

const NamedDecl &findUnqualifiedDecl(ParsedAST &AST, StringRef Name) {
  return findDecl(AST, [Name](const NamedDecl &ND) {
    if (auto *ID = ND.getIdentifier())
      if (ID->getName() == Name)
        return true;
    return false;
  });
}

} // namespace clangd
} // namespace clang
<commit_msg>[clangd] Fix memory leak in ClangdTests.<commit_after>//===--- TestTU.cpp - Scratch source files for testing --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "TestTU.h"
#include "TestFS.h"
#include "index/FileIndex.h"
#include "index/MemIndex.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Frontend/Utils.h"

using namespace llvm;
namespace clang {
namespace clangd {

ParsedAST TestTU::build() const {
  std::string FullFilename = testPath(Filename),
              FullHeaderName = testPath(HeaderFilename);
  std::vector<const char *> Cmd = {"clang", FullFilename.c_str()};
  // FIXME: this shouldn't need to be conditional, but it breaks a
  // GoToDefinition test for some reason (getMacroArgExpandedLocation fails).
  if (!HeaderCode.empty()) {
    Cmd.push_back("-include");
    Cmd.push_back(FullHeaderName.c_str());
  }
  Cmd.insert(Cmd.end(), ExtraArgs.begin(), ExtraArgs.end());
  ParseInputs Inputs;
  Inputs.CompileCommand.Filename = FullFilename;
  Inputs.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()};
  Inputs.CompileCommand.Directory = testRoot();
  Inputs.Contents = Code;
  Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}});
  auto PCHs = std::make_shared<PCHContainerOperations>();
  auto CI = buildCompilerInvocation(Inputs);
  assert(CI && "Failed to build compilation invocation.");
  auto Preamble =
      buildPreamble(FullFilename, *CI,
                    /*OldPreamble=*/nullptr,
                    /*OldCompileCommand=*/Inputs.CompileCommand, Inputs, PCHs,
                    /*StoreInMemory=*/true, /*PreambleCallback=*/nullptr);
  auto AST = buildAST(FullFilename, createInvocationFromCommandLine(Cmd),
                      Inputs, Preamble, PCHs);
  if (!AST.hasValue()) {
    ADD_FAILURE() << "Failed to build code:\n" << Code;
    llvm_unreachable("Failed to build TestTU!");
  }
  return std::move(*AST);
}

SymbolSlab TestTU::headerSymbols() const {
  auto AST = build();
  return indexHeaderSymbols(AST.getASTContext(), AST.getPreprocessorPtr());
}

std::unique_ptr<SymbolIndex> TestTU::index() const {
  auto AST = build();
  auto Idx = llvm::make_unique<FileIndex>(/*UseDex=*/true);
  Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr());
  Idx->updateMain(Filename, AST);
  return std::move(Idx);
}

const Symbol &findSymbol(const SymbolSlab &Slab, StringRef QName) {
  const Symbol *Result = nullptr;
  for (const Symbol &S : Slab) {
    if (QName != (S.Scope + S.Name).str())
      continue;
    if (Result) {
      ADD_FAILURE() << "Multiple symbols named " << QName << ":\n"
                    << *Result << "\n---\n"
                    << S;
      assert(false && "QName is not unique");
    }
    Result = &S;
  }
  if (!Result) {
    ADD_FAILURE() << "No symbol named " << QName << " in "
                  << ::testing::PrintToString(Slab);
    assert(false && "No symbol with QName");
  }
  return *Result;
}

const NamedDecl &findDecl(ParsedAST &AST, StringRef QName) {
  SmallVector<StringRef, 4> Components;
  QName.split(Components, "::");

  auto &Ctx = AST.getASTContext();
  auto LookupDecl = [&Ctx](const DeclContext &Scope,
                           StringRef Name) -> const NamedDecl & {
    auto LookupRes = Scope.lookup(DeclarationName(&Ctx.Idents.get(Name)));
    assert(!LookupRes.empty() && "Lookup failed");
    assert(LookupRes.size() == 1 && "Lookup returned multiple results");
    return *LookupRes.front();
  };

  const DeclContext *Scope = Ctx.getTranslationUnitDecl();
  for (auto NameIt = Components.begin(), End = Components.end() - 1;
       NameIt != End; ++NameIt) {
    Scope = &cast<DeclContext>(LookupDecl(*Scope, *NameIt));
  }
  return LookupDecl(*Scope, Components.back());
}

const NamedDecl &findDecl(ParsedAST &AST,
                          std::function<bool(const NamedDecl &)> Filter) {
  struct Visitor : RecursiveASTVisitor<Visitor> {
    decltype(Filter) F;
    SmallVector<const NamedDecl *, 1> Decls;
    bool VisitNamedDecl(const NamedDecl *ND) {
      if (F(*ND))
        Decls.push_back(ND);
      return true;
    }
  } Visitor;
  Visitor.F = Filter;
  Visitor.TraverseDecl(AST.getASTContext().getTranslationUnitDecl());
  if (Visitor.Decls.size() != 1) {
    ADD_FAILURE() << Visitor.Decls.size() << " symbols matched.";
    assert(Visitor.Decls.size() == 1);
  }
  return *Visitor.Decls.front();
}

const NamedDecl &findUnqualifiedDecl(ParsedAST &AST, StringRef Name) {
  return findDecl(AST, [Name](const NamedDecl &ND) {
    if (auto *ID = ND.getIdentifier())
      if (ID->getName() == Name)
        return true;
    return false;
  });
}

} // namespace clangd
} // namespace clang
<|endoftext|>