text:
// Copyright (c) 2019 Tim Perkins

// 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.

#include "trollauncher/java_detector.hpp"

#include <optional>
#include <regex>
#include <vector>

// Work around for Boost on MSYS2
#ifdef _WIN32
#ifndef __kernel_entry
#define __kernel_entry
#endif
#endif

#include <boost/process.hpp>

#include "trollauncher/utils.hpp"

#ifndef ITS_A_UNIX_SYSTEM
#ifndef _WIN32
#define ITS_A_UNIX_SYSTEM true
#else
#define ITS_A_UNIX_SYSTEM false
#endif
#endif

namespace tl {

namespace {

namespace bfs = boost::filesystem;
namespace bp = boost::process;
namespace fs = std::filesystem;

std::vector<fs::path> GetProgramFilesPaths();
std::vector<fs::path> GetPrefixedPaths(const std::vector<fs::path>& prefix_paths,
                                       const std::vector<fs::path>& relative_paths);
std::optional<std::string> GetJavaVersion(const fs::path& java_path);
bool CheckJavaVersion(const fs::path& java_path,
                      const std::optional<std::regex>& version_regex_opt);
std::optional<fs::path> FindBundledJava(const std::vector<fs::path>& program_files_paths,
                                        const std::optional<std::regex>& version_regex_opt);
std::optional<fs::path> FindLinuxJava(const std::optional<std::regex>& version_regex_opt);
std::optional<fs::path> FindWindowsJava(const std::vector<fs::path>& program_files_paths,
                                        const std::optional<std::regex>& version_regex_opt);
std::optional<fs::path> FindPathedJava(const std::optional<std::regex>& version_regex_opt);
std::optional<fs::path> FindJava(const std::optional<std::regex>& version_regex_opt);

}  // namespace

std::optional<fs::path> JavaDetector::GetAnyJava()
{
  return FindJava(std::nullopt);
}

std::optional<fs::path> JavaDetector::GetJavaVersion8()
{
  const std::regex version_8_regex("^1\\.8\\.[0-9]+");
  return FindJava(version_8_regex);
}

namespace {

std::vector<fs::path> GetProgramFilesPaths()
{
  if (ITS_A_UNIX_SYSTEM) {
    return {};
  }
  const std::vector<std::optional<std::string>> program_files_path_opts = {
      GetEnvironmentVar("PROGRAMFILES"), GetEnvironmentVar("PROGRAMFILES(X86)")};
  std::vector<fs::path> program_files_paths;
  for (const auto& program_files_path_opt : program_files_path_opts) {
    if (program_files_path_opt) {
      program_files_paths.push_back(program_files_path_opt.value());
    }
  }
  // Remove duplicate entries
  if (program_files_paths.size() == 2 && program_files_paths.at(0) == program_files_paths.at(1)) {
    program_files_paths.pop_back();
  }
  return program_files_paths;
}

std::vector<fs::path> GetPrefixedPaths(const std::vector<fs::path>& prefix_paths,
                                       const std::vector<fs::path>& relative_paths)
{
  std::vector<fs::path> full_paths;
  for (const auto& prefix_path : prefix_paths) {
    for (const auto& relative_path : relative_paths) {
      full_paths.push_back(prefix_path / relative_path);
    }
  }
  return full_paths;
}

std::optional<std::string> GetJavaVersion(const fs::path& java_path)
{
  if (!fs::is_regular_file(java_path)) {
    return std::nullopt;
  }
  bp::ipstream java_ips;
  std::error_code java_ec;
  const int return_code = bp::system(          //
      bp::exe = java_path.string(),            //
      bp::args = {"-version"},                 //
      (bp::std_out & bp::std_err) > java_ips,  //
      bp::error = java_ec                      //
  );
  if (java_ec || return_code != 0) {
    return std::nullopt;
  }
  std::string java_output;
  std::getline(java_ips, java_output);
  // Example version strings:
  // java version "1.8.0_51"
  // openjdk version "11.0.5" 2019-10-15
  std::smatch version_match;
  const std::regex version_regex("^[^ ]+ version \"([^\"]+)\"");
  if (!std::regex_search(java_output, version_match, version_regex)) {
    return std::nullopt;
  }
  return version_match[1];
}

bool CheckJavaVersion(const fs::path& java_path, const std::optional<std::regex>& version_regex_opt)
{
  const std::optional<std::string> java_version_opt = GetJavaVersion(java_path);
  if (!java_version_opt) {
    return false;
  }
  const std::string& java_version = java_version_opt.value();
  if (version_regex_opt && !std::regex_search(java_version, version_regex_opt.value())) {
    return false;
  }
  return true;
}

std::optional<fs::path> FindBundledJava(const std::vector<fs::path>& program_files_paths,
                                        const std::optional<std::regex>& version_regex_opt)
{
  if (ITS_A_UNIX_SYSTEM) {
    return std::nullopt;
  }
  // Example Java path:
  // C:\Program Files (x86)\Minecraft Launcher\runtime\jre-x64\bin\javaw.exe
  const std::vector<fs::path> minecraft_paths =
      GetPrefixedPaths(program_files_paths, {"Minecraft Launcher", "Minecraft"});
  const std::vector<fs::path> bundled_java_paths =
      GetPrefixedPaths(minecraft_paths, {"runtime\\jre-x64\\bin\\javaw.exe"});
  for (const fs::path& java_path : bundled_java_paths) {
    if (CheckJavaVersion(java_path, version_regex_opt)) {
      return java_path;
    }
  }
  return std::nullopt;
}

std::optional<fs::path> FindLinuxJava(const std::optional<std::regex>& version_regex_opt)
{
  if (!ITS_A_UNIX_SYSTEM) {
    return std::nullopt;
  }
  // Example Java paths:
  // /usr/lib/jvm/java-8-openjdk-amd64/bin/java
  // /usr/lib/jvm/java-11-openjdk-amd64/bin/java
  const fs::path java_root_path = "/usr/lib/jvm/";
  std::error_code fs_ec;
  for (const fs::path& java_dir_path : fs::directory_iterator(java_root_path, fs_ec)) {
    if (!fs::is_directory(java_dir_path)) {
      continue;
    }
    const fs::path java_path = java_dir_path / "bin/java";
    if (CheckJavaVersion(java_path, version_regex_opt)) {
      return java_path;
    }
  }
  return std::nullopt;
}

std::optional<fs::path> FindWindowsJava(const std::vector<fs::path>& program_files_paths,
                                        const std::optional<std::regex>& version_regex_opt)
{
  if (ITS_A_UNIX_SYSTEM) {
    return std::nullopt;
  }
  // Example Java path:
  // C:\Program Files\Java\jre1.8.0_231\bin\javaw.exe
  const std::vector<fs::path> java_root_paths = GetPrefixedPaths(program_files_paths, {"Java"});
  for (const auto& java_root_path : java_root_paths) {
    std::error_code fs_ec;
    for (const fs::path& java_dir_path : fs::directory_iterator(java_root_path, fs_ec)) {
      if (!fs::is_directory(java_dir_path)) {
        continue;
      }
      const fs::path java_path = java_dir_path / "bin\\javaw.exe";
      if (CheckJavaVersion(java_path, version_regex_opt)) {
        return java_path;
      }
    }
  }
  return std::nullopt;
}

std::optional<fs::path> FindPathedJava(const std::optional<std::regex>& version_regex_opt)
{
  const std::string java_command = (ITS_A_UNIX_SYSTEM ? "java" : "javaw");
  const fs::path path_java_path = bp::search_path(java_command).string();
  if (CheckJavaVersion(path_java_path, version_regex_opt)) {
    return path_java_path;
  }
  return std::nullopt;
}

std::optional<fs::path> FindJava(const std::optional<std::regex>& version_regex_opt)
{
  const std::vector<fs::path> program_files_paths = GetProgramFilesPaths();
  const std::optional<fs::path> launcher_java_path_opt =
      FindBundledJava(program_files_paths, version_regex_opt);
  if (launcher_java_path_opt) {
    return launcher_java_path_opt;
  }
  const std::optional<fs::path> os_java_path_opt =
      (ITS_A_UNIX_SYSTEM ? FindLinuxJava(version_regex_opt)
                         : FindWindowsJava(program_files_paths, version_regex_opt));
  if (os_java_path_opt) {
    return os_java_path_opt;
  }
  const std::optional<fs::path> pathed_java_path_opt = FindPathedJava(version_regex_opt);
  if (pathed_java_path_opt) {
    return pathed_java_path_opt;
  }
  return std::nullopt;
}

}  // namespace

}  // namespace tl

ext: cpp


text:
// Copyright 2018-2020 the openhoi authors. See COPYING.md for legal info.

#include "game_manager.hpp"

#include <Ogre.h>
#include <OgreLogManager.h>
#include <OgreOverlaySystem.h>
#include <OgreRTShaderSystem.h>
#include <OgreRoot.h>
#include <OgreSTBICodec.h>
#include <OgreTextureManager.h>
#include <SDL.h>
#include <SDL_syswm.h>

#include <boost/format.hpp>
#include <exception>
#include <hoibase/file/file_access.hpp>

#include "gui/gui_manager.hpp"
#include "state/menu_state.hpp"

#ifdef OPENHOI_OS_WINDOWS
#  include <OgreD3D11RenderSystem.h>
#  include <expandedresources.h>
#  include <shellscalingapi.h>
#endif

