Skip to content
Snippets Groups Projects
Commit 93796e56 authored by David Sehnal's avatar David Sehnal
Browse files

ValueCell updates

parent 63d1a342
No related branches found
No related tags found
No related merge requests found
...@@ -4,31 +4,56 @@ ...@@ -4,31 +4,56 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
/** A mutable value cell. */ /** A mutable value reference. */
interface ValueCell<T> { value: T } interface ValueRef<T> { value: T }
/** Create a mutable value cell. */
function ValueCell<T>(value: T): ValueCell<T> { return { value }; } namespace ValueRef {
export function create<T>(value: T): ValueRef<T> { return { value }; }
export function update<T>(cell: ValueRef<T>, value: T) { cell.value = value; return cell; }
}
let _valueBoxId = 0; let _valueBoxId = 0;
function getNextId() { function getNextId() {
return _valueBoxId++ % 0x7FFFFFFF; return _valueBoxId++ % 0x7FFFFFFF;
} }
/** An immutable value box that also holds a version of the attribute. */ /**
interface ValueBox<T> { * An immutable value box that also holds a version of the attribute.
* Optionally includes automatically propadated "metadata".
*/
type ValueBox<T, D = never> = {
// Unique identifier in the range 0 to 0x7FFFFFFF // Unique identifier in the range 0 to 0x7FFFFFFF
readonly id: number, readonly id: number,
readonly version: number, readonly version: number,
readonly value: T readonly metadata: D,
readonly value: T,
}
namespace ValueBox {
export function create<T, D = never>(value: T, metadata?: D): ValueBox<T, D> {
return { id: getNextId(), version: 0, value, metadata: metadata! };
}
/** If diffInfo is not specified, copy the old value */
export function withValue<T, D>(box: ValueBox<T, D>, value: T): ValueBox<T, D> {
return { id: box.id, version: box.version + 1, value, metadata: box.metadata };
}
}
/** An immutable box stored inside a mutable cell. */
type ValueCell<T, D = never> = ValueRef<ValueBox<T, D>>
namespace ValueCell {
export function create<T, D = never>(value: T, metadata?: D): ValueCell<T, D> {
return ValueRef.create(ValueBox.create(value, metadata));
}
/** If diffInfo is not specified, copy the old value */
export function update<T, D>(cell: ValueCell<T, D>, value: T): ValueCell<T, D> {
ValueRef.update(cell, ValueBox.withValue(cell.value, value));
return cell;
} }
/** Create a new box with the specified value and version = 0 */
function ValueBox<T>(value: T): ValueBox<T>
/** Create a new box by updating the value of an old box and incrementing the version number. */
function ValueBox<T>(box: ValueBox<T>, value: T): ValueBox<T>
function ValueBox<T>(boxOrValue: T | ValueBox<T>, value?: T): ValueBox<T> {
if (arguments.length === 2) return { id: (boxOrValue as ValueBox<T>).id, version: (boxOrValue as ValueBox<T>).version + 1, value: value! };
return { id: getNextId(), version: 0, value: boxOrValue as T };
} }
export { ValueCell, ValueBox }; export { ValueRef, ValueBox, ValueCell };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment