core: change the component arguments to be WpSpaJson instead of GVariant

This allows us to pass entire JSON objects from the config file
down to the modules / scripts without any conversion
This commit is contained in:
George Kiagiadakis 2023-05-25 18:29:58 +03:00
parent d755ec4f20
commit 5c3032c064
20 changed files with 63 additions and 59 deletions

View file

@ -31,7 +31,7 @@ WP_DEFINE_LOCAL_LOG_TOPIC ("wp-comp-loader")
*/
#define WP_MODULE_INIT_SYMBOL "wireplumber__module_init"
typedef GObject *(*WpModuleInitFunc) (WpCore *, GVariant *, GError **);
typedef GObject *(*WpModuleInitFunc) (WpCore *, WpSpaJson *, GError **);
G_DEFINE_ABSTRACT_TYPE (WpComponentLoader, wp_component_loader, WP_TYPE_PLUGIN)
@ -47,7 +47,7 @@ wp_component_loader_class_init (WpComponentLoaderClass * klass)
static GObject *
load_module (WpCore * core, const gchar * module_name,
GVariant * args, GError ** error)
WpSpaJson * args, GError ** error)
{
g_autofree gchar *module_path = NULL;
GModule *gmodule;
@ -99,7 +99,7 @@ wp_component_loader_find (WpCore * core, const gchar * type)
static void
wp_component_loader_load (WpComponentLoader * self, const gchar * component,
const gchar * type, GVariant * args, GAsyncReadyCallback callback,
const gchar * type, WpSpaJson * args, GAsyncReadyCallback callback,
gpointer data)
{
g_return_if_fail (WP_IS_COMPONENT_LOADER (self));
@ -132,17 +132,16 @@ on_object_loaded (WpObject *object, GAsyncResult *res, gpointer data)
* \param self the core
* \param component the module name or file name
* \param type the type of the component
* \param args (transfer floating)(nullable): additional arguments for the component,
* usually a dict or a string
* \param args (transfer none)(nullable): additional arguments for the component,
* expected to be a JSON object
* \param callback (scope async): the callback to call when the operation is done
* \param data (closure): data to pass to \a callback
*/
void
wp_core_load_component (WpCore * self, const gchar * component,
const gchar * type, GVariant * args, GAsyncReadyCallback callback,
const gchar * type, WpSpaJson * args, GAsyncReadyCallback callback,
gpointer data)
{
g_autoptr (GVariant) args_ref = args ? g_variant_ref_sink (args) : NULL;
g_autoptr (GTask) task = NULL;
g_autoptr (WpComponentLoader) c = NULL;
@ -153,7 +152,7 @@ wp_core_load_component (WpCore * self, const gchar * component,
g_autoptr (GObject) o = NULL;
/* load Module */
o = load_module (self, component, args_ref, &error);
o = load_module (self, component, args, &error);
if (!o) {
g_task_return_error (task, g_steal_pointer (&error));
return;

View file

@ -10,6 +10,7 @@
#define __WIREPLUMBER_COMPONENT_LOADER_H__
#include "plugin.h"
#include "spa-json.h"
G_BEGIN_DECLS
@ -29,7 +30,7 @@ struct _WpComponentLoaderClass
gboolean (*supports_type) (WpComponentLoader * self, const gchar * type);
void (*load) (WpComponentLoader * self, const gchar * component,
const gchar * type, GVariant * args, GAsyncReadyCallback callback,
const gchar * type, WpSpaJson * args, GAsyncReadyCallback callback,
gpointer data);
/*< private >*/

View file

@ -12,6 +12,7 @@
#include <gio/gio.h>
#include "defs.h"
#include "properties.h"
#include "spa-json.h"
G_BEGIN_DECLS
@ -49,7 +50,7 @@ gchar *wp_core_get_vm_type (WpCore *self);
WP_API
void wp_core_load_component (WpCore * self, const gchar * component,
const gchar * type, GVariant * args, GAsyncReadyCallback callback,
const gchar * type, WpSpaJson * args, GAsyncReadyCallback callback,
gpointer data);
WP_API

View file

@ -307,7 +307,7 @@ wp_default_nodes_api_class_init (WpDefaultNodesApiClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_default_nodes_api_get_type (),
"name", "default-nodes-api",

View file

@ -204,7 +204,7 @@ wp_file_monitor_api_class_init (WpFileMonitorApiClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_file_monitor_api_get_type (),
"name", "file-monitor-api",

View file

@ -134,7 +134,7 @@ wp_logind_class_init (WpLogindClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_logind_get_type (),
"name", NAME,

View file

@ -173,7 +173,7 @@ on_script_loaded (WpObject *object, GAsyncResult *res, gpointer data)
static void
wp_lua_scripting_plugin_load (WpComponentLoader * cl, const gchar * component,
const gchar * type, GVariant * args, GAsyncReadyCallback callback,
const gchar * type, WpSpaJson * args, GAsyncReadyCallback callback,
gpointer data)
{
WpLuaScriptingPlugin * self = WP_LUA_SCRIPTING_PLUGIN (cl);
@ -238,7 +238,7 @@ wp_lua_scripting_plugin_class_init (WpLuaScriptingPluginClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_lua_scripting_plugin_get_type (),
"name", "lua-scripting",

View file

@ -29,7 +29,7 @@ struct _WpLuaScript
lua_State *L;
gchar *filename;
GVariant *args;
WpSpaJson *args;
};
enum {
@ -64,7 +64,7 @@ wp_lua_script_finalize (GObject * object)
wp_lua_script_cleanup (self);
g_clear_pointer (&self->L, wplua_unref);
g_clear_pointer (&self->filename, g_free);
g_clear_pointer (&self->args, g_variant_unref);
g_clear_pointer (&self->args, wp_spa_json_unref);
G_OBJECT_CLASS (wp_lua_script_parent_class)->finalize (object);
}
@ -86,7 +86,7 @@ wp_lua_script_set_property (GObject * object, guint property_id,
self->filename = g_value_dup_string (value);
break;
case PROP_ARGUMENTS:
self->args = g_value_dup_variant (value);
self->args = g_value_dup_boxed (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@ -231,7 +231,7 @@ wp_lua_script_enable (WpPlugin * plugin, WpTransition * transition)
/* push script arguments */
if (self->args) {
wplua_gvariant_to_lua (self->L, self->args);
wplua_pushboxed (self->L, WP_TYPE_SPA_JSON, wp_spa_json_ref (self->args));
nargs++;
}
@ -282,7 +282,7 @@ wp_lua_script_class_init (WpLuaScriptClass * klass)
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_ARGUMENTS,
g_param_spec_variant ("arguments", "arguments", "arguments",
G_VARIANT_TYPE_VARDICT, NULL,
g_param_spec_boxed ("arguments", "arguments", "arguments",
WP_TYPE_SPA_JSON,
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
}

View file

@ -30,6 +30,7 @@ _wplua_gboxed___index (lua_State *L)
"expected userdata storing GValue<GBoxed>");
GValue *obj_v = lua_touserdata (L, 1);
const gchar *key = luaL_checkstring (L, 2);
GType type = G_VALUE_TYPE (obj_v);
lua_CFunction func = NULL;
GHashTable *vtables;
@ -39,15 +40,15 @@ _wplua_gboxed___index (lua_State *L)
lua_pop (L, 1);
/* search in registered vtables */
if (!func) {
GType type = G_VALUE_TYPE (obj_v);
while (!func && type) {
luaL_Reg *reg = g_hash_table_lookup (vtables, GUINT_TO_POINTER (type));
func = find_method_in_luaL_Reg (reg, key);
type = g_type_parent (type);
}
while (!func && type) {
luaL_Reg *reg = g_hash_table_lookup (vtables, GUINT_TO_POINTER (type));
func = find_method_in_luaL_Reg (reg, key);
type = g_type_parent (type);
}
wp_trace_boxed (type, g_value_get_boxed (obj_v),
"indexing GBoxed, looking for '%s', found: %p", key, func);
if (func) {
lua_pushcfunction (L, func);
return 1;

View file

@ -617,7 +617,7 @@ wp_mixer_api_class_init (WpMixerApiClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_mixer_api_get_type (),
"name", "mixer-api",

View file

@ -305,7 +305,7 @@ wp_portal_permissionstore_plugin_class_init (
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (
wp_portal_permissionstore_plugin_get_type(),

View file

@ -267,7 +267,7 @@ wp_reserve_device_plugin_class_init (WpReserveDevicePluginClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_reserve_device_plugin_get_type (),
"name", "reserve-device",

View file

@ -339,15 +339,15 @@ wp_settings_plugin_class_init (WpSettingsPluginClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
const gchar *metadata_name = "sm-settings";
g_autofree gchar *metadata_name = NULL;
if (args)
metadata_name = g_variant_get_string (args, NULL);
wp_spa_json_object_get (args, "metadata-name", "s", &metadata_name, NULL);
return G_OBJECT (g_object_new (wp_settings_plugin_get_type (),
"name", "settings",
"core", core,
"metadata-name", metadata_name,
"metadata-name", metadata_name ? metadata_name : "sm-settings",
NULL));
}

View file

@ -780,7 +780,7 @@ si_audio_adapter_linkable_init (WpSiLinkableInterface * iface)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (wp_si_factory_new_simple (SI_FACTORY_NAME,
si_audio_adapter_get_type ()));

View file

@ -358,7 +358,7 @@ si_audio_virtual_adapter_init (WpSiAdapterInterface * iface)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (wp_si_factory_new_simple (SI_FACTORY_NAME,
si_audio_virtual_get_type ()));

View file

@ -222,7 +222,7 @@ si_node_linkable_init (WpSiLinkableInterface * iface)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (wp_si_factory_new_simple (SI_FACTORY_NAME,
si_node_get_type ()));

View file

@ -778,7 +778,7 @@ si_standard_link_link_init (WpSiLinkInterface * iface)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (wp_si_factory_new_simple (SI_FACTORY_NAME,
si_standard_link_get_type ()));

View file

@ -452,7 +452,7 @@ wp_standard_event_source_class_init (WpStandardEventSourceClass * klass)
}
WP_PLUGIN_EXPORT GObject *
wireplumber__module_init (WpCore * core, GVariant * args, GError ** error)
wireplumber__module_init (WpCore * core, WpSpaJson * args, GError ** error)
{
return G_OBJECT (g_object_new (wp_standard_event_source_get_type (),
"name", "standard-event-source",

View file

@ -27,8 +27,8 @@ enum WpExitCode
};
static gchar * exec_script = NULL;
static GVariantBuilder exec_args_b =
G_VARIANT_BUILDER_INIT (G_VARIANT_TYPE_VARDICT);
static gchar *exec_args_s = NULL;
static WpSpaJson *exec_args = NULL;
static gboolean
parse_exec_script_arg (const gchar *option_name, const gchar *value,
@ -40,16 +40,17 @@ parse_exec_script_arg (const gchar *option_name, const gchar *value,
return TRUE;
}
g_auto(GStrv) tokens = g_strsplit (value, "=", 2);
if (!tokens[0] || *g_strstrip (tokens[0]) == '\0') {
g_set_error (error, WP_DOMAIN_DAEMON, WP_EXIT_USAGE,
"invalid script argument '%s'; must be in key=value format", value);
return FALSE;
/* the second argument is a json object with script arguments */
if (!exec_args) {
exec_args_s = g_strdup (value);
exec_args = wp_spa_json_new_from_string (exec_args_s);
if (!exec_args || !wp_spa_json_is_object (exec_args)) {
g_set_error (error, WP_DOMAIN_DAEMON, WP_EXIT_USAGE,
"script argument must be a JSON object");
return FALSE;
}
}
g_variant_builder_add (&exec_args_b, "{sv}", tokens[0], tokens[1] ?
g_variant_new_string (g_strstrip (tokens[1])) :
g_variant_new_boolean (TRUE));
return TRUE;
}
@ -146,8 +147,7 @@ wp_init_transition_execute_step (WpTransition * transition, guint step)
}
case STEP_ACTIVATE_SCRIPT: {
GVariant *args = g_variant_builder_end (&exec_args_b);
wp_core_load_component (core, exec_script, "script/lua", args,
wp_core_load_component (core, exec_script, "script/lua", exec_args,
(GAsyncReadyCallback) on_plugin_loaded, self);
break;
}

View file

@ -10,21 +10,23 @@
-- This is an example of an interactive script
--
-- Execute with:
-- wpexec ./interactive.lua option1=value1 option2=value2 ...
-- wpexec ./interactive.lua '{ option1 = "value1" , option2 = "value2" }' ...
-- or:
-- ./interactive.lua option1=value1 option2=value2
-- ./interactive.lua '{ option1 = "value1" , option2 = "value2" }'
-----------------------------------------------------------------------------
--
-- Collects arguments passed in from the command line
-- Assuming option1=value1 option2=value2 were passed, this will be a table
-- like this: { ["option1"] = "value1", ["option2"] = "value2" }
-- Assuming '{ option1 = "value1" , option2 = "value2" }' were passed,
-- this will be a table like this:
-- { ["option1"] = "value1", ["option2"] = "value2" }
--
local argv = ...
if argv then
argv = argv:parse()
print ("Command-line arguments:")
for k, v in pairs(argv) do
print ("\t" .. k .. ": " .. v)
print ("Command-line arguments:")
Debug.dump_table (argv)
end
--