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

/*!
* \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_