source tree changed detached PIConsole and PIScreen* in "pip_console" library
267 lines
7.2 KiB
C++
267 lines
7.2 KiB
C++
/*
|
|
PIP - Platform Independent Primitives
|
|
Global includes
|
|
Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "piincludes.h"
|
|
#include "piincludes_p.h"
|
|
#include "piconsole.h"
|
|
#include "pitime.h"
|
|
#ifndef QNX
|
|
# include <clocale>
|
|
#else
|
|
# include <locale.h>
|
|
#endif
|
|
#ifdef MAC_OS
|
|
//# include <mach/mach_traps.h>
|
|
//# include <mach/mach.h>
|
|
# include <mach/clock.h>
|
|
//# include <crt_externs.h>
|
|
#endif
|
|
#include <errno.h>
|
|
|
|
bool piDebug = true;
|
|
double piMountInfoRefreshIntervalMs = 10000.;
|
|
|
|
lconv * currentLocale =
|
|
#ifdef ANDROID
|
|
0;
|
|
#else
|
|
std::localeconv();
|
|
#endif
|
|
|
|
#ifdef MAC_OS
|
|
clock_serv_t __pi_mac_clock;
|
|
#endif
|
|
|
|
#ifdef WINDOWS
|
|
FILETIME __pi_ftjan1970;
|
|
long long __pi_perf_freq = -1;
|
|
PINtQueryTimerResolution getTimerResolutionAddr = 0;
|
|
PINtSetTimerResolution setTimerResolutionAddr = 0;
|
|
#endif
|
|
|
|
void errorClear() {
|
|
#ifdef WINDOWS
|
|
SetLastError(0);
|
|
#else
|
|
errno = 0;
|
|
#endif
|
|
}
|
|
|
|
PIString errorString() {
|
|
#ifdef WINDOWS
|
|
char * msg;
|
|
int err = GetLastError();
|
|
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 0, NULL);
|
|
return "code " + PIString::fromNumber(err) + " - " + PIString(msg);
|
|
#else
|
|
int e = errno;
|
|
return PIString("code ") + PIString::fromNumber(e) + " - " + PIString(strerror(e));
|
|
#endif
|
|
}
|
|
|
|
PIString PIPVersion() {
|
|
static PIString ret = PIStringAscii(PIP_VERSION_NAME);
|
|
return ret;
|
|
}
|
|
|
|
/*! \class PICout
|
|
* \brief Class for formatted output similar std::cout
|
|
*
|
|
* \section PICout_sec0 Synopsis
|
|
* This class provide many stream operators for output with some features.
|
|
* Output to PICout is thread-sequential, i.e. doesn`t mixed from parallel
|
|
* threads.
|
|
*
|
|
* \section PICout_sec1 Features
|
|
* - insertion spaces between entries
|
|
* - insertion new line at the end of output
|
|
* - strings are quoted
|
|
* - custom output operator can be easily written
|
|
*
|
|
* \section PICout_ex0 Usage
|
|
* \snippet picout.cpp 0
|
|
*
|
|
* \section PICout_ex1 Writing your own output operator
|
|
* \snippet picout.cpp own
|
|
*/
|
|
|
|
|
|
/*! \mainpage What is PIP
|
|
* PIP - Platform-Independent Primitives - is crossplatform library for C++ developers.
|
|
* It is wrap around STL and pure C++. This library can help developers write non-GUI
|
|
* projects much more quickly, efficiently and customizable than on pure C++.
|
|
* Library contains many classes, some of them are pure abstract, some classes
|
|
* can be used as they are, some classes should be inherited to new classes.
|
|
* PIP provide classes:
|
|
* * direct output to console (\a PICout)
|
|
* * containers (\a PIVector, \a PIList, \a PIMap, \a PIStack)
|
|
* * byte array (\a PIByteArray)
|
|
* * string (\a PIString, \a PIStringList)
|
|
* * base object (events and handlers) (\a PIObject)
|
|
* * multithreading
|
|
* * thread (\a PIThread)
|
|
* * executor (\a PIThreadPoolExecutor)
|
|
* * blocking dequeue (\a PIBlockingDequeue)
|
|
* * timer (\a PITimer)
|
|
* * console (information output) (\a PIConsole)
|
|
* * stand-alone
|
|
* * server
|
|
* * client
|
|
* * I/O devices
|
|
* * base class (\a PIIODevice)
|
|
* * file (\a PIFile)
|
|
* * serial port (\a PISerial)
|
|
* * ethernet (\a PIEthernet)
|
|
* * USB (\a PIUSB)
|
|
* * packets extractor (\a PIPacketExtractor)
|
|
* * binary log (\a PIBinaryLog)
|
|
* * complex I/O point (\a PIConnection)
|
|
* * connection quality diagnotic (\a PIDiagnostics)
|
|
* * command-line arguments parser (\a PICLI)
|
|
* * math evaluator (\a PIEvaluator)
|
|
* * peering net node (\a PIPeer)
|
|
* * process (\a PIProcess)
|
|
* * state machine (\a PIStateMachine)
|
|
* \n \n Basic using of PIP described at page \ref using_basic */
|
|
|
|
|
|
/*! \page using_basic Getting started
|
|
* Many novice programmers are solved many common task with system integrity: output to console,
|
|
* keyboard buttons press detecting, working with serial ports, ethernet or files, and many other.
|
|
* These tasks can solve this library, and code, based only on PIP will be compile and work
|
|
* similar on many systems: Windows, any Linux, Red Hat, FreeBSD, MacOS X and QNX.
|
|
* Typical application on PIP looks like this: \n
|
|
\code{.cpp}
|
|
#include <pip.h>
|
|
|
|
|
|
// declare key press handler
|
|
void key_event(char key, void * );
|
|
|
|
|
|
PIConsole console(false, key_event); // don`t start now, key handler is "key_event"
|
|
|
|
|
|
// some vars
|
|
int i = 2, j = 3;
|
|
|
|
|
|
// implicit key press handler
|
|
void key_event(char key, void * ) {
|
|
switch (key) {
|
|
case '-':
|
|
i--;
|
|
break;
|
|
case '+':
|
|
i++;
|
|
break;
|
|
case '(':
|
|
j--;
|
|
break;
|
|
case ')':
|
|
j++;
|
|
break;
|
|
};
|
|
};
|
|
|
|
|
|
class MainClass: public PITimer {
|
|
PIOBJECT(MainClass)
|
|
public:
|
|
MainClass() {}
|
|
protected:
|
|
void tick(void * data, int delimiter) {
|
|
piCout << "timer tick";
|
|
// timer tick
|
|
}
|
|
};
|
|
|
|
|
|
MainClass main_class;
|
|
|
|
|
|
int main(int argc, char * argv[]) {
|
|
// enabling auto-detection of exit button press, by default 'Q' (shift+q)
|
|
console.enableExitCapture();
|
|
|
|
// if we want to parse command-line arguments
|
|
PICLI cli(argc, argv);
|
|
cli.addArgument("console"); // "-c" or "--console"
|
|
cli.addArgument("debug"); // "-d" or "--debug"
|
|
|
|
// enabling or disabling global debug flag
|
|
piDebug = cli.hasArgument("debug");
|
|
|
|
// configure console
|
|
console.addTab("first tab", '1');
|
|
console.addString("PIP console", 1, PIConsole::Bold);
|
|
console.addVariable("int var (i)", &i, 1);
|
|
console.addVariable("int green var (j)", &j, 1, PIConsole::Green);
|
|
console.addString("'-' - i--", 2);
|
|
console.addString("'+' - i++", 2);
|
|
console.addString("'(' - j--", 2);
|
|
console.addString("')' - j++", 2);
|
|
console.addTab("second tab", '2');
|
|
console.addString("col 1", 1);
|
|
console.addString("col 2", 2);
|
|
console.addString("col 3", 3);
|
|
console.setTab("first tab");
|
|
|
|
// start output to console if "console" argument exists
|
|
if (cli.hasArgument("console"))
|
|
console.start();
|
|
|
|
// start main class, e.g. 40 Hz
|
|
main_class.start(25.);
|
|
|
|
// wait for 'Q' press, independently if console is started or not
|
|
console.waitForFinish();
|
|
|
|
return 0;
|
|
};
|
|
\endcode
|
|
* This code demonstrates simple interactive configurable program, which can be started with console
|
|
* display or not, and with debug or not. \b MainClass is central class that also can be inherited from
|
|
* \a PIThread and reimplement \a run() function.
|
|
* \n Many PIP classes has events and event handlers, which can be connected one to another.
|
|
* Details you can see at \a PIObject reference page (\ref PIObject_sec0).
|
|
* \n To configure your program from file use \a PIConfig.
|
|
* \n If you want more information see \ref using_advanced */
|
|
|
|
|
|
/*! \page using_advanced Advanced using
|
|
* Sorry, creativity crysis xD
|
|
*/
|
|
|
|
|
|
void piqsort(void * base, size_t num, size_t size, int (*compar)(const void *, const void *)) {
|
|
qsort(base, num, size, compar);
|
|
}
|
|
|
|
|
|
void randomize() {
|
|
srand(PISystemTime::current(true).nanoseconds);
|
|
}
|
|
|
|
|
|
int randomi() {
|
|
return rand();
|
|
}
|
|
|