refactor: migrate MICRO_PIP to fine-grained feature flags

Replace monolithic MICRO_PIP/PIP_MICRO with granular flags:

Feature flags (CMake options + platform auto-detection):
- PIP_NO_FILESYSTEM, PIP_NO_THREADS, PIP_NO_SOCKET
- PIP_NO_PROCESS, PIP_NO_DYNLIB, PIP_NO_FFT, PIP_NO_SERIAL

Embedded optimization flag:
- PIP_EMBEDDED (auto-set for Pico SDK and FreeRTOS)
  Controls buffer sizes, time stubs, terminal fallback, init stubs

Platform blocks in CMakeLists.txt:
- Pico SDK: auto-disables FS, PROCESS, DYNLIB, FFT, SERIAL;
  conditionally disables THREADS (no FreeRTOS) and SOCKET (no LWIP)
- FreeRTOS: auto-disables FS, PROCESS, DYNLIB, FFT, SERIAL;
  conditionally disables SOCKET (no LWIP)
- Android: auto-disables PROCESS, DYNLIB, FFT

Updated 96 files across libs/, utils/, tests/, and CMakeLists.txt.
Builds verified for Linux (547 tests pass) and Pico SDK (100%).
Removed all MICRO_PIP and PIP_MICRO references (0 remaining).
This commit is contained in:
2026-08-11 14:34:59 +03:00
parent 87c53d45a4
commit 4d8b743075
97 changed files with 1555 additions and 914 deletions
+3 -3
View File
@@ -5,7 +5,7 @@
### Basic Build ### Basic Build
```bash ```bash
# Configure with CMake (release build) # Configure with CMake (release build)
cmake -B build -j16 cmake -B build
# Build the project # Build the project
cmake --build build -j16 cmake --build build -j16
@@ -14,12 +14,12 @@ cmake --build build -j16
cmake --build build --target install -j16 cmake --build build --target install -j16
# Local install (bin/lib/include in build directory) # Local install (bin/lib/include in build directory)
cmake -B build -DLOCAL=ON -j16 cmake -B build -DLOCAL=ON
``` ```
### With Tests ### With Tests
```bash ```bash
cmake -B build -DTESTS=ON -j16 cmake -B build -DTESTS=ON -DTESTS_RUN=ON
cmake --build build -j16 cmake --build build -j16
cd build && ctest cd build && ctest
``` ```
+127 -103
View File
@@ -3,6 +3,9 @@ cmake_policy(SET CMP0017 NEW) # need include() with .cmake
if (POLICY CMP0177) if (POLICY CMP0177)
cmake_policy(SET CMP0177 OLD) cmake_policy(SET CMP0177 OLD)
endif() endif()
if(DEFINED PICO_SDK_PATH)
include(${PICO_SDK_PATH}/pico_sdk_init.cmake)
endif()
project(PIP) project(PIP)
set(PIP_MAJOR 5) set(PIP_MAJOR 5)
set(PIP_MINOR 8) set(PIP_MINOR 8)
@@ -72,6 +75,11 @@ option(TESTS_RUN "Run tests before install step" OFF)
option(COVERAGE "Build project with coverage info" OFF) option(COVERAGE "Build project with coverage info" OFF)
option(PIP_NO_FILESYSTEM "Disable filesystem support" OFF) option(PIP_NO_FILESYSTEM "Disable filesystem support" OFF)
option(PIP_NO_THREADS "Disable threading support" OFF) option(PIP_NO_THREADS "Disable threading support" OFF)
option(PIP_NO_SOCKET "Disable socket/network support" OFF)
option(PIP_NO_PROCESS "Disable process management" OFF)
option(PIP_NO_DYNLIB "Disable dynamic library loading" OFF)
option(PIP_NO_FFT "Disable FFT support" OFF)
option(PIP_NO_SERIAL "Disable serial port support" OFF)
option(PIP_FFTW_F "Support fftw module for float" ON) option(PIP_FFTW_F "Support fftw module for float" ON)
option(PIP_FFTW_L "Support fftw module for long double" ON) option(PIP_FFTW_L "Support fftw module for long double" ON)
option(PIP_FFTW_Q "Support fftw module for quad double" OFF) option(PIP_FFTW_Q "Support fftw module for quad double" OFF)
@@ -225,26 +233,64 @@ if (TESTS)
add_subdirectory(tests) add_subdirectory(tests)
endif() endif()
if(PIP_MICRO)
add_definitions(-DMICRO_PIP)
set(ICU OFF)
set(LOCAL ON)
endif()
if(PIP_FREERTOS)
add_definitions(-DPIP_FREERTOS)
endif()
if(DEFINED PICO_BOARD) if(DEFINED PICO_BOARD)
add_definitions(-DPICO_SDK) add_definitions(-DPICO_SDK)
add_definitions(-DPIP_EMBEDDED)
set(PIP_NO_FILESYSTEM ON CACHE BOOL "" FORCE) set(PIP_NO_FILESYSTEM ON CACHE BOOL "" FORCE)
if(NOT DEFINED PICO_FREERTOS)
set(PIP_NO_THREADS ON CACHE BOOL "" FORCE)
endif()
if(NOT DEFINED PICO_LWIP)
set(PIP_NO_SOCKET ON CACHE BOOL "" FORCE)
set(PIP_BUILD_MQTT_CLIENT OFF CACHE BOOL "" FORCE)
endif()
set(PIP_NO_PROCESS ON CACHE BOOL "" FORCE)
set(PIP_NO_DYNLIB ON CACHE BOOL "" FORCE)
set(PIP_NO_FFT ON CACHE BOOL "" FORCE)
set(PIP_NO_SERIAL ON CACHE BOOL "" FORCE)
message(STATUS "Building PIP for Pi Pico SDK ${PICO_SDK_VERSION_STRING}") message(STATUS "Building PIP for Pi Pico SDK ${PICO_SDK_VERSION_STRING}")
endif() endif()
if(PIP_FREERTOS)
add_definitions(-DPIP_FREERTOS)
add_definitions(-DPIP_EMBEDDED)
set(PIP_NO_FILESYSTEM ON CACHE BOOL "" FORCE)
if(NOT DEFINED LWIP)
set(PIP_NO_SOCKET ON CACHE BOOL "" FORCE)
endif()
set(PIP_NO_PROCESS ON CACHE BOOL "" FORCE)
set(PIP_NO_DYNLIB ON CACHE BOOL "" FORCE)
set(PIP_NO_FFT ON CACHE BOOL "" FORCE)
set(PIP_NO_SERIAL ON CACHE BOOL "" FORCE)
endif()
if(DEFINED ANDROID_PLATFORM)
set(PIP_NO_PROCESS ON CACHE BOOL "" FORCE)
set(PIP_NO_DYNLIB ON CACHE BOOL "" FORCE)
set(PIP_NO_FFT ON CACHE BOOL "" FORCE)
endif()
if(PIP_NO_FILESYSTEM) if(PIP_NO_FILESYSTEM)
add_definitions(-DPIP_NO_FILESYSTEM) add_definitions(-DPIP_NO_FILESYSTEM)
endif() endif()
if(PIP_NO_THREADS) if(PIP_NO_THREADS)
add_definitions(-DPIP_NO_THREADS) add_definitions(-DPIP_NO_THREADS)
endif() endif()
if(PIP_NO_SOCKET)
add_definitions(-DPIP_NO_SOCKET)
endif()
if(PIP_NO_PROCESS)
add_definitions(-DPIP_NO_PROCESS)
endif()
if(PIP_NO_DYNLIB)
add_definitions(-DPIP_NO_DYNLIB)
endif()
if(PIP_NO_FFT)
add_definitions(-DPIP_NO_FFT)
endif()
if(PIP_NO_SERIAL)
add_definitions(-DPIP_NO_SERIAL)
endif()
# Check Bessel functions # Check Bessel functions
set(CMAKE_REQUIRED_INCLUDES math.h) set(CMAKE_REQUIRED_INCLUDES math.h)
@@ -348,34 +394,28 @@ if ((NOT DEFINED SHSTKPROJECT) AND (DEFINED ANDROID_PLATFORM))
#message("${ANDROID_NDK}/sysroot/usr/include") #message("${ANDROID_NDK}/sysroot/usr/include")
endif() endif()
if(NOT PIP_MICRO) if(WIN32)
if(WIN32) if(${C_COMPILER} STREQUAL "cl.exe")
if(${C_COMPILER} STREQUAL "cl.exe")
else()
list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi cfgmgr32 setupapi hid)
endif()
else() else()
list(APPEND LIBS_MAIN dl) list(APPEND LIBS_MAIN ws2_32 iphlpapi psapi cfgmgr32 setupapi hid)
if(DEFINED ENV{QNX_HOST}) endif()
list(APPEND LIBS_MAIN socket) else()
else() list(APPEND LIBS_MAIN dl)
if (NOT DEFINED ANDROID_PLATFORM) if(DEFINED ENV{QNX_HOST})
list(APPEND LIBS_MAIN pthread util) list(APPEND LIBS_MAIN socket)
if (NOT APPLE) else()
list(APPEND LIBS_MAIN rt) if (NOT DEFINED ANDROID_PLATFORM)
endif() list(APPEND LIBS_MAIN pthread util)
if (NOT APPLE)
list(APPEND LIBS_MAIN rt)
endif() endif()
endif() endif()
endif() endif()
endif() endif()
set(PIP_LIBS) set(PIP_LIBS)
if(PIP_MICRO) foreach(LIB_ ${LIBS_MAIN})
set(PIP_LIBS ${LIBS_MAIN}) pip_find_lib(${LIB_})
else() endforeach()
foreach(LIB_ ${LIBS_MAIN})
pip_find_lib(${LIB_})
endforeach()
endif()
if(WIN32) if(WIN32)
add_definitions(-DPSAPI_VERSION=1) add_definitions(-DPSAPI_VERSION=1)
if(${C_COMPILER} STREQUAL "cl.exe") if(${C_COMPILER} STREQUAL "cl.exe")
@@ -388,7 +428,7 @@ else()
endif() endif()
endif() endif()
set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}")
if(DEFINED ENV{QNX_HOST} OR PIP_MICRO) if(DEFINED ENV{QNX_HOST})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32")
endif() endif()
@@ -428,9 +468,7 @@ endif()
if (NOT CROSSTOOLS) if (NOT CROSSTOOLS)
if (NOT PIP_MICRO) if (PIP_BUILD_CONSOLE)
if (PIP_BUILD_CONSOLE)
pip_module(console "" "PIP console support" "" "" "") pip_module(console "" "PIP console support" "" "" "")
endif() endif()
@@ -561,6 +599,9 @@ if (NOT CROSSTOOLS)
else() else()
target_compile_definitions(pip_lua PRIVATE LUA_USE_POSIX) target_compile_definitions(pip_lua PRIVATE LUA_USE_POSIX)
endif() endif()
if(DEFINED PICO_SDK_PATH)
target_compile_definitions(pip_lua PRIVATE LUA_32BITS)
endif()
list(APPEND HDR_DIRS "${PIP_3PL_DIR}/LuaBridge") list(APPEND HDR_DIRS "${PIP_3PL_DIR}/LuaBridge")
list(APPEND HDRS ${_lua_src_hdr}) list(APPEND HDRS ${_lua_src_hdr})
endif() endif()
@@ -654,55 +695,36 @@ if (NOT CROSSTOOLS)
endif() endif()
endif() endif()
endif() endif()
else()
if (PIP_BUILD_CRYPT)
pip_module(crypt "" "PIP crypt support" "" "" "")
endif()
if (PIP_BUILD_COMPRESS)
pip_module(compress "" "PIP compression support" "" "" "")
endif()
if (PIP_BUILD_IO_UTILS)
if(PIP_BUILD_CRYPT)
pip_module(io_utils "pip_crypt" "PIP I/O support" "" "" " (+crypt)")
else()
pip_module(io_utils "" "PIP I/O support" "" "" "")
endif()
endif()
endif()
endif() endif()
string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}") string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}")
target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"") target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"")
if(NOT PIP_MICRO)
# Auxiliary # Auxiliary
if (NOT CROSSTOOLS) if (NOT CROSSTOOLS AND NOT DEFINED PICO_SDK_PATH)
add_subdirectory("utils/piterminal") add_subdirectory("utils/piterminal")
endif() endif()
# Utils # Utils
add_subdirectory("utils/code_model_generator") if(NOT DEFINED PICO_SDK_PATH)
add_subdirectory("utils/resources_compiler") add_subdirectory("utils/code_model_generator")
add_subdirectory("utils/deploy_tool") add_subdirectory("utils/resources_compiler")
add_subdirectory("utils/qt_support") add_subdirectory("utils/deploy_tool")
add_subdirectory("utils/translator") add_subdirectory("utils/qt_support")
add_subdirectory("utils/value_tree_translator") endif()
if(PIP_UTILS AND (NOT CROSSTOOLS)) if(NOT DEFINED PICO_SDK_PATH)
add_subdirectory("utils/system_calib") add_subdirectory("utils/translator")
add_subdirectory("utils/udp_file_transfer") add_subdirectory("utils/value_tree_translator")
if(sodium_FOUND) endif()
add_subdirectory("utils/system_daemon") if(PIP_UTILS AND (NOT CROSSTOOLS) AND (NOT DEFINED PICO_SDK_PATH))
add_subdirectory("utils/crypt_tool") add_subdirectory("utils/system_calib")
add_subdirectory("utils/cloud_dispatcher") add_subdirectory("utils/udp_file_transfer")
endif() if(sodium_FOUND)
add_subdirectory("utils/system_daemon")
add_subdirectory("utils/crypt_tool")
add_subdirectory("utils/cloud_dispatcher")
endif() endif()
endif() endif()
@@ -756,20 +778,18 @@ if(NOT LOCAL)
install(TARGETS ${PIP_MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) install(TARGETS ${PIP_MODULES} DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
endif() endif()
else() else()
if(NOT PIP_MICRO) if(WIN32)
if(WIN32) install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin)
install(TARGETS ${PIP_MODULES} RUNTIME DESTINATION bin) install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib)
install(TARGETS ${PIP_MODULES} ARCHIVE DESTINATION lib) else()
else() install(TARGETS ${PIP_MODULES} DESTINATION lib)
install(TARGETS ${PIP_MODULES} DESTINATION lib) endif()
endif() install(FILES ${HDRS} DESTINATION include/pip)
install(FILES ${HDRS} DESTINATION include/pip) if(PIP_LANG)
if(PIP_LANG) install(FILES ${PIP_LANG} DESTINATION share/pip/lang)
install(FILES ${PIP_LANG} DESTINATION share/pip/lang) endif()
endif() if(HDR_DIRS)
if(HDR_DIRS) install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip)
install(DIRECTORY ${HDR_DIRS} DESTINATION include/pip)
endif()
endif() endif()
endif() endif()
file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in") file(GLOB CMAKES "cmake/*.cmake" "cmake/*.in")
@@ -784,7 +804,7 @@ endif()
# #
# Build Documentation # Build Documentation
# #
if ((NOT PIP_MICRO) AND (NOT CROSSTOOLS)) if (NOT CROSSTOOLS)
include(PIPDocumentation) include(PIPDocumentation)
find_package(Doxygen) find_package(Doxygen)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
@@ -853,9 +873,7 @@ message(" Type : ${CMAKE_BUILD_TYPE}")
if (NOT LOCAL) if (NOT LOCAL)
message(" Install: \"${CMAKE_INSTALL_PREFIX}\"") message(" Install: \"${CMAKE_INSTALL_PREFIX}\"")
else() else()
if(NOT PIP_MICRO) message(" Install: local \"bin\", \"lib\" and \"include\"")
message(" Install: local \"bin\", \"lib\" and \"include\"")
endif()
endif() endif()
message("") message("")
message(" Options:") message(" Options:")
@@ -863,6 +881,14 @@ message(" std::iostream: ${PIP_STD_IOSTREAM}")
message(" ICU strings : ${PIP_ICU}") message(" ICU strings : ${PIP_ICU}")
message(" Introspection: ${PIP_INTROSPECTION}") message(" Introspection: ${PIP_INTROSPECTION}")
message(" Coverage : ${PIP_COVERAGE}") message(" Coverage : ${PIP_COVERAGE}")
message(" Feature flags:")
message(" PIP_NO_FILESYSTEM: ${PIP_NO_FILESYSTEM}")
message(" PIP_NO_THREADS : ${PIP_NO_THREADS}")
message(" PIP_NO_SOCKET : ${PIP_NO_SOCKET}")
message(" PIP_NO_PROCESS : ${PIP_NO_PROCESS}")
message(" PIP_NO_DYNLIB : ${PIP_NO_DYNLIB}")
message(" PIP_NO_FFT : ${PIP_NO_FFT}")
message(" PIP_NO_SERIAL : ${PIP_NO_SERIAL}")
if(INTROSPECTION) if(INTROSPECTION)
message(STATUS " Warning: Introspection reduces the performance!") message(STATUS " Warning: Introspection reduces the performance!")
endif() endif()
@@ -889,17 +915,15 @@ message(" Utilites:")
foreach(_util ${PIP_UTILS_LIST}) foreach(_util ${PIP_UTILS_LIST})
message(" * ${_util}") message(" * ${_util}")
endforeach() endforeach()
if(NOT PIP_MICRO) message("")
message("") message(" Using libraries:")
message(" Using libraries:") foreach(LIB_ ${LIBS_STATUS})
foreach(LIB_ ${LIBS_STATUS}) if (NOT TARGET ${LIB_})
if (NOT TARGET ${LIB_}) if(${LIB_}_FOUND)
if(${LIB_}_FOUND) message(" ${LIB_} -> ${${LIB_}_LIBRARIES}")
message(" ${LIB_} -> ${${LIB_}_LIBRARIES}") else()
else() message(" ${LIB_} not found, may fail")
message(" ${LIB_} not found, may fail")
endif()
endif() endif()
endforeach() endif()
endif() endforeach()
message("-----------------------") message("-----------------------")
+223
View File
@@ -0,0 +1,223 @@
# План миграции MICRO_PIP → тонкозернистые макросы
## Архитектура
**CMakeLists.txt** — центр логики:
- Опции `PIP_NO_*` (можно переопределить вручную)
- Platform-блоки (Pico SDK, FreeRTOS) устанавливают опции автоматически
- `add_definitions(-DPIP_NO_*)` передаёт флаги в компилятор
**piplatform.h** — минимальная логика:
- `PIP_MIN_MSLEEP` от `PIP_NO_THREADS`
- `PISERIAL_NO_PINS` для embedded
- Определение `LINUX` (без MICRO_PIP)
**Код** — использует feature flags: `#ifndef PIP_NO_THREADS`, `#ifndef PIP_NO_FILESYSTEM` и т.д.
## Флаг-карта по платформам
| Платформа | FS | Threads | Socket | Process | Dynlib | FFT | Serial |
|---|---|---|---|---|---|---|---|
| Linux/Desktop | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Windows | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| macOS | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Android | ✓ | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| QNX | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| FreeBSD | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| FreeRTOS (+LWIP) | ✗ | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| FreeRTOS (no LWIP) | ✗ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ |
| Pico SDK (+FreeRTOS+LWIP) | ✗ | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ |
| Pico SDK (bare metal) | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
---
## Пошаговый план
### Шаг 1. CMakeLists.txt — опции + platform-логика
**Добавить опции:**
```cmake
option(PIP_NO_SOCKET "Disable socket/network support" OFF)
option(PIP_NO_PROCESS "Disable process management" OFF)
option(PIP_NO_DYNLIB "Disable dynamic library loading" OFF)
option(PIP_NO_FFT "Disable FFT support" OFF)
option(PIP_NO_SERIAL "Disable serial port support" OFF)
```
**Pico SDK блок:**
```cmake
if(DEFINED PICO_BOARD)
add_definitions(-DPICO_SDK)
set(PIP_NO_FILESYSTEM ON CACHE BOOL "" FORCE)
if(NOT DEFINED PICO_FREERTOS)
set(PIP_NO_THREADS ON CACHE BOOL "" FORCE)
endif()
if(NOT DEFINED PICO_LWIP)
set(PIP_NO_SOCKET ON CACHE BOOL "" FORCE)
endif()
set(PIP_NO_PROCESS ON CACHE BOOL "" FORCE)
set(PIP_NO_DYNLIB ON CACHE BOOL "" FORCE)
set(PIP_NO_FFT ON CACHE BOOL "" FORCE)
set(PIP_NO_SERIAL ON CACHE BOOL "" FORCE)
message(STATUS "Building PIP for Pi Pico SDK ${PICO_SDK_VERSION_STRING}")
endif()
```
**FreeRTOS блок:**
```cmake
if(PIP_FREERTOS)
add_definitions(-DPIP_FREERTOS)
set(PIP_NO_FILESYSTEM ON CACHE BOOL "" FORCE)
if(NOT DEFINED LWIP)
set(PIP_NO_SOCKET ON CACHE BOOL "" FORCE)
endif()
set(PIP_NO_PROCESS ON CACHE BOOL "" FORCE)
set(PIP_NO_DYNLIB ON CACHE BOOL "" FORCE)
set(PIP_NO_FFT ON CACHE BOOL "" FORCE)
set(PIP_NO_SERIAL ON CACHE BOOL "" FORCE)
endif()
```
**Android блок (если нет):**
```cmake
if(DEFINED ANDROID_PLATFORM)
set(PIP_NO_PROCESS ON CACHE BOOL "" FORCE)
set(PIP_NO_DYNLIB ON CACHE BOOL "" FORCE)
set(PIP_NO_FFT ON CACHE BOOL "" FORCE)
endif()
```
**add_definitions для всех флагов:**
```cmake
if(PIP_NO_FILESYSTEM) add_definitions(-DPIP_NO_FILESYSTEM) endif()
if(PIP_NO_THREADS) add_definitions(-DPIP_NO_THREADS) endif()
if(PIP_NO_SOCKET) add_definitions(-DPIP_NO_SOCKET) endif()
if(PIP_NO_PROCESS) add_definitions(-DPIP_NO_PROCESS) endif()
if(PIP_NO_DYNLIB) add_definitions(-DPIP_NO_DYNLIB) endif()
if(PIP_NO_FFT) add_definitions(-DPIP_NO_FFT) endif()
if(PIP_NO_SERIAL) add_definitions(-DPIP_NO_SERIAL) endif()
```
**PIP_MIN_MSLEEP:**
```cmake
if(PIP_NO_THREADS)
add_definitions(-DPIP_MIN_MSLEEP=10)
else()
add_definitions(-DPIP_MIN_MSLEEP=1)
endif()
```
**Убрать:** блок `PIP_MICRO` / `MICRO_PIP`.
---
### Шаг 2. piplatform.h
**Заменить блок MICRO_PIP (строки 156-163) на:**
```cpp
#ifdef PICO_SDK
#define PISERIAL_NO_PINS
#endif
#ifdef FREERTOS
#ifndef PISERIAL_NO_PINS
#define PISERIAL_NO_PINS
#endif
#endif
```
**Linux определение (строки 165-179):** убрать `MICRO_PIP` из цепочки.
**Убрать doxygen-документацию MICRO_PIP (строка 77-81).**
---
### Шаг 3. pibase_macros.h
**Убрать doxygen MICRO_PIP (строки 119-121, 171).**
**`__PIP_TYPENAME__` (строки 226-232):** уже перенесено на RTTI check.
**`PIP_MIN_MSLEEP` (строка ~402):** убрать, теперь задается CMake.
---
### Шаг 4. Файлы целиком под MICRO_PIP
#### 4a. PIProcess → `PIP_NO_PROCESS`
- `libs/main/system/piprocess.h` / `.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_PROCESS`
#### 4b. PILibrary → `PIP_NO_DYNLIB`
- `libs/main/system/pilibrary.h` / `.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_DYNLIB`
#### 4c. PIPluginLoader → `PIP_NO_DYNLIB`
- `libs/main/system/piplugin.h` / `.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_DYNLIB`
#### 4d. PIKbdListener → `PIP_NO_THREADS`
- `libs/main/console/pikbdlistener.h` / `.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_THREADS`
#### 4e. PISerial → `PIP_NO_SERIAL`
- `libs/main/io_devices/piserial.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_SERIAL`
#### 4f. PIWaitEvent → `PIP_NO_THREADS`
- `libs/main/core/piwaitevent_p.h` / `.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_THREADS`
#### 4g. PIFFT → `PIP_NO_FFT`
- `libs/main/math/pifft.h` / `.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_FFT`
#### 4h. PITerminal → `PIP_NO_PROCESS`
- `libs/console/piterminal.cpp`: `#ifndef MICRO_PIP``#ifndef PIP_NO_PROCESS`
#### 4i. PIInit → композитная проверка
- `piinit.h`: композитный макрос `_PIP_INIT_STUB_`
- `piinit.cpp`, `piinit.h`, `piincludes.h`: `MICRO_PIP``_PIP_INIT_STUB_`
---
### Шаг 5. Частичные MICRO_PIP
#### 5a. __PIThreadCollection → `PIP_NO_THREADS`
- `pithread.h` / `.cpp`: все `MICRO_PIP``PIP_NO_THREADS`
#### 5b. PIObject diagnostics
- `piobject.h`: `PIIntrospection` friend → `PIP_INTROSPECTION`, убрать `PIObjectManager`, `dumpApplication` без guard
- `piobject.cpp`: includes по фичам, mutex → `PIP_NO_THREADS`
#### 5c. Buffer sizes → убрать ветки, оставить дефолтные
#### 5d. piscreen → `PIP_NO_PROCESS`
#### 5e. PISystemMonitor → `PIP_NO_PROCESS` / `PIP_NO_FILESYSTEM`
#### 5f. PIFile → `PICO_SDK` / `LINUX` / `FREE_BSD`
#### 5g. Time functions → `PICO_SDK` / `FREERTOS` / `PIP_NO_FILESYSTEM`
#### 5h. Variants → RTTI check / `PIP_NO_FILESYSTEM`
#### 5i. System tests → `PIP_NO_FILESYSTEM`
#### 5j. PIIODevice stop → `PIP_NO_THREADS`
#### 5k. PICAN → `PIP_NO_SOCKET` (уже сделано)
---
### Шаг 6. Doxygen/документация
Убрать MICRO_PIP из piplatform.h, pibase_macros.h.
### Шаг 7. Финальная очистка
`grep -r MICRO_PIP` → 0. Убрать PIP_MICRO из CMakeLists.txt.
---
## Порядок выполнения
1. CMakeLists.txt — опции + platform-блоки + add_definitions
2. piplatform.h — убрать MICRO_PIP, оставить PISERIAL_NO_PINS
3. pibase_macros.h — убрать MICRO_PIP, PIP_MIN_MSLEEP (теперь CMake)
4. Файлы целиком (шаг 4)
5. Частичные (шаг 5)
6. Doxygen (шаг 6)
7. grep-проверка (шаг 7)
+55 -50
View File
@@ -22,9 +22,11 @@
#include "piliterals_time.h" #include "piliterals_time.h"
// clang-format off // clang-format off
#ifndef WINDOWS #ifndef WINDOWS
#ifndef PICO_SDK
# include <fcntl.h> # include <fcntl.h>
# include <sys/ioctl.h> # include <sys/ioctl.h>
# include <termios.h> # include <termios.h>
#endif // PICO_SDK
#else #else
# include <wingdi.h> # include <wingdi.h>
# include <wincon.h> # include <wincon.h>
@@ -35,11 +37,12 @@
// clang-format on // clang-format on
#if !defined(PICO_SDK)
using namespace PIScreenTypes; using namespace PIScreenTypes;
PRIVATE_DEFINITION_START(PIScreen::SystemConsole) PRIVATE_DEFINITION_START(PIScreen::SystemConsole)
#ifdef WINDOWS # ifdef WINDOWS
void * hOut; void * hOut;
CONSOLE_SCREEN_BUFFER_INFO sbi, csbi; CONSOLE_SCREEN_BUFFER_INFO sbi, csbi;
CONSOLE_CURSOR_INFO curinfo; CONSOLE_CURSOR_INFO curinfo;
@@ -48,7 +51,7 @@ PRIVATE_DEFINITION_START(PIScreen::SystemConsole)
WORD dattr; WORD dattr;
DWORD smode, written; DWORD smode, written;
PIVector<CHAR_INFO> chars; PIVector<CHAR_INFO> chars;
#endif # endif
PRIVATE_DEFINITION_END(PIScreen::SystemConsole) PRIVATE_DEFINITION_END(PIScreen::SystemConsole)
@@ -59,16 +62,16 @@ PIScreen::SystemConsole::SystemConsole() {
PIScreen::SystemConsole::~SystemConsole() { PIScreen::SystemConsole::~SystemConsole() {
#ifdef WINDOWS # ifdef WINDOWS
SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); SetConsoleMode(PRIVATE->hOut, PRIVATE->smode);
SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr);
#endif # endif
} }
void PIScreen::SystemConsole::begin() { void PIScreen::SystemConsole::begin() {
int w, h; int w, h;
#ifdef WINDOWS # ifdef WINDOWS
PRIVATE->ulcoord.X = 0; PRIVATE->ulcoord.X = 0;
PRIVATE->hOut = GetStdHandle(STD_OUTPUT_HANDLE); PRIVATE->hOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi);
@@ -78,24 +81,24 @@ void PIScreen::SystemConsole::begin() {
PRIVATE->ulcoord.Y = PRIVATE->sbi.srWindow.Top; PRIVATE->ulcoord.Y = PRIVATE->sbi.srWindow.Top;
GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode); GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode);
GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo);
#else # else
# ifdef MICRO_PIP # ifdef PIP_EMBEDDED
w = 80; w = 80;
h = 24; h = 24;
# else # else
winsize ws; winsize ws;
ioctl(0, TIOCGWINSZ, &ws); ioctl(0, TIOCGWINSZ, &ws);
w = ws.ws_col; w = ws.ws_col;
h = ws.ws_row; h = ws.ws_row;
# endif
# endif # endif
#endif
resize(w, h); resize(w, h);
#ifdef WINDOWS # ifdef WINDOWS
SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT); SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT);
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi);
PRIVATE->bc.X = 0; PRIVATE->bc.X = 0;
PRIVATE->bc.Y = 0; PRIVATE->bc.Y = 0;
#endif # endif
clear(); clear();
clearScreen(); clearScreen();
hideCursor(); hideCursor();
@@ -103,11 +106,11 @@ void PIScreen::SystemConsole::begin() {
void PIScreen::SystemConsole::end() { void PIScreen::SystemConsole::end() {
#ifdef WINDOWS # ifdef WINDOWS
SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr);
#else # else
printf("\e[0m"); printf("\e[0m");
#endif # endif
moveTo(0, height); moveTo(0, height);
showCursor(); showCursor();
} }
@@ -115,18 +118,18 @@ void PIScreen::SystemConsole::end() {
void PIScreen::SystemConsole::prepare() { void PIScreen::SystemConsole::prepare() {
int w = 80, h = 24; int w = 80, h = 24;
#ifdef WINDOWS # ifdef WINDOWS
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->csbi); GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->csbi);
w = PRIVATE->csbi.srWindow.Right - PRIVATE->csbi.srWindow.Left + 1; w = PRIVATE->csbi.srWindow.Right - PRIVATE->csbi.srWindow.Left + 1;
h = PRIVATE->csbi.srWindow.Bottom - PRIVATE->csbi.srWindow.Top + 1; h = PRIVATE->csbi.srWindow.Bottom - PRIVATE->csbi.srWindow.Top + 1;
#else # else
# ifndef MICRO_PIP # ifndef PIP_EMBEDDED
winsize ws; winsize ws;
ioctl(0, TIOCGWINSZ, &ws); ioctl(0, TIOCGWINSZ, &ws);
w = ws.ws_col; w = ws.ws_col;
h = ws.ws_row; h = ws.ws_row;
# endif
# endif # endif
#endif
resize(w, h); resize(w, h);
} }
@@ -149,10 +152,10 @@ void PIScreen::SystemConsole::resize(int w, int h) {
cells[i].resize(width); cells[i].resize(width);
pcells[i].resize(width, Cell(PIChar())); pcells[i].resize(width, Cell(PIChar()));
} }
#ifdef WINDOWS # ifdef WINDOWS
PRIVATE->sbi.srWindow = PRIVATE->csbi.srWindow; PRIVATE->sbi.srWindow = PRIVATE->csbi.srWindow;
PRIVATE->chars.resize(width * height); PRIVATE->chars.resize(width * height);
#endif # endif
for (int i = 0; i < pcells.size_s(); ++i) for (int i = 0; i < pcells.size_s(); ++i)
pcells[i].fill(Cell()); pcells[i].fill(Cell());
clear(); clear();
@@ -164,7 +167,7 @@ void PIScreen::SystemConsole::print() {
if (mouse_x >= 0 && mouse_x < width && mouse_y >= 0 && mouse_y < height) { if (mouse_x >= 0 && mouse_x < width && mouse_y >= 0 && mouse_y < height) {
/// cells[mouse_y][mouse_x].format.flags ^= Inverse; /// cells[mouse_y][mouse_x].format.flags ^= Inverse;
} }
#ifdef WINDOWS # ifdef WINDOWS
PRIVATE->srect = PRIVATE->sbi.srWindow; PRIVATE->srect = PRIVATE->sbi.srWindow;
int dx0 = -1, dx1 = -1, dy0 = -1, dy1 = -1; int dx0 = -1, dx1 = -1, dy0 = -1, dy1 = -1;
for (int j = 0; j < height; ++j) { for (int j = 0; j < height; ++j) {
@@ -201,7 +204,7 @@ void PIScreen::SystemConsole::print() {
PRIVATE->srect.Right -= width - dx1 - 1; PRIVATE->srect.Right -= width - dx1 - 1;
PRIVATE->srect.Bottom -= height - dy1 - 1; PRIVATE->srect.Bottom -= height - dy1 - 1;
WriteConsoleOutputW(PRIVATE->hOut, PRIVATE->chars.data(), PRIVATE->bs, PRIVATE->bc, &PRIVATE->srect); WriteConsoleOutputW(PRIVATE->hOut, PRIVATE->chars.data(), PRIVATE->bs, PRIVATE->bc, &PRIVATE->srect);
#else # else
PIString s; PIString s;
int si = 0, sj = 0; int si = 0, sj = 0;
CellFormat prf(0xFFFF); CellFormat prf(0xFFFF);
@@ -238,14 +241,14 @@ void PIScreen::SystemConsole::print() {
} }
printf("\e[0m"); printf("\e[0m");
fflush(0); fflush(0);
#endif # endif
pcells = cells; pcells = cells;
} }
#ifdef WINDOWS # ifdef WINDOWS
# define FOREGROUND_MASK (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) # define FOREGROUND_MASK (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
# define BACKGROUND_MASK (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE) # define BACKGROUND_MASK (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
ushort PIScreen::SystemConsole::attributes(const PIScreenTypes::Cell & c) { ushort PIScreen::SystemConsole::attributes(const PIScreenTypes::Cell & c) {
WORD attr = PRIVATE->dattr; WORD attr = PRIVATE->dattr;
if (c.format.flags & Bold) if (c.format.flags & Bold)
@@ -284,8 +287,8 @@ ushort PIScreen::SystemConsole::attributes(const PIScreenTypes::Cell & c) {
} }
return attr; return attr;
} }
# undef FOREGROUND_MASK # undef FOREGROUND_MASK
# undef BACKGROUND_MASK # undef BACKGROUND_MASK
void PIScreen::SystemConsole::getWinCurCoord() { void PIScreen::SystemConsole::getWinCurCoord() {
GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->csbi); GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->csbi);
@@ -304,7 +307,7 @@ void PIScreen::SystemConsole::newLine() {
PRIVATE->ccoord.Y++; PRIVATE->ccoord.Y++;
SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord); SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord);
} }
#else // WINDOWS # else // WINDOWS
PIString PIScreen::SystemConsole::formatString(const PIScreenTypes::Cell & c) { PIString PIScreen::SystemConsole::formatString(const PIScreenTypes::Cell & c) {
PIString ts = PIStringAscii("\e[0"); PIString ts = PIStringAscii("\e[0");
switch (c.format.color_char) { switch (c.format.color_char) {
@@ -333,39 +336,39 @@ PIString PIScreen::SystemConsole::formatString(const PIScreenTypes::Cell & c) {
if ((c.format.flags & Inverse) == Inverse) ts += PIStringAscii(";7"); if ((c.format.flags & Inverse) == Inverse) ts += PIStringAscii(";7");
return ts + 'm'; return ts + 'm';
} }
#endif // WINDOWS # endif // WINDOWS
void PIScreen::SystemConsole::toUpperLeft() { void PIScreen::SystemConsole::toUpperLeft() {
#ifdef WINDOWS # ifdef WINDOWS
SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ulcoord); SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ulcoord);
#else # else
printf("\e[H"); printf("\e[H");
#endif # endif
} }
void PIScreen::SystemConsole::moveTo(int x, int y) { void PIScreen::SystemConsole::moveTo(int x, int y) {
#ifdef WINDOWS # ifdef WINDOWS
PRIVATE->ccoord.X = x; PRIVATE->ccoord.X = x;
PRIVATE->ccoord.Y = PRIVATE->ulcoord.Y + y; PRIVATE->ccoord.Y = PRIVATE->ulcoord.Y + y;
SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord); SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord);
#else # else
printf("\e[%d;%dH", y + 1, x + 1); printf("\e[%d;%dH", y + 1, x + 1);
#endif # endif
} }
void PIScreen::SystemConsole::clearScreen() { void PIScreen::SystemConsole::clearScreen() {
#ifdef WINDOWS # ifdef WINDOWS
toUpperLeft(); toUpperLeft();
FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written); FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written);
FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written); FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written);
#else # else
printf("\e[0m\e[H\e[J"); printf("\e[0m\e[H\e[J");
#endif # endif
} }
void PIScreen::SystemConsole::clearScreenLower() { void PIScreen::SystemConsole::clearScreenLower() {
#ifdef WINDOWS # ifdef WINDOWS
getWinCurCoord(); getWinCurCoord();
FillConsoleOutputAttribute(PRIVATE->hOut, FillConsoleOutputAttribute(PRIVATE->hOut,
PRIVATE->dattr, PRIVATE->dattr,
@@ -377,27 +380,27 @@ void PIScreen::SystemConsole::clearScreenLower() {
width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X,
PRIVATE->ccoord, PRIVATE->ccoord,
&PRIVATE->written); &PRIVATE->written);
#else # else
printf("\e[0m\e[J"); printf("\e[0m\e[J");
#endif # endif
} }
void PIScreen::SystemConsole::hideCursor() { void PIScreen::SystemConsole::hideCursor() {
#ifdef WINDOWS # ifdef WINDOWS
PRIVATE->curinfo.bVisible = false; PRIVATE->curinfo.bVisible = false;
SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo);
#else # else
printf("\e[?25l"); printf("\e[?25l");
#endif # endif
} }
void PIScreen::SystemConsole::showCursor() { void PIScreen::SystemConsole::showCursor() {
#ifdef WINDOWS # ifdef WINDOWS
PRIVATE->curinfo.bVisible = true; PRIVATE->curinfo.bVisible = true;
SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo);
#else # else
printf("\e[?25h"); printf("\e[?25h");
#endif # endif
} }
@@ -602,9 +605,9 @@ void PIScreen::start(bool wait) {
void PIScreen::stop(bool clear) { void PIScreen::stop(bool clear) {
PIThread::stopAndWait(); PIThread::stopAndWait();
if (clear) console.clearScreen(); if (clear) console.clearScreen();
#ifndef WINDOWS # ifndef WINDOWS
fflush(0); fflush(0);
#endif # endif
} }
@@ -657,3 +660,5 @@ PIScreenTile * PIScreen::tileByName(const PIString & name) {
if (t->name() == name) return t; if (t->name() == name) return t;
return 0; return 0;
} }
#endif // !PICO_SDK
+8
View File
@@ -19,6 +19,10 @@
#include "piscreendrawer.h" #include "piscreendrawer.h"
#if !defined(PICO_SDK)
#if !defined(PICO_SDK)
// comment for use ascii instead of unicode symbols // comment for use ascii instead of unicode symbols
#define USE_UNICODE #define USE_UNICODE
@@ -264,3 +268,7 @@ void PIScreenDrawer::drawText(int x, int y, const PIString & s, Color col_char,
} }
} }
} }
#endif // !PICO_SDK
#endif // !PICO_SDK
+8
View File
@@ -21,6 +21,10 @@
#include "piscreendrawer.h" #include "piscreendrawer.h"
#if !defined(PICO_SDK)
#if !defined(PICO_SDK)
using namespace PIScreenTypes; using namespace PIScreenTypes;
@@ -255,3 +259,7 @@ void PIScreenTile::layout() {
t->layout(); t->layout();
} }
} }
#endif // !PICO_SDK
#endif // !PICO_SDK
+8
View File
@@ -21,6 +21,10 @@
#include "piscreendrawer.h" #include "piscreendrawer.h"
#if !defined(PICO_SDK)
#if !defined(PICO_SDK)
using namespace PIScreenTypes; using namespace PIScreenTypes;
@@ -692,3 +696,7 @@ void TileInput::reserCursor() {
tm_blink.reset(); tm_blink.reset();
inv = false; inv = false;
} }
#endif // !PICO_SDK
#endif // !PICO_SDK
+9 -5
View File
@@ -21,7 +21,9 @@
#include "piincludes_p.h" #include "piincludes_p.h"
#include "piliterals_time.h" #include "piliterals_time.h"
#include "pisharedmemory.h" #include "pisharedmemory.h"
#ifndef MICRO_PIP
#if !defined(PICO_SDK)
#ifndef PIP_NO_PROCESS
# ifdef WINDOWS # ifdef WINDOWS
# include <windows.h> # include <windows.h>
# include <wingdi.h> # include <wingdi.h>
@@ -346,8 +348,8 @@ void PITerminal::getCursor(int & x, int & y) {
int sz = 0; int sz = 0;
PRIVATE->shm->read(&sz, 4); PRIVATE->shm->read(&sz, 4);
# else # else
x = PRIVATE->cur_x; x = PRIVATE->cur_x;
y = PRIVATE->cur_y; y = PRIVATE->cur_y;
# endif # endif
} }
@@ -934,7 +936,7 @@ void PITerminal::destroy() {
} }
if (PRIVATE->pipe != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->pipe); if (PRIVATE->pipe != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->pipe);
if (PRIVATE->hConBuf != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->hConBuf); if (PRIVATE->hConBuf != INVALID_HANDLE_VALUE) CloseHandle(PRIVATE->hConBuf);
// piCout << "destroy" << size_y; // piCout << "destroy" << size_y;
# else # else
# ifdef HAS_FORKPTY # ifdef HAS_FORKPTY
if (PRIVATE->pid != 0) kill(PRIVATE->pid, SIGKILL); if (PRIVATE->pid != 0) kill(PRIVATE->pid, SIGKILL);
@@ -977,4 +979,6 @@ bool PITerminal::resize(int cols, int rows) {
return ret; return ret;
} }
#endif // MICRO_PIP #endif // PIP_NO_PROCESS
#endif // !PICO_SDK
+7 -3
View File
@@ -21,6 +21,8 @@
#include "piliterals_time.h" #include "piliterals_time.h"
#ifndef PIP_NO_SOCKET
/** \class PIBroadcast /** \class PIBroadcast
* \brief Broadcast for all interfaces, including loopback * \brief Broadcast for all interfaces, including loopback
* *
@@ -43,7 +45,7 @@
* *
*/ */
#define MULTICAST_TTL 4 # define MULTICAST_TTL 4
PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() { PIBroadcast::PIBroadcast(bool send_only): PIThread(), PIEthUtilBase() {
@@ -205,8 +207,8 @@ void PIBroadcast::initAll(PIVector<PINetworkAddress> al) {
void PIBroadcast::send(const PIByteArray & data) { void PIBroadcast::send(const PIByteArray & data) {
/*if (!isRunning()) { /*if (!isRunning()) {
reinit(); reinit();
PIThread::start(3000); PIThread::start(3000);
}*/ }*/
PIByteArray cd = cryptData(data); PIByteArray cd = cryptData(data);
if (cd.isEmpty()) return; if (cd.isEmpty()) return;
@@ -268,3 +270,5 @@ void PIBroadcast::run() {
if (ac || r) reinit(); if (ac || r) reinit();
if (ac) addressesChanged(); if (ac) addressesChanged();
} }
#endif // PIP_NO_SOCKET
+4
View File
@@ -19,6 +19,8 @@
#include "piethutilbase.h" #include "piethutilbase.h"
#ifndef PIP_NO_SOCKET
#include "pitranslator.h" #include "pitranslator.h"
#ifdef PIP_CRYPT #ifdef PIP_CRYPT
# include "picrypt.h" # include "picrypt.h"
@@ -129,3 +131,5 @@ size_t PIEthUtilBase::cryptSizeAddition() {
return 0; return 0;
#endif #endif
} }
#endif // PIP_NO_SOCKET
+4
View File
@@ -22,6 +22,8 @@
#include "piethernet.h" #include "piethernet.h"
#include "piliterals.h" #include "piliterals.h"
#ifndef PIP_NO_SOCKET
/** \class PIPackedTCP pipackedtcp.h /** \class PIPackedTCP pipackedtcp.h
* \brief * \brief
@@ -197,3 +199,5 @@ bool PIPackedTCP::closeDevice() {
} }
return eth->close(); return eth->close();
} }
#endif // PIP_NO_SOCKET
+4
View File
@@ -25,6 +25,8 @@
#include "piiodevice.h" #include "piiodevice.h"
#include "pitranslator.h" #include "pitranslator.h"
#ifndef PIP_NO_SOCKET
#ifdef __GNUC__ #ifdef __GNUC__
# pragma GCC diagnostic pop # pragma GCC diagnostic pop
#endif #endif
@@ -174,3 +176,5 @@ void PIStreamPacker::assignDevice(PIIODevice * dev) {
uint PIStreamPacker::sizeCryptedSize() { uint PIStreamPacker::sizeCryptedSize() {
return sizeof(int) + (crypt_size ? cryptSizeAddition() : 0); return sizeof(int) + (crypt_size ? cryptSizeAddition() : 0);
} }
#endif // PIP_NO_SOCKET
+14 -9
View File
@@ -1,6 +1,6 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
High-level log High-level log
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -24,6 +24,8 @@
#include "piliterals_time.h" #include "piliterals_time.h"
#include "pitime.h" #include "pitime.h"
#ifndef PIP_NO_THREADS
# ifndef PIP_NO_FILESYSTEM
//! \class PILog pilog.h //! \class PILog pilog.h
//! \details //! \details
@@ -124,12 +126,12 @@ PIStringList PILog::readAllLogs() const {
auto it = names.makeIterator(); auto it = names.makeIterator();
bool was_own = false; bool was_own = false;
auto readFile = [&ret](PIFile * f) { auto readFile = [&ret](PIFile * f) {
PIIOTextStream ts(f); PIIOTextStream ts(f);
PIString line; PIString line;
while (!ts.isEnd()) { while (!ts.isEnd()) {
line = ts.readLine().trim(); line = ts.readLine().trim();
if (line.isNotEmpty()) ret << line; if (line.isNotEmpty()) ret << line;
} }
}; };
while (it.next()) { while (it.next()) {
PIFile * f = nullptr; PIFile * f = nullptr;
@@ -203,8 +205,8 @@ void PILog::newFile() {
PIString aname = log_name; PIString aname = log_name;
if (aname.isNotEmpty()) aname += "__"; if (aname.isNotEmpty()) aname += "__";
log_file.open(log_dir + "/" + aname + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss") + ".log." + log_file.open(log_dir + "/" + aname + PIDateTime::current().toString("yyyy_MM_dd__hh_mm_ss") + ".log." +
PIString::fromNumber(++part_number), PIString::fromNumber(++part_number),
PIIODevice::ReadWrite); PIIODevice::ReadWrite);
} }
@@ -245,3 +247,6 @@ void PILog::run() {
} }
} }
} }
# endif // PIP_NO_FILESYSTEM
#endif // PIP_NO_THREADS
+7 -1
View File
@@ -29,6 +29,9 @@
#include "piiostream.h" #include "piiostream.h"
#include "pithread.h" #include "pithread.h"
#ifndef PIP_NO_THREADS
# ifndef PIP_NO_FILESYSTEM
//! \~\ingroup Application //! \~\ingroup Application
//! \~\brief //! \~\brief
//! \~english High-level log //! \~english High-level log
@@ -184,4 +187,7 @@ private:
int part_number = -1, cout_id = -1; int part_number = -1, cout_id = -1;
}; };
#endif # endif // PIP_NO_FILESYSTEM
#endif // PIP_NO_THREADS
#endif // PIlog_H
@@ -24,6 +24,7 @@
#include "pisharedmemory.h" #include "pisharedmemory.h"
#include "pitime.h" #include "pitime.h"
#ifndef PIP_NO_THREADS
//! \class PISingleApplication pisingleapplication.h //! \class PISingleApplication pisingleapplication.h
//! \~\details //! \~\details
@@ -64,7 +65,7 @@
//! //!
#define SHM_SIZE 32_KiB # define SHM_SIZE 32_KiB
PISingleApplication::PISingleApplication(const PIString & app_name): PIThread() { PISingleApplication::PISingleApplication(const PIString & app_name): PIThread() {
@@ -150,3 +151,5 @@ void PISingleApplication::waitFirst() const {
while (!started) while (!started)
piMSleep(50); piMSleep(50);
} }
#endif // PIP_NO_THREADS
@@ -29,6 +29,8 @@
class PISharedMemory; class PISharedMemory;
#ifndef PIP_NO_THREADS
//! \~\ingroup Application //! \~\ingroup Application
//! \~\brief //! \~\brief
//! \~english Single-instance application control. //! \~english Single-instance application control.
@@ -92,4 +94,5 @@ private:
int sacnt; int sacnt;
}; };
#endif // PIP_NO_THREADS
#endif // PISINGLEAPPLICATION_H #endif // PISINGLEAPPLICATION_H
+56 -53
View File
@@ -40,6 +40,7 @@ struct kqueue_id_t;
# include "esp_heap_caps.h" # include "esp_heap_caps.h"
#endif #endif
#ifndef PIP_NO_THREADS
void PISystemMonitor::ProcessStats::makeStrings() { void PISystemMonitor::ProcessStats::makeStrings() {
physical_memsize_readable.setReadableSize(physical_memsize); physical_memsize_readable.setReadableSize(physical_memsize);
@@ -50,43 +51,43 @@ void PISystemMonitor::ProcessStats::makeStrings() {
} }
#ifndef MICRO_PIP # ifndef PIP_NO_PROCESS
PRIVATE_DEFINITION_START(PISystemMonitor) PRIVATE_DEFINITION_START(PISystemMonitor)
# ifndef WINDOWS # ifndef WINDOWS
# ifdef MAC_OS # ifdef MAC_OS
PISystemTime PISystemTime
# else # else
llong llong
# endif # endif
cpu_u_cur, cpu_u_cur,
cpu_u_prev, cpu_s_cur, cpu_s_prev; cpu_u_prev, cpu_s_cur, cpu_s_prev;
PIString proc_dir; PIString proc_dir;
PIFile file, filem; PIFile file, filem;
# else # else
HANDLE hProc; HANDLE hProc;
PROCESS_MEMORY_COUNTERS mem_cnt; PROCESS_MEMORY_COUNTERS mem_cnt;
PISystemTime tm_kernel, tm_user; PISystemTime tm_kernel, tm_user;
PITimeMeasurer tm; PITimeMeasurer tm;
# endif # endif
PRIVATE_DEFINITION_END(PISystemMonitor) PRIVATE_DEFINITION_END(PISystemMonitor)
#endif # endif // PIP_NO_PROCESS
PISystemMonitor::PISystemMonitor(): PIThread() { PISystemMonitor::PISystemMonitor(): PIThread() {
pID_ = cycle = 0; pID_ = cycle = 0;
cpu_count = PISystemInfo::instance()->processorsCount; cpu_count = PISystemInfo::instance()->processorsCount;
#ifndef MICRO_PIP # ifndef PIP_NO_PROCESS
# ifndef WINDOWS # ifndef WINDOWS
# ifdef QNX # ifdef QNX
page_size = 4096; page_size = 4096;
# else # else
page_size = getpagesize(); page_size = getpagesize();
# endif # endif
# else # else
PRIVATE->hProc = 0; PRIVATE->hProc = 0;
PRIVATE->mem_cnt.cb = sizeof(PRIVATE->mem_cnt); PRIVATE->mem_cnt.cb = sizeof(PRIVATE->mem_cnt);
# endif # endif
#endif # endif // PIP_NO_PROCESS
setName("system_monitor"_a); setName("system_monitor"_a);
} }
@@ -96,14 +97,14 @@ PISystemMonitor::~PISystemMonitor() {
} }
#ifndef MICRO_PIP # ifndef PIP_NO_PROCESS
bool PISystemMonitor::startOnProcess(int pID, PISystemTime interval) { bool PISystemMonitor::startOnProcess(int pID, PISystemTime interval) {
stop(); stop();
pID_ = pID; pID_ = pID;
Pool::instance()->add(this); Pool::instance()->add(this);
cycle = -1; cycle = -1;
# ifndef WINDOWS # ifndef WINDOWS
# ifndef MAC_OS # ifndef MAC_OS
PRIVATE->proc_dir = PIStringAscii("/proc/") + PIString::fromNumber(pID_) + PIStringAscii("/"); PRIVATE->proc_dir = PIStringAscii("/proc/") + PIString::fromNumber(pID_) + PIStringAscii("/");
PRIVATE->file.open(PRIVATE->proc_dir + "stat", PIIODevice::ReadOnly); PRIVATE->file.open(PRIVATE->proc_dir + "stat", PIIODevice::ReadOnly);
PRIVATE->filem.open(PRIVATE->proc_dir + "statm", PIIODevice::ReadOnly); PRIVATE->filem.open(PRIVATE->proc_dir + "statm", PIIODevice::ReadOnly);
@@ -111,27 +112,27 @@ bool PISystemMonitor::startOnProcess(int pID, PISystemTime interval) {
piCoutObj << "Can`t find process with ID = %1!"_tr("PISystemMonitor").arg(pID_); piCoutObj << "Can`t find process with ID = %1!"_tr("PISystemMonitor").arg(pID_);
return false; return false;
} }
# endif # endif
# else # else
PRIVATE->hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pID_); PRIVATE->hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pID_);
if (PRIVATE->hProc == 0) { if (PRIVATE->hProc == 0) {
piCoutObj << "Can`t open process with ID = %1, %2!"_tr("PISystemMonitor").arg(pID_).arg(errorString()); piCoutObj << "Can`t open process with ID = %1, %2!"_tr("PISystemMonitor").arg(pID_).arg(errorString());
return false; return false;
} }
PRIVATE->tm.reset(); PRIVATE->tm.reset();
# endif # endif
return start(interval); return start(interval);
} }
#endif # endif // PIP_NO_PROCESS
bool PISystemMonitor::startOnSelf(PISystemTime interval) { bool PISystemMonitor::startOnSelf(PISystemTime interval) {
#ifndef MICRO_PIP # ifndef PIP_NO_PROCESS
bool ret = startOnProcess(PIProcess::currentPID(), interval); bool ret = startOnProcess(PIProcess::currentPID(), interval);
cycle = -1; cycle = -1;
#else # else
bool ret = start(interval); bool ret = start(interval);
#endif # endif // PIP_NO_PROCESS
return ret; return ret;
} }
@@ -153,12 +154,12 @@ void PISystemMonitor::setStatistic(const PISystemMonitor::ProcessStats & s) {
void PISystemMonitor::stop() { void PISystemMonitor::stop() {
PIThread::stopAndWait(); PIThread::stopAndWait();
#ifdef WINDOWS # ifdef WINDOWS
if (PRIVATE->hProc != 0) { if (PRIVATE->hProc != 0) {
CloseHandle(PRIVATE->hProc); CloseHandle(PRIVATE->hProc);
PRIVATE->hProc = 0; PRIVATE->hProc = 0;
} }
#endif # endif
Pool::instance()->remove(this); Pool::instance()->remove(this);
} }
@@ -169,18 +170,18 @@ PISystemMonitor::ProcessStats PISystemMonitor::statistic() const {
} }
#ifdef MAC_OS # ifdef MAC_OS
PISystemTime uint64toST(uint64_t v) { PISystemTime uint64toST(uint64_t v) {
return PISystemTime(((uint *)&(v))[1], ((uint *)&(v))[0]); return PISystemTime(((uint *)&(v))[1], ((uint *)&(v))[0]);
} }
#endif # endif
void PISystemMonitor::run() { void PISystemMonitor::run() {
cur_tm.clear(); cur_tm.clear();
tbid.clear(); tbid.clear();
ProcessStats tstat; ProcessStats tstat;
tstat.ID = pID_; tstat.ID = pID_;
#ifndef PIP_NO_THREADS # ifndef PIP_NO_THREADS
__PIThreadCollection * pitc = __PIThreadCollection::instance(); __PIThreadCollection * pitc = __PIThreadCollection::instance();
pitc->lock(); pitc->lock();
PIVector<PIThread *> tv = pitc->threads(); PIVector<PIThread *> tv = pitc->threads();
@@ -188,14 +189,14 @@ void PISystemMonitor::run() {
if (t->isPIObject()) tbid[t->tid()] = t->name(); if (t->isPIObject()) tbid[t->tid()] = t->name();
pitc->unlock(); pitc->unlock();
// piCout << tbid.keys().toType<uint>(); // piCout << tbid.keys().toType<uint>();
# ifdef FREERTOS # ifdef FREERTOS
for (auto * t: tv) for (auto * t: tv)
if (t->isPIObject()) gatherThread(t->tid()); if (t->isPIObject()) gatherThread(t->tid());
# else // FREERTOS # else // FREERTOS
# ifndef WINDOWS # ifndef WINDOWS
double delay_ms = delay_.toMilliseconds(); double delay_ms = delay_.toMilliseconds();
tbid[pID_] = "main"; tbid[pID_] = "main";
# ifdef MAC_OS # ifdef MAC_OS
rusage_info_current ru; rusage_info_current ru;
proc_pid_rusage(pID_, RUSAGE_INFO_CURRENT, (rusage_info_t *)&ru); proc_pid_rusage(pID_, RUSAGE_INFO_CURRENT, (rusage_info_t *)&ru);
// piCout << PISystemTime(((uint*)&(ru.ri_user_time))[1], ((uint*)&(ru.ri_user_time))[0]); // piCout << PISystemTime(((uint*)&(ru.ri_user_time))[1], ((uint*)&(ru.ri_user_time))[0]);
@@ -211,7 +212,7 @@ void PISystemMonitor::run() {
tstat.cpu_load_user = 100.f * (PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev).toMilliseconds() / delay_ms; tstat.cpu_load_user = 100.f * (PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev).toMilliseconds() / delay_ms;
cycle = 0; cycle = 0;
// piCout << (PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev).toMilliseconds() / delay_ms; // piCout << (PRIVATE->cpu_u_cur - PRIVATE->cpu_u_prev).toMilliseconds() / delay_ms;
# else // MAC_OS # else // MAC_OS
PRIVATE->file.seekToBegin(); PRIVATE->file.seekToBegin();
PIString str = PIString::fromAscii(PRIVATE->file.readAll()); PIString str = PIString::fromAscii(PRIVATE->file.readAll());
int si = str.find('(') + 1, fi = 0, cc = 1; int si = str.find('(') + 1, fi = 0, cc = 1;
@@ -265,8 +266,8 @@ void PISystemMonitor::run() {
if (i.flags[PIFile::FileInfo::Dot] || i.flags[PIFile::FileInfo::DotDot]) continue; if (i.flags[PIFile::FileInfo::Dot] || i.flags[PIFile::FileInfo::DotDot]) continue;
gatherThread(i.name().toInt()); gatherThread(i.name().toInt());
} }
# endif // MAC_OS # endif // MAC_OS
# else // WINDOWS # else // WINDOWS
if (GetProcessMemoryInfo(PRIVATE->hProc, &PRIVATE->mem_cnt, sizeof(PRIVATE->mem_cnt)) != 0) { if (GetProcessMemoryInfo(PRIVATE->hProc, &PRIVATE->mem_cnt, sizeof(PRIVATE->mem_cnt)) != 0) {
tstat.physical_memsize = PRIVATE->mem_cnt.WorkingSetSize; tstat.physical_memsize = PRIVATE->mem_cnt.WorkingSetSize;
} }
@@ -316,9 +317,9 @@ void PISystemMonitor::run() {
tstat.cpu_load_user = 0.f; tstat.cpu_load_user = 0.f;
} }
PRIVATE->tm.reset(); PRIVATE->tm.reset();
# endif // WINDOWS # endif // WINDOWS
# endif // FREERTOS # endif // FREERTOS
#endif // PIP_NO_THREADS # endif // PIP_NO_THREADS
tstat.cpu_load_system = piClampf(tstat.cpu_load_system, 0.f, 100.f); tstat.cpu_load_system = piClampf(tstat.cpu_load_system, 0.f, 100.f);
tstat.cpu_load_user = piClampf(tstat.cpu_load_user, 0.f, 100.f); tstat.cpu_load_user = piClampf(tstat.cpu_load_user, 0.f, 100.f);
@@ -351,11 +352,11 @@ void PISystemMonitor::gatherThread(llong id) {
PISystemMonitor::ThreadStats ts; PISystemMonitor::ThreadStats ts;
if (id == 0) return; if (id == 0) return;
ts.id = id; ts.id = id;
#ifdef MICRO_PIP # ifdef PIP_NO_PROCESS
ts.name = tbid.value(id, "<PIThread>"); ts.name = tbid.value(id, "<PIThread>");
#else # else
ts.name = tbid.value(id, "<non-PIThread>"); ts.name = tbid.value(id, "<non-PIThread>");
# ifndef WINDOWS # ifndef WINDOWS
PIFile f(PRIVATE->proc_dir + "task/" + PIString::fromNumber(id) + "/stat"); PIFile f(PRIVATE->proc_dir + "task/" + PIString::fromNumber(id) + "/stat");
// piCout << f.path(); // piCout << f.path();
if (!f.open(PIIODevice::ReadOnly)) return; if (!f.open(PIIODevice::ReadOnly)) return;
@@ -375,7 +376,7 @@ void PISystemMonitor::gatherThread(llong id) {
// piCout << sl[0] << sl[12] << sl[13]; // piCout << sl[0] << sl[12] << sl[13];
ts.user_time = PISystemTime::fromMilliseconds(sl[12].toInt() * 10.); ts.user_time = PISystemTime::fromMilliseconds(sl[12].toInt() * 10.);
ts.kernel_time = PISystemTime::fromMilliseconds(sl[13].toInt() * 10.); ts.kernel_time = PISystemTime::fromMilliseconds(sl[13].toInt() * 10.);
# else # else
PISystemTime ct = PISystemTime::current(); PISystemTime ct = PISystemTime::current();
FILETIME times[4]; FILETIME times[4];
HANDLE thdl = OpenThread(THREAD_QUERY_INFORMATION, FALSE, DWORD(id)); HANDLE thdl = OpenThread(THREAD_QUERY_INFORMATION, FALSE, DWORD(id));
@@ -393,8 +394,8 @@ void PISystemMonitor::gatherThread(llong id) {
ts.work_time = ct - ts.created.toSystemTime(); ts.work_time = ct - ts.created.toSystemTime();
ts.kernel_time = FILETIME2PISystemTime(times[2]); ts.kernel_time = FILETIME2PISystemTime(times[2]);
ts.user_time = FILETIME2PISystemTime(times[3]); ts.user_time = FILETIME2PISystemTime(times[3]);
# endif # endif
#endif # endif // PIP_NO_PROCESS
cur_tm[id] = ts; cur_tm[id] = ts;
} }
@@ -406,34 +407,34 @@ float PISystemMonitor::calcThreadUsage(PISystemTime & t_new, PISystemTime & t_ol
ullong PISystemMonitor::totalRAM() { ullong PISystemMonitor::totalRAM() {
#ifdef ESP_PLATFORM # ifdef ESP_PLATFORM
multi_heap_info_t heap_info; multi_heap_info_t heap_info;
piZeroMemory(heap_info); piZeroMemory(heap_info);
heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT); heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT);
return heap_info.total_allocated_bytes + heap_info.total_free_bytes; return heap_info.total_allocated_bytes + heap_info.total_free_bytes;
#endif # endif
return 0; return 0;
} }
ullong PISystemMonitor::freeRAM() { ullong PISystemMonitor::freeRAM() {
#ifdef ESP_PLATFORM # ifdef ESP_PLATFORM
multi_heap_info_t heap_info; multi_heap_info_t heap_info;
piZeroMemory(heap_info); piZeroMemory(heap_info);
heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT); heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT);
return heap_info.total_free_bytes; return heap_info.total_free_bytes;
#endif # endif
return 0; return 0;
} }
ullong PISystemMonitor::usedRAM() { ullong PISystemMonitor::usedRAM() {
#ifdef ESP_PLATFORM # ifdef ESP_PLATFORM
multi_heap_info_t heap_info; multi_heap_info_t heap_info;
piZeroMemory(heap_info); piZeroMemory(heap_info);
heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT); heap_caps_get_info(&heap_info, MALLOC_CAP_8BIT);
return heap_info.total_allocated_bytes; return heap_info.total_allocated_bytes;
#endif # endif
return 0; return 0;
} }
@@ -460,3 +461,5 @@ void PISystemMonitor::Pool::remove(PISystemMonitor * sm) {
PIMutexLocker _ml(mutex); PIMutexLocker _ml(mutex);
sysmons.remove(sm->pID()); sysmons.remove(sm->pID());
} }
#endif // PIP_NO_THREADS
+8 -6
View File
@@ -28,6 +28,7 @@
#include "pifile.h" #include "pifile.h"
#include "pithread.h" #include "pithread.h"
#ifndef PIP_NO_THREADS
//! \~\ingroup Application //! \~\ingroup Application
//! \~\brief //! \~\brief
@@ -51,7 +52,7 @@ public:
//! \~russian Останавливает мониторинг и отсоединяет объект от текущей цели. //! \~russian Останавливает мониторинг и отсоединяет объект от текущей цели.
~PISystemMonitor(); ~PISystemMonitor();
#pragma pack(push, 1) # pragma pack(push, 1)
//! \~\ingroup Application //! \~\ingroup Application
//! \~\brief //! \~\brief
//! \~english Process statistics (fixed-size fields). //! \~english Process statistics (fixed-size fields).
@@ -155,7 +156,7 @@ public:
//! \~russian Дата и время создания //! \~russian Дата и время создания
PIDateTime created; PIDateTime created;
}; };
#pragma pack(pop) # pragma pack(pop)
//! \~\ingroup Application //! \~\ingroup Application
//! \~\brief //! \~\brief
@@ -205,12 +206,12 @@ public:
PIString name; PIString name;
}; };
#ifndef MICRO_PIP # ifndef PIP_NO_PROCESS
//! \~english Starts monitoring the process with PID "pID" using the given update interval. //! \~english Starts monitoring the process with PID "pID" using the given update interval.
//! \~russian Запускает мониторинг процесса с PID "pID" с указанным интервалом обновления. //! \~russian Запускает мониторинг процесса с PID "pID" с указанным интервалом обновления.
bool startOnProcess(int pID, PISystemTime interval = PISystemTime::fromSeconds(1.)); bool startOnProcess(int pID, PISystemTime interval = PISystemTime::fromSeconds(1.));
#endif # endif // PIP_NO_PROCESS
//! \~english Starts monitoring the current application process. //! \~english Starts monitoring the current application process.
//! \~russian Запускает мониторинг текущего процесса приложения. //! \~russian Запускает мониторинг текущего процесса приложения.
@@ -271,9 +272,9 @@ private:
PIMap<llong, PIString> tbid; PIMap<llong, PIString> tbid;
mutable PIMutex stat_mutex; mutable PIMutex stat_mutex;
int pID_, page_size, cpu_count, cycle; int pID_, page_size, cpu_count, cycle;
#ifndef MICRO_PIP # ifndef PIP_NO_PROCESS
PRIVATE_DECLARATION(PIP_EXPORT) PRIVATE_DECLARATION(PIP_EXPORT)
#endif # endif // PIP_NO_PROCESS
class PIP_EXPORT Pool { class PIP_EXPORT Pool {
friend class PISystemMonitor; friend class PISystemMonitor;
@@ -337,4 +338,5 @@ BINARY_STREAM_READ(PISystemMonitor::ThreadStats) {
return s; return s;
} }
#endif // PIP_NO_THREADS
#endif // PISYSTEMMONITOR_H #endif // PISYSTEMMONITOR_H
+7 -4
View File
@@ -1,6 +1,6 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Translation support Translation support
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -25,6 +25,7 @@
#include "pitranslator_p.h" #include "pitranslator_p.h"
#include "pivaluetree_conversions.h" #include "pivaluetree_conversions.h"
#ifndef PIP_NO_FILESYSTEM
//! \class PITranslator pitranslator.h //! \class PITranslator pitranslator.h
//! \details //! \details
@@ -64,9 +65,9 @@ void PITranslator::loadLang(const PIString & short_lang, PIString dir) {
auto vt = PIValueTreeConversions::fromText(getBuiltinConfig()); auto vt = PIValueTreeConversions::fromText(getBuiltinConfig());
auto lang = vt.child(short_lang.toLowerCase().trim()); auto lang = vt.child(short_lang.toLowerCase().trim());
for (const auto & cn: lang.children()) { for (const auto & cn: lang.children()) {
auto c = s->PRIVATEWB->content.createContext(cn.name()); auto c = s->PRIVATEWB->content.createContext(cn.name());
for (const auto & s: cn.children()) for (const auto & s: cn.children())
c->add(s.name(), s.value().toString()); c->add(s.name(), s.value().toString());
}*/ }*/
} }
@@ -114,3 +115,5 @@ PITranslator * PITranslator::instance() {
static PITranslator ret; static PITranslator ret;
return &ret; return &ret;
} }
#endif // PIP_NO_FILESYSTEM
+2
View File
@@ -153,6 +153,7 @@ bool PICodeParser::isEnum(const PIString & name) {
} }
#ifndef PIP_NO_FILESYSTEM
bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes) { bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes) {
if (proc_files[file]) return true; if (proc_files[file]) return true;
with_includes = follow_includes; with_includes = follow_includes;
@@ -178,6 +179,7 @@ bool PICodeParser::parseFileInternal(const PIString & file, bool follow_includes
piCout << "parsing" << f.path() << "done"; piCout << "parsing" << f.path() << "done";
return ret; return ret;
} }
#endif // PIP_NO_FILESYSTEM
void PICodeParser::clear() { void PICodeParser::clear() {
+2 -2
View File
@@ -18,7 +18,7 @@
*/ */
#include "pikbdlistener.h" #include "pikbdlistener.h"
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
# include "piincludes_p.h" # include "piincludes_p.h"
# include "piliterals.h" # include "piliterals.h"
@@ -590,4 +590,4 @@ void PIKbdListener::setActive(bool yes) {
} }
} }
#endif // MICRO_PIP #endif // PIP_NO_THREADS
+8 -8
View File
@@ -27,7 +27,7 @@
#include "pibase.h" #include "pibase.h"
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
# include "pithread.h" # include "pithread.h"
# include "pitime.h" # include "pitime.h"
@@ -36,12 +36,12 @@
//! \~\brief //! \~\brief
//! \~english Waits until the active listener captures the configured exit key and then stops it. //! \~english Waits until the active listener captures the configured exit key and then stops it.
//! \~russian Ожидает, пока активный слушатель перехватит настроенную клавишу выхода, и затем останавливает его. //! \~russian Ожидает, пока активный слушатель перехватит настроенную клавишу выхода, и затем останавливает его.
# define WAIT_FOR_EXIT \ # define WAIT_FOR_EXIT \
while (!PIKbdListener::exiting) \ while (!PIKbdListener::exiting) \
piMSleep(PIP_MIN_MSLEEP * 5); \ piMSleep(PIP_MIN_MSLEEP * 5); \
if (PIKbdListener::instance()) { \ if (PIKbdListener::instance()) { \
if (!PIKbdListener::instance()->stopAndWait(PISystemTime::fromSeconds(1))) PIKbdListener::instance()->terminate(); \ if (!PIKbdListener::instance()->stopAndWait(PISystemTime::fromSeconds(1))) PIKbdListener::instance()->terminate(); \
} }
//! \~\ingroup Console //! \~\ingroup Console
@@ -381,5 +381,5 @@ REGISTER_PIVARIANTSIMPLE(PIKbdListener::KeyEvent)
REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent) REGISTER_PIVARIANTSIMPLE(PIKbdListener::MouseEvent)
REGISTER_PIVARIANTSIMPLE(PIKbdListener::WheelEvent) REGISTER_PIVARIANTSIMPLE(PIKbdListener::WheelEvent)
#endif // MICRO_PIP #endif // PIP_NO_THREADS
#endif // PIKBDLISTENER_H #endif // PIKBDLISTENER_H
+5 -4
View File
@@ -34,6 +34,7 @@
//! \~\brief //! \~\brief
//! \~english Console screen manager with tile layout, drawing, and input routing. //! \~english Console screen manager with tile layout, drawing, and input routing.
//! \~russian Менеджер консольного экрана с раскладкой тайлов, отрисовкой и маршрутизацией ввода. //! \~russian Менеджер консольного экрана с раскладкой тайлов, отрисовкой и маршрутизацией ввода.
#if !defined(PICO_SDK)
class PIP_CONSOLE_EXPORT PIScreen class PIP_CONSOLE_EXPORT PIScreen
: public PIThread : public PIThread
, public PIScreenTypes::PIScreenBase { , public PIScreenTypes::PIScreenBase {
@@ -177,14 +178,14 @@ private:
void showCursor(); void showCursor();
void clearScreen(); void clearScreen();
void clearScreenLower(); void clearScreenLower();
#ifdef WINDOWS # ifdef WINDOWS
void getWinCurCoord(); void getWinCurCoord();
void clearLine(); void clearLine();
void newLine(); void newLine();
ushort attributes(const PIScreenTypes::Cell & c); ushort attributes(const PIScreenTypes::Cell & c);
#else # else
PIString formatString(const PIScreenTypes::Cell & c); PIString formatString(const PIScreenTypes::Cell & c);
#endif # endif
PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT) PRIVATE_DECLARATION(PIP_CONSOLE_EXPORT)
int width, height, pwidth, pheight; int width, height, pwidth, pheight;
int mouse_x, mouse_y; int mouse_x, mouse_y;
@@ -214,6 +215,6 @@ private:
PIScreenTile root; PIScreenTile root;
PIScreenTile *tile_focus, *tile_dialog; PIScreenTile *tile_focus, *tile_dialog;
}; };
#endif // !PICO_SDK
#endif // PISCREEN_H #endif // PISCREEN_H
+2
View File
@@ -24,6 +24,7 @@
#ifndef PISCREENDRAWER_H #ifndef PISCREENDRAWER_H
#define PISCREENDRAWER_H #define PISCREENDRAWER_H
#if !defined(PICO_SDK)
#include "pip_console_export.h" #include "pip_console_export.h"
#include "piscreentypes.h" #include "piscreentypes.h"
@@ -146,4 +147,5 @@ private:
}; };
#endif // !PICO_SDK
#endif // PISCREENDRAWER_H #endif // PISCREENDRAWER_H
+8 -4
View File
@@ -38,6 +38,7 @@ class PIScreenDrawer;
//! \details //! \details
//! \~english Base class for all screen tiles providing layout and event handling. //! \~english Base class for all screen tiles providing layout and event handling.
//! \~russian Базовый класс для всех экранных тайлов, обеспечивающий компоновку и обработку событий. //! \~russian Базовый класс для всех экранных тайлов, обеспечивающий компоновку и обработку событий.
#if !defined(PICO_SDK)
class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject { class PIP_CONSOLE_EXPORT PIScreenTile: public PIObject {
friend class PIScreen; friend class PIScreen;
PIOBJECT_SUBCLASS(PIScreenTile, PIObject); PIOBJECT_SUBCLASS(PIScreenTile, PIObject);
@@ -163,8 +164,10 @@ public:
bool visible; bool visible;
protected: protected:
//! \~english Returns the preferred tile size in \a w and \a h. The base implementation derives it from visible children, spacing, and margins. //! \~english Returns the preferred tile size in \a w and \a h. The base implementation derives it from visible children, spacing, and
//! \~russian Возвращает предпочтительный размер тайла в \a w и \a h. Базовая реализация вычисляет его по видимым дочерним тайлам, интервалам и отступам. //! margins.
//! \~russian Возвращает предпочтительный размер тайла в \a w и \a h. Базовая реализация вычисляет его по видимым дочерним тайлам,
//! интервалам и отступам.
virtual void sizeHint(int & w, int & h) const; virtual void sizeHint(int & w, int & h) const;
//! \~english Called after the tile size changes to \a w by \a h during layout. //! \~english Called after the tile size changes to \a w by \a h during layout.
@@ -208,7 +211,8 @@ protected:
void layout(); void layout();
//! \~english Returns whether this tile should participate in automatic layout. Tiles with policy \a PIScreenTypes::Ignore are skipped. //! \~english Returns whether this tile should participate in automatic layout. Tiles with policy \a PIScreenTypes::Ignore are skipped.
//! \~russian Возвращает, должен ли тайл участвовать в автоматической компоновке. Тайлы с политикой \a PIScreenTypes::Ignore пропускаются. //! \~russian Возвращает, должен ли тайл участвовать в автоматической компоновке. Тайлы с политикой \a PIScreenTypes::Ignore
//! пропускаются.
bool needLayout() { return size_policy != PIScreenTypes::Ignore; } bool needLayout() { return size_policy != PIScreenTypes::Ignore; }
//! \~english Owned direct child tiles. //! \~english Owned direct child tiles.
@@ -234,6 +238,6 @@ protected:
private: private:
int pw, ph; int pw, ph;
}; };
#endif // !PICO_SDK
#endif // PISCREENTILE_H #endif // PISCREENTILE_H
+2
View File
@@ -27,6 +27,7 @@
#ifndef PISCREENTILES_H #ifndef PISCREENTILES_H
#define PISCREENTILES_H #define PISCREENTILES_H
#if !defined(PICO_SDK)
#include "pip_console_export.h" #include "pip_console_export.h"
#include "piscreentile.h" #include "piscreentile.h"
@@ -444,4 +445,5 @@ protected:
}; };
#endif // !PICO_SDK
#endif // PISCREENTILES_H #endif // PISCREENTILES_H
+2
View File
@@ -27,6 +27,7 @@
#ifndef PISCREENTYPES_H #ifndef PISCREENTYPES_H
#define PISCREENTYPES_H #define PISCREENTYPES_H
#if !defined(PICO_SDK)
#include "pip_console_export.h" #include "pip_console_export.h"
#include "pivariant.h" #include "pivariant.h"
@@ -284,4 +285,5 @@ BINARY_STREAM_READ(PIScreenTypes::TileEvent) {
REGISTER_PIVARIANTSIMPLE(PIScreenTypes::TileEvent) REGISTER_PIVARIANTSIMPLE(PIScreenTypes::TileEvent)
#endif // !PICO_SDK
#endif // PISCREENTYPES_H #endif // PISCREENTYPES_H
+2
View File
@@ -24,6 +24,7 @@
#ifndef PITERMINAL_H #ifndef PITERMINAL_H
#define PITERMINAL_H #define PITERMINAL_H
#if !defined(PICO_SDK)
#include "pikbdlistener.h" #include "pikbdlistener.h"
#include "pip_console_export.h" #include "pip_console_export.h"
@@ -114,4 +115,5 @@ private:
}; };
#endif // !PICO_SDK
#endif // PITERMINAL_H #endif // PITERMINAL_H
+50 -68
View File
@@ -116,10 +116,6 @@
//! \~russian Макрос объявлен когда PIP решил что система поддерживает локализацию //! \~russian Макрос объявлен когда PIP решил что система поддерживает локализацию
# define HAS_LOCALE # define HAS_LOCALE
//! \~english Macro is defined when PIP is building for embedded systems
//! \~russian Макрос объявлен когда PIP собирается для встраиваемых систем
# define MICRO_PIP
//! \~english Macro is defined when compiler is Visual Studio //! \~english Macro is defined when compiler is Visual Studio
//! \~russian Макрос объявлен когда компилятор Visual Studio //! \~russian Макрос объявлен когда компилятор Visual Studio
# define CC_VC # define CC_VC
@@ -168,7 +164,6 @@
//! \~russian Макрос для подавления предупреждения компилятора о неиспользуемой переменной //! \~russian Макрос для подавления предупреждения компилятора о неиспользуемой переменной
# define NO_UNUSED(x) # define NO_UNUSED(x)
# undef MICRO_PIP
# undef FREERTOS # undef FREERTOS
#endif // DOXYGEN #endif // DOXYGEN
@@ -223,12 +218,10 @@ extern char ** environ;
# define assertm(exp, msg) assert(((void)msg, exp)) # define assertm(exp, msg) assert(((void)msg, exp))
# endif # endif
# ifdef MICRO_PIP # if defined(__GXX_RTTI__) || defined(__RTTI__)
# define __PIP_TYPENAME__(T) "?" # define __PIP_TYPENAME__(T) typeid(T).name()
# elif defined(__GXX_RTTI__) || defined(__RTTI__)
# define __PIP_TYPENAME__(T) typeid(T).name()
# else # else
# define __PIP_TYPENAME__(T) "?" # define __PIP_TYPENAME__(T) "?"
# endif # endif
# ifdef CC_GCC # ifdef CC_GCC
@@ -298,17 +291,17 @@ typedef long long ssize_t;
//! \~english Macro to declare private section, "export" is optional //! \~english Macro to declare private section, "export" is optional
//! \~russian Макрос для объявления частной секции, "export" необязателен //! \~russian Макрос для объявления частной секции, "export" необязателен
//! \~sa PRIVATE PRIVATEWB //! \~sa PRIVATE PRIVATEWB
# define PRIVATE_DECLARATION(e) \ # define PRIVATE_DECLARATION(e) \
struct __Private__; \ struct __Private__; \
friend struct __Private__; \ friend struct __Private__; \
struct e __PrivateInitializer__ { \ struct e __PrivateInitializer__ { \
__PrivateInitializer__(); \ __PrivateInitializer__(); \
__PrivateInitializer__(const __PrivateInitializer__ & o); \ __PrivateInitializer__(const __PrivateInitializer__ & o); \
~__PrivateInitializer__(); \ ~__PrivateInitializer__(); \
__PrivateInitializer__ & operator=(const __PrivateInitializer__ & o); \ __PrivateInitializer__ & operator=(const __PrivateInitializer__ & o); \
__Private__ * p = nullptr; \ __Private__ * p = nullptr; \
}; \ }; \
__PrivateInitializer__ __privateinitializer__; __PrivateInitializer__ __privateinitializer__;
//! \~english Macro to start definition of private section //! \~english Macro to start definition of private section
//! \~russian Макрос для начала реализации частной секции //! \~russian Макрос для начала реализации частной секции
@@ -318,35 +311,31 @@ typedef long long ssize_t;
//! \~russian Макрос для окончания реализации частной секции без инициализации //! \~russian Макрос для окончания реализации частной секции без инициализации
//! \~sa PRIVATE_DEFINITION_END PRIVATE_DEFINITION_START PRIVATE_DEFINITION_INITIALIZE PRIVATE PRIVATEWB //! \~sa PRIVATE_DEFINITION_END PRIVATE_DEFINITION_START PRIVATE_DEFINITION_INITIALIZE PRIVATE PRIVATEWB
# define PRIVATE_DEFINITION_END_NO_INITIALIZE(c) \ # define PRIVATE_DEFINITION_END_NO_INITIALIZE(c) \
} \ } \
; ;
//! \~english Macro to initialize private section //! \~english Macro to initialize private section
//! \~russian Макрос для инициализации частной секции //! \~russian Макрос для инициализации частной секции
//! \~sa PRIVATE_DEFINITION_END PRIVATE_DEFINITION_START PRIVATE_DEFINITION_END_NO_INITIALIZE PRIVATE PRIVATEWB //! \~sa PRIVATE_DEFINITION_END PRIVATE_DEFINITION_START PRIVATE_DEFINITION_END_NO_INITIALIZE PRIVATE PRIVATEWB
# define PRIVATE_DEFINITION_INITIALIZE(c) \ # define PRIVATE_DEFINITION_INITIALIZE(c) \
c::__PrivateInitializer__::__PrivateInitializer__() { \ c::__PrivateInitializer__::__PrivateInitializer__() { p = new c::__Private__(); } \
p = new c::__Private__(); \ c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ &) { /*if (p) delete p;*/ \
} \ p = new c::__Private__(); \
c::__PrivateInitializer__::__PrivateInitializer__(const c::__PrivateInitializer__ &) { /*if (p) delete p;*/ \ } \
p = new c::__Private__(); \ c::__PrivateInitializer__::~__PrivateInitializer__() { piDeleteSafety(p); } \
} \ c::__PrivateInitializer__ & c::__PrivateInitializer__::operator=(const c::__PrivateInitializer__ &) { \
c::__PrivateInitializer__::~__PrivateInitializer__() { \ piDeleteSafety(p); \
piDeleteSafety(p); \ p = new c::__Private__(); \
} \ return *this; \
c::__PrivateInitializer__ & c::__PrivateInitializer__::operator=(const c::__PrivateInitializer__ &) { \ }
piDeleteSafety(p); \
p = new c::__Private__(); \
return *this; \
}
//! \~english Macro to end definition of private section with initialization //! \~english Macro to end definition of private section with initialization
//! \~russian Макрос для окончания реализации частной секции с инициализацией //! \~russian Макрос для окончания реализации частной секции с инициализацией
//! \~sa PRIVATE_DEFINITION_END_NO_INITIALIZE PRIVATE_DEFINITION_START PRIVATE_DEFINITION_INITIALIZE PRIVATE PRIVATEWB //! \~sa PRIVATE_DEFINITION_END_NO_INITIALIZE PRIVATE_DEFINITION_START PRIVATE_DEFINITION_INITIALIZE PRIVATE PRIVATEWB
# define PRIVATE_DEFINITION_END(c) \ # define PRIVATE_DEFINITION_END(c) \
PRIVATE_DEFINITION_END_NO_INITIALIZE \ PRIVATE_DEFINITION_END_NO_INITIALIZE \
(c) PRIVATE_DEFINITION_INITIALIZE(c) (c) PRIVATE_DEFINITION_INITIALIZE(c)
//! \~english Macro to access private section by pointer //! \~english Macro to access private section by pointer
//! \~russian Макрос для доступа к частной секции //! \~russian Макрос для доступа к частной секции
@@ -362,9 +351,9 @@ typedef long long ssize_t;
//! \~english Macro to remove class copy availability //! \~english Macro to remove class copy availability
//! \~russian Макрос для запрета копирования класса //! \~russian Макрос для запрета копирования класса
#define NO_COPY_CLASS(name) \ #define NO_COPY_CLASS(name) \
name(const name &) = delete; \ name(const name &) = delete; \
name & operator=(const name &) = delete; name & operator=(const name &) = delete;
//! \~english Counter macro for unique identifier generation //! \~english Counter macro for unique identifier generation
//! \~russian Макрос счетчика для генерации уникальных идентификаторов //! \~russian Макрос счетчика для генерации уникальных идентификаторов
@@ -377,34 +366,19 @@ typedef long long ssize_t;
//! \~russian Макрос для начала статической инициализации //! \~russian Макрос для начала статической инициализации
//! \~sa STATIC_INITIALIZER_END //! \~sa STATIC_INITIALIZER_END
#define STATIC_INITIALIZER_BEGIN \ #define STATIC_INITIALIZER_BEGIN \
class { \ class { \
class _Initializer_ { \ class _Initializer_ { \
public: \ public: \
_Initializer_() { _Initializer_() {
//! \~english Macro to end static initializer //! \~english Macro to end static initializer
//! \~russian Макрос для окончания статической инициализации //! \~russian Макрос для окончания статической инициализации
//! \~sa STATIC_INITIALIZER_BEGIN //! \~sa STATIC_INITIALIZER_BEGIN
#define STATIC_INITIALIZER_END \ #define STATIC_INITIALIZER_END \
} \ } \
} \ } \
_initializer_; \ _initializer_; \
} \ } \
_PIP_ADD_COUNTER(_pip_initializer_); _PIP_ADD_COUNTER(_pip_initializer_);
//! \~english Minimal sleep in milliseconds for internal PIP using
//! \~russian Минимальное значание задержки в милисекундах для внутреннего использования в библиотеке PIP
//! \~\details
//! \~english Using in \a piMinSleep(), \a PIThread, \a PITimer::Pool. By default 1ms.
//! \~russian Используется в \a piMinSleep(), \a PIThread, \a PITimer::Pool. По умолчанию равна 1мс.
//! \~\sa PIP_MIN_MSLEEP
#ifndef PIP_MIN_MSLEEP
# ifndef MICRO_PIP
# define PIP_MIN_MSLEEP 1.
# else
# define PIP_MIN_MSLEEP 10.
# endif
#endif
//! \~english Macro used for infinite loop //! \~english Macro used for infinite loop
@@ -430,4 +404,12 @@ typedef long long ssize_t;
#define WAIT_FOREVER FOREVER piMinSleep(); #define WAIT_FOREVER FOREVER piMinSleep();
#ifndef PIP_MIN_MSLEEP
# ifdef PIP_EMBEDDED
# define PIP_MIN_MSLEEP 10.
# else
# define PIP_MIN_MSLEEP 1.
# endif
#endif
#endif // PIBASE_MACROS_H #endif // PIBASE_MACROS_H
+28 -26
View File
@@ -367,7 +367,7 @@ void PICout::stdoutPIString(const PIString & str, PICoutStdStream s) {
#ifdef HAS_LOCALE #ifdef HAS_LOCALE
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf8conv; std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf8conv;
getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()), getStdStream(s) << utf8conv.to_bytes((char16_t *)&(const_cast<PIString &>(str).front()),
(char16_t *)&(const_cast<PIString &>(str).front()) + str.size()); (char16_t *)&(const_cast<PIString &>(str).front()) + str.size());
#else #else
for (PIChar c: str) for (PIChar c: str)
getStdWStream(s).put(c.toWChar()); getStdWStream(s).put(c.toWChar());
@@ -409,32 +409,32 @@ void PICout::writeChar(char c) {
} }
#define PIINTCOUT(v) \ #define PIINTCOUT(v) \
{ \ { \
if (!actve_) return *this; \ if (!actve_) return *this; \
space(); \ space(); \
if (int_base_ == 10) { \ if (int_base_ == 10) { \
if (buffer_) { \ if (buffer_) { \
(*buffer_) += PIString::fromNumber(v); \ (*buffer_) += PIString::fromNumber(v); \
} else { \ } else { \
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \ if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v); \ if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v); \
} \ } \
} else \ } else \
write(PIString::fromNumber(v, int_base_)); \ write(PIString::fromNumber(v, int_base_)); \
return *this; \ return *this; \
} }
#define PIFLOATCOUT(v) \ #define PIFLOATCOUT(v) \
{ \ { \
if (buffer_) { \ if (buffer_) { \
(*buffer_) += PIString::fromNumber(v, 'g'); \ (*buffer_) += PIString::fromNumber(v, 'g'); \
} else { \ } else { \
if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \ if (isOutputDeviceActive(Console)) getStdStream(stream_) << (v); \
if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v, 'g'); \ if (isOutputDeviceActive(Buffer)) PICout::__string__() += PIString::fromNumber(v, 'g'); \
} \ } \
} \ } \
return *this; return *this;
PICout & PICout::operator<<(const PIString & v) { PICout & PICout::operator<<(const PIString & v) {
@@ -709,6 +709,7 @@ void PICout::applyFormat(PICoutFormat f) {
} }
#ifndef PIP_NO_THREADS
PIString PICout::getBuffer() { PIString PICout::getBuffer() {
PIMutexLocker ml(PICout::__mutex__()); PIMutexLocker ml(PICout::__mutex__());
PIString ret = PICout::__string__(); PIString ret = PICout::__string__();
@@ -728,6 +729,7 @@ void PICout::clearBuffer() {
PIMutexLocker ml(PICout::__mutex__()); PIMutexLocker ml(PICout::__mutex__());
PICout::__string__().clear(); PICout::__string__().clear();
} }
#endif // PIP_NO_THREADS
bool PICout::setOutputDevice(PICout::OutputDevice d, bool on) { bool PICout::setOutputDevice(PICout::OutputDevice d, bool on) {
+2 -2
View File
@@ -41,9 +41,9 @@ class PIString;
class PIByteArray; class PIByteArray;
template<typename P> template<typename P>
class PIBinaryStream; class PIBinaryStream;
#ifndef MICRO_PIP #ifndef _PIP_INIT_STUB_
class PIInit; class PIInit;
#endif #endif // _PIP_INIT_STUB_
class PIChar; class PIChar;
class PICout; class PICout;
class PIWaitEvent; class PIWaitEvent;
+3 -3
View File
@@ -20,7 +20,7 @@
#include "piinit.h" #include "piinit.h"
#include "piincludes_p.h" #include "piincludes_p.h"
#ifndef MICRO_PIP #ifndef _PIP_INIT_STUB_
# include "pidir.h" # include "pidir.h"
# include "piobject.h" # include "piobject.h"
@@ -251,7 +251,7 @@ PIInit::PIInit() {
PIStringAscii("FreeBSD"); PIStringAscii("FreeBSD");
# elif defined(FREERTOS) # elif defined(FREERTOS)
PIStringAscii("FreeRTOS"); PIStringAscii("FreeRTOS");
# elif defined(MICRO_PIP) # elif defined(_PIP_INIT_STUB_)
PIStringAscii("MicroPIP"); PIStringAscii("MicroPIP");
# else # else
uns.sysname; uns.sysname;
@@ -395,4 +395,4 @@ __PIInit_Initializer__::~__PIInit_Initializer__() {
} }
} }
#endif // MICRO_PIP #endif // _PIP_INIT_STUB_
+11 -6
View File
@@ -31,6 +31,11 @@
#include "pibase.h" #include "pibase.h"
// PIInit stub: enabled for embedded or when core features are missing
#if defined(PIP_EMBEDDED) || (defined(PIP_NO_THREADS) && defined(PIP_NO_FILESYSTEM))
# define _PIP_INIT_STUB_
#endif
#ifndef PIP_NO_THREADS #ifndef PIP_NO_THREADS
# include "piincludes.h" # include "piincludes.h"
@@ -50,11 +55,11 @@ public:
static __PIInit_Initializer__ __piinit_initializer__; static __PIInit_Initializer__ __piinit_initializer__;
#ifdef MICRO_PIP # ifdef _PIP_INIT_STUB_
#ifndef PIINIT_MICRO_STUB_DEFINED # ifndef PIINIT_MICRO_STUB_DEFINED
#define PIINIT_MICRO_STUB_DEFINED # define PIINIT_MICRO_STUB_DEFINED
int __PIInit_Initializer__::count_ = 0; int __PIInit_Initializer__::count_ = 0;
PIInit * __PIInit_Initializer__::__instance__ = nullptr; PIInit * __PIInit_Initializer__::__instance__ = nullptr;
__PIInit_Initializer__::__PIInit_Initializer__() { __PIInit_Initializer__::__PIInit_Initializer__() {
@@ -71,8 +76,8 @@ __PIInit_Initializer__::~__PIInit_Initializer__() {
} }
} }
#endif # endif
#endif # endif
//! \~\ingroup Core //! \~\ingroup Core
+18 -5
View File
@@ -22,7 +22,7 @@
#include "piconditionvar.h" #include "piconditionvar.h"
#include "pithread.h" #include "pithread.h"
#include "pitime.h" #include "pitime.h"
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
# include "pifile.h" # include "pifile.h"
# include "piiostream.h" # include "piiostream.h"
# include "pisysteminfo.h" # include "pisysteminfo.h"
@@ -176,9 +176,13 @@ PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__),
in_event_cnt = 0; in_event_cnt = 0;
setName(name); setName(name);
setDebug(true); setDebug(true);
#ifndef PIP_NO_THREADS
mutexObjects().lock(); mutexObjects().lock();
#endif
objects() << this; objects() << this;
#ifndef PIP_NO_THREADS
mutexObjects().unlock(); mutexObjects().unlock();
#endif
// piCout << "new" << this; // piCout << "new" << this;
} }
@@ -186,9 +190,13 @@ PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__),
PIObject::~PIObject() { PIObject::~PIObject() {
in_event_cnt = 0; in_event_cnt = 0;
// piCout << "delete" << this; // piCout << "delete" << this;
#ifndef PIP_NO_THREADS
mutexObjects().lock(); mutexObjects().lock();
#endif
objects().removeAll(this); objects().removeAll(this);
#ifndef PIP_NO_THREADS
mutexObjects().unlock(); mutexObjects().unlock();
#endif
deleted(this); deleted(this);
piDisconnectAll(); piDisconnectAll();
_signature_ = 0; _signature_ = 0;
@@ -464,7 +472,7 @@ void PIObject::piDisconnect(PIObject * src, const PIString & sig) {
src->connections.remove(i); src->connections.remove(i);
i--; i--;
if (dest) { if (dest) {
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(MICRO_PIP) #if !defined(ANDROID) && !defined(MAC_OS) && !defined(PIP_NO_THREADS)
PIMutexLocker _mld(dest->mutex_connect, src != dest); PIMutexLocker _mld(dest->mutex_connect, src != dest);
#endif #endif
dest->updateConnectors(); dest->updateConnectors();
@@ -482,7 +490,7 @@ void PIObject::piDisconnectAll() {
// piCout << "disconnect"<< src << o; // piCout << "disconnect"<< src << o;
if (!o || (o == this)) continue; if (!o || (o == this)) continue;
if (!o->isPIObject()) continue; if (!o->isPIObject()) continue;
#if !defined(ANDROID) && !defined(MAC_OS) && !defined(MICRO_PIP) #if !defined(ANDROID) && !defined(MAC_OS) && !defined(PIP_NO_THREADS)
PIMutexLocker _mld(o->mutex_connect, this != o); PIMutexLocker _mld(o->mutex_connect, this != o);
#endif #endif
PIVector<Connection> & oc(o->connections); PIVector<Connection> & oc(o->connections);
@@ -547,6 +555,7 @@ PIMap<uint, PIObject::__MetaData> & PIObject::__meta_data() {
} }
#ifndef PIP_NO_THREADS
void PIObject::callQueuedEvents() { void PIObject::callQueuedEvents() {
mutex_queue.lock(); mutex_queue.lock();
PIVector<__QueuedEvent> qe = events_queue; PIVector<__QueuedEvent> qe = events_queue;
@@ -560,6 +569,7 @@ void PIObject::callQueuedEvents() {
if (e.dest_o->thread_safe_) e.dest_o->mutex_.unlock(); if (e.dest_o->thread_safe_) e.dest_o->mutex_.unlock();
} }
} }
#endif // PIP_NO_THREADS
//! \details //! \details
@@ -570,9 +580,11 @@ void PIObject::callQueuedEvents() {
//! При первом вызове стартует фоновый поток для удаления объектов. //! При первом вызове стартует фоновый поток для удаления объектов.
//! Каждый объект из очереди удаляется только когда выйдет из всех //! Каждый объект из очереди удаляется только когда выйдет из всех
//! событий и обработок. //! событий и обработок.
#ifndef PIP_NO_THREADS
void PIObject::deleteLater() { void PIObject::deleteLater() {
Deleter::instance()->post(this); Deleter::instance()->post(this);
} }
#endif // PIP_NO_THREADS
bool PIObject::findSuitableMethodV(const PIString & method, int args, int & ret_args, PIObject::__MetaFunc & ret) { bool PIObject::findSuitableMethodV(const PIString & method, int args, int & ret_args, PIObject::__MetaFunc & ret) {
@@ -732,7 +744,7 @@ void PIObject::dump(const PIString & line_prefix) const {
} }
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
void dumpApplication(bool with_objects) { void dumpApplication(bool with_objects) {
PIMutexLocker _ml(PIObject::mutexObjects()); PIMutexLocker _ml(PIObject::mutexObjects());
// printf("dump application ...\n"); // printf("dump application ...\n");
@@ -835,7 +847,7 @@ bool PIObject::Connection::disconnect() const {
return ret; return ret;
} }
#ifndef PIP_NO_THREADS
PRIVATE_DEFINITION_START(PIObject::Deleter) PRIVATE_DEFINITION_START(PIObject::Deleter)
PIThread thread; PIThread thread;
PIConditionVariable cond_var; PIConditionVariable cond_var;
@@ -899,3 +911,4 @@ void PIObject::Deleter::deleteObject(PIObject * o) {
} }
// piCout << "[Deleter] delete" << (uintptr_t)o << "done"; // piCout << "[Deleter] delete" << (uintptr_t)o << "done";
} }
#endif // PIP_NO_THREADS
+36 -4
View File
@@ -54,7 +54,7 @@
//! требует явного опустошения очереди через \a callQueuedEvents() или //! требует явного опустошения очереди через \a callQueuedEvents() или
//! \a maybeCallQueuedEvents(). //! \a maybeCallQueuedEvents().
class PIP_EXPORT PIObject { class PIP_EXPORT PIObject {
#ifndef MICRO_PIP #ifndef PIP_INTROSPECTION
friend class PIObjectManager; friend class PIObjectManager;
friend PIP_EXPORT void dumpApplication(bool); friend PIP_EXPORT void dumpApplication(bool);
friend class PIIntrospection; friend class PIIntrospection;
@@ -461,7 +461,9 @@ public:
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.lock(); if (ts) i.dest_o->mutex_.lock();
#endif
i.dest_o->eventBegin(); i.dest_o->eventBegin();
sender->eventBegin(); sender->eventBegin();
i.dest_o->emitter_ = sender; i.dest_o->emitter_ = sender;
@@ -469,7 +471,9 @@ public:
sender->eventEnd(); sender->eventEnd();
if (i.dest_o->isPIObject()) { if (i.dest_o->isPIObject()) {
i.dest_o->emitter_ = 0; i.dest_o->emitter_ = 0;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.unlock(); if (ts) i.dest_o->mutex_.unlock();
#endif
i.dest_o->eventEnd(); i.dest_o->eventEnd();
} }
} }
@@ -494,7 +498,9 @@ public:
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.lock(); if (ts) i.dest_o->mutex_.lock();
#endif
i.dest_o->eventBegin(); i.dest_o->eventBegin();
sender->eventBegin(); sender->eventBegin();
i.dest_o->emitter_ = sender; i.dest_o->emitter_ = sender;
@@ -505,7 +511,9 @@ public:
sender->eventEnd(); sender->eventEnd();
if (i.dest_o->isPIObject()) { if (i.dest_o->isPIObject()) {
i.dest_o->emitter_ = 0; i.dest_o->emitter_ = 0;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.unlock(); if (ts) i.dest_o->mutex_.unlock();
#endif
i.dest_o->eventEnd(); i.dest_o->eventEnd();
} }
} }
@@ -530,7 +538,9 @@ public:
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.lock(); if (ts) i.dest_o->mutex_.lock();
#endif
i.dest_o->eventBegin(); i.dest_o->eventBegin();
sender->eventBegin(); sender->eventBegin();
i.dest_o->emitter_ = sender; i.dest_o->emitter_ = sender;
@@ -542,7 +552,9 @@ public:
sender->eventEnd(); sender->eventEnd();
if (i.dest_o->isPIObject()) { if (i.dest_o->isPIObject()) {
i.dest_o->emitter_ = 0; i.dest_o->emitter_ = 0;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.unlock(); if (ts) i.dest_o->mutex_.unlock();
#endif
i.dest_o->eventEnd(); i.dest_o->eventEnd();
} }
} }
@@ -568,7 +580,9 @@ public:
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.lock(); if (ts) i.dest_o->mutex_.lock();
#endif
i.dest_o->eventBegin(); i.dest_o->eventBegin();
sender->eventBegin(); sender->eventBegin();
i.dest_o->emitter_ = sender; i.dest_o->emitter_ = sender;
@@ -581,7 +595,9 @@ public:
sender->eventEnd(); sender->eventEnd();
if (i.dest_o->isPIObject()) { if (i.dest_o->isPIObject()) {
i.dest_o->emitter_ = 0; i.dest_o->emitter_ = 0;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.unlock(); if (ts) i.dest_o->mutex_.unlock();
#endif
i.dest_o->eventEnd(); i.dest_o->eventEnd();
} }
} }
@@ -613,7 +629,9 @@ public:
i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl)); i.performer->postQueuedEvent(__QueuedEvent(i.slot, i.dest, i.dest_o, sender, vl));
} else { } else {
bool ts = sender->thread_safe_; bool ts = sender->thread_safe_;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.lock(); if (ts) i.dest_o->mutex_.lock();
#endif
i.dest_o->eventBegin(); i.dest_o->eventBegin();
sender->eventBegin(); sender->eventBegin();
i.dest_o->emitter_ = sender; i.dest_o->emitter_ = sender;
@@ -627,7 +645,9 @@ public:
sender->eventEnd(); sender->eventEnd();
if (i.dest_o->isPIObject()) { if (i.dest_o->isPIObject()) {
i.dest_o->emitter_ = 0; i.dest_o->emitter_ = 0;
#ifndef PIP_NO_THREADS
if (ts) i.dest_o->mutex_.unlock(); if (ts) i.dest_o->mutex_.unlock();
#endif
i.dest_o->eventEnd(); i.dest_o->eventEnd();
} }
} }
@@ -638,6 +658,7 @@ public:
//! \~english Returns the first live object with name "name", or \c nullptr. //! \~english Returns the first live object with name "name", or \c nullptr.
//! \~russian Возвращает первый живой объект с именем "name", либо \c nullptr. //! \~russian Возвращает первый живой объект с именем "name", либо \c nullptr.
#ifndef PIP_NO_THREADS
static PIObject * findByName(const PIString & name) { static PIObject * findByName(const PIString & name) {
PIMutexLocker _ml(mutexObjects()); PIMutexLocker _ml(mutexObjects());
for (auto * i: PIObject::objects()) { for (auto * i: PIObject::objects()) {
@@ -646,6 +667,7 @@ public:
} }
return nullptr; return nullptr;
} }
#endif
//! \~english Returns whether this pointer still refers to a live %PIObject instance. //! \~english Returns whether this pointer still refers to a live %PIObject instance.
//! \~russian Возвращает, указывает ли этот указатель на ещё существующий экземпляр %PIObject. //! \~russian Возвращает, указывает ли этот указатель на ещё существующий экземпляр %PIObject.
@@ -653,6 +675,7 @@ public:
//! \~english Returns whether this object belongs to class "T" or one of its registered descendants. //! \~english Returns whether this object belongs to class "T" or one of its registered descendants.
//! \~russian Возвращает, принадлежит ли этот объект классу "T" или одному из его зарегистрированных потомков. //! \~russian Возвращает, принадлежит ли этот объект классу "T" или одному из его зарегистрированных потомков.
#ifndef PIP_NO_THREADS
template<typename T> template<typename T>
bool isTypeOf() const { bool isTypeOf() const {
if (!isPIObject()) return false; if (!isPIObject()) return false;
@@ -667,6 +690,7 @@ public:
if (!isTypeOf<T>()) return (T *)nullptr; if (!isTypeOf<T>()) return (T *)nullptr;
return (T *)this; return (T *)this;
} }
#endif
//! \~english Returns whether "o" points to a live %PIObject instance. //! \~english Returns whether "o" points to a live %PIObject instance.
//! \~russian Возвращает, указывает ли "o" на ещё существующий экземпляр %PIObject. //! \~russian Возвращает, указывает ли "o" на ещё существующий экземпляр %PIObject.
@@ -796,6 +820,7 @@ private:
PIVector<PIVariantSimple> values; PIVector<PIVariantSimple> values;
}; };
#ifndef PIP_NO_THREADS
class Deleter { class Deleter {
public: public:
Deleter(); Deleter();
@@ -807,6 +832,7 @@ private:
void deleteObject(PIObject * o); void deleteObject(PIObject * o);
PRIVATE_DECLARATION(PIP_EXPORT) PRIVATE_DECLARATION(PIP_EXPORT)
}; };
#endif
bool findSuitableMethodV(const PIString & method, int args, int & ret_args, __MetaFunc & ret); bool findSuitableMethodV(const PIString & method, int args, int & ret_args, __MetaFunc & ret);
PIVector<__MetaFunc> findEH(const PIString & name) const; PIVector<__MetaFunc> findEH(const PIString & name) const;
@@ -830,13 +856,19 @@ private:
PIMap<uint, PIVariant> properties_; PIMap<uint, PIVariant> properties_;
PISet<PIObject *> connectors; PISet<PIObject *> connectors;
PIVector<__QueuedEvent> events_queue; PIVector<__QueuedEvent> events_queue;
PIMutex mutex_, mutex_connect, mutex_queue;
PIObject * emitter_; PIObject * emitter_;
bool thread_safe_, proc_event_queue;
std::atomic_int in_event_cnt; std::atomic_int in_event_cnt;
#ifndef PIP_NO_THREADS
PIMutex mutex_, mutex_connect, mutex_queue;
bool thread_safe_, proc_event_queue;
#else
PIMutex mutex_, mutex_connect, mutex_queue;
bool thread_safe_ = false, proc_event_queue = false;
#endif
}; };
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
//! \~english Dumps application-level %PIObject diagnostics. //! \~english Dumps application-level %PIObject diagnostics.
//! \~russian Выводит диагностическую информацию уровня приложения для %PIObject. //! \~russian Выводит диагностическую информацию уровня приложения для %PIObject.
+2 -2
View File
@@ -18,7 +18,7 @@
*/ */
#include "piwaitevent_p.h" #include "piwaitevent_p.h"
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
# ifdef WINDOWS # ifdef WINDOWS
// # ifdef _WIN32_WINNT // # ifdef _WIN32_WINNT
// # undef _WIN32_WINNT // # undef _WIN32_WINNT
@@ -154,4 +154,4 @@ void * PIWaitEvent::getEvent() const {
# endif # endif
} }
#endif // MICRO_PIP #endif // PIP_NO_THREADS
+2 -2
View File
@@ -20,7 +20,7 @@
#ifndef PIWAITEVENT_P_H #ifndef PIWAITEVENT_P_H
#define PIWAITEVENT_P_H #define PIWAITEVENT_P_H
#ifndef MICRO_PIP #ifndef PIP_NO_THREADS
# include "pibase.h" # include "pibase.h"
// clang-format off // clang-format off
@@ -67,5 +67,5 @@ private:
}; };
#endif // MICRO_PIP #endif // PIP_NO_THREADS
#endif // PIWAITEVENT_P_H #endif // PIWAITEVENT_P_H
+12 -8
View File
@@ -23,10 +23,12 @@
#include "piliterals_bytes.h" #include "piliterals_bytes.h"
#include "piliterals_time.h" #include "piliterals_time.h"
#include "pipropertystorage.h" #include "pipropertystorage.h"
#include "pitime.h"
#include "pitranslator.h"
#define PIBINARYLOG_VERSION_OLD 0x31 #ifndef PIP_NO_FILESYSTEM
# include "pitime.h"
# include "pitranslator.h"
# define PIBINARYLOG_VERSION_OLD 0x31
/*! \class PIBinaryLog /*! \class PIBinaryLog
* \brief Class for read and write binary data to logfile, and playback this data in realtime, or custom speed * \brief Class for read and write binary data to logfile, and playback this data in realtime, or custom speed
@@ -52,17 +54,17 @@
static const uchar binlog_sig[] = {'B', 'I', 'N', 'L', 'O', 'G'}; static const uchar binlog_sig[] = {'B', 'I', 'N', 'L', 'O', 'G'};
#define PIBINARYLOG_VERSION 0x32 # define PIBINARYLOG_VERSION 0x32
#define PIBINARYLOG_SIGNATURE_SIZE sizeof(binlog_sig) # define PIBINARYLOG_SIGNATURE_SIZE sizeof(binlog_sig)
REGISTER_DEVICE(PIBinaryLog) REGISTER_DEVICE(PIBinaryLog)
PIBinaryLog::PIBinaryLog() { PIBinaryLog::PIBinaryLog() {
#ifdef MICRO_PIP # ifdef PIP_NO_THREADS
setThreadedReadBufferSize(512); setThreadedReadBufferSize(512);
#else # else
setThreadedReadBufferSize(64_KiB); setThreadedReadBufferSize(64_KiB);
#endif # endif // PIP_NO_THREADS
is_started = is_indexed = is_pause = false; is_started = is_indexed = is_pause = false;
create_index_on_fly = false; create_index_on_fly = false;
current_index = -1; current_index = -1;
@@ -1008,3 +1010,5 @@ void PIBinaryLog::CompleteIndex::makeIndexPos() {
for (uint i = 0; i < index.size(); i++) for (uint i = 0; i < index.size(); i++)
index_pos[index[i].pos] = i; index_pos[index[i].pos] = i;
} }
#endif // PIP_NO_FILESYSTEM
+7 -4
View File
@@ -29,6 +29,8 @@
#include "pichunkstream.h" #include "pichunkstream.h"
#include "pifile.h" #include "pifile.h"
#ifndef PIP_NO_FILESYSTEM
//! \~english Class for writing and reading binary data to/from log files, with support for playback in different modes. //! \~english Class for writing and reading binary data to/from log files, with support for playback in different modes.
//! \~russian Класс для записи и чтения бинарных данных в/из файлов логов с поддержкой воспроизведения в различных режимах. //! \~russian Класс для записи и чтения бинарных данных в/из файлов логов с поддержкой воспроизведения в различных режимах.
//! \~\details //! \~\details
@@ -79,7 +81,7 @@ public:
, ,
}; };
#pragma pack(push, 8) # pragma pack(push, 8)
//! \~english Statistics for records sharing the same record ID. //! \~english Statistics for records sharing the same record ID.
//! \~russian Статистика по записям с одинаковым идентификатором. //! \~russian Статистика по записям с одинаковым идентификатором.
@@ -141,7 +143,7 @@ public:
PISystemTime timestamp; PISystemTime timestamp;
}; };
#pragma pack(pop) # pragma pack(pop)
//! \~english Summary information about a log file and its indexed record types. //! \~english Summary information about a log file and its indexed record types.
//! \~russian Сводная информация о файле лога и его индексированных типах записей. //! \~russian Сводная информация о файле лога и его индексированных типах записей.
@@ -591,7 +593,7 @@ public:
//! \~russian Возвращает пользовательский заголовок, сохраненный в текущем открытом логе. //! \~russian Возвращает пользовательский заголовок, сохраненный в текущем открытом логе.
PIByteArray getHeader() const; PIByteArray getHeader() const;
#ifdef DOXYGEN # ifdef DOXYGEN
//! \~english Reads one message using \a filterID when it is not empty. //! \~english Reads one message using \a filterID when it is not empty.
//! \~russian Читает одно сообщение, используя \a filterID, если он не пуст. //! \~russian Читает одно сообщение, используя \a filterID, если он не пуст.
int read(void * read_to, int max_size); int read(void * read_to, int max_size);
@@ -599,7 +601,7 @@ public:
//! \~english Writes one record using \a defaultID(). //! \~english Writes one record using \a defaultID().
//! \~russian Записывает одну запись, используя \a defaultID(). //! \~russian Записывает одну запись, используя \a defaultID().
int write(const void * data, int size); int write(const void * data, int size);
#endif # endif
//! \~english Optional list of record IDs accepted by \a read() and threaded playback. //! \~english Optional list of record IDs accepted by \a read() and threaded playback.
//! \~russian Необязательный список идентификаторов записей, допустимых для \a read() и потокового воспроизведения. //! \~russian Необязательный список идентификаторов записей, допустимых для \a read() и потокового воспроизведения.
@@ -991,4 +993,5 @@ inline PICout operator<<(PICout s, const PIBinaryLog::BinLogInfo & bi) {
return s; return s;
} }
#endif // PIP_NO_FILESYSTEM
#endif // PIBINARYLOG_H #endif // PIBINARYLOG_H
+12
View File
@@ -288,6 +288,7 @@ PIConfig::PIConfig(PIIODevice * device, PIIODevice::DeviceMode mode) {
} }
#ifndef PIP_NO_FILESYSTEM
PIConfig::PIConfig(const PIString & path, PIStringList dirs) { PIConfig::PIConfig(const PIString & path, PIStringList dirs) {
_init(); _init();
internal = true; internal = true;
@@ -311,6 +312,7 @@ PIConfig::PIConfig(const PIString & path, PIStringList dirs) {
_setupDev(); _setupDev();
parse(); parse();
} }
#endif // PIP_NO_FILESYSTEM
PIConfig::~PIConfig() { PIConfig::~PIConfig() {
@@ -319,6 +321,7 @@ PIConfig::~PIConfig() {
} }
#ifndef PIP_NO_FILESYSTEM
bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) { bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) {
_destroy(); _destroy();
incdirs << PIFile::fileInfo(path).dir(); incdirs << PIFile::fileInfo(path).dir();
@@ -329,6 +332,7 @@ bool PIConfig::open(const PIString & path, PIIODevice::DeviceMode mode) {
parse(); parse();
return dev->isOpened(); return dev->isOpened();
} }
#endif // PIP_NO_FILESYSTEM
bool PIConfig::open(PIString * string, PIIODevice::DeviceMode mode) { bool PIConfig::open(PIString * string, PIIODevice::DeviceMode mode) {
@@ -347,7 +351,9 @@ bool PIConfig::open(PIIODevice * device, PIIODevice::DeviceMode mode) {
dev = device; dev = device;
if (dev) { if (dev) {
dev->open(mode); dev->open(mode);
#ifndef PIP_NO_FILESYSTEM
if (dev->isTypeOf<PIFile>()) incdirs << PIFile::fileInfo(((PIFile *)dev)->path()).dir(); if (dev->isTypeOf<PIFile>()) incdirs << PIFile::fileInfo(((PIFile *)dev)->path()).dir();
#endif
} }
_setupDev(); _setupDev();
parse(); parse();
@@ -383,10 +389,12 @@ void PIConfig::_setupDev() {
void PIConfig::_clearDev() { void PIConfig::_clearDev() {
if (!dev) return; if (!dev) return;
#ifndef PIP_NO_FILESYSTEM
if (PIString(dev->className()) == "PIFile") { if (PIString(dev->className()) == "PIFile") {
((PIFile *)dev)->clear(); ((PIFile *)dev)->clear();
return; return;
} }
#endif
if (PIString(dev->className()) == "PIIOString") { if (PIString(dev->className()) == "PIIOString") {
((PIIOString *)dev)->clear(); ((PIIOString *)dev)->clear();
((PIIOString *)dev)->setMode(PIIODevice::WriteOnly); ((PIIOString *)dev)->setMode(PIIODevice::WriteOnly);
@@ -397,9 +405,11 @@ void PIConfig::_clearDev() {
void PIConfig::_flushDev() { void PIConfig::_flushDev() {
if (!dev) return; if (!dev) return;
#ifndef PIP_NO_FILESYSTEM
if (PIString(dev->className()) == "PIFile") { if (PIString(dev->className()) == "PIFile") {
((PIFile *)dev)->flush(); ((PIFile *)dev)->flush();
} }
#endif
} }
@@ -411,10 +421,12 @@ bool PIConfig::_isEndDev() {
void PIConfig::_seekToBeginDev() { void PIConfig::_seekToBeginDev() {
if (!dev) return; if (!dev) return;
#ifndef PIP_NO_FILESYSTEM
if (PIString(dev->className()) == "PIFile") { if (PIString(dev->className()) == "PIFile") {
((PIFile *)dev)->seekToBegin(); ((PIFile *)dev)->seekToBegin();
return; return;
} }
#endif
if (PIString(dev->className()) == "PIIOString") { if (PIString(dev->className()) == "PIIOString") {
((PIIOString *)dev)->seekToBegin(); ((PIIOString *)dev)->seekToBegin();
((PIIOString *)dev)->setMode(PIIODevice::ReadOnly); ((PIIOString *)dev)->setMode(PIIODevice::ReadOnly);
+80 -80
View File
@@ -18,61 +18,61 @@
*/ */
#ifndef PIP_NO_FILESYSTEM #ifndef PIP_NO_FILESYSTEM
#include "pifile.h" # include "pifile.h"
#include "pidir.h" # include "pidir.h"
#include "piincludes_p.h" # include "piincludes_p.h"
#include "piiostream.h" # include "piiostream.h"
#include "piliterals_bytes.h" # include "piliterals_bytes.h"
#include "pitime_win.h" # include "pitime_win.h"
#include "pitranslator.h" # include "pitranslator.h"
#ifdef WINDOWS # ifdef WINDOWS
# undef S_IFDIR # undef S_IFDIR
# undef S_IFREG # undef S_IFREG
# undef S_IFLNK # undef S_IFLNK
# undef S_IFBLK # undef S_IFBLK
# undef S_IFCHR # undef S_IFCHR
# undef S_IFSOCK # undef S_IFSOCK
# define S_IFDIR 0x01 # define S_IFDIR 0x01
# define S_IFREG 0x02 # define S_IFREG 0x02
# define S_IFLNK 0x04 # define S_IFLNK 0x04
# define S_IFBLK 0x08 # define S_IFBLK 0x08
# define S_IFCHR 0x10 # define S_IFCHR 0x10
# define S_IFSOCK 0x20 # define S_IFSOCK 0x20
#else
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <utime.h>
#endif
#define S_IFHDN 0x40
#if defined(QNX) || defined(ANDROID) || defined(MICRO_PIP)
# define _fopen_call_ fopen
# define _fseek_call_ fseek
# define _ftell_call_ ftell
# define _stat_struct_ struct stat
# define _stat_call_ stat
# define _stat_link_ lstat
#else
# if defined(MAC_OS)
# define _fopen_call_ fopen
# define _fseek_call_ fseek
# define _ftell_call_ ftell
# else # else
# ifdef CC_GCC # include <fcntl.h>
# define _fopen_call_ fopen64 # include <sys/stat.h>
# define _fseek_call_ fseeko64 # include <sys/time.h>
# define _ftell_call_ ftello64 # include <utime.h>
# else # endif
# define S_IFHDN 0x40
# if defined(QNX) || defined(ANDROID) || defined(PIP_NO_FILESYSTEM)
# define _fopen_call_ fopen
# define _fseek_call_ fseek
# define _ftell_call_ ftell
# define _stat_struct_ struct stat
# define _stat_call_ stat
# define _stat_link_ lstat
# else
# if defined(MAC_OS)
# define _fopen_call_ fopen # define _fopen_call_ fopen
# define _fseek_call_ fseek # define _fseek_call_ fseek
# define _ftell_call_ ftell # define _ftell_call_ ftell
# else
# ifdef CC_GCC
# define _fopen_call_ fopen64
# define _fseek_call_ fseeko64
# define _ftell_call_ ftello64
# else
# define _fopen_call_ fopen
# define _fseek_call_ fseek
# define _ftell_call_ ftell
# endif
# endif # endif
# define _stat_struct_ struct stat64
# define _stat_call_ stat64
# define _stat_link_ lstat64
# endif # endif
# define _stat_struct_ struct stat64
# define _stat_call_ stat64
# define _stat_link_ lstat64
#endif
//! \class PIFile pifile.h //! \class PIFile pifile.h
@@ -176,18 +176,18 @@ PIFile::PIFile(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(p
bool PIFile::openTemporary(PIIODevice::DeviceMode mode) { bool PIFile::openTemporary(PIIODevice::DeviceMode mode) {
PIString tp; PIString tp;
#ifdef WINDOWS # ifdef WINDOWS
tp = PIDir::temporary().path() + PIDir::separator + "file" + PIString::fromNumber(randomi()); tp = PIDir::temporary().path() + PIDir::separator + "file" + PIString::fromNumber(randomi());
while (isExists(tp)) { while (isExists(tp)) {
tp += PIString::fromNumber(randomi() % 10); tp += PIString::fromNumber(randomi() % 10);
} }
#else # else
char template_rc[] = "/tmp/pifile_tmp_XXXXXX"; char template_rc[] = "/tmp/pifile_tmp_XXXXXX";
int fd = mkstemp(template_rc); int fd = mkstemp(template_rc);
if (fd == -1) return false; if (fd == -1) return false;
::close(fd); ::close(fd);
tp = template_rc; tp = template_rc;
#endif # endif
return open(tp, mode); return open(tp, mode);
} }
@@ -213,9 +213,9 @@ bool PIFile::openDevice() {
bool opened = (PRIVATE->fd != 0); bool opened = (PRIVATE->fd != 0);
if (opened) { if (opened) {
fdi = fileno(PRIVATE->fd); fdi = fileno(PRIVATE->fd);
#ifndef WINDOWS # ifndef WINDOWS
fcntl(fdi, F_SETFL, O_NONBLOCK); fcntl(fdi, F_SETFL, O_NONBLOCK);
#endif # endif
if (mode_ == PIIODevice::ReadOnly) { if (mode_ == PIIODevice::ReadOnly) {
_fseek_call_(PRIVATE->fd, 0, SEEK_END); _fseek_call_(PRIVATE->fd, 0, SEEK_END);
_size = _ftell_call_(PRIVATE->fd); _size = _ftell_call_(PRIVATE->fd);
@@ -307,11 +307,11 @@ bool PIFile::isExists(const PIString & path) {
bool PIFile::remove(const PIString & path) { bool PIFile::remove(const PIString & path) {
#ifdef WINDOWS # ifdef WINDOWS
if (PIDir::isExists(path)) if (PIDir::isExists(path))
return RemoveDirectoryA(path.data()) > 0; return RemoveDirectoryA(path.data()) > 0;
else else
#endif # endif
return ::remove(path.data()) == 0; return ::remove(path.data()) == 0;
} }
@@ -479,7 +479,7 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
ret.path = path.replacedAll("\\", PIDir::separator); ret.path = path.replacedAll("\\", PIDir::separator);
PIString n = ret.name(); PIString n = ret.name();
// piCout << "open" << path; // piCout << "open" << path;
#ifdef WINDOWS # ifdef WINDOWS
DWORD attr = GetFileAttributesA((LPCSTR)(path.data())); DWORD attr = GetFileAttributesA((LPCSTR)(path.data()));
if (attr == 0xFFFFFFFF) return ret; if (attr == 0xFFFFFFFF) return ret;
HANDLE hFile = 0; HANDLE hFile = 0;
@@ -511,37 +511,37 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
ret.time_modification = FILETIME2PIDateTime(fi.ftLastWriteTime); ret.time_modification = FILETIME2PIDateTime(fi.ftLastWriteTime);
} }
CloseHandle(hFile); CloseHandle(hFile);
#else # else
_stat_struct_ fs; _stat_struct_ fs;
piZeroMemory(fs); piZeroMemory(fs);
_stat_call_(path.data(), &fs); _stat_call_(path.data(), &fs);
int mode = fs.st_mode; int mode = fs.st_mode;
ret.size = fs.st_size; ret.size = fs.st_size;
ret.id_user = fs.st_uid; ret.id_user = fs.st_uid;
ret.id_group = fs.st_gid; ret.id_group = fs.st_gid;
# ifdef ANDROID # ifdef ANDROID
ret.time_access = PIDateTime::fromSystemTime(PISystemTime(fs.st_atime, fs.st_atime_nsec)); ret.time_access = PIDateTime::fromSystemTime(PISystemTime(fs.st_atime, fs.st_atime_nsec));
ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.st_mtime, fs.st_mtime_nsec)); ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.st_mtime, fs.st_mtime_nsec));
# else # else
# if defined(QNX) || defined(FREERTOS) # if defined(QNX) || defined(FREERTOS)
ret.time_access = PIDateTime::fromSecondSinceEpoch(fs.st_atime); ret.time_access = PIDateTime::fromSecondSinceEpoch(fs.st_atime);
ret.time_modification = PIDateTime::fromSecondSinceEpoch(fs.st_mtime); ret.time_modification = PIDateTime::fromSecondSinceEpoch(fs.st_mtime);
# else
# ifdef MAC_OS
# define ATIME st_atimespec
# define MTIME st_ctimespec
# else # else
# define ATIME st_atim # ifdef MAC_OS
# define MTIME st_mtim # define ATIME st_atimespec
# endif # define MTIME st_ctimespec
# else
# define ATIME st_atim
# define MTIME st_mtim
# endif
ret.time_access = PIDateTime::fromSystemTime(PISystemTime(fs.ATIME.tv_sec, fs.ATIME.tv_nsec)); ret.time_access = PIDateTime::fromSystemTime(PISystemTime(fs.ATIME.tv_sec, fs.ATIME.tv_nsec));
ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.MTIME.tv_sec, fs.MTIME.tv_nsec)); ret.time_modification = PIDateTime::fromSystemTime(PISystemTime(fs.MTIME.tv_sec, fs.MTIME.tv_nsec));
# endif
# endif # endif
# endif # ifndef PIP_NO_FILESYSTEM
# ifndef MICRO_PIP ret.perm_user = FileInfo::Permissions((mode & S_IRUSR) == S_IRUSR, (mode & S_IWUSR) == S_IWUSR, (mode & S_IXUSR) == S_IXUSR);
ret.perm_user = FileInfo::Permissions((mode & S_IRUSR) == S_IRUSR, (mode & S_IWUSR) == S_IWUSR, (mode & S_IXUSR) == S_IXUSR); ret.perm_group = FileInfo::Permissions((mode & S_IRGRP) == S_IRGRP, (mode & S_IWGRP) == S_IWGRP, (mode & S_IXGRP) == S_IXGRP);
ret.perm_group = FileInfo::Permissions((mode & S_IRGRP) == S_IRGRP, (mode & S_IWGRP) == S_IWGRP, (mode & S_IXGRP) == S_IXGRP); ret.perm_other = FileInfo::Permissions((mode & S_IROTH) == S_IROTH, (mode & S_IWOTH) == S_IWOTH, (mode & S_IXOTH) == S_IXOTH);
ret.perm_other = FileInfo::Permissions((mode & S_IROTH) == S_IROTH, (mode & S_IWOTH) == S_IWOTH, (mode & S_IXOTH) == S_IXOTH);
piZeroMemory(fs); piZeroMemory(fs);
_stat_link_(path.data(), &fs); _stat_link_(path.data(), &fs);
mode &= ~S_IFLNK; mode &= ~S_IFLNK;
@@ -551,8 +551,8 @@ PIFile::FileInfo PIFile::fileInfo(const PIString & path) {
if ((mode & S_IFREG) == S_IFREG) ret.flags |= FileInfo::File; if ((mode & S_IFREG) == S_IFREG) ret.flags |= FileInfo::File;
if ((mode & S_IFLNK) == S_IFLNK) ret.flags |= FileInfo::SymbolicLink; if ((mode & S_IFLNK) == S_IFLNK) ret.flags |= FileInfo::SymbolicLink;
if ((mode & S_IFHDN) == S_IFHDN) ret.flags |= FileInfo::Hidden; if ((mode & S_IFHDN) == S_IFHDN) ret.flags |= FileInfo::Hidden;
# endif
# endif # endif
#endif
if (n == ".") ret.flags = FileInfo::Dir | FileInfo::Dot; if (n == ".") ret.flags = FileInfo::Dir | FileInfo::Dot;
if (n == "..") ret.flags = FileInfo::Dir | FileInfo::DotDot; if (n == "..") ret.flags = FileInfo::Dir | FileInfo::DotDot;
return ret; return ret;
@@ -563,7 +563,7 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
if (path.isEmpty()) return false; if (path.isEmpty()) return false;
PIString fp(path); PIString fp(path);
if (fp.endsWith(PIDir::separator)) fp.pop_back(); if (fp.endsWith(PIDir::separator)) fp.pop_back();
#ifdef WINDOWS # ifdef WINDOWS
DWORD attr = GetFileAttributesA((LPCSTR)(path.data())); DWORD attr = GetFileAttributesA((LPCSTR)(path.data()));
if (attr == 0xFFFFFFFF) return false; if (attr == 0xFFFFFFFF) return false;
attr &= ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY); attr &= ~(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
@@ -591,7 +591,7 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
return false; return false;
} }
CloseHandle(hFile); CloseHandle(hFile);
#else # else
int mode(0); int mode(0);
if (info.perm_user.read) mode |= S_IRUSR; if (info.perm_user.read) mode |= S_IRUSR;
if (info.perm_user.write) mode |= S_IWUSR; if (info.perm_user.write) mode |= S_IWUSR;
@@ -618,7 +618,7 @@ bool PIFile::applyFileInfo(const PIString & path, const PIFile::FileInfo & info)
if (utimes(fp.data(), tm) != 0) { if (utimes(fp.data(), tm) != 0) {
piCout << "[PIFile] applyFileInfo: \"utimes\" error:" << errorString(); piCout << "[PIFile] applyFileInfo: \"utimes\" error:" << errorString();
} }
#endif # endif
return true; return true;
} }
+21 -18
View File
@@ -30,6 +30,7 @@
#endif #endif
#include "piliterals.h" #include "piliterals.h"
#ifndef PIP_NO_THREADS
//! \class PIGPIO pigpio.h //! \class PIGPIO pigpio.h
//! \~english \section PIGPIO_sec0 Synopsis //! \~english \section PIGPIO_sec0 Synopsis
@@ -74,7 +75,7 @@ PIGPIO::~PIGPIO() {
stop(); stop();
waitForFinish(100_ms); waitForFinish(100_ms);
PIMutexLocker ml(mutex); PIMutexLocker ml(mutex);
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
PIVector<int> ids = gpio_.keys(); PIVector<int> ids = gpio_.keys();
for (int i = 0; i < ids.size_s(); i++) { for (int i = 0; i < ids.size_s(); i++) {
GPIOData & g(gpio_[ids[i]]); GPIOData & g(gpio_[ids[i]]);
@@ -84,7 +85,7 @@ PIGPIO::~PIGPIO() {
} }
} }
gpio_.clear(); gpio_.clear();
#endif # endif
} }
@@ -100,7 +101,7 @@ PIString PIGPIO::GPIOName(int gpio_num) {
void PIGPIO::exportGPIO(int gpio_num) { void PIGPIO::exportGPIO(int gpio_num) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
PIString valfile = "/sys/class/gpio/" + GPIOName(gpio_num) + "/value"; PIString valfile = "/sys/class/gpio/" + GPIOName(gpio_num) + "/value";
int fd = ::open(valfile.dataAscii(), O_RDONLY); int fd = ::open(valfile.dataAscii(), O_RDONLY);
if (fd != -1) { if (fd != -1) {
@@ -120,12 +121,12 @@ void PIGPIO::exportGPIO(int gpio_num) {
piMSleep(1); piMSleep(1);
} }
} }
#endif # endif
} }
void PIGPIO::openGPIO(GPIOData & g) { void PIGPIO::openGPIO(GPIOData & g) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
if (g.fd != -1) { if (g.fd != -1) {
::close(g.fd); ::close(g.fd);
g.fd = -1; g.fd = -1;
@@ -133,12 +134,12 @@ void PIGPIO::openGPIO(GPIOData & g) {
PIString fp = "/sys/class/gpio/" + g.name + "/value"; PIString fp = "/sys/class/gpio/" + g.name + "/value";
g.fd = ::open(fp.dataAscii(), O_RDWR); g.fd = ::open(fp.dataAscii(), O_RDWR);
// piCoutObj << "initGPIO" << g.num << ":" << fp << g.fd << errorString(); // piCoutObj << "initGPIO" << g.num << ":" << fp << g.fd << errorString();
#endif # endif
} }
bool PIGPIO::getPinState(int gpio_num) { bool PIGPIO::getPinState(int gpio_num) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
GPIOData & g(gpio_[gpio_num]); GPIOData & g(gpio_[gpio_num]);
char r = 0; char r = 0;
int ret = 0; int ret = 0;
@@ -151,7 +152,7 @@ bool PIGPIO::getPinState(int gpio_num) {
} }
} }
// piCoutObj << "pinState" << gpio_num << ":" << ret << (int)r << errorString(); // piCoutObj << "pinState" << gpio_num << ":" << ret << (int)r << errorString();
#endif # endif
return false; return false;
} }
@@ -201,9 +202,9 @@ void PIGPIO::end() {
for (int i = 0; i < ids.size_s(); i++) { for (int i = 0; i < ids.size_s(); i++) {
GPIOData & g(gpio_[ids[i]]); GPIOData & g(gpio_[ids[i]]);
if (g.fd != -1) { if (g.fd != -1) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
::close(g.fd); ::close(g.fd);
#endif # endif
g.fd = -1; g.fd = -1;
} }
} }
@@ -211,7 +212,7 @@ void PIGPIO::end() {
void PIGPIO::initPin(int gpio_num, Direction dir) { void PIGPIO::initPin(int gpio_num, Direction dir) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
PIMutexLocker ml(mutex); PIMutexLocker ml(mutex);
GPIOData & g(gpio_[gpio_num]); GPIOData & g(gpio_[gpio_num]);
if (g.num == -1) { if (g.num == -1) {
@@ -228,12 +229,12 @@ void PIGPIO::initPin(int gpio_num, Direction dir) {
default: break; default: break;
} }
openGPIO(g); openGPIO(g);
#endif # endif
} }
void PIGPIO::pinSet(int gpio_num, bool value) { void PIGPIO::pinSet(int gpio_num, bool value) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
PIMutexLocker ml(mutex); PIMutexLocker ml(mutex);
GPIOData & g(gpio_[gpio_num]); GPIOData & g(gpio_[gpio_num]);
int ret = 0; int ret = 0;
@@ -245,7 +246,7 @@ void PIGPIO::pinSet(int gpio_num, bool value) {
ret = ::write(g.fd, "0", 1); ret = ::write(g.fd, "0", 1);
} }
// piCoutObj << "pinSet" << gpio_num << ":" << ret << errorString(); // piCoutObj << "pinSet" << gpio_num << ":" << ret << errorString();
#endif # endif
} }
@@ -267,9 +268,9 @@ void PIGPIO::pinBeginWatch(int gpio_num) {
PIMutexLocker ml(mutex); PIMutexLocker ml(mutex);
GPIOData & g(gpio_[gpio_num]); GPIOData & g(gpio_[gpio_num]);
if (g.fd != -1) { if (g.fd != -1) {
#ifdef GPIO_SYS_CLASS # ifdef GPIO_SYS_CLASS
::close(g.fd); ::close(g.fd);
#endif # endif
g.fd = -1; g.fd = -1;
} }
watch_state.insert(gpio_num, false); watch_state.insert(gpio_num, false);
@@ -304,6 +305,8 @@ void PIGPIO::clearWatch() {
} }
#ifdef __GNUC__ # ifdef __GNUC__
// # pragma GCC diagnostic pop // # pragma GCC diagnostic pop
#endif # endif
#endif // PIP_NO_THREADS
+3 -1
View File
@@ -28,6 +28,7 @@
#include "pithread.h" #include "pithread.h"
#ifndef PIP_NO_THREADS
//! \~\ingroup IO //! \~\ingroup IO
//! \~\brief //! \~\brief
@@ -143,5 +144,6 @@ private:
PIMutex mutex; PIMutex mutex;
}; };
#endif // PIP_NO_THREADS
#endif // PIDIR_H #endif // PIGPIO_H
+51 -19
View File
@@ -117,7 +117,9 @@
//! //!
#ifndef PIP_NO_THREADS
PIMutex PIIODevice::nfp_mutex; PIMutex PIIODevice::nfp_mutex;
#endif
PIMap<PIString, PIString> PIIODevice::nfp_cache; PIMap<PIString, PIString> PIIODevice::nfp_cache;
@@ -138,6 +140,7 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIOb
PIIODevice::~PIIODevice() { PIIODevice::~PIIODevice() {
destroying = true; destroying = true;
stopAndWait(); stopAndWait();
(void)destroying;
} }
@@ -195,6 +198,7 @@ void PIIODevice::setThreadedReadBufferSize(int new_size) {
} }
#ifndef PIP_NO_THREADS
bool PIIODevice::isThreadedRead() const { bool PIIODevice::isThreadedRead() const {
return read_thread.isRunning(); return read_thread.isRunning();
} }
@@ -216,16 +220,12 @@ void PIIODevice::startThreadedRead(ReadRetFunc func) {
void PIIODevice::stopThreadedRead() { void PIIODevice::stopThreadedRead() {
if (!isThreadedRead()) return; if (!isThreadedRead()) return;
#ifdef MICRO_PIP
read_thread.stop();
#else
read_thread.stop(); read_thread.stop();
if (!destroying) { if (!destroying) {
interrupt(); interrupt();
} else { } else {
piCoutObj << "Error: Device is running after destructor!"_tr("PIIODevice"); piCoutObj << "Error: Device is running after destructor!"_tr("PIIODevice");
} }
#endif
} }
@@ -248,56 +248,80 @@ bool PIIODevice::waitThreadedReadFinished(PISystemTime timeout) {
} }
return true; return true;
} }
#endif
bool PIIODevice::isThreadedWrite() const { bool PIIODevice::isThreadedWrite() const {
#ifndef PIP_NO_THREADS
return write_thread.isRunning(); return write_thread.isRunning();
#else
return false;
#endif
} }
void PIIODevice::startThreadedWrite() { void PIIODevice::startThreadedWrite() {
#ifndef PIP_NO_THREADS
if (!write_thread.isRunning()) write_thread.startOnce(); if (!write_thread.isRunning()) write_thread.startOnce();
#endif
} }
void PIIODevice::stopThreadedWrite() { void PIIODevice::stopThreadedWrite() {
#ifndef PIP_NO_THREADS
if (!write_thread.isRunning()) return; if (!write_thread.isRunning()) return;
write_thread.stop(); write_thread.stop();
#endif
} }
void PIIODevice::terminateThreadedWrite() { void PIIODevice::terminateThreadedWrite() {
#ifndef PIP_NO_THREADS
write_thread.terminate(); write_thread.terminate();
#endif
} }
bool PIIODevice::waitThreadedWriteFinished(PISystemTime timeout) { bool PIIODevice::waitThreadedWriteFinished(PISystemTime timeout) {
#ifndef PIP_NO_THREADS
return write_thread.waitForFinish(timeout); return write_thread.waitForFinish(timeout);
#else
(void)timeout;
return true;
#endif
} }
void PIIODevice::clearThreadedWriteQueue() { void PIIODevice::clearThreadedWriteQueue() {
#ifndef PIP_NO_THREADS
write_thread.lock(); write_thread.lock();
write_queue.clear(); write_queue.clear();
write_thread.unlock(); write_thread.unlock();
#endif
} }
void PIIODevice::start() { void PIIODevice::start() {
#ifndef PIP_NO_THREADS
startThreadedRead(); startThreadedRead();
#endif
startThreadedWrite(); startThreadedWrite();
} }
void PIIODevice::stop() { void PIIODevice::stop() {
#ifndef PIP_NO_THREADS
stopThreadedRead(); stopThreadedRead();
#endif
stopThreadedWrite(); stopThreadedWrite();
} }
void PIIODevice::stopAndWait(PISystemTime timeout) { void PIIODevice::stopAndWait(PISystemTime timeout) {
stop(); stop();
#ifndef PIP_NO_THREADS
waitThreadedReadFinished(timeout); waitThreadedReadFinished(timeout);
#endif
waitThreadedWriteFinished(timeout); waitThreadedWriteFinished(timeout);
} }
@@ -333,11 +357,10 @@ void PIIODevice::_init() {
setOptions(0); setOptions(0);
setReopenEnabled(true); setReopenEnabled(true);
setReopenTimeout(1_s); setReopenTimeout(1_s);
#ifdef MICRO_PIP #ifdef PIP_NO_THREADS
threaded_read_buffer_size = 512; threaded_read_buffer_size = 512;
#else #else
threaded_read_buffer_size = 4_KiB; threaded_read_buffer_size = 4_KiB;
#endif
read_thread.setName("_S.PIIODev.read"); read_thread.setName("_S.PIIODev.read");
write_thread.setName("_S.PIIODev.write"); write_thread.setName("_S.PIIODev.write");
CONNECT(void, &write_thread, started, this, write_func); CONNECT(void, &write_thread, started, this, write_func);
@@ -345,9 +368,11 @@ void PIIODevice::_init() {
if (!isOpened()) open(); if (!isOpened()) open();
}); });
read_thread.setSlot([this](void *) { read_func(); }); read_thread.setSlot([this](void *) { read_func(); });
#endif // PIP_NO_THREADS
} }
#ifndef PIP_NO_THREADS
void PIIODevice::write_func() { void PIIODevice::write_func() {
while (!write_thread.isStopping()) { while (!write_thread.isStopping()) {
while (!write_queue.isEmpty()) { while (!write_queue.isEmpty()) {
@@ -362,15 +387,6 @@ void PIIODevice::write_func() {
} }
} }
PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
if (!prefix) return nullptr;
auto fi = fabrics().value(prefix);
if (fi.fabricator) return fi.fabricator();
return nullptr;
}
void PIIODevice::read_func() { void PIIODevice::read_func() {
if (!isReadable()) { if (!isReadable()) {
read_thread.stop(); read_thread.stop();
@@ -391,13 +407,20 @@ void PIIODevice::read_func() {
if (read_thread.isStopping()) return; if (read_thread.isStopping()) return;
if (readed_ <= 0) { if (readed_ <= 0) {
piMSleep(threaded_read_timeout_ms); piMSleep(threaded_read_timeout_ms);
// cout << readed_ << ", " << errno << ", " << errorString() << endl;
return; return;
} }
// piCoutObj << "readed" << readed_;// << ", " << errno << ", " << errorString();
threadedRead(buffer_tr.data(), readed_); threadedRead(buffer_tr.data(), readed_);
threadedReadEvent(buffer_tr.data(), readed_); threadedReadEvent(buffer_tr.data(), readed_);
} }
#endif // PIP_NO_THREADS
PIIODevice * PIIODevice::newDeviceByPrefix(const char * prefix) {
if (!prefix) return nullptr;
auto fi = fabrics().value(prefix);
if (fi.fabricator) return fi.fabricator();
return nullptr;
}
PIByteArray PIIODevice::readForTime(PISystemTime timeout) { PIByteArray PIIODevice::readForTime(PISystemTime timeout) {
@@ -420,6 +443,7 @@ PIByteArray PIIODevice::readForTime(PISystemTime timeout) {
} }
#ifndef PIP_NO_THREADS
ullong PIIODevice::writeThreaded(const PIByteArray & data) { ullong PIIODevice::writeThreaded(const PIByteArray & data) {
write_thread.lock(); write_thread.lock();
write_queue.enqueue(PIPair<PIByteArray, ullong>(data, tri)); write_queue.enqueue(PIPair<PIByteArray, ullong>(data, tri));
@@ -427,6 +451,7 @@ ullong PIIODevice::writeThreaded(const PIByteArray & data) {
write_thread.unlock(); write_thread.unlock();
return tri - 1; return tri - 1;
} }
#endif
bool PIIODevice::open() { bool PIIODevice::open() {
@@ -543,7 +568,7 @@ void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode *
if (o == "br"_a || o == "blockr"_a || o == "blockread"_a || o == "blockingread"_a) op |= BlockingRead; if (o == "br"_a || o == "blockr"_a || o == "blockread"_a || o == "blockingread"_a) op |= BlockingRead;
if (o == "bw"_a || o == "blockw"_a || o == "blockwrite"_a || o == "blockingwrite"_a) op |= BlockingWrite; if (o == "bw"_a || o == "blockw"_a || o == "blockwrite"_a || o == "blockingwrite"_a) op |= BlockingWrite;
if (o == "brw"_a || o == "bwr"_a || o == "blockrw"_a || o == "blockwr"_a || o == "blockreadrite"_a || if (o == "brw"_a || o == "bwr"_a || o == "blockrw"_a || o == "blockwr"_a || o == "blockreadrite"_a ||
o == "blockingreadwrite"_a) o == "blockingreadwrite"_a)
op |= BlockingRead | BlockingWrite; op |= BlockingRead | BlockingWrite;
} }
fpwm.cutRight(fpwm.length() - fpwm.findLast('(')).trim(); fpwm.cutRight(fpwm.length() - fpwm.findLast('(')).trim();
@@ -638,15 +663,20 @@ PIIODevice * PIIODevice::createFromVariant(const PIVariantTypes::IODevice & d) {
PIString PIIODevice::normalizeFullPath(const PIString & full_path) { PIString PIIODevice::normalizeFullPath(const PIString & full_path) {
#ifndef PIP_NO_THREADS
nfp_mutex.lock(); nfp_mutex.lock();
#endif
PIString ret = nfp_cache.value(full_path); PIString ret = nfp_cache.value(full_path);
if (!ret.isEmpty()) { if (!ret.isEmpty()) {
#ifndef PIP_NO_THREADS
nfp_mutex.unlock(); nfp_mutex.unlock();
#endif
return ret; return ret;
} }
#ifndef PIP_NO_THREADS
nfp_mutex.unlock(); nfp_mutex.unlock();
#endif
PIIODevice * d = createFromFullPath(full_path); PIIODevice * d = createFromFullPath(full_path);
// piCout << "normalizeFullPath" << d;
if (d == 0) return PIString(); if (d == 0) return PIString();
ret = d->constructFullPath(); ret = d->constructFullPath();
delete d; delete d;
@@ -655,7 +685,9 @@ PIString PIIODevice::normalizeFullPath(const PIString & full_path) {
void PIIODevice::cacheFullPath(const PIString & full_path, const PIIODevice * d) { void PIIODevice::cacheFullPath(const PIString & full_path, const PIIODevice * d) {
#ifndef PIP_NO_THREADS
PIMutexLocker nfp_ml(nfp_mutex); PIMutexLocker nfp_ml(nfp_mutex);
#endif
nfp_cache[full_path] = d->constructFullPath(); nfp_cache[full_path] = d->constructFullPath();
} }
+23 -24
View File
@@ -59,26 +59,20 @@ typedef std::function<bool(const uchar *, int, void *)> ReadRetFunc;
#else #else
# define REGISTER_DEVICE(name) \ # define REGISTER_DEVICE(name) \
STATIC_INITIALIZER_BEGIN \ STATIC_INITIALIZER_BEGIN \
PIIODevice::registerDevice(name::fullPathPrefixS(), #name, []() -> PIIODevice * { return new name(); }); \ PIIODevice::registerDevice(name::fullPathPrefixS(), #name, []() -> PIIODevice * { return new name(); }); \
STATIC_INITIALIZER_END STATIC_INITIALIZER_END
# define PIIODEVICE(name, prefix) \ # define PIIODEVICE(name, prefix) \
PIOBJECT_SUBCLASS(name, PIIODevice) \ PIOBJECT_SUBCLASS(name, PIIODevice) \
PIIODevice * copy() const override { \ PIIODevice * copy() const override { return new name(); } \
return new name(); \ \
} \ public: \
\ PIConstChars fullPathPrefix() const override { return prefix; } \
public: \ static PIConstChars fullPathPrefixS() { return prefix; } \
PIConstChars fullPathPrefix() const override { \ \
return prefix; \ private:
} \
static PIConstChars fullPathPrefixS() { \
return prefix; \
} \
\
private:
#endif #endif
@@ -248,7 +242,7 @@ public:
//! \~russian Возвращает пользовательские данные, передаваемые в callback потокового чтения. //! \~russian Возвращает пользовательские данные, передаваемые в callback потокового чтения.
void * threadedReadData() const { return ret_data_; } void * threadedReadData() const { return ret_data_; }
#ifndef PIP_NO_THREADS
//! \~english Returns whether threaded read is running. //! \~english Returns whether threaded read is running.
//! \~russian Возвращает, запущено ли потоковое чтение. //! \~russian Возвращает, запущено ли потоковое чтение.
bool isThreadedRead() const; bool isThreadedRead() const;
@@ -279,6 +273,7 @@ public:
//! \~english Waits until threaded read finishes or "timeout" expires. //! \~english Waits until threaded read finishes or "timeout" expires.
//! \~russian Ожидает завершения потокового чтения, но не дольше "timeout". //! \~russian Ожидает завершения потокового чтения, но не дольше "timeout".
bool waitThreadedReadFinished(PISystemTime timeout = {}); bool waitThreadedReadFinished(PISystemTime timeout = {});
#endif // PIP_NO_THREADS
//! \~english Returns delay between unsuccessful threaded read attempts in milliseconds. //! \~english Returns delay between unsuccessful threaded read attempts in milliseconds.
@@ -367,6 +362,7 @@ public:
PIByteArray readForTime(PISystemTime timeout); PIByteArray readForTime(PISystemTime timeout);
#ifndef PIP_NO_THREADS
//! \~english Queues "data" for threaded write and returns task ID. //! \~english Queues "data" for threaded write and returns task ID.
//! \~russian Помещает "data" в очередь потоковой записи и возвращает ID задания. //! \~russian Помещает "data" в очередь потоковой записи и возвращает ID задания.
ullong writeThreaded(const void * data, ssize_t max_size) { return writeThreaded(PIByteArray(data, uint(max_size))); } ullong writeThreaded(const void * data, ssize_t max_size) { return writeThreaded(PIByteArray(data, uint(max_size))); }
@@ -374,6 +370,7 @@ public:
//! \~english Queues byte array "data" for threaded write and returns task ID. //! \~english Queues byte array "data" for threaded write and returns task ID.
//! \~russian Помещает массив байт "data" в очередь потоковой записи и возвращает ID задания. //! \~russian Помещает массив байт "data" в очередь потоковой записи и возвращает ID задания.
ullong writeThreaded(const PIByteArray & data); ullong writeThreaded(const PIByteArray & data);
#endif
//! \~english Configures the device from section "section" of file "config_file". //! \~english Configures the device from section "section" of file "config_file".
@@ -611,16 +608,18 @@ private:
static PIMap<PIConstChars, FabricInfo> & fabrics(); static PIMap<PIConstChars, FabricInfo> & fabrics();
PITimeMeasurer tm, reopen_tm; PITimeMeasurer tm, reopen_tm;
PIThread read_thread, write_thread;
PIByteArray buffer_in, buffer_tr; PIByteArray buffer_in, buffer_tr;
PIQueue<PIPair<PIByteArray, ullong>> write_queue;
PISystemTime reopen_timeout; PISystemTime reopen_timeout;
ullong tri = 0; ullong tri = 0;
uint threaded_read_buffer_size, threaded_read_timeout_ms = 10; uint threaded_read_buffer_size, threaded_read_timeout_ms = 10;
bool reopen_enabled = true, destroying = false; bool reopen_enabled = true, destroying = false;
static PIMutex nfp_mutex;
static PIMap<PIString, PIString> nfp_cache; static PIMap<PIString, PIString> nfp_cache;
#ifndef PIP_NO_THREADS
PIThread read_thread, write_thread;
PIQueue<PIPair<PIByteArray, ullong>> write_queue;
static PIMutex nfp_mutex;
#endif
}; };
#endif // PIIODEVICE_H #endif // PIIODEVICE_H
+20 -16
View File
@@ -23,20 +23,22 @@
#include "pidatatransfer.h" #include "pidatatransfer.h"
#include "piliterals_time.h" #include "piliterals_time.h"
#include "pipropertystorage.h" #include "pipropertystorage.h"
#include "pitime.h"
#define _PIPEER_MSG_SIZE 4000 #ifndef PIP_NO_SOCKET
#define _PIPEER_MSG_TTL 100 # include "pitime.h"
#define _PIPEER_MULTICAST_TTL 4
#define _PIPEER_MULTICAST_IP "232.13.3.12" # define _PIPEER_MSG_SIZE 4000
#define _PIPEER_LOOPBACK_PORT_S 13313 # define _PIPEER_MSG_TTL 100
#define _PIPEER_LOOPBACK_PORT_E (13313 + 32) # define _PIPEER_MULTICAST_TTL 4
#define _PIPEER_MULTICAST_PORT 13360 # define _PIPEER_MULTICAST_IP "232.13.3.12"
#define _PIPEER_TCP_PORT _PIPEER_MULTICAST_PORT # define _PIPEER_LOOPBACK_PORT_S 13313
#define _PIPEER_BROADCAST_PORT 13361 # define _PIPEER_LOOPBACK_PORT_E (13313 + 32)
#define _PIPEER_TRAFFIC_PORT_S 13400 # define _PIPEER_MULTICAST_PORT 13360
#define _PIPEER_TRAFFIC_PORT_E 14000 # define _PIPEER_TCP_PORT _PIPEER_MULTICAST_PORT
#define _PIPEER_PING_TIMEOUT 5.0 # define _PIPEER_BROADCAST_PORT 13361
# define _PIPEER_TRAFFIC_PORT_S 13400
# define _PIPEER_TRAFFIC_PORT_E 14000
# define _PIPEER_PING_TIMEOUT 5.0
class PIPeer::PeerData: public PIObject { class PIPeer::PeerData: public PIObject {
PIOBJECT_SUBCLASS(PeerData, PIObject); PIOBJECT_SUBCLASS(PeerData, PIObject);
@@ -893,11 +895,11 @@ void PIPeer::pingNeighbours() {
bool PIPeer::openDevice() { bool PIPeer::openDevice() {
PIConfig conf( PIConfig conf(
#ifndef WINDOWS # ifndef WINDOWS
"/etc/pip.conf" "/etc/pip.conf"
#else # else
"pip.conf" "pip.conf"
#endif # endif
, ,
PIIODevice::ReadOnly); PIIODevice::ReadOnly);
server_ip = conf.getValue("peer_server_ip", "").toString(); server_ip = conf.getValue("peer_server_ip", "").toString();
@@ -1176,3 +1178,5 @@ bool PIPeer::hasPeer(const PIString & name) {
if (i.name == name) return true; if (i.name == name) return true;
return false; return false;
} }
#endif // PIP_NO_SOCKET
+3 -2
View File
@@ -34,10 +34,11 @@
//! \~russian Именованный сетевой пир, построенный поверх %PIIODevice. //! \~russian Именованный сетевой пир, построенный поверх %PIIODevice.
//! \~\details //! \~\details
//! \~english //! \~english
//! The class discovers peers, routes packets by peer name and can expose a trusted-peer stream through inherited \a read() and \a write(). //! The class discovers peers, routes packets by peer name and can expose a trusted-peer stream through inherited \a read() и \a write().
//! \~russian //! \~russian
//! Класс обнаруживает пиры, маршрутизирует пакеты по имени пира и может предоставлять поток trusted-peer через унаследованные \a read() и //! Класс обнаруживает пиры, маршрутизирует пакеты по имени пира и может предоставлять поток trusted-peer через унаследованные \a read() и
//! \a write(). //! \a write().
#ifndef PIP_NO_SOCKET
class PIP_EXPORT PIPeer: public PIIODevice { class PIP_EXPORT PIPeer: public PIIODevice {
PIIODEVICE(PIPeer, "peer"); PIIODEVICE(PIPeer, "peer");
@@ -436,6 +437,6 @@ BINARY_STREAM_READ(PIPeer::PeerInfo) {
s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time; s >> v.name >> v.addresses >> v.dist >> v.neighbours >> v.cnt >> v.time;
return s; return s;
} }
#endif // PIP_NO_SOCKET
#endif // PIPEER_H #endif // PIPEER_H
+2 -2
View File
@@ -19,7 +19,7 @@
#include "piserial.h" #include "piserial.h"
#ifndef MICRO_PIP #ifndef PIP_NO_SERIAL
# include "piconfig.h" # include "piconfig.h"
# include "pidir.h" # include "pidir.h"
@@ -1321,4 +1321,4 @@ void PISerial::threadedReadBufferSizeChanged() {
# endif # endif
} }
#endif // MICRO_PIP #endif // PIP_NO_SERIAL
+2 -2
View File
@@ -43,11 +43,11 @@ REGISTER_DEVICE(PISPI)
PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode): PIIODevice(path, mode) { PISPI::PISPI(const PIString & path, uint speed, PIIODevice::DeviceMode mode): PIIODevice(path, mode) {
#ifdef MICRO_PIP #ifdef PIP_NO_THREADS
setThreadedReadBufferSize(512); setThreadedReadBufferSize(512);
#else #else
setThreadedReadBufferSize(1024); setThreadedReadBufferSize(1024);
#endif #endif // PIP_NO_THREADS
setPath(path); setPath(path);
setSpeed(speed); setSpeed(speed);
setBits(8); setBits(8);
+32 -3
View File
@@ -27,7 +27,12 @@
const uint PIBaseTransfer::signature = 0x54424950; const uint PIBaseTransfer::signature = 0x54424950;
PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) { PIBaseTransfer::PIBaseTransfer()
: crc(standardCRC_16())
#ifndef PIP_NO_THREADS
, diag(false)
#endif
{
header.sig = signature; header.sig = signature;
crc_enabled = true; crc_enabled = true;
header.session_id = 0; header.session_id = 0;
@@ -39,12 +44,14 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
send_queue = 0; send_queue = 0;
send_up = 0; send_up = 0;
timeout_ = 10.; timeout_ = 10.;
#ifndef PIP_NO_THREADS
diag.setDisconnectTimeout(PISystemTime::fromSeconds(timeout_ / 10.)); diag.setDisconnectTimeout(PISystemTime::fromSeconds(timeout_ / 10.));
diag.setName("PIBaseTransfer"); diag.setName("PIBaseTransfer");
diag.start(20_Hz); diag.start(20_Hz);
#endif
packets_count = 10; packets_count = 10;
#ifdef MICRO_PIP #ifdef PIP_EMBEDDED
setPacketSize(512); setPacketSize(1024);
#else #else
setPacketSize(4096); setPacketSize(4096);
#endif #endif
@@ -53,7 +60,9 @@ PIBaseTransfer::PIBaseTransfer(): crc(standardCRC_16()), diag(false) {
PIBaseTransfer::~PIBaseTransfer() { PIBaseTransfer::~PIBaseTransfer() {
#ifndef PIP_NO_THREADS
diag.stopAndWait(); diag.stopAndWait();
#endif
break_ = true; break_ = true;
} }
@@ -85,14 +94,18 @@ void PIBaseTransfer::setPause(bool pause_) {
void PIBaseTransfer::setTimeout(double sec) { void PIBaseTransfer::setTimeout(double sec) {
timeout_ = sec; timeout_ = sec;
#ifndef PIP_NO_THREADS
diag.setDisconnectTimeout(PISystemTime::fromSeconds(sec)); diag.setDisconnectTimeout(PISystemTime::fromSeconds(sec));
#endif
} }
void PIBaseTransfer::received(PIByteArray data) { void PIBaseTransfer::received(PIByteArray data) {
packet_header_size = sizeof(PacketHeader) + customHeader().size(); packet_header_size = sizeof(PacketHeader) + customHeader().size();
if (data.size() < sizeof(PacketHeader)) { if (data.size() < sizeof(PacketHeader)) {
#ifndef PIP_NO_THREADS
diag.received(data.size(), false); diag.received(data.size(), false);
#endif
return; return;
} }
PacketHeader h; PacketHeader h;
@@ -100,10 +113,14 @@ void PIBaseTransfer::received(PIByteArray data) {
PacketType pt = (PacketType)h.type; PacketType pt = (PacketType)h.type;
if (!h.check_sig()) { if (!h.check_sig()) {
piCoutObj << "invalid packet signature"_tr("PIBaseTransfer"); piCoutObj << "invalid packet signature"_tr("PIBaseTransfer");
#ifndef PIP_NO_THREADS
diag.received(data.size(), false); diag.received(data.size(), false);
#endif
return; return;
} else } else
#ifndef PIP_NO_THREADS
diag.received(data.size(), true); diag.received(data.size(), true);
#endif
// piCoutObj << "receive" << h.session_id << h.type << h.id; // piCoutObj << "receive" << h.session_id << h.type << h.id;
switch (pt) { switch (pt) {
case pt_Unknown: break; case pt_Unknown: break;
@@ -244,7 +261,9 @@ void PIBaseTransfer::received(PIByteArray data) {
replies.resize(sr.packets + 1); replies.resize(sr.packets + 1);
replies.fill(pt_Unknown); replies.fill(pt_Unknown);
pm_string.resize(replies.size(), '-'); pm_string.resize(replies.size(), '-');
#ifndef PIP_NO_THREADS
diag.reset(); diag.reset();
#endif
// piCoutObj << "receiveStarted()"; // piCoutObj << "receiveStarted()";
is_receiving = true; is_receiving = true;
break_ = false; break_ = false;
@@ -291,7 +310,9 @@ bool PIBaseTransfer::send_process() {
mutex_session.lock(); mutex_session.lock();
packet_header_size = sizeof(PacketHeader) + customHeader().size(); packet_header_size = sizeof(PacketHeader) + customHeader().size();
break_ = false; break_ = false;
#ifndef PIP_NO_THREADS
diag.reset(); diag.reset();
#endif
sendStarted(); sendStarted();
is_sending = true; is_sending = true;
int session_size = session.size(); int session_size = session.size();
@@ -339,7 +360,9 @@ bool PIBaseTransfer::send_process() {
} }
stm.reset(); stm.reset();
ba = build_packet(i); ba = build_packet(i);
#ifndef PIP_NO_THREADS
diag.sended(ba.size_s()); diag.sended(ba.size_s());
#endif
sendRequest(ba); sendRequest(ba);
pm_string[i + 1] = '+'; pm_string[i + 1] = '+';
mutex_send.lock(); mutex_send.lock();
@@ -392,7 +415,9 @@ bool PIBaseTransfer::send_process() {
continue; continue;
} }
ba = build_packet(chk - 1); ba = build_packet(chk - 1);
#ifndef PIP_NO_THREADS
diag.sended(ba.size_s()); diag.sended(ba.size_s());
#endif
sendRequest(ba); sendRequest(ba);
pm_string[chk] = '+'; pm_string[chk] = '+';
mutex_send.lock(); mutex_send.lock();
@@ -497,7 +522,9 @@ void PIBaseTransfer::sendReply(PacketType reply) {
header.type = reply; header.type = reply;
PIByteArray ba; PIByteArray ba;
ba << header; ba << header;
#ifndef PIP_NO_THREADS
if (is_sending || is_receiving) diag.sended(ba.size_s()); if (is_sending || is_receiving) diag.sended(ba.size_s());
#endif
sendRequest(ba); sendRequest(ba);
} }
@@ -516,7 +543,9 @@ bool PIBaseTransfer::getStartRequest() {
state_string = "send request"; state_string = "send request";
PITimeMeasurer tm; PITimeMeasurer tm;
while (tm.elapsed_s() < timeout_) { while (tm.elapsed_s() < timeout_) {
#ifndef PIP_NO_THREADS
diag.sended(ba.size_s()); diag.sended(ba.size_s());
#endif
sendRequest(ba); sendRequest(ba);
if (break_) return false; if (break_) return false;
// piCoutObj << replies[0]; // piCoutObj << replies[0];
+4
View File
@@ -159,12 +159,14 @@ public:
//! \~russian Возвращает число байтов, уже обработанных в текущей сессии. //! \~russian Возвращает число байтов, уже обработанных в текущей сессии.
llong bytesCur() const { return bytes_cur; } llong bytesCur() const { return bytes_cur; }
#ifndef PIP_NO_THREADS
//! \~english Get diagnostics object //! \~english Get diagnostics object
//! \~russian Получить объект диагностики //! \~russian Получить объект диагностики
//! \~\return //! \~\return
//! \~english Diagnostic object reference //! \~english Diagnostic object reference
//! \~russian Ссылка на объект диагностики //! \~russian Ссылка на объект диагностики
const PIDiagnostics & diagnostic() { return diag; } const PIDiagnostics & diagnostic() { return diag; }
#endif
//! \~english Returns the packet signature constant used by the protocol. //! \~english Returns the packet signature constant used by the protocol.
//! \~russian Возвращает константу сигнатуры пакета, используемую протоколом. //! \~russian Возвращает константу сигнатуры пакета, используемую протоколом.
@@ -344,7 +346,9 @@ private:
CRC_16 crc; CRC_16 crc;
int send_queue; int send_queue;
int send_up; int send_up;
#ifndef PIP_NO_THREADS
PIDiagnostics diag; PIDiagnostics diag;
#endif
PIMutex mutex_session; PIMutex mutex_session;
PIMutex mutex_send; PIMutex mutex_send;
PIMutex mutex_header; PIMutex mutex_header;
+2
View File
@@ -34,6 +34,7 @@
//! \~\brief //! \~\brief
//! \~english Multi-channel sender and receiver over multicast, broadcast and loopback endpoints. //! \~english Multi-channel sender and receiver over multicast, broadcast and loopback endpoints.
//! \~russian Многоканальный отправитель и приемник через multicast-, broadcast- и loopback-конечные точки. //! \~russian Многоканальный отправитель и приемник через multicast-, broadcast- и loopback-конечные точки.
#ifndef PIP_NO_SOCKET
class PIP_IO_UTILS_EXPORT PIBroadcast class PIP_IO_UTILS_EXPORT PIBroadcast
: public PIThread : public PIThread
, public PIEthUtilBase { , public PIEthUtilBase {
@@ -182,5 +183,6 @@ private:
int lo_pcnt; int lo_pcnt;
bool _started, _send_only, _reinit; bool _started, _send_only, _reinit;
}; };
#endif // PIP_NO_SOCKET
#endif // PIBROADCAST_H #endif // PIBROADCAST_H
+5 -1
View File
@@ -23,7 +23,9 @@
#include "piiostream.h" #include "piiostream.h"
#include "piliterals_time.h" #include "piliterals_time.h"
#include "pitime.h" #include "pitime.h"
#include "pitranslator.h"
#ifndef PIP_NO_THREADS
# include "pitranslator.h"
/** \class PIConnection /** \class PIConnection
* \brief Complex Input/Output point * \brief Complex Input/Output point
@@ -1294,3 +1296,5 @@ __DevicePoolContainer__::__DevicePoolContainer__() {
inited_ = true; inited_ = true;
__device_pool__ = new PIConnection::DevicePool(); __device_pool__ = new PIConnection::DevicePool();
} }
#endif // PIP_NO_THREADS
+16
View File
@@ -379,6 +379,7 @@ public:
bool isEmpty() const { return device_modes.isEmpty(); } bool isEmpty() const { return device_modes.isEmpty(); }
#ifndef PIP_NO_THREADS
//! \~english Returns diagnostics object for device or filter "full_path_name". //! \~english Returns diagnostics object for device or filter "full_path_name".
//! \~russian Возвращает объект диагностики для устройства или фильтра "full_path_name". //! \~russian Возвращает объект диагностики для устройства или фильтра "full_path_name".
PIDiagnostics * diagnostic(const PIString & full_path_name) const; PIDiagnostics * diagnostic(const PIString & full_path_name) const;
@@ -386,6 +387,7 @@ public:
//! \~english Returns diagnostics object associated with device or filter "dev". //! \~english Returns diagnostics object associated with device or filter "dev".
//! \~russian Возвращает объект диагностики, связанный с устройством или фильтром "dev". //! \~russian Возвращает объект диагностики, связанный с устройством или фильтром "dev".
PIDiagnostics * diagnostic(const PIIODevice * dev) const { return diags_.value(const_cast<PIIODevice *>(dev), 0); } PIDiagnostics * diagnostic(const PIIODevice * dev) const { return diags_.value(const_cast<PIIODevice *>(dev), 0); }
#endif
//! \~english Writes "data" to device resolved by full path "full_path". //! \~english Writes "data" to device resolved by full path "full_path".
//! \~russian Записывает "data" в устройство, найденное по полному пути "full_path". //! \~russian Записывает "data" в устройство, найденное по полному пути "full_path".
@@ -415,6 +417,7 @@ public:
//! \~russian Возвращает, работает ли общий пул устройств в режиме имитации. //! \~russian Возвращает, работает ли общий пул устройств в режиме имитации.
static bool isFakeMode(); static bool isFakeMode();
#ifndef PIP_NO_THREADS
class PIP_EXPORT DevicePool: public PIThread { class PIP_EXPORT DevicePool: public PIThread {
PIOBJECT_SUBCLASS(DevicePool, PIThread); PIOBJECT_SUBCLASS(DevicePool, PIThread);
friend void __DevicePool_threadReadDP(void * ddp); friend void __DevicePool_threadReadDP(void * ddp);
@@ -456,6 +459,7 @@ public:
PIMap<PIString, DeviceData *> devices; PIMap<PIString, DeviceData *> devices;
bool fake; bool fake;
}; };
#endif // PIP_NO_THREADS
//! \events //! \events
@@ -471,10 +475,12 @@ public:
//! \~russian Генерируется, когда фильтр "from" выдает пакет. //! \~russian Генерируется, когда фильтр "from" выдает пакет.
EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data); EVENT2(packetReceivedEvent, const PIString &, from, const PIByteArray &, data);
#ifndef PIP_NO_THREADS
//! \fn void qualityChanged(const PIIODevice * device, PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality) //! \fn void qualityChanged(const PIIODevice * device, PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality)
//! \~english Emitted when diagnostics quality of "device" changes. //! \~english Emitted when diagnostics quality of "device" changes.
//! \~russian Генерируется при изменении качества диагностики устройства "device". //! \~russian Генерируется при изменении качества диагностики устройства "device".
EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality); EVENT3(qualityChanged, const PIIODevice *, dev, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
#endif
//! \} //! \}
@@ -496,7 +502,9 @@ private:
void rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data); void rawReceived(PIIODevice * dev, const PIString & from, const PIByteArray & data);
void unboundExtractor(PIPacketExtractor * pe); void unboundExtractor(PIPacketExtractor * pe);
EVENT_HANDLER2(void, packetExtractorReceived, const uchar *, data, int, size); EVENT_HANDLER2(void, packetExtractorReceived, const uchar *, data, int, size);
#ifndef PIP_NO_THREADS
EVENT_HANDLER2(void, diagQualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality); EVENT_HANDLER2(void, diagQualityChanged, PIDiagnostics::Quality, new_quality, PIDiagnostics::Quality, old_quality);
#endif
PIString devPath(const PIIODevice * d) const; PIString devPath(const PIIODevice * d) const;
PIString devFPath(const PIIODevice * d) const; PIString devFPath(const PIIODevice * d) const;
@@ -509,6 +517,7 @@ private:
PIVector<PIIODevice *> devices; PIVector<PIIODevice *> devices;
}; };
#ifndef PIP_NO_THREADS
class PIP_EXPORT Sender: public PITimer { class PIP_EXPORT Sender: public PITimer {
PIOBJECT_SUBCLASS(Sender, PIObject); PIOBJECT_SUBCLASS(Sender, PIObject);
@@ -521,18 +530,24 @@ private:
PISystemTime int_; PISystemTime int_;
void tick(int) override; void tick(int) override;
}; };
#endif
PIMap<PIString, Extractor *> extractors; PIMap<PIString, Extractor *> extractors;
#ifndef PIP_NO_THREADS
PIMap<PIString, Sender *> senders; PIMap<PIString, Sender *> senders;
#endif
PIMap<PIString, PIIODevice *> device_names; PIMap<PIString, PIIODevice *> device_names;
PIMap<PIIODevice *, PIIODevice::DeviceMode> device_modes; PIMap<PIIODevice *, PIIODevice::DeviceMode> device_modes;
PIMap<PIIODevice *, PIVector<PIPacketExtractor *>> bounded_extractors; PIMap<PIIODevice *, PIVector<PIPacketExtractor *>> bounded_extractors;
PIMap<PIIODevice *, PIVector<PIIODevice *>> channels_; PIMap<PIIODevice *, PIVector<PIIODevice *>> channels_;
#ifndef PIP_NO_THREADS
PIMap<PIIODevice *, PIDiagnostics *> diags_; PIMap<PIIODevice *, PIDiagnostics *> diags_;
#endif
static PIVector<PIConnection *> _connections; static PIVector<PIConnection *> _connections;
}; };
#ifndef PIP_NO_THREADS
void __DevicePool_threadReadDP(void * ddp); void __DevicePool_threadReadDP(void * ddp);
extern PIP_EXPORT PIConnection::DevicePool * __device_pool__; extern PIP_EXPORT PIConnection::DevicePool * __device_pool__;
@@ -544,6 +559,7 @@ public:
}; };
static __DevicePoolContainer__ __device_pool_container__; static __DevicePoolContainer__ __device_pool_container__;
#endif // PIP_NO_THREADS
#endif // PICONNECTION_H #endif // PICONNECTION_H
+6 -2
View File
@@ -19,8 +19,10 @@
#include "pidiagnostics.h" #include "pidiagnostics.h"
#include "piliterals_time.h" #ifndef PIP_NO_THREADS
#include "pitranslator.h"
# include "piliterals_time.h"
# include "pitranslator.h"
/** \class PIDiagnostics /** \class PIDiagnostics
@@ -250,3 +252,5 @@ void PIDiagnostics::changeDisconnectTimeout(PISystemTime disct) {
// piCoutObj << hist_size << disconn_ << interval(); // piCoutObj << hist_size << disconn_ << interval();
mutex_state.unlock(); mutex_state.unlock();
} }
#endif // PIP_NO_THREADS
+3 -1
View File
@@ -29,6 +29,7 @@
#include "pitimer.h" #include "pitimer.h"
#ifndef PIP_NO_THREADS
//! \~\ingroup IO-Utils //! \~\ingroup IO-Utils
//! \brief //! \brief
//! \~english Connection diagnostics for packet frequency, throughput and receive quality //! \~english Connection diagnostics for packet frequency, throughput and receive quality
@@ -56,7 +57,7 @@ public:
enum Quality { enum Quality {
Unknown = 1 /** \~english No receive history yet \~russian История приема еще отсутствует */, Unknown = 1 /** \~english No receive history yet \~russian История приема еще отсутствует */,
Failure = 2 /** \~english No correct packets in the recent window \~russian В недавнем окне нет корректных пакетов */, Failure = 2 /** \~english No correct packets in the recent window \~russian В недавнем окне нет корректных пакетов */,
Bad = 3 /** \~english Correct packets are at most 20 percent \~russian Корректных пакетов не более 20 процентов */, Bad = 3 /** \~english Correct packets are at most 20 percent \~russian Корректных пакетов не более 20 процентов */,
Average = Average =
4 /** \~english Correct packets are above 20 and up to 80 percent \~russian Корректных пакетов больше 20 и до 80 процентов */ 4 /** \~english Correct packets are above 20 and up to 80 percent \~russian Корректных пакетов больше 20 и до 80 процентов */
, ,
@@ -235,5 +236,6 @@ inline bool operator!=(const PIDiagnostics::Entry & f, const PIDiagnostics::Entr
inline bool operator<(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s) { inline bool operator<(const PIDiagnostics::Entry & f, const PIDiagnostics::Entry & s) {
return f.bytes_ok < s.bytes_ok; return f.bytes_ok < s.bytes_ok;
} }
#endif // PIP_NO_THREADS
#endif // PIDIAGNOSTICS_H #endif // PIDIAGNOSTICS_H
+2
View File
@@ -24,6 +24,7 @@
#ifndef PIETHUTILBASE_H #ifndef PIETHUTILBASE_H
#define PIETHUTILBASE_H #define PIETHUTILBASE_H
#ifndef PIP_NO_SOCKET
#include "pibytearray.h" #include "pibytearray.h"
#include "pip_io_utils_export.h" #include "pip_io_utils_export.h"
@@ -96,4 +97,5 @@ private:
bool _crypt; bool _crypt;
}; };
#endif // PIP_NO_SOCKET
#endif // PIETHUTILBASE_H #endif // PIETHUTILBASE_H
+3
View File
@@ -19,6 +19,7 @@
#include "pifiletransfer.h" #include "pifiletransfer.h"
#ifndef PIP_NO_FILESYSTEM
const char PIFileTransfer::sign[] = {'P', 'F', 'T'}; const char PIFileTransfer::sign[] = {'P', 'F', 'T'};
PIFileTransfer::PIFileTransfer() { PIFileTransfer::PIFileTransfer() {
@@ -339,3 +340,5 @@ void PIFileTransfer::send_finished(bool ok) {
work_file.close(); work_file.close();
} }
} }
#endif // PIP_NO_FILESYSTEM
+6 -3
View File
@@ -31,7 +31,8 @@
#include "pibasetransfer.h" #include "pibasetransfer.h"
#include "pidir.h" #include "pidir.h"
#define __PIFILETRANSFER_VERSION 2 #ifndef PIP_NO_FILESYSTEM
# define __PIFILETRANSFER_VERSION 2
//! \~\ingroup IO-Utils //! \~\ingroup IO-Utils
@@ -70,7 +71,7 @@ public:
PIString dest_path; PIString dest_path;
}; };
#pragma pack(push, 1) # pragma pack(push, 1)
//! \~english Custom packet header used by the file-transfer protocol. //! \~english Custom packet header used by the file-transfer protocol.
//! \~russian Пользовательский заголовок пакета, используемый протоколом передачи файлов. //! \~russian Пользовательский заголовок пакета, используемый протоколом передачи файлов.
@@ -104,7 +105,7 @@ public:
return true; return true;
} }
}; };
#pragma pack(pop) # pragma pack(pop)
//! \~english Sends one file-system entry identified by "file". //! \~english Sends one file-system entry identified by "file".
@@ -262,4 +263,6 @@ inline PICout operator<<(PICout s, const PIFileTransfer::PFTFileInfo & v) {
s.restoreControls(); s.restoreControls();
return s; return s;
} }
#endif // PIP_NO_FILESYSTEM
#endif // PIFILETRANSFER_H #endif // PIFILETRANSFER_H
+3
View File
@@ -24,6 +24,7 @@
#ifndef pipackedtcp_H #ifndef pipackedtcp_H
#define pipackedtcp_H #define pipackedtcp_H
#ifndef PIP_NO_SOCKET
#include "piiodevice.h" #include "piiodevice.h"
#include "pinetworkaddress.h" #include "pinetworkaddress.h"
@@ -122,4 +123,6 @@ private:
REGISTER_DEVICE(PIPackedTCP) REGISTER_DEVICE(PIPackedTCP)
#endif // PIP_NO_SOCKET
#endif #endif
+2 -2
View File
@@ -98,8 +98,8 @@ void PIPacketExtractor::construct() {
func_payload = nullptr; func_payload = nullptr;
setPayloadSize(0); setPayloadSize(0);
setTimeout(100_ms); setTimeout(100_ms);
#ifdef MICRO_PIP #ifdef PIP_EMBEDDED
setThreadedReadBufferSize(512); setThreadedReadBufferSize(16_KiB);
#else #else
setThreadedReadBufferSize(64_KiB); setThreadedReadBufferSize(64_KiB);
#endif #endif
+2
View File
@@ -24,6 +24,7 @@
#ifndef PISTREAMPACKER_H #ifndef PISTREAMPACKER_H
#define PISTREAMPACKER_H #define PISTREAMPACKER_H
#ifndef PIP_NO_SOCKET
#include "piethutilbase.h" #include "piethutilbase.h"
#include "piobject.h" #include "piobject.h"
@@ -200,4 +201,5 @@ private:
mutable PIMutex prog_s_mutex, prog_r_mutex; mutable PIMutex prog_s_mutex, prog_r_mutex;
}; };
#endif // PIP_NO_SOCKET
#endif // PISTREAMPACKER_H #endif // PISTREAMPACKER_H
+2 -2
View File
@@ -19,7 +19,7 @@
#include "pifft.h" #include "pifft.h"
#ifndef MICRO_PIP #ifndef PIP_NO_FFT
PIFFT_double::PIFFT_double() {} PIFFT_double::PIFFT_double() {}
@@ -1961,4 +1961,4 @@ void PIFFT_float::ftbase_ffttwcalc(PIVector<float> * a, int aoffset, int n1, int
} }
} }
#endif // MICRO_PIP #endif // PIP_NO_FFT
+13 -13
View File
@@ -59,7 +59,7 @@
#include "pimathcomplex.h" #include "pimathcomplex.h"
#ifndef MICRO_PIP #ifndef PIP_NO_FFT
# include "pip_fftw_export.h" # include "pip_fftw_export.h"
@@ -225,17 +225,17 @@ typedef PIFFT_float PIFFTf;
# ifndef CC_VC # ifndef CC_VC
# define _PIFFTW_H(type) \ # define _PIFFTW_H(type) \
class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \ class PIP_FFTW_EXPORT _PIFFTW_P_##type##_ { \
public: \ public: \
_PIFFTW_P_##type##_(); \ _PIFFTW_P_##type##_(); \
~_PIFFTW_P_##type##_(); \ ~_PIFFTW_P_##type##_(); \
const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \ const PIVector<complex<type>> & calcFFT(const PIVector<complex<type>> & in); \
const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \ const PIVector<complex<type>> & calcFFTR(const PIVector<type> & in); \
const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \ const PIVector<complex<type>> & calcFFTI(const PIVector<complex<type>> & in); \
void preparePlan(int size, int op); \ void preparePlan(int size, int op); \
void * impl; \ void * impl; \
}; };
_PIFFTW_H(float) _PIFFTW_H(float)
_PIFFTW_H(double) _PIFFTW_H(double)
_PIFFTW_H(ldouble) _PIFFTW_H(ldouble)
@@ -384,6 +384,6 @@ typedef PIFFTW<ldouble> PIFFTWld;
# endif # endif
#endif // MICRO_PIP #endif // PIP_NO_FFT
#endif // PIFFT_H #endif // PIFFT_H
+33 -13
View File
@@ -4,27 +4,28 @@
//! \~english //! \~english
//! \~russian //! \~russian
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
MQTT common types MQTT common types
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef pimqtttypes_h #ifndef pimqtttypes_h
#define pimqtttypes_h #define pimqtttypes_h
#include "pibinarystream.h"
#include "pip_export.h" #include "pip_export.h"
#include "pistringlist.h" #include "pistringlist.h"
@@ -159,7 +160,26 @@ public:
//! \~russian Возвращает ID сообщения. //! \~russian Возвращает ID сообщения.
MessageMutable & setID(int id); MessageMutable & setID(int id);
}; };
template<typename P>
inline PIBinaryStream<P> & operator<<(PIBinaryStream<P> & s, const MessageConst & v) {
s << v.topic() << v.pathArguments() << v.payload() << v.properties() << static_cast<int>(v.qos()) << v.ID() << v.isDuplicate();
return s;
}
template<typename P>
inline PIBinaryStream<P> & operator>>(PIBinaryStream<P> & s, MessageMutable & v) {
PIString topic;
PIMap<PIString, PIString> path_args;
PIByteArray payload;
PIMap<int, PIString> props;
int qos_val, msg_id;
bool is_dup;
s >> topic >> path_args >> payload >> props >> qos_val >> msg_id >> is_dup;
v.setTopic(topic).setPayload(payload).setQos(static_cast<QoS>(qos_val)).setID(msg_id).setDuplicate(is_dup);
v.pathArguments() = path_args;
v.properties() = props;
return s;
}
}; // namespace PIMQTT }; // namespace PIMQTT
+10 -15
View File
@@ -74,12 +74,6 @@
//! \~russian Определяется для целевых сборок FreeBSD. //! \~russian Определяется для целевых сборок FreeBSD.
# define FREE_BSD # define FREE_BSD
//! \~\ingroup Core
//! \~\brief
//! \~english Defined for reduced embedded PIP builds.
//! \~russian Определяется для облегченных встраиваемых сборок PIP.
# define MICRO_PIP
//! \~\ingroup Core //! \~\ingroup Core
//! \~\brief //! \~\brief
//! \~english Defined when the target architecture is 32-bit. //! \~english Defined when the target architecture is 32-bit.
@@ -153,23 +147,24 @@
#ifdef PIP_FREERTOS #ifdef PIP_FREERTOS
# define FREERTOS # define FREERTOS
#endif #endif
#ifdef MICRO_PIP #ifdef PICO_SDK
# ifndef FREERTOS
# define PIP_NO_THREADS
# endif
# ifndef LWIP
# define PIP_NO_SOCKET
# endif
# define PISERIAL_NO_PINS # define PISERIAL_NO_PINS
#endif #endif
#ifdef FREERTOS
# ifndef PISERIAL_NO_PINS
# define PISERIAL_NO_PINS
# endif
#endif
#ifndef WINDOWS #ifndef WINDOWS
# ifndef QNX # ifndef QNX
# ifndef FREE_BSD # ifndef FREE_BSD
# ifndef MAC_OS # ifndef MAC_OS
# ifndef ANDROID # ifndef ANDROID
# ifndef BLACKBERRY # ifndef BLACKBERRY
# ifndef MICRO_PIP # ifndef FREERTOS
# define LINUX # ifndef PICO_SDK
# define LINUX
# endif
# endif # endif
# endif # endif
# endif # endif
@@ -43,11 +43,15 @@ PIString mask(const PIString & str) {
} }
PIString overrideFile(PIString path) { PIString overrideFile(PIString path) {
#ifndef PIP_NO_FILESYSTEM
if (path.isEmpty()) return {}; if (path.isEmpty()) return {};
PIFile::FileInfo fi(path); PIFile::FileInfo fi(path);
auto ext = fi.extension(); auto ext = fi.extension();
path.insert(path.size_s() - ext.size_s() - (ext.isEmpty() ? 0 : 1), ".override"); path.insert(path.size_s() - ext.size_s() - (ext.isEmpty() ? 0 : 1), ".override");
return path; return path;
#else
return path;
#endif
} }
@@ -138,7 +142,9 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
PIMap<PIString, PIString> substitutions; PIMap<PIString, PIString> substitutions;
if (!device) return ret; if (!device) return ret;
PIString base_path; PIString base_path;
#ifndef PIP_NO_FILESYSTEM
if (device->isTypeOf<PIFile>()) base_path = PIFile::FileInfo(device->path()).dir().replaceAll('\\', '/'); if (device->isTypeOf<PIFile>()) base_path = PIFile::FileInfo(device->path()).dir().replaceAll('\\', '/');
#endif
PIIOTextStream ts(device); PIIOTextStream ts(device);
PIString line, comm; PIString line, comm;
PIVariant value; PIVariant value;
@@ -211,10 +217,12 @@ PIValueTree PIValueTreeConversions::fromText(PIIODevice * device) {
line.cutLeft(1).trim(); line.cutLeft(1).trim();
if (path.front() == "include") { if (path.front() == "include") {
PIString include = line.trimmed(); PIString include = line.trimmed();
#ifndef PIP_NO_FILESYSTEM
if (!PIFile::FileInfo(include).isAbsolute()) { if (!PIFile::FileInfo(include).isAbsolute()) {
include = base_path + "/" + include.replaceAll('\\', '/'); include = base_path + "/" + include.replaceAll('\\', '/');
include.replaceAll("//", '/'); include.replaceAll("//", '/');
} }
#endif
PIValueTree inc_vt = PIValueTreeConversions::fromTextFile(include); PIValueTree inc_vt = PIValueTreeConversions::fromTextFile(include);
inc_vt.forEachRecursive( inc_vt.forEachRecursive(
[&substitutions](const PIValueTree & v, const PIString & fn) { substitutions[fn] = v.value().toString(); }); [&substitutions](const PIValueTree & v, const PIString & fn) { substitutions[fn] = v.value().toString(); });
@@ -345,6 +353,9 @@ PIValueTree PIValueTreeConversions::fromText(const PIString & str) {
PIValueTree PIValueTreeConversions::fromJSONFile(const PIString & path) { PIValueTree PIValueTreeConversions::fromJSONFile(const PIString & path) {
#ifdef PIP_NO_FILESYSTEM
return PIValueTree();
#else
auto ret = PIValueTreeConversions::fromJSON(PIJSON::fromJSON(PIString::fromUTF8(PIFile::readAll(path)))); auto ret = PIValueTreeConversions::fromJSON(PIJSON::fromJSON(PIString::fromUTF8(PIFile::readAll(path))));
auto ofp = overrideFile(path); auto ofp = overrideFile(path);
if (PIFile::isExists(ofp)) { if (PIFile::isExists(ofp)) {
@@ -352,10 +363,14 @@ PIValueTree PIValueTreeConversions::fromJSONFile(const PIString & path) {
ret.merge(override_vt); ret.merge(override_vt);
} }
return ret; return ret;
#endif
} }
PIValueTree PIValueTreeConversions::fromTextFile(const PIString & path) { PIValueTree PIValueTreeConversions::fromTextFile(const PIString & path) {
#ifdef PIP_NO_FILESYSTEM
return PIValueTree();
#else
PIFile f(path, PIIODevice::ReadOnly); PIFile f(path, PIIODevice::ReadOnly);
auto ret = PIValueTreeConversions::fromText(&f); auto ret = PIValueTreeConversions::fromText(&f);
auto ofp = overrideFile(path); auto ofp = overrideFile(path);
@@ -365,18 +380,27 @@ PIValueTree PIValueTreeConversions::fromTextFile(const PIString & path) {
ret.merge(override_vt); ret.merge(override_vt);
} }
return ret; return ret;
#endif
} }
bool PIValueTreeConversions::toJSONFile(const PIString & path, const PIValueTree & root, Options options) { bool PIValueTreeConversions::toJSONFile(const PIString & path, const PIValueTree & root, Options options) {
#ifdef PIP_NO_FILESYSTEM
return false;
#else
auto d = toJSON(root, options).toJSON(PIJSON::Tree).toUTF8(); auto d = toJSON(root, options).toJSON(PIJSON::Tree).toUTF8();
int written = PIFile::writeAll(path, d); int written = PIFile::writeAll(path, d);
return written == d.size_s(); return written == d.size_s();
#endif
} }
bool PIValueTreeConversions::toTextFile(const PIString & path, const PIValueTree & root, Options options) { bool PIValueTreeConversions::toTextFile(const PIString & path, const PIValueTree & root, Options options) {
#ifdef PIP_NO_FILESYSTEM
return false;
#else
auto d = toText(root, options).toUTF8(); auto d = toText(root, options).toUTF8();
int written = PIFile::writeAll(path, d); int written = PIFile::writeAll(path, d);
return written == d.size_s(); return written == d.size_s();
#endif
} }
@@ -1,20 +1,20 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
State machine State machine
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "pistatemachine_transition.h" #include "pistatemachine_transition.h"
@@ -99,24 +99,32 @@ void PITransitionBase::trigger() {
PITransitionTimeout::PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout) PITransitionTimeout::PITransitionTimeout(PIStateBase * source, PIStateBase * target, PISystemTime timeout)
: PITransitionBase(source, target, 0) { : PITransitionBase(source, target, 0) {
#ifndef PIP_NO_THREADS
timer.setInterval(timeout); timer.setInterval(timeout);
timer.setSlot([this] { timer.setSlot([this] {
trigger(); trigger();
timer.stop(); timer.stop();
}); });
#endif
} }
PITransitionTimeout::~PITransitionTimeout() { PITransitionTimeout::~PITransitionTimeout() {
#ifndef PIP_NO_THREADS
timer.stopAndWait(); timer.stopAndWait();
#endif
} }
void PITransitionTimeout::enabled() { void PITransitionTimeout::enabled() {
#ifndef PIP_NO_THREADS
timer.start(); timer.start();
#endif
} }
void PITransitionTimeout::disabled() { void PITransitionTimeout::disabled() {
#ifndef PIP_NO_THREADS
timer.stop(); timer.stop();
#endif
} }
@@ -5,8 +5,8 @@
//! \~russian Объявляет переходы, используемые в PIStateMachine //! \~russian Объявляет переходы, используемые в PIStateMachine
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
State machine transition State machine transition
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -142,7 +142,9 @@ private:
void enabled() override; void enabled() override;
void disabled() override; void disabled() override;
#ifndef PIP_NO_THREADS
PITimer timer; PITimer timer;
#endif
}; };
#endif #endif
+74 -70
View File
@@ -2,27 +2,29 @@
#include "piliterals_string.h" #include "piliterals_string.h"
#include "piliterals_time.h" #include "piliterals_time.h"
#ifndef WINDOWS
# include "pidir.h"
# include "pifile.h"
# include "piiostream.h"
# ifdef LINUX #ifndef PIP_NO_THREADS
# include <fcntl.h> # ifndef WINDOWS
# include <linux/input-event-codes.h> # include "pidir.h"
# include <linux/input.h> # include "pifile.h"
# include <sys/ioctl.h> # include "piiostream.h"
# include <sys/time.h>
# include <unistd.h> # ifdef LINUX
# else # include <fcntl.h>
# include <linux/input-event-codes.h>
# include <linux/input.h>
# include <sys/ioctl.h>
# include <sys/time.h>
# include <unistd.h>
# else
// Stubs for embedded/non-Linux builds // Stubs for embedded/non-Linux builds
# define EV_SYN 0 # define EV_SYN 0
# define EV_KEY 1 # define EV_KEY 1
# define EV_REL 2 # define EV_REL 2
# define EV_ABS 3 # define EV_ABS 3
# define EVIOCGABS(_v) 0 # define EVIOCGABS(_v) 0
# endif # endif
#else # else
// clang-format off // clang-format off
# undef _WIN32_WINNT # undef _WIN32_WINNT
# define _WIN32_WINNT 0x0600 # define _WIN32_WINNT 0x0600
@@ -32,7 +34,7 @@ extern "C" {
# include <hidsdi.h> # include <hidsdi.h>
} }
// clang-format on // clang-format on
#endif # endif
bool PIHIDeviceInfo::match(const PIString & str) const { bool PIHIDeviceInfo::match(const PIString & str) const {
@@ -79,14 +81,14 @@ PICout operator<<(PICout s, const PIHIDeviceInfo & v) {
PRIVATE_DEFINITION_START(PIHIDevice) PRIVATE_DEFINITION_START(PIHIDevice)
#ifndef WINDOWS # ifndef WINDOWS
PIFile file; PIFile file;
bool is_js = false; bool is_js = false;
#else # else
PIByteArray buffer; PIByteArray buffer;
HANDLE deviceHandle = nullptr; HANDLE deviceHandle = nullptr;
PHIDP_PREPARSED_DATA preparsed = nullptr; PHIDP_PREPARSED_DATA preparsed = nullptr;
#endif # endif
PRIVATE_DEFINITION_END(PIHIDevice) PRIVATE_DEFINITION_END(PIHIDevice)
@@ -95,11 +97,11 @@ PIHIDevice::~PIHIDevice() {
} }
bool PIHIDevice::isOpened() const { bool PIHIDevice::isOpened() const {
#ifndef WINDOWS # ifndef WINDOWS
return PRIVATE->file.isOpened(); return PRIVATE->file.isOpened();
#else # else
return PRIVATE->deviceHandle; return PRIVATE->deviceHandle;
#endif # endif
} }
@@ -110,21 +112,21 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) {
di = device; di = device;
di.prepare(); di.prepare();
if (device.isNull()) return false; if (device.isNull()) return false;
#ifndef WINDOWS # ifndef WINDOWS
if (!PRIVATE->file.open(di.path, PIIODevice::ReadOnly)) { if (!PRIVATE->file.open(di.path, PIIODevice::ReadOnly)) {
piCout << "PIHIDevice::open" << di.path << "error:" << errorString(); piCout << "PIHIDevice::open" << di.path << "error:" << errorString();
return false; return false;
} }
PRIVATE->is_js = PIFile::FileInfo(di.path).name().startsWith("js"_a); PRIVATE->is_js = PIFile::FileInfo(di.path).name().startsWith("js"_a);
return true; return true;
#else # else
PRIVATE->deviceHandle = CreateFileA(di.path.dataAscii(), PRIVATE->deviceHandle = CreateFileA(di.path.dataAscii(),
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, nullptr,
OPEN_EXISTING, OPEN_EXISTING,
0, 0,
nullptr); nullptr);
if (PRIVATE->deviceHandle == INVALID_HANDLE_VALUE) { if (PRIVATE->deviceHandle == INVALID_HANDLE_VALUE) {
piCoutObj << "PIHIDevice::open" << di.path << "error:" << errorString(); piCoutObj << "PIHIDevice::open" << di.path << "error:" << errorString();
PRIVATE->deviceHandle = nullptr; PRIVATE->deviceHandle = nullptr;
@@ -136,7 +138,7 @@ bool PIHIDevice::open(const PIHIDeviceInfo & device) {
return false; return false;
} }
return true; return true;
#endif # endif
} }
@@ -147,9 +149,9 @@ bool PIHIDevice::open() {
void PIHIDevice::close() { void PIHIDevice::close() {
stop(); stop();
#ifndef WINDOWS # ifndef WINDOWS
PRIVATE->file.close(); PRIVATE->file.close();
#else # else
if (PRIVATE->deviceHandle) { if (PRIVATE->deviceHandle) {
CloseHandle(PRIVATE->deviceHandle); CloseHandle(PRIVATE->deviceHandle);
PRIVATE->deviceHandle = nullptr; PRIVATE->deviceHandle = nullptr;
@@ -158,34 +160,34 @@ void PIHIDevice::close() {
HidD_FreePreparsedData(PRIVATE->preparsed); HidD_FreePreparsedData(PRIVATE->preparsed);
PRIVATE->preparsed = nullptr; PRIVATE->preparsed = nullptr;
} }
#endif # endif
} }
void PIHIDevice::start() { void PIHIDevice::start() {
if (!isOpened()) return; if (!isOpened()) return;
PIThread::start(200_Hz); PIThread::start(200_Hz);
#ifndef WINDOWS # ifndef WINDOWS
#else # else
#endif # endif
} }
void PIHIDevice::stop() { void PIHIDevice::stop() {
PIThread::stop(); PIThread::stop();
#ifdef WINDOWS # ifdef WINDOWS
if (PRIVATE->deviceHandle) { if (PRIVATE->deviceHandle) {
CancelIoEx(PRIVATE->deviceHandle, nullptr); CancelIoEx(PRIVATE->deviceHandle, nullptr);
} }
#endif # endif
if (!waitForFinish(1000_ms)) terminate(); if (!waitForFinish(1000_ms)) terminate();
} }
void PIHIDevice::run() { void PIHIDevice::run() {
Event e; Event e;
#ifndef WINDOWS # ifndef WINDOWS
# pragma pack(push, 1) # pragma pack(push, 1)
struct input_event { struct input_event {
struct timeval time; struct timeval time;
ushort type; ushort type;
@@ -198,7 +200,7 @@ void PIHIDevice::run() {
uchar type; /* event type */ uchar type; /* event type */
uchar number; /* axis/button number */ uchar number; /* axis/button number */
}; };
# pragma pack(pop) # pragma pack(pop)
if (PRIVATE->is_js) { if (PRIVATE->is_js) {
js_event ie; js_event ie;
while (PRIVATE->file.read(&ie, sizeof(ie)) == sizeof(ie)) { while (PRIVATE->file.read(&ie, sizeof(ie)) == sizeof(ie)) {
@@ -253,7 +255,7 @@ void PIHIDevice::run() {
if (!ok) continue; if (!ok) continue;
} }
} }
#else # else
PRIVATE->buffer.resize(di.input_report_size).fill(0); PRIVATE->buffer.resize(di.input_report_size).fill(0);
DWORD readed = 0; DWORD readed = 0;
// piCout << "read" << PRIVATE->deviceHandle << PRIVATE->buffer.size(); // piCout << "read" << PRIVATE->deviceHandle << PRIVATE->buffer.size();
@@ -293,7 +295,7 @@ void PIHIDevice::run() {
continue; continue;
} }
} }
#endif # endif
auto ait = cur_axes.makeIterator(); auto ait = cur_axes.makeIterator();
e.type = Event::tAxisMove; e.type = Event::tAxisMove;
@@ -333,7 +335,7 @@ double PIHIDevice::procDeadZone(double in) {
PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) { PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
PIVector<PIHIDeviceInfo> ret; PIVector<PIHIDeviceInfo> ret;
#ifndef WINDOWS # ifndef WINDOWS
auto readFile = [](const PIString & path) { auto readFile = [](const PIString & path) {
auto ba = PIFile::readAll(path); auto ba = PIFile::readAll(path);
@@ -379,11 +381,11 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
} }
/*bool dev_found = false; /*bool dev_found = false;
for (const auto & d: devs) { for (const auto & d: devs) {
if (d.startsWith("js"_a)) { if (d.startsWith("js"_a)) {
dev.path = "/dev/input/"_a + d; dev.path = "/dev/input/"_a + d;
dev_found = true; dev_found = true;
break; break;
} }
} }
if (!dev_found) {*/ if (!dev_found) {*/
// search for event<N> dir // search for event<N> dir
@@ -408,7 +410,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
ullong bits = readFile(hd_i.path + file).toULLong(16); ullong bits = readFile(hd_i.path + file).toULLong(16);
// piCout<< PICoutManipulators::Bin << abs; // piCout<< PICoutManipulators::Bin << abs;
if (bits > 0) { if (bits > 0) {
#ifdef LINUX # ifdef LINUX
int fd = ::open(dev.path.dataAscii(), O_RDONLY); int fd = ::open(dev.path.dataAscii(), O_RDONLY);
if (fd < 0) { if (fd < 0) {
// piCout << "Warning: can`t open" << dev.path << errorString(); // piCout << "Warning: can`t open" << dev.path << errorString();
@@ -433,7 +435,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
} }
} }
if (fd >= 0) ::close(fd); if (fd >= 0) ::close(fd);
#else # else
// Stub implementation for non-Linux builds // Stub implementation for non-Linux builds
PIHIDeviceInfo::AxisInfo ai; PIHIDeviceInfo::AxisInfo ai;
ai.is_relative = is_relative; ai.is_relative = is_relative;
@@ -445,7 +447,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
ret << ai; ret << ai;
} }
} }
#endif # endif
} }
return ret; return ret;
}; };
@@ -496,7 +498,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
} }
} }
#else # else
GUID guid; GUID guid;
HidD_GetHidGuid(&guid); HidD_GetHidGuid(&guid);
@@ -518,23 +520,23 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
PIScopeExitCall exit_call([&deviceInterfaceDetailData]() { delete[] reinterpret_cast<BYTE *>(deviceInterfaceDetailData); }); PIScopeExitCall exit_call([&deviceInterfaceDetailData]() { delete[] reinterpret_cast<BYTE *>(deviceInterfaceDetailData); });
deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); deviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet, if (!SetupDiGetDeviceInterfaceDetail(deviceInfoSet,
&deviceInterfaceData, &deviceInterfaceData,
deviceInterfaceDetailData, deviceInterfaceDetailData,
requiredSize, requiredSize,
nullptr, nullptr,
nullptr)) { nullptr)) {
piCout << "SetupDiGetDeviceInterfaceDetail error:" << errorString(); piCout << "SetupDiGetDeviceInterfaceDetail error:" << errorString();
continue; continue;
} }
if (try_open) { if (try_open) {
auto test_f = CreateFileA(deviceInterfaceDetailData->DevicePath, auto test_f = CreateFileA(deviceInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
nullptr, nullptr,
OPEN_EXISTING, OPEN_EXISTING,
0, 0,
nullptr); nullptr);
if (test_f == INVALID_HANDLE_VALUE) continue; if (test_f == INVALID_HANDLE_VALUE) continue;
CloseHandle(test_f); CloseHandle(test_f);
} }
@@ -657,7 +659,7 @@ PIVector<PIHIDeviceInfo> PIHIDevice::allDevices(bool try_open) {
SetupDiDestroyDeviceInfoList(deviceInfoSet); SetupDiDestroyDeviceInfoList(deviceInfoSet);
#endif # endif
return ret; return ret;
} }
@@ -671,3 +673,5 @@ PIHIDeviceInfo PIHIDevice::findDevice(const PIString & name) {
} }
return PIHIDeviceInfo(); return PIHIDeviceInfo();
} }
#endif // PIP_NO_THREADS
+3 -1
View File
@@ -169,6 +169,7 @@ PIP_EXPORT PICout operator<<(PICout s, const PIHIDeviceInfo & v);
//! \~english Provides access to HID (Human Interface Device) devices such as game controllers, joysticks, and other input devices. //! \~english Provides access to HID (Human Interface Device) devices such as game controllers, joysticks, and other input devices.
//! \~russian Предоставляет доступ к HID (Human Interface Device) устройствам, таким как геймконтроллеры, джойстики и другие устройства //! \~russian Предоставляет доступ к HID (Human Interface Device) устройствам, таким как геймконтроллеры, джойстики и другие устройства
//! ввода. //! ввода.
#ifndef PIP_NO_THREADS
class PIP_EXPORT PIHIDevice: public PIThread { class PIP_EXPORT PIHIDevice: public PIThread {
PIOBJECT_SUBCLASS(PIHIDevice, PIThread) PIOBJECT_SUBCLASS(PIHIDevice, PIThread)
@@ -188,7 +189,7 @@ public:
tNone /** \~english Empty event \~russian Пустое событие */, tNone /** \~english Empty event \~russian Пустое событие */,
tButton /** \~english Button state change \~russian Изменение состояния кнопки */, tButton /** \~english Button state change \~russian Изменение состояния кнопки */,
tAxisMove /** \~english Axis value change or relative axis delta \~russian Изменение значения оси или дельта относительной оси tAxisMove /** \~english Axis value change or relative axis delta \~russian Изменение значения оси или дельта относительной оси
*/ */
, ,
}; };
@@ -270,6 +271,7 @@ private:
PIMap<int, int> prev_buttons, cur_buttons; PIMap<int, int> prev_buttons, cur_buttons;
float dead_zone = 0.f; float dead_zone = 0.f;
}; };
#endif // PIP_NO_THREADS
#endif #endif
+2 -2
View File
@@ -17,7 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MICRO_PIP #ifndef PIP_NO_DYNLIB
# include "pilibrary.h" # include "pilibrary.h"
@@ -233,4 +233,4 @@ void PILibrary::getLastError() {
# endif # endif
} }
#endif // MICRO_PIP #endif // PIP_NO_DYNLIB
+2 -2
View File
@@ -26,7 +26,7 @@
#ifndef PILIBRARY_H #ifndef PILIBRARY_H
#define PILIBRARY_H #define PILIBRARY_H
#ifndef MICRO_PIP #ifndef PIP_NO_DYNLIB
# include "pistring.h" # include "pistring.h"
@@ -82,5 +82,5 @@ private:
PIString libpath, liberror; PIString libpath, liberror;
}; };
#endif // MICRO_PIP #endif // PIP_NO_DYNLIB
#endif // PILIBRARY_H #endif // PILIBRARY_H
+2 -2
View File
@@ -17,7 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef MICRO_PIP #ifndef PIP_NO_DYNLIB
# include "piplugin.h" # include "piplugin.h"
@@ -493,4 +493,4 @@ PIString PIPluginLoader::libExtension() {
} }
#endif // MICRO_PIP #endif // PIP_NO_DYNLIB
+21 -23
View File
@@ -28,7 +28,7 @@
#ifndef PIPLUGIN_H #ifndef PIPLUGIN_H
#define PIPLUGIN_H #define PIPLUGIN_H
#ifndef MICRO_PIP #ifndef PIP_NO_DYNLIB
# include "pilibrary.h" # include "pilibrary.h"
# include "pistringlist.h" # include "pistringlist.h"
@@ -96,30 +96,28 @@
# define __PIP_PLUGIN_STATIC_MERGE_FUNC__ pip_merge_static # define __PIP_PLUGIN_STATIC_MERGE_FUNC__ pip_merge_static
# define __PIP_PLUGIN_LOADER_VERSION__ 2 # define __PIP_PLUGIN_LOADER_VERSION__ 2
# define PIP_PLUGIN_SET_USER_VERSION(v) \ # define PIP_PLUGIN_SET_USER_VERSION(v) \
STATIC_INITIALIZER_BEGIN \ STATIC_INITIALIZER_BEGIN \
PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \ PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \
if (pi) pi->setUserVersion(v); \ if (pi) pi->setUserVersion(v); \
STATIC_INITIALIZER_END STATIC_INITIALIZER_END
# define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \ # define PIP_PLUGIN_ADD_STATIC_SECTION(type, ptr) \
STATIC_INITIALIZER_BEGIN \ STATIC_INITIALIZER_BEGIN \
PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \ PIPluginInfo * pi = PIPluginInfoStorage::instance()->currentInfo(); \
if (pi) pi->setStaticSection(type, ptr); \ if (pi) pi->setStaticSection(type, ptr); \
STATIC_INITIALIZER_END STATIC_INITIALIZER_END
# define PIP_PLUGIN \ # define PIP_PLUGIN \
extern "C" { \ extern "C" { \
PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() { \ PIP_PLUGIN_EXPORT int __PIP_PLUGIN_LOADER_VERSION_FUNC__() { return __PIP_PLUGIN_LOADER_VERSION__; } \
return __PIP_PLUGIN_LOADER_VERSION__; \ }
} \
}
# define PIP_PLUGIN_STATIC_SECTION_MERGE \ # define PIP_PLUGIN_STATIC_SECTION_MERGE \
extern "C" { \ extern "C" { \
PIP_PLUGIN_EXPORT void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to); \ PIP_PLUGIN_EXPORT void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to); \
} \ } \
void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to) void __PIP_PLUGIN_STATIC_MERGE_FUNC__(int type, void * from, void * to)
# endif # endif
@@ -300,5 +298,5 @@ private:
}; };
#endif // MICRO_PIP #endif // PIP_NO_DYNLIB
#endif // PIPLUGIN_H #endif // PIPLUGIN_H
+2 -2
View File
@@ -18,7 +18,7 @@
*/ */
#include "pitime.h" #include "pitime.h"
#ifndef MICRO_PIP #ifndef PIP_NO_PROCESS
# include "piincludes_p.h" # include "piincludes_p.h"
# include "piliterals_bytes.h" # include "piliterals_bytes.h"
@@ -507,4 +507,4 @@ PIString PIProcess::getEnvironmentVariable(const PIString & variable) {
return PIString(); return PIString();
} }
#endif // MICRO_PIP #endif // PIP_NO_PROCESS
+2 -2
View File
@@ -26,7 +26,7 @@
#ifndef PIPROCESS_H #ifndef PIPROCESS_H
#define PIPROCESS_H #define PIPROCESS_H
#ifndef MICRO_PIP #ifndef PIP_NO_PROCESS
# include "pithread.h" # include "pithread.h"
@@ -258,5 +258,5 @@ private:
std::atomic_bool exec_finished; std::atomic_bool exec_finished;
}; };
#endif // MICRO_PIP #endif // PIP_NO_PROCESS
#endif // PIPROCESS_H #endif // PIPROCESS_H
+10
View File
@@ -207,11 +207,19 @@ PIVector<PISystemInfo::MountInfo> PISystemInfo::mountInfo(bool ignore_cache) {
PIString confDir() { PIString confDir() {
return return
#ifdef WINDOWS #ifdef WINDOWS
# ifndef PIP_NO_FILESYSTEM
PIDir::home().path() + "/AppData/Local" PIDir::home().path() + "/AppData/Local"
# else
""
# endif
#elif defined(ANDROID) #elif defined(ANDROID)
"" ""
#else #else
# ifndef PIP_NO_FILESYSTEM
PIDir::home().path() + "/.config" PIDir::home().path() + "/.config"
# else
""
# endif
#endif #endif
; ;
} }
@@ -234,11 +242,13 @@ PIString PISystemInfo::machineKey() {
PISystemInfo * si = instance(); PISystemInfo * si = instance();
PIByteArray salt; PIByteArray salt;
PIString conf = confDir() + "/.pip_machine_salt"; PIString conf = confDir() + "/.pip_machine_salt";
#ifndef PIP_NO_FILESYSTEM
if (PIFile::isExists(conf)) salt = PIFile::readAll(conf); if (PIFile::isExists(conf)) salt = PIFile::readAll(conf);
if (salt.size_s() != SALT_SIZE) { if (salt.size_s() != SALT_SIZE) {
salt = generateSalt(); salt = generateSalt();
PIFile::writeAll(conf, salt); PIFile::writeAll(conf, salt);
} }
#endif
ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex(); ret = si->OS_name + "_" + si->architecture + "_" + si->hostname + "_" + salt.toHex();
} }
return ret; return ret;
+4 -4
View File
@@ -19,9 +19,9 @@
#include "pisystemtests.h" #include "pisystemtests.h"
#ifndef MICRO_PIP #ifndef PIP_NO_FILESYSTEM
# include "piconfig.h" # include "piconfig.h"
#endif #endif // !PIP_NO_FILESYSTEM
namespace PISystemTests { namespace PISystemTests {
@@ -35,10 +35,10 @@ PISystemTestReader pisystestreader;
PISystemTests::PISystemTestReader::PISystemTestReader() { PISystemTests::PISystemTestReader::PISystemTestReader() {
#if !defined(WINDOWS) && !defined(MICRO_PIP) #if !defined(WINDOWS) && !defined(PIP_NO_FILESYSTEM)
PIConfig conf(PIStringAscii("/etc/pip.conf"), PIIODevice::ReadOnly); PIConfig conf(PIStringAscii("/etc/pip.conf"), PIIODevice::ReadOnly);
time_resolution_ns = conf.getValue(PIStringAscii("time_resolution_ns"), 1).toLong(); time_resolution_ns = conf.getValue(PIStringAscii("time_resolution_ns"), 1).toLong();
time_elapsed_ns = conf.getValue(PIStringAscii("time_elapsed_ns"), 0).toLong(); time_elapsed_ns = conf.getValue(PIStringAscii("time_elapsed_ns"), 0).toLong();
usleep_offset_us = conf.getValue(PIStringAscii("usleep_offset_us"), 60).toLong(); usleep_offset_us = conf.getValue(PIStringAscii("usleep_offset_us"), 60).toLong();
#endif #endif // !WINDOWS && !PIP_NO_FILESYSTEM
} }
+29 -14
View File
@@ -4,22 +4,22 @@
//! \~english Condition variable for waiting and notification between threads //! \~english Condition variable for waiting and notification between threads
//! \~russian Переменная условия для ожидания и уведомления между потоками //! \~russian Переменная условия для ожидания и уведомления между потоками
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Condition variable for waiting and notification between threads Condition variable for waiting and notification between threads
Stephan Fomenko Stephan Fomenko
This program is free software: you can redistribute it and/or modify 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 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 the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details. GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License 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/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef PICONDITIONVAR_H #ifndef PICONDITIONVAR_H
@@ -108,7 +108,7 @@ public:
//! \param condition вызываемый объект или функция, не принимающая аргументов и возвращающая значение, которое может быть оценено как //! \param condition вызываемый объект или функция, не принимающая аргументов и возвращающая значение, которое может быть оценено как
//! bool. Вызывается повторно, пока не примет значение true //! bool. Вызывается повторно, пока не примет значение true
//! //!
virtual void wait(PIMutex & lk, std::function<bool ()> condition); virtual void wait(PIMutex & lk, std::function<bool()> condition);
//! \~english Waits for at most \a timeout and returns \c true if awakened before it expires. //! \~english Waits for at most \a timeout and returns \c true if awakened before it expires.
@@ -176,4 +176,19 @@ private:
}; };
#endif // PIP_NO_THREADS #endif // PIP_NO_THREADS
#ifdef PIP_NO_THREADS
class PIConditionVariable {
public:
void wait(PIMutex &) {}
void wait(PIMutex &, std::function<bool()>) {}
bool waitFor(PIMutex &, PISystemTime) { return false; }
bool waitFor(PIMutex &, PISystemTime, std::function<bool()>) { return false; }
bool wait(PIMutex &, PISystemTime) { return true; }
bool wait(PIMutex &, ullong) { return true; }
void notifyOne() {}
void notifyAll() {}
};
#endif // PIP_NO_THREADS
#endif // PICONDITIONVAR_H #endif // PICONDITIONVAR_H
+24
View File
@@ -95,4 +95,28 @@ private:
}; };
#endif // PIP_NO_THREADS #endif // PIP_NO_THREADS
#ifdef PIP_NO_THREADS
//! \~\ingroup Thread
//! \~\brief
//! \~english Dummy mutex for builds without threading support.
//! \~russian Заглушка мьютекса для сборки без поддержки потоков.
class PIMutex {
public:
void lock() {}
void unlock() {}
bool tryLock() { return true; }
void * handle() { return nullptr; }
};
//! \~\ingroup Thread
//! \~\brief
//! \~english Dummy mutex locker for builds without threading support.
//! \~russian Заглушка блокировщика для сборки без поддержки потоков.
class PIMutexLocker {
public:
PIMutexLocker(PIMutex &, bool = true) {}
};
#endif // PIP_NO_THREADS
#endif // PIMUTEX_H #endif // PIMUTEX_H
+6 -2
View File
@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
PIReadWriteLock, PIReadLocker, PIWriteLocker PIReadWriteLock, PIReadLocker, PIWriteLocker
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -151,6 +151,8 @@
#include "pireadwritelock.h" #include "pireadwritelock.h"
#ifndef PIP_NO_THREADS
PIReadWriteLock::PIReadWriteLock() {} PIReadWriteLock::PIReadWriteLock() {}
@@ -232,3 +234,5 @@ void PIReadWriteLock::unlockRead() {
--reading; --reading;
var.notifyAll(); var.notifyAll();
} }
#endif // PIP_NO_THREADS
+4
View File
@@ -98,6 +98,8 @@
#include "pisemaphore.h" #include "pisemaphore.h"
#ifndef PIP_NO_THREADS
PISemaphore::PISemaphore(int initial) { PISemaphore::PISemaphore(int initial) {
count = initial; count = initial;
@@ -150,3 +152,5 @@ int PISemaphore::available() const {
PIMutexLocker _ml(mutex); PIMutexLocker _ml(mutex);
return count; return count;
} }
#endif // PIP_NO_THREADS
+104 -111
View File
@@ -18,39 +18,37 @@
*/ */
#ifndef PIP_NO_THREADS #ifndef PIP_NO_THREADS
#include "pithread.h" # include "pithread.h"
#include "piincludes_p.h" # include "piincludes_p.h"
#include "piintrospection_threads.h" # include "piintrospection_threads.h"
#include "piliterals_time.h" # include "piliterals_time.h"
#include "pitime.h"
#include "pitranslator.h"
#ifndef MICRO_PIP
# include "pisystemtests.h" # include "pisystemtests.h"
#endif # include "pitime.h"
#ifdef WINDOWS # include "pitranslator.h"
# include <ioapiset.h> # ifdef WINDOWS
#endif # include <ioapiset.h>
#include <signal.h> # endif
#if defined(WINDOWS) # include <signal.h>
# define __THREAD_FUNC_RET__ uint __stdcall # if defined(WINDOWS)
#elif defined(FREERTOS) # define __THREAD_FUNC_RET__ uint __stdcall
# define __THREAD_FUNC_RET__ void # elif defined(FREERTOS)
#else # define __THREAD_FUNC_RET__ void
# define __THREAD_FUNC_RET__ void * # else
#endif # define __THREAD_FUNC_RET__ void *
#ifndef FREERTOS # endif
# define __THREAD_FUNC_END__ 0 # ifndef FREERTOS
#else # define __THREAD_FUNC_END__ 0
# define __THREAD_FUNC_END__ # else
#endif # define __THREAD_FUNC_END__
#if defined(LINUX) # endif
# include <sys/syscall.h> # if defined(LINUX)
# define gettid() syscall(SYS_gettid) # include <sys/syscall.h>
#endif # define gettid() syscall(SYS_gettid)
#if defined(MAC_OS) || defined(BLACKBERRY) # endif
# include <pthread.h> # if defined(MAC_OS) || defined(BLACKBERRY)
#endif # include <pthread.h>
# endif
__THREAD_FUNC_RET__ thread_function(void * t) { __THREAD_FUNC_RET__ thread_function(void * t) {
((PIThread *)t)->__thread_func__(); ((PIThread *)t)->__thread_func__();
return __THREAD_FUNC_END__; return __THREAD_FUNC_END__;
@@ -60,13 +58,8 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {
return __THREAD_FUNC_END__; return __THREAD_FUNC_END__;
} }
#ifndef MICRO_PIP
# define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t) # define REGISTER_THREAD(t) __PIThreadCollection::instance()->registerThread(t)
# define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t) # define UNREGISTER_THREAD(t) __PIThreadCollection::instance()->unregisterThread(t)
#else
# define REGISTER_THREAD(t)
# define UNREGISTER_THREAD(t)
#endif
//! \addtogroup Thread //! \addtogroup Thread
//! \{ //! \{
@@ -457,7 +450,7 @@ __THREAD_FUNC_RET__ thread_function_once(void * t) {
//! \return \c false если таймаут истёк //! \return \c false если таймаут истёк
#ifndef MICRO_PIP # ifndef PIP_NO_THREADS
__PIThreadCollection * __PIThreadCollection::instance() { __PIThreadCollection * __PIThreadCollection::instance() {
return __PIThreadCollection_Initializer__::__instance__; return __PIThreadCollection_Initializer__::__instance__;
@@ -523,18 +516,18 @@ __PIThreadCollection_Initializer__::~__PIThreadCollection_Initializer__() {
} }
} }
#endif // MICRO_PIP # endif // PIP_NO_THREADS
PRIVATE_DEFINITION_START(PIThread) PRIVATE_DEFINITION_START(PIThread)
#if defined(WINDOWS) # if defined(WINDOWS)
void * thread = nullptr; void * thread = nullptr;
#elif defined(FREERTOS) # elif defined(FREERTOS)
TaskHandle_t thread; TaskHandle_t thread;
#else # else
pthread_t thread = 0; pthread_t thread = 0;
sched_param sparam; sched_param sparam;
#endif # endif
PRIVATE_DEFINITION_END(PIThread) PRIVATE_DEFINITION_END(PIThread)
@@ -572,25 +565,25 @@ PIThread::~PIThread() {
PIINTROSPECTION_THREAD_DELETE(this); PIINTROSPECTION_THREAD_DELETE(this);
if (!running_ || PRIVATE->thread == 0) return; if (!running_ || PRIVATE->thread == 0) return;
piCout << "[PIThread \"%1\"] Warning, terminate on destructor!"_tr("PIThread").arg(name()); piCout << "[PIThread \"%1\"] Warning, terminate on destructor!"_tr("PIThread").arg(name());
#ifdef FREERTOS # ifdef FREERTOS
// void * ret(0); // void * ret(0);
// PICout(PICoutManipulators::DefaultControls) << "~PIThread" << PRIVATE->thread; // PICout(PICoutManipulators::DefaultControls) << "~PIThread" << PRIVATE->thread;
// PICout(PICoutManipulators::DefaultControls) << pthread_join(PRIVATE->thread, 0); // PICout(PICoutManipulators::DefaultControls) << pthread_join(PRIVATE->thread, 0);
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop"; PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stopAndWait(); stopAndWait();
// PICout(PICoutManipulators::DefaultControls) << "stopped!"; // PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else
# ifndef WINDOWS
# ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM);
# else
pthread_cancel(PRIVATE->thread);
# endif
# else # else
# ifndef WINDOWS
# ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM);
# else
pthread_cancel(PRIVATE->thread);
# endif
# else
TerminateThread(PRIVATE->thread, 0); TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread); CloseHandle(PRIVATE->thread);
# endif
# endif # endif
#endif
UNREGISTER_THREAD(this); UNREGISTER_THREAD(this);
PIINTROSPECTION_THREAD_STOP(this); PIINTROSPECTION_THREAD_STOP(this);
terminating = running_ = false; terminating = running_ = false;
@@ -668,32 +661,32 @@ void PIThread::stop() {
void PIThread::terminate() { void PIThread::terminate() {
piCoutObj << "Warning, terminate!"_tr("PIThread"); piCoutObj << "Warning, terminate!"_tr("PIThread");
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ..." << running_; // PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ..." << running_;
#ifdef FREERTOS # ifdef FREERTOS
PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop"; PICout(PICoutManipulators::DefaultControls) << "FreeRTOS can't terminate pthreads! waiting for stop";
stop(true); stop(true);
// PICout(PICoutManipulators::DefaultControls) << "stopped!"; // PICout(PICoutManipulators::DefaultControls) << "stopped!";
#else # else
if (PRIVATE->thread == 0) return; if (PRIVATE->thread == 0) return;
UNREGISTER_THREAD(this); UNREGISTER_THREAD(this);
terminating = running_ = false; terminating = running_ = false;
tid_ = -1; tid_ = -1;
// PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread; // PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
# ifndef WINDOWS # ifndef WINDOWS
# ifdef ANDROID # ifdef ANDROID
pthread_kill(PRIVATE->thread, SIGTERM); pthread_kill(PRIVATE->thread, SIGTERM);
# else # else
// pthread_kill(PRIVATE->thread, SIGKILL); // pthread_kill(PRIVATE->thread, SIGKILL);
// void * ret(0); // void * ret(0);
pthread_cancel(PRIVATE->thread); pthread_cancel(PRIVATE->thread);
// pthread_join(PRIVATE->thread, &ret); // pthread_join(PRIVATE->thread, &ret);
# endif # endif
# else # else
TerminateThread(PRIVATE->thread, 0); TerminateThread(PRIVATE->thread, 0);
CloseHandle(PRIVATE->thread); CloseHandle(PRIVATE->thread);
# endif # endif
PRIVATE->thread = 0; PRIVATE->thread = 0;
end(); end();
#endif // FREERTOS # endif // FREERTOS
PIINTROSPECTION_THREAD_STOP(this); PIINTROSPECTION_THREAD_STOP(this);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_; // PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
} }
@@ -701,31 +694,31 @@ void PIThread::terminate() {
int PIThread::priority2System(PIThread::Priority p) { int PIThread::priority2System(PIThread::Priority p) {
switch (p) { switch (p) {
#if defined(QNX) # if defined(QNX)
case piLowerst: return 8; case piLowerst: return 8;
case piLow: return 9; case piLow: return 9;
case piNormal: return 10; case piNormal: return 10;
case piHigh: return 11; case piHigh: return 11;
case piHighest: return 12; case piHighest: return 12;
#elif defined(WINDOWS) # elif defined(WINDOWS)
case piLowerst: return -2; case piLowerst: return -2;
case piLow: return -1; case piLow: return -1;
case piNormal: return 0; case piNormal: return 0;
case piHigh: return 1; case piHigh: return 1;
case piHighest: return 2; case piHighest: return 2;
#elif defined(FREERTOS) # elif defined(FREERTOS)
case piLowerst: return 2; case piLowerst: return 2;
case piLow: return 3; case piLow: return 3;
case piNormal: return 4; case piNormal: return 4;
case piHigh: return 5; case piHigh: return 5;
case piHighest: return 6; case piHighest: return 6;
#else # else
case piLowerst: return 2; case piLowerst: return 2;
case piLow: return 1; case piLow: return 1;
case piNormal: return 0; case piNormal: return 0;
case piHigh: return -1; case piHigh: return -1;
case piHighest: return -2; case piHighest: return -2;
#endif # endif
default: return 0; default: return 0;
} }
return 0; return 0;
@@ -736,7 +729,7 @@ bool PIThread::_startThread(void * func) {
terminating = false; terminating = false;
running_ = true; running_ = true;
#ifdef FREERTOS # ifdef FREERTOS
auto name_ba = createThreadName(); auto name_ba = createThreadName();
if (xTaskCreate((__THREAD_FUNC_RET__(*)(void *))func, if (xTaskCreate((__THREAD_FUNC_RET__(*)(void *))func,
@@ -749,20 +742,20 @@ bool PIThread::_startThread(void * func) {
return true; return true;
} }
#elif defined(WINDOWS) # elif defined(WINDOWS)
if (PRIVATE->thread) CloseHandle(PRIVATE->thread); if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC # ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void *))func, this, CREATE_SUSPENDED, 0); PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void *))func, this, CREATE_SUSPENDED, 0);
# else # else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, CREATE_SUSPENDED, 0); PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, CREATE_SUSPENDED, 0);
# endif # endif
if (PRIVATE->thread != 0) { if (PRIVATE->thread != 0) {
ResumeThread(PRIVATE->thread); ResumeThread(PRIVATE->thread);
return true; return true;
} }
#else # else
pthread_attr_t attr; pthread_attr_t attr;
pthread_attr_init(&attr); pthread_attr_init(&attr);
@@ -775,7 +768,7 @@ bool PIThread::_startThread(void * func) {
return true; return true;
} }
#endif # endif
running_ = false; running_ = false;
PRIVATE->thread = 0; PRIVATE->thread = 0;
@@ -787,30 +780,30 @@ bool PIThread::_startThread(void * func) {
void PIThread::setPriority(PIThread::Priority prior) { void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior; priority_ = prior;
if (!running_ || (PRIVATE->thread == 0)) return; if (!running_ || (PRIVATE->thread == 0)) return;
#ifdef FREERTOS # ifdef FREERTOS
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_)); vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
#else # else
# ifndef WINDOWS # ifndef WINDOWS
// PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread; // PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
int policy_ = 0; int policy_ = 0;
piZeroMemory(PRIVATE->sparam); piZeroMemory(PRIVATE->sparam);
pthread_getschedparam(PRIVATE->thread, &policy_, &(PRIVATE->sparam)); pthread_getschedparam(PRIVATE->thread, &policy_, &(PRIVATE->sparam));
PRIVATE->sparam. PRIVATE->sparam.
# ifndef LINUX # ifndef LINUX
sched_priority sched_priority
# else # else
__sched_priority __sched_priority
# endif # endif
= priority2System(priority_); = priority2System(priority_);
pthread_setschedparam(PRIVATE->thread, policy_, &(PRIVATE->sparam)); pthread_setschedparam(PRIVATE->thread, policy_, &(PRIVATE->sparam));
# else # else
SetThreadPriority(PRIVATE->thread, priority2System(priority_)); SetThreadPriority(PRIVATE->thread, priority2System(priority_));
# endif # endif
#endif // FREERTOS # endif // FREERTOS
} }
#ifdef WINDOWS # ifdef WINDOWS
bool isExists(HANDLE hThread) { bool isExists(HANDLE hThread) {
// errorClear(); // errorClear();
// piCout << "isExists" << hThread; // piCout << "isExists" << hThread;
@@ -821,7 +814,7 @@ bool isExists(HANDLE hThread) {
// piCout << errorString(); // piCout << errorString();
return false; return false;
} }
#endif # endif
bool PIThread::waitForFinish(PISystemTime timeout) { bool PIThread::waitForFinish(PISystemTime timeout) {
@@ -857,18 +850,18 @@ bool PIThread::waitForStart(PISystemTime timeout) {
void PIThread::_beginThread() { void PIThread::_beginThread() {
#ifndef WINDOWS # ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS) # if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0); pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0); pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
# endif
# endif # endif
#endif # ifdef WINDOWS
#ifdef WINDOWS
tid_ = GetCurrentThreadId(); tid_ = GetCurrentThreadId();
#endif # endif
#ifdef LINUX # ifdef LINUX
tid_ = gettid(); tid_ = gettid();
#endif # endif
setPriority(priority_); setPriority(priority_);
setThreadName(); setThreadName();
PIINTROSPECTION_THREAD_START(this); PIINTROSPECTION_THREAD_START(this);
@@ -887,13 +880,13 @@ void PIThread::_runThread() {
if (lockRun) thread_mutex.lock(); if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok"; // PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "..."; // PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
#ifdef PIP_INTROSPECTION # ifdef PIP_INTROSPECTION
PITimeMeasurer _tm; PITimeMeasurer _tm;
#endif # endif
run(); run();
#ifdef PIP_INTROSPECTION # ifdef PIP_INTROSPECTION
PIINTROSPECTION_THREAD_RUN_DONE(this, ullong(_tm.elapsed_u())); PIINTROSPECTION_THREAD_RUN_DONE(this, ullong(_tm.elapsed_u()));
#endif # endif
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok"; // PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok";
// printf("thread %p tick\n", this); // printf("thread %p tick\n", this);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "..."; // PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "...";
@@ -924,20 +917,20 @@ void PIThread::_endThread() {
// PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread; // PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this); UNREGISTER_THREAD(this);
PIINTROSPECTION_THREAD_STOP(this); PIINTROSPECTION_THREAD_STOP(this);
#if defined(WINDOWS) # if defined(WINDOWS)
ec.callAndCancel(); ec.callAndCancel();
# ifdef CC_GCC # ifdef CC_GCC
_endthreadex(0); _endthreadex(0);
# else # else
ExitThread(0); ExitThread(0);
# endif # endif
#elif defined(FREERTOS) # elif defined(FREERTOS)
PRIVATE->thread = 0; PRIVATE->thread = 0;
#else # else
PRIVATE->thread = 0; PRIVATE->thread = 0;
ec.callAndCancel(); ec.callAndCancel();
pthread_exit(0); pthread_exit(0);
#endif # endif
} }
@@ -1010,10 +1003,10 @@ void PIThread::runOnce(PIObject * object, const char * handler, const PIString &
delete t; delete t;
return; return;
} }
#ifndef MICRO_PIP # ifndef PIP_NO_THREADS
__PIThreadCollection::instance()->startedAuto(t); __PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto); CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
#endif # endif
t->startOnce(); t->startOnce();
} }
@@ -1044,10 +1037,10 @@ void PIThread::runOnce(std::function<void()> func, const PIString & name) {
PIThread * t = new PIThread(); PIThread * t = new PIThread();
t->setName(name); t->setName(name);
t->setSlot(std::move(func)); t->setSlot(std::move(func));
#ifndef MICRO_PIP # ifndef PIP_NO_THREADS
__PIThreadCollection::instance()->startedAuto(t); __PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto); CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
#endif # endif
t->startOnce(); t->startOnce();
} }
@@ -1063,15 +1056,15 @@ PIByteArray PIThread::createThreadName(int size) const {
void PIThread::setThreadName() { void PIThread::setThreadName() {
#ifndef WINDOWS # ifndef WINDOWS
auto name_ba = createThreadName(); auto name_ba = createThreadName();
# ifdef MAC_OS # ifdef MAC_OS
pthread_setname_np((const char *)name_ba.data()); pthread_setname_np((const char *)name_ba.data());
pthread_threadid_np(PRIVATE->thread, (__uint64_t *)&tid_); pthread_threadid_np(PRIVATE->thread, (__uint64_t *)&tid_);
# else # else
pthread_setname_np(PRIVATE->thread, (const char *)name_ba.data()); pthread_setname_np(PRIVATE->thread, (const char *)name_ba.data());
# endif
# endif # endif
#endif
} }
@@ -1079,12 +1072,12 @@ bool PIThread::_waitForFinish(PISystemTime max_tm) {
if (!running_) return true; if (!running_) return true;
state_notifier.waitFor(max_tm); state_notifier.waitFor(max_tm);
if (!running_) return true; if (!running_) return true;
#ifdef WINDOWS # ifdef WINDOWS
if (!isExists(PRIVATE->thread)) { if (!isExists(PRIVATE->thread)) {
unlock(); unlock();
return true; return true;
} }
#endif # endif
return false; return false;
} }
#endif // PIP_NO_THREADS #endif // PIP_NO_THREADS
+4 -4
View File
@@ -44,7 +44,7 @@
class PIThread; class PIThread;
#ifndef PIP_NO_THREADS #ifndef PIP_NO_THREADS
#ifndef MICRO_PIP # ifndef PIP_NO_THREADS
class PIIntrospectionThreads; class PIIntrospectionThreads;
class PIP_EXPORT __PIThreadCollection: public PIObject { class PIP_EXPORT __PIThreadCollection: public PIObject {
@@ -75,7 +75,7 @@ public:
}; };
static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__; static __PIThreadCollection_Initializer__ __PIThreadCollection_initializer__;
#endif // MICRO_PIP # endif // PIP_NO_THREADS
//! \~english Callback executed by %PIThread with the current \a data() pointer. //! \~english Callback executed by %PIThread with the current \a data() pointer.
//! \~russian Обратный вызов, который %PIThread выполняет с текущим указателем \a data(). //! \~russian Обратный вызов, который %PIThread выполняет с текущим указателем \a data().
@@ -99,9 +99,9 @@ typedef std::function<void(void *)> ThreadFunc;
//! проход без повторяющегося цикла обработки очереди. //! проход без повторяющегося цикла обработки очереди.
class PIP_EXPORT PIThread: public PIObject { class PIP_EXPORT PIThread: public PIObject {
PIOBJECT_SUBCLASS(PIThread, PIObject); PIOBJECT_SUBCLASS(PIThread, PIObject);
#ifndef MICRO_PIP # ifndef PIP_NO_THREADS
friend class PIIntrospectionThreads; friend class PIIntrospectionThreads;
#endif # endif
public: public:
NO_COPY_CLASS(PIThread); NO_COPY_CLASS(PIThread);
+4
View File
@@ -19,6 +19,8 @@
#include "pithreadnotifier.h" #include "pithreadnotifier.h"
#ifndef PIP_NO_THREADS
//! \addtogroup Thread //! \addtogroup Thread
//! \{ //! \{
//! \class PIThreadNotifier pithreadnotifier.h //! \class PIThreadNotifier pithreadnotifier.h
@@ -142,3 +144,5 @@ void PIThreadNotifier::notify() {
v.notifyAll(); v.notifyAll();
m.unlock(); m.unlock();
} }
#endif // PIP_NO_THREADS
+3 -1
View File
@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Class for simply notify and wait in different threads Class for simply notify and wait in different threads
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -27,6 +27,7 @@
#include "piconditionvar.h" #include "piconditionvar.h"
#ifndef PIP_NO_THREADS
//! \~\ingroup Thread //! \~\ingroup Thread
//! \~\brief //! \~\brief
@@ -63,5 +64,6 @@ private:
PIMutex m; PIMutex m;
PIConditionVariable v; PIConditionVariable v;
}; };
#endif // PIP_NO_THREADS
#endif // PITHREADNOTIFIER_H #endif // PITHREADNOTIFIER_H
+4
View File
@@ -23,6 +23,8 @@
#include "pisysteminfo.h" #include "pisysteminfo.h"
#include "pithread.h" #include "pithread.h"
#ifndef PIP_NO_THREADS
//! \addtogroup Thread //! \addtogroup Thread
//! \{ //! \{
@@ -166,3 +168,5 @@ void PIThreadPoolLoop::exec(int index_start, int index_count, std::function<void
setFunction(std::move(f)); setFunction(std::move(f));
exec(index_start, index_count); exec(index_start, index_count);
} }
#endif // PIP_NO_THREADS
+6 -2
View File
@@ -1,7 +1,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko, Stephan Fomenko Ivan Pelipenko, Stephan Fomenko
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +21,8 @@
#include "pisysteminfo.h" #include "pisysteminfo.h"
#ifndef PIP_NO_THREADS
//! \addtogroup Thread //! \addtogroup Thread
//! \{ //! \{
//! \class PIThreadPoolWorker pithreadpoolworker.h //! \class PIThreadPoolWorker pithreadpoolworker.h
@@ -177,7 +179,7 @@ int64_t PIThreadPoolWorker::enqueueTask(std::function<void(int64_t)> func, PIObj
contexts.remove(context); contexts.remove(context);
auto qref = tasks_queue.getRef(); auto qref = tasks_queue.getRef();
// auto prev_size = qref->size(); // auto prev_size = qref->size();
// piCout << "deleted" << (void *)context << qref->map<void *>([](const Task & t) { return t.context; }); // piCout << "deleted" << (void *)context << qref->map<void *>([](const Task & t) { return t.context; });
qref->removeWhere([context](const Task & t) { return t.context == context; }); qref->removeWhere([context](const Task & t) { return t.context == context; });
// piCout << prev_size << qref->size() << qref->map<void *>([](const Task & t) { return t.context; }); // piCout << prev_size << qref->size() << qref->map<void *>([](const Task & t) { return t.context; });
})); }));
@@ -236,3 +238,5 @@ void PIThreadPoolWorker::threadFunc(Worker * w) {
taskFinished(task.id); taskFinished(task.id);
w->notifier.notify(); w->notifier.notify();
} }
#endif // PIP_NO_THREADS
+5 -3
View File
@@ -6,7 +6,7 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Ivan Pelipenko, Stephan Fomenko Ivan Pelipenko, Stephan Fomenko
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU Lesser General Public License as published by
@@ -33,6 +33,7 @@
//! \~\brief //! \~\brief
//! \~english Fixed-size pool of worker threads for generic-purpose tasks. //! \~english Fixed-size pool of worker threads for generic-purpose tasks.
//! \~russian Фиксированный пул рабочих потоков для задач общего назначения. //! \~russian Фиксированный пул рабочих потоков для задач общего назначения.
#ifndef PIP_NO_THREADS
class PIP_EXPORT PIThreadPoolWorker: public PIObject { class PIP_EXPORT PIThreadPoolWorker: public PIObject {
PIOBJECT(PIThreadPoolWorker) PIOBJECT(PIThreadPoolWorker)
@@ -109,7 +110,7 @@ public:
template<typename O> template<typename O>
int64_t enqueueTask(O * obj, void (O::*member_func)(int64_t)) { int64_t enqueueTask(O * obj, void (O::*member_func)(int64_t)) {
return enqueueTask([obj, member_func](int64_t id) { (obj->*member_func)(id); }, return enqueueTask([obj, member_func](int64_t id) { (obj->*member_func)(id); },
PIObject::isPIObject(obj) ? dynamic_cast<PIObject *>(obj) : nullptr); PIObject::isPIObject(obj) ? dynamic_cast<PIObject *>(obj) : nullptr);
} }
//! \~english Queue class member method to execution. Returns task ID. //! \~english Queue class member method to execution. Returns task ID.
@@ -117,7 +118,7 @@ public:
template<typename O> template<typename O>
int64_t enqueueTask(O * obj, void (O::*member_func)()) { int64_t enqueueTask(O * obj, void (O::*member_func)()) {
return enqueueTask([obj, member_func](int64_t) { (obj->*member_func)(); }, return enqueueTask([obj, member_func](int64_t) { (obj->*member_func)(); },
PIObject::isPIObject(obj) ? dynamic_cast<PIObject *>(obj) : nullptr); PIObject::isPIObject(obj) ? dynamic_cast<PIObject *>(obj) : nullptr);
} }
//! \~english Remove task with id \a id from queue. Returns if task delete. //! \~english Remove task with id \a id from queue. Returns if task delete.
@@ -172,6 +173,7 @@ private:
PISet<PIObject *> contexts; PISet<PIObject *> contexts;
std::atomic_int64_t next_task_id = {0}; std::atomic_int64_t next_task_id = {0};
}; };
#endif // PIP_NO_THREADS
#endif // PITHREADPOOLWORKER_H #endif // PITHREADPOOLWORKER_H
+1 -1
View File
@@ -31,7 +31,7 @@
# include <mach/clock.h> # include <mach/clock.h>
// # include <crt_externs.h> // # include <crt_externs.h>
#endif #endif
#ifdef MICRO_PIP #ifdef PIP_EMBEDDED
# include <sys/time.h> # include <sys/time.h>
#endif #endif
+13 -1
View File
@@ -1,6 +1,6 @@
/* /*
PIP - Platform Independent Primitives PIP - Platform Independent Primitives
Network address Network address
Ivan Pelipenko peri4ko@yandex.ru Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -20,6 +20,7 @@
#include "pinetworkaddress.h" #include "pinetworkaddress.h"
// clang-format off // clang-format off
#ifndef PIP_NO_SOCKET
#ifdef QNX #ifdef QNX
# include <netdb.h> # include <netdb.h>
#else #else
@@ -33,6 +34,7 @@
# endif # endif
# endif # endif
#endif #endif
#endif // PIP_NO_SOCKET
// clang-format on // clang-format on
@@ -145,11 +147,17 @@ PINetworkAddress PINetworkAddress::resolve(const PIString & host_port) {
PINetworkAddress PINetworkAddress::resolve(const PIString & host, ushort port) { PINetworkAddress PINetworkAddress::resolve(const PIString & host, ushort port) {
#ifndef PIP_NO_SOCKET
PINetworkAddress ret(0, port); PINetworkAddress ret(0, port);
hostent * he = gethostbyname(host.dataAscii()); hostent * he = gethostbyname(host.dataAscii());
if (!he) return ret; if (!he) return ret;
if (he->h_addr_list[0]) ret.setIP(*((uint *)(he->h_addr_list[0]))); if (he->h_addr_list[0]) ret.setIP(*((uint *)(he->h_addr_list[0])));
return ret; return ret;
#else
(void)host;
(void)port;
return PINetworkAddress();
#endif
} }
@@ -162,5 +170,9 @@ void PINetworkAddress::splitIPPort(const PIString & ipp, PIString * _ip, int * _
void PINetworkAddress::initIP(const PIString & _ip) { void PINetworkAddress::initIP(const PIString & _ip) {
#ifndef PIP_NO_SOCKET
ip_ = inet_addr(_ip.dataAscii()); ip_ = inet_addr(_ip.dataAscii());
#else
(void)_ip;
#endif
} }
+7 -7
View File
@@ -29,7 +29,7 @@
#ifdef QNX #ifdef QNX
# include <time.h> # include <time.h>
#endif #endif
#ifndef MICRO_PIP #ifndef PIP_EMBEDDED
# include "pisystemtests.h" # include "pisystemtests.h"
#elif defined(ARDUINO) #elif defined(ARDUINO)
# include <Arduino.h> # include <Arduino.h>
@@ -49,7 +49,7 @@ long long __PIQueryPerformanceCounter() {
// # include <crt_externs.h> // # include <crt_externs.h>
extern clock_serv_t __pi_mac_clock; extern clock_serv_t __pi_mac_clock;
#endif #endif
#ifdef MICRO_PIP #ifdef PIP_EMBEDDED
# include <sys/time.h> # include <sys/time.h>
#endif #endif
@@ -246,7 +246,7 @@ PISystemTime PISystemTime::current(bool precise_but_not_system) {
#elif defined(MAC_OS) #elif defined(MAC_OS)
mach_timespec_t t_cur; mach_timespec_t t_cur;
clock_get_time(__pi_mac_clock, &t_cur); clock_get_time(__pi_mac_clock, &t_cur);
#elif defined(MICRO_PIP) #elif defined(PIP_EMBEDDED)
timespec t_cur; timespec t_cur;
# ifdef ARDUINO # ifdef ARDUINO
static const uint32_t offSetSinceEpoch_s = 1581897605UL; static const uint32_t offSetSinceEpoch_s = 1581897605UL;
@@ -278,7 +278,7 @@ PITimeMeasurer::PITimeMeasurer() {
double PITimeMeasurer::elapsed_n() const { double PITimeMeasurer::elapsed_n() const {
return (PISystemTime::current(true) - t_st).toNanoseconds() return (PISystemTime::current(true) - t_st).toNanoseconds()
#ifndef MICRO_PIP #ifndef PIP_EMBEDDED
- PISystemTests::time_elapsed_ns - PISystemTests::time_elapsed_ns
#endif #endif
; ;
@@ -287,7 +287,7 @@ double PITimeMeasurer::elapsed_n() const {
double PITimeMeasurer::elapsed_u() const { double PITimeMeasurer::elapsed_u() const {
return (PISystemTime::current(true) - t_st).toMicroseconds() return (PISystemTime::current(true) - t_st).toMicroseconds()
#ifndef MICRO_PIP #ifndef PIP_EMBEDDED
- PISystemTests::time_elapsed_ns / 1.E+3 - PISystemTests::time_elapsed_ns / 1.E+3
#endif #endif
; ;
@@ -296,7 +296,7 @@ double PITimeMeasurer::elapsed_u() const {
double PITimeMeasurer::elapsed_m() const { double PITimeMeasurer::elapsed_m() const {
return (PISystemTime::current(true) - t_st).toMilliseconds() return (PISystemTime::current(true) - t_st).toMilliseconds()
#ifndef MICRO_PIP #ifndef PIP_EMBEDDED
- PISystemTests::time_elapsed_ns / 1.E+6 - PISystemTests::time_elapsed_ns / 1.E+6
#endif #endif
; ;
@@ -305,7 +305,7 @@ double PITimeMeasurer::elapsed_m() const {
double PITimeMeasurer::elapsed_s() const { double PITimeMeasurer::elapsed_s() const {
return (PISystemTime::current(true) - t_st).toSeconds() return (PISystemTime::current(true) - t_st).toSeconds()
#ifndef MICRO_PIP #ifndef PIP_EMBEDDED
- PISystemTests::time_elapsed_ns / 1.E+9 - PISystemTests::time_elapsed_ns / 1.E+9
#endif #endif
; ;
+7 -5
View File
@@ -22,16 +22,16 @@
#ifdef QNX #ifdef QNX
# include <time.h> # include <time.h>
#endif #endif
#ifndef MICRO_PIP #ifndef PIP_EMBEDDED
# include "pisystemtests.h" # include "pisystemtests.h"
#elif defined(ARDUINO) #elif defined(ARDUINO)
# include <Arduino.h> # include <Arduino.h>
#elif defined(PICO_SDK) #else
# include "hardware/time.h"
#endif
#ifdef MICRO_PIP
# include <sys/time.h> # include <sys/time.h>
#endif #endif
#ifdef PICO_SDK
extern "C" void sleep_us(unsigned int);
#endif
//! \details //! \details
@@ -56,7 +56,9 @@ void piUSleep(int usecs) {
#elif defined(PICO_SDK) #elif defined(PICO_SDK)
sleep_us(usecs); sleep_us(usecs);
#else #else
# ifndef PIP_NO_THREADS
usecs -= PISystemTests::usleep_offset_us; usecs -= PISystemTests::usleep_offset_us;
# endif
if (usecs > 0) usleep(usecs); if (usecs > 0) usleep(usecs);
#endif #endif
} }
+28 -28
View File
@@ -28,9 +28,9 @@
#include "pistring.h" #include "pistring.h"
#include <typeinfo> #include <typeinfo>
#ifdef MICRO_PIP #if !defined(__GXX_RTTI__) && !defined(__RTTI__)
# include "pivariant.h" # include "pivariant.h"
#endif #endif // !defined(__GXX_RTTI__) && !defined(__RTTI__)
class __VariantFunctionsBase__ { class __VariantFunctionsBase__ {
@@ -52,21 +52,21 @@ public:
static __VariantFunctions__<T> ret; static __VariantFunctions__<T> ret;
return &ret; return &ret;
} }
#ifdef MICRO_PIP #if !defined(__GXX_RTTI__) && !defined(__RTTI__)
PIString typeName() const final { PIString typeName() const final {
static PIString ret(PIVariant::fromValue<T>(T()).typeName()); static PIString ret(PIVariant::fromValue<T>(T()).typeName());
return ret; return ret;
} }
#else #else
PIString typeName() const final { PIString typeName() const final {
#if defined(__GXX_RTTI__) || defined(__RTTI__) # if defined(__GXX_RTTI__) || defined(__RTTI__)
static PIString ret(typeid(T).name()); static PIString ret(typeid(T).name());
#else # else
static PIString ret("unknown"); static PIString ret("unknown");
#endif # endif
return ret; return ret;
} }
#endif #endif // !defined(__GXX_RTTI__) && !defined(__RTTI__)
uint hash() const final { uint hash() const final {
static uint ret = typeName().hash(); static uint ret = typeName().hash();
return ret; return ret;
@@ -182,27 +182,27 @@ private:
//! \~\brief //! \~\brief
//! \~english Registers a readable type name for %PIVariantSimple. //! \~english Registers a readable type name for %PIVariantSimple.
//! \~russian Регистрирует читаемое имя типа для %PIVariantSimple. //! \~russian Регистрирует читаемое имя типа для %PIVariantSimple.
#define REGISTER_PIVARIANTSIMPLE(Type) \ #define REGISTER_PIVARIANTSIMPLE(Type) \
template<> \ template<> \
class __VariantFunctions__<Type>: public __VariantFunctionsBase__ { \ class __VariantFunctions__<Type>: public __VariantFunctionsBase__ { \
public: \ public: \
__VariantFunctionsBase__ * instance() final { \ __VariantFunctionsBase__ * instance() final { \
static __VariantFunctions__<Type> ret; \ static __VariantFunctions__<Type> ret; \
return &ret; \ return &ret; \
} \ } \
PIString typeName() const final { \ PIString typeName() const final { \
static PIString ret(#Type); \ static PIString ret(#Type); \
return ret; \ return ret; \
} \ } \
uint hash() const final { \ uint hash() const final { \
static uint ret = typeName().hash(); \ static uint ret = typeName().hash(); \
return ret; \ return ret; \
} \ } \
void newT(void *& ptr, const void * value) final { ptr = (void *)(new Type(*(const Type *)value)); } \ void newT(void *& ptr, const void * value) final { ptr = (void *)(new Type(*(const Type *)value)); } \
void newNullT(void *& ptr) final { ptr = (void *)(new Type()); } \ void newNullT(void *& ptr) final { ptr = (void *)(new Type()); } \
void assignT(void *& ptr, const void * value) final { *(Type *)ptr = *(const Type *)value; } \ void assignT(void *& ptr, const void * value) final { *(Type *)ptr = *(const Type *)value; } \
void deleteT(void *& ptr) final { delete (Type *)(ptr); } \ void deleteT(void *& ptr) final { delete (Type *)(ptr); } \
}; };
REGISTER_PIVARIANTSIMPLE(std::function<void(void *)>) REGISTER_PIVARIANTSIMPLE(std::function<void(void *)>)
+7 -7
View File
@@ -21,9 +21,9 @@
#include "colors_p.h" #include "colors_p.h"
#include "pipropertystorage.h" #include "pipropertystorage.h"
#ifndef MICRO_PIP #ifndef PIP_NO_FILESYSTEM
# include "piiodevice.h" # include "piiodevice.h"
#endif #endif // PIP_NO_FILESYSTEM
int PIVariantTypes::Enum::selectedValue() const { int PIVariantTypes::Enum::selectedValue() const {
@@ -84,11 +84,11 @@ PIStringList PIVariantTypes::Enum::names() const {
PIVariantTypes::IODevice::IODevice() { PIVariantTypes::IODevice::IODevice() {
#ifndef MICRO_PIP #ifndef PIP_NO_FILESYSTEM
mode = PIIODevice::ReadWrite; mode = PIIODevice::ReadWrite;
#else #else
mode = 0; // TODO: PIIODevice for MICRO PIP mode = 0; // TODO: PIIODevice for PIP_NO_FILESYSTEM
#endif // MICRO_PIP #endif // PIP_NO_FILESYSTEM
options = 0; options = 0;
} }
@@ -121,12 +121,12 @@ PIString PIVariantTypes::IODevice::toPICout() const {
} }
if (rwc == 1) s += "o"; if (rwc == 1) s += "o";
s += ", flags="; s += ", flags=";
#ifndef MICRO_PIP // TODO: PIIODevice for MICRO PIP #ifndef PIP_NO_FILESYSTEM // TODO: PIIODevice for PIP_NO_FILESYSTEM
if (options != 0) { if (options != 0) {
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead]) s += " br"; if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingRead]) s += " br";
if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite]) s += " bw"; if (((PIIODevice::DeviceOptions)options)[PIIODevice::BlockingWrite]) s += " bw";
} }
#endif // MICRO_PIP #endif // PIP_NO_FILESYSTEM
PIPropertyStorage ps = get(); PIPropertyStorage ps = get();
for (const auto & p: ps) { for (const auto & p: ps) {
s += ", " + p.name + "=\"" + p.value.toString() + "\""; s += ", " + p.name + "=\"" + p.value.toString() + "\"";
+4
View File
@@ -27,6 +27,8 @@
#include "pitranslator.h" #include "pitranslator.h"
#include "stream.h" #include "stream.h"
#if !defined(PICO_SDK)
using namespace PICoutManipulators; using namespace PICoutManipulators;
@@ -278,3 +280,5 @@ int main(int argc, char * argv[]) {
} }
return 0; return 0;
} }
#endif // !PICO_SDK