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

Author Topic: Using a window management class without copying a renderWindow?  (Read 7125 times)

0 Members and 1 Guest are viewing this topic.

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
      So I've been trying to come up with a decent, yet simple way to do this, and I really can't think of anything. I've tried it many ways so far, all of which throw a non copyable error because the render window was copied and sent back to the requesting class/method.

       I just wanted to make it that a outside class could control the functions of creating/destroying/modifying/reloading the render window for instances of setting changes, like resolution changes, or switching from full screen to windowed.

        So far what I have, and yes I KNOW this won't work, and now looking at it, it seems kind of stupid given that it will throw an error the moment you even think of soing it this way. But I just wanted to ask for some input and or ideas on the subject, as for a practical way to do this.

in Main.cpp
        WindowEngine windowEngine;
        sf::RenderWindow mainWindow = windowEngine.LaunchEngineWindow();
 

int WindowEngine.cpp
sf::RenderWindow WindowEngine::LaunchEngineWindow(void)
{
        int Height = 0;
        int Width = 0;

        GetScreenResolution(Height,Width);

        sf::RenderWindow mainWindow(sf::VideoMode(Width,Height,32),"Genesis",sf::Style::Fullscreen);

        mainWindow.setMouseCursorVisible(false);
        mainWindow.setVerticalSyncEnabled(true);

        return mainWindow;
}
 

Anyways. I look foreward to hearing from you, and your great ideas!

Have a wonderful day! :D

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Using a window management class without copying a renderWindow?
« Reply #1 on: July 12, 2012, 05:46:46 pm »
You have to ask yourself: Which class should be the owner of the render window?
There can't be two windows thus it's logical that you can't copy them around.
Now if your WindowEngine is the owner of the render window, then you just have to declare it as member variable and return it as reference.

Somewhere in the WindowEngine.hpp file:
class WindowEngine
{
    // ...
    sf::RenderWindow mWindow;
    // ...
};

And then you'll have to change the function signature to use a reference and make use of the member variable.

sf::RenderWindow& WindowEngine::LaunchEngineWindow(void)
{
        int Height = 0;
        int Width = 0;

        GetScreenResolution(Height,Width);

        mWindow.create(sf::VideoMode(Width,Height,32),"Genesis",sf::Style::Fullscreen);

        mWindow.setMouseCursorVisible(false);
        mWindow.setVerticalSyncEnabled(true);

        return mainWindow;
}
 

Also since you probably don't understand the concept of passing stuff around by-value or by-reference, I advice you to pick up a C++ and read it or at least that section. It's basic and crucial knowledge.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #2 on: July 12, 2012, 06:47:38 pm »
You have to ask yourself: Which class should be the owner of the render window?
There can't be two windows thus it's logical that you can't copy them around.
Now if your WindowEngine is the owner of the render window, then you just have to declare it as member variable and return it as reference.

Somewhere in the WindowEngine.hpp file:
class WindowEngine
{
    // ...
    sf::RenderWindow mWindow;
    // ...
};

And then you'll have to change the function signature to use a reference and make use of the member variable.

sf::RenderWindow& WindowEngine::LaunchEngineWindow(void)
{
        int Height = 0;
        int Width = 0;

        GetScreenResolution(Height,Width);

        mWindow.create(sf::VideoMode(Width,Height,32),"Genesis",sf::Style::Fullscreen);

        mWindow.setMouseCursorVisible(false);
        mWindow.setVerticalSyncEnabled(true);

        return mainWindow;
}
 

Also since you probably don't understand the concept of passing stuff around by-value or by-reference, I advice you to pick up a C++ and read it or at least that section. It's basic and crucial knowledge.

Thank you very much! I was still unable to get it working without a non copyable error though. >_> I'm not sure if its something having to do with the way I try to retrieve the mainWindow from the main class, or if its the method of returning it in the WindowEngine.  ???

I'm new to C++ in general and have been learning it for a bit now, "used to program everything in java". I understand references when sending things between methods, but sending references between classes is fairly new to me. Well, I guess. Returning something as a reference between classes is very new. As For books... I'm going to college in a month for this stuff, xD I'll get books then... providing their books are actually decent and not a complete waste of money that is.

So theres nothing I have to change to my main class then? Because it seems like its still returning the mainWindow with "return mainWindow;" and its still getting the main window with, "sf::RenderWindow mainWindow = windowEngine.LaunchEngineWindow();" Correct me if I'm wrong "and I probably am" but doesn't that still make a copy of it? I mean, At the top of the method it does say reference with the "&" but it doesn't seem to be referencing because it still throws a nice litter error into my debug box. :/

