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)) {
g_return_val_if_fail (object != NULL, FALSE);
return wp_object_interest_matches_full (self, self->gtype, NULL,
(WpProperties *) object, NULL);
return wp_object_interest_matches_full (self, 0, self->gtype, NULL,
(WpProperties *) object, NULL) == WP_INTEREST_MATCH_ALL;
}
else {
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
return wp_object_interest_matches_full (self, G_OBJECT_TYPE (object),
object, NULL, NULL);
return wp_object_interest_matches_full (self, 0, G_OBJECT_TYPE (object),
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
* 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
* \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 GObject)(transfer none)(nullable): the object to be used for
* 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
* \param pw_global_props (transfer none)(nullable): the properties to be used for
* checking constraints of type WP_CONSTRAINT_TYPE_PW_GLOBAL_PROPERTY
* \returns TRUE if the the type matches this interest and the properties
* match the constraints, FALSE otherwise
* \returns flags that indicate which components of the interest match.
* 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,
GType object_type, gpointer object, WpProperties * pw_props,
WpProperties * pw_global_props)
WpInterestMatchFlags flags, GType object_type, gpointer object,
WpProperties * pw_props, WpProperties * pw_global_props)
{
WpInterestMatch result = WP_INTEREST_MATCH_ALL;
g_autoptr (WpProperties) props = NULL;
g_autoptr (WpProperties) global_props = NULL;
g_autoptr (GError) error = NULL;
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))) {
wp_critical_boxed (WP_TYPE_OBJECT_INTEREST, self, "validation failed: %s",
error->message);
return FALSE;
return WP_INTEREST_MATCH_NONE;
}
/* check if the GType matches */
if (!g_type_is_a (object_type, self->gtype))
return FALSE;
result &= ~WP_INTEREST_MATCH_GTYPE;
/* prepare for constraint lookups on proxy properties */
if (object) {
@@ -793,6 +805,11 @@ wp_object_interest_matches_full (WpObjectInterest * self,
g_auto (GValue) value = G_VALUE_INIT;
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 */
switch (c->type) {
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_transform (&orig, &value);
}
else
return FALSE;
else {
result &= ~(1 << c->type);
continue;
}
}
}
break;
}
default:
g_return_val_if_reached (FALSE);
g_return_val_if_reached (WP_INTEREST_MATCH_NONE);
}
/* match the subject to the constraint's value,
@@ -850,39 +869,39 @@ wp_object_interest_matches_full (WpObjectInterest * self,
case WP_CONSTRAINT_VERB_EQUALS:
if (!exists ||
!constraint_verb_equals (c->subject_type, &value, c->value))
return FALSE;
result &= ~(1 << c->type);
break;
case WP_CONSTRAINT_VERB_NOT_EQUALS:
if (exists &&
constraint_verb_equals (c->subject_type, &value, c->value))
return FALSE;
result &= ~(1 << c->type);
break;
case WP_CONSTRAINT_VERB_MATCHES:
if (!exists ||
!constraint_verb_matches (c->subject_type, &value, c->value))
return FALSE;
result &= ~(1 << c->type);
break;
case WP_CONSTRAINT_VERB_IN_LIST:
if (!exists ||
!constraint_verb_in_list (c->subject_type, &value, c->value))
return FALSE;
result &= ~(1 << c->type);
break;
case WP_CONSTRAINT_VERB_IN_RANGE:
if (!exists ||
!constraint_verb_in_range (c->subject_type, &value, c->value))
return FALSE;
result &= ~(1 << c->type);
break;
case WP_CONSTRAINT_VERB_IS_PRESENT:
if (!exists)
return FALSE;
result &= ~(1 << c->type);
break;
case WP_CONSTRAINT_VERB_IS_ABSENT:
if (exists)
return FALSE;
result &= ~(1 << c->type);
break;
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 = '-',
} 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
* \ingroup wpobjectinterest
@@ -96,9 +130,9 @@ WP_API
gboolean wp_object_interest_matches (WpObjectInterest * self, gpointer object);
WP_API
gboolean wp_object_interest_matches_full (WpObjectInterest * self,
GType object_type, gpointer object, WpProperties * pw_props,
WpProperties * pw_global_props);
WpInterestMatch wp_object_interest_matches_full (WpObjectInterest * self,
WpInterestMatchFlags flags, GType object_type, gpointer object,
WpProperties * pw_props, WpProperties * pw_global_props);
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++) {
interest = g_ptr_array_index (self->interests, i);
if (wp_object_interest_matches_full (interest, global->type,
global->proxy, NULL, global->properties)) {
if (wp_object_interest_matches_full (interest, 0, global->type,
global->proxy, NULL, global->properties) == WP_INTEREST_MATCH_ALL) {
gpointer ft = g_hash_table_lookup (self->features,
GSIZE_TO_POINTER (global->type));
*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_true (ret); \
\
g_assert_true (wp_object_interest_matches_full (interest, \
WP_TYPE_NODE, NULL, props, global_props)); \
g_assert_cmphex (wp_object_interest_matches_full (interest, 0, \
WP_TYPE_NODE, NULL, props, global_props), ==, WP_INTEREST_MATCH_ALL); \
\
g_clear_pointer (&interest, wp_object_interest_unref); \
} G_STMT_END
@@ -277,8 +277,8 @@ test_object_interest_teardown (TestFixture * f, gconstpointer data)
g_assert_no_error (error); \
g_assert_true (ret); \
\
g_assert_false (wp_object_interest_matches_full (interest, \
WP_TYPE_NODE, NULL, props, global_props)); \
g_assert_cmphex (wp_object_interest_matches_full (interest, 0, \
WP_TYPE_NODE, NULL, props, global_props), !=, WP_INTEREST_MATCH_ALL); \
\
g_clear_pointer (&interest, wp_object_interest_unref); \
} G_STMT_END