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

Author Topic: different results on several compiles with same code  (Read 6286 times)

0 Members and 1 Guest are viewing this topic.

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
different results on several compiles with same code
« on: November 27, 2013, 02:15:18 pm »
My obvious goal is to get a button class in which changes color on mouse hovering over the button. I have 2 problems. 1) if i recompile time after time again, sometimes it prints correctly when the mouse is inside the rectangel, sometimes it prints when the mouse is bleow the rectangle. It is different each time compiling. 2) At the time it does display correctly when the mouse is inside the rectangle, i expected it to change color bassed on is_hovering bool value. However the color never changes, yet the display messages do?

I tried minimizing it, but i am not sure how to minimize it more without losing a working example.

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>


class Button{
    public:
        sf::Vector2f position;
        sf::RectangleShape rect;
        bool is_hovering;
        int width, height;
       
        Button(){
            rect.setFillColor(sf::Color(200,200,200));
        }
           
        void create(float w, float h, float x, float y){
            width = w;
            height = h;
            position = {x,y};
            rect.setSize(sf::Vector2f(w,h));
            rect.setPosition(position);
        }
       

       
        void update(sf::Vector2i mouse){
            if (mouse.x > position.x &&
            mouse.x < (position.x + width) &&
            mouse.y > position.y &&
            mouse.y < position.y + height){
                std::cout << "inside rect" << std::endl;
                is_hovering = true;
            }
            else
                std::cout << std::endl;
                is_hovering = false;
           
            if (is_hovering)
                rect.setFillColor(sf::Color(50,50,50));
            else
                rect.setFillColor(sf::Color(200,200,200));
        }
};

class Control{
    public:
        sf::RenderWindow window;
        sf::Clock clock;
        sf::Time frame_time = sf::seconds(1.f/60.f);
        sf::Time time = sf::Time::Zero, update_time = sf::Time::Zero;
        sf::Vector2i mouse;
        Button button;
       
        Control(){
            window.create(sf::VideoMode(600,400), "Title");
            button.create(100,20, 100,100);
            //window.setKeyRepeatEnabled(false);
        }
       
        void update(){
            mouse = sf::Mouse::getPosition(window);
           
            time = clock.restart();
            update_time += time;

            while(update_time > frame_time){
                update_time -= frame_time;
                button.update(mouse);
            }
            render();
        }
       
        void render(){
            window.clear(sf::Color::Black);
            window.draw(button.rect);
            window.display();
        }
       
        void event_handler(sf::Event event){
            while(window.pollEvent(event)){
                if (event.type == sf::Event::Closed)
                    window.close();
            }
        }
       
        void run(){
            while (window.isOpen()){
                sf::Event event;
                event_handler(event);
                update();
            }
        }
};

int main(){
    Control app;
    app.run();
}
 
« Last Edit: November 27, 2013, 03:39:18 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: different results on several compiles
« Reply #1 on: November 27, 2013, 02:33:32 pm »
Quote
1) if i recompile time after time again, sometimes it prints correctly when the mouse is inside the rectangel, sometimes it prints when the mouse is bleow the rectangle. It is different each time compiling.
Can't reproduce.

Quote
2) At the time it does display correctly when the mouse is inside the rectangle, i expected it to change color bassed on is_hovering bool value. However the color never changes, yet the display messages do?
Without // !! lines you always set is_hovering to false and use the non hover color all the time:
if (mouse.x > position.x &&
mouse.x < (position.x + width) &&
mouse.y > position.y &&
mouse.y < position.y + height){
    std::cout << "inside rect" << std::endl;
    is_hovering = true;
}
else
{// !!
    std::cout << std::endl;
    is_hovering = false;
}// !!
 
Back to C++ gamedev with SFML in May 2023

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: different results on several compiles
« Reply #2 on: November 27, 2013, 02:56:51 pm »
I suspect its because you sometimes maximize the window before testing. You have to either catch the resize event and adapt the window accordingly or you need to always use mapPixelToCoords on the coordinates you got for the mouse.
I would also think it is better you only update the coordinates when you get a mouse event from the included data and not always read mouse status.

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles
« Reply #3 on: November 27, 2013, 03:07:19 pm »
Quote
Can't reproduce.
I posted this to represent my problem.
Note i did this before i read your second part regarding the missing brackets
http://www.youtube.com/watch?v=Yy1fRtQCXlo&feature=youtu.be
Also the execute button is not just re-running, but also recompiling via:
g++ -std=c++11 -Wall -o "%e" "%f" -lsfml-audio -lsfml-graphics -lsfml-window -lsfml-system &&"./%e"