Anyways, bit thanks for the help so far! I look foreward to hearing from you again. :D

:EDIT:

So after some snooping, light reading, looking over examples, more light reading, and tinkering. I wound up with this:

WindowEngine.cpp
#include "stdafx.h"
#include "WindowEngine.h"
#include <WTypes.h>
sf::RenderWindow& WindowEngine::LaunchEngineWindow(void)
{
        int Height = 0;
        int Width = 0;

        GetScreenResolution(Height,Width);

        mWindow.create(sf::VideoMode(Width,Height,32),"Genesis",sf::Style::Fullscreen);

        mWindow.setMouseCursorVisible(false);
        mWindow.setVerticalSyncEnabled(true);

        return mWindow;
}
sf::RenderWindow WindowEngine::ApplyResolutionChanges(int&Height,int&Width)
{
//Something will be here soon enough.
}
void WindowEngine::GetScreenResolution(int&Height,int&Width)
{
        RECT desktop;
        const HWND hDesktop = GetDesktopWindow();
        GetWindowRect(hDesktop, &desktop);
    Width = desktop.right;
    Height = desktop.bottom;
}
 

WindowEngine.hpp
#ifndef WINDOWENGINE_H
#define WINDOWENGINE_H
class WindowEngine
{
        sf::RenderWindow & mWindow;
public:
        sf::RenderWindow& LaunchEngineWindow();
        sf::RenderWindow ApplyResolutionChanges(int&Height,int&Width);
private:
        void GetScreenResolution(int&Height,int&Width);
};
#endif
 

Fortunettely it doesn't complain about things being copied anymore. Now it just has an error about having no suitable constructor. xD "no appropriate default constructor available" *sigh something else to learn about......Gotta love these learning expiriences xD
« Last Edit: July 12, 2012, 07:09:16 pm by Flash619 »

Acrobat

  • Full Member
  • ***
  • Posts: 153
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #3 on: July 12, 2012, 07:08:17 pm »
#ifndef WINDOWENGINE_H
#define WINDOWENGINE_H
class WindowEngine
{
        sf::RenderWindow mWindow;
public:
        sf::RenderWindow& LaunchEngineWindow();
        sf::RenderWindow& ApplyResolutionChanges(int Height, int Width);
private:
        void GetScreenResolution(int Height, int Width);
};
#endif
....

sf::RenderWindow & WindowEngine::ApplyResolutionChanges(int Height, int Width)
{
//Something will be here soon enough.
}
 
« Last Edit: July 12, 2012, 07:10:03 pm by Acrobat »

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #4 on: July 12, 2012, 07:10:33 pm »
#ifndef WINDOWENGINE_H
#define WINDOWENGINE_H
class WindowEngine
{
        sf::RenderWindow mWindow;
public:
        sf::RenderWindow& LaunchEngineWindow();
        sf::RenderWindow& ApplyResolutionChanges(int Height, int Width);
private:
        void GetScreenResolution(int Height, int Width);
};
#endif
....

sf::RenderWindow & WindowEngine::ApplyResolutionChanges(int Height, int Width)
{
//Something will be here soon enough.
}
 

Hmnnn?

If your trying to point at it not returning anything, I know that will throw an error. xD I'm just focusing on one error at a time. Without opening a renderWindow, I can't really change it. xD

Also at the moment, I'm trying to find a way of throwing in a constructor so it quiets down about that. Honestly, at the risk of sounding like a complete noob, I have no idea why it even requires one, I mean, it looks like it would work the way it is. I remember constructors in java..... good times.
« Last Edit: July 12, 2012, 07:15:33 pm by Flash619 »

Acrobat

  • Full Member
  • ***
  • Posts: 153
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #5 on: July 12, 2012, 07:19:15 pm »
constructor error is because of
sf::RenderWindow & mWindow;
just type
sf::RenderWindow mWindow;

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #6 on: July 12, 2012, 07:28:17 pm »
constructor error is because of
sf::RenderWindow & mWindow;
just type
sf::RenderWindow mWindow;

And that brought me back to this again:
Quote
1>c:\sfml-2.0-rc\include\sfml\window\window.hpp(476): error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1>          c:\sfml-2.0-rc\include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'
1>          c:\sfml-2.0-rc\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-2.0-rc\include\sfml\graphics\rendertarget.hpp(369): error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1>          c:\sfml-2.0-rc\include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'
1>          c:\sfml-2.0-rc\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 &)'

>_<

Any ideas? xD I don't have any ideas at this point that I havn't already tried.
« Last Edit: July 12, 2012, 07:34:22 pm by Flash619 »

