New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Plugin API #1879
base: develop
Are you sure you want to change the base?
Plugin API #1879
Conversation
if (!existingIds.isEmpty()) { | ||
// TODO: we need to restart when plugins where removed from disk! | ||
} |
Check notice
Code scanning / CodeQL
Futile conditional
bool setEnabled(const QModelIndexList& indexes, Plugin::EnableAction action); | ||
|
||
[[nodiscard]] QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override; | ||
// bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole) override; |
Check notice
Code scanning / CodeQL
Commented-out code
// connect(ui->actionRemoveItem, &QAction::triggered, this, &PluginPage::removeItem); | ||
connect(ui->actionEnableItem, &QAction::triggered, this, &PluginPage::enableItem); | ||
connect(ui->actionDisableItem, &QAction::triggered, this, &PluginPage::disableItem); | ||
// connect(ui->actionViewConfigs, &QAction::triggered, this, &PluginPage::viewConfigs); |
Check notice
Code scanning / CodeQL
Commented-out code
// connect(ui->actionAddItem, &QAction::triggered, this, &PluginPage::addItem); | ||
// connect(ui->actionRemoveItem, &QAction::triggered, this, &PluginPage::removeItem); |
Check notice
Code scanning / CodeQL
Commented-out code
switch (pluginFormatVersion) { | ||
case 1: { | ||
loadV1(root); | ||
return true; | ||
} | ||
default: { | ||
QString newName = "plugin-old.json"; | ||
qWarning() << "Unknown format version when loading plugin info. Existing one will be renamed to" << newName; | ||
// Attempt to rename the old version. | ||
file.rename(newName); | ||
return false; | ||
} | ||
} |
Check notice
Code scanning / CodeQL
No trivial switch statements
switch (column) { | ||
case ActiveColumn: | ||
return m_plugins[row]->enabled() ? Qt::Checked : Qt::Unchecked; | ||
default: | ||
return {}; | ||
} |
Check notice
Code scanning / CodeQL
No trivial switch statements
{ | ||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); | ||
if (m_model->setEnabled(selection.indexes(), Plugin::EnableAction::DISABLE)) { | ||
auto response = CustomMessageBox::selectable(this, "Need Launcher restart", |
Check notice
Code scanning / CodeQL
Unused local variable
{ | ||
auto selection = m_filterModel->mapSelectionToSource(ui->treeView->selectionModel()->selection()); | ||
if (m_model->setEnabled(selection.indexes(), Plugin::EnableAction::TOGGLE)) { | ||
auto response = CustomMessageBox::selectable(this, "Need Launcher restart", |
Check notice
Code scanning / CodeQL
Unused local variable
// protected: | ||
// [[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override; | ||
// [[nodiscard]] bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const override; |
Check notice
Code scanning / CodeQL
Commented-out code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😍 very cool - thank you for spending time on this!
Hmm, that's hard. One thing that's unique to every loader (which are components) is a UID (usually reversed domain), so a QSet of component IDs could be a (less efficient) replacement. In future there may be a way to add loaders to menus without plugins (I think a repository system would be better) - I don't think you should need a plugin to register a new loader type if you went with that sort of system.
Yeah... probably best to have separate PRs to avoid a lot of merge conflicts |
9f88158
to
bc2fbca
Compare
While it's true that a (native) plugin might be a overhead, I still would like to add the ability for a plugin to add an loader type, so developers can reduce the steps for someone to install their stuff to a simple plugin install, which then configures / adds all the things neccessary.
Okay; will then polish this PR, maybe add a thing or two, and make it into a normal one so it can be reviewed properly and merged. |
A first thing I noticed is that you put Win32 and win64 in natives but we also have an arm build and it should make the distinction between mingw and msvc too and for macOS It also needs both x64 and arm64 |
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
… active; just using the first remaining one instead Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Fixed by changing the plugin.json format to specify natives per qt version. Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
Signed-off-by: Mai-Lapyst <67418776+Mai-Lapyst@users.noreply.github.com>
01bf369
to
dfb9975
Compare
Hmm is mingw and msvc that incompatible? I would like to keep down plugin-dev's burden and not require them to compile things more times than strictly neccessary. It's generally a problem currently: since PrismLauncher is distributed twice, once with Qt5 and once with Qt6, it would be needed to compile the plugin once for each qt version, and that is without any custom rendering hook's or similar. Because of that it might be a better way to map out what plugins should be able to accomplish. I.e. should we allow them to create their own ui elements, can we get away with ui custimisation by a declarative approach and only require a native library for API requests or file handling and so on. |
Note that we don't have a x32/qt5 build anymore on windows and we're probably gonna drop qt5 soon-ish |
This PR contains a first design and POC of a plugin API for PrismLauncher; related to #1240.
The current draft implements a few things:
To test things out i've created a test plugin over here: https://github.com/Mai-Lapyst/prism-test-plugin
The design
The basic idea behind this version of a plugin API is to make plugins as much as possible data driven. Here's an example
plugin.json
:A data driven approach was picked to reduce developer burden for writing a complete C++ native plugin, compiling it for every platform (OS + Processor) only to do basic tasks. This also prevents bugs where plugins might not register / deregister everything correctly and thus become not completly unloadable without a restart (currently WIP). This also minimalizes entrypoints for malicious code an thus improving security for simple plugins.
The next steps
To further extend the API, there is unfortunatly a rather large set of edits needed to the core structure of the launcher. For example: modplatforms all extend a basic page but it would be against the data driven approach to requiring every plugin that wants to add a modplatform to implement it themself, potentially breaking the UI/UX design of the launcher too. Loaders are completly NOT extensible since it's internally represented trough a compile-time enum.
To further work on this, it needs to be decided how these and similar issues are solved, and if this should be done in this PR, making it potentially VERY huge, or to do it incrementally by reworking the internals with each plugin extension point added.