#include "ftnoir_tracker_base.h" #include #include #include "Windows.h" class FTNoIR_Tracker_UDP : public ITracker, QThread { public: FTNoIR_Tracker_UDP(); ~FTNoIR_Tracker_UDP(); void Release(); void Initialize(); void StartTracker(); void GiveHeadPoseData(THeadPoseData *data); protected: void run(); // qthread override run method private: // Handles to neatly terminate thread... HANDLE m_StopThread; HANDLE m_WaitThread; // UDP socket-variables QUdpSocket *inSocket; // Receive from ... QUdpSocket *outSocket; // Send to ... QHostAddress destIP; // Destination IP-address int destPort; // Destination port-number QHostAddress srcIP; // Source IP-address int srcPort; // Source port-number THeadPoseData newHeadPose; // Structure with new headpose }; FTNoIR_Tracker_UDP::FTNoIR_Tracker_UDP() { inSocket = 0; outSocket = 0; // Create events m_StopThread = CreateEvent(0, TRUE, FALSE, 0); m_WaitThread = CreateEvent(0, TRUE, FALSE, 0); newHeadPose.x = 1.0f; newHeadPose.y = 2.0f; newHeadPose.z = 3.0f; newHeadPose.yaw = 4.0f; newHeadPose.pitch = 5.0f; newHeadPose.roll = 6.0f; } FTNoIR_Tracker_UDP::~FTNoIR_Tracker_UDP() { // Trigger thread to stop ::SetEvent(m_StopThread); // Wait until thread finished if (isRunning()) { ::WaitForSingleObject(m_WaitThread, INFINITE); } // Close handles ::CloseHandle(m_StopThread); ::CloseHandle(m_WaitThread); if (inSocket) { inSocket->disconnectFromHost(); inSocket->waitForDisconnected(); delete inSocket; } if (outSocket) { outSocket->disconnectFromHost(); outSocket->waitForDisconnected(); delete outSocket; } } /** QThread run @override **/ void FTNoIR_Tracker_UDP::run() { int no_bytes; QHostAddress sender; quint16 senderPort; // // Create UDP-sockets if they don't exist already. // They must be created here, because they must be in the new thread (FTNoIR_Tracker_UDP::run()) // if (inSocket == 0) { qDebug() << "FTNoIR_Tracker_UDP::run() creating insocket"; inSocket = new QUdpSocket(); // Connect the inSocket to the port, to receive messages inSocket->bind(QHostAddress::Any, destPort+1); } // // Read the data that was received. // forever { // Check event for stop thread if(::WaitForSingleObject(m_StopThread, 0) == WAIT_OBJECT_0) { // Set event ::SetEvent(m_WaitThread); qDebug() << "FTNoIR_Tracker_UDP::run() terminated run()"; return; } while (inSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(inSocket->pendingDatagramSize()); inSocket->readDatagram( (char * ) &newHeadPose, sizeof(newHeadPose), &sender, &senderPort); } //for lower cpu load usleep(5000); yieldCurrentThread(); } } void FTNoIR_Tracker_UDP::Release() { delete this; } void FTNoIR_Tracker_UDP::Initialize() { return; } void FTNoIR_Tracker_UDP::StartTracker() { start( QThread::TimeCriticalPriority ); return; } void FTNoIR_Tracker_UDP::GiveHeadPoseData(THeadPoseData *data) { newHeadPose.x += 1.0f; newHeadPose.y += 2.0f; newHeadPose.z += 3.0f; newHeadPose.yaw += 4.0f; newHeadPose.pitch += 5.0f; newHeadPose.roll += 6.0f; data->x = newHeadPose.x; data->y = newHeadPose.y; data->z = newHeadPose.z; data->yaw = newHeadPose.yaw; data->pitch = newHeadPose.pitch; data->roll = newHeadPose.roll; return; } //////////////////////////////////////////////////////////////////////////////// // Factory function that creates instances if the Tracker object. // Export both decorated and undecorated names. // GetTracker - Undecorated name, which can be easily used with GetProcAddress // Win32 API function. // _GetTracker@0 - Common name decoration for __stdcall functions in C language. #pragma comment(linker, "/export:GetTracker=_GetTracker@0") FTNOIR_TRACKER_BASE_EXPORT TRACKERHANDLE __stdcall GetTracker() { return new FTNoIR_Tracker_UDP; }