Class ValueSignal<T extends @Nullable Object>

java.lang.Object
com.vaadin.flow.signals.local.AbstractLocalSignal<T>
com.vaadin.flow.signals.local.ValueSignal<T>
Type Parameters:
T - the signal value type
All Implemented Interfaces:
Signal<T>, Serializable

public class ValueSignal<T extends @Nullable Object> extends AbstractLocalSignal<T>
A local writable signal that holds a reference to an object.

Local signals are non-serializable and intended for UI-local state only. They do not participate in clustering and are simpler than shared signals.

Changing the signal to reference another immutable value is an atomic operation. It is safe to concurrently read and write the signal value from multiple threads.

The signal can also be used with mutable values in which case no thread safety is provided. Mutations must be done through modify(ValueModifier) to ensure dependents are informed after the modification is applied.

Local value signals can't be used inside signal transactions.

All operation objects returned from methods on this class are resolved immediately.

See Also:
  • Constructor Details

    • ValueSignal

      public ValueSignal(T initialValue)
      Creates a new value signal with the given initial value.
      Parameters:
      initialValue - the initial value
    • ValueSignal

      public ValueSignal(T initialValue, SerializableBiPredicate<T,T> equalityChecker)
      Creates a new value signal with the given initial value and a custom equality checker.

      The equality checker is used to determine if a new value is equal to the current value. If the equality checker returns true, the value update is skipped, and no change notification is triggered, i.e., no dependent effect function is triggered.

      Parameters:
      initialValue - the initial value, may be null
      equalityChecker - the predicate used to compare values for equality, not null
  • Method Details

    • checkPreconditions

      protected void checkPreconditions()
      Description copied from class: AbstractLocalSignal
      Hook for subclasses to perform precondition checks before accessing the value. Called while holding the lock. The base implementation verifies that the signal is not accessed from a different session than the one that first used it.
      Overrides:
      checkPreconditions in class AbstractLocalSignal<T extends @Nullable Object>
    • set

      public void set(T value)
      Sets the value of this signal.

      If the new value is not equal to the current value, the value is set and effect functions that have reads from this signal are triggered. If the values are equal, no change is made and effect functions are not triggered. The equality checker provided in the constructor is used to compare the values and defaults to Objects.equals(Object, Object).

      Parameters:
      value - the value to set
    • replace

      public boolean replace(T expectedValue, T newValue)
      Sets the value of this signal if and only if the signal has the expected value at the time when the operation is confirmed. This is the signal counterpart to AtomicReference.compareAndSet(Object, Object).

      If the expected value matches and the new value differs from the old value, the value is set and effect functions are triggered. If the expected value matches but the new value equals the old value, no change is made and effect functions are not triggered. The equality checker provided in the constructor is used to compare the expected value with the current value, and to compare the new value with the old value.

      Parameters:
      expectedValue - the expected value
      newValue - the new value
      Returns:
      true if the expected value was present, false if there was a different value
    • update

      public T update(SignalUpdater<T> updater)
      Updates the signal value based on the given callback. The callback receives the current signal value and returns the new value to use. This implementation acquires a lock while running the updater which means that it's never necessary to run the callback again. This also means that canceling the returned operation will never have any effect.

      Update operations cannot participate in transactions since any retry would occur after the original transaction has already been committed. For this reason, the whole operation completely bypasses all transaction handling.

      If the new value is equal to the current value, no change is made and effect functions are not triggered. The equality checker provided in the constructor is used to compare the values.

      Parameters:
      updater - the value update callback, not null
      Returns:
      the previous value
    • modify

      public void modify(ValueModifier<T> modifier)
      Runs the given callback to apply changes to a mutable referenced value and then notifies dependents.

      This method is only intended for cases where concurrency is limited through other means, such as Vaadin's session lock. Using this method concurrently with any other methods on the same instance may, but is not guaranteed to, cause an ConcurrentModificationException. The exception can be thrown either from this method or from the other invoked method. This can happen even if the other method is safe for concurrent use.

      Parameters:
      modifier - a callback that receives the current value to modify, not null
    • asReadonly

      public Signal<T> asReadonly()
      Wraps this signal to not accept changes.

      This signal will keep its current configuration and changes applied through this instance will be visible through the wrapped instance.

      Returns:
      the new readonly signal, not null
    • updater

      public <C> SerializableConsumer<C> updater(ValueMerger<T,C> merger)
      Creates a callback that updates this signal value using the provided merger function. This is useful for creating write callbacks for bindValue when working with immutable value patterns.

      The merger function receives the current signal value and a new child value, and should return a new signal value. This is typically a method reference to a "with" style method on an immutable record or class.

      Example usage with an immutable record:

       record Person(String name, int age) {
           Person withName(String name) {
               return new Person(name, this.age);
           }
       }
      
       ValueSignal<Person> personSignal = new ValueSignal<>(
               new Person("Alice", 30));
       textField.bindValue(personSignal.map(Person::name),
               personSignal.updater(Person::withName));
       
      Type Parameters:
      C - the child value type that will be provided to the callback
      Parameters:
      merger - the function to create a new signal value from the old value and a new child value, not null
      Returns:
      a callback that updates this signal using the merger function, not null
    • modifier

      public <C> SerializableConsumer<C> modifier(SignalModifier<T,C> modifier)
      Creates a callback that modifies this signal's mutable value in place using the provided modifier function. This is useful for creating write callbacks for bindValue when working with mutable value patterns.

      The modifier function receives the current signal value and a new child value, and should modify the signal value in place. This is typically a method reference to a setter method on a mutable bean.

      Example usage with a mutable bean:

       class Person {
           private String name;
           private int age;
      
           public String getName() {
               return name;
           }
      
           public void setName(String name) {
               this.name = name;
           }
       }
      
       ValueSignal<Person> personSignal = new ValueSignal<>(new Person());
       textField.bindValue(personSignal.map(Person::getName),
               personSignal.modifier(Person::setName));
       
      Type Parameters:
      C - the child value type that will be provided to the callback
      Parameters:
      modifier - the function to modify the signal value in place with a new child value, not null
      Returns:
      a callback that modifies this signal using the modifier function, not null
    • toString

      public String toString()
      Overrides:
      toString in class Object