mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 10:53:17 +00:00
Various fixes and improvements (#269)
- Bump version for next release - Fix default gamma for CYD 2432S032C - Remember gamma curve setting from Display settings app - Add UART to Core2 (still has no voltage on Grove port, though) - LVGL performance improvements: pin to second core and set task priority to "critical" - Fix build warnings, including deprecations - Removed deprecated `Thread` constructor - Fix WaveShare S3 display: Some displays would show a white screen at 12MHz, so I'm putting it back to the official config values.
This commit is contained in:
parent
eb4e9f9649
commit
08029a84dd
@ -3,12 +3,26 @@
|
|||||||
#include "hal/CydDisplay.h"
|
#include "hal/CydDisplay.h"
|
||||||
#include "hal/CydSdCard.h"
|
#include "hal/CydSdCard.h"
|
||||||
|
|
||||||
|
#include <Tactility/kernel/SystemEvents.h>
|
||||||
|
|
||||||
#include <PwmBacklight.h>
|
#include <PwmBacklight.h>
|
||||||
|
|
||||||
#define CYD_SPI_TRANSFER_SIZE_LIMIT (TWODOTFOUR_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
|
||||||
|
|
||||||
bool initBoot() {
|
bool initBoot() {
|
||||||
return driver::pwmbacklight::init(GPIO_NUM_27);
|
if (!driver::pwmbacklight::init(GPIO_NUM_27)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This display has a weird glitch with gamma during boot, which results in uneven dark gray colours.
|
||||||
|
// Setting gamma curve index to 0 doesn't work at boot for an unknown reason, so we set the curve index to 1:
|
||||||
|
tt::kernel::subscribeSystemEvent(tt::kernel::SystemEvent::BootInitLvglEnd, [](auto event) {
|
||||||
|
auto display = tt::hal::findFirstDevice<tt::hal::display::DisplayDevice>(tt::hal::Device::Type::Display);
|
||||||
|
assert(display != nullptr);
|
||||||
|
tt::lvgl::lock(portMAX_DELAY);
|
||||||
|
display->setGammaCurve(1U);
|
||||||
|
tt::lvgl::unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tt::hal::Configuration cyd_2432S032c_config = {
|
const tt::hal::Configuration cyd_2432S032c_config = {
|
||||||
|
|||||||
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#define CORE2_SPI_TRANSFER_SIZE_LIMIT (CORE2_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
#define CORE2_SPI_TRANSFER_SIZE_LIMIT (CORE2_LCD_DRAW_BUFFER_SIZE * LV_COLOR_DEPTH / 8)
|
||||||
|
|
||||||
|
using namespace tt::hal;
|
||||||
|
|
||||||
extern const tt::hal::Configuration m5stack_core2 = {
|
extern const tt::hal::Configuration m5stack_core2 = {
|
||||||
.initBoot = initBoot,
|
.initBoot = initBoot,
|
||||||
.createDisplay = createDisplay,
|
.createDisplay = createDisplay,
|
||||||
@ -74,5 +76,30 @@ extern const tt::hal::Configuration m5stack_core2 = {
|
|||||||
.isMutable = false,
|
.isMutable = false,
|
||||||
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
.lock = tt::lvgl::getSyncLock() // esp_lvgl_port owns the lock for the display
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
.uart {
|
||||||
|
uart::Configuration {
|
||||||
|
.name = "Grove",
|
||||||
|
.port = UART_NUM_1,
|
||||||
|
.rxPin = GPIO_NUM_32,
|
||||||
|
.txPin = GPIO_NUM_33,
|
||||||
|
.rtsPin = GPIO_NUM_NC,
|
||||||
|
.ctsPin = GPIO_NUM_NC,
|
||||||
|
.rxBufferSize = 1024,
|
||||||
|
.txBufferSize = 1024,
|
||||||
|
.config = {
|
||||||
|
.baud_rate = 115200,
|
||||||
|
.data_bits = UART_DATA_8_BITS,
|
||||||
|
.parity = UART_PARITY_DISABLE,
|
||||||
|
.stop_bits = UART_STOP_BITS_1,
|
||||||
|
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||||
|
.rx_flow_ctrl_thresh = 0,
|
||||||
|
.source_clk = UART_SCLK_DEFAULT,
|
||||||
|
.flags = {
|
||||||
|
.allow_pd = 0,
|
||||||
|
.backup_before_sleep = 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -137,7 +137,7 @@ static void updatePowerSwitch() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t powerSwitchMain(void*) { // check power switch every 10th of sec
|
static int32_t powerSwitchMain() { // check power switch every 10th of sec
|
||||||
while (true) {
|
while (true) {
|
||||||
updatePowerSwitch();
|
updatePowerSwitch();
|
||||||
tt::kernel::delayMillis(200);
|
tt::kernel::delayMillis(200);
|
||||||
@ -148,8 +148,7 @@ static void startPowerSwitchThread() {
|
|||||||
powerThread = std::make_unique<tt::Thread>(
|
powerThread = std::make_unique<tt::Thread>(
|
||||||
"unphone_power_switch",
|
"unphone_power_switch",
|
||||||
4096,
|
4096,
|
||||||
powerSwitchMain,
|
[]() { return powerSwitchMain(); }
|
||||||
nullptr
|
|
||||||
);
|
);
|
||||||
powerThread->start();
|
powerThread->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,15 +23,15 @@ std::shared_ptr<tt::hal::display::DisplayDevice> createDisplay() {
|
|||||||
esp_lcd_rgb_panel_config_t rgb_panel_config = {
|
esp_lcd_rgb_panel_config_t rgb_panel_config = {
|
||||||
.clk_src = LCD_CLK_SRC_DEFAULT,
|
.clk_src = LCD_CLK_SRC_DEFAULT,
|
||||||
.timings = {
|
.timings = {
|
||||||
.pclk_hz = 12'000'000, // NOTE: original was 14MHz, but we had to slow it down with PSRAM frame buffer,
|
.pclk_hz = 16'000'000,
|
||||||
.h_res = 800,
|
.h_res = 800,
|
||||||
.v_res = 480,
|
.v_res = 480,
|
||||||
.hsync_pulse_width = 10,
|
.hsync_pulse_width = 4,
|
||||||
.hsync_back_porch = 10,
|
.hsync_back_porch = 8,
|
||||||
.hsync_front_porch = 20,
|
.hsync_front_porch = 8,
|
||||||
.vsync_pulse_width = 10,
|
.vsync_pulse_width = 4,
|
||||||
.vsync_back_porch = 10,
|
.vsync_back_porch = 8,
|
||||||
.vsync_front_porch = 10,
|
.vsync_front_porch = 8,
|
||||||
.flags = {
|
.flags = {
|
||||||
.hsync_idle_low = false,
|
.hsync_idle_low = false,
|
||||||
.vsync_idle_low = false,
|
.vsync_idle_low = false,
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
# TODOs
|
# TODOs
|
||||||
|
|
||||||
|
- Add a Keyboard setting app to override the behaviour of soft keyboard hiding (e.g. keyboard hardware is present, but user wants soft keyboard)
|
||||||
|
- HAL for display touch calibration
|
||||||
|
- Display app: hide controls for unsupported features, instead of disabling them
|
||||||
- Split up boot stages, so the last stage can be done from the splash screen
|
- Split up boot stages, so the last stage can be done from the splash screen
|
||||||
- Start using non_null (either via MS GSL, or custom)
|
- Start using non_null (either via MS GSL, or custom)
|
||||||
- `hal/Configuration.h` defines C function types: Use C++ std::function instead
|
- `hal/Configuration.h` defines C function types: Use C++ std::function instead
|
||||||
@ -38,6 +42,7 @@
|
|||||||
- Remove flex_flow from app_container in Gui.cpp
|
- Remove flex_flow from app_container in Gui.cpp
|
||||||
|
|
||||||
# Nice-to-haves
|
# Nice-to-haves
|
||||||
|
|
||||||
- Give external app a different icon. Allow an external app update their id, icon, type and name once they are running(and persist that info?). Loader will need to be able to find app by (external) location.
|
- Give external app a different icon. Allow an external app update their id, icon, type and name once they are running(and persist that info?). Loader will need to be able to find app by (external) location.
|
||||||
- Audio player app
|
- Audio player app
|
||||||
- Audio recording app
|
- Audio recording app
|
||||||
@ -52,8 +57,9 @@
|
|||||||
- Files app: copy/paste actions
|
- Files app: copy/paste actions
|
||||||
- On crash, try to save current log to flash or SD card? (this is risky, though, so ask in Discord first)
|
- On crash, try to save current log to flash or SD card? (this is risky, though, so ask in Discord first)
|
||||||
- Support more than 1 hardware keyboard (see lvgl::hardware_keyboard_set_indev()). LVGL init currently calls keyboard init, but that part should probably be done from the KeyboardDevice base class.
|
- Support more than 1 hardware keyboard (see lvgl::hardware_keyboard_set_indev()). LVGL init currently calls keyboard init, but that part should probably be done from the KeyboardDevice base class.
|
||||||
|
|
||||||
# App Ideas
|
# App Ideas
|
||||||
|
|
||||||
- Map widget:
|
- Map widget:
|
||||||
https://github.com/portapack-mayhem/mayhem-firmware/blob/b66d8b1aa178d8a9cd06436fea788d5d58cb4c8d/firmware/application/ui/ui_geomap.cpp
|
https://github.com/portapack-mayhem/mayhem-firmware/blob/b66d8b1aa178d8a9cd06436fea788d5d58cb4c8d/firmware/application/ui/ui_geomap.cpp
|
||||||
https://github.com/portapack-mayhem/mayhem-firmware/blob/b66d8b1aa178d8a9cd06436fea788d5d58cb4c8d/firmware/tools/generate_world_map.bin.py
|
https://github.com/portapack-mayhem/mayhem-firmware/blob/b66d8b1aa178d8a9cd06436fea788d5d58cb4c8d/firmware/tools/generate_world_map.bin.py
|
||||||
|
|||||||
@ -12,15 +12,12 @@ static void touchReadCallback(lv_indev_t* indev, lv_indev_data_t* data) {
|
|||||||
touch->readLast(data);
|
touch->readLast(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t threadCallback(void* context) {
|
|
||||||
auto* touch = (Ft6x36Touch*)context;
|
|
||||||
touch->driverThreadMain();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ft6x36Touch::Ft6x36Touch(std::unique_ptr<Configuration> inConfiguration) :
|
Ft6x36Touch::Ft6x36Touch(std::unique_ptr<Configuration> inConfiguration) :
|
||||||
configuration(std::move(inConfiguration)),
|
configuration(std::move(inConfiguration)),
|
||||||
driverThread(tt::Thread("ft6x36", 4096, threadCallback, this))
|
driverThread(tt::Thread("ft6x36", 4096, [this]() {
|
||||||
|
driverThreadMain();
|
||||||
|
return 0;
|
||||||
|
}))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Ft6x36Touch::~Ft6x36Touch() {
|
Ft6x36Touch::~Ft6x36Touch() {
|
||||||
|
|||||||
@ -5,8 +5,15 @@
|
|||||||
namespace tt::app::display {
|
namespace tt::app::display {
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t value);
|
void setBacklightDuty(uint8_t value);
|
||||||
uint8_t getBacklightDuty();
|
|
||||||
|
bool getBacklightDuty(uint8_t& duty);
|
||||||
|
|
||||||
|
void setGammaCurve(uint8_t curveIndex);
|
||||||
|
|
||||||
|
bool getGammaCurve(uint8_t& curveIndex);
|
||||||
|
|
||||||
void setRotation(lv_display_rotation_t rotation);
|
void setRotation(lv_display_rotation_t rotation);
|
||||||
|
|
||||||
lv_display_rotation_t getRotation();
|
lv_display_rotation_t getRotation();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -32,9 +32,9 @@ class BootApp : public App {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Thread thread = Thread("boot", 4096, bootThreadCallback, this);
|
Thread thread = Thread("boot", 4096, [this]() { return bootThreadCallback(); });
|
||||||
|
|
||||||
static int32_t bootThreadCallback(TT_UNUSED void* context) {
|
int32_t bootThreadCallback() {
|
||||||
TickType_t start_time = kernel::getTicks();
|
TickType_t start_time = kernel::getTicks();
|
||||||
|
|
||||||
kernel::publishSystemEvent(kernel::SystemEvent::BootSplash);
|
kernel::publishSystemEvent(kernel::SystemEvent::BootSplash);
|
||||||
@ -42,14 +42,22 @@ private:
|
|||||||
auto hal_display = getHalDisplay();
|
auto hal_display = getHalDisplay();
|
||||||
assert(hal_display != nullptr);
|
assert(hal_display != nullptr);
|
||||||
if (hal_display->supportsBacklightDuty()) {
|
if (hal_display->supportsBacklightDuty()) {
|
||||||
int32_t backlight_duty = app::display::getBacklightDuty();
|
uint8_t backlight_duty = 200;
|
||||||
TT_LOG_I(TAG, "backlight %ld", backlight_duty);
|
app::display::getBacklightDuty(backlight_duty);
|
||||||
|
TT_LOG_I(TAG, "backlight %du", backlight_duty);
|
||||||
hal_display->setBacklightDuty(backlight_duty);
|
hal_display->setBacklightDuty(backlight_duty);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
TT_LOG_I(TAG, "no backlight");
|
TT_LOG_I(TAG, "no backlight");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hal_display->getGammaCurveCount() > 0) {
|
||||||
|
uint8_t gamma_curve;
|
||||||
|
if (app::display::getGammaCurve(gamma_curve)) {
|
||||||
|
hal_display->setGammaCurve(gamma_curve);
|
||||||
|
TT_LOG_I(TAG, "gamma %du", gamma_curve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hal::usb::isUsbBootMode()) {
|
if (hal::usb::isUsbBootMode()) {
|
||||||
TT_LOG_I(TAG, "Rebooting into mass storage device mode");
|
TT_LOG_I(TAG, "Rebooting into mass storage device mode");
|
||||||
hal::usb::resetUsbBootMode();
|
hal::usb::resetUsbBootMode();
|
||||||
|
|||||||
@ -55,6 +55,7 @@ static void onGammaSliderEvent(lv_event_t* event) {
|
|||||||
gamma = (uint8_t)slider_value;
|
gamma = (uint8_t)slider_value;
|
||||||
|
|
||||||
hal_display->setGammaCurve(gamma);
|
hal_display->setGammaCurve(gamma);
|
||||||
|
tt::app::display::setGammaCurve(gamma);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,11 +137,25 @@ class DisplayApp : public App {
|
|||||||
lv_slider_set_value(brightness_slider, 255, LV_ANIM_OFF);
|
lv_slider_set_value(brightness_slider, 255, LV_ANIM_OFF);
|
||||||
lv_obj_add_state(brightness_slider, LV_STATE_DISABLED);
|
lv_obj_add_state(brightness_slider, LV_STATE_DISABLED);
|
||||||
} else {
|
} else {
|
||||||
uint8_t value = getBacklightDuty();
|
uint8_t value;
|
||||||
lv_slider_set_value(brightness_slider, value, LV_ANIM_OFF);
|
if (getBacklightDuty(value)) {
|
||||||
|
lv_slider_set_value(brightness_slider, value, LV_ANIM_OFF);
|
||||||
|
} else {
|
||||||
|
lv_slider_set_value(brightness_slider, 0, LV_ANIM_OFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_slider_set_value(gamma_slider, 128, LV_ANIM_OFF);
|
if (hal_display->getGammaCurveCount() == 0) {
|
||||||
|
lv_slider_set_value(gamma_slider, 0, LV_ANIM_OFF);
|
||||||
|
lv_obj_add_state(gamma_slider, LV_STATE_DISABLED);
|
||||||
|
} else {
|
||||||
|
uint8_t curve_index;
|
||||||
|
if (getGammaCurve(curve_index)) {
|
||||||
|
lv_slider_set_value(gamma_slider, curve_index, LV_ANIM_OFF);
|
||||||
|
} else {
|
||||||
|
lv_slider_set_value(gamma_slider, 0, LV_ANIM_OFF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto* orientation_label = lv_label_create(wrapper);
|
auto* orientation_label = lv_label_create(wrapper);
|
||||||
lv_label_set_text(orientation_label, "Orientation");
|
lv_label_set_text(orientation_label, "Orientation");
|
||||||
|
|||||||
@ -6,19 +6,21 @@ namespace tt::app::display {
|
|||||||
|
|
||||||
tt::Preferences preferences("display");
|
tt::Preferences preferences("display");
|
||||||
|
|
||||||
#define BACKLIGHT_DUTY_KEY "backlight_duty"
|
constexpr const char* BACKLIGHT_DUTY_KEY = "backlight_duty";
|
||||||
#define ROTATION_KEY "rotation"
|
constexpr const char* GAMMA_CURVE_KEY = "gamma";
|
||||||
|
constexpr const char* ROTATION_KEY = "rotation";
|
||||||
|
|
||||||
void setBacklightDuty(uint8_t value) {
|
void setBacklightDuty(uint8_t value) {
|
||||||
preferences.putInt32(BACKLIGHT_DUTY_KEY, (int32_t)value);
|
preferences.putInt32(BACKLIGHT_DUTY_KEY, (int32_t)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t getBacklightDuty() {
|
bool getBacklightDuty(uint8_t& duty) {
|
||||||
int32_t result;
|
int32_t result;
|
||||||
if (preferences.optInt32(BACKLIGHT_DUTY_KEY, result)) {
|
if (preferences.optInt32(BACKLIGHT_DUTY_KEY, result)) {
|
||||||
return (uint8_t)(result % 256);
|
duty = (uint8_t)(result % 256);
|
||||||
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return 200;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,4 +37,18 @@ lv_display_rotation_t getRotation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setGammaCurve(uint8_t curveIndex) {
|
||||||
|
preferences.putInt32(GAMMA_CURVE_KEY, (int32_t)curveIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getGammaCurve(uint8_t& curveIndex) {
|
||||||
|
int32_t result;
|
||||||
|
if (preferences.optInt32(GAMMA_CURVE_KEY, result)) {
|
||||||
|
curveIndex = (uint8_t)(result % 256);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -228,8 +228,8 @@ void View::showActionsForFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void View::update() {
|
void View::update() {
|
||||||
auto scoped_lockable = lvgl::getSyncLock()->scoped();
|
auto scoped_lockable = lvgl::getSyncLock()->asScopedLock();
|
||||||
if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) {
|
if (scoped_lockable.lock(lvgl::defaultLockTime)) {
|
||||||
lv_obj_clean(dir_entry_list);
|
lv_obj_clean(dir_entry_list);
|
||||||
|
|
||||||
state->withEntries([this](const std::vector<dirent>& entries) {
|
state->withEntries([this](const std::vector<dirent>& entries) {
|
||||||
@ -277,15 +277,15 @@ void View::init(lv_obj_t* parent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void View::onDirEntryListScrollBegin() {
|
void View::onDirEntryListScrollBegin() {
|
||||||
auto scoped_lockable = lvgl::getSyncLock()->scoped();
|
auto scoped_lockable = lvgl::getSyncLock()->asScopedLock();
|
||||||
if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) {
|
if (scoped_lockable.lock(lvgl::defaultLockTime)) {
|
||||||
lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void View::onNavigate() {
|
void View::onNavigate() {
|
||||||
auto scoped_lockable = lvgl::getSyncLock()->scoped();
|
auto scoped_lockable = lvgl::getSyncLock()->asScopedLock();
|
||||||
if (scoped_lockable->lock(100 / portTICK_PERIOD_MS)) {
|
if (scoped_lockable.lock(lvgl::defaultLockTime)) {
|
||||||
lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(action_list, LV_OBJ_FLAG_HIDDEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,8 +57,8 @@ void GpioApp::updatePinWidgets() {
|
|||||||
lv_obj_t* label = lvPins[j];
|
lv_obj_t* label = lvPins[j];
|
||||||
void* label_user_data = lv_obj_get_user_data(label);
|
void* label_user_data = lv_obj_get_user_data(label);
|
||||||
// The user data stores the state, so we can avoid unnecessary updates
|
// The user data stores the state, so we can avoid unnecessary updates
|
||||||
if ((void*)level != label_user_data) {
|
if (reinterpret_cast<void*>(level) != label_user_data) {
|
||||||
lv_obj_set_user_data(label, (void*)level);
|
lv_obj_set_user_data(label, reinterpret_cast<void*>(level));
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
lv_obj_set_style_text_color(label, lv_color_black(), 0);
|
lv_obj_set_style_text_color(label, lv_color_black(), 0);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -20,7 +20,8 @@ class ImageViewerApp : public App {
|
|||||||
auto wrapper = lv_obj_create(parent);
|
auto wrapper = lv_obj_create(parent);
|
||||||
lv_obj_set_size(wrapper, LV_PCT(100), LV_PCT(100));
|
lv_obj_set_size(wrapper, LV_PCT(100), LV_PCT(100));
|
||||||
lv_obj_set_style_border_width(wrapper, 0, 0);
|
lv_obj_set_style_border_width(wrapper, 0, 0);
|
||||||
lvgl::obj_set_style_no_padding(wrapper);
|
lv_obj_set_style_pad_all(wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(wrapper, 0, 0);
|
||||||
|
|
||||||
auto toolbar = lvgl::toolbar_create(wrapper, app);
|
auto toolbar = lvgl::toolbar_create(wrapper, app);
|
||||||
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
lv_obj_align(toolbar, LV_ALIGN_TOP_MID, 0, 0);
|
||||||
@ -32,7 +33,8 @@ class ImageViewerApp : public App {
|
|||||||
lv_obj_set_height(image_wrapper, parent_height - TOOLBAR_HEIGHT);
|
lv_obj_set_height(image_wrapper, parent_height - TOOLBAR_HEIGHT);
|
||||||
lv_obj_set_flex_flow(image_wrapper, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(image_wrapper, LV_FLEX_FLOW_COLUMN);
|
||||||
lv_obj_set_flex_align(image_wrapper, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
lv_obj_set_flex_align(image_wrapper, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||||
lvgl::obj_set_style_no_padding(image_wrapper);
|
lv_obj_set_style_pad_all(image_wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(image_wrapper, 0, 0);
|
||||||
lvgl::obj_set_style_bg_invisible(image_wrapper);
|
lvgl::obj_set_style_bg_invisible(image_wrapper);
|
||||||
|
|
||||||
auto* image = lv_image_create(image_wrapper);
|
auto* image = lv_image_create(image_wrapper);
|
||||||
|
|||||||
@ -81,7 +81,8 @@ public:
|
|||||||
lv_obj_set_width(wrapper, LV_PCT(100));
|
lv_obj_set_width(wrapper, LV_PCT(100));
|
||||||
lv_obj_set_flex_grow(wrapper, 1);
|
lv_obj_set_flex_grow(wrapper, 1);
|
||||||
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
|
||||||
lvgl::obj_set_style_no_padding(wrapper);
|
lv_obj_set_style_pad_all(wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(wrapper, 0, 0);
|
||||||
lvgl::obj_set_style_bg_invisible(wrapper);
|
lvgl::obj_set_style_bg_invisible(wrapper);
|
||||||
|
|
||||||
labelWidget = lv_label_create(wrapper);
|
labelWidget = lv_label_create(wrapper);
|
||||||
|
|||||||
@ -161,7 +161,8 @@ public:
|
|||||||
lv_obj_t* switch_container = lv_obj_create(wrapper);
|
lv_obj_t* switch_container = lv_obj_create(wrapper);
|
||||||
lv_obj_set_width(switch_container, LV_PCT(100));
|
lv_obj_set_width(switch_container, LV_PCT(100));
|
||||||
lv_obj_set_height(switch_container, LV_SIZE_CONTENT);
|
lv_obj_set_height(switch_container, LV_SIZE_CONTENT);
|
||||||
lvgl::obj_set_style_no_padding(switch_container);
|
lv_obj_set_style_pad_all(switch_container, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(switch_container, 0, 0);
|
||||||
lvgl::obj_set_style_bg_invisible(switch_container);
|
lvgl::obj_set_style_bg_invisible(switch_container);
|
||||||
|
|
||||||
enableLabel = lv_label_create(switch_container);
|
enableLabel = lv_label_create(switch_container);
|
||||||
|
|||||||
@ -78,7 +78,8 @@ class WifiApSettings : public App {
|
|||||||
|
|
||||||
auto* auto_connect_wrapper = lv_obj_create(wrapper);
|
auto* auto_connect_wrapper = lv_obj_create(wrapper);
|
||||||
lv_obj_set_size(auto_connect_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
lv_obj_set_size(auto_connect_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
lvgl::obj_set_style_no_padding(auto_connect_wrapper);
|
lv_obj_set_style_pad_all(auto_connect_wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(auto_connect_wrapper, 0, 0);
|
||||||
lv_obj_set_style_border_width(auto_connect_wrapper, 0, 0);
|
lv_obj_set_style_border_width(auto_connect_wrapper, 0, 0);
|
||||||
|
|
||||||
auto* auto_connect_label = lv_label_create(auto_connect_wrapper);
|
auto* auto_connect_label = lv_label_create(auto_connect_wrapper);
|
||||||
|
|||||||
@ -16,8 +16,6 @@ namespace tt::app::wificonnect {
|
|||||||
|
|
||||||
#define TAG "wifi_connect"
|
#define TAG "wifi_connect"
|
||||||
|
|
||||||
std::shared_ptr<WifiConnect> _Nullable optWifiConnect();
|
|
||||||
|
|
||||||
void View::resetErrors() {
|
void View::resetErrors() {
|
||||||
lv_obj_add_flag(password_error, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(password_error, LV_OBJ_FLAG_HIDDEN);
|
||||||
lv_obj_add_flag(ssid_error, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(ssid_error, LV_OBJ_FLAG_HIDDEN);
|
||||||
@ -87,7 +85,8 @@ void View::createBottomButtons(lv_obj_t* parent) {
|
|||||||
auto* button_container = lv_obj_create(parent);
|
auto* button_container = lv_obj_create(parent);
|
||||||
lv_obj_set_width(button_container, LV_PCT(100));
|
lv_obj_set_width(button_container, LV_PCT(100));
|
||||||
lv_obj_set_height(button_container, LV_SIZE_CONTENT);
|
lv_obj_set_height(button_container, LV_SIZE_CONTENT);
|
||||||
lvgl::obj_set_style_no_padding(button_container);
|
lv_obj_set_style_pad_all(button_container, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(button_container, 0, 0);
|
||||||
lv_obj_set_style_border_width(button_container, 0, 0);
|
lv_obj_set_style_border_width(button_container, 0, 0);
|
||||||
|
|
||||||
remember_switch = lv_switch_create(button_container);
|
remember_switch = lv_switch_create(button_container);
|
||||||
@ -126,7 +125,8 @@ void View::init(AppContext& app, lv_obj_t* parent) {
|
|||||||
auto* ssid_wrapper = lv_obj_create(wrapper);
|
auto* ssid_wrapper = lv_obj_create(wrapper);
|
||||||
lv_obj_set_width(ssid_wrapper, LV_PCT(100));
|
lv_obj_set_width(ssid_wrapper, LV_PCT(100));
|
||||||
lv_obj_set_height(ssid_wrapper, LV_SIZE_CONTENT);
|
lv_obj_set_height(ssid_wrapper, LV_SIZE_CONTENT);
|
||||||
lvgl::obj_set_style_no_padding(ssid_wrapper);
|
lv_obj_set_style_pad_all(ssid_wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(ssid_wrapper, 0, 0);
|
||||||
lv_obj_set_style_border_width(ssid_wrapper, 0, 0);
|
lv_obj_set_style_border_width(ssid_wrapper, 0, 0);
|
||||||
|
|
||||||
auto* ssid_label_wrapper = lv_obj_create(ssid_wrapper);
|
auto* ssid_label_wrapper = lv_obj_create(ssid_wrapper);
|
||||||
@ -154,7 +154,8 @@ void View::init(AppContext& app, lv_obj_t* parent) {
|
|||||||
auto* password_wrapper = lv_obj_create(wrapper);
|
auto* password_wrapper = lv_obj_create(wrapper);
|
||||||
lv_obj_set_width(password_wrapper, LV_PCT(100));
|
lv_obj_set_width(password_wrapper, LV_PCT(100));
|
||||||
lv_obj_set_height(password_wrapper, LV_SIZE_CONTENT);
|
lv_obj_set_height(password_wrapper, LV_SIZE_CONTENT);
|
||||||
lvgl::obj_set_style_no_padding(password_wrapper);
|
lv_obj_set_style_pad_all(password_wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(password_wrapper, 0, 0);
|
||||||
lv_obj_set_style_border_width(password_wrapper, 0, 0);
|
lv_obj_set_style_border_width(password_wrapper, 0, 0);
|
||||||
|
|
||||||
auto* password_label_wrapper = lv_obj_create(password_wrapper);
|
auto* password_label_wrapper = lv_obj_create(password_wrapper);
|
||||||
|
|||||||
@ -93,7 +93,8 @@ void View::createSsidListItem(const service::wifi::ApRecord& record, bool isConn
|
|||||||
lv_obj_add_event_cb(wrapper, &connect, LV_EVENT_SHORT_CLICKED, bindings);
|
lv_obj_add_event_cb(wrapper, &connect, LV_EVENT_SHORT_CLICKED, bindings);
|
||||||
lv_obj_set_user_data(wrapper, bindings);
|
lv_obj_set_user_data(wrapper, bindings);
|
||||||
lv_obj_set_size(wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
lv_obj_set_size(wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||||
lvgl::obj_set_style_no_padding(wrapper);
|
lv_obj_set_style_pad_all(wrapper, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(wrapper, 0, 0);
|
||||||
lv_obj_set_style_margin_all(wrapper, 0, 0);
|
lv_obj_set_style_margin_all(wrapper, 0, 0);
|
||||||
lv_obj_set_style_border_width(wrapper, 0, 0);
|
lv_obj_set_style_border_width(wrapper, 0, 0);
|
||||||
|
|
||||||
@ -285,7 +286,8 @@ void View::init(const AppContext& app, lv_obj_t* parent) {
|
|||||||
lv_obj_set_flex_grow(secondary_flex, 1);
|
lv_obj_set_flex_grow(secondary_flex, 1);
|
||||||
lv_obj_set_flex_flow(secondary_flex, LV_FLEX_FLOW_COLUMN);
|
lv_obj_set_flex_flow(secondary_flex, LV_FLEX_FLOW_COLUMN);
|
||||||
lv_obj_set_style_border_width(secondary_flex, 0, 0);
|
lv_obj_set_style_border_width(secondary_flex, 0, 0);
|
||||||
lvgl::obj_set_style_no_padding(secondary_flex);
|
lv_obj_set_style_pad_all(secondary_flex, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(secondary_flex, 0, 0);
|
||||||
lvgl::obj_set_style_bg_invisible(secondary_flex);
|
lvgl::obj_set_style_bg_invisible(secondary_flex);
|
||||||
|
|
||||||
// align() methods don't work on flex, so we need this extra wrapper
|
// align() methods don't work on flex, so we need this extra wrapper
|
||||||
|
|||||||
@ -16,9 +16,9 @@ bool initEspLvglPort() {
|
|||||||
TT_LOG_D(TAG, "Port init");
|
TT_LOG_D(TAG, "Port init");
|
||||||
static lv_disp_t* display = nullptr;
|
static lv_disp_t* display = nullptr;
|
||||||
const lvgl_port_cfg_t lvgl_cfg = {
|
const lvgl_port_cfg_t lvgl_cfg = {
|
||||||
.task_priority = static_cast<UBaseType_t>(tt::THREAD_PRIORITY_RENDER),
|
.task_priority = static_cast<UBaseType_t>(Thread::Priority::Critical),
|
||||||
.task_stack = TDECK_LVGL_TASK_STACK_DEPTH,
|
.task_stack = TDECK_LVGL_TASK_STACK_DEPTH,
|
||||||
.task_affinity = -1, // core pinning
|
.task_affinity = 1, // -1 = disabled, 0 = core 1, 1 = core 2
|
||||||
.task_max_sleep_ms = 500,
|
.task_max_sleep_ms = 500,
|
||||||
.timer_period_ms = 5
|
.timer_period_ms = 5
|
||||||
};
|
};
|
||||||
|
|||||||
@ -22,7 +22,7 @@ void syncSet(LvglLock lock, LvglUnlock unlock) {
|
|||||||
auto old_unlock = unlock_singleton;
|
auto old_unlock = unlock_singleton;
|
||||||
|
|
||||||
// Ensure the old lock is not engaged when changing locks
|
// Ensure the old lock is not engaged when changing locks
|
||||||
old_lock(portMAX_DELAY);
|
old_lock((uint32_t)portMAX_DELAY);
|
||||||
lock_singleton = lock;
|
lock_singleton = lock;
|
||||||
unlock_singleton = unlock;
|
unlock_singleton = unlock;
|
||||||
old_unlock();
|
old_unlock();
|
||||||
|
|||||||
@ -112,7 +112,8 @@ lv_obj_t* toolbar_add_button_action(lv_obj_t* obj, const char* icon, lv_event_cb
|
|||||||
|
|
||||||
lv_obj_t* action_button = lv_button_create(toolbar->action_container);
|
lv_obj_t* action_button = lv_button_create(toolbar->action_container);
|
||||||
lv_obj_set_size(action_button, TOOLBAR_HEIGHT - 4, TOOLBAR_HEIGHT - 4);
|
lv_obj_set_size(action_button, TOOLBAR_HEIGHT - 4, TOOLBAR_HEIGHT - 4);
|
||||||
obj_set_style_no_padding(action_button);
|
lv_obj_set_style_pad_all(action_button, 0, 0);
|
||||||
|
lv_obj_set_style_pad_gap(action_button, 0, 0);
|
||||||
lv_obj_add_event_cb(action_button, callback, LV_EVENT_SHORT_CLICKED, user_data);
|
lv_obj_add_event_cb(action_button, callback, LV_EVENT_SHORT_CLICKED, user_data);
|
||||||
lv_obj_t* action_button_image = lv_image_create(action_button);
|
lv_obj_t* action_button_image = lv_image_create(action_button);
|
||||||
lv_image_set_src(action_button_image, icon);
|
lv_image_set_src(action_button_image, icon);
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace tt::service::gui {
|
|||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
void redraw(Gui*);
|
void redraw(Gui*);
|
||||||
static int32_t guiMain(TT_UNUSED void* p);
|
static int32_t guiMain();
|
||||||
|
|
||||||
Gui* gui = nullptr;
|
Gui* gui = nullptr;
|
||||||
|
|
||||||
@ -33,8 +33,7 @@ Gui* gui_alloc() {
|
|||||||
instance->thread = new Thread(
|
instance->thread = new Thread(
|
||||||
"gui",
|
"gui",
|
||||||
4096, // Last known minimum was 2800 for launching desktop
|
4096, // Last known minimum was 2800 for launching desktop
|
||||||
&guiMain,
|
[]() { return guiMain(); }
|
||||||
nullptr
|
|
||||||
);
|
);
|
||||||
instance->loader_pubsub_subscription = loader::getPubsub()->subscribe(&onLoaderMessage, instance);
|
instance->loader_pubsub_subscription = loader::getPubsub()->subscribe(&onLoaderMessage, instance);
|
||||||
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
||||||
@ -118,7 +117,7 @@ void hideApp() {
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t guiMain(TT_UNUSED void* p) {
|
static int32_t guiMain() {
|
||||||
tt_check(gui);
|
tt_check(gui);
|
||||||
Gui* local_gui = gui;
|
Gui* local_gui = gui;
|
||||||
|
|
||||||
|
|||||||
@ -59,13 +59,6 @@ static void makeScreenshot(const std::string& filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t screenshotTaskCallback(void* context) {
|
|
||||||
auto* data = static_cast<ScreenshotTask*>(context);
|
|
||||||
assert(data != nullptr);
|
|
||||||
data->taskMain();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScreenshotTask::taskMain() {
|
void ScreenshotTask::taskMain() {
|
||||||
uint8_t screenshots_taken = 0;
|
uint8_t screenshots_taken = 0;
|
||||||
std::string last_app_id;
|
std::string last_app_id;
|
||||||
@ -116,8 +109,10 @@ void ScreenshotTask::taskStart() {
|
|||||||
thread = new Thread(
|
thread = new Thread(
|
||||||
"screenshot",
|
"screenshot",
|
||||||
8192,
|
8192,
|
||||||
&screenshotTaskCallback,
|
[this]() {
|
||||||
this
|
this->taskMain();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
thread->start();
|
thread->start();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,8 +18,9 @@ ThreadHandle tt_thread_alloc_ext(
|
|||||||
return new tt::Thread(
|
return new tt::Thread(
|
||||||
name,
|
name,
|
||||||
stackSize,
|
stackSize,
|
||||||
callback,
|
[callback, callbackContext]() {
|
||||||
callbackContext
|
return callback(callbackContext);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,7 +37,9 @@ void tt_thread_set_stack_size(ThreadHandle handle, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void tt_thread_set_callback(ThreadHandle handle, ThreadCallback callback, void* _Nullable callbackContext) {
|
void tt_thread_set_callback(ThreadHandle handle, ThreadCallback callback, void* _Nullable callbackContext) {
|
||||||
HANDLE_AS_THREAD(handle)->setCallback(callback, callbackContext);
|
HANDLE_AS_THREAD(handle)->setMainFunction([callback, callbackContext]() {
|
||||||
|
return callback(callbackContext);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void tt_thread_set_priority(ThreadHandle handle, ThreadPriority priority) {
|
void tt_thread_set_priority(ThreadHandle handle, ThreadPriority priority) {
|
||||||
|
|||||||
@ -73,22 +73,6 @@ public:
|
|||||||
|
|
||||||
Thread() = default;
|
Thread() = default;
|
||||||
|
|
||||||
/** Allocate Thread, shortcut version
|
|
||||||
* @param[in] name the name of the thread
|
|
||||||
* @param[in] stackSize in bytes
|
|
||||||
* @param[in] callback
|
|
||||||
* @param[in] callbackContext
|
|
||||||
* @param[in] affinity Which CPU core to pin this task to, -1 means unpinned (only works on ESP32)
|
|
||||||
*/
|
|
||||||
[[deprecated("Use constructor variant with std::function")]]
|
|
||||||
Thread(
|
|
||||||
std::string name,
|
|
||||||
configSTACK_DEPTH_TYPE stackSize,
|
|
||||||
Callback callback,
|
|
||||||
_Nullable void* callbackContext,
|
|
||||||
portBASE_TYPE affinity = -1
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Allocate Thread, shortcut version
|
/** Allocate Thread, shortcut version
|
||||||
* @param[in] name the name of the thread
|
* @param[in] name the name of the thread
|
||||||
* @param[in] stackSize in bytes
|
* @param[in] stackSize in bytes
|
||||||
@ -200,7 +184,6 @@ public:
|
|||||||
static uint32_t awaitFlags(uint32_t flags, uint32_t options, uint32_t timeout);
|
static uint32_t awaitFlags(uint32_t flags, uint32_t options, uint32_t timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define THREAD_PRIORITY_APP Thread::PriorityNormal
|
|
||||||
#define THREAD_PRIORITY_SERVICE Thread::Priority::High
|
#define THREAD_PRIORITY_SERVICE Thread::Priority::High
|
||||||
#define THREAD_PRIORITY_RENDER Thread::Priority::Higher
|
#define THREAD_PRIORITY_RENDER Thread::Priority::Higher
|
||||||
#define THREAD_PRIORITY_ISR Thread::Priority::Critical
|
#define THREAD_PRIORITY_ISR Thread::Priority::Critical
|
||||||
|
|||||||
@ -24,6 +24,8 @@ static char toPrefix(LogLevel level) {
|
|||||||
return 'D';
|
return 'D';
|
||||||
case Verbose:
|
case Verbose:
|
||||||
return 'V';
|
return 'V';
|
||||||
|
default:
|
||||||
|
return ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,21 +66,6 @@ void Thread::mainBody(void* context) {
|
|||||||
threadCatch();
|
threadCatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(
|
|
||||||
std::string name,
|
|
||||||
configSTACK_DEPTH_TYPE stackSize,
|
|
||||||
Callback callback,
|
|
||||||
_Nullable void* callbackContext,
|
|
||||||
portBASE_TYPE affinity
|
|
||||||
) :
|
|
||||||
mainFunction([callback, callbackContext]() {
|
|
||||||
return callback(callbackContext);
|
|
||||||
}),
|
|
||||||
name(std::move(name)),
|
|
||||||
stackSize(stackSize),
|
|
||||||
affinity(affinity)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Thread::Thread(
|
Thread::Thread(
|
||||||
std::string name,
|
std::string name,
|
||||||
configSTACK_DEPTH_TYPE stackSize,
|
configSTACK_DEPTH_TYPE stackSize,
|
||||||
|
|||||||
@ -4,12 +4,6 @@
|
|||||||
|
|
||||||
using namespace tt;
|
using namespace tt;
|
||||||
|
|
||||||
static int32_t thread_with_mutex_parameter(void* parameter) {
|
|
||||||
auto* mutex = (Mutex*)parameter;
|
|
||||||
mutex->lock(portMAX_DELAY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("a mutex can block a thread") {
|
TEST_CASE("a mutex can block a thread") {
|
||||||
auto mutex = Mutex(Mutex::Type::Normal);
|
auto mutex = Mutex(Mutex::Type::Normal);
|
||||||
mutex.lock(portMAX_DELAY);
|
mutex.lock(portMAX_DELAY);
|
||||||
@ -17,8 +11,10 @@ TEST_CASE("a mutex can block a thread") {
|
|||||||
Thread thread = Thread(
|
Thread thread = Thread(
|
||||||
"thread",
|
"thread",
|
||||||
1024,
|
1024,
|
||||||
&thread_with_mutex_parameter,
|
[&mutex]() {
|
||||||
&mutex
|
mutex.lock(portMAX_DELAY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
thread.start();
|
thread.start();
|
||||||
|
|
||||||
|
|||||||
@ -4,33 +4,17 @@
|
|||||||
|
|
||||||
using namespace tt;
|
using namespace tt;
|
||||||
|
|
||||||
static int interruptable_thread(void* parameter) {
|
|
||||||
bool* interrupted = (bool*)parameter;
|
|
||||||
while (!*interrupted) {
|
|
||||||
kernel::delayMillis(5);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int immediate_return_thread(void* parameter) {
|
|
||||||
bool* has_called = (bool*)parameter;
|
|
||||||
*has_called = true;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int thread_with_return_code(void* parameter) {
|
|
||||||
int* code = (int*)parameter;
|
|
||||||
return *code;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("when a thread is started then its callback should be called") {
|
TEST_CASE("when a thread is started then its callback should be called") {
|
||||||
bool has_called = false;
|
bool has_called = false;
|
||||||
auto* thread = new Thread(
|
auto* thread = new Thread(
|
||||||
"immediate return task",
|
"immediate return task",
|
||||||
4096,
|
4096,
|
||||||
&immediate_return_thread,
|
[&has_called]() {
|
||||||
&has_called
|
has_called = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
CHECK(!has_called);
|
CHECK(!has_called);
|
||||||
thread->start();
|
thread->start();
|
||||||
thread->join();
|
thread->join();
|
||||||
@ -43,9 +27,14 @@ TEST_CASE("a thread can be started and stopped") {
|
|||||||
auto* thread = new Thread(
|
auto* thread = new Thread(
|
||||||
"interruptable thread",
|
"interruptable thread",
|
||||||
4096,
|
4096,
|
||||||
&interruptable_thread,
|
[&interrupted]() {
|
||||||
&interrupted
|
while (!interrupted) {
|
||||||
|
kernel::delayMillis(5);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
CHECK(thread);
|
CHECK(thread);
|
||||||
thread->start();
|
thread->start();
|
||||||
interrupted = true;
|
interrupted = true;
|
||||||
@ -58,8 +47,12 @@ TEST_CASE("thread id should only be set at when thread is started") {
|
|||||||
auto* thread = new Thread(
|
auto* thread = new Thread(
|
||||||
"interruptable thread",
|
"interruptable thread",
|
||||||
4096,
|
4096,
|
||||||
&interruptable_thread,
|
[&interrupted]() {
|
||||||
&interrupted
|
while (!interrupted) {
|
||||||
|
kernel::delayMillis(5);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
CHECK_EQ(thread->getId(), nullptr);
|
CHECK_EQ(thread->getId(), nullptr);
|
||||||
thread->start();
|
thread->start();
|
||||||
@ -75,8 +68,13 @@ TEST_CASE("thread state should be correct") {
|
|||||||
auto* thread = new Thread(
|
auto* thread = new Thread(
|
||||||
"interruptable thread",
|
"interruptable thread",
|
||||||
4096,
|
4096,
|
||||||
&interruptable_thread,
|
[&interrupted]() {
|
||||||
&interrupted
|
while (!interrupted) {
|
||||||
|
kernel::delayMillis(5);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
CHECK_EQ(thread->getState(), Thread::State::Stopped);
|
CHECK_EQ(thread->getState(), Thread::State::Stopped);
|
||||||
thread->start();
|
thread->start();
|
||||||
@ -93,8 +91,7 @@ TEST_CASE("thread id should only be set at when thread is started") {
|
|||||||
auto* thread = new Thread(
|
auto* thread = new Thread(
|
||||||
"return code",
|
"return code",
|
||||||
4096,
|
4096,
|
||||||
&thread_with_return_code,
|
[&code]() { return code; }
|
||||||
&code
|
|
||||||
);
|
);
|
||||||
thread->start();
|
thread->start();
|
||||||
thread->join();
|
thread->join();
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
0.3.0
|
0.4.0
|
||||||
Loading…
x
Reference in New Issue
Block a user