<commit_before>// Copyright (c) 2010 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 "chrome/common/pepper_plugin_registry.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "remoting/client/plugin/pepper_entrypoints.h"

PepperPluginInfo::PepperPluginInfo() : is_internal(false) {
}

// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
  static PepperPluginRegistry registry;
  return &registry;
}

// static
void PepperPluginRegistry::GetList(std::vector<PepperPluginInfo>* plugins) {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    plugins->push_back(*it);
  }

  GetPluginInfoFromSwitch(plugins);
  GetExtraPlugins(plugins);
}

// static
void PepperPluginRegistry::PreloadModules() {
  std::vector<PepperPluginInfo> plugins;
  GetList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (!plugins[i].is_internal) {
      base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
      LOG_IF(WARNING, !library) << "Unable to load plugin "
                                << plugins[i].path.value();
    }
  }
}

// static
void PepperPluginRegistry::GetPluginInfoFromSwitch(
    std::vector<PepperPluginInfo>* plugins) {
  const std::wstring& value = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kRegisterPepperPlugins);
  if (value.empty())
    return;

  // FORMAT:
  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
  // plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
  //                *1( LWS + ";" + LWS + <mime-type> )

  std::vector<std::wstring> modules;
  SplitString(value, ',', &modules);
  for (size_t i = 0; i < modules.size(); ++i) {
    std::vector<std::wstring> parts;
    SplitString(modules[i], ';', &parts);
    if (parts.size() < 2) {
      DLOG(ERROR) << "Required mime-type not found";
      continue;
    }

    std::vector<std::wstring> name_parts;
    SplitString(parts[0], '#', &name_parts);

    PepperPluginInfo plugin;
    plugin.path = FilePath::FromWStringHack(name_parts[0]);
    if (name_parts.size() > 1)
      plugin.name = WideToUTF8(name_parts[1]);
    if (name_parts.size() > 2)
      plugin.type_descriptions = WideToUTF8(name_parts[2]);
    for (size_t j = 1; j < parts.size(); ++j)
      plugin.mime_types.push_back(WideToASCII(parts[j]));

    plugins->push_back(plugin);
  }
}

// static
void PepperPluginRegistry::GetExtraPlugins(
    std::vector<PepperPluginInfo>* plugins) {
  FilePath path;
  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path) &&
      file_util::PathExists(path)) {
    PepperPluginInfo pdf;
    pdf.path = path;
    pdf.name = "Chrome PDF Viewer";
    pdf.mime_types.push_back("application/pdf");
    pdf.file_extensions = "pdf";
    pdf.type_descriptions = "Portable Document Format";
    plugins->push_back(pdf);
  }
}

PepperPluginRegistry::InternalPluginInfo::InternalPluginInfo() {
  is_internal = true;
}

// static
void PepperPluginRegistry::GetInternalPluginInfo(
    InternalPluginInfoList* plugin_info) {
  // Currently, to centralize the internal plugin registration logic, we
  // hardcode the list of plugins, mimetypes, and registration information
  // in this function.  This is gross, but because the GetList() function is
  // called from both the renderer and browser the other option is to force a
  // special register function for each plugin to be called by both
  // RendererMain() and BrowserMain().  This seemed like the better tradeoff.
  //
  // TODO(ajwong): Think up a better way to maintain the plugin registration
  // information. Pehraps by construction of a singly linked list of
  // plugin initializers that is built with static initializers?

#if defined(ENABLE_REMOTING)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableChromoting)) {
    InternalPluginInfo info;
    // Add the chromoting plugin.
    DCHECK(info.is_internal);
    info.path =
        FilePath(FILE_PATH_LITERAL("internal-chromoting"));
    info.mime_types.push_back("pepper-application/x-chromoting");
    info.entry_points.get_interface = remoting::PPP_GetInterface;
    info.entry_points.initialize_module = remoting::PPP_InitializeModule;
    info.entry_points.shutdown_module = remoting::PPP_ShutdownModule;

    plugin_info->push_back(info);
  }
#endif
}

pepper::PluginModule* PepperPluginRegistry::GetModule(
    const FilePath& path) const {
  ModuleMap::const_iterator it = modules_.find(path);
  if (it == modules_.end())
    return NULL;
  return it->second;
}

PepperPluginRegistry::PepperPluginRegistry() {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);
  // Register modules for these suckers.
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    const FilePath& path = it->path;
    ModuleHandle module =
        pepper::PluginModule::CreateInternalModule(it->entry_points);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    modules_[path] = module;
  }

  // Add the modules specified on the command line last so that they can
  // override the internal plugins.
  std::vector<PepperPluginInfo> plugins;
  GetPluginInfoFromSwitch(&plugins);
  GetExtraPlugins(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    const FilePath& path = plugins[i].path;
    ModuleHandle module = pepper::PluginModule::CreateModule(path);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    modules_[path] = module;
  }
}
<commit_msg>Fix for pdf plugin not loaded in the linux sandbox.<commit_after>// Copyright (c) 2010 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 "chrome/common/pepper_plugin_registry.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "remoting/client/plugin/pepper_entrypoints.h"

PepperPluginInfo::PepperPluginInfo() : is_internal(false) {
}

// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
  static PepperPluginRegistry registry;
  return &registry;
}

// static
void PepperPluginRegistry::GetList(std::vector<PepperPluginInfo>* plugins) {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    plugins->push_back(*it);
  }

  GetPluginInfoFromSwitch(plugins);
  GetExtraPlugins(plugins);
}

// static
void PepperPluginRegistry::PreloadModules() {
  std::vector<PepperPluginInfo> plugins;
  GetList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (!plugins[i].is_internal) {
      base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
      LOG_IF(WARNING, !library) << "Unable to load plugin "
                                << plugins[i].path.value();
    }
  }
}

// static
void PepperPluginRegistry::GetPluginInfoFromSwitch(
    std::vector<PepperPluginInfo>* plugins) {
  const std::wstring& value = CommandLine::ForCurrentProcess()->GetSwitchValue(
      switches::kRegisterPepperPlugins);
  if (value.empty())
    return;

  // FORMAT:
  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
  // plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
  //                *1( LWS + ";" + LWS + <mime-type> )

  std::vector<std::wstring> modules;
  SplitString(value, ',', &modules);
  for (size_t i = 0; i < modules.size(); ++i) {
    std::vector<std::wstring> parts;
    SplitString(modules[i], ';', &parts);
    if (parts.size() < 2) {
      DLOG(ERROR) << "Required mime-type not found";
      continue;
    }

    std::vector<std::wstring> name_parts;
    SplitString(parts[0], '#', &name_parts);

    PepperPluginInfo plugin;
    plugin.path = FilePath::FromWStringHack(name_parts[0]);
    if (name_parts.size() > 1)
      plugin.name = WideToUTF8(name_parts[1]);
    if (name_parts.size() > 2)
      plugin.type_descriptions = WideToUTF8(name_parts[2]);
    for (size_t j = 1; j < parts.size(); ++j)
      plugin.mime_types.push_back(WideToASCII(parts[j]));

    plugins->push_back(plugin);
  }
}

// static
void PepperPluginRegistry::GetExtraPlugins(
    std::vector<PepperPluginInfo>* plugins) {
  FilePath path;
  // We can't check for path existance here, since we are in the sandbox.
  // If plugin is missing, it will later fail to
  // load the library and the missing plugin message will be displayed.
  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) {
    PepperPluginInfo pdf;
    pdf.path = path;
    pdf.name = "Chrome PDF Viewer";
    pdf.mime_types.push_back("application/pdf");
    pdf.file_extensions = "pdf";
    pdf.type_descriptions = "Portable Document Format";
    plugins->push_back(pdf);
  }
}

PepperPluginRegistry::InternalPluginInfo::InternalPluginInfo() {
  is_internal = true;
}

// static
void PepperPluginRegistry::GetInternalPluginInfo(
    InternalPluginInfoList* plugin_info) {
  // Currently, to centralize the internal plugin registration logic, we
  // hardcode the list of plugins, mimetypes, and registration information
  // in this function.  This is gross, but because the GetList() function is
  // called from both the renderer and browser the other option is to force a
  // special register function for each plugin to be called by both
  // RendererMain() and BrowserMain().  This seemed like the better tradeoff.
  //
  // TODO(ajwong): Think up a better way to maintain the plugin registration
  // information. Pehraps by construction of a singly linked list of
  // plugin initializers that is built with static initializers?

#if defined(ENABLE_REMOTING)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableChromoting)) {
    InternalPluginInfo info;
    // Add the chromoting plugin.
    DCHECK(info.is_internal);
    info.path =
        FilePath(FILE_PATH_LITERAL("internal-chromoting"));
    info.mime_types.push_back("pepper-application/x-chromoting");
    info.entry_points.get_interface = remoting::PPP_GetInterface;
    info.entry_points.initialize_module = remoting::PPP_InitializeModule;
    info.entry_points.shutdown_module = remoting::PPP_ShutdownModule;

    plugin_info->push_back(info);
  }
#endif
}

pepper::PluginModule* PepperPluginRegistry::GetModule(
    const FilePath& path) const {
  ModuleMap::const_iterator it = modules_.find(path);
  if (it == modules_.end())
    return NULL;
  return it->second;
}

