SFML community forums

Help => General => Topic started by: Keameng Ong on March 22, 2020, 07:59:23 am

Title: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Keameng Ong on March 22, 2020, 07:59:23 am
Hi there!
I'm a C++ newbie, and I'm new to the forum as well. Recently I've been trying to write my own GUI classes, so I can use them in my later projects. While writing a combo box, I stumbled something strange. When I constructed a button I'd written, it was drawn 'perfectly fine' to the window. But when I pushed my button object to std::vector and called it to draw to the screen. This happened: https://drive.google.com/file/d/1QclBCkOzErf6zx9jbKtUh1X36Ox3PzFb/view?usp=sharing
Thanks.
Title: Re: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Fx8qkaoy on March 22, 2020, 10:14:25 am
Hi there!
I'm a C++ newbie, and I'm new to the forum as well. Recently I've been trying to write my own GUI classes, so I can use them in my later projects. While writing a combo box, I stumbled something strange. When I constructed a button I'd written, it was drawn 'perfectly fine' to the window. But when I pushed my button object to std::vector and called it to draw to the screen. This happened: https://drive.google.com/file/d/1QclBCkOzErf6zx9jbKtUh1X36Ox3PzFb/view?usp=sharing
Thanks.

It would've been also useful to provide some code. Try these:
- use a debugger and break before drawing
- make sure u use the "=" operator right
- prepare for us a minimal code which reproduces the problem
Title: Re: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Keameng Ong on March 22, 2020, 11:51:15 am
Hi there!
I'm a C++ newbie, and I'm new to the forum as well. Recently I've been trying to write my own GUI classes, so I can use them in my later projects. While writing a combo box, I stumbled something strange. When I constructed a button I'd written, it was drawn 'perfectly fine' to the window. But when I pushed my button object to std::vector and called it to draw to the screen. This happened: https://drive.google.com/file/d/1QclBCkOzErf6zx9jbKtUh1X36Ox3PzFb/view?usp=sharing
Thanks.

It would've been also useful to provide some code. Try these:
- use a debugger and break before drawing
- make sure u use the "=" operator right
- prepare for us a minimal code which reproduces the problem

Here's the "simplified" version:

//////////BEGIN//////////
#include <iostream>
#include <string>
#include <functional>
#include "SFML/Graphics.hpp"

#define Log(x) std::cout << x << std::endl;

class Button
{
private:
   float x, y, w, h;
   std::string string;
   std::function<void(void)> function;
   sf::Font font;
   sf::RenderWindow* window;
   sf::Event* event;
   sf::Text text;
   sf::RectangleShape rectangle;

   bool is_clicked()
   {
      if (this->event->type == sf::Event::MouseButtonPressed && this->rectangle.getGlobalBounds().contains(sf::Vector2<float>(sf::Mouse::getPosition(*window))))
      {
         return true;
      }
      else
      {
         return false;
      }
   }
public:
   Button(const char* const string, float x, float y, sf::RenderWindow& window, sf::Event& event)
      : x(x), y(y), w(100.f), h(25.f), string(string), window(&window), event(&event)
   {
      this->font.loadFromMemory(SOME_FONT, SOME_FONT_LENGTH);
      this->text.setFont(this->font);
      this->text.setString(this->string);
      this->text.setFillColor(sf::Color::Black);
      this->text.setOrigin(this->text.getGlobalBounds().width / 2.f, this->text.getGlobalBounds().height / 2.f);
      this->text.setPosition(sf::Vector2<float>(this->x + this->w / 2.f, this->y - this->h / 10.f));
      this->rectangle.setPosition(sf::Vector2<float>(this->x, this->y));
      this->rectangle.setSize(sf::Vector2<float>(this->w, this->h));
      this->rectangle.setFillColor(sf::Color::Blue);
   }
   ~Button()
   {

   }
   void draw()
   {
      this->window->draw(this->rectangle);
      this->window->draw(this->text);
   }
   void update()
   {
      if (this->is_clicked())
      {
         this->function();
      }
   }
   void set_function(const std::function<void(void)>& function)
   {
      this->function = function;
   }
};

