diff --git a/Makefile_qnx b/Makefile_qnx index 0c62deb8..0aca81f9 100644 --- a/Makefile_qnx +++ b/Makefile_qnx @@ -37,7 +37,10 @@ SOURCES = main.cpp \ picli.cpp \ piprocess.cpp \ picodec.cpp \ - pisignals.cpp + pisignals.cpp \ + pimonitor.cpp \ + piobject.cpp \ + pisystemmonitor.cpp OBJECTS = main.o \ pibytearray.o \ piconfig.o \ @@ -57,7 +60,10 @@ OBJECTS = main.o \ picli.o \ piprocess.o \ picodec.o \ - pisignals.o + pisignals.o \ + pimonitor.o \ + piobject.o \ + pisystemmonitor.o first: all ####### Implicit rules @@ -250,6 +256,15 @@ picodec.o: picodec.cpp pisignals.o: pisignals.cpp $(CXX) -c $(CXXFLAGS) $(INCPATH) -o pisignals.o pisignals.cpp +pimonitor.o: pimonitor.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o pimonitor.o pimonitor.cpp + +piobject.o: piobject.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o piobject.o piobject.cpp + +pisystemmonitor.o: pisystemmonitor.cpp + $(CXX) -c $(CXXFLAGS) $(INCPATH) -o pisystemmonitor.o pisystemmonitor.cpp + ####### Install install: FORCE diff --git a/main.cpp b/main.cpp index fad73a36..6074c8b8 100644 --- a/main.cpp +++ b/main.cpp @@ -1,150 +1,232 @@ -#include +#include "pip.h" -class Prot: public PIProtocol { + +class ThreadTest: public PIThread { public: - Prot(): PIProtocol() { - setName("test"); - ba.resize(1024); - setReceiverAddress("127.0.0.1", 3003, true); - setReceiverData(ba.data(), ba.size_s()); - setSenderAddress("127.0.0.2", 3003, true); - setSenderData(ba.data(), ba.size_s()); - setExpectedFrequency(100); - //setSenderFrequency(); - //startReceive(100); - startSend(10); - }; - PIByteArray ba; + ThreadTest(): PIThread() {cnt = 0; b = r = e = false;} + int cnt; + bool b, r, e; +private: + void begin() {b = true; cout << " thread begin\n";} + void run() {r = true; cout << " thread run " << cnt++ << endl; if (cnt == 10) stop();} + void end() {e = true; cout << " thread end\n";} }; -class MProt: public PIMultiProtocol { +PIMutex mutex_; +bool m = false; +int cnt = 0, gm = 0; + +class MutexTest: public PIThread { public: - MProt() {cor = incor = 0;} - - int cor, incor; - - virtual void received(PIProtocol * prot, bool corrected, char * data, int size) {if (corrected) cor++; else incor++; if (prot->name() == "test" && corrected) prot->send();} - - + MutexTest(): PIThread() {;} +private: + void run() {mutex_.lock(); if (m && cnt > 1) gm++; m = true; cout << " " << flush; if (cnt++ >= 128) stop(); msleep(20); mutex_.unlock();} }; - -struct BitsStruct { - uchar b1: 1; - uchar b2: 2; - uchar b4: 4; +class MutexTest2: public PIThread { +public: + MutexTest2(): PIThread() {;} +private: + void run() {mutex_.lock(); if (!m && cnt > 1) gm++; m = false; cout << "|" << flush; if (cnt++ >= 128) stop(); msleep(20); mutex_.unlock();} }; -int i = 1; -BitsStruct bits; - -void keyFunc(char key, void * ); - -PIConsole c(false, keyFunc); - -void keyFunc(char key, void * ) { - switch (key) { - case '-': i--; break; - case '+': i++; break; - case '[': bits.b1--; break; - case ']': bits.b1++; break; - case ';': bits.b2--; break; - case '\'': bits.b2++; break; - case ',': bits.b4--; break; - case '.': bits.b4++; break; - case 'i': i = c.getInt(1, 2); break; - } -}; void signalFunc(PISignals::Signal signal) { - if (signal == PISignals::Interrupt) cout << "Ctrl+C pressed" << endl; + if (signal != PISignals::Interrupt) return; + cout << "Ctrl+C pressed, exiting ..." << endl; + exit(0); }; -void timerEvent(void*, int delim) { - cout << "tick " << delim << endl; + +bool t = false; +void timerEvent(void * data, int delim) { + t = true; + cout << " tick from constuctor, delimiter = " << delim << ", data = " << data << endl; }; -PITimer timer(timerEvent); +bool +t2 = false; +void timerEvent2(void * data, int delim) { + t2 = true; + cout << " tick from delimiter " << delim << ", data = " << data << endl; +}; -void timerEvent2(void*, int delim) { - cout << "tick2 " << delim << endl; + +class ObjectTest: public PIObject { +public: + ObjectTest(const PIString & name = PIString()): PIObject(name) {h = hi = ht = false;} + EVENT_HANDLER(ObjectTest, void, handler) {h = true; cout << " handler in \"" << name() << "\"" << endl;} + EVENT_HANDLER2(ObjectTest, void, handler_i_s, int, i, PIString, s) {hi = true; cout << " handler_i_s in \"" << name() << "\", i = " << i << ", s = \"" << s << "\"" << endl;} + EVENT_HANDLER2(ObjectTest, void, handler_timeout, void * , data, int, delim) {ht = true; cout << " handler_timeout in \"" << name() << "\", data = " << data << ", delim = " << delim << endl;} + bool h, hi, ht; +}; + + +class ObjectTest2: public PIObject { +public: + ObjectTest2(const PIString & name = PIString()): PIObject(name) {;} + void raise0(const PIString & e) {cout << " event \"" << e << "\" from \"" << name() << "\"" << endl; raiseEvent(this, e);} + void raise2(const PIString & e, int i, const PIString & s) {cout << " event \"" << e << "\" from \"" << name() << "\"" << endl; raiseEvent(this, e, i, s);} +}; + +class CA: public PIObject { +public: + CA(const PIString & n): PIObject(n) {;} + EVENT_HANDLER(CA, void, handler_ca) {a = true; cout << " handler CA" << endl;} + bool a; +}; + +class CB: public CA { +public: + CB(const PIString & n): CA(n) {;} + EVENT_HANDLER(CB, void, handler_cb) {b = true; cout << " handler CB" << endl;} + bool b; +}; + +class CC: public CB { +public: + CC(const PIString & n): CB(n) {;} + EVENT_HANDLER(CC, void, handler_cc) {c = true; cout << " handler CC" << endl;} + bool c; +}; + +class CD: public CC { +public: + CD(const PIString & n): CC(n) {;} + EVENT_HANDLER(CD, void, handler_cd) {d = true; cout << " handler CD" << endl;} + bool d; }; int main(int argc, char * argv[]) { - /*PICLI cli(argc, argv); - cli.addArgument("debug"); - cli.addArgument("value", "V", "Val", true); - if (cli.hasArgument("debug")) - cout << "has debug" << endl; - if (cli.hasArgument("value")) - cout << "value = " << cli.argumentValue("value") << endl;*/ - /* - timer.start(100); - timer.addDelimiter(2, timerEvent2); + PIFile f; + f.open("_test", PIFile::ReadWrite || PIFile::New); + if (f.isEmpty()) f.remove(); + + return 0; + bool r_string = true, r_thread = true, r_mutex = true, r_timer = true, r_file = true, r_eval = true, r_event = true; + bool succ = true; + cout << "== PIP test program ==" << endl; + cout << "== Built with PIP " << PIPVersion() << " ==" << endl << endl; + cout << "== String test ==" << endl; + PIString string("test string"); + cout << " \"test string\" -> \"" << string << "\"" << endl; + if (string.length() != 11) succ = r_string = false; + cout << " to char * = \"" << string.data() << "\"" << endl; + cout << " to std::string = \"" << string.stdString() << "\"" << endl; + if (string.stdString().length() != 11) succ = r_string = false; + cout << " to std::wstring = \"" << string.stdWString() << "\"" << endl; + if (string.stdWString().length() != 11) succ = r_string = false; + if (succ) cout << " convertions success" << endl; + else cout << " convertions fail" << endl; + succ = true; + string = PIString("αβγ°℃"); + cout << " \"αβγ°℃\" -> \"" << string << "\"" << endl; + if (string.length() != 5) succ = r_string = false; + cout << " to char * = \"" << string.data() << "\"" << endl; + cout << " to std::string = \"" << string.stdString() << "\"" << endl; + if (string.stdString().length() != 10) succ = r_string = false; + cout << " to std::wstring = \"" << string.stdWString() << "\"" << endl; + if (string.stdWString().length() != 5) succ = r_string = false; + if (succ) cout << " complex convertions success" << endl; + else cout << " complex convertions fail" << endl; + if (r_string) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; + + cout << endl << "== Thread test ==" << endl; + ThreadTest thread; + thread.start(100); + msleep(10); + thread.waitForFinish(); + r_thread = thread.b && thread.r && thread.e && thread.cnt == 10; + if (r_thread) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; + + cout << endl << "== Mutex test ==" << endl << " "; + MutexTest thread_m; + MutexTest2 thread_m2; + thread_m.start(); + thread_m2.start(); + thread_m.waitForFinish(); + thread_m2.waitForFinish(); + cout << endl; + r_mutex = gm < 5; + if (r_mutex) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; + + cout << endl << "== Timer test ==" << endl; + PITimer timer(timerEvent, (void*)255); + timer.addDelimiter(2); timer.addDelimiter(5, timerEvent2); - FOREVER_WAIT - */ - /*PISignals::setSlot(signalFunc); - PISignals::grabSignals(PISignals::Interrupt); - FOREVER_WAIT*/ + timer.start(100.f); + msleep(1005); + timer.stop(); + r_timer = t && t2; + if (r_timer) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; - /*PIString ip; - int port; - PIConfig conf("protocols.conf~"); - ip = conf.getValue("mcp1.receiver.ip"); - port = conf.getValue("mcp1.receiver.port"); - cout << ip << ":" << port << endl;*/ + cout << endl << "== File test ==" << endl; + PIFile file(" file_test", PIFile::New | PIFile::ReadWrite); + cout << " file \"" << file.path() << "\" is "; + if (!file.isOpened()) cout << "not "; + cout << "opened" << endl; + file << "test string"; + cout << " write " << file.pos() << " bytes" << endl; + if (file.pos() != 11) r_file = false; + PIByteArray ba = file.readAll(); + if (ba.size() != 11) r_file = false; + cout << " read " << ba.size() << " bytes: \"" << PIString(ba) << '\"' << endl; + file.remove(); + if (r_file) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; + + cout << endl << "== Evaluator test ==" << endl; + PIEvaluator evaluator; + evaluator.setVariable("x", complexd(2., 1.)); + PIString expression("2x^2 + i"); + evaluator.check(expression); + cout << " expression = \"" << expression << '\"' << endl; + cout << " recognized = \"" << evaluator.expression() << '\"' << endl; + cout << " error = \"" << evaluator.error() << '\"' << endl; + cout << " \"x\" = " << evaluator.content.variable("x").value << endl; + cout << " result = " << evaluator.evaluate() << endl; + r_eval = round(evaluator.lastResult()) == complexd(9., 12.); + if (r_eval) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; - c.addString("PIConsole example"); - c.addEmptyLine(); + cout << endl << "== Event test ==" << endl; + ObjectTest object("obj"); + ObjectTest2 object2("obj2"); + PITimer timer2; + timer2.setData((void * )128); + timer2.addDelimiter(2); + timer2.addDelimiter(5); + CONNECT0(void, &object2, event0, &object, handler); + CONNECT2(void, int, PIString, &object2, event2, &object, handler_i_s); + CONNECT2(void, void * , int, &timer2, timeout, &object, handler_timeout); + object2.raise0("event0"); + object2.raise2("event2", 123, "string"); + timer2.start(100.f); + msleep(505); + timer2.stop(); + CA ca("cd"); + CD cd("cd"); + CONNECT(void, &ca, event_ca, &cd, handler_cd); + CONNECT(void, &ca, event_ca, &cd, handler_cc); + CONNECT(void, &ca, event_ca, &cd, handler_cb); + CONNECT(void, &ca, event_ca, &cd, handler_ca); + PIObject::raiseEvent(&ca, "event_ca"); + r_event = object.h && object.hi && object.ht && cd.a && cd.b && cd.c && cd.d; + if (r_event) cout << "== Success ==" << endl; + else cout << "== Fail ==" << endl; - c.addTab("colors", '1'); - c.addString("Red string", 1, PIConsole::Red); - c.addString("Blue on yellow", 1, PIConsole::Blue | PIConsole::BackYellow); - c.addEmptyLine(); - - c.addTab("columns", '2'); - c.addString("column 1", 1, PIConsole::BackYellow); - c.addString("column 2", 2, PIConsole::BackCyan); - c.addString("column 3", 3, PIConsole::BackMagenta); - c.addEmptyLine(); - - c.addTab("bits", '3'); - c.addBitVariable("b1", &bits, 0, 1); - c.addBitVariable("b2", &bits, 1, 2); - c.addBitVariable("b4", &bits, 3, 4); - c.addCustomStatus("[] - -/+ b1, ;\' - -/+ b2, ,. - -/+ b4"); - c.addEmptyLine(); - - c.addTab("formats", '4'); - c.addVariable("our int", &i); - c.addVariable("dec", &i); - c.addVariable("oct", &i, 1, PIConsole::Oct); - c.addVariable("hex", &i, 1, PIConsole::Hex); - c.addCustomStatus("-+ - -/+ number"); - c.addEmptyLine(); - - c.setTab(0); - c.enableExitCapture(); - c.start(true); - - /*MProt mp; - Prot p; - PIRepeater r("protocols.conf", "r", 1024); - mp.addProtocol(p); - c.addVariable("rec : " + mp[0]->receiverDeviceName() + ":", mp[0]->receiverDeviceState_ptr()); - c.addVariable("send: " + mp[0]->senderDeviceName() + ":", mp[0]->senderDeviceState_ptr()); - c.addVariable("freq", mp[0]->immediateFrequency_ptr()); - c.addVariable("sent ", mp[0]->sendCount_ptr()); - c.addVariable("ok ", mp[0]->receiveCount_ptr()); - c.addVariable("wrong", mp[0]->wrongCount_ptr()); - c.addEmptyLine(); - c.addVariable("mp_corr", &mp.cor); - c.addVariable("mp_incr", &mp.incor); - c.addVariable(r.firstChannelName() + ", rec ", r.receiveCount_ptr()); - c.addVariable(r.secondChannelName() + ", send", r.sendCount_ptr()); - c.enableExitCapture(); - mp.start(); - c.start(false);*/ - c.waitForFinish(); + cout << endl << "== Results ==" << endl; + cout << "= String " << r_string << " =" << endl; + cout << "= Thread " << r_thread << " =" << endl; + cout << "= Mutex " << r_mutex << " =" << endl; + cout << "= Timer " << r_timer << " =" << endl; + cout << "= File " << r_file << " =" << endl; + cout << "= Evaluator " << r_eval << " =" << endl; + cout << "= Event " << r_event << " =" << endl; + if (r_string && r_thread && r_mutex && r_timer && r_file && r_eval && r_event) + cout << "== All tests successful ==" << endl; }; diff --git a/make_install_qnx_6.3.0.sh b/make_install_qnx_6.3.0.sh new file mode 100644 index 00000000..971775fd --- /dev/null +++ b/make_install_qnx_6.3.0.sh @@ -0,0 +1,5 @@ +#! /bin/sh +make $@ +cp -vf *.h /usr/qnx630/target/qnx6/usr/include/ +cp -vf lib*.so /usr/qnx630/target/qnx6/x86/lib/ +cp -vf lib*.so /lib/ diff --git a/pibitarray.h b/pibitarray.h index 9223f643..362ea7ee 100644 --- a/pibitarray.h +++ b/pibitarray.h @@ -37,7 +37,7 @@ public: if (value) data_[si] |= (1 << ti); else data_[si] &= ~(1 << ti); return *this;} - PIBitArray & insert(const uint & index, const uchar & value) {return push_back(value > 0);} + PIBitArray & insert(const uint & index, const uchar & value) {return insert(index, value > 0);} PIBitArray & push_front(const bool & value) {return insert(0, value);} PIBitArray & push_front(const uchar & value) {return push_front(value > 0);} PIBitArray & pop_back() {return resize(size_ - 1);} diff --git a/pibytearray.cpp b/pibytearray.cpp index 3bac7ed2..65e62d43 100644 --- a/pibytearray.cpp +++ b/pibytearray.cpp @@ -15,19 +15,19 @@ PIVector PIHuffman::compress(const PIVector & src) { void PIHuffman::calcFrequencies(const PIVector & src) { nodes.resize(256); - for (uint i = 0; i < 256; ++i) { + for (int i = 0; i < 256; ++i) { nodes[i].parent = nodes[i].right = nodes[i].left = 0; nodes[i].freq = 0; nodes[i].word.resize(1); nodes[i].word[0] = static_cast(i); } - for (uint i = 0; i < src.size(); ++i) + for (int i = 0; i < src.size_s(); ++i) nodes[src[i]].freq++; std::qsort(nodes.data(), 256, sizeof(node), nodeCompare); - for (uint i = 255; i >= 0; --i) + for (int i = 255; i >= 0; --i) if (nodes[i].freq > 0 && i < 255) {nodes.remove(i + 1, 255 - i); break;} - for (uint i = 0; i < nodes.size(); ++i) + for (int i = 0; i < nodes.size_s(); ++i) cout << string((char*)nodes[i].word.data(), 1) << ": " << nodes[i].freq << endl; } @@ -38,8 +38,8 @@ PIByteArray & PIByteArray::convertToBase64() { base64HelpStruct hs; PIByteArray t; if (size() == 0) return *this; - uint sz = (size() / 3) * 3; - for (uint i = 0; i < sz; ++i) { + int sz = (size_s() / 3) * 3; + for (int i = 0; i < sz; ++i) { hs.byte0 = hs.byte1 = hs.byte2 = 0; hs.byte0 = at(i); hs.byte1 = at(++i); diff --git a/pichar.h b/pichar.h index 3c5cbde3..9aa19ef3 100644 --- a/pichar.h +++ b/pichar.h @@ -63,7 +63,7 @@ public: int toInt() const {return static_cast(ch);} const wchar_t * toWCharPtr() const {return &ch;} const char * toCharPtr() const {return reinterpret_cast(&ch);} - const wchar_t toWChar() const {return ch;} + wchar_t toWChar() const {return ch;} char toAscii() const {return ch % 256;} int unicode16Code() const {wchar_t wc; if (mbtowc(&wc, toCharPtr(), 4) > 0) return wc; return 0;} //#ifdef WINDOWS diff --git a/picli.h b/picli.h index 948d3243..a58b3a80 100644 --- a/picli.h +++ b/picli.h @@ -28,8 +28,8 @@ public: const PIString & shortKeyPrefix() const {return _prefix_short;} const PIString & fullKeyPrefix() const {return _prefix_full;} - const int mandatoryArgumentsCount() const {return _count_mand;} - const int optionalArgumentsCount() const {return _count_opt;} + int mandatoryArgumentsCount() const {return _count_mand;} + int optionalArgumentsCount() const {return _count_opt;} void setShortKeyPrefix(const PIString & prefix) {_prefix_short = prefix;} void setFullKeyPrefix(const PIString & prefix) {_prefix_full = prefix;} void setMandatoryArgumentsCount(const int count) {_count_mand = count;} diff --git a/piconfig.h b/piconfig.h index 2edafd77..f9b5b72d 100644 --- a/piconfig.h +++ b/piconfig.h @@ -4,18 +4,31 @@ #include "pifile.h" #define PICONFIG_GET_VALUE \ - inline Entry & getValue(const PIString & vname, const char * def, bool * exist = 0) {return getValue(vname, PIString(def), exist);} \ - inline Entry & getValue(const PIString & vname, const PIStringList & def, bool * exist = 0) {return getValue(vname, def.join("%|%"), exist);} \ - inline Entry & getValue(const PIString & vname, const bool def, bool * exist = 0) {return getValue(vname, PIString::fromBool(def), exist);} \ - inline Entry & getValue(const PIString & vname, const short def, bool * exist = 0) {return getValue(vname, itos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const int def, bool * exist = 0) {return getValue(vname, itos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const long def, bool * exist = 0) {return getValue(vname, ltos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const uchar def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const ushort def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const uint def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const ulong def, bool * exist = 0) {return getValue(vname, ultos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const float def, bool * exist = 0) {return getValue(vname, ftos(def), exist);} \ - inline Entry & getValue(const PIString & vname, const double def, bool * exist = 0) {return getValue(vname, dtos(def), exist);} + Entry & getValue(const PIString & vname, const char * def, bool * exist = 0) {return getValue(vname, PIString(def), exist);} \ + Entry & getValue(const PIString & vname, const PIStringList & def, bool * exist = 0) {return getValue(vname, def.join("%|%"), exist);} \ + Entry & getValue(const PIString & vname, const bool def, bool * exist = 0) {return getValue(vname, PIString::fromBool(def), exist);} \ + Entry & getValue(const PIString & vname, const short def, bool * exist = 0) {return getValue(vname, itos(def), exist);} \ + Entry & getValue(const PIString & vname, const int def, bool * exist = 0) {return getValue(vname, itos(def), exist);} \ + Entry & getValue(const PIString & vname, const long def, bool * exist = 0) {return getValue(vname, ltos(def), exist);} \ + Entry & getValue(const PIString & vname, const uchar def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \ + Entry & getValue(const PIString & vname, const ushort def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \ + Entry & getValue(const PIString & vname, const uint def, bool * exist = 0) {return getValue(vname, uitos(def), exist);} \ + Entry & getValue(const PIString & vname, const ulong def, bool * exist = 0) {return getValue(vname, ultos(def), exist);} \ + Entry & getValue(const PIString & vname, const float def, bool * exist = 0) {return getValue(vname, ftos(def), exist);} \ + Entry & getValue(const PIString & vname, const double def, bool * exist = 0) {return getValue(vname, dtos(def), exist);} \ + \ + Entry & getValue(const PIString & vname, const char * def, bool * exist = 0) const {return getValue(vname, PIString(def), exist);} \ + Entry & getValue(const PIString & vname, const PIStringList & def, bool * exist = 0) const {return getValue(vname, def.join("%|%"), exist);} \ + Entry & getValue(const PIString & vname, const bool def, bool * exist = 0) const {return getValue(vname, PIString::fromBool(def), exist);} \ + Entry & getValue(const PIString & vname, const short def, bool * exist = 0) const {return getValue(vname, itos(def), exist);} \ + Entry & getValue(const PIString & vname, const int def, bool * exist = 0) const {return getValue(vname, itos(def), exist);} \ + Entry & getValue(const PIString & vname, const long def, bool * exist = 0) const {return getValue(vname, ltos(def), exist);} \ + Entry & getValue(const PIString & vname, const uchar def, bool * exist = 0) const {return getValue(vname, uitos(def), exist);} \ + Entry & getValue(const PIString & vname, const ushort def, bool * exist = 0) const {return getValue(vname, uitos(def), exist);} \ + Entry & getValue(const PIString & vname, const uint def, bool * exist = 0) const {return getValue(vname, uitos(def), exist);} \ + Entry & getValue(const PIString & vname, const ulong def, bool * exist = 0) const {return getValue(vname, ultos(def), exist);} \ + Entry & getValue(const PIString & vname, const float def, bool * exist = 0) const {return getValue(vname, ftos(def), exist);} \ + Entry & getValue(const PIString & vname, const double def, bool * exist = 0) const {return getValue(vname, dtos(def), exist);} class PIConfig: public PIFile { @@ -23,7 +36,7 @@ class PIConfig: public PIFile friend class Branch; public: PIConfig(const PIString & path, PIFlags mode = Read | Write); - ~PIConfig() {;} + ~PIConfig() {piForeach (Entry * i, root._children) deleteEntry(i);} class Entry; @@ -32,9 +45,10 @@ public: friend class Entry; friend std::ostream & operator <<(std::ostream & s, const Branch & v); public: - inline Branch() {;} + Branch() {;} Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0); + Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0) const {return const_cast(this)->getValue(vname, def, exist);} PICONFIG_GET_VALUE Branch allLeaves(); @@ -42,15 +56,15 @@ public: Branch getLeaves(); Branch getBranches(); Branch & filter(const PIString & f); - inline bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;} - inline int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;} + bool isEntryExists(const PIString & name) const {piForeachC (Entry * i, *this) if (entryExists(i, name)) return true; return false;} + int indexOf(const Entry * e) {for (int i = 0; i < size_s(); ++i) if (at(i) == e) return i; return -1;} - inline void clear() {piForeach (Entry * i, *this) delete i; PIVector::clear();} + void clear() {piForeach (Entry * i, *this) delete i; PIVector::clear();} private: bool entryExists(const Entry * e, const PIString & name) const; - inline void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}} - inline void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);} + void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if (i->isLeaf()) b << i; else allLeaves(b, i);}} + void coutt(std::ostream & s, const PIString & p) const {piForeachC (Entry * i, *this) i->coutt(s, p);} static Entry _empty; PIString delim; @@ -61,46 +75,47 @@ public: friend class PIConfig; friend class Branch; public: - inline Entry() {_parent = 0;} + Entry() {_parent = 0;} - inline Entry * parent() const {return _parent;} - inline int childCount() {return _children.size_s();} - inline Branch & children() {_children.delim = delim; return _children;} - inline Entry * child(const int index) const {return _children[index];} - inline Entry * findChild(const PIString & name) {piForeach (Entry * i, _children) if (i->_name == name) return i; return 0;} - inline const Entry * findChild(const PIString & name) const {piForeachC (Entry * i, _children) if (i->_name == name) return i; return 0;} - inline bool isLeaf() const {return _children.isEmpty();} + Entry * parent() const {return _parent;} + int childCount() {return _children.size_s();} + Branch & children() {_children.delim = delim; return _children;} + Entry * child(const int index) const {return _children[index];} + Entry * findChild(const PIString & name) {piForeach (Entry * i, _children) if (i->_name == name) return i; return 0;} + const Entry * findChild(const PIString & name) const {piForeachC (Entry * i, _children) if (i->_name == name) return i; return 0;} + bool isLeaf() const {return _children.isEmpty();} - inline const PIString & name() const {return _name;} - inline const PIString & value() const {return _value;} - inline const PIString & type() const {return _type;} - inline const PIString & comment() const {return _comment;} - inline const PIString & fullName() const {return _full_name;} + const PIString & name() const {return _name;} + const PIString & value() const {return _value;} + const PIString & type() const {return _type;} + const PIString & comment() const {return _comment;} + const PIString & fullName() const {return _full_name;} - inline Entry & setName(const PIString & value) {_name = value; return *this;} - inline Entry & setType(const PIString & value) {_type = value; return *this;} - inline Entry & setComment(const PIString & value) {_comment = value; return *this;} - inline Entry & setValue(const PIString & value) {_value = value; return *this;} - inline Entry & setValue(const PIStringList & value) {setValue(value.join("%|%")); setType("l"); return *this;} - inline Entry & setValue(const char * value) {setValue(PIString(value)); setType("s"); return *this;} - inline Entry & setValue(const bool value) {setValue(btos(value)); setType("b"); return *this;} - inline Entry & setValue(const char value) {setValue(PIString(1, value)); setType("s"); return *this;} - inline Entry & setValue(const short value) {setValue(itos(value)); setType("n"); return *this;} - inline Entry & setValue(const int value) {setValue(itos(value)); setType("n"); return *this;} - inline Entry & setValue(const long value) {setValue(ltos(value)); setType("n"); return *this;} - inline Entry & setValue(const uchar value) {setValue(uitos(value)); setType("n"); return *this;} - inline Entry & setValue(const ushort value) {setValue(uitos(value)); setType("n"); return *this;} - inline Entry & setValue(const uint value) {setValue(uitos(value)); setType("n"); return *this;} - inline Entry & setValue(const ulong value) {setValue(ultos(value)); setType("n"); return *this;} - inline Entry & setValue(const float value) {setValue(ftos(value)); setType("f"); return *this;} - inline Entry & setValue(const double value) {setValue(dtos(value)); setType("f"); return *this;} + Entry & setName(const PIString & value) {_name = value; return *this;} + Entry & setType(const PIString & value) {_type = value; return *this;} + Entry & setComment(const PIString & value) {_comment = value; return *this;} + Entry & setValue(const PIString & value) {_value = value; return *this;} + Entry & setValue(const PIStringList & value) {setValue(value.join("%|%")); setType("l"); return *this;} + Entry & setValue(const char * value) {setValue(PIString(value)); setType("s"); return *this;} + Entry & setValue(const bool value) {setValue(btos(value)); setType("b"); return *this;} + Entry & setValue(const char value) {setValue(PIString(1, value)); setType("s"); return *this;} + Entry & setValue(const short value) {setValue(itos(value)); setType("n"); return *this;} + Entry & setValue(const int value) {setValue(itos(value)); setType("n"); return *this;} + Entry & setValue(const long value) {setValue(ltos(value)); setType("n"); return *this;} + Entry & setValue(const uchar value) {setValue(uitos(value)); setType("n"); return *this;} + Entry & setValue(const ushort value) {setValue(uitos(value)); setType("n"); return *this;} + Entry & setValue(const uint value) {setValue(uitos(value)); setType("n"); return *this;} + Entry & setValue(const ulong value) {setValue(ultos(value)); setType("n"); return *this;} + Entry & setValue(const float value) {setValue(ftos(value)); setType("f"); return *this;} + Entry & setValue(const double value) {setValue(dtos(value)); setType("f"); return *this;} Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0); + Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0) const {return const_cast(this)->getValue(vname, def, exist);} PICONFIG_GET_VALUE Branch getValues(const PIString & vname); - inline bool isEntryExists(const PIString & name) const {return entryExists(this, name);} + bool isEntryExists(const PIString & name) const {return entryExists(this, name);} operator bool() {return _value.toBool();} operator char() {return (_value.isEmpty() ? 0 : _value[0].toAscii());} @@ -117,11 +132,11 @@ public: operator PIStringList() {return _value.split("%|%");} private: - inline static bool compare(const PIConfig::Entry * f, const PIConfig::Entry * s) {return f->_line < s->_line;} + static bool compare(const PIConfig::Entry * f, const PIConfig::Entry * s) {return f->_line < s->_line;} bool entryExists(const Entry * e, const PIString & name) const; - inline void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;} - inline void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;} - inline void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->coutt(s, nl);} + void buildLine() {_all = _tab + _full_name + " = " + _value + " #" + _type + " " + _comment;} + void clear() {_children.clear(); _name = _value = _type = _comment = _all = PIString(); _line = 0; _parent = 0;} + void coutt(std::ostream & s, const PIString & p) const {PIString nl = p + " "; if (!_value.isEmpty()) s << p << _name << " = " << _value << endl; else cout << p << _name << endl; piForeachC (Entry * i, _children) i->coutt(s, nl);} static Entry _empty; Entry * _parent; @@ -138,36 +153,37 @@ public: }; Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0); + Entry & getValue(const PIString & vname, const PIString & def = PIString(), bool * exist = 0) const {return const_cast(this)->getValue(vname, def, exist);} PICONFIG_GET_VALUE Branch getValues(const PIString & vname); void setValue(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true); - inline void setValue(const PIString & name, const PIStringList & value, bool write = true) {setValue(name, value.join("%|%"), "l", write);} - inline void setValue(const PIString & name, const char * value, bool write = true) {setValue(name, PIString(value), "s", write);} - inline void setValue(const PIString & name, const bool value, bool write = true) {setValue(name, btos(value), "b", write);} - inline void setValue(const PIString & name, const short value, bool write = true) {setValue(name, itos(value), "n", write);} - inline void setValue(const PIString & name, const int value, bool write = true) {setValue(name, itos(value), "n", write);} - inline void setValue(const PIString & name, const long value, bool write = true) {setValue(name, ltos(value), "n", write);} - inline void setValue(const PIString & name, const uchar value, bool write = true) {setValue(name, uitos(value), "n", write);} - inline void setValue(const PIString & name, const ushort value, bool write = true) {setValue(name, uitos(value), "n", write);} - inline void setValue(const PIString & name, const uint value, bool write = true) {setValue(name, uitos(value), "n", write);} - inline void setValue(const PIString & name, const ulong value, bool write = true) {setValue(name, ultos(value), "n", write);} - inline void setValue(const PIString & name, const float value, bool write = true) {setValue(name, ftos(value), "f", write);} - inline void setValue(const PIString & name, const double value, bool write = true) {setValue(name, dtos(value), "f", write);} + void setValue(const PIString & name, const PIStringList & value, bool write = true) {setValue(name, value.join("%|%"), "l", write);} + void setValue(const PIString & name, const char * value, bool write = true) {setValue(name, PIString(value), "s", write);} + void setValue(const PIString & name, const bool value, bool write = true) {setValue(name, btos(value), "b", write);} + void setValue(const PIString & name, const short value, bool write = true) {setValue(name, itos(value), "n", write);} + void setValue(const PIString & name, const int value, bool write = true) {setValue(name, itos(value), "n", write);} + void setValue(const PIString & name, const long value, bool write = true) {setValue(name, ltos(value), "n", write);} + void setValue(const PIString & name, const uchar value, bool write = true) {setValue(name, uitos(value), "n", write);} + void setValue(const PIString & name, const ushort value, bool write = true) {setValue(name, uitos(value), "n", write);} + void setValue(const PIString & name, const uint value, bool write = true) {setValue(name, uitos(value), "n", write);} + void setValue(const PIString & name, const ulong value, bool write = true) {setValue(name, ultos(value), "n", write);} + void setValue(const PIString & name, const float value, bool write = true) {setValue(name, ftos(value), "f", write);} + void setValue(const PIString & name, const double value, bool write = true) {setValue(name, dtos(value), "f", write);} - inline Entry & rootEntry() {return root;} - inline int entriesCount() const {return childCount(&root);} - inline bool isEntryExists(const PIString & name) const {return entryExists(&root, name);} + Entry & rootEntry() {return root;} + int entriesCount() const {return childCount(&root);} + bool isEntryExists(const PIString & name) const {return entryExists(&root, name);} - inline Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;} - inline Branch allLeaves() {Branch b; allLeaves(b, &root); std::sort(b.begin(), b.end(), Entry::compare); return b;} + Branch allTree() {Branch b; piForeach (Entry * i, root._children) b << i; return b;} + Branch allLeaves() {Branch b; allLeaves(b, &root); std::sort(b.begin(), b.end(), Entry::compare); return b;} int entryIndex(const PIString & name); - inline PIString getName(uint number) {return entryByIndex(number)._name;} - inline PIString getValue(uint number) {return entryByIndex(number)._value;} - inline PIChar getType(uint number) {return entryByIndex(number)._type[0];} - inline PIString getComment(uint number) {return entryByIndex(number)._comment;} + PIString getName(uint number) {return entryByIndex(number)._name;} + PIString getValue(uint number) {return entryByIndex(number)._value;} + PIChar getType(uint number) {return entryByIndex(number)._type[0];} + PIString getComment(uint number) {return entryByIndex(number)._comment;} void addEntry(const PIString & name, const PIString & value, const PIString & type = "s", bool write = true); void setName(uint number, const PIString & name, bool write = true); @@ -190,8 +206,9 @@ private: void buildFullNames(Entry * e) {piForeach (Entry * i, e->_children) {if (e != &root) i->_full_name = e->_full_name + delim + i->_name; else i->_full_name = i->_name; buildFullNames(i);}} void allLeaves(Branch & b, Entry * e) {piForeach (Entry * i, e->_children) {if ((!i->_value.isEmpty() && !i->isLeaf()) || i->isLeaf()) b << i; allLeaves(b, i);}} void setEntryDelim(Entry * e, const PIString & d) {piForeach (Entry * i, e->_children) setEntryDelim(i, d); e->delim = d;} - inline Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);} + Entry & entryByIndex(const int index) {Branch b = allLeaves(); if (index < 0 || index >= b.size_s()) return empty; return *(b[index]);} void removeEntry(Branch & b, Entry * e); + void deleteEntry(Entry * e) {piForeach (Entry * i, e->_children) deleteEntry(i); delete e;} void parse(); int centry; diff --git a/piconsole.cpp b/piconsole.cpp index aac782c9..1aa1338d 100644 --- a/piconsole.cpp +++ b/piconsole.cpp @@ -217,7 +217,7 @@ PIString PIConsole::fstr(PIFlags f) { #define liprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%ld", x); break;} #define lliprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; default: return printf("%lld", x); break;} #define cuprint(x) switch (num_format) {case (1): return printf("0x%.2X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;} -#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hd", x); break;} +#define suprint(x) switch (num_format) {case (1): return printf("0x%.4hX", x); break; case (2): return printf("%o", x); break; default: return printf("%hu", x); break;} #define uprint(x) switch (num_format) {case (1): return printf("0x%.8X", x); break; case (2): return printf("%o", x); break; default: return printf("%u", x); break;} #define luprint(x) switch (num_format) {case (1): return printf("0x%.16lX", x); break; case (2): return printf("%lo", x); break; default: return printf("%lu", x); break;} #define lluprint(x) switch (num_format) {case (1): return printf("0x%.16llX", x); break; case (2): return printf("%llo", x); break; default: return printf("%llu", x); break;} @@ -436,6 +436,27 @@ void PIConsole::addVariable(const PIString & name, llong * ptr, int column, PIFl ADD_VAR_BODY tv.type = 12; tv.ll = ptr; vars()[column - 1].push_back(tv);} void PIConsole::addVariable(const PIString & name, ullong * ptr, int column, PIFlags format) { ADD_VAR_BODY tv.type = 13; tv.ull = ptr; vars()[column - 1].push_back(tv);} +void PIConsole::addVariable(const PIString & name, PIProtocol * ptr, int column, PIFlags format) { + addString("protocol " + name, column, format | PIConsole::Bold); + addVariable("Rec :" + ptr->receiverDeviceName() + " ", ptr->receiverDeviceState_ptr(), column, format); + addVariable("Send:" + ptr->senderDeviceName() + " ", ptr->senderDeviceState_ptr(), column, format); + addVariable("Sended count", ptr->sendCount_ptr(), column, format); + addVariable("Received count", ptr->receiveCount_ptr(), column, format); + addVariable("Invalid count", ptr->wrongCount_ptr(), column, format); + addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), column, format); + addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), column, format); + addVariable("Disconnect Timeout, s", ptr->disconnectTimeout_ptr(), column, format); + addVariable("Quality", ptr->quality_ptr(), column, format); +} +void PIConsole::addVariable(const PIString & name, PISystemMonitor * ptr, int column, PIFlags format) { + addString("monitor " + name, column, format | PIConsole::Bold); + addVariable("state ", &(ptr->statistic().state), column, format); + addVariable("threads ", &(ptr->statistic().threads), column, format); + addVariable("priority", &(ptr->statistic().priority), column, format); + addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), column, format); + addVariable("memory shared ", &(ptr->statistic().share_memsize_readable), column, format); + addVariable("cpu load", &(ptr->statistic().cpu_load_system), column, format); +} void PIConsole::addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column, PIFlags format) { tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format; checkColumn(column); vars()[column - 1].push_back(tv);} diff --git a/piconsole.h b/piconsole.h index ee19e542..6132b02e 100644 --- a/piconsole.h +++ b/piconsole.h @@ -2,10 +2,11 @@ #define PICONSOLE_H #include "pikbdlistener.h" -#include "pistring.h" +#include "piprotocol.h" +#include "pisystemmonitor.h" #ifndef WINDOWS -#include -#include +# include +# include #endif class PIConsole: public PIThread @@ -57,6 +58,8 @@ public: void addVariable(const PIString & name, ullong * ptr, int column = 1, PIFlags format = PIConsole::Normal); void addVariable(const PIString & name, float * ptr, int column = 1, PIFlags format = PIConsole::Normal); void addVariable(const PIString & name, double * ptr, int column = 1, PIFlags format = PIConsole::Normal); + void addVariable(const PIString & name, PIProtocol * ptr, int column = 1, PIFlags format = PIConsole::Normal); + void addVariable(const PIString & name, PISystemMonitor * ptr, int column = 1, PIFlags format = PIConsole::Normal); void addBitVariable(const PIString & name, void * ptr, int fromBit, int bitCount, int column = 1, PIFlags format = PIConsole::Normal); void addEmptyLine(int column = 1, uint count = 1); @@ -85,17 +88,20 @@ public: void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;} void clearCustomStatus() {tabs[cur_tab].status.clear();} - void clearVariables(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();} + EVENT_HANDLER0(PIConsole, void, clearVariables) {clearVariables(true);} + EVENT_HANDLER1(PIConsole, void, clearVariables, bool, clearScreen) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} vars().clear();} - inline void waitForFinish() {WAIT_FOR_EXIT} - inline void start(bool wait = false) {PIThread::start(40); if (wait) waitForFinish();} - void stop(bool clear = false); + EVENT_HANDLER0(PIConsole, void, waitForFinish) {WAIT_FOR_EXIT} + EVENT_HANDLER0(PIConsole, void, start) {start(false);} + EVENT_HANDLER1(PIConsole, void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();} + EVENT_HANDLER0(PIConsole, void, stop) {stop(false);} + EVENT_HANDLER1(PIConsole, void, stop, bool, clear); PIString fstr(PIFlags f); - inline void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);} - inline void disableExitCapture() {listener->disableExitCapture();} - inline bool exitCaptured() const {return listener->exitCaptured();} - inline char exitKey() const {return listener->exitKey();} + void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);} + void disableExitCapture() {listener->disableExitCapture();} + bool exitCaptured() const {return listener->exitCaptured();} + char exitKey() const {return listener->exitKey();} private: void begin(); @@ -103,32 +109,32 @@ private: void fillLabels(); #ifdef WINDOWS - inline void getWinCurCoord() {GetConsoleScreenBufferInfo(hOut, &csbi); ccoord = csbi.dwCursorPosition;} - inline COORD & getWinCoord(int dx = 0, int dy = 0) {getWinCurCoord(); ccoord.X += dx; ccoord.Y += dy; return ccoord;} - inline void toUpperLeft() {SetConsoleCursorPosition(hOut, ulcoord);} - inline void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));} - inline void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));} - inline void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = y; SetConsoleCursorPosition(hOut, ccoord);} - inline void clearScreen() {FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written); - FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);} - inline void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written); - FillConsoleOutputCharacter(hOut, ' ', width * height - width * ccoord.Y + ccoord.X, ccoord, &written);} - inline void clearLine() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width - ccoord.X, ccoord, &written); - FillConsoleOutputCharacter(hOut, ' ', width - ccoord.X, ccoord, &written);} - inline void newLine() {getWinCurCoord(); ccoord.X = 0; ccoord.Y++; SetConsoleCursorPosition(hOut, ccoord);} - inline void hideCursor() {curinfo.bVisible = false; SetConsoleCursorInfo(hOut, &curinfo);} - inline void showCursor() {curinfo.bVisible = true; SetConsoleCursorInfo(hOut, &curinfo);} + 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 toUpperLeft() {SetConsoleCursorPosition(hOut, ulcoord);} + void moveRight(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(n));} + void moveLeft(int n = 1) {SetConsoleCursorPosition(hOut, getWinCoord(-n));} + void moveTo(int x = 0, int y = 0) {ccoord.X = x; ccoord.Y = y; SetConsoleCursorPosition(hOut, ccoord);} + void clearScreen() {FillConsoleOutputAttribute(hOut, dattr, width * (height + 1), ulcoord, &written); + FillConsoleOutputCharacter(hOut, ' ', width * (height + 1), ulcoord, &written);} + void clearScreenLower() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width * height - width * ccoord.Y + ccoord.X, ccoord, &written); + FillConsoleOutputCharacter(hOut, ' ', width * height - width * ccoord.Y + ccoord.X, ccoord, &written);} + void clearLine() {getWinCurCoord(); FillConsoleOutputAttribute(hOut, dattr, width - ccoord.X, ccoord, &written); + FillConsoleOutputCharacter(hOut, ' ', width - ccoord.X, ccoord, &written);} + void newLine() {getWinCurCoord(); ccoord.X = 0; ccoord.Y++; SetConsoleCursorPosition(hOut, ccoord);} + void hideCursor() {curinfo.bVisible = false; SetConsoleCursorInfo(hOut, &curinfo);} + void showCursor() {curinfo.bVisible = true; SetConsoleCursorInfo(hOut, &curinfo);} #else - inline void toUpperLeft() {printf("\e[H");} - inline void moveRight(int n = 1) {if (n > 0) printf("\e[%dC", n);} - inline void moveLeft(int n = 1) {if (n > 0) printf("\e[%dD", n);} - inline void moveTo(int x = 0, int y = 0) {printf("\e[%d;%dH", y, x);} - inline void clearScreen() {printf("\e[H\e[J");} - inline void clearScreenLower() {printf("\e[J");} - inline void clearLine() {printf("\e[K");} - inline void newLine() {printf("\eE");} - inline void hideCursor() {printf("\e[?25l");} - inline void showCursor() {printf("\e[?25h");} + void toUpperLeft() {printf("\e[H");} + void moveRight(int n = 1) {if (n > 0) printf("\e[%dC", n);} + void moveLeft(int n = 1) {if (n > 0) printf("\e[%dD", n);} + void moveTo(int x = 0, int y = 0) {printf("\e[%d;%dH", y, x);} + void clearScreen() {printf("\e[H\e[J");} + void clearScreenLower() {printf("\e[J");} + void clearLine() {printf("\e[K");} + void newLine() {printf("\eE");} + void hideCursor() {printf("\e[?25l");} + void showCursor() {printf("\e[?25h");} #endif void status(); void checkColumn(uint col) {if (vars().size() < col) {vars().resize(col);}} @@ -188,9 +194,10 @@ private: char key; Tab() {;} Tab(PIString n, char k) {name = n; key = k;} + ~Tab() {;} }; - inline PIVector > & vars() {return tabs[cur_tab].variables;} + PIVector > & vars() {return tabs[cur_tab].variables;} inline int couts(const string v); inline int couts(const char * v); inline int couts(const bool v); diff --git a/picontainers.h b/picontainers.h index 1dd389b7..dbadbba1 100644 --- a/picontainers.h +++ b/picontainers.h @@ -123,12 +123,12 @@ public: void operator &=(const PIFlags & f) {flags = flags & f.flags;} void operator &=(const Enum & e) {flags = flags & e;} void operator &=(const int i) {flags = flags & i;} - PIFlags & operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;} - PIFlags & operator |(Enum e) const {PIFlags tf(flags | e); return tf;} - PIFlags & operator |(int i) const {PIFlags tf(flags | i); return tf;} - PIFlags & operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;} - PIFlags & operator &(Enum e) const {PIFlags tf(flags & e); return tf;} - PIFlags & operator &(int i) const {PIFlags tf(flags & i); return tf;} + PIFlags operator |(PIFlags f) const {PIFlags tf(flags | f.flags); return tf;} + PIFlags operator |(Enum e) const {PIFlags tf(flags | e); return tf;} + PIFlags operator |(int i) const {PIFlags tf(flags | i); return tf;} + PIFlags operator &(PIFlags f) const {PIFlags tf(flags & f.flags); return tf;} + PIFlags operator &(Enum e) const {PIFlags tf(flags & e); return tf;} + PIFlags operator &(int i) const {PIFlags tf(flags & i); return tf;} bool operator [](Enum e) {return (flags & e) == e;} operator int() const {return flags;} private: @@ -140,12 +140,13 @@ class PIVector: public vector { typedef PIVector _CVector; typedef vector _stlc; public: - PIVector() {;} - PIVector(const Type & value) {_stlc::push_back(value);} - PIVector(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);} - PIVector(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);} - PIVector(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);} - PIVector(uint size, const Type & value = Type()) {_stlc::resize(size, value);} + PIVector() {piMonitor.containers++;} + PIVector(const Type & value) {piMonitor.containers++; _stlc::push_back(value);} + PIVector(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);} + PIVector(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);} + PIVector(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);} + PIVector(uint size, const Type & value = Type()) {piMonitor.containers++; _stlc::resize(size, value);} + ~PIVector() {piMonitor.containers--;} const Type & at(uint index) const {return (*this)[index];} Type & at(uint index) {return (*this)[index];} const Type * data(uint index = 0) const {return &(*this)[index];} @@ -161,6 +162,8 @@ public: _CVector & insert(uint pos, const Type & t) {_stlc::insert(_stlc::begin() + pos, t); return *this;} _CVector & operator <<(const Type & t) {_stlc::push_back(t); return *this;} _CVector & operator <<(const _CVector & t) {for (typename _stlc::iterator i = t.begin(); i != t.end(); i++) _stlc::push_back(*i); return *this;} + bool operator ==(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return false; return true;} + bool operator !=(const _CVector & t) {for (uint i = 0; i < _stlc::size(); ++i) if (t[i] != at(i)) return true; return false;} bool contain(const Type & v) const {for (uint i = 0; i < _stlc::size(); ++i) if (v == at(i)) return true; return false;} }; @@ -172,12 +175,13 @@ class PIList: public list { typedef PIList _CList; typedef list _stlc; public: - PIList() {;} - PIList(const Type & value) {_stlc::resize(1, value);} - PIList(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);} - PIList(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);} - PIList(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);} - PIList(uint size, const Type & value = Type()) {_stlc::resize(size, value);} + PIList() {piMonitor.containers++;} + PIList(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);} + PIList(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);} + PIList(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);} + PIList(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);} + PIList(uint size, const Type & value = Type()) {piMonitor.containers++; _stlc::resize(size, value);} + ~PIList() {piMonitor.containers--;} Type & operator [](uint index) {return (*this)[index];} Type & operator [](uint index) const {return (*this)[index];} const Type * data(uint index = 0) const {return &(*this)[index];} @@ -197,11 +201,12 @@ class PISet: public set { typedef PISet _CSet; typedef set _stlc; public: - PISet() {;} - PISet(const Type & value) {_stlc::resize(1, value);} - PISet(const Type & v0, const Type & v1) {_stlc::insert(v0); _stlc::insert(v1);} - PISet(const Type & v0, const Type & v1, const Type & v2) {_stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2);} - PISet(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2); _stlc::insert(v3);} + PISet() {piMonitor.containers++;} + PISet(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);} + PISet(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::insert(v0); _stlc::insert(v1);} + PISet(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2);} + PISet(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::insert(v0); _stlc::insert(v1); _stlc::insert(v2); _stlc::insert(v3);} + ~PISet() {piMonitor.containers--;} int size_s() const {return static_cast(_stlc::size());} bool isEmpty() const {return _stlc::empty();} _CSet & remove(uint num) {_stlc::erase(_stlc::begin() + num); return *this;} @@ -232,11 +237,12 @@ class PIDeque: public deque { typedef PIDeque _CDeque; typedef deque _stlc; public: - PIDeque() {;} - PIDeque(const Type & value) {_stlc::resize(1, value);} - PIDeque(const Type & v0, const Type & v1) {_stlc::push_back(v0); _stlc::push_back(v1);} - PIDeque(const Type & v0, const Type & v1, const Type & v2) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);} - PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {_stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);} + PIDeque() {piMonitor.containers++;} + PIDeque(const Type & value) {piMonitor.containers++; _stlc::resize(1, value);} + PIDeque(const Type & v0, const Type & v1) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1);} + PIDeque(const Type & v0, const Type & v1, const Type & v2) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2);} + PIDeque(const Type & v0, const Type & v1, const Type & v2, const Type & v3) {piMonitor.containers++; _stlc::push_back(v0); _stlc::push_back(v1); _stlc::push_back(v2); _stlc::push_back(v3);} + ~PIDeque() {piMonitor.containers--;} int size_s() const {return static_cast(_stlc::size());} bool isEmpty() const {return _stlc::empty();} _CDeque & operator <<(const Type & t) {_CDeque::push_back(t); return *this;} @@ -279,9 +285,9 @@ class PIHash: public PISet > { public: PIHash() {;} PIHash(const Type & value, const Key & key) {insert(value, key);} - _CHash & insert(const Type & value, const Key & key) {_CSet::insert(PIPair(key, value));} - Type value(Key key) {for (typename _CHash::iterator i = _CHash::begin(); i != _CHash::end(); i++) if ((*i).first == key) return (*i).second; return Key();} - Type operator[](Key key) {return value(key);} + _CHash & insert(const Type & value, const Key & key) {_CSet::insert(PIPair(key, value)); return *this;} + Type value(Key key) const {for (typename _CHash::iterator i = _CHash::begin(); i != _CHash::end(); i++) if ((*i).first == key) return (*i).second; return Type();} + Type operator[](Key key) const {return value(key);} }; #endif // PICONTAINERS_H diff --git a/piethernet.cpp b/piethernet.cpp index 490ed38d..a13de62c 100644 --- a/piethernet.cpp +++ b/piethernet.cpp @@ -2,6 +2,7 @@ PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot): PIThread() { + piMonitor.ethernets++; setPriority(piHigh); data = data_; ip_ = ip_s = ip; @@ -19,6 +20,7 @@ PIEthernet::PIEthernet(PIString ip, int port, void * data_, EthernetFunc slot): PIEthernet::~PIEthernet() { + piMonitor.ethernets--; terminate(); #ifdef WINDOWS WSACleanup(); @@ -73,13 +75,13 @@ void PIEthernet::begin() { void PIEthernet::run() { -#ifdef WINDOWS +/*#ifdef WINDOWS int addr_len = sizeof(sockaddr); #else socklen_t addr_len = sizeof(sockaddr_storage); -#endif +#endif*/ //cout << "[PIEthernet] reading from " << &addr_ << endl; - readed = recvfrom(sock, buffer_, BUFFER_SIZE, 0, (sockaddr * )&addr_, &addr_len); + readed = recv(sock, buffer_, BUFFER_SIZE, 0/*, (sockaddr * )&addr_, &addr_len*/); //cout << WSAGetLastError() << endl; if (readed < 0) { cout << "[PIEthernet] Error while reading, " << errorString() << endl; diff --git a/piethernet.h b/piethernet.h index d0e12f7a..6215a361 100644 --- a/piethernet.h +++ b/piethernet.h @@ -40,7 +40,7 @@ public: bool receiverInitialized() const {return sock != -1;} bool senderInitialized() const {return sock_s != -1;} void terminate(); - inline const char * buffer() const {return buffer_;} + const char * buffer() const {return buffer_;} private: void begin(); diff --git a/pievaluator.h b/pievaluator.h index 55ffe9e3..38a32881 100644 --- a/pievaluator.h +++ b/pievaluator.h @@ -60,24 +60,24 @@ public: PIEvaluatorContent(); ~PIEvaluatorContent() {;} - inline void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));} - inline void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();} - inline int functionsCount() const {return functions.size();} - inline int variablesCount() const {return variables.size();} - inline int customVariablesCount() const {return variables.size() - cv_count;} - inline int findFunction(const PIString & name) const {for (uint i = 0; i < functions.size(); i++) if (functions[i].identifier == name) return i; return -1;} - inline int findVariable(const PIString & var_name) const {for (uint i = 0; i < variables.size(); i++) if (variables[i].name == var_name) return i; return -1;} - inline PIEvaluatorTypes::Function function(int index) {if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function(); return functions[index];} - inline PIEvaluatorTypes::Variable variable(int index) {if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable(); return variables[index];} - inline PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));} - inline PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));} - inline PIEvaluatorTypes::Variable customVariable(int index) {if (index < cv_count || index >= variables.size_s() + cv_count) return PIEvaluatorTypes::Variable(); return variables[index + cv_count];} + void addFunction(const PIString & name, int args = 1) {functions.push_back(PIEvaluatorTypes::Function(name, args, getBaseFunction(name)));} + void addVariable(const PIString & name, const complexd & val = 0.) {variables.push_back(PIEvaluatorTypes::Variable(name, val)); sortVariables();} + int functionsCount() const {return functions.size();} + int variablesCount() const {return variables.size();} + int customVariablesCount() const {return variables.size() - cv_count;} + int findFunction(const PIString & name) const {for (uint i = 0; i < functions.size(); i++) if (functions[i].identifier == name) return i; return -1;} + int findVariable(const PIString & var_name) const {for (uint i = 0; i < variables.size(); i++) if (variables[i].name == var_name) return i; return -1;} + PIEvaluatorTypes::Function function(int index) {if (index < 0 || index >= functions.size_s()) return PIEvaluatorTypes::Function(); return functions[index];} + PIEvaluatorTypes::Variable variable(int index) {if (index < 0 || index >= variables.size_s()) return PIEvaluatorTypes::Variable(); return variables[index];} + PIEvaluatorTypes::Function function(const PIString & name) {return function(findFunction(name));} + PIEvaluatorTypes::Variable variable(const PIString & name) {return variable(findVariable(name));} + PIEvaluatorTypes::Variable customVariable(int index) {if (index < cv_count || index >= variables.size_s() + cv_count) return PIEvaluatorTypes::Variable(); return variables[index + cv_count];} bool setVariableValue(int index, complexd new_value); bool setVariableName(int index, const PIString & new_name); - inline bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);} - inline bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);} - inline void removeVariable(int index) {variables.remove(index);} - inline void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));} + bool setVariableValue(const PIString & var_name, const complexd & new_value) {return setVariableValue(findVariable(var_name), new_value);} + bool setVariableName(const PIString & var_name, const PIString & new_name) {return setVariableName(findVariable(var_name), new_name);} + void removeVariable(int index) {variables.remove(index);} + void removeVariable(const PIString & var_name) {removeVariable(findVariable(var_name));} void clearCustomVariables(); void sortVariables(); PIEvaluatorTypes::BaseFunctions getBaseFunction(const PIString & name); @@ -96,17 +96,17 @@ public: ~PIEvaluator() {;} bool check(const PIString & string); - inline int setVariable(const PIString & name, complexd value = 0.) {if (content.findVariable(name) < 0) content.addVariable(name, value); else content.setVariableValue(name, value); return content.findVariable(name);} - inline void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);} - inline void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;} + int setVariable(const PIString & name, complexd value = 0.) {if (content.findVariable(name) < 0) content.addVariable(name, value); else content.setVariableValue(name, value); return content.findVariable(name);} + void setVariable(int index, complexd value = 0.) {if (index >= 0 && index < content.variablesCount()) content.setVariableValue(index, value);} + void setCustomVariableValue(int index, complexd value = 0.) {content.variables[index + content.cv_count].value = value;} complexd evaluate(); - inline void removeVariable(const PIString & name) {content.removeVariable(name);} - inline void clearCustomVariables() {content.clearCustomVariables();} - inline int variableIndex(const PIString & name) const {return content.findVariable(name);} - inline const PIStringList & unknownVariables() {return unknownVars;} - inline const PIString & expression() {return currentString;} - inline const PIString & error() {return lastError;} - inline const complexd & lastResult() {return out;} + void removeVariable(const PIString & name) {content.removeVariable(name);} + void clearCustomVariables() {content.clearCustomVariables();} + int variableIndex(const PIString & name) const {return content.findVariable(name);} + const PIStringList & unknownVariables() {return unknownVars;} + const PIString & expression() {return currentString;} + const PIString & error() {return lastError;} + const complexd & lastResult() {return out;} PIEvaluatorContent content; @@ -124,13 +124,13 @@ private: bool fillElements(); bool setSignes(); bool isSign(const PIChar & ch); - inline PIString inverse(const PIString & string) {int len = string.length(); PIString s; for (int i = 0; i < len; i++) s += string[len - i - 1]; return s;} + PIString inverse(const PIString & string) {int len = string.length(); PIString s; for (int i = 0; i < len; i++) s += string[len - i - 1]; return s;} bool check(); bool execInstructions(); PIString inBrackets(const PIString & string); PIString operationChar(const PIEvaluatorTypes::Operation & operation); PIEvaluatorTypes::Operation operationInOrder(const int & index); - inline complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;} + complexd value(const int & index) {if (index < 0) return tmpvars[-index - 1].value; else return kvars->at(index).value;} inline complexd residue(const complexd & f, const complexd & s); inline void execFunction(const PIEvaluatorTypes::Instruction & ci); diff --git a/pifile.cpp b/pifile.cpp index 7116b2cb..ab3fa115 100644 --- a/pifile.cpp +++ b/pifile.cpp @@ -23,18 +23,32 @@ PIString PIFile::readLine() { llong PIFile::readAll(void * data) { - llong cp = pos(), s = size(); + llong cp = pos(), s = size(), i = -1; stream.seekg(0); - stream.read((char * )data, s); + if (s < 0) { + while (!stream.eof()) + stream.read(&(((char*)data)[++i]), 1); + } else + stream.read((char * )data, s); seek(cp); return s; } -PIByteArray PIFile::readAll() { - llong s = size(); - if (s < 0) return PIByteArray(); - PIByteArray a(s); +PIByteArray PIFile::readAll(bool forceRead) { + llong cp = pos(), s = size(); + char c; + PIByteArray a; + if (s < 0) { + if (!forceRead) return a; + while (!stream.eof()) { + stream.read(&c, 1); + a.push_back(c); + } + seek(cp); + return a; + } + a.resize(s); s = readAll(a.data()); if (s >= 0) a.resize(s); return a; @@ -47,6 +61,7 @@ llong PIFile::size() { stream.seekg(0, fstream::end); s = stream.tellg(); stream.seekg(cp, fstream::beg); + stream.clear(); return s; } diff --git a/pifile.h b/pifile.h index 903ebb1a..1b600772 100644 --- a/pifile.h +++ b/pifile.h @@ -1,41 +1,42 @@ #ifndef PIFILE_H #define PIFILE_H -#include "pistring.h" +#include "piobject.h" #include using std::fstream; -class PIFile +class PIFile: public PIObject { public: - PIFile() {;} + PIFile(): PIObject() {;} - enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app}; + enum Mode {Read = fstream::in, Write = fstream::out, Truncate = fstream::trunc, New = fstream::app, ReadWrite = Read | Write}; - PIFile(const PIString & path, PIFlags mode = Read | Write) {open(path, mode);} - PIFile(const PIFile & file) {cpath = file.cpath; cmode = file.cmode;} + PIFile(const PIString & path, PIFlags mode = ReadWrite): PIObject(path) {open(path, mode);} + PIFile(const PIFile & file): PIObject(file.cpath) {cpath = file.cpath; cmode = file.cmode;} ~PIFile() {if (isOpened()) close();} PIFile & operator =(const PIFile & f) {cpath = f.cpath; cmode = f.cmode; return *this;} - bool open(const PIString & path, PIFlags mode); - bool open(PIFlags mode) {return open(cpath, mode);} - bool open(const PIString & path) {return open(path, cmode);} - bool open() {return open(cpath, cmode);} - void close() {stream.close();} - void clear() {string st = cpath.stdString(); close(); stream.open(st.c_str(), fstream::trunc | fstream::binary | (fstream::openmode)(int)cmode);} + EVENT_HANDLER2(PIFile, bool, open, const PIString & , path, PIFlags, mode); + EVENT_HANDLER1(PIFile, bool, open, PIFlags, mode) {return open(cpath, mode);} + EVENT_HANDLER1(PIFile, bool, open, const PIString & , path) {return open(path, cmode);} + EVENT_HANDLER0(PIFile, bool, open) {return open(cpath, cmode);} + EVENT_HANDLER0(PIFile, void, close) {stream.close();} + EVENT_HANDLER0(PIFile, void, clear) {string st = cpath.stdString(); close(); stream.open(st.c_str(), fstream::trunc | fstream::binary | (fstream::openmode)(int)cmode);} void seek(llong position) {stream.clear(); stream.seekg(position); stream.seekp(position);} void seekToBegin() {stream.clear(); stream.seekg(0, fstream::beg); stream.seekp(0, fstream::beg);} void seekToEnd() {stream.clear(); stream.seekg(0, fstream::end); stream.seekp(0, fstream::end);} void seekToLine(llong line) {stream.clear(); seekToBegin(); piForTimes (line) readLine();} // line 0 - begin of file - void resize(llong new_size, char fill = 0); + EVENT_HANDLER1(PIFile, void, resize, llong, new_size) {resize(new_size, 0);} + EVENT_HANDLER2(PIFile, void, resize, llong, new_size, char, fill); void fill(char c) {stream.fill(c);} - void flush() {stream.flush();} + EVENT_HANDLER0(PIFile, void, flush) {stream.flush();} PIString readLine(); llong readAll(void * data); - PIByteArray readAll(); - void remove() {if (isOpened()) close(); std::remove(cpath.data());} + PIByteArray readAll(bool forceRead = false); + EVENT_HANDLER0(PIFile, void, remove) {if (isOpened()) close(); std::remove(cpath.data());} PIString path() const {return cpath;} void setPath(const PIString & path) {cpath = path;} @@ -86,7 +87,9 @@ public: PIFile & operator >>(float & v) {stream >> v; return *this;} PIFile & operator >>(double & v) {stream >> v; return *this;} - static PIFile openTemporary(PIFlags mode = PIFile::Read | PIFile::Write); + static PIFile openTemporary(PIFlags mode = PIFile::ReadWrite); + static bool isExists(const PIString & path) {return std::ifstream(path.stdString().c_str()).good();} + static bool remove(const PIString & path) {return std::remove(path.stdString().c_str()) == 0;} private: fstream stream; diff --git a/piincludes.h b/piincludes.h index 10f4f0d9..85e4ecb0 100644 --- a/piincludes.h +++ b/piincludes.h @@ -1,7 +1,12 @@ #ifndef PIINCLUDES_H #define PIINCLUDES_H -#if __WIN32__ || __WIN64__ || WIN32 || WIN64 +#define PIP_VERSION 0x000100 +#define PIP_VERSION_MAJOR (PIP_VERSION & 0xFF0000) >> 16 +#define PIP_VERSION_MINOR (PIP_VERSION & 0xFF00) >> 8 +#define PIP_VERSION_REVISION PIP_VERSION & 0xFF + +#if WIN32 || WIN64 || _WIN32 || _WIN64 || __WIN32__ || __WIN64__ # define WINDOWS #endif #if __QNX__ || __QNXNTO__ @@ -28,17 +33,17 @@ #include #ifdef CC_GCC -#include +# include #endif #include #include #ifndef QNX -#include -#include -#include +# include +# include +# include #else -#include -#include +# include +# include #endif #include #include @@ -56,10 +61,13 @@ #include #include #ifdef WINDOWS -#include -#include -#include +# include +# include +# include #endif +#include "pimonitor.h" + +extern PIMonitor piMonitor; #define FOREVER for (;;) #define FOREVER_WAIT FOREVER msleep(1); @@ -94,9 +102,9 @@ typedef std::basic_string wstring; static bool isPIInit = false; -class piInit { +class PIInit { public: - piInit() { + PIInit() { if (isPIInit) return; isPIInit = true; #ifdef LINUX @@ -109,15 +117,14 @@ public: setlocale(LC_ALL, ""); #endif } - ~piInit() { + ~PIInit() { //if (currentLocale_t != 0) freelocale(currentLocale_t); } }; -static piInit __pi_init; +static PIInit piInit; static lconv * currentLocale = std::localeconv(); - #ifdef CC_VC inline string errorString() {char buff[1024]; strerror_s(buff, 1024, GetLastError()); return string(buff);} #else @@ -189,4 +196,6 @@ inline string dtos(const double num) { #endif return string(ch); }; +inline string PIPVersion() {return itos(PIP_VERSION_MAJOR) + "." + itos(PIP_VERSION_MINOR) + "." + itos(PIP_VERSION_REVISION);} + #endif // PIINCLUDES_H diff --git a/pimath.h b/pimath.h index c62d956e..32d3fad7 100644 --- a/pimath.h +++ b/pimath.h @@ -35,6 +35,9 @@ const double rad2deg = 45. / atan(1.); inline int pow2(const int p) {return 1 << p;} inline double sqr(const double & v) {return v * v;} inline double sinc(const double & v) {double t = M_PI * v; return sin(t) / t;} +inline complexd round(const complexd & c) {return complexd(round(c.real()), round(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()));} inline complexd atanc(const complexd & c) {return -complexd(-0.5, 1.) * 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));} @@ -68,58 +71,58 @@ public: PIMathVectorT(const PIVector & val) {resize(Size); PIMV_FOR(i, 0) c[i] = val[i];} PIMathVectorT(const _CVector & st, const _CVector & fn) {resize(Size); set(st, fn);} - inline uint size() const {return Size;} - inline _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - inline _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;} - inline _CVector & set(const _CVector & st, const _CVector & fn) {PIMV_FOR(i, 0) c[i] = fn[i] - st[i]; return *this;} - inline _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} - inline _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} - inline _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;} - inline Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} - inline Type length() const {return sqrt(lengthSqr());} - inline Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} - inline Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} - inline Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} - inline Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - inline Type angleDeg(const _CVector & v) const {return acos(angleCos(v)) * rad2deg;} - inline _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} - inline _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;} - inline _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} - inline bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} - inline bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} + uint size() const {return Size;} + _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} + _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;} + _CVector & set(const _CVector & st, const _CVector & fn) {PIMV_FOR(i, 0) c[i] = fn[i] - st[i]; return *this;} + _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} + _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} + _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;} + Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} + Type length() const {return sqrt(lengthSqr());} + Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} + Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} + Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} + Type angleRad(const _CVector & v) const {return acos(angleCos(v));} + Type angleDeg(const _CVector & v) const {return acos(angleCos(v)) * rad2deg;} + _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} + _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;} + _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} + bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} + bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} - inline Type & at(uint index) {return c[index];} - inline Type at(uint index) const {return c[index];} - inline Type & operator [](uint index) {return c[index];} - inline Type operator [](uint index) const {return c[index];} - inline void operator =(const _CVector & v) {c = v.c;} - inline bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} - inline bool operator !=(const _CVector & v) const {return !(*this == c);} - inline void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} - inline void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} - inline void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} - inline void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} - inline void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} - inline void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} - inline _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} - inline _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} - inline _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} - inline _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} - inline _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} - inline _CVector operator *(const _CVector & v) const {if (Size > 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} - inline Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} + Type & at(uint index) {return c[index];} + Type at(uint index) const {return c[index];} + Type & operator [](uint index) {return c[index];} + Type operator [](uint index) const {return c[index];} + void operator =(const _CVector & v) {c = v.c;} + bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} + bool operator !=(const _CVector & v) const {return !(*this == c);} + void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} + void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} + void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} + void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} + void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} + void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} + _CVector operator -() const {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} + _CVector operator +(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} + _CVector operator -(const _CVector & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} + _CVector operator *(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} + _CVector operator /(const Type & v) const {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} + _CVector operator *(const _CVector & v) const {if (Size > 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} + Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} - inline operator PIMathMatrixT<1, Size, Type>() {return PIMathMatrixT<1, Size, Type>(c);} - inline Type distToLine(const _CVector & lp0, const _CVector & lp1) { + operator PIMathMatrixT<1, Size, Type>() {return PIMathMatrixT<1, Size, Type>(c);} + Type distToLine(const _CVector & lp0, const _CVector & lp1) { _CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length();//, s = b.length() + c.length() - a.length(); return f;} template /// vector {Size, Type} to vector {Size1, Type1} - inline PIMathVectorT turnTo() {PIMathVectorT tv; uint sz = piMin(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} + PIMathVectorT turnTo() {PIMathVectorT tv; uint sz = piMin(Size, Size1); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} private: - inline void resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value);} + void resize(uint size, const Type & new_value = Type()) {c.resize(size, new_value);} PIVector c; }; @@ -127,7 +130,7 @@ private: template inline std::ostream & operator <<(std::ostream & s, const PIMathVectorT & v) {s << '{'; PIMV_FOR(i, 0) {s << v[i]; if (i < Size - 1) s << ", ";} s << '}'; return s;} template -inline const bool operator ||(const PIMathVectorT & f, const PIMathVectorT & s) {return (f * s).isNull();} +inline bool operator ||(const PIMathVectorT & f, const PIMathVectorT & s) {return (f * s).isNull();} //template /// vector {Size0, Type0} to vector {Size1, Type1} //inline operator PIMathVectorT(const PIMathVectorT & v) {PIMathVectorT tv; uint sz = piMin(Size0, Size1); for (uint i = 0; i < sz; ++i) tv[i] = v[i]; return tv;} @@ -161,37 +164,37 @@ public: static _CMatrix identity() {_CMatrix tm = _CMatrix(); PIMM_FOR_WB(c, r) tm.m[c][r] = (c == r ? Type(1) : Type(0)); return tm;} - inline uint cols() const {return Cols;} - inline uint rows() const {return Rows;} - inline _CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[index][i]; return tv;} - inline _CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[i][index]; return tv;} - inline _CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[index][i] = v[i]; return *this;} - inline _CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[i][index] = v[i]; return *this;} - inline _CMatrix & swapRows(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[i][r0]; m[i][r0] = m[i][r1]; m[i][r1] = t;} return *this;} - inline _CMatrix & swapCols(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[c0][i]; m[c0][i] = m[c1][i]; m[c1][i] = t;} return *this;} - inline _CMatrix & fill(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] = v; return *this;} + uint cols() const {return Cols;} + uint rows() const {return Rows;} + _CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[index][i]; return tv;} + _CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[i][index]; return tv;} + _CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[index][i] = v[i]; return *this;} + _CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[i][index] = v[i]; return *this;} + _CMatrix & swapRows(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[i][r0]; m[i][r0] = m[i][r1]; m[i][r1] = t;} return *this;} + _CMatrix & swapCols(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[c0][i]; m[c0][i] = m[c1][i]; m[c1][i] = t;} return *this;} + _CMatrix & fill(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] = v; return *this;} //inline _CMatrix & set(Type fval, ...) {m[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) m[i] = va_arg(vl, Type); va_end(vl); return *this;} //inline void normalize() {Type tv = length(); if (tv == Type(1)) return; PIMV_FOR(i, 0) m[i] /= tv;} - inline bool isSquare() const {return cols() == rows();} - inline bool isIdentity() const {PIMM_FOR_WB(c, r) if ((c == r) ? m[c][r] != Type(1) : m[c][r] != Type(0)) return false; return true;} - inline bool isNull() const {PIMM_FOR_WB(c, r) if (m[c][r] != Type(0)) return false; return true;} + bool isSquare() const {return cols() == rows();} + bool isIdentity() const {PIMM_FOR_WB(c, r) if ((c == r) ? m[c][r] != Type(1) : m[c][r] != Type(0)) return false; return true;} + bool isNull() const {PIMM_FOR_WB(c, r) if (m[c][r] != Type(0)) return false; return true;} - inline Type & at(uint col, uint row) {return m[col][row];} - inline Type at(uint col, uint row) const {return m[col][row];} - inline PIVector & operator [](uint col) {return m[col];} - inline PIVector operator [](uint col) const {return m[col];} - inline void operator =(const _CMatrix & sm) {m = sm.m;} - inline bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;} - inline bool operator !=(const _CMatrix & sm) const {return !(*this == sm);} - inline void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];} - inline void operator -=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] -= sm.m[c][r];} - inline void operator *=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] *= v;} - inline void operator /=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] /= v;} - inline _CMatrix operator -() {_CMatrix tm; PIMM_FOR_WB(c, r) tm.m[c][r] = -m[c][r]; return tm;} - inline _CMatrix operator +(const _CMatrix & sm) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] += sm.m[c][r]; return tm;} - inline _CMatrix operator -(const _CMatrix & sm) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] -= sm.m[c][r]; return tm;} - inline _CMatrix operator *(const Type & v) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] *= v; return tm;} - inline _CMatrix operator /(const Type & v) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] /= v; return tm;} + Type & at(uint col, uint row) {return m[col][row];} + Type at(uint col, uint row) const {return m[col][row];} + PIVector & operator [](uint col) {return m[col];} + PIVector operator [](uint col) const {return m[col];} + void operator =(const _CMatrix & sm) {m = sm.m;} + bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;} + bool operator !=(const _CMatrix & sm) const {return !(*this == sm);} + void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];} + void operator -=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] -= sm.m[c][r];} + void operator *=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] *= v;} + void operator /=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] /= v;} + _CMatrix operator -() {_CMatrix tm; PIMM_FOR_WB(c, r) tm.m[c][r] = -m[c][r]; return tm;} + _CMatrix operator +(const _CMatrix & sm) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] += sm.m[c][r]; return tm;} + _CMatrix operator -(const _CMatrix & sm) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] -= sm.m[c][r]; return tm;} + _CMatrix operator *(const Type & v) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] *= v; return tm;} + _CMatrix operator /(const Type & v) {_CMatrix tm = _CMatrix(*this); PIMM_FOR_WB(c, r) tm.m[c][r] /= v; return tm;} _CMatrix & toUpperTriangular(bool * ok = 0) { if (Cols != Rows) { @@ -291,11 +294,11 @@ public: m = mtmp.m; return *this; } - inline _CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;} - inline _CMatrixI transposed() {_CMatrixI tm; PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;} + _CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;} + _CMatrixI transposed() {_CMatrixI tm; PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;} private: - inline void resize(uint cols, uint rows, const Type & new_value = Type()) {m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value);} + void resize(uint cols, uint rows, const Type & new_value = Type()) {m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value);} PIVector > m; }; @@ -367,57 +370,57 @@ public: PIMathVector(const PIVector & val) {resize(val.size); PIMV_FOR(i, 0) c[i] = val[i];} PIMathVector(const _CVector & st, const _CVector & fn) {resize(st.size()); PIMV_FOR(i, 0) c[i] = fn[i] - st[i];} - inline uint size() const {return size_;} - inline _CVector & resize(uint size, const Type & new_value = Type()) {size_ = size; c.resize(size, new_value); return *this;} - inline _CVector resized(uint size, const Type & new_value = Type()) {_CVector tv = _CVector(*this); tv.resize(size, new_value); return tv;} - inline _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} - inline _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;} - inline _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} - inline _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} - inline _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;} - inline _CVector & swap(uint fe, uint se) {piSwap(c[fe], c[se]); return *this;} - inline Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} - inline Type length() const {return sqrt(lengthSqr());} - inline Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} - inline Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} - inline Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} - inline Type angleRad(const _CVector & v) const {return acos(angleCos(v));} - inline Type angleDeg(const _CVector & v) const {return acos(angleCos(v)) * rad2deg;} - inline _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} - inline _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;} - inline _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} - inline bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} - inline bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} + uint size() const {return size_;} + _CVector & resize(uint size, const Type & new_value = Type()) {size_ = size; c.resize(size, new_value); return *this;} + _CVector resized(uint size, const Type & new_value = Type()) {_CVector tv = _CVector(*this); tv.resize(size, new_value); return tv;} + _CVector & fill(const Type & v) {PIMV_FOR(i, 0) c[i] = v; return *this;} + _CVector & set(Type fval, ...) {c[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] = va_arg(vl, Type); va_end(vl); return *this;} + _CVector & move(const Type & v) {PIMV_FOR(i, 0) c[i] += v; return *this;} + _CVector & move(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i]; return *this;} + _CVector & move(Type fval, ...) {c[0] += fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) c[i] += va_arg(vl, Type); va_end(vl); return *this;} + _CVector & swap(uint fe, uint se) {piSwap(c[fe], c[se]); return *this;} + Type lengthSqr() const {Type tv(0); PIMV_FOR(i, 0) tv += (c[i] * c[i]); return tv;} + Type length() const {return sqrt(lengthSqr());} + Type manhattanLength() const {Type tv(0); PIMV_FOR(i, 0) tv += fabs(c[i]); return tv;} + Type angleCos(const _CVector & v) const {Type tv = v.length() * length(); return (tv == Type(0) ? Type(0) : ((*this) ^ v) / tv);} + Type angleSin(const _CVector & v) const {Type tv = angleCos(v); return sqrt(Type(1) - tv * tv);} + Type angleRad(const _CVector & v) const {return acos(angleCos(v));} + Type angleDeg(const _CVector & v) const {return acos(angleCos(v)) * rad2deg;} + _CVector projection(const _CVector & v) {Type tv = v.length(); return (tv == Type(0) ? _CVector() : v * (((*this) ^ v) / tv));} + _CVector & normalize() {Type tv = length(); if (tv == Type(1)) return *this; PIMV_FOR(i, 0) c[i] /= tv; return *this;} + _CVector normalized() {_CVector tv(*this); tv.normalize(); return tv;} + bool isNull() const {PIMV_FOR(i, 0) if (c[i] != Type(0)) return false; return true;} + bool isOrtho(const _CVector & v) const {return ((*this) ^ v) == Type(0);} - inline Type & at(uint index) {return c[index];} - inline Type at(uint index) const {return c[index];} - inline Type & operator [](uint index) {return c[index];} - inline Type operator [](uint index) const {return c[index];} - inline void operator =(const _CVector & v) {c = v.c;} - inline bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} - inline bool operator !=(const _CVector & v) const {return !(*this == c);} - inline void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} - inline void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} - inline void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} - inline void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} - inline void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} - inline void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} - inline _CVector operator -() {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} - inline _CVector operator +(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} - inline _CVector operator -(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} - inline _CVector operator *(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} - inline _CVector operator /(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} - inline _CVector operator *(const _CVector & v) {if (size_ < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} - inline Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} + Type & at(uint index) {return c[index];} + Type at(uint index) const {return c[index];} + Type & operator [](uint index) {return c[index];} + Type operator [](uint index) const {return c[index];} + void operator =(const _CVector & v) {c = v.c;} + bool operator ==(const _CVector & v) const {PIMV_FOR(i, 0) if (c[i] != v[i]) return false; return true;} + bool operator !=(const _CVector & v) const {return !(*this == c);} + void operator +=(const _CVector & v) {PIMV_FOR(i, 0) c[i] += v[i];} + void operator -=(const _CVector & v) {PIMV_FOR(i, 0) c[i] -= v[i];} + void operator *=(const Type & v) {PIMV_FOR(i, 0) c[i] *= v;} + void operator *=(const _CVector & v) {PIMV_FOR(i, 0) c[i] *= v[i];} + void operator /=(const Type & v) {PIMV_FOR(i, 0) c[i] /= v;} + void operator /=(const _CVector & v) {PIMV_FOR(i, 0) c[i] /= v[i];} + _CVector operator -() {_CVector tv; PIMV_FOR(i, 0) tv[i] = -c[i]; return tv;} + _CVector operator +(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] += v[i]; return tv;} + _CVector operator -(const _CVector & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] -= v[i]; return tv;} + _CVector operator *(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] *= v; return tv;} + _CVector operator /(const Type & v) {_CVector tv = _CVector(*this); PIMV_FOR(i, 0) tv[i] /= v; return tv;} + _CVector operator *(const _CVector & v) {if (size_ < 3) return _CVector(); _CVector tv; tv.fill(Type(1)); tv[0] = c[1]*v[2] - v[1]*c[2]; tv[1] = v[0]*c[2] - c[0]*v[2]; tv[2] = c[0]*v[1] - v[0]*c[1]; return tv;} + Type operator ^(const _CVector & v) const {Type tv(0); PIMV_FOR(i, 0) tv += c[i] * v[i]; return tv;} //inline operator PIMathMatrix<1, Size, Type>() {return PIMathMatrix<1, Size, Type>(c);} - inline Type distToLine(const _CVector & lp0, const _CVector & lp1) { + Type distToLine(const _CVector & lp0, const _CVector & lp1) { _CVector a(lp0, lp1), b(lp0, *this), c(lp1, *this); Type f = fabs(a[0]*b[1] - a[1]*b[0]) / a.length();//, s = b.length() + c.length() - a.length(); return f;} template - inline PIMathVector turnTo(uint size) {PIMathVector tv; uint sz = piMin(size_, size); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} + PIMathVector turnTo(uint size) {PIMathVector tv; uint sz = piMin(size_, size); for (uint i = 0; i < sz; ++i) tv[i] = c[i]; return tv;} private: uint size_; @@ -452,38 +455,38 @@ public: static _CMatrix identity(const uint cols_, const uint rows_) {_CMatrix tm(cols_, rows_); PIMM_FOR_WB(c, r) tm.m[c][r] = (c == r ? Type(1) : Type(0)); return tm;} - inline uint cols() const {return cols_;} - inline uint rows() const {return rows_;} - inline _CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[index][i]; return tv;} - inline _CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[i][index]; return tv;} - inline _CMatrix & resize(const uint cols, const uint rows, const Type & new_value = Type()) {cols_ = cols; rows_ = rows; m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value); return *this;} - inline _CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[index][i] = v[i]; return *this;} - inline _CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[i][index] = v[i]; return *this;} - inline _CMatrix & swapRows(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[i][r0]; m[i][r0] = m[i][r1]; m[i][r1] = t;} return *this;} - inline _CMatrix & swapCols(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[c0][i]; m[c0][i] = m[c1][i]; m[c1][i] = t;} return *this;} - inline _CMatrix & fill(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] = v; return *this;} + uint cols() const {return cols_;} + uint rows() const {return rows_;} + _CMCol col(uint index) {_CMCol tv; PIMM_FOR_R(i) tv[i] = m[index][i]; return tv;} + _CMRow row(uint index) {_CMRow tv; PIMM_FOR_C(i) tv[i] = m[i][index]; return tv;} + _CMatrix & resize(const uint cols, const uint rows, const Type & new_value = Type()) {cols_ = cols; rows_ = rows; m.resize(cols); PIMM_FOR_C(i) m[i].resize(rows, new_value); return *this;} + _CMatrix & setCol(uint index, const _CMCol & v) {PIMM_FOR_R(i) m[index][i] = v[i]; return *this;} + _CMatrix & setRow(uint index, const _CMRow & v) {PIMM_FOR_C(i) m[i][index] = v[i]; return *this;} + _CMatrix & swapRows(uint r0, uint r1) {Type t; PIMM_FOR_C(i) {t = m[i][r0]; m[i][r0] = m[i][r1]; m[i][r1] = t;} return *this;} + _CMatrix & swapCols(uint c0, uint c1) {Type t; PIMM_FOR_R(i) {t = m[c0][i]; m[c0][i] = m[c1][i]; m[c1][i] = t;} return *this;} + _CMatrix & fill(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] = v; return *this;} //inline _CMatrix & set(Type fval, ...) {m[0] = fval; va_list vl; va_start(vl, fval); PIMV_FOR(i, 1) m[i] = va_arg(vl, Type); va_end(vl); return *this;} //inline void normalize() {Type tv = length(); if (tv == Type(1)) return; PIMV_FOR(i, 0) m[i] /= tv;} - inline bool isSquare() const {return cols() == rows();} - inline bool isIdentity() const {PIMM_FOR_WB(c, r) if ((c == r) ? m[c][r] != Type(1) : m[c][r] != Type(0)) return false; return true;} - inline bool isNull() const {PIMM_FOR_WB(c, r) if (m[c][r] != Type(0)) return false; return true;} + bool isSquare() const {return cols() == rows();} + bool isIdentity() const {PIMM_FOR_WB(c, r) if ((c == r) ? m[c][r] != Type(1) : m[c][r] != Type(0)) return false; return true;} + bool isNull() const {PIMM_FOR_WB(c, r) if (m[c][r] != Type(0)) return false; return true;} - inline Type & at(uint col, uint row) {return m[col][row];} - inline Type at(uint col, uint row) const {return m[col][row];} - inline PIVector & operator [](uint col) {return m[col];} - inline PIVector operator [](uint col) const {return m[col];} - inline void operator =(const _CMatrix & sm) {m = sm.m;} - inline bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;} - inline bool operator !=(const _CMatrix & sm) const {return !(*this == sm);} - inline void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];} - inline void operator -=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] -= sm.m[c][r];} - inline void operator *=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] *= v;} - inline void operator /=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] /= v;} - inline _CMatrix operator -() {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] = -m[c][r]; return tm;} - inline _CMatrix operator +(const _CMatrix & sm) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] += sm.m[c][r]; return tm;} - inline _CMatrix operator -(const _CMatrix & sm) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] -= sm.m[c][r]; return tm;} - inline _CMatrix operator *(const Type & v) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] *= v; return tm;} - inline _CMatrix operator /(const Type & v) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] /= v; return tm;} + Type & at(uint col, uint row) {return m[col][row];} + Type at(uint col, uint row) const {return m[col][row];} + PIVector & operator [](uint col) {return m[col];} + PIVector operator [](uint col) const {return m[col];} + void operator =(const _CMatrix & sm) {m = sm.m;} + bool operator ==(const _CMatrix & sm) const {PIMM_FOR_WB(c, r) if (m[c][r] != sm.m[c][r]) return false; return true;} + bool operator !=(const _CMatrix & sm) const {return !(*this == sm);} + void operator +=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] += sm.m[c][r];} + void operator -=(const _CMatrix & sm) {PIMM_FOR_WB(c, r) m[c][r] -= sm.m[c][r];} + void operator *=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] *= v;} + void operator /=(const Type & v) {PIMM_FOR_WB(c, r) m[c][r] /= v;} + _CMatrix operator -() {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] = -m[c][r]; return tm;} + _CMatrix operator +(const _CMatrix & sm) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] += sm.m[c][r]; return tm;} + _CMatrix operator -(const _CMatrix & sm) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] -= sm.m[c][r]; return tm;} + _CMatrix operator *(const Type & v) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] *= v; return tm;} + _CMatrix operator /(const Type & v) {_CMatrix tm(*this); PIMM_FOR_WB(c, r) tm.m[c][r] /= v; return tm;} _CMatrix & toUpperTriangular(bool * ok = 0) { if (cols_ != rows_) { @@ -587,8 +590,8 @@ public: m = mtmp.m; return *this; } - inline _CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;} - inline _CMatrix transposed() {_CMatrix tm(rows_, cols_); PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;} + _CMatrix inverted(bool * ok = 0) {_CMatrix tm(*this); tm.invert(ok); return tm;} + _CMatrix transposed() {_CMatrix tm(rows_, cols_); PIMM_FOR_WB(c, r) tm[r][c] = m[c][r]; return tm;} private: uint cols_, rows_; @@ -696,17 +699,17 @@ public: void solveABM3(double u, double h); void solveABM4(double u, double h); void solvePA(double u, double h, uint deg); - inline void solvePA2(double u, double h) {if (step > 0) solvePA(u, h, 2); else solveEyler1(u, h);} - inline void solvePA3(double u, double h) {if (step > 1) solvePA(u, h, 3); else solvePA2(u, h);} - inline void solvePA4(double u, double h) {if (step > 2) solvePA(u, h, 4); else solvePA3(u, h);} - inline void solvePA5(double u, double h) {if (step > 3) solvePA(u, h, 5); else solvePA4(u, h);} + void solvePA2(double u, double h) {if (step > 0) solvePA(u, h, 2); else solveEyler1(u, h);} + void solvePA3(double u, double h) {if (step > 1) solvePA(u, h, 3); else solvePA2(u, h);} + void solvePA4(double u, double h) {if (step > 2) solvePA(u, h, 4); else solvePA3(u, h);} + void solvePA5(double u, double h) {if (step > 3) solvePA(u, h, 5); else solvePA4(u, h);} PIMathVectord X; static Method method_global; static const char methods_desc[]; private: - inline void moveF() {for (uint i = F.size() - 1; i > 0; --i) F[i] = F[i - 1];} + void moveF() {for (uint i = F.size() - 1; i > 0; --i) F[i] = F[i - 1];} PIMathMatrixd A, M; PIMathVectord d, a1, b1; diff --git a/pimonitor.cpp b/pimonitor.cpp new file mode 100644 index 00000000..0fd7f2d9 --- /dev/null +++ b/pimonitor.cpp @@ -0,0 +1,7 @@ +#include "pimonitor.h" + +PIMonitor piMonitor; + +PIMonitor::PIMonitor() { + containers = strings = threads = timers = serials = ethernets = files = objects = 0; +} diff --git a/pimonitor.h b/pimonitor.h new file mode 100644 index 00000000..b32e4fb7 --- /dev/null +++ b/pimonitor.h @@ -0,0 +1,13 @@ +#ifndef PIMONITOR_H +#define PIMONITOR_H + +class PIMonitor +{ +public: + PIMonitor(); + + int containers, strings, threads, timers, serials, ethernets, files, objects; + +}; + +#endif // PIMONITOR_H diff --git a/pimultiprotocol.cpp b/pimultiprotocol.cpp new file mode 100644 index 00000000..39114158 --- /dev/null +++ b/pimultiprotocol.cpp @@ -0,0 +1,2 @@ +#include "pimultiprotocol.h" + diff --git a/pimultiprotocol.h b/pimultiprotocol.h index 958e92bb..2dc347b2 100644 --- a/pimultiprotocol.h +++ b/pimultiprotocol.h @@ -42,21 +42,19 @@ private: class PIRepeater: public PIMultiProtocol { public: - PIRepeater(const PIString & config, const PIString & name, int data_size) { - ba_f = new PIByteArray(data_size); - ba_s = new PIByteArray(data_size); + PIRepeater(const PIString & config, const PIString & name) { PIConfig conf(config, PIFile::Read); if (!conf.isOpened()) { cout << "[PIRepeater \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; return; } - PIConfig::Entry b = conf.getValue(name); + PIConfig::Entry & b(conf.getValue(name)); if (b.childCount() != 2) { cout << "[PIRepeater \"" << name << "\"] \"" << config << "\" should consist 2 nodes!" << endl; return; } - addProtocol(config, b.child(0)->fullName(), 0, 0, ba_f->data(), data_size, ba_s->data(), data_size); - addProtocol(config, b.child(1)->fullName(), 0, 0, ba_s->data(), data_size, ba_f->data(), data_size); + addProtocol(config, b.child(0)->fullName()); + addProtocol(config, b.child(1)->fullName()); start(); } @@ -68,10 +66,8 @@ public: ullong sendCount() {if (count() == 2) return protocol(0)->sendCount(); return 0;} ullong * sendCount_ptr() {if (count() == 2) return protocol(0)->sendCount_ptr(); return 0;} - PIByteArray * ba_f, * ba_s; - private: - void received(PIProtocol * prot, bool , char * , int ) {if (prot == protocol(0)) protocol(1)->send(); else protocol(0)->send();} + void received(PIProtocol * prot, bool , char * data, int size) {if (prot == protocol(0)) protocol(1)->send(data, size); else protocol(0)->send(data, size);} }; diff --git a/pimutex.h b/pimutex.h index 05111ddc..7126af1b 100644 --- a/pimutex.h +++ b/pimutex.h @@ -1,53 +1,53 @@ -#ifndef PIMUTEX_H -#define PIMUTEX_H - +#ifndef PIMUTEX_H +#define PIMUTEX_H + +#include "piincludes.h" #ifdef CC_GCC #include #endif -#include "piincludes.h" - -class PIMutex -{ -public: -#ifndef WINDOWS - PIMutex() { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED); - pthread_mutex_init(&mutex, &attr); - pthread_mutexattr_destroy(&attr); - } - ~PIMutex() {pthread_mutex_destroy(&mutex);} - - void lock() {pthread_mutex_lock(&mutex);} - void unlock() {pthread_mutex_unlock(&mutex);} - bool tryLock() {return (pthread_mutex_trylock(&mutex) == 0);} -#else - PIMutex() {mutex = CreateMutex(0, false, 0);} - ~PIMutex() {CloseHandle(mutex);} - - void lock() {WaitForSingleObject(mutex, INFINITE);} - void unlock() {ReleaseMutex(mutex);} - bool tryLock() {return (WaitForSingleObject(mutex, 0) == WAIT_OBJECT_0);} -#endif - -private: -#ifndef WINDOWS - pthread_mutex_t mutex; -#else - void * mutex; -#endif - -}; - -class PIMutexLocker -{ -public: - PIMutexLocker(PIMutex * m): mutex(m) {mutex->lock();} - PIMutexLocker(PIMutex & m): mutex(&m) {mutex->lock();} - ~PIMutexLocker() {mutex->unlock();} -private: - PIMutex * mutex; -}; - -#endif // PIMUTEX_H + +class PIMutex +{ +public: +#ifndef WINDOWS + PIMutex() { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&mutex, &attr); + pthread_mutexattr_destroy(&attr); + } + ~PIMutex() {pthread_mutex_destroy(&mutex);} + + void lock() {pthread_mutex_lock(&mutex);} + void unlock() {pthread_mutex_unlock(&mutex);} + bool tryLock() {return (pthread_mutex_trylock(&mutex) == 0);} +#else + PIMutex() {mutex = CreateMutex(0, false, 0);} + ~PIMutex() {CloseHandle(mutex);} + + void lock() {WaitForSingleObject(mutex, INFINITE);} + void unlock() {ReleaseMutex(mutex);} + bool tryLock() {return (WaitForSingleObject(mutex, 0) == WAIT_OBJECT_0);} +#endif + +private: +#ifndef WINDOWS + pthread_mutex_t mutex; +#else + void * mutex; +#endif + +}; + +class PIMutexLocker +{ +public: + PIMutexLocker(PIMutex * m): mutex(m) {mutex->lock();} + PIMutexLocker(PIMutex & m): mutex(&m) {mutex->lock();} + ~PIMutexLocker() {mutex->unlock();} +private: + PIMutex * mutex; +}; + +#endif // PIMUTEX_H diff --git a/piobject.cpp b/piobject.cpp new file mode 100644 index 00000000..5cd2c4e8 --- /dev/null +++ b/piobject.cpp @@ -0,0 +1,20 @@ +#include "piobject.h" + +PIVector PIObject::objects; + +/* +PIStringList PIObject::events() { + PIStringList l; + for (PIHash::const_iterator i = signals_.begin(); i != signals_.end(); i++) + l << (*i).first; + return l; +} + + +PIStringList PIObject::eventHandlers() { + PIStringList l; + for (PIHash::const_iterator i = slots_.begin(); i != slots_.end(); i++) + l << (*i).first; + return l; +} +*/ \ No newline at end of file diff --git a/piobject.h b/piobject.h new file mode 100644 index 00000000..2cd43b7a --- /dev/null +++ b/piobject.h @@ -0,0 +1,236 @@ +#ifndef PIOBJECT_H +#define PIOBJECT_H + +#include "pistring.h" + +//#ifdef CC_VC +//#define HANDLER(c,s) #s,PIObject::handlerPtr((void(c::*)())&c::s) +//#else +//#define HANDLER(c,s) #s,(void*)&c::s +//#endif + +//#define EVENT_HANDLER0(obj, name) static void __stat_##name##__(obj * o) {o->name();} void name() +//#define EVENT_HANDLER1(obj, name, a0, n0) static void __stat_##name##__(obj * o, a0 n0) {o->name(n0);} void name(a0 n0) +//#define EVENT_HANDLER2(obj, name, a0, n0, a1, n1) static void __stat_##name##__(obj * o, a0 n0, a1 n1) {o->name(n0, n1);} void name(a0 n0, a1 n1) + +#define EVENT_HANDLER0(obj, ret, name) static ret __stat_##name##__(void * o) {return ((obj*)o)->name();} ret name() +#define EVENT_HANDLER1(obj, ret, name, a0, n0) static ret __stat_##name##__(void * o, a0 n0) {return ((obj*)o)->name(n0);} ret name(a0 n0) +#define EVENT_HANDLER2(obj, ret, name, a0, n0, a1, n1) static ret __stat_##name##__(void * o, a0 n0, a1 n1) {return ((obj*)o)->name(n0, n1);} ret name(a0 n0, a1 n1) +#define EVENT_HANDLER3(obj, ret, name, a0, n0, a1, n1, a2, n2) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2) {return ((obj*)o)->name(n0, n1, n2);} ret name(a0 n0, a1 n1, a2 n2) +#define EVENT_HANDLER4(obj, ret, name, a0, n0, a1, n1, a2, n2, a3, n3) static ret __stat_##name##__(void * o, a0 n0, a1 n1, a2 n2, a3 n3) {return ((obj*)o)->name(n0, n1, n2, n3);} ret name(a0 n0, a1 n1, a2 n2, a3 n3) +#define EVENT_HANDLER EVENT_HANDLER0 + +#define CONNECT0(ret, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*))(&(dst)->__stat_##handler##__)); +#define CONNECT1(ret, a0, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0))(&(dst)->__stat_##handler##__)); +#define CONNECT2(ret, a0, a1, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1))(&(dst)->__stat_##handler##__)); +#define CONNECT3(ret, a0, a1, a2, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2))(&(dst)->__stat_##handler##__)); +#define CONNECT4(ret, a0, a1, a2, a3, src, event, dst, handler) PIObject::connect(src, #event, dst, (void*)(ret(*)(void*, a0, a1, a2, a3))(&(dst)->__stat_##handler##__)); +#define CONNECT CONNECT0 + +class PIObject +{ + friend class PIObjectManager; +public: + PIObject(const PIString & name = PIString()) {piMonitor.objects++; setName(name); objects << this;} + ~PIObject() {piMonitor.objects--; objects.remove(this);} + + const PIString & name() const {return name_;} + void setName(const PIString & name) {name_ = name;} + /* + PIStringList events(); + PIStringList eventHandlers(); + + /// Events + void addEvent(const PIString & name) { + signals_.insert(NamedFunction(0, name, PIStringList()), name); + } + template + void addEvent(const PIString & name) { + signals_.insert(NamedFunction(0, name, PIStringList(typeid(T0).name())), name); + } + template + void addEvent(const PIString & name) { + signals_.insert(NamedFunction(0, name, PIStringList(typeid(T0).name(), typeid(T1).name())), name); + } + template + void addEvent(const PIString & name) { + signals_.insert(NamedFunction(0, name, PIStringList(typeid(T0).name(), typeid(T1).name(), typeid(T2).name())), name); + } + template + void addEvent(const PIString & name) { + signals_.insert(NamedFunction(0, name, PIStringList(typeid(T0).name(), typeid(T1).name(), typeid(T2).name(), typeid(T3).name())), name); + } + + /// Event handlers + void addEventHandler(const PIString & name, void * func) { + slots_.insert(NamedFunction(func, name, PIStringList()), name); + } + template + void addEventHandler(const PIString & name, void * func) { + slots_.insert(NamedFunction(func, name, PIStringList(typeid(T0).name())), name); + } + template + void addEventHandler(const PIString & name, void * func) { + slots_.insert(NamedFunction(func, name, PIStringList(typeid(T0).name(), typeid(T1).name())), name); + } + template + void addEventHandler(const PIString & name, void * func) { + slots_.insert(NamedFunction(func, name, PIStringList(typeid(T0).name(), typeid(T1).name(), typeid(T2).name())), name); + } + template + void addEventHandler(const PIString & name, void * func) { + slots_.insert(NamedFunction(func, name, PIStringList(typeid(T0).name(), typeid(T1).name(), typeid(T2).name(), typeid(T3).name())), name); + } + */ + /// Direct connect + static void connect(PIObject * src, const PIString & sig, void * dest, void * ev_h) {src->connections << Connection(ev_h, sig, dest);} + //static void connect(PIObject & src, const PIString & sig, PIObject * dest, void * ev_h) {src.connections << Connection(ev_h, sig, dest);} + //static void connect(PIObject * src, const PIString & sig, PIObject & dest, void * ev_h) {src->connections << Connection(ev_h, sig, &dest);} + //static void connect(PIObject & src, const PIString & sig, PIObject & dest, void * ev_h) {src.connections << Connection(ev_h, sig, &dest);} + + /*/// Connect through manager + static bool connect(const PIString & srcObject, const PIString & event, const PIString & destObject, const PIString & handler, bool force = false) { + PIObject * src = findByName(srcObject); + if (src == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << srcObject << "\" name!" << endl; + return false; + } + PIObject * dest = findByName(destObject); + if (dest == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl; + return false; + } + return PIObject::connect(src, event, dest, handler, force); + }*/ + + /// Raise events + static void raiseEvent(PIObject * sender, const PIString & event) { + for (int j = 0; j < sender->connections.size_s(); ++j) { + Connection & i(sender->connections[j]); + if (i.event != event) continue; + ((void(*)(void * ))i.slot)(i.dest); + } + } + template + static void raiseEvent(PIObject * sender, const PIString & event, const T0 & v0 = T0()) { + for (int j = 0; j < sender->connections.size_s(); ++j) { + Connection & i(sender->connections[j]); + if (i.event != event) continue; + ((void(*)(void * , T0))i.slot)(i.dest, v0); + } + } + template + static void raiseEvent(PIObject * sender, const PIString & event, const T0 & v0 = T0(), const T1 & v1 = T1()) { + for (int j = 0; j < sender->connections.size_s(); ++j) { + Connection & i(sender->connections[j]); + if (i.event != event) continue; + ((void(*)(void * , T0, T1))i.slot)(i.dest, v0, v1); + } + } + template + static void raiseEvent(PIObject * sender, const PIString & event, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) { + for (int j = 0; j < sender->connections.size_s(); ++j) { + Connection & i(sender->connections[j]); + if (i.event != event) continue; + ((void(*)(void * , T0, T1, T2))i.slot)(i.dest, v0, v1, v2); + } + } + template + static void raiseEvent(PIObject * sender, const PIString & event, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) { + for (int j = 0; j < sender->connections.size_s(); ++j) { + Connection & i(sender->connections[j]); + if (i.event != event) continue; + ((void(*)(void * , T0, T1, T2, T3))i.slot)(i.dest, v0, v1, v2, v3); + } + } + /* + /// Raise events (static) + static void raiseEvent(PIObject * destObject, const PIString & name) { + destObject->raiseEvent(name); + } + template + static void raiseEvent(PIObject * destObject, const PIString & name, const T0 & v0 = T0()) { + destObject->raiseEvent(name, v0); + } + template + static void raiseEvent(PIObject * destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1()) { + destObject->raiseEvent(name, v0, v1); + } + template + static void raiseEvent(PIObject * destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) { + destObject->raiseEvent(name, v0, v1, v2); + } + template + static void raiseEvent(PIObject * destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) { + destObject->raiseEvent(name, v0, v1, v2, v3); + } + */ + /// Raise events through manager + static void raiseEvent(const PIString & destObject, const PIString & name) { + PIObject * dest = findByName(destObject); + if (dest == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl; + return; + } + raiseEvent(dest, name); + } + template + static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0()) { + PIObject * dest = findByName(destObject); + if (dest == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl; + return; + } + raiseEvent(dest, name, v0); + } + template + static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1()) { + PIObject * dest = findByName(destObject); + if (dest == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl; + return; + } + raiseEvent(dest, name, v0, v1); + } + template + static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2()) { + PIObject * dest = findByName(destObject); + if (dest == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl; + return; + } + raiseEvent(name, dest, v0, v1, v2); + } + template + static void raiseEvent(const PIString & destObject, const PIString & name, const T0 & v0 = T0(), const T1 & v1 = T1(), const T2 & v2 = T2(), const T3 & v3 = T3()) { + PIObject * dest = findByName(destObject); + if (dest == 0) { + cout << "PIObject::connect: can`t find PIObject with \"" << destObject << "\" name!" << endl; + return; + } + raiseEvent(name,dest , v0, v1, v2, v3); + } + +private: + struct Connection { + Connection(void * s = 0, const PIString & e = PIString(), void * o = 0) {slot = s; event = e; dest = o;} + void * slot; + PIString event; + void * dest; + }; + + PIString name_; + PIVector connections; + + static PIVector objects; + static PIObject * findByName(const PIString & name) { + piForeach (PIObject * i, PIObject::objects) { + if (i->name_ != name) continue; + return i; + } + return 0; + }; + +}; + +#endif // PIOBJECT_H diff --git a/pip.h b/pip.h index 72fd39a9..86d7c876 100644 --- a/pip.h +++ b/pip.h @@ -6,3 +6,5 @@ #include "pimultiprotocol.h" #include "picodec.h" #include "pisignals.h" +#include "piobject.h" +#include "pisystemmonitor.h" diff --git a/pip.pro b/pip.pro index d10d9bd2..52122f91 100644 --- a/pip.pro +++ b/pip.pro @@ -1,18 +1,23 @@ ###################################################################### -# Automatically generated by qmake (2.01a) ?? ???. 18 21:49:21 2011 +# Automatically generated by qmake (2.01a) ?? ???. 5 22:55:18 2011 ###################################################################### TEMPLATE = app -TARGET = +TARGET = pip_test DEPENDPATH += . INCLUDEPATH += . +QT -= core gui +LIBS += -lpthread -lrt # Input HEADERS += pibitarray.h \ pibytearray.h \ pichar.h \ + picli.h \ + picodec.h \ piconfig.h \ piconsole.h \ + picontainers.h \ pidir.h \ piethernet.h \ pievaluator.h \ @@ -21,16 +26,24 @@ HEADERS += pibitarray.h \ piincludes.h \ pikbdlistener.h \ pimath.h \ + pimonitor.h \ + pimultiprotocol.h \ pimutex.h \ + piobject.h \ pip.h \ + piprocess.h \ piprotocol.h \ piserial.h \ + pisignals.h \ pistring.h \ + pisystemmonitor.h \ pithread.h \ pitimer.h \ pivariable.h SOURCES += main.cpp \ pibytearray.cpp \ + picli.cpp \ + picodec.cpp \ piconfig.cpp \ piconsole.cpp \ pidir.cpp \ @@ -39,9 +52,15 @@ SOURCES += main.cpp \ pifile.cpp \ pikbdlistener.cpp \ pimath.cpp \ + pimonitor.cpp \ + pimultiprotocol.cpp \ + piobject.cpp \ + piprocess.cpp \ piprotocol.cpp \ piserial.cpp \ + pisignals.cpp \ pistring.cpp \ + pisystemmonitor.cpp \ pithread.cpp \ pitimer.cpp \ pivariable.cpp diff --git a/piprocess.cpp b/piprocess.cpp index ca3509c8..d6549178 100644 --- a/piprocess.cpp +++ b/piprocess.cpp @@ -123,7 +123,7 @@ void PIProcess::run() { } else cout << "[PIProcess] \"CreateProcess\" error, " << errorString() << endl; #else - if (execvpe(str.c_str(), a, e) < 0) + if (execve(str.c_str(), a, e) < 0) cout << "[PIProcess] \"execvpe\" error, " << errorString() << endl; } else { msleep(1); diff --git a/piprocess.h b/piprocess.h index 4db73787..91303187 100644 --- a/piprocess.h +++ b/piprocess.h @@ -38,7 +38,7 @@ public: void exec(const PIString & program, const PIString & arg) {args.clear(); args << program << arg; exec_();} void exec(const PIString & program, const PIString & arg1, const PIString & arg2) {args.clear(); args << program << arg1 << arg2; exec_();} void exec(const PIString & program, const PIString & arg1, const PIString & arg2, const PIString & arg3) {args.clear(); args << program << arg1 << arg2 << arg3; exec_();} - void exec(const PIString & program, const PIStringList & args_) {args = args_; exec_();} + void exec(const PIString & program, const PIStringList & args_) {args << program << args_; exec_();} #ifdef WINDOWS void terminate() {if (is_exec) if (!TerminateProcess(pi.hProcess, 0)) return; pi.dwProcessId = 0;} #else @@ -54,6 +54,11 @@ public: void setEnvironmentVariable(const PIString & variable, const PIString & value); static PIStringList currentEnvironment() {PIStringList l; int i = 0; while (environ[i] != 0) {l << environ[i]; ++i;} return l;} +#ifdef WINDOWS + static int currentPID() {return GetCurrentProcessId();} +#else + static int currentPID() {return getpid();} +#endif private: virtual void run(); diff --git a/piprotocol.cpp b/piprotocol.cpp index 64c79810..5b05b899 100644 --- a/piprotocol.cpp +++ b/piprotocol.cpp @@ -1,9 +1,10 @@ #include "piprotocol.h" -PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_) { +PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr, int recHeaderSize, void * recDataPtr, int recDataSize, void * sendDataPtr_, int sendDataSize_): PIObject() { init(); protName = name; + PIObject::setName(name); PIConfig conf(config, PIFile::Read); if (!conf.isOpened()) { cout << "[PIProtocol \"" << name << "\"] Can`t open \"" << config << "\"!" << endl; @@ -11,13 +12,13 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re return; } int ps; - bool ok; + bool ok, has_dev = false; PIFlags pp; - PIConfig::Entry b = conf.getValue(name), - rb = b.getValue("receiver"), - sb = b.getValue("sender"); + PIConfig::Entry & b(conf.getValue(name)), + & rb(b.getValue("receiver")), + & sb(b.getValue("sender")); PIString dev; - + /// receiver section if (rb.isEntryExists("ip") && rb.isEntryExists("device")) { cout << "[PIProtocol \"" << name << "\"] Ambiguous receiver type in \"" << config << "\"!" << endl; @@ -35,6 +36,11 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re type_rec = PIProtocol::Ethernet; eth = new PIEthernet(dev, ps, this, receiveEvent); setReceiverAddress(dev, ps); + has_dev = true; + if (recDataPtr == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; + if (recDataSize == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; } dev = rb.getValue("device", "", &ok); if (ok) { @@ -54,9 +60,22 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re ser->setInSpeed((PISerial::Speed)ps); ser->setParameters(pp); ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize); + has_dev = true; + if (recDataPtr == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null receive data pointer!" << endl; + if (recDataSize == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null receive data size!" << endl; } - setExpectedFrequency(rb.getValue("frequency", -1.f)); - + float freq = rb.getValue("frequency", -1.f); + if (freq > 0. && !has_dev) + cout << "[PIProtocol \"" << name << "\"] Warning: no receiver device and not null expected frequency!" << endl; + float tm = b.getValue("disconnectTimeout", 3.f); + if (tm <= 0.) + cout << "[PIProtocol \"" << name << "\"] Warning: diconnect timeout <= 0 s!" << endl; + timeout_ = (tm < 0.) ? 0. : tm; + setExpectedFrequency(freq); + changeDisconnectTimeout(); + /// sender section if (sb.isEntryExists("ip") && sb.isEntryExists("device")) { cout << "[PIProtocol \"" << name << "\"] Ambiguous sender type in \"" << config << "\"!" << endl; @@ -64,6 +83,7 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re return; } dev = sb.getValue("ip", "", &ok); + has_dev = false; if (ok) { ps = sb.getValue("port", 0, &ok); if (!ok) { @@ -74,6 +94,11 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re type_send = PIProtocol::Ethernet; if (eth == 0) eth = new PIEthernet(dev, ps, this, receiveEvent); setSenderAddress(dev, ps); + has_dev = true; + if (sendDataPtr_ == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; + if (sendDataSize_ == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; } dev = sb.getValue("device", "", &ok); if (ok) { @@ -91,9 +116,17 @@ PIProtocol::PIProtocol(const PIString & config, const PIString & name, void * re ser->setOutSpeed((PISerial::Speed)ps); ser->setParameters(pp); ser->setReadData(recHeaderPtr, recHeaderSize, recDataSize); + has_dev = true; + if (sendDataPtr_ == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null send data pointer!" << endl; + if (sendDataSize_ == 0) + cout << "[PIProtocol \"" << name << "\"] Warning: null send data size!" << endl; } - setSenderFrequency(sb.getValue("frequency", -1.f)); - + freq = sb.getValue("frequency", -1.f); + if (freq > 0. && !has_dev) + cout << "[PIProtocol \"" << name << "\"] Warning: no sender device and not null send frequency!" << endl; + setSenderFrequency(freq); + headerPtr = (uchar * )recHeaderPtr; headerSize = recHeaderSize; dataPtr = (uchar * )recDataPtr; @@ -122,23 +155,36 @@ PIProtocol::~PIProtocol() { void PIProtocol::init() { work = new_mp_prot = false; + eth = 0; + ser = 0; ret_func = 0; mp_owner = 0; net_diag = PIProtocol::Unknown; cur_pckt = 0; diagTimer = 0; packet = 0; + timeout_ = 3.f; sendTimer = new PITimer(sendEvent, this); diagTimer = new PITimer(diagEvent, this); wrong_count = receive_count = send_count = 0; - immediateFreq = integralFreq = 0.f; + immediate_freq = integral_freq = 0.f; headerPtr = dataPtr = sendDataPtr = 0; headerSize = dataSize = sendDataSize = 0; - eth = 0; - ser = 0; type_rec = type_send = PIProtocol::None; devSenderState = devReceiverState = "Unknown"; devSenderName = devReceiverName = "no device"; + /*addEvent("receiver started"); + addEvent("receiver stopped"); + addEvent("sender started"); + addEvent("sender stopped"); + addEvent("received"); + addEvent("quality changed"); + addEventHandler(HANDLER(PIProtocol, startReceive)); + addEventHandler(HANDLER(PIProtocol, startSend)); + addEventHandler(HANDLER(PIProtocol, start)); + addEventHandler(HANDLER(PIProtocol, stopReceive)); + addEventHandler(HANDLER(PIProtocol, stopSend)); + addEventHandler(HANDLER(PIProtocol, stop));*/ } @@ -196,8 +242,13 @@ void PIProtocol::setSenderAddress(const PIString & ip, int port, bool force) { void PIProtocol::setExpectedFrequency(float frequency) { exp_freq = frequency; - if (exp_freq < 10.f / 3.f) pckt_cnt_max = 10; - else pckt_cnt_max = uint(round(3.f * exp_freq)); + changeDisconnectTimeout(); +} + + +void PIProtocol::changeDisconnectTimeout() { + pckt_cnt_max = int(round(timeout_ * exp_freq)); + if (pckt_cnt_max < 3) pckt_cnt_max = 3; last_packets.resize(pckt_cnt_max); } @@ -210,6 +261,7 @@ void PIProtocol::startReceive(float exp_frequency) { setExpectedFrequency(exp_freq); diagTimer->start(1000. / exp_freq); diagTimer->reset(); + raiseEvent(this, "receiver started"); } @@ -217,6 +269,7 @@ void PIProtocol::startSend(float frequency) { if (frequency > 0.f) send_freq = frequency; if (send_freq <= 0.f) return; sendTimer->start(1000. / send_freq); + raiseEvent(this, "sender started"); } @@ -224,6 +277,7 @@ void PIProtocol::stopReceive() { if (type_rec == PIProtocol::Serial) ser->stop(); if (type_rec == PIProtocol::Ethernet) eth->stop(); diagTimer->stop(); + raiseEvent(this, "receiver stopped"); } @@ -232,8 +286,8 @@ bool PIProtocol::receiveEvent(void * t, char * data, int size) { if (!p->receive(data, size)) return false; p->work = true; //p->lock(); - if (p->validate()) - { + if (p->validate()) { + raiseEvent(p, "received", true); //p->unlock(); p->receive_count++; p->cur_pckt = 1; @@ -241,6 +295,7 @@ bool PIProtocol::receiveEvent(void * t, char * data, int size) { if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, true, data, size); return true; } + raiseEvent(p, "received", false); //p->unlock(); p->wrong_count++; if (p->mp_owner != 0) PIMultiProtocolBase::receiveEvent(p->mp_owner, p, false, data, size); @@ -278,39 +333,54 @@ void PIProtocol::calc_diag() { else if (good_percents <= 20.f) diag = PIProtocol::Bad; else if (good_percents > 20.f && good_percents <= 80.f) diag = PIProtocol::Average; else diag = PIProtocol::Good; - if (diag != net_diag) net_diag = diag; + if (diag != net_diag) { + net_diag = diag; + raiseEvent(this, "quality changed", diag); + } } void PIProtocol::calc_freq() { - tf = float(1000.f / diagTimer->elapsed_m()); + float tf = float(1000.f / diagTimer->elapsed_m()); diagTimer->reset(); if (cur_pckt != 1) tf = 0.f; - immediateFreq = tf; - if (last_freq.size() >= pckt_cnt_max) last_freq.pop_front(); + immediate_freq = tf; + if (last_freq.size_s() >= pckt_cnt_max && last_freq.size_s() > 0) last_freq.pop_front(); last_freq.push_back(tf); tf = last_freq[0]; for (uint i = 1; i < last_freq.size(); ++i) tf += last_freq[i]; - integralFreq = tf / last_freq.size(); + integral_freq = tf / last_freq.size(); } void PIProtocol::check_state() { if (type_rec == PIProtocol::Serial) { - if (ser->initialized()) devReceiverState = "Initialized"; + if (ser != 0) { + if (ser->initialized()) devReceiverState = "Initialized"; + else devReceiverState = "Uninitialized"; + } else devReceiverState = "Uninitialized"; } if (type_rec == PIProtocol::Ethernet) { - if (eth->receiverInitialized()) devReceiverState = "Initialized"; + if (eth != 0) { + if (eth->receiverInitialized()) devReceiverState = "Initialized"; + else devReceiverState = "Uninitialized"; + } else devReceiverState = "Uninitialized"; } if (type_send == PIProtocol::Serial) { - if (ser->initialized()) devSenderState = "Initialized"; + if (ser != 0) { + if (ser->initialized()) devSenderState = "Initialized"; + else devSenderState = "Uninitialized"; + } else devSenderState = "Uninitialized"; } if (type_send == PIProtocol::Ethernet) { - if (eth->senderInitialized()) devSenderState = "Initialized"; + if (eth != 0) { + if (eth->senderInitialized()) devSenderState = "Initialized"; + else devSenderState = "Uninitialized"; + } else devSenderState = "Uninitialized"; } } diff --git a/piprotocol.h b/piprotocol.h index a528a71a..585113b6 100644 --- a/piprotocol.h +++ b/piprotocol.h @@ -6,6 +6,7 @@ #include "pitimer.h" #include "piconfig.h" #include "math.h" +#include "piobject.h" class PIProtocol; @@ -15,60 +16,68 @@ class PIMultiProtocolBase public: PIMultiProtocolBase() {;} ~PIMultiProtocolBase() {;} - + protected: virtual void received(PIProtocol * prot, bool corrected, char * data, int size) {;} - + private: static void receiveEvent(PIMultiProtocolBase * p, PIProtocol * prot, bool corrected, char * data, int size) {p->mutex_receive.lock(); p->received(prot, corrected, data, size); p->mutex_receive.unlock();} - + PIMutex mutex_receive; - + }; typedef void (*ReceiveFunc)(void * ); -class PIProtocol +class PIProtocol: public PIObject { friend class PIMultiProtocolBase; friend class PIMultiProtocol; enum Type {None, Serial, Ethernet}; - enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5}; - + public: - PIProtocol() {init();} + PIProtocol(): PIObject() {init();} PIProtocol(const PIString & config, const PIString & name, void * recHeaderPtr = 0, int recHeaderSize = 0, void * recDataPtr = 0, int recDataSize = 0, void * sendDataPtr = 0, int sendDataSize = 0); // from config ~PIProtocol(); - - void startReceive(float exp_frequency = -1.f); // if "frequency = -1" used last passed value - void stopReceive(); + + enum Quality {Unknown = 1, Failure = 2, Bad = 3, Average = 4, Good = 5}; + + EVENT_HANDLER0(PIProtocol, void, startReceive) {startReceive(-1.f);} + EVENT_HANDLER1(PIProtocol, void, startReceive, float, exp_frequency); // if "frequency = -1" used last passed value + EVENT_HANDLER0(PIProtocol, void, stopReceive); + float expectedFrequency() const {return exp_freq;} void setExpectedFrequency(float frequency); // for connection quality diagnostic void setReceiverDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial void setReceiverData(void * dataPtr, int dataSize) {this->dataPtr = (uchar * )dataPtr; this->dataSize = dataSize;} void setReceiverAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setReceiverParameters(PIFlags parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial void setReceiveSlot(ReceiveFunc slot) {ret_func = slot;} - - void startSend(float frequency = -1.f); // if "frequency = -1" used last passed value - void stopSend() {sendTimer->stop();} + + EVENT_HANDLER0(PIProtocol, void, startSend) {startSend(-1.f);} // if "frequency = -1" used last passed value + EVENT_HANDLER1(PIProtocol, void, startSend, float, frequency); // if "frequency = -1" used last passed value + EVENT_HANDLER0(PIProtocol, void, stopSend) {sendTimer->stop(); raiseEvent(this, "sender stopped");} + float senderFrequency() const {return send_freq;} void setSenderFrequency(float frequency) {send_freq = frequency;} void setSenderDevice(const PIString & device, PISerial::Speed speed, bool force = false); // for Serial void setSenderData(void * dataPtr, int dataSize) {sendDataPtr = (uchar * )dataPtr; sendDataSize = dataSize;} void setSenderAddress(const PIString & ip, int port, bool force = false); // for Ethernet void setSenderParameters(PIFlags parameters) {if (type_send == PIProtocol::Serial) ser->setParameters(parameters);} // for Serial - - void start() {startReceive(); startSend();} - void stop() {stopReceive(); stopSend();} - void send(); - void send(const void * data, int size); - void setName(const PIString & name) {protName = name;} + EVENT_HANDLER0(PIProtocol, void, start) {startReceive(); startSend();} + EVENT_HANDLER0(PIProtocol, void, stop) {stopReceive(); stopSend();} + EVENT_HANDLER0(PIProtocol, void, send); + EVENT_HANDLER2(PIProtocol, void, send, const void *, data, int, size); + + void setName(const PIString & name) {protName = name; PIObject::setName(name);} PIString name() const {return protName;} - float immediateFrequency() const {return immediateFreq;} - float integralFrequency() const {return integralFreq;} - float * immediateFrequency_ptr() {return &immediateFreq;} - float * integralFrequency_ptr() {return &integralFreq;} + void setDisconnectTimeout(float timeout) {timeout_ = timeout; changeDisconnectTimeout();} + float disconnectTimeout() const {return timeout_;} + float * disconnectTimeout_ptr() {return &timeout_;} + float immediateFrequency() const {return immediate_freq;} + float integralFrequency() const {return integral_freq;} + float * immediateFrequency_ptr() {return &immediate_freq;} + float * integralFrequency_ptr() {return &integral_freq;} ullong receiveCount() const {return receive_count;} ullong * receiveCount_ptr() {return &receive_count;} ullong wrongCount() const {return wrong_count;} @@ -78,17 +87,20 @@ public: PIProtocol::Quality quality() const {return net_diag;} // receive quality int * quality_ptr() {return (int * )&net_diag;} // receive quality pointer PIString receiverDeviceName() const {return devReceiverName;} - PIString senderDeviceName() const {cout << devSenderName << endl; return devSenderName;} + PIString senderDeviceName() const {return devSenderName;} PIString receiverDeviceState() const {return devReceiverState;} PIString * receiverDeviceState_ptr() {return &devReceiverState;} PIString senderDeviceState() const {return devSenderState;} PIString * senderDeviceState_ptr() {return &devSenderState;} - + void * receiveData() {return dataPtr;} void * sendData() {return sendDataPtr;} + PIByteArray lastHeader() {if (ser != 0) return ser->lastHeader(); return PIByteArray();} + PIByteArray internalBuffer() {if (ser != 0) return ser->internalBuffer(); return PIByteArray();} + protected: - virtual bool receive(char * data, int size) {memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return + virtual bool receive(char * data, int size) {if (dataPtr != 0) memcpy(dataPtr, data, size); return true;} // executed when raw data received, break if 'false' return virtual bool validate() {return true;} // function for validate algorithm and save data from dataPtr to external struct virtual uint checksum_i(void * data, int size) { // function for checksum (uint) uint c = 0; @@ -120,10 +132,11 @@ private: static void sendEvent(void * e, int) {((PIProtocol * )e)->send();} static bool receiveEvent(void * t, char * data, int size); static void diagEvent(void * t, int); - + void setMultiProtocolOwner(PIMultiProtocolBase * mp) {mp_owner = mp;} PIMultiProtocolBase * multiProtocolOwner() const {return mp_owner;} - + void changeDisconnectTimeout(); + ReceiveFunc ret_func; PITimer * diagTimer, * sendTimer; PIMultiProtocolBase * mp_owner; @@ -133,12 +146,11 @@ private: PIDeque last_packets; PIString protName, devReceiverName, devReceiverState, devSenderName, devSenderState; bool work, new_mp_prot; - float exp_freq, send_freq, immediateFreq, integralFreq, tf; - int packets[2]; - uint pckt_cnt, pckt_cnt_max; + float exp_freq, send_freq, immediate_freq, integral_freq, timeout_; + int packets[2], pckt_cnt, pckt_cnt_max; char * packet, cur_pckt; ullong wrong_count, receive_count, send_count; - + }; #endif // PIPROTOCOL_H diff --git a/piserial.cpp b/piserial.cpp index e7370f92..33733c96 100644 --- a/piserial.cpp +++ b/piserial.cpp @@ -2,6 +2,7 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { + piMonitor.serials++; setPriority(piHigh); data = data_; devName = name; @@ -10,6 +11,8 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { headerPtr = 0; hbuffer = pbuffer = 0; ret_func = slot; + memset(buffer, 0, BUFFER_SIZE); + memset(sbuffer, 0, BUFFER_SIZE); #ifdef WINDOWS hCom = 0; #endif @@ -18,6 +21,7 @@ PISerial::PISerial(PIString name, void * data_, SerialFunc slot): PIThread() { PISerial::~PISerial() { + piMonitor.serials--; terminate(); } @@ -132,6 +136,8 @@ void PISerial::run() { } if (j == headerSize) { first = true; + mheader.resize(headerSize); + memcpy(mheader.data(),headerPtr,headerSize); //cout << "yes" << endl; } } diff --git a/piserial.h b/piserial.h index 6497db24..1ff36fac 100644 --- a/piserial.h +++ b/piserial.h @@ -4,23 +4,23 @@ #include "pithread.h" #include "pistring.h" #ifndef WINDOWS -#include -#include +# include +# include #else -#define B110 110 -#define B300 300 -#define B600 600 -#define B1200 1200 -#define B2400 2400 -#define B4800 4800 -#define B9600 9600 -#define B14400 14400 -#define B19200 19200 -#define B38400 38400 -#define B57600 57600 -#define B115200 115200 -#define B128000 128000 -#define B256000 256000 +# define B110 110 +# define B300 300 +# define B600 600 +# define B1200 1200 +# define B2400 2400 +# define B4800 4800 +# define B9600 9600 +# define B14400 14400 +# define B19200 19200 +# define B38400 38400 +# define B57600 57600 +# define B115200 115200 +# define B128000 128000 +# define B256000 256000 #endif #define BUFFER_SIZE 4096 @@ -64,6 +64,9 @@ public: bool init(); bool initialized() const {return fd != -1;} void terminate(); + + PIByteArray lastHeader() {return mheader;} + PIByteArray internalBuffer() {return PIByteArray(sbuffer, BUFFER_SIZE);} private: int convertSpeed(PISerial::Speed speed); @@ -85,6 +88,7 @@ private: PIString devName; SerialFunc ret_func; char buffer[BUFFER_SIZE], sbuffer[BUFFER_SIZE], * hbuffer, * pbuffer; + PIByteArray mheader; void * headerPtr, * data; int dataSize, headerSize, sbuffIndex, startIndex, backIndex; PIFlags params; diff --git a/pistring.cpp b/pistring.cpp index 1795e06a..5a724e83 100644 --- a/pistring.cpp +++ b/pistring.cpp @@ -203,6 +203,10 @@ PIString & PIString::replace(int from, int count, const PIString & with) { PIString & PIString::replace(const PIString & what, const PIString & with, bool * ok) { + if (what.isEmpty()) { + if (ok != 0) *ok = false; + return *this; + } int s = find(what); if (s >= 0) replace(s, what.length(), with); if (ok != 0) *ok = (s >= 0); diff --git a/pistring.h b/pistring.h index e6446c6d..00dc8e75 100644 --- a/pistring.h +++ b/pistring.h @@ -9,7 +9,7 @@ class PIStringList; class PIString: public PIVector { public: - PIString() {;} + PIString() {piMonitor.strings++; piMonitor.containers--;} //inline PIString & operator +=(const char c) {push_back(c); return *this;} PIString & operator +=(const PIChar c) {push_back(c); return *this;} @@ -21,16 +21,17 @@ public: PIString & operator +=(const wstring & str); //PIString(const char c) {*this += c;} - PIString(const PIChar c) {*this += c;} - PIString(const char * str) {*this += str;} - PIString(const wchar_t * str) {*this += str;} - PIString(const string & str) {*this += str;} - PIString(const wstring & str) {*this += str;} - PIString(const PIByteArray & ba) {*this += ba;} - PIString(const char * str, const int len) {*this += string(str, len);} - PIString(const int len, const char c) {for (int i = 0; i < len; ++i) push_back(c);} - PIString(const int len, const PIChar & c) {for (int i = 0; i < len; ++i) push_back(c);} - PIString(const PIString & str) {*this += str;} + PIString(const PIChar c) {piMonitor.strings++; piMonitor.containers--;*this += c;} + PIString(const char * str) {piMonitor.strings++; piMonitor.containers--;*this += str;} + PIString(const wchar_t * str) {piMonitor.strings++; piMonitor.containers--;*this += str;} + PIString(const string & str) {piMonitor.strings++; piMonitor.containers--;*this += str;} + PIString(const wstring & str) {piMonitor.strings++; piMonitor.containers--;*this += str;} + PIString(const PIByteArray & ba) {piMonitor.strings++; piMonitor.containers--;*this += ba;} + PIString(const char * str, const int len) {piMonitor.strings++; piMonitor.containers--;*this += string(str, len);} + PIString(const int len, const char c) {piMonitor.strings++; piMonitor.containers--;for (int i = 0; i < len; ++i) push_back(c);} + PIString(const int len, const PIChar & c) {piMonitor.strings++; piMonitor.containers--;for (int i = 0; i < len; ++i) push_back(c);} + PIString(const PIString & str) {piMonitor.strings++; piMonitor.containers--;*this += str;} + ~PIString() {piMonitor.strings--; piMonitor.containers++;} operator const char*() {return data();} operator const string() {if (size() == 0) return string(); string s; for (int i = 0; i < length(); ++i) s.push_back(at(i).toAscii()); return s;} diff --git a/pisystemmonitor.cpp b/pisystemmonitor.cpp new file mode 100644 index 00000000..1fa5ce14 --- /dev/null +++ b/pisystemmonitor.cpp @@ -0,0 +1,105 @@ +#include "pisystemmonitor.h" + + +PISystemMonitor::PISystemMonitor(): PIThread() { + pID_ = cycle = 0; + cpu_count = 1; +#ifndef WINDOWS +# ifdef QNX + page_size = 4096; +# else + page_size = getpagesize(); +# endif + cpu_count = sysconf(_SC_NPROCESSORS_ONLN); + if (cpu_count < 1) cpu_count = 1; +#endif +} + + +bool PISystemMonitor::startOnProcess(int pID) { + stop(); + pID_ = pID; +#ifndef WINDOWS + file.open("/proc/" + PIString::fromNumber(pID_) + "/stat", PIFile::Read); + filem.open("/proc/" + PIString::fromNumber(pID_) + "/statm", PIFile::Read); + if (!file.isOpened()) { + cout << "[PISystemMonitor] Can`t find process with ID = " << pID_ << "!" << endl; + return false; + } + cycle = -1; +#endif + return start(25); +} + + +void PISystemMonitor::run() { +#ifndef WINDOWS + PIString str(file.readAll(true)); + int si = str.find('(') + 1, fi = 0, cc = 1; + for (int i = si; i < str.size_s(); ++i) { + if (str[i] == '(') cc++; + if (str[i] == ')') cc--; + if (cc <= 0) { + fi = i; + break; + } + } + stat.exec_name = str.mid(si, fi - si); + str.cutMid(si - 1, fi - si + 3); + PIStringList sl = str.split(" "); + if (sl.size_s() < 18) return; + stat.ID = sl[0].toInt(); + stat.state = sl[1]; + stat.parent_ID = sl[2].toInt(); + stat.group_ID = sl[3].toInt(); + stat.session_ID = sl[4].toInt(); + if (cycle < 0) { + cpu_u_prev = cpu_u_cur = sl[12].toLLong(); + cpu_s_prev = cpu_s_cur = sl[13].toLLong(); + } + cycle++; + if (cycle >= 40) { + cpu_u_prev = cpu_u_cur; + cpu_s_prev = cpu_s_cur; + cpu_u_cur = sl[12].toLLong(); + cpu_s_cur = sl[13].toLLong(); + stat.cpu_load_system = cpu_s_cur - cpu_s_prev; + stat.cpu_load_user = cpu_u_cur - cpu_u_prev; + if (stat.cpu_load_system > 100) stat.cpu_load_system = 100; + if (stat.cpu_load_user > 100) stat.cpu_load_user = 100; + stat.cpu_load_system /= cpu_count; + stat.cpu_load_user /= cpu_count; + cycle = 0; + } + stat.priority = sl[16].toInt(); + stat.threads = sl[18].toInt(); + + str = filem.readAll(true); + sl = str.split(" "); + if (sl.size_s() < 5) return; + stat.virtual_memsize = sl[0].toLong() * page_size; + stat.resident_memsize = sl[1].toLong() * page_size; + stat.share_memsize = sl[2].toLong() * page_size; + stat.data_memsize = sl[5].toLong() * page_size; + stat.physical_memsize = stat.resident_memsize - stat.share_memsize; + + stat.physical_memsize_readable = readableSize(stat.physical_memsize); + stat.resident_memsize_readable = readableSize(stat.resident_memsize); + stat.share_memsize_readable = readableSize(stat.share_memsize); + stat.virtual_memsize_readable = readableSize(stat.virtual_memsize); + stat.data_memsize_readable = readableSize(stat.data_memsize); +#endif +} + + +PIString PISystemMonitor::readableSize(long bytes) { + if (bytes < 999) return PIString::fromNumber(bytes) + " B"; + long res = bytes / 1024; + if (res < 999) return PIString::fromNumber(res) + " kB"; + res = res / 1024; + if (res < 999) return PIString::fromNumber(res) + " MB"; + res = res / 1024; + if (res < 999) return PIString::fromNumber(res) + " GB"; + res = res / 1024; + return PIString::fromNumber(res) + " PB"; +} diff --git a/pisystemmonitor.h b/pisystemmonitor.h new file mode 100644 index 00000000..2d9458d3 --- /dev/null +++ b/pisystemmonitor.h @@ -0,0 +1,52 @@ +#ifndef PISYSTEMMONITOR_H +#define PISYSTEMMONITOR_H + +#include "pithread.h" +#include "piprocess.h" + +class PISystemMonitor: public PIThread +{ +public: + PISystemMonitor(); + + struct ProcessStats { + PIString exec_name; + PIString state; + int ID; + int parent_ID; + int group_ID; + int session_ID; + int priority; + int threads; + ulong physical_memsize; + ulong resident_memsize; + ulong share_memsize; + ulong virtual_memsize; + ulong data_memsize; + PIString physical_memsize_readable; + PIString resident_memsize_readable; + PIString share_memsize_readable; + PIString virtual_memsize_readable; + PIString data_memsize_readable; + float cpu_load_system; + float cpu_load_user; + }; + + bool startOnProcess(int pID); + bool startOnSelf() {return startOnProcess(PIProcess::currentPID());} + ProcessStats & statistic() {return stat;} + +private: + void run(); + PIString readableSize(long bytes); + + PIFile file, filem; + ProcessStats stat; + int pID_, page_size, cpu_count, cycle; +#ifndef WINDOWS + llong cpu_u_cur, cpu_u_prev, cpu_s_cur, cpu_s_prev; +#endif + +}; + +#endif // PISYSTEMMONITOR_H diff --git a/pithread.cpp b/pithread.cpp index fe3e61e1..921ea796 100644 --- a/pithread.cpp +++ b/pithread.cpp @@ -1,10 +1,17 @@ #include "pithread.h" -PIThread::PIThread(bool startNow, int timer_delay) { +PIThread::PIThread(bool startNow, int timer_delay): PIObject() { + piMonitor.threads++; running = lockRun = false; priority_ = piNormal; timer = timer_delay; + /*addEvent("started"); + addEvent("stopped"); + addEventHandler(HANDLER(PIThread, start)); + addEventHandler(HANDLER(PIThread, startOnce)); + addEventHandler(HANDLER(PIThread, stop)); + addEventHandler(HANDLER(PIThread, terminate));*/ if (startNow) start(timer_delay); } @@ -13,6 +20,7 @@ PIThread::PIThread(bool startNow, int timer_delay) { #endif PIThread::~PIThread() { + piMonitor.threads--; if (!running) return; #ifndef WINDOWS pthread_cancel(thread); @@ -79,12 +87,14 @@ void * PIThread::thread_function(void * t) { PIThread * ct = (PIThread * )t; ct->running = true; ct->begin(); + raiseEvent(ct, "started"); while (!ct->terminating) { if (ct->lockRun) ct->mutex_.lock(); ct->run(); if (ct->lockRun) ct->mutex_.unlock(); if (ct->timer > 0) msleep(ct->timer); } + raiseEvent(ct, "stopped"); ct->end(); ct->running = false; //cout << "thread " << t << " exiting ... " << endl; @@ -101,9 +111,11 @@ void * PIThread::thread_function_once(void * t) { PIThread * ct = (PIThread * )t; ct->running = true; ct->begin(); + raiseEvent(ct, "started"); if (ct->lockRun) ct->mutex_.lock(); ct->run(); if (ct->lockRun) ct->mutex_.unlock(); + raiseEvent(ct, "stopped"); ct->end(); ct->running = false; //cout << "thread " << t << " exiting ... " << endl; diff --git a/pithread.h b/pithread.h index 91b02cbc..4bad446f 100644 --- a/pithread.h +++ b/pithread.h @@ -3,6 +3,7 @@ #include #include "pimutex.h" +#include "piobject.h" #ifdef WINDOWS inline void msleep(int msecs) {Sleep(msecs);} @@ -10,7 +11,7 @@ inline void msleep(int msecs) {Sleep(msecs);} inline void msleep(int msecs) {usleep(msecs * 1000);} #endif -class PIThread { +class PIThread: public PIObject { public: PIThread(bool startNow = false, int timer_delay = -1); ~PIThread(); @@ -29,18 +30,24 @@ public: piLowerst = 2 }; #endif - bool start(int timer_delay = -1); - bool startOnce(); - void stop(bool wait = false) {terminating = true; if (wait) waitForFinish();} - void terminate(bool hard = false); + //bool start(int timer_delay = -1); + EVENT_HANDLER0(PIThread, bool, start) {return start(-1);} + EVENT_HANDLER1(PIThread, bool, start, int, timer_delay); + EVENT_HANDLER0(PIThread, bool, startOnce); + EVENT_HANDLER0(PIThread, void, stop) {stop(false);} + EVENT_HANDLER1(PIThread, void, stop, bool, wait) {terminating = true; if (wait) waitForFinish();} + EVENT_HANDLER0(PIThread, void, terminate) {terminate(false);} + EVENT_HANDLER1(PIThread, void, terminate, bool, hard); void setPriority(PIThread::Priority prior); PIThread::Priority priority() const {return priority_;} bool isRunning() const {return running;} - bool waitForFinish(int timeout_msecs = -1); - bool waitForStart(int timeout_msecs = -1); + EVENT_HANDLER0(PIThread, bool, waitForFinish) {return waitForFinish(-1);} + EVENT_HANDLER1(PIThread, bool, waitForFinish, int, timeout_msecs); + EVENT_HANDLER0(PIThread, bool, waitForStart) {return waitForStart(-1);} + EVENT_HANDLER1(PIThread, bool, waitForStart, int, timeout_msecs); void needLockRun(bool need) {lockRun = need;} - void lock() {mutex_.lock();} - void unlock() {mutex_.unlock();} + EVENT_HANDLER0(PIThread, void, lock) {mutex_.lock();} + EVENT_HANDLER0(PIThread, void, unlock) {mutex_.unlock();} PIMutex & mutex() {return mutex_;} private: diff --git a/pitimer.cpp b/pitimer.cpp index 306f5c17..bd9567dc 100644 --- a/pitimer.cpp +++ b/pitimer.cpp @@ -1,10 +1,16 @@ #include "pitimer.h" -PITimer::PITimer(TimerEvent slot, void * data_) { +PITimer::PITimer(TimerEvent slot, void * data_) +#ifdef WINDOWS +: PIThread() { +#else +: PIObject() { +#endif ret_func = slot; data = data_; #ifndef WINDOWS + piMonitor.timers++; ti = -1; running = false; se.sigev_notify = SIGEV_THREAD; @@ -14,11 +20,24 @@ PITimer::PITimer(TimerEvent slot, void * data_) { lockRun = false; #endif reset(); + /*addEvent("timeout"); + addEventHandler(HANDLER(PITimer, start)); + addEventHandler(HANDLER(PITimer, stop)); + addEventHandler(HANDLER(PITimer, reset));*/ +} + + +PITimer::~PITimer() { +#ifndef WINDOWS + piMonitor.timers--; +#endif + stop(); } #ifndef WINDOWS void PITimer::start(double msecs) { + if (ti == 0) return; spec.it_interval.tv_nsec = ((int)(msecs * 1000) % 1000000) * 1000; spec.it_interval.tv_sec = (time_t)(msecs / 1000); spec.it_value = spec.it_interval; @@ -30,31 +49,50 @@ void PITimer::start(double msecs) { void PITimer::timer_event(sigval e) { PITimer * ct = (PITimer * )e.sival_ptr; - if (ct->ret_func != 0) { - if (ct->lockRun) ct->lock(); - ct->ret_func(ct->data, 1); - piForeach (TimerSlot & i, ct->ret_funcs) { - if (i.delim > ++(i.tick)) continue; - i.tick = 0; - if (i.slot != 0) i.slot(ct->data, i.delim); - else ct->ret_func(ct->data, i.delim); - } - if (ct->lockRun) ct->unlock(); + if (!ct->running) return; + if (ct->lockRun) ct->lock(); + if (ct->ret_func != 0) ct->ret_func(ct->data, 1); + raiseEvent(ct, "timeout", ct->data, 1); + piForeach (TimerSlot & i, ct->ret_funcs) { + if (i.delim > ++(i.tick)) continue; + i.tick = 0; + if (i.slot != 0) i.slot(ct->data, i.delim); + else if (ct->ret_func != 0) ct->ret_func(ct->data, i.delim); + raiseEvent(ct, "timeout", ct->data, i.delim); } + if (ct->lockRun) ct->unlock(); } + + +bool PITimer::waitForFinish(int timeout_msecs) { + if (timeout_msecs < 0) { + while (running) + msleep(1); + return true; + } + int cnt = 0; + while (running && cnt < timeout_msecs) { + msleep(1); + ++cnt; + } + return cnt < timeout_msecs; +} + + #else void PITimer::run() { - if (ret_func != 0) { - if (lockRun) lock(); - ret_func(data, 1); - piForeach (TimerSlot & i, ret_funcs) { - if (i.delim > ++(i.tick)) continue; - i.tick = 0; - if (i.slot != 0) i.slot(data, i.delim); - else ret_func(data, i.delim); - } - if (lockRun) unlock(); + if (!running) return; + if (lockRun) lock(); + if (ret_func != 0) ret_func(data, 1); + raiseEvent(this, "timeout", data, 1); + piForeach (TimerSlot & i, ret_funcs) { + if (i.delim > ++(i.tick)) continue; + i.tick = 0; + if (i.slot != 0) i.slot(data, i.delim); + else if (ret_func != 0) ret_func(data, i.delim); + raiseEvent(this, "timeout", data, i.delim); } + if (lockRun) unlock(); } #endif diff --git a/pitimer.h b/pitimer.h index 4daa4c79..04dd6924 100644 --- a/pitimer.h +++ b/pitimer.h @@ -5,6 +5,7 @@ #include #include "pithread.h" #include "pistring.h" +#include "piobject.h" typedef void (*TimerEvent)(void * , int ); @@ -23,30 +24,34 @@ struct PIDate { class PITimer #ifdef WINDOWS : public PIThread +#else +: public PIObject #endif { public: PITimer(TimerEvent slot = 0, void * data = 0); - ~PITimer() {stop();} + ~PITimer(); void setData(void * data_) {data = data_;} void setSlot(TimerEvent slot) {ret_func = slot;} #ifdef WINDOWS void reset() {t_st = GetCurrentTime();} #else - void reset() {clock_gettime(0, &t_st);} - void start(double msecs); - void stop() {if (ti == 0) timer_delete(timer); ti = -1; running = false;} + EVENT_HANDLER0(PITimer, void, reset) {clock_gettime(0, &t_st);} + EVENT_HANDLER1(PITimer, void, start, double, msecs); + EVENT_HANDLER0(PITimer, void, stop) {if (ti == 0) timer_delete(timer); ti = -1; running = false;} + EVENT_HANDLER0(PITimer, bool, waitForFinish) {return waitForFinish(-1);} + EVENT_HANDLER1(PITimer, bool, waitForFinish, int, timeout_msecs); bool isRunning() const {return running;} void needLockRun(bool need) {lockRun = need;} - void lock() {mutex_.lock();} - void unlock() {mutex_.unlock();} + EVENT_HANDLER0(PITimer, void, lock) {mutex_.lock();} + EVENT_HANDLER0(PITimer, void, unlock) {mutex_.unlock();} #endif void addDelimiter(int delim, TimerEvent slot = 0) {ret_funcs << TimerSlot(slot, delim);} void removeDelimiter(int delim) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}} void removeDelimiter(TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot) {ret_funcs.remove(i); i--;}} void removeDelimiter(int delim, TimerEvent slot) {for (int i = 0; i < ret_funcs.size_s(); ++i) if (ret_funcs[i].slot == slot && ret_funcs[i].delim == delim) {ret_funcs.remove(i); i--;}} - void clearDelimiters() {ret_funcs.clear();} + EVENT_HANDLER0(PITimer, void, clearDelimiters) {ret_funcs.clear();} double elapsed_n(); // nanoseconds double elapsed_u(); // microseconds diff --git a/Описание.odt b/Описание.odt index 87361e48..41fa2ab3 100644 Binary files a/Описание.odt and b/Описание.odt differ diff --git a/Описание.pdf b/Описание.pdf index b9ecfc09..846efce8 100644 Binary files a/Описание.pdf and b/Описание.pdf differ