#pragma once #include #include #include #include namespace cigus { using json = nlohmann::json; template class Ref { T *ptr; public: explicit Ref(T *ptr) : ptr(ptr) { if (ptr == nullptr) { spdlog::error("Ref cannot be null"); throw std::runtime_error("Ref cannot be null"); } } Ref(const Ref &other) : ptr(other.ptr) { if (other.ptr == nullptr) { spdlog::error("Ref cannot be null"); throw std::runtime_error("Ref cannot be null"); } } Ref(Ref &&other) noexcept : ptr(other.ptr) { if (other.ptr == nullptr) { spdlog::error("Ref cannot be null"); throw std::runtime_error("Ref cannot be null"); } } Ref &operator=(Ref &&other) noexcept { if (this->ptr != other.ptr) { ptr = other.ptr; } return *this; } T &operator*() { return *ptr; } const T &operator*() const { return *ptr; } T *operator->() { return ptr; } const T *operator->() const { return ptr; } void free() { delete ptr; ptr = nullptr; } }; } namespace cigus::UI { class RenderCall { sf::Drawable *drawable; sf::RenderStates states; public: RenderCall(sf::Drawable *drawable, sf::RenderStates states) : drawable(drawable), states(states) { } ~RenderCall() { delete drawable; } void draw(sf::RenderTarget &target, const sf::RenderStates &states) const { target.draw(*drawable, states); } }; class View { std::vector m_RenderCalls; protected: void Rectangle() { m_RenderCalls.emplace_back(new sf::RectangleShape(sf::Vector2f(100, 100)), sf::RenderStates()); } public: virtual ~View() = default; [[nodiscard]] const std::vector &renderCalls() const { return m_RenderCalls; } virtual void body() = 0; }; class Renderer { public: explicit Renderer(const Ref &_view) : view(_view) { view->body(); } void destroy() { view.free(); } Ref view; void update() { view->body(); } void render(sf::RenderTarget &target, const sf::RenderStates &states) const { for (const auto &renderCall: view->renderCalls()) { renderCall.draw(target, states); } } }; }