| 190 | |
| 191 | == Вариант 1.1 == |
| 192 | |
| 193 | Этот вариант является модификацией предыдущего в части объявления и подключения слотов. Настраиваемый пакет Generic_Slot в Objects.Signals настраивается на тэговый тип и подпрограмму, играющую роль слота и предоставляет подпрогаммы подключения/отключения: |
| 194 | |
| 195 | === API поддержки === |
| 196 | |
| 197 | {{{ |
| 198 | package Objects.Signals is |
| 199 | |
| 200 | ---------------------- |
| 201 | -- Signal_Connector -- |
| 202 | ---------------------- |
| 203 | |
| 204 | type Signal_Connector (<>) is limited private; |
| 205 | |
| 206 | generic |
| 207 | type T is abstract new Abstract_Object with private; |
| 208 | with procedure Method (Self : not null access T) is abstract; |
| 209 | |
| 210 | package Generic_Slot is |
| 211 | |
| 212 | procedure Connect |
| 213 | (Self : Signal_Connector; |
| 214 | Object : not null access T'Class); |
| 215 | |
| 216 | end Generic_Slot; |
| 217 | |
| 218 | ------------ |
| 219 | -- Signal -- |
| 220 | ------------ |
| 221 | |
| 222 | type Signal |
| 223 | (Object : not null access Abstract_Object'Class) is tagged limited private; |
| 224 | |
| 225 | not overriding procedure Emit (Self : Signal); |
| 226 | |
| 227 | not overriding function Connector |
| 228 | (Self : in out Signal) return Signal_Connector; |
| 229 | |
| 230 | private |
| 231 | ... |
| 232 | end Objects.Signals; |
| 233 | }}} |
| 234 | |
| 235 | === Пример использования === |
| 236 | |
| 237 | По сравнения с предыдущим вариантом изменяется способ использования только для типов, содержащих слоты. Для каждого слота объявляется собственный дочерний пакет, содержащий настройку пакета Objects.Signals.Generic_Slot: |
| 238 | |
| 239 | {{{ |
| 240 | with Objects.Signals; |
| 241 | |
| 242 | package Collectors.Process_Slot is |
| 243 | new Objects.Signals.Generic_Slots (Collector, Process); |
| 244 | }}} |
| 245 | |
| 246 | Главная программа выглядит следующим образом: |
| 247 | |
| 248 | {{{ |
| 249 | with Collectors.Process_Slot; |
| 250 | with Emitters; |
| 251 | |
| 252 | procedure Main is |
| 253 | C : aliased Collectors.Collector; |
| 254 | E : aliased Emitters.Emitter; |
| 255 | |
| 256 | begin |
| 257 | Collectors.Process_Slot.Connect (E.Signal, C'Access); |
| 258 | E.Test; |
| 259 | end Main; |
| 260 | }}} |
| 261 | |
| 262 | === Выводы === |
| 263 | |
| 264 | Больше писанины, поскольку необходимо объявлять отдельный пакет для каждого слота, но (1) меньше усилий на выполнение подключения и лучше понимание происходящего, и (2) жестко контролируется, что слот есть примитивная операция типа. |