用std::async调用的方法行为不正确



我有一个方法来初始化我的程序状态,并加快整个过程,我试图添加多线程到我的应用程序(第一次使用这个-仍在学习)。问题是,当我调用它时,通常一切都很好,但是使用std::future和std::async时,我遇到了一些问题(比如复制SFML纹理时的gl_invalid_operation,或者有时wstring中的一些字母是不正确的)。

我以前从未接触过多线程,但根据许多教程,一切都应该很好。

我代码:

SettingsState.cpp

void SettingsState::InitState()
{
#define ASYNC 1
#if ASYNC
// Weird behavior
std::future<void> gen_gui_init =  std::async(std::launch::async, &SettingsState::InitGenSetGUI, this);
std::future<void> win_sett_init = std::async(std::launch::async, &SettingsState::InitWindowSettings, this);
std::future<void> aud_sett_init = std::async(std::launch::async, &SettingsState::InitAudioSettings, this);
std::future<void> sim_sett_init = std::async(std::launch::async, &SettingsState::InitSimulationSettings, this);
std::future<void> key_sett_init = std::async(std::launch::async, &SettingsState::InitKeybindsSettings, this);
#else
// Everything is fine
this->InitGenSetGUI();
this->InitWindowSettings();
this->InitAudioSettings();
this->InitSimulationSettings();
this->InitKeybindsSettings();
#endif
}

SettingsState.hpp

class SettingsState :
public State
{
public:
// constructors
void InitState();
void InitGenSetGUI();
void InitWindowSettings();
void InitAudioSettings();
void InitSimulationSettings();
void InitKeybindsSettings();
// other methods and members
};

我觉得std::future有问题,但是就像我说的,我刚刚接触了它,找不到答案。提前感谢

其他init:

void SettingsState::InitGenSetGUI()
{
const int types_number = 4;
//const int wSettingsColorsCount = 26;
sf::Event fake_event;
m_stateBackground.create(winSize, { 0, 0 }, ke::Origin::LEFT_TOP, "Textures/earth_view2.png");
m_backgroundMask.create(winSize, { 0, 0 }, ke::Origin::LEFT_TOP, L"", 0, {}, sf::Color(0, 0, 0, 255.f - 255.f * AppSettings::BackgroundBrightness() * 0.01f));
m_stateMask.create(winSize, { 0, 0 }, ke::Origin::LEFT_TOP, {}, {}, {}, sf::Color(0, 0, 0, 0));

// SETTINGS GUI

// window settings types
m_settings_types.reserve(types_number);
m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f, sf::Vector2f(1 * winSize.x / 9, winSize.y / 18), ke::Origin::LEFT_TOP, L"Window", winSize.y / 32.f, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 255)));
m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f, sf::Vector2f(3 * winSize.x / 9, winSize.y / 18), ke::Origin::LEFT_TOP, L"Audio", winSize.y / 32.f, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 128)));
m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f, sf::Vector2f(5 * winSize.x / 9, winSize.y / 18), ke::Origin::LEFT_TOP, L"Simulation", winSize.y / 32.f, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 128)));
m_settings_types.emplace_back(std::make_unique<ke::Rectangle>(winSize / 9.f, sf::Vector2f(7 * winSize.x / 9, winSize.y / 18), ke::Origin::LEFT_TOP, L"Keybinds", winSize.y / 32.f, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 128)));
m_selected_type_itr = m_settings_types.begin();
for (auto& itr : m_settings_types)
itr->update({ 0, 0 }, fake_event, sf::Mouse::Left, nullptr);

// separation bar
m_separation_bar.create({ winSize.x, winSize.y / 576 }, { 0, winSize.y / 4.5f }, ke::Origin::LEFT_MIDDLE, {}, {}, {}, sf::Color(255, 255, 255, 160));

// slider
m_slider.create({ winSize.x / 100, winSize.y - winSize.y / 4.5f }, { winSize.x, winSize.y / 4.5f }, viewSize.y * 1.1f, ke::Origin::RIGHT_TOP, nullptr, nullptr, sf::Color(192, 192, 192, 128), sf::Color(128, 128, 128, 128));

// apply and restore defaults button
m_apply_button.create({ winSize.x * 0.1f, winSize.y * 0.05f }, { winSize.x / 6.f, 0.95f * winSize.y }, ke::RIGHT_TOP, L"Apply", winSize.y / 32.f, ke::Origin::MIDDLE_MIDDLE, sf::Color(128, 128, 128, 64), sf::Color(192, 192, 192, 192));
m_restore_def_buttoon.create({ winSize.x * 0.1f, winSize.y * 0.05f }, { winSize.x / 6.f, 0.95f * winSize.y }, ke::LEFT_TOP, L"Restore defaults", winSize.y / 48.f, ke::Origin::MIDDLE_MIDDLE, sf::Color(128, 128, 128, 128), sf::Color(192, 192, 192, 255));
}


