[DEV] try to create variant type for auto parameter set ...

This commit is contained in:
Edouard DUPIN 2016-03-04 22:56:56 +01:00
parent b0dc65af0d
commit 53bb23e1c2
15 changed files with 341 additions and 283 deletions

View File

@ -7,17 +7,13 @@
*/
#pragma once
#include <eproperty/debug.h>
#include <eproperty/Interface.h>
#include <eproperty/Property.h>
#include <eproperty/PropertyType.h>
#include <map>
#include <typeinfo>
namespace eproperty {
template<typename TYPE> class List : public Property {
template<typename TYPE> class List : public PropertyType<TYPE> {
private:
TYPE m_value; //!< Element value ==> can be directly used.
TYPE m_default; //!< Default value.
std::map<std::string, TYPE> m_list; //!< pointer on the list of all elements.
public:
/**
@ -34,12 +30,8 @@ namespace eproperty {
const TYPE& _defaultValue,
const std::string& _description="",
void (CLASS_TYPE::*_setObs)()=nullptr) :
Property(_owner, _name),
m_value(_defaultValue),
m_default(_defaultValue) {
if (_setObs != nullptr) {
setObserver([=](){(*_owner.*_setObs)();});
}
eproperty::PropertyType<TYPE>(_owner, _name, _defaultValue, _description, _setObs) {
};
/**
* @brief Destructor.
@ -53,29 +45,15 @@ namespace eproperty {
}
m_list.insert(std::make_pair(_name, _value));
}
// herited methode
virtual std::string getPropertyType() const {
std::string getPropertyType() const override {
return "eproperty::List";
}
// herited methode
virtual std::string getType() const {
return typeid(TYPE).name();
}
// herited methode
virtual std::string getString() const {
return getElement(m_value);
}
// herited methode
virtual std::string getDefault() const {
return getElement(m_default);
}
// herited methode
virtual void setString(const std::string& _newVal) {
void setString(const std::string& _newVal) override {
auto it = m_list.find(_newVal);
if (it != m_list.end()) {
if (it->second != m_value) {
m_value = it->second;
notifyChange();
if (it->second != eproperty::PropertyType<TYPE>::m_value) {
eproperty::PropertyType<TYPE>::m_value = it->second;
eproperty::PropertyType<TYPE>::notifyChange();
}
return;
}
@ -84,94 +62,44 @@ namespace eproperty {
EPROPERTY_VERBOSE(" element : " << it.first);
}
}
// herited methode
virtual std::string getInfo() const {
std::string list = "List default=" + getElement(m_default) + " in : [";
std::string getInfo() const override {
std::string list = "List default=" + getValueSpecific(eproperty::PropertyType<TYPE>::m_default) + " in : [";
for (auto &it : m_list) {
list += it.first + "/";
}
return list + "]";
}
// herited methode
virtual bool isDefault() const {
return m_value == m_default;
}
// herited methode
virtual void setDefault() {
set(m_default);
}
void setDefaultValue(const TYPE& _value) {
m_default = _value;
}
/**
* @brief Get the value of the current parameter.
* @return the Reference value
*/
const inline TYPE& get() const {
return m_value;
};
/**
* @brief Set the value of the current parameter.
* @param[in] _newVal New value of the parameter. (not set if out of range)
*/
void set(TYPE _newVal) {
if (_newVal == m_value) {
void set(const TYPE& _newVal) override {
if (_newVal == eproperty::PropertyType<TYPE>::m_value) {
return;
}
for (auto &it : m_list) {
if (it.second == _newVal) {
m_value = it.second;
notifyChange();
eproperty::PropertyType<TYPE>::m_value = it.second;
eproperty::PropertyType<TYPE>::notifyChange();
return;
}
}
EPROPERTY_WARNING("paramList value=??? is not un the list ... ==> no change");
}
/**
* @brief Set the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @param[in] newVal New value to set
*/
inline void setDirect(const TYPE& _newVal) {
m_value = _newVal;
};
/**
* @brief Get the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @return a reference on the value
*/
TYPE& getDirect() {
return m_value;
}
private:
/**
* @brief Get the element description from real Value.
* @param[in] _intValue value that might be converted in string.
* @return the description string coresponding to this ID.
*/
std::string getElement(TYPE _intValue) const {
std::string getValueSpecific(const TYPE& _valueRequested) const override {
for (auto &it : m_list) {
if (it.second == _intValue) {
if (it.second == _valueRequested) {
return it.first;
}
}
return "???";
}
public:
const List<TYPE>& operator= (const TYPE& _newVal) = delete;
operator const TYPE&() const {
return m_value;
}
const TYPE& operator *() const noexcept {
return m_value;
}
const TYPE* operator->() const noexcept {
return &m_value;
}
};
template<typename TYPE> std::ostream& operator <<(std::ostream& _os, const eproperty::List<TYPE>& _obj) {
_os << _obj.get();

View File

@ -8,6 +8,7 @@
#pragma once
#include <eproperty/Interface.h>
#include <eproperty/VariantBase.h>
#include <string>
#include <typeinfo>
#include <functional>
@ -75,6 +76,7 @@ namespace eproperty {
* @brief Reset the value to the default value.
*/
virtual void setDefault() = 0;
virtual void setVariant(eproperty::VariantBase* _variantValue) = 0;
public:
template<class TYPE>
bool operator== (const TYPE& _obj) const = delete;

153
eproperty/PropertyType.h Normal file
View File

@ -0,0 +1,153 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <eproperty/Interface.h>
#include <eproperty/Property.h>
#include <eproperty/VariantBase.h>
#include <eproperty/debug.h>
namespace eproperty {
template<typename TYPE> class VariantSpecify : public eproperty::VariantBase {
private:
TYPE m_value;
public:
VariantSpecify() :
eproperty::VariantBase(uint64_t(typeid(TYPE))),
m_value() {
}
VariantSpecify(TYPE&& _value) :
eproperty::VariantBase(uint64_t(typeid(TYPE))),
m_value(_value) {
}
const TYPE& get() {
return m_value;
}
};
template<typename TYPE> class PropertyType : public Property {
protected:
TYPE m_value; //!< Current value.
TYPE m_default; //!< Default value.
public:
/**
* @brief Create a parameter with a specific type.
* @param[in] _owner Owner of the parameter.
* @param[in] _name Static name of the parameter.
* @param[in] _defaultValue Default value of the parameter.
* @param[in] _description description of the parameter.
* @param[in] _setObs function of the class that opserve the change of the value
*/
template<class CLASS_TYPE>
PropertyType(CLASS_TYPE* _owner,
const std::string& _name,
const TYPE& _defaultValue,
const std::string& _description = "",
void (CLASS_TYPE::*_setObs)()=nullptr) :
Property(_owner, _name),
m_value(_defaultValue),
m_default(_defaultValue) {
if (_setObs != nullptr) {
setObserver([=](){(*_owner.*_setObs)();});
}
}
/**
* @brief Destructor.
*/
virtual ~PropertyType() = default;
std::string getPropertyType() const override {
return "eproperty::Value";
}
std::string getType() const override {
return typeid(TYPE).name();
}
std::string getString() const override {
return getValueSpecific(m_value);
}
std::string getDefault() const override {
return getValueSpecific(m_default);
}
std::string getInfo() const override {
return getType() + " default=" + getDefault();
}
bool isDefault() const override {
return m_value == m_default;
}
void setDefault() override {
set(m_default);
}
public:
/**
* @brief Get the value of the current parameter.
* @note For performence, this function must be inline
* @return the Reference value
*/
const inline TYPE& get() const {
return m_value;
};
/**
* @brief Set a new value for this parameter
* @param[in] newVal New value to set (set the nearest value if range is set)
*/
virtual void set(const TYPE& _newVal) {
if (_newVal != m_value) {
m_value = _newVal;
notifyChange();
}
}
void setVariant(eproperty::VariantBase* _variantValue) override {
eproperty::VariantSpecify<TYPE>* value = dynamic_cast<eproperty::VariantSpecify<TYPE>*>(_variantValue);
if (value == nullptr) {
EPROPERTY_ERROR("Can not set property : '" << getName() << "' wrong variant type ...");
return;
}
// TODO : Check range ...
setDirect(value->get());
}
/**
* @brief Set the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @param[in] newVal New value to set
*/
inline void setDirect(const TYPE& _newVal) {
m_value = _newVal;
}
/**
* @brief Get the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @return a reference on the value
*/
TYPE& getDirect() {
return m_value;
}
virtual std::string getValueSpecific(const TYPE& _valueRequested) const = 0;
public:
operator const TYPE&() const {
return m_value;
}
const TYPE& operator *() const noexcept {
return m_value;
}
const TYPE* operator->() const noexcept {
return &m_value;
}
const PropertyType<TYPE>& operator= (const TYPE& _newVal) = delete;
};
template<typename TYPE> std::ostream& operator <<(std::ostream& _os, const eproperty::PropertyType<TYPE>& _obj) {
_os << _obj.get();
return _os;
}
}

View File

@ -8,16 +8,14 @@
#pragma once
#include <eproperty/Interface.h>
#include <eproperty/Property.h>
#include <eproperty/Value.h>
#include <typeinfo>
namespace eproperty {
template<typename TYPE> class Range : public Property {
template<typename TYPE> class Range : public Value<TYPE> {
private:
TYPE m_value; //!< Current value.
TYPE m_min; //!< Minimum value.
TYPE m_max; //!< Maximum value.
TYPE m_default; //!< Default value.
public:
/**
* @brief Create a parameter with a specific type.
@ -37,122 +35,48 @@ namespace eproperty {
const TYPE& _max,
const std::string& _description = "",
void (CLASS_TYPE::*_setObs)()=nullptr) :
Property(_owner, _name),
m_value(_defaultValue),
eproperty::Value<TYPE>(_owner, _name, _defaultValue, _description, _setObs),
m_min(_min),
m_max(_max),
m_default(_defaultValue) {
m_max(_max) {
if (m_min > m_max) {
//EPROPERTY_CRITICAL("min > max...");
}
if (_setObs != nullptr) {
setObserver([=](){(*_owner.*_setObs)();});
}
};
/**
* @brief Destructor.
*/
virtual ~Range() = default;
// herited methode
virtual std::string getPropertyType() const {
std::string getPropertyType() const override {
return "eproperty::Range";
}
// herited methode
virtual std::string getType() const {
return typeid(TYPE).name();
}
// herited methode
virtual std::string getString() const {
return getValueSpecific(m_value);
};
// herited methode
virtual std::string getDefault() const {
return getValueSpecific(m_default);
};
// herited methode
virtual void setString(const std::string& _newVal) {
void setString(const std::string& _newVal) override {
TYPE val;
// when you want to set an element in parameter you will implement the function template std::from_string
etk::from_string(val, _newVal);
set(val);
}
// herited methode
virtual std::string getInfo() const {
return getType() + " default=" + getDefault();
}
// herited methode
virtual bool isDefault() const {
return m_value == m_default;
}
// herited methode
virtual void setDefault() {
set(m_default);
std::string getInfo() const override {
return eproperty::Value<TYPE>::getType() + " default=" + eproperty::Value<TYPE>::getDefault();
}
public:
/**
* @brief Get the value of the current parameter.
* @return The reference value
*/
const inline TYPE& get() const {
return m_value;
};
/**
* @brief Set a new value for this parameter
* @param[in] newVal New value to set (set the nearest value if range is set)
*/
void set(const TYPE& _newVal) {
void set(const TYPE& _newVal) override {
if (m_min == m_max) {
if (_newVal != m_value) {
m_value = _newVal;
notifyChange();
if (_newVal != eproperty::Value<TYPE>::m_value) {
eproperty::Value<TYPE>::m_value = _newVal;
eproperty::Value<TYPE>::notifyChange();
}
} else {
TYPE newVal = std::avg(m_min, _newVal, m_max);
if (newVal != m_value) {
m_value = newVal;
notifyChange();
if (newVal != eproperty::Value<TYPE>::m_value) {
eproperty::Value<TYPE>::m_value = newVal;
eproperty::Value<TYPE>::notifyChange();
}
}
}
/**
* @brief Set the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @param[in] newVal New value to set
*/
inline void setDirect(const TYPE& _newVal) {
m_value = _newVal;
};
/**
* @brief Get the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @return a reference on the value
*/
TYPE& getDirect() {
return m_value;
}
private:
/**
* @brief Get the string of the specify value.
* @return convetion of the velue in string.
*/
std::string getValueSpecific(const TYPE& _valueRequested) const {
return etk::to_string(_valueRequested);
}
public:
const Range<TYPE>& operator= (const TYPE& _newVal) = delete;
operator const TYPE&() const {
return m_value;
}
const TYPE& operator*() const noexcept {
return m_value;
}
const TYPE* operator->() const noexcept {
return &m_value;
}
};
template<typename TYPE> std::ostream& operator <<(std::ostream& _os, const eproperty::Range<TYPE>& _obj) {

View File

@ -7,15 +7,11 @@
*/
#pragma once
#include <eproperty/Interface.h>
#include <eproperty/Property.h>
#include <eproperty/PropertyType.h>
namespace eproperty {
template<typename TYPE> class Value : public Property {
private:
TYPE m_value; //!< Current value.
TYPE m_default; //!< Default value.
template<typename TYPE> class Value : public PropertyType<TYPE> {
public:
/**
* @brief Create a parameter with a specific type.
@ -31,110 +27,23 @@ namespace eproperty {
const TYPE& _defaultValue,
const std::string& _description = "",
void (CLASS_TYPE::*_setObs)()=nullptr) :
Property(_owner, _name),
m_value(_defaultValue),
m_default(_defaultValue) {
if (_setObs != nullptr) {
setObserver([=](){(*_owner.*_setObs)();});
}
eproperty::PropertyType<TYPE>(_owner, _name, _defaultValue, _description, _setObs) {
}
/**
* @brief Destructor.
*/
virtual ~Value() = default;
// herited methode
virtual std::string getPropertyType() const {
return "eproperty::Value";
}
// herited methode
virtual std::string getType() const {
return typeid(TYPE).name();
}
// herited methode
virtual std::string getString() const {
return getValueSpecific(m_value);
}
// herited methode
virtual std::string getDefault() const {
return getValueSpecific(m_default);
}
// herited methode
virtual void setString(const std::string& _newVal) {
// when you want to set an element in parameter you will implement the function template std::from_string
etk::from_string(m_value, _newVal);
// TODO : Do it better ...
notifyChange();
}
// herited methode
virtual std::string getInfo() const {
return getType() + " default=" + getDefault();
}
// herited methode
virtual bool isDefault() const {
return m_value == m_default;
}
// herited methode
virtual void setDefault() {
set(m_default);
}
public:
/**
* @brief Get the value of the current parameter.
* @note For performence, this function must be inline
* @return the Reference value
*/
const inline TYPE& get() const {
return m_value;
};
/**
* @brief Set a new value for this parameter
* @param[in] newVal New value to set (set the nearest value if range is set)
*/
void set(const TYPE& _newVal) {
if (_newVal != m_value) {
m_value = _newVal;
notifyChange();
}
}
/**
* @brief Set the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @param[in] newVal New value to set
*/
inline void setDirect(const TYPE& _newVal) {
m_value = _newVal;
}
/**
* @brief Get the value of the current parameter (no check (for internal set with no check).
* @note For performence, this function must be inline
* @note Only use by the owner of the property (can not be check on compile time for now ...)
* TODO: Do it better ... compile check
* @return a reference on the value
*/
TYPE& getDirect() {
return m_value;
}
private:
protected:
/**
* @brief Get the string of the specify value.
* @return convetion of the velue in string.
*/
std::string getValueSpecific(const TYPE& _valueRequested) const {
std::string getValueSpecific(const TYPE& _valueRequested) const override {
return etk::to_string(_valueRequested);
}
public:
operator const TYPE&() const {
return m_value;
void setString(const std::string& _newVal) override {
// when you want to set an element in parameter you will implement the function template std::from_string
etk::from_string(eproperty::PropertyType<TYPE>::m_value, _newVal);
// TODO : Do it better ...
eproperty::PropertyType<TYPE>::notifyChange();
}
const TYPE& operator *() const noexcept {
return m_value;
}
const TYPE* operator->() const noexcept {
return &m_value;
}
const Value<TYPE>& operator= (const TYPE& _newVal) = delete;
};
template<typename TYPE> std::ostream& operator <<(std::ostream& _os, const eproperty::Value<TYPE>& _obj) {

14
eproperty/Variant.cpp Normal file
View File

@ -0,0 +1,14 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <eproperty/debug.h>
#include <eproperty/Variant.h>
eproperty::Variant::~Variant() {
}

28
eproperty/Variant.h Normal file
View File

@ -0,0 +1,28 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <eproperty/Interface.h>
#include <eproperty/Property.h>
#include <eproperty/VariantBase.h>
#include <eproperty/Value.h>
namespace eproperty {
class Variant {
private:
std::unique_ptr<VariantBase> m_value;
public:
template<class TYPE>
Variant(TYPE&& _value):
m_value() {
eproperty::VariantSpecify<TYPE>* _val = new eproperty::VariantSpecify<TYPE>();
}
~Variant();
};
}

View File

25
eproperty/VariantBase.h Normal file
View File

@ -0,0 +1,25 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <eproperty/Interface.h>
#include <eproperty/Property.h>
namespace eproperty {
class VariantBase {
protected:
uint64_t m_type;
public:
VariantBase(const uint64_t& _type) :
m_type(_type) {
}
virtual ~VariantBase() = default;
};
}

39
lutin_eproperty-test.py Normal file
View File

@ -0,0 +1,39 @@
#!/usr/bin/python
import lutin.module as module
import lutin.tools as tools
import datetime
def get_type():
return "BINARY"
def get_sub_type():
return "TEST"
def get_desc():
return "e-property test software"
def get_licence():
return "APACHE-2"
def get_compagny_type():
return "com"
def get_compagny_name():
return "atria-soft"
def get_maintainer():
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
def create(target, module_name):
my_module = module.Module(__file__, module_name, get_type())
my_module.add_src_file([
'test/main.cpp',
'test/declareSignals.cpp',
'test/test_list.cpp',
'test/test_range.cpp',
'test/test_value.cpp'
])
my_module.add_module_depend(['eproperty', 'gtest', 'test-debug'])
return my_module

View File

@ -33,14 +33,18 @@ def create(target, module_name):
'eproperty/debug.cpp',
'eproperty/Property.cpp',
'eproperty/Interface.cpp',
'eproperty/Variant.cpp',
])
my_module.add_header_file([
'eproperty/debug.h',
'eproperty/Value.h',
'eproperty/Interface.h',
'eproperty/Property.h',
'eproperty/PropertyType.h',
'eproperty/Range.h',
'eproperty/List.h'
'eproperty/List.h',
'eproperty/Variant.h',
'eproperty/VariantBase.h'
])
my_module.add_module_depend(['etk'])
my_module.add_path(tools.get_current_path(__file__))

32
test/main.cpp Normal file
View File

@ -0,0 +1,32 @@
/**
* @author Edouard DUPIN
*
* @copyright 2016, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#define NAME "Empty"
#include <etk/types.h>
#include <etk/etk.h>
#include <test-debug/debug.h>
#include <gtest/gtest.h>
#undef __class__
#define __class__ "eproperty-test"
int main(int _argc, const char *_argv[]) {
::testing::InitGoogleTest(&_argc, const_cast<char **>(_argv));
etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if ( data == "-h"
|| data == "--help") {
TEST_PRINT("eproperty-test - help : ");
TEST_PRINT(" " << _argv[0] << " [options]");
TEST_PRINT(" No optiions ...");
return -1;
}
}
return RUN_ALL_TESTS();
}

0
test/test_list.cpp Normal file
View File

0
test/test_range.cpp Normal file
View File

0
test/test_value.cpp Normal file
View File