Files
pip/libs/main/thread/pigrabberbase.h
peri4 1c7fc39b6c version 4.0.0_alpha
in almost all methods removed timeouts in milliseconds, replaced to PISystemTime
PITimer rewrite, remove internal impl, now only thread implementation, API similar to PIThread
PITimer API no longer pass void*
PIPeer, PIConnection improved stability on reinit and exit
PISystemTime new methods
pisd now exit without hanging
2024-07-30 14:18:02 +03:00

195 lines
4.1 KiB
C++

/*! \file pigrabberbase.h
* \ingroup Thread
* \~\brief
* \~english Abstract class for create grabbers
* \~russian Базовый класс для создания грабберов
*/
/*
PIP - Platform Independent Primitives
Abstract class for create grabbers
Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIGRABBERBASE_H
#define PIGRABBERBASE_H
#include "pidiagnostics.h"
#include "pithread.h"
#include "pitime.h"
template<typename T = PIByteArray>
class PIGrabberBase: public PIThread {
PIOBJECT_SUBCLASS(PIGrabberBase, PIThread);
public:
PIGrabberBase() {
is_opened = false;
is_recording = false;
}
virtual ~PIGrabberBase() { stopGrabber(false); }
virtual bool isOpened() const { return is_opened; }
virtual bool isRecording() const { return is_recording; }
virtual void startRecord(const PIString & filename) {
if (!isOpened()) return;
if (isRecording()) return;
rec_mutex.lock();
startRecordInternal(filename);
is_recording = true;
rec_mutex.unlock();
}
virtual void stopRecord() {
if (!isOpened()) return;
if (!isRecording()) return;
rec_mutex.lock();
is_recording = false;
stopRecordInternal();
rec_mutex.unlock();
}
T last() const {
T ret;
last_mutex.lock();
ret = last_;
last_mutex.unlock();
return ret;
}
bool isEmpty() {
bool ret;
que_mutex.lock();
ret = que.isEmpty();
que_mutex.unlock();
return ret;
}
int queSize() {
int ret;
que_mutex.lock();
ret = que.size();
que_mutex.unlock();
return ret;
}
T dequeue() {
T ret;
// piCoutObj << "start";
que_mutex.lock();
if (!que.isEmpty()) {
// piCoutObj << "dequeue";
ret = que.dequeue();
}
// piCoutObj << "end";
que_mutex.unlock();
return ret;
}
void stopGrabber(bool wait_forever = true) {
if (isRunning()) {
stop();
if (wait_forever)
waitForFinish();
else {
if (!waitForFinish(100)) terminate();
stopRecord();
close();
}
}
}
bool open() {
bool ret = openInternal();
if (!is_opened && ret) opened();
is_opened = ret;
return ret;
}
void close() {
bool em = is_opened;
closeInternal();
last_ = T();
if (em) closed();
is_opened = false;
}
const PIDiagnostics & diag() const { return diag_; }
void clear() {
que_mutex.lock();
que.clear();
que_mutex.unlock();
}
void restart() {
clear();
close();
}
EVENT(dataReady);
EVENT(opened);
EVENT(closed);
protected:
virtual void init() {}
virtual bool openInternal() = 0;
virtual void closeInternal() = 0;
virtual int get(T & val) = 0;
virtual void record(const T & val) {}
virtual void startRecordInternal(const PIString & filename) {}
virtual void stopRecordInternal() {}
bool is_opened, is_recording;
mutable PIMutex rec_mutex;
private:
void begin() override { init(); }
void run() override {
if (!isOpened()) {
open();
diag_.reset();
if (!is_opened) piMSleep(200);
}
if (isOpened()) {
T c;
int ret = get(c);
if (ret < 0) {
close();
return;
}
if (ret > 0) {
piMinSleep();
return;
}
diag_.received(1);
que_mutex.lock();
que.enqueue(c);
que_mutex.unlock();
if (isRecording()) {
rec_mutex.lock();
record(c);
rec_mutex.unlock();
diag_.sended(1);
}
last_mutex.lock();
last_ = c;
last_mutex.unlock();
dataReady();
}
}
void end() override {
stopRecord();
close();
}
T last_;
PIQueue<T> que;
PIDiagnostics diag_;
mutable PIMutex que_mutex, last_mutex;
};
#endif // PIGRABBERBASE_H