📄 opcdrvgroup.cpp
字号:
////////////////////////////////////////////////////////////////
// COPCDrvGroup::SetActive()
//
// Sets the active state for the group. If the group is going
// active, then it will queue an OnDataChange() for each item
// in its list. If it is going inactive, then it will clear any
// OnDataChange()'s for each active item is its list.
//
// Returns:
// void
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::SetActive(BOOL bNewActiveState)
{
COPCDrvItem *pItem = NULL;
POSITION posItem = NULL;
OPCHANDLE OPCHandle = 0;
DWORD dwNumItems = 0;
Lock();
// If no change in state, then we don't want to queue or
// clear any OnDataChange() bits for the items.
//
if (bNewActiveState == m_bActive)
{
UnLock();
return;
}
m_bActive = bNewActiveState;
// Loop through each item in the list.
//
dwNumItems = GetNumItemHandles();
posItem = m_mapItem.GetStartPosition();
for (DWORD j = 0; j < dwNumItems; j++)
{
m_mapItem.GetNextAssoc(posItem, OPCHandle, pItem);
if (pItem->GetActive())
{
pItem->Lock();
if (this->m_bActive)
{
// Going active, so queue OnDataChange()
//
pItem->MarkAsChanged(OPC_ODC_ANY);
}
else
{
// Going inactive, so clear OnDataChange()
//
pItem->ClearChanged(OPC_ODC_ANY);
}
pItem->UnLock();
}
}
UnLock();
}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::GetActive()
//
// Returns the active state of the group.
//
// NOTE: This is an inline function defined in OpcDrv.h!!!
//
////////////////////////////////////////////////////////////////
//BOOL COPCDrvGroup::GetActive(void)
//{
// return this->m_bActive;
//}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::SetUpdateRate()
//
// Sets the update rate of the group with validation.
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::SetUpdateRate(DWORD dwRequestedRate,
DWORD *pReviseRate)
{
// Validate the UpdateRate
//
if (dwRequestedRate < g_dwWaitPeriod)
{
m_dwRevisedRate = g_dwWaitPeriod;
}
else
{
m_dwRevisedRate = dwRequestedRate;
}
// Return the revised rate, if necessary.
//
if (pReviseRate)
{
*pReviseRate = m_dwRevisedRate;
}
}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::GetUpdateRate()
//
// Returns the update rate of the group
//
// NOTE: This is an inline function defined in OpcDrv.h!!!
//
////////////////////////////////////////////////////////////////
//DWORD COPCDrvGroup::GetUpdateRate(void)
//{
// return this->m_dwRevisedRate;
//}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::GetItemList()
//
// Create a list of all the item attributes in Local Memory
//
// Note that local heap is used and that caller must free the
// list using FreeItemList
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::GetItemList(OPCITEMATTRIBUTES **AttrList,
int *ItemCount)
{
int nNumItems;
OPCITEMATTRIBUTES *myAttr;
POSITION ItemPosition;
COPCDrvItem *pItem;
OPCHANDLE OPCHandle;
*ItemCount = 0;
// Lock the group object
//
Lock();
// Get the info about the item list
//
nNumItems = GetNumItemHandles();
ItemPosition = m_mapItem.GetStartPosition();
// If there are no items in this group, then there is nothing
// to put in the list, so return.
//
if((0 == nNumItems) || (NULL == ItemPosition))
{
UnLock();
return;
}
*AttrList = myAttr = new OPCITEMATTRIBUTES[nNumItems];
if (NULL == myAttr)
{
UnLock();
return;
}
// Copy the requested data
for (int j = 0; j < nNumItems; j++)
{
m_mapItem.GetNextAssoc(ItemPosition, OPCHandle, pItem);
pItem->IAGet(&myAttr[*ItemCount]);
(*ItemCount)++;
}
// Unlock the group object.
//
UnLock();
}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::FreeItemList()
//
// Free a list of item attributes
//
// The strings in the ATTRs
// The Attrs themselves
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::FreeItemList(OPCITEMATTRIBUTES *AttrList,
int ItemCount)
{
if(0 == ItemCount)
{
return;
}
for (int j = 0; j < ItemCount; j++)
{
// Free the contents of the IA
IAFree(&AttrList[j], NULL);
}
delete [] AttrList;
}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::GroupProcess()
//
// This method handles all ASYNC logic for the group.
// Note that we respond to async reads & writes
// at faster than the update rate.
//
// The DataObject and ConnectionPoint logic are very similar
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::GroupProcess(DWORD dwTics)
{
// Update the values at the update rate and check for OnDataChange
//
m_lUpdateTime -= dwTics;
if(m_lUpdateTime <= 0)
{
// If the group isn't active, then don't refresh it's items cache
//
if (GetActive())
{
// Update the data cache. This will make a call to NIO for each item
// in the group.
//
UpdateDataCache();
// If IAdviseSink active then check for OnDataChange
//
if (m_pCImpIDataObject && ((m_pCImpIDataObject->m_datatimeCallback) ||
(m_pCImpIDataObject->m_dataCallback)))
{
CheckDataObjectOnDataTimeChange(); // DataObject with time
CheckDataObjectOnDataChange(); // DataObject without time
}
// Used to calculate the bandwidth
//
m_pParentServer->m_dwNumGroupsProcessed++;
}
m_lUpdateTime = m_dwRevisedRate;
}
// Used to calculate the bandwidth
//
m_pParentServer->m_dwTotalPasses++;
// Check for Async Operations
//
AsyncProcess();
}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::AsyncProcess()
//
// Checks for async read, refresh and write requests
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::AsyncProcess(void)
{
// Make sure IAdviseSink is active
//
if (!m_pCImpIDataObject)
{
return;
}
// Async reads/refreshes
//
if ((m_pCImpIDataObject->m_datatimeCallback) || (m_pCImpIDataObject->m_dataCallback))
{
CheckDataObjectAsyncRead();
}
// Async writes complete
//
if (m_pCImpIDataObject && m_pCImpIDataObject->m_writeCallback)
{
CheckDataObjectAsyncWrite();
}
}
////////////////////////////////////////////////////////////////
// COPCDrvGroup::UpdateDataCache()
//
// Group Scanner - called at UpdateRate
// This keeps the local data cache up to date.
// It also marks items as changed for OnDataChange
//
////////////////////////////////////////////////////////////////
void COPCDrvGroup::UpdateDataCache(void)
{
DWORD dwNumItems = 0;
POSITION ItemPosition = NULL;
COPCDrvItem *pItem = NULL;
OPCHANDLE OPCHandle = 0;
// Lock the group object
//
Lock();
// Get the info about the item list
//
dwNumItems = GetNumItemHandles();
ItemPosition = m_mapItem.GetStartPosition();
// Go get the data for the items
for (DWORD j = 0; j < dwNumItems; j++)
{
m_mapItem.GetNextAssoc(ItemPosition, OPCHandle, pItem);
// If the item is active, then update its data
//
if (pItem->GetActive())
{
pItem->UpdateDataCache();
}
// If the primefirst flag is set, then mark this item as changed.
//
if (m_dwAdvfDataFlags & ADVF_PRIMEFIRST)
{
pItem->MarkAsChanged(OPC_ODC_DO);
}
if (m_dwAdvfDataTimeFlags & ADVF_PRIMEFIRST)
{
pItem->MarkAsChanged(OPC_ODC_DOT);
}
}
// Clear the prime flags.
//
m_dwAdvfDataFlags &= ~ADVF_PRIMEFIRST;
m_dwAdvfDataTimeFlags &= ~ADVF_PRIMEFIRST;
// Unlock the group object
//
UnLock();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -