<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/cpu/backend/x64/x64_code_cache.h"

#include <cstdlib>
#include <cstring>

#if ENABLE_VTUNE
#include "third_party/vtune/include/jitprofiling.h"
#pragma comment(lib, "../third_party/vtune/lib64/jitprofiling.lib")
#endif

#include "xenia/base/assert.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/memory.h"
#include "xenia/cpu/function.h"
#include "xenia/cpu/module.h"

namespace xe {
namespace cpu {
namespace backend {
namespace x64 {

X64CodeCache::X64CodeCache() = default;

X64CodeCache::~X64CodeCache() {
  if (indirection_table_base_) {
    xe::memory::DeallocFixed(indirection_table_base_, 0,
                             xe::memory::DeallocationType::kRelease);
  }

  // Unmap all views and close mapping.
  if (mapping_) {
    xe::memory::UnmapFileView(mapping_, generated_code_base_,
                              kGeneratedCodeSize);
    xe::memory::CloseFileMappingHandle(mapping_);
    mapping_ = nullptr;
  }
}

bool X64CodeCache::Initialize() {
  indirection_table_base_ = reinterpret_cast<uint8_t*>(xe::memory::AllocFixed(
      reinterpret_cast<void*>(kIndirectionTableBase), kIndirectionTableSize,
      xe::memory::AllocationType::kReserve,
      xe::memory::PageAccess::kReadWrite));
  if (!indirection_table_base_) {
    XELOGE("Unable to allocate code cache indirection table");
    XELOGE(
        "This is likely because the %.8X-%.8X range is in use by some other "
        "system DLL",
        kIndirectionTableBase, kIndirectionTableBase + kIndirectionTableSize);
  }

  // Create mmap file. This allows us to share the code cache with the debugger.
  file_name_ = std::wstring(L"Local\\xenia_code_cache_") +
               std::to_wstring(Clock::QueryHostTickCount());
  mapping_ = xe::memory::CreateFileMappingHandle(
      file_name_, kGeneratedCodeSize, xe::memory::PageAccess::kExecuteReadWrite,
      false);
  if (!mapping_) {
    XELOGE("Unable to create code cache mmap");
    return false;
  }

  // Map generated code region into the file. Pages are committed as required.
  generated_code_base_ = reinterpret_cast<uint8_t*>(xe::memory::MapFileView(
      mapping_, reinterpret_cast<void*>(kGeneratedCodeBase), kGeneratedCodeSize,
      xe::memory::PageAccess::kExecuteReadWrite, 0));
  if (!generated_code_base_) {
    XELOGE("Unable to allocate code cache generated code storage");
    XELOGE(
        "This is likely because the %.8X-%.8X range is in use by some other "
        "system DLL",
        kGeneratedCodeBase, kGeneratedCodeBase + kGeneratedCodeSize);
    return false;
  }

  // Preallocate the function map to a large, reasonable size.
  generated_code_map_.reserve(kMaximumFunctionCount);

  return true;
}

void X64CodeCache::set_indirection_default(uint32_t default_value) {
  indirection_default_value_ = default_value;
}

void X64CodeCache::AddIndirection(uint32_t guest_address,
                                  uint32_t host_address) {
  if (!indirection_table_base_) {
    return;
  }

  uint32_t* indirection_slot = reinterpret_cast<uint32_t*>(
      indirection_table_base_ + (guest_address - kIndirectionTableBase));
  *indirection_slot = host_address;
}

void X64CodeCache::CommitExecutableRange(uint32_t guest_low,
                                         uint32_t guest_high) {
  if (!indirection_table_base_) {
    return;
  }

  // Commit the memory.
  xe::memory::AllocFixed(
      indirection_table_base_ + (guest_low - kIndirectionTableBase),
      guest_high - guest_low, xe::memory::AllocationType::kCommit,
      xe::memory::PageAccess::kExecuteReadWrite);

  // Fill memory with the default value.
  uint32_t* p = reinterpret_cast<uint32_t*>(indirection_table_base_);
  for (uint32_t address = guest_low; address < guest_high; ++address) {
    p[(address - kIndirectionTableBase) / 4] = indirection_default_value_;
  }
}

void* X64CodeCache::PlaceHostCode(uint32_t guest_address, void* machine_code,
                                  size_t code_size, size_t stack_size) {
  // Same for now. We may use different pools or whatnot later on, like when
  // we only want to place guest code in a serialized cache on disk.
  return PlaceGuestCode(guest_address, machine_code, code_size, stack_size,
                        nullptr);
}

void* X64CodeCache::PlaceGuestCode(uint32_t guest_address, void* machine_code,
                                   size_t code_size, size_t stack_size,
                                   GuestFunction* function_info) {
  // Hold a lock while we bump the pointers up. This is important as the
  // unwind table requires entries AND code to be sorted in order.
  size_t low_mark;
  size_t high_mark;
  uint8_t* code_address = nullptr;
  UnwindReservation unwind_reservation;
  {
    auto global_lock = global_critical_region_.Acquire();

    low_mark = generated_code_offset_;

    // Reserve code.
    // Always move the code to land on 16b alignment.
    code_address = generated_code_base_ + generated_code_offset_;
    generated_code_offset_ += xe::round_up(code_size, 16);

    // Reserve unwind info.
    // We go on the high size of the unwind info as we don't know how big we
    // need it, and a few extra bytes of padding isn't the worst thing.
    unwind_reservation =
        RequestUnwindReservation(generated_code_base_ + generated_code_offset_);
    generated_code_offset_ += unwind_reservation.data_size;

    high_mark = generated_code_offset_;

    // Store in map. It is maintained in sorted order of host PC dependent on
    // us also being append-only.
    generated_code_map_.emplace_back(
        (uint64_t(code_address - generated_code_base_) << 32) |
            generated_code_offset_,
        function_info);

    // TODO(DrChat): The following code doesn't really need to be under the
    // global lock except for PlaceCode (but it depends on the previous code
    // already being ran)

    // If we are going above the high water mark of committed memory, commit
    // some more. It's ok if multiple threads do this, as redundant commits
    // aren't harmful.
    size_t old_commit_mark = generated_code_commit_mark_;
    if (high_mark > old_commit_mark) {
      size_t new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
      xe::memory::AllocFixed(generated_code_base_, new_commit_mark,
                             xe::memory::AllocationType::kCommit,
                             xe::memory::PageAccess::kExecuteReadWrite);
      generated_code_commit_mark_.compare_exchange_strong(old_commit_mark,
                                                          new_commit_mark);
    }

    // Copy code.
    std::memcpy(code_address, machine_code, code_size);

    // Fill unused slots with 0xCC
    std::memset(
        code_address + code_size, 0xCC,
        xe::round_up(code_size + unwind_reservation.data_size, 16) - code_size);

    // Notify subclasses of placed code.
    PlaceCode(guest_address, machine_code, code_size, stack_size, code_address,
              unwind_reservation);
  }

#if ENABLE_VTUNE
  if (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON) {
    std::string method_name;
    if (function_info && function_info->name().size() != 0) {
      method_name = function_info->name();
    } else {
      method_name = xe::format_string("sub_%.8X", guest_address);
    }

    iJIT_Method_Load_V2 method = {0};
    method.method_id = iJIT_GetNewMethodID();
    method.method_load_address = code_address;
    method.method_size = uint32_t(code_size);
    method.method_name = const_cast<char*>(method_name.data());
    method.module_name = function_info
                             ? (char*)function_info->module()->name().c_str()
                             : nullptr;
    iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, (void*)&method);
  }
#endif

  // Now that everything is ready, fix up the indirection table.
  // Note that we do support code that doesn't have an indirection fixup, so
  // ignore those when we see them.
  if (guest_address && indirection_table_base_) {
    uint32_t* indirection_slot = reinterpret_cast<uint32_t*>(
        indirection_table_base_ + (guest_address - kIndirectionTableBase));
    *indirection_slot = uint32_t(reinterpret_cast<uint64_t>(code_address));
  }

  return code_address;
}

uint32_t X64CodeCache::PlaceData(const void* data, size_t length) {
  // Hold a lock while we bump the pointers up.
  size_t high_mark;
  uint8_t* data_address = nullptr;
  {
    auto global_lock = global_critical_region_.Acquire();

    // Reserve code.
    // Always move the code to land on 16b alignment.
    data_address = generated_code_base_ + generated_code_offset_;
    generated_code_offset_ += xe::round_up(length, 16);

    high_mark = generated_code_offset_;
  }

  // If we are going above the high water mark of committed memory, commit some
  // more. It's ok if multiple threads do this, as redundant commits aren't
  // harmful.
  size_t old_commit_mark = generated_code_commit_mark_;
  if (high_mark > old_commit_mark) {
    size_t new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
    xe::memory::AllocFixed(generated_code_base_, new_commit_mark,
                           xe::memory::AllocationType::kCommit,
                           xe::memory::PageAccess::kExecuteReadWrite);
    generated_code_commit_mark_.compare_exchange_strong(old_commit_mark,
                                                        new_commit_mark);
  }

  // Copy code.
  std::memcpy(data_address, data, length);

  return uint32_t(uintptr_t(data_address));
}

GuestFunction* X64CodeCache::LookupFunction(uint64_t host_pc) {
  uint32_t key = uint32_t(host_pc - kGeneratedCodeBase);
  void* fn_entry = std::bsearch(
      &key, generated_code_map_.data(), generated_code_map_.size() + 1,
      sizeof(std::pair<uint32_t, Function*>),
      [](const void* key_ptr, const void* element_ptr) {
        auto key = *reinterpret_cast<const uint32_t*>(key_ptr);
        auto element =
            reinterpret_cast<const std::pair<uint64_t, GuestFunction*>*>(
                element_ptr);
        if (key < (element->first >> 32)) {
          return -1;
        } else if (key > uint32_t(element->first)) {
          return 1;
        } else {
          return 0;
        }
      });
  if (fn_entry) {
    return reinterpret_cast<const std::pair<uint64_t, GuestFunction*>*>(
               fn_entry)
        ->second;
  } else {
    return nullptr;
  }
}

}  // namespace x64
}  // namespace backend
}  // namespace cpu
}  // namespace xe
<commit_msg>[x64] Fix improper use of compare_exchange_strong when adjusting code commit mark<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 Ben Vanik. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include "xenia/cpu/backend/x64/x64_code_cache.h"

#include <cstdlib>
#include <cstring>

#if ENABLE_VTUNE
#include "third_party/vtune/include/jitprofiling.h"
#pragma comment(lib, "../third_party/vtune/lib64/jitprofiling.lib")
#endif

#include "xenia/base/assert.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/memory.h"
#include "xenia/cpu/function.h"
#include "xenia/cpu/module.h"