namespace openhoi {

// Initializes the game manager
GameManager::GameManager() {
  // Create options instance and load options from file
  options = std::make_unique<Options>();

  // Initialize logging
  logManager = OGRE_NEW Ogre::LogManager();
  std::string logFile = (FileAccess::getUserGameConfigDirectory() /
                         filesystem::path(OPENHOI_GAME_NAME ".log"))
                            .u8string();
  Ogre::Log* logger = logManager->createLog(logFile, true);
  logger->addListener(this);

  // Create root object of OGRE system
  root = OGRE_NEW Ogre::Root("", "", "");

  // Create the overlay system
  overlaySystem = OGRE_NEW Ogre::OverlaySystem();

  // Load the render system
  loadRenderSystem();

  // Load the STBI codec plugin for image processing
  root->loadPlugin(getPluginPath(OGRE_PLUGIN_STBI));

  // Load the ParticleFX plugin
  root->loadPlugin(getPluginPath(OGRE_PLUGIN_PARTICLEFX));

  // Initialize root
  root->initialise(false);

  // Create window
  createWindow();

  // Initialize audio
  initializeAudio();

  // Locate resources
  locateResources();

  // Initialize real-time shader system
  if (Ogre::RTShader::ShaderGenerator::initialize()) {
    // Get shader generator
    shaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
    // Add ourself as a material manager listener
    Ogre::MaterialManager::getSingleton().addListener(this);
  }

  // Load resources
  loadResources();

  // Add ourself as an frame listener
  root->addFrameListener(this);

  // Create GUI manager instance
  guiManager = std::make_unique<GuiManager>();

  // Create a generic scene manager
  sceneManager = root->createSceneManager();
  sceneManager->addRenderQueueListener(overlaySystem);

  // Register our scene with the RTSS
  Ogre::RTShader::ShaderGenerator::getSingleton().addSceneManager(sceneManager);

  // Initialize GUI manager
  guiManager->initialize(sceneManager, root->getRenderSystem(), window.sdl);

  // Create camera
  createCamera();

  // Save options to file
  options->saveToFile();

  // Create state manager and startup with menu state
  stateManager = std::make_unique<StateManager>();
  stateManager->startup(new MenuState());
}

// Destroys the game manager
GameManager::~GameManager() {
  // Shutdown state manager
  if (stateManager) stateManager->requestStateChange(nullptr);

  // Unregister the material manager listener
  Ogre::MaterialManager::getSingleton().setActiveScheme(
      Ogre::MaterialManager::DEFAULT_SCHEME_NAME);
  Ogre::MaterialManager::getSingleton().removeListener(this);
  Ogre::RTShader::ShaderGenerator::destroy();

  // Destroy window
  destroyWindow();

  // Destroy overlay system
  if (overlaySystem) delete overlaySystem;
}

// Gets the game options
std::shared_ptr<Options> const& GameManager::getOptions() const {
  return options;
}

// Gets the state manager
std::unique_ptr<StateManager> const& GameManager::getStateManager() const {
  return stateManager;
}

// Gets the GUI manager
std::unique_ptr<GuiManager> const& GameManager::getGuiManager() const {
  return guiManager;
}

// Gets the audio manager
std::shared_ptr<AudioManager> const& GameManager::getAudioManager() const {
  return audioManager;
}

// Gets the OGRE root
Ogre::Root* const& GameManager::getRoot() const { return root; }

// Gets the OGRE scene manager
Ogre::SceneManager* const& GameManager::getSceneManager() const {
  return sceneManager;
}

// Gets the OGRE camera
Ogre::Camera* const& GameManager::getCamera() const { return camera; }

// Get the OGRE render window
Ogre::RenderWindow* const& GameManager::getRenderWindow() const {
  return window.ogre;
}

// Start the main loop
void GameManager::run() {
#ifdef OPENHOI_OS_WINDOWS
  // Gets the expected number of exclusive CPU sets that are available to the
  // app when in Windows Game Mode
  ULONG exclusiveCpuCount;
  HRESULT result = GetExpandedResourceExclusiveCpuCount(&exclusiveCpuCount);
  if (result == S_OK) {
    Ogre::LogManager::getSingletonPtr()->logMessage(
        (boost::format("Windows Game Mode provides us a total of %d exclusive "
                       "CPU cores") %
         exclusiveCpuCount)
            .str());
  } else {
    Ogre::LogManager::getSingletonPtr()->logMessage(
        "Unable to get number of exclusive CPU cores provided by Windows Game "
        "Mode",
        Ogre::LogMessageLevel::LML_WARNING);
  }
#endif

  // Start rendering. This will call the main game loop and block here until the
  // game ends
  root->startRendering();
}

// Request game exit
void GameManager::requestExit() {
  exiting = true;
  root->queueEndRendering(true);
}

// Gets the full path to the provided OGRE plugin
std::string GameManager::getPluginPath(std::string pluginName) {
  filesystem::path pluginDirectory = FileAccess::getOgrePluginDirectory();
  if (!pluginDirectory.empty()) {
    return (pluginDirectory /
            (pluginName + FileAccess::getOgreLibraryFileExtension()))
        .u8string();
  } else {
    return pluginName + FileAccess::getOgreLibraryFileExtension();
  }
}

// Initialize audio
void GameManager::initializeAudio() {
  // Create audio manager
  audioManager = std::make_shared<AudioManager>();

  // Try to set pre-defined audio device
  if (!options->getAudioDevice().empty()) {
    for (auto const& audioDevice : audioManager->getPossibleDevices()) {
      if (audioDevice->getFriendlyName() == options->getAudioDevice()) {
        audioManager->setDevice(audioDevice);
        break;
      }
    }
  }

  // Update last device in options
  std::shared_ptr<AudioDevice> device = audioManager->getDevice();
  options->setAudioDevice(device ? device->getFriendlyName() : std::string());
}

// Load and configure the render system
void GameManager::loadRenderSystem() {
#if defined(OPENHOI_OS_WINDOWS)
  // Prefer DirectX11 on Windows
  try {
    root->loadPlugin(getPluginPath(OGRE_PLUGIN_RS_D3D11));
  } catch (const std::exception&) {
    // do nothing
  }

  if (root->getAvailableRenderers().empty()) {
#endif
    // Check if we can use OpenGL3+
    // We also try to detect if we are running inside a VM because VM's OpenGL
    // support is very bad and it will most likely crash with GL3+
    if (!OS::isRunningInVirtualMachine()) {
      try {
        root->loadPlugin(getPluginPath(OGRE_PLUGIN_RS_GL3PLUS));
      } catch (const std::exception&) {
        // do nothing
      }
    }
#if defined(OPENHOI_OS_WINDOWS)
  }
#endif

  if (root->getAvailableRenderers().empty()) {
    // Use legacy OpenGL as a fallback
    root->loadPlugin(getPluginPath(OGRE_PLUGIN_RS_GL));
  }

  // Get loaded render system
  Ogre::RenderSystem* renderSystem = root->getAvailableRenderers().front();

  // Configure render system
  bool d3d11 = false;
#if defined(OPENHOI_OS_WINDOWS)
  if (Ogre::D3D11RenderSystem* d3d11rs =
          dynamic_cast<Ogre::D3D11RenderSystem*>(renderSystem)) {
    d3d11 = true;

    // Set driver type to hardware
    renderSystem->setConfigOption("Driver type", "Hardware");

    // Disable NVIDIA PerfHUD
    renderSystem->setConfigOption("Allow NVPerfHUD", "No");

    // Set floating-point mode to fastest
    renderSystem->setConfigOption("Floating-point mode", "Fastest");

    // Set DirectX feature levels
    renderSystem->setConfigOption("Min Requested Feature Levels", "9.1");
    renderSystem->setConfigOption("Max Requested Feature Levels", "11.0");
  }
#endif
  if (!d3d11) {
    // Set RTT Preferred Mode to FBO
    renderSystem->setConfigOption("RTT Preferred Mode", "FBO");
  }

  // Set best possible video mode
  setBestPossibleVideoMode(renderSystem);

  // Set Full Screen Anti-Aliasing (FSAA)
  renderSystem->setConfigOption(
      "FSAA", std::to_string(options->getFullScreenAntiAliasing()));

  // Set VSync (turn always on in windowed screen mode because disabling VSync
  // can cause timing issues at lower frame rates here)
  renderSystem->setConfigOption(
      "VSync", (options->isVerticalSync() ||
                options->getWindowMode() != WindowMode::FULLSCREEN)
                   ? "Yes"
                   : "No");

  // Disable sRGB Gamma conversion
  renderSystem->setConfigOption("sRGB Gamma Conversion", "No");

  // Print out render system details to log
#ifdef _DEBUG
  Ogre::LogManager::getSingletonPtr()->logMessage(
      "*** Render system config options ***");
  const Ogre::ConfigOptionMap& configOptions = renderSystem->getConfigOptions();
  for (auto opt : configOptions) {
    Ogre::LogManager::getSingletonPtr()->logMessage(" [*] " + opt.first);
    for (Ogre::StringVector::iterator vals = opt.second.possibleValues.begin();
         vals != opt.second.possibleValues.end(); vals++)
      Ogre::LogManager::getSingletonPtr()->logMessage("   -> " + *vals);
  }
#endif

  // Set active render system
  root->setRenderSystem(renderSystem);
}

// Set best possible video mode
void GameManager::setBestPossibleVideoMode(Ogre::RenderSystem* renderSystem) {
  // Get all possible video modes for the current render system
  const Ogre::ConfigOption& configValue =
      renderSystem->getConfigOptions().at("Video Mode");
  for (auto it = configValue.possibleValues.begin();
       it != configValue.possibleValues.end(); ++it) {
    std::string possibleVideoMode = *it;
    if (std::next(it) == configValue.possibleValues.end() ||
        (!options->getVideoMode().empty() &&
         (possibleVideoMode == options->getVideoMode() ||
          possibleVideoMode.find(options->getVideoMode() + " ", 0) ==
              0 /* D3D11 adds color depth to video mode */))) {
      // Set video mode if it is the latest one or if it matches the one stored
      // in the config
      options->setVideoMode(possibleVideoMode);
      break;
    }
  }

  // Set video mode
  renderSystem->setConfigOption("Video Mode", options->getVideoMode());

#ifdef OPENHOI_OS_WINDOWS
  if (options->getWindowMode() != WindowMode::FULLSCREEN) {
    // Enable DPI awareness on Windows. Otherwise, openhoi's window size be
    // increased by Windows' desktop scaling factor (e.g. 125%)
    Ogre::LogManager::getSingletonPtr()->logMessage("Enabling DPI awareness");
    HRESULT result = SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
    if (result != S_OK) {
      Ogre::LogManager::getSingletonPtr()->logMessage(
          "Unable to DPI awareness. Checking for monitor scale factor",
          Ogre::LogMessageLevel::LML_WARNING);

      // Something did not work. But this may not be an issue if the scale
      // factor is 100%. We we have to check that first
      HMONITOR monitor =
          MonitorFromPoint(POINT{0, 0}, MONITOR_DEFAULTTOPRIMARY);
      DEVICE_SCALE_FACTOR scaleFactor;
      result = GetScaleFactorForMonitor(monitor, &scaleFactor);
      bool switchToFullscreen = false;
      if (result == S_OK && scaleFactor != DEVICE_SCALE_FACTOR_INVALID) {
        // Check scale factor. If it is 100%, we can just continue. If not, we
        // maybe have to select a lower resolution..
        Ogre::LogManager::getSingletonPtr()->logMessage(
            (boost::format("The primary monitor's scale factor is at %d%%") %
             scaleFactor)
                .str());
        if (scaleFactor != SCALE_100_PERCENT) {
          // Scale factor is not 100%. Thus, we have to switch to full screen
          switchToFullscreen = true;
        }
      } else {
        Ogre::LogManager::getSingletonPtr()->logMessage(
            "Unable to get scale factor of primary monitor",
            Ogre::LogMessageLevel::LML_WARNING);
        switchToFullscreen = true;
      }
      if (switchToFullscreen) {
        Ogre::LogManager::getSingletonPtr()->logMessage(
            "Switching to fullscreen");
        options->setWindowMode(WindowMode::FULLSCREEN);
      }
    }
  }
#endif

  // Set fullscreen flag
  renderSystem->setConfigOption(
      "Full Screen",
      options->getWindowMode() == WindowMode::FULLSCREEN ? "Yes" : "No");
}

// Create a new render window
void GameManager::createWindow() {
  window = {nullptr, nullptr};
  Ogre::NameValuePairList miscParams = Ogre::NameValuePairList();

  if (!SDL_WasInit(SDL_INIT_VIDEO)) SDL_InitSubSystem(SDL_INIT_VIDEO);

  auto windowDesc = root->getRenderSystem()->getRenderWindowDescription();
  miscParams.insert(windowDesc.miscParams.begin(), windowDesc.miscParams.end());
  windowDesc.miscParams = miscParams;
  windowDesc.name = OPENHOI_GAME_NAME;

  // Create SDL window
  Uint32 flags = SDL_WINDOW_ALLOW_HIGHDPI;
  if (options->getWindowMode() == WindowMode::BORDERLESS)
    flags |= SDL_WINDOW_BORDERLESS;
  else if (options->getWindowMode() == WindowMode::FULLSCREEN)
    flags |= SDL_WINDOW_FULLSCREEN;
  window.sdl = SDL_CreateWindow(windowDesc.name.c_str(), SDL_WINDOWPOS_CENTERED,
                                SDL_WINDOWPOS_CENTERED, windowDesc.width,
                                windowDesc.height, flags);

  // Set window manager information
  SDL_SysWMinfo wmInfo;
  SDL_VERSION(&wmInfo.version);
  SDL_GetWindowWMInfo(window.sdl, &wmInfo);
#ifdef OPENHOI_OS_WINDOWS
  windowDesc.miscParams["externalWindowHandle"] =
      Ogre::StringConverter::toString(size_t(wmInfo.info.win.window));
#elif defined(OPENHOI_OS_LINUX) || defined(OPENHOI_OS_BSD)
  windowDesc.miscParams["parentWindowHandle"] =
      Ogre::StringConverter::toString(size_t(wmInfo.info.x11.window));
#elif defined(OPENHOI_OS_MACOS)
  windowDesc.miscParams["externalWindowHandle"] =
      Ogre::StringConverter::toString(size_t(wmInfo.info.cocoa.window));
#endif

  window.ogre = root->createRenderWindow(windowDesc);
}

// Destroy the render window
void GameManager::destroyWindow() {
  if (window.ogre) root->destroyRenderTarget(window.ogre);

  if (window.sdl) SDL_DestroyWindow(window.sdl);

  SDL_QuitSubSystem(SDL_INIT_VIDEO);
}

// Locate resources
void GameManager::locateResources() {
  filesystem::path assetRoot = FileAccess::getAssetRootDirectory();
#ifndef OPENHOI_OS_WINDOWS
  filesystem::path mediaRoot = FileAccess::getOgreMediaRootDirectory();
#endif

  // Declare all font resources
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "fonts").u8string(), "FileSystem", Ogre::RGN_DEFAULT);

  // Declare all texture resources
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "graphics").u8string(), "FileSystem", Ogre::RGN_DEFAULT);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "graphics" / "coat_of_arms").u8string(), "FileSystem",
      OPENHOI_RSG_COA_TEXTURES);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "graphics" / "flags").u8string(), "FileSystem",
      OPENHOI_RSG_FLAG_TEXTURES);

  // Declare all material/shader resources
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "materials").u8string(), "FileSystem", Ogre::RGN_DEFAULT);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "materials" / "glsl").u8string(), "FileSystem",
      Ogre::RGN_DEFAULT);