////////////////////////////////////////////////////////////////

void SettingsState::InitWindowSettings()
{
// WINDOW SETTINGS
sf::Event fake_event;
auto color_itr = m_windowSettings_colors.begin();

// FPS bars
m_maxMenuFPS_bar.create({ winSize.x / 6, winSize.y / 24 }, { 0.6f * winSize.x, 4 * winSize.y * 0.1f }, nullptr, AppSettings::MaxMenuFPS(), 30, 240, ke::Origin::LEFT_MIDDLE, sf::Color::Black, sf::Color(255, 255, 255, 160), winSize.y / 450, 0, sf::Color(255, 255, 255, 160), sf::Color::Transparent);;
m_maxSimFPS_bar.create({ winSize.x / 6, winSize.y / 24 }, { 0.6f * winSize.x, 5 * winSize.y * 0.1f }, nullptr, AppSettings::MaxSimulationFPS(), 120, 960, ke::Origin::LEFT_MIDDLE, sf::Color::Black, sf::Color(255, 255, 255, 160), winSize.y / 450, 0, sf::Color(255, 255, 255, 160), sf::Color::Transparent);;

// FPS bars accessories
m_WS_accessories.reserve(11);
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f, winSize.y / 24.f), sf::Vector2f(0.6f * winSize.x, 4 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, "Textures/left_arrow2.png"));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f, winSize.y / 24.f), sf::Vector2f(23.f * winSize.x / 30, 4 * winSize.y * 0.1f), ke::Origin::LEFT_MIDDLE, "Textures/right_arrow2.png"));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6.f, winSize.y / 24.f), sf::Vector2f(0.4f * winSize.x, 4 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, L"Menu FPS limit", winSize.y / 32, ke::Origin::RIGHT_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 160)));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f, winSize.y / 24.f), sf::Vector2f(0.6f * winSize.x, 4 * winSize.y * 0.1f), ke::Origin::LEFT_MIDDLE, std::to_wstring(AppSettings::MaxMenuFPS()), winSize.y / 48, ke::Origin::LEFT_MIDDLE, sf::Color::Transparent, sf::Color::Black, 0, sf::Color::Transparent, 0, sf::Text::Regular, sf::Vector2f(2 * winSize.y / 450, 0)));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f, winSize.y / 24.f), sf::Vector2f(0.6f * winSize.x, 5 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, "Textures/left_arrow2.png"));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f, winSize.y / 24.f), sf::Vector2f(23.f * winSize.x / 30, 5 * winSize.y * 0.1f), ke::Origin::LEFT_MIDDLE, "Textures/right_arrow2.png"));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6.f, winSize.y / 24.f), sf::Vector2f(0.4f * winSize.x, 5 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, L"Simulation FPS limit", winSize.y / 32, ke::Origin::RIGHT_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 160)));
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.y / 24.f, winSize.y / 24.f), sf::Vector2f(0.6f * winSize.x, 5 * winSize.y * 0.1f), ke::Origin::LEFT_MIDDLE, std::to_wstring(AppSettings::MaxSimulationFPS()), winSize.y / 48, ke::Origin::LEFT_MIDDLE, sf::Color::Transparent, sf::Color::Black, 0, sf::Color::Transparent, 0, sf::Text::Regular, sf::Vector2f(2 * winSize.y / 450, 0)));
if (m_maxSimFPS_bar.getPointCount() >= 960)
m_WS_accessories.at(7)->setText(L"Unlimited");
// vertical sync status buttons
m_vSyncOn.create({ winSize.x / 12.f, winSize.y / 24.f }, { 41.f * winSize.x / 60.f, 6.f * winSize.y * 0.1f }, ke::Origin::RIGHT_MIDDLE, L"ON", winSize.y / 48, ke::Origin::MIDDLE_MIDDLE, sf::Color(160, 160, 160, 128), sf::Color::Black);
m_vSyncOff.create({ winSize.x / 12.f, winSize.y / 24.f }, { 41.f * winSize.x / 60.f, 6.f * winSize.y * 0.1f }, ke::Origin::LEFT_MIDDLE, L"OFF", winSize.y / 48, ke::Origin::MIDDLE_MIDDLE, sf::Color(160, 160, 160, 128), sf::Color::Black);
if (m_vSyncStatus)
{
m_vSyncOn.setFillColor(sf::Color(255, 255, 255, 192));
m_vSyncOn.setTextStyle(sf::Text::Bold);
}
else
{
m_vSyncOff.setFillColor(sf::Color(255, 255, 255, 192));
m_vSyncOff.setTextStyle(sf::Text::Bold);
}

