Refactored toggle::value to avoid entire implementation being generic.

This commit is contained in:
Samuel Guerra 2024-01-02 16:52:46 -03:00
parent 94d9b9e0a4
commit 9591b4bd08
14 changed files with 281 additions and 70 deletions

View File

@ -70,6 +70,14 @@ impl<T: VarValue> AnyVar for ArcVar<T> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value));
Ok(())

View File

@ -32,6 +32,106 @@ impl Clone for BoxedAnyWeakVar {
}
}
impl crate::private::Sealed for Box<dyn AnyVar> {}
impl AnyVar for Box<dyn AnyVar> {
fn clone_any(&self) -> BoxedAnyVar {
(**self).clone_any()
}
fn as_any(&self) -> &dyn Any {
(**self).as_any()
}
fn as_unboxed_any(&self) -> &dyn Any {
(**self).as_unboxed_any()
}
fn double_boxed_any(self: Box<Self>) -> Box<dyn Any> {
self
}
fn var_type_id(&self) -> TypeId {
(**self).var_type_id()
}
fn get_any(&self) -> Box<dyn AnyVarValue> {
(**self).get_any()
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
(**self).with_any(read)
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
(**self).with_new_any(read)
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
(**self).set_any(value)
}
fn last_update(&self) -> VarUpdateId {
(**self).last_update()
}
fn is_contextual(&self) -> bool {
(**self).is_contextual()
}
fn capabilities(&self) -> VarCapabilities {
(**self).capabilities()
}
fn is_animating(&self) -> bool {
(**self).is_animating()
}
fn modify_importance(&self) -> usize {
(**self).modify_importance()
}
fn hook_any(&self, pos_modify_action: Box<dyn Fn(&AnyVarHookArgs) -> bool + Send + Sync>) -> VarHandle {
(**self).hook_any(pos_modify_action)
}
fn hook_animation_stop(&self, handler: Box<dyn FnOnce() + Send>) -> Result<(), Box<dyn FnOnce() + Send>> {
(**self).hook_animation_stop(handler)
}
fn strong_count(&self) -> usize {
(**self).strong_count()
}
fn weak_count(&self) -> usize {
(**self).weak_count()
}
fn actual_var_any(&self) -> BoxedAnyVar {
(**self).actual_var_any()
}
fn downgrade_any(&self) -> BoxedAnyWeakVar {
(**self).downgrade_any()
}
fn var_ptr(&self) -> VarPtr {
(**self).var_ptr()
}
fn get_debug(&self) -> Txt {
(**self).get_debug()
}
fn update(&self) -> Result<(), VarIsReadOnlyError> {
(**self).update()
}
fn map_debug(&self) -> BoxedVar<Txt> {
(**self).map_debug()
}
}
#[doc(hidden)]
pub trait VarBoxed<T: VarValue>: AnyVar {
fn clone_boxed(&self) -> BoxedVar<T>;
@ -151,6 +251,14 @@ impl<T: VarValue> AnyVar for BoxedVar<T> {
(**self).get_any()
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
(**self).with_any(read)
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
(**self).with_new_any(read)
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
(**self).set_any(value)
}

View File

@ -145,6 +145,14 @@ impl<T: VarValue> AnyVar for ContextVar<T> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value))
}

View File

@ -157,6 +157,14 @@ impl<T: VarValue, S: Var<T>> AnyVar for ContextualizedVar<T, S> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.borrow_init().with_any(read)
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.borrow_init().with_new_any(read)
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value))
}

View File

@ -165,6 +165,14 @@ impl<T: VarValue, S: Var<T>> AnyVar for ArcCowVar<T, S> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value));
Ok(())

View File

@ -144,6 +144,14 @@ where
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.0.read().var.with_any(read)
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.0.read().var.with_new_any(read)
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value))
}

View File