namespace xe {
namespace cpu {
namespace backend {
namespace x64 {

X64CodeCache::X64CodeCache() = default;

X64CodeCache::~X64CodeCache() {
  if (indirection_table_base_) {
    xe::memory::DeallocFixed(indirection_table_base_, 0,
                             xe::memory::DeallocationType::kRelease);
  }

  // Unmap all views and close mapping.
  if (mapping_) {
    xe::memory::UnmapFileView(mapping_, generated_code_base_,
                              kGeneratedCodeSize);
    xe::memory::CloseFileMappingHandle(mapping_);
    mapping_ = nullptr;
  }
}

bool X64CodeCache::Initialize() {
  indirection_table_base_ = reinterpret_cast<uint8_t*>(xe::memory::AllocFixed(
      reinterpret_cast<void*>(kIndirectionTableBase), kIndirectionTableSize,
      xe::memory::AllocationType::kReserve,
      xe::memory::PageAccess::kReadWrite));
  if (!indirection_table_base_) {
    XELOGE("Unable to allocate code cache indirection table");
    XELOGE(
        "This is likely because the %.8X-%.8X range is in use by some other "
        "system DLL",
        kIndirectionTableBase, kIndirectionTableBase + kIndirectionTableSize);
  }

  // Create mmap file. This allows us to share the code cache with the debugger.
  file_name_ = std::wstring(L"Local\\xenia_code_cache_") +
               std::to_wstring(Clock::QueryHostTickCount());
  mapping_ = xe::memory::CreateFileMappingHandle(
      file_name_, kGeneratedCodeSize, xe::memory::PageAccess::kExecuteReadWrite,
      false);
  if (!mapping_) {
    XELOGE("Unable to create code cache mmap");
    return false;
  }

  // Map generated code region into the file. Pages are committed as required.
  generated_code_base_ = reinterpret_cast<uint8_t*>(xe::memory::MapFileView(
      mapping_, reinterpret_cast<void*>(kGeneratedCodeBase), kGeneratedCodeSize,
      xe::memory::PageAccess::kExecuteReadWrite, 0));
  if (!generated_code_base_) {
    XELOGE("Unable to allocate code cache generated code storage");
    XELOGE(
        "This is likely because the %.8X-%.8X range is in use by some other "
        "system DLL",
        kGeneratedCodeBase, kGeneratedCodeBase + kGeneratedCodeSize);
    return false;
  }

  // Preallocate the function map to a large, reasonable size.
  generated_code_map_.reserve(kMaximumFunctionCount);

  return true;
}

void X64CodeCache::set_indirection_default(uint32_t default_value) {
  indirection_default_value_ = default_value;
}

void X64CodeCache::AddIndirection(uint32_t guest_address,
                                  uint32_t host_address) {
  if (!indirection_table_base_) {
    return;
  }

  uint32_t* indirection_slot = reinterpret_cast<uint32_t*>(
      indirection_table_base_ + (guest_address - kIndirectionTableBase));
  *indirection_slot = host_address;
}

void X64CodeCache::CommitExecutableRange(uint32_t guest_low,
                                         uint32_t guest_high) {
  if (!indirection_table_base_) {
    return;
  }

  // Commit the memory.
  xe::memory::AllocFixed(
      indirection_table_base_ + (guest_low - kIndirectionTableBase),
      guest_high - guest_low, xe::memory::AllocationType::kCommit,
      xe::memory::PageAccess::kExecuteReadWrite);

  // Fill memory with the default value.
  uint32_t* p = reinterpret_cast<uint32_t*>(indirection_table_base_);
  for (uint32_t address = guest_low; address < guest_high; ++address) {
    p[(address - kIndirectionTableBase) / 4] = indirection_default_value_;
  }
}

void* X64CodeCache::PlaceHostCode(uint32_t guest_address, void* machine_code,
                                  size_t code_size, size_t stack_size) {
  // Same for now. We may use different pools or whatnot later on, like when
  // we only want to place guest code in a serialized cache on disk.
  return PlaceGuestCode(guest_address, machine_code, code_size, stack_size,
                        nullptr);
}

void* X64CodeCache::PlaceGuestCode(uint32_t guest_address, void* machine_code,
                                   size_t code_size, size_t stack_size,
                                   GuestFunction* function_info) {
  // Hold a lock while we bump the pointers up. This is important as the
  // unwind table requires entries AND code to be sorted in order.
  size_t low_mark;
  size_t high_mark;
  uint8_t* code_address = nullptr;
  UnwindReservation unwind_reservation;
  {
    auto global_lock = global_critical_region_.Acquire();

    low_mark = generated_code_offset_;

    // Reserve code.
    // Always move the code to land on 16b alignment.
    code_address = generated_code_base_ + generated_code_offset_;
    generated_code_offset_ += xe::round_up(code_size, 16);

    // Reserve unwind info.
    // We go on the high size of the unwind info as we don't know how big we
    // need it, and a few extra bytes of padding isn't the worst thing.
    unwind_reservation =
        RequestUnwindReservation(generated_code_base_ + generated_code_offset_);
    generated_code_offset_ += unwind_reservation.data_size;

    high_mark = generated_code_offset_;

    // Store in map. It is maintained in sorted order of host PC dependent on
    // us also being append-only.
    generated_code_map_.emplace_back(
        (uint64_t(code_address - generated_code_base_) << 32) |
            generated_code_offset_,
        function_info);

    // TODO(DrChat): The following code doesn't really need to be under the
    // global lock except for PlaceCode (but it depends on the previous code
    // already being ran)

    // If we are going above the high water mark of committed memory, commit
    // some more. It's ok if multiple threads do this, as redundant commits
    // aren't harmful.
    size_t old_commit_mark, new_commit_mark;
    do {
      old_commit_mark = generated_code_commit_mark_;
      if (high_mark <= old_commit_mark) break;

      new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
      xe::memory::AllocFixed(generated_code_base_, new_commit_mark,
                             xe::memory::AllocationType::kCommit,
                             xe::memory::PageAccess::kExecuteReadWrite);
    } while (generated_code_commit_mark_.compare_exchange_weak(
        old_commit_mark, new_commit_mark));

    // Copy code.
    std::memcpy(code_address, machine_code, code_size);

    // Fill unused slots with 0xCC
    std::memset(
        code_address + code_size, 0xCC,
        xe::round_up(code_size + unwind_reservation.data_size, 16) - code_size);

    // Notify subclasses of placed code.
    PlaceCode(guest_address, machine_code, code_size, stack_size, code_address,
              unwind_reservation);
  }

#if ENABLE_VTUNE
  if (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON) {
    std::string method_name;
    if (function_info && function_info->name().size() != 0) {
      method_name = function_info->name();
    } else {
      method_name = xe::format_string("sub_%.8X", guest_address);
    }

    iJIT_Method_Load_V2 method = {0};
    method.method_id = iJIT_GetNewMethodID();
    method.method_load_address = code_address;
    method.method_size = uint32_t(code_size);
    method.method_name = const_cast<char*>(method_name.data());
    method.module_name = function_info
                             ? (char*)function_info->module()->name().c_str()
                             : nullptr;
    iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2, (void*)&method);
  }
#endif

  // Now that everything is ready, fix up the indirection table.
  // Note that we do support code that doesn't have an indirection fixup, so
  // ignore those when we see them.
  if (guest_address && indirection_table_base_) {
    uint32_t* indirection_slot = reinterpret_cast<uint32_t*>(
        indirection_table_base_ + (guest_address - kIndirectionTableBase));
    *indirection_slot = uint32_t(reinterpret_cast<uint64_t>(code_address));
  }

  return code_address;
}

uint32_t X64CodeCache::PlaceData(const void* data, size_t length) {
  // Hold a lock while we bump the pointers up.
  size_t high_mark;
  uint8_t* data_address = nullptr;
  {
    auto global_lock = global_critical_region_.Acquire();

    // Reserve code.
    // Always move the code to land on 16b alignment.
    data_address = generated_code_base_ + generated_code_offset_;
    generated_code_offset_ += xe::round_up(length, 16);

    high_mark = generated_code_offset_;
  }

  // If we are going above the high water mark of committed memory, commit some
  // more. It's ok if multiple threads do this, as redundant commits aren't
  // harmful.
  size_t old_commit_mark, new_commit_mark;
  do {
    old_commit_mark = generated_code_commit_mark_;
    if (high_mark <= old_commit_mark) break;

    new_commit_mark = old_commit_mark + 16 * 1024 * 1024;
    xe::memory::AllocFixed(generated_code_base_, new_commit_mark,
                           xe::memory::AllocationType::kCommit,
                           xe::memory::PageAccess::kExecuteReadWrite);
  } while (generated_code_commit_mark_.compare_exchange_weak(old_commit_mark,
                                                             new_commit_mark));

  // Copy code.
  std::memcpy(data_address, data, length);

  return uint32_t(uintptr_t(data_address));
}

GuestFunction* X64CodeCache::LookupFunction(uint64_t host_pc) {
  uint32_t key = uint32_t(host_pc - kGeneratedCodeBase);
  void* fn_entry = std::bsearch(
      &key, generated_code_map_.data(), generated_code_map_.size() + 1,
      sizeof(std::pair<uint32_t, Function*>),
      [](const void* key_ptr, const void* element_ptr) {
        auto key = *reinterpret_cast<const uint32_t*>(key_ptr);
        auto element =
            reinterpret_cast<const std::pair<uint64_t, GuestFunction*>*>(
                element_ptr);
        if (key < (element->first >> 32)) {
          return -1;
        } else if (key > uint32_t(element->first)) {
          return 1;
        } else {
          return 0;
        }
      });
  if (fn_entry) {
    return reinterpret_cast<const std::pair<uint64_t, GuestFunction*>*>(
               fn_entry)
        ->second;
  } else {
    return nullptr;
  }
}

}  // namespace x64
}  // namespace backend
}  // namespace cpu
}  // namespace xe
<|endoftext|>


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

   Program:   ORFEO Toolbox
   Language:  C++
   Date:      $Date$
   Version:   $Revision$

   Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
   See OTBCopyright.txt for details.

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

 =========================================================================*/
#include "otbCommandLineArgumentParser.h"
#include "otbOSMDataToVectorDataGenerator.h"
#include "otbVectorDataFileWriter.h"

typedef otb::OSMDataToVectorDataGenerator                     FilterType;
typedef otb::VectorDataFileWriter<FilterType::VectorDataType> VectorDataFileWriterType;

int otbOSMToVectorDataGeneratorNew (int argc, char * argv[])
{
  FilterType::Pointer filter = FilterType::New();

  return EXIT_SUCCESS;
}

int otbOSMToVectorDataGeneratorTest (int argc, char * argv[])
{
  FilterType::Pointer filter = FilterType::New();
  filter->SetFileName(argv[1]);
  filter->SetUseUrl(false);
  filter->Update();

  // Write the IndexTile
  VectorDataFileWriterType::Pointer writer = VectorDataFileWriterType::New();
  writer->SetInput(filter->GetVectorDataByName("building"));
  writer->SetFileName(argv[2]);
  writer->Update();

  return EXIT_SUCCESS;
}

