Updating Ref system. [segvault]
This commit is contained in:
parent
0ca3c9cc64
commit
1bc396c4b2
3 changed files with 162 additions and 45 deletions
|
@ -5,7 +5,7 @@ project(cigus
|
|||
LANGUAGES CXX)
|
||||
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
|
|
187
cigus.hpp
187
cigus.hpp
|
@ -8,33 +8,103 @@
|
|||
namespace cigus {
|
||||
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>
|
||||
class Ref {
|
||||
T *ptr;
|
||||
protected:
|
||||
T *ptr = nullptr;
|
||||
|
||||
public:
|
||||
explicit Ref(T *ptr) : ptr(ptr) {
|
||||
if (ptr == nullptr) {
|
||||
spdlog::error("Ref<T> cannot be null");
|
||||
throw std::runtime_error("Ref<T> cannot be null");
|
||||
virtual ~Ref() {}
|
||||
Ref() = delete;
|
||||
Ref(const Ref &other) = delete;
|
||||
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) {
|
||||
if (other.ptr == nullptr) {
|
||||
spdlog::error("Ref<T> cannot be null");
|
||||
throw std::runtime_error("Ref<T> cannot be null");
|
||||
}
|
||||
[[nodiscard]] MutRef<T> mut() {
|
||||
return MutRef<T>(this->ptr);
|
||||
}
|
||||
|
||||
Ref(Ref &&other) noexcept : ptr(other.ptr) {
|
||||
if (other.ptr == nullptr) {
|
||||
spdlog::error("Ref<T> cannot be null");
|
||||
throw std::runtime_error("Ref<T> cannot be null");
|
||||
[[nodiscard]] ConstRef<T> immute() const {
|
||||
return ConstRef<T>(this->ptr);
|
||||
}
|
||||
};
|
||||
|
||||
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) {
|
||||
ptr = other.ptr;
|
||||
}
|
||||
|
@ -42,52 +112,82 @@ namespace cigus {
|
|||
}
|
||||
|
||||
T &operator*() {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
const T &operator*() const {
|
||||
check();
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
T *operator->() {
|
||||
check();
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
const T *operator->() const {
|
||||
return ptr;
|
||||
template<typename T>
|
||||
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() {
|
||||
delete ptr;
|
||||
ptr = nullptr;
|
||||
ConstRef(const MutRef<T> other) : Ref<T>(other.ptr) {
|
||||
}
|
||||
};
|
||||
|
||||
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 {
|
||||
class RenderCall {
|
||||
sf::Drawable *drawable;
|
||||
OriginRef<sf::Drawable> drawable;
|
||||
sf::RenderStates states;
|
||||
|
||||
public:
|
||||
RenderCall(sf::Drawable *drawable, sf::RenderStates states) : drawable(drawable), states(states) {
|
||||
}
|
||||
|
||||
~RenderCall() {
|
||||
delete drawable;
|
||||
explicit RenderCall(const sf::RenderStates& states, sf::Drawable *ptr) : drawable(ptr), states(states) {
|
||||
drawable.check();
|
||||
}
|
||||
|
||||
void draw(sf::RenderTarget &target, const sf::RenderStates &states) const {
|
||||
target.draw(*drawable, states);
|
||||
}
|
||||
|
||||
MutRef<sf::Drawable> operator->() {
|
||||
drawable.check();
|
||||
return drawable.mut();
|
||||
}
|
||||
};
|
||||
|
||||
class View {
|
||||
std::vector<RenderCall> m_RenderCalls;
|
||||
|
||||
protected:
|
||||
void Rectangle() {
|
||||
m_RenderCalls.emplace_back(new sf::RectangleShape(sf::Vector2f(100, 100)), sf::RenderStates());
|
||||
void Rectangle(const float x, const float y, sf::Color color = sf::Color::White) {
|
||||
auto shape = new sf::RectangleShape(sf::Vector2f(x, y));
|
||||
shape->setFillColor(color);
|
||||
m_RenderCalls.emplace_back(sf::RenderStates(), shape);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -97,21 +197,30 @@ namespace cigus::UI {
|
|||
return m_RenderCalls;
|
||||
}
|
||||
|
||||
virtual bool update()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void draw() {
|
||||
if (!m_RenderCalls.empty())
|
||||
{
|
||||
m_RenderCalls.clear();
|
||||
}
|
||||
body();
|
||||
}
|
||||
virtual void body() = 0;
|
||||
};
|
||||
|
||||
class Renderer {
|
||||
public:
|
||||
explicit Renderer(const Ref<View> &_view) : view(_view) { view->body(); }
|
||||
explicit Renderer(const MutRef<View> &_view) : view(_view) { view->body(); }
|
||||
|
||||
void destroy() {
|
||||
view.free();
|
||||
}
|
||||
|
||||
Ref<View> view;
|
||||
MutRef<View> view;
|
||||
|
||||
void update() {
|
||||
view->body();
|
||||
if (view->update())
|
||||
view->draw();
|
||||
}
|
||||
|
||||
void render(sf::RenderTarget &target, const sf::RenderStates &states) const {
|
||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -8,9 +8,16 @@
|
|||
|
||||
class NewView : public cigus::UI::View {
|
||||
public:
|
||||
bool update() override
|
||||
{
|
||||
std::cout << "Update...\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
void body() override {
|
||||
std::cout << "Hello World!" << std::endl;
|
||||
Rectangle();
|
||||
std::cout << "Body\n";
|
||||
//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!");
|
||||
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()) {
|
||||
|
||||
|
@ -32,12 +40,12 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
renderer.update();
|
||||
|
||||
window.clear();
|
||||
renderer.render(window, sf::RenderStates());
|
||||
window.display();
|
||||
}
|
||||
renderer.destroy();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue