【问题标题】:SFML Network MultithreadingSFML 网络多线程
【发布时间】:2016-03-12 18:59:51
【问题描述】:

我需要创建一个线程来运行我的游戏的网络部分。我更喜欢使用 SFML 线程,因为我的编译器还不支持 C++11 线程。但是包含线程的类是用make_shared() 创建的。这是代码:

Game.cpp(并非所有代码只是GameScreen的声明)

std::shared_ptr<Screen> Game::screen = std::make_shared<GameScreen>();

Screen 只是一个包含纯虚函数的基类。您应该能够根据覆盖关键字找出哪些是虚拟的。

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(仅接收功能)

void Network::Recieve(Events& eManager)
{
    sf::Packet m_rPacket;
    m_socket.receive(m_rPacket, m_serverIP, port);
    m_rPacket >> /*Data*/
    eManager.addEvent(tmp);
}

【问题讨论】:

  • 呃,方法为什么不能引用this???而且,如果你想引用类实例...... 那你为什么要让它成为静态的?!?
  • 我需要将其设为静态,否则 SFML 线程无法正常工作
  • SFML thread 类可以被赋予一个非静态类方法。
  • @Cronnoc:我在这里听到XY Problem。具体来说:1)如果您想将“this”引用传递给方法,您可以这样做。 2)但是,在几乎调用的情况下,最好的解决方案是使方法非堆栈并简单地使用“内置”“this”引用。 3) 您确实 NOT 需要将方法设为“静态”以适应 SFML 线程。请参阅其他回复。 4) 如果您在使非静态方法正常工作时仍有疑问/问题,请更新您的帖子并提供详细信息。
  • @paulsm4 好的,我将重写我的问题,询问问题而不是我想出的解决方案。

标签: c++ multithreading class sfml


【解决方案1】:

可以在构造函数的初始化列表中使用this

MyClass::MyClass()
    : AClass(&MyFunction(*this))
{
    /*do stuff*/
}

但是,这在您的示例中没有意义,因为您正在尝试将指向 MyFunction(或其不存在的返回值)的指针传递给 AClass(),并且您无法使用参数。您只能在实际调用 MyFunction() 时将参数传递给MyFunction()。你确定你的意思不是更像这样吗:

MyClass::MyClass()
    : AClass()
{
    /*do stuff*/
    MyFunction(*this);
}

如果不了解 AClass() 的实际含义,或者它期望的输入内容,就很难确定您正在尝试做什么。

更新显然你还没有阅读SFML documentationSFML Tutorial 关于线程。 Thread 构造函数将指向函数/方法的指针作为一个输入参数,并将函数/方法的可选输入值作为单独的参数。试试这个:

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'*/
}

或者这样,您可以使用带有 SFML 线程的非静态类方法:

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'*/
}

更新:根据您的新代码,您仍然无法正确构建sf::Thread 对象(您是否阅读了我链接到的文档/教程?)。此外,您的线程需要访问GameScreen 拥有的多个对象,因此您不能将它们全部传递给sf::Thread 构造函数。你需要做更多这样的事情:

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);
}

【讨论】:

  • 抱歉,我会编辑这个问题,因为它是一个 SFML 线程类,我只是想让这个问题尽可能笼统
  • 我已经重写了这个问题,所以这个答案可能不再相关。
  • 那么你应该关闭/删除这个问题并发布一个新问题。
  • 好的,我还是堆栈交换的新手
  • 即使在你重写之后,根本问题仍然是一样的。您没有正确构建sf::Thread。我已经更新了我的答案。
猜你喜欢
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
相关资源
最近更新 更多