<commit_before>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2013-10-17 GONG Chen <chen.sst@gmail.com>
//

#include <rime_api.h>
#include <rime_levers_api.h>
#include <rime/common.h>
#include <rime/registry.h>
#include <rime/service.h>

#include <rime/lever/custom_settings.h>
#include <rime/lever/deployment_tasks.h>
#include <rime/lever/switcher_settings.h>
#include <rime/lever/user_dict_manager.h>

static void rime_levers_initialize() {
  using namespace rime;

  LOG(INFO) << "registering components from module 'levers'.";
  Registry& r = Registry::instance();

  // deployment tools
  r.Register("installation_update", new Component<InstallationUpdate>);
  r.Register("workspace_update", new Component<WorkspaceUpdate>);
  r.Register("schema_update", new Component<SchemaUpdate>);
  r.Register("config_file_update", new Component<ConfigFileUpdate>);
  r.Register("prebuild_all_schemas", new Component<PrebuildAllSchemas>);
  r.Register("user_dict_upgrade", new Component<UserDictUpgrade>);
  r.Register("cleanup_trash", new Component<CleanupTrash>);
  r.Register("user_dict_sync", new Component<UserDictSync>);
  r.Register("backup_config_files", new Component<BackupConfigFiles>);
  r.Register("clean_old_log_files", new Component<CleanOldLogFiles>);
}

static void rime_levers_finalize() {
}

// implementation of levers api

static RimeCustomSettings*
rime_levers_custom_settings_init(const char* config_id,
                                 const char* generator_id) {
  return reinterpret_cast<RimeCustomSettings*>(
      new rime::CustomSettings(&rime::Service::instance().deployer(),
                               config_id, generator_id));
}

static void rime_levers_custom_settings_destroy(RimeCustomSettings* settings) {
  delete reinterpret_cast<rime::CustomSettings*>(settings);
}

static Bool rime_levers_load_settings(RimeCustomSettings* settings) {
  return Bool(reinterpret_cast<rime::CustomSettings*>(settings)->Load());
}

static Bool rime_levers_save_settings(RimeCustomSettings* settings) {
  return Bool(reinterpret_cast<rime::CustomSettings*>(settings)->Save());
}

static Bool rime_levers_customize_bool(RimeCustomSettings* settings,
                                       const char* key, bool value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_int(RimeCustomSettings* settings,
                                      const char* key, int value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_double(RimeCustomSettings* settings,
                                         const char* key, double value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_string(RimeCustomSettings* settings,
                                         const char* key, const char* value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_item(RimeCustomSettings* settings,
                                       const char* key, RimeConfig* value) {
  rime::ConfigItemPtr item;
  if (value) {
    if (rime::Config* v = reinterpret_cast<rime::Config*>(value->ptr)) {
      item = v->GetItem("");
    }
  }
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_is_first_run(RimeCustomSettings* settings) {
  return reinterpret_cast<rime::CustomSettings*>(settings)->IsFirstRun();
}

static Bool rime_levers_settings_is_modified(RimeCustomSettings* settings) {
  return reinterpret_cast<rime::CustomSettings*>(settings)->modified();
}

static Bool rime_levers_settings_get_config(RimeCustomSettings* settings,
                                            RimeConfig* config) {
  if (!config)
    return False;
  config->ptr = reinterpret_cast<rime::CustomSettings*>(settings)->config();
  return Bool(!!config->ptr);
}

static RimeSwitcherSettings* rime_levers_switcher_settings_init() {
  return reinterpret_cast<RimeSwitcherSettings*>(
      new rime::SwitcherSettings(&rime::Service::instance().deployer()));
}

static Bool
rime_levers_get_available_schema_list(RimeSwitcherSettings* settings,
                                      RimeSchemaList* list) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  list->size = 0;
  list->list = NULL;
  if (ss->available().empty()) {
    return False;
  }
  list->list = new RimeSchemaListItem[ss->available().size()];
  for (const auto& info : ss->available()) {
    auto& item(list->list[list->size]);
    item.schema_id = const_cast<char*>(info.schema_id.c_str());
    item.name = const_cast<char*>(info.name.c_str());
    item.reserved = const_cast<rime::SchemaInfo*>(&info);
    ++list->size;
  }
  return True;
}

static Bool
rime_levers_get_selected_schema_list(RimeSwitcherSettings* settings,
                                     RimeSchemaList* list) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  list->size = 0;
  list->list = NULL;
  if (ss->selection().empty()) {
    return False;
  }
  list->list = new RimeSchemaListItem[ss->selection().size()];
  for (const std::string& schema_id : ss->selection()) {
    auto& item(list->list[list->size]);
    item.schema_id = const_cast<char*>(schema_id.c_str());
    ++list->size;
  }
  return True;
}

static void rime_levers_schema_list_destroy(RimeSchemaList* list) {
  delete[] list->list;
  list->size = 0;
  list->list = NULL;
}

static const char* rime_levers_get_schema_id(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->schema_id.empty() ? si->schema_id.c_str() : NULL;
}

static const char* rime_levers_get_schema_name(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->name.empty() ? si->name.c_str() : NULL;
}

static const char* rime_levers_get_schema_version(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->version.empty() ? si->version.c_str() : NULL;
}
static const char* rime_levers_get_schema_author(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->author.empty() ? si->author.c_str() : NULL;
}

static const char* rime_levers_get_schema_description(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->description.empty() ? si->description.c_str() : NULL;
}

static const char* rime_levers_get_schema_file_path(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->file_path.empty() ? si->file_path.c_str() : NULL;
}

static Bool rime_levers_select_schemas(RimeSwitcherSettings* settings,
                                       const char* schema_id_list[],
                                       int count) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  rime::SwitcherSettings::Selection selection;
  for (int i = 0; i < count; ++i) {
    selection.push_back(schema_id_list[i]);
  }
  return ss->Select(selection);
}

static const char* rime_levers_get_hotkeys(RimeSwitcherSettings* settings) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  return !ss->hotkeys().empty() ? ss->hotkeys().c_str() : NULL;
}

static Bool rime_levers_set_hotkeys(RimeSwitcherSettings* settings,
                                    const char* hotkeys) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  return Bool(ss->SetHotkeys(hotkeys));
}

static Bool rime_levers_user_dict_iterator_init(RimeUserDictIterator* iter) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  rime::UserDictList* list = new rime::UserDictList;
  mgr.GetUserDictList(list);
  if (list->empty()) {
    delete list;
    return False;
  }
  iter->ptr = list;
  iter->i = 0;
  return True;
}

static void rime_levers_user_dict_iterator_destroy(RimeUserDictIterator* iter) {
  delete (rime::UserDictList*)iter->ptr;
  iter->ptr = NULL;
  iter->i = 0;
}

static const char* rime_levers_next_user_dict(RimeUserDictIterator* iter) {
  auto list = reinterpret_cast<rime::UserDictList*>(iter->ptr);
  if (!list || iter->i >= list->size()) {
    return NULL;
  }
  return (*list)[iter->i++].c_str();
}

static Bool rime_levers_backup_user_dict(const char* dict_name) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return Bool(mgr.Backup(dict_name));
}

static Bool rime_levers_restore_user_dict(const char* snapshot_file) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return Bool(mgr.Restore(snapshot_file));
}

static int rime_levers_export_user_dict(const char* dict_name,
                                        const char* text_file) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return mgr.Export(dict_name, text_file);
}

static int rime_levers_import_user_dict(const char* dict_name,
                                        const char* text_file) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return mgr.Import(dict_name, text_file);
}

//

static RimeCustomApi* rime_levers_get_api() {
  static RimeLeversApi s_api = {0};
  if (!s_api.data_size) {
    RIME_STRUCT_INIT(RimeLeversApi, s_api);
    s_api.custom_settings_init = rime_levers_custom_settings_init;
    s_api.custom_settings_destroy = rime_levers_custom_settings_destroy;
    s_api.load_settings = rime_levers_load_settings;
    s_api.save_settings = rime_levers_save_settings;
    s_api.customize_bool = rime_levers_customize_bool;
    s_api.customize_int = rime_levers_customize_int;
    s_api.customize_double = rime_levers_customize_double;
    s_api.customize_string = rime_levers_customize_string;
    s_api.is_first_run = rime_levers_is_first_run;
    s_api.settings_is_modified = rime_levers_settings_is_modified;
    s_api.settings_get_config = rime_levers_settings_get_config;
    s_api.switcher_settings_init = rime_levers_switcher_settings_init;
    s_api.get_available_schema_list = rime_levers_get_available_schema_list;
    s_api.get_selected_schema_list = rime_levers_get_selected_schema_list;
    s_api.schema_list_destroy = rime_levers_schema_list_destroy;
    s_api.get_schema_id = rime_levers_get_schema_id;
    s_api.get_schema_name = rime_levers_get_schema_name;
    s_api.get_schema_version = rime_levers_get_schema_version;
    s_api.get_schema_author = rime_levers_get_schema_author;
    s_api.get_schema_description = rime_levers_get_schema_description;
    s_api.get_schema_file_path = rime_levers_get_schema_file_path;
    s_api.select_schemas = rime_levers_select_schemas;
    s_api.get_hotkeys = rime_levers_get_hotkeys;
    s_api.set_hotkeys = rime_levers_set_hotkeys;
    s_api.user_dict_iterator_init = rime_levers_user_dict_iterator_init;
    s_api.user_dict_iterator_destroy = rime_levers_user_dict_iterator_destroy;
    s_api.next_user_dict = rime_levers_next_user_dict;
    s_api.backup_user_dict = rime_levers_backup_user_dict;
    s_api.restore_user_dict = rime_levers_restore_user_dict;
    s_api.export_user_dict = rime_levers_export_user_dict;
    s_api.import_user_dict = rime_levers_import_user_dict;
    s_api.customize_item = rime_levers_customize_item;
  }
  return (RimeCustomApi*)&s_api;
}

RIME_REGISTER_CUSTOM_MODULE(levers) {
  module->get_api = rime_levers_get_api;
}
<commit_msg>fix dangling pointers in RimeSchemaListItem<commit_after>//
// Copyright RIME Developers
// Distributed under the BSD License
//
// 2013-10-17 GONG Chen <chen.sst@gmail.com>
//

#include <rime_api.h>
#include <rime_levers_api.h>
#include <rime/common.h>
#include <rime/registry.h>
#include <rime/service.h>

#include <rime/lever/custom_settings.h>
#include <rime/lever/deployment_tasks.h>
#include <rime/lever/switcher_settings.h>
#include <rime/lever/user_dict_manager.h>

static void rime_levers_initialize() {
  using namespace rime;

  LOG(INFO) << "registering components from module 'levers'.";
  Registry& r = Registry::instance();

  // deployment tools
  r.Register("installation_update", new Component<InstallationUpdate>);
  r.Register("workspace_update", new Component<WorkspaceUpdate>);
  r.Register("schema_update", new Component<SchemaUpdate>);
  r.Register("config_file_update", new Component<ConfigFileUpdate>);
  r.Register("prebuild_all_schemas", new Component<PrebuildAllSchemas>);
  r.Register("user_dict_upgrade", new Component<UserDictUpgrade>);
  r.Register("cleanup_trash", new Component<CleanupTrash>);
  r.Register("user_dict_sync", new Component<UserDictSync>);
  r.Register("backup_config_files", new Component<BackupConfigFiles>);
  r.Register("clean_old_log_files", new Component<CleanOldLogFiles>);
}

static void rime_levers_finalize() {
}

// implementation of levers api

static RimeCustomSettings*
rime_levers_custom_settings_init(const char* config_id,
                                 const char* generator_id) {
  return reinterpret_cast<RimeCustomSettings*>(
      new rime::CustomSettings(&rime::Service::instance().deployer(),
                               config_id, generator_id));
}

static void rime_levers_custom_settings_destroy(RimeCustomSettings* settings) {
  delete reinterpret_cast<rime::CustomSettings*>(settings);
}

