[gupnp/wip/phako/46: 3/3] Make ServiceIntrospection introspectable




commit a98644226aa9604ae806e3d755d66a04bea4241e
Author: Jens Georg <mail jensge org>
Date:   Mon May 17 23:42:52 2021 +0200

    Make ServiceIntrospection introspectable
    
    Fixes #46

 examples/get-volume.js                 | 25 ++++++++++------
 libgupnp/gupnp-service-introspection.c | 52 +++++++++++++++++++++++++++++-----
 libgupnp/gupnp-service-introspection.h | 11 +++++++
 3 files changed, 73 insertions(+), 15 deletions(-)
---
diff --git a/examples/get-volume.js b/examples/get-volume.js
index b8118f9..caa5269 100755
--- a/examples/get-volume.js
+++ b/examples/get-volume.js
@@ -31,20 +31,28 @@ imports.gi.versions.GUPnP = "1.2"
 const Mainloop = imports.mainloop;
 const GObject = imports.gi.GObject;
 const GUPnP = imports.gi.GUPnP;
+const GLib = imports.gi.GLib;
 
 const CONTENT_DIR = "urn:schemas-upnp-org:service:RenderingControl:1";
 
-function _on_ready () {
+function _on_service_introspection(proxy, res) {
+    let result = proxy.introspect_finish(res);
+    let action_info = result.get_action("GetVolume")
+    let state_variable_name = action_info.arguments[1].related_state_variable;
+
+    let channel = result.get_state_variable (state_variable_name);
+
+    print ("Calling GetVolume for channel ", channel.allowed_values[0]);
+    let action = GUPnP.ServiceProxyAction.new_from_list("GetVolume", ["InstanceId", "Channel"], [0, 
channel.allowed_values[0]]);
+    proxy.call_action(action, null);
+    let [success, volume] = action.get_result_list(["CurrentVolume"], [GObject.TYPE_FLOAT]);
+    print(volume);
 }
 
 function _on_sp_available (cp, proxy) {
-    print ("Got Proxy ", proxy.get_location());
-    for (let i = 0; i < 1000; ++i) {
-       let action = GUPnP.ServiceProxyAction.new_from_list("GetVolume", ["InstanceId", "Channel"], [0, 0]);
-       proxy.call_action(action, null);
-       let [success, result] = action.get_result_list(["CurrentVolume"], [GObject.TYPE_FLOAT]);
-       print(result);
-    }
+    print ("Got ServiceProxy ", proxy.get_id(), proxy.get_location());
+    print ("Introspecting service...");
+    proxy.introspect_async(null, _on_service_introspection)
 }
 
 var context = new GUPnP.Context ( {'interface': "wlp3s0"});
@@ -52,4 +60,5 @@ context.init(null);
 var cp = new GUPnP.ControlPoint ( {'client': context, 'target' : CONTENT_DIR});
 cp.connect ("service-proxy-available", _on_sp_available);
 cp.active = true;
+GLib.timeout_add_seconds (GLib.PRIORITY_LOW, 10, () => { MainLoop.quit(); return false; })
 Mainloop.run ("");
diff --git a/libgupnp/gupnp-service-introspection.c b/libgupnp/gupnp-service-introspection.c
index 9463b34..ae58bd9 100644
--- a/libgupnp/gupnp-service-introspection.c
+++ b/libgupnp/gupnp-service-introspection.c
@@ -103,10 +103,23 @@ gupnp_service_state_variable_info_free
         }
 
         g_list_free_full (variable->allowed_values, g_free);
+}
+
+static void
+gupnp_service_state_variable_info_free (
+        GUPnPServiceStateVariableInfo *variable);
 
-        g_slice_free (GUPnPServiceStateVariableInfo, variable);
+static void
+gupnp_service_state_variable_info_relase (GUPnPServiceStateVariableInfo *info)
+{
+        g_rc_box_release_full (info, (GDestroyNotify)gupnp_service_state_variable_info_free);
 }
 
