blob: 1173b02b4988927485600af4045beecb1a608728 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2022 AIT, fortiss GmbH, Hit robot group
* 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
* ys guo - Fix opc module compilation errors and deadlock bug
* Tibalt Zhao - use stl vector
*******************************************************************************/
#include "opceventhandler.h"
#include "../core/devexec.h"
#include <commfb.h>
#include <ObjBase.h>
DEFINE_HANDLER(COpcEventHandler);
COpcEventHandler::TCallbackDescriptor COpcEventHandler::mCallbackDescCount = 0;
COpcEventHandler::COpcEventHandler(CDeviceExecution& paDeviceExecution) : CExternalEventHandler(paDeviceExecution) {
this->start();
// Sleep to allow new thread to start
CThread::sleepThread(100);
}
COpcEventHandler::~COpcEventHandler(){
this->end();
}
void COpcEventHandler::sendCommand(ICmd *paCmd){
CCriticalRegion critcalRegion(mSync);
mCommandQueue.pushBack(paCmd);
}
void COpcEventHandler::run(){
HRESULT result = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
if(result == S_OK){
while(isAlive()){
ICmd* nextCommand = getNextCommand();
if(nextCommand != nullptr) {
nextCommand->runCommand();
delete nextCommand;
}
MSG msg;
while(PeekMessage(&msg, nullptr, nullptr, nullptr, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
CThread::sleepThread(100);
}
}
CoUninitialize();
}
COpcEventHandler::TCallbackDescriptor COpcEventHandler::addComCallback(forte::com_infra::CComLayer* paComCallback){
CCriticalRegion critcalRegion(mSync);
mCallbackDescCount++;
DEVLOG_INFO("COpcEventHandler::addComCallback[%d]\n",mCallbackDescCount);
TComContainer stNewNode = { mCallbackDescCount, paComCallback };
mComCallbacks.push_back(stNewNode);
return mCallbackDescCount;
}
void COpcEventHandler::removeComCallback(COpcEventHandler::TCallbackDescriptor paCallbackDesc){
CCriticalRegion critcalRegion(mSync);
for(TCallbackList::iterator itRunner = mComCallbacks.begin(); itRunner != mComCallbacks.end(); ++itRunner){
if(itRunner->mCallbackDesc == paCallbackDesc){
mComCallbacks.erase(itRunner);
break;
}
}
}
void COpcEventHandler::executeComCallback(COpcEventHandler::TCallbackDescriptor paCallbackDesc){
CCriticalRegion critcalRegion(mSync);
if(mComCallbacks.empty()){
return;
}
for(TCallbackList::iterator itCallback = mComCallbacks.begin(); itCallback != mComCallbacks.end(); ++itCallback){
if(itCallback->mCallbackDesc == paCallbackDesc){
//FIX
TComContainer comCon = (*itCallback);
mSync.unlock();
if(forte::com_infra::e_Nothing != comCon.mCallback->recvData(0,0)){
startNewEventChain(comCon.mCallback->getCommFB());
}
mSync.lock();
break;
}
}
}
ICmd* COpcEventHandler::getNextCommand(){
ICmd* command = nullptr;
CCriticalRegion critcalRegion(mSync);
TCommandQueue::Iterator itBegin = mCommandQueue.begin();
if(itBegin != mCommandQueue.end()){
command = (*itBegin);
mCommandQueue.popFront();
}
return command;
}