mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-02-05 15:18:45 +00:00
88
examples/_howto_examples/CMakeLists.txt
Normal file
88
examples/_howto_examples/CMakeLists.txt
Normal 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)
|
||||
13
examples/_howto_examples/example_config_file.cfg
Normal file
13
examples/_howto_examples/example_config_file.cfg
Normal 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" }
|
||||
170
examples/_howto_examples/example_config_file_parsing.cfg
Normal file
170
examples/_howto_examples/example_config_file_parsing.cfg
Normal 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)
|
||||
12
examples/_howto_examples/source/docu_app_examples.toml
Normal file
12
examples/_howto_examples/source/docu_app_examples.toml
Normal 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
|
||||
|
||||
6
examples/_howto_examples/source/docu_dispatch.toml
Normal file
6
examples/_howto_examples/source/docu_dispatch.toml
Normal file
@@ -0,0 +1,6 @@
|
||||
[Configuration]
|
||||
Version = 100
|
||||
|
||||
[[Component]]
|
||||
Path = "data_dispatch_service.sdv"
|
||||
Class = "DataDispatchService"
|
||||
23
examples/_howto_examples/source/docu_examples.toml
Normal file
23
examples/_howto_examples/source/docu_examples.toml
Normal 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"
|
||||
@@ -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)
|
||||
66
examples/_howto_examples/source/example_application.cpp
Normal file
66
examples/_howto_examples/source/example_application.cpp
Normal 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;
|
||||
}
|
||||
122
examples/_howto_examples/source/example_basic_service.cpp
Normal file
122
examples/_howto_examples/source/example_basic_service.cpp
Normal 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)
|
||||
78
examples/_howto_examples/source/example_complex_service.cpp
Normal file
78
examples/_howto_examples/source/example_complex_service.cpp
Normal 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)
|
||||
107
examples/_howto_examples/source/example_dispatch_service.cpp
Normal file
107
examples/_howto_examples/source/example_dispatch_service.cpp
Normal 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
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
7
examples/_howto_examples/source/example_idl.h
Normal file
7
examples/_howto_examples/source/example_idl.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#include <interfaces/core.idl>
|
||||
|
||||
interface ISayHello
|
||||
{
|
||||
void SayHello() const;
|
||||
};
|
||||
|
||||
21
examples/_howto_examples/source/example_interfaces.h
Normal file
21
examples/_howto_examples/source/example_interfaces.h
Normal 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
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
123
examples/_howto_examples/source/example_vehicle_device.cpp
Normal file
123
examples/_howto_examples/source/example_vehicle_device.cpp
Normal 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)
|
||||
189
examples/_howto_examples/source/run_all_examples.cpp
Normal file
189
examples/_howto_examples/source/run_all_examples.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user