-
Notifications
You must be signed in to change notification settings - Fork 70
/
devices.jl
125 lines (110 loc) · 3.39 KB
/
devices.jl
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
"""
This function add a service to the component without checking if the component and the service are attached to the same system
"""
function add_service_internal!(device::Device, service::Service)
services = get_services(device)
for _service in services
if IS.get_uuid(service) == IS.get_uuid(_service)
throw(
ArgumentError(
"service $(get_name(service)) is already attached to $(get_name(device))",
),
)
end
end
push!(services, service)
@debug "Add $service to $(get_name(device))" _group = IS.LOG_GROUP_SYSTEM
end
function add_service_internal!(device::Device, service::AGC)
if !isa(device, RegulationDevice)
throw(
IS.ConflictingInputsError(
"AGC service can only accept contributing devices of type RegulationDevice",
),
)
end
device_bus_area = get_area(get_bus(device))
service_area = get_area(service)
if isnothing(device_bus_area) ||
!(IS.get_uuid(device_bus_area) == IS.get_uuid(service_area))
throw(
IS.ConflictingInputsError(
"Device $(get_name(device)) is not located in the regulation control area",
),
)
end
services = get_services(device)
for _service in services
if IS.get_uuid(service) == IS.get_uuid(_service)
throw(
ArgumentError(
"service $(get_name(service)) is already attached to $(get_name(device))",
),
)
end
end
push!(services, service)
@debug "Add $service to $(get_name(device))" _group = IS.LOG_GROUP_SYSTEM
end
"""
Remove a service from a device.
Throws ArgumentError if the service is not attached to the device.
"""
function remove_service!(device::Device, service::Service)
if !_remove_service!(device, service)
throw(
ArgumentError(
"service $(get_name(service)) was not attached to $(get_name(device))",
),
)
end
end
"""
Return true if the service is attached to the device.
"""
function has_service(device::Device, service::Service)
for _service in get_services(device)
if IS.get_uuid(_service) == IS.get_uuid(service)
return true
end
end
return false
end
"""
Return true if a service with type T is attached to the device.
"""
function has_service(device::Device, ::Type{T}) where {T <: Service}
for _service in get_services(device)
if isa(_service, T)
return true
end
end
return false
end
"""
Remove service from device if it is attached.
"""
function _remove_service!(device::Device, service::Service)
removed = false
services = get_services(device)
# The expectation is that there won't be many services in each device, and so
# a faster lookup method is not needed.
for (i, _service) in enumerate(services)
if IS.get_uuid(_service) == IS.get_uuid(service)
deleteat!(services, i)
removed = true
@debug "Removed service $(get_name(service)) from $(get_name(device))" _group =
IS.LOG_GROUP_SYSTEM
break
end
end
return removed
end
"""
Remove all services attached to the device.
"""
function clear_services!(device::Device)
services = get_services(device)
empty!(services)
return
end