Orbit 라이브러리를 사용하면, 다음과 같이 intent DSL 코드를 작성할 수 있습니다.

intent { ... }

MVI 패턴을 추구하는 Orbit 라이브러리이니, 해당 부분이 MVI 패턴에서 intent action 부분일 것 같네요. 그래서 State와 SideEffect 는 별도의 클래스를 분리하지만 해당 Intent 는 분리하지 않는 것을 알 수 있었습니다.

(네 그렇습니다. 해당 DSL을 사용하기 위해서는 사용되는 위치 클래스가 ContainerHost<STATE, SIDE_EFFECT> 를 상속하고 있어야 합니다. 아래의 intent DSL 코드로 명세된 함수를 살펴보면, ContainerHost<STATE, SIDE_EFFECT> 를 확장하여 intent DSL 코드를 만드는 것을 알 수 있습니다.)

해당 DSL을 추적해보겠습니다.

@OrbitDsl
public fun <STATE : Any, SIDE_EFFECT : Any> ContainerHost<STATE, SIDE_EFFECT>.intent(
    registerIdling: Boolean = true,
    transformer: suspend SimpleSyntax<STATE, SIDE_EFFECT>.() -> Unit
): Job = container.intent(registerIdling) { SimpleSyntax(this).transformer() }

SimpleSyntax

SimpleSyntax 클래스를 살펴봅시다.

@OrbitDsl
public class SimpleSyntax<S : Any, SE : Any>(public val containerContext: ContainerContext<S, SE>) {
    public val state: S get() = containerContext.state
}
@OrbitInternal
public class ContainerContext<S : Any, SE : Any>(
    public val settings: RealSettings,
    public val postSideEffect: suspend (SE) -> Unit,
    private val getState: () -> S,
    public val reduce: suspend ((S) -> S) -> Unit,
    public val subscribedCounter: SubscribedCounter
) {
    public val state: S
        get() = getState()
}

자 SimpleSyntax 클래스는 intent DSL 함수에서 suspend 키워드를 사용하여 비동기식으로 처리됩니다. 또한, ContainerContext 클래스를 사용하여 내부의 컴포넌트인 state 즉, 상태 프로퍼티를 가져옵니다.

그렇기 때문에, intent DSL 함수 블록에서는 state 변수를 사용할 수 있습니다.

intent { state }