int otbOSMToVectorDataGeneratorByName (int argc, char * argv[])
{
  // Parse command line parameters
  typedef otb::CommandLineArgumentParser ParserType;
  ParserType::Pointer parser = ParserType::New();
  parser->AddOption("--OSMFile","The osm file containig the points to extract",
                    "-osm", 1, true);

  parser->AddOption("--OutputVectorData","The output vectordata",
                    "-vd", 1, true);

  typedef otb::CommandLineArgumentParseResult ParserResultType;
  ParserResultType::Pointer  parseResult = ParserResultType::New();

  try
    {
    parser->ParseCommandLine(argc, argv, parseResult);
    }
  catch ( itk::ExceptionObject )
    {
    return EXIT_FAILURE;
    }

  FilterType::Pointer filter = FilterType::New();
  filter->SetFileName(parseResult->GetParameterString("--OSMFile"));
  filter->SetUseUrl(false);
  filter->Update();

  const FilterType::VectorDataType*  v1 = filter->GetVectorDataByName("waterway");
  std::cout <<"Size of the vectordata v1 : "<< v1->Size() << std::endl;

  const FilterType::VectorDataType*  v2 = filter->GetVectorDataByName("highway");
  std::cout <<"Size of the vectordata v2 : "<< v2->Size() << std::endl;

  const FilterType::VectorDataType*  v3 = filter->GetVectorDataByName("building");
  std::cout <<"Size of the vectordata v3 : "<< v3->Size() << std::endl;

  const FilterType::VectorDataType*  v4 = filter->GetVectorDataByName("highway","motorway_link");
  std::cout <<"Size of the vectordata v4 : "<< v4->Size() << std::endl;

  // Write the VectorData
  VectorDataFileWriterType::Pointer writer = VectorDataFileWriterType::New();
  writer->SetFileName(parseResult->GetParameterString("--OutputVectorData"));
  writer->SetInput(v4);
  writer->Update();

  return EXIT_SUCCESS;
}
<commit_msg>ENH : use the methods Set{West,East,North,South} in the tests<commit_after>/*=========================================================================

   Program:   ORFEO Toolbox
   Language:  C++
   Date:      $Date$
   Version:   $Revision$

   Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
   See OTBCopyright.txt for details.

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

 =========================================================================*/
#include "otbCommandLineArgumentParser.h"
#include "otbOSMDataToVectorDataGenerator.h"
#include "otbVectorDataFileWriter.h"

typedef otb::OSMDataToVectorDataGenerator                     FilterType;
typedef otb::VectorDataFileWriter<FilterType::VectorDataType> VectorDataFileWriterType;

int otbOSMToVectorDataGeneratorNew (int argc, char * argv[])
{
  FilterType::Pointer filter = FilterType::New();

  return EXIT_SUCCESS;
}

int otbOSMToVectorDataGeneratorTest (int argc, char * argv[])
{
  FilterType::Pointer filter = FilterType::New();
  filter->SetFileName(argv[1]);
  filter->SetUseUrl(false);
  filter->SetNorth(43.62811);
  filter->SetSouth(43.60185);
  filter->SetWest(1.54911);
  filter->SetEast(1.59323);
  filter->Update();

  // Write the IndexTile
  VectorDataFileWriterType::Pointer writer = VectorDataFileWriterType::New();
  writer->SetInput(filter->GetVectorDataByName("building"));
  writer->SetFileName(argv[2]);
  writer->Update();

  return EXIT_SUCCESS;
}

int otbOSMToVectorDataGeneratorByName (int argc, char * argv[])
{
  // Parse command line parameters
  typedef otb::CommandLineArgumentParser ParserType;
  ParserType::Pointer parser = ParserType::New();
  parser->AddOption("--OSMFile","The osm file containig the points to extract",
                    "-osm", 1, true);

  parser->AddOption("--OutputVectorData","The output vectordata",
                    "-vd", 1, true);

  typedef otb::CommandLineArgumentParseResult ParserResultType;
  ParserResultType::Pointer  parseResult = ParserResultType::New();

  try
    {
    parser->ParseCommandLine(argc, argv, parseResult);
    }
  catch ( itk::ExceptionObject )
    {
    return EXIT_FAILURE;
    }

  FilterType::Pointer filter = FilterType::New();
  filter->SetFileName(parseResult->GetParameterString("--OSMFile"));
  filter->SetUseUrl(false);

  // Set the extent of the request
  filter->SetNorth(43.62811);
  filter->SetSouth(43.60185);
  filter->SetWest(1.54911);
  filter->SetEast(1.59323);

  filter->Update();

  const FilterType::VectorDataType*  v1 = filter->GetVectorDataByName("waterway");
  std::cout <<"Size of the vectordata v1 : "<< v1->Size() << std::endl;

  const FilterType::VectorDataType*  v2 = filter->GetVectorDataByName("highway");
  std::cout <<"Size of the vectordata v2 : "<< v2->Size() << std::endl;

  const FilterType::VectorDataType*  v3 = filter->GetVectorDataByName("building");
  std::cout <<"Size of the vectordata v3 : "<< v3->Size() << std::endl;

  const FilterType::VectorDataType*  v4 = filter->GetVectorDataByName("highway","motorway_link");
  std::cout <<"Size of the vectordata v4 : "<< v4->Size() << std::endl;

  // Write the VectorData
  VectorDataFileWriterType::Pointer writer = VectorDataFileWriterType::New();
  writer->SetFileName(parseResult->GetParameterString("--OutputVectorData"));
  writer->SetInput(v4);
  writer->Update();

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>
#include <iostream>

//#include "assimp/Importer.hpp"
//#include "assimp/postprocess.h"
//#include "assimp/scene.h"
//#include "assimp/cimport.h"

#include <fbxsdk.h>

using namespace std;

#include "common.h"

int main (int argc, char *argv[])
{
    cout << "Loading file with fbxsdk" << endl;

    const char* filename = "model.fbx";
    FbxScene* scene = Load(filename);
    PrintObject(scene);

    return 0;
}

FbxScene* Load(const char* filename, FbxManager* manager)
{
    if (manager == NULL)
    {
        manager = FbxManager::Create();
    }

    FbxScene* pScene = FbxScene::Create(manager, "My Scene");

    int lFileMajor, lFileMinor, lFileRevision;
    int lSDKMajor,  lSDKMinor,  lSDKRevision;
    //int lFileFormat = -1;
    int i, lAnimStackCount;
    bool lStatus;
    char lPassword[1024];

    // Get the file version number generate by the FBX SDK.
    FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);

    // Create an importer.
    FbxImporter* lImporter = FbxImporter::Create(manager,"");

    // Initialize the importer by providing a filename.
    const bool lImportStatus = lImporter->Initialize(filename, -1, manager->GetIOSettings());
    lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);

    if( !lImportStatus )
    {
        FBXSDK_printf("Call to FbxImporter::Initialize() failed.\n");
        FBXSDK_printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString());

//        if (lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedYet ||
//            lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedAnymore)
//        {
            FBXSDK_printf("FBX file format version for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision);
            FBXSDK_printf("FBX file format version for file '%s' is %d.%d.%d\n\n", filename, lFileMajor, lFileMinor, lFileRevision);
//        }

        exit(-1);
    }

    lImporter->Import(pScene);

    printf("file version info: %i.%i.%i\n", lFileMajor, lFileMinor, lFileRevision);

    return pScene;
}
<commit_msg>Manually construct a scene and node.<commit_after>
#include <iostream>

//#include "assimp/Importer.hpp"
//#include "assimp/postprocess.h"
//#include "assimp/scene.h"
//#include "assimp/cimport.h"

#include <fbxsdk.h>

using namespace std;

#include "common.h"

int main (int argc, char *argv[])
{
    cout << "Loading file with fbxsdk" << endl;

//    const char* filename = "model.fbx";
//    FbxScene* scene = Load(filename);

    FbxManager* manager = FbxManager::Create();

    FbxScene* scene = FbxScene::Create(manager, "TheScene");

    FbxNode* root = scene->GetRootNode();

    FbxNode* node2 = FbxNode::Create(manager, "ChildNode");

    PrintObject(root);
    PrintObject(node2);

    cout << "------------------------------------------------" << endl;

    root->AddChild(node2);

    PrintObject(root);
    PrintObject(node2);

    return 0;
}

FbxScene* Load(const char* filename, FbxManager* manager)
{
    if (manager == NULL)
    {
        manager = FbxManager::Create();
    }

    FbxScene* pScene = FbxScene::Create(manager, "My Scene");

    int lFileMajor, lFileMinor, lFileRevision;
    int lSDKMajor,  lSDKMinor,  lSDKRevision;
    //int lFileFormat = -1;
    int i, lAnimStackCount;
    bool lStatus;
    char lPassword[1024];

    // Get the file version number generate by the FBX SDK.
    FbxManager::GetFileFormatVersion(lSDKMajor, lSDKMinor, lSDKRevision);

    // Create an importer.
    FbxImporter* lImporter = FbxImporter::Create(manager,"");

    // Initialize the importer by providing a filename.
    const bool lImportStatus = lImporter->Initialize(filename, -1, manager->GetIOSettings());
    lImporter->GetFileVersion(lFileMajor, lFileMinor, lFileRevision);

    if( !lImportStatus )
    {
        FBXSDK_printf("Call to FbxImporter::Initialize() failed.\n");
        FBXSDK_printf("Error returned: %s\n\n", lImporter->GetStatus().GetErrorString());

//        if (lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedYet ||
//            lImporter->GetLastErrorID() == FbxIOBase::eFileVersionNotSupportedAnymore)
//        {
            FBXSDK_printf("FBX file format version for this FBX SDK is %d.%d.%d\n", lSDKMajor, lSDKMinor, lSDKRevision);
            FBXSDK_printf("FBX file format version for file '%s' is %d.%d.%d\n\n", filename, lFileMajor, lFileMinor, lFileRevision);
//        }

        exit(-1);
    }

    lImporter->Import(pScene);

    printf("file version info: %i.%i.%i\n", lFileMajor, lFileMinor, lFileRevision);

    return pScene;
}
<|endoftext|>


