traversity/traversity

0d3b392ac740
Parents 1fab141c84ff
Children 29a65eb4a571
Change the API of Discoverer to not be GAsyncResult based

The rational behind this can be found in TRAVERSITY-8.

The existing API was left for now, so we can port TraversityUpnpDiscoverer and
then delete it after that port is done.

We also need to add glib-mkenums for this change.

Testing Done:
Compiled

Bugs closed: TRAVERSITY-8

Reviewed at https://reviews.imfreedom.org/r/1897/
--- a/traversity/meson.build Wed Oct 05 02:17:22 2022 -0500
+++ b/traversity/meson.build Mon Oct 17 23:50:06 2022 -0500
@@ -10,13 +10,26 @@
'traversityupnpdiscoverer.h',
]
+TRAVERSITY_ENUM_HEADERS = [
+ 'traversitydiscoverer.h',
+]
+
TRAVERSITY_BUILT_SOURCES = []
TRAVERSITY_BUILT_HEADERS = []
traversity_filebase = 'traversity-1'
+traversity_include_base = traversity_filebase / 'traversity'
+
+TRAVERSITY_ENUMS = gnome.mkenums_simple('traversityenums',
+ sources : TRAVERSITY_ENUM_HEADERS,
+ install_header : true,
+ install_dir : get_option('includedir') / traversity_include_base)
+TRAVERSITY_BUILT_SOURCES += TRAVERSITY_ENUMS[0]
+TRAVERSITY_BUILT_HEADERS += TRAVERSITY_ENUMS[1]
+
TRAVERSITY_H_INCLUDES = []
-foreach header : TRAVERSITY_HEADERS
+foreach header : TRAVERSITY_HEADERS + ['traversityenums.h']
TRAVERSITY_H_INCLUDES += '#include <traversity/@0@>'.format(header)
endforeach
traversity_h_conf = configuration_data()
@@ -34,7 +47,8 @@
'resources/traversity.gresource.xml',
source_dir : 'resources',
c_name : 'traversity')
-TRAVERSITY_BUILT_SOURCES += traversity_resources
+TRAVERSITY_BUILT_SOURCES += traversity_resources[0]
+TRAVERSITY_BUILT_HEADERS += traversity_resources[1]
traversity_inc = include_directories('.')
@@ -55,13 +69,15 @@
traversity_dep = declare_dependency(
# Ensure headers built before any dependencies:
- sources : TRAVERSITY_BUILT_SOURCES,
+ sources : TRAVERSITY_BUILT_HEADERS,
include_directories : [toplevel_inc, traversity_inc],
link_with : libtraversity,
dependencies : [GLIB, GOBJECT, TEMPLATE_GLIB])
meson.override_dependency(traversity_filebase, traversity_dep)
+install_headers(TRAVERSITY_HEADERS, subdir : traversity_include_base)
+
pkgconfig.generate(
libtraversity,
name : 'libtraversity',
--- a/traversity/traversitydiscoverer.c Wed Oct 05 02:17:22 2022 -0500
+++ b/traversity/traversitydiscoverer.c Mon Oct 17 23:50:06 2022 -0500
@@ -1,6 +1,11 @@
#include "traversitydiscoverer.h"
+#include "traversityenums.h"
+
typedef struct {
+ TraversityDiscovererStatus status;
+ GError *error;
+
GInetAddress *local_ipv4;
GInetAddress *local_ipv6;
@@ -10,6 +15,8 @@
enum {
PROP_0,
+ PROP_STATUS,
+ PROP_ERROR,
PROP_LOCAL_IPV4,
PROP_LOCAL_IPV6,
PROP_PUBLIC_IPV4,
@@ -20,7 +27,6 @@
G_DEFINE_TYPE_WITH_PRIVATE(TraversityDiscoverer, traversity_discoverer,
G_TYPE_OBJECT)
-
/******************************************************************************
* GObject Implementation
*****************************************************************************/
@@ -31,6 +37,14 @@
TraversityDiscoverer *discoverer = TRAVERSITY_DISCOVERER(obj);
switch(param_id) {
+ case PROP_STATUS:
+ g_value_set_enum(value,
+ traversity_discoverer_get_status(discoverer));
+ break;
+ case PROP_ERROR:
+ g_value_set_boxed(value,
+ traversity_discoverer_get_error(discoverer));
+ break;
case PROP_LOCAL_IPV4:
g_value_set_object(value,
traversity_discoverer_get_local_ipv4(discoverer));
@@ -89,6 +103,8 @@
priv = traversity_discoverer_get_instance_private(discoverer);
+ g_clear_error(&priv->error);
+
g_clear_object(&priv->local_ipv4);
g_clear_object(&priv->local_ipv6);
g_clear_object(&priv->public_ipv4);
@@ -110,6 +126,34 @@
obj_class->dispose = traversity_discoverer_dispose;
/**
+ * TraversityDiscoverer:status:
+ *
+ * The [enum@Traversity.DiscovererStatus] that represents the state of this
+ * discoverer.
+ *
+ * Since: 1.0.0
+ */
+ properties[PROP_STATUS] = g_param_spec_enum(
+ "status", "status",
+ "The status of this discoverer",
+ TRAVERSITY_TYPE_DISCOVERER_STATUS,
+ TRAVERSITY_DISCOVERER_STATUS_UNDISCOVERED,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * TraversityDiscoverer:error:
+ *
+ * The error from the last discovery attempt.
+ *
+ * Since: 1.0.0
+ */
+ properties[PROP_ERROR] = g_param_spec_boxed(
+ "error", "error",
+ "The error from the last discovery attempt",
+ G_TYPE_ERROR,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+ /**
* TraversityDiscoverer:local-ipv4:
*
* The local IPv4 address if found or %NULL.
@@ -168,6 +212,78 @@
* Public API
*****************************************************************************/
void
+traversity_discoverer_discover(TraversityDiscoverer *discoverer) {
+ TraversityDiscovererClass *klass = NULL;
+ TraversityDiscovererPrivate *priv = NULL;
+
+ g_return_if_fail(TRAVERSITY_IS_DISCOVERER(discoverer));
+
+ priv = traversity_discoverer_get_instance_private(discoverer);
+ if(priv->status == TRAVERSITY_DISCOVERER_STATUS_DISCOVERING) {
+ return;
+ }
+
+ klass = TRAVERSITY_DISCOVERER_GET_CLASS(discoverer);
+ if(klass != NULL && klass->discover != NULL) {
+ /* This method is named for the way it's normally called, but we abuse
+ * it here, to set the state to discovering and clear the error.
+ */
+ traversity_discoverer_update_status(discoverer,
+ TRAVERSITY_DISCOVERER_STATUS_DISCOVERING,
+ NULL);
+
+ klass->discover(discoverer);
+ }
+}
+
+void
+traversity_discoverer_update_status(TraversityDiscoverer *discoverer,
+ TraversityDiscovererStatus status,
+ GError *error)
+{
+ TraversityDiscovererPrivate *priv = NULL;
+ GObject *obj = NULL;
+
+ g_return_if_fail(TRAVERSITY_IS_DISCOVERER(discoverer));
+
+ priv = traversity_discoverer_get_instance_private(discoverer);
+
+ priv->status = status;
+
+ g_clear_error(&priv->error);
+ priv->error = error;
+
+ obj = G_OBJECT(discoverer);
+ g_object_freeze_notify(obj);
+ g_object_notify_by_pspec(obj, properties[PROP_STATUS]);
+ g_object_notify_by_pspec(obj, properties[PROP_ERROR]);
+ g_object_thaw_notify(obj);
+}
+
+TraversityDiscovererStatus
+traversity_discoverer_get_status(TraversityDiscoverer *discoverer) {
+ TraversityDiscovererPrivate *priv = NULL;
+
+ g_return_val_if_fail(TRAVERSITY_IS_DISCOVERER(discoverer),
+ TRAVERSITY_DISCOVERER_STATUS_UNDISCOVERED);
+
+ priv = traversity_discoverer_get_instance_private(discoverer);
+
+ return priv->status;
+}
+
+GError *
+traversity_discoverer_get_error(TraversityDiscoverer *discoverer) {
+ TraversityDiscovererPrivate *priv = NULL;
+
+ g_return_val_if_fail(TRAVERSITY_IS_DISCOVERER(discoverer), NULL);
+
+ priv = traversity_discoverer_get_instance_private(discoverer);
+
+ return priv->error;
+}
+
+void
traversity_discoverer_discover_async(TraversityDiscoverer *discoverer,
GCancellable *cancellable,
GAsyncReadyCallback callback,
--- a/traversity/traversitydiscoverer.h Wed Oct 05 02:17:22 2022 -0500
+++ b/traversity/traversitydiscoverer.h Mon Oct 17 23:50:06 2022 -0500
@@ -13,6 +13,28 @@
G_BEGIN_DECLS
/**
+ * TraversityDiscovererStatus:
+ * @TRAVERSITY_DISCOVERER_STATUS_UNDISCOVERED: A discovery attempt has not yet
+ * been made.
+ * @TRAVERSITY_DISCOVERER_STATUS_UNABLE_TO_DISCOVER: The most recent discovery
+ * attempt failed.
+ * @TRAVERSITY_DISCOVERER_STATUS_DISCOVERING: A discovery attempt is in
+ * progress.
+ * @TRAVERSITY_DISCOVERER_STATUS_DISCOVERED: The most recent discovery attempt
+ * was successful.
+ *
+ * A status that represents the state of a [class@Traversity.Discoverer].
+ *
+ * Since: 1.0.0
+ */
+typedef enum {
+ TRAVERSITY_DISCOVERER_STATUS_UNDISCOVERED = -1,
+ TRAVERSITY_DISCOVERER_STATUS_UNABLE_TO_DISCOVER,
+ TRAVERSITY_DISCOVERER_STATUS_DISCOVERING,
+ TRAVERSITY_DISCOVERER_STATUS_DISCOVERED
+} TraversityDiscovererStatus;
+
+/**
* TraversityDiscoverer:
*
* A discoverer is an abstract class that defines the interface for discovering
@@ -29,52 +51,72 @@
/*< private >*/
GObjectClass parent;
+ /*< public >*/
void (*discover_async)(TraversityDiscoverer *discoverer, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data);
- gboolean (*discover_finish)(TraversityDiscoverer *discoverer, GAsyncResult *result, GError **error);
+ gboolean (*discover_finish)(TraversityDiscoverer *discoverer, GAsyncResult *result, GError **error);
+
+ void (*discover)(TraversityDiscoverer *discoverer);
/*< private >*/
gpointer reserved[8];
};
/**
- * traversity_discoverer_discover_async:
+ * traversity_discoverer_discover:
* @discoverer: The instance.
- * @cancellable: (nullable): A [class@Gio.Cancellable] or %NULL.
- * @callback: The callback to call when discovery is done.
- * @data: User data to pass to @callback.
+ *
+ * Starts the discovery process asynchronously.
+ *
+ * To know when this process is finished, you may connect to the
+ * [signal@GObject.Object::notify] signal for this instance. You can either watch for
+ * the [property@Traversity.Discoverer:status] or the specific IP address that
+ * you are interested in.
*
- * Starts the discovery process asynchronously. When the process has been
- * completed, @callback will be called with @data and you should call
- * [method@Traversity.Discoverer.discover_finish] to get the results of the
- * discovery.
+ * Since: 1.0.0
+ */
+void traversity_discoverer_discover(TraversityDiscoverer *discoverer);
+
+/**
+ * traversity_discoverer_update_status:
+ * @discoverer: The instance.
+ * @status: The new status.
+ * @error: (nullable) (transfer full): The [type@GLib.Error] if there was an
+ * error.
+ *
+ * Sets the status of the most recent call to
+ * [method@Traversity.Discoverer.discover].
+ *
+ * This method is only meant to be called by subclasses.
*
* Since: 1.0.0
*/
-void traversity_discoverer_discover_async(TraversityDiscoverer *discoverer, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data);
+void traversity_discoverer_update_status(TraversityDiscoverer *discoverer, TraversityDiscovererStatus status, GError *error);
/**
- * traversity_discoverer_discover_finish:
+ * traversity_discoverer_get_status:
* @discoverer: The instance.
- * @result: The [iface@Gio.AsyncResult] that was passed to your callback.
- * @error: (out) (nullable): A return address for a [struct@Glib.Error].
- *
- * Retrieves the results from a previous call to
- * [method@Traversity.Discoverer.discover_async] which should only be called in
- * the callback function from the previous call.
*
- * If a new address has been discovered, this will return %TRUE, otherwise
- * %FALSE will be returned.
+ * Gets the status of the discoverer.
*
- * Use [method@Traversity.Discoverer.get_local_ipv4],
- * [method@Traversity.Discoverer.get_local_ipv6],
- * [method@Traversity.Discoverer.get_public_ipv4], and
- * [method@Traversity.Discoverer.get_public_ipv6] to get the new IP addresses.
- *
- * Returns: %TRUE if something new was discovered, otherwise %FALSE.
+ * Returns: The status of the discoverer.
*
* Since: 1.0.0
*/
-gboolean traversity_discoverer_discover_finish(TraversityDiscoverer *discoverer, GAsyncResult *result, GError **error);
+TraversityDiscovererStatus traversity_discoverer_get_status(TraversityDiscoverer *discoverer);
+
+/**
+ * traversity_discoverer_get_error:
+ * @discoverer: The instance.
+ *
+ * Gets the [type@GLib.Error] from the last discover run or %NULL if there was
+ * no error.
+ *
+ * Returns: (transfer none): The error from the last discover run or %NULL if
+ * there was no error.
+ *
+ * Since: 1.0.0
+ */
+GError *traversity_discoverer_get_error(TraversityDiscoverer *discoverer);
/**
* traversity_discoverer_get_local_ipv4:
@@ -188,6 +230,9 @@
*/
void traversity_discoverer_set_public_ipv6(TraversityDiscoverer *discoverer, GInetAddress *public_ipv6);
+void traversity_discoverer_discover_async(TraversityDiscoverer *discoverer, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer data);
+gboolean traversity_discoverer_discover_finish(TraversityDiscoverer *discoverer, GAsyncResult *result, GError **error);
+
G_END_DECLS
#endif /* TRAVERSITY_DISCOVERER_H */