blob: 5ef36a2802e497afb41c66489195e4879a51422f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Johannes Kepler University
*
* 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.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Alois Zoitl - initial implementation and rework communication infrastructure
*******************************************************************************/
#ifdef FORTE_ENABLE_GENERATED_SOURCE_CPP
#include "forte_any_gen.cpp"
#endif
template<class T>
CGenFunctionBlock<T>::CGenFunctionBlock(CResource *paSrcRes, const CStringDictionary::TStringId paInstanceNameId) :
T(paSrcRes, 0, paInstanceNameId, 0, 0),
mConfiguredFBTypeNameId(CStringDictionary::scm_nInvalidStringId), mGenInterfaceSpec(), mFBConnData(0), mFBVarsData(0) {
FORTE_STATIC_ASSERT((forte::core::mpl::is_base_of<CFunctionBlock, T>::value), TFunctionBlock);
}
template<class T>
CGenFunctionBlock<T>::~CGenFunctionBlock(){
if(0 != T::m_pstInterfaceSpec){
T::freeAllData(); //clean the interface and connections first.
delete[] mFBConnData;
delete[] mFBVarsData;
T::m_pstInterfaceSpec = 0; //this stops the base classes from any wrong clean-up
}
}
template<class T>
bool CGenFunctionBlock<T>::configureFB(const char *paConfigString){
setConfiguredTypeNameId(CStringDictionary::getInstance().insert(paConfigString));
if(createInterfaceSpec(paConfigString, mGenInterfaceSpec)){
mFBConnData = new TForteByte[T::genFBConnDataSize(mGenInterfaceSpec.m_nNumEOs, mGenInterfaceSpec.m_nNumDIs, mGenInterfaceSpec.m_nNumDOs)];
mFBVarsData = new TForteByte[T::genFBVarsDataSize(mGenInterfaceSpec.m_nNumDIs, mGenInterfaceSpec.m_nNumDOs)];
T::setupFBInterface(&mGenInterfaceSpec, mFBConnData, mFBVarsData);
return true;
}
return false;
}
template<class T>
void CGenFunctionBlock<T>::generateGenericInterfacePointNameArray(const char * const paPrefix, CStringDictionary::TStringId* paNamesArayStart,
size_t paNumGenericDataPoints) {
size_t len = strlen(paPrefix);
unsigned int noOfDigits = 0;
{
size_t tempNum = paNumGenericDataPoints;
while(tempNum){
tempNum /= 10;
noOfDigits++;
}
}
if(cg_nIdentifierLength >= (len + noOfDigits)){
TIdentifier acBuffer;
memcpy(acBuffer, paPrefix, len);
for(size_t i = 0; i <= noOfDigits; i++){
acBuffer[len + i] = '\0';
}
for(size_t i = 1; i <= paNumGenericDataPoints; i++) {
if(i < 10){ //1 digit
acBuffer[len] = static_cast<char>(0x30 + i);
}
else if(i < 100){ //2 digits
if(0 == i % 10){
acBuffer[len] = static_cast<char>(0x30 + (i % 100 / 10));
}
acBuffer[len + 1] = static_cast<char>(0x30 + i % 10);
}
else{ //3 digits
if(0 == i % 100){
acBuffer[len] = static_cast<char>(0x30 + (i / 100));
}
if(0 == i % 10){
acBuffer[len + 1] = static_cast<char>(0x30 + (i % 100 / 10));
}
acBuffer[len + 2] = static_cast<char>(0x30 + i % 10);
}
paNamesArayStart[i - 1] = CStringDictionary::getInstance().insert(acBuffer);
}
}
else{
DEVLOG_ERROR("CFunctionBlock::generateGenericInterfacePointNameArray won't be able to create all the generics since %s is too long to hold until %d", paPrefix, paNumGenericDataPoints);
}
}
template<class T>
void CGenFunctionBlock<T>::generateGenericDataPointArrays(const char * const paPrefix, CStringDictionary::TStringId* paDataTypeNamesArrayStart,
CStringDictionary::TStringId* paNamesArrayStart, size_t paNumGenericDataPoints) {
generateGenericInterfacePointNameArray(paPrefix, paNamesArrayStart, paNumGenericDataPoints);
for(size_t i = 0; i < paNumGenericDataPoints; i++){
paDataTypeNamesArrayStart[i] = g_nStringIdANY;
}
}