<commit_before>#ifndef SpMVAcceleratorDriver_H
#define SpMVAcceleratorDriver_H
#include <assert.h>
class SpMVAcceleratorDriver {
public:
 SpMVAcceleratorDriver(volatile unsigned int * baseAddr) {
  m_baseAddr = baseAddr; assert(signature() == m_signature);};
 // read+write register: startInit index: 4
 void startInit(unsigned int v) {m_baseAddr[4] = v;};
 unsigned int startInit() {return m_baseAddr[4];};
 // read+write register: startRegular index: 5
 void startRegular(unsigned int v) {m_baseAddr[5] = v;};
 unsigned int startRegular() {return m_baseAddr[5];};
 // read+write register: startWrite index: 6
 void startWrite(unsigned int v) {m_baseAddr[6] = v;};
 unsigned int startWrite() {return m_baseAddr[6];};
 // read+write register: numRows index: 7
 void numRows(unsigned int v) {m_baseAddr[7] = v;};
 unsigned int numRows() {return m_baseAddr[7];};
 // read+write register: numCols index: 8
 void numCols(unsigned int v) {m_baseAddr[8] = v;};
 unsigned int numCols() {return m_baseAddr[8];};
 // read+write register: numNZ index: 9
 void numNZ(unsigned int v) {m_baseAddr[9] = v;};
 unsigned int numNZ() {return m_baseAddr[9];};
 // read+write register: baseColPtr index: 10
 void baseColPtr(unsigned int v) {m_baseAddr[10] = v;};
 unsigned int baseColPtr() {return m_baseAddr[10];};
 // read+write register: baseRowInd index: 11
 void baseRowInd(unsigned int v) {m_baseAddr[11] = v;};
 unsigned int baseRowInd() {return m_baseAddr[11];};
 // read+write register: baseNZData index: 12
 void baseNZData(unsigned int v) {m_baseAddr[12] = v;};
 unsigned int baseNZData() {return m_baseAddr[12];};
 // read+write register: baseInputVec index: 13
 void baseInputVec(unsigned int v) {m_baseAddr[13] = v;};
 unsigned int baseInputVec() {return m_baseAddr[13];};
 // read+write register: baseOutputVec index: 14
 void baseOutputVec(unsigned int v) {m_baseAddr[14] = v;};
 unsigned int baseOutputVec() {return m_baseAddr[14];};
 // read+write register: thresColPtr index: 15
 void thresColPtr(unsigned int v) {m_baseAddr[15] = v;};
 unsigned int thresColPtr() {return m_baseAddr[15];};
 // read+write register: thresRowInd index: 16
 void thresRowInd(unsigned int v) {m_baseAddr[16] = v;};
 unsigned int thresRowInd() {return m_baseAddr[16];};
 // read+write register: thresNZData index: 17
 void thresNZData(unsigned int v) {m_baseAddr[17] = v;};
 unsigned int thresNZData() {return m_baseAddr[17];};
 // read+write register: thresInputVec index: 18
 void thresInputVec(unsigned int v) {m_baseAddr[18] = v;};
 unsigned int thresInputVec() {return m_baseAddr[18];};
 // read+write register: statBackend index: 1
 void statBackend(unsigned int v) {m_baseAddr[1] = v;};
 unsigned int statBackend() {return m_baseAddr[1];};
 // read+write register: statFrontend index: 2
 void statFrontend(unsigned int v) {m_baseAddr[2] = v;};
 unsigned int statFrontend() {return m_baseAddr[2];};
 // read+write register: hazardStalls index: 3
 void hazardStalls(unsigned int v) {m_baseAddr[3] = v;};
 unsigned int hazardStalls() {return m_baseAddr[3];};
 // read+write register: signature index: 0
 void signature(unsigned int v) {m_baseAddr[0] = v;};
 unsigned int signature() {return m_baseAddr[0];};

protected:
 volatile unsigned int * m_baseAddr;
 const static unsigned int m_signature = 0xcbbb437f;
};
#endif
<commit_msg>also update reg driver for bw mon stats<commit_after>#ifndef SpMVAcceleratorDriver_H
#define SpMVAcceleratorDriver_H
#include <assert.h>
class SpMVAcceleratorDriver {
public:
 SpMVAcceleratorDriver(volatile unsigned int * baseAddr) {
  m_baseAddr = baseAddr; assert(signature() == m_signature);};
 // read+write register: startInit index: 6
 void startInit(unsigned int v) {m_baseAddr[6] = v;};
 unsigned int startInit() {return m_baseAddr[6];};
 // read+write register: startRegular index: 7
 void startRegular(unsigned int v) {m_baseAddr[7] = v;};
 unsigned int startRegular() {return m_baseAddr[7];};
 // read+write register: startWrite index: 8
 void startWrite(unsigned int v) {m_baseAddr[8] = v;};
 unsigned int startWrite() {return m_baseAddr[8];};
 // read+write register: numRows index: 9
 void numRows(unsigned int v) {m_baseAddr[9] = v;};
 unsigned int numRows() {return m_baseAddr[9];};
 // read+write register: numCols index: 10
 void numCols(unsigned int v) {m_baseAddr[10] = v;};
 unsigned int numCols() {return m_baseAddr[10];};
 // read+write register: numNZ index: 11
 void numNZ(unsigned int v) {m_baseAddr[11] = v;};
 unsigned int numNZ() {return m_baseAddr[11];};
 // read+write register: baseColPtr index: 12
 void baseColPtr(unsigned int v) {m_baseAddr[12] = v;};
 unsigned int baseColPtr() {return m_baseAddr[12];};
 // read+write register: baseRowInd index: 13
 void baseRowInd(unsigned int v) {m_baseAddr[13] = v;};
 unsigned int baseRowInd() {return m_baseAddr[13];};
 // read+write register: baseNZData index: 14
 void baseNZData(unsigned int v) {m_baseAddr[14] = v;};
 unsigned int baseNZData() {return m_baseAddr[14];};
 // read+write register: baseInputVec index: 15
 void baseInputVec(unsigned int v) {m_baseAddr[15] = v;};
 unsigned int baseInputVec() {return m_baseAddr[15];};
 // read+write register: baseOutputVec index: 16
 void baseOutputVec(unsigned int v) {m_baseAddr[16] = v;};
 unsigned int baseOutputVec() {return m_baseAddr[16];};
 // read+write register: thresColPtr index: 17
 void thresColPtr(unsigned int v) {m_baseAddr[17] = v;};
 unsigned int thresColPtr() {return m_baseAddr[17];};
 // read+write register: thresRowInd index: 18
 void thresRowInd(unsigned int v) {m_baseAddr[18] = v;};
 unsigned int thresRowInd() {return m_baseAddr[18];};
 // read+write register: thresNZData index: 19
 void thresNZData(unsigned int v) {m_baseAddr[19] = v;};
 unsigned int thresNZData() {return m_baseAddr[19];};
 // read+write register: thresInputVec index: 20
 void thresInputVec(unsigned int v) {m_baseAddr[20] = v;};
 unsigned int thresInputVec() {return m_baseAddr[20];};
 // read+write register: statBackend index: 1
 void statBackend(unsigned int v) {m_baseAddr[1] = v;};
 unsigned int statBackend() {return m_baseAddr[1];};
 // read+write register: statFrontend index: 2
 void statFrontend(unsigned int v) {m_baseAddr[2] = v;};
 unsigned int statFrontend() {return m_baseAddr[2];};
 // read+write register: hazardStalls index: 3
 void hazardStalls(unsigned int v) {m_baseAddr[3] = v;};
 unsigned int hazardStalls() {return m_baseAddr[3];};
 // read+write register: bwMon_totalCycles index: 4
 void bwMon_totalCycles(unsigned int v) {m_baseAddr[4] = v;};
 unsigned int bwMon_totalCycles() {return m_baseAddr[4];};
 // read+write register: bwMon_activeCycles index: 5
 void bwMon_activeCycles(unsigned int v) {m_baseAddr[5] = v;};
 unsigned int bwMon_activeCycles() {return m_baseAddr[5];};
 // read+write register: signature index: 0
 void signature(unsigned int v) {m_baseAddr[0] = v;};
 unsigned int signature() {return m_baseAddr[0];};

protected:
 volatile unsigned int * m_baseAddr;
 const static unsigned int m_signature = 0x52b212c5;
};
#endif
<|endoftext|>


<commit_before>// @(#)root/proof:$Id$
// Author: Sangsu Ryu 22/06/2010

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSelHandleDataSet                                                    //
//                                                                      //
// PROOF selector for file cache release.                               //
// List of files to be cleaned for each node is provided by client.     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#define TSelHandleDataSet_cxx

#include "TSelHandleDataSet.h"

#include "TDSet.h"
#include "TEnv.h"
#include "TFile.h"
#include "TMap.h"
#include "TParameter.h"
#include "TProofBenchTypes.h"
#include "TSystem.h"
#include "TUrl.h"
#include "errno.h"
#include <unistd.h>
#include <fcntl.h>

ClassImp(TSelHandleDataSet)

//______________________________________________________________________________
void TSelHandleDataSet::SlaveBegin(TTree *)
{
   // Init the type from the input parameters

   TObject *o = fInput->FindObject("PROOF_Benchmark_HandleDSType");
   if (o) fType = dynamic_cast<TPBHandleDSType *>(o);

   TNamed *n = dynamic_cast<TNamed *>(fInput->FindObject("PROOF_Benchmark_DestDir"));
   if (n) {
      fDestDir = n->GetTitle();
      if (gSystem->AccessPathName(fDestDir)) {
         // Create the directory
         if (gSystem->mkdir(fDestDir, kTRUE) != 0) {
            fDestDir = "";
            Error("SlaveBegin", "could not create dir '%s'", fDestDir.Data());
         } else {
            if (gSystem->AccessPathName(fDestDir, kWritePermission)) {
               fDestDir = "";
               Error("SlaveBegin", "dir '%s' is not writable by this process", fDestDir.Data());
            } else {
               Info("SlaveBegin", "dir '%s' successfully created", fDestDir.Data());
            }
         }
      }
   }

   // Use default if nothing found in the input list
   if (!fType) fType = new TPBHandleDSType(TPBHandleDSType::kReleaseCache);
}

//______________________________________________________________________________
void TSelHandleDataSet::ReleaseCache(const char *fn)
{
   // Release the memory cache associated with file 'fn'.

#if defined(R__LINUX)
   TString filename(fn);
   Int_t fd;
   fd = open(filename.Data(), O_RDONLY);
   if (fd > -1) {
      fdatasync(fd);
      posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
      close(fd);
      Info("ReleaseCache", "file cache for file '%s' cleaned ...", filename.Data());
   } else {
      Error("ReleaseCache", "cannot open file '%s' for cache clean up; errno=%d",
                            filename.Data(), errno);
   }
#else
   Info("ReleaseCache", "dummy function: file '%s' untouched ...", fn);
#endif
   // Done
   return;
}

//______________________________________________________________________________
void TSelHandleDataSet::CheckCache(const char * /*fn*/)
{
   // Check the memory cache associated with file 'fn'.

   Warning("CheckCache", "cache checker not implemented yet");
   // Done
   return;
}

//______________________________________________________________________________
void TSelHandleDataSet::RemoveFile(const char *fn)
{
   // Physically remove the file 'fn'.

   if (!gSystem->AccessPathName(fn, kWritePermission)) {
      if (gSystem->Unlink(fn) != 0) {
         Error("RemoveFile", "problems removing file '%s' ...", fn);
      } else {
         if (!gSystem->AccessPathName(fn))
            Warning("RemoveFile", "'unlink' returned success but the file still exists ('%s')", fn);
      }
   } else {
      if (!gSystem->AccessPathName(fn)) {
         Error("RemoveFile", "file '%s' cannot removed by this process", fn);
      } else {
         Error("RemoveFile", "file '%s' does not exists", fn);
      }
   }
   // Done
   return;
}

//______________________________________________________________________________
void TSelHandleDataSet::CopyFile(const char *fn)
{
   // Copy file 'fn' to fDestDir

   // Check if we have a destination dir
   if (fDestDir.IsNull()) {
      Error("CopyFile", "destination dir undefined: file '%s' not copied", fn);
      return;
   }

   TString basefn = gSystem->BaseName(TUrl(fn, kTRUE).GetFile());
   TString dst = TString::Format("%s/%s", fDestDir.Data(), basefn.Data());
   if (!TFile::Cp(fn, dst.Data())) {
      Error("CopyFile", "problems copying file '%s' to '%s'", fn, dst.Data());
      return;
   }
   Info("CopyFile", "file '%s' created ...", dst.Data());

   // Done
   return;
}

