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 | with Ada.Containers.Indefinite_Doubly_Linked_Lists;
package body Rx.Op.Repeat is
use type Operate.T;
package T_Lists is new Ada.Containers.Indefinite_Doubly_Linked_Lists (Operate.T);
use type Actions.HTFilter0;
type Kinds is (Counter, While_Do, Repeat_Until);
type Operator (Kind : Kinds) is new Operate.Operator with record
Sequence : T_Lists.List;
First_Seen : Boolean := False;
case Kind is
when Counter => Repeats : Rx_Integer range 0 .. Rx_Integer'Last;
when others => Filter : Actions.HTFilter0;
end case;
end record;
overriding
procedure On_Next (This : in out Operator;
V : Operate.T);
overriding
procedure On_Complete (This : in out Operator);
overriding
procedure On_Next (This : in out Operator;
V : Operate.T) is
begin
if This.Kind = While_Do and then not This.First_Seen and then not This.Filter.Ref.Check then
This.Get_Observer.On_Complete ;
This.Unsubscribe;
else
This.First_Seen := True;
This.Sequence.Append (V);
This.Get_Observer.On_Next (V);
end if;
end On_Next;
overriding
procedure On_Complete (This : in out Operator)
is
Check : Boolean;
begin
if not This.Is_Subscribed then -- Because its While_Do and first check failed
return;
end if;
if not This.Sequence.Is_Empty then
case This.Kind is
when Counter =>
for I in 1 .. This.Repeats loop
for V of This.Sequence loop
This.Get_Observer.On_Next (V);
end loop;
end loop;
when While_Do | Repeat_Until =>
loop
Check := This.Filter.Ref.Check;
exit when (This.Kind = Repeat_Until and then Check) or else
(This.Kind = While_Do and then not Check);
for V of This.Sequence loop
This.Get_Observer.On_Next (V);
end loop;
end loop;
end case;
end if;
This.Get_Observer.On_Complete ;
end On_Complete ;
--------------------
-- Repeat_Forever --
--------------------
function Repeat_Forever return Operate.Operator'Class is
begin
return Operator'(Operate.Operator with
Kind => While_Do,
Filter => + Actions.Wrap (Always'Access),
others => <>);
end Repeat_Forever;
------------
-- Repeat --
------------
function Repeat (Times : Rx_Integer) return Operate.Operator'Class is
begin
return Operator'(Operate.Operator with
Kind => Counter,
Repeats => Times,
others => <>);
end Repeat;
--------------
-- While_Do --
--------------
function While_Do
(Check : Actions.TFilter0'Class)
return Operate.Operator'Class
is
begin
return Operator'(Operate.Operator with
Kind => While_Do,
Filter => + Check,
others => <>);
end While_Do;
------------------
-- Repeat_Until --
------------------
function Repeat_Until
(Check : Actions.TFilter0'Class)
return Operate.Operator'Class
is
begin
return Operator'(Operate.Operator with
Kind => Repeat_Until,
Filter => + Check,
others => <>);
end Repeat_Until;
end Rx.Op.Repeat;
|