and 2), ah thanks, I guess i should just always put the brackets when i put one line of code being the fact that i add a line and forget to add the brackets. thanks.

EDIT:
deleted original youtube video and thus replaced previous link with latest link
« Last Edit: November 30, 2013, 11:38:07 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles
« Reply #4 on: November 27, 2013, 03:24:02 pm »
Quote
I suspect its because you sometimes maximize the window before testing. You have to either catch the resize event and adapt the window accordingly or you need to always use mapPixelToCoords on the coordinates you got for the mouse.
I do not change the window size at all. Is this still accurate if i do not?

Quote
I would also think it is better you only update the coordinates when you get a mouse event from the included data and not always read mouse status.
To be 100% honest, i am not exactly sure what you mean by this?
« Last Edit: November 27, 2013, 03:26:04 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: different results on several compiles
« Reply #5 on: November 27, 2013, 03:39:49 pm »
As long as there is a resize button on the window you want to be compatible to it. Some people click it even without thinking about it.

You call pollEvent, but you throw away all the information you get instead of using it. You should read the tutorial about all event types. Then you dont need to call Mouse::getPosition anymore. Thats because the mouse does not always move on every frame.
Even worse you have a useless busy loop that calls Button::update a million times with the same data that prevents your program from getting fresh events.

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles with same code
« Reply #6 on: November 27, 2013, 03:51:42 pm »
Quote
As long as there is a resize button on the window you want to be compatible to it. Some people click it even without thinking about it.
I tried it without touching the window at all to ensure not touching the window resize. However, it still has the same results. I also added sf::Style::Titlebar | sf::Style::Close to window.create() to disable winodw resizing, however i still get the same results.

Quote
You call pollEvent, but you throw away all the information you get instead of using it. You should read the tutorial about all event types. Then you dont need to call Mouse::getPosition anymore. Thats because the mouse does not always move on every frame.
I have read the tutorials. I actually have spent the past few days re-reading and re-reading the tutorials. I have at least read events tutorial page 4 times yesterday. If you are referring to specific method, i would advise you to note that method. No where in this quote do you suggest what specifc event you are referring to. If you are referring to sf::Event::MouseMoved, however i dont know, because you do not say... why use that over this method? Plus i do not see where that would cause such strange behavior with the button class?

Quote
Even worse you have a useless busy loop that calls Button::update a million times with the same data that prevents your program from getting fresh events.
ah ok. Thanks. That makes sense. I had that there after reading the SMFL book. Although now i am not sure why the SFML book states to even have that loop in the first place.
        void update(){
            mouse = sf::Mouse::getPosition(window);
            button.update(mouse);
           
            time = clock.restart();
            update_time += time;

            while(update_time > frame_time){
                update_time -= frame_time;

            }
            render();
        }
« Last Edit: November 27, 2013, 04:12:33 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: different results on several compiles with same code
« Reply #7 on: November 27, 2013, 04:16:57 pm »
I was speaking of this tutorial: http://sfml-dev.org/tutorials/2.1/window-events.php
There is some updated code:
        void update() {
        }

        void event_handler() {
            sf::Event event;
            while(window.pollEvent(event)) {
                if (event.type == sf::Event::Closed)
                    window.close();
                else if(event.type == sf::Event::MouseMoved)
                    button.update(window.mapPixelToCoords(sf::Vector2i(event.mouseMove.x,event.mouseMove.y)));
            }
        }
     
        void run(){
            while (window.isOpen()){
                event_handler();
                update();
                render();
            }
        }

 
« Last Edit: November 27, 2013, 04:21:03 pm by wintertime »

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles with same code
« Reply #8 on: November 27, 2013, 04:33:21 pm »
Here is the entire code with that implemented. Your method looks a lot more complex for something i do not understand the benfits of, as it does the same thing as sf::Mouse::getPosition(window) and sending it to Button::update.
Regardless...(if this code is correct in what you meant) the original problem of the OP #1 still exists in the matter of the button gets hovered color sometimes when the mouse is off below the button and somtimes compiled when the mouse is on hte button. identical to the video clip.

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>


class Button{
    public:
        sf::Vector2f position;
        sf::RectangleShape rect;
        bool is_hovering;
        int width, height;
       
        Button(){
            rect.setFillColor(sf::Color(200,200,200));
        }
           
        void create(float w, float h, float x, float y){
            width = w;
            height = h;
            position = {x,y};
            rect.setSize(sf::Vector2f(w,h));
            rect.setPosition(position);
        }
       

       
        void update(sf::Vector2f mouse){
            if (mouse.x > position.x &&
            mouse.x < (position.x + width) &&
            mouse.y > position.y &&
            mouse.y < position.y + height){
                is_hovering = true;
            }
            else{
                is_hovering = false;
            }
           
            if (is_hovering)
                rect.setFillColor(sf::Color(50,50,50));
            else
                rect.setFillColor(sf::Color(200,200,200));
        }
};

