Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Granular Observability. #68

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .haxerc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "4.2.0",
"version": "4.2.3",
"resolveLibs": "scoped"
}
8 changes: 3 additions & 5 deletions haxe_libraries/tink_streams.hxml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# @install: lix --silent download "gh://github.com/haxetink/tink_streams#5066a96c4a8b483479b6a8df8893eaf8922d3bea" into tink_streams/0.4.0/github/5066a96c4a8b483479b6a8df8893eaf8922d3bea
# @install: lix --silent download "gh://github.com/haxetink/tink_streams#f4478825ef0a30df1187f02a354ec61176b47b8b" into tink_streams/0.3.3/github/f4478825ef0a30df1187f02a354ec61176b47b8b
-lib tink_core
-cp ${HAXE_LIBCACHE}/tink_streams/0.4.0/github/5066a96c4a8b483479b6a8df8893eaf8922d3bea/src
-D tink_streams=0.4.0
# temp for development, delete this file when pure branch merged
-D pure
-cp ${HAXE_LIBCACHE}/tink_streams/0.3.3/github/f4478825ef0a30df1187f02a354ec61176b47b8b/src
-D tink_streams=0.3.3
7 changes: 3 additions & 4 deletions haxe_libraries/tink_testrunner.hxml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# @install: lix --silent download "gh://github.com/haxetink/tink_testrunner#45f704215ae28c3d864755036dc2ee63f7c44e8a" into tink_testrunner/0.9.0/github/45f704215ae28c3d864755036dc2ee63f7c44e8a
# @install: lix --silent download "gh://github.com/haxetink/tink_testrunner#866de8b991be89b969825b0c0f5565d51f96a6f7" into tink_testrunner/0.8.0/github/866de8b991be89b969825b0c0f5565d51f96a6f7
-lib ansi
-lib tink_macro
-lib tink_streams
-cp ${HAXE_LIBCACHE}/tink_testrunner/0.9.0/github/45f704215ae28c3d864755036dc2ee63f7c44e8a/src
-D tink_testrunner=0.9.0
--macro addGlobalMetadata('ANSI.Attribute', "@:native('ANSIAttribute')", false)
-cp ${HAXE_LIBCACHE}/tink_testrunner/0.8.0/github/866de8b991be89b969825b0c0f5565d51f96a6f7/src
-D tink_testrunner=0.8.0
3 changes: 3 additions & 0 deletions src/tink/state/Observable.hx
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,9 @@ private class ConstObservable<T> implements ObservableObject<T> {
#end
}

function retain() {}
function release() {}

public function getValue()
return value;

Expand Down
94 changes: 82 additions & 12 deletions src/tink/state/ObservableArray.hx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ abstract ObservableArray<T>(ArrayImpl<T>) from ArrayImpl<T> to Observable<ArrayV
});

public function entry(index)
return Observable.auto(() -> this.get(index));
return Observable.auto(() -> get(index));

@:deprecated('use iterator instead')
public function values()
Expand All @@ -33,7 +33,7 @@ abstract ObservableArray<T>(ArrayImpl<T>) from ArrayImpl<T> to Observable<ArrayV
return 0...this.length;

@:op([]) public inline function get(index)
return this.get(index);
return view[index];

@:op([]) public inline function set(index, value)
return this.set(index, value);
Expand Down Expand Up @@ -77,8 +77,21 @@ abstract ObservableArrayView<T>(ArrayView<T>) from ArrayView<T> {
public function keys()
return 0...this.length;

@:op([]) public inline function get(index)
return this.get(index);
@:op([]) public function get(index) {
return
if (AutoObservable.needsTracking(this)) {
var wrappers = AutoObservable.currentAnnex().get(Wrappers).forSource(this);

wrappers.get(index, () -> new TransformObservable(
this,
_ -> this.get(index),
null,
() -> wrappers.remove(index)
#if tink_state.debug , () -> 'Entry $index of ${this.toString()}' #end
)).value;
}
else this.get(index);
}

public function toArray():Array<T>
return this.copy();
Expand Down Expand Up @@ -139,12 +152,21 @@ private class ArrayImpl<T> extends Invalidator implements ArrayView<T> {

public var length(get, never):Int;
function get_length()
return calc(() -> entries.length);
return observableLength.value;

public function new(entries) {
super(#if tink_state.debug id -> 'ObservableArray#$id${this.entries.toString()}' #end);
super(#if tink_state.debug id -> 'ObservableArray#$id[${this.entries.toString()}]' #end);
this.entries = entries;
this.observableLength = new TransformObservable(this, _ -> this.entries.length, null #if tink_state.debug , () -> 'length of ${toString()}' #end);
this.observableLength = new TransformObservable(
this,
_ -> {
valid = true;
this.entries.length;
},
null,
null
#if tink_state.debug , () -> 'length of ${this.toString()}' #end
);
}

public function replace(values:Array<T>)
Expand Down Expand Up @@ -192,8 +214,10 @@ private class ArrayImpl<T> extends Invalidator implements ArrayView<T> {
public function shift()
return update(() -> entries.shift());

public function get(index:Int)
return calc(() -> entries[index]);
public function get(index:Int) {
valid = true;
return entries[index];
}

public function set(index:Int, value:T)
return update(() -> entries[index] = value);
Expand Down Expand Up @@ -238,11 +262,46 @@ private class ArrayImpl<T> extends Invalidator implements ArrayView<T> {
}
}

private class Wrappers {
final bySource = new Map<{}, SourceWrappers<Dynamic>>();

public function new(target:{}) {}

public function forSource<T>(source:ArrayView<T>):SourceWrappers<T>
return cast switch bySource[source] {
case null: bySource[source] = new SourceWrappers<T>(() -> bySource.remove(source));
case v: v;
}
}

private class SourceWrappers<T> {
final dispose:()->Void;
var count = 0;
final observables = new Map<Int, Observable<T>>();

public function new(dispose)
this.dispose = dispose;

public function get(index, create:() -> Observable<T>):Observable<T>
return switch observables[index] {
case null:
count++;
observables[index] = create();
case v: v;
}

public function remove(index:Int) {
if (observables.remove(index) && (--count == 0)) dispose();
}
}

private class DerivedView<T> implements ArrayView<T> {

final observableLength:Observable<Int>;

public var length(get, never):Int;
function get_length()
return o.value.length;
return observableLength.value;

final o:Observable<Array<T>>;

Expand All @@ -252,11 +311,19 @@ private class DerivedView<T> implements ArrayView<T> {
public function canFire()
return self().canFire();

public function new(o)
public function new(o) {
this.o = o;
this.observableLength = new TransformObservable(
o,
a -> a.length,
null,
null
#if tink_state.debug , () -> 'length of ${toString()}' #end
);
}

public function get(index:Int)
return o.value[index];
return self().getValue()[index];

inline function self()
return (o:ObservableObject<Array<T>>);
Expand Down Expand Up @@ -297,4 +364,7 @@ private class DerivedView<T> implements ArrayView<T> {
public function keyValueIterator()
return o.value.keyValueIterator();

function retain() {}
function release() {}

}
3 changes: 3 additions & 0 deletions src/tink/state/ObservableDate.hx
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,7 @@ class ObservableDate implements ObservableObject<Bool> {

public function getComparator()
return null;

function retain() {}
function release() {}
}
Loading