@ -493,6 +493,14 @@ pub trait AnyVar: Any + Send + Sync + crate::private::Sealed {
/// Get a clone of the current value, with type erased.
fn get_any(&self) -> Box<dyn AnyVarValue>;
/// Visit the current value of the variable.
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue));
/// Visit the current value of the variable, if it [`is_new`].
///
/// [`is_new`]: AnyVar::is_new
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool;
/// Schedule a new `value` for the variable, it will be set in the end of the current app update.
///
/// # Panics
@ -1110,8 +1118,7 @@ pub trait Var<T: VarValue>: IntoVar<T, Var = Self> + AnyVar + Clone {
/// Output of [`Var::easing`].
type Easing: Var<T>;
/// Visit the current value of the variable, inside `read` the variable is locked/borrowed and cannot
/// be modified.
/// Visit the current value of the variable.
fn with<R, F>(&self, read: F) -> R
where
F: FnOnce(&T) -> R;

View File

@ -36,6 +36,14 @@ impl<T: VarValue> AnyVar for LocalVar<T> {
Box::new(self.0.clone())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
read(&self.0)
}
fn with_new_any(&self, _: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
false
}
fn set_any(&self, _: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
Err(VarIsReadOnlyError {
capabilities: self.capabilities(),

View File

@ -64,6 +64,14 @@ impl<I: VarValue, O: VarValue, S: Var<I>> AnyVar for MapRef<I, O, S> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, _: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
Err(VarIsReadOnlyError {
capabilities: self.capabilities(),
@ -388,6 +396,14 @@ impl<I: VarValue, O: VarValue, S: Var<I>> AnyVar for MapRefBidi<I, O, S> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value))
}

View File

@ -198,6 +198,14 @@ impl<T: VarValue> AnyVar for ArcMergeVar<T> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, _: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
Err(VarIsReadOnlyError {
capabilities: self.capabilities(),

View File

@ -55,6 +55,14 @@ impl<T: VarValue, V: Var<T>> AnyVar for ReadOnlyVar<T, V> {
self.1.get_any()
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.1.with_any(read)
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.1.with_new_any(read)
}
fn set_any(&self, _: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
Err(VarIsReadOnlyError {
capabilities: self.capabilities(),

View File

@ -472,6 +472,14 @@ impl<T: VarValue> AnyVar for ArcWhenVar<T> {
Box::new(self.get())
}
fn with_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) {
self.with(|v| read(v))
}
fn with_new_any(&self, read: &mut dyn FnMut(&dyn AnyVarValue)) -> bool {
self.with_new(|v| read(v)).is_some()
}
fn set_any(&self, value: Box<dyn AnyVarValue>) -> Result<(), VarIsReadOnlyError> {
self.modify(var_set_any(value))
}

View File

@ -1,7 +1,8 @@
//! Commands that control toggle.
use parking_lot::Mutex;
use std::{any::Any, fmt, sync::Arc};
use std::{fmt, sync::Arc};
use zero_ui_var::AnyVarValue;
use zero_ui_wgt::prelude::*;
@ -67,7 +68,7 @@ impl SelectOp {
}
/// Select the `value`.
pub fn select(value: Box<dyn Any + Send>) -> Self {
pub fn select(value: Box<dyn AnyVarValue>) -> Self {
let mut value = Some(value);
Self::new(move || {
if let Some(value) = value.take() {
@ -79,9 +80,9 @@ impl SelectOp {
}
/// Deselect the `value`.
pub fn deselect(value: Box<dyn Any + Send>) -> Self {
pub fn deselect(value: Box<dyn AnyVarValue>) -> Self {
Self::new(move || {
if let Err(e) = SELECTOR.get().deselect(&value) {
if let Err(e) = SELECTOR.get().deselect(&*value) {
tracing::error!("deselect error: {e}");
}
})

View File

@ -6,7 +6,7 @@
zero_ui_wgt::enable_widget_macros!();
use std::ops;
use std::{any::Any, error::Error, fmt, marker::PhantomData, sync::Arc};
use std::{error::Error, fmt, marker::PhantomData, sync::Arc};
use task::parking_lot::Mutex;
use zero_ui_ext_font::FontNames;
@ -16,7 +16,7 @@ use zero_ui_ext_input::{
pointer_capture::CaptureMode,
};
use zero_ui_ext_l10n::lang;
use zero_ui_var::VarIsReadOnlyError;
use zero_ui_var::{AnyVar, AnyVarValue, BoxedAnyVar, Var, VarIsReadOnlyError};
use zero_ui_wgt::{align, border, border_align, border_over, corner_radius, hit_test_mode, is_inited, prelude::*, Wgt};
use zero_ui_wgt_access::{access_role, accessible, AccessRole};
use zero_ui_wgt_container::{child_align, child_end, child_start, padding};
@ -326,11 +326,14 @@ pub fn is_checked(child: impl UiNode, state: impl IntoVar<bool>) -> impl UiNode
///
/// [`selector`]: fn@selector
#[property(CONTEXT+2, widget_impl(Toggle))]
pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>) -> impl UiNode {
pub fn value<T: VarValue>(child: impl UiNode, value: impl IntoVar<T>) -> impl UiNode {
value_impl(child, value.into_var().boxed_any())
}
fn value_impl(child: impl UiNode, value: BoxedAnyVar) -> impl UiNode {
// Returns `true` if selected.
let select = |value: &T| {
fn select(value: &dyn AnyVarValue) -> bool {
let selector = SELECTOR.get();
match selector.select(Box::new(value.clone())) {
match selector.select(value.clone_boxed()) {
Ok(()) => true,
Err(e) => {
let selected = selector.is_selected(value);
@ -344,9 +347,9 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
selected
}
}
};
}
// Returns `true` if deselected.
let deselect = |value: &T| {
fn deselect(value: &dyn AnyVarValue) -> bool {
let selector = SELECTOR.get();
match selector.deselect(value) {
Ok(()) => true,
@ -362,13 +365,14 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
deselected
}
}
};
let is_selected = |value: &T| SELECTOR.get().is_selected(value);
}
fn is_selected(value: &dyn AnyVarValue) -> bool {
SELECTOR.get().is_selected(value)
}
let value = value.into_var();
let checked = var(Some(false));
let child = with_context_var(child, IS_CHECKED_VAR, checked.clone());
let mut prev_value = None;
let mut prev_value = None::<Box<dyn AnyVarValue>>;
let mut _click_handle = None;
let mut _toggle_handle = CommandHandle::dummy();
@ -380,7 +384,7 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
WIDGET.sub_var(&value).sub_var(&DESELECT_ON_NEW_VAR).sub_var(&checked);
SELECTOR.get().subscribe();
value.with(|value| {
value.with_any(&mut |value| {
let selected = if SELECT_ON_INIT_VAR.get() {
select(value)
} else {
@ -389,7 +393,7 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
checked.set(Some(selected));
if DESELECT_ON_DEINIT_VAR.get() {
prev_value = Some(value.clone());
prev_value = Some(value.clone_boxed());
}
});
@ -399,7 +403,7 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
}
UiNodeOp::Deinit => {
if checked.get() == Some(true) && DESELECT_ON_DEINIT_VAR.get() {
value.with(|value| {
value.with_any(&mut |value| {
if deselect(value) {
checked.set(Some(false));
}
@ -418,29 +422,27 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
if args.is_primary() && !args.propagation().is_stopped() && args.is_enabled(WIDGET.id()) {
args.propagation().stop();
let selected = value.with(|value| {
let selected = checked.get() == Some(true);
if selected {
value.with_any(&mut |value| {
let selected = if checked.get() == Some(true) {
!deselect(value)
} else {
select(value)
}
};
checked.set(Some(selected))
});
checked.set(Some(selected))
}
} else if let Some(args) = cmd::TOGGLE_CMD.scoped(WIDGET.id()).on_unhandled(update) {
if args.param.is_none() {
args.propagation().stop();
let selected = value.with(|value| {
let selected = checked.get() == Some(true);
if selected {
value.with_any(&mut |value| {
let selected = if checked.get() == Some(true) {
!deselect(value)
} else {
select(value)
}
};
checked.set(Some(selected))
});
checked.set(Some(selected))
} else {
let s = if let Some(s) = args.param::<Option<bool>>() {
Some(s.unwrap_or(false))
@ -450,14 +452,16 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
if let Some(s) = s {
args.propagation().stop();
let selected = value.with(|value| if s { select(value) } else { !deselect(value) });
checked.set(Some(selected))
value.with_any(&mut |value| {
let selected = if s { select(value) } else { !deselect(value) };
checked.set(Some(selected))
});
}
}
} else if let Some(args) = cmd::SELECT_CMD.scoped(WIDGET.id()).on_unhandled(update) {
if args.param.is_none() {
args.propagation().stop();
value.with(|value| {
value.with_any(&mut |value| {
let selected = checked.get() == Some(true);
if !selected && select(value) {
checked.set(Some(true));
@ -467,34 +471,37 @@ pub fn value<T: VarValue + PartialEq>(child: impl UiNode, value: impl IntoVar<T>
}
}
UiNodeOp::Update { .. } => {
let selected = value.with_new(|new| {
let mut selected = None;
value.with_new_any(&mut |new| {
// auto select new.
let selected = if checked.get() == Some(true) && SELECT_ON_NEW_VAR.get() {
selected = Some(if checked.get() == Some(true) && SELECT_ON_NEW_VAR.get() {
select(new)
} else {
is_selected(new)
};
});
// auto deselect prev, need to be done after potential auto select new to avoid `CannotClear` error.
if let Some(prev) = prev_value.take() {
if DESELECT_ON_NEW_VAR.get() {
deselect(&prev);
prev_value = Some(new.clone());
deselect(&*prev);
prev_value = Some(new.clone_boxed());
}
}
selected
});
let selected = selected.unwrap_or_else(|| {
// contextual selector can change in any update.
value.with(is_selected)
let mut s = false;
value.with_any(&mut |v| {
s = is_selected(v);
});
s
});
checked.set(selected);
if DESELECT_ON_NEW_VAR.get() && selected {
// save a clone of the value to reference it on deselection triggered by variable value changing.
if prev_value.is_none() {
prev_value = Some(value.get());
prev_value = Some(value.get_any());
}
} else {
prev_value = None;
@ -648,13 +655,13 @@ pub trait SelectorImpl: Send + 'static {
fn subscribe(&self);
/// Insert the `value` in the selection, returns `Ok(())` if the value was inserted or was already selected.
fn select(&mut self, value: Box<dyn Any>) -> Result<(), SelectorError>;
fn select(&mut self, value: Box<dyn AnyVarValue>) -> Result<(), SelectorError>;
/// Remove the `value` from the selection, returns `Ok(())` if the value was removed or was not selected.
fn deselect(&mut self, value: &dyn Any) -> Result<(), SelectorError>;
fn deselect(&mut self, value: &dyn AnyVarValue) -> Result<(), SelectorError>;
/// Returns `true` if the `value` is selected.
fn is_selected(&self, value: &dyn Any) -> bool;
fn is_selected(&self, value: &dyn AnyVarValue) -> bool;
}
/// Represents the contextual selector behavior of [`value`] selector.
@ -677,15 +684,15 @@ impl Selector {
impl SelectorImpl for NilSel {
fn subscribe(&self) {}
fn select(&mut self, _: Box<dyn Any>) -> Result<(), SelectorError> {
fn select(&mut self, _: Box<dyn AnyVarValue>) -> Result<(), SelectorError> {
Err(SelectorError::custom_str("no contextual `selector`"))
}
fn deselect(&mut self, _: &dyn Any) -> Result<(), SelectorError> {
fn deselect(&mut self, _: &dyn AnyVarValue) -> Result<(), SelectorError> {
Ok(())
}
fn is_selected(&self, __r: &dyn Any) -> bool {
fn is_selected(&self, __r: &dyn AnyVarValue) -> bool {
false
}
}
@ -710,8 +717,8 @@ impl Selector {
WIDGET.sub_var(&self.selection);
}
fn select(&mut self, value: Box<dyn Any>) -> Result<(), SelectorError> {
match value.downcast::<T>() {
fn select(&mut self, value: Box<dyn AnyVarValue>) -> Result<(), SelectorError> {
match value.into_any().downcast::<T>() {
Ok(value) => match self.selection.set(*value) {
Ok(_) => Ok(()),
Err(VarIsReadOnlyError { .. }) => Err(SelectorError::ReadOnly),
@ -720,7 +727,7 @@ impl Selector {
}
}
fn deselect(&mut self, value: &dyn Any) -> Result<(), SelectorError> {
fn deselect(&mut self, value: &dyn AnyVarValue) -> Result<(), SelectorError> {
if self.is_selected(value) {
Err(SelectorError::CannotClear)
} else {
@ -728,8 +735,8 @@ impl Selector {
}
}
fn is_selected(&self, value: &dyn Any) -> bool {
match value.downcast_ref::<T>() {
fn is_selected(&self, value: &dyn AnyVarValue) -> bool {
match value.as_any().downcast_ref::<T>() {
Some(value) => self.selection.with(|t| t == value),
None => false,
}
@ -759,8 +766,8 @@ impl Selector {
WIDGET.sub_var(&self.selection);
}
fn select(&mut self, value: Box<dyn Any>) -> Result<(), SelectorError> {
match value.downcast::<T>() {
fn select(&mut self, value: Box<dyn AnyVarValue>) -> Result<(), SelectorError> {
match value.into_any().downcast::<T>() {
Ok(value) => match self.selection.set(Some(*value)) {
Ok(_) => Ok(()),
Err(VarIsReadOnlyError { .. }) => Err(SelectorError::ReadOnly),
@ -775,8 +782,8 @@ impl Selector {
}
}
fn deselect(&mut self, value: &dyn Any) -> Result<(), SelectorError> {
match value.downcast_ref::<T>() {
fn deselect(&mut self, value: &dyn AnyVarValue) -> Result<(), SelectorError> {
match value.as_any().downcast_ref::<T>() {
Some(value) => {
if self.selection.with(|t| t.as_ref() == Some(value)) {
match self.selection.set(None) {
@ -787,7 +794,7 @@ impl Selector {
Ok(())
}
}
None => match value.downcast_ref::<Option<T>>() {
None => match value.as_any().downcast_ref::<Option<T>>() {
Some(value) => {
if self.selection.with(|t| t == value) {
if value.is_none() {
@ -807,10 +814,10 @@ impl Selector {
}
}
fn is_selected(&self, value: &dyn Any) -> bool {
match value.downcast_ref::<T>() {
fn is_selected(&self, value: &dyn AnyVarValue) -> bool {
match value.as_any().downcast_ref::<T>() {
Some(value) => self.selection.with(|t| t.as_ref() == Some(value)),
None => match value.downcast_ref::<Option<T>>() {
None => match value.as_any().downcast_ref::<Option<T>>() {
Some(value) => self.selection.with(|t| t == value),
None => false,
},
@ -841,8 +848,8 @@ impl Selector {
WIDGET.sub_var(&self.selection);
}
fn select(&mut self, value: Box<dyn Any>) -> Result<(), SelectorError> {
match value.downcast::<T>() {
fn select(&mut self, value: Box<dyn AnyVarValue>) -> Result<(), SelectorError> {
match value.into_any().downcast::<T>() {
Ok(value) => self
.selection
.modify(move |m| {
@ -857,8 +864,8 @@ impl Selector {
}
}
fn deselect(&mut self, value: &dyn Any) -> Result<(), SelectorError> {
match value.downcast_ref::<T>() {
fn deselect(&mut self, value: &dyn AnyVarValue) -> Result<(), SelectorError> {
match value.as_any().downcast_ref::<T>() {
Some(value) => self
.selection
.modify(clmv!(value, |m| {
@ -872,8 +879,8 @@ impl Selector {
}
}
fn is_selected(&self, value: &dyn Any) -> bool {
match value.downcast_ref::<T>() {
fn is_selected(&self, value: &dyn AnyVarValue) -> bool {
match value.as_any().downcast_ref::<T>() {
Some(value) => &(self.selection.get() & value.clone()) == value,
None => false,
}
@ -892,17 +899,17 @@ impl Selector {
}
/// Insert the `value` in the selection, returns `Ok(())` if the value was inserted or was already selected.
pub fn select(&self, value: Box<dyn Any>) -> Result<(), SelectorError> {
pub fn select(&self, value: Box<dyn AnyVarValue>) -> Result<(), SelectorError> {
self.0.lock().select(value)
}
/// Remove the `value` from the selection, returns `Ok(())` if the value was removed or was not selected.
pub fn deselect(&self, value: &dyn Any) -> Result<(), SelectorError> {
pub fn deselect(&self, value: &dyn AnyVarValue) -> Result<(), SelectorError> {
self.0.lock().deselect(value)
}
/// Returns `true` if the `value` is selected.
pub fn is_selected(&self, value: &dyn Any) -> bool {
pub fn is_selected(&self, value: &dyn AnyVarValue) -> bool {
self.0.lock().is_selected(value)
}
}