class Control{
    public:
        sf::RenderWindow window;
        sf::Clock clock;
        sf::Time frame_time = sf::seconds(1.f/60.f);
        sf::Time time = sf::Time::Zero, update_time = sf::Time::Zero;
        sf::Vector2i mouse;
        Button button;
       
        Control(){
            window.create(sf::VideoMode(600,400), "Title", sf::Style::Titlebar | sf::Style::Close);
            button.create(100,20, 100,100);
            //window.setKeyRepeatEnabled(false);
        }
       
        void time_update(){
            time = clock.restart();
            update_time += time;

            while(update_time > frame_time){
                update_time -= frame_time;

            }
        }
       
        void update(){
            time_update();
            mouse = sf::Mouse::getPosition(window);
            //button.update(mouse);
           

            render();
        }
       
        void render(){
            window.clear(sf::Color::Black);
            window.draw(button.rect);
            window.display();
        }
       
        void event_handler(){
            sf::Event event;
            while(window.pollEvent(event)){
                if (event.type == sf::Event::Closed)
                    window.close();
                else if(event.type == sf::Event::MouseMoved)
                    button.update(window.mapPixelToCoords(sf::Vector2i(event.mouseMove.x,event.mouseMove.y)));
            }
        }
       
        void run(){
            while (window.isOpen()){
                event_handler();
                update();
            }
        }
};

int main(){
    Control app;
    app.run();
}
 
« Last Edit: November 27, 2013, 04:36:24 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles with same code
« Reply #9 on: November 27, 2013, 04:56:13 pm »
well this is quite interesting...
If i compile the previous post's code in Ubuntu 12.04.3, i do not have any problems that i can see. The button always gets highlighted. I tried it about 20 times. Same thing every time. However in Arch Linux, with the same code compiled, most of the time the button gets highlighted, but roughly 1/4 the time i get the problem of the mouse having to be below the button for it to get highlighted. I tried this about 20 times with having this problem about 4 of those times. Such like: http://www.youtube.com/watch?v=Yy1fRtQCXlo&feature=youtu.be
Note the last 2 compiling/runs.

Now my question is what is different about arch and ubuntu. Both of my distros have the required libs for SFML, obviously otherwise they would not compile at all. I normally blame my code first, but i think this time the only thing i can think of is a bug in SFML. Can another Arch Linux user compile this code and have it work 100% of the time?

Both my Arch and Ubuntu are using SFML 2.1 64 bit
« Last Edit: November 27, 2013, 06:30:55 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: different results on several compiles with same code
« Reply #10 on: November 27, 2013, 11:11:03 pm »
Could you please make this example more minimal (and thus more readable)? There are a lot of unused stuff (update_time, mouse, ...) and it's hard to follow the logic with everything split up in small parts. A single main() with everything directly written would be great, instead of those useless levels of abstraction.
Laurent Gomila - SFML developer

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles with same code
« Reply #11 on: November 27, 2013, 11:43:18 pm »
Quote
Could you please make this example more minimal

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>





int main(){
    sf::RenderWindow window(sf::VideoMode(600,400), "Title", sf::Style::Titlebar | sf::Style::Close);
   
    sf::Vector2f position;
    sf::RectangleShape rect;
    int width, height;
   
    rect.setFillColor(sf::Color(200,200,200));
    width = 100;
    height = 20;
    position = {100,100};
    rect.setSize(sf::Vector2f(width, height));
    rect.setPosition(position);
   
    sf::Vector2i mouse;

    while (window.isOpen()){
        mouse = sf::Mouse::getPosition(window);
        sf::Event event;
        while(window.pollEvent(event)){
            if (event.type == sf::Event::Closed)
                window.close();
            else if(event.type == sf::Event::MouseMoved){
                if (mouse.x > position.x &&
                mouse.x < (position.x + width) &&
                mouse.y > position.y &&
                mouse.y < position.y + height){
                    rect.setFillColor(sf::Color(50,50,50));
                }
                else{
                    rect.setFillColor(sf::Color(200,200,200));
                }
            }
        }
        window.clear(sf::Color::Black);
        window.draw(rect);
        window.display();
    }
}
I tried this is Ubuntu 12.04.3 and Windows 8 and they both seem to work 100% of the time. It appears to only happen in Arch.
« Last Edit: November 28, 2013, 01:10:30 am by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: different results on several compiles with same code
« Reply #12 on: November 28, 2013, 02:18:39 am »
I don't know if anyone else noticed, but the problem doesn't lie in the mouse collision detection or event handling at all. If you look very carefully at the video(s), you will notice the position of the sf::RectangleShape changes between executions. Maybe this is a sign that I've been working on GUIs for too long 8).

