Precommit (#1)

* first commit

* cleanup
This commit is contained in:
tompzf
2025-11-04 13:28:06 +01:00
committed by GitHub
parent dba45dc636
commit 6ed4b1534e
898 changed files with 256340 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
project(HowToExamples)
# Use new policy for project version settings and default warning level
cmake_policy(SET CMP0048 NEW) # requires CMake 3.14
cmake_policy(SET CMP0092 NEW) # requires CMake 3.15
# Use C++17 support
set(CMAKE_CXX_STANDARD 17)
# Libary symbols are hidden by default
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
# Include link to export directory of SDV V-API development include files location
include_directories(${SDV_FRAMEWORK_DEV_INCLUDE})
add_library(example_vehicle_device SHARED source/example_vehicle_device.cpp)
set_target_properties(example_vehicle_device PROPERTIES PREFIX "")
set_target_properties(example_vehicle_device PROPERTIES SUFFIX ".sdv")
add_library(example_basic_service SHARED source/example_basic_service.cpp)
set_target_properties(example_basic_service PROPERTIES PREFIX "")
set_target_properties(example_basic_service PROPERTIES SUFFIX ".sdv")
add_library(example_access_to_other_components SHARED source/example_access_to_other_components.cpp)
set_target_properties(example_access_to_other_components PROPERTIES PREFIX "")
set_target_properties(example_access_to_other_components PROPERTIES SUFFIX ".sdv")
add_library(example_general_component SHARED source/example_general_component.cpp)
set_target_properties(example_general_component PROPERTIES PREFIX "")
set_target_properties(example_general_component PROPERTIES SUFFIX ".sdv")
add_library(example_general_component_with_initialization SHARED source/example_general_component_with_initialization.cpp)
set_target_properties(example_general_component_with_initialization PROPERTIES PREFIX "")
set_target_properties(example_general_component_with_initialization PROPERTIES SUFFIX ".sdv")
add_library(example_dispatch_service SHARED source/example_dispatch_service.cpp)
set_target_properties(example_dispatch_service PROPERTIES PREFIX "")
set_target_properties(example_dispatch_service PROPERTIES SUFFIX ".sdv")
add_library(example_complex_service SHARED source/example_complex_service.cpp)
set_target_properties(example_complex_service PROPERTIES PREFIX "")
set_target_properties(example_complex_service PROPERTIES SUFFIX ".sdv")
#---------------------------------------
# Verify all HowTo examples
#---------------------------------------
add_executable(example_run_all_components "source/run_all_examples.cpp")
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (WIN32)
target_link_libraries(example_run_all_components Ws2_32 Winmm Rpcrt4.lib)
else()
target_link_libraries(example_run_all_components ${CMAKE_DL_LIBS} rt ${CMAKE_THREAD_LIBS_INIT})
endif()
else()
target_link_libraries(example_run_all_components Rpcrt4.lib)
endif()
# Copy the config files for the application example
file (COPY ${PROJECT_SOURCE_DIR}/source/docu_dispatch.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
file (COPY ${PROJECT_SOURCE_DIR}/source/docu_examples.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
file (COPY ${PROJECT_SOURCE_DIR}/source/docu_app_examples.toml DESTINATION ${CMAKE_BINARY_DIR}/bin/config)
#---------------------------------
# Application examples
#---------------------------------
add_executable(example_application source/example_application.cpp)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (WIN32)
target_link_libraries(example_application Ws2_32 Winmm Rpcrt4.lib)
else()
target_link_libraries(example_application ${CMAKE_DL_LIBS} rt ${CMAKE_THREAD_LIBS_INIT})
endif()
else()
target_link_libraries(example_application Rpcrt4.lib)
endif()
add_dependencies(example_run_all_components example_vehicle_device example_complex_service
example_dispatch_service example_general_component
example_access_to_other_components example_basic_service
example_general_component_with_initialization)
add_dependencies(example_application example_general_component example_access_to_other_components)

View File

@@ -0,0 +1,13 @@
[Configuration]
Version = 100
[[Component]]
Path = "module_example.sdv"
Class = "class_example"
Name = "object_name_example"
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" }

View File

@@ -0,0 +1,170 @@
#include <iostream>
#include <support/component_impl.h>
#include <support/toml.h>
class DemoConfigurationComponent : public sdv::CSdvObject, public sdv::IObjectControl
{
public:
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
DECLARE_OBJECT_CLASS_NAME("Configuration_Example")
/**
* @brief initialize function to register, access the task timer interface from platform abstraction.
* After initialization 'CreateTimer' function is called to execute the task periodically.
* @param[in] rssObjectConfig An object configuration is currently not used by this demo component.
*/
virtual void Initialize([[maybe_unused]] const sdv::u8string& rssObjectConfig) override
{
try
{
sdv::toml::CTOMLParser config(rssObjectConfig.c_str());
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 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());
m_status = sdv::EObjectStatus::initialization_failure;
return;
}
PrintAllVariables();
m_status = sdv::EObjectStatus::initialized;
};
/**
* @brief Gets the current status of the object
* @return EObjectStatus The current status of the object
*/
virtual sdv::EObjectStatus GetStatus() const override
{
return m_status;
};
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(/*in*/ sdv::EOperationMode eMode)
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_status == sdv::EObjectStatus::running || m_status == sdv::EObjectStatus::initialized)
m_status = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_status == sdv::EObjectStatus::configuring || m_status == sdv::EObjectStatus::initialized)
m_status = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Shutdown function is to shutdown the execution of periodic task.
* Timer ID of the task is used to shutdown the specific task.
*/
virtual void Shutdown() override
{
m_status = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Print all global variables to console
*/
void PrintAllVariables()
{
std::cout << "\nValues parsed during initialization:\n" << std::endl;
std::cout << "string: " << m_Message.c_str() << std::endl;
std::cout << "integer: " << std::to_string(m_Id) << std::endl;
std::cout << "float: " << std::to_string(m_Pi) << std::endl;
std::cout << "bool: " << std::to_string(m_IsValid) << std::endl;
std::cout << "table column a: " << std::to_string(m_TableA) << " " << std::to_string(m_DirectTableA) << std::endl;
std::cout << "table column b: " << std::to_string(m_TableB) << " " << std::to_string(m_DirectTableB) << std::endl;
std::cout << "table column c: " << m_TableC.c_str() << " " << m_DirectTableC.c_str() << std::endl;
std::cout << "array: ";
for (auto counter : m_Counters)
{
std::cout << std::to_string(counter) << ", ";
}
std::cout << std::endl;
}
private:
std::atomic<sdv::EObjectStatus> m_status = {sdv::EObjectStatus::initialization_pending}; //!< To update the object status when it changes.
std::string m_Message = "";
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 = "";
};
DEFINE_SDV_OBJECT(DemoConfigurationComponent)

View File

@@ -0,0 +1,12 @@
[Configuration]
Version = 100
[[Component]]
Path = "example_general_component.sdv"
Class = "Hello_Component"
[[Component]]
Path = "example_general_component.sdv"
Class = "Hello_Component"
number = 42

View File

@@ -0,0 +1,6 @@
[Configuration]
Version = 100
[[Component]]
Path = "data_dispatch_service.sdv"
Class = "DataDispatchService"

View File

@@ -0,0 +1,23 @@
[Configuration]
Version = 100
[[Component]]
Path = "example_general_component.sdv"
Class = "Hello_Component"
[[Component]]
Path = "example_general_component_with_initialization.sdv"
Class = "Hello_Component_With_Initialization"
number = 42
[[Component]]
Path = "example_vehicle_device.sdv"
Class = "VehicleDevice_Component"
[[Component]]
Path = "example_basic_service.sdv"
Class = "BasicService_Component"
[[Component]]
Path = "example_complex_service.sdv"
Class = "ComplexService_Component"

View File

@@ -0,0 +1,47 @@
#include <iostream>
#include <stdexcept>
#include "example_interfaces.h"
#include <support/component_impl.h>
class CAccessComponent
: public sdv::CSdvObject
, public IShowExample
{
public:
CAccessComponent()
{
m_HelloInterface = sdv::core::GetObject("Hello_Component").GetInterface<ISayHello>();
sdv::TInterfaceAccessPtr helloComp = sdv::core::GetObject("Hello_Component");
m_GoodbyeInterface = helloComp.GetInterface<ISayGoodbye>();
if (!m_HelloInterface || !m_GoodbyeInterface)
{
throw std::runtime_error("Could not get all needed interfaces!");
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(IShowExample)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("Access_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Show messages, implements the function of IShowExample
*/
void Show() override
{
m_HelloInterface->SayHello();
m_GoodbyeInterface->SayGoodbye();
}
private:
ISayHello * m_HelloInterface = nullptr;
ISayGoodbye * m_GoodbyeInterface = nullptr;
};
DEFINE_SDV_OBJECT(CAccessComponent)

View File

@@ -0,0 +1,66 @@
#include <iostream>
#include <support/app_control.h>
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
/**
* @brief check if SDV_FRAMEWORK_RUNTIME environment variable exists
* @return Return true if environment variable is found otherwise false
*/
bool IsSDVFrameworkEnvironmentSet()
{
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
if (envVariable)
{
return true;
}
return false;
}
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain()
#else
extern "C" int main()
#endif
{
sdv::app::CAppControl appcontrol;
if (!IsSDVFrameworkEnvironmentSet())
{
// if SDV_FRAMEWORK_RUNTIME environment variable is not set we need to set the Framework Runtime directory
appcontrol.SetFrameworkRuntimeDirectory("../../bin");
}
auto bResult = appcontrol.AddModuleSearchDir("../../bin");
bResult &= appcontrol.Startup("");
appcontrol.SetConfigMode();
bResult &= appcontrol.AddConfigSearchDir("config");
bResult &= appcontrol.LoadConfig("docu_app_examples.toml") == sdv::core::EConfigProcessResult::successful;
if (!bResult)
{
std::cout << "Exit, Could not load docu_examples.toml." << std::endl;
appcontrol.Shutdown();
return 0;
}
appcontrol.SetRunningMode();
auto hello1 = sdv::core::GetObject("Hello_Component").GetInterface<ISayHello>();
auto bye1 = sdv::core::GetObject("Hello_Component").GetInterface<ISayGoodbye>();
auto hello2 = sdv::core::GetObject("Hello_Component_With_Initialization").GetInterface<ISayHello>();
auto bye2 = sdv::core::GetObject("Hello_Component_With_Initialization").GetInterface<ISayGoodbye>();
if (!hello1 || !bye1 || !hello2 || !bye2)
{
hello1->SayHello();
bye1->SayGoodbye();
hello2->SayHello();
bye2->SayGoodbye();
}
else
{
std::cout << "Could not get all interfaces interface" << std::endl;
}
appcontrol.Shutdown();
return 0;
}

View File

@@ -0,0 +1,122 @@
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CBasicService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
, public vss::Service::IReceptionSignalSpeed
, public vss::Service::ITransferSignalBrakeForce
{
public:
CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (!device)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
device->RegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
m_BrakeForce = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::ITransferSignalBrakeForce>();
if (!m_BrakeForce)
{
SDV_LOG_ERROR("Could not get abstract device: [CBasicService]");
throw std::runtime_error("VehicleDevice_Component device not found");
}
SDV_LOG_TRACE("CBasicService created: [BasicService_Component]");
}
~CBasicService()
{
auto device = sdv::core::GetObject("VehicleDevice_Component").GetInterface<vss::Device::IReceptionSignalSpeed>();
if (device)
{
device->UnRegisterSpeedEvent(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Service::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
SDV_INTERFACE_ENTRY(vss::Service::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("BasicService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::BasicService);
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
return m_BrakeForce->SetBrakeForce(value);
}
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
m_Speed = value;
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
for (auto callback : m_Callbacks)
{
callback->SetSpeedValue(value);
}
}
/**
* @brief Get Speedspeed
*/
int32_t GetSpeedValue() override
{
return m_Speed;
}
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.insert(callback);
}
}
/**
* @brief Unregister Callback
* @param[in] callback function
*/
void UnregisterCallBack(vss::Device::IReceptionSignalSpeed_Event* callback) override
{
if (callback)
{
std::lock_guard<std::mutex> lock(m_mutexCallbacks);
m_Callbacks.erase(callback);
}
}
private:
uint32_t m_Speed = { 0 }; ///< speed value which will be received
mutable std::mutex m_mutexCallbacks; ///< Mutex protecting m_Callbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_Callbacks; ///< collection of events to be called (received value)
vss::Device::ITransferSignalBrakeForce* m_BrakeForce = nullptr; ///< To write the brake force to the abstract device
};
DEFINE_SDV_OBJECT(CBasicService)

View File

@@ -0,0 +1,78 @@
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CComplexService
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed_Event
//
// complex service should offer interface(s) to be used by applications
//
{
public:
CComplexService()
{
m_SrvBrakeForce = sdv::core::GetObject("BasicService_Component").GetInterface<vss::Service::ITransferSignalBrakeForce>();
if (!m_SrvBrakeForce)
{
SDV_LOG_ERROR("Could not get basic service: [CComplexService]");
throw std::runtime_error("Brake force service not found");
}
auto serviceSpeed = sdv::core::GetObject("BasicService_Component").GetInterface<vss::Service::IReceptionSignalSpeed>();
if (serviceSpeed)
{
serviceSpeed->RegisterCallBack(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
else
{
SDV_LOG_ERROR("Could not get basic service: [CComplexService]");
throw std::runtime_error("Speed service not found");
}
}
~CComplexService()
{
auto serviceSpeed = sdv::core::GetObject("BasicService_Component").GetInterface<vss::Service::IReceptionSignalSpeed>();
if (serviceSpeed)
{
serviceSpeed->UnregisterCallBack(static_cast<vss::Device::IReceptionSignalSpeed_Event*> (this));
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed_Event)
//
// complex service should offer interface(s) to be used by applications
//
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_NAME("ComplexService_Component")
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::ComplexService);
/**
* @brief Set speed
* @param[in] value speed
*/
void SetSpeedValue(int32_t value) override
{
if (value > m_SpeedMaximum)
{
//Forward brake force to the basic service
m_SrvBrakeForce->SetBrakeForce(value);
}
}
private:
int32_t m_SpeedMaximum = { 100 }; ///< maximum allowed speed in this service implementation
int32_t m_Speed = { 0 }; ///< speed value which will be received
vss::Service::ITransferSignalBrakeForce* m_SrvBrakeForce = nullptr; ///< To write the brake force the basic service
};
DEFINE_SDV_OBJECT(CComplexService)

View File

@@ -0,0 +1,107 @@
#include <iostream>
#include <support/toml.h>
#include <support/component_impl.h>
#include <support/signal_support.h>
class CExampleDispatchService
{
public:
CExampleDispatchService()
{
sdv::core::CDispatchService dispatch;
m_dataLinkSignalRx = dispatch.RegisterRxSignal("Signal_DataLink_to_AbstractDevice"); ///< signals created by data link
m_dataLinkSignalTx01 = dispatch.RegisterTxSignal("Signal_AbstractDevice_to_DataLink_01", 123);
m_dataLinkSignalTx02 = dispatch.RegisterTxSignal("Signal_AbstractDevice_to_DataLink_02", 123);
m_dataLinkSignalTx03 = dispatch.RegisterTxSignal("Signal_AbstractDevice_to_DataLink_03", 123);
}
~CExampleDispatchService()
{
if (m_dataLinkSignalRx)
m_dataLinkSignalRx.Reset();
if (m_dataLinkSignalTx01)
m_dataLinkSignalTx01.Reset();
if (m_dataLinkSignalTx02)
m_dataLinkSignalTx02.Reset();
if (m_dataLinkSignalTx03)
m_dataLinkSignalTx03.Reset();
}
void SubscripSignals()
{
sdv::core::CDispatchService dispatch;
m_abstractDeviceSubscriper = dispatch.Subscribe("Signal_DataLink_to_AbstractDevice", [&](sdv::any_t value) { CallBackFunction(value); });
if (!m_abstractDeviceSubscriper)
{
std::cout << "Could not subscrupe to 'Signal_DataLink_to_AbstractDevice'" << std::endl;
}
else
{
std::cout << "Subscript to 'Signal_DataLink_to_AbstractDevice'" << std::endl;
}
}
void AddPublisherSignals()
{
sdv::core::CDispatchService dispatch;
m_abstractDevicePublisher01 = dispatch.AddPublisher("Signal_AbstractDevice_to_DataLink_01");
m_abstractDevicePublisher02 = dispatch.AddPublisher("Signal_AbstractDevice_to_DataLink_02");
m_abstractDevicePublisher03 = dispatch.AddPublisher("Signal_AbstractDevice_to_DataLink_03");
if (!m_abstractDevicePublisher01 || !m_abstractDevicePublisher02 || !m_abstractDevicePublisher03 )
{
std::cout << "Could not add publisher to 'Signal_AbstractDevice_to_DataLink'" << std::endl;
}
else
{
std::cout << "Publisher added to 'Signal_AbstractDevice_to_DataLink'" << std::endl;
}
}
void DataLinkWriter(const uint32_t value)
{
m_dataLinkSignalRx.Write(value);
}
void WriteToSignalAsPublisher(const uint32_t value01, const uint32_t value02, const uint32_t value03)
{
sdv::core::CDispatchService dispatch;
auto transaction = dispatch.CreateTransaction();
m_abstractDevicePublisher01.Write(value01, transaction);
m_abstractDevicePublisher02.Write(value02, transaction);
m_abstractDevicePublisher03.Write(value03, transaction);
transaction.Finish();
}
void GetTxSignalValue(const std::string& msg, uint32_t& value01, uint32_t& value02, uint32_t& value03)
{
sdv::core::CDispatchService dispatch;
auto transaction = dispatch.CreateTransaction();
value01 = m_dataLinkSignalTx01.Read(transaction).get<uint32_t>();
value02 = m_dataLinkSignalTx02.Read(transaction).get<uint32_t>();
value03 = m_dataLinkSignalTx03.Read(transaction).get<uint32_t>();
transaction.Finish();
std::cout << "Read Tx signals (" << msg.c_str() <<"): " << std::to_string(value01) << ", " << std::to_string(value02) << ", " << std::to_string(value03) << std::endl;
}
private:
/**
* @brief CallBackFunction for the subscription
*/
void CallBackFunction(sdv::any_t value)
{
uint32_t sayHello = value.get<uint32_t>();
std::cout << "This CallBackFunction is called on signal change: " << std::to_string(sayHello) << std::endl;
}
sdv::core::CSignal m_dataLinkSignalRx; ///< signals created and used by data link
sdv::core::CSignal m_dataLinkSignalTx01; ///< signals created and used by data link
sdv::core::CSignal m_dataLinkSignalTx02; ///< signals created and used by data link
sdv::core::CSignal m_dataLinkSignalTx03; ///< signals created and used by data link
sdv::core::CSignal m_abstractDeviceSubscriper; ///< signals used by an abstract device
sdv::core::CSignal m_abstractDevicePublisher01; ///< signals used by an abstract device
sdv::core::CSignal m_abstractDevicePublisher02; ///< signals used by an abstract device
sdv::core::CSignal m_abstractDevicePublisher03; ///< signals used by an abstract device
};

View File

@@ -0,0 +1,46 @@
#include <iostream>
#include "example_interfaces.h"
#include <support/component_impl.h>
class CTestComponent
: public sdv::CSdvObject
, public ISayHello
, public ISayGoodbye
{
public:
CTestComponent()
{
std::cout << "Entering CTestComponent constructor..." << std::endl;
}
~CTestComponent() override
{
std::cout << "Entering CTestComponent destructor..." << std::endl;
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(ISayHello)
SDV_INTERFACE_ENTRY(ISayGoodbye)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
DECLARE_OBJECT_CLASS_NAME("Hello_Component")
/**
* @brief Show hello message, implements the function of ISayHello
*/
void SayHello() override
{
std::cout << "Hello from Hello_Component ..." << std::endl;
}
/**
* @brief Show hello message, implements the function of ISayGoodbye
*/
void SayGoodbye() override
{
std::cout << "Goodbye from Hello_Component ..." << std::endl;
}
};
DEFINE_SDV_OBJECT(CTestComponent)

View File

@@ -0,0 +1,127 @@
#include <iostream>
#include <support/toml.h>
#include <support/component_impl.h>
#include "example_interfaces.h"
class CTestComponentWithInitialization
: public sdv::CSdvObject
, public sdv::IObjectControl
, public ISayHello
, public ISayGoodbye
{
public:
CTestComponentWithInitialization()
{
std::cout << "Entering CTestComponentWithInitialization constructor..." << std::endl;
}
~CTestComponentWithInitialization() override
{
std::cout << "Entering CTestComponentWithInitialization destructor..." << std::endl;
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(ISayHello)
SDV_INTERFACE_ENTRY(ISayGoodbye)
SDV_INTERFACE_ENTRY(sdv::IObjectControl)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
DECLARE_OBJECT_CLASS_NAME("Hello_Component_With_Initialization")
/**
* @brief Initialize the object. Overload of sdv::IObjectControl::Initialize.
* @param[in] ssObjectConfig Optional configuration string.
*/
inline virtual void Initialize(const sdv::u8string& ssObjectConfig) override
{
if (!ParseConfigurationString(ssObjectConfig))
{
m_status = sdv::EObjectStatus::initialization_failure;
return;
}
m_status = sdv::EObjectStatus::initialized;
};
/**
* @brief Set the component operation mode. Overload of sdv::IObjectControl::SetOperationMode.
* @param[in] eMode The operation mode, the component should run in.
*/
void SetOperationMode(/*in*/ sdv::EOperationMode eMode) override
{
switch (eMode)
{
case sdv::EOperationMode::configuring:
if (m_status == sdv::EObjectStatus::running || m_status == sdv::EObjectStatus::initialized)
m_status = sdv::EObjectStatus::configuring;
break;
case sdv::EOperationMode::running:
if (m_status == sdv::EObjectStatus::configuring || m_status == sdv::EObjectStatus::initialized)
m_status = sdv::EObjectStatus::running;
break;
default:
break;
}
}
/**
* @brief Get the current status of the object. Overload of sdv::IObjectControl::GetStatus.
* @return Return the current status of the object.
*/
inline virtual sdv::EObjectStatus GetStatus() const override
{
return m_status;
};
/**
* @brief Shutdown called before the object is destroyed. Overload of sdv::IObjectControl::Shutdown.
*/
inline virtual void Shutdown() override
{
m_status = sdv::EObjectStatus::destruction_pending;
}
/**
* @brief Show messages, implements the function of IShowExample
*/
void SayHello() override
{
std::cout << "Hello from Hello_Component_With_Initialization ... " << std::to_string(m_Number) << std::endl;
}
/**
* @brief Show messages, implements the function of ISayGoodbye
*/
void SayGoodbye() override
{
std::cout << "Goodbye from Hello_Component_With_Initialization ... " << std::to_string(m_Number) << std::endl;
}
private:
bool ParseConfigurationString(const sdv::u8string& objectConfig)
{
try
{
sdv::toml::CTOMLParser config(objectConfig.c_str());
// get any settings from the configuration
auto nodeNumber = config.GetDirect("number");
if (nodeNumber.GetType() == sdv::toml::ENodeType::node_integer)
{
m_Number = static_cast<int32_t>(nodeNumber.GetValue());
}
}
catch (const sdv::toml::XTOMLParseException& e)
{
std::cout << "Configuration could not be read:" << e.what() << std::endl;
return false;
}
std::cout << "Initialization number: " << std::to_string(m_Number) << std::endl;
return true;
}
int32_t m_Number = -1;
std::atomic<sdv::EObjectStatus> m_status = { sdv::EObjectStatus::initialization_pending }; //!< To update the object status when it changes.
};
DEFINE_SDV_OBJECT(CTestComponentWithInitialization)

View File

@@ -0,0 +1,7 @@
#include <interfaces/core.idl>
interface ISayHello
{
void SayHello() const;
};

View File

@@ -0,0 +1,21 @@
#include <interfaces/core.h>
#include <support/signal_support.h>
interface ISayHello ///< interface example ISayHello
{
virtual void SayHello() = 0; ///< function og the interface
static constexpr ::sdv::interface_id _id = 0xA012345678900100; ///< Interface Id
};
interface ISayGoodbye ///< interface example ISayGoodbye
{
virtual void SayGoodbye() = 0; ///< function og the interface
static constexpr ::sdv::interface_id _id = 0xA012345678900200; ///< Interface Id
};
interface IShowExample ///< interface example IShowExample
{
virtual void Show() = 0; ///< function og the interface
static constexpr ::sdv::interface_id _id = 0xA012345678900300; ///< Interface Id
};

View File

@@ -0,0 +1,79 @@
#include <interfaces/core.h>
#include <support/signal_support.h>
namespace vss
{
namespace Device
{
/**
* @brief IReceptionSignalSpeed abstract device interface, example of receiving a value
*/
interface IReceptionSignalSpeed_Event
{
/** Interface ID. */
static constexpr ::sdv::interface_id _id = 0xA012345678900400;
/**
* @brief Set Speed value (for example of type int32_t)
* @param[in] value of current speed
*/
virtual void SetSpeedValue(/*in*/ int32_t value) = 0;
};
/**
* @brief IReceptionSignalSpeed abstract device interface, example of receiving a value
*/
interface IReceptionSignalSpeed
{
/** Interface ID. */
static constexpr ::sdv::interface_id _id = 0xA012345678900500;
/**
* @brief Register IReceptionSignalSpeed_Event on signal change
* Register all events and call them on signal change
* @param[in] event function
*/
virtual void RegisterSpeedEvent(/*in*/ IReceptionSignalSpeed_Event* event) = 0;
/**
* @brief UnRegister IReceptionSignalSpeed_Event on signal change
* Register all events and call them on signal change
* @param[in] event function
*/
virtual void UnRegisterSpeedEvent(/*in*/ IReceptionSignalSpeed_Event* event) = 0;
};
}
}
namespace vss
{
namespace Service
{
/**
* @brief Vehicle speed service
*/
interface IReceptionSignalSpeed
{
/** Interface ID. */
static constexpr ::sdv::interface_id _id = 0xA012345678900600;
/**
* @brief Get Speed value (for example of type int32_t)
* @return Returns current speed
*/
virtual int32_t GetSpeedValue() = 0;
/**
* @brief Register Callback on signal change
* @param[in] callback function
*/
virtual void RegisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) = 0;
/**
* @brief Unregister Callback
* @param[in] callback function
*/
virtual void UnregisterCallBack(/*in*/ vss::Device::IReceptionSignalSpeed_Event* callback) = 0;
};
}
}

View File

@@ -0,0 +1,46 @@
#include <interfaces/core.h>
#include <support/signal_support.h>
namespace vss
{
namespace Device
{
/**
* @brief ITransferSignalBrakeForce interface, example of transferring a value
*/
interface ITransferSignalBrakeForce
{
/** Interface ID. */
static constexpr ::sdv::interface_id _id = 0xA012345678900800;
/**
* @brief Set brake force value
* @param[in] value brake force
* @return true on success otherwise false
*/
virtual bool SetBrakeForce(/*in*/ uint32_t value) = 0;
};
}
}
namespace vss
{
namespace Service
{
/**
* @brief ITransferSignalBrakeForce interface, example oftransferringg a value
*/
interface ITransferSignalBrakeForce
{
/** Interface ID. */
static constexpr ::sdv::interface_id _id = 0xA012345678900900;
/**
* @brief Set brake force value
* @param[in] value brake force
* @return true on success otherwise false
*/
virtual bool SetBrakeForce(/*in*/ uint32_t value) = 0;
};
}
}

View File

@@ -0,0 +1,123 @@
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include <support/signal_support.h>
#include <support/component_impl.h>
#include <interfaces/dispatch.h>
#include <iostream>
#include <set>
class CVehicleDevice
: public sdv::CSdvObject
, public vss::Device::IReceptionSignalSpeed
, public vss::Device::ITransferSignalBrakeForce
{
public:
CVehicleDevice()
{
sdv::core::CDispatchService dispatch;
m_SpeedSignal = dispatch.Subscribe("SPEED_SIGNAL_NAME", [&](sdv::any_t value) { CallBackFunctionSpeedSignal(value); });
if (!m_SpeedSignal)
{
std::cout << "Speed signal not found" << std::endl;
throw std::runtime_error("SpeedSignal not found");
}
m_TransferSignalBrakeForce = dispatch.AddPublisher("BRAKE_FORCE_SIGNAL_NAME");
if (!m_TransferSignalBrakeForce)
{
std::cout << "BrakeForce signal not found" << std::endl;
throw std::runtime_error("BrakeForce not found");
}
}
BEGIN_SDV_INTERFACE_MAP()
SDV_INTERFACE_ENTRY(vss::Device::IReceptionSignalSpeed)
SDV_INTERFACE_ENTRY(vss::Device::ITransferSignalBrakeForce)
END_SDV_INTERFACE_MAP()
DECLARE_OBJECT_CLASS_TYPE(sdv::EObjectType::Device)
DECLARE_OBJECT_CLASS_NAME("VehicleDevice_Component")
~CVehicleDevice()
{
if (m_SpeedSignal)
{
m_SpeedSignal.Reset();
}
if (m_TransferSignalBrakeForce)
{
m_TransferSignalBrakeForce.Reset();
}
}
/**
* @brief Register ReceptionSignalSpeed event on signal change
* Collect all events and call them on signal change
* @param[in] event function
*/
void RegisterSpeedEvent(vss::Device::IReceptionSignalSpeed_Event* event) override
{
if (event)
{
std::cout << "register a SignalSpeedEvent ..." << std::endl;
std::lock_guard<std::mutex> lock(m_SpeedMutexCallbacks);
m_SpeedCallbacks.insert(event);
}
}
/**
* @brief Register ReceptionSignalSpeed event on signal change
* Collect all events and call them on signal change
* @param[in] event function
*/
void UnRegisterSpeedEvent(vss::Device::IReceptionSignalSpeed_Event* event) override
{
if (event)
{
std::cout << "unregister a SignalSpeedEvent ..." << std::endl;
std::lock_guard<std::mutex> lock(m_SpeedMutexCallbacks);
m_SpeedCallbacks.erase(event);
}
}
/**
* @brief Set brake force
* @param[in] value of the brake force
* @return true on success otherwise false
*/
bool SetBrakeForce(uint32_t value) override
{
if (m_TransferSignalBrakeForce)
{
m_TransferSignalBrakeForce.Write(value);
return true;
}
return false;
}
private:
/**
* @brief Execute all callbacks for the Speed Signal
*/
void CallBackFunctionSpeedSignal(sdv::any_t value)
{
uint32_t speed = value.get<uint32_t>();
std::cout << "CallBackFunction SpeedSignal: " << std::to_string(speed) << std::endl;
std::lock_guard<std::mutex> lock(m_SpeedMutexCallbacks);
for (auto callback : m_SpeedCallbacks)
{
callback->SetSpeedValue(speed);
}
}
sdv::core::CSignal m_TransferSignalBrakeForce; ///< SignalBrakeForce of the abstract device
sdv::core::CSignal m_SpeedSignal; ///< SpeedSignal of the abstract device
mutable std::mutex m_SpeedMutexCallbacks; ///< Mutex protecting m_SpeedCallbacks
std::set<vss::Device::IReceptionSignalSpeed_Event*> m_SpeedCallbacks; ///< collection of IReceptionSignalSpeed events to be called
};
DEFINE_SDV_OBJECT(CVehicleDevice)

View File

@@ -0,0 +1,189 @@
#include <iostream>
#include <support/signal_support.h>
#include <support/app_control.h>
#include "example_interfaces.h"
#include "example_reception_interfaces.h"
#include "example_transfer_interfaces.h"
#include "example_dispatch_service.cpp"
sdv::core::CSignal m_signalSpeedRx;
sdv::core::CSignal m_signalBrakeForceTx;
/**
* @brief check if SDV_FRAMEWORK_RUNTIME environment variable exists
* @return Return true if environment variable is found otherwise false
*/
bool IsSDVFrameworkEnvironmentSet()
{
const char* envVariable = std::getenv("SDV_FRAMEWORK_RUNTIME");
if (envVariable)
{
return true;
}
return false;
}
void UsageOfGeneralComponent()
{
std::cout << "Running example of General Component use:" << std::endl;
auto hello = sdv::core::GetObject("Hello_Component").GetInterface<ISayHello>();
auto bye = sdv::core::GetObject("Hello_Component").GetInterface<ISayGoodbye>();
if (!hello)
std::cout << "Could not get hello interface" << std::endl;
else
hello->SayHello();
if (!bye)
std::cout << "Could not get bye interface" << std::endl;
else
bye->SayGoodbye();
std::cout << "\n";
}
void UsageOfGeneralComponentWithInitialization()
{
std::cout << "Running example of General Component With Initialization, the number should be 42:" << std::endl;
auto hello = sdv::core::GetObject("Hello_Component_With_Initialization").GetInterface<ISayHello>();
auto bye = sdv::core::GetObject("Hello_Component_With_Initialization").GetInterface<ISayGoodbye>();
if (!hello)
std::cout << "Could not get hello interface" << std::endl;
else
hello->SayHello();
if (!bye)
std::cout << "Could not get bye interface" << std::endl;
else
bye->SayGoodbye();
std::cout << "\n";
}
void UsageOfAbstractDeviceAndBasicService()
{
std::cout << "Running example of Abstract Device Component use:" << std::endl;
auto brakeForce = sdv::core::GetObject("BasicService_Component").GetInterface<vss::Service::ITransferSignalBrakeForce>();
if (brakeForce)
{
brakeForce->SetBrakeForce(123);
sdv::core::CDispatchService dispatch;
auto transaction = dispatch.CreateTransaction();
auto value = m_signalBrakeForceTx.Read(transaction).get<uint32_t>();
transaction.Finish();
std::cout << "Set Brake force 123 and read value: " << std::to_string(value) << std::endl;
}
else
{
std::cout << "No interface 'vss::Service::ITransferSignalBrakeForce' of the basic service " << std::endl;
}
std::cout << "Now a callback function should be called with 12345:" << std::endl;
m_signalSpeedRx.Write(12345);
auto speed = sdv::core::GetObject("BasicService_Component").GetInterface<vss::Service::IReceptionSignalSpeed>();
if (speed)
{
auto value = speed->GetSpeedValue();
std::cout << "Speed value should be 12345: " << std::to_string(value) << std::endl;
}
else
{
std::cout << "No interface 'vss::Service::IReceptionSignalSpeed' of the basic service " << std::endl;
}
std::cout << "Complex service exists? " << std::to_string(sdv::core::GetObject("ComplexService_Component").IsValid()) << std::endl;
std::cout << "\n";
}
void UsageOfDataDispatchServiceAccess(CExampleDispatchService* exampleDispatchService)
{
uint32_t value01{ 0 };
uint32_t value02{ 0 };
uint32_t value03{ 0 };
std::cout << "Running example of dispatchservice\n";
std::cout << "Start: " << std::to_string(value01) << " " << std::to_string(value02) << " " << std::to_string(value03) << " " << std::endl;
exampleDispatchService->GetTxSignalValue("after creation", value01, value02, value03);
exampleDispatchService->WriteToSignalAsPublisher(17, 18, 19);
exampleDispatchService->GetTxSignalValue("after 17, 18, 19 written", value01, value02, value03);
exampleDispatchService->GetTxSignalValue("after nothing changed", value01, value02, value03);
exampleDispatchService->WriteToSignalAsPublisher(456, 455, 454);
exampleDispatchService->GetTxSignalValue("after 456, 455, 454 written", value01, value02, value03);
std::cout << "Write 77 to RX signal: " << std::endl;
exampleDispatchService->DataLinkWriter(77);
std::cout << "\n";
}
bool InitializeAppControl(sdv::app::CAppControl* appcontrol)
{
auto bResult = appcontrol->AddModuleSearchDir("../../bin");
bResult &= appcontrol->Startup("");
appcontrol->SetConfigMode();
if (appcontrol->LoadConfig("docu_dispatch.toml") != sdv::core::EConfigProcessResult::successful)
{
std::cout << "dispatch service could be loaded" << std::endl;
}
sdv::core::CDispatchService dispatch;
m_signalSpeedRx = dispatch.RegisterRxSignal("SPEED_SIGNAL_NAME"); ///< signals for abstract device
m_signalBrakeForceTx = dispatch.RegisterTxSignal("BRAKE_FORCE_SIGNAL_NAME", 0);
if (!m_signalSpeedRx || !m_signalBrakeForceTx)
{
std::cout << "Signal for Speed and Brake Force could not be registered" << std::endl;
bResult = false;
}
if (appcontrol->LoadConfig("docu_examples.toml") != sdv::core::EConfigProcessResult::successful)
{
std::cout << "Not all examples could be loaded" << std::endl;
bResult = false;
}
return bResult;
}
void AddPuplisherAndSubscriper(CExampleDispatchService* exampleDispatchService)
{
exampleDispatchService->AddPublisherSignals();
exampleDispatchService->SubscripSignals();
std::cout << "\n";
}
#if defined(_WIN32) && defined(_UNICODE)
extern "C" int wmain()
#else
extern "C" int main()
#endif
{
sdv::app::CAppControl appcontrol;
if (!IsSDVFrameworkEnvironmentSet())
{
// if SDV_FRAMEWORK_RUNTIME environment variable is not set we need to set the Framework Runtime directory
appcontrol.SetFrameworkRuntimeDirectory("../../bin");
}
std::cout << "Run documentation code examples:\n- Initialization/Configuration mode.\n" << std::endl;
InitializeAppControl(&appcontrol);
CExampleDispatchService exampleDispatchService;
AddPuplisherAndSubscriper(&exampleDispatchService); // for dispatch example, must be done before appcontrol.SetRunningMode();
appcontrol.SetRunningMode();
std::cout << "- Set running mode\n" << std::endl;
std::cout << "------------------------------------------------\n---Running UsageOfDataDispatchServiceAccess():" << std::endl;
UsageOfDataDispatchServiceAccess(&exampleDispatchService);
std::cout << "------------------------------------------------\n---Running UsageOfGeneralComponent():" << std::endl;
UsageOfGeneralComponent();
std::cout << "------------------------------------------------\n---Running UsageOfGeneralComponentWithInitialization():" << std::endl;
UsageOfGeneralComponentWithInitialization();
std::cout << "------------------------------------------------\n---Running UsageOfAbstractDeviceAndBasicService():" << std::endl;
UsageOfAbstractDeviceAndBasicService();
appcontrol.Shutdown();
std::cout << "\n\nTest finished." << std::endl;
return 0;
}