#ifdef OPENHOI_OS_WINDOWS
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "materials" / "glsl" / "win64").u8string(), "FileSystem",
      Ogre::RGN_DEFAULT);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "materials" / "hlsl").u8string(), "FileSystem",
      Ogre::RGN_DEFAULT);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "materials" / "hlsl" / "win64").u8string(), "FileSystem",
      Ogre::RGN_DEFAULT);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "materials" / "win64").u8string(), "FileSystem",
      Ogre::RGN_DEFAULT);
#elif defined(OPENHOI_OS_LINUX) || defined(OPENHOI_OS_BSD)
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (mediaRoot / "RTShaderLib" / "GLSL").u8string(), "FileSystem",
      Ogre::RGN_DEFAULT);
#endif

  // Declare all particle resources
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "particles").u8string(), "FileSystem", Ogre::RGN_DEFAULT);

  // Declare all mesh resources
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
      (assetRoot / "meshes").u8string(), "FileSystem", Ogre::RGN_DEFAULT);
}

// Load resources
void GameManager::loadResources() {
  // Disable mipmapping
  Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(0);

  // Initialize and load resource groups
  std::array<std::string, 3> defaultResourceGroups = {
      Ogre::RGN_DEFAULT, OPENHOI_RSG_COA_TEXTURES, OPENHOI_RSG_FLAG_TEXTURES};
  for (const auto& resourceGroup : defaultResourceGroups) {
    Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup(
        resourceGroup);
    Ogre::ResourceGroupManager::getSingleton().loadResourceGroup(resourceGroup);
  }

  // Load background audio and other audio effects
  filesystem::path audioDirectory =
      FileAccess::getAssetRootDirectory() / "audio";
  audioManager->loadBackgroundMusicAsync(audioDirectory / "background");
  audioManager->loadEffects(audioDirectory);
}

// Poll for events
void GameManager::pollEvents() {
  if (!window.sdl) {
    // SDL events not initialized
    return;
  }

  SDL_Event event;
  while (SDL_PollEvent(&event)) {
    // Handle event in GUI
    guiManager->handleEvent(event);

    // Handle event for the rest of the game
    switch (event.type) {
      case SDL_KEYDOWN:
        keyDown(event);
        break;
      case SDL_KEYUP:
        keyUp(event);
        break;
      case SDL_MOUSEBUTTONDOWN:
        mouseDown(event);
        break;
      case SDL_MOUSEBUTTONUP:
        mouseUp(event);
        break;
      case SDL_MOUSEWHEEL:
        mouseWheelRolled(event);
        break;
      case SDL_MOUSEMOTION:
        mouseMoved(event);
        break;
      case SDL_FINGERDOWN:
        fingerDown(event);
        break;
      case SDL_FINGERUP:
        fingerUp(event);
        break;
      case SDL_FINGERMOTION:
        fingerMoved(event);
        break;
      case SDL_WINDOWEVENT:
        if (event.window.event == SDL_WINDOWEVENT_CLOSE)
          exiting = true;
        else if (event.window.event != SDL_WINDOWEVENT_RESIZED)
          continue;

        if (event.window.windowID != SDL_GetWindowID(window.sdl)) continue;

        window.ogre->windowMovedOrResized();
        break;
      case SDL_QUIT:
        root->queueEndRendering();
        break;
      default:
        break;
    }
  }

#ifdef OPENHOI_OS_MACOS
  // Hacky workaround for black window on macOS
  for (const auto& win : windows) {
    SDL_SetWindowSize(win.sdl, win.ogre->getWidth(), win.ogre->getHeight());
    win.ogre->windowMovedOrResized();
  }
#endif
}

// Key down event
void GameManager::keyDown(const SDL_Event evt) {}

// Key up event
void GameManager::keyUp(const SDL_Event evt) {
  if (evt.key.keysym.sym == SDLK_CARET || evt.key.keysym.sym == 0x40000000) {
    // Show debug console on caret button click
    guiManager->getDebugConsole()->toggle();
  }
}

// Mouse button down event
void GameManager::mouseDown(const SDL_Event evt) {}

// Mouse button up event
void GameManager::mouseUp(const SDL_Event evt) {}

// Mouse wheel rolled event
void GameManager::mouseWheelRolled(const SDL_Event evt) {}

// Mouse moved event
void GameManager::mouseMoved(const SDL_Event evt) {}

// Finger down  event
void GameManager::fingerDown(const SDL_Event evt) {}

// Finger up event
void GameManager::fingerUp(const SDL_Event evt) {}

// Finger moved event
void GameManager::fingerMoved(const SDL_Event evt) {}

// Frame started event
bool GameManager::frameStarted(const Ogre::FrameEvent& evt) {
  // Poll for events
  pollEvents();

  // Start new GUI frame
  guiManager->newFrame(evt);

  // Update GUI in current state
  stateManager->updateGui();

  // Refresh audio status
  audioManager->updateStats();

  return true;
}

// Frame rendering queued event (overrides OGRE Bites)
bool GameManager::frameRenderingQueued(const Ogre::FrameEvent& evt) {
  // Update state
  stateManager->updateState(evt);

  return true;
}

// Create camera
void GameManager::createCamera() {
  // Create the camera
  camera = sceneManager->createCamera(
      OPENHOI_BUILD_DYNAMIC_OBJECT_NAME("Player_Cam"));

  // Position it at 100 in Z direction
  camera->setPosition(Ogre::Vector3(0, 0, 100));
  // Look -300 back along Z
  camera->lookAt(Ogre::Vector3(0, 0, -300));

  // Set clip distances
  camera->setNearClipDistance(0.1f);
  camera->setFarClipDistance(500000);  // Some very high value..
  if (root->getRenderSystem()->getCapabilities()->hasCapability(
          Ogre::RSC_INFINITE_FAR_PLANE)) {
    // If possible, set infinite far clip distance
    camera->setFarClipDistance(0);
  }

  // Create one viewport, entire window
  Ogre::Viewport* vp = getRenderWindow()->addViewport(camera);
  vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

  // Alter the camera aspect ratio to match the viewport
  camera->setAspectRatio(Ogre::Real(vp->getActualWidth()) /
                         Ogre::Real(vp->getActualHeight()));
  camera->setAutoAspectRatio(true);
}

// Hook point where shader based technique will be created. Will be called
// whenever the material manager won't find appropriate technique to satisfy
// the target scheme name. If the scheme name is out target RT Shader System
// scheme name we will try to create shader generated technique for it
Ogre::Technique* GameManager::handleSchemeNotFound(
    unsigned short /*schemeIndex*/, const Ogre::String& schemeName,
    Ogre::Material* originalMaterial, unsigned short /*lodIndex*/,
    const Ogre::Renderable* /*rend*/) {
  if (!shaderGenerator->hasRenderState(schemeName)) return nullptr;

  // Create shader generated technique for this material
  if (!shaderGenerator->createShaderBasedTechnique(
          *originalMaterial, Ogre::MaterialManager::DEFAULT_SCHEME_NAME,
          schemeName))
    return nullptr;

  // Force creating the shaders for the generated technique
  shaderGenerator->validateMaterial(schemeName, originalMaterial->getName(),
                                    originalMaterial->getGroup());

  // Grab the generated technique
  Ogre::Material::Techniques::const_iterator it;
  for (it = originalMaterial->getTechniques().begin();
       it != originalMaterial->getTechniques().end(); ++it) {
    Ogre::Technique* curTech = *it;

    if (curTech->getSchemeName() == schemeName) return curTech;
  }

  return nullptr;
}

