Skip to content

Commit 3d35ee2

Browse files
authored
serial interface: connect protocol with actual data (#130)
Resolves #119
2 parents 4bf500a + 7105d07 commit 3d35ee2

File tree

4 files changed

+85
-16
lines changed

4 files changed

+85
-16
lines changed

lib/3rd_party_adapters/nlohmann/JsonGenerator.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <serial_protocol/ProtocolVersionObject.hpp>
55
#include <serial_protocol/TaskList.hpp>
66
#include <serial_protocol/TaskObject.hpp>
7+
#include <tasks/Task.hpp>
78

89
/**
910
* Indentation used by default for formating JSON.
@@ -38,10 +39,17 @@ std::string toJsonString<task_tracker_systems::TaskObject>(const task_tracker_sy
3839
return jsonObject.dump(defaultJsonIndent);
3940
}
4041

42+
void to_json(nlohmann::json &jsonObject, const device::TaskCollection::value_type &object)
43+
{
44+
jsonObject["id"] = object.first;
45+
jsonObject["label"] = object.second.getLabel();
46+
jsonObject["duration"] = object.second.getLastRecordedDuration().count();
47+
}
48+
4149
template <>
42-
std::string toJsonString<task_tracker_systems::TaskList>(const task_tracker_systems::TaskList &object)
50+
std::string toJsonString<device::TaskCollection>(const device::TaskCollection &container)
4351
{
44-
nlohmann::json jsonObject(object);
52+
nlohmann::json jsonObject(container);
4553
return jsonObject.dump(defaultJsonIndent);
4654
}
4755

lib/application_business_rules/serial_interface/Protocol.cpp

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ namespace cli = command_line_interpreter;
99
// --- define commands ------
1010
// --------------------------
1111
#include "JsonGenerator.hpp"
12+
#include <serial_protocol/DeletedTaskObject.hpp>
1213
#include <serial_protocol/ProtocolVersionObject.hpp>
1314
#include <serial_protocol/TaskList.hpp>
1415
#include <serial_protocol/TaskObject.hpp>
1516
#include <string>
17+
#include <tasks/Task.hpp>
1618

1719
using namespace task_tracker_systems;
1820

@@ -24,25 +26,62 @@ static const auto info = []() {
2426
static const auto infoCmd = cli::makeCommand("info", std::function(info));
2527

2628
// command for list
27-
static const auto list = []() {
28-
const TaskList dummyList = {
29-
{.id = 1, .label = "first", .duration = 100U},
30-
{.id = 2, .label = "second", .duration = 200U},
31-
};
32-
serial_port::cout << toJsonString(dummyList) << std::endl; };
29+
static const auto list = []() { serial_port::cout << toJsonString(device::tasks) << std::endl; };
3330
static const auto listCmd = cli::makeCommand("list", std::function(list));
3431

3532
// command for edit
36-
static const auto edit = [](const unsigned int id, const std::basic_string<ProtocolHandler::CharType> label, const std::chrono::seconds::rep duration) {
37-
const TaskObject task = {.id = id, .label = label, .duration = duration};
38-
serial_port::cout << toJsonString(task) << std::endl;
33+
static const auto edit = [](const TaskId id, const std::basic_string<ProtocolHandler::CharType> label, const Task::Duration::rep duration) {
34+
try
35+
{
36+
auto &task = device::tasks.at(id);
37+
task.setLabel(label);
38+
task.setRecordedDuration(std::chrono::seconds(duration));
39+
const TaskObject taskObject = {.id = id, .label = task.getLabel(), .duration = task.getLastRecordedDuration().count()};
40+
serial_port::cout << toJsonString(taskObject) << std::endl;
41+
}
42+
catch (std::out_of_range &e)
43+
{
44+
serial_port::cout << "ERROR: Task not found." << std::endl;
45+
}
3946
};
40-
static const cli::Option<unsigned int> id = {.labels = {"--id"}, .defaultValue = 0};
47+
static const cli::Option<TaskId> id = {.labels = {"--id"}, .defaultValue = 0};
4148
static const cli::Option<std::basic_string<ProtocolHandler::CharType>> label = {.labels = {"--name"}, .defaultValue = "foo"};
42-
static const cli::Option<std::chrono::seconds::rep> duration = {.labels = {"--duration"}, .defaultValue = 0};
49+
static const cli::Option<Task::Duration::rep> duration = {.labels = {"--duration"}, .defaultValue = 0};
4350
static const auto editCmd = cli::makeCommand("edit", std::function(edit), std::make_tuple(&id, &label, &duration));
4451

45-
static const std::array<const cli::BaseCommand<char> *, 3> commands = {&listCmd, &editCmd, &infoCmd};
52+
// command for create/add
53+
static const auto add = [](const TaskId id, const std::basic_string<ProtocolHandler::CharType> label, const Task::Duration::rep duration) {
54+
try
55+
{
56+
const auto &[element, created] = device::tasks.try_emplace(id, label, std::chrono::seconds(duration));
57+
const auto &task = element->second;
58+
const TaskObject taskObject = {.id = element->first, .label = task.getLabel(), .duration = task.getLastRecordedDuration().count()};
59+
serial_port::cout << toJsonString(taskObject) << std::endl;
60+
if (!created)
61+
{
62+
serial_port::cout << "ERROR: Task with the specified ID already exists." << std::endl;
63+
}
64+
}
65+
catch (std::out_of_range &e)
66+
{
67+
serial_port::cout << "ERROR: Task not found." << std::endl;
68+
}
69+
};
70+
static const auto addCmd = cli::makeCommand("add", std::function(add), std::make_tuple(&id, &label, &duration));
71+
72+
// command for delete/remove
73+
static const auto del = [](const TaskId id) {
74+
const bool deleted = device::tasks.erase(id) > 0;
75+
const DeletedTaskObject taskObject{.id = id};
76+
serial_port::cout << toJsonString(taskObject) << std::endl;
77+
if (!deleted)
78+
{
79+
serial_port::cout << "ERROR: No task deleted." << std::endl;
80+
}
81+
};
82+
static const auto delCmd = cli::makeCommand("delete", std::function(del), std::make_tuple(&id));
83+
84+
static const std::array<const cli::BaseCommand<char> *, 5> commands = {&listCmd, &editCmd, &infoCmd, &addCmd, &delCmd};
4685

4786
bool ProtocolHandler::execute(const CharType *const commandLine)
4887
{

lib/application_business_rules/tasks/Task.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,14 @@ Task::Duration Task::getRecordedDuration()
4747
return std::chrono::round<Duration>(recordedDuration);
4848
}
4949

50-
std::map<TaskId, Task> device::tasks;
50+
device::TaskCollection device::tasks;
51+
52+
void Task::setRecordedDuration(Duration newDuration)
53+
{
54+
recordedDuration = newDuration;
55+
}
56+
57+
Task::Duration Task::getLastRecordedDuration() const
58+
{
59+
return std::chrono::round<Duration>(recordedDuration);
60+
}

lib/application_business_rules/tasks/Task.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ class Task
6565
* \returns the accumulated duration
6666
*/
6767
Duration getRecordedDuration();
68+
69+
Duration getLastRecordedDuration() const;
70+
71+
/**
72+
* Sets the recorded duration.
73+
*
74+
* Useful for example if the task has been recorded outside the device.
75+
* @param newDuration new duration to apply
76+
*/
77+
void setRecordedDuration(Duration newDuration);
6878
bool isRunning() const;
6979

7080
private:
@@ -87,8 +97,10 @@ class Task
8797

8898
namespace device
8999
{
100+
typedef std::map<TaskId, Task> TaskCollection;
101+
90102
/**
91103
* *The* collection of tasks to be used by the device application.
92104
*/
93-
extern std::map<TaskId, Task> tasks;
105+
extern TaskCollection tasks;
94106
} // namespace device

0 commit comments

Comments
 (0)