Merge pull request #58 from Holt59/modlist-setactive-bulk

Fix bindings of IModList::setActive.
This commit is contained in:
Al
2020-09-01 03:59:32 -07:00
committed by GitHub
3 changed files with 84 additions and 4 deletions
+22 -4
View File
@@ -59,7 +59,6 @@ namespace mp11 = boost::mp11;
return bpy::object{ (QClass*)w }.attr(str); \
})
BOOST_PYTHON_MODULE(mobase)
{
PyEval_InitThreads();
@@ -111,7 +110,8 @@ BOOST_PYTHON_MODULE(mobase)
utils::register_associative_container<QMap<QString, QVariant>>(); // Required for QVariant since this is QVariantMap.
utils::register_associative_container<QMap<QString, QStringList>>();
utils::register_associative_container<std::map<QString, IModList::ModStates>>();
utils::register_associative_container<IFileTree::OverwritesType>();
// Tuple:
@@ -132,7 +132,7 @@ BOOST_PYTHON_MODULE(mobase)
utils::register_functor_converter<void(const QString&)>();
utils::register_functor_converter<void(const QString&, unsigned int)>();
utils::register_functor_converter<void(const QString&, int, int)>(); // converter for the onModMoved-callback and onPluginMoved callbacks
utils::register_functor_converter<void(const QString&, IModList::ModStates)>(); // converter for the onModStateChanged-callback (IModList)
utils::register_functor_converter<void(const std::map<QString, IModList::ModStates>&)>(); // converter for the onModStateChanged-callback (IModList)
utils::register_functor_converter<void(const QString&, IPluginList::PluginStates)>(); // converter for the onPluginStateChanged-callback (IPluginList)
utils::register_functor_converter<void(const QString&, const QString&, const QVariant&, const QVariant&)>();
utils::register_functor_converter<void(QMainWindow*)>();
@@ -143,6 +143,9 @@ BOOST_PYTHON_MODULE(mobase)
utils::register_functor_converter<bool(std::shared_ptr<FileTreeEntry> const&)>();
utils::register_functor_converter<std::variant<QString, bool>(QString const&)>();
// This one is kept for backward-compatibility while we deprecate onModStateChanged for singl mod.
utils::register_functor_converter<void(const QString&, IModList::ModStates)>(); // converter for the onModStateChanged-callback (IModList).
//
// Class declarations:
//
@@ -646,9 +649,24 @@ BOOST_PYTHON_MODULE(mobase)
.def("displayName", &MOBase::IModList::displayName, bpy::arg("name"))
.def("allMods", &MOBase::IModList::allMods)
.def("state", &MOBase::IModList::state, bpy::arg("name"))
.def("setActive", &MOBase::IModList::setActive, (bpy::arg("name"), "active"))
.def("setActive",
static_cast<int(IModList::*)(QStringList const&, bool)>(&MOBase::IModList::setActive), (bpy::arg("names"), "active"))
.def("setActive",
static_cast<bool(IModList::*)(QString const&, bool)>(&MOBase::IModList::setActive), (bpy::arg("name"), "active"))
.def("priority", &MOBase::IModList::priority, bpy::arg("name"))
.def("setPriority", &MOBase::IModList::setPriority, (bpy::arg("name"), "priority"))
// Kept but deprecated for backward compatibility:
.def("onModStateChanged", +[](IModList* modList, const std::function<void(const QString&, IModList::ModStates)>& fn) {
utils::show_deprecation_warning("onModStateChanged",
"onModStateChanged(Callable[[str, IModList.ModStates], None]) is deprecated, "
"use onModStateChanged(Callable[[Dict[str, IModList.ModStates], None]) instead.");
return modList->onModStateChanged([fn](auto const& map) {
for (const auto& entry : map) {
fn(entry.first, entry.second);
}
});
}, bpy::arg("callback"))
.def("onModStateChanged", &MOBase::IModList::onModStateChanged, bpy::arg("callback"))
.def("onModMoved", &MOBase::IModList::onModMoved, bpy::arg("callback"))
;
+46
View File
@@ -0,0 +1,46 @@
#include "pythonutils.h"
#include <filesystem>
#include <set>
#include <QCoreApplication>
#include "log.h"
namespace utils {
void show_deprecation_warning(std::string_view name, std::string_view message, bool show_once) {
// Contains the list of filename / line number for which a deprecation warning has already been shown.
static std::set<std::pair<std::string, int>> DeprecatedLines;
// Find the caller:
auto inspect = bpy::import("inspect");
auto current_frame = inspect.attr("currentframe")();
auto callable_frame = inspect.attr("getouterframes")(current_frame, 2);
auto filename = bpy::extract<std::string>(callable_frame[-1].attr("filename"))();
auto function = bpy::extract<std::string>(callable_frame[-1].attr("function"))();
auto lineno = bpy::extract<int>(callable_frame[-1].attr("lineno"));
// Only show once if requested:
if (show_once && DeprecatedLines.contains({ filename, lineno })) {
return;
}
// Register the deprecation:
DeprecatedLines.emplace(filename, lineno);
auto path = relative(std::filesystem::path(filename), QCoreApplication::applicationDirPath().toStdWString());
// Show the message:
if (message.empty()) {
MOBase::log::warn(
"[deprecated] {} in {} [{}:{}].", name, function, path.native(), lineno);
}
else {
MOBase::log::warn(
"[deprecated] {} in {} [{}:{}]: {}", name, function, path.native(), lineno, message);
}
}
}
+16
View File
@@ -3,6 +3,8 @@
#include <boost/python.hpp>
#include "error.h"
namespace utils {
namespace bpy = boost::python;
@@ -195,6 +197,20 @@ namespace utils {
, bpy::type_id<Container>());
};
/**
* @brief Show a deprecation warning.
*
* This methods will print a warning in MO2 log containing the location of the call to
* the deprecated function. If show_once is true, the deprecation warning will only be
* logged the first time the function is called at this location.
*
* @param name Name of the deprecated function.
* @param message Deprecation message.
* @param show_once Only show the message once per call location.
*/
void show_deprecation_warning(std::string_view name, std::string_view message = "", bool show_once = true);
}
#endif