-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathisobus_virtual_terminal_client_update_helper.cpp
175 lines (156 loc) · 5.47 KB
/
isobus_virtual_terminal_client_update_helper.cpp
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//================================================================================================
/// @file isobus_virtual_terminal_client_update_helper.cpp
///
/// @brief A helper class to update and track the state of an active working set.
/// @author Daan Steenbergen
///
/// @copyright 2023 The Open-Agriculture Developers
//================================================================================================
#include "isobus_virtual_terminal_client_update_helper.hpp"
#include "can_stack_logger.hpp"
namespace isobus
{
VirtualTerminalClientUpdateHelper::VirtualTerminalClientUpdateHelper(std::shared_ptr<VirtualTerminalClient> client) :
VirtualTerminalClientStateTracker(nullptr == client ? nullptr : client->get_internal_control_function()),
vtClient(client)
{
if (nullptr == client)
{
LOG_ERROR("[VTStateHelper] constructor: client is nullptr");
return;
}
numericValueChangeEventHandle = client->get_vt_change_numeric_value_event_dispatcher().add_listener(
std::bind(&VirtualTerminalClientUpdateHelper::process_numeric_value_change_event, this, std::placeholders::_1));
}
VirtualTerminalClientUpdateHelper::~VirtualTerminalClientUpdateHelper()
{
if (nullptr != vtClient)
{
vtClient->get_vt_change_numeric_value_event_dispatcher().remove_listener(numericValueChangeEventHandle);
}
}
bool VirtualTerminalClientUpdateHelper::set_numeric_value(std::uint16_t object_id, std::uint32_t value)
{
if (nullptr == client)
{
LOG_ERROR("[VTStateHelper] set_numeric_value: client is nullptr");
return false;
}
if (numericValueStates.find(object_id) == numericValueStates.end())
{
LOG_WARNING("[VTStateHelper] set_numeric_value: objectId %lu not tracked", object_id);
return false;
}
if (numericValueStates.at(object_id) == value)
{
return true;
}
bool success = vtClient->send_change_numeric_value(object_id, value);
if (success)
{
numericValueStates[object_id] = value;
}
return success;
}
bool VirtualTerminalClientUpdateHelper::increase_numeric_value(std::uint16_t object_id, std::uint32_t step)
{
return set_numeric_value(object_id, get_numeric_value(object_id) + step);
}
bool VirtualTerminalClientUpdateHelper::decrease_numeric_value(std::uint16_t object_id, std::uint32_t step)
{
return set_numeric_value(object_id, get_numeric_value(object_id) - step);
}
void VirtualTerminalClientUpdateHelper::set_callback_validate_numeric_value(const std::function<bool(std::uint16_t, std::uint32_t)> &callback)
{
callbackValidateNumericValue = callback;
}
void VirtualTerminalClientUpdateHelper::process_numeric_value_change_event(const VirtualTerminalClient::VTChangeNumericValueEvent &event)
{
if (numericValueStates.find(event.objectID) == numericValueStates.end())
{
// Only proccess numeric value changes for tracked objects.
return;
}
if (numericValueStates.at(event.objectID) == event.value)
{
// Do not process the event if the value has not changed.
return;
}
std::uint32_t targetValue = event.value; // Default to the value received in the event.
if ((callbackValidateNumericValue != nullptr) && callbackValidateNumericValue(event.objectID, event.value))
{
// If the callback function returns false, reject the change by sending the previous value.
targetValue = numericValueStates.at(event.objectID);
}
vtClient->send_change_numeric_value(event.objectID, targetValue);
}
bool VirtualTerminalClientUpdateHelper::set_active_data_or_alarm_mask(std::uint16_t workingSetId, std::uint16_t dataOrAlarmMaskId)
{
if (nullptr == client)
{
LOG_ERROR("[VTStateHelper] set_active_data_or_alarm_mask: client is nullptr");
return false;
}
if (activeDataOrAlarmMask == dataOrAlarmMaskId)
{
return true;
}
bool success = vtClient->send_change_active_mask(workingSetId, dataOrAlarmMaskId);
if (success)
{
activeDataOrAlarmMask = dataOrAlarmMaskId;
}
return success;
}
bool VirtualTerminalClientUpdateHelper::set_active_soft_key_mask(VirtualTerminalClient::MaskType maskType, std::uint16_t maskId, std::uint16_t softKeyMaskId)
{
if (nullptr == client)
{
LOG_ERROR("[VTStateHelper] set_active_soft_key_mask: client is nullptr");
return false;
}
if (softKeyMasks.find(maskId) == softKeyMasks.end())
{
LOG_WARNING("[VTStateHelper] set_active_soft_key_mask: data/alarm mask '%lu' not tracked", maskId);
return false;
}
if (softKeyMasks.at(maskId) == softKeyMaskId)
{
return true;
}
bool success = vtClient->send_change_softkey_mask(maskType, maskId, softKeyMaskId);
if (success)
{
softKeyMasks[maskId] = softKeyMaskId;
}
return success;
}
bool VirtualTerminalClientUpdateHelper::set_attribute(std::uint16_t objectId, std::uint8_t attribute, std::uint32_t value)
{
if (nullptr == client)
{
LOG_ERROR("[VTStateHelper] set_attribute: client is nullptr");
return false;
}
if (attributeStates.find(objectId) == attributeStates.end())
{
LOG_ERROR("[VTStateHelper] set_attribute: objectId %lu not tracked", objectId);
return false;
}
if (attributeStates.at(objectId).find(attribute) == attributeStates.at(objectId).end())
{
LOG_WARNING("[VTStateHelper] set_attribute: attribute %lu of objectId %lu not tracked", attribute, objectId);
return false;
}
if (attributeStates.at(objectId).at(attribute) == value)
{
return true;
}
bool success = vtClient->send_change_attribute(objectId, attribute, value);
if (success)
{
attributeStates[objectId][attribute] = value;
}
return success;
}
} // namespace isobus