Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Exception thrown every time sf::RenderWindow draws something from an std::vector  (Read 2000 times)

0 Members and 1 Guest are viewing this topic.

Keameng Ong

  • Newbie
  • *
  • Posts: 4
    • View Profile
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.

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
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

Keameng Ong

  • Newbie
  • *
  • Posts: 4
    • View Profile
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.)

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
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
« Last Edit: March 23, 2020, 09:54:22 am by Fx8qkaoy »

Keameng Ong

  • Newbie
  • *
  • Posts: 4
    • View Profile
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

Fx8qkaoy

  • Newbie
  • *
  • Posts: 42
    • View Profile
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

Keameng Ong

  • Newbie
  • *
  • Posts: 4
    • View Profile
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.
« Last Edit: March 24, 2020, 09:00:24 am by Keameng Ong »