jonahwilliams / signal_concept

A concept implementation of Signals for Dart.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

signal

A proof of concept for a Signal (value + changes over time) implementation in Dart.

Usage

A SignalRef allows you to change the value of a Signal. A SignalRef can be cooerced into a Signal (SignalRef extends Signal). This distinction is useful because it allows the developer to control what parts of the code can read/write a signal value and which parts can only read it.

var ref = new SignalRef<int>(2);
ref.value = 3;

Signal<int> signal = ref;

New signals can be dervied from existing ones using computeN functions. Any time the value of one of the signal changes the function will be reevaulated.

var refOne = new SignalRef(3);
var refTwo = new SignalRef('Hello');
var sentence = computeTwo(refOne, refTwo, (a, b) => a * b);

print(sentence.value);
// => 'HelloHelloHello';

Also, here is a neat trick for computations. Updates to computed values are defered to the end of the current microtask queue, allowing us to ensure a maximum of a single update per computed value.

var refOne = new SignalRef(2);
var refTwo = new SignalRef(3);
var refThree = new SignalRef(4);
var refFour = new SignalRef(5);
var changeCount = 0;

var computed = computeFour(
  refOne,
  refTwo,
  refThree,
  refFour,
  (a, b, c, d) => a + b + c + d,
);

computed.onChange((_) {
  changeCount++;
});

// microtasks are elapsed...

print(changeCount);
// => 1

refOne.value = 3;
refTwo.value = -1;
refThree.value = 9;
refFour.value = 10;

// microtasks are elapsed...

print(computed.value);
// => 21

print(changeCount);
// => 2

A Signal without an initial value or a value of null is marked as "cold", and will not trigger updates in computations. As a result, null cannot be used as a regular value inside of signals.

var refOne = new SignalRef();
var refTwo = new SignalRef(2);

var timesResult = computeTwo(refOne, refTwo, (a, b) => a * b);
print(timesResult.value);
// => null

refOne.value = 3;
print(timesResult.value);
// => 6

If a signal value is set to something which is equal to the previous value, then the signal does not trigger updates.

var calledCount = 0;
var refOne = new SignalRef(2);

refOne.onChange((_) {
  calledCount++;
});

refOne.value = 2;
refOne.value = 2;

print(calledCount);
// => 0;

About

A concept implementation of Signals for Dart.

License:BSD 3-Clause "New" or "Revised" License


Languages

Language:Dart 100.0%