Remove TactilityCore (#550)
This commit is contained in:
committed by
GitHub
parent
dfaeb9a2d9
commit
66a4eb66d6
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @brief key-value storage for general purpose.
|
||||
* Maps strings on a fixed set of data types.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace tt {
|
||||
|
||||
/**
|
||||
* A dictionary that maps keys (strings) onto several atomary types.
|
||||
*/
|
||||
class Bundle final {
|
||||
|
||||
typedef uint32_t Hash;
|
||||
|
||||
enum class Type {
|
||||
Bool,
|
||||
Int32,
|
||||
Int64,
|
||||
String,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
Type type;
|
||||
union {
|
||||
bool value_bool;
|
||||
int32_t value_int32;
|
||||
int64_t value_int64;
|
||||
};
|
||||
std::string value_string;
|
||||
} Value;
|
||||
|
||||
std::unordered_map<std::string, Value> entries;
|
||||
|
||||
public:
|
||||
|
||||
Bundle() = default;
|
||||
|
||||
Bundle(const Bundle& bundle) {
|
||||
this->entries = bundle.entries;
|
||||
}
|
||||
|
||||
bool getBool(const std::string& key) const;
|
||||
int32_t getInt32(const std::string& key) const;
|
||||
int64_t getInt64(const std::string& key) const;
|
||||
std::string getString(const std::string& key) const;
|
||||
|
||||
bool hasBool(const std::string& key) const;
|
||||
bool hasInt32(const std::string& key) const;
|
||||
bool hasInt64(const std::string& key) const;
|
||||
bool hasString(const std::string& key) const;
|
||||
|
||||
bool optBool(const std::string& key, bool& out) const;
|
||||
bool optInt32(const std::string& key, int32_t& out) const;
|
||||
bool optInt64(const std::string& key, int64_t& out) const;
|
||||
bool optString(const std::string& key, std::string& out) const;
|
||||
|
||||
void putBool(const std::string& key, bool value);
|
||||
void putInt32(const std::string& key, int32_t value);
|
||||
void putInt64(const std::string& key, int64_t value);
|
||||
void putString(const std::string& key, const std::string& value);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#define TT_STRINGIFY(x) #x
|
||||
|
||||
// region Variable arguments support
|
||||
|
||||
// Adapted from https://stackoverflow.com/a/78848701/3848666
|
||||
#define TT_ARG_IGNORE(X)
|
||||
#define TT_ARG_CAT(X,Y) _TT_ARG_CAT(X,Y)
|
||||
#define _TT_ARG_CAT(X,Y) X ## Y
|
||||
#define TT_ARGCOUNT(...) _TT_ARGCOUNT ## __VA_OPT__(1(__VA_ARGS__) TT_ARG_IGNORE) (0)
|
||||
#define _TT_ARGCOUNT1(X,...) _TT_ARGCOUNT ## __VA_OPT__(2(__VA_ARGS__) TT_ARG_IGNORE) (1)
|
||||
#define _TT_ARGCOUNT2(X,...) _TT_ARGCOUNT ## __VA_OPT__(3(__VA_ARGS__) TT_ARG_IGNORE) (2)
|
||||
#define _TT_ARGCOUNT3(X,...) _TT_ARGCOUNT ## __VA_OPT__(4(__VA_ARGS__) TT_ARG_IGNORE) (3)
|
||||
#define _TT_ARGCOUNT4(X,...) _TT_ARGCOUNT ## __VA_OPT__(5(__VA_ARGS__) TT_ARG_IGNORE) (4)
|
||||
#define _TT_ARGCOUNT5(X,...) 5
|
||||
#define _TT_ARGCOUNT(X) X
|
||||
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define TT_DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define TT_DEPRECATED __declspec(deprecated)
|
||||
#else
|
||||
#pragma message("WARNING: TT_DEPRECATED is not implemented for this compiler")
|
||||
#define TT_DEPRECATED
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/freertoscompat/RTOS.h>
|
||||
|
||||
namespace tt {
|
||||
|
||||
typedef portBASE_TYPE CpuAffinity;
|
||||
|
||||
constexpr static CpuAffinity None = -1;
|
||||
|
||||
/**
|
||||
* Determines the preferred affinity for certain (sub)systems.
|
||||
*/
|
||||
struct CpuAffinityConfiguration {
|
||||
CpuAffinity system;
|
||||
CpuAffinity graphics; // Display, LVGL
|
||||
CpuAffinity wifi;
|
||||
CpuAffinity mainDispatcher;
|
||||
CpuAffinity apps;
|
||||
CpuAffinity timer; // Tactility Timer (based on FreeRTOS)
|
||||
};
|
||||
|
||||
void setCpuAffinityConfiguration(const CpuAffinityConfiguration& config);
|
||||
|
||||
const CpuAffinityConfiguration& getCpuAffinityConfiguration();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
namespace tt::string {
|
||||
|
||||
/**
|
||||
* Given a filesystem path as input, try and get the parent path.
|
||||
* @param[in] path input path
|
||||
* @param[out] output an output buffer that is allocated to at least the size of "current"
|
||||
* @return true when successful
|
||||
*/
|
||||
bool getPathParent(const std::string& path, std::string& output);
|
||||
|
||||
/**
|
||||
* Given a filesystem path as input, get the last segment of a path
|
||||
* @param[in] path input path
|
||||
*/
|
||||
std::string getLastPathSegment(const std::string& path);
|
||||
|
||||
/**
|
||||
* Splits the provided input into separate pieces with delimiter as separator text.
|
||||
* When the input string is empty, the output list will be empty too.
|
||||
*
|
||||
* @param input the input to split up
|
||||
* @param delimiter a non-empty string to recognize as separator
|
||||
*/
|
||||
std::vector<std::string> split(const std::string& input, const std::string& delimiter);
|
||||
|
||||
/**
|
||||
* Splits the provided input into separate pieces with delimiter as separator text.
|
||||
* When the input string is empty, the output list will be empty too.
|
||||
*
|
||||
* @param input the input to split up
|
||||
* @param delimiter a non-empty string to recognize as separator
|
||||
* @param callback the callback function that receives the split parts
|
||||
*/
|
||||
void split(const std::string& input, const std::string& delimiter, std::function<void(const std::string&)> callback);
|
||||
|
||||
/**
|
||||
* Join a set of tokens into a single string, given a delimiter (separator).
|
||||
* If the input is an empty list, the result will be an empty string.
|
||||
* The delimeter is only placed inbetween tokens and not appended at the end of the resulting string.
|
||||
*
|
||||
* @param input the tokens to join together
|
||||
* @param delimiter the separator to join with
|
||||
*/
|
||||
std::string join(const std::vector<std::string>& input, const std::string& delimiter);
|
||||
|
||||
/**
|
||||
* Join a set of tokens into a single string, given a delimiter (separator).
|
||||
* If the input is an empty list, the result will be an empty string.
|
||||
* The delimeter is only placed inbetween tokens and not appended at the end of the resulting string.
|
||||
*
|
||||
* @param input the tokens to join together
|
||||
* @param delimiter the separator to join with
|
||||
*/
|
||||
std::string join(const std::vector<const char*>& input, const std::string& delimiter);
|
||||
|
||||
/**
|
||||
* Returns the lowercase value of a string.
|
||||
* @warning This only works for strings with 1 byte per character
|
||||
* @param[in] the string with lower and/or uppercase characters
|
||||
* @return a string with only lowercase characters
|
||||
*/
|
||||
template <typename T>
|
||||
std::basic_string<T> lowercase(const std::basic_string<T>& input) {
|
||||
std::basic_string<T> output = input;
|
||||
std::transform(
|
||||
output.begin(),
|
||||
output.end(),
|
||||
output.begin(),
|
||||
[](const T character) { return static_cast<T>(std::tolower(character)); }
|
||||
);
|
||||
return std::move(output);
|
||||
}
|
||||
|
||||
/** @return true when input only has hex characters: [a-z], [A-Z], [0-9] */
|
||||
bool isAsciiHexString(const std::string& input);
|
||||
|
||||
/** @return the first part of a file name right up (and excluding) the first period character. */
|
||||
std::string removeFileExtension(const std::string& input);
|
||||
|
||||
/**
|
||||
* Remove the given characters from the start and end of the specified string.
|
||||
* @param[in] input the text to trim
|
||||
* @param[in] characters the characters to remove from the input
|
||||
* @return the input where the specified characters are removed from the start and end of the input string
|
||||
*/
|
||||
std::string trim(const std::string& input, const std::string& characters);
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "CoreDefines.h"
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* All functions in this file can be safely called without manually applying file locks.
|
||||
* For calls to C stdlib APIs such as fopen(), always call file::getLock(path) first!
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Tactility/TactilityCore.h>
|
||||
#include <Tactility/Lock.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @warning SD card access requires a locking mechanism:
|
||||
* @warning When using this in the Tactility main project, use `file::getLock()` or `file::withLock()`
|
||||
*/
|
||||
namespace tt::file {
|
||||
|
||||
/** File types for `dirent`'s `d_type`. */
|
||||
enum {
|
||||
TT_DT_UNKNOWN = 0, // Unknown type
|
||||
TT_DT_FIFO = 1, // Named pipe or FIFO
|
||||
TT_DT_CHR = 2, // Character device
|
||||
TT_DT_DIR = 4, // Directory
|
||||
TT_DT_BLK = 6, // Block device
|
||||
TT_DT_REG = 8, // Regular file
|
||||
TT_DT_LNK = 10, // Symbolic link
|
||||
TT_DT_SOCK = 12, // Local-domain socket
|
||||
TT_DT_WHT = 14 // Whiteout inodes
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
constexpr char SEPARATOR = '\\';
|
||||
#else
|
||||
constexpr char SEPARATOR = '/';
|
||||
#endif
|
||||
|
||||
struct FileCloser {
|
||||
void operator()(FILE* file) {
|
||||
if (file != nullptr) {
|
||||
fclose(file);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::function<std::shared_ptr<Lock>(const std::string&)> FindLockFunction;
|
||||
|
||||
/**
|
||||
* @param[in] path the path to get a lock for
|
||||
* @return a lock instance (never null)
|
||||
*/
|
||||
std::shared_ptr<Lock> getLock(const std::string& path);
|
||||
|
||||
void setFindLockFunction(const FindLockFunction& function);
|
||||
|
||||
long getSize(FILE* file);
|
||||
|
||||
/** Read a file and return its data.
|
||||
* @param[in] filepath the path of the file
|
||||
* @param[out] size the amount of bytes that were read
|
||||
* @return null on error, or an array of bytes in case of success
|
||||
*/
|
||||
std::unique_ptr<uint8_t[]> readBinary(const std::string& filepath, size_t& outSize);
|
||||
|
||||
/** Read a file and return a null-terminated string that represents its content.
|
||||
* @param[in] filepath the path of the file
|
||||
* @return null on error, or an array of bytes in case of success. Empty string returns as a single 0 character.
|
||||
*/
|
||||
std::unique_ptr<uint8_t[]> readString(const std::string& filepath);
|
||||
|
||||
/** Write text to a file
|
||||
* @param[in] path file path to write to
|
||||
* @param[in] content file content to write
|
||||
* @return true when operation is successful
|
||||
*/
|
||||
bool writeString(const std::string& filepath, const std::string& content);
|
||||
|
||||
/** Ensure a directory path exists.
|
||||
* @param[in] path the directory path to find, or to create recursively
|
||||
* @param[in] mode the mode to use when creating directories
|
||||
* @return true when the specified path was found, or otherwise creates the directories recursively with the specified mode.
|
||||
*/
|
||||
bool findOrCreateDirectory(const std::string& path, mode_t mode);
|
||||
|
||||
bool findOrCreateParentDirectory(const std::string& path, mode_t mode);
|
||||
|
||||
bool deleteRecursively(const std::string& path);
|
||||
|
||||
bool deleteFile(const std::string& path);
|
||||
|
||||
bool deleteDirectory(const std::string& path);
|
||||
|
||||
/**
|
||||
* Concatenate a child path with a parent path, ensuring proper slash inbetween
|
||||
* @param basePath an absolute path with or without trailing "/"
|
||||
* @param childPath the name of the child path (e.g. subfolder or file)
|
||||
* @return the concatenated path
|
||||
*/
|
||||
std::string getChildPath(const std::string& basePath, const std::string& childPath);
|
||||
|
||||
/**
|
||||
* Find the last part of the path. This can either be the filename or the deepest folder name.
|
||||
* @param path an absolute or relative path
|
||||
* @return the last segment of the specified path
|
||||
*/
|
||||
std::string getLastPathSegment(const std::string& path);
|
||||
|
||||
/**
|
||||
* Find the first part of the path. This is either the root folder, or a file if the latter has no parent folder.
|
||||
* @param path an absolute or relative path
|
||||
* @return the first segment of the specified path
|
||||
*/
|
||||
std::string getFirstPathSegment(const std::string& path);
|
||||
|
||||
typedef int (*ScandirFilter)(const dirent*);
|
||||
|
||||
typedef bool (*ScandirSort)(const dirent&, const dirent&);
|
||||
|
||||
/** Used for sorting by alphanumeric value and file type */
|
||||
bool direntSortAlphaAndType(const dirent& left, const dirent& right);
|
||||
|
||||
/** A filter for filtering out "." and ".." */
|
||||
int direntFilterDotEntries(const dirent* entry);
|
||||
|
||||
bool isFile(const std::string& path);
|
||||
|
||||
bool isDirectory(const std::string& path);
|
||||
|
||||
/**
|
||||
* A scandir()-like implementation that works on ESP32.
|
||||
* It does not return "." and ".." items but otherwise functions the same.
|
||||
* It returns an allocated output array with allocated dirent instances.
|
||||
* The caller is responsible for free-ing the memory of these.
|
||||
*
|
||||
* @param[in] path path the scan for files and directories
|
||||
* @param[out] onEntry a pointer to a function that accepts an entry
|
||||
* @return true if the directory exists and listing its contents was successful
|
||||
*/
|
||||
bool listDirectory(
|
||||
const std::string& path,
|
||||
std::function<void(const dirent&)> onEntry
|
||||
);
|
||||
|
||||
/**
|
||||
* A scandir()-like implementation that works on ESP32.
|
||||
* It does not return "." and ".." items but otherwise functions the same.
|
||||
* It returns an allocated output array with allocated dirent instances.
|
||||
* The caller is responsible for free-ing the memory of these.
|
||||
*
|
||||
* @param[in] path path the scan for files and directories
|
||||
* @param[out] outList a pointer to vector of dirent
|
||||
* @param[in] filter an optional filter to filter out specific items (nullable)
|
||||
* @param[in] sort an optional sorting function (nullable)
|
||||
* @return the amount of items that were stored in "output" or -1 when an error occurred
|
||||
*/
|
||||
int scandir(
|
||||
const std::string& path,
|
||||
std::vector<dirent>& outList,
|
||||
ScandirFilter filter = nullptr,
|
||||
ScandirSort sort = nullptr
|
||||
);
|
||||
|
||||
bool readLines(const std::string& filePath, bool stripNewLine, std::function<void(const char* line)> callback);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#define CRASH_DATA_CALLSTACK_LIMIT 64
|
||||
#define CRASH_DATA_INCLUDES_SP false
|
||||
|
||||
/** Represents a single frame on the callstack. */
|
||||
struct CallstackFrame {
|
||||
uint32_t pc = 0;
|
||||
#if CRASH_DATA_INCLUDES_SP
|
||||
uint32_t sp = 0;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Callstack-related crash data. */
|
||||
struct CrashData {
|
||||
bool callstackCorrupted = false;
|
||||
uint8_t callstackLength = 0;
|
||||
CallstackFrame callstack[CRASH_DATA_CALLSTACK_LIMIT];
|
||||
};
|
||||
|
||||
/** @return the crash data */
|
||||
const CrashData& getRtcCrashData();
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace tt::kernel {
|
||||
|
||||
/** Recognized platform types */
|
||||
typedef enum {
|
||||
PlatformEsp,
|
||||
PlatformSimulator
|
||||
} Platform;
|
||||
|
||||
/** @return the platform that Tactility currently is running on. */
|
||||
Platform getPlatform();
|
||||
|
||||
} // namespace
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <tactility/drivers/spi_controller.h>
|
||||
#include <tactility/device.h>
|
||||
|
||||
#include <Tactility/Lock.h>
|
||||
|
||||
namespace tt {
|
||||
|
||||
class SpiDeviceLock : public Lock {
|
||||
::Device* device;
|
||||
public:
|
||||
explicit SpiDeviceLock(::Device* device) : device(device) { }
|
||||
|
||||
bool lock(TickType_t timeout) const override {
|
||||
return spi_controller_try_lock(device, timeout) == ERROR_NONE;
|
||||
}
|
||||
|
||||
void unlock() const override {
|
||||
spi_controller_unlock(device);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user