Music Notation
ci / checks (push) Successful in 43m19s

This commit is contained in:
khodowany
2026-09-15 01:30:42 -05:00
parent fe42d811fa
commit 1d1bd3e871
41 changed files with 1546 additions and 5236 deletions
+2 -2
View File
@@ -496,7 +496,7 @@ auto vamp_zero::async_load_performance_library(boost::asio::any_io_executor exec
.part = text_value(row[3]),
.source_path = text_value(row[4]),
.source_json = std::move(source_json),
.measure_count = parsed->measures.size(),
.measure_count = parsed->measure_count,
.total_pages = vamp_zero::score_page_count(*parsed),
});
}
@@ -547,7 +547,7 @@ auto vamp_zero::async_load_practice_library(boost::asio::any_io_executor executo
.key_signature = key_signature,
.source_path = source_path,
.source_json = source_json,
.measure_count = parsed->measures.size(),
.measure_count = parsed->measure_count,
.total_pages = vamp_zero::score_page_count(*parsed),
};
exercises.push_back({
+2 -2
View File
@@ -240,7 +240,7 @@ auto vamp_zero::load_performance_library(std::string const &assets_path) -> std:
.part = document.part,
.source_path = document.source_path,
.source_json = std::move(document.source_json),
.measure_count = document.measures.size(),
.measure_count = document.measure_count,
.total_pages = vamp_zero::score_page_count(document),
});
}
@@ -303,7 +303,7 @@ auto vamp_zero::load_practice_library(std::string const &assets_path) -> std::ex
.key_signature = key,
.source_path = document->source_path,
.source_json = document->source_json,
.measure_count = document->measures.size(),
.measure_count = document->measure_count,
.total_pages = vamp_zero::score_page_count(*document),
};
exercises.push_back({
File diff suppressed because it is too large Load Diff
+70 -2767
View File
File diff suppressed because it is too large Load Diff
+39 -41
View File
@@ -9,7 +9,6 @@
#include <optional>
#include <string>
#include <string_view>
#include <unordered_map>
#include <utility>
#include <boost/asio/any_io_executor.hpp>
@@ -20,6 +19,7 @@
#include <vamp_style.hpp>
#include <vamp_style/font.hpp>
#include <vamp_zero/color.hpp>
#include <vamp_zero/errors.hpp>
#include <vamp_zero/library.hpp>
#include <vamp_zero/navigation.hpp>
#include <vamp_zero/parse.hpp>
@@ -27,49 +27,46 @@
struct vamp_zero::score_draw_cache {
struct entry {
std::string source_json{};
std::shared_ptr<vamp_zero::score_document const> document{};
};
auto get(std::string_view source_json, std::string source_path, std::string part_override) -> std::expected<std::shared_ptr<vamp_zero::score_document const>, modulus::error> {
auto key = source_path;
key.push_back('\n');
key += part_override;
key.push_back('\n');
key += std::to_string(source_json.size());
key.push_back('\n');
key += std::to_string(std::hash<std::string_view>{}(source_json));
auto found = entries.find(key);
if (found != entries.end() && found->second.source_json == source_json && found->second.document) {
return found->second.document;
explicit score_draw_cache(luma::application &application)
: textures{[this, &application](std::string const &name) -> std::expected<std::shared_ptr<luma::texture>, modulus::error> {
auto found = std::find_if(document->pages.begin(), document->pages.end(), [&](auto const &page) { return page.path == name; });
auto path = vamp_zero::validated_page_path(*document, static_cast<std::size_t>(std::distance(document->pages.begin(), found)));
if (!path) {
return std::unexpected(path.error());
}
return application.load_texture_uncached(*path);
}} {}
auto get(std::string_view source_json, std::string source_path) -> std::expected<std::shared_ptr<vamp_zero::score_document const>, modulus::error> {
if (document && document->source_path == source_path && document->source_json == source_json) {
return document;
}
auto parsed = vamp_zero::parse_score_document(source_json, source_path);
auto parsed = vamp_zero::parse_score_document(source_json, std::move(source_path));
if (!parsed) {
return std::unexpected(parsed.error());
}
if (!part_override.empty()) {
parsed->part = std::move(part_override);
}
auto document = std::make_shared<vamp_zero::score_document const>(std::move(*parsed));
entries[key] = {
.source_json = std::string{source_json},
.document = document,
};
textures.clear();
document = std::make_shared<vamp_zero::score_document const>(std::move(*parsed));
return document;
}
std::unordered_map<std::string, entry> entries{};
std::shared_ptr<vamp_zero::score_document const> page_document{};
std::size_t page_index{};
std::optional<vamp_zero::score_page_layout> page{};
auto draw(luma::draw_context &context, luma::rect bounds, std::shared_ptr<vamp_zero::score_document const> document, std::size_t index) -> void {
if (!page || page_document != document || index != page_index || page->bounds.x != bounds.x ||
page->bounds.y != bounds.y || page->bounds.width != bounds.width || page->bounds.height != bounds.height) {
page = vamp_zero::layout_score_page(bounds, *document, index);
page_document = std::move(document);
page_index = index;
auto draw(luma::draw_context &context, luma::rect bounds, std::size_t index) -> std::expected<void, modulus::error> {
if (!document || index >= document->pages.size()) {
return std::unexpected(vamp_zero::make_error(vamp_zero::error_code::INVALID_ARGUMENT, "page index outside score"));
}
vamp_zero::draw_score_layout(context, *page);
auto texture = textures.get(document->pages[index].path);
if (!texture) {
return std::unexpected(texture.error());
}
auto scale = std::min(bounds.width / 976.0F, bounds.height / 484.0F);
auto page = luma::rect{.x = bounds.x + (bounds.width - 976.0F * scale) / 2.0F,
.y = bounds.y + (bounds.height - 484.0F * scale) / 2.0F,
.width = 976.0F * scale,
.height = 484.0F * scale};
context.fill_rect(page, {.r = 255, .g = 255, .b = 255, .a = 255});
context.draw_texture(**texture, {.x = 0, .y = 0, .width = 976, .height = 484}, page, {.r = 255, .g = 255, .b = 255, .a = 255});
return {};
}
vamp_zero::score_page_cache textures;
std::shared_ptr<vamp_zero::score_document const> document{};
};
namespace {
@@ -448,7 +445,6 @@ auto draw_practice_key_menu(luma::draw_context &context, luma::rect bounds, vamp
auto draw_score(luma::draw_context &context, luma::rect bounds, vamp_zero::app_state const &state, vamp_zero::score_draw_cache &score_cache) -> void {
auto source_json = std::string_view{};
auto source_path = std::string{};
auto part_override = std::string{};
if (state.mode == vamp_zero::app_mode::PERFORMANCE_SCORE) {
auto const *part = active_part(state);
if (part == nullptr) {
@@ -470,9 +466,8 @@ auto draw_score(luma::draw_context &context, luma::rect bounds, vamp_zero::app_s
}
source_json = variant->source_json;
source_path = variant->source_path;
part_override = "Key: " + effective_practice_key(state, *exercise);
}
auto parsed = score_cache.get(source_json, source_path, std::move(part_override));
auto parsed = score_cache.get(source_json, source_path);
if (!parsed) {
draw_text(context, bounds.x + 36.0F, bounds.y + 38.0F, "SCORE ERROR", 4, vamp_style::danger, 360.0F);
draw_text(context, bounds.x + 38.0F, bounds.y + 86.0F, parsed.error().describe(), 1, vamp_style::muted, bounds.width - 72.0F);
@@ -484,7 +479,10 @@ auto draw_score(luma::draw_context &context, luma::rect bounds, vamp_zero::app_s
.width = bounds.width - 48.0F,
.height = bounds.height - 36.0F,
};
score_cache.draw(context, paper_bounds, *parsed, state.page_index);
if (auto status = score_cache.draw(context, paper_bounds, state.page_index); !status) {
draw_text(context, bounds.x + 36.0F, bounds.y + 38.0F, "SCORE PAGE ERROR", 3, vamp_style::danger, bounds.width - 72.0F);
draw_text(context, bounds.x + 38.0F, bounds.y + 86.0F, status.error().describe(), 1, vamp_style::muted, bounds.width - 72.0F);
}
}
class vamp_root_control final : public luma::control {
@@ -540,7 +538,7 @@ private:
vamp_zero::zero_ui::zero_ui(boost::asio::any_io_executor executor, luma::application_config config, std::function<void(vamp_protocol::page_command)> command_handler)
: executor_{std::move(executor)}, tap_timer_{executor_}, application_{std::move(config)},
command_handler_{std::move(command_handler)}, score_cache_{std::make_shared<vamp_zero::score_draw_cache>()} {}
command_handler_{std::move(command_handler)}, score_cache_{std::make_shared<vamp_zero::score_draw_cache>(application_)} {}
auto vamp_zero::zero_ui::send_touch_command(vamp_protocol::page_command command) -> void {
if (!command_handler_) {