object-interest: enrich _matches_full() to be able to check all constraints
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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);
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user