com.vaadin.signals.

Class Signal<T>

java.lang.Object
com.vaadin.signals.Signal<T>

Type Parameters:

T - the signal value type

Direct Known Subclasses:

ComputedSignal, ListSignal, MapSignal, NodeSignal, ValueSignal

public abstract class Signal<T> extends Object

Base type for all signals. A signal is a reactive value holder with automatic subscription and unsubscription of listeners.

Reactivity is based on effect(Runnable) callbacks that detect the signals used during invocation. The callback will be run again whenever there's a change to any of the signal instances used in the previous invocation. Detection is based on running value(). peek() can be used to read the value within an effect without registering a dependency.

A signal may be synchronized across a cluster. In that case, changes to the signal value are only confirmed asynchronously. The regular signal value() returns the assumed value based on local modifications whereas peekConfirmed() gives access to the confirmed value.

  • Field Details

    • ANYTHING_GOES

      protected static final Predicate<SignalCommand> ANYTHING_GOES

      Signal validator that accepts anything. This is defined as a constant to enable using == to detect and optimize cases where no validation is applied.

  • Constructor Details

    • Signal

      protected Signal(SignalTree tree, Id id, Predicate<SignalCommand> validator)

      Creates a new signal instance with the given id and validator for the given signal tree.

      Parameters:

      tree - the signal tree that contains the value for this signal, not null

      id - the id of the signal node within the signal tree, not null

      validator - the validator to check operations submitted to this singal, not null

  • Method Details

    • data

      protected Node.Data data(TreeRevision revision)

      Gets the data node for this signal in the given tree revision.

      Parameters:

      revision - the tree revision to read from, not null

      Returns:

      the data node, or null if there is no node for this signal in the revision

    • data

      protected Node.Data data(Transaction transaction)

      Gets the data node for this signal in the given transaction.

      Parameters:

      transaction - the transaction to read from, not null

      Returns:

      the data node, or null if there is no node for this signal in the transaction

    • value

      public T value()

      Gets the current value of this signal. The value is read in a way that takes the current transaction into account and in the case of clustering also changes that have been submitted to the cluster but not yet confirmed.

      Reading the value in a regular (i.e. Transaction.Type.STAGED) transaction makes the transaction depend on the value so that the transaction fails in case the signal value is changed concurrently.

      Reading the value inside an effect(Runnable) or computed(Supplier) callback sets up that effect or computed signal to depend on the signal.

      Returns:

      the signal value

    • peek

      public T peek()

      Reads the value without setting up any dependencies. This method returns the same value as value() but without creating a dependency when used inside a transaction, effect or computed signal.

      Returns:

      the signal value

    • peekConfirmed

      public T peekConfirmed()

      Reads the confirmed value without setting up any dependencies. The confirmed value doesn't consider changes in the current transaction or changes that have been submitted but not yet confirmed in a cluster.

      Returns:

      the confirmed signal value

    • validator

      protected Predicate<SignalCommand> validator()

      Gets the validator used by this signal instance.

      Returns:

      the used validator, not null

    • mergeValidators

      protected Predicate<SignalCommand> mergeValidators(Predicate<SignalCommand> validator)

      Merges the validator used by this signal with the given validator. This chains the two validators so that both must accept any change but it additionally avoids redundant chaining in case either validator is ANYTHING_GOES.

      Parameters:

      validator - the validator to merge, not null

      Returns:

      a combined validator, not null

    • extractValue

      protected abstract T extractValue(Node.Data data)

      Extracts the value for this signal from the given signal data node.

      Parameters:

      data - the data node to extract the value from, or null if the node doesn't exist in the tree

      Returns:

      the signal value

    • usageChangeValue

      protected abstract Object usageChangeValue(Node.Data data)

      Gets a reference value that will be used to determine whether a dependency based on previous usage should be invalidated. This is done by getting one reference value when the dependency occurs and then comparing that to the current value to determine if the value has changed.

      The implementation should return an object that changes if and only if the value() of this signal changes.

      Parameters:

      data - the data node to read from, not null

      Returns:

      a reference value to use for validity checks, may be null

    • submit

      protected <R, O extends SignalOperation<R>> O submit(SignalCommand command, Function<CommandResult.Accept,R> resultConverter, O operation)

      Submits a command for this signal and updates the given operation using the given result converter once the command result is confirmed. The command is submitted through the current Transaction and it uses SignalEnvironment.synchronousDispatcher() for delivering the result update.

      Type Parameters:

      R - the result type

      O - the operation type

      Parameters:

      command - the command to submit, not null

      resultConverter - a callback for creating an operation result value based on the command result, not null

      operation - the operation to update with the eventual result, not null

      Returns:

      the provided operation, for chaining

    • submitVoidOperation

      protected <O extends SignalOperation<Void>> O submitVoidOperation(SignalCommand command, O operation)

      Submits a command for this signal and updates the given operation without a value once the command result is confirmed. This is a shorthand for submit(SignalCommand, Function, SignalOperation) in the case of operations that don't have a result value.

      Type Parameters:

      O - the operation type

      Parameters:

      command - the command to submit, not null

      operation - the operation to update with the eventual result, not null

      Returns:

      the provided operation, for chaining

    • submitInsert

      protected <I extends Signal<?>> InsertOperation<I> submitInsert(SignalCommand command, Function<Id,I> childFactory)

      Submits a command for this signal and creates and insert operation that is updated once the command result is confirmed. This is a shorthand for submit(SignalCommand, Function, SignalOperation) in the case of insert operations.

      Type Parameters:

      I - the insert operation type

      Parameters:

      command - the command to submit, not null

      childFactory - callback used to create a signal instance in the insert operation, not null

      Returns:

      the created insert operation, not null

    • submit

      protected <R> SignalOperation<R> submit(SignalCommand command, Function<CommandResult.Accept,R> resultConverter)

      Submits a command for this signal and uses the provided result converter to updates the created operation once the command result is confirmed. This is a shorthand for submit(SignalCommand, Function, SignalOperation) in the case of using the default operation type.

      Type Parameters:

      R - the operation result value

      Parameters:

      command - the command to submit, not null

      resultConverter - a callback for creating an operation result value based on the command result, not null

      Returns:

      the created operation instance, not null

    • submit

      protected SignalOperation<Void> submit(SignalCommand command)

      Submits a command for this signal and updates the created operation without a value once the command result is confirmed. This is a shorthand for submit(SignalCommand, Function, SignalOperation) in the case of using the default operation type and no result value.

      Parameters:

      command - the command to submit, not null

      Returns:

      the created operation instance, not null

    • id

      public Id id()

      Gets the unique id of this signal instance. The id will be the same for other signal instances backed by the same data, e.g. in the case of using asNode() to create a signal of different type.

      Returns:

      the signal id, not null

    • tree

      protected SignalTree tree()

      Gets the signal tree that stores the value for this signal.

      Returns:

      the signal tree, not null

    • createUsage

      protected UsageTracker.Usage createUsage(Transaction transaction)

      Creates a usage instance based on the current state of this signal.

      Parameters:

      transaction - the transaction for which the usage occurs, not null

      Returns:

      a usage instance, not null

    • asNode

      protected NodeSignal asNode()

      Converts this signal into a node signal. This allows further conversion into any specific signal type through the methods in NodeSignal. The converted signal is backed by the same underlying data and uses the same validator as this signal.

      Returns:

      this signal as a node signal, not null

    • clear

      protected SignalOperation<Void> clear()

      Helper to submit a clear command. This is a helper is re-defined as public in the signal types where a clear operation makes sense.

      Returns:

      the created signal operation instance, not null

    • remove

      protected SignalOperation<Void> remove(Signal<?> child)

      Helper to submit a remove command. This is a helper is re-defined as public in the signal types where a remove operation makes sense.

      Parameters:

      child - the child signal to remove, not null

      Returns:

      the created signal operation instance, not null

    • toJson

      protected static com.fasterxml.jackson.databind.JsonNode toJson(Object value)

      Helper to convert the given object to JSON using the global signal object mapper.

      Parameters:

      value - the object to convert to JSON

      Returns:

      the converted JSON node, not null

      See Also:

    • fromJson

      protected static <T> T fromJson(com.fasterxml.jackson.databind.JsonNode value, Class<T> targetType)

      Helper to convert the given JSON to a Java instance of the given type using the global signal object mapper.

      Type Parameters:

      T - the target type

      Parameters:

      value - the JSON value to convert

      targetType - the target type, not null

      Returns:

      the converted Java instance

      See Also:

    • nodeValue

      protected static <T> T nodeValue(Node node, Class<T> valueType)

      Helper to convert the value of the given node into Java object of the given type.

      Type Parameters:

      T - the Java object type

      Parameters:

      node - the signal node to read the value from, not null

      valueType - the type to convert to, not null

      Returns:

      the converted Java instance

    • effect

      public static Runnable effect(Runnable action)

      Creates a signal effect with the given action. The action is run when the effect is created and is subsequently run again whenever there's a change to any signal value that was read during the last invocation.

      Parameters:

      action - the effect action to use, not null

      Returns:

      a callback used to close the effect so that it no longer listens to signal changes, not null

    • computed

      public static <T> Signal<T> computed(Supplier<T> computation)

      Creates a new computed signal with the given computation callback. A computed signal behaves like a regular signal except that the value is not directly set but instead computed from other signals. The computed signal is automatically updated if any of the used signals are updated. The computation is lazy so that it only runs when its value is accessed and only if the previously computed value might have been invalidated by dependent signal changes. An effect or computed signal that uses the value from a computed signal will not be invalidated if the computation is run again but produces the same value as before.

      Type Parameters:

      T - the signal type

      Parameters:

      computation - the computation callback, not null

      Returns:

      the computed signal, not null

    • map

      public <C> Signal<C> map(Function<T,C> mapper)

      Creates a computed signal based on a mapper function that is passed the value of this signal. If the mapper function accesses other signal values, then the computed signal will also depend on those signals.

      Type Parameters:

      C - the computed signal type

      Parameters:

      mapper - the mapper function to use, not null

      Returns:

      the computed signal, not null

    • runInTransaction

      public static <T> TransactionOperation<T> runInTransaction(Supplier<T> transactionTask)

      Runs the provided supplier in a transaction. All signal operations performed within the transaction will be staged and atomically committed at the end of the transaction. The commit fails and doesn't apply any of the commands if any of the commands fail. Reading a signal value within a transaction will make the transaction depend on that value so that the transaction fails if the signal value has been changed concurrently.

      The value returned by the supplier will be available from the returned operation instance. The result of the operation will be set based on whether the transaction was successfully committed once the status is confirmed.

      Type Parameters:

      T - the type returned by the supplier

      Parameters:

      transactionTask - the supplier to run, not null

      Returns:

      a transaction operation containing the supplier return value and the eventual result

      See Also:

    • runInTransaction

      public static TransactionOperation<Void> runInTransaction(Runnable transactionTask)

      Runs the provided runnable in a transaction. All signal operations performed within the transaction will be staged and atomically committed at the end of the transaction. The commit fails and doesn't apply any of the commands if any of the commands fail. Reading a signal value within a transaction will make the transaction depend on that value so that the transaction fails if the signal value has been changed concurrently.

      The result of the operation will be set based on whether the transaction was successfully committed once the status is confirmed.

      Parameters:

      transactionTask - the runnable to run, not null

      Returns:

      a transaction operation containing the supplier return value and the eventual result

      See Also:

    • runWithoutTransaction

      public static <T> T runWithoutTransaction(Supplier<T> task)

      Runs the given supplier outside any transaction and returns the supplied value. The current transaction will be restored after the task has been run.

      Type Parameters:

      T - the supplier type

      Parameters:

      task - the supplier to run, not null

      Returns:

      the value returned from the supplier

    • runWithoutTransaction

      public static void runWithoutTransaction(Runnable task)

      Runs the given task outside any transaction. The current transaction will be restored after the task has been run.

      Parameters:

      task - the task to run, not null

    • untracked

      public static <T> T untracked(Supplier<T> task)

      Runs the given supplier without tracking dependencies for signals that are read within the supplier. This has the same effect as peek() but is effective for an entire code block rather than just a single invocation.

      Type Parameters:

      T - the supplier type

      Parameters:

      task - the supplier task to run, not null

      Returns:

      the value returned from the supplier