Releases: Miha-x64/Lychee
0.0.7
Properties core
Removed
concurrentMutableDiffPropertyOf(value: T): MutableDiffProperty<T, D>
object Identity
object Equals
PropertyIo: chars, ints, longs, floats, doubles, stringList, enum, enumSet
Property<Collection>: isEmpty, isNotEmpty
Property.equalTo
Property<CharSequence>: length, isEmpty, isNotEmpty, isBlank, isNotBlank, trimmed
mutablePropertyOf, concurrentMutablePropertyOf, unsynchronizedMutablePropertyOf
Changed
CharSequencez.ValueOf: (Any?) -> String to (Any) -> String
Added
CharSequencez.ValueOfOrNull
CharSequencez.ValueOfOrBlank
Behaviour changes
- fixed subscription of multi-arity listeners
- fixed unsubscription of concurrent diff listeners
- fixed sequential correctness of bi- and multi-mapped properties
- fixed concurrent correctness of bi-mapped ones
Persistence
Removed useless parameters from enumSet
DataType
factories
JavaFx bindings
removed FxProperty.bind
and bindBidirectionally
Android bindings
Removed PrefAdapters and according SharedPreferenceProperty
constructor
Deprecated
fun View.bindToAttachedToWidow(attachedToWindowProperty: MutableProperty<Boolean>)
Behabiour changes
bindViewTo
and all View bindings now observeActivity
's started state (via awful workaound ;)- fixed
SharedPreferencesStruct constructor(Struct, SharedPreferences)
0.0.6
Properties core
- if notification happens right now, postponing actual
ChangeListener
subscription until comes a value which was never seen yet - fixed a bug around multi-arity subscribers for
DiffProperty
- renamed
concurrentMutableDiffPropertyOf
toconcurrentDiffPropertyOf
and deprecated the latter - executing thread-confined
ChangeListener
s in-place when possible (i. e. when changed from target thread and no pending notifications) - made methods searching for platform executors easily removable by ProGuard
- added
Objectz
,Arrayz
,CharSequencez
,Enumz
,Collectionz
utilities - new APIs
interface TransactionalProperty<TRANSACTION, T> : Property<T>
fun immutablePropertyOf(value: Unit): Property<Unit>
fun Property<subtype of Number>.any arithmetic operator(Property<same Number>): Property<same Number>
fun <T, U> Property<T>.zipWith(that: Property<U>): Property<Pair<T, U>>
fun <T, U> Property<T>.flatMap(transform: (T) -> Property<U>): Property<U>
fun <T> updatedEvery(period: Long, unit: TimeUnit = TimeUnit.MILLISECONDS, compute: () -> T): Property<T>
- added utilities:
fun <T> identity(): (T) -> T
fun isEqualTo(that: Any?): (Any?) -> Boolean
fun notEqualTo(that: Any?): (Any?) -> Boolean
fun isSameAs(that: Any?): (Any?) -> Boolean
fun notSameAs(that: Any?): (Any?) -> Boolean
- added extensions for properties of collections
operator fun <K, V> MutableProperty<Map<K, V>>.plusAssign(newMapping: Pair<K, V>)
operator fun <K, V> MutableProperty<Map<K, V>>.minusAssign(victimKey: K)
operator fun <T> MutableProperty<List<T>>.plusAssign(newElement: T)
operator fun <T> MutableProperty<Set<T>>.plusAssign(newElement: T)
operator fun <T> MutableProperty<Set<T>>.minusAssign(victim: T)
inline fun <T> Collection<Property<T>>.valueList(): Property<List<T>>
- added extensions for properties
fun <T> Property<T>.observeChangesIf(subscribe: Boolean, onChange: ChangeListener<T>)
fun <T : Any, U> Property<T?>.flatMapNotNullOrDefault(default: U, transform: (T) -> Property<U>): Property<U>
fun <T> MutableProperty<T>.unbind()
fun <T : Any> MutableProperty<T?>.clearEachAnd(crossinline action: (T) -> Unit)
- deprecated
inline fun <T> Property<T>.equalTo(that: Property<T>): Property<Boolean> // in favour of Objectz.Equal
val Property<CharSequence>.***: Property<Int> // in favour of CharSequencez.***
Added Persistence module
Its API will be slightly changed in the future.
// Streams
interface BetterDataOutput<T>
interface BetterDataInput<T>
fun <D, SCH : Schema<SCH>> BetterDataOutput<D>.write(output: D, struct: Struct<SCH>)
fun <D, T> DataType<T>.write(out: BetterDataOutput<D>, put: D, value: T)
fun <D, SCH : Schema<SCH>> BetterDataInput<D>.read(input: D, schema: SCH): StructSnapshot<SCH>
fun <D, T> DataType<T>.read(inp: BetterDataInput<D>, ut: D): T
// Structs
abstract class Schema<SELF : Schema<SELF>>
sealed class FieldDef<SCH : Schema<SCH>, T>
interface Struct<SCH : Schema<SCH>>
interface TransactionalStruct<SCH : Schema<SCH>> : Struct<SCH>
/* and some stuff around transactions */
abstract class BaseStruct<SCH : Schema<SCH>>(
final override val schema: SCH
) : Struct<SCH>
class StructSnapshot<SCH : Schema<SCH>> : BaseStruct<SCH>
fun <SCH : Schema<SCH>> SCH.build(build: SCH.(StructBuilder<SCH>) -> Unit): StructSnapshot<SCH>
inline class FieldSet<SCH : Schema<SCH>, FLD : FieldDef<SCH, *>> /* and some methods for manipulating these sets */
// Types
sealed class DataType<T> {
class Nullable<T : Any>(val actualType: DataType<T>) : DataType<T?>()
abstract class Simple<T>(val kind: Kind) : DataType<T>() /* primitives, strings, byte arrays */
abstract class Collect<C, E>(val elementType: DataType<E>) : DataType<C>()
}
val string: DataType.Simple<String>
val byteArray: DataType.Simple<ByteArray>
val bool: DataType.Simple<Boolean>
val byte: DataType.Simple<Byte>
val short: DataType.Simple<Short>
val int: DataType.Simple<Int>
val long: DataType.Simple<Long>
val float: DataType.Simple<Float>
val double: DataType.Simple<Double>
val byteString: DataType<ByteString> = byteString(byteArray)
fun byteString(blobType: DataType.Simple<ByteArray>): DataType<ByteString>
inline fun <T : Any> nullable(type: DataType<T>): DataType.Nullable<T>
fun <T> serialized(type: DataType<T>): DataType.Simple<T>
fun enum(/* several overloads */): DataType.Simple<E>
fun enumSet(/* several overloads */): DataType<Set<E>>
fun <E> collection(elementType: DataType<E>): DataType.Collect<Collection<E>, E>
fun <E> set(elementType: DataType<E>): DataType.Collect<Set<E>, E>
Properties && Persistence
Added
interface PropertyStruct<SCH : Schema<SCH>> : Struct<SCH>
interface TransactionalPropertyStruct<SCH : Schema<SCH>> : PropertyStruct<SCH>, TransactionalStruct<SCH>
class ObservableStruct<SCH : Schema<SCH>> : BaseStruct<SCH>, PropertyStruct<SCH>
interface PropertyIo members {
operator fun <T> DataType<T>.invoke(prop: MutableProperty<T>)
}
Deprecated
interface PropertyIo members {
fun chars(prop: MutableProperty<CharArray>)
fun ints(prop: MutableProperty<IntArray>)
fun longs(prop: MutableProperty<LongArray>)
fun floats(prop: MutableProperty<FloatArray>)
fun doubles(prop: MutableProperty<DoubleArray>)
fun stringList(prop: MutableProperty<List<String>>)
fun <E : Enum<E>> enum(prop: MutableProperty<E>, type: Class<E>)
fun <E : Enum<E>> enumSet(prop: MutableProperty<Set<E>>, type: Class<E>)
/* and according PropertyIo.x(prop) extensions */
}
Renamed
class PropertyInput -> PropertyReader
class PropertyOutput -> PropertyWriter
Android bindings
Added:
// View binding
fun <V : View, T> V.bindViewTo(source: Property<T>, destination: android.util.Property<V, T>)
fun View.bindBackgroundTo(backgroundProperty: Property<Drawable?>)
fun View.bindBackgroundTo(backgroundProperty: Property<Int>)
fun View.bindBackgroundColorTo(backgroundColorProperty: Property<Int>)
fun TextView.bindToText(textProperty: MutableProperty<in String>)
fun CardView.bindCardBackgroundColorTo(backgroundColorProperty: Property<Int>)
fun CardView.bindCardBackgroundColorResTo(backgroundColorResProperty: Property<Int>)
interface Holder<T>
fun <T> Holder<T>.setItemWhenClicked(target: MutableProperty<in T>): View.OnClickListener
fun RecyclerView.ViewHolder.setPositionWhenClicked(target: MutableProperty<in Int>): View.OnClickListener
fun <T> Holder<T>.setItemWhenLongClicked(target: MutableProperty<in T>): View.OnLongClickListener
fun RecyclerView.ViewHolder.setPositionWhenLongClicked(target: MutableProperty<in Int>): View.OnLongClickListener
abstract class ObservingAdapter<VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH>()
// Persistence
fun <SCH : Schema<SCH>> JsonReader.readListOf(schema: SCH): List<StructSnapshot<SCH>>
fun <SCH : Schema<SCH>> JsonReader.read(schema: SCH): StructSnapshot<SCH>
fun <SCH : Schema<SCH>> JsonWriter.write(list: List<Struct<SCH>>, fields: FieldSet<SCH, FieldDef<SCH, *>>)
fun <SCH : Schema<SCH>> JsonWriter.write(struct: Struct<SCH>, fields: FieldSet<SCH, FieldDef<SCH, *>>)
object ParcelIo : BetterDataInput<Parcel>, BetterDataOutput<Parcel>
class SharedPreferenceStruct<SCH : Schema<SCH>> : BaseStruct<SCH>, TransactionalPropertyStruct<SCH>
Deprecated:
// View binding
View.bindToAttachedToWidow(attachedToWindowProperty: MutableProperty<Boolean>)
// Persistence
interface PrefAdapter<T> /* and all its implementations */
class SharedPreferenceProperty members {
fun bindTo(sample: Property<T>)
fun casValue(expect: T, update: T): Boolean
}
JavaFX bindings
Added
fun <T> Property<List<T>>.fxList(): ObservableList<T>
fun <T> MutableProperty<T>.bindTo(that: ObservableValue<T>)
fun ButtonBase.setWhenClicked(clickedProperty: MutableProperty<Boolean>)
0.0.5
Core
— performance optimizations 8b288e4, 1f91f69, 25a4513
— bound (bidirectionally mapped) properties 0daf01b, c47ec70, b9286a0
— fixed casValue
behaviour, 315dbdc
— added MutableProperty.plusAssign extension 4df7a0a (a bunch of extensions may be added and moved to another artifact in the future)
— potential fix for theoretical concurrent bug #40
Android bindings
Nothing changed, just recompiled against new core.
0.0.4
Properties:
— moved platform executors and their factories into according *-bindings
packages;
— fixed single-threaded debounced properties' notification thread;
— added Property<T>.equalTo(Property<T>): Property<Boolean>
extension;
— FJ pools with parallelism != 1
is now unsupported for subscription because thread is unpredictable.
Android bindings:
— not clearing out text selection on bound (EditTexts);
— fixed POM dependencies section;
— added CompoundButton.checked
bindings.
0.0.3
— Cancel async notification when ConfinedChangeListener
gets removed #30 ;
— made ConfinedChangeListener
internal
;
— Property<T>.debounced()
parameter unit
defaults to millis;
— Added Handlecutor
class — it's an android.os.Handler
implementing j.u.c.Executor
— major behaviour change: addChangeListener
now subscribes on current thread #27; use addUnconfinedChangeListener
if you need old behaviour;
— fixed a potential deadlock in #36, no we're lock-free again;
— fixed potential bugs when property value is assigned to itself 😳;
— made internal declarations inaccessbile from Java, #34;
— now attached views can be bound safely, too, #26;
— Android bindings: moved some classes to more specific packages;
— moved HandlerAsExecutor
to Android bindings and renamed it to HandlerExecutor
(core uses Handlecutor
now);
— Android bindings: added IdleExecutor
.
0.0.2
Both
- methods count reduction, aggressive class merging, synthetic and bridge methods removal, breaks binary compatibility wherever possible because of many
inline
functions which expose many changed classes
Reactive Properties
- safer notification code (#18): if a property gets (un)subscribed during notification, changes are applied instantly; if a new value is being set during notification, the next notification gets deferred
- added
mapOn
(#19) which calculates mapped property value on a specified worker - renamed
MutableProperty.cas
tocasValue
, breaks both source and binary compatibility - removed
Short
,Char
,ShortArray
,Array<String>
support frompersistence
because these types are rare, breaks both source and binary compatibility (Mutable)Property.value
is a property again, removedgetValue
/setValue
accessors andvalue
extension-property, breaks source compatibility- fixed
Property.onEach
extension, #21 DiffProperty
support (#15): diff-property is a property which also provides a difference betweenold
andnew
valuesForkJoinPool
support — debounce and background mapping of single-threaded property will deliver result to the pool where it was called (Android's Handler and JavaFX Platform are supported from the very beginning, too)- fixed
MutableProperty.bindTo
behaviour under contention - all dependent properties (mapped, debounced, distinct, bound, etc) now observe original property only when they are being observed (#23), this prevents memory leaks
- all inline extensions are now in
PropertiesInline
class (which shouldn't ever be loaded by VM), all not inline — inProperties
, breaks binary compatibility - fixed
MutableProperty<Boolean>.clearEachAnd
— now it callsaction
when just bound to a property withtrue
value - deprecated
unsynchronizedMutablePropertyOf
andconcurrentMutablePropertyOf
, usepropertyOf
andconcurrentPropertyOf
instead
Android Bindings
View.bindTo
now throws an exception when called on attachedView
on API 17+ (noisAttachedToWindow
for API <17, we can't perform this check safely, for production; just bind views which are not attached yet, forFragment
s this meansonCreateView
, notonViewCreated
), breaks incorrect codeView.bindTo
now passes also a view tobind
function, breaks both source and binary compatibilitySharedPreferenceProperty
: addedStringSetPrefAdapter
,IntPrefAdapter
,LongPrefAdapter
,FloatPrefAdapter
,DoublePrefAdapter
,BoolPrefAdapter
- removed
mutablePropertyOf
extension-functions forView
,Activity
,Fragment
since we havepropertyOf
TextView
: compound drawables support
Snapshot 1
A sample with reactive properties.