//______________________________________________________________________________
Bool_t TSelHandleDataSet::Process(Long64_t entry)
{
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.

   // WARNING when a selector is used with a TChain, you must use
   //  the pointer to the current TTree to call GetEntry(entry).
   //  The entry is always the local entry number in the current tree.
   //  Assuming that fChain is the pointer to the TChain being processed,
   //  use fChain->GetTree()->GetEntry(entry).

   TDSetElement *fCurrent = 0;
   TPair *elemPair = 0;
   if (fInput && (elemPair = dynamic_cast<TPair *>
                      (fInput->FindObject("PROOF_CurrentElement")))) {
      if ((fCurrent = dynamic_cast<TDSetElement *>(elemPair->Value()))) {
         Info("Process", "entry %lld: file: '%s'", entry, fCurrent->GetName());
      } else {
         Error("Process", "entry %lld: no file specified!", entry);
         return kFALSE;
      }
   }

   // Resolve the file type; this also adjusts names for Xrd based systems
   TUrl url(fCurrent->GetName());
   url.SetAnchor(0);
   TString lfname = gEnv->GetValue("Path.Localroot", "");
   TFile::EFileType type = TFile::GetType(url.GetUrl(), "", &lfname);
   if (type == TFile::kLocal &&
       strcmp(url.GetProtocol(),"root") && strcmp(url.GetProtocol(),"xrd"))
      lfname = url.GetFileAndOptions();

   if (fType->GetType() == TPBHandleDSType::kReleaseCache) {
      // Release the file cache
      if (type == TFile::kLocal) {
         ReleaseCache(lfname);
      } else {
         Error("Process",
               "attempt to call ReleaseCache for a non-local file: '%s'", lfname.Data());
      }
   } else if (fType->GetType() == TPBHandleDSType::kCheckCache) {
      // Check the file cache
      if (type == TFile::kLocal) {
         CheckCache(lfname);
      } else {
         Error("Process",
               "attempt to call CheckCache for a non-local file: '%s'", lfname.Data());
      }
   } else if (fType->GetType() == TPBHandleDSType::kRemoveFiles) {
      // Remove the file
      RemoveFile(url.GetFileAndOptions());
   } else if (fType->GetType() == TPBHandleDSType::kCopyFiles) {
      // Copy file
      CopyFile(url.GetFileAndOptions());
   } else {
      // Type unknown
      Warning("Process", "type: %d is unknown", fType->GetType());
   }

   return kTRUE;
}

<commit_msg>Fix way the path name is passed to cache handling functions<commit_after>// @(#)root/proof:$Id$
// Author: Sangsu Ryu 22/06/2010

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TSelHandleDataSet                                                    //
//                                                                      //
// PROOF selector for file cache release.                               //
// List of files to be cleaned for each node is provided by client.     //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#define TSelHandleDataSet_cxx

#include "TSelHandleDataSet.h"

#include "TDSet.h"
#include "TEnv.h"
#include "TFile.h"
#include "TMap.h"
#include "TParameter.h"
#include "TProofBenchTypes.h"
#include "TSystem.h"
#include "TUrl.h"
#include "errno.h"
#include <unistd.h>
#include <fcntl.h>

ClassImp(TSelHandleDataSet)

//______________________________________________________________________________
void TSelHandleDataSet::SlaveBegin(TTree *)
{
   // Init the type from the input parameters

   TObject *o = fInput->FindObject("PROOF_Benchmark_HandleDSType");
   if (o) fType = dynamic_cast<TPBHandleDSType *>(o);

   TNamed *n = dynamic_cast<TNamed *>(fInput->FindObject("PROOF_Benchmark_DestDir"));
   if (n) {
      fDestDir = n->GetTitle();
      if (gSystem->AccessPathName(fDestDir)) {
         // Create the directory
         if (gSystem->mkdir(fDestDir, kTRUE) != 0) {
            fDestDir = "";
            Error("SlaveBegin", "could not create dir '%s'", fDestDir.Data());
         } else {
            if (gSystem->AccessPathName(fDestDir, kWritePermission)) {
               fDestDir = "";
               Error("SlaveBegin", "dir '%s' is not writable by this process", fDestDir.Data());
            } else {
               Info("SlaveBegin", "dir '%s' successfully created", fDestDir.Data());
            }
         }
      }
   }

   // Use default if nothing found in the input list
   if (!fType) fType = new TPBHandleDSType(TPBHandleDSType::kReleaseCache);
}

//______________________________________________________________________________
void TSelHandleDataSet::ReleaseCache(const char *fn)
{
   // Release the memory cache associated with file 'fn'.

#if defined(R__LINUX)
   TString filename(fn);
   Int_t fd;
   fd = open(filename.Data(), O_RDONLY);
   if (fd > -1) {
      fdatasync(fd);
      posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
      close(fd);
      Info("ReleaseCache", "file cache for file '%s' cleaned ...", filename.Data());
   } else {
      Error("ReleaseCache", "cannot open file '%s' for cache clean up; errno=%d",
                            filename.Data(), errno);
   }
#else
   Info("ReleaseCache", "dummy function: file '%s' untouched ...", fn);
#endif
   // Done
   return;
}

//______________________________________________________________________________
void TSelHandleDataSet::CheckCache(const char * /*fn*/)
{
   // Check the memory cache associated with file 'fn'.

   Warning("CheckCache", "cache checker not implemented yet");
   // Done
   return;
}

//______________________________________________________________________________
void TSelHandleDataSet::RemoveFile(const char *fn)
{
   // Physically remove the file 'fn'.

   if (!gSystem->AccessPathName(fn, kWritePermission)) {
      if (gSystem->Unlink(fn) != 0) {
         Error("RemoveFile", "problems removing file '%s' ...", fn);
      } else {
         if (!gSystem->AccessPathName(fn))
            Warning("RemoveFile", "'unlink' returned success but the file still exists ('%s')", fn);
      }
   } else {
      if (!gSystem->AccessPathName(fn)) {
         Error("RemoveFile", "file '%s' cannot removed by this process", fn);
      } else {
         Error("RemoveFile", "file '%s' does not exists", fn);
      }
   }
   // Done
   return;
}

//______________________________________________________________________________
void TSelHandleDataSet::CopyFile(const char *fn)
{
   // Copy file 'fn' to fDestDir

   // Check if we have a destination dir
   if (fDestDir.IsNull()) {
      Error("CopyFile", "destination dir undefined: file '%s' not copied", fn);
      return;
   }

   TString basefn = gSystem->BaseName(TUrl(fn, kTRUE).GetFile());
   TString dst = TString::Format("%s/%s", fDestDir.Data(), basefn.Data());
   if (!TFile::Cp(fn, dst.Data())) {
      Error("CopyFile", "problems copying file '%s' to '%s'", fn, dst.Data());
      return;
   }
   Info("CopyFile", "file '%s' created ...", dst.Data());

   // Done
   return;
}

//______________________________________________________________________________
Bool_t TSelHandleDataSet::Process(Long64_t entry)
{
   // The Process() function is called for each entry in the tree (or possibly
   // keyed object in the case of PROOF) to be processed. The entry argument
   // specifies which entry in the currently loaded tree is to be processed.
   // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()
   // to read either all or the required parts of the data. When processing
   // keyed objects with PROOF, the object is already loaded and is available
   // via the fObject pointer.
   //
   // This function should contain the "body" of the analysis. It can contain
   // simple or elaborate selection criteria, run algorithms on the data
   // of the event and typically fill histograms.

   // WARNING when a selector is used with a TChain, you must use
   //  the pointer to the current TTree to call GetEntry(entry).
   //  The entry is always the local entry number in the current tree.
   //  Assuming that fChain is the pointer to the TChain being processed,
   //  use fChain->GetTree()->GetEntry(entry).

   TDSetElement *fCurrent = 0;
   TPair *elemPair = 0;
   if (fInput && (elemPair = dynamic_cast<TPair *>
                      (fInput->FindObject("PROOF_CurrentElement")))) {
      if ((fCurrent = dynamic_cast<TDSetElement *>(elemPair->Value()))) {
         Info("Process", "entry %lld: file: '%s'", entry, fCurrent->GetName());
      } else {
         Error("Process", "entry %lld: no file specified!", entry);
         return kFALSE;
      }
   }

   // Resolve the file type; this also adjusts names for Xrd based systems
   TUrl url(fCurrent->GetName());
   url.SetAnchor(0);
   TString lfname = gEnv->GetValue("Path.Localroot", "");
   TFile::EFileType type = TFile::GetType(url.GetUrl(), "", &lfname);
   if (type == TFile::kLocal &&
       strcmp(url.GetProtocol(),"root") && strcmp(url.GetProtocol(),"xrd"))
      lfname = url.GetFileAndOptions();

   if (fType->GetType() == TPBHandleDSType::kReleaseCache) {
      // Release the file cache
      if (type == TFile::kLocal) {
         ReleaseCache(lfname);
      } else if (type == TFile::kFile) {
         ReleaseCache(url.GetFile());
      } else {
         Error("Process",
               "attempt to call ReleaseCache for a non-local file: '%s'", url.GetUrl());
      }
   } else if (fType->GetType() == TPBHandleDSType::kCheckCache) {
      // Check the file cache
      if (type == TFile::kLocal) {
         CheckCache(lfname);
      } else if (type == TFile::kFile) {
         CheckCache(url.GetFile());
      } else {
         Error("Process",
               "attempt to call CheckCache for a non-local file: '%s'", url.GetUrl());
      }
   } else if (fType->GetType() == TPBHandleDSType::kRemoveFiles) {
      // Remove the file
      RemoveFile(url.GetFileAndOptions());
   } else if (fType->GetType() == TPBHandleDSType::kCopyFiles) {
      // Copy file
      CopyFile(url.GetFileAndOptions());
   } else {
      // Type unknown
      Warning("Process", "type: %d is unknown", fType->GetType());
   }

   return kTRUE;
}

<|endoftext|>


<commit_before>#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "physics/solar_system.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "integrators/symplectic_runge_kutta_nyström_integrator.hpp"
#include "geometry/epoch.hpp"
#include "geometry/named_quantities.hpp"
#include "astronomy/frames.hpp"

namespace principia {

using astronomy::ICRFJ2000Equator;
using geometry::JulianDate;
using integrators::McLachlanAtela1992Order5Optimal;
using quantities::si::Minute;
using quantities::si::Metre;
using quantities::si::Milli;
using geometry::Position;

namespace physics {

    class EclipseTest : public testing::Test {
    protected:
        EclipseTest() {
			solar_system_1950_.Initialize(
				SOLUTION_DIR / "astronomy" / "gravity_model.proto.txt",
				SOLUTION_DIR / "astronomy" / "initial_state_jd_2433282_500000000.proto.txt");
		}

		SolarSystem<ICRFJ2000Equator> solar_system_1950_;
    };

    TEST_F(EclipseTest, Dummy) {
        auto ephemeris = solar_system_1950_.MakeEphemeris(McLachlanAtela1992Order5Optimal<Position<ICRFJ000Equator>>(),
		45 * Minute,
		5 * Milli(Metre));

		ephemeris->Prolong(JulianDate(2433374.5));
		// Prolong until date of eclipse
		// pass body to Ephemeris.trajectory
    };

} // physics

} // principia
<commit_msg>egg is going to kill me for this.<commit_after>#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include "physics/solar_system.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "integrators/symplectic_runge_kutta_nyström_integrator.hpp"
#include "geometry/epoch.hpp"
#include "geometry/named_quantities.hpp"

