doc ru
This commit is contained in:
@@ -26,6 +26,107 @@
|
||||
#endif
|
||||
|
||||
|
||||
//! \addtogroup System
|
||||
//! \{
|
||||
//! \class PILibrary pilibrary.h
|
||||
//!
|
||||
//! \~\brief
|
||||
//! \~english Run-time library
|
||||
//! \~russian Run-time библиотека
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english \section _sec0 Synopsis
|
||||
//! \~russian \section _sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! %PILibrary allow you dynamically load external library and use
|
||||
//! some methods from it. %PILibrary instance contains library
|
||||
//! pointer and unload library on destructor, so recommended
|
||||
//! to use it with \b new creation.
|
||||
//!
|
||||
//! Main method of %PILibrary is \a resolve(const char *), which returns
|
||||
//! "void*" pointer to requested method. One should test it
|
||||
//! to \c nullptr and convert it in pointer to the required method.
|
||||
//!
|
||||
//! In case of C++ libraries it`s very important to use C-linkage
|
||||
//! of exported methods! You may also need to mark methods for
|
||||
//! export, e.g. \с __declspec(dllexport)
|
||||
//!
|
||||
//! \~russian
|
||||
//! %PILibrary позволяет динамически загружать стороннюю библиотеку
|
||||
//! и использовать оттуда методы. Экземпляр %PILibrary содержит
|
||||
//! указатель на библиотеку и выгружает её в деструкторе, поэтому
|
||||
//! рекомендуется создавать её с помощью \b new.
|
||||
//!
|
||||
//! Основной метод %PILibrary - это \a resolve(const char *), который возвращает
|
||||
//! "void*" указатель на запрошенный метод. Необходимо проверить его
|
||||
//! на \c nullptr и преобразовать в указатель на нужный метод.
|
||||
//!
|
||||
//! В случае C++ библиотеки очень важно использовать C-linkage
|
||||
//! для экспортируемых методов! Также может понадобиться пометить
|
||||
//! методы на экспорт, например, \с __declspec(dllexport)
|
||||
//!
|
||||
//! \~\code
|
||||
//! extern "C" {
|
||||
//! __declspec(dllexport) int exportedSum(int,int);
|
||||
//! __declspec(dllexport) int exportedMul(int,int);
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english \section _sec1 Usage
|
||||
//! \~russian \section _sec1 Использование
|
||||
//!
|
||||
//! \~english Library:
|
||||
//! \~russian Библиотека:
|
||||
//! \~\code
|
||||
//! #include <piplugin.h>
|
||||
//!
|
||||
//! extern "C" {
|
||||
//! PIP_PLUGIN_EXPORT int exportedSum(int,int);
|
||||
//! PIP_PLUGIN_EXPORT int exportedMul(int,int);
|
||||
//! }
|
||||
//!
|
||||
//! int exportedSum(int a, int b) {
|
||||
//! return a + b;
|
||||
//! }
|
||||
//! int exportedMul(int a, int b) {
|
||||
//! return a * b;
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Program:
|
||||
//! \~russian Программа:
|
||||
//! \~\code
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! typedef int(*MyFunc)(int,int);
|
||||
//! PILibrary * lib = new PILibrary();
|
||||
//! if (lib->load("mylib.dll")) {
|
||||
//! MyFunc fadd = (MyFunc)lib->resolve("exportedSum");
|
||||
//! MyFunc fmul = (MyFunc)lib->resolve("exportedMul");
|
||||
//! if (fadd) {
|
||||
//! int sum = fadd(1, 2);
|
||||
//! piCout << "sum =" << sum;
|
||||
//! } else {
|
||||
//! piCout << "Can`t resolve" << "exportedSum";
|
||||
//! }
|
||||
//! if (fmul) {
|
||||
//! int mul = fadd(10, 20);
|
||||
//! piCout << "mul =" << mul;
|
||||
//! } else {
|
||||
//! piCout << "Can`t resolve" << "exportedMul";
|
||||
//! }
|
||||
//! } else {
|
||||
//! piCout << lib->lastError();
|
||||
//! }
|
||||
//! delete lib;
|
||||
//! }
|
||||
//!
|
||||
//! // sum = 3
|
||||
//! // mul = 30
|
||||
//! \endcode
|
||||
//!
|
||||
//! \}
|
||||
|
||||
|
||||
PRIVATE_DEFINITION_START(PILibrary)
|
||||
#ifdef WINDOWS
|
||||
HMODULE
|
||||
|
||||
@@ -32,16 +32,43 @@
|
||||
|
||||
class PIP_EXPORT PILibrary {
|
||||
public:
|
||||
|
||||
//! \~english Constructs %PILibrary and load if "path_" not empty
|
||||
//! \~russian Создает %PILibrary и загружает если "path_" не пустой
|
||||
PILibrary(const PIString & path_ = PIString());
|
||||
|
||||
//! \~english Destroy %PILibrary, unload if library was loaded
|
||||
//! \~russian Уничтожает %PILibrary и выгружает библиотеку, если она была загружена
|
||||
~PILibrary();
|
||||
|
||||
|
||||
//! \~english Load library with relative or absolute path "path_"
|
||||
//! \~russian Загружает библиотеку по относительному или абсолютному пути "path_"
|
||||
bool load(const PIString & path_);
|
||||
|
||||
//! \~english Load library with \a path() path
|
||||
//! \~russian Загружает библиотеку по пути \a path()
|
||||
bool load();
|
||||
|
||||
//! \~english Unload library if it was loaded
|
||||
//! \~russian Выгружает библиотеку, если она была загружена
|
||||
void unload();
|
||||
|
||||
//! \~english Obtain exported library method with name "symbol"
|
||||
//! \~russian Получает экспортированный метод библиотеки с именем "symbol"
|
||||
void * resolve(const char * symbol);
|
||||
|
||||
|
||||
//! \~english Returns if library successfully loaded
|
||||
//! \~russian Возвращает успешно ли загружена библиотека
|
||||
bool isLoaded() const;
|
||||
|
||||
//! \~english Returns library path
|
||||
//! \~russian Возвращает путь к библиотеке
|
||||
PIString path() const {return libpath;}
|
||||
|
||||
//! \~english Returns last occured error in human-readable format
|
||||
//! \~russian Возвращает последнюю ошибку в читаемом виде
|
||||
PIString lastError() const {return liberror;}
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,139 +24,144 @@
|
||||
#include "pidir.h"
|
||||
#include "piincludes_p.h"
|
||||
|
||||
/*! \class PIPluginLoader
|
||||
* \brief Plugin loader
|
||||
*
|
||||
* \section PIPluginLoader_sec0 Synopsis
|
||||
* This class provides several macro to define plugin and %PIPluginLoader - class
|
||||
* to load and check plugin.
|
||||
*
|
||||
* \section PIPluginLoader_sec1 Plugin side
|
||||
* Plugin is a shared library that can be loaded in run-time.
|
||||
* This is only PIP_PLUGIN macro necessary to define plugin.
|
||||
* If you want to set and check some version, use macro
|
||||
* \a PIP_PLUGIN_SET_USER_VERSION(version). Also you can
|
||||
* define a function to merge static sections between application
|
||||
* and plugin with macro \a PIP_PLUGIN_STATIC_SECTION_MERGE. Before
|
||||
* merge, you should set pointers to that sections with macro
|
||||
* \a PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr).
|
||||
*
|
||||
* \section PIPluginLoader_sec2 Application side
|
||||
* Application should use class \a PIPluginLoader to load
|
||||
* plugin. Main function is \a load(PIString name).
|
||||
* "name" is base name of library, %PIPluginLoader
|
||||
* try to use sevaral names, \<name\>, lib\<name\> and
|
||||
* "dll", "so" and "dylib" extensions, depends on system.
|
||||
* For example:
|
||||
* \code
|
||||
* PIPluginLoader l;
|
||||
* l.load("foo");
|
||||
* \endcode
|
||||
* On Windows, try to open "foo", "libfoo", "foo.dll" and
|
||||
* "libfoo.dll".
|
||||
* If you using user version check, you should set it
|
||||
* with macro \a PIP_PLUGIN_SET_USER_VERSION(version).
|
||||
* When plugin is successfully loaded and checked,
|
||||
* you can load your custom symbols with function
|
||||
* \a resolve(name), similar to PILibrary.
|
||||
* \note You should use PIP_PLUGIN_EXPORT and "export "C""
|
||||
* with functions you want to use with \a resolve(name)!
|
||||
*
|
||||
* \section PIPluginLoader_sec3 Static sections
|
||||
* Macro \a PIP_PLUGIN_STATIC_SECTION_MERGE defines function
|
||||
* with arguments (int type, void * from, void * to), so you
|
||||
* can leave this macro as declaration or define its body next:
|
||||
* \code
|
||||
* PIP_PLUGIN_STATIC_SECTION_MERGE() {
|
||||
* switch (type) {
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
* \note If you using singletones, remember that cpp-defined
|
||||
* singletones in shared libraries are single for whole application,
|
||||
* including plugins! But if you use h-defined singletones or
|
||||
* static linking, there are many objects in application and you
|
||||
* should merge their content with this macro.
|
||||
*
|
||||
* Anyway, if this is macro \a PIP_PLUGIN_STATIC_SECTION_MERGE, it
|
||||
* called once while loading plugin with "from" - plugin side
|
||||
* and "to" - application side, and second (optionally) on method
|
||||
* \a mergeStatic() with "from" - application side and "to" - plugin side.
|
||||
* First direction allow you to copy all defined static content from plugin
|
||||
* to application, and second - after loading all plugins (for example)
|
||||
* to copy static content from application (and all plugins) to plugin.
|
||||
*
|
||||
* \section PIPluginLoader_sec4 Examples
|
||||
* Simple plugin:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
*
|
||||
* PIP_PLUGIN
|
||||
*
|
||||
* extern "C" {
|
||||
* PIP_PLUGIN_EXPORT void myFunc() {
|
||||
* piCout << "Hello plugin!";
|
||||
* }
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Application:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
* int main() {
|
||||
* PIPluginLoader pl;
|
||||
* pl.load("your_lib");
|
||||
* if (pl.isLoaded()) {
|
||||
* typedef void(*MyFunc)();
|
||||
* MyFunc f = (MyFunc)pl.resolve("myFunc");
|
||||
* if (f) f();
|
||||
* }
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Complex plugin:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
*
|
||||
* PIStringList global_list;
|
||||
*
|
||||
* PIP_PLUGIN
|
||||
* PIP_PLUGIN_SET_USER_VERSION("1.0.0")
|
||||
* PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list)
|
||||
*
|
||||
* STATIC_INITIALIZER_BEGIN
|
||||
* global_list << "plugin_init";
|
||||
* STATIC_INITIALIZER_END
|
||||
*
|
||||
* PIP_PLUGIN_STATIC_SECTION_MERGE {
|
||||
* PIStringList * sfrom = (PIStringList*)from, * sto = (PIStringList*)to;
|
||||
* *sto << *sfrom;
|
||||
* sto->removeDuplicates();
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
* Application:
|
||||
* \code
|
||||
* #include <piplugin.h>
|
||||
*
|
||||
* PIStringList global_list;
|
||||
*
|
||||
* PIP_PLUGIN_SET_USER_VERSION("1.0.0");
|
||||
* PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list);
|
||||
*
|
||||
* int main() {
|
||||
* global_list << "app";
|
||||
* PIPluginLoader pl;
|
||||
* pl.load("your_lib");
|
||||
* pl.mergeStatic();
|
||||
* piCout << "list =" << global_list;
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
*
|
||||
*/
|
||||
//! \addtogroup System
|
||||
//! \{
|
||||
//! \class PIPluginLoader piplugin.h
|
||||
//!
|
||||
//! \brief
|
||||
//! \~english Plugin loader
|
||||
//! \~russian Загрузчик плагина
|
||||
//!
|
||||
//! \section PIPluginLoader_sec0 Synopsis
|
||||
//! This class provides several macro to define plugin and %PIPluginLoader - class
|
||||
//! to load and check plugin.
|
||||
//!
|
||||
//! \section PIPluginLoader_sec1 Plugin side
|
||||
//! Plugin is a shared library that can be loaded in run-time.
|
||||
//! This is only PIP_PLUGIN macro necessary to define plugin.
|
||||
//! If you want to set and check some version, use macro
|
||||
//! \a PIP_PLUGIN_SET_USER_VERSION(version). Also you can
|
||||
//! define a function to merge static sections between application
|
||||
//! and plugin with macro \a PIP_PLUGIN_STATIC_SECTION_MERGE. Before
|
||||
//! merge, you should set pointers to that sections with macro
|
||||
//! \a PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr).
|
||||
//!
|
||||
//! \section PIPluginLoader_sec2 Application side
|
||||
//! Application should use class \a PIPluginLoader to load
|
||||
//! plugin. Main function is \a load(PIString name).
|
||||
//! "name" is base name of library, %PIPluginLoader
|
||||
//! try to use sevaral names, \<name\>, lib\<name\> and
|
||||
//! "dll", "so" and "dylib" extensions, depends on system.
|
||||
//! For example:
|
||||
//! \code
|
||||
//! PIPluginLoader l;
|
||||
//! l.load("foo");
|
||||
//! \endcode
|
||||
//! On Windows, try to open "foo", "libfoo", "foo.dll" and
|
||||
//! "libfoo.dll".
|
||||
//! If you using user version check, you should set it
|
||||
//! with macro \a PIP_PLUGIN_SET_USER_VERSION(version).
|
||||
//! When plugin is successfully loaded and checked,
|
||||
//! you can load your custom symbols with function
|
||||
//! \a resolve(name), similar to PILibrary.
|
||||
//! \note You should use PIP_PLUGIN_EXPORT and "export "C""
|
||||
//! with functions you want to use with \a resolve(name)!
|
||||
//!
|
||||
//! \section PIPluginLoader_sec3 Static sections
|
||||
//! Macro \a PIP_PLUGIN_STATIC_SECTION_MERGE defines function
|
||||
//! with arguments (int type, void * from, void * to), so you
|
||||
//! can leave this macro as declaration or define its body next:
|
||||
//! \code
|
||||
//! PIP_PLUGIN_STATIC_SECTION_MERGE() {
|
||||
//! switch (type) {
|
||||
//! ...
|
||||
//! }
|
||||
//! }
|
||||
//! \endcode
|
||||
//! \note If you using singletones, remember that cpp-defined
|
||||
//! singletones in shared libraries are single for whole application,
|
||||
//! including plugins! But if you use h-defined singletones or
|
||||
//! static linking, there are many objects in application and you
|
||||
//! should merge their content with this macro.
|
||||
//!
|
||||
//! Anyway, if this is macro \a PIP_PLUGIN_STATIC_SECTION_MERGE, it
|
||||
//! called once while loading plugin with "from" - plugin side
|
||||
//! and "to" - application side, and second (optionally) on method
|
||||
//! \a mergeStatic() with "from" - application side and "to" - plugin side.
|
||||
//! First direction allow you to copy all defined static content from plugin
|
||||
//! to application, and second - after loading all plugins (for example)
|
||||
//! to copy static content from application (and all plugins) to plugin.
|
||||
//!
|
||||
//! \section PIPluginLoader_sec4 Examples
|
||||
//! Simple plugin:
|
||||
//! \code
|
||||
//! #include <piplugin.h>
|
||||
//!
|
||||
//! PIP_PLUGIN
|
||||
//!
|
||||
//! extern "C" {
|
||||
//! PIP_PLUGIN_EXPORT void myFunc() {
|
||||
//! piCout << "Hello plugin!";
|
||||
//! }
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! Application:
|
||||
//! \code
|
||||
//! #include <piplugin.h>
|
||||
//! int main() {
|
||||
//! PIPluginLoader pl;
|
||||
//! pl.load("your_lib");
|
||||
//! if (pl.isLoaded()) {
|
||||
//! typedef void(*MyFunc)();
|
||||
//! MyFunc f = (MyFunc)pl.resolve("myFunc");
|
||||
//! if (f) f();
|
||||
//! }
|
||||
//! return 0;
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! Complex plugin:
|
||||
//! \code
|
||||
//! #include <piplugin.h>
|
||||
//!
|
||||
//! PIStringList global_list;
|
||||
//!
|
||||
//! PIP_PLUGIN
|
||||
//! PIP_PLUGIN_SET_USER_VERSION("1.0.0")
|
||||
//! PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list)
|
||||
//!
|
||||
//! STATIC_INITIALIZER_BEGIN
|
||||
//! global_list << "plugin_init";
|
||||
//! STATIC_INITIALIZER_END
|
||||
//!
|
||||
//! PIP_PLUGIN_STATIC_SECTION_MERGE {
|
||||
//! PIStringList * sfrom = (PIStringList*)from, * sto = (PIStringList*)to;
|
||||
//! *sto << *sfrom;
|
||||
//! sto->removeDuplicates();
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! Application:
|
||||
//! \code
|
||||
//! #include <piplugin.h>
|
||||
//!
|
||||
//! PIStringList global_list;
|
||||
//!
|
||||
//! PIP_PLUGIN_SET_USER_VERSION("1.0.0");
|
||||
//! PIP_PLUGIN_ADD_STATIC_SECTION(1, &global_list);
|
||||
//!
|
||||
//! int main() {
|
||||
//! global_list << "app";
|
||||
//! PIPluginLoader pl;
|
||||
//! pl.load("your_lib");
|
||||
//! pl.mergeStatic();
|
||||
//! piCout << "list =" << global_list;
|
||||
//! return 0;
|
||||
//! }
|
||||
//! \endcode
|
||||
//!
|
||||
//! \}
|
||||
|
||||
#define STR_WF(s) #s
|
||||
#define STR(s) STR_WF(s)
|
||||
|
||||
@@ -209,7 +209,7 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
|
||||
//! If "func" if not null this function will be executed after \a run().
|
||||
//!
|
||||
//! ThreadFunc is any static function with format "void func(void * data)", or
|
||||
//! lambda-function with format [...]( ){...}.
|
||||
//! [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) with format [...]( ){...}.
|
||||
//! "Data" is custom data set from constructor or with \a setData() function.
|
||||
//!
|
||||
//! Also you can connect to event \a started(), but in this case you should to white
|
||||
@@ -221,7 +221,7 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
|
||||
//! если "ThreadFunc" существует, он будет вызываться после \a run().
|
||||
//!
|
||||
//! ThreadFunc может быть любым статическим методом в формате "void func(void * data)", либо
|
||||
//! лямбда-функцией в формате [...]( ){...}.
|
||||
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) в формате [...]( ){...}.
|
||||
//! "Data" является произвольным указателем, задаваемым в конструкторе или методом \a setData().
|
||||
//!
|
||||
//! Также можно присоединиться к событию \a started(), но в этом случае надо будет своими силами
|
||||
@@ -273,8 +273,8 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {((PIThread*)t)->__thread_fun
|
||||
//! // thread run 1
|
||||
//! \endcode
|
||||
//!
|
||||
//! \~english Using with lambda-function
|
||||
//! \~russian Использование с лямбда-функцией
|
||||
//! \~english Using with [lambda expression](https://en.cppreference.com/w/cpp/language/lambda)
|
||||
//! \~russian Использование с [лямбда-выражением](https://ru.cppreference.com/w/cpp/language/lambda)
|
||||
//! \~\code{.cpp}
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! int cnt = 0;
|
||||
@@ -971,13 +971,13 @@ void PIThread::runOnce(PIObject * object, const char * handler, const PIString &
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//! This method create %PIThread with name "name" and execute
|
||||
//! lambda-function "func" in this thread.\n
|
||||
//! [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "func" in this thread.\n
|
||||
//! This %PIThread automatically delete on function finish.\n
|
||||
//! "func" shouldn`t have arguments.
|
||||
//!
|
||||
//! \~russian
|
||||
//! Этот метод создает %PIThread с именем "name" и выполняет
|
||||
//! лямбда-функцию "func" в этом потоке.\n
|
||||
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "func" в этом потоке.\n
|
||||
//! %PIThread автоматически удаляется после завершения функции.\n
|
||||
//! "func" не должна иметь аргументов.
|
||||
//!
|
||||
|
||||
@@ -173,8 +173,8 @@ public:
|
||||
//! \~russian Вызывает обработчик "handler" объекта "object" в отдельном потоке
|
||||
static void runOnce(PIObject * object, const char * handler, const PIString & name = PIString());
|
||||
|
||||
//! \~english Call lambda-function "func" in separate thread
|
||||
//! \~russian Вызывает лямбда-функцию "func" в отдельном потоке
|
||||
//! \~english Call [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "func" in separate thread
|
||||
//! \~russian Вызывает [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "func" в отдельном потоке
|
||||
static void runOnce(std::function<void()> func, const PIString & name = PIString());
|
||||
|
||||
//! \handlers
|
||||
|
||||
@@ -28,25 +28,63 @@
|
||||
//! \~russian Класс для простого уведомления и ожидания в различных потоках
|
||||
//!
|
||||
//! \~\details
|
||||
//! \~english
|
||||
//!
|
||||
//! \~russian
|
||||
//!
|
||||
//!
|
||||
//! \~english \section PIThreadNotifier_sec0 Synopsis
|
||||
//! \~russian \section PIThreadNotifier_sec0 Краткий обзор
|
||||
//! \~english
|
||||
//! This class used as event mechanism between threads. One thread wait for some event,
|
||||
//! and another send this event, unblocking first thread. It is useful to
|
||||
//! syncronize some actions in several threads.
|
||||
//!
|
||||
//! \~russian
|
||||
//!
|
||||
//!Этот класс используется как событийный механизм между потоками.
|
||||
//! Один поток ждёт некоторого события и другой его отправляет, разблокируя первый.
|
||||
//! Это полезно для синхронизации действий в нескольких потоках.
|
||||
//!
|
||||
//! \~english \section PIThreadNotifier_sec1 Usage
|
||||
//! \~russian \section PIThreadNotifier_sec1 Использование
|
||||
//! \~english
|
||||
//! \~\code
|
||||
//! PIThreadNotifier notifier;
|
||||
//! PITimeMeasurer time;
|
||||
//!
|
||||
//! \~russian
|
||||
//! class Worker: public PIThread {
|
||||
//! PIOBJECT_SUBCLASS(Worker, PIThread)
|
||||
//! public:
|
||||
//! Worker(const PIString & n) {
|
||||
//! setName(n);
|
||||
//! }
|
||||
//! void run() override {
|
||||
//! piCoutObj << (int)time.elapsed_m() << "wait ...";
|
||||
//! notifier.wait();
|
||||
//! piCoutObj << (int)time.elapsed_m() << "done";
|
||||
//! };
|
||||
//! };
|
||||
//!
|
||||
//!
|
||||
//! int main(int argc, char * argv[]) {
|
||||
//! PIVector<Worker*> workers;
|
||||
//!
|
||||
//! // create 2 threads
|
||||
//! for (auto n: {"first ", "second"})
|
||||
//! workers << new Worker(n);
|
||||
//!
|
||||
//! // start them
|
||||
//! for (auto * w: workers)
|
||||
//! w->startOnce();
|
||||
//!
|
||||
//! piMSleep(500);
|
||||
//! notifier.notifyOnce(); // notify one of them after 500 ms
|
||||
//! piMSleep(500);
|
||||
//! notifier.notifyOnce(); // notify one of them after 1000 ms
|
||||
//!
|
||||
//! for (auto * w: workers)
|
||||
//! w->waitForFinish();
|
||||
//! }
|
||||
//!
|
||||
//! // [Worker "first "] 0 wait ...
|
||||
//! // [Worker "second"] 0 wait ...
|
||||
//! // [Worker "second"] 500 done
|
||||
//! // [Worker "first "] 1000 done
|
||||
//! \endcode
|
||||
//! \}
|
||||
|
||||
|
||||
|
||||
@@ -43,8 +43,8 @@ public:
|
||||
|
||||
virtual ~PIThreadPoolLoop();
|
||||
|
||||
//! \~english Set threads function to "f" with format [ ](int){ ... }
|
||||
//! \~russian Устанавливает функцию потоков на "f" в формате [ ](int){ ... }
|
||||
//! \~english Set threads function to [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "f" with format [ ](int){ ... }
|
||||
//! \~russian Устанавливает функцию потоков на [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "f" в формате [ ](int){ ... }
|
||||
void setFunction(std::function<void(int)> f);
|
||||
|
||||
//! \~english Wait for all threads stop
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
//! \~russian \section PITimer_sec1 Варианты уведомления
|
||||
//! \~english
|
||||
//! Notify variants:
|
||||
//! * "slot" - static function with format void func(void * data, int delimiter) or lambda-function;
|
||||
//! * "slot" - static function with format void func(void * data, int delimiter) or [lambda expression](https://en.cppreference.com/w/cpp/language/lambda);
|
||||
//! * event - \a tickEvent();
|
||||
//! * virtual function - \a tick().
|
||||
//!
|
||||
@@ -58,7 +58,7 @@
|
||||
//! All these variants are equivalent, use most applicable.
|
||||
//! \~russian
|
||||
//! Варианты уведомления:
|
||||
//! * "slot" - статический метод в формате void func(void * data, int delimiter) или лямбда-функция;
|
||||
//! * "slot" - статический метод в формате void func(void * data, int delimiter) или [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda);
|
||||
//! * event - \a tickEvent();
|
||||
//! * виртуальный метод - \a tick().
|
||||
//!
|
||||
|
||||
@@ -48,6 +48,7 @@ const char help_string[] =
|
||||
"You can override ID with PIMETA(id=<ID>). If in class or struct\n"
|
||||
"PIMETA(simple-stream) presence, then variables stored/restored\n"
|
||||
"with simple << and >> operators.\n"
|
||||
"If PIMETA(no-stream) presence, then class or struct ignored.\n"
|
||||
"\n"
|
||||
"-G (Getter functions)\n"
|
||||
"Generate anonymous access methods for member typenames and values.\n"
|
||||
|
||||
Reference in New Issue
Block a user