PepperPluginRegistry::PepperPluginRegistry() {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);
  // Register modules for these suckers.
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    const FilePath& path = it->path;
    ModuleHandle module =
        pepper::PluginModule::CreateInternalModule(it->entry_points);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    modules_[path] = module;
  }

  // Add the modules specified on the command line last so that they can
  // override the internal plugins.
  std::vector<PepperPluginInfo> plugins;
  GetPluginInfoFromSwitch(&plugins);
  GetExtraPlugins(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    const FilePath& path = plugins[i].path;
    ModuleHandle module = pepper::PluginModule::CreateModule(path);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    modules_[path] = module;
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 "chrome/common/pepper_plugin_registry.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "remoting/client/plugin/pepper_entrypoints.h"

const char* PepperPluginRegistry::kPDFPluginName = "Chrome PDF Viewer";
const char* PepperPluginRegistry::kPDFPluginMimeType = "application/pdf";
const char* PepperPluginRegistry::kPDFPluginExtension = "pdf";
const char* PepperPluginRegistry::kPDFPluginDescription =
    "Portable Document Format";

PepperPluginInfo::PepperPluginInfo()
    : is_internal(false),
      is_out_of_process(false) {
}

PepperPluginInfo::~PepperPluginInfo() {}

// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
  static PepperPluginRegistry registry;
  return &registry;
}

// static
void PepperPluginRegistry::GetList(std::vector<PepperPluginInfo>* plugins) {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    plugins->push_back(*it);
  }

  GetPluginInfoFromSwitch(plugins);
  GetExtraPlugins(plugins);
}

// static
void PepperPluginRegistry::PreloadModules() {
  std::vector<PepperPluginInfo> plugins;
  GetList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (!plugins[i].is_internal && !plugins[i].is_out_of_process) {
      base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
      LOG_IF(WARNING, !library) << "Unable to load plugin "
                                << plugins[i].path.value();
    }
  }
}

// static
void PepperPluginRegistry::GetPluginInfoFromSwitch(
    std::vector<PepperPluginInfo>* plugins) {
  const std::string value =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kRegisterPepperPlugins);
  if (value.empty())
    return;

  bool out_of_process =
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);

  // FORMAT:
  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
  // plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
  //                *1( LWS + ";" + LWS + <mime-type> )

  std::vector<std::string> modules;
  base::SplitString(value, ',', &modules);
  for (size_t i = 0; i < modules.size(); ++i) {
    std::vector<std::string> parts;
    base::SplitString(modules[i], ';', &parts);
    if (parts.size() < 2) {
      DLOG(ERROR) << "Required mime-type not found";
      continue;
    }

    std::vector<std::string> name_parts;
    base::SplitString(parts[0], '#', &name_parts);

    PepperPluginInfo plugin;
    plugin.is_out_of_process = out_of_process;
#if defined(OS_WIN)
    // This means we can't provide plugins from non-ASCII paths, but
    // since this switch is only for development I don't think that's
    // too awful.
    plugin.path = FilePath(ASCIIToUTF16(name_parts[0]));
#else
    plugin.path = FilePath(name_parts[0]);
#endif
    if (name_parts.size() > 1)
      plugin.name = name_parts[1];
    if (name_parts.size() > 2)
      plugin.type_descriptions = name_parts[2];
    for (size_t j = 1; j < parts.size(); ++j)
      plugin.mime_types.push_back(parts[j]);

    plugins->push_back(plugin);
  }
}

// static
void PepperPluginRegistry::GetExtraPlugins(
    std::vector<PepperPluginInfo>* plugins) {
  // Once we're sandboxed, we can't know if the PDF plugin is
  // available or not; but (on Linux) this function is always called
  // once before we're sandboxed.  So the first time through test if
  // the file is available and then skip the check on subsequent calls
  // if yes.
  static bool skip_pdf_file_check = false;
  FilePath path;
  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) {
    if (skip_pdf_file_check || file_util::PathExists(path)) {
      PepperPluginInfo pdf;
      pdf.path = path;
      pdf.name = kPDFPluginName;
      pdf.mime_types.push_back(kPDFPluginMimeType);
      pdf.file_extensions = kPDFPluginExtension;
      pdf.type_descriptions = kPDFPluginDescription;
      plugins->push_back(pdf);

      skip_pdf_file_check = true;
    }
  }
}

PepperPluginRegistry::InternalPluginInfo::InternalPluginInfo() {
  is_internal = true;
}

// static
void PepperPluginRegistry::GetInternalPluginInfo(
    InternalPluginInfoList* plugin_info) {
  // Currently, to centralize the internal plugin registration logic, we
  // hardcode the list of plugins, mimetypes, and registration information
  // in this function.  This is gross, but because the GetList() function is
  // called from both the renderer and browser the other option is to force a
  // special register function for each plugin to be called by both
  // RendererMain() and BrowserMain().  This seemed like the better tradeoff.
  //
  // TODO(ajwong): Think up a better way to maintain the plugin registration
  // information. Perhaps by construction of a singly linked list of
  // plugin initializers that is built with static initializers?

#if defined(ENABLE_REMOTING)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableRemoting)) {
    InternalPluginInfo info;
    // Add the chromoting plugin.
    DCHECK(info.is_internal);
    info.path =
        FilePath(FILE_PATH_LITERAL("internal-chromoting"));
    info.mime_types.push_back("pepper-application/x-chromoting");
    info.entry_points.get_interface = remoting::PPP_GetInterface;
    info.entry_points.initialize_module = remoting::PPP_InitializeModule;
    info.entry_points.shutdown_module = remoting::PPP_ShutdownModule;

    plugin_info->push_back(info);
  }
#endif
}

bool PepperPluginRegistry::RunOutOfProcessForPlugin(
    const FilePath& path) const {
  // TODO(brettw) don't recompute this every time. But since this Pepper
  // switch is only for development, it's OK for now.
  std::vector<PepperPluginInfo> plugins;
  GetList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (path == plugins[i].path)
      return plugins[i].is_out_of_process;
  }
  return false;
}

pepper::PluginModule* PepperPluginRegistry::GetModule(
    const FilePath& path) const {
  ModuleMap::const_iterator it = modules_.find(path);
  if (it == modules_.end())
    return NULL;
  return it->second;
}

PepperPluginRegistry::~PepperPluginRegistry() {}

PepperPluginRegistry::PepperPluginRegistry() {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);

  // Register modules for these suckers.
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    const FilePath& path = it->path;
    ModuleHandle module =
        pepper::PluginModule::CreateInternalModule(it->entry_points);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    module->set_name(it->name);
    modules_[path] = module;
  }

  // Add the modules specified on the command line last so that they can
  // override the internal plugins.
  std::vector<PepperPluginInfo> plugins;
  GetPluginInfoFromSwitch(&plugins);
  GetExtraPlugins(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (plugins[i].is_out_of_process)
      continue;  // Only preload in-process plugins.

    const FilePath& path = plugins[i].path;
    ModuleHandle module = pepper::PluginModule::CreateModule(path);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    module->set_name(plugins[i].name);
    modules_[path] = module;
  }
}
<commit_msg>Pepper: leak the plugin registry<commit_after>// Copyright (c) 2010 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 "chrome/common/pepper_plugin_registry.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/native_library.h"
#include "base/path_service.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "remoting/client/plugin/pepper_entrypoints.h"

const char* PepperPluginRegistry::kPDFPluginName = "Chrome PDF Viewer";
const char* PepperPluginRegistry::kPDFPluginMimeType = "application/pdf";
const char* PepperPluginRegistry::kPDFPluginExtension = "pdf";
const char* PepperPluginRegistry::kPDFPluginDescription =
    "Portable Document Format";

PepperPluginInfo::PepperPluginInfo()
    : is_internal(false),
      is_out_of_process(false) {
}

PepperPluginInfo::~PepperPluginInfo() {}

// static
PepperPluginRegistry* PepperPluginRegistry::GetInstance() {
  static PepperPluginRegistry* registry = NULL;
  // This object leaks.  It is a temporary hack to work around a crash.
  // http://code.google.com/p/chromium/issues/detail?id=63234
  if (!registry)
    registry = new PepperPluginRegistry;
  return registry;
}

// static
void PepperPluginRegistry::GetList(std::vector<PepperPluginInfo>* plugins) {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    plugins->push_back(*it);
  }

  GetPluginInfoFromSwitch(plugins);
  GetExtraPlugins(plugins);
}

// static
void PepperPluginRegistry::PreloadModules() {
  std::vector<PepperPluginInfo> plugins;
  GetList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (!plugins[i].is_internal && !plugins[i].is_out_of_process) {
      base::NativeLibrary library = base::LoadNativeLibrary(plugins[i].path);
      LOG_IF(WARNING, !library) << "Unable to load plugin "
                                << plugins[i].path.value();
    }
  }
}

