/* * 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.util.dbg import java.util.concurrent.Executor typealias DirectEventBoxIn = EventBox> typealias DirectEventBoxOut = EventBox> typealias DirectWritableEventBoxOut = EventBox> private class DirectEventBoxImpl>(event: E) : AbstractEventBox(event) private fun DirectEventBoxIn.unbox(): DirectEvent = (this as DirectEventBoxImpl).event class DirectWritableEventBuilder(val executor: Executor) : EventContext, WritableEventFactory>, EventContextProvider>, IntEventCombiner> { private val producers = mutableListOf>() override fun createWritableEvent(value: T): DirectWritableEventBoxOut { return DirectEventBoxImpl(DirectWritableEvent(value)) } override fun combineIntEvents( events: Iterable>, transform: (Array) -> R, ): DirectEventBoxOut { dbg { "combineIntEvents" } val producer = DirectEvent( recalculate = { val intArray = events .map { (it.unbox() as DirectWritableEvent).value } .toList() .toTypedArray() val rv = transform(intArray) dbg { "recalculate rv=$rv" } rv } ) producers += producer return DirectEventBoxImpl(producer) } val readContext = object : ReadContext> { override fun DirectEventBoxIn.observe(block: (T) -> Unit) { val directEvent = (this as DirectEventBoxImpl).event directEvent.callback = block directEvent.refresh(executor) } } override fun read(block: ReadContext>.() -> Unit): AutoCloseable { with(readContext) { block() } return NoopAutoCloseable } val writeContext = object : WriteContext> { override fun DirectEventBoxIn.update(value: T) { (unbox() as DirectWritableEvent).value = value } override fun DirectEventBoxIn.current(): T { return (unbox() as DirectWritableEvent).value } } override fun write(block: WriteContext>.() -> Unit) { with(writeContext) { dbg { "START write block {{{" } block() dbg { "}}} END write block" } producers.forEach { it.refresh(executor) } } } } open class DirectEvent(val recalculate: (() -> T)? = null) { var callback: (T) -> Unit = {} fun refresh(executor: Executor) { dbg { "refresh()" } recalculate?.let { executor.execute { callback(it()) } } } } class DirectWritableEvent(initialValue: T) : DirectEvent() { var value: T = initialValue get() { dbg { "DirectWritableEvent#getValue -> $field" } return field } set(value) { dbg { "DirectWritableEvent#setValue $field -> $value" } field = value } init { dbg { "DirectWritableEvent#init value=$initialValue" } } }