Skip to content

Commit 2cf4a2b

Browse files
committed
Add Operator
1 parent ca235b1 commit 2cf4a2b

4 files changed

Lines changed: 103 additions & 1 deletion

File tree

src/SimJulia.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,20 @@ module SimJulia
88
using DataStructures
99

1010
import Base.run, Base.now, Base.isless, Base.show
11+
import Base.(&), Base.(|)
1112

1213
export AbstractEvent
1314
export value, state, environment
1415
export Simulation
1516
export run, now, active_process
1617
export Event, Timeout
1718
export succeed, fail, append_callback, @callback, remove_callback
19+
export Operator
20+
export (&), (|)
1821

1922
include("base.jl")
2023
include("simulations.jl")
2124
include("events.jl")
25+
include("operators.jl")
2226

2327
end

src/operators.jl

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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

test/operators.jl

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using SimJulia
2+
3+
function and_callback(ev::AbstractEvent)
4+
println("Both events are triggered: $(value(ev))")
5+
end
6+
7+
function or_callback(ev::AbstractEvent)
8+
println("One of both events is triggered: $(value(ev))")
9+
end
10+
11+
function or_callback_succeed(ev::AbstractEvent, ev2::AbstractEvent)
12+
println("One of both events is triggered: $(value(ev))")
13+
succeed(ev2)
14+
end
15+
16+
function or_callback_fail(ev::AbstractEvent, ev2::AbstractEvent)
17+
println("One of both events is triggered: $(value(ev))")
18+
fail(ev2, TestException())
19+
end
20+
21+
sim = Simulation()
22+
ev1 = Timeout(sim, 1)
23+
ev2 = Event(sim)
24+
@callback and_callback(ev1 & ev2)
25+
@callback or_callback_succeed(ev1 | ev2, ev2)
26+
run(sim)
27+
28+
sim = Simulation()
29+
ev1 = Timeout(sim, 1, value=TestException())
30+
ev2 = Event(sim)
31+
@callback or_callback_fail(ev1 | ev2, ev2)
32+
@callback and_callback(ev1 & ev2)
33+
run(sim)
34+
35+
sim = Simulation()
36+
ev1 = Timeout(sim)
37+
ev2 = Timeout(sim, value=TestException())
38+
@callback or_callback(ev1 | ev2)
39+
run(sim)

test/runtests.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ testpath(f) = joinpath(dirname(@__FILE__), f)
33
for test_file in [
44
"base.jl",
55
"simulations.jl",
6-
"events.jl",]
6+
"events.jl",
7+
"operators.jl",]
78
include(testpath(test_file))
89
end

0 commit comments

Comments
 (0)