Packages
bpe
11.4.15
13.5.22-aleph
11.4.16
11.4.15
11.4.14
11.4.13
9.9.7
9.9.6
8.12.4
8.12.3
8.12.1
8.12.0
retired
8.2.1
8.2.0
8.1.0
7.11.0
7.10.4
7.10.3
7.10.2
7.10.1
7.9.1
7.9.0
7.8.2
7.8.1
7.8.0
7.6.4
7.6.3
7.6.2
7.6.1
7.6.0
7.5.15
7.5.14
7.5.13
7.5.12
7.5.11
7.5.10
7.5.9
7.5.8
7.5.7
7.5.6
7.5.5
7.5.3
7.5.2
7.5.1
7.5.0
7.4.11
7.4.10
7.4.9
7.4.8
7.4.7
7.4.6
7.4.5
7.4.4
7.4.3
7.4.2
7.4.1
7.4.0
7.3.0
7.2.8
7.2.7
7.2.6
7.1.6
7.1.5
7.1.4
7.1.3
7.1.2
6.12.7
6.12.6
6.12.5
6.12.3
6.12.2
6.12.1
6.12.0
6.11.0
6.10.0
6.5.3
6.5.2
6.5.1
6.5.0
6.4.0
6.3.0
5.12.0
5.11.4
5.11.3
5.11.2
5.11.1
5.11.0
5.8.7
5.8.6
5.8.5
5.8.4
5.8.3
5.8.2
5.8.1
5.8.0
5.7.0
5.6.0
5.5.2
5.5.1
5.4.0
5.2.0
5.1.3
5.1.2
5.1.1
4.12.4
4.12.3
4.12.2
4.12.1
4.12.0
4.11.8
4.11.7
4.11.6
4.11.5
4.11.4
4.11.3
4.11.2
4.11.1
4.11.0
4.10.24
4.10.23
4.10.22
4.10.21
4.10.20
4.10.19
4.10.18
4.10.17
4.10.16
4.10.15
4.10.14
4.10.13
4.10.12
4.10.11
4.10.10
4.10.9
4.10.8
4.10.7
4.10.6
4.10.5
4.10.4
4.10.3
4.10.2
4.10.1
4.10.0
4.9.18
4.9.17
4.9.16
4.9.15
4.9.14
4.9.13
4.9.12
4.9.11
4.9.10
4.9.9
4.9.8
4.9.7
4.9.6
4.9.5
4.9.4
4.9.3
4.9.2
4.9.1
4.9.0
4.8.1
4.8.0
4.7.5
4.7.3
4.7.2
4.7.1
4.7.0
4.6.0
2.4.0
0.7.16
ERP/1: RTP GST WebRTC ICE SDP H.264 H.265 MP4 MPEG-2 HLS HEVC
Current section
Files
Jump to
Current section
Files
lib/bpe/gateways.ex
defmodule BPE.Gateways do
require BPE
import BPE
# field positions in the task/gateway tuple (1-based, as used by :erlang.element/2)
# tuple layout: {record_atom, id, name, input, output, prompt, roles, etc, ...}
@id_pos 2
@input_pos 4
@output_pos 5
@roles_pos 7
def def do
r_raw = [
{:r1, :a, :b}, {:r2, :b, :c}, {:r3, :b, :d}, {:r4, :c, :e},
{:r5, :c, :f}, {:r6, :d, :g}, {:r7, :e, :h}, {:r8, :h, :j},
{:r9, :f, :i}, {:r10, :i, :j}, {:r11, :f, :g}, {:r12, :g, :j},
{:r13, :j, :k}
]
{r, n} = get_edges_and_vertices(r_raw)
p = process(name: :Graph, flows: r, tasks: n, beginEvent: :a, endEvent: :k, events: [])
fix_gateways(fix_begin_end_events(p))
end
def vertices(r), do: vertices(Enum.reverse(r), [])
def vertices([], n), do: n
def vertices([sequenceFlow(id: id, source: from, target: to) | rtail], n) do
n1 =
case find_task(from, n) do
false -> [task(name: from, output: [id]) | n]
v -> replace_task(from, n, task(v, output: [id | task(v, :output)]))
end
new_n =
case find_task(to, n1) do
false -> [task(name: to, input: [id]) | n1]
v1 -> replace_task(to, n1, task(v1, input: [id | task(v1, :input)]))
end
vertices(rtail, new_n)
end
def get_edges_and_vertices(edges_raw) do
r = for {id, from, to} <- edges_raw, do: sequenceFlow(name: id, source: from, target: to)
{r, vertices(r)}
end
def set_vertex_type(id, type, vertices) do
case find_task(id, vertices) do
false -> vertices
v ->
new_vertex = gateway(id: task(v, :id), name: task(v, :name),
input: task(v, :input), output: task(v, :output), type: type)
replace_task(id, vertices, new_vertex)
end
end
def fix_begin_end_events(proc) do
tasks = process(proc, :tasks)
[begin_task] = for task(input: []) = t <- tasks, do: t
[end_task] = for task(output: []) = t <- tasks, do: t
begin_event = beginEvent(name: task(begin_task, :name))
end_event = endEvent(name: task(end_task, :name))
process(proc,
tasks: [begin_event, end_event | tasks -- [begin_task, end_task]],
beginEvent: task(begin_task, :name),
endEvent: task(end_task, :name)
)
end
def fix_gateways(process(tasks: tasks) = proc) do
process(proc, tasks: Enum.map(tasks, &convert_if_needed/1))
end
def convert_if_needed(task(name: name, input: in_f, output: out_f) = t)
when length(in_f) > 1 or length(out_f) > 1 do
gateway(name: name, type: :parallel, input: task(t, :input), output: task(t, :output))
end
def convert_if_needed(t), do: t
def action({:request, _, _}, proc), do: {:reply, proc}
# ── helpers ─────────────────────────────────────────────────────────────────
defp find_task(id, list) do
Enum.find(list, fn t -> is_tuple(t) and :erlang.element(@id_pos, t) == id end)
end
defp replace_task(id, list, new_val) do
Enum.map(list, fn t ->
if is_tuple(t) and :erlang.element(@id_pos, t) == id, do: new_val, else: t
end)
end
# Called from BPE.XML.fill_in_out with field positions
def key_push_value(value, value_key_pos, elem_id, list) do
case find_task(elem_id, list) do
nil -> list
false -> list
found ->
if elem(found, 0) == :endEvent do
list
else
new_found = :erlang.setelement(value_key_pos, found,
[value | :erlang.element(value_key_pos, found)])
replace_task(elem_id, list, new_found)
end
end
end
def output_pos, do: @output_pos
def input_pos, do: @input_pos
def roles_pos, do: @roles_pos
def id_pos, do: @id_pos
end