Made cell implementations internal and added some factory methods.

This commit is contained in:
Daan Vanden Bosch 2022-11-01 15:00:19 +01:00
parent 2bcde67e18
commit e10ac484d7
39 changed files with 77 additions and 69 deletions

View File

@ -2,7 +2,7 @@ package world.phantasmal.cell
import world.phantasmal.core.unsafe.unsafeCast import world.phantasmal.core.unsafe.unsafeCast
abstract class AbstractDependentCell<T, Event : ChangeEvent<T>> : AbstractCell<T>(), Dependent { internal abstract class AbstractDependentCell<T, Event : ChangeEvent<T>> : AbstractCell<T>(), Dependent {
protected var _value: T? = null protected var _value: T? = null
final override val value: T final override val value: T

View File

@ -2,7 +2,7 @@ package world.phantasmal.cell
import world.phantasmal.core.unsafe.unsafeAssertNotNull import world.phantasmal.core.unsafe.unsafeAssertNotNull
abstract class AbstractFlatteningDependentCell<T, ComputedCell : Cell<T>, Event : ChangeEvent<T>>( internal abstract class AbstractFlatteningDependentCell<T, ComputedCell : Cell<T>, Event : ChangeEvent<T>>(
private val dependencies: Array<out Cell<*>>, private val dependencies: Array<out Cell<*>>,
private val compute: () -> ComputedCell, private val compute: () -> ComputedCell,
) : AbstractDependentCell<T, Event>() { ) : AbstractDependentCell<T, Event>() {

View File

@ -6,7 +6,7 @@ import world.phantasmal.core.unsafe.unsafeCast
/** /**
* Calls [callback] when [dependency] changes. * Calls [callback] when [dependency] changes.
*/ */
class CallbackChangeObserver<T, E : ChangeEvent<T>>( internal class CallbackChangeObserver<T, E : ChangeEvent<T>>(
private val dependency: Cell<T>, private val dependency: Cell<T>,
// We don't use ChangeObserver<T> because of type system limitations. It would break e.g. // We don't use ChangeObserver<T> because of type system limitations. It would break e.g.
// AbstractListCell.observeListChange. // AbstractListCell.observeListChange.

View File

@ -5,7 +5,7 @@ import world.phantasmal.core.disposable.TrackedDisposable
/** /**
* Calls [callback] when one or more cells in [dependencies] change. * Calls [callback] when one or more cells in [dependencies] change.
*/ */
class CallbackObserver( internal class CallbackObserver(
private vararg val dependencies: Cell<*>, private vararg val dependencies: Cell<*>,
private val callback: () -> Unit, private val callback: () -> Unit,
) : TrackedDisposable(), LeafDependent { ) : TrackedDisposable(), LeafDependent {

View File

@ -1,6 +1,6 @@
package world.phantasmal.cell package world.phantasmal.cell
class DelegatingCell<T>( internal class DelegatingCell<T>(
private val getter: () -> T, private val getter: () -> T,
private val setter: (T) -> Unit, private val setter: (T) -> Unit,
) : AbstractCell<T>(), MutableCell<T> { ) : AbstractCell<T>(), MutableCell<T> {

View File

@ -3,7 +3,7 @@ package world.phantasmal.cell
/** /**
* Cell of which the value depends on 0 or more dependencies. * Cell of which the value depends on 0 or more dependencies.
*/ */
class DependentCell<T>( internal class DependentCell<T>(
private vararg val dependencies: Cell<*>, private vararg val dependencies: Cell<*>,
private val compute: () -> T, private val compute: () -> T,
) : AbstractDependentCell<T, ChangeEvent<T>>() { ) : AbstractDependentCell<T, ChangeEvent<T>>() {

View File

@ -3,7 +3,7 @@ package world.phantasmal.cell
/** /**
* Similar to [DependentCell], except that this cell's [compute] returns a cell. * Similar to [DependentCell], except that this cell's [compute] returns a cell.
*/ */
class FlatteningDependentCell<T>( internal class FlatteningDependentCell<T>(
vararg dependencies: Cell<*>, vararg dependencies: Cell<*>,
compute: () -> Cell<T>, compute: () -> Cell<T>,
) : AbstractFlatteningDependentCell<T, Cell<T>, ChangeEvent<T>>(dependencies, compute) { ) : AbstractFlatteningDependentCell<T, Cell<T>, ChangeEvent<T>>(dependencies, compute) {

View File

@ -3,7 +3,7 @@ package world.phantasmal.cell
import world.phantasmal.core.disposable.Disposable import world.phantasmal.core.disposable.Disposable
import world.phantasmal.core.disposable.nopDisposable import world.phantasmal.core.disposable.nopDisposable
class ImmutableCell<T>(override val value: T) : Dependency<T>, Cell<T> { internal class ImmutableCell<T>(override val value: T) : Dependency<T>, Cell<T> {
override val changeEvent: ChangeEvent<T>? get() = null override val changeEvent: ChangeEvent<T>? get() = null
override fun addDependent(dependent: Dependent) { override fun addDependent(dependent: Dependent) {

View File

@ -1,6 +1,6 @@
package world.phantasmal.cell package world.phantasmal.cell
class SimpleCell<T>(value: T) : AbstractCell<T>(), MutableCell<T> { internal class SimpleCell<T>(value: T) : AbstractCell<T>(), MutableCell<T> {
override var value: T = value override var value: T = value
set(value) { set(value) {
if (value != field) { if (value != field) {

View File

@ -5,7 +5,7 @@ import world.phantasmal.cell.Dependent
import world.phantasmal.cell.MutationManager import world.phantasmal.cell.MutationManager
import world.phantasmal.core.unsafe.unsafeCast import world.phantasmal.core.unsafe.unsafeCast
abstract class AbstractFilteredListCell<E>( internal abstract class AbstractFilteredListCell<E>(
protected val list: ListCell<E>, protected val list: ListCell<E>,
) : AbstractListCell<E>(), Dependent { ) : AbstractListCell<E>(), Dependent {

View File

@ -8,7 +8,7 @@ import world.phantasmal.cell.AbstractCell
import world.phantasmal.cell.Cell import world.phantasmal.cell.Cell
import world.phantasmal.cell.DependentCell import world.phantasmal.cell.DependentCell
abstract class AbstractListCell<E> : AbstractCell<List<E>>(), ListCell<E> { internal abstract class AbstractListCell<E> : AbstractCell<List<E>>(), ListCell<E> {
private var _size: Cell<Int>? = null private var _size: Cell<Int>? = null
final override val size: Cell<Int> final override val size: Cell<Int>

View File

@ -7,7 +7,7 @@ import world.phantasmal.cell.Cell
/** /**
* ListCell of which the value depends on 0 or more other cells. * ListCell of which the value depends on 0 or more other cells.
*/ */
class DependentListCell<E>( internal class DependentListCell<E>(
private vararg val dependencies: Cell<*>, private vararg val dependencies: Cell<*>,
private val computeElements: () -> List<E>, private val computeElements: () -> List<E>,
) : AbstractListCell<E>(), Dependent { ) : AbstractListCell<E>(), Dependent {

View File

@ -8,7 +8,7 @@ import world.phantasmal.core.assert
import world.phantasmal.core.assertUnreachable import world.phantasmal.core.assertUnreachable
import world.phantasmal.core.unsafe.unsafeCast import world.phantasmal.core.unsafe.unsafeCast
class FilteredListCell<E>( internal class FilteredListCell<E>(
list: ListCell<E>, list: ListCell<E>,
private val predicate: Cell<(E) -> Cell<Boolean>>, private val predicate: Cell<(E) -> Cell<Boolean>>,
) : AbstractFilteredListCell<E>(list) { ) : AbstractFilteredListCell<E>(list) {

View File

@ -9,7 +9,7 @@ import world.phantasmal.core.unsafe.unsafeAssertNotNull
*/ */
// TODO: Improve performance when transitive cell changes. At the moment a change event is generated // TODO: Improve performance when transitive cell changes. At the moment a change event is generated
// that just pretends the whole list has changed. // that just pretends the whole list has changed.
class FlatteningDependentListCell<E>( internal class FlatteningDependentListCell<E>(
vararg dependencies: Cell<*>, vararg dependencies: Cell<*>,
computeElements: () -> ListCell<E>, computeElements: () -> ListCell<E>,
) : ) :

View File

@ -1,16 +1,13 @@
package world.phantasmal.cell.list package world.phantasmal.cell.list
import world.phantasmal.cell.*
import world.phantasmal.core.disposable.Disposable import world.phantasmal.core.disposable.Disposable
import world.phantasmal.core.disposable.nopDisposable import world.phantasmal.core.disposable.nopDisposable
import world.phantasmal.cell.ChangeObserver
import world.phantasmal.cell.Dependency
import world.phantasmal.cell.Dependent
import world.phantasmal.cell.Cell
import world.phantasmal.cell.cell
import world.phantasmal.cell.falseCell
import world.phantasmal.cell.trueCell
class ImmutableListCell<E>(private val elements: List<E>) : Dependency<List<E>>, ListCell<E> { internal class ImmutableListCell<E>(
private val elements: List<E>,
) : Dependency<List<E>>, ListCell<E> {
override val size: Cell<Int> = cell(elements.size) override val size: Cell<Int> = cell(elements.size)
override val empty: Cell<Boolean> = if (elements.isEmpty()) trueCell() else falseCell() override val empty: Cell<Boolean> = if (elements.isEmpty()) trueCell() else falseCell()
override val notEmpty: Cell<Boolean> = if (elements.isNotEmpty()) trueCell() else falseCell() override val notEmpty: Cell<Boolean> = if (elements.isNotEmpty()) trueCell() else falseCell()

View File

@ -9,6 +9,10 @@ private val EMPTY_LIST_CELL = ImmutableListCell<Nothing>(emptyList())
/** Returns an immutable list cell containing [elements]. */ /** Returns an immutable list cell containing [elements]. */
fun <E> listCell(vararg elements: E): ListCell<E> = ImmutableListCell(elements.toList()) fun <E> listCell(vararg elements: E): ListCell<E> = ImmutableListCell(elements.toList())
/** Returns a list cell backed by [elements]. */
fun <E> listCell(elements: List<E>): ListCell<E> =
ImmutableListCell(elements)
/** Returns a singleton empty immutable cell. */ /** Returns a singleton empty immutable cell. */
fun <E> emptyListCell(): ListCell<E> = EMPTY_LIST_CELL fun <E> emptyListCell(): ListCell<E> = EMPTY_LIST_CELL
@ -16,6 +20,10 @@ fun <E> emptyListCell(): ListCell<E> = EMPTY_LIST_CELL
fun <E> mutableListCell(vararg elements: E): MutableListCell<E> = fun <E> mutableListCell(vararg elements: E): MutableListCell<E> =
SimpleListCell(mutableListOf(*elements)) SimpleListCell(mutableListOf(*elements))
/** Returns a mutable list cell initially backed by [elements]. */
fun <E> mutableListCell(elements: MutableList<E>): MutableListCell<E> =
SimpleListCell(elements)
/** /**
* Returns a cell that changes whenever this list cell is structurally changed or when its * Returns a cell that changes whenever this list cell is structurally changed or when its
* individual elements change. * individual elements change.

View File

@ -10,7 +10,7 @@ import world.phantasmal.cell.Cell
/** /**
* Depends on a [ListCell] and zero or more cells per element in the list. * Depends on a [ListCell] and zero or more cells per element in the list.
*/ */
class ListElementsDependentCell<E>( internal class ListElementsDependentCell<E>(
private val list: ListCell<E>, private val list: ListCell<E>,
private val extractCells: (element: E) -> Array<out Cell<*>>, private val extractCells: (element: E) -> Array<out Cell<*>>,
) : AbstractCell<List<E>>(), Dependent { ) : AbstractCell<List<E>>(), Dependent {

View File

@ -4,7 +4,7 @@ import world.phantasmal.core.assertUnreachable
import world.phantasmal.cell.Dependency import world.phantasmal.cell.Dependency
import world.phantasmal.cell.Cell import world.phantasmal.cell.Cell
class SimpleFilteredListCell<E>( internal class SimpleFilteredListCell<E>(
list: ListCell<E>, list: ListCell<E>,
private val predicate: Cell<(E) -> Boolean>, private val predicate: Cell<(E) -> Boolean>,
) : AbstractFilteredListCell<E>(list) { ) : AbstractFilteredListCell<E>(list) {

View File

@ -6,7 +6,7 @@ import world.phantasmal.core.unsafe.unsafeCast
/** /**
* @param elements The backing list for this [ListCell]. * @param elements The backing list for this [ListCell].
*/ */
class SimpleListCell<E>( internal class SimpleListCell<E>(
private var elements: MutableList<E>, private var elements: MutableList<E>,
) : AbstractListCell<E>(), MutableListCell<E> { ) : AbstractListCell<E>(), MutableListCell<E> {

View File

@ -14,7 +14,7 @@ class DelegatingCellTests : RegularCellTests, MutableCellTests<Int> {
override fun createValue(): Int = v + 1 override fun createValue(): Int = v + 1
} }
override fun <T> createWithValue(value: T): DelegatingCell<T> { override fun <T> createWithValue(value: T): Cell<T> {
var v = value var v = value
return DelegatingCell({ v }, { v = it }) return DelegatingCell({ v }, { v = it })
} }

View File

@ -4,7 +4,7 @@ package world.phantasmal.cell
class DependentCellTests : RegularCellTests, CellWithDependenciesTests { class DependentCellTests : RegularCellTests, CellWithDependenciesTests {
override fun createProvider() = Provider() override fun createProvider() = Provider()
override fun <T> createWithValue(value: T): DependentCell<T> { override fun <T> createWithValue(value: T): Cell<T> {
val dependency = SimpleCell(value) val dependency = SimpleCell(value)
return DependentCell(dependency) { dependency.value } return DependentCell(dependency) { dependency.value }
} }
@ -13,7 +13,7 @@ class DependentCellTests : RegularCellTests, CellWithDependenciesTests {
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
DependentCell(dependency1, dependency2, dependency3) { DependentCell(dependency1, dependency2, dependency3) {
dependency1.value + dependency2.value + dependency3.value dependency1.value + dependency2.value + dependency3.value
} }
@ -21,7 +21,7 @@ class DependentCellTests : RegularCellTests, CellWithDependenciesTests {
class Provider : CellTests.Provider { class Provider : CellTests.Provider {
private val dependencyCell = SimpleCell(1) private val dependencyCell = SimpleCell(1)
override val cell = DependentCell(dependencyCell) { 2 * dependencyCell.value } override val cell: Cell<Any> = DependentCell(dependencyCell) { 2 * dependencyCell.value }
override fun emit() { override fun emit() {
dependencyCell.value += 2 dependencyCell.value += 2

View File

@ -9,7 +9,7 @@ class DependentCellWithSimpleListCellTests : CellTests {
class Provider : CellTests.Provider { class Provider : CellTests.Provider {
private val dependencyCell = SimpleListCell(mutableListOf("a", "b", "c")) private val dependencyCell = SimpleListCell(mutableListOf("a", "b", "c"))
override val cell = DependentCell(dependencyCell) { dependencyCell.value } override val cell: Cell<Any> = DependentCell(dependencyCell) { dependencyCell.value }
override fun emit() { override fun emit() {
dependencyCell.add("x") dependencyCell.add("x")

View File

@ -12,7 +12,7 @@ class FlatteningDependentCellDirectAndTransitiveDependencyEmitTests : CellTests
// This cell is both the direct and transitive dependency. // This cell is both the direct and transitive dependency.
private val dependencyCell = SimpleCell('a') private val dependencyCell = SimpleCell('a')
override val cell = FlatteningDependentCell(dependencyCell) { dependencyCell } override val cell: Cell<Any> = FlatteningDependentCell(dependencyCell) { dependencyCell }
override fun emit() { override fun emit() {
dependencyCell.value += 1 dependencyCell.value += 1

View File

@ -22,7 +22,7 @@ class FlatteningDependentCellDirectDependencyEmitsTests : RegularCellTests {
} }
} }
override fun <T> createWithValue(value: T): FlatteningDependentCell<T> { override fun <T> createWithValue(value: T): Cell<T> {
val v = ImmutableCell(ImmutableCell(value)) val v = ImmutableCell(ImmutableCell(value))
return FlatteningDependentCell(v) { v.value } return FlatteningDependentCell(v) { v.value }
} }

View File

@ -10,7 +10,7 @@ class FlatteningDependentCellTransitiveDependencyEmitsTests :
override fun createProvider() = Provider() override fun createProvider() = Provider()
override fun <T> createWithValue(value: T): FlatteningDependentCell<T> { override fun <T> createWithValue(value: T): Cell<T> {
val dependency = ImmutableCell(ImmutableCell(value)) val dependency = ImmutableCell(ImmutableCell(value))
return FlatteningDependentCell(dependency) { dependency.value } return FlatteningDependentCell(dependency) { dependency.value }
} }
@ -19,7 +19,7 @@ class FlatteningDependentCellTransitiveDependencyEmitsTests :
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
FlatteningDependentCell(dependency1, dependency2, dependency3) { FlatteningDependentCell(dependency1, dependency2, dependency3) {
ImmutableCell(dependency1.value + dependency2.value + dependency3.value) ImmutableCell(dependency1.value + dependency2.value + dependency3.value)
} }
@ -31,7 +31,7 @@ class FlatteningDependentCellTransitiveDependencyEmitsTests :
// The direct dependency of the cell under test can't change. // The direct dependency of the cell under test can't change.
private val directDependency = ImmutableCell(transitiveDependency) private val directDependency = ImmutableCell(transitiveDependency)
override val cell = override val cell: Cell<Any> =
FlatteningDependentCell(directDependency) { directDependency.value } FlatteningDependentCell(directDependency) { directDependency.value }
override fun emit() { override fun emit() {

View File

@ -12,5 +12,5 @@ class SimpleCellTests : RegularCellTests, MutableCellTests<Int> {
override fun createValue(): Int = cell.value + 1 override fun createValue(): Int = cell.value + 1
} }
override fun <T> createWithValue(value: T) = SimpleCell(value) override fun <T> createWithValue(value: T): Cell<T> = SimpleCell(value)
} }

View File

@ -13,7 +13,7 @@ class DependentListCellTests : ListCellTests, CellWithDependenciesTests {
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
DependentListCell(dependency1, dependency2, dependency3) { DependentListCell(dependency1, dependency2, dependency3) {
listOf(dependency1.value, dependency2.value, dependency3.value) listOf(dependency1.value, dependency2.value, dependency3.value)
} }
@ -22,7 +22,7 @@ class DependentListCellTests : ListCellTests, CellWithDependenciesTests {
private val dependencyCell = private val dependencyCell =
SimpleListCell(if (empty) mutableListOf() else mutableListOf(5)) SimpleListCell(if (empty) mutableListOf() else mutableListOf(5))
override val cell = override val cell: ListCell<Any> =
DependentListCell(dependencyCell) { dependencyCell.value.map { 2 * it } } DependentListCell(dependencyCell) { dependencyCell.value.map { 2 * it } }
override fun addElement() { override fun addElement() {

View File

@ -31,7 +31,7 @@ class FilteredListCellListDependencyEmitsTests : ListCellTests, CellWithDependen
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
FilteredListCell( FilteredListCell(
list = dependency1.mapToList { listOf(it) }, list = dependency1.mapToList { listOf(it) },
predicate = dependency2.map { value2 -> predicate = dependency2.map { value2 ->

View File

@ -9,6 +9,7 @@ import world.phantasmal.cell.*
class FilteredListCellPredicateDependencyEmitsTests : ListCellTests, CellWithDependenciesTests { class FilteredListCellPredicateDependencyEmitsTests : ListCellTests, CellWithDependenciesTests {
override fun createListProvider(empty: Boolean) = object : ListCellTests.Provider { override fun createListProvider(empty: Boolean) = object : ListCellTests.Provider {
private var maxValue = if (empty) 0 else 1 private var maxValue = if (empty) 0 else 1
// The predicate cell changes, the predicate results don't. // The predicate cell changes, the predicate results don't.
private val predicateCell = SimpleCell<(Int) -> Cell<Boolean>> { cell(it <= maxValue) } private val predicateCell = SimpleCell<(Int) -> Cell<Boolean>> { cell(it <= maxValue) }
@ -30,7 +31,7 @@ class FilteredListCellPredicateDependencyEmitsTests : ListCellTests, CellWithDep
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
FilteredListCell( FilteredListCell(
list = listCell(1, 2, 3, 4, 5, 6, 7, 8, 9), list = listCell(1, 2, 3, 4, 5, 6, 7, 8, 9),
predicate = map(dependency1, dependency2, dependency3) { value1, value2, value3 -> predicate = map(dependency1, dependency2, dependency3) { value1, value2, value3 ->

View File

@ -31,7 +31,7 @@ class FilteredListCellPredicateResultDependenciesEmitTests : ListCellTests,
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
): FilteredListCell<Int> { ): Cell<Any> {
val deps = listOf(dependency1, dependency2, dependency3) val deps = listOf(dependency1, dependency2, dependency3)
return FilteredListCell( return FilteredListCell(

View File

@ -12,6 +12,9 @@ import world.phantasmal.cell.map
*/ */
@Suppress("unused") @Suppress("unused")
class FilteredListCellTests : AbstractFilteredListCellTests { class FilteredListCellTests : AbstractFilteredListCellTests {
override fun <E> createFilteredListCell(list: ListCell<E>, predicate: Cell<(E) -> Boolean>) = override fun <E> createFilteredListCell(
list: ListCell<E>,
predicate: Cell<(E) -> Boolean>,
): ListCell<E> =
FilteredListCell(list, predicate.map { p -> { cell(p(it)) } }) FilteredListCell(list, predicate.map { p -> { cell(p(it)) } })
} }

View File

@ -21,7 +21,7 @@ class FlatteningDependentListCellTransitiveDependencyEmitsTests :
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
FlatteningDependentListCell(dependency1, dependency2, dependency3) { FlatteningDependentListCell(dependency1, dependency2, dependency3) {
ImmutableListCell(listOf(dependency1.value, dependency2.value, dependency3.value)) ImmutableListCell(listOf(dependency1.value, dependency2.value, dependency3.value))
} }
@ -34,7 +34,7 @@ class FlatteningDependentListCellTransitiveDependencyEmitsTests :
// The direct dependency of the list under test can't change. // The direct dependency of the list under test can't change.
private val directDependency = ImmutableCell<ListCell<Int>>(transitiveDependency) private val directDependency = ImmutableCell<ListCell<Int>>(transitiveDependency)
override val cell = override val cell: ListCell<Any> =
FlatteningDependentListCell(directDependency) { directDependency.value } FlatteningDependentListCell(directDependency) { directDependency.value }
override fun addElement() { override fun addElement() {

View File

@ -1,11 +1,6 @@
package world.phantasmal.cell.list package world.phantasmal.cell.list
import world.phantasmal.cell.Cell import world.phantasmal.cell.*
import world.phantasmal.cell.CellTests
import world.phantasmal.cell.CellWithDependenciesTests
import world.phantasmal.cell.DependentCell
import world.phantasmal.cell.MutableCell
import world.phantasmal.cell.SimpleCell
/** /**
* In these tests, the direct list cell dependency of the [ListElementsDependentCell] doesn't * In these tests, the direct list cell dependency of the [ListElementsDependentCell] doesn't
@ -33,7 +28,7 @@ class ListElementsDependentCellElementEmitsTests : CellWithDependenciesTests {
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
ListElementsDependentCell( ListElementsDependentCell(
ImmutableListCell(listOf(dependency1, dependency2, dependency3)) ImmutableListCell(listOf(dependency1, dependency2, dependency3))
) { arrayOf(it) } ) { arrayOf(it) }

View File

@ -30,7 +30,7 @@ class SimpleFilteredListCellListDependencyEmitsTests :
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
SimpleFilteredListCell( SimpleFilteredListCell(
list = mapToList(dependency1, dependency2, dependency3) { value1, value2, value3 -> list = mapToList(dependency1, dependency2, dependency3) { value1, value2, value3 ->
listOf(value1, value2, value3) listOf(value1, value2, value3)

View File

@ -33,7 +33,7 @@ class SimpleFilteredListCellPredicateDependencyEmitsTests :
dependency1: Cell<Int>, dependency1: Cell<Int>,
dependency2: Cell<Int>, dependency2: Cell<Int>,
dependency3: Cell<Int>, dependency3: Cell<Int>,
) = ): Cell<Any> =
SimpleFilteredListCell( SimpleFilteredListCell(
list = listCell(1, 2, 3, 4, 5, 6, 7, 8, 9), list = listCell(1, 2, 3, 4, 5, 6, 7, 8, 9),
predicate = map(dependency1, dependency2, dependency3) { value1, value2, value3 -> predicate = map(dependency1, dependency2, dependency3) { value1, value2, value3 ->

View File

@ -10,6 +10,9 @@ import world.phantasmal.cell.Cell
*/ */
@Suppress("unused") @Suppress("unused")
class SimpleFilteredListCellTests : AbstractFilteredListCellTests { class SimpleFilteredListCellTests : AbstractFilteredListCellTests {
override fun <E> createFilteredListCell(list: ListCell<E>, predicate: Cell<(E) -> Boolean>) = override fun <E> createFilteredListCell(
list: ListCell<E>,
predicate: Cell<(E) -> Boolean>,
): ListCell<E> =
SimpleFilteredListCell(list, predicate) SimpleFilteredListCell(list, predicate)
} }

View File

@ -2,7 +2,7 @@ package world.phantasmal.web.questEditor.models
import world.phantasmal.cell.Cell import world.phantasmal.cell.Cell
import world.phantasmal.cell.list.ListCell import world.phantasmal.cell.list.ListCell
import world.phantasmal.cell.list.SimpleListCell import world.phantasmal.cell.list.mutableListCell
import world.phantasmal.cell.map import world.phantasmal.cell.map
import world.phantasmal.cell.mutableCell import world.phantasmal.cell.mutableCell
@ -19,7 +19,7 @@ class QuestEventModel(
private val _sectionId = mutableCell(sectionId) private val _sectionId = mutableCell(sectionId)
private val _waveId = mutableCell(waveId) private val _waveId = mutableCell(waveId)
private val _delay = mutableCell(delay) private val _delay = mutableCell(delay)
private val _actions = SimpleListCell(actions) private val _actions = mutableListCell(actions)
val id: Cell<Int> = _id val id: Cell<Int> = _id
val sectionId: Cell<Int> = _sectionId val sectionId: Cell<Int> = _sectionId

View File

@ -1,15 +1,15 @@
package world.phantasmal.web.questEditor.models package world.phantasmal.web.questEditor.models
import world.phantasmal.cell.Cell
import world.phantasmal.cell.list.ListCell
import world.phantasmal.cell.list.flatMapToList
import world.phantasmal.cell.list.listCell
import world.phantasmal.cell.list.mutableListCell
import world.phantasmal.cell.map
import world.phantasmal.cell.mutableCell
import world.phantasmal.psolib.Episode import world.phantasmal.psolib.Episode
import world.phantasmal.psolib.asm.BytecodeIr import world.phantasmal.psolib.asm.BytecodeIr
import world.phantasmal.psolib.fileFormats.quest.DatUnknown import world.phantasmal.psolib.fileFormats.quest.DatUnknown
import world.phantasmal.cell.Cell
import world.phantasmal.cell.list.ListCell
import world.phantasmal.cell.list.SimpleListCell
import world.phantasmal.cell.list.flatMapToList
import world.phantasmal.cell.list.listCell
import world.phantasmal.cell.map
import world.phantasmal.cell.mutableCell
class QuestModel( class QuestModel(
id: Int, id: Int,
@ -36,9 +36,9 @@ class QuestModel(
private val _shortDescription = mutableCell("") private val _shortDescription = mutableCell("")
private val _longDescription = mutableCell("") private val _longDescription = mutableCell("")
private val _mapDesignations = mutableCell(mapDesignations) private val _mapDesignations = mutableCell(mapDesignations)
private val _npcs = SimpleListCell(npcs) private val _npcs = mutableListCell(npcs)
private val _objects = SimpleListCell(objects) private val _objects = mutableListCell(objects)
private val _events = SimpleListCell(events) private val _events = mutableListCell(events)
val id: Cell<Int> = _id val id: Cell<Int> = _id
val language: Cell<Int> = _language val language: Cell<Int> = _language

View File

@ -3,7 +3,8 @@ package world.phantasmal.webui
import kotlinx.coroutines.* import kotlinx.coroutines.*
import mu.KotlinLogging import mu.KotlinLogging
import world.phantasmal.cell.Cell import world.phantasmal.cell.Cell
import world.phantasmal.cell.SimpleCell import world.phantasmal.cell.MutableCell
import world.phantasmal.cell.mutableCell
import kotlin.time.measureTime import kotlin.time.measureTime
private val logger = KotlinLogging.logger {} private val logger = KotlinLogging.logger {}
@ -26,14 +27,14 @@ class LoadingStatusCellImpl private constructor(
private val dataName: String, private val dataName: String,
/** Will be called with [Dispatchers.Main] context. */ /** Will be called with [Dispatchers.Main] context. */
private val loadData: suspend () -> Unit, private val loadData: suspend () -> Unit,
private val cellDelegate: SimpleCell<LoadingStatus>, private val cellDelegate: MutableCell<LoadingStatus>,
) : LoadingStatusCell, Cell<LoadingStatus> by cellDelegate { ) : LoadingStatusCell, Cell<LoadingStatus> by cellDelegate {
constructor( constructor(
scope: CoroutineScope, scope: CoroutineScope,
dataName: String, dataName: String,
loadData: suspend () -> Unit, loadData: suspend () -> Unit,
) : this(scope, dataName, loadData, SimpleCell(LoadingStatus.Uninitialized)) ) : this(scope, dataName, loadData, mutableCell(LoadingStatus.Uninitialized))
private var currentJob: Job? = null private var currentJob: Job? = null