// static
void PepperPluginRegistry::GetPluginInfoFromSwitch(
    std::vector<PepperPluginInfo>* plugins) {
  const std::string value =
      CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kRegisterPepperPlugins);
  if (value.empty())
    return;

  bool out_of_process =
      CommandLine::ForCurrentProcess()->HasSwitch(switches::kPpapiOutOfProcess);

  // FORMAT:
  // command-line = <plugin-entry> + *( LWS + "," + LWS + <plugin-entry> )
  // plugin-entry = <file-path> + ["#" + <name> + ["#" + <description>]] +
  //                *1( LWS + ";" + LWS + <mime-type> )

  std::vector<std::string> modules;
  base::SplitString(value, ',', &modules);
  for (size_t i = 0; i < modules.size(); ++i) {
    std::vector<std::string> parts;
    base::SplitString(modules[i], ';', &parts);
    if (parts.size() < 2) {
      DLOG(ERROR) << "Required mime-type not found";
      continue;
    }

    std::vector<std::string> name_parts;
    base::SplitString(parts[0], '#', &name_parts);

    PepperPluginInfo plugin;
    plugin.is_out_of_process = out_of_process;
#if defined(OS_WIN)
    // This means we can't provide plugins from non-ASCII paths, but
    // since this switch is only for development I don't think that's
    // too awful.
    plugin.path = FilePath(ASCIIToUTF16(name_parts[0]));
#else
    plugin.path = FilePath(name_parts[0]);
#endif
    if (name_parts.size() > 1)
      plugin.name = name_parts[1];
    if (name_parts.size() > 2)
      plugin.type_descriptions = name_parts[2];
    for (size_t j = 1; j < parts.size(); ++j)
      plugin.mime_types.push_back(parts[j]);

    plugins->push_back(plugin);
  }
}

// static
void PepperPluginRegistry::GetExtraPlugins(
    std::vector<PepperPluginInfo>* plugins) {
  // Once we're sandboxed, we can't know if the PDF plugin is
  // available or not; but (on Linux) this function is always called
  // once before we're sandboxed.  So the first time through test if
  // the file is available and then skip the check on subsequent calls
  // if yes.
  static bool skip_pdf_file_check = false;
  FilePath path;
  if (PathService::Get(chrome::FILE_PDF_PLUGIN, &path)) {
    if (skip_pdf_file_check || file_util::PathExists(path)) {
      PepperPluginInfo pdf;
      pdf.path = path;
      pdf.name = kPDFPluginName;
      pdf.mime_types.push_back(kPDFPluginMimeType);
      pdf.file_extensions = kPDFPluginExtension;
      pdf.type_descriptions = kPDFPluginDescription;
      plugins->push_back(pdf);

      skip_pdf_file_check = true;
    }
  }
}

PepperPluginRegistry::InternalPluginInfo::InternalPluginInfo() {
  is_internal = true;
}

// static
void PepperPluginRegistry::GetInternalPluginInfo(
    InternalPluginInfoList* plugin_info) {
  // Currently, to centralize the internal plugin registration logic, we
  // hardcode the list of plugins, mimetypes, and registration information
  // in this function.  This is gross, but because the GetList() function is
  // called from both the renderer and browser the other option is to force a
  // special register function for each plugin to be called by both
  // RendererMain() and BrowserMain().  This seemed like the better tradeoff.
  //
  // TODO(ajwong): Think up a better way to maintain the plugin registration
  // information. Perhaps by construction of a singly linked list of
  // plugin initializers that is built with static initializers?

#if defined(ENABLE_REMOTING)
  if (CommandLine::ForCurrentProcess()->HasSwitch(
      switches::kEnableRemoting)) {
    InternalPluginInfo info;
    // Add the chromoting plugin.
    DCHECK(info.is_internal);
    info.path =
        FilePath(FILE_PATH_LITERAL("internal-chromoting"));
    info.mime_types.push_back("pepper-application/x-chromoting");
    info.entry_points.get_interface = remoting::PPP_GetInterface;
    info.entry_points.initialize_module = remoting::PPP_InitializeModule;
    info.entry_points.shutdown_module = remoting::PPP_ShutdownModule;

    plugin_info->push_back(info);
  }
#endif
}

bool PepperPluginRegistry::RunOutOfProcessForPlugin(
    const FilePath& path) const {
  // TODO(brettw) don't recompute this every time. But since this Pepper
  // switch is only for development, it's OK for now.
  std::vector<PepperPluginInfo> plugins;
  GetList(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (path == plugins[i].path)
      return plugins[i].is_out_of_process;
  }
  return false;
}

pepper::PluginModule* PepperPluginRegistry::GetModule(
    const FilePath& path) const {
  ModuleMap::const_iterator it = modules_.find(path);
  if (it == modules_.end())
    return NULL;
  return it->second;
}

PepperPluginRegistry::~PepperPluginRegistry() {}

