Example of the Config File#
A Config File contains a configuration of a system in a TOML-like structure.
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
[Component.Parameters]
updatableValue = 13
Message = "It's me"
Id = 42
Pi = 3.1415926
Boolean = true
Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ]
Table = { a = 77, b = 1.2, c = "das ist ein string" }
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
[Component.Parameters]
updatableValue = 13
Message = "It's me"
Id = 42
Pi = 3.1415926
Boolean = true
Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ]
Table = { a = 77, b = 1.2, c = "das ist ein string" }
A Config File must contain a version information.
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
[Component.Parameters]
updatableValue = 13
Message = "It's me"
Id = 42
Pi = 3.1415926
Boolean = true
Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ]
Table = { a = 77, b = 1.2, c = "das ist ein string" }
To load a VAPI Component the path/name to the binary file and the class name is required.
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
[Component.Parameters]
updatableValue = 13
Message = "It's me"
Id = 42
Pi = 3.1415926
Boolean = true
Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ]
Table = { a = 77, b = 1.2, c = "das ist ein string" }
The object name is optional. With that multiple VAPI Component s of the same class can be created.
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
[Component.Parameters]
updatableValue = 13
Message = "It's me"
Id = 42
Pi = 3.1415926
Boolean = true
Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ]
Table = { a = 77, b = 1.2, c = "das ist ein string" }
The component can have a parameter map. If the variable name fits the variable is directly updated and no parsing is required. Here the variable ‘updatableValue’ is updated, the other variable in the map is not touched.
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
[Component.Parameters]
updatableValue = 13
Message = "It's me"
Id = 42
Pi = 3.1415926
Boolean = true
Array = [ 1, 2, 3 , 5 , 7, 11, 13, 17 ]
Table = { a = 77, b = 1.2, c = "das ist ein string" }
The rest are user defined variables of any type including arrays and further tables. With that any data could be in the configuration file
Setting one or more folders for the modules:
sdv::app::CAppControl appcontrol;
auto bResult = appcontrol.AddModuleSearchDir("../../tests/bin");
bResult &= appcontrol.AddModuleSearchDir("../../bin"); // even more can be added
Setting one or more folders for the config files:
appcontrol.SetConfigMode();
bResult &= appcontrol.AddConfigSearchDir("ApplicationConfigFiles");
bResult &= appcontrol.AddConfigSearchDir("ServiceConfigFiles"); // even more can be added
Following shows how to parse the configuration example above.
#include <iostream>
#include <support/component_impl.h>
#include <support/toml.h>
class DemoConfigurationComponent : public sdv::CSdvObject
{
public:
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device)
DECLARE_OBJECT_CLASS_NAME("Configuration_Example")
// Parameter map
BEGIN_SDV_PARAM_MAP()
SDV_PARAM_ENABLE_LOCKING() // optional, if the parameter should be updatable
SDV_PARAM_ENTRY(m_InitializedValue, "initializedValue", 7, "km/h", "Description for an initialized parameter.")
SDV_PARAM_ENTRY(m_UpdatableValue, "updatableValue", 7, "m/s", "Description for an updatable parameter.")
END_SDV_PARAM_MAP()
/**
* @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize.
* @return Returns 'true' when the initialization was successful, 'false' when not.
*/
virtual bool OnInitialize() override
{
try
{
sdv::toml::CTOMLParser config(GetObjectConfig());
sdv::toml::CNode messageNode = config.GetDirect("Message");
if (messageNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_Message = static_cast<std::string>(messageNode.GetValue());
}
sdv::toml::CNode jsonNode = config.GetDirect("JSONConfig");
if (jsonNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_JSONConfig = static_cast<std::string>(jsonNode.GetValue());
}
sdv::toml::CNode idNode = config.GetDirect("Id");
if (idNode.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Id = static_cast<int32_t>(idNode.GetValue());
}
sdv::toml::CNode floatNode = config.GetDirect("Pi");
if (floatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
{
m_Pi = static_cast<float>(floatNode.GetValue());
}
sdv::toml::CNode boolNode = config.GetDirect("Boolean");
if (boolNode.GetType() == sdv::toml::ENodeType::node_boolean)
{
m_IsValid = static_cast<bool>(boolNode.GetValue());
}
sdv::toml::CNodeCollection arrayNodes = config.GetDirect("Array");
if (arrayNodes.GetType() == sdv::toml::ENodeType::node_array)
{
for (size_t nIndex = 0; nIndex < arrayNodes.GetCount(); nIndex++)
{
sdv::toml::CNode node = arrayNodes[nIndex];
if (node.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Counters.push_back(static_cast<uint32_t>(node.GetValue()));
}
}
}
sdv::toml::CNodeCollection tableNodes = config.GetDirect("Table");
if (tableNodes.GetType() == sdv::toml::ENodeType::node_table)
{
if (tableNodes.GetCount() >= 3)
{
m_TableA = static_cast<uint32_t>(tableNodes[0].GetValue());
m_TableB = static_cast<float>(tableNodes[1].GetValue());
m_TableC = static_cast<std::string>(tableNodes[2].GetValue());
}
}
auto table_a = config.GetDirect("Table.a");
auto table_b = config.GetDirect("Table.b");
auto table_c = config.GetDirect("Table.c");
m_DirectTableA = static_cast<uint32_t>(table_a.GetValue());
m_DirectTableB = static_cast<float>(table_b.GetValue());
m_DirectTableC = static_cast<std::string>(table_c.GetValue());
}
catch (const sdv::toml::XTOMLParseException& e)
{
SDV_LOG_ERROR("Parsing error: ", e.what());
return false;
}
PrintAllVariables();
return true;
};
/**
* @brief Shutdown the object. Overload of sdv::CSdvObject::OnShutdown.
*/
virtual void OnShutdown() override
{}
/**
* @brief Print all global variables to console
*/
void PrintAllVariables() const
{
std::cout << "\n----------\nValues from the parameter map:" << std::endl;
std::cout << "Expected 7, got " << "initialized value - not changed, not in configuration file: " << std::to_string(m_InitializedValue) << std::endl;
std::cout << "Expected 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl;
std::cout << "\n----------\nValues parsed during initialization:" << std::endl;
std::cout << "Expected 'It's me', got " << "string: " << m_Message.c_str() << std::endl;
std::cout << "multiline string: " << m_JSONConfig.c_str() << std::endl;
std::cout << "Expected 42, got " << "integer: " << std::to_string(m_Id) << std::endl;
std::cout << "Expected 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl;
std::cout << "Expected 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl;
std::cout << "Expected 77, got " << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl;
std::cout << "Expected 1.200000, got " << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl;
std::cout << "Expected 'this is a string', got " << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl;
for (auto counter : m_Counters)
{
std::cout << std::to_string(counter) << ", ";
}
std::cout << std::endl;
}
private:
std::string m_Message { "" };
std::string m_JSONConfig { "" };
int32_t m_Id { -1 };
float m_Pi { 0.0 };
bool m_IsValid { false };
std::vector<uint32_t> m_Counters{};
uint32_t m_TableA { 0 };
float m_TableB { 0.0 };
std::string m_TableC { "" };
uint32_t m_DirectTableA { 0 };
float m_DirectTableB { 0.0 };
std::string m_DirectTableC { "" };
uint32_t m_InitializedValue { 0 };
uint32_t m_UpdatableValue { 0 };
};
DEFINE_SDV_OBJECT(DemoConfigurationComponent)
#include <iostream>
#include <support/component_impl.h>
#include <support/toml.h>
class DemoConfigurationComponent : public sdv::CSdvObject
{
public:
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device)
DECLARE_OBJECT_CLASS_NAME("Configuration_Example")
// Parameter map
BEGIN_SDV_PARAM_MAP()
SDV_PARAM_ENABLE_LOCKING() // optional, if the parameter should be updatable
SDV_PARAM_ENTRY(m_InitializedValue, "initializedValue", 7, "km/h", "Description for an initialized parameter.")
SDV_PARAM_ENTRY(m_UpdatableValue, "updatableValue", 7, "m/s", "Description for an updatable parameter.")
END_SDV_PARAM_MAP()
/**
* @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize.
* @return Returns 'true' when the initialization was successful, 'false' when not.
*/
virtual bool OnInitialize() override
{
try
{
sdv::toml::CTOMLParser config(GetObjectConfig());
sdv::toml::CNode messageNode = config.GetDirect("Message");
if (messageNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_Message = static_cast<std::string>(messageNode.GetValue());
}
sdv::toml::CNode jsonNode = config.GetDirect("JSONConfig");
if (jsonNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_JSONConfig = static_cast<std::string>(jsonNode.GetValue());
}
sdv::toml::CNode idNode = config.GetDirect("Id");
if (idNode.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Id = static_cast<int32_t>(idNode.GetValue());
}
sdv::toml::CNode floatNode = config.GetDirect("Pi");
if (floatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
{
m_Pi = static_cast<float>(floatNode.GetValue());
}
sdv::toml::CNode boolNode = config.GetDirect("Boolean");
if (boolNode.GetType() == sdv::toml::ENodeType::node_boolean)
{
m_IsValid = static_cast<bool>(boolNode.GetValue());
}
sdv::toml::CNodeCollection arrayNodes = config.GetDirect("Array");
if (arrayNodes.GetType() == sdv::toml::ENodeType::node_array)
{
for (size_t nIndex = 0; nIndex < arrayNodes.GetCount(); nIndex++)
{
sdv::toml::CNode node = arrayNodes[nIndex];
if (node.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Counters.push_back(static_cast<uint32_t>(node.GetValue()));
}
}
}
sdv::toml::CNodeCollection tableNodes = config.GetDirect("Table");
if (tableNodes.GetType() == sdv::toml::ENodeType::node_table)
{
if (tableNodes.GetCount() >= 3)
{
m_TableA = static_cast<uint32_t>(tableNodes[0].GetValue());
m_TableB = static_cast<float>(tableNodes[1].GetValue());
m_TableC = static_cast<std::string>(tableNodes[2].GetValue());
}
}
auto table_a = config.GetDirect("Table.a");
auto table_b = config.GetDirect("Table.b");
auto table_c = config.GetDirect("Table.c");
m_DirectTableA = static_cast<uint32_t>(table_a.GetValue());
m_DirectTableB = static_cast<float>(table_b.GetValue());
m_DirectTableC = static_cast<std::string>(table_c.GetValue());
}
catch (const sdv::toml::XTOMLParseException& e)
{
SDV_LOG_ERROR("Parsing error: ", e.what());
return false;
}
PrintAllVariables();
return true;
};
/**
* @brief Shutdown the object. Overload of sdv::CSdvObject::OnShutdown.
*/
virtual void OnShutdown() override
{}
/**
* @brief Print all global variables to console
*/
void PrintAllVariables() const
{
std::cout << "\n----------\nValues from the parameter map:" << std::endl;
std::cout << "Expected 7, got " << "initialized value - not changed, not in configuration file: " << std::to_string(m_InitializedValue) << std::endl;
std::cout << "Expected 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl;
std::cout << "\n----------\nValues parsed during initialization:" << std::endl;
std::cout << "Expected 'It's me', got " << "string: " << m_Message.c_str() << std::endl;
std::cout << "multiline string: " << m_JSONConfig.c_str() << std::endl;
std::cout << "Expected 42, got " << "integer: " << std::to_string(m_Id) << std::endl;
std::cout << "Expected 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl;
std::cout << "Expected 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl;
std::cout << "Expected 77, got " << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl;
std::cout << "Expected 1.200000, got " << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl;
std::cout << "Expected 'this is a string', got " << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl;
for (auto counter : m_Counters)
{
std::cout << std::to_string(counter) << ", ";
}
std::cout << std::endl;
}
private:
std::string m_Message { "" };
std::string m_JSONConfig { "" };
int32_t m_Id { -1 };
float m_Pi { 0.0 };
bool m_IsValid { false };
std::vector<uint32_t> m_Counters{};
uint32_t m_TableA { 0 };
float m_TableB { 0.0 };
std::string m_TableC { "" };
uint32_t m_DirectTableA { 0 };
float m_DirectTableB { 0.0 };
std::string m_DirectTableC { "" };
uint32_t m_InitializedValue { 0 };
uint32_t m_UpdatableValue { 0 };
};
DEFINE_SDV_OBJECT(DemoConfigurationComponent)
With a parameter map variables can already be defined. If allowed, then these variables can be automatically be updated, no parsing of the configuration file necessary.
#include <iostream>
#include <support/component_impl.h>
#include <support/toml.h>
class DemoConfigurationComponent : public sdv::CSdvObject
{
public:
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device)
DECLARE_OBJECT_CLASS_NAME("Configuration_Example")
// Parameter map
BEGIN_SDV_PARAM_MAP()
SDV_PARAM_ENABLE_LOCKING() // optional, if the parameter should be updatable
SDV_PARAM_ENTRY(m_InitializedValue, "initializedValue", 7, "km/h", "Description for an initialized parameter.")
SDV_PARAM_ENTRY(m_UpdatableValue, "updatableValue", 7, "m/s", "Description for an updatable parameter.")
END_SDV_PARAM_MAP()
/**
* @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize.
* @return Returns 'true' when the initialization was successful, 'false' when not.
*/
virtual bool OnInitialize() override
{
try
{
sdv::toml::CTOMLParser config(GetObjectConfig());
sdv::toml::CNode messageNode = config.GetDirect("Message");
if (messageNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_Message = static_cast<std::string>(messageNode.GetValue());
}
sdv::toml::CNode jsonNode = config.GetDirect("JSONConfig");
if (jsonNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_JSONConfig = static_cast<std::string>(jsonNode.GetValue());
}
sdv::toml::CNode idNode = config.GetDirect("Id");
if (idNode.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Id = static_cast<int32_t>(idNode.GetValue());
}
sdv::toml::CNode floatNode = config.GetDirect("Pi");
if (floatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
{
m_Pi = static_cast<float>(floatNode.GetValue());
}
sdv::toml::CNode boolNode = config.GetDirect("Boolean");
if (boolNode.GetType() == sdv::toml::ENodeType::node_boolean)
{
m_IsValid = static_cast<bool>(boolNode.GetValue());
}
sdv::toml::CNodeCollection arrayNodes = config.GetDirect("Array");
if (arrayNodes.GetType() == sdv::toml::ENodeType::node_array)
{
for (size_t nIndex = 0; nIndex < arrayNodes.GetCount(); nIndex++)
{
sdv::toml::CNode node = arrayNodes[nIndex];
if (node.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Counters.push_back(static_cast<uint32_t>(node.GetValue()));
}
}
}
sdv::toml::CNodeCollection tableNodes = config.GetDirect("Table");
if (tableNodes.GetType() == sdv::toml::ENodeType::node_table)
{
if (tableNodes.GetCount() >= 3)
{
m_TableA = static_cast<uint32_t>(tableNodes[0].GetValue());
m_TableB = static_cast<float>(tableNodes[1].GetValue());
m_TableC = static_cast<std::string>(tableNodes[2].GetValue());
}
}
auto table_a = config.GetDirect("Table.a");
auto table_b = config.GetDirect("Table.b");
auto table_c = config.GetDirect("Table.c");
m_DirectTableA = static_cast<uint32_t>(table_a.GetValue());
m_DirectTableB = static_cast<float>(table_b.GetValue());
m_DirectTableC = static_cast<std::string>(table_c.GetValue());
}
catch (const sdv::toml::XTOMLParseException& e)
{
SDV_LOG_ERROR("Parsing error: ", e.what());
return false;
}
PrintAllVariables();
return true;
};
/**
* @brief Shutdown the object. Overload of sdv::CSdvObject::OnShutdown.
*/
virtual void OnShutdown() override
{}
/**
* @brief Print all global variables to console
*/
void PrintAllVariables() const
{
std::cout << "\n----------\nValues from the parameter map:" << std::endl;
std::cout << "Expected 7, got " << "initialized value - not changed, not in configuration file: " << std::to_string(m_InitializedValue) << std::endl;
std::cout << "Expected 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl;
std::cout << "\n----------\nValues parsed during initialization:" << std::endl;
std::cout << "Expected 'It's me', got " << "string: " << m_Message.c_str() << std::endl;
std::cout << "multiline string: " << m_JSONConfig.c_str() << std::endl;
std::cout << "Expected 42, got " << "integer: " << std::to_string(m_Id) << std::endl;
std::cout << "Expected 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl;
std::cout << "Expected 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl;
std::cout << "Expected 77, got " << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl;
std::cout << "Expected 1.200000, got " << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl;
std::cout << "Expected 'this is a string', got " << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl;
for (auto counter : m_Counters)
{
std::cout << std::to_string(counter) << ", ";
}
std::cout << std::endl;
}
private:
std::string m_Message { "" };
std::string m_JSONConfig { "" };
int32_t m_Id { -1 };
float m_Pi { 0.0 };
bool m_IsValid { false };
std::vector<uint32_t> m_Counters{};
uint32_t m_TableA { 0 };
float m_TableB { 0.0 };
std::string m_TableC { "" };
uint32_t m_DirectTableA { 0 };
float m_DirectTableB { 0.0 };
std::string m_DirectTableC { "" };
uint32_t m_InitializedValue { 0 };
uint32_t m_UpdatableValue { 0 };
};
DEFINE_SDV_OBJECT(DemoConfigurationComponent)
The access to the variables is very easy with the sdv::toml::CTOMLParser. Just get direct access, validate the data type and get the value.
#include <iostream>
#include <support/component_impl.h>
#include <support/toml.h>
class DemoConfigurationComponent : public sdv::CSdvObject
{
public:
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device)
DECLARE_OBJECT_CLASS_NAME("Configuration_Example")
// Parameter map
BEGIN_SDV_PARAM_MAP()
SDV_PARAM_ENABLE_LOCKING() // optional, if the parameter should be updatable
SDV_PARAM_ENTRY(m_InitializedValue, "initializedValue", 7, "km/h", "Description for an initialized parameter.")
SDV_PARAM_ENTRY(m_UpdatableValue, "updatableValue", 7, "m/s", "Description for an updatable parameter.")
END_SDV_PARAM_MAP()
/**
* @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize.
* @return Returns 'true' when the initialization was successful, 'false' when not.
*/
virtual bool OnInitialize() override
{
try
{
sdv::toml::CTOMLParser config(GetObjectConfig());
sdv::toml::CNode messageNode = config.GetDirect("Message");
if (messageNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_Message = static_cast<std::string>(messageNode.GetValue());
}
sdv::toml::CNode jsonNode = config.GetDirect("JSONConfig");
if (jsonNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_JSONConfig = static_cast<std::string>(jsonNode.GetValue());
}
sdv::toml::CNode idNode = config.GetDirect("Id");
if (idNode.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Id = static_cast<int32_t>(idNode.GetValue());
}
sdv::toml::CNode floatNode = config.GetDirect("Pi");
if (floatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
{
m_Pi = static_cast<float>(floatNode.GetValue());
}
sdv::toml::CNode boolNode = config.GetDirect("Boolean");
if (boolNode.GetType() == sdv::toml::ENodeType::node_boolean)
{
m_IsValid = static_cast<bool>(boolNode.GetValue());
}
sdv::toml::CNodeCollection arrayNodes = config.GetDirect("Array");
if (arrayNodes.GetType() == sdv::toml::ENodeType::node_array)
{
for (size_t nIndex = 0; nIndex < arrayNodes.GetCount(); nIndex++)
{
sdv::toml::CNode node = arrayNodes[nIndex];
if (node.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Counters.push_back(static_cast<uint32_t>(node.GetValue()));
}
}
}
sdv::toml::CNodeCollection tableNodes = config.GetDirect("Table");
if (tableNodes.GetType() == sdv::toml::ENodeType::node_table)
{
if (tableNodes.GetCount() >= 3)
{
m_TableA = static_cast<uint32_t>(tableNodes[0].GetValue());
m_TableB = static_cast<float>(tableNodes[1].GetValue());
m_TableC = static_cast<std::string>(tableNodes[2].GetValue());
}
}
auto table_a = config.GetDirect("Table.a");
auto table_b = config.GetDirect("Table.b");
auto table_c = config.GetDirect("Table.c");
m_DirectTableA = static_cast<uint32_t>(table_a.GetValue());
m_DirectTableB = static_cast<float>(table_b.GetValue());
m_DirectTableC = static_cast<std::string>(table_c.GetValue());
}
catch (const sdv::toml::XTOMLParseException& e)
{
SDV_LOG_ERROR("Parsing error: ", e.what());
return false;
}
PrintAllVariables();
return true;
};
/**
* @brief Shutdown the object. Overload of sdv::CSdvObject::OnShutdown.
*/
virtual void OnShutdown() override
{}
/**
* @brief Print all global variables to console
*/
void PrintAllVariables() const
{
std::cout << "\n----------\nValues from the parameter map:" << std::endl;
std::cout << "Expected 7, got " << "initialized value - not changed, not in configuration file: " << std::to_string(m_InitializedValue) << std::endl;
std::cout << "Expected 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl;
std::cout << "\n----------\nValues parsed during initialization:" << std::endl;
std::cout << "Expected 'It's me', got " << "string: " << m_Message.c_str() << std::endl;
std::cout << "multiline string: " << m_JSONConfig.c_str() << std::endl;
std::cout << "Expected 42, got " << "integer: " << std::to_string(m_Id) << std::endl;
std::cout << "Expected 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl;
std::cout << "Expected 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl;
std::cout << "Expected 77, got " << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl;
std::cout << "Expected 1.200000, got " << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl;
std::cout << "Expected 'this is a string', got " << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl;
for (auto counter : m_Counters)
{
std::cout << std::to_string(counter) << ", ";
}
std::cout << std::endl;
}
private:
std::string m_Message { "" };
std::string m_JSONConfig { "" };
int32_t m_Id { -1 };
float m_Pi { 0.0 };
bool m_IsValid { false };
std::vector<uint32_t> m_Counters{};
uint32_t m_TableA { 0 };
float m_TableB { 0.0 };
std::string m_TableC { "" };
uint32_t m_DirectTableA { 0 };
float m_DirectTableB { 0.0 };
std::string m_DirectTableC { "" };
uint32_t m_InitializedValue { 0 };
uint32_t m_UpdatableValue { 0 };
};
DEFINE_SDV_OBJECT(DemoConfigurationComponent)
The configuration can include very complex data including tables. It’s not required to get from top to down, a direct access is also possible.
#include <iostream>
#include <support/component_impl.h>
#include <support/toml.h>
class DemoConfigurationComponent : public sdv::CSdvObject
{
public:
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::device)
DECLARE_OBJECT_CLASS_NAME("Configuration_Example")
// Parameter map
BEGIN_SDV_PARAM_MAP()
SDV_PARAM_ENABLE_LOCKING() // optional, if the parameter should be updatable
SDV_PARAM_ENTRY(m_InitializedValue, "initializedValue", 7, "km/h", "Description for an initialized parameter.")
SDV_PARAM_ENTRY(m_UpdatableValue, "updatableValue", 7, "m/s", "Description for an updatable parameter.")
END_SDV_PARAM_MAP()
/**
* @brief Initialization event, called after object configuration was loaded. Overload of sdv::CSdvObject::OnInitialize.
* @return Returns 'true' when the initialization was successful, 'false' when not.
*/
virtual bool OnInitialize() override
{
try
{
sdv::toml::CTOMLParser config(GetObjectConfig());
sdv::toml::CNode messageNode = config.GetDirect("Message");
if (messageNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_Message = static_cast<std::string>(messageNode.GetValue());
}
sdv::toml::CNode jsonNode = config.GetDirect("JSONConfig");
if (jsonNode.GetType() == sdv::toml::ENodeType::node_string)
{
m_JSONConfig = static_cast<std::string>(jsonNode.GetValue());
}
sdv::toml::CNode idNode = config.GetDirect("Id");
if (idNode.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Id = static_cast<int32_t>(idNode.GetValue());
}
sdv::toml::CNode floatNode = config.GetDirect("Pi");
if (floatNode.GetType() == sdv::toml::ENodeType::node_floating_point)
{
m_Pi = static_cast<float>(floatNode.GetValue());
}
sdv::toml::CNode boolNode = config.GetDirect("Boolean");
if (boolNode.GetType() == sdv::toml::ENodeType::node_boolean)
{
m_IsValid = static_cast<bool>(boolNode.GetValue());
}
sdv::toml::CNodeCollection arrayNodes = config.GetDirect("Array");
if (arrayNodes.GetType() == sdv::toml::ENodeType::node_array)
{
for (size_t nIndex = 0; nIndex < arrayNodes.GetCount(); nIndex++)
{
sdv::toml::CNode node = arrayNodes[nIndex];
if (node.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Counters.push_back(static_cast<uint32_t>(node.GetValue()));
}
}
}
sdv::toml::CNodeCollection tableNodes = config.GetDirect("Table");
if (tableNodes.GetType() == sdv::toml::ENodeType::node_table)
{
if (tableNodes.GetCount() >= 3)
{
m_TableA = static_cast<uint32_t>(tableNodes[0].GetValue());
m_TableB = static_cast<float>(tableNodes[1].GetValue());
m_TableC = static_cast<std::string>(tableNodes[2].GetValue());
}
}
auto table_a = config.GetDirect("Table.a");
auto table_b = config.GetDirect("Table.b");
auto table_c = config.GetDirect("Table.c");
m_DirectTableA = static_cast<uint32_t>(table_a.GetValue());
m_DirectTableB = static_cast<float>(table_b.GetValue());
m_DirectTableC = static_cast<std::string>(table_c.GetValue());
}
catch (const sdv::toml::XTOMLParseException& e)
{
SDV_LOG_ERROR("Parsing error: ", e.what());
return false;
}
PrintAllVariables();
return true;
};
/**
* @brief Shutdown the object. Overload of sdv::CSdvObject::OnShutdown.
*/
virtual void OnShutdown() override
{}
/**
* @brief Print all global variables to console
*/
void PrintAllVariables() const
{
std::cout << "\n----------\nValues from the parameter map:" << std::endl;
std::cout << "Expected 7, got " << "initialized value - not changed, not in configuration file: " << std::to_string(m_InitializedValue) << std::endl;
std::cout << "Expected 13, got " << "updated value - changed, found in configuration file: " << std::to_string(m_UpdatableValue) << std::endl;
std::cout << "\n----------\nValues parsed during initialization:" << std::endl;
std::cout << "Expected 'It's me', got " << "string: " << m_Message.c_str() << std::endl;
std::cout << "multiline string: " << m_JSONConfig.c_str() << std::endl;
std::cout << "Expected 42, got " << "integer: " << std::to_string(m_Id) << std::endl;
std::cout << "Expected 3.141593, got " << "float: " << std::to_string(m_Pi) << std::endl;
std::cout << "Expected 1, got " << "bool: " << std::to_string(m_IsValid) << std::endl;
std::cout << "Expected 77, got " << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl;
std::cout << "Expected 1.200000, got " << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl;
std::cout << "Expected 'this is a string', got " << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl;
for (auto counter : m_Counters)
{
std::cout << std::to_string(counter) << ", ";
}
std::cout << std::endl;
}
private:
std::string m_Message { "" };
std::string m_JSONConfig { "" };
int32_t m_Id { -1 };
float m_Pi { 0.0 };
bool m_IsValid { false };
std::vector<uint32_t> m_Counters{};
uint32_t m_TableA { 0 };
float m_TableB { 0.0 };
std::string m_TableC { "" };
uint32_t m_DirectTableA { 0 };
float m_DirectTableB { 0.0 };
std::string m_DirectTableC { "" };
uint32_t m_InitializedValue { 0 };
uint32_t m_UpdatableValue { 0 };
};
DEFINE_SDV_OBJECT(DemoConfigurationComponent)
These are the variables required for the parsing of the example. The example can be found in the code examples.