You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
6.8 KiB
C++
290 lines
6.8 KiB
C++
/*!
|
|
* \file CyclopsParam.h
|
|
* \date 2019/11/12
|
|
*
|
|
* \author Lin, Chi
|
|
* Contact: lin.chi@hzleaper.com
|
|
*
|
|
*
|
|
* \note
|
|
*/
|
|
|
|
#ifndef __CyclopsParam_h_
|
|
#define __CyclopsParam_h_
|
|
|
|
#include <vector>
|
|
#include <memory>
|
|
#include "CVUtils.h"
|
|
|
|
struct CyclopsParam
|
|
{
|
|
virtual void serialize(FileStorage& fs) const = 0;
|
|
virtual void deserialize(const FileNode& node) = 0;
|
|
virtual void resetValue() = 0;
|
|
virtual size_t getType() const = 0;
|
|
virtual CyclopsParam* copy() const = 0;
|
|
virtual void backup() = 0;
|
|
virtual void restore() = 0;
|
|
virtual void print(std::stringstream& ss) const = 0;
|
|
virtual void fromString(std::stringstream& ss) = 0;
|
|
};
|
|
|
|
template<typename T>
|
|
struct CyclopsParamX : public CyclopsParam
|
|
{
|
|
T val;
|
|
|
|
const T minVal;
|
|
const T maxVal;
|
|
const T defaultVal;
|
|
|
|
T backupVal;
|
|
|
|
CyclopsParamX(const T& defaultV, const T& minV, const T& maxV) :
|
|
defaultVal(defaultV), val(defaultV), minVal(minV), maxVal(maxV)
|
|
{}
|
|
virtual ~CyclopsParamX() {}
|
|
|
|
virtual void serialize(FileStorage& fs) const {
|
|
fs << "val" << val;
|
|
fs << "backup" << backupVal;
|
|
}
|
|
|
|
virtual void deserialize(const FileNode& node) {
|
|
node["val"] >> val;
|
|
node["backup"] >> backupVal;
|
|
}
|
|
|
|
void setValue(const T& v) {
|
|
if (v >= minVal && v <= maxVal) {
|
|
val = v;
|
|
}
|
|
}
|
|
|
|
virtual void resetValue() {
|
|
val = defaultVal;
|
|
}
|
|
|
|
virtual size_t getType() const {
|
|
return typeid(T).hash_code();
|
|
}
|
|
|
|
virtual CyclopsParam* copy() const {
|
|
CyclopsParamX* p = new CyclopsParamX(defaultVal, minVal, maxVal);
|
|
p->val = val;
|
|
return p;
|
|
}
|
|
|
|
virtual void backup() {
|
|
backupVal = val;
|
|
}
|
|
|
|
virtual void restore() {
|
|
val = backupVal;
|
|
}
|
|
|
|
virtual void print(std::stringstream& ss) const {
|
|
ss << val;
|
|
}
|
|
|
|
virtual void fromString(std::stringstream& ss) {
|
|
ss >> val;
|
|
}
|
|
};
|
|
|
|
typedef CyclopsParamX<int> CyclopsParamInt;
|
|
typedef CyclopsParamX<double> CyclopsParamDouble;
|
|
typedef CyclopsParamX<bool> CyclopsParamBool;
|
|
typedef CyclopsParamX<Size> CyclopsParamSize;
|
|
// special instantiation for size param
|
|
void CyclopsParamSize::print(std::stringstream& ss) const {
|
|
ss << val.width << " x " << val.height;
|
|
}
|
|
void CyclopsParamSize::fromString(std::stringstream& ss) {
|
|
ss >> val.width;
|
|
std::string temp; ss >> temp;
|
|
ss >> val.height;
|
|
}
|
|
// add more CyclopsParamX for other data types
|
|
|
|
struct CyclopsParams
|
|
{
|
|
public:
|
|
CyclopsParams() {}
|
|
~CyclopsParams() {
|
|
for (CyclopsParam* p : params) delete p;
|
|
params.clear();
|
|
}
|
|
|
|
CyclopsParams(const CyclopsParams& other) {
|
|
setDirtyBit(true);
|
|
validateFunc = other.validateFunc;
|
|
for (const CyclopsParam* p : other.params) {
|
|
params.push_back(p->copy());
|
|
}
|
|
}
|
|
|
|
void operator= (const CyclopsParams& other) = delete;
|
|
|
|
template<typename T>
|
|
void addParam(const T& defaultV, const T& minV, const T& maxV) {
|
|
params.push_back(new CyclopsParamX<T>(defaultV, minV, maxV));
|
|
}
|
|
template<typename T>
|
|
void addParam(const T& defaultV) {
|
|
params.push_back(new CyclopsParamX<T>(defaultV,
|
|
std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max()));
|
|
}
|
|
template<typename T>
|
|
void addParam(const T& defaultV, const T& oneLimit) {
|
|
params.push_back(new CyclopsParamX<T>(defaultV,
|
|
oneLimit <= defaultV ? oneLimit : std::numeric_limits<T>::lowest(),
|
|
oneLimit > defaultV ? oneLimit : std::numeric_limits<T>::max()));
|
|
}
|
|
|
|
template<>
|
|
void addParam<Size>(const Size& defaultV) {
|
|
params.push_back(new CyclopsParamSize(defaultV, Size(0, 0), Size(INT_MAX, INT_MAX)));
|
|
}
|
|
template<>
|
|
void addParam(const Size& defaultV, const Size& minV, const Size& maxV) {
|
|
params.push_back(new CyclopsParamSize(defaultV, minV, maxV));
|
|
}
|
|
template<>
|
|
void addParam(const Size& defaultV, const Size& oneLimit) = delete;
|
|
|
|
int count() const { return params.size(); }
|
|
|
|
void serialize(FileStorage& fs) const {
|
|
fs << "params" << "[";
|
|
for (const CyclopsParam* p : params) {
|
|
fs << "{:";
|
|
fs << "type" << std::to_string(p->getType());
|
|
p->serialize(fs);
|
|
fs << "}";
|
|
}
|
|
fs << "]";
|
|
fs << "dirty" << dirtyBit;
|
|
}
|
|
|
|
void deserialize(const FileNode& node) {
|
|
FileNode pNode = node["params"];
|
|
if (pNode.isNone()) return;
|
|
if (params.size() != pNode.size()) return;
|
|
int i = 0;
|
|
for (auto it = pNode.begin(); it != pNode.end(); ++it, i++) {
|
|
std::string typecode;
|
|
(*it)["type"] >> typecode;
|
|
if (typecode != std::to_string(params[i]->getType())) continue;
|
|
params[i]->deserialize(*it);
|
|
}
|
|
node["dirty"] >> dirtyBit;
|
|
}
|
|
|
|
template<typename T>
|
|
void setValue(int idx, const T& val) {
|
|
if (idx < 0 || idx > params.size()) return;
|
|
CyclopsParamX<T>* p = dynamic_cast<CyclopsParamX<T>*>(params[idx]);
|
|
if (p && p->val != val) {
|
|
p->setValue(val);
|
|
setDirtyBit(true);
|
|
}
|
|
}
|
|
|
|
void setValueFromString(int idx, const std::string& str) {
|
|
if (idx < 0 || idx > params.size()) return;
|
|
CyclopsParam* p = params[idx];
|
|
std::stringstream ss(str);
|
|
p->fromString(ss);
|
|
}
|
|
|
|
template<typename T>
|
|
T getValue(int idx) const {
|
|
if (idx < 0 || idx > params.size()) return T();
|
|
const CyclopsParamX<T>* p = dynamic_cast<const CyclopsParamX<T>*>(params[idx]);
|
|
if (p) {
|
|
return p->val;
|
|
}
|
|
return T();
|
|
}
|
|
|
|
void reset() {
|
|
for (CyclopsParam* p : params) {
|
|
p->resetValue();
|
|
}
|
|
setDirtyBit(true);
|
|
}
|
|
|
|
template<typename T>
|
|
void getSetting(int idx, T* pMinVal = nullptr, T* pMaxVal = nullptr, T* pDefaultVal = nullptr) const {
|
|
if (idx < 0 || idx > params.size()) return;
|
|
const CyclopsParamX<T>* p = dynamic_cast<const CyclopsParamX<T>*>(params[idx]);
|
|
if (p) {
|
|
if (pMinVal) *pMinVal = p->minVal;
|
|
if (pMaxVal) *pMaxVal = p->maxVal;
|
|
if (pDefaultVal) *pDefaultVal = p->defaultVal;
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
bool checkParamType(int idx) const {
|
|
if (idx < 0 || idx > params.size()) return false;
|
|
return params[idx]->getType() == typeid(T).hash_code();
|
|
}
|
|
|
|
void setDirtyBit(bool dirty) { dirtyBit = dirty; }
|
|
bool isDirty() const { return dirtyBit; }
|
|
|
|
typedef std::function<std::list<int>(CyclopsParams*, const Size&, bool)> ValidateFunc;
|
|
void setValidateFunc(ValidateFunc func) { validateFunc = func; }
|
|
std::list<int> isValid(const Size& sampleSize, bool fix) {
|
|
return validateFunc ? validateFunc(this, sampleSize, fix) : std::list<int>();
|
|
}
|
|
bool isValidSimple(const Size& sampleSize) {
|
|
return isValid(sampleSize, false).empty();
|
|
}
|
|
|
|
void backupAll() {
|
|
for (CyclopsParam* p : params) {
|
|
p->backup();
|
|
}
|
|
}
|
|
|
|
void restoreAll() {
|
|
for (CyclopsParam* p : params) {
|
|
p->restore();
|
|
}
|
|
setDirtyBit(true);
|
|
}
|
|
|
|
std::string print() const {
|
|
std::stringstream ss;
|
|
for (int i = 0; i < params.size(); ++i) {
|
|
const CyclopsParam* p = params[i];
|
|
p->print(ss);
|
|
ss << ",";
|
|
}
|
|
return ss.str();
|
|
}
|
|
|
|
protected:
|
|
friend class CyclopsGrids;
|
|
CyclopsParam* get(int idx) {
|
|
if (idx < 0 || idx > params.size()) return nullptr;
|
|
return params[idx];
|
|
}
|
|
|
|
const CyclopsParam* get(int idx) const {
|
|
if (idx < 0 || idx > params.size()) return nullptr;
|
|
return params[idx];
|
|
}
|
|
|
|
private:
|
|
std::vector<CyclopsParam*> params;
|
|
bool dirtyBit = true;
|
|
ValidateFunc validateFunc = nullptr;
|
|
};
|
|
|
|
#endif // CyclopsParam_h_
|
|
|