summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--logic/main-settings.cpp7
-rw-r--r--migration/20180428_00-module-names.cpp84
-rw-r--r--options/tie.hpp94
-rw-r--r--variant/default/main-window.cpp106
-rw-r--r--variant/default/main-window.hpp21
5 files changed, 222 insertions, 90 deletions
diff --git a/logic/main-settings.cpp b/logic/main-settings.cpp
index c735ac6e..53a5054c 100644
--- a/logic/main-settings.cpp
+++ b/logic/main-settings.cpp
@@ -49,9 +49,9 @@ main_settings::main_settings() :
module_settings::module_settings() :
b(make_bundle("modules")),
- tracker_dll(b, "tracker-dll", "PointTracker 1.1"),
- filter_dll(b, "filter-dll", "Accela"),
- protocol_dll(b, "protocol-dll", "freetrack 2.0 Enhanced")
+ tracker_dll(b, "tracker-dll", "pt"),
+ filter_dll(b, "filter-dll", "accela"),
+ protocol_dll(b, "protocol-dll", "freetrack")
{
}
@@ -60,3 +60,4 @@ key_opts::key_opts(bundle b, const QString& name) :
guid(b, QString("guid-%1").arg(name), ""),
button(b, QString("button-%1").arg(name), -1)
{}
+
diff --git a/migration/20180428_00-module-names.cpp b/migration/20180428_00-module-names.cpp
new file mode 100644
index 00000000..fbb7a161
--- /dev/null
+++ b/migration/20180428_00-module-names.cpp
@@ -0,0 +1,84 @@
+#include "migration.hpp"
+#include "options/options.hpp"
+
+using namespace migrations;
+using namespace options;
+
+#include "api/plugin-support.hpp"
+#include "compat/library-path.hpp"
+
+struct module_names : migration
+{
+ using dylib_ptr = Modules::dylib_ptr;
+ using dylib_list = Modules::dylib_list;
+
+ QString unique_date() const override
+ {
+ return "20180428_00";
+ }
+
+ QString name() const override
+ {
+ return "module names";
+ }
+
+ bool should_run() const override
+ {
+ return true;
+ }
+
+ void run() override
+ {
+ struct module_type {
+ QString name, def;
+ dylib_list const& list;
+ };
+
+ Modules m { OPENTRACK_BASE_PATH + OPENTRACK_LIBRARY_PATH };
+
+ module_type types[3] {
+ { "tracker-dll", "pt", m.trackers() },
+ { "protocol-dll", "freetrack", m.protocols() },
+ { "filter-dll", "accela", m.filters() },
+ };
+
+ bundle b = make_bundle("modules");
+
+ for (module_type& type : types)
+ {
+ QByteArray n = type.name.toUtf8();
+
+ if (!b->contains(type.name))
+ {
+ qDebug() << n.constData() << "=>" << "EMPTY";
+ b->store_kv(type.name, type.def);
+ continue;
+ }
+
+ QString value = b->get<QString>(type.name);
+
+ bool found = false;
+
+ for (dylib_ptr lib : type.list)
+ {
+ if (value == lib->name)
+ {
+ qDebug() << n.constData() << "=>" << lib->module_name;
+ b->store_kv(type.name, lib->module_name);
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ qDebug() << n.constData() << "=>" << "not found" << value;
+ b->store_kv(type.name, type.def);
+ }
+ }
+
+ b->save();
+ }
+};
+
+OPENTRACK_MIGRATION(module_names);
diff --git a/options/tie.hpp b/options/tie.hpp
index 307f5930..ca5eae5e 100644
--- a/options/tie.hpp
+++ b/options/tie.hpp
@@ -8,12 +8,10 @@
#pragma once
-#include "value-traits.hpp"
+#include "export.hpp"
#include "value.hpp"
#include "compat/run-in-thread.hpp"
-#include "compat/macros.hpp"
-
-#include <type_traits>
+#include "compat/meta.hpp"
#include <QComboBox>
#include <QCheckBox>
@@ -26,8 +24,6 @@
#include <cmath>
-#include "export.hpp"
-
#if defined __GNUG__
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wattributes"
@@ -35,67 +31,48 @@
namespace options {
-namespace detail {
-
template<typename t>
-struct tie_setting_traits_helper
-{
- using traits = detail::value_traits<t>;
- using value_type = typename traits::value_type;
- using element_type = typename traits::element_type;
-
- static element_type to_element_type(const value<t>& v)
- {
- return static_cast<element_type>(static_cast<value_type>(v));
- }
-};
-
-template<typename t, typename Enable = void>
-struct tie_setting_traits final : tie_setting_traits_helper<t>
+std::enable_if_t<std::is_enum_v<t>> tie_setting(value<t>& v, QComboBox* cb)
{
- static constexpr inline bool should_bind_to_itemdata() { return false; }
-};
-
-template<typename t>
-struct tie_setting_traits<t, std::enable_if_t<std::is_enum_v<t>>> : tie_setting_traits_helper<t>
-{
- static constexpr inline bool should_bind_to_itemdata() { return true; }
-
- static t itemdata_to_value(int, const QVariant& var)
- {
- return static_cast<t>(var.toInt());
- }
-};
-
-} // ns options::detail
-
-template<typename t, typename traits_type = detail::tie_setting_traits<t>>
-std::enable_if_t<traits_type::should_bind_to_itemdata()>
-tie_setting(value<t>& v, QComboBox* cb, const traits_type& traits = traits_type())
-{
- using element_type = typename detail::value_traits<t>::element_type;
-
- cb->setCurrentIndex(cb->findData(traits.to_element_type(v)));
- v = traits.itemdata_to_value(cb->currentIndex(), cb->currentData());
+ cb->setCurrentIndex(cb->findData(int(static_cast<t>(v))));
+ v = static_cast<t>(cb->currentData().toInt());
base_value::connect(cb,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
- &v,
- [&v, cb, traits](int idx)
- {
- run_in_thread_sync(cb,
- [&, traits]() {
- v = traits.itemdata_to_value(idx, cb->currentData());
- });
- },
- v.DIRECT_CONNTYPE);
- base_value::connect(&v, base_value::value_changed<element_type>(),
+ &v, [&v, cb](int idx) {
+ run_in_thread_sync(cb, [&]() {
+ v = static_cast<t>(cb->itemData(idx).toInt());
+ });
+ },
+ v.DIRECT_CONNTYPE);
+
+ base_value::connect(&v, base_value::value_changed<int>(),
cb, [cb](int x) {
- run_in_thread_sync(cb, [&]() { cb->setCurrentIndex(cb->findData(x)); });
+ run_in_thread_sync(cb, [=]() { cb->setCurrentIndex(cb->findData(x)); });
},
v.DIRECT_CONNTYPE);
}
+template<typename t, typename From, typename To>
+void tie_setting(value<t>& v, QComboBox* cb, From&& fn_to_index, To&& fn_to_value)
+{
+ cb->setCurrentIndex(fn_to_index(v));
+ v = fn_to_value(cb->currentIndex(), cb->currentData());
+
+ base_value::connect(cb, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ &v, [&v, cb, fn_to_value](int idx) {
+ run_in_thread_sync(cb, [&]() {
+ v = fn_to_value(idx, cb->currentData());
+ });
+ }, v.DIRECT_CONNTYPE);
+ base_value::connect(&v, base_value::value_changed<t>(),
+ cb, [&v, cb, fn_to_index](cv_qualified<t>& v) {
+ run_in_thread_sync(cb, [&]() {
+ cb->setCurrentIndex(fn_to_index(v));
+ });
+ });
+}
+
template<typename t, typename F>
void tie_setting(value<t>& v, QLabel* lb, F&& fun)
{
@@ -120,9 +97,6 @@ void tie_setting(value<t>& v, QObject* obj, F&& fun)
v.DIRECT_CONNTYPE);
}
-// XXX TODO add combobox transform both ways via std::function
-// need for non-translated `module_settings' dylib names
-
OTR_OPTIONS_EXPORT void tie_setting(value<int>& v, QComboBox* cb);
OTR_OPTIONS_EXPORT void tie_setting(value<QString>& v, QComboBox* cb);
OTR_OPTIONS_EXPORT void tie_setting(value<QVariant>& v, QComboBox* cb);
diff --git a/variant/default/main-window.cpp b/variant/default/main-window.cpp
index 62b969e1..c52a806e 100644
--- a/variant/default/main-window.cpp
+++ b/variant/default/main-window.cpp
@@ -17,6 +17,8 @@
#include "compat/library-path.hpp"
#include "compat/math.hpp"
+#include <iterator>
+
#include <QMessageBox>
#include <QDesktopServices>
#include <QDir>
@@ -82,7 +84,7 @@ main_window::main_window() :
if (!refresh_config_list())
{
- exit(64);
+ exit(EX_OSFILE);
return;
}
@@ -97,16 +99,16 @@ main_window::main_window() :
// fill dylib comboboxen
{
- modules.filters().push_front(std::make_shared<dylib>("", dylib::Filter));
+ modules.filters().push_front(std::make_shared<dylib>(QString(), dylib::Filter));
- for (std::shared_ptr<dylib>& x : modules.trackers())
- ui.iconcomboTrackerSource->addItem(x->icon, x->name);
+ for (dylib_ptr& x : modules.trackers())
+ ui.iconcomboTrackerSource->addItem(x->icon, x->name, x->module_name);
- for (std::shared_ptr<dylib>& x : modules.protocols())
- ui.iconcomboProtocol->addItem(x->icon, x->name);
+ for (dylib_ptr& x : modules.protocols())
+ ui.iconcomboProtocol->addItem(x->icon, x->name, x->module_name);
- for (std::shared_ptr<dylib>& x : modules.filters())
- ui.iconcomboFilter->addItem(x->icon, x->name);
+ for (dylib_ptr& x : modules.filters())
+ ui.iconcomboFilter->addItem(x->icon, x->name, x->module_name);
}
// timers
@@ -155,13 +157,48 @@ main_window::main_window() :
this,
[&](const QString&) { if (pFilterDialog) pFilterDialog = nullptr; });
- connect(&m.tracker_dll, base_value::value_changed<QString>(), this, &main_window::save_modules, Qt::DirectConnection);
- connect(&m.protocol_dll, base_value::value_changed<QString>(), this, &main_window::save_modules, Qt::DirectConnection);
- connect(&m.filter_dll, base_value::value_changed<QString>(), this, &main_window::save_modules, Qt::DirectConnection);
+ connect(&m.tracker_dll, base_value::value_changed<QString>(),
+ this, &main_window::save_modules,
+ Qt::DirectConnection);
+
+ connect(&m.protocol_dll, base_value::value_changed<QString>(),
+ this, &main_window::save_modules,
+ Qt::DirectConnection);
- tie_setting(m.tracker_dll, ui.iconcomboTrackerSource);
- tie_setting(m.protocol_dll, ui.iconcomboProtocol);
- tie_setting(m.filter_dll, ui.iconcomboFilter);
+ connect(&m.filter_dll, base_value::value_changed<QString>(),
+ this, &main_window::save_modules,
+ Qt::DirectConnection);
+
+ {
+ struct list {
+ dylib_list& libs;
+ QComboBox* input;
+ value<QString>& place;
+ };
+
+ list types[] {
+ { modules.trackers(), ui.iconcomboTrackerSource, m.tracker_dll },
+ { modules.protocols(), ui.iconcomboProtocol, m.protocol_dll },
+ { modules.filters(), ui.iconcomboFilter, m.filter_dll },
+ };
+
+ for (list& type : types)
+ {
+ list& t = type;
+ tie_setting(t.place, t.input,
+ [t](const QString& name) {
+ auto [ptr, idx] = module_by_name(name, t.libs);
+ return idx;
+ },
+ [t](int, const QVariant& userdata) {
+ auto [ptr, idx] = module_by_name(userdata.toString(), t.libs);
+ if (ptr)
+ return ptr->module_name;
+ else
+ return QString();
+ });
+ }
+ }
}
connect(this, &main_window::start_tracker,
@@ -461,6 +498,39 @@ bool main_window::refresh_config_list()
return true;
}
+std::tuple<main_window::dylib_ptr, int> main_window::module_by_name(const QString& name, Modules::dylib_list& list)
+{
+ auto it = std::find_if(list.cbegin(), list.cend(), [&name](const dylib_ptr& lib) {
+ if (!lib)
+ return name.isEmpty();
+ else
+ return name == lib->module_name;
+ });
+
+ if (it == list.cend())
+ return { nullptr, -1 };
+ else
+ return { *it, int(std::distance(list.cbegin(), it)) };
+}
+
+main_window::dylib_ptr main_window::current_tracker()
+{
+ auto [ptr, idx] = module_by_name(m.tracker_dll, modules.trackers());
+ return ptr;
+}
+
+main_window::dylib_ptr main_window::current_protocol()
+{
+ auto [ptr, idx] = module_by_name(m.protocol_dll, modules.protocols());
+ return ptr;
+}
+
+main_window::dylib_ptr main_window::current_filter()
+{
+ auto [ptr, idx] = module_by_name(m.filter_dll, modules.filters());
+ return ptr;
+}
+
void main_window::update_button_state(bool running, bool inertialp)
{
bool not_running = !running;
@@ -718,13 +788,19 @@ bool main_window::set_profile(const QString& new_name_)
ui.iconcomboProfile->setCurrentText(new_name);
set_profile_in_registry(new_name);
- set_title();
+ // XXX workaround migration breakage -sh 20180428
+ QSignalBlocker b1(ui.iconcomboTrackerSource);
+ QSignalBlocker b2(ui.iconcomboProtocol);
+ QSignalBlocker b3(ui.iconcomboFilter);
+
options::detail::bundler::refresh_all_bundles();
// migrations are for config layout changes and other user-visible
// incompatibilities in future versions
run_migrations();
+ set_title();
+
return true;
}
diff --git a/variant/default/main-window.hpp b/variant/default/main-window.hpp
index c28aadc4..6e85a13c 100644
--- a/variant/default/main-window.hpp
+++ b/variant/default/main-window.hpp
@@ -32,6 +32,7 @@
#include <QEvent>
#include <QCloseEvent>
+#include <algorithm>
#include <vector>
#include <tuple>
#include <memory>
@@ -72,18 +73,14 @@ class main_window : public QMainWindow, private State
menu_action_options { &tray_menu },
menu_action_mappings { &tray_menu };
- std::shared_ptr<dylib> current_tracker()
- {
- return modules.trackers().value(ui.iconcomboTrackerSource->currentIndex(), nullptr);
- }
- std::shared_ptr<dylib> current_protocol()
- {
- return modules.protocols().value(ui.iconcomboProtocol->currentIndex(), nullptr);
- }
- std::shared_ptr<dylib> current_filter()
- {
- return modules.filters().value(ui.iconcomboFilter->currentIndex(), nullptr);
- }
+ using dylib_ptr = Modules::dylib_ptr;
+ using dylib_list = Modules::dylib_list;
+
+ static std::tuple<dylib_ptr, int> module_by_name(const QString& name, Modules::dylib_list& list);
+
+ dylib_ptr current_tracker();
+ dylib_ptr current_protocol();
+ dylib_ptr current_filter();
void update_button_state(bool running, bool inertialp);
void display_pose(const double* mapped, const double* raw);