Service & app paths improvements
|
Before Width: | Height: | Size: 753 B After Width: | Height: | Size: 753 B |
|
Before Width: | Height: | Size: 528 B After Width: | Height: | Size: 528 B |
|
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 142 B |
|
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 144 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 146 B After Width: | Height: | Size: 146 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 149 B |
|
Before Width: | Height: | Size: 193 B After Width: | Height: | Size: 193 B |
|
Before Width: | Height: | Size: 196 B After Width: | Height: | Size: 196 B |
|
Before Width: | Height: | Size: 394 B After Width: | Height: | Size: 394 B |
|
Before Width: | Height: | Size: 407 B After Width: | Height: | Size: 407 B |
|
Before Width: | Height: | Size: 524 B After Width: | Height: | Size: 524 B |
|
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 517 B |
|
Before Width: | Height: | Size: 534 B After Width: | Height: | Size: 534 B |
@ -17,37 +17,31 @@ public:
|
|||||||
explicit AppPaths(const AppManifest& manifest) : manifest(manifest) {}
|
explicit AppPaths(const AppManifest& manifest) : manifest(manifest) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the directory path for the data location for an app.
|
* The user data directory is intended to survive OS upgrades.
|
||||||
* The data directory is intended to survive OS upgrades.
|
|
||||||
* The path will not end with a "/".
|
* The path will not end with a "/".
|
||||||
*/
|
*/
|
||||||
std::string getDataDirectory() const;
|
std::string getUserDataPath() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full path for an entry inside the data location for an app.
|
* The user data directory is intended to survive OS upgrades.
|
||||||
* The data directory is intended to survive OS upgrades.
|
|
||||||
* Configuration data should be stored here.
|
* Configuration data should be stored here.
|
||||||
* @param[in] childPath the path without a "/" prefix
|
* @param[in] childPath the path without a "/" prefix
|
||||||
*/
|
*/
|
||||||
std::string getDataPath(const std::string& childPath) const;
|
std::string getUserDataPath(const std::string& childPath) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the directory path for the system location for an app.
|
|
||||||
* The system directory is not intended to survive OS upgrades.
|
|
||||||
* You should not store configuration data here.
|
* You should not store configuration data here.
|
||||||
* The path will not end with a "/".
|
* The path will not end with a "/".
|
||||||
* This is mainly used for core apps (system/boot/settings type).
|
* This is mainly used for core apps (system/boot/settings type).
|
||||||
*/
|
*/
|
||||||
std::string getSystemDirectory() const;
|
std::string getAssetsDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full path for an entry inside the system location for an app.
|
|
||||||
* The data directory is not intended to survive OS upgrades.
|
|
||||||
* You should not store configuration data here.
|
* You should not store configuration data here.
|
||||||
* This is mainly used for core apps (system/boot/settings type).
|
* This is mainly used for core apps (system/boot/settings type).
|
||||||
* @param[in] childPath the path without a "/" prefix
|
* @param[in] childPath the path without a "/" prefix
|
||||||
*/
|
*/
|
||||||
std::string getSystemPath(const std::string& childPath) const;
|
std::string getAssetsPath(const std::string& childPath) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -17,37 +17,29 @@ public:
|
|||||||
explicit ServicePaths(std::shared_ptr<const ServiceManifest> manifest) : manifest(std::move(manifest)) {}
|
explicit ServicePaths(std::shared_ptr<const ServiceManifest> manifest) : manifest(std::move(manifest)) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the directory path for the data location for a service.
|
* The user data directory is intended to survive OS upgrades.
|
||||||
* The data directory is intended to survive OS upgrades.
|
|
||||||
* The path will not end with a "/".
|
* The path will not end with a "/".
|
||||||
*/
|
*/
|
||||||
std::string getDataDirectory() const;
|
std::string getUserDataDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full path for an entry inside the data location for a service.
|
* The user data directory is intended to survive OS upgrades.
|
||||||
* The data directory is intended to survive OS upgrades.
|
|
||||||
* Configuration data should be stored here.
|
* Configuration data should be stored here.
|
||||||
* @param[in] childPath the path without a "/" prefix
|
* @param[in] childPath the path without a "/" prefix
|
||||||
*/
|
*/
|
||||||
std::string getDataPath(const std::string& childPath) const;
|
std::string getUserDataPath(const std::string& childPath) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the directory path for the system location for a service.
|
|
||||||
* The system directory is not intended to survive OS upgrades.
|
|
||||||
* You should not store configuration data here.
|
* You should not store configuration data here.
|
||||||
* The path will not end with a "/".
|
* The path will not end with a "/".
|
||||||
* This is mainly used for core services.
|
|
||||||
*/
|
*/
|
||||||
std::string getSystemDirectory() const;
|
std::string getAssetsDirectory() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the full path for an entry inside the system location for an app.
|
|
||||||
* The data directory is not intended to survive OS upgrades.
|
|
||||||
* You should not store configuration data here.
|
* You should not store configuration data here.
|
||||||
* This is mainly used for core apps (system/boot/settings type).
|
|
||||||
* @param[in] childPath the path without a "/" prefix
|
* @param[in] childPath the path without a "/" prefix
|
||||||
*/
|
*/
|
||||||
std::string getSystemPath(const std::string& childPath) const;
|
std::string getAssetsPath(const std::string& childPath) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2,36 +2,43 @@
|
|||||||
|
|
||||||
#include <Tactility/app/AppManifest.h>
|
#include <Tactility/app/AppManifest.h>
|
||||||
#include <Tactility/MountPoints.h>
|
#include <Tactility/MountPoints.h>
|
||||||
|
#include <Tactility/file/File.h>
|
||||||
|
|
||||||
|
#include <format>
|
||||||
|
|
||||||
#define LVGL_PATH_PREFIX std::string("A:/")
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#define PARTITION_PREFIX std::string("/")
|
constexpr auto PARTITION_PREFIX = std::string("/");
|
||||||
#else
|
#else
|
||||||
#define PARTITION_PREFIX std::string("")
|
constexpr auto PARTITION_PREFIX = std::string("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace tt::app {
|
namespace tt::app {
|
||||||
|
|
||||||
std::string AppPaths::getDataDirectory() const {
|
std::string AppPaths::getUserDataPath() const {
|
||||||
if (manifest.appLocation.isInternal()) {
|
if (manifest.appLocation.isInternal()) {
|
||||||
|
return std::format("{}{}/app/{}", PARTITION_PREFIX, file::DATA_PARTITION_NAME, manifest.appId);
|
||||||
|
} else {
|
||||||
|
return std::format("{}/user/{}", file::getFirstPathSegment(manifest.appLocation.getPath()), manifest.appId);
|
||||||
}
|
}
|
||||||
return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/app/" + manifest.appId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AppPaths::getDataPath(const std::string& childPath) const {
|
std::string AppPaths::getUserDataPath(const std::string& childPath) const {
|
||||||
assert(!childPath.starts_with('/'));
|
assert(!childPath.starts_with('/'));
|
||||||
return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/app/" + manifest.appId + '/' + childPath;
|
return getUserDataPath() + '/' + childPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string AppPaths::getSystemDirectory() const {
|
std::string AppPaths::getAssetsDirectory() const {
|
||||||
return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/app/" + manifest.appId;
|
if (manifest.appLocation.isInternal()) {
|
||||||
|
return std::format("{}{}/app/{}/assets", PARTITION_PREFIX, file::SYSTEM_PARTITION_NAME, manifest.appId);
|
||||||
|
} else {
|
||||||
|
return std::format("{}/assets", manifest.appLocation.getPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AppPaths::getSystemPath(const std::string& childPath) const {
|
std::string AppPaths::getAssetsPath(const std::string& childPath) const {
|
||||||
assert(!childPath.starts_with('/'));
|
assert(!childPath.starts_with('/'));
|
||||||
return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/app/" + manifest.appId + '/' + childPath;
|
return std::format("{}/{}", getAssetsDirectory(), childPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -164,11 +164,11 @@ public:
|
|||||||
const char* logo;
|
const char* logo;
|
||||||
// TODO: Replace with automatic asset buckets like on Android
|
// TODO: Replace with automatic asset buckets like on Android
|
||||||
if (getSmallestDimension() < 150) { // e.g. Cardputer
|
if (getSmallestDimension() < 150) { // e.g. Cardputer
|
||||||
logo = hal::usb::isUsbBootMode() ? "assets/logo_usb.png" : "assets/logo_small.png";
|
logo = hal::usb::isUsbBootMode() ? "logo_usb.png" : "logo_small.png";
|
||||||
} else {
|
} else {
|
||||||
logo = hal::usb::isUsbBootMode() ? "assets/logo_usb.png" : "assets/logo.png";
|
logo = hal::usb::isUsbBootMode() ? "logo_usb.png" : "logo.png";
|
||||||
}
|
}
|
||||||
const auto logo_path = "A:" + paths->getSystemPath(logo);
|
const auto logo_path = "A:" + paths->getAssetsPath(logo);
|
||||||
TT_LOG_I(TAG, "%s", logo_path.c_str());
|
TT_LOG_I(TAG, "%s", logo_path.c_str());
|
||||||
lv_image_set_src(image, logo_path.c_str());
|
lv_image_set_src(image, logo_path.c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,9 +113,9 @@ public:
|
|||||||
const int32_t margin = is_landscape_display ? std::min<int32_t>(available_width / 16, button_size) : 0;
|
const int32_t margin = is_landscape_display ? std::min<int32_t>(available_width / 16, button_size) : 0;
|
||||||
|
|
||||||
const auto paths = app.getPaths();
|
const auto paths = app.getPaths();
|
||||||
const auto apps_icon_path = "A:" + paths->getSystemPath("assets/icon_apps.png");
|
const auto apps_icon_path = "A:" + paths->getAssetsPath("icon_apps.png");
|
||||||
const auto files_icon_path = "A:" + paths->getSystemPath("assets/icon_files.png");
|
const auto files_icon_path = "A:" + paths->getAssetsPath("icon_files.png");
|
||||||
const auto settings_icon_path = "A:" + paths->getSystemPath("assets/icon_settings.png");
|
const auto settings_icon_path = "A:" + paths->getAssetsPath("icon_settings.png");
|
||||||
|
|
||||||
createAppButton(buttons_wrapper, ui_scale, apps_icon_path.c_str(), "AppList", margin);
|
createAppButton(buttons_wrapper, ui_scale, apps_icon_path.c_str(), "AppList", margin);
|
||||||
createAppButton(buttons_wrapper, ui_scale, files_icon_path.c_str(), "Files", margin);
|
createAppButton(buttons_wrapper, ui_scale, files_icon_path.c_str(), "Files", margin);
|
||||||
|
|||||||
@ -201,7 +201,7 @@ public:
|
|||||||
lv_obj_set_style_image_recolor_opa(icon, 255, 0);
|
lv_obj_set_style_image_recolor_opa(icon, 255, 0);
|
||||||
lv_obj_set_style_image_recolor(icon, lv_theme_get_color_primary(parent), 0);
|
lv_obj_set_style_image_recolor(icon, lv_theme_get_color_primary(parent), 0);
|
||||||
|
|
||||||
std::string icon_path = "A:" + app.getPaths()->getSystemPath("search.png");
|
std::string icon_path = "A:" + app.getPaths()->getAssetsPath("search.png");
|
||||||
lv_image_set_src(icon, icon_path.c_str());
|
lv_image_set_src(icon, icon_path.c_str());
|
||||||
lv_obj_set_style_image_recolor(icon, lv_theme_get_color_primary(parent), 0);
|
lv_obj_set_style_image_recolor(icon, lv_theme_get_color_primary(parent), 0);
|
||||||
|
|
||||||
|
|||||||
@ -3,32 +3,33 @@
|
|||||||
#include <Tactility/service/ServiceManifest.h>
|
#include <Tactility/service/ServiceManifest.h>
|
||||||
#include <Tactility/MountPoints.h>
|
#include <Tactility/MountPoints.h>
|
||||||
|
|
||||||
#define LVGL_PATH_PREFIX std::string("A:/")
|
#include <cassert>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#define PARTITION_PREFIX std::string("/")
|
constexpr auto PARTITION_PREFIX = std::string("/");
|
||||||
#else
|
#else
|
||||||
#define PARTITION_PREFIX std::string("")
|
constexpr auto PARTITION_PREFIX = std::string("");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace tt::service {
|
namespace tt::service {
|
||||||
|
|
||||||
std::string ServicePaths::getDataDirectory() const {
|
std::string ServicePaths::getUserDataDirectory() const {
|
||||||
return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/service/" + manifest->id;
|
return std::format("{}{}/service/{}", PARTITION_PREFIX, file::DATA_PARTITION_NAME, manifest->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ServicePaths::getDataPath(const std::string& childPath) const {
|
std::string ServicePaths::getUserDataPath(const std::string& childPath) const {
|
||||||
assert(!childPath.starts_with('/'));
|
assert(!childPath.starts_with('/'));
|
||||||
return PARTITION_PREFIX + file::DATA_PARTITION_NAME + "/service/" + manifest->id + '/' + childPath;
|
return std::format("{}/{}", getUserDataDirectory(), childPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ServicePaths::getSystemDirectory() const {
|
std::string ServicePaths::getAssetsDirectory() const {
|
||||||
return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/service/" + manifest->id;
|
return std::format("{}{}/service/{}/assets", PARTITION_PREFIX, file::SYSTEM_PARTITION_NAME, manifest->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ServicePaths::getSystemPath(const std::string& childPath) const {
|
std::string ServicePaths::getAssetsPath(const std::string& childPath) const {
|
||||||
assert(!childPath.starts_with('/'));
|
assert(!childPath.starts_with('/'));
|
||||||
return PARTITION_PREFIX + file::SYSTEM_PARTITION_NAME + "/service/" + manifest->id + '/' + childPath;
|
return std::format("{}/{}", getAssetsDirectory(), childPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,12 +17,12 @@ bool GpsService::getConfigurationFilePath(std::string& output) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file::findOrCreateDirectory(paths->getDataDirectory(), 0777)) {
|
if (!file::findOrCreateDirectory(paths->getUserDataDirectory(), 0777)) {
|
||||||
TT_LOG_E(TAG, "Failed to find or create path %s", paths->getDataDirectory().c_str());
|
TT_LOG_E(TAG, "Failed to find or create path %s", paths->getUserDataDirectory().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
output = paths->getDataPath("config.bin");
|
output = paths->getUserDataPath("config.bin");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -163,7 +163,7 @@ class StatusbarService final : public Service {
|
|||||||
bool show_icon = (gps_state == gps::State::OnPending) || (gps_state == gps::State::On);
|
bool show_icon = (gps_state == gps::State::OnPending) || (gps_state == gps::State::On);
|
||||||
if (gps_last_state != show_icon) {
|
if (gps_last_state != show_icon) {
|
||||||
if (show_icon) {
|
if (show_icon) {
|
||||||
auto icon_path = "A:" + paths->getSystemPath(STATUSBAR_ICON_GPS);
|
auto icon_path = "A:" + paths->getAssetsPath(STATUSBAR_ICON_GPS);
|
||||||
lvgl::statusbar_icon_set_image(gps_icon_id, icon_path);
|
lvgl::statusbar_icon_set_image(gps_icon_id, icon_path);
|
||||||
lvgl::statusbar_icon_set_visibility(gps_icon_id, true);
|
lvgl::statusbar_icon_set_visibility(gps_icon_id, true);
|
||||||
} else {
|
} else {
|
||||||
@ -179,7 +179,7 @@ class StatusbarService final : public Service {
|
|||||||
const char* desired_icon = getWifiStatusIcon(radio_state, is_secure);
|
const char* desired_icon = getWifiStatusIcon(radio_state, is_secure);
|
||||||
if (wifi_last_icon != desired_icon) {
|
if (wifi_last_icon != desired_icon) {
|
||||||
if (desired_icon != nullptr) {
|
if (desired_icon != nullptr) {
|
||||||
auto icon_path = "A:" + paths->getSystemPath(desired_icon);
|
auto icon_path = "A:" + paths->getAssetsPath(desired_icon);
|
||||||
lvgl::statusbar_icon_set_image(wifi_icon_id, icon_path);
|
lvgl::statusbar_icon_set_image(wifi_icon_id, icon_path);
|
||||||
lvgl::statusbar_icon_set_visibility(wifi_icon_id, true);
|
lvgl::statusbar_icon_set_visibility(wifi_icon_id, true);
|
||||||
} else {
|
} else {
|
||||||
@ -193,7 +193,7 @@ class StatusbarService final : public Service {
|
|||||||
const char* desired_icon = getPowerStatusIcon();
|
const char* desired_icon = getPowerStatusIcon();
|
||||||
if (power_last_icon != desired_icon) {
|
if (power_last_icon != desired_icon) {
|
||||||
if (desired_icon != nullptr) {
|
if (desired_icon != nullptr) {
|
||||||
auto icon_path = "A:" + paths->getSystemPath(desired_icon);
|
auto icon_path = "A:" + paths->getAssetsPath(desired_icon);
|
||||||
lvgl::statusbar_icon_set_image(power_icon_id, icon_path);
|
lvgl::statusbar_icon_set_image(power_icon_id, icon_path);
|
||||||
lvgl::statusbar_icon_set_visibility(power_icon_id, true);
|
lvgl::statusbar_icon_set_visibility(power_icon_id, true);
|
||||||
} else {
|
} else {
|
||||||
@ -212,7 +212,7 @@ class StatusbarService final : public Service {
|
|||||||
if (state != hal::sdcard::SdCardDevice::State::Timeout) {
|
if (state != hal::sdcard::SdCardDevice::State::Timeout) {
|
||||||
auto* desired_icon = getSdCardStatusIcon(state);
|
auto* desired_icon = getSdCardStatusIcon(state);
|
||||||
if (sdcard_last_icon != desired_icon) {
|
if (sdcard_last_icon != desired_icon) {
|
||||||
auto icon_path = "A:" + paths->getSystemPath(desired_icon);
|
auto icon_path = "A:" + paths->getAssetsPath(desired_icon);
|
||||||
lvgl::statusbar_icon_set_image(sdcard_icon_id, icon_path);
|
lvgl::statusbar_icon_set_image(sdcard_icon_id, icon_path);
|
||||||
lvgl::statusbar_icon_set_visibility(sdcard_icon_id, true);
|
lvgl::statusbar_icon_set_visibility(sdcard_icon_id, true);
|
||||||
sdcard_last_icon = desired_icon;
|
sdcard_last_icon = desired_icon;
|
||||||
|
|||||||
@ -1,24 +1,19 @@
|
|||||||
#include "Tactility/service/wifi/Wifi.h"
|
|
||||||
|
|
||||||
#ifndef ESP_PLATFORM
|
#ifndef ESP_PLATFORM
|
||||||
|
|
||||||
#include "Tactility/service/ServiceContext.h"
|
#include <Tactility/service/wifi/Wifi.h>
|
||||||
|
|
||||||
#include <Tactility/Check.h>
|
#include <Tactility/Check.h>
|
||||||
#include <Tactility/Log.h>
|
#include <Tactility/Log.h>
|
||||||
#include <Tactility/Mutex.h>
|
#include <Tactility/Mutex.h>
|
||||||
#include <Tactility/PubSub.h>
|
#include <Tactility/PubSub.h>
|
||||||
|
#include <Tactility/service/Service.h>
|
||||||
|
#include <Tactility/service/ServiceManifest.h>
|
||||||
|
|
||||||
namespace tt::service::wifi {
|
namespace tt::service::wifi {
|
||||||
|
|
||||||
#define TAG "wifi"
|
constexpr auto* TAG = "Wifi";
|
||||||
#define WIFI_CONNECTED_BIT BIT0
|
|
||||||
#define WIFI_FAIL_BIT BIT1
|
|
||||||
|
|
||||||
struct Wifi {
|
struct Wifi {
|
||||||
Wifi() = default;
|
|
||||||
~Wifi() = default;
|
|
||||||
|
|
||||||
/** @brief Locking mechanism for modifying the Wifi instance */
|
/** @brief Locking mechanism for modifying the Wifi instance */
|
||||||
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
Mutex mutex = Mutex(Mutex::Type::Recursive);
|
||||||
/** @brief The public event bus */
|
/** @brief The public event bus */
|
||||||
@ -144,13 +139,13 @@ class WifiService final : public Service {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bool onStart(TT_UNUSED ServiceContext& service) final {
|
bool onStart(TT_UNUSED ServiceContext& service) override {
|
||||||
tt_check(wifi == nullptr);
|
tt_check(wifi == nullptr);
|
||||||
wifi = new Wifi();
|
wifi = new Wifi();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStop(TT_UNUSED ServiceContext& service) final {
|
void onStop(TT_UNUSED ServiceContext& service) override {
|
||||||
tt_check(wifi != nullptr);
|
tt_check(wifi != nullptr);
|
||||||
delete wifi;
|
delete wifi;
|
||||||
wifi = nullptr;
|
wifi = nullptr;
|
||||||
|
|||||||
@ -39,7 +39,7 @@ void tt_app_get_data_directory(AppPathsHandle handle, char* buffer, size_t* size
|
|||||||
assert(size != nullptr);
|
assert(size != nullptr);
|
||||||
assert(*size > 0);
|
assert(*size > 0);
|
||||||
auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
|
auto paths = HANDLE_AS_APP_CONTEXT(handle)->getPaths();
|
||||||
auto data_path = paths->getDataDirectory();
|
auto data_path = paths->getUserDataPath();
|
||||||
auto expected_length = data_path.length() + 1;
|
auto expected_length = data_path.length() + 1;
|
||||||
if (*size < expected_length) {
|
if (*size < expected_length) {
|
||||||
TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", *size, expected_length);
|
TT_LOG_E(TAG, "Path buffer not large enough (%d < %d)", *size, expected_length);
|
||||||
|
|||||||
@ -83,6 +83,8 @@ std::string getChildPath(const std::string& basePath, const std::string& childPa
|
|||||||
|
|
||||||
std::string getLastPathSegment(const std::string& path);
|
std::string getLastPathSegment(const std::string& path);
|
||||||
|
|
||||||
|
std::string getFirstPathSegment(const std::string& path);
|
||||||
|
|
||||||
typedef int (*ScandirFilter)(const dirent*);
|
typedef int (*ScandirFilter)(const dirent*);
|
||||||
|
|
||||||
typedef bool (*ScandirSort)(const dirent&, const dirent&);
|
typedef bool (*ScandirSort)(const dirent&, const dirent&);
|
||||||
|
|||||||
@ -216,6 +216,19 @@ std::string getLastPathSegment(const std::string& path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getFirstPathSegment(const std::string& path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
auto start_index = path[0] == SEPARATOR ? 1 : 0;
|
||||||
|
auto index = path.find_first_of(SEPARATOR, start_index);
|
||||||
|
if (index != std::string::npos) {
|
||||||
|
return path.substr(0, index);
|
||||||
|
} else {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool findOrCreateDirectory(const std::string& path, mode_t mode) {
|
bool findOrCreateDirectory(const std::string& path, mode_t mode) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||