Compare commits
79 Commits
zmq
...
fff2aa468a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fff2aa468a | ||
|
|
4921a3b0fd | ||
|
|
8296e9a32b | ||
|
|
7403ee67be | ||
|
|
cde2341c1f | ||
|
|
542f180d9d | ||
| 86130d7105 | |||
|
|
c9e329d27d | ||
|
|
d4c6c410da | ||
|
|
a7df53fbfe | ||
|
|
0504fa187e | ||
| 1d9a39f792 | |||
| cbdaabee4a | |||
| 3c8ccf357b | |||
|
|
92b20f6f46 | ||
| 04d7ed77d9 | |||
| a2a205cfd2 | |||
| d3b6597042 | |||
|
|
48c885e12a | ||
|
|
6e5a5a6ade | ||
| 21e03fc8cb | |||
| b85de0d704 | |||
|
|
f781cc3846 | ||
|
|
1cb3d4ffe9 | ||
|
|
9293706634 | ||
|
|
fde6bdf17f | ||
|
|
a1c1fd8339 | ||
|
|
01b39dc75f | ||
| 07ec32c969 | |||
| 042366e19e | |||
| 948a90fcd9 | |||
| c404688bbd | |||
| aa76a15f40 | |||
|
|
ca20785b53 | ||
|
|
13d0b2f960 | ||
|
|
46571ac39f | ||
| 36d770ea2e | |||
|
|
bc7d129a9e | ||
| 8accc28804 | |||
|
|
62e130f91b | ||
| a009221092 | |||
| dedc35b466 | |||
| 5e33587703 | |||
| 950f6830da | |||
|
|
19a8ca84e6 | ||
|
|
ece3fb1536 | ||
| 0d119502a8 | |||
| cc5951cfc3 | |||
| 61d42e0ac5 | |||
| 127935086c | |||
| 76ed60edf3 | |||
| 3b0a1c70fe | |||
| 186e07e45d | |||
| 047cff7d6e | |||
| 305275e3ac | |||
| efb0d5f4f9 | |||
| 991a074538 | |||
| f82b6c12ee | |||
| 00edfa4ef0 | |||
| 35a3ce6402 | |||
| be3ce454a0 | |||
| 4c85206cfa | |||
| 5ecdcbe46e | |||
| c937d7251a | |||
| 1cc46468c1 | |||
| 5cc8ef1eb0 | |||
| 99e135caa2 | |||
| 9de7045d63 | |||
| 0e65151e9f | |||
| 3c20728210 | |||
| 4c0530d89a | |||
| f5af8a1da9 | |||
| 44b9c37391 | |||
| 97b0b6fc0c | |||
| 1a2e9afaef | |||
| 39a3a23a24 | |||
| ee131921a0 | |||
| f8818c8537 | |||
| b07242226e |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,4 +2,5 @@
|
|||||||
/.svn
|
/.svn
|
||||||
/doc/rtf
|
/doc/rtf
|
||||||
_unsused
|
_unsused
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
|
/include
|
||||||
@@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.0)
|
|||||||
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
cmake_policy(SET CMP0017 NEW) # need include() with .cmake
|
||||||
project(pip)
|
project(pip)
|
||||||
set(pip_MAJOR 2)
|
set(pip_MAJOR 2)
|
||||||
set(pip_MINOR 28)
|
set(pip_MINOR 33)
|
||||||
set(pip_REVISION 1)
|
set(pip_REVISION 0)
|
||||||
set(pip_SUFFIX )
|
set(pip_SUFFIX )
|
||||||
set(pip_COMPANY SHS)
|
set(pip_COMPANY SHS)
|
||||||
set(pip_DOMAIN org.SHS)
|
set(pip_DOMAIN org.SHS)
|
||||||
@@ -284,7 +284,7 @@ endif()
|
|||||||
if(APPLE)
|
if(APPLE)
|
||||||
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
|
add_definitions(-D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE)
|
||||||
endif()
|
endif()
|
||||||
if ((NOT DEFINED LIBPROJECT) AND (DEFINED ANDROID_PLATFORM))
|
if ((NOT DEFINED SHSTKPROJECT) AND (DEFINED ANDROID_PLATFORM))
|
||||||
include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include)
|
include_directories(${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include)
|
||||||
#message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include")
|
#message("${ANDROID_SYSTEM_LIBRARY_PATH}/usr/include")
|
||||||
#message("${ANDROID_NDK}/sysroot/usr/include")
|
#message("${ANDROID_NDK}/sysroot/usr/include")
|
||||||
@@ -320,7 +320,7 @@ if(WIN32)
|
|||||||
set(CMAKE_CXX_FLAGS "/O2 /Ob2 /Ot /W0")
|
set(CMAKE_CXX_FLAGS "/O2 /Ob2 /Ot /W0")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(${CMAKE_CXX_FLAGS} "${CMAKE_CXX_FLAGS} -fPIC")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||||
if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS)
|
if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
|
||||||
endif()
|
endif()
|
||||||
@@ -567,8 +567,8 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS))
|
|||||||
list(APPEND DOXY_INPUT "\"${F}\"")
|
list(APPEND DOXY_INPUT "\"${F}\"")
|
||||||
endforeach(F)
|
endforeach(F)
|
||||||
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"")
|
string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"")
|
||||||
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}")
|
string(REPLACE ";" " " DOXY_INCLUDE_PATH "${PIP_INCLUDES}")
|
||||||
string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS")
|
string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS}")
|
||||||
add_documentation(doc doc/Doxyfile.in)
|
add_documentation(doc doc/Doxyfile.in)
|
||||||
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL)
|
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -71,6 +71,10 @@ if (NOT BUILDING_pip)
|
|||||||
find_library(PTHREAD_LIBRARY pthread)
|
find_library(PTHREAD_LIBRARY pthread)
|
||||||
find_library(UTIL_LIBRARY util)
|
find_library(UTIL_LIBRARY util)
|
||||||
set(_PIP_ADD_LIBS_ ${PTHREAD_LIBRARY} ${UTIL_LIBRARY})
|
set(_PIP_ADD_LIBS_ ${PTHREAD_LIBRARY} ${UTIL_LIBRARY})
|
||||||
|
if((NOT DEFINED ENV{QNX_HOST}) AND (NOT APPLE) AND (NOT PIP_FREERTOS))
|
||||||
|
find_library(RT_LIBRARY rt)
|
||||||
|
list(APPEND _PIP_ADD_LIBS_ ${RT_LIBRARY})
|
||||||
|
endif()
|
||||||
list(APPEND PIP_LIBRARY ${_PIP_ADD_LIBS_})
|
list(APPEND PIP_LIBRARY ${_PIP_ADD_LIBS_})
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -2164,7 +2164,7 @@ INCLUDE_FILE_PATTERNS =
|
|||||||
# recursively expanded use the := operator instead of the = operator.
|
# recursively expanded use the := operator instead of the = operator.
|
||||||
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
|
||||||
|
|
||||||
PREDEFINED = ${DOXY_DEFINES}
|
PREDEFINED = DOXYGEN PIOBJECT PIOBJECT_SUBCLASS PIIODEVICE NO_COPY_CLASS ${DOXY_DEFINES}
|
||||||
|
|
||||||
|
|
||||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
|
||||||
|
|||||||
29
library.json
Normal file
29
library.json
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "PIP",
|
||||||
|
"keywords": "pip",
|
||||||
|
"description": "Platform-Independent Primitives",
|
||||||
|
"repository":
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.shs.tools/SHS/pip.git"
|
||||||
|
},
|
||||||
|
"frameworks": "*",
|
||||||
|
"platforms": "*",
|
||||||
|
"dependencies": {
|
||||||
|
"mike-matera/ArduinoSTL": "^1.3.2",
|
||||||
|
"linlin-study/FreeRTOS-Kernel": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"build":
|
||||||
|
{
|
||||||
|
"srcFilter": [
|
||||||
|
"+<libs/main/core/*.cpp>",
|
||||||
|
"+<libs/main/containers/*.cpp>",
|
||||||
|
"+<libs/main/math/*.cpp>",
|
||||||
|
"+<libs/main/thread/*.cpp>",
|
||||||
|
"+<libs/main/io_uutils/*.cpp>",
|
||||||
|
"+<libs/main/geo/*.cpp>"
|
||||||
|
],
|
||||||
|
"extraScript": "platformio_pre.py",
|
||||||
|
"flags": "-DPIP_FREERTOS"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(ð), tcp(&streampacker) {
|
PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(ð), tcp(&streampacker) {
|
||||||
|
eth.setDebug(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,29 +25,36 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode)
|
|||||||
tcp.setRole(PICloud::TCP::Client);
|
tcp.setRole(PICloud::TCP::Client);
|
||||||
setName("cloud_client");
|
setName("cloud_client");
|
||||||
is_connected = false;
|
is_connected = false;
|
||||||
CONNECTL(ð, connected, [this](){tcp.sendStart();});
|
is_deleted = false;
|
||||||
|
// setReopenEnabled(false);
|
||||||
|
CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();});
|
||||||
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
||||||
CONNECTL(ð, disconnected, [this](bool){
|
CONNECTL(ð, disconnected, [this](bool){
|
||||||
piCoutObj << "disconnected";
|
if (is_deleted) return;
|
||||||
|
bool need_disconn = is_connected;
|
||||||
|
//piCoutObj << "eth disconnected";
|
||||||
|
static_cast<PIThread*>(ð)->stop();
|
||||||
opened_ = false;
|
opened_ = false;
|
||||||
is_connected = false;
|
internalDisconnect();
|
||||||
cond_connect.notifyOne();
|
if (need_disconn)
|
||||||
cond_buff.notifyOne();
|
disconnected();
|
||||||
piMSleep(100);
|
//piCoutObj << "eth disconnected done";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PICloudClient::~PICloudClient() {
|
PICloudClient::~PICloudClient() {
|
||||||
eth.close();
|
//piCoutObj << "~PICloudClient()";
|
||||||
if (is_connected) {
|
PIThread::stop();
|
||||||
is_connected = false;
|
//eth.close();
|
||||||
disconnected();
|
//if (is_connected) disconnected();
|
||||||
cond_buff.notifyOne();
|
|
||||||
cond_connect.notifyOne();
|
|
||||||
}
|
|
||||||
close();
|
close();
|
||||||
stop();
|
//piCoutObj << "~PICloudClient() closed";
|
||||||
|
internalDisconnect();
|
||||||
|
// stop(false);
|
||||||
|
is_deleted = true;
|
||||||
|
internalDisconnect();
|
||||||
|
//piCoutObj << "~PICloudClient() done";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -63,80 +70,100 @@ void PICloudClient::setKeepConnection(bool on) {
|
|||||||
|
|
||||||
|
|
||||||
bool PICloudClient::openDevice() {
|
bool PICloudClient::openDevice() {
|
||||||
// piCout << "PICloudClient open device" << path();
|
//piCoutObj << "open";// << path();
|
||||||
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
||||||
if (op) {
|
if (op) {
|
||||||
mutex_buff.lock();
|
mutex_connect.lock();
|
||||||
eth.startThreadedRead();
|
eth.startThreadedRead();
|
||||||
bool conn_ok = cond_connect.waitFor(mutex_buff, (int)eth.readTimeout(), [this](){return isConnected();});
|
//piCoutObj << "connecting...";
|
||||||
piCoutObj << "conn_ok" << conn_ok;
|
bool conn_ok = cond_connect.waitFor(mutex_connect, (int)eth.readTimeout());
|
||||||
mutex_buff.unlock();
|
//piCoutObj << "conn_ok" << conn_ok << is_connected;
|
||||||
|
mutex_connect.unlock();
|
||||||
if (!conn_ok) {
|
if (!conn_ok) {
|
||||||
|
mutex_connect.lock();
|
||||||
eth.stop();
|
eth.stop();
|
||||||
eth.close();
|
eth.close();
|
||||||
piMSleep(100);
|
mutex_connect.unlock();
|
||||||
}
|
}
|
||||||
return isConnected();
|
return is_connected;
|
||||||
} else {
|
} else {
|
||||||
eth.close();
|
//eth.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PICloudClient::closeDevice() {
|
bool PICloudClient::closeDevice() {
|
||||||
|
//PIThread::stop();
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
is_connected = false;
|
internalDisconnect();
|
||||||
disconnected();
|
|
||||||
cond_buff.notifyOne();
|
|
||||||
cond_connect.notifyOne();
|
|
||||||
}
|
}
|
||||||
eth.stop();
|
eth.stop();
|
||||||
if (eth.isOpened()) eth.close();
|
eth.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PICloudClient::readDevice(void * read_to, int max_size) {
|
int PICloudClient::readDevice(void * read_to, int max_size) {
|
||||||
// piCoutObj << "readDevice";
|
if (is_deleted) return -1;
|
||||||
if (!is_connected) return -1;
|
//piCoutObj << "readDevice";
|
||||||
|
if (!is_connected && eth.isClosed()) openDevice();
|
||||||
|
int sz = -1;
|
||||||
mutex_buff.lock();
|
mutex_buff.lock();
|
||||||
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();});
|
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
|
||||||
int sz = piMini(max_size, buff.size());
|
if (is_connected) {
|
||||||
memcpy(read_to, buff.data(), sz);
|
sz = piMini(max_size, buff.size());
|
||||||
buff.remove(0, sz);
|
memcpy(read_to, buff.data(), sz);
|
||||||
|
buff.remove(0, sz);
|
||||||
|
}
|
||||||
mutex_buff.unlock();
|
mutex_buff.unlock();
|
||||||
|
if (!is_connected) opened_ = false;
|
||||||
|
//piCoutObj << "readDevice done" << sz;
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PICloudClient::writeDevice(const void * data, int size) {
|
int PICloudClient::writeDevice(const void * data, int size) {
|
||||||
|
if (is_deleted) return -1;
|
||||||
// piCoutObj << "writeDevice";
|
// piCoutObj << "writeDevice";
|
||||||
return tcp.sendData(PIByteArray(data, size));
|
return tcp.sendData(PIByteArray(data, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PICloudClient::internalDisconnect() {
|
||||||
|
is_connected = false;
|
||||||
|
cond_buff.notifyOne();
|
||||||
|
cond_connect.notifyOne();
|
||||||
|
streampacker.clear();
|
||||||
|
buff.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PICloudClient::_readed(PIByteArray & ba) {
|
void PICloudClient::_readed(PIByteArray & ba) {
|
||||||
mutex_buff.lock();
|
if (is_deleted) return;
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
||||||
|
//piCoutObj << "_readed" << ba.size() << hdr.first << hdr.second;
|
||||||
if (hdr.second == tcp.role()) {
|
if (hdr.second == tcp.role()) {
|
||||||
switch (hdr.first) {
|
switch (hdr.first) {
|
||||||
case PICloud::TCP::Connect:
|
case PICloud::TCP::Connect:
|
||||||
if (tcp.parseConnect(ba) == 1) {
|
if (tcp.parseConnect(ba) == 1) {
|
||||||
|
mutex_connect.lock();
|
||||||
is_connected = true;
|
is_connected = true;
|
||||||
connected();
|
mutex_connect.unlock();
|
||||||
cond_connect.notifyOne();
|
cond_connect.notifyOne();
|
||||||
|
connected();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PICloud::TCP::Disconnect:
|
case PICloud::TCP::Disconnect:
|
||||||
is_connected = false;
|
static_cast<PIThread*>(ð)->stop();
|
||||||
eth.stop();
|
opened_ = false;
|
||||||
eth.close();
|
eth.close();
|
||||||
disconnected();
|
|
||||||
break;
|
break;
|
||||||
case PICloud::TCP::Data:
|
case PICloud::TCP::Data:
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
|
mutex_buff.lock();
|
||||||
buff.append(ba);
|
buff.append(ba);
|
||||||
|
mutex_buff.unlock();
|
||||||
cond_buff.notifyOne();
|
cond_buff.notifyOne();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -145,7 +172,7 @@ void PICloudClient::_readed(PIByteArray & ba) {
|
|||||||
}
|
}
|
||||||
//piCoutObj << "readed" << ba.toHex();
|
//piCoutObj << "readed" << ba.toHex();
|
||||||
}
|
}
|
||||||
mutex_buff.unlock();
|
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); // FIXME: sleep here is bad
|
||||||
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100);
|
//piCoutObj << "_readed done";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,12 +26,17 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode)
|
|||||||
tcp.setServerName(server_name);
|
tcp.setServerName(server_name);
|
||||||
setName("cloud_server__" + server_name);
|
setName("cloud_server__" + server_name);
|
||||||
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
CONNECTU(&streampacker, packetReceiveEvent, this, _readed);
|
||||||
CONNECTL(ð, connected, [this](){tcp.sendStart();});
|
CONNECTL(ð, connected, [this](){opened_ = true; piCoutObj << "connected"; tcp.sendStart();});
|
||||||
CONNECTL(ð, disconnected, [this](bool){
|
CONNECTL(ð, disconnected, [this](bool){
|
||||||
piCoutObj << "disconnected";
|
piCoutObj << "disconnected";
|
||||||
|
static_cast<PIThread*>(ð)->stop();
|
||||||
opened_ = false;
|
opened_ = false;
|
||||||
|
ping_timer.stop(false);
|
||||||
piMSleep(100);
|
piMSleep(100);
|
||||||
});
|
});
|
||||||
|
CONNECTL(&ping_timer, tickEvent, [this] (void *, int){
|
||||||
|
if (eth.isConnected()) tcp.sendPing();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -54,12 +59,14 @@ PIVector<PICloudServer::Client *> PICloudServer::clients() const {
|
|||||||
|
|
||||||
|
|
||||||
bool PICloudServer::openDevice() {
|
bool PICloudServer::openDevice() {
|
||||||
piCout << "PICloudServer open device" << path();
|
//piCout << "PICloudServer open device" << path();
|
||||||
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
bool op = eth.connect(PIEthernet::Address::resolve(path()), false);
|
||||||
if (op) {
|
if (op) {
|
||||||
eth.startThreadedRead();
|
eth.startThreadedRead();
|
||||||
|
ping_timer.start(5000);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
ping_timer.stop(false);
|
||||||
eth.close();
|
eth.close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -67,6 +74,7 @@ bool PICloudServer::openDevice() {
|
|||||||
|
|
||||||
bool PICloudServer::closeDevice() {
|
bool PICloudServer::closeDevice() {
|
||||||
eth.stop();
|
eth.stop();
|
||||||
|
ping_timer.stop(false);
|
||||||
clients_mutex.lock();
|
clients_mutex.lock();
|
||||||
for (auto c : clients_) {
|
for (auto c : clients_) {
|
||||||
c->close();
|
c->close();
|
||||||
@@ -82,7 +90,8 @@ bool PICloudServer::closeDevice() {
|
|||||||
|
|
||||||
int PICloudServer::readDevice(void * read_to, int max_size) {
|
int PICloudServer::readDevice(void * read_to, int max_size) {
|
||||||
//piCoutObj << "readDevice";
|
//piCoutObj << "readDevice";
|
||||||
piMSleep(eth.readTimeout());
|
if (!opened_) openDevice();
|
||||||
|
else piMSleep(eth.readTimeout());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,22 +135,26 @@ bool PICloudServer::Client::openDevice() {
|
|||||||
|
|
||||||
|
|
||||||
bool PICloudServer::Client::closeDevice() {
|
bool PICloudServer::Client::closeDevice() {
|
||||||
|
PIThread::stop(false);
|
||||||
if (is_connected) {
|
if (is_connected) {
|
||||||
server->clientDisconnect(client_id);
|
server->clientDisconnect(client_id);
|
||||||
is_connected = false;
|
is_connected = false;
|
||||||
cond_buff.notifyOne();
|
|
||||||
}
|
}
|
||||||
|
cond_buff.notifyOne();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int PICloudServer::Client::readDevice(void * read_to, int max_size) {
|
int PICloudServer::Client::readDevice(void * read_to, int max_size) {
|
||||||
if (!is_connected) return -1;
|
if (!is_connected) return -1;
|
||||||
|
int sz = -1;
|
||||||
mutex_buff.lock();
|
mutex_buff.lock();
|
||||||
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();});
|
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty() || !is_connected;});
|
||||||
int sz = piMini(max_size, buff.size());
|
if (is_connected) {
|
||||||
memcpy(read_to, buff.data(), sz);
|
sz = piMini(max_size, buff.size());
|
||||||
buff.remove(0, sz);
|
memcpy(read_to, buff.data(), sz);
|
||||||
|
buff.remove(0, sz);
|
||||||
|
}
|
||||||
mutex_buff.unlock();
|
mutex_buff.unlock();
|
||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
@@ -158,7 +171,7 @@ void PICloudServer::Client::pushBuffer(const PIByteArray & ba) {
|
|||||||
buff.append(ba);
|
buff.append(ba);
|
||||||
cond_buff.notifyOne();
|
cond_buff.notifyOne();
|
||||||
mutex_buff.unlock();
|
mutex_buff.unlock();
|
||||||
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100);
|
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100); // FIXME: sleep here is bad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -174,7 +187,7 @@ void PICloudServer::_readed(PIByteArray & ba) {
|
|||||||
if (oc) {
|
if (oc) {
|
||||||
tcp.sendDisconnected(id);
|
tcp.sendDisconnected(id);
|
||||||
} else {
|
} else {
|
||||||
piCoutObj << "new Client" << id;
|
//piCoutObj << "new Client" << id;
|
||||||
Client * c = new Client(this, id);
|
Client * c = new Client(this, id);
|
||||||
CONNECTU(c, deleted, this, clientDeleted);
|
CONNECTU(c, deleted, this, clientDeleted);
|
||||||
clients_mutex.lock();
|
clients_mutex.lock();
|
||||||
@@ -186,7 +199,7 @@ void PICloudServer::_readed(PIByteArray & ba) {
|
|||||||
} break;
|
} break;
|
||||||
case PICloud::TCP::Disconnect: {
|
case PICloud::TCP::Disconnect: {
|
||||||
uint id = tcp.parseDisconnect(ba);
|
uint id = tcp.parseDisconnect(ba);
|
||||||
piCoutObj << "remove Client" << id;
|
//piCoutObj << "remove Client" << id;
|
||||||
clients_mutex.lock();
|
clients_mutex.lock();
|
||||||
Client * oc = index_clients.value(id, nullptr);
|
Client * oc = index_clients.value(id, nullptr);
|
||||||
clients_mutex.unlock();
|
clients_mutex.unlock();
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "pistreampacker.h"
|
#include "pistreampacker.h"
|
||||||
|
|
||||||
|
|
||||||
const char hash_def_key[] = "_picrypt_";
|
const char hash_cloud_key[] = "_picloud_";
|
||||||
|
|
||||||
|
|
||||||
PICloud::TCP::Header::Header() {
|
PICloud::TCP::Header::Header() {
|
||||||
@@ -33,7 +33,7 @@ PICloud::TCP::Header::Header() {
|
|||||||
|
|
||||||
|
|
||||||
PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) {
|
PICloud::TCP::TCP(PIStreamPacker * s) : streampacker(s) {
|
||||||
|
streampacker->setMaxPacketSize(63*1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PICloud::TCP::setRole(PICloud::TCP::Role r) {
|
void PICloud::TCP::setRole(PICloud::TCP::Role r) {
|
||||||
@@ -43,7 +43,7 @@ void PICloud::TCP::setRole(PICloud::TCP::Role r) {
|
|||||||
|
|
||||||
void PICloud::TCP::setServerName(const PIString & server_name_) {
|
void PICloud::TCP::setServerName(const PIString & server_name_) {
|
||||||
server_name = server_name_;
|
server_name = server_name_;
|
||||||
suuid = PICrypt::hash(server_name_);
|
suuid = PICrypt::hash(PIByteArray(server_name_.data(), server_name_.size()), (const unsigned char *)hash_cloud_key, sizeof(hash_cloud_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -62,7 +62,9 @@ void PICloud::TCP::sendStart() {
|
|||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
ba << header;
|
ba << header;
|
||||||
ba.append(suuid);
|
ba.append(suuid);
|
||||||
|
//mutex_send.lock();
|
||||||
streampacker->send(ba);
|
streampacker->send(ba);
|
||||||
|
//mutex_send.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -70,7 +72,9 @@ void PICloud::TCP::sendConnected(uint client_id) {
|
|||||||
header.type = PICloud::TCP::Connect;
|
header.type = PICloud::TCP::Connect;
|
||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
ba << header << client_id;
|
ba << header << client_id;
|
||||||
|
// mutex_send.lock();
|
||||||
streampacker->send(ba);
|
streampacker->send(ba);
|
||||||
|
// mutex_send.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -78,7 +82,9 @@ void PICloud::TCP::sendDisconnected(uint client_id) {
|
|||||||
header.type = PICloud::TCP::Disconnect;
|
header.type = PICloud::TCP::Disconnect;
|
||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
ba << header << client_id;
|
ba << header << client_id;
|
||||||
|
// mutex_send.lock();
|
||||||
streampacker->send(ba);
|
streampacker->send(ba);
|
||||||
|
// mutex_send.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -87,8 +93,10 @@ int PICloud::TCP::sendData(const PIByteArray & data) {
|
|||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
ba << header;
|
ba << header;
|
||||||
ba.append(data);
|
ba.append(data);
|
||||||
// piCout << "sendData" << ba.toHex();
|
// piCout << "[PICloud::TCP] sendData" << ba.toHex();
|
||||||
|
mutex_send.lock();
|
||||||
streampacker->send(ba);
|
streampacker->send(ba);
|
||||||
|
mutex_send.unlock();
|
||||||
return data.size_s();
|
return data.size_s();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,11 +106,24 @@ int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) {
|
|||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
ba << header << client_id;
|
ba << header << client_id;
|
||||||
ba.append(data);
|
ba.append(data);
|
||||||
|
mutex_send.lock();
|
||||||
streampacker->send(ba);
|
streampacker->send(ba);
|
||||||
|
mutex_send.unlock();
|
||||||
return data.size_s();
|
return data.size_s();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PICloud::TCP::sendPing() {
|
||||||
|
header.type = PICloud::TCP::Ping;
|
||||||
|
PIByteArray ba;
|
||||||
|
ba << header;
|
||||||
|
ba.append(suuid);
|
||||||
|
mutex_send.lock();
|
||||||
|
streampacker->send(ba);
|
||||||
|
mutex_send.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteArray & ba) {
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteArray & ba) {
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret;
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret;
|
||||||
ret.first = InvalidType;
|
ret.first = InvalidType;
|
||||||
@@ -120,11 +141,8 @@ PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteA
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIByteArray PICloud::TCP::parseData(PIByteArray & ba) {
|
bool PICloud::TCP::canParseData(PIByteArray & ba) {
|
||||||
if (header.role == Client) {
|
return header.role == Client;
|
||||||
return ba;
|
|
||||||
}
|
|
||||||
return PIByteArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,7 +151,7 @@ PIPair<uint, PIByteArray> PICloud::TCP::parseDataServer(PIByteArray & ba) {
|
|||||||
ret.first = 0;
|
ret.first = 0;
|
||||||
if (header.role == Server) {
|
if (header.role == Server) {
|
||||||
ba >> ret.first;
|
ba >> ret.first;
|
||||||
ret.second = ba;
|
ret.second.swap(ba);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "picompress.h"
|
#include "picompress.h"
|
||||||
#ifdef PIP_COMPRESS
|
#ifdef PIP_COMPRESS
|
||||||
# ifdef FREERTOS
|
# ifdef ESP_PLATFORM
|
||||||
# include "esp32/rom/miniz.h"
|
# include "esp32/rom/miniz.h"
|
||||||
# define compress2 mz_compress2
|
# define compress2 mz_compress2
|
||||||
# define Z_OK MZ_OK
|
# define Z_OK MZ_OK
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
# include <fcntl.h>
|
# include <fcntl.h>
|
||||||
# include <termios.h>
|
# include <termios.h>
|
||||||
#else
|
#else
|
||||||
|
# include <wingdi.h>
|
||||||
# include <wincon.h>
|
# include <wincon.h>
|
||||||
# ifndef COMMON_LVB_UNDERSCORE
|
# ifndef COMMON_LVB_UNDERSCORE
|
||||||
# define COMMON_LVB_UNDERSCORE 0x8000
|
# define COMMON_LVB_UNDERSCORE 0x8000
|
||||||
@@ -62,7 +63,7 @@ PIScreen::SystemConsole::SystemConsole() {
|
|||||||
GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode);
|
GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode);
|
||||||
GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo);
|
GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo);
|
||||||
#else
|
#else
|
||||||
# ifdef FREERTOS
|
# ifdef MICRO_PIP
|
||||||
w = 80;
|
w = 80;
|
||||||
h = 24;
|
h = 24;
|
||||||
# else
|
# else
|
||||||
@@ -108,16 +109,13 @@ void PIScreen::SystemConsole::end() {
|
|||||||
|
|
||||||
|
|
||||||
void PIScreen::SystemConsole::prepare() {
|
void PIScreen::SystemConsole::prepare() {
|
||||||
int w, h;
|
int w = 80, h = 24;
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->csbi);
|
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->csbi);
|
||||||
w = PRIVATE->csbi.srWindow.Right - PRIVATE->csbi.srWindow.Left + 1;
|
w = PRIVATE->csbi.srWindow.Right - PRIVATE->csbi.srWindow.Left + 1;
|
||||||
h = PRIVATE->csbi.srWindow.Bottom - PRIVATE->csbi.srWindow.Top + 1;
|
h = PRIVATE->csbi.srWindow.Bottom - PRIVATE->csbi.srWindow.Top + 1;
|
||||||
#else
|
#else
|
||||||
# ifdef FREERTOS
|
# ifndef MICRO_PIP
|
||||||
w = 80;
|
|
||||||
h = 24;
|
|
||||||
# else
|
|
||||||
winsize ws;
|
winsize ws;
|
||||||
ioctl(0, TIOCGWINSZ, &ws);
|
ioctl(0, TIOCGWINSZ, &ws);
|
||||||
w = ws.ws_col;
|
w = ws.ws_col;
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "piterminal.h"
|
#include "piterminal.h"
|
||||||
#include "pisharedmemory.h"
|
#include "pisharedmemory.h"
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include <wingdi.h>
|
||||||
# include <wincon.h>
|
# include <wincon.h>
|
||||||
# include <winuser.h>
|
# include <winuser.h>
|
||||||
#else
|
#else
|
||||||
@@ -917,4 +918,4 @@ bool PITerminal::resize(int cols, int rows) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FREERTOS
|
#endif // MICRO_PIP
|
||||||
|
|||||||
@@ -169,6 +169,19 @@ PIByteArray PICrypt::hash(const PIByteArray & data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIByteArray PICrypt::hash(const PIByteArray & data, const unsigned char *key, size_t keylen) {
|
||||||
|
PIByteArray hash;
|
||||||
|
#ifdef PIP_CRYPT
|
||||||
|
if (!init()) return hash;
|
||||||
|
hash.resize(crypto_generichash_BYTES);
|
||||||
|
crypto_generichash(hash.data(), hash.size(), data.data(), data.size(), key, keylen);
|
||||||
|
#else
|
||||||
|
PICRYPT_DISABLED_WARNING
|
||||||
|
#endif
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t PICrypt::sizeHash() {
|
size_t PICrypt::sizeHash() {
|
||||||
#ifdef PIP_CRYPT
|
#ifdef PIP_CRYPT
|
||||||
return crypto_generichash_BYTES;
|
return crypto_generichash_BYTES;
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() {
|
|||||||
_started = false;
|
_started = false;
|
||||||
_send_only = send_only;
|
_send_only = send_only;
|
||||||
_reinit = true;
|
_reinit = true;
|
||||||
//initMcast(PIEthernet::allAddresses());
|
|
||||||
PIThread::start(3000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -140,7 +138,6 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
piForeachC (PIEthernet::Address & a, al) {
|
piForeachC (PIEthernet::Address & a, al) {
|
||||||
PIEthernet * ce = 0;
|
PIEthernet * ce = 0;
|
||||||
//piCout << "mcast try" << a;
|
//piCout << "mcast try" << a;
|
||||||
|
|
||||||
if (_channels[Multicast]) {
|
if (_channels[Multicast]) {
|
||||||
ce = new PIEthernet();
|
ce = new PIEthernet();
|
||||||
ce->setDebug(false);
|
ce->setDebug(false);
|
||||||
@@ -184,7 +181,6 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
eth_mcast << ce;
|
eth_mcast << ce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_channels[Loopback]) {
|
if (_channels[Loopback]) {
|
||||||
@@ -207,11 +203,14 @@ void PIBroadcast::initAll(PIVector<PIEthernet::Address> al) {
|
|||||||
|
|
||||||
|
|
||||||
void PIBroadcast::send(const PIByteArray & data) {
|
void PIBroadcast::send(const PIByteArray & data) {
|
||||||
|
if (!isRunning()) {
|
||||||
|
reinit();
|
||||||
|
PIThread::start(3000);
|
||||||
|
}
|
||||||
PIByteArray cd = cryptData(data);
|
PIByteArray cd = cryptData(data);
|
||||||
if (cd.isEmpty()) return;
|
if (cd.isEmpty()) return;
|
||||||
PIMutexLocker ml(mcast_mutex);
|
PIMutexLocker ml(mcast_mutex);
|
||||||
piForeach (PIEthernet * e, eth_mcast)
|
piForeach (PIEthernet * e, eth_mcast) e->send(cd);
|
||||||
e->send(cd);
|
|
||||||
if (eth_lo) {
|
if (eth_lo) {
|
||||||
for (int i = 0; i < lo_pcnt; ++i) {
|
for (int i = 0; i < lo_pcnt; ++i) {
|
||||||
eth_lo->send("127.0.0.1", lo_port + i, cd);
|
eth_lo->send("127.0.0.1", lo_port + i, cd);
|
||||||
@@ -221,30 +220,31 @@ void PIBroadcast::send(const PIByteArray & data) {
|
|||||||
|
|
||||||
|
|
||||||
void PIBroadcast::startRead() {
|
void PIBroadcast::startRead() {
|
||||||
|
if (!isRunning()) {
|
||||||
|
_started = false;
|
||||||
|
reinit();
|
||||||
|
PIThread::start(3000);
|
||||||
|
}
|
||||||
if (_send_only) return;
|
if (_send_only) return;
|
||||||
PIMutexLocker ml(mcast_mutex);
|
PIMutexLocker ml(mcast_mutex);
|
||||||
piForeach (PIEthernet * e, eth_mcast)
|
piForeach (PIEthernet * e, eth_mcast) e->startThreadedRead();
|
||||||
e->startThreadedRead();
|
if (eth_lo) eth_lo->startThreadedRead();
|
||||||
if (eth_lo)
|
|
||||||
eth_lo->startThreadedRead();
|
|
||||||
_started = true;
|
_started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBroadcast::stopRead() {
|
void PIBroadcast::stopRead() {
|
||||||
|
if (isRunning()) stop();
|
||||||
PIMutexLocker ml(mcast_mutex);
|
PIMutexLocker ml(mcast_mutex);
|
||||||
piForeach (PIEthernet * e, eth_mcast)
|
piForeach (PIEthernet * e, eth_mcast) e->stopThreadedRead();
|
||||||
e->stopThreadedRead();
|
if (eth_lo) eth_lo->stopThreadedRead();
|
||||||
if (eth_lo)
|
|
||||||
eth_lo->stopThreadedRead();
|
|
||||||
_started = false;
|
_started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBroadcast::reinit() {
|
void PIBroadcast::reinit() {
|
||||||
initAll(PIEthernet::allAddresses());
|
initAll(PIEthernet::allAddresses());
|
||||||
if (_started)
|
if (_started) startRead();
|
||||||
startRead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -261,8 +261,6 @@ void PIBroadcast::run() {
|
|||||||
mcast_mutex.lock();
|
mcast_mutex.lock();
|
||||||
bool r = _reinit, ac = (al != prev_al);
|
bool r = _reinit, ac = (al != prev_al);
|
||||||
mcast_mutex.unlock();
|
mcast_mutex.unlock();
|
||||||
if (ac || r)
|
if (ac || r) reinit();
|
||||||
reinit();
|
if (ac) addressesChanged();
|
||||||
if (ac)
|
|
||||||
addressesChanged();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,6 +68,13 @@ void PIStreamPacker::setCryptSizeEnabled(bool on) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIStreamPacker::clear() {
|
||||||
|
packet.clear();
|
||||||
|
packet_size = -1;
|
||||||
|
stream.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIStreamPacker::send(const PIByteArray & data) {
|
void PIStreamPacker::send(const PIByteArray & data) {
|
||||||
if (data.isEmpty()) return;
|
if (data.isEmpty()) return;
|
||||||
PIByteArray cd;
|
PIByteArray cd;
|
||||||
@@ -94,31 +101,12 @@ void PIStreamPacker::send(const PIByteArray & data) {
|
|||||||
hdr << int(cd.size_s());
|
hdr << int(cd.size_s());
|
||||||
cd.insert(0, hdr);
|
cd.insert(0, hdr);
|
||||||
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
|
int pcnt = (cd.size_s() - 1) / max_packet_size + 1, pst = 0;
|
||||||
if (pcnt > 1) {
|
|
||||||
prog_s_mutex.lock();
|
|
||||||
prog_s.active = true;
|
|
||||||
prog_s.bytes_all = data.size_s();
|
|
||||||
prog_s.bytes_current = 0;
|
|
||||||
prog_s.progress = 0.;
|
|
||||||
prog_s_mutex.unlock();
|
|
||||||
}
|
|
||||||
for (int i = 0; i < pcnt; ++i) {
|
for (int i = 0; i < pcnt; ++i) {
|
||||||
if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst);
|
if (i == pcnt - 1) part = PIByteArray(cd.data(pst), cd.size_s() - pst);
|
||||||
else part = PIByteArray(cd.data(pst), max_packet_size);
|
else part = PIByteArray(cd.data(pst), max_packet_size);
|
||||||
//piCout << "send" << part.size();
|
//piCout << "send" << part.size();
|
||||||
sendRequest(part);
|
sendRequest(part);
|
||||||
pst += max_packet_size;
|
pst += max_packet_size;
|
||||||
if (pcnt > 1) {
|
|
||||||
prog_s_mutex.lock();
|
|
||||||
prog_s.bytes_current += part.size_s();
|
|
||||||
prog_s.progress = (double)prog_s.bytes_current / prog_s.bytes_all;
|
|
||||||
prog_s_mutex.unlock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pcnt > 1) {
|
|
||||||
prog_s_mutex.lock();
|
|
||||||
prog_s.active = false;
|
|
||||||
prog_s_mutex.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,22 +154,10 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
|||||||
packet_size = sz;
|
packet_size = sz;
|
||||||
if (packet_size == 0)
|
if (packet_size == 0)
|
||||||
packet_size = -1;
|
packet_size = -1;
|
||||||
else {
|
|
||||||
prog_r_mutex.lock();
|
|
||||||
prog_r.active = true;
|
|
||||||
prog_r.bytes_all = packet_size;
|
|
||||||
prog_r.bytes_current = 0;
|
|
||||||
prog_r.progress = 0.;
|
|
||||||
prog_r_mutex.unlock();
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
int ps = piMini(stream.size_s(), packet_size - packet.size_s());
|
int ps = piMini(stream.size_s(), packet_size - packet.size_s());
|
||||||
packet.append(stream.data(), ps);
|
packet.append(stream.data(), ps);
|
||||||
prog_r_mutex.lock();
|
|
||||||
prog_r.bytes_current = packet.size_s();
|
|
||||||
prog_r.progress = (double)prog_r.bytes_current / piMaxi(1, prog_r.bytes_all);
|
|
||||||
prog_r_mutex.unlock();
|
|
||||||
stream.remove(0, ps);
|
stream.remove(0, ps);
|
||||||
if (packet.size_s() == packet_size) {
|
if (packet.size_s() == packet_size) {
|
||||||
PIByteArray cd;
|
PIByteArray cd;
|
||||||
@@ -211,9 +187,6 @@ void PIStreamPacker::received(const PIByteArray & data) {
|
|||||||
}
|
}
|
||||||
packet.clear();
|
packet.clear();
|
||||||
packet_size = -1;
|
packet_size = -1;
|
||||||
prog_r_mutex.lock();
|
|
||||||
prog_r.active = false;
|
|
||||||
prog_r_mutex.unlock();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,30 +200,3 @@ void PIStreamPacker::assignDevice(PIIODevice * dev) {
|
|||||||
CONNECTU(dev, threadedReadEvent, this, received);
|
CONNECTU(dev, threadedReadEvent, this, received);
|
||||||
CONNECTU(this, sendRequest, dev, write);
|
CONNECTU(this, sendRequest, dev, write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIStreamPacker::Progress PIStreamPacker::progressSend() const {
|
|
||||||
PIStreamPacker::Progress ret;
|
|
||||||
prog_s_mutex.lock();
|
|
||||||
ret = prog_s;
|
|
||||||
prog_s_mutex.unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIStreamPacker::Progress PIStreamPacker::progressReceive() const {
|
|
||||||
PIStreamPacker::Progress ret;
|
|
||||||
prog_r_mutex.lock();
|
|
||||||
ret = prog_r;
|
|
||||||
prog_r_mutex.unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PIStreamPacker::Progress::Progress() {
|
|
||||||
active = false;
|
|
||||||
bytes_all = bytes_current = 0;
|
|
||||||
progress = 0.;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -52,12 +52,15 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER1(void, _readed, PIByteArray &, data);
|
EVENT_HANDLER1(void, _readed, PIByteArray &, data);
|
||||||
|
void internalDisconnect();
|
||||||
|
|
||||||
PIByteArray buff;
|
PIByteArray buff;
|
||||||
PIMutex mutex_buff;
|
PIMutex mutex_buff;
|
||||||
PIMutex mutex_connect;
|
PIMutex mutex_connect;
|
||||||
PIConditionVariable cond_buff;
|
PIConditionVariable cond_buff;
|
||||||
PIConditionVariable cond_connect;
|
PIConditionVariable cond_connect;
|
||||||
std::atomic_bool is_connected;
|
std::atomic_bool is_connected;
|
||||||
|
std::atomic_bool is_deleted;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PICLOUDCLIENT_H
|
#endif // PICLOUDCLIENT_H
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ private:
|
|||||||
|
|
||||||
PIVector<Client *> clients_;
|
PIVector<Client *> clients_;
|
||||||
PIMap<uint, Client *> index_clients;
|
PIMap<uint, Client *> index_clients;
|
||||||
|
PITimer ping_timer;
|
||||||
mutable PIMutex clients_mutex;
|
mutable PIMutex clients_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "pip_cloud_export.h"
|
#include "pip_cloud_export.h"
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
#include "pimutex.h"
|
||||||
|
|
||||||
|
|
||||||
class PIEthernet;
|
class PIEthernet;
|
||||||
@@ -52,6 +53,7 @@ public:
|
|||||||
Connect = 1,
|
Connect = 1,
|
||||||
Disconnect = 2,
|
Disconnect = 2,
|
||||||
Data = 3,
|
Data = 3,
|
||||||
|
Ping = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
TCP(PIStreamPacker * s);
|
TCP(PIStreamPacker * s);
|
||||||
@@ -65,8 +67,9 @@ public:
|
|||||||
void sendDisconnected(uint client_id);
|
void sendDisconnected(uint client_id);
|
||||||
int sendData(const PIByteArray & data);
|
int sendData(const PIByteArray & data);
|
||||||
int sendData(const PIByteArray & data, uint client_id);
|
int sendData(const PIByteArray & data, uint client_id);
|
||||||
|
void sendPing();
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
||||||
PIByteArray parseData(PIByteArray & ba);
|
bool canParseData(PIByteArray & ba);
|
||||||
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
|
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
|
||||||
PIByteArray parseConnect_d(PIByteArray & ba);
|
PIByteArray parseConnect_d(PIByteArray & ba);
|
||||||
uint parseConnect(PIByteArray & ba);
|
uint parseConnect(PIByteArray & ba);
|
||||||
@@ -84,6 +87,8 @@ private:
|
|||||||
PIByteArray suuid;
|
PIByteArray suuid;
|
||||||
PIString server_name;
|
PIString server_name;
|
||||||
PIStreamPacker * streampacker;
|
PIStreamPacker * streampacker;
|
||||||
|
PIMutex mutex_send;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ int PICodeInfo::EnumInfo::memberValue(const PIString & name_) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIVariantTypes::Enum PICodeInfo::EnumInfo::toPIVariantEnum() {
|
||||||
|
PIVariantTypes::Enum en(name);
|
||||||
|
for (auto m: members) en << m.toPIVariantEnumerator();
|
||||||
|
if (!en.isEmpty()) en.selectValue(members.front().value);
|
||||||
|
return en;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
|
PIMap<PIString, PICodeInfo::ClassInfo * > * PICodeInfo::classesInfo;
|
||||||
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
|
PIMap<PIString, PICodeInfo::EnumInfo * > * PICodeInfo::enumsInfo;
|
||||||
PIMap<PIString, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions;
|
PIMap<PIString, PICodeInfo::AccessValueFunction> * PICodeInfo::accessValueFunctions;
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
#define PICODEINFO_H
|
#define PICODEINFO_H
|
||||||
|
|
||||||
#include "pistringlist.h"
|
#include "pistringlist.h"
|
||||||
|
#include "pivarianttypes.h"
|
||||||
|
|
||||||
|
|
||||||
class PIVariant;
|
class PIVariant;
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ struct PIP_EXPORT ClassInfo {
|
|||||||
|
|
||||||
struct PIP_EXPORT EnumeratorInfo {
|
struct PIP_EXPORT EnumeratorInfo {
|
||||||
EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
|
EnumeratorInfo(const PIString & n = PIString(), int v = 0) {name = n; value = v;}
|
||||||
|
PIVariantTypes::Enumerator toPIVariantEnumerator() {return PIVariantTypes::Enumerator(value, name);}
|
||||||
MetaMap meta;
|
MetaMap meta;
|
||||||
PIString name;
|
PIString name;
|
||||||
int value;
|
int value;
|
||||||
@@ -85,6 +88,7 @@ struct PIP_EXPORT EnumeratorInfo {
|
|||||||
struct PIP_EXPORT EnumInfo {
|
struct PIP_EXPORT EnumInfo {
|
||||||
PIString memberName(int value) const;
|
PIString memberName(int value) const;
|
||||||
int memberValue(const PIString & name) const;
|
int memberValue(const PIString & name) const;
|
||||||
|
PIVariantTypes::Enum toPIVariantEnum();
|
||||||
MetaMap meta;
|
MetaMap meta;
|
||||||
PIString name;
|
PIString name;
|
||||||
PIVector<PICodeInfo::EnumeratorInfo> members;
|
PIVector<PICodeInfo::EnumeratorInfo> members;
|
||||||
|
|||||||
@@ -190,10 +190,39 @@ void PICodeParser::clear() {
|
|||||||
piForeachC (PIString & d, defs)
|
piForeachC (PIString & d, defs)
|
||||||
defines << Define(d, "");
|
defines << Define(d, "");
|
||||||
defines << Define(PIStringAscii("PICODE"), "") << custom_defines;
|
defines << Define(PIStringAscii("PICODE"), "") << custom_defines;
|
||||||
|
macros << Macro(PIStringAscii("PIOBJECT"), "", PIStringList() << "name")
|
||||||
|
<< Macro(PIStringAscii("PIOBJECT_PARENT"), "", PIStringList() << "parent")
|
||||||
|
<< Macro(PIStringAscii("PIOBJECT_SUBCLASS"), "", PIStringList() << "name" << "parent")
|
||||||
|
<< Macro(PIStringAscii("PIIODEVICE"), "", PIStringList() << "name")
|
||||||
|
<< Macro(PIStringAscii("NO_COPY_CLASS"), "", PIStringList() << "name")
|
||||||
|
<< Macro(PIStringAscii("PRIVATE_DECLARATION"))
|
||||||
|
|
||||||
|
<< Macro(PIStringAscii("EVENT" ), "void name();", PIStringList() << "name")
|
||||||
|
<< Macro(PIStringAscii("EVENT0"), "void name();", PIStringList() << "name")
|
||||||
|
<< Macro(PIStringAscii("EVENT1"), "void name(a0 n0);", PIStringList() << "name" << "a0" << "n0")
|
||||||
|
<< Macro(PIStringAscii("EVENT2"), "void name(a0 n0, a1 n1);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1")
|
||||||
|
<< Macro(PIStringAscii("EVENT3"), "void name(a0 n0, a1 n1, a2 n2);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||||
|
<< Macro(PIStringAscii("EVENT4"), "void name(a0 n0, a1 n1, a2 n2, a3 n3);", PIStringList() << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||||
|
|
||||||
|
<< Macro(PIStringAscii("EVENT_HANDLER" ), "ret name()", PIStringList() << "ret" << "name")
|
||||||
|
<< Macro(PIStringAscii("EVENT_HANDLER0"), "ret name()", PIStringList() << "ret" << "name")
|
||||||
|
<< Macro(PIStringAscii("EVENT_HANDLER1"), "ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0")
|
||||||
|
<< Macro(PIStringAscii("EVENT_HANDLER2"), "ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1")
|
||||||
|
<< Macro(PIStringAscii("EVENT_HANDLER3"), "ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||||
|
<< Macro(PIStringAscii("EVENT_HANDLER4"), "ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||||
|
|
||||||
|
<< Macro(PIStringAscii("EVENT_VHANDLER" ), "virtual ret name()", PIStringList() << "ret" << "name")
|
||||||
|
<< Macro(PIStringAscii("EVENT_VHANDLER0"), "virtual ret name()", PIStringList() << "ret" << "name")
|
||||||
|
<< Macro(PIStringAscii("EVENT_VHANDLER1"), "virtual ret name(a0 n0)", PIStringList() << "ret" << "name" << "a0" << "n0")
|
||||||
|
<< Macro(PIStringAscii("EVENT_VHANDLER2"), "virtual ret name(a0 n0, a1 n1)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1")
|
||||||
|
<< Macro(PIStringAscii("EVENT_VHANDLER3"), "virtual ret name(a0 n0, a1 n1, a2 n2)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2")
|
||||||
|
<< Macro(PIStringAscii("EVENT_VHANDLER4"), "virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)", PIStringList() << "ret" << "name" << "a0" << "n0" << "a1" << "n1" << "a2" << "n2" << "a3" << "n3")
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
||||||
|
static const PIString s_ns = PIStringAscii("::");
|
||||||
static const PIString s_bo = PIStringAscii("{\n");
|
static const PIString s_bo = PIStringAscii("{\n");
|
||||||
static const PIString s_bc = PIStringAscii("\n}\n");
|
static const PIString s_bc = PIStringAscii("\n}\n");
|
||||||
static const PIString s_class = PIStringAscii("class");
|
static const PIString s_class = PIStringAscii("class");
|
||||||
@@ -280,7 +309,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
|||||||
|
|
||||||
replaceMeta(pfc);
|
replaceMeta(pfc);
|
||||||
|
|
||||||
//piCout << NewLine << "file" << cur_file << pfc;
|
//piCout << PICoutManipulators::NewLine << "file" << cur_file << pfc;
|
||||||
int pl = -1;
|
int pl = -1;
|
||||||
while (!pfc.isEmpty()) {
|
while (!pfc.isEmpty()) {
|
||||||
pfc.trim();
|
pfc.trim();
|
||||||
@@ -288,7 +317,12 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) {
|
|||||||
if (pl == nl) break;
|
if (pl == nl) break;
|
||||||
pl = nl;
|
pl = nl;
|
||||||
if (pfc.left(9) == s_namespace) {
|
if (pfc.left(9) == s_namespace) {
|
||||||
pfc.cutLeft(pfc.find('{') + 1);
|
pfc.cutLeft(9);
|
||||||
|
PIString prev_namespace = cur_namespace, ccmn;
|
||||||
|
cur_namespace += pfc.takeCWord() + s_ns;
|
||||||
|
ccmn = pfc.takeRange('{', '}');
|
||||||
|
parseClass(0, ccmn);
|
||||||
|
cur_namespace = prev_namespace;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (pfc.left(8) == s_template) {
|
if (pfc.left(8) == s_template) {
|
||||||
@@ -417,7 +451,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) {
|
|||||||
int ps = -1;
|
int ps = -1;
|
||||||
bool def = false;
|
bool def = false;
|
||||||
PIString prev_namespace = cur_namespace, stmp;
|
PIString prev_namespace = cur_namespace, stmp;
|
||||||
cur_namespace = ce->name + s_ns;
|
cur_namespace += ce->name + s_ns;
|
||||||
//piCout << "parse class" << ce->name << "namespace" << cur_namespace;
|
//piCout << "parse class" << ce->name << "namespace" << cur_namespace;
|
||||||
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
|
//piCout << "\nparse class" << ce->name << "namespace" << cur_namespace;
|
||||||
while (!fc.isEmpty()) {
|
while (!fc.isEmpty()) {
|
||||||
@@ -1052,10 +1086,10 @@ PIString PICodeParser::procMacros(PIString fc) {
|
|||||||
|
|
||||||
|
|
||||||
bool PICodeParser::parseDirective(PIString d) {
|
bool PICodeParser::parseDirective(PIString d) {
|
||||||
static const PIString s_include = PIStringAscii("include");
|
static const PIString s_include = PIStringAscii("include");
|
||||||
static const PIString s_define = PIStringAscii("define");
|
static const PIString s_define = PIStringAscii("define");
|
||||||
static const PIString s_undef = PIStringAscii("undef");
|
static const PIString s_undef = PIStringAscii("undef");
|
||||||
static const PIString s_PIMETA = PIStringAscii("PIMETA");
|
static const PIString s_PIMETA = PIStringAscii("PIMETA");
|
||||||
if (d.isEmpty()) return true;
|
if (d.isEmpty()) return true;
|
||||||
PIString dname = d.takeCWord();
|
PIString dname = d.takeCWord();
|
||||||
//piCout << "parseDirective" << d;
|
//piCout << "parseDirective" << d;
|
||||||
@@ -1074,9 +1108,19 @@ bool PICodeParser::parseDirective(PIString d) {
|
|||||||
if (mname == s_PIMETA) return true;
|
if (mname == s_PIMETA) return true;
|
||||||
if (d.left(1) == PIChar('(')) { // macro
|
if (d.left(1) == PIChar('(')) { // macro
|
||||||
PIStringList args = d.takeRange('(', ')').split(',').trim();
|
PIStringList args = d.takeRange('(', ')').split(',').trim();
|
||||||
|
for (int i = 0; i < macros.size_s(); ++i)
|
||||||
|
if (macros[i].name == mname) {
|
||||||
|
macros.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
macros << Macro(mname, d.trim(), args);
|
macros << Macro(mname, d.trim(), args);
|
||||||
} else { // define
|
} else { // define
|
||||||
d.trim();
|
d.trim();
|
||||||
|
for (int i = 0; i < defines.size_s(); ++i)
|
||||||
|
if (defines[i].first == mname) {
|
||||||
|
defines.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
defines << Define(mname, d);
|
defines << Define(mname, d);
|
||||||
evaluator.setVariable(mname, complexd_1);
|
evaluator.setVariable(mname, complexd_1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
# include <termios.h>
|
# include <termios.h>
|
||||||
#else
|
#else
|
||||||
|
# include <wingdi.h>
|
||||||
# include <wincon.h>
|
# include <wincon.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
|
|
||||||
#define WAIT_FOR_EXIT while (!PIKbdListener::exiting) piMSleep(PIP_MIN_MSLEEP*5);
|
#define WAIT_FOR_EXIT while (!PIKbdListener::exiting) piMSleep(PIP_MIN_MSLEEP*5); // TODO: rewrite with condvar
|
||||||
|
|
||||||
|
|
||||||
class PIP_EXPORT PIKbdListener: public PIThread
|
class PIP_EXPORT PIKbdListener: public PIThread
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
resize(pid_size, f);
|
resize(pid_size, f);
|
||||||
}
|
}
|
||||||
inline PIDeque(size_t piv_size, std::function<T(size_t)> f): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
inline PIDeque(size_t piv_size, std::function<T(size_t i)> f): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
resize(piv_size, f);
|
resize(piv_size, f);
|
||||||
}
|
}
|
||||||
@@ -174,6 +174,20 @@ public:
|
|||||||
inline size_t capacity() const {return pid_rsize;}
|
inline size_t capacity() const {return pid_rsize;}
|
||||||
inline size_t _start() const {return pid_start;}
|
inline size_t _start() const {return pid_start;}
|
||||||
inline bool isEmpty() const {return (pid_size == 0);}
|
inline bool isEmpty() const {return (pid_size == 0);}
|
||||||
|
inline bool isNotEmpty() const {return (pid_size > 0);}
|
||||||
|
inline bool any(std::function<bool(const T & e)> test) const {
|
||||||
|
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (test(pid_data[i])) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool every(std::function<bool(const T & e)> test) const {
|
||||||
|
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (!test(pid_data[i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline T & operator [](size_t index) {return pid_data[pid_start + index];}
|
inline T & operator [](size_t index) {return pid_data[pid_start + index];}
|
||||||
inline const T & operator [](size_t index) const {return pid_data[pid_start + index];}
|
inline const T & operator [](size_t index) const {return pid_data[pid_start + index];}
|
||||||
@@ -182,48 +196,102 @@ public:
|
|||||||
inline const T & back() const {return pid_data[pid_start + pid_size - 1];}
|
inline const T & back() const {return pid_data[pid_start + pid_size - 1];}
|
||||||
inline T & front() {return pid_data[pid_start];}
|
inline T & front() {return pid_data[pid_start];}
|
||||||
inline const T & front() const {return pid_data[pid_start];}
|
inline const T & front() const {return pid_data[pid_start];}
|
||||||
inline bool operator ==(const PIDeque<T> & t) const {
|
inline bool operator ==(const PIDeque<T> & v) const {
|
||||||
if (pid_size != t.pid_size) return false;
|
if (pid_size != v.pid_size) return false;
|
||||||
for (size_t i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
if (t[i] != (*this)[i])
|
if (v[i] != (*this)[i]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inline bool operator !=(const PIDeque<T> & t) const {return !(*this == t);}
|
inline bool operator !=(const PIDeque<T> & v) const {return !(*this == v);}
|
||||||
inline bool operator >(const PIDeque<T> & t) const {
|
inline bool operator <(const PIDeque<T> & v) const {
|
||||||
if (pid_size != t.pid_size) return pid_size > t.pid_size;
|
if (pid_size != v.pid_size) return pid_size < v.pid_size;
|
||||||
for (size_t i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
if (t[i] != (*this)[i]) return t[i] > (*this)[i];
|
if ((*this)[i] != v[i]) return (*this)[i] < v[i];
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool contains(const T & v) const {
|
inline bool operator >(const PIDeque<T> & v) const {
|
||||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i)
|
if (pid_size != v.pid_size) return pid_size > v.pid_size;
|
||||||
if (v == pid_data[i])
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
|
if ((*this)[i] != v[i]) return (*this)[i] > v[i];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool contains(const T & e) const {
|
||||||
|
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (e == pid_data[i]) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline int etries(const T & v) const {
|
inline int etries(const T & e, size_t start = 0) const {
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i)
|
if (start >= pid_size) return ec;
|
||||||
if (v == pid_data[i]) ++ec;
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (e == pid_data[i]) ++ec;
|
||||||
|
}
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
inline ssize_t indexOf(const T & v) const {
|
inline int etries(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
for (ssize_t i = pid_start; i < pid_start + (ssize_t)pid_size; ++i)
|
int ec = 0;
|
||||||
if (v == pid_data[i])
|
if (start >= pid_size) return ec;
|
||||||
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (test(pid_data[i])) ++ec;
|
||||||
|
}
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
inline ssize_t indexOf(const T & e, size_t start = 0) const {
|
||||||
|
if (start >= pid_size) return -1;
|
||||||
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (e == pid_data[i]) {
|
||||||
return i - pid_start;
|
return i - pid_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
inline ssize_t lastIndexOf(const T & v) const {
|
inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
for (ssize_t i = pid_start + (ssize_t)pid_size - 1; i >= pid_start; --i)
|
if (start >= pid_size) return -1;
|
||||||
if (v == pid_data[i])
|
for (ssize_t i = pid_start + start; i < pid_start + (ssize_t)pid_size; ++i) {
|
||||||
|
if (test(pid_data[i])) {
|
||||||
return i - pid_start;
|
return i - pid_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
|
if (start < 0) start = pid_size - 1;
|
||||||
|
else start = piMin<ssize_t>(pid_size - 1, start);
|
||||||
|
for (ssize_t i = pid_start + start; i >= pid_start; --i) {
|
||||||
|
if (e == pid_data[i]) {
|
||||||
|
return i - pid_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
|
if (start < 0) start = pid_size - 1;
|
||||||
|
else start = piMin<ssize_t>(pid_size - 1, start);
|
||||||
|
for (ssize_t i = pid_start + start; i >= pid_start; --i) {
|
||||||
|
if (test(pid_data[i])) {
|
||||||
|
return i - pid_start;
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);}
|
inline T * data(size_t index = 0) {return &(pid_data[pid_start + index]);}
|
||||||
inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);}
|
inline const T * data(size_t index = 0) const {return &(pid_data[pid_start + index]);}
|
||||||
|
|
||||||
|
PIDeque<T> getRange(size_t index, size_t count) const {
|
||||||
|
if (index >= pid_size || count == 0) return PIDeque<T>();
|
||||||
|
if (index + count > pid_size) count = pid_size - index;
|
||||||
|
return PIDeque(&(pid_data[pid_start + index]), count);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
!std::is_trivially_copyable<T1>::value
|
!std::is_trivially_copyable<T1>::value
|
||||||
, int>::type = 0>
|
, int>::type = 0>
|
||||||
@@ -244,15 +312,17 @@ public:
|
|||||||
inline PIDeque<T> & fill(const T & f = T()) {
|
inline PIDeque<T> & fill(const T & f = T()) {
|
||||||
deleteT(pid_data + pid_start, pid_size);
|
deleteT(pid_data + pid_start, pid_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, pid_size)
|
PIINTROSPECTION_CONTAINER_USED(T, pid_size)
|
||||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i)
|
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||||
elementNew(pid_data + i, f);
|
elementNew(pid_data + i, f);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & fill(std::function<T(size_t)> f) {
|
inline PIDeque<T> & fill(std::function<T(size_t i)> f) {
|
||||||
deleteT(pid_data + pid_start, pid_size);
|
deleteT(pid_data + pid_start, pid_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, pid_size)
|
PIINTROSPECTION_CONTAINER_USED(T, pid_size)
|
||||||
for (size_t i = pid_start; i < pid_start + pid_size; ++i)
|
for (size_t i = pid_start; i < pid_start + pid_size; ++i) {
|
||||||
elementNew(pid_data + i, f(i));
|
elementNew(pid_data + i, f(i));
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & assign(const T & f = T()) {return fill(f);}
|
inline PIDeque<T> & assign(const T & f = T()) {return fill(f);}
|
||||||
@@ -275,31 +345,35 @@ public:
|
|||||||
if (new_size < pid_size) {
|
if (new_size < pid_size) {
|
||||||
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
|
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
|
||||||
pid_size = new_size;
|
pid_size = new_size;
|
||||||
if (new_size == 0)
|
if (new_size == 0) {
|
||||||
pid_start = (pid_rsize - pid_size) / 2;
|
pid_start = (pid_rsize - pid_size) / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (new_size > pid_size) {
|
if (new_size > pid_size) {
|
||||||
size_t os = pid_size;
|
size_t os = pid_size;
|
||||||
alloc(new_size, true);
|
alloc(new_size, true);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||||
for (size_t i = os + pid_start; i < new_size + pid_start; ++i)
|
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
||||||
elementNew(pid_data + i, f);
|
elementNew(pid_data + i, f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & resize(size_t new_size, std::function<T(size_t)> f) {
|
inline PIDeque<T> & resize(size_t new_size, std::function<T(size_t i)> f) {
|
||||||
if (new_size < pid_size) {
|
if (new_size < pid_size) {
|
||||||
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
|
deleteT(&(pid_data[new_size + pid_start]), pid_size - new_size);
|
||||||
pid_size = new_size;
|
pid_size = new_size;
|
||||||
if (new_size == 0)
|
if (new_size == 0) {
|
||||||
pid_start = (pid_rsize - pid_size) / 2;
|
pid_start = (pid_rsize - pid_size) / 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (new_size > pid_size) {
|
if (new_size > pid_size) {
|
||||||
size_t os = pid_size;
|
size_t os = pid_size;
|
||||||
alloc(new_size, true);
|
alloc(new_size, true);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||||
for (size_t i = os + pid_start; i < new_size + pid_start; ++i)
|
for (size_t i = os + pid_start; i < new_size + pid_start; ++i) {
|
||||||
elementNew(pid_data + i, f(i));
|
elementNew(pid_data + i, f(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -326,8 +400,8 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIDeque<T> & insert(size_t index, const T & v = T()) {
|
inline PIDeque<T> & insert(size_t index, const T & e = T()) {
|
||||||
if (index == pid_size) return push_back(v);
|
if (index == pid_size) return push_back(e);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||||
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
@@ -338,14 +412,15 @@ public:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alloc(pid_size + 1, false, -1);
|
alloc(pid_size + 1, false, -1);
|
||||||
if (index > 0)
|
if (index > 0) {
|
||||||
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elementNew(pid_data + pid_start + index, v);
|
elementNew(pid_data + pid_start + index, e);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & insert(size_t index, T && v) {
|
inline PIDeque<T> & insert(size_t index, T && e) {
|
||||||
if (index == pid_size) return push_back(v);
|
if (index == pid_size) return push_back(e);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||||
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
@@ -356,10 +431,11 @@ public:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
alloc(pid_size + 1, false, -1);
|
alloc(pid_size + 1, false, -1);
|
||||||
if (index > 0)
|
if (index > 0) {
|
||||||
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
elementNew(pid_data + pid_start + index, std::move(v));
|
elementNew(pid_data + pid_start + index, std::move(e));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & insert(size_t index, const PIDeque<T> & other) {
|
inline PIDeque<T> & insert(size_t index, const PIDeque<T> & other) {
|
||||||
@@ -369,12 +445,14 @@ public:
|
|||||||
if (dir) {
|
if (dir) {
|
||||||
ssize_t os = pid_size - index;
|
ssize_t os = pid_size - index;
|
||||||
alloc(pid_size + other.pid_size, true);
|
alloc(pid_size + other.pid_size, true);
|
||||||
if (os > 0)
|
if (os > 0) {
|
||||||
memmove((void*)(&(pid_data[index + pid_start + other.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
memmove((void*)(&(pid_data[index + pid_start + other.pid_size])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
alloc(pid_size + other.pid_size, false, -other.pid_size);
|
alloc(pid_size + other.pid_size, false, -other.pid_size);
|
||||||
if (index > 0)
|
if (index > 0) {
|
||||||
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + other.pid_size])), index * sizeof(T));
|
memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + other.pid_size])), index * sizeof(T));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
newT(pid_data + pid_start + index, other.pid_data + other.pid_start, other.pid_size);
|
newT(pid_data + pid_start + index, other.pid_data + other.pid_start, other.pid_size);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -389,9 +467,13 @@ public:
|
|||||||
size_t os = pid_size - index - count;
|
size_t os = pid_size - index - count;
|
||||||
deleteT(&(pid_data[index + pid_start]), count);
|
deleteT(&(pid_data[index + pid_start]), count);
|
||||||
if (os <= index) {
|
if (os <= index) {
|
||||||
if (os > 0) memmove((void*)(&(pid_data[index + pid_start])), (const void*)(&(pid_data[index + pid_start + count])), os * sizeof(T));
|
if (os > 0) {
|
||||||
|
memmove((void*)(&(pid_data[index + pid_start])), (const void*)(&(pid_data[index + pid_start + count])), os * sizeof(T));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (index > 0) memmove((void*)(&(pid_data[pid_start + count])), (const void*)(&(pid_data[pid_start])), index * sizeof(T));
|
if (index > 0) {
|
||||||
|
memmove((void*)(&(pid_data[pid_start + count])), (const void*)(&(pid_data[pid_start])), index * sizeof(T));
|
||||||
|
}
|
||||||
pid_start += count;
|
pid_start += count;
|
||||||
}
|
}
|
||||||
pid_size -= count;
|
pid_size -= count;
|
||||||
@@ -419,88 +501,114 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIDeque<T> & removeOne(const T & v) {
|
inline PIDeque<T> & removeOne(const T & e) {
|
||||||
for (size_t i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
if (pid_data[i + pid_start] == v) {
|
if (pid_data[i + pid_start] == e) {
|
||||||
remove(i);
|
remove(i);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & removeAll(const T & v) {
|
inline PIDeque<T> & removeAll(const T & e) {
|
||||||
for (ssize_t i = 0; i < ssize_t(pid_size); ++i)
|
for (ssize_t i = 0; i < ssize_t(pid_size); ++i) {
|
||||||
if (pid_data[i + pid_start] == v) {
|
if (pid_data[i + pid_start] == e) {
|
||||||
remove(i);
|
remove(i);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline PIDeque<T> & removeWhere(std::function<bool(const T & e)> test) {
|
||||||
|
for (ssize_t i = 0; i < ssize_t(pid_size); ++i) {
|
||||||
|
if (test(pid_data[i + pid_start])) {
|
||||||
|
remove(i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIDeque<T> & push_back(const T & v) {
|
inline PIDeque<T> & push_back(const T & e) {
|
||||||
alloc(pid_size + 1, true);
|
alloc(pid_size + 1, true);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
||||||
elementNew(pid_data + pid_start + pid_size - 1, v);
|
elementNew(pid_data + pid_start + pid_size - 1, e);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & push_back(T && v) {
|
inline PIDeque<T> & push_back(T && e) {
|
||||||
alloc(pid_size + 1, true);
|
alloc(pid_size + 1, true);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
||||||
elementNew(pid_data + pid_start + pid_size - 1, std::move(v));
|
elementNew(pid_data + pid_start + pid_size - 1, std::move(e));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & append(const T & v) {return push_back(v);}
|
inline PIDeque<T> & append(const T & e) {return push_back(e);}
|
||||||
inline PIDeque<T> & append(T && v) {return push_back(std::move(v));}
|
inline PIDeque<T> & append(T && e) {return push_back(std::move(e));}
|
||||||
inline PIDeque<T> & append(const PIDeque<T> & t) {
|
inline PIDeque<T> & append(const PIDeque<T> & v) {
|
||||||
assert(&t != this);
|
assert(&v != this);
|
||||||
size_t ps = pid_size;
|
size_t ps = pid_size;
|
||||||
alloc(pid_size + t.pid_size, true);
|
alloc(pid_size + v.pid_size, true);
|
||||||
newT(pid_data + ps + pid_start, t.pid_data + t.pid_start, t.pid_size);
|
newT(pid_data + ps + pid_start, v.pid_data + v.pid_start, v.pid_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIDeque<T> & operator <<(const T & v) {return push_back(v);}
|
inline PIDeque<T> & operator <<(const T & e) {return push_back(e);}
|
||||||
inline PIDeque<T> & operator <<(T && v) {return push_back(std::move(v));}
|
inline PIDeque<T> & operator <<(T && e) {return push_back(std::move(e));}
|
||||||
inline PIDeque<T> & operator <<(const PIDeque<T> & t) {return append(t);}
|
inline PIDeque<T> & operator <<(const PIDeque<T> & v) {return append(v);}
|
||||||
|
|
||||||
inline PIDeque<T> & push_front(const T & v) {insert(0, v); return *this;}
|
inline PIDeque<T> & push_front(const T & e) {insert(0, e); return *this;}
|
||||||
inline PIDeque<T> & push_front(T && v) {insert(0, std::move(v)); return *this;}
|
inline PIDeque<T> & push_front(T && e) {insert(0, std::move(e)); return *this;}
|
||||||
inline PIDeque<T> & prepend(const T & v) {return push_front(v);}
|
inline PIDeque<T> & prepend(const T & e) {return push_front(e);}
|
||||||
inline PIDeque<T> & prepend(T && v) {return push_front(std::move(v));}
|
inline PIDeque<T> & prepend(T && e) {return push_front(std::move(e));}
|
||||||
|
|
||||||
inline PIDeque<T> & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;}
|
inline PIDeque<T> & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;}
|
||||||
inline PIDeque<T> & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;}
|
inline PIDeque<T> & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;}
|
||||||
|
|
||||||
inline T take_back() {T t(back()); pop_back(); return t;}
|
inline T take_back() {T e(back()); pop_back(); return e;}
|
||||||
inline T take_front() {T t(front()); pop_front(); return t;}
|
inline T take_front() {T e(front()); pop_front(); return e;}
|
||||||
|
|
||||||
template <typename ST>
|
template <typename ST>
|
||||||
PIDeque<ST> toType() const {
|
PIDeque<ST> toType() const {
|
||||||
PIDeque<ST> ret(pid_size);
|
PIDeque<ST> ret(pid_size);
|
||||||
for (uint i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
ret[i] = ST(pid_data[i + pid_start]);
|
ret[i] = ST(pid_data[i + pid_start]);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PIDeque<T> & forEach(std::function<void(const T &)> f) const {
|
const PIDeque<T> & forEach(std::function<void(const T & e)> f) const {
|
||||||
for (uint i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
f(pid_data[i + pid_start]);
|
f(pid_data[i + pid_start]);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PIDeque<T> copyForEach(std::function<T(const T &)> f) const {
|
PIDeque<T> copyForEach(std::function<T(const T & e)> f) const {
|
||||||
PIDeque<T> ret; ret.reserve(pid_size);
|
PIDeque<T> ret; ret.reserve(pid_size);
|
||||||
for (uint i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
ret << f(pid_data[i + pid_start]);
|
ret << f(pid_data[i + pid_start]);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
PIDeque<T> & forEachInplace(std::function<T(const T &)> f) {
|
PIDeque<T> & forEachInplace(std::function<T(const T & e)> f) {
|
||||||
for (uint i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i)
|
||||||
pid_data[i + pid_start] = f(pid_data[i + pid_start]);
|
pid_data[i + pid_start] = f(pid_data[i + pid_start]);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
template <typename ST>
|
template <typename ST>
|
||||||
PIDeque<ST> toType(std::function<ST(const T &)> f) const {
|
PIDeque<ST> map(std::function<ST(const T & e)> f) const {
|
||||||
PIDeque<ST> ret; ret.reserve(pid_size);
|
PIDeque<ST> ret; ret.reserve(pid_size);
|
||||||
for (uint i = 0; i < pid_size; ++i)
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
ret << f(pid_data[i + pid_start]);
|
ret << f(pid_data[i + pid_start]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <typename ST>
|
||||||
|
PIDeque<ST> toType(std::function<ST(const T & e)> f) const {return map(f);}
|
||||||
|
|
||||||
|
template <typename ST>
|
||||||
|
ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||||
|
ST ret(initial);
|
||||||
|
for (size_t i = 0; i < pid_size; ++i) {
|
||||||
|
ret = f(pid_data[i + pid_start], ret);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,14 +618,16 @@ public:
|
|||||||
assert(rows*cols == pid_size);
|
assert(rows*cols == pid_size);
|
||||||
ret.resize(rows);
|
ret.resize(rows);
|
||||||
if (order == byRow) {
|
if (order == byRow) {
|
||||||
for (size_t r = 0; r < rows; r++)
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret[r] = PIDeque<T>(&(pid_data[r*cols]), cols);
|
ret[r] = PIDeque<T>(&(pid_data[r*cols]), cols);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (order == byColumn) {
|
if (order == byColumn) {
|
||||||
for (size_t r = 0; r < rows; r++) {
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret[r].resize(cols);
|
ret[r].resize(cols);
|
||||||
for (size_t c = 0; c < cols; c++)
|
for (size_t c = 0; c < cols; c++) {
|
||||||
ret[r][c] = pid_data[c*rows + r];
|
ret[r][c] = pid_data[c*rows + r];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -533,13 +643,16 @@ public:
|
|||||||
size_t cols = at(0).size();
|
size_t cols = at(0).size();
|
||||||
ret.reserve(rows * cols);
|
ret.reserve(rows * cols);
|
||||||
if (order == byRow) {
|
if (order == byRow) {
|
||||||
for (size_t r = 0; r < rows; r++)
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret.append(at(r));
|
ret.append(at(r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (order == byColumn) {
|
if (order == byColumn) {
|
||||||
for (size_t c = 0; c < cols; c++)
|
for (size_t c = 0; c < cols; c++) {
|
||||||
for (size_t r = 0; r < rows; r++)
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret << at(r)[c];
|
ret << at(r)[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret.resize(rows * cols);
|
ret.resize(rows * cols);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -549,11 +662,13 @@ private:
|
|||||||
inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;}
|
inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;}
|
||||||
inline size_t asize(ssize_t s) {
|
inline size_t asize(ssize_t s) {
|
||||||
if (s <= 0) return 0;
|
if (s <= 0) return 0;
|
||||||
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s))
|
if (pid_rsize + pid_rsize >= size_t(s) && pid_rsize < size_t(s)) {
|
||||||
return pid_rsize + pid_rsize;
|
return pid_rsize + pid_rsize;
|
||||||
|
}
|
||||||
ssize_t t = 0, s_ = s - 1;
|
ssize_t t = 0, s_ = s - 1;
|
||||||
while (s_ >> t)
|
while (s_ >> t) {
|
||||||
++t;
|
++t;
|
||||||
|
}
|
||||||
return (1 << t);
|
return (1 << t);
|
||||||
}
|
}
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
@@ -577,8 +692,9 @@ private:
|
|||||||
inline void deleteT(T * d, size_t sz) {
|
inline void deleteT(T * d, size_t sz) {
|
||||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||||
if ((uchar*)d != 0) {
|
if ((uchar*)d != 0) {
|
||||||
for (size_t i = 0; i < sz; ++i)
|
for (size_t i = 0; i < sz; ++i) {
|
||||||
elementDelete(d[i]);
|
elementDelete(d[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
@@ -652,10 +768,11 @@ private:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
size_t as;
|
size_t as;
|
||||||
if (pid_start + start_offset < 0)
|
if (pid_start + start_offset < 0) {
|
||||||
as = asize(pid_rsize - start_offset);
|
as = asize(pid_rsize - start_offset);
|
||||||
else as = pid_rsize;
|
} else {
|
||||||
|
as = pid_rsize;
|
||||||
|
}
|
||||||
if (as > pid_rsize) {
|
if (as > pid_rsize) {
|
||||||
T * td = (T*)(malloc(as * sizeof(T)));
|
T * td = (T*)(malloc(as * sizeof(T)));
|
||||||
ssize_t ns = pid_start + as - pid_rsize;
|
ssize_t ns = pid_start + as - pid_rsize;
|
||||||
@@ -682,7 +799,15 @@ private:
|
|||||||
|
|
||||||
#ifdef PIP_STD_IOSTREAM
|
#ifdef PIP_STD_IOSTREAM
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIDeque<T> & v) {
|
||||||
|
s << "{";
|
||||||
|
for (size_t i = 0; i < v.size(); ++i) {
|
||||||
|
s << v[i];
|
||||||
|
if (i < v.size() - 1) s << ", ";
|
||||||
|
}
|
||||||
|
s << "}";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -692,8 +817,7 @@ inline PICout operator <<(PICout s, const PIDeque<T> & v) {
|
|||||||
s << "{";
|
s << "{";
|
||||||
for (size_t i = 0; i < v.size(); ++i) {
|
for (size_t i = 0; i < v.size(); ++i) {
|
||||||
s << v[i];
|
s << v[i];
|
||||||
if (i < v.size() - 1)
|
if (i < v.size() - 1) s << ", ";
|
||||||
s << ", ";
|
|
||||||
}
|
}
|
||||||
s << "}";
|
s << "}";
|
||||||
s.restoreControl();
|
s.restoreControl();
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ public:
|
|||||||
iterator(): parent(0), pos(0) {}
|
iterator(): parent(0), pos(0) {}
|
||||||
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
||||||
T & value() {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
T & value() {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
||||||
|
inline PIPair<Key, T> operator *() const {return PIPair<Key, T>(const_cast<PIMap<Key, T> * >(parent)->_key(pos), const_cast<PIMap<Key, T> * >(parent)->_value(pos));}
|
||||||
void operator ++() {++pos;}
|
void operator ++() {++pos;}
|
||||||
void operator ++(int) {++pos;}
|
void operator ++(int) {++pos;}
|
||||||
void operator --() {--pos;}
|
void operator --() {--pos;}
|
||||||
@@ -125,6 +126,7 @@ public:
|
|||||||
reverse_iterator(): parent(0), pos(0) {}
|
reverse_iterator(): parent(0), pos(0) {}
|
||||||
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
const Key & key() const {return const_cast<PIMap<Key, T> * >(parent)->_key(pos);}
|
||||||
T & value() const {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
T & value() const {return const_cast<PIMap<Key, T> * >(parent)->_value(pos);}
|
||||||
|
inline PIPair<Key, T> operator *() const {return PIPair<Key, T>(const_cast<PIMap<Key, T> * >(parent)->_key(pos), const_cast<PIMap<Key, T> * >(parent)->_value(pos));}
|
||||||
void operator ++() {--pos;}
|
void operator ++() {--pos;}
|
||||||
void operator ++(int) {--pos;}
|
void operator ++(int) {--pos;}
|
||||||
void operator --() {++pos;}
|
void operator --() {++pos;}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ template<typename Type0, typename Type1>
|
|||||||
class PIPair {
|
class PIPair {
|
||||||
public:
|
public:
|
||||||
PIPair() {first = Type0(); second = Type1();}
|
PIPair() {first = Type0(); second = Type1();}
|
||||||
|
PIPair(std::tuple<Type0, Type1> tuple) {first = std::get<0>(tuple); second = std::get<1>(tuple);}
|
||||||
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;}
|
||||||
Type0 first;
|
Type0 first;
|
||||||
Type1 second;
|
Type1 second;
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ public:
|
|||||||
alloc(size);
|
alloc(size);
|
||||||
newT(piv_data, data, piv_size);
|
newT(piv_data, data, piv_size);
|
||||||
}
|
}
|
||||||
inline PIVector(const PIVector<T> & other): piv_data(0), piv_size(0), piv_rsize(0) {
|
inline PIVector(const PIVector<T> & v): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
alloc(other.piv_size);
|
alloc(v.piv_size);
|
||||||
newT(piv_data, other.piv_data, piv_size);
|
newT(piv_data, v.piv_data, piv_size);
|
||||||
}
|
}
|
||||||
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) {
|
inline PIVector(std::initializer_list<T> init_list): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
@@ -53,13 +53,13 @@ public:
|
|||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
resize(piv_size, f);
|
resize(piv_size, f);
|
||||||
}
|
}
|
||||||
inline PIVector(size_t piv_size, std::function<T(size_t)> f): piv_data(0), piv_size(0), piv_rsize(0) {
|
inline PIVector(size_t piv_size, std::function<T(size_t i)> f): piv_data(0), piv_size(0), piv_rsize(0) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
resize(piv_size, f);
|
resize(piv_size, f);
|
||||||
}
|
}
|
||||||
inline PIVector(PIVector<T> && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) {
|
inline PIVector(PIVector<T> && v): piv_data(v.piv_data), piv_size(v.piv_size), piv_rsize(v.piv_rsize) {
|
||||||
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T))
|
||||||
other._reset();
|
v._reset();
|
||||||
}
|
}
|
||||||
inline virtual ~PIVector() {
|
inline virtual ~PIVector() {
|
||||||
PIINTROSPECTION_CONTAINER_DELETE(T)
|
PIINTROSPECTION_CONTAINER_DELETE(T)
|
||||||
@@ -69,17 +69,17 @@ public:
|
|||||||
_reset();
|
_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & operator =(const PIVector<T> & other) {
|
inline PIVector<T> & operator =(const PIVector<T> & v) {
|
||||||
if (this == &other) return *this;
|
if (this == &v) return *this;
|
||||||
clear();
|
clear();
|
||||||
deleteT(piv_data, piv_size);
|
deleteT(piv_data, piv_size);
|
||||||
alloc(other.piv_size);
|
alloc(v.piv_size);
|
||||||
newT(piv_data, other.piv_data, piv_size);
|
newT(piv_data, v.piv_data, piv_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & operator =(PIVector<T> && other) {
|
inline PIVector<T> & operator =(PIVector<T> && v) {
|
||||||
swap(other);
|
swap(v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,6 +174,19 @@ public:
|
|||||||
inline size_t length() const {return piv_size;}
|
inline size_t length() const {return piv_size;}
|
||||||
inline size_t capacity() const {return piv_rsize;}
|
inline size_t capacity() const {return piv_rsize;}
|
||||||
inline bool isEmpty() const {return (piv_size == 0);}
|
inline bool isEmpty() const {return (piv_size == 0);}
|
||||||
|
inline bool isNotEmpty() const {return (piv_size > 0);}
|
||||||
|
inline bool any(std::function<bool(const T & e)> test) const {
|
||||||
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
if (test(piv_data[i])) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool every(std::function<bool(const T & e)> test) const {
|
||||||
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
if (!test(piv_data[i])) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
inline T & operator [](size_t index) {return piv_data[index];}
|
inline T & operator [](size_t index) {return piv_data[index];}
|
||||||
inline const T & operator [](size_t index) const {return piv_data[index];}
|
inline const T & operator [](size_t index) const {return piv_data[index];}
|
||||||
@@ -183,42 +196,103 @@ public:
|
|||||||
inline T & front() {return piv_data[0];}
|
inline T & front() {return piv_data[0];}
|
||||||
inline const T & front() const {return piv_data[0];}
|
inline const T & front() const {return piv_data[0];}
|
||||||
inline bool operator ==(const PIVector<T> & t) const {
|
inline bool operator ==(const PIVector<T> & t) const {
|
||||||
if (piv_size != t.piv_size)
|
if (piv_size != t.piv_size) {
|
||||||
return false;
|
return false;
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
}
|
||||||
if (t[i] != piv_data[i])
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
if (t[i] != piv_data[i]) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
|
inline bool operator !=(const PIVector<T> & t) const {return !(*this == t);}
|
||||||
inline bool contains(const T & v) const {
|
inline bool operator <(const PIVector<T> & t) const {
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
if (piv_size != t.piv_size) return piv_size < t.piv_size;
|
||||||
if (v == piv_data[i])
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
return true;
|
if ((*this)[i] != t[i]) return (*this)[i] < t[i];
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline int etries(const T & v) const {
|
inline bool operator >(const PIVector<T> & t) const {
|
||||||
|
if (piv_size != t.piv_size) return piv_size > t.piv_size;
|
||||||
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
if ((*this)[i] != t[i]) return (*this)[i] > t[i];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline bool contains(const T & e) const {
|
||||||
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
if (e == piv_data[i]) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
inline int etries(const T & e, size_t start = 0) const {
|
||||||
int ec = 0;
|
int ec = 0;
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
if (start >= piv_size) return ec;
|
||||||
if (v == piv_data[i]) ++ec;
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
|
if (e == piv_data[i]) ++ec;
|
||||||
|
}
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
inline ssize_t indexOf(const T & v) const {
|
inline int etries(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
int ec = 0;
|
||||||
if (v == piv_data[i])
|
if (start >= piv_size) return ec;
|
||||||
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
|
if (test(piv_data[i])) ++ec;
|
||||||
|
}
|
||||||
|
return ec;
|
||||||
|
}
|
||||||
|
inline ssize_t indexOf(const T & e, size_t start = 0) const {
|
||||||
|
if (start >= piv_size) return -1;
|
||||||
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
|
if (e == piv_data[i]) {
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
inline ssize_t lastIndexOf(const T & v) const {
|
inline ssize_t indexWhere(std::function<bool(const T & e)> test, size_t start = 0) const {
|
||||||
for (ssize_t i = piv_size - 1; i >= 0; --i)
|
if (start >= piv_size) return -1;
|
||||||
if (v == piv_data[i])
|
for (size_t i = start; i < piv_size; ++i) {
|
||||||
|
if (test(piv_data[i])) {
|
||||||
return i;
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inline ssize_t lastIndexOf(const T & e, ssize_t start = -1) const {
|
||||||
|
if (start < 0) start = piv_size - 1;
|
||||||
|
else start = piMin<ssize_t>(piv_size - 1, start);
|
||||||
|
for (ssize_t i = start; i >= 0; --i) {
|
||||||
|
if (e == piv_data[i]) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
inline ssize_t lastIndexWhere(std::function<bool(const T & e)> test, ssize_t start = -1) const {
|
||||||
|
if (start < 0) start = piv_size - 1;
|
||||||
|
else start = piMin<ssize_t>(piv_size - 1, start);
|
||||||
|
for (ssize_t i = start; i >= 0; --i) {
|
||||||
|
if (test(piv_data[i])) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T * data(size_t index = 0) {return &(piv_data[index]);}
|
inline T * data(size_t index = 0) {return &(piv_data[index]);}
|
||||||
inline const T * data(size_t index = 0) const {return &(piv_data[index]);}
|
inline const T * data(size_t index = 0) const {return &(piv_data[index]);}
|
||||||
|
|
||||||
|
PIVector<T> getRange(size_t index, size_t count) const {
|
||||||
|
if (index >= piv_size || count == 0) return PIVector<T>();
|
||||||
|
if (index + count > piv_size) count = piv_size - index;
|
||||||
|
return PIVector(&(piv_data[index]), count);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
!std::is_trivially_copyable<T1>::value
|
!std::is_trivially_copyable<T1>::value
|
||||||
, int>::type = 0>
|
, int>::type = 0>
|
||||||
@@ -238,15 +312,17 @@ public:
|
|||||||
inline PIVector<T> & fill(const T & f = T()) {
|
inline PIVector<T> & fill(const T & f = T()) {
|
||||||
deleteT(piv_data, piv_size);
|
deleteT(piv_data, piv_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, piv_size)
|
PIINTROSPECTION_CONTAINER_USED(T, piv_size)
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
elementNew(piv_data + i, f);
|
elementNew(piv_data + i, f);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & fill(std::function<T(size_t)> f) {
|
inline PIVector<T> & fill(std::function<T(size_t i)> f) {
|
||||||
deleteT(piv_data, piv_size);
|
deleteT(piv_data, piv_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, piv_size)
|
PIINTROSPECTION_CONTAINER_USED(T, piv_size)
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
elementNew(piv_data + i, f(i));
|
elementNew(piv_data + i, f(i));
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
inline PIVector<T> & assign(const T & f = T()) {return fill(f);}
|
||||||
@@ -275,12 +351,13 @@ public:
|
|||||||
size_t os = piv_size;
|
size_t os = piv_size;
|
||||||
alloc(new_size);
|
alloc(new_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||||
for (size_t i = os; i < new_size; ++i)
|
for (size_t i = os; i < new_size; ++i) {
|
||||||
elementNew(piv_data + i, f);
|
elementNew(piv_data + i, f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & resize(size_t new_size, std::function<T(size_t)> f) {
|
inline PIVector<T> & resize(size_t new_size, std::function<T(size_t i)> f) {
|
||||||
if (new_size < piv_size) {
|
if (new_size < piv_size) {
|
||||||
T * de = &(piv_data[new_size]);
|
T * de = &(piv_data[new_size]);
|
||||||
deleteT(de, piv_size - new_size);
|
deleteT(de, piv_size - new_size);
|
||||||
@@ -290,8 +367,9 @@ public:
|
|||||||
size_t os = piv_size;
|
size_t os = piv_size;
|
||||||
alloc(new_size);
|
alloc(new_size);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
PIINTROSPECTION_CONTAINER_USED(T, (new_size-os))
|
||||||
for (size_t i = os; i < new_size; ++i)
|
for (size_t i = os; i < new_size; ++i) {
|
||||||
elementNew(piv_data + i, f(i));
|
elementNew(piv_data + i, f(i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -320,34 +398,35 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & insert(size_t index, const T & v = T()) {
|
inline PIVector<T> & insert(size_t index, const T & e = T()) {
|
||||||
alloc(piv_size + 1);
|
alloc(piv_size + 1);
|
||||||
if (index < piv_size - 1) {
|
if (index < piv_size - 1) {
|
||||||
size_t os = piv_size - index - 1;
|
size_t os = piv_size - index - 1;
|
||||||
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
|
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
|
||||||
}
|
}
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||||
elementNew(piv_data + index, v);
|
elementNew(piv_data + index, e);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & insert(size_t index, T && v) {
|
inline PIVector<T> & insert(size_t index, T && e) {
|
||||||
alloc(piv_size + 1);
|
alloc(piv_size + 1);
|
||||||
if (index < piv_size - 1) {
|
if (index < piv_size - 1) {
|
||||||
size_t os = piv_size - index - 1;
|
size_t os = piv_size - index - 1;
|
||||||
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
|
memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T));
|
||||||
}
|
}
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
PIINTROSPECTION_CONTAINER_USED(T, 1)
|
||||||
elementNew(piv_data + index, std::move(v));
|
elementNew(piv_data + index, std::move(e));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & insert(size_t index, const PIVector<T> & other) {
|
inline PIVector<T> & insert(size_t index, const PIVector<T> & v) {
|
||||||
if (other.isEmpty()) return *this;
|
if (v.isEmpty()) return *this;
|
||||||
assert(&other != this);
|
assert(&v != this);
|
||||||
ssize_t os = piv_size - index;
|
ssize_t os = piv_size - index;
|
||||||
alloc(piv_size + other.piv_size);
|
alloc(piv_size + v.piv_size);
|
||||||
if (os > 0)
|
if (os > 0) {
|
||||||
memmove((void*)(&(piv_data[index + other.piv_size])), (const void*)(&(piv_data[index])), os * sizeof(T));
|
memmove((void*)(&(piv_data[index + v.piv_size])), (const void*)(&(piv_data[index])), os * sizeof(T));
|
||||||
newT(piv_data + index, other.piv_data, other.piv_size);
|
}
|
||||||
|
newT(piv_data + index, v.piv_data, v.piv_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,10 +443,10 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void swap(PIVector<T> & other) {
|
inline void swap(PIVector<T> & v) {
|
||||||
piSwap<T*>(piv_data, other.piv_data);
|
piSwap<T*>(piv_data, v.piv_data);
|
||||||
piSwap<size_t>(piv_size, other.piv_size);
|
piSwap<size_t>(piv_size, v.piv_size);
|
||||||
piSwap<size_t>(piv_rsize, other.piv_rsize);
|
piSwap<size_t>(piv_rsize, v.piv_rsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*CompareFunc)(const T * , const T * );
|
typedef int (*CompareFunc)(const T * , const T * );
|
||||||
@@ -384,98 +463,126 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & removeOne(const T & v) {
|
inline PIVector<T> & removeOne(const T & e) {
|
||||||
for (size_t i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
if (piv_data[i] == v) {
|
if (piv_data[i] == e) {
|
||||||
remove(i);
|
remove(i);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & removeAll(const T & v) {
|
inline PIVector<T> & removeAll(const T & e) {
|
||||||
for (ssize_t i = 0; i < ssize_t(piv_size); ++i)
|
for (ssize_t i = 0; i < ssize_t(piv_size); ++i) {
|
||||||
if (piv_data[i] == v) {
|
if (piv_data[i] == e) {
|
||||||
remove(i);
|
remove(i);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
inline PIVector<T> & removeWhere(std::function<bool(const T & e)> test) {
|
||||||
|
for (ssize_t i = 0; i < ssize_t(piv_size); ++i) {
|
||||||
|
if (test(piv_data[i])) {
|
||||||
|
remove(i);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PIVector<T> & push_back(const T & v) {
|
inline PIVector<T> & push_back(const T & e) {
|
||||||
alloc(piv_size + 1);
|
alloc(piv_size + 1);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
||||||
elementNew(piv_data + piv_size - 1, v);
|
elementNew(piv_data + piv_size - 1, e);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & push_back(T && v) {
|
|
||||||
|
inline PIVector<T> & push_back(T && e) {
|
||||||
alloc(piv_size + 1);
|
alloc(piv_size + 1);
|
||||||
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
PIINTROSPECTION_CONTAINER_USED(T, 1);
|
||||||
elementNew(piv_data + piv_size - 1, std::move(v));
|
elementNew(piv_data + piv_size - 1, std::move(e));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & append(const T & v) {return push_back(v);}
|
|
||||||
inline PIVector<T> & append(T && v) {return push_back(std::move(v));}
|
inline PIVector<T> & append(const T & e) {return push_back(e);}
|
||||||
inline PIVector<T> & append(const PIVector<T> & other) {
|
inline PIVector<T> & append(T && e) {return push_back(std::move(e));}
|
||||||
assert(&other != this);
|
inline PIVector<T> & append(const PIVector<T> & v) {
|
||||||
|
assert(&v != this);
|
||||||
size_t ps = piv_size;
|
size_t ps = piv_size;
|
||||||
alloc(piv_size + other.piv_size);
|
alloc(piv_size + v.piv_size);
|
||||||
newT(piv_data + ps, other.piv_data, other.piv_size);
|
newT(piv_data + ps, v.piv_data, v.piv_size);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & operator <<(const T & v) {return push_back(v);}
|
inline PIVector<T> & operator <<(const T & e) {return push_back(e);}
|
||||||
inline PIVector<T> & operator <<(T && v) {return push_back(std::move(v));}
|
inline PIVector<T> & operator <<(T && e) {return push_back(std::move(e));}
|
||||||
inline PIVector<T> & operator <<(const PIVector<T> & other) {return append(other);}
|
inline PIVector<T> & operator <<(const PIVector<T> & v) {return append(v);}
|
||||||
|
|
||||||
inline PIVector<T> & push_front(const T & v) {insert(0, v); return *this;}
|
inline PIVector<T> & push_front(const T & e) {insert(0, e); return *this;}
|
||||||
inline PIVector<T> & push_front(T && v) {insert(0, std::move(v)); return *this;}
|
inline PIVector<T> & push_front(T && e) {insert(0, std::move(e)); return *this;}
|
||||||
inline PIVector<T> & prepend(const T & v) {return push_front(v);}
|
inline PIVector<T> & prepend(const T & e) {return push_front(e);}
|
||||||
inline PIVector<T> & prepend(T && v) {return push_front(std::move(v));}
|
inline PIVector<T> & prepend(T && e) {return push_front(std::move(e));}
|
||||||
|
|
||||||
inline PIVector<T> & pop_back() {
|
inline PIVector<T> & pop_back() {
|
||||||
if (piv_size == 0)
|
if (piv_size == 0) return *this;
|
||||||
return *this;
|
|
||||||
resize(piv_size - 1);
|
resize(piv_size - 1);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
inline PIVector<T> & pop_front() {
|
inline PIVector<T> & pop_front() {
|
||||||
if (piv_size == 0)
|
if (piv_size == 0) return *this;
|
||||||
return *this;
|
|
||||||
remove(0);
|
remove(0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T take_back() {T t(back()); pop_back(); return t;}
|
inline T take_back() {T e(back()); pop_back(); return e;}
|
||||||
inline T take_front() {T t(front()); pop_front(); return t;}
|
inline T take_front() {T e(front()); pop_front(); return e;}
|
||||||
|
|
||||||
template <typename ST>
|
template <typename ST>
|
||||||
PIVector<ST> toType() const {
|
PIVector<ST> toType() const {
|
||||||
PIVector<ST> ret(piv_size);
|
PIVector<ST> ret(piv_size);
|
||||||
for (uint i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
ret[i] = ST(piv_data[i]);
|
ret[i] = ST(piv_data[i]);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PIVector<T> & forEach(std::function<void(const T &)> f) const {
|
const PIVector<T> & forEach(std::function<void(const T & e)> f) const {
|
||||||
for (uint i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
f(piv_data[i]);
|
f(piv_data[i]);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
PIVector<T> copyForEach(std::function<T(const T &)> f) const {
|
PIVector<T> copyForEach(std::function<T(const T & e)> f) const {
|
||||||
PIVector<T> ret; ret.reserve(piv_size);
|
PIVector<T> ret; ret.reserve(piv_size);
|
||||||
for (uint i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
ret << f(piv_data[i]);
|
ret << f(piv_data[i]);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
PIVector<T> & forEachInplace(std::function<T(const T &)> f) {
|
PIVector<T> & forEachInplace(std::function<T(const T & e)> f) {
|
||||||
for (uint i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
piv_data[i] = f(piv_data[i]);
|
piv_data[i] = f(piv_data[i]);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ST>
|
template <typename ST>
|
||||||
PIVector<ST> toType(std::function<ST(const T &)> f) const {
|
PIVector<ST> map(std::function<ST(const T & e)> f) const {
|
||||||
PIVector<ST> ret; ret.reserve(piv_size);
|
PIVector<ST> ret; ret.reserve(piv_size);
|
||||||
for (uint i = 0; i < piv_size; ++i)
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
ret << f(piv_data[i]);
|
ret << f(piv_data[i]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
template <typename ST>
|
||||||
|
PIVector<ST> toType(std::function<ST(const T & e)> f) const {return map(f);}
|
||||||
|
|
||||||
|
template <typename ST>
|
||||||
|
ST reduce(std::function<ST(const T & e, const ST & acc)> f, const ST & initial = ST()) const {
|
||||||
|
ST ret(initial);
|
||||||
|
for (size_t i = 0; i < piv_size; ++i) {
|
||||||
|
ret = f(piv_data[i], ret);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,14 +592,16 @@ public:
|
|||||||
assert(rows*cols == piv_size);
|
assert(rows*cols == piv_size);
|
||||||
ret.resize(rows);
|
ret.resize(rows);
|
||||||
if (order == byRow) {
|
if (order == byRow) {
|
||||||
for (size_t r = 0; r < rows; r++)
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret[r] = PIVector<T>(&(piv_data[r*cols]), cols);
|
ret[r] = PIVector<T>(&(piv_data[r*cols]), cols);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (order == byColumn) {
|
if (order == byColumn) {
|
||||||
for (size_t r = 0; r < rows; r++) {
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret[r].resize(cols);
|
ret[r].resize(cols);
|
||||||
for (size_t c = 0; c < cols; c++)
|
for (size_t c = 0; c < cols; c++) {
|
||||||
ret[r][c] = piv_data[c*rows + r];
|
ret[r][c] = piv_data[c*rows + r];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
@@ -508,13 +617,16 @@ public:
|
|||||||
size_t cols = at(0).size();
|
size_t cols = at(0).size();
|
||||||
ret.reserve(rows * cols);
|
ret.reserve(rows * cols);
|
||||||
if (order == byRow) {
|
if (order == byRow) {
|
||||||
for (size_t r = 0; r < rows; r++)
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret.append(at(r));
|
ret.append(at(r));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (order == byColumn) {
|
if (order == byColumn) {
|
||||||
for (size_t c = 0; c < cols; c++)
|
for (size_t c = 0; c < cols; c++) {
|
||||||
for (size_t r = 0; r < rows; r++)
|
for (size_t r = 0; r < rows; r++) {
|
||||||
ret << at(r)[c];
|
ret << at(r)[c];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret.resize(rows * cols);
|
ret.resize(rows * cols);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -524,8 +636,9 @@ private:
|
|||||||
inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;}
|
inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;}
|
||||||
inline size_t asize(size_t s) {
|
inline size_t asize(size_t s) {
|
||||||
if (s == 0) return 0;
|
if (s == 0) return 0;
|
||||||
if (piv_rsize + piv_rsize >= s && piv_rsize < s)
|
if (piv_rsize + piv_rsize >= s && piv_rsize < s) {
|
||||||
return piv_rsize + piv_rsize;
|
return piv_rsize + piv_rsize;
|
||||||
|
}
|
||||||
ssize_t t = 0, s_ = s - 1;
|
ssize_t t = 0, s_ = s - 1;
|
||||||
while (s_ >> t) ++t;
|
while (s_ >> t) ++t;
|
||||||
return (1 << t);
|
return (1 << t);
|
||||||
@@ -551,8 +664,9 @@ private:
|
|||||||
inline void deleteT(T * d, size_t sz) {
|
inline void deleteT(T * d, size_t sz) {
|
||||||
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
PIINTROSPECTION_CONTAINER_UNUSED(T, sz)
|
||||||
if ((uchar*)d != 0) {
|
if ((uchar*)d != 0) {
|
||||||
for (size_t i = 0; i < sz; ++i)
|
for (size_t i = 0; i < sz; ++i) {
|
||||||
elementDelete(d[i]);
|
elementDelete(d[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T1 = T, typename std::enable_if<
|
template<typename T1 = T, typename std::enable_if<
|
||||||
@@ -612,7 +726,15 @@ private:
|
|||||||
|
|
||||||
#ifdef PIP_STD_IOSTREAM
|
#ifdef PIP_STD_IOSTREAM
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {s << "{"; for (size_t i = 0; i < v.size(); ++i) {s << v[i]; if (i < v.size() - 1) s << ", ";} s << "}"; return s;}
|
inline std::ostream & operator <<(std::ostream & s, const PIVector<T> & v) {
|
||||||
|
s << "{";
|
||||||
|
for (size_t i = 0; i < v.size(); ++i) {
|
||||||
|
s << v[i];
|
||||||
|
if (i < v.size() - 1) s << ", ";
|
||||||
|
}
|
||||||
|
s << "}";
|
||||||
|
return s;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@@ -622,8 +744,9 @@ inline PICout operator <<(PICout s, const PIVector<T> & v) {
|
|||||||
s << "{";
|
s << "{";
|
||||||
for (size_t i = 0; i < v.size(); ++i) {
|
for (size_t i = 0; i < v.size(); ++i) {
|
||||||
s << v[i];
|
s << v[i];
|
||||||
if (i < v.size() - 1)
|
if (i < v.size() - 1) {
|
||||||
s << ", ";
|
s << ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s << "}";
|
s << "}";
|
||||||
s.restoreControl();
|
s.restoreControl();
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
#include "pip_export.h"
|
#include "pip_export.h"
|
||||||
#include "pip_defs.h"
|
#include "pip_defs.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
|
|
||||||
//! Meta-information section for any entity.
|
//! Meta-information section for any entity.
|
||||||
//! Parsing by \a pip_cmg and can be accessed by \a PICodeInfo.
|
//! Parsing by \a pip_cmg and can be accessed by \a PICodeInfo.
|
||||||
//! Contains sequence of key=value pairs, e.g.
|
//! Contains sequence of key=value pairs, e.g.
|
||||||
@@ -118,9 +117,15 @@
|
|||||||
|
|
||||||
#endif //DOXYGEN
|
#endif //DOXYGEN
|
||||||
|
|
||||||
|
#ifdef CC_AVR_GCC
|
||||||
|
# include <ArduinoSTL.h>
|
||||||
|
#endif
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cassert>
|
||||||
|
#include <limits>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# ifdef CC_VC
|
# ifdef CC_VC
|
||||||
# define SHUT_RDWR 2
|
# define SHUT_RDWR 2
|
||||||
@@ -161,7 +166,6 @@
|
|||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
# undef NDEBUG
|
# undef NDEBUG
|
||||||
#endif
|
#endif
|
||||||
#include <cassert>
|
|
||||||
#ifndef assert
|
#ifndef assert
|
||||||
# define assert(x)
|
# define assert(x)
|
||||||
# define assertm(exp, msg)
|
# define assertm(exp, msg)
|
||||||
@@ -274,7 +278,7 @@
|
|||||||
} _PIP_ADD_COUNTER(_pip_initializer_);
|
} _PIP_ADD_COUNTER(_pip_initializer_);
|
||||||
|
|
||||||
|
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
# define PIP_MIN_MSLEEP 10.
|
# define PIP_MIN_MSLEEP 10.
|
||||||
#else
|
#else
|
||||||
# define PIP_MIN_MSLEEP 1.
|
# define PIP_MIN_MSLEEP 1.
|
||||||
@@ -285,10 +289,10 @@
|
|||||||
#define FOREVER for (;;)
|
#define FOREVER for (;;)
|
||||||
|
|
||||||
//! Macro used for infinite wait
|
//! Macro used for infinite wait
|
||||||
#define FOREVER_WAIT FOREVER msleep(PIP_MIN_MSLEEP);
|
#define FOREVER_WAIT FOREVER piMinSleep;
|
||||||
|
|
||||||
//! Macro used for infinite wait
|
//! Macro used for infinite wait
|
||||||
#define WAIT_FOREVER FOREVER msleep(PIP_MIN_MSLEEP);
|
#define WAIT_FOREVER FOREVER piMinSleep;
|
||||||
|
|
||||||
|
|
||||||
//! global variable enabling output to piCout, default is true
|
//! global variable enabling output to piCout, default is true
|
||||||
@@ -355,6 +359,17 @@ inline bool piCompareBinary(const void * f, const void * s, size_t size) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! @brief Function for compare two numeric values with epsilon
|
||||||
|
* \details Example:\n \snippet piincludes.cpp compare
|
||||||
|
* There are some macros:
|
||||||
|
* - \c piComparef for "float"
|
||||||
|
* - \c piCompared for "double"
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
inline bool piCompare(const T & a, const T & b, const T & epsilon = std::numeric_limits<T>::epsilon()) {
|
||||||
|
return piAbs(a - b) <= epsilon;
|
||||||
|
}
|
||||||
|
|
||||||
/*! @brief Templated function return round of float falue
|
/*! @brief Templated function return round of float falue
|
||||||
* \details Round is the nearest integer value \n
|
* \details Round is the nearest integer value \n
|
||||||
* There are some macros:
|
* There are some macros:
|
||||||
@@ -487,13 +502,13 @@ template<typename T> inline void piLetobe(T * v) {piLetobe(v, sizeof(T));}
|
|||||||
template<typename T> inline T piLetobe(const T & v) {T tv(v); piLetobe(&tv, sizeof(T)); return tv;}
|
template<typename T> inline T piLetobe(const T & v) {T tv(v); piLetobe(&tv, sizeof(T)); return tv;}
|
||||||
|
|
||||||
// specialization
|
// specialization
|
||||||
template<> inline ushort piLetobe(const ushort & v) {return (v << 8) | (v >> 8);}
|
template<> inline uint16_t piLetobe(const uint16_t & v) {return (v << 8) | (v >> 8);}
|
||||||
template<> inline uint piLetobe(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
template<> inline uint32_t piLetobe(const uint32_t & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);}
|
||||||
template<> inline float piLetobe(const float & v) {
|
template<> inline float piLetobe(const float & v) {
|
||||||
union _pletobe_f {
|
union _pletobe_f {
|
||||||
_pletobe_f(const float &f_) {f = f_;}
|
_pletobe_f(const float &f_) {f = f_;}
|
||||||
float f;
|
float f;
|
||||||
uint v;
|
uint32_t v;
|
||||||
};
|
};
|
||||||
_pletobe_f a(v);
|
_pletobe_f a(v);
|
||||||
a.v = (a.v >> 24) | ((a.v >> 8) & 0xFF00) | ((a.v << 8) & 0xFF0000) | ((a.v << 24) & 0xFF000000);
|
a.v = (a.v >> 24) | ((a.v >> 8) & 0xFF00) | ((a.v << 8) & 0xFF0000) | ((a.v << 24) & 0xFF000000);
|
||||||
@@ -558,6 +573,8 @@ template<> inline uint piHash(const ldouble & v) {return piHashData((const uchar
|
|||||||
|
|
||||||
#define piRoundf piRound<float>
|
#define piRoundf piRound<float>
|
||||||
#define piRoundd piRound<double>
|
#define piRoundd piRound<double>
|
||||||
|
#define piComparef piCompare<float>
|
||||||
|
#define piCompared piCompare<double>
|
||||||
#define piFloorf piFloor<float>
|
#define piFloorf piFloor<float>
|
||||||
#define piFloord piFloor<double>
|
#define piFloord piFloor<double>
|
||||||
#define piCeilf piCeil<float>
|
#define piCeilf piCeil<float>
|
||||||
|
|||||||
@@ -221,22 +221,22 @@ PIByteArray & PIByteArray::decompressRLE(uchar threshold) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uchar PIByteArray::checksumPlain8() const {
|
uchar PIByteArray::checksumPlain8(bool inverse) const {
|
||||||
uchar c = 0;
|
uchar c = 0;
|
||||||
int sz = size_s();
|
int sz = size_s();
|
||||||
for (int i = 0; i < sz; ++i)
|
for (int i = 0; i < sz; ++i)
|
||||||
c += at(i);
|
c += at(i);
|
||||||
c = ~(c + 1);
|
if (inverse) c = ~(c + 1);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint PIByteArray::checksumPlain32() const {
|
uint PIByteArray::checksumPlain32(bool inverse) const {
|
||||||
uint c = 0;
|
uint c = 0;
|
||||||
int sz = size_s();
|
int sz = size_s();
|
||||||
for (int i = 0; i < sz; ++i)
|
for (int i = 0; i < sz; ++i)
|
||||||
c += at(i) * (i + 1);
|
c += at(i) * (i + 1);
|
||||||
c = ~(c + 1);
|
if (inverse) c = ~(c + 1);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,9 @@
|
|||||||
#include "pibitarray.h"
|
#include "pibitarray.h"
|
||||||
#include "pimap.h"
|
#include "pimap.h"
|
||||||
#include "pivector2d.h"
|
#include "pivector2d.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
# define _TYPENAME_(T) "?"
|
# define _TYPENAME_(T) "?"
|
||||||
#else
|
#else
|
||||||
# define _TYPENAME_(T) typeid(T).name()
|
# define _TYPENAME_(T) typeid(T).name()
|
||||||
@@ -85,6 +86,8 @@ public:
|
|||||||
|
|
||||||
PIByteArray(const PIByteArray & o): PIDeque<uchar>(o) {}
|
PIByteArray(const PIByteArray & o): PIDeque<uchar>(o) {}
|
||||||
|
|
||||||
|
PIByteArray(const PIDeque<uchar> & o): PIDeque<uchar>(o) {}
|
||||||
|
|
||||||
PIByteArray(PIByteArray && o): PIDeque<uchar>(std::move(o)) {}
|
PIByteArray(PIByteArray && o): PIDeque<uchar>(std::move(o)) {}
|
||||||
|
|
||||||
//! Constructs 0-filled byte array with size "size"
|
//! Constructs 0-filled byte array with size "size"
|
||||||
@@ -116,6 +119,12 @@ public:
|
|||||||
//! Return resized byte array
|
//! Return resized byte array
|
||||||
PIByteArray resized(uint new_size) const {PIByteArray ret(new_size); memcpy(ret.data(), data(), new_size); return ret;}
|
PIByteArray resized(uint new_size) const {PIByteArray ret(new_size); memcpy(ret.data(), data(), new_size); return ret;}
|
||||||
|
|
||||||
|
//! Return sub-array starts from "index" and has "count" or less bytes
|
||||||
|
PIByteArray getRange(size_t index, size_t count) const {
|
||||||
|
return PIDeque<uchar>::getRange(index, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Convert data to Base 64 and return this byte array
|
//! Convert data to Base 64 and return this byte array
|
||||||
PIByteArray & convertToBase64();
|
PIByteArray & convertToBase64();
|
||||||
|
|
||||||
@@ -146,18 +155,18 @@ public:
|
|||||||
PIByteArray & append(uchar t) {push_back(t); return *this;}
|
PIByteArray & append(uchar t) {push_back(t); return *this;}
|
||||||
|
|
||||||
//! Returns 8-bit checksum
|
//! Returns 8-bit checksum
|
||||||
//! sum all bytes, add 1, inverse
|
//! sum all bytes, if inverse - add 1, inverse
|
||||||
//! Pseudocode:
|
//! Pseudocode:
|
||||||
//! sum += at(i);
|
//! sum += at(i);
|
||||||
//! return ~(sum + 1)
|
//! return ~(sum + 1)
|
||||||
uchar checksumPlain8() const;
|
uchar checksumPlain8(bool inverse = true) const;
|
||||||
|
|
||||||
//! Returns 32-bit checksum
|
//! Returns 32-bit checksum
|
||||||
//! sum all bytes multiplyed by index+1, add 1, inverse
|
//! sum all bytes multiplyed by index+1, if inverse - add 1, inverse
|
||||||
//! Pseudocode:
|
//! Pseudocode:
|
||||||
//! sum += at(i) * (i + 1);
|
//! sum += at(i) * (i + 1);
|
||||||
//! return ~(sum + 1)
|
//! return ~(sum + 1)
|
||||||
uint checksumPlain32() const;
|
uint checksumPlain32(bool inverse = true) const;
|
||||||
|
|
||||||
//! Returns hash
|
//! Returns hash
|
||||||
uint hash() const;
|
uint hash() const;
|
||||||
@@ -190,34 +199,39 @@ public:
|
|||||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||||
inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {
|
inline bool operator <(const PIByteArray & v0, const PIByteArray & v1) {
|
||||||
if (v0.size() == v1.size()) {
|
if (v0.size() == v1.size()) {
|
||||||
for (uint i = 0; i < v0.size(); ++i)
|
if (v0.isEmpty()) return false;
|
||||||
if (v0[i] != v1[i])
|
return memcmp(v0.data(), v1.data(), v0.size()) < 0;
|
||||||
return v0[i] < v1[i];
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return v0.size() < v1.size();
|
return v0.size() < v1.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||||
inline bool operator ==(PIByteArray & f, PIByteArray & s) {
|
inline bool operator >(const PIByteArray & v0, const PIByteArray & v1) {
|
||||||
if (f.size_s() != s.size_s())
|
if (v0.size() == v1.size()) {
|
||||||
return false;
|
if (v0.isEmpty()) return false;
|
||||||
for (int i = 0; i < f.size_s(); ++i)
|
return memcmp(v0.data(), v1.data(), v0.size()) > 0;
|
||||||
if (f[i] != s[i])
|
}
|
||||||
return false;
|
return v0.size() > v1.size();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||||
inline bool operator !=(PIByteArray & f, PIByteArray & s) {
|
inline bool operator ==(const PIByteArray & v0, const PIByteArray & v1) {
|
||||||
if (f.size_s() != s.size_s())
|
if (v0.size() == v1.size()) {
|
||||||
return true;
|
if (v0.isEmpty()) return true;
|
||||||
for (int i = 0; i < f.size_s(); ++i)
|
return memcmp(v0.data(), v1.data(), v0.size()) == 0;
|
||||||
if (f[i] != s[i])
|
}
|
||||||
return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \relatesalso PIByteArray @brief Byte arrays compare operator
|
||||||
|
inline bool operator !=(const PIByteArray & v0, const PIByteArray & v1) {
|
||||||
|
if (v0.size() == v1.size()) {
|
||||||
|
if (v0.isEmpty()) return false;
|
||||||
|
return memcmp(v0.data(), v1.data(), v0.size()) != 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PIP_STD_IOSTREAM
|
#ifdef PIP_STD_IOSTREAM
|
||||||
//! \relatesalso PIByteArray @brief Output to std::ostream operator
|
//! \relatesalso PIByteArray @brief Output to std::ostream operator
|
||||||
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);
|
inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "pistring_std.h"
|
#include "pistring_std.h"
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
# include <wingdi.h>
|
||||||
# include <wincon.h>
|
# include <wincon.h>
|
||||||
# define COMMON_LVB_UNDERSCORE 0x8000
|
# define COMMON_LVB_UNDERSCORE 0x8000
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,15 +26,15 @@
|
|||||||
#ifdef PIP_STD_IOSTREAM
|
#ifdef PIP_STD_IOSTREAM
|
||||||
# include <iostream>
|
# include <iostream>
|
||||||
#endif
|
#endif
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
|
|
||||||
class PIMutex;
|
class PIMutex;
|
||||||
class PIMutexLocker;
|
class PIMutexLocker;
|
||||||
class PIObject;
|
class PIObject;
|
||||||
class PIString;
|
class PIString;
|
||||||
class PIByteArray;
|
class PIByteArray;
|
||||||
|
#ifndef MICRO_PIP
|
||||||
class PIInit;
|
class PIInit;
|
||||||
|
#endif
|
||||||
class PIChar;
|
class PIChar;
|
||||||
class PICout;
|
class PICout;
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,15 @@ typedef LONG(NTAPI*PINtSetTimerResolution)(ULONG, BOOLEAN, PULONG);
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#ifdef FREERTOS
|
||||||
|
# ifdef ESP_PLATFORM
|
||||||
|
# include "freertos/FreeRTOS.h"
|
||||||
|
# include "freertos/task.h"
|
||||||
|
# endif
|
||||||
|
# ifdef ARDUINO_ARCH_STM32
|
||||||
|
# include <STM32FreeRTOS.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // PIINCLUDES_P_H
|
#endif // PIINCLUDES_P_H
|
||||||
|
|||||||
@@ -19,15 +19,15 @@
|
|||||||
|
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "piinit.h"
|
#include "piinit.h"
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
#include "pisignals.h"
|
#include "pisignals.h"
|
||||||
#include "piobject.h"
|
#include "piobject.h"
|
||||||
#include "pisysteminfo.h"
|
#include "pisysteminfo.h"
|
||||||
#include "piresourcesstorage.h"
|
#include "piresourcesstorage.h"
|
||||||
#include "pidir.h"
|
#include "pidir.h"
|
||||||
#ifndef FREERTOS
|
#include "piprocess.h"
|
||||||
# include "piprocess.h"
|
|
||||||
#endif
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
# include "esp_system.h"
|
# include "esp_system.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -49,9 +49,7 @@ void __PISetTimerResolution() {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# include <pwd.h>
|
# include <pwd.h>
|
||||||
# ifndef FREERTOS
|
# include <sys/utsname.h>
|
||||||
# include <sys/utsname.h>
|
|
||||||
# endif
|
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
# ifdef BLACKBERRY
|
# ifdef BLACKBERRY
|
||||||
# include <signal.h>
|
# include <signal.h>
|
||||||
@@ -84,7 +82,6 @@ ULONG prev_res;
|
|||||||
bool delete_locs;
|
bool delete_locs;
|
||||||
PRIVATE_DEFINITION_END(PIInit)
|
PRIVATE_DEFINITION_END(PIInit)
|
||||||
|
|
||||||
#ifndef FREERTOS
|
|
||||||
void __sighandler__(PISignals::Signal s) {
|
void __sighandler__(PISignals::Signal s) {
|
||||||
//piCout << Hex << int(s);
|
//piCout << Hex << int(s);
|
||||||
if (s == PISignals::StopTTYInput || s == PISignals::StopTTYOutput)
|
if (s == PISignals::StopTTYInput || s == PISignals::StopTTYOutput)
|
||||||
@@ -92,7 +89,6 @@ void __sighandler__(PISignals::Signal s) {
|
|||||||
if (s == PISignals::UserDefined1)
|
if (s == PISignals::UserDefined1)
|
||||||
dumpApplicationToFile(PIDir::home().path() + PIDir::separator + PIStringAscii("_PIP_DUMP_") + PIString::fromNumber(PIProcess::currentPID()));
|
dumpApplicationToFile(PIDir::home().path() + PIDir::separator + PIStringAscii("_PIP_DUMP_") + PIString::fromNumber(PIProcess::currentPID()));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
@@ -107,7 +103,6 @@ PIInit::PIInit() {
|
|||||||
PISystemInfo * sinfo = PISystemInfo::instance();
|
PISystemInfo * sinfo = PISystemInfo::instance();
|
||||||
sinfo->execDateTime = PIDateTime::current();
|
sinfo->execDateTime = PIDateTime::current();
|
||||||
setFileCharset("UTF-8");
|
setFileCharset("UTF-8");
|
||||||
#ifndef FREERTOS
|
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
PISignals::setSlot(__sighandler__);
|
PISignals::setSlot(__sighandler__);
|
||||||
PISignals::grabSignals(PISignals::UserDefined1);
|
PISignals::grabSignals(PISignals::UserDefined1);
|
||||||
@@ -128,7 +123,7 @@ PIInit::PIInit() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# else
|
# else //WINDOWS
|
||||||
// OS version
|
// OS version
|
||||||
DWORD dwVersion = GetVersion();
|
DWORD dwVersion = GetVersion();
|
||||||
DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
DWORD dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
|
||||||
@@ -154,7 +149,7 @@ PIInit::PIInit() {
|
|||||||
setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtSetTimerResolution");
|
setTimerResolutionAddr = (PINtSetTimerResolution)GetProcAddress(PRIVATE->ntlib, "NtSetTimerResolution");
|
||||||
__PISetTimerResolution();
|
__PISetTimerResolution();
|
||||||
}
|
}
|
||||||
# endif
|
# endif //WINDOWS
|
||||||
# ifdef HAS_LOCALE
|
# ifdef HAS_LOCALE
|
||||||
//cout << "has locale" << endl;
|
//cout << "has locale" << endl;
|
||||||
if (currentLocale_t != 0) {
|
if (currentLocale_t != 0) {
|
||||||
@@ -162,18 +157,18 @@ PIInit::PIInit() {
|
|||||||
currentLocale_t = 0;
|
currentLocale_t = 0;
|
||||||
}
|
}
|
||||||
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
currentLocale_t = newlocale(LC_ALL, setlocale(LC_ALL, ""), 0);
|
||||||
# else
|
# else //HAS_LOCALE
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
# endif
|
# endif //HAS_LOCALE
|
||||||
#else
|
#else //ANDROID
|
||||||
struct sigaction actions;
|
struct sigaction actions;
|
||||||
memset(&actions, 0, sizeof(actions));
|
memset(&actions, 0, sizeof(actions));
|
||||||
sigemptyset(&actions.sa_mask);
|
sigemptyset(&actions.sa_mask);
|
||||||
actions.sa_flags = 0;
|
actions.sa_flags = 0;
|
||||||
actions.sa_handler = android_thread_exit_handler;
|
actions.sa_handler = android_thread_exit_handler;
|
||||||
sigaction(SIGTERM, &actions, 0);
|
sigaction(SIGTERM, &actions, 0);
|
||||||
#endif
|
#endif //ANDROID
|
||||||
PRIVATE->delete_locs = false;
|
PRIVATE->delete_locs = false;
|
||||||
__syslocname__ = __sysoemname__ = 0;
|
__syslocname__ = __sysoemname__ = 0;
|
||||||
__utf8name__ = const_cast<char*>("UTF-8");
|
__utf8name__ = const_cast<char*>("UTF-8");
|
||||||
@@ -201,13 +196,13 @@ PIInit::PIInit() {
|
|||||||
# endif
|
# endif
|
||||||
//piCout << __syslocname__;
|
//piCout << __syslocname__;
|
||||||
//piCout << __sysoemname__;
|
//piCout << __sysoemname__;
|
||||||
#else
|
#else //PIP_ICU
|
||||||
# ifdef WINDOWS
|
# ifdef WINDOWS
|
||||||
__syslocname__ = (char *)CP_ACP;
|
__syslocname__ = (char *)CP_ACP;
|
||||||
__sysoemname__ = (char *)CP_OEMCP;
|
__sysoemname__ = (char *)CP_OEMCP;
|
||||||
__utf8name__ = (char *)CP_UTF8;
|
__utf8name__ = (char *)CP_UTF8;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif //PIP_ICU
|
||||||
#ifdef MAC_OS
|
#ifdef MAC_OS
|
||||||
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &__pi_mac_clock);
|
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &__pi_mac_clock);
|
||||||
#endif
|
#endif
|
||||||
@@ -236,7 +231,7 @@ PIInit::PIInit() {
|
|||||||
ulong unlen = 1023;
|
ulong unlen = 1023;
|
||||||
if (GetUserName(cbuff, &unlen) != 0)
|
if (GetUserName(cbuff, &unlen) != 0)
|
||||||
sinfo->user = cbuff;
|
sinfo->user = cbuff;
|
||||||
#else
|
#else //WINDOWS
|
||||||
sinfo->processorsCount = piMaxi(1, int(sysconf(_SC_NPROCESSORS_ONLN)));
|
sinfo->processorsCount = piMaxi(1, int(sysconf(_SC_NPROCESSORS_ONLN)));
|
||||||
passwd * ps = getpwuid(getuid());
|
passwd * ps = getpwuid(getuid());
|
||||||
if (ps)
|
if (ps)
|
||||||
@@ -252,8 +247,8 @@ PIInit::PIInit() {
|
|||||||
sinfo->OS_version = uns.release;
|
sinfo->OS_version = uns.release;
|
||||||
sinfo->architecture = uns.machine;
|
sinfo->architecture = uns.machine;
|
||||||
}
|
}
|
||||||
# endif
|
#endif //WINDOWS
|
||||||
#endif
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
esp_chip_info_t chip_info;
|
esp_chip_info_t chip_info;
|
||||||
esp_chip_info(&chip_info);
|
esp_chip_info(&chip_info);
|
||||||
@@ -275,6 +270,8 @@ PIInit::PIInit() {
|
|||||||
PIStringAscii("FreeBSD");
|
PIStringAscii("FreeBSD");
|
||||||
#elif defined(FREERTOS)
|
#elif defined(FREERTOS)
|
||||||
PIStringAscii("FreeRTOS");
|
PIStringAscii("FreeRTOS");
|
||||||
|
#elif defined(MICRO_PIP)
|
||||||
|
PIStringAscii("MicroPIP");
|
||||||
#else
|
#else
|
||||||
uns.sysname;
|
uns.sysname;
|
||||||
#endif
|
#endif
|
||||||
@@ -305,49 +302,49 @@ PIInit::~PIInit() {
|
|||||||
|
|
||||||
bool PIInit::isBuildOptionEnabled(PIInit::BuildOption o) {
|
bool PIInit::isBuildOptionEnabled(PIInit::BuildOption o) {
|
||||||
switch (o) {
|
switch (o) {
|
||||||
case ICU: return
|
case boICU: return
|
||||||
#ifdef PIP_ICU
|
#ifdef PIP_ICU
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case USB: return
|
case boUSB: return
|
||||||
#ifdef PIP_USB
|
#ifdef PIP_USB
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case Crypt: return
|
case boCrypt: return
|
||||||
#ifdef PIP_CRYPT
|
#ifdef PIP_CRYPT
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case Introspection: return
|
case boIntrospection: return
|
||||||
#ifdef PIP_INTROSPECTION
|
#ifdef PIP_INTROSPECTION
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case FFTW: return
|
case boFFTW: return
|
||||||
#ifdef PIP_FFTW
|
#ifdef PIP_FFTW
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case Compress: return
|
case boCompress: return
|
||||||
#ifdef PIP_COMPRESS
|
#ifdef PIP_COMPRESS
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case OpenCL: return
|
case boOpenCL: return
|
||||||
#ifdef PIP_OPENCL
|
#ifdef PIP_OPENCL
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
false;
|
false;
|
||||||
#endif
|
#endif
|
||||||
case Cloud: return
|
case boCloud: return
|
||||||
#ifdef PIP_CLOUD
|
#ifdef PIP_CLOUD
|
||||||
true;
|
true;
|
||||||
#else
|
#else
|
||||||
@@ -361,14 +358,14 @@ bool PIInit::isBuildOptionEnabled(PIInit::BuildOption o) {
|
|||||||
|
|
||||||
PIStringList PIInit::buildOptions() {
|
PIStringList PIInit::buildOptions() {
|
||||||
PIStringList ret;
|
PIStringList ret;
|
||||||
if (isBuildOptionEnabled(ICU)) ret << "ICU";
|
if (isBuildOptionEnabled(boICU)) ret << "ICU";
|
||||||
if (isBuildOptionEnabled(USB)) ret << "USB";
|
if (isBuildOptionEnabled(boUSB)) ret << "USB";
|
||||||
if (isBuildOptionEnabled(Crypt)) ret << "Crypt";
|
if (isBuildOptionEnabled(boCrypt)) ret << "Crypt";
|
||||||
if (isBuildOptionEnabled(Introspection)) ret << "Introspection";
|
if (isBuildOptionEnabled(boIntrospection)) ret << "Introspection";
|
||||||
if (isBuildOptionEnabled(FFTW)) ret << "FFTW";
|
if (isBuildOptionEnabled(boFFTW)) ret << "FFTW";
|
||||||
if (isBuildOptionEnabled(Compress)) ret << "Compress";
|
if (isBuildOptionEnabled(boCompress)) ret << "Compress";
|
||||||
if (isBuildOptionEnabled(OpenCL)) ret << "OpenCL";
|
if (isBuildOptionEnabled(boOpenCL)) ret << "OpenCL";
|
||||||
if (isBuildOptionEnabled(Cloud)) ret << "Cloud";
|
if (isBuildOptionEnabled(boCloud)) ret << "Cloud";
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,3 +412,6 @@ __PIInit_Initializer__::~__PIInit_Initializer__() {
|
|||||||
__instance__ = 0;
|
__instance__ = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // MICRO_PIP
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,10 @@
|
|||||||
#ifndef PIINIT_H
|
#ifndef PIINIT_H
|
||||||
#define PIINIT_H
|
#define PIINIT_H
|
||||||
|
|
||||||
|
#include "pibase.h"
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "piincludes.h"
|
#include "piincludes.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -49,14 +53,14 @@ public:
|
|||||||
|
|
||||||
//! @brief Build options which PIP library was built
|
//! @brief Build options which PIP library was built
|
||||||
enum BuildOption {
|
enum BuildOption {
|
||||||
ICU /*! Unicode support */ = 0x01,
|
boICU /*! Unicode support */ = 0x01,
|
||||||
USB /*! USB support */ = 0x02,
|
boUSB /*! USB support */ = 0x02,
|
||||||
Crypt /*! Crypt support */ = 0x08,
|
boCrypt /*! Crypt support */ = 0x08,
|
||||||
Introspection /*! Introspection */ = 0x010,
|
boIntrospection /*! Introspection */ = 0x010,
|
||||||
FFTW /*! FFTW3 support */ = 0x40,
|
boFFTW /*! FFTW3 support */ = 0x40,
|
||||||
Compress /*! Zlib compression support */ = 0x80,
|
boCompress /*! Zlib compression support */ = 0x80,
|
||||||
OpenCL /*! OpenCL support */ = 0x100,
|
boOpenCL /*! OpenCL support */ = 0x100,
|
||||||
Cloud /*! Cloud transport support */ = 0x200,
|
boCloud /*! Cloud transport support */ = 0x200,
|
||||||
};
|
};
|
||||||
static PIInit * instance() {return __PIInit_Initializer__::__instance__;}
|
static PIInit * instance() {return __PIInit_Initializer__::__instance__;}
|
||||||
static bool isBuildOptionEnabled(BuildOption o);
|
static bool isBuildOptionEnabled(BuildOption o);
|
||||||
@@ -70,4 +74,5 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MICRO_PIP
|
||||||
#endif // PIINIT_H
|
#endif // PIINIT_H
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "piobject.h"
|
#include "piobject.h"
|
||||||
#include "pisysteminfo.h"
|
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "piconditionvar.h"
|
#include "piconditionvar.h"
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
# include "pisysteminfo.h"
|
||||||
# include "pifile.h"
|
# include "pifile.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -91,9 +91,11 @@ PIObject::~PIObject() {
|
|||||||
mutexObjects().lock();
|
mutexObjects().lock();
|
||||||
objects().removeAll(this);
|
objects().removeAll(this);
|
||||||
mutexObjects().unlock();
|
mutexObjects().unlock();
|
||||||
piDisconnect(this);
|
deleted(this);
|
||||||
|
piDisconnectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIMap<PIString, PIVariant> PIObject::properties() const {
|
PIMap<PIString, PIVariant> PIObject::properties() const {
|
||||||
PIMap<PIString, PIVariant> ret;
|
PIMap<PIString, PIVariant> ret;
|
||||||
piForeachC (PropertyHash p, properties_)
|
piForeachC (PropertyHash p, properties_)
|
||||||
@@ -141,50 +143,6 @@ bool PIObject::executeQueued(PIObject * performer, const PIString & method, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIObject::piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h) {
|
|
||||||
PIObject * o = findByName(src);
|
|
||||||
if (o == 0) {
|
|
||||||
piCout << "[PIObject] Can`t find object with name \"" << src << "\"!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PIMutexLocker _ml(o->mutex_connect);
|
|
||||||
PIMutexLocker _mld(((PIObject*)dest)->mutex_connect, ((PIObject*)dest) != o);
|
|
||||||
o->connections << __Connection(ev_h, 0, sig, (PIObject*)dest, dest);
|
|
||||||
((PIObject*)dest)->connectors << o;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIObject::piConnect(PIObject * src, const PIString & sig, const PIString & dest, void * ev_h) {
|
|
||||||
PIObject * o = findByName(dest);
|
|
||||||
if (o == 0) {
|
|
||||||
piCout << "[PIObject] Can`t find object with name \"" << dest << "\"!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PIMutexLocker _ml(src->mutex_connect);
|
|
||||||
PIMutexLocker _mld(o->mutex_connect, src != o);
|
|
||||||
src->connections << __Connection(ev_h, 0, sig, o, o);
|
|
||||||
((PIObject*)o)->connectors << src;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIObject::piConnect(const PIString & src, const PIString & sig, const PIString & dest, void * ev_h) {
|
|
||||||
PIObject * s = findByName(src);
|
|
||||||
if (s == 0) {
|
|
||||||
piCout << "[PIObject] Can`t find object with name \"" << src << "\"!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PIObject * d = findByName(dest);
|
|
||||||
if (d == 0) {
|
|
||||||
piCout << "[PIObject] Can`t find object with name \"" << dest << "\"!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PIMutexLocker _ml(s->mutex_connect);
|
|
||||||
PIMutexLocker _mld(d->mutex_connect, s != d);
|
|
||||||
s->connections << __Connection(ev_h, 0, sig, d, d);
|
|
||||||
d->connectors << s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PIStringList PIObject::scopeList() const {
|
PIStringList PIObject::scopeList() const {
|
||||||
PIMutexLocker ml(__meta_mutex());
|
PIMutexLocker ml(__meta_mutex());
|
||||||
return __meta_data()[classNameID()].scope_list;
|
return __meta_data()[classNameID()].scope_list;
|
||||||
@@ -256,31 +214,33 @@ PIObject::__MetaFunc PIObject::methodEH(const void * addr) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIObject::piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc) {
|
PIObject::Connection PIObject::piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc) {
|
||||||
//piCout << "piConnect ...";
|
//piCout << "piConnect ...";
|
||||||
//piCout << "piConnect" << src << (void*)(dest) << sig;
|
//piCout << "piConnect" << src << (void*)(dest) << sig;
|
||||||
//piCout << "piConnect" << src->className() << "->" << ((PIObject*)dest)->className();
|
//piCout << "piConnect" << src->className() << "->" << ((PIObject*)dest)->className();
|
||||||
PIMutexLocker _ml(src->mutex_connect);
|
PIMutexLocker _ml(src->mutex_connect);
|
||||||
PIMutexLocker _mld(dest_o->mutex_connect, src != dest_o);
|
PIMutexLocker _mld(dest_o->mutex_connect, src != dest_o);
|
||||||
|
|
||||||
src->connections << __Connection(ev_h, e_h, sig, dest_o, dest, args);
|
Connection conn(ev_h, e_h, sig, src, dest_o, dest, args);
|
||||||
|
src->connections << conn;
|
||||||
//piCout << "piConnect" << ((PIObject*)dest) << sig << ((PIObject*)dest)->connectors.size_s() << "...";
|
//piCout << "piConnect" << ((PIObject*)dest) << sig << ((PIObject*)dest)->connectors.size_s() << "...";
|
||||||
//piCout << "addConnector" << dest_o << src;
|
//piCout << "addConnector" << dest_o << src;
|
||||||
dest_o->connectors << src;
|
dest_o->connectors << src;
|
||||||
//piCout << "piConnect" << ((PIObject*)dest) << sig << ((PIObject*)dest)->connectors.size_s();
|
//piCout << "piConnect" << ((PIObject*)dest) << sig << ((PIObject*)dest)->connectors.size_s();
|
||||||
//piCout << "piConnect ok";
|
//piCout << "piConnect ok";
|
||||||
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIObject::piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer) {
|
PIObject::Connection PIObject::piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer) {
|
||||||
if (src == 0 || dest_o == 0 || dest == 0) return false;
|
if (src == 0 || dest_o == 0 || dest == 0) return Connection();
|
||||||
if (!src->isPIObject()) {
|
if (!src->isPIObject()) {
|
||||||
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: source object is not PIObject! (" << loc << ")";
|
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: source object is not PIObject! (" << loc << ")";
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
if (!dest_o->isPIObject()) {
|
if (!dest_o->isPIObject()) {
|
||||||
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: destination object is not PIObject! (" << loc << ")";
|
piCout << "[piConnectU] \"" << sig << "\" -> \"" << hname << "\" error: destination object is not PIObject! (" << loc << ")";
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
PIMutexLocker ml(__meta_mutex());
|
PIMutexLocker ml(__meta_mutex());
|
||||||
PIMutexLocker mls(src->mutex_connect);
|
PIMutexLocker mls(src->mutex_connect);
|
||||||
@@ -288,11 +248,11 @@ bool PIObject::piConnectU(PIObject * src, const PIString & sig, PIObject * dest_
|
|||||||
PIVector<__MetaFunc> m_src = src->findEH(sig), m_dest = dest_o->findEH(hname);
|
PIVector<__MetaFunc> m_src = src->findEH(sig), m_dest = dest_o->findEH(hname);
|
||||||
if (m_src.isEmpty()) {
|
if (m_src.isEmpty()) {
|
||||||
piCout << "[piConnectU] Error: can`t find event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
piCout << "[piConnectU] Error: can`t find event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
if (m_dest.isEmpty()) {
|
if (m_dest.isEmpty()) {
|
||||||
piCout << "[piConnectU] Error: can`t find handler \"" << hname << "\" in class \"" << dest_o->className() << "\"! (" << loc << ")";
|
piCout << "[piConnectU] Error: can`t find handler \"" << hname << "\" in class \"" << dest_o->className() << "\"! (" << loc << ")";
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
void * addr_src(0), * addr_dest(0);
|
void * addr_src(0), * addr_dest(0);
|
||||||
int args(0);
|
int args(0);
|
||||||
@@ -311,25 +271,26 @@ bool PIObject::piConnectU(PIObject * src, const PIString & sig, PIObject * dest_
|
|||||||
if (addr_src == 0) {
|
if (addr_src == 0) {
|
||||||
piCout << "[piConnectU] Error: can`t find suitable pair of event \"" << sig << "\" in class \"" << src->className()
|
piCout << "[piConnectU] Error: can`t find suitable pair of event \"" << sig << "\" in class \"" << src->className()
|
||||||
<< "\" and handler \"" << hname << "\" in class \"" << dest_o->className() << "\"! (" << loc << ")";
|
<< "\" and handler \"" << hname << "\" in class \"" << dest_o->className() << "\"! (" << loc << ")";
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
src->connections << PIObject::__Connection(addr_dest, addr_src, sig, dest_o, dest, args, performer);
|
Connection conn(addr_dest, addr_src, sig, src, dest_o, dest, args, performer);
|
||||||
|
src->connections << conn;
|
||||||
if (que) performer->proc_event_queue = true;
|
if (que) performer->proc_event_queue = true;
|
||||||
dest_o->connectors << src;
|
dest_o->connectors << src;
|
||||||
//piCout << cc << cq << _ol.size();//"connect" << src << "->" << dest_o << ", dest.connectors.size() =" << dest_o->connectors.size();
|
//piCout << cc << cq << _ol.size();//"connect" << src << "->" << dest_o << ", dest.connectors.size() =" << dest_o->connectors.size();
|
||||||
return true;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIObject::piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc) {
|
PIObject::Connection PIObject::piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc) {
|
||||||
if (src == 0) {
|
if (src == 0) {
|
||||||
delete f;
|
delete f;
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
if (!src->isPIObject()) {
|
if (!src->isPIObject()) {
|
||||||
piCout << "[piConnectLS] \"" << sig << "\" -> [lambda] error: source object is not PIObject! (" << loc << ")";
|
piCout << "[piConnectLS] \"" << sig << "\" -> [lambda] error: source object is not PIObject! (" << loc << ")";
|
||||||
delete f;
|
delete f;
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
PIMutexLocker ml(__meta_mutex());
|
PIMutexLocker ml(__meta_mutex());
|
||||||
PIMutexLocker mls(src->mutex_connect);
|
PIMutexLocker mls(src->mutex_connect);
|
||||||
@@ -338,19 +299,19 @@ bool PIObject::piConnectLS(PIObject * src, const PIString & sig, std::function<v
|
|||||||
if (m_src.isEmpty()) {
|
if (m_src.isEmpty()) {
|
||||||
piCout << "[piConnectLS] Error: can`t find event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
piCout << "[piConnectLS] Error: can`t find event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
||||||
delete f;
|
delete f;
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
if (m_src.size() != 1) {
|
if (m_src.size() != 1) {
|
||||||
piCout << "[piConnectLS] Error: can`t connect overloaded event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
piCout << "[piConnectLS] Error: can`t connect overloaded event \"" << sig << "\" in class \"" << src->className() << "\"! (" << loc << ")";
|
||||||
delete f;
|
delete f;
|
||||||
return false;
|
return Connection();
|
||||||
}
|
}
|
||||||
PIObject::__Connection conn(0, m_src[0].addr, sig);
|
PIObject::Connection conn(0, m_src[0].addr, sig, src);
|
||||||
//piCout << "found";
|
//piCout << "found";
|
||||||
conn.functor = f;
|
conn.functor = f;
|
||||||
src->connections << conn;
|
src->connections << conn;
|
||||||
//piCout << "finished";
|
//piCout << "finished";
|
||||||
return true;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -358,7 +319,7 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig, PIObject * des
|
|||||||
PIMutexLocker _ml(src->mutex_connect);
|
PIMutexLocker _ml(src->mutex_connect);
|
||||||
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
||||||
for (int i = 0; i < src->connections.size_s(); ++i) {
|
for (int i = 0; i < src->connections.size_s(); ++i) {
|
||||||
__Connection & cc(src->connections[i]);
|
Connection & cc(src->connections[i]);
|
||||||
if (cc.event == sig && cc.dest_o == dest && cc.slot == ev_h) {
|
if (cc.event == sig && cc.dest_o == dest && cc.slot == ev_h) {
|
||||||
src->connections[i].destroy();
|
src->connections[i].destroy();
|
||||||
src->connections.remove(i);
|
src->connections.remove(i);
|
||||||
@@ -373,7 +334,7 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig, PIObject * des
|
|||||||
PIMutexLocker _ml(src->mutex_connect);
|
PIMutexLocker _ml(src->mutex_connect);
|
||||||
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
||||||
for (int i = 0; i < src->connections.size_s(); ++i) {
|
for (int i = 0; i < src->connections.size_s(); ++i) {
|
||||||
__Connection & cc(src->connections[i]);
|
Connection & cc(src->connections[i]);
|
||||||
if (cc.event == sig && cc.dest_o == dest) {
|
if (cc.event == sig && cc.dest_o == dest) {
|
||||||
src->connections[i].destroy();
|
src->connections[i].destroy();
|
||||||
src->connections.remove(i);
|
src->connections.remove(i);
|
||||||
@@ -387,14 +348,14 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig, PIObject * des
|
|||||||
void PIObject::piDisconnect(PIObject * src, const PIString & sig) {
|
void PIObject::piDisconnect(PIObject * src, const PIString & sig) {
|
||||||
PIMutexLocker _ml(src->mutex_connect);
|
PIMutexLocker _ml(src->mutex_connect);
|
||||||
for (int i = 0; i < src->connections.size_s(); ++i) {
|
for (int i = 0; i < src->connections.size_s(); ++i) {
|
||||||
__Connection & cc(src->connections[i]);
|
Connection & cc(src->connections[i]);
|
||||||
if (cc.event == sig) {
|
if (cc.event == sig) {
|
||||||
PIObject * dest = cc.dest_o;
|
PIObject * dest = cc.dest_o;
|
||||||
if (!dest) {
|
src->connections[i].destroy();
|
||||||
src->connections[i].destroy();
|
src->connections.remove(i);
|
||||||
src->connections.remove(i);
|
i--;
|
||||||
i--;
|
if (dest) {
|
||||||
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(FREERTOS)
|
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||||
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
PIMutexLocker _mld(dest->mutex_connect, src != dest);
|
||||||
#endif
|
#endif
|
||||||
dest->updateConnectors();
|
dest->updateConnectors();
|
||||||
@@ -404,37 +365,38 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIObject::piDisconnect(PIObject * src) {
|
void PIObject::piDisconnectAll() {
|
||||||
src->deleted(src);
|
PIMutexLocker _ml(mutex_connect);
|
||||||
PIMutexLocker _ml(src->mutex_connect);
|
PIVector<PIObject * > cv = connectors.toVector();
|
||||||
PIVector<PIObject * > cv = src->connectors.toVector();
|
// piCout << "disconnect connectors =" << connectors.size();
|
||||||
piForeach (PIObject * o, cv) {
|
piForeach (PIObject * o, cv) {
|
||||||
//piCout << "disconnect"<< src->className()<< o->className();
|
// piCout << "disconnect"<< src << o;
|
||||||
if (!o || (o == src)) continue;
|
if (!o || (o == this)) continue;
|
||||||
if (!o->isPIObject()) continue;
|
if (!o->isPIObject()) continue;
|
||||||
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(FREERTOS)
|
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||||
PIMutexLocker _mld(o->mutex_connect, src != o);
|
PIMutexLocker _mld(o->mutex_connect, this != o);
|
||||||
#endif
|
#endif
|
||||||
PIVector<__Connection> & oc(o->connections);
|
PIVector<Connection> & oc(o->connections);
|
||||||
for (int i = 0; i < oc.size_s(); ++i) {
|
for (int i = 0; i < oc.size_s(); ++i) {
|
||||||
if (oc[i].functor) continue;
|
if (oc[i].functor) continue;
|
||||||
//piCout << " check" << (void*)(oc[i].dest_o) << "==" << (void*)(src);
|
//piCout << " check" << (void*)(oc[i].dest_o) << "==" << (void*)(src);
|
||||||
if (oc[i].dest_o == src) {
|
if (oc[i].dest_o == this) {
|
||||||
oc[i].destroy();
|
oc[i].destroy();
|
||||||
oc.remove(i);
|
oc.remove(i);
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
piForeachC (PIObject::__Connection & c, src->connections) {
|
// piCout << "disconnect connections =" << connections.size();
|
||||||
|
piForeachC (PIObject::Connection & c, connections) {
|
||||||
if (c.functor) continue;
|
if (c.functor) continue;
|
||||||
if (!c.dest_o) continue;
|
if (!c.dest_o) continue;
|
||||||
if (!c.dest_o->isPIObject()) continue;
|
if (!c.dest_o->isPIObject()) continue;
|
||||||
c.dest_o->connectors.remove(src);
|
c.dest_o->connectors.remove(this);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < src->connections.size_s(); ++i)
|
for (int i = 0; i < connections.size_s(); ++i)
|
||||||
src->connections[i].destroy();
|
connections[i].destroy();
|
||||||
src->connections.clear();
|
connections.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -444,8 +406,8 @@ void PIObject::updateConnectors() {
|
|||||||
PIMutexLocker _ml(mutexObjects());
|
PIMutexLocker _ml(mutexObjects());
|
||||||
piForeach (PIObject * o, objects()) {
|
piForeach (PIObject * o, objects()) {
|
||||||
if (o == this) continue;
|
if (o == this) continue;
|
||||||
PIVector<__Connection> & oc(o->connections);
|
PIVector<Connection> & oc(o->connections);
|
||||||
piForeach (__Connection & c, oc)
|
piForeach (Connection & c, oc)
|
||||||
if (c.dest == this)
|
if (c.dest == this)
|
||||||
connectors << o;
|
connectors << o;
|
||||||
}
|
}
|
||||||
@@ -606,7 +568,7 @@ void PIObject::dump(const PIString & line_prefix) const {
|
|||||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " connections {";
|
PICout(PICoutManipulators::AddNewLine) << line_prefix << " connections {";
|
||||||
PICout(PICoutManipulators::AddNewLine) << line_prefix << " count: " << connections.size_s();
|
PICout(PICoutManipulators::AddNewLine) << line_prefix << " count: " << connections.size_s();
|
||||||
//printf("dump %d connections\n",connections.size());
|
//printf("dump %d connections\n",connections.size());
|
||||||
piForeachC (__Connection & c, connections) {
|
piForeachC (Connection & c, connections) {
|
||||||
PIObject * dst = c.dest_o;
|
PIObject * dst = c.dest_o;
|
||||||
__MetaFunc ef = methodEH(c.signal);
|
__MetaFunc ef = methodEH(c.signal);
|
||||||
PIString src(c.event);
|
PIString src(c.event);
|
||||||
@@ -627,6 +589,7 @@ void PIObject::dump(const PIString & line_prefix) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
void dumpApplication() {
|
void dumpApplication() {
|
||||||
PIMutexLocker _ml(PIObject::mutexObjects());
|
PIMutexLocker _ml(PIObject::mutexObjects());
|
||||||
//printf("dump application ...\n");
|
//printf("dump application ...\n");
|
||||||
@@ -653,7 +616,6 @@ void dumpApplication() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef FREERTOS
|
|
||||||
bool dumpApplicationToFile(const PIString & path) {
|
bool dumpApplicationToFile(const PIString & path) {
|
||||||
PIFile f(path + "_tmp");
|
PIFile f(path + "_tmp");
|
||||||
f.setName("__S__DumpFile");
|
f.setName("__S__DumpFile");
|
||||||
@@ -679,41 +641,87 @@ void PIObject::__MetaData::addScope(const PIString & s, uint shash) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIObject::__Connection::destroy() {
|
|
||||||
|
|
||||||
|
void PIObject::Connection::destroy() {
|
||||||
if (functor) delete functor;
|
if (functor) delete functor;
|
||||||
functor = nullptr;
|
functor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIObject::Connection::Connection() {
|
||||||
|
slot = signal = dest = nullptr;
|
||||||
|
src_o = dest_o = performer = nullptr;
|
||||||
|
functor = nullptr;
|
||||||
|
eventID = 0;
|
||||||
|
args_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PIObject::Connection::disconnect() {
|
||||||
|
if (!isValid() || !src_o) return false;
|
||||||
|
if (!src_o->isPIObject()) return false;
|
||||||
|
bool ndm = dest_o && (src_o != dest_o), ret = false, found = false;
|
||||||
|
if (dest_o) {
|
||||||
|
if (!dest_o->isPIObject()) ndm = false;
|
||||||
|
}
|
||||||
|
PIMutexLocker _ml(src_o->mutex_connect);
|
||||||
|
if (ndm) dest_o->mutex_connect.lock();
|
||||||
|
for (int i = 0; i < src_o->connections.size_s(); ++i) {
|
||||||
|
Connection & cc(src_o->connections[i]);
|
||||||
|
if (cc.eventID == eventID) {
|
||||||
|
if (dest_o && (cc.dest_o == dest_o)) {
|
||||||
|
if (cc.slot == slot)
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
if (functor && (cc.functor == functor))
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
src_o->connections[i].destroy();
|
||||||
|
src_o->connections.remove(i);
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dest_o) {
|
||||||
|
if (dest_o->isPIObject())
|
||||||
|
dest_o->updateConnectors();
|
||||||
|
}
|
||||||
|
if (ndm) dest_o->mutex_connect.unlock();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PRIVATE_DEFINITION_START(PIObject::Deleter)
|
PRIVATE_DEFINITION_START(PIObject::Deleter)
|
||||||
PIThread thread;
|
PIThread thread;
|
||||||
PIConditionVariable cond_var;
|
PIConditionVariable cond_var;
|
||||||
PIMutex cond_mutex, queue_mutex;
|
|
||||||
PIVector<PIObject*> obj_queue;
|
PIVector<PIObject*> obj_queue;
|
||||||
PRIVATE_DEFINITION_END(PIObject::Deleter)
|
PRIVATE_DEFINITION_END(PIObject::Deleter)
|
||||||
|
|
||||||
|
|
||||||
PIObject::Deleter::Deleter() {
|
PIObject::Deleter::Deleter() {
|
||||||
//piCout << "Deleter start ...";
|
//piCout << "Deleter start ...";
|
||||||
stopping = started = posted = false;
|
PRIVATE->thread.setSlot([this](){
|
||||||
CONNECTL(&(PRIVATE->thread), started, [this](){proc();});
|
PIVector<PIObject*> oq;
|
||||||
PRIVATE->thread.startOnce();
|
PRIVATE->thread.lock();
|
||||||
while (!started)
|
while(PRIVATE->obj_queue.isEmpty()) PRIVATE->cond_var.wait(PRIVATE->thread.mutex());
|
||||||
piMSleep(1);
|
oq.swap(PRIVATE->obj_queue);
|
||||||
|
PRIVATE->thread.unlock();
|
||||||
|
for (PIObject * o : oq) deleteObject(o);
|
||||||
|
});
|
||||||
|
PRIVATE->thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIObject::Deleter::~Deleter() {
|
PIObject::Deleter::~Deleter() {
|
||||||
//piCout << "~Deleter ...";
|
//piCout << "~Deleter ...";
|
||||||
stopping = true;
|
PRIVATE->thread.stop();
|
||||||
PRIVATE->cond_var.notifyAll();
|
PRIVATE->cond_var.notifyAll();
|
||||||
#ifndef WINDOWS
|
PRIVATE->thread.waitForFinish();
|
||||||
while (PRIVATE->thread.isRunning())
|
for (PIObject * o : PRIVATE->obj_queue) deleteObject(o);
|
||||||
piMSleep(1);
|
|
||||||
#endif
|
|
||||||
deleteAll();
|
|
||||||
//piCout << "~Deleter ok";
|
//piCout << "~Deleter ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,46 +735,13 @@ PIObject::Deleter * PIObject::Deleter::instance() {
|
|||||||
void PIObject::Deleter::post(PIObject * o) {
|
void PIObject::Deleter::post(PIObject * o) {
|
||||||
if (!o->isPIObject()) return;
|
if (!o->isPIObject()) return;
|
||||||
//piCout << "[Deleter] post" << o << "...";
|
//piCout << "[Deleter] post" << o << "...";
|
||||||
PRIVATE->queue_mutex.lock();
|
PRIVATE->thread.lock();
|
||||||
if (!PRIVATE->obj_queue.contains(o))
|
if (!PRIVATE->obj_queue.contains(o)) {
|
||||||
PRIVATE->obj_queue << o;
|
PRIVATE->obj_queue << o;
|
||||||
PRIVATE->queue_mutex.unlock();
|
PRIVATE->cond_var.notifyAll();
|
||||||
PRIVATE->cond_var.notifyAll();
|
|
||||||
posted = true;
|
|
||||||
//piCout << "[Deleter] post" << o << "done";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PIObject::Deleter::proc() {
|
|
||||||
//piCout << "[Deleter] proc start";
|
|
||||||
while (!stopping) {
|
|
||||||
//piMSleep(1);
|
|
||||||
//piCout << "[Deleter] proc wait ...";
|
|
||||||
if (posted) {
|
|
||||||
posted = false;
|
|
||||||
started = true;
|
|
||||||
} else {
|
|
||||||
PRIVATE->cond_mutex.lock();
|
|
||||||
started = true;
|
|
||||||
PRIVATE->cond_var.wait(PRIVATE->cond_mutex);
|
|
||||||
PRIVATE->cond_mutex.unlock();
|
|
||||||
}
|
|
||||||
//piCout << "[Deleter] proc wait done";
|
|
||||||
deleteAll();
|
|
||||||
}
|
}
|
||||||
//piCout << "[Deleter] proc end ok";
|
PRIVATE->thread.unlock();
|
||||||
}
|
//piCout << "[Deleter] post" << o << "done";
|
||||||
|
|
||||||
|
|
||||||
void PIObject::Deleter::deleteAll() {
|
|
||||||
PIVector<PIObject*> oq;
|
|
||||||
PRIVATE->queue_mutex.lock();
|
|
||||||
oq = PRIVATE->obj_queue;
|
|
||||||
//piCout << "[Deleter] deleteAll" << oq.size_s() << "...";
|
|
||||||
PRIVATE->obj_queue.clear();
|
|
||||||
PRIVATE->queue_mutex.unlock();
|
|
||||||
piForeach (PIObject * o, oq)
|
|
||||||
deleteObject(o);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -774,12 +749,9 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
|
|||||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "...";
|
//piCout << "[Deleter] delete" << (uintptr_t)o << "...";
|
||||||
if (o->isPIObject()) {
|
if (o->isPIObject()) {
|
||||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
|
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic ...";
|
||||||
while (o->isInEvent()) {
|
while (o->isInEvent()) piMinSleep();
|
||||||
piMSleep(1);
|
|
||||||
}
|
|
||||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
|
//piCout << "[Deleter] delete" << (uintptr_t)o << "wait atomic done";
|
||||||
if (o->isPIObject())
|
delete o;
|
||||||
delete o;
|
|
||||||
}
|
}
|
||||||
//piCout << "[Deleter] delete" << (uintptr_t)o << "done";
|
//piCout << "[Deleter] delete" << (uintptr_t)o << "done";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,11 +37,13 @@
|
|||||||
typedef void (*Handler)(void * );
|
typedef void (*Handler)(void * );
|
||||||
|
|
||||||
class PIP_EXPORT PIObject {
|
class PIP_EXPORT PIObject {
|
||||||
|
#ifndef MICRO_PIP
|
||||||
friend class PIObjectManager;
|
friend class PIObjectManager;
|
||||||
friend void dumpApplication();
|
friend void dumpApplication();
|
||||||
|
friend class PIIntrospection;
|
||||||
|
#endif
|
||||||
typedef PIObject __PIObject__;
|
typedef PIObject __PIObject__;
|
||||||
typedef void __Parent__;
|
typedef void __Parent__;
|
||||||
friend class PIIntrospection;
|
|
||||||
public:
|
public:
|
||||||
NO_COPY_CLASS(PIObject)
|
NO_COPY_CLASS(PIObject)
|
||||||
|
|
||||||
@@ -50,6 +52,54 @@ public:
|
|||||||
|
|
||||||
virtual ~PIObject();
|
virtual ~PIObject();
|
||||||
|
|
||||||
|
//! Helper class for obtain info about if connection successful and disconnect single connection
|
||||||
|
class PIP_EXPORT Connection {
|
||||||
|
friend class PIObject;
|
||||||
|
Connection(void * sl, void * si, const PIString & e = PIString(),
|
||||||
|
PIObject * s_o = nullptr, PIObject * d_o = nullptr,
|
||||||
|
void * d = nullptr, int ac = 0, PIObject * p = nullptr) {
|
||||||
|
slot = sl;
|
||||||
|
signal = si;
|
||||||
|
event = e;
|
||||||
|
eventID = e.hash();
|
||||||
|
src_o = s_o;
|
||||||
|
dest_o = d_o;
|
||||||
|
dest = d;
|
||||||
|
args_count = ac;
|
||||||
|
performer = p;
|
||||||
|
functor = 0;
|
||||||
|
}
|
||||||
|
void destroy();
|
||||||
|
void * slot;
|
||||||
|
void * signal;
|
||||||
|
std::function<void()> * functor;
|
||||||
|
PIString event;
|
||||||
|
uint eventID;
|
||||||
|
PIObject * src_o, * dest_o;
|
||||||
|
PIObject * performer;
|
||||||
|
void * dest;
|
||||||
|
int args_count;
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Contructs invalid %Connection
|
||||||
|
Connection();
|
||||||
|
|
||||||
|
//! Returns if %Connection is valid
|
||||||
|
bool isValid() const {return signal;}
|
||||||
|
|
||||||
|
//! Returns source object
|
||||||
|
PIObject * sourceObject() const {return src_o;}
|
||||||
|
|
||||||
|
//! Returns destination object or nullptr if this is lambda connection
|
||||||
|
PIObject * destinationObject() const {return dest_o;}
|
||||||
|
|
||||||
|
//! Returns performer object or nullptr if this is non-queued connection
|
||||||
|
PIObject * performerObject() const {return performer;}
|
||||||
|
|
||||||
|
//! Disconnect this %Connection, returns if operation successful
|
||||||
|
bool disconnect();
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint _signature_;
|
uint _signature_;
|
||||||
|
|
||||||
@@ -141,33 +191,38 @@ public:
|
|||||||
PIString methodEHFromAddr(const void * addr) const;
|
PIString methodEHFromAddr(const void * addr) const;
|
||||||
|
|
||||||
// / Direct connect
|
// / Direct connect
|
||||||
static void piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc);
|
static PIObject::Connection piConnect(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, void * ev_h, void * e_h, int args, const char * loc);
|
||||||
static bool piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer = 0);
|
static PIObject::Connection piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer = 0);
|
||||||
static bool piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc);
|
static PIObject::Connection piConnectLS(PIObject * src, const PIString & sig, std::function<void()> * f, const char * loc);
|
||||||
template <typename INPUT, typename... TYPES>
|
template <typename PIINPUT, typename... PITYPES>
|
||||||
static std::function<void()> * __newFunctor(void(*stat_handler)(void*,TYPES...), INPUT functor) {
|
static std::function<void()> * __newFunctor(void(*stat_handler)(void*,PITYPES...), PIINPUT functor) {
|
||||||
return (std::function<void()>*)(new std::function<void(TYPES...)>(functor));
|
return (std::function<void()>*)(new std::function<void(PITYPES...)>(functor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// / Through names and mixed
|
|
||||||
static void piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h);
|
|
||||||
static void piConnect(PIObject * src, const PIString & sig, const PIString & dest, void * ev_h);
|
|
||||||
static void piConnect(const PIString & src, const PIString & sig, const PIString & dest, void * ev_h);
|
|
||||||
|
|
||||||
|
|
||||||
|
//! Disconnect object from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
|
||||||
|
void piDisconnect(const PIString & sig, PIObject * dest, void * ev_h) {piDisconnect(this, sig, dest, ev_h);}
|
||||||
|
|
||||||
|
//! Disconnect object from all connections with event name "sig", connected to destination object "dest"
|
||||||
|
void piDisconnect(const PIString & sig, PIObject * dest) {piDisconnect(this, sig, dest);}
|
||||||
|
|
||||||
|
//! Disconnect object from all connections with event name "sig"
|
||||||
|
void piDisconnect(const PIString & sig) {piDisconnect(this, sig);}
|
||||||
|
|
||||||
|
|
||||||
|
//! Disconnect object "src" from all connections with event name "sig", connected to destination object "dest" and handler "ev_h"
|
||||||
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest, void * ev_h);
|
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest, void * ev_h);
|
||||||
|
|
||||||
|
//! Disconnect object "src" from all connections with event name "sig", connected to destination object "dest"
|
||||||
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest);
|
static void piDisconnect(PIObject * src, const PIString & sig, PIObject * dest);
|
||||||
|
|
||||||
//! Disconnect object "src" from all connections with event name "sig"
|
//! Disconnect object "src" from all connections with event name "sig"
|
||||||
static void piDisconnect(PIObject * src, const PIString & sig);
|
static void piDisconnect(PIObject * src, const PIString & sig);
|
||||||
|
|
||||||
//! Disconnect object "src" from all connections, i.e. all connections where object "src" is emitter
|
|
||||||
static void piDisconnect(PIObject * src);
|
|
||||||
|
|
||||||
// / Raise events
|
// / Raise events
|
||||||
static void raiseEvent(PIObject * sender, const uint eventID) {
|
static void raiseEvent(PIObject * sender, const uint eventID) {
|
||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
__Connection i(sender->connections[j]);
|
Connection i(sender->connections[j]);
|
||||||
if (i.eventID != eventID) continue;
|
if (i.eventID != eventID) continue;
|
||||||
if (i.functor) {
|
if (i.functor) {
|
||||||
(*(i.functor))();
|
(*(i.functor))();
|
||||||
@@ -196,7 +251,7 @@ public:
|
|||||||
template <typename T0>
|
template <typename T0>
|
||||||
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0()) {
|
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0()) {
|
||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
__Connection i(sender->connections[j]);
|
Connection i(sender->connections[j]);
|
||||||
if (i.eventID != eventID) continue;
|
if (i.eventID != eventID) continue;
|
||||||
if (i.functor) {
|
if (i.functor) {
|
||||||
(*((std::function<void(T0)>*)i.functor))(v0);
|
(*((std::function<void(T0)>*)i.functor))(v0);
|
||||||
@@ -227,7 +282,7 @@ public:
|
|||||||
template <typename T0, typename T1>
|
template <typename T0, typename T1>
|
||||||
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1()) {
|
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1()) {
|
||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
__Connection i(sender->connections[j]);
|
Connection i(sender->connections[j]);
|
||||||
if (i.eventID != eventID) continue;
|
if (i.eventID != eventID) continue;
|
||||||
if (i.functor) {
|
if (i.functor) {
|
||||||
(*((std::function<void(T0, T1)>*)i.functor))(v0, v1);
|
(*((std::function<void(T0, T1)>*)i.functor))(v0, v1);
|
||||||
@@ -262,7 +317,7 @@ public:
|
|||||||
template <typename T0, typename T1, typename T2>
|
template <typename T0, typename T1, typename T2>
|
||||||
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) {
|
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) {
|
||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
__Connection i(sender->connections[j]);
|
Connection i(sender->connections[j]);
|
||||||
if (i.eventID != eventID) continue;
|
if (i.eventID != eventID) continue;
|
||||||
if (i.functor) {
|
if (i.functor) {
|
||||||
(*((std::function<void(T0, T1, T2)>*)i.functor))(v0, v1, v2);
|
(*((std::function<void(T0, T1, T2)>*)i.functor))(v0, v1, v2);
|
||||||
@@ -299,7 +354,7 @@ public:
|
|||||||
template <typename T0, typename T1, typename T2, typename T3>
|
template <typename T0, typename T1, typename T2, typename T3>
|
||||||
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) {
|
static void raiseEvent(PIObject * sender, const uint eventID, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) {
|
||||||
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
for (int j = 0; j < sender->connections.size_s(); ++j) {
|
||||||
__Connection i(sender->connections[j]);
|
Connection i(sender->connections[j]);
|
||||||
if (i.eventID != eventID) continue;
|
if (i.eventID != eventID) continue;
|
||||||
if (i.functor) {
|
if (i.functor) {
|
||||||
(*((std::function<void(T0, T1, T2, T3)>*)i.functor))(v0, v1, v2, v3);
|
(*((std::function<void(T0, T1, T2, T3)>*)i.functor))(v0, v1, v2, v3);
|
||||||
@@ -428,30 +483,6 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct __Connection {
|
|
||||||
__Connection(void * sl = 0, void * si = 0, const PIString & e = PIString(), PIObject * d_o = 0, void * d = 0, int ac = 0, PIObject * p = 0) {
|
|
||||||
slot = sl;
|
|
||||||
signal = si;
|
|
||||||
event = e;
|
|
||||||
eventID = e.hash();
|
|
||||||
dest_o = d_o;
|
|
||||||
dest = d;
|
|
||||||
args_count = ac;
|
|
||||||
performer = p;
|
|
||||||
functor = 0;
|
|
||||||
}
|
|
||||||
void destroy();
|
|
||||||
void * slot;
|
|
||||||
void * signal;
|
|
||||||
std::function<void()> * functor;
|
|
||||||
PIString event;
|
|
||||||
uint eventID;
|
|
||||||
PIObject * dest_o;
|
|
||||||
PIObject * performer;
|
|
||||||
void * dest;
|
|
||||||
int args_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __QueuedEvent {
|
struct __QueuedEvent {
|
||||||
__QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector<PIVariantSimple> & v = PIVector<PIVariantSimple>()) {
|
__QueuedEvent(void * sl = 0, void * d = 0, PIObject * d_o = 0, PIObject * s = 0, const PIVector<PIVariantSimple> & v = PIVector<PIVariantSimple>()) {
|
||||||
slot = sl;
|
slot = sl;
|
||||||
@@ -474,10 +505,7 @@ private:
|
|||||||
static Deleter * instance();
|
static Deleter * instance();
|
||||||
void post(PIObject * o);
|
void post(PIObject * o);
|
||||||
private:
|
private:
|
||||||
void proc();
|
|
||||||
void deleteAll();
|
|
||||||
void deleteObject(PIObject * o);
|
void deleteObject(PIObject * o);
|
||||||
std::atomic_bool stopping, started, posted;
|
|
||||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -488,6 +516,8 @@ private:
|
|||||||
PIVector<__MetaFunc> findEH(const PIString & name) const;
|
PIVector<__MetaFunc> findEH(const PIString & name) const;
|
||||||
__MetaFunc methodEH(const void * addr) const;
|
__MetaFunc methodEH(const void * addr) const;
|
||||||
void updateConnectors();
|
void updateConnectors();
|
||||||
|
void piDisconnectAll();
|
||||||
|
|
||||||
void postQueuedEvent(const __QueuedEvent & e);
|
void postQueuedEvent(const __QueuedEvent & e);
|
||||||
void eventBegin() {in_event_cnt++;}
|
void eventBegin() {in_event_cnt++;}
|
||||||
void eventEnd () {in_event_cnt--;}
|
void eventEnd () {in_event_cnt--;}
|
||||||
@@ -500,7 +530,7 @@ private:
|
|||||||
static void callAddrV(void * slot, void * obj, int args, const PIVector<PIVariantSimple> & vl);
|
static void callAddrV(void * slot, void * obj, int args, const PIVector<PIVariantSimple> & vl);
|
||||||
|
|
||||||
|
|
||||||
PIVector<__Connection> connections;
|
PIVector<Connection> connections;
|
||||||
PIMap<uint, PIPair<PIString, PIVariant> > properties_;
|
PIMap<uint, PIPair<PIString, PIVariant> > properties_;
|
||||||
PISet<PIObject * > connectors;
|
PISet<PIObject * > connectors;
|
||||||
PIVector<__QueuedEvent> events_queue;
|
PIVector<__QueuedEvent> events_queue;
|
||||||
@@ -511,8 +541,9 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
PIP_EXPORT void dumpApplication();
|
PIP_EXPORT void dumpApplication();
|
||||||
PIP_EXPORT bool dumpApplicationToFile(const PIString & path);
|
PIP_EXPORT bool dumpApplicationToFile(const PIString & path);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // PIOBJECT_H
|
#endif // PIOBJECT_H
|
||||||
|
|||||||
@@ -102,28 +102,36 @@
|
|||||||
|
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\". \"Event\" and \"handler\" must has equal argument lists.
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\". \"Event\" and \"handler\" must has equal argument lists.
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECTU(src, event, dest, handler)
|
#define CONNECTU(src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\".
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\".
|
||||||
/// Event handler will be executed by \"performer\". \"Event\" and \"handler\" must has equal argument lists.
|
/// Event handler will be executed by \"performer\". \"Event\" and \"handler\" must has equal argument lists.
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECTU_QUEUED(src, event, dest, handler, performer)
|
#define CONNECTU_QUEUED(src, event, dest, handler, performer)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to lambda-expression \"functor\". \"Event\" and \"functor\" must has equal argument lists.
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to lambda-expression \"functor\". \"Event\" and \"functor\" must has equal argument lists.
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECTL(src, event, functor)
|
#define CONNECTL(src, event, functor)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECT0(ret, src, event, dest, handler)
|
#define CONNECT0(ret, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECT1(ret, type0, src, event, dest, handler)
|
#define CONNECT1(ret, type0, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECT2(ret, type0, type1, src, event, dest, handler)
|
#define CONNECT2(ret, type0, type1, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
#define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists
|
/// \relatesalso PIObject @brief connect event \"event\" from object \"src\" to event handler \"handler\" with return type \"ret\" from object \"dest\" with check of event and handler exists.
|
||||||
|
/// Returns PIObject::Connection
|
||||||
#define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
#define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
|
||||||
|
|
||||||
/// \relatesalso PIObject @brief CONNECT is synonym of CONNECT0
|
/// \relatesalso PIObject @brief CONNECT is synonym of CONNECT0
|
||||||
|
|||||||
@@ -19,7 +19,11 @@
|
|||||||
|
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
#include "pisystemtests.h"
|
#ifndef MICRO_PIP
|
||||||
|
# include "pisystemtests.h"
|
||||||
|
#elif defined(ARDUINO)
|
||||||
|
# include <Arduino.h>
|
||||||
|
#endif
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
extern FILETIME __pi_ftjan1970;
|
extern FILETIME __pi_ftjan1970;
|
||||||
long long __PIQueryPerformanceCounter() {LARGE_INTEGER li; QueryPerformanceCounter(&li); return li.QuadPart;}
|
long long __PIQueryPerformanceCounter() {LARGE_INTEGER li; QueryPerformanceCounter(&li); return li.QuadPart;}
|
||||||
@@ -31,9 +35,8 @@
|
|||||||
//# include <crt_externs.h>
|
//# include <crt_externs.h>
|
||||||
extern clock_serv_t __pi_mac_clock;
|
extern clock_serv_t __pi_mac_clock;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
# include "freertos/FreeRTOS.h"
|
# include <sys/time.h>
|
||||||
# include "freertos/task.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! \class PISystemTime
|
/*! \class PISystemTime
|
||||||
@@ -252,24 +255,29 @@ PISystemTime PISystemTime::current(bool precise_but_not_system) {
|
|||||||
ullong lt = ullong(sft.dwHighDateTime) * 0x100000000U + ullong(sft.dwLowDateTime);
|
ullong lt = ullong(sft.dwHighDateTime) * 0x100000000U + ullong(sft.dwLowDateTime);
|
||||||
return PISystemTime(lt / 10000000U, (lt % 10000000U) * 100U);
|
return PISystemTime(lt / 10000000U, (lt % 10000000U) * 100U);
|
||||||
}
|
}
|
||||||
#else
|
#elif defined(MAC_OS)
|
||||||
# ifdef MAC_OS
|
|
||||||
mach_timespec_t t_cur;
|
mach_timespec_t t_cur;
|
||||||
clock_get_time(__pi_mac_clock, &t_cur);
|
clock_get_time(__pi_mac_clock, &t_cur);
|
||||||
# else
|
#elif defined(MICRO_PIP)
|
||||||
# ifdef FREERTOS
|
|
||||||
timespec t_cur;
|
timespec t_cur;
|
||||||
|
# ifdef ARDUINO
|
||||||
|
static const uint32_t offSetSinceEpoch_s = 1581897605UL;
|
||||||
|
uint32_t mt = millis();
|
||||||
|
t_cur.tv_sec = offSetSinceEpoch_s + (mt / 1000);
|
||||||
|
t_cur.tv_nsec = (mt - (mt / 1000)) * 1000000UL;
|
||||||
|
# else
|
||||||
timeval tv;
|
timeval tv;
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&tv, NULL);
|
||||||
t_cur.tv_sec = tv.tv_sec;
|
t_cur.tv_sec = tv.tv_sec;
|
||||||
t_cur.tv_nsec = tv.tv_usec * 1000;
|
t_cur.tv_nsec = tv.tv_usec * 1000;
|
||||||
# else
|
# endif
|
||||||
|
#else
|
||||||
timespec t_cur;
|
timespec t_cur;
|
||||||
clock_gettime(precise_but_not_system ? CLOCK_MONOTONIC : 0, &t_cur);
|
clock_gettime(precise_but_not_system ? CLOCK_MONOTONIC : 0, &t_cur);
|
||||||
# endif
|
#endif
|
||||||
# endif
|
#ifndef WINDOWS
|
||||||
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
return PISystemTime(t_cur.tv_sec, t_cur.tv_nsec);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -407,22 +415,38 @@ PITimeMeasurer::PITimeMeasurer() {
|
|||||||
|
|
||||||
|
|
||||||
double PITimeMeasurer::elapsed_n() const {
|
double PITimeMeasurer::elapsed_n() const {
|
||||||
return (PISystemTime::current(true) - t_st).toNanoseconds() - PISystemTests::time_elapsed_ns;
|
return (PISystemTime::current(true) - t_st).toNanoseconds()
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
- PISystemTests::time_elapsed_ns
|
||||||
|
#endif
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double PITimeMeasurer::elapsed_u() const {
|
double PITimeMeasurer::elapsed_u() const {
|
||||||
return (PISystemTime::current(true) - t_st).toMicroseconds() - PISystemTests::time_elapsed_ns / 1.E+3;
|
return (PISystemTime::current(true) - t_st).toMicroseconds()
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
- PISystemTests::time_elapsed_ns / 1.E+3
|
||||||
|
#endif
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double PITimeMeasurer::elapsed_m() const {
|
double PITimeMeasurer::elapsed_m() const {
|
||||||
return (PISystemTime::current(true) - t_st).toMilliseconds() - PISystemTests::time_elapsed_ns / 1.E+6;
|
return (PISystemTime::current(true) - t_st).toMilliseconds()
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
- PISystemTests::time_elapsed_ns / 1.E+6
|
||||||
|
#endif
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double PITimeMeasurer::elapsed_s() const {
|
double PITimeMeasurer::elapsed_s() const {
|
||||||
return (PISystemTime::current(true) - t_st).toSeconds() - PISystemTests::time_elapsed_ns / 1.E+9;
|
return (PISystemTime::current(true) - t_st).toSeconds()
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
- PISystemTests::time_elapsed_ns / 1.E+9
|
||||||
|
#endif
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -469,13 +493,3 @@ PICout operator <<(PICout s, const PIDateTime & v) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WINDOWS
|
|
||||||
void msleep(int msecs) {Sleep(msecs);}
|
|
||||||
#else
|
|
||||||
# ifdef FREERTOS
|
|
||||||
void msleep(int msecs) {vTaskDelay(msecs / portTICK_PERIOD_MS);}
|
|
||||||
# else
|
|
||||||
void msleep(int msecs) {usleep(msecs * 1000);}
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|||||||
@@ -29,8 +29,6 @@
|
|||||||
#ifdef QNX
|
#ifdef QNX
|
||||||
# include <time.h>
|
# include <time.h>
|
||||||
#endif
|
#endif
|
||||||
//! @brief Sleep for "msecs" milliseconds
|
|
||||||
PIP_EXPORT void msleep(int msecs);
|
|
||||||
|
|
||||||
/*! @brief Precise sleep for "usecs" microseconds
|
/*! @brief Precise sleep for "usecs" microseconds
|
||||||
* \details This function consider \c "usleep" offset
|
* \details This function consider \c "usleep" offset
|
||||||
@@ -48,6 +46,8 @@ inline void piMSleep(double msecs) {piUSleep(int(msecs * 1000.));} // on !Window
|
|||||||
* \details This function exec \a piUSleep (msecs * 1000000). */
|
* \details This function exec \a piUSleep (msecs * 1000000). */
|
||||||
inline void piSleep(double secs) {piUSleep(int(secs * 1000000.));} // on !Windows consider constant "usleep" offset
|
inline void piSleep(double secs) {piUSleep(int(secs * 1000000.));} // on !Windows consider constant "usleep" offset
|
||||||
|
|
||||||
|
//! Shortest available on current system sleep
|
||||||
|
inline void piMinSleep() {piMSleep(PIP_MIN_MSLEEP);}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#ifdef PIP_FREERTOS
|
#ifdef MICRO_PIP
|
||||||
#include "pivariant.h"
|
#include "pivariant.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -48,10 +48,10 @@ template<typename T>
|
|||||||
class __VariantFunctions__: public __VariantFunctionsBase__ {
|
class __VariantFunctions__: public __VariantFunctionsBase__ {
|
||||||
public:
|
public:
|
||||||
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<T> ret; return &ret;}
|
__VariantFunctionsBase__ * instance() final {static __VariantFunctions__<T> ret; return &ret;}
|
||||||
#ifdef PIP_FREERTOS
|
#ifdef MICRO_PIP
|
||||||
PIString typeName() const final {static PIString ret(PIVariant(T()).typeName()); return ret;}
|
PIString typeName() const final {static PIString ret(PIVariant(T()).typeName()); return ret;}
|
||||||
#else
|
#else
|
||||||
PIString typeName() const final {static PIString ret(typeid(T).name()); return ret;}
|
PIString typeName() const final {static PIString ret(_TYPENAME_(T)); return ret;}
|
||||||
#endif
|
#endif
|
||||||
uint hash() const final {static uint ret = typeName().hash(); return ret;}
|
uint hash() const final {static uint ret = typeName().hash(); return ret;}
|
||||||
void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value));}
|
void newT(void *& ptr, const void * value) final {ptr = (void*)(new T(*(const T*)value));}
|
||||||
|
|||||||
@@ -19,8 +19,9 @@
|
|||||||
|
|
||||||
#include "pivarianttypes.h"
|
#include "pivarianttypes.h"
|
||||||
#include "pipropertystorage.h"
|
#include "pipropertystorage.h"
|
||||||
#include "piiodevice.h"
|
#ifndef MICRO_PIP
|
||||||
|
# include "piiodevice.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int PIVariantTypes::Enum::selectedValue() const {
|
int PIVariantTypes::Enum::selectedValue() const {
|
||||||
piForeachC (Enumerator & e, enum_list)
|
piForeachC (Enumerator & e, enum_list)
|
||||||
@@ -83,9 +84,12 @@ PIStringList PIVariantTypes::Enum::names() const {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PIVariantTypes::IODevice::IODevice() {
|
PIVariantTypes::IODevice::IODevice() {
|
||||||
|
#ifndef MICRO_PIP
|
||||||
mode = PIIODevice::ReadWrite;
|
mode = PIIODevice::ReadWrite;
|
||||||
|
#else
|
||||||
|
mode = 0; // TODO: PIIODevice for MICRO PIP
|
||||||
|
#endif // MICRO_PIP
|
||||||
options = 0;
|
options = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,12 +116,14 @@ PIString PIVariantTypes::IODevice::toPICout() const {
|
|||||||
if (mode & 2) {s << "w"; ++rwc;}
|
if (mode & 2) {s << "w"; ++rwc;}
|
||||||
if (rwc == 1) s << "o";
|
if (rwc == 1) s << "o";
|
||||||
s << ", flags=";
|
s << ", flags=";
|
||||||
|
#ifndef MICRO_PIP // TODO: PIIODevice for MICRO PIP
|
||||||
if (options != 0) {
|
if (options != 0) {
|
||||||
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead])
|
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead])
|
||||||
s << " br";
|
s << " br";
|
||||||
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite])
|
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite])
|
||||||
s << " bw";
|
s << " bw";
|
||||||
}
|
}
|
||||||
|
#endif // MICRO_PIP
|
||||||
PIPropertyStorage ps = get();
|
PIPropertyStorage ps = get();
|
||||||
piForeachC (PIPropertyStorage::Property & p, ps) {
|
piForeachC (PIPropertyStorage::Property & p, ps) {
|
||||||
s << ", " << p.name << "=\"" << p.value.toString() << "\"";
|
s << ", " << p.name << "=\"" << p.value.toString() << "\"";
|
||||||
@@ -128,7 +134,6 @@ PIString PIVariantTypes::IODevice::toPICout() const {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIVariantTypes::Enumerator & v) {
|
PIVariantTypes::Enum & PIVariantTypes::Enum::operator <<(const PIVariantTypes::Enumerator & v) {
|
||||||
enum_list << v;
|
enum_list << v;
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -99,9 +99,6 @@ struct PIP_EXPORT Enum {
|
|||||||
* @brief Make vector of Enum names
|
* @brief Make vector of Enum names
|
||||||
*/
|
*/
|
||||||
PIStringList names() const;
|
PIStringList names() const;
|
||||||
PIString enum_name;
|
|
||||||
PIString selected;
|
|
||||||
PIVector<Enumerator> enum_list;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Add PIVariantTypes::Enumerator to Enum
|
* @brief Add PIVariantTypes::Enumerator to Enum
|
||||||
@@ -119,6 +116,15 @@ struct PIP_EXPORT Enum {
|
|||||||
* @brief Add PIVariantTypes::Enumerator element for each name in vector
|
* @brief Add PIVariantTypes::Enumerator element for each name in vector
|
||||||
*/
|
*/
|
||||||
Enum & operator <<(const PIStringList & v);
|
Enum & operator <<(const PIStringList & v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return true if Enum is empty
|
||||||
|
*/
|
||||||
|
bool isEmpty() const {return enum_list.isEmpty();}
|
||||||
|
|
||||||
|
PIString enum_name;
|
||||||
|
PIString selected;
|
||||||
|
PIVector<Enumerator> enum_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PIP_EXPORT File {
|
struct PIP_EXPORT File {
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ public:
|
|||||||
//! Generate hash from bytearray
|
//! Generate hash from bytearray
|
||||||
static PIByteArray hash(const PIByteArray & data);
|
static PIByteArray hash(const PIByteArray & data);
|
||||||
|
|
||||||
|
//! Generate hash from bytearray
|
||||||
|
static PIByteArray hash(const PIByteArray & data, const unsigned char * key, size_t keylen);
|
||||||
|
|
||||||
//! Returns hash size
|
//! Returns hash size
|
||||||
static size_t sizeHash();
|
static size_t sizeHash();
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class PIPeer;
|
|||||||
class PIIntrospection;
|
class PIIntrospection;
|
||||||
class PIIntrospectionServer;
|
class PIIntrospectionServer;
|
||||||
|
|
||||||
#ifdef PIP_INTROSPECTION
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
#define __PIINTROSPECTION_SINGLETON_H__(T) \
|
#define __PIINTROSPECTION_SINGLETON_H__(T) \
|
||||||
static PIIntrospection##T##Interface * instance();
|
static PIIntrospection##T##Interface * instance();
|
||||||
|
|
||||||
|
|||||||
@@ -17,11 +17,11 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
|
|
||||||
#include "piintrospection_containers.h"
|
#include "piintrospection_containers.h"
|
||||||
#include "piintrospection_containers_p.h"
|
#include "piintrospection_containers_p.h"
|
||||||
|
|
||||||
#ifdef PIP_INTROSPECTION
|
|
||||||
|
|
||||||
__PIINTROSPECTION_SINGLETON_CPP__(Containers)
|
__PIINTROSPECTION_SINGLETON_CPP__(Containers)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,10 @@
|
|||||||
#ifndef PIINTROSPECTION_CONTAINERS_H
|
#ifndef PIINTROSPECTION_CONTAINERS_H
|
||||||
#define PIINTROSPECTION_CONTAINERS_H
|
#define PIINTROSPECTION_CONTAINERS_H
|
||||||
|
|
||||||
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
|
|
||||||
#include "piintrospection_base.h"
|
#include "piintrospection_base.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
|
||||||
class PIIntrospectionContainers;
|
class PIIntrospectionContainers;
|
||||||
|
|
||||||
#define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance())//(PIIntrospectionContainersInterface::instance())
|
#define PIINTROSPECTION_CONTAINERS (PIIntrospectionContainersInterface::instance())//(PIIntrospectionContainersInterface::instance())
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef PIP_INTROSPECTION
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
|
|
||||||
#include "piintrospection_server.h"
|
#include "piintrospection_server.h"
|
||||||
#include "piintrospection_server_p.h"
|
#include "piintrospection_server_p.h"
|
||||||
|
|||||||
@@ -20,11 +20,10 @@
|
|||||||
#ifndef PIINTROSPECTION_SERVER_H
|
#ifndef PIINTROSPECTION_SERVER_H
|
||||||
#define PIINTROSPECTION_SERVER_H
|
#define PIINTROSPECTION_SERVER_H
|
||||||
|
|
||||||
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
|
|
||||||
#include "pipeer.h"
|
#include "pipeer.h"
|
||||||
|
|
||||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
|
||||||
|
|
||||||
class PIIntrospectionServer;
|
class PIIntrospectionServer;
|
||||||
class PISystemMonitor;
|
class PISystemMonitor;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef PIP_INTROSPECTION
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
|
|
||||||
#include "piintrospection_threads.h"
|
#include "piintrospection_threads.h"
|
||||||
#include "piintrospection_threads_p.h"
|
#include "piintrospection_threads_p.h"
|
||||||
|
|||||||
@@ -20,11 +20,10 @@
|
|||||||
#ifndef PIINTROSPECTION_THREADS_H
|
#ifndef PIINTROSPECTION_THREADS_H
|
||||||
#define PIINTROSPECTION_THREADS_H
|
#define PIINTROSPECTION_THREADS_H
|
||||||
|
|
||||||
#include "piintrospection_base.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
#if defined(PIP_INTROSPECTION) && !defined(PIP_FORCE_NO_PIINTROSPECTION)
|
||||||
|
|
||||||
|
#include "piintrospection_base.h"
|
||||||
|
|
||||||
class PIIntrospectionThreads;
|
class PIIntrospectionThreads;
|
||||||
|
|
||||||
#define PIINTROSPECTION_THREADS (PIIntrospectionThreadsInterface::instance())
|
#define PIINTROSPECTION_THREADS (PIIntrospectionThreadsInterface::instance())
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ static const uchar binlog_sig[] = {'B','I','N','L','O','G'};
|
|||||||
REGISTER_DEVICE(PIBinaryLog)
|
REGISTER_DEVICE(PIBinaryLog)
|
||||||
|
|
||||||
PIBinaryLog::PIBinaryLog() {
|
PIBinaryLog::PIBinaryLog() {
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
setThreadedReadBufferSize(512);
|
setThreadedReadBufferSize(512);
|
||||||
#else
|
#else
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
@@ -181,7 +181,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
|||||||
pausemutex.lock();
|
pausemutex.lock();
|
||||||
if (is_pause) {
|
if (is_pause) {
|
||||||
pausemutex.unlock();
|
pausemutex.unlock();
|
||||||
piMSleep(100);
|
piMSleep(100); // TODO: rewrite with condvar
|
||||||
return false;
|
return false;
|
||||||
} else if (pause_time > PISystemTime()) {
|
} else if (pause_time > PISystemTime()) {
|
||||||
startlogtime += pause_time;
|
startlogtime += pause_time;
|
||||||
@@ -204,22 +204,22 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
|||||||
int dtc;
|
int dtc;
|
||||||
if (is_started) {
|
if (is_started) {
|
||||||
if (is_pause) {
|
if (is_pause) {
|
||||||
piMSleep(100);
|
piMSleep(100); // TODO: rewrite with condvar
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
cdelay = delay * play_speed;
|
cdelay = delay * play_speed;// TODO: rewrite with condvar
|
||||||
dtc = int(cdelay) /100;
|
dtc = int(cdelay) / 100;// TODO: rewrite with condvar
|
||||||
if (play_speed <= 0.) dtc = 2;
|
if (play_speed <= 0.) dtc = 2;
|
||||||
//piCout << play_speed << dtc;
|
//piCout << play_speed << dtc;
|
||||||
for (int j=0; j<dtc; j++) {
|
for (int j=0; j<dtc; j++) {
|
||||||
cdelay = delay * play_speed;
|
cdelay = delay * play_speed;// TODO: rewrite with condvar
|
||||||
dtc = int(cdelay) /100;
|
dtc = int(cdelay) / 100;// TODO: rewrite with condvar
|
||||||
piMSleep(100);
|
piMSleep(100);// TODO: rewrite with condvar
|
||||||
if (play_speed <= 0.) {dtc = 2; j = 0;}
|
if (play_speed <= 0.) {dtc = 2; j = 0;}
|
||||||
//piCout << " " << play_speed << dtc << j;
|
//piCout << " " << play_speed << dtc << j;
|
||||||
}
|
}
|
||||||
cdelay = cdelay - dtc*100;
|
cdelay = cdelay - dtc*100;// TODO: rewrite with condvar
|
||||||
PISystemTime::fromMilliseconds(cdelay).sleep();
|
PISystemTime::fromMilliseconds(cdelay).sleep();
|
||||||
}
|
}
|
||||||
} else is_started = true;
|
} else is_started = true;
|
||||||
@@ -228,7 +228,7 @@ bool PIBinaryLog::threadedRead(uchar *readed, int size) {
|
|||||||
case PlayStaticDelay:
|
case PlayStaticDelay:
|
||||||
if (is_started) {
|
if (is_started) {
|
||||||
if (is_pause) {
|
if (is_pause) {
|
||||||
piMSleep(100);
|
piMSleep(100);// TODO: rewrite with condvar
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
play_delay.sleep();
|
play_delay.sleep();
|
||||||
@@ -357,7 +357,9 @@ PIByteArray PIBinaryLog::readBinLog(int id, PISystemTime * time, int * readed_id
|
|||||||
if (readed_id) *readed_id = br.id;
|
if (readed_id) *readed_id = br.id;
|
||||||
return br.data;
|
return br.data;
|
||||||
}
|
}
|
||||||
|
logmutex.lock();
|
||||||
while (br.id != id && !isEnd()) br = readRecord();
|
while (br.id != id && !isEnd()) br = readRecord();
|
||||||
|
logmutex.unlock();
|
||||||
if (br.id == -1) {
|
if (br.id == -1) {
|
||||||
piCoutObj << "End of BinLog file";
|
piCoutObj << "End of BinLog file";
|
||||||
fileEnd();
|
fileEnd();
|
||||||
@@ -579,6 +581,7 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector<
|
|||||||
if (info) {
|
if (info) {
|
||||||
BinLogIndex bl_ind;
|
BinLogIndex bl_ind;
|
||||||
bl_ind.id = br.id;
|
bl_ind.id = br.id;
|
||||||
|
bl_ind.data_size = br.size;
|
||||||
bl_ind.pos = f->pos() - br.size - hdr_size;
|
bl_ind.pos = f->pos() - br.size - hdr_size;
|
||||||
bl_ind.timestamp = br.timestamp;
|
bl_ind.timestamp = br.timestamp;
|
||||||
index->append(bl_ind);
|
index->append(bl_ind);
|
||||||
@@ -665,9 +668,22 @@ bool PIBinaryLog::createIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PIBinaryLog::posForTime(const PISystemTime & time) {
|
||||||
|
int ci = -1;
|
||||||
|
for (uint i = 0; i < index.size(); i++) {
|
||||||
|
if (time <= index[i].timestamp && (filterID.contains(index[i].id) || filterID.isEmpty())) {
|
||||||
|
ci = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ci;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIBinaryLog::seekTo(int rindex) {
|
void PIBinaryLog::seekTo(int rindex) {
|
||||||
// piCoutObj << "seekTo";
|
// piCoutObj << "seekTo";
|
||||||
logmutex.lock();
|
logmutex.lock();
|
||||||
|
pausemutex.lock();
|
||||||
if (rindex < index.size_s() && rindex >= 0) {
|
if (rindex < index.size_s() && rindex >= 0) {
|
||||||
file.seek(index[rindex].pos);
|
file.seek(index[rindex].pos);
|
||||||
moveIndex(index_pos.value(file.pos(), -1));
|
moveIndex(index_pos.value(file.pos(), -1));
|
||||||
@@ -679,18 +695,13 @@ void PIBinaryLog::seekTo(int rindex) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// piCoutObj << "seekTo done";
|
// piCoutObj << "seekTo done";
|
||||||
|
pausemutex.unlock();
|
||||||
logmutex.unlock();
|
logmutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIBinaryLog::seek(const PISystemTime & time) {
|
bool PIBinaryLog::seek(const PISystemTime & time) {
|
||||||
int ci = -1;
|
int ci = posForTime(time);
|
||||||
for (uint i=0; i<index.size(); i++) {
|
|
||||||
if (time <= index[i].timestamp && (filterID.contains(index[i].id) || filterID.isEmpty())) {
|
|
||||||
ci = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ci >= 0) {
|
if (ci >= 0) {
|
||||||
seekTo(ci);
|
seekTo(ci);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ public:
|
|||||||
//! @brief Struct contains position, ID and timestamp of record in file
|
//! @brief Struct contains position, ID and timestamp of record in file
|
||||||
struct PIP_EXPORT BinLogIndex {
|
struct PIP_EXPORT BinLogIndex {
|
||||||
int id;
|
int id;
|
||||||
|
int data_size;
|
||||||
llong pos;
|
llong pos;
|
||||||
PISystemTime timestamp;
|
PISystemTime timestamp;
|
||||||
};
|
};
|
||||||
@@ -201,6 +202,9 @@ public:
|
|||||||
//! Returns timestamp of last readed record
|
//! Returns timestamp of last readed record
|
||||||
PISystemTime lastReadedTimestamp() const {return lastrecord.timestamp;}
|
PISystemTime lastReadedTimestamp() const {return lastrecord.timestamp;}
|
||||||
|
|
||||||
|
//! Returns timestamp of log start
|
||||||
|
PISystemTime logStartTimestamp() const {return startlogtime;}
|
||||||
|
|
||||||
//!Set custom file header, you can get it back when read this binlog
|
//!Set custom file header, you can get it back when read this binlog
|
||||||
void setHeader(const PIByteArray & header);
|
void setHeader(const PIByteArray & header);
|
||||||
|
|
||||||
@@ -233,6 +237,9 @@ public:
|
|||||||
//! Return if current binlog file is indexed
|
//! Return if current binlog file is indexed
|
||||||
bool isIndexed() {return is_indexed;}
|
bool isIndexed() {return is_indexed;}
|
||||||
|
|
||||||
|
//! Find nearest record of time \"time\". Returns -1 if not indexed or time less than first record
|
||||||
|
int posForTime(const PISystemTime & time);
|
||||||
|
|
||||||
//! Go to record #index
|
//! Go to record #index
|
||||||
void seekTo(int rindex);
|
void seekTo(int rindex);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include "pican.h"
|
#include "pican.h"
|
||||||
#include "pipropertystorage.h"
|
#include "pipropertystorage.h"
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#if !defined(WINDOWS) && !defined(MAC_OS) && !defined(FREERTOS)
|
#if !defined(WINDOWS) && !defined(MAC_OS) && !defined(MICRO_PIP)
|
||||||
# define PIP_CAN
|
# define PIP_CAN
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIP_CAN
|
#ifdef PIP_CAN
|
||||||
|
|||||||
@@ -58,10 +58,10 @@
|
|||||||
# include <sys/socket.h>
|
# include <sys/socket.h>
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
# include <net/if.h>
|
# include <net/if.h>
|
||||||
# if !defined(ANDROID) && !defined(FREERTOS)
|
# if !defined(ANDROID) && !defined(LWIP)
|
||||||
# include <ifaddrs.h>
|
# include <ifaddrs.h>
|
||||||
# endif
|
# endif
|
||||||
# ifdef FREERTOS
|
# ifdef LWIP
|
||||||
# include <lwip/sockets.h>
|
# include <lwip/sockets.h>
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
@@ -260,7 +260,7 @@ void PIEthernet::construct() {
|
|||||||
setMulticastTTL(1);
|
setMulticastTTL(1);
|
||||||
server_thread_.setData(this);
|
server_thread_.setData(this);
|
||||||
server_thread_.setName("__S__server_thread");
|
server_thread_.setName("__S__server_thread");
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
setThreadedReadBufferSize(512);
|
setThreadedReadBufferSize(512);
|
||||||
#else
|
#else
|
||||||
setThreadedReadBufferSize(65536);
|
setThreadedReadBufferSize(65536);
|
||||||
@@ -473,7 +473,7 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
|||||||
}
|
}
|
||||||
PIFlags<Parameters> params = parameters();
|
PIFlags<Parameters> params = parameters();
|
||||||
addr_r.set(path());
|
addr_r.set(path());
|
||||||
#ifndef FREERTOS
|
#ifndef LWIP
|
||||||
struct ip_mreqn mreq;
|
struct ip_mreqn mreq;
|
||||||
#else
|
#else
|
||||||
struct ip_mreq mreq;
|
struct ip_mreq mreq;
|
||||||
@@ -486,13 +486,13 @@ bool PIEthernet::joinMulticastGroup(const PIString & group) {
|
|||||||
if (ci != 0) mreq.imr_ifindex = ci->index;*/
|
if (ci != 0) mreq.imr_ifindex = ci->index;*/
|
||||||
#endif
|
#endif
|
||||||
if (params[PIEthernet::Broadcast])
|
if (params[PIEthernet::Broadcast])
|
||||||
#ifndef FREERTOS
|
#ifndef LWIP
|
||||||
mreq.imr_address.s_addr = INADDR_ANY;
|
mreq.imr_address.s_addr = INADDR_ANY;
|
||||||
#else
|
#else
|
||||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
#ifndef FREERTOS
|
#ifndef LWIP
|
||||||
mreq.imr_address.s_addr = addr_r.ip();
|
mreq.imr_address.s_addr = addr_r.ip();
|
||||||
#else
|
#else
|
||||||
mreq.imr_interface.s_addr = addr_r.ip();
|
mreq.imr_interface.s_addr = addr_r.ip();
|
||||||
@@ -520,20 +520,20 @@ bool PIEthernet::leaveMulticastGroup(const PIString & group) {
|
|||||||
}
|
}
|
||||||
PIFlags<Parameters> params = parameters();
|
PIFlags<Parameters> params = parameters();
|
||||||
addr_r.set(path());
|
addr_r.set(path());
|
||||||
#ifndef FREERTOS
|
#ifndef LWIP
|
||||||
struct ip_mreqn mreq;
|
struct ip_mreqn mreq;
|
||||||
#else
|
#else
|
||||||
struct ip_mreq mreq;
|
struct ip_mreq mreq;
|
||||||
#endif
|
#endif
|
||||||
memset(&mreq, 0, sizeof(mreq));
|
memset(&mreq, 0, sizeof(mreq));
|
||||||
if (params[PIEthernet::Broadcast])
|
if (params[PIEthernet::Broadcast])
|
||||||
#ifndef FREERTOS
|
#ifndef LWIP
|
||||||
mreq.imr_address.s_addr = INADDR_ANY;
|
mreq.imr_address.s_addr = INADDR_ANY;
|
||||||
#else
|
#else
|
||||||
mreq.imr_interface.s_addr = INADDR_ANY;
|
mreq.imr_interface.s_addr = INADDR_ANY;
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
#ifndef FREERTOS
|
#ifndef LWIP
|
||||||
mreq.imr_address.s_addr = addr_r.ip();
|
mreq.imr_address.s_addr = addr_r.ip();
|
||||||
#else
|
#else
|
||||||
mreq.imr_interface.s_addr = addr_r.ip();
|
mreq.imr_interface.s_addr = addr_r.ip();
|
||||||
@@ -686,7 +686,7 @@ int PIEthernet::readDevice(void * read_to, int max_size) {
|
|||||||
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
s = accept(sock, (sockaddr * )&client_addr, &slen);
|
||||||
if (s == -1) {
|
if (s == -1) {
|
||||||
//piCoutObj << "Can`t accept new connection, " << ethErrorString();
|
//piCoutObj << "Can`t accept new connection, " << ethErrorString();
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rs = ethRecv(s, read_to, max_size);
|
rs = ethRecv(s, read_to, max_size);
|
||||||
@@ -788,7 +788,7 @@ int PIEthernet::writeDevice(const void * data, int max_size) {
|
|||||||
//piCoutObj << "connect SingleTCP" << ip_s << ":" << port_s << "...";
|
//piCoutObj << "connect SingleTCP" << ip_s << ":" << port_s << "...";
|
||||||
if (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) != 0) {
|
if (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) != 0) {
|
||||||
//piCoutObj << "Can`t connect to " << ip_s << ":" << port_s << ", " << ethErrorString();
|
//piCoutObj << "Can`t connect to " << ip_s << ":" << port_s << ", " << ethErrorString();
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//piCoutObj << "ok, write SingleTCP" << int(data) << max_size << "bytes ...";
|
//piCoutObj << "ok, write SingleTCP" << int(data) << max_size << "bytes ...";
|
||||||
@@ -993,6 +993,7 @@ void PIEthernet::configureFromVariantDevice(const PIPropertyStorage & d) {
|
|||||||
|
|
||||||
|
|
||||||
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
PIEthernet::InterfaceList PIEthernet::interfaces() {
|
||||||
|
//piCout << "PIEthernet::interfaces()";
|
||||||
PIEthernet::InterfaceList il;
|
PIEthernet::InterfaceList il;
|
||||||
Interface ci;
|
Interface ci;
|
||||||
ci.index = -1;
|
ci.index = -1;
|
||||||
@@ -1039,12 +1040,20 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
}
|
}
|
||||||
pAdapter = pAdapter->Next;
|
pAdapter = pAdapter->Next;
|
||||||
}
|
}
|
||||||
} else
|
} else {
|
||||||
piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
switch (ret) {
|
||||||
|
case ERROR_NO_DATA: break;
|
||||||
|
case ERROR_NOT_SUPPORTED:
|
||||||
|
piCout << "[PIEthernet] GetAdaptersInfo not supported";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
piCout << "[PIEthernet] GetAdaptersInfo failed with error:" << ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (pAdapterInfo)
|
if (pAdapterInfo)
|
||||||
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
HeapFree(GetProcessHeap(), 0, (pAdapterInfo));
|
||||||
#else
|
#else
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
#else
|
#else
|
||||||
# ifdef ANDROID
|
# ifdef ANDROID
|
||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
@@ -1156,7 +1165,7 @@ PIEthernet::InterfaceList PIEthernet::interfaces() {
|
|||||||
|
|
||||||
|
|
||||||
PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
|
PIEthernet::Address PIEthernet::interfaceAddress(const PIString & interface_) {
|
||||||
#if defined(WINDOWS) || defined(FREERTOS)
|
#if defined(WINDOWS) || defined(MICRO_PIP)
|
||||||
piCout << "[PIEthernet] Not implemented, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead";
|
piCout << "[PIEthernet] Not implemented, use \"PIEthernet::allAddresses\" or \"PIEthernet::interfaces\" instead";
|
||||||
return Address();
|
return Address();
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -148,7 +148,17 @@ PIFile::PIFile(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(p
|
|||||||
|
|
||||||
|
|
||||||
bool PIFile::openTemporary(PIIODevice::DeviceMode mode) {
|
bool PIFile::openTemporary(PIIODevice::DeviceMode mode) {
|
||||||
return open(PIString(tmpnam(0)), mode);
|
PIString tp;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
tp = PIDir::temporary().path() + PIDir::separator + "file" + PIString::fromNumber(randomi());
|
||||||
|
#else
|
||||||
|
char * rc = tmpnam(0);
|
||||||
|
if (!rc) return false;
|
||||||
|
tp = rc;
|
||||||
|
#endif
|
||||||
|
while (isExists(tp))
|
||||||
|
tp += PIString::fromNumber(randomi() % 10);
|
||||||
|
return open(tp, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -701,7 +711,7 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
|
|||||||
ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.MTIME.tv_sec, fs.MTIME.tv_nsec));
|
ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.MTIME.tv_sec, fs.MTIME.tv_nsec));
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
ret.perm_user = FileInfo::Permissions((mode & S_IRUSR) == S_IRUSR, (mode & S_IWUSR) == S_IWUSR, (mode & S_IXUSR) == S_IXUSR);
|
ret.perm_user = FileInfo::Permissions((mode & S_IRUSR) == S_IRUSR, (mode & S_IWUSR) == S_IWUSR, (mode & S_IXUSR) == S_IXUSR);
|
||||||
ret.perm_group = FileInfo::Permissions((mode & S_IRGRP) == S_IRGRP, (mode & S_IWGRP) == S_IWGRP, (mode & S_IXGRP) == S_IXGRP);
|
ret.perm_group = FileInfo::Permissions((mode & S_IRGRP) == S_IRGRP, (mode & S_IWGRP) == S_IWGRP, (mode & S_IXGRP) == S_IXGRP);
|
||||||
ret.perm_other = FileInfo::Permissions((mode & S_IROTH) == S_IROTH, (mode & S_IWOTH) == S_IWOTH, (mode & S_IXOTH) == S_IXOTH);
|
ret.perm_other = FileInfo::Permissions((mode & S_IROTH) == S_IROTH, (mode & S_IWOTH) == S_IWOTH, (mode & S_IXOTH) == S_IXOTH);
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Constructs a file with path "path" and open mode "mode"
|
//! Constructs a file with path "path" and open mode "mode"
|
||||||
|
//! If "path" is not empty then open file
|
||||||
explicit PIFile(const PIString & path, DeviceMode mode = ReadWrite);
|
explicit PIFile(const PIString & path, DeviceMode mode = ReadWrite);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ bool PIIODevice::setOption(PIIODevice::DeviceOption o, bool yes) {
|
|||||||
|
|
||||||
|
|
||||||
bool stopThread(PIThread * t, bool hard) {
|
bool stopThread(PIThread * t, bool hard) {
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
t->stop(true);
|
t->stop(true);
|
||||||
#else
|
#else
|
||||||
if (hard) {
|
if (hard) {
|
||||||
@@ -163,7 +163,7 @@ bool stopThread(PIThread * t, bool hard) {
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
t->stop();
|
t->stop();
|
||||||
if (t->waitForFinish(10000)) {
|
if (!t->waitForFinish(10000)) {
|
||||||
t->terminate();
|
t->terminate();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ void PIIODevice::_init() {
|
|||||||
setOptions(0);
|
setOptions(0);
|
||||||
setReopenEnabled(true);
|
setReopenEnabled(true);
|
||||||
setReopenTimeout(1000);
|
setReopenTimeout(1000);
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
threaded_read_buffer_size = 512;
|
threaded_read_buffer_size = 512;
|
||||||
//setThreadedReadBufferSize(512);
|
//setThreadedReadBufferSize(512);
|
||||||
#else
|
#else
|
||||||
@@ -239,7 +239,7 @@ void PIIODevice::check_start(void * data, int delim) {
|
|||||||
//cout << "check " << tread_started_ << endl;
|
//cout << "check " << tread_started_ << endl;
|
||||||
if (open()) {
|
if (open()) {
|
||||||
thread_started_ = true;
|
thread_started_ = true;
|
||||||
timer.stop();
|
timer.stop(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ void PIIODevice::write_func() {
|
|||||||
int ret = write(item.first);
|
int ret = write(item.first);
|
||||||
threadedWriteEvent(item.second, ret);
|
threadedWriteEvent(item.second, ret);
|
||||||
}
|
}
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +276,7 @@ void PIIODevice::terminate() {
|
|||||||
thread_started_ = false;
|
thread_started_ = false;
|
||||||
if (!init_) return;
|
if (!init_) return;
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
stop(true);
|
stop(true);
|
||||||
#else
|
#else
|
||||||
stop();
|
stop();
|
||||||
@@ -338,7 +338,7 @@ PIByteArray PIIODevice::readForTime(double timeout_ms) {
|
|||||||
tm.reset();
|
tm.reset();
|
||||||
while (tm.elapsed_m() < timeout_ms) {
|
while (tm.elapsed_m() < timeout_ms) {
|
||||||
ret = read(td, threaded_read_buffer_size);
|
ret = read(td, threaded_read_buffer_size);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else str.append(td, ret);
|
else str.append(td, ret);
|
||||||
}
|
}
|
||||||
delete[] td;
|
delete[] td;
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#include "pipropertystorage.h"
|
#include "pipropertystorage.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#if defined(FREERTOS)
|
#if defined(MICRO_PIP)
|
||||||
# define PISERIAL_NO_PINS
|
# define PISERIAL_NO_PINS
|
||||||
#endif
|
#endif
|
||||||
#if defined(PISERIAL_NO_PINS) || defined(WINDOWS)
|
#if defined(PISERIAL_NO_PINS) || defined(WINDOWS)
|
||||||
@@ -289,6 +289,39 @@ bool PISerial::isRNG() const {return isBit(TIOCM_RNG, "RNG");}
|
|||||||
bool PISerial::isDSR() const {return isBit(TIOCM_DSR, "DSR");}
|
bool PISerial::isDSR() const {return isBit(TIOCM_DSR, "DSR");}
|
||||||
|
|
||||||
|
|
||||||
|
bool PISerial::setBreak(bool enabled) {
|
||||||
|
if (fd < 0) {
|
||||||
|
piCoutObj << "sendBreak error: \"" << path() << "\" is not opened!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#ifdef WINDOWS
|
||||||
|
if (enabled) {
|
||||||
|
if (!SetCommBreak(PRIVATE->hCom)) {
|
||||||
|
piCoutObj << "setBreak error: " << errorString();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!ClearCommBreak(PRIVATE->hCom)) {
|
||||||
|
piCoutObj << "setBreak error: " << errorString();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (ioctl(fd, enabled ? TIOCSBRK : TIOCCBRK) < 0) {
|
||||||
|
piCoutObj << "setBreak error: " << errorString();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
bool PISerial::setBit(int bit, bool on, const PIString & bname) {
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
piCoutObj << "setBit" << bname << " error: \"" << path() << "\" is not opened!";
|
piCoutObj << "setBit" << bname << " error: \"" << path() << "\" is not opened!";
|
||||||
@@ -356,6 +389,9 @@ int PISerial::convertSpeed(PISerial::Speed speed) {
|
|||||||
case S2400: return B2400;
|
case S2400: return B2400;
|
||||||
case S4800: return B4800;
|
case S4800: return B4800;
|
||||||
case S9600: return B9600;
|
case S9600: return B9600;
|
||||||
|
#ifdef WINDOWS
|
||||||
|
case S14400: return B14400;
|
||||||
|
#endif
|
||||||
case S19200: return B19200;
|
case S19200: return B19200;
|
||||||
case S38400: return B38400;
|
case S38400: return B38400;
|
||||||
case S57600: return B57600;
|
case S57600: return B57600;
|
||||||
@@ -398,7 +434,7 @@ bool PISerial::read(void * data, int size, double timeout_ms) {
|
|||||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(&((uchar * )data)[all], size - all);
|
ret = readDevice(&((uchar * )data)[all], size - all);
|
||||||
if (ret > 0) all += ret;
|
if (ret > 0) all += ret;
|
||||||
else msleep(PIP_MIN_MSLEEP);
|
else piMinSleep();
|
||||||
}
|
}
|
||||||
setOption(BlockingRead, br);
|
setOption(BlockingRead, br);
|
||||||
received(data, all);
|
received(data, all);
|
||||||
@@ -437,13 +473,13 @@ PIString PISerial::read(int size, double timeout_ms) {
|
|||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
while (tm_.elapsed_m() < timeout_ms) {
|
while (tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(td, 1024);
|
ret = readDevice(td, 1024);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else str << PIString((char*)td, ret);
|
else str << PIString((char*)td, ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(td, size - all);
|
ret = readDevice(td, size - all);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else {
|
else {
|
||||||
str << PIString((char*)td, ret);
|
str << PIString((char*)td, ret);
|
||||||
all += ret;
|
all += ret;
|
||||||
@@ -457,7 +493,7 @@ PIString PISerial::read(int size, double timeout_ms) {
|
|||||||
str << PIString((char*)td, all);
|
str << PIString((char*)td, all);
|
||||||
while (all < size) {
|
while (all < size) {
|
||||||
ret = readDevice(td, size - all);
|
ret = readDevice(td, size - all);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else {
|
else {
|
||||||
str << PIString((char*)td, ret);
|
str << PIString((char*)td, ret);
|
||||||
all += ret;
|
all += ret;
|
||||||
@@ -489,13 +525,13 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
|||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
while (tm_.elapsed_m() < timeout_ms) {
|
while (tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(td, 1024);
|
ret = readDevice(td, 1024);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else str.append(td, ret);
|
else str.append(td, ret);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
while (all < size && tm_.elapsed_m() < timeout_ms) {
|
||||||
ret = readDevice(td, size - all);
|
ret = readDevice(td, size - all);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else {
|
else {
|
||||||
str.append(td, ret);
|
str.append(td, ret);
|
||||||
all += ret;
|
all += ret;
|
||||||
@@ -509,7 +545,7 @@ PIByteArray PISerial::readData(int size, double timeout_ms) {
|
|||||||
str.append(td, all);
|
str.append(td, all);
|
||||||
while (all < size) {
|
while (all < size) {
|
||||||
ret = readDevice(td, size - all);
|
ret = readDevice(td, size - all);
|
||||||
if (ret <= 0) msleep(PIP_MIN_MSLEEP);
|
if (ret <= 0) piMinSleep();
|
||||||
else {
|
else {
|
||||||
str.append(td, ret);
|
str.append(td, ret);
|
||||||
all += ret;
|
all += ret;
|
||||||
@@ -846,9 +882,13 @@ void PISerial::configureFromVariantDevice(const PIPropertyStorage & d) {
|
|||||||
PIVector<int> PISerial::availableSpeeds() {
|
PIVector<int> PISerial::availableSpeeds() {
|
||||||
PIVector<int> spds;
|
PIVector<int> spds;
|
||||||
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 <<
|
spds << 50 << 75 << 110 << 300 << 600 << 1200 << 2400 << 4800 <<
|
||||||
9600 << 19200 << 38400 << 57600 << 115200 << 230400 << 460800 <<
|
9600 <<
|
||||||
500000 << 576000 << 921600 << 1000000 << 1152000 << 1500000 <<
|
#ifdef WINDOWS
|
||||||
2000000 << 2500000 << 3000000 << 3500000 << 4000000;
|
14400 <<
|
||||||
|
#endif
|
||||||
|
19200 << 38400 << 57600 << 115200 << 230400 <<
|
||||||
|
460800 << 500000 << 576000 << 921600 << 1000000 << 1152000 <<
|
||||||
|
1500000 << 2000000 << 2500000 << 3000000 << 3500000 << 4000000;
|
||||||
return spds;
|
return spds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
S2400 /*! 2400 baud */ = 2400,
|
S2400 /*! 2400 baud */ = 2400,
|
||||||
S4800 /*! 4800 baud */ = 4800,
|
S4800 /*! 4800 baud */ = 4800,
|
||||||
S9600 /*! 9600 baud */ = 9600,
|
S9600 /*! 9600 baud */ = 9600,
|
||||||
|
S14400 /*! 14400 baud */ = 14400,
|
||||||
S19200 /*! 19200 baud */ = 19200,
|
S19200 /*! 19200 baud */ = 19200,
|
||||||
S38400 /*! 38400 baud */ = 38400,
|
S38400 /*! 38400 baud */ = 38400,
|
||||||
S57600 /*! 57600 baud */ = 57600,
|
S57600 /*! 57600 baud */ = 57600,
|
||||||
@@ -159,6 +160,12 @@ public:
|
|||||||
bool isRNG() const;
|
bool isRNG() const;
|
||||||
bool isDSR() const;
|
bool isDSR() const;
|
||||||
|
|
||||||
|
//! Switch transmission line in break if enabled.
|
||||||
|
//! i.e. sends a continuous stream of zero bits.
|
||||||
|
//! If successful, returns true; otherwise returns false.
|
||||||
|
//! The serial port has to be open before trying to send a break duration; otherwise returns false
|
||||||
|
bool setBreak(bool enabled);
|
||||||
|
|
||||||
void setVTime(int t) {vtime = t; applySettings();}
|
void setVTime(int t) {vtime = t; applySettings();}
|
||||||
|
|
||||||
//! Returns device name
|
//! Returns device name
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ REGISTER_DEVICE(PISPI)
|
|||||||
|
|
||||||
|
|
||||||
PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) {
|
PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) {
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
setThreadedReadBufferSize(512);
|
setThreadedReadBufferSize(512);
|
||||||
#else
|
#else
|
||||||
setThreadedReadBufferSize(1024);
|
setThreadedReadBufferSize(1024);
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
|
|||||||
diag.setName("PIBaseTransfer");
|
diag.setName("PIBaseTransfer");
|
||||||
diag.start(50);
|
diag.start(50);
|
||||||
packets_count = 10;
|
packets_count = 10;
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
setPacketSize(512);
|
setPacketSize(512);
|
||||||
#else
|
#else
|
||||||
setPacketSize(4096);
|
setPacketSize(4096);
|
||||||
@@ -346,7 +346,7 @@ bool PIBaseTransfer::send_process() {
|
|||||||
if (chk == 0) return finish_send(true);
|
if (chk == 0) return finish_send(true);
|
||||||
if (chk != prev_chk) rtm.reset();
|
if (chk != prev_chk) rtm.reset();
|
||||||
else if (rtm.elapsed_m() < 100) {
|
else if (rtm.elapsed_m() < 100) {
|
||||||
piMSleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (is_pause) {
|
if (is_pause) {
|
||||||
@@ -507,7 +507,7 @@ bool PIBaseTransfer::getStartRequest() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mutex_session.unlock();
|
mutex_session.unlock();
|
||||||
piMSleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ void PIPacketExtractor::construct() {
|
|||||||
ret_func_header = ret_func_footer = 0;
|
ret_func_header = ret_func_footer = 0;
|
||||||
setPayloadSize(0);
|
setPayloadSize(0);
|
||||||
setTimeout(100);
|
setTimeout(100);
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
setBufferSize(512);
|
setBufferSize(512);
|
||||||
#else
|
#else
|
||||||
setBufferSize(65536);
|
setBufferSize(65536);
|
||||||
|
|||||||
@@ -36,22 +36,6 @@ public:
|
|||||||
//! Contructs packer and try to assign \"dev\"
|
//! Contructs packer and try to assign \"dev\"
|
||||||
PIStreamPacker(PIIODevice * dev = 0);
|
PIStreamPacker(PIIODevice * dev = 0);
|
||||||
|
|
||||||
//! Progress info
|
|
||||||
struct PIP_IO_UTILS_EXPORT Progress {
|
|
||||||
Progress();
|
|
||||||
|
|
||||||
//! Is send/receive in progress
|
|
||||||
bool active;
|
|
||||||
|
|
||||||
//! Overall send/receive packet size
|
|
||||||
int bytes_all;
|
|
||||||
|
|
||||||
//! Current send/receive size
|
|
||||||
int bytes_current;
|
|
||||||
|
|
||||||
//! Current send/receive progress from 0 to 1
|
|
||||||
double progress;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! Set maximum size of single packet
|
//! Set maximum size of single packet
|
||||||
void setMaxPacketSize(int max_size) {max_packet_size = max_size;}
|
void setMaxPacketSize(int max_size) {max_packet_size = max_size;}
|
||||||
@@ -83,6 +67,8 @@ public:
|
|||||||
bool cryptSizeEnabled() const {return crypt_size;}
|
bool cryptSizeEnabled() const {return crypt_size;}
|
||||||
void setCryptSizeEnabled(bool on);
|
void setCryptSizeEnabled(bool on);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
|
||||||
//! Prepare data for send and raise \a sendRequest() events
|
//! Prepare data for send and raise \a sendRequest() events
|
||||||
void send(const PIByteArray & data);
|
void send(const PIByteArray & data);
|
||||||
@@ -97,12 +83,6 @@ public:
|
|||||||
//! and \a sendRequest() event to \"dev\" \a PIIODevice::write() handler
|
//! and \a sendRequest() event to \"dev\" \a PIIODevice::write() handler
|
||||||
void assignDevice(PIIODevice * dev);
|
void assignDevice(PIIODevice * dev);
|
||||||
|
|
||||||
//! Returns \a Progress info about sending
|
|
||||||
Progress progressSend() const;
|
|
||||||
|
|
||||||
//! Returns \a Progress info about receiving
|
|
||||||
Progress progressReceive() const;
|
|
||||||
|
|
||||||
EVENT1(packetReceiveEvent, PIByteArray &, data)
|
EVENT1(packetReceiveEvent, PIByteArray &, data)
|
||||||
EVENT1(sendRequest, PIByteArray, data)
|
EVENT1(sendRequest, PIByteArray, data)
|
||||||
|
|
||||||
@@ -139,7 +119,6 @@ private:
|
|||||||
int packet_size, crypt_frag_size;
|
int packet_size, crypt_frag_size;
|
||||||
ushort packet_sign;
|
ushort packet_sign;
|
||||||
int max_packet_size, size_crypted_size;
|
int max_packet_size, size_crypted_size;
|
||||||
Progress prog_s, prog_r;
|
|
||||||
mutable PIMutex prog_s_mutex, prog_r_mutex;
|
mutable PIMutex prog_s_mutex, prog_r_mutex;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "pifft.h"
|
#include "pifft.h"
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
PIFFT_double::PIFFT_double() {
|
PIFFT_double::PIFFT_double() {
|
||||||
}
|
}
|
||||||
@@ -1883,3 +1884,5 @@ void PIFFT_float::ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // MICRO_PIP
|
||||||
|
|||||||
@@ -23,9 +23,12 @@
|
|||||||
#ifndef PIFFT_H
|
#ifndef PIFFT_H
|
||||||
#define PIFFT_H
|
#define PIFFT_H
|
||||||
|
|
||||||
#include "pip_fftw_export.h"
|
|
||||||
#include "pimathcomplex.h"
|
#include "pimathcomplex.h"
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
|
#include "pip_fftw_export.h"
|
||||||
|
|
||||||
class PIP_EXPORT PIFFT_double
|
class PIP_EXPORT PIFFT_double
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -194,4 +197,6 @@ typedef PIFFTW<ldouble> PIFFTWld;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // MICRO_PIP
|
||||||
|
|
||||||
#endif // PIFFT_H
|
#endif // PIFFT_H
|
||||||
|
|||||||
@@ -51,13 +51,16 @@
|
|||||||
#ifdef PIP_FREERTOS
|
#ifdef PIP_FREERTOS
|
||||||
# define FREERTOS
|
# define FREERTOS
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(FREERTOS) || defined(PLATFORMIO)
|
||||||
|
# define MICRO_PIP
|
||||||
|
#endif
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
# ifndef QNX
|
# ifndef QNX
|
||||||
# ifndef FREE_BSD
|
# ifndef FREE_BSD
|
||||||
# ifndef MAC_OS
|
# ifndef MAC_OS
|
||||||
# ifndef ANDROID
|
# ifndef ANDROID
|
||||||
# ifndef BLACKBERRY
|
# ifndef BLACKBERRY
|
||||||
# ifndef FREERTOS
|
# ifndef MICRO_PIP
|
||||||
# define LINUX
|
# define LINUX
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
@@ -84,6 +87,10 @@
|
|||||||
# define CC_OTHER
|
# define CC_OTHER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
# define CC_AVR_GCC
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# ifdef CC_GCC
|
# ifdef CC_GCC
|
||||||
# define typeof __typeof
|
# define typeof __typeof
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "pilibrary.h"
|
#include "pilibrary.h"
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
@@ -110,4 +110,4 @@ void PILibrary::getLastError() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PIP_FREERTOS
|
#endif // MICRO_PIP
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#ifndef PILIBRARY_H
|
#ifndef PILIBRARY_H
|
||||||
#define PILIBRARY_H
|
#define PILIBRARY_H
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "pistring.h"
|
#include "pistring.h"
|
||||||
|
|
||||||
@@ -50,5 +50,5 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIP_FREERTOS
|
#endif // MICRO_PIP
|
||||||
#endif // PILIBRARY_H
|
#endif // PILIBRARY_H
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "piplugin.h"
|
#include "piplugin.h"
|
||||||
#include "pifile.h"
|
#include "pifile.h"
|
||||||
@@ -408,4 +408,4 @@ PIString PIPluginLoader::libExtension() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // PIP_FREERTOS
|
#endif // MICRO_PIP
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#ifndef PIPLUGIN_H
|
#ifndef PIPLUGIN_H
|
||||||
#define PIPLUGIN_H
|
#define PIPLUGIN_H
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "pilibrary.h"
|
#include "pilibrary.h"
|
||||||
#include "pistringlist.h"
|
#include "pistringlist.h"
|
||||||
@@ -212,5 +212,5 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif // PIP_FREERTOS
|
#endif // MICRO_PIP
|
||||||
#endif // PIPLUGIN_H
|
#endif // PIPLUGIN_H
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "piprocess.h"
|
#include "piprocess.h"
|
||||||
@@ -66,7 +66,7 @@ void PIProcess::exec_() {
|
|||||||
startOnce();
|
startOnce();
|
||||||
//cout << "exec wait" << endl;
|
//cout << "exec wait" << endl;
|
||||||
while (!is_exec)
|
while (!is_exec)
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
//cout << "exec end" << endl;
|
//cout << "exec end" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +172,7 @@ void PIProcess::startProc(bool detached) {
|
|||||||
if (execve(str.data(), a, e) < 0)
|
if (execve(str.data(), a, e) < 0)
|
||||||
piCoutObj << "\"execve" << str << args << "\" error :" << errorString();
|
piCoutObj << "\"execve" << str << args << "\" error :" << errorString();
|
||||||
} else {
|
} else {
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep;
|
||||||
//cout << "wait" << endl;
|
//cout << "wait" << endl;
|
||||||
if (!detached) {
|
if (!detached) {
|
||||||
wait(&exit_code);
|
wait(&exit_code);
|
||||||
@@ -290,5 +290,5 @@ PIString PIProcess::getEnvironmentVariable(const PIString & variable) {
|
|||||||
return PIString();
|
return PIString();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PIP_FREERTOS
|
#endif // MICRO_PIP
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#ifndef PIPROCESS_H
|
#ifndef PIPROCESS_H
|
||||||
#define PIPROCESS_H
|
#define PIPROCESS_H
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "pifile.h"
|
#include "pifile.h"
|
||||||
@@ -104,5 +104,5 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIP_FREERTOS
|
#endif // MICRO_PIP
|
||||||
#endif // PIPROCESS_H
|
#endif // PIPROCESS_H
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ uint PISystemInfo::machineID() {
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
CRC_32 crc = standardCRC_32();
|
CRC_32 crc = standardCRC_32();
|
||||||
ret = crc.calculate(machineKey().toByteArray());
|
ret = crc.calculate(machineKey().toByteArray());
|
||||||
piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret;
|
//piCout << "machineID \"" << machineKey() << "\" =" << PICoutManipulators::Hex << ret;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ PISystemMonitor::ThreadStatsFixed::ThreadStatsFixed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
PRIVATE_DEFINITION_START(PISystemMonitor)
|
PRIVATE_DEFINITION_START(PISystemMonitor)
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
# ifdef MAC_OS
|
# ifdef MAC_OS
|
||||||
@@ -83,7 +83,7 @@ PRIVATE_DEFINITION_END(PISystemMonitor)
|
|||||||
PISystemMonitor::PISystemMonitor(): PIThread() {
|
PISystemMonitor::PISystemMonitor(): PIThread() {
|
||||||
pID_ = cycle = 0;
|
pID_ = cycle = 0;
|
||||||
cpu_count = PISystemInfo::instance()->processorsCount;
|
cpu_count = PISystemInfo::instance()->processorsCount;
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
#ifndef WINDOWS
|
#ifndef WINDOWS
|
||||||
# ifdef QNX
|
# ifdef QNX
|
||||||
page_size = 4096;
|
page_size = 4096;
|
||||||
@@ -104,7 +104,7 @@ PISystemMonitor::~PISystemMonitor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
bool PISystemMonitor::startOnProcess(int pID, int interval_ms) {
|
bool PISystemMonitor::startOnProcess(int pID, int interval_ms) {
|
||||||
stop();
|
stop();
|
||||||
pID_ = pID;
|
pID_ = pID;
|
||||||
@@ -134,7 +134,7 @@ bool PISystemMonitor::startOnProcess(int pID, int interval_ms) {
|
|||||||
|
|
||||||
|
|
||||||
bool PISystemMonitor::startOnSelf(int interval_ms) {
|
bool PISystemMonitor::startOnSelf(int interval_ms) {
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
bool ret = startOnProcess(PIProcess::currentPID(), interval_ms);
|
bool ret = startOnProcess(PIProcess::currentPID(), interval_ms);
|
||||||
cycle = -1;
|
cycle = -1;
|
||||||
#else
|
#else
|
||||||
@@ -145,9 +145,9 @@ bool PISystemMonitor::startOnSelf(int interval_ms) {
|
|||||||
|
|
||||||
|
|
||||||
PIVector<PISystemMonitor::ThreadStats> PISystemMonitor::threadsStatistic() const {
|
PIVector<PISystemMonitor::ThreadStats> PISystemMonitor::threadsStatistic() const {
|
||||||
mutex_.lock();
|
lock();
|
||||||
PIVector<PISystemMonitor::ThreadStats> ret = cur_ts;
|
PIVector<PISystemMonitor::ThreadStats> ret = cur_ts;
|
||||||
mutex_.unlock();
|
unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ void PISystemMonitor::run() {
|
|||||||
//piCout << tbid.keys().toType<uint>();
|
//piCout << tbid.keys().toType<uint>();
|
||||||
ProcessStats tstat;
|
ProcessStats tstat;
|
||||||
tstat.ID = pID_;
|
tstat.ID = pID_;
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
piForeach (PIThread * t, tv)
|
piForeach (PIThread * t, tv)
|
||||||
if (t->isPIObject())
|
if (t->isPIObject())
|
||||||
gatherThread(t->tid());
|
gatherThread(t->tid());
|
||||||
@@ -341,9 +341,9 @@ void PISystemMonitor::run() {
|
|||||||
//piCout << ts_new.cpu_load_user;
|
//piCout << ts_new.cpu_load_user;
|
||||||
}
|
}
|
||||||
last_tm = cur_tm;
|
last_tm = cur_tm;
|
||||||
mutex_.lock();
|
lock();
|
||||||
cur_ts = cur_tm.values();
|
cur_ts = cur_tm.values();
|
||||||
mutex_.unlock();
|
unlock();
|
||||||
tstat.ram_total = totalRAM();
|
tstat.ram_total = totalRAM();
|
||||||
tstat.ram_used = usedRAM();
|
tstat.ram_used = usedRAM();
|
||||||
tstat.ram_free = freeRAM();
|
tstat.ram_free = freeRAM();
|
||||||
@@ -357,7 +357,7 @@ void PISystemMonitor::run() {
|
|||||||
void PISystemMonitor::gatherThread(llong id) {
|
void PISystemMonitor::gatherThread(llong id) {
|
||||||
PISystemMonitor::ThreadStats ts;
|
PISystemMonitor::ThreadStats ts;
|
||||||
ts.id = id;
|
ts.id = id;
|
||||||
#ifdef FREERTOS
|
#ifdef MICRO_PIP
|
||||||
ts.name = tbid.value(id, "<PIThread>");
|
ts.name = tbid.value(id, "<PIThread>");
|
||||||
#else
|
#else
|
||||||
ts.name = tbid.value(id, "<non-PIThread>");
|
ts.name = tbid.value(id, "<non-PIThread>");
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
PIString name;
|
PIString name;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
bool startOnProcess(int pID, int interval_ms = 1000);
|
bool startOnProcess(int pID, int interval_ms = 1000);
|
||||||
#endif
|
#endif
|
||||||
bool startOnSelf(int interval_ms = 1000);
|
bool startOnSelf(int interval_ms = 1000);
|
||||||
@@ -106,7 +106,7 @@ private:
|
|||||||
PIMap<llong, PIString> tbid;
|
PIMap<llong, PIString> tbid;
|
||||||
mutable PIMutex stat_mutex;
|
mutable PIMutex stat_mutex;
|
||||||
int pID_, page_size, cpu_count, cycle;
|
int pID_, page_size, cpu_count, cycle;
|
||||||
#ifndef FREERTOS
|
#ifndef MICRO_PIP
|
||||||
PRIVATE_DECLARATION(PIP_EXPORT)
|
PRIVATE_DECLARATION(PIP_EXPORT)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
#include "pisystemtests.h"
|
#include "pisystemtests.h"
|
||||||
|
|
||||||
#ifndef PIP_FREERTOS
|
#ifndef MICRO_PIP
|
||||||
# include "piconfig.h"
|
# include "piconfig.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ namespace PISystemTests {
|
|||||||
|
|
||||||
|
|
||||||
PISystemTests::PISystemTestReader::PISystemTestReader() {
|
PISystemTests::PISystemTestReader::PISystemTestReader() {
|
||||||
#if !defined(WINDOWS) && !defined(FREERTOS)
|
#if !defined(WINDOWS) && !defined(MICRO_PIP)
|
||||||
PIConfig conf(PIStringAscii("/etc/pip.conf"), PIIODevice::ReadOnly);
|
PIConfig conf(PIStringAscii("/etc/pip.conf"), PIIODevice::ReadOnly);
|
||||||
time_resolution_ns = conf.getValue(PIStringAscii("time_resolution_ns"), 1).toLong();
|
time_resolution_ns = conf.getValue(PIStringAscii("time_resolution_ns"), 1).toLong();
|
||||||
time_elapsed_ns = conf.getValue(PIStringAscii("time_elapsed_ns"), 0).toLong();
|
time_elapsed_ns = conf.getValue(PIStringAscii("time_elapsed_ns"), 0).toLong();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "piconditionvar.h"
|
#include "piconditionvar.h"
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "pitime.h"
|
#include "pitime.h"
|
||||||
|
#include "piincludes_p.h"
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
# undef _WIN32_WINNT
|
# undef _WIN32_WINNT
|
||||||
# define _WIN32_WINNT 0x0600
|
# define _WIN32_WINNT 0x0600
|
||||||
@@ -28,27 +28,32 @@
|
|||||||
# include <windef.h>
|
# include <windef.h>
|
||||||
# include <winbase.h>
|
# include <winbase.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FREERTOS
|
||||||
|
# include <event_groups.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
PRIVATE_DEFINITION_START(PIConditionVariable)
|
PRIVATE_DEFINITION_START(PIConditionVariable)
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
CONDITION_VARIABLE nativeHandle;
|
CONDITION_VARIABLE
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
EventGroupHandle_t
|
||||||
#else
|
#else
|
||||||
pthread_cond_t nativeHandle;
|
pthread_cond_t
|
||||||
#endif
|
#endif
|
||||||
bool isDestroying;
|
nativeHandle;
|
||||||
PRIVATE_DEFINITION_END(PIConditionVariable)
|
PRIVATE_DEFINITION_END(PIConditionVariable)
|
||||||
|
|
||||||
|
|
||||||
PIConditionVariable::PIConditionVariable() {
|
PIConditionVariable::PIConditionVariable() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
InitializeConditionVariable(&PRIVATE->nativeHandle);
|
InitializeConditionVariable(&PRIVATE->nativeHandle);
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
PRIVATE->nativeHandle = xEventGroupCreate();
|
||||||
#else
|
#else
|
||||||
PRIVATE->isDestroying = false;
|
|
||||||
|
|
||||||
pthread_condattr_t condattr;
|
pthread_condattr_t condattr;
|
||||||
pthread_condattr_init(&condattr);
|
pthread_condattr_init(&condattr);
|
||||||
# ifndef MAC_OS
|
# if !defined(MAC_OS)
|
||||||
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
|
pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC);
|
||||||
# endif
|
# endif
|
||||||
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
|
memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle));
|
||||||
@@ -58,7 +63,9 @@ PIConditionVariable::PIConditionVariable() {
|
|||||||
|
|
||||||
|
|
||||||
PIConditionVariable::~PIConditionVariable() {
|
PIConditionVariable::~PIConditionVariable() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
vEventGroupDelete(PRIVATE->nativeHandle);
|
||||||
#else
|
#else
|
||||||
pthread_cond_destroy(&PRIVATE->nativeHandle);
|
pthread_cond_destroy(&PRIVATE->nativeHandle);
|
||||||
#endif
|
#endif
|
||||||
@@ -66,8 +73,11 @@ PIConditionVariable::~PIConditionVariable() {
|
|||||||
|
|
||||||
|
|
||||||
void PIConditionVariable::wait(PIMutex& lk) {
|
void PIConditionVariable::wait(PIMutex& lk) {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
|
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
|
||||||
|
xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, portMAX_DELAY);
|
||||||
#else
|
#else
|
||||||
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
|
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
|
||||||
#endif
|
#endif
|
||||||
@@ -79,20 +89,27 @@ void PIConditionVariable::wait(PIMutex& lk, const std::function<bool()>& conditi
|
|||||||
while (true) {
|
while (true) {
|
||||||
isCondition = condition();
|
isCondition = condition();
|
||||||
if (isCondition) break;
|
if (isCondition) break;
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
|
SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE);
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
|
||||||
|
xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, portMAX_DELAY);
|
||||||
#else
|
#else
|
||||||
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
|
pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle());
|
||||||
#endif
|
#endif
|
||||||
if (PRIVATE->isDestroying) return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) {
|
bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) {
|
||||||
bool isNotTimeout;
|
bool isNotTimeout;
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0;
|
isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0;
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
|
||||||
|
EventBits_t uxBits;
|
||||||
|
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, timeoutMs / portTICK_PERIOD_MS);
|
||||||
|
isNotTimeout = (uxBits & 1) != 0;
|
||||||
#else
|
#else
|
||||||
timespec expire_ts;
|
timespec expire_ts;
|
||||||
PISystemTime st = PISystemTime::current(true);
|
PISystemTime st = PISystemTime::current(true);
|
||||||
@@ -100,42 +117,50 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) {
|
|||||||
st.toTimespec(&expire_ts);
|
st.toTimespec(&expire_ts);
|
||||||
isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) == 0;
|
isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) == 0;
|
||||||
#endif
|
#endif
|
||||||
if (PRIVATE->isDestroying) return false;
|
|
||||||
return isNotTimeout;
|
return isNotTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function<bool()> &condition) {
|
bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function<bool()> &condition) {
|
||||||
bool isCondition;
|
bool isCondition;
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS) || defined(FREERTOS)
|
||||||
PITimeMeasurer measurer;
|
PITimeMeasurer measurer;
|
||||||
#else
|
#else
|
||||||
timespec expire_ts;
|
timespec expire_ts;
|
||||||
PISystemTime st = PISystemTime::current(true);
|
PISystemTime st = PISystemTime::current(true);
|
||||||
st.addMilliseconds(timeoutMs);
|
st.addMilliseconds(timeoutMs);
|
||||||
st.toTimespec(&expire_ts);
|
st.toTimespec(&expire_ts);
|
||||||
|
#endif
|
||||||
|
#ifdef FREERTOS
|
||||||
|
xEventGroupClearBits(PRIVATE->nativeHandle, 1);
|
||||||
#endif
|
#endif
|
||||||
while (true) {
|
while (true) {
|
||||||
isCondition = condition();
|
isCondition = condition();
|
||||||
if (isCondition) break;
|
if (isCondition) break;
|
||||||
#ifdef WINDOWS
|
bool isTimeout;
|
||||||
bool isTimeout = SleepConditionVariableCS(
|
#if defined(WINDOWS)
|
||||||
|
isTimeout = SleepConditionVariableCS(
|
||||||
&PRIVATE->nativeHandle,
|
&PRIVATE->nativeHandle,
|
||||||
(PCRITICAL_SECTION)lk.handle(),
|
(PCRITICAL_SECTION)lk.handle(),
|
||||||
timeoutMs - (int)measurer.elapsed_m()) == 0;
|
timeoutMs - (int)measurer.elapsed_m()) == 0;
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
EventBits_t uxBits;
|
||||||
|
uxBits = xEventGroupWaitBits(PRIVATE->nativeHandle, 1, pdTRUE, pdTRUE, (timeoutMs - (int)measurer.elapsed_m()) / portTICK_PERIOD_MS);
|
||||||
|
isTimeout = (uxBits & 1) == 0;
|
||||||
#else
|
#else
|
||||||
bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) != 0;
|
isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &expire_ts) != 0;
|
||||||
#endif
|
#endif
|
||||||
if (isTimeout) return false;
|
if (isTimeout) return false;
|
||||||
if (PRIVATE->isDestroying) return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIConditionVariable::notifyOne() {
|
void PIConditionVariable::notifyOne() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
WakeConditionVariable(&PRIVATE->nativeHandle);
|
WakeConditionVariable(&PRIVATE->nativeHandle);
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xEventGroupSetBits(PRIVATE->nativeHandle, 1);
|
||||||
#else
|
#else
|
||||||
pthread_cond_signal(&PRIVATE->nativeHandle);
|
pthread_cond_signal(&PRIVATE->nativeHandle);
|
||||||
#endif
|
#endif
|
||||||
@@ -143,8 +168,10 @@ void PIConditionVariable::notifyOne() {
|
|||||||
|
|
||||||
|
|
||||||
void PIConditionVariable::notifyAll() {
|
void PIConditionVariable::notifyAll() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
WakeAllConditionVariable(&PRIVATE->nativeHandle);
|
WakeAllConditionVariable(&PRIVATE->nativeHandle);
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xEventGroupSetBits(PRIVATE->nativeHandle, 1);
|
||||||
#else
|
#else
|
||||||
pthread_cond_broadcast(&PRIVATE->nativeHandle);
|
pthread_cond_broadcast(&PRIVATE->nativeHandle);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
piMSleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
diag_.received(1);
|
diag_.received(1);
|
||||||
|
|||||||
@@ -36,8 +36,10 @@
|
|||||||
|
|
||||||
#include "pimutex.h"
|
#include "pimutex.h"
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
# include <synchapi.h>
|
# include <synchapi.h>
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
# include <semphr.h>
|
||||||
#else
|
#else
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -45,8 +47,10 @@
|
|||||||
|
|
||||||
|
|
||||||
PRIVATE_DEFINITION_START(PIMutex)
|
PRIVATE_DEFINITION_START(PIMutex)
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
CRITICAL_SECTION
|
CRITICAL_SECTION
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
SemaphoreHandle_t
|
||||||
#else
|
#else
|
||||||
pthread_mutex_t
|
pthread_mutex_t
|
||||||
#endif
|
#endif
|
||||||
@@ -65,8 +69,10 @@ PIMutex::~PIMutex() {
|
|||||||
|
|
||||||
|
|
||||||
void PIMutex::lock() {
|
void PIMutex::lock() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
EnterCriticalSection(&(PRIVATE->mutex));
|
EnterCriticalSection(&(PRIVATE->mutex));
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xSemaphoreTake(PRIVATE->mutex, portMAX_DELAY);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_lock(&(PRIVATE->mutex));
|
pthread_mutex_lock(&(PRIVATE->mutex));
|
||||||
#endif
|
#endif
|
||||||
@@ -74,8 +80,10 @@ void PIMutex::lock() {
|
|||||||
|
|
||||||
|
|
||||||
void PIMutex::unlock() {
|
void PIMutex::unlock() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
LeaveCriticalSection(&(PRIVATE->mutex));
|
LeaveCriticalSection(&(PRIVATE->mutex));
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xSemaphoreGive(PRIVATE->mutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_unlock(&(PRIVATE->mutex));
|
pthread_mutex_unlock(&(PRIVATE->mutex));
|
||||||
#endif
|
#endif
|
||||||
@@ -84,8 +92,10 @@ void PIMutex::unlock() {
|
|||||||
|
|
||||||
bool PIMutex::tryLock() {
|
bool PIMutex::tryLock() {
|
||||||
bool ret =
|
bool ret =
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
(TryEnterCriticalSection(&(PRIVATE->mutex)) != 0);
|
(TryEnterCriticalSection(&(PRIVATE->mutex)) != 0);
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
xSemaphoreTake(PRIVATE->mutex, 0);
|
||||||
#else
|
#else
|
||||||
(pthread_mutex_trylock(&(PRIVATE->mutex)) == 0);
|
(pthread_mutex_trylock(&(PRIVATE->mutex)) == 0);
|
||||||
#endif
|
#endif
|
||||||
@@ -94,13 +104,19 @@ bool PIMutex::tryLock() {
|
|||||||
|
|
||||||
|
|
||||||
void * PIMutex::handle() {
|
void * PIMutex::handle() {
|
||||||
|
#ifdef FREERTOS
|
||||||
|
return PRIVATE->mutex;
|
||||||
|
#else
|
||||||
return (void*)&(PRIVATE->mutex);
|
return (void*)&(PRIVATE->mutex);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PIMutex::init() {
|
void PIMutex::init() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
InitializeCriticalSection(&(PRIVATE->mutex));
|
InitializeCriticalSection(&(PRIVATE->mutex));
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
PRIVATE->mutex = xSemaphoreCreateMutex();
|
||||||
#else
|
#else
|
||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
memset(&attr, 0, sizeof(attr));
|
memset(&attr, 0, sizeof(attr));
|
||||||
@@ -114,8 +130,10 @@ void PIMutex::init() {
|
|||||||
|
|
||||||
|
|
||||||
void PIMutex::destroy() {
|
void PIMutex::destroy() {
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
DeleteCriticalSection(&(PRIVATE->mutex));
|
DeleteCriticalSection(&(PRIVATE->mutex));
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
vSemaphoreDelete(PRIVATE->mutex);
|
||||||
#else
|
#else
|
||||||
pthread_mutex_destroy(&(PRIVATE->mutex));
|
pthread_mutex_destroy(&(PRIVATE->mutex));
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#define PIMUTEX_H
|
#define PIMUTEX_H
|
||||||
|
|
||||||
#include "piinit.h"
|
#include "piinit.h"
|
||||||
#include <mutex>
|
|
||||||
|
|
||||||
|
|
||||||
class PIP_EXPORT PIMutex
|
class PIP_EXPORT PIMutex
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "piqueue.h"
|
#include "piqueue.h"
|
||||||
|
#include "piconditionvar.h"
|
||||||
|
|
||||||
|
|
||||||
template <typename Tin, typename Tout>
|
template <typename Tin, typename Tout>
|
||||||
class PIPipelineThread : public PIThread
|
class PIPipelineThread : public PIThread
|
||||||
@@ -35,10 +37,10 @@ public:
|
|||||||
cnt = 0;
|
cnt = 0;
|
||||||
max_size = 0;
|
max_size = 0;
|
||||||
wait_next_pipe = false;
|
wait_next_pipe = false;
|
||||||
next_overload = false;
|
|
||||||
}
|
}
|
||||||
~PIPipelineThread() {
|
~PIPipelineThread() {
|
||||||
stop();
|
stop();
|
||||||
|
cv.notifyAll();
|
||||||
if (!waitForFinish(1000)) {
|
if (!waitForFinish(1000)) {
|
||||||
piCoutObj << "terminating self thread";
|
piCoutObj << "terminating self thread";
|
||||||
terminate();
|
terminate();
|
||||||
@@ -46,21 +48,27 @@ public:
|
|||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void connectTo(PIPipelineThread<Tout, T> * next) {
|
void connectTo(PIPipelineThread<Tout, T> * next) {
|
||||||
CONNECT2(void, Tout, bool *, this, calculated, next, enqueue)
|
CONNECT3(void, Tout, bool, bool *, this, calculated, next, enqueue)
|
||||||
}
|
}
|
||||||
EVENT2(calculated, const Tout &, v, bool *, overload)
|
EVENT3(calculated, const Tout &, v, bool, wait, bool *, overload)
|
||||||
void enqueue(const Tin &v) {enqueue(v, 0);}
|
EVENT_HANDLER3(void, enqueue, const Tin &, v, bool, wait, bool *, overload) {
|
||||||
EVENT_HANDLER2(void, enqueue, const Tin &, v, bool *, overload) {
|
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
//piCoutObj << "enque" << overload;
|
//piCoutObj << "enque" << overload;
|
||||||
|
if (wait && max_size != 0) {
|
||||||
|
mutex_wait.lock();
|
||||||
|
while (in.size() >= max_size) cv_wait.wait(mutex_wait);
|
||||||
|
mutex_wait.unlock();
|
||||||
|
}
|
||||||
if (max_size == 0 || in.size() < max_size) {
|
if (max_size == 0 || in.size() < max_size) {
|
||||||
in.enqueue(v);
|
in.enqueue(v);
|
||||||
|
cv.notifyAll();
|
||||||
if (overload) *overload = false;
|
if (overload) *overload = false;
|
||||||
} else {
|
} else {
|
||||||
if (overload) *overload = true;
|
if (overload) *overload = true;
|
||||||
}
|
}
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
void enqueue(const Tin &v, bool wait = false) {enqueue(v, wait, nullptr);}
|
||||||
const ullong * counterPtr() const {return &cnt;}
|
const ullong * counterPtr() const {return &cnt;}
|
||||||
ullong counter() const {return cnt;}
|
ullong counter() const {return cnt;}
|
||||||
bool isEmpty() {
|
bool isEmpty() {
|
||||||
@@ -79,15 +87,18 @@ public:
|
|||||||
}
|
}
|
||||||
void clear() {
|
void clear() {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
|
mutex_wait.lock();
|
||||||
in.clear();
|
in.clear();
|
||||||
next_overload = false;
|
cv_wait.notifyAll();
|
||||||
|
mutex_wait.unlock();
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
void stopCalc(int wait_delay = 100) {
|
void stopCalc(int wait_delay = 100) {
|
||||||
if (isRunning()) {
|
if (isRunning()) {
|
||||||
stop();
|
stop();
|
||||||
|
cv.notifyAll();
|
||||||
if (!waitForFinish(wait_delay)) {
|
if (!waitForFinish(wait_delay)) {
|
||||||
mutex_l.unlock();
|
mutex_last.unlock();
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
terminate();
|
terminate();
|
||||||
}
|
}
|
||||||
@@ -95,18 +106,14 @@ public:
|
|||||||
}
|
}
|
||||||
Tout getLast() {
|
Tout getLast() {
|
||||||
Tout ret;
|
Tout ret;
|
||||||
mutex_l.lock();
|
mutex_last.lock();
|
||||||
ret = last;
|
ret = last;
|
||||||
mutex_l.unlock();
|
mutex_last.unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint maxQueSize() {
|
uint maxQueSize() {
|
||||||
uint ret;
|
return max_size;
|
||||||
mutex.lock();
|
|
||||||
ret = max_size;
|
|
||||||
mutex.unlock();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMaxQueSize(uint count) {
|
void setMaxQueSize(uint count) {
|
||||||
@@ -127,39 +134,35 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void begin() {cnt = 0;}
|
void begin() {cnt = 0;}
|
||||||
void run() {
|
void run() {
|
||||||
//piCoutObj << "run ...";
|
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
if (in.isEmpty()) {
|
while (in.isEmpty()) {
|
||||||
mutex.unlock();
|
cv.wait(mutex);
|
||||||
piMSleep(10);
|
if (terminating) {
|
||||||
//piCoutObj << "run in empty";
|
mutex.unlock();
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (next_overload && wait_next_pipe) {
|
|
||||||
mutex.unlock();
|
|
||||||
//piCoutObj << "wait" << &next_overload;
|
|
||||||
calculated(last, &next_overload);
|
|
||||||
piMSleep(10);
|
|
||||||
} else {
|
|
||||||
Tin t = in.dequeue();
|
|
||||||
mutex.unlock();
|
|
||||||
bool ok = true;
|
|
||||||
Tout r = calc(t, ok);
|
|
||||||
if (ok) {
|
|
||||||
mutex_l.lock();
|
|
||||||
last = r;
|
|
||||||
mutex_l.unlock();
|
|
||||||
cnt++;
|
|
||||||
//piCoutObj << "calc ok" << &next_overload;
|
|
||||||
calculated(r, &next_overload);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mutex_wait.lock();
|
||||||
|
Tin t = in.dequeue();
|
||||||
|
mutex.unlock();
|
||||||
|
cv_wait.notifyAll();
|
||||||
|
mutex_wait.unlock();
|
||||||
|
bool ok = true;
|
||||||
|
Tout r = calc(t, ok);
|
||||||
|
if (ok) {
|
||||||
|
mutex_last.lock();
|
||||||
|
last = r;
|
||||||
|
mutex_last.unlock();
|
||||||
|
cnt++;
|
||||||
|
//piCoutObj << "calc ok";
|
||||||
|
calculated(r, wait_next_pipe);
|
||||||
|
}
|
||||||
//piCoutObj << "run ok";
|
//piCoutObj << "run ok";
|
||||||
}
|
}
|
||||||
PIMutex mutex;
|
PIMutex mutex, mutex_wait;
|
||||||
PIMutex mutex_l;
|
PIConditionVariable cv, cv_wait;
|
||||||
|
PIMutex mutex_last;
|
||||||
bool wait_next_pipe;
|
bool wait_next_pipe;
|
||||||
bool next_overload;
|
|
||||||
ullong cnt;
|
ullong cnt;
|
||||||
PIQueue<Tin> in;
|
PIQueue<Tin> in;
|
||||||
Tout last;
|
Tout last;
|
||||||
|
|||||||
@@ -19,27 +19,40 @@
|
|||||||
|
|
||||||
#include "piincludes_p.h"
|
#include "piincludes_p.h"
|
||||||
#include "pithread.h"
|
#include "pithread.h"
|
||||||
#include "pisystemtests.h"
|
|
||||||
#include "piintrospection_threads.h"
|
#include "piintrospection_threads.h"
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
# include "pisystemtests.h"
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#ifdef WINDOWS
|
#if defined(WINDOWS)
|
||||||
# define __THREAD_FUNC_RET__ uint __stdcall
|
# define __THREAD_FUNC_RET__ uint __stdcall
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
# define __THREAD_FUNC_RET__ void
|
||||||
#else
|
#else
|
||||||
# define __THREAD_FUNC_RET__ void*
|
# define __THREAD_FUNC_RET__ void*
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FREERTOS
|
||||||
|
# define __THREAD_FUNC_END__ 0
|
||||||
|
#else
|
||||||
|
# define __THREAD_FUNC_END__
|
||||||
|
#endif
|
||||||
#if defined(LINUX)
|
#if defined(LINUX)
|
||||||
# include <sys/syscall.h>
|
# include <sys/syscall.h>
|
||||||
# define gettid() syscall(SYS_gettid)
|
# define gettid() syscall(SYS_gettid)
|
||||||
#endif
|
#endif
|
||||||
#if defined(MAC_OS) || defined(BLACKBERRY) || defined(FREERTOS)
|
#if defined(MAC_OS) || defined(BLACKBERRY)
|
||||||
# include <pthread.h>
|
# include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return 0;}
|
__THREAD_FUNC_RET__ thread_function(void * t) {((PIThread*)t)->__thread_func__(); return __THREAD_FUNC_END__;}
|
||||||
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return 0;}
|
__THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_func_once__(); return __THREAD_FUNC_END__;}
|
||||||
|
|
||||||
#define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
|
|
||||||
#define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
|
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
# define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
|
||||||
|
# define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
|
||||||
|
#else
|
||||||
|
# define REGISTER_THREAD(t)
|
||||||
|
# define UNREGISTER_THREAD(t)
|
||||||
|
#endif
|
||||||
|
|
||||||
/*! \class PIThread
|
/*! \class PIThread
|
||||||
* @brief Thread class
|
* @brief Thread class
|
||||||
@@ -63,7 +76,7 @@ event started();
|
|||||||
while (isRunning()) {
|
while (isRunning()) {
|
||||||
run();
|
run();
|
||||||
ThreadFunc();
|
ThreadFunc();
|
||||||
msleep(timer_delay);
|
piMSleep(timer_delay);
|
||||||
}
|
}
|
||||||
event stopped();
|
event stopped();
|
||||||
end();
|
end();
|
||||||
@@ -90,6 +103,7 @@ end();
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
|
|
||||||
__PIThreadCollection *__PIThreadCollection::instance() {
|
__PIThreadCollection *__PIThreadCollection::instance() {
|
||||||
return __PIThreadCollection_Initializer__::__instance__;
|
return __PIThreadCollection_Initializer__::__instance__;
|
||||||
@@ -158,15 +172,17 @@ __PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // MICRO_PIP
|
||||||
|
|
||||||
|
|
||||||
PRIVATE_DEFINITION_START(PIThread)
|
PRIVATE_DEFINITION_START(PIThread)
|
||||||
#ifndef WINDOWS
|
#if defined(WINDOWS)
|
||||||
|
void * thread;
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
TaskHandle_t thread;
|
||||||
|
#else
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
sched_param sparam;
|
sched_param sparam;
|
||||||
#else
|
|
||||||
void * thread;
|
|
||||||
#endif
|
#endif
|
||||||
PRIVATE_DEFINITION_END(PIThread)
|
PRIVATE_DEFINITION_END(PIThread)
|
||||||
|
|
||||||
@@ -267,22 +283,22 @@ void PIThread::terminate() {
|
|||||||
terminating = running_ = false;
|
terminating = running_ = false;
|
||||||
tid_ = -1;
|
tid_ = -1;
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
|
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
|
||||||
#ifndef WINDOWS
|
# ifndef WINDOWS
|
||||||
# ifdef ANDROID
|
# ifdef ANDROID
|
||||||
pthread_kill(PRIVATE->thread, SIGTERM);
|
pthread_kill(PRIVATE->thread, SIGTERM);
|
||||||
# else
|
# else
|
||||||
//pthread_kill(PRIVATE->thread, SIGKILL);
|
//pthread_kill(PRIVATE->thread, SIGKILL);
|
||||||
//void * ret(0);
|
//void * ret(0);
|
||||||
pthread_cancel(PRIVATE->thread);
|
pthread_cancel(PRIVATE->thread);
|
||||||
//pthread_join(PRIVATE->thread, &ret);
|
//pthread_join(PRIVATE->thread, &ret);
|
||||||
# endif
|
# endif
|
||||||
#else
|
# else
|
||||||
TerminateThread(PRIVATE->thread, 0);
|
TerminateThread(PRIVATE->thread, 0);
|
||||||
CloseHandle(PRIVATE->thread);
|
CloseHandle(PRIVATE->thread);
|
||||||
#endif
|
# endif
|
||||||
PRIVATE->thread = 0;
|
PRIVATE->thread = 0;
|
||||||
end();
|
end();
|
||||||
#endif
|
#endif //FREERTOS
|
||||||
PIINTROSPECTION_THREAD_STOP(this);
|
PIINTROSPECTION_THREAD_STOP(this);
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
|
||||||
}
|
}
|
||||||
@@ -290,27 +306,31 @@ void PIThread::terminate() {
|
|||||||
|
|
||||||
int PIThread::priority2System(PIThread::Priority p) {
|
int PIThread::priority2System(PIThread::Priority p) {
|
||||||
switch (p) {
|
switch (p) {
|
||||||
# ifdef QNX
|
#if defined(QNX)
|
||||||
case piLowerst: return 8;
|
case piLowerst: return 8;
|
||||||
case piLow: return 9;
|
case piLow: return 9;
|
||||||
case piNormal: return 10;
|
case piNormal: return 10;
|
||||||
case piHigh: return 11;
|
case piHigh: return 11;
|
||||||
case piHighest: return 12;
|
case piHighest: return 12;
|
||||||
# else
|
#elif defined(WINDOWS)
|
||||||
# ifdef WINDOWS
|
|
||||||
case piLowerst: return -2;
|
case piLowerst: return -2;
|
||||||
case piLow: return -1;
|
case piLow: return -1;
|
||||||
case piNormal: return 0;
|
case piNormal: return 0;
|
||||||
case piHigh: return 1;
|
case piHigh: return 1;
|
||||||
case piHighest: return 2;
|
case piHighest: return 2;
|
||||||
# else
|
#elif defined(FREERTOS)
|
||||||
|
case piLowerst: return 2;
|
||||||
|
case piLow: return 3;
|
||||||
|
case piNormal: return 4;
|
||||||
|
case piHigh: return 5;
|
||||||
|
case piHighest: return 6;
|
||||||
|
#else
|
||||||
case piLowerst: return 2;
|
case piLowerst: return 2;
|
||||||
case piLow: return 1;
|
case piLow: return 1;
|
||||||
case piNormal: return 0;
|
case piNormal: return 0;
|
||||||
case piHigh: return -1;
|
case piHigh: return -1;
|
||||||
case piHighest: return -2;
|
case piHighest: return -2;
|
||||||
# endif
|
#endif
|
||||||
# endif
|
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -320,34 +340,44 @@ int PIThread::priority2System(PIThread::Priority p) {
|
|||||||
bool PIThread::_startThread(void * func) {
|
bool PIThread::_startThread(void * func) {
|
||||||
terminating = false;
|
terminating = false;
|
||||||
running_ = true;
|
running_ = true;
|
||||||
#ifndef WINDOWS
|
#if !defined(WINDOWS) && !defined(FREERTOS)
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
int ret = pthread_create(&PRIVATE->thread, &attr, (void*(*)(void*))func, this);
|
int ret = pthread_create(&PRIVATE->thread, &attr, (__THREAD_FUNC_RET__(*)(void*))func, this);
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
|
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
# ifdef MAC_OS
|
# ifdef MAC_OS
|
||||||
pthread_setname_np(((PIString&)name().elided(15, 0.4f).resize(15, '\0')).dataAscii());
|
pthread_setname_np(((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
|
||||||
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
|
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
|
||||||
# else
|
# else
|
||||||
# ifdef FREERTOS
|
pthread_setname_np(PRIVATE->thread, ((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
|
||||||
tid_ = PRIVATE->thread;
|
|
||||||
# else
|
|
||||||
pthread_setname_np(PRIVATE->thread, ((PIString&)name().elided(15, 0.4f).resize(15, '\0')).dataAscii());
|
|
||||||
# endif
|
|
||||||
# endif
|
# endif
|
||||||
#else
|
#endif
|
||||||
|
#ifdef WINDOWS
|
||||||
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
|
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
|
||||||
# ifdef CC_GCC
|
# ifdef CC_GCC
|
||||||
PRIVATE->thread = (void *)_beginthreadex(0, 0, (unsigned(__stdcall*)(void*))func, this, 0, 0);
|
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void*))func, this, 0, 0);
|
||||||
# else
|
# else
|
||||||
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
|
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
|
||||||
# endif
|
# endif
|
||||||
if (PRIVATE->thread != 0) {
|
if (PRIVATE->thread != 0) {
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef FREERTOS
|
||||||
|
if (xTaskCreate(
|
||||||
|
(__THREAD_FUNC_RET__(*)(void*))func,
|
||||||
|
((PIString&)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii(), // A name just for humans
|
||||||
|
128, // This stack size can be checked & adjusted by reading the Stack Highwater
|
||||||
|
this,
|
||||||
|
priority_,
|
||||||
|
&PRIVATE->thread
|
||||||
|
) == pdPASS) {
|
||||||
|
tid_ = (llong)PRIVATE->thread;
|
||||||
|
#endif
|
||||||
|
#ifndef FREERTOS
|
||||||
setPriority(priority_);
|
setPriority(priority_);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
running_ = false;
|
running_ = false;
|
||||||
@@ -360,10 +390,12 @@ bool PIThread::_startThread(void * func) {
|
|||||||
|
|
||||||
|
|
||||||
void PIThread::setPriority(PIThread::Priority prior) {
|
void PIThread::setPriority(PIThread::Priority prior) {
|
||||||
#ifndef FREERTOS // FreeRTOS can't change priority runtime
|
|
||||||
priority_ = prior;
|
priority_ = prior;
|
||||||
# ifndef WINDOWS
|
|
||||||
if (!running_ || (PRIVATE->thread == 0)) return;
|
if (!running_ || (PRIVATE->thread == 0)) return;
|
||||||
|
#ifdef FREERTOS
|
||||||
|
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
|
||||||
|
#else
|
||||||
|
# ifndef WINDOWS
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
|
//PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
|
||||||
policy_ = 0;
|
policy_ = 0;
|
||||||
memset(&(PRIVATE->sparam), 0, sizeof(PRIVATE->sparam));
|
memset(&(PRIVATE->sparam), 0, sizeof(PRIVATE->sparam));
|
||||||
@@ -402,7 +434,7 @@ bool PIThread::waitForFinish(int timeout_msecs) {
|
|||||||
if (!running_) return true;
|
if (!running_) return true;
|
||||||
if (timeout_msecs < 0) {
|
if (timeout_msecs < 0) {
|
||||||
while (running_) {
|
while (running_) {
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (!isExists(PRIVATE->thread)) {
|
if (!isExists(PRIVATE->thread)) {
|
||||||
unlock();
|
unlock();
|
||||||
@@ -414,7 +446,7 @@ bool PIThread::waitForFinish(int timeout_msecs) {
|
|||||||
}
|
}
|
||||||
tmf_.reset();
|
tmf_.reset();
|
||||||
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
|
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
if (!isExists(PRIVATE->thread)) {
|
if (!isExists(PRIVATE->thread)) {
|
||||||
unlock();
|
unlock();
|
||||||
@@ -430,12 +462,12 @@ bool PIThread::waitForStart(int timeout_msecs) {
|
|||||||
if (running_) return true;
|
if (running_) return true;
|
||||||
if (timeout_msecs < 0) {
|
if (timeout_msecs < 0) {
|
||||||
while (!running_)
|
while (!running_)
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
tms_.reset();
|
tms_.reset();
|
||||||
while (!running_ && tms_.elapsed_m() < timeout_msecs)
|
while (!running_ && tms_.elapsed_m() < timeout_msecs)
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return tms_.elapsed_m() < timeout_msecs;
|
return tms_.elapsed_m() < timeout_msecs;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,9 +488,9 @@ void PIThread::_beginThread() {
|
|||||||
PIINTROSPECTION_THREAD_START(this);
|
PIINTROSPECTION_THREAD_START(this);
|
||||||
REGISTER_THREAD(this);
|
REGISTER_THREAD(this);
|
||||||
running_ = true;
|
running_ = true;
|
||||||
if (lockRun) mutex_.lock();
|
if (lockRun) thread_mutex.lock();
|
||||||
begin();
|
begin();
|
||||||
if (lockRun) mutex_.unlock();
|
if (lockRun) thread_mutex.unlock();
|
||||||
started();
|
started();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -466,7 +498,7 @@ void PIThread::_beginThread() {
|
|||||||
void PIThread::_runThread() {
|
void PIThread::_runThread() {
|
||||||
PIINTROSPECTION_THREAD_RUN(this);
|
PIINTROSPECTION_THREAD_RUN(this);
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
|
||||||
if (lockRun) mutex_.lock();
|
if (lockRun) thread_mutex.lock();
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
|
||||||
#ifdef PIP_INTROSPECTION
|
#ifdef PIP_INTROSPECTION
|
||||||
@@ -482,7 +514,7 @@ void PIThread::_runThread() {
|
|||||||
if (ret_func != 0) ret_func(data_);
|
if (ret_func != 0) ret_func(data_);
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
|
||||||
if (lockRun) mutex_.unlock();
|
if (lockRun) thread_mutex.unlock();
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,11 +523,11 @@ void PIThread::_endThread() {
|
|||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
|
||||||
stopped();
|
stopped();
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
||||||
if (lockRun) mutex_.lock();
|
if (lockRun) thread_mutex.lock();
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
|
||||||
end();
|
end();
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
|
||||||
if (lockRun) mutex_.unlock();
|
if (lockRun) thread_mutex.unlock();
|
||||||
terminating = running_ = false;
|
terminating = running_ = false;
|
||||||
tid_ = -1;
|
tid_ = -1;
|
||||||
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
|
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
|
||||||
@@ -503,18 +535,18 @@ void PIThread::_endThread() {
|
|||||||
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
|
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
|
||||||
UNREGISTER_THREAD(this);
|
UNREGISTER_THREAD(this);
|
||||||
PIINTROSPECTION_THREAD_STOP(this);
|
PIINTROSPECTION_THREAD_STOP(this);
|
||||||
#ifndef WINDOWS
|
#if defined(WINDOWS)
|
||||||
pthread_detach(PRIVATE->thread);
|
|
||||||
PRIVATE->thread = 0;
|
|
||||||
#endif
|
|
||||||
#ifndef WINDOWS
|
|
||||||
pthread_exit(0);
|
|
||||||
#else
|
|
||||||
# ifdef CC_GCC
|
# ifdef CC_GCC
|
||||||
_endthreadex(0);
|
_endthreadex(0);
|
||||||
# else
|
# else
|
||||||
ExitThread(0);
|
ExitThread(0);
|
||||||
# endif
|
# endif
|
||||||
|
#elif defined(FREERTOS)
|
||||||
|
PRIVATE->thread = 0;
|
||||||
|
#else
|
||||||
|
pthread_detach(PRIVATE->thread);
|
||||||
|
PRIVATE->thread = 0;
|
||||||
|
pthread_exit(0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -554,12 +586,14 @@ void PIThread::__thread_func_once__() {
|
|||||||
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
|
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
|
||||||
PIThread * t = new PIThread();
|
PIThread * t = new PIThread();
|
||||||
t->setName(name);
|
t->setName(name);
|
||||||
if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce")) {
|
if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce").isValid()) {
|
||||||
delete t;
|
delete t;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifndef MICRO_PIP
|
||||||
__PIThreadCollection::instance()->startedAuto(t);
|
__PIThreadCollection::instance()->startedAuto(t);
|
||||||
CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto);
|
CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto);
|
||||||
|
#endif
|
||||||
t->startOnce();
|
t->startOnce();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -568,8 +602,10 @@ void PIThread::runOnce(std::function<void ()> func, const PIString & name) {
|
|||||||
PIThread * t = new PIThread();
|
PIThread * t = new PIThread();
|
||||||
t->setName(name);
|
t->setName(name);
|
||||||
t->setSlot(func);
|
t->setSlot(func);
|
||||||
|
#ifndef MICRO_PIP
|
||||||
__PIThreadCollection::instance()->startedAuto(t);
|
__PIThreadCollection::instance()->startedAuto(t);
|
||||||
CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto);
|
CONNECTU(t, stopped, __PIThreadCollection::instance(), stoppedAuto);
|
||||||
|
#endif
|
||||||
t->startOnce();
|
t->startOnce();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
#include "piobject.h"
|
#include "piobject.h"
|
||||||
|
|
||||||
class PIThread;
|
class PIThread;
|
||||||
|
|
||||||
|
#ifndef MICRO_PIP
|
||||||
class PIIntrospectionThreads;
|
class PIIntrospectionThreads;
|
||||||
|
|
||||||
class PIP_EXPORT __PIThreadCollection: public PIObject {
|
class PIP_EXPORT __PIThreadCollection: public PIObject {
|
||||||
@@ -58,14 +60,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__;
|
static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__;
|
||||||
|
#endif // MICRO_PIP
|
||||||
|
|
||||||
typedef std::function<void(void *)> ThreadFunc;
|
typedef std::function<void(void *)> ThreadFunc;
|
||||||
|
|
||||||
class PIP_EXPORT PIThread: public PIObject
|
class PIP_EXPORT PIThread: public PIObject
|
||||||
{
|
{
|
||||||
PIOBJECT_SUBCLASS(PIThread, PIObject)
|
PIOBJECT_SUBCLASS(PIThread, PIObject)
|
||||||
|
#ifndef MICRO_PIP
|
||||||
friend class PIIntrospectionThreads;
|
friend class PIIntrospectionThreads;
|
||||||
|
#endif
|
||||||
public:
|
public:
|
||||||
NO_COPY_CLASS(PIThread)
|
NO_COPY_CLASS(PIThread)
|
||||||
|
|
||||||
@@ -131,11 +135,15 @@ public:
|
|||||||
|
|
||||||
//! @brief Set necessity of lock every \a run with internal mutex
|
//! @brief Set necessity of lock every \a run with internal mutex
|
||||||
void needLockRun(bool need) {lockRun = need;}
|
void needLockRun(bool need) {lockRun = need;}
|
||||||
EVENT_HANDLER0(void, lock) {mutex_.lock();}
|
|
||||||
EVENT_HANDLER0(void, unlock) {mutex_.unlock();}
|
//! @brief Lock internal mutex
|
||||||
|
EVENT_HANDLER0(void, lock) const {thread_mutex.lock();}
|
||||||
|
|
||||||
|
//! @brief Unlock internal mutex
|
||||||
|
EVENT_HANDLER0(void, unlock) const {thread_mutex.unlock();}
|
||||||
|
|
||||||
//! @brief Returns internal mutex
|
//! @brief Returns internal mutex
|
||||||
PIMutex & mutex() {return mutex_;}
|
PIMutex & mutex() const {return thread_mutex;}
|
||||||
|
|
||||||
//! @brief Returns thread ID
|
//! @brief Returns thread ID
|
||||||
llong tid() const {return tid_;}
|
llong tid() const {return tid_;}
|
||||||
@@ -239,7 +247,7 @@ protected:
|
|||||||
int delay_, policy_;
|
int delay_, policy_;
|
||||||
llong tid_;
|
llong tid_;
|
||||||
void * data_;
|
void * data_;
|
||||||
mutable PIMutex mutex_;
|
mutable PIMutex thread_mutex;
|
||||||
PITimeMeasurer tmf_, tms_, tmr_;
|
PITimeMeasurer tmf_, tms_, tmr_;
|
||||||
PIThread::Priority priority_;
|
PIThread::Priority priority_;
|
||||||
ThreadFunc ret_func;
|
ThreadFunc ret_func;
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
#include "pitimer.h"
|
#include "pitimer.h"
|
||||||
#include "pipipelinethread.h"
|
#include "pipipelinethread.h"
|
||||||
#include "pigrabberbase.h"
|
#include "pigrabberbase.h"
|
||||||
#include "pithreadpoolexecutor.h"
|
|
||||||
#include "piconditionvar.h"
|
#include "piconditionvar.h"
|
||||||
|
#include "pithreadpoolexecutor.h"
|
||||||
|
#include "pithreadpoolloop.h"
|
||||||
|
#include "pithreadnotifier.h"
|
||||||
|
|
||||||
#endif // PITHREADMODULE_H
|
#endif // PITHREADMODULE_H
|
||||||
|
|||||||
39
libs/main/thread/pithreadnotifier.cpp
Normal file
39
libs/main/thread/pithreadnotifier.cpp
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Class for simply notify and wait in different threads
|
||||||
|
Andrey Bychkov work.a.b@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pithreadnotifier.h"
|
||||||
|
|
||||||
|
|
||||||
|
PIThreadNotifier::PIThreadNotifier() : cnt(0) {}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadNotifier::wait() {
|
||||||
|
m.lock();
|
||||||
|
while (cnt == 0) v.wait(m);
|
||||||
|
cnt--;
|
||||||
|
m.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadNotifier::notifyOnce() {
|
||||||
|
m.lock();
|
||||||
|
cnt++;
|
||||||
|
v.notifyAll();
|
||||||
|
m.unlock();
|
||||||
|
}
|
||||||
52
libs/main/thread/pithreadnotifier.h
Normal file
52
libs/main/thread/pithreadnotifier.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*! @file pithreadnotifier.h
|
||||||
|
* @brief Class for simply notify and wait in different threads
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Class for simply notify and wait in different threads
|
||||||
|
Andrey Bychkov work.a.b@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PITHREADNOTIFIER_H
|
||||||
|
#define PITHREADNOTIFIER_H
|
||||||
|
|
||||||
|
#include "piconditionvar.h"
|
||||||
|
|
||||||
|
|
||||||
|
class PIP_EXPORT PIThreadNotifier {
|
||||||
|
public:
|
||||||
|
PIThreadNotifier();
|
||||||
|
|
||||||
|
//! Start waiting, return if other thread call \a notifyOnce().
|
||||||
|
//! If \a notifyOnce() has been called before, then returns immediately.
|
||||||
|
//! If notifyOnce() has been called "n" times, then returns immediately "n" times,
|
||||||
|
//! but only if wait in one thread.
|
||||||
|
//! If many threads waiting, then If notifyOnce() has been called "n" times,
|
||||||
|
//! All threads total returns "n" times in random sequence.
|
||||||
|
void wait();
|
||||||
|
|
||||||
|
//! Notify one waiting thread, wich waiting on \a wait() function.
|
||||||
|
//! If many threads waiting, then notify randomly one.
|
||||||
|
//! If call this "n" times, then notify any waiting threads totally "n" times.
|
||||||
|
void notifyOnce();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ullong cnt;
|
||||||
|
PIMutex m;
|
||||||
|
PIConditionVariable v;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PITHREADNOTIFIER_H
|
||||||
130
libs/main/thread/pithreadpoolloop.cpp
Normal file
130
libs/main/thread/pithreadpoolloop.cpp
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Thread pool loop
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "pithreadpoolloop.h"
|
||||||
|
#include "pisysteminfo.h"
|
||||||
|
#include "pithread.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*! \class PIThreadPoolLoop
|
||||||
|
* @brief Thread class
|
||||||
|
* \details This class allow you parallelize loop.
|
||||||
|
*
|
||||||
|
* \section PIThreadPoolLoop_sec0 Usage
|
||||||
|
* This class designed to replace "for(;;)" statement in very simple way.
|
||||||
|
* In constructor several threads created, then by "setFunction()" method
|
||||||
|
* you should pass body of your loop, and then call "start()" or "exec()".
|
||||||
|
* Every thread take loop counter and execute your function until all
|
||||||
|
* counter range is passed.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
\code{.cpp}
|
||||||
|
PIVector<int> data(10, [](int i)->int{return i;});
|
||||||
|
|
||||||
|
piCout << data; // {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
|
||||||
|
PIThreadPoolLoop pool;
|
||||||
|
pool.exec(0, data.size(), [&](int i){ // parallel analogue "for (int i = 0; i < data.size(); i++)"
|
||||||
|
data[i] = data[i] + 10;
|
||||||
|
});
|
||||||
|
|
||||||
|
piCout << data; // {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
|
||||||
|
\endcode
|
||||||
|
*
|
||||||
|
* Equivalent to:
|
||||||
|
\code{.cpp}
|
||||||
|
PIVector<int> data(10, [](int i)->int{return i;});
|
||||||
|
|
||||||
|
piCout << data; // {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||||
|
|
||||||
|
pool.setFunction([&](int i){
|
||||||
|
data[i] = data[i] + 10;
|
||||||
|
});
|
||||||
|
pool.exec(0, data.size());
|
||||||
|
|
||||||
|
piCout << data; // {10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
|
||||||
|
\endcode
|
||||||
|
*
|
||||||
|
* \section PIThreadPoolLoop_sec1 Important
|
||||||
|
* Due to multithreading it`s very important to protect output data of loop body, use mutex.
|
||||||
|
* Also remember that execution order is undefined and you shouldn`t use global variables in
|
||||||
|
* your function. Use local variables and lambda capture.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
PIThreadPoolLoop::PIThreadPoolLoop(int thread_cnt) {
|
||||||
|
if (thread_cnt <= 0)
|
||||||
|
thread_cnt = piMaxi(1, PISystemInfo::instance()->processorsCount);
|
||||||
|
piForTimes (thread_cnt) {
|
||||||
|
auto * t = new PIThread();
|
||||||
|
threads << t;
|
||||||
|
}
|
||||||
|
//piCout << "PIThreadPoolLoop" << proc_cnt << "threads";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIThreadPoolLoop::~PIThreadPoolLoop() {
|
||||||
|
for (auto * t: threads) {
|
||||||
|
t->stop(false);
|
||||||
|
if (!t->waitForFinish(100))
|
||||||
|
t->terminate();
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadPoolLoop::setFunction(std::function<void (int)> f) {
|
||||||
|
func = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadPoolLoop::start(int index_start, int index_count) {
|
||||||
|
counter = index_start;
|
||||||
|
int end = index_start + index_count;
|
||||||
|
for (auto * t: threads)
|
||||||
|
t->start([this,end,t](){
|
||||||
|
while (1) {
|
||||||
|
int cc = counter.fetch_add(1);
|
||||||
|
if (cc >= end) {
|
||||||
|
t->stop(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
func(cc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadPoolLoop::exec(int index_start, int index_count) {
|
||||||
|
start(index_start, index_count);
|
||||||
|
wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadPoolLoop::exec(int index_start, int index_count, std::function<void (int)> f) {
|
||||||
|
setFunction(f);
|
||||||
|
exec(index_start, index_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PIThreadPoolLoop::wait() {
|
||||||
|
for (auto * t: threads)
|
||||||
|
t->waitForFinish();
|
||||||
|
}
|
||||||
69
libs/main/thread/pithreadpoolloop.h
Normal file
69
libs/main/thread/pithreadpoolloop.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*! @file pithreadpoolloop.h
|
||||||
|
* @brief Thread pool loop
|
||||||
|
*
|
||||||
|
* This file declare thread class and some wait functions
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
PIP - Platform Independent Primitives
|
||||||
|
Thread pool loop
|
||||||
|
Ivan Pelipenko peri4ko@yandex.ru
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PITHREADPOOLLOOP_H
|
||||||
|
#define PITHREADPOOLLOOP_H
|
||||||
|
|
||||||
|
#include "pivector.h"
|
||||||
|
|
||||||
|
class PIThread;
|
||||||
|
|
||||||
|
class PIP_EXPORT PIThreadPoolLoop {
|
||||||
|
public:
|
||||||
|
|
||||||
|
//! Contructs thread pool with threads count "thread_cnt".
|
||||||
|
//! If "thread_cnt" = -1 then system processors count used
|
||||||
|
PIThreadPoolLoop(int thread_cnt = -1);
|
||||||
|
|
||||||
|
virtual ~PIThreadPoolLoop();
|
||||||
|
|
||||||
|
//! Set threads function to "f" with format [](int){...}
|
||||||
|
void setFunction(std::function<void(int)> f);
|
||||||
|
|
||||||
|
//! Wait for all threads stop
|
||||||
|
void wait();
|
||||||
|
|
||||||
|
//! Start functions execution with integer argument range
|
||||||
|
//! from "index_start" to "index_start + index_count - 1"
|
||||||
|
void start(int index_start, int index_count);
|
||||||
|
|
||||||
|
//! Start functions execution with integer argument range
|
||||||
|
//! from "index_start" to "index_start + index_count - 1"
|
||||||
|
//! and wait for finish
|
||||||
|
void exec(int index_start, int index_count);
|
||||||
|
|
||||||
|
//! Start functions "f" execution with integer argument range
|
||||||
|
//! from "index_start" to "index_start + index_count - 1"
|
||||||
|
//! and wait for finish
|
||||||
|
void exec(int index_start, int index_count, std::function<void(int)> f);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PIVector<PIThread * > threads;
|
||||||
|
std::function<void(int)> func;
|
||||||
|
std::atomic_int counter;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -648,11 +648,11 @@ bool PITimer::stop(bool wait) {
|
|||||||
bool PITimer::waitForFinish(int timeout_msecs) {
|
bool PITimer::waitForFinish(int timeout_msecs) {
|
||||||
if (timeout_msecs < 0) {
|
if (timeout_msecs < 0) {
|
||||||
while (isRunning())
|
while (isRunning())
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
PITimeMeasurer tm;
|
PITimeMeasurer tm;
|
||||||
while (isRunning() && tm.elapsed_m() < timeout_msecs)
|
while (isRunning() && tm.elapsed_m() < timeout_msecs)
|
||||||
msleep(PIP_MIN_MSLEEP);
|
piMinSleep();
|
||||||
return tm.elapsed_m() < timeout_msecs;
|
return tm.elapsed_m() < timeout_msecs;
|
||||||
}
|
}
|
||||||
|
|||||||
83
main.cpp
83
main.cpp
@@ -2,63 +2,30 @@
|
|||||||
|
|
||||||
|
|
||||||
int main(int argc, char * argv[]) {
|
int main(int argc, char * argv[]) {
|
||||||
PICLI cli(argc, argv);
|
PIThreadNotifier n;
|
||||||
PITimer tm;
|
int cnt1 = 0;
|
||||||
cli.addArgument("connect", true);
|
int cnt2 = 0;
|
||||||
cli.addArgument("name", true);
|
int cnt3 = 0;
|
||||||
PICloudClient c("127.0.0.1:10101");
|
PIThread t1([&n, &cnt1](){n.wait(); cnt1++; piMSleep(1);}, true);
|
||||||
// c.setReopenEnabled(true);
|
PIThread t2([&n, &cnt2](){n.wait(); cnt2++; piMSleep(2);}, true);
|
||||||
PICloudServer s("127.0.0.1:10101");
|
piCout << "created";
|
||||||
PIVector<PICloudServer::Client *> clients;
|
piMSleep(10);
|
||||||
CONNECTL(&tm, tickEvent, ([&](void *, int){
|
piCout << "unlock" << cnt1 << cnt2 << cnt3;
|
||||||
if (c.isConnected()) {
|
n.notifyOnce(); cnt3++;
|
||||||
PIString str = "ping";
|
piMSleep(10);
|
||||||
piCout << "[Client] send:" << str;
|
piCout << "unlock" << cnt1 << cnt2 << cnt3;
|
||||||
c.write(str.toByteArray());
|
n.notifyOnce(); cnt3++;
|
||||||
}
|
piMSleep(10);
|
||||||
if (s.isRunning()) {
|
piCout << "run" << cnt1 << cnt2 << cnt3;
|
||||||
for (auto cl : clients) {
|
PIThread t3([&n, &cnt3](){n.notifyOnce(); cnt3++; piMSleep(1);}, true);
|
||||||
if (cl->isOpened()) {
|
piMSleep(20);
|
||||||
PIString str = "ping_S";
|
t3.stop();
|
||||||
piCout << "[Server] send to" << cl << ":" << str;
|
piMSleep(100);
|
||||||
cl->write(str.toByteArray());
|
piCout << "exit" << cnt1 << cnt2 << cnt3;
|
||||||
}
|
PIByteArray ba = PIByteArray::fromHex("00aabbcc");
|
||||||
}
|
PIByteArray ba2 = ba.getRange(1, 2);
|
||||||
}
|
piCout << ba2.toHex();
|
||||||
}));
|
// m.unlock();
|
||||||
CONNECTL(&c, threadedReadEvent, ([&](uchar * readed, int size){
|
// piMSleep(10);
|
||||||
PIByteArray ba(readed, size);
|
|
||||||
PIString str = PIString(ba);
|
|
||||||
piCout << "[Client] data:" << str;
|
|
||||||
if (str == "ping_S") c.write(PIString("pong_S").toByteArray());
|
|
||||||
}));
|
|
||||||
CONNECTL(&s, newConnection, ([&](PICloudServer::Client * cl){
|
|
||||||
piCout << "[Server] new client:" << cl;
|
|
||||||
clients << cl;
|
|
||||||
CONNECTL(cl, threadedReadEvent, ([&c, &s, cl](uchar * readed, int size){
|
|
||||||
PIByteArray ba(readed, size);
|
|
||||||
PIString str = PIString(ba);
|
|
||||||
piCout << "[Server] data from" << cl << ":" << str;
|
|
||||||
if (str == "ping") cl->write(PIString("pong").toByteArray());
|
|
||||||
}));
|
|
||||||
CONNECTL(cl, closed, ([&clients, cl](){
|
|
||||||
cl->stop();
|
|
||||||
clients.removeAll(cl);
|
|
||||||
cl->deleteLater();
|
|
||||||
}));
|
|
||||||
cl->startThreadedRead();
|
|
||||||
}));
|
|
||||||
if (cli.hasArgument("name")) s.setServerName(cli.argumentValue("name"));
|
|
||||||
if (cli.hasArgument("connect")) {
|
|
||||||
c.setServerName(cli.argumentValue("connect"));
|
|
||||||
c.startThreadedRead();
|
|
||||||
} else {
|
|
||||||
s.startThreadedRead();
|
|
||||||
}
|
|
||||||
tm.start(1000);
|
|
||||||
PIKbdListener ls;
|
|
||||||
ls.enableExitCapture(PIKbdListener::F10);
|
|
||||||
ls.start();
|
|
||||||
WAIT_FOR_EXIT
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
73
main_picloud_test.cpp
Normal file
73
main_picloud_test.cpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#include "pip.h"
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char * argv[]) {
|
||||||
|
PIByteArray rnd;
|
||||||
|
rnd.resize(1024*1024, 'x');
|
||||||
|
PICLI cli(argc, argv);
|
||||||
|
PITimer tm;
|
||||||
|
cli.addArgument("connect", true);
|
||||||
|
cli.addArgument("name", true);
|
||||||
|
PICloudClient c("127.0.0.1:10101");
|
||||||
|
// c.setReopenEnabled(true);
|
||||||
|
PICloudServer s("127.0.0.1:10101");
|
||||||
|
PIVector<PICloudServer::Client *> clients;
|
||||||
|
CONNECTL(&tm, tickEvent, ([&](void *, int){
|
||||||
|
if (c.isConnected()) {
|
||||||
|
PIString str = "ping";
|
||||||
|
piCout << "[Client] send:" << str;
|
||||||
|
c.write(str.toByteArray());
|
||||||
|
}
|
||||||
|
if (s.isRunning()) {
|
||||||
|
for (auto cl : clients) {
|
||||||
|
if (cl->isOpened()) {
|
||||||
|
PIString str = "ping_S";
|
||||||
|
piCout << "[Server] send to" << cl << ":" << str;
|
||||||
|
cl->write(str.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
CONNECTL(&c, threadedReadEvent, ([&](uchar * readed, int size){
|
||||||
|
PIByteArray ba(readed, size);
|
||||||
|
if (size < 1024) {
|
||||||
|
PIString str = PIString(ba);
|
||||||
|
piCout << "[Client] data:" << str;
|
||||||
|
if (str == "ping_S") c.write(PIString("pong_S").toByteArray());
|
||||||
|
} else piCout << "[Client] blob:" << size;
|
||||||
|
}));
|
||||||
|
CONNECTL(&c, connected, ([](){piCout << "connected";}));
|
||||||
|
CONNECTL(&c, disconnected, ([](){piCout << "disconnected";}));
|
||||||
|
CONNECTL(&s, newConnection, ([&](PICloudServer::Client * cl){
|
||||||
|
piCout << "[Server] new client:" << cl;
|
||||||
|
clients << cl;
|
||||||
|
CONNECTL(cl, threadedReadEvent, ([&c, &s, cl, &rnd](uchar * readed, int size){
|
||||||
|
PIByteArray ba(readed, size);
|
||||||
|
PIString str = PIString(ba);
|
||||||
|
piCout << "[Server] data from" << cl << ":" << str;
|
||||||
|
if (str == "ping") {
|
||||||
|
cl->write(PIString("pong").toByteArray());
|
||||||
|
cl->write(rnd);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
CONNECTL(cl, closed, ([&clients, cl](){
|
||||||
|
cl->stop();
|
||||||
|
clients.removeAll(cl);
|
||||||
|
cl->deleteLater();
|
||||||
|
}));
|
||||||
|
cl->startThreadedRead();
|
||||||
|
}));
|
||||||
|
if (cli.hasArgument("name")) s.setServerName(cli.argumentValue("name"));
|
||||||
|
if (cli.hasArgument("connect")) {
|
||||||
|
c.setServerName(cli.argumentValue("connect"));
|
||||||
|
c.startThreadedRead();
|
||||||
|
} else {
|
||||||
|
s.startThreadedRead();
|
||||||
|
}
|
||||||
|
tm.start(1000);
|
||||||
|
PIKbdListener ls;
|
||||||
|
ls.enableExitCapture(PIKbdListener::F10);
|
||||||
|
ls.start();
|
||||||
|
WAIT_FOR_EXIT
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
85
platformio_pre.py
Normal file
85
platformio_pre.py
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
|
import re
|
||||||
|
|
||||||
|
# The list of items
|
||||||
|
files = glob.glob('libs/main/*/*.h', recursive=True)
|
||||||
|
files += glob.glob('libs/main/*.h', recursive=True)
|
||||||
|
|
||||||
|
tdir = './include/'
|
||||||
|
|
||||||
|
if os.path.exists(tdir):
|
||||||
|
shutil.rmtree(tdir)
|
||||||
|
|
||||||
|
os.mkdir(tdir)
|
||||||
|
|
||||||
|
for filename in files:
|
||||||
|
shutil.copy(filename, tdir)
|
||||||
|
|
||||||
|
with open(tdir+'pip_defs.h', 'w') as f:
|
||||||
|
f.write('// This file was generated by PlatformIO, don`t edit it!')
|
||||||
|
|
||||||
|
with open(tdir+'pip_export.h', 'w') as f:
|
||||||
|
f.write('''
|
||||||
|
#ifndef PIP_EXPORT_H
|
||||||
|
#define PIP_EXPORT_H
|
||||||
|
|
||||||
|
# define PIP_EXPORT
|
||||||
|
# define PIP_NO_EXPORT
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PIP_DEPRECATED
|
||||||
|
# define PIP_DEPRECATED __attribute__ ((__deprecated__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PIP_DEPRECATED_EXPORT
|
||||||
|
# define PIP_DEPRECATED_EXPORT PIP_EXPORT PIP_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PIP_DEPRECATED_NO_EXPORT
|
||||||
|
# define PIP_DEPRECATED_NO_EXPORT PIP_NO_EXPORT PIP_DEPRECATED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* PIP_EXPORT_H */
|
||||||
|
''')
|
||||||
|
|
||||||
|
version_h = '''
|
||||||
|
#ifndef PIP_VERSION_H
|
||||||
|
#define PIP_VERSION_H
|
||||||
|
|
||||||
|
|
||||||
|
// Project
|
||||||
|
|
||||||
|
#define PIP_VERSION_MAJOR ${VERSION_MAJOR}
|
||||||
|
#define PIP_VERSION_MINOR ${VERSION_MINOR}
|
||||||
|
#define PIP_VERSION_REVISION ${VERSION_REVISION}
|
||||||
|
#define PIP_VERSION_BUILD 0
|
||||||
|
#define PIP_VERSION_SUFFIX \"${VERSION_SUFFIX}\"
|
||||||
|
#define PIP_VERSION_NAME \"${VERSION}\"
|
||||||
|
#define PIP_MAKE_VERSION(major, minor, revision) ((major << 16) | (minor << 8) | revision)
|
||||||
|
#define PIP_VERSION PIP_MAKE_VERSION(PIP_VERSION_MAJOR, PIP_VERSION_MINOR, PIP_VERSION_REVISION)
|
||||||
|
|
||||||
|
#endif // PIP_VERSION_H
|
||||||
|
'''
|
||||||
|
|
||||||
|
with open('CMakeLists.txt') as cm:
|
||||||
|
str = cm.read()
|
||||||
|
v_major = re.findall(r'pip_MAJOR\s+(\d+)\)', str)
|
||||||
|
v_minor = re.findall(r'pip_MINOR\s+(\d+)\)', str)
|
||||||
|
v_rev = re.findall(r'pip_REVISION\s+(\d+)\)', str)
|
||||||
|
v_suffix = re.findall(r'pip_SUFFIX\s+(\w+)\)', str)
|
||||||
|
ver = ''
|
||||||
|
ver = v_major[0]+'.'+v_minor[0]+'.'+v_rev[0]
|
||||||
|
version_h.replace('${VERSION_MAJOR}', v_major[0])
|
||||||
|
version_h.replace('${VERSION_MINOR}', v_minor[0])
|
||||||
|
version_h.replace('${VERSION_REVISION}', v_rev[0])
|
||||||
|
if len(v_suffix):
|
||||||
|
ver += v_suffix[0]
|
||||||
|
version_h.replace('${VERSION_SUFFIX}', v_suffix[0])
|
||||||
|
else:
|
||||||
|
version_h.replace('${VERSION_SUFFIX}', '')
|
||||||
|
print('PIP version = '+ver)
|
||||||
|
with open(tdir+'pip_version.h', 'w') as f:
|
||||||
|
f.write(version_h)
|
||||||
|
|
||||||
@@ -25,3 +25,4 @@ endmacro()
|
|||||||
pip_test(concurrent "")
|
pip_test(concurrent "")
|
||||||
pip_test(math "")
|
pip_test(math "")
|
||||||
pip_test(core "")
|
pip_test(core "")
|
||||||
|
pip_test(piobject "")
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ TEST_F(ConditionVariable, wait_is_protected_unblock_when_notifyOne) {
|
|||||||
// Missing unlock
|
// Missing unlock
|
||||||
});
|
});
|
||||||
variable->notifyOne();
|
variable->notifyOne();
|
||||||
msleep(WAIT_THREAD_TIME_MS);
|
piMSleep(WAIT_THREAD_TIME_MS);
|
||||||
ASSERT_FALSE(m.tryLock());
|
ASSERT_FALSE(m.tryLock());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +130,7 @@ TEST_F(ConditionVariable, wait_condition_is_check_condition_when_notifyOne) {
|
|||||||
isConditionChecked = false;
|
isConditionChecked = false;
|
||||||
m.unlock();
|
m.unlock();
|
||||||
variable->notifyOne();
|
variable->notifyOne();
|
||||||
msleep(threadStartTime + 1);
|
piMSleep(threadStartTime + 1);
|
||||||
m.lock();
|
m.lock();
|
||||||
ASSERT_TRUE(isConditionChecked);
|
ASSERT_TRUE(isConditionChecked);
|
||||||
m.unlock();
|
m.unlock();
|
||||||
@@ -198,6 +198,6 @@ TEST_F(ConditionVariable, waitFor_is_unblock_when_condition_and_notifyOne) {
|
|||||||
condition = true;
|
condition = true;
|
||||||
m.unlock();
|
m.unlock();
|
||||||
variable->notifyOne();
|
variable->notifyOne();
|
||||||
msleep(WAIT_THREAD_TIME_MS);
|
piMSleep(WAIT_THREAD_TIME_MS);
|
||||||
ASSERT_FALSE(thread->isRunning());
|
ASSERT_FALSE(thread->isRunning());
|
||||||
}
|
}
|
||||||
|
|||||||
34
tests/concurrent/pithreadnotifier_test.cpp
Normal file
34
tests/concurrent/pithreadnotifier_test.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "pithreadnotifier.h"
|
||||||
|
|
||||||
|
|
||||||
|
TEST(PIThreadNotifierTest, One) {
|
||||||
|
PIThreadNotifier n;
|
||||||
|
int cnt = 0;
|
||||||
|
PIThread t1([&n, &cnt](){n.wait(); cnt++;}, true);
|
||||||
|
piMSleep(10);
|
||||||
|
n.notifyOnce();
|
||||||
|
piMSleep(10);
|
||||||
|
ASSERT_EQ(cnt, 1);
|
||||||
|
n.notifyOnce();
|
||||||
|
piMSleep(10);
|
||||||
|
ASSERT_EQ(cnt, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(PIThreadNotifierTest, Two) {
|
||||||
|
PIThreadNotifier n;
|
||||||
|
int cnt1 = 0;
|
||||||
|
int cnt2 = 0;
|
||||||
|
int cnt3 = 0;
|
||||||
|
PIThread t1([&n, &cnt1](){n.wait(); cnt1++; piMSleep(2);}, true);
|
||||||
|
PIThread t2([&n, &cnt2](){n.wait(); cnt2++; piMSleep(2);}, true);
|
||||||
|
PIThread t3([&n, &cnt3](){n.notifyOnce(); cnt3++; piMSleep(1);}, true);
|
||||||
|
piMSleep(20);
|
||||||
|
t3.stop(true);
|
||||||
|
piMSleep(100);
|
||||||
|
t1.stop();
|
||||||
|
t2.stop();
|
||||||
|
ASSERT_EQ(cnt1+cnt2, cnt3);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,54 +1,73 @@
|
|||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
#include "pimathmatrix.h"
|
#include "pimathmatrix.h"
|
||||||
|
|
||||||
bool cmpSquareMatrixWithValue(PIMathMatrix<double> matrix, double val, int num) {
|
template<typename Type>
|
||||||
bool b = true;
|
bool cmpSquareMatrixWithValue(PIMathMatrix<Type> matrix, Type val, int num) {
|
||||||
for(int i = 0; i < num; i++) {
|
for(int i = 0; i < num; i++) {
|
||||||
for(int j = 0; j < num; j++) {
|
for(int j = 0; j < num; j++) {
|
||||||
if(matrix.element(i, j) != val) {
|
if(matrix.element(i, j) != val) {
|
||||||
b = false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return b;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, identity) {
|
TEST(PIMathMatrix_Test, constructor1) {
|
||||||
|
PIMathMatrix<double> matrix(3, 3, 5.0);
|
||||||
|
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, 5.0, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PIMathMatrix_Test, constructor2) {
|
||||||
|
PIVector<double> vector(2, 5.0);
|
||||||
|
PIMathMatrix<PIVector<double>> matrix(3, 3, vector);
|
||||||
|
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, vector, 3));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PIMathMatrix_Test, constructor3) {
|
||||||
|
PIVector2D<double> vector(2, 2, 5.0);
|
||||||
|
PIMathMatrix<double> matrix(vector);
|
||||||
|
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, 5.0, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PIMathMatrix_Test, identity1) {
|
||||||
auto matrix = PIMathMatrix<double>::identity(3, 3);
|
auto matrix = PIMathMatrix<double>::identity(3, 3);
|
||||||
for(int i = 0; i < 3; i++) {
|
for(int i = 0; i < 3; i++) {
|
||||||
for(int j = 0; j < 3; j++) {
|
for(int j = 0; j < 3; j++) {
|
||||||
if(i != j) {
|
if(i != j) {
|
||||||
if(matrix[i][j] != 0.0){
|
if(matrix[i][j] != 0.0){
|
||||||
ASSERT_TRUE(false);
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(matrix[i][i] != 1.0){
|
if(matrix[i][i] != 1.0){
|
||||||
ASSERT_TRUE(false);
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(true);
|
SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PIMathMatrix_Test, identity2) {
|
||||||
|
auto matrix = PIMathMatrix<double>::identity(4, 3);
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
for(int j = 0; j < 4; j++) {
|
||||||
|
if(matrix.element(i,j) != (i == j ? 1. : 0.))
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrixT_Test, element) {
|
TEST(PIMathMatrixT_Test, element) {
|
||||||
auto matrix = PIMathMatrix<double>::identity(3, 3);
|
auto matrix = PIMathMatrix<double>::identity(3, 3);
|
||||||
for(int i = 0; i < 3; i++){
|
for(int i = 0; i < 3; i++) {
|
||||||
for(int j = 0; j < 3; j++){
|
for(int j = 0; j < 3; j++) {
|
||||||
if(i != j){
|
if(matrix.element(i,j) != (i == j ? 1. : 0.))
|
||||||
if(matrix[i][j] != 0.0){
|
FAIL();
|
||||||
ASSERT_TRUE(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if(matrix.element(i,i) != 1.0) {
|
|
||||||
ASSERT_TRUE(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(true);
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, matrixRow) {
|
TEST(PIMathMatrix_Test, matrixRow) {
|
||||||
@@ -57,10 +76,10 @@ TEST(PIMathMatrix_Test, matrixRow) {
|
|||||||
auto matrix = PIMathMatrix<double>::matrixRow(vector);
|
auto matrix = PIMathMatrix<double>::matrixRow(vector);
|
||||||
for(uint i = 0; i < vector.size(); i++) {
|
for(uint i = 0; i < vector.size(); i++) {
|
||||||
if(matrix[0][i] != 3.0) {
|
if(matrix[0][i] != 3.0) {
|
||||||
ASSERT_TRUE(false);
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(true);
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, matrixCol) {
|
TEST(PIMathMatrix_Test, matrixCol) {
|
||||||
@@ -69,10 +88,10 @@ TEST(PIMathMatrix_Test, matrixCol) {
|
|||||||
auto matrix = PIMathMatrix<double>::matrixCol(vector);
|
auto matrix = PIMathMatrix<double>::matrixCol(vector);
|
||||||
for(uint i = 0; i < vector.size(); i++) {
|
for(uint i = 0; i < vector.size(); i++) {
|
||||||
if(matrix[i][0] != 3.0) {
|
if(matrix[i][0] != 3.0) {
|
||||||
ASSERT_TRUE(false);
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(true);
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, setCol) {
|
TEST(PIMathMatrix_Test, setCol) {
|
||||||
@@ -83,10 +102,10 @@ TEST(PIMathMatrix_Test, setCol) {
|
|||||||
matrix.setCol(0, vector);
|
matrix.setCol(0, vector);
|
||||||
for(uint i = 0; i < vector.size(); i++) {
|
for(uint i = 0; i < vector.size(); i++) {
|
||||||
if(matrix[i][0] != 10.0) {
|
if(matrix[i][0] != 10.0) {
|
||||||
ASSERT_TRUE(false);
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(true);
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, setRow) {
|
TEST(PIMathMatrix_Test, setRow) {
|
||||||
@@ -97,10 +116,10 @@ TEST(PIMathMatrix_Test, setRow) {
|
|||||||
matrix.setRow(0, vector);
|
matrix.setRow(0, vector);
|
||||||
for(uint i = 0; i < vector.size(); i++) {
|
for(uint i = 0; i < vector.size(); i++) {
|
||||||
if(matrix[0][i] != 10.0) {
|
if(matrix[0][i] != 10.0) {
|
||||||
ASSERT_TRUE(false);
|
FAIL();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ASSERT_TRUE(true);
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, swapCols) {
|
TEST(PIMathMatrix_Test, swapCols) {
|
||||||
@@ -137,407 +156,3 @@ TEST(PIMathMatrix_Test, swapCols) {
|
|||||||
}
|
}
|
||||||
ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0));
|
ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, swapRows) {
|
|
||||||
PIMathMatrix<double> origMatr;
|
|
||||||
PIMathMatrix<double> matrix1;
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
uint i1 = 0; uint i2 = 1;
|
|
||||||
double a1[3], a2[3], a3[3];
|
|
||||||
double b1[3], b2[3], b3[3];
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix1 = origMatr.identity(3, 3);
|
|
||||||
matrix1.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix1.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix1.setCol(2, vector);
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
a1[i] = matrix1.element(0, i);
|
|
||||||
a2[i] = matrix1.element(1, i);
|
|
||||||
a3[i] = matrix1.element(2, i);
|
|
||||||
}
|
|
||||||
matrix1.swapRows(i1, i2);
|
|
||||||
for(int i = 0; i < 3; i++) {
|
|
||||||
b1[i] = matrix1.element(0, i);
|
|
||||||
b2[i] = matrix1.element(1, i);
|
|
||||||
b3[i] = matrix1.element(2, i);
|
|
||||||
}
|
|
||||||
ASSERT_TRUE((memcmp(a1, b2, sizeof(b1)) == 0) && (memcmp(a2, b1, sizeof(b1)) == 0) && (memcmp(a3, b3, sizeof(b1)) == 0));
|
|
||||||
}
|
|
||||||
TEST(PIMathMatrix_Test, fill) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 5.0);
|
|
||||||
matrix.fill(7.0);
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix, 7.0, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isSquareTrue) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 1.0);
|
|
||||||
ASSERT_TRUE(matrix.isSquare());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isSquareFalse) {
|
|
||||||
PIMathMatrix<double> matrix(2, 4, 1.0);
|
|
||||||
ASSERT_FALSE(matrix.isSquare());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isIdentityTrue) {
|
|
||||||
auto matrix = PIMathMatrix<double>::identity(3, 3);
|
|
||||||
ASSERT_TRUE(matrix.isIdentity());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isIdentityFalse) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 5.0);
|
|
||||||
ASSERT_FALSE(matrix.isIdentity());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isNullTrue) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 0.0);
|
|
||||||
ASSERT_TRUE(matrix.isNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isNullFalse) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 5.0);
|
|
||||||
ASSERT_FALSE(matrix.isNull());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isValidTrue) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 1.62);
|
|
||||||
ASSERT_TRUE(matrix.isValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, isValidFalse) {
|
|
||||||
PIMathMatrix<double> matrix;
|
|
||||||
ASSERT_FALSE(matrix.isValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Assignment) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 5.72);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 7.12);
|
|
||||||
matrix1 = matrix2;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.12, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_EqualTrue) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 2.0);
|
|
||||||
PIMathMatrix<double> matrix2(2, 2, 2.0);
|
|
||||||
matrix1.element(0, 0) = 5.1;
|
|
||||||
matrix1.element(0, 1) = 1.21;
|
|
||||||
matrix1.element(1, 1) = 0.671;
|
|
||||||
matrix1.element(1, 0) = 2.623;
|
|
||||||
matrix2.element(0, 0) = 5.1;
|
|
||||||
matrix2.element(0, 1) = 1.21;
|
|
||||||
matrix2.element(1, 1) = 0.671;
|
|
||||||
matrix2.element(1, 0) = 2.623;
|
|
||||||
ASSERT_TRUE(matrix1 == matrix2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_EqualFalse) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 2.0);
|
|
||||||
PIMathMatrix<double> matrix2(2, 2, 2.0);
|
|
||||||
matrix1.element(0, 0) = 5.1;
|
|
||||||
matrix1.element(0, 1) = 1.21;
|
|
||||||
matrix1.element(1, 1) = 0.671;
|
|
||||||
matrix1.element(1, 0) = 2.623;
|
|
||||||
matrix2.element(0, 0) = 5.1;
|
|
||||||
matrix2.element(0, 1) = 1.21;
|
|
||||||
matrix2.element(1, 1) = 665.671;
|
|
||||||
matrix2.element(1, 0) = 2.623;
|
|
||||||
ASSERT_FALSE(matrix1 == matrix2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Not_EqualTrue) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 2.0);
|
|
||||||
PIMathMatrix<double> matrix2(2, 2, 2.0);
|
|
||||||
matrix1.element(0, 0) = 5.1;
|
|
||||||
matrix1.element(0, 1) = 1.21;
|
|
||||||
matrix1.element(1, 1) = 0.671;
|
|
||||||
matrix1.element(1, 0) = 2.623;
|
|
||||||
matrix2.element(0, 0) = 5.1;
|
|
||||||
matrix2.element(0, 1) = 1.21;
|
|
||||||
matrix2.element(1, 1) = 665.671;
|
|
||||||
matrix2.element(1, 0) = 2.623;
|
|
||||||
ASSERT_TRUE(matrix1 != matrix2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Not_EqualFalse) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 2.0);
|
|
||||||
PIMathMatrix<double> matrix2(2, 2, 2.0);
|
|
||||||
matrix1.element(0, 0) = 5.1;
|
|
||||||
matrix1.element(0, 1) = 1.21;
|
|
||||||
matrix1.element(1, 1) = 0.671;
|
|
||||||
matrix1.element(1, 0) = 2.623;
|
|
||||||
matrix2.element(0, 0) = 5.1;
|
|
||||||
matrix2.element(0, 1) = 1.21;
|
|
||||||
matrix2.element(1, 1) = 0.671;
|
|
||||||
matrix2.element(1, 0) = 2.623;
|
|
||||||
ASSERT_FALSE(matrix1 != matrix2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Addition_Aassignment) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.72);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 1.0);
|
|
||||||
matrix1 += matrix2;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 7.72, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Subtraction_Assignment) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 1.0);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 6.72);
|
|
||||||
matrix1 -= matrix2;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, -5.72, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Multiplication_Assignment) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.72);
|
|
||||||
matrix1 *= 2.0;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 13.44, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Division_Assignment) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.72);
|
|
||||||
matrix1 /= 2.0;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1, 3.36, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Addition) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.72);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 8.28);
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 + matrix2, 15.0, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Subtraction) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.0);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 5.0);
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 - matrix2, 1.0, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, operator_Multiplication) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.72);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 5.0);
|
|
||||||
matrix2 = matrix1*4.0;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix2, 26.88, 3));
|
|
||||||
}
|
|
||||||
TEST(PIMathMatrix_Test, operator_Division) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 6.72);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 5.0);
|
|
||||||
matrix2 = matrix1/4.0;
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix2, 1.68, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, determinantIfSquare) {
|
|
||||||
double d;
|
|
||||||
double i = 59.0;
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 0.0);
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix.setCol(2, vector);
|
|
||||||
d = matrix.determinant();
|
|
||||||
ASSERT_DOUBLE_EQ(d, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, trace) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 0.0);
|
|
||||||
double t;
|
|
||||||
double i = 9.0;
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix.setCol(2, vector);
|
|
||||||
t = matrix.trace();
|
|
||||||
ASSERT_DOUBLE_EQ(t, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, toUpperTriangular) {
|
|
||||||
PIMathMatrix<double> matrix(3, 3, 0.0);
|
|
||||||
double d1, d2 = 1;
|
|
||||||
int i;
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix.setCol(2, vector);
|
|
||||||
d1 = matrix.determinant();
|
|
||||||
matrix.toUpperTriangular();
|
|
||||||
for(i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
d2 = d2 * matrix.element(i, i);
|
|
||||||
}
|
|
||||||
ASSERT_DOUBLE_EQ(d1, d2);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, invert) {
|
|
||||||
double d1, d2;
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 0.0);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 0.0);
|
|
||||||
PIMathMatrix<double> matrix3(3, 3, 0.0);
|
|
||||||
PIMathMatrix<double> matrix4(3, 3, 0.0);
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix1.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix1.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix1.setCol(2, vector);
|
|
||||||
d1 = matrix1.determinant();
|
|
||||||
matrix2 = matrix1;
|
|
||||||
matrix2.invert();
|
|
||||||
d2 = matrix2.determinant();
|
|
||||||
matrix4.invert();
|
|
||||||
ASSERT_TRUE((matrix3 == matrix4) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, inverted) {
|
|
||||||
double d1, d2;
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 0.0);
|
|
||||||
PIMathMatrix<double> matrix2(3, 3, 0.0);
|
|
||||||
PIMathMatrix<double> matrix3(3, 3, 0.0);
|
|
||||||
PIMathMatrix<double> matrix4(3, 3, 0.0);
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix1.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix1.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix1.setCol(2, vector);
|
|
||||||
d1 = matrix1.determinant();
|
|
||||||
matrix2 = matrix1;
|
|
||||||
matrix1 = matrix2.invert();
|
|
||||||
d2 = matrix1.determinant();
|
|
||||||
matrix3 = matrix4.invert();
|
|
||||||
ASSERT_TRUE((matrix3 == matrix4) && (round((1/d1)*10000)/10000 == round(d2*10000)/10000));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, transposed) {
|
|
||||||
PIMathMatrix<double> origMatr;
|
|
||||||
double d1, d2;
|
|
||||||
PIMathMatrix<double> matrix1;
|
|
||||||
PIMathMatrix<double> matrix2;
|
|
||||||
PIMathMatrix<double> matrix3;
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(3, 3.0);
|
|
||||||
vector[0] = 3.0;
|
|
||||||
vector[1] = 6.0;
|
|
||||||
vector[2] = 8.0;
|
|
||||||
matrix1 = origMatr.identity(3, 3);
|
|
||||||
matrix1.setCol(0, vector);
|
|
||||||
vector[0] = 2.0;
|
|
||||||
vector[1] = 1.0;
|
|
||||||
vector[2] = 4.0;
|
|
||||||
matrix1.setCol(1, vector);
|
|
||||||
vector[0] = 6.0;
|
|
||||||
vector[1] = 2.0;
|
|
||||||
vector[2] = 5.0;
|
|
||||||
matrix1.setCol(2, vector);
|
|
||||||
d1 = matrix1.determinant();
|
|
||||||
matrix2 = matrix1.transposed();
|
|
||||||
d2 = matrix2.determinant();
|
|
||||||
matrix3 = matrix2.transposed();
|
|
||||||
ASSERT_TRUE((d1 == d2) && (matrix1 == matrix3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, matrixMultiplication) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 1.5);
|
|
||||||
PIMathMatrix<double> matrix2(2, 2, 2.5);
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(matrix1 * matrix2, 7.5, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, matrixAndVectorMultiplication) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 1.5);
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(2, 2.5);
|
|
||||||
for(uint i = 0; i < 2; i++) {
|
|
||||||
if((matrix1 * vector)[i] != 7.5) {
|
|
||||||
ASSERT_TRUE(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, vectorAndMatrixMultiplication) {
|
|
||||||
PIMathMatrix<double> matrix1(2, 2, 1.5);
|
|
||||||
PIMathVector<double> vector;
|
|
||||||
vector.resize(2, 2.5);
|
|
||||||
for(uint i = 0; i < 2; i++) {
|
|
||||||
if((vector * matrix1)[i] != 7.5) {
|
|
||||||
ASSERT_TRUE(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, valAndMatrixMultiplication) {
|
|
||||||
PIMathMatrix<double> matrix1(3, 3, 1.5);
|
|
||||||
ASSERT_TRUE(cmpSquareMatrixWithValue(25.0*matrix1, 37.5, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(PIMathMatrix_Test, hermitian) {
|
|
||||||
complex<double> val;
|
|
||||||
complex<double> res;
|
|
||||||
val.imag(1.0);
|
|
||||||
val.real(1.0);
|
|
||||||
PIMathMatrix<complex<double>> matrix(3, 3, val);
|
|
||||||
res.imag(-1.0);
|
|
||||||
res.real(1.0);
|
|
||||||
auto matr = hermitian(matrix);
|
|
||||||
for(uint i = 0; i < 3; i++) {
|
|
||||||
for(uint j = 0; j < 3; j++) {
|
|
||||||
if(matr.element(i, j) != res) {
|
|
||||||
ASSERT_TRUE(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ASSERT_TRUE(true);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -5,15 +5,14 @@ const uint rows = 3;
|
|||||||
const uint cols = 3;
|
const uint cols = 3;
|
||||||
|
|
||||||
bool cmpSquareMatrixWithValue(PIMathMatrixT<rows, cols, double> matrix, double val, int num) {
|
bool cmpSquareMatrixWithValue(PIMathMatrixT<rows, cols, double> matrix, double val, int num) {
|
||||||
bool b = true;
|
|
||||||
for(int i = 0; i < num; i++) {
|
for(int i = 0; i < num; i++) {
|
||||||
for(int j = 0; j < num; j++) {
|
for(int j = 0; j < num; j++) {
|
||||||
if(matrix.at(i, j) != val) {
|
if(matrix.at(i, j) != val) {
|
||||||
b = false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return b;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PIMathMatrixT_Test, identity) {
|
TEST(PIMathMatrixT_Test, identity) {
|
||||||
|
|||||||
317
tests/piobject/connect.cpp
Normal file
317
tests/piobject/connect.cpp
Normal file
@@ -0,0 +1,317 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "piobject.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Object : public PIObject
|
||||||
|
{
|
||||||
|
PIOBJECT(Object)
|
||||||
|
public:
|
||||||
|
Object() {
|
||||||
|
x=0;
|
||||||
|
// CONNECTL(this, deleted, [](PIObject * o){
|
||||||
|
// piCout << "deteted" << o;
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
void test() {event_test();}
|
||||||
|
void test_val() {event_val(x);}
|
||||||
|
int getX() const {return x;}
|
||||||
|
|
||||||
|
EVENT(event_test)
|
||||||
|
EVENT1(event_val, int, arg)
|
||||||
|
|
||||||
|
EVENT_HANDLER(void, handler_test) {x++;}
|
||||||
|
EVENT_HANDLER1(void, handler_val, int, arg) {x = arg;}
|
||||||
|
private:
|
||||||
|
int x;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECT0) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECT0(void, &a, event_test, &b, handler_test);
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECT0_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
a.setName("A");
|
||||||
|
b.setName("B");
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECT0(void, &a, event_test, &b, handler_test);
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTU) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECTU(&a, event_test, &b, handler_test);
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTU_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECTU(&a, event_test, &b, handler_test);
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
a.handler_val(99);
|
||||||
|
ASSERT_EQ(a.getX(), 99);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
CONNECTU(&a, event_val, &b, handler_val);
|
||||||
|
ASSERT_EQ(a.getX(), 99);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
a.test_val();
|
||||||
|
ASSERT_EQ(a.getX(), 99);
|
||||||
|
ASSERT_EQ(b.getX(), 99);
|
||||||
|
a.handler_val(-1);
|
||||||
|
ASSERT_EQ(a.getX(), -1);
|
||||||
|
ASSERT_EQ(b.getX(), 99);
|
||||||
|
PIObject::piDisconnect(&a, "event_val", &b);
|
||||||
|
ASSERT_EQ(a.getX(), -1);
|
||||||
|
ASSERT_EQ(b.getX(), 99);
|
||||||
|
a.test_val();
|
||||||
|
ASSERT_EQ(a.getX(), -1);
|
||||||
|
ASSERT_EQ(b.getX(), 99);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTL) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_val(7);
|
||||||
|
});
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 7);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 7);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTL_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_test();
|
||||||
|
});
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
b.handler_test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTL_twice) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_test();
|
||||||
|
});
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_test();
|
||||||
|
});
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 3);
|
||||||
|
b.handler_val(0);
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 0);
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_test();
|
||||||
|
});
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(a.getX(), 0);
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECT_AFTER_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_test();
|
||||||
|
});
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
DISCONNECT1(void, int, &a, event_val, &b, handler_val);
|
||||||
|
CONNECT1(void, int, &a, event_val, &b, handler_val);
|
||||||
|
a.handler_val(8);
|
||||||
|
a.test_val();
|
||||||
|
ASSERT_EQ(a.getX(), 8);
|
||||||
|
ASSERT_EQ(b.getX(), 8);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTL_WRONG_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
CONNECTL(&a, event_test, [&b](){
|
||||||
|
b.handler_test();
|
||||||
|
});
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
PIObject::piDisconnect(&b, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECT_WRONG_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
|
||||||
|
CONNECT0(void, &a, event_test, &b, handler_test);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
PIObject::piDisconnect(&b, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(PiobjectConnections, CONNECTU_WRONG_DISCONNECT) {
|
||||||
|
Object a;
|
||||||
|
Object b;
|
||||||
|
CONNECTU(&a, event_test, &b, handler_test);
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 1);
|
||||||
|
PIObject::piDisconnect(&b, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
PIObject::piDisconnect(&a, "event_test");
|
||||||
|
a.test();
|
||||||
|
ASSERT_EQ(b.getX(), 2);
|
||||||
|
// piCout << "================";
|
||||||
|
}
|
||||||
51
tests/piobject/delete_later.cpp
Normal file
51
tests/piobject/delete_later.cpp
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "piobject.h"
|
||||||
|
|
||||||
|
std::atomic<int> obj_cnt;
|
||||||
|
|
||||||
|
class Send: public PIObject {
|
||||||
|
PIOBJECT(Send)
|
||||||
|
public:
|
||||||
|
Send() {obj_cnt++;}
|
||||||
|
~Send() {obj_cnt--;}
|
||||||
|
EVENT1(ev, PIObject * , o)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Recv: public PIObject {
|
||||||
|
PIOBJECT(Recv)
|
||||||
|
public:
|
||||||
|
Recv() {obj_cnt++;}
|
||||||
|
~Recv() {obj_cnt--;}
|
||||||
|
EVENT_HANDLER1(void, eh, PIObject * , o) {
|
||||||
|
o->deleteLater();
|
||||||
|
piMSleep(10);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
TEST(Piobject, deleteLater) {
|
||||||
|
obj_cnt = 0;
|
||||||
|
Send * s = new Send();
|
||||||
|
Recv * r = new Recv();
|
||||||
|
CONNECTU(s, ev, r, eh);
|
||||||
|
s->ev(r);
|
||||||
|
r->deleteLater();
|
||||||
|
s->deleteLater();
|
||||||
|
piMSleep(100);
|
||||||
|
ASSERT_EQ(obj_cnt, 0);
|
||||||
|
|
||||||
|
PIVector<Send *> s2;
|
||||||
|
s2.resize(100, new Send());
|
||||||
|
for (auto o : s2) o->deleteLater();
|
||||||
|
piMSleep(10);
|
||||||
|
ASSERT_EQ(obj_cnt, 0);
|
||||||
|
s2.clear();
|
||||||
|
|
||||||
|
PIVector<Recv *> r2;
|
||||||
|
r2.resize(100, [](size_t i){return new Recv();});
|
||||||
|
for (auto o : r2) o->deleteLater();
|
||||||
|
piMSleep(10);
|
||||||
|
ASSERT_EQ(obj_cnt, 0);
|
||||||
|
r2.clear();
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user