331 lines
11 KiB
C++
331 lines
11 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 "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 = nullptr;
|
||
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);
|
||
PIString ret = PIStringAscii("code ") + PIString::fromNumber(err) + PIStringAscii(" - ");
|
||
if (msg) {
|
||
ret += PIString::fromSystem(msg).trim();
|
||
LocalFree(msg);
|
||
} else
|
||
ret += '?';
|
||
return ret;
|
||
#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;
|
||
}
|
||
|
||
|
||
void randomize() {
|
||
srand(PISystemTime::current(true).nanoseconds);
|
||
}
|
||
|
||
|
||
int randomi() {
|
||
return rand();
|
||
}
|
||
|
||
|
||
/*! \~english \mainpage What is PIP
|
||
* \~russian \mainpage Что такое PIP
|
||
*
|
||
* \~english
|
||
* 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)
|
||
* * tiling console (with widgets) (\a PIScreen)
|
||
* * simple text rows
|
||
* * scroll bar
|
||
* * list
|
||
* * button
|
||
* * buttons group
|
||
* * check box
|
||
* * progress bar
|
||
* * PICout output
|
||
* * text input
|
||
* * 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)
|
||
* * Run-time libraries
|
||
* * abstract (\a PILibrary)
|
||
* * plugin (\a PIPluginLoader)
|
||
* * 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
|
||
*
|
||
* \~russian
|
||
* PIP - Platform-Independent Primitives - кроссплатформенная библиотека для разработчиков на C++.
|
||
* 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++.
|
||
* PIP предоставляет следующие классы:
|
||
* * общение с консолью (\a PICout)
|
||
* * контейнеры (\a PIVector, \a PIList, \a PIMap, \a PIStack)
|
||
* * байтовый массив (\a PIByteArray)
|
||
* * строка (\a PIString, \a PIStringList)
|
||
* * базовый объект (события и обработчики) (\a PIObject)
|
||
* * многопоточность
|
||
* * поток (\a PIThread)
|
||
* * исполнитель (\a PIThreadPoolExecutor)
|
||
* * блокирующая очередь (\a PIBlockingDequeue)
|
||
* * таймер (\a PITimer)
|
||
* * тайлинговая консоль (с виджетами) (\a PIScreen)
|
||
* * простой вывод строк
|
||
* * скроллбар
|
||
* * лист
|
||
* * кнопка
|
||
* * группа кнопок
|
||
* * галочка
|
||
* * прогрессбар
|
||
* * вывод PICout
|
||
* * текстовый ввод
|
||
* * устройства ввода/вывода
|
||
* * базовый класс (\a PIIODevice)
|
||
* * файл (\a PIFile)
|
||
* * последовательный порт (\a PISerial)
|
||
* * ethernet (\a PIEthernet)
|
||
* * USB (\a PIUSB)
|
||
* * packets extractor (\a PIPacketExtractor)
|
||
* * бинарный логфайл (\a PIBinaryLog)
|
||
* * сложное составное устройство (\a PIConnection)
|
||
* * поддержка библиотек времени выполнения
|
||
* * базовая функциональность (\a PILibrary)
|
||
* * плагин (\a PIPluginLoader)
|
||
* * диагностика качества связи (\a PIDiagnostics)
|
||
* * парсер аргументов командной строки (\a PICLI)
|
||
* * вычислитель (\a PIEvaluator)
|
||
* * пиринговая сеть (\a PIPeer)
|
||
* * процесс (\a PIProcess)
|
||
* * машина состояний (\a PIStateMachine)
|
||
* \n \n Базовое использование PIP описано на странице \ref using_basic
|
||
*/
|
||
|
||
|
||
/*! \~english \page using_basic Getting started
|
||
* \~russian \page using_basic Простые начала
|
||
*
|
||
* \~english
|
||
* 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
|
||
*
|
||
* \~russian
|
||
* Многие начинающие программисты решают общие задачи взаимодействия с операционной системой:
|
||
* вывод в консоль, определение нажатия клавиш, работа с последовательными портами, сетью или файлами,
|
||
* и многое другое. Эти задачи решены в библиотеке, и код, основанный на PIP будет компилироваться
|
||
* и работать одинаково на многих системах: Windows, любой Linux, Red Hat, FreeBSD, MacOS X и QNX.
|
||
* Типовое приложение на PIP выглядит примерно так: \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
|
||
*
|
||
* \~english
|
||
* 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
|
||
*
|
||
* \~russian
|
||
* Этот код демонстрирует простую конфигурируемую программу, которая может быть запущена с
|
||
* 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.
|
||
*/
|
||
|
||
|
||
/*! \page using_advanced Advanced using
|
||
* Sorry, creativity crysis xD
|
||
*/
|
||
|
||
/*
|
||
* \~english
|
||
* \~russian
|
||
*/
|