- some should be the same as previous commit (sorry!) - some should be new: LINT checks, ...?
124 lines
3.1 KiB
C++
124 lines
3.1 KiB
C++
#ifndef FILEPLAYER_H
|
|
#define FILEPLAYER_H
|
|
|
|
#include "FileReader.h"
|
|
#include <thread>
|
|
|
|
namespace Offline {
|
|
|
|
/**
|
|
* this class can be used to "play" previously recorded [so-called "offline"] files.
|
|
* one can attach itself as listener and is informed whenever new sensor data is available.
|
|
* one may choose whether to use full-speed playback [as many events as possible] or
|
|
* live-speed playback with the same timing the values were recorded with
|
|
*/
|
|
class FilePlayer {
|
|
|
|
private:
|
|
|
|
FileReader* reader;
|
|
|
|
bool realtime = false;
|
|
bool enabled;
|
|
std::thread thread;
|
|
|
|
/** the listener to inform */
|
|
Listener* listener = nullptr;
|
|
|
|
public:
|
|
|
|
/** empty ctor */
|
|
FilePlayer() : reader(nullptr), listener(nullptr) {
|
|
;
|
|
}
|
|
|
|
/** ctor */
|
|
FilePlayer(FileReader* reader, Listener* l) : reader(reader), listener(l) {
|
|
;
|
|
}
|
|
|
|
/** whether to use realtime playback or "as fast as possible" */
|
|
void setRealtime(const bool rt) {
|
|
this->realtime = rt;
|
|
}
|
|
|
|
/** set the offline-file-reader to use as data source */
|
|
void setReader(FileReader* r) {
|
|
this->reader = r;
|
|
}
|
|
|
|
/** set the event listener to inform */
|
|
void setListener(Listener* l) {
|
|
this->listener = l;
|
|
}
|
|
|
|
/** start playback */
|
|
void start() {
|
|
|
|
// sanity check
|
|
Assert::isNotNull(reader, "call FilePlayer::setReader() first");
|
|
Assert::isNotNull(listener, "call FilePlayer::setListener() first");
|
|
Assert::isFalse(reader->getEntries().empty(), "FileReader has no loaded entries for playback within the FilePlayer!");
|
|
|
|
enabled = true;
|
|
thread = std::thread(&FilePlayer::loop, this);
|
|
|
|
}
|
|
|
|
/** stop playback */
|
|
void stop() {
|
|
enabled = false;
|
|
}
|
|
|
|
/** wait for termination */
|
|
void join() {
|
|
thread.join();
|
|
}
|
|
|
|
private:
|
|
|
|
/** background loop */
|
|
void loop() {
|
|
|
|
// get all sensor events from the offline file
|
|
const std::vector<Entry> events = reader->getEntries();
|
|
|
|
// process every event
|
|
for (const Entry& e : events) {
|
|
|
|
// aborted?
|
|
if (!enabled) {break;}
|
|
|
|
// timestamp
|
|
const Timestamp ts = Timestamp::fromMS(e.ts);
|
|
|
|
// event index
|
|
const size_t idx = e.idx;
|
|
|
|
#warning "some sensors todo:"
|
|
switch(e.type) {
|
|
case Sensor::ACC: listener->onAccelerometer(ts, reader->getAccelerometer()[idx].data); break;
|
|
case Sensor::BARO: listener->onBarometer(ts, reader->getBarometer()[idx].data); break;
|
|
case Sensor::BEACON: break;//listener->onBe(ts, reader->getBarometer()[idx].data); break;
|
|
case Sensor::COMPASS: listener->onCompass(ts, reader->getCompass()[idx].data); break;
|
|
case Sensor::GPS: listener->onGPS(ts, reader->getGPS()[idx].data); break;
|
|
case Sensor::GRAVITY: listener->onGravity(ts, reader->getGravity()[idx].data); break;
|
|
case Sensor::GYRO: listener->onGyroscope(ts, reader->getGyroscope()[idx].data); break;
|
|
case Sensor::LIN_ACC: break;//listener->on(ts, reader->getBarometer()[idx].data); break;
|
|
case Sensor::WIFI: listener->onWiFi(ts, reader->getWiFiGroupedByTime()[idx].data); break;
|
|
default: throw Exception("code error. found not-yet-implemented sensor");
|
|
}
|
|
|
|
}
|
|
|
|
// done
|
|
enabled = false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif // FILEPLAYER_H
|