|
| 1 | +struct StateValue |
| 2 | + state :: EVENT_STATE |
| 3 | + value :: Any |
| 4 | + function StateValue(state::EVENT_STATE, value::Any=nothing) |
| 5 | + new(state, value) |
| 6 | + end |
| 7 | +end |
| 8 | + |
| 9 | +struct Operator <: AbstractEvent |
| 10 | + bev :: BaseEvent |
| 11 | + eval :: Function |
| 12 | + function Operator(eval::Function, fev::AbstractEvent, events::AbstractEvent...) |
| 13 | + env = environment(fev) |
| 14 | + op = new(BaseEvent(env), eval) |
| 15 | + event_state_values = Dict{AbstractEvent, StateValue}() |
| 16 | + for ev in tuple(fev, events...) |
| 17 | + event_state_values[ev] = StateValue(state(ev)) |
| 18 | + append_callback(check, ev, op, event_state_values) |
| 19 | + end |
| 20 | + op |
| 21 | + end |
| 22 | +end |
| 23 | + |
| 24 | +function check(ev::AbstractEvent, op::Operator, event_state_values::Dict{AbstractEvent, StateValue}) |
| 25 | + val = value(ev) |
| 26 | + if state(op) == idle |
| 27 | + if isa(val, Exception) |
| 28 | + schedule(op.bev, value=val) |
| 29 | + else |
| 30 | + event_state_values[ev] = StateValue(state(ev), val) |
| 31 | + if op.eval(collect(values(event_state_values))) |
| 32 | + schedule(op.bev, value=event_state_values) |
| 33 | + end |
| 34 | + end |
| 35 | + elseif state(op) == scheduled |
| 36 | + if isa(val, Exception) |
| 37 | + schedule(op.bev, priority=typemax(Int8), value=val) |
| 38 | + else |
| 39 | + event_state_values[ev] = StateValue(state(ev), val) |
| 40 | + end |
| 41 | + end |
| 42 | +end |
| 43 | + |
| 44 | +function eval_and(state_values::Vector{StateValue}) |
| 45 | + return all(map((sv)->sv.state == triggered, state_values)) |
| 46 | +end |
| 47 | + |
| 48 | +function eval_or(state_values::Vector{StateValue}) |
| 49 | + return any(map((sv)->sv.state == triggered, state_values)) |
| 50 | +end |
| 51 | + |
| 52 | +function (&)(ev1::AbstractEvent, ev2::AbstractEvent) |
| 53 | + return Operator(eval_and, ev1, ev2) |
| 54 | +end |
| 55 | + |
| 56 | +function (|)(ev1::AbstractEvent, ev2::AbstractEvent) |
| 57 | + return Operator(eval_or, ev1, ev2) |
| 58 | +end |
0 commit comments