blob: f2ec4fcf8685c7e31064aa780701a1c7cfdf6b8d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012 - 2014 AIT, fortiss GmbH
* 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:
* Filip Andren, Alois Zoitl - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "opceventhandler.h"
#include "../core/devexec.h"
#include <commfb.h>
#include <ObjBase.h>
DEFINE_HANDLER(COpcEventHandler);
COpcEventHandler::TCallbackDescriptor COpcEventHandler::m_nCallbackDescCount = 0;
COpcEventHandler::COpcEventHandler(CDeviceExecution& pa_poDeviceExecution) : CExternalEventHandler(pa_poDeviceExecution) {
this->start();
// Sleep to allow new thread to start
CThread::sleep(100);
}
COpcEventHandler::~COpcEventHandler(){
this->end();
}
void COpcEventHandler::sendCommand(ICmd *pa_pCmd){
m_oSync.lock();
m_lCommandQueue.pushBack(pa_pCmd);
m_oSync.unlock();
}
void COpcEventHandler::run(){
HRESULT result = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if(result == S_OK){
while(isAlive()){
ICmd* nextCommand = getNextCommand();
if(nextCommand != NULL) {
nextCommand->runCommand();
}
MSG msg;
while(PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
CoUninitialize();
}
COpcEventHandler::TCallbackDescriptor COpcEventHandler::addComCallback(forte::com_infra::CComLayer* pa_pComCallback){
m_oSync.lock();
m_nCallbackDescCount++;
TComContainer stNewNode = { m_nCallbackDescCount, pa_pComCallback };
m_lstComCallbacks.pushBack(stNewNode);
m_oSync.unlock();
return m_nCallbackDescCount;
}
void COpcEventHandler::removeComCallback(COpcEventHandler::TCallbackDescriptor pa_nCallbackDesc){
m_oSync.lock();
TCallbackList::Iterator itRunner(m_lstComCallbacks.begin());
if(itRunner->m_nCallbackDesc == pa_nCallbackDesc){
m_lstComCallbacks.popFront();
}
else{
TCallbackList::Iterator itLastPos(itRunner);
TCallbackList::Iterator itEnd(m_lstComCallbacks.end());
++itRunner;
while(itRunner != itEnd){
if(itRunner->m_nCallbackDesc == pa_nCallbackDesc){
m_lstComCallbacks.eraseAfter(itLastPos);
break;
}
itLastPos = itRunner;
++itRunner;
}
}
m_oSync.unlock();
}
void COpcEventHandler::executeComCallback(COpcEventHandler::TCallbackDescriptor pa_nCallbackDesc){
m_oSync.lock();
TCallbackList::Iterator itEnd(m_lstComCallbacks.end());
for(TCallbackList::Iterator itCallback = m_lstComCallbacks.begin(); itCallback != itEnd; ++itCallback){
if(itCallback->m_nCallbackDesc == pa_nCallbackDesc){
//FIX
TComContainer comCon = (*itCallback);
m_oSync.unlock();
if(forte::com_infra::e_Nothing != comCon.m_pCallback->recvData(0,0)){
startNewEventChain(comCon.m_pCallback->getCommFB());
}
m_oSync.lock();
break;
}
}
m_oSync.unlock();
}
ICmd* COpcEventHandler::getNextCommand(){
ICmd* command;
m_oSync.lock();
TCommandQueue::Iterator itBegin = m_lCommandQueue.begin();
if(itBegin != m_lCommandQueue.end()){
command = (*itBegin);
m_lCommandQueue.popFront();
} else {
command = NULL;
}
m_oSync.unlock();
return command;
}