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.

  • 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