object-interest: enrich _matches_full() to be able to check all constraints

This commit is contained in:
George Kiagiadakis
2021-06-07 16:13:43 +03:00
parent 342c3a7ea2
commit 997bdb65cd
4 changed files with 86 additions and 33 deletions

View File

@@ -704,13 +704,13 @@ wp_object_interest_matches (WpObjectInterest * self, gpointer object)
{ {
if (g_type_is_a (self->gtype, WP_TYPE_PROPERTIES)) { if (g_type_is_a (self->gtype, WP_TYPE_PROPERTIES)) {
g_return_val_if_fail (object != NULL, FALSE); g_return_val_if_fail (object != NULL, FALSE);
return wp_object_interest_matches_full (self, self->gtype, NULL, return wp_object_interest_matches_full (self, 0, self->gtype, NULL,
(WpProperties *) object, NULL); (WpProperties *) object, NULL) == WP_INTEREST_MATCH_ALL;
} }
else { else {
g_return_val_if_fail (G_IS_OBJECT (object), FALSE); g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
return wp_object_interest_matches_full (self, G_OBJECT_TYPE (object), return wp_object_interest_matches_full (self, 0, G_OBJECT_TYPE (object),
object, NULL, NULL); object, NULL, NULL) == WP_INTEREST_MATCH_ALL;
} }
} }
@@ -731,8 +731,17 @@ wp_object_interest_matches (WpObjectInterest * self, gpointer object)
* retrieved from \a object by calling wp_pipewire_object_get_properties() and * retrieved from \a object by calling wp_pipewire_object_get_properties() and
* wp_global_proxy_get_global_properties() respectively. * wp_global_proxy_get_global_properties() respectively.
* *
* When \a flags contains WP_INTEREST_MATCH_FLAGS_CHECK_ALL, all the constraints
* are checked and the returned value contains accurate information about which
* types of constraints have failed to match, if any. When this flag is not
* present, this function returns after the first failure has been encountered.
* This means that the returned flags set will contain all but one flag, which
* will indicate the kind of constraint that failed (more could have failed,
* but they are not checked...)
*
* \ingroup wpobjectinterest * \ingroup wpobjectinterest
* \param self the object interest * \param self the object interest
* \param flags flags to alter the behavior of this function
* \param object_type the type to be checked against the interest's type * \param object_type the type to be checked against the interest's type
* \param object (type GObject)(transfer none)(nullable): the object to be used for * \param object (type GObject)(transfer none)(nullable): the object to be used for
* checking constraints of type WP_CONSTRAINT_TYPE_G_PROPERTY * checking constraints of type WP_CONSTRAINT_TYPE_G_PROPERTY
@@ -740,30 +749,33 @@ wp_object_interest_matches (WpObjectInterest * self, gpointer object)
* checking constraints of type WP_CONSTRAINT_TYPE_PW_PROPERTY * checking constraints of type WP_CONSTRAINT_TYPE_PW_PROPERTY
* \param pw_global_props (transfer none)(nullable): the properties to be used for * \param pw_global_props (transfer none)(nullable): the properties to be used for
* checking constraints of type WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY * checking constraints of type WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY
* \returns TRUE if the the type matches this interest and the properties * \returns flags that indicate which components of the interest match.
* match the constraints, FALSE otherwise * WP_INTEREST_MATCH_ALL indicates a fully successful match; any other
* combination indicates a failure on the component(s) that do not appear on
* the flag set
*/ */
gboolean WpInterestMatch
wp_object_interest_matches_full (WpObjectInterest * self, wp_object_interest_matches_full (WpObjectInterest * self,
GType object_type, gpointer object, WpProperties * pw_props, WpInterestMatchFlags flags, GType object_type, gpointer object,
WpProperties * pw_global_props) WpProperties * pw_props, WpProperties * pw_global_props)
{ {
WpInterestMatch result = WP_INTEREST_MATCH_ALL;
g_autoptr (WpProperties) props = NULL; g_autoptr (WpProperties) props = NULL;
g_autoptr (WpProperties) global_props = NULL; g_autoptr (WpProperties) global_props = NULL;
g_autoptr (GError) error = NULL; g_autoptr (GError) error = NULL;
struct constraint *c; struct constraint *c;
g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (self != NULL, WP_INTEREST_MATCH_NONE);
if (G_UNLIKELY (!wp_object_interest_validate (self, &error))) { if (G_UNLIKELY (!wp_object_interest_validate (self, &error))) {
wp_critical_boxed (WP_TYPE_OBJECT_INTEREST, self, "validation failed: %s", wp_critical_boxed (WP_TYPE_OBJECT_INTEREST, self, "validation failed: %s",
error->message); error->message);
return FALSE; return WP_INTEREST_MATCH_NONE;
} }
/* check if the GType matches */ /* check if the GType matches */
if (!g_type_is_a (object_type, self->gtype)) if (!g_type_is_a (object_type, self->gtype))
return FALSE; result &= ~WP_INTEREST_MATCH_GTYPE;
/* prepare for constraint lookups on proxy properties */ /* prepare for constraint lookups on proxy properties */
if (object) { if (object) {
@@ -793,6 +805,11 @@ wp_object_interest_matches_full (WpObjectInterest * self,
g_auto (GValue) value = G_VALUE_INIT; g_auto (GValue) value = G_VALUE_INIT;
gboolean exists = FALSE; gboolean exists = FALSE;
/* return early if the match failed and CHECK_ALL is not specified */
if (!(flags & WP_INTEREST_MATCH_FLAGS_CHECK_ALL) &&
result != WP_INTEREST_MATCH_ALL)
return result;
/* collect, check & convert the subject property */ /* collect, check & convert the subject property */
switch (c->type) { switch (c->type) {
case WP_CONSTRAINT_TYPE_PW_PROPERTY: case WP_CONSTRAINT_TYPE_PW_PROPERTY:
@@ -833,15 +850,17 @@ wp_object_interest_matches_full (WpObjectInterest * self,
g_value_init (&value, subject_type_to_gtype (c->subject_type)); g_value_init (&value, subject_type_to_gtype (c->subject_type));
g_value_transform (&orig, &value); g_value_transform (&orig, &value);
} }
else else {
return FALSE; result &= ~(1 << c->type);
continue;
}
} }
} }
break; break;
} }
default: default:
g_return_val_if_reached (FALSE); g_return_val_if_reached (WP_INTEREST_MATCH_NONE);
} }
/* match the subject to the constraint's value, /* match the subject to the constraint's value,
@@ -850,39 +869,39 @@ wp_object_interest_matches_full (WpObjectInterest * self,
case WP_CONSTRAINT_VERB_EQUALS: case WP_CONSTRAINT_VERB_EQUALS:
if (!exists || if (!exists ||
!constraint_verb_equals (c->subject_type, &value, c->value)) !constraint_verb_equals (c->subject_type, &value, c->value))
return FALSE; result &= ~(1 << c->type);
break; break;
case WP_CONSTRAINT_VERB_NOT_EQUALS: case WP_CONSTRAINT_VERB_NOT_EQUALS:
if (exists && if (exists &&
constraint_verb_equals (c->subject_type, &value, c->value)) constraint_verb_equals (c->subject_type, &value, c->value))
return FALSE; result &= ~(1 << c->type);
break; break;
case WP_CONSTRAINT_VERB_MATCHES: case WP_CONSTRAINT_VERB_MATCHES:
if (!exists || if (!exists ||
!constraint_verb_matches (c->subject_type, &value, c->value)) !constraint_verb_matches (c->subject_type, &value, c->value))
return FALSE; result &= ~(1 << c->type);
break; break;
case WP_CONSTRAINT_VERB_IN_LIST: case WP_CONSTRAINT_VERB_IN_LIST:
if (!exists || if (!exists ||
!constraint_verb_in_list (c->subject_type, &value, c->value)) !constraint_verb_in_list (c->subject_type, &value, c->value))
return FALSE; result &= ~(1 << c->type);
break; break;
case WP_CONSTRAINT_VERB_IN_RANGE: case WP_CONSTRAINT_VERB_IN_RANGE:
if (!exists || if (!exists ||
!constraint_verb_in_range (c->subject_type, &value, c->value)) !constraint_verb_in_range (c->subject_type, &value, c->value))
return FALSE; result &= ~(1 << c->type);
break; break;
case WP_CONSTRAINT_VERB_IS_PRESENT: case WP_CONSTRAINT_VERB_IS_PRESENT:
if (!exists) if (!exists)
return FALSE; result &= ~(1 << c->type);
break; break;
case WP_CONSTRAINT_VERB_IS_ABSENT: case WP_CONSTRAINT_VERB_IS_ABSENT:
if (exists) if (exists)
return FALSE; result &= ~(1 << c->type);
break; break;
default: default:
g_return_val_if_reached (FALSE); g_return_val_if_reached (WP_INTEREST_MATCH_NONE);
} }
} }
return TRUE; return result;
} }

View File

@@ -56,6 +56,40 @@ typedef enum {
WP_CONSTRAINT_VERB_IS_ABSENT = '-', WP_CONSTRAINT_VERB_IS_ABSENT = '-',
} WpConstraintVerb; } WpConstraintVerb;
/*!
* \brief Flags that indicate which constraints have been matched in
* wp_object_interest_matches_full()
* \ingroup wpobjectinterest
*/
typedef enum { /*< flags >*/
WP_INTEREST_MATCH_NONE = 0,
WP_INTEREST_MATCH_GTYPE = (1 << 0),
WP_INTEREST_MATCH_PW_GLOBAL_PROPERTIES = (1 << 1),
WP_INTEREST_MATCH_PW_PROPERTIES = (1 << 2),
WP_INTEREST_MATCH_G_PROPERTIES = (1 << 3),
} WpInterestMatch;
/*!
* \brief Special WpInterestMatch value that indicates that all constraints
* have been matched
* \ingroup wpobjectinterest
*/
static const gint WP_INTEREST_MATCH_ALL =
(WP_INTEREST_MATCH_GTYPE |
WP_INTEREST_MATCH_PW_GLOBAL_PROPERTIES |
WP_INTEREST_MATCH_PW_PROPERTIES |
WP_INTEREST_MATCH_G_PROPERTIES);
/*!
* \brief Flags to alter the behaviour of wp_object_interest_matches_full()
* \ingroup wpobjectinterest
*/
typedef enum { /*< flags >*/
WP_INTEREST_MATCH_FLAGS_NONE = 0,
/*! check all the constraints instead of returning after the first mis-match */
WP_INTEREST_MATCH_FLAGS_CHECK_ALL = (1 << 0),
} WpInterestMatchFlags;
/*! /*!
* \brief The WpObjectInterest GType * \brief The WpObjectInterest GType
* \ingroup wpobjectinterest * \ingroup wpobjectinterest
@@ -96,9 +130,9 @@ WP_API
gboolean wp_object_interest_matches (WpObjectInterest * self, gpointer object); gboolean wp_object_interest_matches (WpObjectInterest * self, gpointer object);
WP_API WP_API
gboolean wp_object_interest_matches_full (WpObjectInterest * self, WpInterestMatch wp_object_interest_matches_full (WpObjectInterest * self,
GType object_type, gpointer object, WpProperties * pw_props, WpInterestMatchFlags flags, GType object_type, gpointer object,
WpProperties * pw_global_props); WpProperties * pw_props, WpProperties * pw_global_props);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (WpObjectInterest, wp_object_interest_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (WpObjectInterest, wp_object_interest_unref)

View File

@@ -620,8 +620,8 @@ wp_object_manager_is_interested_in_global (WpObjectManager * self,
for (i = 0; i < self->interests->len; i++) { for (i = 0; i < self->interests->len; i++) {
interest = g_ptr_array_index (self->interests, i); interest = g_ptr_array_index (self->interests, i);
if (wp_object_interest_matches_full (interest, global->type, if (wp_object_interest_matches_full (interest, 0, global->type,
global->proxy, NULL, global->properties)) { global->proxy, NULL, global->properties) == WP_INTEREST_MATCH_ALL) {
gpointer ft = g_hash_table_lookup (self->features, gpointer ft = g_hash_table_lookup (self->features,
GSIZE_TO_POINTER (global->type)); GSIZE_TO_POINTER (global->type));
*wanted_features = (WpObjectFeatures) GPOINTER_TO_UINT (ft); *wanted_features = (WpObjectFeatures) GPOINTER_TO_UINT (ft);

View File

@@ -260,8 +260,8 @@ test_object_interest_teardown (TestFixture * f, gconstpointer data)
g_assert_no_error (error); \ g_assert_no_error (error); \
g_assert_true (ret); \ g_assert_true (ret); \
\ \
g_assert_true (wp_object_interest_matches_full (interest, \ g_assert_cmphex (wp_object_interest_matches_full (interest, 0, \
WP_TYPE_NODE, NULL, props, global_props)); \ WP_TYPE_NODE, NULL, props, global_props), ==, WP_INTEREST_MATCH_ALL); \
\ \
g_clear_pointer (&interest, wp_object_interest_unref); \ g_clear_pointer (&interest, wp_object_interest_unref); \
} G_STMT_END } G_STMT_END
@@ -277,8 +277,8 @@ test_object_interest_teardown (TestFixture * f, gconstpointer data)
g_assert_no_error (error); \ g_assert_no_error (error); \
g_assert_true (ret); \ g_assert_true (ret); \
\ \
g_assert_false (wp_object_interest_matches_full (interest, \ g_assert_cmphex (wp_object_interest_matches_full (interest, 0, \
WP_TYPE_NODE, NULL, props, global_props)); \ WP_TYPE_NODE, NULL, props, global_props), !=, WP_INTEREST_MATCH_ALL); \
\ \
g_clear_pointer (&interest, wp_object_interest_unref); \ g_clear_pointer (&interest, wp_object_interest_unref); \
} G_STMT_END } G_STMT_END