aboutsummaryrefslogtreecommitdiffstats
path: root/core/value.moon
diff options
context:
space:
mode:
Diffstat (limited to 'core/value.moon')
-rw-r--r--core/value.moon118
1 files changed, 11 insertions, 107 deletions
diff --git a/core/value.moon b/core/value.moon
index b01b28f..26771ea 100644
--- a/core/value.moon
+++ b/core/value.moon
@@ -1,9 +1,5 @@
--- ALV Value types
-local Scope, Registry, Op, Action, IOInput, FnDef
-load_ = ->
- import Scope from require 'core.scope'
- import Registry from require 'core.registry'
- import Op, Action, IOInput, FnDef from require 'core.base'
+import Result from require 'core.result'
+import scope, base, registry from require 'core.cycle'
ancestor = (klass) ->
assert klass, "cant find the ancestor of nil"
@@ -11,98 +7,6 @@ ancestor = (klass) ->
klass = klass.__parent
klass
--- Result of evaluating an expression
--- carries (all optional):
--- - a Value
--- - an Op (to update)
--- - children (results of subexpressions that were evaluated)
--- - cached list of all Dispatchers affecting all Ops in the subtree
---
--- Results form a tree that controls execution order and message passing
--- between Ops.
-class Result
- -- params: table with optional keys op, value, children
- new: (params={}) =>
- @value = params.value
- @op = params.op
- @children = params.children or {}
-
- @side_inputs, is_child = {}, {}
- for child in *@children
- for s, d in pairs child.side_inputs
- @side_inputs[s] = d
- if child.value
- is_child[child.value] = true
-
- if @op
- for input in @op\all_inputs!
- if input.impure or not is_child[input.stream]
- @side_inputs[input.stream] = input
-
- is_const: => not next @side_inputs
-
- -- asserts value-constness and returns the value
- const: (msg) =>
- assert not (next @side_inputs), msg or "eval-time const expected"
- @value
-
- -- asserts a value exists and returns its type
- type: =>
- assert @value, "Result with value expected"
- @value.type
-
- -- create a value-copy of this result that has the same impulses but without
- -- affecting the original's update logic
- make_ref: =>
- with Result value: @value
- .side_inputs = @side_inputs
-
- -- tick all IO instances that are effecting this (sub) tree
- -- should be called once per frame on the root, right before tick
- tick_io: =>
- for stream, input in pairs @side_inputs
- if input.__class == IOInput
- io = input!
- io\tick!
-
- -- in depth-first order, tick all Ops who have dirty Stream inputs or impulses
- --
- -- short-circuits if there are no dirty Streams in the entire subtree
- tick: =>
- any_dirty = false
- for stream, input in pairs @side_inputs
- if input\dirty!
- any_dirty = true
- break
-
- -- early-out if no streams are dirty in this whole subtree
- return unless any_dirty
-
- for child in *@children
- child\tick!
-
- if @op
- -- we have to check self_dirty here, because streams from child
- -- expressions might have changed
- self_dirty = false
- for stream in @op\all_inputs!
- if stream\dirty!
- self_dirty = true
- break
-
- L\trace "#{@op} is #{if self_dirty then 'dirty' else 'clean'}"
- return unless self_dirty
-
- @op\tick!
-
--- static
- __tostring: =>
- buf = "<result=#{@value}"
- buf ..= " #{@op}" if @op
- buf ..= " (#{#@children} children)" if #@children > 0
- buf ..= ">"
- buf
-
-- ALV Type wrapper
class Value
-- @type - type name.
@@ -112,9 +16,9 @@ class Value
new: (@type, @value, @raw) =>
@updated = nil
- dirty: => @updated == Registry.active!.tick
+ dirty: => @updated == registry.Registry.active!.tick
- set: (@value) => @updated = Registry.active!.tick
+ set: (@value) => @updated = registry.Registry.active!.tick
-- unwrap to the Lua type
-- asserts @type == type, msg if given
@@ -149,29 +53,30 @@ class Value
-- wrap a Lua type
@wrap: (val, name='(unknown)') ->
+
typ = switch type val
when 'number' then 'num'
when 'string' then 'str'
when 'table'
- if base = rawget val, '__base'
+ if rawget val, '__base'
-- a class
switch ancestor val
- when Op then 'opdef'
- when Action then 'builtin'
+ when base.Op then 'opdef'
+ when base.Action then 'builtin'
else
error "#{name}: cannot wrap class '#{val.__name}'"
elseif val.__class
-- an instance
switch ancestor val.__class
- when Scope then 'scope'
- when FnDef then 'fndef'
+ when scope.Scope then 'scope'
+ when base.FnDef then 'fndef'
when Value
return val
else
error "#{name}: cannot wrap '#{val.__class.__name}' instance"
else
-- plain table
- return Value 'scope', Scope.from_table val
+ return Value 'scope', scope.Scope.from_table val
else
error "#{name}: cannot wrap Lua type '#{type val}'"
@@ -190,7 +95,6 @@ class Value
@bool: (bool) -> Value 'bool', bool, tostring bool
{
- :Result
:Value
:load_
}