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:
- Restriction:
- This interface is not intended to be implemented by clients.
-
Method Summary
Modifier and TypeMethodDescription<T> ISideEffectconsumeOnceAsync(Supplier<T> supplier, Consumer<T> consumer) Runs the given supplier until it returns a non-null result.Runs the given runnable once synchronously.<T> ISideEffectRuns the supplier and passes its result to the consumer.static ISideEffectFactorycreateFactory(Consumer<ISideEffect> sideEffectConsumer) Creates a newISideEffectFactorywhich will notify the givenConsumerof everyISideEffectthat is constructed by the factory.createPaused(Runnable runnable) Creates a newISideEffecton the defaultRealmbut does not run it immediately.createPaused(Realm realm, Runnable runnable) Creates a newISideEffecton the given Realm but does not activate it immediately.<T> ISideEffectcreateResumed(Supplier<T> supplier, Consumer<T> consumer) Runs the supplier and passes its result to the consumer.
-
Method Details
-
createFactory
Creates a newISideEffectFactorywhich will notify the givenConsumerof everyISideEffectthat is constructed by the factory.For example, a
Consumercould be passed to this method which automatically inserts everyISideEffectinto 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 aggregatedISideEffectinstances, 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 everyISideEffectconstructed by this factory. The consumer must guarantee thatISideEffect.dispose()will be called on everyISideEffectit receives at some point in the future.- Returns:
- a newly constructed
ISideEffectFactory - See Also:
-
createPaused
Creates a newISideEffecton the defaultRealmbut does not run it immediately. The lifecycle of the returnedISideEffectwill 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 resultingISideEffectwill have its lifecycle managed by the factory.- Parameters:
runnable- the runnable to execute. Must be idempotent.- Returns:
- a newly-created
ISideEffectwhich 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 returnedISideEffectis managed automatically.
-
createPaused
Creates a newISideEffecton 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 resultingISideEffectwill have its lifecycle managed by the factory.- Parameters:
realm- the realm to executerunnable- the runnable to execute. Must be idempotent.- Returns:
- a newly-created
ISideEffectwhich 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 returnedISideEffectis 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 returnedISideEffectis disposed. The returnedISideEffectis 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 resultingISideEffectwill 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
ISideEffectinterface that may be used to stop the side-effect from running. TheRunnablewill 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 returnedISideEffectis 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 givenISideEffectis disposed. The returnedISideEffectis 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 resultingISideEffectwill 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
ISideEffectinterface that may be used to stop the side-effect from running. TheRunnablewill 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 returnedISideEffectis 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 givenISideEffectis disposed. The returnedISideEffectis 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
ISideEffectin 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 resultingISideEffectwill 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
ISideEffectinterface that may be used to stop the side-effect from running. TheRunnablewill 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 returnedISideEffectis 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 resultingISideEffectwill 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.
-