Package org.eclipse.core.databinding.observable.sideeffect

# Interface ISideEffectFactory

public interface ISideEffectFactory

A factory to create `ISideEffect` objects, which are applied to the given `Consumer` in `createFactory(Consumer)`.

Callers who provide the Consumer<ISideEffect> for the creation of an `ISideEffectFactory`, are supposed to manage the lifecycle of the aggregated `ISideEffect` instances, which are created by this factory.

Since:
  1.6
See Also:
  - `SideEffectFactory`
  - `CompositeSideEffect`
Restriction:
  This interface is not intended to be implemented by clients.

## Method Summary

Modifier and Type
Method
Description
`<T> ISideEffect`
`consumeOnceAsync(Supplier<T> supplier, Consumer<T> consumer)`
Runs the given supplier until it returns a non-null result.
`ISideEffect`
`create(Runnable runnable)`
Runs the given runnable once synchronously.
`<T> ISideEffect`
`create(Supplier<T> supplier, Consumer<T> consumer)`
Runs the supplier and passes its result to the consumer.
`static ISideEffectFactory`
`createFactory(Consumer<ISideEffect> sideEffectConsumer)`
Creates a new `ISideEffectFactory` which will notify the given `Consumer` of every `ISideEffect` that is constructed by the factory.
`ISideEffect`
`createPaused(Runnable runnable)`
Creates a new `ISideEffect` on the default `Realm` but does not run it immediately.
`ISideEffect`
`createPaused(Realm realm, Runnable runnable)`
Creates a new `ISideEffect` on the given Realm but does not activate it immediately.
`<T> ISideEffect`
`createResumed(Supplier<T> supplier, Consumer<T> consumer)`
Runs the supplier and passes its result to the consumer.

## Method Details

### createFactory

static ISideEffectFactory createFactory(Consumer<ISideEffect> sideEffectConsumer)
Creates a new `ISideEffectFactory` which will notify the given `Consumer` of every `ISideEffect` that is constructed by the factory.

For example, a `Consumer` could be passed to this method which automatically inserts every `ISideEffect` into the same `CompositeSideEffect`, allowing their lifecycle to be managed automatically by the object which provides the factory.

Callers who invoke this `createFactory(Consumer)` method are supposed to manage the lifecycle of the aggregated `ISideEffect` instances, which are created by this factory. They do so by passing in a consumer which collects the side-effects constructed by the factory, allowing `ISideEffect.dispose()` to be invoked on them at a later time.

Parameters:
  `sideEffectConsumer` - a consumer which will be notified about every `ISideEffect` constructed by this factory. The consumer must guarantee that `ISideEffect.dispose()` will be called on every `ISideEffect` it receives at some point in the future.
Returns:
  a newly constructed `ISideEffectFactory`
See Also:
  - `CompositeSideEffect`

### createPaused

ISideEffect createPaused(Runnable runnable)
Creates a new `ISideEffect` on the default `Realm` but does not run it immediately. The lifecycle of the returned `ISideEffect` will be managed by the factory.

Callers are not required to dispose the resulting `ISideEffect`, but may do so if they wish to dispose it early.

This is similar to `ISideEffect.createPaused(Runnable)` except that the resulting `ISideEffect` will have its lifecycle managed by the factory.

Parameters:
  `runnable` - the runnable to execute. Must be idempotent.
Returns:
  a newly-created `ISideEffect` which has not yet been activated. Callers may call `ISideEffect.dispose()` on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returned `ISideEffect` is managed automatically.

### createPaused

ISideEffect createPaused(Realm realm, Runnable runnable)
Creates a new `ISideEffect` on the given Realm but does not activate it immediately. Callers are not required to dispose the resulting `ISideEffect`, but may do so if they wish to dispose it early.

This is similar to `ISideEffect.createPaused(Realm, Runnable)` except that the resulting `ISideEffect` will have its lifecycle managed by the factory.

Parameters:
  `realm` - the realm to execute
  `runnable` - the runnable to execute. Must be idempotent.
Returns:
  a newly-created `ISideEffect` which has not yet been activated. Callers may call `ISideEffect.dispose()` on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returned `ISideEffect` is managed automatically.

### create

ISideEffect create(Runnable runnable)
Runs the given runnable once synchronously. The runnable will then run again after any tracked getter invoked by the runnable changes. It will continue doing so until the returned `ISideEffect` is disposed. The returned `ISideEffect` is associated with the default realm.

Callers are not required to dispose the resulting `ISideEffect`, but may do so if they wish to dispose it early.

This is similar to `ISideEffect.create(Runnable)` except that the resulting `ISideEffect` will have its lifecycle managed by the factory.

Parameters:
  `runnable` - an idempotent runnable which will be executed once synchronously then additional times after any tracked getter it uses changes state
