From 659f495faf8a7ef126fa21fb4e13e7f1362f3ab5 Mon Sep 17 00:00:00 2001 From: Martin Jobst Date: Wed, 25 Sep 2024 17:54:13 +0200 Subject: [PATCH] Add generic event accessors Add generic event accessors to enable usage of network FBs as internal FBs. --- src/core/genfb.h | 64 +++++++++++++++++++++++++++- src/stdfblib/net/GEN_CLIENT_fbt.h | 31 ++++++++++++-- src/stdfblib/net/GEN_PUBLISH_fbt.h | 34 ++++++++++++--- src/stdfblib/net/GEN_SERVER_fbt.h | 29 +++++++++++-- src/stdfblib/net/GEN_SUBSCRIBE_fbt.h | 27 +++++++++++- 5 files changed, 170 insertions(+), 15 deletions(-) diff --git a/src/core/genfb.h b/src/core/genfb.h index 07662553e..67cdbfb8a 100644 --- a/src/core/genfb.h +++ b/src/core/genfb.h @@ -1,5 +1,6 @@ /******************************************************************************* - * Copyright (c) 2018 Johannes Kepler University + * Copyright (c) 2018, 2024 Johannes Kepler University + * Martin Erich Jobst * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at @@ -9,6 +10,7 @@ * * Contributors: * Alois Zoitl - initial implementation and rework communication infrastructure + * Martin Erich Jobst - add generic event accessor helpers *******************************************************************************/ #ifndef _GENFB_H_ #define _GENFB_H_ @@ -65,6 +67,66 @@ class CGenFunctionBlock : public T { bool initialize(); + template + void writeArguments(Args &&...paArgs) { + TPortId index = 0; + (writeArgument(index++, std::forward(paArgs)), ...); + } + + template + void writeArgument(TPortId paIndex, const Arg &paArg) { + const SFBInterfaceSpec &interfaceSpec = T::getFBInterfaceSpec(); + if (paIndex < interfaceSpec.mNumDIs) { + T::getDIFromPortId(paIndex)->setValue(paArg); + } else if (paIndex < interfaceSpec.mNumDIs + interfaceSpec.mNumDIOs) { + T::getDIOFromPortId(paIndex - interfaceSpec.mNumDIs)->setValue(paArg); + } else if (paIndex < interfaceSpec.mNumDIs + interfaceSpec.mNumDIOs + interfaceSpec.mNumDOs) { + T::getDOFromPortId(paIndex - interfaceSpec.mNumDIs - interfaceSpec.mNumDIOs)->setValue(paArg); + } + } + + template + void writeInputArguments(Args &&...paArgs) { + TPortId index = 0; + (writeInputArgument(index++, std::forward(paArgs)), ...); + } + + template + void writeInputArgument(TPortId paIndex, const Arg &paArg) { + const SFBInterfaceSpec &interfaceSpec = T::getFBInterfaceSpec(); + if (paIndex < interfaceSpec.mNumDIs) { + T::getDIFromPortId(paIndex)->setValue(paArg); + } else if (paIndex < interfaceSpec.mNumDIs + interfaceSpec.mNumDIOs) { + T::getDIOFromPortId(paIndex - interfaceSpec.mNumDIs)->setValue(paArg); + } // skip DO + } + + template + void readOutputArguments(Args &&...paArgs) { + TPortId index = 0; + (readOutputArgument(index++, std::forward(paArgs)), ...); + } + + template + void readOutputArgument(TPortId paIndex, Arg &&paArg) { + const SFBInterfaceSpec &interfaceSpec = T::getFBInterfaceSpec(); + if (paIndex < interfaceSpec.mNumDIs) { + // do nothing + } else if (paIndex < interfaceSpec.mNumDIs + interfaceSpec.mNumDIOs) { + if constexpr (std::is_const_v>) { + DEVLOG_ERROR("[CGenFunctionBlock] Trying to pass const argument to in/out variable\n"); + } else { + paArg.setValue(T::getDIOFromPortId(paIndex - interfaceSpec.mNumDIs)->unwrap()); + } + } else if (paIndex < interfaceSpec.mNumDIs + interfaceSpec.mNumDIOs + interfaceSpec.mNumDOs) { + if constexpr (std::is_const_v>) { + DEVLOG_ERROR("[CGenFunctionBlock] Trying to pass const argument to output variable\n"); + } else { + paArg.setValue(T::getDOFromPortId(paIndex - interfaceSpec.mNumDIs - interfaceSpec.mNumDIOs)->unwrap()); + } + } + } + static void generateGenericInterfacePointNameArray(const char * const paPrefix, CStringDictionary::TStringId* paNamesArayStart, size_t paNumGenericDataPoints); diff --git a/src/stdfblib/net/GEN_CLIENT_fbt.h b/src/stdfblib/net/GEN_CLIENT_fbt.h index 2711ed0aa..948466f6d 100644 --- a/src/stdfblib/net/GEN_CLIENT_fbt.h +++ b/src/stdfblib/net/GEN_CLIENT_fbt.h @@ -1,5 +1,7 @@ /******************************************************************************* - * Copyright (c) 2006 - 2011 ACIN, Profactor GmbH + * Copyright (c) 2006, 2024 ACIN, Profactor GmbH + * Martin Erich Jobst + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -9,6 +11,8 @@ * Contributors: * Alois Zoitl, Rene Smodic, Gerhard Ebenhofer, Martin Melik Merkumians * - initial API and implementation and/or initial documentation + * Martin Erich Jobst + * - add generic event accessors *******************************************************************************/ #ifndef _GEN_CLIENT_H_ #define _GEN_CLIENT_H_ @@ -22,10 +26,29 @@ class GEN_CLIENT : public forte::com_infra::CCommFB { DECLARE_GENERIC_FIRMWARE_FB(GEN_CLIENT) -public: - GEN_CLIENT(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); - ~GEN_CLIENT() override = default; + public: + GEN_CLIENT(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); + + ~GEN_CLIENT() override = default; + + template + void evt_INIT(Args &&...paArgs) { + writeInputArguments(std::forward(paArgs)...); + receiveInputEvent(scmEventINITID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + + template + void evt_REQ(Args &&...paArgs) { + writeInputArguments(std::forward(paArgs)...); + receiveInputEvent(scmSendNotificationEventID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + template + void operator()(Args &&...paArgs) { + evt_INIT(std::forward(paArgs)...); + } }; #endif //_GEN_CLIENT_H_ diff --git a/src/stdfblib/net/GEN_PUBLISH_fbt.h b/src/stdfblib/net/GEN_PUBLISH_fbt.h index bafcc736a..fc9dcfc93 100644 --- a/src/stdfblib/net/GEN_PUBLISH_fbt.h +++ b/src/stdfblib/net/GEN_PUBLISH_fbt.h @@ -1,5 +1,7 @@ /******************************************************************************* - * Copyright (c) 2006 - 2011 ACIN, Profactor GmbH + * Copyright (c) 2006, 2024 ACIN, Profactor GmbH + * Martin Erich Jobst + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -9,6 +11,8 @@ * Contributors: * Alois Zoitl, Rene Smodic, Gerhard Ebenhofer, Martin Melik Merkumians * - initial API and implementation and/or initial documentation + * Martin Erich Jobst + * - add generic event accessors *******************************************************************************/ #ifndef _GEN_PUBLISH_H_ #define _GEN_PUBLISH_H_ @@ -19,11 +23,31 @@ */ class GEN_PUBLISH : public forte::com_infra::CCommFB { -DECLARE_GENERIC_FIRMWARE_FB(GEN_PUBLISH) + DECLARE_GENERIC_FIRMWARE_FB(GEN_PUBLISH) + + public: + GEN_PUBLISH(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); + + ~GEN_PUBLISH() override = default; + + template + void evt_INIT(Args&& ...paArgs) { + writeInputArguments(std::forward(paArgs)...); + receiveInputEvent(scmEventINITID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + + template + void evt_REQ(Args&& ...paArgs) { + writeInputArguments(std::forward(paArgs)...); + receiveInputEvent(scmSendNotificationEventID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } -public: - GEN_PUBLISH(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); - ~GEN_PUBLISH() override = default; + template + void operator()(Args&& ...paArgs) { + evt_INIT(std::forward(paArgs)...); + } }; #endif //_GEN_PUBLISH_H_ diff --git a/src/stdfblib/net/GEN_SERVER_fbt.h b/src/stdfblib/net/GEN_SERVER_fbt.h index 93dbc586d..c4e9d60fe 100644 --- a/src/stdfblib/net/GEN_SERVER_fbt.h +++ b/src/stdfblib/net/GEN_SERVER_fbt.h @@ -1,5 +1,7 @@ /******************************************************************************* - * Copyright (c) 2006 - 2011 ACIN, Profactor GmbH + * Copyright (c) 2006, 2024 ACIN, Profactor GmbH + * Martin Erich Jobst + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -9,6 +11,8 @@ * Contributors: * Rene Smodic, Alois Zoitl, Gerhard Ebenhofer, Martin Melik Merkumians * - initial API and implementation and/or initial documentation + * Martin Erich Jobst + * - add generic event accessors *******************************************************************************/ #ifndef _GEN_SERVER_H_ #define _GEN_SERVER_H_ @@ -19,12 +23,31 @@ * */ -class GEN_SERVER: public forte::com_infra::CCommFB { - DECLARE_GENERIC_FIRMWARE_FB(GEN_SERVER) +class GEN_SERVER : public forte::com_infra::CCommFB { + DECLARE_GENERIC_FIRMWARE_FB(GEN_SERVER) public: GEN_SERVER(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); + ~GEN_SERVER() override = default; + template + void evt_INIT(Args &&...paArgs) { + writeArguments(std::forward(paArgs)...); // write all arguments to get type information + receiveInputEvent(scmEventINITID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + + template + void evt_RSP(Args &&...paArgs) { + writeInputArguments(std::forward(paArgs)...); + receiveInputEvent(scmSendNotificationEventID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + + template + void operator()(Args &&...paArgs) { + evt_INIT(std::forward(paArgs)...); + } }; #endif //_GEN_SERVER_H_ diff --git a/src/stdfblib/net/GEN_SUBSCRIBE_fbt.h b/src/stdfblib/net/GEN_SUBSCRIBE_fbt.h index 34aa84c31..9dc46488f 100644 --- a/src/stdfblib/net/GEN_SUBSCRIBE_fbt.h +++ b/src/stdfblib/net/GEN_SUBSCRIBE_fbt.h @@ -1,5 +1,7 @@ /******************************************************************************* - * Copyright (c) 2006 - 2011 ACIN, Profactor GmbH + * Copyright (c) 2006, 2024 ACIN, Profactor GmbH + * Martin Erich Jobst + * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. @@ -9,6 +11,8 @@ * Contributors: * Rene Smodic, Alois Zoitl, Gerhard Ebenhofer, Martin Melik Merkumians * - initial API and implementation and/or initial documentation + * Martin Erich Jobst + * - add generic event accessors *******************************************************************************/ #ifndef _GEN_SUBSCRIBE_H_ #define _GEN_SUBSCRIBE_H_ @@ -20,12 +24,31 @@ class GEN_SUBSCRIBE : public forte::com_infra::CCommFB { - DECLARE_GENERIC_FIRMWARE_FB(GEN_SUBSCRIBE) + DECLARE_GENERIC_FIRMWARE_FB(GEN_SUBSCRIBE) public: GEN_SUBSCRIBE(const CStringDictionary::TStringId paInstanceNameId, forte::core::CFBContainer &paContainer); + ~GEN_SUBSCRIBE() override = default; + template + void evt_INIT(Args &&...paArgs) { + writeArguments(std::forward(paArgs)...); // write all arguments to get type information + receiveInputEvent(scmEventINITID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + + template + void evt_RSP(Args &&...paArgs) { + writeInputArguments(std::forward(paArgs)...); + receiveInputEvent(scmSendNotificationEventID, nullptr); + readOutputArguments(std::forward(paArgs)...); + } + + template + void operator()(Args &&...paArgs) { + evt_INIT(std::forward(paArgs)...); + } }; #endif //_GEN_SUBSCRIBE_H_