// Called right before illuminated passes were created, so that owner of
// runtime generated technique can handle this
bool GameManager::beforeIlluminationPassesCleared(Ogre::Technique* tech) {
  if (shaderGenerator->hasRenderState(tech->getSchemeName())) {
    Ogre::Material* mat = tech->getParent();
    shaderGenerator->invalidateMaterialIlluminationPasses(
        tech->getSchemeName(), mat->getName(), mat->getGroup());
    return true;
  }
  return false;
}

// Called right after illuminated passes were created, so that owner of
// runtime generated technique can handle this
bool GameManager::afterIlluminationPassesCreated(Ogre::Technique* tech) {
  if (shaderGenerator->hasRenderState(tech->getSchemeName())) {
    Ogre::Material* mat = tech->getParent();
    shaderGenerator->validateMaterialIlluminationPasses(
        tech->getSchemeName(), mat->getName(), mat->getGroup());
    return true;
  }
  return false;
}

// This is called whenever the log receives a message and is about to write it
// out
void GameManager::messageLogged(const Ogre::String& message,
                                Ogre::LogMessageLevel lml, bool /*maskDebug*/,
                                const Ogre::String& /*logName*/,
                                bool& /*skipThisMessage*/) {
  if (exiting) {
    // Do not attempt to log anything to console when the game is exiting!
    return;
  }

#ifndef _DEBUG
  if (lml != Ogre::LogMessageLevel::LML_TRIVIAL) {
#endif
    if (guiManager) {
      // Log to debug console
      auto it = queuedDebugConsoleLogs.begin();
      while (it != queuedDebugConsoleLogs.end()) {
        guiManager->getDebugConsole()->addLog(it->first, it->second.c_str());
        it = queuedDebugConsoleLogs.erase(it);
      }
      guiManager->getDebugConsole()->addLog(lml, message.c_str());
    } else {
      queuedDebugConsoleLogs.push_back(std::pair(lml, message));
    }
#ifndef _DEBUG
  }
#endif
}

}  // namespace openhoi

max_stars_repo_name: openhoi/openhoi

max_issues_repo_name: openhoi/openhoi

max_forks_repo_name: openhoi/openhoi


text:
//==================================================================================================
/**
  Copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
**/
//==================================================================================================

#ifndef BOOST_SIMD_FUNCTION_SIMD_NEGIF_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_SIMD_NEGIF_HPP_INCLUDED

#include <boost/simd/function/scalar/negif.hpp>
#include <boost/simd/arch/common/generic/function/autodispatcher.hpp>
#include <boost/simd/arch/common/simd/function/negif.hpp>

#endif

ext: hpp

max_stars_repo_name: xmar/pythran

max_issues_repo_name: xmar/pythran

max_forks_repo_name: xmar/pythran


text:
// (C) Copyright Gert-Jan de Vos and Jan Wilmans 2013.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

// Repository at: https://github.com/djeedjay/DebugViewPP/

#include "stdafx.h"
#include <boost/algorithm/string/case_conv.hpp>
#include "Win32/Registry.h"
#include "CobaltFusion/stringbuilder.h"
#include "DebugView++Lib/Colors.h"
#include "DebugView++Lib/Filter.h"

namespace fusion {
namespace debugviewpp {

std::string MatchKey(const std::smatch& match, MatchType::type matchType)
{
    if (matchType == MatchType::RegexGroups && match.size() > 1)
    {
        std::string key;
        auto it = match.begin();
        while (++it != match.end())
        {
            if (!key.empty())
            {
                key.append(1, '\0');
            }
            key += boost::to_lower_copy(it->str());
        }
        return key;
    }
    return boost::to_lower_copy(match.str());
}

Filter::Filter() :
    matchType(MatchType::Simple),
    filterType(FilterType::Include),
    bgColor(RGB(255, 255, 255)),
    fgColor(RGB(0, 0, 0)),
    enable(true),
    matched(false)
{
}

std::regex_constants::syntax_option_type MakeSot(MatchType::type matchType)
{
    if (matchType == MatchType::RegexCase)
    {
        return std::regex_constants::optimize;
    }
    return std::regex_constants::icase | std::regex_constants::optimize;
}

Filter::Filter(const std::string& text, MatchType::type matchType, FilterType::type filterType, COLORREF bgColor, COLORREF fgColor, bool enable, bool matched) :
    text(text),
    re(MakePattern(matchType, text), MakeSot(matchType)),
    matchType(matchType),
    filterType(filterType),
    bgColor(bgColor),
    fgColor(fgColor),
    enable(enable),
    matched(matched)
{
}

void SaveFilterSettings(const std::vector<Filter>& filters, CRegKey& reg)
{
    int i = 0;
    for (auto& filter : filters)
    {
        CRegKey regFilter;
        regFilter.Create(reg, WStr(wstringbuilder() << L"Filter" << i));
        regFilter.SetStringValue(L"", WStr(filter.text));
        regFilter.SetDWORDValue(L"MatchType", MatchTypeToInt(filter.matchType));
        regFilter.SetDWORDValue(L"FilterType", FilterTypeToInt(filter.filterType));
        regFilter.SetDWORDValue(L"Type", FilterTypeToInt(filter.filterType));
        regFilter.SetDWORDValue(L"BgColor", filter.bgColor);
        regFilter.SetDWORDValue(L"FgColor", filter.fgColor);
        regFilter.SetDWORDValue(L"Enable", static_cast<DWORD>(filter.enable));
        ++i;
    }
}

// Temporary backward compatibilty for loading FilterType::MatchColor:
Filter MakeFilter(const std::string& text, MatchType::type matchType, FilterType::type filterType, COLORREF bgColor, COLORREF fgColor, bool enable, bool matched)
{
    if (filterType == FilterType::MatchColor)
    {
        filterType = FilterType::Token;
        bgColor = Colors::Auto;
    }
    return Filter(text, matchType, filterType, bgColor, fgColor, enable, matched);
}

void LoadFilterSettings(std::vector<Filter>& filters, CRegKey& reg)
{
    for (int i = 0;; ++i)
    {
        CRegKey regFilter;
        if (regFilter.Open(reg, WStr(wstringbuilder() << L"Filter" << i)) != ERROR_SUCCESS)
        {
            break;
        }

        filters.push_back(MakeFilter(
            Str(Win32::RegGetStringValue(regFilter)),
            IntToMatchType(Win32::RegGetDWORDValue(regFilter, L"MatchType", MatchType::Regex)),
            IntToFilterType(Win32::RegGetDWORDValue(regFilter, L"Type")),
            Win32::RegGetDWORDValue(regFilter, L"BgColor", Colors::BackGround),
            Win32::RegGetDWORDValue(regFilter, L"FgColor", Colors::Text),
            Win32::RegGetDWORDValue(regFilter, L"Enable", 1) != 0));
    }
}

bool IsIncluded(std::vector<Filter>& filters, const std::string& text, MatchColors& matchColors)
{
    for (auto& filter : filters)
    {
        if (!filter.enable)
        {
            continue;
        }

        if (filter.filterType == FilterType::Exclude && std::regex_search(text, filter.re))
        {
            return false;
        }
    }

    bool included = false;
    bool includeFilterPresent = false;
    for (auto& filter : filters)
    {
        if (!filter.enable)
        {
            continue;
        }

        if (filter.bgColor == Colors::Auto)
        {
            std::sregex_iterator begin(text.begin(), text.end(), filter.re);
            std::sregex_iterator end;
            for (auto tok = begin; tok != end; ++tok)
            {
                auto key = MatchKey(*tok, filter.matchType);
                if (matchColors.find(key) == matchColors.end())
                {
                    matchColors.emplace(std::make_pair(key, GetRandomBackColor()));
                }
            }
        }

        if (filter.filterType == FilterType::Include)
        {
            includeFilterPresent = true;
            included |= std::regex_search(text, filter.re);
        }

        if (filter.filterType == FilterType::Once && std::regex_search(text, filter.re))
        {
            included |= !filter.matched;
            filter.matched = true;
        }
    }

    return !includeFilterPresent || included;
}

bool MatchFilterType(const std::vector<Filter>& filters, FilterType::type type, const std::string& text)
{
    for (auto& filter : filters)
    {
        if (filter.enable && filter.filterType == type && std::regex_search(text, filter.re))
        {
            return true;
        }
    }

    return false;
}

} // namespace debugviewpp
} // namespace fusion

max_stars_repo_name: wbaby/DebugViewPP

max_issues_repo_name: wbaby/DebugViewPP

max_forks_repo_name: wbaby/DebugViewPP


text:
// Copyright 2018, Intel Corporation

#include "tile/codegen/localize.h"

#include <algorithm>

#include <boost/format.hpp>

#include "base/util/throw.h"
#include "tile/stripe/stripe.h"