static Bool rime_levers_load_settings(RimeCustomSettings* settings) {
  return Bool(reinterpret_cast<rime::CustomSettings*>(settings)->Load());
}

static Bool rime_levers_save_settings(RimeCustomSettings* settings) {
  return Bool(reinterpret_cast<rime::CustomSettings*>(settings)->Save());
}

static Bool rime_levers_customize_bool(RimeCustomSettings* settings,
                                       const char* key, bool value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_int(RimeCustomSettings* settings,
                                      const char* key, int value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_double(RimeCustomSettings* settings,
                                         const char* key, double value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_string(RimeCustomSettings* settings,
                                         const char* key, const char* value) {
  rime::ConfigItemPtr item = rime::New<rime::ConfigValue>(value);
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_customize_item(RimeCustomSettings* settings,
                                       const char* key, RimeConfig* value) {
  rime::ConfigItemPtr item;
  if (value) {
    if (rime::Config* v = reinterpret_cast<rime::Config*>(value->ptr)) {
      item = v->GetItem("");
    }
  }
  auto custom_settings = reinterpret_cast<rime::CustomSettings*>(settings);
  return custom_settings->Customize(key, item);
}

static Bool rime_levers_is_first_run(RimeCustomSettings* settings) {
  return reinterpret_cast<rime::CustomSettings*>(settings)->IsFirstRun();
}

static Bool rime_levers_settings_is_modified(RimeCustomSettings* settings) {
  return reinterpret_cast<rime::CustomSettings*>(settings)->modified();
}

static Bool rime_levers_settings_get_config(RimeCustomSettings* settings,
                                            RimeConfig* config) {
  if (!config)
    return False;
  config->ptr = reinterpret_cast<rime::CustomSettings*>(settings)->config();
  return Bool(!!config->ptr);
}

static RimeSwitcherSettings* rime_levers_switcher_settings_init() {
  return reinterpret_cast<RimeSwitcherSettings*>(
      new rime::SwitcherSettings(&rime::Service::instance().deployer()));
}

static Bool
rime_levers_get_available_schema_list(RimeSwitcherSettings* settings,
                                      RimeSchemaList* list) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  list->size = 0;
  list->list = NULL;
  if (ss->available().empty()) {
    return False;
  }
  list->list = new RimeSchemaListItem[ss->available().size()];
  for (const auto& info : ss->available()) {
    auto& item(list->list[list->size]);
    item.schema_id = const_cast<char*>(info.schema_id.c_str());
    item.name = const_cast<char*>(info.name.c_str());
    item.reserved = const_cast<rime::SchemaInfo*>(&info);
    ++list->size;
  }
  return True;
}

static Bool
rime_levers_get_selected_schema_list(RimeSwitcherSettings* settings,
                                     RimeSchemaList* list) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  list->size = 0;
  list->list = NULL;
  if (ss->selection().empty()) {
    return False;
  }
  list->list = new RimeSchemaListItem[ss->selection().size()];
  for (const std::string& schema_id : ss->selection()) {
    auto& item(list->list[list->size]);
    item.schema_id = const_cast<char*>(schema_id.c_str());
    item.name = NULL;
    item.reserved = NULL;
    ++list->size;
  }
  return True;
}

static void rime_levers_schema_list_destroy(RimeSchemaList* list) {
  delete[] list->list;
  list->size = 0;
  list->list = NULL;
}

static const char* rime_levers_get_schema_id(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->schema_id.empty() ? si->schema_id.c_str() : NULL;
}

static const char* rime_levers_get_schema_name(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->name.empty() ? si->name.c_str() : NULL;
}

static const char* rime_levers_get_schema_version(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->version.empty() ? si->version.c_str() : NULL;
}
static const char* rime_levers_get_schema_author(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->author.empty() ? si->author.c_str() : NULL;
}

static const char* rime_levers_get_schema_description(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->description.empty() ? si->description.c_str() : NULL;
}

static const char* rime_levers_get_schema_file_path(RimeSchemaInfo* info) {
  auto si = reinterpret_cast<rime::SchemaInfo*>(info);
  return si && !si->file_path.empty() ? si->file_path.c_str() : NULL;
}

static Bool rime_levers_select_schemas(RimeSwitcherSettings* settings,
                                       const char* schema_id_list[],
                                       int count) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  rime::SwitcherSettings::Selection selection;
  for (int i = 0; i < count; ++i) {
    selection.push_back(schema_id_list[i]);
  }
  return ss->Select(selection);
}

static const char* rime_levers_get_hotkeys(RimeSwitcherSettings* settings) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  return !ss->hotkeys().empty() ? ss->hotkeys().c_str() : NULL;
}

static Bool rime_levers_set_hotkeys(RimeSwitcherSettings* settings,
                                    const char* hotkeys) {
  auto ss = reinterpret_cast<rime::SwitcherSettings*>(settings);
  return Bool(ss->SetHotkeys(hotkeys));
}

static Bool rime_levers_user_dict_iterator_init(RimeUserDictIterator* iter) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  rime::UserDictList* list = new rime::UserDictList;
  mgr.GetUserDictList(list);
  if (list->empty()) {
    delete list;
    return False;
  }
  iter->ptr = list;
  iter->i = 0;
  return True;
}

static void rime_levers_user_dict_iterator_destroy(RimeUserDictIterator* iter) {
  delete (rime::UserDictList*)iter->ptr;
  iter->ptr = NULL;
  iter->i = 0;
}

static const char* rime_levers_next_user_dict(RimeUserDictIterator* iter) {
  auto list = reinterpret_cast<rime::UserDictList*>(iter->ptr);
  if (!list || iter->i >= list->size()) {
    return NULL;
  }
  return (*list)[iter->i++].c_str();
}

static Bool rime_levers_backup_user_dict(const char* dict_name) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return Bool(mgr.Backup(dict_name));
}

static Bool rime_levers_restore_user_dict(const char* snapshot_file) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return Bool(mgr.Restore(snapshot_file));
}

static int rime_levers_export_user_dict(const char* dict_name,
                                        const char* text_file) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return mgr.Export(dict_name, text_file);
}

static int rime_levers_import_user_dict(const char* dict_name,
                                        const char* text_file) {
  rime::UserDictManager mgr(&rime::Service::instance().deployer());
  return mgr.Import(dict_name, text_file);
}

//

static RimeCustomApi* rime_levers_get_api() {
  static RimeLeversApi s_api = {0};
  if (!s_api.data_size) {
    RIME_STRUCT_INIT(RimeLeversApi, s_api);
    s_api.custom_settings_init = rime_levers_custom_settings_init;
    s_api.custom_settings_destroy = rime_levers_custom_settings_destroy;
    s_api.load_settings = rime_levers_load_settings;
    s_api.save_settings = rime_levers_save_settings;
    s_api.customize_bool = rime_levers_customize_bool;
    s_api.customize_int = rime_levers_customize_int;
    s_api.customize_double = rime_levers_customize_double;
    s_api.customize_string = rime_levers_customize_string;
    s_api.is_first_run = rime_levers_is_first_run;
    s_api.settings_is_modified = rime_levers_settings_is_modified;
    s_api.settings_get_config = rime_levers_settings_get_config;
    s_api.switcher_settings_init = rime_levers_switcher_settings_init;
    s_api.get_available_schema_list = rime_levers_get_available_schema_list;
    s_api.get_selected_schema_list = rime_levers_get_selected_schema_list;
    s_api.schema_list_destroy = rime_levers_schema_list_destroy;
    s_api.get_schema_id = rime_levers_get_schema_id;
    s_api.get_schema_name = rime_levers_get_schema_name;
    s_api.get_schema_version = rime_levers_get_schema_version;
    s_api.get_schema_author = rime_levers_get_schema_author;
    s_api.get_schema_description = rime_levers_get_schema_description;
    s_api.get_schema_file_path = rime_levers_get_schema_file_path;
    s_api.select_schemas = rime_levers_select_schemas;
    s_api.get_hotkeys = rime_levers_get_hotkeys;
    s_api.set_hotkeys = rime_levers_set_hotkeys;
    s_api.user_dict_iterator_init = rime_levers_user_dict_iterator_init;
    s_api.user_dict_iterator_destroy = rime_levers_user_dict_iterator_destroy;
    s_api.next_user_dict = rime_levers_next_user_dict;
    s_api.backup_user_dict = rime_levers_backup_user_dict;
    s_api.restore_user_dict = rime_levers_restore_user_dict;
    s_api.export_user_dict = rime_levers_export_user_dict;
    s_api.import_user_dict = rime_levers_import_user_dict;
    s_api.customize_item = rime_levers_customize_item;
  }
  return (RimeCustomApi*)&s_api;
}

RIME_REGISTER_CUSTOM_MODULE(levers) {
  module->get_api = rime_levers_get_api;
}
<|endoftext|>


<commit_before>#include "DecisionGenerator.h"

#include "Game.h"
#include <memory>
#include "EndGameState.h"

DecisionGenerator::DecisionGenerator(Game* game) : game(game)
{

    decisions.emplace_back(
        "Advance the front!", "Seem like it wasnt the best option", 0, 20, 2, &game->textures.acquire("AdvanceTheFront", thor::ResourceLoader<sf::Texture>(thor::Resources::fromFile<sf::Texture>("assets/AdvanceTheFront.png"))), [](Game* game, Player* player) -> void
    {
        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);

    }
    );

    decisions.emplace_back(
        "Stay defensive!", "It kind of scary to stay back while the enemy go forward", 0, 10, 2, &game->textures.acquire("HoldTheLine", thor::ResourceLoader<sf::Texture>(thor::Resources::fromFile<sf::Texture>("assets/HoldTheLine.png"))), [](Game* game, Player*)
    {

    }
    );

    decisions.emplace_back(
        "End the war...", "Well that's sad", 3, 30, 3, &game->textures.acquire("EndTheWar", thor::ResourceLoader<sf::Texture>(thor::Resources::fromFile<sf::Texture>("assets/EndTheWar.png"))), [](Game* game, Player* player)
    {
        auto sp = std::make_shared<sf::RenderTexture>();
        sp->create(game->window.getSize().x, game->window.getSize().y);
        game->activeState->render(*sp.get());
        sp->display();
        game->nextState = std::make_shared<EndGameState>(game, sp);
    }
    );

    updateDangerLevel(0);

}

#include "MathHelper.h"

Decision DecisionGenerator::getDecision(int dangerLevel, Decision* filter)
{
	float totalPropability = 0;

	for (auto& it : eligable) {
		if (filter != nullptr && *filter == it)
			continue;

		totalPropability += it.probability;
	}

	float result = math::rand(totalPropability);
	float currentProb = 0;

	for (auto &it : eligable) {
		currentProb += it.probability;
		if (result <= currentProb) {
			if (filter != nullptr) {
				if (*filter == it && it.message != "End the war...") // #Bodged
					continue;
			}

			return it;
		}
	}

	throw "Nyrox is an idiot exception";
}

void DecisionGenerator::updateDangerLevel(int level)
{

	// remove decisions from the array that are too advanced
	for (auto it = eligable.begin(); it != eligable.end(); it++) {
		if (it->maxDangerLevel < level) {
			it = eligable.erase(it);
		}
		if (it == eligable.end())
			break;
	}

    eligable.clear();

    // add decisions to the array that are now eligable
    for (auto it = decisions.begin(); it != decisions.end(); it++)
    {
        if (it->minDangerLevel <= level && it->maxDangerLevel >= level)
        {
            for(int x = 0 ; x < it->probability; x++)
                eligable.push_back(*it);
        }
    }
}
<commit_msg>more decisions<commit_after>#include "DecisionGenerator.h"

#include "Game.h"
#include <memory>
#include "EndGameState.h"