namespace principia {

using astronomy::ICRFJ2000Equator;
using geometry::JulianDate;
using integrators::McLachlanAtela1992Order5Optimal;
using quantities::si::Minute;
using quantities::si::Metre;
using quantities::si::Milli;

namespace physics {

	class EclipseTest : public testing::Test {
	protected:
		EclipseTest() {
			solar_system_1950_.Initialize(
				SOLUTION_DIR / "astronomy" / "gravity_model.proto.txt",
				SOLUTION_DIR / "astronomy" / "initial_state_jd_2433282_500000000.proto.txt");
		}

		SolarSystem<ICRFJ2000Equator> solar_system_1950_;
	};

	TEST_F(EclipseTest, Dummy) {
		auto ephemeris = solar_system_1950_.MakeEphemeris(McLachlanAtela1992Order5Optimal<Position<ICRFJ2000Equator>>(),
		45 * Minute,
		5 * Milli(Metre));

		ephemeris->Prolong(JulianDate(2433374.5));
		// Prolong until date of eclipse
		// pass body to Ephemeris.trajectory
	};

} // physics

} // principia
<|endoftext|>


<commit_before>#include "geometry/epoch.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/grassmann.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/symplectic_runge_kutta_nyström_integrator.hpp"
#include "physics/solar_system.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/numerics.hpp"

namespace principia {

using astronomy::ICRFJ2000Equator;
using geometry::JulianDate;
using geometry::Sign;
using integrators::McLachlanAtela1992Order5Optimal;
using quantities::ArcCos;
using quantities::si::Kilo;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Nano;
using testing_utilities::AbsoluteError;
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;

namespace physics {

class EclipseTest : public testing::Test {
 protected:
  EclipseTest() {
    solar_system_1950_.Initialize(
        SOLUTION_DIR / "astronomy" / "gravity_model.proto.txt",
        SOLUTION_DIR / "astronomy" /
            "initial_state_jd_2433282_500000000.proto.txt");
  }

  void CheckLunarEclipse(Instant const& current_time,
                         Sign const moon_offset_sign) {
    auto ephemeris = solar_system_1950_.MakeEphemeris(
        McLachlanAtela1992Order5Optimal<Position<ICRFJ2000Equator>>(),
        45 * Minute, 5 * Milli(Metre));

    ephemeris->Prolong(
        JulianDate(2433374.5));  // Prolong just past date of eclipse
                                 // (Eclipse was 1950-04-02 but JD
                                 // is 1950-04-03 00:00:00).
    auto const sun = solar_system_1950_.massive_body(*ephemeris, "Sun");
    auto const earth = solar_system_1950_.massive_body(*ephemeris, "Earth");
    auto const moon = solar_system_1950_.massive_body(*ephemeris, "Moon");

    auto const q_sun = ephemeris->trajectory(sun)
                           ->EvaluatePosition(current_time, /*hint=*/nullptr);
    auto const q_moon = ephemeris->trajectory(moon)
                            ->EvaluatePosition(current_time, /*hint=*/nullptr);
    auto const q_earth = ephemeris->trajectory(earth)
                             ->EvaluatePosition(current_time, /*hint=*/nullptr);

    // MassiveBody will need radius information.  Or non-hardcoded data from
    // https://github.com/mockingbirdnest/Principia/blob/master/astronomy/gravity_model.proto.txt
    auto const r_sun = 696000.0 * Kilo(Metre);
    auto const r_earth = 6378.1363 * Kilo(Metre);
    auto const r_moon = 1738.0 * Kilo(Metre);

    // Checking body angles at the target time.
    // Angle formed by a right circular cone with sides defined by tangent lines
    // between Sun and Earth, and axis running through the centers of each.
    auto const umbral_half_aperture =
        ArcSin((r_sun - r_earth) / (q_sun - q_earth).Norm());
    auto const apex_of_moon_locus_at_umbral_contact =
        q_earth +
        Normalize(q_earth - q_sun) * (r_earth + moon_offset_sign * r_moon) /
            Sin(umbral_half_aperture);
    // Angle between Earth and Moon as seen at
    // apex_of_moon_locus_at_umbral_contact.
    auto const earth_moon_angle =
        ArcCos(InnerProduct(apex_of_moon_locus_at_umbral_contact - q_earth,
                            apex_of_moon_locus_at_umbral_contact - q_moon) /
               ((apex_of_moon_locus_at_umbral_contact - q_moon).Norm() *
                (apex_of_moon_locus_at_umbral_contact - q_earth).Norm()));
    // We are at the desired contact if the angle between Earth and Moon from
    // the apex of locus of the moon at that contact is the same value (though
    // offset from) the half-aperture of the umbra (Earth-Sun cone).
    EXPECT_THAT(AbsoluteError(umbral_half_aperture, earth_moon_angle),
                AllOf(Lt(1.0 * Milli(Radian)), Gt(1.0 * Nano(Radian))))
        << NAMED(umbral_half_aperture) << ", " << NAMED(earth_moon_angle)
        << ", " << NAMED(current_time);
    return;
  }

  SolarSystem<ICRFJ2000Equator> solar_system_1950_;
};

TEST_F(EclipseTest, Dummy) {
  // Dates are TDB Julian Day for 1948-04-02.
  auto const P1 = JulianDate(2433374.25788409);  // 18:10:49 UT
  auto const U1 = JulianDate(2433374.29850909);  // 19:09:19
  auto const U2 = JulianDate(2433374.354979);    // 20:30:38
  auto const U3 = JulianDate(2433374.37367113);  // 20:57:33
  auto const U4 = JulianDate(2433374.43016419);  // 22:18:54
  auto const P4 = JulianDate(2433374.47075446);  // 23:17:21

  Sign const U14 = Sign(1);
  Sign const U23 = Sign(-1);
  CheckLunarEclipse(U1, U14);
  CheckLunarEclipse(U2, U23);
  CheckLunarEclipse(U3, U23);
  CheckLunarEclipse(U4, U14);

  // Later on for additional accuracy: 2 * ArcTan((x_norm_y -
  // y_normx).Norm(),(x_norm_y + y_norm_x).Norm())
  // x_norm_y = x * y.Norm() and y_norm_x = y * x.Norm()

  // Future: check 2048-01-01 Lunar eclipse.
  // P1 = 03:52:39 UT
  // U1 = 05:05:17 UT
  // U2 = 06:24:27
  // U3 = 07:20:23
  // U4 = 08:39:33
  // P4 = 09:52:05
  // etimes = {2469076.66235167, 2469076.71279148, 2469076.76776833,
  // 2469076.80661092, 2469076.86158778, 2469076.91195815};
}

}  // namespace physics
}  // namespace principia
<commit_msg>Accidentally a word, removed redundant phrase.<commit_after>#include "geometry/epoch.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/grassmann.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/symplectic_runge_kutta_nyström_integrator.hpp"
#include "physics/solar_system.hpp"
#include "quantities/elementary_functions.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/numerics.hpp"

namespace principia {

using astronomy::ICRFJ2000Equator;
using geometry::JulianDate;
using geometry::Sign;
using integrators::McLachlanAtela1992Order5Optimal;
using quantities::ArcCos;
using quantities::si::Kilo;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using quantities::si::Nano;
using testing_utilities::AbsoluteError;
using ::testing::AllOf;
using ::testing::Gt;
using ::testing::Lt;

namespace physics {

class EclipseTest : public testing::Test {
 protected:
  EclipseTest() {
    solar_system_1950_.Initialize(
        SOLUTION_DIR / "astronomy" / "gravity_model.proto.txt",
        SOLUTION_DIR / "astronomy" /
            "initial_state_jd_2433282_500000000.proto.txt");
  }

  void CheckLunarEclipse(Instant const& current_time,
                         Sign const moon_offset_sign) {
    auto ephemeris = solar_system_1950_.MakeEphemeris(
        McLachlanAtela1992Order5Optimal<Position<ICRFJ2000Equator>>(),
        45 * Minute, 5 * Milli(Metre));

    ephemeris->Prolong(
        JulianDate(2433374.5));  // Prolong just past date of eclipse
                                 // (Eclipse was 1950-04-02 but JD
                                 // is 1950-04-03 00:00:00).
    auto const sun = solar_system_1950_.massive_body(*ephemeris, "Sun");
    auto const earth = solar_system_1950_.massive_body(*ephemeris, "Earth");
    auto const moon = solar_system_1950_.massive_body(*ephemeris, "Moon");

    auto const q_sun = ephemeris->trajectory(sun)
                           ->EvaluatePosition(current_time, /*hint=*/nullptr);
    auto const q_moon = ephemeris->trajectory(moon)
                            ->EvaluatePosition(current_time, /*hint=*/nullptr);
    auto const q_earth = ephemeris->trajectory(earth)
                             ->EvaluatePosition(current_time, /*hint=*/nullptr);

    // MassiveBody will need radius information.  Or non-hardcoded data from
    // https://github.com/mockingbirdnest/Principia/blob/master/astronomy/gravity_model.proto.txt
    auto const r_sun = 696000.0 * Kilo(Metre);
    auto const r_earth = 6378.1363 * Kilo(Metre);
    auto const r_moon = 1738.0 * Kilo(Metre);

    // Checking body angles at the target time.
    // Angle formed by a right circular cone with sides defined by tangent lines
    // between Sun and Earth, and axis running through the centers of each.
    auto const umbral_half_aperture =
        ArcSin((r_sun - r_earth) / (q_sun - q_earth).Norm());
    auto const apex_of_moon_locus_at_umbral_contact =
        q_earth +
        Normalize(q_earth - q_sun) * (r_earth + moon_offset_sign * r_moon) /
            Sin(umbral_half_aperture);
    // Angle between Earth and Moon as seen at
    // apex_of_moon_locus_at_umbral_contact.
    auto const earth_moon_angle =
        ArcCos(InnerProduct(apex_of_moon_locus_at_umbral_contact - q_earth,
                            apex_of_moon_locus_at_umbral_contact - q_moon) /
               ((apex_of_moon_locus_at_umbral_contact - q_moon).Norm() *
                (apex_of_moon_locus_at_umbral_contact - q_earth).Norm()));
    // We are at the desired contact if the angle between Earth and Moon from
    // the apex of locus of the moon at that contact is the same value as the
    // half-aperture of the umbra (Earth-Sun cone).
    EXPECT_THAT(AbsoluteError(umbral_half_aperture, earth_moon_angle),
                AllOf(Lt(1.0 * Milli(Radian)), Gt(1.0 * Nano(Radian))))
        << NAMED(umbral_half_aperture) << ", " << NAMED(earth_moon_angle)
        << ", " << NAMED(current_time);
  }