namespace vertexai {
namespace tile {
namespace codegen {

using namespace stripe;  // NOLINT

void FixupRefs(Block* block, const std::string& var_name) {
  auto it = block->ref_by_into(var_name, false);
  if (it == block->refs.end()) {
    return;
  }
  for (auto stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (inner) {
      for (auto& ref : inner->refs) {
        if (ref.from == var_name) {
          ref.mut().location = it->location;
          ref.mut().offset = it->offset;
          ref.mut().interior_shape.is_const = it->interior_shape.is_const;
          for (size_t i = 0; i < ref.interior_shape.dims.size(); i++) {
            ref.mut().interior_shape.dims[i].stride = it->interior_shape.dims[i].stride;
          }
          FixupRefs(inner.get(), ref.into());
        }
      }
    }
  }
}

// Make var_name a local (in location) and restride to match size
// Also, propagate this on down
void LocalizeRef(Block* block, const std::string& var_name) {
  auto it_ref = block->ref_by_into(var_name);
  // Get the sizes
  std::vector<size_t> sizes;
  for (const auto& dim : it_ref->interior_shape.dims) {
    sizes.push_back(dim.size);
  }
  // Set the size of the bank-dim to be 1 for simple shape purposes
  size_t orig_size = 1;
  if (it_ref->bank_dim) {
    std::swap(sizes[it_ref->bank_dim->dim_pos], orig_size);
  }
  // Change the shape
  it_ref->mut().interior_shape = SimpleShape(it_ref->interior_shape.type, sizes);
  // Fix the bankdim back up
  if (it_ref->bank_dim) {
    it_ref->mut().interior_shape.dims[it_ref->bank_dim->dim_pos].size = orig_size;
    it_ref->mut().interior_shape.dims[it_ref->bank_dim->dim_pos].stride = 0;
  }
  // Change dir + from
  it_ref->mut().dir = RefDir::None;
  it_ref->mut().from = "";
  // Clear its affines
  for (Affine& aff : it_ref->mut().access) {
    aff = 0;
  }
  // Remove any tmp tags
  it_ref->mut().remove_tag("tmp");
  // Propagate the changes
  FixupRefs(block, var_name);
}

void LocalizeBlockPass(const AliasMap& scope, Block* block, const std::set<std::string>& ref_reqs) {
  auto use_count = scope.RefUseCounts(*block);
  for (auto& stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (!inner) {
      continue;
    }
    std::set<std::string> refs_to_localize;
    std::set<std::string> refs_to_remove;
    for (const auto& ref : inner->refs) {
      auto it = block->ref_by_into(ref.from, false);
      if (it == block->refs.end()) {
        continue;
      }
      // If this wasn't allocated in the outer block and it's not tagged with tmp, skip it for consideration
      if (it->dir != RefDir::None && !it->has_tag("tmp")) {
        continue;
      }
      // If we have a ref_req and we don't have the right tags, skip
      if (ref_reqs.size() != 0 && !ref.has_tags(ref_reqs)) {
        continue;
      }
      // If it's not uniquely located in this block, don't consider
      if (use_count[ref.from] != 1) {
        continue;
      }
      refs_to_localize.emplace(ref.into());
      refs_to_remove.emplace(ref.from);
    }
    for (const auto& name : refs_to_remove) {
      block->refs.erase(block->ref_by_into(name));
    }
    for (const auto& name : refs_to_localize) {
      LocalizeRef(inner.get(), name);
    }
    // Now localize block itself
    AliasMap inner_map(scope, inner.get());
    LocalizeBlockPass(inner_map, inner.get(), ref_reqs);
  }
}

void LocalizePass::Apply(CompilerState* state) const {
  auto reqs = stripe::FromProto(options_.reqs());
  auto ref_reqs = stripe::FromProto(options_.ref_reqs());
  RunOnBlocks(state->entry(), reqs, [&](const AliasMap& map, stripe::Block* block) {  //
    LocalizeBlockPass(map, block, ref_reqs);
  });
}

void LocateInnerBlock(Block* block, const Tags& inner_tags, const Location& loc,
                      const proto::LocateInnerBlockPass& options) {
  for (const auto& stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (!inner) {
      continue;
    }
    if (inner->has_tags(inner_tags)) {
      auto* inner_loc = &inner->location;
      if (options.append_devs()) {
        inner_loc->devs.insert(inner_loc->devs.end(), loc.devs.begin(), loc.devs.end());
      } else {
        *inner_loc = loc;
      }
    }
    LocateInnerBlock(inner.get(), inner_tags, loc, options);
  }
}

void LocateMemoryPass::Apply(CompilerState* state) const {
  auto reqs = FromProto(options_.reqs());
  auto loc = stripe::FromProto(options_.loc());
  RunOnBlocks(state->entry(), reqs, [&loc, this](const AliasMap& map, Block* block) {
    for (auto& ref : block->refs) {
      if (ref.dir == RefDir::None) {
        auto* ref_loc = &ref.mut().location;
        if (options_.append_devs()) {
          ref_loc->devs.insert(ref_loc->devs.end(), loc.devs.begin(), loc.devs.end());
        } else {
          *ref_loc = loc;
        }
        FixupRefs(block, ref.into());
      }
    }
  });
}

void LocateBlockPass::Apply(CompilerState* state) const {
  auto reqs = FromProto(options_.reqs());
  auto loc = stripe::FromProto(options_.loc());
  RunOnBlocks(state->entry(), reqs, [&loc, this](const AliasMap& map, Block* block) {  //
    auto* block_loc = &block->location;
    if (options_.append_devs()) {
      block_loc->devs.insert(block_loc->devs.end(), loc.devs.begin(), loc.devs.end());
    } else {
      *block_loc = loc;
    }
  });
}

void LocateInnerBlockPass::Apply(CompilerState* state) const {
  auto reqs = FromProto(options_.reqs());
  auto inner_reqs = FromProto(options_.inner_reqs());
  auto loc = stripe::FromProto(options_.loc());
  RunOnBlocks(state->entry(), reqs, [&](const AliasMap& map, Block* block) {  //
    LocateInnerBlock(block, inner_reqs, loc, options_);
  });
}

// LocateInnerBlocksRefinementsRecursively pass. Places all the refinements in the Location specified in the
// LocateInnerBlocksRefinementsPass options. Very useful for the CPU jit to place all the
// newly created buffers into the same single arena. (It just appends the new dev to the Location devices.)
static void LocateBlocksRefinementsRecursively(Block* block, const Location& loc, const stripe::Tags& skip_tags) {
  if (loc.devs.size() == 0) {
    // Nothing to add.
    return;
  }
  for (auto& itRef : block->refs) {
    // The refinment has a skip tag. Don't locate
    if (itRef.has_any_tags(skip_tags)) {
      continue;
    }

    for (auto& newLocDev : loc.devs) {
      if (itRef.location.devs.size() == 0) {
        // No Devices on the Ref's location. Add all.
        auto* ref_loc = &itRef.mut().location;
        ref_loc->devs.insert(ref_loc->devs.end(), loc.devs.begin(), loc.devs.end());
      } else {
        for (auto& itDev : itRef.location.devs) {
          if (newLocDev.name == itDev.name) {
            // Already added. Nothing to do.
            break;
          }

          auto* mutable_location = &itRef.mut().location;
          std::vector<stripe::Device> mut_loc_devs = mutable_location->devs;
          mut_loc_devs.insert(mut_loc_devs.end(), newLocDev);
        }
      }
    }
  }

  for (auto stmt : block->stmts) {
    auto inner = Block::Downcast(stmt);
    if (inner) {
      LocateBlocksRefinementsRecursively(inner.get(), loc, skip_tags);
    }
  }
}

void LocateBlocksRefinementsRecursivelyPass::Apply(CompilerState* state) const {
  auto reqs = FromProto(options_.reqs());
  auto loc = stripe::FromProto(options_.loc());
  auto skip_tags = stripe::FromProto(options_.skip_tags());

  RunOnBlocks(state->entry(), reqs,
              [&](const AliasMap& map, Block* block) { LocateBlocksRefinementsRecursively(block, loc, skip_tags); });
}

namespace {
[[gnu::unused]] char reg = []() -> char {
  CompilePassFactory<LocalizePass, proto::LocalizePass>::Register();
  CompilePassFactory<LocateMemoryPass, proto::LocateMemoryPass>::Register();
  CompilePassFactory<LocateBlockPass, proto::LocateBlockPass>::Register();
  CompilePassFactory<LocateInnerBlockPass, proto::LocateInnerBlockPass>::Register();
  CompilePassFactory<LocateBlocksRefinementsRecursivelyPass, proto::LocateBlocksRefinementsRecursivelyPass>::Register();
  return 0;
}();
}  // namespace
}  // namespace codegen
}  // namespace tile
}  // namespace vertexai

ext: cc

max_stars_repo_name: redoclag/plaidml

max_issues_repo_name: HOZHENWAI/plaidml

max_forks_repo_name: HOZHENWAI/plaidml


text:
#include <algorithm>
#include <string>
#include <vector>

#include <boost/algorithm/string.hpp>

#include <pluginlib/class_list_macros.h>
#include <tf/transform_datatypes.h>

#include <ros_node_transformation/device/publisher/imu_publisher.h>

namespace device {
namespace publisher {

bool ImuPublisher::init(ros::NodeHandle &root_nh,
                        ros::NodeHandle &publisher_nh) {
  // Get topic name
  if (not publisher_nh.hasParam("topic_name")) {
    ROS_ERROR("ImuPublisher: Failed to get topic_name");
    return false;
  }
  std::string topic_name;
  publisher_nh.getParam("topic_name", topic_name);

  // Get frame id
  if (not publisher_nh.hasParam("frame_id")) {
    ROS_ERROR("ImuPublisher: Failed to get frame_id");
    return false;
  }
  std::string frame_id;
  publisher_nh.getParam("frame_id", frame_id);

  // Initialize topic
  initMsg(frame_id);
  publisher_ = root_nh.advertise<sensor_msgs::Imu>(topic_name, 1);

  return true;
}

void ImuPublisher::publish(const std::string &data) {
  try {
    ImuData imu_data = parse(data);
    updateMsg(imu_data);
  } catch (const std::exception &error) {
    ROS_ERROR_THROTTLE(1, "ImuPublisher: Failed to parse data - %s",
                       error.what());
    return;
  }

  publisher_.publish(msg_);
}

void ImuPublisher::initMsg(const std::string &frame_id) {
  msg_.header.frame_id = frame_id;
  msg_.orientation_covariance[0] = 0.01;
  msg_.orientation_covariance[4] = 0.01;
  msg_.orientation_covariance[8] = 0.01;
  msg_.angular_velocity_covariance[0] = 0.01;
  msg_.angular_velocity_covariance[4] = 0.01;
  msg_.angular_velocity_covariance[8] = 0.01;
  msg_.linear_acceleration_covariance[0] = 0.01;
  msg_.linear_acceleration_covariance[4] = 0.01;
  msg_.linear_acceleration_covariance[8] = 0.01;
}

void ImuPublisher::updateMsg(const ImuPublisher::ImuData &data) {
  msg_.header.stamp = ros::Time::now();
  msg_.orientation =
      tf::createQuaternionMsgFromRollPitchYaw(data.roll, data.pitch, data.yaw);
  msg_.angular_velocity.x = data.vel[0];
  msg_.angular_velocity.y = data.vel[1];
  msg_.angular_velocity.z = data.vel[2];
  msg_.linear_acceleration.x = data.acc[0];
  msg_.linear_acceleration.y = data.acc[1];
  msg_.linear_acceleration.z = data.acc[2];
}

ImuPublisher::ImuData ImuPublisher::parse(const std::string &data) const {
  // Parse data
  std::vector<std::string> string_values;
  boost::split(string_values, data, [](char c) { return c == ','; });
  if (string_values.size() != 9)
    throw std::runtime_error("Wrong number of values: " +
                             std::to_string(string_values.size()));
  std::vector<double> values(string_values.size());
  std::transform(
      string_values.begin(), string_values.end(), values.begin(),
      [](const std::string &str) -> double { return std::stod(str); });

  // Get data
  ImuData imu_data;
  imu_data.roll = values[0];
  imu_data.pitch = values[1];
  imu_data.yaw = values[2];
  imu_data.vel[0] = values[3];
  imu_data.vel[1] = values[4];
  imu_data.vel[2] = values[5];
  imu_data.acc[0] = values[6];
  imu_data.acc[1] = values[7];
  imu_data.acc[2] = values[8];

  return imu_data;
}

}  // namespace publisher
}  // namespace device

PLUGINLIB_EXPORT_CLASS(device::publisher::ImuPublisher,
                       device::publisher::BasePublisher)


text:
/*
 * Configuration.hpp
 *
 *  Created on: Nov 15, 2019
 *      Author: chester-debian
 */
#include <string>
#include <iostream>
#include <ostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include "Machine.hpp"
#include <vector>

#ifndef PRODUCTIONCONTROL_CONFIGURATION_HPP_
#define PRODUCTIONCONTROL_CONFIGURATION_HPP_

class Configuration {

public:
	Configuration();
	virtual ~Configuration();

