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

Author Topic: sf::NonCopyable error?  (Read 2895 times)

0 Members and 1 Guest are viewing this topic.

Inflammatory Nugget

  • Newbie
  • *
  • Posts: 21
    • View Profile
sf::NonCopyable error?
« on: July 31, 2013, 07:58:47 pm »
Greetings,

I have been fiddling around with SFML recently, and I wrote the following program:
#include <iostream>
#include <SFML\Graphics.hpp>
#include <SFML\Window.hpp>
#include <SFML\Audio.hpp>
#include <SFML\System.hpp>
using namespace std;

struct main_variables{
public:
        sf::Sound main_variables::clock_ticking_1;
        sf::RenderWindow main_variables::application;
        int main_variables::seconds;
};

bool timer(main_variables& m_1);
bool sound_player(main_variables& m_1);

int main(){
        // main variables
        main_variables m;
        m.seconds = 0;
        // icon
        sf::Image icon;
        if(!icon.loadFromFile("data/clock_icon.png"))
                return 1;
        m.application.setIcon(32, 32, icon.getPixelsPtr());
        m.application.create(sf::VideoMode(300, 300, 64), "Clock", sf::Style::Close);
        m.application.setFramerateLimit(30);
        // clock_t
        sf::Texture clock_t;
        if(!clock_t.loadFromFile("data/clock.png"))
                return 1;
        // long_pointer_t
        sf::Texture long_pointer_t;
        if(!long_pointer_t.loadFromFile("data/clock_long_pointer.png"))
                return 1;
        // short_pointer_t
        sf::Texture short_pointer_t;
        if(!short_pointer_t.loadFromFile("data/clock_short_pointer.png"))
                return 1;
        // longest pointer_t
        sf::Texture longest_pointer_t;
        if(!longest_pointer_t.loadFromFile("data/clock_longest_pointer.png"))
                return 1;
        short_pointer_t.setSmooth(1);
        // clock
        sf::RectangleShape clock(sf::Vector2f(300,300));
        clock.setTexture(&clock_t);
        clock.setPosition(0, 0);
        // long_pointer
        sf::RectangleShape long_pointer(sf::Vector2f(125,20));
        long_pointer.setTexture(&long_pointer_t);
        long_pointer.setOrigin(5,10);
        long_pointer.setPosition(150, 150);
        // short pointer
        sf::RectangleShape short_pointer(sf::Vector2f(100,20));
        short_pointer.setTexture(&short_pointer_t);
        short_pointer.setOrigin(5,10);
        short_pointer.setPosition(150, 150);
        // longest pointer
        sf::RectangleShape longest_pointer(sf::Vector2f(125,20));
        longest_pointer.setTexture(&longest_pointer_t);
        longest_pointer.setOrigin(5,10);
        longest_pointer.setPosition(150, 150);
        // sound
        sf::SoundBuffer clock_ticking_1_b;
        if(!clock_ticking_1_b.loadFromFile("data/clock_ticking_2.wav"));
        sf::Sound clock_ticking_1;

        clock_ticking_1.setBuffer(clock_ticking_1_b);
        // event
        sf::Event event;
        // threads
        sf::Thread timer_thread(&timer, m);
        timer_thread.launch();
        sf::Thread sound_player_thread(&sound_player, m);
        sound_player_thread.launch();

        while(m.application.isOpen()){
                while(m.application.pollEvent(event)){
                        if (event.type == sf::Event::Closed ||(event.KeyPressed && event.key.code == sf::Keyboard::Escape)){
                                goto exit;
                        }
                }
                if(m.seconds == (60*60*12))
                        m.seconds = 0;
                longest_pointer.setRotation(static_cast<float>(m.seconds*6-90));
                long_pointer.setRotation(static_cast<float>(m.seconds*6/60-90));
                short_pointer.setRotation(static_cast<float>(m.seconds*6/60/60-90));
               
                m.application.clear(sf::Color::Black);
                m.application.draw(clock);
                m.application.draw(short_pointer);
                m.application.draw(long_pointer);
                m.application.draw(longest_pointer);
                m.application.display();
        }
        exit:
                m.application.close();
                cout << "exiting program..." << endl;
                return 0;
}

bool timer( main_variables& m_1){
        while( m_1.application.isOpen()){
                sf::sleep(sf::seconds(1));
                m_1.seconds++;
        }
        return 0;
}

bool sound_player( main_variables& m_1){
        while( m_1.application.isOpen()){
                m_1.clock_ticking_1.play();
                sf::sleep(sf::seconds(10));
        }
        return 0;
}

The output:
1>------ Build started: Project: CppApplication_2, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\frank\documents\visual studio 2010\projects\cppapplication_2\main.cpp(68): warning C4390: ';' : empty controlled statement found; is this the intent?
1>c:\sfml\include\sfml\window\window.hpp(476): error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1>          c:\sfml\include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'
1>          c:\sfml\include\sfml\system\noncopyable.hpp(42) : see declaration of 'sf::NonCopyable'
1>          This diagnostic occurred in the compiler generated function 'sf::Window::Window(const sf::Window &)'
1>c:\sfml\include\sfml\graphics\rendertarget.hpp(419): error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1>          c:\sfml\include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'
1>          c:\sfml\include\sfml\system\noncopyable.hpp(42) : see declaration of 'sf::NonCopyable'
1>          This diagnostic occurred in the compiler generated function 'sf::RenderTarget::RenderTarget(const sf::RenderTarget &)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I have no idea why the compiler gives me these errors. As far as I can see, there are no copies being made of m.application or of m.clock_ticking_1, they are only being passed as a reference.

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: sf::NonCopyable error?
« Reply #1 on: August 01, 2013, 01:31:59 am »
sf::Thread tries to store a copy of your main_variables struct when you write these lines:
sf::Thread timer_thread(&timer, m);
sf::Thread sound_player_thread(&sound_player, m);
 
This is because the sf::Thread constructor is templated, and the compiler deduces the argument you passed as being a value instead of a reference which you expected. This is also the reason why you are getting the "This diagnostic occurred in the compiler generated function" message. std::ref might help you here.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Inflammatory Nugget

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: sf::NonCopyable error?
« Reply #2 on: August 01, 2013, 08:01:48 am »
Thank you for your response. However, I can't used std::ref, because I am using Visual Studio C++ 2010...

I'll have another look at my code and see if I can work around it myself.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: sf::NonCopyable error?
« Reply #3 on: August 01, 2013, 08:06:32 am »
If you can't use std::ref, you can pass a pointer to your threaded function instead of a reference.
Laurent Gomila - SFML developer

Inflammatory Nugget

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: sf::NonCopyable error?
« Reply #4 on: August 01, 2013, 10:19:02 am »
Ah, thank you Laurent! This little piece of advice has been very helpful.

My program now runs perfectly fine.