blob: c89337f7e7fab2f613cd99575d34023475d70495 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
----
-- Update scheduling policy for `Op` arguments.
--
-- @classmod Input
import Value from require 'core.value'
import Result from require 'core.result'
local ColdInput, ValueInput, EventInput, IOInput
class Input
--- Input interface.
--
-- Methods that have to be implemented by `Input` implementations.
-- @section interface
--- create a new Input.
--
-- `value` is either a `Value` or a `Result` instance and should be
-- unwrapped and assigned to `stream`.
--
-- @classmethod
-- @tparam Value|Result value
new: (value) =>
assert value, "nil passed to Input: #{value}"
@stream = switch value.__class
when Result
assert value.value, "Input from result without value!"
when Value
value
else
error "Input from unknown value: #{value}"
--- copy state from old instance (optional).
--
-- called by `Op:setup` with another `Input` instance or `nil` once this instance is
-- registered. Must prepare this instance for `dirty`.
--
-- May enter a 'setup state' that is exited using `finish_setup`.
--
-- @tparam ?Input prev previous `Input` intance or nil
setup: (prev) =>
--- whether this input requires processing (optional).
--
-- must return a boolean indicating whether `Op`s that refer to this instance
-- should be notified (via `Op:tick`). If not overwritten, delegates to
-- `stream`:@{Value:dirty|dirty}.
--
-- @treturn bool whether processing is necessary
dirty: => @stream\dirty!
--- leave setup state (optional).
--
-- called after the `Op` has completed (or skipped) its first `Op:tick` after
-- `Op:setup`. Must prepare this instance for dataflow operation.
finish_setup: =>
--- unwrap to Lua value (optional).
--
-- @treturn any the raw Lua value
unwrap: => @stream\unwrap!
--- return the type name of this `Input` (optional).
type: => @stream.type
--- the current value
--
-- @tfield Value stream
--- members
-- @section members
--- alias for `unwrap`.
__call: => @stream\unwrap!
__tostring: => "#{@@__name}:#{@stream}"
__inherited: (cls) =>
cls.__base.__call = @__call
cls.__base.__tostring = @__tostring
--- static functions
-- @section static
--- Create a `cold` `Input`.
--
-- Never marked dirty. Use this for input streams that are only read when
-- another `Input` is dirty.
--
-- @tparam Value|Result value
@cold: (value) -> ColdInput value
--- Create a `value` `Input`.
--
-- Marked dirty for the eval-tick if old and new `Value` differ. This is the
-- most common `Input` strategy. Should be used whenever a
-- value denotes state.
--
-- @tparam Value|Result value
@value: (value) -> ValueInput value
--- Create an `event` `Input`.
--
-- Only marked dirty if the `Value` itself is dirty. Should be used whenever
-- an `Input` denotes a momentary event or impulse.
--
-- @tparam Value|Result value
@event: (value) -> EventInput value
--- Create an `IO` `Input`.
--
-- Marked dirty only when an `IO` is dirty. Must be used only for `Value`s
-- which @{Value:unwrap|unwrap} to `IO` instances.
--
-- @tparam Value|Result value
@io: (value) -> IOInput value
class ColdInput extends Input
dirty: => false
class ValueInput extends Input
setup: (old) => @dirty_setup = not old or @stream != old.stream
finish_setup: => @dirty_setup = nil
dirty: =>
return @dirty_setup if @dirty_setup != nil
@stream\dirty!
class EventInput extends Input
class IOInput extends Input
impure: true
dirty: => @stream\unwrap!\dirty!
{
:Input
}
|