You can throw out the collision detection code and all the event handling, and it might probably still occur that the sf::RectangleShape doesn't stay in the same position although the hardcoded position doesn't change, and that is the real problem, not the fact that the collision is not properly detected. The collision detection uses data that is saved in the user code, not the data representation inside SFML. If you were to query the sf::RectangleShape for its position in one of those broken executions, it would probably return some bogus values.

The only critical places I would look at are:
sf::Vector2f position;
...
position = {100,100};
...
rect.setPosition(position);
When initially constructing the sf::Vector2f, its constructor sets both x and y values to 0, regardless of data type, no narrowing conversion should ever be required.
The second one is a bit trickier. Normally you would be able to initialize data structures using aggregate initialization with the { 1, 2, 3 }; syntax, but only if the object doesn't have any user defined constructors, which sf::Vector<T> has. So in C++03 that syntax would be illegal. It only works because -std=c++11 is used. In C++11 it isn't about aggregate initialization any more. That expression evaluates to a construction of a new sf::Vector2f to assign to position due to uniform initialization. In this case as well, a non-narrowing conversion has to be performed.
The last spot is when the position is finally passed on to SFML. Since SFML takes the parameter by reference, I don't see much opportunity for anything to go wrong there.

Obviously, something is going wrong somewhere. The executable produced by the compiler/linker should stay the same unless your disk was dying in the process of your testing. The only spot I could think of where something might go wrong is during the conversion from int to float. Normally it should not be a problem since it is not a narrowing conversion, but considering something has to be a problem, that would be the most likely candidate, short of random memory corruption due to broken RAM, a broken disk, a broken processor, or (since it only happens on Arch) a broken runtime environment and/or kernel.

I would try to minimize the opportunities for the culprit to mess with your data and try to avoid unnecessary conversions, as is the case in all your code examples. Also, try to print out the data before it gets passed over to SFML, even though it should be what you would expect, better safe than sorry. Over time developers learn to trust their compiler and runtime environments, but a little scepticism can go a long way sometimes, especially when something has to obviously be broken.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

metulburr

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: different results on several compiles with same code
« Reply #13 on: November 30, 2013, 03:29:10 pm »
it took me awhile to test it to ensure it was still happening as i did get a kernel update and had to re-compile it. Although it still happens with the newer kernel.

All in all, now it happens 1/20 of the time in arch for some reason, regardless of being float or int. Which makes it worse. As it is even harder to test.

Quote
The only spot I could think of where something might go wrong is during the conversion from int to float. Normally it should not be a problem since it is not a narrowing conversion, but considering something has to be a problem, that would be the most likely candidate,
changing everything to float to ensure there is no conversion, i also still get the same problem.



It is driving me nuts as i am not sure i can safely move around in distros and expect the same results with SFML.

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>

int main(){
    sf::RenderWindow window(sf::VideoMode(600,400), "Title", sf::Style::Titlebar | sf::Style::Close);
   
    sf::Vector2f position;
    sf::RectangleShape rect;
    float width, height;
   
    rect.setFillColor(sf::Color(200,200,200));
    width = 100.0;
    height = 20.0;
    position = {100.0,100.0};
    rect.setSize(sf::Vector2f(width, height));
    rect.setPosition(position);
   
    sf::Vector2i mouse;

    while (window.isOpen()){
        mouse = sf::Mouse::getPosition(window);
        sf::Event event;
        while(window.pollEvent(event)){
            if (event.type == sf::Event::Closed)
                window.close();
            else if(event.type == sf::Event::MouseMoved){
                if (mouse.x > position.x &&
                mouse.x < (position.x + width) &&
                mouse.y > position.y &&
                mouse.y < position.y + height){
                    rect.setFillColor(sf::Color(50,50,50));
                }
                else{
                    rect.setFillColor(sf::Color(200,200,200));
                }
            }
        }
        window.clear(sf::Color::Black);
        window.draw(rect);
        window.display();
    }
}
« Last Edit: November 30, 2013, 03:30:52 pm by metulburr »
OS Ubuntu 13.04, Arch Linux, Gentoo, Windows 7/8
SFML 2.1
Ati Radeon HD 6770

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: different results on several compiles with same code
« Reply #14 on: November 30, 2013, 04:31:48 pm »
Did you already try using a debugger and watching the values as they get passed around?
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).