	std::string getName();
	std::string getStyle();
	std::string getMachineStyle();
	unsigned long getDuration();

	void setName(std::string aName);
	void setStyle(std::string aName);
	void setMachineStyle(std::string aName);
	void setDuration(unsigned long time);

	/**
	 * function to extract machine and system configuration from two different JSON files. The given parameter is the name of the JSON file.
	 * @param fileName
	 */
	void extractJson(std::string fileName);

	std::vector<Machine> machines;

private:

	unsigned long duration;
	std::string name;
	std::string style;
	std::string machineStyle;
};

#endif /* CONFIGURATION_HPP_ */


text:
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "../node/self_node.hpp"
#include "interactive_prompt.hpp"
#include "../common/readline.hpp"
#include "../wallet/wallet.hpp"
#include "meta_interpreter.hpp"

using namespace prologcoin::common;
using namespace prologcoin::node;
using namespace prologcoin::wallet;
using namespace prologcoin::main;

static std::string program_name;
static std::string home_dir;
unsigned short port = self_node::DEFAULT_PORT;
static std::string name;
static std::string dir;
static bool is_wallet = false;
static bool is_meta = false;
static bool check_pow = true;

static void help()
{
    std::cout << std::endl;
    std::cout << "Usage: " << program_name << " --interactive(-wallet/-meta) [--port <number>]" << std::endl;
    std::cout << "  --interactive (non-interactive currently unavailable)" << std::endl;
    std::cout << "  --interactive-wallet (will start both the node and a walet " << std::endl;
    std::cout << "                        connecting to that node.)" << std::endl;
    std::cout << "  --port <number> (start service on this port, default is " << self_node::DEFAULT_PORT << ")" << std::endl;
    std::cout << "  --name <string> (set friendly name on node, default is noname)" << std::endl;
    std::cout << "  --dir <dir> (location of data directory)" << std::endl;

    std::cout << std::endl;
    std::cout << "Example: " << program_name << " --interactive --port 8700" << std::endl;
    std::cout << std::endl;
}

static void meta()
{
    meta_interpreter meta(dir);

    prologcoin::main::interactive_prompt prompt;
    prompt.connect_meta(&meta);
    prompt.run();

    std::cout << "Shutting down..." << std::endl;
}

static void start()
{
    std::cout << std::endl;

    std::cout << "[" << program_name << " v" << self_node::VERSION_MAJOR << "." << self_node::VERSION_MINOR << "]" << std::endl;
    std::cout << "Data directory: " << dir << std::endl;
    std::cout << "Port          : " << port << std::endl;
    std::cout << std::endl;

    if (is_meta) {
	meta();
	return;
    }

    self_node node(dir, port);
    if (!name.empty()) {
	node.set_name(name);
    }

    if (!check_pow) {
	node.set_check_pow(false);
    }

    node.start();
    // node.start_sync();

    prologcoin::main::interactive_prompt prompt;
    if (!prompt.connect_node(port)) {
        std::cout << "Couldn't connect to node." << std::endl;
	return;
    }

    wallet *w = nullptr;

    if (is_wallet) {
        std::string wallet_file = dir;
        wallet_file += boost::filesystem::path::preferred_separator;
	wallet_file += "wallet.pl";
	std::cout << "[In wallet mode using: " << wallet_file << "]" << std::endl;
        w = new wallet(wallet_file);
	try {
	    w->load();
	} catch (term_parse_exception &ex) {
	    std::cout << term_parser::report_string(w->env(), ex);
	} catch (token_exception &ex) {
	    std::cout << term_parser::report_string(w->env(), ex);
	} catch (...) {
  	    std::cout << "Unknown error while loading wallet." << std::endl;
	}
	prompt.connect_wallet(w);
	w->connect_node(prompt.node_terminal());
    }

    prompt.run();

    if (is_wallet) {
        delete w;
    }

    node.stop();
    node.join();
}

typedef std::vector<std::string> args_t;

const std::string & get_option(args_t &args, const std::string &name)
{
    using namespace boost;

    static const std::string empty;
    static const std::string tr("true");
    for (size_t i = 0; i < args.size(); i++) {
	if (args[i] == name) {
	    if (i == args.size()-1 || boost::starts_with(args[i+1], "--")) {
		return tr;
	    } else {
		return args[i+1];
	    }
	}
    }
    return empty;
}

int main(int argc, char *argv[])
{
    auto path = boost::filesystem::path(argv[0]);
    program_name = path.filename().string();
    home_dir = path.parent_path().string();

    if (argc <= 1) {
	help();
	return 0;
    }

    args_t args;
    for (int i = 0; i < argc; i++) {
	args.push_back(argv[i]);
    }

    std::string checkkey_opt = get_option(args, "--check_key");
    if (!checkkey_opt.empty()) {
        prologcoin::common::readline::check_key();
	return 0;
    }

    std::string help_opt = get_option(args, "--help");
    if (!help_opt.empty()) {
	help();
	return 0;
    }

    std::string interactive_opt = get_option(args, "--interactive");
    std::string interactive_wallet_opt = get_option(args, "--interactive-wallet");
    std::string interactive_meta_opt = get_option(args, "--interactive-meta");

    if (interactive_meta_opt.empty() && interactive_wallet_opt.empty() && interactive_opt.empty()) {
	std::cout << std::endl << program_name << ": --interactive, --interactive-wallet or --interactive-meta is missing (see --help.)" << std::endl << std::endl;
	return 0;
    }

    is_meta = !interactive_meta_opt.empty();
    is_wallet = !interactive_wallet_opt.empty();

    std::string port_opt = get_option(args, "--port");
    if (!port_opt.empty()) {
	try {
	    port = boost::lexical_cast<unsigned short>(port_opt);
	} catch (boost::exception &ex) {
	    std::cout << std::endl << program_name << ": erroneous port: " << port_opt << std::endl << std::endl;
	}
    }

    std::string name_opt = get_option(args, "--name");
    if (!name_opt.empty()) {
	name = name_opt;
    }

    auto bdir = boost::filesystem::path(home_dir);
    bdir /= "prologcoin-data";
    dir = bdir.string();
    std::string dir_opt = get_option(args, "--dir");
    if (!dir_opt.empty()) {
        dir = dir_opt;
    }

    std::string ignore_pow = get_option(args, "--ignore_pow");
    if (ignore_pow == "1" || ignore_pow == "true") {
	check_pow = false;
    }

    start();

    return 0;
}

max_stars_repo_name: datavetaren/prologcoin

max_issues_repo_name: datavetaren/prologcoin

max_forks_repo_name: datavetaren/prologcoin


text:
#ifndef DI_SYSTEMS_INPUT_TOUCH_DEVICE_HPP_
#define DI_SYSTEMS_INPUT_TOUCH_DEVICE_HPP_

#include <array>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <string>
#include <vector>

#include <boost/signals2.hpp>
#include <SDL2/SDL_gesture.h>
#include <SDL2/SDL_touch.h>

#include <di/systems/input/finger.hpp>
#include <di/systems/input/gesture.hpp>
#include <di/systems/input/multi_gesture.hpp>

namespace di
{
class input_system;

class touch_device
{
public:
  explicit touch_device  (const std::size_t& index) : id_(SDL_GetTouchDevice(static_cast<int>(index)))
  {
    if(!id_)
      throw std::runtime_error("Failed to get SDL touch device. SDL Error: " + std::string(SDL_GetError()));
  }
  touch_device           (const touch_device&  that) = default;
  touch_device           (      touch_device&& temp) = default;
  ~touch_device          ()                          = default;
  touch_device& operator=(const touch_device&  that) = default;
  touch_device& operator=(      touch_device&& temp) = default;

  std::vector<finger> fingers       () const
  {
    std::vector<finger> fingers(static_cast<std::size_t>(SDL_GetNumTouchFingers(id_)));
    for(auto i = 0; i < fingers.size(); ++i)
    {
      const auto native_finger = SDL_GetTouchFinger(id_, i);
      fingers[i] = {static_cast<std::size_t>(native_finger->id), {native_finger->x, native_finger->y}, native_finger->pressure};
    }
    return fingers;
  }
  void                record_gesture(const std::function<void(gesture)>& callback)
  {
    record_gesture_callback_ = callback;
    SDL_RecordGesture(id_);
  }
  static void         load_gestures (const std::string& filename)
  {
    const auto stream = SDL_RWFromFile(filename.c_str(), "rb");
    SDL_LoadDollarTemplates(-1, stream);
    SDL_FreeRW(stream);
  }
  static void         save_gestures (const std::string& filename)
  {
    const auto stream = SDL_RWFromFile(filename.c_str(), "wb");
    SDL_SaveAllDollarTemplates(stream);
    SDL_FreeRW(stream);
  }

  boost::signals2::signal<void(finger)>        on_finger_press  ;
  boost::signals2::signal<void(finger)>        on_finger_release;
  boost::signals2::signal<void(finger)>        on_finger_motion ;
  boost::signals2::signal<void(gesture)>       on_gesture       ;
  boost::signals2::signal<void(multi_gesture)> on_multi_gesture ;

protected:
  friend input_system;

  std::int64_t id_;
  std::function<void(gesture)> record_gesture_callback_;
};
}

#endif


text:
#ifndef TISSOT_CONVERTER_IMW_P_HPP
#define TISSOT_CONVERTER_IMW_P_HPP

// Tissot, converts projecton source code (Proj4) to Boost.Geometry
// (or potentially other source code)
//
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#include "tissot_structs.hpp"
#include "tissot_util.hpp"
#include "converter_base.hpp"
#include <boost/algorithm/string/replace.hpp>

namespace boost { namespace geometry { namespace proj4converter
{

class converter_cpp_bg_imw_p : public converter_cpp_bg_default
{
    public :
        converter_cpp_bg_imw_p(projection_properties& prop)
            : m_prop(prop)
        {
        }

        void replace_if_found(std::vector<std::string>& lines, std::string const& line, std::string const& term, std::string const& replacement)
        {
            std::vector<std::string>::iterator it =
                std::find_if(lines.begin(), lines.end(),
                    functor_trimmed_equals(line));

            if (it != lines.end())
            {
                boost::replace_all(*it, term, replacement);
            }
        }

        void pre_convert()
        {
            // Move the free function xy, after inverse, to inlined_functions
            BOOST_FOREACH(projection& proj, m_prop.projections)
            {
                std::vector<std::string>::iterator it
                    = std::find_if(proj.lines.begin(), proj.lines.end(),
                                           functor_trimmed_equals("static void"));
                if (it != proj.lines.end())
                {
                    // Move all further lines
                    for (std::vector<std::string>::iterator fit = it; fit != proj.lines.end(); ++fit)
                    {
                        m_prop.inlined_functions.push_back(*fit);
                    }
                    proj.lines.erase(it, proj.lines.end());
                }
            }
        }

        void convert()
        {
            m_prop.extra_structs.push_back("struct XY { double x, y; }; // specific for IMW_P");

            // First adapt projections and move xy to inlined_functions
            BOOST_FOREACH(projection& proj, m_prop.projections)
            {
                replace_if_found(proj.lines, "double yc;", ";", " = 0;");
                replace_if_found(proj.lines, "xy = loc_for(lp, P, &yc);", "xy =", "XY xy =");
                BOOST_FOREACH(std::string& line, proj.lines)
                {
                    boost::replace_all(line, "lp, P", "lp_lon, lp_lat, this->m_par, m_proj_parm");
                }
                if (proj.direction == "forward")
                {
                    proj.lines.push_back(tab1 + "xy_x = xy.x; xy_y = xy.y;");
                }
            }

            BOOST_FOREACH(std::string& line, m_prop.inlined_functions)
            {
                boost::replace_all(line, "LP lp", "double const& lp_lam, double const& lp_phi");
                boost::replace_all(line, "lp.lam", "lp_lam");
                boost::replace_all(line, "lp.phi", "lp_phi");
                boost::replace_all(line, "Parameters& par,", "Parameters& par, par_imw_p& proj_parm,");
                if (boost::contains(line, "Parameters")
                    && (boost::contains(line, "loc_for") || boost::contains(line, "xy")))
                {
                    // Make parameters const in this function definition
                    boost::replace_all(line, "& par", " const& par");
                    boost::replace_all(line, "& proj_parm", " const& proj_parm");
                }

                // Set translation (done in converter) to proj_parm, but not for .params and .es
                boost::replace_all(line, "par.", "proj_parm.");
                boost::replace_all(line, "this->m_proj_parm.", "proj_parm.");

                boost::replace_all(line, "proj_parm.params", "par.params");
                boost::replace_all(line, "proj_parm.es", "par.es");
            }

            // See also lsat/sconics
            BOOST_FOREACH(derived& d, m_prop.derived_projections)
            {
                BOOST_FOREACH(std::string& line, d.constructor_lines)
                {
                    boost::replace_last(line, "(P,", "(par, proj_parm,");
                }
            }

        }

    private :

        projection_properties& m_prop;
};

}}} // namespace boost::geometry::proj4converter

#endif // TISSOT_CONVERTER_IMW_P_HPP

max_stars_repo_name: barendgehrels/tissot

max_issues_repo_name: barendgehrels/tissot

max_forks_repo_name: barendgehrels/tissot


text:
/*
 * Bayes++ the Bayesian Filtering Library
 * Copyright (c) 2002 Michael Stevens
 * See accompanying Bayes++.htm for terms and conditions of use.
 *
 * $Id$
 */

/*
 * UdU' Factorisation of Covariance Filter.
 *
 * For efficiency UD_scheme requires to know the maximum q_size of the predict_model
 * ISSUES:
 *  observe functions: returned rcond is the minimum of each sequential update, an overall conditioning would be better
 */
#include "UDFlt.hpp"
#include "matSup.hpp"
#include <boost/limits.hpp>

/* Filter namespace */
namespace Bayesian_filter
{
	using namespace Bayesian_filter_matrix;

UD_scheme::
UD_scheme (std::size_t x_size, std::size_t q_maxsize, std::size_t z_initialsize) :
		Kalman_state_filter(x_size),
		q_max(q_maxsize),
		UD(x_size,x_size+q_max),
		s(Empty), Sd(Empty),
		d(x_size+q_max), dv(x_size+q_max), v(x_size+q_max),
		a(x_size), b(x_size),
		h1(x_size), w(x_size),
		znorm(Empty),
		zpdecol(Empty),
		Gz(Empty),
		GIHx(Empty)
/* Initialise filter and set the size of things we know about
 */
{
	last_z_size = 0;	// Matrices conform to z_initialsize, they are left Empty if z_initialsize==0
	observe_size (z_initialsize);
}

UD_scheme&
 UD_scheme::operator= (const UD_scheme& a)
/* Optimise copy assignment to only copy filter state
 * Precond: matrix size conformance
 */
{
	Kalman_state_filter::operator=(a);
	q_max = a.q_max;
	UD = a.UD;
	return *this;
}

void
 UD_scheme::init ()
/* Initialise from a state and state coveriance
 * Computes UD factor from initial covaiance
 * Predcond:
 *  X
 * Postcond:
 *  X
 *  UD=X, d is PSD
 */
{
					// Factorise X into left partition of UD
	std::size_t x_size = UD.size1();
	UD.sub_matrix(0,x_size, 0,x_size) .assign (X);
	Float rcond = UdUfactor (UD, x_size);
	rclimit.check_PSD(rcond, "Initial X not PSD");
}

void
 UD_scheme::update ()
/* Defactor UD back into X
 * Precond:
 *  UD
 * Postcond:
 *  X=UD  PSD iff UD is PSD
 */
{
	UdUrecompose (X, UD);
}

UD_scheme::Float
 UD_scheme::predict (Linrz_predict_model& f)
/* Prediction using a diagonalised noise q, and its coupling G
 *  q can have order less then x and a matching G so GqG' has order of x
 * Precond:
 *	UD
 * Postcond:
 *  UD is PSD
 */
{
	x = f.f(x);			// Extended Kalman state predict is f(x) directly

						// Predict UD from model
	Float rcond = predictGq (f.Fx, f.G, f.q);
	rclimit.check_PSD(rcond, "X not PSD in predict");
	return rcond;
}

UD_scheme::Float
 UD_scheme::predictGq (const Matrix& Fx, const Matrix& G, const FM::Vec& q)
/* MWG-S prediction from Bierman  p.132
 *  q can have order less then x and a matching G so GqG' has order of x
 * Precond:
 *  UD
 * Postcond:
 *  UD
 *
 * Return:
 *		reciprocal condition number, -1 if negative, 0 if semi-definite (including zero)
 */
{
	std::size_t i,j,k;
	const std::size_t n = x.size();
	const std::size_t Nq = q.size();
	const std::size_t N = n+Nq;
	Float e;
					// Check preallocated space for q size
	if (Nq > q_max)
		error (Logic_exception("Predict model q larger than preallocated space"));

	if (n > 0)		// Simplify reverse loop termination
	{
						// Augment d with q, UD with G
		for (i = 0; i < Nq; ++i)		// 0..Nq-1
		{
			d[i+n] = q[i];
		}
		for (j = 0; j < n; ++j)		// 0..n-1
		{
			Matrix::Row UDj(UD,j);
			Matrix::const_Row  Gj(G,j);
			for (i = 0; i < Nq; ++i)		// 0..Nq-1
				UDj[i+n] = Gj[i];
		}

						// U=Fx*U and diagonals retrieved
		for (j = n-1; j > 0; --j)		// n-1..1
		{
						// Prepare d(0)..d(j) as temporary
			for (i = 0; i <= j; ++i)	// 0..j
				d[i] = Float(UD(i,j));	// ISSUE mixed type proxy assignment

						// Lower triangle of UD is implicitly empty
			for (i = 0; i < n; ++i) 	// 0..n-1
			{
				Matrix::Row UDi(UD,i);
				Matrix::const_Row Fxi(Fx,i);
				UDi[j] = Fxi[j];
				for (k = 0; k < j; ++k)	// 0..j-1
					UDi[j] += Fxi[k] * d[k];
			}
		}
		d[0] = Float(UD(0,0));	// ISSUE mixed type proxy assignment

						//  Complete U = Fx*U
		for (j = 0; j < n; ++j)			// 0..n-1
		{
			UD(j,0) = Fx(j,0);
		}

						// The MWG-S algorithm on UD transpose
		j = n-1;
		do {							// n-1..0
			Matrix::Row UDj(UD,j);
			e = 0;
			for (k = 0; k < N; ++k)		// 0..N-1
			{
				v[k] = Float(UDj[k]);	// ISSUE mixed type proxy assignment
				dv[k] = d[k] * v[k];
				e += v[k] * dv[k];
			}
			// Check diagonal element
			if (e > 0)
			{
				// Positive definite
				UDj[j] = e;

				Float diaginv = 1 / e;
				for (k = 0; k < j; ++k)	// 0..j-1
				{
					Matrix::Row UDk(UD,k);
					e = 0;
					for (i = 0; i < N; ++i)	// 0..N-1
						e += UDk[i] * dv[i];
					e *= diaginv;
					UDj[k] = e;

					for (i = 0; i < N; ++i)	// 0..N-1
						UDk[i] -= e * v[i];
				}
			}//PD
			else if (e == 0)
			{
				// Possibly semi-definite, check not negative
				UDj[j] = e;

				// 1 / e is infinite
				for (k = 0; k < j; ++k)	// 0..j-1
				{
					Matrix::Row UDk(UD,k);
					for (i = 0; i < N; ++i)	// 0..N-1
					{
						e = UDk[i] * dv[i];
						if (e != 0)
							goto Negative;
					}
					// UD(j,k) unaffected
				}
			}//PD
			else
			{
				// Negative
				goto Negative;
			}
		} while (j-- > 0); //MWG-S loop

						// Transpose and Zero lower triangle
		for (j = 1; j < n; ++j)			// 0..n-1
		{
			Matrix::Row UDj(UD,j);
			for (i = 0; i < j; ++i)
			{
				UD(i,j) = UDj[i];
				UDj[i] = 0;			// Zeroing unnecessary as lower only used as a scratch
			}
		}

	}

	// Estimate the reciprocal condition number from upper triangular part
	return UdUrcond(UD,n);

Negative:
	return -1;
}

void
 UD_scheme::observe_size (std::size_t z_size)
/* Optimised dynamic observation sizing
 */
{
	if (z_size != last_z_size) {
		last_z_size = z_size;

		s.resize(z_size, false);
		Sd.resize(z_size, false);
		znorm.resize(z_size, false);
	}
}

Bayes_base::Float
 UD_scheme::observe (Linrz_uncorrelated_observe_model& h, const Vec& z)
/* Standard linrz observe
 *  Uncorrelated observations are applied sequentially in the order they appear in z
 *  The sequential observation updates state x
 *  Therefore the model of each observation needs to be computed sequentially. Generally this
 *  is inefficient and observe (UD_sequential_observe_model&) should be used instead
 * Precond:
 *	 UD
 *	 Zv is PSD
 * Postcond:
 *  UD is PSD
 * Return: Minimum rcond of all sequential observe
 */
{
	const std::size_t z_size = z.size();
	Float s, S;			// Innovation and covariance

								// Dynamic sizing
	observe_size (z_size);
								// Apply observations sequentially as they are decorrelated
	Float rcondmin = std::numeric_limits<Float>::max();
	for (std::size_t o = 0; o < z_size; ++o)
	{
								// Observation model, extracted for a single z element
		const Vec& zp = h.h(x);
		h.normalise(znorm = z, zp);
		noalias(h1) = row(h.Hx, o);
								// Check Z precondition
		if (h.Zv[o] < 0)
			error (Numeric_exception("Zv not PSD in observe"));
								// Update UD and extract gain
		Float rcond = observeUD (w, S, h1, h.Zv[o]);
		rclimit.check_PSD(rcond, "S not PD in observe");	// -1 implies S singular
		if (rcond < rcondmin) rcondmin = rcond;
								// State update using normalised non-linear innovation
		s = znorm[o] - zp[o];
		noalias(x) += w * s;
								// Copy s and Sd
		UD_scheme::s[o] = s;
		UD_scheme::Sd[o] = S;
	}
	return rcondmin;
}

Bayes_base::Float
 UD_scheme::observe (Linrz_correlated_observe_model& /*h*/, const Vec& /*z*/)
/* No solution for Correlated noise and Linearised model
 */
{
	error (Logic_exception("observe no Linrz_correlated_observe_model solution"));
	return 0;	// never reached
}

Bayes_base::Float
 UD_scheme::observe (Linear_correlated_observe_model& h, const Vec& z)
/* Special Linear Hx observe for correlated Z
 *  Z must be PD and will be decorrelated
 * Applies observations sequentially in the order they appear in z
 * Creates temporary Vec and Matrix to decorrelate z,Z
 * Precondition:
 *  UD
 *  Z is PSD
 * Postcondition:
 *  UD is PSD
 * Return: Minimum rcond of all sequential observe
 */
{
	std::size_t i, j, k;
	const std::size_t x_size = x.size();
	const std::size_t z_size = z.size();
	Float s, S;			// Innovation and covariance

					// Dynamic sizing
	observe_size (z_size);
	if (z_size != zpdecol.size()) {
		zpdecol.resize(z_size, false);
		Gz.resize(z_size,z_size, false);
		GIHx.resize(z_size, x_size, false);
	}

					// Factorise process noise as GzG'
	{	Float rcond = FM::UdUfactor (Gz, h.Z);
		rclimit.check_PSD(rcond, "Z not PSD in observe");
	}

								// Observation prediction and normalised observation
	const Vec& zp = h.h(x);
	h.normalise(znorm = z, zp);

	if (z_size > 0)
	{							// Solve G* GIHx = Hx for GIHx in-place
		GIHx = h.Hx;
		for (j = 0; j < x_size; ++j)
		{
			i = z_size-1;
			do {
				for (k = i+1; k < z_size; ++k)
				{
					GIHx(i,j) -= Gz(i,k) * GIHx(k,j);
				}
			} while (i-- > 0);
		}

		zpdecol = zp;			// Solve G zp~ = z, G z~ = z  for zp~,z~ in-place
		i = z_size-1;
		do {
			for (k = i+1; k < z_size; ++k)
			{
				znorm[i] -= Gz(i,k) * znorm[k];
				zpdecol[i] -= Gz(i,k) * zpdecol[k];
			}
		} while (i-- > 0);
	}//if (z_size>0)

								// Apply observations sequential as they are decorrelated
	Float rcondmin = std::numeric_limits<Float>::max();
	for (std::size_t o = 0; o < z_size; ++o)
	{
		h1 = row(GIHx,o);
								// Update UD and extract gain
		Float rcond = observeUD (w, S, h1, Gz(o,o));
		rclimit.check_PSD(rcond, "S not PD in observe");	// -1 implies S singular
		if (rcond < rcondmin) rcondmin = rcond;
								// State update using linear innovation
		s = znorm[o]-zpdecol[o];
		noalias(x) += w * s;
								// Copy s and Sd
		UD_scheme::s[o] = s;
		UD_scheme::Sd[o] = S;
	}
	return rcondmin;
}

Bayes_base::Float
 UD_scheme::observe (UD_sequential_observe_model& h, const Vec& z)
/* Special observe using observe_model_sequential for fast uncorrelated linrz operation
 * Uncorrelated observations are applied sequentially in the order they appear in z
 * The sequential observation updates state x. Therefore the model of
 * each observation needs to be computed sequentially
 * Precondition:
 *  UD
 *  Z is PSD
 * Postcondition:
 *  UD is PSD
 * Return: Minimum rcond of all sequential observe
 */
{
	std::size_t o;
	const std::size_t z_size = z.size();
	Float s, S;			// Innovation and covariance

								// Dynamic sizing
	observe_size (z_size);
								// Apply observations sequentially as they are decorrelated
	Float rcondmin = std::numeric_limits<Float>::max();
	for (o = 0; o < z_size; ++o)
	{
								// Observation prediction and model
		const Vec& zp = h.ho(x, o);
		h.normalise(znorm = z, zp);
								// Check Z precondition
		if (h.Zv[o] < 0)
			error (Numeric_exception("Zv not PSD in observe"));
								// Update UD and extract gain
		Float rcond = observeUD (w, S, h.Hx_o, h.Zv[o]);
		rclimit.check_PSD(rcond, "S not PD in observe");	// -1 implies S singular
		if (rcond < rcondmin) rcondmin = rcond;
								// State update using non-linear innovation
		s = znorm[o]-zp[o];
		noalias(x) += w * s;
								// Copy s and Sd
		UD_scheme::s[o] = s;
		UD_scheme::Sd[o] = S;
	}
	return rcondmin;
}

UD_scheme::Float
 UD_scheme::observeUD (FM::Vec& gain, Float & alpha, const Vec& h, const Float r)
/** Linear UD factorisation update
 *  Bierman UdU' factorisation update. Bierman p.100
 * Input
 *  h observation coefficients
 *  r observation variance
 * Output
 *  gain  observation Kalman gain
 *  alpha observation innovation variance
 * Variables with physical significance
 *  gamma becomes covariance of innovation
 * Precondition:
 *  UD
 *  r is PSD (not checked)
 * Postcondition:
 *  UD (see return value)
 * Return:
 *  reciprocal condition number of UD, -1 if alpha singular (negative or zero)
 */
{
	std::size_t i,j,k;
	const std::size_t n = UD.size1();
	Float gamma, alpha_jm1, lamda;
	// a(n) is U'a
	// b(n) is Unweighted Kalman gain

					// Compute b = DU'h, a = U'h
	a = h;
	for (j = n-1; j >= 1; --j)	// n-1..1
	{
		for (k = 0; k < j; ++k)	// 0..j-1
		{
			a[j] += UD(k,j) * a[k];
		}
		b[j] = UD(j,j) * a[j];
	}
	b[0] = UD(0,0) * a[0];

					// Update UD(0,0), d(0) modification
	alpha = r + b[0] * a[0];
	if (alpha <= 0) goto alphaNotPD;
	gamma = 1 / alpha;
	UD(0,0) *= r * gamma;
					// Update rest of UD and gain b
	for (j = 1; j < n; ++j)		// 1..n-1
	{
					// d modification
		alpha_jm1 = alpha;	// alpha at j-1
		alpha += b[j] * a[j];
		lamda = -a[j] * gamma;
		if (alpha <= 0) goto alphaNotPD;
		gamma = 1 / alpha;
		UD(j,j) *= alpha_jm1 * gamma;
					// U modification
		for (i = 0; i < j; ++i)		// 0..j-1
		{
			Float UD_jm1 = UD(i,j);
			UD(i,j) = UD_jm1 + lamda * b[i];
			b[i] += b[j] * UD_jm1;
		}
	}
					// Update gain from b
	noalias(gain) = b * gamma;
 	// Estimate the reciprocal condition number from upper triangular part
	return UdUrcond(UD,n);

alphaNotPD:
	return -1;
}

}//namespace