// vertical sync buttons accessories
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6, winSize.y / 24), sf::Vector2f(0.4f * winSize.x, 6 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, L"Vertical Synchronization", winSize.y / 32, ke::Origin::RIGHT_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 160)));

// bright level bar
m_bright_lvl.create({ winSize.x / 6.f, winSize.y / 24.f }, winSize.y / 49, { 41.f * winSize.x / 60.f, 7.f * winSize.y * 0.1f }, ke::Origin::MIDDLE_MIDDLE, nullptr, nullptr, sf::Color(160, 160, 160, 255), sf::Color(96, 96, 96, 255));
m_bright_lvl.setPercent(AppSettings::BackgroundBrightness());

// bright level accessories 
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6, winSize.y / 24), sf::Vector2f(0.4f * winSize.x, 7 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, L"Background brightness", winSize.y / 32, ke::Origin::RIGHT_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 160)));

// window size dropdown list
m_windowSize_drl.create({ winSize.x / 6.f, winSize.y / 24.f }, { 41.f * winSize.x / 60.f, 8.f * winSize.y * 0.1f }, "Textures/earth_view2.png", L"Something went wrong :(",
winSize.y / 48, ke::Origin::MIDDLE_MIDDLE, sf::Color::Black, sf::Color(255, 255, 255, 192), winSize.y / 450, sf::Color(255, 255, 255, 192), sf::Text::Bold);
m_windowSize_drl.addMember(nullptr, L"1024 u00D7 576", winSize.y / 56, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(160, 160, 160, 255));
m_windowSize_drl.addMember(nullptr, L"1280 u00D7 720", winSize.y / 56, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(160, 160, 160, 255));
m_windowSize_drl.addMember(nullptr, L"1366 u00D7 768", winSize.y / 56, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(160, 160, 160, 255));
m_windowSize_drl.addMember(nullptr, L"1600 u00D7 900", winSize.y / 56, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(160, 160, 160, 255));
m_windowSize_drl.addMember(nullptr, L"1920 u00D7 1080", winSize.y / 56, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(160, 160, 160, 255));
m_windowSize_drl.addMember(nullptr, L"1920 u00D7 1080 Fullscreen", winSize.y / 56, ke::Origin::MIDDLE_MIDDLE, sf::Color::Transparent, sf::Color(160, 160, 160, 255));
for (auto& itr : *m_windowSize_drl.getMembers())
itr->update({ 0, 0 }, fake_event, sf::Mouse::Left, nullptr);

if (AppSettings::DefaultWindowSize() == sf::Vector2f(1024, 576)) m_windowSize_drl.setMemberAsActive(0);
if (AppSettings::DefaultWindowSize() == sf::Vector2f(1280, 720)) m_windowSize_drl.setMemberAsActive(1);
if (AppSettings::DefaultWindowSize() == sf::Vector2f(1366, 768)) m_windowSize_drl.setMemberAsActive(2);
if (AppSettings::DefaultWindowSize() == sf::Vector2f(1600, 900)) m_windowSize_drl.setMemberAsActive(3);
if (AppSettings::DefaultWindowSize() == sf::Vector2f(1920, 1080)) m_windowSize_drl.setMemberAsActive(4);
if (AppSettings::DefaultWindowSize() == sf::Vector2f(1920, 1080)) m_windowSize_drl.setMemberAsActive(5);

m_start_window_size = m_windowSize_drl.getSelectedID();
m_current_window_size = m_windowSize_drl.getSelectedID();

// window size dropdown list accessories
m_WS_accessories.emplace_back(std::make_unique<ke::Rectangle>(sf::Vector2f(winSize.x / 6, winSize.y / 24), sf::Vector2f(0.4f * winSize.x, 8 * winSize.y * 0.1f), ke::Origin::RIGHT_MIDDLE, L"Window Resolution", winSize.y / 32, ke::Origin::RIGHT_MIDDLE, sf::Color::Transparent, sf::Color(255, 255, 255, 160)));
}

在使用OpenGL之前,你需要在线程中初始化它。更多信息请点击这里:https://www.khronos.org/opengl/wiki/OpenGL_and_multithreading

最新更新