<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 "native_client/src/shared/ppapi_proxy/command_buffer_nacl.h"

#include <sys/mman.h>
#include "gpu/command_buffer/common/logging.h"
#include "native_client/src/shared/ppapi_proxy/plugin_globals.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
#include "ppapi/c/ppb_core.h"

#include "srpcgen/ppb_rpc.h"

using ppapi_proxy::DebugPrintf;

CommandBufferNacl::CommandBufferNacl(PP_Resource graphics_3d,
                                     const PPB_Core* iface_core)
    : graphics_3d_(graphics_3d), iface_core_(iface_core) {
  iface_core_->AddRefResource(graphics_3d_);
}

CommandBufferNacl::~CommandBufferNacl() {
  DebugPrintf("CommandBufferNacl::~CommandBufferNacl()\n");
  iface_core_->ReleaseResource(graphics_3d_);
}

bool CommandBufferNacl::Initialize() {
  DebugPrintf("CommandBufferNacl::Initialize\n");
  int32_t success;
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer(
          channel, graphics_3d_, &success);
  DebugPrintf("CommandBufferNaCl::Initialize returned success=%s\n",
      (PP_TRUE == success) ? "TRUE" : "FALSE");
  return NACL_SRPC_RESULT_OK == retval && PP_TRUE == success;
}

gpu::CommandBuffer::State CommandBufferNacl::GetState() {
  DebugPrintf("CommandBufferNacl::GetState\n");
  PP_Graphics3DTrustedState state;
  nacl_abi_size_t state_size = static_cast<nacl_abi_size_t>(sizeof(state));

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetState(
          channel, graphics_3d_, &state_size, reinterpret_cast<char*>(&state));
  if (NACL_SRPC_RESULT_OK != retval
      || state_size != static_cast<nacl_abi_size_t>(sizeof(state))) {
    return ErrorGpuState();
  }

  last_state_ = PpapiToGpuState(state);
  return last_state_;
}

gpu::CommandBuffer::State CommandBufferNacl::GetLastState() {
  return last_state_;
}

void CommandBufferNacl::Flush(int32 put_offset) {
  DebugPrintf("CommandBufferNacl::Flush\n");
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_Flush(
      channel, graphics_3d_, put_offset);
}

gpu::CommandBuffer::State CommandBufferNacl::FlushSync(int32 put_offset,
                                                       int32 last_known_get) {
  DebugPrintf("CommandBufferNacl::FlushSync\n");
  PP_Graphics3DTrustedState state;
  nacl_abi_size_t state_size = static_cast<nacl_abi_size_t>(sizeof(state));

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_FlushSyncFast(
          channel,
          graphics_3d_,
          put_offset,
          last_known_get,
          &state_size,
          reinterpret_cast<char*>(&state));
  if (NACL_SRPC_RESULT_OK != retval
      || state_size != static_cast<nacl_abi_size_t>(sizeof(state))) {
    return ErrorGpuState();
  }

  last_state_ = PpapiToGpuState(state);
  return last_state_;
}

void CommandBufferNacl::SetGetBuffer(int32 transfer_buffer_id) {
  DebugPrintf("CommandBufferNacl::SetGetBuffer\n");
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_SetGetBuffer(
      channel, graphics_3d_, transfer_buffer_id);
}

void CommandBufferNacl::SetGetOffset(int32 get_offset) {
  DebugPrintf("CommandBufferNacl::SetGetOffset\n");
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

int32 CommandBufferNacl::CreateTransferBuffer(size_t size, int32 id_request) {
  DebugPrintf("CommandBufferNacl::CreateTransferBuffer\n");
  int32_t id;

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateTransferBuffer(
          channel, graphics_3d_, size, id_request, &id);
  if (NACL_SRPC_RESULT_OK != retval)
    return 0;

  return id;
}

void CommandBufferNacl::DestroyTransferBuffer(int32 id) {
  DebugPrintf("CommandBufferNacl::DestroyTransferBuffer\n");
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_DestroyTransferBuffer(
      channel, graphics_3d_, id);
}

gpu::Buffer CommandBufferNacl::GetTransferBuffer(int32 id) {
  DebugPrintf("CommandBufferNacl::GetTransferBuffer\n");
  int shm_handle;
  int32_t shm_size;

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetTransferBuffer(
          channel, graphics_3d_, id, &shm_handle, &shm_size);
  if (NACL_SRPC_RESULT_OK != retval) {
    return BufferFromShm(-1, 0);
  }
  return BufferFromShm(shm_handle, shm_size);
}

void CommandBufferNacl::SetToken(int32 token) {
  DebugPrintf("CommandBufferNacl::SetToken\n");
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

void CommandBufferNacl::SetParseError(
    gpu::error::Error error) {
  DebugPrintf("CommandBufferNacl::SetParseError\n");
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

void CommandBufferNacl::SetContextLostReason(gpu::error::ContextLostReason) {
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

// static
gpu::Buffer CommandBufferNacl::BufferFromShm(int shm_handle,
                                             uint32_t shm_size) {
  gpu::Buffer buffer;
  buffer.ptr = mmap(0,
                    shm_size,
                    PROT_READ | PROT_WRITE,
                    MAP_SHARED,
                    shm_handle,
                    0);
  // TODO(neb): Close the fd now that it's mapped.
  // TODO(neb): Unmap ring & transfer buffers in the destructor.
  if (NULL != buffer.ptr)
    buffer.size = shm_size;
  return buffer;
}

// static
gpu::CommandBuffer::State CommandBufferNacl::ErrorGpuState() {
  gpu::CommandBuffer::State state;
  state.error = gpu::error::kGenericError;
  return state;
}

// static
gpu::CommandBuffer::State CommandBufferNacl::PpapiToGpuState(
    PP_Graphics3DTrustedState s) {
  gpu::CommandBuffer::State state;
  state.num_entries = s.num_entries;
  state.get_offset  = s.get_offset;
  state.put_offset  = s.put_offset;
  state.token       = s.token;
  state.error       = static_cast<gpu::error::Error>(s.error);
  return state;
}
<commit_msg>IWYU nit in ppapi_proxy<commit_after>// Copyright (c) 2012 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 "native_client/src/shared/ppapi_proxy/command_buffer_nacl.h"

#include <sys/types.h>
#include <sys/mman.h>
#include "gpu/command_buffer/common/logging.h"
#include "native_client/src/shared/ppapi_proxy/plugin_globals.h"
#include "native_client/src/shared/ppapi_proxy/utility.h"
#include "ppapi/c/ppb_core.h"

#include "srpcgen/ppb_rpc.h"

using ppapi_proxy::DebugPrintf;

CommandBufferNacl::CommandBufferNacl(PP_Resource graphics_3d,
                                     const PPB_Core* iface_core)
    : graphics_3d_(graphics_3d), iface_core_(iface_core) {
  iface_core_->AddRefResource(graphics_3d_);
}

CommandBufferNacl::~CommandBufferNacl() {
  DebugPrintf("CommandBufferNacl::~CommandBufferNacl()\n");
  iface_core_->ReleaseResource(graphics_3d_);
}

bool CommandBufferNacl::Initialize() {
  DebugPrintf("CommandBufferNacl::Initialize\n");
  int32_t success;
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_InitCommandBuffer(
          channel, graphics_3d_, &success);
  DebugPrintf("CommandBufferNaCl::Initialize returned success=%s\n",
      (PP_TRUE == success) ? "TRUE" : "FALSE");
  return NACL_SRPC_RESULT_OK == retval && PP_TRUE == success;
}

gpu::CommandBuffer::State CommandBufferNacl::GetState() {
  DebugPrintf("CommandBufferNacl::GetState\n");
  PP_Graphics3DTrustedState state;
  nacl_abi_size_t state_size = static_cast<nacl_abi_size_t>(sizeof(state));

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetState(
          channel, graphics_3d_, &state_size, reinterpret_cast<char*>(&state));
  if (NACL_SRPC_RESULT_OK != retval
      || state_size != static_cast<nacl_abi_size_t>(sizeof(state))) {
    return ErrorGpuState();
  }

  last_state_ = PpapiToGpuState(state);
  return last_state_;
}

gpu::CommandBuffer::State CommandBufferNacl::GetLastState() {
  return last_state_;
}

void CommandBufferNacl::Flush(int32 put_offset) {
  DebugPrintf("CommandBufferNacl::Flush\n");
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_Flush(
      channel, graphics_3d_, put_offset);
}

gpu::CommandBuffer::State CommandBufferNacl::FlushSync(int32 put_offset,
                                                       int32 last_known_get) {
  DebugPrintf("CommandBufferNacl::FlushSync\n");
  PP_Graphics3DTrustedState state;
  nacl_abi_size_t state_size = static_cast<nacl_abi_size_t>(sizeof(state));

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_FlushSyncFast(
          channel,
          graphics_3d_,
          put_offset,
          last_known_get,
          &state_size,
          reinterpret_cast<char*>(&state));
  if (NACL_SRPC_RESULT_OK != retval
      || state_size != static_cast<nacl_abi_size_t>(sizeof(state))) {
    return ErrorGpuState();
  }

  last_state_ = PpapiToGpuState(state);
  return last_state_;
}

void CommandBufferNacl::SetGetBuffer(int32 transfer_buffer_id) {
  DebugPrintf("CommandBufferNacl::SetGetBuffer\n");
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_SetGetBuffer(
      channel, graphics_3d_, transfer_buffer_id);
}

void CommandBufferNacl::SetGetOffset(int32 get_offset) {
  DebugPrintf("CommandBufferNacl::SetGetOffset\n");
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

int32 CommandBufferNacl::CreateTransferBuffer(size_t size, int32 id_request) {
  DebugPrintf("CommandBufferNacl::CreateTransferBuffer\n");
  int32_t id;

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_CreateTransferBuffer(
          channel, graphics_3d_, size, id_request, &id);
  if (NACL_SRPC_RESULT_OK != retval)
    return 0;

  return id;
}

void CommandBufferNacl::DestroyTransferBuffer(int32 id) {
  DebugPrintf("CommandBufferNacl::DestroyTransferBuffer\n");
  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_DestroyTransferBuffer(
      channel, graphics_3d_, id);
}

gpu::Buffer CommandBufferNacl::GetTransferBuffer(int32 id) {
  DebugPrintf("CommandBufferNacl::GetTransferBuffer\n");
  int shm_handle;
  int32_t shm_size;

  NaClSrpcChannel* channel = ppapi_proxy::GetMainSrpcChannel();
  NaClSrpcError retval =
      PpbGraphics3DRpcClient::PPB_Graphics3DTrusted_GetTransferBuffer(
          channel, graphics_3d_, id, &shm_handle, &shm_size);
  if (NACL_SRPC_RESULT_OK != retval) {
    return BufferFromShm(-1, 0);
  }
  return BufferFromShm(shm_handle, shm_size);
}

void CommandBufferNacl::SetToken(int32 token) {
  DebugPrintf("CommandBufferNacl::SetToken\n");
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

void CommandBufferNacl::SetParseError(
    gpu::error::Error error) {
  DebugPrintf("CommandBufferNacl::SetParseError\n");
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

void CommandBufferNacl::SetContextLostReason(gpu::error::ContextLostReason) {
  // Not implemented by proxy.
  GPU_NOTREACHED();
}

// static
gpu::Buffer CommandBufferNacl::BufferFromShm(int shm_handle,
                                             uint32_t shm_size) {
  gpu::Buffer buffer;
  buffer.ptr = mmap(0,
                    shm_size,
                    PROT_READ | PROT_WRITE,
                    MAP_SHARED,
                    shm_handle,
                    0);
  // TODO(neb): Close the fd now that it's mapped.
  // TODO(neb): Unmap ring & transfer buffers in the destructor.
  if (NULL != buffer.ptr)
    buffer.size = shm_size;
  return buffer;
}

// static
gpu::CommandBuffer::State CommandBufferNacl::ErrorGpuState() {
  gpu::CommandBuffer::State state;
  state.error = gpu::error::kGenericError;
  return state;
}

// static
gpu::CommandBuffer::State CommandBufferNacl::PpapiToGpuState(
    PP_Graphics3DTrustedState s) {
  gpu::CommandBuffer::State state;
  state.num_entries = s.num_entries;
  state.get_offset  = s.get_offset;
  state.put_offset  = s.put_offset;
  state.token       = s.token;
  state.error       = static_cast<gpu::error::Error>(s.error);
  return state;
}
<|endoftext|>


<commit_before>#include <jni.h>

#include "../maps/Framework.hpp"
#include "../maps/MapStorage.hpp"
#include "../core/jni_helper.hpp"
#include "country_helper.hpp"

using namespace storage_utils;
using namespace storage;

extern "C"
{
  JNIEXPORT jint JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getOutOfDateCount(JNIEnv * env, jclass clazz)
  {
    return GetMapLayout().GetOutOfDateCount();
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCountInGroup(JNIEnv * env, jclass clazz, jint group)
  {
    return GetMapLayout().GetCountInGroup(ToGroup(group));
  }

  JNIEXPORT jobject JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCountryItem(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    ActiveMapsLayout & layout = GetMapLayout();
    ActiveMapsLayout::TGroup coreGroup = ToGroup(group);
    int corePosition = static_cast<int>(position);
    jstring name = jni::ToJavaString(env, layout.GetCountryName(coreGroup, corePosition));
    jint status = static_cast<jint>(layout.GetCountryStatus(coreGroup, corePosition));
    jint options = static_cast<jint>(layout.GetCountryOptions(coreGroup, corePosition));

    jclass createClass = env->FindClass("com/mapswithme/country/CountryItem");
    ASSERT(createClass, ());

    jmethodID createMethodId = env->GetMethodID(createClass, "<init>", "(Ljava/lang/String;IIZ)V");
    ASSERT(createMethodId, ());

    return env->NewObject(createClass, createMethodId,
                          name, status, options, JNI_FALSE);
  }

  JNIEXPORT jlong JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCountrySize(JNIEnv * env, jclass clazz, jint group, jint position, jint options, jboolean isLocal)
  {
    ActiveMapsLayout & layout = GetMapLayout();
    ActiveMapsLayout::TGroup coreGroup = ToGroup(group);
    int pos = static_cast<int>(position);
    bool const local = isLocal == JNI_TRUE;
    MapOptions opt = ToOptions(options);

    if (options == -1 || local)
    {
      LocalAndRemoteSizeT sizes = options == -1 ? layout.GetDownloadableCountrySize(coreGroup, pos)
                                                : layout.GetCountrySize(coreGroup, pos, opt);
      return local ? sizes.first : sizes.second;
    }

    LocalAndRemoteSizeT sizes = layout.GetRemoteCountrySizes(coreGroup, pos);
    switch (opt)
    {
      case MapOptions::Map:
        return sizes.first;
      case MapOptions::CarRouting:
        return sizes.second;
      default:
        return sizes.first + sizes.second;
    }
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_cancelDownloading(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    GetMapLayout().CancelDownloading(ToGroup(group), position);
  }

  JNIEXPORT jboolean JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_isDownloadingActive(JNIEnv * env, jclass clazz)
  {
    return GetMapLayout().IsDownloadingActive();
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_retryDownloading(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    GetMapLayout().RetryDownloading(ToGroup(group), position);
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_downloadMap(JNIEnv * env, jclass clazz, jint group, jint position, jint options)
  {
    GetMapLayout().DownloadMap(ToGroup(group), position, ToOptions(options));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_deleteMap(JNIEnv * env, jclass clazz, jint group, jint position, jint options)
  {
    GetMapLayout().DeleteMap(ToGroup(group), position, ToOptions(options));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_showOnMap(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    g_framework->PostDrapeTask([group, position]()
    {
      GetMapLayout().ShowMap(ToGroup(group), position);
    });
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_updateAll(JNIEnv * env, jclass clazz)
  {
    GetMapLayout().UpdateAll();
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_cancelAll(JNIEnv * env, jclass clazz)
  {
    GetMapLayout().CancelAll();
  }

  JNIEXPORT int JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_addListener(JNIEnv * env, jclass clazz, jobject listener)
  {
    return g_framework->AddActiveMapsListener(jni::make_global_ref(listener));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_removeListener(JNIEnv * env, jclass clazz, jint slotID)
  {
    g_framework->RemoveActiveMapsListener(slotID);
  }

  JNIEXPORT jobject JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCoreIndex(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    return storage::ToJava(GetMapLayout().GetCoreIndex(static_cast<storage::ActiveMapsLayout::TGroup>(group),
                                                       static_cast<int>(position)));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_downloadMapForIndex(JNIEnv * env, jclass clazz, jobject index, jint options)
  {
    GetMapLayout().DownloadMap(storage::ToNative(index), ToOptions(options));
  }

  JNIEXPORT jboolean JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_isLegacyMode(JNIEnv * env, jclass clazz)
  {
    return g_framework->NeedMigrate();
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_migrate(JNIEnv * env, jclass clazz)
  {
    g_framework->Migrate();
  }
}
<commit_msg>[old map downloader][android] fix: Do not show "Map update available" marker until migrated.<commit_after>#include <jni.h>

#include "../maps/Framework.hpp"
#include "../maps/MapStorage.hpp"
#include "../core/jni_helper.hpp"
#include "country_helper.hpp"

using namespace storage_utils;
using namespace storage;

extern "C"
{
  JNIEXPORT jint JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getOutOfDateCount(JNIEnv * env, jclass clazz)
  {
    return (g_framework->NeedMigrate() ? 0 : GetMapLayout().GetOutOfDateCount());
  }

  JNIEXPORT jint JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCountInGroup(JNIEnv * env, jclass clazz, jint group)
  {
    return GetMapLayout().GetCountInGroup(ToGroup(group));
  }

  JNIEXPORT jobject JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCountryItem(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    ActiveMapsLayout & layout = GetMapLayout();
    ActiveMapsLayout::TGroup coreGroup = ToGroup(group);
    int corePosition = static_cast<int>(position);
    jstring name = jni::ToJavaString(env, layout.GetCountryName(coreGroup, corePosition));
    jint status = static_cast<jint>(layout.GetCountryStatus(coreGroup, corePosition));
    jint options = static_cast<jint>(layout.GetCountryOptions(coreGroup, corePosition));

    jclass createClass = env->FindClass("com/mapswithme/country/CountryItem");
    ASSERT(createClass, ());

    jmethodID createMethodId = env->GetMethodID(createClass, "<init>", "(Ljava/lang/String;IIZ)V");
    ASSERT(createMethodId, ());

    return env->NewObject(createClass, createMethodId,
                          name, status, options, JNI_FALSE);
  }

  JNIEXPORT jlong JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCountrySize(JNIEnv * env, jclass clazz, jint group, jint position, jint options, jboolean isLocal)
  {
    ActiveMapsLayout & layout = GetMapLayout();
    ActiveMapsLayout::TGroup coreGroup = ToGroup(group);
    int pos = static_cast<int>(position);
    bool const local = isLocal == JNI_TRUE;
    MapOptions opt = ToOptions(options);

    if (options == -1 || local)
    {
      LocalAndRemoteSizeT sizes = options == -1 ? layout.GetDownloadableCountrySize(coreGroup, pos)
                                                : layout.GetCountrySize(coreGroup, pos, opt);
      return local ? sizes.first : sizes.second;
    }

    LocalAndRemoteSizeT sizes = layout.GetRemoteCountrySizes(coreGroup, pos);
    switch (opt)
    {
      case MapOptions::Map:
        return sizes.first;
      case MapOptions::CarRouting:
        return sizes.second;
      default:
        return sizes.first + sizes.second;
    }
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_cancelDownloading(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    GetMapLayout().CancelDownloading(ToGroup(group), position);
  }

  JNIEXPORT jboolean JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_isDownloadingActive(JNIEnv * env, jclass clazz)
  {
    return GetMapLayout().IsDownloadingActive();
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_retryDownloading(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    GetMapLayout().RetryDownloading(ToGroup(group), position);
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_downloadMap(JNIEnv * env, jclass clazz, jint group, jint position, jint options)
  {
    GetMapLayout().DownloadMap(ToGroup(group), position, ToOptions(options));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_deleteMap(JNIEnv * env, jclass clazz, jint group, jint position, jint options)
  {
    GetMapLayout().DeleteMap(ToGroup(group), position, ToOptions(options));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_showOnMap(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    g_framework->PostDrapeTask([group, position]()
    {
      GetMapLayout().ShowMap(ToGroup(group), position);
    });
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_updateAll(JNIEnv * env, jclass clazz)
  {
    GetMapLayout().UpdateAll();
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_cancelAll(JNIEnv * env, jclass clazz)
  {
    GetMapLayout().CancelAll();
  }

  JNIEXPORT int JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_addListener(JNIEnv * env, jclass clazz, jobject listener)
  {
    return g_framework->AddActiveMapsListener(jni::make_global_ref(listener));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_removeListener(JNIEnv * env, jclass clazz, jint slotID)
  {
    g_framework->RemoveActiveMapsListener(slotID);
  }

  JNIEXPORT jobject JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_getCoreIndex(JNIEnv * env, jclass clazz, jint group, jint position)
  {
    return storage::ToJava(GetMapLayout().GetCoreIndex(static_cast<storage::ActiveMapsLayout::TGroup>(group),
                                                       static_cast<int>(position)));
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_downloadMapForIndex(JNIEnv * env, jclass clazz, jobject index, jint options)
  {
    GetMapLayout().DownloadMap(storage::ToNative(index), ToOptions(options));
  }

  JNIEXPORT jboolean JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_isLegacyMode(JNIEnv * env, jclass clazz)
  {
    return g_framework->NeedMigrate();
  }

  JNIEXPORT void JNICALL
  Java_com_mapswithme_country_ActiveCountryTree_migrate(JNIEnv * env, jclass clazz)
  {
    g_framework->Migrate();
  }
}
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "DebugOperatorNew.h"

#include "UiMainWindow.h"
#include "Framework.h"
#include "VersionInfo.h"
#include "ConfigAPI.h"
#include "LoggingFunctions.h"

#include <QCloseEvent>
#include <QDesktopWidget>
#include <QApplication>
#include <QMenuBar>

#include <utility>
#include <iostream>

#include "MemoryLeakCheck.h"

using namespace std;

UiMainWindow::UiMainWindow(Framework *owner_)
:owner(owner_)
{
    setAcceptDrops(true);
}

int UiMainWindow::DesktopWidth()
{
    QDesktopWidget *desktop = QApplication::desktop();
    if (!desktop)
    {
        std::string error("UiMainWindow::DesktopWidth: QApplication::desktop() returned null!");
        LogError(error);
        cerr << error << endl;
        return 1024; // Just guess some value for desktop width.
    }
    int width = 0;
    for(int i = 0; i < desktop->screenCount(); ++i)
        width += desktop->screenGeometry(i).width();

    return width;
}

int UiMainWindow::DesktopHeight()
{
    QDesktopWidget *desktop = QApplication::desktop();
    if (!desktop)
    {
        std::string error("UiMainWindow::DesktopHeight: QApplication::desktop() returned null!");
        LogError(error);
        cerr << error << endl;
        return 768; // Just guess some value for desktop height.
    }
    return desktop->screenGeometry().height();
}

void UiMainWindow::LoadWindowSettingsFromFile()
{
    ConfigData configData(ConfigAPI::FILE_FRAMEWORK, ConfigAPI::SECTION_UI);
    int width = owner->Config()->Get(configData, "window width", 800).toInt();
    int height = owner->Config()->Get(configData, "window height", 600).toInt();
    int windowX = owner->Config()->Get(configData, "window left", -1).toInt();
    int windowY = owner->Config()->Get(configData, "window top", -1).toInt();
    bool maximized = owner->Config()->Get(configData, "window maximized", false).toBool();
    bool fullscreen = owner->Config()->Get(configData, "fullscreen", false).toBool();

    // Round up width to next 16 to avoid startup artifacts with the Ogre blit
    width += 15;
    width &= 0xfffffff0;

    setWindowTitle(owner->ApplicationVersion()->GetFullIdentifier());

    width = max(1, min(DesktopWidth(), width));
    height = max(1, min(DesktopHeight(), height));
    windowX = max(0, min(DesktopWidth()-width, windowX));
    windowY = max(25, min(DesktopHeight()-height, windowY));

    resize(width, height);
    move(windowX, windowY);

    if (fullscreen)
        showFullScreen();
    else if (maximized)
        showMaximized();
    else
        showNormal();
}

void UiMainWindow::SaveWindowSettingsToFile()
{
    // The values (0, 25) and (-50, -20) below serve to artificially limit the main window positioning into awkward places.
    int windowX = max(0, min(DesktopWidth()-50, pos().x()));
    int windowY = max(25, min(DesktopHeight()-20, pos().y()));
    int width = max(1, min(DesktopWidth()-windowX, size().width()));
    int height = max(1, min(DesktopHeight()-windowY, size().height()));

    // If we are in windowed mode, store the window rectangle for next run.
    ConfigData configData(ConfigAPI::FILE_FRAMEWORK, ConfigAPI::SECTION_UI);
    if (!isMaximized() && !isFullScreen())
    {
        owner->Config()->Set(configData, "window width", width);
        owner->Config()->Set(configData, "window height", height);
        owner->Config()->Set(configData, "window left", windowX);
        owner->Config()->Set(configData, "window top", windowY);
    }
    owner->Config()->Set(configData, "window maximized", isMaximized());
    owner->Config()->Set(configData, "fullscreen", isFullScreen());
}

void UiMainWindow::closeEvent(QCloseEvent *e)
{
    emit WindowCloseEvent();
    e->ignore();
}

void UiMainWindow::resizeEvent(QResizeEvent *e)
{
    emit WindowResizeEvent(width(), height());
}

void UiMainWindow::EnsurePositionWithinDesktop(QWidget *widget, QPoint pos) const
{
    if (!widget)
    {
        LogError("UiMainWindow::EnsurePositionWithinDesktop: null widget passed!");
        return;
    }
    int xMax = DesktopWidth(), yMax = DesktopHeight();
    if (pos.x() + widget->height() > xMax)
        pos.setX(xMax - widget->width());
    if (pos.y() + widget->width() > yMax)
        pos.setY(yMax - widget->height());
    widget->move(pos);
}

bool UiMainWindow::HasMenu(const QString &name) const
{
    if (!menuBar())
        return false;

    QList<QString> menuNames = menus_.keys();
    return menuNames.contains(name);
}

QMenu *UiMainWindow::GetMenu(const QString &name) const
{
    if (!menuBar())
        return 0;

    if (HasMenu(name))
        return menus_[name];
    return 0;
}

QMenu *UiMainWindow::AddMenu(const QString &name)
{
    if (!menuBar())
        return 0;

    if (HasMenu(name))
        return menus_[name];
    QMenu *menu = menuBar()->addMenu(name);
    menus_[name] = menu;
    return menu;
}

QAction *UiMainWindow::AddMenuAction(const QString &menuName, const QString &actionName, const QIcon &icon)
{
    if (!menuBar())
        return 0;

    QMenu *menu = 0;
    if (HasMenu(menuName))
        menu = menus_[menuName];
    else
        menu = AddMenu(menuName);

    if (!menu)
        return 0;
    return menu->addAction(icon, actionName);
}
<commit_msg>Fixed swapped width/height params in UiMainWindow::EnsurePositionWithinDesktop. Altered the logic to allow windows to partially go outside the screen.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "DebugOperatorNew.h"

#include "UiMainWindow.h"
#include "Framework.h"
#include "VersionInfo.h"
#include "ConfigAPI.h"
#include "LoggingFunctions.h"

#include <QCloseEvent>
#include <QDesktopWidget>
#include <QApplication>
#include <QMenuBar>

#include <utility>
#include <iostream>

#include "MemoryLeakCheck.h"

using namespace std;

UiMainWindow::UiMainWindow(Framework *owner_)
:owner(owner_)
{
    setAcceptDrops(true);
}

int UiMainWindow::DesktopWidth()
{
    QDesktopWidget *desktop = QApplication::desktop();
    if (!desktop)
    {
        std::string error("UiMainWindow::DesktopWidth: QApplication::desktop() returned null!");
        LogError(error);
        cerr << error << endl;
        return 1024; // Just guess some value for desktop width.
    }
    int width = 0;
    for(int i = 0; i < desktop->screenCount(); ++i)
        width += desktop->screenGeometry(i).width();

    return width;
}

int UiMainWindow::DesktopHeight()
{
    QDesktopWidget *desktop = QApplication::desktop();
    if (!desktop)
    {
        std::string error("UiMainWindow::DesktopHeight: QApplication::desktop() returned null!");
        LogError(error);
        cerr << error << endl;
        return 768; // Just guess some value for desktop height.
    }
    return desktop->screenGeometry().height();
}

void UiMainWindow::LoadWindowSettingsFromFile()
{
    ConfigData configData(ConfigAPI::FILE_FRAMEWORK, ConfigAPI::SECTION_UI);
    int width = owner->Config()->Get(configData, "window width", 800).toInt();
    int height = owner->Config()->Get(configData, "window height", 600).toInt();
    int windowX = owner->Config()->Get(configData, "window left", -1).toInt();
    int windowY = owner->Config()->Get(configData, "window top", -1).toInt();
    bool maximized = owner->Config()->Get(configData, "window maximized", false).toBool();
    bool fullscreen = owner->Config()->Get(configData, "fullscreen", false).toBool();

    // Round up width to next 16 to avoid startup artifacts with the Ogre blit
    width += 15;
    width &= 0xfffffff0;

    setWindowTitle(owner->ApplicationVersion()->GetFullIdentifier());

    width = max(1, min(DesktopWidth(), width));
    height = max(1, min(DesktopHeight(), height));
    windowX = max(0, min(DesktopWidth()-width, windowX));
    windowY = max(25, min(DesktopHeight()-height, windowY));

    resize(width, height);
    move(windowX, windowY);

    if (fullscreen)
        showFullScreen();
    else if (maximized)
        showMaximized();
    else
        showNormal();
}

void UiMainWindow::SaveWindowSettingsToFile()
{
    // The values (0, 25) and (-50, -20) below serve to artificially limit the main window positioning into awkward places.
    int windowX = max(0, min(DesktopWidth()-50, pos().x()));
    int windowY = max(25, min(DesktopHeight()-20, pos().y()));
    int width = max(1, min(DesktopWidth()-windowX, size().width()));
    int height = max(1, min(DesktopHeight()-windowY, size().height()));

    // If we are in windowed mode, store the window rectangle for next run.
    ConfigData configData(ConfigAPI::FILE_FRAMEWORK, ConfigAPI::SECTION_UI);
    if (!isMaximized() && !isFullScreen())
    {
        owner->Config()->Set(configData, "window width", width);
        owner->Config()->Set(configData, "window height", height);
        owner->Config()->Set(configData, "window left", windowX);
        owner->Config()->Set(configData, "window top", windowY);
    }
    owner->Config()->Set(configData, "window maximized", isMaximized());
    owner->Config()->Set(configData, "fullscreen", isFullScreen());
}

void UiMainWindow::closeEvent(QCloseEvent *e)
{
    emit WindowCloseEvent();
    e->ignore();
}

void UiMainWindow::resizeEvent(QResizeEvent *e)
{
    emit WindowResizeEvent(width(), height());
}

void UiMainWindow::EnsurePositionWithinDesktop(QWidget *widget, QPoint pos) const
{
    if (!widget)
    {
        LogError("UiMainWindow::EnsurePositionWithinDesktop: null widget passed!");
        return;
    }
    int xMax = DesktopWidth(), yMax = DesktopHeight();

    // Allow setting windows partially outside the screen.
    // Apply an arbitrary guardband of (50x100) along the screen borders.
    const int w = max(widget->width()/2, 50);
    const int h = max(widget->height()/2, 100);
    if (pos.x() + w > xMax)
        pos.setX(xMax - w);
    if (pos.y() + h > yMax)
        pos.setY(yMax - h);
    if (pos.x() < 0)
        pos.setX(0);
    if (pos.y() < 0)
        pos.setY(0);
    widget->move(pos);
}

bool UiMainWindow::HasMenu(const QString &name) const
{
    if (!menuBar())
        return false;

    QList<QString> menuNames = menus_.keys();
    return menuNames.contains(name);
}

QMenu *UiMainWindow::GetMenu(const QString &name) const
{
    if (!menuBar())
        return 0;

    if (HasMenu(name))
        return menus_[name];
    return 0;
}

QMenu *UiMainWindow::AddMenu(const QString &name)
{
    if (!menuBar())
        return 0;

    if (HasMenu(name))
        return menus_[name];
    QMenu *menu = menuBar()->addMenu(name);
    menus_[name] = menu;
    return menu;
}

QAction *UiMainWindow::AddMenuAction(const QString &menuName, const QString &actionName, const QIcon &icon)
{
    if (!menuBar())
        return 0;

    QMenu *menu = 0;
    if (HasMenu(menuName))
        menu = menus_[menuName];
    else
        menu = AddMenu(menuName);

    if (!menu)
        return 0;
    return menu->addAction(icon, actionName);
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */
//
// Realisations of the AliGenReader interface to be used with AliGenExFile.
// NextEvent() loops over events
// and NextParticle() loops over particles.
// This implementation reads various StarLight output formats
// Author: andreas.morsch@cern.ch

#include <TVirtualMC.h>
#include <TDatabasePDG.h>
#include <TParticle.h>

#include "AliGenReaderSL.h"
#include "AliRun.h"

ClassImp(AliGenReaderSL)

AliGenReaderSL& AliGenReaderSL::operator=(const  AliGenReaderSL& rhs)
{
// Assignment operator
    rhs.Copy(*this);
    return *this;
}

void AliGenReaderSL::Copy(TObject&) const
{
    //
    // Copy
    //
    Fatal("Copy","Not implemented!\n");
}

void AliGenReaderSL::Init()
{
    // Initialisation
    if( !(fFile = fopen(fFileName,"r")) ) {
	printf("Couldn't open input file: %s \n", fFileName);
    } else {
	printf("File %s opened \n", fFileName);
    }

}

Int_t AliGenReaderSL::NextEvent()
{
// Read the next event

    if (fFormat == 0) {
	fNParticles = 4;
	return (fNParticles);
    }

// Example
// EVENT: 7 23 1
// GAMMAENERGIES: 27.6431
// VERTEX: 0 0 0 0 1 0 0 23
    char linelabel[20];
    int i1 = 0;
    int i2 = 0;
    int i3 = 0;

    double x1 = 0.0;
    double x2 = 0.0;
    double x3 = 0.0;
    double x4 = 0.0;

    int ntrk = 0;
    int nvtx = 0;
    //
    Float_t eGamma1, eGamma2;
    eGamma2 = 0.;

    // Event line
    fscanf(fFile,"%s %d %d %d ",linelabel, &i1, &ntrk, &i2);
    fNParticles = ntrk;
//    printf("Event line: %s i1 = %5d ntrk = %5d i2 = %5d \n", linelabel, i1, ntrk, i2);

    // Gamma line
    if (fFormat == 1) {
	fscanf(fFile, "%s %f  ",linelabel, &eGamma1);
    } else if (fFormat == 2) {
	fscanf(fFile, "%s %f %f ",linelabel, &eGamma1, &eGamma2);
    }

//  printf("Gamma line: %s Egamma1 = %13.3f Egamma2 = %13.3f \n", linelabel, eGamma1, eGamma2);

    // Vertex line
    fscanf(fFile, "%s %lf %lf %lf %lf %d %d %d %d",
	   linelabel, &x1, &x2, &x3, &x4, &i1, &i2, &i3, &nvtx);
//    printf("Vertex line: %s (x = %13.3f, y =  %13.3f, z =  %13.3f, t =  %13.3f) i1 = %5d i2 = %5d i3 = %5d nvtx = %5d \n",
//	   linelabel, x1, x2, x3, x4, i1, i2, i3, nvtx);
    if(ntrk != nvtx) printf("ERROR: ntrk = %5d  nvtx = %5d \n", ntrk, nvtx);

    return (fNParticles);

}

TParticle* AliGenReaderSL::NextParticle()
{
    // Read next particle

    Float_t px, py, pz;
    Int_t pdg;
    static TParticle particle;

    if (fFormat == 0) {
	Int_t ievent;
	Int_t ipart;
	fscanf(fFile, "%d %d %d %f %f %f ", &ievent, &ipart, &pdg, &px, &py, &pz);
//	printf("%5d %5d %5d %13.3f %13.3f %13.3f \n", ievent, ipart, pdg, px, py, pz);

	if (pdg == 8) pdg =  211;
	if (pdg == 9) pdg = -211;

    } else {
	char tracklabel[20];
	int i1 = 0;
	int i2 = 0;
	int i3 = 0;
	int i4 = 0;
	fscanf(fFile,"%s %d %f %f %f %d %d %d %d",
	       tracklabel, &i1, &px, &py, &pz, &i2, &i3, &i4, &pdg);
//	printf("Particle %5d %13.3f %13.3f %13.3f \n",  pdg, px, py, pz);
    }

    Double_t mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
    Float_t e = TMath::Sqrt(px * px + py * py + pz * pz + mass * mass);
    particle.SetMomentum(px, py, pz, e);
    particle.SetPdgCode(pdg);

    return &particle;
}

void AliGenReaderSL::RewindEvent()
{
//    fFile->Rewind();
}
<commit_msg>Coverity Fix.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */
//
// Realisations of the AliGenReader interface to be used with AliGenExFile.
// NextEvent() loops over events
// and NextParticle() loops over particles.
// This implementation reads various StarLight output formats
// Author: andreas.morsch@cern.ch

#include <TVirtualMC.h>
#include <TDatabasePDG.h>
#include <TParticle.h>

#include "AliGenReaderSL.h"
#include "AliRun.h"

ClassImp(AliGenReaderSL)

AliGenReaderSL& AliGenReaderSL::operator=(const  AliGenReaderSL& rhs)
{
// Assignment operator
    rhs.Copy(*this);
    return *this;
}

void AliGenReaderSL::Copy(TObject&) const
{
    //
    // Copy
    //
    Fatal("Copy","Not implemented!\n");
}

void AliGenReaderSL::Init()
{
    // Initialisation
    if( !(fFile = fopen(fFileName,"r")) ) {
	printf("Couldn't open input file: %s \n", fFileName);
    } else {
	printf("File %s opened \n", fFileName);
    }

}

Int_t AliGenReaderSL::NextEvent()
{
// Read the next event

    if (fFormat == 0) {
	fNParticles = 4;
	return (fNParticles);
    }

// Example
// EVENT: 7 23 1
// GAMMAENERGIES: 27.6431
// VERTEX: 0 0 0 0 1 0 0 23
    char linelabel[20];
    int i1 = 0;
    int i2 = 0;
    int i3 = 0;

    double x1 = 0.0;
    double x2 = 0.0;
    double x3 = 0.0;
    double x4 = 0.0;

    int ntrk = 0;
    int nvtx = 0;
    //
    Float_t eGamma1, eGamma2;
    eGamma2 = 0.;

    // Event line
    fscanf(fFile,"%6s %d %d %d ",linelabel, &i1, &ntrk, &i2);
    fNParticles = ntrk;
    //printf("Event line: %s i1 = %5d ntrk = %5d i2 = %5d \n", linelabel, i1, ntrk, i2);

    // Gamma line
    if (fFormat == 1) {
	fscanf(fFile, "%14s %f  ",linelabel, &eGamma1);
    } else if (fFormat == 2) {
	fscanf(fFile, "%14s %f %f ",linelabel, &eGamma1, &eGamma2);
    }

//    printf("Gamma line: %s Egamma1 = %13.3f Egamma2 = %13.3f \n", linelabel, eGamma1, eGamma2);

    // Vertex line
    fscanf(fFile, "%7s %lf %lf %lf %lf %d %d %d %d",
	   linelabel, &x1, &x2, &x3, &x4, &i1, &i2, &i3, &nvtx);
//    printf("Vertex line: %s (x = %13.3f, y =  %13.3f, z =  %13.3f, t =  %13.3f) i1 = %5d i2 = %5d i3 = %5d nvtx = %5d \n",
//	   linelabel, x1, x2, x3, x4, i1, i2, i3, nvtx);
    if(ntrk != nvtx) printf("ERROR: ntrk = %5d  nvtx = %5d \n", ntrk, nvtx);

    return (fNParticles);

}

TParticle* AliGenReaderSL::NextParticle()
{
    // Read next particle

    Float_t px, py, pz;
    Int_t pdg;
    static TParticle particle;

    if (fFormat == 0) {
	Int_t ievent;
	Int_t ipart;
	fscanf(fFile, "%d %d %d %f %f %f ", &ievent, &ipart, &pdg, &px, &py, &pz);
//	printf("%5d %5d %5d %13.3f %13.3f %13.3f \n", ievent, ipart, pdg, px, py, pz);

	if (pdg == 8) pdg =  211;
	if (pdg == 9) pdg = -211;

    } else {
	char tracklabel[20];
	int i1 = 0;
	int i2 = 0;
	int i3 = 0;
	int i4 = 0;
	fscanf(fFile,"%6s %d %f %f %f %d %d %d %d",
	       tracklabel, &i1, &px, &py, &pz, &i2, &i3, &i4, &pdg);
//	printf("Particle %5d %13.3f %13.3f %13.3f \n",  pdg, px, py, pz);
    }

    Double_t mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
    Float_t e = TMath::Sqrt(px * px + py * py + pz * pz + mass * mass);
    particle.SetMomentum(px, py, pz, e);
    particle.SetPdgCode(pdg);

    return &particle;
}

void AliGenReaderSL::RewindEvent()
{
//    fFile->Rewind();
}
<|endoftext|>


<commit_before>/*
GPE_Tiles.cpp
This file is part of:
GAME PENCIL ENGINE
https://create.pawbyte.com
Copyright (c) 2014-2019 Nathan Hurde, Chase Lee.

Copyright (c) 2014-2019 PawByte LLC.
Copyright (c) 2014-2019 Game Pencil Engine contributors ( Contributors Page )

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

-Game Pencil Engine <https://create.pawbyte.com>

*/

#include "GPE_Tiles.h"

GPE_GameMapTile::GPE_GameMapTile()
{
    tset = IS_NULL;
    tileIdNumb = IS_NULL;
    tSetPos = -1;
    xCoord = 0;
    yCoord = 0;
    tileLayer = -1;
    tileType =0;
    isSolid = false;
    drewBefore = false;
    tileBox = new GPE_Rect();
    tileBox->update_shape(0,0,32,32);
}

GPE_GameMapTile::~GPE_GameMapTile()
{
    if( tileBox!=NULL)
    {
        delete tileBox;
        tileBox = NULL;
    }
}

int GPE_GameMapTile::get_type ()
{
    return tileType;
}

void GPE_GameMapTile::update_box ( int xNew,  int yNew,  int wNew, int hNew)
{
    tileBox->update_shape(xNew,yNew,wNew,hNew);
}

void GPE_GameMapTile::render_self ( GPE_Rect * cam )
{
    //ensures that the Tilesheet for the tile isn't NULL
    if(tset >=0 && tset < (int)gcm->rTilesheets.size() )
    {
        GPE_Tilesheet * gameTilesheet = gcm->rTilesheets[tset];
        //console.log( tset)
        if( gameTilesheet!=NULL )
        {
            //checks to see if tile is in the camera region
            //if(gpe.check_collision_with_rect(xCoord,yCoord-tileBox.get_height()-cam.get_y(),tileBox.get_width(),tileBox.get_height(),cam) == true )
            //{
            if( gameTilesheet->tsImage!=NULL )
            {
                if( cam!=NULL)
                {
                    gameTilesheet->tsImage->render_tex( xCoord - cam->x,yCoord - cam->y,tileBox);
                }
                else
                {
                    gameTilesheet->tsImage->render_tex( xCoord,yCoord,tileBox);
                }
            }
            //}
        }
    }
}

void GPE_GameMapTile::render_self_auto ( GPE_Rect * cam)
{
    render_self( cam );
}

GPE_LayerTileMapObject::GPE_LayerTileMapObject()
{
    tileAmountX = IS_NULL;
    tileAmountY = IS_NULL;
}

GPE_LayerTileMapObject::~GPE_LayerTileMapObject()
{
    clear_tiles();
}

void GPE_LayerTileMapObject::clear_tiles()
{
    GPE_GameMapTile *  tempTile = NULL;
    for( int i = (int)layerTiles.size()-1; i >=0; i-- )
    {
        tempTile = layerTiles[i];
        if( tempTile!=NULL)
        {
            delete tempTile;
            tempTile = NULL;
        }
    }
    layerTiles.clear();
}

void GPE_LayerTileMapObject::create_new_map ( int newTX, int newTY)
{
    tileAmountX=newTX;
    tileAmountY=newTY;
    int newSize = tileAmountX*tileAmountY;
    int i=0;
    clear_tiles();
    for(i=0; i<newSize; i++)
    {
        layerTiles[i] = new GPE_GameMapTile();
        layerTiles[i]->tileType = 0;
    }
}

int GPE_LayerTileMapObject::find_tile ( int xPos, int yPos )
{
    if( tileWidth==0 || tileHeight == 0)
    {
        return IS_NULL;
    }
    // find rectangle to check (limited to field size):
    xPos = std::max(0, std::min(gridWidth - 1, (xPos / tileWidth)|0 ) );
    yPos = std::max(0, std::min(gridHeight - 1,(yPos / tileHeight)|0 ) );

    GPE_GameMapTile * foundTile = NULL;
    foundTile = get_tile_at(xPos, yPos);
    if(foundTile!= NULL )
    {
        return foundTile->tset;
    }
    return IS_NULL;
}

int GPE_LayerTileMapObject::find_tile_in_box(  int x1,  int y1,  int x2, int y2 )
{
    if( tileWidth==0 || tileHeight == 0)
    {
        return IS_NULL;
    }
    int i=0;
    int j=0;
    int l=0;
    int t=0;
    int r=0;
    int b=0;
    GPE_GameMapTile * foundTile = NULL;
    // find rectangle to check (limited to field size):
    l = std::max(0, std::min(gridWidth - 1, (x1 / tileWidth)|0 ) );
    t = std::max(0, std::min(gridHeight - 1,(y1 / tileHeight)|0 ) );
    r = std::max(0, std::min(gridWidth - 1, (x2 / tileWidth)|0 ) );
    b = std::max(0, std::min(gridHeight - 1, (y2 / tileHeight)|0  ) );

    for (j = t; j <= b; j += 1)
    {
        for (i = l; i <= r; i += 1)
        {
            foundTile = get_tile_at(i, j);
            if(foundTile!= NULL )
            {
                return foundTile->tset;
            }
        }
    }
    return IS_NULL;
}

bool GPE_LayerTileMapObject::find_matching_tile( int xPos,  int yPos,  int tileTypeToSearchFor )
{
    //if we have an actual layer to look for
    if( tileWidth==0 || tileHeight == 0)
    {
        return false;
    }
    GPE_GameMapTile * foundTile = NULL;
    // find rectangle to check (limited to field size):
    xPos = std::max(0, std::min(gridWidth - 1, (xPos / tileWidth)|0 ) );
    yPos = std::max(0, std::min(gridHeight - 1,(yPos / tileHeight)|0 ) );
    foundTile = get_tile_at(xPos, yPos);
    if( foundTile!= NULL && foundTile->tset == tileTypeToSearchFor )
    {
        return true;
    }
    return false;
}

bool GPE_LayerTileMapObject::find_matching_tile_in_box( int x1,  int y1,  int x2, int y2,  int tileTypeToSearchFor)
{
    if( tileWidth==0 || tileHeight == 0)
    {
        return false;
    }
    int l = std::max(0, std::min(gridWidth - 1, (x1 / tileWidth)|0 ) );
    int t = std::max(0, std::min(gridHeight - 1,(y1 / tileHeight)|0 ) );
    int r = std::max(0, std::min(gridWidth - 1, (x2 / tileWidth)|0 ) );
    int b = std::max(0, std::min(gridHeight - 1, (y2 / tileHeight)|0  ) );
    GPE_GameMapTile * foundTile = NULL;
    int i=0;
    int j=0;
    // find rectangle to check (limited to field size):
    for (j = t; j <= b; j += 1)
    {
        for (i = l; i <= r; i += 1)
        {
            foundTile = get_tile_at(i, j);
            if(foundTile!= NULL && foundTile->tset == tileTypeToSearchFor )
            {
                return true;
            }
        }
    }
    return false;
}

int GPE_LayerTileMapObject::get_map_size()
{
    return (int)layerTiles.size();
}

GPE_GameMapTile * GPE_LayerTileMapObject::get_tile_at ( int xIn,  int yIn )
{
    int seekedTile = xIn+ yIn*tileAmountX;
    if(  seekedTile>=0 && seekedTile < (int)layerTiles.size() )
        return layerTiles[seekedTile];
    return NULL;
}
<commit_msg>Delete GPE_Tiles.cpp<commit_after><|endoftext|>


<commit_before>#include <nano/node/node.hpp>
#include <nano/node/vote_processor.hpp>

nano::vote_processor::vote_processor (nano::node & node_a) :
node (node_a),
started (false),
stopped (false),
active (false),
thread ([this]() {
	nano::thread_role::set (nano::thread_role::name::vote_processing);
	process_loop ();
})
{
	std::unique_lock<std::mutex> lock (mutex);
	while (!started)
	{
		condition.wait (lock);
	}
}

void nano::vote_processor::process_loop ()
{
	std::chrono::steady_clock::time_point start_time, end_time;
	std::chrono::steady_clock::duration elapsed_time;
	std::chrono::milliseconds elapsed_time_ms;
	uint64_t elapsed_time_ms_int;
	bool log_this_iteration;

	std::unique_lock<std::mutex> lock (mutex);
	started = true;

	lock.unlock ();
	condition.notify_all ();
	lock.lock ();

	while (!stopped)
	{
		if (!votes.empty ())
		{
			std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> votes_l;
			votes_l.swap (votes);

			log_this_iteration = false;
			if (node.config.logging.network_logging () && votes_l.size () > 50)
			{
				/*
				 * Only log the timing information for this iteration if
				 * there are a sufficient number of items for it to be relevant
				 */
				log_this_iteration = true;
				start_time = std::chrono::steady_clock::now ();
			}
			active = true;
			lock.unlock ();
			verify_votes (votes_l);
			{
				std::unique_lock<std::mutex> active_single_lock (node.active.mutex);
				auto transaction (node.store.tx_begin_read ());
				uint64_t count (1);
				for (auto & i : votes_l)
				{
					vote_blocking (transaction, i.first, i.second, true);
					// Free active_transactions mutex each 100 processed votes
					if (count % 100 == 0)
					{
						active_single_lock.unlock ();
						active_single_lock.lock ();
					}
					count++;
				}
			}
			lock.lock ();
			active = false;

			lock.unlock ();
			condition.notify_all ();
			lock.lock ();

			if (log_this_iteration)
			{
				end_time = std::chrono::steady_clock::now ();
				elapsed_time = end_time - start_time;
				elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds> (elapsed_time);
				elapsed_time_ms_int = elapsed_time_ms.count ();

				if (elapsed_time_ms_int >= 100)
				{
					/*
					 * If the time spent was less than 100ms then
					 * the results are probably not useful as well,
					 * so don't spam the logs.
					 */
					node.logger.try_log (boost::str (boost::format ("Processed %1% votes in %2% milliseconds (rate of %3% votes per second)") % votes_l.size () % elapsed_time_ms_int % ((votes_l.size () * 1000ULL) / elapsed_time_ms_int)));
				}
			}
		}
		else
		{
			condition.wait (lock);
		}
	}
}

void nano::vote_processor::vote (std::shared_ptr<nano::vote> vote_a, std::shared_ptr<nano::transport::channel> channel_a)
{
	std::unique_lock<std::mutex> lock (mutex);
	if (!stopped)
	{
		bool process (false);
		/* Random early delection levels
		 Always process votes for test network (process = true)
		 Stop processing with max 144 * 1024 votes */
		if (!node.network_params.network.is_test_network ())
		{
			// Level 0 (< 0.1%)
			if (votes.size () < 96 * 1024)
			{
				process = true;
			}
			// Level 1 (0.1-1%)
			else if (votes.size () < 112 * 1024)
			{
				process = (representatives_1.find (vote_a->account) != representatives_1.end ());
			}
			// Level 2 (1-5%)
			else if (votes.size () < 128 * 1024)
			{
				process = (representatives_2.find (vote_a->account) != representatives_2.end ());
			}
			// Level 3 (> 5%)
			else if (votes.size () < 144 * 1024)
			{
				process = (representatives_3.find (vote_a->account) != representatives_3.end ());
			}
		}
		else
		{
			// Process for test network
			process = true;
		}
		if (process)
		{
			votes.push_back (std::make_pair (vote_a, channel_a));

			lock.unlock ();
			condition.notify_all ();
			lock.lock ();
		}
		else
		{
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_overflow);
		}
	}
}

void nano::vote_processor::verify_votes (std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> & votes_a)
{
	auto size (votes_a.size ());
	std::vector<unsigned char const *> messages;
	messages.reserve (size);
	std::vector<nano::uint256_union> hashes;
	hashes.reserve (size);
	std::vector<size_t> lengths (size, sizeof (nano::uint256_union));
	std::vector<unsigned char const *> pub_keys;
	pub_keys.reserve (size);
	std::vector<unsigned char const *> signatures;
	signatures.reserve (size);
	std::vector<int> verifications;
	verifications.resize (size);
	for (auto & vote : votes_a)
	{
		hashes.push_back (vote.first->hash ());
		messages.push_back (hashes.back ().bytes.data ());
		pub_keys.push_back (vote.first->account.bytes.data ());
		signatures.push_back (vote.first->signature.bytes.data ());
	}
	nano::signature_check_set check = { size, messages.data (), lengths.data (), pub_keys.data (), signatures.data (), verifications.data () };
	node.checker.verify (check);
	std::remove_reference_t<decltype (votes_a)> result;
	auto i (0);
	for (auto & vote : votes_a)
	{
		assert (verifications[i] == 1 || verifications[i] == 0);
		if (verifications[i] == 1)
		{
			result.push_back (vote);
		}
		++i;
	}
	votes_a.swap (result);
}

// node.active.mutex lock required
nano::vote_code nano::vote_processor::vote_blocking (nano::transaction const & transaction_a, std::shared_ptr<nano::vote> vote_a, std::shared_ptr<nano::transport::channel> channel_a, bool validated)
{
	assert (!node.active.mutex.try_lock ());
	auto result (nano::vote_code::invalid);
	if (validated || !vote_a->validate ())
	{
		auto max_vote (node.store.vote_max (transaction_a, vote_a));
		result = nano::vote_code::replay;
		if (!node.active.vote (vote_a, true))
		{
			result = nano::vote_code::vote;
		}
		switch (result)
		{
			case nano::vote_code::vote:
				node.observers.vote.notify (transaction_a, vote_a, channel_a);
			case nano::vote_code::replay:
				// This tries to assist rep nodes that have lost track of their highest sequence number by replaying our highest known vote back to them
				// Only do this if the sequence number is significantly different to account for network reordering
				// Amplify attack considerations: We're sending out a confirm_ack in response to a confirm_ack for no net traffic increase
				if (max_vote->sequence > vote_a->sequence + 10000)
				{
					nano::confirm_ack confirm (max_vote);
					channel_a->send (confirm); // this is non essential traffic as it will be resolicited if not received
				}
				break;
			case nano::vote_code::invalid:
				assert (false);
				break;
		}
	}
	std::string status;
	switch (result)
	{
		case nano::vote_code::invalid:
			status = "Invalid";
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_invalid);
			break;
		case nano::vote_code::replay:
			status = "Replay";
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_replay);
			break;
		case nano::vote_code::vote:
			status = "Vote";
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_valid);
			break;
	}
	if (node.config.logging.vote_logging ())
	{
		node.logger.try_log (boost::str (boost::format ("Vote from: %1% sequence: %2% block(s): %3%status: %4%") % vote_a->account.to_account () % std::to_string (vote_a->sequence) % vote_a->hashes_string () % status));
	}
	return result;
}

void nano::vote_processor::stop ()
{
	{
		std::lock_guard<std::mutex> lock (mutex);
		stopped = true;
	}
	condition.notify_all ();
	if (thread.joinable ())
	{
		thread.join ();
	}
}

void nano::vote_processor::flush ()
{
	std::unique_lock<std::mutex> lock (mutex);
	while (active || !votes.empty ())
	{
		condition.wait (lock);
	}
}

void nano::vote_processor::calculate_weights ()
{
	std::unique_lock<std::mutex> lock (mutex);
	if (!stopped)
	{
		representatives_1.clear ();
		representatives_2.clear ();
		representatives_3.clear ();
		auto supply (node.online_reps.online_stake ());
		auto transaction (node.store.tx_begin_read ());
		for (auto i (node.store.representation_begin (transaction)), n (node.store.representation_end ()); i != n; ++i)
		{
			nano::account const & representative (i->first);
			auto weight (node.ledger.weight (transaction, representative));
			if (weight > supply / 1000) // 0.1% or above (level 1)
			{
				representatives_1.insert (representative);
				if (weight > supply / 100) // 1% or above (level 2)
				{
					representatives_2.insert (representative);
					if (weight > supply / 20) // 5% or above (level 3)
					{
						representatives_3.insert (representative);
					}
				}
			}
		}
	}
}

namespace nano
{
std::unique_ptr<seq_con_info_component> collect_seq_con_info (vote_processor & vote_processor, const std::string & name)
{
	size_t votes_count = 0;
	size_t representatives_1_count = 0;
	size_t representatives_2_count = 0;
	size_t representatives_3_count = 0;

	{
		std::lock_guard<std::mutex> guard (vote_processor.mutex);
		votes_count = vote_processor.votes.size ();
		representatives_1_count = vote_processor.representatives_1.size ();
		representatives_2_count = vote_processor.representatives_2.size ();
		representatives_3_count = vote_processor.representatives_3.size ();
	}

	auto composite = std::make_unique<seq_con_info_composite> (name);
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "votes", votes_count, sizeof (decltype (vote_processor.votes)::value_type) }));
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "representatives_1", representatives_1_count, sizeof (decltype (vote_processor.representatives_1)::value_type) }));
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "representatives_2", representatives_2_count, sizeof (decltype (vote_processor.representatives_2)::value_type) }));
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "representatives_3", representatives_3_count, sizeof (decltype (vote_processor.representatives_3)::value_type) }));
	return composite;
}
}
<commit_msg>Reduce time holding read transaction in vote processor (#2231)<commit_after>#include <nano/node/node.hpp>
#include <nano/node/vote_processor.hpp>

nano::vote_processor::vote_processor (nano::node & node_a) :
node (node_a),
started (false),
stopped (false),
active (false),
thread ([this]() {
	nano::thread_role::set (nano::thread_role::name::vote_processing);
	process_loop ();
})
{
	std::unique_lock<std::mutex> lock (mutex);
	while (!started)
	{
		condition.wait (lock);
	}
}

void nano::vote_processor::process_loop ()
{
	std::chrono::steady_clock::time_point start_time, end_time;
	std::chrono::steady_clock::duration elapsed_time;
	std::chrono::milliseconds elapsed_time_ms;
	uint64_t elapsed_time_ms_int;
	bool log_this_iteration;

	std::unique_lock<std::mutex> lock (mutex);
	started = true;

	lock.unlock ();
	condition.notify_all ();
	lock.lock ();

	while (!stopped)
	{
		if (!votes.empty ())
		{
			std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> votes_l;
			votes_l.swap (votes);

			log_this_iteration = false;
			if (node.config.logging.network_logging () && votes_l.size () > 50)
			{
				/*
				 * Only log the timing information for this iteration if
				 * there are a sufficient number of items for it to be relevant
				 */
				log_this_iteration = true;
				start_time = std::chrono::steady_clock::now ();
			}
			active = true;
			lock.unlock ();
			verify_votes (votes_l);
			{
				std::unique_lock<std::mutex> active_single_lock (node.active.mutex);
				auto transaction (node.store.tx_begin_read ());
				uint64_t count (1);
				for (auto & i : votes_l)
				{
					vote_blocking (transaction, i.first, i.second, true);
					// Free active_transactions mutex each 100 processed votes
					if (count % 100 == 0)
					{
						active_single_lock.unlock ();
						transaction.refresh ();
						active_single_lock.lock ();
					}
					count++;
				}
			}
			lock.lock ();
			active = false;

			lock.unlock ();
			condition.notify_all ();
			lock.lock ();

			if (log_this_iteration)
			{
				end_time = std::chrono::steady_clock::now ();
				elapsed_time = end_time - start_time;
				elapsed_time_ms = std::chrono::duration_cast<std::chrono::milliseconds> (elapsed_time);
				elapsed_time_ms_int = elapsed_time_ms.count ();

				if (elapsed_time_ms_int >= 100)
				{
					/*
					 * If the time spent was less than 100ms then
					 * the results are probably not useful as well,
					 * so don't spam the logs.
					 */
					node.logger.try_log (boost::str (boost::format ("Processed %1% votes in %2% milliseconds (rate of %3% votes per second)") % votes_l.size () % elapsed_time_ms_int % ((votes_l.size () * 1000ULL) / elapsed_time_ms_int)));
				}
			}
		}
		else
		{
			condition.wait (lock);
		}
	}
}

void nano::vote_processor::vote (std::shared_ptr<nano::vote> vote_a, std::shared_ptr<nano::transport::channel> channel_a)
{
	std::unique_lock<std::mutex> lock (mutex);
	if (!stopped)
	{
		bool process (false);
		/* Random early delection levels
		 Always process votes for test network (process = true)
		 Stop processing with max 144 * 1024 votes */
		if (!node.network_params.network.is_test_network ())
		{
			// Level 0 (< 0.1%)
			if (votes.size () < 96 * 1024)
			{
				process = true;
			}
			// Level 1 (0.1-1%)
			else if (votes.size () < 112 * 1024)
			{
				process = (representatives_1.find (vote_a->account) != representatives_1.end ());
			}
			// Level 2 (1-5%)
			else if (votes.size () < 128 * 1024)
			{
				process = (representatives_2.find (vote_a->account) != representatives_2.end ());
			}
			// Level 3 (> 5%)
			else if (votes.size () < 144 * 1024)
			{
				process = (representatives_3.find (vote_a->account) != representatives_3.end ());
			}
		}
		else
		{
			// Process for test network
			process = true;
		}
		if (process)
		{
			votes.push_back (std::make_pair (vote_a, channel_a));

			lock.unlock ();
			condition.notify_all ();
			lock.lock ();
		}
		else
		{
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_overflow);
		}
	}
}

void nano::vote_processor::verify_votes (std::deque<std::pair<std::shared_ptr<nano::vote>, std::shared_ptr<nano::transport::channel>>> & votes_a)
{
	auto size (votes_a.size ());
	std::vector<unsigned char const *> messages;
	messages.reserve (size);
	std::vector<nano::uint256_union> hashes;
	hashes.reserve (size);
	std::vector<size_t> lengths (size, sizeof (nano::uint256_union));
	std::vector<unsigned char const *> pub_keys;
	pub_keys.reserve (size);
	std::vector<unsigned char const *> signatures;
	signatures.reserve (size);
	std::vector<int> verifications;
	verifications.resize (size);
	for (auto & vote : votes_a)
	{
		hashes.push_back (vote.first->hash ());
		messages.push_back (hashes.back ().bytes.data ());
		pub_keys.push_back (vote.first->account.bytes.data ());
		signatures.push_back (vote.first->signature.bytes.data ());
	}
	nano::signature_check_set check = { size, messages.data (), lengths.data (), pub_keys.data (), signatures.data (), verifications.data () };
	node.checker.verify (check);
	std::remove_reference_t<decltype (votes_a)> result;
	auto i (0);
	for (auto & vote : votes_a)
	{
		assert (verifications[i] == 1 || verifications[i] == 0);
		if (verifications[i] == 1)
		{
			result.push_back (vote);
		}
		++i;
	}
	votes_a.swap (result);
}

// node.active.mutex lock required
nano::vote_code nano::vote_processor::vote_blocking (nano::transaction const & transaction_a, std::shared_ptr<nano::vote> vote_a, std::shared_ptr<nano::transport::channel> channel_a, bool validated)
{
	assert (!node.active.mutex.try_lock ());
	auto result (nano::vote_code::invalid);
	if (validated || !vote_a->validate ())
	{
		auto max_vote (node.store.vote_max (transaction_a, vote_a));
		result = nano::vote_code::replay;
		if (!node.active.vote (vote_a, true))
		{
			result = nano::vote_code::vote;
		}
		switch (result)
		{
			case nano::vote_code::vote:
				node.observers.vote.notify (transaction_a, vote_a, channel_a);
			case nano::vote_code::replay:
				// This tries to assist rep nodes that have lost track of their highest sequence number by replaying our highest known vote back to them
				// Only do this if the sequence number is significantly different to account for network reordering
				// Amplify attack considerations: We're sending out a confirm_ack in response to a confirm_ack for no net traffic increase
				if (max_vote->sequence > vote_a->sequence + 10000)
				{
					nano::confirm_ack confirm (max_vote);
					channel_a->send (confirm); // this is non essential traffic as it will be resolicited if not received
				}
				break;
			case nano::vote_code::invalid:
				assert (false);
				break;
		}
	}
	std::string status;
	switch (result)
	{
		case nano::vote_code::invalid:
			status = "Invalid";
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_invalid);
			break;
		case nano::vote_code::replay:
			status = "Replay";
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_replay);
			break;
		case nano::vote_code::vote:
			status = "Vote";
			node.stats.inc (nano::stat::type::vote, nano::stat::detail::vote_valid);
			break;
	}
	if (node.config.logging.vote_logging ())
	{
		node.logger.try_log (boost::str (boost::format ("Vote from: %1% sequence: %2% block(s): %3%status: %4%") % vote_a->account.to_account () % std::to_string (vote_a->sequence) % vote_a->hashes_string () % status));
	}
	return result;
}

void nano::vote_processor::stop ()
{
	{
		std::lock_guard<std::mutex> lock (mutex);
		stopped = true;
	}
	condition.notify_all ();
	if (thread.joinable ())
	{
		thread.join ();
	}
}

void nano::vote_processor::flush ()
{
	std::unique_lock<std::mutex> lock (mutex);
	while (active || !votes.empty ())
	{
		condition.wait (lock);
	}
}

void nano::vote_processor::calculate_weights ()
{
	std::unique_lock<std::mutex> lock (mutex);
	if (!stopped)
	{
		representatives_1.clear ();
		representatives_2.clear ();
		representatives_3.clear ();
		auto supply (node.online_reps.online_stake ());
		auto transaction (node.store.tx_begin_read ());
		for (auto i (node.store.representation_begin (transaction)), n (node.store.representation_end ()); i != n; ++i)
		{
			nano::account const & representative (i->first);
			auto weight (node.ledger.weight (transaction, representative));
			if (weight > supply / 1000) // 0.1% or above (level 1)
			{
				representatives_1.insert (representative);
				if (weight > supply / 100) // 1% or above (level 2)
				{
					representatives_2.insert (representative);
					if (weight > supply / 20) // 5% or above (level 3)
					{
						representatives_3.insert (representative);
					}
				}
			}
		}
	}
}

namespace nano
{
std::unique_ptr<seq_con_info_component> collect_seq_con_info (vote_processor & vote_processor, const std::string & name)
{
	size_t votes_count = 0;
	size_t representatives_1_count = 0;
	size_t representatives_2_count = 0;
	size_t representatives_3_count = 0;

	{
		std::lock_guard<std::mutex> guard (vote_processor.mutex);
		votes_count = vote_processor.votes.size ();
		representatives_1_count = vote_processor.representatives_1.size ();
		representatives_2_count = vote_processor.representatives_2.size ();
		representatives_3_count = vote_processor.representatives_3.size ();
	}

	auto composite = std::make_unique<seq_con_info_composite> (name);
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "votes", votes_count, sizeof (decltype (vote_processor.votes)::value_type) }));
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "representatives_1", representatives_1_count, sizeof (decltype (vote_processor.representatives_1)::value_type) }));
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "representatives_2", representatives_2_count, sizeof (decltype (vote_processor.representatives_2)::value_type) }));
	composite->add_component (std::make_unique<seq_con_info_leaf> (seq_con_info{ "representatives_3", representatives_3_count, sizeof (decltype (vote_processor.representatives_3)::value_type) }));
	return composite;
}
}
<|endoftext|>


<commit_before><commit_msg>Coverity: Argument cannot be negative (actually a bug by using the wrong index variable)<commit_after><|endoftext|>


<commit_before>/*
 * Copyright © 2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "brw_vec4.h"
#include "brw_vec4_live_variables.h"
#include "brw_cfg.h"

/** @file brw_vec4_dead_code_eliminate.cpp
 *
 * Dataflow-aware dead code elimination.
 *
 * Walks the instruction list from the bottom, removing instructions that
 * have results that both aren't used in later blocks and haven't been read
 * yet in the tail end of this block.
 */

using namespace brw;

static bool
can_do_writemask(const struct brw_context *brw,
                 const vec4_instruction *inst)
{
   switch (inst->opcode) {
   case SHADER_OPCODE_GEN4_SCRATCH_READ:
   case VS_OPCODE_PULL_CONSTANT_LOAD:
   case VS_OPCODE_PULL_CONSTANT_LOAD_GEN7:
      return false;
   default:
      /* The MATH instruction on Gen6 only executes in align1 mode, which does
       * not support writemasking.
       */
      if (brw->gen == 6 && inst->is_math())
         return false;

      if (inst->is_tex())
         return false;

      return true;
   }
}

bool
vec4_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
   BITSET_WORD *flag_live = ralloc_array(NULL, BITSET_WORD, 1);

   foreach_block(block, cfg) {
      memcpy(live, live_intervals->block_data[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
      memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
             sizeof(BITSET_WORD));

      foreach_inst_in_block_reverse(vec4_instruction, inst, block) {
         if (inst->dst.file == GRF && !inst->has_side_effects()) {
            bool result_live[4] = { false };

            for (int c = 0; c < 4; c++) {
               int var = inst->dst.reg * 4 + c;
               result_live[c] = BITSET_TEST(live, var);
            }

            /* If the instruction can't do writemasking, then it's all or
             * nothing.
             */
            if (!can_do_writemask(brw, inst)) {
               bool result = result_live[0] | result_live[1] |
                             result_live[2] | result_live[3];
               result_live[0] = result;
               result_live[1] = result;
               result_live[2] = result;
               result_live[3] = result;
            }

            for (int c = 0; c < 4; c++) {
               if (!result_live[c] && inst->dst.writemask & (1 << c)) {
                  inst->dst.writemask &= ~(1 << c);
                  progress = true;

                  if (inst->dst.writemask == 0) {
                     if (inst->writes_accumulator) {
                        inst->dst = dst_reg(retype(brw_null_reg(), inst->dst.type));
                     } else {
                        inst->opcode = BRW_OPCODE_NOP;
                        continue;
                     }
                  }
               }
            }
         }

         if (inst->dst.is_null() && inst->writes_flag()) {
            if (!BITSET_TEST(flag_live, 0)) {
               inst->opcode = BRW_OPCODE_NOP;
               progress = true;
               continue;
            }
         }

         if (inst->dst.file == GRF && !inst->predicate) {
            for (int c = 0; c < 4; c++) {
               if (inst->dst.writemask & (1 << c)) {
                  int var = inst->dst.reg * 4 + c;
                  BITSET_CLEAR(live, var);
               }
            }
         }

         if (inst->writes_flag()) {
            BITSET_CLEAR(flag_live, 0);
         }

         for (int i = 0; i < 3; i++) {
            if (inst->src[i].file == GRF) {
               for (int c = 0; c < 4; c++) {
                  int swiz = BRW_GET_SWZ(inst->src[i].swizzle, c);
                  int var = inst->src[i].reg * 4 + swiz;

                  BITSET_SET(live, var);
               }
            }
         }

         if (inst->reads_flag()) {
            BITSET_SET(flag_live, 0);
         }
      }
   }

   ralloc_free(live);
   ralloc_free(flag_live);

   if (progress) {
      foreach_block_and_inst_safe(block, backend_instruction, inst, cfg) {
         if (inst->opcode == BRW_OPCODE_NOP) {
            inst->remove(block);
         }
      }

      invalidate_live_intervals();
   }

   return progress;
}
<commit_msg>i965/vec4: Don't DCE flag-writing insts because dest was unused.<commit_after>/*
 * Copyright © 2014 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "brw_vec4.h"
#include "brw_vec4_live_variables.h"
#include "brw_cfg.h"

/** @file brw_vec4_dead_code_eliminate.cpp
 *
 * Dataflow-aware dead code elimination.
 *
 * Walks the instruction list from the bottom, removing instructions that
 * have results that both aren't used in later blocks and haven't been read
 * yet in the tail end of this block.
 */

using namespace brw;

static bool
can_do_writemask(const struct brw_context *brw,
                 const vec4_instruction *inst)
{
   switch (inst->opcode) {
   case SHADER_OPCODE_GEN4_SCRATCH_READ:
   case VS_OPCODE_PULL_CONSTANT_LOAD:
   case VS_OPCODE_PULL_CONSTANT_LOAD_GEN7:
      return false;
   default:
      /* The MATH instruction on Gen6 only executes in align1 mode, which does
       * not support writemasking.
       */
      if (brw->gen == 6 && inst->is_math())
         return false;

      if (inst->is_tex())
         return false;

      return true;
   }
}

bool
vec4_visitor::dead_code_eliminate()
{
   bool progress = false;

   calculate_live_intervals();

   int num_vars = live_intervals->num_vars;
   BITSET_WORD *live = ralloc_array(NULL, BITSET_WORD, BITSET_WORDS(num_vars));
   BITSET_WORD *flag_live = ralloc_array(NULL, BITSET_WORD, 1);

   foreach_block(block, cfg) {
      memcpy(live, live_intervals->block_data[block->num].liveout,
             sizeof(BITSET_WORD) * BITSET_WORDS(num_vars));
      memcpy(flag_live, live_intervals->block_data[block->num].flag_liveout,
             sizeof(BITSET_WORD));

      foreach_inst_in_block_reverse(vec4_instruction, inst, block) {
         if (inst->dst.file == GRF && !inst->has_side_effects()) {
            bool result_live[4] = { false };

            for (int c = 0; c < 4; c++) {
               int var = inst->dst.reg * 4 + c;
               result_live[c] = BITSET_TEST(live, var);
            }

            /* If the instruction can't do writemasking, then it's all or
             * nothing.
             */
            if (!can_do_writemask(brw, inst)) {
               bool result = result_live[0] | result_live[1] |
                             result_live[2] | result_live[3];
               result_live[0] = result;
               result_live[1] = result;
               result_live[2] = result;
               result_live[3] = result;
            }

            for (int c = 0; c < 4; c++) {
               if (!result_live[c] && inst->dst.writemask & (1 << c)) {
                  inst->dst.writemask &= ~(1 << c);
                  progress = true;

                  if (inst->dst.writemask == 0) {
                     if (inst->writes_accumulator || inst->writes_flag()) {
                        inst->dst = dst_reg(retype(brw_null_reg(), inst->dst.type));
                     } else {
                        inst->opcode = BRW_OPCODE_NOP;
                        continue;
                     }
                  }
               }
            }
         }

         if (inst->dst.is_null() && inst->writes_flag()) {
            if (!BITSET_TEST(flag_live, 0)) {
               inst->opcode = BRW_OPCODE_NOP;
               progress = true;
               continue;
            }
         }

         if (inst->dst.file == GRF && !inst->predicate) {
            for (int c = 0; c < 4; c++) {
               if (inst->dst.writemask & (1 << c)) {
                  int var = inst->dst.reg * 4 + c;
                  BITSET_CLEAR(live, var);
               }
            }
         }

         if (inst->writes_flag()) {
            BITSET_CLEAR(flag_live, 0);
         }

         for (int i = 0; i < 3; i++) {
            if (inst->src[i].file == GRF) {
               for (int c = 0; c < 4; c++) {
                  int swiz = BRW_GET_SWZ(inst->src[i].swizzle, c);
                  int var = inst->src[i].reg * 4 + swiz;

                  BITSET_SET(live, var);
               }
            }
         }

         if (inst->reads_flag()) {
            BITSET_SET(flag_live, 0);
         }
      }
   }

   ralloc_free(live);
   ralloc_free(flag_live);

   if (progress) {
      foreach_block_and_inst_safe(block, backend_instruction, inst, cfg) {
         if (inst->opcode == BRW_OPCODE_NOP) {
            inst->remove(block);
         }
      }

      invalidate_live_intervals();
   }

   return progress;
}
<|endoftext|>