aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-05-11 17:24:51 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:23:21 +0000
commit4ca20944892bebc0ddac7aa23ed8abef5d537209 (patch)
treefe1f4de29ec578ddc7c226739287796fc9b70353
parentmake <num! 4> == <num= 4> (diff)
downloadalive-4ca20944892bebc0ddac7aa23ed8abef5d537209.tar.gz
alive-4ca20944892bebc0ddac7aa23ed8abef5d537209.zip
make EvtStreams carry a single value
-rw-r--r--alv/result/evt.moon21
-rw-r--r--spec/input_spec.moon6
-rw-r--r--spec/result/evt_spec.moon111
-rw-r--r--spec/result/sig_spec.moon6
-rw-r--r--spec/rtnode_spec.moon6
5 files changed, 126 insertions, 24 deletions
diff --git a/alv/result/evt.moon b/alv/result/evt.moon
index ad4c102..a89aa74 100644
--- a/alv/result/evt.moon
+++ b/alv/result/evt.moon
@@ -16,15 +16,16 @@ class EvtStream extends Result
--- get the sequence of current events (if any).
--
- -- Returns `events` if `dirty`, or an empty table otherwise.
+ -- Returns `value` if `dirty`, or `nil` otherwise.
-- Asserts `@type == type` if `type` is given.
--
-- @tparam[opt] type.Type type the type to check for
-- @tparam[optchain] string msg message to throw if type don't match
- -- @treturn {any,...} `events`
+ -- @treturn ?any `value`
unwrap: (type, msg) =>
assert type == @type, msg or "#{@} is not a #{type}" if type
- if @dirty! then @events else {}
+ @value
+ if @dirty! then @value
--- create a mutable copy of this stream.
--
@@ -37,8 +38,7 @@ class EvtStream extends Result
__call: (...) => @unwrap ...
__tostring: =>
- events = table.concat [@type\pp e for e in *@events], ' '
- "<#{@type}#{@metatype} #{events}>"
+ "<#{@type}#{@metatype} #{if @dirty then @type\pp @value else 'nil'}>"
--- the type of this Result's value.
-- @tfield type.Type type
@@ -65,15 +65,13 @@ class EvtStream extends Result
--- push an event value into the stream.
--
-- Marks this stream as dirty for the remainder of the current tick.
- add: (event) =>
- if not @dirty!
- @events = {}
-
+ set: (event) =>
+ assert not @dirty!, "#{@} is already dirty!"
@updated = COPILOT.T
- table.insert @events, event
+ @value = event
--- the wrapped Lua value.
- -- @tfield {any,...} events
+ -- @tfield any value
--- static functions
-- @section static
@@ -84,7 +82,6 @@ class EvtStream extends Result
-- @tparam type.Type type the type
new: (type) =>
super type
- @events = {}
{
:EvtStream
diff --git a/spec/input_spec.moon b/spec/input_spec.moon
index 8dbd726..3a8eff9 100644
--- a/spec/input_spec.moon
+++ b/spec/input_spec.moon
@@ -13,8 +13,8 @@ basic_tests = (result, input) ->
assert.is.equal result, input.result
it 'forwards :unwrap', ->
- assert.is.same result\unwrap!, input\unwrap!
- assert.is.same result\unwrap!, input!
+ assert.is.equal result\unwrap!, input\unwrap!, nil
+ assert.is.equal result\unwrap!, input!, nil
it 'gives access to the type string', ->
assert.is.equal result.type, input\type!
@@ -96,7 +96,7 @@ describe 'Input.hot', ->
input\finish_setup!
COPILOT\next_tick!
- result\add 1
+ result\set 1
assert.is.true input\dirty!
assert.is.true result\dirty!
diff --git a/spec/result/evt_spec.moon b/spec/result/evt_spec.moon
new file mode 100644
index 0000000..93c09e0
--- /dev/null
+++ b/spec/result/evt_spec.moon
@@ -0,0 +1,111 @@
+import do_setup from require 'spec.test_setup'
+import EvtStream, RTNode, Scope, SimpleRegistry, T from require 'alv'
+import Op, Builtin from require 'alv.base'
+
+setup do_setup
+
+describe 'EvtStream', ->
+ describe ':unwrap', ->
+ it 'returns the set value', ->
+ stream = EvtStream T.num
+ assert.is.nil stream\unwrap!
+
+ stream\set 3.14
+ assert.is.equal 3.14, stream\unwrap!
+
+ it 'returns nil if not dirty', ->
+ stream = EvtStream T.num
+ assert.is.nil stream\unwrap!
+
+ stream\set 3.14
+ COPILOT\next_tick!
+ assert.is.nil stream\unwrap!
+
+ test 'can assert the type', ->
+ assert.is.nil (EvtStream T.num)\unwrap T.num
+ assert.is.nil (EvtStream T.str)\unwrap T.str
+ assert.is.nil (EvtStream T.sym)\unwrap T.sym
+ assert.has_error -> (EvtStream T.num)\unwrap T.sym
+ assert.has_error -> (EvtStream T.str)\unwrap T.num
+ assert.has_error -> (EvtStream T.sym)\unwrap T.str
+
+ test 'has __call shorthand', ->
+ stream = EvtStream T.num
+ assert.is.nil stream!
+
+ stream\set 3.14
+ assert.is.equal 3.14, stream!
+
+ describe ':set', ->
+ it 'sets the value', ->
+ stream = EvtStream T.num
+ assert.is.false stream\dirty!
+
+ stream\set 4
+ assert.is.equal 4, stream\unwrap!
+ assert.is.true stream\dirty!
+
+ COPILOT\next_tick!
+
+ assert.is.false stream\dirty!
+ stream\set 3
+ assert.is.equal 3, stream\unwrap!
+ assert.is.true stream\dirty!
+
+ it 'errors when set twice', ->
+ stream = EvtStream T.num
+ stream\set 1
+ assert.has.error -> stream\set 2
+ assert.is.equal 1, stream\unwrap!
+
+ it 'resets on the next tick', ->
+ stream = EvtStream T.num
+ stream\set 1
+
+ COPILOT\next_tick!
+
+ assert.is.false stream\dirty!
+ stream\set 2
+ assert.is.equal 2, stream\unwrap!
+ assert.is.true stream\dirty!
+
+ describe ':fork', ->
+ it 'is clean', ->
+ a = EvtStream T.num
+ b = EvtStream T.str
+ b\set 'asdf'
+
+ aa, bb = a\fork!, b\fork!
+ assert.is.nil aa!
+ assert.is.nil bb!
+ assert.is.false aa\dirty!
+ assert.is.false bb\dirty!
+
+ it 'leaves the original', ->
+ a = EvtStream T.num
+ b = EvtStream T.str
+ b\set 'asdf'
+
+ aa, bb = a\fork!, b\fork!
+ assert.is.nil a!
+ assert.is.equal 'asdf', b!
+ assert.is.false a\dirty!
+ assert.is.true b\dirty!
+
+ it 'isolates the original from the fork', ->
+ a = EvtStream T.num
+ b = EvtStream T.str
+
+ aa, bb = a\fork!, b\fork!
+ a\set 1
+ bb\set 2
+
+ assert.is.equal 1, a!
+ assert.is.true a\dirty!
+ assert.is.nil aa!
+ assert.is.false aa\dirty!
+
+ assert.is.equal 2, bb!
+ assert.is.true bb\dirty!
+ assert.is.nil b!
+ assert.is.false b\dirty!
diff --git a/spec/result/sig_spec.moon b/spec/result/sig_spec.moon
index 6e9a11c..1a92bdc 100644
--- a/spec/result/sig_spec.moon
+++ b/spec/result/sig_spec.moon
@@ -2,12 +2,6 @@ import do_setup from require 'spec.test_setup'
import SigStream, Constant, RTNode, Scope, SimpleRegistry, T from require 'alv'
import Op, Builtin from require 'alv.base'
-class TestOp extends Op
- new: (...) => super ...
-
-class TestBuiltin extends Builtin
- new: (...) =>
-
setup do_setup
describe 'SigStream', ->
diff --git a/spec/rtnode_spec.moon b/spec/rtnode_spec.moon
index 5dfebf7..9c62350 100644
--- a/spec/rtnode_spec.moon
+++ b/spec/rtnode_spec.moon
@@ -115,7 +115,7 @@ describe 'RTNode', ->
b_child = node_with_sideinput b_value, b_input
it 'updates children when a side_input is dirty', ->
- a_value\add 1
+ a_value\set 1
assert.is.true a_input\dirty!
assert.is.false b_input\dirty!
@@ -142,7 +142,7 @@ describe 'RTNode', ->
assert.spy(b).was_not_called!
it 'updates op when any op-inputs are dirty', ->
- a_value\add 1
+ a_value\set 1
assert.is.true a_input\dirty!
assert.is.false b_input\dirty!
@@ -155,7 +155,7 @@ describe 'RTNode', ->
assert.spy(s).was_called_with match.ref op
it 'early-outs when no op-inputs are dirty', ->
- a_value\add 1
+ a_value\set 1
assert.is.true a_input\dirty!
assert.is.false b_input\dirty!