Shows how to implement a filter which is triggered by a Timer Runner.
Additionally, it show how to use DDL type reflection API to create valid description from a cpp defined struct:
#include "demo_time_trigger_function.h"
#include <easy/profiler.h>
using namespace adtf::util;
namespace
{
#pragma pack(push, 1)
enum class eSimpleEnum : tUInt8
{
eEnum_value_zero = 0,
eEnum_value_one = 1,
eEnum_value_two = 2,
eEnum_value_three = 3,
eEnum_value_four = 4,
eEnum_value_five = 5,
eEnum_value_six = 6,
eEnum_value_seven = 7,
eEnum_value_eight = 8,
eEnum_value_nine = 9
};
struct tSimpleStruct
{
uint8_t ui8Val;
uint16_t ui16Val;
uint32_t ui32Val;
int32_t i32Val;
int64_t i64Val;
double f64Val;
float f32Val;
eSimpleEnum ei8EnumVal;
};
struct tSimpleStructArray
{
int32_t i32SimpleValidElementCount;
tSimpleStruct sSimple[10];
};
struct tHeaderStruct
{
uint32_t ui32HeaderVal;
double f64HeaderVal;
};
struct tNestedStruct
{
tHeaderStruct sHeaderStruct;
tSimpleStruct sSimpleStruct;
};
struct tNestedArrayStruct
{
tHeaderStruct sHeaderStructArray[100];
tSimpleStruct sSimpleStructArray[2000];
};
struct tArraysWithValidElementCount
{
uint32_t nSimpleStructArrayValidElementCount;
tSimpleStructArray sSimpleStructArray[20];
uint64_t nArrayValidElementCount;
int64_t nArray[30];
int64_t nValue;
bool bValueValid;
};
#pragma pack(pop)
}
ADTF_PLUGIN(
"Demo Time Trigger Plugin", cSimpleDataGenerator);
cSimpleDataGenerator::cSimpleDataGenerator(): m_oDistribution(0.0, 100.0)
{
SetDescription("out", "Provides the generated data based on number_gen_type");
m_pWriterSimpleArray = CreateOutputPin(
"out_array",
stream_type_plain<std::array<int64_t, 10>>());
SetDescription("out_array", "Provides the generated data array based on number_gen_type");
.
Add(
"eEnum_value_zero", eSimpleEnum::eEnum_value_zero)
.
Add(
"eEnum_value_one", eSimpleEnum::eEnum_value_one)
.
Add(
"eEnum_value_two", eSimpleEnum::eEnum_value_two)
.
Add(
"eEnum_value_three", eSimpleEnum::eEnum_value_three)
.
Add(
"eEnum_value_four", eSimpleEnum::eEnum_value_four)
.
Add(
"eEnum_value_five", eSimpleEnum::eEnum_value_five)
.
Add(
"eEnum_value_six", eSimpleEnum::eEnum_value_six)
.
Add(
"eEnum_value_seven", eSimpleEnum::eEnum_value_seven)
.
Add(
"eEnum_value_eight", eSimpleEnum::eEnum_value_eight)
.
Add(
"eEnum_value_nine", eSimpleEnum::eEnum_value_nine);
oSimpleStructDefinition.createElement("ui8Val", &tSimpleStruct::ui8Val);
oSimpleStructDefinition.createElement("ui16Val", &tSimpleStruct::ui16Val);
oSimpleStructDefinition.createElement("ui32Val", &tSimpleStruct::ui32Val);
oSimpleStructDefinition.createElement("i32Val", &tSimpleStruct::i32Val);
oSimpleStructDefinition.createElement("i64Val", &tSimpleStruct::i64Val);
oSimpleStructDefinition.createElement("f64Val", &tSimpleStruct::f64Val);
oSimpleStructDefinition.createElement("f32Val", &tSimpleStruct::f32Val);
oSimpleStructDefinition.createElement("ei8EnumVal", &tSimpleStruct::ei8EnumVal, oSimpleEnumDefinition);
oSimpleStructArrayDefinition.createElement("i32SimpleValidElementCount",
&tSimpleStructArray::i32SimpleValidElementCount);
oSimpleStructArrayDefinition.createElement("sSimple", &tSimpleStructArray::sSimple, oSimpleStructDefinition)
.setValidElementCount("i32SimpleValidElementCount");
oHeaderStructDefinition.createElement("ui32HeaderVal", &tHeaderStruct::ui32HeaderVal);
oHeaderStructDefinition.createElement("f64HeaderVal", &tHeaderStruct::f64HeaderVal);
oNestedDefinition.createElement("sHeaderStruct", &tNestedStruct::sHeaderStruct, oHeaderStructDefinition);
oNestedDefinition.createElement("sSimpleStruct", &tNestedStruct::sSimpleStruct, oSimpleStructDefinition);
m_pWriterNested = CreateOutputPin("nested_struct", oNestedDefinition);
SetDescription("nested_struct", "Provides the generated data based on number_gen_type");
oNestedArrayDefinition.createElement("sHeaderStructArray", &tNestedArrayStruct::sHeaderStructArray,
oHeaderStructDefinition);
oNestedArrayDefinition.createElement("sSimpleStructArray", &tNestedArrayStruct::sSimpleStructArray,
oSimpleStructDefinition);
m_pWriterNestedArray = CreateOutputPin("nested_struct_array", oNestedArrayDefinition);
SetDescription("nested_struct_array",
"Provides the generated data based on number_gen_type in a structure with arrays");
auto oArraysWithValidElementCountDefinition =
oArraysWithValidElementCountDefinition.createElement(
"nSimpleStructArrayValidElementCount", &tArraysWithValidElementCount::nSimpleStructArrayValidElementCount);
oArraysWithValidElementCountDefinition
.createElement("sSimpleStructArray", &tArraysWithValidElementCount::sSimpleStructArray,
oSimpleStructArrayDefinition)
.setValidElementCount("nSimpleStructArrayValidElementCount");
oArraysWithValidElementCountDefinition
.createElement("nArrayValidElementCount", &tArraysWithValidElementCount::nArrayValidElementCount)
.setComment("This is an valid element count for the nArray!");
oArraysWithValidElementCountDefinition.createElement("nArray", &tArraysWithValidElementCount::nArray,
"nArrayValidElementCount");
oArraysWithValidElementCountDefinition.createElement("nValue", &tArraysWithValidElementCount::nValue);
oArraysWithValidElementCountDefinition.createElement("bValueValid", &tArraysWithValidElementCount::bValueValid);
oArraysWithValidElementCountDefinition.getElement("nValue").setValidElementCount("bValueValid");
m_pWriterArraysWithValidElementCount =
CreateOutputPin("arrays_with_valid_element_count", oArraysWithValidElementCountDefinition);
SetDescription("arrays_with_valid_element_count", "Provides the generated data based on number_gen_type in a "
"struct containing arrays with valid element count set");
CreateRunner("data_generator_function", cTimerTriggerHint(std::chrono::seconds{1}));
SetDescription("data_generator_function",
"Runner to periodically trigger the function which generates the output data for all pins");
m_eGeneratorType.SetValueList({{eCounter, "Counter"}, {eRandom, "Random"}});
m_eGeneratorType.SetDescription("Chooses the generator used for calculating output data.");
RegisterPropertyVariable("data_generator_function/number_gen_type", m_eGeneratorType);
SetDescription("Use this filter to generate data whenever a defined Timer Runner triggers.");
SetHelpLink("$(ADTF_DIR)/doc/html/page_demo_time_trigger.html");
}
cSimpleDataGenerator::~cSimpleDataGenerator() = default;
tResult cSimpleDataGenerator::Init(tInitStage eStage)
{
if (eStage == StageNormal)
{
switch (m_eGeneratorType)
{
case eCounter:
{
m_fnGenerator = [&]
{
return static_cast<double>(++m_nCounter);
};
LOG_INFO(
"Current generation type is Counter");
break;
}
case eRandom:
{
m_fnGenerator = [&]
{
return m_oDistribution(m_oRandomGenerator);
};
LOG_INFO(
"Current generation type is Random");
break;
}
default:
{
"Invalid property value '%" PRIu32 "' for 'number_gen_type', use Counter",
*m_eGeneratorType);
}
}
}
}
{
double fOutValue = m_fnGenerator();
GenerateSimpleData(tmTimeOfTrigger, fOutValue);
GenerateSimpleArrayData(tmTimeOfTrigger, fOutValue);
GenerateNestedData(tmTimeOfTrigger, fOutValue);
GenerateNestedArrayData(tmTimeOfTrigger, fOutValue);
GenerateArraysWithValidElementCountData(tmTimeOfTrigger, fOutValue);
}
void cSimpleDataGenerator::GenerateSimpleData(
tNanoSeconds tmTimeOfTrigger,
double fOutValue)
{
EASY_FUNCTION();
oOutputData = static_cast<float>(fOutValue);
m_pWriterSimple->Write(oOutputData.Release());
}
void cSimpleDataGenerator::GenerateSimpleArrayData(
tNanoSeconds tmTimeOfTrigger,
double fOutValue)
{
EASY_FUNCTION();
for (auto& oCurrentArrayValue : *oOutputData)
{
oCurrentArrayValue = static_cast<int64_t>(fOutValue);
}
m_pWriterSimpleArray->Write(oOutputData.Release());
}
namespace
{
void fill_simple_struct(tSimpleStruct& oStruct, double fValue)
{
oStruct.ui8Val = static_cast<uint8_t>(fValue);
oStruct.ui16Val = static_cast<uint16_t>(fValue);
oStruct.ui32Val = static_cast<uint32_t>(fValue);
oStruct.i32Val = static_cast<int32_t>(fValue);
oStruct.i64Val = static_cast<int64_t>(fValue);
oStruct.f64Val = fValue;
oStruct.f32Val = static_cast<float>(fValue);
oStruct.ei8EnumVal = static_cast<eSimpleEnum>(oStruct.ui8Val % 10);
}
void fill_header_struct(tHeaderStruct& oStruct, double fValue)
{
oStruct.ui32HeaderVal = static_cast<uint32_t>(fValue);
oStruct.f64HeaderVal = fValue;
}
}
void cSimpleDataGenerator::GenerateNestedData(
tNanoSeconds tmTimeOfTrigger,
double fOutValue)
{
EASY_FUNCTION();
fill_header_struct(oOutputData->sHeaderStruct, fOutValue);
fill_simple_struct(oOutputData->sSimpleStruct, fOutValue);
m_pWriterNested->Write(oOutputData.Release());
}
void cSimpleDataGenerator::GenerateNestedArrayData(
tNanoSeconds tmTimeOfTrigger,
double fOutValue)
{
EASY_FUNCTION();
for (size_t nCurrentPos = 0; nCurrentPos < 100; ++nCurrentPos)
{
fill_header_struct(oOutputData->sHeaderStructArray[nCurrentPos], fOutValue);
}
for (size_t nCurrentPos = 0; nCurrentPos < 2000; ++nCurrentPos)
{
fill_simple_struct(oOutputData->sSimpleStructArray[nCurrentPos], fOutValue);
}
m_pWriterNestedArray->Write(oOutputData.Release());
}
void cSimpleDataGenerator::GenerateArraysWithValidElementCountData(
tNanoSeconds tmTimeOfTrigger,
double fOutValue)
{
EASY_FUNCTION();
const auto bValid = (m_nValidElementCountCounter % 20) < 10;
const uint32_t nSimpleArrayValidElementCount = bValid ? 10 : 20;
oOutputData->nSimpleStructArrayValidElementCount = nSimpleArrayValidElementCount;
for (uint32_t nCurrentSimpleArrayIndex = 0; nCurrentSimpleArrayIndex < nSimpleArrayValidElementCount;
++nCurrentSimpleArrayIndex)
{
auto& sCurrentStructArray = oOutputData->sSimpleStructArray[nCurrentSimpleArrayIndex];
const int32_t nSimpleValidElementCount = m_nValidElementCountCounter % 10;
sCurrentStructArray.i32SimpleValidElementCount = nSimpleValidElementCount;
for (int32_t nCurrentSimpleIndex = 0; nCurrentSimpleIndex < nSimpleValidElementCount; ++nCurrentSimpleIndex)
{
fill_simple_struct(sCurrentStructArray.sSimple[nCurrentSimpleIndex], fOutValue);
}
}
const uint64_t nArrayValidElementCount = bValid ? 15 : 30;
oOutputData->nArrayValidElementCount = nArrayValidElementCount;
for (uint64_t nArrayIndex = 0; nArrayIndex < nArrayValidElementCount; ++nArrayIndex)
{
oOutputData->nArray[nArrayIndex] = static_cast<int64_t>(fOutValue);
}
oOutputData->bValueValid = bValid;
oOutputData->nValue = static_cast<int64_t>(fOutValue);
m_pWriterArraysWithValidElementCount->Write(oOutputData.Release());
++m_nValidElementCountCounter;
}
#define ADTF_PLUGIN(__plugin_identifier,...)
Definition adtf_plugin.h:29
#define LOG_INFO(...)
Logs an info message.
Definition log.h:388
#define RETURN_ERROR_DESC(_code,...)
Same as RETURN_ERROR(_error) using a printf like parameter list for detailed error description.
Definition result.h:44
#define RETURN_NOERROR
Return status ERR_NOERROR, which requires the calling function's return type to be tResult.
Definition result.h:29
Generator template to create an instance of a ant::IStreamType class for penguin::stream_meta_type_pl...
Definition streammetatypeplain.h:315
Namespace for the ADTF Base SDK.
Definition adtf_base_type_traits.h:13
Namespace for the ADTF Filter SDK.
Definition configurable_runner.h:18
Namespace for the ADTF Streaming SDK.
Definition bindingproxyinport.h:14
Namespace for the ADTF uCOM SDK.
Definition adtf_system.h:324
definition of the ddl namespace
Definition codec.h:21