2023-02-09 05:57:17 +08:00
|
|
|
#ifndef TRACEDIFFERENCEGENERATOR_H
|
|
|
|
#define TRACEDIFFERENCEGENERATOR_H
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
2023-11-01 01:49:08 +08:00
|
|
|
template<typename T>
|
2023-02-09 05:57:17 +08:00
|
|
|
class TraceDifferenceGenerator {
|
|
|
|
public:
|
|
|
|
TraceDifferenceGenerator(std::function<void(const T&)> changeCallback) :
|
2023-03-27 06:13:01 +08:00
|
|
|
nextCallbackIndex(0),
|
2023-02-09 05:57:17 +08:00
|
|
|
last{},
|
2023-03-27 06:13:01 +08:00
|
|
|
callback(changeCallback)
|
2023-02-09 05:57:17 +08:00
|
|
|
{}
|
|
|
|
|
|
|
|
void reset() {
|
|
|
|
last.clear();
|
|
|
|
nextCallbackIndex = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void newTrace(const std::vector<T> &trace) {
|
2023-11-01 01:49:08 +08:00
|
|
|
if(trace.size() < last.size()) {
|
2023-02-09 05:57:17 +08:00
|
|
|
// got less points than last time. This must be a completely new trace, generate callbacks for all points
|
|
|
|
for(auto &i : trace) {
|
|
|
|
callback(i);
|
|
|
|
}
|
|
|
|
nextCallbackIndex = 0;
|
|
|
|
} else {
|
2023-11-01 01:49:08 +08:00
|
|
|
// same amount or more points -> find first difference going backwards from next scheduled update point
|
|
|
|
unsigned int lastDiff = nextCallbackIndex;
|
2023-02-09 05:57:17 +08:00
|
|
|
do {
|
2023-11-01 01:49:08 +08:00
|
|
|
if(lastDiff > 0) {
|
|
|
|
lastDiff--;
|
2023-02-09 05:57:17 +08:00
|
|
|
} else {
|
2023-11-01 01:49:08 +08:00
|
|
|
// reached the beginning of the trace
|
|
|
|
if(last.size() == trace.size()) {
|
|
|
|
if(nextCallbackIndex == trace.size()) {
|
|
|
|
// nothing has changed in the whole trace, abort
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
// wrap around to the end
|
|
|
|
lastDiff = trace.size() - 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// trace must be longer than last -> update all the way to the end
|
|
|
|
lastDiff = trace.size() - 1;
|
|
|
|
for(;nextCallbackIndex!=trace.size();nextCallbackIndex++) {
|
|
|
|
callback(trace[nextCallbackIndex]);
|
|
|
|
}
|
|
|
|
break;
|
2023-02-09 05:57:17 +08:00
|
|
|
}
|
2023-11-01 01:49:08 +08:00
|
|
|
}
|
|
|
|
if(!(last[lastDiff] == trace[lastDiff])) {
|
|
|
|
do {
|
|
|
|
if(nextCallbackIndex >= trace.size()) {
|
|
|
|
nextCallbackIndex = 0;
|
|
|
|
}
|
|
|
|
callback(trace[nextCallbackIndex]);
|
|
|
|
nextCallbackIndex++;
|
|
|
|
} while(nextCallbackIndex != lastDiff + 1);
|
2023-02-09 05:57:17 +08:00
|
|
|
break;
|
|
|
|
}
|
2023-11-01 01:49:08 +08:00
|
|
|
} while(lastDiff != nextCallbackIndex);
|
2023-02-09 05:57:17 +08:00
|
|
|
}
|
|
|
|
last = trace;
|
2023-11-01 01:49:08 +08:00
|
|
|
// if(trace.size() > last.size()) {
|
|
|
|
// // definitely got more points than last time. Find first point that hasn't been transmitted and generate callbacks for it and all subsequent points
|
|
|
|
// unsigned int i=nextCallbackIndex;
|
|
|
|
// while(i < trace.size()) {
|
|
|
|
// callback(trace[i]);
|
|
|
|
// i++;
|
|
|
|
// }
|
|
|
|
// nextCallbackIndex = trace.size();
|
|
|
|
// } else i else {
|
|
|
|
// // still the same amount of points.
|
|
|
|
// unsigned int i = nextCallbackIndex;
|
|
|
|
// unsigned int changedPoints = 0;
|
|
|
|
// do {
|
|
|
|
// if(i > 0) {
|
|
|
|
// i--;
|
|
|
|
// } else {
|
|
|
|
// // reached the end
|
|
|
|
// if(nextCallbackIndex == trace.size()) {
|
|
|
|
// // checked the whole trace
|
|
|
|
// break;
|
|
|
|
// } else {
|
|
|
|
// // last callback was within trace, wrap around
|
|
|
|
// i = trace.size() - 1;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// bool unchanged = last[i] == trace[i];
|
|
|
|
// if(!unchanged) {
|
|
|
|
// changedPoints = (i + trace.size() - nextCallbackIndex + 1);
|
|
|
|
// if(changedPoints > trace.size()) {
|
|
|
|
// changedPoints -= trace.size();
|
|
|
|
// }
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
// } while (i != nextCallbackIndex);
|
|
|
|
// i = nextCallbackIndex;
|
|
|
|
// while(changedPoints--) {
|
|
|
|
// callback(trace[i]);
|
|
|
|
// i = (i + 1) % trace.size();
|
|
|
|
// }
|
|
|
|
// nextCallbackIndex = i;
|
|
|
|
// }
|
|
|
|
// last = trace;
|
2023-02-09 05:57:17 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
unsigned int nextCallbackIndex;
|
|
|
|
std::vector<T> last;
|
|
|
|
std::function<void(const T&)> callback;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // TRACEDIFFERENCEGENERATOR_H
|