  SolarSystem<ICRFJ2000Equator> solar_system_1950_;
};

TEST_F(EclipseTest, Dummy) {
  // Dates are TDB Julian Day for 1948-04-02.
  auto const P1 = JulianDate(2433374.25788409);  // 18:10:49 UT
  auto const U1 = JulianDate(2433374.29850909);  // 19:09:19
  auto const U2 = JulianDate(2433374.354979);    // 20:30:38
  auto const U3 = JulianDate(2433374.37367113);  // 20:57:33
  auto const U4 = JulianDate(2433374.43016419);  // 22:18:54
  auto const P4 = JulianDate(2433374.47075446);  // 23:17:21

  Sign const U14 = Sign(1);
  Sign const U23 = Sign(-1);
  CheckLunarEclipse(U1, U14);
  CheckLunarEclipse(U2, U23);
  CheckLunarEclipse(U3, U23);
  CheckLunarEclipse(U4, U14);

  // Later on for additional accuracy: 2 * ArcTan((x_norm_y -
  // y_normx).Norm(),(x_norm_y + y_norm_x).Norm())
  // x_norm_y = x * y.Norm() and y_norm_x = y * x.Norm()

  // Future: check 2048-01-01 Lunar eclipse.
  // P1 = 03:52:39 UT
  // U1 = 05:05:17 UT
  // U2 = 06:24:27
  // U3 = 07:20:23
  // U4 = 08:39:33
  // P4 = 09:52:05
  // etimes = {2469076.66235167, 2469076.71279148, 2469076.76776833,
  // 2469076.80661092, 2469076.86158778, 2469076.91195815};
}

}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>#include "GLVertArray.h"
#include <cassert>
#include <OpenGL\gl_core_4_4.hpp>
#include <GLM\detail\func_common.hpp>
#include "..\Common\Constants.h"

using glm::min;
using glm::max;

GLVertArray::GLVertArray(const GLuint n_attr, const GLsizei* const component_counts):
                         m_n_vbos{n_attr}, m_vbos{new VertBuffer[n_attr]},
                         m_ibo{nullptr}, m_num_vert{0}, m_is_buffered{false} {
    // Create vertex array object
    gl::GenVertexArrays(1, &m_handle);
    gl::BindVertexArray(m_handle);
    // Create buffer objects
    GLuint buffer_handles[MAX_N_VBOS];
    gl::GenBuffers(m_n_vbos, buffer_handles);
    for (auto i = 0; i < m_n_vbos; ++i) {
        // Assign handles
        m_vbos[i].handle = buffer_handles[i];
        // Assign strides
        m_vbos[i].n_components = component_counts[i];
        // Reserve a bit of memory
        m_vbos[i].data_vec.reserve(12);
    }
    // Map attribute incides to buffers
    for (GLuint i = 0; i < static_cast<GLuint>(m_n_vbos); ++i) {
        gl::EnableVertexAttribArray(i);
        #ifdef OLD_STYLE_BINDING
            gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
            gl::VertexAttribPointer(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0, nullptr);
        #else
            gl::BindVertexBuffer(i, m_vbos[i].handle, 0, m_vbos[i].n_components * sizeof(GLfloat));
            gl::VertexAttribFormat(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0);
            gl::VertexAttribBinding(i, i);
        #endif
    }
}

GLVertArray::GLVertArray(const GLVertArray& va): m_n_vbos{va.m_n_vbos},
                                                 m_vbos{new VertBuffer[m_n_vbos]},
                                                 m_ibo{va.isIndexed() ? new IndexBuffer : nullptr},
                                                 m_num_vert{va.m_num_vert},
                                                 m_is_buffered{va.m_is_buffered} {
    // Create vertex array object
    gl::GenVertexArrays(1, &m_handle);
    gl::BindVertexArray(m_handle);
    // Create buffer objects
    GLuint buffer_handles[MAX_N_VBOS];
    gl::GenBuffers(m_n_vbos, buffer_handles);
    for (auto i = 0; i < m_n_vbos; ++i) {
        // Use the new handles...
        m_vbos[i].handle = buffer_handles[i];
        // ... and copy the rest
        m_vbos[i].n_components = va.m_vbos[i].n_components;
        m_vbos[i].data_vec     = va.m_vbos[i].data_vec;
    }
    // Map attribute incides to buffers
    for (GLuint i = 0; i < static_cast<GLuint>(m_n_vbos); ++i) {
        gl::EnableVertexAttribArray(i);
        #ifdef OLD_STYLE_BINDING
             gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
             gl::VertexAttribPointer(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0, nullptr);
        #else
             gl::BindVertexBuffer(i, m_vbos[i].handle, 0, m_vbos[i].n_components * sizeof(GLfloat));
             gl::VertexAttribFormat(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0);
             gl::VertexAttribBinding(i, i);
        #endif
    }
    if (va.isIndexed()) {
        // Generate a new handle...
        gl::GenBuffers(1, &m_ibo->handle);
        // ... and copy the data
        m_ibo->data_vec = va.m_ibo->data_vec;
    }
    if (m_is_buffered) { buffer(); }
}

GLVertArray& GLVertArray::operator=(const GLVertArray& va) {
    if (this != &va) {
        m_n_vbos      = va.m_n_vbos;
        m_vbos        = new VertBuffer[m_n_vbos];
        m_ibo         = va.isIndexed() ? new IndexBuffer : nullptr;
        m_num_vert    = va.m_num_vert;
        m_is_buffered = va.m_is_buffered;
        // Create vertex array object
        gl::GenVertexArrays(1, &m_handle);
        gl::BindVertexArray(m_handle);
        // Create buffer objects
        GLuint buffer_handles[MAX_N_VBOS];
        gl::GenBuffers(m_n_vbos, buffer_handles);
        for (auto i = 0; i < m_n_vbos; ++i) {
            // Use the new handles...
            m_vbos[i].handle = buffer_handles[i];
            // ... and copy the rest
            m_vbos[i].n_components = va.m_vbos[i].n_components;
            m_vbos[i].data_vec     = va.m_vbos[i].data_vec;
        }
        // Map attribute incides to buffers
        for (GLuint i = 0; i < static_cast<GLuint>(m_n_vbos); ++i) {
            gl::EnableVertexAttribArray(i);
            #ifdef OLD_STYLE_BINDING
                gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
                gl::VertexAttribPointer(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0, nullptr);
            #else
                gl::BindVertexBuffer(i, m_vbos[i].handle, 0, m_vbos[i].n_components * sizeof(GLfloat));
                gl::VertexAttribFormat(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0);
                gl::VertexAttribBinding(i, i);
            #endif
        }
        if (va.isIndexed()) {
            // Generate a new handle...
            gl::GenBuffers(1, &m_ibo->handle);
            // ... and copy the data
            m_ibo->data_vec = va.m_ibo->data_vec;
        }
        if (m_is_buffered) { buffer(); }
    }
    return *this;
}

GLVertArray::GLVertArray(GLVertArray&& va): m_handle{va.m_handle}, m_n_vbos{va.m_n_vbos},
                                            m_vbos{va.m_vbos}, m_ibo{va.m_ibo},
                                            m_num_vert{va.m_num_vert},
                                            m_is_buffered{va.m_is_buffered} {
    // Mark as moved
    va.m_handle = 0;
}

GLVertArray& GLVertArray::operator=(GLVertArray&& va) {
    assert(this != &va);
    memcpy(this, &va, sizeof(*this));
    // Mark as moved
    va.m_handle = 0;
    return *this;
}

GLVertArray::~GLVertArray() {
    // Check if it was moved
    if (m_handle) {
        if (isIndexed()) {
            gl::DeleteBuffers(1, &m_ibo->handle);
            delete m_ibo;
        }
        GLuint buffer_handles[MAX_N_VBOS];
        for (auto i = 0; i < m_n_vbos; ++i) {
            buffer_handles[i] = m_vbos[i].handle;
        }
        delete[] m_vbos;
        gl::DeleteBuffers(m_n_vbos, buffer_handles);
        gl::DeleteVertexArrays(1, &m_handle);
    }
}

GLuint GLVertArray::id() const {
    return m_handle;
}

bool GLVertArray::isIndexed() const {
    return (nullptr != m_ibo);
}

void GLVertArray::loadAttrData(const GLuint attr_id, const std::vector<GLfloat>& data_vec) {
    loadAttrData(attr_id, data_vec.size(), data_vec.data());
}

void GLVertArray::loadAttrData(const GLuint attr_id, const size_t n_elems,
                               const GLfloat* const data) {
    for (auto i = 0; i < n_elems; ++i) {
        m_vbos[attr_id].data_vec.push_back(data[i]);
    }
    if (!isIndexed() && 0 == attr_id) {
        // The size of the first buffer determines number of vertices
        m_num_vert = static_cast<GLsizei>(m_vbos[0].data_vec.size() / 3);
    }
    m_is_buffered = false;
}

void GLVertArray::loadIndexData(const std::vector<GLuint>& data_vec, const GLuint offset) {
    loadIndexData(data_vec.size(), data_vec.data(), offset);
}

void GLVertArray::loadIndexData(const size_t n_elems, const GLuint* const data,
                                const GLuint offset) {
    if (!isIndexed()) {
        m_ibo = new IndexBuffer;
        gl::GenBuffers(1, &m_ibo->handle);
        m_ibo->min_idx = UINT_MAX;
        m_ibo->max_idx = 0;
    }
    for (auto i = 0; i < n_elems; ++i) {
        const GLuint idx{offset + data[i]};
        m_ibo->min_idx = min(m_ibo->min_idx, idx);
        m_ibo->max_idx = max(m_ibo->max_idx, idx);
        m_ibo->data_vec.push_back(idx);
    }
    m_num_vert = static_cast<GLsizei>(m_ibo->data_vec.size());
    m_is_buffered = false;
}

void GLVertArray::buffer() {
    for (auto i = 0; i < m_n_vbos; ++i) {
        gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
        const auto byte_sz = m_vbos[i].data_vec.size() * sizeof(GLfloat);
        gl::BufferData(gl::ARRAY_BUFFER, byte_sz, m_vbos[i].data_vec.data(), gl::STATIC_DRAW);
    }
    if (isIndexed()) {
        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, m_ibo->handle);
        const auto byte_sz = m_ibo->data_vec.size() * sizeof(GLuint);
        gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, byte_sz, m_ibo->data_vec.data(), gl::STATIC_DRAW);
    }
    m_is_buffered = true;
}

void GLVertArray::draw() const {
    assert(m_is_buffered);
    gl::BindVertexArray(m_handle);
    if (isIndexed()) {
        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, m_ibo->handle);
        gl::DrawRangeElements(gl::TRIANGLES, m_ibo->min_idx, m_ibo->max_idx, m_num_vert,
                              gl::UNSIGNED_INT, nullptr);
    } else {
        gl::DrawArrays(gl::TRIANGLES, 0, m_num_vert);
    }
}
<commit_msg>Check buffered state of the object being copied more consistently.<commit_after>#include "GLVertArray.h"
#include <cassert>
#include <OpenGL\gl_core_4_4.hpp>
#include <GLM\detail\func_common.hpp>
#include "..\Common\Constants.h"

using glm::min;
using glm::max;