Returns:
  an `ISideEffect` interface that may be used to stop the side-effect from running. The `Runnable` will not be executed anymore after the dispose method is invoked. Callers may call `ISideEffect.dispose()` on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returned `ISideEffect` is managed automatically.

### create

<T> ISideEffect create(Supplier<T> supplier, Consumer<T> consumer)
Runs the supplier and passes its result to the consumer. The same thing will happen again after any tracked getter invoked by the supplier changes. It will continue to do so until the given `ISideEffect` is disposed. The returned `ISideEffect` is associated with the default realm.

Callers are not required to dispose the resulting `ISideEffect`, but may do so if they wish to dispose it early.

The ISideEffect will initially be in the resumed state.

The first invocation of this method will be synchronous. This version is slightly more efficient than `createResumed(Supplier, Consumer)` and should be preferred if synchronous execution is acceptable.

This is similar to `ISideEffect.create(Supplier, Consumer)` except that the resulting `ISideEffect` will have its lifecycle managed by the factory.

Parameters:
  `supplier` - a supplier which will compute a value and be monitored for changes in tracked getters. It should be side-effect-free.
  `consumer` - a consumer which will receive the value. It should be idempotent. It will not be monitored for tracked getters.
Returns:
  an `ISideEffect` interface that may be used to stop the side-effect from running. The `Runnable` will not be executed anymore after the dispose method is invoked. Callers may call `ISideEffect.dispose()` on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returned `ISideEffect` is managed automatically.

### createResumed

<T> ISideEffect createResumed(Supplier<T> supplier, Consumer<T> consumer)
Runs the supplier and passes its result to the consumer. The same thing will happen again after any tracked getter invoked by the supplier changes. It will continue to do so until the given `ISideEffect` is disposed. The returned `ISideEffect` is associated with the default realm.

Callers are not required to dispose the resulting `ISideEffect`, but may do so if they wish to dispose it early.

The ISideEffect will initially be in the resumed state.

The first invocation of this method will be asynchronous. This is useful, for example, when constructing an `ISideEffect` in a constructor since it ensures that the constructor will run to completion before the first invocation of the `ISideEffect`. However, this extra safety comes with a small performance cost over `create(Supplier, Consumer)`.

This is similar to `ISideEffect.createResumed(Supplier, Consumer)` except that the resulting `ISideEffect` will have its lifecycle managed by the factory.

Parameters:
  `supplier` - a supplier which will compute a value and be monitored for changes in tracked getters. It should be side-effect-free.
  `consumer` - a consumer which will receive the value. It should be idempotent. It will not be monitored for tracked getters.
Returns:
  an `ISideEffect` interface that may be used to stop the side-effect from running. The `Runnable` will not be executed anymore after the dispose method is invoked. Callers may call `ISideEffect.dispose()` on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returned `ISideEffect` is managed automatically.

### consumeOnceAsync

<T> ISideEffect consumeOnceAsync(Supplier<T> supplier, Consumer<T> consumer)
Runs the given supplier until it returns a non-null result. The first time it returns a non-null result, that result will be passed to the consumer and the ISideEffect will dispose itself. As long as the supplier returns null, any tracked getters it invokes will be monitored for changes. If they change, the supplier will be run again at some point in the future.

The resulting ISideEffect will be dirty and resumed, so the first invocation of the supplier will be asynchronous. If the caller needs it to be invoked synchronously, they can call `ISideEffect.runIfDirty()`

Unlike `create(Supplier, Consumer)`, the consumer does not need to be idempotent.

This method is used for gathering asynchronous data before opening an editor, saving to disk, opening a dialog box, or doing some other operation which should only be performed once.

Consider the following example, which displays the content of a text file in a message box without doing any file I/O on the UI thread.

     IObservableValue<String> loadFileAsString(String filename) {
       // Uses another thread to load the given filename. The resulting observable returns
       // null if the file is not yet loaded or contains the file contents if the file is
       // fully loaded
       // ...
     }

     void showFileContents(Shell parentShell, String filename) {
       IObservableValue<String> webPageContent = loadFileAsString(filename);
       ISideEffect.runOnce(webPageContent::getValue, (content) -> {
            MessageDialog.openInformation(parentShell, "Your file contains", content);
       })
     }

This is similar to `ISideEffect.consumeOnceAsync(Supplier, Consumer)` except that the resulting `ISideEffect` will have its lifecycle managed by the factory.

Parameters:
  `supplier` - supplier which returns null if the side-effect should continue to wait or returns a non-null value to be passed to the consumer if it is time to invoke the consumer
  `consumer` - a (possibly non-idempotent) consumer which will receive the first non-null result returned by the supplier.
Returns:
  a side-effect which can be used to control this operation. If it is disposed before the consumer is invoked, the consumer will never be invoked. It will not invoke the supplier if it is paused.