From 3f7f67e198f9cced4d8289100a1ec894b9d4ee11 Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 15 Jun 2020 11:09:34 +0300 Subject: [PATCH 01/68] picloud start develop --- src_cloud/piccloudclient.cpp | 15 ++++++++++ src_main/cloud/piccloudclient.h | 13 +++++++-- utils/cloud_dispatcher/dispatcherclient.cpp | 28 ++++++++++++++++++ utils/cloud_dispatcher/dispatcherclient.h | 21 ++++++++++++++ utils/cloud_dispatcher/dispatcherserver.cpp | 32 +++++++++++++++++++++ utils/cloud_dispatcher/dispatcherserver.h | 20 +++++++++++++ utils/cloud_dispatcher/main.cpp | 11 +++---- 7 files changed, 133 insertions(+), 7 deletions(-) create mode 100644 utils/cloud_dispatcher/dispatcherclient.cpp create mode 100644 utils/cloud_dispatcher/dispatcherclient.h create mode 100644 utils/cloud_dispatcher/dispatcherserver.cpp create mode 100644 utils/cloud_dispatcher/dispatcherserver.h diff --git a/src_cloud/piccloudclient.cpp b/src_cloud/piccloudclient.cpp index 6b7507ab..98fec593 100644 --- a/src_cloud/piccloudclient.cpp +++ b/src_cloud/piccloudclient.cpp @@ -23,3 +23,18 @@ PICloudClient::PICloudClient() { } + +PICloudClient::~PICloudClient() { + +} + + +bool PICloudClient::openDevice() { + +} + + +bool PICloudClient::closeDevice() { + +} + diff --git a/src_main/cloud/piccloudclient.h b/src_main/cloud/piccloudclient.h index 131555dd..943056b6 100644 --- a/src_main/cloud/piccloudclient.h +++ b/src_main/cloud/piccloudclient.h @@ -25,14 +25,23 @@ #include "piiodevice.h" +class PIEthernet; -class PIP_EXPORT PICloudClient { + +class PIP_EXPORT PICloudClient : public PIIODevice +{ + PIIODEVICE(PICloudClient) public: //! explicit PICloudClient(); + virtual ~PICloudClient(); + +protected: + bool openDevice(); + bool closeDevice(); private: - + PIEthernet * eth; }; #endif // PICCLOUDCLIENT_H diff --git a/utils/cloud_dispatcher/dispatcherclient.cpp b/utils/cloud_dispatcher/dispatcherclient.cpp new file mode 100644 index 00000000..83f3c02e --- /dev/null +++ b/utils/cloud_dispatcher/dispatcherclient.cpp @@ -0,0 +1,28 @@ +#include "dispatcherclient.h" + + +DispatcherClient::DispatcherClient(PIEthernet * eth_) { + eth = eth_; + eth->startThreadedRead(); + CONNECTU(eth, threadedReadEvent, this, readed); + CONNECTU(eth, disconnected, this, disconnected); + piCoutObj << "client connected" << eth->sendAddress(); +} + + +DispatcherClient::~DispatcherClient() { +} + + +void DispatcherClient::disconnected(bool withError) { + piCoutObj << "client disconnected" << eth->sendAddress(); + disconnectEvent(this); +} + + +void DispatcherClient::readed(uchar *data, int size) { + PIByteArray ba(data, size); + piCoutObj << "readed" << ba.toHex(); + eth->write(ba); +} + diff --git a/utils/cloud_dispatcher/dispatcherclient.h b/utils/cloud_dispatcher/dispatcherclient.h new file mode 100644 index 00000000..aa0e0c6f --- /dev/null +++ b/utils/cloud_dispatcher/dispatcherclient.h @@ -0,0 +1,21 @@ +#ifndef DISPATCHERCLIENT_H +#define DISPATCHERCLIENT_H + +#include "piethernet.h" + + +class DispatcherClient: public PIObject { + PIOBJECT(DispatcherClient) +public: + DispatcherClient(PIEthernet * eth_); + ~DispatcherClient(); + EVENT_HANDLER2(void, readed, uchar * , data, int, size); + EVENT_HANDLER1(void, disconnected, bool, withError); + EVENT1(disconnectEvent, DispatcherClient *, client) + +private: + PIEthernet * eth; +}; + + +#endif // DISPATCHERCLIENT_H diff --git a/utils/cloud_dispatcher/dispatcherserver.cpp b/utils/cloud_dispatcher/dispatcherserver.cpp new file mode 100644 index 00000000..40959cbf --- /dev/null +++ b/utils/cloud_dispatcher/dispatcherserver.cpp @@ -0,0 +1,32 @@ +#include "dispatcherserver.h" + + +DispatcherServer::DispatcherServer(PIEthernet::Address addr) { + eth = new PIEthernet(PIEthernet::TCP_Server); + eth->setParameter(PIEthernet::ReuseAddress); + CONNECTU(eth, newConnection, this, newConnection); + eth->listen(addr, true); + piCoutObj << eth << "server started" << addr; +} + + +DispatcherServer::~DispatcherServer() { + eth->close(); + piCoutObj << "server stoped"; + delete eth; +} + + +void DispatcherServer::disconnectClient(DispatcherClient *client) { + piCoutObj << "remove client" << client; + clients.removeOne(client); + delete client; +} + + +void DispatcherServer::newConnection(PIEthernet *cl) { + DispatcherClient * client = new DispatcherClient(cl); + piCoutObj << "add client" << client; + CONNECTU(client, disconnectEvent, this, disconnectClient); + clients.push_back(client); +} diff --git a/utils/cloud_dispatcher/dispatcherserver.h b/utils/cloud_dispatcher/dispatcherserver.h new file mode 100644 index 00000000..4edf2c23 --- /dev/null +++ b/utils/cloud_dispatcher/dispatcherserver.h @@ -0,0 +1,20 @@ +#ifndef DISPATCHERSERVER_H +#define DISPATCHERSERVER_H + +#include "dispatcherclient.h" + + +class DispatcherServer: public PIObject { + PIOBJECT(DispatcherServer) +public: + DispatcherServer(PIEthernet::Address addr); + ~DispatcherServer(); + EVENT_HANDLER1(void, newConnection, PIEthernet * , cl); + EVENT_HANDLER1(void, disconnectClient, DispatcherClient *, client); + +private: + PIEthernet * eth; + PIVector clients; +}; + +#endif // DISPATCHERSERVER_H diff --git a/utils/cloud_dispatcher/main.cpp b/utils/cloud_dispatcher/main.cpp index d85c147c..6a685a3d 100644 --- a/utils/cloud_dispatcher/main.cpp +++ b/utils/cloud_dispatcher/main.cpp @@ -19,12 +19,12 @@ #include "pip.h" #include "picrypt.h" +#include "dispatcherserver.h" using namespace PICoutManipulators; -PIString ip = "0.0.0.0"; -int port = 10101; +PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101); void usage() { piCout << Bold << "PIP Cloud Dispatcher"; @@ -49,10 +49,11 @@ int main (int argc, char * argv[]) { return 0; } if (cli.hasArgument("ip")) - ip = cli.argumentValue("ip"); + addr.setIP(cli.argumentValue("ip")); if (cli.hasArgument("port")) - port = cli.argumentValue("port").toInt(); - + addr.setPort(cli.argumentValue("port").toInt()); + DispatcherServer server(addr); + WAIT_FOR_EXIT return 0; } From 6f5c864e9f696483013e1559c3c392bf147bebd3 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 17 Jul 2020 11:14:11 +0300 Subject: [PATCH 02/68] PIMutex as std::mutex --- lib/main/core/piincludes.h | 5 +- lib/main/introspection/piintrospection_base.h | 2 +- lib/main/io_devices/pipeer.h | 10 +- lib/main/thread/pimutex.cpp | 172 +++++----- lib/main/thread/pimutex.h | 58 ++-- main.cpp | 300 +----------------- utils/system_daemon/main.cpp | 15 +- 7 files changed, 130 insertions(+), 432 deletions(-) diff --git a/lib/main/core/piincludes.h b/lib/main/core/piincludes.h index 14a45a27..3f40293f 100644 --- a/lib/main/core/piincludes.h +++ b/lib/main/core/piincludes.h @@ -26,9 +26,12 @@ #ifdef PIP_STD_IOSTREAM # include #endif +#include +#include +typedef std::mutex PIMutex; class PIObject; -class PIMutex; +//class PIMutex; class PIString; class PIByteArray; class PIInit; diff --git a/lib/main/introspection/piintrospection_base.h b/lib/main/introspection/piintrospection_base.h index 6b86771d..e838f722 100644 --- a/lib/main/introspection/piintrospection_base.h +++ b/lib/main/introspection/piintrospection_base.h @@ -23,7 +23,7 @@ #include "pibase.h" class PIString; -class PIMutex; +//class PIMutex; class PIThread; class PITimer; class PIPeer; diff --git a/lib/main/io_devices/pipeer.h b/lib/main/io_devices/pipeer.h index c142b81b..155d6055 100644 --- a/lib/main/io_devices/pipeer.h +++ b/lib/main/io_devices/pipeer.h @@ -120,11 +120,11 @@ public: EVENT1(peerConnectedEvent, const PIString &, name) EVENT1(peerDisconnectedEvent, const PIString &, name) - bool lockedEth() const {return eth_mutex.isLocked();} - bool lockedPeers() const {return peers_mutex.isLocked();} - bool lockedMBcasts() const {return mc_mutex.isLocked();} - bool lockedSends() const {return send_mutex.isLocked();} - bool lockedMCSends() const {return send_mc_mutex.isLocked();} +// bool lockedEth() const {return eth_mutex.isLocked();} +// bool lockedPeers() const {return peers_mutex.isLocked();} +// bool lockedMBcasts() const {return mc_mutex.isLocked();} +// bool lockedSends() const {return send_mutex.isLocked();} +// bool lockedMCSends() const {return send_mc_mutex.isLocked();} protected: virtual void dataReceived(const PIString & from, const PIByteArray & data) {;} diff --git a/lib/main/thread/pimutex.cpp b/lib/main/thread/pimutex.cpp index efdf9918..1180d338 100644 --- a/lib/main/thread/pimutex.cpp +++ b/lib/main/thread/pimutex.cpp @@ -34,110 +34,100 @@ * * */ -#include "pimutex.h" -#include "piincludes_p.h" -#ifdef BLACKBERRY -# include -#endif +//#include "pimutex.h" +//#include "piincludes_p.h" +//#ifdef BLACKBERRY +//# include +//#endif -PRIVATE_DEFINITION_START(PIMutex) -#ifdef WINDOWS - HANDLE -#else - pthread_mutex_t -#endif - mutex; -PRIVATE_DEFINITION_END(PIMutex) +//PRIVATE_DEFINITION_START(PIMutex) +//#ifdef WINDOWS +// HANDLE +//#else +// pthread_mutex_t +//#endif +// mutex; +//PRIVATE_DEFINITION_END(PIMutex) -PIMutex::PIMutex(): inited_(false) { - //printf("new Mutex %p\n", this); -#ifdef WINDOWS - PRIVATE->mutex = 0; -#endif - init(); -} +//PIMutex::PIMutex(): inited_(false) { +// //printf("new Mutex %p\n", this); +//#ifdef WINDOWS +// PRIVATE->mutex = 0; +//#endif +// init(); +//} -PIMutex::~PIMutex() { - //printf("del Mutex %p\n", this); - destroy(); -} +//PIMutex::~PIMutex() { +// //printf("del Mutex %p\n", this); +// destroy(); +//} -void PIMutex::lock() { -#ifdef WINDOWS -// std::cout << (ullong)PRIVATE->mutex << "locking..." << std::endl; -// DWORD wr = - WaitForSingleObject(PRIVATE->mutex, INFINITE); -// std::cout << (ullong)PRIVATE->mutex << " lock wr=" << wr << std::endl; -#else - pthread_mutex_lock(&(PRIVATE->mutex)); -#endif - locked = true; -} +//void PIMutex::lock() { +//#ifdef WINDOWS +//// std::cout << (ullong)PRIVATE->mutex << "locking..." << std::endl; +//// DWORD wr = +// WaitForSingleObject(PRIVATE->mutex, INFINITE); +//// std::cout << (ullong)PRIVATE->mutex << " lock wr=" << wr << std::endl; +//#else +// pthread_mutex_lock(&(PRIVATE->mutex)); +//#endif +//} -void PIMutex::unlock() { -#ifdef WINDOWS -// BOOL wr = -// ReleaseMutex(PRIVATE->mutex); - SetEvent(PRIVATE->mutex); -// std::cout << (ullong)PRIVATE->mutex << " unlock wr=" << wr << std::endl; -#else - pthread_mutex_unlock(&(PRIVATE->mutex)); -#endif - locked = false; -} +//void PIMutex::unlock() { +//#ifdef WINDOWS +//// BOOL wr = +//// ReleaseMutex(PRIVATE->mutex); +// SetEvent(PRIVATE->mutex); +//// std::cout << (ullong)PRIVATE->mutex << " unlock wr=" << wr << std::endl; +//#else +// pthread_mutex_unlock(&(PRIVATE->mutex)); +//#endif +//} -bool PIMutex::tryLock() { - bool ret = -#ifdef WINDOWS - (WaitForSingleObject(PRIVATE->mutex, 0) == WAIT_OBJECT_0); -#else - (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); -#endif - locked = true; - return ret; -} +//bool PIMutex::tryLock() { +// bool ret = +//#ifdef WINDOWS +// (WaitForSingleObject(PRIVATE->mutex, 0) == WAIT_OBJECT_0); +//#else +// (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); +//#endif +// return ret; +//} -bool PIMutex::isLocked() const { -// std::cout << "test " << (ullong)PRIVATE->mutex << std::endl; - return locked; -} +//void PIMutex::init() { +// if (inited_) destroy(); +//#ifdef WINDOWS +// PRIVATE->mutex = CreateEvent(NULL, FALSE, TRUE, NULL); +//// std::cout << "create " << (ullong)PRIVATE->mutex << std::endl; +//#else +// pthread_mutexattr_t attr; +// memset(&attr, 0, sizeof(attr)); +// pthread_mutexattr_init(&attr); +// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); +// memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); +// pthread_mutex_init(&(PRIVATE->mutex), &attr); +// pthread_mutexattr_destroy(&attr); +//#endif +// inited_ = true; +//} -void PIMutex::init() { - if (inited_) destroy(); -#ifdef WINDOWS - PRIVATE->mutex = CreateEvent(NULL, FALSE, TRUE, NULL); -// std::cout << "create " << (ullong)PRIVATE->mutex << std::endl; -#else - pthread_mutexattr_t attr; - memset(&attr, 0, sizeof(attr)); - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); - pthread_mutex_init(&(PRIVATE->mutex), &attr); - pthread_mutexattr_destroy(&attr); -#endif - locked = false; - inited_ = true; -} - - -void PIMutex::destroy() { - if (inited_) { -#ifdef WINDOWS -// std::cout << "destroy " << (ullong)PRIVATE->mutex << std::endl; - if (PRIVATE->mutex) CloseHandle(PRIVATE->mutex); - PRIVATE->mutex = 0; -#else - pthread_mutex_destroy(&(PRIVATE->mutex)); -#endif - } - locked = inited_ = false; -} +//void PIMutex::destroy() { +// if (inited_) { +//#ifdef WINDOWS +//// std::cout << "destroy " << (ullong)PRIVATE->mutex << std::endl; +// if (PRIVATE->mutex) CloseHandle(PRIVATE->mutex); +// PRIVATE->mutex = 0; +//#else +// pthread_mutex_destroy(&(PRIVATE->mutex)); +//#endif +// } +// inited_ = false; +//} diff --git a/lib/main/thread/pimutex.h b/lib/main/thread/pimutex.h index ac4277e5..24ce7868 100644 --- a/lib/main/thread/pimutex.h +++ b/lib/main/thread/pimutex.h @@ -25,42 +25,42 @@ #include "piinit.h" -class PIP_EXPORT PIMutex -{ -public: - //! Constructs unlocked mutex - explicit PIMutex(); + +//class PIP_EXPORT PIMutex +//{ +//public: +// //! Constructs unlocked mutex +// explicit PIMutex(); - //! Destroy mutex - ~PIMutex(); +// //! Destroy mutex +// ~PIMutex(); - //! \brief Lock mutex - //! \details If mutex is unlocked it set to locked state and returns immediate. - //! If mutex is already locked function blocks until mutex will be unlocked - void lock(); +// //! \brief Lock mutex +// //! \details If mutex is unlocked it set to locked state and returns immediate. +// //! If mutex is already locked function blocks until mutex will be unlocked +// void lock(); - //! \brief Unlock mutex - //! \details In any case this function returns immediate - void unlock(); +// //! \brief Unlock mutex +// //! \details In any case this function returns immediate +// void unlock(); - //! \brief Try to lock mutex - //! \details If mutex is unlocked it set to locked state and returns "true" immediate. - //! If mutex is already locked function returns immediate an returns "false" - bool tryLock(); +// //! \brief Try to lock mutex +// //! \details If mutex is unlocked it set to locked state and returns "true" immediate. +// //! If mutex is already locked function returns immediate an returns "false" +// bool tryLock(); - //! Returns if mutex is locked - bool isLocked() const; +// //! Returns if mutex is locked +// bool isLocked() const; -private: - NO_COPY_CLASS(PIMutex) +//private: +// NO_COPY_CLASS(PIMutex) - void init(); - void destroy(); - bool inited_; - bool locked; - PRIVATE_DECLARATION -}; +// void init(); +// void destroy(); +// bool inited_; +// PRIVATE_DECLARATION +//}; class PIP_EXPORT PIMutexLocker @@ -71,7 +71,7 @@ public: ~PIMutexLocker() {if (cond) mutex->unlock();} private: PIMutex * mutex; - volatile bool cond; + std::atomic_bool cond; }; #endif // PIMUTEX_H diff --git a/main.cpp b/main.cpp index dafd934c..17beba83 100644 --- a/main.cpp +++ b/main.cpp @@ -2,308 +2,12 @@ #include #include #include -/*#include -#include -void print(PIConfig::Entry*e, PIString indent = "") { - piCout << indent << e->name() << "=" << e->value(); - indent += " "; - e->children().forEach([=](PIConfig::Entry*e)->PIConfig::Entry*{print(e, indent); return e;}); -} - -class AsyncIOWatcher: public PIThread { - PIOBJECT_SUBCLASS(AsyncIOWatcher, PIThread) +class A : public PIObject { public: - AsyncIOWatcher() { - pipe_fd[0] = pipe_fd[1] = 0; - if (pipe(pipe_fd) != 0) { - piCoutObj << "Warning: can`t create pipe," << errorString(); - } else { - fd_list << pipe_fd[0]; - } - piCout << pipe_fd[0] << pipe_fd[1]; - fd_list_changed = false; - start(); - } - ~AsyncIOWatcher() { - stop(); - breakSelect(); - if (!waitForFinish(2000)) - terminate(); - if (pipe_fd[0]) ::close(pipe_fd[0]); - if (pipe_fd[1]) ::close(pipe_fd[1]); - } - - void add(int fd) { - que_mutex.lock(); - fd_list_changed = true; - if (!add_que.contains(fd)) - add_que.enqueue(fd); - que_mutex.unlock(); - breakSelect(); - } - void remove(int fd) { - que_mutex.lock(); - fd_list_changed = true; - if (!remove_que.contains(fd)) - remove_que.enqueue(fd); - que_mutex.unlock(); - breakSelect(); - } - -private: - virtual void run() { - que_mutex.lock(); - if (fd_list_changed) { - for (int i = 0; i < add_que.size_s(); ++i) { - if (!fd_list.contains(add_que[i])) - fd_list << add_que[i]; - } - for (int i = 0; i < remove_que.size_s(); ++i) { - fd_list.removeAll(remove_que[i]); - } - add_que.clear(); - remove_que.clear(); - } - fd_list_changed = false; - que_mutex.unlock(); - - s_tv.tv_sec = 1; - s_tv.tv_usec = 0; - FD_ZERO(&s_set); - int max_fd = 0; - piForeachC (int fd, fd_list) { - FD_SET(fd, &s_set); - if (max_fd < fd) - max_fd = fd; - } - int ret = select(max_fd + 1, &s_set, 0, 0, 0); - piCout << "select" << ret; - if (ret <= 0) return; - read_buff.resize(1024); - uint ibuff = 0; - piForeachC (int fd, fd_list) { - if (!FD_ISSET(fd, &s_set)) continue; - if (fd == pipe_fd[0]) { - read(fd, &ibuff, sizeof(ibuff)); - piCoutObj << "breaked"; - continue; - } - int readed = read(fd, read_buff.data(), read_buff.size_s()); - piCout << "readed" << fd << readed; - } - } - void breakSelect() { - if (pipe_fd[1]) - ::write(pipe_fd[1], "\0", 1); - } - - PIQueue add_que, remove_que; - PIDeque fd_list; - PIByteArray read_buff; - PIMutex que_mutex; - bool fd_list_changed; - int pipe_fd[2]; - - fd_set s_set; - struct timeval s_tv; - + void test() {piCout << "test";} }; -*/ -struct A { - double arr[1000]; -}; - - -//PIKbdListener kbd(0, 0, false); - -// void swap(int & x, int & y) {int t = x; x = y; y = t;} -// void swap2(int & x, int & y) {int t(std::move(x)); x = y; y = t;} -// void swap(uint & x, uint & y) {uint t = x; x = y; y = t;} -// void swap2(uint & x, uint & y) {uint t(std::move(x)); x = y; y = t;} -// void swap(ullong & x, ullong & y) {ullong t = x; x = y; y = t;} -// void swap2(ullong & x, ullong & y) {ullong t{std::move(x)}; x = y; y = t;} -// void swap(llong & x, llong & y) {llong t = x; x = y; y = t;} -// void swap2(llong & x, llong & y) {llong t{std::move(x)}; x = y; y = t;} -// void swap(double & x, double & y) {double t = x; x = y; y = t;} -// void swap2(double & x, double & y) {double t(std::move(x)); x = std::move(y); y = std::move(t);} -// void swap(float & x, float & y) {float t = x; x = y; y = t;} -// void swap2(float & x, float & y) {float t(std::move(x)); x = std::move(y); y = std::move(t);} -// void swap(PIString & x, PIString & y) {PIString t = x; x = y; y = t;} -// void swap2(PIString & x, PIString & y) {PIString t(std::move(x)); x = std::move(y); y = std::move(t);} -// void swap(std::string & x, std::string & y) {std::string t = x; x = y; y = t;} -// void swap2(std::string & x, std::string & y) {std::string t{std::move(x)}; x = std::move(y); y = std::move(t);} -// void swap(A & x, A & y) {A t = x; x = y; y = t;} -// void swap2(A & x, A & y) {A t{std::move(x)}; x = std::move(y); y = std::move(t);} -//void swap(PIObject & x, PIObject & y) {A t = x; x = y; y = t;} -//void swap2(PIObject & x, PIObject & y) {A t(std::move(x)); x = std::move(y); y = std::move(t);} int main(int argc, char * argv[]) { - // PITimeMeasurer tm; - // int m = 100000; - // int a = 99, b = 77; - // piCout << "int"; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(a,b); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(a,b); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(a,b); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(a,b); - // } - // piCout << tm.elapsed_s(); - - // piCout << "size_t"; - // size_t ta = 99, tb = 77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(ta,tb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(ta,tb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(ta,tb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(ta,tb); - // } - // piCout << tm.elapsed_s(); - - // piCout << "ullong"; - // ullong lla = 99, llb = 77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(lla,llb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(lla,llb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(lla,llb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(lla,llb); - // } - // piCout << tm.elapsed_s(); - - // piCout << "double"; - // double da = 0.99,db = 77.77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(da,db); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(da,db); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(da,db); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(da,db); - // } - // piCout << tm.elapsed_s(); - - // piCout << "float"; - // float fa = 0.99,fb = 77.77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(fa,fb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(fa,fb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(fa,fb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(fa,fb); - // } - // piCout << tm.elapsed_s(); - - // piCout << "A"; - // A aa,ab; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(aa,ab); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(aa,ab); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(aa,ab); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(aa,ab); - // } - // piCout << tm.elapsed_s(); - - // piCout << "std::string"; - // std::string ia = "123456789012345678901vfsdvsd2345678",ib = "qwertyvsdfvvsdvfsuiopqwertyuikolsdfghjklsdfghjk"; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(ia,ib); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(ia,ib); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // ia.swap(ib); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(ia,ib); - // } - // piCout << tm.elapsed_s(); - - - // PIString sa = "123456789012345678901vfsdvsd2345678",sb = "qwertyvsdfvvsdvfsuiopqwertyuikolsdfghjklsdfghjk"; - // piCout << "PIString"; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(sa,sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(sa, sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // sa.swap(sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(sa, sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(sa, sb); - // } - // piCout << tm.elapsed_s(); return 0; } diff --git a/utils/system_daemon/main.cpp b/utils/system_daemon/main.cpp index 40962fa0..b1ed08d4 100755 --- a/utils/system_daemon/main.cpp +++ b/utils/system_daemon/main.cpp @@ -164,19 +164,20 @@ public: tl->content << TileSimple::Row("Quality: " + PIString::fromNumber((int)ds.quality), CellFormat()); } void updatePeerInfo() { - bool pm = daemon_.lockedPeers(); +// bool pm = daemon_.lockedPeers(); screen->lock(); daemon_.lock(); peers_tl->content.clear(); addrs_tl->content.clear(); peerinfo_tl->content.clear(); peermap_tl->content.clear(); - peers_tl->content << TileList::Row("this | 0 | 0 | " + PIString::fromNumber(daemon_.allPeers().size_s()) + - " [em = " + PIString::fromBool(daemon_.lockedEth()) + ", " - "mm = " + PIString::fromBool(daemon_.lockedMBcasts()) + ", " - "sm = " + PIString::fromBool(daemon_.lockedSends()) + ", " - "ms = " + PIString::fromBool(daemon_.lockedMCSends()) + ", " - "pm = " + PIString::fromBool(pm) + "]", CellFormat()); + peers_tl->content << TileList::Row("this | 0 | 0 | " + PIString::fromNumber(daemon_.allPeers().size_s()) +// + " [em = " + PIString::fromBool(daemon_.lockedEth()) + ", " +// "mm = " + PIString::fromBool(daemon_.lockedMBcasts()) + ", " +// "sm = " + PIString::fromBool(daemon_.lockedSends()) + ", " +// "ms = " + PIString::fromBool(daemon_.lockedMCSends()) + ", " +// "pm = " + PIString::fromBool(pm) + "]" + , CellFormat()); piForeachC(PIPeer::PeerInfo &p , daemon_.allPeers()) peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) + " | p = " + PIString::fromNumber(p.ping()) + From 1a3096c48bf4cec3d068e2f8164632faab73cd1b Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 17 Jul 2020 11:32:04 +0300 Subject: [PATCH 03/68] PIMutex typedef std::mutex, patch PIMutexLocker, replace volatile by atomic --- CMakeLists.txt | 4 +- lib/fftw/pifft_p.h | 1 - lib/main/concurrent/piconditionlock.h | 2 +- lib/main/core/piincludes.h | 2 +- lib/main/introspection/piintrospection_base.h | 1 - lib/main/thread/pimutex.cpp | 133 ------------------ lib/main/thread/pimutex.h | 47 +------ lib/main/thread/pithread.h | 2 +- lib/main/thread/pitimer.h | 2 +- 9 files changed, 12 insertions(+), 182 deletions(-) delete mode 100644 lib/main/thread/pimutex.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ff959ed..a550a01d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 1) -set(_PIP_MINOR 24) +set(_PIP_MINOR 99) set(_PIP_REVISION 0) -set(_PIP_SUFFIX ) +set(_PIP_SUFFIX _pre_alpha) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/lib/fftw/pifft_p.h b/lib/fftw/pifft_p.h index 92c7f378..b4551a94 100644 --- a/lib/fftw/pifft_p.h +++ b/lib/fftw/pifft_p.h @@ -24,7 +24,6 @@ #define PIFFT_P_H #include "pivector.h" -#include "pimutex.h" #include "picout.h" #if defined(PIP_FFTW) || defined(PIP_FFTWf) || defined(PIP_FFTWl) || defined(PIP_FFTWq) # include "fftw3.h" diff --git a/lib/main/concurrent/piconditionlock.h b/lib/main/concurrent/piconditionlock.h index b44e4633..4919e693 100644 --- a/lib/main/concurrent/piconditionlock.h +++ b/lib/main/concurrent/piconditionlock.h @@ -20,7 +20,7 @@ #ifndef PICONDITIONLOCK_H #define PICONDITIONLOCK_H -#include "pimutex.h" +#include "pibase.h" /** diff --git a/lib/main/core/piincludes.h b/lib/main/core/piincludes.h index 3f40293f..1027228f 100644 --- a/lib/main/core/piincludes.h +++ b/lib/main/core/piincludes.h @@ -30,8 +30,8 @@ #include typedef std::mutex PIMutex; +//typedef std::lock_guard PIMutexLocker; class PIObject; -//class PIMutex; class PIString; class PIByteArray; class PIInit; diff --git a/lib/main/introspection/piintrospection_base.h b/lib/main/introspection/piintrospection_base.h index e838f722..e21f9830 100644 --- a/lib/main/introspection/piintrospection_base.h +++ b/lib/main/introspection/piintrospection_base.h @@ -23,7 +23,6 @@ #include "pibase.h" class PIString; -//class PIMutex; class PIThread; class PITimer; class PIPeer; diff --git a/lib/main/thread/pimutex.cpp b/lib/main/thread/pimutex.cpp deleted file mode 100644 index 1180d338..00000000 --- a/lib/main/thread/pimutex.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* - PIP - Platform Independent Primitives - Mutex - Ivan Pelipenko peri4ko@yandex.ru, 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 . -*/ - -/** \class PIMutex - * \brief Mutex - * \details - * \section PIMutex_sec0 Synopsis - * %PIMutex provides synchronization blocks between several threads. - * Using mutex guarantees execution of some code only one of threads. - * Mutex contains logic state and functions to change it: \a lock(), - * \a unlock() and \a tryLock(). - * - * \section PIMutex_sec1 Usage - * Block of code that should to be executed only one thread simultaniously - * should to be started with \a lock() and ended with \a unlock(). - * \snippet pimutex.cpp main - * "mutex" in this example is one for all threads. - * - * */ - -//#include "pimutex.h" -//#include "piincludes_p.h" -//#ifdef BLACKBERRY -//# include -//#endif - - -//PRIVATE_DEFINITION_START(PIMutex) -//#ifdef WINDOWS -// HANDLE -//#else -// pthread_mutex_t -//#endif -// mutex; -//PRIVATE_DEFINITION_END(PIMutex) - - -//PIMutex::PIMutex(): inited_(false) { -// //printf("new Mutex %p\n", this); -//#ifdef WINDOWS -// PRIVATE->mutex = 0; -//#endif -// init(); -//} - - -//PIMutex::~PIMutex() { -// //printf("del Mutex %p\n", this); -// destroy(); -//} - - -//void PIMutex::lock() { -//#ifdef WINDOWS -//// std::cout << (ullong)PRIVATE->mutex << "locking..." << std::endl; -//// DWORD wr = -// WaitForSingleObject(PRIVATE->mutex, INFINITE); -//// std::cout << (ullong)PRIVATE->mutex << " lock wr=" << wr << std::endl; -//#else -// pthread_mutex_lock(&(PRIVATE->mutex)); -//#endif -//} - - -//void PIMutex::unlock() { -//#ifdef WINDOWS -//// BOOL wr = -//// ReleaseMutex(PRIVATE->mutex); -// SetEvent(PRIVATE->mutex); -//// std::cout << (ullong)PRIVATE->mutex << " unlock wr=" << wr << std::endl; -//#else -// pthread_mutex_unlock(&(PRIVATE->mutex)); -//#endif -//} - - -//bool PIMutex::tryLock() { -// bool ret = -//#ifdef WINDOWS -// (WaitForSingleObject(PRIVATE->mutex, 0) == WAIT_OBJECT_0); -//#else -// (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); -//#endif -// return ret; -//} - - -//void PIMutex::init() { -// if (inited_) destroy(); -//#ifdef WINDOWS -// PRIVATE->mutex = CreateEvent(NULL, FALSE, TRUE, NULL); -//// std::cout << "create " << (ullong)PRIVATE->mutex << std::endl; -//#else -// pthread_mutexattr_t attr; -// memset(&attr, 0, sizeof(attr)); -// pthread_mutexattr_init(&attr); -// pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); -// memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); -// pthread_mutex_init(&(PRIVATE->mutex), &attr); -// pthread_mutexattr_destroy(&attr); -//#endif -// inited_ = true; -//} - - -//void PIMutex::destroy() { -// if (inited_) { -//#ifdef WINDOWS -//// std::cout << "destroy " << (ullong)PRIVATE->mutex << std::endl; -// if (PRIVATE->mutex) CloseHandle(PRIVATE->mutex); -// PRIVATE->mutex = 0; -//#else -// pthread_mutex_destroy(&(PRIVATE->mutex)); -//#endif -// } -// inited_ = false; -//} diff --git a/lib/main/thread/pimutex.h b/lib/main/thread/pimutex.h index 24ce7868..0c72f50b 100644 --- a/lib/main/thread/pimutex.h +++ b/lib/main/thread/pimutex.h @@ -26,51 +26,16 @@ #include "piinit.h" -//class PIP_EXPORT PIMutex -//{ -//public: -// //! Constructs unlocked mutex -// explicit PIMutex(); - -// //! Destroy mutex -// ~PIMutex(); - - -// //! \brief Lock mutex -// //! \details If mutex is unlocked it set to locked state and returns immediate. -// //! If mutex is already locked function blocks until mutex will be unlocked -// void lock(); - -// //! \brief Unlock mutex -// //! \details In any case this function returns immediate -// void unlock(); - -// //! \brief Try to lock mutex -// //! \details If mutex is unlocked it set to locked state and returns "true" immediate. -// //! If mutex is already locked function returns immediate an returns "false" -// bool tryLock(); - -// //! Returns if mutex is locked -// bool isLocked() const; - -//private: -// NO_COPY_CLASS(PIMutex) - -// void init(); -// void destroy(); -// bool inited_; -// PRIVATE_DECLARATION -//}; - - class PIP_EXPORT PIMutexLocker { public: - PIMutexLocker(PIMutex * m, bool condition = true): mutex(m), cond(condition) {if (cond) mutex->lock();} - PIMutexLocker(PIMutex & m, bool condition = true): mutex(&m), cond(condition) {if (cond) mutex->lock();} - ~PIMutexLocker() {if (cond) mutex->unlock();} + PIMutexLocker(PIMutex & m, bool condition = true): mutex(m), cond(condition) {if (cond) mutex.lock();} + ~PIMutexLocker() {if (cond) mutex.unlock();} + + PIMutexLocker(const PIMutexLocker&) = delete; + PIMutexLocker& operator=(const PIMutexLocker&) = delete; private: - PIMutex * mutex; + PIMutex & mutex; std::atomic_bool cond; }; diff --git a/lib/main/thread/pithread.h b/lib/main/thread/pithread.h index a2805bea..ababe98e 100644 --- a/lib/main/thread/pithread.h +++ b/lib/main/thread/pithread.h @@ -246,7 +246,7 @@ protected: //! Function executed once at the end of thread. virtual void end() {;} - volatile bool terminating, running_, lockRun; + std::atomic_bool terminating, running_, lockRun; int delay_, policy_; llong tid_; void * data_; diff --git a/lib/main/thread/pitimer.h b/lib/main/thread/pitimer.h index 2d58b847..e5109cab 100644 --- a/lib/main/thread/pitimer.h +++ b/lib/main/thread/pitimer.h @@ -68,7 +68,7 @@ protected: double interval_, deferred_delay; bool deferred_, deferred_mode; // mode: true - date, false - delay - volatile bool running_; + std::atomic_bool running_; PIDateTime deferred_datetime; }; From 33a6382f4d1a241b541e5be136fef769b34cd533 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 17 Jul 2020 11:46:21 +0300 Subject: [PATCH 04/68] NO_COPY_CLASS c++11 --- lib/main/concurrent/piconditionlock.h | 2 +- lib/main/concurrent/piconditionvar.h | 2 +- lib/main/core/pibase.h | 16 ++++------------ lib/main/io_devices/piiodevice.h | 3 +-- lib/main/io_utils/pidiagnostics.h | 5 ++--- lib/main/thread/pimutex.h | 16 ++++++++++------ lib/main/thread/pithread.h | 5 ++--- lib/main/thread/pitimer.h | 9 +++------ 8 files changed, 24 insertions(+), 34 deletions(-) diff --git a/lib/main/concurrent/piconditionlock.h b/lib/main/concurrent/piconditionlock.h index 4919e693..eba7a8a3 100644 --- a/lib/main/concurrent/piconditionlock.h +++ b/lib/main/concurrent/piconditionlock.h @@ -28,6 +28,7 @@ */ class PIP_EXPORT PIConditionLock { public: + NO_COPY_CLASS(PIConditionLock) explicit PIConditionLock(); ~PIConditionLock(); @@ -43,7 +44,6 @@ public: void * handle(); private: - NO_COPY_CLASS(PIConditionLock) PRIVATE_DECLARATION }; diff --git a/lib/main/concurrent/piconditionvar.h b/lib/main/concurrent/piconditionvar.h index dc32d43d..4d011187 100644 --- a/lib/main/concurrent/piconditionvar.h +++ b/lib/main/concurrent/piconditionvar.h @@ -32,6 +32,7 @@ */ class PIP_EXPORT PIConditionVariable { public: + NO_COPY_CLASS(PIConditionVariable) explicit PIConditionVariable(); virtual ~PIConditionVariable(); @@ -111,7 +112,6 @@ public: virtual bool waitFor(PIConditionLock& lk, int timeoutMs, const std::function& condition); private: - NO_COPY_CLASS(PIConditionVariable) PRIVATE_DECLARATION }; diff --git a/lib/main/core/pibase.h b/lib/main/core/pibase.h index cad880fd..0fb52771 100644 --- a/lib/main/core/pibase.h +++ b/lib/main/core/pibase.h @@ -96,9 +96,7 @@ #endif -#ifdef PIP_CXX11_SUPPORT -# include -#endif +#include #include #ifdef WINDOWS @@ -220,8 +218,8 @@ #define PRIVATEWB __privateinitializer__.p #define NO_COPY_CLASS(name) \ - explicit name(const name & ); \ - void operator =(const name & ); + name(const name&) = delete; \ + name& operator=(const name&) = delete; #ifdef FREERTOS # define PIP_MIN_MSLEEP 10. @@ -255,15 +253,9 @@ typedef unsigned long long ullong; typedef long long llong; typedef long double ldouble; -#ifdef PIP_CXX11_SUPPORT -#define piMove(v) std::move(v) -#else -#define piMove(v) v -#endif - /*! \brief Templated function for swap two values * \details Example:\n \snippet piincludes.cpp swap */ -template inline void piSwap(T & f, T & s) {T t(piMove(f)); f = piMove(s); s = piMove(t);} +template inline void piSwap(T & f, T & s) {T t(std::move(f)); f = std::move(s); s = std::move(t);} /*! \brief Templated function for swap two values without "=" * \details Example:\n \snippet piincludes.cpp swapBinary */ diff --git a/lib/main/io_devices/piiodevice.h b/lib/main/io_devices/piiodevice.h index 74a6e8b7..a9d1d227 100644 --- a/lib/main/io_devices/piiodevice.h +++ b/lib/main/io_devices/piiodevice.h @@ -54,6 +54,7 @@ class PIP_EXPORT PIIODevice: public PIThread PIOBJECT_SUBCLASS(PIIODevice, PIThread) friend void __DevicePool_threadReadDP(void * ddp); public: + NO_COPY_CLASS(PIIODevice) //! Constructs a empty PIIODevice explicit PIIODevice(); @@ -388,8 +389,6 @@ protected: void * ret_data_; private: - NO_COPY_CLASS(PIIODevice) - EVENT_HANDLER2(void, check_start, void * , data, int, delim); EVENT_HANDLER(void, write_func); diff --git a/lib/main/io_utils/pidiagnostics.h b/lib/main/io_utils/pidiagnostics.h index 74a69348..9815bb19 100644 --- a/lib/main/io_utils/pidiagnostics.h +++ b/lib/main/io_utils/pidiagnostics.h @@ -32,12 +32,13 @@ class PIP_EXPORT PIDiagnostics: public PITimer PIOBJECT_SUBCLASS(PIDiagnostics, PITimer) friend class PIConnection; public: + NO_COPY_CLASS(PIDiagnostics) //! Constructs an empty diagnostics and if "start_" start it PIDiagnostics(bool start_ = true); virtual ~PIDiagnostics(); - + //! Connection quality enum Quality { Unknown /** Unknown, no one packet received yet */ = 1, @@ -122,8 +123,6 @@ public: //! \} private: - NO_COPY_CLASS(PIDiagnostics) - struct Entry { Entry() {bytes_ok = bytes_fail = 0; cnt_ok = cnt_fail = 0; empty = true;} ullong bytes_ok; diff --git a/lib/main/thread/pimutex.h b/lib/main/thread/pimutex.h index 0c72f50b..02892916 100644 --- a/lib/main/thread/pimutex.h +++ b/lib/main/thread/pimutex.h @@ -1,9 +1,9 @@ /*! \file pimutex.h - * \brief Mutex + * \brief PIMutexLocker */ /* PIP - Platform Independent Primitives - Mutex + PIMutexLocker Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru This program is free software: you can redistribute it and/or modify @@ -25,15 +25,19 @@ #include "piinit.h" - +//! \brief PIMutexLocker +//! \details Same as std::lock_guard. +//! When a PIMutexLocker object is created, it attempts to lock the mutex it is given, if "condition" true. +//! When control leaves the scope in which the PIMutexLocker object was created, +//! the PIMutexLocker is destructed and the mutex is released, if "condition" true. +//! If "condition" false this class do nothing. +//! The PIMutexLocker class is non-copyable. class PIP_EXPORT PIMutexLocker { public: + NO_COPY_CLASS(PIMutexLocker) PIMutexLocker(PIMutex & m, bool condition = true): mutex(m), cond(condition) {if (cond) mutex.lock();} ~PIMutexLocker() {if (cond) mutex.unlock();} - - PIMutexLocker(const PIMutexLocker&) = delete; - PIMutexLocker& operator=(const PIMutexLocker&) = delete; private: PIMutex & mutex; std::atomic_bool cond; diff --git a/lib/main/thread/pithread.h b/lib/main/thread/pithread.h index ababe98e..2724f674 100644 --- a/lib/main/thread/pithread.h +++ b/lib/main/thread/pithread.h @@ -71,7 +71,8 @@ class PIP_EXPORT PIThread: public PIObject PIOBJECT_SUBCLASS(PIThread, PIObject) friend class PIIntrospectionThreads; public: - + NO_COPY_CLASS(PIThread) + //! Contructs thread with custom data "data", external function "func" and main loop delay "loop_delay". PIThread(void * data, ThreadFunc func, bool startNow = false, int loop_delay = -1); @@ -257,8 +258,6 @@ protected: PRIVATE_DECLARATION private: - NO_COPY_CLASS(PIThread) - bool _startThread(void * func); void _beginThread(); void _runThread(); diff --git a/lib/main/thread/pitimer.h b/lib/main/thread/pitimer.h index e5109cab..7ffb9338 100644 --- a/lib/main/thread/pitimer.h +++ b/lib/main/thread/pitimer.h @@ -78,7 +78,8 @@ protected: class PIP_EXPORT PITimer: public PIObject { PIOBJECT_SUBCLASS(PITimer, PIObject) public: - + NO_COPY_CLASS(PITimer) + //! \brief Constructs timer with PITimer::Thread implementation explicit PITimer(); @@ -254,17 +255,13 @@ protected: virtual void tick(void * data_, int delimiter) {} void * data_t; - volatile bool lockRun, callEvents; + std::atomic_bool lockRun, callEvents; PIMutex mutex_; TimerEvent ret_func; TimerImplementation imp_mode; PIVector delims; mutable _PITimerBase * imp; - -private: - NO_COPY_CLASS(PITimer) - }; From b772928dc1af0542e3468ff8e68764f0772bc1df Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 17 Jul 2020 11:51:30 +0300 Subject: [PATCH 05/68] =?UTF-8?q?#15=20=D1=83=D0=B1=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D1=8C=20PIP=5FCXX11=5FSUPPORT?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/main/console/pikbdlistener.h | 6 ----- lib/main/containers/pideque.h | 2 -- lib/main/containers/pivector.h | 2 -- lib/main/core/piobject.cpp | 4 --- lib/main/core/piobject.h | 42 +++----------------------------- lib/main/math/pimathcomplex.h | 13 +++------- lib/main/piplatform.h | 4 --- lib/main/thread/pithread.cpp | 2 -- lib/main/thread/pithread.h | 12 --------- lib/main/thread/pitimer.cpp | 3 +-- lib/main/thread/pitimer.h | 10 -------- 11 files changed, 8 insertions(+), 92 deletions(-) diff --git a/lib/main/console/pikbdlistener.h b/lib/main/console/pikbdlistener.h index 8da6553c..5ea90cd6 100644 --- a/lib/main/console/pikbdlistener.h +++ b/lib/main/console/pikbdlistener.h @@ -133,11 +133,7 @@ public: bool direction; }; -#ifdef PIP_CXX11_SUPPORT typedef std::function KBFunc; -#else - typedef void (*KBFunc)(KeyEvent, void * ); -#endif //! Constructs keyboard listener with external function "slot" and custom data "data" explicit PIKbdListener(KBFunc slot = 0, void * data = 0, bool startNow = true); @@ -154,10 +150,8 @@ public: //! Set external function to "slot" void setSlot(KBFunc slot) {ret_func = slot;} -#ifdef PIP_CXX11_SUPPORT //! Set external function to "slot" void setSlot(std::function slot) {ret_func = [slot](KeyEvent e, void *){slot(e);};} -#endif //! Returns if exit key if awaiting bool exitCaptured() const {return exit_enabled;} diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index f9c24a15..d8c8de06 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -364,7 +364,6 @@ public: return ret; } -#ifdef PIP_CXX11_SUPPORT const PIDeque & forEach(std::function f) const { for (uint i = 0; i < pid_size; ++i) f(pid_data[i + pid_start]); @@ -388,7 +387,6 @@ public: ret << f(pid_data[i + pid_start]); return ret; } -#endif private: inline void _reset() {pid_size = pid_rsize = pid_start = 0; pid_data = 0;} diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index 2f4ae66e..d943af3d 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -358,7 +358,6 @@ public: return ret; } -#ifdef PIP_CXX11_SUPPORT const PIVector & forEach(std::function f) const { for (uint i = 0; i < piv_size; ++i) f(piv_data[i]); @@ -382,7 +381,6 @@ public: ret << f(piv_data[i]); return ret; } -#endif private: inline void _reset() {piv_size = piv_rsize = 0; piv_data = 0;} diff --git a/lib/main/core/piobject.cpp b/lib/main/core/piobject.cpp index 5d190f99..9d420f6f 100644 --- a/lib/main/core/piobject.cpp +++ b/lib/main/core/piobject.cpp @@ -313,7 +313,6 @@ bool PIObject::piConnectU(PIObject * src, const PIString & sig, PIObject * dest_ } -#ifdef PIP_CXX11_SUPPORT bool PIObject::piConnectLS(PIObject * src, const PIString & sig, std::function * f, const char * loc) { if (src == 0) { delete f; @@ -345,7 +344,6 @@ bool PIObject::piConnectLS(PIObject * src, const PIString & sig, std::function__stat_eh_##event##__, functor), LOCATION); -#endif +#define CONNECTL(src, event, functor) PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION); #define CONNECT0(ret, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*))(&(src)->__stat_eh_##event##__), 0, LOCATION); #define CONNECT1(ret, a0, src, event, dest, handler) PIObject::piConnect(src, PIStringAscii(#event), dest, dest, (void*)(ret(*)(void*, a0))(&(dest)->__stat_eh_##handler##__), (void*)(void(*)(void*, a0))(&(src)->__stat_eh_##event##__), 1, LOCATION); @@ -499,21 +497,13 @@ class PIP_EXPORT PIObject { typedef void __Parent__; friend class PIIntrospection; public: - + NO_COPY_CLASS(PIObject) + //! Contructs PIObject with name "name" explicit PIObject(const PIString & name = PIString()); virtual ~PIObject(); -#ifdef PIP_CXX11_SUPPORT - explicit PIObject(const PIObject & ) = delete; - void operator =(const PIObject & ) = delete; -#else -private: - explicit PIObject(const PIObject & ); - void operator =(const PIObject & ); -#endif - private: uint _signature_; @@ -607,13 +597,11 @@ public: // / 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 bool piConnectU(PIObject * src, const PIString & sig, PIObject * dest_o, void * dest, const PIString & hname, const char * loc, PIObject * performer = 0); -#ifdef PIP_CXX11_SUPPORT static bool piConnectLS(PIObject * src, const PIString & sig, std::function * f, const char * loc); template static std::function * __newFunctor(void(*stat_handler)(void*,TYPES...), INPUT functor) { return (std::function*)(new std::function(functor)); } -#endif // / Through names and mixed static void piConnect(const PIString & src, const PIString & sig, void * dest, void * ev_h); @@ -635,11 +623,9 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { __Connection i(sender->connections[j]); if (i.eventID != eventID) continue; -#ifdef PIP_CXX11_SUPPORT if (i.functor) { (*(i.functor))(); } else { -#endif if (i.performer) { i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender)); } else { @@ -652,9 +638,7 @@ public: if (ts) i.dest_o->mutex_.unlock(); } } -#ifdef PIP_CXX11_SUPPORT } -#endif if (!sender->isPIObject()) break; } } @@ -664,11 +648,9 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { __Connection i(sender->connections[j]); if (i.eventID != eventID) continue; -#ifdef PIP_CXX11_SUPPORT if (i.functor) { (*((std::function*)i.functor))(v0); } else { -#endif if (i.performer) { PIVector vl; if (i.args_count > 0) vl << PIVariant::fromValue(v0); @@ -684,9 +666,7 @@ public: if (ts) i.dest_o->mutex_.unlock(); } } -#ifdef PIP_CXX11_SUPPORT } -#endif if (!sender->isPIObject()) break; } } @@ -695,11 +675,9 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { __Connection i(sender->connections[j]); if (i.eventID != eventID) continue; -#ifdef PIP_CXX11_SUPPORT if (i.functor) { (*((std::function*)i.functor))(v0, v1); } else { -#endif if (i.performer) { PIVector vl; if (i.args_count > 0) vl << PIVariant::fromValue(v0); @@ -719,9 +697,7 @@ public: if (ts) i.dest_o->mutex_.unlock(); } } -#ifdef PIP_CXX11_SUPPORT } -#endif if (!sender->isPIObject()) break; } } @@ -730,11 +706,9 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { __Connection i(sender->connections[j]); if (i.eventID != eventID) continue; -#ifdef PIP_CXX11_SUPPORT if (i.functor) { (*((std::function*)i.functor))(v0, v1, v2); } else { -#endif if (i.performer) { PIVector vl; if (i.args_count > 0) vl << PIVariant::fromValue(v0); @@ -756,9 +730,7 @@ public: if (ts) i.dest_o->mutex_.unlock(); } } -#ifdef PIP_CXX11_SUPPORT } -#endif if (!sender->isPIObject()) break; } } @@ -767,11 +739,9 @@ public: for (int j = 0; j < sender->connections.size_s(); ++j) { __Connection i(sender->connections[j]); if (i.eventID != eventID) continue; -#ifdef PIP_CXX11_SUPPORT if (i.functor) { (*((std::function*)i.functor))(v0, v1, v2, v3); } else { -#endif if (i.performer) { PIVector vl; if (i.args_count > 0) vl << PIVariant::fromValue(v0); @@ -795,9 +765,7 @@ public: if (ts) i.dest_o->mutex_.unlock(); } } -#ifdef PIP_CXX11_SUPPORT } -#endif if (!sender->isPIObject()) break; } } @@ -897,16 +865,12 @@ private: dest = d; args_count = ac; performer = p; -#ifdef PIP_CXX11_SUPPORT functor = 0; -#endif } void destroy(); void * slot; void * signal; -#ifdef PIP_CXX11_SUPPORT std::function * functor; -#endif PIString event; uint eventID; PIObject * dest_o; diff --git a/lib/main/math/pimathcomplex.h b/lib/main/math/pimathcomplex.h index 4c1ffe1b..2bcc7fea 100644 --- a/lib/main/math/pimathcomplex.h +++ b/lib/main/math/pimathcomplex.h @@ -68,15 +68,10 @@ inline complexd sign(const complexd & x) {return complexd(sign(x.real()), sign(x inline complexd round(const complexd & c) {return complexd(piRound(c.real()), piRound(c.imag()));} inline complexd floor(const complexd & c) {return complexd(floor(c.real()), floor(c.imag()));} inline complexd ceil (const complexd & c) {return complexd(ceil(c.real()), ceil(c.imag()));} -#ifdef PIP_CXX11_SUPPORT -# define acosc acos -# define asinc asin -# define atanc atan -#else -inline complexd atanc(const complexd & c) {return complexd(0., 0.5) * log((complexd_1 - complexd_i * c) / (complexd_1 + complexd_i * c));} -inline complexd asinc(const complexd & c) {return -complexd_i * log(complexd_i * c + sqrt(complexd_1 - c * c));} -inline complexd acosc(const complexd & c) {return -complexd_i * log(c + complexd_i * sqrt(complexd_1 - c * c));} -#endif + +#define acosc acos +#define asinc asin +#define atanc atan #ifdef CC_GCC # if CC_GCC_VERSION <= 0x025F diff --git a/lib/main/piplatform.h b/lib/main/piplatform.h index 597520b8..73eebc88 100644 --- a/lib/main/piplatform.h +++ b/lib/main/piplatform.h @@ -20,10 +20,6 @@ #ifndef PIPLATFORM_H #define PIPLATFORM_H -#if (__cplusplus >= 201103L) // стандарт C++ 11 или выше - #define PIP_CXX11_SUPPORT -#endif - #if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) # define WINDOWS # define ARCH_BITS_64 diff --git a/lib/main/thread/pithread.cpp b/lib/main/thread/pithread.cpp index 9fdd98eb..5ce598e8 100644 --- a/lib/main/thread/pithread.cpp +++ b/lib/main/thread/pithread.cpp @@ -184,7 +184,6 @@ PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay) } -#ifdef PIP_CXX11_SUPPORT PIThread::PIThread(std::function func, bool startNow, int timer_delay) { PIINTROSPECTION_THREAD_NEW(this); tid_ = -1; @@ -196,7 +195,6 @@ PIThread::PIThread(std::function func, bool startNow, int timer_delay) delay_ = timer_delay; if (startNow) start(timer_delay); } -#endif PIThread::PIThread(bool startNow, int timer_delay): PIObject() { diff --git a/lib/main/thread/pithread.h b/lib/main/thread/pithread.h index 2724f674..2e08aa68 100644 --- a/lib/main/thread/pithread.h +++ b/lib/main/thread/pithread.h @@ -60,11 +60,7 @@ public: static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__; -#ifdef PIP_CXX11_SUPPORT typedef std::function ThreadFunc; -#else -typedef void (*ThreadFunc)(void * ); -#endif class PIP_EXPORT PIThread: public PIObject { @@ -76,10 +72,8 @@ public: //! Contructs thread with custom data "data", external function "func" and main loop delay "loop_delay". PIThread(void * data, ThreadFunc func, bool startNow = false, int loop_delay = -1); -#ifdef PIP_CXX11_SUPPORT //! Contructs thread with external function "func" and main loop delay "loop_delay". PIThread(std::function func, bool startNow = false, int loop_delay = -1); -#endif //! Contructs thread with main loop delay "loop_delay". PIThread(bool startNow = false, int loop_delay = -1); @@ -99,10 +93,8 @@ public: EVENT_HANDLER1(bool, start, int, timer_delay); bool start(ThreadFunc func) {return start(func, -1);} bool start(ThreadFunc func, int timer_delay) {ret_func = func; return start(timer_delay);} -#ifdef PIP_CXX11_SUPPORT bool start(std::function func) {return start(func, -1);} bool start(std::function func, int timer_delay) {ret_func = [func](void*){func();}; return start(timer_delay);} -#endif EVENT_HANDLER0(bool, startOnce); EVENT_HANDLER1(bool, startOnce, ThreadFunc, func) {ret_func = func; return startOnce();} EVENT_HANDLER0(void, stop) {stop(false);} @@ -115,10 +107,8 @@ public: //! \brief Set external function that will be executed after every \a run() void setSlot(ThreadFunc func) {ret_func = func;} -#ifdef PIP_CXX11_SUPPORT //! \brief Set external function that will be executed after every \a run() void setSlot(std::function func) {ret_func = [func](void*){func();};} -#endif //! \brief Set priority of thread void setPriority(PIThread::Priority prior); @@ -161,11 +151,9 @@ public: //! and automatically delete it on function finish static void runOnce(PIObject * object, const char * handler, const PIString & name = PIString()); -#ifdef PIP_CXX11_SUPPORT //! \brief Start function \"func\" in separate thread with name \"name\" //! and automatically delete it on function finish static void runOnce(std::function func, const PIString & name = PIString()); -#endif //! \handlers //! \{ diff --git a/lib/main/thread/pitimer.cpp b/lib/main/thread/pitimer.cpp index f3a68a64..b2878f42 100644 --- a/lib/main/thread/pitimer.cpp +++ b/lib/main/thread/pitimer.cpp @@ -479,7 +479,6 @@ PITimer::PITimer(TimerEvent slot, void * data, PITimer::TimerImplementation ti): } -#ifdef PIP_CXX11_SUPPORT PITimer::PITimer(std::function slot, PITimer::TimerImplementation ti) { imp_mode = ti; initFirst(); @@ -493,7 +492,7 @@ PITimer::PITimer(std::function slot, void * data, PITimer::TimerI data_t = data; ret_func = [slot](void *d, int){slot(d);}; } -#endif + PITimer::~PITimer() { destroy(); diff --git a/lib/main/thread/pitimer.h b/lib/main/thread/pitimer.h index 7ffb9338..842af062 100644 --- a/lib/main/thread/pitimer.h +++ b/lib/main/thread/pitimer.h @@ -26,11 +26,7 @@ #include "pithread.h" #include "pitime.h" -#ifdef PIP_CXX11_SUPPORT typedef std::function TimerEvent; -#else -typedef void (*TimerEvent)(void *, int); -#endif class PITimer; @@ -97,13 +93,11 @@ public: //! \brief Constructs timer with "slot" slot void(void *,int), "data" data and "ti" implementation explicit PITimer(TimerEvent slot, void * data = 0, TimerImplementation ti = Thread); -#ifdef PIP_CXX11_SUPPORT //! \brief Constructs timer with "slot" slot void(), and "ti" implementation explicit PITimer(std::function slot, TimerImplementation ti = Thread); //! \brief Constructs timer with "slot" slot void(void *), "data" data and "ti" implementation explicit PITimer(std::function slot, void * data, TimerImplementation ti = Thread); -#endif virtual ~PITimer(); @@ -160,13 +154,11 @@ public: //! \brief Set timer tick function void setSlot(TimerEvent slot) {ret_func = slot;} -#ifdef PIP_CXX11_SUPPORT //! \brief Set timer tick function void setSlot(std::function slot) {ret_func = [slot](void *, int){slot();};} //! \brief Set timer tick function void setSlot(std::function slot) {ret_func = [slot](void *d, int){slot(d);};} -#endif //! \brief Returns common data passed to tick functions void * data() const {return data_t;} @@ -186,13 +178,11 @@ public: //! \brief Add frequency delimiter \b delim with optional delimiter slot \b slot. void addDelimiter(int delim, TimerEvent slot = 0) {delims << Delimiter(slot, delim);} -#ifdef PIP_CXX11_SUPPORT //! \brief Add frequency delimiter \b delim with optional delimiter slot \b slot. void addDelimiter(int delim, std::function slot) {delims << Delimiter([slot](void *, int){slot();}, delim);} //! \brief Add frequency delimiter \b delim with optional delimiter slot \b slot. void addDelimiter(int delim, std::function slot) {delims << Delimiter([slot](void *d, int){slot(d);}, delim);} -#endif //! \brief Remove all frequency delimiters \b delim. void removeDelimiter(int delim) {for (int i = 0; i < delims.size_s(); ++i) if (delims[i].delim == delim) {delims.remove(i); i--;}} From 94c09e1131801b6bc0f428bc72138fefa046aadf Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 22 Jul 2020 21:11:33 +0300 Subject: [PATCH 06/68] test lua support --- 3rd_party/lua/LuaBridge/List.h | 55 + 3rd_party/lua/LuaBridge/LuaBridge.h | 59 + 3rd_party/lua/LuaBridge/Map.h | 56 + 3rd_party/lua/LuaBridge/RefCountedObject.h | 356 +++++ 3rd_party/lua/LuaBridge/RefCountedPtr.h | 244 ++++ 3rd_party/lua/LuaBridge/UnorderedMap.h | 55 + 3rd_party/lua/LuaBridge/Vector.h | 54 + 3rd_party/lua/LuaBridge/detail/CFunctions.h | 495 +++++++ 3rd_party/lua/LuaBridge/detail/ClassInfo.h | 169 +++ 3rd_party/lua/LuaBridge/detail/Config.h | 10 + 3rd_party/lua/LuaBridge/detail/Constructor.h | 205 +++ 3rd_party/lua/LuaBridge/detail/FuncTraits.h | 942 +++++++++++++ 3rd_party/lua/LuaBridge/detail/Iterator.h | 154 ++ 3rd_party/lua/LuaBridge/detail/LuaException.h | 144 ++ 3rd_party/lua/LuaBridge/detail/LuaHelpers.h | 151 ++ 3rd_party/lua/LuaBridge/detail/LuaRef.h | 1051 ++++++++++++++ 3rd_party/lua/LuaBridge/detail/Namespace.h | 1252 +++++++++++++++++ 3rd_party/lua/LuaBridge/detail/Security.h | 62 + 3rd_party/lua/LuaBridge/detail/Stack.h | 622 ++++++++ 3rd_party/lua/LuaBridge/detail/TypeList.h | 218 +++ 3rd_party/lua/LuaBridge/detail/TypeTraits.h | 135 ++ 3rd_party/lua/LuaBridge/detail/Userdata.h | 829 +++++++++++ 3rd_party/lua/LuaBridge/detail/dump.h | 143 ++ CMakeLists.txt | 14 +- main.cpp | 330 +---- 25 files changed, 7501 insertions(+), 304 deletions(-) create mode 100644 3rd_party/lua/LuaBridge/List.h create mode 100644 3rd_party/lua/LuaBridge/LuaBridge.h create mode 100644 3rd_party/lua/LuaBridge/Map.h create mode 100644 3rd_party/lua/LuaBridge/RefCountedObject.h create mode 100644 3rd_party/lua/LuaBridge/RefCountedPtr.h create mode 100644 3rd_party/lua/LuaBridge/UnorderedMap.h create mode 100644 3rd_party/lua/LuaBridge/Vector.h create mode 100644 3rd_party/lua/LuaBridge/detail/CFunctions.h create mode 100644 3rd_party/lua/LuaBridge/detail/ClassInfo.h create mode 100644 3rd_party/lua/LuaBridge/detail/Config.h create mode 100644 3rd_party/lua/LuaBridge/detail/Constructor.h create mode 100644 3rd_party/lua/LuaBridge/detail/FuncTraits.h create mode 100644 3rd_party/lua/LuaBridge/detail/Iterator.h create mode 100644 3rd_party/lua/LuaBridge/detail/LuaException.h create mode 100644 3rd_party/lua/LuaBridge/detail/LuaHelpers.h create mode 100644 3rd_party/lua/LuaBridge/detail/LuaRef.h create mode 100644 3rd_party/lua/LuaBridge/detail/Namespace.h create mode 100644 3rd_party/lua/LuaBridge/detail/Security.h create mode 100644 3rd_party/lua/LuaBridge/detail/Stack.h create mode 100644 3rd_party/lua/LuaBridge/detail/TypeList.h create mode 100644 3rd_party/lua/LuaBridge/detail/TypeTraits.h create mode 100644 3rd_party/lua/LuaBridge/detail/Userdata.h create mode 100644 3rd_party/lua/LuaBridge/detail/dump.h diff --git a/3rd_party/lua/LuaBridge/List.h b/3rd_party/lua/LuaBridge/List.h new file mode 100644 index 00000000..66e0d8fb --- /dev/null +++ b/3rd_party/lua/LuaBridge/List.h @@ -0,0 +1,55 @@ +// https://github.com/vinniefalco/LuaBridge +// +// Copyright 2018, Dmitry Tarakanov +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +namespace luabridge { + +template +struct Stack > +{ + static void push (lua_State* L, std::list const& list) + { + lua_createtable (L, static_cast (list.size ()), 0); + typename std::list ::const_iterator item = list.begin (); + for (std::size_t i = 1; i <= list.size (); ++i) + { + lua_pushinteger (L, static_cast (i)); + Stack ::push (L, *item); + lua_settable (L, -3); + ++item; + } + } + + static std::list get (lua_State* L, int index) + { + if (!lua_istable (L, index)) + { + luaL_error (L, "#%d argument must be a table", index); + } + + std::list list; + + int const absindex = lua_absindex (L, index); + lua_pushnil (L); + while (lua_next (L, absindex) != 0) + { + list.push_back (Stack ::get (L, -1)); + lua_pop (L, 1); + } + return list; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_istable (L, index); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/LuaBridge.h b/3rd_party/lua/LuaBridge/LuaBridge.h new file mode 100644 index 00000000..866acc39 --- /dev/null +++ b/3rd_party/lua/LuaBridge/LuaBridge.h @@ -0,0 +1,59 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +// All #include dependencies are listed here +// instead of in the individual header files. +// + +#define LUABRIDGE_MAJOR_VERSION 2 +#define LUABRIDGE_MINOR_VERSION 3 +#define LUABRIDGE_VERSION 203 + +#ifndef LUA_VERSION_NUM +#error "Lua headers must be included prior to LuaBridge ones" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/3rd_party/lua/LuaBridge/Map.h b/3rd_party/lua/LuaBridge/Map.h new file mode 100644 index 00000000..a36d269a --- /dev/null +++ b/3rd_party/lua/LuaBridge/Map.h @@ -0,0 +1,56 @@ +// https://github.com/vinniefalco/LuaBridge +// +// Copyright 2018, Dmitry Tarakanov +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include + +namespace luabridge { + +template +struct Stack > +{ + typedef std::map Map; + + static void push (lua_State* L, const Map& map) + { + lua_createtable (L, 0, static_cast (map.size ())); + typedef typename Map::const_iterator ConstIter; + for (ConstIter i = map.begin (); i != map.end (); ++i) + { + Stack ::push (L, i->first); + Stack ::push (L, i->second); + lua_settable (L, -3); + } + } + + static Map get (lua_State* L, int index) + { + if (!lua_istable (L, index)) + { + luaL_error (L, "#%d argument must be a table", index); + } + + Map map; + int const absindex = lua_absindex (L, index); + lua_pushnil (L); + while (lua_next (L, absindex) != 0) + { + map.emplace (Stack ::get (L, -2), Stack ::get (L, -1)); + lua_pop (L, 1); + } + return map; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_istable (L, index); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/RefCountedObject.h b/3rd_party/lua/LuaBridge/RefCountedObject.h new file mode 100644 index 00000000..ebc749e3 --- /dev/null +++ b/3rd_party/lua/LuaBridge/RefCountedObject.h @@ -0,0 +1,356 @@ +//============================================================================== +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco + Copyright 2004-11 by Raw Material Software Ltd. + + This is a derivative work used by permission from part of + JUCE, available at http://www.rawaterialsoftware.com + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + This file incorporates work covered by the following copyright and + permission notice: + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-11 by Raw Material Software Ltd. +*/ +//============================================================================== + +#pragma once + +//#define LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS 1 + +#include + +#include + +namespace luabridge { + +//============================================================================== +/** + Adds reference-counting to an object. + + To add reference-counting to a class, derive it from this class, and + use the RefCountedObjectPtr class to point to it. + + e.g. @code + class MyClass : public RefCountedObjectType + { + void foo(); + + // This is a neat way of declaring a typedef for a pointer class, + // rather than typing out the full templated name each time.. + typedef RefCountedObjectPtr Ptr; + }; + + MyClass::Ptr p = new MyClass(); + MyClass::Ptr p2 = p; + p = 0; + p2->foo(); + @endcode + + Once a new RefCountedObjectType has been assigned to a pointer, be + careful not to delete the object manually. +*/ +template +class RefCountedObjectType +{ +public: + //============================================================================== + /** Increments the object's reference count. + + This is done automatically by the smart pointer, but is public just + in case it's needed for nefarious purposes. + */ + inline void incReferenceCount() const + { + ++refCount; + } + + /** Decreases the object's reference count. + + If the count gets to zero, the object will be deleted. + */ + inline void decReferenceCount() const + { + assert (getReferenceCount() > 0); + + if (--refCount == 0) + delete this; + } + + /** Returns the object's current reference count. */ + inline int getReferenceCount() const + { + return static_cast (refCount); + } + +protected: + //============================================================================== + /** Creates the reference-counted object (with an initial ref count of zero). */ + RefCountedObjectType() : refCount () + { + } + + /** Destructor. */ + virtual ~RefCountedObjectType() + { + // it's dangerous to delete an object that's still referenced by something else! + assert (getReferenceCount() == 0); + } + +private: + //============================================================================== + CounterType mutable refCount; +}; + +//============================================================================== + +/** Non thread-safe reference counted object. + + This creates a RefCountedObjectType that uses a non-atomic integer + as the counter. +*/ +typedef RefCountedObjectType RefCountedObject; + +//============================================================================== +/** + A smart-pointer class which points to a reference-counted object. + + The template parameter specifies the class of the object you want to point + to - the easiest way to make a class reference-countable is to simply make + it inherit from RefCountedObjectType, but if you need to, you could roll + your own reference-countable class by implementing a pair of methods called + incReferenceCount() and decReferenceCount(). + + When using this class, you'll probably want to create a typedef to + abbreviate the full templated name - e.g. + + @code + + typedef RefCountedObjectPtr MyClassPtr; + + @endcode +*/ +template +class RefCountedObjectPtr +{ +public: + /** The class being referenced by this pointer. */ + typedef ReferenceCountedObjectClass ReferencedType; + + //============================================================================== + /** Creates a pointer to a null object. */ + inline RefCountedObjectPtr() : referencedObject (0) + { + } + + /** Creates a pointer to an object. + + This will increment the object's reference-count if it is non-null. + */ + inline RefCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) + : referencedObject (refCountedObject) + { + if (refCountedObject != 0) + refCountedObject->incReferenceCount(); + } + + /** Copies another pointer. + This will increment the object's reference-count (if it is non-null). + */ + inline RefCountedObjectPtr (const RefCountedObjectPtr& other) + : referencedObject (other.referencedObject) + { + if (referencedObject != 0) + referencedObject->incReferenceCount(); + } + +#if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Takes-over the object from another pointer. */ + inline RefCountedObjectPtr (RefCountedObjectPtr&& other) + : referencedObject (other.referencedObject) + { + other.referencedObject = 0; + } +#endif + + /** Copies another pointer. + This will increment the object's reference-count (if it is non-null). + */ + template + inline RefCountedObjectPtr (const RefCountedObjectPtr& other) + : referencedObject (static_cast (other.getObject())) + { + if (referencedObject != 0) + referencedObject->incReferenceCount(); + } + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + RefCountedObjectPtr& operator= (const RefCountedObjectPtr& other) + { + return operator= (other.referencedObject); + } + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + template + RefCountedObjectPtr& operator= (const RefCountedObjectPtr& other) + { + return operator= (static_cast (other.getObject())); + } + +#if LUABRIDGE_COMPILER_SUPPORTS_MOVE_SEMANTICS + /** Takes-over the object from another pointer. */ + RefCountedObjectPtr& operator= (RefCountedObjectPtr&& other) + { + std::swap (referencedObject, other.referencedObject); + return *this; + } +#endif + + /** Changes this pointer to point at a different object. + + The reference count of the old object is decremented, and it might be + deleted if it hits zero. The new object's count is incremented. + */ + RefCountedObjectPtr& operator= (ReferenceCountedObjectClass* const newObject) + { + if (referencedObject != newObject) + { + if (newObject != 0) + newObject->incReferenceCount(); + + ReferenceCountedObjectClass* const oldObject = referencedObject; + referencedObject = newObject; + + if (oldObject != 0) + oldObject->decReferenceCount(); + } + + return *this; + } + + /** Destructor. + + This will decrement the object's reference-count, and may delete it if it + gets to zero. + */ + inline ~RefCountedObjectPtr() + { + if (referencedObject != 0) + referencedObject->decReferenceCount(); + } + + /** Returns the object that this pointer references. + The pointer returned may be zero, of course. + */ + inline operator ReferenceCountedObjectClass*() const + { + return referencedObject; + } + + // the -> operator is called on the referenced object + inline ReferenceCountedObjectClass* operator->() const + { + return referencedObject; + } + + /** Returns the object that this pointer references. + The pointer returned may be zero, of course. + */ + inline ReferenceCountedObjectClass* getObject() const + { + return referencedObject; + } + +private: + //============================================================================== + ReferenceCountedObjectClass* referencedObject; +}; + +/** Compares two ReferenceCountedObjectPointers. */ +template +bool operator== (const RefCountedObjectPtr& object1, ReferenceCountedObjectClass* const object2) +{ + return object1.getObject() == object2; +} + +/** Compares two ReferenceCountedObjectPointers. */ +template +bool operator== (const RefCountedObjectPtr& object1, const RefCountedObjectPtr& object2) +{ + return object1.getObject() == object2.getObject(); +} + +/** Compares two ReferenceCountedObjectPointers. */ +template +bool operator== (ReferenceCountedObjectClass* object1, RefCountedObjectPtr& object2) +{ + return object1 == object2.getObject(); +} + +/** Compares two ReferenceCountedObjectPointers. */ +template +bool operator!= (const RefCountedObjectPtr& object1, const ReferenceCountedObjectClass* object2) +{ + return object1.getObject() != object2; +} + +/** Compares two ReferenceCountedObjectPointers. */ +template +bool operator!= (const RefCountedObjectPtr& object1, RefCountedObjectPtr& object2) +{ + return object1.getObject() != object2.getObject(); +} + +/** Compares two ReferenceCountedObjectPointers. */ +template +bool operator!= (ReferenceCountedObjectClass* object1, RefCountedObjectPtr& object2) +{ + return object1 != object2.getObject(); +} + +//============================================================================== + +template +struct ContainerTraits > +{ + typedef T Type; + + static T* get (RefCountedObjectPtr const& c) + { + return c.getObject (); + } +}; + +//============================================================================== + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/RefCountedPtr.h b/3rd_party/lua/LuaBridge/RefCountedPtr.h new file mode 100644 index 00000000..4db103f5 --- /dev/null +++ b/3rd_party/lua/LuaBridge/RefCountedPtr.h @@ -0,0 +1,244 @@ +//============================================================================== +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include +#include "RefCountedObject.h" + +namespace luabridge { + +//============================================================================== +/** + Support for our RefCountedPtr. +*/ +struct RefCountedPtrBase +{ + // Declaration of container for the refcounts + typedef std::unordered_map RefCountsType; + +protected: + RefCountsType& getRefCounts () const + { + static RefCountsType refcounts; + return refcounts ; + } +}; + +//============================================================================== +/** + A reference counted smart pointer. + + The api is compatible with boost::RefCountedPtr and std::RefCountedPtr, in the + sense that it implements a strict subset of the functionality. + + This implementation uses a hash table to look up the reference count + associated with a particular pointer. + + @tparam T The class type. + + @todo Decompose RefCountedPtr using a policy. At a minimum, the underlying + reference count should be policy based (to support atomic operations) + and the delete behavior should be policy based (to support custom + disposal methods). + + @todo Provide an intrusive version of RefCountedPtr. +*/ +template +class RefCountedPtr : private RefCountedPtrBase +{ +public: + template + struct rebind + { + typedef RefCountedPtr other; + }; + + /** Construct as nullptr or from existing pointer to T. + + @param p The optional, existing pointer to assign from. + */ + RefCountedPtr (T* p = 0) : m_p (p) + { + ++getRefCounts () [m_p]; + } + + /** Construct from another RefCountedPtr. + + @param rhs The RefCountedPtr to assign from. + */ + RefCountedPtr (RefCountedPtr const& rhs) : m_p (rhs.get()) + { + ++getRefCounts () [m_p]; + } + + /** Construct from a RefCountedPtr of a different type. + + @invariant A pointer to U must be convertible to a pointer to T. + + @param rhs The RefCountedPtr to assign from. + @tparam U The other object type. + */ + template + RefCountedPtr (RefCountedPtr const& rhs) : m_p (static_cast (rhs.get())) + { + ++getRefCounts () [m_p]; + } + + /** Release the object. + + If there are no more references then the object is deleted. + */ + ~RefCountedPtr () + { + reset(); + } + + /** Assign from another RefCountedPtr. + + @param rhs The RefCountedPtr to assign from. + @return A reference to the RefCountedPtr. + */ + RefCountedPtr & operator= (RefCountedPtr const& rhs) + { + if (m_p != rhs.m_p) + { + reset (); + m_p = rhs.m_p; + ++getRefCounts () [m_p]; + } + return *this; + } + + /** Assign from another RefCountedPtr of a different type. + + @note A pointer to U must be convertible to a pointer to T. + + @tparam U The other object type. + @param rhs The other RefCountedPtr to assign from. + @return A reference to the RefCountedPtr. + */ + template + RefCountedPtr & operator= (RefCountedPtr const& rhs) + { + reset (); + m_p = static_cast (rhs.get()); + ++getRefCounts () [m_p]; + return *this; + } + + /** Retrieve the raw pointer. + + @return A pointer to the object. + */ + T* get () const + { + return m_p; + } + + /** Retrieve the raw pointer. + + @return A pointer to the object. + */ + T* operator* () const + { + return m_p; + } + + /** Retrieve the raw pointer. + + @return A pointer to the object. + */ + T* operator-> () const + { + return m_p; + } + + /** Determine the number of references. + + @note This is not thread-safe. + + @return The number of active references. + */ + long use_count () const + { + return getRefCounts () [m_p]; + } + + /** Release the pointer. + + The reference count is decremented. If the reference count reaches + zero, the object is deleted. + */ + void reset () + { + if (m_p != 0) + { + if (--getRefCounts () [m_p] <= 0) + delete m_p; + + m_p = 0; + } + } + +private: + T* m_p; +}; + +template +bool operator== (const RefCountedPtr & lhs, const RefCountedPtr & rhs) +{ + return lhs.get () == rhs.get (); +} + +template +bool operator!= (const RefCountedPtr & lhs, const RefCountedPtr & rhs) +{ + return lhs.get() != rhs.get(); +} + +//============================================================================== + +// forward declaration +template +struct ContainerTraits; + +template +struct ContainerTraits > +{ + typedef T Type; + + static T* get (RefCountedPtr const& c) + { + return c.get (); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/UnorderedMap.h b/3rd_party/lua/LuaBridge/UnorderedMap.h new file mode 100644 index 00000000..78a7acee --- /dev/null +++ b/3rd_party/lua/LuaBridge/UnorderedMap.h @@ -0,0 +1,55 @@ +// https://github.com/vinniefalco/LuaBridge +// +// Copyright 2019, Dmitry Tarakanov +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +namespace luabridge { + +template +struct Stack > +{ + typedef std::unordered_map Map; + + static void push (lua_State* L, const Map& map) + { + lua_createtable (L, 0, static_cast (map.size ())); + typedef typename Map::const_iterator ConstIter; + for (ConstIter i = map.begin (); i != map.end (); ++i) + { + Stack ::push (L, i->first); + Stack ::push (L, i->second); + lua_settable (L, -3); + } + } + + static Map get (lua_State* L, int index) + { + if (!lua_istable (L, index)) + { + luaL_error (L, "#%d argument must be a table", index); + } + + Map map; + int const absindex = lua_absindex (L, index); + lua_pushnil (L); + while (lua_next (L, absindex) != 0) + { + map.emplace (Stack ::get (L, -2), Stack ::get (L, -1)); + lua_pop (L, 1); + } + return map; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_istable (L, index); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/Vector.h b/3rd_party/lua/LuaBridge/Vector.h new file mode 100644 index 00000000..cc803136 --- /dev/null +++ b/3rd_party/lua/LuaBridge/Vector.h @@ -0,0 +1,54 @@ +// https://github.com/vinniefalco/LuaBridge +// +// Copyright 2018, Dmitry Tarakanov +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +namespace luabridge { + +template +struct Stack > +{ + static void push (lua_State* L, std::vector const& vector) + { + lua_createtable (L, static_cast (vector.size ()), 0); + for (std::size_t i = 0; i < vector.size (); ++i) + { + lua_pushinteger (L, static_cast (i + 1)); + Stack ::push (L, vector [i]); + lua_settable (L, -3); + } + } + + static std::vector get (lua_State* L, int index) + { + if (!lua_istable (L, index)) + { + luaL_error (L, "#%d argument must be a table", index); + } + + std::vector vector; + vector.reserve (static_cast (get_length (L, index))); + + int const absindex = lua_absindex (L, index); + lua_pushnil (L); + while (lua_next (L, absindex) != 0) + { + vector.push_back (Stack ::get (L, -1)); + lua_pop (L, 1); + } + return vector; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_istable (L, index); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/CFunctions.h b/3rd_party/lua/LuaBridge/detail/CFunctions.h new file mode 100644 index 00000000..d4ae0cca --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/CFunctions.h @@ -0,0 +1,495 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include +#include + +#include + +namespace luabridge { + +// We use a structure so we can define everything in the header. +// +struct CFunc +{ + static void addGetter (lua_State* L, const char* name, int tableIndex) + { + assert (lua_istable (L, tableIndex)); + assert (lua_iscfunction (L, -1)); // Stack: getter + + lua_rawgetp (L, tableIndex, getPropgetKey ()); // Stack: getter, propget table (pg) + lua_pushvalue (L, -2); // Stack: getter, pg, getter + rawsetfield (L, -2, name); // Stack: getter, pg + lua_pop (L, 2); // Stack: - + } + + static void addSetter (lua_State* L, const char* name, int tableIndex) + { + assert (lua_istable (L, tableIndex)); + assert (lua_iscfunction (L, -1)); // Stack: setter + + lua_rawgetp (L, tableIndex, getPropsetKey ()); // Stack: setter, propset table (ps) + lua_pushvalue (L, -2); // Stack: setter, ps, setter + rawsetfield (L, -2, name); // Stack: setter, ps + lua_pop (L, 2); // Stack: - + } + + //---------------------------------------------------------------------------- + /** + __index metamethod for a namespace or class static and non-static members. + Retrieves functions from metatables and properties from propget tables. + Looks through the class hierarchy if inheritance is present. + */ + static int indexMetaMethod (lua_State* L) + { + assert (lua_istable (L, 1) || lua_isuserdata (L, 1)); // Stack (further not shown): table | userdata, name + + lua_getmetatable (L, 1); // Stack: class/const table (mt) + assert (lua_istable (L, -1)); + + for (;;) + { + lua_pushvalue (L, 2); // Stack: mt, field name + lua_rawget (L, -2); // Stack: mt, field | nil + + if (lua_iscfunction (L, -1)) // Stack: mt, field + { + lua_remove (L, -2); // Stack: field + return 1; + } + + assert (lua_isnil (L, -1)); // Stack: mt, nil + lua_pop (L, 1); // Stack: mt + + lua_rawgetp (L, -1, getPropgetKey ()); // Stack: mt, propget table (pg) + assert (lua_istable (L, -1)); + + lua_pushvalue (L, 2); // Stack: mt, pg, field name + lua_rawget (L, -2); // Stack: mt, pg, getter | nil + lua_remove (L, -2); // Stack: mt, getter | nil + + if (lua_iscfunction (L, -1)) // Stack: mt, getter + { + lua_remove (L, -2); // Stack: getter + lua_pushvalue (L, 1); // Stack: getter, table | userdata + lua_call (L, 1, 1); // Stack: value + return 1; + } + + assert (lua_isnil (L, -1)); // Stack: mt, nil + lua_pop (L, 1); // Stack: mt + + // It may mean that the field may be in const table and it's constness violation. + // Don't check that, just return nil + + // Repeat the lookup in the parent metafield, + // or return nil if the field doesn't exist. + lua_rawgetp (L, -1, getParentKey ()); // Stack: mt, parent mt | nil + + if (lua_isnil (L, -1)) // Stack: mt, nil + { + lua_remove (L, -2); // Stack: nil + return 1; + } + + // Removethe metatable and repeat the search in the parent one. + assert (lua_istable (L, -1)); // Stack: mt, parent mt + lua_remove (L, -2); // Stack: parent mt + } + + // no return + } + + //---------------------------------------------------------------------------- + /** + __newindex metamethod for namespace or class static members. + Retrieves properties from propset tables. + */ + static int newindexStaticMetaMethod (lua_State* L) + { + return newindexMetaMethod (L, false); + } + + //---------------------------------------------------------------------------- + /** + __newindex metamethod for non-static members. + Retrieves properties from propset tables. + */ + static int newindexObjectMetaMethod (lua_State* L) + { + return newindexMetaMethod (L, true); + } + + static int newindexMetaMethod (lua_State* L, bool pushSelf) + { + assert (lua_istable (L, 1) || lua_isuserdata (L, 1)); // Stack (further not shown): table | userdata, name, new value + + lua_getmetatable (L, 1); // Stack: metatable (mt) + assert (lua_istable (L, -1)); + + for (;;) + { + lua_rawgetp (L, -1, getPropsetKey ()); // Stack: mt, propset table (ps) | nil + + if (lua_isnil (L, -1)) // Stack: mt, nil + { + lua_pop (L, 2); // Stack: - + return luaL_error (L, "No member named '%s'", lua_tostring (L, 2)); + } + + assert (lua_istable (L, -1)); + + lua_pushvalue (L, 2); // Stack: mt, ps, field name + lua_rawget (L, -2); // Stack: mt, ps, setter | nil + lua_remove (L, -2); // Stack: mt, setter | nil + + if (lua_iscfunction (L, -1)) // Stack: mt, setter + { + lua_remove (L, -2); // Stack: setter + if (pushSelf) + { + lua_pushvalue (L, 1); // Stack: setter, table | userdata + } + lua_pushvalue (L, 3); // Stack: setter, table | userdata, new value + lua_call (L, pushSelf ? 2 : 1, 0); // Stack: - + return 0; + } + + assert (lua_isnil (L, -1)); // Stack: mt, nil + lua_pop (L, 1); // Stack: mt + + lua_rawgetp (L, -1, getParentKey ()); // Stack: mt, parent mt | nil + + if (lua_isnil (L, -1)) // Stack: mt, nil + { + lua_pop (L, 1); // Stack: - + return luaL_error (L, "No writable member '%s'", lua_tostring (L, 2)); + } + + assert (lua_istable (L, -1)); // Stack: mt, parent mt + lua_remove (L, -2); // Stack: parent mt + // Repeat the search in the parent + } + + // no return + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to report an error writing to a read-only value. + + The name of the variable is in the first upvalue. + */ + static int readOnlyError (lua_State* L) + { + std::string s; + + s = s + "'" + lua_tostring (L, lua_upvalueindex (1)) + "' is read-only"; + + return luaL_error (L, s.c_str ()); + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to get a variable. + + This is used for global variables or class static data members. + + The pointer to the data is in the first upvalue. + */ + template + static int getVariable (lua_State* L) + { + assert (lua_islightuserdata (L, lua_upvalueindex (1))); + T const* ptr = static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (ptr != 0); + Stack ::push (L, *ptr); + return 1; + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to set a variable. + + This is used for global variables or class static data members. + + The pointer to the data is in the first upvalue. + */ + template + static int setVariable (lua_State* L) + { + assert (lua_islightuserdata (L, lua_upvalueindex (1))); + T* ptr = static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (ptr != 0); + *ptr = Stack ::get (L, 1); + return 0; + } + + //---------------------------------------------------------------------------- + /** + lua_CFunction to call a function with a return value. + + This is used for global functions, global properties, class static methods, + and class static properties. + + The function pointer (lightuserdata) in the first upvalue. + */ + template + struct Call + { + typedef typename FuncTraits ::Params Params; + typedef typename FuncTraits ::ReturnType ReturnType; + + static int f (lua_State* L) + { + assert (lua_islightuserdata (L, lua_upvalueindex (1))); + FnPtr fnptr = reinterpret_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return Invoke ::run (L, fnptr); + } + }; + + //---------------------------------------------------------------------------- + /** + lua_CFunction to call a class member function with a return value. + + The member function pointer is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template + struct CallMember + { + typedef typename FuncTraits ::ClassType T; + typedef typename FuncTraits ::Params Params; + typedef typename FuncTraits ::ReturnType ReturnType; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T* const t = Userdata::get (L, 1, false); + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return Invoke ::run (L, t, fnptr); + } + }; + + template + struct CallConstMember + { + typedef typename FuncTraits ::ClassType T; + typedef typename FuncTraits ::Params Params; + typedef typename FuncTraits ::ReturnType ReturnType; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + T const* const t = Userdata::get (L, 1, true); + MemFnPtr const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return Invoke ::run (L, t, fnptr); + } + }; + + //-------------------------------------------------------------------------- + /** + lua_CFunction to call a class member lua_CFunction. + + The member function pointer is in the first upvalue. + The object userdata ('this') value is at top ot the Lua stack. + */ + template + struct CallMemberCFunction + { + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + typedef int (T::*MFP) (lua_State* L); + T* const t = Userdata::get (L, 1, false); + MFP const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return (t->*fnptr) (L); + } + }; + + template + struct CallConstMemberCFunction + { + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + typedef int (T::*MFP) (lua_State* L); + T const* const t = Userdata::get (L, 1, true); + MFP const& fnptr = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return (t->*fnptr) (L); + } + }; + +#ifdef LUABRIDGE_CXX11 + + //-------------------------------------------------------------------------- + /** + lua_CFunction to call on a object. + + The proxy function pointer (lightuserdata) is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template + struct CallProxyFunction + { + using Params = typename FuncTraits ::Params; + using ReturnType = typename FuncTraits ::ReturnType; + + static int f (lua_State* L) + { + assert (lua_islightuserdata (L, lua_upvalueindex (1))); + auto fnptr = reinterpret_cast (lua_touserdata (L, lua_upvalueindex (1))); + assert (fnptr != 0); + return Invoke ::run (L, fnptr); + } + }; + + template + struct CallProxyFunctor + { + using Params = typename FuncTraits ::Params; + using ReturnType = typename FuncTraits ::ReturnType; + + static int f (lua_State* L) + { + assert (isfulluserdata (L, lua_upvalueindex (1))); + Functor& fn = *static_cast (lua_touserdata (L, lua_upvalueindex (1))); + return Invoke ::run (L, fn); + } + }; + +#endif + + //-------------------------------------------------------------------------- + + // SFINAE Helpers + + template + struct CallMemberFunctionHelper + { + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallConstMember ::f, 1); + lua_pushvalue (L, -1); + rawsetfield (L, -5, name); // const table + rawsetfield (L, -3, name); // class table + } + }; + + template + struct CallMemberFunctionHelper + { + static void add (lua_State* L, char const* name, MemFnPtr mf) + { + new (lua_newuserdata (L, sizeof (MemFnPtr))) MemFnPtr (mf); + lua_pushcclosure (L, &CallMember ::f, 1); + rawsetfield (L, -3, name); // class table + } + }; + + //-------------------------------------------------------------------------- + /** + __gc metamethod for a class. + */ + template + static int gcMetaMethod (lua_State* L) + { + Userdata* const ud = Userdata::getExact (L, 1); + ud->~Userdata (); + return 0; + } + + /** + __gc metamethod for an arbitrary class. + */ + template + static int gcMetaMethodAny (lua_State* L) + { + assert (isfulluserdata (L, 1)); + T* t = static_cast (lua_touserdata (L, 1)); + t->~T (); + return 0; + } + + //-------------------------------------------------------------------------- + /** + lua_CFunction to get a class data member. + + The pointer-to-member is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template + static int getProperty (lua_State* L) + { + C* const c = Userdata::get (L, 1, true); + T C::** mp = static_cast (lua_touserdata (L, lua_upvalueindex (1))); + try + { + Stack ::push (L, c->**mp); + } + catch (const std::exception& e) + { + luaL_error (L, e.what ()); + } + return 1; + } + + //-------------------------------------------------------------------------- + /** + lua_CFunction to set a class data member. + + The pointer-to-member is in the first upvalue. + The class userdata object is at the top of the Lua stack. + */ + template + static int setProperty (lua_State* L) + { + C* const c = Userdata::get (L, 1, false); + T C::** mp = static_cast (lua_touserdata (L, lua_upvalueindex (1))); + try + { + c->**mp = Stack ::get (L, 2); + } + catch (const std::exception& e) + { + luaL_error (L, e.what ()); + } + return 0; + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/ClassInfo.h b/3rd_party/lua/LuaBridge/detail/ClassInfo.h new file mode 100644 index 00000000..ca83f93d --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/ClassInfo.h @@ -0,0 +1,169 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +namespace luabridge { + +/** + * A unique key for a type name in a metatable. + */ +inline const void* getTypeKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0x71); +#endif +} + +/** + * The key of a const table in another metatable. + */ +inline const void* getConstKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0xc07); +#endif +} + +/** + * The key of a class table in another metatable. + */ +inline const void* getClassKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0xc1a); +#endif +} + +/** + * The key of a propget table in another metatable. + */ +inline const void* getPropgetKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0x6e7); +#endif +} + +/** + * The key of a propset table in another metatable. + */ +inline const void* getPropsetKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0x5e7); +#endif +} + +/** + * The key of a static table in another metatable. + */ +inline const void* getStaticKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0x57a); +#endif +} + +/** + * The key of a parent table in another metatable. + */ +inline const void* getParentKey () +{ +#ifdef _NDEBUG + static char value; + return &value; +#else + return reinterpret_cast (0xdad); +#endif +} + +/** Unique Lua registry keys for a class. + + Each registered class inserts three keys into the registry, whose + values are the corresponding static, class, and const metatables. This + allows a quick and reliable lookup for a metatable from a template type. +*/ +template +class ClassInfo +{ +public: + /** Get the key for the static table. + + The static table holds the static data members, static properties, and + static member functions for a class. + */ + static void const* getStaticKey () + { + static char value; + return &value; + } + + /** Get the key for the class table. + + The class table holds the data members, properties, and member functions + of a class. Read-only data and properties, and const member functions are + also placed here (to save a lookup in the const table). + */ + static void const* getClassKey () + { + static char value; + return &value; + } + + /** Get the key for the const table. + + The const table holds read-only data members and properties, and const + member functions of a class. + */ + static void const* getConstKey () + { + static char value; + return &value; + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/Config.h b/3rd_party/lua/LuaBridge/detail/Config.h new file mode 100644 index 00000000..76b3d420 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Config.h @@ -0,0 +1,10 @@ +// https://github.com/vinniefalco/LuaBridge +// +// Copyright 2019, Dmitry Tarakanov +// SPDX-License-Identifier: MIT + +#pragma once + +#if !defined (LUABRIDGE_NO_CXX11) && (__cplusplus >= 201103L || (defined (_MSC_VER) && _MSC_VER >= 1900)) +#define LUABRIDGE_CXX11 +#endif diff --git a/3rd_party/lua/LuaBridge/detail/Constructor.h b/3rd_party/lua/LuaBridge/detail/Constructor.h new file mode 100644 index 00000000..04b3dab0 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Constructor.h @@ -0,0 +1,205 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +namespace luabridge { + +/* +* Constructor generators. These templates allow you to call operator new and +* pass the contents of a type/value list to the Constructor. Like the +* function pointer containers, these are only defined up to 8 parameters. +*/ + +/** Constructor generators. + + These templates call operator new with the contents of a type/value + list passed to the Constructor with up to 8 parameters. Two versions + of call() are provided. One performs a regular new, the other performs + a placement new. +*/ +template +struct Constructor {}; + +template +struct Constructor +{ + static T* call (TypeListValues const&) + { + return new T; + } + static T* call (void* mem, TypeListValues const&) + { + return new (mem) T; + } +}; + +template +struct Constructor > +{ + static T* call (const TypeListValues > &tvl) + { + return new T(tvl.hd); + } + static T* call (void* mem, const TypeListValues > &tvl) + { + return new (mem) T(tvl.hd); + } +}; + +template +struct Constructor > > +{ + static T* call (const TypeListValues > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd); + } +}; + +template +struct Constructor > > > +{ + static T* call (const TypeListValues > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template +struct Constructor > > > > +{ + static T* call (const TypeListValues > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template +struct Constructor > > > > > +{ + static T* call (const TypeListValues > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd); + } +}; + +template +struct Constructor > > > > > > +{ + static T* call (const TypeListValues > > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template +struct Constructor > > > > > > > +{ + static T* call (const TypeListValues > > > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template +struct Constructor > > > > > > > > +{ + static T* call (const TypeListValues > > > > > > > > &tvl) + { + return new T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } + static T* call (void* mem, const TypeListValues > > > > > > > > &tvl) + { + return new (mem) T(tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/FuncTraits.h b/3rd_party/lua/LuaBridge/detail/FuncTraits.h new file mode 100644 index 00000000..22b15863 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/FuncTraits.h @@ -0,0 +1,942 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2020, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include + +#ifdef LUABRIDGE_CXX11 +#include +#endif + +namespace luabridge { + +/** + Since the throw specification is part of a function signature, the FuncTraits + family of templates needs to be specialized for both types. The + LUABRIDGE_THROWSPEC macro controls whether we use the 'throw ()' form, or + 'noexcept' (if C++11 is available) to distinguish the functions. +*/ +#if defined (__APPLE_CPP__) || defined (__APPLE_CC__) || defined (__clang__) || defined (__GNUC__) || \ + (defined (_MSC_VER) && (_MSC_VER >= 1700)) +// Do not define LUABRIDGE_THROWSPEC since the Xcode and gcc compilers do not +// distinguish the throw specification in the function signature. +#define LUABRIDGE_THROWSPEC +#else +// Visual Studio 10 and earlier pay too much mind to useless throw () spec. +// +# define LUABRIDGE_THROWSPEC throw () +#endif + +//============================================================================== +/** + * Traits class for unrolling the type list values into function arguments. + */ +template +struct Caller; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & params) + { + return fn (); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues &) + { + return (obj->*fn) (); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template +struct Caller +{ + template + static ReturnType f (Fn& fn, TypeListValues & tvl) + { + return fn (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd); + } + + template + static ReturnType f (T* obj, MemFn& fn, TypeListValues & tvl) + { + return (obj->*fn) (tvl.hd, tvl.tl.hd, tvl.tl.tl.hd, tvl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.hd, tvl.tl.tl.tl.tl.tl.tl.tl.hd, + tvl.tl.tl.tl.tl.tl.tl.tl.tl.hd); + } +}; + +template +ReturnType doCall (Fn& fn, TypeListValues & tvl) +{ + return Caller ::value>::f (fn, tvl); +} + +template +static ReturnType doCall(T* obj, MemFn& fn, TypeListValues & tvl) +{ + return Caller ::value>::f (obj, fn, tvl); +} + +//============================================================================== +/** + Traits for function pointers. + + There are three types of functions: global, non-const member, and const + member. These templates determine the type of function, which class type it + belongs to if it is a class member, the const-ness if it is a member + function, and the type information for the return value and argument list. + + Expansions are provided for functions with up to 8 parameters. This can be + manually extended, or expanded to an arbitrary amount using C++11 features. +*/ +template +struct FuncTraits +{ +}; + +#ifndef LUABRIDGE_CXX11 + +/* Ordinary function pointers. */ + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef None Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +/* Windows: WINAPI (a.k.a. __stdcall) function pointers. */ + +#ifdef _M_IX86 // Windows 32bit only + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef None Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + typedef D DeclType; + typedef R ReturnType; + typedef TypeList > > > > > > > Params; + static R call (D fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +#endif // _M_IX86 + +/* Non-const member function pointers. */ + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef None Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > > > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > > > > Params; + static R call (T* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +/* Const member function pointers. */ + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef None Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > Params; + static R call (T const* obj, R (T::*fp) (P1, P2) const, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > > Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > > > Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + typedef D DeclType; + typedef T ClassType; + typedef R ReturnType; + typedef TypeList > > > > > > > Params; + static R call (T const* obj, D fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +#else // ifndef LUABRIDGE_CXX11 + +/* Ordinary function pointers. */ + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + using DeclType = R (*) (ParamList...); + using ReturnType = R; + using Params = typename MakeTypeList ::Result; + + static R call (const DeclType& fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +/* Windows: WINAPI (a.k.a. __stdcall) function pointers. */ + +#ifdef _M_IX86 // Windows 32bit only + +template +struct FuncTraits +{ + static bool const isMemberFunction = false; + using DeclType = R (__stdcall *) (ParamList...); + using ReturnType = R; + using Params = typename MakeTypeList ::Result; + + static R call (const DeclType& fp, TypeListValues & tvl) + { + return doCall (fp, tvl); + } +}; + +#endif // _M_IX86 + +/* Non-const member function pointers. */ + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = false; + using DeclType = R (T::*) (ParamList...); + using ClassType = T; + using ReturnType = R; + using Params = typename MakeTypeList ::Result; + + static R call (ClassType* obj, const DeclType& fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +/* Const member function pointers. */ + +template +struct FuncTraits +{ + static bool const isMemberFunction = true; + static bool const isConstMemberFunction = true; + using DeclType = R (T::*) (ParamList...) const; + using ClassType = T; + using ReturnType = R; + using Params = typename MakeTypeList ::Result; + + static R call (const ClassType* obj, const DeclType& fp, TypeListValues & tvl) + { + return doCall (obj, fp, tvl); + } +}; + +/* std::function */ + +template +struct FuncTraits > +{ + static bool const isMemberFunction = false; + static bool const isConstMemberFunction = false; + using DeclType = std::function ; + using ReturnType = R; + using Params = typename MakeTypeList ::Result; + + static ReturnType call (DeclType& fn, TypeListValues & tvl) + { + return doCall (fn, tvl); + } +}; + +#endif // ifndef LUABRIDGE_CXX11 + +template +struct Invoke +{ + template + static int run (lua_State* L, Fn& fn) + { + try + { + ArgList args (L); + Stack ::push (L, FuncTraits ::call (fn, args)); + return 1; + } + catch (const std::exception& e) + { + return luaL_error (L, e.what ()); + } + } + + template + static int run (lua_State* L, T* object, const MemFn& fn) + { + try + { + ArgList args (L); + Stack ::push (L, FuncTraits ::call (object, fn, args)); + return 1; + } + catch (const std::exception& e) + { + return luaL_error (L, e.what ()); + } + } +}; + +template +struct Invoke +{ + template + static int run (lua_State* L, Fn& fn) + { + try + { + ArgList args (L); + FuncTraits ::call (fn, args); + return 0; + } + catch (const std::exception& e) + { + return luaL_error (L, e.what ()); + } + } + + template + static int run (lua_State* L, T* object, const MemFn& fn) + { + try + { + ArgList args (L); + FuncTraits ::call (object, fn, args); + return 0; + } + catch (const std::exception& e) + { + return luaL_error (L, e.what ()); + } + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/Iterator.h b/3rd_party/lua/LuaBridge/detail/Iterator.h new file mode 100644 index 00000000..6c176232 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Iterator.h @@ -0,0 +1,154 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2018, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include + +#include + + +namespace luabridge { + +/** Allows table iteration. +*/ +class Iterator +{ + lua_State* m_L; + LuaRef m_table; + LuaRef m_key; + LuaRef m_value; + + void next () + { + m_table.push (); + m_key.push (); + if (lua_next (m_L, -2)) + { + m_value.pop (); + m_key.pop (); + } + else + { + m_key = Nil (); + m_value = Nil (); + } + lua_pop (m_L, 1); + } + +public: + explicit Iterator (const LuaRef& table, bool isEnd = false) + : m_L (table.state ()) + , m_table (table) + , m_key (table.state ()) // m_key is nil + , m_value (table.state ()) // m_value is nil + { + if (!isEnd) + { + next (); // get the first (key, value) pair from table + } + } + + lua_State* state () const + { + return m_L; + } + + std::pair operator* () const + { + return std::make_pair (m_key, m_value); + } + + LuaRef operator-> () const + { + return m_value; + } + + bool operator!= (const Iterator& rhs) const + { + assert (m_L == rhs.m_L); + return !m_table.rawequal (rhs.m_table) || !m_key.rawequal (rhs.m_key); + } + + Iterator& operator++ () + { + if (isNil ()) + { + // if the iterator reaches the end, do nothing + return *this; + } + else + { + next (); + return *this; + } + } + + bool isNil () const + { + return m_key.isNil (); + } + + LuaRef key () const + { + return m_key; + } + + LuaRef value () const + { + return m_value; + } + +private: + // Don't use postfix increment, it is less efficient + Iterator operator++ (int); +}; + +class Range +{ + Iterator m_begin; + Iterator m_end; + +public: + Range (const Iterator& begin, const Iterator& end) + : m_begin (begin) + , m_end (end) + { + } + + const Iterator& begin () const { return m_begin; } + const Iterator& end () const { return m_end; } +}; + +inline Range pairs (const LuaRef& table) +{ + return Range (Iterator (table, false), Iterator (table, true)); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/LuaException.h b/3rd_party/lua/LuaBridge/detail/LuaException.h new file mode 100644 index 00000000..836cb852 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/LuaException.h @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco + Copyright 2008, Nigel Atkinson + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include +#include + +namespace luabridge { + +class LuaException : public std::exception +{ +private: + lua_State* m_L; + std::string m_what; + +public: + //---------------------------------------------------------------------------- + /** + Construct a LuaException after a lua_pcall(). + */ + LuaException (lua_State* L, int /*code*/) + : m_L (L) + { + whatFromStack (); + } + + //---------------------------------------------------------------------------- + + LuaException (lua_State *L, + char const*, + char const*, + long) + : m_L (L) + { + whatFromStack (); + } + + //---------------------------------------------------------------------------- + + ~LuaException() throw () + { + } + + //---------------------------------------------------------------------------- + + char const* what() const throw () + { + return m_what.c_str(); + } + + //============================================================================ + /** + Throw an exception. + + This centralizes all the exceptions thrown, so that we can set + breakpoints before the stack is unwound, or otherwise customize the + behavior. + */ + template + static void Throw (Exception e) + { + throw e; + } + + //---------------------------------------------------------------------------- + /** + Wrapper for lua_pcall that throws. + */ + static void pcall (lua_State* L, int nargs = 0, int nresults = 0, int msgh = 0) + { + int code = lua_pcall (L, nargs, nresults, msgh); + + if (code != LUABRIDGE_LUA_OK) + Throw (LuaException (L, code)); + } + + //---------------------------------------------------------------------------- + /** + Initializes error handling. Subsequent Lua errors are translated to C++ exceptions. + */ + static void enableExceptions (lua_State* L) + { + lua_atpanic (L, throwAtPanic); + } + +protected: + void whatFromStack () + { + if (lua_gettop (m_L) > 0) + { + char const* s = lua_tostring (m_L, -1); + m_what = s ? s : ""; + } + else + { + // stack is empty + m_what = "missing error"; + } + } + +private: + static int throwAtPanic (lua_State* L) + { + throw LuaException (L, -1); + } +}; + +//---------------------------------------------------------------------------- +/** + Initializes error handling. Subsequent Lua errors are translated to C++ exceptions. +*/ +static void enableExceptions (lua_State* L) +{ + LuaException::enableExceptions (L); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/LuaHelpers.h b/3rd_party/lua/LuaBridge/detail/LuaHelpers.h new file mode 100644 index 00000000..e336cf2b --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/LuaHelpers.h @@ -0,0 +1,151 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include + +namespace luabridge { + +// These are for Lua versions prior to 5.2.0. +// +#if LUA_VERSION_NUM < 502 +inline int lua_absindex (lua_State* L, int idx) +{ + if (idx > LUA_REGISTRYINDEX && idx < 0) + return lua_gettop (L) + idx + 1; + else + return idx; +} + +inline void lua_rawgetp (lua_State* L, int idx, void const* p) +{ + idx = lua_absindex (L, idx); + lua_pushlightuserdata (L, const_cast (p)); + lua_rawget (L,idx); +} + +inline void lua_rawsetp (lua_State* L, int idx, void const* p) +{ + idx = lua_absindex (L, idx); + lua_pushlightuserdata (L, const_cast (p)); + // put key behind value + lua_insert (L, -2); + lua_rawset (L, idx); +} + +#define LUA_OPEQ 1 +#define LUA_OPLT 2 +#define LUA_OPLE 3 + +inline int lua_compare (lua_State* L, int idx1, int idx2, int op) +{ + switch (op) + { + case LUA_OPEQ: + return lua_equal (L, idx1, idx2); + break; + + case LUA_OPLT: + return lua_lessthan (L, idx1, idx2); + break; + + case LUA_OPLE: + return lua_equal (L, idx1, idx2) || lua_lessthan (L, idx1, idx2); + break; + + default: + return 0; + }; +} + +inline int get_length (lua_State* L, int idx) +{ + return int (lua_objlen (L, idx)); +} + +#else +inline int get_length (lua_State* L, int idx) +{ + lua_len (L, idx); + int len = int (luaL_checknumber (L, -1)); + lua_pop (L, 1); + return len; +} + +#endif + +#ifndef LUA_OK +# define LUABRIDGE_LUA_OK 0 +#else +# define LUABRIDGE_LUA_OK LUA_OK +#endif + +/** Get a table value, bypassing metamethods. +*/ +inline void rawgetfield (lua_State* L, int index, char const* key) +{ + assert (lua_istable (L, index)); + index = lua_absindex (L, index); + lua_pushstring (L, key); + lua_rawget (L, index); +} + +/** Set a table value, bypassing metamethods. +*/ +inline void rawsetfield (lua_State* L, int index, char const* key) +{ + assert (lua_istable (L, index)); + index = lua_absindex (L, index); + lua_pushstring (L, key); + lua_insert (L, -2); + lua_rawset (L, index); +} + +/** Returns true if the value is a full userdata (not light). +*/ +inline bool isfulluserdata (lua_State* L, int index) +{ + return lua_isuserdata (L, index) && !lua_islightuserdata (L, index); +} + +/** Test lua_State objects for global equality. + + This can determine if two different lua_State objects really point + to the same global state, such as when using coroutines. + + @note This is used for assertions. +*/ +inline bool equalstates (lua_State* L1, lua_State* L2) +{ + return lua_topointer (L1, LUA_REGISTRYINDEX) == + lua_topointer (L2, LUA_REGISTRYINDEX); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/LuaRef.h b/3rd_party/lua/LuaBridge/detail/LuaRef.h new file mode 100644 index 00000000..995c4650 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/LuaRef.h @@ -0,0 +1,1051 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2018, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + Copyright 2008, Nigel Atkinson + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include +#include + +#include +#include +#include +#include + +namespace luabridge { + +//------------------------------------------------------------------------------ +/** + Type tag for representing LUA_TNIL. + + Construct one of these using `Nil ()` to represent a Lua nil. This is faster + than creating a reference in the registry to nil. Example: + + LuaRef t (LuaRef::createTable (L)); + ... + t ["k"] = Nil (); // assign nil +*/ +struct Nil +{ +}; + + +//------------------------------------------------------------------------------ +/** + Stack specialization for Nil. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, Nil) + { + lua_pushnil (L); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TTABLE; + } +}; + +/** + * Base class for LuaRef and table value proxy classes. + */ +template +class LuaRefBase +{ +protected: + //---------------------------------------------------------------------------- + /** + Pop the Lua stack. + + Pops the specified number of stack items on destruction. We use this + when returning objects, to avoid an explicit temporary variable, since + the destructor executes after the return statement. For example: + + template + U cast (lua_State* L) + { + StackPop p (L, 1); + ... + return U (); // dtor called after this line + } + + @note The `StackPop` object must always be a named local variable. + */ + class StackPop + { + public: + /** Create a StackPop object. + + @param count The number of stack entries to pop on destruction. + */ + StackPop (lua_State* L, int count) + : m_L (L) + , m_count (count) + { + } + + ~StackPop () + { + lua_pop (m_L, m_count); + } + + private: + lua_State* m_L; + int m_count; + }; + + friend struct Stack ; + + //---------------------------------------------------------------------------- + /** + Type tag for stack construction. + */ + struct FromStack { }; + + LuaRefBase (lua_State* L) + : m_L (L) + { + } + + //---------------------------------------------------------------------------- + /** + Create a reference to this ref. + + This is used internally. + */ + int createRef () const + { + impl ().push (); + return luaL_ref (m_L, LUA_REGISTRYINDEX); + } + +public: + //---------------------------------------------------------------------------- + /** + converts to a string using luas tostring function + */ + std::string tostring () const + { + lua_getglobal (m_L, "tostring"); + impl ().push (); + lua_call (m_L, 1, 1); + const char* str = lua_tostring (m_L, -1); + lua_pop (m_L, 1); + return str; + } + + //---------------------------------------------------------------------------- + /** + Print a text description of the value to a stream. + + This is used for diagnostics. + */ + void print (std::ostream& os) const + { + switch (type ()) + { + case LUA_TNIL: + os << "nil"; + break; + + case LUA_TNUMBER: + os << cast (); + break; + + case LUA_TBOOLEAN: + os << (cast () ? "true" : "false"); + break; + + case LUA_TSTRING: + os << '"' << cast () << '"'; + break; + + case LUA_TTABLE: + os << "table: " << tostring (); + break; + + case LUA_TFUNCTION: + os << "function: " << tostring (); + break; + + case LUA_TUSERDATA: + os << "userdata: " << tostring (); + break; + + case LUA_TTHREAD: + os << "thread: " << tostring (); + break; + + case LUA_TLIGHTUSERDATA: + os << "lightuserdata: " << tostring (); + break; + + default: + os << "unknown"; + break; + } + } + + //------------------------------------------------------------------------------ + /** + Write a LuaRef to a stream. + + This allows LuaRef and table proxies to work with streams. + */ + friend std::ostream& operator<< (std::ostream& os, LuaRefBase const& ref) + { + ref.print (os); + return os; + } + + //============================================================================ + // + // This group of member functions is mirrored in Proxy + // + + /** Retrieve the lua_State associated with the reference. + */ + lua_State* state () const + { + return m_L; + } + + //---------------------------------------------------------------------------- + /** + Place the object onto the Lua stack. + */ + void push (lua_State* L) const + { + assert (equalstates (L, m_L)); + (void) L; + impl ().push (); + } + + //---------------------------------------------------------------------------- + /** + Pop the top of Lua stack and assign the ref to m_ref + */ + void pop (lua_State* L) + { + assert (equalstates (L, m_L)); + (void) L; + impl ().pop (); + } + + //---------------------------------------------------------------------------- + /** + Determine the object type. + + The return values are the same as for `lua_type`. + */ + /** @{ */ + int type () const + { + impl ().push (); + StackPop p (m_L, 1); + return lua_type (m_L, -1); + } + + // should never happen + // bool isNone () const { return m_ref == LUA_NOREF; } + + bool isNil () const { return type () == LUA_TNIL; } + bool isBool () const { return type () == LUA_TBOOLEAN; } + bool isNumber () const { return type () == LUA_TNUMBER; } + bool isString () const { return type () == LUA_TSTRING; } + bool isTable () const { return type () == LUA_TTABLE; } + bool isFunction () const { return type () == LUA_TFUNCTION; } + bool isUserdata () const { return type () == LUA_TUSERDATA; } + bool isThread () const { return type () == LUA_TTHREAD; } + bool isLightUserdata () const { return type () == LUA_TLIGHTUSERDATA; } + + /** @} */ + + //---------------------------------------------------------------------------- + /** + Perform an explicit conversion. + */ + template + T cast () const + { + StackPop p (m_L, 1); + impl ().push (); + return Stack ::get (m_L, -1); + } + + //---------------------------------------------------------------------------- + /** + Type check + */ + template + bool isInstance () const + { + StackPop p (m_L, 1); + impl ().push (); + return Stack ::isInstance (m_L, -1); + } + + //---------------------------------------------------------------------------- + /** + Universal implicit conversion operator. + + NOTE: Visual Studio 2010 and 2012 have a bug where this function + is not used. See: + + http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/e30b2664-a92d-445c-9db2-e8e0fbde2014 + https://connect.microsoft.com/VisualStudio/feedback/details/771509/correct-code-doesnt-compile + + // This code snippet fails to compile in vs2010,vs2012 + struct S { + template operator T () const { return T (); } + }; + int main () { + S () || false; + return 0; + } + */ + template + operator T () const + { + return cast (); + } + + //---------------------------------------------------------------------------- + /** + Universal comparison operators. + */ + /** @{ */ + template + bool operator== (T rhs) const + { + StackPop p (m_L, 2); + impl ().push (); + Stack ::push (m_L, rhs); + return lua_compare (m_L, -2, -1, LUA_OPEQ) == 1; + } + + template + bool operator< (T rhs) const + { + StackPop p (m_L, 2); + impl ().push ();; + Stack ::push (m_L, rhs); + int lhsType = lua_type (m_L, -2); + int rhsType = lua_type (m_L, -1); + if (lhsType != rhsType) + { + return lhsType < rhsType; + } + return lua_compare (m_L, -2, -1, LUA_OPLT) == 1; + } + + template + bool operator<= (T rhs) const + { + StackPop p (m_L, 2); + impl ().push ();; + Stack ::push (m_L, rhs); + int lhsType = lua_type (m_L, -2); + int rhsType = lua_type (m_L, -1); + if (lhsType != rhsType) + { + return lhsType <= rhsType; + } + return lua_compare (m_L, -2, -1, LUA_OPLE) == 1; + } + + template + bool operator> (T rhs) const + { + StackPop p (m_L, 2); + impl ().push ();; + Stack ::push (m_L, rhs); + int lhsType = lua_type (m_L, -2); + int rhsType = lua_type (m_L, -1); + if (lhsType != rhsType) + { + return lhsType > rhsType; + } + return lua_compare (m_L, -1, -2, LUA_OPLT) == 1; + } + + template + bool operator>= (T rhs) const + { + StackPop p (m_L, 2); + impl ().push ();; + Stack ::push (m_L, rhs); + int lhsType = lua_type (m_L, -2); + int rhsType = lua_type (m_L, -1); + if (lhsType != rhsType) + { + return lhsType >= rhsType; + } + return lua_compare (m_L, -1, -2, LUA_OPLE) == 1; + } + + template + bool rawequal (T rhs) const + { + StackPop p (m_L, 2); + impl ().push ();; + Stack ::push (m_L, rhs); + return lua_rawequal (m_L, -1, -2) == 1; + } + /** @} */ + + //---------------------------------------------------------------------------- + /** + Append a value to the table. + + If the table is a sequence this will add another element to it. + */ + template + void append (T v) const + { + impl ().push ();; + Stack ::push (m_L, v); + luaL_ref (m_L, -2); + lua_pop (m_L, 1); + } + + //---------------------------------------------------------------------------- + /** + Call the length operator. + + This is identical to applying the Lua # operator. + */ + int length () const + { + StackPop p (m_L, 1); + impl ().push ();; + return get_length (m_L, -1); + } + + //---------------------------------------------------------------------------- + /** + Call Lua code. + + These overloads allow Lua code to be called with up to 8 parameters. + The return value is provided as a LuaRef (which may be LUA_REFNIL). + If an error occurs, a LuaException is thrown. + */ + /** @{ */ + LuaRef operator() () const + { + impl ().push ();; + LuaException::pcall (m_L, 0, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1) const + { + impl ().push ();; + Stack ::push (m_L, p1); + LuaException::pcall (m_L, 1, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2) const + { + impl ().push ();; + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + LuaException::pcall (m_L, 2, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2, P3 p3) const + { + impl ().push ();; + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + Stack ::push (m_L, p3); + LuaException::pcall (m_L, 3, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4) const + { + impl ().push ();; + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + Stack ::push (m_L, p3); + Stack ::push (m_L, p4); + LuaException::pcall (m_L, 4, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const + { + impl ().push ();; + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + Stack ::push (m_L, p3); + Stack ::push (m_L, p4); + Stack ::push (m_L, p5); + LuaException::pcall (m_L, 5, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const + { + impl ().push ();; + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + Stack ::push (m_L, p3); + Stack ::push (m_L, p4); + Stack ::push (m_L, p5); + Stack ::push (m_L, p6); + LuaException::pcall (m_L, 6, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const + { + impl ().push ();; + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + Stack ::push (m_L, p3); + Stack ::push (m_L, p4); + Stack ::push (m_L, p5); + Stack ::push (m_L, p6); + Stack ::push (m_L, p7); + LuaException::pcall (m_L, 7, 1); + return LuaRef::fromStack (m_L); + } + + template + LuaRef operator() (P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const + { + impl ().push (); + Stack ::push (m_L, p1); + Stack ::push (m_L, p2); + Stack ::push (m_L, p3); + Stack ::push (m_L, p4); + Stack ::push (m_L, p5); + Stack ::push (m_L, p6); + Stack ::push (m_L, p7); + Stack ::push (m_L, p8); + LuaException::pcall (m_L, 8, 1); + return LuaRef::fromStack (m_L); + } + /** @} */ + + //============================================================================ + +protected: + lua_State* m_L; + +private: + const Impl& impl () const + { + return static_cast (*this); + } + + Impl& impl () + { + return static_cast (*this); + } +}; + +//------------------------------------------------------------------------------ +/** + Lightweight reference to a Lua object. + + The reference is maintained for the lifetime of the C++ object. +*/ +class LuaRef : public LuaRefBase +{ + //---------------------------------------------------------------------------- + /** + A proxy for representing table values. + */ + class Proxy : public LuaRefBase + { + friend class LuaRef; + + public: + //-------------------------------------------------------------------------- + /** + Construct a Proxy from a table value. + + The table is in the registry, and the key is at the top of the stack. + The key is popped off the stack. + */ + Proxy (lua_State* L, int tableRef) + : LuaRefBase (L) + , m_tableRef (LUA_NOREF) + , m_keyRef (luaL_ref (L, LUA_REGISTRYINDEX)) + { + lua_rawgeti (m_L, LUA_REGISTRYINDEX, tableRef); + m_tableRef = luaL_ref (L, LUA_REGISTRYINDEX); + } + + //-------------------------------------------------------------------------- + /** + Create a Proxy via copy constructor. + + It is best to avoid code paths that invoke this, because it creates + an extra temporary Lua reference. Typically this is done by passing + the Proxy parameter as a `const` reference. + */ + Proxy (Proxy const& other) + : LuaRefBase (other.m_L) + , m_tableRef (LUA_NOREF) + , m_keyRef (LUA_NOREF) + { + lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_tableRef); + m_tableRef = luaL_ref (m_L, LUA_REGISTRYINDEX); + + lua_rawgeti (m_L, LUA_REGISTRYINDEX, other.m_keyRef); + m_keyRef = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //-------------------------------------------------------------------------- + /** + Destroy the proxy. + + This does not destroy the table value. + */ + ~Proxy () + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_keyRef); + luaL_unref (m_L, LUA_REGISTRYINDEX, m_tableRef); + } + + //-------------------------------------------------------------------------- + /** + Assign a new value to this table key. + + This may invoke metamethods. + */ + template + Proxy& operator= (T v) + { + StackPop p (m_L, 1); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); + Stack ::push (m_L, v); + lua_settable (m_L, -3); + return *this; + } + + //-------------------------------------------------------------------------- + /** + Assign a new value to this table key. + + The assignment is raw, no metamethods are invoked. + */ + template + Proxy& rawset (T v) + { + StackPop p (m_L, 1); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); + Stack ::push (m_L, v); + lua_rawset (m_L, -3); + return *this; + } + + //-------------------------------------------------------------------------- + /** + Push the value onto the Lua stack. + */ + using LuaRefBase::push; + + void push () const + { + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_tableRef); + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_keyRef); + lua_gettable (m_L, -2); + lua_remove (m_L, -2); // remove the table + } + + //-------------------------------------------------------------------------- + /** + Access a table value using a key. + + This invokes metamethods. + */ + template + Proxy operator[] (T key) const + { + return LuaRef (*this) [key]; + } + + //-------------------------------------------------------------------------- + /** + Access a table value using a key. + + The operation is raw, metamethods are not invoked. The result is + passed by value and may not be modified. + */ + template + LuaRef rawget (T key) const + { + return LuaRef (*this).rawget (key); + } + + private: + int m_tableRef; + int m_keyRef; + }; + + friend struct Stack ; + friend struct Stack ; + + //---------------------------------------------------------------------------- + /** + Create a reference to an object at the top of the Lua stack and pop it. + + This constructor is private and not invoked directly. + Instead, use the `fromStack` function. + + @note The object is popped. + */ + LuaRef (lua_State* L, FromStack) + : LuaRefBase (L) + , m_ref (luaL_ref (m_L, LUA_REGISTRYINDEX)) + { + } + + //---------------------------------------------------------------------------- + /** + Create a reference to an object on the Lua stack. + + This constructor is private and not invoked directly. + Instead, use the `fromStack` function. + + @note The object is not popped. + */ + LuaRef (lua_State* L, int index, FromStack) + : LuaRefBase (L) + , m_ref (LUA_NOREF) + { + lua_pushvalue (m_L, index); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + +public: + //---------------------------------------------------------------------------- + /** + Create a nil reference. + + The LuaRef may be assigned later. + */ + LuaRef (lua_State* L) + : LuaRefBase (L) + , m_ref (LUA_NOREF) + { + } + + //---------------------------------------------------------------------------- + /** + Create a reference to a value. + */ + template + LuaRef (lua_State* L, T v) + : LuaRefBase (L) + , m_ref (LUA_NOREF) + { + Stack ::push (m_L, v); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //---------------------------------------------------------------------------- + /** + Create a reference to a table value. + */ + LuaRef (Proxy const& v) + : LuaRefBase (v.state ()) + , m_ref (v.createRef ()) + { + } + + //---------------------------------------------------------------------------- + /** + Create a new reference to an existing reference. + */ + LuaRef (LuaRef const& other) + : LuaRefBase (other.m_L) + , m_ref (other.createRef ()) + { + } + + //---------------------------------------------------------------------------- + /** + Destroy a reference. + + The corresponding Lua registry reference will be released. + + @note If the state refers to a thread, it is the responsibility of the + caller to ensure that the thread still exists when the LuaRef + is destroyed. + */ + ~LuaRef () + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); + } + + //---------------------------------------------------------------------------- + /** + Return a LuaRef from a top stack item. + + The stack item is not popped. + */ + static LuaRef fromStack (lua_State* L) + { + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Return a LuaRef from a stack item. + + The stack item is not popped. + */ + static LuaRef fromStack (lua_State* L, int index) + { + lua_pushvalue (L, index); + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Create a new empty table and return a reference to it. + + It is also possible to use the free function `newTable`. + + @see ::luabridge::newTable + */ + static LuaRef newTable (lua_State* L) + { + lua_newtable (L); + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Return a reference to a named global. + + It is also possible to use the free function `getGlobal`. + + @see ::luabridge::getGlobal + */ + static LuaRef getGlobal (lua_State *L, char const* name) + { + lua_getglobal (L, name); + return LuaRef (L, FromStack ()); + } + + //---------------------------------------------------------------------------- + /** + Assign another LuaRef to this LuaRef. + */ + LuaRef& operator= (LuaRef const& rhs) + { + LuaRef ref (rhs); + swap (ref); + return *this; + } + + //---------------------------------------------------------------------------- + /** + Assign Proxy to this LuaRef. + */ + LuaRef& operator= (LuaRef::Proxy const& rhs) + { + LuaRef ref (rhs); + swap (ref); + return *this; + } + + //---------------------------------------------------------------------------- + /** + Assign nil to this LuaRef. + */ + LuaRef& operator= (Nil const&) + { + LuaRef ref (m_L); + swap (ref); + return *this; + } + + //---------------------------------------------------------------------------- + /** + Assign a different value to this LuaRef. + */ + template + LuaRef& operator= (T rhs) + { + LuaRef ref (m_L, rhs); + swap (ref); + return *this; + } + + //---------------------------------------------------------------------------- + /** + Place the object onto the Lua stack. + */ + using LuaRefBase::push; + + void push () const + { + lua_rawgeti (m_L, LUA_REGISTRYINDEX, m_ref); + } + + //---------------------------------------------------------------------------- + /** + Pop the top of Lua stack and assign the ref to m_ref + */ + void pop () + { + luaL_unref (m_L, LUA_REGISTRYINDEX, m_ref); + m_ref = luaL_ref (m_L, LUA_REGISTRYINDEX); + } + + //---------------------------------------------------------------------------- + /** + Access a table value using a key. + + This invokes metamethods. + */ + template + Proxy operator[] (T key) const + { + Stack ::push (m_L, key); + return Proxy (m_L, m_ref); + } + + //-------------------------------------------------------------------------- + /** + Access a table value using a key. + + The operation is raw, metamethods are not invoked. The result is + passed by value and may not be modified. + */ + template + LuaRef rawget (T key) const + { + StackPop (m_L, 1); + push (m_L); + Stack ::push (m_L, key); + lua_rawget (m_L, -2); + return LuaRef (m_L, FromStack ()); + } + +private: + void swap (LuaRef& other) + { + std::swap (m_L, other.m_L); + std::swap (m_ref, other.m_ref); + } + + int m_ref; +}; + +//------------------------------------------------------------------------------ +/** + * Stack specialization for `LuaRef`. + */ +template <> +struct Stack +{ + // The value is const& to prevent a copy construction. + // + static void push (lua_State* L, LuaRef const& v) + { + v.push (L); + } + + static LuaRef get (lua_State* L, int index) + { + return LuaRef::fromStack (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + * Stack specialization for `Proxy`. + */ +template <> +struct Stack +{ + // The value is const& to prevent a copy construction. + // + static void push (lua_State* L, LuaRef::Proxy const& v) + { + v.push (L); + } +}; + +//------------------------------------------------------------------------------ +/** + Create a reference to a new, empty table. + + This is a syntactic abbreviation for LuaRef::newTable (). +*/ +inline LuaRef newTable (lua_State* L) +{ + return LuaRef::newTable (L); +} + +//------------------------------------------------------------------------------ +/** + Create a reference to a value in the global table. + + This is a syntactic abbreviation for LuaRef::getGlobal (). +*/ +inline LuaRef getGlobal (lua_State *L, char const* name) +{ + return LuaRef::getGlobal (L, name); +} + +//------------------------------------------------------------------------------ + +// more C++-like cast syntax +// +template +T LuaRef_cast (LuaRef const& lr) +{ + return lr.cast (); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/Namespace.h b/3rd_party/lua/LuaBridge/detail/Namespace.h new file mode 100644 index 00000000..68ae21fa --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Namespace.h @@ -0,0 +1,1252 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +namespace luabridge { + +namespace detail { + +/** + * Base for class and namespace registration. + * Maintains Lua stack in the proper state. + * Once beginNamespace, beginClass or deriveClass is called the parent + * object upon its destruction may no longer clear the Lua stack. + * Then endNamespace or endClass is called, a new parent is created + * and the child transfers the responsibility for clearing stack to it. + * So there can be maximum one "active" registrar object. + */ +class Registrar +{ +protected: + lua_State* const L; + int mutable m_stackSize; + + Registrar (lua_State* L) + : L (L) + , m_stackSize (0) + { + } + + Registrar (const Registrar& rhs) + : L (rhs.L) + , m_stackSize (rhs.m_stackSize) + { + rhs.m_stackSize = 0; + } + +#ifndef _MSC_VER + // MS compiler thinks it's the 2nd copy ctor + Registrar(Registrar& rhs) + : L (rhs.L) + , m_stackSize (rhs.m_stackSize) + { + rhs.m_stackSize = 0; + } +#endif // ifndef _MSC_VER + + Registrar& operator= (const Registrar& rhs) + { + Registrar tmp (rhs); + std::swap (m_stackSize, tmp.m_stackSize); + return *this; + } + + ~Registrar () + { + if (m_stackSize > 0) + { + assert (m_stackSize <= lua_gettop (L)); + lua_pop (L, m_stackSize); + } + } + + void assertIsActive () const + { + if (m_stackSize == 0) + { + throw std::logic_error ("Unable to continue registration"); + } + } +}; + +} // namespace detail + +/** Provides C++ to Lua registration capabilities. + + This class is not instantiated directly, call `getGlobalNamespace` to start + the registration process. +*/ +class Namespace : public detail::Registrar +{ + //============================================================================ + /** + Error reporting. + + VF: This function looks handy, why aren't we using it? + */ +#if 0 + static int luaError (lua_State* L, std::string message) + { + assert (lua_isstring (L, lua_upvalueindex (1))); + std::string s; + + // Get information on the caller's caller to format the message, + // so the error appears to originate from the Lua source. + lua_Debug ar; + int result = lua_getstack (L, 2, &ar); + if (result != 0) + { + lua_getinfo (L, "Sl", &ar); + s = ar.short_src; + if (ar.currentline != -1) + { + // poor mans int to string to avoid . + lua_pushnumber (L, ar.currentline); + s = s + ":" + lua_tostring (L, -1) + ": "; + lua_pop (L, 1); + } + } + + s = s + message; + + return luaL_error (L, s.c_str ()); + } +#endif + + /** + Factored base to reduce template instantiations. + */ + class ClassBase : public detail::Registrar + { + public: + explicit ClassBase (Namespace& parent) + : Registrar (parent) + { + } + + using Registrar::operator=; + + protected: + //-------------------------------------------------------------------------- + /** + Create the const table. + */ + void createConstTable (const char* name, bool trueConst = true) + { + std::string type_name = std::string (trueConst ? "const " : "") + name; + + // Stack: namespace table (ns) + lua_newtable (L); // Stack: ns, const table (co) + lua_pushvalue (L, -1); // Stack: ns, co, co + lua_setmetatable (L, -2); // co.__metatable = co. Stack: ns, co + + lua_pushstring (L, type_name.c_str ()); + lua_rawsetp (L, -2, getTypeKey ()); // co [typeKey] = name. Stack: ns, co + + lua_pushcfunction (L, &CFunc::indexMetaMethod); + rawsetfield (L, -2, "__index"); + + lua_pushcfunction (L, &CFunc::newindexObjectMetaMethod); + rawsetfield (L, -2, "__newindex"); + + lua_newtable (L); + lua_rawsetp (L, -2, getPropgetKey ()); + + if (Security::hideMetatables ()) + { + lua_pushnil (L); + rawsetfield (L, -2, "__metatable"); + } + } + + //-------------------------------------------------------------------------- + /** + Create the class table. + + The Lua stack should have the const table on top. + */ + void createClassTable (char const* name) + { + // Stack: namespace table (ns), const table (co) + + // Class table is the same as const table except the propset table + createConstTable (name, false); // Stack: ns, co, cl + + lua_newtable (L); // Stack: ns, co, cl, propset table (ps) + lua_rawsetp (L, -2, getPropsetKey ()); // cl [propsetKey] = ps. Stack: ns, co, cl + + lua_pushvalue (L, -2); // Stack: ns, co, cl, co + lua_rawsetp(L, -2, getConstKey ()); // cl [constKey] = co. Stack: ns, co, cl + + lua_pushvalue (L, -1); // Stack: ns, co, cl, cl + lua_rawsetp (L, -3, getClassKey ()); // co [classKey] = cl. Stack: ns, co, cl + } + + //-------------------------------------------------------------------------- + /** + Create the static table. + */ + void createStaticTable (char const* name) + { + // Stack: namespace table (ns), const table (co), class table (cl) + lua_newtable (L); // Stack: ns, co, cl, visible static table (vst) + lua_newtable (L); // Stack: ns, co, cl, st, static metatable (st) + lua_pushvalue (L, -1); // Stack: ns, co, cl, vst, st, st + lua_setmetatable (L, -3); // st.__metatable = mt. Stack: ns, co, cl, vst, st + lua_insert (L, -2); // Stack: ns, co, cl, st, vst + rawsetfield (L, -5, name); // ns [name] = vst. Stack: ns, co, cl, st + +#if 0 + lua_pushlightuserdata (L, this); + lua_pushcclosure (L, &tostringMetaMethod, 1); + rawsetfield (L, -2, "__tostring"); +#endif + lua_pushcfunction (L, &CFunc::indexMetaMethod); + rawsetfield (L, -2, "__index"); + + lua_pushcfunction (L, &CFunc::newindexStaticMetaMethod); + rawsetfield (L, -2, "__newindex"); + + lua_newtable (L); // Stack: ns, co, cl, st, proget table (pg) + lua_rawsetp (L, -2, getPropgetKey ()); // st [propgetKey] = pg. Stack: ns, co, cl, st + + lua_newtable (L); // Stack: ns, co, cl, st, propset table (ps) + lua_rawsetp (L, -2, getPropsetKey ()); // st [propsetKey] = pg. Stack: ns, co, cl, st + + lua_pushvalue (L, -2); // Stack: ns, co, cl, st, cl + lua_rawsetp(L, -2, getClassKey()); // st [classKey] = cl. Stack: ns, co, cl, st + + if (Security::hideMetatables ()) + { + lua_pushnil (L); + rawsetfield (L, -2, "__metatable"); + } + } + + //========================================================================== + /** + lua_CFunction to construct a class object wrapped in a container. + */ + template + static int ctorContainerProxy (lua_State* L) + { + typedef typename ContainerTraits ::Type T; + ArgList args (L); + T* const p = Constructor ::call (args); + UserdataSharedHelper ::push (L, p); + return 1; + } + + //-------------------------------------------------------------------------- + /** + lua_CFunction to construct a class object in-place in the userdata. + */ + template + static int ctorPlacementProxy (lua_State* L) + { + ArgList args (L); + UserdataValue * value = UserdataValue ::place (L); + Constructor ::call (value->getObject (), args); + value->commit (); + return 1; + } + + void assertStackState () const + { + // Stack: const table (co), class table (cl), static table (st) + assert (lua_istable (L, -3)); + assert (lua_istable (L, -2)); + assert (lua_istable (L, -1)); + } + }; + + //============================================================================ + // + // Class + // + //============================================================================ + /** + Provides a class registration in a lua_State. + + After construction the Lua stack holds these objects: + -1 static table + -2 class table + -3 const table + -4 enclosing namespace table + */ + template + class Class : public ClassBase + { + public: + //========================================================================== + /** + Register a new class or add to an existing class registration. + */ + Class (char const* name, Namespace& parent) + : ClassBase (parent) + { + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + rawgetfield (L, -1, name); // Stack: ns, static table (st) | nil + + if (lua_isnil (L, -1)) // Stack: ns, nil + { + lua_pop (L, 1); // Stack: ns + + createConstTable (name); // Stack: ns, const table (co) + lua_pushcfunction (L, &CFunc::gcMetaMethod ); // Stack: ns, co, function + rawsetfield (L, -2, "__gc"); // co ["__gc"] = function. Stack: ns, co + ++m_stackSize; + + createClassTable (name); // Stack: ns, co, class table (cl) + lua_pushcfunction (L, &CFunc::gcMetaMethod ); // Stack: ns, co, cl, function + rawsetfield (L, -2, "__gc"); // cl ["__gc"] = function. Stack: ns, co, cl + ++m_stackSize; + + createStaticTable (name); // Stack: ns, co, cl, st + ++m_stackSize; + + // Map T back to its tables. + lua_pushvalue (L, -1); // Stack: ns, co, cl, st, st + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo ::getStaticKey ()); // Stack: ns, co, cl, st + lua_pushvalue (L, -2); // Stack: ns, co, cl, st, cl + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo ::getClassKey ()); // Stack: ns, co, cl, st + lua_pushvalue (L, -3); // Stack: ns, co, cl, st, co + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo ::getConstKey ()); // Stack: ns, co, cl, st + } + else + { + assert (lua_istable (L, -1)); // Stack: ns, st + ++m_stackSize; + + // Map T back from its stored tables + + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getConstKey ()); // Stack: ns, st, co + lua_insert (L, -2); // Stack: ns, co, st + ++m_stackSize; + + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getClassKey ()); // Stack: ns, co, st, cl + lua_insert (L, -2); // Stack: ns, co, cl, st + ++m_stackSize; + } + } + + //========================================================================== + /** + Derive a new class. + */ + Class (char const* name, Namespace& parent, void const* const staticKey) + : ClassBase (parent) + { + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + + createConstTable (name); // Stack: ns, const table (co) + lua_pushcfunction (L, &CFunc::gcMetaMethod ); // Stack: ns, co, function + rawsetfield (L, -2, "__gc"); // co ["__gc"] = function. Stack: ns, co + ++m_stackSize; + + createClassTable (name); // Stack: ns, co, class table (cl) + lua_pushcfunction (L, &CFunc::gcMetaMethod ); // Stack: ns, co, cl, function + rawsetfield (L, -2, "__gc"); // cl ["__gc"] = function. Stack: ns, co, cl + ++m_stackSize; + + createStaticTable (name); // Stack: ns, co, cl, st + ++m_stackSize; + + lua_rawgetp (L, LUA_REGISTRYINDEX, staticKey); // Stack: ns, co, cl, st, parent st (pst) | nil + if (lua_isnil (L, -1)) // Stack: ns, co, cl, st, nil + { + ++m_stackSize; + throw std::runtime_error ("Base class is not registered"); + } + + assert (lua_istable (L, -1)); // Stack: ns, co, cl, st, pst + + lua_rawgetp (L, -1, getClassKey ()); // Stack: ns, co, cl, st, pst, parent cl (pcl) + assert (lua_istable (L, -1)); + + lua_rawgetp (L, -1, getConstKey ()); // Stack: ns, co, cl, st, pst, pcl, parent co (pco) + assert (lua_istable (L, -1)); + + lua_rawsetp (L, -6, getParentKey ()); // co [parentKey] = pco. Stack: ns, co, cl, st, pst, pcl + lua_rawsetp (L, -4, getParentKey ()); // cl [parentKey] = pcl. Stack: ns, co, cl, st, pst + lua_rawsetp (L, -2, getParentKey ()); // st [parentKey] = pst. Stack: ns, co, cl, st + + lua_pushvalue (L, -1); // Stack: ns, co, cl, st, st + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo ::getStaticKey ()); // Stack: ns, co, cl, st + lua_pushvalue (L, -2); // Stack: ns, co, cl, st, cl + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo ::getClassKey ()); // Stack: ns, co, cl, st + lua_pushvalue (L, -3); // Stack: ns, co, cl, st, co + lua_rawsetp (L, LUA_REGISTRYINDEX, ClassInfo ::getConstKey ()); // Stack: ns, co, cl, st + } + + //-------------------------------------------------------------------------- + /** + Continue registration in the enclosing namespace. + */ + Namespace endClass () + { + assert (m_stackSize > 3); + m_stackSize -= 3; + lua_pop (L, 3); + return Namespace (*this); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static data member. + */ + template + Class & addStaticProperty (char const* name, U* pu, bool isWritable = true) + { + return addStaticData (name, pu, isWritable); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static data member. + */ + template + Class & addStaticData (char const* name, U* pu, bool isWritable = true) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushlightuserdata (L, pu); // Stack: co, cl, st, pointer + lua_pushcclosure (L, &CFunc::getVariable , 1); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -2); // Stack: co, cl, st + + if (isWritable) + { + lua_pushlightuserdata (L, pu); // Stack: co, cl, st, ps, pointer + lua_pushcclosure (L, &CFunc::setVariable , 1); // Stack: co, cl, st, ps, setter + } + else + { + lua_pushstring (L, name); // Stack: co, cl, st, name + lua_pushcclosure (L, &CFunc::readOnlyError, 1); // Stack: co, cl, st, error_fn + } + CFunc::addSetter (L, name, -2); // Stack: co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static property member. + + If the set function is null, the property is read-only. + */ + template + Class & addStaticProperty (char const* name, U (*get) (), void (*set) (U) = 0) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushlightuserdata (L, reinterpret_cast (get)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -2); // Stack: co, cl, st + + if (set != 0) + { + lua_pushlightuserdata (L, reinterpret_cast (set)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // Stack: co, cl, st, setter + } + else + { + lua_pushstring (L, name); // Stack: co, cl, st, ps, name + lua_pushcclosure (L, &CFunc::readOnlyError, 1); // Stack: co, cl, st, error_fn + } + CFunc::addSetter (L, name, -2); // Stack: co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a static member function. + */ + template + Class & addStaticFunction (char const* name, FP const fp) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushlightuserdata (L, reinterpret_cast (fp)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // co, cl, st, function + rawsetfield (L, -2, name); // co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a lua_CFunction. + */ + Class & addStaticFunction (char const* name, int (*const fp) (lua_State*)) + { + return addStaticCFunction (name, fp); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a lua_CFunction. + */ + Class & addStaticCFunction (char const* name, int (*const fp) (lua_State*)) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushcfunction (L, fp); // co, cl, st, function + rawsetfield (L, -2, name); // co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a data member. + */ + template + Class & addProperty (char const* name, U T::* mp, bool isWritable = true) + { + return addData (name, mp, isWritable); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a data member. + */ + template + Class & addData (char const* name, U T::* mp, bool isWritable = true) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + typedef const U T::*mp_t; + new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); // Stack: co, cl, st, field ptr + lua_pushcclosure (L, &CFunc::getProperty , 1); // Stack: co, cl, st, getter + lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter + CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -3); // Stack: co, cl, st + + if (isWritable) + { + new (lua_newuserdata (L, sizeof (mp_t))) mp_t (mp); // Stack: co, cl, st, field ptr + lua_pushcclosure (L, &CFunc::setProperty , 1); // Stack: co, cl, st, setter + CFunc::addSetter (L, name, -3); // Stack: co, cl, st + } + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a property member. + */ + template + Class & addProperty (char const* name, TG (T::* get) () const, void (T::* set) (TS) = 0) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + typedef TG (T::*get_t) () const; + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); // Stack: co, cl, st, funcion ptr + lua_pushcclosure (L, &CFunc::CallConstMember ::f, 1); // Stack: co, cl, st, getter + lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter + CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -3); // Stack: co, cl, st + + if (set != 0) + { + typedef void (T::* set_t) (TS); + new (lua_newuserdata (L, sizeof (set_t))) set_t (set); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::CallMember ::f, 1); // Stack: co, cl, st, setter + CFunc::addSetter (L, name, -3); // Stack: co, cl, st + } + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a property member. + */ + template + Class & addProperty (char const* name, TG (T::* get) (lua_State*) const, void (T::* set) (TS, lua_State*) = 0) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + typedef TG (T::*get_t) (lua_State*) const; + new (lua_newuserdata (L, sizeof (get_t))) get_t (get); // Stack: co, cl, st, funcion ptr + lua_pushcclosure (L, &CFunc::CallConstMember ::f, 1); // Stack: co, cl, st, getter + lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter + CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -3); // Stack: co, cl, st + + if (set != 0) + { + typedef void (T::* set_t) (TS, lua_State*); + new (lua_newuserdata (L, sizeof (set_t))) set_t (set); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::CallMember ::f, 1); // Stack: co, cl, st, setter + CFunc::addSetter (L, name, -3); // Stack: co, cl, st + } + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a property member, by proxy. + + When a class is closed for modification and does not provide (or cannot + provide) the function signatures necessary to implement get or set for + a property, this will allow non-member functions act as proxies. + + Both the get and the set functions require a T const* and T* in the first + argument respectively. + */ + template + Class & addProperty (char const* name, TG (*get) (T const*), void (*set) (T*, TS) = 0) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushlightuserdata (L, reinterpret_cast (get)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // Stack: co, cl, st, getter + lua_pushvalue (L, -1); // Stack: co, cl, st,, getter, getter + CFunc::addGetter (L, name, -5); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -3); // Stack: co, cl, st + + if (set != 0) + { + lua_pushlightuserdata (L, reinterpret_cast (set)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // Stack: co, cl, st, setter + CFunc::addSetter (L, name, -3); // Stack: co, cl, st + } + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a property member, by proxy C-function. + + When a class is closed for modification and does not provide (or cannot + provide) the function signatures necessary to implement get or set for + a property, this will allow non-member functions act as proxies. + + The object userdata ('this') value is at the index 1. + The new value for set function is at the index 2. + */ + Class & addProperty (char const* name, int (*get) (lua_State*), int (*set) (lua_State*) = 0) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushcfunction (L, get); + lua_pushvalue (L, -1); // Stack: co, cl, st,, getter, getter + CFunc::addGetter (L, name, -5); // Stack: co, cl, st,, getter + CFunc::addGetter (L, name, -3); // Stack: co, cl, st, + + if (set != 0) + { + lua_pushcfunction (L, set); + CFunc::addSetter (L, name, -3); // Stack: co, cl, st, + } + + return *this; + } + +#ifdef LUABRIDGE_CXX11 + template + Class & addProperty (char const* name, + std::function get, + std::function set = nullptr) + { + using GetType = decltype (get); + new (lua_newuserdata (L, sizeof (get))) GetType (std::move (get)); // Stack: co, cl, st, function userdata (ud) + lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt) + lua_pushcfunction (L, &CFunc::gcMetaMethodAny ); // Stack: co, cl, st, ud, mt, gc function + rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt + lua_setmetatable (L, -2); // Stack: co, cl, st, ud + lua_pushcclosure (L, &CFunc::CallProxyFunctor ::f, 1); // Stack: co, cl, st, getter + lua_pushvalue (L, -1); // Stack: co, cl, st, getter, getter + CFunc::addGetter (L, name, -4); // Stack: co, cl, st, getter + CFunc::addGetter (L, name, -4); // Stack: co, cl, st + + if (set != nullptr) + { + using SetType = decltype (set); + new (lua_newuserdata (L, sizeof (set))) SetType (std::move (set)); // Stack: co, cl, st, function userdata (ud) + lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt) + lua_pushcfunction (L, &CFunc::gcMetaMethodAny ); // Stack: co, cl, st, ud, mt, gc function + rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt + lua_setmetatable (L, -2); // Stack: co, cl, st, ud + lua_pushcclosure (L, &CFunc::CallProxyFunctor ::f, 1); // Stack: co, cl, st, setter + CFunc::addSetter (L, name, -3); // Stack: co, cl, st + } + + return *this; + } + +#endif // LUABRIDGE_CXX11 + +#ifndef LUABRIDGE_CXX11 + + //-------------------------------------------------------------------------- + /** + Add or replace a member function. + */ + template + Class & addFunction (char const* name, MemFn mf) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + static const std::string GC = "__gc"; + if (name == GC) + { + throw std::logic_error (GC + " metamethod registration is forbidden"); + } + CFunc::CallMemberFunctionHelper ::isConstMemberFunction>::add (L, name, mf); + return *this; + } + +#else // ifndef LUABRIDGE_CXX11 + + //-------------------------------------------------------------------------- + /** + Add or replace a member function by std::function. + */ + template + Class & addFunction (char const* name, std::function function) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + using FnType = decltype (function); + new (lua_newuserdata (L, sizeof (function))) FnType (std::move (function)); // Stack: co, cl, st, function userdata (ud) + lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt) + lua_pushcfunction (L, &CFunc::gcMetaMethodAny ); // Stack: co, cl, st, ud, mt, gc function + rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt + lua_setmetatable (L, -2); // Stack: co, cl, st, ud + lua_pushcclosure (L, &CFunc::CallProxyFunctor ::f, 1); // Stack: co, cl, st, function + rawsetfield (L, -3, name); // Stack: co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a const member function by std::function. + */ + template + Class & addFunction (char const* name, std::function function) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + using FnType = decltype (function); + new (lua_newuserdata (L, sizeof (function))) FnType (std::move (function)); // Stack: co, cl, st, function userdata (ud) + lua_newtable (L); // Stack: co, cl, st, ud, ud metatable (mt) + lua_pushcfunction (L, &CFunc::gcMetaMethodAny ); // Stack: co, cl, st, ud, mt, gc function + rawsetfield (L, -2, "__gc"); // Stack: co, cl, st, ud, mt + lua_setmetatable (L, -2); // Stack: co, cl, st, ud + lua_pushcclosure (L, &CFunc::CallProxyFunctor ::f, 1); // Stack: co, cl, st, function + lua_pushvalue (L, -1); // Stack: co, cl, st, function, function + rawsetfield (L, -4, name); // Stack: co, cl, st, function + rawsetfield (L, -4, name); // Stack: co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a member function. + */ + template + Class & addFunction (char const* name, ReturnType (T::* mf) (Params...)) + { + using MemFn = ReturnType (T::*) (Params...); + + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + static const std::string GC = "__gc"; + if (name == GC) + { + throw std::logic_error (GC + " metamethod registration is forbidden"); + } + CFunc::CallMemberFunctionHelper ::add (L, name, mf); + return *this; + } + + template + Class & addFunction (char const* name, ReturnType (T::* mf) (Params...) const) + { + using MemFn = ReturnType (T::*) (Params...) const; + + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + static const std::string GC = "__gc"; + if (name == GC) + { + throw std::logic_error (GC + " metamethod registration is forbidden"); + } + CFunc::CallMemberFunctionHelper ::add (L, name, mf); + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a proxy function. + */ + template + Class & addFunction (char const* name, ReturnType (*proxyFn) (T* object, Params...)) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + static const std::string GC = "__gc"; + if (name == GC) + { + throw std::logic_error (GC + " metamethod registration is forbidden"); + } + using FnType = decltype (proxyFn); + lua_pushlightuserdata (L, reinterpret_cast (proxyFn)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::CallProxyFunction ::f, 1); // Stack: co, cl, st, function + rawsetfield (L, -3, name); // Stack: co, cl, st + return *this; + } + + template + Class & addFunction (char const* name, ReturnType (*proxyFn) (const T* object, Params...)) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + static const std::string GC = "__gc"; + if (name == GC) + { + throw std::logic_error (GC + " metamethod registration is forbidden"); + } + using FnType = decltype (proxyFn); + lua_pushlightuserdata (L, reinterpret_cast (proxyFn)); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::CallProxyFunction ::f, 1); // Stack: co, cl, st, function + lua_pushvalue (L, -1); // Stack: co, cl, st, function, function + rawsetfield (L, -4, name); // Stack: co, cl, st, function + rawsetfield (L, -4, name); // Stack: co, cl, st + return *this; + } + +#endif + + //-------------------------------------------------------------------------- + /** + Add or replace a member lua_CFunction. + */ + Class & addFunction (char const* name, int (T::*mfp) (lua_State*)) + { + return addCFunction (name, mfp); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a member lua_CFunction. + */ + Class & addCFunction (char const* name, int (T::*mfp) (lua_State*)) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + typedef int (T::*MFP) (lua_State*); + new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); // Stack: co, cl, st, function ptr + lua_pushcclosure (L, &CFunc::CallMemberCFunction ::f, 1); // Stack: co, cl, st, function + rawsetfield (L, -3, name); // Stack: co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a const member lua_CFunction. + */ + Class & addFunction (char const* name, int (T::*mfp) (lua_State*) const) + { + return addCFunction (name, mfp); + } + + //-------------------------------------------------------------------------- + /** + Add or replace a const member lua_CFunction. + */ + Class & addCFunction (char const* name, int (T::*mfp) (lua_State*) const) + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + typedef int (T::*MFP) (lua_State*) const; + new (lua_newuserdata (L, sizeof (mfp))) MFP (mfp); + lua_pushcclosure (L, &CFunc::CallConstMemberCFunction ::f, 1); + lua_pushvalue (L, -1); // Stack: co, cl, st, function, function + rawsetfield (L, -4, name); // Stack: co, cl, st, function + rawsetfield (L, -4, name); // Stack: co, cl, st + + return *this; + } + + //-------------------------------------------------------------------------- + /** + Add or replace a primary Constructor. + + The primary Constructor is invoked when calling the class type table + like a function. + + The template parameter should be a function pointer type that matches + the desired Constructor (since you can't take the address of a Constructor + and pass it as an argument). + */ + template + Class & addConstructor () + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushcclosure (L, &ctorContainerProxy ::Params, C>, 0); + rawsetfield (L, -2, "__call"); + + return *this; + } + + template + Class & addConstructor () + { + assertStackState (); // Stack: const table (co), class table (cl), static table (st) + + lua_pushcclosure (L, &ctorPlacementProxy ::Params, T>, 0); + rawsetfield (L, -2, "__call"); + + return *this; + } + }; + +private: + //---------------------------------------------------------------------------- + /** + Open the global namespace for registrations. + */ + explicit Namespace (lua_State* L) + : Registrar (L) + { + lua_getglobal (L, "_G"); + ++m_stackSize; + } + + //---------------------------------------------------------------------------- + /** + Open a namespace for registrations. + + The namespace is created if it doesn't already exist. + The parent namespace is at the top of the Lua stack. + */ + Namespace (char const* name, Namespace& parent) + : Registrar (parent) + { + assert (lua_istable (L, -1)); // Stack: parent namespace (pns) + + rawgetfield (L, -1, name); // Stack: pns, namespace (ns) | nil + + if (lua_isnil (L, -1)) // Stack: pns, nil + { + lua_pop (L, 1); // Stack: pns + + lua_newtable (L); // Stack: pns, ns + lua_pushvalue (L, -1); // Stack: pns, ns, ns + + // na.__metatable = ns + lua_setmetatable (L, -2); // Stack: pns, ns + + // ns.__index = indexMetaMethod + lua_pushcfunction (L, &CFunc::indexMetaMethod); + rawsetfield (L, -2, "__index"); // Stack: pns, ns + + // ns.__newindex = newindexMetaMethod + lua_pushcfunction (L, &CFunc::newindexStaticMetaMethod); + rawsetfield (L, -2, "__newindex"); // Stack: pns, ns + + lua_newtable (L); // Stack: pns, ns, propget table (pg) + lua_rawsetp (L, -2, getPropgetKey ()); // ns [propgetKey] = pg. Stack: pns, ns + + lua_newtable (L); // Stack: pns, ns, propset table (ps) + lua_rawsetp (L, -2, getPropsetKey ()); // ns [propsetKey] = ps. Stack: pns, ns + + // pns [name] = ns + lua_pushvalue (L, -1); // Stack: pns, ns, ns + rawsetfield (L, -3, name); // Stack: pns, ns +#if 0 + lua_pushcfunction (L, &tostringMetaMethod); + rawsetfield (L, -2, "__tostring"); +#endif + } + + ++m_stackSize; + } + + //---------------------------------------------------------------------------- + /** + Close the class and continue the namespace registrations. + */ + explicit Namespace (ClassBase& child) + : Registrar (child) + { + } + + using Registrar::operator=; + +public: + //---------------------------------------------------------------------------- + /** + Open the global namespace. + */ + static Namespace getGlobalNamespace (lua_State* L) + { + enableExceptions (L); + return Namespace (L); + } + + //---------------------------------------------------------------------------- + /** + Open a new or existing namespace for registrations. + */ + Namespace beginNamespace (char const* name) + { + assertIsActive (); + return Namespace (name, *this); + } + + //---------------------------------------------------------------------------- + /** + Continue namespace registration in the parent. + + Do not use this on the global namespace. + */ + Namespace endNamespace () + { + if (m_stackSize == 1) + { + throw std::logic_error ("endNamespace () called on global namespace"); + } + + assert (m_stackSize > 1); + --m_stackSize; + lua_pop (L, 1); + return Namespace (*this); + } + + //---------------------------------------------------------------------------- + /** + Add or replace a variable. + */ + template + Namespace& addProperty (char const* name, T* pt, bool isWritable = true) + { + return addVariable (name, pt, isWritable); + } + + //---------------------------------------------------------------------------- + /** + Add or replace a variable. + */ + template + Namespace& addVariable (char const* name, T* pt, bool isWritable = true) + { + if (m_stackSize == 1) + { + throw std::logic_error ("addProperty () called on global namespace"); + } + + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + + lua_pushlightuserdata (L, pt); // Stack: ns, pointer + lua_pushcclosure (L, &CFunc::getVariable , 1); // Stack: ns, getter + CFunc::addGetter (L, name, -2); // Stack: ns + + if (isWritable) + { + lua_pushlightuserdata (L, pt); // Stack: ns, pointer + lua_pushcclosure (L, &CFunc::setVariable , 1); // Stack: ns, setter + } + else + { + lua_pushstring (L, name); // Stack: ns, ps, name + lua_pushcclosure (L, &CFunc::readOnlyError, 1); // Stack: ns, error_fn + } + CFunc::addSetter (L, name, -2); // Stack: ns + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Add or replace a property. + + If the set function is omitted or null, the property is read-only. + */ + template + Namespace& addProperty (char const* name, TG (*get) (), void (*set) (TS) = 0) + { + if (m_stackSize == 1) + { + throw std::logic_error ("addProperty () called on global namespace"); + } + + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + + lua_pushlightuserdata (L, reinterpret_cast (get)); // Stack: ns, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // Stack: ns, getter + CFunc::addGetter (L, name, -2); + + if (set != 0) + { + lua_pushlightuserdata(L, reinterpret_cast (set)); // Stack: ns, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); + } + else + { + lua_pushstring (L, name); + lua_pushcclosure (L, &CFunc::readOnlyError, 1); + } + CFunc::addSetter (L, name, -2); + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Add or replace a property. + If the set function is omitted or null, the property is read-only. + */ + Namespace& addProperty (char const* name, int (*get) (lua_State*), int (*set) (lua_State*) = 0) + { + if (m_stackSize == 1) + { + throw std::logic_error ("addProperty () called on global namespace"); + } + + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + lua_pushcfunction (L, get); // Stack: ns, getter + CFunc::addGetter (L, name, -2); // Stack: ns + if (set != 0) + { + lua_pushcfunction(L, set); // Stack: ns, setter + CFunc::addSetter(L, name, -2); // Stack: ns + } + else + { + lua_pushstring(L, name); // Stack: ns, name + lua_pushcclosure(L, &CFunc::readOnlyError, 1); // Stack: ns, name, readOnlyError + CFunc::addSetter(L, name, -2); // Stack: ns + } + + return *this; + } + +//---------------------------------------------------------------------------- + /** + Add or replace a free function. + */ + template + Namespace& addFunction (char const* name, FP const fp) + { + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + + lua_pushlightuserdata (L, reinterpret_cast (fp)); // Stack: ns, function ptr + lua_pushcclosure (L, &CFunc::Call ::f, 1); // Stack: ns, function + rawsetfield (L, -2, name); // Stack: ns + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Add or replace a lua_CFunction. + */ + Namespace& addFunction (char const* name, int (*const fp) (lua_State*)) + { + return addCFunction (name, fp); + } + + //---------------------------------------------------------------------------- + /** + Add or replace a lua_CFunction. + */ + Namespace& addCFunction (char const* name, int (*const fp) (lua_State*)) + { + assert (lua_istable (L, -1)); // Stack: namespace table (ns) + + lua_pushcfunction (L, fp); // Stack: ns, function + rawsetfield (L, -2, name); // Stack: ns + + return *this; + } + + //---------------------------------------------------------------------------- + /** + Open a new or existing class for registrations. + */ + template + Class beginClass (char const* name) + { + assertIsActive (); + return Class (name, *this); + } + + //---------------------------------------------------------------------------- + /** + Derive a new class for registrations. + + To continue registrations for the class later, use beginClass (). + Do not call deriveClass () again. + */ + template + Class deriveClass (char const* name) + { + assertIsActive (); + return Class (name, *this, ClassInfo ::getStaticKey ()); + } +}; + +//------------------------------------------------------------------------------ +/** + Retrieve the global namespace. + + It is recommended to put your namespace inside the global namespace, and + then add your classes and functions to it, rather than adding many classes + and functions directly to the global namespace. +*/ +inline Namespace getGlobalNamespace (lua_State* L) +{ + return Namespace::getGlobalNamespace (L); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/Security.h b/3rd_party/lua/LuaBridge/detail/Security.h new file mode 100644 index 00000000..51725456 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Security.h @@ -0,0 +1,62 @@ +#pragma once + +namespace luabridge { + +//------------------------------------------------------------------------------ +/** +security options. +*/ +class Security +{ +public: + static bool hideMetatables() + { + return getSettings().hideMetatables; + } + + static void setHideMetatables(bool shouldHide) + { + getSettings().hideMetatables = shouldHide; + } + +private: + struct Settings + { + Settings() : hideMetatables(true) + { + } + + bool hideMetatables; + }; + + static Settings& getSettings() + { + static Settings settings; + return settings; + } +}; + +//------------------------------------------------------------------------------ +/** +Set a global value in the lua_State. + +@note This works on any type specialized by `Stack`, including `LuaRef` and +its table proxies. +*/ +template +inline void setGlobal(lua_State* L, T t, char const* name) +{ + push(L, t); + lua_setglobal(L, name); +} + +//------------------------------------------------------------------------------ +/** +Change whether or not metatables are hidden (on by default). +*/ +inline void setHideMetatables(bool shouldHide) +{ + Security::setHideMetatables(shouldHide); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/Stack.h b/3rd_party/lua/LuaBridge/detail/Stack.h new file mode 100644 index 00000000..f00b9c9d --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Stack.h @@ -0,0 +1,622 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include +#include + +#include + +namespace luabridge { + +template +struct Stack; + +template <> +struct Stack +{ + static void push (lua_State* L) + { + } +}; + +//------------------------------------------------------------------------------ +/** + Receive the lua_State* as an argument. +*/ +template <> +struct Stack +{ + static lua_State* get (lua_State* L, int) + { + return L; + } +}; + +//------------------------------------------------------------------------------ +/** + Push a lua_CFunction. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, lua_CFunction f) + { + lua_pushcfunction (L, f); + } + + static lua_CFunction get (lua_State* L, int index) + { + return lua_tocfunction (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_iscfunction (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `int`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, int value) + { + lua_pushinteger (L, static_cast (value)); + } + + static int get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned int`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, unsigned int value) + { + lua_pushinteger (L, static_cast (value)); + } + + static unsigned int get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned char`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, unsigned char value) + { + lua_pushinteger (L, static_cast (value)); + } + + static unsigned char get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `short`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, short value) + { + lua_pushinteger (L, static_cast (value)); + } + + static short get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned short`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, unsigned short value) + { + lua_pushinteger (L, static_cast (value)); + } + + static unsigned short get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `long`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, long value) + { + lua_pushinteger (L, static_cast (value)); + } + + static long get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `unsigned long`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, unsigned long value) + { + lua_pushinteger (L, static_cast (value)); + } + + static unsigned long get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + * Stack specialization for `long long`. + */ +template <> +struct Stack +{ + static void push (lua_State* L, long long value) + { + lua_pushinteger (L, static_cast (value)); + } + + static long long get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + * Stack specialization for `unsigned long long`. + */ +template <> +struct Stack +{ + static void push (lua_State* L, unsigned long long value) + { + lua_pushinteger (L, static_cast (value)); + } + static unsigned long long get (lua_State* L, int index) + { + return static_cast (luaL_checkinteger (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `float`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, float value) + { + lua_pushnumber (L, static_cast (value)); + } + + static float get (lua_State* L, int index) + { + return static_cast (luaL_checknumber (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `double`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, double value) + { + lua_pushnumber (L, static_cast (value)); + } + + static double get (lua_State* L, int index) + { + return static_cast (luaL_checknumber (L, index)); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TNUMBER; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `bool`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, bool value) + { + lua_pushboolean (L, value ? 1 : 0); + } + + static bool get (lua_State* L, int index) + { + return lua_toboolean (L, index) ? true : false; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_isboolean (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `char`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, char value) + { + lua_pushlstring (L, &value, 1); + } + + static char get (lua_State* L, int index) + { + return luaL_checkstring (L, index) [0]; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TSTRING; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `const char*`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, char const* str) + { + if (str != 0) + lua_pushstring (L, str); + else + lua_pushnil (L); + } + + static char const* get (lua_State* L, int index) + { + return lua_isnil (L, index) ? 0 : luaL_checkstring (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return lua_isnil (L, index) || lua_type (L, index) == LUA_TSTRING; + } +}; + +//------------------------------------------------------------------------------ +/** + Stack specialization for `std::string`. +*/ +template <> +struct Stack +{ + static void push (lua_State* L, std::string const& str) + { + lua_pushlstring (L, str.data (), str.size ()); + } + + static std::string get (lua_State* L, int index) + { + size_t len; + if (lua_type (L, index) == LUA_TSTRING) + { + const char* str = lua_tolstring (L, index, &len); + return std::string (str, len); + } + + // Lua reference manual: + // If the value is a number, then lua_tolstring also changes the actual value in the stack to a string. + // (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.) + lua_pushvalue (L, index); + const char* str = lua_tolstring(L, -1, &len); + std::string string (str, len); + lua_pop (L, 1); // Pop the temporary string + return string; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TSTRING; + } +}; + + +template +struct StackOpSelector +{ + typedef T ReturnType; + + static void push (lua_State* L, T& value) + { + Stack ::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Stack ::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Stack ::isInstance (L, index); + } +}; + +template +struct StackOpSelector +{ + typedef T ReturnType; + + static void push (lua_State* L, const T& value) + { + Stack ::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Stack ::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Stack ::isInstance (L, index); + } +}; + +template +struct StackOpSelector +{ + typedef T ReturnType; + + static void push (lua_State* L, T* value) + { + Stack ::push (L, *value); + } + + static ReturnType get (lua_State* L, int index) + { + return Stack ::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Stack ::isInstance (L, index); + } +}; + +template +struct StackOpSelector +{ + typedef T ReturnType; + + static void push (lua_State* L, const T* value) + { + Stack ::push (L, *value); + } + + static ReturnType get (lua_State* L, int index) + { + return Stack ::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Stack ::isInstance (L, index); + } +}; + + +template +struct Stack +{ + typedef StackOpSelector ::value> Helper; + typedef typename Helper::ReturnType ReturnType; + + static void push (lua_State* L, T& value) + { + Helper::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Helper::get (L, index); + } +}; + +template +struct Stack +{ + typedef StackOpSelector ::value> Helper; + typedef typename Helper::ReturnType ReturnType; + + static void push (lua_State* L, const T& value) + { + Helper::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Helper::get (L, index); + } +}; + +template +struct Stack +{ + typedef StackOpSelector ::value> Helper; + typedef typename Helper::ReturnType ReturnType; + + static void push (lua_State* L, T* value) + { + Helper::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Helper::get (L, index); + } +}; + +template +struct Stack +{ + typedef StackOpSelector ::value> Helper; + typedef typename Helper::ReturnType ReturnType; + + static void push (lua_State* L, const T* value) + { + Helper::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Helper::get (L, index); + } +}; + +//------------------------------------------------------------------------------ +/** + * Push an object onto the Lua stack. + */ +template +inline void push (lua_State* L, T t) +{ + Stack ::push (L, t); +} + +//------------------------------------------------------------------------------ +/** + * Check whether an object on the Lua stack is of type T. + */ +template +inline bool isInstance (lua_State* L, int index) +{ + return Stack ::isInstance (L, index); +} + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/TypeList.h b/3rd_party/lua/LuaBridge/detail/TypeList.h new file mode 100644 index 00000000..d142f6e1 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/TypeList.h @@ -0,0 +1,218 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + This file incorporates work covered by the following copyright and + permission notice: + + The Loki Library + Copyright (c) 2001 by Andrei Alexandrescu + This code accompanies the book: + Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design + Patterns Applied". Copyright (c) 2001. Addison-Wesley. + Permission to use, copy, modify, distribute and sell this software for any + purpose is hereby granted without fee, provided that the above copyright + notice appear in all copies and that both that copyright notice and this + permission notice appear in supporting documentation. + The author or Addison-Welsey Longman make no representations about the + suitability of this software for any purpose. It is provided "as is" + without express or implied warranty. +*/ +//============================================================================== + +#pragma once + +#include +#include + +#include +#include + +namespace luabridge { + +/** + None type means void parameters or return value. +*/ +typedef void None; + +template +struct TypeList +{ + typedef Tail TailType; +}; + +template +struct TypeListSize +{ + static const size_t value = TypeListSize ::value + 1; +}; + +template <> +struct TypeListSize +{ + static const size_t value = 0; +}; + +#ifdef LUABRIDGE_CXX11 + +template +struct MakeTypeList; + +template +struct MakeTypeList +{ + using Result = TypeList ::Result>; +}; + +template <> +struct MakeTypeList <> +{ + using Result = None; +}; + +#endif + +/** + A TypeList with actual values. +*/ +template +struct TypeListValues +{ + static std::string const tostring (bool) + { + return ""; + } +}; + +/** + TypeListValues recursive template definition. +*/ +template +struct TypeListValues > +{ + Head hd; + TypeListValues tl; + + TypeListValues (Head hd_, TypeListValues const& tl_) + : hd (hd_), tl (tl_) + { + } + + static std::string tostring (bool comma = false) + { + std::string s; + + if (comma) + s = ", "; + + s = s + typeid (Head).name (); + + return s + TypeListValues ::tostring (true); + } +}; + +// Specializations of type/value list for head types that are references and +// const-references. We need to handle these specially since we can't count +// on the referenced object hanging around for the lifetime of the list. + +template +struct TypeListValues > +{ + Head hd; + TypeListValues tl; + + TypeListValues (Head& hd_, TypeListValues const& tl_) + : hd (hd_), tl (tl_) + { + } + + static std::string const tostring (bool comma = false) + { + std::string s; + + if (comma) + s = ", "; + + s = s + typeid (Head).name () + "&"; + + return s + TypeListValues ::tostring (true); + } +}; + +template +struct TypeListValues > +{ + Head hd; + TypeListValues tl; + + TypeListValues (Head const& hd_, const TypeListValues & tl_) + : hd (hd_), tl (tl_) + { + } + + static std::string const tostring (bool comma = false) + { + std::string s; + + if (comma) + s = ", "; + + s = s + typeid (Head).name () + " const&"; + + return s + TypeListValues ::tostring (true); + } +}; + +//============================================================================== +/** + Subclass of a TypeListValues constructable from the Lua stack. +*/ + +template +struct ArgList +{ +}; + +template +struct ArgList : public TypeListValues +{ + ArgList (lua_State*) + { + } +}; + +template +struct ArgList , Start> + : public TypeListValues > +{ + ArgList (lua_State* L) + : TypeListValues > (Stack ::get (L, Start), + ArgList (L)) + { + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/TypeTraits.h b/3rd_party/lua/LuaBridge/detail/TypeTraits.h new file mode 100644 index 00000000..5fad3756 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/TypeTraits.h @@ -0,0 +1,135 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include + + +namespace luabridge { + +//------------------------------------------------------------------------------ +/** + Container traits. + + Unspecialized ContainerTraits has the isNotContainer typedef for SFINAE. + All user defined containers must supply an appropriate specialization for + ContinerTraits (without the typedef isNotContainer). The containers that + come with LuaBridge also come with the appropriate ContainerTraits + specialization. See the corresponding declaration for details. + + A specialization of ContainerTraits for some generic type ContainerType + looks like this: + + template + struct ContainerTraits > + { + typedef typename T Type; + + static T* get (ContainerType const& c) + { + return c.get (); // Implementation-dependent on ContainerType + } + }; +*/ +template +struct ContainerTraits +{ + typedef bool isNotContainer; + typedef T Type; +}; + +//------------------------------------------------------------------------------ +/** + Type traits. + + Specializations return information about a type. +*/ +struct TypeTraits +{ + /** Determine if type T is a container. + + To be considered a container, there must be a specialization of + ContainerTraits with the required fields. + */ + template + class isContainer + { + private: + typedef char yes[1]; // sizeof (yes) == 1 + typedef char no [2]; // sizeof (no) == 2 + + template + static no& test (typename C::isNotContainer*); + + template + static yes& test (...); + + public: + static const bool value = sizeof (test >(0)) == sizeof (yes); + }; + + /** Determine if T is const qualified. + */ + /** @{ */ + template + struct isConst + { + static bool const value = false; + }; + + template + struct isConst + { + static bool const value = true; + }; + /** @} */ + + /** Remove the const qualifier from T. + */ + /** @{ */ + template + struct removeConst + { + typedef T Type; + }; + + template + struct removeConst + { + typedef T Type; + }; + /**@}*/ +}; + + +template +struct Stack; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/Userdata.h b/3rd_party/lua/LuaBridge/detail/Userdata.h new file mode 100644 index 00000000..ef13d9fc --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/Userdata.h @@ -0,0 +1,829 @@ +//------------------------------------------------------------------------------ +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include + +#include +#include + + +namespace luabridge { + +//============================================================================== +/** + Return the identity pointer for our lightuserdata tokens. + + Because of Lua's dynamic typing and our improvised system of imposing C++ + class structure, there is the possibility that executing scripts may + knowingly or unknowingly cause invalid data to get passed to the C functions + created by LuaBridge. In particular, our security model addresses the + following: + 1. Scripts cannot create a userdata (ignoring the debug lib). + 2. Scripts cannot create a lightuserdata (ignoring the debug lib). + 3. Scripts cannot set the metatable on a userdata. +*/ + +/** + Interface to a class pointer retrievable from a userdata. +*/ +class Userdata +{ +protected: + void* m_p; // subclasses must set this + + Userdata() : m_p (0) + { + } + + //-------------------------------------------------------------------------- + /** + Get an untyped pointer to the contained class. + */ + void* getPointer () + { + return m_p; + } + +private: + //-------------------------------------------------------------------------- + /** + Validate and retrieve a Userdata on the stack. + + The Userdata must exactly match the corresponding class table or + const table, or else a Lua error is raised. This is used for the + __gc metamethod. + */ + static Userdata* getExactClass (lua_State* L, int index, void const* /*classKey*/) + { + return static_cast (lua_touserdata (L, lua_absindex (L, index))); + } + + //-------------------------------------------------------------------------- + /** + Validate and retrieve a Userdata on the stack. + + The Userdata must be derived from or the same as the given base class, + identified by the key. If canBeConst is false, generates an error if + the resulting Userdata represents to a const object. We do the type check + first so that the error message is informative. + */ + static Userdata* getClass (lua_State* L, + int index, + void const* registryConstKey, + void const* registryClassKey, + bool canBeConst) + { + index = lua_absindex (L, index); + + lua_getmetatable (L, index); // Stack: object metatable (ot) | nil + if (!lua_istable (L, -1)) + { + lua_rawgetp (L, LUA_REGISTRYINDEX, registryClassKey); // Stack: registry metatable (rt) | nil + return throwBadArg (L, index); + } + + lua_rawgetp (L, -1, getConstKey ()); // Stack: ot | nil, const table (co) | nil + assert (lua_istable (L, -1) || lua_isnil (L, -1)); + + // If const table is NOT present, object is const. Use non-const registry table + // if object cannot be const, so constness validation is done automatically. + // E.g. nonConstFn (constObj) + // -> canBeConst = false, isConst = true + // -> 'Class' registry table, 'const Class' object table + // -> 'expected Class, got const Class' + bool isConst = lua_isnil (L, -1); // Stack: ot | nil, nil, rt + if (isConst && canBeConst) + { + lua_rawgetp (L, LUA_REGISTRYINDEX, registryConstKey); // Stack: ot, nil, rt + } + else + { + lua_rawgetp (L, LUA_REGISTRYINDEX, registryClassKey); // Stack: ot, co, rt + } + + lua_insert (L, -3); // Stack: rt, ot, co | nil + lua_pop (L, 1); // Stack: rt, ot + + for (;;) + { + if (lua_rawequal (L, -1, -2)) // Stack: rt, ot + { + lua_pop (L, 2); // Stack: - + return static_cast (lua_touserdata (L, index)); + } + + // Replace current metatable with it's base class. + lua_rawgetp (L, -1, getParentKey ()); // Stack: rt, ot, parent ot (pot) | nil + + if (lua_isnil (L, -1)) // Stack: rt, ot, nil + { + // Drop the object metatable because it may be some parent metatable + lua_pop (L, 2); // Stack: rt + return throwBadArg (L, index); + } + + lua_remove (L, -2); // Stack: rt, pot + } + + // no return + } + + static bool isInstance (lua_State* L, int index, void const* registryClassKey) + { + index = lua_absindex (L, index); + + int result = lua_getmetatable (L, index); // Stack: object metatable (ot) | nothing + if (result == 0) + { + return false; // Nothing was pushed on the stack + } + if (!lua_istable (L, -1)) + { + lua_pop (L, 1); // Stack: - + return false; + } + + lua_rawgetp (L, LUA_REGISTRYINDEX, registryClassKey); // Stack: ot, rt + lua_insert (L, -2); // Stack: rt, ot + + for (;;) + { + if (lua_rawequal (L, -1, -2)) // Stack: rt, ot + { + lua_pop (L, 2); // Stack: - + return true; + } + + // Replace current metatable with it's base class. + lua_rawgetp (L, -1, getParentKey ()); // Stack: rt, ot, parent ot (pot) | nil + + if (lua_isnil (L, -1)) // Stack: rt, ot, nil + { + lua_pop (L, 3); // Stack: - + return false; + } + + lua_remove (L, -2); // Stack: rt, pot + } + } + + static Userdata* throwBadArg (lua_State* L, int index) + { + assert (lua_istable (L, -1) || lua_isnil (L, -1)); // Stack: rt | nil + + const char* expected = 0; + if (lua_isnil (L, -1)) // Stack: nil + { + expected = "unregistered class"; + } + else + { + lua_rawgetp (L, -1, getTypeKey ()); // Stack: rt, registry type + expected = lua_tostring (L, -1); + } + + const char* got = 0; + if (lua_isuserdata (L, index)) + { + lua_getmetatable (L, index); // Stack: ..., ot | nil + if (lua_istable (L, -1)) // Stack: ..., ot + { + lua_rawgetp (L, -1, getTypeKey ()); // Stack: ..., ot, object type | nil + if (lua_isstring (L, -1)) + { + got = lua_tostring (L, -1); + } + } + } + if (!got) + { + got = lua_typename (L, lua_type (L, index)); + } + + luaL_argerror (L, index, lua_pushfstring (L, "%s expected, got %s", expected, got)); + return 0; + } + +public: + virtual ~Userdata () { } + + //-------------------------------------------------------------------------- + /** + Returns the Userdata* if the class on the Lua stack matches. + + If the class does not match, a Lua error is raised. + */ + template + static Userdata* getExact (lua_State* L, int index) + { + return getExactClass (L, index, ClassInfo ::getClassKey ()); + } + + //-------------------------------------------------------------------------- + /** + Get a pointer to the class from the Lua stack. + + If the object is not the class or a subclass, or it violates the + const-ness, a Lua error is raised. + */ + template + static T* get (lua_State* L, int index, bool canBeConst) + { + if (lua_isnil (L, index)) + return 0; + + return static_cast (getClass ( + L, index, ClassInfo ::getConstKey (), + ClassInfo ::getClassKey (), + canBeConst)->getPointer ()); + } + + template + static bool isInstance (lua_State* L, int index) + { + return isInstance (L, index, ClassInfo ::getClassKey ()); + } +}; + +//---------------------------------------------------------------------------- +/** + Wraps a class object stored in a Lua userdata. + + The lifetime of the object is managed by Lua. The object is constructed + inside the userdata using placement new. +*/ +template +class UserdataValue : public Userdata +{ +private: + UserdataValue (UserdataValue const&); + UserdataValue operator= (UserdataValue const&); + + char m_storage [sizeof (T)]; + +private: + /** + Used for placement construction. + */ + UserdataValue () + { + m_p = 0; + } + + ~UserdataValue () + { + if (getPointer () != 0) + { + getObject ()->~T (); + } + } + +public: + /** + Push a T via placement new. + + The caller is responsible for calling placement new using the + returned uninitialized storage. + */ + static UserdataValue * place (lua_State* const L) + { + UserdataValue * const ud = new ( + lua_newuserdata (L, sizeof (UserdataValue ))) UserdataValue (); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getClassKey ()); + if (!lua_istable (L, -1)) + { + throw std::logic_error ("The class is not registered in LuaBridge"); + } + lua_setmetatable (L, -2); + return ud; + } + + /** + Push T via copy construction from U. + */ + template + static inline void push (lua_State* const L, U const& u) + { + UserdataValue * ud = place (L); + new (ud->getObject ()) U (u); + ud->commit (); + } + + /** + Confirm object construction. + */ + void commit () + { + m_p = getObject (); + } + + T* getObject () + { + // If this fails to compile it means you forgot to provide + // a Container specialization for your container! + // + return reinterpret_cast (&m_storage [0]); + } +}; + +//---------------------------------------------------------------------------- +/** + Wraps a pointer to a class object inside a Lua userdata. + + The lifetime of the object is managed by C++. +*/ +class UserdataPtr : public Userdata +{ +private: + UserdataPtr (UserdataPtr const&); + UserdataPtr operator= (UserdataPtr const&); + +private: + /** Push a pointer to object using metatable key. + */ + static void push (lua_State* L, const void* p, void const* const key) + { + new (lua_newuserdata (L, sizeof (UserdataPtr))) UserdataPtr (const_cast (p)); + lua_rawgetp (L, LUA_REGISTRYINDEX, key); + if (!lua_istable (L, -1)) + { + throw std::logic_error ("The class is not registered in LuaBridge"); + } + lua_setmetatable (L, -2); + } + + explicit UserdataPtr (void* const p) + { + m_p = p; + + // Can't construct with a null pointer! + // + assert (m_p != 0); + } + +public: + /** Push non-const pointer to object. + */ + template + static void push (lua_State* const L, T* const p) + { + if (p) + push (L, p, ClassInfo ::getClassKey ()); + else + lua_pushnil (L); + } + + /** Push const pointer to object. + */ + template + static void push (lua_State* const L, T const* const p) + { + if (p) + push (L, p, ClassInfo ::getConstKey ()); + else + lua_pushnil (L); + } +}; + +//============================================================================ +/** + Wraps a container that references a class object. + + The template argument C is the container type, ContainerTraits must be + specialized on C or else a compile error will result. +*/ +template +class UserdataShared : public Userdata +{ +private: + UserdataShared (UserdataShared const&); + UserdataShared & operator= (UserdataShared const&); + + typedef typename TypeTraits::removeConst < + typename ContainerTraits ::Type>::Type T; + + C m_c; + +private: + ~UserdataShared () + { + } + +public: + /** + Construct from a container to the class or a derived class. + */ + template + explicit UserdataShared (U const& u) : m_c (u) + { + m_p = const_cast (reinterpret_cast ( + (ContainerTraits ::get (m_c)))); + } + + /** + Construct from a pointer to the class or a derived class. + */ + template + explicit UserdataShared (U* u) : m_c (u) + { + m_p = const_cast (reinterpret_cast ( + (ContainerTraits ::get (m_c)))); + } +}; + +//---------------------------------------------------------------------------- +// +// SFINAE helpers. +// + +// non-const objects +template +struct UserdataSharedHelper +{ + typedef typename TypeTraits::removeConst < + typename ContainerTraits ::Type>::Type T; + + static void push (lua_State* L, C const& c) + { + if (ContainerTraits ::get (c) != 0) + { + new (lua_newuserdata (L, sizeof (UserdataShared ))) UserdataShared (c); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getClassKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } + + static void push (lua_State* L, T* const t) + { + if (t) + { + new (lua_newuserdata (L, sizeof (UserdataShared ))) UserdataShared (t); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getClassKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } +}; + +// const objects +template +struct UserdataSharedHelper +{ + typedef typename TypeTraits::removeConst < + typename ContainerTraits ::Type>::Type T; + + static void push (lua_State* L, C const& c) + { + if (ContainerTraits ::get (c) != 0) + { + new (lua_newuserdata (L, sizeof (UserdataShared ))) UserdataShared (c); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getConstKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } + + static void push (lua_State* L, T* const t) + { + if (t) + { + new (lua_newuserdata (L, sizeof (UserdataShared ))) UserdataShared (t); + lua_rawgetp (L, LUA_REGISTRYINDEX, ClassInfo ::getConstKey ()); + // If this goes off it means the class T is unregistered! + assert (lua_istable (L, -1)); + lua_setmetatable (L, -2); + } + else + { + lua_pushnil (L); + } + } +}; + +/** + Pass by container. + + The container controls the object lifetime. Typically this will be a + lifetime shared by C++ and Lua using a reference count. Because of type + erasure, containers like std::shared_ptr will not work. Containers must + either be of the intrusive variety, or in the style of the RefCountedPtr + type provided by LuaBridge (that uses a global hash table). +*/ +template +struct StackHelper +{ + static void push (lua_State* L, C const& c) + { + UserdataSharedHelper ::Type>::value>::push (L, c); + } + + typedef typename TypeTraits::removeConst < + typename ContainerTraits ::Type>::Type T; + + static C get (lua_State* L, int index) + { + return Userdata::get (L, index, true); + } +}; + +/** + Pass by value. + + Lifetime is managed by Lua. A C++ function which accesses a pointer or + reference to an object outside the activation record in which it was + retrieved may result in undefined behavior if Lua garbage collected it. +*/ +template +struct StackHelper +{ + static inline void push (lua_State* L, T const& t) + { + UserdataValue ::push (L, t); + } + + static inline T const& get (lua_State* L, int index) + { + return *Userdata::get (L, index, true); + } +}; + + +//------------------------------------------------------------------------------ +/** + Lua stack conversions for pointers and references to class objects. + + Lifetime is managed by C++. Lua code which remembers a reference to the + value may result in undefined behavior if C++ destroys the object. The + handling of the const and volatile qualifiers happens in UserdataPtr. +*/ + +template +struct RefStackHelper +{ + typedef C return_type; + + static inline void push (lua_State* L, C const& t) + { + UserdataSharedHelper ::Type>::value>::push (L, t); + } + + typedef typename TypeTraits::removeConst < + typename ContainerTraits ::Type>::Type T; + + static return_type get (lua_State* L, int index) + { + return Userdata::get (L, index, true); + } +}; + +template +struct RefStackHelper +{ + typedef T& return_type; + + static void push (lua_State* L, T const& t) + { + UserdataPtr::push (L, &t); + } + + static return_type get (lua_State* L, int index) + { + T* t = Userdata::get (L, index, true); + + if (!t) + luaL_error (L, "nil passed to reference"); + return *t; + } +}; + + +/** + * Voider class template. Used to force a comiler to instantiate + * an otherwise probably unused template parameter type T. + * See the C++20 std::void_t <> for details. + */ +template +struct Void +{ + typedef void Type; +}; + + +/** + * Trait class that selects whether to return a user registered + * class object by value or by reference. + */ + +template +struct UserdataGetter +{ + typedef T* ReturnType; + + static ReturnType get (lua_State* L, int index) + { + return Userdata::get (L, index, false); + } +}; + +template +struct UserdataGetter ::Type> +{ + typedef T ReturnType; + + static ReturnType get (lua_State* L, int index) + { + return StackHelper ::value>::get (L, index); + } +}; + +//============================================================================== + +/** + Lua stack conversions for class objects passed by value. +*/ +template +struct Stack +{ + typedef void IsUserdata; + + typedef UserdataGetter Getter; + typedef typename Getter::ReturnType ReturnType; + + static void push (lua_State* L, T const& value) + { + StackHelper ::value>::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Getter::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Userdata::isInstance (L, index); + } +}; + + +/** + * Trait class indicating whether the parameter type must be + * a user registered class. The trait checks the existence of + * member type Stack ::IsUserdata specialization for detection. + */ +template +struct IsUserdata +{ + static const bool value = false; +}; + +template +struct IsUserdata ::IsUserdata>::Type> +{ + static const bool value = true; +}; + + +/** + * Trait class that selects a specific push/get implemenation. + */ +template +struct StackOpSelector; + +// pointer +template +struct StackOpSelector +{ + typedef T* ReturnType; + + static void push (lua_State* L, T* value) + { + UserdataPtr::push (L, value); + } + + static T* get (lua_State* L, int index) + { + return Userdata::get (L, index, false); + } + + static bool isInstance (lua_State* L, int index) + { + return Userdata::isInstance (L, index); + } +}; + +// pointer to const +template +struct StackOpSelector +{ + typedef const T* ReturnType; + + static void push (lua_State* L, const T* value) + { + UserdataPtr::push (L, value); + } + + static const T* get (lua_State* L, int index) + { + return Userdata::get (L, index, true); + } + + static bool isInstance (lua_State* L, int index) + { + return Userdata::isInstance (L, index); + } +}; + +// reference +template +struct StackOpSelector +{ + typedef RefStackHelper ::value> Helper; + typedef typename Helper::return_type ReturnType; + + static void push (lua_State* L, T& value) + { + UserdataPtr::push (L, &value); + } + + static ReturnType get (lua_State* L, int index) + { + return Helper::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Userdata::isInstance (L, index); + } +}; + +// reference to const +template +struct StackOpSelector +{ + typedef RefStackHelper ::value> Helper; + typedef typename Helper::return_type ReturnType; + + static void push (lua_State* L, const T& value) + { + Helper::push (L, value); + } + + static ReturnType get (lua_State* L, int index) + { + return Helper::get (L, index); + } + + static bool isInstance (lua_State* L, int index) + { + return Userdata::isInstance (L, index); + } +}; + +} // namespace luabridge diff --git a/3rd_party/lua/LuaBridge/detail/dump.h b/3rd_party/lua/LuaBridge/detail/dump.h new file mode 100644 index 00000000..7e23f9f5 --- /dev/null +++ b/3rd_party/lua/LuaBridge/detail/dump.h @@ -0,0 +1,143 @@ +//============================================================================== +/* + https://github.com/vinniefalco/LuaBridge + + Copyright 2019, Dmitry Tarakanov + Copyright 2012, Vinnie Falco + Copyright 2007, Nathan Reed + + License: The MIT License (http://www.opensource.org/licenses/mit-license.php) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ +//============================================================================== + +#pragma once + +#include "LuaBridge/detail/ClassInfo.h" + +#include +#include + + +namespace luabridge { +namespace debug { + +inline void putIndent (std::ostream& stream, unsigned level) +{ + for (unsigned i = 0; i < level; ++i) + { + stream << " "; + } +} + +inline void dumpTable (lua_State* L, int index, std::ostream& stream, unsigned level); + +inline void dumpValue (lua_State* L, int index, std::ostream& stream, unsigned level = 0) +{ + const int type = lua_type (L, index); + switch (type) + { + case LUA_TNIL: + stream << "nil"; + break; + + case LUA_TBOOLEAN: + stream << (lua_toboolean (L, index) ? "true" : "false"); + break; + + case LUA_TNUMBER: + stream << lua_tonumber (L, index); + break; + + case LUA_TSTRING: + stream << '"' << lua_tostring (L, index) << '"'; + break; + + case LUA_TFUNCTION: + if (lua_iscfunction (L, index)) + { + stream << "cfunction@" << lua_topointer (L, index); + } + else + { + stream << "function@" << lua_topointer (L, index); + } + break; + + case LUA_TTHREAD: + stream << "thread@" << lua_tothread (L, index); + break; + + case LUA_TLIGHTUSERDATA: + stream << "lightuserdata@" << lua_touserdata (L, index); + break; + + case LUA_TTABLE: + dumpTable (L, index, stream, level); + break; + + case LUA_TUSERDATA: + stream << "userdata@" << lua_touserdata (L, index); + break; + + default: + stream << lua_typename (L, type);; + break; + } +} + +inline void dumpTable (lua_State* L, int index, std::ostream& stream, unsigned level) +{ + stream << "table@" << lua_topointer (L, index); + + if (level > 0) + { + return; + } + + index = lua_absindex (L, index); + stream << " {"; + lua_pushnil (L); // Initial key + while (lua_next (L, index)) + { + stream << "\n"; + putIndent (stream, level + 1); + dumpValue (L, -2, stream, level + 1); // Key + stream << ": "; + dumpValue (L, -1, stream, level + 1); // Value + lua_pop (L, 1); // Value + } + putIndent (stream, level); + stream << "\n}"; +} + +inline void dumpState (lua_State *L, std::ostream& stream = std::cerr) +{ + int top = lua_gettop (L); + for (int i = 1; i <= top; ++i) + { + stream << "stack #" << i << ": "; + dumpValue (L, i, stream, 0); + stream << "\n"; + } +} + +} // namespace debug +} // namespace luabridge diff --git a/CMakeLists.txt b/CMakeLists.txt index 98a0bb6a..a9b643c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -122,7 +122,6 @@ endif() list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/piversion.h") message(STATUS "Building PIP version ${PIP_VERSION} (${PIP_LIB_TYPE})") - if(MINGW) find_package(MinGW REQUIRED) list(APPEND CMAKE_LIBRARY_PATH ${MINGW_LIB}) @@ -614,11 +613,24 @@ if (NOT CROSSTOOLS) list(APPEND PIP_LIBS_TARGETS pip_cloud) endif() + # Check Lua support + if(MINGW) + set(LUA_INCLUDE_DIR ${MINGW_INCLUDE}) + endif() + find_package(Lua REQUIRED) + if (LUA_FOUND) + message(STATUS "Building PIP with Lua support") + add_definitions(-DPIP_LUA) + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/lua) + endif() # Test program if(PIP_UTILS) add_executable(pip_test "main.cpp") target_link_libraries(pip_test pip) + if (LUA_FOUND) + target_link_libraries(pip_test ${LUA_LIBRARIES}) + endif() endif() else() diff --git a/main.cpp b/main.cpp index dafd934c..c8f8b312 100644 --- a/main.cpp +++ b/main.cpp @@ -1,309 +1,33 @@ #include "pip.h" -#include -#include -#include -/*#include -#include - -void print(PIConfig::Entry*e, PIString indent = "") { - piCout << indent << e->name() << "=" << e->value(); - indent += " "; - e->children().forEach([=](PIConfig::Entry*e)->PIConfig::Entry*{print(e, indent); return e;}); +#ifdef PIP_LUA +extern "C" { +# include "lua.h" +# include "lauxlib.h" +# include "lualib.h" } +#include +#include "pistring_std.h" -class AsyncIOWatcher: public PIThread { - PIOBJECT_SUBCLASS(AsyncIOWatcher, PIThread) -public: - AsyncIOWatcher() { - pipe_fd[0] = pipe_fd[1] = 0; - if (pipe(pipe_fd) != 0) { - piCoutObj << "Warning: can`t create pipe," << errorString(); - } else { - fd_list << pipe_fd[0]; - } - piCout << pipe_fd[0] << pipe_fd[1]; - fd_list_changed = false; - start(); - } - ~AsyncIOWatcher() { - stop(); - breakSelect(); - if (!waitForFinish(2000)) - terminate(); - if (pipe_fd[0]) ::close(pipe_fd[0]); - if (pipe_fd[1]) ::close(pipe_fd[1]); - } - - void add(int fd) { - que_mutex.lock(); - fd_list_changed = true; - if (!add_que.contains(fd)) - add_que.enqueue(fd); - que_mutex.unlock(); - breakSelect(); - } - void remove(int fd) { - que_mutex.lock(); - fd_list_changed = true; - if (!remove_que.contains(fd)) - remove_que.enqueue(fd); - que_mutex.unlock(); - breakSelect(); - } - -private: - virtual void run() { - que_mutex.lock(); - if (fd_list_changed) { - for (int i = 0; i < add_que.size_s(); ++i) { - if (!fd_list.contains(add_que[i])) - fd_list << add_que[i]; - } - for (int i = 0; i < remove_que.size_s(); ++i) { - fd_list.removeAll(remove_que[i]); - } - add_que.clear(); - remove_que.clear(); - } - fd_list_changed = false; - que_mutex.unlock(); - - s_tv.tv_sec = 1; - s_tv.tv_usec = 0; - FD_ZERO(&s_set); - int max_fd = 0; - piForeachC (int fd, fd_list) { - FD_SET(fd, &s_set); - if (max_fd < fd) - max_fd = fd; - } - int ret = select(max_fd + 1, &s_set, 0, 0, 0); - piCout << "select" << ret; - if (ret <= 0) return; - read_buff.resize(1024); - uint ibuff = 0; - piForeachC (int fd, fd_list) { - if (!FD_ISSET(fd, &s_set)) continue; - if (fd == pipe_fd[0]) { - read(fd, &ibuff, sizeof(ibuff)); - piCoutObj << "breaked"; - continue; - } - int readed = read(fd, read_buff.data(), read_buff.size_s()); - piCout << "readed" << fd << readed; - } - } - void breakSelect() { - if (pipe_fd[1]) - ::write(pipe_fd[1], "\0", 1); - } - - PIQueue add_que, remove_que; - PIDeque fd_list; - PIByteArray read_buff; - PIMutex que_mutex; - bool fd_list_changed; - int pipe_fd[2]; - - fd_set s_set; - struct timeval s_tv; - -}; -*/ -struct A { - double arr[1000]; -}; +static const char * script += "-- script.lua \n" + "testString = \"LuaBridge works!\" \n" + "number = 42 \n"; - -//PIKbdListener kbd(0, 0, false); - -// void swap(int & x, int & y) {int t = x; x = y; y = t;} -// void swap2(int & x, int & y) {int t(std::move(x)); x = y; y = t;} -// void swap(uint & x, uint & y) {uint t = x; x = y; y = t;} -// void swap2(uint & x, uint & y) {uint t(std::move(x)); x = y; y = t;} -// void swap(ullong & x, ullong & y) {ullong t = x; x = y; y = t;} -// void swap2(ullong & x, ullong & y) {ullong t{std::move(x)}; x = y; y = t;} -// void swap(llong & x, llong & y) {llong t = x; x = y; y = t;} -// void swap2(llong & x, llong & y) {llong t{std::move(x)}; x = y; y = t;} -// void swap(double & x, double & y) {double t = x; x = y; y = t;} -// void swap2(double & x, double & y) {double t(std::move(x)); x = std::move(y); y = std::move(t);} -// void swap(float & x, float & y) {float t = x; x = y; y = t;} -// void swap2(float & x, float & y) {float t(std::move(x)); x = std::move(y); y = std::move(t);} -// void swap(PIString & x, PIString & y) {PIString t = x; x = y; y = t;} -// void swap2(PIString & x, PIString & y) {PIString t(std::move(x)); x = std::move(y); y = std::move(t);} -// void swap(std::string & x, std::string & y) {std::string t = x; x = y; y = t;} -// void swap2(std::string & x, std::string & y) {std::string t{std::move(x)}; x = std::move(y); y = std::move(t);} -// void swap(A & x, A & y) {A t = x; x = y; y = t;} -// void swap2(A & x, A & y) {A t{std::move(x)}; x = std::move(y); y = std::move(t);} -//void swap(PIObject & x, PIObject & y) {A t = x; x = y; y = t;} -//void swap2(PIObject & x, PIObject & y) {A t(std::move(x)); x = std::move(y); y = std::move(t);} - -int main(int argc, char * argv[]) { - // PITimeMeasurer tm; - // int m = 100000; - // int a = 99, b = 77; - // piCout << "int"; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(a,b); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(a,b); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(a,b); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(a,b); - // } - // piCout << tm.elapsed_s(); - - // piCout << "size_t"; - // size_t ta = 99, tb = 77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(ta,tb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(ta,tb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(ta,tb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(ta,tb); - // } - // piCout << tm.elapsed_s(); - - // piCout << "ullong"; - // ullong lla = 99, llb = 77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(lla,llb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(lla,llb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(lla,llb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(lla,llb); - // } - // piCout << tm.elapsed_s(); - - // piCout << "double"; - // double da = 0.99,db = 77.77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(da,db); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(da,db); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(da,db); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(da,db); - // } - // piCout << tm.elapsed_s(); - - // piCout << "float"; - // float fa = 0.99,fb = 77.77; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(fa,fb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(fa,fb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(fa,fb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(fa,fb); - // } - // piCout << tm.elapsed_s(); - - // piCout << "A"; - // A aa,ab; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(aa,ab); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(aa,ab); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(aa,ab); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(aa,ab); - // } - // piCout << tm.elapsed_s(); - - // piCout << "std::string"; - // std::string ia = "123456789012345678901vfsdvsd2345678",ib = "qwertyvsdfvvsdvfsuiopqwertyuikolsdfghjklsdfghjk"; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(ia,ib); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(ia,ib); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // ia.swap(ib); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(ia,ib); - // } - // piCout << tm.elapsed_s(); - - - // PIString sa = "123456789012345678901vfsdvsd2345678",sb = "qwertyvsdfvvsdvfsuiopqwertyuikolsdfghjklsdfghjk"; - // piCout << "PIString"; - // tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap(sa,sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // swap2(sa, sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // sa.swap(sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwapBinary(sa, sb); - // } - // piCout << tm.elapsed_s(); tm.reset(); - // for (int i = 0; i < m; ++i) { - // piSwap(sa, sb); - // } - // piCout << tm.elapsed_s(); +using namespace luabridge; +int main() { + lua_State* L = luaL_newstate(); + luaL_dostring(L, script); + luaL_openlibs(L); + lua_pcall(L, 0, 0, 0); + LuaRef s = getGlobal(L, "testString"); + LuaRef n = getGlobal(L, "number"); + std::string luaString = s.cast(); + int answer = n.cast(); + piCout << StdString2PIString(luaString); + piCout << "And here's our number:" << answer; +} +#else +int main() { return 0; } +#endif From b018ea9e073909fe18a28e46bf5e18bcf307153d Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 22 Jul 2020 21:22:20 +0300 Subject: [PATCH 07/68] PIString test for Lua --- CMakeLists.txt | 2 +- main.cpp | 43 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9b643c6..e66837a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -617,7 +617,7 @@ if (NOT CROSSTOOLS) if(MINGW) set(LUA_INCLUDE_DIR ${MINGW_INCLUDE}) endif() - find_package(Lua REQUIRED) + find_package(Lua QUIET) if (LUA_FOUND) message(STATUS "Building PIP with Lua support") add_definitions(-DPIP_LUA) diff --git a/main.cpp b/main.cpp index c8f8b312..518d390a 100644 --- a/main.cpp +++ b/main.cpp @@ -13,7 +13,46 @@ static const char * script "testString = \"LuaBridge works!\" \n" "number = 42 \n"; +namespace luabridge { + +template <> +struct Stack +{ + static void push (lua_State* L, PIString const& str) + { + lua_pushstring(L, str.dataAscii()); + } + + static PIString get (lua_State* L, int index) + { + size_t len; + if (lua_type (L, index) == LUA_TSTRING) + { + const char* str = lua_tolstring(L, index, &len); + return PIString(str, len); + } + + // Lua reference manual: + // If the value is a number, then lua_tolstring also changes the actual value in the stack to a string. + // (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.) + lua_pushvalue (L, index); + const char* str = lua_tolstring(L, -1, &len); + PIString string (str, len); + lua_pop (L, 1); // Pop the temporary string + return string; + } + + static bool isInstance (lua_State* L, int index) + { + return lua_type (L, index) == LUA_TSTRING; + } +}; + +} + + using namespace luabridge; + int main() { lua_State* L = luaL_newstate(); luaL_dostring(L, script); @@ -21,9 +60,9 @@ int main() { lua_pcall(L, 0, 0, 0); LuaRef s = getGlobal(L, "testString"); LuaRef n = getGlobal(L, "number"); - std::string luaString = s.cast(); + PIString luaString = s.cast(); int answer = n.cast(); - piCout << StdString2PIString(luaString); + piCout << luaString; piCout << "And here's our number:" << answer; } #else From 16bbcddf5094fef7d36550ab45d04fa44b8f680c Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 22 Jul 2020 22:20:54 +0300 Subject: [PATCH 08/68] PIP Lua Module --- CMakeLists.txt | 19 ++++++-- cmake/FindPIP.cmake | 14 +++++- .../lua => lib/lua/3rd}/LuaBridge/List.h | 0 .../lua => lib/lua/3rd}/LuaBridge/LuaBridge.h | 0 .../lua => lib/lua/3rd}/LuaBridge/Map.h | 0 .../lua/3rd}/LuaBridge/RefCountedObject.h | 0 .../lua/3rd}/LuaBridge/RefCountedPtr.h | 0 .../lua/3rd}/LuaBridge/UnorderedMap.h | 0 .../lua => lib/lua/3rd}/LuaBridge/Vector.h | 0 .../lua/3rd}/LuaBridge/detail/CFunctions.h | 0 .../lua/3rd}/LuaBridge/detail/ClassInfo.h | 0 .../lua/3rd}/LuaBridge/detail/Config.h | 0 .../lua/3rd}/LuaBridge/detail/Constructor.h | 0 .../lua/3rd}/LuaBridge/detail/FuncTraits.h | 0 .../lua/3rd}/LuaBridge/detail/Iterator.h | 0 .../lua/3rd}/LuaBridge/detail/LuaException.h | 0 .../lua/3rd}/LuaBridge/detail/LuaHelpers.h | 0 .../lua/3rd}/LuaBridge/detail/LuaRef.h | 0 .../lua/3rd}/LuaBridge/detail/Namespace.h | 0 .../lua/3rd}/LuaBridge/detail/Security.h | 0 .../lua/3rd}/LuaBridge/detail/Stack.h | 0 .../lua/3rd}/LuaBridge/detail/TypeList.h | 0 .../lua/3rd}/LuaBridge/detail/TypeTraits.h | 0 .../lua/3rd}/LuaBridge/detail/Userdata.h | 0 .../lua/3rd}/LuaBridge/detail/dump.h | 0 lib/main/lua/piluaprogram.h | 12 +++++ lib/main/lua/pip_lua.h | 39 +++++++++++++++ main.cpp | 47 +------------------ 28 files changed, 82 insertions(+), 49 deletions(-) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/List.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/LuaBridge.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/Map.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/RefCountedObject.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/RefCountedPtr.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/UnorderedMap.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/Vector.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/CFunctions.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/ClassInfo.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Config.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Constructor.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/FuncTraits.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Iterator.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/LuaException.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/LuaHelpers.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/LuaRef.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Namespace.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Security.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Stack.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/TypeList.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/TypeTraits.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/Userdata.h (100%) rename {3rd_party/lua => lib/lua/3rd}/LuaBridge/detail/dump.h (100%) create mode 100644 lib/main/lua/piluaprogram.h create mode 100644 lib/main/lua/pip_lua.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e66837a8..145b35c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ set(PIP_SRC_OPENCL "lib/opencl") set(PIP_SRC_IO_UTILS "lib/io_utils") set(PIP_SRC_CONCURRENT "lib/concurrent") set(PIP_SRC_CLOUD "lib/cloud") +set(PIP_SRC_LUA "lib/lua") set(PIP_SRC_DIRS ${PIP_SRC_MAIN} ${PIP_SRC_CONSOLE} ${PIP_SRC_CRYPT} @@ -83,6 +84,7 @@ set(LIBS_MAIN) set(LIBS_STATUS) set(HDRS) set(PHDRS) +set(HDR_DIRS) if (TESTS) include(DownloadGTest) @@ -178,7 +180,7 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) # Sources # Main lib -set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "concurrent" "cloud") +set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "concurrent" "cloud" "lua") include_directories("${PIP_SRC_MAIN}") set(PIP_MAIN_FOLDERS) foreach(F ${PIP_FOLDERS}) @@ -215,6 +217,9 @@ gather_src("${PIP_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS) # Cloud lib gather_src("${PIP_SRC_CLOUD}" CPP_LIB_CLOUD HDRS PHDRS) +# LUA lib +gather_src("${PIP_SRC_LUA}" CPP_LIB_LUA HDRS PHDRS) + if(PIP_FREERTOS) add_definitions(-DPIP_FREERTOS) set(ICU OFF) @@ -621,7 +626,11 @@ if (NOT CROSSTOOLS) if (LUA_FOUND) message(STATUS "Building PIP with Lua support") add_definitions(-DPIP_LUA) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/3rd_party/lua) + include_directories(${LUA_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd) + list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge") + add_library(pip_lua ${PIP_LIB_TYPE} ${CPP_LIB_LUA} ${_RC}) + target_link_libraries(pip_lua pip ${LUA_LIBRARIES}) + list(APPEND PIP_LIBS_TARGETS pip_lua) endif() # Test program @@ -629,7 +638,7 @@ if (NOT CROSSTOOLS) add_executable(pip_test "main.cpp") target_link_libraries(pip_test pip) if (LUA_FOUND) - target_link_libraries(pip_test ${LUA_LIBRARIES}) + target_link_libraries(pip_test pip_lua ${LUA_LIBRARIES}) endif() endif() @@ -662,6 +671,8 @@ if(LIB) if(MINGW) if (NOT CROSSTOOLS) install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) + install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) + install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip) install(TARGETS ${PIP_LIBS_TARGETS} ARCHIVE DESTINATION ${MINGW_LIB}) endif() install(TARGETS ${PIP_LIBS_TARGETS} RUNTIME DESTINATION ${MINGW_BIN}) @@ -680,6 +691,7 @@ if(LIB) else() if (NOT CROSSTOOLS) install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) + install(DIRECTORY ${HDR_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) endif() install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) endif() @@ -695,6 +707,7 @@ else() install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION lib) endif() install(FILES ${HDRS} DESTINATION include/pip) + install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip) message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") endif() endif() diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 5b21dc6b..aa662695 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -10,6 +10,7 @@ Also create imported targets: * PIP::IOUtils * PIP::Concurrent * PIP::Cloud + * PIP::Lua These targets include directories and depends on main library @@ -66,6 +67,7 @@ find_library(PIP_COMPRESS_LIBRARY pip_compress${_pip_suffix} HINTS ${_PIP_LIBDIR find_library(PIP_IO_UTILS_LIBRARY pip_io_utils${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CONCURRENT_LIBRARY pip_concurrent${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CLOUD_LIBRARY pip_cloud HINTS${_pip_suffix} ${_PIP_LIBDIR}) +find_library(PIP_LUA_LIBRARY pip_lua HINTS${_pip_suffix} ${_PIP_LIBDIR}) find_file(PIP_H_INCLUDE "pip.h" HINTS ${_PIP_INCDIR} $ENV{SMSDK_DIR}/include/pip) get_filename_component(PIP_INCLUDES ${PIP_H_INCLUDE} PATH) set(__ext "") @@ -94,6 +96,12 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") list(APPEND PIP_LIBRARY ${_PIP_ADD_LIBS_}) endif() endif() +if(PIP_LUA_LIBRARY) + if(MINGW) + set(LUA_INCLUDE_DIR ${MINGW_INCLUDE}) + endif() + find_package(Lua QUIET) +endif() if(NOT PIP_VERSION) include(CheckSymbolExists) @@ -117,7 +125,7 @@ if(PIP_FIND_VERSION VERSION_GREATER PIP_VERSION) message(FATAL_ERROR "PIP version ${PIP_VERSION} is available, but ${PIP_FIND_VERSION} requested!") endif() -set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Concurrent;Cloud") +set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Concurrent;Cloud;Lua") set(__module_USB "${PIP_USB_LIBRARY}" ) set(__module_Console "${PIP_CONSOLE_LIBRARY}" ) set(__module_Crypt "${PIP_CRYPT_LIBRARY}" ) @@ -126,6 +134,7 @@ set(__module_Compress "${PIP_COMPRESS_LIBRARY}" ) set(__module_IOUtils "${PIP_IO_UTILS_LIBRARY}" ) set(__module_Concurrent "${PIP_CONCURRENT_LIBRARY}") set(__module_Cloud "${PIP_CLOUD_LIBRARY}" ) +set(__module_Lua "${PIP_LUA_LIBRARY}" ) if((NOT TARGET PIP) AND PIP_LIBRARY) add_library(PIP UNKNOWN IMPORTED) set_target_properties(PIP PROPERTIES @@ -147,6 +156,9 @@ endif() if(__module_Cloud AND __module_IOUtils) set_target_properties(PIP::Cloud PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::IOUtils") endif() +if(__module_Lua ) + set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIR} INTERFACE_LINK_LIBRARIES "PIP::Lua" ${LUA_LIBRARIES}) +endif() include(PIPMacros) diff --git a/3rd_party/lua/LuaBridge/List.h b/lib/lua/3rd/LuaBridge/List.h similarity index 100% rename from 3rd_party/lua/LuaBridge/List.h rename to lib/lua/3rd/LuaBridge/List.h diff --git a/3rd_party/lua/LuaBridge/LuaBridge.h b/lib/lua/3rd/LuaBridge/LuaBridge.h similarity index 100% rename from 3rd_party/lua/LuaBridge/LuaBridge.h rename to lib/lua/3rd/LuaBridge/LuaBridge.h diff --git a/3rd_party/lua/LuaBridge/Map.h b/lib/lua/3rd/LuaBridge/Map.h similarity index 100% rename from 3rd_party/lua/LuaBridge/Map.h rename to lib/lua/3rd/LuaBridge/Map.h diff --git a/3rd_party/lua/LuaBridge/RefCountedObject.h b/lib/lua/3rd/LuaBridge/RefCountedObject.h similarity index 100% rename from 3rd_party/lua/LuaBridge/RefCountedObject.h rename to lib/lua/3rd/LuaBridge/RefCountedObject.h diff --git a/3rd_party/lua/LuaBridge/RefCountedPtr.h b/lib/lua/3rd/LuaBridge/RefCountedPtr.h similarity index 100% rename from 3rd_party/lua/LuaBridge/RefCountedPtr.h rename to lib/lua/3rd/LuaBridge/RefCountedPtr.h diff --git a/3rd_party/lua/LuaBridge/UnorderedMap.h b/lib/lua/3rd/LuaBridge/UnorderedMap.h similarity index 100% rename from 3rd_party/lua/LuaBridge/UnorderedMap.h rename to lib/lua/3rd/LuaBridge/UnorderedMap.h diff --git a/3rd_party/lua/LuaBridge/Vector.h b/lib/lua/3rd/LuaBridge/Vector.h similarity index 100% rename from 3rd_party/lua/LuaBridge/Vector.h rename to lib/lua/3rd/LuaBridge/Vector.h diff --git a/3rd_party/lua/LuaBridge/detail/CFunctions.h b/lib/lua/3rd/LuaBridge/detail/CFunctions.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/CFunctions.h rename to lib/lua/3rd/LuaBridge/detail/CFunctions.h diff --git a/3rd_party/lua/LuaBridge/detail/ClassInfo.h b/lib/lua/3rd/LuaBridge/detail/ClassInfo.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/ClassInfo.h rename to lib/lua/3rd/LuaBridge/detail/ClassInfo.h diff --git a/3rd_party/lua/LuaBridge/detail/Config.h b/lib/lua/3rd/LuaBridge/detail/Config.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Config.h rename to lib/lua/3rd/LuaBridge/detail/Config.h diff --git a/3rd_party/lua/LuaBridge/detail/Constructor.h b/lib/lua/3rd/LuaBridge/detail/Constructor.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Constructor.h rename to lib/lua/3rd/LuaBridge/detail/Constructor.h diff --git a/3rd_party/lua/LuaBridge/detail/FuncTraits.h b/lib/lua/3rd/LuaBridge/detail/FuncTraits.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/FuncTraits.h rename to lib/lua/3rd/LuaBridge/detail/FuncTraits.h diff --git a/3rd_party/lua/LuaBridge/detail/Iterator.h b/lib/lua/3rd/LuaBridge/detail/Iterator.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Iterator.h rename to lib/lua/3rd/LuaBridge/detail/Iterator.h diff --git a/3rd_party/lua/LuaBridge/detail/LuaException.h b/lib/lua/3rd/LuaBridge/detail/LuaException.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/LuaException.h rename to lib/lua/3rd/LuaBridge/detail/LuaException.h diff --git a/3rd_party/lua/LuaBridge/detail/LuaHelpers.h b/lib/lua/3rd/LuaBridge/detail/LuaHelpers.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/LuaHelpers.h rename to lib/lua/3rd/LuaBridge/detail/LuaHelpers.h diff --git a/3rd_party/lua/LuaBridge/detail/LuaRef.h b/lib/lua/3rd/LuaBridge/detail/LuaRef.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/LuaRef.h rename to lib/lua/3rd/LuaBridge/detail/LuaRef.h diff --git a/3rd_party/lua/LuaBridge/detail/Namespace.h b/lib/lua/3rd/LuaBridge/detail/Namespace.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Namespace.h rename to lib/lua/3rd/LuaBridge/detail/Namespace.h diff --git a/3rd_party/lua/LuaBridge/detail/Security.h b/lib/lua/3rd/LuaBridge/detail/Security.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Security.h rename to lib/lua/3rd/LuaBridge/detail/Security.h diff --git a/3rd_party/lua/LuaBridge/detail/Stack.h b/lib/lua/3rd/LuaBridge/detail/Stack.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Stack.h rename to lib/lua/3rd/LuaBridge/detail/Stack.h diff --git a/3rd_party/lua/LuaBridge/detail/TypeList.h b/lib/lua/3rd/LuaBridge/detail/TypeList.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/TypeList.h rename to lib/lua/3rd/LuaBridge/detail/TypeList.h diff --git a/3rd_party/lua/LuaBridge/detail/TypeTraits.h b/lib/lua/3rd/LuaBridge/detail/TypeTraits.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/TypeTraits.h rename to lib/lua/3rd/LuaBridge/detail/TypeTraits.h diff --git a/3rd_party/lua/LuaBridge/detail/Userdata.h b/lib/lua/3rd/LuaBridge/detail/Userdata.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/Userdata.h rename to lib/lua/3rd/LuaBridge/detail/Userdata.h diff --git a/3rd_party/lua/LuaBridge/detail/dump.h b/lib/lua/3rd/LuaBridge/detail/dump.h similarity index 100% rename from 3rd_party/lua/LuaBridge/detail/dump.h rename to lib/lua/3rd/LuaBridge/detail/dump.h diff --git a/lib/main/lua/piluaprogram.h b/lib/main/lua/piluaprogram.h new file mode 100644 index 00000000..ef80bbf7 --- /dev/null +++ b/lib/main/lua/piluaprogram.h @@ -0,0 +1,12 @@ +#ifndef PILUAPROGRAM_H +#define PILUAPROGRAM_H + +#include "pip_lua.h" + +class PILuaProgram +{ +public: + PILuaProgram(); +}; + +#endif // PILUAPROGRAM_H diff --git a/lib/main/lua/pip_lua.h b/lib/main/lua/pip_lua.h new file mode 100644 index 00000000..8830d081 --- /dev/null +++ b/lib/main/lua/pip_lua.h @@ -0,0 +1,39 @@ +#ifndef PIP_LUA_H +#define PIP_LUA_H + +extern "C" { +# include "lua.h" +# include "lauxlib.h" +# include "lualib.h" +} +#include +#include "pistring.h" + +namespace luabridge { + +template <> +struct Stack { + static void push (lua_State* L, PIString const& str) { + lua_pushstring(L, str.dataUTF8()); + } + + static PIString get (lua_State* L, int index) { + if (lua_type(L, index) == LUA_TSTRING) { + const char* str = lua_tostring(L, index); + return PIString::fromUTF8(str); + } + + lua_pushvalue(L, index); + const char* str = lua_tostring(L, -1); + PIString string = PIString::fromUTF8(str); + lua_pop(L, 1); + return string; + } + + static bool isInstance (lua_State* L, int index) { + return lua_type(L, index) == LUA_TSTRING; + } +}; + +} +#endif // PIP_LUA_H diff --git a/main.cpp b/main.cpp index 518d390a..5b32984f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,55 +1,12 @@ #include "pip.h" #ifdef PIP_LUA -extern "C" { -# include "lua.h" -# include "lauxlib.h" -# include "lualib.h" -} -#include -#include "pistring_std.h" +#include "piluaprogram.h" static const char * script = "-- script.lua \n" - "testString = \"LuaBridge works!\" \n" + "testString = \"LuaBridge works ававава!\" \n" "number = 42 \n"; -namespace luabridge { - -template <> -struct Stack -{ - static void push (lua_State* L, PIString const& str) - { - lua_pushstring(L, str.dataAscii()); - } - - static PIString get (lua_State* L, int index) - { - size_t len; - if (lua_type (L, index) == LUA_TSTRING) - { - const char* str = lua_tolstring(L, index, &len); - return PIString(str, len); - } - - // Lua reference manual: - // If the value is a number, then lua_tolstring also changes the actual value in the stack to a string. - // (This change confuses lua_next when lua_tolstring is applied to keys during a table traversal.) - lua_pushvalue (L, index); - const char* str = lua_tolstring(L, -1, &len); - PIString string (str, len); - lua_pop (L, 1); // Pop the temporary string - return string; - } - - static bool isInstance (lua_State* L, int index) - { - return lua_type (L, index) == LUA_TSTRING; - } -}; - -} - using namespace luabridge; From 6f58388d8dbb9664940ff6d9006e015671d1ce71 Mon Sep 17 00:00:00 2001 From: Andrey Date: Wed, 22 Jul 2020 23:00:31 +0300 Subject: [PATCH 09/68] PILuaProgram --- CMakeLists.txt | 19 ++++++++++--- cmake/FindPIP.cmake | 4 +-- lib/lua/piluaprogram.cpp | 53 +++++++++++++++++++++++++++++++++++++ lib/main/lua/piluaprogram.h | 38 ++++++++++++++++++++++++++ lib/main/lua/pip_lua.h | 23 ++++++++++++++++ main.cpp | 17 +++++++----- 6 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 lib/lua/piluaprogram.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 145b35c3..aecd32ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -625,6 +625,13 @@ if (NOT CROSSTOOLS) find_package(Lua QUIET) if (LUA_FOUND) message(STATUS "Building PIP with Lua support") + import_version(pip_lua pip) + set_deploy_property(pip_lua ${PIP_LIB_TYPE} + LABEL "PIP Lua support" + FULLNAME "${_PIP_DOMAIN}.pip_lua" + COMPANY "${_PIP_COMPANY}" + INFO "Platform-Independent Primitives") + make_rc(pip_lua _RC) add_definitions(-DPIP_LUA) include_directories(${LUA_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd) list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge") @@ -672,7 +679,9 @@ if(LIB) if (NOT CROSSTOOLS) install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) - install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip) + if(HDR_DIRS) + install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip) + endif() install(TARGETS ${PIP_LIBS_TARGETS} ARCHIVE DESTINATION ${MINGW_LIB}) endif() install(TARGETS ${PIP_LIBS_TARGETS} RUNTIME DESTINATION ${MINGW_BIN}) @@ -691,7 +700,9 @@ if(LIB) else() if (NOT CROSSTOOLS) install(FILES ${HDRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) - install(DIRECTORY ${HDR_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) + if(HDR_DIRS) + install(DIRECTORY ${HDR_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) + endif() endif() install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) endif() @@ -707,7 +718,9 @@ else() install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION lib) endif() install(FILES ${HDRS} DESTINATION include/pip) - install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip) + if(HDR_DIRS) + install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip) + endif() message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") endif() endif() diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index aa662695..910d72bd 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -156,8 +156,8 @@ endif() if(__module_Cloud AND __module_IOUtils) set_target_properties(PIP::Cloud PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::IOUtils") endif() -if(__module_Lua ) - set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIR} INTERFACE_LINK_LIBRARIES "PIP::Lua" ${LUA_LIBRARIES}) +if(__module_Lua) + set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIR} INTERFACE_LINK_LIBRARIES "PIP" ${LUA_LIBRARIES}) endif() include(PIPMacros) diff --git a/lib/lua/piluaprogram.cpp b/lib/lua/piluaprogram.cpp new file mode 100644 index 00000000..93603e86 --- /dev/null +++ b/lib/lua/piluaprogram.cpp @@ -0,0 +1,53 @@ +/* + PIP - Platform Independent Primitives + PILuaProgram + 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 . +*/ +#include "piluaprogram.h" + + +PRIVATE_DEFINITION_START(PILuaProgram) + lua_State * lua_state; +PRIVATE_DEFINITION_END(PILuaProgram) + + +PILuaProgram::PILuaProgram() { + PRIVATE->lua_state = luaL_newstate(); + luaL_openlibs(PRIVATE->lua_state); +} + + +bool PILuaProgram::load(const PIString & script) { + int ret = luaL_dostring(PRIVATE->lua_state, script.dataUTF8()); + if (ret != 0) return false; + return true; +} + + +bool PILuaProgram::prepare() { + return (lua_pcall(PRIVATE->lua_state, 0, 0, 0) == 0); +} + + +luabridge::LuaRef PILuaProgram::getGlobal(const PIString & name) { + return luabridge::getGlobal(PRIVATE->lua_state, name.dataUTF8()); +} + + +luabridge::Namespace PILuaProgram::getGlobalNamespace() { + return luabridge::getGlobalNamespace(PRIVATE->lua_state); +} + diff --git a/lib/main/lua/piluaprogram.h b/lib/main/lua/piluaprogram.h index ef80bbf7..a21b075a 100644 --- a/lib/main/lua/piluaprogram.h +++ b/lib/main/lua/piluaprogram.h @@ -1,3 +1,25 @@ +/*! \file piluaprogram.h + * \brief Lua Program +*/ +/* + PIP - Platform Independent Primitives + PILuaProgram + 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 . +*/ + #ifndef PILUAPROGRAM_H #define PILUAPROGRAM_H @@ -6,7 +28,23 @@ class PILuaProgram { public: + //! Constructs an empty PILuaProgram, initialize Lua context PILuaProgram(); + + //! Load Lua script from PIString + bool load(const PIString & script); + + //! Execute script + bool prepare(); + + //! Get Lua Object or Function + luabridge::LuaRef getGlobal(const PIString & name); + + //! Return Lua global namespace + luabridge::Namespace getGlobalNamespace(); + +private: + PRIVATE_DECLARATION }; #endif // PILUAPROGRAM_H diff --git a/lib/main/lua/pip_lua.h b/lib/main/lua/pip_lua.h index 8830d081..56a1a9a5 100644 --- a/lib/main/lua/pip_lua.h +++ b/lib/main/lua/pip_lua.h @@ -1,3 +1,26 @@ +/*! \file pip_lua.h + * \brief PIP Lua bindings + * + * This file declare conversions for PIP types via LuaBridge +*/ +/* + PIP - Platform Independent Primitives + PIP Lua bindings + 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 . +*/ #ifndef PIP_LUA_H #define PIP_LUA_H diff --git a/main.cpp b/main.cpp index 5b32984f..d78cedcf 100644 --- a/main.cpp +++ b/main.cpp @@ -4,19 +4,22 @@ static const char * script = "-- script.lua \n" + "test()\n" "testString = \"LuaBridge works ававава!\" \n" "number = 42 \n"; -using namespace luabridge; +void test() { + piCout << "C function test"; +} int main() { - lua_State* L = luaL_newstate(); - luaL_dostring(L, script); - luaL_openlibs(L); - lua_pcall(L, 0, 0, 0); - LuaRef s = getGlobal(L, "testString"); - LuaRef n = getGlobal(L, "number"); + PILuaProgram p; + p.getGlobalNamespace().addFunction("test", test); + if (!p.load(PIString::fromUTF8(script))) piCout << "error"; + p.prepare(); + luabridge::LuaRef s = p.getGlobal("testString"); + luabridge::LuaRef n = p.getGlobal("number"); PIString luaString = s.cast(); int answer = n.cast(); piCout << luaString; From e63aab40f6f62149678a55eba2c9bbf73242786d Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 24 Jul 2020 12:14:00 +0300 Subject: [PATCH 10/68] fix FindPIP.cmake --- cmake/FindPIP.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 910d72bd..52678bef 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -157,7 +157,7 @@ if(__module_Cloud AND __module_IOUtils) set_target_properties(PIP::Cloud PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::IOUtils") endif() if(__module_Lua) - set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${LUA_INCLUDE_DIR} INTERFACE_LINK_LIBRARIES "PIP" ${LUA_LIBRARIES}) + set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}" INTERFACE_LINK_LIBRARIES "PIP ${LUA_LIBRARIES}") endif() include(PIPMacros) From cdbc401616e73c896db3e7f586bbe4a21e6701c8 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 24 Jul 2020 14:04:19 +0300 Subject: [PATCH 11/68] fixed FindPIP with Lua --- CMakeLists.txt | 2 +- cmake/FindPIP.cmake | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7a095b0..5a0fe738 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(pip) set(_PIP_MAJOR 1) set(_PIP_MINOR 99) set(_PIP_REVISION 0) -set(_PIP_SUFFIX _pre_alpha) +set(_PIP_SUFFIX _prealpha) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 52678bef..0752e873 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -97,10 +97,17 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") endif() endif() if(PIP_LUA_LIBRARY) - if(MINGW) - set(LUA_INCLUDE_DIR ${MINGW_INCLUDE}) + if (NOT LUA_FOUND) + if(MINGW) + set(LUA_INCLUDE_DIR ${MINGW_INCLUDE}) + set(_prev_clp "${CMAKE_LIBRARY_PATH}") + set(CMAKE_LIBRARY_PATH "${MINGW_LIB}") + endif() + find_package(Lua QUIET) + if(MINGW) + set(CMAKE_LIBRARY_PATH "${_prev_clp}") + endif() endif() - find_package(Lua QUIET) endif() if(NOT PIP_VERSION) @@ -157,7 +164,7 @@ if(__module_Cloud AND __module_IOUtils) set_target_properties(PIP::Cloud PROPERTIES INTERFACE_LINK_LIBRARIES "PIP::IOUtils") endif() if(__module_Lua) - set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}" INTERFACE_LINK_LIBRARIES "PIP ${LUA_LIBRARIES}") + set_target_properties(PIP::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LUA_INCLUDE_DIR}" INTERFACE_LINK_LIBRARIES "PIP;${LUA_LIBRARIES}") endif() include(PIPMacros) From e82831377a1afd6cd796863393bc341d7bc64485 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 25 Jul 2020 13:13:53 +0300 Subject: [PATCH 12/68] CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f7a095b0..fac379b4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -594,7 +594,7 @@ if (NOT CROSSTOOLS) list(APPEND PIP_LIBS_TARGETS pip_concurrent) # Enable build tests for concurrent module - if(CONCURRENT_TESTS) + if(PIP_CONCURRENT_TEST) add_executable(pip_concurrent_test ${CPP_CONCURRENT_TEST}) target_link_libraries(pip_concurrent_test gtest_main gmock_main pip_concurrent) add_test(NAME pip_concurrent_test COMMAND tests) From b153673974843419eda02b023a2528e9501ddc40 Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 27 Jul 2020 17:54:07 +0300 Subject: [PATCH 13/68] CMakeLists.txt --- CMakeLists.txt | 6 ++++-- lib/main/lua/pip_lua.h | 6 +----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b14572bc..a657a73f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -624,7 +624,7 @@ if (NOT CROSSTOOLS) endif() find_package(Lua QUIET) if (LUA_FOUND) - message(STATUS "Building PIP with Lua support") + message(STATUS "Building PIP with Lua support: Lua ${LUA_VERSION_STRING}") import_version(pip_lua pip) set_deploy_property(pip_lua ${PIP_LIB_TYPE} LABEL "PIP Lua support" @@ -638,8 +638,10 @@ if (NOT CROSSTOOLS) add_library(pip_lua ${PIP_LIB_TYPE} ${CPP_LIB_LUA} ${_RC}) target_link_libraries(pip_lua pip ${LUA_LIBRARIES}) list(APPEND PIP_LIBS_TARGETS pip_lua) + else() + message(STATUS "Building PIP without Lua support") endif() - + # Test program if(PIP_UTILS) add_executable(pip_test "main.cpp") diff --git a/lib/main/lua/pip_lua.h b/lib/main/lua/pip_lua.h index 56a1a9a5..a9b94167 100644 --- a/lib/main/lua/pip_lua.h +++ b/lib/main/lua/pip_lua.h @@ -24,11 +24,7 @@ #ifndef PIP_LUA_H #define PIP_LUA_H -extern "C" { -# include "lua.h" -# include "lauxlib.h" -# include "lualib.h" -} +#include "lua.hpp" #include #include "pistring.h" From 48692a47246e96f39f6475f47438cfa56e84f368 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 30 Jul 2020 00:20:19 +0300 Subject: [PATCH 14/68] remove remote_console --- CMakeLists.txt | 141 +++++++++++++--------- cmake/FindPIP.cmake | 5 +- utils/cloud_dispatcher/CMakeLists.txt | 3 +- utils/code_model_generator/CMakeLists.txt | 3 +- utils/crypt_tool/CMakeLists.txt | 3 +- utils/deploy_tool/CMakeLists.txt | 3 +- utils/remote_console/CMakeLists.txt | 6 - utils/remote_console/main.cpp | 63 ---------- utils/resources_compiler/CMakeLists.txt | 3 +- utils/system_daemon/CMakeLists.txt | 3 +- utils/system_test/CMakeLists.txt | 3 +- utils/udp_file_transfer/CMakeLists.txt | 3 +- 12 files changed, 103 insertions(+), 136 deletions(-) delete mode 100755 utils/remote_console/CMakeLists.txt delete mode 100755 utils/remote_console/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index a657a73f..4b98ce8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ set(PIP_UTILS 1) if(LIBPROJECT) set(PIP_UTILS ${UTILS}) endif() +set(CMAKE_CXX_STANDARD_REQUIRED 1) set(CMAKE_CXX_STANDARD 11) @@ -86,6 +87,19 @@ set(HDRS) set(PHDRS) set(HDR_DIRS) +set(PIP_STD_IOSTREAM "no") +set(PIP_ICU "no") +set(PIP_INTROSPECTION "no") +set(PIP_USB "no") +set(PIP_CRYPT "no") +set(PIP_CLOUD "no") +set(PIP_COMPRESS "no") +set(PIP_FFTW "no") +set(PIP_OPENCL "no") +set(PIP_LUA "no") +set(PIP_IOUTILS "yes") +set(PIP_UTILS_LIST) + if (TESTS) include(DownloadGTest) set(PIP_CONCURRENT_TEST "lib/concurrent/test") @@ -97,11 +111,11 @@ endif() if(STATIC_LIB) set(PIP_LIB_TYPE STATIC) + set(PIP_LIB_TYPE_MSG "Static") add_definitions(-DPIP_STATIC_DEFINE) - #message(STATUS "Building PIP static library") else() set(PIP_LIB_TYPE SHARED) - #message(STATUS "Building PIP shared library") + set(PIP_LIB_TYPE_MSG "Shared") endif() @@ -122,7 +136,6 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h") file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h") endif() list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/piversion.h") -message(STATUS "Building PIP version ${PIP_VERSION} (${PIP_LIB_TYPE})") if(MINGW) find_package(MinGW REQUIRED) @@ -174,7 +187,6 @@ endif() # Compiler get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) -#message("${C_COMPILER}") # Sources @@ -269,31 +281,27 @@ CHECK_FUNCTION_EXISTS(timer_delete PIP_TIMER_RT_2) # Check if build debug version if (CMAKE_BUILD_TYPE MATCHES Debug) + set(PIP_BUILD_TYPE "Debug") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3 -Wall") add_definitions(-DPIP_DEBUG) - message(STATUS "Building PIP debug version") else() + set(PIP_BUILD_TYPE "Release") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall") - message(STATUS "Building PIP release version") endif() # Check if std::iostream operators support if(STD_IOSTREAM) + set(PIP_STD_IOSTREAM "yes") add_definitions(-DPIP_STD_IOSTREAM) - message(STATUS "Building PIP with std iostream operators support") -else() - message(STATUS "Building PIP without std iostream operators support") endif() # Check if ICU used for PIString and PIChar if(ICU) - message(STATUS "Building PIP with ICU") + set(PIP_ICU "yes") add_definitions(-DPIP_ICU) list(APPEND LIBS_MAIN icuuc) -else() - message(STATUS "Building PIP without ICU") endif() @@ -301,12 +309,9 @@ endif() set(_PIP_DEFS "") set(_PIP_DEFS_FILE "${CMAKE_CURRENT_BINARY_DIR}/pip_defs.h") if(INTROSPECTION) - message(STATUS "Building PIP with introspection") - message(STATUS "Warning: Introspection reduces the performance!") + set(PIP_INTROSPECTION "yes") add_definitions(-DPIP_INTROSPECTION) set(_PIP_DEFS "PIP_INTROSPECTION") -else() - message(STATUS "Building PIP without introspection") endif() if ((NOT DEFINED _PIP_SAVED_DEFS) OR (NOT "x${_PIP_SAVED_DEFS}" STREQUAL "x${_PIP_DEFS}")) set(_PIP_SAVED_DEFS "${_PIP_DEFS}" CACHE STRING "pip_defs" FORCE) @@ -321,10 +326,10 @@ list(APPEND HDRS ${_PIP_DEFS_FILE}) # Check if RT timers exists if(PIP_TIMER_RT_0 AND PIP_TIMER_RT_1 AND PIP_TIMER_RT_2) + set(PIP_TIMERS "Thread, ThreadRT, Pool") add_definitions(-DPIP_TIMER_RT) - message(STATUS "Building PIP with timers: Thread, ThreadRT, Pool") else() - message(STATUS "Building PIP with timers: Thread, Pool") + set(PIP_TIMERS "Thread, Pool") endif() @@ -395,7 +400,7 @@ if (NOT CROSSTOOLS) # Check if USB is supported find_library(usb_FOUND usb SHARED) if(usb_FOUND) - message(STATUS "Building PIP with USB support") + set(PIP_USB "yes") import_version(pip_usb pip) set_deploy_property(pip_usb ${PIP_LIB_TYPE} LABEL "PIP usb support" @@ -408,8 +413,6 @@ if (NOT CROSSTOOLS) target_link_libraries(pip_usb pip ${usb_FOUND}) list(APPEND LIBS_STATUS usb) list(APPEND PIP_LIBS_TARGETS pip_usb) - else() - message(STATUS "Building PIP without USB support") endif() @@ -429,7 +432,9 @@ if (NOT CROSSTOOLS) # Check if PIP support cryptographic encryption/decryption using sodium library find_library(sodium_FOUND sodium) if(sodium_FOUND) - message(STATUS "Building PIP with crypt support") + set(PIP_CRYPT "yes") + set(PIP_IOUTILS "yes (+crypt)") + set(PIP_CLOUD "yes") import_version(pip_crypt pip) set_deploy_property(pip_crypt ${PIP_LIB_TYPE} LABEL "PIP crypt support" @@ -442,15 +447,13 @@ if (NOT CROSSTOOLS) target_link_libraries(pip_crypt pip ${sodium_FOUND}) list(APPEND LIBS_STATUS sodium) list(APPEND PIP_LIBS_TARGETS pip_crypt) - else() - message(STATUS "Building PIP without crypt support") endif() # Check if PIP support compress/decompress using zlib library find_library(zlib_FOUND NAMES z zlib) if(zlib_FOUND) - message(STATUS "Building PIP with zlib compress support") + set(PIP_COMPRESS "yes") import_version(pip_compress pip) set_deploy_property(pip_compress ${PIP_LIB_TYPE} LABEL "PIP compression support" @@ -463,8 +466,6 @@ if (NOT CROSSTOOLS) target_link_libraries(pip_compress pip ${zlib_FOUND}) list(APPEND LIBS_STATUS zlib) list(APPEND PIP_LIBS_TARGETS pip_compress) - else() - message(STATUS "Building PIP without compress support") endif() @@ -487,7 +488,6 @@ if (NOT CROSSTOOLS) if(${FFTW_CLN}_FOUND) list(APPEND FFTW_LIBS "${FFTW_CLN}") list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_FOUND}") - #message(STATUS "PIFFTW found ${FFTW_CLN} = ${${FFTW_CLN}_FOUND}") set(${FFTW_CLN}_CTS "${FFTW_CLN}") if(${FFTW_CLNT}_FOUND) list(APPEND FFTW_LIBS "${FFTW_CLNT}") @@ -503,13 +503,12 @@ if (NOT CROSSTOOLS) else() message(STATUS "Warning: PIFFTW${FFTW_S_}::preparePlan was not threadsafe") endif() - #message(STATUS "${FFTW_CLN} -> ${${FFTW_CLN}_TSFE}") endif() endif() endforeach() endforeach() if(FFTW_LIBS) - message(STATUS "Building PIP with fftw3 support: ${FFTW_LIBS}") + set(PIP_FFTW "yes (${FFTW_LIBS})") import_version(pip_fftw pip) set_deploy_property(pip_fftw ${PIP_LIB_TYPE} LABEL "PIP FFTW support" @@ -521,15 +520,13 @@ if (NOT CROSSTOOLS) target_link_libraries(pip_fftw pip ${FFTW_ABS_LIBS}) list(APPEND LIBS_STATUS ${FFTW_LIBS}) list(APPEND PIP_LIBS_TARGETS pip_fftw) - else() - message(STATUS "Building PIP without fftw3 support") endif() # Check if PIP support OpenCL find_package(OpenCL QUIET) if(OpenCL_FOUND) - message(STATUS "Building PIP with OpenCL support") + set(PIP_OPENCL "yes (${OpenCL_VERSION_STRING})") import_version(pip_opencl pip) set_deploy_property(pip_opencl ${PIP_LIB_TYPE} LABEL "PIP OpenCL support" @@ -554,8 +551,6 @@ if (NOT CROSSTOOLS) list(APPEND LIBS_STATUS OpenCL) list(APPEND PIP_LIBS_TARGETS pip_opencl) set(OpenCL_FOUND ${OpenCL_LIBRARIES}) - else() - message(STATUS "Building PIP without OpenCL support") endif() @@ -570,10 +565,7 @@ if (NOT CROSSTOOLS) make_rc(pip_io_utils _RC) add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS} ${_RC}) if(sodium_FOUND) - message(STATUS "Building PIP IO Utils library with crypt support") list(APPEND IO_UTILS_LIBS pip_crypt) - else() - message(STATUS "Building PIP IO Utils library without crypt support, attention!") endif() target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) list(APPEND PIP_LIBS_TARGETS pip_io_utils) @@ -604,7 +596,6 @@ if (NOT CROSSTOOLS) # Build cloud library if crypt enabled if(sodium_FOUND) - message(STATUS "Building PICloud support") import_version(pip_cloud pip) set_deploy_property(pip_cloud ${PIP_LIB_TYPE} LABEL "PIP cloud transport support" @@ -624,7 +615,7 @@ if (NOT CROSSTOOLS) endif() find_package(Lua QUIET) if (LUA_FOUND) - message(STATUS "Building PIP with Lua support: Lua ${LUA_VERSION_STRING}") + set(PIP_LUA "yes (${LUA_VERSION_STRING})") import_version(pip_lua pip) set_deploy_property(pip_lua ${PIP_LIB_TYPE} LABEL "PIP Lua support" @@ -638,8 +629,6 @@ if (NOT CROSSTOOLS) add_library(pip_lua ${PIP_LIB_TYPE} ${CPP_LIB_LUA} ${_RC}) target_link_libraries(pip_lua pip ${LUA_LIBRARIES}) list(APPEND PIP_LIBS_TARGETS pip_lua) - else() - message(STATUS "Building PIP without Lua support") endif() # Test program @@ -653,18 +642,17 @@ if (NOT CROSSTOOLS) else() - message(STATUS "Building PIP with crypt support") + set(PIP_CRYPT "yes") + set(PIP_COMPRESS "yes") add_definitions(-DPIP_CRYPT) add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT}) target_link_libraries(pip_crypt pip) list(APPEND PIP_LIBS_TARGETS pip_crypt) set(IO_UTILS_LIBS pip) add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS}) - message(STATUS "Building PIP IO Utils library with crypt support") list(APPEND IO_UTILS_LIBS pip_crypt) target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) list(APPEND PIP_LIBS_TARGETS pip_io_utils) - message(STATUS "Building PIP with zlib compress support") add_definitions(-DPIP_COMPRESS) add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS}) target_link_libraries(pip_compress pip) @@ -696,7 +684,6 @@ if(LIB) file(COPY "${STDLIB}" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/utils/deploy_tool") endif() else() - #message("${CMAKE_CURRENT_BINARY_DIR}/pip_export.h") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pip_export.h DESTINATION include) endif() else() @@ -708,7 +695,6 @@ if(LIB) endif() install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) endif() - message(STATUS "Install ${PROJECT_NAME} to system \"${CMAKE_INSTALL_PREFIX}\"") file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in" "cmake/android_debug.keystore") install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) else() @@ -723,7 +709,6 @@ else() if(HDR_DIRS) install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip) endif() - message(STATUS "Install ${PROJECT_NAME} to local \"bin\", \"lib\" and \"include\"") endif() endif() @@ -740,7 +725,6 @@ if(NOT PIP_FREERTOS) add_subdirectory("utils/deploy_tool") if(PIP_UTILS AND (NOT CROSSTOOLS)) add_subdirectory("utils/system_test") - add_subdirectory("utils/remote_console") add_subdirectory("utils/udp_file_transfer") if(sodium_FOUND) add_subdirectory("utils/system_daemon") @@ -753,20 +737,11 @@ endif() # Libraries messages -message(STATUS "Building PIP modules: ${PIP_LIBS_TARGETS}") if(DEFINED LIBPROJECT) set(PIP_LIBS_TARGETS ${PIP_LIBS_TARGETS} PARENT_SCOPE) list(APPEND _ALL_TARGETS ${PIP_LIBS_TARGETS}) set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) endif() -if(NOT PIP_FREERTOS) - foreach(LIB_ ${LIBS_STATUS}) - message(STATUS "Library ${LIB_} -> " ${${LIB_}_FOUND}) - if(NOT ${LIB_}_FOUND) - message(WARNING "Library ${LIB_} not found, please install it") - endif() - endforeach() -endif() # # Build Documentation @@ -797,3 +772,53 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS)) endif() endif() + + +message("----------PIP----------") +message(" Version: ${PIP_VERSION} ") +message(" Linkage: ${PIP_LIB_TYPE_MSG}") +message(" Type : ${PIP_BUILD_TYPE}") +if(LIB) + message(" Install: \"${CMAKE_INSTALL_PREFIX}\"") +else() + if(NOT PIP_FREERTOS) + message(" Install: local \"bin\", \"lib\" and \"include\"") + endif() +endif() +message("") +message(" Options:") +message(" std::iostream: ${PIP_STD_IOSTREAM}") +message(" ICU strings : ${PIP_ICU}") +message(" Timer types : ${PIP_TIMERS}") +message(" Introspection: ${PIP_INTROSPECTION}") +if(INTROSPECTION) + message(STATUS " Warning: Introspection reduces the performance!") +endif() +message("") +message(" Modules:") +message(" USB : ${PIP_USB}") +message(" Console : yes") +message(" Crypt : ${PIP_CRYPT}") +message(" Compress : ${PIP_COMPRESS}") +message(" FFTW : ${PIP_FFTW}") +message(" OpenCL : ${PIP_OPENCL}") +message(" IOUtils : ${PIP_IOUTILS}") +message(" Concurrent: yes") +message(" Cloud : ${PIP_CLOUD}") +message(" Lua : ${PIP_LUA}") +message("") +message(" Utilites:") +foreach(_util ${PIP_UTILS_LIST}) + message(" * ${_util}") +endforeach() +if(NOT PIP_FREERTOS) + message("") + message(" Using libraries:") + foreach(LIB_ ${LIBS_STATUS}) + message(" ${LIB_} -> " ${${LIB_}_FOUND}) + if(NOT ${LIB_}_FOUND) + message(" ${LIB_} not found, may fail") + endif() + endforeach() +endif() +message("-----------------------") diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 0752e873..48b4b47f 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -5,8 +5,9 @@ Also create imported targets: * PIP::USB * PIP::Console * PIP::Crypt - * PIP::FFTW * PIP::Compress + * PIP::FFTW + * PIP::OpenCL * PIP::IOUtils * PIP::Concurrent * PIP::Cloud @@ -64,6 +65,7 @@ find_library(PIP_CONSOLE_LIBRARY pip_console${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CRYPT_LIBRARY pip_crypt${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_FFTW_LIBRARY pip_fftw${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_COMPRESS_LIBRARY pip_compress${_pip_suffix} HINTS ${_PIP_LIBDIR}) +find_library(PIP_OPENCL_LIBRARY pip_opencl${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_IO_UTILS_LIBRARY pip_io_utils${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CONCURRENT_LIBRARY pip_concurrent${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CLOUD_LIBRARY pip_cloud HINTS${_pip_suffix} ${_PIP_LIBDIR}) @@ -138,6 +140,7 @@ set(__module_Console "${PIP_CONSOLE_LIBRARY}" ) set(__module_Crypt "${PIP_CRYPT_LIBRARY}" ) set(__module_FFTW "${PIP_FFTW_LIBRARY}" ) set(__module_Compress "${PIP_COMPRESS_LIBRARY}" ) +set(__module_OpenCL "${PIP_OPENCL_LIBRARY}" ) set(__module_IOUtils "${PIP_IO_UTILS_LIBRARY}" ) set(__module_Concurrent "${PIP_CONCURRENT_LIBRARY}") set(__module_Cloud "${PIP_CLOUD_LIBRARY}" ) diff --git a/utils/cloud_dispatcher/CMakeLists.txt b/utils/cloud_dispatcher/CMakeLists.txt index 80d86378..e48f86f4 100644 --- a/utils/cloud_dispatcher/CMakeLists.txt +++ b/utils/cloud_dispatcher/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building picloud") +list(APPEND PIP_UTILS_LIST "picloud") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) file(GLOB CPPS "*.cpp") file(GLOB HDRS "*.h") add_executable(picloud ${CPPS} ${HDRS}) diff --git a/utils/code_model_generator/CMakeLists.txt b/utils/code_model_generator/CMakeLists.txt index 51995226..bdbef9b6 100755 --- a/utils/code_model_generator/CMakeLists.txt +++ b/utils/code_model_generator/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building pip_cmg") +list(APPEND PIP_UTILS_LIST "pip_cmg") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) import_version(pip_cmg pip) set_deploy_property(pip_cmg LABEL "PIP code model generator" diff --git a/utils/crypt_tool/CMakeLists.txt b/utils/crypt_tool/CMakeLists.txt index 302631d0..0b99f04f 100644 --- a/utils/crypt_tool/CMakeLists.txt +++ b/utils/crypt_tool/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building picrypt") +list(APPEND PIP_UTILS_LIST "picrypt") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) add_executable(picrypt "main.cpp") target_link_libraries(picrypt pip pip_crypt) if (DEFINED LIB) diff --git a/utils/deploy_tool/CMakeLists.txt b/utils/deploy_tool/CMakeLists.txt index ce53d07f..3441412c 100644 --- a/utils/deploy_tool/CMakeLists.txt +++ b/utils/deploy_tool/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building deploy_tool") +list(APPEND PIP_UTILS_LIST "deploy_tool") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) import_version(deploy_tool pip) set_deploy_property(deploy_tool LABEL "PIP deploy tool" diff --git a/utils/remote_console/CMakeLists.txt b/utils/remote_console/CMakeLists.txt deleted file mode 100755 index 33234067..00000000 --- a/utils/remote_console/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -message(STATUS "Building pip_remote_console") -add_executable(pip_remote_console "main.cpp") -target_link_libraries(pip_remote_console pip pip_console) -if (DEFINED LIB) - install(TARGETS pip_remote_console DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) -endif () diff --git a/utils/remote_console/main.cpp b/utils/remote_console/main.cpp deleted file mode 100755 index d0c89fcc..00000000 --- a/utils/remote_console/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - PIP - Platform Independent Primitives - Remote console viewer - 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 . -*/ - -#include "pip.h" - -void key_event(PIKbdListener::KeyEvent key, void * ); - -PIConsole console(false, key_event); -PIStringList as; -bool selected = false; - -void key_event(PIKbdListener::KeyEvent key, void * ) { - if (key.key < '1' || key.key > '9') return; - int ind = key.key - '1'; - if (ind < 0 || ind >= as.size_s()) return; - selected = true; - console.connectToServer(as[ind]); -} - -int main(int argc, char * argv[]) { - console.enableExitCapture(); - console.listenServers(); - while (!PIKbdListener::exiting) { - msleep(200); - if (selected) break; - console.clearScreen(); - as = console.availableServers(); - if (as.isEmpty()) { - piCout << "No servers are available!"; - } else { - piCout << "Select one with numeric key:"; - for (int i = 0; i < as.size_s(); ++i) - piCout << (i + 1) << as[i]; - } - } - if (!selected) return 0; - piCout << "Connecting to" << console.selectedServer() << "..."; - while (!PIKbdListener::exiting) { - msleep(20); - if (console.isConnected()) - break; - } - if (PIKbdListener::exiting) - return 0; - console.start(); - console.waitForFinish(); -}; diff --git a/utils/resources_compiler/CMakeLists.txt b/utils/resources_compiler/CMakeLists.txt index af7642ab..e0a575c6 100644 --- a/utils/resources_compiler/CMakeLists.txt +++ b/utils/resources_compiler/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building pip_rc") +list(APPEND PIP_UTILS_LIST "pip_rc") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) import_version(pip_rc pip) set_deploy_property(pip_rc LABEL "PIP resources compiler" diff --git a/utils/system_daemon/CMakeLists.txt b/utils/system_daemon/CMakeLists.txt index 004a22f8..ecf2bbf2 100755 --- a/utils/system_daemon/CMakeLists.txt +++ b/utils/system_daemon/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building pisd") +list(APPEND PIP_UTILS_LIST "pisd") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) file(GLOB CPPS "*.cpp") file(GLOB HDRS "*.h") add_executable(pisd ${CPPS} ${HDRS}) diff --git a/utils/system_test/CMakeLists.txt b/utils/system_test/CMakeLists.txt index fe07d4bb..e93f6be7 100755 --- a/utils/system_test/CMakeLists.txt +++ b/utils/system_test/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building pip_system_test") +list(APPEND PIP_UTILS_LIST "pip_system_test") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) add_executable(pip_system_test "main.cpp") target_link_libraries(pip_system_test pip) if (DEFINED LIB) diff --git a/utils/udp_file_transfer/CMakeLists.txt b/utils/udp_file_transfer/CMakeLists.txt index cc3ab463..d2404bb9 100644 --- a/utils/udp_file_transfer/CMakeLists.txt +++ b/utils/udp_file_transfer/CMakeLists.txt @@ -1,4 +1,5 @@ -message(STATUS "Building pift") +list(APPEND PIP_UTILS_LIST "pift") +set(PIP_UTILS_LIST ${PIP_UTILS_LIST} PARENT_SCOPE) add_executable(pift "main.cpp") target_link_libraries(pift pip pip_console) if (DEFINED LIB) From 4dd59132d598cb71ba2730757a700ff93bfc6906 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 30 Jul 2020 16:17:45 +0300 Subject: [PATCH 15/68] LUA lib status, some fixes --- CMakeLists.txt | 59 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b98ce8f..4d731562 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -365,10 +365,12 @@ if(PIP_FREERTOS) set(PIP_LIBS ${LIBS_MAIN}) else() foreach(LIB_ ${LIBS_MAIN}) - find_library(${LIB_}_FOUND ${LIB_}) - if(${LIB_}_FOUND) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${${LIB_}_FOUND}) - list(APPEND PIP_LIBS ${${LIB_}_FOUND}) + find_library(${LIB_}_LIBRARIES ${LIB_}) + set(${LIB_}_FOUND FALSE) + if(${LIB_}_LIBRARIES) + set(${LIB_}_FOUND TRUE) + list(APPEND CMAKE_REQUIRED_LIBRARIES ${${LIB_}_LIBRARIES}) + list(APPEND PIP_LIBS ${${LIB_}_LIBRARIES}) endif() endforeach() endif() @@ -398,8 +400,10 @@ target_link_libraries(pip ${PIP_LIBS}) if (NOT CROSSTOOLS) if (NOT PIP_FREERTOS) # Check if USB is supported - find_library(usb_FOUND usb SHARED) - if(usb_FOUND) + find_library(usb_LIBRARIES usb SHARED) + set(usb_FOUND FALSE) + if(usb_LIBRARIES) + set(usb_FOUND TRUE) set(PIP_USB "yes") import_version(pip_usb pip) set_deploy_property(pip_usb ${PIP_LIB_TYPE} @@ -410,7 +414,7 @@ if (NOT CROSSTOOLS) make_rc(pip_usb _RC) add_definitions(-DPIP_USB) add_library(pip_usb ${PIP_LIB_TYPE} ${CPP_LIB_USB} ${_RC}) - target_link_libraries(pip_usb pip ${usb_FOUND}) + target_link_libraries(pip_usb pip ${usb_LIBRARIES}) list(APPEND LIBS_STATUS usb) list(APPEND PIP_LIBS_TARGETS pip_usb) endif() @@ -430,8 +434,10 @@ if (NOT CROSSTOOLS) # Check if PIP support cryptographic encryption/decryption using sodium library - find_library(sodium_FOUND sodium) - if(sodium_FOUND) + find_library(sodium_LIBRARIES sodium) + set(sodium_FOUND FALSE) + if(sodium_LIBRARIES) + set(sodium_FOUND TRUE) set(PIP_CRYPT "yes") set(PIP_IOUTILS "yes (+crypt)") set(PIP_CLOUD "yes") @@ -444,15 +450,17 @@ if (NOT CROSSTOOLS) make_rc(pip_crypt _RC) add_definitions(-DPIP_CRYPT) add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT} ${_RC}) - target_link_libraries(pip_crypt pip ${sodium_FOUND}) + target_link_libraries(pip_crypt pip ${sodium_LIBRARIES}) list(APPEND LIBS_STATUS sodium) list(APPEND PIP_LIBS_TARGETS pip_crypt) endif() # Check if PIP support compress/decompress using zlib library - find_library(zlib_FOUND NAMES z zlib) - if(zlib_FOUND) + find_library(zlib_LIBRARIES NAMES z zlib) + set(zlib_FOUND FALSE) + if(zlib_LIBRARIES) + set(zlib_FOUND TRUE) set(PIP_COMPRESS "yes") import_version(pip_compress pip) set_deploy_property(pip_compress ${PIP_LIB_TYPE} @@ -463,7 +471,7 @@ if (NOT CROSSTOOLS) make_rc(pip_compress _RC) add_definitions(-DPIP_COMPRESS) add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS} ${_RC}) - target_link_libraries(pip_compress pip ${zlib_FOUND}) + target_link_libraries(pip_compress pip ${zlib_LIBRARIES}) list(APPEND LIBS_STATUS zlib) list(APPEND PIP_LIBS_TARGETS pip_compress) endif() @@ -475,7 +483,6 @@ if (NOT CROSSTOOLS) set(FFTW_LIB_SUFFIXES2 "" "-3") set(FFTW_LIBS) set(FFTW_ABS_LIBS) - set(PIP_FFTW_FOUND) set(CMAKE_REQUIRED_INCLUDES fftw3.h) foreach(FFTW_S_ IN LISTS FFTW_LIB_SUFFIXES) set(FFTW_BREAK false) @@ -483,21 +490,24 @@ if (NOT CROSSTOOLS) if(NOT FFTW_BREAK) set(FFTW_CLN "${FFTW_LIB_NAME}${FFTW_S_}${FFTW_S2_}") set(FFTW_CLNT "${FFTW_LIB_NAME}${FFTW_S_}_threads${FFTW_S2_}") - find_library(${FFTW_CLN}_FOUND ${FFTW_CLN}) - find_library(${FFTW_CLNT}_FOUND ${FFTW_CLNT}) - if(${FFTW_CLN}_FOUND) + find_library(${FFTW_CLN}_LIBRARIES ${FFTW_CLN}) + find_library(${FFTW_CLNT}_LIBRARIES ${FFTW_CLNT}) + set(${FFTW_CLN}_FOUND FALSE) + set(${FFTW_CLNT}_FOUND FALSE) + if(${FFTW_CLN}_LIBRARIES) + set(${FFTW_CLN}_FOUND TRUE) list(APPEND FFTW_LIBS "${FFTW_CLN}") - list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_FOUND}") + list(APPEND FFTW_ABS_LIBS "${${FFTW_CLN}_LIBRARIES}") set(${FFTW_CLN}_CTS "${FFTW_CLN}") - if(${FFTW_CLNT}_FOUND) + if(${FFTW_CLNT}_FLIBRARIES) + set(${FFTW_CLNT}_FOUND TRUE) list(APPEND FFTW_LIBS "${FFTW_CLNT}") - list(APPEND FFTW_ABS_LIBS "${${FFTW_CLNT}_FOUND}") + list(APPEND FFTW_ABS_LIBS "${${FFTW_CLNT}_LIBRARIES}") list(APPEND ${FFTW_CLN}_CTS "${FFTW_CLNT}") endif() set(CMAKE_REQUIRED_LIBRARIES ${${FFTW_CLN}_CTS}) CHECK_FUNCTION_EXISTS(fftw${FFTW_S_}_make_planner_thread_safe ${FFTW_CLN}_TSFE) add_definitions(-DPIP_FFTW${FFTW_S_}) - set(PIP_FFTW_FOUND true) if(${FFTW_CLN}_TSFE) add_definitions(-DPIP_FFTW${FFTW_S_}_THREADSAFE) else() @@ -550,7 +560,6 @@ if (NOT CROSSTOOLS) endif() list(APPEND LIBS_STATUS OpenCL) list(APPEND PIP_LIBS_TARGETS pip_opencl) - set(OpenCL_FOUND ${OpenCL_LIBRARIES}) endif() @@ -628,6 +637,7 @@ if (NOT CROSSTOOLS) list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge") add_library(pip_lua ${PIP_LIB_TYPE} ${CPP_LIB_LUA} ${_RC}) target_link_libraries(pip_lua pip ${LUA_LIBRARIES}) + list(APPEND LIBS_STATUS LUA) list(APPEND PIP_LIBS_TARGETS pip_lua) endif() @@ -815,8 +825,9 @@ if(NOT PIP_FREERTOS) message("") message(" Using libraries:") foreach(LIB_ ${LIBS_STATUS}) - message(" ${LIB_} -> " ${${LIB_}_FOUND}) - if(NOT ${LIB_}_FOUND) + if(${LIB_}_FOUND) + message(" ${LIB_} -> ${${LIB_}_LIBRARIES}") + else() message(" ${LIB_} not found, may fail") endif() endforeach() From 2ffc45756628f4905f547ea7cc57fbdc0790d822 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 30 Jul 2020 18:50:42 +0300 Subject: [PATCH 16/68] merged concurrent to main library removed PIConditionLock, use PIMutex instead --- CMakeLists.txt | 34 +- cmake/FindPIP.cmake | 7 +- lib/concurrent/piconditionlock.cpp | 95 -- .../test/BlockingDequeueUnitTest.cpp | 8 +- .../test/ConditionLockIntegrationTest.cpp | 6 +- .../test/ConditionVariableIntegrationTest.cpp | 4 +- .../test/ExecutorIntegrationTest.cpp | 4 +- lib/console/piconsole.cpp | 1168 ----------------- lib/main/concurrent/piconditionlock.h | 51 - lib/main/console/piconsole.h | 461 ------- lib/main/console/piconsolemodule.h | 1 - lib/main/containers/pideque.h | 36 + lib/main/containers/pimap.h | 7 + lib/main/containers/pivector.h | 29 + lib/main/core/picout.cpp | 2 +- lib/main/core/piincludes.cpp | 1 - lib/main/core/piincludes.h | 5 +- lib/main/core/pistring.h | 4 + lib/main/core/pistringlist.h | 1 + lib/main/system/picodec.cpp | 45 - lib/main/system/picodec.h | 54 - lib/main/system/pisystemmodule.h | 1 - .../piblockingdequeue.h | 22 +- .../thread}/piconditionvar.cpp | 282 ++-- .../{concurrent => thread}/piconditionvar.h | 27 +- lib/main/thread/pimutex.cpp | 122 ++ lib/main/thread/pimutex.h | 43 +- lib/main/thread/pithreadmodule.h | 2 + .../thread/pithreadpoolexecutor.cpp} | 163 +-- .../pithreadpoolexecutor.h} | 21 +- main.cpp | 28 +- 31 files changed, 558 insertions(+), 2176 deletions(-) delete mode 100644 lib/concurrent/piconditionlock.cpp delete mode 100644 lib/console/piconsole.cpp delete mode 100644 lib/main/concurrent/piconditionlock.h delete mode 100644 lib/main/console/piconsole.h delete mode 100644 lib/main/system/picodec.cpp delete mode 100644 lib/main/system/picodec.h rename lib/main/{concurrent => thread}/piblockingdequeue.h (93%) rename lib/{concurrent => main/thread}/piconditionvar.cpp (87%) rename lib/main/{concurrent => thread}/piconditionvar.h (83%) create mode 100644 lib/main/thread/pimutex.cpp rename lib/{concurrent/executor.cpp => main/thread/pithreadpoolexecutor.cpp} (71%) rename lib/main/{concurrent/executor.h => thread/pithreadpoolexecutor.h} (70%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d731562..5e7e49d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,6 @@ set(PIP_SRC_USB "lib/usb") set(PIP_SRC_FFTW "lib/fftw") set(PIP_SRC_OPENCL "lib/opencl") set(PIP_SRC_IO_UTILS "lib/io_utils") -set(PIP_SRC_CONCURRENT "lib/concurrent") set(PIP_SRC_CLOUD "lib/cloud") set(PIP_SRC_LUA "lib/lua") set(PIP_SRC_DIRS ${PIP_SRC_MAIN} @@ -77,8 +76,8 @@ set(PIP_SRC_DIRS ${PIP_SRC_MAIN} ${PIP_SRC_FFTW} ${PIP_SRC_OPENCL} ${PIP_SRC_IO_UTILS} - ${PIP_SRC_CONCURRENT} - ${PIP_SRC_CLOUD} + ${PIP_SRC_CLOUD} + ${PIP_SRC_LUA} ) set(PIP_LIBS_TARGETS pip) set(LIBS_MAIN) @@ -192,7 +191,7 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) # Sources # Main lib -set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "concurrent" "cloud" "lua") +set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "cloud" "lua") include_directories("${PIP_SRC_MAIN}") set(PIP_MAIN_FOLDERS) foreach(F ${PIP_FOLDERS}) @@ -221,17 +220,17 @@ gather_src("${PIP_SRC_OPENCL}" CPP_LIB_OPENCL HDRS PHDRS) # IO Utils lib gather_src("${PIP_SRC_IO_UTILS}" CPP_LIB_IO_UTILS HDRS PHDRS) -# Concurrent lib -gather_src("${PIP_SRC_CONCURRENT}" CPP_LIB_CONCURRENT HDRS PHDRS) - -gather_src("${PIP_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS) - # Cloud lib gather_src("${PIP_SRC_CLOUD}" CPP_LIB_CLOUD HDRS PHDRS) # LUA lib gather_src("${PIP_SRC_LUA}" CPP_LIB_LUA HDRS PHDRS) +if (TESTS) + # Concurrent lib tests + gather_src("${PIP_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS) +endif() + if(PIP_FREERTOS) add_definitions(-DPIP_FREERTOS) set(ICU OFF) @@ -580,24 +579,10 @@ if (NOT CROSSTOOLS) list(APPEND PIP_LIBS_TARGETS pip_io_utils) - # Concurrent module - set(CONCURRENT_LIBS pip) - import_version(pip_concurrent pip) - set_deploy_property(pip_concurrent ${PIP_LIB_TYPE} - LABEL "PIP concurrent support" - FULLNAME "${_PIP_DOMAIN}.pip_concurrent" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_concurrent _RC) - add_library(pip_concurrent ${PIP_LIB_TYPE} ${CPP_LIB_CONCURRENT} ${_RC}) - target_link_libraries(pip_concurrent ${CONCURRENT_LIBS}) - set_property(TARGET pip_concurrent PROPERTY CXX_STANDARD 11) - list(APPEND PIP_LIBS_TARGETS pip_concurrent) - # Enable build tests for concurrent module if(PIP_CONCURRENT_TEST) add_executable(pip_concurrent_test ${CPP_CONCURRENT_TEST}) - target_link_libraries(pip_concurrent_test gtest_main gmock_main pip_concurrent) + target_link_libraries(pip_concurrent_test pip gtest_main gmock_main) add_test(NAME pip_concurrent_test COMMAND tests) add_custom_target(pip_concurrent_test_perform ALL COMMAND pip_concurrent_test) endif() @@ -813,7 +798,6 @@ message(" Compress : ${PIP_COMPRESS}") message(" FFTW : ${PIP_FFTW}") message(" OpenCL : ${PIP_OPENCL}") message(" IOUtils : ${PIP_IOUTILS}") -message(" Concurrent: yes") message(" Cloud : ${PIP_CLOUD}") message(" Lua : ${PIP_LUA}") message("") diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 48b4b47f..06292c0d 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -9,7 +9,6 @@ Also create imported targets: * PIP::FFTW * PIP::OpenCL * PIP::IOUtils - * PIP::Concurrent * PIP::Cloud * PIP::Lua @@ -67,7 +66,6 @@ find_library(PIP_FFTW_LIBRARY pip_fftw${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_COMPRESS_LIBRARY pip_compress${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_OPENCL_LIBRARY pip_opencl${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_IO_UTILS_LIBRARY pip_io_utils${_pip_suffix} HINTS ${_PIP_LIBDIR}) -find_library(PIP_CONCURRENT_LIBRARY pip_concurrent${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CLOUD_LIBRARY pip_cloud HINTS${_pip_suffix} ${_PIP_LIBDIR}) find_library(PIP_LUA_LIBRARY pip_lua HINTS${_pip_suffix} ${_PIP_LIBDIR}) find_file(PIP_H_INCLUDE "pip.h" HINTS ${_PIP_INCDIR} $ENV{SMSDK_DIR}/include/pip) @@ -134,15 +132,14 @@ if(PIP_FIND_VERSION VERSION_GREATER PIP_VERSION) message(FATAL_ERROR "PIP version ${PIP_VERSION} is available, but ${PIP_FIND_VERSION} requested!") endif() -set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Concurrent;Cloud;Lua") +set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Cloud;Lua") set(__module_USB "${PIP_USB_LIBRARY}" ) set(__module_Console "${PIP_CONSOLE_LIBRARY}" ) set(__module_Crypt "${PIP_CRYPT_LIBRARY}" ) set(__module_FFTW "${PIP_FFTW_LIBRARY}" ) set(__module_Compress "${PIP_COMPRESS_LIBRARY}" ) -set(__module_OpenCL "${PIP_OPENCL_LIBRARY}" ) +set(__module_OpenCL "${PIP_OPENCL_LIBRARY}" ) set(__module_IOUtils "${PIP_IO_UTILS_LIBRARY}" ) -set(__module_Concurrent "${PIP_CONCURRENT_LIBRARY}") set(__module_Cloud "${PIP_CLOUD_LIBRARY}" ) set(__module_Lua "${PIP_LUA_LIBRARY}" ) if((NOT TARGET PIP) AND PIP_LIBRARY) diff --git a/lib/concurrent/piconditionlock.cpp b/lib/concurrent/piconditionlock.cpp deleted file mode 100644 index 35dee0c4..00000000 --- a/lib/concurrent/piconditionlock.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#include "piconditionlock.h" -#ifdef WINDOWS -# include -#else -# include -#endif - - -PRIVATE_DEFINITION_START(PIConditionLock) -#ifdef WINDOWS - CRITICAL_SECTION -#else - pthread_mutex_t -#endif - nativeHandle; -PRIVATE_DEFINITION_END(PIConditionLock) - - -PIConditionLock::PIConditionLock() { -#ifdef WINDOWS - InitializeCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutexattr_t attr; - memset(&attr, 0, sizeof(attr)); - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); - pthread_mutex_init(&(PRIVATE->nativeHandle), &attr); - pthread_mutexattr_destroy(&attr); -#endif -} - - -PIConditionLock::~PIConditionLock() { -#ifdef WINDOWS - DeleteCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutex_destroy(&(PRIVATE->nativeHandle)); -#endif -} - - -void PIConditionLock::lock() { -#ifdef WINDOWS - EnterCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutex_lock(&(PRIVATE->nativeHandle)); -#endif -} - - -void PIConditionLock::unlock() { -#ifdef WINDOWS - LeaveCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutex_unlock(&(PRIVATE->nativeHandle)); -#endif -} - - -void *PIConditionLock::handle() { -#ifdef WINDOWS - return &PRIVATE->nativeHandle; -#else - return &PRIVATE->nativeHandle; -#endif -} - - -bool PIConditionLock::tryLock() { -#ifdef WINDOWS - return TryEnterCriticalSection(&PRIVATE->nativeHandle) != 0; -#else - return (pthread_mutex_trylock(&(PRIVATE->nativeHandle)) == 0); -#endif -} diff --git a/lib/concurrent/test/BlockingDequeueUnitTest.cpp b/lib/concurrent/test/BlockingDequeueUnitTest.cpp index e0d4dd46..fb673059 100644 --- a/lib/concurrent/test/BlockingDequeueUnitTest.cpp +++ b/lib/concurrent/test/BlockingDequeueUnitTest.cpp @@ -8,24 +8,24 @@ public: bool isTrueCondition = false; int timeout = -1; - void wait(PIConditionLock& lk) override { + void wait(PIMutex& lk) override { isWaitCalled = true; } - void wait(PIConditionLock& lk, const std::function& condition) override { + void wait(PIMutex& lk, const std::function& condition) override { isWaitCalled = true; lk.lock(); isTrueCondition = condition(); lk.unlock(); } - bool waitFor(PIConditionLock& lk, int timeoutMs) override { + bool waitFor(PIMutex& lk, int timeoutMs) override { isWaitForCalled = true; timeout = timeoutMs; return false; } - bool waitFor(PIConditionLock& lk, int timeoutMs, const std::function& condition) override { + bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition) override { isWaitForCalled = true; lk.lock(); isTrueCondition = condition(); diff --git a/lib/concurrent/test/ConditionLockIntegrationTest.cpp b/lib/concurrent/test/ConditionLockIntegrationTest.cpp index 8d42a597..13a6c6f6 100644 --- a/lib/concurrent/test/ConditionLockIntegrationTest.cpp +++ b/lib/concurrent/test/ConditionLockIntegrationTest.cpp @@ -2,12 +2,12 @@ #include "gmock/gmock.h" #include "piconditionvar.h" -#include +#include "pithread.h" #include "testutil.h" class ConditionLock : public ::testing::Test, public TestUtil { public: - PIConditionLock* m = new PIConditionLock(); + PIMutex* m = new PIMutex(); }; TEST_F(ConditionLock, lock_is_protect) { @@ -50,4 +50,4 @@ TEST_F(ConditionLock, tryLock_is_true_when_unlocked) { TEST_F(ConditionLock, tryLock_is_recursive_lock_enable) { m->lock(); ASSERT_TRUE(m->tryLock()); -} \ No newline at end of file +} diff --git a/lib/concurrent/test/ConditionVariableIntegrationTest.cpp b/lib/concurrent/test/ConditionVariableIntegrationTest.cpp index 6a2609fa..a9d26cec 100644 --- a/lib/concurrent/test/ConditionVariableIntegrationTest.cpp +++ b/lib/concurrent/test/ConditionVariableIntegrationTest.cpp @@ -5,7 +5,7 @@ class ConditionVariable : public ::testing::Test, public TestUtil { public: - PIConditionLock m; + PIMutex m; PIConditionVariable* variable; protected: @@ -197,4 +197,4 @@ TEST_F(ConditionVariable, waitFor_is_unblock_when_condition_and_notifyOne) { variable->notifyOne(); msleep(WAIT_THREAD_TIME_MS); ASSERT_FALSE(thread->isRunning()); -} \ No newline at end of file +} diff --git a/lib/concurrent/test/ExecutorIntegrationTest.cpp b/lib/concurrent/test/ExecutorIntegrationTest.cpp index 099c5a8e..8e58a48c 100644 --- a/lib/concurrent/test/ExecutorIntegrationTest.cpp +++ b/lib/concurrent/test/ExecutorIntegrationTest.cpp @@ -1,5 +1,5 @@ #include "gtest/gtest.h" -#include "executor.h" +#include "pithreadpoolexecutor.h" #include "pimutex.h" const int WAIT_THREAD_TIME_MS = 30; @@ -51,4 +51,4 @@ TEST(ExcutorIntegrationTest, execute_is_awaitTermination_wait) { double waitTime = measurer.elapsed_m(); ASSERT_GE(waitTime, WAIT_THREAD_TIME_MS); ASSERT_LE(waitTime, 4 * WAIT_THREAD_TIME_MS); -} \ No newline at end of file +} diff --git a/lib/console/piconsole.cpp b/lib/console/piconsole.cpp deleted file mode 100644 index 8202826b..00000000 --- a/lib/console/piconsole.cpp +++ /dev/null @@ -1,1168 +0,0 @@ -/* - PIP - Platform Independent Primitives - Console output/input - 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 . -*/ -#include "piconsole.h" -#include "piincludes_p.h" -#include "pipeer.h" -#include "pidiagnostics.h" -#include "pisystemmonitor.h" -#ifndef WINDOWS -# include -# include -# include -#else -# include -# define COMMON_LVB_UNDERSCORE 0x8000 -#endif - - -/** \class PIConsole - * \brief Console output class - * \details - * \section PIConsole_sec0 Synopsis - * This class provides output to console with automatic alignment and update. - * It supports tabs, keyboard listening, formats and colors. - * - * \section PIConsole_sec1 Layout - * %PIConsole works with variable pointers. You should add your variables with - * functions \a addVariable() which receives label name, pointer to variable - * and optional column and format. Columns count is dynamically increased if - * new column used. E.g. if you add variable to empty tab to column 3, columns - * count will be increased to 3, but two firsts columns will be empty. Each column - * filled from top to bottom, but you can add just string with function - * \a addString() or add empty line with function \a addEmptyLine(). Layout scheme: - * \image html piconsole_layout.png - * - * \section PIConsole_sec2 Keyboard usage - * %PIConsole should to be single in application. %PIConsole aggregate PIKbdListener - * which grab keyboard and automatic switch tabs by theirs bind keys. If there is no - * tab binded to pressed key external function "slot" will be called - * - **/ - - -PRIVATE_DEFINITION_START(PIConsole) -#ifdef WINDOWS -void getWinCurCoord() {GetConsoleScreenBufferInfo(hOut, &csbi); ccoord = csbi.dwCursorPosition;} -COORD & getWinCoord(int dx = 0, int dy = 0) {getWinCurCoord(); ccoord.X += dx; ccoord.Y += dy; return ccoord;} -void * hOut; -CONSOLE_SCREEN_BUFFER_INFO sbi, csbi; -CONSOLE_CURSOR_INFO curinfo; -COORD ccoord, ulcoord; -WORD dattr; -DWORD smode, written; -#endif -PRIVATE_DEFINITION_END(PIConsole) - - -PIConsole::PIConsole(bool startNow, PIKbdListener::KBFunc slot): PIThread() { - setName("console"); - setPriority(piLow); - needLockRun(true); - ret_func = slot; - num_format = systime_format = 0; - vid = 0; - cur_tab = width = height = pwidth = pheight = max_y = 0; - def_align = Nothing; - tabs.reserve(16); -#ifdef WINDOWS - PRIVATE->ulcoord.X = 0; - PRIVATE->hOut = GetStdHandle(STD_OUTPUT_HANDLE); - GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); - PRIVATE->dattr = PRIVATE->sbi.wAttributes; - width = PRIVATE->sbi.srWindow.Right - PRIVATE->sbi.srWindow.Left; - height = PRIVATE->sbi.srWindow.Bottom - PRIVATE->sbi.srWindow.Top; - PRIVATE->ulcoord.Y = PRIVATE->sbi.srWindow.Top; - GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode); - GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); -#else -# ifdef FREERTOS - width = 80; - height = 24; -# else - winsize ws; - ioctl(0, TIOCGWINSZ, &ws); - width = ws.ws_col; - height = ws.ws_row; -# endif -#endif - addTab("main"); - listener = new PIKbdListener(key_event, this); - peer_timer = new PITimer(); - peer_timer->setName("__S__.PIConsole.peer_timer"); - peer = 0; - server_mode = pause_ = false; - state = Disconnected; - peer_timer->addDelimiter(20); - peer_timer->setName("__S__PIConsole::peer_timer"); - CONNECT2(void, void * , int, peer_timer, tickEvent, this, peerTimer); - if (startNow) start(); -} - - -PIConsole::~PIConsole() { - stopPeer(); - if (isRunning()) - stop(); - clearTabs(false); - delete listener; - delete peer_timer; -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); - SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); -#endif -} - - -int PIConsole::addTab(const PIString & name, char bind_key) { - if (isRunning()) lock(); - tabs.push_back(Tab(name, bind_key)); - cur_tab = tabs.size() - 1; - if (isRunning()) unlock(); - return tabs.size(); -} - - -void PIConsole::removeTab(uint index) { - if (index >= tabs.size()) return; - if (isRunning()) lock(); - tabs.remove(index); - if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1; - if (isRunning()) unlock(); -} - - -void PIConsole::removeTab(const PIString & name) { - uint index = tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - removeTab(index); -} - - -void PIConsole::clearTab(uint index) { - if (index >= tabs.size()) return; - lock(); - tabs[index].columns.clear(); - if (cur_tab == index) { - clearScreen(); - fillLabels(); - } - if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1; - unlock(); -} - - -void PIConsole::clearTab(const PIString & name) { - uint index = tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - clearTab(index); -} - - -void PIConsole::update() { - lock(); - fillLabels(); - unlock(); -} - - -bool PIConsole::setTab(uint index) { - if (index >= tabs.size()) - return false; - if (!isRunning()) { - cur_tab = index; - return true; - } - lock(); - PICout::__mutex__().lock(); - cur_tab = index; - clearScreen(); - fillLabels(); - PICout::__mutex__().unlock(); - unlock(); - return true; -} - - -bool PIConsole::setTab(const PIString & name) { - uint index = tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - return setTab(index); -} - - -bool PIConsole::setTabBindKey(uint index, char bind_key) { - if (index >= tabs.size()) - return false; - tabs[index].key = bind_key; - return true; -} - - -bool PIConsole::setTabBindKey(const PIString & name, char bind_key) { - uint index =tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - return setTabBindKey(index, bind_key); -} - - -void PIConsole::key_event(PIKbdListener::KeyEvent key, void * t) { - PIConsole * p = (PIConsole * )t; - int ct = p->cur_tab; - if (key.key == PIKbdListener::LeftArrow) { - do { - ct--; - if (ct < 0) return; - } while (p->tabs[ct].key == 0); - p->setTab(ct); - return; - } - if (key.key == PIKbdListener::RightArrow) { - do { - ct++; - if (ct >= p->tabs.size_s()) return; - } while (p->tabs[ct].key == 0); - p->setTab(ct); - return; - } - for (uint i = 0; i < p->tabsCount(); ++i) { - if (p->tabs[i].key == key.key) { - p->setTab(i); - return; - } - } - if (p->ret_func != 0) p->ret_func(key, t); - p->keyPressed(key, t); -} - - -int PIConsole::couts(const PIString & v) { - return printf("%s", v.data()); -} - - -int PIConsole::couts(const char * v) { - return printf("%s", v); -} - - -void PIConsole::clearVariables(bool clearScreen) { - if (isRunning()) lock(); - if (clearScreen && isRunning()) { - toUpperLeft(); - clearScreenLower(); - } - columns().clear(); - if (isRunning()) unlock(); -} - - -void PIConsole::stop(bool clear) { - PIThread::stop(true); - if (clear) clearScreen(); - moveTo(0, max_y + 4); - showCursor(); - couts(fstr(Normal)); -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); - SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); -#endif - fflush(0); -} - - -PIString PIConsole::fstr(FormatFlags f) { - num_format = systime_format = 0; - if (f[PIConsole::Dec]) num_format = 0; - if (f[PIConsole::Hex]) num_format = 1; - if (f[PIConsole::Oct]) num_format = 2; - if (f[PIConsole::Bin]) num_format = 4; - if (f[PIConsole::Scientific]) num_format = 3; - if (f[PIConsole::SystemTimeSplit]) systime_format = 0; - if (f[PIConsole::SystemTimeSeconds]) systime_format = 1; - -#ifdef WINDOWS - WORD attr = 0; - - if (f[PIConsole::Inverse]) { - if (f[PIConsole::Red]) attr |= BACKGROUND_RED; - if (f[PIConsole::Green]) attr |= BACKGROUND_GREEN; - if (f[PIConsole::Blue]) attr |= BACKGROUND_BLUE; - if (f[PIConsole::Yellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN); - if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE); - if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE); - if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if (f[PIConsole::BackRed]) attr |= FOREGROUND_RED; - if (f[PIConsole::BackGreen]) attr |= FOREGROUND_GREEN; - if (f[PIConsole::BackBlue]) attr |= FOREGROUND_BLUE; - if (f[PIConsole::BackYellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN); - if (f[PIConsole::BackMagenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE); - if (f[PIConsole::BackCyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE); - if (f[PIConsole::BackWhite]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if ((attr & BACKGROUND_RED) + (attr & BACKGROUND_GREEN) + (attr & BACKGROUND_BLUE) == 0) - attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - } else { - if (f[PIConsole::Red]) attr |= FOREGROUND_RED; - if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN; - if (f[PIConsole::Blue]) attr |= FOREGROUND_BLUE; - if (f[PIConsole::Yellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN); - if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE); - if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE); - if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if (f[PIConsole::BackRed]) attr |= BACKGROUND_RED; - if (f[PIConsole::BackGreen]) attr |= BACKGROUND_GREEN; - if (f[PIConsole::BackBlue]) attr |= BACKGROUND_BLUE; - if (f[PIConsole::BackYellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN); - if (f[PIConsole::BackMagenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE); - if (f[PIConsole::BackCyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE); - if (f[PIConsole::BackWhite]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if ((attr & FOREGROUND_RED) + (attr & FOREGROUND_GREEN) + (attr & FOREGROUND_BLUE) == 0) - attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - } - if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY; - if (f[PIConsole::Underline]) attr |= COMMON_LVB_UNDERSCORE; - - SetConsoleTextAttribute(PRIVATE->hOut, attr); - return PIString(); -#else - PIString ts("\e[0"); - - if (f[PIConsole::Bold]) ts += ";1"; - if (f[PIConsole::Faint]) ts += ";2"; - if (f[PIConsole::Italic]) ts += ";3"; - if (f[PIConsole::Underline]) ts += ";4"; - if (f[PIConsole::Blink]) ts += ";5"; - if (f[PIConsole::Inverse]) ts += ";7"; - - if (f[PIConsole::Black]) ts += ";30"; - if (f[PIConsole::Red]) ts += ";31"; - if (f[PIConsole::Green]) ts += ";32"; - if (f[PIConsole::Yellow]) ts += ";33"; - if (f[PIConsole::Blue]) ts += ";34"; - if (f[PIConsole::Magenta]) ts += ";35"; - if (f[PIConsole::Cyan]) ts += ";36"; - if (f[PIConsole::White]) ts += ";37"; - - if (f[PIConsole::BackBlack]) ts += ";40"; - if (f[PIConsole::BackRed]) ts += ";41"; - if (f[PIConsole::BackGreen]) ts += ";42"; - if (f[PIConsole::BackYellow]) ts += ";43"; - if (f[PIConsole::BackBlue]) ts += ";44"; - if (f[PIConsole::BackMagenta]) ts += ";45"; - if (f[PIConsole::BackCyan]) ts += ";46"; - if (f[PIConsole::BackWhite]) ts += ";47"; - - return ts + "m"; -#endif -} - - -inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));} -inline int PIConsole::couts(const char v) {return printf("%c", v);} -inline int PIConsole::couts(const short v) { - switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hd", v); break;} -} -inline int PIConsole::couts(const int v) { - switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%d", v); break;} -} -inline int PIConsole::couts(const long v) { - switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%ld", v); break;} -} -inline int PIConsole::couts(const llong v) { - switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lld", v); break;} -} -inline int PIConsole::couts(const uchar v) { - switch (num_format) {case (1): return printf("0x%.2X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 1)); break; default: return printf("%u", v); break;} -} -inline int PIConsole::couts(const ushort v) { - switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hu", v); break;} -} -inline int PIConsole::couts(const uint v) { - switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%u", v); break;} -} -inline int PIConsole::couts(const ulong v) { - switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lu", v); break;} -} -inline int PIConsole::couts(const ullong v) { - switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%llu", v); break;} -} -inline int PIConsole::couts(const float v) { - switch (num_format) {case (3): return printf("%e", v); break; default: return printf("%.5g", v); break;} -} -inline int PIConsole::couts(const double v) { - switch (num_format) {case (3): return printf("%le", v); break; default: return printf("%.5lg", v); break;} -} -inline int PIConsole::couts(const PISystemTime & v) { - switch (systime_format) {case (1): return printf("%.6lg", v.toSeconds()); break; - default: return couts(v.seconds) + printf(" s, ") + couts(v.nanoseconds) + printf(" ns"); break;} -} - - -void PIConsole::toUpperLeft() { -#ifdef WINDOWS - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ulcoord); -#else - printf("\e[H"); -#endif -} - -void PIConsole::moveRight(int n) { -#ifdef WINDOWS - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->getWinCoord(n)); -#else - if (n > 0) printf("\e[%dC", n); -#endif -} - -void PIConsole::moveLeft(int n) { -#ifdef WINDOWS - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->getWinCoord(-n)); -#else - if (n > 0) printf("\e[%dD", n); -#endif -} - -void PIConsole::moveTo(int x, int y) { -#ifdef WINDOWS - PRIVATE->ccoord.X = x; - PRIVATE->ccoord.Y = PRIVATE->ulcoord.Y + y; - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord); -#else - printf("\e[%d;%dH", y, x); -#endif -} - -void PIConsole::clearScreen() { -#ifdef WINDOWS - couts(fstr(Normal)); - toUpperLeft(); - FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written); - FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written); -#else - couts(fstr(Normal)); printf("\e[H\e[J"); -#endif -} - -void PIConsole::clearScreenLower() { -#ifdef WINDOWS - couts(fstr(Normal)); - PRIVATE->getWinCurCoord(); - FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); - FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); -#else - couts(fstr(Normal)); printf("\e[J"); -#endif -} - -void PIConsole::clearLine() { -#ifdef WINDOWS - PRIVATE->getWinCurCoord(); - FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width - PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); - FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width - PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); -#else - printf("\e[K"); -#endif -} - -void PIConsole::newLine() { -#ifdef WINDOWS - PRIVATE->getWinCurCoord(); - PRIVATE->ccoord.X = 0; PRIVATE->ccoord.Y++; - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord); -#else - printf("\eE"); -#endif -} - -void PIConsole::hideCursor() { -#ifdef WINDOWS - PRIVATE->curinfo.bVisible = false; - SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); -#else - printf("\e[?25l"); -#endif -} - -void PIConsole::showCursor() { -#ifdef WINDOWS - PRIVATE->curinfo.bVisible = true; SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); -#else - printf("\e[?25h"); -#endif -} - - -void PIConsole::begin() { -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT); -#endif - max_y = 0; - PICout::__mutex__().lock(); - clearScreen(); - hideCursor(); - fillLabels(); - PICout::__mutex__().unlock(); -} - - -void PIConsole::run() { - if (pause_) return; - uint cx, clen = 0; - int j; -#ifdef WINDOWS - GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); - width = PRIVATE->sbi.srWindow.Right - PRIVATE->sbi.srWindow.Left; - height = PRIVATE->sbi.srWindow.Bottom - PRIVATE->sbi.srWindow.Top; -#else -# ifdef FREERTOS - width = 80; - height = 24; -# else - winsize ws; - ioctl(0, TIOCGWINSZ, &ws); - width = ws.ws_col; - height = ws.ws_row; -# endif -#endif - //fflush(0); return; - PICout::__mutex__().lock(); - if (pwidth != width || pheight != height) { - clearScreen(); - fillLabels(); - } - pwidth = width; - pheight = height; - col_cnt = columns().size(); - col_wid = (col_cnt > 0) ? width / col_cnt : width; - for (uint i = 0; i < col_cnt; ++i) { - PIVector & cvars(tabs[cur_tab].columns[i].variables); - cx = col_wid * i; - toUpperLeft(); - if (max_y < cvars.size()) max_y = cvars.size(); - j = 0; - piForeachC (Variable & tv_, cvars) { - if (j > height - 3) continue; - j++; - moveRight(cx); - if (tv_.type == 15) { - newLine(); - continue; - } - moveRight(tv_.offset); - const void * ptr = 0; - if (tv_.remote) { - if (tv_.type == 0) { - rstr.clear(); - rba = tv_.rdata; - rba >> rstr; - rstr.trim(); - ptr = &rstr; - } else - ptr = tv_.rdata.data(); - } else - ptr = tv_.ptr; - switch (tv_.type) { - case 0: clen = printValue(ptr != 0 ? *(const PIString*)ptr : PIString(), tv_.format); break; - case 1: clen = printValue(ptr != 0 ? *(const bool*)ptr : false, tv_.format); break; - case 2: clen = printValue(ptr != 0 ? *(const int*)ptr : 0, tv_.format); break; - case 3: clen = printValue(ptr != 0 ? *(const long*)ptr : 0l, tv_.format); break; - case 4: clen = printValue(ptr != 0 ? *(const char*)ptr : char(0), tv_.format); break; - case 5: clen = printValue(ptr != 0 ? *(const float*)ptr : 0.f, tv_.format); break; - case 6: clen = printValue(ptr != 0 ? *(const double*)ptr : 0., tv_.format); break; - case 7: clen = printValue(ptr != 0 ? *(const short*)ptr : short(0), tv_.format); break; - case 8: clen = printValue(ptr != 0 ? *(const uint*)ptr : 0u, tv_.format); break; - case 9: clen = printValue(ptr != 0 ? *(const ulong*)ptr : 0ul, tv_.format); break; - case 10: clen = printValue(ptr != 0 ? *(const ushort*)ptr : ushort(0), tv_.format); break; - case 11: clen = printValue(ptr != 0 ? *(const uchar*)ptr : uchar(0), tv_.format); break; - case 12: clen = printValue(ptr != 0 ? *(const llong*)ptr : 0l, tv_.format); break; - case 13: clen = printValue(ptr != 0 ? *(const ullong*)ptr: 0ull, tv_.format); break; - case 20: clen = printValue(ptr != 0 ? *(const PISystemTime*)ptr: PISystemTime(), tv_.format); break; - case 14: clen = printValue(bitsValue(ptr, tv_.bitFrom, tv_.bitCount), tv_.format); break; - } - if (clen + tv_.offset < (uint)col_wid) { - PIString ts = PIString( - #if defined(QNX) || defined(FREE_BSD) - col_wid - clen - tv_.offset - 1, ' '); -#else - col_wid - clen - tv_.offset, ' '); -#endif - printf("%s", ts.data()); - } - newLine(); - } - } -#ifdef WINDOWS - moveTo(0, max_y + 1); -#else - moveTo(0, max_y + 2); -#endif - fflush(0); - PICout::__mutex__().unlock(); -} - - -void PIConsole::fillLabels() { - if (!isRunning()) return; - uint cx, cy, mx = 0, dx; -#ifdef WINDOWS - GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); - width = PRIVATE->sbi.srWindow.Right - PRIVATE->sbi.srWindow.Left; - height = PRIVATE->sbi.srWindow.Bottom - PRIVATE->sbi.srWindow.Top; -#else -# ifdef FREERTOS - width = 80; - height = 24; -# else - winsize ws; - ioctl(0, TIOCGWINSZ, &ws); - width = ws.ws_col; - height = ws.ws_row; -# endif -#endif - max_y = 0; - col_cnt = columns().size(); - col_wid = (col_cnt > 0) ? width / col_cnt : width; - for (uint i = 0; i < col_cnt; ++i) { - Column & ccol(tabs[cur_tab].columns[i]); - PIVector & cvars(ccol.variables); - if (ccol.alignment != Nothing) { - mx = 0; - piForeachC (Variable & j, cvars) - if (!j.isEmpty()) - if (mx < j.name.size()) - mx = j.name.size(); - mx += 2; - } - cx = col_wid * i; - cy = 1; - toUpperLeft(); - for (uint j = 0; j < cvars.size(); ++j) { - if (int(j) > height - 3) continue; - if (max_y < j) max_y = j; - moveRight(cx); - Variable & tv_(cvars[j]); - cvars[j].nx = cx; - cvars[j].ny = cy; - if (tv_.name.isEmpty()) { - cvars[j].offset = 0; - clearLine(); - newLine(); - cy++; - continue; - } - clearLine(); - //piCout << tv_.name << tv_.type << tv_.ptr; - if (tv_.type == 15) { - cvars[j].offset = cvars[j].name.length(); - cvars[j].nx += cvars[j].offset; - printLine(tv_.name, cx, tv_.format); - newLine(); - cy++; - continue; - } - if (!tv_.isEmpty()) { - switch (ccol.alignment) { - case Nothing: - cvars[j].offset = (tv_.name + ": ").length(); - cvars[j].nx += cvars[j].offset; - printValue(tv_.name + ": ", tv_.format); - break; - case Left: - cvars[j].offset = mx; - cvars[j].nx += cvars[j].offset; - printValue(tv_.name + ": ", tv_.format); - break; - case Right: - cvars[j].offset = mx; - cvars[j].nx += cvars[j].offset; - dx = mx - (tv_.name + ": ").length(); - moveRight(dx); - printValue(tv_.name + ": ", tv_.format); - moveLeft(dx); - break; - } - } - newLine(); - cy++; - } - } -#ifdef WINDOWS - moveTo(0, max_y + 1); -#else - moveTo(0, max_y + 2); -#endif - if (!tabs[cur_tab].status.isEmpty()) { - printValue(tabs[cur_tab].status); - newLine(); - } - status(); -} - - -void PIConsole::status() { - Tab * ctab; - for (uint i = 0; i < tabsCount(); ++i) { - ctab = &tabs[i]; - if (ctab->key == 0) continue; - printValue(ctab->key, PIConsole::White | PIConsole::Bold); - if (i == cur_tab) - printValue(ctab->name + " ", PIConsole::BackYellow | PIConsole::Black); - else - printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse); - printValue(" "); - } - newLine(); -} - - -int PIConsole::bitsValue(const void * src, int offset, int count) const { - int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8; - char cbyte = reinterpret_cast(src)[stbyte]; - for (int i = 0; i < count; i++) { - ret |= ((cbyte >> cbit & 1) << i); - cbit++; - if (cbit == 8) { - cbit = 0; - stbyte++; - cbyte = reinterpret_cast(src)[stbyte]; - } - } - return ret; -} - - -const char * PIConsole::toBin(const void * d, int s) { - binstr.clear(); - uchar cc, b; - for (int i = 0; i < s; ++i) { - cc = ((const uchar *)d)[i]; - b = 1; - for (int j = 0; j < 8; ++j) { - binstr << (cc & b ? "1" : "0"); - b <<= 1; - } - if (i < s - 1) binstr << " "; - } - binstr.reverse(); - return binstr.data(); -} - - -#define ADD_VAR_BODY vid++; tv.id = vid; tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; tv.remote = false; checkColumn(col); - -void PIConsole::addString(const PIString & name, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 15; tv.size = 0; tv.ptr = 0; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const PIString * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 0; tv.size = 0; tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const bool * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 1; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const int * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 2; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const long * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 3; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const char * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 4; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const float * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 5; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const double * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 6; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const short * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 7; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const uint * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 8; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const ulong * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 9; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const ushort * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 10; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const uchar * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 11; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const llong * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 12; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 13; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const PISystemTime * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 20; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - * \details This function add to column "column" next lines: - * * " diagnostics" - * * "Received count": \a PIDiagnostics::receiveCount - * * "Invalid count": \a PIDiagnostics::wrongCount - * * "Sended count": \a PIDiagnostics::sendCount - * * "Immediate Frequency, Hz": \a PIDiagnostics::immediateFrequency - * * "Integral Frequency, Hz": \a PIDiagnostics::integralFrequency - * * "Receive speed": \a PIDiagnostics::receiveSpeed - * * "Send speed": \a PIDiagnostics::sendSpeed - * * "Quality": \a PIDiagnostics::quality - * */ -void PIConsole::addVariable(const PIString & name, const PIDiagnostics * ptr, int col, FormatFlags format) { - addString(name + " diagnostics", col, format | PIConsole::Bold); -// addVariable("Received count", ptr->receiveCount_ptr(), col, format); -// addVariable("Invalid count", ptr->wrongCount_ptr(), col, format); -// addVariable("Sended count", ptr->sendCount_ptr(), col, format); -// addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format); -// addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format); -// addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format); -// addVariable("Send speed", ptr->sendSpeed_ptr(), col, format); -// addVariable("Quality", ptr->quality_ptr(), col, format); -} -void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr, int col, FormatFlags format) { - addString("monitor " + name, col, format | PIConsole::Bold); - //addVariable("PID", &(ptr->statistic().ID), col, format); - //addVariable("state", &(ptr->statistic().state), col, format); - //addVariable("threads", &(ptr->statistic().threads), col, format); - //addVariable("priority", &(ptr->statistic().priority), col, format); - //addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format); - //addVariable("memory shared", &(ptr->statistic().share_memsize_readable), col, format); - //addVariable("cpu load kernel", &(ptr->statistic().cpu_load_system), col, format); - //addVariable("cpu load user", &(ptr->statistic().cpu_load_user), col, format); -} -void PIConsole::addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int col, FormatFlags format) { - vid++; tv.id = vid; tv.size = sizeof(ullong); tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format; - checkColumn(col); column(col).push_back(tv);} -void PIConsole::addEmptyLine(int col, uint count) { - tv.id = 0; tv.size = 0; tv.name = ""; tv.type = 0; tv.ptr = 0; tv.format = Normal; - for (uint i = 0; i < count; ++i) { - checkColumn(col); - column(col).push_back(tv); - } -} - - -PIString PIConsole::getString(int x, int y) { - bool run = isRunning(); - if (run) PIThread::stop(true); - listener->setActive(false); - msleep(50); -#ifdef WINDOWS - moveTo(x - 1, y - 1); -#else - moveTo(x, y); -#endif - showCursor(); - PIByteArray ba(4096); -#ifdef CC_VC - int ret = scanf_s(" %s", ba.data()); -#else - int ret = scanf(" %s", ba.data()); -#endif - listener->setActive(true); - if (run) start(); - if (ret >= 1) return PIString(ba); - else return PIString(); -} - - -PIString PIConsole::getString(const PIString & name) { - piForeachC (Column & i, tabs[cur_tab].columns) - piForeachC (Variable & j, i.variables) - if (j.name == name) - return getString(j.nx + 1, j.ny); - return PIString(); -} - - -#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); couts(fstr(PIConsole::Dec)); return ret; - -inline void PIConsole::printLine(const PIString & value, int dx, FormatFlags format) { - int i = width - value.length() - dx; -#if defined(QNX) || defined(FREE_BSD) - --i; -#endif - PIString ts = fstr(format); - couts(ts); - if (i >= 0) ts = value + PIString(i, ' '); - else ts = value.left(value.size() + i); - couts(ts); - couts(fstr(Dec)); -} -inline int PIConsole::printValue(const PIString & value, FormatFlags format) { - couts(fstr(format)); - int ret = couts(value); - fstr(PIConsole::Dec); - return ret; -} -inline int PIConsole::printValue(const char * value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const bool value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const int value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const long value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const llong value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const float value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const double value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const char value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const short value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const uchar value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const ushort value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const uint value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const ulong value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const ullong value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const PISystemTime & value, FormatFlags format) {PRINT_VAR_BODY} - - - -void PIConsole::startServer(const PIString & name) { - stopPeer(); - server_mode = true; - peer = new PIPeer("_rcs_:" + name); - CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived); - CONNECT1(void, const PIString & , peer, peerDisconnectedEvent, this, peerDisconnectedEvent); - peer_timer->start(50.); - serverSendInfo(); -} - - -void PIConsole::stopPeer() { - remote_clients.clear(); - peer_timer->stop(); - if (peer != 0) delete peer; - peer = 0; - state = Disconnected; -} - - -PIStringList PIConsole::clients() const { - PIStringList sl; - if (peer == 0) return sl; - piForeachC (PIPeer::PeerInfo & i, peer->allPeers()) { - if (i.name.left(6) != "_rcc_:") continue; - sl << i.name.right(i.name.length() - 6); - } - return sl; -} - - -void PIConsole::listenServers() { - stopPeer(); - server_mode = false; - server_name.clear(); - randomize(); - peer = new PIPeer("_rcc_:" + PIDateTime::current().toString("hhmmssddMMyy_") + PIString::fromNumber(randomi())); - CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived); - peer_timer->start(100.); -} - - -PIStringList PIConsole::availableServers() const { - PIStringList sl; - if (peer == 0) return sl; - piForeachC (PIPeer::PeerInfo & i, peer->allPeers()) { - if (i.name.left(6) != "_rcs_:") continue; - sl << i.name.right(i.name.length() - 6); - } - return sl; -} - - -void PIConsole::connectToServer(const PIString & name) { - if (peer == 0) listenServers(); - server_name = name; -} - - -void PIConsole::disconnect() { - stopPeer(); -} - - -void PIConsole::serverSendInfo() { - if (peer == 0) return; - PIByteArray ba; - ba << int(0xAA); - peer->sendToAll(ba); -} - - -void PIConsole::serverSendData() { - if (peer == 0) return; - PIByteArray ba; - PIVector content; - piForeach (Tab & t, tabs) - piForeach (Column & c, t.columns) - piForeach (Variable & v, c.variables) - if (!v.isEmpty() && v.id > 0) { - VariableContent vc; - vc.id = v.id; - v.writeData(vc.rdata); - content << vc; - } - piForeach (RemoteClient & rc, remote_clients) { - ba.clear(); - switch (rc.state) { - case FetchingData: - ba << int(0xCC) << tabs; - //piCout << "server send const data" << rc.name << ba.size_s(); - break; - case Committing: - ba << int(0xDD); - break; - case Connected: - ba << int(0xEE) << content; - //piCout << "send data" << ba.size(); - break; - default: break; - } - if (!ba.isEmpty()) - peer->send(rc.name, ba); - } -} - - -PIConsole::RemoteClient & PIConsole::remoteClient(const PIString & fname) { - piForeach (RemoteClient & i, remote_clients) - if (i.name == fname) - return i; - remote_clients << RemoteClient(fname); - return remote_clients.back(); -} - - -void PIConsole::peerReceived(const PIString & from, const PIByteArray & data) { - int type; - PIByteArray ba(data); - ba >> type; - //piCout << "rec packet from" << from << "type" << PICoutManipulators::Hex << type; - if (server_mode) { - if (from.left(5) != "_rcc_") return; - //PIString rcn = from.right(from.length() - 6); - RemoteClient & rc(remoteClient(from)); - switch (type) { - case 0xBB: // fetch const data request - //piCout << "fetch data request from" << from << rc.state; - if (rc.state != Connected) - rc.state = FetchingData; - break; - case 0xCC: // const data commit - //piCout << "commit from" << from; - if (rc.state != Connected) - rc.state = Connected; - break; - default: break; - } - } else { - PIVector content; - PIMap vids; - if (from.left(5) != "_rcs_") return; - //PIString rcn = from.right(from.length() - 6); - switch (type) { - case 0xAA: // new server - //piCout << "new server" << rcn; - break; - case 0xCC: // const data - //piCout << "received const data"; - state = Committing; - ba >> tabs; - cur_tab = tabs.isEmpty() ? -1 : 0; - piForeach (Tab & t, tabs) - piForeach (Column & c, t.columns) - piForeach (Variable & v, c.variables) - v.remote = true; - break; - case 0xDD: // const data commit - //piCout << "received commit"; - state = Connected; - break; - case 0xEE: // dynamic data - //piCout << "received data" << ba.size_s(); - piForeach (Tab & t, tabs) - piForeach (Column & c, t.columns) - piForeach (Variable & v, c.variables) - if (!v.isEmpty() && v.id > 0) - vids[v.id] = &v; - ba >> content; - piForeach (VariableContent & vc, content) { - if (vc.id <= 0) continue; - Variable * v = vids.at(vc.id); - if (v == 0) continue; - //piCout << "read" << v->name << vc.rdata.size_s(); - v->rdata = vc.rdata; - } - break; - default: break; - } - } -} - - -void PIConsole::peerTimer(void * data, int delim) { - if (peer == 0) return; - //piCout << "timer" << delim; - if (server_mode) { - if (delim == 20) - serverSendInfo(); - else - serverSendData(); - } else { - if (delim != 1 || server_name.isEmpty()) return; - const PIPeer::PeerInfo * p = peer->getPeerByName("_rcs_:" + server_name); - if (p == 0) return; - PIByteArray ba; - switch (state) { - case Disconnected: - peer_tm.reset(); - ba << int(0xBB); - //piCout << "send to" << server_name << "fetch request disc"; - peer->send(p, ba); - state = FetchingData; - break; - case FetchingData: - if (peer_tm.elapsed_s() < 3.) - return; - peer_tm.reset(); - ba << int(0xBB); - //piCout << "send to" << server_name << "fetch request fd"; - peer->send(p, ba); - break; - case Committing: - peer_tm.reset(); - ba << int(0xCC); - //piCout << "send to" << server_name << "committing"; - state = Connected; - peer->send(p, ba); - break; - default: break; - }; - } -} - - -void PIConsole::peerDisconnectedEvent(const PIString & name) { - for (int i = 0; i < remote_clients.size_s(); ++i) - if (remote_clients[i].name == name) { - remote_clients.remove(i); - --i; - } -} diff --git a/lib/main/concurrent/piconditionlock.h b/lib/main/concurrent/piconditionlock.h deleted file mode 100644 index eba7a8a3..00000000 --- a/lib/main/concurrent/piconditionlock.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#ifndef PICONDITIONLOCK_H -#define PICONDITIONLOCK_H - -#include "pibase.h" - - -/** - * @brief Continued - */ -class PIP_EXPORT PIConditionLock { -public: - NO_COPY_CLASS(PIConditionLock) - explicit PIConditionLock(); - ~PIConditionLock(); - - //! \brief lock - void lock(); - - //! \brief unlock - void unlock(); - - //! \brief tryLock - bool tryLock(); - - void * handle(); - -private: - PRIVATE_DECLARATION -}; - - -#endif // PICONDITIONLOCK_H diff --git a/lib/main/console/piconsole.h b/lib/main/console/piconsole.h deleted file mode 100644 index 5e843d1d..00000000 --- a/lib/main/console/piconsole.h +++ /dev/null @@ -1,461 +0,0 @@ -/*! \file piconsole.h - * \brief Console output class -*/ -/* - PIP - Platform Independent Primitives - Console output/input - 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 . -*/ - -#ifndef PICONSOLE_H -#define PICONSOLE_H - -#include "pikbdlistener.h" - -class PIProtocol; -class PIDiagnostics; -class PISystemMonitor; -class PIPeer; -class PITimer; - -class PIP_EXPORT PIConsole: public PIThread -{ - PIOBJECT_SUBCLASS(PIConsole, PIThread) -public: - - //! Constructs %PIConsole with key handler "slot" and if "startNow" start it - explicit PIConsole(bool startNow = true, PIKbdListener::KBFunc slot = 0); - - ~PIConsole(); - - - //! Variables output format - enum Format { - Normal /** Default console format */ = 0x01, - Bold /** Bold text */ = 0x02, - Faint = 0x04, - Italic = 0x08, - Underline /** Underlined text */ = 0x10, - Blink /** Blinked text */ = 0x20, - Inverse /** Swap text and background colors */ = 0x40, - Black /** Black text */ = 0x100, - Red /** Red text */ = 0x200, - Green /** Green text */ = 0x400, - Yellow /** Yellow text */ = 0x800, - Blue /** Blue text */ = 0x1000, - Magenta /** Magenta text */ = 0x2000, - Cyan /** Cyan text */ = 0x4000, - White /** White text */ = 0x8000, - BackBlack /** Black background */ = 0x10000, - BackRed /** Red background */ = 0x20000, - BackGreen /** Green background */ = 0x40000, - BackYellow /** Yellow background */ = 0x80000, - BackBlue /** Blue background */ = 0x100000, - BackMagenta /** Magenta background */ = 0x200000, - BackCyan /** Cyan background */ = 0x400000, - BackWhite /** White background */ = 0x800000, - Dec /** Decimal base for integers */ = 0x1000000, - Hex /** Hexadecimal base for integers */ = 0x2000000, - Oct /** Octal base for integers */ = 0x4000000, - Bin /** Binary base for integers */ = 0x8000000, - Scientific /** Scientific representation of floats */ = 0x10000000, - SystemTimeSplit /** PISystemTime split representation (* s, * ns) */ = 0x20000000, - SystemTimeSeconds /** PISystemTime seconds representation (*.* s) */ = 0x40000000 - }; - - //! Column labels alignment - enum Alignment { - Nothing /** No alignment */ , - Left /** Labels align left and variables align left */ , - Right /** Labels align right and variables align left */ - }; - - typedef PIFlags FormatFlags; - - //! Add to current tab to column "column" string "name" with format "format" - void addString(const PIString & name, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const PIString * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const char * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const bool * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const short * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const int * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const long * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const llong * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const uchar * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const ushort * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const uint * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const ulong * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const ullong * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const float * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const double * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const PISystemTime * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" bits field with label "name", pointer "ptr" and format "format" - void addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitsCount, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" "count" empty lines - void addEmptyLine(int column = 1, uint count = 1); - - PIString getString(int x, int y); - short getShort(int x, int y) {return getString(x, y).toShort();} - int getInt(int x, int y) {return getString(x, y).toInt();} - float getFloat(int x, int y) {return getString(x, y).toFloat();} - double getDouble(int x, int y) {return getString(x, y).toDouble();} - PIString getString(const PIString & name); - short getShort(const PIString & name) {return getString(name).toShort();} - int getInt(const PIString & name) {return getString(name).toInt();} - float getFloat(const PIString & name) {return getString(name).toFloat();} - double getDouble(const PIString & name) {return getString(name).toDouble();} - - - //! Returns tabs count - uint tabsCount() const {return tabs.size();} - - //! Returns current tab name - PIString currentTab() const {return tabs[cur_tab].name;} - - //! Returns current tab index - int currentTabIndex() const {return cur_tab;} - - //! Add new tab with name "name", bind key "bind_key" and returns this tab index - int addTab(const PIString & name, char bind_key = 0); - - //! Remove tab with index "index" - void removeTab(uint index); - - //! Remove tab with name "name" - void removeTab(const PIString & name); - - //! Clear content of tab with index "index" - void clearTab(uint index); - - //! Clear content of tab with name "name" - void clearTab(const PIString & name); - - //! Set current tab to tab with index "index", returns if tab exists - bool setTab(uint index); - - //! Set current tab to tab with name "name", returns if tab exists - bool setTab(const PIString & name); - - //! Set tab with index "index" bind key to "bind_key", returns if tab exists - bool setTabBindKey(uint index, char bind_key); - - //! Set tab with name "name" bind key to "bind_key", returns if tab exists - bool setTabBindKey(const PIString & name, char bind_key); - - //! Remove all tabs and if "clearScreen" clear the screen - void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();} - - - //! Set custom status text of current tab to "str" - void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;} - - //! Clear custom status text of current tab - void clearCustomStatus() {tabs[cur_tab].status.clear();} - - //! Returns default alignment - Alignment defaultAlignment() const {return def_align;} - - //! Set default alignment to "align" - void setDefaultAlignment(Alignment align) {def_align = align;} - - //! Set column "col" alignment to "align" - void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;} - - //! Set all columns of all tabs alignment to "align" - void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();} - - - //! Directly call function from \a PIKbdListener - void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);} - - //! Directly call function from \a PIKbdListener - void disableExitCapture() {listener->disableExitCapture();} - - //! Directly call function from \a PIKbdListener - bool exitCaptured() const {return listener->exitCaptured();} - - //! Directly call function from \a PIKbdListener - char exitKey() const {return listener->exitKey();} - - - int windowWidth() const {return width;} - int windowHeight() const {return height;} - - PIString fstr(FormatFlags f); - void update(); - void pause(bool yes) {pause_ = yes;} - - // Server functions - void startServer(const PIString & name); - void stopPeer(); - bool isServerStarted() const {return peer != 0;} - PIStringList clients() const; - - // Client functions - void listenServers(); - PIStringList availableServers() const; - PIString selectedServer() const {return server_name;} - void connectToServer(const PIString & name); - void disconnect(); - bool isConnected() const {return state == Connected;} - - void toUpperLeft(); - void moveRight(int n = 1); - void moveLeft(int n = 1); - void moveTo(int x = 0, int y = 0); - void clearScreen(); - void clearScreenLower(); - void clearLine(); - void newLine(); - void hideCursor(); - void showCursor(); - - EVENT_HANDLER0(void, clearVariables) {clearVariables(true);} - EVENT_HANDLER1(void, clearVariables, bool, clearScreen); - - EVENT_HANDLER0(void, waitForFinish) {WAIT_FOR_EXIT} - EVENT_HANDLER0(void, start) {start(false);} - EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();} - EVENT_HANDLER0(void, stop) {stop(false);} - EVENT_HANDLER1(void, stop, bool, clear); - - EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data) - - //! \handlers - //! \{ - - //! \fn void waitForFinish() - //! \brief block until finished (exit key will be pressed) - - //! \fn void clearVariables(bool clearScreen = true) - //! \brief Remove all columns at current tab and if "clearScreen" clear the screen - - //! \fn void start(bool wait = false) - //! \brief Start console output and if "wait" block until finished (exit key will be pressed) - - //! \fn void stop(bool clear = false) - //! \brief Stop console output and if "clear" clear the screen - - //! \} - //! \events - //! \{ - - //! \fn void keyPressed(PIKbdListener::KeyEvent key, void * data) - //! \brief Raise on key "key" pressed, "data" is pointer to %PIConsole object - - //! \} - - private: - void begin(); - void run(); - void fillLabels(); - void status(); - void checkColumn(uint col) {while (columns().size() < col) columns().push_back(Column(def_align));} - int bitsValue(const void * src, int offset, int count) const; - const char * toBin(const void * d, int s); - inline void printLine(const PIString & str, int dx = 0, FormatFlags format = PIConsole::Normal); - inline int printValue(const PIString & str, FormatFlags format = PIConsole::Normal); - inline int printValue(const char * str, FormatFlags format = PIConsole::Normal); - inline int printValue(const bool value, FormatFlags format = PIConsole::Normal); - inline int printValue(const int value, FormatFlags format = PIConsole::Normal); - inline int printValue(const long value, FormatFlags format = PIConsole::Normal); - inline int printValue(const llong value, FormatFlags format = PIConsole::Normal); - inline int printValue(const float value, FormatFlags format = PIConsole::Normal); - inline int printValue(const double value, FormatFlags format = PIConsole::Normal); - inline int printValue(const char value, FormatFlags format = PIConsole::Normal); - inline int printValue(const short value, FormatFlags format = PIConsole::Normal); - inline int printValue(const uchar value, FormatFlags format = PIConsole::Normal); - inline int printValue(const ushort value, FormatFlags format = PIConsole::Normal); - inline int printValue(const uint value, FormatFlags format = PIConsole::Normal); - inline int printValue(const ulong value, FormatFlags format = PIConsole::Normal); - inline int printValue(const ullong value, FormatFlags format = PIConsole::Normal); - inline int printValue(const PISystemTime & value, FormatFlags format = PIConsole::Normal); - static void key_event(PIKbdListener::KeyEvent key, void * t); - - struct Variable { - Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = Normal; remote = false; ptr = 0; id = 1;} - Variable(const Variable & src) {remote = src.remote; name = src.name; format = src.format; type = src.type; offset = src.offset; size = src.size; - bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny; rdata = src.rdata; id = src.id;} - bool isEmpty() const {return (remote ? false : ptr == 0);} - const void * data() {return (remote ? rdata.data() : ptr);} - void writeData(PIByteArray & ba) { - if (remote) ba << rdata; - else { - if (type == 0) ba << (*(PIString * )ptr); - else ba << PIByteArray::RawData(ptr, size); - } - } - PIString name; - FormatFlags format; - int nx; - int ny; - int type; - int offset; - int bitFrom; - int bitCount; - int size; - int id; - bool remote; - const void * ptr; - PIByteArray rdata; - void operator =(const Variable & src) {remote = src.remote; name = src.name; format = src.format; type = src.type; offset = src.offset; size = src.size; - bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny; rdata = src.rdata; id = src.id;} - }; - - struct VariableContent { - int id; - PIByteArray rdata; - }; - - struct Column { - Column(Alignment align = PIConsole::Right) {variables.reserve(32); alignment = align;} - PIVector variables; - Alignment alignment; - uint size() const {return variables.size();} - Variable & operator [](int index) {return variables[index];} - const Variable & operator [](int index) const {return variables[index];} - void push_back(const Variable & v) {variables.push_back(v);} - void operator =(const Column & src) {variables = src.variables; alignment = src.alignment;} - }; - - struct Tab { - Tab(PIString n = "", char k = 0) {columns.reserve(8); name = n; key = k;} - PIVector columns; - PIString name; - PIString status; - char key; - }; - - enum ConnectedState {Disconnected, FetchingData, Committing, Connected}; - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::VariableContent & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::VariableContent & v); - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Variable & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::Variable & v); - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Column & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::Column & v); - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Tab & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::Tab & v); - - PIVector & columns() {return tabs[cur_tab].columns;} - Column & column(int index) {return tabs[cur_tab].columns[index - 1];} - int couts(const PIString & v); - int couts(const char * v); - int couts(const bool v); - int couts(const char v); - int couts(const short v); - int couts(const int v); - int couts(const long v); - int couts(const llong v); - int couts(const uchar v); - int couts(const ushort v); - int couts(const uint v); - int couts(const ulong v); - int couts(const ullong v); - int couts(const float v); - int couts(const double v); - int couts(const PISystemTime & v); - - struct RemoteClient; - - void serverSendInfo(); - void serverSendData(); - RemoteClient & remoteClient(const PIString & fname); - EVENT_HANDLER2(void, peerReceived, const PIString &, from, const PIByteArray &, data); - EVENT_HANDLER2(void, peerTimer, void * , data, int, delim); - EVENT_HANDLER1(void, peerDisconnectedEvent, const PIString &, name); - - PRIVATE_DECLARATION - PIVector tabs; - PIString binstr, rstr; - PIByteArray rba; - Variable tv; - PIKbdListener * listener; - Alignment def_align; - PIKbdListener::KBFunc ret_func; - int width, height, pwidth, pheight, col_wid, num_format, systime_format; - uint max_y; - int vid; - uint cur_tab, col_cnt; - - PIPeer * peer; - PITimer * peer_timer; - PITimeMeasurer peer_tm; - PIString server_name; - bool server_mode, pause_; - ConnectedState state; - - struct RemoteClient { - RemoteClient(const PIString & n = "") {name = n; state = Disconnected;} - PIString name; - ConnectedState state; - }; - - PIVector remote_clients; - -}; - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::VariableContent & v) {ba << v.id << v.rdata; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::VariableContent & v) {ba >> v.id; ba >> v.rdata; return ba;} - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Variable & v) {ba << v.name << v.id << (int)v.format << v.type << v.size << v.bitFrom << v.bitCount; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::Variable & v) {ba >> v.name >> v.id >> (int & )v.format >> v.type >> v.size >> v.bitFrom >> v.bitCount; return ba;} - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Column & v) {ba << (int)v.alignment << v.variables; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::Column & v) {int a; ba >> a >> v.variables; v.alignment = (PIConsole::Alignment)a; return ba;} - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Tab & v) {ba << v.name << v.status << (uchar)v.key << v.columns; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::Tab & v) {ba >> v.name >> v.status >> (uchar&)v.key >> v.columns; return ba;} - -#endif // PICONSOLE_H diff --git a/lib/main/console/piconsolemodule.h b/lib/main/console/piconsolemodule.h index d6f24eab..a266884c 100644 --- a/lib/main/console/piconsolemodule.h +++ b/lib/main/console/piconsolemodule.h @@ -21,7 +21,6 @@ #define PICONSOLEMODULE_H #include "pikbdlistener.h" -#include "piconsole.h" #include "piscreen.h" #include "piscreentiles.h" diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index d8c8de06..c5e3c1b8 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -49,6 +49,9 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(pid_size, f); } + inline PIDeque(PIDeque && other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { + swap(other); + } inline virtual ~PIDeque() { //piCout << "~PIDeque"; PIINTROSPECTION_CONTAINER_DELETE(T) @@ -66,6 +69,12 @@ public: return *this; } + inline PIDeque & operator =(PIDeque && other) { + if (this == &other) return *this; + swap(other); + return *this; + } + typedef T value_type; class iterator { @@ -256,6 +265,23 @@ public: elementNew(pid_data + pid_start + index, v); return *this; } + inline PIDeque & insert(size_t index, T && v) { + bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false); + if (dir) { + alloc(pid_size + 1, true); + if (index < pid_size - 1) { + size_t os = pid_size - index - 1; + memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); + } + } else { + alloc(pid_size + 1, false, -1); + if (index > 0) + memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); + } + PIINTROSPECTION_CONTAINER_USED(T, 1) + elementNew(pid_data + pid_start + index, v); + return *this; + } inline PIDeque & insert(size_t index, const PIDeque & other) { if (other.isEmpty()) return *this; assert(&other != this); @@ -336,7 +362,14 @@ public: elementNew(pid_data + pid_start + pid_size - 1, v); return *this; } + inline PIDeque & push_back(T && v) { + alloc(pid_size + 1, true); + PIINTROSPECTION_CONTAINER_USED(T, 1); + elementNew(pid_data + pid_start + pid_size - 1, v); + return *this; + } inline PIDeque & append(const T & v) {return push_back(v);} + inline PIDeque & append(T && v) {return push_back(v);} inline PIDeque & append(const PIDeque & t) { assert(&t != this); size_t ps = pid_size; @@ -345,6 +378,7 @@ public: return *this; } inline PIDeque & operator <<(const T & v) {return push_back(v);} + inline PIDeque & operator <<(T && v) {return push_back(v);} inline PIDeque & operator <<(const PIDeque & t) {return append(t);} inline PIDeque & push_front(const T & v) {insert(0, v); return *this;} @@ -412,6 +446,7 @@ private: } } inline void elementNew(T * to, const T & from) {new(to)T(from);} + inline void elementNew(T * to, T && from) {piSwap(*to, from);} inline void elementDelete(T & from) {from.~T();} inline void dealloc() { if ((uchar*)pid_data != 0) free((uchar*)pid_data); @@ -485,6 +520,7 @@ private: template<> inline void PIDeque::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIDeque::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIDeque::elementNew(T * to, const T & from) {(*to) = from;} \ + template<> inline void PIDeque::elementNew(T * to, T && from) {(*to) = from;} \ template<> inline void PIDeque::elementDelete(T &) {;} \ template<> inline PIDeque & PIDeque::_resizeRaw(size_t new_size) { \ if (new_size > pid_size) { \ diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index f397a09f..6939eb53 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -74,6 +74,7 @@ class PIMap { public: PIMap() {;} PIMap(const PIMap & other) {*this = other;} + PIMap(PIMap && other) {swap(other);} virtual ~PIMap() {;} PIMap & operator =(const PIMap & other) { @@ -84,6 +85,12 @@ public: return *this; } + PIMap & operator =(PIMap && other) { + if (this == &other) return *this; + swap(other); + return *this; + } + typedef T mapped_type; typedef Key key_type; typedef PIPair value_type; diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index d943af3d..1ea45b15 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -48,6 +48,9 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(piv_size, f); } + inline PIVector(PIVector && other): piv_data(0), piv_size(0), piv_rsize(0) { + swap(other); + } inline virtual ~PIVector() { PIINTROSPECTION_CONTAINER_DELETE(T) PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize)) @@ -65,6 +68,12 @@ public: return *this; } + inline PIVector & operator =(PIVector && other) { + if (this == &other) return *this; + swap(other); + return *this; + } + typedef T value_type; class iterator { @@ -253,6 +262,16 @@ public: elementNew(piv_data + index, v); return *this; } + inline PIVector & insert(size_t index, T && v) { + alloc(piv_size + 1); + if (index < piv_size - 1) { + size_t os = piv_size - index - 1; + memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); + } + PIINTROSPECTION_CONTAINER_USED(T, 1) + elementNew(piv_data + index, v); + return *this; + } inline PIVector & insert(size_t index, const PIVector & other) { if (other.isEmpty()) return *this; assert(&other != this); @@ -320,7 +339,14 @@ public: elementNew(piv_data + piv_size - 1, v); return *this; } + inline PIVector & push_back(T && v) { + alloc(piv_size + 1); + PIINTROSPECTION_CONTAINER_USED(T, 1); + elementNew(piv_data + piv_size - 1, v); + return *this; + } inline PIVector & append(const T & v) {return push_back(v);} + inline PIVector & append(T && v) {return push_back(v);} inline PIVector & append(const PIVector & other) { assert(&other != this); size_t ps = piv_size; @@ -329,6 +355,7 @@ public: return *this; } inline PIVector & operator <<(const T & v) {return push_back(v);} + inline PIVector & operator <<(T && v) {return push_back(v);} inline PIVector & operator <<(const PIVector & other) {return append(other);} inline PIVector & push_front(const T & v) {insert(0, v); return *this;} @@ -405,6 +432,7 @@ private: } } inline void elementNew(T * to, const T & from) {new(to)T(from);} + inline void elementNew(T * to, T && from) {piSwap(*to, from);} inline void elementDelete(T & from) {from.~T();} inline void dealloc() { if ((uchar*)piv_data != 0) free((uchar*)piv_data); @@ -434,6 +462,7 @@ private: template<> inline void PIVector::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIVector::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIVector::elementNew(T * to, const T & from) {(*to) = from;} \ + template<> inline void PIVector::elementNew(T * to, T && from) {(*to) = from;} \ template<> inline void PIVector::elementDelete(T &) {;} \ template<> inline PIVector & PIVector::_resizeRaw(size_t new_size) { \ if (new_size > piv_size) { \ diff --git a/lib/main/core/picout.cpp b/lib/main/core/picout.cpp index c20cf82f..ff37a625 100644 --- a/lib/main/core/picout.cpp +++ b/lib/main/core/picout.cpp @@ -18,9 +18,9 @@ */ #include "piincludes_p.h" #include "picout.h" -#include "piconsole.h" #include "pibytearray.h" #include "pistack.h" +#include "piobject.h" #include "pistring_std.h" #ifdef WINDOWS # include diff --git a/lib/main/core/piincludes.cpp b/lib/main/core/piincludes.cpp index 5600257c..6b480a21 100644 --- a/lib/main/core/piincludes.cpp +++ b/lib/main/core/piincludes.cpp @@ -19,7 +19,6 @@ #include "piincludes.h" #include "piincludes_p.h" -#include "piconsole.h" #include "pitime.h" #ifndef QNX # include diff --git a/lib/main/core/piincludes.h b/lib/main/core/piincludes.h index 1027228f..7d74775e 100644 --- a/lib/main/core/piincludes.h +++ b/lib/main/core/piincludes.h @@ -27,10 +27,9 @@ # include #endif #include -#include -typedef std::mutex PIMutex; -//typedef std::lock_guard PIMutexLocker; +class PIMutex; +class PIMutexLocker; class PIObject; class PIString; class PIByteArray; diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index e7affb17..00c87197 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -51,6 +51,8 @@ public: PIString(const PIString & o): PIDeque() {*this += o;} + PIString(PIString && o): PIDeque() {swap(o);} + //! Contructs string with single symbol "c" PIString(const PIChar & c): PIDeque() {*this += c;} @@ -89,6 +91,8 @@ public: PIString & operator =(const PIString & o) {if (this == &o) return *this; clear(); *this += o; return *this;} + PIString & operator =(PIString && o) {if (this == &o) return *this; swap(o); return *this;} + /*! \brief Return c-string representation of string * \details Converts content of string to c-string and return * pointer to first char. This buffer is valid until new convertion diff --git a/lib/main/core/pistringlist.h b/lib/main/core/pistringlist.h index 0a9669f0..6e81f034 100644 --- a/lib/main/core/pistringlist.h +++ b/lib/main/core/pistringlist.h @@ -83,6 +83,7 @@ public: PIStringList & operator =(const PIStringList & o) {PIDeque::operator=(o); return *this;} PIStringList & operator <<(const PIString & str) {append(str); return *this;} + PIStringList & operator <<(PIString && str) {append(str); return *this;} PIStringList & operator <<(const PIStringList & sl) {append(sl); return *this;} }; diff --git a/lib/main/system/picodec.cpp b/lib/main/system/picodec.cpp deleted file mode 100644 index 235d2ad6..00000000 --- a/lib/main/system/picodec.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - PIP - Platform Independent Primitives - Text codings coder, based on "iconv" - 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 . -*/ - -#ifndef PIP_FREERTOS - -#include "picodec.h" - - -PIStringList PICodec::availableCodecs() { - exec("/usr/bin/iconv", "-l"); - waitForFinish(); - PIString str(readOutput()); - str.cutLeft(str.find("\n ")); - str.replaceAll("\n", ""); - return str.split("//"); -} - - -PIByteArray PICodec::exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str) { - tf.openTemporary(PIIODevice::ReadWrite); - tf.clear(); - tf << str; - tf.close(); - exec("/usr/bin/iconv", PIStringList() << ("-f=" + from) << ("-t=" + to) << tf.path()); - waitForFinish(); - return readOutput(); -} - -#endif // PIP_FREERTOS diff --git a/lib/main/system/picodec.h b/lib/main/system/picodec.h deleted file mode 100644 index 67a88941..00000000 --- a/lib/main/system/picodec.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - PIP - Platform Independent Primitives - Text codings coder, based on "iconv" - 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 . -*/ - -#ifndef PICODEC_H -#define PICODEC_H - -#ifndef PIP_FREERTOS - -#include "piprocess.h" - -class PIP_EXPORT PICodec: protected PIProcess -{ - PIOBJECT(PICodec) -public: - PICodec(): PIProcess() {setGrabOutput(true);} - PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to);} - ~PICodec() {tf.remove();} - - void setFromCoding(const PIString & from) {c_from = from;} - void setToCoding(const PIString & to) {c_to = to;} - void setCodings(const PIString & from, const PIString & to) {c_from = from; c_to = to;} - - PIStringList availableCodecs(); - PIString encode(PIString & str) {return PIString(exec_iconv(c_from, c_to, str.toByteArray()));} - PIString encode(const PIByteArray & str) {return PIString(exec_iconv(c_from, c_to, str));} - PIString decode(PIString & str) {return PIString(exec_iconv(c_to, c_from, str.toByteArray()));} - PIString decode(const PIByteArray & str) {return PIString(exec_iconv(c_to, c_from, str));} - -private: - PIByteArray exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str); - - PIString c_from, c_to; - PIFile tf; - -}; - -#endif // PIP_FREERTOS -#endif // PICODEC_H diff --git a/lib/main/system/pisystemmodule.h b/lib/main/system/pisystemmodule.h index f550868f..a75662c4 100644 --- a/lib/main/system/pisystemmodule.h +++ b/lib/main/system/pisystemmodule.h @@ -20,7 +20,6 @@ #ifndef PISYSTEMMODULE_H #define PISYSTEMMODULE_H -#include "picodec.h" #include "pisignals.h" #include "pilibrary.h" #include "pisysteminfo.h" diff --git a/lib/main/concurrent/piblockingdequeue.h b/lib/main/thread/piblockingdequeue.h similarity index 93% rename from lib/main/concurrent/piblockingdequeue.h rename to lib/main/thread/piblockingdequeue.h index 5f64da06..fe8f5a1f 100644 --- a/lib/main/concurrent/piblockingdequeue.h +++ b/lib/main/thread/piblockingdequeue.h @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#ifndef PIP_TESTS_PIBLOCKINGDEQUEUE_H -#define PIP_TESTS_PIBLOCKINGDEQUEUE_H +#ifndef PIBLOCKINGDEQUEUE_H +#define PIBLOCKINGDEQUEUE_H #include "pideque.h" #include "piconditionvar.h" @@ -140,14 +140,14 @@ public: * return value is retrieved value * @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available */ - T poll(int timeoutMs, const T & defaultVal = T(), bool* isOk = nullptr) { + T poll(int timeoutMs, const T & defaultVal = T(), bool * isOk = nullptr) { T t; mutex.lock(); bool isNotEmpty = cond_var_add->waitFor(mutex, timeoutMs, [&]() { return !PIDeque::isEmpty(); }); t = isNotEmpty ? T(PIDeque::take_front()) : defaultVal; mutex.unlock(); if (isNotEmpty) cond_var_rem->notifyOne(); - if (isOk != nullptr) *isOk = isNotEmpty; + if (isOk) *isOk = isNotEmpty; return t; } @@ -160,14 +160,14 @@ public: * return value is retrieved value * @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available */ - T poll(const T & defaultVal = T(), bool* isOk = nullptr) { + T poll(const T & defaultVal = T(), bool * isOk = nullptr) { T t; mutex.lock(); bool isNotEmpty = !PIDeque::isEmpty(); t = isNotEmpty ? T(PIDeque::take_front()) : defaultVal; mutex.unlock(); if (isNotEmpty) cond_var_rem->notifyOne(); - if (isOk != nullptr) *isOk = isNotEmpty; + if (isOk) *isOk = isNotEmpty; return t; } @@ -213,7 +213,7 @@ public: */ size_t drainTo(PIDeque& other, size_t maxCount = SIZE_MAX) { mutex.lock(); - size_t count = maxCount > PIDeque::size() ? PIDeque::size() : maxCount; + size_t count = ((maxCount > PIDeque::size()) ? PIDeque::size() : maxCount); for (size_t i = 0; i < count; ++i) other.push_back(PIDeque::take_front()); mutex.unlock(); return count; @@ -235,11 +235,11 @@ public: } private: - PIConditionLock mutex; - PIConditionVariable* cond_var_add; - PIConditionVariable* cond_var_rem; + PIMutex mutex; + PIConditionVariable * cond_var_add, * cond_var_rem; size_t max_size; + }; -#endif //PIP_TESTS_PIBLOCKINGDEQUEUE_H +#endif // PIBLOCKINGDEQUEUE_H diff --git a/lib/concurrent/piconditionvar.cpp b/lib/main/thread/piconditionvar.cpp similarity index 87% rename from lib/concurrent/piconditionvar.cpp rename to lib/main/thread/piconditionvar.cpp index 5f3fac3a..395f53f6 100644 --- a/lib/concurrent/piconditionvar.cpp +++ b/lib/main/thread/piconditionvar.cpp @@ -1,141 +1,141 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#include "piconditionvar.h" -#include "pithread.h" -#include "pitime.h" - -#ifdef WINDOWS -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0600 -# include -# include -# include -#endif - - -PRIVATE_DEFINITION_START(PIConditionVariable) -#ifdef WINDOWS - CONDITION_VARIABLE nativeHandle; -#else - pthread_cond_t nativeHandle; - PIConditionLock* currentLock; -#endif - bool isDestroying; -PRIVATE_DEFINITION_END(PIConditionVariable) - - -PIConditionVariable::PIConditionVariable() { -#ifdef WINDOWS - InitializeConditionVariable(&PRIVATE->nativeHandle); -#else - PRIVATE->isDestroying = false; - PRIVATE->currentLock = nullptr; - memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); - pthread_cond_init(&PRIVATE->nativeHandle, NULL); -#endif -} - - -PIConditionVariable::~PIConditionVariable() { -#ifdef WINDOWS -#else - pthread_cond_destroy(&PRIVATE->nativeHandle); -#endif -} - - -void PIConditionVariable::wait(PIConditionLock& lk) { -#ifdef WINDOWS - SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); -#else - pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); -#endif -} - - -void PIConditionVariable::wait(PIConditionLock& lk, const std::function& condition) { - bool isCondition; - while (true) { - isCondition = condition(); - if (isCondition) break; -#ifdef WINDOWS - SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); -#else - pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); -#endif - if (PRIVATE->isDestroying) return; - } -} - - -bool PIConditionVariable::waitFor(PIConditionLock &lk, int timeoutMs) { - bool isNotTimeout; -#ifdef WINDOWS - isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; -#else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000}; - isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; -#endif - if (PRIVATE->isDestroying) return false; - return isNotTimeout; -} - - -bool PIConditionVariable::waitFor(PIConditionLock& lk, int timeoutMs, const std::function &condition) { - bool isCondition; - PITimeMeasurer measurer; - while (true) { - isCondition = condition(); - if (isCondition) break; -#ifdef WINDOWS - WINBOOL isTimeout = SleepConditionVariableCS( - &PRIVATE->nativeHandle, - (PCRITICAL_SECTION)lk.handle(), - timeoutMs - (int)measurer.elapsed_m()); - if (isTimeout == 0) return false; -#else - int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000}; - bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; - if (isTimeout) return false; -#endif - if (PRIVATE->isDestroying) return false; - } - return true; -} - - -void PIConditionVariable::notifyOne() { -#ifdef WINDOWS - WakeConditionVariable(&PRIVATE->nativeHandle); -#else - pthread_cond_signal(&PRIVATE->nativeHandle); -#endif -} - - -void PIConditionVariable::notifyAll() { -#ifdef WINDOWS - WakeAllConditionVariable(&PRIVATE->nativeHandle); -#else - pthread_cond_broadcast(&PRIVATE->nativeHandle); -#endif -} - +/* + PIP - Platform Independent Primitives + + Stephan Fomenko + + 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 . +*/ + +#include "piconditionvar.h" +#include "pithread.h" +#include "pitime.h" + +#ifdef WINDOWS +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +# include +# include +# include +#endif + + +PRIVATE_DEFINITION_START(PIConditionVariable) +#ifdef WINDOWS + CONDITION_VARIABLE nativeHandle; +#else + pthread_cond_t nativeHandle; + PIMutex * currentLock; +#endif + bool isDestroying; +PRIVATE_DEFINITION_END(PIConditionVariable) + + +PIConditionVariable::PIConditionVariable() { +#ifdef WINDOWS + InitializeConditionVariable(&PRIVATE->nativeHandle); +#else + PRIVATE->isDestroying = false; + PRIVATE->currentLock = nullptr; + memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); + pthread_cond_init(&PRIVATE->nativeHandle, NULL); +#endif +} + + +PIConditionVariable::~PIConditionVariable() { +#ifdef WINDOWS +#else + pthread_cond_destroy(&PRIVATE->nativeHandle); +#endif +} + + +void PIConditionVariable::wait(PIMutex& lk) { +#ifdef WINDOWS + SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); +#else + pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); +#endif +} + + +void PIConditionVariable::wait(PIMutex& lk, const std::function& condition) { + bool isCondition; + while (true) { + isCondition = condition(); + if (isCondition) break; +#ifdef WINDOWS + SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); +#else + pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); +#endif + if (PRIVATE->isDestroying) return; + } +} + + +bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { + bool isNotTimeout; +#ifdef WINDOWS + isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; +#else + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000}; + isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; +#endif + if (PRIVATE->isDestroying) return false; + return isNotTimeout; +} + + +bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function &condition) { + bool isCondition; + PITimeMeasurer measurer; + while (true) { + isCondition = condition(); + if (isCondition) break; +#ifdef WINDOWS + WINBOOL isTimeout = SleepConditionVariableCS( + &PRIVATE->nativeHandle, + (PCRITICAL_SECTION)lk.handle(), + timeoutMs - (int)measurer.elapsed_m()); + if (isTimeout == 0) return false; +#else + int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000}; + bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; + if (isTimeout) return false; +#endif + if (PRIVATE->isDestroying) return false; + } + return true; +} + + +void PIConditionVariable::notifyOne() { +#ifdef WINDOWS + WakeConditionVariable(&PRIVATE->nativeHandle); +#else + pthread_cond_signal(&PRIVATE->nativeHandle); +#endif +} + + +void PIConditionVariable::notifyAll() { +#ifdef WINDOWS + WakeAllConditionVariable(&PRIVATE->nativeHandle); +#else + pthread_cond_broadcast(&PRIVATE->nativeHandle); +#endif +} + diff --git a/lib/main/concurrent/piconditionvar.h b/lib/main/thread/piconditionvar.h similarity index 83% rename from lib/main/concurrent/piconditionvar.h rename to lib/main/thread/piconditionvar.h index 4d011187..923e2ba7 100644 --- a/lib/main/concurrent/piconditionvar.h +++ b/lib/main/thread/piconditionvar.h @@ -20,14 +20,13 @@ #ifndef PICONDITIONVAR_H #define PICONDITIONVAR_H -#include "piconditionlock.h" #include "pithread.h" /** * @brief A condition variable is an object able to block the calling thread until notified to resume. * - * It uses a PIConditionLock to lock the thread when one of its wait functions is called. The thread remains + * It uses a PIMutex to lock the thread when one of its wait functions is called. The thread remains * blocked until woken up by another thread that calls a notification function on the same PIConditionVariable object. */ class PIP_EXPORT PIConditionVariable { @@ -49,20 +48,20 @@ public: void notifyAll(); /** - * @brief see wait(PIConditionLock&, const std::function&) + * @brief see wait(PIMutex &, const std::function&) */ - virtual void wait(PIConditionLock& lk); + virtual void wait(PIMutex & lk); /** * @brief Wait until notified * - * The execution of the current thread (which shall have locked with lk method PIConditionLock::lock()) is blocked + * The execution of the current thread (which shall have locked with lk method PIMutex::lock()) is blocked * until notified. * - * At the moment of blocking the thread, the function automatically calls lk.unlock() (PIConditionLock::unlock()), + * At the moment of blocking the thread, the function automatically calls lk.unlock() (PIMutex::unlock()), * allowing other locked threads to continue. * - * Once notified (explicitly, by some other thread), the function unblocks and calls lk.lock() (PIConditionLock::lock()), + * Once notified (explicitly, by some other thread), the function unblocks and calls lk.lock() (PIMutex::lock()), * leaving lk in the same state as when the function was called. Then the function returns (notice that this last mutex * locking may block again the thread before returning). * @@ -77,23 +76,23 @@ public: * @param condition A callable object or function that takes no arguments and returns a value that can be evaluated * as a bool. This is called repeatedly until it evaluates to true. */ - virtual void wait(PIConditionLock& lk, const std::function& condition); + virtual void wait(PIMutex& lk, const std::function& condition); /** - * @brief see waitFor(PIConditionLock&, int, const std::function&) + * @brief see waitFor(PIMutex &, int, const std::function&) */ - virtual bool waitFor(PIConditionLock& lk, int timeoutMs); + virtual bool waitFor(PIMutex & lk, int timeoutMs); /** * @brief Wait for timeout or until notified * - * The execution of the current thread (which shall have locked with lk method PIConditionLock::lock()) is blocked + * The execution of the current thread (which shall have locked with lk method PIMutex::lock()) is blocked * during timeoutMs, or until notified (if the latter happens first). * - * At the moment of blocking the thread, the function automatically calls lk.lock() (PIConditionLock::lock()), allowing + * At the moment of blocking the thread, the function automatically calls lk.lock() (PIMutex::lock()), allowing * other locked threads to continue. * - * Once notified or once timeoutMs has passed, the function unblocks and calls lk.unlock() (PIConditionLock::unlock()), + * Once notified or once timeoutMs has passed, the function unblocks and calls lk.unlock() (PIMutex::unlock()), * leaving lk in the same state as when the function was called. Then the function returns (notice that this last * mutex locking may block again the thread before returning). * @@ -109,7 +108,7 @@ public: * as a bool. This is called repeatedly until it evaluates to true. * @return false if timeout reached or true if wakeup condition is true */ - virtual bool waitFor(PIConditionLock& lk, int timeoutMs, const std::function& condition); + virtual bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition); private: PRIVATE_DECLARATION diff --git a/lib/main/thread/pimutex.cpp b/lib/main/thread/pimutex.cpp new file mode 100644 index 00000000..2c0a97b2 --- /dev/null +++ b/lib/main/thread/pimutex.cpp @@ -0,0 +1,122 @@ +/* + PIP - Platform Independent Primitives + Mutex + Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, 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 . +*/ + +/** \class PIMutex + * \brief Mutex + * \details + * \section PIMutex_sec0 Synopsis + * %PIMutex provides synchronization blocks between several threads. + * Using mutex guarantees execution of some code only one of threads. + * Mutex contains logic state and functions to change it: \a lock(), + * \a unlock() and \a tryLock(). + * + * \section PIMutex_sec1 Usage + * Block of code that should to be executed only one thread simultaniously + * should to be started with \a lock() and ended with \a unlock(). + * \snippet pimutex.cpp main + * "mutex" in this example is one for all threads. + * + * */ + +#include "pimutex.h" +#include "piincludes_p.h" +#ifdef WINDOWS +# include +#else +# include +#endif + + + +PRIVATE_DEFINITION_START(PIMutex) +#ifdef WINDOWS + CRITICAL_SECTION +#else + pthread_mutex_t +#endif + mutex; +PRIVATE_DEFINITION_END(PIMutex) + + +PIMutex::PIMutex() { + init(); +} + + +PIMutex::~PIMutex() { + destroy(); +} + + +void PIMutex::lock() { +#ifdef WINDOWS + EnterCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutex_lock(&(PRIVATE->mutex)); +#endif +} + + +void PIMutex::unlock() { +#ifdef WINDOWS + LeaveCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutex_unlock(&(PRIVATE->mutex)); +#endif +} + + +bool PIMutex::tryLock() { + bool ret = +#ifdef WINDOWS + (TryEnterCriticalSection(&(PRIVATE->mutex)) != 0); +#else + (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); +#endif + return ret; +} + + +void * PIMutex::handle() { + return (void*)&(PRIVATE->mutex); +} + + +void PIMutex::init() { +#ifdef WINDOWS + InitializeCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutexattr_t attr; + memset(&attr, 0, sizeof(attr)); + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); + pthread_mutex_init(&(PRIVATE->mutex), &attr); + pthread_mutexattr_destroy(&attr); +#endif +} + + +void PIMutex::destroy() { +#ifdef WINDOWS + DeleteCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutex_destroy(&(PRIVATE->mutex)); +#endif +} diff --git a/lib/main/thread/pimutex.h b/lib/main/thread/pimutex.h index 02892916..b71b1600 100644 --- a/lib/main/thread/pimutex.h +++ b/lib/main/thread/pimutex.h @@ -4,7 +4,7 @@ /* PIP - Platform Independent Primitives PIMutexLocker - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, 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 @@ -24,6 +24,45 @@ #define PIMUTEX_H #include "piinit.h" +#include + + +class PIP_EXPORT PIMutex +{ +public: + NO_COPY_CLASS(PIMutex) + + //! Constructs unlocked mutex + explicit PIMutex(); + + //! Destroy mutex + ~PIMutex(); + + + //! \brief Lock mutex + //! \details If mutex is unlocked it set to locked state and returns immediate. + //! If mutex is already locked function blocks until mutex will be unlocked + void lock(); + + //! \brief Unlock mutex + //! \details In any case this function returns immediate + void unlock() ; + + //! \brief Try to lock mutex + //! \details If mutex is unlocked it set to locked state and returns "true" immediate. + //! If mutex is already locked function returns immediate an returns "false" + bool tryLock(); + + void * handle(); + +private: + void init(); + void destroy(); + + PRIVATE_DECLARATION + +}; + //! \brief PIMutexLocker //! \details Same as std::lock_guard. @@ -40,7 +79,7 @@ public: ~PIMutexLocker() {if (cond) mutex.unlock();} private: PIMutex & mutex; - std::atomic_bool cond; + bool cond; }; #endif // PIMUTEX_H diff --git a/lib/main/thread/pithreadmodule.h b/lib/main/thread/pithreadmodule.h index e0d97bcb..5973dfe4 100644 --- a/lib/main/thread/pithreadmodule.h +++ b/lib/main/thread/pithreadmodule.h @@ -25,5 +25,7 @@ #include "pitimer.h" #include "pipipelinethread.h" #include "pigrabberbase.h" +#include "pithreadpoolexecutor.h" +#include "piconditionvar.h" #endif // PITHREADMODULE_H diff --git a/lib/concurrent/executor.cpp b/lib/main/thread/pithreadpoolexecutor.cpp similarity index 71% rename from lib/concurrent/executor.cpp rename to lib/main/thread/pithreadpoolexecutor.cpp index a1c80042..d0feeb83 100644 --- a/lib/concurrent/executor.cpp +++ b/lib/main/thread/pithreadpoolexecutor.cpp @@ -1,74 +1,89 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#include "executor.h" - - -PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue> *taskQueue_) : isShutdown_(false), taskQueue(taskQueue_) { - for (size_t i = 0; i < corePoolSize; ++i) { - PIThread * thread = new PIThread([&, i](){ - auto runnable = taskQueue->poll(100, std::function()); - if (runnable) { - runnable(); - } - if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop(); - }); - threadPool.push_back(thread); - thread->start(); - } -} - - -bool PIThreadPoolExecutor::awaitTermination(int timeoutMs) { - PITimeMeasurer measurer; - for (size_t i = 0; i < threadPool.size(); ++i) { - int dif = timeoutMs - (int)measurer.elapsed_m(); - if (dif < 0) return false; - if (!threadPool[i]->waitForFinish(dif)) return false; - } - return true; -} - - -void PIThreadPoolExecutor::shutdownNow() { - isShutdown_ = true; - for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop(); -} - - -PIThreadPoolExecutor::~PIThreadPoolExecutor() { - shutdownNow(); - while (threadPool.size() > 0) delete threadPool.take_back(); - delete taskQueue; -} - - -void PIThreadPoolExecutor::execute(const std::function &runnable) { - if (!isShutdown_) taskQueue->offer(runnable); -} - - -bool PIThreadPoolExecutor::isShutdown() const { - return isShutdown_; -} - - -void PIThreadPoolExecutor::shutdown() { - isShutdown_ = true; -} +/* + PIP - Platform Independent Primitives + + Stephan Fomenko + + 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 . +*/ + +#include "pithreadpoolexecutor.h" +#include "pisysteminfo.h" + +/*! \class PIThreadPoolExecutor + * @brief Thread pools address two different problems: they usually provide improved performance when executing large + * numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and + * managing the resources, including threads, consumed when executing a collection of tasks. + */ + + +PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue > * taskQueue_) : isShutdown_(false) { + queue_own = false; + if (corePoolSize <= 0) + corePoolSize = PISystemInfo::instance()->processorsCount; + if (!taskQueue_) { + taskQueue = new PIBlockingDequeue >(); + queue_own = true; + } + for (size_t i = 0; i < corePoolSize; ++i) { + PIThread * thread = new PIThread([&, i](){ + auto runnable = taskQueue->poll(100, std::function()); + if (runnable) { + runnable(); + } + if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop(); + }); + threadPool.push_back(thread); + thread->start(); + } +} + + +bool PIThreadPoolExecutor::awaitTermination(int timeoutMs) { + PITimeMeasurer measurer; + for (size_t i = 0; i < threadPool.size(); ++i) { + int dif = timeoutMs - (int)measurer.elapsed_m(); + if (dif < 0) return false; + if (!threadPool[i]->waitForFinish(dif)) return false; + } + return true; +} + + +void PIThreadPoolExecutor::shutdownNow() { + isShutdown_ = true; + for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop(); +} + + +PIThreadPoolExecutor::~PIThreadPoolExecutor() { + shutdownNow(); + while (threadPool.size() > 0) delete threadPool.take_back(); + if (queue_own) + delete taskQueue; +} + + +void PIThreadPoolExecutor::execute(const std::function & runnable) { + if (!isShutdown_) taskQueue->offer(runnable); +} + + +bool PIThreadPoolExecutor::isShutdown() const { + return isShutdown_; +} + + +void PIThreadPoolExecutor::shutdown() { + isShutdown_ = true; +} diff --git a/lib/main/concurrent/executor.h b/lib/main/thread/pithreadpoolexecutor.h similarity index 70% rename from lib/main/concurrent/executor.h rename to lib/main/thread/pithreadpoolexecutor.h index 63a6135c..d8655843 100644 --- a/lib/main/concurrent/executor.h +++ b/lib/main/thread/pithreadpoolexecutor.h @@ -17,20 +17,16 @@ along with this program. If not, see . */ -#ifndef PIP_TESTS_EXECUTOR_H -#define PIP_TESTS_EXECUTOR_H +#ifndef PITHREADPOOLEXECUTOR_H +#define PITHREADPOOLEXECUTOR_H #include "piblockingdequeue.h" #include -/** - * @brief Thread pools address two different problems: they usually provide improved performance when executing large - * numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and - * managing the resources, including threads, consumed when executing a collection of tasks. - */ + class PIThreadPoolExecutor { public: - explicit PIThreadPoolExecutor(size_t corePoolSize = 1, PIBlockingDequeue >* taskQueue_ = new PIBlockingDequeue >()); + explicit PIThreadPoolExecutor(size_t corePoolSize = -1, PIBlockingDequeue > * taskQueue_ = 0); virtual ~PIThreadPoolExecutor(); @@ -41,7 +37,7 @@ public: * * @param runnable not empty function for thread pool execution */ - void execute(const std::function& runnable); + void execute(const std::function & runnable); void shutdownNow(); @@ -55,10 +51,13 @@ public: bool isShutdown() const; bool awaitTermination(int timeoutMs); + private: std::atomic_bool isShutdown_; - PIBlockingDequeue >* taskQueue; + PIBlockingDequeue > * taskQueue; PIVector threadPool; + bool queue_own; + }; -#endif //PIP_TESTS_EXECUTOR_H +#endif // PITHREADPOOLEXECUTOR_H diff --git a/main.cpp b/main.cpp index d78cedcf..5bc395f7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ #include "pip.h" -#ifdef PIP_LUA +/*#ifdef PIP_LUA #include "piluaprogram.h" static const char * script @@ -30,3 +30,29 @@ int main() { return 0; } #endif +*/ + +#include "picodeparser.h" +int main() { + piDebug = false; + double min = -1, max = -1, mean = 0; + for (int i = 0; i < 50; ++i) { + PITimeMeasurer tm; + /*PICodeParser cp; + cp.parseFile("SH_plugin_base.h");*/ + PIStringList sl; + for (int i = 0; i < 5000; ++i) { + //PIString s("1234567890-="); + //sl << s; + sl << PIString("1234567890-="); + } + double ms = tm.elapsed_m(); + if (min < 0) min = ms; + if (max < 0) max = ms; + min = piMin(min, ms); + max = piMax(max, ms); + mean += ms; + } + piDebug = true; + piCout << min << (mean / 50) << max; +} From 557f2a4d0d0170dd4ef98a4660e79175758e73fc Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 30 Jul 2020 20:08:33 +0300 Subject: [PATCH 17/68] replace piForeach* to for(:) another c++11 try ... --- CMakeLists.txt | 4 +- lib/console/piscreen.cpp | 4 +- lib/console/piterminal.cpp | 2 +- lib/main/containers/picontainers.h | 149 ++++------------------------ lib/main/containers/pideque.h | 7 +- lib/main/containers/pimap.h | 4 + lib/main/containers/pivector.h | 6 +- lib/main/core/piinit.cpp | 2 +- lib/main/core/piobject.cpp | 46 +++++---- lib/main/io_devices/pibinarylog.cpp | 2 +- lib/main/io_devices/pipeer.cpp | 4 +- lib/main/io_devices/piserial.cpp | 2 +- lib/main/io_utils/piconnection.cpp | 122 ++++++++++++----------- lib/main/thread/piblockingdequeue.h | 2 +- main.cpp | 17 ++-- utils/code_model_generator/main.cpp | 4 +- utils/deploy_tool/main.cpp | 2 +- utils/system_daemon/main.cpp | 7 +- 18 files changed, 151 insertions(+), 235 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e7e49d1..2fcbe46b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 1) set(_PIP_MINOR 99) -set(_PIP_REVISION 0) -set(_PIP_SUFFIX _prealpha) +set(_PIP_REVISION 1) +set(_PIP_SUFFIX _prebeta) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/lib/console/piscreen.cpp b/lib/console/piscreen.cpp index 60945d17..786c1b02 100644 --- a/lib/console/piscreen.cpp +++ b/lib/console/piscreen.cpp @@ -480,7 +480,7 @@ void PIScreen::mouse_event(PIKbdListener::MouseEvent me) { PIVector tl = prepareMouse(&me); if (tl.isEmpty()) return; piForeachR (PIScreenTile * t, tl) - if (t->mouseEvent(me)) piBreak; + if (t->mouseEvent(me)) break; } @@ -488,7 +488,7 @@ void PIScreen::wheel_event(PIKbdListener::WheelEvent we) { PIVector tl = prepareMouse(&we); if (tl.isEmpty()) return; piForeachR (PIScreenTile * t, tl) - if (t->wheelEvent(we)) piBreak; + if (t->wheelEvent(we)) break; } diff --git a/lib/console/piterminal.cpp b/lib/console/piterminal.cpp index 2c0da013..ce9623aa 100644 --- a/lib/console/piterminal.cpp +++ b/lib/console/piterminal.cpp @@ -805,7 +805,7 @@ bool PITerminal::initialize() { if (e.startsWith("TERM=")) { PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase()); //piCout << PRIVATE->term_type; - piBreak; + break; } pid_t fr = forkpty(&(PRIVATE->fd), pty, 0, &ws); //piCoutObj << fr << PRIVATE->fd << pty; diff --git a/lib/main/containers/picontainers.h b/lib/main/containers/picontainers.h index 688388de..0487c892 100644 --- a/lib/main/containers/picontainers.h +++ b/lib/main/containers/picontainers.h @@ -97,141 +97,32 @@ */ # define piForeachCR(i,c) -/*!\brief Macro for break from any piForeach* loop - * \details \warning C++ ordinary "break" doesn`t work inside piForeach* - * loops! Always use "piBreak" instead! - */ -# define piBreak - #else -# define piBreak {_for._end = true; break;} + +template +struct _reverse_wrapper { + C & c_; + _reverse_wrapper(C & c): c_(c) {} + _reverse_wrapper(const C & c): c_(const_cast(c)) {} + typename C::reverse_iterator begin() {return c_.rbegin();} + typename C::reverse_iterator end() {return c_.rend(); } + typename C::const_reverse_iterator begin() const {return c_.rbegin();} + typename C::const_reverse_iterator end() const {return c_.rend(); } +}; + +template _reverse_wrapper _reverse_wrap(C & c) {return _reverse_wrapper(c);} +template _reverse_wrapper _reverse_wrap(const C & c) {return _reverse_wrapper(c);} + # define piForTimes(c) for(int _i##c = 0; _i##c < c; ++_i##c) -#ifdef CC_GCC +# define piForeach(i,c) for(i : c) +# define piForeachC(i,c) for(const i : c) +# define piForeachR(i,c) for(i : _reverse_wrap(c)) +# define piForeachRC(i,c) for(const i : _reverse_wrap(c)) -template -class _PIForeach { -public: - _PIForeach(Type & t): _t(t), _break(false), _end(false) {_it = _t.begin();} - typename Type::value_type _var; - typename Type::iterator _it; - Type & _t; - bool _break, _end; - inline bool isEnd() {return _it == _t.end();} - inline void operator ++() {if (_end) _it = _t.end(); else _it++; _break = false;} -}; - -template -class _PIForeachR { -public: - _PIForeachR(Type & t): _t(t), _break(false), _end(false) {_rit = _t.rbegin();} - typename Type::value_type _var; - typename Type::reverse_iterator _rit; - Type & _t; - bool _break, _end; - inline bool isEnd() {return _rit == _t.rend();} - inline void operator ++() {if (_end) _rit = _t.rend(); else _rit++; _break = false;} -}; - -template -class _PIForeachC { -public: - _PIForeachC(const Type & t): _t(t), _break(false), _end(false) {_it = _t.begin();} - typename Type::value_type _var; - typename Type::const_iterator _it; - const Type & _t; - bool _break, _end; - inline bool isEnd() {return _it == _t.end();} - inline void operator ++() {if (_end) _it = _t.end(); else _it++; _break = false;} -}; - -template -class _PIForeachCR { -public: - _PIForeachCR(const Type & t): _t(t), _break(false), _end(false) {_rit = _t.rbegin();} - typename Type::value_type _var; - typename Type::const_reverse_iterator _rit; - const Type & _t; - bool _break, _end; - inline bool isEnd() {return _rit == _t.rend();} - inline void operator ++() {if (_end) _rit = _t.rend(); else _rit++; _break = false;} -}; - -#define piForeach(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) \ - for(i(*_for._it); !_for._break; _for._break = true) -#define piForeachR(i,c) for(_PIForeachR _for(c); !_for.isEnd(); ++_for) \ - for(i(*_for._rit); !_for._break; _for._break = true) -#define piForeachA(i,c) for(_PIForeach _for(c); !_for.isEnd(); ++_for) \ - for(typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true) -#define piForeachAR(i,c) for(_PIForeachR _for(c); !_for.isEnd(); ++_for) \ - for(typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true) -#define piForeachC(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) \ - for(const i(*_for._it); !_for._break; _for._break = true) -#define piForeachCR(i,c) for(_PIForeachCR _for(c); !_for.isEnd(); ++_for) \ - for(const i(*_for._rit); !_for._break; _for._break = true) -#define piForeachCA(i,c) for(_PIForeachC _for(c); !_for.isEnd(); ++_for) \ - for(const typeof(_for._var) & i(*_for._it); !_for._break; _for._break = true) -#define piForeachCAR(i,c) for(_PIForeachCR _for(c); !_for.isEnd(); ++_for) \ - for(const typeof(_for._var) & i(*_for._rit); !_for._break; _for._break = true) - -#define piForeachRA piForeachAR -#define piForeachAC piForeachCA -#define piForeachCRA piForeachCAR -#define piForeachARC piForeachCAR -#define piForeachACR piForeachCAR -#define piForeachRCA piForeachCAR -#define piForeachRAC piForeachCAR - -#else - -class _PIForeachBase {public: mutable bool _break, _end; }; - -template -class _PIForeach: public _PIForeachBase { -public: - _PIForeach(Type & t, bool i = false): _t(t), _inv(i) {_break = _end = false; if (_inv) _rit = _t.rbegin(); else _it = _t.begin();} - mutable typename Type::value_type _var; - mutable typename Type::iterator _it; - mutable typename Type::reverse_iterator _rit; - Type & _t; - bool _inv; - bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();} - void operator ++() {if (_inv) {if (_end) _rit = _t.rend(); else _rit++;} else {if (_end) _it = _t.end(); else _it++;} _break = false;} -}; - -template -class _PIForeachC: public _PIForeachBase { -public: - _PIForeachC(const Type & t, bool i = false): _t(t), _inv(i) {_break = _end = false; if (_inv) _rit = _t.rbegin(); else _it = _t.begin();} - mutable typename Type::value_type _var; - mutable typename Type::const_iterator _it; - mutable typename Type::const_reverse_iterator _rit; - const Type & _t; - bool _inv; - bool isEnd() {if (_inv) return _rit == _t.rend(); else return _it == _t.end();} - void operator ++() {if (_inv) {if (_end) _rit = _t.rend(); else _rit++;} else {if (_end) _it = _t.end(); else _it++;} _break = false;} -}; - -template inline _PIForeach _PIForeachNew(T & t, bool i = false) {return _PIForeach(t, i);} -template inline _PIForeach * _PIForeachCast(_PIForeachBase & c, T & ) {return static_cast<_PIForeach * >(&c);} - -template inline _PIForeachC _PIForeachNewC(const T & t, bool i = false) {return _PIForeachC(t, i);} -template inline _PIForeachC * _PIForeachCastC(_PIForeachBase & c, const T & ) {return static_cast<_PIForeachC * >(&c);} - -#define piForeach(i,c) for(_PIForeachBase & _for = _PIForeachNew(c); !_PIForeachCast(_for, c)->isEnd(); ++(*_PIForeachCast(_for, c))) \ - for(i = *(_PIForeachCast(_for, c)->_it); !_for._break; _for._break = true) -#define piForeachR(i,c) for(_PIForeachBase & _for = _PIForeachNew(c, true); !_PIForeachCast(_for, c)->isEnd(); ++(*_PIForeachCast(_for, c))) \ - for(i = *(_PIForeachCast(_for, c)->_rit); !_for._break; _for._break = true) -#define piForeachC(i,c) for(_PIForeachBase & _for = _PIForeachNewC(c); !_PIForeachCastC(_for, c)->isEnd(); ++(*_PIForeachCastC(_for, c))) \ - for(const i = *(_PIForeachCastC(_for, c)->_it); !_for._break; _for._break = true) -#define piForeachCR(i,c) for(_PIForeachBase & _for = _PIForeachNewC(c, false); !_PIForeachCastC(_for, c)->isEnd(); ++(*_PIForeachCastC(_for, c))) \ - for(const i = *(_PIForeachCastC(_for, c)->_rit); !_for._break; _for._break = true) - -#endif - -#define piForeachRC piForeachCR +# define piForeachCR piForeachRC #endif // DOXYGEN diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index c5e3c1b8..945a1227 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -70,7 +70,6 @@ public: } inline PIDeque & operator =(PIDeque && other) { - if (this == &other) return *this; swap(other); return *this; } @@ -324,6 +323,12 @@ public: piSwap(pid_rsize, other.pid_rsize); piSwap(pid_start, other.pid_start); } + inline void swap(PIDeque && other) { + piSwap(pid_data, other.pid_data); + piSwap(pid_size, other.pid_size); + piSwap(pid_rsize, other.pid_rsize); + piSwap(pid_start, other.pid_start); + } typedef int (*CompareFunc)(const T * , const T * ); static int compare_func(const T * t0, const T * t1) {return (*t0) < (*t1) ? -1 : ((*t0) == (*t1) ? 0 : 1);} diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index 6939eb53..da18e4a9 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -226,6 +226,10 @@ public: pim_content.swap(other.pim_content); pim_index.swap(other.pim_index); } + void swap(PIMap && other) { + pim_content.swap(other.pim_content); + pim_index.swap(other.pim_index); + } PIMap & insert(const Key & key, const T & value) { bool f(false); diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index 1ea45b15..df2987be 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -69,7 +69,6 @@ public: } inline PIVector & operator =(PIVector && other) { - if (this == &other) return *this; swap(other); return *this; } @@ -301,6 +300,11 @@ public: piSwap(piv_size, other.piv_size); piSwap(piv_rsize, other.piv_rsize); } + inline void swap(PIVector && other) { + piSwap(piv_data, other.piv_data); + piSwap(piv_size, other.piv_size); + piSwap(piv_rsize, other.piv_rsize); + } typedef int (*CompareFunc)(const T * , const T * ); static int compare_func(const T * t0, const T * t1) {return (*t0) < (*t1) ? -1 : ((*t0) == (*t1) ? 0 : 1);} diff --git a/lib/main/core/piinit.cpp b/lib/main/core/piinit.cpp index 6063a2c5..90eacfa1 100644 --- a/lib/main/core/piinit.cpp +++ b/lib/main/core/piinit.cpp @@ -125,7 +125,7 @@ PIInit::PIInit() { piForeachC (PIString & i, ifpathes) { if (fileExists(i)) { sinfo->ifconfigPath = i; - piBreak; + break; } } # else diff --git a/lib/main/core/piobject.cpp b/lib/main/core/piobject.cpp index 9d420f6f..42af0a01 100644 --- a/lib/main/core/piobject.cpp +++ b/lib/main/core/piobject.cpp @@ -190,39 +190,42 @@ PIStringList PIObject::scopeList() const { PIStringList PIObject::methodsEH() const { PIMutexLocker ml(__meta_mutex()); PIStringList ret; - __MetaData & ehd(__meta_data()[classNameID()]); - piForeachC (__EHPair & eh, ehd.eh_func) - ret << eh.second.fullFormat(); + const __MetaData & ehd(__meta_data()[classNameID()]); + for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) + ret << eh.value().fullFormat(); return ret; } bool PIObject::isMethodEHContains(const PIString & name) const { PIMutexLocker ml(__meta_mutex()); - __MetaData & ehd(__meta_data()[classNameID()]); - piForeachC (__EHPair & eh, ehd.eh_func) - if (eh.second.func_name == name) + const __MetaData & ehd(__meta_data()[classNameID()]); + for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) { + if (eh.value().func_name == name) return true; + } return false; } PIString PIObject::methodEHArguments(const PIString & name) const { PIMutexLocker ml(__meta_mutex()); - __MetaData & ehd(__meta_data()[classNameID()]); - piForeachC (__EHPair & eh, ehd.eh_func) - if (eh.second.func_name == name) - return eh.second.arguments(); + const __MetaData & ehd(__meta_data()[classNameID()]); + for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) { + if (eh.value().func_name == name) + return eh.value().arguments(); + } return PIString(); } PIString PIObject::methodEHFullFormat(const PIString & name) const { PIMutexLocker ml(__meta_mutex()); - __MetaData & ehd(__meta_data()[classNameID()]); - piForeachC (__EHPair & eh, ehd.eh_func) - if (eh.second.func_name == name) - return eh.second.fullFormat(); + const __MetaData & ehd(__meta_data()[classNameID()]); + for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) { + if (eh.value().func_name == name) + return eh.value().fullFormat(); + } return PIString(); } @@ -234,10 +237,11 @@ PIString PIObject::methodEHFromAddr(const void * addr) const { PIVector PIObject::findEH(const PIString & name) const { PIVector<__MetaFunc> ret; - __MetaData & ehd(__meta_data()[classNameID()]); - piForeachC (__EHPair & eh, ehd.eh_func) - if (eh.second.func_name == name) - ret << eh.second; + const __MetaData & ehd(__meta_data()[classNameID()]); + for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) { + if (eh.value().func_name == name) + ret << eh.value(); + } return ret; } @@ -582,11 +586,11 @@ void PIObject::dump(const PIString & line_prefix) const { //printf("dump %d properties ok\n", properties_.size()); PICout(PICoutManipulators::AddNewLine) << line_prefix << " }"; PICout(PICoutManipulators::AddNewLine) << line_prefix << " methods {"; - __MetaData & ehd(__meta_data()[classNameID()]); + const __MetaData & ehd(__meta_data()[classNameID()]); PICout(PICoutManipulators::AddNewLine) << line_prefix << " count: " << ehd.eh_func.size_s(); //printf("dump %d methods\n", ehd.eh_func.size()); - piForeachC (__EHPair & eh, ehd.eh_func) { - PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << eh.second.fullFormat(); + for (auto eh = ehd.eh_func.constBegin(); eh != ehd.eh_func.constEnd(); eh++) { + PICout(PICoutManipulators::AddNewLine) << line_prefix << " " << eh.value().fullFormat(); } //printf("dump %d methods ok\n", ehd.eh_func.size()); PICout(PICoutManipulators::AddNewLine) << line_prefix << " }"; diff --git a/lib/main/io_devices/pibinarylog.cpp b/lib/main/io_devices/pibinarylog.cpp index 51b33dc6..c1e46d4d 100644 --- a/lib/main/io_devices/pibinarylog.cpp +++ b/lib/main/io_devices/pibinarylog.cpp @@ -96,7 +96,7 @@ bool PIBinaryLog::openDevice() { piForeachC(PIFile::FileInfo &i, es) { if (i.extension() == "binlog" && i.isFile() && i.baseName().startsWith(filePrefix())) { setPath(i.path); - piBreak; + break; } } } diff --git a/lib/main/io_devices/pipeer.cpp b/lib/main/io_devices/pipeer.cpp index 260812f6..85cc0bc3 100644 --- a/lib/main/io_devices/pipeer.cpp +++ b/lib/main/io_devices/pipeer.cpp @@ -491,7 +491,7 @@ bool PIPeer::dataRead(uchar * readed, int size) { if (p.name != from) continue; piForeach (PeerInfo::PeerAddress & a, p.addresses) { if (a.address != addr) continue; - if (a.last_ping >= time) piBreak; + if (a.last_ping >= time) break; ptime = ctime - time; a.last_ping = time; a.wait_ping = false; @@ -677,7 +677,7 @@ bool PIPeer::mbcastRead(uchar * data, int size) { if (peer.name == pi.name) peer.sync = 0; ch = true; } - piBreak; + break; } } if (exist || isRemoved(rpeer)) continue; diff --git a/lib/main/io_devices/piserial.cpp b/lib/main/io_devices/piserial.cpp index b39fad68..4c526a62 100644 --- a/lib/main/io_devices/piserial.cpp +++ b/lib/main/io_devices/piserial.cpp @@ -544,7 +544,7 @@ bool PISerial::openDevice() { piForeachC (DeviceInfo & d, devs) { if (d.id() == pl) { p = d.path; - piBreak; + break; } } if (p.isEmpty()) { diff --git a/lib/main/io_utils/piconnection.cpp b/lib/main/io_utils/piconnection.cpp index ddafa147..785c5ebf 100644 --- a/lib/main/io_utils/piconnection.cpp +++ b/lib/main/io_utils/piconnection.cpp @@ -375,20 +375,20 @@ bool PIConnection::removeDevice(const PIString & full_path) { PIStringList dntd(deviceNames(dev)); piForeachC (PIString & n, dntd) device_names.removeOne(n); - piForeachC (SPair & s, senders) { - if (s.second == 0) continue; - s.second->lock(); - s.second->devices.removeAll(dev); - s.second->unlock(); + for (auto s = senders.constBegin(); s != senders.constEnd(); s++) { + if (s.value() == 0) continue; + s.value()->lock(); + s.value()->devices.removeAll(dev); + s.value()->unlock(); } device_modes.remove(dev); - piForeachC (PEPair & i, extractors) { - if (i.second == 0) continue; - i.second->devices.removeAll(dev); + for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { + if (i.value() == 0) continue; + i.value()->devices.removeAll(dev); } bounded_extractors.remove(dev); channels_.remove(dev); - for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) + for (auto it = channels_.begin(); it != channels_.end(); it++) it.value().removeAll(dev); __device_pool__->lock(); if (diags_.value(dev, 0) != 0) @@ -404,11 +404,11 @@ void PIConnection::removeAllDevices() { PIVector bdevs(__device_pool__->boundedDevices(this)); __device_pool__->lock(); piForeach (PIIODevice * d, bdevs) { - piForeachC (SPair & s, senders) { - if (s.second == 0) continue; - s.second->lock(); - s.second->devices.removeAll(d); - s.second->unlock(); + for (auto s = senders.constBegin(); s != senders.constEnd(); s++) { + if (s.value() == 0) continue; + s.value()->lock(); + s.value()->devices.removeAll(d); + s.value()->unlock(); } channels_.remove(d); for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) @@ -421,9 +421,9 @@ void PIConnection::removeAllDevices() { __device_pool__->unlock(); device_modes.clear(); bounded_extractors.clear(); - piForeachC (PEPair & i, extractors) { - if (i.second == 0) continue; - i.second->devices.clear(); + for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { + if (i.value() == 0) continue; + i.value()->devices.clear(); } } @@ -563,15 +563,15 @@ bool PIConnection::removeFilter(const PIString & name_) { void PIConnection::removeAllFilters() { __device_pool__->lock(); - piForeachC (PEPair & i, extractors) { - if (i.second == 0) continue; - channels_.remove(i.second->extractor); + for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { + if (i.value() == 0) continue; + channels_.remove(i.value()->extractor); for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) - it.value().removeAll(i.second->extractor); - if (diags_.value(i.second->extractor, 0) != 0) - delete diags_.value(i.second->extractor); - diags_.remove(i.second->extractor); - delete i.second; + it.value().removeAll(i.value()->extractor); + if (diags_.value(i.value()->extractor, 0) != 0) + delete diags_.value(i.value()->extractor); + diags_.remove(i.value()->extractor); + delete i.value(); } extractors.clear(); bounded_extractors.clear(); @@ -581,28 +581,31 @@ void PIConnection::removeAllFilters() { PIVector PIConnection::filters() const { PIVector ret; - piForeachC (PEPair & i, extractors) - if (i.second != 0) - if (i.second->extractor != 0) ret << i.second->extractor; + for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { + if (i.value() != 0) + if (i.value()->extractor != 0) ret << i.value()->extractor; + } return ret; } PIStringList PIConnection::filterNames() const { PIStringList ret; - piForeachC (PEPair & i, extractors) - if (i.second != 0) - if (i.second->extractor != 0) ret << i.first; + for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { + if (i.value() != 0) + if (i.value()->extractor != 0) ret << i.key(); + } return ret; } PIPacketExtractor * PIConnection::filter(const PIString & name_) const { PIString fname_ = name_.trimmed(); - piForeachC (PEPair & i, extractors) - if (i.second != 0) - if (i.second->extractor != 0 && i.first == fname_) - return i.second->extractor; + for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { + if (i.value() != 0) + if (i.value()->extractor != 0 && i.key() == fname_) + return i.value()->extractor; + } return 0; } @@ -784,9 +787,10 @@ float PIConnection::senderFrequency(const PIString & name) const { void PIConnection::removeAllSenders() { - piForeachC (SPair & s, senders) - if (s.second != 0) - delete s.second; + for (auto s = senders.constBegin(); s != senders.constEnd(); s++) { + if (s.value() != 0) + delete s.value(); + } senders.clear(); } @@ -802,8 +806,8 @@ void PIConnection::startThreadedRead(const PIString & full_path_name) { void PIConnection::startAllThreadedReads() { - piForeachC (DevicePool::DDPair & d, __device_pool__->devices) - startThreadedRead(d.first); + for (auto d = __device_pool__->devices.constBegin(); d != __device_pool__->devices.constEnd(); d++) + startThreadedRead(d.key()); } @@ -816,10 +820,10 @@ void PIConnection::startSender(const PIString & name) { void PIConnection::startAllSenders() { - piForeachC (SPair & s, senders) { - if (s.second == 0) continue; - if (!s.second->isRunning() && !__device_pool__->fake) - s.second->start(s.second->int_); + for (auto s = senders.constBegin(); s != senders.constEnd(); s++) { + if (s.value() == 0) continue; + if (!s.value()->isRunning() && !__device_pool__->fake) + s.value()->start(s.value()->int_); } } @@ -835,8 +839,8 @@ void PIConnection::stopThreadedRead(const PIString & full_path_name) { void PIConnection::stopAllThreadedReads() { - piForeachC (DevicePool::DDPair & d, __device_pool__->devices) - stopThreadedRead(d.first); + for (auto d = __device_pool__->devices.constBegin(); d != __device_pool__->devices.constEnd(); d++) + stopThreadedRead(d.key()); } @@ -848,10 +852,10 @@ void PIConnection::stopSender(const PIString & name) { void PIConnection::stopAllSenders() { - piForeachC (SPair & s, senders) { - if (s.second == 0) continue; - if (s.second->isRunning()) - s.second->stop(); + for (auto s = senders.constBegin(); s != senders.constEnd(); s++) { + if (s.value() == 0) continue; + if (s.value()->isRunning()) + s.value()->stop(); } } @@ -1012,14 +1016,14 @@ bool PIConnection::DevicePool::removeDevice(PIConnection * parent, const PIStrin void PIConnection::DevicePool::unboundConnection(PIConnection * parent) { PIStringList rem; - piForeachC (DDPair & i, devices) { - if (i.second == 0) { - rem << i.first; + for (auto i = devices.constBegin(); i != devices.constEnd(); i++) { + if (i.value() == 0) { + rem << i.key(); continue; } - i.second->listeners.removeAll(parent); - if (i.second->listeners.isEmpty()) - rem << i.first; + i.value()->listeners.removeAll(parent); + if (i.value()->listeners.isEmpty()) + rem << i.key(); } piForeachC (PIString & i, rem) { DeviceData * dd = devices.value(i); @@ -1105,9 +1109,9 @@ PIConnection::DevicePool::DeviceData::~DeviceData() { void PIConnection::DevicePool::run() { PIVector conns(PIConnection::allConnections()); piForeach (PIConnection * c, conns) { - piForeachC (PIConnection::DPair & d, c->diags_) { - if (d.second == 0) continue; - d.second->tick(0, 1); + for (auto d = c->diags_.constBegin(); d != c->diags_.constEnd(); d++) { + if (d.value() == 0) continue; + d.value()->tick(0, 1); } } } diff --git a/lib/main/thread/piblockingdequeue.h b/lib/main/thread/piblockingdequeue.h index fe8f5a1f..27e23572 100644 --- a/lib/main/thread/piblockingdequeue.h +++ b/lib/main/thread/piblockingdequeue.h @@ -164,7 +164,7 @@ public: T t; mutex.lock(); bool isNotEmpty = !PIDeque::isEmpty(); - t = isNotEmpty ? T(PIDeque::take_front()) : defaultVal; + t = isNotEmpty ? PIDeque::take_front() : defaultVal; mutex.unlock(); if (isNotEmpty) cond_var_rem->notifyOne(); if (isOk) *isOk = isNotEmpty; diff --git a/main.cpp b/main.cpp index 5bc395f7..cbcedb6b 100644 --- a/main.cpp +++ b/main.cpp @@ -34,17 +34,22 @@ int main() { #include "picodeparser.h" int main() { - piDebug = false; + //piDebug = false; double min = -1, max = -1, mean = 0; - for (int i = 0; i < 50; ++i) { + for (int i = 0; i < 1; ++i) { PITimeMeasurer tm; /*PICodeParser cp; cp.parseFile("SH_plugin_base.h");*/ PIStringList sl; - for (int i = 0; i < 5000; ++i) { - //PIString s("1234567890-="); - //sl << s; - sl << PIString("1234567890-="); + sl.reserve(10); + for (int i = 0; i < 10; ++i) { + //PIString s = PIString("1234567890-=").repeated(100); + //sl.push_back(PIString("1234567890-=").repeated(100)); + sl << PIString("abc").repeated(i + 1); + } + for (PIString & s : sl) { + s = s.toUpperCase(); + piCout << s; } double ms = tm.elapsed_m(); if (min < 0) min = ms; diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index 6cb26cbf..7bff7667 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -218,7 +218,7 @@ void writeClassStreamMembersOut(PIFile & f, const PICodeParser::Entity * e, int f << "));\n"; } if (is_union) - piBreak; + break; } if (is_union) return; piForeachC (PICodeParser::Entity * ce, e->children) { @@ -261,7 +261,7 @@ void writeClassStreamMembersIn(PIFile & f, const PICodeParser::Entity * e, int & f << "\t\t\tbreak;\n"; } if (is_union) - piBreak; + break; } if (is_union) return; piForeachC (PICodeParser::Entity * ce, e->children) { diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index 88019be2..46badca3 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -370,7 +370,7 @@ void procQt() { } } } - piBreak; + break; } } } diff --git a/utils/system_daemon/main.cpp b/utils/system_daemon/main.cpp index b1ed08d4..85900bd1 100755 --- a/utils/system_daemon/main.cpp +++ b/utils/system_daemon/main.cpp @@ -192,11 +192,10 @@ public: addrs_tl->content << TileList::Row(a.address.toString() + " | p = " + PIString::fromNumber(a.ping) + " | a = " + PIString::fromBool(a.isAvailable()), CellFormat()); - typedef PIPair > PeerPair; PIStringList peermap; - piForeachC(PeerPair &p , daemon_._peerMap()) { - PIString s = p.first + " | "; - piForeachCR(PIPeer::PeerInfo * pp, p.second) s += " -> " + pp->name; + for (auto p = daemon_._peerMap().constBegin(); p != daemon_._peerMap().constEnd(); p++) { + PIString s = p.key() + " | "; + piForeachCR(PIPeer::PeerInfo * pp, p.value()) s += " -> " + pp->name; peermap << s; } piForeachC(PIString &s , peermap) From 52062e6ccdabb3d84492898c5a8291a71275097f Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 30 Jul 2020 20:30:24 +0300 Subject: [PATCH 18/68] move operators works --- lib/main/containers/pideque.h | 10 +++++----- lib/main/containers/pivector.h | 10 +++++----- main.cpp | 18 +++++++----------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index 945a1227..770c123e 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -278,7 +278,7 @@ public: memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); } PIINTROSPECTION_CONTAINER_USED(T, 1) - elementNew(pid_data + pid_start + index, v); + elementNew(pid_data + pid_start + index, std::move(v)); return *this; } inline PIDeque & insert(size_t index, const PIDeque & other) { @@ -370,11 +370,11 @@ public: inline PIDeque & push_back(T && v) { alloc(pid_size + 1, true); PIINTROSPECTION_CONTAINER_USED(T, 1); - elementNew(pid_data + pid_start + pid_size - 1, v); + elementNew(pid_data + pid_start + pid_size - 1, std::move(v)); return *this; } inline PIDeque & append(const T & v) {return push_back(v);} - inline PIDeque & append(T && v) {return push_back(v);} + inline PIDeque & append(T && v) {return push_back(std::move(v));} inline PIDeque & append(const PIDeque & t) { assert(&t != this); size_t ps = pid_size; @@ -383,7 +383,7 @@ public: return *this; } inline PIDeque & operator <<(const T & v) {return push_back(v);} - inline PIDeque & operator <<(T && v) {return push_back(v);} + inline PIDeque & operator <<(T && v) {return push_back(std::move(v));} inline PIDeque & operator <<(const PIDeque & t) {return append(t);} inline PIDeque & push_front(const T & v) {insert(0, v); return *this;} @@ -451,7 +451,7 @@ private: } } inline void elementNew(T * to, const T & from) {new(to)T(from);} - inline void elementNew(T * to, T && from) {piSwap(*to, from);} + inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} inline void elementDelete(T & from) {from.~T();} inline void dealloc() { if ((uchar*)pid_data != 0) free((uchar*)pid_data); diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index df2987be..7b3e3982 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -268,7 +268,7 @@ public: memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); } PIINTROSPECTION_CONTAINER_USED(T, 1) - elementNew(piv_data + index, v); + elementNew(piv_data + index, std::move(v)); return *this; } inline PIVector & insert(size_t index, const PIVector & other) { @@ -346,11 +346,11 @@ public: inline PIVector & push_back(T && v) { alloc(piv_size + 1); PIINTROSPECTION_CONTAINER_USED(T, 1); - elementNew(piv_data + piv_size - 1, v); + elementNew(piv_data + piv_size - 1, std::move(v)); return *this; } inline PIVector & append(const T & v) {return push_back(v);} - inline PIVector & append(T && v) {return push_back(v);} + inline PIVector & append(T && v) {return push_back(std::move(v));} inline PIVector & append(const PIVector & other) { assert(&other != this); size_t ps = piv_size; @@ -359,7 +359,7 @@ public: return *this; } inline PIVector & operator <<(const T & v) {return push_back(v);} - inline PIVector & operator <<(T && v) {return push_back(v);} + inline PIVector & operator <<(T && v) {return push_back(std::move(v));} inline PIVector & operator <<(const PIVector & other) {return append(other);} inline PIVector & push_front(const T & v) {insert(0, v); return *this;} @@ -436,7 +436,7 @@ private: } } inline void elementNew(T * to, const T & from) {new(to)T(from);} - inline void elementNew(T * to, T && from) {piSwap(*to, from);} + inline void elementNew(T * to, T && from) {new(to)T(std::move(from));} inline void elementDelete(T & from) {from.~T();} inline void dealloc() { if ((uchar*)piv_data != 0) free((uchar*)piv_data); diff --git a/main.cpp b/main.cpp index cbcedb6b..7832f59b 100644 --- a/main.cpp +++ b/main.cpp @@ -34,22 +34,18 @@ int main() { #include "picodeparser.h" int main() { - //piDebug = false; + piDebug = false; double min = -1, max = -1, mean = 0; - for (int i = 0; i < 1; ++i) { + for (int i = 0; i < 50; ++i) { PITimeMeasurer tm; /*PICodeParser cp; cp.parseFile("SH_plugin_base.h");*/ PIStringList sl; - sl.reserve(10); - for (int i = 0; i < 10; ++i) { - //PIString s = PIString("1234567890-=").repeated(100); - //sl.push_back(PIString("1234567890-=").repeated(100)); - sl << PIString("abc").repeated(i + 1); - } - for (PIString & s : sl) { - s = s.toUpperCase(); - piCout << s; + sl.reserve(50000); + for (int i = 0; i < 50000; ++i) { +// PIString s("1234567890-="); + sl.push_back(PIString("1234567890-=")); + //sl << PIString("1234567890-="); } double ms = tm.elapsed_m(); if (min < 0) min = ms; From a12e63e5696861884ca1a75e3ab23b192b028b3f Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 30 Jul 2020 20:41:38 +0300 Subject: [PATCH 19/68] PIStringList move operator fix --- lib/main/core/pistringlist.h | 2 +- main.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/main/core/pistringlist.h b/lib/main/core/pistringlist.h index 6e81f034..141b1478 100644 --- a/lib/main/core/pistringlist.h +++ b/lib/main/core/pistringlist.h @@ -83,7 +83,7 @@ public: PIStringList & operator =(const PIStringList & o) {PIDeque::operator=(o); return *this;} PIStringList & operator <<(const PIString & str) {append(str); return *this;} - PIStringList & operator <<(PIString && str) {append(str); return *this;} + PIStringList & operator <<(PIString && str) {append(std::move(str)); return *this;} PIStringList & operator <<(const PIStringList & sl) {append(sl); return *this;} }; diff --git a/main.cpp b/main.cpp index 7832f59b..8e7a86b4 100644 --- a/main.cpp +++ b/main.cpp @@ -41,11 +41,12 @@ int main() { /*PICodeParser cp; cp.parseFile("SH_plugin_base.h");*/ PIStringList sl; - sl.reserve(50000); - for (int i = 0; i < 50000; ++i) { -// PIString s("1234567890-="); - sl.push_back(PIString("1234567890-=")); - //sl << PIString("1234567890-="); + sl.reserve(500000); + for (int i = 0; i < 500000; ++i) { + //PIString s("1234567890-="); + //sl << s; + //sl.push_back(PIString("1234567890-=")); + sl << PIString("1234567890-="); } double ms = tm.elapsed_m(); if (min < 0) min = ms; From 79e17b48b8d6e85859d1b85decbb51aa7ed39368 Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 30 Jul 2020 22:26:05 +0300 Subject: [PATCH 20/68] rvalue functions for containers --- lib/main/containers/pideque.h | 17 +++++++---------- lib/main/containers/pimap.h | 22 +++++++++++++++------- lib/main/containers/piqueue.h | 6 ++++-- lib/main/containers/piset.h | 1 + lib/main/containers/pistack.h | 9 ++++++++- lib/main/containers/pivector.h | 16 +++++++--------- lib/main/containers/pivector2d.h | 9 +++++---- lib/main/core/pistring.h | 6 +++--- lib/main/core/pistringlist.h | 7 ++++++- main.cpp | 9 +++++---- 10 files changed, 61 insertions(+), 41 deletions(-) diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index 770c123e..259b997e 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -49,8 +49,8 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(pid_size, f); } - inline PIDeque(PIDeque && other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { - swap(other); + inline PIDeque(PIDeque && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_size), pid_start(other.pid_start) { + other._reset(); } inline virtual ~PIDeque() { //piCout << "~PIDeque"; @@ -70,7 +70,8 @@ public: } inline PIDeque & operator =(PIDeque && other) { - swap(other); + PIDeque moved(std::move(other)); + swap(moved); return *this; } @@ -323,12 +324,6 @@ public: piSwap(pid_rsize, other.pid_rsize); piSwap(pid_start, other.pid_start); } - inline void swap(PIDeque && other) { - piSwap(pid_data, other.pid_data); - piSwap(pid_size, other.pid_size); - piSwap(pid_rsize, other.pid_rsize); - piSwap(pid_start, other.pid_start); - } typedef int (*CompareFunc)(const T * , const T * ); static int compare_func(const T * t0, const T * t1) {return (*t0) < (*t1) ? -1 : ((*t0) == (*t1) ? 0 : 1);} @@ -387,7 +382,9 @@ public: inline PIDeque & operator <<(const PIDeque & t) {return append(t);} inline PIDeque & push_front(const T & v) {insert(0, v); return *this;} + inline PIDeque & push_front(T && v) {insert(0, std::move(v)); return *this;} inline PIDeque & prepend(const T & v) {return push_front(v);} + inline PIDeque & prepend(T && v) {return push_front(std::move(v));} inline PIDeque & pop_back() {if (pid_size == 0) return *this; resize(pid_size - 1); return *this;} inline PIDeque & pop_front() {if (pid_size == 0) return *this; remove(0); return *this;} @@ -525,7 +522,7 @@ private: template<> inline void PIDeque::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIDeque::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIDeque::elementNew(T * to, const T & from) {(*to) = from;} \ - template<> inline void PIDeque::elementNew(T * to, T && from) {(*to) = from;} \ + template<> inline void PIDeque::elementNew(T * to, T && from) {(*to) = std::move(from);} \ template<> inline void PIDeque::elementDelete(T &) {;} \ template<> inline PIDeque & PIDeque::_resizeRaw(size_t new_size) { \ if (new_size > pid_size) { \ diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index da18e4a9..6cf4b5c4 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -74,7 +74,7 @@ class PIMap { public: PIMap() {;} PIMap(const PIMap & other) {*this = other;} - PIMap(PIMap && other) {swap(other);} + PIMap(PIMap && other) : pim_content(std::move(other.pim_content)), pim_index(std::move(other.pim_index)) {} virtual ~PIMap() {;} PIMap & operator =(const PIMap & other) { @@ -86,8 +86,8 @@ public: } PIMap & operator =(PIMap && other) { - if (this == &other) return *this; - swap(other); + PIMap moved(std::move(other)); + swap(moved); return *this; } @@ -226,10 +226,6 @@ public: pim_content.swap(other.pim_content); pim_index.swap(other.pim_index); } - void swap(PIMap && other) { - pim_content.swap(other.pim_content); - pim_index.swap(other.pim_index); - } PIMap & insert(const Key & key, const T & value) { bool f(false); @@ -243,6 +239,18 @@ public: } return *this; } + PIMap & insert(const Key & key, T && value) { + bool f(false); + ssize_t i = _find(key, f); + //piCout << "insert key=" << key << "found=" << f << "index=" << i << "value=" << value; + if (f) { + pim_content[pim_index[i].index] = std::move(value); + } else { + pim_content.push_back(std::move(value)); + pim_index.insert(i, MapIndex(key, pim_content.size() - 1)); + } + return *this; + } const T value(const Key & key, const T & default_ = T()) const {bool f(false); ssize_t i = _find(key, f); if (!f) return default_; return pim_content[pim_index[i].index];} PIVector values() const {return pim_content;} Key key(const T & value_, const Key & default_ = Key()) const {for (int i = 0; i < pim_index.size_s(); ++i) if (pim_content[pim_index[i].index] == value_) return pim_index[i].key; return default_;} diff --git a/lib/main/containers/piqueue.h b/lib/main/containers/piqueue.h index 60612797..cebd1d76 100644 --- a/lib/main/containers/piqueue.h +++ b/lib/main/containers/piqueue.h @@ -35,13 +35,15 @@ public: PIQueue() {} virtual ~PIQueue() {} PIDeque & enqueue(const T & v) {PIDeque::push_front(v); return *this;} + PIDeque & enqueue(T && v) {PIDeque::push_front(std::move(v)); return *this;} T dequeue() {return PIDeque::take_back();} T & head() {return PIDeque::back();} const T & head() const {return PIDeque::back();} PIVector toVector() { - PIVector v(PIDeque::size()); + PIVector v; + v.reserve(PIDeque::size()); for (uint i = 0; i < PIDeque::size(); ++i) - v[i] = PIDeque::at(i); + v.push_back(PIDeque::at(i)); return v; } }; diff --git a/lib/main/containers/piset.h b/lib/main/containers/piset.h index 795124ac..5a819f78 100644 --- a/lib/main/containers/piset.h +++ b/lib/main/containers/piset.h @@ -75,6 +75,7 @@ public: typedef T key_type; PISet & operator <<(const T & t) {_CSet::insert(t, 0); return *this;} + PISet & operator <<(T && t) {_CSet::insert(std::move(t), 0); return *this;} PISet & operator <<(const PISet & other) {(*(_CSet*)this) << *((_CSet*)&other); return *this;} //! Returns if element "t" exists in this set diff --git a/lib/main/containers/pistack.h b/lib/main/containers/pistack.h index 9cbd072b..02e62318 100644 --- a/lib/main/containers/pistack.h +++ b/lib/main/containers/pistack.h @@ -33,10 +33,17 @@ public: PIStack() {;} virtual ~PIStack() {;} PIVector & push(const T & v) {PIVector::push_back(v); return *this;} + PIVector & push(T && v) {PIVector::push_back(std::move(v)); return *this;} T pop() {return PIVector::take_back();} T & top() {return PIVector::back();} const T & top() const {return PIVector::back();} - PIVector toVector() {PIVector v(PIVector::size()); for (uint i = 0; i < PIVector::size(); ++i) v[i] = PIVector::at(i); return v;} + PIVector toVector() { + PIVector v; + v.reserve(PIVector::size()); + for (uint i = 0; i < PIVector::size(); ++i) + v.push_back(PIVector::at(i)); + return v; + } }; #endif // PISTACK_H diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index 7b3e3982..017e0f73 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -48,8 +48,8 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(piv_size, f); } - inline PIVector(PIVector && other): piv_data(0), piv_size(0), piv_rsize(0) { - swap(other); + inline PIVector(PIVector && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_size) { + other._reset(); } inline virtual ~PIVector() { PIINTROSPECTION_CONTAINER_DELETE(T) @@ -69,7 +69,8 @@ public: } inline PIVector & operator =(PIVector && other) { - swap(other); + PIVector moved(std::move(other)); + swap(moved); return *this; } @@ -300,11 +301,6 @@ public: piSwap(piv_size, other.piv_size); piSwap(piv_rsize, other.piv_rsize); } - inline void swap(PIVector && other) { - piSwap(piv_data, other.piv_data); - piSwap(piv_size, other.piv_size); - piSwap(piv_rsize, other.piv_rsize); - } typedef int (*CompareFunc)(const T * , const T * ); static int compare_func(const T * t0, const T * t1) {return (*t0) < (*t1) ? -1 : ((*t0) == (*t1) ? 0 : 1);} @@ -363,7 +359,9 @@ public: inline PIVector & operator <<(const PIVector & other) {return append(other);} inline PIVector & push_front(const T & v) {insert(0, v); return *this;} + inline PIVector & push_front(T && v) {insert(0, std::move(v)); return *this;} inline PIVector & prepend(const T & v) {return push_front(v);} + inline PIVector & prepend(T && v) {return push_front(std::move(v));} inline PIVector & pop_back() { if (piv_size == 0) @@ -466,7 +464,7 @@ private: template<> inline void PIVector::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIVector::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIVector::elementNew(T * to, const T & from) {(*to) = from;} \ - template<> inline void PIVector::elementNew(T * to, T && from) {(*to) = from;} \ + template<> inline void PIVector::elementNew(T * to, T && from) {(*to) = std::move(from);} \ template<> inline void PIVector::elementDelete(T &) {;} \ template<> inline PIVector & PIVector::_resizeRaw(size_t new_size) { \ if (new_size > piv_size) { \ diff --git a/lib/main/containers/pivector2d.h b/lib/main/containers/pivector2d.h index 744316af..f573439f 100644 --- a/lib/main/containers/pivector2d.h +++ b/lib/main/containers/pivector2d.h @@ -44,10 +44,10 @@ public: cols_ = cols; mat.resize(rows*cols, f); } - inline PIVector2D(size_t rows, size_t cols, const PIVector & v) { - mat = v; - rows_ = rows; - cols_ = cols; + inline PIVector2D(size_t rows, size_t cols, const PIVector & v) : rows_(rows), cols_(cols), mat(v) { + mat.resize(rows*cols); + } + inline PIVector2D(size_t rows, size_t cols, PIVector && v) : rows_(rows), cols_(cols), mat(std::move(v)) { mat.resize(rows*cols); } inline PIVector2D(const PIVector > & v) { @@ -236,6 +236,7 @@ public: PIVector > toVectors() const { PIVector > ret; + ret.reserve(rows_); for(size_t i = 0; i < rows_; ++i) ret << PIVector(mat.data(i*cols_), cols_); return ret; diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index 00c87197..bbc8543a 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -49,9 +49,9 @@ public: PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s(), __utf8name__); return *this;} PIString & operator +=(const PIString & str); - PIString(const PIString & o): PIDeque() {*this += o;} + PIString(const PIString & o): PIDeque(o) {} - PIString(PIString && o): PIDeque() {swap(o);} + PIString(PIString && o): PIDeque(std::move(o)) {} //! Contructs string with single symbol "c" @@ -91,7 +91,7 @@ public: PIString & operator =(const PIString & o) {if (this == &o) return *this; clear(); *this += o; return *this;} - PIString & operator =(PIString && o) {if (this == &o) return *this; swap(o); return *this;} + PIString & operator =(PIString && o) {PIString moved(std::move(o)); swap(moved); return *this;} /*! \brief Return c-string representation of string * \details Converts content of string to c-string and return diff --git a/lib/main/core/pistringlist.h b/lib/main/core/pistringlist.h index 141b1478..e5a9210e 100644 --- a/lib/main/core/pistringlist.h +++ b/lib/main/core/pistringlist.h @@ -37,17 +37,22 @@ public: //! Contructs strings list with one string "str" PIStringList(const PIString & str) {push_back(str);} + PIStringList(PIString && str) {push_back(std::move(str));} //! Contructs empty strings list with strings "s0" and "s1" PIStringList(const PIString & s0, const PIString & s1) {push_back(s0); push_back(s1);} + PIStringList(PIString && s0, PIString && s1) {push_back(std::move(s0)); push_back(std::move(s1));} //! Contructs empty strings list with strings "s0", "s1" and "s2" PIStringList(const PIString & s0, const PIString & s1, const PIString & s2) {push_back(s0); push_back(s1); push_back(s2);} + PIStringList(PIString && s0, PIString && s1, PIString && s2) {push_back(std::move(s0)); push_back(std::move(s1)); push_back(std::move(s2));} //! Contructs empty strings list with strings "s0", "s1", "s2" and "s3" PIStringList(const PIString & s0, const PIString & s1, const PIString & s2, const PIString & s3) {push_back(s0); push_back(s1); push_back(s2); push_back(s3);} + PIStringList(PIString && s0, PIString && s1, PIString && s2, PIString && s3) {push_back(std::move(s0)); push_back(std::move(s1)); push_back(std::move(s2)); push_back(std::move(s3));} - PIStringList(const PIStringList & o): PIDeque() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];} + PIStringList(const PIStringList & o): PIDeque(o) {} + PIStringList(PIStringList && o): PIDeque(std::move(o)) {} PIStringList(const PIVector & o): PIDeque() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];} PIStringList(const PIDeque & o): PIDeque() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];} diff --git a/main.cpp b/main.cpp index 8e7a86b4..dbabd1f9 100644 --- a/main.cpp +++ b/main.cpp @@ -35,6 +35,7 @@ int main() { #include "picodeparser.h" int main() { piDebug = false; + PIString t("1234567890-="); double min = -1, max = -1, mean = 0; for (int i = 0; i < 50; ++i) { PITimeMeasurer tm; @@ -43,10 +44,10 @@ int main() { PIStringList sl; sl.reserve(500000); for (int i = 0; i < 500000; ++i) { - //PIString s("1234567890-="); - //sl << s; - //sl.push_back(PIString("1234567890-=")); - sl << PIString("1234567890-="); +// PIString s(t); +// sl << s; + sl.push_back(PIString(t)); + //sl << PIString("1234567890-="); } double ms = tm.elapsed_m(); if (min < 0) min = ms; From 1d5c979607f88870e6501225aa8656b24f7c0b33 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 31 Jul 2020 00:00:26 +0300 Subject: [PATCH 21/68] fix bug in move constructor --- CMakeLists.txt | 2 +- lib/main/containers/pideque.h | 7 ++----- lib/main/containers/pimap.h | 3 +-- lib/main/containers/pivector.h | 5 ++--- lib/main/core/pistring.h | 2 +- main.cpp | 31 +++++++++++++++++++++++-------- 6 files changed, 30 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2fcbe46b..f530f135 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ set(PIP_UTILS 1) if(LIBPROJECT) set(PIP_UTILS ${UTILS}) endif() -set(CMAKE_CXX_STANDARD_REQUIRED 1) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) set(CMAKE_CXX_STANDARD 11) diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index 259b997e..6efead6f 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -32,7 +32,6 @@ template class PIDeque { public: inline PIDeque(): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { - //piCout << "PIDeque"; PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) } inline PIDeque(const PIDeque & other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { @@ -49,11 +48,10 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(pid_size, f); } - inline PIDeque(PIDeque && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_size), pid_start(other.pid_start) { + inline PIDeque(PIDeque && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) { other._reset(); } inline virtual ~PIDeque() { - //piCout << "~PIDeque"; PIINTROSPECTION_CONTAINER_DELETE(T) PIINTROSPECTION_CONTAINER_FREE(T, (pid_rsize)) deleteT(pid_data + pid_start, pid_size); @@ -70,8 +68,7 @@ public: } inline PIDeque & operator =(PIDeque && other) { - PIDeque moved(std::move(other)); - swap(moved); + swap(other); return *this; } diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index 6cf4b5c4..7a5486fe 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -86,8 +86,7 @@ public: } PIMap & operator =(PIMap && other) { - PIMap moved(std::move(other)); - swap(moved); + swap(other); return *this; } diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index 017e0f73..e41aeaea 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -48,7 +48,7 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(piv_size, f); } - inline PIVector(PIVector && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_size) { + inline PIVector(PIVector && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) { other._reset(); } inline virtual ~PIVector() { @@ -69,8 +69,7 @@ public: } inline PIVector & operator =(PIVector && other) { - PIVector moved(std::move(other)); - swap(moved); + swap(other); return *this; } diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index bbc8543a..0fb7bedd 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -91,7 +91,7 @@ public: PIString & operator =(const PIString & o) {if (this == &o) return *this; clear(); *this += o; return *this;} - PIString & operator =(PIString && o) {PIString moved(std::move(o)); swap(moved); return *this;} + PIString & operator =(PIString && o) {swap(o); return *this;} /*! \brief Return c-string representation of string * \details Converts content of string to c-string and return diff --git a/main.cpp b/main.cpp index dbabd1f9..923d74ee 100644 --- a/main.cpp +++ b/main.cpp @@ -31,23 +31,38 @@ int main() { } #endif */ +class db { +public: + db() { + for (int i=0; i<1000; ++i) + x << sin(double(i)/180.0); + printf("jkfkhg\n"); + } +// db(const db & d) {x = d.x;} +// db(db && o) {x.swap(o.x);} +private: + PIVector x; +}; #include "picodeparser.h" int main() { piDebug = false; - PIString t("1234567890-="); + printf("==============\n"); double min = -1, max = -1, mean = 0; for (int i = 0; i < 50; ++i) { PITimeMeasurer tm; /*PICodeParser cp; cp.parseFile("SH_plugin_base.h");*/ - PIStringList sl; - sl.reserve(500000); - for (int i = 0; i < 500000; ++i) { -// PIString s(t); -// sl << s; - sl.push_back(PIString(t)); - //sl << PIString("1234567890-="); + PIVector sl; + sl.reserve(10000); + db d; + for (int i = 0; i < 10000; ++i) { +// db b(d); +// db c(b); +// c = b; +// sl << c; + sl << db(d); +// sl << std::move(d); } double ms = tm.elapsed_m(); if (min < 0) min = ms; From e728b30e5e7fe02e273c47e890e054a18a4278dc Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 31 Jul 2020 14:12:47 +0300 Subject: [PATCH 22/68] PIString hard optimization --- lib/main/code/picodeparser.cpp | 294 ++++++++++++++-------------- lib/main/core/pistring.cpp | 151 +++++++++----- lib/main/core/pistring.h | 88 +++++---- lib/main/io_devices/pifile.cpp | 2 +- lib/main/io_devices/piiodevice.cpp | 2 +- main.cpp | 25 +-- utils/code_model_generator/main.cpp | 14 +- 7 files changed, 318 insertions(+), 258 deletions(-) diff --git a/lib/main/code/picodeparser.cpp b/lib/main/code/picodeparser.cpp index 8d26d1fe..d4301feb 100644 --- a/lib/main/code/picodeparser.cpp +++ b/lib/main/code/picodeparser.cpp @@ -24,7 +24,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { PIStringList arg_vals; while (!args_.isEmpty()) { - int ci = args_.find(","), bi = args_.find("("); + int ci = args_.find(','), bi = args_.find('('); if (ci < 0) { arg_vals << args_; break; @@ -33,7 +33,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { if (bi >= 0 && bi < ci) { ca = args_.left(args_.takeLeft(bi).toInt()); ci -= ca.size_s(); bi -= ca.size_s(); - ca += "(" + args_.takeRange("(", ")") + ")"; + ca += '(' + args_.takeRange('(', ')') + ')'; } else { ca = args_.takeLeft(ci); } @@ -41,7 +41,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { args_.trim(); args_.takeLeft(1); args_.trim(); } if (args.size() != arg_vals.size()) { - piCout << ("Error: in expansion of macro \"" + name + "(" + args.join(", ") + ")\": expect") + piCout << ("Error: in expansion of macro \"" + name + '(' + args.join(", ") + ")\": expect") << args.size() << "arguments but takes" << arg_vals.size() << "!"; if (ok != 0) *ok = false; return PIString(); @@ -57,7 +57,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { if (ind + an.size_s() < ret.size_s()) nc = ret.mid(ind + an.size_s(),1)[0]; if (ppc != '#' && pc == '#' && !_isCChar(nc)) { // to chars ind--; - ret.replace(ind, an.size_s() + 1, "\"" + av + "\""); + ret.replace(ind, an.size_s() + 1, '\"' + av + '\"'); ind -= an.size_s() - av.size_s() - 1; continue; } @@ -66,7 +66,7 @@ PIString PICodeParser::Macro::expand(PIString args_, bool * ok) const { ind -= an.size_s() - av.size_s(); } } - ret.replaceAll("##", ""); + ret.replaceAll(PIStringAscii("##"), ""); if (ok != 0) *ok = true; return ret; } @@ -99,20 +99,20 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) { } piCout << "\n\nDefines:"; piForeachC (Define & m, defines) - piCout << "define" << m.first << m.second; + piCout << PIStringAscii("define") << m.first << m.second; piCout << "\n\nMacros:"; piForeachC (Macro & m, macros) piCout << "Macro:" << m.name << m.args << m.value; piCout << "\n\nClasses:"; piCout << "\n\nEnums:"; piForeachC (Enum & c, enums) { - piCout << "enum" << c.name << c.meta; + piCout << PIStringAscii("enum") << c.name << c.meta; piForeachC (EnumeratorInfo & e, c.members) piCout << " " << e.name << "=" << e.value << e.meta; } piCout << "\n\nTypedefs:"; piForeachC (Typedef & c, typedefs) - piCout << "typedef" << c;*/ + piCout << PIStringAscii("typedef") << c;*/ } @@ -122,19 +122,19 @@ void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) parseFileInternal(f, follow_includes); /*piCout << "\n\nDefines:"; piForeachC (Define & m, defines) - piCout << "define" << m.first << m.second; + piCout << PIStringAscii("define") << m.first << m.second; piCout << "\n\nMacros:"; piForeachC (Macro & m, macros) piCout << "Macro:" << m.name << m.args << m.value; piCout << "\n\nClasses:"; piForeachC (Entity * c, entities) - piCout << "class" << c->name << c->parents; + piCout << PIStringAscii("class") << c->name << c->parents; piCout << "\n\nEnums:"; piForeachC (Enum & c, enums) - piCout << "enum" << c.name << c.members; + piCout << PIStringAscii("enum") << c.name << c.members; piCout << "\n\nTypedefs:"; piForeachC (Typedef & c, typedefs) - piCout << "typedef" << c;*/ + piCout << PIStringAscii("typedef") << c;*/ } @@ -153,7 +153,7 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes PIFile f(file, PIIODevice::ReadOnly); int ii = 0; while (!f.isOpened() && ii < (includes.size_s() - 1)) { - f.setPath(includes[++ii] + "/" + file); + f.setPath(includes[++ii] + '/' + file); //piCout << "try" << f.path(); f.open(PIIODevice::ReadOnly); } @@ -186,7 +186,7 @@ void PICodeParser::clear() { evaluator.clearCustomVariables(); cur_def_vis = Global; anon_num = 0; - defines << Define("PICODE", "") << custom_defines; + defines << Define(PIStringAscii("PICODE"), "") << custom_defines; } @@ -197,9 +197,9 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { PIString pfc, line, ccmn, tmp; PIMap cchars; - /// Remove comments, join multiline "*" and replace "*" to $n (cchars) - fc.replaceAll("\r\n", "\n"); - fc.replaceAll("\r", "\n"); + /// Remove comments, join multiline '*' and replace '*' to $n (cchars) + fc.replaceAll("\r\n", '\n'); + fc.replaceAll('\r', '\n'); for (int i = 0; i < fc.size_s() - 1; ++i) { if (fc[i].unicode16Code() >= 255) continue; if (i > 0) pc = c; @@ -256,7 +256,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { if (ind + m.name.size_s() < pfc.size_s()) nc = pfc.mid(ind + m.name.size_s(),1)[0]; if (_isCChar(pc) || _isCChar(nc) || nc.isDigit()) continue; PIString ret, range; bool ok(false); - range = pfc.mid(ind + m.name.size_s()).takeRange("(", ")"); + range = pfc.mid(ind + m.name.size_s()).takeRange('(', ')'); ret = m.expand(range, &ok); if (!ok) return false; int rlen = pfc.find(range, ind + m.name.size_s()) + range.size_s() + 1 - ind; @@ -275,20 +275,20 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { if (pl == nl) break; pl = nl; if (pfc.left(9) == "namespace") { - pfc.cutLeft(pfc.find("{") + 1); + pfc.cutLeft(pfc.find('{') + 1); continue; } if (pfc.left(8) == "template") { pfc.cutLeft(8); - pfc.takeRange("<", ">"); + pfc.takeRange('<', '>'); bool def = !isDeclaration(pfc, 0, &end); pfc.cutLeft(end); - if (def) pfc.takeRange("{", "}"); + if (def) pfc.takeRange('{', '}'); else pfc.takeSymbol(); continue; } - if (pfc.left(5) == "class" || pfc.left(6) == "struct" || pfc.left(5) == "union") { - int dind = pfc.find("{", 0), find = pfc.find(";", 0); + if (pfc.left(5) == PIStringAscii("class") || pfc.left(6) == "struct" || pfc.left(5) == "union") { + int dind = pfc.find('{', 0), find = pfc.find(';', 0); if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;} if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;} ccmn = pfc.left(dind) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n"; @@ -296,24 +296,24 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { parseClass(0, ccmn); continue; } - if (pfc.left(4) == "enum") { + if (pfc.left(4) == PIStringAscii("enum")) { pfc.cutLeft(4); tmp = pfc.takeCWord(); pfc.trim(); MetaMap meta = maybeMeta(pfc); - parseEnum(0, cur_namespace + tmp, pfc.takeRange("{", "}"), meta); + parseEnum(0, cur_namespace + tmp, pfc.takeRange('{', '}'), meta); pfc.takeSymbol(); continue; } - if (pfc.left(7) == "typedef") { + if (pfc.left(7) == PIStringAscii("typedef")) { pfc.cutLeft(7); - typedefs << parseTypedef(pfc.takeLeft(pfc.find(";"))); + typedefs << parseTypedef(pfc.takeLeft(pfc.find(';'))); if (typedefs.back().first.isEmpty()) typedefs.pop_back(); else root_.typedefs << typedefs.back(); pfc.takeSymbol(); continue; } - int sci = pfc.find(";", 0), obi = pfc.find("{", 0); + int sci = pfc.find(';', 0), obi = pfc.find('{', 0); if (sci < 0 && obi < 0) { pfc.takeLeft(1); continue; @@ -323,7 +323,7 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { str = pfc.takeLeft(sci + 1); } else { str = pfc.takeLeft(obi); - pfc.cutLeft(pfc.takeRange("{", "}").toInt()); + pfc.cutLeft(pfc.takeRange('{', '}').toInt()); } parseMember(&root_, str); } @@ -333,22 +333,22 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) { - PIString cd = fc.trimmed().removeAll('\n').replaceAll("\t", " ").replaceAll(" ", " "), pn; + PIString cd = fc.trimmed().removeAll('\n').replaceAll('\t', ' ').replaceAll(PIStringAscii(" "), ' '), pn; MetaMap meta; - int ind = cd.find("$M"); + int ind = cd.find(PIStringAscii("$M")); if (ind >= 0) { meta = tmp_meta.value(cd.takeMid(ind, 5)); - cd.replaceAll(" ", " "); + cd.replaceAll(PIStringAscii(" "), ' '); } //piCout << "found class <****\n" << cd << "\n****>"; - ind = cd.find(":"); + ind = cd.find(':'); PIVector parents; if (ind > 0) { - PIStringList pl = cd.takeMid(ind + 1).trim().split(","); + PIStringList pl = cd.takeMid(ind + 1).trim().split(','); cd.cutRight(1); Entity * pe = 0; piForeachC (PIString & p, pl) { - if (p.contains(" ")) pn = p.mid(p.find(" ") + 1); + if (p.contains(' ')) pn = p.mid(p.find(' ') + 1); else pn = p; pe = findEntityByName(pn); if (pe == 0) ;//{piCout << "Error: can`t find" << pn;} @@ -356,11 +356,11 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) } } PIString typename_ = cd.left(6).trim(); - bool is_class = typename_ == "class"; + bool is_class = typename_ == PIStringAscii("class"); cur_def_vis = (is_class ? Private : Public); PIString cn = cd.mid(6).trim(); bool has_name = !cn.isEmpty(); - if (cn.isEmpty()) cn = ""; + if (cn.isEmpty()) cn = "'; //piCout << "found " << typename_ << cn; if (cn.isEmpty()) return 0; Entity * e = new Entity(); @@ -377,7 +377,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { Visibility prev_vis = cur_def_vis; - int dind = fc.find("{"), find = fc.find(";"), end = 0; + int dind = fc.find('{'), find = fc.find(';'), end = 0; if (dind < 0 && find < 0) return PIString(); if (dind < 0 || find < dind) return fc.left(find); //piCout << "parse class <****\n" << fc.left(20) << "\n****>"; @@ -396,37 +396,37 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { while (!fc.isEmpty()) { PIString cw = fc.takeCWord(), tmp; //piCout << "\ntaked word" << cw; - if (cw == "public") {cur_def_vis = Public; fc.cutLeft(1); continue;} - if (cw == "protected") {cur_def_vis = Protected; fc.cutLeft(1); continue;} - if (cw == "private") {cur_def_vis = Private; fc.cutLeft(1); continue;} - if (cw == "class" || cw == "struct" || cw == "union") { + if (cw == PIStringAscii("public" )) {cur_def_vis = Public; fc.cutLeft(1); continue;} + if (cw == PIStringAscii("protected")) {cur_def_vis = Protected; fc.cutLeft(1); continue;} + if (cw == PIStringAscii("private" )) {cur_def_vis = Private; fc.cutLeft(1); continue;} + if (cw == PIStringAscii("class") || cw == PIStringAscii("struct") || cw == PIStringAscii("union")) { if (isDeclaration(fc, 0, &end)) { fc.cutLeft(end); fc.takeSymbol(); continue; } - tmp = fc.takeLeft(fc.find("{")); - stmp = fc.takeRange("{", "}"); + tmp = fc.takeLeft(fc.find('{')); + stmp = fc.takeRange('{', '}'); fc.takeSymbol(); - stmp = cw + " " + tmp + "{" + stmp + "}"; + stmp = cw + ' ' + tmp + '{' + stmp + '}'; parseClass(ce, stmp); continue; } - if (cw == "enum") { + if (cw == PIStringAscii("enum")) { tmp = fc.takeCWord(); fc.trim(); MetaMap meta = maybeMeta(fc); - parseEnum(ce, cur_namespace + tmp, fc.takeRange("{", "}"), meta); + parseEnum(ce, cur_namespace + tmp, fc.takeRange('{', '}'), meta); fc.takeSymbol(); continue; } - if (cw == "friend") {fc.cutLeft(fc.find(";") + 1); continue;} - if (cw == "typedef") {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(";"))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;} + if (cw == PIStringAscii("friend")) {fc.cutLeft(fc.find(';') + 1); continue;} + if (cw == PIStringAscii("typedef")) {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';'))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;} if (cw == "template") { - fc.takeRange("<", ">"); + fc.takeRange('<', '>'); def = !isDeclaration(fc, 0, &end); fc.cutLeft(end); - if (def) fc.takeRange("{", "}"); + if (def) fc.takeRange('{', '}'); else fc.takeSymbol(); continue; } @@ -434,7 +434,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { tmp = (cw + fc.takeLeft(end)).trim(); if (!tmp.isEmpty()) parseMember(ce, tmp); - if (def) fc.takeRange("{", "}"); + if (def) fc.takeRange('{', '}'); else fc.takeSymbol(); if (ps == fc.size_s()) {fc.cutLeft(1);} ps = fc.size_s(); @@ -448,13 +448,13 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { PICodeParser::MetaMap ret; if (fc.isEmpty()) return ret; - PIStringList ml = fc.split(","); + PIStringList ml = fc.split(','); piForeachC (PIString & m, ml) { int i = m.find("="); if (i < 0) continue; PIString mv = m.mid(i + 1).trim(); - if (mv.startsWith("\"")) mv.cutLeft(1); - if (mv.endsWith("\"")) mv.cutRight(1); + if (mv.startsWith('\"')) mv.cutLeft(1); + if (mv.endsWith('\"')) mv.cutRight(1); ret[m.left(i).trim()] = mv; } //piCout << ms << ret; @@ -463,18 +463,18 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta) { - //piCout << "enum" << name << fc; + //piCout << PIStringAscii("enum") << name << fc; Enum e(name); e.meta = meta; - PIStringList vl(fc.split(",")); + PIStringList vl(fc.split(',')); PIString vn; int cv = -1, ind = 0; piForeach (PIString & v, vl) { MetaMap meta; - int mi = v.find("$M"); + int mi = v.find(PIStringAscii("$M")); if (mi >= 0) { meta = tmp_meta.value(v.takeMid(mi, 5)); - v.replaceAll(" ", " "); + v.replaceAll(" ", ' '); } vn = v; ind = v.find("="); if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);} @@ -492,15 +492,15 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) { //piCout << "parse typedef" << fc; Typedef td; - fc.replaceAll("\t", " "); + fc.replaceAll('\t', ' '); - if (fc.contains("(")) { - int start = fc.find("("), end = fc.find(")"); + if (fc.contains('(')) { + int start = fc.find('('), end = fc.find(')'); td.first = fc.takeMid(start + 1, end - start - 1).trim(); - if (td.first.left(1) == "*") {td.first.cutLeft(1).trim(); fc.insert(start + 1, "*");} + if (td.first.left(1) == PIChar('*')) {td.first.cutLeft(1).trim(); fc.insert(start + 1, '*');} td.second = fc.trim(); } else { - td.first = fc.takeMid(fc.findLast(" ")).trim(); + td.first = fc.takeMid(fc.findLast(' ')).trim(); td.second = fc.trim(); } //piCout << "found typedef" << td; @@ -513,30 +513,30 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { if (fc.find("operator") >= 0) return true; tmp_temp.clear(); //piCout << "parse member" << fc; - int ts = fc.find("<"), te = 0; + int ts = fc.find('<'), te = 0; PIString ctemp, crepl; while (ts >= 0) { - ctemp = fc.mid(ts).takeRange("<", ">"); - if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find("<", te); continue;} - crepl = "$T" + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, "0"); + ctemp = fc.mid(ts).takeRange('<', '>'); + if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find('<', te); continue;} + crepl = PIStringAscii("$T") + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, '0'); fc.replace(ts, ctemp.size_s() + 2, crepl); - tmp_temp[crepl] = "<" + ctemp + ">"; - ts = fc.find("<", te); + tmp_temp[crepl] = '<' + ctemp + '>'; + ts = fc.find('<', te); } - fc.replaceAll("\n", " ").replaceAll("\t", " ").replaceAll(" ", " ").replaceAll(", ", ",").replaceAll(" (", "(").replaceAll(" $M", "$M"); + fc.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll(" ", ' ').replaceAll(", ", ',').replaceAll(PIStringAscii(" ("), '(').replaceAll(PIStringAscii(" $M"), PIStringAscii("$M")); //piCout << "parse member" << fc; PIStringList tl, al; Member me; //piCout << fc; - if (fc.contains("(")) { + if (fc.contains('(')) { MetaMap meta; - int ind = fc.find("$M"); + int ind = fc.find(PIStringAscii("$M")); if (ind >= 0) { meta = tmp_meta.value(fc.takeMid(ind, 5)); - fc.replaceAll(" ", " ").replaceAll(" (", "("); + fc.replaceAll(PIStringAscii(" "), ' ').replaceAll(PIStringAscii(" ("), '('); } - fc.cutRight(fc.size_s() - fc.findLast(")") - 1); - te = fc.find("("); + fc.cutRight(fc.size_s() - fc.findLast(')') - 1); + te = fc.find('('); //piCout << fc; for (ts = te - 1; ts >= 0; --ts) if (!_isCChar(fc[ts]) && !(fc[ts].isDigit())) break; @@ -544,20 +544,20 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { me.meta = meta; me.name = fc.takeMid(ts + 1, te - ts - 1); if (me.name == parent->name) return true; - me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(","); + me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(','); me.type = fc.cutRight(1).trim(); me.visibility = cur_def_vis; - if (me.type.find("inline ") >= 0) { + if (me.type.find(PIStringAscii("inline ")) >= 0) { me.attributes |= Inline; - me.type.removeAll("inline "); + me.type.removeAll(PIStringAscii("inline ")); } - if (me.type.find("static ") >= 0) { + if (me.type.find(PIStringAscii("static ")) >= 0) { me.attributes |= Static; - me.type.removeAll("static "); + me.type.removeAll(PIStringAscii("static ")); } - if (me.type.find("virtual ") >= 0) { + if (me.type.find(PIStringAscii("virtual ")) >= 0) { me.attributes |= Virtual; - me.type.removeAll("virtual "); + me.type.removeAll(PIStringAscii("virtual ")); } normalizeEntityNamespace(me.type); int i = 0; @@ -566,15 +566,15 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { if ((i = a.find("=")) > 0) a.cutRight(a.size_s() - i).trim(); for (int j = 0; j < me.arguments_full.size_s(); ++j) - if (me.arguments_full[j] == "void") { + if (me.arguments_full[j] == PIStringAscii("void")) { me.arguments_full.remove(j); --j; } me.arguments_type = me.arguments_full; piForeach (PIString & a, me.arguments_type) { crepl.clear(); - if (a.contains("[")) - crepl = a.takeMid(a.find("["), a.findLast("]") - a.find("[") + 1); + if (a.contains('[')) + crepl = a.takeMid(a.find('['), a.findLast(']') - a.find('[') + 1); for (ts = a.size_s() - 1; ts >= 0; --ts) if (!_isCChar(a[ts]) && !(a[ts].isDigit())) break; a.cutRight(a.size_s() - ts - 1); @@ -586,18 +586,18 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { //piCout << "func" << me.type << me.name << me.arguments_full << me.arguments_type; parent->functions << me; } else { - if (fc.endsWith(";")) fc.cutRight(1); - if (fc.startsWith("using") || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; + if (fc.endsWith(';')) fc.cutRight(1); + if (fc.startsWith(PIStringAscii("using")) || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; int bits = extractMemberBits(fc); - tl = fc.split(","); + tl = fc.split(','); //piCout << "member" << fc << tl; //piCout << "member after eb" << fc << ", bits =" << bits; if (tl.isEmpty()) return true; bool vn = true; ctemp = tl.front().trim(); PIString meta_t; - if (ctemp.contains("$M")) - meta_t = ctemp.takeMid(ctemp.find("$M")); + if (ctemp.contains(PIStringAscii("$M"))) + meta_t = ctemp.takeMid(ctemp.find(PIStringAscii("$M"))); for (ts = ctemp.size_s() - 1; ts > 0; --ts) { if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;} else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;} @@ -606,26 +606,26 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { me.visibility = cur_def_vis; ctemp += meta_t; restoreTmpTemp(&me); - PIString type = " " + me.type; - if (type.find(" const ") >= 0) { + PIString type = PIStringAscii(" ") + me.type; + if (type.find(PIStringAscii(" const ")) >= 0) { me.attributes |= Const; - type.replaceAll(" const ", " "); + type.replaceAll(PIStringAscii(" const "), ' '); } - if (type.find(" static ") >= 0) { + if (type.find(PIStringAscii(" static ")) >= 0) { me.attributes |= Static; - type.replaceAll(" static ", " "); + type.replaceAll(PIStringAscii(" static "), ' '); } - if (type.find(" mutable ") >= 0) { + if (type.find(PIStringAscii(" mutable ")) >= 0) { me.attributes |= Mutable; - type.replaceAll(" mutable ", " "); + type.replaceAll(PIStringAscii(" mutable "), ' '); } - if (type.find(" volatile ") >= 0) { + if (type.find(PIStringAscii(" volatile ")) >= 0) { me.attributes |= Volatile; - type.replaceAll(" volatile ", " "); + type.replaceAll(PIStringAscii(" volatile "), ' '); } - if (type.find(" extern ") >= 0) { + if (type.find(PIStringAscii(" extern ")) >= 0) { me.attributes |= Extern; - type.replaceAll(" extern ", " "); + type.replaceAll(PIStringAscii(" extern "), ' '); } type.trim(); normalizeEntityNamespace(type); @@ -637,15 +637,15 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { me.type = type; restoreTmpMeta(&me); if (me.name.isEmpty()) continue; - if (me.name.contains("[")) - crepl = me.name.takeMid(me.name.find("["), me.name.findLast("]") - me.name.find("[") + 1); + if (me.name.contains('[')) + crepl = me.name.takeMid(me.name.find('['), me.name.findLast(']') - me.name.find('[') + 1); while (!me.name.isEmpty()) { - if (me.name.front() == "*" || me.name.front() == "&") { + if (me.name.front() == PIChar('*') || me.name.front() == PIChar('&')) { me.type += me.name.takeLeft(1); me.name.trim(); } else break; } - me.is_type_ptr = (me.type.right(1) == "]" || me.type.right(1) == "*"); + me.is_type_ptr = (me.type.right(1) == PIChar(']') || me.type.right(1) == PIChar('*')); me.type += crepl; me.bits = bits; while (!crepl.isEmpty()) { @@ -664,7 +664,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { int PICodeParser::extractMemberBits(PIString & fc) { - int i = fc.findLast(":"); + int i = fc.findLast(':'); if (i <= 0) return -1; if (fc[i - 1].toAscii() == ':') return -1; PIString bs = fc.takeMid(i).mid(1).trim(); @@ -681,11 +681,11 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { n.cutRight(suff.size_s()); break; } - n.push_front(" "); - if (n.find(" static ") >= 0) {n.replaceAll(" static ", ""); pref += "static ";} - if (n.find(" const ") >= 0) {n.replaceAll(" const ", ""); pref += "const ";} - if (n.find(" mutable ") >= 0) {n.replaceAll(" mutable ", ""); pref += "mutable ";} - if (n.find(" volatile ") >= 0) {n.replaceAll(" volatile ", ""); pref += "volatile ";} + n.push_front(' '); + if (n.find(PIStringAscii(" static ")) >= 0) {n.replaceAll(PIStringAscii(" static "), ""); pref += PIStringAscii("static ");} + if (n.find(PIStringAscii(" const ")) >= 0) {n.replaceAll(PIStringAscii(" const "), ""); pref += PIStringAscii("const ");} + if (n.find(PIStringAscii(" mutable ")) >= 0) {n.replaceAll(PIStringAscii(" mutable "), ""); pref += PIStringAscii("mutable ");} + if (n.find(PIStringAscii(" volatile ")) >= 0) {n.replaceAll(PIStringAscii(" volatile "), ""); pref += PIStringAscii("volatile ");} n.trim(); int f = 0; piForeachC (Entity * e, entities) { @@ -694,7 +694,7 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { return; } if ((f = e->name.find(n)) >= 0) - if (e->name.mid(f - 1, 1) == ":") + if (e->name.mid(f - 1, 1) == PIChar(':')) if (e->name.find(cur_namespace) >= 0) { n = pref + e->name + suff; return; @@ -702,7 +702,7 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { } piForeachC (Enum & e, enums) if ((f = e.name.find(n)) >= 0) - if (e.name.mid(f - 1, 1) == ":") + if (e.name.mid(f - 1, 1) == PIChar(':')) if (e.name.find(cur_namespace) >= 0) { //piCout << "change" << n << "to" << e.name + suff; n = pref + e.name + suff; @@ -710,7 +710,7 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { } piForeachC (Typedef & e, typedefs) if ((f = e.first.find(n)) >= 0) - if (e.first.mid(f - 1, 1) == ":") + if (e.first.mid(f - 1, 1) == PIChar(':')) if (e.first.find(cur_namespace) >= 0) { //piCout << "change" << n << "to" << e.name + suff; n = pref + e.first + suff; @@ -723,20 +723,20 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { void PICodeParser::restoreTmpTemp(Member * e) { int i = 0; piForeach (PIString & a, e->arguments_full) { - while ((i = a.find("$T")) >= 0) + while ((i = a.find(PIStringAscii("$T"))) >= 0) a.replace(i, 5, tmp_temp[a.mid(i, 5)]); } piForeach (PIString & a, e->arguments_type) { - while ((i = a.find("$T")) >= 0) + while ((i = a.find(PIStringAscii("$T"))) >= 0) a.replace(i, 5, tmp_temp[a.mid(i, 5)]); } - while ((i = e->type.find("$T")) >= 0) + while ((i = e->type.find(PIStringAscii("$T"))) >= 0) e->type.replace(i, 5, tmp_temp[e->type.mid(i, 5)]); } void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) { - int i = e->name.find("$M"); + int i = e->name.find(PIStringAscii("$M")); if (i < 0) return; e->meta = tmp_meta[e->name.takeMid(i, 5)]; } @@ -744,7 +744,7 @@ void PICodeParser::restoreTmpMeta(PICodeParser::Member * e) { PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) { PICodeParser::MetaMap ret; - if (fc.left(2) == "$M") { + if (fc.left(2) == PIStringAscii("$M")) { ret = tmp_meta.value(fc.takeLeft(5)); fc.trim(); } @@ -754,10 +754,10 @@ PICodeParser::MetaMap PICodeParser::maybeMeta(PIString & fc) { bool PICodeParser::macroCondition(const PIString & mif, PIString mifcond) { //piCout << "macroCondition" << mif << mifcond; - if (mif == "ifdef") return isDefineExists(mifcond); - if (mif == "ifndef") return !isDefineExists(mifcond); - if (mif == "if" || mif == "elif") { - mifcond.removeAll(" ").removeAll("\t"); + if (mif == PIStringAscii("ifdef")) return isDefineExists(mifcond); + if (mif == PIStringAscii("ifndef")) return !isDefineExists(mifcond); + if (mif == PIStringAscii("if") || mif == PIStringAscii("elif")) { + mifcond.removeAll(' ').removeAll('\t'); return procMacrosCond(mifcond) > 0.; } return false; @@ -770,7 +770,7 @@ double PICodeParser::procMacrosCond(PIString fc) { int oper = 0, ps = -1; char cc, nc; PIString ce; - fc.removeAll("defined"); + fc.removeAll(PIStringAscii("defined")); //piCout << "procMacrosCond" << fc; while (!fc.isEmpty()) { cc = fc[0].toAscii(); @@ -825,17 +825,17 @@ double PICodeParser::defineValue(const PIString & dn) { void PICodeParser::replaceMeta(PIString & dn) { tmp_meta.clear(); if (dn.isEmpty()) return; - int s = dn.find("PIMETA"); + int s = dn.find(PIStringAscii("PIMETA")); while (s >= 0) { int ms = 0, ml = 0; ms = dn.findRange('(', ')', '\\', s + 6, &ml); if (ms < 0) return; PIString meta = dn.mid(ms, ml).trim(); - PIString rm = "$M" + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, "0"); + PIString rm = PIStringAscii("$M") + PIString::fromNumber(tmp_meta.size_s()).expandLeftTo(3, '0'); dn.replace(s, ms + ml + 1 - s, rm); - //piCout << "FOUND META \"" << meta << "\""; + //piCout << "FOUND META \"" << meta << '\"'; tmp_meta[rm] = parseMeta(meta); - s = dn.find("PIMETA"); + s = dn.find(PIStringAscii("PIMETA")); } } @@ -849,7 +849,7 @@ PICodeParser::Entity * PICodeParser::findEntityByName(const PIString & en) { bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) { - int dind = fc.find("{", start), find = fc.find(";", start); + int dind = fc.find('{', start), find = fc.find(';', start); //piCout << "isDeclaration" << dind << find << fc.left(10); if (dind < 0 && find < 0) {if (end) *end = -1; return true;} if (dind < 0 || find < dind) {if (end) *end = find; return true;} @@ -866,11 +866,11 @@ bool PICodeParser::isMainFile(const PIString & fc) { if (csi < 0) csi = fc.find("\nmain", si); if (csi < 0) return false; si = csi; - int fi = fc.find("(", si + 5); + int fi = fc.find('(', si + 5); if (fi < 0) return false; if (fi - si < 10) { PIString ms(fc.mid(si, fi - si + 1)); - ms.removeAll(" ").removeAll("\t").removeAll("\n"); + ms.removeAll(' ').removeAll('\t').removeAll('\n'); if (ms == "main(") return true; } si += 5; @@ -885,17 +885,17 @@ PIString PICodeParser::procMacros(PIString fc) { bool grab = false, skip = false, cond_ok = false; PIString pfc, nfc, line, mif, mifcond; //piCout << "procMacros\n<******" << fc << "\n******>"; - fc += "\n"; + fc += '\n'; while (!fc.isEmpty()) { line = fc.takeLine().trimmed(); - if (line.left(1) == "#") { + if (line.left(1) == PIChar('#')) { mifcond = line.mid(1); mif = mifcond.takeCWord(); //piCout << mif; //piCout << "mif mifcond" << mif << mifcond << ifcnt; if (skip || grab) { - if (mif.left(2) == "if") ifcnt++; - if (mif.left(5) == "endif") { + if (mif.left(2) == PIStringAscii("if")) ifcnt++; + if (mif.left(5) == PIStringAscii("endif")) { if (ifcnt > 0) ifcnt--; else { //piCout << "main endif" << skip << grab; @@ -904,7 +904,7 @@ PIString PICodeParser::procMacros(PIString fc) { continue; } } - if (mif.left(4) == "elif" && ifcnt == 0) { + if (mif.left(4) == PIStringAscii("elif") && ifcnt == 0) { //piCout << "main elif" << skip << grab << cond_ok; if (cond_ok) { if (grab) { @@ -929,10 +929,10 @@ PIString PICodeParser::procMacros(PIString fc) { else {skip = true; grab = false;} continue; } - if (grab) nfc << line << "\n"; + if (grab) nfc << line << '\n'; continue; } - if (mif.left(2) == "if") { + if (mif.left(2) == PIStringAscii("if")) { //piCout << "main if"; skip = grab = cond_ok = false; if (macroCondition(mif, mifcond.trimmed())) grab = cond_ok = true; @@ -944,8 +944,8 @@ PIString PICodeParser::procMacros(PIString fc) { //return false; /// WARNING: now skip errors } } else { - if (grab) nfc << line << "\n"; - else if (!skip) pfc << line << "\n"; + if (grab) nfc << line << '\n'; + else if (!skip) pfc << line << '\n'; } } return pfc; @@ -957,20 +957,20 @@ bool PICodeParser::parseDirective(PIString d) { PIString dname = d.takeCWord(); //piCout << "parseDirective" << d; if (dname == "include") { - d.replaceAll("<", "\"").replaceAll(">", "\""); - PIString cf = cur_file, ifc = d.takeRange("\"", "\""); + d.replaceAll('<', '\"').replaceAll('>', '\"'); + PIString cf = cur_file, ifc = d.takeRange('\"', '\"'); if (with_includes) { bool ret = parseFileInternal(ifc, with_includes); cur_file = cf; return ret; } } - if (dname == "define") { + if (dname == PIStringAscii("define")) { PIString mname = d.takeCWord(); //piCout << mname; - if (mname == "PIMETA") return true; - if (d.left(1) == "(") { // macro - PIStringList args = d.takeRange("(", ")").split(",").trim(); + if (mname == PIStringAscii("PIMETA")) return true; + if (d.left(1) == PIChar('(')) { // macro + PIStringList args = d.takeRange('(', ')').split(',').trim(); macros << Macro(mname, d.trim(), args); } else { // define d.trim(); diff --git a/lib/main/core/pistring.cpp b/lib/main/core/pistring.cpp index 4cd27fab..508fd126 100644 --- a/lib/main/core/pistring.cpp +++ b/lib/main/core/pistring.cpp @@ -173,7 +173,7 @@ PIString PIString::dtos(const double num, char format, int precision) { PIString PIString::fromNumberBaseS(const llong value, int base, bool * ok) { - if (value == 0LL) return PIString("0"); + if (value == 0LL) return PIString('0'); if (base < 2 || base > 40) {if (ok != 0) *ok = false; return PIString();} if (ok != 0) *ok = true; if (base == 10) return lltos(value); @@ -192,7 +192,7 @@ PIString PIString::fromNumberBaseS(const llong value, int base, bool * ok) { } PIString PIString::fromNumberBaseU(const ullong value, int base, bool * ok) { - if (value == 0ULL) return PIString("0"); + if (value == 0ULL) return PIString('0'); if (base < 2 || base > 40) {if (ok != 0) *ok = false; return PIString();} if (ok != 0) *ok = true; if (base == 10) return ulltos(value); @@ -211,9 +211,10 @@ PIString PIString::fromNumberBaseU(const ullong value, int base, bool * ok) { llong PIString::toNumberBase(const PIString & value, int base, bool * ok) { + static const PIString s_0x = PIStringAscii("0x"); PIString v = value.trimmed(); if (base < 0) { - int ind = v.find("0x"); + int ind = v.find(s_0x); if (ind == 0 || ind == 1) {v.remove(ind, 2); base = 16;} else base = 10; } else @@ -254,6 +255,7 @@ void PIString::appendFromChars(const char * c, int s, const char * codepage) { int sz = ucnv_toUChars(cc, ucs, s, c, s, &e); //printf("appendFromChars %d -> %d\n", s, sz); //printf("PIString %d -> %d\n", c[0], ucs[0]); + reserve(size_s() + sz); for (int i = 0; i < sz; ++i) push_back(PIChar(ucs[i])); delete[] ucs; @@ -264,11 +266,9 @@ void PIString::appendFromChars(const char * c, int s, const char * codepage) { # ifdef WINDOWS sz = MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, 0, 0); if (sz <= 0) return; - wchar_t * buffer = new wchar_t[sz]; - MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, buffer, sz); - for (int i = 0; i < sz; ++i) - push_back(PIChar((ushort)buffer[i])); - delete[] buffer; + int old_sz = size_s(); + enlarge(sz); + MultiByteToWideChar((uint)(uintptr_t)codepage, MB_ERR_INVALID_CHARS, c, s, (LPWSTR)PIDeque::data(old_sz), sz); return; //printf("request %d\n", sz); # else @@ -330,9 +330,14 @@ PIString PIString::fromAscii(const char * s) { PIString ret; int l = 0; while (s[l] != '\0') { - ret.push_back(PIChar(short(s[l]))); + ret.push_back(PIChar(s[l])); ++l; } + /*while (s[l] != '\0') ++l; + PIString ret; + ret.resize(l); + for (int i = 0; i < l; ++i) + ret[i] = s[i];*/ return ret; } @@ -369,6 +374,7 @@ void PIString::buildData(const char * cp) const { UConverter * cc = ucnv_open(cp, &e); if (cc) { char uc[8]; + data_.reserve(size_s()); for (int i = 0; i < size_s(); ++i) { if (at(i).isAscii()) data_.push_back(uchar(at(i).unicode16Code())); @@ -605,16 +611,18 @@ PIString PIString::trimmed() const { PIString & PIString::replace(int from, int count, const PIString & with) { - if (count < length() - from) remove(from, count); - else remove(from, length() - from); - uint c = with.length(); - for (uint i = 0; i < c; ++i) insert(from + i, with[i]); + count = piMini(count, length() - from); + if (count == with.size_s()) + memcpy(&(at(from)), &(with.at(0)), count * sizeof(PIChar)); + else { + remove(from, count); + PIDeque::insert(from, with); + } return *this; } PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) { - //piCout << "replace" << what << with; if (what.isEmpty()) { if (ok != 0) *ok = false; return *this; @@ -628,8 +636,53 @@ PIString & PIString::replace(const PIString & what, const PIString & with, bool PIString & PIString::replaceAll(const PIString & what, const PIString & with) { if (what.isEmpty() || what == with) return *this; - bool ok = true; - while (ok) replace(what, with, &ok); + if (with.isEmpty()) removeAll(what); + else { + int l = what.length(), dl = with.length() - what.length(); + for (int i = 0; i < length() - l + 1; ++i) { + bool match = true; + for (int j = 0; j < l; ++j) { + if (at(j + i) != what[j]) { + match = false; + break; + } + } + if (!match) continue; + if (dl > 0) PIDeque::insert(i, PIDeque((size_t)dl)); + if (dl < 0) PIDeque::remove(i, -dl); + memcpy(PIDeque::data(i), &(with.at(0)), with.length() * sizeof(PIChar)); + //i -= l; + } + } + return *this; +} + + +PIString & PIString::replaceAll(const char what, const char with) { + int l = length(); + for (int i = 0; i < l; ++i) { + if (at(i) == what) + at(i) = with; + } + return *this; +} + + +PIString & PIString::removeAll(const PIString & str) { + if (str.isEmpty()) return *this; + int l = str.length(); + for (int i = 0; i < length() - l + 1; ++i) { + bool match = true; + for (int j = 0; j < l; ++j) { + if (at(j + i) != str[j]) { + match = false; + break; + } + } + if (!match) continue; + PIDeque::remove(i, l); + i -= l; + } return *this; } @@ -641,16 +694,17 @@ PIString & PIString::insert(int index, const PIString & str) { PIString & PIString::elide(int size, float pos) { + static const PIString s_dotdot = PIStringAscii(".."); if (length() <= size) return *this; if (length() <= 2) { - fill("."); + fill('.'); return *this; } pos = piClampf(pos, 0.f, 1.f); int ns = size - 2; int ls = piRoundf(ns * pos); remove(ls, length() - ns); - insert(ls, ".."); + insert(ls, s_dotdot); return *this; } @@ -670,9 +724,9 @@ PIStringList PIString::split(const PIString & delim) const { } -int PIString::find(const char str, const int start) const { +int PIString::find(const char c, const int start) const { for (int i = start; i < length(); ++i) - if (at(i) == str) + if (at(i) == c) return i; return -1; } @@ -687,9 +741,9 @@ int PIString::find(const PIString & str, const int start) const { } -int PIString::findLast(const char str, const int start) const { +int PIString::findLast(const char c, const int start) const { for (int i = length() - 1; i >= start; --i) - if (at(i) == str) + if (at(i) == c) return i; return -1; } @@ -730,7 +784,7 @@ int PIString::findCWord(const PIString & word, const int start) const { } -int PIString::findRange(const PIChar & start, const PIChar & end, const PIChar & shield, const int start_index, int * len) const { +int PIString::findRange(const PIChar start, const PIChar end, const PIChar shield, const int start_index, int * len) const { if (len) *len = 0; bool trim_ = (start != ' ' && start != '\t' && start != '\n' && start != '\r'), eq = (start == end); int sz = size_s(), ls = -1, le = -1, cnt = 0; @@ -783,7 +837,7 @@ int PIString::findAnyLast(const PIString & str, const int start) const { } -int PIString::entries(const PIChar & c) const { +int PIString::entries(const PIChar c) const { int sz = size_s(), ret = 0; for (int i = 0; i < sz; ++i) if (at(i) == c) ++ret; @@ -804,9 +858,14 @@ bool PIString::endsWith(const PIString & str) const { bool PIString::toBool() const { + static const PIString s_true = PIStringAscii("true"); + static const PIString s_yes = PIStringAscii("yes" ); + static const PIString s_on = PIStringAscii("on" ); + static const PIString s_ok = PIStringAscii("ok" ); PIString s(*this); s = s.trimmed().toLowerCase(); - if ( atof(s.toNativeDecimalPoints().data()) > 0. || s == "true" || s == "yes" || s == "on" || s == "ok") return true; + if (s == s_true || s == s_yes || s == s_on || s == s_ok) return true; + if (atof(s.toNativeDecimalPoints().data()) > 0.) return true; return false; } @@ -953,7 +1012,7 @@ PIString PIString::takeNumber() { } -PIString PIString::takeRange(const PIChar & start, const PIChar & end, const PIChar & shield) { +PIString PIString::takeRange(const PIChar start, const PIChar end, const PIChar shield) { PIString ret; bool trim_ = (start != ' ' && start != '\t' && start != '\n' && start != '\r'), eq = (start == end); int sz = size_s(), ls = -1, le = -1, cnt = 0; @@ -991,7 +1050,7 @@ PIString PIString::takeRange(const PIChar & start, const PIChar & end, const PIC } -PIString PIString::inBrackets(const PIChar &start, const PIChar &end) const { +PIString PIString::inBrackets(const PIChar start, const PIChar end) const { int slen = length(); int st = -1, bcnt = 0; PIChar cc; @@ -1030,9 +1089,9 @@ PIString PIString::toNativeDecimalPoints() const { #ifdef HAS_LOCALE PIString s(*this); if (currentLocale == 0) return s; - return s.replaceAll(".", currentLocale->decimal_point).replaceAll(",", currentLocale->decimal_point); + return s.replaceAll('.', currentLocale->decimal_point).replaceAll(',', currentLocale->decimal_point); #else - return PIString(*this).replaceAll(",", "."); + return PIString(*this).replaceAll(',', '.'); #endif } @@ -1062,27 +1121,27 @@ ldouble PIString::toLDouble() const { PIString & PIString::setReadableSize(llong bytes) { clear(); - if (bytes < 1024) {*this += (PIString::fromNumber(bytes) + " B"); return *this;} + if (bytes < 1024) {*this += (PIString::fromNumber(bytes) + PIStringAscii(" B")); return *this;} double fres = bytes / 1024.; llong res = bytes / 1024; fres -= res; - if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " kB"); return *this;} + if (res < 1024) {*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" kB")); return *this;} fres = res / 1024.; res /= 1024; fres -= res; - if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " MB"); return *this;} + if (res < 1024) {*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" MB")); return *this;} fres = res / 1024.; res /= 1024; fres -= res; - if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " GB"); return *this;} + if (res < 1024) {*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" GB")); return *this;} fres = res / 1024.; res /= 1024; fres -= res; - if (res < 1024) {*this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " TB"); return *this;} + if (res < 1024) {*this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" TB")); return *this;} fres = res / 1024.; res /= 1024; fres -= res; - *this += (PIString::fromNumber(res) + "." + PIString::fromNumber(llong(fres * 10)).left(1) + " PB"); + *this += (PIString::fromNumber(res) + PIStringAscii(".") + PIString::fromNumber(llong(fres * 10)).left(1) + PIStringAscii(" PB")); return *this; } @@ -1110,14 +1169,14 @@ void parseVersion(PIString s, PIVector & codes, PIStringList & strs) { } int mccnt = 2 - s.entries('.'); if (mccnt > 0) { - int ind = s.findLast(".") + 1; + int ind = s.findLast('.') + 1; while (!_versionDelims_.contains(s[ind])) { ++ind; if (ind > s.size_s() - 1) break; } for (int i = 0; i < mccnt; ++i) - s.insert(ind, ".0"); + s.insert(ind, PIStringAscii(".0")); } PIStringList comps; while (!s.isEmpty()) { @@ -1132,7 +1191,7 @@ void parseVersion(PIString s, PIVector & codes, PIStringList & strs) { } for (int i = 0; i < comps.size_s(); ++i) { if (comps[i].isEmpty()) - comps[i] = "0"; + comps[i] = '0'; bool ok = false; int val = comps[i].toInt(-1, &ok); if (ok) { @@ -1148,20 +1207,20 @@ void parseVersion(PIString s, PIVector & codes, PIStringList & strs) { int versionLabelValue(PIString s) { int ret = -10000; if (s.isEmpty()) return 0; - if (s.startsWith("pre")) { + if (s.startsWith(PIStringAscii("pre"))) { s.cutLeft(3); ret -= 1; } - if (s.startsWith("rc")) { + if (s.startsWith(PIStringAscii("rc"))) { s.cutLeft(2); ret += s.toInt(); } - if (s.startsWith("r")) { + if (s.startsWith(PIStringAscii("r"))) { s.cutLeft(1); ret += 10000 + s.toInt(); } - if (s == "alpha") ret -= 4; - if (s == "beta" ) ret -= 2; + if (s == PIStringAscii("alpha")) ret -= 4; + if (s == PIStringAscii("beta" )) ret -= 2; return ret; } @@ -1200,13 +1259,13 @@ PIString versionNormalize(const PIString & v) { PIString ret; for (int i = 0; i < codes.size_s(); ++i) { if (i > 0) { - if (i < 3) ret += "."; - else ret += "-"; + if (i < 3) ret += '.'; + else ret += '-'; } ret += PIString::fromNumber(codes[i]); } for (int i = 0; i < strs.size_s(); ++i) { - ret += "_"; + ret += '_'; ret += strs[i]; } return ret; diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index 0fb7bedd..e73d73bf 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -43,7 +43,8 @@ public: static const float ElideCenter; static const float ElideRight ; - PIString & operator +=(const PIChar & c) {push_back(c); return *this;} + PIString & operator +=(const PIChar c) {push_back(c); return *this;} + PIString & operator +=(const char c) {push_back(PIChar(c)); return *this;} PIString & operator +=(const char * str); PIString & operator +=(const wchar_t * str); PIString & operator +=(const PIByteArray & ba) {appendFromChars((const char * )ba.data(), ba.size_s(), __utf8name__); return *this;} @@ -55,7 +56,7 @@ public: //! Contructs string with single symbol "c" - PIString(const PIChar & c): PIDeque() {*this += c;} + PIString(const PIChar c): PIDeque() {*this += c;} PIString(const char c): PIDeque() {*this += PIChar(c);} /*! \brief Contructs string from c-string "str" @@ -84,7 +85,7 @@ public: /*! \brief Contructs string as sequence of symbols "c" of buffer with length "len" * \details Example: \snippet pistring.cpp PIString(int, PIChar) */ - PIString(const int len, const PIChar & c): PIDeque() {for (int i = 0; i < len; ++i) push_back(c);} + PIString(const int len, const PIChar c): PIDeque() {for (int i = 0; i < len; ++i) push_back(c);} ~PIString() {} @@ -110,7 +111,7 @@ public: bool operator ==(const PIString & str) const; //! Compare operator - bool operator ==(const PIChar c) const {return *this == PIString(c);} + bool operator ==(const PIChar c) const {if (size_s() != 1) return false; return at(0) == c;} //! Compare operator bool operator ==(const char * str) const {return *this == PIString(str);} @@ -119,7 +120,7 @@ public: bool operator !=(const PIString & str) const; //! Compare operator - bool operator !=(const PIChar c) const {return *this != PIString(c);} + bool operator !=(const PIChar c) const {if (size_s() != 1) return true; return at(0) != c;} //! Compare operator bool operator !=(const char * str) const {return *this != PIString(str);} @@ -128,7 +129,7 @@ public: bool operator <(const PIString & str) const; //! Compare operator - bool operator <(const PIChar c) const {return *this < PIString(c);} + bool operator <(const PIChar c) const {if (size_s() != 1) return size_s() < 1; return at(0) < c;} //! Compare operator bool operator <(const char * str) const {return *this < PIString(str);} @@ -137,7 +138,7 @@ public: bool operator >(const PIString & str) const; //! Compare operator - bool operator >(const PIChar c) const {return *this > PIString(c);} + bool operator >(const PIChar c) const {if (size_s() != 1) return size_s() > 1; return at(0) > c;} //! Compare operator bool operator >(const char * str) const {return *this > PIString(str);} @@ -146,7 +147,7 @@ public: bool operator <=(const PIString & str) const {return !(*this > str);} //! Compare operator - bool operator <=(const PIChar c) const {return *this <= PIString(c);} + bool operator <=(const PIChar c) const {return !(*this > c);} //! Compare operator bool operator <=(const char * str) const {return *this <= PIString(str);} @@ -155,7 +156,7 @@ public: bool operator >=(const PIString & str) const {return !(*this < str);} //! Compare operator - bool operator >=(const PIChar c) const {return *this >= PIString(c);} + bool operator >=(const PIChar c) const {return !(*this < c);} //! Compare operator bool operator >=(const char * str) const {return *this >= PIString(str);} @@ -166,7 +167,11 @@ public: /*! \brief Append symbol "c" at the end of string * \details Example: \snippet pistring.cpp PIString::<<(PIChar) */ - PIString & operator <<(const PIChar & c) {*this += c; return *this;} + PIString & operator <<(const PIChar c) {*this += c; return *this;} + + /*! \brief Append symbol "c" at the end of string + * \details Example: \snippet pistring.cpp PIString::<<(PIChar) */ + PIString & operator <<(const char c) {*this += PIChar(c); return *this;} /*! \brief Append c-string "str" at the end of string * \details Example: \snippet pistring.cpp PIString::<<(char * ) */ @@ -181,11 +186,6 @@ public: PIString & operator <<(const int & num) {*this += PIString::fromNumber(num); return *this;} PIString & operator <<(const uint & num) {*this += PIString::fromNumber(num); return *this;} - /*! \brief Append string representation of "num" at the end of string - * \details Example: \snippet pistring.cpp PIString::<<(int) */ - PIString & operator <<(const short & num) {*this += PIString::fromNumber(num); return *this;} - PIString & operator <<(const ushort & num) {*this += PIString::fromNumber(num); return *this;} - /*! \brief Append string representation of "num" at the end of string * \details Example: \snippet pistring.cpp PIString::<<(int) */ PIString & operator <<(const long & num) {*this += PIString::fromNumber(num); return *this;} @@ -282,8 +282,20 @@ public: * \details Example: \snippet pistring.cpp PIString::replaceAll * \sa \a replace(), \a replaced() */ PIString & replaceAll(const PIString & what, const PIString & with); - PIString replaceAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;} - + + /*! \brief Replace all founded symbols "what" with symbol "with" and return this string + * \details Example: \snippet pistring.cpp PIString::replaceAll + * \sa \a replace(), \a replaced() */ + PIString & replaceAll(const char what, const char with); + + PIString replacedAll(const PIString & what, const PIString & with) const {PIString str(*this); str.replaceAll(what, with); return str;} + + PIString replacedAll(const char what, const char with) const {PIString str(*this); str.replaceAll(what, with); return str;} + + PIString & removeAll(const PIString & str); + + PIString & removeAll(char c) {PIDeque::removeAll(PIChar(c)); return *this;} + /*! \brief Repeat content of string "times" times and return this string * \details Example: \snippet pistring.cpp PIString::repeat */ PIString & repeat(int times) {PIString ss(*this); times--; piForTimes (times) *this += ss; return *this;} @@ -294,11 +306,11 @@ public: /*! \brief Insert symbol "c" after index "index" and return this string * \details Example: \snippet pistring.cpp PIString::insert_0 */ - PIString & insert(const int index, const PIChar & c) {PIDeque::insert(index, c); return *this;} + PIString & insert(const int index, const PIChar c) {PIDeque::insert(index, c); return *this;} /*! \brief Insert symbol "c" after index "index" and return this string * \details Example: \snippet pistring.cpp PIString::insert_1 */ - PIString & insert(const int index, const char & c) {return insert(index, PIChar(c));} + PIString & insert(const int index, const char c) {return insert(index, PIChar(c));} /*! \brief Insert string "str" after index "index" and return this string * \details Example: \snippet pistring.cpp PIString::insert_2 */ @@ -312,13 +324,13 @@ public: * "c" at the end of string, and return this string * \details Example: \snippet pistring.cpp PIString::expandRightTo * \sa \a expandLeftTo() */ - PIString & expandRightTo(const int len, const PIChar & c) {if (len > length()) resize(len, c); return *this;} + PIString & expandRightTo(const int len, const PIChar c) {if (len > length()) resize(len, c); return *this;} /*! \brief Enlarge string to length "len" by addition sequence of symbols * "c" at the beginning of string, and return this string * \details Example: \snippet pistring.cpp PIString::expandLeftTo * \sa \a expandRightTo() */ - PIString & expandLeftTo(const int len, const PIChar & c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} + PIString & expandLeftTo(const int len, const PIChar c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} /*! \brief Add "c" symbols at the beginning and end of the string, and return this string * \sa \a quoted() */ @@ -331,7 +343,7 @@ public: /*! \brief Reverse string and return this string * \details Example: \snippet pistring.cpp PIString::reverse * \sa \a reversed() */ - PIString & reverse() {PIString str(*this); clear(); piForeachR (const PIChar & c, str) push_back(c); return *this;} + PIString & reverse() {PIString str(*this); clear(); piForeachCR (PIChar c, str) push_back(c); return *this;} /*! \brief Reverse copy of this string and return it * \details Example: \snippet pistring.cpp PIString::reversed @@ -394,13 +406,13 @@ public: * \details "Shield" symbol prevent analysis of the next symbol. * Example: \snippet pistring.cpp PIString::takeRange * \sa \a takeSymbol(), \a takeWord(), \a takeLine(), \a takeNumber() */ - PIString takeRange(const PIChar & start, const PIChar & end, const PIChar & shield = '\\'); + PIString takeRange(const PIChar start, const PIChar end, const PIChar shield = '\\'); /*! \brief Return a string in brackets "start" and "end" symbols from the begin of this * string and return it. * \details Example: string = "a(b(c)d)e"; inBrackets('(', ')') = "b(c)d"; */ - PIString inBrackets(const PIChar & start, const PIChar & end) const; + PIString inBrackets(const PIChar start, const PIChar end) const; /*! \brief Return real bytes count of this string * \details It`s equivalent length of char sequence @@ -467,11 +479,8 @@ public: PIString toNativeDecimalPoints() const; - //! \brief Returns if string contains "str" - bool contains(const char str) const {return contains(PIString(str));} - - //! \brief Returns if string contains "str" - bool contains(const PIChar str) const {return contains(PIString(str));} + //! \brief Returns if string contains "c" + bool contains(const char c) const {return PIDeque::contains(PIChar(c));} //! \brief Returns if string contains "str" bool contains(const char * str) const {return contains(PIString(str));} @@ -480,9 +489,9 @@ public: bool contains(const PIString & str) const {return find(str) >= 0;} - //! \brief Search substring "str" from symbol at index "start" and return first occur position + //! \brief Search symbol "c" from symbol at index "start" and return first occur position //! \details Example: \snippet pistring.cpp PIString::find - int find(const char str, const int start = 0) const; + int find(const char c, const int start = 0) const; //! \brief Search substring "str" from symbol at index "start" and return first occur position //! \details Example: \snippet pistring.cpp PIString::find @@ -492,9 +501,9 @@ public: //! \details Example: \snippet pistring.cpp PIString::find int find(const char * str, const int start = 0) const {return find(PIString(str), start);} - //! \brief Search substring "str" from symbol at index "start" and return last occur position + //! \brief Search symbol "c" from symbol at index "start" and return last occur position //! \details Example: \snippet pistring.cpp PIString::findLast - int findLast(const char str, const int start = 0) const; + int findLast(const char c, const int start = 0) const; //! \brief Search substring "str" from symbol at index "start" and return last occur position //! \details Example: \snippet pistring.cpp PIString::findLast @@ -514,7 +523,7 @@ public: //! \brief Search range between "start" and "end" symbols at index "start_index" and return first occur position. //! \details Example: \snippet pistring.cpp PIString::findRange - int findRange(const PIChar & start, const PIChar & end, const PIChar & shield = '\\', const int start_index = 0, int * len = 0) const; + int findRange(const PIChar start, const PIChar end, const PIChar shield = '\\', const int start_index = 0, int * len = 0) const; //! \brief Search any symbol of "str" from symbol at index "start" and return first occur position //! \details Example: \snippet pistring.cpp PIString::findAny @@ -533,7 +542,7 @@ public: int findAnyLast(const char * str, const int start = 0) const {return findAnyLast(PIString(str), start);} //! \brief Returns number of occurrences of symbol "c" - int entries(const PIChar & c) const; + int entries(const PIChar c) const; //! \brief Returns number of occurrences of symbol "c" int entries(char c) const {return entries(PIChar(c));} @@ -718,9 +727,6 @@ public: //! \details Example: \snippet pistring.cpp PIString::readableSize static PIString readableSize(llong bytes); - PIString & removeAll(char v) {replaceAll(v, ""); return *this;} - PIString & removeAll(const PIString & v) {replaceAll(v, ""); return *this;} - private: static const char toBaseN[]; static const int fromBaseN[]; @@ -763,6 +769,12 @@ inline PIString operator +(const PIString & f, const char * str) {PIString s(f); //! \relatesalso PIString \brief Return concatenated string inline PIString operator +(const char * str, const PIString & f) {return PIString(str) + f;} +//! \relatesalso PIString \brief Return concatenated string +inline PIString operator +(const char c, const PIString & f) {return PIChar(c) + f;} + +//! \relatesalso PIString \brief Return concatenated string +inline PIString operator +(const PIString & f, const char c) {return f + PIChar(c);} + inline char chrUpr(char c); inline char chrLwr(char c); diff --git a/lib/main/io_devices/pifile.cpp b/lib/main/io_devices/pifile.cpp index cc9d0d9c..065cc635 100644 --- a/lib/main/io_devices/pifile.cpp +++ b/lib/main/io_devices/pifile.cpp @@ -593,7 +593,7 @@ void PIFile::setDefaultCharset(const char * c) { PIFile::FileInfo PIFile::fileInfo(const PIString & path) { FileInfo ret; if (path.isEmpty()) return ret; - ret.path = path.replaceAll("\\", PIDir::separator); + ret.path = path.replacedAll("\\", PIDir::separator); PIString n = ret.name(); //piCout << "open" << path; #ifdef WINDOWS diff --git a/lib/main/io_devices/piiodevice.cpp b/lib/main/io_devices/piiodevice.cpp index f4919052..ec54085b 100644 --- a/lib/main/io_devices/piiodevice.cpp +++ b/lib/main/io_devices/piiodevice.cpp @@ -382,7 +382,7 @@ void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode * int dm = 0; DeviceOptions op = 0; if (fpwm.find("(") > 0 && fpwm.find(")") > 0) { - PIString dms(fpwm.right(fpwm.length() - fpwm.findLast("(")).takeRange("(", ")").trim().toLowerCase().removeAll(" ")); + PIString dms(fpwm.right(fpwm.length() - fpwm.findLast("(")).takeRange("(", ")").trim().toLowerCase().removeAll(' ')); PIStringList opts(dms.split(",")); piForeachC (PIString & o, opts) { //piCout << dms; diff --git a/main.cpp b/main.cpp index 923d74ee..f0613273 100644 --- a/main.cpp +++ b/main.cpp @@ -34,36 +34,25 @@ int main() { class db { public: db() { - for (int i=0; i<1000; ++i) + for (int i=0; i<10000; ++i) x << sin(double(i)/180.0); - printf("jkfkhg\n"); + //printf("jkfkhg\n"); } -// db(const db & d) {x = d.x;} -// db(db && o) {x.swap(o.x);} private: PIVector x; }; #include "picodeparser.h" int main() { + /*PIString s(" 324 654 sf 5fdwg sdfsdf sdfefg"); + piCout << s; + piCout << s.replaceAll(' ', '1');*/ piDebug = false; - printf("==============\n"); double min = -1, max = -1, mean = 0; for (int i = 0; i < 50; ++i) { + PICodeParser cp; PITimeMeasurer tm; - /*PICodeParser cp; - cp.parseFile("SH_plugin_base.h");*/ - PIVector sl; - sl.reserve(10000); - db d; - for (int i = 0; i < 10000; ++i) { -// db b(d); -// db c(b); -// c = b; -// sl << c; - sl << db(d); -// sl << std::move(d); - } + cp.parseFile("SH_plugin_base.h"); double ms = tm.elapsed_m(); if (min < 0) min = ms; if (max < 0) max = ms; diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index 7bff7667..cb42eaac 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -331,13 +331,13 @@ void makeGetterValue(PIFile & f, const PICodeParser::Entity * e) { void writeModel(PICodeParser & parser, PICLI & cli, const PIString out, bool meta, bool enums, bool streams, bool texts, bool getters) { PIVector ventities; PIString defname = out - .replaceAll(".", "_") - .replaceAll("/", "_") - .replaceAll(":", "_") - .replaceAll("-", "_") - .replaceAll("@", "_") - .replaceAll("\\", "_") - .removeAll(" ") + .replacedAll('.', '_') + .replaceAll('/', '_') + .replaceAll(':', '_') + .replaceAll('-', '_') + .replaceAll('@', '_') + .replaceAll('\\', '_') + .removeAll(' ') .toUpperCase() + "_H"; bool inc_h, inc_cpp; From 21111b3e67e3e32881c743ada7a25c6e0d1b071e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 31 Jul 2020 15:47:08 +0300 Subject: [PATCH 23/68] move tests to separate dir create macro "pip_test()" for easily add new tests --- CMakeLists.txt | 34 +- tests/CMakeLists.txt | 15 + .../GTestCMakeLists.txt.in | 30 +- .../concurrent}/BlockingDequeueUnitTest.cpp | 528 +++++++++--------- .../ConditionLockIntegrationTest.cpp | 106 ++-- .../ConditionVariableIntegrationTest.cpp | 400 ++++++------- .../concurrent}/ExecutorIntegrationTest.cpp | 108 ++-- .../test => tests/concurrent}/testutil.h | 120 ++-- 8 files changed, 675 insertions(+), 666 deletions(-) create mode 100644 tests/CMakeLists.txt rename GTestCMakeLists.txt.in => tests/GTestCMakeLists.txt.in (97%) rename {lib/concurrent/test => tests/concurrent}/BlockingDequeueUnitTest.cpp (97%) rename {lib/concurrent/test => tests/concurrent}/ConditionLockIntegrationTest.cpp (95%) rename {lib/concurrent/test => tests/concurrent}/ConditionVariableIntegrationTest.cpp (96%) rename {lib/concurrent/test => tests/concurrent}/ExecutorIntegrationTest.cpp (96%) rename {lib/concurrent/test => tests/concurrent}/testutil.h (96%) diff --git a/CMakeLists.txt b/CMakeLists.txt index f530f135..678f5e13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 1) set(_PIP_MINOR 99) -set(_PIP_REVISION 1) +set(_PIP_REVISION 2) set(_PIP_SUFFIX _prebeta) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) @@ -98,11 +98,7 @@ set(PIP_OPENCL "no") set(PIP_LUA "no") set(PIP_IOUTILS "yes") set(PIP_UTILS_LIST) - -if (TESTS) - include(DownloadGTest) - set(PIP_CONCURRENT_TEST "lib/concurrent/test") -endif() +set(PIP_TESTS_LIST) if (DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) set(STATIC_LIB ON) @@ -199,6 +195,11 @@ foreach(F ${PIP_FOLDERS}) include_directories("${PIP_SRC_MAIN}/${F}") gather_src("${PIP_SRC_MAIN}/${F}" CPP_LIB_MAIN HDRS PHDRS) endforeach(F) + +if (TESTS) + add_subdirectory(tests) +endif() + # Crypt lib gather_src("${PIP_SRC_CRYPT}" CPP_LIB_CRYPT HDRS PHDRS) @@ -226,11 +227,6 @@ gather_src("${PIP_SRC_CLOUD}" CPP_LIB_CLOUD HDRS PHDRS) # LUA lib gather_src("${PIP_SRC_LUA}" CPP_LIB_LUA HDRS PHDRS) -if (TESTS) - # Concurrent lib tests - gather_src("${PIP_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS) -endif() - if(PIP_FREERTOS) add_definitions(-DPIP_FREERTOS) set(ICU OFF) @@ -579,15 +575,6 @@ if (NOT CROSSTOOLS) list(APPEND PIP_LIBS_TARGETS pip_io_utils) - # Enable build tests for concurrent module - if(PIP_CONCURRENT_TEST) - add_executable(pip_concurrent_test ${CPP_CONCURRENT_TEST}) - target_link_libraries(pip_concurrent_test pip gtest_main gmock_main) - add_test(NAME pip_concurrent_test COMMAND tests) - add_custom_target(pip_concurrent_test_perform ALL COMMAND pip_concurrent_test) - endif() - - # Build cloud library if crypt enabled if(sodium_FOUND) import_version(pip_cloud pip) @@ -800,6 +787,13 @@ message(" OpenCL : ${PIP_OPENCL}") message(" IOUtils : ${PIP_IOUTILS}") message(" Cloud : ${PIP_CLOUD}") message(" Lua : ${PIP_LUA}") +if (PIP_TESTS_LIST) + message("") + message(" Tests:") + foreach(_test ${PIP_TESTS_LIST}) + message(" * ${_test}") + endforeach() +endif() message("") message(" Utilites:") foreach(_util ${PIP_UTILS_LIST}) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000..bcb399c3 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,15 @@ +include(DownloadGTest) + +macro(pip_test NAME LIBS) + gather_src("${NAME}" CPP_${NAME}_TEST _T_H _T_PH) + set(_target pip_${NAME}_test) + add_executable(${_target} ${CPP_${NAME}_TEST}) + target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main) + add_test(NAME ${_target} COMMAND tests) + add_custom_target(${_target}_perform ALL COMMAND ${_target}) + list(APPEND PIP_TESTS_LIST "${NAME}") + set(PIP_TESTS_LIST ${PIP_TESTS_LIST} PARENT_SCOPE) +endmacro() + +# Concurrent tests +pip_test(concurrent "") diff --git a/GTestCMakeLists.txt.in b/tests/GTestCMakeLists.txt.in similarity index 97% rename from GTestCMakeLists.txt.in rename to tests/GTestCMakeLists.txt.in index aacb573a..51b1cc0c 100644 --- a/GTestCMakeLists.txt.in +++ b/tests/GTestCMakeLists.txt.in @@ -1,16 +1,16 @@ -cmake_minimum_required(VERSION 2.8.2) - -project(googletest-download NONE) - -include(ExternalProject) -ExternalProject_Add(googletest - GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG "dea0216d0c6bc5e63cf5f6c8651cd268668032ec" - GIT_CONFIG "advice.detachedHead=false" - SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" - BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" - CONFIGURE_COMMAND "" - BUILD_COMMAND "" - INSTALL_COMMAND "" - TEST_COMMAND "" +cmake_minimum_required(VERSION 2.8.2) + +project(googletest-download NONE) + +include(ExternalProject) +ExternalProject_Add(googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG "dea0216d0c6bc5e63cf5f6c8651cd268668032ec" + GIT_CONFIG "advice.detachedHead=false" + SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" + BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + TEST_COMMAND "" ) \ No newline at end of file diff --git a/lib/concurrent/test/BlockingDequeueUnitTest.cpp b/tests/concurrent/BlockingDequeueUnitTest.cpp similarity index 97% rename from lib/concurrent/test/BlockingDequeueUnitTest.cpp rename to tests/concurrent/BlockingDequeueUnitTest.cpp index fb673059..fae9f3ff 100644 --- a/lib/concurrent/test/BlockingDequeueUnitTest.cpp +++ b/tests/concurrent/BlockingDequeueUnitTest.cpp @@ -1,264 +1,264 @@ -#include "gtest/gtest.h" -#include "piblockingdequeue.h" - -class MockConditionVar: public PIConditionVariable { -public: - bool isWaitCalled = false; - bool isWaitForCalled = false; - bool isTrueCondition = false; - int timeout = -1; - - void wait(PIMutex& lk) override { - isWaitCalled = true; - } - - void wait(PIMutex& lk, const std::function& condition) override { - isWaitCalled = true; - lk.lock(); - isTrueCondition = condition(); - lk.unlock(); - } - - bool waitFor(PIMutex& lk, int timeoutMs) override { - isWaitForCalled = true; - timeout = timeoutMs; - return false; - } - - bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition) override { - isWaitForCalled = true; - lk.lock(); - isTrueCondition = condition(); - timeout = timeoutMs; - lk.unlock(); - return isTrueCondition; - } -}; - -TEST(BlockingDequeueUnitTest, put_is_block_when_capacity_reach) { - size_t capacity = 0; - auto conditionVarAdd = new MockConditionVar(); - auto conditionVarRem = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); - dequeue.put(11); - ASSERT_TRUE(conditionVarRem->isWaitCalled); - ASSERT_FALSE(conditionVarRem->isTrueCondition); -} - -TEST(BlockingDequeueUnitTest, offer_timedout_is_false_when_capacity_reach) { - size_t capacity = 0; - int timeout = 11; - auto conditionVarAdd = new MockConditionVar(); - auto conditionVarRem = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); - ASSERT_FALSE(dequeue.offer(11, timeout)); -} - -TEST(BlockingDequeueUnitTest, offer_timedout_is_block_when_capacity_reach) { - size_t capacity = 0; - int timeout = 11; - auto conditionVarAdd = new MockConditionVar(); - auto conditionVarRem = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); - dequeue.offer(11, timeout); - EXPECT_TRUE(conditionVarRem->isWaitForCalled); - EXPECT_EQ(timeout, conditionVarRem->timeout); - ASSERT_FALSE(conditionVarRem->isTrueCondition); -} - -TEST(BlockingDequeueUnitTest, offer_is_true_before_capacity_reach) { - size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); - ASSERT_TRUE(dequeue.offer(10)); -} - -TEST(BlockingDequeueUnitTest, offer_is_false_when_capacity_reach) { - size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); - dequeue.offer(11); - ASSERT_FALSE(dequeue.offer(10)); -} - -// TODO change take_is_block_when_empty to prevent segfault -TEST(DISABLED_BlockingDequeueUnitTest, take_is_block_when_empty) { - size_t capacity = 1; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - // May cause segfault because take front of empty queue - dequeue.take(); - EXPECT_TRUE(conditionVar->isWaitCalled); - ASSERT_FALSE(conditionVar->isTrueCondition); -} - -TEST(BlockingDequeueUnitTest, take_is_not_block_when_not_empty) { - size_t capacity = 1; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.offer(111); - dequeue.take(); - - EXPECT_TRUE(conditionVar->isWaitCalled); - ASSERT_TRUE(conditionVar->isTrueCondition); -} - -TEST(BlockingDequeueUnitTest, take_is_value_eq_to_offer_value) { - size_t capacity = 1; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - - dequeue.offer(111); - ASSERT_EQ(dequeue.take(), 111); -} - -TEST(BlockingDequeueUnitTest, take_is_last) { - size_t capacity = 10; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - EXPECT_TRUE(dequeue.offer(111)); - EXPECT_TRUE(dequeue.offer(222)); - ASSERT_EQ(dequeue.take(), 111); - ASSERT_EQ(dequeue.take(), 222); -} - -TEST(BlockingDequeueUnitTest, poll_is_not_block_when_empty) { - size_t capacity = 1; - bool isOk; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.poll(111, &isOk); - EXPECT_FALSE(conditionVar->isWaitForCalled); -} - -TEST(BlockingDequeueUnitTest, poll_is_default_value_when_empty) { - size_t capacity = 1; - bool isOk; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - ASSERT_EQ(dequeue.poll(111, &isOk), 111); -} - -TEST(BlockingDequeueUnitTest, poll_is_offer_value_when_not_empty) { - size_t capacity = 1; - bool isOk; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.offer(111); - ASSERT_EQ(dequeue.poll(-1, &isOk), 111); -} - -TEST(BlockingDequeueUnitTest, poll_timeouted_is_block_when_empty) { - size_t capacity = 1; - int timeout = 11; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.poll(timeout, 111); - EXPECT_TRUE(conditionVar->isWaitForCalled); - EXPECT_EQ(timeout, conditionVar->timeout); - ASSERT_FALSE(conditionVar->isTrueCondition); -} - -TEST(BlockingDequeueUnitTest, poll_timeouted_is_default_value_when_empty) { - size_t capacity = 1; - int timeout = 11; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - ASSERT_EQ(dequeue.poll(timeout, 111), 111); -} - -TEST(BlockingDequeueUnitTest, poll_timeouted_is_not_block_when_not_empty) { - size_t capacity = 1; - int timeout = 11; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.offer(111); - dequeue.poll(timeout, -1); - - EXPECT_TRUE(conditionVar->isWaitForCalled); - ASSERT_TRUE(conditionVar->isTrueCondition); -} - -TEST(BlockingDequeueUnitTest, poll_timeouted_is_offer_value_when_not_empty) { - size_t capacity = 1; - int timeout = 11; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.offer(111); - ASSERT_EQ(dequeue.poll(timeout, -1), 111); -} - -TEST(BlockingDequeueUnitTest, poll_timeouted_is_last) { - size_t capacity = 10; - auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.offer(111); - dequeue.offer(222); - ASSERT_EQ(dequeue.poll(10, -1), 111); - ASSERT_EQ(dequeue.poll(10, -1), 222); -} - -TEST(BlockingDequeueUnitTest, capacity_is_eq_constructor_capacity) { - size_t capacity = 10; - PIBlockingDequeue dequeue(capacity); - ASSERT_EQ(dequeue.capacity(), capacity); -} - -TEST(BlockingDequeueUnitTest, remainingCapacity_is_dif_of_capacity_and_size) { - size_t capacity = 2; - PIBlockingDequeue dequeue(capacity); - ASSERT_EQ(dequeue.remainingCapacity(), capacity); - dequeue.offer(111); - ASSERT_EQ(dequeue.remainingCapacity(), capacity - 1); -} - -TEST(BlockingDequeueUnitTest, remainingCapacity_is_zero_when_capacity_reach) { - size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); - dequeue.offer(111); - dequeue.offer(111); - ASSERT_EQ(dequeue.remainingCapacity(), 0); -} - -TEST(BlockingDequeueUnitTest, size_is_eq_to_num_of_elements) { - size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); - ASSERT_EQ(dequeue.size(), 0); - dequeue.offer(111); - ASSERT_EQ(dequeue.size(), 1); -} - -TEST(BlockingDequeueUnitTest, size_is_eq_to_capacity_when_capacity_reach) { - size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); - dequeue.offer(111); - dequeue.offer(111); - ASSERT_EQ(dequeue.size(), capacity); -} - -TEST(BlockingDequeueUnitTest, drainTo_is_elements_moved) { - size_t capacity = 10; - PIDeque refDeque; - for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); - PIBlockingDequeue blockingDequeue(refDeque); - PIDeque deque; - blockingDequeue.drainTo(deque); - ASSERT_EQ(blockingDequeue.size(), 0); - ASSERT_TRUE(deque == refDeque); -} - -TEST(BlockingDequeueUnitTest, drainTo_is_ret_eq_to_size_when_all_moved) { - size_t capacity = 10; - PIDeque refDeque; - for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); - PIBlockingDequeue blockingDequeue(refDeque); - PIDeque deque; - ASSERT_EQ(blockingDequeue.drainTo(deque), refDeque.size()); -} - -TEST(BlockingDequeueUnitTest, drainTo_is_ret_eq_to_maxCount) { - size_t capacity = 10; - PIDeque refDeque; - for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); - PIBlockingDequeue blockingDequeue(refDeque); - PIDeque deque; - ASSERT_EQ(blockingDequeue.drainTo(deque, refDeque.size() - 1), refDeque.size() - 1); -} +#include "gtest/gtest.h" +#include "piblockingdequeue.h" + +class MockConditionVar: public PIConditionVariable { +public: + bool isWaitCalled = false; + bool isWaitForCalled = false; + bool isTrueCondition = false; + int timeout = -1; + + void wait(PIMutex& lk) override { + isWaitCalled = true; + } + + void wait(PIMutex& lk, const std::function& condition) override { + isWaitCalled = true; + lk.lock(); + isTrueCondition = condition(); + lk.unlock(); + } + + bool waitFor(PIMutex& lk, int timeoutMs) override { + isWaitForCalled = true; + timeout = timeoutMs; + return false; + } + + bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition) override { + isWaitForCalled = true; + lk.lock(); + isTrueCondition = condition(); + timeout = timeoutMs; + lk.unlock(); + return isTrueCondition; + } +}; + +TEST(BlockingDequeueUnitTest, put_is_block_when_capacity_reach) { + size_t capacity = 0; + auto conditionVarAdd = new MockConditionVar(); + auto conditionVarRem = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); + dequeue.put(11); + ASSERT_TRUE(conditionVarRem->isWaitCalled); + ASSERT_FALSE(conditionVarRem->isTrueCondition); +} + +TEST(BlockingDequeueUnitTest, offer_timedout_is_false_when_capacity_reach) { + size_t capacity = 0; + int timeout = 11; + auto conditionVarAdd = new MockConditionVar(); + auto conditionVarRem = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); + ASSERT_FALSE(dequeue.offer(11, timeout)); +} + +TEST(BlockingDequeueUnitTest, offer_timedout_is_block_when_capacity_reach) { + size_t capacity = 0; + int timeout = 11; + auto conditionVarAdd = new MockConditionVar(); + auto conditionVarRem = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); + dequeue.offer(11, timeout); + EXPECT_TRUE(conditionVarRem->isWaitForCalled); + EXPECT_EQ(timeout, conditionVarRem->timeout); + ASSERT_FALSE(conditionVarRem->isTrueCondition); +} + +TEST(BlockingDequeueUnitTest, offer_is_true_before_capacity_reach) { + size_t capacity = 1; + PIBlockingDequeue dequeue(capacity); + ASSERT_TRUE(dequeue.offer(10)); +} + +TEST(BlockingDequeueUnitTest, offer_is_false_when_capacity_reach) { + size_t capacity = 1; + PIBlockingDequeue dequeue(capacity); + dequeue.offer(11); + ASSERT_FALSE(dequeue.offer(10)); +} + +// TODO change take_is_block_when_empty to prevent segfault +TEST(DISABLED_BlockingDequeueUnitTest, take_is_block_when_empty) { + size_t capacity = 1; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + // May cause segfault because take front of empty queue + dequeue.take(); + EXPECT_TRUE(conditionVar->isWaitCalled); + ASSERT_FALSE(conditionVar->isTrueCondition); +} + +TEST(BlockingDequeueUnitTest, take_is_not_block_when_not_empty) { + size_t capacity = 1; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.offer(111); + dequeue.take(); + + EXPECT_TRUE(conditionVar->isWaitCalled); + ASSERT_TRUE(conditionVar->isTrueCondition); +} + +TEST(BlockingDequeueUnitTest, take_is_value_eq_to_offer_value) { + size_t capacity = 1; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + + dequeue.offer(111); + ASSERT_EQ(dequeue.take(), 111); +} + +TEST(BlockingDequeueUnitTest, take_is_last) { + size_t capacity = 10; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + EXPECT_TRUE(dequeue.offer(111)); + EXPECT_TRUE(dequeue.offer(222)); + ASSERT_EQ(dequeue.take(), 111); + ASSERT_EQ(dequeue.take(), 222); +} + +TEST(BlockingDequeueUnitTest, poll_is_not_block_when_empty) { + size_t capacity = 1; + bool isOk; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.poll(111, &isOk); + EXPECT_FALSE(conditionVar->isWaitForCalled); +} + +TEST(BlockingDequeueUnitTest, poll_is_default_value_when_empty) { + size_t capacity = 1; + bool isOk; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + ASSERT_EQ(dequeue.poll(111, &isOk), 111); +} + +TEST(BlockingDequeueUnitTest, poll_is_offer_value_when_not_empty) { + size_t capacity = 1; + bool isOk; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.offer(111); + ASSERT_EQ(dequeue.poll(-1, &isOk), 111); +} + +TEST(BlockingDequeueUnitTest, poll_timeouted_is_block_when_empty) { + size_t capacity = 1; + int timeout = 11; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.poll(timeout, 111); + EXPECT_TRUE(conditionVar->isWaitForCalled); + EXPECT_EQ(timeout, conditionVar->timeout); + ASSERT_FALSE(conditionVar->isTrueCondition); +} + +TEST(BlockingDequeueUnitTest, poll_timeouted_is_default_value_when_empty) { + size_t capacity = 1; + int timeout = 11; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + ASSERT_EQ(dequeue.poll(timeout, 111), 111); +} + +TEST(BlockingDequeueUnitTest, poll_timeouted_is_not_block_when_not_empty) { + size_t capacity = 1; + int timeout = 11; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.offer(111); + dequeue.poll(timeout, -1); + + EXPECT_TRUE(conditionVar->isWaitForCalled); + ASSERT_TRUE(conditionVar->isTrueCondition); +} + +TEST(BlockingDequeueUnitTest, poll_timeouted_is_offer_value_when_not_empty) { + size_t capacity = 1; + int timeout = 11; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.offer(111); + ASSERT_EQ(dequeue.poll(timeout, -1), 111); +} + +TEST(BlockingDequeueUnitTest, poll_timeouted_is_last) { + size_t capacity = 10; + auto conditionVar = new MockConditionVar(); + PIBlockingDequeue dequeue(capacity, conditionVar); + dequeue.offer(111); + dequeue.offer(222); + ASSERT_EQ(dequeue.poll(10, -1), 111); + ASSERT_EQ(dequeue.poll(10, -1), 222); +} + +TEST(BlockingDequeueUnitTest, capacity_is_eq_constructor_capacity) { + size_t capacity = 10; + PIBlockingDequeue dequeue(capacity); + ASSERT_EQ(dequeue.capacity(), capacity); +} + +TEST(BlockingDequeueUnitTest, remainingCapacity_is_dif_of_capacity_and_size) { + size_t capacity = 2; + PIBlockingDequeue dequeue(capacity); + ASSERT_EQ(dequeue.remainingCapacity(), capacity); + dequeue.offer(111); + ASSERT_EQ(dequeue.remainingCapacity(), capacity - 1); +} + +TEST(BlockingDequeueUnitTest, remainingCapacity_is_zero_when_capacity_reach) { + size_t capacity = 1; + PIBlockingDequeue dequeue(capacity); + dequeue.offer(111); + dequeue.offer(111); + ASSERT_EQ(dequeue.remainingCapacity(), 0); +} + +TEST(BlockingDequeueUnitTest, size_is_eq_to_num_of_elements) { + size_t capacity = 1; + PIBlockingDequeue dequeue(capacity); + ASSERT_EQ(dequeue.size(), 0); + dequeue.offer(111); + ASSERT_EQ(dequeue.size(), 1); +} + +TEST(BlockingDequeueUnitTest, size_is_eq_to_capacity_when_capacity_reach) { + size_t capacity = 1; + PIBlockingDequeue dequeue(capacity); + dequeue.offer(111); + dequeue.offer(111); + ASSERT_EQ(dequeue.size(), capacity); +} + +TEST(BlockingDequeueUnitTest, drainTo_is_elements_moved) { + size_t capacity = 10; + PIDeque refDeque; + for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); + PIBlockingDequeue blockingDequeue(refDeque); + PIDeque deque; + blockingDequeue.drainTo(deque); + ASSERT_EQ(blockingDequeue.size(), 0); + ASSERT_TRUE(deque == refDeque); +} + +TEST(BlockingDequeueUnitTest, drainTo_is_ret_eq_to_size_when_all_moved) { + size_t capacity = 10; + PIDeque refDeque; + for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); + PIBlockingDequeue blockingDequeue(refDeque); + PIDeque deque; + ASSERT_EQ(blockingDequeue.drainTo(deque), refDeque.size()); +} + +TEST(BlockingDequeueUnitTest, drainTo_is_ret_eq_to_maxCount) { + size_t capacity = 10; + PIDeque refDeque; + for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); + PIBlockingDequeue blockingDequeue(refDeque); + PIDeque deque; + ASSERT_EQ(blockingDequeue.drainTo(deque, refDeque.size() - 1), refDeque.size() - 1); +} diff --git a/lib/concurrent/test/ConditionLockIntegrationTest.cpp b/tests/concurrent/ConditionLockIntegrationTest.cpp similarity index 95% rename from lib/concurrent/test/ConditionLockIntegrationTest.cpp rename to tests/concurrent/ConditionLockIntegrationTest.cpp index 13a6c6f6..e7f211ae 100644 --- a/lib/concurrent/test/ConditionLockIntegrationTest.cpp +++ b/tests/concurrent/ConditionLockIntegrationTest.cpp @@ -1,53 +1,53 @@ -#include "gtest/gtest.h" -#include "gmock/gmock.h" - -#include "piconditionvar.h" -#include "pithread.h" -#include "testutil.h" - -class ConditionLock : public ::testing::Test, public TestUtil { -public: - PIMutex* m = new PIMutex(); -}; - -TEST_F(ConditionLock, lock_is_protect) { - m->lock(); - bool* isProtect = new bool(true); - - createThread([&](){ - m->lock(); - *isProtect = false; - }); - EXPECT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); - ASSERT_TRUE(*isProtect); -} - -TEST_F(ConditionLock, unlock_is_release) { - m->lock(); - bool* isReleased = new bool(false); - m->unlock(); - - createThread([&](){ - m->lock(); - *isReleased = true; - m->unlock(); - }); - ASSERT_TRUE(*isReleased); -} - -TEST_F(ConditionLock, tryLock_is_false_when_locked) { - createThread([&](){ - m->lock(); - piMSleep(WAIT_THREAD_TIME_MS); - }); - ASSERT_FALSE(m->tryLock()); -} - -TEST_F(ConditionLock, tryLock_is_true_when_unlocked) { - ASSERT_TRUE(m->tryLock()); -} - -TEST_F(ConditionLock, tryLock_is_recursive_lock_enable) { - m->lock(); - ASSERT_TRUE(m->tryLock()); -} +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include "piconditionvar.h" +#include "pithread.h" +#include "testutil.h" + +class ConditionLock : public ::testing::Test, public TestUtil { +public: + PIMutex* m = new PIMutex(); +}; + +TEST_F(ConditionLock, lock_is_protect) { + m->lock(); + bool* isProtect = new bool(true); + + createThread([&](){ + m->lock(); + *isProtect = false; + }); + EXPECT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); + ASSERT_TRUE(*isProtect); +} + +TEST_F(ConditionLock, unlock_is_release) { + m->lock(); + bool* isReleased = new bool(false); + m->unlock(); + + createThread([&](){ + m->lock(); + *isReleased = true; + m->unlock(); + }); + ASSERT_TRUE(*isReleased); +} + +TEST_F(ConditionLock, tryLock_is_false_when_locked) { + createThread([&](){ + m->lock(); + piMSleep(WAIT_THREAD_TIME_MS); + }); + ASSERT_FALSE(m->tryLock()); +} + +TEST_F(ConditionLock, tryLock_is_true_when_unlocked) { + ASSERT_TRUE(m->tryLock()); +} + +TEST_F(ConditionLock, tryLock_is_recursive_lock_enable) { + m->lock(); + ASSERT_TRUE(m->tryLock()); +} diff --git a/lib/concurrent/test/ConditionVariableIntegrationTest.cpp b/tests/concurrent/ConditionVariableIntegrationTest.cpp similarity index 96% rename from lib/concurrent/test/ConditionVariableIntegrationTest.cpp rename to tests/concurrent/ConditionVariableIntegrationTest.cpp index a9d26cec..b8d82a92 100644 --- a/lib/concurrent/test/ConditionVariableIntegrationTest.cpp +++ b/tests/concurrent/ConditionVariableIntegrationTest.cpp @@ -1,200 +1,200 @@ -#include "gtest/gtest.h" -#include "piconditionvar.h" -#include "pithread.h" -#include "testutil.h" - -class ConditionVariable : public ::testing::Test, public TestUtil { -public: - PIMutex m; - PIConditionVariable* variable; - -protected: - void SetUp() override { - variable = new PIConditionVariable(); - adapterFunctionDefault = [&](){ - m.lock(); - variable->wait(m); - m.unlock(); - }; - } -}; - -TEST_F(ConditionVariable, wait_is_block) { - createThread(); - ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); -} - -TEST_F(ConditionVariable, wait_is_block_when_notifyOne_before_wait) { - variable->notifyOne(); - createThread(); - ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); -} - -TEST_F(ConditionVariable, wait_is_block_when_notifyAll_before_wait) { - variable->notifyAll(); - createThread(); - ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); -} - -TEST_F(ConditionVariable, wait_is_unblock_when_notifyOne_after_wait) { - createThread(); - variable->notifyOne(); - ASSERT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); -} - -TEST_F(ConditionVariable, wait_is_unblock_when_notifyAll_after_wait) { - PIVector threads; - - for (int i = 0; i < THREAD_COUNT; ++i) { - threads.push_back(new PIThread([=](){ adapterFunctionDefault(); })); - } - - piForeach(PIThread* thread, threads) thread->startOnce(); - piMSleep(WAIT_THREAD_TIME_MS * THREAD_COUNT); - variable->notifyAll(); - PITimeMeasurer measurer; - piForeach(PIThread* thread, threads) { - int timeout = WAIT_THREAD_TIME_MS * THREAD_COUNT - (int)measurer.elapsed_m(); - thread->waitForFinish(timeout > 0 ? timeout : 0); - } - for (size_t i = 0; i < threads.size(); ++i) EXPECT_FALSE(threads[i]->isRunning()) << "Thread " << i << " still running"; - piForeach(PIThread* thread, threads) delete thread; -} - -TEST_F(ConditionVariable, wait_is_one_unblock_when_notifyOne) { - PIVector threads; - - for (int i = 0; i < THREAD_COUNT; ++i) { - threads.push_back(new PIThread(adapterFunctionDefault)); - } - - piForeach(PIThread* thread, threads) thread->startOnce(); - piMSleep(WAIT_THREAD_TIME_MS * THREAD_COUNT); - variable->notifyOne(); - piMSleep(WAIT_THREAD_TIME_MS * THREAD_COUNT); - int runningThreadCount = 0; - piForeach(PIThread* thread, threads) if (thread->isRunning()) runningThreadCount++; - ASSERT_EQ(runningThreadCount, THREAD_COUNT - 1); -} - -TEST_F(ConditionVariable, wait_is_protected_unblock_when_notifyOne) { - createThread([&](){ - m.lock(); - variable->wait(m); - piMSleep(2 * WAIT_THREAD_TIME_MS); - // Missing unlock - }); - variable->notifyOne(); - msleep(WAIT_THREAD_TIME_MS); - ASSERT_FALSE(m.tryLock()); -} - -TEST_F(ConditionVariable, wait_condition_is_block) { - createThread([&](){ - m.lock(); - variable->wait(m, [](){ return false; }); - m.unlock(); - }); - ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); -} - -TEST_F(ConditionVariable, wait_condition_is_check_condition_before_block) { - bool isConditionChecked = false; - createThread([&](){ - m.lock(); - variable->wait(m, [&](){ - isConditionChecked = true; - return false; - }); - m.unlock(); - }); - m.lock(); - ASSERT_TRUE(isConditionChecked); - m.unlock(); -} - -TEST_F(ConditionVariable, wait_condition_is_check_condition_when_notifyOne) { - bool isConditionChecked; - createThread([&](){ - m.lock(); - variable->wait(m, [&](){ - isConditionChecked = true; - return false; - }); - m.unlock(); - }); - m.lock(); - isConditionChecked = false; - m.unlock(); - variable->notifyOne(); - msleep(threadStartTime + 1); - m.lock(); - ASSERT_TRUE(isConditionChecked); - m.unlock(); -} - -TEST_F(ConditionVariable, wait_condition_is_unblock_when_condition_and_notifyOne) { - bool condition = false; - createThread([&](){ - m.lock(); - variable->wait(m, [&](){ return condition; }); - m.unlock(); - }); - m.lock(); - condition = true; - m.unlock(); - variable->notifyOne(); - ASSERT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); -} - -TEST_F(ConditionVariable, DISABLED_waitFor_is_block_before_timeout) { - createThread([&](){ - PITimeMeasurer measurer; - m.lock(); - variable->waitFor(m, WAIT_THREAD_TIME_MS * 2); - m.unlock(); - // Not reliable because spurious wakeup may happen - ASSERT_GE(measurer.elapsed_m(), WAIT_THREAD_TIME_MS); - }); - EXPECT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS * 3)); -} - -TEST_F(ConditionVariable, waitFor_is_unblock_when_timeout) { - std::atomic_bool isUnblock(false); - createThread([&](){ - m.lock(); - variable->waitFor(m, WAIT_THREAD_TIME_MS); - isUnblock = true; - m.unlock(); - }); - // Test failed if suspend forever - EXPECT_TRUE(thread->waitForFinish(2 * WAIT_THREAD_TIME_MS)); - ASSERT_TRUE(isUnblock); -} - -TEST_F(ConditionVariable, waitFor_is_false_when_timeout) { - bool waitRet = true; - createThread([&](){ - m.lock(); - waitRet = variable->waitFor(m, WAIT_THREAD_TIME_MS); - m.unlock(); - }); - EXPECT_TRUE(thread->waitForFinish(2 * WAIT_THREAD_TIME_MS)); - ASSERT_FALSE(waitRet); -} - -TEST_F(ConditionVariable, waitFor_is_unblock_when_condition_and_notifyOne) { - bool condition = false; - createThread([&](){ - m.lock(); - variable->waitFor(m, 3 * WAIT_THREAD_TIME_MS, [&](){ return condition; }); - m.unlock(); - }); - EXPECT_TRUE(thread->isRunning()); - m.lock(); - condition = true; - m.unlock(); - variable->notifyOne(); - msleep(WAIT_THREAD_TIME_MS); - ASSERT_FALSE(thread->isRunning()); -} +#include "gtest/gtest.h" +#include "piconditionvar.h" +#include "pithread.h" +#include "testutil.h" + +class ConditionVariable : public ::testing::Test, public TestUtil { +public: + PIMutex m; + PIConditionVariable* variable; + +protected: + void SetUp() override { + variable = new PIConditionVariable(); + adapterFunctionDefault = [&](){ + m.lock(); + variable->wait(m); + m.unlock(); + }; + } +}; + +TEST_F(ConditionVariable, wait_is_block) { + createThread(); + ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); +} + +TEST_F(ConditionVariable, wait_is_block_when_notifyOne_before_wait) { + variable->notifyOne(); + createThread(); + ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); +} + +TEST_F(ConditionVariable, wait_is_block_when_notifyAll_before_wait) { + variable->notifyAll(); + createThread(); + ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); +} + +TEST_F(ConditionVariable, wait_is_unblock_when_notifyOne_after_wait) { + createThread(); + variable->notifyOne(); + ASSERT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); +} + +TEST_F(ConditionVariable, wait_is_unblock_when_notifyAll_after_wait) { + PIVector threads; + + for (int i = 0; i < THREAD_COUNT; ++i) { + threads.push_back(new PIThread([=](){ adapterFunctionDefault(); })); + } + + piForeach(PIThread* thread, threads) thread->startOnce(); + piMSleep(WAIT_THREAD_TIME_MS * THREAD_COUNT); + variable->notifyAll(); + PITimeMeasurer measurer; + piForeach(PIThread* thread, threads) { + int timeout = WAIT_THREAD_TIME_MS * THREAD_COUNT - (int)measurer.elapsed_m(); + thread->waitForFinish(timeout > 0 ? timeout : 0); + } + for (size_t i = 0; i < threads.size(); ++i) EXPECT_FALSE(threads[i]->isRunning()) << "Thread " << i << " still running"; + piForeach(PIThread* thread, threads) delete thread; +} + +TEST_F(ConditionVariable, wait_is_one_unblock_when_notifyOne) { + PIVector threads; + + for (int i = 0; i < THREAD_COUNT; ++i) { + threads.push_back(new PIThread(adapterFunctionDefault)); + } + + piForeach(PIThread* thread, threads) thread->startOnce(); + piMSleep(WAIT_THREAD_TIME_MS * THREAD_COUNT); + variable->notifyOne(); + piMSleep(WAIT_THREAD_TIME_MS * THREAD_COUNT); + int runningThreadCount = 0; + piForeach(PIThread* thread, threads) if (thread->isRunning()) runningThreadCount++; + ASSERT_EQ(runningThreadCount, THREAD_COUNT - 1); +} + +TEST_F(ConditionVariable, wait_is_protected_unblock_when_notifyOne) { + createThread([&](){ + m.lock(); + variable->wait(m); + piMSleep(2 * WAIT_THREAD_TIME_MS); + // Missing unlock + }); + variable->notifyOne(); + msleep(WAIT_THREAD_TIME_MS); + ASSERT_FALSE(m.tryLock()); +} + +TEST_F(ConditionVariable, wait_condition_is_block) { + createThread([&](){ + m.lock(); + variable->wait(m, [](){ return false; }); + m.unlock(); + }); + ASSERT_FALSE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); +} + +TEST_F(ConditionVariable, wait_condition_is_check_condition_before_block) { + bool isConditionChecked = false; + createThread([&](){ + m.lock(); + variable->wait(m, [&](){ + isConditionChecked = true; + return false; + }); + m.unlock(); + }); + m.lock(); + ASSERT_TRUE(isConditionChecked); + m.unlock(); +} + +TEST_F(ConditionVariable, wait_condition_is_check_condition_when_notifyOne) { + bool isConditionChecked; + createThread([&](){ + m.lock(); + variable->wait(m, [&](){ + isConditionChecked = true; + return false; + }); + m.unlock(); + }); + m.lock(); + isConditionChecked = false; + m.unlock(); + variable->notifyOne(); + msleep(threadStartTime + 1); + m.lock(); + ASSERT_TRUE(isConditionChecked); + m.unlock(); +} + +TEST_F(ConditionVariable, wait_condition_is_unblock_when_condition_and_notifyOne) { + bool condition = false; + createThread([&](){ + m.lock(); + variable->wait(m, [&](){ return condition; }); + m.unlock(); + }); + m.lock(); + condition = true; + m.unlock(); + variable->notifyOne(); + ASSERT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS)); +} + +TEST_F(ConditionVariable, DISABLED_waitFor_is_block_before_timeout) { + createThread([&](){ + PITimeMeasurer measurer; + m.lock(); + variable->waitFor(m, WAIT_THREAD_TIME_MS * 2); + m.unlock(); + // Not reliable because spurious wakeup may happen + ASSERT_GE(measurer.elapsed_m(), WAIT_THREAD_TIME_MS); + }); + EXPECT_TRUE(thread->waitForFinish(WAIT_THREAD_TIME_MS * 3)); +} + +TEST_F(ConditionVariable, waitFor_is_unblock_when_timeout) { + std::atomic_bool isUnblock(false); + createThread([&](){ + m.lock(); + variable->waitFor(m, WAIT_THREAD_TIME_MS); + isUnblock = true; + m.unlock(); + }); + // Test failed if suspend forever + EXPECT_TRUE(thread->waitForFinish(2 * WAIT_THREAD_TIME_MS)); + ASSERT_TRUE(isUnblock); +} + +TEST_F(ConditionVariable, waitFor_is_false_when_timeout) { + bool waitRet = true; + createThread([&](){ + m.lock(); + waitRet = variable->waitFor(m, WAIT_THREAD_TIME_MS); + m.unlock(); + }); + EXPECT_TRUE(thread->waitForFinish(2 * WAIT_THREAD_TIME_MS)); + ASSERT_FALSE(waitRet); +} + +TEST_F(ConditionVariable, waitFor_is_unblock_when_condition_and_notifyOne) { + bool condition = false; + createThread([&](){ + m.lock(); + variable->waitFor(m, 3 * WAIT_THREAD_TIME_MS, [&](){ return condition; }); + m.unlock(); + }); + EXPECT_TRUE(thread->isRunning()); + m.lock(); + condition = true; + m.unlock(); + variable->notifyOne(); + msleep(WAIT_THREAD_TIME_MS); + ASSERT_FALSE(thread->isRunning()); +} diff --git a/lib/concurrent/test/ExecutorIntegrationTest.cpp b/tests/concurrent/ExecutorIntegrationTest.cpp similarity index 96% rename from lib/concurrent/test/ExecutorIntegrationTest.cpp rename to tests/concurrent/ExecutorIntegrationTest.cpp index 8e58a48c..0dacc5c4 100644 --- a/lib/concurrent/test/ExecutorIntegrationTest.cpp +++ b/tests/concurrent/ExecutorIntegrationTest.cpp @@ -1,54 +1,54 @@ -#include "gtest/gtest.h" -#include "pithreadpoolexecutor.h" -#include "pimutex.h" - -const int WAIT_THREAD_TIME_MS = 30; - -TEST(ExcutorIntegrationTest, execute_is_runnable_invoke) { - PIMutex m; - int invokedRunnables = 0; - PIThreadPoolExecutor executorService(1); - executorService.execute([&]() { - m.lock(); - invokedRunnables++; - m.unlock(); - }); - piMSleep(WAIT_THREAD_TIME_MS); - ASSERT_EQ(invokedRunnables, 1); -} - -TEST(ExcutorIntegrationTest, execute_is_not_execute_after_shutdown) { - bool isRunnableInvoke = false; - PIThreadPoolExecutor executorService(1); - executorService.shutdown(); - executorService.execute([&]() { - isRunnableInvoke = true; - }); - piMSleep(WAIT_THREAD_TIME_MS); - ASSERT_FALSE(isRunnableInvoke); -} - -TEST(ExcutorIntegrationTest, execute_is_execute_before_shutdown) { - bool isRunnableInvoke = false; - PIThreadPoolExecutor executorService(1); - executorService.execute([&]() { - piMSleep(WAIT_THREAD_TIME_MS); - isRunnableInvoke = true; - }); - executorService.shutdown(); - piMSleep(2 * WAIT_THREAD_TIME_MS); - ASSERT_TRUE(isRunnableInvoke); -} - -TEST(ExcutorIntegrationTest, execute_is_awaitTermination_wait) { - PIThreadPoolExecutor executorService(1); - executorService.execute([&]() { - piMSleep(2 * WAIT_THREAD_TIME_MS); - }); - executorService.shutdown(); - PITimeMeasurer measurer; - ASSERT_TRUE(executorService.awaitTermination(3 * WAIT_THREAD_TIME_MS)); - double waitTime = measurer.elapsed_m(); - ASSERT_GE(waitTime, WAIT_THREAD_TIME_MS); - ASSERT_LE(waitTime, 4 * WAIT_THREAD_TIME_MS); -} +#include "gtest/gtest.h" +#include "pithreadpoolexecutor.h" +#include "pimutex.h" + +const int WAIT_THREAD_TIME_MS = 30; + +TEST(ExcutorIntegrationTest, execute_is_runnable_invoke) { + PIMutex m; + int invokedRunnables = 0; + PIThreadPoolExecutor executorService(1); + executorService.execute([&]() { + m.lock(); + invokedRunnables++; + m.unlock(); + }); + piMSleep(WAIT_THREAD_TIME_MS); + ASSERT_EQ(invokedRunnables, 1); +} + +TEST(ExcutorIntegrationTest, execute_is_not_execute_after_shutdown) { + bool isRunnableInvoke = false; + PIThreadPoolExecutor executorService(1); + executorService.shutdown(); + executorService.execute([&]() { + isRunnableInvoke = true; + }); + piMSleep(WAIT_THREAD_TIME_MS); + ASSERT_FALSE(isRunnableInvoke); +} + +TEST(ExcutorIntegrationTest, execute_is_execute_before_shutdown) { + bool isRunnableInvoke = false; + PIThreadPoolExecutor executorService(1); + executorService.execute([&]() { + piMSleep(WAIT_THREAD_TIME_MS); + isRunnableInvoke = true; + }); + executorService.shutdown(); + piMSleep(2 * WAIT_THREAD_TIME_MS); + ASSERT_TRUE(isRunnableInvoke); +} + +TEST(ExcutorIntegrationTest, execute_is_awaitTermination_wait) { + PIThreadPoolExecutor executorService(1); + executorService.execute([&]() { + piMSleep(2 * WAIT_THREAD_TIME_MS); + }); + executorService.shutdown(); + PITimeMeasurer measurer; + ASSERT_TRUE(executorService.awaitTermination(3 * WAIT_THREAD_TIME_MS)); + double waitTime = measurer.elapsed_m(); + ASSERT_GE(waitTime, WAIT_THREAD_TIME_MS); + ASSERT_LE(waitTime, 4 * WAIT_THREAD_TIME_MS); +} diff --git a/lib/concurrent/test/testutil.h b/tests/concurrent/testutil.h similarity index 96% rename from lib/concurrent/test/testutil.h rename to tests/concurrent/testutil.h index 063f6622..7c3c15c7 100644 --- a/lib/concurrent/test/testutil.h +++ b/tests/concurrent/testutil.h @@ -1,60 +1,60 @@ -#ifndef AWRCANFLASHER_TESTUTIL_H -#define AWRCANFLASHER_TESTUTIL_H - -#include "pithread.h" -#include - -/** - * Minimum wait thread start, switch context or another interthread communication action time. Increase it if tests - * write "Start thread timeout reach!" message. You can reduce it if you want increase test performance. - */ -const int WAIT_THREAD_TIME_MS = 40; - -const int THREAD_COUNT = 5; - -class TestUtil: public PIObject { -PIOBJECT(TestUtil) -public: - double threadStartTime; - PIThread* thread = new PIThread(); - std::atomic_bool isRunning; - std::function adapterFunctionDefault; - - TestUtil() : isRunning(false) {} - - bool createThread(const std::function& fun = nullptr, PIThread* thread_ = nullptr) { - std::function actualFun = fun == nullptr ? adapterFunctionDefault : fun; - if (thread_ == nullptr) thread_ = thread; - thread_->startOnce([=](void*){ - isRunning = true; - actualFun(); - }); - return waitThread(thread_); - } - - bool waitThread(PIThread* thread_, bool runningStatus = true) { - PITimeMeasurer measurer; - bool isTimeout = !thread_->waitForStart(WAIT_THREAD_TIME_MS); - while (!isRunning) { - isTimeout = WAIT_THREAD_TIME_MS <= measurer.elapsed_m(); - if (isTimeout) break; - piUSleep(100); - } - - threadStartTime = measurer.elapsed_m(); - - if (isTimeout) piCout << "Start thread timeout reach!"; - - if (threadStartTime > 1) { - piCout << "Start time" << threadStartTime << "ms"; - } else if (threadStartTime > 0.001) { - piCout << "Start time" << threadStartTime * 1000 << "mcs"; - } else { - piCout << "Start time" << threadStartTime * 1000 * 1000 << "ns"; - } - - return !isTimeout; - } -}; - -#endif //AWRCANFLASHER_TESTUTIL_H +#ifndef AWRCANFLASHER_TESTUTIL_H +#define AWRCANFLASHER_TESTUTIL_H + +#include "pithread.h" +#include + +/** + * Minimum wait thread start, switch context or another interthread communication action time. Increase it if tests + * write "Start thread timeout reach!" message. You can reduce it if you want increase test performance. + */ +const int WAIT_THREAD_TIME_MS = 40; + +const int THREAD_COUNT = 5; + +class TestUtil: public PIObject { +PIOBJECT(TestUtil) +public: + double threadStartTime; + PIThread* thread = new PIThread(); + std::atomic_bool isRunning; + std::function adapterFunctionDefault; + + TestUtil() : isRunning(false) {} + + bool createThread(const std::function& fun = nullptr, PIThread* thread_ = nullptr) { + std::function actualFun = fun == nullptr ? adapterFunctionDefault : fun; + if (thread_ == nullptr) thread_ = thread; + thread_->startOnce([=](void*){ + isRunning = true; + actualFun(); + }); + return waitThread(thread_); + } + + bool waitThread(PIThread* thread_, bool runningStatus = true) { + PITimeMeasurer measurer; + bool isTimeout = !thread_->waitForStart(WAIT_THREAD_TIME_MS); + while (!isRunning) { + isTimeout = WAIT_THREAD_TIME_MS <= measurer.elapsed_m(); + if (isTimeout) break; + piUSleep(100); + } + + threadStartTime = measurer.elapsed_m(); + + if (isTimeout) piCout << "Start thread timeout reach!"; + + if (threadStartTime > 1) { + piCout << "Start time" << threadStartTime << "ms"; + } else if (threadStartTime > 0.001) { + piCout << "Start time" << threadStartTime * 1000 << "mcs"; + } else { + piCout << "Start time" << threadStartTime * 1000 * 1000 << "ns"; + } + + return !isTimeout; + } +}; + +#endif //AWRCANFLASHER_TESTUTIL_H From c7ac4fa55176859fc518e01d7a7ced887aac2df9 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 1 Aug 2020 21:29:32 +0300 Subject: [PATCH 24/68] Refactored CMakeLists.txt * new pip_module() macro * fixed exports * automatic gather all exports and pass them to Doxygen and PICodeParser --- CMakeLists.txt | 444 +++++++----------- cmake/PIPDocumentation.cmake | 23 +- doc/Doxyfile.in | 40 +- lib/fftw/pifft_p.h | 2 +- lib/main/cloud/piccloudclient.h | 3 +- lib/main/cloud/piccloudserver.h | 3 +- lib/main/cloud/piccloudtcp.h | 3 +- lib/main/code/picodeinfo.h | 14 +- lib/main/code/picodeparser.cpp | 3 + lib/main/code/picodeparser.h | 4 +- lib/main/console/pikbdlistener.h | 2 +- lib/main/console/piscreen.h | 7 +- lib/main/console/piscreenconsole.h | 5 +- lib/main/console/piscreendrawer.h | 3 +- lib/main/console/piscreentile.h | 3 +- lib/main/console/piscreentiles.h | 19 +- lib/main/console/piscreentypes.h | 19 +- lib/main/console/piterminal.h | 5 +- lib/main/containers/pipair.h | 2 +- lib/main/containers/piqueue.h | 2 +- lib/main/containers/piset.h | 2 +- lib/main/containers/pistack.h | 2 +- lib/main/core/pibase.h | 4 +- lib/main/core/pibytearray.h | 4 +- lib/main/core/pichar.h | 6 +- lib/main/core/picout.h | 12 +- lib/main/core/piflags.h | 2 +- lib/main/core/piincludes.h | 2 +- lib/main/core/piinit.h | 2 +- lib/main/core/piobject.h | 8 +- lib/main/core/pipropertystorage.h | 4 +- lib/main/core/pivariant.h | 12 +- lib/main/crypt/piauth.h | 3 +- lib/main/crypt/picrypt.h | 3 +- lib/main/geo/pigeoposition.h | 3 +- .../piintrospection_containers_p.h | 8 +- .../introspection/piintrospection_server_p.h | 22 +- .../introspection/piintrospection_threads_p.h | 6 +- lib/main/io_devices/pibinarylog.h | 8 +- lib/main/io_devices/piconfig.h | 4 +- lib/main/io_devices/piethernet.h | 10 +- lib/main/io_devices/pifile.h | 4 +- lib/main/io_devices/pigpio.h | 4 +- lib/main/io_devices/pipeer.h | 4 +- lib/main/io_devices/piserial.h | 4 +- lib/main/io_devices/pisharedmemory.h | 2 +- lib/main/io_devices/pispi.h | 2 +- lib/main/io_devices/piusb.h | 10 +- lib/main/io_utils/pibasetransfer.h | 2 +- lib/main/io_utils/pibroadcast.h | 3 +- lib/main/io_utils/piconnection.h | 2 +- lib/main/io_utils/pidiagnostics.h | 4 +- lib/main/io_utils/piethutilbase.h | 3 +- lib/main/io_utils/pifiletransfer.h | 2 +- lib/main/io_utils/pistreampacker.h | 5 +- lib/main/lua/piluaprogram.h | 5 +- lib/main/math/picompress.h | 4 +- lib/main/math/pievaluator.h | 6 +- lib/main/math/pifft.h | 5 +- lib/main/math/pimathbase.h | 16 +- lib/main/math/pimathsolver.h | 2 +- lib/main/math/piquaternion.h | 6 +- lib/main/math/pistatistic.h | 2 +- lib/main/opencl/piopencl.h | 23 +- lib/main/piplatform.h | 8 +- lib/main/system/pilibrary.h | 2 +- lib/main/system/piprocess.h | 2 +- lib/main/system/pisysteminfo.h | 2 +- lib/main/system/pisystemmonitor.h | 20 +- lib/main/system/pisystemtests.h | 10 +- lib/main/thread/piconditionvar.h | 2 +- lib/main/thread/pigrabberbase.h | 2 +- lib/main/thread/pimutex.h | 2 +- lib/main/thread/pithread.h | 2 +- lib/main/thread/pithreadpoolexecutor.h | 2 +- main.cpp | 2 +- tests/CMakeLists.txt | 5 +- .../piterminal/CMakeLists.txt | 4 +- .../auxiliary => utils}/piterminal/main.cpp | 2 +- 79 files changed, 389 insertions(+), 531 deletions(-) rename {lib/main/auxiliary => utils}/piterminal/CMakeLists.txt (74%) rename {lib/main/auxiliary => utils}/piterminal/main.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 678f5e13..fc58688e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 1) set(_PIP_MINOR 99) -set(_PIP_REVISION 2) +set(_PIP_REVISION 3) set(_PIP_SUFFIX _prebeta) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) @@ -14,6 +14,7 @@ endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) set(PIP_BUILD 1) include(CheckFunctionExists) +include(GenerateExportHeader) include(DeployMacros) include(PIPMacros) if(NOT DEFINED BUILD_NUMBER) @@ -45,60 +46,89 @@ set(CMAKE_CXX_STANDARD 11) # Basic -macro(gather_src DIR CPP H H_P) - set(CS) - set(HS) - set(PHS) - file(GLOB CS "${DIR}/*.cpp") - file(GLOB HS "${DIR}/*.h") - file(GLOB PHS "${DIR}/*_p.h") - list(REMOVE_ITEM HS "${PHS}") - list(APPEND ${CPP} ${CS}) - list(APPEND ${H} ${HS}) - list(APPEND ${H_P} ${PHS}) -endmacro() - -set(PIP_SRC_MAIN "lib/main") -set(PIP_SRC_CONSOLE "lib/console") -set(PIP_SRC_CRYPT "lib/crypt") -set(PIP_SRC_COMPRESS "lib/compress") -set(PIP_SRC_USB "lib/usb") -set(PIP_SRC_FFTW "lib/fftw") -set(PIP_SRC_OPENCL "lib/opencl") -set(PIP_SRC_IO_UTILS "lib/io_utils") -set(PIP_SRC_CLOUD "lib/cloud") -set(PIP_SRC_LUA "lib/lua") -set(PIP_SRC_DIRS ${PIP_SRC_MAIN} - ${PIP_SRC_CONSOLE} - ${PIP_SRC_CRYPT} - ${PIP_SRC_COMPRESS} - ${PIP_SRC_USB} - ${PIP_SRC_FFTW} - ${PIP_SRC_OPENCL} - ${PIP_SRC_IO_UTILS} - ${PIP_SRC_CLOUD} - ${PIP_SRC_LUA} -) -set(PIP_LIBS_TARGETS pip) +set(PIP_MODULES) set(LIBS_MAIN) set(LIBS_STATUS) set(HDRS) set(PHDRS) set(HDR_DIRS) - -set(PIP_STD_IOSTREAM "no") -set(PIP_ICU "no") -set(PIP_INTROSPECTION "no") -set(PIP_USB "no") -set(PIP_CRYPT "no") -set(PIP_CLOUD "no") -set(PIP_COMPRESS "no") -set(PIP_FFTW "no") -set(PIP_OPENCL "no") -set(PIP_LUA "no") -set(PIP_IOUTILS "yes") set(PIP_UTILS_LIST) set(PIP_TESTS_LIST) +set(PIP_EXPORTS) + +set(PIP_SRC_MODULES "console;crypt;compress;usb;fftw;opencl;io_utils;cloud;lua") +foreach(_m ${PIP_SRC_MODULES}) + set(PIP_MSG_${_m} "no") +endforeach() + +macro(pip_module NAME LIBS LABEL INCLUDES MSG) + set(CPPS) + set(HS) + set(PHS) + set(CRES) + file(GLOB_RECURSE CPPS "lib/${NAME}/*.cpp") + file(GLOB_RECURSE HS "lib/${NAME}/*.h") + file(GLOB_RECURSE PHS "lib/${NAME}/*_p.h") + file(GLOB_RECURSE RES "lib/${NAME}/*conf.h") + list(REMOVE_ITEM HS "${PHS}") + list(APPEND HDRS ${HS}) + list(APPEND PHDRS ${PHS}) + + set(_target "pip_${NAME}") + set(_libs "${LIBS}") + if ("${NAME}" STREQUAL "main") + set(_target "pip") + else() + list(APPEND _libs "pip") + endif() + string(TOUPPER "${_target}" DEF_NAME) + + set(PIP_MSG_${NAME} "yes${MSG}") + import_version(${_target} PIP) + set_deploy_property(${_target} ${PIP_LIB_TYPE} + LABEL "${LABEL}" + FULLNAME "${_PIP_DOMAIN}.${_target}" + COMPANY "${_PIP_COMPANY}" + INFO "Platform-Independent Primitives") + make_rc(${_target} _RC) + + set(LINK_LIBS) + foreach (_l ${_libs}) + if (${${_l}_FOUND}) + list(APPEND LINK_LIBS ${${_l}_LIBRARIES}) + else() + list(APPEND LINK_LIBS ${_l}) + endif() + endforeach() + + if (NOT "${RES}" STREQUAL "") + pip_resources(CRES "${RES}") + endif() + add_definitions(-D${DEF_NAME}) + add_library(${_target} ${PIP_LIB_TYPE} ${CPPS} ${CRES} ${_RC}) + if (NOT "${RES}" STREQUAL "") + add_dependencies(${_target} pip_rc) + endif() + if (NOT "${INCLUDES}" STREQUAL "") + target_include_directories(${_target} PRIVATE ${INCLUDES}) + endif() + generate_export_header(${_target}) + list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/${_target}_export.h") + list(APPEND PIP_EXPORTS "${DEF_NAME}_EXPORT") + target_link_libraries(${_target} ${LINK_LIBS}) + list(APPEND PIP_MODULES ${_target}) + if (NOT "${LIBS}" STREQUAL "") + list(APPEND LIBS_STATUS ${LIBS}) + endif() +endmacro() + +macro(pip_find_lib NAME) + find_library(${NAME}_LIBRARIES ${NAME} ${ARGN}) + set(${NAME}_FOUND FALSE) + if(${NAME}_LIBRARIES) + set(${NAME}_FOUND TRUE) + endif() +endmacro() if (DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) set(STATIC_LIB ON) @@ -122,11 +152,6 @@ set_version(PIP BUILD "${BUILD_NUMBER}" SUFFIX "${_PIP_SUFFIX}" OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/piversion.h") -set_deploy_property(pip ${PIP_LIB_TYPE} - LABEL "PIP main library" - FULLNAME "${_PIP_DOMAIN}.pip" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h") file(REMOVE "${CMAKE_CURRENT_SOURCE_DIR}/${PIP_SRC_MAIN}/piversion.h") endif() @@ -184,49 +209,25 @@ endif() get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) -# Sources - # Main lib -set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "cloud" "lua") -include_directories("${PIP_SRC_MAIN}") +#set(PIP_FOLDERS ".;core;containers;thread;system;io_devices;io_utils;console;math;code;geo;resources;opencl;crypt;introspection;cloud;lua") +file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/lib/main/*") +list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/lib/main") set(PIP_MAIN_FOLDERS) foreach(F ${PIP_FOLDERS}) - list(APPEND PIP_MAIN_FOLDERS "\"${PROJECT_SOURCE_DIR}/${PIP_SRC_MAIN}/${F}\"") - include_directories("${PIP_SRC_MAIN}/${F}") - gather_src("${PIP_SRC_MAIN}/${F}" CPP_LIB_MAIN HDRS PHDRS) + if (IS_DIRECTORY "${F}") + list(APPEND PIP_MAIN_FOLDERS "${F}") + include_directories("${F}") + endif() endforeach(F) +if (DEFINED LIBPROJECT) + set(PIP_MAIN_FOLDERS "${PIP_MAIN_FOLDERS}" PARENT_SCOPE) +endif() if (TESTS) add_subdirectory(tests) endif() -# Crypt lib -gather_src("${PIP_SRC_CRYPT}" CPP_LIB_CRYPT HDRS PHDRS) - -# Console lib -gather_src("${PIP_SRC_CONSOLE}" CPP_LIB_CONSOLE HDRS PHDRS) - -# Compress lib -gather_src("${PIP_SRC_COMPRESS}" CPP_LIB_COMPRESS HDRS PHDRS) - -# USB lib -gather_src("${PIP_SRC_USB}" CPP_LIB_USB HDRS PHDRS) - -# FFTW lib -gather_src("${PIP_SRC_FFTW}" CPP_LIB_FFTW HDRS PHDRS) - -# OpenCL lib -gather_src("${PIP_SRC_OPENCL}" CPP_LIB_OPENCL HDRS PHDRS) - -# IO Utils lib -gather_src("${PIP_SRC_IO_UTILS}" CPP_LIB_IO_UTILS HDRS PHDRS) - -# Cloud lib -gather_src("${PIP_SRC_CLOUD}" CPP_LIB_CLOUD HDRS PHDRS) - -# LUA lib -gather_src("${PIP_SRC_LUA}" CPP_LIB_LUA HDRS PHDRS) - if(PIP_FREERTOS) add_definitions(-DPIP_FREERTOS) set(ICU OFF) @@ -269,9 +270,9 @@ if((NOT DEFINED ENV{QNX_HOST}) AND (NOT APPLE) AND (NOT WIN32) AND (NOT DEFINED list(APPEND LIBS_MAIN rt) set(CMAKE_REQUIRED_LIBRARIES rt) endif() -CHECK_FUNCTION_EXISTS(timer_create PIP_TIMER_RT_0) +CHECK_FUNCTION_EXISTS(timer_create PIP_TIMER_RT_0) CHECK_FUNCTION_EXISTS(timer_settime PIP_TIMER_RT_1) -CHECK_FUNCTION_EXISTS(timer_delete PIP_TIMER_RT_2) +CHECK_FUNCTION_EXISTS(timer_delete PIP_TIMER_RT_2) # Check if build debug version @@ -286,6 +287,7 @@ endif() # Check if std::iostream operators support +set(PIP_STD_IOSTREAM "no") if(STD_IOSTREAM) set(PIP_STD_IOSTREAM "yes") add_definitions(-DPIP_STD_IOSTREAM) @@ -293,6 +295,7 @@ endif() # Check if ICU used for PIString and PIChar +set(PIP_ICU "no") if(ICU) set(PIP_ICU "yes") add_definitions(-DPIP_ICU) @@ -303,6 +306,7 @@ endif() # Check if PIP should be built with introspection set(_PIP_DEFS "") set(_PIP_DEFS_FILE "${CMAKE_CURRENT_BINARY_DIR}/pip_defs.h") +set(PIP_INTROSPECTION "no") if(INTROSPECTION) set(PIP_INTROSPECTION "yes") add_definitions(-DPIP_INTROSPECTION) @@ -360,21 +364,12 @@ if(PIP_FREERTOS) set(PIP_LIBS ${LIBS_MAIN}) else() foreach(LIB_ ${LIBS_MAIN}) - find_library(${LIB_}_LIBRARIES ${LIB_}) - set(${LIB_}_FOUND FALSE) - if(${LIB_}_LIBRARIES) - set(${LIB_}_FOUND TRUE) - list(APPEND CMAKE_REQUIRED_LIBRARIES ${${LIB_}_LIBRARIES}) - list(APPEND PIP_LIBS ${${LIB_}_LIBRARIES}) - endif() + pip_find_lib(${LIB_}) endforeach() endif() -list(APPEND LIBS_STATUS ${LIBS_MAIN}) import_version(pip PIP) if(WIN32) - make_rc(pip _RC) add_definitions(-DPSAPI_VERSION=1) - add_library(pip ${PIP_LIB_TYPE} ${CPP_LIB_MAIN} ${HDRS} ${PHDRS} ${_RC}) if(${C_COMPILER} STREQUAL "cl.exe") set(CMAKE_CXX_FLAGS "/O2 /Ob2 /Ot /W0") endif() @@ -382,93 +377,37 @@ else() set(${CMAKE_CXX_FLAGS} "${CMAKE_CXX_FLAGS} -fPIC") if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32") - else() endif() - add_library(pip ${PIP_LIB_TYPE} ${CPP_LIB_MAIN}) endif() set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") -include(GenerateExportHeader) -generate_export_header(pip) -list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_export.h") -target_link_libraries(pip ${PIP_LIBS}) + + +pip_module(main "${LIBS_MAIN}" "PIP main library" "" "") + if (NOT CROSSTOOLS) if (NOT PIP_FREERTOS) - # Check if USB is supported - find_library(usb_LIBRARIES usb SHARED) - set(usb_FOUND FALSE) - if(usb_LIBRARIES) - set(usb_FOUND TRUE) - set(PIP_USB "yes") - import_version(pip_usb pip) - set_deploy_property(pip_usb ${PIP_LIB_TYPE} - LABEL "PIP usb support" - FULLNAME "${_PIP_DOMAIN}.pip_usb" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_usb _RC) - add_definitions(-DPIP_USB) - add_library(pip_usb ${PIP_LIB_TYPE} ${CPP_LIB_USB} ${_RC}) - target_link_libraries(pip_usb pip ${usb_LIBRARIES}) - list(APPEND LIBS_STATUS usb) - list(APPEND PIP_LIBS_TARGETS pip_usb) + + + pip_module(console "" "PIP console support" "" "") + + + pip_find_lib(usb) + if(usb_FOUND) + pip_module(usb "usb" "PIP usb support" "" "") endif() - # Add console library - import_version(pip_console pip) - set_deploy_property(pip_console ${PIP_LIB_TYPE} - LABEL "PIP console support" - FULLNAME "${_PIP_DOMAIN}.pip_console" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_console _RC) - add_library(pip_console ${PIP_LIB_TYPE} ${CPP_LIB_CONSOLE} ${_RC}) - target_link_libraries(pip_console pip) - list(APPEND PIP_LIBS_TARGETS pip_console) - - - # Check if PIP support cryptographic encryption/decryption using sodium library - find_library(sodium_LIBRARIES sodium) - set(sodium_FOUND FALSE) - if(sodium_LIBRARIES) - set(sodium_FOUND TRUE) - set(PIP_CRYPT "yes") - set(PIP_IOUTILS "yes (+crypt)") - set(PIP_CLOUD "yes") - import_version(pip_crypt pip) - set_deploy_property(pip_crypt ${PIP_LIB_TYPE} - LABEL "PIP crypt support" - FULLNAME "${_PIP_DOMAIN}.pip_crypt" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_crypt _RC) - add_definitions(-DPIP_CRYPT) - add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT} ${_RC}) - target_link_libraries(pip_crypt pip ${sodium_LIBRARIES}) - list(APPEND LIBS_STATUS sodium) - list(APPEND PIP_LIBS_TARGETS pip_crypt) + pip_find_lib(zlib NAMES z zlib) + if(zlib_FOUND) + pip_module(compress "zlib" "PIP compression support" "" "") endif() - # Check if PIP support compress/decompress using zlib library - find_library(zlib_LIBRARIES NAMES z zlib) - set(zlib_FOUND FALSE) - if(zlib_LIBRARIES) - set(zlib_FOUND TRUE) - set(PIP_COMPRESS "yes") - import_version(pip_compress pip) - set_deploy_property(pip_compress ${PIP_LIB_TYPE} - LABEL "PIP compression support" - FULLNAME "${_PIP_DOMAIN}.pip_compress" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_compress _RC) - add_definitions(-DPIP_COMPRESS) - add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS} ${_RC}) - target_link_libraries(pip_compress pip ${zlib_LIBRARIES}) - list(APPEND LIBS_STATUS zlib) - list(APPEND PIP_LIBS_TARGETS pip_compress) + pip_find_lib(sodium) + if(sodium_FOUND) + pip_module(crypt "sodium" "PIP crypt support" "" "") + pip_module(cloud "pip_crypt" "PIP crypt support" "" "") endif() @@ -513,106 +452,38 @@ if (NOT CROSSTOOLS) endforeach() endforeach() if(FFTW_LIBS) - set(PIP_FFTW "yes (${FFTW_LIBS})") - import_version(pip_fftw pip) - set_deploy_property(pip_fftw ${PIP_LIB_TYPE} - LABEL "PIP FFTW support" - FULLNAME "${_PIP_DOMAIN}.pip_fftw" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_fftw _RC) - add_library(pip_fftw ${PIP_LIB_TYPE} ${CPP_LIB_FFTW} ${_RC}) - target_link_libraries(pip_fftw pip ${FFTW_ABS_LIBS}) - list(APPEND LIBS_STATUS ${FFTW_LIBS}) - list(APPEND PIP_LIBS_TARGETS pip_fftw) + pip_module(fftw "${FFTW_LIBS}" "PIP FFTW support" "" "") endif() - # Check if PIP support OpenCL - find_package(OpenCL QUIET) + find_package(OpenCL QUIET) #OpenCL_VERSION_STRING if(OpenCL_FOUND) - set(PIP_OPENCL "yes (${OpenCL_VERSION_STRING})") - import_version(pip_opencl pip) - set_deploy_property(pip_opencl ${PIP_LIB_TYPE} - LABEL "PIP OpenCL support" - FULLNAME "${_PIP_DOMAIN}.pip_opencl" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_opencl _RC) - if(APPLE) - include_directories(${OpenCL_INCLUDE_DIRS}/Headers) - else() - include_directories(${OpenCL_INCLUDE_DIRS}) - endif() - add_definitions(-DPIP_OPENCL) - pip_resources(CL_RES "${PIP_SRC_OPENCL}/resources.conf") - add_library(pip_opencl ${PIP_LIB_TYPE} ${CPP_LIB_OPENCL} ${CL_RES} ${_RC}) - add_dependencies(pip_opencl pip_rc) + set(_opencl_lib OpenCL::OpenCL) if(${CMAKE_VERSION} VERSION_LESS "3.7.0") - target_link_libraries(pip_opencl pip OpenCL) - else() - target_link_libraries(pip_opencl pip OpenCL::OpenCL) + target_link_libraries(_opencl_lib OpenCL) endif() - list(APPEND LIBS_STATUS OpenCL) - list(APPEND PIP_LIBS_TARGETS pip_opencl) + pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "" " (${OpenCL_VERSION_STRING})") endif() - # Check if PIP IO Utils library supports crypt - set(IO_UTILS_LIBS pip) - import_version(pip_io_utils pip) - set_deploy_property(pip_io_utils ${PIP_LIB_TYPE} - LABEL "PIP I/O utilites" - FULLNAME "${_PIP_DOMAIN}.pip_io_utils" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_io_utils _RC) - add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS} ${_RC}) if(sodium_FOUND) - list(APPEND IO_UTILS_LIBS pip_crypt) + pip_module(io_utils "pip_crypt" "PIP I/O support" "" " (+crypt)") + else() + pip_module(io_utils "" "PIP I/O support" "" "") endif() - target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) - list(APPEND PIP_LIBS_TARGETS pip_io_utils) - # Build cloud library if crypt enabled - if(sodium_FOUND) - import_version(pip_cloud pip) - set_deploy_property(pip_cloud ${PIP_LIB_TYPE} - LABEL "PIP cloud transport support" - FULLNAME "${_PIP_DOMAIN}.pip_cloud" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_cloud _RC) - add_definitions(-DPIP_CLOUD) - add_library(pip_cloud ${PIP_LIB_TYPE} ${CPP_LIB_CLOUD} ${_RC}) - target_link_libraries(pip_cloud pip pip_crypt) - list(APPEND PIP_LIBS_TARGETS pip_cloud) - endif() - # Check Lua support if(MINGW) set(LUA_INCLUDE_DIR ${MINGW_INCLUDE}) endif() find_package(Lua QUIET) if (LUA_FOUND) - set(PIP_LUA "yes (${LUA_VERSION_STRING})") - import_version(pip_lua pip) - set_deploy_property(pip_lua ${PIP_LIB_TYPE} - LABEL "PIP Lua support" - FULLNAME "${_PIP_DOMAIN}.pip_lua" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_lua _RC) - add_definitions(-DPIP_LUA) - include_directories(${LUA_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd) + pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd" " (${LUA_VERSION_STRING})") list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge") - add_library(pip_lua ${PIP_LIB_TYPE} ${CPP_LIB_LUA} ${_RC}) - target_link_libraries(pip_lua pip ${LUA_LIBRARIES}) - list(APPEND LIBS_STATUS LUA) - list(APPEND PIP_LIBS_TARGETS pip_lua) endif() + # Test program if(PIP_UTILS) add_executable(pip_test "main.cpp") @@ -624,25 +495,29 @@ if (NOT CROSSTOOLS) else() - set(PIP_CRYPT "yes") - set(PIP_COMPRESS "yes") + set(PIP_MSG_crypt "yes") + set(PIP_MSG_compress "yes") + set(PIP_MODULES pip) add_definitions(-DPIP_CRYPT) add_library(pip_crypt ${PIP_LIB_TYPE} ${CPP_LIB_CRYPT}) target_link_libraries(pip_crypt pip) - list(APPEND PIP_LIBS_TARGETS pip_crypt) + list(APPEND PIP_MODULES pip_crypt) set(IO_UTILS_LIBS pip) add_library(pip_io_utils ${PIP_LIB_TYPE} ${CPP_LIB_IO_UTILS}) list(APPEND IO_UTILS_LIBS pip_crypt) target_link_libraries(pip_io_utils ${IO_UTILS_LIBS}) - list(APPEND PIP_LIBS_TARGETS pip_io_utils) + list(APPEND PIP_MODULES pip_io_utils) add_definitions(-DPIP_COMPRESS) add_library(pip_compress ${PIP_LIB_TYPE} ${CPP_LIB_COMPRESS}) target_link_libraries(pip_compress pip) - list(APPEND PIP_LIBS_TARGETS pip_compress) + list(APPEND PIP_MODULES pip_compress) endif() endif() +string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}") +target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"") + # Install # Check if system or local install will be used (to system install use "-DLIB=" argument of cmake) if(LIB) @@ -654,9 +529,9 @@ if(LIB) if(HDR_DIRS) install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip) endif() - install(TARGETS ${PIP_LIBS_TARGETS} ARCHIVE DESTINATION ${MINGW_LIB}) + install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION ${MINGW_LIB}) endif() - install(TARGETS ${PIP_LIBS_TARGETS} RUNTIME DESTINATION ${MINGW_BIN}) + install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION ${MINGW_BIN}) find_library(STDLIB "stdc++-6" PATHS ${MINGW_BIN} NO_DEFAULT_PATH) find_library(STDLIB "stdc++-6") #message("${STDLIB}") @@ -675,17 +550,17 @@ if(LIB) install(DIRECTORY ${HDR_DIRS} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/pip) endif() endif() - install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) + install(TARGETS ${PIP_MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) endif() file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in" "cmake/android_debug.keystore") install(FILES ${CMAKES} DESTINATION ${CMAKE_ROOT}/Modules) else() if(NOT PIP_FREERTOS) if(WIN32) - install(TARGETS ${PIP_LIBS_TARGETS} RUNTIME DESTINATION bin) - install(TARGETS ${PIP_LIBS_TARGETS} ARCHIVE DESTINATION lib) + install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin) + install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib) else() - install(TARGETS ${PIP_LIBS_TARGETS} DESTINATION lib) + install(TARGETS ${PIP_MODULES} DESTINATION lib) endif() install(FILES ${HDRS} DESTINATION include/pip) if(HDR_DIRS) @@ -698,7 +573,7 @@ if(NOT PIP_FREERTOS) # Auxiliary if (NOT CROSSTOOLS) - add_subdirectory("${PIP_SRC_MAIN}/auxiliary/piterminal") + add_subdirectory("utils/piterminal") endif() # Utils @@ -720,8 +595,8 @@ endif() # Libraries messages if(DEFINED LIBPROJECT) - set(PIP_LIBS_TARGETS ${PIP_LIBS_TARGETS} PARENT_SCOPE) - list(APPEND _ALL_TARGETS ${PIP_LIBS_TARGETS}) + set(PIP_MODULES ${PIP_MODULES} PARENT_SCOPE) + list(APPEND _ALL_TARGETS ${PIP_MODULES}) set(_ALL_TARGETS ${_ALL_TARGETS} PARENT_SCOPE) endif() @@ -735,8 +610,9 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS)) set(DOXY_PROJECT_NUMBER "${PIP_VERSION}") set(DOXY_QHP_CUST_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"") set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"") - set(DOXY_EXAMPLE_PATH "\"${PROJECT_SOURCE_DIR}/doc/examples\"") - set(DOXY_IMAGE_PATH "\"${PROJECT_SOURCE_DIR}/doc/images\"") + set(DOXY_EXAMPLE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/examples\"") + set(DOXY_IMAGE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/images\"") + set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd\"") if(DOXYGEN_DOT_EXECUTABLE) string(REPLACE "\\" "" _DOT_PATH "${DOXYGEN_DOT_PATH}") set(DOXY_DOT_PATH "\"${_DOT_PATH}\"") @@ -744,11 +620,12 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS)) set(DOXY_DIA_PATH "\"${_DOT_PATH}\"") endif() set(DOXY_INPUT) - foreach(F ${PIP_SRC_DIRS}) - list(APPEND DOXY_INPUT "\"${PROJECT_SOURCE_DIR}/${F}\"") + foreach(F ${PIP_MAIN_FOLDERS}) + list(APPEND DOXY_INPUT "\"${F}\"") endforeach(F) - string(REPLACE ";" " " DOXY_INPUT "${DOXY_INPUT}") - string(REPLACE ";" " " DOXY_INCLUDE_PATH "${PIP_MAIN_FOLDERS}") + string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/lib\"") + string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}") + string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS") add_documentation(doc doc/Doxyfile.in) install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html DESTINATION ../share/doc/pip COMPONENT doc EXCLUDE_FROM_ALL OPTIONAL) endif() @@ -756,6 +633,7 @@ endif() +list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES}) message("----------PIP----------") message(" Version: ${PIP_VERSION} ") message(" Linkage: ${PIP_LIB_TYPE_MSG}") @@ -778,15 +656,9 @@ if(INTROSPECTION) endif() message("") message(" Modules:") -message(" USB : ${PIP_USB}") -message(" Console : yes") -message(" Crypt : ${PIP_CRYPT}") -message(" Compress : ${PIP_COMPRESS}") -message(" FFTW : ${PIP_FFTW}") -message(" OpenCL : ${PIP_OPENCL}") -message(" IOUtils : ${PIP_IOUTILS}") -message(" Cloud : ${PIP_CLOUD}") -message(" Lua : ${PIP_LUA}") +foreach(_m ${PIP_SRC_MODULES}) + message(" ${_m}: ${PIP_MSG_${_m}}") +endforeach() if (PIP_TESTS_LIST) message("") message(" Tests:") @@ -803,10 +675,12 @@ if(NOT PIP_FREERTOS) message("") message(" Using libraries:") foreach(LIB_ ${LIBS_STATUS}) - if(${LIB_}_FOUND) - message(" ${LIB_} -> ${${LIB_}_LIBRARIES}") - else() - message(" ${LIB_} not found, may fail") + if (NOT TARGET ${LIB_}) + if(${LIB_}_FOUND) + message(" ${LIB_} -> ${${LIB_}_LIBRARIES}") + else() + message(" ${LIB_} not found, may fail") + endif() endif() endforeach() endif() diff --git a/cmake/PIPDocumentation.cmake b/cmake/PIPDocumentation.cmake index e034bad2..9e9a099a 100644 --- a/cmake/PIPDocumentation.cmake +++ b/cmake/PIPDocumentation.cmake @@ -1,27 +1,6 @@ -macro(CONFIGURE_DOXYGEN_FILE DOXYGEN_CONFIG_FILE FILE_NAME_SUFFIX) - if(EXISTS ${PROJECT_SOURCE_DIR}/${DOXYGEN_CONFIG_FILE}) - file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${FILE_NAME_SUFFIX}") - file(READ ${PROJECT_SOURCE_DIR}/${DOXYGEN_CONFIG_FILE} DOXYFILE_CONTENTS) - string(REPLACE "\\\n" " " DOXYFILE_CONTENTS "${DOXYFILE_CONTENTS}") - string(REPLACE "\n" ";" DOXYFILE_LINES "${DOXYFILE_CONTENTS}") - foreach(LINE IN LISTS DOXYFILE_LINES) - if(LINE STRGREATER "") - string(REGEX MATCH "^[a-zA-Z]([^ ])+" DOXY_PARAM ${LINE}) - if(DEFINED DOXY_${DOXY_PARAM}) - STRING(REGEX REPLACE "=([^\n])+" "= ${DOXY_${DOXY_PARAM}}" LINE ${LINE}) - endif(DEFINED DOXY_${DOXY_PARAM}) - endif() - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${FILE_NAME_SUFFIX} "${LINE}\n") - endforeach() - else() - MESSAGE(SEND_ERROR "Doxygen configuration file '${DOXYGEN_CONFIG_FILE}' not found, can`t generate documentation") - endif() -endmacro(CONFIGURE_DOXYGEN_FILE) - - macro(ADD_DOCUMENTATION TARGET DOXYGEN_CONFIG_FILE) if(DOXYGEN_FOUND) - configure_doxygen_file(${DOXYGEN_CONFIG_FILE} ${TARGET}) + configure_file("${PROJECT_SOURCE_DIR}/${DOXYGEN_CONFIG_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${TARGET}") add_custom_target("genereate.${TARGET}" COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/doxyfile-${TARGET}) add_custom_target("${TARGET}" COMMAND ${CMAKE_COMMAND} -D COMPONENT=doc -P cmake_install.cmake) add_dependencies("${TARGET}" "genereate.${TARGET}") diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 462dd31b..cbc2f526 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -38,7 +38,7 @@ PROJECT_NAME = PIP # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.8.0 +PROJECT_NUMBER = ${DOXY_PROJECT_NUMBER} # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -816,13 +816,7 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = src_main \ - src_crypt \ - src_fftw \ - src_io_utils \ - src_compress \ - src_opencl \ - src_usb +INPUT = ${DOXY_INPUT} # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses @@ -895,7 +889,7 @@ RECURSIVE = YES # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = ${DOXY_EXCLUDE} # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded @@ -928,7 +922,7 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = doc/examples +EXAMPLE_PATH = ${DOXY_EXAMPLE_PATH} # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -948,7 +942,7 @@ EXAMPLE_RECURSIVE = NO # that contain images that are to be included in the documentation (see the # \image command). -IMAGE_PATH = doc/images +IMAGE_PATH = ${DOXY_IMAGE_PATH} # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program @@ -1459,14 +1453,14 @@ QHP_CUST_FILTER_NAME = PIP # filters). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_CUST_FILTER_ATTRS = PIP +QHP_CUST_FILTER_ATTRS = ${DOXY_QHP_CUST_FILTER_ATTRS} # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. -QHP_SECT_FILTER_ATTRS = PIP +QHP_SECT_FILTER_ATTRS = ${DOXY_QHP_SECT_FILTER_ATTRS} # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the @@ -2152,15 +2146,7 @@ SEARCH_INCLUDES = YES # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = src_main/code \ - src_main/containers \ - src_main/core \ - src_main/math \ - src_main/system \ - src_main/thread \ - src_main/console \ - src_main/io_devices \ - src_main/io_utils +INCLUDE_PATH = ${DOXY_INCLUDE_PATH} # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2178,8 +2164,8 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = DOXYGEN \ - PIP_EXPORT +PREDEFINED = ${DOXY_DEFINES} + # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2272,14 +2258,14 @@ CLASS_DIAGRAMS = YES # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = "C:/Program Files/doxygen/graphviz/bin" +MSCGEN_PATH = ${DOXY_MSCGEN_PATH} # You can include diagrams made with dia in doxygen documentation. Doxygen will # then run dia to produce the diagram and insert it in the documentation. The # DIA_PATH tag allows you to specify the directory where the dia binary resides. # If left empty dia is assumed to be found in the default search path. -DIA_PATH = "C:/Program Files/doxygen/graphviz/bin" +DIA_PATH = ${DOXY_DIA_PATH} # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. @@ -2472,7 +2458,7 @@ INTERACTIVE_SVG = NO # found. If left blank, it is assumed the dot tool can be found in the path. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_PATH = "C:/Program Files/doxygen/graphviz/bin" +DOT_PATH = ${DOXY_DOT_PATH} # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the \dotfile diff --git a/lib/fftw/pifft_p.h b/lib/fftw/pifft_p.h index b4551a94..04c61169 100644 --- a/lib/fftw/pifft_p.h +++ b/lib/fftw/pifft_p.h @@ -36,7 +36,7 @@ template -class PIP_EXPORT PIFFTW_Private +class PIFFTW_Private { public: explicit PIFFTW_Private() { diff --git a/lib/main/cloud/piccloudclient.h b/lib/main/cloud/piccloudclient.h index 30eea971..8765c38d 100644 --- a/lib/main/cloud/piccloudclient.h +++ b/lib/main/cloud/piccloudclient.h @@ -23,10 +23,11 @@ #ifndef PICCLOUDCLIENT_H #define PICCLOUDCLIENT_H +#include "pip_cloud_export.h" #include "piiodevice.h" -class PIP_EXPORT PICloudClient { +class PIP_CLOUD_EXPORT PICloudClient { public: //! explicit PICloudClient(); diff --git a/lib/main/cloud/piccloudserver.h b/lib/main/cloud/piccloudserver.h index eb65d1de..cf0e4e23 100644 --- a/lib/main/cloud/piccloudserver.h +++ b/lib/main/cloud/piccloudserver.h @@ -23,10 +23,11 @@ #ifndef PICCLOUDSERVER_H #define PICCLOUDSERVER_H +#include "pip_cloud_export.h" #include "piiodevice.h" -class PIP_EXPORT PICloudServer { +class PIP_CLOUD_EXPORT PICloudServer { public: //! explicit PICloudServer(); diff --git a/lib/main/cloud/piccloudtcp.h b/lib/main/cloud/piccloudtcp.h index 2d0c0703..ea0e4f5c 100644 --- a/lib/main/cloud/piccloudtcp.h +++ b/lib/main/cloud/piccloudtcp.h @@ -23,9 +23,10 @@ #ifndef PICCLOUDTCP_H #define PICCLOUDTCP_H +#include "pip_cloud_export.h" #include "pistring.h" -class PIP_EXPORT PICloudTCP { +class PIP_CLOUD_EXPORT PICloudTCP { public: //! PICloudTCP(); diff --git a/lib/main/code/picodeinfo.h b/lib/main/code/picodeinfo.h index 5b182fc5..97506149 100644 --- a/lib/main/code/picodeinfo.h +++ b/lib/main/code/picodeinfo.h @@ -30,7 +30,7 @@ class PIVariant; namespace PICodeInfo { -enum PIP_EXPORT TypeFlag { +enum TypeFlag { NoFlag, Const = 0x01, Static = 0x02, @@ -153,10 +153,10 @@ inline PICout operator <<(PICout s, const PICodeInfo::EnumInfo & v) { return s; } -extern PIMap * classesInfo; -extern PIMap * enumsInfo; -extern PIMap * accessValueFunctions; -extern PIMap * accessTypeFunctions; +extern PIP_EXPORT PIMap * classesInfo; +extern PIP_EXPORT PIMap * enumsInfo; +extern PIP_EXPORT PIMap * accessValueFunctions; +extern PIP_EXPORT PIMap * accessTypeFunctions; inline PIByteArray getMemberValue(const void * p, const char * class_name, const char * member_name) { if (!p || !class_name || !member_name || !accessValueFunctions) return PIByteArray(); @@ -172,11 +172,11 @@ inline const char * getMemberType(const char * class_name, const char * member_n return af(member_name); } -PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); +PIP_EXPORT PIVariant getMemberAsVariant(const void * p, const char * class_name, const char * member_name); } -class __PICodeInfoInitializer__ { +class PIP_EXPORT __PICodeInfoInitializer__ { public: __PICodeInfoInitializer__() { if (_inited_) return; diff --git a/lib/main/code/picodeparser.cpp b/lib/main/code/picodeparser.cpp index d4301feb..99c02061 100644 --- a/lib/main/code/picodeparser.cpp +++ b/lib/main/code/picodeparser.cpp @@ -186,6 +186,9 @@ void PICodeParser::clear() { evaluator.clearCustomVariables(); cur_def_vis = Global; anon_num = 0; + PIStringList defs = PIStringAscii(PICODE_DEFINES).split(","); + piForeachC (PIString & d, defs) + defines << Define(d, ""); defines << Define(PIStringAscii("PICODE"), "") << custom_defines; } diff --git a/lib/main/code/picodeparser.h b/lib/main/code/picodeparser.h index 9eaf2821..716dda9a 100644 --- a/lib/main/code/picodeparser.h +++ b/lib/main/code/picodeparser.h @@ -33,8 +33,8 @@ class PIP_EXPORT PICodeParser { public: PICodeParser(); - enum PIP_EXPORT Visibility {Global, Public, Protected, Private}; - enum PIP_EXPORT Attribute { + enum Visibility {Global, Public, Protected, Private}; + enum Attribute { NoAttributes = 0x0, Const = 0x01, Static = 0x02, diff --git a/lib/main/console/pikbdlistener.h b/lib/main/console/pikbdlistener.h index 5ea90cd6..d1eab548 100644 --- a/lib/main/console/pikbdlistener.h +++ b/lib/main/console/pikbdlistener.h @@ -228,7 +228,7 @@ private: static const EscSeq esc_seq[]; #endif - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) KBFunc ret_func; int exit_key; bool exit_enabled, is_active; diff --git a/lib/main/console/piscreen.h b/lib/main/console/piscreen.h index 493fc84e..34439e1b 100644 --- a/lib/main/console/piscreen.h +++ b/lib/main/console/piscreen.h @@ -23,11 +23,12 @@ #ifndef PISCREEN_H #define PISCREEN_H +#include "pip_console_export.h" #include "piscreentile.h" #include "piscreendrawer.h" -class PIP_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase +class PIP_CONSOLE_EXPORT PIScreen: public PIThread, public PIScreenTypes::PIScreenBase { PIOBJECT_SUBCLASS(PIScreen, PIThread) class SystemConsole; @@ -100,7 +101,7 @@ public: //! \} private: - class SystemConsole { + class PIP_CONSOLE_EXPORT SystemConsole { public: SystemConsole(); ~SystemConsole(); @@ -124,7 +125,7 @@ private: #else PIString formatString(const PIScreenTypes::Cell & c); #endif - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT) int width, height, pwidth, pheight; int mouse_x, mouse_y; PIVector > cells, pcells; diff --git a/lib/main/console/piscreenconsole.h b/lib/main/console/piscreenconsole.h index 4b745b1d..7d0582ff 100644 --- a/lib/main/console/piscreenconsole.h +++ b/lib/main/console/piscreenconsole.h @@ -25,12 +25,13 @@ #ifndef PISCREENCONSOLE_H #define PISCREENCONSOLE_H +#include "pip_console_export.h" #include "piscreentiles.h" /// NOTE: incomplete class /// TODO: write TileVars -class PIP_EXPORT TileVars: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile { public: TileVars(const PIString & n = PIString()); protected: @@ -68,7 +69,7 @@ protected: -class PIP_EXPORT PIScreenConsoleTile : public PIScreenTile +class PIP_CONSOLE_EXPORT PIScreenConsoleTile : public PIScreenTile { public: PIScreenConsoleTile(); diff --git a/lib/main/console/piscreendrawer.h b/lib/main/console/piscreendrawer.h index 3efd48fd..6a118adb 100644 --- a/lib/main/console/piscreendrawer.h +++ b/lib/main/console/piscreendrawer.h @@ -23,10 +23,11 @@ #ifndef PISCREENDRAWER_H #define PISCREENDRAWER_H +#include "pip_console_export.h" #include "piscreentypes.h" #include "pistring.h" -class PIP_EXPORT PIScreenDrawer +class PIP_CONSOLE_EXPORT PIScreenDrawer { friend class PIScreen; PIScreenDrawer(PIVector > & c); diff --git a/lib/main/console/piscreentile.h b/lib/main/console/piscreentile.h index e9ab7b30..28e7dcd7 100644 --- a/lib/main/console/piscreentile.h +++ b/lib/main/console/piscreentile.h @@ -23,12 +23,13 @@ #ifndef PISCREENTILE_H #define PISCREENTILE_H +#include "pip_console_export.h" #include "piscreentypes.h" #include "pikbdlistener.h" class PIScreenDrawer; -class PIP_EXPORT PIScreenTile: public PIObject { +class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject { friend class PIScreen; PIOBJECT_SUBCLASS(PIScreenTile, PIObject) public: diff --git a/lib/main/console/piscreentiles.h b/lib/main/console/piscreentiles.h index b6c41a25..ee617156 100644 --- a/lib/main/console/piscreentiles.h +++ b/lib/main/console/piscreentiles.h @@ -23,10 +23,11 @@ #ifndef PISCREENTILES_H #define PISCREENTILES_H +#include "pip_console_export.h" #include "piscreentile.h" -class PIP_EXPORT TileSimple: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileSimple: public PIScreenTile { PIOBJECT_SUBCLASS(TileSimple, PIScreenTile) public: typedef PIPair Row; @@ -43,7 +44,7 @@ protected: class TileList; -class PIP_EXPORT TileScrollBar: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileScrollBar: public PIScreenTile { PIOBJECT_SUBCLASS(TileScrollBar, PIScreenTile) friend class TileList; public: @@ -66,7 +67,7 @@ protected: }; -class PIP_EXPORT TileList: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileList: public PIScreenTile { PIOBJECT_SUBCLASS(TileList, PIScreenTile) public: TileList(const PIString & n = PIString()); @@ -98,7 +99,7 @@ protected: }; -class PIP_EXPORT TileButton: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileButton: public PIScreenTile { PIOBJECT_SUBCLASS(TileButton, PIScreenTile) public: TileButton(const PIString & n = PIString()); @@ -118,7 +119,7 @@ protected: -class PIP_EXPORT TileButtons: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileButtons: public PIScreenTile { PIOBJECT_SUBCLASS(TileButtons, PIScreenTile) public: TileButtons(const PIString & n = PIString()); @@ -143,7 +144,7 @@ protected: }; -class PIP_EXPORT TileCheck: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileCheck: public PIScreenTile { PIOBJECT_SUBCLASS(TileCheck, PIScreenTile) public: TileCheck(const PIString & n = PIString()); @@ -162,7 +163,7 @@ protected: }; -class PIP_EXPORT TileProgress: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileProgress: public PIScreenTile { PIOBJECT_SUBCLASS(TileProgress, PIScreenTile) public: TileProgress(const PIString & n = PIString()); @@ -178,7 +179,7 @@ protected: }; -class PIP_EXPORT TilePICout: public TileList { +class PIP_CONSOLE_EXPORT TilePICout: public TileList { PIOBJECT_SUBCLASS(TilePICout, PIScreenTile) public: TilePICout(const PIString & n = PIString()); @@ -191,7 +192,7 @@ protected: }; -class PIP_EXPORT TileInput: public PIScreenTile { +class PIP_CONSOLE_EXPORT TileInput: public PIScreenTile { PIOBJECT_SUBCLASS(TileInput, PIScreenTile) public: TileInput(const PIString & n = PIString()); diff --git a/lib/main/console/piscreentypes.h b/lib/main/console/piscreentypes.h index 34c3349b..2d88cea7 100644 --- a/lib/main/console/piscreentypes.h +++ b/lib/main/console/piscreentypes.h @@ -23,6 +23,7 @@ #ifndef PISCREENTYPES_H #define PISCREENTYPES_H +#include "pip_console_export.h" #include "pivariant.h" class PIScreenTile; @@ -30,7 +31,7 @@ class PIScreenTile; namespace PIScreenTypes { //! Color for chars or background - enum PIP_EXPORT Color { + enum Color { Default /** Default */, Black /** Black */, Red /** Red */, @@ -44,7 +45,7 @@ namespace PIScreenTypes { }; //! Flags for chars - enum PIP_EXPORT CharFlag { + enum CharFlag { Bold /** Bold or bright */ = 0x1, Blink /** Blink text */ = 0x2, Underline /** Underline text */ = 0x4, @@ -52,14 +53,14 @@ namespace PIScreenTypes { }; //! Alignment - enum PIP_EXPORT Alignment { + enum Alignment { Left /** Left */ , Center /** Center */ , Right /** Right */ }; //! Size policy - enum PIP_EXPORT SizePolicy { + enum SizePolicy { Fixed /** Fixed size */ , Preferred /** Preferred size */ , Expanding /** Maximum available size */ , @@ -67,13 +68,13 @@ namespace PIScreenTypes { }; //! Direction - enum PIP_EXPORT Direction { + enum Direction { Horizontal /** Horizontal */ , Vertical /** Vertical */ }; //! Focus flags - enum PIP_EXPORT FocusFlag { + enum FocusFlag { CanHasFocus /** Tile can has focus */ = 0x1, NextByTab /** Focus passed to next tile by tab key */ = 0x2, NextByArrowsHorizontal /** Focus passed to next tile by arrow keys left or right */ = 0x4, @@ -87,7 +88,7 @@ namespace PIScreenTypes { typedef PIFlags CharFlags; typedef PIFlags FocusFlags; - union PIP_EXPORT CellFormat { + union PIP_CONSOLE_EXPORT CellFormat { CellFormat(ushort f = 0) {raw_format = f;} CellFormat(Color col_char, Color col_back = Default, CharFlags flags_ = 0) { color_char = col_char; @@ -104,7 +105,7 @@ namespace PIScreenTypes { bool operator !=(const CellFormat & c) const {return raw_format != c.raw_format;} }; - struct PIP_EXPORT Cell { + struct PIP_CONSOLE_EXPORT Cell { Cell(PIChar c = PIChar(' '), CellFormat f = CellFormat()) {symbol = c; format = f;} CellFormat format; PIChar symbol; @@ -120,7 +121,7 @@ namespace PIScreenTypes { } }; - struct PIP_EXPORT TileEvent { + struct PIP_CONSOLE_EXPORT TileEvent { TileEvent(int t = -1, const PIVariant & d = PIVariant()): type(t), data(d) {} int type; PIVariant data; diff --git a/lib/main/console/piterminal.h b/lib/main/console/piterminal.h index 040892dd..b519d6bd 100644 --- a/lib/main/console/piterminal.h +++ b/lib/main/console/piterminal.h @@ -23,11 +23,12 @@ #ifndef PITERMINAL_H #define PITERMINAL_H +#include "pip_console_export.h" #include "pikbdlistener.h" #include "piscreentypes.h" -class PIP_EXPORT PITerminal: public PIThread +class PIP_CONSOLE_EXPORT PITerminal: public PIThread { PIOBJECT_SUBCLASS(PITerminal, PIThread) public: @@ -63,7 +64,7 @@ private: int termType(const PIString & t); #endif - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT) int dsize_x, dsize_y; int size_x, size_y, cursor_x, cursor_y; bool cursor_blink, cursor_visible; diff --git a/lib/main/containers/pipair.h b/lib/main/containers/pipair.h index 670b240a..0e91ed31 100644 --- a/lib/main/containers/pipair.h +++ b/lib/main/containers/pipair.h @@ -30,7 +30,7 @@ class PICout; template -class PIP_EXPORT PIPair { +class PIPair { public: PIPair() {first = Type0(); second = Type1();} PIPair(const Type0 & value0, const Type1 & value1) {first = value0; second = value1;} diff --git a/lib/main/containers/piqueue.h b/lib/main/containers/piqueue.h index cebd1d76..5c56b1b0 100644 --- a/lib/main/containers/piqueue.h +++ b/lib/main/containers/piqueue.h @@ -30,7 +30,7 @@ template -class PIP_EXPORT PIQueue: public PIDeque { +class PIQueue: public PIDeque { public: PIQueue() {} virtual ~PIQueue() {} diff --git a/lib/main/containers/piset.h b/lib/main/containers/piset.h index 5a819f78..50603403 100644 --- a/lib/main/containers/piset.h +++ b/lib/main/containers/piset.h @@ -35,7 +35,7 @@ * has logarithmic complexity. */ template -class PIP_EXPORT PISet: public PIMap { +class PISet: public PIMap { typedef PIMap _CSet; public: diff --git a/lib/main/containers/pistack.h b/lib/main/containers/pistack.h index 02e62318..5b65fa90 100644 --- a/lib/main/containers/pistack.h +++ b/lib/main/containers/pistack.h @@ -28,7 +28,7 @@ #include "pivector.h" template -class PIP_EXPORT PIStack: public PIVector { +class PIStack: public PIVector { public: PIStack() {;} virtual ~PIStack() {;} diff --git a/lib/main/core/pibase.h b/lib/main/core/pibase.h index 0fb52771..e0b1dd0a 100644 --- a/lib/main/core/pibase.h +++ b/lib/main/core/pibase.h @@ -192,10 +192,10 @@ // Private data macros -#define PRIVATE_DECLARATION \ +#define PRIVATE_DECLARATION(e) \ struct __Private__; \ friend struct __Private__; \ - struct __PrivateInitializer__ { \ + struct e __PrivateInitializer__ { \ __PrivateInitializer__(); \ __PrivateInitializer__(const __PrivateInitializer__ & o); \ ~__PrivateInitializer__(); \ diff --git a/lib/main/core/pibytearray.h b/lib/main/core/pibytearray.h index 47f61f78..79fdf39b 100644 --- a/lib/main/core/pibytearray.h +++ b/lib/main/core/pibytearray.h @@ -138,7 +138,7 @@ inline std::ostream & operator <<(std::ostream & s, const PIByteArray & ba); #endif //! \relatesalso PIByteArray \brief Output to PICout operator -PICout operator <<(PICout s, const PIByteArray & ba); +PIP_EXPORT PICout operator <<(PICout s, const PIByteArray & ba); #define PBA_OPERATOR_TO int os = s.size_s(); s.enlarge(sizeof(v)); memcpy(s.data(os), &v, sizeof(v)); @@ -212,7 +212,7 @@ inline PIByteArray & operator >>(PIByteArray & s, ldouble & v) {assert(s.size() //! \relatesalso PIByteArray \brief Restore operator template inline PIByteArray & operator >>(PIByteArray & s, PIFlags & v) {PBA_OPERATOR_FROM return s;} //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details -PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIByteArray & v); //! \relatesalso PIByteArray \brief Restore operator, see \ref PIByteArray_sec1 for details inline PIByteArray & operator >>(PIByteArray & s, PIByteArray::RawData v) {assert(s.size_s() >= v.s); if (v.s > 0) memcpy((void*)(v.d), s.data(), v.s); s.remove(0, v.s); return s;} diff --git a/lib/main/core/pichar.h b/lib/main/core/pichar.h index cf7dbe0f..5b18db41 100644 --- a/lib/main/core/pichar.h +++ b/lib/main/core/pichar.h @@ -25,9 +25,9 @@ #include "piincludes.h" -extern char * __syslocname__; -extern char * __sysoemname__; -extern char * __utf8name__; +extern PIP_EXPORT char * __syslocname__; +extern PIP_EXPORT char * __sysoemname__; +extern PIP_EXPORT char * __utf8name__; class PIP_EXPORT PIChar { diff --git a/lib/main/core/picout.h b/lib/main/core/picout.h index 19eab8ec..6e4b39d6 100644 --- a/lib/main/core/picout.h +++ b/lib/main/core/picout.h @@ -46,7 +46,7 @@ class PIObject; namespace PICoutManipulators { //! \brief Enum contains special characters - enum PIP_EXPORT PICoutSpecialChar { + enum PICoutSpecialChar { Null /*! Null-character, '\\0' */, NewLine /*! New line character, '\\n' */, Tab /*! Tab character, '\\t' */, @@ -55,7 +55,7 @@ namespace PICoutManipulators { }; //! \brief Enum contains immediate action - enum PIP_EXPORT PICoutAction { + enum PICoutAction { Flush /*! Flush the output */, Backspace /*! Remove last symbol */, ShowCursor /*! Show cursor */, @@ -67,7 +67,7 @@ namespace PICoutManipulators { }; //! \brief Enum contains control of PICout - enum PIP_EXPORT PICoutControl { + enum PICoutControl { AddNone /*! No controls */ = 0x0, AddSpaces /*! Spaces will be appear after each output */ = 0x1, AddNewLine /*! New line will be appear after all output */ = 0x2, @@ -78,7 +78,7 @@ namespace PICoutManipulators { }; //! \brief Enum contains output format - enum PIP_EXPORT PICoutFormat { + enum PICoutFormat { Bin /*! Binary representation of integers */ = 0x01, Oct /*! Octal representation of integers */ = 0x02, Dec /*! Decimal representation of integers */ = 0x04, @@ -128,7 +128,7 @@ public: ~PICout(); - class Notifier { + class PIP_EXPORT Notifier { public: static Notifier * instance(); static PIObject * object(); @@ -291,7 +291,7 @@ private: void applyFormat(PICoutManipulators::PICoutFormat f); static OutputDevices devs; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) bool fo_, cc_, fc_, act_; int cnb_, attr_, id_; PIString * buffer_; diff --git a/lib/main/core/piflags.h b/lib/main/core/piflags.h index 202027f9..d7584dd5 100644 --- a/lib/main/core/piflags.h +++ b/lib/main/core/piflags.h @@ -32,7 +32,7 @@ * \snippet piincludes.cpp flags */ template -class PIP_EXPORT PIFlags { +class PIFlags { public: //! Constructor with flags = 0 PIFlags(): flags(0) {;} diff --git a/lib/main/core/piincludes.h b/lib/main/core/piincludes.h index 7d74775e..ba158476 100644 --- a/lib/main/core/piincludes.h +++ b/lib/main/core/piincludes.h @@ -39,7 +39,7 @@ class PICout; struct lconv; -extern lconv * currentLocale; +extern PIP_EXPORT lconv * currentLocale; /*! \fn errorString() * \brief Return readable error description in format "code - " */ diff --git a/lib/main/core/piinit.h b/lib/main/core/piinit.h index d72d7b1f..e0dad2c8 100644 --- a/lib/main/core/piinit.h +++ b/lib/main/core/piinit.h @@ -63,7 +63,7 @@ private: explicit PIInit(); void setFileCharset(const char *charset); bool fileExists(const PIString & p); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) char * file_charset; }; diff --git a/lib/main/core/piobject.h b/lib/main/core/piobject.h index 9bb9aeb8..6bf52e8c 100644 --- a/lib/main/core/piobject.h +++ b/lib/main/core/piobject.h @@ -800,7 +800,7 @@ public: static bool isTypeOf(const void * o) {return isTypeOf((PIObject*)o);} static PIString simplifyType(const char * a); - struct __MetaFunc { + struct PIP_EXPORT __MetaFunc { __MetaFunc(): addr(0), addrV(0) {;} bool isNull() const {return addr == 0;} PIString arguments() const; @@ -813,7 +813,7 @@ public: PIStringList types; PIStringList names; }; - struct __MetaData { + struct PIP_EXPORT __MetaData { __MetaData() {scope_list << PIStringAscii("PIObject"); scope_id << PIStringAscii("PIObject").hash();} void addScope(const PIString & s, uint shash); PIStringList scope_list; @@ -919,7 +919,7 @@ private: }; -void dumpApplication(); -bool dumpApplicationToFile(const PIString & path); +PIP_EXPORT void dumpApplication(); +PIP_EXPORT bool dumpApplicationToFile(const PIString & path); #endif // PIOBJECT_H diff --git a/lib/main/core/pipropertystorage.h b/lib/main/core/pipropertystorage.h index 56c09a51..a4a8ad15 100644 --- a/lib/main/core/pipropertystorage.h +++ b/lib/main/core/pipropertystorage.h @@ -32,14 +32,14 @@ * contains unique name and you can identify property by name with propertyValueByName(), propertyByName(). * You can add property using addProperty(const Property&), addProperty(const PIString&, const PIVariant&, const PIString&, int). */ -class PIPropertyStorage { +class PIP_EXPORT PIPropertyStorage { public: PIPropertyStorage() {} /** * @brief PIPropertyStorage element. */ - struct Property { + struct PIP_EXPORT Property { Property(const PIString & n = PIString(), const PIString & c = PIString(), const PIVariant & v = PIVariant(), int f = 0): name(n), comment(c), value(v), flags(f) {} diff --git a/lib/main/core/pivariant.h b/lib/main/core/pivariant.h index d40fa561..f5da7ce1 100644 --- a/lib/main/core/pivariant.h +++ b/lib/main/core/pivariant.h @@ -39,7 +39,7 @@ template -class PIP_EXPORT __PIVariantFunctions__ { +class __PIVariantFunctions__ { public: static PIString typeNameHelper() {return PIStringAscii("");} @@ -59,7 +59,7 @@ struct PIP_EXPORT __PIVariantInfo__ { }; template -struct PIP_EXPORT __PIVariantTypeInfo__ { +struct __PIVariantTypeInfo__ { typedef T PureType; typedef const T ConstPureType; typedef T * PointerType; @@ -102,7 +102,7 @@ REGISTER_VARIANT_TYPEINFO(ns::classname) #define REGISTER_VARIANT_CPP(classname) \ template \ -class PIP_EXPORT __##classname##_PIVariantInitializer__ { \ +class __##classname##_PIVariantInitializer__ { \ public: \ __##classname##_PIVariantInitializer__(const PIString & name) { \ if (__PIVariantInfoStorage__::get()->map->contains(name)) \ @@ -115,7 +115,7 @@ public: \ #define REGISTER_NS_VARIANT_CPP(ns, classname) \ template \ -class PIP_EXPORT __##ns##classname##_PIVariantInitializer__ { \ +class __##ns##classname##_PIVariantInitializer__ { \ public: \ __##ns##classname##_PIVariantInitializer__(const PIString & name) { \ if (__PIVariantInfoStorage__::get()->map->contains(name)) \ @@ -155,7 +155,7 @@ PIByteArray __PIVariantFunctions__::castHelper(PIB PIByteArray ret; ret << t; \ return ret;} \ template \ -class PIP_EXPORT __##classname_from##_##classname_to##_PIVariantCastInitializer__ { \ +class __##classname_from##_##classname_to##_PIVariantCastInitializer__ { \ public: \ __##classname_from##_##classname_to##_PIVariantCastInitializer__(const PIString & name, const PIString & cname) { \ __PIVariantInfo__ * vi(__PIVariantInfoStorage__::get()->map->value(name, 0)); \ @@ -206,7 +206,7 @@ class PIP_EXPORT PIVariant { public: //! Type of %PIVariant content - enum PIP_EXPORT Type { + enum Type { pivInvalid /** Invalid type , default type of empty contructor */ = 0 , pivBool /** bool */ , pivChar /** char */ , diff --git a/lib/main/crypt/piauth.h b/lib/main/crypt/piauth.h index 55559484..947d7e77 100644 --- a/lib/main/crypt/piauth.h +++ b/lib/main/crypt/piauth.h @@ -23,11 +23,12 @@ #ifndef PIAUTH_H #define PIAUTH_H +#include "pip_crypt_export.h" #include "piobject.h" #include "picrypt.h" -class PIP_EXPORT PIAuth : public PIObject +class PIP_CRYPT_EXPORT PIAuth : public PIObject { PIOBJECT(PIAuth) public: diff --git a/lib/main/crypt/picrypt.h b/lib/main/crypt/picrypt.h index e9eea9cd..67fe3a6b 100644 --- a/lib/main/crypt/picrypt.h +++ b/lib/main/crypt/picrypt.h @@ -23,9 +23,10 @@ #ifndef PICRYPT_H #define PICRYPT_H +#include "pip_crypt_export.h" #include "pistring.h" -class PIP_EXPORT PICrypt { +class PIP_CRYPT_EXPORT PICrypt { public: //! Construct and generate random key PICrypt(); diff --git a/lib/main/geo/pigeoposition.h b/lib/main/geo/pigeoposition.h index ef6ead1e..bb301198 100644 --- a/lib/main/geo/pigeoposition.h +++ b/lib/main/geo/pigeoposition.h @@ -30,8 +30,7 @@ class PIP_EXPORT PIGeoPosition : public PIMathVectorT3d { public: - enum CoordinateSystem - { + enum CoordinateSystem { Unknown=0, /// Unknown coordinate system Geodetic, /// Geodetic latitude, longitude, and height above ellipsoid Geocentric, /// Geocentric (regular spherical coordinates) diff --git a/lib/main/introspection/piintrospection_containers_p.h b/lib/main/introspection/piintrospection_containers_p.h index f9d24a71..7ace0e6d 100644 --- a/lib/main/introspection/piintrospection_containers_p.h +++ b/lib/main/introspection/piintrospection_containers_p.h @@ -44,7 +44,7 @@ public: PIVector getInfo() const; #pragma pack(push, 1) - struct _Type { + struct PIP_EXPORT _Type { _Type(); uint id; uint count; @@ -54,7 +54,7 @@ public: }; #pragma pack(pop) - struct TypeInfo: _Type { + struct PIP_EXPORT TypeInfo: _Type { PIString name; }; @@ -63,7 +63,7 @@ public: mutable PIMutex mutex; }; -PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v); -PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PIIntrospectionContainers::TypeInfo & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PIIntrospectionContainers::TypeInfo & v); #endif // PIINTROSPECTION_CONTAINERS_P_H diff --git a/lib/main/introspection/piintrospection_server_p.h b/lib/main/introspection/piintrospection_server_p.h index d47b83da..549dd044 100644 --- a/lib/main/introspection/piintrospection_server_p.h +++ b/lib/main/introspection/piintrospection_server_p.h @@ -27,7 +27,7 @@ #include "pisystemmonitor.h" -class PIIntrospection { +class PIP_EXPORT PIIntrospection { public: enum InfoTypes { @@ -38,12 +38,12 @@ public: itThreads = 0x10, }; - struct RequiredInfo { + struct PIP_EXPORT RequiredInfo { RequiredInfo(); PIFlags types; }; - struct ProcessInfo { + struct PIP_EXPORT ProcessInfo { ProcessInfo(); PIString execCommand, hostname, user, OS_name, OS_version, architecture; @@ -53,14 +53,14 @@ public: PIStringList build_options; }; - struct ProcessStat { + struct PIP_EXPORT ProcessStat { ProcessStat() {} PISystemMonitor::ProcessStats proc; PIVector threads; }; - struct ObjectInfo { + struct PIP_EXPORT ObjectInfo { ObjectInfo(); PIString classname, name; @@ -91,13 +91,13 @@ public: }; -PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::RequiredInfo & v); -PIByteArray & operator >>(PIByteArray & b, PIIntrospection::RequiredInfo & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::RequiredInfo & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::RequiredInfo & v); -PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v); -PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ProcessInfo & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ProcessInfo & v); -PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v); -PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospection::ObjectInfo & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospection::ObjectInfo & v); #endif // PIINTROSPECTION_SERVER_P_H diff --git a/lib/main/introspection/piintrospection_threads_p.h b/lib/main/introspection/piintrospection_threads_p.h index b9f12461..3318a4d2 100644 --- a/lib/main/introspection/piintrospection_threads_p.h +++ b/lib/main/introspection/piintrospection_threads_p.h @@ -35,7 +35,7 @@ public: sWaiting, }; - struct ThreadInfo { + struct PIP_EXPORT ThreadInfo { ThreadInfo(); PIString classname, name; int id, delay; @@ -57,7 +57,7 @@ public: }; -PIByteArray & operator <<(PIByteArray & b, const PIIntrospectionThreads::ThreadInfo & v); -PIByteArray & operator >>(PIByteArray & b, PIIntrospectionThreads::ThreadInfo & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & b, const PIIntrospectionThreads::ThreadInfo & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & b, PIIntrospectionThreads::ThreadInfo & v); #endif // PIINTROSPECTION_THREADS_P_H diff --git a/lib/main/io_devices/pibinarylog.h b/lib/main/io_devices/pibinarylog.h index c41401f0..6703dcf0 100644 --- a/lib/main/io_devices/pibinarylog.h +++ b/lib/main/io_devices/pibinarylog.h @@ -56,7 +56,7 @@ public: }; //! \brief Struct contains information about all records with same ID - struct BinLogRecordInfo { + struct PIP_EXPORT BinLogRecordInfo { BinLogRecordInfo() { id = count = 0; minimum_size = maximum_size = 0; @@ -70,7 +70,7 @@ public: }; //! \brief Struct contains full information about Binary Log file and about all Records using map of \a BinLogRecordInfo - struct BinLogInfo { + struct PIP_EXPORT BinLogInfo { PIString path; int records_count; llong log_size; @@ -80,7 +80,7 @@ public: }; //! \brief Struct contains position, ID and timestamp of record in file - struct BinLogIndex { + struct PIP_EXPORT BinLogIndex { int id; llong pos; PISystemTime timestamp; @@ -293,7 +293,7 @@ protected: DeviceInfoFlags deviceInfoFlags() const {return PIIODevice::Reliable;} private: - struct BinLogRecord { + struct PIP_EXPORT BinLogRecord { int id; int size; PISystemTime timestamp; diff --git a/lib/main/io_devices/piconfig.h b/lib/main/io_devices/piconfig.h index cb3ddb6e..c6027ffc 100644 --- a/lib/main/io_devices/piconfig.h +++ b/lib/main/io_devices/piconfig.h @@ -505,8 +505,8 @@ private: #ifdef PIP_STD_IOSTREAM -std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v); -std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v); +PIP_EXPORT std::ostream & operator <<(std::ostream & s, const PIConfig::Branch & v); +PIP_EXPORT std::ostream & operator <<(std::ostream & s, const PIConfig::Entry & v); #endif inline PICout operator <<(PICout s, const PIConfig::Branch & v) {s.setControl(0, true); v.piCoutt(s, ""); s.restoreControl(); return s;} diff --git a/lib/main/io_devices/piethernet.h b/lib/main/io_devices/piethernet.h index 574f9fab..bb9f988e 100644 --- a/lib/main/io_devices/piethernet.h +++ b/lib/main/io_devices/piethernet.h @@ -43,7 +43,7 @@ public: explicit PIEthernet(); //! \brief Type of %PIEthernet - enum PIP_EXPORT Type { + enum Type { UDP /** UDP - User Datagram Protocol */ , TCP_Client /** TCP client - allow connection to TCP server */ , TCP_Server /** TCP server - receive connections from TCP clients */ , @@ -51,7 +51,7 @@ public: }; //! \brief Parameters of %PIEthernet - enum PIP_EXPORT Parameters { + enum Parameters { ReuseAddress /** Rebind address if there is already binded. Enabled by default */ = 0x1, Broadcast /** Broadcast send. Disabled by default */ = 0x2, SeparateSockets /** If this parameter is set, %PIEthernet will initialize two different sockets, @@ -63,7 +63,7 @@ public: //! \brief IPv4 network address, IP and port - class Address { + class PIP_EXPORT Address { friend class PIEthernet; friend inline PIByteArray & operator <<(PIByteArray & s, const PIEthernet::Address & v); friend inline PIByteArray & operator >>(PIByteArray & s, PIEthernet::Address & v); @@ -322,7 +322,7 @@ public: //! Flags of network interface - enum PIP_EXPORT InterfaceFlag { + enum InterfaceFlag { ifActive /** Is active */ = 0x1, ifRunning /** Is running */ = 0x2, ifBroadcast /** Support broadcast */ = 0x4, @@ -485,7 +485,7 @@ protected: void applyTimeout(int fd, int opt, double ms); void applyOptInt(int level, int opt, int val); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) int sock, sock_s; bool connected_, connecting_, listen_threaded, server_bounded; mutable Address addr_r, addr_s, addr_lr; diff --git a/lib/main/io_devices/pifile.h b/lib/main/io_devices/pifile.h index e8af7626..1f94625b 100644 --- a/lib/main/io_devices/pifile.h +++ b/lib/main/io_devices/pifile.h @@ -38,7 +38,7 @@ public: struct PIP_EXPORT FileInfo { FileInfo() {size = 0; id_group = id_user = 0;} - enum PIP_EXPORT Flag { + enum Flag { File = 0x01, Dir = 0x02, Dot = 0x04, @@ -292,7 +292,7 @@ protected: private: PIString strType(const PIIODevice::DeviceMode type); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) int ret, prec_, fdi; PIString prec_str; diff --git a/lib/main/io_devices/pigpio.h b/lib/main/io_devices/pigpio.h index cd2b91e7..ed566206 100644 --- a/lib/main/io_devices/pigpio.h +++ b/lib/main/io_devices/pigpio.h @@ -26,7 +26,7 @@ #include "pithread.h" -class PIGPIO: public PIThread +class PIP_EXPORT PIGPIO: public PIThread { PIOBJECT_SUBCLASS(PIGPIO, PIThread) public: @@ -85,7 +85,7 @@ public: //! \} private: - struct GPIOData { + struct PIP_EXPORT GPIOData { GPIOData() {dir = PIGPIO::In; num = fd = -1;} PIString name; int dir; diff --git a/lib/main/io_devices/pipeer.h b/lib/main/io_devices/pipeer.h index 155d6055..41862623 100644 --- a/lib/main/io_devices/pipeer.h +++ b/lib/main/io_devices/pipeer.h @@ -36,7 +36,7 @@ public: explicit PIPeer(const PIString & name = PIString()); virtual ~PIPeer(); - class PeerInfo { + class PIP_EXPORT PeerInfo { friend class PIPeer; friend PIByteArray & operator <<(PIByteArray & s, const PIPeer::PeerInfo & v); friend PIByteArray & operator >>(PIByteArray & s, PIPeer::PeerInfo & v); @@ -44,7 +44,7 @@ public: PeerInfo() {dist = sync = cnt = 0; trace = -1; was_update = false; _data = 0;} ~PeerInfo() {} - struct PeerAddress { + struct PIP_EXPORT PeerAddress { PeerAddress(const PIEthernet::Address & a = PIEthernet::Address(), const PIEthernet::Address & m = PIEthernet::Address("255.255.255.0")); bool isAvailable() const {return ping > 0;} PIEthernet::Address address; diff --git a/lib/main/io_devices/piserial.h b/lib/main/io_devices/piserial.h index 8ef9e9d7..4b8cae4e 100644 --- a/lib/main/io_devices/piserial.h +++ b/lib/main/io_devices/piserial.h @@ -72,7 +72,7 @@ public: }; //! \brief Information about serial device - struct DeviceInfo { + struct PIP_EXPORT DeviceInfo { DeviceInfo(); //! \brief String representation of USB ID in format \"xxxx:xxxx\" @@ -246,7 +246,7 @@ protected: bool openDevice(); bool closeDevice(); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) int fd, vtime; bool sending; PITimeMeasurer tm_; diff --git a/lib/main/io_devices/pisharedmemory.h b/lib/main/io_devices/pisharedmemory.h index f00046e8..36bd8c3f 100644 --- a/lib/main/io_devices/pisharedmemory.h +++ b/lib/main/io_devices/pisharedmemory.h @@ -86,7 +86,7 @@ private: void initPrivate(); int dsize; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) }; diff --git a/lib/main/io_devices/pispi.h b/lib/main/io_devices/pispi.h index f6705f81..7c30a59f 100644 --- a/lib/main/io_devices/pispi.h +++ b/lib/main/io_devices/pispi.h @@ -77,7 +77,7 @@ private: uchar spi_bits; PIByteArray tx_buf, rx_buf; PIByteArray recv_buf; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) }; #endif // PISPI_H diff --git a/lib/main/io_devices/piusb.h b/lib/main/io_devices/piusb.h index ce729734..2b17d382 100644 --- a/lib/main/io_devices/piusb.h +++ b/lib/main/io_devices/piusb.h @@ -34,7 +34,7 @@ public: explicit PIUSB(ushort vid = 0, ushort pid = 0); ~PIUSB() {closeDevice();} - struct Endpoint { + struct PIP_EXPORT Endpoint { Endpoint(uchar a = 0, uchar at = 0, ushort mps = 0) {address = a; attributes = at; max_packet_size = mps; parse();} enum Direction {Write = 0, Read = 1}; @@ -54,7 +54,7 @@ public: UsageType usage_type; }; - struct Interface { + struct PIP_EXPORT Interface { Interface() {index = value_to_select = class_code = subclass_code = protocol_code = 0;} uchar index; uchar value_to_select; @@ -64,7 +64,7 @@ public: PIVector endpoints; }; - struct Configuration { + struct PIP_EXPORT Configuration { Configuration() {index = value_to_select = attributes = max_power = 0; self_powered = remote_wakeup = false;} uchar index; uchar value_to_select; @@ -75,7 +75,7 @@ public: PIVector interfaces; }; - struct Descriptor { + struct PIP_EXPORT Descriptor { Descriptor() {usb_spec_number = 0; device_class = device_subclass = device_protocol = max_packet_size = 0; id_vendor = id_product = id_device_release = 0; index_manufacturer = index_product = index_serial = 0;} ushort usb_spec_number; uchar device_class; @@ -148,6 +148,6 @@ protected: }; -PICout operator <<(PICout s, const PIUSB::Endpoint & v); +PIP_EXPORT PICout operator <<(PICout s, const PIUSB::Endpoint & v); #endif // PIUSB_H diff --git a/lib/main/io_utils/pibasetransfer.h b/lib/main/io_utils/pibasetransfer.h index a11909da..d5f54ac2 100644 --- a/lib/main/io_utils/pibasetransfer.h +++ b/lib/main/io_utils/pibasetransfer.h @@ -102,7 +102,7 @@ protected: llong bytes_all, bytes_cur; private: - enum PIP_EXPORT PacketType {pt_Unknown, pt_Data, pt_ReplySuccess, pt_ReplyInvalid, pt_Break, pt_Start, pt_Pause}; + enum PacketType {pt_Unknown, pt_Data, pt_ReplySuccess, pt_ReplyInvalid, pt_Break, pt_Start, pt_Pause}; # pragma pack(push,1) struct PIP_EXPORT StartRequest { diff --git a/lib/main/io_utils/pibroadcast.h b/lib/main/io_utils/pibroadcast.h index b099e43e..67008007 100644 --- a/lib/main/io_utils/pibroadcast.h +++ b/lib/main/io_utils/pibroadcast.h @@ -23,11 +23,12 @@ #ifndef PIBROADCAST_H #define PIBROADCAST_H +#include "pip_io_utils_export.h" #include "piethutilbase.h" #include "piethernet.h" -class PIBroadcast: public PIThread, public PIEthUtilBase { +class PIP_IO_UTILS_EXPORT PIBroadcast: public PIThread, public PIEthUtilBase { PIOBJECT_SUBCLASS(PIBroadcast, PIThread) public: diff --git a/lib/main/io_utils/piconnection.h b/lib/main/io_utils/piconnection.h index 5af11b52..f6be10bd 100644 --- a/lib/main/io_utils/piconnection.h +++ b/lib/main/io_utils/piconnection.h @@ -404,7 +404,7 @@ private: void __DevicePool_threadReadDP(void * ddp); -extern PIConnection::DevicePool * __device_pool__; +extern PIP_EXPORT PIConnection::DevicePool * __device_pool__; class PIP_EXPORT __DevicePoolContainer__ { public: diff --git a/lib/main/io_utils/pidiagnostics.h b/lib/main/io_utils/pidiagnostics.h index 9815bb19..71da060a 100644 --- a/lib/main/io_utils/pidiagnostics.h +++ b/lib/main/io_utils/pidiagnostics.h @@ -49,7 +49,7 @@ public: }; //! Information about current diagnostics state - struct State { + struct PIP_EXPORT State { State(); float immediate_freq; float integral_freq; @@ -123,7 +123,7 @@ public: //! \} private: - struct Entry { + struct PIP_EXPORT Entry { Entry() {bytes_ok = bytes_fail = 0; cnt_ok = cnt_fail = 0; empty = true;} ullong bytes_ok; ullong bytes_fail; diff --git a/lib/main/io_utils/piethutilbase.h b/lib/main/io_utils/piethutilbase.h index 8542ef36..fc564004 100644 --- a/lib/main/io_utils/piethutilbase.h +++ b/lib/main/io_utils/piethutilbase.h @@ -23,9 +23,10 @@ #ifndef PIETHUTILBASE_H #define PIETHUTILBASE_H +#include "pip_io_utils_export.h" #include "pibytearray.h" -class PIEthUtilBase { +class PIP_IO_UTILS_EXPORT PIEthUtilBase { public: PIEthUtilBase(); ~PIEthUtilBase(); diff --git a/lib/main/io_utils/pifiletransfer.h b/lib/main/io_utils/pifiletransfer.h index 241b499c..b74b9eef 100644 --- a/lib/main/io_utils/pifiletransfer.h +++ b/lib/main/io_utils/pifiletransfer.h @@ -35,7 +35,7 @@ public: PIFileTransfer(); ~PIFileTransfer(); - enum PIP_EXPORT StepType {pft_None, pft_Description, pft_Data}; + enum StepType {pft_None, pft_Description, pft_Data}; struct PIP_EXPORT PFTFileInfo: public PIFile::FileInfo { PFTFileInfo(const PIFile::FileInfo &fi = PIFile::FileInfo()): PIFile::FileInfo(fi) {} diff --git a/lib/main/io_utils/pistreampacker.h b/lib/main/io_utils/pistreampacker.h index 361e647c..f9777ee4 100644 --- a/lib/main/io_utils/pistreampacker.h +++ b/lib/main/io_utils/pistreampacker.h @@ -23,20 +23,21 @@ #ifndef PISTREAMPACKER_H #define PISTREAMPACKER_H +#include "pip_io_utils_export.h" #include "piobject.h" #include "piethutilbase.h" class PIIODevice; -class PIP_EXPORT PIStreamPacker: public PIObject, public PIEthUtilBase { +class PIP_IO_UTILS_EXPORT PIStreamPacker: public PIObject, public PIEthUtilBase { PIOBJECT(PIStreamPacker) public: //! Contructs packer and try to assign \"dev\" PIStreamPacker(PIIODevice * dev = 0); //! Progress info - struct Progress { + struct PIP_IO_UTILS_EXPORT Progress { Progress(); //! Is send/receive in progress diff --git a/lib/main/lua/piluaprogram.h b/lib/main/lua/piluaprogram.h index a21b075a..3b2cf5da 100644 --- a/lib/main/lua/piluaprogram.h +++ b/lib/main/lua/piluaprogram.h @@ -23,9 +23,10 @@ #ifndef PILUAPROGRAM_H #define PILUAPROGRAM_H +#include "pip_lua_export.h" #include "pip_lua.h" -class PILuaProgram +class PIP_LUA_EXPORT PILuaProgram { public: //! Constructs an empty PILuaProgram, initialize Lua context @@ -44,7 +45,7 @@ public: luabridge::Namespace getGlobalNamespace(); private: - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_LUA_EXPORT) }; #endif // PILUAPROGRAM_H diff --git a/lib/main/math/picompress.h b/lib/main/math/picompress.h index 187b019e..799ab072 100644 --- a/lib/main/math/picompress.h +++ b/lib/main/math/picompress.h @@ -25,8 +25,8 @@ #include "pibytearray.h" -PIByteArray piCompress(const PIByteArray & ba, int level = 6); +PIP_EXPORT PIByteArray piCompress(const PIByteArray & ba, int level = 6); -PIByteArray piDecompress(const PIByteArray & zba); +PIP_EXPORT PIByteArray piDecompress(const PIByteArray & zba); #endif // PICOMPRESS_H diff --git a/lib/main/math/pievaluator.h b/lib/main/math/pievaluator.h index fa4095a2..94ff6250 100644 --- a/lib/main/math/pievaluator.h +++ b/lib/main/math/pievaluator.h @@ -30,12 +30,12 @@ typedef complexd (*FuncFunc)(void * , int, complexd * ); namespace PIEvaluatorTypes { - enum PIP_EXPORT eType {etNumber, etOperator, etVariable, etFunction}; - enum PIP_EXPORT Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower, + enum eType {etNumber, etOperator, etVariable, etFunction}; + enum Operation {oNone, oAdd, oSubtract, oMultiply, oDivide, oResidue, oPower, oEqual, oNotEqual, oGreater, oSmaller, oGreaterEqual, oSmallerEqual, oAnd, oOr, oFunction }; - enum PIP_EXPORT BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg, + enum BaseFunctions {bfUnknown, bfSin, bfCos, bfTg, bfCtg, bfArcsin, bfArccos, bfArctg, bfArcctg, bfExp, bfRandom, bfRandomn, bfSh, bfCh, bfTh, bfCth, diff --git a/lib/main/math/pifft.h b/lib/main/math/pifft.h index 06250e32..628f3979 100644 --- a/lib/main/math/pifft.h +++ b/lib/main/math/pifft.h @@ -23,6 +23,7 @@ #ifndef PIFFT_H #define PIFFT_H +#include "pip_fftw_export.h" #include "pimathcomplex.h" class PIP_EXPORT PIFFT_double @@ -123,7 +124,7 @@ typedef PIFFT_float PIFFTf; #ifndef CC_VC -#define _PIFFTW_H(type) class _PIFFTW_P_##type##_ { \ +#define _PIFFTW_H(type) class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \ public: \ _PIFFTW_P_##type##_(); \ ~_PIFFTW_P_##type##_(); \ @@ -138,7 +139,7 @@ _PIFFTW_H(double) _PIFFTW_H(ldouble) template -class PIP_EXPORT PIFFTW +class PIFFTW { public: explicit PIFFTW() {p = 0; newP(p);} diff --git a/lib/main/math/pimathbase.h b/lib/main/math/pimathbase.h index 740514b7..d33482b7 100644 --- a/lib/main/math/pimathbase.h +++ b/lib/main/math/pimathbase.h @@ -103,21 +103,21 @@ inline float sqr(const float & v) {return v * v;} inline double sqr(const double & v) {return v * v;} inline double sinc(const double & v) {if (v == 0.) return 1.; double t = M_PI * v; return sin(t) / t;} -double piJ0(const double & v); -double piJ1(const double & v); -double piJn(int n, const double & v); -double piY0(const double & v); -double piY1(const double & v); -double piYn(int n, const double & v); +PIP_EXPORT double piJ0(const double & v); +PIP_EXPORT double piJ1(const double & v); +PIP_EXPORT double piJn(int n, const double & v); +PIP_EXPORT double piY0(const double & v); +PIP_EXPORT double piY1(const double & v); +PIP_EXPORT double piYn(int n, const double & v); inline double toDb(double val) {return 10. * log10(val);} inline double fromDb(double val) {return pow(10., val / 10.);} inline double toRad(double deg) {return deg * M_PI_180;} inline double toDeg(double rad) {return rad * M_180_PI;} // [-1 ; 1] -double randomd(); +PIP_EXPORT double randomd(); // [-1 ; 1] normal -double randomn(double dv = 0., double sv = 1.); +PIP_EXPORT double randomn(double dv = 0., double sv = 1.); inline PIVector abs(const PIVector & v) { diff --git a/lib/main/math/pimathsolver.h b/lib/main/math/pimathsolver.h index 23bbd249..5d030c20 100644 --- a/lib/main/math/pimathsolver.h +++ b/lib/main/math/pimathsolver.h @@ -27,7 +27,7 @@ /// Differential evaluations -struct TransferFunction { +struct PIP_EXPORT TransferFunction { PIVector vector_Bm, vector_An; }; diff --git a/lib/main/math/piquaternion.h b/lib/main/math/piquaternion.h index 475da1b6..e9b79e92 100644 --- a/lib/main/math/piquaternion.h +++ b/lib/main/math/piquaternion.h @@ -25,7 +25,7 @@ #include "pimathmatrix.h" -class PIQuaternion +class PIP_EXPORT PIQuaternion { friend PIQuaternion operator*(const PIQuaternion & q0, const PIQuaternion & q1); friend PIQuaternion operator*(const double & a, const PIQuaternion & q); @@ -57,8 +57,8 @@ protected: }; -PIQuaternion operator *(const double & a, const PIQuaternion & q); -PIQuaternion operator *(const PIQuaternion & q0, const PIQuaternion & q1); +PIP_EXPORT PIQuaternion operator *(const double & a, const PIQuaternion & q); +PIP_EXPORT PIQuaternion operator *(const PIQuaternion & q0, const PIQuaternion & q1); inline PIQuaternion operator +(const PIQuaternion & q0, const PIQuaternion & q1) {return PIQuaternion(q0.vector() + q1.vector(), q0.scalar() + q1.scalar());} inline PIQuaternion operator -(const PIQuaternion & q0, const PIQuaternion & q1) {return PIQuaternion(q0.vector() - q1.vector(), q0.scalar() - q1.scalar());} inline PIQuaternion operator -(const PIQuaternion & q0) {return PIQuaternion(-q0.vector(), -q0.scalar());} diff --git a/lib/main/math/pistatistic.h b/lib/main/math/pistatistic.h index f5f66f30..d4e70997 100644 --- a/lib/main/math/pistatistic.h +++ b/lib/main/math/pistatistic.h @@ -26,7 +26,7 @@ #include "pimathbase.h" template -class PIP_EXPORT PIStatistic { +class PIStatistic { public: PIStatistic() {mean = variance = skewness = kurtosis = T();} diff --git a/lib/main/opencl/piopencl.h b/lib/main/opencl/piopencl.h index ac00f160..51be9a6a 100644 --- a/lib/main/opencl/piopencl.h +++ b/lib/main/opencl/piopencl.h @@ -20,10 +20,11 @@ #ifndef PIOPENCL_H #define PIOPENCL_H +#include "pip_opencl_export.h" #include "pivariant.h" -class PIOpenCL { +class PIP_OPENCL_EXPORT PIOpenCL { public: struct KernelArg; @@ -69,7 +70,7 @@ public: Double, }; - struct KernelArg { + struct PIP_OPENCL_EXPORT KernelArg { KernelArg(); AddressQualifier address_qualifier; AccessQualifier access_qualifier; @@ -85,7 +86,7 @@ public: void init(void * _k, uint index); }; - struct Device { + struct PIP_OPENCL_EXPORT Device { Device() {id = platform_id = 0; max_compute_units = max_clock_frequency = 0; max_memory_size = 0;} bool isValid() const {return id != 0;} PIString displayText() const {return name.trimmed() + " (" + device_version.trimmed() + ")";} @@ -100,7 +101,7 @@ public: ullong max_memory_size; }; - struct Platform { + struct PIP_OPENCL_EXPORT Platform { Platform() {id = 0;} bool isValid() const {return id != 0;} PIString displayText() const {return name.trimmed() + " (" + version.trimmed() + ", " + profile.trimmed() + ")";} @@ -113,7 +114,7 @@ public: PIVector devices; }; - class Context { + class PIP_OPENCL_EXPORT Context { friend class Program; public: ~Context(); @@ -125,10 +126,10 @@ public: void zero(); void deletePrograms(); PIVector programs_; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; - class Program { + class PIP_OPENCL_EXPORT Program { friend class Context; friend class Kernel; public: @@ -143,10 +144,10 @@ public: Context * context_; PIString source_; PIVector kernels_; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; - class Kernel { + class PIP_OPENCL_EXPORT Kernel { friend class Program; public: const PIString & name() const {return name_;} @@ -165,7 +166,7 @@ public: Program * program_; PIString name_; PIVector args_; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_OPENCL_EXPORT) }; static void init(); @@ -177,7 +178,7 @@ public: private: static PIString prog_header; PIOpenCL() {;} - class Initializer { + class PIP_OPENCL_EXPORT Initializer { public: Initializer(); static Initializer * instance(); diff --git a/lib/main/piplatform.h b/lib/main/piplatform.h index 73eebc88..cb46423d 100644 --- a/lib/main/piplatform.h +++ b/lib/main/piplatform.h @@ -20,6 +20,8 @@ #ifndef PIPLATFORM_H #define PIPLATFORM_H +#include + #if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) # define WINDOWS # define ARCH_BITS_64 @@ -90,11 +92,5 @@ # define typeof __typeof__ #endif -#if defined(DOXYGEN) || defined(CC_GCC) || defined(PICODE) -# undef PIP_EXPORT -# define PIP_EXPORT -# undef DEPRECATED -# define DEPRECATED -#endif #endif // PIPLATFORM_H diff --git a/lib/main/system/pilibrary.h b/lib/main/system/pilibrary.h index 653f7db6..581fa5d1 100644 --- a/lib/main/system/pilibrary.h +++ b/lib/main/system/pilibrary.h @@ -42,7 +42,7 @@ private: bool loadInternal(); void getLastError(); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) PIString libpath, liberror; }; diff --git a/lib/main/system/piprocess.h b/lib/main/system/piprocess.h index 74f48cc6..d7473432 100644 --- a/lib/main/system/piprocess.h +++ b/lib/main/system/piprocess.h @@ -93,7 +93,7 @@ private: void exec_(); void startProc(bool detached); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) PIStringList args, env; PIString wd; PIByteArray out; diff --git a/lib/main/system/pisysteminfo.h b/lib/main/system/pisysteminfo.h index db1e54d2..5de39d5f 100644 --- a/lib/main/system/pisysteminfo.h +++ b/lib/main/system/pisysteminfo.h @@ -26,7 +26,7 @@ class PIP_EXPORT PISystemInfo { public: PISystemInfo(); - struct MountInfo { + struct PIP_EXPORT MountInfo { MountInfo(); PIString mount_point; PIString device; diff --git a/lib/main/system/pisystemmonitor.h b/lib/main/system/pisystemmonitor.h index a860a19a..f3407f81 100644 --- a/lib/main/system/pisystemmonitor.h +++ b/lib/main/system/pisystemmonitor.h @@ -32,7 +32,7 @@ public: ~PISystemMonitor(); #pragma pack(push, 1) - struct ProcessStatsFixed { + struct PIP_EXPORT ProcessStatsFixed { ProcessStatsFixed(); int ID; int parent_ID; @@ -52,7 +52,7 @@ public: float cpu_load_user; }; - struct ThreadStatsFixed { + struct PIP_EXPORT ThreadStatsFixed { ThreadStatsFixed(); llong id; PISystemTime work_time; @@ -63,7 +63,7 @@ public: }; #pragma pack(pop) - struct ProcessStats: ProcessStatsFixed { + struct PIP_EXPORT ProcessStats: ProcessStatsFixed { void makeStrings(); PIString exec_name; PIString state; @@ -74,7 +74,7 @@ public: PIString data_memsize_readable; }; - struct ThreadStats: ThreadStatsFixed { + struct PIP_EXPORT ThreadStats: ThreadStatsFixed { PIString name; PIDateTime created; }; @@ -107,10 +107,10 @@ private: mutable PIMutex stat_mutex; int pID_, page_size, cpu_count, cycle; #ifndef FREERTOS - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) #endif - class Pool { + class PIP_EXPORT Pool { friend class PISystemMonitor; public: static Pool * instance(); @@ -136,9 +136,9 @@ inline PICout operator <<(PICout s, const PISystemMonitor::ThreadStats & v) { return s; } -PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ProcessStats & v); -PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ProcessStats & v); -PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ThreadStats & v); -PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ThreadStats & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ProcessStats & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ProcessStats & v); +PIP_EXPORT PIByteArray & operator <<(PIByteArray & s, const PISystemMonitor::ThreadStats & v); +PIP_EXPORT PIByteArray & operator >>(PIByteArray & s, PISystemMonitor::ThreadStats & v); #endif // PISYSTEMMONITOR_H diff --git a/lib/main/system/pisystemtests.h b/lib/main/system/pisystemtests.h index 7aaafc85..094c85c1 100644 --- a/lib/main/system/pisystemtests.h +++ b/lib/main/system/pisystemtests.h @@ -23,16 +23,16 @@ #include "pibase.h" namespace PISystemTests { - PIP_EXPORT extern long time_resolution_ns; - PIP_EXPORT extern long time_elapsed_ns; - PIP_EXPORT extern long usleep_offset_us; + extern PIP_EXPORT long time_resolution_ns; + extern PIP_EXPORT long time_elapsed_ns; + extern PIP_EXPORT long usleep_offset_us; - class PISystemTestReader { + class PIP_EXPORT PISystemTestReader { public: PISystemTestReader(); }; - extern PISystemTestReader pisystestreader; + extern PIP_EXPORT PISystemTestReader pisystestreader; } #endif // PISYSTEMTESTS_H diff --git a/lib/main/thread/piconditionvar.h b/lib/main/thread/piconditionvar.h index 923e2ba7..0e988e32 100644 --- a/lib/main/thread/piconditionvar.h +++ b/lib/main/thread/piconditionvar.h @@ -111,7 +111,7 @@ public: virtual bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition); private: - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) }; diff --git a/lib/main/thread/pigrabberbase.h b/lib/main/thread/pigrabberbase.h index 3ba007fe..07a5c35d 100644 --- a/lib/main/thread/pigrabberbase.h +++ b/lib/main/thread/pigrabberbase.h @@ -28,7 +28,7 @@ template -class PIP_EXPORT PIGrabberBase: public PIThread +class PIGrabberBase: public PIThread { PIOBJECT_SUBCLASS(PIGrabberBase, PIThread) public: diff --git a/lib/main/thread/pimutex.h b/lib/main/thread/pimutex.h index b71b1600..a551625d 100644 --- a/lib/main/thread/pimutex.h +++ b/lib/main/thread/pimutex.h @@ -59,7 +59,7 @@ private: void init(); void destroy(); - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) }; diff --git a/lib/main/thread/pithread.h b/lib/main/thread/pithread.h index 2e08aa68..b6aa3c95 100644 --- a/lib/main/thread/pithread.h +++ b/lib/main/thread/pithread.h @@ -243,7 +243,7 @@ protected: PITimeMeasurer tmf_, tms_, tmr_; PIThread::Priority priority_; ThreadFunc ret_func; - PRIVATE_DECLARATION + PRIVATE_DECLARATION(PIP_EXPORT) private: bool _startThread(void * func); diff --git a/lib/main/thread/pithreadpoolexecutor.h b/lib/main/thread/pithreadpoolexecutor.h index d8655843..1d3bf75f 100644 --- a/lib/main/thread/pithreadpoolexecutor.h +++ b/lib/main/thread/pithreadpoolexecutor.h @@ -24,7 +24,7 @@ #include -class PIThreadPoolExecutor { +class PIP_EXPORT PIThreadPoolExecutor { public: explicit PIThreadPoolExecutor(size_t corePoolSize = -1, PIBlockingDequeue > * taskQueue_ = 0); diff --git a/main.cpp b/main.cpp index f0613273..5a9484ff 100644 --- a/main.cpp +++ b/main.cpp @@ -49,7 +49,7 @@ int main() { piCout << s.replaceAll(' ', '1');*/ piDebug = false; double min = -1, max = -1, mean = 0; - for (int i = 0; i < 50; ++i) { + for (int i = 0; i < 1; ++i) { PICodeParser cp; PITimeMeasurer tm; cp.parseFile("SH_plugin_base.h"); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bcb399c3..7f52c1a6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,9 +1,10 @@ include(DownloadGTest) macro(pip_test NAME LIBS) - gather_src("${NAME}" CPP_${NAME}_TEST _T_H _T_PH) + file(GLOB _CPPS "${NAME}/*.cpp") + file(GLOB _HDRS "${NAME}/*.h") set(_target pip_${NAME}_test) - add_executable(${_target} ${CPP_${NAME}_TEST}) + add_executable(${_target} ${_CPPS} ${_HDRS}) target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main) add_test(NAME ${_target} COMMAND tests) add_custom_target(${_target}_perform ALL COMMAND ${_target}) diff --git a/lib/main/auxiliary/piterminal/CMakeLists.txt b/utils/piterminal/CMakeLists.txt similarity index 74% rename from lib/main/auxiliary/piterminal/CMakeLists.txt rename to utils/piterminal/CMakeLists.txt index 81f2d998..89e51920 100644 --- a/lib/main/auxiliary/piterminal/CMakeLists.txt +++ b/utils/piterminal/CMakeLists.txt @@ -2,4 +2,6 @@ add_executable(piterminal "main.cpp") target_link_libraries(piterminal pip pip_console) if (DEFINED LIB) install(TARGETS piterminal DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) -endif () +else() + install(TARGETS piterminal DESTINATION bin) +endif() diff --git a/lib/main/auxiliary/piterminal/main.cpp b/utils/piterminal/main.cpp similarity index 100% rename from lib/main/auxiliary/piterminal/main.cpp rename to utils/piterminal/main.cpp index 8e077933..d78f1a8f 100644 --- a/lib/main/auxiliary/piterminal/main.cpp +++ b/utils/piterminal/main.cpp @@ -25,9 +25,9 @@ int main (int argc, char * argv[]) { #else # include "piscreentypes.h" # include "pisharedmemory.h" -# include "../../lib/console/piterminal.cpp" # include "pifile.h" # include +# include "../../lib/console/piterminal.cpp" PIVector > cells; From 7486866c1717785ab4baf450a2c130718d6e7a72 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 1 Aug 2020 22:34:20 +0300 Subject: [PATCH 25/68] CMakeLists.txt fix --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fc58688e..6c9a3aba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,7 +210,6 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) # Main lib -#set(PIP_FOLDERS ".;core;containers;thread;system;io_devices;io_utils;console;math;code;geo;resources;opencl;crypt;introspection;cloud;lua") file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/lib/main/*") list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/lib/main") set(PIP_MAIN_FOLDERS) @@ -407,7 +406,7 @@ if (NOT CROSSTOOLS) pip_find_lib(sodium) if(sodium_FOUND) pip_module(crypt "sodium" "PIP crypt support" "" "") - pip_module(cloud "pip_crypt" "PIP crypt support" "" "") + pip_module(cloud "pip_crypt" "PIP cloud support" "" "") endif() From 2d317a9959262ca66d6d7a58773da15fb819d526 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 1 Aug 2020 22:42:11 +0300 Subject: [PATCH 26/68] missed exports --- lib/main/console/pikbdlistener.h | 8 ++++---- lib/main/console/piscreenconsole.h | 2 +- lib/main/console/piscreentypes.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/main/console/pikbdlistener.h b/lib/main/console/pikbdlistener.h index d1eab548..c1bf9906 100644 --- a/lib/main/console/pikbdlistener.h +++ b/lib/main/console/pikbdlistener.h @@ -77,7 +77,7 @@ public: typedef PIFlags KeyModifiers; //! This struct contains information about pressed keyboard key - struct KeyEvent { + struct PIP_EXPORT KeyEvent { KeyEvent(int k = 0, KeyModifiers m = 0) {key = k; modifiers = m;} //! Pressed key. It can be simple \b char or special key (see PIKbdListener::SpecialKey) @@ -106,7 +106,7 @@ public: typedef PIFlags MouseButtons; //! This struct contains information about mouse action - struct MouseEvent { + struct PIP_EXPORT MouseEvent { MouseEvent(MouseAction a = MouseButtonPress, MouseButtons b = 0, KeyModifiers m = 0) {x = y = 0; action = a; buttons = b; modifiers = m;} //! Event X coordinate in view-space, from 0 @@ -126,7 +126,7 @@ public: }; //! This struct contains information about mouse wheel action - struct WheelEvent: public MouseEvent { + struct PIP_EXPORT WheelEvent: public MouseEvent { WheelEvent(): MouseEvent() {direction = false;} //! Wheel direction, /b true - up, /b fasle - down @@ -207,7 +207,7 @@ private: void end(); #ifndef WINDOWS - struct EscSeq { + struct PIP_EXPORT EscSeq { const char * seq; int key; int mod; diff --git a/lib/main/console/piscreenconsole.h b/lib/main/console/piscreenconsole.h index 7d0582ff..cd45ba73 100644 --- a/lib/main/console/piscreenconsole.h +++ b/lib/main/console/piscreenconsole.h @@ -35,7 +35,7 @@ class PIP_CONSOLE_EXPORT TileVars: public PIScreenTile { public: TileVars(const PIString & n = PIString()); protected: - struct Variable { + struct PIP_CONSOLE_EXPORT Variable { Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = PIScreenTypes::CellFormat(); ptr = 0;} bool isEmpty() const {return (ptr == 0);} PIString name; diff --git a/lib/main/console/piscreentypes.h b/lib/main/console/piscreentypes.h index 2d88cea7..05335ed1 100644 --- a/lib/main/console/piscreentypes.h +++ b/lib/main/console/piscreentypes.h @@ -127,7 +127,7 @@ namespace PIScreenTypes { PIVariant data; }; - class PIScreenBase { + class PIP_CONSOLE_EXPORT PIScreenBase { public: PIScreenBase() {} virtual ~PIScreenBase() {} From 0821742e45848f9db7f0b87e337104fc1db167b6 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 1 Aug 2020 23:18:02 +0300 Subject: [PATCH 27/68] missed exports --- lib/main/core/picollection.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main/core/picollection.h b/lib/main/core/picollection.h index ac8d3017..93e58a6c 100644 --- a/lib/main/core/picollection.h +++ b/lib/main/core/picollection.h @@ -64,13 +64,13 @@ public: static bool addToGroup(const PIString & group, const PIObject * element); - class CollectionAdder { + class PIP_EXPORT CollectionAdder { public: CollectionAdder(const PIString & group, const PIObject * element, const PIString & name = PIString(), bool own = false); }; protected: - struct Group { + struct PIP_EXPORT Group { Group(const PIString & name_ = PIString()) {name = name_;} PIString name; PIVector elements; From edacac54f99e6920ab88c49ed9e338b96f3e47e6 Mon Sep 17 00:00:00 2001 From: Andrey Date: Sat, 1 Aug 2020 23:24:08 +0300 Subject: [PATCH 28/68] PIByteArray rvalue, some fixes --- CMakeLists.txt | 4 +++- lib/main/core/pibytearray.h | 8 ++++++++ utils/piterminal/main.cpp | 2 ++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c9a3aba..470722e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -658,12 +658,14 @@ message(" Modules:") foreach(_m ${PIP_SRC_MODULES}) message(" ${_m}: ${PIP_MSG_${_m}}") endforeach() +message("") if (PIP_TESTS_LIST) - message("") message(" Tests:") foreach(_test ${PIP_TESTS_LIST}) message(" * ${_test}") endforeach() +else() + message(" Tests: skip (tests off)") endif() message("") message(" Utilites:") diff --git a/lib/main/core/pibytearray.h b/lib/main/core/pibytearray.h index 79fdf39b..d3d532b4 100644 --- a/lib/main/core/pibytearray.h +++ b/lib/main/core/pibytearray.h @@ -56,6 +56,10 @@ public: //! Constructs an empty byte array PIByteArray() {;} + PIByteArray(const PIByteArray & o): PIDeque(o) {} + + PIByteArray(PIByteArray && o): PIDeque(std::move(o)) {} + //! Constructs 0-filled byte array with size "size" PIByteArray(const uint size) {resize(size);} @@ -124,6 +128,10 @@ public: void operator =(const PIDeque & d) {resize(d.size()); memcpy(data(), d.data(), d.size());} + PIByteArray & operator =(const PIByteArray & o) {if (this == &o) return *this; clear(); append(o); return *this;} + + PIByteArray & operator =(PIByteArray && o) {swap(o); return *this;} + static PIByteArray fromUserInput(PIString str); static PIByteArray fromHex(PIString str); static PIByteArray fromBase64(const PIByteArray & base64); diff --git a/utils/piterminal/main.cpp b/utils/piterminal/main.cpp index d78f1a8f..eae32a9a 100644 --- a/utils/piterminal/main.cpp +++ b/utils/piterminal/main.cpp @@ -23,6 +23,8 @@ int main (int argc, char * argv[]) { return 0; } #else +# define PIP_CONSOLE_STATIC_DEFINE +# include "pip_console_export.h" # include "piscreentypes.h" # include "pisharedmemory.h" # include "pifile.h" From 01f7b158186abdefa3e950e5a97e81fdd2d7c02a Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 1 Aug 2020 23:27:10 +0300 Subject: [PATCH 29/68] remove " " --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 470722e2..7e08b469 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -665,7 +665,7 @@ if (PIP_TESTS_LIST) message(" * ${_test}") endforeach() else() - message(" Tests: skip (tests off)") + message(" Tests: skip (tests off)") endif() message("") message(" Utilites:") From 1fb5356825f8f123bc1c5679f325816f71c41e37 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 1 Aug 2020 23:34:23 +0300 Subject: [PATCH 30/68] move picompress.h --- lib/main/{math => compress}/picompress.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) rename lib/main/{math => compress}/picompress.h (82%) diff --git a/lib/main/math/picompress.h b/lib/main/compress/picompress.h similarity index 82% rename from lib/main/math/picompress.h rename to lib/main/compress/picompress.h index 799ab072..e0ada4d0 100644 --- a/lib/main/math/picompress.h +++ b/lib/main/compress/picompress.h @@ -23,10 +23,11 @@ #ifndef PICOMPRESS_H #define PICOMPRESS_H +#include "pip_compress_export.h" #include "pibytearray.h" -PIP_EXPORT PIByteArray piCompress(const PIByteArray & ba, int level = 6); +PIP_COMPRESS_EXPORT PIByteArray piCompress(const PIByteArray & ba, int level = 6); -PIP_EXPORT PIByteArray piDecompress(const PIByteArray & zba); +PIP_COMPRESS_EXPORT PIByteArray piDecompress(const PIByteArray & zba); #endif // PICOMPRESS_H From b468a6d5816b93e605c887c3752d807da48d9b61 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 2 Aug 2020 15:57:21 +0300 Subject: [PATCH 31/68] PIMapIterator small PIString optimize general PIChunkStream pack optimization --- lib/main/code/picodeparser.cpp | 163 ++++++++++++++++++++------------- lib/main/containers/pimap.h | 44 +++++++++ lib/main/core/pichunkstream.h | 30 +++++- lib/main/core/pistring.cpp | 20 ++++ lib/main/core/pistring.h | 5 + lib/main/io_devices/pifile.cpp | 2 +- main.cpp | 67 ++++++++++++-- 7 files changed, 253 insertions(+), 78 deletions(-) diff --git a/lib/main/code/picodeparser.cpp b/lib/main/code/picodeparser.cpp index 99c02061..9e7271d0 100644 --- a/lib/main/code/picodeparser.cpp +++ b/lib/main/code/picodeparser.cpp @@ -108,7 +108,7 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) { piForeachC (Enum & c, enums) { piCout << PIStringAscii("enum") << c.name << c.meta; piForeachC (EnumeratorInfo & e, c.members) - piCout << " " << e.name << "=" << e.value << e.meta; + piCout << " " << e.name << '=' << e.value << e.meta; } piCout << "\n\nTypedefs:"; piForeachC (Typedef & c, typedefs) @@ -119,7 +119,7 @@ void PICodeParser::parseFile(const PIString & file, bool follow_includes) { void PICodeParser::parseFiles(const PIStringList & files, bool follow_includes) { clear(); piForeachC (PIString & f, files) - parseFileInternal(f, follow_includes); + parseFileInternal(f, follow_includes); /*piCout << "\n\nDefines:"; piForeachC (Define & m, defines) piCout << PIStringAscii("define") << m.first << m.second; @@ -277,11 +277,11 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { int nl = pfc.size_s(); if (pl == nl) break; pl = nl; - if (pfc.left(9) == "namespace") { + if (pfc.left(9) == PIStringAscii("namespace")) { pfc.cutLeft(pfc.find('{') + 1); continue; } - if (pfc.left(8) == "template") { + if (pfc.left(8) == PIStringAscii("template")) { pfc.cutLeft(8); pfc.takeRange('<', '>'); bool def = !isDeclaration(pfc, 0, &end); @@ -290,11 +290,11 @@ bool PICodeParser::parseFileContent(PIString & fc, bool main) { else pfc.takeSymbol(); continue; } - if (pfc.left(5) == PIStringAscii("class") || pfc.left(6) == "struct" || pfc.left(5) == "union") { + if (pfc.left(5) == PIStringAscii("class") || pfc.left(6) == PIStringAscii("struct") || pfc.left(5) == PIStringAscii("union")) { int dind = pfc.find('{', 0), find = pfc.find(';', 0); if (dind < 0 && find < 0) {pfc.cutLeft(6); continue;} if (dind < 0 || find < dind) {pfc.cutLeft(6); continue;} - ccmn = pfc.left(dind) + "{\n" + pfc.mid(dind).takeRange('{', '}') + "\n}\n"; + ccmn = pfc.left(dind) + PIStringAscii("{\n") + pfc.mid(dind).takeRange('{', '}') + PIStringAscii("\n}\n"); pfc.remove(0, ccmn.size()); parseClass(0, ccmn); continue; @@ -363,7 +363,7 @@ PICodeParser::Entity * PICodeParser::parseClassDeclaration(const PIString & fc) cur_def_vis = (is_class ? Private : Public); PIString cn = cd.mid(6).trim(); bool has_name = !cn.isEmpty(); - if (cn.isEmpty()) cn = "'; + if (cn.isEmpty()) cn = PIStringAscii("'; //piCout << "found " << typename_ << cn; if (cn.isEmpty()) return 0; Entity * e = new Entity(); @@ -393,7 +393,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { int ps = -1; bool def = false; PIString prev_namespace = cur_namespace, stmp; - cur_namespace = ce->name + "::"; + cur_namespace = ce->name + PIStringAscii("::"); //piCout << "parse class" << ce->name << "namespace" << cur_namespace; //piCout << "\nparse class" << ce->name << "namespace" << cur_namespace; while (!fc.isEmpty()) { @@ -425,7 +425,7 @@ PIString PICodeParser::parseClass(Entity * parent, PIString & fc) { } if (cw == PIStringAscii("friend")) {fc.cutLeft(fc.find(';') + 1); continue;} if (cw == PIStringAscii("typedef")) {ce->typedefs << parseTypedef(fc.takeLeft(fc.find(';'))); typedefs << ce->typedefs.back(); typedefs.back().first.insert(0, cur_namespace); if (ce->typedefs.back().first.isEmpty()) ce->typedefs.pop_back(); fc.takeSymbol(); continue;} - if (cw == "template") { + if (cw == PIStringAscii("template")) { fc.takeRange('<', '>'); def = !isDeclaration(fc, 0, &end); fc.cutLeft(end); @@ -453,7 +453,7 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { if (fc.isEmpty()) return ret; PIStringList ml = fc.split(','); piForeachC (PIString & m, ml) { - int i = m.find("="); + int i = m.find('='); if (i < 0) continue; PIString mv = m.mid(i + 1).trim(); if (mv.startsWith('\"')) mv.cutLeft(1); @@ -466,6 +466,8 @@ PICodeParser::MetaMap PICodeParser::parseMeta(PIString & fc) { bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc, const MetaMap & meta) { + static const PIString s_ss = PIStringAscii(" "); + static const PIString s_M = PIStringAscii("$M"); //piCout << PIStringAscii("enum") << name << fc; Enum e(name); e.meta = meta; @@ -474,12 +476,12 @@ bool PICodeParser::parseEnum(Entity * parent, const PIString & name, PIString fc int cv = -1, ind = 0; piForeach (PIString & v, vl) { MetaMap meta; - int mi = v.find(PIStringAscii("$M")); + int mi = v.find(s_M); if (mi >= 0) { meta = tmp_meta.value(v.takeMid(mi, 5)); - v.replaceAll(" ", ' '); + v.replaceAll(s_ss, ' '); } - vn = v; ind = v.find("="); + vn = v; ind = v.find('='); if (ind > 0) {cv = v.right(v.size_s() - ind - 1).toInt(); vn = v.left(ind);} if (ind < 0) ++cv; e.members << EnumeratorInfo(vn.trim(), cv, meta); @@ -512,8 +514,27 @@ PICodeParser::Typedef PICodeParser::parseTypedef(PIString fc) { bool PICodeParser::parseMember(Entity * parent, PIString & fc) { + static const PIString s_operator = PIStringAscii("operator"); + static const PIString s_ss = PIStringAscii(" "); + static const PIString s_cs = PIStringAscii(", "); + static const PIString s_sb = PIStringAscii(" ("); + static const PIString s_sM = PIStringAscii(" $M"); + static const PIString s_M = PIStringAscii("$M"); + static const PIString s_T = PIStringAscii("$T"); + static const PIString s_inline_s = PIStringAscii("inline "); + static const PIString s_static_s = PIStringAscii("static "); + static const PIString s_virtual_s = PIStringAscii("virtual "); + static const PIString s_void = PIStringAscii("void"); + static const PIString s_using = PIStringAscii("using"); + static const PIString s_s5 = PIStringAscii(" "); + static const PIString s_s_const_s = PIStringAscii(" const "); + static const PIString s_s_static_s = PIStringAscii(" static "); + static const PIString s_s_mutable_s = PIStringAscii(" mutable "); + static const PIString s_s_volatile_s = PIStringAscii(" volatile "); + static const PIString s_s_extern_s = PIStringAscii(" extern "); + if (fc.trim().isEmpty()) return true; - if (fc.find("operator") >= 0) return true; + if (fc.find(s_operator) >= 0) return true; tmp_temp.clear(); //piCout << "parse member" << fc; int ts = fc.find('<'), te = 0; @@ -521,22 +542,22 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { while (ts >= 0) { ctemp = fc.mid(ts).takeRange('<', '>'); if (ctemp.isEmpty()) {te = ts + 1; ts = fc.find('<', te); continue;} - crepl = PIStringAscii("$T") + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, '0'); + crepl = s_T + PIString::fromNumber(tmp_temp.size_s()).expandLeftTo(3, '0'); fc.replace(ts, ctemp.size_s() + 2, crepl); tmp_temp[crepl] = '<' + ctemp + '>'; ts = fc.find('<', te); } - fc.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll(" ", ' ').replaceAll(", ", ',').replaceAll(PIStringAscii(" ("), '(').replaceAll(PIStringAscii(" $M"), PIStringAscii("$M")); + fc.replaceAll('\n', ' ').replaceAll('\t', ' ').replaceAll(s_ss, ' ').replaceAll(s_cs, ',').replaceAll(s_sb, '(').replaceAll(s_sM, s_M); //piCout << "parse member" << fc; PIStringList tl, al; Member me; //piCout << fc; if (fc.contains('(')) { MetaMap meta; - int ind = fc.find(PIStringAscii("$M")); + int ind = fc.find(s_M); if (ind >= 0) { meta = tmp_meta.value(fc.takeMid(ind, 5)); - fc.replaceAll(PIStringAscii(" "), ' ').replaceAll(PIStringAscii(" ("), '('); + fc.replaceAll(s_ss, ' ').replaceAll(s_sb, '('); } fc.cutRight(fc.size_s() - fc.findLast(')') - 1); te = fc.find('('); @@ -550,26 +571,26 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { me.arguments_full = fc.takeMid(ts + 2).cutRight(1).split(','); me.type = fc.cutRight(1).trim(); me.visibility = cur_def_vis; - if (me.type.find(PIStringAscii("inline ")) >= 0) { + if (me.type.find(s_inline_s) >= 0) { me.attributes |= Inline; - me.type.removeAll(PIStringAscii("inline ")); + me.type.removeAll(s_inline_s); } - if (me.type.find(PIStringAscii("static ")) >= 0) { + if (me.type.find(s_static_s) >= 0) { me.attributes |= Static; - me.type.removeAll(PIStringAscii("static ")); + me.type.removeAll(s_static_s); } - if (me.type.find(PIStringAscii("virtual ")) >= 0) { + if (me.type.find(s_virtual_s) >= 0) { me.attributes |= Virtual; - me.type.removeAll(PIStringAscii("virtual ")); + me.type.removeAll(s_virtual_s); } normalizeEntityNamespace(me.type); int i = 0; //piCout << me.arguments_full; piForeach (PIString & a, me.arguments_full) - if ((i = a.find("=")) > 0) + if ((i = a.find('=')) > 0) a.cutRight(a.size_s() - i).trim(); for (int j = 0; j < me.arguments_full.size_s(); ++j) - if (me.arguments_full[j] == PIStringAscii("void")) { + if (me.arguments_full[j] == s_void) { me.arguments_full.remove(j); --j; } @@ -590,7 +611,7 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { parent->functions << me; } else { if (fc.endsWith(';')) fc.cutRight(1); - if (fc.startsWith(PIStringAscii("using")) || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; + if (fc.startsWith(s_using) || !(fc.contains(' ') || fc.contains('\t') || fc.contains('\n'))) return true; int bits = extractMemberBits(fc); tl = fc.split(','); //piCout << "member" << fc << tl; @@ -599,8 +620,8 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { bool vn = true; ctemp = tl.front().trim(); PIString meta_t; - if (ctemp.contains(PIStringAscii("$M"))) - meta_t = ctemp.takeMid(ctemp.find(PIStringAscii("$M"))); + if (ctemp.contains(s_M)) + meta_t = ctemp.takeMid(ctemp.find(s_M)); for (ts = ctemp.size_s() - 1; ts > 0; --ts) { if (vn) {if (!_isCChar(ctemp[ts]) && !ctemp[ts].isDigit() && ctemp[ts] != '[' && ctemp[ts] != ']') vn = false;} else {if (_isCChar(ctemp[ts]) || ctemp[ts].isDigit()) break;} @@ -609,26 +630,26 @@ bool PICodeParser::parseMember(Entity * parent, PIString & fc) { me.visibility = cur_def_vis; ctemp += meta_t; restoreTmpTemp(&me); - PIString type = PIStringAscii(" ") + me.type; - if (type.find(PIStringAscii(" const ")) >= 0) { + PIString type = s_s5 + me.type; + if (type.find(s_s_const_s) >= 0) { me.attributes |= Const; - type.replaceAll(PIStringAscii(" const "), ' '); + type.replaceAll(s_s_const_s, ' '); } - if (type.find(PIStringAscii(" static ")) >= 0) { + if (type.find(s_s_static_s) >= 0) { me.attributes |= Static; - type.replaceAll(PIStringAscii(" static "), ' '); + type.replaceAll(s_s_static_s, ' '); } - if (type.find(PIStringAscii(" mutable ")) >= 0) { + if (type.find(s_s_mutable_s) >= 0) { me.attributes |= Mutable; - type.replaceAll(PIStringAscii(" mutable "), ' '); + type.replaceAll(s_s_mutable_s, ' '); } - if (type.find(PIStringAscii(" volatile ")) >= 0) { + if (type.find(s_s_volatile_s) >= 0) { me.attributes |= Volatile; - type.replaceAll(PIStringAscii(" volatile "), ' '); + type.replaceAll(s_s_volatile_s, ' '); } - if (type.find(PIStringAscii(" extern ")) >= 0) { + if (type.find(s_s_extern_s) >= 0) { me.attributes |= Extern; - type.replaceAll(PIStringAscii(" extern "), ' '); + type.replaceAll(s_s_extern_s, ' '); } type.trim(); normalizeEntityNamespace(type); @@ -677,6 +698,14 @@ int PICodeParser::extractMemberBits(PIString & fc) { void PICodeParser::normalizeEntityNamespace(PIString & n) { + static const PIString s_const_s = PIStringAscii("const "); + static const PIString s_static_s = PIStringAscii("static "); + static const PIString s_mutable_s = PIStringAscii("mutable "); + static const PIString s_volatile_s = PIStringAscii("volatile "); + static const PIString s_s_const_s = PIStringAscii(" const "); + static const PIString s_s_static_s = PIStringAscii(" static "); + static const PIString s_s_mutable_s = PIStringAscii(" mutable "); + static const PIString s_s_volatile_s = PIStringAscii(" volatile "); PIString suff, pref; for (int i = n.size_s() - 1; i > 0; --i) if (_isCChar(n[i]) || n[i].isDigit()) { @@ -685,10 +714,10 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { break; } n.push_front(' '); - if (n.find(PIStringAscii(" static ")) >= 0) {n.replaceAll(PIStringAscii(" static "), ""); pref += PIStringAscii("static ");} - if (n.find(PIStringAscii(" const ")) >= 0) {n.replaceAll(PIStringAscii(" const "), ""); pref += PIStringAscii("const ");} - if (n.find(PIStringAscii(" mutable ")) >= 0) {n.replaceAll(PIStringAscii(" mutable "), ""); pref += PIStringAscii("mutable ");} - if (n.find(PIStringAscii(" volatile ")) >= 0) {n.replaceAll(PIStringAscii(" volatile "), ""); pref += PIStringAscii("volatile ");} + if (n.find(s_s_const_s) >= 0) {n.replaceAll(s_s_const_s, ""); pref += s_const_s;} + if (n.find(s_s_static_s) >= 0) {n.replaceAll(s_s_static_s, ""); pref += s_static_s;} + if (n.find(s_s_mutable_s) >= 0) {n.replaceAll(s_s_mutable_s, ""); pref += s_mutable_s;} + if (n.find(s_s_volatile_s) >= 0) {n.replaceAll(s_s_volatile_s, ""); pref += s_volatile_s;} n.trim(); int f = 0; piForeachC (Entity * e, entities) { @@ -697,27 +726,29 @@ void PICodeParser::normalizeEntityNamespace(PIString & n) { return; } if ((f = e->name.find(n)) >= 0) - if (e->name.mid(f - 1, 1) == PIChar(':')) + if (e->name.at(f - 1) == PIChar(':')) if (e->name.find(cur_namespace) >= 0) { n = pref + e->name + suff; return; } } - piForeachC (Enum & e, enums) - if ((f = e.name.find(n)) >= 0) - if (e.name.mid(f - 1, 1) == PIChar(':')) - if (e.name.find(cur_namespace) >= 0) { - //piCout << "change" << n << "to" << e.name + suff; - n = pref + e.name + suff; - return; + piForeachC (Enum & e, enums) { + if ((f = e.name.find(n)) >= 0) + if (e.name.at(f - 1) == PIChar(':')) + if (e.name.find(cur_namespace) >= 0) { + //piCout << "change" << n << "to" << e.name + suff; + n = pref + e.name + suff; + return; + } } - piForeachC (Typedef & e, typedefs) - if ((f = e.first.find(n)) >= 0) - if (e.first.mid(f - 1, 1) == PIChar(':')) - if (e.first.find(cur_namespace) >= 0) { - //piCout << "change" << n << "to" << e.name + suff; - n = pref + e.first + suff; - return; + piForeachC (Typedef & e, typedefs) { + if ((f = e.first.find(n)) >= 0) + if (e.first.at(f - 1) == PIChar(':')) + if (e.first.find(cur_namespace) >= 0) { + //piCout << "change" << n << "to" << e.name + suff; + n = pref + e.first + suff; + return; + } } n = (pref + n + suff).trim(); } @@ -864,9 +895,9 @@ bool PICodeParser::isDeclaration(const PIString & fc, int start, int * end) { bool PICodeParser::isMainFile(const PIString & fc) { int si = 0; while (si >= 0) { - int csi = fc.find(" main", si); - if (csi < 0) csi = fc.find("\tmain", si); - if (csi < 0) csi = fc.find("\nmain", si); + int csi = fc.find(PIStringAscii(" main"), si); + if (csi < 0) csi = fc.find(PIStringAscii("\tmain"), si); + if (csi < 0) csi = fc.find(PIStringAscii("\nmain"), si); if (csi < 0) return false; si = csi; int fi = fc.find('(', si + 5); @@ -874,7 +905,7 @@ bool PICodeParser::isMainFile(const PIString & fc) { if (fi - si < 10) { PIString ms(fc.mid(si, fi - si + 1)); ms.removeAll(' ').removeAll('\t').removeAll('\n'); - if (ms == "main(") return true; + if (ms == PIStringAscii("main(")) return true; } si += 5; } @@ -925,7 +956,7 @@ PIString PICodeParser::procMacros(PIString fc) { } continue; } - if (mif.left(4) == "else" && ifcnt == 0) { + if (mif.left(4) == PIStringAscii("else") && ifcnt == 0) { //piCout << "main else" << skip << grab; if (grab) pfc << procMacros(nfc); if (skip && !cond_ok) {skip = false; grab = true;} @@ -959,7 +990,7 @@ bool PICodeParser::parseDirective(PIString d) { if (d.isEmpty()) return true; PIString dname = d.takeCWord(); //piCout << "parseDirective" << d; - if (dname == "include") { + if (dname == PIStringAscii("include")) { d.replaceAll('<', '\"').replaceAll('>', '\"'); PIString cf = cur_file, ifc = d.takeRange('\"', '\"'); if (with_includes) { @@ -982,7 +1013,7 @@ bool PICodeParser::parseDirective(PIString d) { } return true; } - if (dname == "undef") { + if (dname == PIStringAscii("undef")) { PIString mname = d.takeCWord(); for (int i = 0; i < defines.size_s(); ++i) if (defines[i].first == mname) {defines.remove(i); --i;} diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index 7a5486fe..dd3f02ec 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -67,10 +67,16 @@ void piQuickSort(T * a, ssize_t N) { } } + +template +class PIMapIterator; + + template class PIMap { template friend PIByteArray & operator >>(PIByteArray & s, PIMap & v); template friend PIByteArray & operator <<(PIByteArray & s, const PIMap & v); + template friend class PIMapIterator; public: PIMap() {;} PIMap(const PIMap & other) {*this = other;} @@ -183,6 +189,9 @@ public: const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);} const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);} + PIMapIterator iterate() const {return PIMapIterator(*this);} + PIMapIterator riterate() const {return PIMapIterator(*this, true);} + size_t size() const {return pim_content.size();} int size_s() const {return pim_content.size_s();} size_t length() const {return pim_content.size();} @@ -327,6 +336,41 @@ protected: }; +template +class PIMapIterator { + typedef PIMap MapType; +public: + PIMapIterator(const PIMap & map, bool reverse = false): m(map), pos(-1), rev(reverse) { + if (rev) pos = m.size_s(); + } + const Key & key() const {return const_cast(m)._key(pos);} + const T & value() const {return const_cast(m)._value(pos);} + T & valueRef() const {return const_cast(m)._value(pos);} + inline bool hasNext() const { + if (rev) { + return pos > 0; + } else { + return pos < (m.size_s() - 1); + } + return false; + } + inline bool next() { + if (rev) { + --pos; + return pos >= 0; + } else { + ++pos; + return pos < m.size_s(); + } + return false; + } +private: + const MapType & m; + ssize_t pos; + bool rev; +}; + + #ifdef PIP_STD_IOSTREAM template inline std::ostream & operator <<(std::ostream & s, const PIMap & v) { diff --git a/lib/main/core/pichunkstream.h b/lib/main/core/pichunkstream.h index ef4f9e25..4dec6789 100644 --- a/lib/main/core/pichunkstream.h +++ b/lib/main/core/pichunkstream.h @@ -54,12 +54,18 @@ public: int id; T data; }; + template + struct ChunkConst { + ChunkConst(int i, const T & d): id(i), data(d) {} + int id; + const T & data; + }; //! Returns chunk with ID "id" and value "data" for write to stream - template static Chunk chunk(int id, const T & data) {return Chunk(id, data);} + template static ChunkConst chunk(int id, const T & data) {return ChunkConst(id, data);} //! Add data to this chunk strean with ID "id" and value "data" - template PIChunkStream & add(int id, const T & data) {*this << Chunk(id, data); return *this;} + template PIChunkStream & add(int id, const T & data) {*this << ChunkConst(id, data); return *this;} void setSource(const PIByteArray & data); void setSource(PIByteArray * data); @@ -112,6 +118,7 @@ private: PIMap data_map; template friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk & c); + template friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst & c); }; template @@ -133,5 +140,24 @@ PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk & c } return s; } +template +PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst & c) { + PIByteArray ba; + ba << c.data; + switch (s.version_) { + case PIChunkStream::Version_1: + (*(s.data_)) << c.id << ba; + break; + case PIChunkStream::Version_2: + if (s.data_->isEmpty()) + (*(s.data_)) << uchar(uchar(s.version_) | 0x80); + PIChunkStream::writeVInt(*(s.data_), c.id); + PIChunkStream::writeVInt(*(s.data_), ba.size()); + s.data_->append(ba); + break; + default: break; + } + return s; +} #endif // PICHUNKSTREAM_H diff --git a/lib/main/core/pistring.cpp b/lib/main/core/pistring.cpp index 508fd126..f2f454e8 100644 --- a/lib/main/core/pistring.cpp +++ b/lib/main/core/pistring.cpp @@ -658,6 +658,26 @@ PIString & PIString::replaceAll(const PIString & what, const PIString & with) { } +PIString & PIString::replaceAll(const PIString & what, const char with) { + if (what.isEmpty()) return *this; + int l = what.length(), dl = what.length() - 1; + for (int i = 0; i < length() - l + 1; ++i) { + bool match = true; + for (int j = 0; j < l; ++j) { + if (at(j + i) != what[j]) { + match = false; + break; + } + } + if (!match) continue; + if (dl > 0) PIDeque::remove(i, dl); + at(i) = PIChar(with); + //i -= l; + } + return *this; +} + + PIString & PIString::replaceAll(const char what, const char with) { int l = length(); for (int i = 0; i < l; ++i) { diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index e73d73bf..9268f759 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -283,6 +283,11 @@ public: * \sa \a replace(), \a replaced() */ PIString & replaceAll(const PIString & what, const PIString & with); + /*! \brief Replace all founded substrings "what" with symbol "with" and return this string + * \details Example: \snippet pistring.cpp PIString::replaceAll + * \sa \a replace(), \a replaced() */ + PIString & replaceAll(const PIString & what, const char with); + /*! \brief Replace all founded symbols "what" with symbol "with" and return this string * \details Example: \snippet pistring.cpp PIString::replaceAll * \sa \a replace(), \a replaced() */ diff --git a/lib/main/io_devices/pifile.cpp b/lib/main/io_devices/pifile.cpp index 065cc635..8984253b 100644 --- a/lib/main/io_devices/pifile.cpp +++ b/lib/main/io_devices/pifile.cpp @@ -235,7 +235,7 @@ PIByteArray PIFile::readAll(bool forceRead) { llong s = size(); if (s < 0) return a; a.resize(s); - s = readAll(a.data()); + fread(a.data(), 1, s, PRIVATE->fd); seek(cp); if (s >= 0) a.resize(s); return a; diff --git a/main.cpp b/main.cpp index 5a9484ff..77733e97 100644 --- a/main.cpp +++ b/main.cpp @@ -34,32 +34,81 @@ int main() { class db { public: db() { + name = PIStringAscii("sflner;ljner.vjnrevsg;j35m4;gberjg2mnv"); for (int i=0; i<10000; ++i) x << sin(double(i)/180.0); //printf("jkfkhg\n"); } -private: + PIString name; PIVector x; }; +inline PIByteArray & operator <<(PIByteArray & ba, const db & v) { + PIChunkStream cs; + cs.add(1, v.name).add(2, v.x); + ba << cs.data(); + return ba; +} +inline PIByteArray & operator >>(PIByteArray & ba, db & v) { + PIByteArray src; ba >> src; PIChunkStream cs(src); + while (!cs.atEnd()) { + switch (cs.read()) { + case 1: cs.get(v.name); break; + case 2: cs.get(v.x); break; + } + } + return ba; +} + +PIEthernet eth; + #include "picodeparser.h" int main() { - /*PIString s(" 324 654 sf 5fdwg sdfsdf sdfefg"); - piCout << s; - piCout << s.replaceAll(' ', '1');*/ - piDebug = false; + //PICodeParser cp; + //cp.parseFile("SH_plugin_base.h"); + + PIMap m; + m[1] = "one"; + m[2] = "two"; + + auto it = m.riterate(); + while (it.next()) { + //it.next(); + it.valueRef() << "_!"; + piCout << it.key() << it.value(); + } + + /*eth.__meta_data + piForeachC (auto & i, cp.enums) { + i. + }*/ + + /*piDebug = false; double min = -1, max = -1, mean = 0; - for (int i = 0; i < 1; ++i) { - PICodeParser cp; + const int iterations = 50; + db d, d2; + for (int i = 0; i < iterations; ++i) { + //PICodeParser cp; PITimeMeasurer tm; - cp.parseFile("SH_plugin_base.h"); + for (int j = 0; j < 100; ++j) { + PIByteArray ba; + ba << d; + } + //cp.parseFile("SH_plugin_base.h"); double ms = tm.elapsed_m(); if (min < 0) min = ms; if (max < 0) max = ms; min = piMin(min, ms); max = piMax(max, ms); mean += ms; + + PIByteArray ba; + ba << d; + d2.name.clear(); + d2.x.clear(); + ba >> d2; } piDebug = true; - piCout << min << (mean / 50) << max; + piCout << d2.name << d2.x.size_s(); + piCout << min << (mean / iterations) << max;*/ } From df457a16023ec508dd44d313581bfbafb401b32d Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sun, 2 Aug 2020 19:18:28 +0300 Subject: [PATCH 32/68] rename "iterate" --- lib/main/containers/pimap.h | 4 ++-- main.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index dd3f02ec..47f0d3b7 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -189,8 +189,8 @@ public: const_reverse_iterator constRbegin() const {return const_reverse_iterator(this, size() - 1);} const_reverse_iterator constRend() const {return const_reverse_iterator(this, -1);} - PIMapIterator iterate() const {return PIMapIterator(*this);} - PIMapIterator riterate() const {return PIMapIterator(*this, true);} + PIMapIterator makeIterator() const {return PIMapIterator(*this);} + PIMapIterator makeReverseIterator() const {return PIMapIterator(*this, true);} size_t size() const {return pim_content.size();} int size_s() const {return pim_content.size_s();} diff --git a/main.cpp b/main.cpp index 77733e97..621a56e3 100644 --- a/main.cpp +++ b/main.cpp @@ -71,7 +71,7 @@ int main() { m[1] = "one"; m[2] = "two"; - auto it = m.riterate(); + auto it = m.makeIterator(); while (it.next()) { //it.next(); it.valueRef() << "_!"; From 427e7411c18fa9521c4e70273d5400508e90c464 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Mon, 3 Aug 2020 01:43:23 +0300 Subject: [PATCH 33/68] move most old PIMap iterators to new Documentation of PIVector, PIMap and PIMapIterator --- lib/main/containers/picontainers.cpp | 276 +++++++++++++++--- .../piintrospection_server_p.cpp | 7 +- lib/main/io_utils/piconnection.cpp | 25 +- lib/main/resources/piresources.cpp | 9 +- lib/main/resources/piresourcesstorage.cpp | 14 +- lib/main/system/pisystemmonitor.cpp | 5 +- utils/code_model_generator/main.cpp | 9 +- utils/deploy_tool/main.cpp | 5 +- 8 files changed, 280 insertions(+), 70 deletions(-) diff --git a/lib/main/containers/picontainers.cpp b/lib/main/containers/picontainers.cpp index d4a356c8..43d1ffde 100644 --- a/lib/main/containers/picontainers.cpp +++ b/lib/main/containers/picontainers.cpp @@ -28,147 +28,347 @@ * \fn PIVector::PIVector(); * Contructs an empty vector - * \fn PIVector::PIVector(ullong size, const Type & value = Type()); + * \fn PIVector::PIVector(size_t size, const T & value = T()); * \brief Contructs vector with size "size" filled elements "value" * \details Example: \snippet picontainers.cpp PIVector::PIVector - * \fn const Type & PIVector::at(ullong index) const; + * \fn const T & PIVector::at(size_t index) const; * \brief Read-only access to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::at_c * \sa \a operator[] - * \fn Type & PIVector::at(ullong index); + * \fn T & PIVector::at(size_t index); * \brief Full access to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::at * \sa \a operator[] - * \fn const Type * PIVector::data(ullong index = 0) const; + * \fn const T * PIVector::data(size_t index = 0) const; * \brief Read-only pointer to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::data_c - * \fn Type * PIVector::data(ullong index = 0); + * \fn T * PIVector::data(size_t index = 0); * \brief Pointer to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::data - * \fn ullong PIVector::size() const; + * \fn size_t PIVector::size() const; * \brief Elements count - * \fn int PIVector::size_s() const; + * \fn ssize_t PIVector::size_s() const; * \brief Elements count * \fn bool PIVector::isEmpty() const; * \brief Return \c "true" if vector is empty, i.e. size = 0 - * \fn bool PIVector::has(const Type & t) const; + * \fn bool PIVector::has(const T & t) const; - * \fn bool PIVector::contains(const Type & v) const; + * \fn bool PIVector::contains(const T & v) const; * \brief Return \c "true" if vector has at least one element equal "t" - * \fn int PIVector::etries(const Type & t) const; + * \fn int PIVector::etries(const T & t) const; * \brief Return how many times element "t" appears in vector - * \fn static int PIVector::compare_func(const Type * t0, const Type * t1); - * \brief Standard compare function for type "Type". Return 0 if t0 = t1, -1 if t0 < t1 and 1 if t0 > t1. + * \fn ssize_t PIVector::indexOf(const T & t) const; + * \brief Return index of first element equal "t" or -1 if there is no such element - * \fn void PIVector::resize(ullong size, const Type & new_type = Type()); + * \fn ssize_t PIVector::lastIndexOf(const T & t) const; + * \brief Return index of last element equal "t" or -1 if there is no such element + + * \fn static int PIVector::compare_func(const T * t0, const T * t1); + * \brief Standard compare function for type "T". Return 0 if t0 = t1, -1 if t0 < t1 and 1 if t0 > t1. + + * \fn void PIVector::resize(size_t size, const T & new_type = T()); * \brief Resize vector to size "size" * \details Elements removed from end of vector if new size < old size, or added new elements = "new_type" if new size > old size.\n * Example: \snippet picontainers.cpp PIVector::resize * \sa \a size(), \a clear() - * \fn PIVector & PIVector::enlarge(ullong size); + * \fn PIVector & PIVector::enlarge(size_t size); * \brief Increase vector size with "size" elements * \fn void PIVector::clear(); * \brief Clear vector. Equivalent to call "resize(0)" - * \fn PIVector & PIVector::sort(CompareFunc compare = compare_func); + * \fn PIVector & PIVector::sort(CompareFunc compare = compare_func); * \brief Sort vector using quick sort algorithm and standard compare function * \details Example: \snippet picontainers.cpp PIVector::sort_0 * With custom compare function: \snippet picontainers.cpp PIVector::sort_1 - * \fn PIVector & PIVector::fill(const Type & t); + * \fn PIVector & PIVector::fill(const T & t); * \brief Fill vector with elements "t" leave size is unchanged and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::fill - * \fn Type & PIVector::back(); + * \fn PIVector & PIVector::assign(const T & t = T()); + * \brief Synonym of \a fill(t) + + * \fn PIVector & PIVector::assign(size_t new_size, const T & t); + * \brief Resize to "new_size", then fill with "t" + + * \fn T & PIVector::back(); * \brief Last element of the vector - * \fn const Type & PIVector::back() const; + * \fn const T & PIVector::back() const; * \brief Last element of the vector - * \fn Type & PIVector::front(); + * \fn T & PIVector::front(); * \brief First element of the vector - * \fn const Type & PIVector::front() const; + * \fn const T & PIVector::front() const; * \brief First element of the vector - * \fn PIVector & PIVector::push_back(const Type & t); + * \fn PIVector & PIVector::push_back(const T & t); * \brief Add new element "t" at the end of vector and return reference to vector - * \fn PIVector & PIVector::push_front(const Type & t); + * \fn PIVector & PIVector::push_front(const T & t); * \brief Add new element "t" at the beginning of vector and return reference to vector - * \fn PIVector & PIVector::pop_back(); + * \fn PIVector & PIVector::pop_back(); * \brief Remove one element from the end of vector and return reference to vector - * \fn PIVector & PIVector::pop_front(); + * \fn PIVector & PIVector::pop_front(); * \brief Remove one element from the beginning of vector and return reference to vector - * \fn Type PIVector::take_back(); + * \fn T PIVector::take_back(); * \brief Remove one element from the end of vector and return it - * \fn Type PIVector::take_front(); + * \fn T PIVector::take_front(); * \brief Remove one element from the beginning of vector and return it - * \fn PIVector & PIVector::remove(uint index); + * \fn PIVector & PIVector::remove(size_t index); * \brief Remove one element by index "index" and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::remove_0 * \sa \a removeOne(), \a removeAll() - * \fn PIVector & PIVector::remove(uint index, uint count); + * \fn PIVector & PIVector::remove(size_t index, size_t count); * \brief Remove "count" elements by first index "index" and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::remove_1 * \sa \a removeOne(), \a removeAll() - * \fn PIVector & PIVector::removeOne(const Type & v); + * \fn PIVector & PIVector::removeOne(const T & v); * \brief Remove no more than one element equal "v" and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::removeOne * \sa \a remove(), \a removeAll() - * \fn PIVector & PIVector::removeAll(const Type & v); + * \fn PIVector & PIVector::removeAll(const T & v); * \brief Remove all elements equal "v" and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::removeAll * \sa \a remove(), \a removeOne() - * \fn PIVector & PIVector::insert(uint pos, const Type & t); + * \fn PIVector & PIVector::insert(size_t pos, const T & t); * \brief Insert element "t" after index "pos" and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::insert_0 - * \fn PIVector & PIVector::insert(uint pos, const PIVector & t); + * \fn PIVector & PIVector::insert(size_t pos, const PIVector & t); * \brief Insert other vector "t" after index "pos" and return reference to vector * \details Example: \snippet picontainers.cpp PIVector::insert_1 - * \fn Type & PIVector::operator [](uint index); + * \fn T & PIVector::operator [](size_t index); * \brief Full access to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::() * \sa \a at() - * \fn const Type & PIVector::operator [](uint index) const; + * \fn const T & PIVector::operator [](size_t index) const; * \brief Read-only access to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::()_c * \sa \a at() - * \fn PIVector & PIVector::operator <<(const Type & t); + * \fn PIVector & PIVector::operator <<(const T & t); * \brief Add new element "t" at the end of vector and return reference to vector - * \fn PIVector & PIVector::operator <<(const PIVector & t); + * \fn PIVector & PIVector::operator <<(const PIVector & t); * \brief Add vector "t" at the end of vector and return reference to vector - * \fn bool PIVector::operator ==(const PIVector & t); + * \fn bool PIVector::operator ==(const PIVector & t); * \brief Compare with vector "t" - * \fn bool PIVector::operator !=(const PIVector & t); + * \fn bool PIVector::operator !=(const PIVector & t); * \brief Compare with vector "t" * */ + + + + +/** \class PIMap + * \brief Associative array + * \details This class used to store Key = Value array of any + * type of data. \a value() returns value for key and leave map + * unchaged in any case. \a operator [] create entry in map if + * there is no entry for given key. You can retrieve all + * keys by method \a keys() and all values by methos \a values(). + * To iterate all entries use class PIMapIterator, or methods + * \a makeIterator() and \a makeReverseIterator(). + + * \fn PIMap::PIMap(); + * \brief Contructs an empty map + + * \fn PIMap::PIMap(const PIMap & other); + * \brief Contructs a copy of "other" + + * \fn PIMap & PIMap::operator =(const PIMap & other); + * \brief Copy operator + + * \fn PIMap::PIMap(const PIMap & other); + * \brief Contructs a copy of "other" + +* \fn PIMapIterator PIMap::makeIterator() const +* \brief Returns PIMapIterator for this map + +* \fn PIMapIterator PIMap::makeReverseIterator() const +* \brief Returns reverse PIMapIterator for this map + + +* \fn size_t PIMap::size() const +* \brief Returns entries count + +* \fn int PIMap::size_s() const +* \brief Returns entries count + +* \fn size_t PIMap::length() const +* \brief Returns entries count + +* \fn bool PIMap::isEmpty() const +* \brief Returns if map is empty + + +* \fn T & PIMap::operator [](const Key & key) +* \brief Returns value for key "key". If there is no key in map, create one. + +* \fn const T PIMap::operator [](const Key & key) const +* \brief Returns value for key "key". If there is no key in map, returns default T(). + +* \fn T & PIMap::at(const Key & key) +* \brief Equivalent to operator [] + +* \fn const T PIMap::at(const Key & key) const +* \brief Equivalent to operator [] + + +* \fn PIMap & PIMap::operator <<(const PIMap & other) +* \brief Insert all etries of "other" to this map. Override existing values. + +* \fn bool PIMap::operator ==(const PIMap & t) const +* \brief Compare operator + +* \fn bool PIMap::operator !=(const PIMap & t) const +* \brief Compare operator + +* \fn bool PIMap::contains(const Key & key) const +* \brief Returns "true" if map contains entry with key "key" + + +* \fn PIMap & PIMap::reserve(size_t new_size) +* \brief Reserve space for "new_size" entries + +* \fn PIMap & PIMap::removeOne(const Key & key) +* \brief Remove entry with key "key" + +* \fn PIMap & PIMap::remove(const Key & key) +* \brief Equivalent \a removeOne(key) + +* \fn PIMap & PIMap::erase(const Key & key) +* \brief Equivalent \a removeOne(key) + +* \fn PIMap & PIMap::clear() +* \brief Clear map + + +* \fn void PIMap::swap(PIMap & other) +* \brief Swap map with "other" + + +* \fn PIMap & PIMap::insert(const Key & key, const T & value) +* \brief Insert or rewrite entry with key "key" and value "value" + +* \fn const T PIMap::value(const Key & key, const T & default = T()) +* \brief Returns value for key "key". If there is no key in map, returns "default". + +* \fn PIVector PIMap::values() const +* \brief Returns all values as PIVector + +* \fn Key PIMap::key(const T & value, const Key & default = Key()) const +* \brief Returns key for first founded value "value". If there is no such value in map, returns "default". + +* \fn PIVector PIMap::keys() const +* \brief Returns all keys as PIVector + + * */ + + + + +/** \class PIMapIterator + * \brief Helper class to iterate over PIMap + * \details This class used to access keys and values in PIMap. + * You can use constructor to create iterator, or use \a PIMap::makeIterator() + * and \a PIMap::makeReverseIterator() methods. + * + * First usage variant: + * \code + * PIMap m; + * m[1] = "one"; + * m[2] = "two"; + * m[4] = "four"; + * + * PIMapIterator it(m); + * while (it.next()) { + * piCout << it.key() << it.value(); + * } + * // 1 one + * // 2 two + * // 4 four + * \endcode + * + * Using hasNext(): + * \code + * while (it.hasNext()) { + * it.next(); + * \endcode + * + * Using map method: + * \code + * auto it = m.makeIterator(); + * \endcode + * + * Write access: + * \code + * while (it.next()) { + * it.valueRef().append("_!"); + * piCout << it.key() << it.value(); + * } + * + * // 1 one_! + * // 2 two_! + * // 4 four_! + * \endcode + * + * Reverse iterator: + * \code + * auto it = m.makeReverseIterator(); + * while (it.next()) { + * piCout << it.key() << it.value(); + * } + * + * // 4 four + * // 2 two + * // 1 one + * \endcode + +* \fn PIMapIterator(const PIMap & map, bool reverse = false) +* \brief Contructs iterator for "map". Current position is invalid. + +* \fn const Key & PIMapIterator::key() const +* \brief Returns current entry key + +* \fn const T & PIMapIterator::value() const +* \brief Returns current entry value + +* \fn T & PIMapIterator::valueRef() const +* \brief Returns reference to current entry value + +* \fn bool PIMapIterator::hasNext() +* \brief Returns if iterator can jump to next entry + +* \fn bool PIMapIterator::next() +* \brief Jump to next entry and return if new position is valid. + + * */ diff --git a/lib/main/introspection/piintrospection_server_p.cpp b/lib/main/introspection/piintrospection_server_p.cpp index e5935f10..f0aee35c 100644 --- a/lib/main/introspection/piintrospection_server_p.cpp +++ b/lib/main/introspection/piintrospection_server_p.cpp @@ -214,9 +214,10 @@ PIByteArray PIIntrospection::packThreads() { if (p) { p->mutex.lock(); PIMap & tm(p->threads); - for (PIMap::iterator i = tm.begin(); i != tm.end(); ++i) { - i.value().classname = PIStringAscii(i.key()->className()); - i.value().name = i.key()->name(); + auto it = tm.makeIterator(); + while (it.next()) { + it.valueRef().classname = PIStringAscii(it.key()->className()); + it.valueRef().name = it.key()->name(); } ret << tm.values(); p->mutex.unlock(); diff --git a/lib/main/io_utils/piconnection.cpp b/lib/main/io_utils/piconnection.cpp index 785c5ebf..c82d8c7c 100644 --- a/lib/main/io_utils/piconnection.cpp +++ b/lib/main/io_utils/piconnection.cpp @@ -388,8 +388,9 @@ bool PIConnection::removeDevice(const PIString & full_path) { } bounded_extractors.remove(dev); channels_.remove(dev); - for (auto it = channels_.begin(); it != channels_.end(); it++) - it.value().removeAll(dev); + auto it = channels_.makeIterator(); + while (it.next()) + it.valueRef().removeAll(dev); __device_pool__->lock(); if (diags_.value(dev, 0) != 0) delete diags_.value(dev); @@ -411,8 +412,9 @@ void PIConnection::removeAllDevices() { s.value()->unlock(); } channels_.remove(d); - for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) - it.value().removeAll(d); + auto it = channels_.makeIterator(); + while (it.next()) + it.valueRef().removeAll(d); if (diags_.value(d, 0) != 0) delete diags_.value(d); diags_.remove(d); @@ -566,8 +568,9 @@ void PIConnection::removeAllFilters() { for (auto i = extractors.constBegin(); i != extractors.constEnd(); i++) { if (i.value() == 0) continue; channels_.remove(i.value()->extractor); - for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) - it.value().removeAll(i.value()->extractor); + auto it = channels_.makeIterator(); + while (it.next()) + it.valueRef().removeAll(i.value()->extractor); if (diags_.value(i.value()->extractor, 0) != 0) delete diags_.value(i.value()->extractor); diags_.remove(i.value()->extractor); @@ -658,8 +661,9 @@ bool PIConnection::removeChannel(const PIString & name0) { if (pe0 != 0) dev0 = pe0; if (dev0 == 0) return false; channels_.remove(dev0); - for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) - it.value().removeAll(dev0); + auto it = channels_.makeIterator(); + while (it.next()) + it.valueRef().removeAll(dev0); return true; } @@ -1240,8 +1244,9 @@ void PIConnection::Sender::tick(void * , int) { void PIConnection::unboundExtractor(PIPacketExtractor * pe) { if (pe == 0) return; channels_.remove(pe); - for (PIMap >::iterator it = channels_.begin(); it != channels_.end(); ++it) - it.value().removeAll(pe); + auto it = channels_.makeIterator(); + while (it.next()) + it.valueRef().removeAll(pe); bounded_extractors.remove(pe); PIVector k = bounded_extractors.keys(); piForeach (PIIODevice * i, k) { diff --git a/lib/main/resources/piresources.cpp b/lib/main/resources/piresources.cpp index e3a691d6..035d4d8f 100644 --- a/lib/main/resources/piresources.cpp +++ b/lib/main/resources/piresources.cpp @@ -36,13 +36,12 @@ PIByteArray PIResources::get(const PIString & name) { void PIResources::dump() { - PIMap & sm(PIResourcesStorage::instance()->sections); - PIMap::iterator si; - for (si = sm.begin(); si != sm.end(); ++si) { + auto si = PIResourcesStorage::instance()->sections.makeIterator(); + while (si.next()) { piCout << "Section [" << si.key() << "]"; if (!si.value()) continue; - PIMap::iterator fi; - for (fi = si.value()->entries.begin(); fi != si.value()->entries.end(); ++fi) { + auto fi = si.value()->entries.makeIterator(); + while (fi.next()) { PIString s = fi.key() + ": "; s << (fi.value() ? fi.value()->size_s() : 0) << " b"; piCout << " " << s; diff --git a/lib/main/resources/piresourcesstorage.cpp b/lib/main/resources/piresourcesstorage.cpp index b08dba70..fd6e20eb 100644 --- a/lib/main/resources/piresourcesstorage.cpp +++ b/lib/main/resources/piresourcesstorage.cpp @@ -31,8 +31,8 @@ PIResourcesStorage::Section::~Section() { void PIResourcesStorage::Section::add(const PIResourcesStorage::Section & s) { - PIMap::const_iterator i; - for (i = s.entries.begin(); i != s.entries.end(); ++i) { + auto i = s.entries.makeIterator(); + while (i.next()) { if (!i.value()) continue; if (entries.value(i.key(), 0)) continue; entries[i.key()] = i.value(); @@ -83,10 +83,10 @@ void PIResourcesStorage::registerSection(const uchar * rc_data, const uchar * rc piForeachC (PIResourcesStorage::__RCEntry & e, el) { ebs[e.section] << e; } - PIMap >::iterator it; - for (it = ebs.begin(); it != ebs.end(); ++it) { + auto it = ebs.makeIterator(); + while (it.next()) { PIResourcesStorage::Section s; - PIVector & itv(it.value()); + const PIVector & itv(it.value()); piForeachC (PIResourcesStorage::__RCEntry & e, itv) { //piCout << "add" << e.name << e.alias << PIString::readableSize(e.size); PIByteArray * eba = new PIByteArray(&(rc_data[e.offset]), e.size); @@ -114,8 +114,8 @@ PIByteArray PIResourcesStorage::get(const PIString & section_name, const PIStrin PIByteArray PIResourcesStorage::get(const PIString & entry_name) const { - PIMap::const_iterator i; - for (i = sections.begin(); i != sections.end(); ++i) { + auto i = sections.makeIterator(); + while (i.next()) { if (!i.value()) continue; PIByteArray * ba = i.value()->entries.value(entry_name, 0); if (!ba) continue; diff --git a/lib/main/system/pisystemmonitor.cpp b/lib/main/system/pisystemmonitor.cpp index 6b28f9b1..98e259a6 100644 --- a/lib/main/system/pisystemmonitor.cpp +++ b/lib/main/system/pisystemmonitor.cpp @@ -331,9 +331,10 @@ void PISystemMonitor::run() { tstat.cpu_load_system = piClampf(tstat.cpu_load_system, 0.f, 100.f); tstat.cpu_load_user = piClampf(tstat.cpu_load_user , 0.f, 100.f); - for (PIMap::iterator i = cur_tm.begin(); i != cur_tm.end(); ++i) { + auto i = cur_tm.makeIterator(); + while (i.next()) { if (!last_tm.contains(i.key())) continue; - ThreadStats & ts_new(i.value()); + ThreadStats & ts_new(i.valueRef()); ThreadStats & ts_old(last_tm[i.key()]); ts_new.cpu_load_kernel = calcThreadUsage(ts_new.kernel_time, ts_old.kernel_time); ts_new.cpu_load_user = calcThreadUsage(ts_new.user_time, ts_old.user_time); diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index cb42eaac..b207d679 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -87,7 +87,8 @@ void makeClassInfo(PIFile & f, const PICodeParser::Entity * e) { f << "\tci->name = \"" << e->name << "\";\n"; f << "\tci->has_name = " << (e->has_name ? "true" : "false") << ";\n"; if (!e->meta.isEmpty()) { - for (PICodeParser::MetaMap::const_iterator i = e->meta.begin(); i != e->meta.end(); ++i) + auto i = e->meta.makeIterator(); + while (i.next()) f << "\tci->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } f << "\t(*classesInfo)[ci->name] = ci;\n"; @@ -176,14 +177,16 @@ void makeEnumInfo(PIFile & f, const PICodeParser::Enum * e) { f << "\t(*enumsInfo)[\"" << e->name << "\"] = ei;\n"; f << "\tei->name = \"" << e->name << "\";\n"; if (!e->meta.isEmpty()) { - for (PICodeParser::MetaMap::const_iterator i = e->meta.begin(); i != e->meta.end(); ++i) + auto i = e->meta.makeIterator(); + while (i.next()) f << "\tei->meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } } piForeachC (PICodeParser::EnumeratorInfo & m, e->members) { f << "\tei->members << PICodeInfo::EnumeratorInfo(\"" << m.name << "\", " << m.value << ");\n"; if (!m.meta.isEmpty()) { - for (PICodeParser::MetaMap::const_iterator i = m.meta.begin(); i != m.meta.end(); ++i) + auto i = m.meta.makeIterator(); + while (i.next()) f << "\tei->members.back().meta[\"" << i.key() << "\"] = PIString::fromUTF8(\"" << i.value() << "\");\n"; } } diff --git a/utils/deploy_tool/main.cpp b/utils/deploy_tool/main.cpp index 46badca3..45455398 100644 --- a/utils/deploy_tool/main.cpp +++ b/utils/deploy_tool/main.cpp @@ -583,8 +583,9 @@ int main(int argc, char * argv[]) { qt_filters["platforms"] = platforms; qt_filters["styles" ] = styles ; - for (PIMap::iterator it = qt_filters.begin(); it != qt_filters.end(); ++it) - it.value().forEachInplace([](PIString i)->PIString{ + auto it = qt_filters.makeIterator(); + while (it.next()) + it.valueRef().forEachInplace([](PIString i)->PIString{ if (!i.startsWith("*")) i.prepend("*"); if (!i.endsWith("*")) i.append("*"); return i; From e8a066abcd218b1cdfb37edb75d7b4ffc4542b14 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Mon, 3 Aug 2020 09:04:50 +0300 Subject: [PATCH 34/68] doc --- lib/main/containers/picontainers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/main/containers/picontainers.cpp b/lib/main/containers/picontainers.cpp index 43d1ffde..41ba1fb2 100644 --- a/lib/main/containers/picontainers.cpp +++ b/lib/main/containers/picontainers.cpp @@ -309,7 +309,7 @@ * m[2] = "two"; * m[4] = "four"; * - * PIMapIterator it(m); + * auto it = m.makeIterator(); * while (it.next()) { * piCout << it.key() << it.value(); * } @@ -324,9 +324,9 @@ * it.next(); * \endcode * - * Using map method: + * Using constructor: * \code - * auto it = m.makeIterator(); + * PIMapIterator it(m); * \endcode * * Write access: From 22208fbf513ef434ff69805ba637669d0adb6b35 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Mon, 3 Aug 2020 11:10:05 +0300 Subject: [PATCH 35/68] tests binary dir fix --- CMakeLists.txt | 1 + tests/CMakeLists.txt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e08b469..87748bab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,6 +224,7 @@ if (DEFINED LIBPROJECT) endif() if (TESTS) + set(PIP_ROOT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") add_subdirectory(tests) endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7f52c1a6..befc771e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -4,10 +4,13 @@ macro(pip_test NAME LIBS) file(GLOB _CPPS "${NAME}/*.cpp") file(GLOB _HDRS "${NAME}/*.h") set(_target pip_${NAME}_test) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PIP_ROOT_BINARY_DIR}") + message("${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") add_executable(${_target} ${_CPPS} ${_HDRS}) target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main) add_test(NAME ${_target} COMMAND tests) add_custom_target(${_target}_perform ALL COMMAND ${_target}) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY) list(APPEND PIP_TESTS_LIST "${NAME}") set(PIP_TESTS_LIST ${PIP_TESTS_LIST} PARENT_SCOPE) endmacro() From 9cd108cf20276d04e6ef4522afc4e5f2e5f9a2bb Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Mon, 3 Aug 2020 11:10:27 +0300 Subject: [PATCH 36/68] tests binary dir fix --- tests/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index befc771e..71177e1d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,7 +5,6 @@ macro(pip_test NAME LIBS) file(GLOB _HDRS "${NAME}/*.h") set(_target pip_${NAME}_test) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PIP_ROOT_BINARY_DIR}") - message("${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") add_executable(${_target} ${_CPPS} ${_HDRS}) target_link_libraries(${_target} pip ${LIBS} gtest_main gmock_main) add_test(NAME ${_target} COMMAND tests) From 70a7363f7621d78b1a970d0c53493cc32a6f3cfa Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 5 Aug 2020 00:53:27 +0300 Subject: [PATCH 37/68] some features in main.cpp fastest Variant implementation --- lib/main/containers/picontainers.cpp | 3 + lib/main/containers/pimap.h | 7 + lib/main/core/pibase.h | 2 +- lib/main/core/pistring.h | 10 + main.cpp | 337 +++++++++++++++++++-------- 5 files changed, 262 insertions(+), 97 deletions(-) diff --git a/lib/main/containers/picontainers.cpp b/lib/main/containers/picontainers.cpp index 41ba1fb2..a6533554 100644 --- a/lib/main/containers/picontainers.cpp +++ b/lib/main/containers/picontainers.cpp @@ -371,4 +371,7 @@ * \fn bool PIMapIterator::next() * \brief Jump to next entry and return if new position is valid. +* \fn void PIMapIterator::reset() +* \brief Reset iterator to initial position. + * */ diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index 47f0d3b7..ea71ead1 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -364,6 +364,13 @@ public: } return false; } + inline void reset() { + if (rev) { + pos = m.size_s(); + } else { + pos = -1; + } + } private: const MapType & m; ssize_t pos; diff --git a/lib/main/core/pibase.h b/lib/main/core/pibase.h index e0b1dd0a..7d31d3c8 100644 --- a/lib/main/core/pibase.h +++ b/lib/main/core/pibase.h @@ -467,7 +467,7 @@ uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF #endif -/// \brief Generic hash function, impements murmur3/32 algorithm +/// \brief Generic hash function, implements murmur3/32 algorithm inline uint piHashData(const uchar * data, uint len, uint seed = 0) { if (!data || len <= 0) return 0u; uint h = seed; diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index 9268f759..6c166521 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -337,6 +337,16 @@ public: * \sa \a expandRightTo() */ PIString & expandLeftTo(const int len, const PIChar c) {if (len > length()) insert(0, PIString(len - length(), c)); return *this;} + /*! \brief Enlarge and returns copy of this string to length "len" + * by addition sequence of symbols "c" at the end of string + * \sa \a expandRightTo() */ + PIString expandedRightTo(const int len, const PIChar c) const {return PIString(*this).expandRightTo(len, c);} + + /*! \brief Enlarge and returns copy of this string to length "len" + * by addition sequence of symbols "c" at the beginning of string + * \sa \a expandLeftTo() */ + PIString expandedLeftTo(const int len, const PIChar c) const {return PIString(*this).expandLeftTo(len, c);} + /*! \brief Add "c" symbols at the beginning and end of the string, and return this string * \sa \a quoted() */ PIString & quote(PIChar c = PIChar('"')) {insert(0, c); *this += c; return *this;} diff --git a/main.cpp b/main.cpp index 621a56e3..511302a7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,114 +1,259 @@ #include "pip.h" -/*#ifdef PIP_LUA -#include "piluaprogram.h" -static const char * script -= "-- script.lua \n" - "test()\n" - "testString = \"LuaBridge works ававава!\" \n" - "number = 42 \n"; +PIMap results; -void test() { - piCout << "C function test"; -} - -int main() { - PILuaProgram p; - p.getGlobalNamespace().addFunction("test", test); - if (!p.load(PIString::fromUTF8(script))) piCout << "error"; - p.prepare(); - luabridge::LuaRef s = p.getGlobal("testString"); - luabridge::LuaRef n = p.getGlobal("number"); - PIString luaString = s.cast(); - int answer = n.cast(); - piCout << luaString; - piCout << "And here's our number:" << answer; -} -#else -int main() { - return 0; -} -#endif -*/ -class db { -public: - db() { - name = PIStringAscii("sflner;ljner.vjnrevsg;j35m4;gberjg2mnv"); - for (int i=0; i<10000; ++i) - x << sin(double(i)/180.0); - //printf("jkfkhg\n"); - } - PIString name; - PIVector x; +template +struct __VariantTypeInfo__ { + typedef T PureType; + typedef const T ConstPureType; + typedef T * PointerType; + typedef const T * ConstPointerType; + typedef T & ReferenceType; + typedef const T & ConstReferenceType; }; -inline PIByteArray & operator <<(PIByteArray & ba, const db & v) { - PIChunkStream cs; - cs.add(1, v.name).add(2, v.x); - ba << cs.data(); - return ba; -} -inline PIByteArray & operator >>(PIByteArray & ba, db & v) { - PIByteArray src; ba >> src; PIChunkStream cs(src); - while (!cs.atEnd()) { - switch (cs.read()) { - case 1: cs.get(v.name); break; - case 2: cs.get(v.x); break; - } +#define __TYPEINFO_SINGLE(PT, T) \ + template<> struct __PIVariantTypeInfo__ { \ + typedef PT PureType; \ + typedef const PT ConstPureType; \ + typedef PT * PointerType; \ + typedef const PT * ConstPointerType; \ + typedef PT & ReferenceType; \ + typedef const PT & ConstReferenceType; \ + }; + +#define REGISTER_VARIANT_TYPEINFO(T) \ + __TYPEINFO_SINGLE(T, T &) \ + __TYPEINFO_SINGLE(T, const T) \ + __TYPEINFO_SINGLE(T, const T &) + + + + +class __VariantFunctionsBase__ { +public: + virtual __VariantFunctionsBase__ * instance() {return 0;} + virtual PIString typeName() const {return PIString();} + virtual uint hash() const {return 0;} + virtual void newT(void *& ptr, const void * value) {;} + virtual void newNullT(void *& ptr) {;} + virtual void equalT(void *& ptr, const void * value) {;} + virtual void deleteT(void *& ptr) {;} + virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} + virtual void fromData(void *& ptr, PIByteArray ba) {;} + //template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} + //template static C castVariant(const T & v) {return C();} + static PIMap & registered() {static PIMap ret; return ret;} +}; + + +template +class __VariantFunctions__: public __VariantFunctionsBase__ { +public: + __VariantFunctionsBase__ * instance() override {static __VariantFunctions__ ret; return &ret;} + PIString typeName() const override {return PIString();} + uint hash() const override {static uint ret = typeName().hash(); return ret;} + void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); printf(" * new\n");} + void newNullT(void *& ptr) override {ptr = (void*)(new T()); printf(" * new null\n");} + void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; printf(" * =\n");} + void deleteT(void *& ptr) override {delete (T*)(ptr); printf(" * del\n");} + PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} + void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;} + + template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} + template static C castVariant(const T & v) {return C();} +}; + +class Variant { +public: + Variant() {ptr = 0; f = 0;} + Variant(const Variant & v) { + ptr = 0; + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); } - return ba; -} + ~Variant() {destroy();} + + Variant & operator=(const Variant & v) { + destroy(); + f = v.f; + if (f && v.ptr) + f->newT(ptr, v.ptr); + return *this; + } + + template + void setValue(const T & v) { + if (f) { + if (isMyType()) { + f->equalT(ptr, (const void *)&v); + return; + } + } + destroy(); + f = __VariantFunctions__().instance(); + f->newT(ptr, (const void *)&v); + } + + template + T value() const { + if (!f) return T(); + if (!isMyType()) + return T(); + return *(T*)(ptr); + } + + PIByteArray save() const { + if (!ptr || !f) return PIByteArray(); + PIByteArray ret; + ret << f->hash(); + ret.append(f->toData(ptr)); + return ret; + } + + bool load(PIByteArray ba) { + if (ba.size_s() < 4) return false; + uint h(0); ba >> h; + destroy(); + f = __VariantFunctionsBase__::registered().value(h, 0); + if (!f) return false; + f->newNullT(ptr); + f->fromData(ptr, ba); + return true; + } + +//private: + template + bool isMyType() const {return f->hash() == __VariantFunctions__().instance()->hash();} + + void destroy() { + if (ptr && f) + f->deleteT(ptr); + ptr = 0; + f = 0; + } + + void * ptr; + __VariantFunctionsBase__ * f; + +}; + +int Acnt = 0; + +class A { +public: + A() {i = "constructor"; /*piCout << "A()";*/ ++Acnt;} + A(const A & a): i(a.i) {/*piCout << "copy A()";*/ ++Acnt;} + ~A() {/*piCout << "~A()";*/ --Acnt;} + A & operator =(const A & a) {i = a.i; /*piCout << "= A()";*/ return *this;} + PIString i; +}; +PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;} +PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;} + + +template <> +PIString __VariantFunctions__::typeName() const {static PIString ret("int"); return ret;} +class _VariantRegistrator_int__ { +public: + _VariantRegistrator_int__() { + __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); + __VariantFunctionsBase__::registered()[f->hash()] = f; + } +}; +_VariantRegistrator_int__ __reg_int__; + +template <> +PIString __VariantFunctions__::typeName() const {static PIString ret("A"); return ret;} +class _VariantRegistrator_A__ { +public: + _VariantRegistrator_A__() { + __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); + __VariantFunctionsBase__::registered()[f->hash()] = f; + } +}; +_VariantRegistrator_A__ __reg_A__; -PIEthernet eth; -#include "picodeparser.h" int main() { - //PICodeParser cp; - //cp.parseFile("SH_plugin_base.h"); + { - PIMap m; - m[1] = "one"; - m[2] = "two"; + Variant v, v2; - auto it = m.makeIterator(); - while (it.next()) { - //it.next(); - it.valueRef() << "_!"; - piCout << it.key() << it.value(); + /*{ + A a, ra; + + a.i = "main"; + v.setValue(a); + + ra = v.value(); + piCout << " 1 A.i =" << ra.i; + + a.i = "main second"; + v.setValue(a); + + ra = v.value(); + piCout << " 2 A.i =" << ra.i; + + piCout << "Acnt" << Acnt; } + piCout << "Acnt" << Acnt; - /*eth.__meta_data - piForeachC (auto & i, cp.enums) { - i. - }*/ + v2 = v; + PIString ra = v2.value(); + piCout << " 3 A.i =" << ra;*/ - /*piDebug = false; - double min = -1, max = -1, mean = 0; - const int iterations = 50; - db d, d2; - for (int i = 0; i < iterations; ++i) { - //PICodeParser cp; - PITimeMeasurer tm; - for (int j = 0; j < 100; ++j) { - PIByteArray ba; - ba << d; - } - //cp.parseFile("SH_plugin_base.h"); - double ms = tm.elapsed_m(); - if (min < 0) min = ms; - if (max < 0) max = ms; - min = piMin(min, ms); - max = piMax(max, ms); - mean += ms; + A a, ra; + + a.i = "main"; + v.setValue(a); + PIByteArray ba = v.save(); + + piCout << v2.load(ba); + piCout << v2.value().i; - PIByteArray ba; - ba << d; - d2.name.clear(); - d2.x.clear(); - ba >> d2; } - piDebug = true; - piCout << d2.name << d2.x.size_s(); - piCout << min << (mean / iterations) << max;*/ + piCout << "Acnt" << Acnt; + //__VariantFunctionsBase__ * f = __VariantFunctions__().instance(); + //piCout << f->typeName(); + //f = __VariantFunctions__().instance(); + //piCout << f->typeName(); } + +/* +template +void test_var(const char * Tname) { + piCout << Tname << "..."; + ullong cnt = 0; + PIVariant _v; + PITimeMeasurer tm1s; + while (tm1s.elapsed_m() < 500.) { + ++cnt; + for (int j = 0; j < 1000; ++j) { + PIVariant v; + v = T(); + v.setValue(T(j)); + _v = v; + } + } + PIVariant v; + results[Tname] = cnt; +} + +#define TEST_VAR(T) test_var(#T) + +int main() { + TEST_VAR(int); + TEST_VAR(float); + TEST_VAR(ullong); + TEST_VAR(PIString); + int sz = 0; + auto i = results.makeIterator(); + while (i.next()) sz = piMaxi(sz, i.key().length()); + i.reset(); + while (i.next()) + piCout << i.key().expandedLeftTo(sz, ' ') << ":" << i.value(); +} +*/ From 26742a1fc321b366b2e03de9fd03a9b0d7ba665e Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 6 Aug 2020 15:01:31 +0300 Subject: [PATCH 38/68] PIFile::readAll patch --- lib/main/io_devices/pifile.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/main/io_devices/pifile.cpp b/lib/main/io_devices/pifile.cpp index 8984253b..e0e78ec6 100644 --- a/lib/main/io_devices/pifile.cpp +++ b/lib/main/io_devices/pifile.cpp @@ -235,6 +235,7 @@ PIByteArray PIFile::readAll(bool forceRead) { llong s = size(); if (s < 0) return a; a.resize(s); + seekToBegin(); fread(a.data(), 1, s, PRIVATE->fd); seek(cp); if (s >= 0) a.resize(s); From e08f805525c474ecfb2adcbe48e6afdc097d17a4 Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 6 Aug 2020 15:17:15 +0300 Subject: [PATCH 39/68] small fixes --- CMakeLists.txt | 6 +++--- lib/cloud/piccloudclient.cpp | 4 ++-- lib/main/core/pibytearray.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87748bab..2c16f052 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) -set(_PIP_MAJOR 1) -set(_PIP_MINOR 99) -set(_PIP_REVISION 3) +set(_PIP_MAJOR 2) +set(_PIP_MINOR 0) +set(_PIP_REVISION 0) set(_PIP_SUFFIX _prebeta) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/lib/cloud/piccloudclient.cpp b/lib/cloud/piccloudclient.cpp index 98fec593..b17a2362 100644 --- a/lib/cloud/piccloudclient.cpp +++ b/lib/cloud/piccloudclient.cpp @@ -30,11 +30,11 @@ PICloudClient::~PICloudClient() { bool PICloudClient::openDevice() { - + return false; } bool PICloudClient::closeDevice() { - + return false; } diff --git a/lib/main/core/pibytearray.cpp b/lib/main/core/pibytearray.cpp index 470bdc26..f939ef0a 100644 --- a/lib/main/core/pibytearray.cpp +++ b/lib/main/core/pibytearray.cpp @@ -396,8 +396,8 @@ PIByteArray & operator >>(PIByteArray & s, PIByteArray & v) { } v.resize(sz); if (sz > 0) { - memcpy(v.data(), s.data(), v.size()); - s.remove(0, v.size()); + memcpy(v.data(), s.data(), sz); + s.remove(0, sz); } return s; } From dac318c624c986926c6a1ead06b852d432570678 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 6 Aug 2020 17:25:16 +0300 Subject: [PATCH 40/68] _MAKE_VERSION macro add in "set_version()" CMake generated header --- cmake/DeployMacros.cmake | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cmake/DeployMacros.cmake b/cmake/DeployMacros.cmake index d7670c1e..057cc9a6 100644 --- a/cmake/DeployMacros.cmake +++ b/cmake/DeployMacros.cmake @@ -14,7 +14,9 @@ Create variable _VERSION with full version name If OUTPUT then generate header with version macros - _VERSION_ -Also create macro _VERSION_NAME with full string version +Also create macro _VERSION_NAME with full string version and +macro _MAKE_VERSION(major, minor, revision) that returns +byte-packed integer version. Attention: macro _VERSION is byte-packed integer version! @@ -165,7 +167,7 @@ set(_dt_delim "::") macro(set_version _T) - set(_VERSION_ 1) # macro version + set(_VERSION_ 2) # macro version set(_name) set(_is_name 1) set(_is_out 0) @@ -239,7 +241,8 @@ macro(set_version _T) #define ${_TN}_VERSION_BUILD ${${_T}_VERSION_BUILD} #define ${_TN}_VERSION_SUFFIX \"${${_T}_VERSION_SUFFIX}\" #define ${_TN}_VERSION_NAME \"${${_T}_VERSION}\" -#define ${_TN}_VERSION ((${_TN}_VERSION_MAJOR << 16) | (${_TN}_VERSION_MINOR << 8) | ${_TN}_VERSION_REVISION) +#define ${_TN}_MAKE_VERSION(major, minor, revision) ((major << 16) | (minor << 8) | revision) +#define ${_TN}_VERSION ${_TN}_MAKE_VERSION(${_TN}_VERSION_MAJOR, ${_TN}_VERSION_MINOR, ${_TN}_VERSION_REVISION) // Tools From 8c3349d84afb922878cc77b38825504af03a339a Mon Sep 17 00:00:00 2001 From: andrey Date: Tue, 11 Aug 2020 17:26:44 +0300 Subject: [PATCH 41/68] fix PIThreadPoolExecutor and PIBlockingDequeue --- lib/main/thread/piblockingdequeue.h | 60 +++++--------------- lib/main/thread/pithreadpoolexecutor.cpp | 20 ++----- lib/main/thread/pithreadpoolexecutor.h | 4 +- tests/concurrent/BlockingDequeueUnitTest.cpp | 12 ++-- 4 files changed, 27 insertions(+), 69 deletions(-) diff --git a/lib/main/thread/piblockingdequeue.h b/lib/main/thread/piblockingdequeue.h index 27e23572..4b7fc57f 100644 --- a/lib/main/thread/piblockingdequeue.h +++ b/lib/main/thread/piblockingdequeue.h @@ -86,29 +86,13 @@ public: * @param v the element to add * @return true if the element was added to this queue, else false */ - bool offer(const T & v) { + bool offer(const T & v, int timeoutMs = 0) { + bool isOk; mutex.lock(); - if (PIDeque::size() >= max_size) { - mutex.unlock(); - return false; - } - PIDeque::push_back(v); - mutex.unlock(); - cond_var_add->notifyOne(); - return true; - } - - /** - * @brief Inserts the specified element into this queue, waiting up to the specified wait time if necessary for - * space to become available. - * - * @param v the element to add - * @param timeoutMs how long to wait before giving up, in milliseconds - * @return true if successful, or false if the specified waiting time elapses before space is available - */ - bool offer(const T & v, int timeoutMs) { - mutex.lock(); - bool isOk = cond_var_rem->waitFor(mutex, timeoutMs, [&]() { return PIDeque::size() < max_size; } ); + if (timeoutMs == 0) + isOk = PIDeque::size() < max_size; + else + isOk = cond_var_rem->waitFor(mutex, timeoutMs, [&]() { return PIDeque::size() < max_size; } ); if (isOk) PIDeque::push_back(v); mutex.unlock(); if (isOk) cond_var_add->notifyOne(); @@ -140,31 +124,15 @@ public: * return value is retrieved value * @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available */ - T poll(int timeoutMs, const T & defaultVal = T(), bool * isOk = nullptr) { - T t; + T poll(int timeoutMs = 0, const T & defaultVal = T(), bool * isOk = nullptr) { + T t = defaultVal; + bool isNotEmpty; mutex.lock(); - bool isNotEmpty = cond_var_add->waitFor(mutex, timeoutMs, [&]() { return !PIDeque::isEmpty(); }); - t = isNotEmpty ? T(PIDeque::take_front()) : defaultVal; - mutex.unlock(); - if (isNotEmpty) cond_var_rem->notifyOne(); - if (isOk) *isOk = isNotEmpty; - return t; - } - - /** - * @brief Retrieves and removes the head of this queue and return it if queue not empty, otherwise return defaultVal. - * Do it immediately without waiting. - * - * @param defaultVal value, which returns if the specified waiting time elapses before an element is available - * @param isOk flag, which indicates result of method execution. It will be set to false if timeout, or true if - * return value is retrieved value - * @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available - */ - T poll(const T & defaultVal = T(), bool * isOk = nullptr) { - T t; - mutex.lock(); - bool isNotEmpty = !PIDeque::isEmpty(); - t = isNotEmpty ? PIDeque::take_front() : defaultVal; + if (timeoutMs == 0) + isNotEmpty = !PIDeque::isEmpty(); + else + isNotEmpty = cond_var_add->waitFor(mutex, timeoutMs, [&]() { return !PIDeque::isEmpty(); }); + if (isNotEmpty) t = PIDeque::take_front(); mutex.unlock(); if (isNotEmpty) cond_var_rem->notifyOne(); if (isOk) *isOk = isNotEmpty; diff --git a/lib/main/thread/pithreadpoolexecutor.cpp b/lib/main/thread/pithreadpoolexecutor.cpp index d0feeb83..ea0eb9aa 100644 --- a/lib/main/thread/pithreadpoolexecutor.cpp +++ b/lib/main/thread/pithreadpoolexecutor.cpp @@ -18,7 +18,6 @@ */ #include "pithreadpoolexecutor.h" -#include "pisysteminfo.h" /*! \class PIThreadPoolExecutor * @brief Thread pools address two different problems: they usually provide improved performance when executing large @@ -27,21 +26,14 @@ */ -PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue > * taskQueue_) : isShutdown_(false) { - queue_own = false; - if (corePoolSize <= 0) - corePoolSize = PISystemInfo::instance()->processorsCount; - if (!taskQueue_) { - taskQueue = new PIBlockingDequeue >(); - queue_own = true; - } - for (size_t i = 0; i < corePoolSize; ++i) { +PIThreadPoolExecutor::PIThreadPoolExecutor(int corePoolSize) : isShutdown_(false) { + for (int i = 0; i < corePoolSize; ++i) { PIThread * thread = new PIThread([&, i](){ - auto runnable = taskQueue->poll(100, std::function()); + auto runnable = taskQueue.poll(100, std::function()); if (runnable) { runnable(); } - if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop(); + if (isShutdown_ && taskQueue.size() == 0) threadPool[i]->stop(); }); threadPool.push_back(thread); thread->start(); @@ -69,13 +61,11 @@ void PIThreadPoolExecutor::shutdownNow() { PIThreadPoolExecutor::~PIThreadPoolExecutor() { shutdownNow(); while (threadPool.size() > 0) delete threadPool.take_back(); - if (queue_own) - delete taskQueue; } void PIThreadPoolExecutor::execute(const std::function & runnable) { - if (!isShutdown_) taskQueue->offer(runnable); + if (!isShutdown_) taskQueue.offer(runnable); } diff --git a/lib/main/thread/pithreadpoolexecutor.h b/lib/main/thread/pithreadpoolexecutor.h index 1d3bf75f..266103ea 100644 --- a/lib/main/thread/pithreadpoolexecutor.h +++ b/lib/main/thread/pithreadpoolexecutor.h @@ -26,7 +26,7 @@ class PIP_EXPORT PIThreadPoolExecutor { public: - explicit PIThreadPoolExecutor(size_t corePoolSize = -1, PIBlockingDequeue > * taskQueue_ = 0); + explicit PIThreadPoolExecutor(int corePoolSize); virtual ~PIThreadPoolExecutor(); @@ -54,7 +54,7 @@ public: private: std::atomic_bool isShutdown_; - PIBlockingDequeue > * taskQueue; + PIBlockingDequeue > taskQueue; PIVector threadPool; bool queue_own; diff --git a/tests/concurrent/BlockingDequeueUnitTest.cpp b/tests/concurrent/BlockingDequeueUnitTest.cpp index fae9f3ff..08a4b7ce 100644 --- a/tests/concurrent/BlockingDequeueUnitTest.cpp +++ b/tests/concurrent/BlockingDequeueUnitTest.cpp @@ -69,7 +69,7 @@ TEST(BlockingDequeueUnitTest, offer_timedout_is_block_when_capacity_reach) { TEST(BlockingDequeueUnitTest, offer_is_true_before_capacity_reach) { size_t capacity = 1; PIBlockingDequeue dequeue(capacity); - ASSERT_TRUE(dequeue.offer(10)); + ASSERT_TRUE(dequeue.offer(10)); } TEST(BlockingDequeueUnitTest, offer_is_false_when_capacity_reach) { @@ -125,7 +125,7 @@ TEST(BlockingDequeueUnitTest, poll_is_not_block_when_empty) { bool isOk; auto conditionVar = new MockConditionVar(); PIBlockingDequeue dequeue(capacity, conditionVar); - dequeue.poll(111, &isOk); + dequeue.poll(0, 111, &isOk); EXPECT_FALSE(conditionVar->isWaitForCalled); } @@ -134,7 +134,7 @@ TEST(BlockingDequeueUnitTest, poll_is_default_value_when_empty) { bool isOk; auto conditionVar = new MockConditionVar(); PIBlockingDequeue dequeue(capacity, conditionVar); - ASSERT_EQ(dequeue.poll(111, &isOk), 111); + ASSERT_EQ(dequeue.poll(0, 111, &isOk), 111); } TEST(BlockingDequeueUnitTest, poll_is_offer_value_when_not_empty) { @@ -143,7 +143,7 @@ TEST(BlockingDequeueUnitTest, poll_is_offer_value_when_not_empty) { auto conditionVar = new MockConditionVar(); PIBlockingDequeue dequeue(capacity, conditionVar); dequeue.offer(111); - ASSERT_EQ(dequeue.poll(-1, &isOk), 111); + ASSERT_EQ(dequeue.poll(0, -1, &isOk), 111); } TEST(BlockingDequeueUnitTest, poll_timeouted_is_block_when_empty) { @@ -152,8 +152,8 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_block_when_empty) { auto conditionVar = new MockConditionVar(); PIBlockingDequeue dequeue(capacity, conditionVar); dequeue.poll(timeout, 111); - EXPECT_TRUE(conditionVar->isWaitForCalled); - EXPECT_EQ(timeout, conditionVar->timeout); + EXPECT_TRUE(conditionVar->isWaitForCalled); + EXPECT_EQ(timeout, conditionVar->timeout); ASSERT_FALSE(conditionVar->isTrueCondition); } From 3ba6a7b0e84f2b3b1d765830a00ae77c138461b5 Mon Sep 17 00:00:00 2001 From: andrey Date: Tue, 11 Aug 2020 19:05:47 +0300 Subject: [PATCH 42/68] rename PIBlockingDequeue -> PIBlockingQueue --- ...{piblockingdequeue.h => piblockingqueue.h} | 25 +++++---- lib/main/thread/pithreadpoolexecutor.h | 4 +- tests/concurrent/BlockingDequeueUnitTest.cpp | 52 +++++++++---------- 3 files changed, 43 insertions(+), 38 deletions(-) rename lib/main/thread/{piblockingdequeue.h => piblockingqueue.h} (89%) diff --git a/lib/main/thread/piblockingdequeue.h b/lib/main/thread/piblockingqueue.h similarity index 89% rename from lib/main/thread/piblockingdequeue.h rename to lib/main/thread/piblockingqueue.h index 4b7fc57f..6021e4d9 100644 --- a/lib/main/thread/piblockingdequeue.h +++ b/lib/main/thread/piblockingqueue.h @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#ifndef PIBLOCKINGDEQUEUE_H -#define PIBLOCKINGDEQUEUE_H +#ifndef PIBLOCKINGQUEUE_H +#define PIBLOCKINGQUEUE_H #include "pideque.h" #include "piconditionvar.h" @@ -28,13 +28,13 @@ * wait for space to become available in the queue when storing an element. */ template -class PIBlockingDequeue: private PIDeque { +class PIBlockingQueue: private PIQueue { public: /** * @brief Constructor */ - explicit inline PIBlockingDequeue(size_t capacity = SIZE_MAX, + explicit inline PIBlockingQueue(size_t capacity = SIZE_MAX, PIConditionVariable* cond_var_add = new PIConditionVariable(), PIConditionVariable* cond_var_rem = new PIConditionVariable()) : cond_var_add(cond_var_add), cond_var_rem(cond_var_rem), max_size(capacity) { } @@ -42,7 +42,7 @@ public: /** * @brief Copy constructor. Initialize queue with copy of other queue elements. Not thread-safe for other queue. */ - explicit inline PIBlockingDequeue(const PIDeque& other) : cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) { + explicit inline PIBlockingQueue(const PIDeque& other) : cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) { mutex.lock(); max_size = SIZE_MAX; PIDeque::append(other); @@ -52,7 +52,7 @@ public: /** * @brief Thread-safe copy constructor. Initialize queue with copy of other queue elements. */ - inline PIBlockingDequeue(PIBlockingDequeue & other) : cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) { + inline PIBlockingQueue(PIBlockingQueue & other) : cond_var_add(new PIConditionVariable()), cond_var_rem(new PIConditionVariable()) { other.mutex.lock(); mutex.lock(); max_size = other.max_size; @@ -61,7 +61,7 @@ public: other.mutex.unlock(); } - ~PIBlockingDequeue() { + ~PIBlockingQueue() { delete cond_var_add; delete cond_var_rem; } @@ -71,14 +71,17 @@ public: * * @param v the element to add */ - void put(const T & v) { + PIBlockingQueue & put(const T & v) { mutex.lock(); cond_var_rem->wait(mutex, [&]() { return PIDeque::size() < max_size; }); PIDeque::push_back(v); mutex.unlock(); cond_var_add->notifyOne(); + return *this; } + PIBlockingQueue & enqueue(const T & v) {return put(v);} + /** * @brief Inserts the specified element at the end of this queue if it is possible to do so immediately without * exceeding the queue's capacity, returning true upon success and false if this queue is full. @@ -114,6 +117,8 @@ public: return t; } + T dequeue() {return take();} + /** * @brief Retrieves and removes the head of this queue, waiting up to the specified wait time if necessary for an * element to become available. @@ -190,7 +195,7 @@ public: /** * @brief Removes all available elements from this queue and adds them to other given queue. */ - size_t drainTo(PIBlockingDequeue& other, size_t maxCount = SIZE_MAX) { + size_t drainTo(PIBlockingQueue& other, size_t maxCount = SIZE_MAX) { mutex.lock(); other.mutex.lock(); size_t count = maxCount > PIDeque::size() ? PIDeque::size() : maxCount; @@ -210,4 +215,4 @@ private: }; -#endif // PIBLOCKINGDEQUEUE_H +#endif // PIBLOCKINGQUEUE_H diff --git a/lib/main/thread/pithreadpoolexecutor.h b/lib/main/thread/pithreadpoolexecutor.h index 266103ea..1fa93fc6 100644 --- a/lib/main/thread/pithreadpoolexecutor.h +++ b/lib/main/thread/pithreadpoolexecutor.h @@ -20,7 +20,7 @@ #ifndef PITHREADPOOLEXECUTOR_H #define PITHREADPOOLEXECUTOR_H -#include "piblockingdequeue.h" +#include "piblockingqueue.h" #include @@ -54,7 +54,7 @@ public: private: std::atomic_bool isShutdown_; - PIBlockingDequeue > taskQueue; + PIBlockingQueue > taskQueue; PIVector threadPool; bool queue_own; diff --git a/tests/concurrent/BlockingDequeueUnitTest.cpp b/tests/concurrent/BlockingDequeueUnitTest.cpp index 08a4b7ce..993326dd 100644 --- a/tests/concurrent/BlockingDequeueUnitTest.cpp +++ b/tests/concurrent/BlockingDequeueUnitTest.cpp @@ -1,5 +1,5 @@ #include "gtest/gtest.h" -#include "piblockingdequeue.h" +#include "piblockingqueue.h" class MockConditionVar: public PIConditionVariable { public: @@ -39,7 +39,7 @@ TEST(BlockingDequeueUnitTest, put_is_block_when_capacity_reach) { size_t capacity = 0; auto conditionVarAdd = new MockConditionVar(); auto conditionVarRem = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); + PIBlockingQueue dequeue(capacity, conditionVarAdd, conditionVarRem); dequeue.put(11); ASSERT_TRUE(conditionVarRem->isWaitCalled); ASSERT_FALSE(conditionVarRem->isTrueCondition); @@ -50,7 +50,7 @@ TEST(BlockingDequeueUnitTest, offer_timedout_is_false_when_capacity_reach) { int timeout = 11; auto conditionVarAdd = new MockConditionVar(); auto conditionVarRem = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); + PIBlockingQueue dequeue(capacity, conditionVarAdd, conditionVarRem); ASSERT_FALSE(dequeue.offer(11, timeout)); } @@ -59,7 +59,7 @@ TEST(BlockingDequeueUnitTest, offer_timedout_is_block_when_capacity_reach) { int timeout = 11; auto conditionVarAdd = new MockConditionVar(); auto conditionVarRem = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVarAdd, conditionVarRem); + PIBlockingQueue dequeue(capacity, conditionVarAdd, conditionVarRem); dequeue.offer(11, timeout); EXPECT_TRUE(conditionVarRem->isWaitForCalled); EXPECT_EQ(timeout, conditionVarRem->timeout); @@ -68,13 +68,13 @@ TEST(BlockingDequeueUnitTest, offer_timedout_is_block_when_capacity_reach) { TEST(BlockingDequeueUnitTest, offer_is_true_before_capacity_reach) { size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); ASSERT_TRUE(dequeue.offer(10)); } TEST(BlockingDequeueUnitTest, offer_is_false_when_capacity_reach) { size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); dequeue.offer(11); ASSERT_FALSE(dequeue.offer(10)); } @@ -83,7 +83,7 @@ TEST(BlockingDequeueUnitTest, offer_is_false_when_capacity_reach) { TEST(DISABLED_BlockingDequeueUnitTest, take_is_block_when_empty) { size_t capacity = 1; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); // May cause segfault because take front of empty queue dequeue.take(); EXPECT_TRUE(conditionVar->isWaitCalled); @@ -93,7 +93,7 @@ TEST(DISABLED_BlockingDequeueUnitTest, take_is_block_when_empty) { TEST(BlockingDequeueUnitTest, take_is_not_block_when_not_empty) { size_t capacity = 1; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.offer(111); dequeue.take(); @@ -104,7 +104,7 @@ TEST(BlockingDequeueUnitTest, take_is_not_block_when_not_empty) { TEST(BlockingDequeueUnitTest, take_is_value_eq_to_offer_value) { size_t capacity = 1; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.offer(111); ASSERT_EQ(dequeue.take(), 111); @@ -113,7 +113,7 @@ TEST(BlockingDequeueUnitTest, take_is_value_eq_to_offer_value) { TEST(BlockingDequeueUnitTest, take_is_last) { size_t capacity = 10; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); EXPECT_TRUE(dequeue.offer(111)); EXPECT_TRUE(dequeue.offer(222)); ASSERT_EQ(dequeue.take(), 111); @@ -124,7 +124,7 @@ TEST(BlockingDequeueUnitTest, poll_is_not_block_when_empty) { size_t capacity = 1; bool isOk; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.poll(0, 111, &isOk); EXPECT_FALSE(conditionVar->isWaitForCalled); } @@ -133,7 +133,7 @@ TEST(BlockingDequeueUnitTest, poll_is_default_value_when_empty) { size_t capacity = 1; bool isOk; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); ASSERT_EQ(dequeue.poll(0, 111, &isOk), 111); } @@ -141,7 +141,7 @@ TEST(BlockingDequeueUnitTest, poll_is_offer_value_when_not_empty) { size_t capacity = 1; bool isOk; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.offer(111); ASSERT_EQ(dequeue.poll(0, -1, &isOk), 111); } @@ -150,7 +150,7 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_block_when_empty) { size_t capacity = 1; int timeout = 11; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.poll(timeout, 111); EXPECT_TRUE(conditionVar->isWaitForCalled); EXPECT_EQ(timeout, conditionVar->timeout); @@ -161,7 +161,7 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_default_value_when_empty) { size_t capacity = 1; int timeout = 11; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); ASSERT_EQ(dequeue.poll(timeout, 111), 111); } @@ -169,7 +169,7 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_not_block_when_not_empty) { size_t capacity = 1; int timeout = 11; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.offer(111); dequeue.poll(timeout, -1); @@ -181,7 +181,7 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_offer_value_when_not_empty) { size_t capacity = 1; int timeout = 11; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.offer(111); ASSERT_EQ(dequeue.poll(timeout, -1), 111); } @@ -189,7 +189,7 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_offer_value_when_not_empty) { TEST(BlockingDequeueUnitTest, poll_timeouted_is_last) { size_t capacity = 10; auto conditionVar = new MockConditionVar(); - PIBlockingDequeue dequeue(capacity, conditionVar); + PIBlockingQueue dequeue(capacity, conditionVar); dequeue.offer(111); dequeue.offer(222); ASSERT_EQ(dequeue.poll(10, -1), 111); @@ -198,13 +198,13 @@ TEST(BlockingDequeueUnitTest, poll_timeouted_is_last) { TEST(BlockingDequeueUnitTest, capacity_is_eq_constructor_capacity) { size_t capacity = 10; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); ASSERT_EQ(dequeue.capacity(), capacity); } TEST(BlockingDequeueUnitTest, remainingCapacity_is_dif_of_capacity_and_size) { size_t capacity = 2; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); ASSERT_EQ(dequeue.remainingCapacity(), capacity); dequeue.offer(111); ASSERT_EQ(dequeue.remainingCapacity(), capacity - 1); @@ -212,7 +212,7 @@ TEST(BlockingDequeueUnitTest, remainingCapacity_is_dif_of_capacity_and_size) { TEST(BlockingDequeueUnitTest, remainingCapacity_is_zero_when_capacity_reach) { size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); dequeue.offer(111); dequeue.offer(111); ASSERT_EQ(dequeue.remainingCapacity(), 0); @@ -220,7 +220,7 @@ TEST(BlockingDequeueUnitTest, remainingCapacity_is_zero_when_capacity_reach) { TEST(BlockingDequeueUnitTest, size_is_eq_to_num_of_elements) { size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); ASSERT_EQ(dequeue.size(), 0); dequeue.offer(111); ASSERT_EQ(dequeue.size(), 1); @@ -228,7 +228,7 @@ TEST(BlockingDequeueUnitTest, size_is_eq_to_num_of_elements) { TEST(BlockingDequeueUnitTest, size_is_eq_to_capacity_when_capacity_reach) { size_t capacity = 1; - PIBlockingDequeue dequeue(capacity); + PIBlockingQueue dequeue(capacity); dequeue.offer(111); dequeue.offer(111); ASSERT_EQ(dequeue.size(), capacity); @@ -238,7 +238,7 @@ TEST(BlockingDequeueUnitTest, drainTo_is_elements_moved) { size_t capacity = 10; PIDeque refDeque; for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); - PIBlockingDequeue blockingDequeue(refDeque); + PIBlockingQueue blockingDequeue(refDeque); PIDeque deque; blockingDequeue.drainTo(deque); ASSERT_EQ(blockingDequeue.size(), 0); @@ -249,7 +249,7 @@ TEST(BlockingDequeueUnitTest, drainTo_is_ret_eq_to_size_when_all_moved) { size_t capacity = 10; PIDeque refDeque; for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); - PIBlockingDequeue blockingDequeue(refDeque); + PIBlockingQueue blockingDequeue(refDeque); PIDeque deque; ASSERT_EQ(blockingDequeue.drainTo(deque), refDeque.size()); } @@ -258,7 +258,7 @@ TEST(BlockingDequeueUnitTest, drainTo_is_ret_eq_to_maxCount) { size_t capacity = 10; PIDeque refDeque; for (size_t i = 0; i < capacity / 2; ++i) refDeque.push_back(i * 10); - PIBlockingDequeue blockingDequeue(refDeque); + PIBlockingQueue blockingDequeue(refDeque); PIDeque deque; ASSERT_EQ(blockingDequeue.drainTo(deque, refDeque.size() - 1), refDeque.size() - 1); } From 57a9ccb854dac460a8b2823433806ede784d5aad Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 11 Aug 2020 20:09:34 +0300 Subject: [PATCH 43/68] version 2.0.0_prealpha PIFile::put() and get() --- CMakeLists.txt | 2 +- lib/main/core/pipropertystorage.cpp | 10 ++++++++++ lib/main/core/pipropertystorage.h | 27 +++++++++++++++++++++++++-- lib/main/core/pivariant.cpp | 22 +++++++++++++++++++++- lib/main/core/pivariant.h | 6 ++++++ lib/main/io_devices/pifile.cpp | 19 +++++++++++++++++++ lib/main/io_devices/pifile.h | 4 ++++ lib/main/system/pisysteminfo.cpp | 2 +- 8 files changed, 87 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c16f052..dd573d11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(pip) set(_PIP_MAJOR 2) set(_PIP_MINOR 0) set(_PIP_REVISION 0) -set(_PIP_SUFFIX _prebeta) +set(_PIP_SUFFIX _prealpha) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/lib/main/core/pipropertystorage.cpp b/lib/main/core/pipropertystorage.cpp index e68d7238..679d374b 100644 --- a/lib/main/core/pipropertystorage.cpp +++ b/lib/main/core/pipropertystorage.cpp @@ -38,6 +38,16 @@ void PIPropertyStorage::addProperty(const PIPropertyStorage::Property & p) { } +void PIPropertyStorage::addProperty(PIPropertyStorage::Property && p) { + for (uint i = 0; i < props.size(); ++i) + if (props[i].name == p.name) { + props[i] = std::move(p); + return; + } + props << std::move(p); +} + + void PIPropertyStorage::removeProperty(const PIString & _name) { for (uint i = 0; i < props.size(); ++i) if (props[i].name == _name) { diff --git a/lib/main/core/pipropertystorage.h b/lib/main/core/pipropertystorage.h index a4a8ad15..c338b968 100644 --- a/lib/main/core/pipropertystorage.h +++ b/lib/main/core/pipropertystorage.h @@ -42,13 +42,33 @@ public: struct PIP_EXPORT Property { Property(const PIString & n = PIString(), const PIString & c = PIString(), const PIVariant & v = PIVariant(), int f = 0): name(n), comment(c), value(v), flags(f) {} - + Property(const Property & o): + name(o.name), comment(o.comment), value(o.value), flags(o.flags) {} + Property(Property && o) {swap(o);} + + Property & operator =(const Property & v) { + name = v.name; + comment = v.comment; + value = v.value; + flags = v.flags; + return *this; + } + Property & operator =(Property && v) {swap(v); return *this;} + + bool toBool() const {return value.toBool();} int toInt() const {return value.toInt();} float toFloat() const {return value.toFloat();} double toDouble() const {return value.toDouble();} PIString toString() const {return value.toString();} - + + void swap(Property & o) { + name.swap(o.name); + comment.swap(o.comment); + value.swap(o.value); + piSwap(flags, o.flags); + } + /*! Uniqueue id of property */ PIString name; @@ -64,6 +84,8 @@ public: PIPropertyStorage(const PIVector & pl) {props = pl;} + PIPropertyStorage(PIVector && pl): props(std::move(pl)) {} + typedef PIVector::const_iterator const_iterator; typedef PIVector::iterator iterator; typedef Property value_type; @@ -97,6 +119,7 @@ public: * @param p to copy in storage */ void addProperty(const Property & p); + void addProperty(Property && p); /** * @brief First of all construct Property with method params. After then add property if name isn't present diff --git a/lib/main/core/pivariant.cpp b/lib/main/core/pivariant.cpp index 2281ce11..9e9da078 100644 --- a/lib/main/core/pivariant.cpp +++ b/lib/main/core/pivariant.cpp @@ -59,7 +59,7 @@ PIVariant::PIVariant() { } -PIVariant::PIVariant(const PIVariant &v) { +PIVariant::PIVariant(const PIVariant & v) { _type = v._type; _content = v._content; #ifdef CUSTOM_PIVARIANT @@ -68,6 +68,11 @@ PIVariant::PIVariant(const PIVariant &v) { } +PIVariant::PIVariant(PIVariant && v) { + swap(v); +} + + void PIVariant::setValueFromString(const PIString & v) { switch (_type) { case PIVariant::pivBool: {setValue(v.toBool());} break; @@ -108,6 +113,12 @@ PIVariant & PIVariant::operator =(const PIVariant & v) { } +PIVariant & PIVariant::operator =(PIVariant && v) { + swap(v); + return *this; +} + + bool PIVariant::operator ==(const PIVariant & v) const { return (_type == v._type) && (_content == v._content); } @@ -161,6 +172,15 @@ PIString PIVariant::typeName() const { } +void PIVariant::swap(PIVariant & v) { + piSwap(_type, v._type); + _content.swap(v._content); +#ifdef CUSTOM_PIVARIANT + piSwap(_info, v._info); +#endif +} + + PIString PIVariant::typeName(PIVariant::Type type) { switch (type) { case PIVariant::pivBool: return "Bool"; diff --git a/lib/main/core/pivariant.h b/lib/main/core/pivariant.h index f5da7ce1..bea37f17 100644 --- a/lib/main/core/pivariant.h +++ b/lib/main/core/pivariant.h @@ -247,6 +247,8 @@ public: PIVariant(const PIVariant & v); + PIVariant(PIVariant && v); + //! Constructs variant from string PIVariant(const char * v) {initType(PIString(v));} @@ -467,6 +469,8 @@ public: //! Assign operator PIVariant & operator =(const PIVariant & v); //! Assign operator + PIVariant & operator =(PIVariant && v); + //! Assign operator PIVariant & operator =(const char * v) {setValue(PIString(v)); return *this;} //! Assign operator PIVariant & operator =(const bool v) {setValue(v); return *this;} @@ -544,6 +548,8 @@ public: //! Returns \b true if type is not Invalid bool isValid() const {return _type != PIVariant::pivInvalid;} + void swap(PIVariant & v); + /** \brief Returns new variant from custom type * \details In case of known types this function equivalent \a PIVariant(T) constructors. \n diff --git a/lib/main/io_devices/pifile.cpp b/lib/main/io_devices/pifile.cpp index e0e78ec6..efbcb521 100644 --- a/lib/main/io_devices/pifile.cpp +++ b/lib/main/io_devices/pifile.cpp @@ -394,6 +394,25 @@ void PIFile::setPrecision(int prec) { } +PIFile & PIFile::put(const PIByteArray & v) { + writeBinary((int)v.size_s()); + write(v); + return *this; +} + + +PIByteArray PIFile::get() { + PIByteArray ret; + int sz(0); + read(&sz, sizeof(sz)); + if (sz > 0) { + ret.resize(sz); + read(ret.data(), sz); + } + return ret; +} + + PIFile &PIFile::operator <<(double v) { if (canWrite() && PRIVATE->fd != 0) ret = fprintf(PRIVATE->fd, ("%" + prec_str + "lf").data(), v); return *this; diff --git a/lib/main/io_devices/pifile.h b/lib/main/io_devices/pifile.h index 1f94625b..ca6d0e6b 100644 --- a/lib/main/io_devices/pifile.h +++ b/lib/main/io_devices/pifile.h @@ -145,6 +145,10 @@ public: //! Set float numbers write precision to "prec_" digits void setPrecision(int prec); + + PIFile & put(const PIByteArray & v); + + PIByteArray get(); //! Write to file binary content of "v" diff --git a/lib/main/system/pisysteminfo.cpp b/lib/main/system/pisysteminfo.cpp index bcea0873..aec6aeb2 100644 --- a/lib/main/system/pisysteminfo.cpp +++ b/lib/main/system/pisysteminfo.cpp @@ -178,7 +178,7 @@ PIVector PISystemInfo::mountInfo(bool ignore_cache) { if (l_df.size_s() < 2) return ret; l_df.pop_front(); piForeachC (PIString & s, l_df) { - PIStringList ml(s.replaceAll(" ", " ").split(" ")); + PIStringList ml(s.replacedAll(" ", " ").split(" ")); if (ml.size_s() < 2) continue; if (ml.front() == "none") continue; m.space_all = ml[1].toULLong(); From 66010c83ebbfb5aed0d9c818ebf09a106fb24343 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 11 Aug 2020 20:59:12 +0300 Subject: [PATCH 44/68] export headers workaround --- CMakeLists.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd573d11..f80396db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -112,8 +112,6 @@ macro(pip_module NAME LIBS LABEL INCLUDES MSG) if (NOT "${INCLUDES}" STREQUAL "") target_include_directories(${_target} PRIVATE ${INCLUDES}) endif() - generate_export_header(${_target}) - list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/${_target}_export.h") list(APPEND PIP_EXPORTS "${DEF_NAME}_EXPORT") target_link_libraries(${_target} ${LINK_LIBS}) list(APPEND PIP_MODULES ${_target}) @@ -384,6 +382,15 @@ set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") pip_module(main "${LIBS_MAIN}" "PIP main library" "" "") +generate_export_header(pip) +list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_export.h") +foreach(_m ${PIP_SRC_MODULES}) + set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_${_m}_EXPORTS) + generate_export_header(pip BASE_NAME "pip_${_m}") + list(APPEND HDRS "${CMAKE_CURRENT_BINARY_DIR}/pip_${_m}_export.h") +endforeach() +set_target_properties(pip PROPERTIES DEFINE_SYMBOL pip_EXPORTS) + if (NOT CROSSTOOLS) if (NOT PIP_FREERTOS) From e77d3a86a96652cbdd747863ff6375c1792aa8de Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 11 Aug 2020 21:18:51 +0300 Subject: [PATCH 45/68] opencl MacOS fix --- CMakeLists.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f80396db..d00630a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -469,7 +469,11 @@ if (NOT CROSSTOOLS) if(${CMAKE_VERSION} VERSION_LESS "3.7.0") target_link_libraries(_opencl_lib OpenCL) endif() - pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "" " (${OpenCL_VERSION_STRING})") + set(_opencl_inc "${OpenCL_INCLUDE_DIRS}") + if(APPLE) + set(_opencl_inc "${OpenCL_INCLUDE_DIRS}/Headers") + endif() + pip_module(opencl "${_opencl_lib}" "PIP OpenCL support" "${_opencl_inc}" " (${OpenCL_VERSION_STRING})") endif() From 294831df17e73c3a63a52f960c17a56ba3741191 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 12 Aug 2020 20:01:24 +0300 Subject: [PATCH 46/68] binlog user header --- CMakeLists.txt | 4 ++-- lib/main/io_devices/pibinarylog.cpp | 25 +++++++++++++++++++++++++ lib/main/io_devices/pibinarylog.h | 10 ++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d00630a9..53269b61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) -set(_PIP_MINOR 0) +set(_PIP_MINOR 1) set(_PIP_REVISION 0) -set(_PIP_SUFFIX _prealpha) +set(_PIP_SUFFIX _alpha) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/lib/main/io_devices/pibinarylog.cpp b/lib/main/io_devices/pibinarylog.cpp index c1e46d4d..ebd44728 100644 --- a/lib/main/io_devices/pibinarylog.cpp +++ b/lib/main/io_devices/pibinarylog.cpp @@ -21,6 +21,8 @@ #include "pidir.h" #include "pipropertystorage.h" +#define PIBINARYLOG_VERSION_OLD 0x31 + /*! \class PIBinaryLog * \brief Class for read and write binary data to logfile, and playback this data in realtime, or custom speed * @@ -356,6 +358,16 @@ int PIBinaryLog::readBinLog(int id, void *read_to, int max_size, PISystemTime * } +void PIBinaryLog::setHeader(const PIByteArray & header) { + user_header = header; +} + + +PIByteArray PIBinaryLog::getHeader() { + return user_header_readed; +} + + int PIBinaryLog::readDevice(void *read_to, int max_size) { if (lastrecord.id == -1 || isEnd()) return 0; if(!is_thread_ok && lastrecord.id > 0) return lastrecord.data.size(); @@ -405,12 +417,16 @@ bool PIBinaryLog::writeFileHeader() { if (file.write(&__S__PIBinaryLog::binlog_sig, PIBINARYLOG_SIGNATURE_SIZE) <= 0) return false; uchar version = PIBINARYLOG_VERSION; if (file.write(&version, 1) <= 0) return false; + uint32_t sz = user_header.size(); + file.write(&sz, 4); + file.write(user_header); file.flush(); return true; } bool PIBinaryLog::checkFileHeader() { + user_header_readed.clear(); uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE]; for (uint i=0; i 0) { + user_header_readed = file.read(sz); + } return true; } if (read_version == 0) diff --git a/lib/main/io_devices/pibinarylog.h b/lib/main/io_devices/pibinarylog.h index 6703dcf0..f9b4bab7 100644 --- a/lib/main/io_devices/pibinarylog.h +++ b/lib/main/io_devices/pibinarylog.h @@ -25,7 +25,7 @@ #include "pifile.h" -#define PIBINARYLOG_VERSION 0x31 +#define PIBINARYLOG_VERSION 0x32 namespace __S__PIBinaryLog { static const uchar binlog_sig[] = {'B','I','N','L','O','G'}; } @@ -207,7 +207,12 @@ public: //! Returns timestamp of last readed record PISystemTime lastReadedTimestamp() const {return lastrecord.timestamp;} - + //!Set custom file header, you can get it back when read this binlog + void setHeader(const PIByteArray & header); + + //!Get custom file header + PIByteArray getHeader(); + #ifdef DOXYGEN //! Read one message from binlog file, with ID contains in "filterID" or any ID, if "filterID" is empty int read(void *read_to, int max_size); @@ -321,6 +326,7 @@ private: llong split_size, log_size; int write_count, split_count, default_id, current_index; bool is_started, is_thread_ok, is_indexed, rapid_start, is_pause; + PIByteArray user_header, user_header_readed; }; //! \relatesalso PICout \relatesalso PIBinaryLog::BinLogInfo \brief Output operator to PICout From 31a347250f74198391997d06d7a0492a0eb291f6 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Thu, 13 Aug 2020 12:59:29 +0300 Subject: [PATCH 47/68] version 2.2.0 remove deprecated members PIVariantTypes::File add "is_save" flag PIBinaryLog clear --- CMakeLists.txt | 2 +- lib/main/core/pibase.h | 13 ------------- lib/main/core/pivarianttypes.h | 22 ++++++++++++---------- lib/main/io_devices/pibinarylog.cpp | 16 +++++++++++++--- lib/main/io_devices/pibinarylog.h | 9 +-------- 5 files changed, 27 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53269b61..6fddfc2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) -set(_PIP_MINOR 1) +set(_PIP_MINOR 2) set(_PIP_REVISION 0) set(_PIP_SUFFIX _alpha) set(_PIP_COMPANY SHS) diff --git a/lib/main/core/pibase.h b/lib/main/core/pibase.h index 7d31d3c8..559ded47 100644 --- a/lib/main/core/pibase.h +++ b/lib/main/core/pibase.h @@ -454,19 +454,6 @@ template<> inline float piLetobe(const float & v) { return a.f; } -DEPRECATED inline ushort letobe_s(const ushort & v) {return (v << 8) | (v >> 8);} -DEPRECATED inline uint letobe_i(const uint & v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);} - -#ifdef DOXYGEN - -/// \deprecated \brief Use \a piLetobe() instead of this function -ushort letobe_s(ushort v) {return (v << 8) | (v >> 8);} - -/// \deprecated \brief Use \a piLetobe() instead of this function -uint letobe_i(uint v) {return (v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000);} - -#endif - /// \brief Generic hash function, implements murmur3/32 algorithm inline uint piHashData(const uchar * data, uint len, uint seed = 0) { if (!data || len <= 0) return 0u; diff --git a/lib/main/core/pivarianttypes.h b/lib/main/core/pivarianttypes.h index 395ecf38..95065d57 100644 --- a/lib/main/core/pivarianttypes.h +++ b/lib/main/core/pivarianttypes.h @@ -48,7 +48,6 @@ struct PIP_EXPORT Enumerator { */ struct PIP_EXPORT Enum { Enum(const PIString & n = PIString()): enum_name(n) {} - PIString toString() const {return selected;} // obsolete /** * @brief Find selected value. @@ -123,15 +122,18 @@ struct PIP_EXPORT Enum { }; struct PIP_EXPORT File { - File(const PIString & p = PIString(), const PIString & f = PIString(), bool abs = false): file(p), filter(f), is_abs(abs) {} + File(const PIString & p = PIString(), const PIString & f = PIString(), bool abs = false, bool save_mode = false): + file(p), filter(f), is_abs(abs), is_save(save_mode) {} PIString toString() const {return file;} PIString file; PIString filter; bool is_abs; + bool is_save; }; struct PIP_EXPORT Dir { - Dir(const PIString & d = PIString(), bool abs = false): dir(d), is_abs(abs) {} + Dir(const PIString & d = PIString(), bool abs = false): + dir(d), is_abs(abs) {} PIString toString() const {return dir;} PIString dir; bool is_abs; @@ -156,27 +158,27 @@ struct PIP_EXPORT IODevice { } inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enumerator & v) {s << v.value << v.name; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enumerator & v) {s >> v.value >> v.name; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enumerator & v) {s >> v.value >> v.name; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Enumerator & v) {s << v.name << "(" << v.value << ")"; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Enum & v) {s << v.enum_name << v.selected << v.enum_list; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enum & v) {s >> v.enum_name >> v.selected >> v.enum_list; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Enum & v) {s >> v.enum_name >> v.selected >> v.enum_list; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Enum & v) {s << "Enum(" << v.selectedValue() << "=" << v.selectedName() << ")"; return s;} -inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::File & v) {s << v.file << v.filter << v.is_abs; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::File & v) {s >> v.file >> v.filter >> v.is_abs; return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::File & v) {s << v.file << v.filter << uchar((v.is_abs ? 1 : 0) + (v.is_save ? 2 : 0)); return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::File & v) {uchar f(0); s >> v.file >> v.filter >> f; v.is_abs = ((f & 1) == 1); v.is_save = ((f & 2) == 2); return s;} inline PICout operator <<(PICout s, const PIVariantTypes::File & v) {s << "File(\"" << v.file << "\")"; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Dir & v) {s << v.dir << v.is_abs; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Dir & v) {s >> v.dir >> v.is_abs; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Dir & v) {s >> v.dir >> v.is_abs; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Dir & v) {s << "Dir(\"" << v.dir << "\")"; return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::Color & v) {s << v.rgba; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Color & v) {s >> v.rgba; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::Color & v) {s >> v.rgba; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::Color & v) {s.saveControl(); s << PICoutManipulators::Hex << "Color(#" << v.rgba << ")"; s.restoreControl(); return s;} inline PIByteArray & operator <<(PIByteArray & s, const PIVariantTypes::IODevice & v) {s << v.prefix << v.mode << v.options << v.props; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::IODevice & v) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIVariantTypes::IODevice & v) {s >> v.prefix >> v.mode >> v.options >> v.props; return s;} inline PICout operator <<(PICout s, const PIVariantTypes::IODevice & v) {s << v.toPICout(); return s;} #endif // PIVARIANTYPES_H diff --git a/lib/main/io_devices/pibinarylog.cpp b/lib/main/io_devices/pibinarylog.cpp index ebd44728..2fd71564 100644 --- a/lib/main/io_devices/pibinarylog.cpp +++ b/lib/main/io_devices/pibinarylog.cpp @@ -45,6 +45,11 @@ * */ +static const uchar binlog_sig[] = {'B','I','N','L','O','G'}; + +#define PIBINARYLOG_VERSION 0x32 +#define PIBINARYLOG_SIGNATURE_SIZE sizeof(binlog_sig) + REGISTER_DEVICE(PIBinaryLog) PIBinaryLog::PIBinaryLog() { @@ -358,6 +363,11 @@ int PIBinaryLog::readBinLog(int id, void *read_to, int max_size, PISystemTime * } +bool PIBinaryLog::isEmpty() const { + return (log_size <= llong(PIBINARYLOG_SIGNATURE_SIZE + 1)); +} + + void PIBinaryLog::setHeader(const PIByteArray & header) { user_header = header; } @@ -414,7 +424,7 @@ void PIBinaryLog::restart() { bool PIBinaryLog::writeFileHeader() { - if (file.write(&__S__PIBinaryLog::binlog_sig, PIBINARYLOG_SIGNATURE_SIZE) <= 0) return false; + if (file.write(binlog_sig, PIBINARYLOG_SIGNATURE_SIZE) <= 0) return false; uchar version = PIBINARYLOG_VERSION; if (file.write(&version, 1) <= 0) return false; uint32_t sz = user_header.size(); @@ -432,7 +442,7 @@ bool PIBinaryLog::checkFileHeader() { if (file.read(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) return false; bool correct = true; for (uint i=0; iread(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) {if (ginfo) bi->records_count = -1; ok = false;} for (uint i=0; irecords_count = -2; ok = false;} + if (read_sig[i] != binlog_sig[i]) {if (ginfo) bi->records_count = -2; ok = false;} uchar read_version = 0; if (f->read(&read_version, 1) < 0) {if (ginfo) bi->records_count = -3; ok = false;} if (read_version == 0) {if (ginfo) bi->records_count = -4; ok = false;} diff --git a/lib/main/io_devices/pibinarylog.h b/lib/main/io_devices/pibinarylog.h index f9b4bab7..13ee83d5 100644 --- a/lib/main/io_devices/pibinarylog.h +++ b/lib/main/io_devices/pibinarylog.h @@ -25,14 +25,7 @@ #include "pifile.h" -#define PIBINARYLOG_VERSION 0x32 -namespace __S__PIBinaryLog { -static const uchar binlog_sig[] = {'B','I','N','L','O','G'}; -} -#define PIBINARYLOG_SIGNATURE_SIZE sizeof(__S__PIBinaryLog::binlog_sig) -/// TODO: Create static functions to join binlog files -/// TODO: Create functions to insert and delete records class PIP_EXPORT PIBinaryLog: public PIIODevice { PIIODEVICE(PIBinaryLog) @@ -196,7 +189,7 @@ public: bool isEnd() const {if (isClosed()) return true; return file.isEnd();} //! Returns if BinLog file is empty - bool isEmpty() const {return (log_size <= llong(PIBINARYLOG_SIGNATURE_SIZE + 1));} + bool isEmpty() const; //! Returns BinLog pause status bool isPause() const {return is_pause;} From e76a07a3f359122aa5f00d0d5774ee326b75d29e Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 13 Aug 2020 18:03:25 +0300 Subject: [PATCH 48/68] binlog fixes --- lib/main/io_devices/pibinarylog.cpp | 60 +++++++++++++++-------------- lib/main/io_devices/pibinarylog.h | 3 +- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/lib/main/io_devices/pibinarylog.cpp b/lib/main/io_devices/pibinarylog.cpp index 2fd71564..bae32580 100644 --- a/lib/main/io_devices/pibinarylog.cpp +++ b/lib/main/io_devices/pibinarylog.cpp @@ -374,7 +374,7 @@ void PIBinaryLog::setHeader(const PIByteArray & header) { PIByteArray PIBinaryLog::getHeader() { - return user_header_readed; + return binfo.user_header; } @@ -436,7 +436,7 @@ bool PIBinaryLog::writeFileHeader() { bool PIBinaryLog::checkFileHeader() { - user_header_readed.clear(); + binfo.user_header.clear(); uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE]; for (uint i=0; i 0) { - user_header_readed = file.read(sz); + binfo.user_header = file.read(sz); } return true; } @@ -505,33 +505,37 @@ PIBinaryLog::BinLogRecord PIBinaryLog::readRecord() { void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector * index) { - BinLogInfo * bi = info; - bool ginfo = info != 0; - bool gindex = index != 0; - if (!ginfo && !gindex) return; - if (ginfo) { - bi->log_size = -1; - bi->records_count = 0; - bi->records.clear(); + if (!info && !index) return; + if (info) { + info->log_size = -1; + info->records_count = 0; + info->records.clear(); } - if (gindex) index->clear(); + if (index) index->clear(); if (f == 0) return; if (!f->canRead()) return; - if (ginfo) { - bi->path = f->path(); - bi->log_size = f->size(); + if (info) { + info->path = f->path(); + info->log_size = f->size(); } uchar read_sig[PIBINARYLOG_SIGNATURE_SIZE]; for (uint i=0; iread(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) {if (ginfo) bi->records_count = -1; ok = false;} + if (f->read(read_sig, PIBINARYLOG_SIGNATURE_SIZE) < 0) {if (info) info->records_count = -1; ok = false;} for (uint i=0; irecords_count = -2; ok = false;} + if (read_sig[i] != binlog_sig[i]) {if (info) info->records_count = -2; ok = false;} uchar read_version = 0; - if (f->read(&read_version, 1) < 0) {if (ginfo) bi->records_count = -3; ok = false;} - if (read_version == 0) {if (ginfo) bi->records_count = -4; ok = false;} - if (read_version < PIBINARYLOG_VERSION) {if (ginfo) bi->records_count = -5; ok = false;} - if (read_version > PIBINARYLOG_VERSION) {if (ginfo) bi->records_count = -6; ok = false;} + if (f->read(&read_version, 1) < 0) {if (info) info->records_count = -3; ok = false;} + if (read_version == 0) {if (info) info->records_count = -4; ok = false;} + if (read_version < PIBINARYLOG_VERSION_OLD) {if (info) info->records_count = -5; ok = false;} + if (read_version > PIBINARYLOG_VERSION) {if (info) info->records_count = -6; ok = false;} + if (read_version == PIBINARYLOG_VERSION) { + uint32_t sz = 0; + f->read(&sz, 4); + if (sz > 0 && info) { + info->user_header = f->read(sz); + } + } if (!ok) return; PIByteArray ba; BinLogRecord br; @@ -545,26 +549,26 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector< ba >> br.id >> br.size >> br.timestamp; } else break; - if (bi->log_size - f->pos() >= br.size) + if (info->log_size - f->pos() >= br.size) f->seek(f->pos() + br.size); else break; } if (br.id > 0) { - if (gindex) { + if (info) { BinLogIndex bl_ind; bl_ind.id = br.id; bl_ind.pos = f->pos() - br.size - hdr_size; bl_ind.timestamp = br.timestamp; index->append(bl_ind); } - if (ginfo) { - bi->records_count++; + if (info) { + info->records_count++; if (first) { - bi->start_time = br.timestamp; + info->start_time = br.timestamp; first = false; } - BinLogRecordInfo &bri(bi->records[br.id]); + BinLogRecordInfo &bri(info->records[br.id]); bri.count++; if (bri.id == 0) { bri.id = br.id; @@ -578,7 +582,7 @@ void PIBinaryLog::parseLog(PIFile * f, PIBinaryLog::BinLogInfo * info, PIVector< } } } - if (ginfo) bi->end_time = br.timestamp; + if (info) info->end_time = br.timestamp; } diff --git a/lib/main/io_devices/pibinarylog.h b/lib/main/io_devices/pibinarylog.h index 13ee83d5..9a835c4b 100644 --- a/lib/main/io_devices/pibinarylog.h +++ b/lib/main/io_devices/pibinarylog.h @@ -70,6 +70,7 @@ public: PISystemTime start_time; PISystemTime end_time; PIMap records; + PIByteArray user_header; }; //! \brief Struct contains position, ID and timestamp of record in file @@ -319,7 +320,7 @@ private: llong split_size, log_size; int write_count, split_count, default_id, current_index; bool is_started, is_thread_ok, is_indexed, rapid_start, is_pause; - PIByteArray user_header, user_header_readed; + PIByteArray user_header; }; //! \relatesalso PICout \relatesalso PIBinaryLog::BinLogInfo \brief Output operator to PICout From 31f0d881570880a73b6b4bdef5708de58570651d Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 14 Aug 2020 18:00:28 +0300 Subject: [PATCH 49/68] version 2.2.1 std::initializer_list supports for vector and dequeue --- CMakeLists.txt | 2 +- doc/examples/picontainers.cpp | 3 +++ lib/main/containers/picontainers.cpp | 4 ++++ lib/main/containers/picontainers.h | 1 + lib/main/containers/pideque.h | 6 ++++++ lib/main/containers/pivector.h | 6 ++++++ 6 files changed, 21 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fddfc2c..1c760cfd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) set(_PIP_MINOR 2) -set(_PIP_REVISION 0) +set(_PIP_REVISION 1) set(_PIP_SUFFIX _alpha) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/doc/examples/picontainers.cpp b/doc/examples/picontainers.cpp index c83cf1ea..2d058037 100644 --- a/doc/examples/picontainers.cpp +++ b/doc/examples/picontainers.cpp @@ -49,6 +49,9 @@ PIVector vec(4u, 'p'); piForeachC (char i, vec) cout << i << ", "; // p, p, p, p, + +piCout << PIVector({1, 2, 3}); +// 1, 2, 3 //! [PIVector::PIVector] //! [PIVector::at_c] PIVector vec; diff --git a/lib/main/containers/picontainers.cpp b/lib/main/containers/picontainers.cpp index a6533554..823cd5c4 100644 --- a/lib/main/containers/picontainers.cpp +++ b/lib/main/containers/picontainers.cpp @@ -32,6 +32,10 @@ * \brief Contructs vector with size "size" filled elements "value" * \details Example: \snippet picontainers.cpp PIVector::PIVector + * \fn PIVector::PIVector(std::initializer_list list); + * \brief Contructs vector from C++11 initializer list + * \details Example: \snippet picontainers.cpp PIVector::PIVector + * \fn const T & PIVector::at(size_t index) const; * \brief Read-only access to element by index "index" * \details Example: \snippet picontainers.cpp PIVector::at_c diff --git a/lib/main/containers/picontainers.h b/lib/main/containers/picontainers.h index 0487c892..014ddfe6 100644 --- a/lib/main/containers/picontainers.h +++ b/lib/main/containers/picontainers.h @@ -42,6 +42,7 @@ #else # include #endif +#include #include #include #ifndef PIP_MEMALIGN_BYTES diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index 6efead6f..9d7ffdcb 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -39,6 +39,11 @@ public: alloc(other.pid_size, true); newT(pid_data + pid_start, other.pid_data + other.pid_start, pid_size); } + inline PIDeque(std::initializer_list init_list): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { + PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) + alloc(init_list.size(), true); + newT(pid_data, init_list.begin(), init_list.size()); + } inline PIDeque(const T * data, size_t size): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) alloc(size, true); @@ -49,6 +54,7 @@ public: resize(pid_size, f); } inline PIDeque(PIDeque && other): pid_data(other.pid_data), pid_size(other.pid_size), pid_rsize(other.pid_rsize), pid_start(other.pid_start) { + PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) other._reset(); } inline virtual ~PIDeque() { diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index e41aeaea..1dce7786 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -44,11 +44,17 @@ public: alloc(other.piv_size); newT(piv_data, other.piv_data, piv_size); } + inline PIVector(std::initializer_list init_list): piv_data(0), piv_size(0), piv_rsize(0) { + PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) + alloc(init_list.size()); + newT(piv_data, init_list.begin(), init_list.size()); + } inline PIVector(size_t piv_size, const T & f = T()): piv_data(0), piv_size(0), piv_rsize(0) { PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(piv_size, f); } inline PIVector(PIVector && other): piv_data(other.piv_data), piv_size(other.piv_size), piv_rsize(other.piv_rsize) { + PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) other._reset(); } inline virtual ~PIVector() { From 9834ac177bfae3f0bfa14c083e3857560ec59b38 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Sat, 15 Aug 2020 21:24:57 +0300 Subject: [PATCH 50/68] debian version fix, "Maj.Min.Rev-Build-suffix" instead of "Maj.Min.Rev-suffix-Build" --- cmake/DeployMacros.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/DeployMacros.cmake b/cmake/DeployMacros.cmake index 057cc9a6..741351d0 100644 --- a/cmake/DeployMacros.cmake +++ b/cmake/DeployMacros.cmake @@ -659,7 +659,8 @@ macro(deploy_target _T) set(_TARGET_OS "linux") endif() string(REPLACE "_" "-" _DEBNAME "${_T}") - string(REPLACE "_" "-" _DEBVERSION "${${_T}_VERSION}${_build}+${_TARGET_OS}") + set(_DEBVERSION "${${_T}_VERSION_MAJOR}.${${_T}_VERSION_MINOR}.${${_T}_VERSION_REVISION}${_build}${${_T}_VERSION_FULLSUFFIX}+${_TARGET_OS}") + string(REPLACE "_" "-" _DEBVERSION "${_DEBVERSION}") string(TOLOWER "${_DEBNAME}" _DEBNAME) set(_DEB_ARCH) if("_${MY_ARCH}" STREQUAL "_arm64") From c582d8ff4690662ba24197f2d064ea5e269b2ee9 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Tue, 18 Aug 2020 22:58:30 +0300 Subject: [PATCH 51/68] PIStringList new constructor --- CMakeLists.txt | 2 +- lib/main/core/pistringlist.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c760cfd..caa137f9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) set(_PIP_MINOR 2) -set(_PIP_REVISION 1) +set(_PIP_REVISION 2) set(_PIP_SUFFIX _alpha) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/lib/main/core/pistringlist.h b/lib/main/core/pistringlist.h index e5a9210e..ce2bb7e8 100644 --- a/lib/main/core/pistringlist.h +++ b/lib/main/core/pistringlist.h @@ -56,6 +56,9 @@ public: PIStringList(const PIVector & o): PIDeque() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];} PIStringList(const PIDeque & o): PIDeque() {resize(o.size()); for (uint i = 0; i < size(); ++i) (*this)[i] = o[i];} + //! Contructs strings list with std::initializer_list + PIStringList(std::initializer_list init_list): PIDeque(init_list) {} + //! \brief Join all strings in one with delimiter "delim" and return it //! \details Example: \snippet pistring.cpp PIStringList::join From ccd6a9888f0b77834fd01dd278f2f1022fa6db58 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 19 Aug 2020 00:47:05 +0300 Subject: [PATCH 52/68] tree changes --- CMakeLists.txt | 40 ++++++++++++++----- {lib => libs}/cloud/piccloudclient.cpp | 0 {lib => libs}/cloud/piccloudserver.cpp | 0 {lib => libs}/cloud/piccloudtcp.cpp | 0 {lib => libs}/compress/picompress.cpp | 0 {lib => libs}/console/piscreen.cpp | 0 {lib => libs}/console/piscreenconsole.cpp | 0 {lib => libs}/console/piscreendrawer.cpp | 0 {lib => libs}/console/piscreentile.cpp | 0 {lib => libs}/console/piscreentiles.cpp | 0 {lib => libs}/console/piterminal.cpp | 0 {lib => libs}/crypt/piauth.cpp | 0 {lib => libs}/crypt/picrypt.cpp | 0 {lib => libs}/fftw/pifft.cpp | 0 {lib => libs}/fftw/pifft_p.h | 0 {lib => libs}/io_utils/pibroadcast.cpp | 0 {lib => libs}/io_utils/piethutilbase.cpp | 0 {lib => libs}/io_utils/pistreampacker.cpp | 0 {lib => libs}/lua/3rd/LuaBridge/List.h | 0 {lib => libs}/lua/3rd/LuaBridge/LuaBridge.h | 0 {lib => libs}/lua/3rd/LuaBridge/Map.h | 0 .../lua/3rd/LuaBridge/RefCountedObject.h | 0 .../lua/3rd/LuaBridge/RefCountedPtr.h | 0 .../lua/3rd/LuaBridge/UnorderedMap.h | 0 {lib => libs}/lua/3rd/LuaBridge/Vector.h | 0 .../lua/3rd/LuaBridge/detail/CFunctions.h | 0 .../lua/3rd/LuaBridge/detail/ClassInfo.h | 0 .../lua/3rd/LuaBridge/detail/Config.h | 0 .../lua/3rd/LuaBridge/detail/Constructor.h | 0 .../lua/3rd/LuaBridge/detail/FuncTraits.h | 0 .../lua/3rd/LuaBridge/detail/Iterator.h | 0 .../lua/3rd/LuaBridge/detail/LuaException.h | 0 .../lua/3rd/LuaBridge/detail/LuaHelpers.h | 0 .../lua/3rd/LuaBridge/detail/LuaRef.h | 0 .../lua/3rd/LuaBridge/detail/Namespace.h | 0 .../lua/3rd/LuaBridge/detail/Security.h | 0 .../lua/3rd/LuaBridge/detail/Stack.h | 0 .../lua/3rd/LuaBridge/detail/TypeList.h | 0 .../lua/3rd/LuaBridge/detail/TypeTraits.h | 0 .../lua/3rd/LuaBridge/detail/Userdata.h | 0 {lib => libs}/lua/3rd/LuaBridge/detail/dump.h | 0 {lib => libs}/lua/piluaprogram.cpp | 0 {lib => libs}/main/cloud/piccloudclient.h | 0 {lib => libs}/main/cloud/piccloudmodule.h | 0 {lib => libs}/main/cloud/piccloudserver.h | 0 {lib => libs}/main/cloud/piccloudtcp.h | 0 {lib => libs}/main/code/picodeinfo.cpp | 0 {lib => libs}/main/code/picodeinfo.h | 0 {lib => libs}/main/code/picodemodule.h | 0 {lib => libs}/main/code/picodeparser.cpp | 0 {lib => libs}/main/code/picodeparser.h | 0 {lib => libs}/main/compress/picompress.h | 0 {lib => libs}/main/console/piconsolemodule.h | 0 {lib => libs}/main/console/pikbdlistener.cpp | 0 {lib => libs}/main/console/pikbdlistener.h | 0 {lib => libs}/main/console/piscreen.h | 0 {lib => libs}/main/console/piscreenconsole.h | 0 {lib => libs}/main/console/piscreendrawer.h | 0 {lib => libs}/main/console/piscreentile.h | 0 {lib => libs}/main/console/piscreentiles.h | 0 {lib => libs}/main/console/piscreentypes.h | 0 {lib => libs}/main/console/piterminal.h | 0 .../main/containers/picontainers.cpp | 0 {lib => libs}/main/containers/picontainers.h | 0 .../main/containers/picontainersmodule.h | 0 {lib => libs}/main/containers/pideque.h | 0 {lib => libs}/main/containers/pimap.h | 0 {lib => libs}/main/containers/pipair.h | 0 {lib => libs}/main/containers/piqueue.h | 0 {lib => libs}/main/containers/piset.h | 0 {lib => libs}/main/containers/pistack.h | 0 {lib => libs}/main/containers/pivector.h | 0 {lib => libs}/main/containers/pivector2d.h | 0 {lib => libs}/main/core/pibase.h | 0 {lib => libs}/main/core/pibitarray.cpp | 0 {lib => libs}/main/core/pibitarray.h | 0 {lib => libs}/main/core/pibytearray.cpp | 0 {lib => libs}/main/core/pibytearray.h | 0 {lib => libs}/main/core/pichar.cpp | 0 {lib => libs}/main/core/pichar.h | 0 {lib => libs}/main/core/pichunkstream.cpp | 0 {lib => libs}/main/core/pichunkstream.h | 0 {lib => libs}/main/core/picli.cpp | 0 {lib => libs}/main/core/picli.h | 0 {lib => libs}/main/core/picollection.cpp | 0 {lib => libs}/main/core/picollection.h | 0 {lib => libs}/main/core/picoremodule.h | 0 {lib => libs}/main/core/picout.cpp | 0 {lib => libs}/main/core/picout.h | 0 {lib => libs}/main/core/piflags.h | 0 {lib => libs}/main/core/piincludes.cpp | 0 {lib => libs}/main/core/piincludes.h | 0 {lib => libs}/main/core/piincludes_p.h | 0 {lib => libs}/main/core/piinit.cpp | 0 {lib => libs}/main/core/piinit.h | 0 {lib => libs}/main/core/piobject.cpp | 0 {lib => libs}/main/core/piobject.h | 0 {lib => libs}/main/core/pipropertystorage.cpp | 0 {lib => libs}/main/core/pipropertystorage.h | 0 {lib => libs}/main/core/pistring.cpp | 0 {lib => libs}/main/core/pistring.h | 0 {lib => libs}/main/core/pistring_std.h | 0 {lib => libs}/main/core/pistringlist.cpp | 0 {lib => libs}/main/core/pistringlist.h | 0 {lib => libs}/main/core/pitime.cpp | 0 {lib => libs}/main/core/pitime.h | 0 {lib => libs}/main/core/pitime_win.h | 0 {lib => libs}/main/core/pivariant.cpp | 0 {lib => libs}/main/core/pivariant.h | 0 {lib => libs}/main/core/pivarianttypes.cpp | 0 {lib => libs}/main/core/pivarianttypes.h | 0 {lib => libs}/main/crypt/piauth.h | 0 {lib => libs}/main/crypt/picrypt.h | 0 {lib => libs}/main/crypt/picryptmodule.h | 0 {lib => libs}/main/geo/piellipsoidmodel.cpp | 0 {lib => libs}/main/geo/piellipsoidmodel.h | 0 {lib => libs}/main/geo/pigeomodule.h | 0 {lib => libs}/main/geo/pigeoposition.cpp | 0 {lib => libs}/main/geo/pigeoposition.h | 0 .../main/introspection/piintrospection_base.h | 0 .../piintrospection_containers.cpp | 0 .../piintrospection_containers.h | 0 .../piintrospection_containers_p.cpp | 0 .../piintrospection_containers_p.h | 0 .../introspection/piintrospection_server.cpp | 0 .../introspection/piintrospection_server.h | 0 .../piintrospection_server_p.cpp | 0 .../introspection/piintrospection_server_p.h | 0 .../introspection/piintrospection_threads.cpp | 0 .../introspection/piintrospection_threads.h | 0 .../piintrospection_threads_p.cpp | 0 .../introspection/piintrospection_threads_p.h | 0 {lib => libs}/main/io_devices/pibinarylog.cpp | 0 {lib => libs}/main/io_devices/pibinarylog.h | 0 {lib => libs}/main/io_devices/pican.cpp | 0 {lib => libs}/main/io_devices/pican.h | 0 {lib => libs}/main/io_devices/piconfig.cpp | 0 {lib => libs}/main/io_devices/piconfig.h | 0 {lib => libs}/main/io_devices/pidir.cpp | 0 {lib => libs}/main/io_devices/pidir.h | 0 {lib => libs}/main/io_devices/piethernet.cpp | 0 {lib => libs}/main/io_devices/piethernet.h | 0 {lib => libs}/main/io_devices/pifile.cpp | 0 {lib => libs}/main/io_devices/pifile.h | 0 {lib => libs}/main/io_devices/pigpio.cpp | 0 {lib => libs}/main/io_devices/pigpio.h | 0 .../main/io_devices/piiobytearray.cpp | 0 {lib => libs}/main/io_devices/piiobytearray.h | 0 {lib => libs}/main/io_devices/piiodevice.cpp | 0 {lib => libs}/main/io_devices/piiodevice.h | 0 .../main/io_devices/piiodevicesmodule.h | 0 {lib => libs}/main/io_devices/piiostring.cpp | 0 {lib => libs}/main/io_devices/piiostring.h | 0 {lib => libs}/main/io_devices/pipeer.cpp | 0 {lib => libs}/main/io_devices/pipeer.h | 0 {lib => libs}/main/io_devices/piserial.cpp | 0 {lib => libs}/main/io_devices/piserial.h | 0 .../main/io_devices/pisharedmemory.cpp | 0 .../main/io_devices/pisharedmemory.h | 0 {lib => libs}/main/io_devices/pispi.cpp | 0 {lib => libs}/main/io_devices/pispi.h | 0 .../main/io_devices/pitransparentdevice.cpp | 0 .../main/io_devices/pitransparentdevice.h | 0 {lib => libs}/main/io_devices/piusb.h | 0 .../main/io_utils/pibasetransfer.cpp | 0 {lib => libs}/main/io_utils/pibasetransfer.h | 0 {lib => libs}/main/io_utils/pibroadcast.h | 0 {lib => libs}/main/io_utils/piconnection.cpp | 0 {lib => libs}/main/io_utils/piconnection.h | 0 .../main/io_utils/pidatatransfer.cpp | 0 {lib => libs}/main/io_utils/pidatatransfer.h | 0 {lib => libs}/main/io_utils/pidiagnostics.cpp | 0 {lib => libs}/main/io_utils/pidiagnostics.h | 0 {lib => libs}/main/io_utils/piethutilbase.h | 0 .../main/io_utils/pifiletransfer.cpp | 0 {lib => libs}/main/io_utils/pifiletransfer.h | 0 {lib => libs}/main/io_utils/piioutilsmodule.h | 0 .../main/io_utils/pipacketextractor.cpp | 0 .../main/io_utils/pipacketextractor.h | 0 {lib => libs}/main/io_utils/pistreampacker.h | 0 {lib => libs}/main/lua/piluaprogram.h | 0 {lib => libs}/main/lua/pip_lua.h | 0 {lib => libs}/main/math/picrc.h | 0 {lib => libs}/main/math/pievaluator.cpp | 0 {lib => libs}/main/math/pievaluator.h | 0 {lib => libs}/main/math/pifft.cpp | 0 {lib => libs}/main/math/pifft.h | 0 {lib => libs}/main/math/pigeometry.h | 0 {lib => libs}/main/math/pimathbase.cpp | 0 {lib => libs}/main/math/pimathbase.h | 0 {lib => libs}/main/math/pimathcomplex.h | 0 {lib => libs}/main/math/pimathmatrix.h | 0 {lib => libs}/main/math/pimathmodule.h | 0 {lib => libs}/main/math/pimathsolver.cpp | 0 {lib => libs}/main/math/pimathsolver.h | 0 {lib => libs}/main/math/pimathvector.h | 0 {lib => libs}/main/math/piquaternion.cpp | 0 {lib => libs}/main/math/piquaternion.h | 0 {lib => libs}/main/math/pistatistic.h | 0 {lib => libs}/main/opencl/piopencl.h | 0 {lib => libs}/main/pip.h | 0 {lib => libs}/main/piplatform.h | 0 {lib => libs}/main/resources/piresources.cpp | 0 {lib => libs}/main/resources/piresources.h | 0 .../main/resources/piresourcesstorage.cpp | 0 .../main/resources/piresourcesstorage.h | 0 {lib => libs}/main/system/pilibrary.cpp | 0 {lib => libs}/main/system/pilibrary.h | 0 {lib => libs}/main/system/piprocess.cpp | 0 {lib => libs}/main/system/piprocess.h | 0 {lib => libs}/main/system/pisignals.cpp | 0 {lib => libs}/main/system/pisignals.h | 0 .../main/system/pisingleapplication.cpp | 0 .../main/system/pisingleapplication.h | 0 {lib => libs}/main/system/pisysteminfo.cpp | 0 {lib => libs}/main/system/pisysteminfo.h | 0 {lib => libs}/main/system/pisystemmodule.h | 0 {lib => libs}/main/system/pisystemmonitor.cpp | 0 {lib => libs}/main/system/pisystemmonitor.h | 0 {lib => libs}/main/system/pisystemtests.cpp | 0 {lib => libs}/main/system/pisystemtests.h | 0 {lib => libs}/main/thread/piblockingqueue.h | 0 {lib => libs}/main/thread/piconditionvar.cpp | 0 {lib => libs}/main/thread/piconditionvar.h | 0 {lib => libs}/main/thread/pigrabberbase.h | 0 {lib => libs}/main/thread/pimutex.cpp | 0 {lib => libs}/main/thread/pimutex.h | 0 {lib => libs}/main/thread/pipipelinethread.h | 0 {lib => libs}/main/thread/pithread.cpp | 0 {lib => libs}/main/thread/pithread.h | 0 {lib => libs}/main/thread/pithreadmodule.h | 0 .../main/thread/pithreadpoolexecutor.cpp | 0 .../main/thread/pithreadpoolexecutor.h | 0 {lib => libs}/main/thread/pitimer.cpp | 0 {lib => libs}/main/thread/pitimer.h | 0 {lib => libs}/opencl/3rd/clcomplex.h | 0 {lib => libs}/opencl/piopencl.cpp | 0 {lib => libs}/opencl/resources.conf | 0 {lib => libs}/usb/piusb.cpp | 0 utils/piterminal/main.cpp | 2 +- 240 files changed, 30 insertions(+), 12 deletions(-) rename {lib => libs}/cloud/piccloudclient.cpp (100%) rename {lib => libs}/cloud/piccloudserver.cpp (100%) rename {lib => libs}/cloud/piccloudtcp.cpp (100%) rename {lib => libs}/compress/picompress.cpp (100%) rename {lib => libs}/console/piscreen.cpp (100%) rename {lib => libs}/console/piscreenconsole.cpp (100%) rename {lib => libs}/console/piscreendrawer.cpp (100%) rename {lib => libs}/console/piscreentile.cpp (100%) rename {lib => libs}/console/piscreentiles.cpp (100%) rename {lib => libs}/console/piterminal.cpp (100%) rename {lib => libs}/crypt/piauth.cpp (100%) rename {lib => libs}/crypt/picrypt.cpp (100%) rename {lib => libs}/fftw/pifft.cpp (100%) rename {lib => libs}/fftw/pifft_p.h (100%) rename {lib => libs}/io_utils/pibroadcast.cpp (100%) rename {lib => libs}/io_utils/piethutilbase.cpp (100%) rename {lib => libs}/io_utils/pistreampacker.cpp (100%) rename {lib => libs}/lua/3rd/LuaBridge/List.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/LuaBridge.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/Map.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/RefCountedObject.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/RefCountedPtr.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/UnorderedMap.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/Vector.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/CFunctions.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/ClassInfo.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Config.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Constructor.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/FuncTraits.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Iterator.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/LuaException.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/LuaHelpers.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/LuaRef.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Namespace.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Security.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Stack.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/TypeList.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/TypeTraits.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/Userdata.h (100%) rename {lib => libs}/lua/3rd/LuaBridge/detail/dump.h (100%) rename {lib => libs}/lua/piluaprogram.cpp (100%) rename {lib => libs}/main/cloud/piccloudclient.h (100%) rename {lib => libs}/main/cloud/piccloudmodule.h (100%) rename {lib => libs}/main/cloud/piccloudserver.h (100%) rename {lib => libs}/main/cloud/piccloudtcp.h (100%) rename {lib => libs}/main/code/picodeinfo.cpp (100%) rename {lib => libs}/main/code/picodeinfo.h (100%) rename {lib => libs}/main/code/picodemodule.h (100%) rename {lib => libs}/main/code/picodeparser.cpp (100%) rename {lib => libs}/main/code/picodeparser.h (100%) rename {lib => libs}/main/compress/picompress.h (100%) rename {lib => libs}/main/console/piconsolemodule.h (100%) rename {lib => libs}/main/console/pikbdlistener.cpp (100%) rename {lib => libs}/main/console/pikbdlistener.h (100%) rename {lib => libs}/main/console/piscreen.h (100%) rename {lib => libs}/main/console/piscreenconsole.h (100%) rename {lib => libs}/main/console/piscreendrawer.h (100%) rename {lib => libs}/main/console/piscreentile.h (100%) rename {lib => libs}/main/console/piscreentiles.h (100%) rename {lib => libs}/main/console/piscreentypes.h (100%) rename {lib => libs}/main/console/piterminal.h (100%) rename {lib => libs}/main/containers/picontainers.cpp (100%) rename {lib => libs}/main/containers/picontainers.h (100%) rename {lib => libs}/main/containers/picontainersmodule.h (100%) rename {lib => libs}/main/containers/pideque.h (100%) rename {lib => libs}/main/containers/pimap.h (100%) rename {lib => libs}/main/containers/pipair.h (100%) rename {lib => libs}/main/containers/piqueue.h (100%) rename {lib => libs}/main/containers/piset.h (100%) rename {lib => libs}/main/containers/pistack.h (100%) rename {lib => libs}/main/containers/pivector.h (100%) rename {lib => libs}/main/containers/pivector2d.h (100%) rename {lib => libs}/main/core/pibase.h (100%) rename {lib => libs}/main/core/pibitarray.cpp (100%) rename {lib => libs}/main/core/pibitarray.h (100%) rename {lib => libs}/main/core/pibytearray.cpp (100%) rename {lib => libs}/main/core/pibytearray.h (100%) rename {lib => libs}/main/core/pichar.cpp (100%) rename {lib => libs}/main/core/pichar.h (100%) rename {lib => libs}/main/core/pichunkstream.cpp (100%) rename {lib => libs}/main/core/pichunkstream.h (100%) rename {lib => libs}/main/core/picli.cpp (100%) rename {lib => libs}/main/core/picli.h (100%) rename {lib => libs}/main/core/picollection.cpp (100%) rename {lib => libs}/main/core/picollection.h (100%) rename {lib => libs}/main/core/picoremodule.h (100%) rename {lib => libs}/main/core/picout.cpp (100%) rename {lib => libs}/main/core/picout.h (100%) rename {lib => libs}/main/core/piflags.h (100%) rename {lib => libs}/main/core/piincludes.cpp (100%) rename {lib => libs}/main/core/piincludes.h (100%) rename {lib => libs}/main/core/piincludes_p.h (100%) rename {lib => libs}/main/core/piinit.cpp (100%) rename {lib => libs}/main/core/piinit.h (100%) rename {lib => libs}/main/core/piobject.cpp (100%) rename {lib => libs}/main/core/piobject.h (100%) rename {lib => libs}/main/core/pipropertystorage.cpp (100%) rename {lib => libs}/main/core/pipropertystorage.h (100%) rename {lib => libs}/main/core/pistring.cpp (100%) rename {lib => libs}/main/core/pistring.h (100%) rename {lib => libs}/main/core/pistring_std.h (100%) rename {lib => libs}/main/core/pistringlist.cpp (100%) rename {lib => libs}/main/core/pistringlist.h (100%) rename {lib => libs}/main/core/pitime.cpp (100%) rename {lib => libs}/main/core/pitime.h (100%) rename {lib => libs}/main/core/pitime_win.h (100%) rename {lib => libs}/main/core/pivariant.cpp (100%) rename {lib => libs}/main/core/pivariant.h (100%) rename {lib => libs}/main/core/pivarianttypes.cpp (100%) rename {lib => libs}/main/core/pivarianttypes.h (100%) rename {lib => libs}/main/crypt/piauth.h (100%) rename {lib => libs}/main/crypt/picrypt.h (100%) rename {lib => libs}/main/crypt/picryptmodule.h (100%) rename {lib => libs}/main/geo/piellipsoidmodel.cpp (100%) rename {lib => libs}/main/geo/piellipsoidmodel.h (100%) rename {lib => libs}/main/geo/pigeomodule.h (100%) rename {lib => libs}/main/geo/pigeoposition.cpp (100%) rename {lib => libs}/main/geo/pigeoposition.h (100%) rename {lib => libs}/main/introspection/piintrospection_base.h (100%) rename {lib => libs}/main/introspection/piintrospection_containers.cpp (100%) rename {lib => libs}/main/introspection/piintrospection_containers.h (100%) rename {lib => libs}/main/introspection/piintrospection_containers_p.cpp (100%) rename {lib => libs}/main/introspection/piintrospection_containers_p.h (100%) rename {lib => libs}/main/introspection/piintrospection_server.cpp (100%) rename {lib => libs}/main/introspection/piintrospection_server.h (100%) rename {lib => libs}/main/introspection/piintrospection_server_p.cpp (100%) rename {lib => libs}/main/introspection/piintrospection_server_p.h (100%) rename {lib => libs}/main/introspection/piintrospection_threads.cpp (100%) rename {lib => libs}/main/introspection/piintrospection_threads.h (100%) rename {lib => libs}/main/introspection/piintrospection_threads_p.cpp (100%) rename {lib => libs}/main/introspection/piintrospection_threads_p.h (100%) rename {lib => libs}/main/io_devices/pibinarylog.cpp (100%) rename {lib => libs}/main/io_devices/pibinarylog.h (100%) rename {lib => libs}/main/io_devices/pican.cpp (100%) rename {lib => libs}/main/io_devices/pican.h (100%) rename {lib => libs}/main/io_devices/piconfig.cpp (100%) rename {lib => libs}/main/io_devices/piconfig.h (100%) rename {lib => libs}/main/io_devices/pidir.cpp (100%) rename {lib => libs}/main/io_devices/pidir.h (100%) rename {lib => libs}/main/io_devices/piethernet.cpp (100%) rename {lib => libs}/main/io_devices/piethernet.h (100%) rename {lib => libs}/main/io_devices/pifile.cpp (100%) rename {lib => libs}/main/io_devices/pifile.h (100%) rename {lib => libs}/main/io_devices/pigpio.cpp (100%) rename {lib => libs}/main/io_devices/pigpio.h (100%) rename {lib => libs}/main/io_devices/piiobytearray.cpp (100%) rename {lib => libs}/main/io_devices/piiobytearray.h (100%) rename {lib => libs}/main/io_devices/piiodevice.cpp (100%) rename {lib => libs}/main/io_devices/piiodevice.h (100%) rename {lib => libs}/main/io_devices/piiodevicesmodule.h (100%) rename {lib => libs}/main/io_devices/piiostring.cpp (100%) rename {lib => libs}/main/io_devices/piiostring.h (100%) rename {lib => libs}/main/io_devices/pipeer.cpp (100%) rename {lib => libs}/main/io_devices/pipeer.h (100%) rename {lib => libs}/main/io_devices/piserial.cpp (100%) rename {lib => libs}/main/io_devices/piserial.h (100%) rename {lib => libs}/main/io_devices/pisharedmemory.cpp (100%) rename {lib => libs}/main/io_devices/pisharedmemory.h (100%) rename {lib => libs}/main/io_devices/pispi.cpp (100%) rename {lib => libs}/main/io_devices/pispi.h (100%) rename {lib => libs}/main/io_devices/pitransparentdevice.cpp (100%) rename {lib => libs}/main/io_devices/pitransparentdevice.h (100%) rename {lib => libs}/main/io_devices/piusb.h (100%) rename {lib => libs}/main/io_utils/pibasetransfer.cpp (100%) rename {lib => libs}/main/io_utils/pibasetransfer.h (100%) rename {lib => libs}/main/io_utils/pibroadcast.h (100%) rename {lib => libs}/main/io_utils/piconnection.cpp (100%) rename {lib => libs}/main/io_utils/piconnection.h (100%) rename {lib => libs}/main/io_utils/pidatatransfer.cpp (100%) rename {lib => libs}/main/io_utils/pidatatransfer.h (100%) rename {lib => libs}/main/io_utils/pidiagnostics.cpp (100%) rename {lib => libs}/main/io_utils/pidiagnostics.h (100%) rename {lib => libs}/main/io_utils/piethutilbase.h (100%) rename {lib => libs}/main/io_utils/pifiletransfer.cpp (100%) rename {lib => libs}/main/io_utils/pifiletransfer.h (100%) rename {lib => libs}/main/io_utils/piioutilsmodule.h (100%) rename {lib => libs}/main/io_utils/pipacketextractor.cpp (100%) rename {lib => libs}/main/io_utils/pipacketextractor.h (100%) rename {lib => libs}/main/io_utils/pistreampacker.h (100%) rename {lib => libs}/main/lua/piluaprogram.h (100%) rename {lib => libs}/main/lua/pip_lua.h (100%) rename {lib => libs}/main/math/picrc.h (100%) rename {lib => libs}/main/math/pievaluator.cpp (100%) rename {lib => libs}/main/math/pievaluator.h (100%) rename {lib => libs}/main/math/pifft.cpp (100%) rename {lib => libs}/main/math/pifft.h (100%) rename {lib => libs}/main/math/pigeometry.h (100%) rename {lib => libs}/main/math/pimathbase.cpp (100%) rename {lib => libs}/main/math/pimathbase.h (100%) rename {lib => libs}/main/math/pimathcomplex.h (100%) rename {lib => libs}/main/math/pimathmatrix.h (100%) rename {lib => libs}/main/math/pimathmodule.h (100%) rename {lib => libs}/main/math/pimathsolver.cpp (100%) rename {lib => libs}/main/math/pimathsolver.h (100%) rename {lib => libs}/main/math/pimathvector.h (100%) rename {lib => libs}/main/math/piquaternion.cpp (100%) rename {lib => libs}/main/math/piquaternion.h (100%) rename {lib => libs}/main/math/pistatistic.h (100%) rename {lib => libs}/main/opencl/piopencl.h (100%) rename {lib => libs}/main/pip.h (100%) rename {lib => libs}/main/piplatform.h (100%) rename {lib => libs}/main/resources/piresources.cpp (100%) rename {lib => libs}/main/resources/piresources.h (100%) rename {lib => libs}/main/resources/piresourcesstorage.cpp (100%) rename {lib => libs}/main/resources/piresourcesstorage.h (100%) rename {lib => libs}/main/system/pilibrary.cpp (100%) rename {lib => libs}/main/system/pilibrary.h (100%) rename {lib => libs}/main/system/piprocess.cpp (100%) rename {lib => libs}/main/system/piprocess.h (100%) rename {lib => libs}/main/system/pisignals.cpp (100%) rename {lib => libs}/main/system/pisignals.h (100%) rename {lib => libs}/main/system/pisingleapplication.cpp (100%) rename {lib => libs}/main/system/pisingleapplication.h (100%) rename {lib => libs}/main/system/pisysteminfo.cpp (100%) rename {lib => libs}/main/system/pisysteminfo.h (100%) rename {lib => libs}/main/system/pisystemmodule.h (100%) rename {lib => libs}/main/system/pisystemmonitor.cpp (100%) rename {lib => libs}/main/system/pisystemmonitor.h (100%) rename {lib => libs}/main/system/pisystemtests.cpp (100%) rename {lib => libs}/main/system/pisystemtests.h (100%) rename {lib => libs}/main/thread/piblockingqueue.h (100%) rename {lib => libs}/main/thread/piconditionvar.cpp (100%) rename {lib => libs}/main/thread/piconditionvar.h (100%) rename {lib => libs}/main/thread/pigrabberbase.h (100%) rename {lib => libs}/main/thread/pimutex.cpp (100%) rename {lib => libs}/main/thread/pimutex.h (100%) rename {lib => libs}/main/thread/pipipelinethread.h (100%) rename {lib => libs}/main/thread/pithread.cpp (100%) rename {lib => libs}/main/thread/pithread.h (100%) rename {lib => libs}/main/thread/pithreadmodule.h (100%) rename {lib => libs}/main/thread/pithreadpoolexecutor.cpp (100%) rename {lib => libs}/main/thread/pithreadpoolexecutor.h (100%) rename {lib => libs}/main/thread/pitimer.cpp (100%) rename {lib => libs}/main/thread/pitimer.h (100%) rename {lib => libs}/opencl/3rd/clcomplex.h (100%) rename {lib => libs}/opencl/piopencl.cpp (100%) rename {lib => libs}/opencl/resources.conf (100%) rename {lib => libs}/usb/piusb.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index caa137f9..b9f471c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,10 +66,10 @@ macro(pip_module NAME LIBS LABEL INCLUDES MSG) set(HS) set(PHS) set(CRES) - file(GLOB_RECURSE CPPS "lib/${NAME}/*.cpp") - file(GLOB_RECURSE HS "lib/${NAME}/*.h") - file(GLOB_RECURSE PHS "lib/${NAME}/*_p.h") - file(GLOB_RECURSE RES "lib/${NAME}/*conf.h") + file(GLOB_RECURSE CPPS "libs/${NAME}/*.cpp") + file(GLOB_RECURSE HS "libs/${NAME}/*.h") + file(GLOB_RECURSE PHS "libs/${NAME}/*_p.h") + file(GLOB_RECURSE RES "libs/${NAME}/*conf.h") list(REMOVE_ITEM HS "${PHS}") list(APPEND HDRS ${HS}) list(APPEND PHDRS ${PHS}) @@ -208,8 +208,8 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) # Main lib -file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/lib/main/*") -list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/lib/main") +file(GLOB PIP_FOLDERS LIST_DIRECTORIES TRUE "${CMAKE_CURRENT_SOURCE_DIR}/libs/main/*") +list(APPEND PIP_FOLDERS "${CMAKE_CURRENT_SOURCE_DIR}/libs/main") set(PIP_MAIN_FOLDERS) foreach(F ${PIP_FOLDERS}) if (IS_DIRECTORY "${F}") @@ -490,8 +490,8 @@ if (NOT CROSSTOOLS) endif() find_package(Lua QUIET) if (LUA_FOUND) - pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd" " (${LUA_VERSION_STRING})") - list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd/LuaBridge") + pip_module(lua "LUA" "PIP Lua support" "${LUA_INCLUDE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd" " (${LUA_VERSION_STRING})") + list(APPEND HDR_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd/LuaBridge") endif() @@ -623,7 +623,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS)) set(DOXY_QHP_SECT_FILTER_ATTRS "\"PIP ${PIP_VERSION}\"") set(DOXY_EXAMPLE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/examples\"") set(DOXY_IMAGE_PATH "\"${CMAKE_CURRENT_SOURCE_DIR}/doc/images\"") - set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/lib/lua/3rd\"") + set(DOXY_EXCLUDE "\"${CMAKE_CURRENT_SOURCE_DIR}/libs/lua/3rd\"") if(DOXYGEN_DOT_EXECUTABLE) string(REPLACE "\\" "" _DOT_PATH "${DOXYGEN_DOT_PATH}") set(DOXY_DOT_PATH "\"${_DOT_PATH}\"") @@ -634,7 +634,7 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS)) foreach(F ${PIP_MAIN_FOLDERS}) list(APPEND DOXY_INPUT "\"${F}\"") endforeach(F) - string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/lib\"") + string(REPLACE ";" " " DOXY_INPUT "\"${CMAKE_CURRENT_SOURCE_DIR}/libs\"") string(REPLACE ";" " " DOXY_INCLUDE_PATH "${DOXY_INPUT}") string(REPLACE ";" " " DOXY_DEFINES "${PIP_EXPORTS};DOXYGEN;PIOBJECT;PIOBJECT_SUBCLASS") add_documentation(doc doc/Doxyfile.in) @@ -643,6 +643,23 @@ if ((NOT PIP_FREERTOS) AND (NOT CROSSTOOLS)) endif() +set(_max_len 0) +foreach(_m ${PIP_SRC_MODULES}) + string(LENGTH "${_m}" _clen) + if (_clen GREATER _max_len) + set(_max_len ${_clen}) + endif() +endforeach() +macro(expand_to_length _out _str _len) + set(${_out} "${_str}") + while(TRUE) + string(LENGTH "${${_out}}" _clen) + if (_clen GREATER_EQUAL ${_len}) + break() + endif() + string(APPEND ${_out} " ") + endwhile() +endmacro() list(REMOVE_ITEM LIBS_STATUS ${PIP_MODULES}) message("----------PIP----------") @@ -668,7 +685,8 @@ endif() message("") message(" Modules:") foreach(_m ${PIP_SRC_MODULES}) - message(" ${_m}: ${PIP_MSG_${_m}}") + expand_to_length(_m_e "${_m}" ${_max_len}) + message(" ${_m_e}: ${PIP_MSG_${_m}}") endforeach() message("") if (PIP_TESTS_LIST) diff --git a/lib/cloud/piccloudclient.cpp b/libs/cloud/piccloudclient.cpp similarity index 100% rename from lib/cloud/piccloudclient.cpp rename to libs/cloud/piccloudclient.cpp diff --git a/lib/cloud/piccloudserver.cpp b/libs/cloud/piccloudserver.cpp similarity index 100% rename from lib/cloud/piccloudserver.cpp rename to libs/cloud/piccloudserver.cpp diff --git a/lib/cloud/piccloudtcp.cpp b/libs/cloud/piccloudtcp.cpp similarity index 100% rename from lib/cloud/piccloudtcp.cpp rename to libs/cloud/piccloudtcp.cpp diff --git a/lib/compress/picompress.cpp b/libs/compress/picompress.cpp similarity index 100% rename from lib/compress/picompress.cpp rename to libs/compress/picompress.cpp diff --git a/lib/console/piscreen.cpp b/libs/console/piscreen.cpp similarity index 100% rename from lib/console/piscreen.cpp rename to libs/console/piscreen.cpp diff --git a/lib/console/piscreenconsole.cpp b/libs/console/piscreenconsole.cpp similarity index 100% rename from lib/console/piscreenconsole.cpp rename to libs/console/piscreenconsole.cpp diff --git a/lib/console/piscreendrawer.cpp b/libs/console/piscreendrawer.cpp similarity index 100% rename from lib/console/piscreendrawer.cpp rename to libs/console/piscreendrawer.cpp diff --git a/lib/console/piscreentile.cpp b/libs/console/piscreentile.cpp similarity index 100% rename from lib/console/piscreentile.cpp rename to libs/console/piscreentile.cpp diff --git a/lib/console/piscreentiles.cpp b/libs/console/piscreentiles.cpp similarity index 100% rename from lib/console/piscreentiles.cpp rename to libs/console/piscreentiles.cpp diff --git a/lib/console/piterminal.cpp b/libs/console/piterminal.cpp similarity index 100% rename from lib/console/piterminal.cpp rename to libs/console/piterminal.cpp diff --git a/lib/crypt/piauth.cpp b/libs/crypt/piauth.cpp similarity index 100% rename from lib/crypt/piauth.cpp rename to libs/crypt/piauth.cpp diff --git a/lib/crypt/picrypt.cpp b/libs/crypt/picrypt.cpp similarity index 100% rename from lib/crypt/picrypt.cpp rename to libs/crypt/picrypt.cpp diff --git a/lib/fftw/pifft.cpp b/libs/fftw/pifft.cpp similarity index 100% rename from lib/fftw/pifft.cpp rename to libs/fftw/pifft.cpp diff --git a/lib/fftw/pifft_p.h b/libs/fftw/pifft_p.h similarity index 100% rename from lib/fftw/pifft_p.h rename to libs/fftw/pifft_p.h diff --git a/lib/io_utils/pibroadcast.cpp b/libs/io_utils/pibroadcast.cpp similarity index 100% rename from lib/io_utils/pibroadcast.cpp rename to libs/io_utils/pibroadcast.cpp diff --git a/lib/io_utils/piethutilbase.cpp b/libs/io_utils/piethutilbase.cpp similarity index 100% rename from lib/io_utils/piethutilbase.cpp rename to libs/io_utils/piethutilbase.cpp diff --git a/lib/io_utils/pistreampacker.cpp b/libs/io_utils/pistreampacker.cpp similarity index 100% rename from lib/io_utils/pistreampacker.cpp rename to libs/io_utils/pistreampacker.cpp diff --git a/lib/lua/3rd/LuaBridge/List.h b/libs/lua/3rd/LuaBridge/List.h similarity index 100% rename from lib/lua/3rd/LuaBridge/List.h rename to libs/lua/3rd/LuaBridge/List.h diff --git a/lib/lua/3rd/LuaBridge/LuaBridge.h b/libs/lua/3rd/LuaBridge/LuaBridge.h similarity index 100% rename from lib/lua/3rd/LuaBridge/LuaBridge.h rename to libs/lua/3rd/LuaBridge/LuaBridge.h diff --git a/lib/lua/3rd/LuaBridge/Map.h b/libs/lua/3rd/LuaBridge/Map.h similarity index 100% rename from lib/lua/3rd/LuaBridge/Map.h rename to libs/lua/3rd/LuaBridge/Map.h diff --git a/lib/lua/3rd/LuaBridge/RefCountedObject.h b/libs/lua/3rd/LuaBridge/RefCountedObject.h similarity index 100% rename from lib/lua/3rd/LuaBridge/RefCountedObject.h rename to libs/lua/3rd/LuaBridge/RefCountedObject.h diff --git a/lib/lua/3rd/LuaBridge/RefCountedPtr.h b/libs/lua/3rd/LuaBridge/RefCountedPtr.h similarity index 100% rename from lib/lua/3rd/LuaBridge/RefCountedPtr.h rename to libs/lua/3rd/LuaBridge/RefCountedPtr.h diff --git a/lib/lua/3rd/LuaBridge/UnorderedMap.h b/libs/lua/3rd/LuaBridge/UnorderedMap.h similarity index 100% rename from lib/lua/3rd/LuaBridge/UnorderedMap.h rename to libs/lua/3rd/LuaBridge/UnorderedMap.h diff --git a/lib/lua/3rd/LuaBridge/Vector.h b/libs/lua/3rd/LuaBridge/Vector.h similarity index 100% rename from lib/lua/3rd/LuaBridge/Vector.h rename to libs/lua/3rd/LuaBridge/Vector.h diff --git a/lib/lua/3rd/LuaBridge/detail/CFunctions.h b/libs/lua/3rd/LuaBridge/detail/CFunctions.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/CFunctions.h rename to libs/lua/3rd/LuaBridge/detail/CFunctions.h diff --git a/lib/lua/3rd/LuaBridge/detail/ClassInfo.h b/libs/lua/3rd/LuaBridge/detail/ClassInfo.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/ClassInfo.h rename to libs/lua/3rd/LuaBridge/detail/ClassInfo.h diff --git a/lib/lua/3rd/LuaBridge/detail/Config.h b/libs/lua/3rd/LuaBridge/detail/Config.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Config.h rename to libs/lua/3rd/LuaBridge/detail/Config.h diff --git a/lib/lua/3rd/LuaBridge/detail/Constructor.h b/libs/lua/3rd/LuaBridge/detail/Constructor.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Constructor.h rename to libs/lua/3rd/LuaBridge/detail/Constructor.h diff --git a/lib/lua/3rd/LuaBridge/detail/FuncTraits.h b/libs/lua/3rd/LuaBridge/detail/FuncTraits.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/FuncTraits.h rename to libs/lua/3rd/LuaBridge/detail/FuncTraits.h diff --git a/lib/lua/3rd/LuaBridge/detail/Iterator.h b/libs/lua/3rd/LuaBridge/detail/Iterator.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Iterator.h rename to libs/lua/3rd/LuaBridge/detail/Iterator.h diff --git a/lib/lua/3rd/LuaBridge/detail/LuaException.h b/libs/lua/3rd/LuaBridge/detail/LuaException.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/LuaException.h rename to libs/lua/3rd/LuaBridge/detail/LuaException.h diff --git a/lib/lua/3rd/LuaBridge/detail/LuaHelpers.h b/libs/lua/3rd/LuaBridge/detail/LuaHelpers.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/LuaHelpers.h rename to libs/lua/3rd/LuaBridge/detail/LuaHelpers.h diff --git a/lib/lua/3rd/LuaBridge/detail/LuaRef.h b/libs/lua/3rd/LuaBridge/detail/LuaRef.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/LuaRef.h rename to libs/lua/3rd/LuaBridge/detail/LuaRef.h diff --git a/lib/lua/3rd/LuaBridge/detail/Namespace.h b/libs/lua/3rd/LuaBridge/detail/Namespace.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Namespace.h rename to libs/lua/3rd/LuaBridge/detail/Namespace.h diff --git a/lib/lua/3rd/LuaBridge/detail/Security.h b/libs/lua/3rd/LuaBridge/detail/Security.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Security.h rename to libs/lua/3rd/LuaBridge/detail/Security.h diff --git a/lib/lua/3rd/LuaBridge/detail/Stack.h b/libs/lua/3rd/LuaBridge/detail/Stack.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Stack.h rename to libs/lua/3rd/LuaBridge/detail/Stack.h diff --git a/lib/lua/3rd/LuaBridge/detail/TypeList.h b/libs/lua/3rd/LuaBridge/detail/TypeList.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/TypeList.h rename to libs/lua/3rd/LuaBridge/detail/TypeList.h diff --git a/lib/lua/3rd/LuaBridge/detail/TypeTraits.h b/libs/lua/3rd/LuaBridge/detail/TypeTraits.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/TypeTraits.h rename to libs/lua/3rd/LuaBridge/detail/TypeTraits.h diff --git a/lib/lua/3rd/LuaBridge/detail/Userdata.h b/libs/lua/3rd/LuaBridge/detail/Userdata.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/Userdata.h rename to libs/lua/3rd/LuaBridge/detail/Userdata.h diff --git a/lib/lua/3rd/LuaBridge/detail/dump.h b/libs/lua/3rd/LuaBridge/detail/dump.h similarity index 100% rename from lib/lua/3rd/LuaBridge/detail/dump.h rename to libs/lua/3rd/LuaBridge/detail/dump.h diff --git a/lib/lua/piluaprogram.cpp b/libs/lua/piluaprogram.cpp similarity index 100% rename from lib/lua/piluaprogram.cpp rename to libs/lua/piluaprogram.cpp diff --git a/lib/main/cloud/piccloudclient.h b/libs/main/cloud/piccloudclient.h similarity index 100% rename from lib/main/cloud/piccloudclient.h rename to libs/main/cloud/piccloudclient.h diff --git a/lib/main/cloud/piccloudmodule.h b/libs/main/cloud/piccloudmodule.h similarity index 100% rename from lib/main/cloud/piccloudmodule.h rename to libs/main/cloud/piccloudmodule.h diff --git a/lib/main/cloud/piccloudserver.h b/libs/main/cloud/piccloudserver.h similarity index 100% rename from lib/main/cloud/piccloudserver.h rename to libs/main/cloud/piccloudserver.h diff --git a/lib/main/cloud/piccloudtcp.h b/libs/main/cloud/piccloudtcp.h similarity index 100% rename from lib/main/cloud/piccloudtcp.h rename to libs/main/cloud/piccloudtcp.h diff --git a/lib/main/code/picodeinfo.cpp b/libs/main/code/picodeinfo.cpp similarity index 100% rename from lib/main/code/picodeinfo.cpp rename to libs/main/code/picodeinfo.cpp diff --git a/lib/main/code/picodeinfo.h b/libs/main/code/picodeinfo.h similarity index 100% rename from lib/main/code/picodeinfo.h rename to libs/main/code/picodeinfo.h diff --git a/lib/main/code/picodemodule.h b/libs/main/code/picodemodule.h similarity index 100% rename from lib/main/code/picodemodule.h rename to libs/main/code/picodemodule.h diff --git a/lib/main/code/picodeparser.cpp b/libs/main/code/picodeparser.cpp similarity index 100% rename from lib/main/code/picodeparser.cpp rename to libs/main/code/picodeparser.cpp diff --git a/lib/main/code/picodeparser.h b/libs/main/code/picodeparser.h similarity index 100% rename from lib/main/code/picodeparser.h rename to libs/main/code/picodeparser.h diff --git a/lib/main/compress/picompress.h b/libs/main/compress/picompress.h similarity index 100% rename from lib/main/compress/picompress.h rename to libs/main/compress/picompress.h diff --git a/lib/main/console/piconsolemodule.h b/libs/main/console/piconsolemodule.h similarity index 100% rename from lib/main/console/piconsolemodule.h rename to libs/main/console/piconsolemodule.h diff --git a/lib/main/console/pikbdlistener.cpp b/libs/main/console/pikbdlistener.cpp similarity index 100% rename from lib/main/console/pikbdlistener.cpp rename to libs/main/console/pikbdlistener.cpp diff --git a/lib/main/console/pikbdlistener.h b/libs/main/console/pikbdlistener.h similarity index 100% rename from lib/main/console/pikbdlistener.h rename to libs/main/console/pikbdlistener.h diff --git a/lib/main/console/piscreen.h b/libs/main/console/piscreen.h similarity index 100% rename from lib/main/console/piscreen.h rename to libs/main/console/piscreen.h diff --git a/lib/main/console/piscreenconsole.h b/libs/main/console/piscreenconsole.h similarity index 100% rename from lib/main/console/piscreenconsole.h rename to libs/main/console/piscreenconsole.h diff --git a/lib/main/console/piscreendrawer.h b/libs/main/console/piscreendrawer.h similarity index 100% rename from lib/main/console/piscreendrawer.h rename to libs/main/console/piscreendrawer.h diff --git a/lib/main/console/piscreentile.h b/libs/main/console/piscreentile.h similarity index 100% rename from lib/main/console/piscreentile.h rename to libs/main/console/piscreentile.h diff --git a/lib/main/console/piscreentiles.h b/libs/main/console/piscreentiles.h similarity index 100% rename from lib/main/console/piscreentiles.h rename to libs/main/console/piscreentiles.h diff --git a/lib/main/console/piscreentypes.h b/libs/main/console/piscreentypes.h similarity index 100% rename from lib/main/console/piscreentypes.h rename to libs/main/console/piscreentypes.h diff --git a/lib/main/console/piterminal.h b/libs/main/console/piterminal.h similarity index 100% rename from lib/main/console/piterminal.h rename to libs/main/console/piterminal.h diff --git a/lib/main/containers/picontainers.cpp b/libs/main/containers/picontainers.cpp similarity index 100% rename from lib/main/containers/picontainers.cpp rename to libs/main/containers/picontainers.cpp diff --git a/lib/main/containers/picontainers.h b/libs/main/containers/picontainers.h similarity index 100% rename from lib/main/containers/picontainers.h rename to libs/main/containers/picontainers.h diff --git a/lib/main/containers/picontainersmodule.h b/libs/main/containers/picontainersmodule.h similarity index 100% rename from lib/main/containers/picontainersmodule.h rename to libs/main/containers/picontainersmodule.h diff --git a/lib/main/containers/pideque.h b/libs/main/containers/pideque.h similarity index 100% rename from lib/main/containers/pideque.h rename to libs/main/containers/pideque.h diff --git a/lib/main/containers/pimap.h b/libs/main/containers/pimap.h similarity index 100% rename from lib/main/containers/pimap.h rename to libs/main/containers/pimap.h diff --git a/lib/main/containers/pipair.h b/libs/main/containers/pipair.h similarity index 100% rename from lib/main/containers/pipair.h rename to libs/main/containers/pipair.h diff --git a/lib/main/containers/piqueue.h b/libs/main/containers/piqueue.h similarity index 100% rename from lib/main/containers/piqueue.h rename to libs/main/containers/piqueue.h diff --git a/lib/main/containers/piset.h b/libs/main/containers/piset.h similarity index 100% rename from lib/main/containers/piset.h rename to libs/main/containers/piset.h diff --git a/lib/main/containers/pistack.h b/libs/main/containers/pistack.h similarity index 100% rename from lib/main/containers/pistack.h rename to libs/main/containers/pistack.h diff --git a/lib/main/containers/pivector.h b/libs/main/containers/pivector.h similarity index 100% rename from lib/main/containers/pivector.h rename to libs/main/containers/pivector.h diff --git a/lib/main/containers/pivector2d.h b/libs/main/containers/pivector2d.h similarity index 100% rename from lib/main/containers/pivector2d.h rename to libs/main/containers/pivector2d.h diff --git a/lib/main/core/pibase.h b/libs/main/core/pibase.h similarity index 100% rename from lib/main/core/pibase.h rename to libs/main/core/pibase.h diff --git a/lib/main/core/pibitarray.cpp b/libs/main/core/pibitarray.cpp similarity index 100% rename from lib/main/core/pibitarray.cpp rename to libs/main/core/pibitarray.cpp diff --git a/lib/main/core/pibitarray.h b/libs/main/core/pibitarray.h similarity index 100% rename from lib/main/core/pibitarray.h rename to libs/main/core/pibitarray.h diff --git a/lib/main/core/pibytearray.cpp b/libs/main/core/pibytearray.cpp similarity index 100% rename from lib/main/core/pibytearray.cpp rename to libs/main/core/pibytearray.cpp diff --git a/lib/main/core/pibytearray.h b/libs/main/core/pibytearray.h similarity index 100% rename from lib/main/core/pibytearray.h rename to libs/main/core/pibytearray.h diff --git a/lib/main/core/pichar.cpp b/libs/main/core/pichar.cpp similarity index 100% rename from lib/main/core/pichar.cpp rename to libs/main/core/pichar.cpp diff --git a/lib/main/core/pichar.h b/libs/main/core/pichar.h similarity index 100% rename from lib/main/core/pichar.h rename to libs/main/core/pichar.h diff --git a/lib/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp similarity index 100% rename from lib/main/core/pichunkstream.cpp rename to libs/main/core/pichunkstream.cpp diff --git a/lib/main/core/pichunkstream.h b/libs/main/core/pichunkstream.h similarity index 100% rename from lib/main/core/pichunkstream.h rename to libs/main/core/pichunkstream.h diff --git a/lib/main/core/picli.cpp b/libs/main/core/picli.cpp similarity index 100% rename from lib/main/core/picli.cpp rename to libs/main/core/picli.cpp diff --git a/lib/main/core/picli.h b/libs/main/core/picli.h similarity index 100% rename from lib/main/core/picli.h rename to libs/main/core/picli.h diff --git a/lib/main/core/picollection.cpp b/libs/main/core/picollection.cpp similarity index 100% rename from lib/main/core/picollection.cpp rename to libs/main/core/picollection.cpp diff --git a/lib/main/core/picollection.h b/libs/main/core/picollection.h similarity index 100% rename from lib/main/core/picollection.h rename to libs/main/core/picollection.h diff --git a/lib/main/core/picoremodule.h b/libs/main/core/picoremodule.h similarity index 100% rename from lib/main/core/picoremodule.h rename to libs/main/core/picoremodule.h diff --git a/lib/main/core/picout.cpp b/libs/main/core/picout.cpp similarity index 100% rename from lib/main/core/picout.cpp rename to libs/main/core/picout.cpp diff --git a/lib/main/core/picout.h b/libs/main/core/picout.h similarity index 100% rename from lib/main/core/picout.h rename to libs/main/core/picout.h diff --git a/lib/main/core/piflags.h b/libs/main/core/piflags.h similarity index 100% rename from lib/main/core/piflags.h rename to libs/main/core/piflags.h diff --git a/lib/main/core/piincludes.cpp b/libs/main/core/piincludes.cpp similarity index 100% rename from lib/main/core/piincludes.cpp rename to libs/main/core/piincludes.cpp diff --git a/lib/main/core/piincludes.h b/libs/main/core/piincludes.h similarity index 100% rename from lib/main/core/piincludes.h rename to libs/main/core/piincludes.h diff --git a/lib/main/core/piincludes_p.h b/libs/main/core/piincludes_p.h similarity index 100% rename from lib/main/core/piincludes_p.h rename to libs/main/core/piincludes_p.h diff --git a/lib/main/core/piinit.cpp b/libs/main/core/piinit.cpp similarity index 100% rename from lib/main/core/piinit.cpp rename to libs/main/core/piinit.cpp diff --git a/lib/main/core/piinit.h b/libs/main/core/piinit.h similarity index 100% rename from lib/main/core/piinit.h rename to libs/main/core/piinit.h diff --git a/lib/main/core/piobject.cpp b/libs/main/core/piobject.cpp similarity index 100% rename from lib/main/core/piobject.cpp rename to libs/main/core/piobject.cpp diff --git a/lib/main/core/piobject.h b/libs/main/core/piobject.h similarity index 100% rename from lib/main/core/piobject.h rename to libs/main/core/piobject.h diff --git a/lib/main/core/pipropertystorage.cpp b/libs/main/core/pipropertystorage.cpp similarity index 100% rename from lib/main/core/pipropertystorage.cpp rename to libs/main/core/pipropertystorage.cpp diff --git a/lib/main/core/pipropertystorage.h b/libs/main/core/pipropertystorage.h similarity index 100% rename from lib/main/core/pipropertystorage.h rename to libs/main/core/pipropertystorage.h diff --git a/lib/main/core/pistring.cpp b/libs/main/core/pistring.cpp similarity index 100% rename from lib/main/core/pistring.cpp rename to libs/main/core/pistring.cpp diff --git a/lib/main/core/pistring.h b/libs/main/core/pistring.h similarity index 100% rename from lib/main/core/pistring.h rename to libs/main/core/pistring.h diff --git a/lib/main/core/pistring_std.h b/libs/main/core/pistring_std.h similarity index 100% rename from lib/main/core/pistring_std.h rename to libs/main/core/pistring_std.h diff --git a/lib/main/core/pistringlist.cpp b/libs/main/core/pistringlist.cpp similarity index 100% rename from lib/main/core/pistringlist.cpp rename to libs/main/core/pistringlist.cpp diff --git a/lib/main/core/pistringlist.h b/libs/main/core/pistringlist.h similarity index 100% rename from lib/main/core/pistringlist.h rename to libs/main/core/pistringlist.h diff --git a/lib/main/core/pitime.cpp b/libs/main/core/pitime.cpp similarity index 100% rename from lib/main/core/pitime.cpp rename to libs/main/core/pitime.cpp diff --git a/lib/main/core/pitime.h b/libs/main/core/pitime.h similarity index 100% rename from lib/main/core/pitime.h rename to libs/main/core/pitime.h diff --git a/lib/main/core/pitime_win.h b/libs/main/core/pitime_win.h similarity index 100% rename from lib/main/core/pitime_win.h rename to libs/main/core/pitime_win.h diff --git a/lib/main/core/pivariant.cpp b/libs/main/core/pivariant.cpp similarity index 100% rename from lib/main/core/pivariant.cpp rename to libs/main/core/pivariant.cpp diff --git a/lib/main/core/pivariant.h b/libs/main/core/pivariant.h similarity index 100% rename from lib/main/core/pivariant.h rename to libs/main/core/pivariant.h diff --git a/lib/main/core/pivarianttypes.cpp b/libs/main/core/pivarianttypes.cpp similarity index 100% rename from lib/main/core/pivarianttypes.cpp rename to libs/main/core/pivarianttypes.cpp diff --git a/lib/main/core/pivarianttypes.h b/libs/main/core/pivarianttypes.h similarity index 100% rename from lib/main/core/pivarianttypes.h rename to libs/main/core/pivarianttypes.h diff --git a/lib/main/crypt/piauth.h b/libs/main/crypt/piauth.h similarity index 100% rename from lib/main/crypt/piauth.h rename to libs/main/crypt/piauth.h diff --git a/lib/main/crypt/picrypt.h b/libs/main/crypt/picrypt.h similarity index 100% rename from lib/main/crypt/picrypt.h rename to libs/main/crypt/picrypt.h diff --git a/lib/main/crypt/picryptmodule.h b/libs/main/crypt/picryptmodule.h similarity index 100% rename from lib/main/crypt/picryptmodule.h rename to libs/main/crypt/picryptmodule.h diff --git a/lib/main/geo/piellipsoidmodel.cpp b/libs/main/geo/piellipsoidmodel.cpp similarity index 100% rename from lib/main/geo/piellipsoidmodel.cpp rename to libs/main/geo/piellipsoidmodel.cpp diff --git a/lib/main/geo/piellipsoidmodel.h b/libs/main/geo/piellipsoidmodel.h similarity index 100% rename from lib/main/geo/piellipsoidmodel.h rename to libs/main/geo/piellipsoidmodel.h diff --git a/lib/main/geo/pigeomodule.h b/libs/main/geo/pigeomodule.h similarity index 100% rename from lib/main/geo/pigeomodule.h rename to libs/main/geo/pigeomodule.h diff --git a/lib/main/geo/pigeoposition.cpp b/libs/main/geo/pigeoposition.cpp similarity index 100% rename from lib/main/geo/pigeoposition.cpp rename to libs/main/geo/pigeoposition.cpp diff --git a/lib/main/geo/pigeoposition.h b/libs/main/geo/pigeoposition.h similarity index 100% rename from lib/main/geo/pigeoposition.h rename to libs/main/geo/pigeoposition.h diff --git a/lib/main/introspection/piintrospection_base.h b/libs/main/introspection/piintrospection_base.h similarity index 100% rename from lib/main/introspection/piintrospection_base.h rename to libs/main/introspection/piintrospection_base.h diff --git a/lib/main/introspection/piintrospection_containers.cpp b/libs/main/introspection/piintrospection_containers.cpp similarity index 100% rename from lib/main/introspection/piintrospection_containers.cpp rename to libs/main/introspection/piintrospection_containers.cpp diff --git a/lib/main/introspection/piintrospection_containers.h b/libs/main/introspection/piintrospection_containers.h similarity index 100% rename from lib/main/introspection/piintrospection_containers.h rename to libs/main/introspection/piintrospection_containers.h diff --git a/lib/main/introspection/piintrospection_containers_p.cpp b/libs/main/introspection/piintrospection_containers_p.cpp similarity index 100% rename from lib/main/introspection/piintrospection_containers_p.cpp rename to libs/main/introspection/piintrospection_containers_p.cpp diff --git a/lib/main/introspection/piintrospection_containers_p.h b/libs/main/introspection/piintrospection_containers_p.h similarity index 100% rename from lib/main/introspection/piintrospection_containers_p.h rename to libs/main/introspection/piintrospection_containers_p.h diff --git a/lib/main/introspection/piintrospection_server.cpp b/libs/main/introspection/piintrospection_server.cpp similarity index 100% rename from lib/main/introspection/piintrospection_server.cpp rename to libs/main/introspection/piintrospection_server.cpp diff --git a/lib/main/introspection/piintrospection_server.h b/libs/main/introspection/piintrospection_server.h similarity index 100% rename from lib/main/introspection/piintrospection_server.h rename to libs/main/introspection/piintrospection_server.h diff --git a/lib/main/introspection/piintrospection_server_p.cpp b/libs/main/introspection/piintrospection_server_p.cpp similarity index 100% rename from lib/main/introspection/piintrospection_server_p.cpp rename to libs/main/introspection/piintrospection_server_p.cpp diff --git a/lib/main/introspection/piintrospection_server_p.h b/libs/main/introspection/piintrospection_server_p.h similarity index 100% rename from lib/main/introspection/piintrospection_server_p.h rename to libs/main/introspection/piintrospection_server_p.h diff --git a/lib/main/introspection/piintrospection_threads.cpp b/libs/main/introspection/piintrospection_threads.cpp similarity index 100% rename from lib/main/introspection/piintrospection_threads.cpp rename to libs/main/introspection/piintrospection_threads.cpp diff --git a/lib/main/introspection/piintrospection_threads.h b/libs/main/introspection/piintrospection_threads.h similarity index 100% rename from lib/main/introspection/piintrospection_threads.h rename to libs/main/introspection/piintrospection_threads.h diff --git a/lib/main/introspection/piintrospection_threads_p.cpp b/libs/main/introspection/piintrospection_threads_p.cpp similarity index 100% rename from lib/main/introspection/piintrospection_threads_p.cpp rename to libs/main/introspection/piintrospection_threads_p.cpp diff --git a/lib/main/introspection/piintrospection_threads_p.h b/libs/main/introspection/piintrospection_threads_p.h similarity index 100% rename from lib/main/introspection/piintrospection_threads_p.h rename to libs/main/introspection/piintrospection_threads_p.h diff --git a/lib/main/io_devices/pibinarylog.cpp b/libs/main/io_devices/pibinarylog.cpp similarity index 100% rename from lib/main/io_devices/pibinarylog.cpp rename to libs/main/io_devices/pibinarylog.cpp diff --git a/lib/main/io_devices/pibinarylog.h b/libs/main/io_devices/pibinarylog.h similarity index 100% rename from lib/main/io_devices/pibinarylog.h rename to libs/main/io_devices/pibinarylog.h diff --git a/lib/main/io_devices/pican.cpp b/libs/main/io_devices/pican.cpp similarity index 100% rename from lib/main/io_devices/pican.cpp rename to libs/main/io_devices/pican.cpp diff --git a/lib/main/io_devices/pican.h b/libs/main/io_devices/pican.h similarity index 100% rename from lib/main/io_devices/pican.h rename to libs/main/io_devices/pican.h diff --git a/lib/main/io_devices/piconfig.cpp b/libs/main/io_devices/piconfig.cpp similarity index 100% rename from lib/main/io_devices/piconfig.cpp rename to libs/main/io_devices/piconfig.cpp diff --git a/lib/main/io_devices/piconfig.h b/libs/main/io_devices/piconfig.h similarity index 100% rename from lib/main/io_devices/piconfig.h rename to libs/main/io_devices/piconfig.h diff --git a/lib/main/io_devices/pidir.cpp b/libs/main/io_devices/pidir.cpp similarity index 100% rename from lib/main/io_devices/pidir.cpp rename to libs/main/io_devices/pidir.cpp diff --git a/lib/main/io_devices/pidir.h b/libs/main/io_devices/pidir.h similarity index 100% rename from lib/main/io_devices/pidir.h rename to libs/main/io_devices/pidir.h diff --git a/lib/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp similarity index 100% rename from lib/main/io_devices/piethernet.cpp rename to libs/main/io_devices/piethernet.cpp diff --git a/lib/main/io_devices/piethernet.h b/libs/main/io_devices/piethernet.h similarity index 100% rename from lib/main/io_devices/piethernet.h rename to libs/main/io_devices/piethernet.h diff --git a/lib/main/io_devices/pifile.cpp b/libs/main/io_devices/pifile.cpp similarity index 100% rename from lib/main/io_devices/pifile.cpp rename to libs/main/io_devices/pifile.cpp diff --git a/lib/main/io_devices/pifile.h b/libs/main/io_devices/pifile.h similarity index 100% rename from lib/main/io_devices/pifile.h rename to libs/main/io_devices/pifile.h diff --git a/lib/main/io_devices/pigpio.cpp b/libs/main/io_devices/pigpio.cpp similarity index 100% rename from lib/main/io_devices/pigpio.cpp rename to libs/main/io_devices/pigpio.cpp diff --git a/lib/main/io_devices/pigpio.h b/libs/main/io_devices/pigpio.h similarity index 100% rename from lib/main/io_devices/pigpio.h rename to libs/main/io_devices/pigpio.h diff --git a/lib/main/io_devices/piiobytearray.cpp b/libs/main/io_devices/piiobytearray.cpp similarity index 100% rename from lib/main/io_devices/piiobytearray.cpp rename to libs/main/io_devices/piiobytearray.cpp diff --git a/lib/main/io_devices/piiobytearray.h b/libs/main/io_devices/piiobytearray.h similarity index 100% rename from lib/main/io_devices/piiobytearray.h rename to libs/main/io_devices/piiobytearray.h diff --git a/lib/main/io_devices/piiodevice.cpp b/libs/main/io_devices/piiodevice.cpp similarity index 100% rename from lib/main/io_devices/piiodevice.cpp rename to libs/main/io_devices/piiodevice.cpp diff --git a/lib/main/io_devices/piiodevice.h b/libs/main/io_devices/piiodevice.h similarity index 100% rename from lib/main/io_devices/piiodevice.h rename to libs/main/io_devices/piiodevice.h diff --git a/lib/main/io_devices/piiodevicesmodule.h b/libs/main/io_devices/piiodevicesmodule.h similarity index 100% rename from lib/main/io_devices/piiodevicesmodule.h rename to libs/main/io_devices/piiodevicesmodule.h diff --git a/lib/main/io_devices/piiostring.cpp b/libs/main/io_devices/piiostring.cpp similarity index 100% rename from lib/main/io_devices/piiostring.cpp rename to libs/main/io_devices/piiostring.cpp diff --git a/lib/main/io_devices/piiostring.h b/libs/main/io_devices/piiostring.h similarity index 100% rename from lib/main/io_devices/piiostring.h rename to libs/main/io_devices/piiostring.h diff --git a/lib/main/io_devices/pipeer.cpp b/libs/main/io_devices/pipeer.cpp similarity index 100% rename from lib/main/io_devices/pipeer.cpp rename to libs/main/io_devices/pipeer.cpp diff --git a/lib/main/io_devices/pipeer.h b/libs/main/io_devices/pipeer.h similarity index 100% rename from lib/main/io_devices/pipeer.h rename to libs/main/io_devices/pipeer.h diff --git a/lib/main/io_devices/piserial.cpp b/libs/main/io_devices/piserial.cpp similarity index 100% rename from lib/main/io_devices/piserial.cpp rename to libs/main/io_devices/piserial.cpp diff --git a/lib/main/io_devices/piserial.h b/libs/main/io_devices/piserial.h similarity index 100% rename from lib/main/io_devices/piserial.h rename to libs/main/io_devices/piserial.h diff --git a/lib/main/io_devices/pisharedmemory.cpp b/libs/main/io_devices/pisharedmemory.cpp similarity index 100% rename from lib/main/io_devices/pisharedmemory.cpp rename to libs/main/io_devices/pisharedmemory.cpp diff --git a/lib/main/io_devices/pisharedmemory.h b/libs/main/io_devices/pisharedmemory.h similarity index 100% rename from lib/main/io_devices/pisharedmemory.h rename to libs/main/io_devices/pisharedmemory.h diff --git a/lib/main/io_devices/pispi.cpp b/libs/main/io_devices/pispi.cpp similarity index 100% rename from lib/main/io_devices/pispi.cpp rename to libs/main/io_devices/pispi.cpp diff --git a/lib/main/io_devices/pispi.h b/libs/main/io_devices/pispi.h similarity index 100% rename from lib/main/io_devices/pispi.h rename to libs/main/io_devices/pispi.h diff --git a/lib/main/io_devices/pitransparentdevice.cpp b/libs/main/io_devices/pitransparentdevice.cpp similarity index 100% rename from lib/main/io_devices/pitransparentdevice.cpp rename to libs/main/io_devices/pitransparentdevice.cpp diff --git a/lib/main/io_devices/pitransparentdevice.h b/libs/main/io_devices/pitransparentdevice.h similarity index 100% rename from lib/main/io_devices/pitransparentdevice.h rename to libs/main/io_devices/pitransparentdevice.h diff --git a/lib/main/io_devices/piusb.h b/libs/main/io_devices/piusb.h similarity index 100% rename from lib/main/io_devices/piusb.h rename to libs/main/io_devices/piusb.h diff --git a/lib/main/io_utils/pibasetransfer.cpp b/libs/main/io_utils/pibasetransfer.cpp similarity index 100% rename from lib/main/io_utils/pibasetransfer.cpp rename to libs/main/io_utils/pibasetransfer.cpp diff --git a/lib/main/io_utils/pibasetransfer.h b/libs/main/io_utils/pibasetransfer.h similarity index 100% rename from lib/main/io_utils/pibasetransfer.h rename to libs/main/io_utils/pibasetransfer.h diff --git a/lib/main/io_utils/pibroadcast.h b/libs/main/io_utils/pibroadcast.h similarity index 100% rename from lib/main/io_utils/pibroadcast.h rename to libs/main/io_utils/pibroadcast.h diff --git a/lib/main/io_utils/piconnection.cpp b/libs/main/io_utils/piconnection.cpp similarity index 100% rename from lib/main/io_utils/piconnection.cpp rename to libs/main/io_utils/piconnection.cpp diff --git a/lib/main/io_utils/piconnection.h b/libs/main/io_utils/piconnection.h similarity index 100% rename from lib/main/io_utils/piconnection.h rename to libs/main/io_utils/piconnection.h diff --git a/lib/main/io_utils/pidatatransfer.cpp b/libs/main/io_utils/pidatatransfer.cpp similarity index 100% rename from lib/main/io_utils/pidatatransfer.cpp rename to libs/main/io_utils/pidatatransfer.cpp diff --git a/lib/main/io_utils/pidatatransfer.h b/libs/main/io_utils/pidatatransfer.h similarity index 100% rename from lib/main/io_utils/pidatatransfer.h rename to libs/main/io_utils/pidatatransfer.h diff --git a/lib/main/io_utils/pidiagnostics.cpp b/libs/main/io_utils/pidiagnostics.cpp similarity index 100% rename from lib/main/io_utils/pidiagnostics.cpp rename to libs/main/io_utils/pidiagnostics.cpp diff --git a/lib/main/io_utils/pidiagnostics.h b/libs/main/io_utils/pidiagnostics.h similarity index 100% rename from lib/main/io_utils/pidiagnostics.h rename to libs/main/io_utils/pidiagnostics.h diff --git a/lib/main/io_utils/piethutilbase.h b/libs/main/io_utils/piethutilbase.h similarity index 100% rename from lib/main/io_utils/piethutilbase.h rename to libs/main/io_utils/piethutilbase.h diff --git a/lib/main/io_utils/pifiletransfer.cpp b/libs/main/io_utils/pifiletransfer.cpp similarity index 100% rename from lib/main/io_utils/pifiletransfer.cpp rename to libs/main/io_utils/pifiletransfer.cpp diff --git a/lib/main/io_utils/pifiletransfer.h b/libs/main/io_utils/pifiletransfer.h similarity index 100% rename from lib/main/io_utils/pifiletransfer.h rename to libs/main/io_utils/pifiletransfer.h diff --git a/lib/main/io_utils/piioutilsmodule.h b/libs/main/io_utils/piioutilsmodule.h similarity index 100% rename from lib/main/io_utils/piioutilsmodule.h rename to libs/main/io_utils/piioutilsmodule.h diff --git a/lib/main/io_utils/pipacketextractor.cpp b/libs/main/io_utils/pipacketextractor.cpp similarity index 100% rename from lib/main/io_utils/pipacketextractor.cpp rename to libs/main/io_utils/pipacketextractor.cpp diff --git a/lib/main/io_utils/pipacketextractor.h b/libs/main/io_utils/pipacketextractor.h similarity index 100% rename from lib/main/io_utils/pipacketextractor.h rename to libs/main/io_utils/pipacketextractor.h diff --git a/lib/main/io_utils/pistreampacker.h b/libs/main/io_utils/pistreampacker.h similarity index 100% rename from lib/main/io_utils/pistreampacker.h rename to libs/main/io_utils/pistreampacker.h diff --git a/lib/main/lua/piluaprogram.h b/libs/main/lua/piluaprogram.h similarity index 100% rename from lib/main/lua/piluaprogram.h rename to libs/main/lua/piluaprogram.h diff --git a/lib/main/lua/pip_lua.h b/libs/main/lua/pip_lua.h similarity index 100% rename from lib/main/lua/pip_lua.h rename to libs/main/lua/pip_lua.h diff --git a/lib/main/math/picrc.h b/libs/main/math/picrc.h similarity index 100% rename from lib/main/math/picrc.h rename to libs/main/math/picrc.h diff --git a/lib/main/math/pievaluator.cpp b/libs/main/math/pievaluator.cpp similarity index 100% rename from lib/main/math/pievaluator.cpp rename to libs/main/math/pievaluator.cpp diff --git a/lib/main/math/pievaluator.h b/libs/main/math/pievaluator.h similarity index 100% rename from lib/main/math/pievaluator.h rename to libs/main/math/pievaluator.h diff --git a/lib/main/math/pifft.cpp b/libs/main/math/pifft.cpp similarity index 100% rename from lib/main/math/pifft.cpp rename to libs/main/math/pifft.cpp diff --git a/lib/main/math/pifft.h b/libs/main/math/pifft.h similarity index 100% rename from lib/main/math/pifft.h rename to libs/main/math/pifft.h diff --git a/lib/main/math/pigeometry.h b/libs/main/math/pigeometry.h similarity index 100% rename from lib/main/math/pigeometry.h rename to libs/main/math/pigeometry.h diff --git a/lib/main/math/pimathbase.cpp b/libs/main/math/pimathbase.cpp similarity index 100% rename from lib/main/math/pimathbase.cpp rename to libs/main/math/pimathbase.cpp diff --git a/lib/main/math/pimathbase.h b/libs/main/math/pimathbase.h similarity index 100% rename from lib/main/math/pimathbase.h rename to libs/main/math/pimathbase.h diff --git a/lib/main/math/pimathcomplex.h b/libs/main/math/pimathcomplex.h similarity index 100% rename from lib/main/math/pimathcomplex.h rename to libs/main/math/pimathcomplex.h diff --git a/lib/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h similarity index 100% rename from lib/main/math/pimathmatrix.h rename to libs/main/math/pimathmatrix.h diff --git a/lib/main/math/pimathmodule.h b/libs/main/math/pimathmodule.h similarity index 100% rename from lib/main/math/pimathmodule.h rename to libs/main/math/pimathmodule.h diff --git a/lib/main/math/pimathsolver.cpp b/libs/main/math/pimathsolver.cpp similarity index 100% rename from lib/main/math/pimathsolver.cpp rename to libs/main/math/pimathsolver.cpp diff --git a/lib/main/math/pimathsolver.h b/libs/main/math/pimathsolver.h similarity index 100% rename from lib/main/math/pimathsolver.h rename to libs/main/math/pimathsolver.h diff --git a/lib/main/math/pimathvector.h b/libs/main/math/pimathvector.h similarity index 100% rename from lib/main/math/pimathvector.h rename to libs/main/math/pimathvector.h diff --git a/lib/main/math/piquaternion.cpp b/libs/main/math/piquaternion.cpp similarity index 100% rename from lib/main/math/piquaternion.cpp rename to libs/main/math/piquaternion.cpp diff --git a/lib/main/math/piquaternion.h b/libs/main/math/piquaternion.h similarity index 100% rename from lib/main/math/piquaternion.h rename to libs/main/math/piquaternion.h diff --git a/lib/main/math/pistatistic.h b/libs/main/math/pistatistic.h similarity index 100% rename from lib/main/math/pistatistic.h rename to libs/main/math/pistatistic.h diff --git a/lib/main/opencl/piopencl.h b/libs/main/opencl/piopencl.h similarity index 100% rename from lib/main/opencl/piopencl.h rename to libs/main/opencl/piopencl.h diff --git a/lib/main/pip.h b/libs/main/pip.h similarity index 100% rename from lib/main/pip.h rename to libs/main/pip.h diff --git a/lib/main/piplatform.h b/libs/main/piplatform.h similarity index 100% rename from lib/main/piplatform.h rename to libs/main/piplatform.h diff --git a/lib/main/resources/piresources.cpp b/libs/main/resources/piresources.cpp similarity index 100% rename from lib/main/resources/piresources.cpp rename to libs/main/resources/piresources.cpp diff --git a/lib/main/resources/piresources.h b/libs/main/resources/piresources.h similarity index 100% rename from lib/main/resources/piresources.h rename to libs/main/resources/piresources.h diff --git a/lib/main/resources/piresourcesstorage.cpp b/libs/main/resources/piresourcesstorage.cpp similarity index 100% rename from lib/main/resources/piresourcesstorage.cpp rename to libs/main/resources/piresourcesstorage.cpp diff --git a/lib/main/resources/piresourcesstorage.h b/libs/main/resources/piresourcesstorage.h similarity index 100% rename from lib/main/resources/piresourcesstorage.h rename to libs/main/resources/piresourcesstorage.h diff --git a/lib/main/system/pilibrary.cpp b/libs/main/system/pilibrary.cpp similarity index 100% rename from lib/main/system/pilibrary.cpp rename to libs/main/system/pilibrary.cpp diff --git a/lib/main/system/pilibrary.h b/libs/main/system/pilibrary.h similarity index 100% rename from lib/main/system/pilibrary.h rename to libs/main/system/pilibrary.h diff --git a/lib/main/system/piprocess.cpp b/libs/main/system/piprocess.cpp similarity index 100% rename from lib/main/system/piprocess.cpp rename to libs/main/system/piprocess.cpp diff --git a/lib/main/system/piprocess.h b/libs/main/system/piprocess.h similarity index 100% rename from lib/main/system/piprocess.h rename to libs/main/system/piprocess.h diff --git a/lib/main/system/pisignals.cpp b/libs/main/system/pisignals.cpp similarity index 100% rename from lib/main/system/pisignals.cpp rename to libs/main/system/pisignals.cpp diff --git a/lib/main/system/pisignals.h b/libs/main/system/pisignals.h similarity index 100% rename from lib/main/system/pisignals.h rename to libs/main/system/pisignals.h diff --git a/lib/main/system/pisingleapplication.cpp b/libs/main/system/pisingleapplication.cpp similarity index 100% rename from lib/main/system/pisingleapplication.cpp rename to libs/main/system/pisingleapplication.cpp diff --git a/lib/main/system/pisingleapplication.h b/libs/main/system/pisingleapplication.h similarity index 100% rename from lib/main/system/pisingleapplication.h rename to libs/main/system/pisingleapplication.h diff --git a/lib/main/system/pisysteminfo.cpp b/libs/main/system/pisysteminfo.cpp similarity index 100% rename from lib/main/system/pisysteminfo.cpp rename to libs/main/system/pisysteminfo.cpp diff --git a/lib/main/system/pisysteminfo.h b/libs/main/system/pisysteminfo.h similarity index 100% rename from lib/main/system/pisysteminfo.h rename to libs/main/system/pisysteminfo.h diff --git a/lib/main/system/pisystemmodule.h b/libs/main/system/pisystemmodule.h similarity index 100% rename from lib/main/system/pisystemmodule.h rename to libs/main/system/pisystemmodule.h diff --git a/lib/main/system/pisystemmonitor.cpp b/libs/main/system/pisystemmonitor.cpp similarity index 100% rename from lib/main/system/pisystemmonitor.cpp rename to libs/main/system/pisystemmonitor.cpp diff --git a/lib/main/system/pisystemmonitor.h b/libs/main/system/pisystemmonitor.h similarity index 100% rename from lib/main/system/pisystemmonitor.h rename to libs/main/system/pisystemmonitor.h diff --git a/lib/main/system/pisystemtests.cpp b/libs/main/system/pisystemtests.cpp similarity index 100% rename from lib/main/system/pisystemtests.cpp rename to libs/main/system/pisystemtests.cpp diff --git a/lib/main/system/pisystemtests.h b/libs/main/system/pisystemtests.h similarity index 100% rename from lib/main/system/pisystemtests.h rename to libs/main/system/pisystemtests.h diff --git a/lib/main/thread/piblockingqueue.h b/libs/main/thread/piblockingqueue.h similarity index 100% rename from lib/main/thread/piblockingqueue.h rename to libs/main/thread/piblockingqueue.h diff --git a/lib/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp similarity index 100% rename from lib/main/thread/piconditionvar.cpp rename to libs/main/thread/piconditionvar.cpp diff --git a/lib/main/thread/piconditionvar.h b/libs/main/thread/piconditionvar.h similarity index 100% rename from lib/main/thread/piconditionvar.h rename to libs/main/thread/piconditionvar.h diff --git a/lib/main/thread/pigrabberbase.h b/libs/main/thread/pigrabberbase.h similarity index 100% rename from lib/main/thread/pigrabberbase.h rename to libs/main/thread/pigrabberbase.h diff --git a/lib/main/thread/pimutex.cpp b/libs/main/thread/pimutex.cpp similarity index 100% rename from lib/main/thread/pimutex.cpp rename to libs/main/thread/pimutex.cpp diff --git a/lib/main/thread/pimutex.h b/libs/main/thread/pimutex.h similarity index 100% rename from lib/main/thread/pimutex.h rename to libs/main/thread/pimutex.h diff --git a/lib/main/thread/pipipelinethread.h b/libs/main/thread/pipipelinethread.h similarity index 100% rename from lib/main/thread/pipipelinethread.h rename to libs/main/thread/pipipelinethread.h diff --git a/lib/main/thread/pithread.cpp b/libs/main/thread/pithread.cpp similarity index 100% rename from lib/main/thread/pithread.cpp rename to libs/main/thread/pithread.cpp diff --git a/lib/main/thread/pithread.h b/libs/main/thread/pithread.h similarity index 100% rename from lib/main/thread/pithread.h rename to libs/main/thread/pithread.h diff --git a/lib/main/thread/pithreadmodule.h b/libs/main/thread/pithreadmodule.h similarity index 100% rename from lib/main/thread/pithreadmodule.h rename to libs/main/thread/pithreadmodule.h diff --git a/lib/main/thread/pithreadpoolexecutor.cpp b/libs/main/thread/pithreadpoolexecutor.cpp similarity index 100% rename from lib/main/thread/pithreadpoolexecutor.cpp rename to libs/main/thread/pithreadpoolexecutor.cpp diff --git a/lib/main/thread/pithreadpoolexecutor.h b/libs/main/thread/pithreadpoolexecutor.h similarity index 100% rename from lib/main/thread/pithreadpoolexecutor.h rename to libs/main/thread/pithreadpoolexecutor.h diff --git a/lib/main/thread/pitimer.cpp b/libs/main/thread/pitimer.cpp similarity index 100% rename from lib/main/thread/pitimer.cpp rename to libs/main/thread/pitimer.cpp diff --git a/lib/main/thread/pitimer.h b/libs/main/thread/pitimer.h similarity index 100% rename from lib/main/thread/pitimer.h rename to libs/main/thread/pitimer.h diff --git a/lib/opencl/3rd/clcomplex.h b/libs/opencl/3rd/clcomplex.h similarity index 100% rename from lib/opencl/3rd/clcomplex.h rename to libs/opencl/3rd/clcomplex.h diff --git a/lib/opencl/piopencl.cpp b/libs/opencl/piopencl.cpp similarity index 100% rename from lib/opencl/piopencl.cpp rename to libs/opencl/piopencl.cpp diff --git a/lib/opencl/resources.conf b/libs/opencl/resources.conf similarity index 100% rename from lib/opencl/resources.conf rename to libs/opencl/resources.conf diff --git a/lib/usb/piusb.cpp b/libs/usb/piusb.cpp similarity index 100% rename from lib/usb/piusb.cpp rename to libs/usb/piusb.cpp diff --git a/utils/piterminal/main.cpp b/utils/piterminal/main.cpp index eae32a9a..6bdbb4d4 100644 --- a/utils/piterminal/main.cpp +++ b/utils/piterminal/main.cpp @@ -29,7 +29,7 @@ int main (int argc, char * argv[]) { # include "pisharedmemory.h" # include "pifile.h" # include -# include "../../lib/console/piterminal.cpp" +# include "../../libs/console/piterminal.cpp" PIVector > cells; From fec68299c17f9e66f6a7cf88e171c490b44b8031 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 19 Aug 2020 16:22:01 +0300 Subject: [PATCH 53/68] remove install duplicate --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b9f471c8..8cd66980 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -535,7 +535,6 @@ if(LIB) if(WIN32) if(MINGW) if (NOT CROSSTOOLS) - install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) install(FILES ${HDRS} DESTINATION ${MINGW_INCLUDE}/pip) if(HDR_DIRS) install(DIRECTORY ${HDR_DIRS} DESTINATION ${MINGW_INCLUDE}/pip) From 05607ccf0e176899f751725b4f1caf8e17d9cb4e Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 19 Aug 2020 16:48:08 +0300 Subject: [PATCH 54/68] static_assert --- libs/main/containers/picontainers.h | 1 + libs/main/math/pigeometry.h | 2 ++ libs/main/math/pimathbase.h | 2 ++ libs/main/math/pimathmatrix.h | 9 +++++---- libs/main/math/pimathvector.h | 2 ++ libs/main/math/pistatistic.h | 1 + 6 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libs/main/containers/picontainers.h b/libs/main/containers/picontainers.h index 014ddfe6..1d989b65 100644 --- a/libs/main/containers/picontainers.h +++ b/libs/main/containers/picontainers.h @@ -43,6 +43,7 @@ # include #endif #include +#include #include #include #ifndef PIP_MEMALIGN_BYTES diff --git a/libs/main/math/pigeometry.h b/libs/main/math/pigeometry.h index 3a5b75cd..ad2df750 100644 --- a/libs/main/math/pigeometry.h +++ b/libs/main/math/pigeometry.h @@ -28,6 +28,7 @@ template class PIP_EXPORT PIPoint { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); public: Type x; Type y; @@ -75,6 +76,7 @@ typedef PIPoint PIPointd; template class PIP_EXPORT PIRect { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); public: Type x0; Type y0; diff --git a/libs/main/math/pimathbase.h b/libs/main/math/pimathbase.h index d33482b7..0841ac4c 100644 --- a/libs/main/math/pimathbase.h +++ b/libs/main/math/pimathbase.h @@ -131,6 +131,7 @@ inline PIVector abs(const PIVector & v) { template bool OLS_Linear(const PIVector > & input, T * out_a, T * out_b) { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); if (input.size_s() < 2) return false; int n = input.size_s(); @@ -154,6 +155,7 @@ bool OLS_Linear(const PIVector > & input, T * out_a, T * out_b) { template bool WLS_Linear(const PIVector > & input, const PIVector & weights, T * out_a, T * out_b) { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); if (input.size_s() < 2) return false; if (input.size_s() != weights.size_s()) diff --git a/libs/main/math/pimathmatrix.h b/libs/main/math/pimathmatrix.h index 07f27863..676a4486 100644 --- a/libs/main/math/pimathmatrix.h +++ b/libs/main/math/pimathmatrix.h @@ -30,6 +30,7 @@ template inline bool _PIMathMatrixNullCompare(const T v) { + static_assert(std::is_floating_point::value, "Type must be floating point"); return (piAbs(v) < T(1E-200)); } @@ -59,6 +60,9 @@ class PIP_EXPORT PIMathMatrixT { typedef PIMathMatrixT _CMatrixI; typedef PIMathVectorT _CMCol; typedef PIMathVectorT _CMRow; + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); + static_assert(Rows > 0, "Row count must be > 0"); + static_assert(Cols > 0, "Column count must be > 0"); public: PIMathMatrixT() {resize(Rows, Cols);} PIMathMatrixT(const PIVector & val) {resize(Rows, Cols); int i = 0; PIMM_FOR_I_WB(r, c) m[r][c] = val[i++];} @@ -156,10 +160,7 @@ public: } _CMatrix & invert(bool * ok = 0) { - if (Cols != Rows) { - if (ok != 0) *ok = false; - return *this; - } + static_assert(Cols == Rows, "Only square matrix invertable"); _CMatrix mtmp = _CMatrix::identity(), smat(*this); bool ndet; uint crow; diff --git a/libs/main/math/pimathvector.h b/libs/main/math/pimathvector.h index ef7d834e..7c4a9b41 100644 --- a/libs/main/math/pimathvector.h +++ b/libs/main/math/pimathvector.h @@ -36,6 +36,8 @@ class PIMathMatrixT; template class PIP_EXPORT PIMathVectorT { typedef PIMathVectorT _CVector; + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); + static_assert(Size > 0, "Size count must be > 0"); public: PIMathVectorT() {resize();} PIMathVectorT(const PIVector & val) {resize(); PIMV_FOR(i, 0) c[i] = val[i];} diff --git a/libs/main/math/pistatistic.h b/libs/main/math/pistatistic.h index d4e70997..8d731842 100644 --- a/libs/main/math/pistatistic.h +++ b/libs/main/math/pistatistic.h @@ -27,6 +27,7 @@ template class PIStatistic { + static_assert(std::is_arithmetic::value, "Type must be arithmetic"); public: PIStatistic() {mean = variance = skewness = kurtosis = T();} From 6b7004591406c320e130d046abe0a12ab7c49e2c Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Fri, 21 Aug 2020 22:12:11 +0300 Subject: [PATCH 55/68] CMake set_version fix --- cmake/DeployMacros.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cmake/DeployMacros.cmake b/cmake/DeployMacros.cmake index 741351d0..6641b09c 100644 --- a/cmake/DeployMacros.cmake +++ b/cmake/DeployMacros.cmake @@ -172,6 +172,7 @@ macro(set_version _T) set(_is_name 1) set(_is_out 0) set(_out) + #message("set_version \"${_T}\"") foreach(_i ${ARGN}) if (_is_out) set(_is_out 0) @@ -179,13 +180,16 @@ macro(set_version _T) elseif ("x${_i}" STREQUAL "xOUTPUT") set(_is_out 1) elseif(_is_name) + #message("set_version component \"${_i}\"") set(_is_name 0) if (_i IN_LIST __version_names) else() message(FATAL_ERROR "Invalid version component \"${_i}\"!") endif() set(_name ${_i}) + set(${_T}_VERSION_${_name}) else() + #message("set_version value \"${_name}\" = \"${_i}\"") set(_is_name 1) set(${_T}_VERSION_${_name} ${_i}) endif() From f033119a8bf82633146c458d1165377661df1c9f Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Mon, 24 Aug 2020 02:08:23 +0300 Subject: [PATCH 56/68] version 2.3.0_beta optimize PIChunkStream::readAll() optimize PIEvaluator --- CMakeLists.txt | 6 +- libs/main/core/pichunkstream.cpp | 34 +++- libs/main/core/pichunkstream.h | 13 +- libs/main/math/pievaluator.cpp | 307 +++++++++++++++---------------- 4 files changed, 194 insertions(+), 166 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cd66980..62b40b2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,9 +2,9 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) -set(_PIP_MINOR 2) -set(_PIP_REVISION 2) -set(_PIP_SUFFIX _alpha) +set(_PIP_MINOR 3) +set(_PIP_REVISION 0) +set(_PIP_SUFFIX _beta) set(_PIP_COMPANY SHS) set(_PIP_DOMAIN org.SHS) diff --git a/libs/main/core/pichunkstream.cpp b/libs/main/core/pichunkstream.cpp index 34f814ae..c80455d3 100644 --- a/libs/main/core/pichunkstream.cpp +++ b/libs/main/core/pichunkstream.cpp @@ -80,11 +80,36 @@ int PIChunkStream::read() { } +int PIChunkStream::peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret) { + switch (version_) { + case Version_1: + memcpy(&ret, data_->data(pos), 4); + return 4; + case Version_2: { + hdr.resize(4); + hdr.fill(uchar(0)); + memcpy(hdr.data(), data_->data(pos), piMini(4, data_->size_s() - pos)); + uchar hsz = 0; + ret = readVInt(hdr, &hsz); + return hsz; + } + default: break; + } + return 0; +} + + void PIChunkStream::readAll() { data_map.clear(); - while (!atEnd()) { - read(); - data_map[last_id] = last_data; + if (!data_) return; + int pos = 0, sz = data_->size_s(); + uint csz = 0, cid = 0; + PIByteArray hdr; + while (pos < sz) { + pos += peekVInt((Version)version_, data_, pos, hdr, cid); + pos += peekVInt((Version)version_, data_, pos, hdr, csz); + data_map[cid] = PIPair(pos, csz); + pos += csz; } } @@ -111,7 +136,7 @@ void PIChunkStream::_init() { } -uint PIChunkStream::readVInt(PIByteArray & s) { +uint PIChunkStream::readVInt(PIByteArray & s, uchar * bytes_cnt) { if (s.isEmpty()) return 0; uchar bytes[4]; s >> bytes[0]; uchar abc = 0; @@ -122,6 +147,7 @@ uint PIChunkStream::readVInt(PIByteArray & s) { s >> bytes[abc + 1]; } else break; } + if (bytes_cnt) *bytes_cnt = (abc + 1); uint ret = 0; for (int i = 0; i <= abc; ++i) { ret += (bytes[i] << (8 * ((int)abc - i))); diff --git a/libs/main/core/pichunkstream.h b/libs/main/core/pichunkstream.h index 4dec6789..89dad97d 100644 --- a/libs/main/core/pichunkstream.h +++ b/libs/main/core/pichunkstream.h @@ -79,11 +79,11 @@ public: //! Returns stream version Version version() const {return (Version)version_;} - + //! Read one chunk from stream and returns its ID int read(); - //! Read all chunks from stream + //! Read all chunks from stream. This function just index input data void readAll(); //! Returns last readed chunk ID @@ -100,7 +100,9 @@ public: //! Place value of chunk with id \"id\" into \"v\". You should call \a readAll() before using this function! template const PIChunkStream & get(int id, T & v) const { - PIByteArray ba = data_map.value(id); + PIPair pos = data_map.value(id); + if (pos.first < 0 || pos.second == 0) return *this; + PIByteArray ba(data_->data(pos.first), pos.second); if (!ba.isEmpty()) ba >> v; return *this; @@ -109,13 +111,14 @@ public: private: void _init(); - static uint readVInt(PIByteArray & s); + static uint readVInt(PIByteArray & s, uchar * bytes = 0); static void writeVInt(PIByteArray & s, uint val); + static int peekVInt(Version version_, PIByteArray * data_, int pos, PIByteArray & hdr, uint & ret); int last_id; uchar version_; PIByteArray * data_, last_data, tmp_data; - PIMap data_map; + PIMap> data_map; template friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::Chunk & c); template friend PIChunkStream & operator <<(PIChunkStream & s, const PIChunkStream::ChunkConst & c); diff --git a/libs/main/math/pievaluator.cpp b/libs/main/math/pievaluator.cpp index 884e5941..06e3fbf2 100644 --- a/libs/main/math/pievaluator.cpp +++ b/libs/main/math/pievaluator.cpp @@ -122,49 +122,49 @@ using namespace PIEvaluatorTypes; PIEvaluatorContent::PIEvaluatorContent() { - addFunction("arcsin", 1); - addFunction("arccos", 1); - addFunction("arctg", 1); - addFunction("arcctg", 1); - addFunction("random", 2); - addFunction("randomn", 2); - addFunction("sin", 1); - addFunction("cos", 1); - addFunction("ctg", 1); - addFunction("tg", 1); - addFunction("exp", 1); - addFunction("cth", 1); - addFunction("sh", 1); - addFunction("ch", 1); - addFunction("th", 1); - addFunction("sqrt", 1); - addFunction("sqr", 1); - addFunction("pow", 2); - addFunction("abs", 1); - addFunction("ln", 1); - addFunction("lg", 1); - addFunction("log", 2); - addFunction("im", 1); - addFunction("re", 1); - addFunction("arg", 1); - addFunction("len", 1); - addFunction("conj", 1); - addFunction("sign", 1); - addFunction("rad", 1); - addFunction("deg", 1); - addFunction("j0", 1); - addFunction("j1", 1); - addFunction("jn", 2); - addFunction("y0", 1); - addFunction("y1", 1); - addFunction("yn", 2); - addFunction("min", -2); // (x0,x1,...) - addFunction("max", -2); // (x0,x1,...) - addFunction("clamp", 3); // (x,a,b) = x < a ? a : (x > b ? b : x) - addFunction("step", 2); // (x,s) = x >= s ? 1. : 0. (1 if 'x' >= 's', else 0) - addFunction("mix", 3); // (x,a,b) = a*(1.-x) + b*x (interpolate between 'a' and 'b' linear for 'x') - addFunction("defined", 1); - addFunction("round", 1); + addFunction(PIStringAscii("arcsin" ), 1); + addFunction(PIStringAscii("arccos" ), 1); + addFunction(PIStringAscii("arctg" ), 1); + addFunction(PIStringAscii("arcctg" ), 1); + addFunction(PIStringAscii("random" ), 2); + addFunction(PIStringAscii("randomn"), 2); + addFunction(PIStringAscii("sin" ), 1); + addFunction(PIStringAscii("cos" ), 1); + addFunction(PIStringAscii("ctg" ), 1); + addFunction(PIStringAscii("tg" ), 1); + addFunction(PIStringAscii("exp" ), 1); + addFunction(PIStringAscii("cth" ), 1); + addFunction(PIStringAscii("sh" ), 1); + addFunction(PIStringAscii("ch" ), 1); + addFunction(PIStringAscii("th" ), 1); + addFunction(PIStringAscii("sqrt" ), 1); + addFunction(PIStringAscii("sqr" ), 1); + addFunction(PIStringAscii("pow" ), 2); + addFunction(PIStringAscii("abs" ), 1); + addFunction(PIStringAscii("ln" ), 1); + addFunction(PIStringAscii("lg" ), 1); + addFunction(PIStringAscii("log" ), 2); + addFunction(PIStringAscii("im" ), 1); + addFunction(PIStringAscii("re" ), 1); + addFunction(PIStringAscii("arg" ), 1); + addFunction(PIStringAscii("len" ), 1); + addFunction(PIStringAscii("conj" ), 1); + addFunction(PIStringAscii("sign" ), 1); + addFunction(PIStringAscii("rad" ), 1); + addFunction(PIStringAscii("deg" ), 1); + addFunction(PIStringAscii("j0" ), 1); + addFunction(PIStringAscii("j1" ), 1); + addFunction(PIStringAscii("jn" ), 2); + addFunction(PIStringAscii("y0" ), 1); + addFunction(PIStringAscii("y1" ), 1); + addFunction(PIStringAscii("yn" ), 2); + addFunction(PIStringAscii("min" ), -2); // (x0,x1,...) + addFunction(PIStringAscii("max" ), -2); // (x0,x1,...) + addFunction(PIStringAscii("clamp" ), 3); // (x,a,b) = x < a ? a : (x > b ? b : x) + addFunction(PIStringAscii("step" ), 2); // (x,s) = x >= s ? 1. : 0. (1 if 'x' >= 's', else 0) + addFunction(PIStringAscii("mix" ), 3); // (x,a,b) = a*(1.-x) + b*x (interpolate between 'a' and 'b' linear for 'x') + addFunction(PIStringAscii("defined"), 1); + addFunction(PIStringAscii("round" ), 1); clearCustomVariables(); } @@ -185,9 +185,9 @@ bool PIEvaluatorContent::setVariableName(int index, const PIString & new_name) { void PIEvaluatorContent::clearCustomVariables() { variables.clear(); - addVariable("i", complexd_i); - addVariable("pi", atan(1.) * 4.); - addVariable("e", exp(1.)); + addVariable(PIStringAscii("i" ), complexd_i); + addVariable(PIStringAscii("pi"), atan(1.) * 4.); + addVariable(PIStringAscii("e" ), exp(1.)); cv_count = variables.size(); } @@ -203,56 +203,56 @@ void PIEvaluatorContent::sortVariables() { BaseFunctions PIEvaluatorContent::getBaseFunction(const PIString & name) { - if (name == "sin") return bfSin; - if (name == "cos") return bfCos; - if (name == "tg") return bfTg; - if (name == "ctg") return bfCtg; - if (name == "arcsin") return bfArcsin; - if (name == "arccos") return bfArccos; - if (name == "arctg") return bfArctg; - if (name == "arcctg") return bfArcctg; - if (name == "exp") return bfExp; - if (name == "random") return bfRandom; - if (name == "randomn") return bfRandomn; - if (name == "sh") return bfSh; - if (name == "ch") return bfCh; - if (name == "th") return bfTh; - if (name == "cth") return bfCth; - if (name == "sqrt") return bfSqrt; - if (name == "sqr") return bfSqr; - if (name == "pow") return bfPow; - if (name == "abs") return bfAbs; - if (name == "ln") return bfLn; - if (name == "lg") return bfLg; - if (name == "log") return bfLog; - if (name == "im") return bfIm; - if (name == "re") return bfRe; - if (name == "arg") return bfArg; - if (name == "len") return bfLen; - if (name == "conj") return bfConj; - if (name == "sign") return bfSign; - if (name == "rad") return bfRad; - if (name == "deg") return bfDeg; - if (name == "j0") return bfJ0; - if (name == "j1") return bfJ1; - if (name == "jn") return bfJN; - if (name == "y0") return bfY0; - if (name == "y1") return bfY1; - if (name == "yn") return bfYN; - if (name == "min") return bfMin; - if (name == "max") return bfMax; - if (name == "clamp") return bfClamp; - if (name == "step") return bfStep; - if (name == "mix") return bfMix; - if (name == "defined") return bfDefined; - if (name == "round") return bfRound; + if (name == PIStringAscii("sin" )) return bfSin; + if (name == PIStringAscii("cos" )) return bfCos; + if (name == PIStringAscii("tg" )) return bfTg; + if (name == PIStringAscii("ctg" )) return bfCtg; + if (name == PIStringAscii("arcsin" )) return bfArcsin; + if (name == PIStringAscii("arccos" )) return bfArccos; + if (name == PIStringAscii("arctg" )) return bfArctg; + if (name == PIStringAscii("arcctg" )) return bfArcctg; + if (name == PIStringAscii("exp" )) return bfExp; + if (name == PIStringAscii("random" )) return bfRandom; + if (name == PIStringAscii("randomn")) return bfRandomn; + if (name == PIStringAscii("sh" )) return bfSh; + if (name == PIStringAscii("ch" )) return bfCh; + if (name == PIStringAscii("th" )) return bfTh; + if (name == PIStringAscii("cth" )) return bfCth; + if (name == PIStringAscii("sqrt" )) return bfSqrt; + if (name == PIStringAscii("sqr" )) return bfSqr; + if (name == PIStringAscii("pow" )) return bfPow; + if (name == PIStringAscii("abs" )) return bfAbs; + if (name == PIStringAscii("ln" )) return bfLn; + if (name == PIStringAscii("lg" )) return bfLg; + if (name == PIStringAscii("log" )) return bfLog; + if (name == PIStringAscii("im" )) return bfIm; + if (name == PIStringAscii("re" )) return bfRe; + if (name == PIStringAscii("arg" )) return bfArg; + if (name == PIStringAscii("len" )) return bfLen; + if (name == PIStringAscii("conj" )) return bfConj; + if (name == PIStringAscii("sign" )) return bfSign; + if (name == PIStringAscii("rad" )) return bfRad; + if (name == PIStringAscii("deg" )) return bfDeg; + if (name == PIStringAscii("j0" )) return bfJ0; + if (name == PIStringAscii("j1" )) return bfJ1; + if (name == PIStringAscii("jn" )) return bfJN; + if (name == PIStringAscii("y0" )) return bfY0; + if (name == PIStringAscii("y1" )) return bfY1; + if (name == PIStringAscii("yn" )) return bfYN; + if (name == PIStringAscii("min" )) return bfMin; + if (name == PIStringAscii("max" )) return bfMax; + if (name == PIStringAscii("clamp" )) return bfClamp; + if (name == PIStringAscii("step" )) return bfStep; + if (name == PIStringAscii("mix" )) return bfMix; + if (name == PIStringAscii("defined")) return bfDefined; + if (name == PIStringAscii("round" )) return bfRound; return bfUnknown; } const PIString & PIEvaluator::prepare(const PIString & string) { currentString = string.trimmed(); - if (currentString.isEmpty()) currentString = "0"; + if (currentString.isEmpty()) currentString = PIStringAscii("0"); replaceOperators(); removeSpaces(); checkBrackets(); @@ -281,7 +281,8 @@ void PIEvaluator::removeJunk() { bool junk = true; int bcnt; while (junk) { - if (currentString.left(1) != "(" || currentString.right(1) != ")") return; + if (currentString.isEmpty()) return; + if (currentString.front() != '(' || currentString.back() != ')') return; bcnt = 1; junk = false; for (int i = 1; i < currentString.length(); i++) { @@ -303,26 +304,26 @@ void PIEvaluator::removeJunk() { void PIEvaluator::replaceOperators() { - currentString.replaceAll("==", "="); - currentString.replaceAll("!=", ":"); - currentString.replaceAll(">=", "}"); - currentString.replaceAll("<=", "{"); - currentString.replaceAll("&&", "&"); - currentString.replaceAll("||", "|"); - currentString.replaceAll(PIString::fromUTF8("≠"), ":"); - currentString.replaceAll(PIString::fromUTF8("≥"), "}"); - currentString.replaceAll(PIString::fromUTF8("≤"), "{"); - currentString.replaceAll(PIString::fromUTF8("⋀"), "&"); - currentString.replaceAll(PIString::fromUTF8("⋁"), "|"); + currentString.replaceAll(PIStringAscii("=="), '='); + currentString.replaceAll(PIStringAscii("!="), ':'); + currentString.replaceAll(PIStringAscii(">="), '}'); + currentString.replaceAll(PIStringAscii("<="), '{'); + currentString.replaceAll(PIStringAscii("&&"), '&'); + currentString.replaceAll(PIStringAscii("||"), '|'); + currentString.replaceAll(PIString::fromUTF8("≠"), ':'); + currentString.replaceAll(PIString::fromUTF8("≥"), '}'); + currentString.replaceAll(PIString::fromUTF8("≤"), '{'); + currentString.replaceAll(PIString::fromUTF8("⋀"), '&'); + currentString.replaceAll(PIString::fromUTF8("⋁"), '|'); } void PIEvaluator::makeOutput(PIString & string) { - string.replaceAll(":", PIString::fromUTF8("≠")); - string.replaceAll("}", PIString::fromUTF8("≥")); - string.replaceAll("{", PIString::fromUTF8("≤")); - string.replaceAll("&", PIString::fromUTF8("⋀")); - string.replaceAll("|", PIString::fromUTF8("⋁")); + string.replaceAll(PIStringAscii(":"), PIString::fromUTF8("≠")); + string.replaceAll(PIStringAscii("}"), PIString::fromUTF8("≥")); + string.replaceAll(PIStringAscii("{"), PIString::fromUTF8("≤")); + string.replaceAll(PIStringAscii("&"), PIString::fromUTF8("⋀")); + string.replaceAll(PIStringAscii("|"), PIString::fromUTF8("⋁")); } @@ -334,7 +335,7 @@ void PIEvaluator::findUnknownVariables() { else { if (cvar.length() == 0) continue; unknownVars << cvar; - cvar = ""; + cvar.clear(); } } if (cvar.length() > 0) unknownVars << cvar; @@ -343,16 +344,13 @@ void PIEvaluator::findUnknownVariables() { bool PIEvaluator::isSign(const PIChar & ch) { - return ch == '+' || ch == '-' || - ch == '*' || ch == '/' || - ch == '%' || ch == '^' || - ch == '=' || ch == ':' || - ch == '>' || ch == '<' || - ch == '}' || ch == '{' || - ch == '&' || ch == '|'; + static PIString signs = PIStringAscii("+-*/%^=:><}{&|"); + if (!ch.isAscii()) return false; + return signs.contains(ch.toAscii()); } + void PIEvaluator::checkBrackets() { PIString tmps = currentString; PIChar fc, sc; @@ -365,7 +363,7 @@ void PIEvaluator::checkBrackets() { } if (tmps[i] == ')') { if (bcnt == 0) { - currentString.insert(bpos + inserted, "("); + currentString.insert(bpos + inserted, '('); inserted++; } else bcnt--; } @@ -428,7 +426,7 @@ bool PIEvaluator::fillElements() { cnum++; } } - curfind = ""; + curfind.clear(); cnum = 1; for (int i = 0; i < tmps.length(); i++) { cc = tmps[i]; @@ -496,19 +494,19 @@ bool PIEvaluator::fillElements() { break; } if (numFound) { - currentVariables.push_back(Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble())); + currentVariables.push_back(Variable(PIStringAscii("tmp") + PIString::fromNumber(cnum), curfind.toDouble())); for (int j = i - curfind.length(); j < i; j++) { elements[j].set(etNumber, cnum, -cnum); tmps.replace(j, 1, fc); } - curfind = ""; + curfind.clear(); cnum++; cpart = 0; numFound = false; } } if (cpart > 0) { - currentVariables.push_back(Variable("tmp" + PIString::fromNumber(cnum), curfind.toDouble())); + currentVariables.push_back(Variable(PIStringAscii("tmp") + PIString::fromNumber(cnum), curfind.toDouble())); for (int j = tmps.length() - curfind.length(); j < tmps.length(); j++) { elements[j].set(etNumber, cnum, -cnum); tmps.replace(j, 1, fc); @@ -584,11 +582,11 @@ bool PIEvaluator::setSignes() { if (elements[pi].type == etOperator && (elements[ni].type == etFunction || elements[ni].type == etVariable) && fc == '-') needInsert = 3; switch (needInsert) { case 1: - currentString.insert(ni + inserted, "*"); + currentString.insert(ni + inserted, '*'); elements.insert(ni + inserted, Element(etOperator, -1)); return true; case 3: - currentString.insert(ni + inserted, "1*"); + currentString.insert(ni + inserted, PIStringAscii("1*")); elements.insert(ni + inserted, Element(etOperator, -1)); return true; } @@ -609,7 +607,7 @@ void PIEvaluator::convert() { if (ce != pe) break; j++; } - currentString.replace(i, j - i, " "); + currentString.replace(i, j - i, ' '); for (int k = i + 1; k < j; k++) elements.remove(i); } for (int i = 0; i < currentString.length(); i++) { @@ -621,7 +619,7 @@ void PIEvaluator::convert() { if (ce != pe) break; j++; } - currentString.replace(i, j - i, " "); + currentString.replace(i, j - i, ' '); for (int k = i + 1; k < j; k++) elements.remove(i); } for (int i = 0; i < currentString.length(); i++) { @@ -633,7 +631,7 @@ void PIEvaluator::convert() { if (ce != pe) break; j++; } - currentString.replace(i, j - i, " "); + currentString.replace(i, j - i, ' '); for (int k = i + 1; k < j; k++) elements.remove(i); } /*cout << " "; @@ -707,7 +705,7 @@ int PIEvaluator::parse(const PIString & string, int offset) { cfunc = content.function(ce.var_num); atmp.clear(); bcnt = farg = 1; - carg = ""; + carg.clear(); k = i + 1; while (bcnt > 0) { cc = string[k]; @@ -719,7 +717,7 @@ int PIEvaluator::parse(const PIString & string, int offset) { ///qDebug() << "arument: " << carg; atmp.push_back(parse(carg, k + offset - carg.length())); k++; - carg = ""; + carg.clear(); if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back(); continue; } @@ -729,7 +727,7 @@ int PIEvaluator::parse(const PIString & string, int offset) { ///qDebug() << "arument: " << carg; atmp.push_back(parse(carg, k + offset - carg.length())); k++; - carg = ""; + carg.clear(); if (atmp.size_s() > 0) if (atmp.back() < 0 && farg > 0) farg = atmp.back(); continue; } @@ -818,7 +816,7 @@ bool PIEvaluator::check() { Instruction ci; bool error; if (unknownVars.size_s() > 0) { - lastError = "Unknown variables: \"" + unknownVars.join("\", \"") + "\""; + lastError = PIStringAscii("Unknown variables: \"") + unknownVars.join("\", \"") + PIStringAscii("\""); return false; } for (int i = 0; i < instructions.size_s(); i++) { @@ -840,25 +838,25 @@ bool PIEvaluator::check() { } if (fac > 0) { if (gac != fac) { - lastError = "Invalid arguments count for function \"" + cf.identifier + - "\", expected " + PIString::fromNumber(fac) + " but " + - PIString::fromNumber(gac) + " given"; + lastError = PIStringAscii("Invalid arguments count for function \"") + cf.identifier + + PIStringAscii("\", expected ") + PIString::fromNumber(fac) + PIStringAscii(" but ") + + PIString::fromNumber(gac) + PIStringAscii(" given"); return false; } if (error) { - lastError = "Invalid at least one of function \"" + cf.identifier + "\" argument"; + lastError = PIStringAscii("Invalid at least one of function \"") + cf.identifier + PIStringAscii("\" argument"); return false; } } if (fac < 0) { if (gac < -fac) { - lastError = "Invalid arguments count for function \"" + cf.identifier + - "\", expected at least " + PIString::fromNumber(-fac) + " but " + - PIString::fromNumber(gac) + " given"; + lastError = PIStringAscii("Invalid arguments count for function \"") + cf.identifier + + PIStringAscii("\", expected at least ") + PIString::fromNumber(-fac) + PIStringAscii(" but ") + + PIString::fromNumber(gac) + PIStringAscii(" given"); return false; } if (error) { - lastError = "Invalid at least one of function \"" + cf.identifier + "\" argument"; + lastError = PIStringAscii("Invalid at least one of function \"") + cf.identifier + PIStringAscii("\" argument"); return false; } } @@ -866,18 +864,18 @@ bool PIEvaluator::check() { default: if (ci.operators[0] == -666 || ci.operators[1] == -666) error = true; if (ci.operators.size_s() != 2 || error) { - lastError = "Invalid arguments count for operation \" " + operationChar(ci.operation) + " \""; + lastError = PIStringAscii("Invalid arguments count for operation \" ") + operationChar(ci.operation) + PIStringAscii(" \""); return false; } break; } if (ci.out < -variables.size_s()) { - lastError = "Invalid variable index \"" + PIString::fromNumber(ci.out) + "\""; + lastError = PIStringAscii("Invalid variable index \"") + PIString::fromNumber(ci.out) + PIStringAscii("\""); return false; } for (int j = 0; j < ci.operators.size_s(); j++) { if (ci.operators[j] < -variables.size_s() || ci.operators[j] >= kvars->size_s()) { - lastError = "Invalid variable index \"" + PIString::fromNumber(ci.operators[j]) + "\""; + lastError = PIStringAscii("Invalid variable index \"") + PIString::fromNumber(ci.operators[j]) + PIStringAscii("\""); return false; } } @@ -903,22 +901,23 @@ PIString PIEvaluator::inBrackets(const PIString & string) { PIString PIEvaluator::operationChar(const Operation & operation) { switch (operation) { - case oAdd: return "+"; - case oSubtract: return "-"; - case oMultiply: return "*"; - case oDivide: return "/"; - case oPower: return "^"; - case oResidue: return "%"; - case oEqual: return "="; - case oNotEqual: return PIString::fromUTF8("≠"); + case oAdd : return PIStringAscii("+"); + case oSubtract : return PIStringAscii("-"); + case oMultiply : return PIStringAscii("*"); + case oDivide : return PIStringAscii("/"); + case oPower : return PIStringAscii("^"); + case oResidue : return PIStringAscii("%"); + case oEqual : return PIStringAscii("="); + case oNotEqual : return PIString::fromUTF8("≠"); case oGreaterEqual: return PIString::fromUTF8("≥"); case oSmallerEqual: return PIString::fromUTF8("≤"); - case oGreater: return ">"; - case oSmaller: return "<"; - case oAnd: return PIString::fromUTF8("⋀"); - case oOr: return PIString::fromUTF8("⋁"); - default: return "???"; + case oGreater : return PIStringAscii(">"); + case oSmaller : return PIStringAscii("<"); + case oAnd : return PIString::fromUTF8("⋀"); + case oOr : return PIString::fromUTF8("⋁"); + default: break; } + return PIStringAscii("???"); } @@ -1182,7 +1181,7 @@ bool PIEvaluator::check(const PIString & string) { instructions.clear(); return false; } - lastError = "Correct"; + lastError = PIStringAscii("Correct"); return true; } From 3965e54e38cbb23e8103e1e09a49910d5b5957b3 Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 24 Aug 2020 13:23:31 +0300 Subject: [PATCH 57/68] start develop picloud --- CMakeLists.txt | 2 +- .../{piccloudclient.cpp => picloudclient.cpp} | 2 +- .../{piccloudserver.cpp => picloudserver.cpp} | 29 +- .../cloud/{piccloudtcp.cpp => picloudtcp.cpp} | 2 +- .../{piccloudclient.h => picloudclient.h} | 8 +- .../{piccloudmodule.h => picloudmodule.h} | 6 +- .../{piccloudserver.h => picloudserver.h} | 22 +- .../cloud/{piccloudtcp.h => picloudtcp.h} | 9 +- libs/main/pip.h | 1 + main.cpp | 263 +----------------- 10 files changed, 67 insertions(+), 277 deletions(-) rename libs/cloud/{piccloudclient.cpp => picloudclient.cpp} (93%) rename libs/cloud/{piccloudserver.cpp => picloudserver.cpp} (54%) rename libs/cloud/{piccloudtcp.cpp => picloudtcp.cpp} (94%) rename libs/main/cloud/{piccloudclient.h => picloudclient.h} (91%) rename libs/main/cloud/{piccloudmodule.h => picloudmodule.h} (91%) rename libs/main/cloud/{piccloudserver.h => picloudserver.h} (68%) rename libs/main/cloud/{piccloudtcp.h => picloudtcp.h} (91%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62b40b2c..6be1e71f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -498,7 +498,7 @@ if (NOT CROSSTOOLS) # Test program if(PIP_UTILS) add_executable(pip_test "main.cpp") - target_link_libraries(pip_test pip) + target_link_libraries(pip_test pip pip_cloud) if (LUA_FOUND) target_link_libraries(pip_test pip_lua ${LUA_LIBRARIES}) endif() diff --git a/libs/cloud/piccloudclient.cpp b/libs/cloud/picloudclient.cpp similarity index 93% rename from libs/cloud/piccloudclient.cpp rename to libs/cloud/picloudclient.cpp index b17a2362..e3a950a0 100644 --- a/libs/cloud/piccloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -17,7 +17,7 @@ along with this program. If not, see . */ -#include "piccloudclient.h" +#include "picloudclient.h" PICloudClient::PICloudClient() { diff --git a/libs/cloud/piccloudserver.cpp b/libs/cloud/picloudserver.cpp similarity index 54% rename from libs/cloud/piccloudserver.cpp rename to libs/cloud/picloudserver.cpp index 45f98ed3..a6210e9b 100644 --- a/libs/cloud/piccloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -17,9 +17,34 @@ along with this program. If not, see . */ -#include "piccloudserver.h" +#include "picloudserver.h" +#include "piethernet.h" -PICloudServer::PICloudServer() { +PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) { + eth = new PIEthernet(PIEthernet::TCP_Client); +} + + +PICloudServer::~PICloudServer() { + +} + + +bool PICloudServer::openDevice() { + piCout << "PICloudServer open device" << path(); + bool op = eth->connect(path(), false); + if (op) { + CONNECTL(eth, disconnected, [this](bool){eth->connect(path());}); + eth->startThreadedRead(); + return true; + } + return false; +} + + +bool PICloudServer::closeDevice() { + eth->stopThreadedRead(); + return eth->close(); } diff --git a/libs/cloud/piccloudtcp.cpp b/libs/cloud/picloudtcp.cpp similarity index 94% rename from libs/cloud/piccloudtcp.cpp rename to libs/cloud/picloudtcp.cpp index a977288e..80786a1d 100644 --- a/libs/cloud/piccloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -17,7 +17,7 @@ along with this program. If not, see . */ -#include "piccloudtcp.h" +#include "picloudtcp.h" #include "picrypt.h" const char hash_def_key[] = "_picrypt_"; diff --git a/libs/main/cloud/piccloudclient.h b/libs/main/cloud/picloudclient.h similarity index 91% rename from libs/main/cloud/piccloudclient.h rename to libs/main/cloud/picloudclient.h index b54cd73c..6de937a4 100644 --- a/libs/main/cloud/piccloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -1,4 +1,4 @@ -/*! \file piccloudclient.h +/*! \file picloudclient.h * \brief PICloud Client */ /* @@ -20,8 +20,8 @@ along with this program. If not, see . */ -#ifndef PICCLOUDCLIENT_H -#define PICCLOUDCLIENT_H +#ifndef PICLOUDCLIENT_H +#define PICLOUDCLIENT_H #include "pip_cloud_export.h" #include "piiodevice.h" @@ -45,4 +45,4 @@ private: PIEthernet * eth; }; -#endif // PICCLOUDCLIENT_H +#endif // PICLOUDCLIENT_H diff --git a/libs/main/cloud/piccloudmodule.h b/libs/main/cloud/picloudmodule.h similarity index 91% rename from libs/main/cloud/piccloudmodule.h rename to libs/main/cloud/picloudmodule.h index 2c37522e..f357f7bc 100644 --- a/libs/main/cloud/piccloudmodule.h +++ b/libs/main/cloud/picloudmodule.h @@ -20,8 +20,8 @@ #ifndef PICLOUDMODULE_H #define PICLOUDMODULE_H -#include "piccloudtcp.h" -#include "piccloudclient.h" -#include "piccloudserver.h" +#include "picloudtcp.h" +#include "picloudclient.h" +#include "picloudserver.h" #endif // PICLOUDMODULE_H diff --git a/libs/main/cloud/piccloudserver.h b/libs/main/cloud/picloudserver.h similarity index 68% rename from libs/main/cloud/piccloudserver.h rename to libs/main/cloud/picloudserver.h index cf0e4e23..b91bf398 100644 --- a/libs/main/cloud/piccloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -1,4 +1,4 @@ -/*! \file piccloudserver.h +/*! \file picloudserver.h * \brief PICloud Server */ /* @@ -20,21 +20,29 @@ along with this program. If not, see . */ -#ifndef PICCLOUDSERVER_H -#define PICCLOUDSERVER_H +#ifndef PICLOUDSERVER_H +#define PICLOUDSERVER_H #include "pip_cloud_export.h" #include "piiodevice.h" +class PIEthernet; -class PIP_CLOUD_EXPORT PICloudServer { + +class PIP_CLOUD_EXPORT PICloudServer : public PIIODevice +{ + PIIODEVICE(PICloudServer) public: //! - explicit PICloudServer(); + explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); + virtual ~PICloudServer(); +protected: + bool openDevice(); + bool closeDevice(); private: - + PIEthernet * eth; }; -#endif // PICCLOUDSERVER_H +#endif // PICLOUDSERVER_H diff --git a/libs/main/cloud/piccloudtcp.h b/libs/main/cloud/picloudtcp.h similarity index 91% rename from libs/main/cloud/piccloudtcp.h rename to libs/main/cloud/picloudtcp.h index ea0e4f5c..5b7f1309 100644 --- a/libs/main/cloud/piccloudtcp.h +++ b/libs/main/cloud/picloudtcp.h @@ -1,4 +1,4 @@ -/*! \file piccloudtcp.h +/*! \file picloudtcp.h * \brief PICloud TCP transport */ /* @@ -20,12 +20,13 @@ along with this program. If not, see . */ -#ifndef PICCLOUDTCP_H -#define PICCLOUDTCP_H +#ifndef PICLOUDTCP_H +#define PICLOUDTCP_H #include "pip_cloud_export.h" #include "pistring.h" + class PIP_CLOUD_EXPORT PICloudTCP { public: //! @@ -36,4 +37,4 @@ private: }; -#endif // PICCLOUDTCP_H +#endif // PICLOUDTCP_H diff --git a/libs/main/pip.h b/libs/main/pip.h index a0a5e97f..91a95569 100644 --- a/libs/main/pip.h +++ b/libs/main/pip.h @@ -30,5 +30,6 @@ #include "pisystemmodule.h" #include "pigeomodule.h" #include "picryptmodule.h" +#include "picloudmodule.h" #endif // PIP_H diff --git a/main.cpp b/main.cpp index 511302a7..d1442618 100644 --- a/main.cpp +++ b/main.cpp @@ -1,259 +1,14 @@ #include "pip.h" -PIMap results; - - -template -struct __VariantTypeInfo__ { - typedef T PureType; - typedef const T ConstPureType; - typedef T * PointerType; - typedef const T * ConstPointerType; - typedef T & ReferenceType; - typedef const T & ConstReferenceType; -}; - -#define __TYPEINFO_SINGLE(PT, T) \ - template<> struct __PIVariantTypeInfo__ { \ - typedef PT PureType; \ - typedef const PT ConstPureType; \ - typedef PT * PointerType; \ - typedef const PT * ConstPointerType; \ - typedef PT & ReferenceType; \ - typedef const PT & ConstReferenceType; \ - }; - -#define REGISTER_VARIANT_TYPEINFO(T) \ - __TYPEINFO_SINGLE(T, T &) \ - __TYPEINFO_SINGLE(T, const T) \ - __TYPEINFO_SINGLE(T, const T &) - - - - -class __VariantFunctionsBase__ { -public: - virtual __VariantFunctionsBase__ * instance() {return 0;} - virtual PIString typeName() const {return PIString();} - virtual uint hash() const {return 0;} - virtual void newT(void *& ptr, const void * value) {;} - virtual void newNullT(void *& ptr) {;} - virtual void equalT(void *& ptr, const void * value) {;} - virtual void deleteT(void *& ptr) {;} - virtual PIByteArray toData(const void * ptr) const {return PIByteArray();} - virtual void fromData(void *& ptr, PIByteArray ba) {;} - //template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} - //template static C castVariant(const T & v) {return C();} - static PIMap & registered() {static PIMap ret; return ret;} -}; - - -template -class __VariantFunctions__: public __VariantFunctionsBase__ { -public: - __VariantFunctionsBase__ * instance() override {static __VariantFunctions__ ret; return &ret;} - PIString typeName() const override {return PIString();} - uint hash() const override {static uint ret = typeName().hash(); return ret;} - void newT(void *& ptr, const void * value) override {ptr = (void*)(new T(*(const T*)value)); printf(" * new\n");} - void newNullT(void *& ptr) override {ptr = (void*)(new T()); printf(" * new null\n");} - void equalT(void *& ptr, const void * value) override {*(T*)ptr = *(const T*)value; printf(" * =\n");} - void deleteT(void *& ptr) override {delete (T*)(ptr); printf(" * del\n");} - PIByteArray toData(const void * ptr) const override {PIByteArray ret; ret << (*(const T* &)ptr); return ret;} - void fromData(void *& ptr, PIByteArray ba) override {ba >> *(T*)ptr;} - - template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} - template static C castVariant(const T & v) {return C();} -}; - -class Variant { -public: - Variant() {ptr = 0; f = 0;} - Variant(const Variant & v) { - ptr = 0; - f = v.f; - if (f && v.ptr) - f->newT(ptr, v.ptr); - } - ~Variant() {destroy();} - - Variant & operator=(const Variant & v) { - destroy(); - f = v.f; - if (f && v.ptr) - f->newT(ptr, v.ptr); - return *this; - } - - template - void setValue(const T & v) { - if (f) { - if (isMyType()) { - f->equalT(ptr, (const void *)&v); - return; - } - } - destroy(); - f = __VariantFunctions__().instance(); - f->newT(ptr, (const void *)&v); - } - - template - T value() const { - if (!f) return T(); - if (!isMyType()) - return T(); - return *(T*)(ptr); - } - - PIByteArray save() const { - if (!ptr || !f) return PIByteArray(); - PIByteArray ret; - ret << f->hash(); - ret.append(f->toData(ptr)); - return ret; - } - - bool load(PIByteArray ba) { - if (ba.size_s() < 4) return false; - uint h(0); ba >> h; - destroy(); - f = __VariantFunctionsBase__::registered().value(h, 0); - if (!f) return false; - f->newNullT(ptr); - f->fromData(ptr, ba); - return true; - } - -//private: - template - bool isMyType() const {return f->hash() == __VariantFunctions__().instance()->hash();} - - void destroy() { - if (ptr && f) - f->deleteT(ptr); - ptr = 0; - f = 0; - } - - void * ptr; - __VariantFunctionsBase__ * f; - -}; - -int Acnt = 0; - -class A { -public: - A() {i = "constructor"; /*piCout << "A()";*/ ++Acnt;} - A(const A & a): i(a.i) {/*piCout << "copy A()";*/ ++Acnt;} - ~A() {/*piCout << "~A()";*/ --Acnt;} - A & operator =(const A & a) {i = a.i; /*piCout << "= A()";*/ return *this;} - PIString i; -}; -PIByteArray & operator <<(PIByteArray & ba, const A & v) {ba << v.i; return ba;} -PIByteArray & operator >>(PIByteArray & ba, A & v) {ba >> v.i; return ba;} - - -template <> -PIString __VariantFunctions__::typeName() const {static PIString ret("int"); return ret;} -class _VariantRegistrator_int__ { -public: - _VariantRegistrator_int__() { - __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); - __VariantFunctionsBase__::registered()[f->hash()] = f; - } -}; -_VariantRegistrator_int__ __reg_int__; - -template <> -PIString __VariantFunctions__::typeName() const {static PIString ret("A"); return ret;} -class _VariantRegistrator_A__ { -public: - _VariantRegistrator_A__() { - __VariantFunctionsBase__ * f = __VariantFunctions__().instance(); - __VariantFunctionsBase__::registered()[f->hash()] = f; - } -}; -_VariantRegistrator_A__ __reg_A__; - - int main() { - { - - Variant v, v2; - - /*{ - A a, ra; - - a.i = "main"; - v.setValue(a); - - ra = v.value(); - piCout << " 1 A.i =" << ra.i; - - a.i = "main second"; - v.setValue(a); - - ra = v.value(); - piCout << " 2 A.i =" << ra.i; - - piCout << "Acnt" << Acnt; + PICloudServer s("127.0.0.1:10101"); + for (int i=0; i<3; ++i) { + s.open(); + piCout() << "opened"; + piSleep(1); + s.close(); + piCout() << "closed"; + piSleep(1); } - piCout << "Acnt" << Acnt; - - v2 = v; - PIString ra = v2.value(); - piCout << " 3 A.i =" << ra;*/ - - A a, ra; - - a.i = "main"; - v.setValue(a); - PIByteArray ba = v.save(); - - piCout << v2.load(ba); - piCout << v2.value().i; - - } - piCout << "Acnt" << Acnt; - //__VariantFunctionsBase__ * f = __VariantFunctions__().instance(); - //piCout << f->typeName(); - //f = __VariantFunctions__().instance(); - //piCout << f->typeName(); + return 0; } - -/* -template -void test_var(const char * Tname) { - piCout << Tname << "..."; - ullong cnt = 0; - PIVariant _v; - PITimeMeasurer tm1s; - while (tm1s.elapsed_m() < 500.) { - ++cnt; - for (int j = 0; j < 1000; ++j) { - PIVariant v; - v = T(); - v.setValue(T(j)); - _v = v; - } - } - PIVariant v; - results[Tname] = cnt; -} - -#define TEST_VAR(T) test_var(#T) - -int main() { - TEST_VAR(int); - TEST_VAR(float); - TEST_VAR(ullong); - TEST_VAR(PIString); - int sz = 0; - auto i = results.makeIterator(); - while (i.next()) sz = piMaxi(sz, i.key().length()); - i.reset(); - while (i.next()) - piCout << i.key().expandedLeftTo(sz, ' ') << ":" << i.value(); -} -*/ From cfebf8cf23e49f44ad82357a0ee3324c578293d4 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 26 Aug 2020 17:28:56 +0300 Subject: [PATCH 58/68] cloud test --- libs/cloud/picloudserver.cpp | 24 ++++++++---- libs/main/cloud/picloudserver.h | 7 +++- libs/main/io_devices/piethernet.cpp | 3 +- main.cpp | 19 +++++---- utils/cloud_dispatcher/cloudserver.cpp | 5 +++ utils/cloud_dispatcher/cloudserver.h | 12 ++++++ utils/cloud_dispatcher/dispatcherclient.cpp | 8 ++++ utils/cloud_dispatcher/dispatcherclient.h | 8 +++- utils/cloud_dispatcher/dispatcherserver.cpp | 43 ++++++++++++++++----- utils/cloud_dispatcher/dispatcherserver.h | 10 ++++- utils/cloud_dispatcher/main.cpp | 3 ++ 11 files changed, 110 insertions(+), 32 deletions(-) create mode 100644 utils/cloud_dispatcher/cloudserver.cpp create mode 100644 utils/cloud_dispatcher/cloudserver.h diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index a6210e9b..2bef35f7 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -18,11 +18,9 @@ */ #include "picloudserver.h" -#include "piethernet.h" -PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) { - eth = new PIEthernet(PIEthernet::TCP_Client); +PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) { } @@ -33,18 +31,28 @@ PICloudServer::~PICloudServer() { bool PICloudServer::openDevice() { piCout << "PICloudServer open device" << path(); - bool op = eth->connect(path(), false); + bool op = eth.connect(path(), false); if (op) { - CONNECTL(eth, disconnected, [this](bool){eth->connect(path());}); - eth->startThreadedRead(); return true; + } else { + eth.close(); } return false; } bool PICloudServer::closeDevice() { - eth->stopThreadedRead(); - return eth->close(); + return eth.close(); } + +int PICloudServer::readDevice(void * read_to, int max_size) { + return eth.read(read_to, max_size); +} + + +int PICloudServer::writeDevice(const void * data, int max_size) { + return eth.write(data, max_size); +} + + diff --git a/libs/main/cloud/picloudserver.h b/libs/main/cloud/picloudserver.h index b91bf398..a7e3da2a 100644 --- a/libs/main/cloud/picloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -24,7 +24,7 @@ #define PICLOUDSERVER_H #include "pip_cloud_export.h" -#include "piiodevice.h" +#include "piethernet.h" class PIEthernet; @@ -40,9 +40,12 @@ public: protected: bool openDevice(); bool closeDevice(); + int readDevice(void * read_to, int max_size); + int writeDevice(const void * data, int max_size); private: - PIEthernet * eth; + PIEthernet eth; + }; #endif // PICLOUDSERVER_H diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index 6f44cfff..2867b069 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -564,8 +564,9 @@ bool PIEthernet::connect(bool threaded) { PRIVATE->addr_.sin_len = sizeof(PRIVATE->addr_); #endif connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0); - if (!connected_) + if (!connected_) { piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); + } opened_ = connected_; if (connected_) { connecting_ = false; diff --git a/main.cpp b/main.cpp index d1442618..a69c28d7 100644 --- a/main.cpp +++ b/main.cpp @@ -2,13 +2,16 @@ int main() { PICloudServer s("127.0.0.1:10101"); - for (int i=0; i<3; ++i) { - s.open(); - piCout() << "opened"; - piSleep(1); - s.close(); - piCout() << "closed"; - piSleep(1); - } +// for (int i=0; i<3; ++i) { +// s.open(); +// piCout << "opened"; +// piSleep(10); +// s.close(); +// piCout << "closed"; +// piSleep(1); +// } +// s.open(); + s.startThreadedRead(); + piSleep(200); return 0; } diff --git a/utils/cloud_dispatcher/cloudserver.cpp b/utils/cloud_dispatcher/cloudserver.cpp new file mode 100644 index 00000000..3a7afcba --- /dev/null +++ b/utils/cloud_dispatcher/cloudserver.cpp @@ -0,0 +1,5 @@ +#include "cloudserver.h" + +CloudServer::CloudServer(DispatcherClient * client) { + +} diff --git a/utils/cloud_dispatcher/cloudserver.h b/utils/cloud_dispatcher/cloudserver.h new file mode 100644 index 00000000..b3b6f3ff --- /dev/null +++ b/utils/cloud_dispatcher/cloudserver.h @@ -0,0 +1,12 @@ +#ifndef CLOUDSERVER_H +#define CLOUDSERVER_H + +#include "dispatcherclient.h" + +class CloudServer +{ +public: + CloudServer(DispatcherClient * client); +}; + +#endif // CLOUDSERVER_H diff --git a/utils/cloud_dispatcher/dispatcherclient.cpp b/utils/cloud_dispatcher/dispatcherclient.cpp index 83f3c02e..7991d353 100644 --- a/utils/cloud_dispatcher/dispatcherclient.cpp +++ b/utils/cloud_dispatcher/dispatcherclient.cpp @@ -3,14 +3,22 @@ DispatcherClient::DispatcherClient(PIEthernet * eth_) { eth = eth_; + CONNECTU(&disconnect_tm, tickEvent, eth, close); eth->startThreadedRead(); CONNECTU(eth, threadedReadEvent, this, readed); CONNECTU(eth, disconnected, this, disconnected); piCoutObj << "client connected" << eth->sendAddress(); + disconnect_tm.start(10000); } DispatcherClient::~DispatcherClient() { +// delete eth; +} + + +PIString DispatcherClient::address() { + return eth->path(); } diff --git a/utils/cloud_dispatcher/dispatcherclient.h b/utils/cloud_dispatcher/dispatcherclient.h index aa0e0c6f..00dbbfaf 100644 --- a/utils/cloud_dispatcher/dispatcherclient.h +++ b/utils/cloud_dispatcher/dispatcherclient.h @@ -9,12 +9,16 @@ class DispatcherClient: public PIObject { public: DispatcherClient(PIEthernet * eth_); ~DispatcherClient(); - EVENT_HANDLER2(void, readed, uchar * , data, int, size); - EVENT_HANDLER1(void, disconnected, bool, withError); EVENT1(disconnectEvent, DispatcherClient *, client) + EVENT2(registerServer, PIString, sname, DispatcherClient *, client) + PIString address(); private: + EVENT_HANDLER2(void, readed, uchar * , data, int, size); + EVENT_HANDLER1(void, disconnected, bool, withError); + PIEthernet * eth; + PITimer disconnect_tm; }; diff --git a/utils/cloud_dispatcher/dispatcherserver.cpp b/utils/cloud_dispatcher/dispatcherserver.cpp index 40959cbf..99bdd045 100644 --- a/utils/cloud_dispatcher/dispatcherserver.cpp +++ b/utils/cloud_dispatcher/dispatcherserver.cpp @@ -1,32 +1,57 @@ #include "dispatcherserver.h" -DispatcherServer::DispatcherServer(PIEthernet::Address addr) { - eth = new PIEthernet(PIEthernet::TCP_Server); - eth->setParameter(PIEthernet::ReuseAddress); - CONNECTU(eth, newConnection, this, newConnection); - eth->listen(addr, true); - piCoutObj << eth << "server started" << addr; +DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::TCP_Server) { + eth.setParameter(PIEthernet::ReuseAddress); + CONNECTU(ð, newConnection, this, newConnection); + eth.listen(addr, true); + piCoutObj << "server started" << addr; + CONNECTU(&status_timer, tickEvent, this, printStatus); + status_timer.start(1000); } DispatcherServer::~DispatcherServer() { - eth->close(); + eth.close(); piCoutObj << "server stoped"; - delete eth; +} + + +void DispatcherServer::printStatus() { + map_mutex.lock(); + piCout << PICoutManipulators::NewLine; + piCout << "Connections:"; + for (auto c: clients) { + piCout << " " << c->address(); + } + piCout << "Servers:"; + auto it = c_servers.makeIterator(); + while(it.next()){ + piCout << " " << it.key(); + } + map_mutex.unlock(); } void DispatcherServer::disconnectClient(DispatcherClient *client) { piCoutObj << "remove client" << client; + map_mutex.lock(); clients.removeOne(client); + map_mutex.unlock(); delete client; } void DispatcherServer::newConnection(PIEthernet *cl) { DispatcherClient * client = new DispatcherClient(cl); - piCoutObj << "add client" << client; CONNECTU(client, disconnectEvent, this, disconnectClient); + CONNECTL(client, registerServer, [this](PIString sname, DispatcherClient * c){ + map_mutex.lock(); + c_servers.insert(sname, new CloudServer(c)); + map_mutex.unlock(); + }); + piCoutObj << "add client" << client; + map_mutex.lock(); clients.push_back(client); + map_mutex.unlock(); } diff --git a/utils/cloud_dispatcher/dispatcherserver.h b/utils/cloud_dispatcher/dispatcherserver.h index 4edf2c23..a7205686 100644 --- a/utils/cloud_dispatcher/dispatcherserver.h +++ b/utils/cloud_dispatcher/dispatcherserver.h @@ -2,6 +2,7 @@ #define DISPATCHERSERVER_H #include "dispatcherclient.h" +#include "cloudserver.h" class DispatcherServer: public PIObject { @@ -9,12 +10,17 @@ class DispatcherServer: public PIObject { public: DispatcherServer(PIEthernet::Address addr); ~DispatcherServer(); + EVENT_HANDLER0(void, printStatus); + +private: EVENT_HANDLER1(void, newConnection, PIEthernet * , cl); EVENT_HANDLER1(void, disconnectClient, DispatcherClient *, client); -private: - PIEthernet * eth; + PIEthernet eth; PIVector clients; + PIMap c_servers; + PITimer status_timer; + PIMutex map_mutex; }; #endif // DISPATCHERSERVER_H diff --git a/utils/cloud_dispatcher/main.cpp b/utils/cloud_dispatcher/main.cpp index 6a685a3d..0fcf610a 100644 --- a/utils/cloud_dispatcher/main.cpp +++ b/utils/cloud_dispatcher/main.cpp @@ -53,6 +53,9 @@ int main (int argc, char * argv[]) { if (cli.hasArgument("port")) addr.setPort(cli.argumentValue("port").toInt()); DispatcherServer server(addr); + PIKbdListener ls; + ls.enableExitCapture(PIKbdListener::F10); + ls.start(); WAIT_FOR_EXIT return 0; } From fa0475cac605a55fe7415470421b29864595f79b Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 26 Aug 2020 17:59:28 +0300 Subject: [PATCH 59/68] PIEthernet disctonnect fix --- libs/main/io_devices/piethernet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index 2867b069..efc48658 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -691,8 +691,8 @@ int PIEthernet::readDevice(void * read_to, int max_size) { } if (connected_) { piCoutObj << "Disconnect on read," << ethErrorString(); + opened_ = connected_ = false; init(); - connected_ = false; disconnected(rs < 0); } if (parameters()[KeepConnection]) From 7f2c82dc69c28fd7cf1ba644cd2f9a5a78b9ca4e Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 26 Aug 2020 18:01:17 +0300 Subject: [PATCH 60/68] PIEthernet reconnect --- libs/cloud/picloudserver.cpp | 4 ++-- libs/main/io_devices/piethernet.cpp | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 2bef35f7..62e51410 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -33,10 +33,10 @@ bool PICloudServer::openDevice() { piCout << "PICloudServer open device" << path(); bool op = eth.connect(path(), false); if (op) { +// CONNECTL(ð, disconnected, [this](bool){opened_ = false;}); return true; - } else { - eth.close(); } + eth.close(); return false; } diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index 2867b069..21a2de34 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -566,6 +566,7 @@ bool PIEthernet::connect(bool threaded) { connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0); if (!connected_) { piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); + closeSocket(sock); } opened_ = connected_; if (connected_) { @@ -662,8 +663,9 @@ int PIEthernet::readDevice(void * read_to, int max_size) { //piCoutObj << "connect to " << ip_ << ":" << port_ << "..."; connected_ = (::connect(sock, (sockaddr * )&(PRIVATE->addr_), sizeof(PRIVATE->addr_)) == 0); //piCoutObj << "connect to " << ip_ << ":" << port_ << connected_; - if (!connected_) + if (!connected_) { piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); + } opened_ = connected_; if (connected_) { connecting_ = false; @@ -672,7 +674,10 @@ int PIEthernet::readDevice(void * read_to, int max_size) { piMSleep(10); //piCout << "connected to" << path(); } - if (!connected_) return -1; + if (!connected_) { + closeSocket(sock); + return -1; + } errorClear(); rs = ethRecv(sock, read_to, max_size); //piCoutObj << "readed" << rs; @@ -737,7 +742,7 @@ int PIEthernet::writeDevice(const void * data, int max_size) { //piCoutObj << "connect SingleTCP" << ip_s << ":" << port_s << "..."; if (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) != 0) { //piCoutObj << "Can`t connect to " << ip_s << ":" << port_s << ", " << ethErrorString(); - msleep(PIP_MIN_MSLEEP); + closeSocket(sock); return -1; } //piCoutObj << "ok, write SingleTCP" << int(data) << max_size << "bytes ..."; @@ -771,15 +776,19 @@ int PIEthernet::writeDevice(const void * data, int max_size) { #endif //piCoutObj << "connect to " << ip << ":" << port_; connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0); - if (!connected_) + if (!connected_) { piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); + } opened_ = connected_; if (connected_) { connecting_ = false; connected(); } } - if (!connected_) return -1; + if (!connected_) { + closeSocket(sock); + return -1; + } ret = ::send(sock, (const char *)data, max_size, 0); if (ret < 0) { connected_ = false; From 73bfe03433a4b7bd67fe107201ebc0e7e1597353 Mon Sep 17 00:00:00 2001 From: Ivan Pelipenko Date: Wed, 26 Aug 2020 18:10:58 +0300 Subject: [PATCH 61/68] PIEthernet disctonnect fix --- libs/main/io_devices/piethernet.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index efc48658..f4fee671 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -782,8 +782,8 @@ int PIEthernet::writeDevice(const void * data, int max_size) { if (!connected_) return -1; ret = ::send(sock, (const char *)data, max_size, 0); if (ret < 0) { - connected_ = false; piCoutObj << "Disconnect on write," << ethErrorString(); + opened_ = connected_ = false; init(); disconnected(true); } From 2ef0ca6946434ebd3c73217bb8b4a01d2fe4035f Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 26 Aug 2020 18:43:33 +0300 Subject: [PATCH 62/68] PIIODevice destructor fix --- libs/cloud/picloudserver.cpp | 3 ++- libs/main/io_devices/pibinarylog.cpp | 6 ++++++ libs/main/io_devices/pibinarylog.h | 2 +- libs/main/io_devices/pican.cpp | 6 ++++++ libs/main/io_devices/pican.h | 2 +- libs/main/io_devices/piethernet.cpp | 21 ++++++-------------- libs/main/io_devices/pifile.cpp | 6 ++++++ libs/main/io_devices/pifile.h | 2 +- libs/main/io_devices/piiobytearray.h | 2 -- libs/main/io_devices/piiodevice.cpp | 5 ----- libs/main/io_devices/piiostring.h | 2 -- libs/main/io_devices/pipeer.cpp | 1 + libs/main/io_devices/piserial.cpp | 3 ++- libs/main/io_devices/piserial.h | 2 +- libs/main/io_devices/pisharedmemory.cpp | 6 ++++++ libs/main/io_devices/pisharedmemory.h | 2 +- libs/main/io_devices/pispi.cpp | 6 ++++++ libs/main/io_devices/pispi.h | 2 +- libs/main/io_devices/pitransparentdevice.cpp | 6 ++++++ libs/main/io_devices/pitransparentdevice.h | 2 +- libs/main/io_devices/piusb.h | 2 +- libs/usb/piusb.cpp | 5 +++++ main.cpp | 3 ++- 23 files changed, 62 insertions(+), 35 deletions(-) diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 62e51410..00f917be 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -25,7 +25,8 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) PICloudServer::~PICloudServer() { - + stop(); + close(); } diff --git a/libs/main/io_devices/pibinarylog.cpp b/libs/main/io_devices/pibinarylog.cpp index bae32580..8bef86c5 100644 --- a/libs/main/io_devices/pibinarylog.cpp +++ b/libs/main/io_devices/pibinarylog.cpp @@ -78,6 +78,12 @@ PIBinaryLog::PIBinaryLog() { } +PIBinaryLog::~PIBinaryLog() { + stop(); + close(); +} + + bool PIBinaryLog::openDevice() { lastrecord.timestamp = PISystemTime(); lastrecord.id = 0; diff --git a/libs/main/io_devices/pibinarylog.h b/libs/main/io_devices/pibinarylog.h index 9a835c4b..fb674700 100644 --- a/libs/main/io_devices/pibinarylog.h +++ b/libs/main/io_devices/pibinarylog.h @@ -31,7 +31,7 @@ class PIP_EXPORT PIBinaryLog: public PIIODevice PIIODEVICE(PIBinaryLog) public: explicit PIBinaryLog(); - ~PIBinaryLog() {closeDevice();} + virtual ~PIBinaryLog(); //! \brief Play modes for \a PIBinaryLog enum PlayMode { diff --git a/libs/main/io_devices/pican.cpp b/libs/main/io_devices/pican.cpp index f3201f09..0d0443c3 100644 --- a/libs/main/io_devices/pican.cpp +++ b/libs/main/io_devices/pican.cpp @@ -46,6 +46,12 @@ PICAN::PICAN(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(pa } +PICAN::~PICAN() { + stop(); + close(); +} + + bool PICAN::openDevice() { #ifdef PIP_CAN piCout << "PICAN open device" << path(); diff --git a/libs/main/io_devices/pican.h b/libs/main/io_devices/pican.h index 51a6689a..11f2bb06 100644 --- a/libs/main/io_devices/pican.h +++ b/libs/main/io_devices/pican.h @@ -31,7 +31,7 @@ class PIP_EXPORT PICAN: public PIIODevice PIIODEVICE(PICAN) public: explicit PICAN(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); - ~PICAN() {} + virtual ~PICAN(); void setCANID(int id); int CANID() const; diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index d0a0de20..3915425b 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -244,7 +244,7 @@ PIEthernet::PIEthernet(int sock_, PIString ip_port): PIIODevice("", ReadWrite) { PIEthernet::~PIEthernet() { //piCout << "~PIEthernet" << uint(this); stop(); - closeDevice(); + close(); //piCoutObj << "~PIEthernet done"; } @@ -566,7 +566,6 @@ bool PIEthernet::connect(bool threaded) { connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0); if (!connected_) { piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); - closeSocket(sock); } opened_ = connected_; if (connected_) { @@ -663,9 +662,8 @@ int PIEthernet::readDevice(void * read_to, int max_size) { //piCoutObj << "connect to " << ip_ << ":" << port_ << "..."; connected_ = (::connect(sock, (sockaddr * )&(PRIVATE->addr_), sizeof(PRIVATE->addr_)) == 0); //piCoutObj << "connect to " << ip_ << ":" << port_ << connected_; - if (!connected_) { + if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); - } opened_ = connected_; if (connected_) { connecting_ = false; @@ -674,10 +672,7 @@ int PIEthernet::readDevice(void * read_to, int max_size) { piMSleep(10); //piCout << "connected to" << path(); } - if (!connected_) { - closeSocket(sock); - return -1; - } + if (!connected_) return -1; errorClear(); rs = ethRecv(sock, read_to, max_size); //piCoutObj << "readed" << rs; @@ -742,7 +737,7 @@ int PIEthernet::writeDevice(const void * data, int max_size) { //piCoutObj << "connect SingleTCP" << ip_s << ":" << port_s << "..."; if (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) != 0) { //piCoutObj << "Can`t connect to " << ip_s << ":" << port_s << ", " << ethErrorString(); - closeSocket(sock); + msleep(PIP_MIN_MSLEEP); return -1; } //piCoutObj << "ok, write SingleTCP" << int(data) << max_size << "bytes ..."; @@ -776,19 +771,15 @@ int PIEthernet::writeDevice(const void * data, int max_size) { #endif //piCoutObj << "connect to " << ip << ":" << port_; connected_ = (::connect(sock, (sockaddr * )&PRIVATE->addr_, sizeof(PRIVATE->addr_)) == 0); - if (!connected_) { + if (!connected_) piCoutObj << "Can`t connect to" << addr_r << "," << ethErrorString(); - } opened_ = connected_; if (connected_) { connecting_ = false; connected(); } } - if (!connected_) { - closeSocket(sock); - return -1; - } + if (!connected_) return -1; ret = ::send(sock, (const char *)data, max_size, 0); if (ret < 0) { connected_ = false; diff --git a/libs/main/io_devices/pifile.cpp b/libs/main/io_devices/pifile.cpp index efbcb521..8f598b05 100644 --- a/libs/main/io_devices/pifile.cpp +++ b/libs/main/io_devices/pifile.cpp @@ -154,6 +154,12 @@ bool PIFile::openTemporary(PIIODevice::DeviceMode mode) { } +PIFile::~PIFile() { + stop(); + close(); +} + + bool PIFile::openDevice() { close(); PIString p = path(); diff --git a/libs/main/io_devices/pifile.h b/libs/main/io_devices/pifile.h index ca6d0e6b..56b1df6f 100644 --- a/libs/main/io_devices/pifile.h +++ b/libs/main/io_devices/pifile.h @@ -91,7 +91,7 @@ public: //! Open temporary file with open mode "mode" bool openTemporary(PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); - ~PIFile() {closeDevice();} + virtual ~PIFile(); //! Immediate write all buffered data to disk void flush(); diff --git a/libs/main/io_devices/piiobytearray.h b/libs/main/io_devices/piiobytearray.h index 64212646..57bec2e4 100644 --- a/libs/main/io_devices/piiobytearray.h +++ b/libs/main/io_devices/piiobytearray.h @@ -37,8 +37,6 @@ public: //! Contructs %PIIOByteArray with \"buffer\" content only for read explicit PIIOByteArray(const PIByteArray & buffer); - ~PIIOByteArray() {closeDevice();} - //! Returns content PIByteArray * byteArray() const {return data_;} diff --git a/libs/main/io_devices/piiodevice.cpp b/libs/main/io_devices/piiodevice.cpp index ec54085b..9dea9dd6 100644 --- a/libs/main/io_devices/piiodevice.cpp +++ b/libs/main/io_devices/piiodevice.cpp @@ -137,11 +137,6 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PITh PIIODevice::~PIIODevice() { stop(); - if (opened_) { - closeDevice(); - if (!opened_) - closed(); - } } diff --git a/libs/main/io_devices/piiostring.h b/libs/main/io_devices/piiostring.h index c195c0cd..9301060d 100644 --- a/libs/main/io_devices/piiostring.h +++ b/libs/main/io_devices/piiostring.h @@ -37,8 +37,6 @@ public: //! Contructs %PIIOString with \"string\" content only for read explicit PIIOString(const PIString & string); - ~PIIOString() {closeDevice();} - //! Returns content PIString * string() const {return str;} diff --git a/libs/main/io_devices/pipeer.cpp b/libs/main/io_devices/pipeer.cpp index 85cc0bc3..96a07810 100644 --- a/libs/main/io_devices/pipeer.cpp +++ b/libs/main/io_devices/pipeer.cpp @@ -181,6 +181,7 @@ PIPeer::PIPeer(const PIString & n): PIIODevice(), inited__(false), eth_tcp_srv(P PIPeer::~PIPeer() { //piCout << "~PIPeer" << uint(this); + stop(); if (destroyed) return; destroyed = true; sync_timer.stop(); diff --git a/libs/main/io_devices/piserial.cpp b/libs/main/io_devices/piserial.cpp index 4c526a62..07fdded6 100644 --- a/libs/main/io_devices/piserial.cpp +++ b/libs/main/io_devices/piserial.cpp @@ -197,7 +197,8 @@ PISerial::PISerial(const PIString & device_, PISerial::Speed speed_, PIFlags params = 0); - ~PISerial(); + virtual ~PISerial(); //! Set both input and output speed to "speed" diff --git a/libs/main/io_devices/pisharedmemory.cpp b/libs/main/io_devices/pisharedmemory.cpp index 63e43293..daaaa2c2 100644 --- a/libs/main/io_devices/pisharedmemory.cpp +++ b/libs/main/io_devices/pisharedmemory.cpp @@ -89,6 +89,12 @@ PISharedMemory::PISharedMemory(const PIString & shm_name, int size, PIIODevice:: } +PISharedMemory::~PISharedMemory() { + stop(); + close(); +} + + bool PISharedMemory::openDevice() { close(); //piCoutObj << "try open" << path() << dsize; diff --git a/libs/main/io_devices/pisharedmemory.h b/libs/main/io_devices/pisharedmemory.h index 36bd8c3f..495739f6 100644 --- a/libs/main/io_devices/pisharedmemory.h +++ b/libs/main/io_devices/pisharedmemory.h @@ -37,7 +37,7 @@ public: explicit PISharedMemory(const PIString & shm_name, int size, DeviceMode mode = ReadWrite); - virtual ~PISharedMemory() {close();} + virtual ~PISharedMemory(); //! Read all shared memory object content to byte array and return it PIByteArray readAll(); diff --git a/libs/main/io_devices/pispi.cpp b/libs/main/io_devices/pispi.cpp index 55bcc99e..80a1e5bc 100644 --- a/libs/main/io_devices/pispi.cpp +++ b/libs/main/io_devices/pispi.cpp @@ -59,6 +59,12 @@ PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode) : P } +PISPI::~PISPI() { + stop(); + close(); +} + + void PISPI::setSpeed(uint speed_hz) { spi_speed = speed_hz; } diff --git a/libs/main/io_devices/pispi.h b/libs/main/io_devices/pispi.h index 7c30a59f..29284a45 100644 --- a/libs/main/io_devices/pispi.h +++ b/libs/main/io_devices/pispi.h @@ -31,7 +31,7 @@ class PIP_EXPORT PISPI: public PIIODevice PIIODEVICE(PISPI) public: explicit PISPI(const PIString & path = PIString(), uint speed_hz = 1000000, PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); - ~PISPI() {} + virtual ~PISPI(); //! \brief Parameters of PISPI enum Parameters { diff --git a/libs/main/io_devices/pitransparentdevice.cpp b/libs/main/io_devices/pitransparentdevice.cpp index 6ea60f2b..42f1a609 100644 --- a/libs/main/io_devices/pitransparentdevice.cpp +++ b/libs/main/io_devices/pitransparentdevice.cpp @@ -37,6 +37,12 @@ PITransparentDevice::PITransparentDevice() { } +PITransparentDevice::~PITransparentDevice() { + stop(); + close(); +} + + int PITransparentDevice::readDevice(void * read_to, int max_size) { if (!canRead()) return -1; que_mutex.lock(); diff --git a/libs/main/io_devices/pitransparentdevice.h b/libs/main/io_devices/pitransparentdevice.h index f1478668..4b49eb4b 100644 --- a/libs/main/io_devices/pitransparentdevice.h +++ b/libs/main/io_devices/pitransparentdevice.h @@ -34,7 +34,7 @@ public: //! Contructs empty %PITransparentDevice explicit PITransparentDevice(); - ~PITransparentDevice() {closeDevice();} + virtual ~PITransparentDevice(); protected: bool openDevice(); diff --git a/libs/main/io_devices/piusb.h b/libs/main/io_devices/piusb.h index 2b17d382..5ba47d8c 100644 --- a/libs/main/io_devices/piusb.h +++ b/libs/main/io_devices/piusb.h @@ -32,7 +32,7 @@ class PIP_EXPORT PIUSB: public PIIODevice PIIODEVICE(PIUSB) public: explicit PIUSB(ushort vid = 0, ushort pid = 0); - ~PIUSB() {closeDevice();} + virtual ~PIUSB(); struct PIP_EXPORT Endpoint { Endpoint(uchar a = 0, uchar at = 0, ushort mps = 0) {address = a; attributes = at; max_packet_size = mps; parse();} diff --git a/libs/usb/piusb.cpp b/libs/usb/piusb.cpp index 91e131a3..6db89eab 100644 --- a/libs/usb/piusb.cpp +++ b/libs/usb/piusb.cpp @@ -46,6 +46,11 @@ PIUSB::PIUSB(ushort vid, ushort pid): PIIODevice("", ReadWrite) { } +PIUSB::~PIUSB() { + stop(); + close(); +} + void PIUSB::Endpoint::parse() { synchronisation_type = NoSynchonisation; usage_type = DataEndpoint; diff --git a/main.cpp b/main.cpp index a69c28d7..193896f4 100644 --- a/main.cpp +++ b/main.cpp @@ -12,6 +12,7 @@ int main() { // } // s.open(); s.startThreadedRead(); - piSleep(200); + piSleep(2); +// s.stopThreadedRead(); return 0; } From e1f2c90790b473c2d0a8049c982498101d7d68b2 Mon Sep 17 00:00:00 2001 From: andrey Date: Wed, 26 Aug 2020 18:45:27 +0300 Subject: [PATCH 63/68] version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6be1e71f..954c240b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) -set(_PIP_MINOR 3) +set(_PIP_MINOR 4) set(_PIP_REVISION 0) set(_PIP_SUFFIX _beta) set(_PIP_COMPANY SHS) From 234d4e73bef2d206323709e5f544c29d7961d34b Mon Sep 17 00:00:00 2001 From: andrey Date: Thu, 27 Aug 2020 19:40:11 +0300 Subject: [PATCH 64/68] picloud --- libs/cloud/picloudtcp.cpp | 14 ++++++++++++ libs/main/cloud/picloudtcp.h | 24 +++++++++++++++++++++ main.cpp | 12 +---------- utils/cloud_dispatcher/cloudserver.cpp | 21 +++++++++++++++++- utils/cloud_dispatcher/cloudserver.h | 14 +++++++++--- utils/cloud_dispatcher/dispatcherclient.cpp | 23 ++++++++++++++++---- utils/cloud_dispatcher/dispatcherclient.h | 4 ++++ utils/cloud_dispatcher/dispatcherserver.cpp | 8 +++++++ utils/cloud_dispatcher/dispatcherserver.h | 1 - 9 files changed, 101 insertions(+), 20 deletions(-) diff --git a/libs/cloud/picloudtcp.cpp b/libs/cloud/picloudtcp.cpp index 80786a1d..5cf2f700 100644 --- a/libs/cloud/picloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -19,10 +19,24 @@ #include "picloudtcp.h" #include "picrypt.h" +#include "pichunkstream.h" + const char hash_def_key[] = "_picrypt_"; +PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v) { + s << v.version << v.type << v.sname; + return s; +} + + +PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v) { + s >> v.version >> v.type >> v.sname; + return s; +} + + PICloudTCP::PICloudTCP() { } diff --git a/libs/main/cloud/picloudtcp.h b/libs/main/cloud/picloudtcp.h index 5b7f1309..5a22b0ab 100644 --- a/libs/main/cloud/picloudtcp.h +++ b/libs/main/cloud/picloudtcp.h @@ -26,6 +26,30 @@ #include "pip_cloud_export.h" #include "pistring.h" +namespace PICloud { + +enum Version { + Version_1 = 1, +}; + +enum HeaderType { + Server = 1, + Client = 2, +}; + +struct PIP_CLOUD_EXPORT Header { + Header() { + version = Version_1; + } + uchar version; // PICloud::Version + uchar type; // PICloud::HeaderType + PIString sname; // server name +}; +} + +PIP_CLOUD_EXPORT PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v); +PIP_CLOUD_EXPORT PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v); + class PIP_CLOUD_EXPORT PICloudTCP { public: diff --git a/main.cpp b/main.cpp index 193896f4..3764b12d 100644 --- a/main.cpp +++ b/main.cpp @@ -2,17 +2,7 @@ int main() { PICloudServer s("127.0.0.1:10101"); -// for (int i=0; i<3; ++i) { -// s.open(); -// piCout << "opened"; -// piSleep(10); -// s.close(); -// piCout << "closed"; -// piSleep(1); -// } -// s.open(); s.startThreadedRead(); - piSleep(2); -// s.stopThreadedRead(); + piSleep(10); return 0; } diff --git a/utils/cloud_dispatcher/cloudserver.cpp b/utils/cloud_dispatcher/cloudserver.cpp index 3a7afcba..01ff10d1 100644 --- a/utils/cloud_dispatcher/cloudserver.cpp +++ b/utils/cloud_dispatcher/cloudserver.cpp @@ -1,5 +1,24 @@ #include "cloudserver.h" -CloudServer::CloudServer(DispatcherClient * client) { +CloudServer::CloudServer(DispatcherClient * c) : server(c) { } + + +CloudServer::~CloudServer() { + for (auto c :clients) { + c->close(); + } +} + + +void CloudServer::addClient(DispatcherClient * c) { + clients << c; +} + +void CloudServer::printStatus() { + piCout << " " << "Clients for" << server->address() << ":"; + for (auto c: clients) { + piCout << " " << c->address(); + } +} diff --git a/utils/cloud_dispatcher/cloudserver.h b/utils/cloud_dispatcher/cloudserver.h index b3b6f3ff..be44352a 100644 --- a/utils/cloud_dispatcher/cloudserver.h +++ b/utils/cloud_dispatcher/cloudserver.h @@ -3,10 +3,18 @@ #include "dispatcherclient.h" -class CloudServer -{ + +class CloudServer : public PIObject { + PIOBJECT(CloudServer) public: - CloudServer(DispatcherClient * client); + CloudServer(DispatcherClient * c); + ~CloudServer(); + void addClient(DispatcherClient * c); + EVENT_HANDLER0(void, printStatus); + +private: + DispatcherClient * server; + PIVector clients; }; #endif // CLOUDSERVER_H diff --git a/utils/cloud_dispatcher/dispatcherclient.cpp b/utils/cloud_dispatcher/dispatcherclient.cpp index 7991d353..b9cdfd64 100644 --- a/utils/cloud_dispatcher/dispatcherclient.cpp +++ b/utils/cloud_dispatcher/dispatcherclient.cpp @@ -1,8 +1,8 @@ #include "dispatcherclient.h" +#include "picloudtcp.h" -DispatcherClient::DispatcherClient(PIEthernet * eth_) { - eth = eth_; +DispatcherClient::DispatcherClient(PIEthernet * eth_) : eth(eth_), authorised(false) { CONNECTU(&disconnect_tm, tickEvent, eth, close); eth->startThreadedRead(); CONNECTU(eth, threadedReadEvent, this, readed); @@ -21,6 +21,10 @@ PIString DispatcherClient::address() { return eth->path(); } +void DispatcherClient::close() { + eth->close(); +} + void DispatcherClient::disconnected(bool withError) { piCoutObj << "client disconnected" << eth->sendAddress(); @@ -30,7 +34,18 @@ void DispatcherClient::disconnected(bool withError) { void DispatcherClient::readed(uchar *data, int size) { PIByteArray ba(data, size); - piCoutObj << "readed" << ba.toHex(); - eth->write(ba); + if (authorised) { + dataReaded(ba); + } else { + if (ba.size() < 4) return; + PICloud::Header hdr; + ba >> hdr; + if ((PICloud::HeaderType)hdr.type == PICloud::Server) { + registerServer(hdr.sname, this); + } + if ((PICloud::HeaderType)hdr.type == PICloud::Client) { + registerClient(hdr.sname, this); + } + } } diff --git a/utils/cloud_dispatcher/dispatcherclient.h b/utils/cloud_dispatcher/dispatcherclient.h index 00dbbfaf..99f7cc62 100644 --- a/utils/cloud_dispatcher/dispatcherclient.h +++ b/utils/cloud_dispatcher/dispatcherclient.h @@ -11,7 +11,10 @@ public: ~DispatcherClient(); EVENT1(disconnectEvent, DispatcherClient *, client) EVENT2(registerServer, PIString, sname, DispatcherClient *, client) + EVENT2(registerClient, PIString, sname, DispatcherClient *, client) PIString address(); + void close(); + EVENT1(dataReaded, PIByteArray, ba) private: EVENT_HANDLER2(void, readed, uchar * , data, int, size); @@ -19,6 +22,7 @@ private: PIEthernet * eth; PITimer disconnect_tm; + bool authorised; }; diff --git a/utils/cloud_dispatcher/dispatcherserver.cpp b/utils/cloud_dispatcher/dispatcherserver.cpp index 99bdd045..4b5a50cf 100644 --- a/utils/cloud_dispatcher/dispatcherserver.cpp +++ b/utils/cloud_dispatcher/dispatcherserver.cpp @@ -28,6 +28,7 @@ void DispatcherServer::printStatus() { auto it = c_servers.makeIterator(); while(it.next()){ piCout << " " << it.key(); + it.value()->printStatus(); } map_mutex.unlock(); } @@ -50,6 +51,13 @@ void DispatcherServer::newConnection(PIEthernet *cl) { c_servers.insert(sname, new CloudServer(c)); map_mutex.unlock(); }); + CONNECTL(client, registerClient, [this](PIString sname, DispatcherClient * c){ + map_mutex.lock(); + if (c_servers.contains(sname)) { + c_servers[sname]->addClient(c); + } + map_mutex.unlock(); + }); piCoutObj << "add client" << client; map_mutex.lock(); clients.push_back(client); diff --git a/utils/cloud_dispatcher/dispatcherserver.h b/utils/cloud_dispatcher/dispatcherserver.h index a7205686..7fba7ef4 100644 --- a/utils/cloud_dispatcher/dispatcherserver.h +++ b/utils/cloud_dispatcher/dispatcherserver.h @@ -1,7 +1,6 @@ #ifndef DISPATCHERSERVER_H #define DISPATCHERSERVER_H -#include "dispatcherclient.h" #include "cloudserver.h" From c5f70f4e09c1df5ba7da10aaba231584fc3933e3 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 28 Aug 2020 17:49:58 +0300 Subject: [PATCH 65/68] picloud --- libs/cloud/picloudclient.cpp | 13 +++++++++++-- libs/cloud/picloudserver.cpp | 24 +++++++++++++++++++++--- libs/cloud/picloudtcp.cpp | 2 +- libs/main/cloud/picloudclient.h | 11 ++++++----- libs/main/cloud/picloudserver.h | 18 ++++++++++++++++-- libs/main/cloud/picloudtcp.h | 16 ++++++++-------- 6 files changed, 63 insertions(+), 21 deletions(-) diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index e3a950a0..2c2bef29 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -20,12 +20,13 @@ #include "picloudclient.h" -PICloudClient::PICloudClient() { +PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode), eth(PIEthernet::TCP_Client) { } PICloudClient::~PICloudClient() { - + stop(); + close(); } @@ -38,3 +39,11 @@ bool PICloudClient::closeDevice() { return false; } +int PICloudClient::readDevice(void * read_to, int max_size) { + return eth.read(read_to, max_size); +} + + +int PICloudClient::writeDevice(const void * data, int max_size) { + return eth.write(data, max_size); +} diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 00f917be..f359483b 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -34,7 +34,10 @@ bool PICloudServer::openDevice() { piCout << "PICloudServer open device" << path(); bool op = eth.connect(path(), false); if (op) { -// CONNECTL(ð, disconnected, [this](bool){opened_ = false;}); + CONNECTL(ð, disconnected, [this](bool){opened_ = false;}); + CONNECTU(ð, threadedReadEvent, this, readed); + eth.startThreadedRead(); + sendStart(); return true; } eth.close(); @@ -48,12 +51,27 @@ bool PICloudServer::closeDevice() { int PICloudServer::readDevice(void * read_to, int max_size) { - return eth.read(read_to, max_size); + return -1; } int PICloudServer::writeDevice(const void * data, int max_size) { - return eth.write(data, max_size); + return -1; } +void PICloudServer::sendStart() { + +} + + + +PICloudServer::Client::Client(PICloudServer * srv) : server(srv) { + +} + + +bool PICloudServer::Client::openDevice() { + return server; +} + diff --git a/libs/cloud/picloudtcp.cpp b/libs/cloud/picloudtcp.cpp index 5cf2f700..905b7980 100644 --- a/libs/cloud/picloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -37,6 +37,6 @@ PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v) { } -PICloudTCP::PICloudTCP() { +PICloud::TCP::TCP() { } diff --git a/libs/main/cloud/picloudclient.h b/libs/main/cloud/picloudclient.h index 6de937a4..cbf4c069 100644 --- a/libs/main/cloud/picloudclient.h +++ b/libs/main/cloud/picloudclient.h @@ -24,9 +24,7 @@ #define PICLOUDCLIENT_H #include "pip_cloud_export.h" -#include "piiodevice.h" - -class PIEthernet; +#include "piethernet.h" class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice @@ -34,7 +32,7 @@ class PIP_CLOUD_EXPORT PICloudClient : public PIIODevice PIIODEVICE(PICloudClient) public: //! - explicit PICloudClient(); + explicit PICloudClient(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); virtual ~PICloudClient(); protected: @@ -42,7 +40,10 @@ protected: bool closeDevice(); private: - PIEthernet * eth; + int readDevice(void * read_to, int max_size); + int writeDevice(const void * data, int max_size); + + PIEthernet eth; }; #endif // PICLOUDCLIENT_H diff --git a/libs/main/cloud/picloudserver.h b/libs/main/cloud/picloudserver.h index a7e3da2a..32f05a8f 100644 --- a/libs/main/cloud/picloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -26,8 +26,6 @@ #include "pip_cloud_export.h" #include "piethernet.h" -class PIEthernet; - class PIP_CLOUD_EXPORT PICloudServer : public PIIODevice { @@ -37,6 +35,18 @@ public: explicit PICloudServer(const PIString & path = PIString(), PIIODevice::DeviceMode mode = PIIODevice::ReadWrite); virtual ~PICloudServer(); + class Client : public PIIODevice { + PIIODEVICE(PICloudServer::Client) + public: + Client(PICloudServer * srv = nullptr); + protected: + bool openDevice(); + private: + PICloudServer * server; + }; + + EVENT1(newConnection, PICloudServer::Client * , client) + protected: bool openDevice(); bool closeDevice(); @@ -44,7 +54,11 @@ protected: int writeDevice(const void * data, int max_size); private: + EVENT_HANDLER2(void, readed, uchar * , data, int, size); + void sendStart(); + PIEthernet eth; + PIVector clients; }; diff --git a/libs/main/cloud/picloudtcp.h b/libs/main/cloud/picloudtcp.h index 5a22b0ab..9c22289e 100644 --- a/libs/main/cloud/picloudtcp.h +++ b/libs/main/cloud/picloudtcp.h @@ -26,6 +26,7 @@ #include "pip_cloud_export.h" #include "pistring.h" + namespace PICloud { enum Version { @@ -45,20 +46,19 @@ struct PIP_CLOUD_EXPORT Header { uchar type; // PICloud::HeaderType PIString sname; // server name }; -} - -PIP_CLOUD_EXPORT PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v); -PIP_CLOUD_EXPORT PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v); -class PIP_CLOUD_EXPORT PICloudTCP { +class PIP_CLOUD_EXPORT TCP { public: - //! - PICloudTCP(); - + TCP(); private: }; +} + +PIP_CLOUD_EXPORT PIByteArray & operator <<(PIByteArray & s, const PICloud::Header & v); +PIP_CLOUD_EXPORT PIByteArray & operator >>(PIByteArray & s, PICloud::Header & v); + #endif // PICLOUDTCP_H From 7065cbd9eef3a0afff9d3f9fbacdee3f0a5ef246 Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 31 Aug 2020 16:01:35 +0300 Subject: [PATCH 66/68] Fixed PIConditionVariable timeout bug on Linux --- libs/main/thread/piconditionvar.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 395f53f6..8377e89c 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -90,7 +90,7 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000}; + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % (int)1e6 * (int)1e6}; isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; #endif if (PRIVATE->isDestroying) return false; @@ -105,17 +105,16 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio isCondition = condition(); if (isCondition) break; #ifdef WINDOWS - WINBOOL isTimeout = SleepConditionVariableCS( + bool isTimeout = SleepConditionVariableCS( &PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), - timeoutMs - (int)measurer.elapsed_m()); - if (isTimeout == 0) return false; + timeoutMs - (int)measurer.elapsed_m()) == 0; #else int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000}; - bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; - if (isTimeout) return false; + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % (int)1e6 * (int)1e6}; + bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) != 0; #endif + if (isTimeout) return false; if (PRIVATE->isDestroying) return false; } return true; From 32d060c8ce4e7a39ea8d230a2217c1b195953b4c Mon Sep 17 00:00:00 2001 From: Stepan Fomenko Date: Mon, 31 Aug 2020 16:41:01 +0300 Subject: [PATCH 67/68] int --- libs/main/thread/piconditionvar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/main/thread/piconditionvar.cpp b/libs/main/thread/piconditionvar.cpp index 8377e89c..6cbfce6b 100644 --- a/libs/main/thread/piconditionvar.cpp +++ b/libs/main/thread/piconditionvar.cpp @@ -90,7 +90,7 @@ bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { #ifdef WINDOWS isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; #else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % (int)1e6 * (int)1e6}; + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs % 1000000 * 1000000}; isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; #endif if (PRIVATE->isDestroying) return false; @@ -111,7 +111,7 @@ bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::functio timeoutMs - (int)measurer.elapsed_m()) == 0; #else int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % (int)1e6 * (int)1e6}; + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr % 1000000 * 1000000}; bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) != 0; #endif if (isTimeout) return false; From 6be22ac39fdf3bfa1638d55ff43ef42e5e1a3c99 Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 31 Aug 2020 17:53:18 +0300 Subject: [PATCH 68/68] reemove piSwapBinary --- CMakeLists.txt | 2 +- libs/cloud/picloudserver.cpp | 4 ++++ libs/main/core/pibase.h | 7 ------- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 954c240b..19045b99 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) cmake_policy(SET CMP0017 NEW) # need include() with .cmake project(pip) set(_PIP_MAJOR 2) -set(_PIP_MINOR 4) +set(_PIP_MINOR 5) set(_PIP_REVISION 0) set(_PIP_SUFFIX _beta) set(_PIP_COMPANY SHS) diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index f359483b..fb7cb68c 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -75,3 +75,7 @@ bool PICloudServer::Client::openDevice() { return server; } + +void PICloudServer::readed(uchar *data, int size) { + +} diff --git a/libs/main/core/pibase.h b/libs/main/core/pibase.h index 559ded47..d9552907 100644 --- a/libs/main/core/pibase.h +++ b/libs/main/core/pibase.h @@ -292,13 +292,6 @@ template<> inline void piSwapBinary(const void *& f, const void *& s) { } } -template<> inline void piSwap(double & f, double & s) {piSwapBinary(f, s);} -template<> inline void piSwap(ldouble & f, ldouble & s) {piSwapBinary(f, s);} -#ifdef ARCH_BITS_32 -template<> inline void piSwap(float & f, float & s) {piSwapBinary(f, s);} -template<> inline void piSwap(llong & f, llong & s) {piSwapBinary(f, s);} -template<> inline void piSwap(ullong & f, ullong & s) {piSwapBinary(f, s);} -#endif /*! \brief Function for compare two values without "=" by raw content * \details Example:\n \snippet piincludes.cpp compareBinary */