/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.agera;
import android.support.annotation.NonNull;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionException;
/**
* Container of the compiler state interfaces supporting the declaration of {@link Repository}s
* using the type-safe declarative language.
*
* <h3>List of directives</h3>
*
* <b>Variables:</b> s: supplier; fs: fallible supplier; m: merger; fm: fallible merger;
* f: function; ff: fallible function; p: predicate; r: receiver; b: binder; e: executor; v: value.
* <ul>
* <li>({@link RFlow#thenGetFrom then}){@link RFlow#getFrom GetFrom(s)}
* <li>({@link RFlow#thenMergeIn then}){@link RFlow#mergeIn MergeIn(s, m)}
* <li>({@link RFlow#thenTransform then}){@link RFlow#transform Transform(f)}
* <li>({@link RFlow#thenAttemptGetFrom then}){@link
* RFlow#attemptGetFrom AttemptGetFrom(fs)}.<i>term</i>
* <li>({@link RFlow#thenAttemptMergeIn then}){@link
* RFlow#attemptMergeIn AttemptMergeIn(s, fm)}.<i>term</i>
* <li>({@link RFlow#thenAttemptTransform then}){@link
* RFlow#attemptTransform AttemptTransform(ff)}.<i>term</i>
* <li>{@link RFlow#check(Predicate) check(p)}.<i>term</i>
* <li>{@link RFlow#check(Function, Predicate) check(f, p)}.<i>term</i>
* <li>{@link RFlow#sendTo sendTo(r)}
* <li>{@link RFlow#bindWith bindWith(s, b)}
* <li>{@link RFlow#goTo goTo(e)}
* <li>{@link RFlow#goLazy goLazy()}
* <li>{@link RFlow#thenSkip thenSkip()}
* </ul>
* where <i>term</i> (the termination clause) is one of:
* <ul>
* <li>{@link RTermination#orSkip orSkip()}
* <li>{@link RTermination#orEnd orEnd(f)}
* </ul>
*
* Agera 中抽象出来的 仓库编译状态 接口
* 由 RepositoryCompilerStates 编译( create )出 一个 Repository
* 并且规定了仓库状态的执行顺序:
* 1. REventSource
* 2. RFrequency
* 3. RFlow
* 4. RSyncFlow( 只有 RFlow.goTo(...) 后才进入此状态 )
* 5. RTermination
* 6. RConfig
*/
public interface RepositoryCompilerStates {
// Note on documentation grammar: most method summaries for flow directives use an infinitive verb
// phrase ("do something") instead of the usual 3rd-person grammar ("does something"). This is
// because the full sentence for these method summaries are "this method specifies that the next
// step of the flow should do something", rather than "this method does something".
/**
* Compiler state allowing to specify the event source of the repository.
*
* @param <TVal> Value type of the repository.
* @param <TStart> Value type at the start of the data processing flow. May be different from
* {@code TVal} when chain-building a repository that starts with
* {@link RConfig#compileIntoRepositoryWithInitialValue}.
*
* REventSource 事件源状态
* TVal 类型 作为 仓库数据类型
* TStart 类型 作为 数据流开始类型
*
* 定义了一个基本的接口方法 - observe(Observable... observables)
* 可以指定一组 事件源。即,被观察者
*/
interface REventSource<TVal, TStart> {
/**
* Specifies the event source of the compiled repository.
* 指定事件源
*
* 结束后,进入 RFrequency 频率状态
* TVal 类型 作为 RFrequency 仓库数据类型 TVal
* TStart 类型 作为 RFrequency 数据流开始类型 TStart
*/
@NonNull RFrequency<TVal, TStart> observe(@NonNull Observable... observables);
}
/**
* Compiler state allowing to specify the frequency of invoking the data processing flow.
*
* @param <TVal> Value type of the repository.
* @param <TStart> Value type at the start of the data processing flow.
*
* RFrequency 频率状态
* TVal 类型 作为 仓库数据类型
* TStart 类型 作为 数据流开始类型
* 同时,也继承了 REventSource<TVal, TStart> 状态,也能在次状态指定事件源
*
* 该状态提供的方法可以 指定调用数据处理流的频率
*/
interface RFrequency<TVal, TStart> extends REventSource<TVal, TStart> {
/**
* Specifies the minimum timeout to wait since starting the previous data processing flow,
* before starting another flow to respond to updates from the event sources. Flows will
* not
* be
* started more frequent than if {@link #onUpdatesPerLoop()} were used, even if the given
* timeout is sufficiently small.
*
*
* 设置更新频率,小于 0 的话,会自动设置为 0
* 这里的频率是两个数据处理流的之间的频率
*
* 结束后,进入 RFlow 流状态
* TVal 类型 作为 RFlow 仓库数据类型 TVal
* TStart 类型 作为 RFlow 上一个数据流输出类型 TPre
*/
@NonNull RFlow<TVal, TStart, ?> onUpdatesPer(int millis);
/**
* Specifies that multiple updates from the event sources per worker looper loop should
* start
* only one data processing flow.
*
* 等同于,onUpdatesPer(0)
*
* 结束后,进入 RFlow 流状态
* TVal 类型 作为 RFlow 仓库数据类型 TVal
* TStart 类型 作为 RFlow 上一个数据流输出类型 TPre
*/
@NonNull RFlow<TVal, TStart, ?> onUpdatesPerLoop();
}
/**
* Compiler state allowing to specify the next directive of the data processing flow.
*
* @param <TVal> Value type of the repository.
* @param <TPre> The output value type of the previous directive.
*
* RFlow 流状态
* TVal 类型 作为 RFlow 仓库数据类型
* TPre 类型 作为 RFlow 上一个数据流输出类型
*
* 1. 可以在这选择进行一些数据流操作,得到返回的 RFlow 对象
* 2. 也可以执行一些 attemptXxx 系列方法,跳出此状态,进入到 RTermination 终止状态
* 3. 还可以执行 goLazy 方法,进入到 RSyncFlow 同步流状态
*/
interface RFlow<TVal, TPre, TSelf extends RFlow<TVal, TPre, TSelf>>
extends RSyncFlow<TVal, TPre, TSelf> {
// Methods whose return types need subtyping (due to no "generic type of generic type" in Java):
/**
* RFlow 获取数据操作
* 可类型转换( 供应者 )
*
* @param supplier 供应者
* @param <TCur> 供应者 的 目标类型
* @return 返回 一个 RFlow 流状态
*
* TVal 类型 作为 RFlow 仓库数据类型
* TCur 类型 作为 RFlow 上一个数据流输出类型
*/
@NonNull
@Override <TCur> RFlow<TVal, TCur, ?> getFrom(@NonNull Supplier<TCur> supplier);
/**
* RFlow 尝试获取数据操作
* 可以截获异常,进行处理( 供应者+Result )
*
* @param attemptSupplier Result 供应者
* @param <TCur> Result 供应者 的 目标类型
* @return 返回一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RFlow<TVal, TCur, ?> 类型 作为 RTermination 编译返回状态类型
*/
@NonNull
@Override <TCur> RTermination<TVal, Throwable, RFlow<TVal, TCur, ?>> attemptGetFrom(
@NonNull Supplier<Result<TCur>> attemptSupplier);
@NonNull
@Override
RTerminationOrContinue<TVal, Throwable, RConfig<TVal>,
RFlow<TVal, Throwable, ?>> thenAttemptGetFrom(
@NonNull Supplier<? extends Result<? extends TVal>> attemptSupplier);
/**
* RFlow 合并操作
* 可类型转换( 供应者 )
* 可以合并供应者转换后的数据 和 之前的流处理结果数据( 合并者 )
*
* @param supplier 供应者
* @param merger 合并者
* @param <TAdd> 供应者 的 目标类型
* @param <TCur> 合并者 的 目标类型
* @return 返回 一个 RFlow 流状态
*
* TVal 类型 作为 RFlow 仓库数据类型
* TCur 类型 作为 RFlow 上一个数据流输出类型
*/
@NonNull
@Override <TAdd, TCur> RFlow<TVal, TCur, ?> mergeIn(@NonNull Supplier<TAdd> supplier,
@NonNull
Merger<? super TPre, ? super TAdd, TCur> merger);
/**
* RFlow 尝试合并操作
* 可类型转换( 供应者 )
* 可以合并供应者转换后的数据 和 之前的流处理结果数据( 合并者 )
* 可以截获异常,进行处理( 合并者+Result )
*
* @param supplier 供应者
* @param attemptMerger 合并者
* @param <TAdd> 供应者 的 目标类型
* @param <TCur> 合并者 的 Result 目标类型
* @return 返回 一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RFlow<TVal, TCur, ?> 类型 作为 RTermination 编译返回状态类型
*/
@NonNull
@Override <TAdd, TCur> RTermination<TVal, Throwable, RFlow<TVal, TCur, ?>> attemptMergeIn(
@NonNull Supplier<TAdd> supplier,
@NonNull Merger<? super TPre, ? super TAdd, Result<TCur>> attemptMerger);
@NonNull
@Override
<TAdd> RTerminationOrContinue<TVal, Throwable, RConfig<TVal>,
RFlow<TVal, Throwable, ?>> thenAttemptMergeIn(
@NonNull Supplier<TAdd> supplier,
@NonNull Merger<? super TPre, ? super TAdd,
? extends Result<? extends TVal>> attemptMerger);
/**
* RFlow 转换操作
* 用于类型转换
* 与 getFrom(...) 的区别:
* getFrom(...) 是通过 Supplier 可以在提供数据时,进行间接的类型转换
* transform(...) 是通过 Function 进行直接的类型之间转换
*
* @param function 转换方法
* @param <TCur> 转换方法 的 目标类型
* @return 返回 一个 RFlow 流状态
*
* TVal 类型 作为 RFlow 仓库数据类型
* TCur 类型 作为 RFlow 上一个数据流输出类型
*/
@NonNull
@Override <TCur> RFlow<TVal, TCur, ?> transform(
@NonNull Function<? super TPre, TCur> function);
/**
* RFlow 尝试转换操作
* 用于类型转换
* 可以截获异常,进行处理( 转换方法+Result )
*
* @param attemptFunction 转换方法
* @param <TCur> 转换方法 的 Result 目标类型
* @return 返回 一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RFlow<TVal, TCur, ?> 类型 作为 RTermination 编译返回状态类型
*/
@NonNull
@Override <TCur> RTermination<TVal, Throwable, RFlow<TVal, TCur, ?>> attemptTransform(
@NonNull Function<? super TPre, Result<TCur>> attemptFunction);
@NonNull
@Override
RTerminationOrContinue<TVal, Throwable, RConfig<TVal>,
RFlow<TVal, Throwable, ?>> thenAttemptTransform(
@NonNull Function<? super TPre, ? extends Result<? extends TVal>> attemptFunction);
// Asynchronous directives:
/**
* Go to the given {@code executor} to continue the data processing flow. The executor is
* assumed to never throw {@link RejectedExecutionException}. Synchronous executors are
* supported but the risk of stack overflow will be higher. Note that when the executor
* resumes
* the flow, the directives that follow are run sequentially within the same
* {@link Runnable#run()} call, until the flow completes or the next {@code goTo()} or, if
* applicable, {@code goLazy()} directive is reached. Depending on the directives and
* operators
* used, this may starve the executor. If necessary, use additional {@code goTo()}
* directives
* with the same executor to achieve fairness.
*/
/**
* RFlow 线程池操作
*
* @param executor 线程池
* @return 一个 RFlow 流状态
*
* 所有类型跟执行 goTo 前的类型一样
*/
@NonNull TSelf goTo(@NonNull Executor executor);
/**
* Suspend the data processing flow and notify the registered {@link Updatable}s of
* updates.
* The remaining of the flow will be run synchronously <i>and uninterruptibly</i> the first
* time
* {@link Repository#get()} is called, to produce the new repository value lazily. After
* this
* directive, {@link #goTo(Executor)} is no longer available, and all further operators
* should
* be fairly lightweight in order not to block the callers of {@code get()} for too long.
*/
/**
* RFlow 懒加载操作
*
* @return 返回 一个 所有类型相同 RSyncFlow 同步流状态
*/
@NonNull RSyncFlow<TVal, TPre, ?> goLazy();
}
/**
* Compiler state allowing to specify the final synchronous steps of the data processing flow.
*
* @param <TVal> Value type of the repository.
* @param <TPre> The output value type of the previous directive.
* @param <TSelf> Self-type; for Java compiler type inference only.
*
* RSyncFlow 同步流状态
*
* TVal 类型 作为 RSyncFlow 仓库数据类型
* TPre 类型 作为 RSyncFlow 上一个数据流输出类型
*/
interface RSyncFlow<TVal, TPre, TSelf extends RSyncFlow<TVal, TPre, TSelf>> {
/**
* Ignore the input value, and use the value newly obtained from the given supplier as the
* output value.
*/
/**
* RSyncFlow 获取数据操作
* 可类型转换( 供应者 )
*
* @param supplier 供应者
* @param <TCur> 供应者 的 目标类型
* @return 返回 一个 RSyncFlow 同步流状态
*
* TVal 类型 作为 RSyncFlow 仓库数据类型
* TCur 类型 作为 RSyncFlow 上一个数据流输出类型
*/
@NonNull <TCur> RSyncFlow<TVal, TCur, ?> getFrom(@NonNull Supplier<TCur> supplier);
/**
* Like {@link #getFrom}, ignore the input value and attempt to get the new value from the
* given
* supplier. If the attempt fails, terminate the data processing flow by sending the
* failure
* to
* the termination clause that follows; otherwise take the successful value as the output
* of
* this directive.
*/
/**
* RSyncFlow 尝试获取数据操作
* 可以截获异常,进行处理( 供应者+Result )
*
* @param attemptSupplier Result 供应者
* @param <TCur> Result 供应者 的 目标类型
* @return 返回一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RSyncFlow<TVal, TCur, ?> 类型 作为 RTermination 编译返回状态类型
*/
@NonNull <TCur>
RTermination<TVal, Throwable, ? extends RSyncFlow<TVal, TCur, ?>> attemptGetFrom(
@NonNull Supplier<Result<TCur>> attemptSupplier);
/**
* Take the input value and the value newly obtained from the given supplier, merge them
* using
* the given merger, and use the resulting value as the output value.
*/
/**
* RSyncFlow 合并操作
* 可类型转换( 供应者 )
* 可以合并供应者转换后的数据 和 之前的流处理结果数据( 合并者 )
*
* @param supplier 供应者
* @param merger 合并者
* @param <TAdd> 供应者 的 目标类型
* @param <TCur> 合并者 的 目标类型
* @return 返回 一个 RSyncFlow 同步流状态
*
* TVal 类型 作为 RSyncFlow 仓库数据类型
* TCur 类型 作为 RSyncFlow 上一个数据流输出类型
*/
@NonNull <TAdd, TCur> RSyncFlow<TVal, TCur, ?> mergeIn(@NonNull Supplier<TAdd> supplier,
@NonNull
Merger<? super TPre, ? super TAdd, TCur> merger);
/**
* Like {@link #mergeIn}, take the input value and the value newly obtained from the given
* supplier, and attempt to merge them using the given merger. If the attempt fails,
* terminate
* the data processing flow by sending the failure to the termination clause that follows;
* otherwise take the successful value as the output of this directive.
*
* <p>This method is agnostic of the return type of the {@code supplier}. If it itself is
* fallible, the {@code merger} is held responsible for processing the failure, which may
* choose
* to pass the failure on as the result of the merge.
*/
/**
* RSyncFlow 尝试合并操作
* 可类型转换( 供应者 )
* 可以合并供应者转换后的数据 和 之前的流处理结果数据( 合并者 )
* 可以截获异常,进行处理( 合并者+Result )
*
* @param supplier 供应者
* @param attemptMerger 合并者
* @param <TAdd> 供应者 的 目标类型
* @param <TCur> 合并者 的 Result 目标类型
* @return 返回 一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RSyncFlow<TVal, TCur, ?> 类型 作为 RTermination 编译返回状态类型
*/
@NonNull <TAdd, TCur>
RTermination<TVal, Throwable, ? extends RSyncFlow<TVal, TCur, ?>> attemptMergeIn(
@NonNull Supplier<TAdd> supplier,
@NonNull Merger<? super TPre, ? super TAdd, Result<TCur>> attemptMerger);
/**
* Transform the input value using the given function into the output value.
*/
/**
* RSyncFlow 转换操作
* 用于类型转换
* 与 getFrom(...) 的区别:
* getFrom(...) 是通过 Supplier 可以在提供数据时,进行间接的类型转换
* transform(...) 是通过 Function 进行直接的类型之间转换
*
* @param function 转换方法
* @param <TCur> 转换方法 的 目标类型
* @return 返回 一个 RFlow 流状态
*
* TVal 类型 作为 RSyncFlow 仓库数据类型
* TCur 类型 作为 RSyncFlow 上一个数据流输出类型
*/
@NonNull <TCur> RSyncFlow<TVal, TCur, ?> transform(
@NonNull Function<? super TPre, TCur> function);
/**
* Like {@link #transform}, attempt to transform the input value using the given function.
* If
* the attempt fails, terminate the data processing flow by sending the failure to the
* termination clause that follows; otherwise take the successful value as the output of
* this
* directive.
*/
/**
* RSyncFlow 尝试转换操作
* 用于类型转换
* 可以截获异常,进行处理( 转换方法+Result )
*
* @param attemptFunction 转换方法
* @param <TCur> 转换方法 的 Result 目标类型
* @return 返回 一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RSyncFlow<TVal, TCur, ?> 类型 作为 RTermination 编译返回状态类型
*/
@NonNull
<TCur> RTermination<TVal, Throwable, ? extends RSyncFlow<TVal, TCur, ?>> attemptTransform(
@NonNull Function<? super TPre, Result<TCur>> attemptFunction);
/**
* Check the input value with the given predicate. If the predicate applies, continue the
* data
* processing flow with the same value, otherwise terminate the flow with the termination
* clause
* that follows. The termination clause takes the input value as its input.
*/
/**
* RSyncFlow 检查方法
* 需要传入一个 断定者,进行上个流传入类型数据的检查操作
*
* @param predicate 断定者
* @return 返回 一个 RTermination 终止状态
*
* 类型全部不变地传下去
*/
@NonNull RTermination<TVal, TPre, TSelf> check(@NonNull Predicate<? super TPre> predicate);
/**
* Use the case-function to compute a case value out of the input value and check it with
* the
* given predicate. If the predicate applies to the case value, continue the data
* processing
* flow with the <i>input value</i>, otherwise terminate the flow with the termination
* clause
* that follows. The termination clause takes the <i>case value</i> as its input.
*/
/**
* RSyncFlow 检查方法
* 需要
* 传入一个 转换方法,进行上个流类型数据的转换,转换为 TCase 类型
* 再传入一个 断定者,进行转换后类型数据的检查操作
*
* @param caseFunction 转换方法
* @param casePredicate 断定者
* @param <TCase> 转换后的数据类型,也是要判断的数据类型
* @return 返回 一个 RTermination 终止状态
*
* 类型全部不变地传下去
*/
@NonNull <TCase> RTermination<TVal, TCase, TSelf> check(
@NonNull Function<? super TPre, TCase> caseFunction,
@NonNull Predicate<? super TCase> casePredicate);
/**
* Send the input value to the given receiver, and then pass on the input value as the
* output of
* this directive, not modifying it.
*
* <p>Typical uses of this directive include reporting progress and/or errors in the UI,
* starting a side process, logging, profiling and debugging, etc. The {@link
* Receiver#accept}
* method is called synchronously, which means its execution blocks the rest of the data
* processing flow. If the flow is to cancel with {@linkplain RepositoryConfig#SEND_INTERRUPT
* the interrupt signal}, the receiver may also see the signal.
*
* <p>The receiver does not have to use the input value, but if it does and it moves onto a
* different thread for processing the input value, note that the data processing flow does
* not
* guarantee value immutability or concurrent access for this receiver. For this reason,
* for
* a
* UI-calling receiver invoked from a background thread, implementation should extract any
* necessary data from the input value, and post the immutable form of it to the main
* thread
* for
* the UI calls, so the UI modifications are main-thread-safe while the data processing
* flow
* can
* continue concurrently.
*
* <p>Note that the blocking semantics of this directive should not be taken as the
* permission
* to mutate the input in a way that affects the rest of the flow -- the appropriate
* directive
* for that purpose is {@code transform}, with a function that returns the same input
* instance
* after mutation.
*/
/**
* RSyncFlow 发送操作
* 其实就是 添加一个 Receiver
*
* @param receiver 接受者
* @return 返回一个 RSyncFlow 同步流状态
*
* 所有类型跟执行 sendTo 前的类型一样
*/
@NonNull TSelf sendTo(@NonNull Receiver<? super TPre> receiver);
/**
* Send the input value and the value from the given supplier to the given binder, and then
* pass
* on the input value as the output of this directive, not modifying it.
*
* <p>The same usage notes for {@link #sendTo} apply to this directive.
*/
/**
* RSyncFlow 绑定操作
* 需要
* 传入一个 供应者,提供 TAdd 类型数据
* 再传入一个 绑定者,进行上一个流的类型 TPre 数据 与 供应者提供的 TAdd 数据进行绑定
*
* @param secondValueSupplier 供应者
* @param binder 绑定者
* @param <TAdd> 供应者 的 目标类型
* @return 返回一个 RSyncFlow 同步流状态
*
* 所有类型跟执行 bindWith 前的类型一样
*/
@NonNull <TAdd> TSelf bindWith(@NonNull Supplier<TAdd> secondValueSupplier,
@NonNull Binder<? super TPre, ? super TAdd> binder);
/**
* End the data processing flow but without using the output value and without notifying
* the
* registered {@link Updatable}s.
*/
/**
* RSyncFlow 快进操作
* 什么也不做,直接快进到 RConfig 配置状态
*
* @return 返回一个 RConfig 配置状态
*
* TVal 类型 作为 RConfig 的仓库类型
*/
@NonNull RConfig<TVal> thenSkip();
/**
* Perform the {@link #getFrom} directive and use the output value as the new value of the
* compiled repository, with notification if necessary.
*/
/**
* RSyncFlow 快进获取数据操作
* 可类型转换( 供应者 )
*
* @param supplier 供应者
* @return 返回 一个 RConfig 配置状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
@NonNull RConfig<TVal> thenGetFrom(@NonNull Supplier<? extends TVal> supplier);
/**
* Perform the {@link #attemptGetFrom} directive and use the successful output value as the
* new
* value of the compiled repository, with notification if necessary.
*/
/**
* RSyncFlow 快进尝试获取数据操作
* 可以截获异常,进行处理( 供应者+Result )
*
* @param attemptSupplier Result 供应者
* @return 返回一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RConfig<TVal> 类型 作为 RTermination 编译返回状态类型
*/
// @NonNull RTermination<TVal, Throwable, RConfig<TVal>> thenAttemptGetFrom(
// @NonNull Supplier<? extends Result<? extends TVal>> attemptSupplier);
@NonNull
RTerminationOrContinue<TVal, Throwable, RConfig<TVal>,
? extends RSyncFlow<TVal, Throwable, ?>> thenAttemptGetFrom(
@NonNull Supplier<? extends Result<? extends TVal>> attemptSupplier);
/**
* Perform the {@link #mergeIn} directive and use the output value as the new value of the
* compiled repository, with notification if necessary.
*/
/**
* RSyncFlow 快进合并操作
* 可类型转换( 供应者 )
* 可以合并供应者转换后的数据 和 之前的流处理结果数据( 合并者 )
*
* @param supplier 供应者
* @param merger 合并者
* @param <TAdd> 供应者 的 目标类型
* @return 返回 一个 RConfig 配置状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
@NonNull <TAdd> RConfig<TVal> thenMergeIn(@NonNull Supplier<TAdd> supplier,
@NonNull
Merger<? super TPre, ? super TAdd, ? extends TVal> merger);
/**
* Perform the {@link #attemptMergeIn} directive and use the successful output value as the
* new
* value of the compiled repository, with notification if necessary.
*/
/**
* RSyncFlow 快进尝试合并操作
* 可类型转换( 供应者 )
* 可以合并供应者转换后的数据 和 之前的流处理结果数据( 合并者 )
* 可以截获异常,进行处理( 合并者+Result )
*
* @param supplier 供应者
* @param attemptMerger 合并者
* @param <TAdd> 供应者 的 目标类型
* @return 返回 一个 RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RConfig<TVal> 类型 作为 RTermination 编译返回状态类型
*/
// @NonNull <TAdd> RTermination<TVal, Throwable, RConfig<TVal>> thenAttemptMergeIn(
// @NonNull Supplier<TAdd> supplier,
// @NonNull Merger<? super TPre, ? super TAdd,
// ? extends Result<? extends TVal>> attemptMerger);
@NonNull
<TAdd> RTerminationOrContinue<TVal, Throwable, RConfig<TVal>,
? extends RSyncFlow<TVal, Throwable, ?>> thenAttemptMergeIn(
@NonNull Supplier<TAdd> supplier,
@NonNull Merger<? super TPre, ? super TAdd,
? extends Result<? extends TVal>> attemptMerger);
/**
* Perform the {@link #transform} directive and use the output value as the new value of
* the
* compiled repository, with notification if necessary.
*/
/**
* RSyncFlow 快进转换操作
* 用于类型转换
*
* @param function 转换方法
* @return 返回 一个 RConfig 配置状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
@NonNull RConfig<TVal> thenTransform(
@NonNull Function<? super TPre, ? extends TVal> function);
/**
* Perform the {@link #attemptTransform} directive and use the successful output value as
* the
* new value of the compiled repository, with notification if necessary.
*/
/**
* RSyncFlow 快进尝试转换操作
* 用于类型转换
* 可以截获异常,进行处理( 转换方法+Result )
*
* @param attemptFunction 转换方法
* @return 返回 一个 RConfig 配置状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* Throwable 类型 作为 RTermination 流终止类型
* RConfig<TVal> 类型 作为 RTermination 编译返回状态类型
*/
// @NonNull RTermination<TVal, Throwable, RConfig<TVal>> thenAttemptTransform(
// @NonNull Function<? super TPre, ? extends Result<? extends TVal>> attemptFunction);
@NonNull
RTerminationOrContinue<TVal, Throwable, RConfig<TVal>,
? extends RSyncFlow<TVal, Throwable, ?>> thenAttemptTransform(
@NonNull Function<? super TPre, ? extends Result<? extends TVal>> attemptFunction);
}
/**
* Compiler state allowing to terminate the data processing flow following a failed check.
*
* @param <TVal> Value type of the repository.
* @param <TTerm> Value type from which to terminate the flow.
* @param <TRet> Compiler state to return to.
*
* RTermination 终止状态
*
* TVal 类型 作为 RTermination 仓库数据类型
* TTerm 类型 作为 RTermination 流终止时的状态,一般为 Throwable
* TRet 类型 作为 RTermination 编译返回的状态,只有两种状态( RFlow( RSyncFlow )、RConfig )
*/
interface RTermination<TVal, TTerm, TRet> {
/**
* If the previous check failed, skip the rest of the data processing flow, and do not
* notify
* any registered {@link Updatable}s.
*/
/**
* RTermination 快进操作
*
* @return 只有可能返回 RFlow( RSyncFlow )、RConfig 状态
*/
@NonNull TRet orSkip();
/**
* If the previous check failed, terminate the data processing flow and update the compiled
* repository's value to the resulting value of applying the given function to the input of
* this
* termination clause, with notification if necessary.
*/
/**
* RTermination 结束状态
* 其实又一次进行转换
*
* @param valueFunction 转换方法
* @return 只有可能返回 RFlow( RSyncFlow )、RConfig 状态
*/
@NonNull TRet orEnd(@NonNull Function<? super TTerm, ? extends TVal> valueFunction);
}
/**
* Compiler state allowing to terminate or continue the data processing flow following a failed
* attempt to produce the new value of the repository.
*
* @param <TVal> Value type of the repository.
* @param <TTerm> Value type from which to terminate the flow.
* @param <TRet> Compiler state to return to if the flow is terminated.
* @param <TCon> Compiler state to return to if the flow is to continue.
*/
interface RTerminationOrContinue<TVal, TTerm, TRet, TCon>
extends RTermination<TVal, TTerm, TRet> {
/**
* If the previous attempt failed, continue with the rest of the data processing flow, using the
* {@linkplain Result#getFailure() failure} as the input value to the next directive. Otherwise,
* end the data processing flow and use the successful output value from the attempt as the new
* value of the compiled repository, with notification if necessary.
*/
@NonNull
TCon orContinue();
}
/**
* Compiler state allowing to configure and end the declaration of the repository.
*
* @param <TVal> Repository value type.
*
* RConfig 配置状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
interface RConfig<TVal> {
/**
* Specifies that this repository should notify the registered {@link Updatable}s if and
* only if
* the given {@code checker} returns {@link Boolean#TRUE}. Every time the data processing
* flow
* ends with a new repository value, the checker is called with the old repository value as
* the
* first argument and the new value the second. The return value determines whether this
* update
* should generate a notification. The default behavior is to notify of the update when the
* new
* value is different as per {@link Object#equals}.
*
* <p>Note that the {@code goLazy()} directive will always generate a notification, as a
* preventative measure to handle a potentially different value which is unknown at the
* time
* of
* {@code goLazy()}. Also, technically the {@link RepositoryConfig#RESET_TO_INITIAL_VALUE}
* deactivation configuration would also update the repository value, and therefore the
* {@code checker} will be consulted, but because the reset happens only when the
* repository
* is
* deactivated, even if the checker returns true, there is no {@link Updatable} to receive
* the
* notification.
*/
/**
* RConfig 通知操作
* 会传入一个 合并者,合并出一个 Boolean 类型
*
* @param checker 合并者
* @return 返回一个 RConfig 状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
@NonNull RConfig<TVal> notifyIf(
@NonNull Merger<? super TVal, ? super TVal, Boolean> checker);
/**
* Specifies the behaviors when this repository is deactivated, i.e. from being observed to
* not
* being observed. The default behavior is {@link RepositoryConfig#CONTINUE_FLOW}.
*
* @param deactivationConfig A bitwise combination of the constants in {@link
* RepositoryConfig}.
*/
/**
* RConfig 失效时的操作( 一些特殊的行为:导致仓库失效,从观察状态变为不观察状态 )
*
* @param deactivationConfig RepositoryConfig 类型
* @return 返回一个 RConfig 配置状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
@NonNull RConfig<TVal> onDeactivation(@RepositoryConfig int deactivationConfig);
/**
* Specifies the behaviors when an update is observed from an event source while a data
* processing flow is ongoing. The default behavior is {@link RepositoryConfig#CONTINUE_FLOW}.
*
* @param concurrentUpdateConfig A bitwise combination of the constants in
* {@link RepositoryConfig}.
*/
/**
* RConfig 并发更新时( 一些特殊的行为:一个观察者从事件源中被观察了,然后一个数据处理流还在运行 )
*
* @param concurrentUpdateConfig RepositoryConfig 类型
* @return 返回一个 RConfig 配置状态
*
* TVal 类型 作为 RConfig 仓库数据类型
*/
@NonNull RConfig<TVal> onConcurrentUpdate(@RepositoryConfig int concurrentUpdateConfig);
/**
* Compiles a {@link Repository} that exhibits the previously defined behaviors.
*/
/**
* RConfig 完成操作
*
* @return 返回一个 仓库 Repository
*
* TVal 类型 作为 Repository 仓库数据类型
*/
@NonNull Repository<TVal> compile();
/**
* Compiles a repository that exhibits the previously defined behaviors, and starts
* compiling
* a new repository with the given initial value (which can be of a different type) that
* uses
* the former repository as the first event source and the first data source.
*
* <p>This method provides a shortcut for the following code:
*
* <pre>
* {@literal Repository<TVal>} subRepository = ….compile();
* {@literal Repository<TVal2>} mainRepository = repositoryWithInitialValue(value)
* .observe(subRepository)
* .… // additional event sources and frequency which can be defined after this method
* .getFrom(subRepository) // first directive
* .… // rest of data processing flow, configuration, compile()
* }</pre>
*
* The repository compiled by this method (the {@code subRepository}) therefore acts as a
* buffer for the next repository to compile (the {@code mainRepository}), with its own
* event
* sources and data processing flow. This simplifies or shortens the flow of the new
* repository,
* and is typically useful if different parts of the overall data processing flow depend on
* different event sources and data sources, and it is beneficial to cache the intermediate
* values between parts.
*
* <p>However, due to the {@code getFrom} directive at the start of this new data
* processing
* flow, the next repository to compile has no access to its previous value. Additionally,
* the
* former repository is not exposed anywhere else. If this is undesirable, consider using
* the
* full form, where the former repository is explicitly compiled.
*/
/**
* RConfig 重构操作
* 重新将一个仓库编译过程后得到 的 RConfig 状态,还有最终目标数据 TVal
* 作为重构仓库的材料,会直接跳到 仓库类型为 TVal2 的编译状态中的
* RFrequency 频率状态
*
* @param value 新仓库的目标数据类型初始值
* @param <TVal2> 新仓库的目标数据类型
* @return 新仓库编译状态中的 RFrequency 频率状态
*/
@NonNull <TVal2> RFrequency<TVal2, TVal> compileIntoRepositoryWithInitialValue(
@NonNull TVal2 value);
}
}