Interface ISideEffectFactory
A factory to create ISideEffect
objects, which are applied to the
given Consumer
in createFactory(Consumer)
.
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 TypeMethodDescription<T> ISideEffect
consumeOnceAsync
(Supplier<T> supplier, Consumer<T> consumer) Runs the given supplier until it returns a non-null result.Runs the given runnable once synchronously.<T> ISideEffect
Runs the supplier and passes its result to the consumer.static ISideEffectFactory
createFactory
(Consumer<ISideEffect> sideEffectConsumer) Creates a newISideEffectFactory
which will notify the givenConsumer
of everyISideEffect
that is constructed by the factory.createPaused
(Runnable runnable) Creates a newISideEffect
on the defaultRealm
but does not run it immediately.createPaused
(Realm realm, Runnable runnable) Creates a newISideEffect
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
Creates a newISideEffectFactory
which will notify the givenConsumer
of everyISideEffect
that is constructed by the factory.For example, a
Consumer
could be passed to this method which automatically inserts everyISideEffect
into the sameCompositeSideEffect
, 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 aggregatedISideEffect
instances, which are created by this factory. They do so by passing in a consumer which collects the side-effects constructed by the factory, allowingISideEffect.dispose()
to be invoked on them at a later time.- Parameters:
sideEffectConsumer
- a consumer which will be notified about everyISideEffect
constructed by this factory. The consumer must guarantee thatISideEffect.dispose()
will be called on everyISideEffect
it receives at some point in the future.- Returns:
- a newly constructed
ISideEffectFactory
- See Also:
-
createPaused
Creates a newISideEffect
on the defaultRealm
but does not run it immediately. The lifecycle of the returnedISideEffect
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 resultingISideEffect
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 callISideEffect.dispose()
on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returnedISideEffect
is managed automatically.
-
createPaused
Creates a newISideEffect
on the given Realm but does not activate it immediately. Callers are not required to dispose the resultingISideEffect
, but may do so if they wish to dispose it early.This is similar to
ISideEffect.createPaused(Realm, Runnable)
except that the resultingISideEffect
will have its lifecycle managed by the factory.- Parameters:
realm
- the realm to executerunnable
- the runnable to execute. Must be idempotent.- Returns:
- a newly-created
ISideEffect
which has not yet been activated. Callers may callISideEffect.dispose()
on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returnedISideEffect
is managed automatically.
-
create
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 returnedISideEffect
is disposed. The returnedISideEffect
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 resultingISideEffect
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. TheRunnable
will not be executed anymore after the dispose method is invoked. Callers may callISideEffect.dispose()
on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returnedISideEffect
is managed automatically.
-
create
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 givenISideEffect
is disposed. The returnedISideEffect
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 resultingISideEffect
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. TheRunnable
will not be executed anymore after the dispose method is invoked. Callers may callISideEffect.dispose()
on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returnedISideEffect
is managed automatically.
-
createResumed
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 givenISideEffect
is disposed. The returnedISideEffect
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 theISideEffect
. However, this extra safety comes with a small performance cost overcreate(Supplier, Consumer)
.This is similar to
ISideEffect.createResumed(Supplier, Consumer)
except that the resultingISideEffect
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. TheRunnable
will not be executed anymore after the dispose method is invoked. Callers may callISideEffect.dispose()
on the result if they wish to dispose it early, but they are not required to do so since the lifecycle of the returnedISideEffect
is managed automatically.
-
consumeOnceAsync
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 toISideEffect.consumeOnceAsync(Supplier, Consumer)
except that the resultingISideEffect
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 consumerconsumer
- 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.
-