@@ -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({
|
||||
|
||||
@@ -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({
|
||||
|
||||
+92
-910
File diff suppressed because it is too large
Load Diff
+70
-2767
File diff suppressed because it is too large
Load Diff
+39
-41
@@ -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_) {
|
||||
|
||||
Reference in New Issue
Block a user