www.pudn.com > Ge_opc_Server_v1.rar > GROUP.CPP
// Group.cpp // // This file contains the implementation of // the 'core' of the LHEpipeviewGroup Object for the OPC server. // // // (c) COPYRIGHT 1996,1997 INTELLUTION INC. // ALL RIGHTS RESERVED // // Original Author: Al Chisholm // // Modification Log: // Vers Date By Notes // ---- -------- --- ----- // 0.00 11/18/96 ACC // 0.90 04/02/97 acc add Async support // // todo //// #define WIN32_LEAN_AND_MEAN #include "OPCLHEpipeview.h" extern CRITICAL_SECTION CritSec; ///////////////////////////////////////////////////////////////////////////// // Constructor /Destructor functions // /////////////////////////////////////// // OPCGroup() // Constructor for the OPC Sample Group. // /////////////////////////////////////// LHEpipeviewGroup::LHEpipeviewGroup( LPUNKNOWN pOuter) { int j; mRefCount = 0; // Record Parent server // m_ParentServer = (LHEpipeviewServer *)pOuter; // Initizlize member variables // m_ServerGroupHandle = 0; m_ClientGroupHandle = 0; m_dwRevisedRate = 0; m_bActive = FALSE; m_szName = 0; // Clear out 'tear-off' interface ptrs // The interfaces will be created as needed in QueryInterface // m_pILHEpipeviewGSM = 0; m_pILHEpipeviewPGSM = 0; // optional m_pILHEpipeviewSIO = 0; m_pILHEpipeviewASIO = 0; m_pILHEpipeviewIM = 0; m_pILHEpipeviewDO = 0; // async state variables used by DataObject // m_AsyncReadActive = 0; m_AsyncReadCancel = 0; m_AsyncReadTID = 0; m_AsyncReadList = 0; m_AsyncReadSource = OPC_DS_CACHE; m_AsyncWriteActive = 0; m_AsyncWriteCancel = 0; m_AsyncWriteTID = 0; m_AsyncWriteList = 0; m_RefreshTID = 0; m_RefreshCancel = 0; m_RefreshSource = OPC_DS_CACHE; m_RefreshActive = 0; m_scan = 0; // Clear out the 'items' // This simple example only holds 100 items // A real implementation would use some sort // of container or linked list // for (j=0; j Free(m_AsyncReadList); // should be 0 already if(m_AsyncWriteList) pIMalloc->Free(m_AsyncWriteList); // Also free any memory associated with the ITEMS // for (j=0; j Release(); } } LeaveCriticalSection(&CritSec); } ///////////////////////////////////////////////////////////////////////////// // IUnknown functions // /////////////////////////////////////// // IUnknown::AddRef() // Standard IUnknown implementation // /////////////////////////////////////// STDMETHODIMP_(ULONG) LHEpipeviewGroup::AddRef( void) { return ++mRefCount; } /////////////////////////////////////// // IUnknown::Release() // Standard IUnknown implementation // /////////////////////////////////////// STDMETHODIMP_(ULONG) LHEpipeviewGroup::Release( void) { ULONG currentCount = --mRefCount; // If no references left for this group if ( currentCount == 0) { // Then delete this group. delete this; } return currentCount; } /////////////////////////////////////// // IUnknown::QueryInterface() // Standard IUnknown implementation // /////////////////////////////////////// STDMETHODIMP LHEpipeviewGroup::QueryInterface( REFIID iid, LPVOID* ppInterface) { if ( ppInterface == NULL) return E_INVALIDARG; if ( iid == IID_IUnknown ) *ppInterface = (IUnknown*) this; else if ( iid == IID_IOPCGroupStateMgt) { if(m_pILHEpipeviewGSM == 0) m_pILHEpipeviewGSM = new ILHEpipeviewGSM(this); *ppInterface = m_pILHEpipeviewGSM; } else if ( iid == IID_IOPCPublicGroupStateMgt) { if(m_pILHEpipeviewPGSM == 0) m_pILHEpipeviewPGSM = 0; // optional (notimplemented) *ppInterface = m_pILHEpipeviewPGSM; } else if ( iid == IID_IOPCSyncIO) { if(m_pILHEpipeviewSIO == 0) m_pILHEpipeviewSIO = new ILHEpipeviewSIO(this) ; *ppInterface = m_pILHEpipeviewSIO; } else if ( iid == IID_IOPCAsyncIO) { if(m_pILHEpipeviewASIO == 0) m_pILHEpipeviewASIO = new ILHEpipeviewASIO(this) ; *ppInterface = m_pILHEpipeviewASIO; } else if ( iid == IID_IOPCItemMgt) { if(m_pILHEpipeviewIM == 0) m_pILHEpipeviewIM = new ILHEpipeviewIM(this) ; *ppInterface = m_pILHEpipeviewIM; } else if ( iid == IID_IDataObject) { if(m_pILHEpipeviewDO == 0) m_pILHEpipeviewDO = new ILHEpipeviewDO(this); *ppInterface = m_pILHEpipeviewDO; } else { *ppInterface = NULL; } if ( *ppInterface == NULL) return E_NOINTERFACE; // Addref the group for each tear off interface created // (This is equivalent to ppInterface->AddRef() which delegates back here) // AddRef(); return S_OK; } /////////////////////////////////////// // LHEpipeviewGroup::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 LHEpipeviewGroup::GetItemList( OPCITEMATTRIBUTES **AttrList, int *ItemCount) { int j, count = 0; OPCITEMATTRIBUTES *myAttr; *ItemCount = 0; // First pass - count items in use // for (j=0; j IAGet(&myAttr[*ItemCount]); (*ItemCount)++; } } } /////////////////////////////////////// // LHEpipeviewGroup::FreeItemList() // Free a list of item attributes // // The strings in the ATTRs // The Attrs themselves // void LHEpipeviewGroup::FreeItemList( OPCITEMATTRIBUTES *AttrList, int ItemCount) { int j; if(!ItemCount) return; for (j=0; j m_datatimeCallback) || (m_pILHEpipeviewDO->m_dataCallback))) { CheckDOOnDataTimeChange(); //DataObject with time CheckDOOnDataChange(); //DataObject without time } m_scan = m_dwRevisedRate; } // If IAdviseSink active then check for Async Operations // if (m_pILHEpipeviewDO && ((m_pILHEpipeviewDO->m_datatimeCallback) || (m_pILHEpipeviewDO->m_dataCallback))) { CheckDORefresh(); CheckDOAsyncRead(); } if (m_pILHEpipeviewDO && m_pILHEpipeviewDO->m_writeCallback) { CheckDOAsyncWrite(); } } /////////////////////////////////////// // LHEpipeviewGroup::Scan // // Group Scanner - called at UpdateRate // This keeps the local data cache up to date. // It also marks items as changed for OnDataChange // void LHEpipeviewGroup::Scan( void ) { int j; // Normally we would fetch fresh data for the group here. // But in this sample we just simulate data... // // *** Add Server Specific Code *** // for (j=0; j Simulate(); } } }