DecisionGenerator::DecisionGenerator(Game* game) : game(game)
{

#define addTexture(textureName) game->textures.acquire(textureName, thor::Resources::fromFile<sf::Texture>("assets/" + std::string(textureName) + ".png"));

    addTexture("AdvanceTheFront");
    addTexture("HoldTheLine");
    addTexture("EndTheWar");

#define addDecision(Text, Effect, min, max, prob, textureName, lambda) decisions.emplace_back(Text, Effect, min, max, prob, &game->textures[textureName], lambda);

    addDecision("Become More Aggressive", "The Military Council approve", 0, 2, 2, "AdvanceTheFront", [](Game* game, Player* player) -> void
    {
        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);
    });

    addDecision("Stay defensive", "It kind of scary to stay back while the enemy go forward", 0, 2, 4, "HoldTheLine", [](Game* game, Player* player)
    {

    });

    addDecision("Recruit More Units", "The Population do not really understand your choices", 0, 2, 2, "HoldTheLine", [](Game* game, Player* player)
    {
        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);
        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);
        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);        dynamic_cast<MainGameState*>(game->activeState.get())->map.spawnUnit(Unit(game, player), player->side);
    });

    addDecision("Send Spy", "Why would you spy? is there not enough dead already?", 0, 2, 2, "HoldTheLine", [](Game* game, Player* player)
    {
        player->deadCount += 10;

    });

    addDecision("Request Bomber", "It seem like the bombs exploded in one of our camp", 0, 2, 2, "HoldTheLine", [](Game* game, Player* player)
    {
        player->deadCount += 20;
    });

    addDecision("Build Hospital", "Your population appreciate", 0, 2, 2, "HoldTheLine", [](Game* game, Player* player)
    {
        player->spawnRateModifier *= 1.1;
    });

    addDecision("Invest in Medication", "The Military Council doesn't like you to put money on this", 0, 2, 2, "HoldTheLine", [](Game* game, Player* player)
    {
        player->fireRateModifier *= 1.1;
    });

    addDecision("Make a money campaign", "People accept to give money but stop enrolling", 0, 2, 2, "HoldTheLine", [](Game* game, Player* player)
    {
        player->spawnRateModifier *= 0.9f;
    });

    addDecision("End the war...", "Well that's sad", 3, 3, 3, "EndTheWar", [](Game* game, Player* player)
    {
        auto sp = std::make_shared<sf::RenderTexture>();
        sp->create(game->window.getSize().x, game->window.getSize().y);
        game->activeState->render(*sp.get());
        sp->display();
        game->nextState = std::make_shared<EndGameState>(game, sp);
    });

    updateDangerLevel(0);

}

#include "MathHelper.h"

Decision DecisionGenerator::getDecision(int dangerLevel, Decision* filter)
{
//    float totalPropability = 0;
//
//    for (auto& it : eligable)
//    {
//        if (filter != nullptr && *filter == it)
//            continue;
//
//        totalPropability += it.probability;
//    }

//    float result = math::rand(totalPropability );
    float result = math::rand(eligable.size() - 1);
//    float currentProb = 0;

    while(filter && eligable[result] == *filter && (*filter).message != "End the war...")
    {
        result++;
        if(result >= eligable.size())
            result = 0;
    }

    return eligable[result];

//    for (auto &it : eligable)
//    {
//        currentProb += it.probability;
//        if (result <= currentProb)
//        {
//            if (filter != nullptr)
//            {
//                if (*filter == it && it.message != "End the war...") // #Bodged
//                    continue;
//            }
//
//
//            return it;
//        }
//    }

    throw "Nyrox is an idiot exception";
}

void DecisionGenerator::updateDangerLevel(int level)
{

//    // remove decisions from the array that are too advanced
//    for (auto it = eligable.begin(); it != eligable.end(); it++)
//    {
//        if (it->maxDangerLevel < level)
//        {
//            it = eligable.erase(it);
//        }
//        if (it == eligable.end())
//            break;
//    }
//

    eligable.clear();

    // add decisions to the array that are now eligable
    for (auto it = decisions.begin(); it != decisions.end(); it++)
    {
        if (it->minDangerLevel <= level && it->maxDangerLevel >= level)
        {
            for(int x = 0 ; x < it->probability; x++)
                eligable.push_back(*it);
        }
    }
}
<|endoftext|>


<commit_before>#include "LogViewer.h"
#include "QDateTime"
#include "QFileInfo"
#include <QDebug>
#include "QBoxLayout"
#include "QComboBox"
#include "QLabel"
#include "Utilities.h"
#include "SignalBlocker.h"

QtMsgType LogViewer::comboBoxIndexToQtMsgType(int index)
{
	switch (index)
	{
	case 0:
	default:
		return QtDebugMsg;
	case 1:
		return QtInfoMsg;
	case 2:
		return QtWarningMsg;
	case 3:
		return QtCriticalMsg;
	case 4:
		return QtFatalMsg;
	}
}

int LogViewer::qtMsgTypeToComboBoxIndex(QtMsgType level)
{
	switch (level)
	{
	case QtDebugMsg:
	default:
		return 0;
	case QtInfoMsg:
		return 1;
	case QtWarningMsg:
		return 2;
	case QtCriticalMsg:
		return 3;
	case QtFatalMsg:
		return 4;
	}
}

int LogViewer::numQtMsgTypes()
{
    return 5;
}

LogViewer::LogViewer(Logger* logger, QWidget* parent /*= nullptr*/)
	: QWidget(parent)
	, mConsole(new QPlainTextEdit(this))
    , mLogger(logger)
	, mLevelComboBox(nullptr)
    , mLevel(QtWarningMsg)
    , mMutex(QMutex::Recursive)
{
	Q_ASSERT(mLogger != nullptr);
	mLogger->addListener(this);
	connect(mLogger, &QObject::destroyed, [this] { mLogger = nullptr; });

	//int level = QSettings().value() gLocalSettings->value(LOCAL_LOG_VIEWER_LEVEL).toInt();

	//mLevel = intToMsgType(level);

	mConsole->setMaximumBlockCount(10000);
	mConsole->setReadOnly(true);
	mConsole->setUndoRedoEnabled(false);

	QVBoxLayout* layout = new QVBoxLayout;
	setLayout(layout);
	QHBoxLayout* toolbar = new QHBoxLayout;
	layout->addLayout(toolbar);
	layout->addWidget(mConsole);

	mLevelComboBox = new QComboBox(this);
	mLevelComboBox->insertItem(0, "Debug");
	mLevelComboBox->insertItem(1, "Info");
	mLevelComboBox->insertItem(2, "Warning");
	mLevelComboBox->insertItem(3, "Critical");
	mLevelComboBox->insertItem(4, "None");
	mLevelComboBox->setCurrentIndex(msgTypeToInt(mLevel));
	connect(mLevelComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [this](int index) {
		//gLocalSettings->setValue(LOCAL_LOG_VIEWER_LEVEL, intToMsgType(index));
		//setLevel(intToMsgType(index));

		setLevel(comboBoxIndexToQtMsgType(index));
	});
	toolbar->addWidget(new QLabel("Level", this));
	toolbar->addWidget(mLevelComboBox);

	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

	setLevel(intToMsgType(QSettings().value("logViewerLevel").toInt()));

	refresh();

	//VERIFY(connect(gLocalSettings, SIGNAL(valueChanged(QString const&, QVariant const&)), this, SLOT(localSettingChanged(QString const&, QVariant const&))));

	QTimer* updateTimer = new QTimer(this);
	updateTimer->setInterval(100);
	VERIFY(connect(updateTimer, SIGNAL(timeout()), this, SLOT(update())));
	updateTimer->start();
}

LogViewer::~LogViewer()
{
	if (mLogger != nullptr)
	{
		mLogger->removeListener(this);
	}
}

void LogViewer::setLevel(QtMsgType level)
{
	mLevel = level;
	{
		SignalBlocker _(mLevelComboBox);
		mLevelComboBox->setCurrentIndex(qtMsgTypeToComboBoxIndex(level));
	}
	refresh();
	QSettings().setValue("logViewerLevel", level);
}

void LogViewer::handle(LogMessage const& message)
{
	QMutexLocker lock(&mMutex);
	p_handle(message);
}

//void LogViewer::localSettingChanged(QString const& key, QVariant const& value)
//{
//	if (key == LOCAL_LOG_VIEWER_LEVEL)
//	{
//		Q_ASSERT(value.type() == QVariant::Int);
//		int index = value.toInt();
//		QtMsgType level = index == 0 ? QtDebugMsg
//			: index == 1 ? QtInfoMsg
//			: index == 2 ? QtWarningMsg
//			: index == 3 ? QtCriticalMsg
//			: QtFatalMsg;
//		setLevel(level);
//	}
//}

