SFML community forums

Help => General => Topic started by: iride on January 02, 2013, 04:08:27 am

Title: A crash in my button class
Post by: iride on January 02, 2013, 04:08:27 am
Here's my button class
#include <SFML/Graphics.hpp>
#include <functional>

class Button
{
public:
        static void init(sf::RenderWindow & window);
private:
        static sf::RenderWindow * window;
        sf::Text text;
        std::function<void(void)>  onEnter;
        std::function<void(void)>  onExit;
        std::function<void(void)>  onClick;
public:
        Button(const char * string, sf::Font & font, sf::Color color, sf::Vector2f position, unsigned int size);
        ~Button();
        sf::Text & getText(){return text;}
        void draw();
        void update();
        void connect(std::function<void(void)>  onEnter, std::function<void(void)>  onExit ,std::function<void(void)>  onClick);
};
#include "Button.h"
#include <SFML/Window.hpp>

sf::RenderWindow * Button::window =nullptr;

void Button::init(sf::RenderWindow & window_)
{
        window=&window_;
}

Button::Button(const char * string, sf::Font & font, sf::Color color, sf::Vector2f position, unsigned int size):text(string, font, size)
{
        text.setColor(color);
        text.setPosition(position);
}

Button::~Button()
{
}

void Button::update()
{
        sf::Vector2i mousePos=sf::Mouse::getPosition(*window);
        float x1=text.getGlobalBounds().left;
        float x2=x1+text.getGlobalBounds().width;
        float y1=text.getGlobalBounds().top;
        float y2=y1+text.getGlobalBounds().height;
        if(x1<=mousePos.x && mousePos.x<=x2 && y1<=mousePos.y && mousePos.y<=y2)
        {
                (onEnter)();
                if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
                        (onClick)();
        }
        else
               (onExit)();
}

void Button::connect(std::function<void(void)> onEnter, std::function<void(void)>  onExit,  std::function<void(void)>  onClick)
{
        this->onEnter=onEnter;
        this->onExit=onExit;
        this->onClick=onClick;
}

void Button::draw()
{
        window->draw(text);
}
 

crash occurs in Button::draw() method.
Is there something wrong with my code?
Title: Re: A crash in my button class
Post by: masskiller on January 02, 2013, 05:00:44 am
Have you checked if the pointer is valid at drawing time? If not it could be a Segmentation Fault. It would also be good to make drawing conditional in case the pointer hasn't been set, regardless of whether that's the issue or not.
Title: Re: A crash in my button class
Post by: iride on January 02, 2013, 05:10:49 am
I edited my code so that it uses boost::signal
But the crash still occurs
class Button
{
private:
        sf::Text text;
        boost::signal<void()> onEnter;
        boost::signal<void()> onExit;
        boost::signal<void()> onClick;
        void update(sf::RenderWindow & window);
public:
        Button(const char * string, sf::Font & font, sf::Color color, sf::Vector2f position, unsigned int size);
        ~Button();
        sf::Text & getText(){return text;}
        void draw(sf::RenderWindow & window);
        void connect(std::function<void()>  onEnter, std::function<void()>  onExit ,std::function<void()> onClick);
};
 

#include "Button.h"
#include <SFML/Window.hpp>

Button::Button(const char * string, sf::Font & font, sf::Color color, sf::Vector2f position, unsigned int size):text(string, font, size)
{
        text.setColor(color);
        text.setPosition(position);
}

Button::~Button()
{
}

void Button::update(sf::RenderWindow & window)
{
        sf::Vector2i mousePos=sf::Mouse::getPosition(window);
        float x1=text.getGlobalBounds().left;
        float x2=x1+text.getGlobalBounds().width;
        float y1=text.getGlobalBounds().top;
        float y2=y1+text.getGlobalBounds().height;
        if(x1<=mousePos.x && mousePos.x<=x2 && y1<=mousePos.y && mousePos.y<=y2)
        {
                (onEnter)();
                if(sf::Mouse::isButtonPressed(sf::Mouse::Button::Left))
                        (onClick)();
        }
        (onExit)();
}

void Button::connect(std::function<void(void)> onEnter, std::function<void(void)>  onExit,  std::function<void(void)>  onClick)
{
        this->onEnter.connect(onEnter);
        this->onExit.connect(onExit);
        this->onClick.connect(onClick);
}

void Button::draw(sf::RenderWindow & window)
{
        update(window);
        window.draw(text);
}

Weird thing is that even if I don't call update() or window.draw(), my program still crashes when the Button destructor gets called...

Here's how I'm using my button class
button=new Button("Hello, World!", font(), sf::Color::Black, sf::Vector2f(100, 100), 40);
        button->connect([&](){button->getText().setCharacterSize(50);},
                                        [&](){button->getText().setCharacterSize(40);},
                                        [&](){std::cout<<"YOU CLICKED ME\n!";});
Title: AW: A crash in my button class
Post by: eXpl0it3r on January 02, 2013, 09:12:00 am
It's not so weird, it just speaks for a faulty code. The biggest problem I see is the static or better global window pointer.
Also you shouldn't use manual memory management (new/delete), but use smart pointers. ;)
Title: Re: A crash in my button class
Post by: masskiller on January 02, 2013, 04:05:17 pm
Quote
Weird thing is that even if I don't call update() or window.draw(), my program still crashes when the Button destructor gets called...

Deleting memory twice without realizing?