before formatting

This commit is contained in:
2022-12-14 13:56:19 +03:00
parent c74ba871cd
commit 430a41fefc
14 changed files with 912 additions and 623 deletions

View File

@@ -25,16 +25,16 @@
struct PIP_EXPORT PIIntrospectionContainersType {
~PIIntrospectionContainersType();
void finish();
uint id = 0;
const char * name = nullptr;
uint id = 0;
const char * name = nullptr;
const char * demangled = "?";
bool inited = false;
bool has_demangled = false;
bool inited = false;
bool has_demangled = false;
};
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
#include "piintrospection_base.h"
# include "piintrospection_base.h"
class PIIntrospectionContainers;
@@ -45,6 +45,7 @@ public:
static PIIntrospectionContainersType ret = create();
return ret;
}
private:
static PIIntrospectionContainersType create() {
PIIntrospectionContainersType ret;
@@ -54,35 +55,39 @@ private:
}
};
#define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance())
# define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance())
# define PIINTROSPECTION_CONTAINER_NEW(t, isz) PIINTROSPECTION_CONTAINERS->containerNew (PIIntrospectionContainersTypeInfo<t>::get(), isz);
# define PIINTROSPECTION_CONTAINER_DELETE(t) PIINTROSPECTION_CONTAINERS->containerDelete(PIIntrospectionContainersTypeInfo<t>::get());
# define PIINTROSPECTION_CONTAINER_ALLOC(t, cnt) PIINTROSPECTION_CONTAINERS->containerAlloc (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_FREE(t, cnt) PIINTROSPECTION_CONTAINERS->containerFree (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_USED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUsed (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUnused(PIIntrospectionContainersTypeInfo<t>::get(), cnt);
// clang-format off
# define PIINTROSPECTION_CONTAINER_NEW (t, isz) PIINTROSPECTION_CONTAINERS->containerNew (PIIntrospectionContainersTypeInfo<t>::get(), isz);
# define PIINTROSPECTION_CONTAINER_DELETE(t ) PIINTROSPECTION_CONTAINERS->containerDelete(PIIntrospectionContainersTypeInfo<t>::get() );
# define PIINTROSPECTION_CONTAINER_ALLOC (t, cnt) PIINTROSPECTION_CONTAINERS->containerAlloc (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_FREE (t, cnt) PIINTROSPECTION_CONTAINERS->containerFree (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_USED (t, cnt) PIINTROSPECTION_CONTAINERS->containerUsed (PIIntrospectionContainersTypeInfo<t>::get(), cnt);
# define PIINTROSPECTION_CONTAINER_UNUSED(t, cnt) PIINTROSPECTION_CONTAINERS->containerUnused(PIIntrospectionContainersTypeInfo<t>::get(), cnt);
// clang-format on
class PIP_EXPORT PIIntrospectionContainersInterface {
friend class PIIntrospection;
friend class PIIntrospectionServer;
public:
__PIINTROSPECTION_SINGLETON_H__(Containers)
// clang-format off
void containerNew (const PIIntrospectionContainersType & ti, uint isz);
void containerDelete(const PIIntrospectionContainersType & ti);
void containerAlloc (const PIIntrospectionContainersType & ti, ullong cnt);
void containerFree (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUsed (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUnused(const PIIntrospectionContainersType & ti, ullong cnt);
// clang-format on
PIIntrospectionContainers * p;
private:
PIIntrospectionContainersInterface();
~PIIntrospectionContainersInterface();
};
@@ -96,5 +101,4 @@ private:
#endif
#endif // PIINTROSPECTION_CONTAINERS_H

View File

@@ -20,10 +20,12 @@
#ifndef PIINTROSPECTION_CONTAINERS_P_H
#define PIINTROSPECTION_CONTAINERS_P_H
#include "piintrospection_containers.h"
#include "pispinlock.h"
#include "pistring.h"
#include <map>
#include <string>
#include "picrc.h"
class PIP_EXPORT PIIntrospectionContainers {
@@ -32,28 +34,30 @@ public:
struct TypeInfo;
// clang-format off
void containerNew (const PIIntrospectionContainersType & ti, uint isz);
void containerDelete(const PIIntrospectionContainersType & ti);
void containerAlloc (const PIIntrospectionContainersType & ti, ullong cnt);
void containerFree (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUsed (const PIIntrospectionContainersType & ti, ullong cnt);
void containerUnused(const PIIntrospectionContainersType & ti, ullong cnt);
// clang-format on
PIVector<TypeInfo> getInfo() const;
#pragma pack(push, 1)
struct PIP_EXPORT _Type {
uint id = 0u;
uint count = 0u;
uint item_size = 0u;
uint id = 0u;
uint count = 0u;
uint item_size = 0u;
ullong allocated = 0u;
ullong used = 0u;
ullong used = 0u;
};
#pragma pack(pop)
struct PIP_EXPORT TypeInfo: _Type {
ullong allocated_bytes = 0u;
ullong used_bytes = 0u;
ullong used_bytes = 0u;
PIString name;
PIString item_size_str;
PIString allocated_str;

View File

@@ -22,25 +22,29 @@
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
#include "piintrospection_base.h"
# include "piintrospection_base.h"
class PIIntrospectionThreads;
#define PIINTROSPECTION_THREADS (PIIntrospectionThreadsInterface::instance())
# define PIINTROSPECTION_THREADS (PIIntrospectionThreadsInterface::instance())
# define PIINTROSPECTION_THREAD_NEW(t) PIINTROSPECTION_THREADS->threadNew (t);
# define PIINTROSPECTION_THREAD_DELETE(t) PIINTROSPECTION_THREADS->threadDelete (t);
# define PIINTROSPECTION_THREAD_START(t) PIINTROSPECTION_THREADS->threadStart (t);
# define PIINTROSPECTION_THREAD_RUN(t) PIINTROSPECTION_THREADS->threadRun (t);
# define PIINTROSPECTION_THREAD_WAIT(t) PIINTROSPECTION_THREADS->threadWait (t);
# define PIINTROSPECTION_THREAD_STOP(t) PIINTROSPECTION_THREADS->threadStop (t);
# define PIINTROSPECTION_THREAD_RUN_DONE(t,us) PIINTROSPECTION_THREADS->threadRunDone(t,us);
// clang-format off
# define PIINTROSPECTION_THREAD_NEW (t ) PIINTROSPECTION_THREADS->threadNew (t );
# define PIINTROSPECTION_THREAD_DELETE (t ) PIINTROSPECTION_THREADS->threadDelete (t );
# define PIINTROSPECTION_THREAD_START (t ) PIINTROSPECTION_THREADS->threadStart (t );
# define PIINTROSPECTION_THREAD_RUN (t ) PIINTROSPECTION_THREADS->threadRun (t );
# define PIINTROSPECTION_THREAD_WAIT (t ) PIINTROSPECTION_THREADS->threadWait (t );
# define PIINTROSPECTION_THREAD_STOP (t ) PIINTROSPECTION_THREADS->threadStop (t );
# define PIINTROSPECTION_THREAD_RUN_DONE(t,us) PIINTROSPECTION_THREADS->threadRunDone(t,us);
// clang-format on
class PIP_EXPORT PIIntrospectionThreadsInterface {
friend class PIIntrospection;
public:
__PIINTROSPECTION_SINGLETON_H__(Threads)
// clang-format off
void threadNew (PIThread * t);
void threadDelete (PIThread * t);
void threadStart (PIThread * t);
@@ -48,13 +52,13 @@ public:
void threadWait (PIThread * t);
void threadStop (PIThread * t);
void threadRunDone(PIThread * t, ullong us);
// clang-format on
private:
PIIntrospectionThreadsInterface();
~PIIntrospectionThreadsInterface();
PIIntrospectionThreads * p;
};
#else
@@ -64,7 +68,7 @@ private:
# define PIINTROSPECTION_THREAD_RUN(t)
# define PIINTROSPECTION_THREAD_WAIT(t)
# define PIINTROSPECTION_THREAD_STOP(t)
# define PIINTROSPECTION_THREAD_RUN_DONE(t,us)
# define PIINTROSPECTION_THREAD_RUN_DONE(t, us)
#endif
#endif // PIINTROSPECTION_THREADS_H

View File

@@ -44,6 +44,7 @@ public:
ullong run_us, run_count;
};
// clang-format off
void threadNew (PIThread * t);
void threadDelete (PIThread * t);
void threadStart (PIThread * t);
@@ -51,10 +52,10 @@ public:
void threadWait (PIThread * t);
void threadStop (PIThread * t);
void threadRunDone(PIThread * t, ullong us);
// clang-format on
PIMap<PIThread*, ThreadInfo> threads;
PIMap<PIThread *, ThreadInfo> threads;
PIMutex mutex;
};

View File

@@ -29,6 +29,7 @@
#include "piiodevice.h"
#include "piiostream.h"
// clang-format off
#define PICONFIG_GET_VALUE \
Entry & getValue(const PIString & vname, const char * def, bool * exists = 0) {return getValue(vname, PIString(def), exists);} \
Entry & getValue(const PIString & vname, const PIStringList & def, bool * exists = 0) {return getValue(vname, def.join("%|%"), exists);} \
@@ -55,13 +56,13 @@
Entry & getValue(const PIString & vname, const ulong def, bool * exists = 0) const {return getValue(vname, PIString::fromNumber(def), exists);} \
Entry & getValue(const PIString & vname, const float def, bool * exists = 0) const {return getValue(vname, PIString::fromNumber(def), exists);} \
Entry & getValue(const PIString & vname, const double def, bool * exists = 0) const {return getValue(vname, PIString::fromNumber(def), exists);}
// clang-format on
class PIP_EXPORT PIConfig
{
class PIP_EXPORT PIConfig {
friend class Entry;
friend class Branch;
public:
public:
//! Contructs and read configuration file at path "path" in mode "mode"
PIConfig(const PIString & path, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite);
@@ -76,18 +77,21 @@ public:
class Entry;
class PIP_EXPORT Branch: public PIVector<Entry * > {
class PIP_EXPORT Branch: public PIVector<Entry *> {
friend class PIConfig;
friend class Entry;
#ifdef PIP_STD_IOSTREAM
friend std::ostream & operator <<(std::ostream & s, const Branch & v);
friend std::ostream & operator<<(std::ostream & s, const Branch & v);
#endif
friend PICout operator <<(PICout s, const Branch & v);
friend PICout operator<<(PICout s, const Branch & v);
public:
Branch() {;}
Branch() { ; }
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0);
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {return const_cast<Branch * >(this)->getValue(vname, def, exists);}
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {
return const_cast<Branch *>(this)->getValue(vname, def, exists);
}
PICONFIG_GET_VALUE
Branch allLeaves();
@@ -95,125 +99,226 @@ public:
Branch getLeaves();
Branch getBranches();
Branch & filter(const PIString & f);
bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;}
int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;}
bool isEntryExists(const PIString & name) const {
piForeachC(Entry * i, *this)
if (entryExists(i, name)) return true;
return false;
}
int indexOf(const Entry * e) {
for (int i = 0; i < size_s(); ++i)
if (at(i) == e) return i;
return -1;
}
private:
bool entryExists(const Entry * e, const PIString & name) const;
void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}}
void allLeaves(Branch & b, Entry * e) {
piForeach(Entry * i, e->_children) {
if (i->isLeaf())
b << i;
else
allLeaves(b, i);
}
}
#ifdef PIP_STD_IOSTREAM
void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);}
void coutt(std::ostream & s, const PIString & p) const {
piForeachC(Entry * i, *this)
i->coutt(s, p);
}
#endif
void piCoutt(PICout s, const PIString & p) const {piForeachC (Entry * i, *this) i->piCoutt(s, p);}
void piCoutt(PICout s, const PIString & p) const {
piForeachC(Entry * i, *this)
i->piCoutt(s, p);
}
static Entry _empty;
PIString delim;
};
class PIP_EXPORT Entry {
friend class PIConfig;
friend class Branch;
public:
Entry() {_parent = 0; _line = -1;}
Entry() {
_parent = 0;
_line = -1;
}
//! Returns parent entry, or 0 if there is no parent (root of default value)
Entry * parent() const {return _parent;}
Entry * parent() const { return _parent; }
//! Returns children count
int childCount() const {return _children.size_s();}
int childCount() const { return _children.size_s(); }
//! Returns children as \a PIConfig::Branch
Branch & children() const {_children.delim = delim; return _children;}
Branch & children() const {
_children.delim = delim;
return _children;
}
//! Returns child at index "index"
Entry * child(const int index) const {return _children[index];}
Entry * child(const int index) const { return _children[index]; }
//! Returns first child with name "name"
Entry * findChild(const PIString & name) {piForeach (Entry * i, _children) if (i->_name == name) return i; return 0;}
Entry * findChild(const PIString & name) {
piForeach(Entry * i, _children)
if (i->_name == name) return i;
return 0;
}
//! Returns first child with name "name"
const Entry * findChild(const PIString & name) const {piForeachC (Entry * i, _children) if (i->_name == name) return i; return 0;}
const Entry * findChild(const PIString & name) const {
piForeachC(Entry * i, _children)
if (i->_name == name) return i;
return 0;
}
//! Returns \b true if there is no children
bool isLeaf() const {return _children.isEmpty();}
bool isLeaf() const { return _children.isEmpty(); }
//! Returns name
const PIString & name() const {return _name;}
const PIString & name() const { return _name; }
//! Returns value
const PIString & value() const {return _value;}
const PIString & value() const { return _value; }
//! Returns type
const PIString & type() const {return _type;}
const PIString & type() const { return _type; }
//! Returns comment
const PIString & comment() const {return _comment;}
const PIString & comment() const { return _comment; }
/** \brief Returns full name, i.e. name as it looks in file
* \details In case of default entry full name always is empty
* \snippet piconfig.cpp fullName */
const PIString & fullName() const {return _full_name;}
const PIString & fullName() const { return _full_name; }
//! Set name to "value" and returns this
Entry & setName(const PIString & value) {_name = value; return *this;}
Entry & setName(const PIString & value) {
_name = value;
return *this;
}
//! Set type to "value" and returns this
Entry & setType(const PIString & value) {_type = value; return *this;}
Entry & setType(const PIString & value) {
_type = value;
return *this;
}
//! Set comment to "value" and returns this
Entry & setComment(const PIString & value) {_comment = value; return *this;}
Entry & setComment(const PIString & value) {
_comment = value;
return *this;
}
//! Set value to "value" and returns this
Entry & setValue(const PIString & value) {_value = value; return *this;}
Entry & setValue(const PIString & value) {
_value = value;
return *this;
}
//! Set value to "value" and returns this. Type is set to "l"
Entry & setValue(const PIStringList & value) {setValue(value.join("%|%")); setType("l"); return *this;}
Entry & setValue(const PIStringList & value) {
setValue(value.join("%|%"));
setType("l");
return *this;
}
//! Set value to "value" and returns this. Type is set to "s"
Entry & setValue(const char * value) {setValue(PIString(value)); setType("s"); return *this;}
Entry & setValue(const char * value) {
setValue(PIString(value));
setType("s");
return *this;
}
//! Set value to "value" and returns this. Type is set to "b"
Entry & setValue(const bool value) {setValue(PIString::fromBool(value)); setType("b"); return *this;}
Entry & setValue(const bool value) {
setValue(PIString::fromBool(value));
setType("b");
return *this;
}
//! Set value to "value" and returns this. Type is set to "s"
Entry & setValue(const char value) {setValue(PIString(1, value)); setType("s"); return *this;}
Entry & setValue(const char value) {
setValue(PIString(1, value));
setType("s");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const short value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const short value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const int value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const int value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const long value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const long value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const uchar value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const uchar value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const ushort value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const ushort value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const uint value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const uint value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "n"
Entry & setValue(const ulong value) {setValue(PIString::fromNumber(value)); setType("n"); return *this;}
Entry & setValue(const ulong value) {
setValue(PIString::fromNumber(value));
setType("n");
return *this;
}
//! Set value to "value" and returns this. Type is set to "f"
Entry & setValue(const float value) {setValue(PIString::fromNumber(value)); setType("f"); return *this;}
Entry & setValue(const float value) {
setValue(PIString::fromNumber(value));
setType("f");
return *this;
}
//! Set value to "value" and returns this. Type is set to "f"
Entry & setValue(const double value) {setValue(PIString::fromNumber(value)); setType("f"); return *this;}
Entry & setValue(const double value) {
setValue(PIString::fromNumber(value));
setType("f");
return *this;
}
/** \brief Returns entry with name "vname" and default value "def"
* \details If there is no suitable entry found, reference to default internal entry with
* value = "def" will be returned, and if "exists" not null it will be set to \b false */
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0);
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {return const_cast<Entry * >(this)->getValue(vname, def, exists);}
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {
return const_cast<Entry *>(this)->getValue(vname, def, exists);
}
PICONFIG_GET_VALUE
//! \fn Entry & getValue(const PIString & vname, const char * def, bool * exists = 0)
@@ -261,58 +366,68 @@ public:
//! If there is no children returns if name == "name". Else returns if any child has name == "name"
bool isEntryExists(const PIString & name) const {return entryExists(this, name);}
bool isEntryExists(const PIString & name) const { return entryExists(this, name); }
//! Convertion to boolean
bool toBool() const {return _value.toBool();}
bool toBool() const { return _value.toBool(); }
//! Convertion to char
char toChar() const {return (_value.isEmpty() ? 0 : _value[0].toAscii());}
char toChar() const { return (_value.isEmpty() ? 0 : _value[0].toAscii()); }
//! Convertion to short
short toShort() const {return _value.toShort();}
short toShort() const { return _value.toShort(); }
//! Convertion to int
int toInt() const {return _value.toInt();}
int toInt() const { return _value.toInt(); }
//! Convertion to long
long toLong() const {return _value.toLong();}
long toLong() const { return _value.toLong(); }
//! Convertion to uchar
uchar toUChar() const {return _value.toInt();}
uchar toUChar() const { return _value.toInt(); }
//! Convertion to ushort
ushort toUShort() const {return _value.toShort();}
ushort toUShort() const { return _value.toShort(); }
//! Convertion to uint
uint toUInt() const {return _value.toInt();}
uint toUInt() const { return _value.toInt(); }
//! Convertion to ulong
ulong toULong() const {return _value.toLong();}
ulong toULong() const { return _value.toLong(); }
//! Convertion to float
float toFloat() const {return _value.toFloat();}
float toFloat() const { return _value.toFloat(); }
//! Convertion to double
double toDouble() const {return _value.toDouble();}
double toDouble() const { return _value.toDouble(); }
//! Convertion to PIString
PIString toString() const {return _value;}
PIString toString() const { return _value; }
//! Convertion to PIStringList
PIStringList toStringList() const {return _value.split("%|%");}
PIStringList toStringList() const { return _value.split("%|%"); }
private:
static bool compare(PIConfig::Entry * const & f, PIConfig::Entry * const & s) {return f->_line < s->_line;}
static bool compare(PIConfig::Entry * const & f, PIConfig::Entry * const & s) { return f->_line < s->_line; }
bool entryExists(const Entry * e, const PIString & name) const;
void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;}
void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;}
void buildLine() { _all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment; }
void clear() {
_children.clear();
_name = _value = _type = _comment = _all = PIString();
_line = 0;
_parent = 0;
}
#ifdef PIP_STD_IOSTREAM
void coutt(std::ostream & s, const PIString & p) const;
#endif
void piCoutt(PICout s, const PIString & p) const;
void deleteBranch() {piForeach (Entry * i, _children) {i->deleteBranch(); delete i;}}
void deleteBranch() {
piForeach(Entry * i, _children) {
i->deleteBranch();
delete i;
}
}
static Entry _empty;
Entry * _parent;
@@ -342,7 +457,9 @@ public:
//! Returns top-level entry with name "vname", if doesn`t exists return entry with value "def" and set *exist to false
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0);
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {return const_cast<PIConfig * >(this)->getValue(vname, def, exists);}
Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exists = 0) const {
return const_cast<PIConfig *>(this)->getValue(vname, def, exists);
}
PICONFIG_GET_VALUE
@@ -390,66 +507,91 @@ public:
Branch getValues(const PIString & vname);
//! Set top-level entry with name "name" value to "value", type to "type" and if "write" immediate write to file. Add new entry if there is no suitable exists
//! Set top-level entry with name "name" value to "value", type to "type" and if "write" immediate write to file. Add new entry if there
//! is no suitable exists
void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
//! Set top-level entry with name "name" value to "value", type to "l" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const PIStringList & value, bool write = true) {setValue(name, value.join("%|%"), "l", write);}
//! Set top-level entry with name "name" value to "value", type to "l" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const PIStringList & value, bool write = true) { setValue(name, value.join("%|%"), "l", write); }
//! Set top-level entry with name "name" value to "value", type to "s" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const char * value, bool write = true) {setValue(name, PIString(value), "s", write);}
//! Set top-level entry with name "name" value to "value", type to "s" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const char * value, bool write = true) { setValue(name, PIString(value), "s", write); }
//! Set top-level entry with name "name" value to "value", type to "b" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const bool value, bool write = true) {setValue(name, PIString::fromBool(value), "b", write);}
//! Set top-level entry with name "name" value to "value", type to "b" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const bool value, bool write = true) { setValue(name, PIString::fromBool(value), "b", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const short value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const short value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const int value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const int value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const long value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const long value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const uchar value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const uchar value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const ushort value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const ushort value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const uint value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const uint value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const ulong value, bool write = true) {setValue(name, PIString::fromNumber(value), "n", write);}
//! Set top-level entry with name "name" value to "value", type to "n" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const ulong value, bool write = true) { setValue(name, PIString::fromNumber(value), "n", write); }
//! Set top-level entry with name "name" value to "value", type to "f" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const float value, bool write = true) {setValue(name, PIString::fromNumber(value), "f", write);}
//! Set top-level entry with name "name" value to "value", type to "f" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const float value, bool write = true) { setValue(name, PIString::fromNumber(value), "f", write); }
//! Set top-level entry with name "name" value to "value", type to "f" and if "write" immediate write to file. Add new entry if there is no suitable exists
void setValue(const PIString & name, const double value, bool write = true) {setValue(name, PIString::fromNumber(value), "f", write);}
//! Set top-level entry with name "name" value to "value", type to "f" and if "write" immediate write to file. Add new entry if there is
//! no suitable exists
void setValue(const PIString & name, const double value, bool write = true) { setValue(name, PIString::fromNumber(value), "f", write); }
//! Returns root entry
Entry & rootEntry() {return root;}
Entry & rootEntry() { return root; }
//! Returns top-level entries count
int entriesCount() const {return childCount(&root);}
int entriesCount() const { return childCount(&root); }
//! Returns if top-level entry with name "name" exists
bool isEntryExists(const PIString & name) const {return entryExists(&root, name);}
bool isEntryExists(const PIString & name) const { return entryExists(&root, name); }
//! Returns all top-level entries
Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; b.delim = delim; return b;}
Branch allTree() {
Branch b;
piForeach(Entry * i, root._children)
b << i;
b.delim = delim;
return b;
}
//! Returns all entries without children
Branch allLeaves() {Branch b; allLeaves(b, &root); b.sort(Entry::compare); b.delim = delim; return b;}
Branch allLeaves() {
Branch b;
allLeaves(b, &root);
b.sort(Entry::compare);
b.delim = delim;
return b;
}
int entryIndex(const PIString & name);
PIString getName(uint number) {return entryByIndex(number)._name;}
PIString getValueByIndex(uint number) {return entryByIndex(number)._value;}
PIChar getType(uint number) {return entryByIndex(number)._type[0];}
PIString getComment(uint number) {return entryByIndex(number)._comment;}
PIString getName(uint number) { return entryByIndex(number)._name; }
PIString getValueByIndex(uint number) { return entryByIndex(number)._value; }
PIChar getType(uint number) { return entryByIndex(number)._type[0]; }
PIString getComment(uint number) { return entryByIndex(number)._comment; }
void addEntry(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true);
void setName(uint number, const PIString & name, bool write = true);
@@ -470,10 +612,14 @@ public:
void writeAll();
//! Returns current tree delimiter, default "."
const PIString & delimiter() const {return delim;}
const PIString & delimiter() const { return delim; }
//! Set current tree delimiter
void setDelimiter(const PIString & d) {delim = d; setEntryDelim(&root, d); readAll();}
void setDelimiter(const PIString & d) {
delim = d;
setEntryDelim(&root, d);
readAll();
}
private:
PIConfig(const PIString & path, PIStringList dirs);
@@ -486,40 +632,75 @@ private:
void _seekToBeginDev();
PIString _readLineDev();
void _writeDev(const PIString & l);
int childCount(const Entry * e) const {int c = 0; piForeachC (Entry * i, e->_children) c += childCount(i); c += e->_children.size_s(); return c;}
int childCount(const Entry * e) const {
int c = 0;
piForeachC(Entry * i, e->_children)
c += childCount(i);
c += e->_children.size_s();
return c;
}
bool entryExists(const Entry * e, const PIString & name) const;
void buildFullNames(Entry * e) {piForeach (Entry * i, e->_children) {if (e != &root) i->_full_name = e->_full_name + delim + i->_name; else i->_full_name = i->_name; buildFullNames(i);}}
void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; allLeaves(b, i);}}
void setEntryDelim(Entry * e, const PIString & d) {piForeach (Entry * i, e->_children) setEntryDelim(i, d); e->delim = d;}
Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);}
void buildFullNames(Entry * e) {
piForeach(Entry * i, e->_children) {
if (e != &root)
i->_full_name = e->_full_name + delim + i->_name;
else
i->_full_name = i->_name;
buildFullNames(i);
}
}
void allLeaves(Branch & b, Entry * e) {
piForeach(Entry * i, e->_children) {
if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i;
allLeaves(b, i);
}
}
void setEntryDelim(Entry * e, const PIString & d) {
piForeach(Entry * i, e->_children)
setEntryDelim(i, d);
e->delim = d;
}
Entry & entryByIndex(const int index) {
Branch b = allLeaves();
if (index < 0 || index >= b.size_s()) return empty;
return *(b[index]);
}
void removeEntry(Branch & b, Entry * e);
void deleteEntry(Entry * e) {piForeach (Entry * i, e->_children) deleteEntry(i); delete e;}
void deleteEntry(Entry * e) {
piForeach(Entry * i, e->_children)
deleteEntry(i);
delete e;
}
PIString getPrefixFromLine(PIString line, bool * exists);
void updateIncludes();
PIString parseLine(PIString v);
void parse();
bool own_dev = false, internal = false;
PIVector<PIConfig * > includes, inc_devs;
PIVector<PIConfig *> includes, inc_devs;
Branch all_includes;
PIIODevice * dev = nullptr;
PIIODevice * dev = nullptr;
PIIOTextStream * stream = nullptr;
PIString delim;
PIStringList incdirs;
Entry root, empty;
uint lines = 0;
PIStringList other;
};
#ifdef PIP_STD_IOSTREAM
PIP_EXPORT std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v);
PIP_EXPORT std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v);
PIP_EXPORT std::ostream & operator<<(std::ostream & s, const PIConfig::Branch & v);
PIP_EXPORT std::ostream & operator<<(std::ostream & s, const PIConfig::Entry & v);
#endif
inline PICout operator <<(PICout s, const PIConfig::Branch & v) {s.saveAndSetControls(0); v.piCoutt(s, ""); s.restoreControls(); return s;}
inline PICout operator <<(PICout s, const PIConfig::Entry & v) {
inline PICout operator<<(PICout s, const PIConfig::Branch & v) {
s.saveAndSetControls(0);
v.piCoutt(s, "");
s.restoreControls();
return s;
}
inline PICout operator<<(PICout s, const PIConfig::Entry & v) {
s << v.value() << "(" << v.type() << v.comment() << ")";
return s;
}

View File

@@ -26,19 +26,18 @@
#ifndef PISERIAL_H
#define PISERIAL_H
#include "pitimer.h"
#include "piiodevice.h"
#include "pitimer.h"
//! \ingroup IO
//! \~\brief
//! \~english Serial device.
//! \~russian Последовательный порт.
class PIP_EXPORT PISerial: public PIIODevice
{
class PIP_EXPORT PISerial: public PIIODevice {
PIIODEVICE(PISerial, "ser");
public:
//! \~english Contructs an empty %PISerial
//! \~russian Создает пустой %PISerial
explicit PISerial();
@@ -49,32 +48,32 @@ public:
//! \~russian Параметры PISerial
enum Parameters {
ParityControl /*! \~english Enable parity check and generate \~russian Включить генерацию и проверку контроля чётности */ = 0x1,
ParityOdd /*! \~english Parity is odd instead of even \~russian Нечётный контроль чётности вместо чётного */ = 0x2,
TwoStopBits /*! \~english Two stop bits instead of one \~russian Два стоповых бита вместо одного */ = 0x4
ParityOdd /*! \~english Parity is odd instead of even \~russian Нечётный контроль чётности вместо чётного */ = 0x2,
TwoStopBits /*! \~english Two stop bits instead of one \~russian Два стоповых бита вместо одного */ = 0x4
};
//! \~english Speed of PISerial
//! \~russian Скорость PISerial
enum Speed {
S50 /*! 50 baud */ = 50,
S75 /*! 75 baud */ = 75,
S110 /*! 110 baud */ = 110,
S300 /*! 300 baud */ = 300,
S600 /*! 600 baud */ = 600,
S1200 /*! 1200 baud */ = 1200,
S2400 /*! 2400 baud */ = 2400,
S4800 /*! 4800 baud */ = 4800,
S9600 /*! 9600 baud */ = 9600,
S14400 /*! 14400 baud */ = 14400,
S19200 /*! 19200 baud */ = 19200,
S38400 /*! 38400 baud */ = 38400,
S57600 /*! 57600 baud */ = 57600,
S115200 /*! 115200 baud */ = 115200,
S230400 /*! 230400 baud */ = 230400,
S460800 /*! 460800 baud */ = 460800,
S500000 /*! 500000 baud */ = 500000,
S576000 /*! 576000 baud */ = 576000,
S921600 /*! 921600 baud */ = 921600,
S50 /*! 50 baud */ = 50,
S75 /*! 75 baud */ = 75,
S110 /*! 110 baud */ = 110,
S300 /*! 300 baud */ = 300,
S600 /*! 600 baud */ = 600,
S1200 /*! 1200 baud */ = 1200,
S2400 /*! 2400 baud */ = 2400,
S4800 /*! 4800 baud */ = 4800,
S9600 /*! 9600 baud */ = 9600,
S14400 /*! 14400 baud */ = 14400,
S19200 /*! 19200 baud */ = 19200,
S38400 /*! 38400 baud */ = 38400,
S57600 /*! 57600 baud */ = 57600,
S115200 /*! 115200 baud */ = 115200,
S230400 /*! 230400 baud */ = 230400,
S460800 /*! 460800 baud */ = 460800,
S500000 /*! 500000 baud */ = 500000,
S576000 /*! 576000 baud */ = 576000,
S921600 /*! 921600 baud */ = 921600,
S1000000 /*! 1000000 baud */ = 1000000,
S1152000 /*! 1152000 baud */ = 1152000,
S1500000 /*! 1500000 baud */ = 1500000,
@@ -113,66 +112,87 @@ public:
//! \~english Device manufacturer
//! \~russian Описание производителя
PIString manufacturer;
};
//! \~english Contructs %PISerial with device name "device", speed "speed" and parameters "params"
//! \~russian Создает %PISerial с именем устройства "device", скоростью "speed" и параметрами "params"
explicit PISerial(const PIString & device, PISerial::Speed speed = S115200, PIFlags<PISerial::Parameters> params = 0);
//! \~english Set both input and output speed to "speed"
//! \~russian Устанавливает скорости приема и передачи в "speed"
void setSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); setProperty("inSpeed", (int)speed); applySettings();}
void setSpeed(PISerial::Speed speed) {
setProperty("outSpeed", (int)speed);
setProperty("inSpeed", (int)speed);
applySettings();
}
//! \~english Set output speed to "speed"
//! \~russian Устанавливает скорость передачи в "speed"
void setOutSpeed(PISerial::Speed speed) {setProperty("outSpeed", (int)speed); applySettings();}
void setOutSpeed(PISerial::Speed speed) {
setProperty("outSpeed", (int)speed);
applySettings();
}
//! \~english Set input speed to "speed"
//! \~russian Устанавливает скорость приема в "speed"
void setInSpeed(PISerial::Speed speed) {setProperty("inSpeed", (int)speed); applySettings();}
void setInSpeed(PISerial::Speed speed) {
setProperty("inSpeed", (int)speed);
applySettings();
}
//! \~english Set device name to "dev"
//! \~russian Устанавливает имя устройства в "dev"
void setDevice(const PIString & dev) {setPath(dev); if (isOpened()) {close(); open();};}
void setDevice(const PIString & dev) {
setPath(dev);
if (isOpened()) {
close();
open();
};
}
//! \~english Set parameters to "parameters_"
//! \~russian Устанавливает параметры в "parameters_"
void setParameters(PIFlags<PISerial::Parameters> parameters_) {setProperty("parameters", (int)parameters_); applySettings();}
void setParameters(PIFlags<PISerial::Parameters> parameters_) {
setProperty("parameters", (int)parameters_);
applySettings();
}
//! \~english Set parameter "parameter" to "on" state
//! \~russian Устанавливает параметр "parameter" в "on"
void setParameter(PISerial::Parameters parameter, bool on = true);
//! \~english Returns if parameter "parameter" is set
//! \~russian Возвращает установлен ли параметр "parameter"
bool isParameterSet(PISerial::Parameters parameter) const;
//! \~english Returns parameters
//! \~russian Возвращает параметры
PIFlags<PISerial::Parameters> parameters() const {return (PIFlags<Parameters>)(property("parameters").toInt());}
PIFlags<PISerial::Parameters> parameters() const { return (PIFlags<Parameters>)(property("parameters").toInt()); }
//! \~english Set data bits count. Valid range is from 5 to 8, befault is 8
//! \~russian Устанавливает количество бит данных. Разрешены значения от 5 до 8, по умолчанию 8
void setDataBitsCount(int bits) {setProperty("dataBitsCount", bits); applySettings();}
void setDataBitsCount(int bits) {
setProperty("dataBitsCount", bits);
applySettings();
}
//! \~english Returns data bits count
//! \~russian Возвращает количество бит данных
int dataBitsCount() const {return property("dataBitsCount").toInt();}
int dataBitsCount() const { return property("dataBitsCount").toInt(); }
//! \~english Set pin number "number" to logic level "on". Valid numbers are 4 (DTR) and 7 (RTS)
//! \~russian Устанавливает пин с номером "number" в логический уровень "on". Разрешены номера 4 (DTR) и 7 (RTS)
bool setPin(int number, bool on);
//! \~english Returns pin number "number" logic level. Valid numbers range is from 1 to 9
//! \~russian Возвращает логический уровень пина с номером "number". Разрешены номера от 1 до 9
bool isPin(int number) const;
bool setLE(bool on); // useless function, just formally
bool setLE(bool on); // useless function, just formally
bool setDTR(bool on);
bool setRTS(bool on);
bool setCTS(bool on); // useless function, just formally
@@ -196,27 +216,30 @@ public:
//! \~russian Переключает состояние передачи в break
bool setBreak(bool enabled);
void setVTime(int t) {vtime = t; applySettings();}
void setVTime(int t) {
vtime = t;
applySettings();
}
//! \~english Returns device name
//! \~russian Возвращает имя устройства
PIString device() const {return path();}
PIString device() const { return path(); }
//! \~english Returns output speed
//! \~russian Возвращает скорость передачи
PISerial::Speed outSpeed() const {return (PISerial::Speed)(property("outSpeed").toInt());}
PISerial::Speed outSpeed() const { return (PISerial::Speed)(property("outSpeed").toInt()); }
//! \~english Returns input speed
//! \~russian Возвращает скорость приема
PISerial::Speed inSpeed() const {return (PISerial::Speed)(property("inSpeed").toInt());}
int VTime() const {return vtime;}
PISerial::Speed inSpeed() const { return (PISerial::Speed)(property("inSpeed").toInt()); }
int VTime() const { return vtime; }
//! \~english Discard all buffered input and output data
//! \~russian Откидывает все буферизированные данные для передачи и приема
virtual void flush() override;
int read(void * read_to, int max_size) {return readDevice(read_to, max_size);}
int read(void * read_to, int max_size) { return readDevice(read_to, max_size); }
//! \~english Read from device no more "max_size" bytes into "read_to" with "timeout_ms" timeout
//! \~russian Читает из устройства не более "max_size" байт в "read_to" с таймаутом "timeout_ms"
@@ -236,14 +259,14 @@ public:
//! \~english Write to device byte array "data". Returns if sended bytes count = size of "data"
//! \~russian Пишет в порт байтовый массив "data". Возвращает если количество записанных байт = размер "data"
bool send(const PIByteArray & data) {return send(data.data(), data.size_s());}
bool send(const PIByteArray & data) { return send(data.data(), data.size_s()); }
void interrupt() override;
//! \~english Returns all available speeds for serial devices
//! \~russian Возвращает все возможные скорости для устройств
static PIVector<int> availableSpeeds();
//! \~english Returns all available system devices path. If "test" each device will be tried to open
//! \~russian Возвращает пути всех доступных устройств в системе. Если "test", то каждое устройство будет опробовано на открытие
static PIStringList availableDevices(bool test = false);
@@ -258,29 +281,29 @@ public:
//! \~english device, default ""
//! \~russian устройство, по умолчанию ""
string device;
//! \~english input/output speed, default 115200
//! \~russian скорость чтения/записи, по умолчанию 115200
int speed;
//! \~english dataBitsCount, default 8
//! \~russian количесво бит данных, по умолчанию 8
int dataBitsCount;
//! \~english parityControl, default false
//! \~russian контроль четности, по умолчанию false
bool parityControl;
//! \~english parityOdd, default false
//! \~russian нечётный контроль четности, по умолчанию false
bool parityOdd;
//! \~english twoStopBits, default false
//! \~russian два стоповых бита, по умолчанию false
bool twoStopBits;
#endif
//! \}
//! \}
protected:
PIString constructFullPathDevice() const override;
void configureFromFullPathDevice(const PIString & full_path) override;
@@ -294,10 +317,10 @@ protected:
//! \~russian Базовое чтение
ssize_t readDevice(void * read_to, ssize_t max_size) override;
ssize_t writeDevice(const void * data, ssize_t max_size) override;
DeviceInfoFlags deviceInfoFlags() const override {return PIIODevice::Sequential;}
DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Sequential; }
//! Executes when any read function was successful. Default implementation does nothing
virtual void received(const void * data, int size) {;}
virtual void received(const void * data, int size) { ; }
void construct();
void applySettings();
@@ -313,36 +336,45 @@ protected:
int fd = -1, vtime = 10;
std::atomic_bool sending;
PITimeMeasurer tm_;
};
//! \relatesalso PICout
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
inline PICout operator <<(PICout s, const PISerial::DeviceInfo & v) {
inline PICout operator<<(PICout s, const PISerial::DeviceInfo & v) {
s << v.path << " (" << v.id() << ", \"" << v.manufacturer << "\", \"" << v.description << "\")";
return s;
}
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {return v0.path == v1.path;}
inline bool operator==(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {
return v0.path == v1.path;
}
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator !=(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {return v0.path != v1.path;}
inline bool operator!=(const PISerial::DeviceInfo & v0, const PISerial::DeviceInfo & v1) {
return v0.path != v1.path;
}
//! \relatesalso PIBinaryStream
//! \~english Store operator.
//! \~russian Оператор сохранения.
BINARY_STREAM_WRITE(PISerial::DeviceInfo) {s << v.vID << v.pID << v.path << v.description << v.manufacturer; return s;}
BINARY_STREAM_WRITE(PISerial::DeviceInfo) {
s << v.vID << v.pID << v.path << v.description << v.manufacturer;
return s;
}
//! \relatesalso PIBinaryStream
//! \~english Restore operator.
//! \~russian Оператор извлечения.
BINARY_STREAM_READ (PISerial::DeviceInfo) {s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer; return s;}
BINARY_STREAM_READ(PISerial::DeviceInfo) {
s >> v.vID >> v.pID >> v.path >> v.description >> v.manufacturer;
return s;
}
#endif // PISERIAL_H

View File

@@ -3,7 +3,7 @@
* \~\brief
* \~english Basic mathematical functions and defines
* \~russian Базовые математические функции и дефайны
*/
*/
/*
PIP - Platform Independent Primitives
Basic mathematical functions and defines
@@ -27,8 +27,8 @@
#define PIMATHBASE_H
#include "piinit.h"
#include "pivector.h"
#include "pipair.h"
#include "pivector.h"
#ifdef QNX
# undef PIP_MATH_J0
# undef PIP_MATH_J1
@@ -94,20 +94,25 @@
#endif
const double deg2rad = M_PI_180;
const double rad2deg = M_180_PI;
// clang-format off
inline int sign(const float & x) {return (x < 0.f) ? -1 : (x > 0.f ? 1 : 0);}
inline int sign(const double & x) {return (x < 0. ) ? -1 : (x > 0. ? 1 : 0);}
inline int sign(const ldouble & x) {return (x < 0.L) ? -1 : (x > 0.L ? 1 : 0);}
inline int pow2(const int p) {return 1 << p;}
inline float pow10(const int & e) {return powf(10.f, e);}
inline double pow10(const double & e) {return pow(10., e);}
inline int pow2 (const int p ) {return 1 << p;}
inline float pow10(const int & e) {return powf(10.f, e);}
inline double pow10(const double & e) {return pow (10. , e);}
inline ldouble pow10(const ldouble & e) {return powl(10.L, e);}
// clang-format on
inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;}
inline double sinc(const double & v) {
if (v == 0.) return 1.;
double t = M_PI * v;
return sin(t) / t;
}
PIP_EXPORT double piJ0(const double & v);
PIP_EXPORT double piJ1(const double & v);
@@ -116,22 +121,34 @@ PIP_EXPORT double piY0(const double & v);
PIP_EXPORT double piY1(const double & v);
PIP_EXPORT double piYn(int n, const double & v);
// clang-format off
inline constexpr float toRad(float deg) {return deg * M_PI_180;}
inline constexpr double toRad(double deg) {return deg * M_PI_180;}
inline constexpr ldouble toRad(ldouble deg) {return deg * M_PI_180;}
inline constexpr float toDeg(float rad) {return rad * M_180_PI;}
inline constexpr double toDeg(double rad) {return rad * M_180_PI;}
inline constexpr ldouble toDeg(ldouble rad) {return rad * M_180_PI;}
template <typename T> inline constexpr T sqr(const T & v) {return v * v;}
template <typename T> inline constexpr T toDb (T val) {return T(10.) * std::log10(val);}
template <typename T> inline constexpr T fromDb(T val) {return std::pow(T(10.), val / T(10.));}
// clang-format on
template<typename T>
inline constexpr T sqr(const T & v) {
return v * v;
}
template<typename T>
inline constexpr T toDb(T val) {
return T(10.) * std::log10(val);
}
template<typename T>
inline constexpr T fromDb(T val) {
return std::pow(T(10.), val / T(10.));
}
// [-1 ; 1]
PIP_EXPORT double randomd();
// [-1 ; 1] normal
PIP_EXPORT double randomn(double dv = 0., double sv = 1.);
template<typename T> inline PIVector<T> piAbs(const PIVector<T> & v) {
template<typename T>
inline PIVector<T> piAbs(const PIVector<T> & v) {
PIVector<T> result;
result.resize(v.size());
for (uint i = 0; i < v.size(); i++)
@@ -140,12 +157,11 @@ template<typename T> inline PIVector<T> piAbs(const PIVector<T> & v) {
}
template <typename T>
bool OLS_Linear(const PIVector<PIPair<T, T> > & input, T * out_a, T * out_b) {
template<typename T>
bool OLS_Linear(const PIVector<PIPair<T, T>> & input, T * out_a, T * out_b) {
static_assert(std::is_arithmetic<T>::value, "Type must be arithmetic");
if (input.size_s() < 2)
return false;
int n = input.size_s();
if (input.size_s() < 2) return false;
int n = input.size_s();
T a_t0 = T(), a_t1 = T(), a_t2 = T(), a_t3 = T(), a_t4 = T(), a = T(), b = T();
for (int i = 0; i < n; ++i) {
const PIPair<T, T> & cv(input[i]);
@@ -155,8 +171,7 @@ bool OLS_Linear(const PIVector<PIPair<T, T> > & input, T * out_a, T * out_b) {
a_t3 += cv.first * cv.first;
}
a_t4 = n * a_t3 - a_t1 * a_t1;
if (a_t4 != T())
a = (n * a_t0 - a_t1 * a_t2) / a_t4;
if (a_t4 != T()) a = (n * a_t0 - a_t1 * a_t2) / a_t4;
b = (a_t2 - a * a_t1) / n;
if (out_a != 0) *out_a = a;
if (out_b != 0) *out_b = b;
@@ -164,14 +179,12 @@ bool OLS_Linear(const PIVector<PIPair<T, T> > & input, T * out_a, T * out_b) {
}
template <typename T>
bool WLS_Linear(const PIVector<PIPair<T, T> > & input, const PIVector<T> & weights, T * out_a, T * out_b) {
template<typename T>
bool WLS_Linear(const PIVector<PIPair<T, T>> & input, const PIVector<T> & weights, T * out_a, T * out_b) {
static_assert(std::is_arithmetic<T>::value, "Type must be arithmetic");
if (input.size_s() < 2)
return false;
if (input.size_s() != weights.size_s())
return false;
int n = input.size_s();
if (input.size_s() < 2) return false;
if (input.size_s() != weights.size_s()) return false;
int n = input.size_s();
T a_t0 = T(), a_t1 = T(), a_t2 = T(), a_t3 = T(), a_t4 = T(), a_n = T(), a = T(), b = T();
for (int i = 0; i < n; ++i) {
T cp = weights[i];
@@ -183,8 +196,7 @@ bool WLS_Linear(const PIVector<PIPair<T, T> > & input, const PIVector<T> & weigh
a_n += cp;
}
a_t4 = a_n * a_t3 - a_t1 * a_t1;
if (a_t4 != T())
a = (a_n * a_t0 - a_t1 * a_t2) / a_t4;
if (a_t4 != T()) a = (a_n * a_t0 - a_t1 * a_t2) / a_t4;
b = (a_t2 - a * a_t1) / a_n;
if (out_a != 0) *out_a = a;
if (out_b != 0) *out_b = b;

View File

@@ -28,26 +28,26 @@
#include "pimathmatrix.h"
class PIP_EXPORT PIQuaternion
{
friend PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1);
friend PIQuaternion operator*(const double & a, const PIQuaternion & q);
class PIP_EXPORT PIQuaternion {
friend PIP_EXPORT PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1);
friend PIP_EXPORT PIQuaternion operator*(const double & a, const PIQuaternion & q);
public:
PIQuaternion(const PIMathVectorT3d & u = PIMathVectorT3d(), double a = 0.);
PIQuaternion conjugate() const {return PIQuaternion(-vector(), scalar());}
PIQuaternion conjugate() const { return PIQuaternion(-vector(), scalar()); }
PIQuaternion rotated(const PIMathVectorT3d & u, double a) const;
void rotate(const PIMathVectorT3d & u, double a);
void normalize();
double & scalar() {return q[0];}
double scalar() const {return q[0];}
PIMathVectorT3d vector() const {return PIMathVectorT3d({q[1], q[2], q[3]});}
double & scalar() { return q[0]; }
double scalar() const { return q[0]; }
PIMathVectorT3d vector() const { return PIMathVectorT3d({q[1], q[2], q[3]}); }
PIMathVectorT3d eyler() const;
PIMathMatrixT33d rotationMatrix() const;
void axis(PIMathVectorT3d*ret) const;
void axis(PIMathVectorT3d * ret) const;
static PIQuaternion fromEyler(double ax, double ay, double az);
static PIQuaternion fromRotationMatrix(const PIMathMatrixT33d & m);
static PIQuaternion fromAngles(double ax, double ay, double az);
@@ -57,10 +57,16 @@ protected:
double q[4];
};
PIP_EXPORT PIQuaternion operator *(const double & a, const PIQuaternion & q);
PIP_EXPORT PIQuaternion operator *(const PIQuaternion & q0, const PIQuaternion & q1);
inline PIQuaternion operator +(const PIQuaternion & q0, const PIQuaternion & q1) {return PIQuaternion(q0.vector() + q1.vector(), q0.scalar() + q1.scalar());}
inline PIQuaternion operator -(const PIQuaternion & q0, const PIQuaternion & q1) {return PIQuaternion(q0.vector() - q1.vector(), q0.scalar() - q1.scalar());}
inline PIQuaternion operator -(const PIQuaternion & q0) {return PIQuaternion(-q0.vector(), -q0.scalar());}
PIP_EXPORT PIQuaternion operator*(const double & a, const PIQuaternion & q);
PIP_EXPORT PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1);
inline PIQuaternion operator+(const PIQuaternion & q0, const PIQuaternion & q1) {
return PIQuaternion(q0.vector() + q1.vector(), q0.scalar() + q1.scalar());
}
inline PIQuaternion operator-(const PIQuaternion & q0, const PIQuaternion & q1) {
return PIQuaternion(q0.vector() - q1.vector(), q0.scalar() - q1.scalar());
}
inline PIQuaternion operator-(const PIQuaternion & q0) {
return PIQuaternion(-q0.vector(), -q0.scalar());
}
#endif // PIQUATERNION_H

View File

@@ -3,7 +3,7 @@
* \brief
* \~english PIValueTree conversions
* \~russian Преобразования PIValueTree
*/
*/
/*
PIP - Platform Independent Primitives
PIValueTree conversions
@@ -34,23 +34,23 @@ class PIIODevice;
namespace PIValueTreeConversions {
enum Option {
WithAttributes = 0x1,
WithComment = 0x2,
WithType = 0x4,
WithAll = 0xFFFFFF,
Default = WithAll
};
typedef PIFlags<Option> Options;
enum Option {
WithAttributes = 0x1,
WithComment = 0x2,
WithType = 0x4,
WithAll = 0xFFFFFF,
Default = WithAll
};
typedef PIFlags<Option> Options;
PIP_EXPORT PIValueTree fromPropertyStorage(const PIPropertyStorage & ps);
PIP_EXPORT PIValueTree fromVariantMap(const PIVariantMap & vm);
PIP_EXPORT PIValueTree fromJSON(const PIJSON & json);
PIP_EXPORT PIValueTree fromText(PIIODevice * device);
PIP_EXPORT PIValueTree fromText(const PIString & str);
PIP_EXPORT PIJSON toJSON(const PIValueTree & root, Options options = Default);
PIP_EXPORT PIString toText(const PIValueTree & root, Options options = Default);
PIP_EXPORT PIValueTree fromPropertyStorage(const PIPropertyStorage & ps);
PIP_EXPORT PIValueTree fromVariantMap(const PIVariantMap & vm);
PIP_EXPORT PIValueTree fromJSON(const PIJSON & json);
PIP_EXPORT PIValueTree fromText(PIIODevice * device);
PIP_EXPORT PIValueTree fromText(const PIString & str);
PIP_EXPORT PIJSON toJSON(const PIValueTree & root, Options options = Default);
PIP_EXPORT PIString toText(const PIValueTree & root, Options options = Default);
}
} // namespace PIValueTreeConversions
#endif

View File

@@ -3,7 +3,7 @@
* \~\brief
* \~english Single string character
* \~russian Один символ строки
*/
*/
/*
PIP - Platform Independent Primitives
Unicode char
@@ -36,26 +36,26 @@ extern PIP_EXPORT char * __utf8name__;
//! \~\brief
//! \~english %PIChar represents a single character.
//! \~russian %PIChar представляет собой один символ строки.
class PIP_EXPORT PIChar
{
class PIP_EXPORT PIChar {
friend class PIString;
friend PICout operator <<(PICout s, const PIChar & v);
friend PIP_EXPORT PICout operator<<(PICout s, const PIChar & v);
public:
//! \~english Contructs Ascii symbol
//! \~russian Создает символ Ascii
PIChar(char c) {ch = c;}
PIChar(char c) { ch = c; }
//! \~english Contructs ascii symbol
//! \~russian Создает символ Ascii
PIChar(uchar c) {ch = c;}
PIChar(uchar c) { ch = c; }
//! \~english Contructs 2-bytes symbol
//! \~russian Создает 2-байтный символ
PIChar(ushort c = 0) {ch = c;}
PIChar(ushort c = 0) { ch = c; }
//! \~english Contructs 2-bytes symbol from `wchar_t`
//! \~russian Создает 2-байтный символ из `wchar_t`
PIChar(wchar_t c) {ch = c;}
PIChar(wchar_t c) { ch = c; }
//! \~english Contructs symbol from system locale and no more than 4 bytes of string
//! \~russian Создает символ из системной локали не более 4 байт длины
@@ -63,52 +63,58 @@ public:
//! \~english Copy operator
//! \~russian Оператор присваивания
PIChar & operator =(const char v) {ch = v; return *this;}
PIChar & operator=(const char v) {
ch = v;
return *this;
}
//! \~english Copy operator
//! \~russian Оператор присваивания
PIChar & operator =(const wchar_t v) {ch = v; return *this;}
PIChar & operator=(const wchar_t v) {
ch = v;
return *this;
}
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator ==(const PIChar & o) const;
bool operator==(const PIChar & o) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator !=(const PIChar & o) const {return !(o == *this);}
bool operator!=(const PIChar & o) const { return !(o == *this); }
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >(const PIChar & o) const;
bool operator>(const PIChar & o) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <(const PIChar & o) const;
bool operator<(const PIChar & o) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator >=(const PIChar & o) const;
bool operator>=(const PIChar & o) const;
//! \~english Compare operator
//! \~russian Оператор сравнения
bool operator <=(const PIChar & o) const;
bool operator<=(const PIChar & o) const;
//! \~english Returns \b true if symbol is digit ('0' to '9')
//! \~russian Возвращает \b true если символ является
bool isDigit() const;
//! \~english Returns \b true if symbol is HEX digit ('0' to '9', 'a' to 'f', 'A' to 'F')
//! \~russian Возвращает \b true если символ является HEX цифрой ('0' до '9', 'a' до 'f', 'A' до 'F')
bool isHex() const;
//! \~english Returns \b true if symbol is drawable (without space)
//! \~russian Возвращает \b true если символ является графическим (исключая пробельные)
bool isGraphical() const;
//! \~english Returns \b true if symbol is control byte (< 32 or 127)
//! \~russian Возвращает \b true если символ является контрольным (< 32 or 127)
bool isControl() const;
//! \~english Returns \b true if symbol is in lower case
//! \~russian Возвращает \b true если символ в нижнем регистре
bool isLower() const;
@@ -116,34 +122,34 @@ public:
//! \~english Returns \b true if symbol is in upper case
//! \~russian Возвращает \b true если символ в верхнем регистре
bool isUpper() const;
//! \~english Returns \b true if symbol is printable (with space)
//! \~russian Возвращает \b true если символ является печатным (включая пробельные)
bool isPrint() const;
//! \~english Returns \b true if symbol is space or tab
//! \~russian Возвращает \b true если символ является пробельным или табуляцией
bool isSpace() const;
//! \~english Returns \b true if symbol is alphabetical letter
//! \~russian Возвращает \b true если символ является алфавитной буквой
bool isAlpha() const;
//! \~english Returns \b true if symbol is Ascii (< 128)
//! \~russian Возвращает \b true если символ является Ascii (< 128)
bool isAscii() const;
const wchar_t * toWCharPtr() const;
//! \~english Returns as `char *` string
//! \~russian Возвращает символ как указатель на `char *`
const char * toCharPtr() const;
wchar_t toWChar() const;
//! \~english Returns symbol as Ascii
//! \~russian Возвращает символ в Ascii
char toAscii() const {return ch % 256;}
char toAscii() const { return ch % 256; }
//! \~english Returns symbol as console codepage
//! \~russian Возвращает символ в консольной кодировке
@@ -153,16 +159,16 @@ public:
//! \~russian Возвращает символ в системной кодировке
char toSystem() const;
ushort unicode16Code() const {return ch;}
ushort unicode16Code() const { return ch; }
//! \~english Returns symbol in upper case
//! \~russian Возвращает символ в нижнем регистре
PIChar toUpper() const;
//! \~english Returns symbol in lower case
//! \~russian Возвращает символ в верхнем регистре
PIChar toLower() const;
//! \~english Returns symbol from console codepage
//! \~russian Возвращает символ из консольной кодировки
static PIChar fromConsole(char c);
@@ -177,89 +183,118 @@ public:
private:
ushort ch;
};
//! \relatesalso PIChar
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
PIP_EXPORT PICout operator <<(PICout s, const PIChar & v);
PIP_EXPORT PICout operator<<(PICout s, const PIChar & v);
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}
inline bool operator==(const char v, const PIChar & c) {
return (PIChar(v) == c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}
inline bool operator>(const char v, const PIChar & c) {
return (PIChar(v) > c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}
inline bool operator<(const char v, const PIChar & c) {
return (PIChar(v) < c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}
inline bool operator>=(const char v, const PIChar & c) {
return (PIChar(v) >= c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}
inline bool operator<=(const char v, const PIChar & c) {
return (PIChar(v) <= c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}
inline bool operator==(const char * v, const PIChar & c) {
return (PIChar(v) == c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}
inline bool operator>(const char * v, const PIChar & c) {
return (PIChar(v) > c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}
inline bool operator<(const char * v, const PIChar & c) {
return (PIChar(v) < c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}
inline bool operator>=(const char * v, const PIChar & c) {
return (PIChar(v) >= c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}
inline bool operator<=(const char * v, const PIChar & c) {
return (PIChar(v) <= c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const int v, const PIChar & c) {return (PIChar((ushort)v) == c);}
inline bool operator==(const int v, const PIChar & c) {
return (PIChar((ushort)v) == c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >(const int v, const PIChar & c) {return (PIChar((ushort)v) > c);}
inline bool operator>(const int v, const PIChar & c) {
return (PIChar((ushort)v) > c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <(const int v, const PIChar & c) {return (PIChar((ushort)v) < c);}
inline bool operator<(const int v, const PIChar & c) {
return (PIChar((ushort)v) < c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >=(const int v, const PIChar & c) {return (PIChar((ushort)v) >= c);}
inline bool operator>=(const int v, const PIChar & c) {
return (PIChar((ushort)v) >= c);
}
//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <=(const int v, const PIChar & c) {return (PIChar((ushort)v) <= c);}
inline bool operator<=(const int v, const PIChar & c) {
return (PIChar((ushort)v) <= c);
}
#endif // PICHAR_H

View File

@@ -1,6 +1,6 @@
/*
PIP - Platform Independent Primitives
Stephan Fomenko
This program is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@
#define PITHREADPOOLEXECUTOR_H
#include "piblockingqueue.h"
#include <atomic>
@@ -30,22 +31,18 @@ public:
virtual ~PIThreadPoolExecutor();
/**
* \brief Executes the given task sometime in the future. The task execute in an existing pooled thread. If the task
* cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been
* reached.
*
* @param runnable not empty function for thread pool execution
*/
//! \brief Executes the given task sometime in the future. The task execute in an existing pooled thread. If the task
//! cannot be submitted for execution, either because this executor has been shutdown or because its capacity has been
//! reached.
//!
//! \param runnable not empty function for thread pool execution
void execute(const std::function<void()> & runnable);
void shutdownNow();
/**
* \brief Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be
* accepted. Invocation has no additional effect if already shut down. This method does not wait for previously
* submitted tasks to complete execution. Use awaitTermination to do that.
*/
//! \brief Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be
//! accepted. Invocation has no additional effect if already shut down. This method does not wait for previously
//! submitted tasks to complete execution. Use awaitTermination to do that.
void shutdown();
bool isShutdown() const;
@@ -54,8 +51,8 @@ public:
private:
std::atomic_bool isShutdown_;
PIBlockingQueue<std::function<void()> > taskQueue;
PIVector<PIThread*> threadPool;
PIBlockingQueue<std::function<void()>> taskQueue;
PIVector<PIThread *> threadPool;
};
#endif // PITHREADPOOLEXECUTOR_H

View File

@@ -35,35 +35,35 @@ class PITimer;
class PIP_EXPORT _PITimerBase {
friend class PITimer;
public:
_PITimerBase();
virtual ~_PITimerBase() {}
double interval() const {return interval_;}
double interval() const { return interval_; }
void setInterval(double i);
bool isRunning() const {return running_;}
bool isStopped() const {return !running_;}
bool start() {return start(interval_);}
bool isRunning() const { return running_; }
bool isStopped() const { return !running_; }
bool start() { return start(interval_); }
bool start(double interval_ms);
void startDeferred(double delay_ms) {startDeferred(interval_, delay_ms);}
void startDeferred(double delay_ms) { startDeferred(interval_, delay_ms); }
void startDeferred(double interval_ms, double delay_ms);
void startDeferred(PIDateTime start_datetime) {startDeferred(interval_, start_datetime);}
void startDeferred(PIDateTime start_datetime) { startDeferred(interval_, start_datetime); }
void startDeferred(double interval_ms, PIDateTime start_datetime);
bool stop();
typedef void(*TickFunc)(PITimer*);
typedef void (*TickFunc)(PITimer *);
TickFunc tfunc;
PITimer * parent;
protected:
virtual bool startTimer(double interval_ms) = 0;
virtual bool stopTimer() = 0;
virtual bool stopTimer() = 0;
double interval_, deferred_delay;
bool deferred_, deferred_mode; // mode: true - date, false - delay
std::atomic_bool running_;
@@ -71,10 +71,9 @@ protected:
};
class PIP_EXPORT PITimer: public PIObject {
PIOBJECT_SUBCLASS(PITimer, PIObject);
public:
NO_COPY_CLASS(PITimer);
@@ -88,56 +87,59 @@ public:
Thread /*!
\~english Timer works in his own thread. Intervals are measured by the system time
\~russian Таймер работает в собственном потоке. Интервалы измеряются с помощью системного времени
*/ = 0x01,
*/
= 0x01,
ThreadRT /*!
\~english Using POSIX timer with SIGEV_THREAD notification. \attention Doesn`t support on Windows and Mac OS!
\~russian Использовать таймер POSIX с SIGEV_THREAD уведомлением. \attention Не поддерживается на Windows и Mac OS!
*/ = 0x02,
*/
= 0x02,
Pool /*!
\~english Using single TimerPool for all timers with this implementation. TimerPool works as Thread implementation and
sequentially executes all timers. \attention Use this implementation with care!
\~russian Использовать единый TimerPool для всех таймеров с этой реализацией. TimerPool реализован через Thread и
последовательно исполняет все таймеры. \attention Осторожнее с этой реализацией!
*/ = 0x04
*/
= 0x04
};
//! \~english Constructs timer with "ti" implementation
//! \~russian Создает таймер с реализацией "ti"
explicit PITimer(TimerImplementation ti);
//! \~english Constructs timer with "slot" slot void(void *,int), "data" data and "ti" implementation
//! \~russian Создает таймер со слотом "slot", данными "data" и реализацией "ti"
explicit PITimer(TimerEvent slot, void * data = 0, TimerImplementation ti = Thread);
//! \~english Constructs timer with "slot" slot void(), and "ti" implementation
//! \~russian Создает таймер со слотом "slot" и реализацией "ti"
explicit PITimer(std::function<void ()> slot, TimerImplementation ti = Thread);
explicit PITimer(std::function<void()> slot, TimerImplementation ti = Thread);
//! \~english Constructs timer with "slot" slot void(void *), "data" data and "ti" implementation
//! \~russian Создает таймер со слотом "slot", данными "data" и реализацией "ti"
explicit PITimer(std::function<void (void *)> slot, void * data, TimerImplementation ti = Thread);
explicit PITimer(std::function<void(void *)> slot, void * data, TimerImplementation ti = Thread);
virtual ~PITimer();
//! \~english Returns timer implementation
//! \~russian Возвращает реализацию таймера
PITimer::TimerImplementation implementation() const {return imp_mode;}
PITimer::TimerImplementation implementation() const { return imp_mode; }
//! \~english Returns timer loop delay in milliseconds
//! \~russian Возвращает задержку цикла таймера в миллисекундах
double interval() const;
EVENT_HANDLER1(void, setInterval, double, ms);
//! \~english Returns if timer is started
//! \~russian Возвращает работает ли таймер
bool isRunning() const;
//! \~english Returns if timer is not started
//! \~russian Возвращает остановлен ли таймер
bool isStopped() const;
EVENT_HANDLER0(bool, start);
EVENT_HANDLER1(bool, start, double, interval_ms_d);
bool start(int interval_ms_i);
@@ -159,64 +161,78 @@ public:
//! \~english Start timer with "interval_msecs" loop delay after "start_datetime" date and time
//! \~russian Запускает таймер с интервалом "interval_msecs" после наступления "start_datetime"
void startDeferred(double interval_ms, PIDateTime start_datetime);
EVENT_HANDLER0(bool, stop);
//! \~english Set custom data
//! \~russian Установить данные, передаваемые в метод таймера
void setData(void * data_) {data_t = data_;}
void setData(void * data_) { data_t = data_; }
//! \~english Returns common data passed to tick functions
//! \~russian Возвращает данные, передаваемые в метод таймера
void * data() const {return data_t;}
void * data() const { return data_t; }
//! \~english Set timer tick function
//! \~russian Установить вызываемый метод
void setSlot(TimerEvent slot) {ret_func = slot;}
void setSlot(TimerEvent slot) { ret_func = slot; }
//! \~english Set timer tick function
//! \~russian Установить вызываемый метод
void setSlot(std::function<void ()> slot) {ret_func = [slot](void *, int){slot();};}
void setSlot(std::function<void()> slot) {
ret_func = [slot](void *, int) { slot(); };
}
//! \~english Set timer tick function
//! \~russian Установить вызываемый метод
void setSlot(std::function<void (void *)> slot) {ret_func = [slot](void *d, int){slot(d);};}
void setSlot(std::function<void(void *)> slot) {
ret_func = [slot](void * d, int) { slot(d); };
}
void needLockRun(bool need) {lockRun = need;}
EVENT_HANDLER0(void, lock) {mutex_.lock();}
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
void needLockRun(bool need) { lockRun = need; }
EVENT_HANDLER0(void, lock) { mutex_.lock(); }
EVENT_HANDLER0(void, unlock) { mutex_.unlock(); }
//! \~english Returns if timer should exec \a maybeCallQueuedEvents() at every tick. By default \b true
//! \~russian Возвращает должен ли таймер вызывать \a maybeCallQueuedEvents() каждый тик. По умолчанию \b true
bool isCallQueuedEvents() const {return callEvents;}
bool isCallQueuedEvents() const { return callEvents; }
//! \~english Set timer exec \a maybeCallQueuedEvents() at every tick
//! \~russian Установает должен ли таймер вызывать \a maybeCallQueuedEvents() каждый тик
void setCallQueuedEvents(bool yes) {callEvents = yes;}
void setCallQueuedEvents(bool yes) { callEvents = yes; }
//! \~english Add frequency delimiter "delim" with optional delimiter slot "slot"
//! \~russian Добавляет делитель частоты "delim" с необязательным методом "slot"
void addDelimiter(int delim, TimerEvent slot = 0) {delims << Delimiter(slot, delim);}
void addDelimiter(int delim, TimerEvent slot = 0) { delims << Delimiter(slot, delim); }
//! \~english Add frequency delimiter "delim" with optional delimiter slot "slot"
//! \~russian Добавляет делитель частоты "delim" с необязательным методом "slot"
void addDelimiter(int delim, std::function<void ()> slot) {delims << Delimiter([slot](void *, int){slot();}, delim);}
void addDelimiter(int delim, std::function<void()> slot) {
delims << Delimiter([slot](void *, int) { slot(); }, delim);
}
//! \~english Add frequency delimiter "delim" with optional delimiter slot "slot"
//! \~russian Добавляет делитель частоты "delim" с необязательным методом "slot"
void addDelimiter(int delim, std::function<void (void *)> slot) {delims << Delimiter([slot](void *d, int){slot(d);}, delim);}
void addDelimiter(int delim, std::function<void(void *)> slot) {
delims << Delimiter([slot](void * d, int) { slot(d); }, delim);
}
//! \~english Remove all frequency delimiters "delim"
//! \~russian Удаляет все делители частоты "delim"
void removeDelimiter(int delim) {for (int i = 0; i < delims.size_s(); ++i) if (delims[i].delim == delim) {delims.remove(i); i--;}}
EVENT_HANDLER0(void, clearDelimiters) {delims.clear();}
EVENT2(tickEvent, void * , data_, int, delimiter);
//! \handlers
//! \{
void removeDelimiter(int delim) {
for (int i = 0; i < delims.size_s(); ++i)
if (delims[i].delim == delim) {
delims.remove(i);
i--;
}
}
EVENT_HANDLER0(void, clearDelimiters) { delims.clear(); }
EVENT2(tickEvent, void *, data_, int, delimiter);
//! \handlers
//! \{
//! \fn void setInterval(double ms)
//! \brief
//! \~english Set timer loop delay in milliseconds
@@ -250,21 +266,21 @@ public:
//! \brief
//! \~english Stop and start timer with \a interval() loop delay
//! \~russian Остановить и запустить таймер с интервалом \a interval()
//! \fn bool stop(bool wait = true)
//! \brief
//! \~english Stop timer and wait for it finish if "wait"
//! \~russian Остановить таймер и если "wait" то дождаться остановки
//! \fn void clearDelimiters()
//! \brief
//! \~english Remove all frequency delimiters
//! \~russian Удаляет все делители частоты
//! \}
//! \events
//! \{
//! \}
//! \events
//! \{
//! \fn void tickEvent(void * data, int delimiter)
//! \brief
//! \~english Raise on timer tick
@@ -276,35 +292,39 @@ public:
//! \~russian
//! "data" устанавливается методом \a setData() или в конструкторе.
//! "delimiter" - делитель частоты, 1 для основного цикла
//! \}
//! \}
protected:
struct PIP_EXPORT Delimiter {
Delimiter(TimerEvent slot_ = 0, int delim_ = 1) {slot = slot_; delim = delim_; tick = 0;}
Delimiter(TimerEvent slot_ = 0, int delim_ = 1) {
slot = slot_;
delim = delim_;
tick = 0;
}
TimerEvent slot;
int delim;
int tick;
};
void initFirst();
void init() const;
void destroy();
static void tickImpS(PITimer * t) {t->tickImp();}
static void tickImpS(PITimer * t) { t->tickImp(); }
void tickImp();
//! Timer execution function, similar to "slot" or event \a timeout(). By default does nothing
virtual void tick(void * data_, int delimiter) {}
void * data_t;
std::atomic_bool lockRun, callEvents;
PIMutex mutex_;
TimerEvent ret_func;
TimerImplementation imp_mode;
PIVector<Delimiter> delims;
mutable _PITimerBase * imp;
};