Updating Ref system. [segvault]

This commit is contained in:
noffie 2025-04-10 15:28:08 +02:00
parent 0ca3c9cc64
commit 1bc396c4b2
3 changed files with 162 additions and 45 deletions

View file

@ -5,7 +5,7 @@ project(cigus
LANGUAGES CXX) LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)

189
cigus.hpp
View file

@ -8,33 +8,103 @@
namespace cigus { namespace cigus {
using json = nlohmann::json; using json = nlohmann::json;
template<typename T> class Ref;
template<typename T> class OriginRef;
template<typename T> class MutRef;
template<typename T> class ConstRef;
template<typename T> template<typename T>
class Ref { class Ref {
T *ptr; protected:
T *ptr = nullptr;
public: public:
explicit Ref(T *ptr) : ptr(ptr) { virtual ~Ref() {}
if (ptr == nullptr) { Ref() = delete;
spdlog::error("Ref<T> cannot be null"); Ref(const Ref &other) = delete;
throw std::runtime_error("Ref<T> cannot be null"); Ref(Ref &&other) = delete;
Ref(const OriginRef<T>& ptr) : ptr(ptr.ptr) {
}
Ref(T* ptr) : ptr(ptr)
{
}
virtual bool operator!() const {
return ptr == nullptr;
}
virtual void check() const {
assert(ptr != nullptr || "Dereferencing null pointer");
}
virtual const T &operator*() const {
check();
return *ptr;
}
virtual const T *operator->() const {
check();
return ptr;
}
static Ref Null()
{
return Ref(nullptr);
}
};
template<typename T>
class OriginRef final : public MutRef<T> {
public:
friend class Ref<T>;
template<typename G, typename... Args>
OriginRef(Args... args) : Ref<T>(new G(std::forward<Args>(args)...)) {
}
OriginRef(T* ptr) : MutRef<T>(ptr) {
}
~OriginRef() override {
if (this->ptr != nullptr) {
delete this->ptr;
} }
} }
Ref(const Ref &other) : ptr(other.ptr) { [[nodiscard]] MutRef<T> mut() {
if (other.ptr == nullptr) { return MutRef<T>(this->ptr);
spdlog::error("Ref<T> cannot be null");
throw std::runtime_error("Ref<T> cannot be null");
}
} }
Ref(Ref &&other) noexcept : ptr(other.ptr) { [[nodiscard]] ConstRef<T> immute() const {
if (other.ptr == nullptr) { return ConstRef<T>(this->ptr);
spdlog::error("Ref<T> cannot be null"); }
throw std::runtime_error("Ref<T> cannot be null"); };
}
template<typename T>
class MutRef : public Ref<T> {
protected:
using Ref<T>::ptr;
public:
friend class Ref<T>;
using Ref<T>::check;
using Ref<T>::operator*;
using Ref<T>::operator->;
MutRef(const OriginRef<T>& other) : Ref<T>(other.ptr) {}
MutRef(T* ptr) : Ref<T>(ptr) {}
MutRef(const MutRef &other) : Ref<T>(other.ptr) {
} }
Ref &operator=(Ref &&other) noexcept { MutRef(MutRef &&other) noexcept : Ref<T>(other.ptr) {
}
MutRef &operator=(MutRef &&other) noexcept {
if (this->ptr != other.ptr) { if (this->ptr != other.ptr) {
ptr = other.ptr; ptr = other.ptr;
} }
@ -42,52 +112,82 @@ namespace cigus {
} }
T &operator*() { T &operator*() {
return *ptr; check();
}
const T &operator*() const {
return *ptr; return *ptr;
} }
T *operator->() { T *operator->() {
check();
return ptr; return ptr;
} }
};
const T *operator->() const { template<typename T>
return ptr; class ConstRef : public Ref<T>
{
protected:
using Ref<T>::ptr;
using Ref<T>::check;
public:
friend class Ref<T>;
ConstRef(const OriginRef<T> other) : Ref<T>(other.ptr) {
} }
void free() { ConstRef(const MutRef<T> other) : Ref<T>(other.ptr) {
delete ptr; }
ptr = nullptr; };
template<typename T>
class NullRef
{
public:
friend class Ref<T>;
NullRef(const NullRef &other) = delete;
NullRef(NullRef &&other) = delete;
NullRef &operator=(NullRef &&other) = delete;
NullRef() : Ref<T>(nullptr) {
}
T *ptr = nullptr;
bool operator!() const {
return false;
} }
}; };
} }
namespace cigus::UI { namespace cigus::UI {
class RenderCall { class RenderCall {
sf::Drawable *drawable; OriginRef<sf::Drawable> drawable;
sf::RenderStates states; sf::RenderStates states;
public: public:
RenderCall(sf::Drawable *drawable, sf::RenderStates states) : drawable(drawable), states(states) { explicit RenderCall(const sf::RenderStates& states, sf::Drawable *ptr) : drawable(ptr), states(states) {
} drawable.check();
~RenderCall() {
delete drawable;
} }
void draw(sf::RenderTarget &target, const sf::RenderStates &states) const { void draw(sf::RenderTarget &target, const sf::RenderStates &states) const {
target.draw(*drawable, states); target.draw(*drawable, states);
} }
MutRef<sf::Drawable> operator->() {
drawable.check();
return drawable.mut();
}
}; };
class View { class View {
std::vector<RenderCall> m_RenderCalls; std::vector<RenderCall> m_RenderCalls;
protected: protected:
void Rectangle() { void Rectangle(const float x, const float y, sf::Color color = sf::Color::White) {
m_RenderCalls.emplace_back(new sf::RectangleShape(sf::Vector2f(100, 100)), sf::RenderStates()); auto shape = new sf::RectangleShape(sf::Vector2f(x, y));
shape->setFillColor(color);
m_RenderCalls.emplace_back(sf::RenderStates(), shape);
} }
public: public:
@ -97,21 +197,30 @@ namespace cigus::UI {
return m_RenderCalls; return m_RenderCalls;
} }
virtual bool update()
{
return false;
}
void draw() {
if (!m_RenderCalls.empty())
{
m_RenderCalls.clear();
}
body();
}
virtual void body() = 0; virtual void body() = 0;
}; };
class Renderer { class Renderer {
public: public:
explicit Renderer(const Ref<View> &_view) : view(_view) { view->body(); } explicit Renderer(const MutRef<View> &_view) : view(_view) { view->body(); }
void destroy() { MutRef<View> view;
view.free();
}
Ref<View> view;
void update() { void update() {
view->body(); if (view->update())
view->draw();
} }
void render(sf::RenderTarget &target, const sf::RenderStates &states) const { void render(sf::RenderTarget &target, const sf::RenderStates &states) const {

View file

@ -8,9 +8,16 @@
class NewView : public cigus::UI::View { class NewView : public cigus::UI::View {
public: public:
bool update() override
{
std::cout << "Update...\n";
return true;
}
void body() override { void body() override {
std::cout << "Hello World!" << std::endl; std::cout << "Body\n";
Rectangle(); //Rectangle(100, 100, sf::Color(250,250,250));
Rectangle(10,20, sf::Color(120,120,120));
} }
}; };
@ -20,7 +27,8 @@ int main(int argc, char** argv) {
sf::RenderWindow window(sf::VideoMode({800, 600}), "Hello World!"); sf::RenderWindow window(sf::VideoMode({800, 600}), "Hello World!");
window.setFramerateLimit(60); window.setFramerateLimit(60);
UI::Renderer renderer(cigus::Ref<UI::View>(new NewView())); cigus::OriginRef<UI::View> view = cigus::OriginRef<UI::View>(new NewView);
UI::Renderer renderer(view);
while (window.isOpen()) { while (window.isOpen()) {
@ -32,12 +40,12 @@ int main(int argc, char** argv) {
} }
} }
renderer.update();
window.clear(); window.clear();
renderer.render(window, sf::RenderStates()); renderer.render(window, sf::RenderStates());
window.display(); window.display();
} }
renderer.destroy();
return 0; return 0;
} }