2025-03-12 11:08:50 +08:00

586 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/******************************************************************************//**
* @file FbdDiagDataImpl.cpp
* @brief 功能块图Diagram数据接口实现
* @author yikenan
* @version 1.0
* @date 2020/12/7
**********************************************************************************/
//< 屏蔽Protobuf编译告警
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4100)
#endif
#include "FBD.pb.h"
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#include "boost/weak_ptr.hpp"
#include "app_fbd/fbd_common/FbdSysInfoApi.h"
#include "FbdDiagDataImpl.h"
namespace kbd_app
{
namespace app_fbd
{
//< 弱指针,观察者模式
static boost::weak_ptr<CFbdDiagDataImpl> g_wpSingleton;
//< 保护 g_wpSingleton
static boost::mutex g_mutexSingleton;
//< 获取单例
FBD_COMMON_API CFbdDiagDataApiPtr getFbdDiagDataApi()
{
CFbdDiagDataImplPtr spInst = g_wpSingleton.lock();
if ( nullptr != spInst )
return spInst;
boost::mutex::scoped_lock lock( g_mutexSingleton );
spInst = g_wpSingleton.lock();
if ( nullptr != spInst )
return spInst;
spInst = boost::make_shared<CFbdDiagDataImpl>();
if ( kbdSuccess == spInst->initialize())
{
g_wpSingleton = spInst;
return spInst;
}
return nullptr;
}
/***********************************************************************************************/
CFbdDiagDataImpl::CFbdDiagDataImpl()
: m_pRdbTableMng( nullptr )
{
m_pMutexModInfoTable = new boost::shared_mutex;
m_pMutexModInputTable = new boost::shared_mutex;
m_pMutexModOutputTable = new boost::shared_mutex;
m_pMutexModPropTable = new boost::shared_mutex;
}
CFbdDiagDataImpl::~CFbdDiagDataImpl()
{
delete m_pRdbTableMng;
m_pRdbTableMng = nullptr;
delete m_pMutexModInfoTable;
m_pMutexModInfoTable = nullptr;
delete m_pMutexModInputTable;
m_pMutexModInputTable = nullptr;
delete m_pMutexModOutputTable;
m_pMutexModOutputTable = nullptr;
delete m_pMutexModPropTable;
m_pMutexModPropTable = nullptr;
}
int CFbdDiagDataImpl::initialize()
{
if ( nullptr == m_pRdbTableMng )
{
CFbdSysInfoApiPtr ptrSysInfo = getFbdSysInfoApi();
if ( nullptr == ptrSysInfo || ptrSysInfo->getCurrentRunAppInfo().strAppName.empty())
{
LOGERROR( "initialize(): 系统信息非预期,检查程序!" );
return kbdFailed;
}
m_pRdbTableMng = new kbd_dbms::CRdbTableMng( getFbdSysInfoApi()->getCurrentRunAppInfo().strAppName );
}
if ( nullptr == m_pRdbTableMng || nullptr == m_pMutexModInfoTable || nullptr == m_pMutexModInputTable
|| nullptr == m_pMutexModOutputTable || nullptr == m_pMutexModPropTable )
{
LOGERROR( "initialize(): 空指针,非预期,检查程序!" );
return kbdFailed;
}
return kbdSuccess;
}
int CFbdDiagDataImpl::getModProperty( const SFbdModPropKey &stPropertyKey, std::string &strValue ) const
{
strValue.clear();
if ( !stPropertyKey.isValid())
{
LOGERROR( "getModProperty(): 无效的输入 stPropertyKey返回失败" );
return kbdFailed;
}
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModInfoTable );
const auto &indexKey = m_objModPropTable.get<SFbdModProperty_Key>();
const auto it = indexKey.find( stPropertyKey );
if ( indexKey.end() == it )
{
LOGERROR( "getModProperty(): m_objModPropTable 中未找到记录 Key=[%s]",
stPropertyKey.toString().c_str());
return kbdFailed;
}
strValue = ( *it )->m_strValue;
return kbdSuccess;
}
int CFbdDiagDataImpl::getValKeyByModInput( const SFbdModInputKey &stInputKey, SFbdValueKey &stValueKey ) const
{
stValueKey.m_ptrModOutput = nullptr;
if ( !stInputKey.isValid())
{
LOGERROR( "getValKeyByModInput(): 无效的输入 stInputKey返回失败" );
return kbdFailed;
}
SFbdModOutputKey stOutputKey;
{
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModInputTable );
const auto &indexKey = m_objModInputTable.get<SFbdModInput_Key>();
const auto it = indexKey.find( stInputKey );
if ( indexKey.end() == it )
{
LOGERROR( "getValKeyByModInput(): m_objModInputTable 中未找到记录 Key=[%s]",
stInputKey.toString().c_str());
return kbdFailed;
}
stOutputKey = ( *it )->m_stOutputKey;
}
{
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
const auto &indexKey = m_objModOutputTable.get<SFbdModOutput_Key>();
const auto it = indexKey.find( stOutputKey );
if ( indexKey.end() == it )
{
LOGERROR( "getValKeyByModInput(): m_objModOutputTable 中未找到记录 Key=[%s]",
stOutputKey.toString().c_str());
return kbdFailed;
}
stValueKey.m_bWriteable = false;
stValueKey.m_ptrModOutput = *it;
}
if ( stValueKey.isValid())
return kbdSuccess;
LOGERROR( "getValKeyByModInput(): 无效的输出,检查程序!" );
return kbdFailed;
}
int CFbdDiagDataImpl::getValKeyByModOutput( const SFbdModOutputKey &stOutputKey, SFbdValueKey &stValueKey ) const
{
stValueKey.m_ptrModOutput = nullptr;
if ( !stOutputKey.isValid())
{
LOGERROR( "getValKeyByModOutput(): 无效的输入 stOutputKey返回失败" );
return kbdFailed;
}
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
const auto &indexKey = m_objModOutputTable.get<SFbdModOutput_Key>();
const auto it = indexKey.find( stOutputKey );
if ( indexKey.end() == it )
{
LOGERROR( "getValKeyByModOutput(): m_objModOutputTable 中未找到记录 Key=[%s]",
stOutputKey.toString().c_str());
return kbdFailed;
}
stValueKey.m_bWriteable = true;
stValueKey.m_ptrModOutput = *it;
if ( stValueKey.isValid())
return kbdSuccess;
LOGERROR( "getValKeyByModOutput(): 无效的输出,检查程序!" );
return kbdFailed;
}
int CFbdDiagDataImpl::getNumericValByKey( const SFbdValueKey &stValueKey, SFbdNumericValue &stValAndSta ) const
{
stValAndSta.m_nStatus = CN_FBD_STATUS_Invalid;
if ( !stValueKey.isValid())
{
LOGERROR( "getNumericValByKey(): 无效的输入 stValueKey返回失败" );
return kbdFailed;
}
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
const SFbdNumericValue *pValue =
boost::any_cast<SFbdNumericValue>( &( stValueKey.m_ptrModOutput->m_anyOutputValue ));
if ( nullptr == pValue )
{
LOGERROR( "getNumericValByKey(): 类型不一致key=[%s],type=[%s]",
stValueKey.toString().c_str(),
stValueKey.m_ptrModOutput->m_anyOutputValue.type().name());
return kbdFailed;
}
stValAndSta = *pValue;
return kbdSuccess;
}
int CFbdDiagDataImpl::setNumericValByKey( const SFbdValueKey &stValueKey, const SFbdNumericValue &stValAndSta )
{
if ( !stValueKey.isValid())
{
LOGERROR( "setNumericValByKey(): 无效的输入 stValueKey返回失败" );
return kbdFailed;
}
if ( !stValueKey.m_bWriteable )
{
LOGERROR( "setNumericValByKey(): 非可写 Key" );
return kbdFailed;
}
//< 写锁
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
stValueKey.m_ptrModOutput->m_anyOutputValue = stValAndSta;
return kbdSuccess;
}
int CFbdDiagDataImpl::getStringValByKey( const SFbdValueKey &stValueKey, SFbdStringValue &stValAndSta ) const
{
stValAndSta.m_nStatus = CN_FBD_STATUS_Invalid;
if ( !stValueKey.isValid())
{
LOGERROR( "getStringValByKey(): 无效的输入 stValueKey返回失败" );
return kbdFailed;
}
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
const SFbdStringValue *pValue =
boost::any_cast<SFbdStringValue>( &( stValueKey.m_ptrModOutput->m_anyOutputValue ));
if ( nullptr == pValue )
{
LOGERROR( "getStringValByKey(): 类型不一致key=[%s],type=[%s]",
stValueKey.toString().c_str(),
stValueKey.m_ptrModOutput->m_anyOutputValue.type().name());
return kbdFailed;
}
stValAndSta = *pValue;
return kbdSuccess;
}
int CFbdDiagDataImpl::setStringValByKey( const SFbdValueKey &stValueKey, const SFbdStringValue &stValAndSta )
{
if ( !stValueKey.isValid())
{
LOGERROR( "setStringValByKey(): 无效的输入 stValueKey返回失败" );
return kbdFailed;
}
if ( !stValueKey.m_bWriteable )
{
LOGERROR( "setStringValByKey(): 非可写 Key" );
return kbdFailed;
}
//< 写锁
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
stValueKey.m_ptrModOutput->m_anyOutputValue = stValAndSta;
return kbdSuccess;
}
int CFbdDiagDataImpl::getAlarmValByKey( const SFbdValueKey &stValueKey, SFbdAlarmValue &stValAndSta ) const
{
stValAndSta.m_nStatus = CN_FBD_STATUS_Invalid;
if ( !stValueKey.isValid())
{
LOGERROR( "getAlarmValByKey(): 无效的输入 stValueKey返回失败" );
return kbdFailed;
}
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
const SFbdAlarmValue *pValue =
boost::any_cast<SFbdAlarmValue>( &( stValueKey.m_ptrModOutput->m_anyOutputValue ));
if ( nullptr == pValue )
{
LOGERROR( "getAlarmValByKey(): 类型不一致key=[%s],type=[%s]",
stValueKey.toString().c_str(),
stValueKey.m_ptrModOutput->m_anyOutputValue.type().name());
return kbdFailed;
}
stValAndSta = *pValue;
return kbdSuccess;
}
int CFbdDiagDataImpl::setAlarmValByKey( const SFbdValueKey &stValueKey, const SFbdAlarmValue &stValAndSta )
{
if ( !stValueKey.isValid())
{
LOGERROR( "setAlarmValByKey(): 无效的输入 stValueKey返回失败" );
return kbdFailed;
}
if ( !stValueKey.m_bWriteable )
{
LOGERROR( "setAlarmValByKey(): 非可写 Key" );
return kbdFailed;
}
//< 写锁
boost::unique_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
stValueKey.m_ptrModOutput->m_anyOutputValue = stValAndSta;
return kbdSuccess;
}
/***********************************************************************************************/
int CFbdDiagDataImpl::getAllGroupInfo( std::vector<SFbdGroupInfo> &vecGrpInfo ) const
{
static const std::string strTableName = CN_TN_FbdGroup;
kbd_dbms::CRdbTableMngLockGuard lock( *m_pRdbTableMng, strTableName );
if ( !m_pRdbTableMng->selectAllColumnNoCondition( strTableName, vecGrpInfo ))
{
LOGERROR( "getAllGroupInfo(): 从RDB获取FBD组信息失败" );
return kbdFailed;
}
return kbdSuccess;
}
int CFbdDiagDataImpl::getModuleInfoByGroup( const int nFbdGrpId, std::vector<SFbdModInfo> &vecModuleInfo ) const
{
vecModuleInfo.clear();
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModInfoTable );
const auto &indexGrpId = m_objModInfoTable.get<SFbdModInfo_GrpId>();
const size_t nCount = indexGrpId.count( nFbdGrpId );
if ( 0 == nCount )
{
//< 允许空组,不作为错误
LOGWARN( "getModuleInfoByGroup(): m_objModInfoTable 中未找到记录 GroupId=[%d],返回成功", nFbdGrpId );
return kbdSuccess;
}
//< 预先分配空间,避免频繁内存移动
vecModuleInfo.reserve( nCount + 1 );
const auto pairRange = indexGrpId.equal_range( nFbdGrpId );
for ( auto it = pairRange.first; pairRange.second != it; ++it )
{
vecModuleInfo.emplace_back( **it );
}
return kbdSuccess;
}
int CFbdDiagDataImpl::deleteAllDataByGroup( const int nFbdGrpId )
{
LOGINFO( "deleteAllDataByGroup(): 开始删除组 GrpId=[%d]", nFbdGrpId );
//< 写锁
boost::unique_lock<boost::shared_mutex> lockModInfo( *m_pMutexModInfoTable );
auto &indexGrpId = m_objModInfoTable.get<SFbdModInfo_GrpId>();
const auto pairModInfo = indexGrpId.equal_range( nFbdGrpId );
if ( pairModInfo.first == pairModInfo.second )
{
LOGWARN( "deleteAllDataByGroup(): m_objModInfoTable 中未找到记录 GroupId=[%d],返回成功", nFbdGrpId );
return kbdSuccess;
}
//< 按图名删除其他表中的记录
{
//< 用于图名去重
std::set<std::string> setDiagName;
//< 写锁
boost::unique_lock<boost::shared_mutex> lockModInput( *m_pMutexModInputTable );
boost::unique_lock<boost::shared_mutex> lockModOutput( *m_pMutexModOutputTable );
boost::unique_lock<boost::shared_mutex> lockModProp( *m_pMutexModPropTable );
auto &indexDiagName_Input = m_objModInputTable.get<SFbdModInput_DiagName>();
auto &indexDiagName_Output = m_objModOutputTable.get<SFbdModOutput_DiagName>();
auto &indexDiagName_Prop = m_objModPropTable.get<SFbdModProperty_DiagName>();
for ( auto itModInfo = pairModInfo.first; pairModInfo.second != itModInfo; ++itModInfo )
{
const std::string &strDiagName = ( *itModInfo )->getDiagName();
if ( setDiagName.count( strDiagName ) != 0 )
{
continue; //< 剔除重复的图名
}
setDiagName.insert( strDiagName );
indexDiagName_Input.erase( strDiagName );
indexDiagName_Output.erase( strDiagName );
indexDiagName_Prop.erase( strDiagName );
}
}
//< 删除 ModInfoTable 中的记录
indexGrpId.erase( nFbdGrpId );
return kbdSuccess;
}
int CFbdDiagDataImpl::insertAllDataByGroup( const SFbdGroupInfo &stGrpInfo, const SFbdGroupData &stGrpData )
{
LOGINFO( "insertAllDataByGroup(): 开始插入组 Id=[%d], BusinessType=[%d], Name=[%s], Desc=[%s]",
stGrpInfo.m_nId, stGrpInfo.m_nBusinessType, stGrpInfo.m_szName, stGrpInfo.m_szDesc );
//< m_objModInfoTable
{
//< 写锁
boost::unique_lock<boost::shared_mutex> lockModInfo( *m_pMutexModInfoTable );
for ( const auto &ptrModInfo : stGrpData.m_vecPtrModInfo )
{
const auto &pairRc = m_objModInfoTable.insert( ptrModInfo );
if ( !pairRc.second )
{
LOGERROR( "insertAllDataByGroup(): 向 m_objModInfoTable 插入失败 mod_key=[%s]",
ptrModInfo->m_stModKey.toString().c_str());
}
}
}
//< m_objModInputTable
{
//< 写锁
boost::unique_lock<boost::shared_mutex> lockModInput( *m_pMutexModInputTable );
for ( const auto &ptrModInput : stGrpData.m_vecPtrModInput )
{
const auto &pairRc = m_objModInputTable.insert( ptrModInput );
if ( !pairRc.second )
{
LOGERROR( "insertAllDataByGroup(): 向 m_objModInputTable 插入失败 Key=[%s]",
ptrModInput->m_stInputKey.toString().c_str());
}
}
}
//< m_objModOutputTable
{
//< 写锁
boost::unique_lock<boost::shared_mutex> lockModOutput( *m_pMutexModOutputTable );
for ( const auto &ptrModOutput : stGrpData.m_vecPtrModOutput )
{
const auto &pairRc = m_objModOutputTable.insert( ptrModOutput );
if ( !pairRc.second )
{
LOGERROR( "insertAllDataByGroup(): 向 m_objModOutputTable 插入失败 Key=[%s]",
ptrModOutput->m_stOutputKey.toString().c_str());
}
}
}
//< m_objModPropTable
{
//< 写锁
boost::unique_lock<boost::shared_mutex> lockModProp( *m_pMutexModPropTable );
for ( const auto &ptrModProp : stGrpData.m_vecPtrModProp )
{
const auto &pairRc = m_objModPropTable.insert( ptrModProp );
if ( !pairRc.second )
{
LOGERROR( "insertAllDataByGroup(): 向 m_objModPropTable 插入失败 Key=[%s]",
ptrModProp->m_stPropKey.toString().c_str());
}
}
}
return kbdSuccess;
}
int CFbdDiagDataImpl::getDebugResponse( const kbd_idlfile::SFBDDebugRequest &objReq,
kbd_idlfile::SFBDDebugResponse &objRep )
{
const std::string &strDiagName = objReq.sdiagramname();
objRep.set_ngroupid( objReq.ngroupid());
objRep.set_sdiagramname( strDiagName );
int nStatus;
//< 读锁
boost::shared_lock<boost::shared_mutex> lock( *m_pMutexModOutputTable );
const auto &indexDiagName = m_objModOutputTable.get<SFbdModOutput_DiagName>();
const auto pairModOutput = indexDiagName.equal_range( strDiagName );
for ( auto it = pairModOutput.first; it != pairModOutput.second; ++it )
{
const SFbdModOutput &stModOutput = *( *it );
auto pDbgData = objRep.add_vecblock();
pDbgData->set_sinstancename( stModOutput.m_stOutputKey.m_stModKey.m_strModName );
pDbgData->set_noutportindex( stModOutput.m_stOutputKey.m_nOutputIndex );
stModOutput.getValueString( nStatus, *( pDbgData->mutable_svalue()));
pDbgData->set_nvalid( nStatus );
}
return kbdSuccess;
}
} //< namespace app_fbd
} //< namespace kbd_app