Refactoring the GUECS UI::render and the components so that it's just calling a .render on each one. This will then let me allow registering any components people want.
This commit is contained in:
parent
a9e219ea96
commit
4d71f552aa
7 changed files with 108 additions and 69 deletions
|
@ -150,7 +150,7 @@ struct CalculatorUI {
|
||||||
}
|
}
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
$gui.set<guecs::Background>($gui.MAIN, {});
|
$gui.set<guecs::Background>($gui.MAIN, {$gui.$parser});
|
||||||
|
|
||||||
for(auto& [name, cell] : $gui.cells()) {
|
for(auto& [name, cell] : $gui.cells()) {
|
||||||
auto id = $gui.entity(name);
|
auto id = $gui.entity(name);
|
||||||
|
|
|
@ -55,7 +55,7 @@ struct Shake {
|
||||||
float tick = ease();
|
float tick = ease();
|
||||||
sf::Vector2f scale{
|
sf::Vector2f scale{
|
||||||
std::lerp(initial_scale.x, initial_scale.x + scale_factor, tick),
|
std::lerp(initial_scale.x, initial_scale.x + scale_factor, tick),
|
||||||
std::lerp(initial_scale.y, initial_scale.y + scale_factor, tick)};
|
std::lerp(initial_scale.y, initial_scale.y + scale_factor, tick)};
|
||||||
|
|
||||||
sprite.sprite->setScale(scale);
|
sprite.sprite->setScale(scale);
|
||||||
} else {
|
} else {
|
||||||
|
@ -83,34 +83,35 @@ struct ClickerUI {
|
||||||
void init() {
|
void init() {
|
||||||
$gui.set<guecs::Background>($gui.MAIN, {$gui.$parser, {0, 0, 0, 255}});
|
$gui.set<guecs::Background>($gui.MAIN, {$gui.$parser, {0, 0, 0, 255}});
|
||||||
|
|
||||||
for(auto& [name, cell] : $gui.cells()) {
|
for(auto& [name, cell] : $gui.cells()) {
|
||||||
auto id = $gui.entity(name);
|
auto id = $gui.entity(name);
|
||||||
if(name != "clicker") {
|
if(name != "clicker") {
|
||||||
$gui.set<guecs::Rectangle>(id, {});
|
$gui.set<guecs::Rectangle>(id, {});
|
||||||
$gui.set<guecs::Effect>(id, {});
|
$gui.set<guecs::Effect>(id, {});
|
||||||
$gui.set<guecs::Sprite>(id, { "clicker_treat_bone" });
|
$gui.set<guecs::Sprite>(id, { "clicker_treat_bone" });
|
||||||
fmt::println("button dim: {},{}", cell.w, cell.h);
|
fmt::println("button dim: {},{}", cell.w, cell.h);
|
||||||
$gui.set<guecs::Clickable>(id, {
|
$gui.set<guecs::Clickable>(id, {
|
||||||
[&](auto, auto) { handle_button(Event::A_BUTTON); }
|
[&](auto, auto) { handle_button(Event::A_BUTTON); }
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$clicker = $gui.entity("clicker");
|
$clicker = $gui.entity("clicker");
|
||||||
$gui.set<guecs::Sprite>($clicker, {"clicker_the_dog"});
|
$gui.set<guecs::Sprite>($clicker, {"clicker_the_dog"});
|
||||||
$gui.set<guecs::Sound>($clicker, {"clicker_bark"});
|
$gui.set<guecs::Sound>($clicker, {"clicker_bark"});
|
||||||
$gui.set<guecs::Clickable>($clicker, {
|
$gui.set<guecs::Clickable>($clicker, {
|
||||||
[&](auto, auto) { handle_button(Event::CLICKER); }
|
[&](auto, auto) { handle_button(Event::CLICKER); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// custom components need to be initialized manually
|
// custom components need to be initialized manually
|
||||||
$gui.set_init<Shake>($clicker, {});
|
$gui.set_init<Shake>($clicker, {});
|
||||||
|
|
||||||
$gui.init();
|
$gui.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render(sf::RenderWindow& window) {
|
void render(sf::RenderWindow& window) {
|
||||||
auto& shaker = $gui.get<Shake>($clicker);
|
auto& shaker = $gui.get<Shake>($clicker);
|
||||||
|
|
||||||
if(shaker.playing) {
|
if(shaker.playing) {
|
||||||
auto& sprite = $gui.get<guecs::Sprite>($clicker);
|
auto& sprite = $gui.get<guecs::Sprite>($clicker);
|
||||||
shaker.render(sprite);
|
shaker.render(sprite);
|
||||||
|
@ -130,17 +131,17 @@ struct ClickerUI {
|
||||||
using enum Event;
|
using enum Event;
|
||||||
switch(ev) {
|
switch(ev) {
|
||||||
case CLICKER: {
|
case CLICKER: {
|
||||||
auto& shaker = $gui.get<Shake>($clicker);
|
auto& shaker = $gui.get<Shake>($clicker);
|
||||||
auto& sprite = $gui.get<guecs::Sprite>($clicker);
|
auto& sprite = $gui.get<guecs::Sprite>($clicker);
|
||||||
shaker.play(sprite);
|
shaker.play(sprite);
|
||||||
fmt::println("CLICKER LOVES YOU!");
|
fmt::println("CLICKER LOVES YOU!");
|
||||||
} break;
|
} break;
|
||||||
case A_BUTTON:
|
case A_BUTTON:
|
||||||
fmt::println("a button clicked");
|
fmt::println("a button clicked");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false && "invalid event");
|
assert(false && "invalid event");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -149,7 +150,7 @@ int main() {
|
||||||
sfml::Backend backend;
|
sfml::Backend backend;
|
||||||
guecs::init(&backend);
|
guecs::init(&backend);
|
||||||
|
|
||||||
sf::RenderWindow window(sf::VideoMode({WINDOW_WIDTH, WINDOW_HEIGHT}), "LEL-GUECS Calculator");
|
sf::RenderWindow window(sf::VideoMode({WINDOW_WIDTH, WINDOW_HEIGHT}), "Clicker the Dog");
|
||||||
window.setFramerateLimit(FRAME_LIMIT);
|
window.setFramerateLimit(FRAME_LIMIT);
|
||||||
window.setVerticalSyncEnabled(VSYNC);
|
window.setVerticalSyncEnabled(VSYNC);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace guecs {
|
||||||
|
|
||||||
void init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr);
|
void init(lel::Cell &cell, shared_ptr<sf::Font> font_ptr);
|
||||||
void update(const std::wstring& new_content);
|
void update(const std::wstring& new_content);
|
||||||
|
void render(sf::RenderWindow& window, sf::Shader *shader_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Label : public Textual {
|
struct Label : public Textual {
|
||||||
|
@ -49,6 +50,7 @@ namespace guecs {
|
||||||
|
|
||||||
void init(lel::Cell &cell);
|
void init(lel::Cell &cell);
|
||||||
void update(const string& new_name);
|
void update(const string& new_name);
|
||||||
|
void render(sf::RenderWindow& window, sf::Shader *shader_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Rectangle {
|
struct Rectangle {
|
||||||
|
@ -59,6 +61,7 @@ namespace guecs {
|
||||||
shared_ptr<sf::RectangleShape> shape = nullptr;
|
shared_ptr<sf::RectangleShape> shape = nullptr;
|
||||||
|
|
||||||
void init(lel::Cell& cell);
|
void init(lel::Cell& cell);
|
||||||
|
void render(sf::RenderWindow& window, sf::Shader *shader_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Meter {
|
struct Meter {
|
||||||
|
@ -67,7 +70,8 @@ namespace guecs {
|
||||||
Rectangle bar;
|
Rectangle bar;
|
||||||
|
|
||||||
void init(lel::Cell& cell);
|
void init(lel::Cell& cell);
|
||||||
void render(lel::Cell& cell);
|
void init(lel::Cell& cell, Rectangle& bg);
|
||||||
|
void render(lel::Cell& cell, sf::RenderWindow& window, sf::Shader *shader_ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Effect {
|
struct Effect {
|
||||||
|
@ -82,8 +86,9 @@ namespace guecs {
|
||||||
void init(lel::Cell &cell);
|
void init(lel::Cell &cell);
|
||||||
void run();
|
void run();
|
||||||
void stop();
|
void stop();
|
||||||
void step();
|
void render();
|
||||||
shared_ptr<sf::Shader> checkout_ptr();
|
sf::Shader* get_shader(bool is_shape);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sound {
|
struct Sound {
|
||||||
|
@ -111,5 +116,6 @@ namespace guecs {
|
||||||
Background() {}
|
Background() {}
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
void render(sf::RenderWindow& window);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,20 +209,11 @@ namespace guecs {
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void render_helper(sf::RenderWindow& window, Entity ent, bool is_shape, T& target) {
|
void render_helper(sf::RenderWindow& window, T& target, sf::Shader *shader_ptr) {
|
||||||
sf::Shader *shader_ptr = nullptr;
|
window.draw(*target, shader_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
if(auto shader = get_if<Effect>(ent)) {
|
sf::Shader* find_shader(Entity ent, bool is_shape);
|
||||||
if(shader->$active) {
|
|
||||||
auto ptr = shader->checkout_ptr();
|
|
||||||
ptr->setUniform("is_shape", is_shape);
|
|
||||||
// NOTE: this is needed because SFML doesn't handle shared_ptr
|
|
||||||
shader_ptr = ptr.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.draw(*target, shader_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void show_sprite(const string& region, const string& sprite_name);
|
void show_sprite(const string& region, const string& sprite_name);
|
||||||
void show_text(const string& region, const wstring& content);
|
void show_text(const string& region, const wstring& content);
|
||||||
|
|
|
@ -45,8 +45,8 @@ namespace sfml {
|
||||||
theme.LABEL_SIZE = 20;
|
theme.LABEL_SIZE = 20;
|
||||||
theme.FILL_COLOR = theme.DARK_MID;
|
theme.FILL_COLOR = theme.DARK_MID;
|
||||||
theme.TEXT_COLOR = theme.LIGHT_LIGHT;
|
theme.TEXT_COLOR = theme.LIGHT_LIGHT;
|
||||||
theme.BG_COLOR = theme.MID;
|
theme.BG_COLOR = theme.DARK_DARK;
|
||||||
theme.BORDER_COLOR = theme.LIGHT_DARK;
|
theme.BORDER_COLOR = theme.DARK_LIGHT;
|
||||||
theme.BG_COLOR_DARK = theme.BLACK;
|
theme.BG_COLOR_DARK = theme.BLACK;
|
||||||
theme.FONT_FILE_NAME = "assets/text.otf";
|
theme.FONT_FILE_NAME = "assets/text.otf";
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,10 @@ namespace guecs {
|
||||||
text->setCharacterSize(size);
|
text->setCharacterSize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Textual::render(sf::RenderWindow& window, sf::Shader *shader_ptr) {
|
||||||
|
window.draw(*text, shader_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void Textual::update(const wstring& new_content) {
|
void Textual::update(const wstring& new_content) {
|
||||||
content = new_content;
|
content = new_content;
|
||||||
text->setString(content);
|
text->setString(content);
|
||||||
|
@ -56,6 +60,10 @@ namespace guecs {
|
||||||
float(cell.h - padding * 2) / bounds.size.y});
|
float(cell.h - padding * 2) / bounds.size.y});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sprite::render(sf::RenderWindow& window, sf::Shader *shader_ptr) {
|
||||||
|
window.draw(*sprite, shader_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void Rectangle::init(lel::Cell& cell) {
|
void Rectangle::init(lel::Cell& cell) {
|
||||||
sf::Vector2f size{float(cell.w) - padding * 2, float(cell.h) - padding * 2};
|
sf::Vector2f size{float(cell.w) - padding * 2, float(cell.h) - padding * 2};
|
||||||
if(shape == nullptr) shape = make_shared<sf::RectangleShape>(size);
|
if(shape == nullptr) shape = make_shared<sf::RectangleShape>(size);
|
||||||
|
@ -65,15 +73,24 @@ namespace guecs {
|
||||||
shape->setOutlineThickness(border_px);
|
shape->setOutlineThickness(border_px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Rectangle::render(sf::RenderWindow& window, sf::Shader *shader_ptr) {
|
||||||
|
window.draw(*shape, shader_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Meter::init(lel::Cell& cell, Rectangle& bg) {
|
||||||
|
bg.shape->setFillColor(color);
|
||||||
|
init(cell);
|
||||||
|
}
|
||||||
|
|
||||||
void Meter::init(lel::Cell& cell) {
|
void Meter::init(lel::Cell& cell) {
|
||||||
bar.init(cell);
|
bar.init(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Meter::render(lel::Cell& cell) {
|
void Meter::render(lel::Cell& cell, sf::RenderWindow& window, sf::Shader *shader_ptr) {
|
||||||
float level = std::clamp(percent, 0.0f, 1.0f) * float(cell.w);
|
float level = std::clamp(percent, 0.0f, 1.0f) * float(cell.w);
|
||||||
// ZED: this 6 is a border width, make it a thing
|
// ZED: this 6 is a border width, make it a thing
|
||||||
bar.shape->setSize({std::max(level, 0.0f), float(cell.h - 6)});
|
bar.shape->setSize({std::max(level, 0.0f), float(cell.h - 6)});
|
||||||
|
window.draw(*bar.shape, shader_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::play(bool hover) {
|
void Sound::play(bool hover) {
|
||||||
|
@ -104,13 +121,17 @@ namespace guecs {
|
||||||
assert(shape != nullptr && "failed to make rectangle");
|
assert(shape != nullptr && "failed to make rectangle");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Background::render(sf::RenderWindow& window) {
|
||||||
|
window.draw(*shape);
|
||||||
|
}
|
||||||
|
|
||||||
void Effect::init(lel::Cell &cell) {
|
void Effect::init(lel::Cell &cell) {
|
||||||
$shader = BACKEND->shader_get(name);
|
$shader = BACKEND->shader_get(name);
|
||||||
$shader->setUniform("u_resolution", sf::Vector2f({float(cell.w), float(cell.h)}));
|
$shader->setUniform("u_resolution", sf::Vector2f({float(cell.w), float(cell.h)}));
|
||||||
$clock = std::make_shared<sf::Clock>();
|
$clock = std::make_shared<sf::Clock>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::step() {
|
void Effect::render() {
|
||||||
sf::Time cur_time = $clock->getElapsedTime();
|
sf::Time cur_time = $clock->getElapsedTime();
|
||||||
float u_time = cur_time.asSeconds();
|
float u_time = cur_time.asSeconds();
|
||||||
|
|
||||||
|
@ -129,12 +150,20 @@ namespace guecs {
|
||||||
$u_time_end = u_time.asSeconds() + duration;
|
$u_time_end = u_time.asSeconds() + duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<sf::Shader> Effect::checkout_ptr() {
|
sf::Shader* Effect::get_shader(bool is_shape) {
|
||||||
|
sf::Shader *shader_ptr = nullptr;
|
||||||
|
|
||||||
if(BACKEND->shader_updated()) {
|
if(BACKEND->shader_updated()) {
|
||||||
$shader = BACKEND->shader_get(name);
|
$shader = BACKEND->shader_get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $shader;
|
if($active) {
|
||||||
|
$shader->setUniform("is_shape", is_shape);
|
||||||
|
// NOTE: this is needed because SFML doesn't handle shared_ptr
|
||||||
|
shader_ptr = $shader.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Effect::stop() {
|
void Effect::stop() {
|
||||||
|
|
|
@ -66,12 +66,12 @@ namespace guecs {
|
||||||
shader.init(cell);
|
shader.init(cell);
|
||||||
});
|
});
|
||||||
|
|
||||||
query<Rectangle, Meter>([](auto, auto& bg, auto &meter) {
|
query<lel::Cell, Meter>([this](auto ent, auto &cell, auto& meter) {
|
||||||
bg.shape->setFillColor(meter.color);
|
if(auto bg = get_if<Rectangle>(ent)) {
|
||||||
});
|
meter.init(cell, *bg);
|
||||||
|
} else {
|
||||||
query<lel::Cell, Meter>([](auto, auto &cell, auto& meter) {
|
meter.init(cell);
|
||||||
meter.init(cell);
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
query<lel::Cell, Textual>([this](auto, auto& cell, auto& text) {
|
query<lel::Cell, Textual>([this](auto, auto& cell, auto& text) {
|
||||||
|
@ -98,34 +98,46 @@ namespace guecs {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sf::Shader* UI::find_shader(Entity ent, bool is_shape) {
|
||||||
|
if(auto shader = get_if<Effect>(ent)) {
|
||||||
|
return shader->get_shader(is_shape);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UI::render(sf::RenderWindow& window) {
|
void UI::render(sf::RenderWindow& window) {
|
||||||
if(auto bg = get_if<Background>(MAIN)) {
|
if(auto bg = get_if<Background>(MAIN)) {
|
||||||
window.draw(*(bg->shape));
|
bg->render(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
query<Effect>([&](auto, auto& shader) {
|
query<Effect>([&](auto, auto& shader) {
|
||||||
if(shader.$active) shader.step();
|
if(shader.$active) shader.render();
|
||||||
});
|
});
|
||||||
|
|
||||||
query<Rectangle>([&](auto ent, auto& rect) {
|
query<Rectangle>([&](auto ent, auto& rect) {
|
||||||
render_helper(window, ent, true, rect.shape);
|
auto shader_ptr = find_shader(ent, true);
|
||||||
|
rect.render(window, shader_ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
query<lel::Cell, Meter>([&](auto ent, auto& cell, auto &meter) {
|
query<lel::Cell, Meter>([&](auto ent, auto& cell, auto &meter) {
|
||||||
meter.render(cell);
|
auto shader_ptr = find_shader(ent, true);
|
||||||
render_helper(window, ent, true, meter.bar.shape);
|
meter.render(cell, window, shader_ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
query<Sprite>([&](auto ent, auto& sprite) {
|
query<Sprite>([&](auto ent, auto& sprite) {
|
||||||
render_helper(window, ent, false, sprite.sprite);
|
auto shader_ptr = find_shader(ent, false);
|
||||||
|
sprite.render(window, shader_ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
query<Label>([&](auto ent, auto& text) {
|
query<Label>([&](auto ent, auto& text) {
|
||||||
render_helper(window, ent, false, text.text);
|
auto shader_ptr = find_shader(ent, false);
|
||||||
|
text.render(window, shader_ptr);
|
||||||
});
|
});
|
||||||
|
|
||||||
query<Textual>([&](auto ent, auto& text) {
|
query<Textual>([&](auto ent, auto& text) {
|
||||||
render_helper(window, ent, false, text.text);
|
auto shader_ptr = find_shader(ent, false);
|
||||||
|
text.render(window, shader_ptr);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,8 +169,8 @@ namespace guecs {
|
||||||
});
|
});
|
||||||
|
|
||||||
do_if<Sound>(ent, [hover](auto& sound) {
|
do_if<Sound>(ent, [hover](auto& sound) {
|
||||||
// here set that it played then only play once
|
// here set that it played then only play once
|
||||||
sound.stop(hover);
|
sound.stop(hover);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue