1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-23 23:04:36 +01:00

Add plugin API to get registered plugin metadata (#20709)

* Added API for getAllPlugins

Added functionality to the Scripting API to allow Contexts to return a list of all registered plugins.

* Fixed naming conventions, returning list of authors

Changed function names to follow get/set convention. Removed unnecessary copies of shared pointers, now using auto instead. Changed the functionality to return an array of authors instead of a string.

* Added changelog entry

Also added myself to list of contributors

* Moved all functionality to ScPlugin

Created a ScPlugin class and moved the current getPlugins functionality there.

* Changed from method to property

Function names now match the get/set convention for properties. Also did some code cleanup.

* Update copyright

* Bump plugin version

---------

Co-authored-by: Tulio Leao <tupaschoal@gmail.com>
This commit is contained in:
Alex Parisi
2024-02-16 03:53:48 -05:00
committed by GitHub
parent 04603f5213
commit efb6d48c4c
7 changed files with 104 additions and 2 deletions

View File

@@ -118,6 +118,7 @@ Appreciation for contributors who have provided substantial work, but are no lon
* Wenzhao Qiu (qwzhaox) - Misc.
* Tiago Reul (reul) - Misc.
* Fredrik Tegnell (fredriktegnell) - Misc.
* Alex Parisi (alex-parisi) - Added API for returning metadata from all registered plugins.
## Bug fixes & Refactors
* (KirilAngelov)

View File

@@ -1,5 +1,6 @@
0.4.9 (in development)
------------------------------------------------------------------------
- Feature: [#20709] [Plugin] Plugins can now check metadata from all registered plugins.
- Feature: [#21376] Add option to reload an object (for object developers).
- Improved: [#21356] Resize the title bar when moving between displays with different scaling factors on Windows systems.
- Improved: [#21388] Tooltips will now show even when an error message is present.

View File

@@ -56,7 +56,10 @@ declare global {
* Plugin writers should check if ui is available using `typeof ui !== 'undefined'`.
*/
var ui: Ui;
/**
* APIs for managing the installed plugins
*/
var pluginManager: PluginManager;
/**
* Registers the plugin. This may only be called once.
* @param metadata Information about the plugin and the entry point.
@@ -4948,4 +4951,11 @@ declare global {
getAllObjects(type: "scenery_group"): SceneryGroupObject[];
getAllObjects(type: "music"): LoadedObject[];
}
/**
* Interface to handle the plugin manager
*/
interface PluginManager {
readonly plugins: PluginMetadata[];
}
}

View File

@@ -511,6 +511,7 @@
<ClInclude Include="scripting\bindings\entity\ScPeep.hpp" />
<ClInclude Include="scripting\bindings\entity\ScStaff.hpp" />
<ClInclude Include="scripting\bindings\entity\ScVehicle.hpp" />
<ClInclude Include="scripting\bindings\game\ScPlugin.hpp" />
<ClInclude Include="scripting\bindings\game\ScProfiler.hpp" />
<ClInclude Include="scripting\bindings\network\ScPlayer.hpp" />
<ClInclude Include="scripting\bindings\network\ScPlayerGroup.hpp" />

View File

@@ -34,6 +34,7 @@
# include "bindings/game/ScConsole.hpp"
# include "bindings/game/ScContext.hpp"
# include "bindings/game/ScDisposable.hpp"
# include "bindings/game/ScPlugin.hpp"
# include "bindings/game/ScProfiler.hpp"
# include "bindings/network/ScNetwork.hpp"
# include "bindings/network/ScPlayer.hpp"
@@ -443,6 +444,7 @@ void ScriptEngine::Initialise()
ScScenarioObjective::Register(ctx);
ScPatrolArea::Register(ctx);
ScStaff::Register(ctx);
ScPlugin::Register(ctx);
dukglue_register_global(ctx, std::make_shared<ScCheats>(), "cheats");
dukglue_register_global(ctx, std::make_shared<ScClimate>(), "climate");
@@ -452,6 +454,7 @@ void ScriptEngine::Initialise()
dukglue_register_global(ctx, std::make_shared<ScMap>(ctx), "map");
dukglue_register_global(ctx, std::make_shared<ScNetwork>(ctx), "network");
dukglue_register_global(ctx, std::make_shared<ScPark>(ctx), "park");
dukglue_register_global(ctx, std::make_shared<ScPlugin>(), "pluginManager");
dukglue_register_global(ctx, std::make_shared<ScProfiler>(ctx), "profiler");
dukglue_register_global(ctx, std::make_shared<ScScenario>(), "scenario");
dukglue_register_global(ctx, std::make_shared<ScObjectManager>(), "objectManager");

View File

@@ -47,7 +47,7 @@ namespace OpenRCT2
namespace OpenRCT2::Scripting
{
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 82;
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 83;
// Versions marking breaking changes.
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;

View File

@@ -0,0 +1,86 @@
/*****************************************************************************
* Copyright (c) 2014-2024 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#ifdef ENABLE_SCRIPTING
# include "../../Duktape.hpp"
# include "../../ScriptEngine.h"
# include "../game/ScContext.hpp"
namespace OpenRCT2::Scripting
{
class ScPlugin
{
public:
static void Register(duk_context* ctx)
{
dukglue_register_property(ctx, &ScPlugin::plugins_get, nullptr, "plugins");
}
private:
std::vector<DukValue> plugins_get()
{
auto ctx = getContext();
auto& allPlugins = getallPlugins();
return formatMetadata(ctx, allPlugins);
}
duk_context* getContext()
{
// Get the context from the script engine
OpenRCT2::Scripting::ScriptEngine& scriptEngine = GetContext()->GetScriptEngine();
return scriptEngine.GetContext();
}
const std::vector<std::shared_ptr<OpenRCT2::Scripting::Plugin>> getallPlugins()
{
// Get all of the plugins from the script engine
OpenRCT2::Scripting::ScriptEngine& scriptEngine = GetContext()->GetScriptEngine();
return scriptEngine.GetPlugins();
}
const std::vector<DukValue> formatMetadata(
duk_context* ctx, const std::vector<std::shared_ptr<OpenRCT2::Scripting::Plugin>>& allPlugins)
{
std::vector<DukValue> formattedMetadata;
duk_idx_t dukIdx = DUK_INVALID_INDEX;
// Iterate through all plugins and and cast their data to Duk objects
for (const auto& pluginPtr : allPlugins)
{
// Pull out metadata
OpenRCT2::Scripting::Plugin& plugin = *pluginPtr;
OpenRCT2::Scripting::PluginMetadata metadata = plugin.GetMetadata();
// Create object using Duk stack
dukIdx = duk_push_object(ctx);
// Name and Version
duk_push_string(ctx, metadata.Name.c_str());
duk_put_prop_string(ctx, dukIdx, "name");
duk_push_string(ctx, metadata.Version.c_str());
duk_put_prop_string(ctx, dukIdx, "version");
// Authors
duk_idx_t arrIdx = duk_push_array(ctx);
for (auto [s, idx] = std::tuple{ metadata.Authors.begin(), 0 }; s != metadata.Authors.end(); s++, idx++)
{
auto& str = *s;
duk_push_string(ctx, str.c_str());
duk_put_prop_index(ctx, arrIdx, idx);
}
duk_put_prop_string(ctx, dukIdx, "authors");
// Take from Duk stack
formattedMetadata.push_back(DukValue::take_from_stack(ctx, dukIdx));
dukIdx = DUK_INVALID_INDEX;
}
return formattedMetadata;
}
};
} // namespace OpenRCT2::Scripting
#endif