Example General Component#

Note

An Vehicle Device is used here as an example, but the described points are relevant for all VAPI Component s.

Warning

When compiling a VAPI Component, basically a shared library (normally .dll under Windows and .so under Linux), it is important that only explicitly exported functions are visible since otherwise dynamic linking will produce crashing errors. Private visibility for functions in shared libraries unless explicitly exported is default under Windows but may not be with other systems and/or compilers. To assure the needed visibility e.g. under CMake one can add the line set(CMAKE_CXX_VISIBILITY_PRESET hidden) in the corresponding CMakeLists.txt files.

#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)
#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)

Any VAPI Component needs to inherit from the CSdvObject class and any interface it implements.

#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)

Any VAPI Component needs to have their destructor virtual through the override keyword if one exists.

#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)

Any VAPI Component needs to declare the interfaces it wants to expose in the interface map to be accessible via the GetInterface template function by other VAPI Component s.

#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)

Any VAPI Component needs to declare to which kind of component it is. This defines also to what other component group it is allowed to communicate with. Possible options are defined in the EObjectType enum.

#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)

Any VAPI Component needs to declare its name to be able to be found by other components and be able to be referenced in the Config File.

Warning

This name has to be unique in any system setup the component is used in!

#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)

Any VAPI Component needs to implement all the functions from the inherited Interface s.

#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)

Any VAPI Component needs to be declared as a VAPI Component by the DEFINE_SDV_OBJECT macro that takes the class type of the component as an argument.

Warning

The call to DEFINE_SDV_OBJECT must be in the same namespace as the object it declares as a VAPI Component since it does not allow for namespaces in front of the class type in the argument.

Note

The Inheritance, Exposing Interfaces, Object Type and Function Implementation can also be, in full or partly, done by an other custom parent class.