int main(int argc, char* argv[])
{
   sf::Clock clock;
   sf::Time delta_time = sf::Time::Zero;
   sf::Time fps = sf::seconds(1.f / 60.f);
   sf::RenderWindow window(sf::VideoMode(500, 500), "Sandbox");
   sf::Event event;


   std::vector<Button> list_of_buttons;
   
   list_of_buttons.push_back(Button("Close 1", 25.f, 25.f + list_of_buttons.size() * 25.f, window, event));
   list_of_buttons.push_back(Button("Close 2", 25.f, 25.f + list_of_buttons.size() * 25.f, window, event));
   list_of_buttons.push_back(Button("Close 3", 25.f, 25.f + list_of_buttons.size() * 25.f, window, event));

   for (int i = 0; i < list_of_buttons.size(); i++)
   {
      list_of_buttons.set_function(std::function<void(void)>([&window]() {window.close(); }));
   }

   while (window.isOpen())
   {
      while (window.pollEvent(event))
      {
         switch (event.type)
         {
         case sf::Event::Closed:
            window.close();
            break;
         default:
            break;
         }

         //Update
         {
            for (int i = 0; i < list_of_buttons.size(); i++)
            {
               list_of_buttons.update();
            }
         }

         if (delta_time > fps)
         {
            delta_time -= fps;

            //Render
            {
               window.clear(sf::Color::White);

               for (int i = 0; i < list_of_buttons.size(); i++)
               {
                  list_of_buttons.draw();
               }

               window.display();
            }

         }
         delta_time += clock.restart();
      }
   }
   return 0;
}
///////////END///////////

https://drive.google.com/open?id=1Bu4cYQusKCf8MdwbWJ2_eypGI6SXqZgP

Although I rewrote the code, the problem is the same. (What I want to achieve is creating a list of buttons.)
Title: Re: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Fx8qkaoy on March 23, 2020, 09:50:38 am
Here's the "simplified" version:

BEGIN
END

https://drive.google.com/open?id=1Bu4cYQusKCf8MdwbWJ2_eypGI6SXqZgP

Although I rewrote the code, the problem is the same. (What I want to achieve is creating a list of buttons.)

I was able to run the program and while it doesn't throw any exception, it also displays the text (see attachment). When stuff is trivial, the simple fact that u're trying to build a minimal code reveals the problem on the way
Title: Re: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Keameng Ong on March 23, 2020, 04:09:06 pm
Here's the "simplified" version:

BEGIN
END

https://drive.google.com/open?id=1Bu4cYQusKCf8MdwbWJ2_eypGI6SXqZgP

Although I rewrote the code, the problem is the same. (What I want to achieve is creating a list of buttons.)

I was able to run the program and while it doesn't throw any exception, it also displays the text (see attachment). When stuff is trivial, the simple fact that u're trying to build a minimal code reveals the problem on the way

Strange. When I compiled and ran my code, this happened:
https://drive.google.com/open?id=1WfHXfHpFPJ83dWvCUyZTBD0tjNgnRPEB
Title: Re: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Fx8qkaoy on March 23, 2020, 06:23:19 pm
Strange. When I compiled and ran my code, this happened:
https://drive.google.com/open?id=1WfHXfHpFPJ83dWvCUyZTBD0tjNgnRPEB

I would bet it's because u're not loading the font from the memory the right way, it is corruped, etc. This should've been the single different thing from our sources
Title: Re: Exception thrown every time sf::RenderWindow draws something from an std::vector
Post by: Keameng Ong on March 24, 2020, 03:03:16 am
Strange. When I compiled and ran my code, this happened:
https://drive.google.com/open?id=1WfHXfHpFPJ83dWvCUyZTBD0tjNgnRPEB

I would bet it's because u're not loading the font from the memory the right way, it is corruped, etc. This should've been the single different thing from our sources
If my font were corrupted, I wouldn't be able to draw a single button to the screen. BTW I loaded my font from an array of chars and the length of the font I've got from xxd on my Linux machine. Does that mean loading from memory is the problem?

Edit: I tried to load from file, and the result was the same.

Edit: I finally found the solution. The problem was that I constructed objects in the parentheses. So when they were out of scope, they got destroyed. Sorry.