PepperPluginRegistry::PepperPluginRegistry() {
  InternalPluginInfoList internal_plugin_info;
  GetInternalPluginInfo(&internal_plugin_info);

  // Register modules for these suckers.
  for (InternalPluginInfoList::const_iterator it =
         internal_plugin_info.begin();
       it != internal_plugin_info.end();
       ++it) {
    const FilePath& path = it->path;
    ModuleHandle module =
        pepper::PluginModule::CreateInternalModule(it->entry_points);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    module->set_name(it->name);
    modules_[path] = module;
  }

  // Add the modules specified on the command line last so that they can
  // override the internal plugins.
  std::vector<PepperPluginInfo> plugins;
  GetPluginInfoFromSwitch(&plugins);
  GetExtraPlugins(&plugins);
  for (size_t i = 0; i < plugins.size(); ++i) {
    if (plugins[i].is_out_of_process)
      continue;  // Only preload in-process plugins.

    const FilePath& path = plugins[i].path;
    ModuleHandle module = pepper::PluginModule::CreateModule(path);
    if (!module) {
      DLOG(ERROR) << "Failed to load pepper module: " << path.value();
      continue;
    }
    module->set_name(plugins[i].name);
    modules_[path] = module;
  }
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <vector>
#include <utility>
#include <string>
#include "util/thread.h"
#include "util/pair.h"
#include "util/script_state.h"

namespace lean {
static mutex g_code_mutex;
static std::vector<std::pair<bool, std::string>> g_code;
static mutex g_state_mutex;
static std::vector<script_state> g_states;
static std::vector<script_state> g_available_states;

/** \brief Execute \c code in all states in the pool */
void system_dostring(char const * code) {
    {
        // Execute code in all existing states
        lock_guard<mutex> lk(g_state_mutex);
        for (auto & s : g_states) {
            s.dostring(code);
        }
    }
    {
        // Save code for future states
        lock_guard<mutex> lk(g_code_mutex);
        g_code.push_back(mk_pair(true, code));
    }
}

/** \brief Import \c fname in all states in the pool */
void system_import(char const * fname) {
    {
        // Import file in all existing states
        lock_guard<mutex> lk(g_state_mutex);
        for (auto & s : g_states) {
            s.import(fname);
        }
    }
    {
        // Save module for future states
        lock_guard<mutex> lk(g_code_mutex);
        g_code.push_back(mk_pair(false, fname));
    }
}

static script_state get_state() {
    {
        // Try to reuse existing state
        lock_guard<mutex> lk(g_state_mutex);
        if (!g_available_states.empty()) {
            script_state r(g_available_states.back());
            g_available_states.pop_back();
            return r;
        }
    }

    {
        // Execute existing code in new state
        lock_guard<mutex> lk(g_code_mutex);
        script_state r;
        for (auto const & p : g_code) {
            if (p.first)
                r.dostring(p.second.c_str());
            else
                r.import(p.second.c_str());
        }
        g_states.push_back(r);
        {
            // save new state in vector of all states
            lock_guard<mutex> lk(g_state_mutex);
            g_states.push_back(r);
        }
        return r;
    }
}

static void recycle_state(script_state s) {
    lock_guard<mutex> lk(g_state_mutex);
    g_available_states.push_back(s);
}

struct script_state_ref {
    script_state m_state;
    script_state_ref():m_state(get_state()) {}
    ~script_state_ref() { recycle_state(m_state); }
};

// We should use std::unique_ptr, but clang++ 3.3.1 crashes when we use it.
std::shared_ptr<script_state_ref> LEAN_THREAD_LOCAL g_thread_state;

script_state get_thread_script_state() {
    if (!g_thread_state)
        g_thread_state = std::make_shared<script_state_ref>();
    return g_thread_state->m_state;
}

void release_thread_script_state() {
    g_thread_state = nullptr;
}
}
<commit_msg>fix(util/thread_script_state): add a better workaround for clang++ bug<commit_after>/*
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.

Author: Leonardo de Moura
*/
#include <vector>
#include <utility>
#include <string>
#include "util/thread.h"
#include "util/pair.h"
#include "util/script_state.h"

namespace lean {
static mutex g_code_mutex;
static std::vector<std::pair<bool, std::string>> g_code;
static mutex g_state_mutex;
static std::vector<script_state> g_states;
static std::vector<script_state> g_available_states;

/** \brief Execute \c code in all states in the pool */
void system_dostring(char const * code) {
    {
        // Execute code in all existing states
        lock_guard<mutex> lk(g_state_mutex);
        for (auto & s : g_states) {
            s.dostring(code);
        }
    }
    {
        // Save code for future states
        lock_guard<mutex> lk(g_code_mutex);
        g_code.push_back(mk_pair(true, code));
    }
}

/** \brief Import \c fname in all states in the pool */
void system_import(char const * fname) {
    {
        // Import file in all existing states
        lock_guard<mutex> lk(g_state_mutex);
        for (auto & s : g_states) {
            s.import(fname);
        }
    }
    {
        // Save module for future states
        lock_guard<mutex> lk(g_code_mutex);
        g_code.push_back(mk_pair(false, fname));
    }
}

static script_state get_state() {
    {
        // Try to reuse existing state
        lock_guard<mutex> lk(g_state_mutex);
        if (!g_available_states.empty()) {
            script_state r(g_available_states.back());
            g_available_states.pop_back();
            return r;
        }
    }

    {
        // Execute existing code in new state
        lock_guard<mutex> lk(g_code_mutex);
        script_state r;
        for (auto const & p : g_code) {
            if (p.first)
                r.dostring(p.second.c_str());
            else
                r.import(p.second.c_str());
        }
        g_states.push_back(r);
        {
            // save new state in vector of all states
            lock_guard<mutex> lk(g_state_mutex);
            g_states.push_back(r);
        }
        return r;
    }
}

static void recycle_state(script_state s) {
    lock_guard<mutex> lk(g_state_mutex);
    g_available_states.push_back(s);
}

struct script_state_ref {
    script_state m_state;
    script_state_ref():m_state(get_state()) {}
    ~script_state_ref() { recycle_state(m_state); }
};

static std::unique_ptr<script_state_ref> & get_script_state_ref() {
    static std::unique_ptr<script_state_ref> LEAN_THREAD_LOCAL g_thread_state;
    if (!g_thread_state)
        g_thread_state.reset(new script_state_ref());
    return g_thread_state;
}

script_state get_thread_script_state() {
    return get_script_state_ref()->m_state;
}

void release_thread_script_state() {
    get_script_state_ref().reset(nullptr);
}
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012-2013, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"
#include "boost/format.hpp"

#include "GafferBindings/Serialisation.h"
#include "GafferBindings/ValuePlugBinding.h"
#include "GafferBindings/TypedPlugBinding.h"

#include "GafferImage/AtomicFormatPlug.h"
#include "GafferImageBindings/FormatBinding.h"
#include "GafferImageBindings/AtomicFormatPlugBinding.h"

using namespace std;
using namespace boost::python;
using namespace Gaffer;
using namespace GafferBindings;
using namespace GafferImage;
using namespace GafferImageBindings;

namespace
{

class AtomicFormatPlugSerialiser : public GafferBindings::ValuePlugSerialiser
{

	public :

		virtual void moduleDependencies( const Gaffer::GraphComponent *graphComponent, std::set<std::string> &modules ) const
		{
			ValuePlugSerialiser::moduleDependencies( graphComponent, modules );
			modules.insert( "IECore" );
		}

		virtual std::string postConstructor( const Gaffer::GraphComponent *graphComponent, const std::string &identifier, const Serialisation &serialisation ) const
		{
			std::string result;

			const Plug *plug = static_cast<const Plug *>( graphComponent );
			if( plug->node()->typeId() == static_cast<IECore::TypeId>(ScriptNodeTypeId) )
			{
				// If this is the default format plug then write out all of the formats.
				/// \todo Why do we do this? Unfortunately it's very hard to tell because
				/// there are no unit tests for it. Why don't we allow the config files to
				/// just recreate the formats next time?
				vector<string> names;
				GafferImage::Format::formatNames( names );
				for( vector<string>::const_iterator it = names.begin(), eIt = names.end(); it != eIt; ++it )
				{
					result +=
						"GafferImage.Format.registerFormat( " +
						formatRepr( Format::getFormat( *it ) ) +
						", \"" + *it + "\" )\n";
				}
			}

			result += ValuePlugSerialiser::postConstructor( graphComponent, identifier, serialisation );
			return result;
		}

};

} // namespace

void GafferImageBindings::bindAtomicFormatPlug()
{
	TypedPlugClass<AtomicFormatPlug>();

	Serialisation::registerSerialiser( static_cast<IECore::TypeId>(AtomicFormatPlugTypeId), new AtomicFormatPlugSerialiser );
}
<commit_msg>AtomicFormatPlugBinding : Remove serialisation of registered formats.<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2012-2013, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//      * Redistributions of source code must retain the above
//        copyright notice, this list of conditions and the following
//        disclaimer.
//
//      * Redistributions in binary form must reproduce the above
//        copyright notice, this list of conditions and the following
//        disclaimer in the documentation and/or other materials provided with
//        the distribution.
//
//      * Neither the name of John Haddon nor the names of
//        any other contributors to this software may be used to endorse or
//        promote products derived from this software without specific prior
//        written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"
#include "boost/format.hpp"

#include "GafferBindings/Serialisation.h"
#include "GafferBindings/ValuePlugBinding.h"
#include "GafferBindings/TypedPlugBinding.h"

#include "GafferImage/AtomicFormatPlug.h"
#include "GafferImageBindings/FormatBinding.h"
#include "GafferImageBindings/AtomicFormatPlugBinding.h"

using namespace std;
using namespace boost::python;
using namespace Gaffer;
using namespace GafferBindings;
using namespace GafferImage;
using namespace GafferImageBindings;

namespace
{

class AtomicFormatPlugSerialiser : public GafferBindings::ValuePlugSerialiser
{

	public :

		virtual void moduleDependencies( const Gaffer::GraphComponent *graphComponent, std::set<std::string> &modules ) const
		{
			ValuePlugSerialiser::moduleDependencies( graphComponent, modules );
			modules.insert( "IECore" );
		}

};

} // namespace

void GafferImageBindings::bindAtomicFormatPlug()
{
	TypedPlugClass<AtomicFormatPlug>();

	Serialisation::registerSerialiser( static_cast<IECore::TypeId>(AtomicFormatPlugTypeId), new AtomicFormatPlugSerialiser );
}
<|endoftext|>


<commit_before>#include <Python.h>

#include <string>

#include <boost/test/unit_test.hpp>

#include <ackward/core/ByteArray.hpp>
#include <ackward/core/Exceptions.hpp>

using namespace ackward::core;
namespace bp=boost::python;

BOOST_AUTO_TEST_SUITE( bytearray_test )

BOOST_AUTO_TEST_CASE( existing_ctor )
{
    static const std::string data("asdf");

    bp::object pb = bp::object(
        bp::handle<>(
            PyByteArray_FromStringAndSize(data.c_str(), data.size())));

    ByteArray b(pb);

    BOOST_CHECK((std::size_t)b.size() == data.size());
    BOOST_CHECK(std::string(b.begin(), b.end()) == data);
}

BOOST_AUTO_TEST_CASE( existing_ctor_throws_value_error )
{
    BOOST_CHECK_THROW(
        ByteArray(bp::object(4)),
        ackward::core::ValueError);
}

BOOST_AUTO_TEST_CASE( from_data_ctor )
{
    std::string data("asdf");

    ByteArray b(data.c_str(), data.size());
    BOOST_CHECK((std::size_t)b.size() == data.size());
    BOOST_CHECK(std::string(b.begin(), b.end()) == data);
}

BOOST_AUTO_TEST_CASE( default_ctor )
{
    ByteArray b;
    BOOST_CHECK(b.size() == 0);
}

BOOST_AUTO_TEST_CASE( index )
{
    std::string data("1234");
    ByteArray b(data.c_str(), data.size());

    for (int i = 0; i < b.size(); ++i)
    {
        BOOST_CHECK(data[i] == b[i]);
    }
}

BOOST_AUTO_TEST_CASE( index_throw )
{
    std::string data("1234");
    ByteArray b(data.c_str(), data.size());

    BOOST_CHECK_THROW(
        b[5],
        IndexError);
}

BOOST_AUTO_TEST_CASE( index_modify )
{
    std::string data("1234");
    ByteArray b(data.c_str(), data.size());

    std::string data2("asdf");
    for (int i = 0; i < b.size(); ++i)
        b[i] = data2[i];

    BOOST_CHECK(std::string(b.begin(), b.end()) == data2);
    BOOST_ASSERT(data != data2);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>updated ByteArray unittests to reflect new API<commit_after>#include <Python.h>

#include <string>
#include <vector>

#include <boost/test/unit_test.hpp>

#include <ackward/core/ByteArray.hpp>
#include <ackward/core/Exceptions.hpp>

using namespace ackward::core;
namespace bp=boost::python;

BOOST_AUTO_TEST_SUITE( bytearray_test )

BOOST_AUTO_TEST_CASE( existing_ctor )
{
    static const std::string data("asdf");

    bp::object pb = bp::object(
        bp::handle<>(
            PyByteArray_FromStringAndSize(data.c_str(), data.size())));

    ByteArray b(pb);

    BOOST_CHECK((std::size_t)b.size() == data.size());
    BOOST_CHECK(std::string(b.begin(), b.end()) == data);
}

BOOST_AUTO_TEST_CASE( existing_ctor_throws_value_error )
{
    BOOST_CHECK_THROW(
        ByteArray(bp::object(4)),
        ackward::core::ValueError);
}

BOOST_AUTO_TEST_CASE( from_data_ctor )
{
    std::string data("asdf");

    ByteArray b(
        reinterpret_cast<const unsigned char*>(data.c_str()),
        data.size());
    BOOST_CHECK((std::size_t)b.size() == data.size());
    BOOST_CHECK(std::string(b.begin(), b.end()) == data);
}

BOOST_AUTO_TEST_CASE( default_ctor )
{
    ByteArray b;
    BOOST_CHECK(b.size() == 0);
}

BOOST_AUTO_TEST_CASE( index )
{
    std::string data("1234");
    ByteArray b(
        reinterpret_cast<const unsigned char*>(data.c_str()),
        data.size());

    for (int i = 0; i < b.size(); ++i)
    {
        BOOST_CHECK(data[i] == b[i]);
    }
}

BOOST_AUTO_TEST_CASE( index_throw )
{
    std::string data("1234");
    ByteArray b(
        reinterpret_cast<const unsigned char*>(data.c_str()),
        data.size());

    BOOST_CHECK_THROW(
        b[5],
        IndexError);
}

BOOST_AUTO_TEST_CASE( index_modify )
{
    std::string data("1234");
    ByteArray b(
        reinterpret_cast<const unsigned char*>(data.c_str()),
        data.size());

    std::string data2("asdf");
    for (int i = 0; i < b.size(); ++i)
        b[i] = data2[i];

    BOOST_CHECK(std::string(b.begin(), b.end()) == data2);
    BOOST_ASSERT(data != data2);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#ifndef PCL_TRACKING_IMPL_PARTICLE_FILTER_H_
#define PCL_TRACKING_IMPL_PARTICLE_FILTER_H_

#include <boost/random.hpp>

#include <pcl/common/common.h>
#include <pcl/common/eigen.h>
#include <pcl/common/transforms.h>

template <typename PointInT, typename StateT> bool
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::initCompute ()
{
  if (!Tracker<PointInT, StateT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  coherence_->setTargetCloud (input_);

  if (!particles_ || particles_->points.empty ())
    initParticles ();
  return (true);
}

template <typename PointInT, typename StateT> double
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::calcLikelihood (const StateT &hypothesis)
{
  const Eigen::Affine3f trans = toEigenMatrix (hypothesis);
  PointCloudInPtr transed_reference = PointCloudInPtr (new PointCloudIn ());
  pcl::transformPointCloudWithNormals<PointInT> (*ref_, *transed_reference, trans);

  // search the nearest pairs
  std::vector<int> k_indices(1);
  std::vector<float> k_distances(1);
  int num_points = 0;
  IndicesPtr indices = IndicesPtr (new std::vector<int> ());
  for ( size_t i = 0; i < transed_reference->points.size (); i++ )
  {
    PointInT input_point = transed_reference->points[i];

    if (!pcl_isfinite(input_point.x) || !pcl_isfinite(input_point.y) || !pcl_isfinite(input_point.z))
      continue;
    // take occlusion into account
    Eigen::Vector4f p = input_point.getVector4fMap ();
    Eigen::Vector4f n = input_point.getNormalVector4fMap ();
    double theta = pcl::getAngle3D(p, n);

    // TODO: check NAN
    if ( theta > occlusion_angle_thr_ )
    {
      indices->push_back (i);
      ++num_points;
    }
  }

  //coherence_->setInputCloud (transed_reference);
  //coherence_->setIndices (indices);
  double val = coherence_->compute (transed_reference, indices);

  // take min_indices_ into account
  // TODO: normalization of likelihood is required?
  double likelihood;
  if ( num_points >= min_indices_ )
    likelihood = val;
  //likelihood = exp((((ret * ret ) / num) / (- 2.0 * sigma2)));
  else
    likelihood = 0.0;
  return likelihood;
}

template <typename PointInT, typename StateT> int
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::sampleWithReplacement
(const std::vector<int>& a, const std::vector<double>& q)
{
  using namespace boost;
  static mt19937 gen (static_cast<unsigned long>(time (0)));
  uniform_real<> dst (0.0, 1.0);
  variate_generator<mt19937&, uniform_real<> > rand (gen, dst);
  double rU = rand () * particle_num_;
  int k = (int)rU;
  rU -= k;    /* rU - [rU] */
  if ( rU < q[k] )
    return k;
  else
    return a[k];
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::genAliasTable (std::vector<int> &a, std::vector<double> &q)
{
  /* generate an alias table, a and q */
  std::vector<int> HL (particle_num_);
  std::vector<int>::iterator H = HL.begin ();
  std::vector<int>::iterator L = HL.end () - 1;
  for ( int i = 0; i < particle_num_; i++ )
    q[i] = particles_->points[i].weight * particle_num_;
  for ( int i = 0; i < particle_num_; i++ )
    a[i] = i;
  // setup H and L
  for ( int i = 0; i < particle_num_; i++ )
    if ( q[i] >= 1.0 )
      *H++ = i;
    else
      *L-- = i;

  while ( H != HL.begin() && L != HL.end() - 1 )
  {
    int j = *(L + 1);
    int k = *(H - 1);
    a[j] = k;
    q[k] += q[j] - 1;
    L++;
    if ( q[k] < 1.0 )
    {
      *L-- = k;
      --H;
    }
  }
}

template <typename PointInT, typename StateT> Eigen::Affine3f
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::toEigenMatrix (const StateT& particle)
{
  return particle.toEigenMatrix ();
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::initParticles ()
{
  PCL_INFO ("[pcl::%s::initParticles] initializing...\n", getClassName ().c_str ());
  particles_.reset( new PointCloudState ());

  representative_state_.zero ();
  representative_state_.weight = 0.0;

  std::vector<double> initial_noise_mean;
  StateT offset = StateT::toState (trans_);
  representative_state_ = offset;
  // sampling...
  for ( int i = 0; i < particle_num_; i++ )
  {
    StateT p;
    p.weight = 1.0 / particle_num_;
    p.zero ();
    p.sample (initial_noise_mean_, initial_noise_covariance_);
    p = p + offset;
    particles_->points.push_back (p); // update
  }
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::normalizeWeight ()
{
  double sum = 0.0;
  for ( int i = 0; i < particle_num_; i++ )
    sum += particles_->points[i].weight;
  for ( int i = 0; i < particle_num_; i++ )
    particles_->points[i].weight =  particles_->points[i].weight / sum;
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::weight ()
{
  coherence_->initCompute ();
  for ( int i = 0; i < particle_num_; i++ )
  {
    double likelihood = calcLikelihood (particles_->points[i]);
    particles_->points[i].weight = likelihood;
  }
  normalizeWeight ();
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::resample ()
{
  std::vector<int> a (particle_num_);
  std::vector<double> q (particle_num_);
  genAliasTable (a, q);

  const std::vector<double> zero_mean (StateT::stateDimension (), 0.0);
  // memoize the original list of particles
  //std::vector<Particle> origparticles = particles_;
  PointCloudStatePtr  origparticles = particles_;
  particles_->points.clear ();
  // the first particle, it is a just copy of the maximum result
  pcl::tracking::ParticleXYZRPY p = representative_state_;
  particles_->points.push_back (p);
  for ( int i = 1; i < particle_num_; i++ )
  {
    int target_particle_index = sampleWithReplacement (a, q);
    pcl::tracking::ParticleXYZRPY p = origparticles->points[target_particle_index];
    // add noise using gaussian
    p.sample (zero_mean, step_noise_covariance_);
    particles_->points.push_back (p);
  }
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::update ()
{
  representative_state_.zero ();

  double maxweight = particles_->points[0].weight;
  int maxindex = 0;
  for ( int i = 1; i < particle_num_; i++)
  {
    StateT p = particles_->points[i];
    if (maxweight < p.weight )
    {
      maxweight = p.weight;
      maxindex = i;
    }
  }
  representative_state_ = particles_->points[maxindex];
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::computeTracking ()
{

  for (int i = 0; i < iteration_num_; i++)
  {
    resample ();
    weight (); // likelihood is called in it
    update ();
  }

  if ( getResult ().weight < resample_likelihood_thr_ )
  {
    PCL_WARN ("too small likelihood, re-initializing...\n");
    initParticles ();
  }
}

#endif
<commit_msg>using the template arguments<commit_after>#ifndef PCL_TRACKING_IMPL_PARTICLE_FILTER_H_
#define PCL_TRACKING_IMPL_PARTICLE_FILTER_H_

#include <boost/random.hpp>

#include <pcl/common/common.h>
#include <pcl/common/eigen.h>
#include <pcl/common/transforms.h>

template <typename PointInT, typename StateT> bool
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::initCompute ()
{
  if (!Tracker<PointInT, StateT>::initCompute ())
  {
    PCL_ERROR ("[pcl::%s::initCompute] Init failed.\n", getClassName ().c_str ());
    return (false);
  }

  coherence_->setTargetCloud (input_);

  if (!particles_ || particles_->points.empty ())
    initParticles ();
  return (true);
}

template <typename PointInT, typename StateT> double
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::calcLikelihood (const StateT &hypothesis)
{
  const Eigen::Affine3f trans = toEigenMatrix (hypothesis);
  PointCloudInPtr transed_reference = PointCloudInPtr (new PointCloudIn ());
  pcl::transformPointCloudWithNormals<PointInT> (*ref_, *transed_reference, trans);

  // search the nearest pairs
  std::vector<int> k_indices(1);
  std::vector<float> k_distances(1);
  int num_points = 0;
  IndicesPtr indices = IndicesPtr (new std::vector<int> ());
  for ( size_t i = 0; i < transed_reference->points.size (); i++ )
  {
    PointInT input_point = transed_reference->points[i];

    if (!pcl_isfinite(input_point.x) || !pcl_isfinite(input_point.y) || !pcl_isfinite(input_point.z))
      continue;
    // take occlusion into account
    Eigen::Vector4f p = input_point.getVector4fMap ();
    Eigen::Vector4f n = input_point.getNormalVector4fMap ();
    double theta = pcl::getAngle3D(p, n);

    // TODO: check NAN
    if ( theta > occlusion_angle_thr_ )
    {
      indices->push_back (i);
      ++num_points;
    }
  }

  //coherence_->setInputCloud (transed_reference);
  //coherence_->setIndices (indices);
  double val = coherence_->compute (transed_reference, indices);

  // take min_indices_ into account
  // TODO: normalization of likelihood is required?
  double likelihood;
  if ( num_points >= min_indices_ )
    likelihood = val / num_points;
  //likelihood = exp((((ret * ret ) / num) / (- 2.0 * sigma2)));
  else
    likelihood = 0.0;
  return likelihood;
}

template <typename PointInT, typename StateT> int
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::sampleWithReplacement
(const std::vector<int>& a, const std::vector<double>& q)
{
  using namespace boost;
  static mt19937 gen (static_cast<unsigned long>(time (0)));
  uniform_real<> dst (0.0, 1.0);
  variate_generator<mt19937&, uniform_real<> > rand (gen, dst);
  double rU = rand () * particle_num_;
  int k = (int)rU;
  rU -= k;    /* rU - [rU] */
  if ( rU < q[k] )
    return k;
  else
    return a[k];
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::genAliasTable (std::vector<int> &a, std::vector<double> &q)
{
  /* generate an alias table, a and q */
  std::vector<int> HL (particle_num_);
  std::vector<int>::iterator H = HL.begin ();
  std::vector<int>::iterator L = HL.end () - 1;
  for ( int i = 0; i < particle_num_; i++ )
    q[i] = particles_->points[i].weight * particle_num_;
  for ( int i = 0; i < particle_num_; i++ )
    a[i] = i;
  // setup H and L
  for ( int i = 0; i < particle_num_; i++ )
    if ( q[i] >= 1.0 )
      *H++ = i;
    else
      *L-- = i;

  while ( H != HL.begin() && L != HL.end() - 1 )
  {
    int j = *(L + 1);
    int k = *(H - 1);
    a[j] = k;
    q[k] += q[j] - 1;
    L++;
    if ( q[k] < 1.0 )
    {
      *L-- = k;
      --H;
    }
  }
}

template <typename PointInT, typename StateT> Eigen::Affine3f
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::toEigenMatrix (const StateT& particle)
{
  return particle.toEigenMatrix ();
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::initParticles ()
{
  PCL_INFO ("[pcl::%s::initParticles] initializing...\n", getClassName ().c_str ());
  particles_.reset (new PointCloudState ());

  representative_state_.zero ();
  representative_state_.weight = 0.0;

  std::vector<double> initial_noise_mean;
  StateT offset = StateT::toState (trans_);
  representative_state_ = offset;
  // sampling...
  for ( int i = 0; i < particle_num_; i++ )
  {
    StateT p;
    p.zero ();
    p.weight = 1.0 / particle_num_;
    p.sample (initial_noise_mean_, initial_noise_covariance_);
    p = p + offset;
    particles_->points.push_back (p); // update
  }
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::normalizeWeight ()
{
  double sum = 0.0;
  for ( int i = 0; i < particle_num_; i++ )
    sum += particles_->points[i].weight;
  for ( int i = 0; i < particle_num_; i++ )
    particles_->points[i].weight =  particles_->points[i].weight / sum;
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::weight ()
{
  coherence_->initCompute ();
  for ( int i = 0; i < particle_num_; i++ )
  {
    double likelihood = calcLikelihood (particles_->points[i]);
    particles_->points[i].weight = likelihood;
  }
  normalizeWeight ();
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::resample ()
{
  std::vector<int> a (particle_num_);
  std::vector<double> q (particle_num_);
  genAliasTable (a, q);

  const std::vector<double> zero_mean (StateT::stateDimension (), 0.0);
  // memoize the original list of particles
  //std::vector<Particle> origparticles = particles_;
  PointCloudStatePtr origparticles = particles_;
  particles_->points.clear ();
  // the first particle, it is a just copy of the maximum result
  StateT p = representative_state_;
  particles_->points.push_back (p);
  for ( int i = 1; i < particle_num_; i++ )
  {
    int target_particle_index = sampleWithReplacement (a, q);
    StateT p = origparticles->points[target_particle_index];
    // add noise using gaussian
    p.sample (zero_mean, step_noise_covariance_);
    particles_->points.push_back (p);
  }
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::update ()
{
  representative_state_.zero ();

  double maxweight = particles_->points[0].weight;
  int maxindex = 0;
  for ( int i = 1; i < particle_num_; i++)
  {
    StateT p = particles_->points[i];
    if (maxweight < p.weight )
    {
      maxweight = p.weight;
      maxindex = i;
    }
  }
  //if (representative_state_.weight < maxweight)
  representative_state_ = particles_->points[maxindex];
}

template <typename PointInT, typename StateT> void
pcl::tracking::ParticleFilterTracker<PointInT, StateT>::computeTracking ()
{

  for (int i = 0; i < iteration_num_; i++)
  {
    resample ();
    weight (); // likelihood is called in it
    update ();
  }

  if ( getResult ().weight < resample_likelihood_thr_ )
  {
    PCL_WARN ("too small likelihood, re-initializing...\n");
    initParticles ();
  }
}

#endif
<|endoftext|>


<commit_before>/***********************************************************************
	filename: 	CEGUIScrollablePaneProperties.cpp
	created:	3/3/2005
	author:		Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "elements/CEGUIScrollablePaneProperties.h"
#include "elements/CEGUIScrollablePane.h"
#include "CEGUIPropertyHelper.h"

// Start of CEGUI namespace section
namespace CEGUI
{
// Start of ScrollablePaneProperties namespace section
namespace ScrollablePaneProperties
{
    String ContentPaneAutoSized::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::boolToString(static_cast<const ScrollablePane*>(receiver)->isContentPaneAutoSized());
    }

    void ContentPaneAutoSized::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setContentPaneAutoSized(PropertyHelper::stringToBool(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String ContentArea::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::rectToString(static_cast<const ScrollablePane*>(receiver)->getContentPaneArea());
    }

    void ContentArea::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setContentPaneArea(PropertyHelper::stringToRect(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String ForceVertScrollbar::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::boolToString(static_cast<const ScrollablePane*>(receiver)->isVertScrollbarAlwaysShown());
    }

    void ForceVertScrollbar::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setShowVertScrollbar(PropertyHelper::stringToBool(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String ForceHorzScrollbar::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::boolToString(static_cast<const ScrollablePane*>(receiver)->isHorzScrollbarAlwaysShown());
    }

    void ForceHorzScrollbar::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setShowHorzScrollbar(PropertyHelper::stringToBool(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String HorzStepSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalStepSize());
    }

    void HorzStepSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setHorizontalStepSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String HorzOverlapSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalOverlapSize());
    }

    void HorzOverlapSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setHorizontalOverlapSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String HorzScrollPosition::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalScrollPosition());
    }

    void HorzScrollPosition::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setHorizontalScrollPosition(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String VertStepSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalStepSize());
    }

    void VertStepSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setVerticalStepSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String VertOverlapSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalOverlapSize());
    }

    void VertOverlapSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setVerticalOverlapSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String VertScrollPosition::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalScrollPosition());
    }

    void VertScrollPosition::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setVerticalScrollPosition(PropertyHelper::stringToFloat(value));
    }

} // End of  ScrollablePaneProperties namespace section
} // End of  CEGUI namespace section
<commit_msg>FIX: VertScrollbar ScrollablePane properties accessing values for horizontal bar.<commit_after>/***********************************************************************
	filename: 	CEGUIScrollablePaneProperties.cpp
	created:	3/3/2005
	author:		Paul D Turner
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "elements/CEGUIScrollablePaneProperties.h"
#include "elements/CEGUIScrollablePane.h"
#include "CEGUIPropertyHelper.h"

// Start of CEGUI namespace section
namespace CEGUI
{
// Start of ScrollablePaneProperties namespace section
namespace ScrollablePaneProperties
{
    String ContentPaneAutoSized::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::boolToString(static_cast<const ScrollablePane*>(receiver)->isContentPaneAutoSized());
    }

    void ContentPaneAutoSized::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setContentPaneAutoSized(PropertyHelper::stringToBool(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String ContentArea::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::rectToString(static_cast<const ScrollablePane*>(receiver)->getContentPaneArea());
    }

    void ContentArea::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setContentPaneArea(PropertyHelper::stringToRect(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String ForceVertScrollbar::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::boolToString(static_cast<const ScrollablePane*>(receiver)->isVertScrollbarAlwaysShown());
    }

    void ForceVertScrollbar::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setShowVertScrollbar(PropertyHelper::stringToBool(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String ForceHorzScrollbar::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::boolToString(static_cast<const ScrollablePane*>(receiver)->isHorzScrollbarAlwaysShown());
    }

    void ForceHorzScrollbar::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setShowHorzScrollbar(PropertyHelper::stringToBool(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String HorzStepSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalStepSize());
    }

    void HorzStepSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setHorizontalStepSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String HorzOverlapSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalOverlapSize());
    }

    void HorzOverlapSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setHorizontalOverlapSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String HorzScrollPosition::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getHorizontalScrollPosition());
    }

    void HorzScrollPosition::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setHorizontalScrollPosition(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String VertStepSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getVerticalStepSize());
    }

    void VertStepSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setVerticalStepSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String VertOverlapSize::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getVerticalOverlapSize());
    }

    void VertOverlapSize::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setVerticalOverlapSize(PropertyHelper::stringToFloat(value));
    }

    //////////////////////////////////////////////////////////////////////////

    String VertScrollPosition::get(const PropertyReceiver* receiver) const
    {
        return PropertyHelper::floatToString(static_cast<const ScrollablePane*>(receiver)->getVerticalScrollPosition());
    }

    void VertScrollPosition::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<ScrollablePane*>(receiver)->setVerticalScrollPosition(PropertyHelper::stringToFloat(value));
    }

} // End of  ScrollablePaneProperties namespace section
} // End of  CEGUI namespace section
<|endoftext|>


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

#include <cstdio>
#include <cstdlib>
#include <string>
#include <limits>
#include <algorithm>
#include <vector>
#include <unistd.h>

#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>

#include "vectormath.h"
#include "geometry.h"
#include "manipulator.h"

#include "drawable.h"
#include "builtin_loader.h"
#include "trisrc_loader.h"

//------------------------------------------------------------------------

static manipulator *gSceneManip;
static manipulator *gObjectManip;
static manipulator *gCurrentManip = NULL;

static bool gDrawWireframe = false;
static bool gStreamFrames = false;

static int gWindowWidth;
static int gWindowHeight;

static double gMotionReported = false;
static double gOldMouseX, gOldMouseY;
static int gButtonPressed = -1;

// XXX Allow these to be set by options
bool gVerbose = true;

std::vector<Drawable::sptr> gObjects;

float gFOV = 45;

void DrawScene()
{
    float nearClip, farClip;

    /* XXX - need to create new box from all subordinate boxes */
    nearClip = - gSceneManip->m_translation[2] - gSceneManip->m_reference_size;
    farClip = - gSceneManip->m_translation[2] + gSceneManip->m_reference_size;
    if(nearClip < 0.1 * gSceneManip->m_reference_size)
	nearClip = 0.1 * gSceneManip->m_reference_size;
    if(farClip < 0.2 * gSceneManip->m_reference_size)
	nearClip = 0.2 * gSceneManip->m_reference_size;

    float frustumLeft, frustumRight, frustumBottom, frustumTop;
    frustumTop = tanf(gFOV / 180.0 * 3.14159 / 2) * nearClip;
    frustumBottom = -frustumTop;
    frustumRight = frustumTop * gWindowWidth / gWindowHeight;
    frustumLeft = -frustumRight;

    Shader::sptr prevshader;
    for(auto it = gObjects.begin(); it != gObjects.end(); it++) {
        Drawable::sptr ob(*it);
        Shader::sptr shader = ob->GetShader();
        if(shader.get() != prevshader.get())
        {
            mat4f projection = mat4f::frustum(frustumLeft, frustumRight, frustumBottom, frustumTop, nearClip, farClip);
            glUniformMatrix4fv(shader->envu.projection, 1, GL_FALSE, projection.m_v);
            CheckOpenGL(__FILE__, __LINE__);

            float lightPosition[4] = {0, 0, 1, 0};
            float lightColor[4] = {1, 1, 1, 1};
            glUniform4fv(shader->envu.lightPosition, 1, lightPosition);
            glUniform4fv(shader->envu.lightColor, 1, lightColor);
            CheckOpenGL(__FILE__, __LINE__);

            /* draw floor, draw shadow, etc */

            // XXX same object matrix for all objects
            mat4f modelview = gObjectManip->m_matrix * gSceneManip->m_matrix;
            mat4f modelview_normal = modelview;
            // XXX should not invert every time; parallel normal matrix math path?
            modelview_normal.transpose();
            modelview_normal.invert();
            glUniformMatrix4fv(shader->envu.modelview, 1, GL_FALSE, modelview.m_v);
            glUniformMatrix4fv(shader->envu.modelviewNormal, 1, GL_FALSE, modelview_normal.m_v);

            prevshader = shader;
        }
        ob->Draw(0, gDrawWireframe);
    }
}

void InitializeGL()
{
    CheckOpenGL(__FILE__, __LINE__);
    glClearColor(.25, .25, .25, 0);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    CheckOpenGL(__FILE__, __LINE__);
}

void TeardownGL()
{
}

static void InitializeScene(std::vector<Drawable::sptr>& objects)
{
    box bounds;
    for(auto it = objects.begin(); it != objects.end(); it++) {
        Drawable::sptr ob(*it);

        bounds.extend(ob->bounds);
    }
    gSceneManip = new manipulator(bounds, gFOV / 180.0 * 3.14159);

    gObjectManip = new manipulator();
    gObjectManip->calculate_matrix();

    gCurrentManip = gSceneManip;
}

static void ErrorCallback(int error, const char* description)
{
    fprintf(stderr, "GLFW: %s\n", description);
}

static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
    if(action == GLFW_PRESS) {
        switch(key) {
            case 'W':
                gDrawWireframe = !gDrawWireframe;
                break;

            case 'R':
                gCurrentManip->m_mode = manipulator::ROTATE;
                break;

            case 'O':
                gCurrentManip->m_mode = manipulator::ROLL;
                break;

            case 'X':
                gCurrentManip->m_mode = manipulator::SCROLL;
                break;

            case 'Z':
                gCurrentManip->m_mode = manipulator::DOLLY;
                break;

            case '1':
                gCurrentManip = gSceneManip;
                break;

            case '2':
                gCurrentManip = gObjectManip;
                break;

            case 'Q': case '\033':
                glfwSetWindowShouldClose(window, GL_TRUE);
                break;
        }
    }
}

static void ResizeCallback(GLFWwindow *window, int x, int y)
{
    glfwGetFramebufferSize(window, &gWindowWidth, &gWindowHeight);
    glViewport(0, 0, gWindowWidth, gWindowHeight);
}

static void ButtonCallback(GLFWwindow *window, int b, int action, int mods)
{
    double x, y;
    glfwGetCursorPos(window, &x, &y);

    if(b == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
        gButtonPressed = 1;
	gOldMouseX = x;
	gOldMouseY = y;
    } else {
        gButtonPressed = -1;
    }
}

static void MotionCallback(GLFWwindow *window, double x, double y)
{
    // glfw/glfw#103
    // If no motion has been reported yet, we catch the first motion
    // reported and store the current location
    if(!gMotionReported) {
        gMotionReported = true;
        gOldMouseX = x;
        gOldMouseY = y;
    }

    double dx, dy;

    dx = x - gOldMouseX;
    dy = y - gOldMouseY;

    gOldMouseX = x;
    gOldMouseY = y;

    if(gButtonPressed == 1) {
        gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
        if(gCurrentManip == gSceneManip)
            gObjectManip->set_frame(gSceneManip->m_matrix);
    }
}

static void ScrollCallback(GLFWwindow *window, double dx, double dy)
{
    gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
    if(gCurrentManip == gSceneManip)
        gObjectManip->set_frame(gSceneManip->m_matrix);
}

static void DrawFrame(GLFWwindow *window)
{
    CheckOpenGL(__FILE__, __LINE__);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    CheckOpenGL(__FILE__, __LINE__);

    DrawScene();

    CheckOpenGL(__FILE__, __LINE__);
}

bool LoadScene(const std::string& filename, std::vector<Drawable::sptr>& objects)
{
    int index = filename.find_last_of(".");
    std::string extension = filename.substr(index + 1);

    if(extension == "builtin") {
        return BuiltinLoader::Load(filename, objects);
    // } else if(extension == "trisrc") {
        // return TriSrcLoader::Load(filename, objects);
    } else {
        return false;
    }
}

int main(int argc, char **argv)
{
    const char *progname = argv[0];
    if(argc < 2) {
        fprintf(stderr, "usage: %s filename # e.g. \"%s 64gon.builtin\"\n", progname, progname);
        exit(EXIT_FAILURE);
    }

    const char *scene_filename = argv[1];

    GLFWwindow* window;

    glfwSetErrorCallback(ErrorCallback);

    if(!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwWindowHint(GLFW_SAMPLES, 4);
    window = glfwCreateWindow(gWindowWidth = 512, gWindowHeight = 512, "Spin", NULL, NULL);
    if (!window) {
        glfwTerminate();
        fprintf(stdout, "Couldn't open main window\n");
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);

    InitializeGL();
    if(!LoadScene(scene_filename, gObjects)) {
        fprintf(stderr, "couldn't load scene from %s\n", scene_filename);
        exit(EXIT_FAILURE);
    }
    InitializeScene(gObjects);

    if(gVerbose) {
        printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
        printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    }

    glfwSetKeyCallback(window, KeyCallback);
    glfwSetMouseButtonCallback(window, ButtonCallback);
    glfwSetCursorPosCallback(window, MotionCallback);
    glfwSetScrollCallback(window, ScrollCallback);
    glfwSetFramebufferSizeCallback(window, ResizeCallback);
    glfwSetWindowRefreshCallback(window, DrawFrame);

    while (!glfwWindowShouldClose(window)) {

        DrawFrame(window);

        glfwSwapBuffers(window);

        if(gStreamFrames)
            glfwPollEvents();
        else
            glfwWaitEvents();
    }

    glfwTerminate();
}
<commit_msg>comment out trisrc loader so trunk will compile<commit_after>//
// Copyright 2013-2014, Bradley A. Grantham
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <cstdio>
#include <cstdlib>
#include <string>
#include <limits>
#include <algorithm>
#include <vector>
#include <unistd.h>

#define GLFW_INCLUDE_GLCOREARB
#include <GLFW/glfw3.h>

#include "vectormath.h"
#include "geometry.h"
#include "manipulator.h"

#include "drawable.h"
#include "builtin_loader.h"
// #include "trisrc_loader.h"

//------------------------------------------------------------------------

static manipulator *gSceneManip;
static manipulator *gObjectManip;
static manipulator *gCurrentManip = NULL;

static bool gDrawWireframe = false;
static bool gStreamFrames = false;

static int gWindowWidth;
static int gWindowHeight;

static double gMotionReported = false;
static double gOldMouseX, gOldMouseY;
static int gButtonPressed = -1;

// XXX Allow these to be set by options
bool gVerbose = true;

std::vector<Drawable::sptr> gObjects;

float gFOV = 45;

void DrawScene()
{
    float nearClip, farClip;

    /* XXX - need to create new box from all subordinate boxes */
    nearClip = - gSceneManip->m_translation[2] - gSceneManip->m_reference_size;
    farClip = - gSceneManip->m_translation[2] + gSceneManip->m_reference_size;
    if(nearClip < 0.1 * gSceneManip->m_reference_size)
	nearClip = 0.1 * gSceneManip->m_reference_size;
    if(farClip < 0.2 * gSceneManip->m_reference_size)
	nearClip = 0.2 * gSceneManip->m_reference_size;

    float frustumLeft, frustumRight, frustumBottom, frustumTop;
    frustumTop = tanf(gFOV / 180.0 * 3.14159 / 2) * nearClip;
    frustumBottom = -frustumTop;
    frustumRight = frustumTop * gWindowWidth / gWindowHeight;
    frustumLeft = -frustumRight;

    Shader::sptr prevshader;
    for(auto it = gObjects.begin(); it != gObjects.end(); it++) {
        Drawable::sptr ob(*it);
        Shader::sptr shader = ob->GetShader();
        if(shader.get() != prevshader.get())
        {
            mat4f projection = mat4f::frustum(frustumLeft, frustumRight, frustumBottom, frustumTop, nearClip, farClip);
            glUniformMatrix4fv(shader->envu.projection, 1, GL_FALSE, projection.m_v);
            CheckOpenGL(__FILE__, __LINE__);

            float lightPosition[4] = {0, 0, 1, 0};
            float lightColor[4] = {1, 1, 1, 1};
            glUniform4fv(shader->envu.lightPosition, 1, lightPosition);
            glUniform4fv(shader->envu.lightColor, 1, lightColor);
            CheckOpenGL(__FILE__, __LINE__);

            /* draw floor, draw shadow, etc */

            // XXX same object matrix for all objects
            mat4f modelview = gObjectManip->m_matrix * gSceneManip->m_matrix;
            mat4f modelview_normal = modelview;
            // XXX should not invert every time; parallel normal matrix math path?
            modelview_normal.transpose();
            modelview_normal.invert();
            glUniformMatrix4fv(shader->envu.modelview, 1, GL_FALSE, modelview.m_v);
            glUniformMatrix4fv(shader->envu.modelviewNormal, 1, GL_FALSE, modelview_normal.m_v);

            prevshader = shader;
        }
        ob->Draw(0, gDrawWireframe);
    }
}

void InitializeGL()
{
    CheckOpenGL(__FILE__, __LINE__);
    glClearColor(.25, .25, .25, 0);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    CheckOpenGL(__FILE__, __LINE__);
}

void TeardownGL()
{
}

static void InitializeScene(std::vector<Drawable::sptr>& objects)
{
    box bounds;
    for(auto it = objects.begin(); it != objects.end(); it++) {
        Drawable::sptr ob(*it);

        bounds.extend(ob->bounds);
    }
    gSceneManip = new manipulator(bounds, gFOV / 180.0 * 3.14159);

    gObjectManip = new manipulator();
    gObjectManip->calculate_matrix();

    gCurrentManip = gSceneManip;
}

static void ErrorCallback(int error, const char* description)
{
    fprintf(stderr, "GLFW: %s\n", description);
}

static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods)
{
    if(action == GLFW_PRESS) {
        switch(key) {
            case 'W':
                gDrawWireframe = !gDrawWireframe;
                break;

            case 'R':
                gCurrentManip->m_mode = manipulator::ROTATE;
                break;

            case 'O':
                gCurrentManip->m_mode = manipulator::ROLL;
                break;

            case 'X':
                gCurrentManip->m_mode = manipulator::SCROLL;
                break;

            case 'Z':
                gCurrentManip->m_mode = manipulator::DOLLY;
                break;

            case '1':
                gCurrentManip = gSceneManip;
                break;

            case '2':
                gCurrentManip = gObjectManip;
                break;

            case 'Q': case '\033':
                glfwSetWindowShouldClose(window, GL_TRUE);
                break;
        }
    }
}

static void ResizeCallback(GLFWwindow *window, int x, int y)
{
    glfwGetFramebufferSize(window, &gWindowWidth, &gWindowHeight);
    glViewport(0, 0, gWindowWidth, gWindowHeight);
}

static void ButtonCallback(GLFWwindow *window, int b, int action, int mods)
{
    double x, y;
    glfwGetCursorPos(window, &x, &y);

    if(b == GLFW_MOUSE_BUTTON_1 && action == GLFW_PRESS) {
        gButtonPressed = 1;
	gOldMouseX = x;
	gOldMouseY = y;
    } else {
        gButtonPressed = -1;
    }
}

static void MotionCallback(GLFWwindow *window, double x, double y)
{
    // glfw/glfw#103
    // If no motion has been reported yet, we catch the first motion
    // reported and store the current location
    if(!gMotionReported) {
        gMotionReported = true;
        gOldMouseX = x;
        gOldMouseY = y;
    }

    double dx, dy;

    dx = x - gOldMouseX;
    dy = y - gOldMouseY;

    gOldMouseX = x;
    gOldMouseY = y;

    if(gButtonPressed == 1) {
        gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
        if(gCurrentManip == gSceneManip)
            gObjectManip->set_frame(gSceneManip->m_matrix);
    }
}

static void ScrollCallback(GLFWwindow *window, double dx, double dy)
{
    gCurrentManip->move(dx / gWindowWidth, dy / gWindowHeight);
    if(gCurrentManip == gSceneManip)
        gObjectManip->set_frame(gSceneManip->m_matrix);
}

static void DrawFrame(GLFWwindow *window)
{
    CheckOpenGL(__FILE__, __LINE__);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    CheckOpenGL(__FILE__, __LINE__);

    DrawScene();

    CheckOpenGL(__FILE__, __LINE__);
}

bool LoadScene(const std::string& filename, std::vector<Drawable::sptr>& objects)
{
    int index = filename.find_last_of(".");
    std::string extension = filename.substr(index + 1);

    if(extension == "builtin") {
        return BuiltinLoader::Load(filename, objects);
    // } else if(extension == "trisrc") {
        // return TriSrcLoader::Load(filename, objects);
    } else {
        return false;
    }
}

int main(int argc, char **argv)
{
    const char *progname = argv[0];
    if(argc < 2) {
        fprintf(stderr, "usage: %s filename # e.g. \"%s 64gon.builtin\"\n", progname, progname);
        exit(EXIT_FAILURE);
    }

    const char *scene_filename = argv[1];

    GLFWwindow* window;

    glfwSetErrorCallback(ErrorCallback);

    if(!glfwInit())
        exit(EXIT_FAILURE);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    glfwWindowHint(GLFW_SAMPLES, 4);
    window = glfwCreateWindow(gWindowWidth = 512, gWindowHeight = 512, "Spin", NULL, NULL);
    if (!window) {
        glfwTerminate();
        fprintf(stdout, "Couldn't open main window\n");
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window);

    InitializeGL();
    if(!LoadScene(scene_filename, gObjects)) {
        fprintf(stderr, "couldn't load scene from %s\n", scene_filename);
        exit(EXIT_FAILURE);
    }
    InitializeScene(gObjects);

    if(gVerbose) {
        printf("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
        printf("GL_VERSION: %s\n", glGetString(GL_VERSION));
    }

    glfwSetKeyCallback(window, KeyCallback);
    glfwSetMouseButtonCallback(window, ButtonCallback);
    glfwSetCursorPosCallback(window, MotionCallback);
    glfwSetScrollCallback(window, ScrollCallback);
    glfwSetFramebufferSizeCallback(window, ResizeCallback);
    glfwSetWindowRefreshCallback(window, DrawFrame);

    while (!glfwWindowShouldClose(window)) {

        DrawFrame(window);

        glfwSwapBuffers(window);

        if(gStreamFrames)
            glfwPollEvents();
        else
            glfwWaitEvents();
    }

    glfwTerminate();
}
<|endoftext|>