@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#if defined(__has_include)
|
||||
#if __has_include(<stdfloat>)
|
||||
#include <stdfloat>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace std {
|
||||
|
||||
using bool_t = decltype(true);
|
||||
using char_t = decltype('x');
|
||||
using uchar_t = std::uint8_t;
|
||||
|
||||
#if !defined(__STDCPP_FLOAT32_T__)
|
||||
using float32_t = decltype(0.0F);
|
||||
#endif
|
||||
|
||||
#if !defined(__STDCPP_FLOAT64_T__)
|
||||
using float64_t = decltype(0.0);
|
||||
#endif
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef NO_SYS
|
||||
#define NO_SYS 1
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_SOCKET
|
||||
#define LWIP_SOCKET 0
|
||||
#endif
|
||||
|
||||
#define LWIP_NETCONN 0
|
||||
#define MEM_LIBC_MALLOC 0
|
||||
#define MEM_ALIGNMENT 4
|
||||
#define MEM_SIZE 16000
|
||||
#define MEMP_NUM_TCP_SEG 32
|
||||
#define MEMP_NUM_ARP_QUEUE 10
|
||||
#define PBUF_POOL_SIZE 24
|
||||
#define LWIP_ARP 1
|
||||
#define LWIP_ETHERNET 1
|
||||
#define LWIP_ICMP 1
|
||||
#define LWIP_RAW 1
|
||||
#define LWIP_DHCP 1
|
||||
#define LWIP_DNS 1
|
||||
#define LWIP_IPV4 1
|
||||
#define LWIP_TCP 1
|
||||
#define LWIP_UDP 1
|
||||
#define LWIP_TCP_KEEPALIVE 1
|
||||
#define LWIP_NETIF_STATUS_CALLBACK 1
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1
|
||||
#define LWIP_NETIF_HOSTNAME 1
|
||||
#define LWIP_NETIF_TX_SINGLE_PBUF 1
|
||||
#define LWIP_CHKSUM_ALGORITHM 3
|
||||
#define DHCP_DOES_ARP_CHECK 0
|
||||
#define LWIP_DHCP_DOES_ACD_CHECK 0
|
||||
|
||||
#define TCP_MSS 1460
|
||||
#define TCP_WND (8 * TCP_MSS)
|
||||
#define TCP_SND_BUF (8 * TCP_MSS)
|
||||
#define TCP_SND_QUEUELEN ((4 * TCP_SND_BUF + TCP_MSS - 1) / TCP_MSS)
|
||||
|
||||
#define MEM_STATS 0
|
||||
#define SYS_STATS 0
|
||||
#define MEMP_STATS 0
|
||||
#define LINK_STATS 0
|
||||
|
||||
#define ETHARP_DEBUG LWIP_DBG_OFF
|
||||
#define NETIF_DEBUG LWIP_DBG_OFF
|
||||
#define PBUF_DEBUG LWIP_DBG_OFF
|
||||
#define API_LIB_DEBUG LWIP_DBG_OFF
|
||||
#define API_MSG_DEBUG LWIP_DBG_OFF
|
||||
#define SOCKETS_DEBUG LWIP_DBG_OFF
|
||||
#define ICMP_DEBUG LWIP_DBG_OFF
|
||||
#define INET_DEBUG LWIP_DBG_OFF
|
||||
#define IP_DEBUG LWIP_DBG_OFF
|
||||
#define IP_REASS_DEBUG LWIP_DBG_OFF
|
||||
#define RAW_DEBUG LWIP_DBG_OFF
|
||||
#define MEM_DEBUG LWIP_DBG_OFF
|
||||
#define MEMP_DEBUG LWIP_DBG_OFF
|
||||
#define SYS_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_RTO_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_CWND_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_WND_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_FR_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
|
||||
#define TCP_RST_DEBUG LWIP_DBG_OFF
|
||||
#define UDP_DEBUG LWIP_DBG_OFF
|
||||
#define TCPIP_DEBUG LWIP_DBG_OFF
|
||||
#define PPP_DEBUG LWIP_DBG_OFF
|
||||
#define SLIP_DEBUG LWIP_DBG_OFF
|
||||
#define DHCP_DEBUG LWIP_DBG_OFF
|
||||
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
#include <types.hpp>
|
||||
#include <vamp_style.hpp>
|
||||
|
||||
namespace vamp_pico {
|
||||
|
||||
constexpr auto display_width = std::int32_t{320};
|
||||
constexpr auto display_height = std::int32_t{240};
|
||||
|
||||
constexpr auto color_black = std::uint16_t{0x0000};
|
||||
constexpr auto color_white = std::uint16_t{0xffff};
|
||||
constexpr auto color_gray = std::uint16_t{0x8410};
|
||||
|
||||
class display {
|
||||
public:
|
||||
auto init() -> void;
|
||||
auto fill(std::uint16_t color) -> void;
|
||||
auto fill_rect(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height, std::uint16_t color) -> void;
|
||||
auto draw_text(std::int32_t x, std::int32_t y, std::char_t const* text, std::uint16_t color, std::int32_t scale = 2) -> void;
|
||||
auto show_boot(std::char_t const* line1, std::char_t const* line2, std::uint16_t accent) -> void;
|
||||
auto show_remote(vamp_style::color status, std::char_t const* title, std::char_t const* part, std::uint32_t page, std::uint32_t pages, std::bool_t active) -> void;
|
||||
private:
|
||||
std::bool_t remote_valid_{};
|
||||
vamp_style::color last_status_{};
|
||||
std::bool_t last_active_{};
|
||||
std::array<std::char_t, 96> last_title_{};
|
||||
std::array<std::char_t, 48> last_part_{};
|
||||
std::uint32_t last_page_{};
|
||||
std::uint32_t last_pages_{};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <vamp_protocol/page_control.hpp>
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_pico {
|
||||
|
||||
struct remote_display_state {
|
||||
std::bool_t active{};
|
||||
std::char_t title[96]{};
|
||||
std::char_t part[48]{};
|
||||
std::char_t mode[24]{};
|
||||
std::uint32_t page{};
|
||||
std::uint32_t pages{};
|
||||
};
|
||||
|
||||
auto post_remote_command(vamp_protocol::page_command command, vamp_pico::remote_display_state& state) -> std::bool_t;
|
||||
auto heartbeat() -> std::bool_t;
|
||||
auto fetch_remote_display(vamp_pico::remote_display_state& state) -> std::bool_t;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_pico {
|
||||
|
||||
struct touch_point {
|
||||
std::int32_t x{};
|
||||
std::int32_t y{};
|
||||
};
|
||||
|
||||
class touch_controller {
|
||||
public:
|
||||
auto init() -> void;
|
||||
auto read(touch_point& point) -> std::bool_t;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_protocol {
|
||||
|
||||
constexpr std::char_t root_path[] = "/";
|
||||
constexpr std::char_t status_path[] = "/api/status";
|
||||
constexpr std::char_t next_page_path[] = "/api/page/next";
|
||||
constexpr std::char_t previous_page_path[] = "/api/page/previous";
|
||||
constexpr std::char_t remote_next_path[] = "/api/remote/next";
|
||||
constexpr std::char_t remote_previous_path[] = "/api/remote/previous";
|
||||
constexpr std::char_t remote_select_path[] = "/api/remote/select";
|
||||
constexpr std::char_t remote_heartbeat_path[] = "/api/remote/heartbeat";
|
||||
constexpr std::char_t remote_display_path[] = "/api/remote/display";
|
||||
|
||||
enum class page_command {
|
||||
PREVIOUS,
|
||||
NEXT,
|
||||
SELECT,
|
||||
};
|
||||
|
||||
auto page_command_path(vamp_protocol::page_command command) -> std::char_t const*;
|
||||
auto page_command_legacy_path(vamp_protocol::page_command command) -> std::char_t const*;
|
||||
auto page_command_name(vamp_protocol::page_command command) -> std::char_t const*;
|
||||
auto page_command_display_label(vamp_protocol::page_command command) -> std::char_t const*;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_style {
|
||||
|
||||
struct color {
|
||||
std::uint8_t r{};
|
||||
std::uint8_t g{};
|
||||
std::uint8_t b{};
|
||||
std::uint8_t a{255};
|
||||
};
|
||||
|
||||
constexpr auto background = vamp_style::color{9, 12, 14, 255};
|
||||
constexpr auto panel = vamp_style::color{21, 27, 30, 255};
|
||||
constexpr auto ink = vamp_style::color{238, 244, 241, 255};
|
||||
constexpr auto muted = vamp_style::color{137, 151, 149, 255};
|
||||
constexpr auto rule = vamp_style::color{66, 78, 78, 255};
|
||||
constexpr auto paper = vamp_style::color{2, 3, 3, 255};
|
||||
constexpr auto paper_ink = vamp_style::color{246, 248, 244, 255};
|
||||
constexpr auto accent = vamp_style::color{232, 190, 70, 255};
|
||||
constexpr auto selection = vamp_style::color{41, 100, 111, 255};
|
||||
constexpr auto connecting = vamp_style::color{45, 111, 185, 255};
|
||||
constexpr auto retrying = vamp_style::color{229, 171, 37, 255};
|
||||
constexpr auto connected = vamp_style::color{40, 170, 88, 255};
|
||||
constexpr auto danger = vamp_style::color{190, 63, 58, 255};
|
||||
|
||||
auto rgb565(vamp_style::color value) -> std::uint16_t;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string_view>
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_style {
|
||||
|
||||
constexpr auto ui_font_path = std::string_view{"/usr/share/product-vamp/fonts/petaluma/PetalumaScript.otf"};
|
||||
constexpr auto score_text_font_path = std::string_view{"/usr/share/product-vamp/fonts/petaluma/PetalumaScript.otf"};
|
||||
constexpr auto score_music_font_path = std::string_view{"/usr/share/product-vamp/fonts/petaluma/Petaluma.otf"};
|
||||
constexpr auto ui_font_height = std::int32_t{36};
|
||||
constexpr auto ui_font_max_width = std::int32_t{28};
|
||||
|
||||
struct font_glyph {
|
||||
std::array<std::uint8_t, ui_font_height * ui_font_max_width> alpha{};
|
||||
std::uint8_t width{};
|
||||
std::uint8_t advance{};
|
||||
};
|
||||
|
||||
auto ui_font_glyph(std::char_t value) -> vamp_style::font_glyph;
|
||||
auto ui_font_pair_adjust(std::char_t left, std::char_t right) -> std::int32_t;
|
||||
auto ui_text_width(std::string_view text, std::int32_t scale) -> std::int32_t;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <modulus.hpp>
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
struct command_line {
|
||||
std::string config_path{"/etc/product-vamp/vamp.json"};
|
||||
std::bool_t check_config{};
|
||||
std::bool_t health_check{};
|
||||
std::bool_t print_version{};
|
||||
std::bool_t exit_after_startup{};
|
||||
std::bool_t migrate{};
|
||||
};
|
||||
|
||||
auto parse_command_line(std::int32_t argc, std::char_t** argv) -> std::expected<vamp_zero::command_line, modulus::error>;
|
||||
auto run(vamp_zero::command_line command) -> std::expected<void, modulus::error>;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <luma.hpp>
|
||||
|
||||
#include <vamp_style.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
auto to_luma(vamp_style::color value) -> luma::color;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <boost/json/value.hpp>
|
||||
|
||||
#include <ligo.hpp>
|
||||
#include <luma.hpp>
|
||||
#include <modulus.hpp>
|
||||
|
||||
#include <types.hpp>
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
struct runtime_config {
|
||||
vamp_zero::hardware_mode hardware{vamp_zero::hardware_mode::REAL};
|
||||
std::bool_t headless{false};
|
||||
std::bool_t exit_after_startup{false};
|
||||
std::string assets_path{"/usr/share/product-vamp"};
|
||||
std::string heartbeat_path{"/run/product-vamp/heartbeat.json"};
|
||||
};
|
||||
|
||||
struct database_config {
|
||||
std::string path{"/var/lib/product-vamp/vamp.db"};
|
||||
std::string migrations_path{"/usr/share/product-vamp/migrations"};
|
||||
};
|
||||
|
||||
struct control_config {
|
||||
ligo::endpoint_config endpoint{
|
||||
.name = "product-vamp-control",
|
||||
.protocol = ligo::protocol::HTTP,
|
||||
.bind = "0.0.0.0:8080",
|
||||
.timeout = std::chrono::milliseconds{5000},
|
||||
.http = {
|
||||
.max_body_size = 64U * 1024U,
|
||||
},
|
||||
};
|
||||
std::string ap_ssid{"Vamp Control"};
|
||||
std::string ap_passphrase{"vamp-control"};
|
||||
std::string ap_interface{"wlan0"};
|
||||
std::string zero_ip{"192.168.42.1"};
|
||||
std::string zero_cidr{"192.168.42.1/24"};
|
||||
};
|
||||
|
||||
struct config {
|
||||
modulus::config modulus{};
|
||||
vamp_zero::runtime_config runtime{};
|
||||
vamp_zero::database_config database{};
|
||||
vamp_zero::control_config control{};
|
||||
luma::application_config display{.title = "Product Vamp"};
|
||||
};
|
||||
|
||||
auto parse_config(boost::json::value const& value) -> std::expected<vamp_zero::config, modulus::error>;
|
||||
auto load_config(std::string const& path) -> std::expected<vamp_zero::config, modulus::error>;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/asio/any_io_executor.hpp>
|
||||
#include <boost/asio/awaitable.hpp>
|
||||
|
||||
#include <modulus.hpp>
|
||||
|
||||
#include <vamp_zero/config.hpp>
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
auto async_migrate_database(boost::asio::any_io_executor executor, vamp_zero::database_config config) -> boost::asio::awaitable<std::expected<void, modulus::error>>;
|
||||
auto async_import_catalogs(boost::asio::any_io_executor executor, vamp_zero::database_config config, std::string assets_path) -> boost::asio::awaitable<std::expected<void, modulus::error>>;
|
||||
auto async_load_performance_library(boost::asio::any_io_executor executor, vamp_zero::database_config config) -> boost::asio::awaitable<std::expected<vamp_zero::library_state, modulus::error>>;
|
||||
auto async_load_practice_library(boost::asio::any_io_executor executor, vamp_zero::database_config config) -> boost::asio::awaitable<std::expected<vamp_zero::practice_library, modulus::error>>;
|
||||
auto split_migration_statements(std::string const& input) -> std::expected<std::vector<std::string>, modulus::error>;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <modulus.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
enum class error_code : std::int32_t {
|
||||
OK = 0,
|
||||
INVALID_ARGUMENT = 1,
|
||||
NOT_FOUND = 2,
|
||||
UNAVAILABLE = 3,
|
||||
PERSISTENCE = 4,
|
||||
CONFLICT = 5,
|
||||
INTERNAL = 6,
|
||||
};
|
||||
|
||||
auto make_error(vamp_zero::error_code code, std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> modulus::error;
|
||||
auto fail_void(vamp_zero::error_code code, std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> std::expected<void, modulus::error>;
|
||||
|
||||
template <typename VALUE>
|
||||
auto fail(vamp_zero::error_code code, std::string message, modulus::source_location location = modulus::source_location(__builtin_FILE(), __builtin_LINE(), __builtin_FUNCTION())) -> std::expected<VALUE, modulus::error>;
|
||||
|
||||
}
|
||||
|
||||
template <typename VALUE>
|
||||
auto vamp_zero::fail(vamp_zero::error_code code, std::string message, modulus::source_location location) -> std::expected<VALUE, modulus::error> {
|
||||
return modulus::fail<VALUE>(vamp_zero::make_error(code, std::move(message), location));
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <modulus.hpp>
|
||||
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
auto parse_score_document(std::string_view json, std::string source_path = {}) -> std::expected<vamp_zero::score_document, modulus::error>;
|
||||
auto load_performance_library(std::string const& assets_path) -> std::expected<vamp_zero::library_state, modulus::error>;
|
||||
auto load_practice_library(std::string const& assets_path) -> std::expected<vamp_zero::practice_library, modulus::error>;
|
||||
auto group_library_parts(std::vector<vamp_zero::library_part> parts) -> vamp_zero::library_state;
|
||||
auto group_practice_exercises(std::vector<vamp_zero::practice_exercise> exercises) -> vamp_zero::practice_library;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <string>
|
||||
|
||||
#include <boost/json/value.hpp>
|
||||
|
||||
#include <modulus.hpp>
|
||||
|
||||
#include <vamp_protocol/page_control.hpp>
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
auto apply_app_command(vamp_zero::app_state state, vamp_protocol::page_command command) -> vamp_zero::app_state;
|
||||
auto app_status_json(vamp_zero::app_state const& state) -> boost::json::value;
|
||||
auto remote_display_text(vamp_zero::app_state const& state) -> std::string;
|
||||
auto validate_app_state(vamp_zero::app_state const& state) -> std::expected<void, modulus::error>;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
|
||||
#include <boost/json/value.hpp>
|
||||
|
||||
#include <ligo.hpp>
|
||||
|
||||
#include <vamp_protocol/page_control.hpp>
|
||||
#include <vamp_zero/config.hpp>
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
class control_state {
|
||||
public:
|
||||
using observer = std::function<void(vamp_zero::app_state)>;
|
||||
|
||||
control_state(vamp_zero::config config, vamp_zero::app_state state);
|
||||
auto config() const -> vamp_zero::config;
|
||||
auto snapshot() const -> vamp_zero::app_state;
|
||||
auto apply(vamp_protocol::page_command command) -> vamp_zero::app_state;
|
||||
auto heartbeat() -> vamp_zero::app_state;
|
||||
auto refresh_connection() -> std::optional<vamp_zero::app_state>;
|
||||
auto set_observer(vamp_zero::control_state::observer observer) -> void;
|
||||
private:
|
||||
auto pico_connected_locked() const -> std::bool_t;
|
||||
auto snapshot_locked() const -> vamp_zero::app_state;
|
||||
mutable std::mutex mutex_{};
|
||||
vamp_zero::config config_{};
|
||||
vamp_zero::app_state state_{};
|
||||
std::chrono::steady_clock::time_point last_heartbeat_{};
|
||||
vamp_zero::control_state::observer observer_{};
|
||||
};
|
||||
|
||||
auto make_router(vamp_zero::control_state& state) -> ligo::service_router;
|
||||
auto portal_status_json(vamp_zero::config const& config, vamp_zero::app_state const& state) -> boost::json::value;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <luma.hpp>
|
||||
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
constexpr auto score_measures_per_system = std::size_t{4};
|
||||
constexpr auto score_systems_per_page = std::size_t{3};
|
||||
constexpr auto score_measures_per_page = score_measures_per_system * score_systems_per_page;
|
||||
|
||||
auto draw_score_page(luma::draw_context& context, luma::rect bounds, vamp_zero::score_document const& score, std::size_t page_index) -> void;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
enum class hardware_mode {
|
||||
FAKE,
|
||||
REAL,
|
||||
};
|
||||
|
||||
struct score_pitch {
|
||||
std::char_t letter{'c'};
|
||||
std::int32_t octave{};
|
||||
std::string accidental{};
|
||||
};
|
||||
|
||||
struct score_note {
|
||||
std::string id{};
|
||||
std::string kind{};
|
||||
std::bool_t hidden{};
|
||||
std::int64_t duration_ticks{};
|
||||
std::int64_t display_ticks{};
|
||||
std::string notehead{};
|
||||
std::string chord_symbol{};
|
||||
std::string lyric{};
|
||||
std::bool_t tie_to_next{};
|
||||
std::bool_t tie_from_previous{};
|
||||
std::vector<vamp_zero::score_pitch> pitches{};
|
||||
};
|
||||
|
||||
struct score_measure {
|
||||
std::string id{};
|
||||
std::string section_label{};
|
||||
std::string time_signature{};
|
||||
std::string key_signature{};
|
||||
std::vector<vamp_zero::score_note> notes{};
|
||||
};
|
||||
|
||||
struct score_document {
|
||||
std::string id{};
|
||||
std::string title{};
|
||||
std::string composer{};
|
||||
std::string key_signature{};
|
||||
std::string part{};
|
||||
std::string arrangement_part_type{};
|
||||
std::string source_path{};
|
||||
std::string source_json{};
|
||||
std::vector<vamp_zero::score_measure> measures{};
|
||||
};
|
||||
|
||||
struct library_part {
|
||||
std::string id{};
|
||||
std::string title{};
|
||||
std::string composer{};
|
||||
std::string key_signature{};
|
||||
std::string part{};
|
||||
std::string source_path{};
|
||||
std::string source_json{};
|
||||
std::size_t measure_count{};
|
||||
std::size_t total_pages{};
|
||||
};
|
||||
|
||||
struct song_group {
|
||||
std::string title{};
|
||||
std::string composer{};
|
||||
std::vector<vamp_zero::library_part> parts{};
|
||||
};
|
||||
|
||||
struct library_state {
|
||||
std::vector<vamp_zero::library_part> parts{};
|
||||
std::vector<vamp_zero::song_group> groups{};
|
||||
};
|
||||
|
||||
struct practice_exercise {
|
||||
struct score_variant {
|
||||
std::string id{};
|
||||
std::string key_signature{};
|
||||
std::string source_path{};
|
||||
std::string source_json{};
|
||||
std::size_t measure_count{};
|
||||
std::size_t total_pages{};
|
||||
};
|
||||
|
||||
std::string id{};
|
||||
std::string practice_type_id{};
|
||||
std::string practice_type_title{};
|
||||
std::string lesson_group_id{};
|
||||
std::string lesson_group_title{};
|
||||
std::string title{};
|
||||
std::string composer{};
|
||||
std::string key_signature{};
|
||||
std::string source_path{};
|
||||
std::string source_json{};
|
||||
std::size_t measure_count{};
|
||||
std::size_t total_pages{};
|
||||
std::vector<vamp_zero::practice_exercise::score_variant> variants{};
|
||||
};
|
||||
|
||||
struct practice_lesson_group {
|
||||
std::string id{};
|
||||
std::string title{};
|
||||
std::vector<vamp_zero::practice_exercise> exercises{};
|
||||
};
|
||||
|
||||
struct practice_type_group {
|
||||
std::string id{};
|
||||
std::string title{};
|
||||
std::vector<vamp_zero::practice_lesson_group> lesson_groups{};
|
||||
};
|
||||
|
||||
struct practice_library {
|
||||
std::vector<vamp_zero::practice_exercise> exercises{};
|
||||
std::vector<vamp_zero::practice_type_group> types{};
|
||||
};
|
||||
|
||||
enum class app_mode {
|
||||
MAIN_MENU,
|
||||
PERFORMANCE_SONG_MENU,
|
||||
PERFORMANCE_PART_MENU,
|
||||
PERFORMANCE_SCORE,
|
||||
PRACTICE_TYPE_MENU,
|
||||
PRACTICE_LESSON_MENU,
|
||||
PRACTICE_EXERCISE_MENU,
|
||||
PRACTICE_KEY_MENU,
|
||||
PRACTICE_SCORE,
|
||||
};
|
||||
|
||||
struct app_state {
|
||||
vamp_zero::library_state performance{};
|
||||
vamp_zero::practice_library practice{};
|
||||
vamp_zero::app_mode mode{vamp_zero::app_mode::MAIN_MENU};
|
||||
std::size_t selected_main_menu_index{};
|
||||
std::size_t selected_song_index{};
|
||||
std::size_t selected_part_index{};
|
||||
std::size_t selected_practice_type_index{};
|
||||
std::size_t selected_practice_lesson_index{};
|
||||
std::size_t selected_practice_exercise_index{};
|
||||
std::size_t selected_practice_key_index{};
|
||||
std::string active_part_id{};
|
||||
std::string active_practice_id{};
|
||||
std::size_t page_index{};
|
||||
std::uint64_t next_count{};
|
||||
std::uint64_t previous_count{};
|
||||
std::uint64_t select_count{};
|
||||
std::uint64_t heartbeat_count{};
|
||||
std::string last_command{"startup"};
|
||||
std::bool_t pico_connected{false};
|
||||
};
|
||||
|
||||
auto to_string(vamp_zero::hardware_mode value) -> std::string;
|
||||
auto to_string(vamp_zero::app_mode value) -> std::string;
|
||||
auto practice_key_names() -> std::vector<std::string_view> const&;
|
||||
auto practice_type_supports_key_selection(std::string_view practice_type_id) -> std::bool_t;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include <expected>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include <boost/asio/any_io_executor.hpp>
|
||||
|
||||
#include <luma.hpp>
|
||||
#include <modulus.hpp>
|
||||
|
||||
#include <vamp_zero/config.hpp>
|
||||
#include <vamp_zero/types.hpp>
|
||||
|
||||
namespace vamp_zero {
|
||||
|
||||
struct ui_state {
|
||||
vamp_zero::app_state app{};
|
||||
std::string ap_ssid{};
|
||||
std::string zero_ip{};
|
||||
std::uint16_t port{8080};
|
||||
};
|
||||
|
||||
class zero_ui {
|
||||
public:
|
||||
zero_ui(boost::asio::any_io_executor executor, luma::application_config config);
|
||||
auto run() -> std::expected<void, modulus::error>;
|
||||
auto stop() -> void;
|
||||
auto publish(vamp_zero::ui_state state) -> std::expected<void, modulus::error>;
|
||||
auto snapshot() const -> vamp_zero::ui_state;
|
||||
private:
|
||||
auto make_root(vamp_zero::ui_state const& state) -> std::expected<std::unique_ptr<luma::control>, modulus::error>;
|
||||
boost::asio::any_io_executor executor_;
|
||||
luma::application application_;
|
||||
mutable std::mutex mutex_{};
|
||||
vamp_zero::ui_state state_{};
|
||||
};
|
||||
|
||||
auto make_ui_state(vamp_zero::config const& config, vamp_zero::app_state app) -> vamp_zero::ui_state;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user