Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

289_29689

Frischling

  • »289_29689« ist der Autor dieses Themas

Beiträge: 10

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

1

06.03.2012, 15:42

Problem mit sf::Thread / .Launch() und Objektorientierung

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.
Buch: Einführung in die Programmierung mit C++ (Stroustrup)
Programmierumgebung:
Ubuntu 11.10 + Code::Blocks

289_29689

Frischling

  • »289_29689« ist der Autor dieses Themas

Beiträge: 10

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

2

08.03.2012, 22:23

Kann mir denn hier keiner helfen? Wenn es so nicht funktionieren kann wäre es gut wenn ich das wüsste bevor ich noch mehr Zeit für die Lösung eines unlösbaren Fehlers verschwende. Dann muss ich halt WinAPI oder Boost ausprobieren für Multithreading.
Buch: Einführung in die Programmierung mit C++ (Stroustrup)
Programmierumgebung:
Ubuntu 11.10 + Code::Blocks

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

09.03.2012, 01:01

C-/C++-Quelltext

1
sf::Thread EventThread(void(Game::*OnEvent)(),Game *theGame);

Ich bin mir nicht ganz sicher was du denkst dass das tut. Aber was es tatsächlich tut ist: Es deklariert eine Funktion namens EventThread, die einen Pointer auf eine Memberfunktion der Klasse Game, sowie einen Zeiger auf ein Game als Parameter bekommt und einen sf::Thread returned.

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

4

09.03.2012, 14:29

Multithreading kann sehr komplex sein und dein Code wirkt nicht so aus wüsstest du was ein Thread ist und wofür man ihn nutzt.
In einem Thread zu initialisieren während der andere schonmal Zeichnet und noch ein anderer die Events abfragt ist nicht besonders klug.

Beschäftige dich erstmal mit den Grundlagen und vergiss Threads erstmal...
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

289_29689

Frischling

  • »289_29689« ist der Autor dieses Themas

Beiträge: 10

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

5

09.03.2012, 22:28

Ich bin mir nicht ganz sicher was du denkst dass das tut. Aber was es tatsächlich tut ist: Es deklariert eine Funktion namens EventThread, die einen Pointer auf eine Memberfunktion der Klasse Game, sowie einen Zeiger auf ein Game als Parameter bekommt und einen sf::Thread returned.
Ja und diesen Thread muss ich dann noch mit .Launch() starten.
So wie ich das verstanden habe bedeutet der Code führe die Funktion theGame.OnEvent(); parallel zum restlichen Programm aus.
Multithreading kann sehr komplex sein und dein Code wirkt nicht so aus wüsstest du was ein Thread ist und wofür man ihn nutzt.
Ein Thread führt eine Funktion parallel zum Restlichen Programm aus.
Man nutzt ihn indem man ihm eine Funktion als Einstiegspunkt gibt und ihn dann startet.
In einem Thread zu initialisieren während der andere schonmal Zeichnet und noch ein anderer die Events abfragt ist nicht besonders klug.
Ich habe doch einen 4. Thread, den Initialisierungs-Thread. Ich weiß den könnte ich mir genau so gut sparen aber ich verweise ja per Referenz auf die anderen 3 Threads und starte die dann in der Initialisierungs-Methode. Was ich nicht verstehe ist warum der Compiler die Thread.Launch() Aufrufe in der Initialisierungsmethode Akzeptiert und den in der OnExecute()-Methode nicht.
Beschäftige dich erstmal mit den Grundlagen und vergiss Threads erstmal...
OOP:

Es gibt Klassen. Mithilfe von Klassen kann man Objekte erstellen auf diese kann man Funktionen anwenden. Es gibt private, public und protected auf private kann nur die Klasse selbst zugreifen auf public auch Funktionen von Außerhalb.

Pointer: Objekt das eine Speicheradresse beinhaltet
Referenz: Die Übergabe einer Speicheradresse eines Objekts z.B. als Parameter

while
do-while
for

Was verstehst du unter Grundlagen. Kannst du dass bitte konkretisieren.

trotzdem Danke mal für die Antwort
Buch: Einführung in die Programmierung mit C++ (Stroustrup)
Programmierumgebung:
Ubuntu 11.10 + Code::Blocks

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