max_stars_repo_name: Exadios/Bayes-

max_issues_repo_name: Exadios/Bayes-

max_forks_repo_name: Exadios/Bayes-


text:
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.

#include <carla/PythonUtil.h>
#include <carla/client/Client.h>
#include <carla/client/World.h>

#include <boost/python/stl_iterator.hpp>

static void SetTimeout(carla::client::Client &client, double seconds) {
  client.SetTimeout(TimeDurationFromSeconds(seconds));
}

static auto GetAvailableMaps(const carla::client::Client &self) {
  carla::PythonUtil::ReleaseGIL unlock;
  boost::python::list result;
  for (const auto &str : self.GetAvailableMaps()) {
    result.append(str);
  }
  return result;
}

static void ApplyBatchCommands(
    const carla::client::Client &self,
    const boost::python::object &commands,
    bool do_tick) {
  using CommandType = carla::rpc::Command;
  std::vector<CommandType> cmds{
      boost::python::stl_input_iterator<CommandType>(commands),
      boost::python::stl_input_iterator<CommandType>()};
  self.ApplyBatch(std::move(cmds), do_tick);
}

static auto ApplyBatchCommandsSync(
    const carla::client::Client &self,
    const boost::python::object &commands,
    bool do_tick) {
  using CommandType = carla::rpc::Command;
  std::vector<CommandType> cmds{
      boost::python::stl_input_iterator<CommandType>(commands),
      boost::python::stl_input_iterator<CommandType>()};
  boost::python::list result;
  for (auto &response : self.ApplyBatchSync(std::move(cmds), do_tick)) {
    result.append(std::move(response));
  }
  return result;
}

void export_client() {
  using namespace boost::python;
  namespace cc = carla::client;

  class_<cc::Client>("Client",
      init<std::string, uint16_t, size_t>((arg("host"), arg("port"), arg("worker_threads")=0u)))
    .def("set_timeout", &::SetTimeout, (arg("seconds")))
    .def("get_client_version", &cc::Client::GetClientVersion)
    .def("get_server_version", CONST_CALL_WITHOUT_GIL(cc::Client, GetServerVersion))
    .def("get_world", &cc::Client::GetWorld)
    .def("get_available_maps", &GetAvailableMaps)
    .def("reload_world", CONST_CALL_WITHOUT_GIL(cc::Client, ReloadWorld))
    .def("load_world", CONST_CALL_WITHOUT_GIL_1(cc::Client, LoadWorld, std::string), (arg("map_name")))
    .def("start_recorder", CALL_WITHOUT_GIL_1(cc::Client, StartRecorder, std::string), (arg("name")))
    .def("stop_recorder", &cc::Client::StopRecorder)
    .def("show_recorder_file_info", CALL_WITHOUT_GIL_1(cc::Client, ShowRecorderFileInfo, std::string), (arg("name")))
    .def("show_recorder_collisions", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderCollisions, std::string, char, char), (arg("name"), arg("type1"), arg("type2")))
    .def("show_recorder_actors_blocked", CALL_WITHOUT_GIL_3(cc::Client, ShowRecorderActorsBlocked, std::string, float, float), (arg("name"), arg("min_time"), arg("min_distance")))
    .def("replay_file", CALL_WITHOUT_GIL_4(cc::Client, ReplayFile, std::string, float, float, int), (arg("name"), arg("time_start"), arg("duration"), arg("follow_id")))
    .def("apply_batch", &ApplyBatchCommands, (arg("commands"), arg("do_tick")=false))
    .def("apply_batch_sync", &ApplyBatchCommandsSync, (arg("commands"), arg("do_tick")=false))
  ;
}