Package ghidra.async

# Class AsyncReference<T,C>

java.lang.Object
ghidra.async.AsyncReference<T,C>

Type Parameters:
  `T` - the type of object stored by reference
  `C` - when updated, the type of the causes of those updates (often `Void`)

Direct Known Subclasses:
  `AsyncReference.DebouncedAsyncReference`

public class AsyncReference<T,C> extends Object
An observable reference useful for asynchronous computations

The reference supports the usual set and get operations. The set operation accepts an optional "cause" argument which is forwarded to some observers. The set operation may also be intercepted by an optional filter. The filter function is provided a copy of the current value, proposed value, and cause. The value it returns becomes the new value. If that value is different than the current value, the observers are notified. The default filter returns the new value, always.

The reference provides three types of observation callbacks. The first is to listen for all changes. This follows the listener pattern. When the value changes, i.e., is set to a value different than the current value, all change listener are invoked with a copy of the new value and a reference to the provided cause, if given. The second is to wait for the very next change. It follows the promises pattern. The returned future completes with the new value upon the very next change. The cause is not provided to the type of observer. The third is to wait for a given value. It, too, follows the promises pattern. The returned future completes as soon as the reference takes the given value. The cause is not provided to this type of observer.

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `protected static class`
  `AsyncReference.ChangeRecord<T,C>`
  Used for debouncing
  `protected static class`
  `AsyncReference.DebouncedAsyncReference<T,C>`
  `static interface`
  `AsyncReference.FilterFunction<T,C>`
  A function to filter updates to an `AsyncReference`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `AsyncReference()`
  Construct a new reference initialized to `null`
  `AsyncReference(T t)`
  Construct a new reference initialized to the given value

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addChangeListener(TriConsumer<? super T,? super T,? super C> listener)`
  Add a listener for any change to this reference's value
  `T`
  `compute(Function<? super T,? extends T> func, C cause)`
  Update this reference using the given function because of the given cause
  `AsyncReference<T,C>`
  `debounced(AsyncTimer timer, long windowMillis)`
  Obtain a new `AsyncReference` whose value is updated after this reference has settled
  `void`
  `dispose(Throwable reason)`
  Clear out the queues of future, completing each exceptionally
  `void`
  `filter(AsyncReference.FilterFunction<T,? super C> newFilter)`
  Apply a filter function to all subsequent updates
  `protected boolean`
  `filterAndSet(T t, C cause)`
  `T`
  `get()`
  Get the current value of this reference
  `protected CompletableFuture<T>`
  `getAndClearChangePromise()`
  `protected List<ghidra.async.AsyncReference.WaitUntilFuture<T>>`
  `getAndRemoveUntils(T t)`
  `protected CompletableFuture<Void>`
  `getAndRemoveWaitFor(T t)`
  `protected void`
  `invokeListeners(List<TriConsumer<? super T,? super T,? super C>> copy, T oldVal, T newVal, C cause)`
  `protected void`
  `invokePromise(CompletableFuture<T> promise, T t)`
  `protected void`
  `invokeWaitFor(CompletableFuture<Void> waiter)`
  `protected void`
  `invokeWaitUntils(List<ghidra.async.AsyncReference.WaitUntilFuture<T>> untils, T t)`
  `void`
  `removeChangeListener(TriConsumer<T,T,C> listener)`
  Remove a change listener
  `boolean`
  `set(T newVal, C cause)`
  Update this reference to the given value because of the given cause
  `CompletableFuture<T>`
  `waitChanged()`
  Wait for the next change and capture the new value The returned future completes with the value of the very next change, at the time of that change.
  `CompletableFuture<T>`
  `waitUntil(Predicate<T> predicate)`
  Wait for this reference to accept the first value meeting the given condition (post-filter)
  `CompletableFuture<Void>`
  `waitValue(T t)`
  Wait for this reference to accept a particular value (post-filter)

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Constructor Details

  - ### AsyncReference

    public AsyncReference()
    Construct a new reference initialized to `null`

  - ### AsyncReference

    public AsyncReference(T t)
    Construct a new reference initialized to the given value
    Parameters:
      `t` - the initial value

- ## Method Details

  - ### filter

    public void filter(AsyncReference.FilterFunction<T,? super C> newFilter)
    Apply a filter function to all subsequent updates

    The given function replaces the current function.

    Parameters:
      `newFilter` - the filter

  - ### get

    public T get()
    Get the current value of this reference
    Returns:
      the current value

  - ### getAndClearChangePromise

    protected CompletableFuture<T> getAndClearChangePromise()

  - ### getAndRemoveWaitFor

    protected CompletableFuture<Void> getAndRemoveWaitFor(T t)

  - ### getAndRemoveUntils

    protected List<ghidra.async.AsyncReference.WaitUntilFuture<T>> getAndRemoveUntils(T t)

  - ### filterAndSet

    protected boolean filterAndSet(T t, C cause)

  - ### invokeListeners

    protected void invokeListeners(List<TriConsumer<? super T,? super T,? super C>> copy, T oldVal, T newVal, C cause)

  - ### invokePromise

    protected void invokePromise(CompletableFuture<T> promise, T t)

  - ### invokeWaitFor

    protected void invokeWaitFor(CompletableFuture<Void> waiter)

  - ### invokeWaitUntils

    protected void invokeWaitUntils(List<ghidra.async.AsyncReference.WaitUntilFuture<T>> untils, T t)

  - ### set

    public boolean set(T newVal, C cause)
    Update this reference to the given value because of the given cause
    Parameters:
      `newVal` - the proposed value (subject to the filter)
      `cause` - the cause, often `null`
    Returns:
      true if the value of this reference changed (post filter)

  - ### compute

    public T compute(Function<? super T,? extends T> func, C cause)
    Update this reference using the given function because of the given cause
    Parameters:
      `func` - the function taking the current value and returning the proposed value (subject to the filter)
      `cause` - the cause, often `null`
    Returns:
      the new value of this reference (post filter)

  - ### addChangeListener

    public void addChangeListener(TriConsumer<? super T,? super T,? super C> listener)
    Add a listener for any change to this reference's value

    Updates that get "filtered out" do not cause a change listener to fire.

    Parameters:
      `listener` - the listener, which is passed the new value (post-filter) and cause

  - ### removeChangeListener

    public void removeChangeListener(TriConsumer<T,T,C> listener)
    Remove a change listener
    Parameters:
      `listener` - the listener to remove

  - ### waitChanged

    public CompletableFuture<T> waitChanged()
    Wait for the next change and capture the new value The returned future completes with the value of the very next change, at the time of that change. Subsequent changes to the value of the reference do not affect the returned future.
    Returns:
      the future value at the next change

  - ### waitValue

    public CompletableFuture<Void> waitValue(T t)
    Wait for this reference to accept a particular value (post-filter)

    If the reference already has the given value, a completed future is returned.

    Parameters:
      `t` - the expected value to wait on
    Returns:
      a future that completes the next time the reference accepts the given value

  - ### waitUntil

    public CompletableFuture<T> waitUntil(Predicate<T> predicate)
    Wait for this reference to accept the first value meeting the given condition (post-filter)

    If the current value already meets the condition, a completed future is returned.

    Parameters:
      `predicate` - the condition to meet
    Returns:
      a future that completes the next time the reference accepts a passing value

  - ### dispose

    public void dispose(Throwable reason)
    Clear out the queues of future, completing each exceptionally
    Parameters:
      `reason` - the reason for disposal

  - ### debounced

    public AsyncReference<T,C> debounced(AsyncTimer timer, long windowMillis)
    Obtain a new `AsyncReference` whose value is updated after this reference has settled

    The original `AsyncReference` continues to behave as usual, except that is has an additional listener on it. When this reference is updated, the update is passed through an `AsyncDebouncer` configured with the given timer and window. When the debouncer settles, the debounced reference is updated.

    Directly updating, i.e., calling `set(Object, Object)` on, the debounced reference subverts the debouncing mechanism, and will result in an exception. Only the original reference should be updated directly.

    Setting a filter on the debounced reference may have undefined behavior.

    If the original reference changes value rapidly, settling on the debounced reference's current value, no update event is produced by the debounced reference. If the original reference changes value rapidly, settling on a value different from the debounced reference's current value, an update event is produced, using the cause of the final update, even if an earlier cause was associated with the same final value.

    Parameters:
      `timer` - a timer for measuring the window
      `windowMillis` - the period of inactive time to consider this reference settled
    Returns:
      the new `AsyncReference`