6

09.03.2012, 22:53

Ich bin mir nicht ganz sicher was du denkst dass das tut. Aber was es tatsächlich tut ist: Es deklariert eine Funktion namens EventThread, die einen Pointer auf eine Memberfunktion der Klasse Game, sowie einen Zeiger auf ein Game als Parameter bekommt und einen sf::Thread returned.
Ja und diesen Thread muss ich dann noch mit .Launch() starten.

Was für einen Thread meinst du? Ich seh da keinen Thread, nur eine Deklaration einer Funktion die nirgendwo existiert...

289_29689

Frischling

  • »289_29689« ist der Autor dieses Themas

Beiträge: 10

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

7

09.03.2012, 23:24

Was für einen Thread meinst du? Ich seh da keinen Thread, nur eine Deklaration einer Funktion die nirgendwo existiert...
Hab ich das schon richtig verstanden, dass ich ein Objekt vom Typ sf::Thread erstelle das als Einstiegspunkt die Funktion theGame.OnEvent() verwendet? Wo deklariere ich da bitte eine Funktion. Ja in der app.h Zeile 23. Aber doch nicht mit

C-/C++-Quelltext

1
sf::Thread EventThread(void(Game::*OnEvent)(),Game *theGame);

oder?

Der Code der Funktionen ist in eigenen .cpp Dateien. Also OnEvent.cpp, OnLoop.cpp und OnRender.cpp .
Buch: Einführung in die Programmierung mit C++ (Stroustrup)
Programmierumgebung:
Ubuntu 11.10 + Code::Blocks

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

09.03.2012, 23:30

Was für einen Thread meinst du? Ich seh da keinen Thread, nur eine Deklaration einer Funktion die nirgendwo existiert...
Hab ich das schon richtig verstanden, dass ich ein Objekt vom Typ sf::Thread erstelle das als Einstiegspunkt die Funktion theGame.OnEvent() verwendet? Wo deklariere ich da bitte eine Funktion. Ja in der app.h Zeile 23. Aber doch nicht mit

C-/C++-Quelltext

1
sf::Thread EventThread(void(Game::*OnEvent)(),Game *theGame);

oder?

Doch. Wie gesagt: Das deklariert eine Funktions namens EventThread, die einen Pointer auf eine Memberfunktion der Klasse Game und einen Pointer auf ein Objekt vom Typ Game als Parameter bekommt und einen sf::Thread returned.

Was du eigentlich meinst ist:

C-/C++-Quelltext

1
sf::Thread EventThread(&Game::OnEvent, &theGame);

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (09.03.2012, 23:35)


289_29689

Frischling

  • »289_29689« ist der Autor dieses Themas

Beiträge: 10

Wohnort: Salzburg

Beruf: Schüler

  • Private Nachricht senden

9

10.03.2012, 00:00

Diese Art des Konstruktors hatte ich auch schon mal ausprobiert. Ich habe den Code gerade geändert. Mit folgendem Ergebnis:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void App::OnExecute()
{
    Game theGame;


    sf::Thread EventThread(&Game::OnEvent(),&theGame);

    sf::Thread LoopThread(&Game::OnLoop(),&theGame);

    sf::Thread RenderThread(&Game::OnRender(),&theGame);

    sf::Thread InitThread(&Game::OnInit(EventThread,LoopThread,RenderThread));

    InitThread.Launch();
}


Fehler: Elementfunktion >>void Game::On#####()<< kann nicht ohne Objekt aufgerufen werden

Aus diesem Grund habe ich in der SFML Dokumentation nachgeschaut und die andere Syntax gefunden.

Edit: Wie kann ich die andere Syntax verstehen? Die ist schlichtweg falsch oder wie?
Buch: Einführung in die Programmierung mit C++ (Stroustrup)
Programmierumgebung:
Ubuntu 11.10 + Code::Blocks

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

10

10.03.2012, 00:07

Ich vermute mal du verwendest SFML 1.6? Der SFML 1.6 Thread unterstützt schlicht und einfach keine Memberfunktionen...

Was für eine "andere Syntax" meinst du?

Werbeanzeige