void LogViewer::p_handle(LogMessage const& message)
{
	static QMap<QtMsgType, QString> const colors = {
		{ QtDebugMsg, "888" },
		{ QtInfoMsg, "222" },
		{ QtWarningMsg, "f44" },
		{ QtCriticalMsg, "f00" },
		{ QtFatalMsg, "f00" },
	};

	QString datetime = message.time.toString("yyyy-MM-dd HH:mm:ss.zzz");
    QString text = message.message;
    text.replace("\n", "
");
    text.replace("\\n", "
");
    QString s(QString("--- %1\t %2 \t%3

%4
").arg(toString(message.type), datetime, message.location, text, colors.value(message.type)));
	{
		QMutexLocker lock(&mMutex);
		mBuffer << s;
	}
}

void LogViewer::update()
{
	// avoid appending html with the buffer locked as can cause deadlock
	QStringList buffer;
	{
		QMutexLocker lock(&mMutex);
		qSwap(mBuffer, buffer);
	}
	for (QString& s : buffer)
	{
		mConsole->appendHtml(std::move(s));
	}
}

void LogViewer::refresh()
{
	QList<std::shared_ptr<LogMessage const>> buffer = mLogger->getHistory();

	{
		QMutexLocker lock(&mMutex);
		mConsole->clear();
		for (auto const& m : buffer)
		{
			if (shouldHandle(m->type))
			{
				p_handle(*m);
			}
		}
	}
}

<commit_msg>Log viewer uses automatic text color for dark mode on macos<commit_after>#include "LogViewer.h"
#include "QDateTime"
#include "QFileInfo"
#include <QDebug>
#include "QBoxLayout"
#include "QComboBox"
#include "QLabel"
#include "Utilities.h"
#include "SignalBlocker.h"

QtMsgType LogViewer::comboBoxIndexToQtMsgType(int index)
{
	switch (index)
	{
	case 0:
	default:
		return QtDebugMsg;
	case 1:
		return QtInfoMsg;
	case 2:
		return QtWarningMsg;
	case 3:
		return QtCriticalMsg;
	case 4:
		return QtFatalMsg;
	}
}

int LogViewer::qtMsgTypeToComboBoxIndex(QtMsgType level)
{
	switch (level)
	{
	case QtDebugMsg:
	default:
		return 0;
	case QtInfoMsg:
		return 1;
	case QtWarningMsg:
		return 2;
	case QtCriticalMsg:
		return 3;
	case QtFatalMsg:
		return 4;
	}
}

int LogViewer::numQtMsgTypes()
{
    return 5;
}

LogViewer::LogViewer(Logger* logger, QWidget* parent /*= nullptr*/)
	: QWidget(parent)
	, mConsole(new QPlainTextEdit(this))
    , mLogger(logger)
	, mLevelComboBox(nullptr)
    , mLevel(QtWarningMsg)
    , mMutex(QMutex::Recursive)
{
	Q_ASSERT(mLogger != nullptr);
	mLogger->addListener(this);
	connect(mLogger, &QObject::destroyed, [this] { mLogger = nullptr; });

	//int level = QSettings().value() gLocalSettings->value(LOCAL_LOG_VIEWER_LEVEL).toInt();

	//mLevel = intToMsgType(level);

	mConsole->setMaximumBlockCount(10000);
	mConsole->setReadOnly(true);
	mConsole->setUndoRedoEnabled(false);

	QVBoxLayout* layout = new QVBoxLayout;
	setLayout(layout);
	QHBoxLayout* toolbar = new QHBoxLayout;
	layout->addLayout(toolbar);
	layout->addWidget(mConsole);

	mLevelComboBox = new QComboBox(this);
	mLevelComboBox->insertItem(0, "Debug");
	mLevelComboBox->insertItem(1, "Info");
	mLevelComboBox->insertItem(2, "Warning");
	mLevelComboBox->insertItem(3, "Critical");
	mLevelComboBox->insertItem(4, "None");
	mLevelComboBox->setCurrentIndex(msgTypeToInt(mLevel));
	connect(mLevelComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [this](int index) {
		//gLocalSettings->setValue(LOCAL_LOG_VIEWER_LEVEL, intToMsgType(index));
		//setLevel(intToMsgType(index));

		setLevel(comboBoxIndexToQtMsgType(index));
	});
	toolbar->addWidget(new QLabel("Level", this));
	toolbar->addWidget(mLevelComboBox);

	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

	setLevel(intToMsgType(QSettings().value("logViewerLevel").toInt()));

	refresh();

	//VERIFY(connect(gLocalSettings, SIGNAL(valueChanged(QString const&, QVariant const&)), this, SLOT(localSettingChanged(QString const&, QVariant const&))));

	QTimer* updateTimer = new QTimer(this);
	updateTimer->setInterval(100);
	VERIFY(connect(updateTimer, SIGNAL(timeout()), this, SLOT(update())));
	updateTimer->start();
}

LogViewer::~LogViewer()
{
	if (mLogger != nullptr)
	{
		mLogger->removeListener(this);
	}
}

void LogViewer::setLevel(QtMsgType level)
{
	mLevel = level;
	{
		SignalBlocker _(mLevelComboBox);
		mLevelComboBox->setCurrentIndex(qtMsgTypeToComboBoxIndex(level));
	}
	refresh();
	QSettings().setValue("logViewerLevel", level);
}

void LogViewer::handle(LogMessage const& message)
{
	QMutexLocker lock(&mMutex);
	p_handle(message);
}

//void LogViewer::localSettingChanged(QString const& key, QVariant const& value)
//{
//	if (key == LOCAL_LOG_VIEWER_LEVEL)
//	{
//		Q_ASSERT(value.type() == QVariant::Int);
//		int index = value.toInt();
//		QtMsgType level = index == 0 ? QtDebugMsg
//			: index == 1 ? QtInfoMsg
//			: index == 2 ? QtWarningMsg
//			: index == 3 ? QtCriticalMsg
//			: QtFatalMsg;
//		setLevel(level);
//	}
//}

void LogViewer::p_handle(LogMessage const& message)
{
	static QMap<QtMsgType, QString> const colors = {
		{ QtDebugMsg, "888" },
		{ QtInfoMsg, QPalette().color(QPalette::Text).name(QColor::HexRgb) },
		{ QtWarningMsg, "f44" },
		{ QtCriticalMsg, "f00" },
		{ QtFatalMsg, "f00" },
	};

	QString datetime = message.time.toString("yyyy-MM-dd HH:mm:ss.zzz");
    QString text = message.message;
    text.replace("\n", "
");
    text.replace("\\n", "
");
    QString s(QString("--- %1\t %2 \t%3

%4
").arg(toString(message.type), datetime, message.location, text, colors.value(message.type)));
	{
		QMutexLocker lock(&mMutex);
		mBuffer << s;
	}
}

void LogViewer::update()
{
	// avoid appending html with the buffer locked as can cause deadlock
	QStringList buffer;
	{
		QMutexLocker lock(&mMutex);
		qSwap(mBuffer, buffer);
	}
	for (QString& s : buffer)
	{
		mConsole->appendHtml(std::move(s));
	}
}

void LogViewer::refresh()
{
	QList<std::shared_ptr<LogMessage const>> buffer = mLogger->getHistory();

	{
		QMutexLocker lock(&mMutex);
		mConsole->clear();
		for (auto const& m : buffer)
		{
			if (shouldHandle(m->type))
			{
				p_handle(*m);
			}
		}
	}
}

<|endoftext|>


<commit_before>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2008, 2009 Ames Laboratory
Iowa State University and The Regents of the University of Michigan All rights
reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

Redistribution and use of HOOMD-blue, 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 the copyright holder nor the names of HOOMD-blue's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR
ANY WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
*/

// $Id$
// $URL$
// Maintainer: ndtrung

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif

#include <boost/python.hpp>
using namespace boost::python;

#include "QuaternionMath.h"
#include "TwoStepBDNVTRigid.h"

/*! \file TwoStepBDNVTRigid.cc
    \brief Contains code for the TwoStepBDNVTRigid class
*/

/*! \param sysdef SystemDefinition this method will act on. Must not be NULL.
    \param group The group of particles this integration method is to work on
    \param T Temperature set point as a function of time
    \param seed Random seed to use in generating random numbers
    \param gamma_diam Set gamma to the particle diameter of each particle if true, otherwise use a per-type
                      gamma via setGamma()
*/
TwoStepBDNVTRigid::TwoStepBDNVTRigid(boost::shared_ptr<SystemDefinition> sysdef,
                           boost::shared_ptr<ParticleGroup> group,
                           boost::shared_ptr<Variant> T,
                           unsigned int seed,
                           bool gamma_diam)
    : TwoStepNVERigid(sysdef, group, true), m_T(T), m_seed(seed), m_gamma_diam(gamma_diam)
    {
    // set a named, but otherwise blank set of integrator variables
    IntegratorVariables v = getIntegratorVariables();

    if (!restartInfoTestValid(v, "bdnvt_rigid", 0))
        {
        v.type = "bdnvt_rigid";
        v.variable.resize(0);
        setValidRestart(false);
        }
    else
        setValidRestart(true);

    setIntegratorVariables(v);

    // allocate memory for the per-type gamma storage and initialize them to 1.0
    GPUArray<Scalar> gamma(m_pdata->getNTypes(), m_pdata->getExecConf());
    m_gamma.swap(gamma);
    ArrayHandle<Scalar> h_gamma(m_gamma, access_location::host, access_mode::overwrite);
    for (unsigned int i = 0; i < m_gamma.getNumElements(); i++)
        h_gamma.data[i] = Scalar(1.0);
    }

/*! \param typ Particle type to set gamma for
    \param gamma The gamma value to set
*/
void TwoStepBDNVTRigid::setGamma(unsigned int typ, Scalar gamma)
    {
    // check for user errors
    if (m_gamma_diam)
        {
        cerr << endl << "***Error! Trying to set gamma when it is set to be the diameter! " << typ << endl << endl;
        throw runtime_error("Error setting params in TwoStepBDNVT");
        }
    if (typ >= m_pdata->getNTypes())
        {
        cerr << endl << "***Error! Trying to set gamma for a non existant type! " << typ << endl << endl;
        throw runtime_error("Error setting params in TwoStepBDNVT");
        }

    ArrayHandle<Scalar> h_gamma(m_gamma, access_location::host, access_mode::readwrite);
    h_gamma.data[typ] = gamma;
    }

/*! \param timestep Current time step
    \post particle velocities are moved forward to timestep+1
*/
void TwoStepBDNVTRigid::integrateStepTwo(unsigned int timestep)
    {
    // sanity check
    if (m_n_bodies <= 0)
        return;

    const GPUArray< Scalar4 >& net_force = m_pdata->getNetForce();

    // profile this step
    if (m_prof)
        m_prof->push("BD NVT rigid step 2");

    {
    // Modify the net forces with the random and drag forces
    const ParticleDataArrays& arrays = m_pdata->acquireReadWrite();
    ArrayHandle<Scalar4> h_net_force(net_force, access_location::host, access_mode::readwrite);
    ArrayHandle<Scalar> h_gamma(m_gamma, access_location::host, access_mode::read);

    // grab some initial variables
    const Scalar currentTemp = m_T->getValue(timestep);
    const Scalar D = Scalar(m_sysdef->getNDimensions());

    // initialize the RNG
    Saru saru(m_seed, timestep);

    // a(t+deltaT) gets modified with the bd forces
    // v(t+deltaT) = v(t+deltaT/2) + 1/2 * a(t+deltaT)*deltaT
    unsigned int group_size = m_group->getNumMembers();
    for (unsigned int group_idx = 0; group_idx < group_size; group_idx++)
        {
        unsigned int j = m_group->getMemberIndex(group_idx);

        // first, calculate the BD forces
        // Generate three random numbers
        Scalar rx = saru.d(-1,1);
        Scalar ry = saru.d(-1,1);
        Scalar rz = saru.d(-1,1);

        Scalar gamma;
        if (m_gamma_diam)
            gamma = arrays.diameter[j];
        else
            gamma = h_gamma.data[arrays.type[j]];

        // compute the bd force
        Scalar coeff = sqrt(Scalar(6.0)*gamma*currentTemp/m_deltaT);
        Scalar bd_fx = rx*coeff - gamma*arrays.vx[j];
        Scalar bd_fy = ry*coeff - gamma*arrays.vy[j];
        Scalar bd_fz = rz*coeff - gamma*arrays.vz[j];

        if (D < 3.0)
            bd_fz = Scalar(0.0);

        h_net_force.data[j].x += bd_fx;
        h_net_force.data[j].y += bd_fy;
        h_net_force.data[j].z += bd_fz;
        }

    m_pdata->release();
    }

    // Perform the second step like in TwoStepNVERigid
    // compute net forces and torques on rigid bodies from particle forces
    computeForceAndTorque(timestep);

    {
    // rigid data handes
    ArrayHandle<Scalar> body_mass_handle(m_rigid_data->getBodyMass(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> moment_inertia_handle(m_rigid_data->getMomentInertia(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> orientation_handle(m_rigid_data->getOrientation(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> ex_space_handle(m_rigid_data->getExSpace(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> ey_space_handle(m_rigid_data->getEySpace(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> ez_space_handle(m_rigid_data->getEzSpace(), access_location::host, access_mode::read);

    ArrayHandle<Scalar4> force_handle(m_rigid_data->getForce(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> torque_handle(m_rigid_data->getTorque(), access_location::host, access_mode::read);

    ArrayHandle<Scalar4> vel_handle(m_rigid_data->getVel(), access_location::host, access_mode::readwrite);
    ArrayHandle<Scalar4> angmom_handle(m_rigid_data->getAngMom(), access_location::host, access_mode::readwrite);
    ArrayHandle<Scalar4> angvel_handle(m_rigid_data->getAngVel(), access_location::host, access_mode::readwrite);

    ArrayHandle<Scalar4> conjqm_handle(m_conjqm, access_location::host, access_mode::readwrite);

    Scalar4 mbody, tbody, fquat;
    Scalar dt_half = 0.5 * m_deltaT;

    // 2nd step: final integration
    for (unsigned int group_idx = 0; group_idx < m_n_bodies; group_idx++)
        {
        unsigned int body = m_body_group->getMemberIndex(group_idx);

        Scalar dtfm = dt_half / body_mass_handle.data[body];
        vel_handle.data[body].x += dtfm * force_handle.data[body].x;
        vel_handle.data[body].y += dtfm * force_handle.data[body].y;
        vel_handle.data[body].z += dtfm * force_handle.data[body].z;

        matrix_dot(ex_space_handle.data[body], ey_space_handle.data[body], ez_space_handle.data[body], torque_handle.data[body], tbody);
        quat_multiply(orientation_handle.data[body], tbody, fquat);

        conjqm_handle.data[body].x += m_deltaT * fquat.x;
        conjqm_handle.data[body].y += m_deltaT * fquat.y;
        conjqm_handle.data[body].z += m_deltaT * fquat.z;
        conjqm_handle.data[body].w += m_deltaT * fquat.w;

        inv_quat_multiply(orientation_handle.data[body], conjqm_handle.data[body], mbody);
        transpose_dot(ex_space_handle.data[body], ey_space_handle.data[body], ez_space_handle.data[body], mbody, angmom_handle.data[body]);

        angmom_handle.data[body].x *= 0.5;
        angmom_handle.data[body].y *= 0.5;
        angmom_handle.data[body].z *= 0.5;

        computeAngularVelocity(angmom_handle.data[body], moment_inertia_handle.data[body],
                               ex_space_handle.data[body], ey_space_handle.data[body], ez_space_handle.data[body], angvel_handle.data[body]);
        }
    } // out of scope for handles

    // set velocities of particles in rigid bodies
    set_v(timestep);

    // done profiling
    if (m_prof)
        m_prof->pop();
    }

void export_TwoStepBDNVTRigid()
    {
    class_<TwoStepBDNVTRigid, boost::shared_ptr<TwoStepBDNVTRigid>, bases<TwoStepNVERigid>, boost::noncopyable>
        ("TwoStepBDNVTRigid", init< boost::shared_ptr<SystemDefinition>,
                         boost::shared_ptr<ParticleGroup>,
                         boost::shared_ptr<Variant>,
                         unsigned int,
                         bool
                         >())
        .def("setT", &TwoStepBDNVTRigid::setT)
        .def("setGamma", &TwoStepBDNVTRigid::setGamma)
        ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif

<commit_msg>Solved a bug the resulted in too little angular velocity in integrate.bdnvt_rigid on the CPU<commit_after>/*
Highly Optimized Object-oriented Many-particle Dynamics -- Blue Edition
(HOOMD-blue) Open Source Software License Copyright 2008, 2009 Ames Laboratory
Iowa State University and The Regents of the University of Michigan All rights
reserved.

HOOMD-blue may contain modifications ("Contributions") provided, and to which
copyright is held, by various Contributors who have granted The Regents of the
University of Michigan the right to modify and/or distribute such Contributions.

Redistribution and use of HOOMD-blue, 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 the copyright holder nor the names of HOOMD-blue's
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.

Disclaimer

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND/OR
ANY WARRANTIES THAT THIS SOFTWARE IS FREE OF INFRINGEMENT ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
*/

// $Id$
// $URL$
// Maintainer: ndtrung

#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4244 )
#endif

#include <boost/python.hpp>
using namespace boost::python;

#include "QuaternionMath.h"
#include "TwoStepBDNVTRigid.h"

/*! \file TwoStepBDNVTRigid.cc
    \brief Contains code for the TwoStepBDNVTRigid class
*/

/*! \param sysdef SystemDefinition this method will act on. Must not be NULL.
    \param group The group of particles this integration method is to work on
    \param T Temperature set point as a function of time
    \param seed Random seed to use in generating random numbers
    \param gamma_diam Set gamma to the particle diameter of each particle if true, otherwise use a per-type
                      gamma via setGamma()
*/
TwoStepBDNVTRigid::TwoStepBDNVTRigid(boost::shared_ptr<SystemDefinition> sysdef,
                           boost::shared_ptr<ParticleGroup> group,
                           boost::shared_ptr<Variant> T,
                           unsigned int seed,
                           bool gamma_diam)
    : TwoStepNVERigid(sysdef, group, true), m_T(T), m_seed(seed), m_gamma_diam(gamma_diam)
    {
    // set a named, but otherwise blank set of integrator variables
    IntegratorVariables v = getIntegratorVariables();

    if (!restartInfoTestValid(v, "bdnvt_rigid", 0))
        {
        v.type = "bdnvt_rigid";
        v.variable.resize(0);
        setValidRestart(false);
        }
    else
        setValidRestart(true);

    setIntegratorVariables(v);

    // allocate memory for the per-type gamma storage and initialize them to 1.0
    GPUArray<Scalar> gamma(m_pdata->getNTypes(), m_pdata->getExecConf());
    m_gamma.swap(gamma);
    ArrayHandle<Scalar> h_gamma(m_gamma, access_location::host, access_mode::overwrite);
    for (unsigned int i = 0; i < m_gamma.getNumElements(); i++)
        h_gamma.data[i] = Scalar(1.0);
    }

/*! \param typ Particle type to set gamma for
    \param gamma The gamma value to set
*/
void TwoStepBDNVTRigid::setGamma(unsigned int typ, Scalar gamma)
    {
    // check for user errors
    if (m_gamma_diam)
        {
        cerr << endl << "***Error! Trying to set gamma when it is set to be the diameter! " << typ << endl << endl;
        throw runtime_error("Error setting params in TwoStepBDNVT");
        }
    if (typ >= m_pdata->getNTypes())
        {
        cerr << endl << "***Error! Trying to set gamma for a non existant type! " << typ << endl << endl;
        throw runtime_error("Error setting params in TwoStepBDNVT");
        }

    ArrayHandle<Scalar> h_gamma(m_gamma, access_location::host, access_mode::readwrite);
    h_gamma.data[typ] = gamma;
    }

/*! \param timestep Current time step
    \post particle velocities are moved forward to timestep+1
*/
void TwoStepBDNVTRigid::integrateStepTwo(unsigned int timestep)
    {
    // sanity check
    if (m_n_bodies <= 0)
        return;

    const GPUArray< Scalar4 >& net_force = m_pdata->getNetForce();

    // profile this step
    if (m_prof)
        m_prof->push("BD NVT rigid step 2");

    {
    // Modify the net forces with the random and drag forces
    const ParticleDataArrays& arrays = m_pdata->acquireReadWrite();
    ArrayHandle<Scalar4> h_net_force(net_force, access_location::host, access_mode::readwrite);
    ArrayHandle<Scalar> h_gamma(m_gamma, access_location::host, access_mode::read);

    // grab some initial variables
    const Scalar currentTemp = m_T->getValue(timestep);
    const Scalar D = Scalar(m_sysdef->getNDimensions());

    // initialize the RNG
    Saru saru(m_seed, timestep);

    // a(t+deltaT) gets modified with the bd forces
    // v(t+deltaT) = v(t+deltaT/2) + 1/2 * a(t+deltaT)*deltaT
    unsigned int group_size = m_group->getNumMembers();
    for (unsigned int group_idx = 0; group_idx < group_size; group_idx++)
        {
        unsigned int j = m_group->getMemberIndex(group_idx);

        // first, calculate the BD forces
        // Generate three random numbers
        Scalar rx = saru.d(-1,1);
        Scalar ry = saru.d(-1,1);
        Scalar rz = saru.d(-1,1);

        Scalar gamma;
        if (m_gamma_diam)
            gamma = arrays.diameter[j];
        else
            gamma = h_gamma.data[arrays.type[j]];

        // compute the bd force
        Scalar coeff = sqrt(Scalar(6.0)*gamma*currentTemp/m_deltaT);
        Scalar bd_fx = rx*coeff - gamma*arrays.vx[j];
        Scalar bd_fy = ry*coeff - gamma*arrays.vy[j];
        Scalar bd_fz = rz*coeff - gamma*arrays.vz[j];

        if (D < 3.0)
            bd_fz = Scalar(0.0);

        h_net_force.data[j].x += bd_fx;
        h_net_force.data[j].y += bd_fy;
        h_net_force.data[j].z += bd_fz;
        }

    m_pdata->release();
    }

    // Perform the second step like in TwoStepNVERigid
    // compute net forces and torques on rigid bodies from particle forces
    computeForceAndTorque(timestep);

    {
    // rigid data handes
    ArrayHandle<Scalar> body_mass_handle(m_rigid_data->getBodyMass(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> moment_inertia_handle(m_rigid_data->getMomentInertia(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> orientation_handle(m_rigid_data->getOrientation(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> ex_space_handle(m_rigid_data->getExSpace(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> ey_space_handle(m_rigid_data->getEySpace(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> ez_space_handle(m_rigid_data->getEzSpace(), access_location::host, access_mode::read);

    ArrayHandle<Scalar4> force_handle(m_rigid_data->getForce(), access_location::host, access_mode::read);
    ArrayHandle<Scalar4> torque_handle(m_rigid_data->getTorque(), access_location::host, access_mode::read);

    ArrayHandle<Scalar4> vel_handle(m_rigid_data->getVel(), access_location::host, access_mode::readwrite);
    ArrayHandle<Scalar4> angmom_handle(m_rigid_data->getAngMom(), access_location::host, access_mode::readwrite);
    ArrayHandle<Scalar4> angvel_handle(m_rigid_data->getAngVel(), access_location::host, access_mode::readwrite);

    ArrayHandle<Scalar4> conjqm_handle(m_conjqm, access_location::host, access_mode::readwrite);

    Scalar4 mbody, tbody, fquat;
    Scalar dt_half = 0.5 * m_deltaT;

    // 2nd step: final integration
    for (unsigned int group_idx = 0; group_idx < m_n_bodies; group_idx++)
        {
        unsigned int body = m_body_group->getMemberIndex(group_idx);

        Scalar dtfm = dt_half / body_mass_handle.data[body];
        vel_handle.data[body].x += dtfm * force_handle.data[body].x;
        vel_handle.data[body].y += dtfm * force_handle.data[body].y;
        vel_handle.data[body].z += dtfm * force_handle.data[body].z;

        angmom_handle.data[body].x += dt_half * torque_handle.data[body].x;
        angmom_handle.data[body].y += dt_half * torque_handle.data[body].y;
        angmom_handle.data[body].z += dt_half * torque_handle.data[body].z;

        /*
        matrix_dot(ex_space_handle.data[body], ey_space_handle.data[body], ez_space_handle.data[body], torque_handle.data[body], tbody);
        quat_multiply(orientation_handle.data[body], tbody, fquat);

        conjqm_handle.data[body].x += m_deltaT * fquat.x;
        conjqm_handle.data[body].y += m_deltaT * fquat.y;
        conjqm_handle.data[body].z += m_deltaT * fquat.z;
        conjqm_handle.data[body].w += m_deltaT * fquat.w;

        inv_quat_multiply(orientation_handle.data[body], conjqm_handle.data[body], mbody);
        transpose_dot(ex_space_handle.data[body], ey_space_handle.data[body], ez_space_handle.data[body], mbody, angmom_handle.data[body]);

        angmom_handle.data[body].x *= 0.5;
        angmom_handle.data[body].y *= 0.5;
        angmom_handle.data[body].z *= 0.5;*/

        computeAngularVelocity(angmom_handle.data[body], moment_inertia_handle.data[body],
                               ex_space_handle.data[body], ey_space_handle.data[body], ez_space_handle.data[body], angvel_handle.data[body]);
        }
    } // out of scope for handles

    // set velocities of particles in rigid bodies
    set_v(timestep);

    // done profiling
    if (m_prof)
        m_prof->pop();
    }

void export_TwoStepBDNVTRigid()
    {
    class_<TwoStepBDNVTRigid, boost::shared_ptr<TwoStepBDNVTRigid>, bases<TwoStepNVERigid>, boost::noncopyable>
        ("TwoStepBDNVTRigid", init< boost::shared_ptr<SystemDefinition>,
                         boost::shared_ptr<ParticleGroup>,
                         boost::shared_ptr<Variant>,
                         unsigned int,
                         bool
                         >())
        .def("setT", &TwoStepBDNVTRigid::setT)
        .def("setGamma", &TwoStepBDNVTRigid::setGamma)
        ;
    }

#ifdef WIN32
#pragma warning( pop )
#endif

<|endoftext|>


<commit_before>//
// Created by everettjf on 2017/7/23.
//

#include "FatHeaderViewNode.h"

MOEX_NAMESPACE_BEGIN
void FatHeaderViewNode::Init(FatHeaderPtr d){
    d_ = d;
    for(auto & f : d_->archs()){
        MachHeaderViewNodePtr node = std::make_shared<MachHeaderViewNode>();
        node->Init(f->mh());
        headers_.push_back(node);
    }
}

void FatHeaderViewNode::ForEachChild(std::function<void(ViewNode*)> callback){
    for(auto & h : headers_){
        callback(h.get());
    }
}

std::vector<ViewData*> FatHeaderViewNode::GetViewDatas(){
    using namespace moex::util;

    // Table
    if(table_.get() == nullptr){
        table_ = std::make_shared<TableViewData>();
        const fat_header * h = d_->offset();

        table_->AddRow(d_->GetRAW(&(h->magic)),h->magic,"Magic Number",d_->GetMagicString());
        table_->AddRow(d_->GetRAW(&(h->nfat_arch)),h->nfat_arch,"Number of Architecture",AsString(d_->data().nfat_arch));

        table_->AddSeparator();

        for(auto & arch : d_->archs()){
            const fat_arch * a = arch->offset();
            table_->AddRow(d_->GetRAW(&(a->cputype)),a->cputype,"CPU Type",arch->GetCpuTypeString());
            table_->AddRow(d_->GetRAW(&(a->cpusubtype)),a->cpusubtype,"CPU SubType",arch->GetCpuSubTypeString());
            table_->AddRow(d_->GetRAW(&(a->offset)),a->offset,"Offset",AsString(arch->data().offset));
            table_->AddRow(d_->GetRAW(&(a->size)),a->size,"Size",AsString(arch->data().size));
            table_->AddRow(d_->GetRAW(&(a->align)),a->align,"Align",AsString(arch->data().align));

            table_->AddSeparator();
        }
    }

    if(binary_.get() == nullptr){

    }

    return {table_.get()};
}

MOEX_NAMESPACE_END
<commit_msg>align fix<commit_after>//
// Created by everettjf on 2017/7/23.
//

#include "FatHeaderViewNode.h"

MOEX_NAMESPACE_BEGIN
void FatHeaderViewNode::Init(FatHeaderPtr d){
    d_ = d;
    for(auto & f : d_->archs()){
        MachHeaderViewNodePtr node = std::make_shared<MachHeaderViewNode>();
        node->Init(f->mh());
        headers_.push_back(node);
    }
}

void FatHeaderViewNode::ForEachChild(std::function<void(ViewNode*)> callback){
    for(auto & h : headers_){
        callback(h.get());
    }
}

std::vector<ViewData*> FatHeaderViewNode::GetViewDatas(){
    using namespace moex::util;

    // Table
    if(table_.get() == nullptr){
        table_ = std::make_shared<TableViewData>();
        const fat_header * h = d_->offset();

        table_->AddRow(d_->GetRAW(&(h->magic)),h->magic,"Magic Number",d_->GetMagicString());
        table_->AddRow(d_->GetRAW(&(h->nfat_arch)),h->nfat_arch,"Number of Architecture",AsString(d_->data().nfat_arch));

        table_->AddSeparator();

        for(auto & arch : d_->archs()){
            const fat_arch * a = arch->offset();
            table_->AddRow(d_->GetRAW(&(a->cputype)),a->cputype,"CPU Type",arch->GetCpuTypeString());
            table_->AddRow(d_->GetRAW(&(a->cpusubtype)),a->cpusubtype,"CPU SubType",arch->GetCpuSubTypeString());
            table_->AddRow(d_->GetRAW(&(a->offset)),a->offset,"Offset",AsString(arch->data().offset));
            table_->AddRow(d_->GetRAW(&(a->size)),a->size,"Size",AsString(arch->data().size));
            table_->AddRow(d_->GetRAW(&(a->align)),a->align,"Align",AsString(1 << arch->data().align)); // why 1<<

            table_->AddSeparator();
        }
    }

    if(binary_.get() == nullptr){

    }

    return {table_.get()};
}

MOEX_NAMESPACE_END
<|endoftext|>


<commit_before>/*
** Author(s):
**  - Cedric GESTES <gestes@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#pragma once
#ifndef _QIMESSAGING_SESSION_HPP_
#define _QIMESSAGING_SESSION_HPP_

#include <qimessaging/api.hpp>
#include <qimessaging/transport_socket.hpp>
#include <qimessaging/service_info.hpp>
#include <qimessaging/future.hpp>
#include <qimessaging/object.hpp>

#include <vector>
#include <string>

namespace qi {

  class SessionPrivate;

  class QIMESSAGING_API SessionInterface
  {
  public:
    virtual ~SessionInterface() = 0;
    inline virtual void onSessionConnected(Session *QI_UNUSED(session), void *data)
    {
      qiLogVerbose("session.hpp") << "onSessionConnected not implemented";
    }

    inline virtual void onSessionConnectionError(Session *QI_UNUSED(session), void *data)
    {
      qiLogVerbose("session.hpp") << "onSessionConnectionError not implemented";
    }

    inline virtual void onSessionDisconnected(Session *QI_UNUSED(session), void *data)
    {
      qiLogVerbose("session.hpp") << "onSessionDisconnected not implemented";
    }

    inline virtual void onServiceRegistered(Session *QI_UNUSED(session),
                                            const std::string &QI_UNUSED(serviceName), void *data)
    {
      qiLogVerbose("session.hpp") << "onServiceRegistered not implemented";
    }

    inline virtual void onServiceUnregistered(Session *QI_UNUSED(session),
                                              const std::string &QI_UNUSED(serviceName), void *data)
    {
      qiLogVerbose("session.hpp") << "onServiceUnregistered not implemented";
    }
  };

  class QIMESSAGING_API Session {
  public:
    Session();
    virtual ~Session();

    enum ServiceLocality {
      ServiceLocality_All    = 0,
      ServiceLocality_Local  = 1,
      ServiceLocality_Remote = 2
    };

    void addCallbacks(SessionInterface *delegate, void *data);
    void removeCallbacks(SessionInterface *delegate);

    //Client
    bool connect(const qi::Url &serviceDirectoryURL);
    bool isConnected() const;
    qi::Url url() const;
    bool waitForConnected(int msecs = 30000);
    bool waitForDisconnected(int msecs = 30000);

    bool waitForServiceReady(const std::string &service, int msecs = 30000);

    qi::Future< std::vector<ServiceInfo> > services(ServiceLocality locality = ServiceLocality_All);

    qi::Future< qi::Object* > service(const std::string &service,
                                      ServiceLocality locality = ServiceLocality_All,
                                      const std::string &protocol  = std::string("any"));

    //Server
    bool    listen(const std::string &address);
    qi::Url listenUrl() const;

    //close both client and server side
    void    close();

    qi::Future<unsigned int> registerService(const std::string &name, qi::Object *object);
    qi::Future<void>         unregisterService(unsigned int idx);

    /// Load a module and register an instance of each declared object as a service.
    std::vector<std::string>      loadService(const std::string& name, int flags = -1);

    SessionPrivate      *_p;
  };
}

#endif  // _QIMESSAGING_SESSION_HPP_
<commit_msg>fix addcallback default argument<commit_after>/*
** Author(s):
**  - Cedric GESTES <gestes@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#pragma once
#ifndef _QIMESSAGING_SESSION_HPP_
#define _QIMESSAGING_SESSION_HPP_

#include <qimessaging/api.hpp>
#include <qimessaging/transport_socket.hpp>
#include <qimessaging/service_info.hpp>
#include <qimessaging/future.hpp>
#include <qimessaging/object.hpp>

#include <vector>
#include <string>

namespace qi {

  class SessionPrivate;

  class QIMESSAGING_API SessionInterface
  {
  public:
    virtual ~SessionInterface() = 0;
    inline virtual void onSessionConnected(Session *QI_UNUSED(session), void *data)
    {
      qiLogVerbose("session.hpp") << "onSessionConnected not implemented";
    }

    inline virtual void onSessionConnectionError(Session *QI_UNUSED(session), void *data)
    {
      qiLogVerbose("session.hpp") << "onSessionConnectionError not implemented";
    }

    inline virtual void onSessionDisconnected(Session *QI_UNUSED(session), void *data)
    {
      qiLogVerbose("session.hpp") << "onSessionDisconnected not implemented";
    }

    inline virtual void onServiceRegistered(Session *QI_UNUSED(session),
                                            const std::string &QI_UNUSED(serviceName), void *data)
    {
      qiLogVerbose("session.hpp") << "onServiceRegistered not implemented";
    }

    inline virtual void onServiceUnregistered(Session *QI_UNUSED(session),
                                              const std::string &QI_UNUSED(serviceName), void *data)
    {
      qiLogVerbose("session.hpp") << "onServiceUnregistered not implemented";
    }
  };

  class QIMESSAGING_API Session {
  public:
    Session();
    virtual ~Session();

    enum ServiceLocality {
      ServiceLocality_All    = 0,
      ServiceLocality_Local  = 1,
      ServiceLocality_Remote = 2
    };

    void addCallbacks(SessionInterface *delegate, void *data = 0);
    void removeCallbacks(SessionInterface *delegate);

    //Client
    bool connect(const qi::Url &serviceDirectoryURL);
    bool isConnected() const;
    qi::Url url() const;
    bool waitForConnected(int msecs = 30000);
    bool waitForDisconnected(int msecs = 30000);

    bool waitForServiceReady(const std::string &service, int msecs = 30000);

    qi::Future< std::vector<ServiceInfo> > services(ServiceLocality locality = ServiceLocality_All);

    qi::Future< qi::Object* > service(const std::string &service,
                                      ServiceLocality locality = ServiceLocality_All,
                                      const std::string &protocol  = std::string("any"));

    //Server
    bool    listen(const std::string &address);
    qi::Url listenUrl() const;

    //close both client and server side
    void    close();

    qi::Future<unsigned int> registerService(const std::string &name, qi::Object *object);
    qi::Future<void>         unregisterService(unsigned int idx);

    /// Load a module and register an instance of each declared object as a service.
    std::vector<std::string>      loadService(const std::string& name, int flags = -1);

    SessionPrivate      *_p;
  };
}

#endif  // _QIMESSAGING_SESSION_HPP_
<|endoftext|>


<commit_before>// Projekt, mit dem die Demos getestet werden koennen

#define TEST_BASICS
#define TEST_FIND
#define TEST_ALIGNMENT
#define TEST_MODIFIERS
#define TEST_INDEX
#define TEST_GRAPH

#ifdef TEST_BASICS

	#define main runAllocator
	#include "../../library/demos/allocator.cpp"
	#undef main

	#define main runAlphabet
	#include "../../library/demos/alphabet.cpp"
	#undef main

	#define main runIterator
	#include "../../library/demos/iterator.cpp"
	#undef main

	#define main runRootedIterator
	#include "../../library/demos/rooted_iterator.cpp"
	#undef main

	#define main runString1
	#include "../../library/demos/string_1.cpp"
	#undef main

	#define main runFileFormat
	#include "../../library/demos/file_format.cpp"
	#undef main

#endif

#ifdef TEST_FIND

	#define main runFindExact
	#include "../../library/demos/find_exact.cpp"
	#undef main

	#define main runFindApprox
	#include "../../library/demos/find_approx.cpp"
	#undef main

	#define main runFindWild
	#include "../../library/demos/find_wild.cpp"
	#undef main

#endif

#ifdef TEST_ALIGNMENT

	#define main runAlignment
	#include "../../library/demos/alignment.cpp"
	#undef main

	#define main runAlignmentLocal
	#include "../../library/demos/alignment_local.cpp"
	#undef main

#endif

#ifdef TEST_MODIFIERS

	#define main runModifierModReverse
	#include "../../library/demos/modifier_modreverse.cpp"
	#undef main

	#define main runModifierModView
	#include "../../library/demos/modifier_modview.cpp"
	#undef main

	#define main runModifierNested
	#include "../../library/demos/modifier_nested.cpp"
	#undef main

#endif

#ifdef TEST_INDEX

	#define main runIndexSA
	#include "../../library/demos/index_sufarray.cpp"
	#undef main

	#define main runIndexFind
	#include "../../library/demos/index_find.cpp"
	#undef main

	#define main runIndexMUMs
	#include "../../library/demos/index_mums.cpp"
	#undef main

	#define main runIndexSuperMaxRepeats
	#include "../../library/demos/index_supermaxrepeats.cpp"
	#undef main

	#define main runIndexMaxRepeats
	#include "../../library/demos/index_maxrepeats.cpp"
	#undef main

	#define main runIndexMummy
	#include "../../library/demos/index_mummy.cpp"
	#undef main

	#define main runIndexNodePredicate
	#include "../../library/demos/index_node_predicate.cpp"
	#undef main

#endif

#ifdef TEST_GRAPH

	#define main runGraphBfs
	#include "../../library/demos/graph_algo_bfs.cpp"
	#undef main

	#define main runGraphDfs
	#include "../../library/demos/graph_algo_dfs.cpp"
	#undef main

	#define main runGraphTopsort
	#include "../../library/demos/graph_algo_topsort.cpp"
	#undef main

	#define main runGraphScc
	#include "../../library/demos/graph_algo_scc.cpp"
	#undef main

	#define main runGraphPrim
	#include "../../library/demos/graph_algo_tree_prim.cpp"
	#undef main

	#define main runGraphKruskal
	#include "../../library/demos/graph_algo_tree_kruskal.cpp"
	#undef main

	#define main runGraphDag
	#include "../../library/demos/graph_algo_path_dag.cpp"
	#undef main

	#define main runGraphBellman
	#include "../../library/demos/graph_algo_path_bellmanford.cpp"
	#undef main

	#define main runGraphDijkstra
	#include "../../library/demos/graph_algo_path_dijkstra.cpp"
	#undef main

	#define main runGraphAllpairs
	#include "../../library/demos/graph_algo_path_allpairs.cpp"
	#undef main

	#define main runGraphFloyd
	#include "../../library/demos/graph_algo_path_floydwarshall.cpp"
	#undef main

	#define main runGraphTransitive
	#include "../../library/demos/graph_algo_path_transitive.cpp"
	#undef main

	#define main runGraphFord
	#include "../../library/demos/graph_algo_flow_fordfulkerson.cpp"
	#undef main

	#define main runGraphLis
	#include "../../library/demos/graph_algo_lis.cpp"
	#undef main

	#define main runGraphHis
	#include "../../library/demos/graph_algo_his.cpp"
	#undef main

	#define main runGraphLcs
	#include "../../library/demos/graph_algo_lcs.cpp"
	#undef main

	#define main runGraphNw
	#include "../../library/demos/graph_align_nw.cpp"
	#undef main

	#define main runGraphGotoh
	#include "../../library/demos/graph_align_gotoh.cpp"
	#undef main

	#define main runGraphHirschberg
	#include "../../library/demos/graph_align_hirschberg.cpp"
	#undef main

	#define main runGraphSw
	#include "../../library/demos/graph_align_sw.cpp"
	#undef main

	#define main runGraphHmm
	#include "../../library/demos/graph_hmm.cpp"
	#undef main

	#define main runGraphHmmSilent
	#include "../../library/demos/graph_hmm_silent.cpp"
	#undef main

#endif

int main(int argc, const char *argv[])
{
#ifdef TEST_BASICS
	runAllocator();
	runAlphabet();
	runIterator();
	runRootedIterator();
	runString1();
	runFileFormat();
#endif

#ifdef TEST_FIND
	runFindExact();
	runFindApprox();
	runFindWild();
#endif

#ifdef TEST_ALIGNMENT
	runAlignment();
	runAlignmentLocal();
#endif

#ifdef TEST_MODIFIERS
	runModifierModReverse();
	runModifierModView();
	runModifierNested();
#endif

#ifdef TEST_INDEX
	runIndexSA();
	runIndexFind();
	runIndexMUMs();
	runIndexSuperMaxRepeats();
	runIndexMaxRepeats();
	runIndexMummy(argc, argv);
	runIndexNodePredicate();
#endif

#ifdef TEST_GRAPH
	runGraphBfs();
	runGraphDfs();
	runGraphTopsort();
	runGraphScc();
	runGraphPrim();
	runGraphKruskal();
	runGraphDag();
	runGraphBellman();
	runGraphDijkstra();
	runGraphAllpairs();
	runGraphFloyd();
	runGraphTransitive();
	runGraphFord();
	runGraphLis();
	runGraphHis();
	runGraphLcs();
	runGraphNw();
	runGraphGotoh();
	runGraphHirschberg();
	runGraphSw();
	runGraphHmm();
	runGraphHmmSilent();
#endif

	return 0;
}
<commit_msg><commit_after>// Projekt, mit dem die Demos getestet werden koennen

#define TEST_BASICS
#define TEST_FIND
#define TEST_ALIGNMENT
#define TEST_MODIFIERS
#define TEST_INDEX
#define TEST_GRAPH

#ifdef TEST_BASICS

	#define main runAllocator
	#include "../../library/demos/allocator.cpp"
	#undef main

	#define main runAlphabet
	#include "../../library/demos/alphabet.cpp"
	#undef main

	#define main runIterator
	#include "../../library/demos/iterator.cpp"
	#undef main

	#define main runRootedIterator
	#include "../../library/demos/rooted_iterator.cpp"
	#undef main

	#define main runFileFormat
	#include "../../library/demos/file_format.cpp"
	#undef main

#endif

#ifdef TEST_FIND

	#define main runFindExact
	#include "../../library/demos/find_exact.cpp"
	#undef main

	#define main runFindApprox
	#include "../../library/demos/find_approx.cpp"
	#undef main

	#define main runFindWild
	#include "../../library/demos/find_wild.cpp"
	#undef main

#endif

#ifdef TEST_ALIGNMENT

	#define main runAlignment
	#include "../../library/demos/alignment.cpp"
	#undef main

	#define main runAlignmentLocal
	#include "../../library/demos/alignment_local.cpp"
	#undef main

#endif

#ifdef TEST_MODIFIERS

	#define main runModifierModReverse
	#include "../../library/demos/modifier_modreverse.cpp"
	#undef main

	#define main runModifierModView
	#include "../../library/demos/modifier_modview.cpp"
	#undef main

	#define main runModifierNested
	#include "../../library/demos/modifier_nested.cpp"
	#undef main

#endif

#ifdef TEST_INDEX

	#define main runIndexSA
	#include "../../library/demos/index_sufarray.cpp"
	#undef main

	#define main runIndexFind
	#include "../../library/demos/index_find.cpp"
	#undef main

	#define main runIndexMUMs
	#include "../../library/demos/index_mums.cpp"
	#undef main

	#define main runIndexSuperMaxRepeats
	#include "../../library/demos/index_supermaxrepeats.cpp"
	#undef main

	#define main runIndexMaxRepeats
	#include "../../library/demos/index_maxrepeats.cpp"
	#undef main

	#define main runIndexMummy
	#include "../../library/demos/index_mummy.cpp"
	#undef main

	#define main runIndexNodePredicate
	#include "../../library/demos/index_node_predicate.cpp"
	#undef main

#endif

#ifdef TEST_GRAPH

	#define main runGraphBfs
	#include "../../library/demos/graph_algo_bfs.cpp"
	#undef main

	#define main runGraphDfs
	#include "../../library/demos/graph_algo_dfs.cpp"
	#undef main

	#define main runGraphTopsort
	#include "../../library/demos/graph_algo_topsort.cpp"
	#undef main

	#define main runGraphScc
	#include "../../library/demos/graph_algo_scc.cpp"
	#undef main

	#define main runGraphPrim
	#include "../../library/demos/graph_algo_tree_prim.cpp"
	#undef main

	#define main runGraphKruskal
	#include "../../library/demos/graph_algo_tree_kruskal.cpp"
	#undef main

	#define main runGraphDag
	#include "../../library/demos/graph_algo_path_dag.cpp"
	#undef main

	#define main runGraphBellman
	#include "../../library/demos/graph_algo_path_bellmanford.cpp"
	#undef main

	#define main runGraphDijkstra
	#include "../../library/demos/graph_algo_path_dijkstra.cpp"
	#undef main

	#define main runGraphAllpairs
	#include "../../library/demos/graph_algo_path_allpairs.cpp"
	#undef main

	#define main runGraphFloyd
	#include "../../library/demos/graph_algo_path_floydwarshall.cpp"
	#undef main

	#define main runGraphTransitive
	#include "../../library/demos/graph_algo_path_transitive.cpp"
	#undef main

	#define main runGraphFord
	#include "../../library/demos/graph_algo_flow_fordfulkerson.cpp"
	#undef main

	#define main runGraphLis
	#include "../../library/demos/graph_algo_lis.cpp"
	#undef main

	#define main runGraphHis
	#include "../../library/demos/graph_algo_his.cpp"
	#undef main

	#define main runGraphLcs
	#include "../../library/demos/graph_algo_lcs.cpp"
	#undef main

	#define main runGraphNw
	#include "../../library/demos/graph_align_nw.cpp"
	#undef main

	#define main runGraphGotoh
	#include "../../library/demos/graph_align_gotoh.cpp"
	#undef main

	#define main runGraphHirschberg
	#include "../../library/demos/graph_align_hirschberg.cpp"
	#undef main

	#define main runGraphSw
	#include "../../library/demos/graph_align_sw.cpp"
	#undef main

	#define main runGraphHmm
	#include "../../library/demos/graph_hmm.cpp"
	#undef main

	#define main runGraphHmmSilent
	#include "../../library/demos/graph_hmm_silent.cpp"
	#undef main

#endif

int main(int argc, const char *argv[])
{
#ifdef TEST_BASICS
	runAllocator();
	runAlphabet();
	runIterator();
	runRootedIterator();
	runFileFormat();
#endif

#ifdef TEST_FIND
	runFindExact();
	runFindApprox();
	runFindWild();
#endif

#ifdef TEST_ALIGNMENT
	runAlignment();
	runAlignmentLocal();
#endif

#ifdef TEST_MODIFIERS
	runModifierModReverse();
	runModifierModView();
	runModifierNested();
#endif

#ifdef TEST_INDEX
	runIndexSA();
	runIndexFind();
	runIndexMUMs();
	runIndexSuperMaxRepeats();
	runIndexMaxRepeats();
	runIndexMummy(argc, argv);
	runIndexNodePredicate();
#endif

#ifdef TEST_GRAPH
	runGraphBfs();
	runGraphDfs();
	runGraphTopsort();
	runGraphScc();
	runGraphPrim();
	runGraphKruskal();
	runGraphDag();
	runGraphBellman();
	runGraphDijkstra();
	runGraphAllpairs();
	runGraphFloyd();
	runGraphTransitive();
	runGraphFord();
	runGraphLis();
	runGraphHis();
	runGraphLcs();
	runGraphNw();
	runGraphGotoh();
	runGraphHirschberg();
	runGraphSw();
	runGraphHmm();
	runGraphHmmSilent();
#endif

	return 0;
}
<|endoftext|>


<commit_before>/*
    Copyright (c) 2013 Daniel Vrátil <dvratil@redhat.com>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "searchresultsretriever.h"
#include "akonadiconnection.h"
#include "searchmanager.h"
#include "storage/selectquerybuilder.h"
#include "storage/collectionqueryhelper.h"

#include <QSqlError>

Akonadi::SearchResultsRetriever::SearchResultsRetriever( Akonadi::AkonadiConnection *connection )
  : mConnection( connection )
{
}

Akonadi::SearchResultsRetriever::~SearchResultsRetriever()
{
}

void Akonadi::SearchResultsRetriever::setQuery( const QString &query )
{
  mQuery = query;
}

void Akonadi::SearchResultsRetriever::setCollections( const QVector<qint64> &collectionsIds )
{
  mCollections = collectionsIds;
}

void Akonadi::SearchResultsRetriever::setMimeTypes( const QStringList &mimeTypes )
{
  mMimeTypes = mimeTypes;
}

QSet<qint64> Akonadi::SearchResultsRetriever::exec( bool *ok )
{
  SelectQueryBuilder<Collection> qb;
  qb.addJoin( QueryBuilder::InnerJoin, Resource::tableName(),
              Collection::resourceIdFullColumnName(),
              Resource::idFullColumnName());
  qb.addColumn( Collection::idFullColumnName() );
  qb.addColumn( Resource::nameFullColumnName() );

  QVariantList list;
  Q_FOREACH ( qint64 collection, mCollections ) {
    list << collection;
  }
  qb.addValueCondition( Collection::idFullColumnName(), Query::In, list );

  if ( !qb.exec() ) {
    throw HandlerException( qb.query().lastError().text() );
  }

  QSqlQuery query = qb.query();
  if ( !query.next() ) {
    return QSet<qint64>();
  }

  QList<SearchRequest*> requests;
  while ( query.isValid() ) {
    SearchRequest *request = new SearchRequest;
    request->id = mConnection->sessionId();
    request->query = mQuery;
    request->mimeTypes = mMimeTypes;
    request->resourceId = query.value( 0 ).toByteArray();
    request->collectionId = query.value( 1 ).toLongLong();
    requests << request;

    query.next();
  }

  query.finish();

  QSet<qint64> result;
  Q_FOREACH ( SearchRequest *request, requests ) {
    try {
      result.unite( SearchManager::instance()->search( request ) );
    } catch ( const SearchResultsRetrieverException &e ) {
      akError() << e.type() << ":" << e.what();
      return QSet<qint64>();
    }
  }

  return result;
}
<commit_msg>Fix handling of query results in SearchResultsRetriever<commit_after>/*
    Copyright (c) 2013 Daniel Vrátil <dvratil@redhat.com>

    This library is free software; you can redistribute it and/or modify it
    under the terms of the GNU Library General Public License as published by
    the Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    This library is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
    License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to the
    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
*/

#include "searchresultsretriever.h"
#include "akonadiconnection.h"
#include "searchmanager.h"
#include "storage/selectquerybuilder.h"
#include "storage/collectionqueryhelper.h"
#include "akdebug.h"

#include <QSqlError>

Akonadi::SearchResultsRetriever::SearchResultsRetriever( Akonadi::AkonadiConnection *connection )
  : mConnection( connection )
{
}

Akonadi::SearchResultsRetriever::~SearchResultsRetriever()
{
}

void Akonadi::SearchResultsRetriever::setQuery( const QString &query )
{
  mQuery = query;
}

void Akonadi::SearchResultsRetriever::setCollections( const QVector<qint64> &collectionsIds )
{
  mCollections = collectionsIds;
}

void Akonadi::SearchResultsRetriever::setMimeTypes( const QStringList &mimeTypes )
{
  mMimeTypes = mimeTypes;
}

QSet<qint64> Akonadi::SearchResultsRetriever::exec( bool *ok )
{
  if ( ok ) {
    *ok = false;
  }

  QueryBuilder qb( Collection::tableName() );
  qb.addJoin( QueryBuilder::InnerJoin, Resource::tableName(),
              Collection::resourceIdFullColumnName(),
              Resource::idFullColumnName());
  qb.addColumn( Collection::idFullColumnName() );
  qb.addColumn( Resource::nameFullColumnName() );

  QVariantList list;
  Q_FOREACH ( qint64 collection, mCollections ) {
    list << collection;
  }
  qb.addValueCondition( Collection::idFullColumnName(), Query::In, list );

  if ( !qb.exec() ) {
    throw HandlerException( qb.query().lastError().text() );
  }

  QSqlQuery query = qb.query();
  if ( !query.next() ) {
    return QSet<qint64>();
  }

  QList<SearchRequest*> requests;
  while ( query.isValid() ) {
    SearchRequest *request = new SearchRequest;
    request->id = mConnection->sessionId();
    request->query = mQuery;
    request->mimeTypes = mMimeTypes;
    request->collectionId = query.value( 0 ).toLongLong();
    request->resourceId = query.value( 1 ).toByteArray();
    requests << request;

    query.next();
  }

  query.finish();

  QSet<qint64> result;
  Q_FOREACH ( SearchRequest *request, requests ) {
    try {
      akDebug() << "Searching in" << request->resourceId << "...";
      result.unite( SearchManager::instance()->search( request ) );
    } catch ( const SearchResultsRetrieverException &e ) {
      akError() << e.type() << ":" << e.what();
      return QSet<qint64>();
    }
  }

  if ( ok ) {
    *ok = true;
  }
  return result;
}
<|endoftext|>


<commit_before>#include <string>

#include <Poco/Event.h>
#include <Poco/Exception.h>
#include <Poco/Net/NetException.h>

#include "dao/DeviceDao.h"
#include "di/Injectable.h"
#include "rpc/GatewayRPC.h"
#include "work/DeviceUnpairWorkExecutor.h"

BEEEON_OBJECT_BEGIN(BeeeOn, DeviceUnpairWorkExecutor)
BEEEON_OBJECT_CASTABLE(WorkExecutor)
BEEEON_OBJECT_REF("deviceDao", &DeviceUnpairWorkExecutor::setDeviceDao)
BEEEON_OBJECT_REF("gatewayRPC", &DeviceUnpairWorkExecutor::setGatewayRPC)
BEEEON_OBJECT_REF("scheduler", &DeviceUnpairWorkExecutor::setScheduler)
BEEEON_OBJECT_END(BeeeOn, DeviceUnpairWorkExecutor)

using namespace std;
using namespace Poco;
using namespace Poco::Net;
using namespace BeeeOn;

DeviceUnpairWorkExecutor::DeviceUnpairWorkExecutor():
	m_rpc(&NullGatewayRPC::instance())
{
}

void DeviceUnpairWorkExecutor::setDeviceDao(DeviceDao::Ptr dao)
{
	m_dao = dao;
}

void DeviceUnpairWorkExecutor::setGatewayRPC(GatewayRPC *rpc)
{
	m_rpc = rpc == NULL? &NullGatewayRPC::instance() : rpc;
}

bool DeviceUnpairWorkExecutor::accepts(const Work::Ptr work) const
{
	if (work->content().type().is<DeviceUnpairWork>())
		return true;

	return false;
}

void DeviceUnpairWorkExecutor::processResult(Work::Ptr work, DeviceUnpairWork &content)
{
	Gateway gateway(content.gatewayID());
	Device device(content.deviceID());

	switch (content.result()) {
	case GatewayRPCResult::NOT_CONNECTED:
		throw ConnectionAbortedException(
			"failed to unpair device " + device + " on gateway " + gateway);

	case GatewayRPCResult::TIMEOUT:
		throw TimeoutException(
			"failed to unpair device " + device + " on gateway " + gateway);

	case GatewayRPCResult::FAILED:
		throw RuntimeException(
			"failed to unpair device " + device + " on gateway " + gateway);

	case GatewayRPCResult::SUCCESS:
		return;

	default:
		suspend(work);
		break;
	}
}

void DeviceUnpairWorkExecutor::execute(Work::Ptr work)
{
	DeviceUnpairWork content = work->contentAs<DeviceUnpairWork>();

	Device device(content.deviceID());
	const Gateway gateway(content.gatewayID());

	if (!m_dao->fetch(device, gateway)) {
		logger().warning("device "
				+ device
				+ " on gateway "
				+ gateway
				+ " not found during unpair",
				__FILE__, __LINE__);
		return; // treat as success
	}

	if (content.hasResult()) {
		processResult(work, content);
		return;
	}

	WorkScheduler::Ptr scheduler = this->scheduler();
	WorkLockManager::Ptr lockManager = this->lockManager();

	m_rpc->unpairDevice([=](GatewayRPCResult::Ptr result) mutable
		{
			WorkWriteGuard accessGuard(lockManager->readWrite(work->id()));

			// update result of the work
			DeviceUnpairWork content = work->contentAs<DeviceUnpairWork>();
			content.setResult(result->status());
			work->setContent(content);

			switch (result->status()) {
			case GatewayRPCResult::PENDING:
			case GatewayRPCResult::ACCEPTED:
				// TODO persist
				return; // no other action is needed
			default:
				scheduler->wakeup(work);
				break;
			}
		},
		gateway,
		device
	);

	suspend(work);
}
<commit_msg>DeviceUnpairWorkExecutor: fix deadlock<commit_after>#include <string>

#include <Poco/Event.h>
#include <Poco/Exception.h>
#include <Poco/Net/NetException.h>

#include "dao/DeviceDao.h"
#include "di/Injectable.h"
#include "rpc/GatewayRPC.h"
#include "work/DeviceUnpairWorkExecutor.h"

BEEEON_OBJECT_BEGIN(BeeeOn, DeviceUnpairWorkExecutor)
BEEEON_OBJECT_CASTABLE(WorkExecutor)
BEEEON_OBJECT_REF("deviceDao", &DeviceUnpairWorkExecutor::setDeviceDao)
BEEEON_OBJECT_REF("gatewayRPC", &DeviceUnpairWorkExecutor::setGatewayRPC)
BEEEON_OBJECT_REF("scheduler", &DeviceUnpairWorkExecutor::setScheduler)
BEEEON_OBJECT_END(BeeeOn, DeviceUnpairWorkExecutor)

using namespace std;
using namespace Poco;
using namespace Poco::Net;
using namespace BeeeOn;

DeviceUnpairWorkExecutor::DeviceUnpairWorkExecutor():
	m_rpc(&NullGatewayRPC::instance())
{
}

void DeviceUnpairWorkExecutor::setDeviceDao(DeviceDao::Ptr dao)
{
	m_dao = dao;
}

void DeviceUnpairWorkExecutor::setGatewayRPC(GatewayRPC *rpc)
{
	m_rpc = rpc == NULL? &NullGatewayRPC::instance() : rpc;
}

bool DeviceUnpairWorkExecutor::accepts(const Work::Ptr work) const
{
	if (work->content().type().is<DeviceUnpairWork>())
		return true;

	return false;
}

void DeviceUnpairWorkExecutor::processResult(Work::Ptr work, DeviceUnpairWork &content)
{
	Gateway gateway(content.gatewayID());
	Device device(content.deviceID());

	switch (content.result()) {
	case GatewayRPCResult::NOT_CONNECTED:
		throw ConnectionAbortedException(
			"failed to unpair device " + device + " on gateway " + gateway);

	case GatewayRPCResult::TIMEOUT:
		throw TimeoutException(
			"failed to unpair device " + device + " on gateway " + gateway);

	case GatewayRPCResult::FAILED:
		throw RuntimeException(
			"failed to unpair device " + device + " on gateway " + gateway);

	case GatewayRPCResult::SUCCESS:
		return;

	default:
		suspend(work);
		break;
	}
}

void DeviceUnpairWorkExecutor::execute(Work::Ptr work)
{
	DeviceUnpairWork content = work->contentAs<DeviceUnpairWork>();

	Device device(content.deviceID());
	const Gateway gateway(content.gatewayID());

	if (!m_dao->fetch(device, gateway)) {
		logger().warning("device "
				+ device
				+ " on gateway "
				+ gateway
				+ " not found during unpair",
				__FILE__, __LINE__);
		return; // treat as success
	}

	if (content.hasResult()) {
		processResult(work, content);
		return;
	}

	WorkScheduler::Ptr scheduler = this->scheduler();
	WorkLockManager::Ptr lockManager = this->lockManager();

	m_rpc->unpairDevice([=](GatewayRPCResult::Ptr result) mutable
		{
			{
				WorkWriteGuard accessGuard(lockManager->readWrite(work->id()));

				// update result of the work
				DeviceUnpairWork content = work->contentAs<DeviceUnpairWork>();
				content.setResult(result->status());
				work->setContent(content);
			}

			switch (result->status()) {
			case GatewayRPCResult::PENDING:
			case GatewayRPCResult::ACCEPTED:
				// TODO persist
				return; // no other action is needed
			default:
				scheduler->wakeup(work);
				break;
			}
		},
		gateway,
		device
	);

	suspend(work);
}
<|endoftext|>