+G_DEFINE_BOXED_TYPE(GUPnPServiceStateVariableInfo,
+                     gupnp_service_state_variable_info,
+                     g_rc_box_acquire,
+                     gupnp_service_state_variable_info_relase)
+
 static void
 gupnp_service_introspection_init (GUPnPServiceIntrospection *introspection)
 {
@@ -147,10 +160,22 @@ gupnp_service_action_arg_info_free (GUPnPServiceActionArgInfo *argument)
 {
         g_free (argument->name);
         g_free (argument->related_state_variable);
+}
 
-        g_slice_free (GUPnPServiceActionArgInfo, argument);
+static void
+gupnp_service_action_arg_info_unref (GUPnPServiceActionArgInfo *argument)
+{
+        g_rc_box_release_full (
+                argument,
+                (GDestroyNotify) gupnp_service_action_arg_info_free);
 }
 
+G_DEFINE_BOXED_TYPE (GUPnPServiceActionArgInfo,
+                     gupnp_service_action_arg_info,
+                     g_rc_box_acquire,
+                     gupnp_service_action_arg_info_unref)
+
+
 /**
  * gupnp_service_action_info_free:
  * @argument: A #GUPnPServiceActionInfo
@@ -163,10 +188,23 @@ gupnp_service_action_info_free (GUPnPServiceActionInfo *action_info)
 {
         g_free (action_info->name);
         g_list_free_full (action_info->arguments,
-                          (GDestroyNotify) gupnp_service_action_arg_info_free);
-        g_slice_free (GUPnPServiceActionInfo, action_info);
+                          (GDestroyNotify) gupnp_service_action_arg_info_unref);
+}
+
+
+static void
+gupnp_service_action_info_unref (GUPnPServiceActionInfo *argument)
+{
+        g_rc_box_release_full (
+                argument,
+                (GDestroyNotify) gupnp_service_action_info_free);
 }
 
+G_DEFINE_BOXED_TYPE (GUPnPServiceActionInfo,
+                     gupnp_service_action_info,
+                     g_rc_box_acquire,
+                     gupnp_service_action_info_unref)
+
 static void
 gupnp_service_introspection_finalize (GObject *object)
 {
@@ -466,7 +504,7 @@ get_state_variable (xmlNodePtr variable_node)
                 return NULL;
         }
 
-        variable = g_slice_new0 (GUPnPServiceStateVariableInfo);
+        variable = g_rc_box_new0(GUPnPServiceStateVariableInfo);
 
         success = set_variable_type (variable, data_type);
         g_free (data_type);
@@ -522,7 +560,7 @@ get_action_argument (xmlNodePtr argument_node)
                 return NULL;
         }
 
-        argument = g_slice_new0 (GUPnPServiceActionArgInfo);
+        argument = g_rc_box_new0 (GUPnPServiceActionArgInfo);
 
         argument->name = name;
         argument->related_state_variable = state_var;
@@ -604,7 +642,7 @@ get_actions (xmlNode *list_element)
                 if (!name)
                         continue;
 
-                action_info = g_slice_new0 (GUPnPServiceActionInfo);
+                action_info = g_rc_box_new0 (GUPnPServiceActionInfo);
                 action_info->name = name;
                 action_info->arguments = get_action_arguments (action_node);
 
diff --git a/libgupnp/gupnp-service-introspection.h b/libgupnp/gupnp-service-introspection.h
index a13ea84..1ee8e06 100644
--- a/libgupnp/gupnp-service-introspection.h
+++ b/libgupnp/gupnp-service-introspection.h
@@ -31,6 +31,10 @@ G_BEGIN_DECLS
 #define GUPNP_TYPE_SERVICE_INTROSPECTION \
                 (gupnp_service_introspection_get_type ())
 
+#define GUPNP_TYPE_SERVICE_ACTION_INFO (gupnp_service_action_info_get_type())
+#define GUPNP_TYPE_SERVICE_ACTION_ARG_INFO (gupnp_service_action_arg_info_get_type())
+
+
 G_DECLARE_FINAL_TYPE (GUPnPServiceIntrospection,
                       gupnp_service_introspection,
                       GUPNP,
@@ -66,6 +70,8 @@ typedef struct {
         char                          *related_state_variable;
         gboolean                       retval;
 } GUPnPServiceActionArgInfo;
+GType
+gupnp_service_action_arg_info_get_type (void);
 
 /**
  * GUPnPServiceActionInfo:
@@ -80,6 +86,9 @@ typedef struct {
         GList *arguments; /* list of #GUPnPServiceActionArgInfo */
 } GUPnPServiceActionInfo;
 
+GType
+gupnp_service_action_info_get_type (void);
+
 /**
  * GUPnPServiceStateVariableInfo:
  * @name: The name of the state variable.
@@ -112,6 +121,8 @@ typedef struct {
         GList   *allowed_values;
 } GUPnPServiceStateVariableInfo;
 
+GType
+gupnp_service_state_variable_info_get_type (void);
 
 const GList *
 gupnp_service_introspection_list_action_names


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]