Hallo,
Ich habe, wie der Titel schon sagt, ein Problem mit der SFML Bibliothek. Genauer gesagt mit der Klasse sf::Thread und der Methode Launch(). Ich hoffe das ist das richtige Forum dafür aber ich habe mir gedacht da SFML ja vorwiegend eine Grafik-Bibliothek ist gehört es hier herein. Ich habe mir bei Google etc. schon die Finger wund gesucht
aber ich finde einfach keine Lösung für mein Problem.
Grundsätzlich besteht folgendes Problem:
Ich will in meinem Spiel drei Threads starten. Einen für Events, einen für Berechnungen und einen für das Rendern. Bei meinem ersten Versuch habe ich eine Klasse mit den Methoden OnExecute(), OnEvent(), OnLoop() und OnRender() erstellt. Erstmal noch ohne Multithreading. Als ich dann eine Klasse für Buttons geschrieben habe und das ganze mal zum Debuggen gestartet habe, habe ich festgestellt, dass das Event-Handling nicht lückenlos funktioniert. Damit meine ich, dass es teilweise ein ziemliches Delay gab. (Ich habe auch sf::Input probiert, ohne erfolg) Deshalb die Entscheidung zum Multithreading.
Also in besagtem Programm habe ich versucht aus der OnExecute()-Methode heraus die anderen Methoden in Threads verpackt. Auf Grund von Problemen habe ich dann die Architektur geändert und eine weitere Klasse als Zwischenlayer zwischen main() und Game::OnExecute eingebaut, die dann die Threads erstellt und sie einer Init-Methode (noch ein Thread) als Referenz-Parameter mitgegeben.
Soweit ich es verstanden habe wäre die allgemeine Syntax: sf::Thread((<Klassenname>::*<Methodenname>)(),*<Klassenobjekt>,[weitere Parameter])
app.h:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#ifndef APP_H_INCLUDED
#define APP_H_INCLUDED
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
class App
{
public:
void OnExecute();
};
class Game
{
public:
Game();
sf::RenderWindow MainWindow;
void OnInit(sf::Thread Event,sf::Thread Loop, sf::Thread Render);
void OnEvent();
void OnLoop();
void OnRender();
};
#endif // APP_H_INCLUDED
|
main.cpp:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#include "app.h"
int main()
{
App theApp;
theApp.OnExecute();
}
void App::OnExecute()
{
Game theGame;
sf::Thread EventThread(void(Game::*OnEvent)(),Game *theGame);
sf::Thread LoopThread(void(Game::*OnLoop)(),Game *theGame);
sf::Thread RenderThread(void(Game::*OnRender)(),Game *theGame);
sf::Thread InitThread(void(Game::*OnInit)(),Game *theGame, sf::Thread* EventThread, sf::Thread* LoopThread, sf::Thread* RenderThread);
InitThread.Launch();
}
Game::Game():MainWindow(sf::VideoMode(800,600,32),"TEST"){};
|
OnInit.cpp
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
|
#include "app.h"
void Game::OnInit(sf::Thread Event,sf::Thread Loop, sf::Thread Render)
{
MainWindow.Clear(sf::Color(255,255,255));
Event.Launch();
Loop.Launch();
Render.Launch();
}
|
In der OnExecute()-Methode regt sich der Compiler auf, dass er Launch() nicht findet. Ich habe schon verschiedenste Möglichkeiten ausprobiert. Hier eine Liste der ausprobierten Sachen (eingefügt in Zeile 23 der main.cpp) mit Fehlermeldung:
|
C-/C++-Quelltext
|
1
|
InitThread.Launch()
|
Fehler: Abfrage des Elementes >>Launch<< in >>InitThread<<, das vom Nicht-Klassentyp >>sf::Thread(void (Game::*)(), Game*, sf::Thread*, sf::Thread*, sf::Thread*)<< ist
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
sf::Thread InitThread.Launch()
|
Fehler expectet initializer before >>.<< token
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
InitThread.sf::Thread::Launch()
|
Fehler: Abfrage des Elementes >>sf::Thread:: Launch<< in >>InitThread<<, das vom Nicht-Klassentyp >>sf::Thread(void (Game::*)(), Game*, sf::Thread*, sf::Thread*, sf::Thread*)<< ist
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
InitThread->Launch()
|
Fehler: Abfrage des Elementes >>Launch<< in >>InitThread<<, das vom Nicht-Klassentyp >>sf::Thread(void (Game::*)(), Game*, sf::Thread*, sf::Thread*, sf::Thread*)<< ist
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
sf::Thread InitThread->Launch()
|
Fehler expectet initializer before >> -> << token
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
InitThread->sf::Thread::Launch()
|
Fehler: Abfrage des Elementes >>sf::Thread:: Launch<< in >>InitThread<<, das vom Nicht-Klassentyp >>sf::Thread(void (Game::*)(), Game*, sf::Thread*, sf::Thread*, sf::Thread*)<< ist
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
this.Launch()
|
Fehler: Abfrage des Elementes >>Launch<< in >>this<<, das vom Nicht-Klassentyp >>App* const<< ist
---------------------------------------------------------------------------------------------
|
C-/C++-Quelltext
|
1
|
this->Launch()
|
Fehler >>class App<< hat kein Element namens >>Launch<<
Wenn ich die Methode OnInit() static definiere (wie in diesem Thread vorgeschlagen
sf::Thread Problem) kommt folgende Fehlermeldung (MainWindow.Clear habe ich natürlich entfernt)
Fehler: Elementfunktion >>static void Game::OnInit(sf::Thread, sf::Thread, sf::Thread<< kann nicht deklariert werden, statische Bindung zu haben [-fpermissive]
Selbst wenn ich mir die Threads sparen könnte möchte ich zumindest wissen warum es nicht funktioniert, denn früher oder später werde ich mal Threads brauchen. Ich weiß, dass der Compiler einfach nicht kapiert, dass er die Methode Launch() in der Klasse sf::Thread suchen soll aber ich weiß nicht wie ich es ihm beibringen soll. Wahrscheinlich ist es nur eine "Kleinigkeit" die ich als "Anfänger" einfach nicht erkenne.
vielen Dank für eure Hilfe.