aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2022-02-04 00:17:26 +0000
committers-ol <s+removethis@s-ol.nu>2025-03-02 14:24:49 +0000
commitc8a26d3be7ce1d752c43eb58ce7dddf893d15a74 (patch)
tree43a35ef5243dc1198de23ce14209be11d3bf8a78
parentlib: add mat4 (diff)
downloadalive-c8a26d3be7ce1d752c43eb58ce7dddf893d15a74.tar.gz
alive-c8a26d3be7ce1d752c43eb58ce7dddf893d15a74.zip
add Op:update_out and use in builtins
-rw-r--r--alv/base/op.moon21
-rw-r--r--alv/base/pureop.moon3
-rw-r--r--alv/builtins.moon10
3 files changed, 27 insertions, 7 deletions
diff --git a/alv/base/op.moon b/alv/base/op.moon
index 982d75b..e751145 100644
--- a/alv/base/op.moon
+++ b/alv/base/op.moon
@@ -4,6 +4,7 @@
-- @classmod Op
import deep_copy, deep_iter, deep_map from require 'alv.util'
import T from require 'alv.type'
+import SigStream, EvtStream from require 'alv.result'
class Op
--- members
@@ -160,6 +161,26 @@ class Op
@inputs = inputs
do_setup old_inputs, @inputs
+ --- create or update `out`.
+ --
+ -- This should be used instead of setting `out` directly.
+ -- It will try to keep the current value if possible.
+ --
+ -- @tparam string metatype (one of `!` or `~`)
+ -- @tparam Type type
+ -- @tparam[opt] any val initial value
+ update_out: (metatype, type, val) =>
+ same_type = @out and @out.type == type
+ if same_type and @out.metatype == metatype
+ -- we can just keep it. do nothing.
+ return
+
+ -- prefer last value if applicable
+ val = same_type and @.out! or val
+
+ ResultType = if metatype == '!' then EvtStream else SigStream
+ @out = ResultType type, val
+
--- `\unwrap` all `Input`s in `@inputs` and return a table with the same
-- shape.
--
diff --git a/alv/base/pureop.moon b/alv/base/pureop.moon
index 10c737c..449519a 100644
--- a/alv/base/pureop.moon
+++ b/alv/base/pureop.moon
@@ -56,7 +56,8 @@ class PureOp extends Op
typ = if (type @type) == 'function' then @type args else @type
if typ
assert (ancestor typ.__class) == Type, "not a type: #{typ}"
- @out = if trigger then typ\mk_evt! else typ\mk_sig!
+ metatype = if trigger then '!' else '~'
+ @update_out metatype, typ
map_fn = if trigger then hot_if_trigger trigger else Input.hot
inputs = deep_map args, map_fn
diff --git a/alv/builtins.moon b/alv/builtins.moon
index bf3c95f..a015bc6 100644
--- a/alv/builtins.moon
+++ b/alv/builtins.moon
@@ -337,10 +337,8 @@ switch_ = Constant.meta
setup: (inputs) =>
{ i, values } = pattern\match inputs
- @out = if values[1].result.metatype ~= '!'
- values[1]\type!\mk_sig!
- else
- values[1]\type!\mk_evt!
+ val1 = values[1]
+ @update_out val1.result.metatype, val1.result.type
if i\type! == T.bang
@state or= 1
@@ -463,8 +461,7 @@ Since ~-streams cannot be emtpy, specifying an `initial` value is necessary."
super event: Input.hot event
- if not @out or @out.type != event\type!
- @out = event\type!\mk_sig initial.result!
+ @update_out '~', event\type!, initial.result!
tick: => @out\set @inputs.event!
@@ -493,6 +490,7 @@ to_evt = Constant.meta
sig: Input.cold Constant.bang true
else
super sig: Input.hot sig_
+
@out = @inputs.sig\type!\mk_evt!
tick: (setup) =>