GLVertArray::GLVertArray(const GLuint n_attr, const GLsizei* const component_counts):
                         m_n_vbos{n_attr}, m_vbos{new VertBuffer[n_attr]},
                         m_ibo{nullptr}, m_num_vert{0}, m_is_buffered{false} {
    // Create vertex array object
    gl::GenVertexArrays(1, &m_handle);
    gl::BindVertexArray(m_handle);
    // Create buffer objects
    GLuint buffer_handles[MAX_N_VBOS];
    gl::GenBuffers(m_n_vbos, buffer_handles);
    for (auto i = 0; i < m_n_vbos; ++i) {
        // Assign handles
        m_vbos[i].handle = buffer_handles[i];
        // Assign strides
        m_vbos[i].n_components = component_counts[i];
        // Reserve a bit of memory
        m_vbos[i].data_vec.reserve(12);
    }
    // Map attribute incides to buffers
    for (GLuint i = 0; i < static_cast<GLuint>(m_n_vbos); ++i) {
        gl::EnableVertexAttribArray(i);
        #ifdef OLD_STYLE_BINDING
            gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
            gl::VertexAttribPointer(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0, nullptr);
        #else
            gl::BindVertexBuffer(i, m_vbos[i].handle, 0, m_vbos[i].n_components * sizeof(GLfloat));
            gl::VertexAttribFormat(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0);
            gl::VertexAttribBinding(i, i);
        #endif
    }
}

GLVertArray::GLVertArray(const GLVertArray& va): m_n_vbos{va.m_n_vbos},
                                                 m_vbos{new VertBuffer[m_n_vbos]},
                                                 m_ibo{va.isIndexed() ? new IndexBuffer : nullptr},
                                                 m_num_vert{va.m_num_vert},
                                                 m_is_buffered{va.m_is_buffered} {
    // Create vertex array object
    gl::GenVertexArrays(1, &m_handle);
    gl::BindVertexArray(m_handle);
    // Create buffer objects
    GLuint buffer_handles[MAX_N_VBOS];
    gl::GenBuffers(m_n_vbos, buffer_handles);
    for (auto i = 0; i < m_n_vbos; ++i) {
        // Use the new handles...
        m_vbos[i].handle = buffer_handles[i];
        // ... and copy the rest
        m_vbos[i].n_components = va.m_vbos[i].n_components;
        m_vbos[i].data_vec     = va.m_vbos[i].data_vec;
    }
    // Map attribute incides to buffers
    for (GLuint i = 0; i < static_cast<GLuint>(m_n_vbos); ++i) {
        gl::EnableVertexAttribArray(i);
        #ifdef OLD_STYLE_BINDING
             gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
             gl::VertexAttribPointer(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0, nullptr);
        #else
             gl::BindVertexBuffer(i, m_vbos[i].handle, 0, m_vbos[i].n_components * sizeof(GLfloat));
             gl::VertexAttribFormat(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0);
             gl::VertexAttribBinding(i, i);
        #endif
    }
    if (va.isIndexed()) {
        // Generate a new handle...
        gl::GenBuffers(1, &m_ibo->handle);
        // ... and copy the data
        m_ibo->data_vec = va.m_ibo->data_vec;
    }
    if (va.m_is_buffered) { buffer(); }
}

GLVertArray& GLVertArray::operator=(const GLVertArray& va) {
    if (this != &va) {
        m_n_vbos      = va.m_n_vbos;
        m_vbos        = new VertBuffer[m_n_vbos];
        m_ibo         = va.isIndexed() ? new IndexBuffer : nullptr;
        m_num_vert    = va.m_num_vert;
        m_is_buffered = va.m_is_buffered;
        // Create vertex array object
        gl::GenVertexArrays(1, &m_handle);
        gl::BindVertexArray(m_handle);
        // Create buffer objects
        GLuint buffer_handles[MAX_N_VBOS];
        gl::GenBuffers(m_n_vbos, buffer_handles);
        for (auto i = 0; i < m_n_vbos; ++i) {
            // Use the new handles...
            m_vbos[i].handle = buffer_handles[i];
            // ... and copy the rest
            m_vbos[i].n_components = va.m_vbos[i].n_components;
            m_vbos[i].data_vec     = va.m_vbos[i].data_vec;
        }
        // Map attribute incides to buffers
        for (GLuint i = 0; i < static_cast<GLuint>(m_n_vbos); ++i) {
            gl::EnableVertexAttribArray(i);
            #ifdef OLD_STYLE_BINDING
                gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
                gl::VertexAttribPointer(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0, nullptr);
            #else
                gl::BindVertexBuffer(i, m_vbos[i].handle, 0, m_vbos[i].n_components * sizeof(GLfloat));
                gl::VertexAttribFormat(i, m_vbos[i].n_components, gl::FLOAT, GL_FALSE, 0);
                gl::VertexAttribBinding(i, i);
            #endif
        }
        if (va.isIndexed()) {
            // Generate a new handle...
            gl::GenBuffers(1, &m_ibo->handle);
            // ... and copy the data
            m_ibo->data_vec = va.m_ibo->data_vec;
        }
        if (va.m_is_buffered) { buffer(); }
    }
    return *this;
}

GLVertArray::GLVertArray(GLVertArray&& va): m_handle{va.m_handle}, m_n_vbos{va.m_n_vbos},
                                            m_vbos{va.m_vbos}, m_ibo{va.m_ibo},
                                            m_num_vert{va.m_num_vert},
                                            m_is_buffered{va.m_is_buffered} {
    // Mark as moved
    va.m_handle = 0;
}

GLVertArray& GLVertArray::operator=(GLVertArray&& va) {
    assert(this != &va);
    memcpy(this, &va, sizeof(*this));
    // Mark as moved
    va.m_handle = 0;
    return *this;
}

GLVertArray::~GLVertArray() {
    // Check if it was moved
    if (m_handle) {
        if (isIndexed()) {
            gl::DeleteBuffers(1, &m_ibo->handle);
            delete m_ibo;
        }
        GLuint buffer_handles[MAX_N_VBOS];
        for (auto i = 0; i < m_n_vbos; ++i) {
            buffer_handles[i] = m_vbos[i].handle;
        }
        delete[] m_vbos;
        gl::DeleteBuffers(m_n_vbos, buffer_handles);
        gl::DeleteVertexArrays(1, &m_handle);
    }
}

GLuint GLVertArray::id() const {
    return m_handle;
}

bool GLVertArray::isIndexed() const {
    return (nullptr != m_ibo);
}

void GLVertArray::loadAttrData(const GLuint attr_id, const std::vector<GLfloat>& data_vec) {
    loadAttrData(attr_id, data_vec.size(), data_vec.data());
}

void GLVertArray::loadAttrData(const GLuint attr_id, const size_t n_elems,
                               const GLfloat* const data) {
    for (auto i = 0; i < n_elems; ++i) {
        m_vbos[attr_id].data_vec.push_back(data[i]);
    }
    if (!isIndexed() && 0 == attr_id) {
        // The size of the first buffer determines number of vertices
        m_num_vert = static_cast<GLsizei>(m_vbos[0].data_vec.size() / 3);
    }
    m_is_buffered = false;
}

void GLVertArray::loadIndexData(const std::vector<GLuint>& data_vec, const GLuint offset) {
    loadIndexData(data_vec.size(), data_vec.data(), offset);
}

void GLVertArray::loadIndexData(const size_t n_elems, const GLuint* const data,
                                const GLuint offset) {
    if (!isIndexed()) {
        m_ibo = new IndexBuffer;
        gl::GenBuffers(1, &m_ibo->handle);
        m_ibo->min_idx = UINT_MAX;
        m_ibo->max_idx = 0;
    }
    for (auto i = 0; i < n_elems; ++i) {
        const GLuint idx{offset + data[i]};
        m_ibo->min_idx = min(m_ibo->min_idx, idx);
        m_ibo->max_idx = max(m_ibo->max_idx, idx);
        m_ibo->data_vec.push_back(idx);
    }
    m_num_vert = static_cast<GLsizei>(m_ibo->data_vec.size());
    m_is_buffered = false;
}

void GLVertArray::buffer() {
    for (auto i = 0; i < m_n_vbos; ++i) {
        gl::BindBuffer(gl::ARRAY_BUFFER, m_vbos[i].handle);
        const auto byte_sz = m_vbos[i].data_vec.size() * sizeof(GLfloat);
        gl::BufferData(gl::ARRAY_BUFFER, byte_sz, m_vbos[i].data_vec.data(), gl::STATIC_DRAW);
    }
    if (isIndexed()) {
        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, m_ibo->handle);
        const auto byte_sz = m_ibo->data_vec.size() * sizeof(GLuint);
        gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, byte_sz, m_ibo->data_vec.data(), gl::STATIC_DRAW);
    }
    m_is_buffered = true;
}

void GLVertArray::draw() const {
    assert(m_is_buffered);
    gl::BindVertexArray(m_handle);
    if (isIndexed()) {
        gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, m_ibo->handle);
        gl::DrawRangeElements(gl::TRIANGLES, m_ibo->min_idx, m_ibo->max_idx, m_num_vert,
                              gl::UNSIGNED_INT, nullptr);
    } else {
        gl::DrawArrays(gl::TRIANGLES, 0, m_num_vert);
    }
}
<|endoftext|>


<commit_before>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#pragma once

#include <stdexcept>

namespace ouzel
{
    class ConfigError final: public std::runtime_error
    {
    public:
        explicit ConfigError(const std::string& str): std::runtime_error(str) {}
        explicit ConfigError(const char* str): std::runtime_error(str) {}
    };

    class DataError final: public std::runtime_error
    {
    public:
        explicit DataError(const std::string& str): std::runtime_error(str) {}
        explicit DataError(const char* str): std::runtime_error(str) {}
    };

    class FileError final: public std::runtime_error
    {
    public:
        explicit FileError(const std::string& str): std::runtime_error(str) {}
        explicit FileError(const char* str): std::runtime_error(str) {}
    };

    class ParseError final: public std::runtime_error
    {
    public:
        explicit ParseError(const std::string& str): std::runtime_error(str) {}
        explicit ParseError(const char* str): std::runtime_error(str) {}
    };

    class SystemError final: public std::runtime_error
    {
    public:
        explicit SystemError(const std::string& str): std::runtime_error(str) {}
        explicit SystemError(const char* str): std::runtime_error(str) {}
    };

    class ThreadError final: public std::runtime_error
    {
    public:
        explicit ThreadError(const std::string& str): std::runtime_error(str) {}
        explicit ThreadError(const char* str): std::runtime_error(str) {}
    };
}
<commit_msg>Remove ThreadError<commit_after>// Copyright 2015-2018 Elviss Strazdins. All rights reserved.

#pragma once

#include <stdexcept>

namespace ouzel
{
    class ConfigError final: public std::runtime_error
    {
    public:
        explicit ConfigError(const std::string& str): std::runtime_error(str) {}
        explicit ConfigError(const char* str): std::runtime_error(str) {}
    };

    class DataError final: public std::runtime_error
    {
    public:
        explicit DataError(const std::string& str): std::runtime_error(str) {}
        explicit DataError(const char* str): std::runtime_error(str) {}
    };

    class FileError final: public std::runtime_error
    {
    public:
        explicit FileError(const std::string& str): std::runtime_error(str) {}
        explicit FileError(const char* str): std::runtime_error(str) {}
    };

    class ParseError final: public std::runtime_error
    {
    public:
        explicit ParseError(const std::string& str): std::runtime_error(str) {}
        explicit ParseError(const char* str): std::runtime_error(str) {}
    };

    class SystemError final: public std::runtime_error
    {
    public:
        explicit SystemError(const std::string& str): std::runtime_error(str) {}
        explicit SystemError(const char* str): std::runtime_error(str) {}
    };
}
<|endoftext|>