【发布时间】:2017-11-17 16:52:32
【问题描述】:
我在编写我的第一个chip8 解释器和多线程程序时遇到了这个问题:当我关闭窗口时,我检测到堆栈粉碎。我已经检查代码很长一段时间了,但我找不到问题所在。真的很想得到一些帮助或建议。
模拟器.hpp
#ifndef CHEAP8_SRC_EMULATOR_HPP
#define CHEAP8_SRC_EMULATOR_HPP
#include "chip8.hpp"
#include "ui-settings.hpp"
#include <SFML/Graphics.hpp>
#include <atomic>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#ifdef _WIN32
#define OS_PATH_SEP '\\'
#else
#define OS_PATH_SEP '/'
#endif
class Emulator
{
//misc
const std::string gamePath;
const std::string gameTitle;
//emulator
unsigned char memory[chip8::kMemSize] = {0};
//flags
bool gameLoaded = false;
std::atomic<bool> gameRunning{false};
//ui
const double kPixelSize = 12.5;
std::shared_ptr<sf::RenderWindow> window;
const UiSettings uiSettings;
//threading
std::thread uiThread;
std::mutex mutex;
void loadGame();
void loadFonts();
public:
explicit Emulator(char*);
~Emulator();
void run();
};
#endif //CHEAP8_SRC_EMULATOR_HPP
模拟器.cpp
#include "emulator.hpp"
#include <chrono> //================
#include <fstream>
#include <iostream>
#include <iterator>
#include <vector>
void launchUi(std::shared_ptr<sf::RenderWindow> window,
const UiSettings& uiSettings,
std::atomic<bool>& gameRunning)
{
window = std::make_shared<sf::RenderWindow>();
window->create(sf::VideoMode(uiSettings.width, uiSettings.height),
uiSettings.title,
sf::Style::Titlebar | sf::Style::Close);
window->setVerticalSyncEnabled(true);
window->setKeyRepeatEnabled(false);
const auto screenParams = sf::VideoMode::getDesktopMode();
window->setPosition(sf::Vector2i(screenParams.width / 2 - uiSettings.width / 2,
screenParams.height / 2 - uiSettings.height / 2));
sf::Event event;
while (window->isOpen()) {
while (window->pollEvent(event)) {
switch (event.type) {
case sf::Event::Closed:
window->close();
gameRunning.store(false);
break;
default:
break;
}
}
}
}
Emulator::Emulator(char* path)
: gamePath(path),
gameTitle(gamePath.substr(gamePath.find_last_of(OS_PATH_SEP) + 1)),
uiSettings(kPixelSize, chip8::kScreenWidth, chip8::kScreenHeight, gameTitle),
uiThread(launchUi, window, std::ref(uiSettings), std::ref(gameRunning))
{
loadGame();
loadFonts();
}
Emulator::~Emulator()
{
uiThread.join();
}
void Emulator::loadGame()
{
std::ifstream file(gamePath, std::ios::binary);
if (!file.is_open()) {
std::cerr << "Couldn't open the game." << std::endl;
return;
}
std::vector<unsigned char> gameData;
gameData.insert(gameData.begin(),
std::istream_iterator<unsigned char>(file),
std::istream_iterator<unsigned char>());
if (gameData.size() > chip8::kAllowedGameSize) {
std::cerr << "The game is too big to fit into memory." << std::endl;
return;
}
for (size_t i = 0; i < gameData.size(); ++i) {
memory[i + chip8::kMemStart] = gameData[i];
}
gameLoaded = true;
std::cout << "Game loaded. Size: " << gameData.size() << '\n';
}
void Emulator::loadFonts()
{
for (int i = 0; i < chip8::kFontsetSize; ++i) {
memory[i] = chip8::kFontset[i];
}
std::cout << "Fontset loaded." << '\n';
}
void Emulator::run()
{
if (!gameLoaded) {
return;
}
gameRunning.store(true);
while (gameRunning.load()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
编辑:
#include "emulator.hpp"
#include <iostream>
int main(int argc, char *argv[])
{
if (argc != 2) {
std::cerr << "Usage: ./" << OS_PATH_SEP << "cheap8 game." << std::endl;
return 1;
}
Emulator emu(argv[1]);
emu.run();
return 0;
}
【问题讨论】:
-
main函数包含什么?
-
@M4rc 已将主要内容添加到原始帖子中
标签: c++ multithreading sfml