Skip to content

Add Rgba map to Styles. Use for tints of weapon rounds. #19

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions assets/styles.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"rgbas": {
"black": "#231d2aff",
"grey": "#535151ff",
"mocha": "#6f5a48ff",
"milk": "#e5cdaeff",
"ice": "#0xd6dbe1e1"
},
"buttons": {
"default": {
"background": {
Expand Down
4 changes: 1 addition & 3 deletions src/spaced/spaced/game/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ void Player::debug_switch_weapon() {
return;
}

auto kinetic = std::make_unique<GunKinetic>(*m_services);
kinetic->projectile_config.tint = bave::cyan_v;
m_weapon = std::move(kinetic);
m_weapon = std::make_unique<GunKinetic>(*m_services);
m_debug.shots_remaining = 10;
}
} // namespace spaced
3 changes: 3 additions & 0 deletions src/spaced/spaced/game/weapons/gun_beam.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <bave/graphics/sprite.hpp>
#include <bave/imgui/im_text.hpp>
#include <spaced/game/weapons/gun_beam.hpp>
#include <spaced/services/styles.hpp>

namespace spaced {
using bave::im_text;
Expand Down Expand Up @@ -96,6 +97,8 @@ class LaserCharge : public IWeaponRound {
};
} // namespace

GunBeam::GunBeam(Services const& services) : Weapon(services, "GunBeam") { config.beam_tint = services.get<Styles>().rgbas["grey"]; }

auto GunBeam::fire(glm::vec2 const muzzle_position) -> std::unique_ptr<Round> {
if (!is_idle() || m_reload_remain > 0s) { return {}; }

Expand Down
2 changes: 1 addition & 1 deletion src/spaced/spaced/game/weapons/gun_beam.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class GunBeam final : public Weapon {
float dps{1.0f};
};

explicit GunBeam(Services const& services) : Weapon(services, "DeathRay") {}
explicit GunBeam(Services const& services);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why pass a reference to services here, and in all the other places? could you also have some ServiceLocator with services and include it in any needed .cpps? if not, why not?

Copy link
Member Author

@karnkaul karnkaul Mar 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Services is a service locator, it's just not globally accessible / a singleton. It has its own lifetime and ownership, which supercedes all the services it owns, thereby also giving them explicit lifetime and ownership. Globals, especially singletons, take away both of these very important aspects in C++.

The rest of your thinking is spot on: instead of passing dozens of different references in various constructors (which would be most explicit and correct, but too cumbersome and volatile), we design commonly referenced items as services, initialized by the game driver (Spaced).


auto fire(glm::vec2 muzzle_position) -> std::unique_ptr<Round> final;
[[nodiscard]] auto is_idle() const -> bool final { return m_fire_remain <= 0s; }
Expand Down
3 changes: 2 additions & 1 deletion src/spaced/spaced/game/weapons/gun_kinetic.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#include <bave/imgui/im_text.hpp>
#include <spaced/game/weapons/gun_kinetic.hpp>
#include <spaced/services/styles.hpp>

namespace spaced {
using bave::im_text;
using bave::Rgba;
using bave::Seconds;

GunKinetic::GunKinetic(Services const& services) : Weapon(services, "GunKinetic") {}
GunKinetic::GunKinetic(Services const& services) : Weapon(services, "GunKinetic") { projectile_config.tint = services.get<Styles>().rgbas["black"]; }

auto GunKinetic::fire(glm::vec2 const muzzle_position) -> std::unique_ptr<Round> {
if (m_reload_remain > 0s) { return {}; }
Expand Down
6 changes: 3 additions & 3 deletions src/spaced/spaced/game/weapons/projectile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ class Projectile : public IWeaponRound {
public:
struct Config {
std::shared_ptr<bave::Texture> texture{};
glm::vec2 size{60.0f, 5.0f};
float corner_radius{2.5f};
glm::vec2 size{60.0f, 10.0f};
float corner_radius{0.5f * size.y};
float x_speed{1500.0f};
bave::Rgba tint{bave::white_v};
bave::Rgba tint{bave::black_v};
float damage{1.0f};
};

Expand Down
5 changes: 4 additions & 1 deletion src/spaced/spaced/scenes/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <spaced/scenes/game.hpp>
#include <spaced/scenes/home.hpp>
#include <spaced/services/scene_switcher.hpp>
#include <spaced/services/styles.hpp>

namespace spaced {
using bave::Action;
Expand Down Expand Up @@ -33,7 +34,9 @@ namespace {
}
} // namespace

Game::Game(App& app, Services const& services) : Scene(app, services, "Game"), m_player(services, make_player_controller(services)) {}
Game::Game(App& app, Services const& services) : Scene(app, services, "Game"), m_player(services, make_player_controller(services)) {
clear_colour = services.get<Styles>().rgbas["mocha"];
}

void Game::on_focus(bave::FocusChange const& focus_change) { m_player.on_focus(focus_change); }

Expand Down
25 changes: 9 additions & 16 deletions src/spaced/spaced/services/styles.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
#include <bave/json_io.hpp>
#include <spaced/services/styles.hpp>
#include <spaced/util.hpp>

namespace spaced::ui {
namespace spaced {
namespace {
using bave::from_json;
using bave::to_json;
using util::from_json;
using util::to_json;

template <typename Type>
void load_styles(Styles::Map<Type>& out, dj::Json const& json) {
void load_styles(StringMap<Type>& out, dj::Json const& json) {
for (auto const& [id, in_style] : json.object_view()) {
if (id.empty()) { continue; }
auto out_style = Type{};
Expand All @@ -17,41 +20,31 @@ void load_styles(Styles::Map<Type>& out, dj::Json const& json) {
}

template <typename Type>
void save_styles(Styles::Map<Type> const& styles, dj::Json& out, std::string_view const key) {
void save_styles(StringMap<Type> const& styles, dj::Json& out, std::string_view const key) {
auto out_styles = dj::Json{};
for (auto const& [id, button_style] : styles) {
if (id.empty()) { continue; }
to_json(out_styles[id], button_style);
}
if (out_styles) { out[key] = std::move(out_styles); }
}

template <typename Type>
[[nodiscard]] auto get_or_default(Styles::Map<Type> const& map, std::string_view const id) -> Type const& {
if (auto const it = map.find(id); it != map.end()) { return it->second; }
static auto const fallback = Type{};
return fallback;
}
} // namespace

auto Styles::load(dj::Json const& json) -> Styles {
auto ret = Styles{};
load_styles(ret.rgbas, json["rgbas"]);
load_styles(ret.buttons, json["buttons"]);
load_styles(ret.progress_bars, json["progress_bars"]);
if (auto const& loading_screen = json["loading_screen"]) { from_json(loading_screen, ret.loading_screen); }
if (auto const& collect_list_item = json["collect_list_item"]) { from_json(collect_list_item, ret.collect_list_item); }
return ret;
}

auto Styles::get_button(std::string_view id) const -> ButtonStyle const& { return get_or_default(buttons, id); }
auto Styles::get_progress_bar(std::string_view id) const -> ProgressBarStyle const& { return get_or_default(progress_bars, id); }

auto Styles::save() const -> dj::Json {
auto ret = dj::Json{};
save_styles(rgbas, ret, "rgbas");
save_styles(buttons, ret, "buttons");
save_styles(progress_bars, ret, "progress_bars");
to_json(ret["loading_screen"], loading_screen);
to_json(ret["collect_list_item"], collect_list_item);
return ret;
}
} // namespace spaced::ui
} // namespace spaced
21 changes: 7 additions & 14 deletions src/spaced/spaced/services/styles.hpp
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
#pragma once
#include <bave/core/string_hash.hpp>
#include <spaced/services/service.hpp>
#include <spaced/string_map.hpp>
#include <spaced/ui/style.hpp>
#include <unordered_map>

namespace dj {
class Json;
}

namespace spaced::ui {
namespace spaced {
struct Styles : IService {
template <typename Type>
using Map = std::unordered_map<std::string, Type, bave::StringHash, std::equal_to<>>;

Map<ButtonStyle> buttons{};
Map<ProgressBarStyle> progress_bars{};
CollectListItemStyle collect_list_item{};
LoadingScreenStyle loading_screen{};
StringMap<bave::Rgba> rgbas{};
StringMap<ui::ButtonStyle> buttons{};
StringMap<ui::ProgressBarStyle> progress_bars{};
ui::LoadingScreenStyle loading_screen{};

static auto load(dj::Json const& json) -> Styles;

[[nodiscard]] auto get_button(std::string_view id) const -> ButtonStyle const&;
[[nodiscard]] auto get_progress_bar(std::string_view id) const -> ProgressBarStyle const&;

[[nodiscard]] auto save() const -> dj::Json;
};
} // namespace spaced::ui
} // namespace spaced
6 changes: 3 additions & 3 deletions src/spaced/spaced/spaced.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ void Spaced::load_resources() {
resources->spinner = loader.load_texture("images/spinner.png", true);
m_services.bind<Resources>(std::move(resources));

auto styles = std::make_unique<ui::Styles>();
auto styles = std::make_unique<Styles>();
if (auto const json = loader.load_json("styles.json")) {
*styles = ui::Styles::load(json);
*styles = Styles::load(json);
m_log.info("loaded Styles from 'styles.json'");
}

Expand All @@ -122,7 +122,7 @@ void Spaced::load_resources() {
json.to_file("styles.json");
}
}
m_services.bind<ui::Styles>(std::move(styles));
m_services.bind<Styles>(std::move(styles));
}

void Spaced::set_layout() {
Expand Down
26 changes: 26 additions & 0 deletions src/spaced/spaced/string_map.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once
#include <bave/core/string_hash.hpp>
#include <unordered_map>

namespace spaced {
template <typename ValueType>
class StringMap : public std::unordered_map<std::string, ValueType, bave::StringHash, std::equal_to<>> {
public:
[[nodiscard]] auto get_or(std::string_view const key, ValueType const& fallback) const -> ValueType {
if (auto const it = this->find(key); it != this->end()) { return it->second; }
return fallback;
}

[[nodiscard]] auto get(std::string_view const key) const -> ValueType
requires(std::is_default_constructible_v<ValueType>)
{
return get_or(key, ValueType{});
}

[[nodiscard]] auto operator[](std::string_view const key) const -> ValueType
requires(std::is_default_constructible_v<ValueType>)
{
return get(key);
}
};
} // namespace spaced
2 changes: 1 addition & 1 deletion src/spaced/spaced/ui/button.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ using bave::TextHeight;
Button::Button(Services const& services) : m_layout(&services.get<ILayout>()), m_styles(&services.get<Styles>()) {
m_text.set_font(services.get<Resources>().main_font);
set_text_height(TextHeight::eDefault);
set_style(m_styles->get_button("default"));
set_style(m_styles->buttons["default"]);
}

void Button::set_position(glm::vec2 const position) {
Expand Down
2 changes: 1 addition & 1 deletion src/spaced/spaced/ui/progress_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace spaced::ui {
using bave::Shader;

ProgressBar::ProgressBar(Services const& services) : m_style(services.get<Styles>().get_progress_bar("default")) {}
ProgressBar::ProgressBar(Services const& services) : m_style(services.get<Styles>().progress_bars["default"]) {}

void ProgressBar::set_progress(float const progress) {
m_progress = progress;
Expand Down
13 changes: 0 additions & 13 deletions src/spaced/spaced/ui/style.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,4 @@ struct ProgressBarStyle {
bave::Rgba outline{bave::red_v};
float outline_width{5.0f};
};

struct CollectListItemStyle {
float panel_diameter{60.0f};
bave::Rgba panel_rgba{bave::white_v};
float outline_width{5.0f};
bave::Rgba outline_rgba{bave::red_v};
glm::vec2 sprite_size{40.0f};
float panel_y_offset{12.0f};
bave::TextHeight text_height = bave::TextHeight{20};
bave::Rgba text_rgba{bave::black_v};
float text_y_offset{-43.0f};
float item_x_pad{100.0f};
};
} // namespace spaced::ui
28 changes: 0 additions & 28 deletions src/spaced/spaced/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,34 +71,6 @@ void util::from_json(dj::Json const& json, ui::ProgressBarStyle& out) {
out.outline_width = json["outline_width"].as<float>();
}

void util::to_json(dj::Json& out, ui::CollectListItemStyle const& collect_list_item_style) {
using bave::to_json;
out["panel_diameter"] = collect_list_item_style.panel_diameter;
to_json(out["panel_rgba"], collect_list_item_style.panel_rgba);
out["outline_width"] = collect_list_item_style.outline_width;
to_json(out["outline_rgba"], collect_list_item_style.outline_rgba);
to_json(out["sprite_size"], collect_list_item_style.sprite_size);
out["panel_y_offset"] = collect_list_item_style.panel_y_offset;
out["text_height"] = static_cast<int>(collect_list_item_style.text_height);
to_json(out["text_rgba"], collect_list_item_style.text_rgba);
out["text_y_offset"] = collect_list_item_style.text_y_offset;
out["item_x_pad"] = collect_list_item_style.item_x_pad;
}

void util::from_json(dj::Json const& json, ui::CollectListItemStyle& out) {
using bave::from_json;
out.panel_diameter = json["panel_diameter"].as<float>(out.panel_diameter);
from_json(json["panel_rgba"], out.panel_rgba);
out.outline_width = json["outline_width"].as<float>();
from_json(json["outline_rgba"], out.outline_rgba);
from_json(json["sprite_size"], out.sprite_size);
out.panel_y_offset = json["panel_y_offset"].as<float>();
out.text_height = bave::TextHeight{json["text_height"].as<int>()};
from_json(json["text_rgba"], out.text_rgba);
out.text_y_offset = json["text_y_offset"].as<float>();
out.item_x_pad = json["item_x_pad"].as<float>();
}

auto util::create_font_atlas_task(std::shared_ptr<bave::Font> font, std::vector<bave::TextHeight> heights) -> std::function<void()> {
if (!font || heights.empty()) { return {}; }
return [font = std::move(font), heights = std::move(heights)] {
Expand Down
3 changes: 0 additions & 3 deletions src/spaced/spaced/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,5 @@ void from_json(dj::Json const& json, ui::ButtonStyle& out);
void to_json(dj::Json& out, ui::ProgressBarStyle const& progress_bar_style);
void from_json(dj::Json const& json, ui::ProgressBarStyle& out);

void to_json(dj::Json& out, ui::CollectListItemStyle const& collect_list_item_style);
void from_json(dj::Json const& json, ui::CollectListItemStyle& out);

auto create_font_atlas_task(std::shared_ptr<bave::Font> font, std::vector<bave::TextHeight> heights) -> std::function<void()>;
} // namespace spaced::util
6 changes: 3 additions & 3 deletions tools/format_code.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#!/bin/bash
#!/bin/bash

[[ ! $(clang-format --version) ]] && exit 1

exclude_list="scene_switcher.hpp"
exclude_list="scene_switcher.hpp string_map.hpp"

script_path=${0%/*}
tools_root=${script_path%/*}
Expand All @@ -15,7 +15,7 @@ fi

exclude_cmd=
for exclude in $exclude_list; do
exclude_cmd+="! -name $exclude"
exclude_cmd+="! -name $exclude "
done

files=$(find src/spaced src/android/app/src/main src/desktop -name "*.?pp" $exclude_cmd)
Expand Down