From 84a5f06dac837262a1db19519fd0283d9aee1d40 Mon Sep 17 00:00:00 2001
From: "Zed A. Shaw" <zed.shaw@gmail.com>
Date: Mon, 14 Apr 2025 23:06:08 -0400
Subject: [PATCH] Reworked the way shaders are configured to reduce the amount
 of times clicks on buttons cause the shared shaders to reset.

---
 combat_ui.cpp |  2 +-
 guecs.cpp     | 21 ++++++++++-----------
 guecs.hpp     |  6 +++---
 ritual_ui.cpp |  4 ++--
 shaders.cpp   | 16 ++++++++--------
 5 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/combat_ui.cpp b/combat_ui.cpp
index aaccae6..fe83137 100644
--- a/combat_ui.cpp
+++ b/combat_ui.cpp
@@ -18,7 +18,7 @@ namespace gui {
     $gui.set<Sprite>(button, {"leather_pouch-128"});
     // $gui.set<Rectangle>(button, {});
     $gui.set<Label>(button, {label});
-    $gui.set<Shader>(button, {.duration=10.0f});
+    $gui.set<Effect>(button, {.duration=0.1f});
     $gui.set<Clickable>(button,
         guecs::make_action(*$level.world, event));
   }
diff --git a/guecs.cpp b/guecs.cpp
index 325ef7f..a3c84e4 100644
--- a/guecs.cpp
+++ b/guecs.cpp
@@ -66,34 +66,33 @@ namespace guecs {
     shape->setFillColor(color);
   }
 
-  void Shader::init(lel::Cell &cell) {
+  void Effect::init(lel::Cell &cell) {
     $shader_version = shaders::version();
     $shader = shaders::get(name);
     $shader->setUniform("u_resolution", sf::Vector2f({float(cell.w), float(cell.h)}));
     $clock = std::make_shared<sf::Clock>();
   }
 
-  void Shader::step() {
+  void Effect::step() {
     sf::Time cur_time = $clock->getElapsedTime();
     float u_time = cur_time.asSeconds();
 
     if(u_time < $u_time_end) {
+      $shader->setUniform("u_duration", duration);
+      $shader->setUniform("u_time_end", $u_time_end);
       $shader->setUniform("u_time", u_time);
     } else {
       $active = false;
     }
   }
 
-  void Shader::run() {
-    $shader = checkout_ptr();
+  void Effect::run() {
     $active = true;
     sf::Time u_time = $clock->getElapsedTime();
     $u_time_end = u_time.asSeconds() + duration;
-    $shader->setUniform("u_duration", duration);
-    $shader->setUniform("u_time_end", $u_time_end);
   }
 
-  shared_ptr<sf::Shader> Shader::checkout_ptr() {
+  shared_ptr<sf::Shader> Effect::checkout_ptr() {
     if(shaders::updated($shader_version)) {
       $shader = shaders::get(name);
       $shader_version = shaders::version();
@@ -150,7 +149,7 @@ namespace guecs {
       rect.init(cell);
     });
 
-    $world.query<lel::Cell, Shader>([](auto, auto& cell, auto& shader) {
+    $world.query<lel::Cell, Effect>([](auto, auto& cell, auto& shader) {
         shader.init(cell);
     });
 
@@ -192,7 +191,7 @@ namespace guecs {
       window.draw(*bg.shape);
     }
 
-    $world.query<Shader>([&](auto, auto& shader) {
+    $world.query<Effect>([&](auto, auto& shader) {
       if(shader.$active) shader.step();
     });
 
@@ -227,8 +226,8 @@ namespace guecs {
       if((x >= cell.x && x <= cell.x + cell.w) &&
           (y >= cell.y && y <= cell.y + cell.h))
       {
-        if($world.has<Shader>(ent)) {
-          auto& shader = $world.get<Shader>(ent);
+        if($world.has<Effect>(ent)) {
+          auto& shader = $world.get<Effect>(ent);
           shader.run();
         }
 
diff --git a/guecs.hpp b/guecs.hpp
index 919c641..3bd8990 100644
--- a/guecs.hpp
+++ b/guecs.hpp
@@ -82,7 +82,7 @@ namespace guecs {
     std::string name;
   };
 
-  struct Shader {
+  struct Effect {
     float duration = 0.1f;
     std::string name{"ui_shader"};
     float $u_time_end = 0.0;
@@ -198,8 +198,8 @@ namespace guecs {
       void render_helper(sf::RenderWindow& window, DinkyECS::Entity ent, bool is_shape, T& target) {
         sf::Shader *shader_ptr = nullptr;
 
-        if($world.has<Shader>(ent)) {
-          auto& shader = $world.get<Shader>(ent);
+        if($world.has<Effect>(ent)) {
+          auto& shader = $world.get<Effect>(ent);
 
           if(shader.$active) {
             auto ptr = shader.checkout_ptr();
diff --git a/ritual_ui.cpp b/ritual_ui.cpp
index c57f513..401ae16 100644
--- a/ritual_ui.cpp
+++ b/ritual_ui.cpp
@@ -42,7 +42,7 @@ namespace gui {
       auto button = $gui.entity(name);
 
       if(name == "circle_area") {
-        $gui.set<Shader>(button, {0.4f});
+        $gui.set<Effect>(button, {0.4f});
         $gui.set<Sprite>(button, {"the_ritual_circle"});
         $gui.set<Clickable>(button, {
             [&](auto ent, auto){ ritual_circle_clicked(ent); }
@@ -50,7 +50,7 @@ namespace gui {
       } else if(name.starts_with("inv_slot")) {
         $gui.set<Sprite>(button, {
             fmt::format("{}-64", junk_list[button % junk_list.size()])});
-        $gui.set<Shader>(button, {0.4f});
+        $gui.set<Effect>(button, {0.4f});
         $gui.set<Clickable>(button, {
             [&](auto ent, auto){ inv_slot_clicked(ent); }
         });
diff --git a/shaders.cpp b/shaders.cpp
index 36c998a..6983191 100644
--- a/shaders.cpp
+++ b/shaders.cpp
@@ -7,16 +7,16 @@
 #include <memory>
 
 namespace shaders {
-  using std::shared_ptr, std::make_shared;
+using std::shared_ptr, std::make_shared;
 
-  static ShaderManager SMGR;
-  static bool INITIALIZED = false;
-  static int VERSION = 0;
+static ShaderManager SMGR;
+static bool INITIALIZED = false;
+static int VERSION = 0;
 
-  bool load_shader(std::string name, nlohmann::json& settings) {
-    std::string file_name = settings["file_name"];
-    auto ptr = std::make_shared<sf::Shader>();
-    bool good = ptr->loadFromFile(file_name, sf::Shader::Type::Fragment);
+bool load_shader(std::string name, nlohmann::json& settings) {
+  std::string file_name = settings["file_name"];
+  auto ptr = std::make_shared<sf::Shader>();
+  bool good = ptr->loadFromFile(file_name, sf::Shader::Type::Fragment);
     if(good) SMGR.shaders.try_emplace(name, name, file_name, ptr);
     return good;
   }