/* * Copyright (C) 2025 The Android Open Source Project * * 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.android.app.concurrent.benchmark.event import com.android.app.concurrent.benchmark.base.BaseSchedulerBenchmark import com.android.app.concurrent.benchmark.util.ThreadFactory import com.android.app.concurrent.benchmark.util.dbg import org.junit.After import org.junit.Before sealed interface EventBox { val event: E } abstract class AbstractEventBox(override val event: E) : EventBox interface ReadContext { fun EventBox.observe(block: (T) -> Unit) } interface WriteContext { fun EventBox.update(value: T) fun EventBox.current(): T } /** Defines the core capability of creating a source state. */ interface WritableEventFactory { fun createWritableEvent(value: T): EventBox } /** Defines the capability of combining two or three states into a derived state. */ interface EventCombiner { fun combineEvents( a: EventBox, b: EventBox, transform: (T1, T2) -> T3, ): EventBox fun combineEvents( a: EventBox, b: EventBox, c: EventBox, transform: (T1, T2, T3) -> T4, ): EventBox } /** Defines the specialized capability of combining a list of integer states. */ interface IntEventCombiner { fun combineIntEvents( events: Iterable>, transform: (Array) -> R, ): EventBox } object NoopAutoCloseable : AutoCloseable { override fun close() {} } /** Defines the capability of providing read/write contexts and managing lifecycle. */ interface EventContext { fun dispose() {} } /** Defines the capability of providing read/write contexts and managing lifecycle. */ interface EventContextProvider { fun read(block: ReadContext.() -> Unit): AutoCloseable fun write(block: WriteContext.() -> Unit) } interface MapOperator { fun EventBox.map(transform: (A) -> B): EventBox } interface SampleOperator { fun EventBox.sample( other: EventBox, transform: (A, B) -> C, ): EventBox } interface FilterOperator { fun EventBox.filter(predicate: (T) -> Boolean): EventBox } interface DistinctUntilChangedOperator { fun EventBox.distinctUntilChanged(): EventBox } abstract class BaseEventBenchmark( threadParam: ThreadFactory, val build: (T) -> P, ) : BaseSchedulerBenchmark(threadParam) { private lateinit var _context: P val context: P get() = _context @Before fun setupEventContext() { _context = build(scheduler) } @After fun disposeEventContext() { dbg { "dispose" } _context.dispose() } }