When I try to compile the demo file from This tutorial, I get a no operator "=" matches these operands error. I've tried including string (advice from similar questions), but that doesn't seem to make sense since it should already be included in JuceHeader.h.
Code issue:
void initialise (const String& commandLine) override
{
// Add your application's initialisation code here..
mainWindow = new MainWindow (getApplicationName());
}
Full Code:
#include "../JuceLibraryCode/JuceHeader.h"
#include <string>
//==============================================================================
class MainWindowTutorialApplication : public JUCEApplication
{
public:
//==============================================================================
MainWindowTutorialApplication() {}
const String getApplicationName() override { return ProjectInfo::projectName; }
const String getApplicationVersion() override { return ProjectInfo::versionString; }
bool moreThanOneInstanceAllowed() override { return true; }
//==============================================================================
void initialise (const String& commandLine) override
{
// Add your application's initialisation code here..
mainWindow = new MainWindow (getApplicationName());
}
void shutdown() override
{
// Add your application's shutdown code here..
mainWindow = nullptr;
}
//==============================================================================
void systemRequestedQuit() override
{
// This is called when the app is being asked to quit: you can ignore this
// request and let the app carry on running, or call quit() to allow the app to close.
quit();
}
void anotherInstanceStarted (const String& commandLine) override
{
// When another instance of the app is launched while this one is running,
// this method is invoked, and the commandLine parameter tells you what
// the other instance's command-line arguments were.
}
class MainWindow : public DocumentWindow
{
public:
MainWindow(String name) : DocumentWindow(name,
Colours::lightgrey,
DocumentWindow::allButtons)
{
centreWithSize(300, 200);
setVisible(true);
}
void closeButtonPressed() override
{
JUCEApplication::getInstance()->systemRequestedQuit();
}
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(MainWindow)
};
private:
std::unique_ptr<MainWindow> mainWindow;
};
//==============================================================================
// This macro generates the main() routine that launches the app.
START_JUCE_APPLICATION (MainWindowTutorialApplication)
The compiler sais you that you cannot assign a pointer to unique_ptr, and it's true: std::unique_ptr::operator=. You can only move another unique_ptr or assign nullptr. There are two possible solutions:
mainWindow.reset(new MainWindow(getApplicationName()));
or
mainWindow = std::make_unique<MainWindow>(getApplicationName());
Related
So, I have this simplified code as an example for my problem:
#include <QDebug>
#include <functional>
void third()
{
qInfo() << "finished everything!";
}
// will use stuff downloaded by `first()`, which will be used by `third`
void second(const std::function<void()>& cb = [] {})
{
// this has to be called after `first()` has been called and finished
// finished, calling callback
cb();
}
// Will download some stuff, which will be used by `second()`
void first(const std::function<void()>& cb = [] {})
{
// finished, calling callback
cb();
}
int main(int argc, char* argv[])
{
first([=] {
second(third);
});
// or, even worse
first([=] {
second([=] {
third();
});
});
}
Is there any way, that I can prevent this callback hell from happening?
I thought about making another thread, where I would call those functions, block that thread and wait for them to finish.
I am not super sure on how I would do that though. So, first of all, is there a better way to write this (maybe even without creating another thread?) and secondly, if I had to make this happen on another thread, how would I do that?
Thanks for any help in advance!
Signals and slots quite naturally clean up this kind of code. For example:
class Downloader : public QObject {
Q_OBJECT
public:
void beginDownload() // this is your first
{
emit downloadFinished({});
}
signals:
void downloadFinished(const QByteArray& data);
};
class DataProcessorA: public QObject {
Q_OBJECT
public:
void processData(const QByteArray& data) // this is your second
{
emit processingFinished({});
}
signals:
void processingFinished(const QDateArray& processedData);
};
class DataProcessorB: public QObject {
Q_OBJECT
public:
void processData2(const QByteArray& data) // this is your third
{
emit processingFinished({});
}
signals:
void processingFinished(const QDateArray& processedData);
};
void myFunction()
{
auto* downloader = new Downloader(parent);
auto* processorA = new DataProcessorA(parent);
auto* processorB = new DataProcessorB(parent);
// make first call second...
QObject::connect(downloader, &Downloader::downloadFinished, processorA, &DataProcessorA::processData);
// make second call third...
QObject::connect(processorA , &DataProcessorA::processingFinished, processorB, &DataProcessorB::processData);
}
This can work even if the download is executed on a separate thread because Qt's signals/slots can work between threads. The data in the signal will be copied to the receiving thread. Ref: https://doc.qt.io/qt-6/qt.html#ConnectionType-enum
There is a bit of boilerplate with all the QObject stuff, but this should allow you to write each piece in isolation and then be able to flexibly connect the individual pieces using QObject::connect.
I am using Qt5.15.2.
I have a QObject used in my GUI and defined as below:
#pragma once
#include "actionstep.h"
#include "anotherthread.h"
#include <QTableWidget>
class TableWidget : public QTableWidget {
Q_OBJECT
public:
TableWidget(QWidget *parent = nullptr) : QTableWidget(4, 4, parent) {
int id = qRegisterMetaType<ActionStep::ActionStatusInfos>();
std::cout << id << std::endl;
connect(this, &TableWidget::SigUpdateActionStatusInfos, this,
&TableWidget::SlotUpdateActionStatusInfos,
Qt::ConnectionType::QueuedConnection);
th.start();
}
void methodCalledByAnotherThread(ActionStep::ActionStatusInfos ActionStepInfosObj)
{
emit SigUpdateActionStatusInfos(ActionStepInfosObj);
}
signals:
void SigUpdateActionStatusInfos(ActionStep::ActionStatusInfos as);
private slots:
void SlotUpdateActionStatusInfos(ActionStep::ActionStatusInfos as) {
}
private:
AnotherThread th;
};
The idea is to be able to send my custom object of type ActionStep::ActionStatusInfos through the signal/slot service.
Content of "actionstep.h", which contains my custom object:
#pragma once
#include <iostream>
#include <QMetaType>
class ActionStep {
public:
class ActionStatusInfos {
public:
// Default constructor
ActionStatusInfos() : Progress(0) {
}
// Default destructor
~ActionStatusInfos() = default;
// Copy constructor
ActionStatusInfos(ActionStatusInfos &source) {
SetProgress(source.GetProgress());
}
// Copy assignment
ActionStatusInfos &operator=(ActionStatusInfos &source) {
SetProgress(source.GetProgress());
return *this;
}
// move constructor
ActionStatusInfos(ActionStatusInfos &&source) noexcept
{
SetProgress(source.GetProgress());
}
//move assignment
ActionStatusInfos &operator=(ActionStatusInfos &&source) noexcept
{
SetProgress(source.GetProgress());
return *this;
}
void SetProgress(int pg) {
Progress = pg;
}
int GetProgress() {
return Progress;
}
private:
int Progress;
};
};
Q_DECLARE_METATYPE(ActionStep::ActionStatusInfos)
I've added both Q_DECLARE_METATYPE(ActionStep::ActionStatusInfos) and qRegisterMetaType<ActionStep::ActionStatusInfos>(), and my class seems to meet the minimum requirements needed by Qt for registering a custom class (default ctor, dtor and copy ctor).
At runtime, methodCalledByAnotherThread is called by a different thread than the GUI. After a few cycles, I get a SIGFAULT, and the debugger shows that there is a dangling reference when the Qt stuff is executed.
Am I missing something obvious?
i am new in juce and getting an error like "allocating an object of abstract class type 'CreateAccount'" i am beginner in c++. i am try to call the class from the main window of juce and getting error like this.Below is my code
Main.cpp file
#include <JuceHeader.h>
#include "CreateAccount.h"
//==============================================================================
class TestApplication : public JUCEApplication
{
public:
//==============================================================================
TestApplication() {
}
const String getApplicationName() override {
return "Test";
}
const String getApplicationVersion() override { return "1.0.0"; }
void initialise (const String&) override {
mainWindow.reset (new MainWindow ("Test", new CreateAccount(), *this));
// splash = new SplashScreen("Welcome to Screen!",ImageFileFormat::loadFrom(File("/Resources/bell.png")),
// true);
// splash->deleteAfterDelay(RelativeTime::seconds(5), false);
}
void shutdown() override {
mainWindow = nullptr;
}
private:
class MainWindow : public DocumentWindow
{
public:
MainWindow (const String& name, Component* c, JUCEApplication& a)
: DocumentWindow (name, Desktop::getInstance().getDefaultLookAndFeel()
.findColour (ResizableWindow::backgroundColourId),
DocumentWindow::allButtons),
app (a)
{
setUsingNativeTitleBar (true);
setContentOwned (c, true);
#if JUCE_ANDROID || JUCE_IOS
setFullScreen (true);
#else
setResizable (true, false);
setResizeLimits (300, 250, 10000, 10000);
centreWithSize (getWidth(), getHeight());
#endif
setVisible (true);
}
void closeButtonPressed() override
{
app.systemRequestedQuit();
}
private:
JUCEApplication& app;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE (MainWindow)
};
std::unique_ptr<MainWindow> mainWindow;
};
//==============================================================================
START_JUCE_APPLICATION (TestApplication)
CreateAccount.h file
#include <JuceHeader.h>
//new page for create profile
class CreateAccount : public Component,
public Button::Listener
{
public:
CreateAccount() {
addAndMakeVisible(lblloginwithfb);
lblloginwithfb.setFont(Font(18.0f));
lblloginwithfb.setText("Login with Facebook", dontSendNotification);
lblloginwithfb.setColour(Label::textColourId, Colours::white);
//ready to play button
btncreteprofile.setButtonText("Create your profile");
btncreteprofile.setColour(TextButton::textColourOffId, Colours::white);
btncreteprofile.setColour(TextButton::textColourOnId, Colours::white);
btncreteprofile.setColour(TextButton::buttonColourId, Colour::fromRGB(235,135,15));
btncreteprofile.setColour(TextButton::buttonOnColourId, Colour::fromRGB(235,135,15));
addAndMakeVisible(btncreteprofile);
}
//==============================================================================
void paint(Graphics &g) override {
g.fillAll(Colours::black);
}
void resized() override {
/*Rectangle<int> bounds = getLocalBounds();
FlexBox flexBox;
flexBox.flexDirection = FlexBox::Direction::column;
flexBox.flexWrap = FlexBox::Wrap ::noWrap;
flexBox.alignContent = FlexBox::AlignContent::center;
Array<FlexItem> itemarray;
itemarray.add(FlexItem(80,50,btncreteprofile));
itemarray.add(FlexItem(getWidth(),50,lblloginwithfb));
flexBox.items = itemarray;
flexBox.performLayout(bounds.removeFromBottom(200));*/
Rectangle<int> bounds = getLocalBounds();
const int insetX = getWidth() / 4;
const int insetY = getHeight() / 4;
btncreteprofile.setBounds(insetX,bounds.getCentre().y+80,getWidth() - insetX * 2, 50);
lblloginwithfb.setBounds(insetX,insetY,getWidth() - insetX * 2,getHeight());
}
private:
//==============================================================================
// Your private member variables go here...
Label lblloginwithfb;
TextButton btncreteprofile;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CreateAccount)
};
Please help me when i try to add the listner in createaccount file then will get an error.
You need to implement all pure virtual methods in Button::Listener to make your class not abstract. Button::Listener contains these two methods
virtual void buttonClicked (Button *)=0
virtual void buttonStateChanged (Button *)
The second method is not pure virtual, so you don't have to implement it.
So add a method to your class
virtual void buttonClicked (Button *) override {}
and add the code needed when the button is clicked.
Depending on the C++ version you're using, the override might not get accepted by the compiler. In that case, just omit it. It is used to allow
the compiler to emit warnings/errors with respect to overridden methods.
In JUCE, most UI related things are implemented as a subclass of Component.
Some of the subclasses have the concept of a content component: all subclasses
of ResizableWindow, which adds the setContentOwned() and setContentNonOwned()
methods, inherited by all subclasses of ResizableWindow (especially
DocumentWindow).
To define the content of the DocumentWindow, the example code in your question
uses setContentOwned() in the MainWindow constructor which it gets from the
initialise() in TestApplication.
To implement the navigation you could do the following (there are other ways to do it):
1. Implement the navigation in the MainWindow, so you have the navigation logic in one central place
2. Give each of your "Pages" (let's call one step a Page.) a pointer to the MainWindow. For CreateAccount that would be
CreateAccount.h file:
void setMainWindow(MainWindow * _mainWindow)
{
mainWindow = _mainWindow;
}
3. Add an instance variable, too, somewhere in the CreateAccount class:
MainWindow * mainWindow;
and update the constructor:
CreateAccount()
: mainWindow(nullptr)
{
// ...
}
4. Change the creation code
replace
mainWindow.reset (new MainWindow ("Test", new CreateAccount(), *this));
by:
CreateAccount * ca = new CreateAccount();
MainWindow * mw = new MainWindow ("Test", ca, *this)
ca->setMainWindow(mw);
mainWindow.reset(mw);
5. Implement your navigation in a set of custom methods (need to be public) in MainWindow, e.g.
public:
void createProfileClicked()
{
// ...get entered data...
// ...process entered data...
// ...implement next navigation step...
// (you would create or recycle the "Page" for the next step here)
setContentOwned(
// ...
);
}
6. Call that method from the buttonClicked() event handler in CreateAccount:
mainWindow->createProfileClicked();
This is just one way to implement what you want. It all depends on the complexity of your project.
Edit:
My suggestion given in this answer introduces cyclic dependencies of classes.
Let me first restate what I think you currently have, deduced from your comments:
mainwindow.h
#include "splashpage.h"
class MainWindow : public DocumentWindow
{
public:
// ...
void alaramReadyBtnClicked()
{
setContentOwned(new SplashPage(), false);
}
// ...
};
splashpage.h:
#include "mainwindow.h"
class SplashPage : public Component, public Button::Listener
{
public:
SplashPage()
: mainWindow(nullptr)
{}
void setMainWindow(MainWindow * _mainWindow)
{ mainWindow = _mainWindow; }
void buttonClicked (Button *) override
{
if (button == &tvbtnSomething) {
mainWindow->splashSomethingClicked();
}
}
private:
MainWindow * mainWindow;
};
There's a cyclic dependency of declarations in there between MainWindow and the Page classes. When the compiler sees
mainWindow->splashSomethingClicked();
it needs to have seen the declaration of MainWindow but in mainwindow.h
it needs the declaration of SplashPage for this:
void alaramReadyBtnClicked()
{
setContentOwned(new SplashPage(), false);
}
First, it is good practice to use include guards in your header files
e.g. mainwindow.h
// you need these include guards to prevent that the compiler
// sees this file a second time; it's a very good rule of thumb to always do this
// in you header files
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "splashpage.h"
class MainWindow : public DocumentWindow
{
// ...
};
#endif // !defined(MAINWINDOW_H)
There are specific situations in C++ for which the compiler doesn't need to know the complete declaration: if you only use pointers or references and don't reference them. You can then use a forward declaration of class names.
But you can't do this with everything in header files only. Because there's a concept of a "compilation unit".
To break the cyclic dependency, change your ...Page.h:
#ifndef SPLASHPAGE_H
#define SPLASHPAGE_H
// don't include mainwindow.h here
class MainWindow; // forward declaration
class SplashPage : public Component, public Button::Listener
{
public:
SplashPage()
: mainWindow(nullptr)
{}
void setMainWindow(MainWindow * _mainWindow)
{
mainWindow = _mainWindow; // pointer copy does not need full declaration
}
// note: implementation not in this header file anymore
void buttonClicked (Button *) override;
private:
// ...
MainWindow * mainWindow; // does not need full declaration
};
#endif // !defined(SPLASHPAGE_H)
splashpage.cpp:
#include "mainwindow.h"
#include "splashpage.h"
void SplashPage::buttonClicked (Button *) override
{
if (button == &tvbtnSomething) {
mainWindow->splashSomethingClicked();
}
}
If you use the JUCE Projucer tool, you can add pairs of these files easily which should already contain the include guards stuff.
So i've been trying to process audio using JUCE and followed a tutorial and there he used override on one of the functions but when i do it it says "Expected function body after function declarator". The goal is to play random white noise as explained by the video.
Video link: https://www.youtube.com/watch?v=GjNeYI6-uNE&index=11&list=PLLgJJsrdwhPxa6-02-CeHW8ocwSwl2jnu
Code:
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#include "MainComponent.h"
//==============================================================================
MainComponent::MainComponent()
{
// Make sure you set the size of the component after
// you add any child components.
setSize (800, 600);
// specify the number of input and output channels that we want to open
setAudioChannels (2, 2);
}
MainComponent::~MainComponent()
{
// This shuts down the audio device and clears the audio source.
shutdownAudio();
}
//==============================================================================
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
// This function will be called when the audio device is started, or when
// its settings (i.e. sample rate, block size, etc) are changed.
// You can use this function to initialise any resources you might need,
// but be careful - it will be called on the audio thread, not the GUI thread.
// For more details, see the help for AudioProcessor::prepareToPlay()
}
void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override /*this one gets the error*/
{
for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)
{
float* const buffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);
for (int sample = 0; sample < bufferToFill.numSamples; ++sample)
{
buffer[sample] = (random.nextFloat() * 2.0f - 1.0f) * 0.25;
}
}
bufferToFill.clearActiveBufferRegion();
}
void MainComponent::releaseResources()
{
// This will be called when the audio device stops, or when it is being
// restarted due to a setting change.
// For more details, see the help for AudioProcessor::releaseResources()
}
//==============================================================================
void MainComponent::paint (Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
// You can add your drawing code here!
}
void MainComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}
.h file:
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainComponent : public AudioAppComponent
{
public:
//==============================================================================
MainComponent();
~MainComponent();
//==============================================================================
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override;
void releaseResources() override;
//==============================================================================
void paint (Graphics& g) override;
void resized() override;
private:
//==============================================================================
// Your private member variables go here...
Random random;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
Main.cpp
/*
==============================================================================
This file was auto-generated!
It contains the basic startup code for a JUCE application.
==============================================================================
*/
#include "../JuceLibraryCode/JuceHeader.h"
#include "MainComponent.h"
//==============================================================================
class AudioOutApplication : public JUCEApplication
{
public:
//==============================================================================
AudioOutApplication() {}
const String getApplicationName() override { return ProjectInfo::projectName; }
const String getApplicationVersion() override { return ProjectInfo::versionString; }
bool moreThanOneInstanceAllowed() override { return true; }
//==============================================================================
void initialise (const String& commandLine) override
{
// This method is where you should put your application's initialisation code..
mainWindow.reset (new MainWindow (getApplicationName()));
}
void shutdown() override
{
// Add your application's shutdown code here..
mainWindow = nullptr; // (deletes our window)
}
//==============================================================================
void systemRequestedQuit() override
{
// This is called when the app is being asked to quit: you can ignore this
// request and let the app carry on running, or call quit() to allow the app to close.
quit();
}
void anotherInstanceStarted (const String& commandLine) override
{
// When another instance of the app is launched while this one is running,
// this method is invoked, and the commandLine parameter tells you what
// the other instance's command-line arguments were.
}
//==============================================================================
/*
This class implements the desktop window that contains an instance of
our MainComponent class.
*/
class MainWindow : public DocumentWindow
{
public:
MainWindow (String name) : DocumentWindow (name,
Desktop::getInstance().getDefaultLookAndFeel()
.findColour (ResizableWindow::backgroundColourId),
DocumentWindow::allButtons)
{
setUsingNativeTitleBar (true);
setContentOwned (new MainComponent(), true);
#if JUCE_IOS || JUCE_ANDROID
setFullScreen (true);
#else
setResizable (true, true);
centreWithSize (getWidth(), getHeight());
#endif
setVisible (true);
}
void closeButtonPressed() override
{
// This is called when the user tries to close this window. Here, we'll just
// ask the app to quit when this happens, but you can change this to do
// whatever you need.
JUCEApplication::getInstance()->systemRequestedQuit();
}
/* Note: Be careful if you override any DocumentWindow methods - the base
class uses a lot of them, so by overriding you might break its functionality.
It's best to do all your work in your content component instead, but if
you really have to override any DocumentWindow methods, make sure your
subclass also calls the superclass's method.
*/
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
};
private:
std::unique_ptr<MainWindow> mainWindow;
};
//==============================================================================
// This macro generates the main() routine that launches the app.
START_JUCE_APPLICATION (AudioOutApplication)
You need to remove the override from the function definition in the .cpp file. This specifier can only appear in a member function declaration (i.e., in the header file), unless you're defining the function inside the header file, in which case it can appear just before the function body.
I need to create a thread to run the Networking portion of my game. I would prefer to use SFML threads as my compiler doesn't yet support C++11 threads. However the class which contains the thread is created with make_shared(). Here is the code:
Game.cpp (not all the code just the declaration of GameScreen)
std::shared_ptr<Screen> Game::screen = std::make_shared<GameScreen>();
Screen is just a base class containing pure virtual functions. You should be able to figure out which ones are virtual based off the override keywords.
GameScreen.h
#ifndef GAMESCREEN_H
#define GAMESCREEN_H
#include <SFML/Graphics.hpp>
#include "Events.h"
#include "Screen.h"
#include "Map.h"
#include "Network.h"
class GameScreen : public Screen
{
public:
GameScreen();
void handleInput(sf::RenderWindow&) override;
void update(sf::RenderWindow&, sf::View&) override;
void render(sf::RenderWindow&) override;
private:
Map m_map;
Network network;
Events eventManager;
sf::Thread networkThread;
};
#endif // GAMESCREEN_H
GameScreen.cpp
#include <memory>
#include <iostream>
#include "GameScreen.h"
#include "Game.h"
GameScreen::GameScreen()
: networkThread(network.receive(eventManager))
{
network.Connect();
}
void GameScreen::handleInput(sf::RenderWindow& window)
{
/*Code*/
}
void GameScreen::update(sf::RenderWindow& window, sf::View& view)
{
/*Code*/
}
void GameScreen::render(sf::RenderWindow& window)
{
/*Code*/
}
Network.cpp (receive function only)
void Network::Recieve(Events& eManager)
{
sf::Packet m_rPacket;
m_socket.receive(m_rPacket, m_serverIP, port);
m_rPacket >> /*Data*/
eManager.addEvent(tmp);
}
You can use this in the constructor's initialization list:
MyClass::MyClass()
: AClass(&MyFunction(*this))
{
/*do stuff*/
}
However, this doesn't make sense in your example, because you are trying to pass a pointer to MyFunction (or its non-existent return value) to AClass(), and you can't quality a pointer with parameters. You can only pass parameters to MyFunction() when actually calling MyFunction(). Are you sure you don't actually mean something more like this instead:
MyClass::MyClass()
: AClass()
{
/*do stuff*/
MyFunction(*this);
}
Without seeing what AClass() actually is, or what it expects as input, it is difficult to know for sure what you are trying to do.
Update clearly you have not read the SFML documentation or SFML Tutorial on threading. The Thread constructor takes a pointer to a function/method as one input parameter, and an optional input value for the function/method as a separate parameter. Try this instead:
class MyClass : public sf::Thread
{
private:
static void MyFunction(MyClass &cls);
public:
MyClass();
};
MyClass::MyClass()
: sf::Thread(&MyClass::MyFunction, *this)
{
/*do stuff*/
}
void MyClass::MyFunction(MyClass &cls)
{
/*do stuff with 'cls'*/
}
Or this, as you can use a non-static class method with an SFML thread:
class MyClass : public sf::Thread
{
private:
void MyFunction();
public:
MyClass();
};
MyClass::MyClass()
: sf::Thread(&MyClass::MyFunction, *this)
{
/*do stuff*/
}
void MyClass::MyFunction()
{
/*do stuff with 'this'*/
}
Update: based on your new code, you are still not even close to constructing the sf::Thread object correctly (did you read the documentation/tutorial I linked to?). Also, your thread needs access to multiple objects owned by GameScreen, so you can't pass them all to the sf::Thread constructor. You need to do something more like this instead:
class GameScreen : public Screen
{
public:
GameScreen();
...
private:
...
Network network;
Events eventManager;
sf::Thread networkThread;
void networkThreadFunc();
};
GameScreen::GameScreen()
: networkThread(&GameScreen::networkThreadFunc, *this)
{
network.Connect();
}
void GameScreen::networkThreadFunc()
{
network.Receive(eventManager);
}