Refactored storage of credits data
* Replaced use of a config with data structs.
* Moved [about] sorting to the parsing stage instead of handling it in the End Credits dialog.
This improves on my refactoring work here from 2016 (476027f239
).
This commit is contained in:
parent
1a3a28c59c
commit
ec34ed950d
3 changed files with 135 additions and 79 deletions
138
src/about.cpp
138
src/about.cpp
|
@ -15,6 +15,7 @@
|
|||
#include "about.hpp"
|
||||
|
||||
#include "config.hpp"
|
||||
#include "gettext.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
|
||||
#include <map>
|
||||
|
@ -25,26 +26,13 @@
|
|||
*/
|
||||
namespace about
|
||||
{
|
||||
|
||||
static config about_list;
|
||||
static std::map<std::string, std::vector<std::string>> images;
|
||||
static std::vector<std::string> images_default;
|
||||
|
||||
const config& get_about_config()
|
||||
namespace
|
||||
{
|
||||
return about_list;
|
||||
}
|
||||
credits_data parsed_credits_data;
|
||||
std::map<std::string, std::vector<std::string>> images_campaigns;
|
||||
std::vector<std::string> images_general;
|
||||
|
||||
std::vector<std::string> get_background_images(const std::string& campaign)
|
||||
{
|
||||
if(!campaign.empty() && !images[campaign].empty()){
|
||||
return images[campaign];
|
||||
}
|
||||
|
||||
return images_default;
|
||||
}
|
||||
|
||||
static void gather_images(const config& from, std::vector<std::string>& to)
|
||||
void gather_images(const config& from, std::vector<std::string>& to)
|
||||
{
|
||||
const auto& im = utils::parenthetical_split(from["images"], ',');
|
||||
if(!im.empty()) {
|
||||
|
@ -52,50 +40,110 @@ static void gather_images(const config& from, std::vector<std::string>& to)
|
|||
}
|
||||
}
|
||||
|
||||
void set_about(const config &cfg)
|
||||
} // end anon namespace
|
||||
|
||||
credits_group::credits_group(const config& cfg, bool is_campaign_credits)
|
||||
: sections()
|
||||
, id()
|
||||
, header()
|
||||
{
|
||||
about_list.clear();
|
||||
if(is_campaign_credits) {
|
||||
id = cfg["id"].str();
|
||||
header = cfg["name"].t_str();
|
||||
}
|
||||
|
||||
images.clear();
|
||||
images_default.clear();
|
||||
sections.reserve(cfg.child_count("about"));
|
||||
|
||||
for(const config& group : cfg.child_range("credits_group")) {
|
||||
if(!group.has_child("about")) {
|
||||
for(const config& about : cfg.child_range("about")) {
|
||||
if(!about.has_child("entry")) {
|
||||
continue;
|
||||
}
|
||||
about_list.add_child("credits_group", group);
|
||||
gather_images(group, images_default);
|
||||
for(const config& about : group.child_range("about")) {
|
||||
gather_images(about, images_default);
|
||||
|
||||
sections.emplace_back(about);
|
||||
|
||||
if(is_campaign_credits) {
|
||||
gather_images(about, images_campaigns[id]);
|
||||
} else {
|
||||
gather_images(about, images_general);
|
||||
}
|
||||
}
|
||||
|
||||
if(cfg["sort"].to_bool(false)) {
|
||||
std::sort(sections.begin(), sections.end());
|
||||
}
|
||||
}
|
||||
|
||||
credits_group::about_group::about_group(const config& cfg)
|
||||
: names()
|
||||
, title(cfg["title"].t_str())
|
||||
{
|
||||
names.reserve(cfg.child_count("entry"));
|
||||
|
||||
for(const config& entry : cfg.child_range("entry")) {
|
||||
names.push_back(entry["name"].str());
|
||||
}
|
||||
}
|
||||
|
||||
bool credits_group::about_group::operator<(const about_group& o)
|
||||
{
|
||||
return translation::compare(title.str(), o.title.str()) < 0;
|
||||
}
|
||||
|
||||
const credits_data& get_credits_data()
|
||||
{
|
||||
return parsed_credits_data;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_background_images(const std::string& campaign)
|
||||
{
|
||||
if(!campaign.empty() && !images_campaigns[campaign].empty()){
|
||||
return images_campaigns[campaign];
|
||||
}
|
||||
|
||||
return images_general;
|
||||
}
|
||||
|
||||
void set_about(const config& cfg)
|
||||
{
|
||||
parsed_credits_data.clear();
|
||||
|
||||
// TODO: should we reserve space in parsed_credits_data here?
|
||||
|
||||
images_campaigns.clear();
|
||||
images_general.clear();
|
||||
|
||||
//
|
||||
// Parse all [credits_group] tags
|
||||
//
|
||||
for(const config& group : cfg.child_range("credits_group")) {
|
||||
if(group.has_child("about")) {
|
||||
parsed_credits_data.emplace_back(group, false);
|
||||
|
||||
// Not in the credits_group since we don't want to inadvertently
|
||||
// pick up images from campaigns.
|
||||
gather_images(group, images_general);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Parse all toplevel [about] tags.
|
||||
//
|
||||
config misc;
|
||||
for(const config& about : cfg.child_range("about")) {
|
||||
misc.add_child("about", about);
|
||||
gather_images(about, images_default);
|
||||
}
|
||||
|
||||
if(!misc.empty()) {
|
||||
about_list.add_child("credits_group", std::move(misc));
|
||||
parsed_credits_data.emplace_back(misc, false);
|
||||
}
|
||||
|
||||
//
|
||||
// Parse all campaign [about] tags.
|
||||
//
|
||||
for(const config& campaign : cfg.child_range("campaign")) {
|
||||
if(!campaign.has_child("about")) {
|
||||
continue;
|
||||
if(campaign.has_child("about")) {
|
||||
parsed_credits_data.emplace_back(campaign, true);
|
||||
}
|
||||
|
||||
const std::string& id = campaign["id"];
|
||||
|
||||
config temp;
|
||||
temp["title"] = campaign["name"];
|
||||
temp["id"] = id;
|
||||
|
||||
for(const config& about : campaign.child_range("about")) {
|
||||
temp.add_child("about", about);
|
||||
gather_images(about, images[id]);
|
||||
}
|
||||
|
||||
about_list.add_child("credits_group", std::move(temp));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,18 +14,48 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
class config;
|
||||
#include "tstring.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class config;
|
||||
|
||||
namespace about
|
||||
{
|
||||
struct credits_group
|
||||
{
|
||||
struct about_group
|
||||
{
|
||||
explicit about_group(const config& cfg);
|
||||
|
||||
/** Contributor names. */
|
||||
std::vector<std::string> names;
|
||||
|
||||
/** The section title. */
|
||||
t_string title;
|
||||
|
||||
bool operator<(const about_group& o);
|
||||
};
|
||||
|
||||
credits_group(const config& cfg, bool is_campaign_credits);
|
||||
|
||||
/** The group's sub-groups. Corresponds to each [about] tag .*/
|
||||
std::vector<about_group> sections;
|
||||
|
||||
/** Optional group ID. Currently only used for identifying campaigns. */
|
||||
std::string id;
|
||||
|
||||
/** Optional group tite. Currently only used for identifying campaigns. */
|
||||
t_string header;
|
||||
};
|
||||
|
||||
using credits_data = std::vector<credits_group>;
|
||||
|
||||
/**
|
||||
* General getter methods for the credits config and image lists by campaign id
|
||||
*/
|
||||
const config& get_about_config();
|
||||
const credits_data& get_credits_data();
|
||||
|
||||
std::vector<std::string> get_background_images(const std::string& campaign);
|
||||
|
||||
|
|
|
@ -47,19 +47,6 @@ end_credits::end_credits(const std::string& campaign)
|
|||
{
|
||||
}
|
||||
|
||||
static void parse_about_tag(const config& cfg, std::stringstream& ss)
|
||||
{
|
||||
if(!cfg.has_child("entry")) {
|
||||
return;
|
||||
}
|
||||
|
||||
ss << "\n" << "<span size='x-large'>" << cfg["title"] << "</span>" << "\n";
|
||||
|
||||
for(const auto& entry : cfg.child_range("entry")) {
|
||||
ss << entry["name"] << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void end_credits::pre_show(window& window)
|
||||
{
|
||||
window.set_callback_next_draw([this]()
|
||||
|
@ -75,28 +62,19 @@ void end_credits::pre_show(window& window)
|
|||
std::stringstream ss;
|
||||
std::stringstream focus_ss;
|
||||
|
||||
const config& credits_config = about::get_about_config();
|
||||
|
||||
for(const auto& group : credits_config.child_range("credits_group")) {
|
||||
std::stringstream& group_stream = (group["id"] == focus_on_) ? focus_ss : ss;
|
||||
|
||||
for(const about::credits_group& group : about::get_credits_data()) {
|
||||
std::stringstream& group_stream = (group.id == focus_on_) ? focus_ss : ss;
|
||||
group_stream << "\n";
|
||||
if(group.has_attribute("title")) {
|
||||
group_stream << "<span size='xx-large'>" << group["title"] << "</span>" << "\n";
|
||||
|
||||
if(!group.header.empty()) {
|
||||
group_stream << "<span size='xx-large'>" << group.header << "</span>" << "\n";
|
||||
}
|
||||
|
||||
if(group["sort"].to_bool(false)) {
|
||||
auto sections = group.child_range("about");
|
||||
std::vector<config> sorted(sections.begin(), sections.end());
|
||||
std::sort(sorted.begin(), sorted.end(), [](const config& entry1, const config& entry2) {
|
||||
return translation::compare(entry1["title"].str(), entry2["title"].str()) < 0;
|
||||
});
|
||||
for(const auto& about : sorted) {
|
||||
parse_about_tag(about, group_stream);
|
||||
}
|
||||
} else {
|
||||
for(const auto& about : group.child_range("about")) {
|
||||
parse_about_tag(about, group_stream);
|
||||
for(const about::credits_group::about_group& about : group.sections) {
|
||||
group_stream << "\n" << "<span size='x-large'>" << about.title << "</span>" << "\n";
|
||||
|
||||
for(const std::string& entry : about.names) {
|
||||
group_stream << entry << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue