Files
pip/main.cpp
2012-02-08 19:39:21 +04:00

307 lines
10 KiB
C++

/*
PIP - Platform Independent Primitives
Test program
Copyright (C) 2011 Ivan Pelipenko peri4ko@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pip.h"
class ThreadTest: public PIThread {
public:
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";}
};
PIMutex mutex_;
bool m = false;
int cnt = 0, gm = 0;
class MutexTest: public PIThread {
public:
MutexTest(): PIThread() {;}
private:
void run() {mutex_.lock(); if (m && cnt > 1) gm++; m = true; cout << " " << flush; if (cnt++ >= 128) stop(); msleep(1); mutex_.unlock();}
};
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(1); mutex_.unlock();}
};
void signalFunc(PISignals::Signal signal) {
if (signal != PISignals::Interrupt) return;
cout << "Ctrl+C pressed, exiting ..." << endl;
exit(0);
};
bool t = false;
void timerEvent(void * data, int delim) {
t = true;
cout << " tick from constuctor, delimiter = " << delim << ", data = " << data << endl;
};
bool
t2 = false;
void timerEvent2(void * data, int delim) {
t2 = true;
cout << " tick from delimiter " << delim << ", data = " << data << 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<int, PIString>(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;
};
#pragma pack(push, 1)
struct Data {
ushort header;
int counter;
float f0;
float f1;
ushort checksum;
};
#pragma pack(pop)
class Prot: public PIProtocol {
public:
Prot() {
setReceiverDevice("/dev/ttyS0", PISerial::S115200, true);
setReceiverDataHeader(&rec, 2);
setReceiverData(&rec.counter, sizeof(rec) - 2);
setSenderData(&send, sizeof(send));
setExpectedFrequency(20.f);
setSenderFrequency(20.f);
send.header = 0xAABB;
rec.header = 0xAABB;
start();
}
virtual bool validate() {
if (rec.checksum != PIByteArray(&rec, sizeof(rec)-2).checksumCRC16()) return false;
return true;
}
virtual bool aboutSend() {
send.counter++;
send.checksum = PIByteArray(&send, sizeof(send)-2).checksumCRC16();
return true;
}
Data send, rec;
};
Prot p;
void key(char k, void*) {
switch (k) {
case '0': p.setSenderData(&p.send, sizeof(p.send)); break;
case '1': p.setSenderData(&p.send, sizeof(p.send) - 1); break;
case '2': p.send.header = 0xAABB; break;
case '3': p.send.header = 0xACBD; break;
}
}
PIConsole c(false, key);
int main(int argc, char * argv[]) {
c.enableExitCapture();
c.addVariable("prot", &p);
if (argc > 1) c.start();
c.waitForFinish();
c.stop();
exit(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);
timer.start(100.f);
msleep(1005);
timer.stop();
r_timer = t && t2;
if (r_timer) cout << "== Success ==" << endl;
else cout << "== Fail ==" << 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;
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;
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;
};