Acrobat

  • Full Member
  • ***
  • Posts: 153
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #7 on: July 12, 2012, 07:35:16 pm »
in this line
 sf::RenderWindow ApplyResolutionChanges(int&Height,int&Width);
you are trying to return a copy, and render window is not copyable, return reference

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #8 on: July 12, 2012, 07:51:16 pm »
in this line
 sf::RenderWindow ApplyResolutionChanges(int&Height,int&Width);
you are trying to return a copy, and render window is not copyable, return reference

I changed that.

My code, as of this moment is:
Window Engine.hpp
#ifndef WINDOWENGINE_H
#define WINDOWENGINE_H
class WindowEngine
{
        sf::RenderWindow mWindow;
public:
        sf::RenderWindow& LaunchEngineWindow();
        sf::RenderWindow& ApplyResolutionChanges(int&Height,int&Width);
private:
        void GetScreenResolution(int&Height,int&Width);
};
#endif
 

Window Engine.cpp

#include "stdafx.h"
#include "WindowEngine.h"
#include <WTypes.h>
sf::RenderWindow& WindowEngine::LaunchEngineWindow(void)
{
        int Height = 0;
        int Width = 0;

        GetScreenResolution(Height,Width);

        mWindow.create(sf::VideoMode(Width,Height,32),"Genesis",sf::Style::Fullscreen);

        mWindow.setMouseCursorVisible(false);
        mWindow.setVerticalSyncEnabled(true);

        return mWindow;
}
sf::RenderWindow& WindowEngine::ApplyResolutionChanges(int&Height,int&Width)
{

}
void WindowEngine::GetScreenResolution(int&Height,int&Width)
{
        RECT desktop;
        const HWND hDesktop = GetDesktopWindow();
        GetWindowRect(hDesktop, &desktop);
    Width = desktop.right;
    Height = desktop.bottom;
}
 

The code being called in the main.cpp

        WindowEngine windowEngine;
        sf::RenderWindow mainWindow = windowEngine.LaunchEngineWindow();
 

Hope that helps ;) Le tme know what you think/find! :D *brb making lunch

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Using a window management class without copying a renderWindow?
« Reply #9 on: July 12, 2012, 08:03:04 pm »
http://www.lmgtfy.com/?q=c+plus+plus+by+reference ::)
If you don't understand a mechnisem don't just try blindly something but go to a source that can teach you something, only then will you be able to understand what we're trying to explain here and won't make the same mistake anymore.

So as I stated in the beginning, the WindowEngine owns the render window, thus we're only returning a reference to the object, but now in your main.cpp you're trying to copy the object at the referred location again.  What you want is to again use a reference.
        WindowEngine windowEngine;
        sf::RenderWindow& mainWindow = windowEngine.LaunchEngineWindow();

Additionally your GetScreenResoltuion function isn't needed at all (so you won't need to code platform depended code). You can simply use sf::VideoMode::getDesktopMode().
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Using a window management class without copying a renderWindow?
« Reply #10 on: July 12, 2012, 08:08:23 pm »
http://www.lmgtfy.com/?q=c+plus+plus+by+reference ::)
If you don't understand a mechnisem don't just try blindly something but go to a source that can teach you something, only then will you be able to understand what we're trying to explain here and won't make the same mistake anymore.

So as I stated in the beginning, the WindowEngine owns the render window, thus we're only returning a reference to the object, but now in your main.cpp you're trying to copy the object at the referred location again.  What you want is to again use a reference.
        WindowEngine windowEngine;
        sf::RenderWindow& mainWindow = windowEngine.LaunchEngineWindow();

Additionally your GetScreenResoltuion function isn't needed at all (so you won't need to code platform depended code). You can simply use sf::VideoMode::getDesktopMode().

So you mean, SFML has a build in function for finding screen resolutions? o_O'

Also, about your google, xD I was following a simple sutorial here.
http://www.functionx.com/cpp/examples/returnreference.htm

Turned out I couldn't get it to work with what I was doing, I'll move onto another one I guess and try it from there. I know whats wrong in the main, but I don't know how to fix it XD I mean, I'm not sure how to jsut go to a class, and get a reference from it without somehow using a "=" so like I said, I'll probably have to spend the next few hours on google. <sarcasm> But still. A lot of google stuff I've found is passing things through methods by reference, or I find reference tutorials that say something like "int myawesomeint = Myclass.GetThatInt();" which looks like its making a copy of it, and not getting a reference.
 
EDIT, again.

So I think I found some nice walkthroughs and tutorials, and got it to work! I deffinetely will have to work with references some more to get them etched clearly into my memory. Thank you all for the awesome help! :D

Many thanks!

~Flash619
« Last Edit: July 12, 2012, 09:05:06 pm by Flash619 »