diff --git a/emulators/emulatorList.hpp b/emulators/emulatorList.hpp index 7a5a5028..49e65202 100644 --- a/emulators/emulatorList.hpp +++ b/emulators/emulatorList.hpp @@ -42,9 +42,9 @@ namespace jaffarPlus { #define DETECT_EMULATOR(EMULATOR) \ if (emulatorName == EMULATOR::getName()) \ - { \ - e = std::make_unique(emulatorConfig); \ - isRecognized = true; \ + { \ + e = std::make_unique(emulatorConfig); \ + isRecognized = true; \ } std::unique_ptr Emulator::getEmulator(const nlohmann::json &emulatorConfig) diff --git a/emulators/quickerArkBot/quickerArkBot.hpp b/emulators/quickerArkBot/quickerArkBot.hpp index ec45366d..6e26bab9 100644 --- a/emulators/quickerArkBot/quickerArkBot.hpp +++ b/emulators/quickerArkBot/quickerArkBot.hpp @@ -43,13 +43,9 @@ class QuickerArkBot final : public Emulator _quickerArkBot->initialize(); } - // Function to get a reference to the input parser from the base emulator - virtual jaffar::InputParser* getInputParser() const - { - return _quickerArkBot->getInputParser(); - } - + virtual jaffar::InputParser *getInputParser() const { return _quickerArkBot->getInputParser(); } + // State advancing function void advanceStateImpl(const jaffar::input_t &input) override { _quickerArkBot->advanceState(input); } @@ -67,26 +63,20 @@ class QuickerArkBot final : public Emulator } // This function opens the video output (e.g., window) - void initializeVideoOutput() override { } + void initializeVideoOutput() override {} // This function closes the video output (e.g., window) - void finalizeVideoOutput() override { } + void finalizeVideoOutput() override {} - __INLINE__ void enableRendering() override { } + __INLINE__ void enableRendering() override {} - __INLINE__ void disableRendering() override { } + __INLINE__ void disableRendering() override {} __INLINE__ void updateRendererState(const size_t stepIdx, const std::string input) override {} - __INLINE__ void serializeRendererState(jaffarCommon::serializer::Base &serializer) const override - { - serializeState(serializer); - } + __INLINE__ void serializeRendererState(jaffarCommon::serializer::Base &serializer) const override { serializeState(serializer); } - __INLINE__ void deserializeRendererState(jaffarCommon::deserializer::Base &deserializer) override - { - deserializeState(deserializer); - } + __INLINE__ void deserializeRendererState(jaffarCommon::deserializer::Base &deserializer) override { deserializeState(deserializer); } __INLINE__ size_t getRendererStateSize() const { @@ -97,7 +87,7 @@ class QuickerArkBot final : public Emulator GameState *getGameState() { return _quickerArkBot->getGameState(); } - __INLINE__ void showRender() override { } + __INLINE__ void showRender() override {} __INLINE__ void doSoftReset() { _quickerArkBot->doSoftReset(); }; diff --git a/emulators/quickerGPGX/quickerGPGX.hpp b/emulators/quickerGPGX/quickerGPGX.hpp index a6900e1f..3528e3ce 100644 --- a/emulators/quickerGPGX/quickerGPGX.hpp +++ b/emulators/quickerGPGX/quickerGPGX.hpp @@ -72,16 +72,16 @@ class QuickerGPGX final : public Emulator // If initial state file defined, load it if (_initialStateFilePath.empty() == false) - { - // Reading from initial state file - std::string initialState; - bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); - if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); - - // Deserializing initial state into the emulator - enableStateProperties(); - jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); - deserializeState(d); + { + // Reading from initial state file + std::string initialState; + bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); + if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); + + // Deserializing initial state into the emulator + enableStateProperties(); + jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); + deserializeState(d); } // Now disabling state properties, as requested diff --git a/emulators/quickerNES/quickerNES.hpp b/emulators/quickerNES/quickerNES.hpp index cf9b3627..1c71b535 100644 --- a/emulators/quickerNES/quickerNES.hpp +++ b/emulators/quickerNES/quickerNES.hpp @@ -82,31 +82,31 @@ class QuickerNES final : public Emulator // Advancing the state using the initial sequence, if provided if (_initialSequenceFilePath != "") - { - // Load initial sequence - std::string initialSequenceFileString; - if (jaffarCommon::file::loadStringFromFile(initialSequenceFileString, _initialSequenceFilePath) == false) - JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial sequence file: %s\n", _initialSequenceFilePath.c_str()); + { + // Load initial sequence + std::string initialSequenceFileString; + if (jaffarCommon::file::loadStringFromFile(initialSequenceFileString, _initialSequenceFilePath) == false) + JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial sequence file: %s\n", _initialSequenceFilePath.c_str()); - // Getting input sequence - const auto initialSequence = jaffarCommon::string::split(initialSequenceFileString, '\0'); + // Getting input sequence + const auto initialSequence = jaffarCommon::string::split(initialSequenceFileString, '\0'); - // Running inputs in the initial sequence - for (const auto &input : initialSequence) advanceState(input); + // Running inputs in the initial sequence + for (const auto &input : initialSequence) advanceState(input); } // If initial state file defined, load it if (_initialStateFilePath.empty() == false) - { - // Reading from initial state file - std::string initialState; - bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); - if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); - - // Deserializing initial state into the emulator - enableStateProperties(); - jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); - deserializeState(d); + { + // Reading from initial state file + std::string initialState; + bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); + if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); + + // Deserializing initial state into the emulator + enableStateProperties(); + jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); + deserializeState(d); } // Now disabling state properties, as requested @@ -174,14 +174,14 @@ class QuickerNES final : public Emulator for (unsigned h = 0; h < emulator_t::image_height; h++, in_pixels += e->frame().pitch, out_pixels += emulator_t::image_width) for (unsigned w = 0; w < emulator_t::image_width; w++) - { - unsigned col = e->frame().palette[in_pixels[w]]; - const emulator_t::rgb_t &rgb = e->nes_colors[col]; - unsigned r = rgb.red; - unsigned g = rgb.green; - unsigned b = rgb.blue; - out_pixels[w] = (r << 16) | (g << 8) | (b << 0); - } + { + unsigned col = e->frame().palette[in_pixels[w]]; + const emulator_t::rgb_t &rgb = e->nes_colors[col]; + unsigned r = rgb.red; + unsigned g = rgb.green; + unsigned b = rgb.blue; + out_pixels[w] = (r << 16) | (g << 8) | (b << 0); + } } // This function opens the video output (e.g., window) @@ -291,7 +291,7 @@ class QuickerNES final : public Emulator std::string _controller2Type; std::string _romFilePath; std::string _romFileSHA1; - + std::string _initialStateFilePath; std::string _initialSequenceFilePath; }; diff --git a/emulators/quickerRAW/quickerRAW.hpp b/emulators/quickerRAW/quickerRAW.hpp index 03cffaf0..d20c3bf6 100644 --- a/emulators/quickerRAW/quickerRAW.hpp +++ b/emulators/quickerRAW/quickerRAW.hpp @@ -40,15 +40,15 @@ class QuickerRAW final : public Emulator // If initial state file defined, load it if (_initialStateFilePath.empty() == false) - { - // Reading from initial state file - std::string initialState; - bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); - if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); - - // Deserializing initial state into the emulator - jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); - deserializeState(d); + { + // Reading from initial state file + std::string initialState; + bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); + if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); + + // Deserializing initial state into the emulator + jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); + deserializeState(d); } _mutex.unlock(); diff --git a/emulators/quickerSDLPoP/quickerSDLPoP.hpp b/emulators/quickerSDLPoP/quickerSDLPoP.hpp index 7e949f1a..3a8bcbc8 100644 --- a/emulators/quickerSDLPoP/quickerSDLPoP.hpp +++ b/emulators/quickerSDLPoP/quickerSDLPoP.hpp @@ -44,12 +44,12 @@ class QuickerSDLPoP final : public Emulator // If an initial state is provided, load it now if (_stateFilePath != "") - { - std::string stateFileData; - if (jaffarCommon::file::loadStringFromFile(stateFileData, _stateFilePath) == false) JAFFAR_THROW_LOGIC("Could not initial state file: %s\n", _stateFilePath.c_str()); + { + std::string stateFileData; + if (jaffarCommon::file::loadStringFromFile(stateFileData, _stateFilePath) == false) JAFFAR_THROW_LOGIC("Could not initial state file: %s\n", _stateFilePath.c_str()); - jaffarCommon::deserializer::Contiguous deserializer(stateFileData.data()); - _QuickerSDLPoP->deserializeState(deserializer); + jaffarCommon::deserializer::Contiguous deserializer(stateFileData.data()); + _QuickerSDLPoP->deserializeState(deserializer); } // Check if RNG elements need overriding diff --git a/emulators/quickerSMBC/quickerSMBC.hpp b/emulators/quickerSMBC/quickerSMBC.hpp index 3e3a7966..85986d9e 100644 --- a/emulators/quickerSMBC/quickerSMBC.hpp +++ b/emulators/quickerSMBC/quickerSMBC.hpp @@ -73,15 +73,15 @@ class QuickerSMBC final : public Emulator // If initial state file defined, load it if (_initialStateFilePath.empty() == false) - { - // Reading from initial state file - std::string initialState; - bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); - if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); - - // Deserializing initial state into the emulator - jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); - deserializeState(d); + { + // Reading from initial state file + std::string initialState; + bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); + if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); + + // Deserializing initial state into the emulator + jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); + deserializeState(d); } // Now disabling state properties, as requested diff --git a/emulators/quickerSnes9x/quickerSnes9x.hpp b/emulators/quickerSnes9x/quickerSnes9x.hpp index 7242e167..bf2c4ea6 100644 --- a/emulators/quickerSnes9x/quickerSnes9x.hpp +++ b/emulators/quickerSnes9x/quickerSnes9x.hpp @@ -69,16 +69,16 @@ class QuickerSnes9x final : public Emulator // If initial state file defined, load it if (_initialStateFilePath.empty() == false) - { - // Reading from initial state file - std::string initialState; - bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); - if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); - - // Deserializing initial state into the emulator - enableStateProperties(); - jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); - deserializeState(d); + { + // Reading from initial state file + std::string initialState; + bool success = jaffarCommon::file::loadStringFromFile(initialState, _initialStateFilePath); + if (success == false) JAFFAR_THROW_LOGIC("[ERROR] Could not find or read from initial state file: %s\n", _initialStateFilePath.c_str()); + + // Deserializing initial state into the emulator + enableStateProperties(); + jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); + deserializeState(d); } // Now disabling state properties, as requested diff --git a/games/gameList.hpp b/games/gameList.hpp index 0adcb575..4630c55b 100644 --- a/games/gameList.hpp +++ b/games/gameList.hpp @@ -46,9 +46,9 @@ namespace jaffarPlus { #define DETECT_GAME(GAME) \ if (gameName == games::GAME::getName()) \ - { \ - g = std::make_unique(std::move(e), gameConfig); \ - isRecognized = true; \ + { \ + g = std::make_unique(std::move(e), gameConfig); \ + isRecognized = true; \ } std::unique_ptr Game::getGame(const nlohmann::json &emulatorConfig, const nlohmann::json &gameConfig) diff --git a/games/genesis/dinoRunner.hpp b/games/genesis/dinoRunner.hpp index 5efcbc51..aa61476a 100644 --- a/games/genesis/dinoRunner.hpp +++ b/games/genesis/dinoRunner.hpp @@ -90,9 +90,9 @@ class DinoRunner final : public jaffarPlus::Game void printInfoImpl() const override { if (std::abs(_pointMagnet.intensity) > 0.0f) - { - jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.y); - jaffarCommon::logger::log("[J+] + Distance %3.3f\n", _player1DistanceToPoint); + { + jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.y); + jaffarCommon::logger::log("[J+] + Distance %3.3f\n", _player1DistanceToPoint); } } @@ -101,11 +101,11 @@ class DinoRunner final : public jaffarPlus::Game bool recognizedActionType = false; if (actionType == "Set Point Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto y = jaffarCommon::json::getNumber(actionJs, "Y"); - rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .y = y}; }); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto y = jaffarCommon::json::getNumber(actionJs, "Y"); + rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .y = y}; }); + recognizedActionType = true; } return recognizedActionType; diff --git a/games/nes/sprilo.hpp b/games/nes/sprilo.hpp index af1f6743..e7e93d13 100644 --- a/games/nes/sprilo.hpp +++ b/games/nes/sprilo.hpp @@ -125,11 +125,11 @@ class Sprilo final : public jaffarPlus::Game void printInfoImpl() const override { if (std::abs(_pointMagnet.intensity) > 0.0f) - { - jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); - jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _player1DistanceToPointX); - jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _player1DistanceToPointY); - jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _player1DistanceToPoint); + { + jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); + jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _player1DistanceToPointX); + jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _player1DistanceToPointY); + jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _player1DistanceToPoint); } } @@ -138,30 +138,30 @@ class Sprilo final : public jaffarPlus::Game bool recognizedActionType = false; if (actionType == "Set Point Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto x = jaffarCommon::json::getNumber(actionJs, "X"); - auto y = jaffarCommon::json::getNumber(actionJs, "Y"); - rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto x = jaffarCommon::json::getNumber(actionJs, "X"); + auto y = jaffarCommon::json::getNumber(actionJs, "Y"); + rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); + recognizedActionType = true; } if (actionType == "Advance Lap Progress") - { - rule.addAction([this]() { *_lapProgress = *_lapProgress + 1; }); - recognizedActionType = true; + { + rule.addAction([this]() { *_lapProgress = *_lapProgress + 1; }); + recognizedActionType = true; } if (actionType == "Clear Lap Progress") - { - rule.addAction([this]() { *_lapProgress = 0; }); - recognizedActionType = true; + { + rule.addAction([this]() { *_lapProgress = 0; }); + recognizedActionType = true; } if (actionType == "Stop Processing Reward") - { - rule.addAction([this]() { _stopProcessingReward = true; }); - recognizedActionType = true; + { + rule.addAction([this]() { _stopProcessingReward = true; }); + recognizedActionType = true; } return recognizedActionType; diff --git a/games/nes/superMarioBros.hpp b/games/nes/superMarioBros.hpp index d5625c3e..c95454ba 100644 --- a/games/nes/superMarioBros.hpp +++ b/games/nes/superMarioBros.hpp @@ -112,11 +112,11 @@ class SuperMarioBros final : public jaffarPlus::Game jaffarCommon::logger::log("[J+] + Mario Position Y %.5f\n", _marioPosY); if (std::abs(_pointMagnet.intensity) > 0.0f) - { - jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); - jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _marioDistanceToPointX); - jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _marioDistanceToPointY); - jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _marioDistanceToPoint); + { + jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); + jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _marioDistanceToPointX); + jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _marioDistanceToPointY); + jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _marioDistanceToPoint); } } @@ -125,12 +125,12 @@ class SuperMarioBros final : public jaffarPlus::Game bool recognizedActionType = false; if (actionType == "Set Point Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto x = jaffarCommon::json::getNumber(actionJs, "X"); - auto y = jaffarCommon::json::getNumber(actionJs, "Y"); - rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto x = jaffarCommon::json::getNumber(actionJs, "X"); + auto y = jaffarCommon::json::getNumber(actionJs, "Y"); + rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); + recognizedActionType = true; } return recognizedActionType; diff --git a/games/raw/anotherWorld.hpp b/games/raw/anotherWorld.hpp index d88e0750..bb928c1a 100644 --- a/games/raw/anotherWorld.hpp +++ b/games/raw/anotherWorld.hpp @@ -152,11 +152,11 @@ class AnotherWorld final : public jaffarPlus::Game void printInfoImpl() const override { if (std::abs(_pointMagnet.intensity) > 0.0f) - { - jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); - jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _lesterDistanceToPointX); - jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _lesterDistanceToPointY); - jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _lesterDistanceToPoint); + { + jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); + jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _lesterDistanceToPointX); + jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _lesterDistanceToPointY); + jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _lesterDistanceToPoint); } } @@ -165,12 +165,12 @@ class AnotherWorld final : public jaffarPlus::Game bool recognizedActionType = false; if (actionType == "Set Point Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto x = jaffarCommon::json::getNumber(actionJs, "X"); - auto y = jaffarCommon::json::getNumber(actionJs, "Y"); - rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto x = jaffarCommon::json::getNumber(actionJs, "X"); + auto y = jaffarCommon::json::getNumber(actionJs, "Y"); + rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); + recognizedActionType = true; } return recognizedActionType; diff --git a/games/sdlpop/princeOfPersia.hpp b/games/sdlpop/princeOfPersia.hpp index c4ae009e..3bf9ae74 100644 --- a/games/sdlpop/princeOfPersia.hpp +++ b/games/sdlpop/princeOfPersia.hpp @@ -125,70 +125,70 @@ class PrinceOfPersia final : public jaffarPlus::Game for (size_t i = 1; i <= 24; i++) for (size_t j = 1; j <= 30; j++) - { - propertyName = std::string("Foreground Element[") + std::to_string(i) + std::string("][") + std::to_string(j) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.fg[i - 1][j - 1], Property::datatype_t::dt_uint8, Property::endianness_t::little); + { + propertyName = std::string("Foreground Element[") + std::to_string(i) + std::string("][") + std::to_string(j) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.fg[i - 1][j - 1], Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Background Element[") + std::to_string(i) + std::string("][") + std::to_string(j) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.bg[i - 1][j - 1], Property::datatype_t::dt_uint8, Property::endianness_t::little); - } + propertyName = std::string("Background Element[") + std::to_string(i) + std::string("][") + std::to_string(j) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.bg[i - 1][j - 1], Property::datatype_t::dt_uint8, Property::endianness_t::little); + } // Registering room properties for (size_t i = 0; i < 24; i++) - { - propertyName = std::string("Room Guard Tile[") + std::to_string(i) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.guards_tile[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); + { + propertyName = std::string("Room Guard Tile[") + std::to_string(i) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.guards_tile[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Room Guard Direction[") + std::to_string(i) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.guards_dir[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Room Guard Direction[") + std::to_string(i) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.guards_dir[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Room Guard Pos X[") + std::to_string(i) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.guards_x[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Room Guard Pos X[") + std::to_string(i) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.guards_x[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Room Guard Sequence Low[") + std::to_string(i) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.guards_skill[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Room Guard Sequence Low[") + std::to_string(i) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.guards_skill[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Room Guard Skill[") + std::to_string(i) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.guards_seq_hi[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Room Guard Skill[") + std::to_string(i) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.guards_seq_hi[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Room Guard Sequence High[") + std::to_string(i) + std::string("]"); - registerGameProperty(propertyName, &_gameState->level.guards_seq_hi[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); - } + propertyName = std::string("Room Guard Sequence High[") + std::to_string(i) + std::string("]"); + registerGameProperty(propertyName, &_gameState->level.guards_seq_hi[i], Property::datatype_t::dt_uint8, Property::endianness_t::little); + } // Registering Moving Objects for (size_t i = 0; i < 24; i++) - { - propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Pos X"); - registerGameProperty(propertyName, &_gameState->mobs[i].xh, Property::datatype_t::dt_uint8, Property::endianness_t::little); + { + propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Pos X"); + registerGameProperty(propertyName, &_gameState->mobs[i].xh, Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Pos Y"); - registerGameProperty(propertyName, &_gameState->mobs[i].y, Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Pos Y"); + registerGameProperty(propertyName, &_gameState->mobs[i].y, Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Room"); - registerGameProperty(propertyName, &_gameState->mobs[i].room, Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Room"); + registerGameProperty(propertyName, &_gameState->mobs[i].room, Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Speed"); - registerGameProperty(propertyName, &_gameState->mobs[i].speed, Property::datatype_t::dt_int8, Property::endianness_t::little); + propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Speed"); + registerGameProperty(propertyName, &_gameState->mobs[i].speed, Property::datatype_t::dt_int8, Property::endianness_t::little); - propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Type"); - registerGameProperty(propertyName, &_gameState->mobs[i].type, Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Type"); + registerGameProperty(propertyName, &_gameState->mobs[i].type, Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Row"); - registerGameProperty(propertyName, &_gameState->mobs[i].row, Property::datatype_t::dt_uint8, Property::endianness_t::little); - } + propertyName = std::string("Moving Object[") + std::to_string(i) + std::string("] Row"); + registerGameProperty(propertyName, &_gameState->mobs[i].row, Property::datatype_t::dt_uint8, Property::endianness_t::little); + } // Registering Transformable Objects for (size_t i = 0; i < 30; i++) - { - propertyName = std::string("Transformable Object[") + std::to_string(i) + std::string("] Tile"); - registerGameProperty(propertyName, &_gameState->trobs[i].tilepos, Property::datatype_t::dt_uint8, Property::endianness_t::little); + { + propertyName = std::string("Transformable Object[") + std::to_string(i) + std::string("] Tile"); + registerGameProperty(propertyName, &_gameState->trobs[i].tilepos, Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Transformable Object[") + std::to_string(i) + std::string("] Room"); - registerGameProperty(propertyName, &_gameState->trobs[i].room, Property::datatype_t::dt_uint8, Property::endianness_t::little); + propertyName = std::string("Transformable Object[") + std::to_string(i) + std::string("] Room"); + registerGameProperty(propertyName, &_gameState->trobs[i].room, Property::datatype_t::dt_uint8, Property::endianness_t::little); - propertyName = std::string("Transformable Object[") + std::to_string(i) + std::string("] Type"); - registerGameProperty(propertyName, &_gameState->trobs[i].type, Property::datatype_t::dt_int8, Property::endianness_t::little); - } + propertyName = std::string("Transformable Object[") + std::to_string(i) + std::string("] Type"); + registerGameProperty(propertyName, &_gameState->trobs[i].type, Property::datatype_t::dt_int8, Property::endianness_t::little); + } } __INLINE__ void advanceStateImpl(const std::string &input) override { _emulator->advanceState(input); } @@ -401,25 +401,25 @@ class PrinceOfPersia final : public jaffarPlus::Game jaffarCommon::logger::log("[J+] + Moving Objects:\n"); for (int i = 0; i < _gameState->mobs_count; ++i) - { - const auto &mob = (_gameState->mobs)[i]; - jaffarCommon::logger::log("[J+] + Room: %d, X: %d, Y: %d, Speed: %d, Type: %d, Row: %d\n", mob.room, mob.xh, mob.y, mob.speed, mob.type, mob.row); - } + { + const auto &mob = (_gameState->mobs)[i]; + jaffarCommon::logger::log("[J+] + Room: %d, X: %d, Y: %d, Speed: %d, Type: %d, Row: %d\n", mob.room, mob.xh, mob.y, mob.speed, mob.type, mob.row); + } jaffarCommon::logger::log("[J+] + Transformable Objects:\n"); for (int i = 0; i < _gameState->trobs_count; i++) - { - const auto &trob = _gameState->trobs[i]; - const auto roomIdx = trob.room - 1; - const auto tileIdx = trob.tilepos - 1; - - jaffarCommon::logger::log("[J+] + Type: %u, Room: %u, Pos: %u, FG: %u, BG: %u\n", - trob.type, - trob.room, - trob.tilepos, - _gameState->level.fg[roomIdx][tileIdx], - _gameState->level.bg[roomIdx][tileIdx]); - } + { + const auto &trob = _gameState->trobs[i]; + const auto roomIdx = trob.room - 1; + const auto tileIdx = trob.tilepos - 1; + + jaffarCommon::logger::log("[J+] + Type: %u, Room: %u, Pos: %u, FG: %u, BG: %u\n", + trob.type, + trob.room, + trob.tilepos, + _gameState->level.fg[roomIdx][tileIdx], + _gameState->level.bg[roomIdx][tileIdx]); + } if (std::abs(_kidPosXMagnet.intensity) > 0.0f) jaffarCommon::logger::log("[J+] + Kid Pos X Magnet - Intensity: %.1f, Center: %u\n", _kidPosXMagnet.intensity, _kidPosXMagnet.position); @@ -442,75 +442,75 @@ class PrinceOfPersia final : public jaffarPlus::Game bool recognizedActionType = false; if (actionType == "Set Kid Pos X Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto position = jaffarCommon::json::getNumber(actionJs, "Position"); - auto room = jaffarCommon::json::getNumber(actionJs, "Room"); - auto action = [=, this]() { _kidPosXMagnet = pointMagnet_t{.intensity = _gameState->Kid.room == room ? intensity : 0.0f, .position = position}; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto position = jaffarCommon::json::getNumber(actionJs, "Position"); + auto room = jaffarCommon::json::getNumber(actionJs, "Room"); + auto action = [=, this]() { _kidPosXMagnet = pointMagnet_t{.intensity = _gameState->Kid.room == room ? intensity : 0.0f, .position = position}; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set Kid Pos Y Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto position = jaffarCommon::json::getNumber(actionJs, "Position"); - auto room = jaffarCommon::json::getNumber(actionJs, "Room"); - auto action = [=, this]() { _kidPosYMagnet = pointMagnet_t{.intensity = _gameState->Kid.room == room ? intensity : 0.0f, .position = position}; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto position = jaffarCommon::json::getNumber(actionJs, "Position"); + auto room = jaffarCommon::json::getNumber(actionJs, "Room"); + auto action = [=, this]() { _kidPosYMagnet = pointMagnet_t{.intensity = _gameState->Kid.room == room ? intensity : 0.0f, .position = position}; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set Guard Pos X Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto position = jaffarCommon::json::getNumber(actionJs, "Position"); - auto room = jaffarCommon::json::getNumber(actionJs, "Room"); - auto action = [=, this]() { _guardPosXMagnet = pointMagnet_t{.intensity = _gameState->Guard.room == room ? intensity : 0.0f, .position = position}; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto position = jaffarCommon::json::getNumber(actionJs, "Position"); + auto room = jaffarCommon::json::getNumber(actionJs, "Room"); + auto action = [=, this]() { _guardPosXMagnet = pointMagnet_t{.intensity = _gameState->Guard.room == room ? intensity : 0.0f, .position = position}; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set Guard Pos Y Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto position = jaffarCommon::json::getNumber(actionJs, "Position"); - auto room = jaffarCommon::json::getNumber(actionJs, "Room"); - auto action = [=, this]() { _guardPosYMagnet = pointMagnet_t{.intensity = _gameState->Guard.room == room ? intensity : 0.0f, .position = position}; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto position = jaffarCommon::json::getNumber(actionJs, "Position"); + auto room = jaffarCommon::json::getNumber(actionJs, "Room"); + auto action = [=, this]() { _guardPosYMagnet = pointMagnet_t{.intensity = _gameState->Guard.room == room ? intensity : 0.0f, .position = position}; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set Kid Direction Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto action = [=, this]() { _kidDirectionMagnet = intensity; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto action = [=, this]() { _kidDirectionMagnet = intensity; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set Level Door Open Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto action = [=, this]() { _levelDoorOpenMagnet = intensity; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto action = [=, this]() { _levelDoorOpenMagnet = intensity; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set United With Shadow Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto action = [=, this]() { _unitedWithShadowMagnet = intensity; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto action = [=, this]() { _unitedWithShadowMagnet = intensity; }; + rule.addAction(action); + recognizedActionType = true; } if (actionType == "Set Guard HP Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto action = [=, this]() { _guardHPMagnet = intensity; }; - rule.addAction(action); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto action = [=, this]() { _guardHPMagnet = intensity; }; + rule.addAction(action); + recognizedActionType = true; } return recognizedActionType; diff --git a/games/snes/christmasCraze.hpp b/games/snes/christmasCraze.hpp index d95b2400..80b2d01a 100644 --- a/games/snes/christmasCraze.hpp +++ b/games/snes/christmasCraze.hpp @@ -98,11 +98,11 @@ class ChristmasCraze final : public jaffarPlus::Game void printInfoImpl() const override { if (std::abs(_pointMagnet.intensity) > 0.0f) - { - jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); - jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _player1DistanceToPointX); - jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _player1DistanceToPointY); - jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _player1DistanceToPoint); + { + jaffarCommon::logger::log("[J+] + Point Magnet Intensity: %.5f, X: %3.3f, Y: %3.3f\n", _pointMagnet.intensity, _pointMagnet.x, _pointMagnet.y); + jaffarCommon::logger::log("[J+] + Distance X %3.3f\n", _player1DistanceToPointX); + jaffarCommon::logger::log("[J+] + Distance Y %3.3f\n", _player1DistanceToPointY); + jaffarCommon::logger::log("[J+] + Total Distance %3.3f\n", _player1DistanceToPoint); } } @@ -111,12 +111,12 @@ class ChristmasCraze final : public jaffarPlus::Game bool recognizedActionType = false; if (actionType == "Set Point Magnet") - { - auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); - auto x = jaffarCommon::json::getNumber(actionJs, "X"); - auto y = jaffarCommon::json::getNumber(actionJs, "Y"); - rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); - recognizedActionType = true; + { + auto intensity = jaffarCommon::json::getNumber(actionJs, "Intensity"); + auto x = jaffarCommon::json::getNumber(actionJs, "X"); + auto y = jaffarCommon::json::getNumber(actionJs, "Y"); + rule.addAction([=, this]() { this->_pointMagnet = pointMagnet_t{.intensity = intensity, .x = x, .y = y}; }); + recognizedActionType = true; } return recognizedActionType; diff --git a/source/condition.hpp b/source/condition.hpp index 4e5715a5..3b50edd1 100644 --- a/source/condition.hpp +++ b/source/condition.hpp @@ -63,17 +63,17 @@ class _vCondition : public Condition , _immediate2(immediate2) { switch (_opType) - { - case op_equal: _opFcPtr = _opEqual; break; - case op_not_equal: _opFcPtr = _opNotEqual; break; - case op_greater: _opFcPtr = _opGreater; break; - case op_greater_or_equal: _opFcPtr = _opGreaterOrEqual; break; - case op_less: _opFcPtr = _opLess; break; - case op_less_or_equal: _opFcPtr = _opLessOrEqual; break; - case op_bit_true: _opFcPtr = _opBitTrue; break; - case op_bit_false: _opFcPtr = _opBitFalse; break; - default: break; - } + { + case op_equal: _opFcPtr = _opEqual; break; + case op_not_equal: _opFcPtr = _opNotEqual; break; + case op_greater: _opFcPtr = _opGreater; break; + case op_greater_or_equal: _opFcPtr = _opGreaterOrEqual; break; + case op_less: _opFcPtr = _opLess; break; + case op_less_or_equal: _opFcPtr = _opLessOrEqual; break; + case op_bit_true: _opFcPtr = _opBitTrue; break; + case op_bit_false: _opFcPtr = _opBitFalse; break; + default: break; + } } __INLINE__ bool evaluate() const diff --git a/source/driver.hpp b/source/driver.hpp index 25b6dfa9..33f6b155 100644 --- a/source/driver.hpp +++ b/source/driver.hpp @@ -114,46 +114,46 @@ class Driver final // Running engine until a termination point while (true) - { - // If found winning state, report it now - if (_endOnFirstWinState && _engine->getWinStatesFound() > 0) { - exitReason = exitReason_t::winStateFound; - break; + // If found winning state, report it now + if (_endOnFirstWinState && _engine->getWinStatesFound() > 0) + { + exitReason = exitReason_t::winStateFound; + break; + } + + // If ran out of states, finish now + if (_engine->getStateCount() == 0) + { + exitReason = exitReason_t::outOfStates; + break; + } + + // If maximum step established and reached, finish now + if (_maxSteps > 0 && _currentStep >= _maxSteps) + { + if (_winStatesFound > 0) exitReason = exitReason_t::winStateFound; + if (_winStatesFound == 0) exitReason = exitReason_t::maximumStepReached; + break; + } + + // Updating best and worst states + updateBestState(); + updateWorstState(); + + // Printing information + printInfo(); + + // Running engine step + _engine->runStep(); + + // Summing amount of win states found + _winStatesFound = _engine->getWinStatesFound(); + + // Increasing step counter + _currentStep++; } - // If ran out of states, finish now - if (_engine->getStateCount() == 0) - { - exitReason = exitReason_t::outOfStates; - break; - } - - // If maximum step established and reached, finish now - if (_maxSteps > 0 && _currentStep >= _maxSteps) - { - if (_winStatesFound > 0) exitReason = exitReason_t::winStateFound; - if (_winStatesFound == 0) exitReason = exitReason_t::maximumStepReached; - break; - } - - // Updating best and worst states - updateBestState(); - updateWorstState(); - - // Printing information - printInfo(); - - // Running engine step - _engine->runStep(); - - // Summing amount of win states found - _winStatesFound = _engine->getWinStatesFound(); - - // Increasing step counter - _currentStep++; - } - // Setting finalized flag _hasFinished = true; @@ -207,25 +207,25 @@ class Driver final // Run loop while the driver is still running while (_hasFinished == false) - { - // Sleeping for 100ms intervals to prevent excessive overheads - usleep(100000); - - // Getting time elapsed since last save - auto currentTime = jaffarCommon::timing::now(); - auto timeElapsedSinceLastSave = jaffarCommon::timing::timeDeltaSeconds(currentTime, lastSaveTime); - - // Checking if we need to save best state - if (timeElapsedSinceLastSave > _saveIntermediateFrequency && _currentStep > 1) { - // Saving worst and best state information - saveBestStateInformation(); - saveWorstStateInformation(); - - // Resetting timer - lastSaveTime = jaffarCommon::timing::now(); + // Sleeping for 100ms intervals to prevent excessive overheads + usleep(100000); + + // Getting time elapsed since last save + auto currentTime = jaffarCommon::timing::now(); + auto timeElapsedSinceLastSave = jaffarCommon::timing::timeDeltaSeconds(currentTime, lastSaveTime); + + // Checking if we need to save best state + if (timeElapsedSinceLastSave > _saveIntermediateFrequency && _currentStep > 1) + { + // Saving worst and best state information + saveBestStateInformation(); + saveWorstStateInformation(); + + // Resetting timer + lastSaveTime = jaffarCommon::timing::now(); + } } - } } void updateWorstState() @@ -265,29 +265,29 @@ class Driver final // If we haven't found any winning state, simply use the currently best state if (_winStatesFound == 0) - { - // Getting best state so far - auto bestState = _engine->getStateDb()->getBestState(); + { + // Getting best state so far + auto bestState = _engine->getStateDb()->getBestState(); - // Saving best state into the storage - memcpy(_bestStateStorage.data(), bestState, _stateSize); + // Saving best state into the storage + memcpy(_bestStateStorage.data(), bestState, _stateSize); } // If we have found a winning state in this step that improves on the current best, save it now if (_engine->getWinStatesFound() > 0) - { - // Getting best win state (best reward) for the current step - auto winStateEntry = _engine->getStepBestWinState(); - - // If the reward if better than the current best, then make it the new best state - if (winStateEntry.reward > _bestWinStateReward) { - // Saving new best - _bestWinStateReward = winStateEntry.reward; - - // Saving win state into the storage - memcpy(_bestStateStorage.data(), winStateEntry.stateData, _stateSize); - } + // Getting best win state (best reward) for the current step + auto winStateEntry = _engine->getStepBestWinState(); + + // If the reward if better than the current best, then make it the new best state + if (winStateEntry.reward > _bestWinStateReward) + { + // Saving new best + _bestWinStateReward = winStateEntry.reward; + + // Saving win state into the storage + memcpy(_bestStateStorage.data(), winStateEntry.stateData, _stateSize); + } } // Loading best state state into runner diff --git a/source/emulator.hpp b/source/emulator.hpp index 05b284e5..805756d9 100644 --- a/source/emulator.hpp +++ b/source/emulator.hpp @@ -49,13 +49,14 @@ class Emulator __INLINE__ InputSet::inputIndex_t registerInput(const std::string inputString) { // Registration is done only at the beginning with linear complexity O(n) to optimize for read access O(1) - for (size_t i = 0; i < _inputMap.size(); i++) if (inputString == _inputMap[i].inputString) return i; + for (size_t i = 0; i < _inputMap.size(); i++) + if (inputString == _inputMap[i].inputString) return i; // Otherwise, getting decoded input data from the emulator auto inputData = getInputParser()->parseInputString(inputString); // Otherwise, register it as a new entry - _inputMap.push_back( { inputString, inputData } ); + _inputMap.push_back({inputString, inputData}); // Returning current index return _inputMap.size() - 1; @@ -82,7 +83,7 @@ class Emulator virtual void deserializeState(jaffarCommon::deserializer::Base &deserializer) = 0; // Function to get a reference to the input parser from the base emulator - virtual jaffar::InputParser* getInputParser() const = 0; + virtual jaffar::InputParser *getInputParser() const = 0; // Function to print debug information, whatever it might be virtual void printInfo() const = 0; diff --git a/source/engine.hpp b/source/engine.hpp index 673209df..1f632a47 100644 --- a/source/engine.hpp +++ b/source/engine.hpp @@ -59,15 +59,15 @@ class Engine final bool stateDatabaseTypeRecognized = false; if (stateDatabaseType == "Plain") - { - _stateDb = std::make_unique(r, jaffarCommon::json::getObject(engineConfig, "State Database")); - stateDatabaseTypeRecognized = true; + { + _stateDb = std::make_unique(r, jaffarCommon::json::getObject(engineConfig, "State Database")); + stateDatabaseTypeRecognized = true; } if (stateDatabaseType == "Numa Aware") - { - _stateDb = std::make_unique(r, jaffarCommon::json::getObject(engineConfig, "State Database")); - stateDatabaseTypeRecognized = true; + { + _stateDb = std::make_unique(r, jaffarCommon::json::getObject(engineConfig, "State Database")); + stateDatabaseTypeRecognized = true; } if (stateDatabaseTypeRecognized == false) JAFFAR_THROW_LOGIC("State database type '%s' not recognized", stateDatabaseType.c_str()); @@ -465,10 +465,10 @@ class Engine final // Printing candidate moves jaffarCommon::logger::log("[J+] Candidate Moves:\n"); for (const auto &entry : _candidateInputsDetected) - { - jaffarCommon::logger::log("[J+] + Hash: %s\n", jaffarCommon::hash::hashToString(entry.first).c_str()); - for (const auto input : entry.second) jaffarCommon::logger::log("[J+] + %3lu %s\n", input, _runners[0]->getInputStringFromIndex(input).c_str()); - } + { + jaffarCommon::logger::log("[J+] + Hash: %s\n", jaffarCommon::hash::hashToString(entry.first).c_str()); + for (const auto input : entry.second) jaffarCommon::logger::log("[J+] + %3lu %s\n", input, _runners[0]->getInputStringFromIndex(input).c_str()); + } } private: @@ -508,60 +508,60 @@ class Engine final // While there are still states in the database, keep on grabbing them while (baseStateData != nullptr) - { - // Increasing base state counter - _stepBaseStatesProcessed++; - - // Load state into runner via the state database - const auto t0 = jaffarCommon::timing::now(); - _stateDb->loadStateIntoRunner(*r, baseStateData); - _runnerStateLoadThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t0); - - // Getting possible inputs - const auto t1 = jaffarCommon::timing::now(); - const auto &possibleInputs = r->getAllowedInputs(); - _getAllowedInputsThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t1); - - // Trying out each possible input in the set - for (auto inputItr = possibleInputs.begin(); inputItr != possibleInputs.end(); inputItr++) runNewInput(*r, baseStateData, *inputItr); - - // Getting candidate moves - const auto t2 = jaffarCommon::timing::now(); - auto candidateInputs = r->getCandidateInputs(); - _getCandidateInputsThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t2); - - // Finding unique candidate inputs - std::vector uniqueCandidateInputs; - for (const auto &input : candidateInputs) - if (possibleInputs.contains(input) == false) uniqueCandidateInputs.push_back(input); - - // Run each candidate input - for (const auto input : uniqueCandidateInputs) { - // Getting discriminating hash key to identify this type of states - auto stateInputHash = r->getGame()->getStateInputHash(); - - // Making sure we don't try the input if it was already detected - if (_candidateInputsDetected.contains(stateInputHash)) - if (_candidateInputsDetected[stateInputHash].contains(input)) continue; - - // Running input - const auto result = runNewInput(*r, baseStateData, input); - - // If this is not a repeated state, store it as new candidate input - if (result != inputResult_t::repeated) _candidateInputsDetected[stateInputHash].insert(input); + // Increasing base state counter + _stepBaseStatesProcessed++; + + // Load state into runner via the state database + const auto t0 = jaffarCommon::timing::now(); + _stateDb->loadStateIntoRunner(*r, baseStateData); + _runnerStateLoadThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t0); + + // Getting possible inputs + const auto t1 = jaffarCommon::timing::now(); + const auto &possibleInputs = r->getAllowedInputs(); + _getAllowedInputsThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t1); + + // Trying out each possible input in the set + for (auto inputItr = possibleInputs.begin(); inputItr != possibleInputs.end(); inputItr++) runNewInput(*r, baseStateData, *inputItr); + + // Getting candidate moves + const auto t2 = jaffarCommon::timing::now(); + auto candidateInputs = r->getCandidateInputs(); + _getCandidateInputsThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t2); + + // Finding unique candidate inputs + std::vector uniqueCandidateInputs; + for (const auto &input : candidateInputs) + if (possibleInputs.contains(input) == false) uniqueCandidateInputs.push_back(input); + + // Run each candidate input + for (const auto input : uniqueCandidateInputs) + { + // Getting discriminating hash key to identify this type of states + auto stateInputHash = r->getGame()->getStateInputHash(); + + // Making sure we don't try the input if it was already detected + if (_candidateInputsDetected.contains(stateInputHash)) + if (_candidateInputsDetected[stateInputHash].contains(input)) continue; + + // Running input + const auto result = runNewInput(*r, baseStateData, input); + + // If this is not a repeated state, store it as new candidate input + if (result != inputResult_t::repeated) _candidateInputsDetected[stateInputHash].insert(input); + } + + // Return base state to the free state queue + const auto t8 = jaffarCommon::timing::now(); + _stateDb->returnFreeState(baseStateData); + _returnFreeStateThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t8); + + // Pulling next state from the database + const auto t9 = jaffarCommon::timing::now(); + baseStateData = _stateDb->popState(); + _popBaseStateDbThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t9); } - - // Return base state to the free state queue - const auto t8 = jaffarCommon::timing::now(); - _stateDb->returnFreeState(baseStateData); - _returnFreeStateThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t8); - - // Pulling next state from the database - const auto t9 = jaffarCommon::timing::now(); - baseStateData = _stateDb->popState(); - _popBaseStateDbThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t9); - } } __INLINE__ inputResult_t runNewInput(Runner &r, const void *baseStateData, const InputSet::inputIndex_t input) @@ -590,10 +590,10 @@ class Engine final const auto stateCheckpointLevel = r.getGame()->getCheckpointLevel(); const auto stateCheckpointTolerance = r.getGame()->getCheckpointTolerance(); if (stateCheckpointLevel > _checkpointLevel) - { - _checkpointLevel = stateCheckpointLevel; - _checkpointTolerance = stateCheckpointTolerance; - _checkpointCutoff = _currentStep + stateCheckpointTolerance; + { + _checkpointLevel = stateCheckpointLevel; + _checkpointTolerance = stateCheckpointTolerance; + _checkpointCutoff = _currentStep + stateCheckpointTolerance; } // Returning result @@ -626,11 +626,11 @@ class Engine final // Checking whether this state meets checkpoint if (_currentStep > _checkpointCutoff) - { - const auto stateCheckpointLevel = r.getGame()->getCheckpointLevel(); + { + const auto stateCheckpointLevel = r.getGame()->getCheckpointLevel(); - // If state does not meet checkpoint, then do not process it further - if (stateCheckpointLevel < _checkpointLevel) return inputResult_t::droppedCheckpoint; + // If state does not meet checkpoint, then do not process it further + if (stateCheckpointLevel < _checkpointLevel) return inputResult_t::droppedCheckpoint; } // Determining state type @@ -661,48 +661,48 @@ class Engine final // If this is a win state, register it and return if (stateType == Game::stateType_t::win) - { - ///////////// Best win state needs to be stored if its better than any previous one found - - // Check if the new win state is the best and store it in that case - _stepBestWinStateLock.lock(); - if (reward > _stepBestWinState.reward) { - _stateDb->saveStateFromRunner(r, _stepBestWinState.stateData); - _stepBestWinState.reward = reward; - } - _stepBestWinStateLock.unlock(); - - // Freeing up the state data - const auto t7 = jaffarCommon::timing::now(); - _stateDb->returnFreeState(newStateData); - _returnFreeStateThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t7); + ///////////// Best win state needs to be stored if its better than any previous one found + + // Check if the new win state is the best and store it in that case + _stepBestWinStateLock.lock(); + if (reward > _stepBestWinState.reward) + { + _stateDb->saveStateFromRunner(r, _stepBestWinState.stateData); + _stepBestWinState.reward = reward; + } + _stepBestWinStateLock.unlock(); + + // Freeing up the state data + const auto t7 = jaffarCommon::timing::now(); + _stateDb->returnFreeState(newStateData); + _returnFreeStateThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t7); - // Returning a win result - return inputResult_t::win; + // Returning a win result + return inputResult_t::win; } // If this is a normal state and has possible inputs store it in the next state database if (stateType == Game::stateType_t::normal) - { - // If this is a normal state, push into the state database - const auto t8 = jaffarCommon::timing::now(); - auto success = _stateDb->pushState(reward, r, newStateData); - _runnerStateSaveThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t8); - - // Attempting to serialize state and push it into the database - // This might fail when using differential serialization due to insufficient space for differentials - // In that, case we just drop the state and continue, while keeping a counter - if (success == false) { - // Freeing up state memory - const auto t9 = jaffarCommon::timing::now(); - _stateDb->returnFreeState(newStateData); - _returnFreeStateThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t9); - - // Returning dropped result by failed serialization - return inputResult_t::droppedFailedSerialization; - } + // If this is a normal state, push into the state database + const auto t8 = jaffarCommon::timing::now(); + auto success = _stateDb->pushState(reward, r, newStateData); + _runnerStateSaveThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t8); + + // Attempting to serialize state and push it into the database + // This might fail when using differential serialization due to insufficient space for differentials + // In that, case we just drop the state and continue, while keeping a counter + if (success == false) + { + // Freeing up state memory + const auto t9 = jaffarCommon::timing::now(); + _stateDb->returnFreeState(newStateData); + _returnFreeStateThreadRawTime += jaffarCommon::timing::timeDeltaNanoseconds(jaffarCommon::timing::now(), t9); + + // Returning dropped result by failed serialization + return inputResult_t::droppedFailedSerialization; + } } // If store succeeded, return a normal execution diff --git a/source/game.hpp b/source/game.hpp index 1c37a264..082e930a 100644 --- a/source/game.hpp +++ b/source/game.hpp @@ -62,29 +62,29 @@ class Game // Registering printable properties for (const auto &property : _printablePropertyNames) - { - // Getting property name hash - const auto propertyHash = jaffarCommon::hash::hashString(property); + { + // Getting property name hash + const auto propertyHash = jaffarCommon::hash::hashString(property); - // Checking the property is registered - if (_propertyMap.contains(propertyHash) == false) JAFFAR_THROW_LOGIC("Property '%s' is not registered in this game", property.c_str()); + // Checking the property is registered + if (_propertyMap.contains(propertyHash) == false) JAFFAR_THROW_LOGIC("Property '%s' is not registered in this game", property.c_str()); - // If so, add its pointer to the print property vector - _propertyPrintVector.push_back(_propertyMap.at(propertyHash).get()); - } + // If so, add its pointer to the print property vector + _propertyPrintVector.push_back(_propertyMap.at(propertyHash).get()); + } // Registering hashable properties for (const auto &property : _hashablePropertyNames) - { - // Getting property name hash - const auto propertyHash = jaffarCommon::hash::hashString(property); + { + // Getting property name hash + const auto propertyHash = jaffarCommon::hash::hashString(property); - // Checking the property is registered - if (_propertyMap.contains(propertyHash) == false) JAFFAR_THROW_LOGIC("Property '%s' is not registered in this game", property.c_str()); + // Checking the property is registered + if (_propertyMap.contains(propertyHash) == false) JAFFAR_THROW_LOGIC("Property '%s' is not registered in this game", property.c_str()); - // If so, add its pointer to the print property vector - _propertyHashVector.push_back(_propertyMap.at(propertyHash).get()); - } + // If so, add its pointer to the print property vector + _propertyHashVector.push_back(_propertyMap.at(propertyHash).get()); + } // Now parsing rules parseRules(_rulesJs); @@ -223,32 +223,32 @@ class Game // Printing game properties defined in the script file jaffarCommon::logger::log("[J+] + Game Properties: \n"); for (const auto &p : _propertyPrintVector) - { - // Getting property name - const auto &name = p->getName(); - - // Printing property name first - jaffarCommon::logger::log("[J+] + '%s':", name.c_str()); - - // Calculating separation spaces for this property - const auto propertySeparatorSize = separatorSize + maximumNameSize - name.size(); - - // Printing separator spaces - for (size_t i = 0; i < propertySeparatorSize; i++) jaffarCommon::logger::log(" "); - - // Then printing separator spaces - if (p->getDatatype() == Property::datatype_t::dt_int8) jaffarCommon::logger::log("0x%02X (%03d)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_int16) jaffarCommon::logger::log("0x%04X (%05d)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_int32) jaffarCommon::logger::log("0x%08X (%10d)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_int64) jaffarCommon::logger::log("0x%16lX (%ld)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_uint8) jaffarCommon::logger::log("0x%02X (%03u)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_uint16) jaffarCommon::logger::log("0x%04X (%05u)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_uint32) jaffarCommon::logger::log("0x%08X (%10u)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_uint64) jaffarCommon::logger::log("0x%16lX (%lu)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_float32) jaffarCommon::logger::log("%f (0x%X)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_float64) jaffarCommon::logger::log("%f (0x%lX)\n", p->getValue(), p->getValue()); - if (p->getDatatype() == Property::datatype_t::dt_bool) jaffarCommon::logger::log("%1u\n", p->getValue()); - } + { + // Getting property name + const auto &name = p->getName(); + + // Printing property name first + jaffarCommon::logger::log("[J+] + '%s':", name.c_str()); + + // Calculating separation spaces for this property + const auto propertySeparatorSize = separatorSize + maximumNameSize - name.size(); + + // Printing separator spaces + for (size_t i = 0; i < propertySeparatorSize; i++) jaffarCommon::logger::log(" "); + + // Then printing separator spaces + if (p->getDatatype() == Property::datatype_t::dt_int8) jaffarCommon::logger::log("0x%02X (%03d)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_int16) jaffarCommon::logger::log("0x%04X (%05d)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_int32) jaffarCommon::logger::log("0x%08X (%10d)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_int64) jaffarCommon::logger::log("0x%16lX (%ld)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_uint8) jaffarCommon::logger::log("0x%02X (%03u)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_uint16) jaffarCommon::logger::log("0x%04X (%05u)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_uint32) jaffarCommon::logger::log("0x%08X (%10u)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_uint64) jaffarCommon::logger::log("0x%16lX (%lu)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_float32) jaffarCommon::logger::log("%f (0x%X)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_float64) jaffarCommon::logger::log("%f (0x%lX)\n", p->getValue(), p->getValue()); + if (p->getDatatype() == Property::datatype_t::dt_bool) jaffarCommon::logger::log("%1u\n", p->getValue()); + } // Printing game-specific stuff now printInfoImpl(); @@ -262,23 +262,23 @@ class Game // Second, check which unsatisfied rules have been satisfied now for (auto &entry : _rules) - { - // Getting rule - auto &rule = *entry.second; + { + // Getting rule + auto &rule = *entry.second; - // Getting rule index - const auto ruleIdx = rule.getIndex(); + // Getting rule index + const auto ruleIdx = rule.getIndex(); - // Evaluate rule only if it's not yet satisfied - if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == false) - { - // Checking if conditions are met - bool isSatisfied = rule.evaluate(); + // Evaluate rule only if it's not yet satisfied + if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == false) + { + // Checking if conditions are met + bool isSatisfied = rule.evaluate(); - // If it's achieved, update its status and run its actions - if (isSatisfied) satisfyRule(rule); + // If it's achieved, update its status and run its actions + if (isSatisfied) satisfyRule(rule); + } } - } // Running game-specific rule actions runGameSpecificRuleActions(); @@ -291,17 +291,17 @@ class Game { // First, checking if the rules have been satisfied for (auto &entry : _rules) - { - // Getting rule - auto &rule = *entry.second; + { + // Getting rule + auto &rule = *entry.second; - // Getting rule index - const auto ruleIdx = rule.getIndex(); + // Getting rule index + const auto ruleIdx = rule.getIndex(); - // Run ations only if rule is satisfied - if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == true) - for (const auto &action : rule.getActions()) action(); - } + // Run ations only if rule is satisfied + if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == true) + for (const auto &action : rule.getActions()) action(); + } } __INLINE__ void updateGameStateType() @@ -314,30 +314,30 @@ class Game // Second, we run the specified actions for the satisfied rules in label order for (auto &entry : _rules) - { - // Getting rule - auto &rule = *entry.second; - - // Getting rule index - const auto ruleIdx = rule.getIndex(); - - // Run actions - if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == true) { - // Modify game state, depending on rule type - - // Evaluate checkpoint rule and store tolerance if specified - if (rule.isCheckpointRule()) - { - _checkpointLevel++; - _checkpointTolerance = rule.getCheckpointTolerance(); + // Getting rule + auto &rule = *entry.second; + + // Getting rule index + const auto ruleIdx = rule.getIndex(); + + // Run actions + if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == true) + { + // Modify game state, depending on rule type + + // Evaluate checkpoint rule and store tolerance if specified + if (rule.isCheckpointRule()) + { + _checkpointLevel++; + _checkpointTolerance = rule.getCheckpointTolerance(); + } + + // Winning in the same rule superseeds checkpoint, and failing superseed everything + if (rule.isWinRule()) _stateType = stateType_t::win; + if (rule.isFailRule()) _stateType = stateType_t::fail; } - - // Winning in the same rule superseeds checkpoint, and failing superseed everything - if (rule.isWinRule()) _stateType = stateType_t::win; - if (rule.isFailRule()) _stateType = stateType_t::fail; } - } } __INLINE__ void updateReward() @@ -347,23 +347,23 @@ class Game // Second, we get the reward from every satisfied rule for (auto &entry : _rules) - { - // Getting rule - auto &rule = *entry.second; + { + // Getting rule + auto &rule = *entry.second; - // Getting rule index - const auto ruleIdx = rule.getIndex(); + // Getting rule index + const auto ruleIdx = rule.getIndex(); - // Run actions - if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == true) - { - // Getting reward from satisfied rule - const auto ruleReward = rule.getReward(); + // Run actions + if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), ruleIdx) == true) + { + // Getting reward from satisfied rule + const auto ruleReward = rule.getReward(); - // Adding it to the state reward - _reward += ruleReward; + // Adding it to the state reward + _reward += ruleReward; + } } - } // Adding any game-specific rewards _reward += calculateGameSpecificReward(); @@ -399,55 +399,55 @@ class Game // If value is a number, take it as immediate if (conditionJs["Value"].is_number()) - { - if (datatype1 == Property::datatype_t::dt_uint8) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_uint16) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_uint32) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_uint64) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - - if (datatype1 == Property::datatype_t::dt_int8) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_int16) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_int32) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_int64) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - - if (datatype1 == Property::datatype_t::dt_float32) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); - if (datatype1 == Property::datatype_t::dt_float64) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + { + if (datatype1 == Property::datatype_t::dt_uint8) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_uint16) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_uint32) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_uint64) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + + if (datatype1 == Property::datatype_t::dt_int8) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_int16) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_int32) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_int64) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + + if (datatype1 == Property::datatype_t::dt_float32) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + if (datatype1 == Property::datatype_t::dt_float64) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); } // If value is a boolean, take it as immediate if (conditionJs["Value"].is_boolean()) - { - if (datatype1 == Property::datatype_t::dt_bool) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); + { + if (datatype1 == Property::datatype_t::dt_bool) return std::make_unique<_vCondition>(opType, property1, nullptr, 0, conditionJs["Value"].get()); } // If value is a string, take value as property number 2 if (conditionJs["Value"].is_string()) - { - // Parsing second operand (property name) - const auto &property2Name = jaffarCommon::json::getString(conditionJs, "Value"); + { + // Parsing second operand (property name) + const auto &property2Name = jaffarCommon::json::getString(conditionJs, "Value"); - // Getting property name hash, for indexing - const auto property2NameHash = jaffarCommon::hash::hashString(property2Name); + // Getting property name hash, for indexing + const auto property2NameHash = jaffarCommon::hash::hashString(property2Name); - // Making sure the requested property exists in the property map - if (_propertyMap.contains(property2NameHash) == false) JAFFAR_THROW_LOGIC("[ERROR] Property '%s' has not been declared.\n", property2Name.c_str()); + // Making sure the requested property exists in the property map + if (_propertyMap.contains(property2NameHash) == false) JAFFAR_THROW_LOGIC("[ERROR] Property '%s' has not been declared.\n", property2Name.c_str()); - // Getting property object - const auto property2 = _propertyMap[property2NameHash].get(); + // Getting property object + const auto property2 = _propertyMap[property2NameHash].get(); - if (datatype1 == Property::datatype_t::dt_uint8) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_uint16) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_uint32) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_uint64) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_uint8) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_uint16) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_uint32) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_uint64) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_int8) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_int16) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_int32) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_int64) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_int8) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_int16) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_int32) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_int64) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_float32) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_float64) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); - if (datatype1 == Property::datatype_t::dt_bool) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_float32) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_float64) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); + if (datatype1 == Property::datatype_t::dt_bool) return std::make_unique<_vCondition>(opType, property1, property2, 0, 0); } JAFFAR_THROW_LOGIC("[ERROR] Rule contains an invalid 'Value' key.\n", conditionJs["Value"].dump().c_str()); @@ -484,7 +484,7 @@ class Game virtual jaffarCommon::hash::hash_t getStateInputHash() = 0; // Function to enable a game code to provide additional allowed inputs based on complex decisions - virtual __INLINE__ void getAdditionalAllowedInputs(std::set& allowedInputSet) { } + virtual __INLINE__ void getAdditionalAllowedInputs(std::set &allowedInputSet) {} protected: @@ -509,25 +509,25 @@ class Game // Evaluate each rule for (size_t idx = 0; idx < rulesJson.size(); idx++) - { - // Getting specific rule json object - const auto &ruleJs = rulesJson[idx]; + { + // Getting specific rule json object + const auto &ruleJs = rulesJson[idx]; - // Check if rule is a key/value object - if (ruleJs.is_object() == false) JAFFAR_THROW_LOGIC("Passed rule is not a JSON object. Dump: \n %s", ruleJs.dump(2).c_str()); + // Check if rule is a key/value object + if (ruleJs.is_object() == false) JAFFAR_THROW_LOGIC("Passed rule is not a JSON object. Dump: \n %s", ruleJs.dump(2).c_str()); - // Getting rule label - auto label = jaffarCommon::json::getNumber(ruleJs, "Label"); + // Getting rule label + auto label = jaffarCommon::json::getNumber(ruleJs, "Label"); - // Creating new rule with the given label - auto rule = std::make_unique(idx, label); + // Creating new rule with the given label + auto rule = std::make_unique(idx, label); - // Parsing json into a rule class - parseRule(*rule, ruleJs); + // Parsing json into a rule class + parseRule(*rule, ruleJs); - // Adding new rule to the collection - _rules[rule->getLabel()] = std::move(rule); - } + // Adding new rule to the collection + _rules[rule->getLabel()] = std::move(rule); + } // Checking all cross references are correct for (const auto &rule : _rules) @@ -561,13 +561,13 @@ class Game // Parsing satisfies vector for (const auto &s : satisfiesVectorJs) - { - // Check for correct format - if (s.is_number() == false) JAFFAR_THROW_LOGIC("Wrong format provided in 'Satisfies' array in rule '%s'\n", ruleJs.dump(2).c_str()); + { + // Check for correct format + if (s.is_number() == false) JAFFAR_THROW_LOGIC("Wrong format provided in 'Satisfies' array in rule '%s'\n", ruleJs.dump(2).c_str()); - // Adding the satisfies label - rule.addSatisfyRuleLabel(s.get()); - } + // Adding the satisfies label + rule.addSatisfyRuleLabel(s.get()); + } } void parseRuleAction(Rule &rule, const nlohmann::json &actionJs) @@ -579,31 +579,31 @@ class Game bool recognizedActionType = false; if (actionType == "Add Reward") - { - rule.setReward(jaffarCommon::json::getNumber(actionJs, "Value")); - recognizedActionType = true; + { + rule.setReward(jaffarCommon::json::getNumber(actionJs, "Value")); + recognizedActionType = true; } // Storing fail state if (actionType == "Trigger Fail") - { - rule.setFailRule(true); - recognizedActionType = true; + { + rule.setFailRule(true); + recognizedActionType = true; } // Storing win state if (actionType == "Trigger Win") - { - rule.setWinRule(true); - recognizedActionType = true; + { + rule.setWinRule(true); + recognizedActionType = true; } // Storing checkpoint flags if (actionType == "Trigger Checkpoint") - { - rule.setCheckpointRule(true); - rule.setCheckpointTolerance(jaffarCommon::json::getNumber(actionJs, "Tolerance")); - recognizedActionType = true; + { + rule.setCheckpointRule(true); + rule.setCheckpointTolerance(jaffarCommon::json::getNumber(actionJs, "Tolerance")); + recognizedActionType = true; } // If not recognized yet, it must be a game specific action @@ -618,18 +618,18 @@ class Game { // Recursively run actions for the yet unsatisfied rules that are satisfied by this one and mark them as satisfied for (const auto &satisfyRuleLabel : rule.getSatisfyRuleLabels()) - { - // Making sure referenced label exists - auto it = _rules.find(satisfyRuleLabel); - if (it == _rules.end()) JAFFAR_THROW_LOGIC("[ERROR] Unrecognized rule label %lu in satisfy array\n", satisfyRuleLabel); - auto &subRule = it->second; + { + // Making sure referenced label exists + auto it = _rules.find(satisfyRuleLabel); + if (it == _rules.end()) JAFFAR_THROW_LOGIC("[ERROR] Unrecognized rule label %lu in satisfy array\n", satisfyRuleLabel); + auto &subRule = it->second; - // Getting index from the subrule - auto subRuleIdx = subRule->getIndex(); + // Getting index from the subrule + auto subRuleIdx = subRule->getIndex(); - // Only activate it if it hasn't been activated before - if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), subRuleIdx) == false) satisfyRule(*subRule); - } + // Only activate it if it hasn't been activated before + if (jaffarCommon::bitwise::getBitValue(_rulesStatus.data(), subRuleIdx) == false) satisfyRule(*subRule); + } // Getting rule index const auto ruleIdx = rule.getIndex(); @@ -638,21 +638,21 @@ class Game jaffarCommon::bitwise::setBitValue(_rulesStatus.data(), ruleIdx, true); } - virtual void initializeImpl(){}; + virtual void initializeImpl() {}; virtual void registerGameProperties() = 0; virtual void serializeStateImpl(jaffarCommon::serializer::Base &serializer) const = 0; virtual void deserializeStateImpl(jaffarCommon::deserializer::Base &deserializer) = 0; virtual float calculateGameSpecificReward() const = 0; virtual void computeAdditionalHashing(MetroHash128 &hashEngine) const = 0; virtual void printInfoImpl() const = 0; - virtual void advanceStateImpl(const InputSet::inputIndex_t input) = 0; + virtual void advanceStateImpl(const InputSet::inputIndex_t input) = 0; virtual bool parseRuleActionImpl(Rule &rule, const std::string &actionType, const nlohmann::json &actionJs) = 0; // Optional hooks - virtual __INLINE__ void stateUpdatePreHook(){}; - virtual __INLINE__ void stateUpdatePostHook(){}; - virtual __INLINE__ void ruleUpdatePreHook(){}; - virtual __INLINE__ void ruleUpdatePostHook(){}; + virtual __INLINE__ void stateUpdatePreHook() {}; + virtual __INLINE__ void stateUpdatePostHook() {}; + virtual __INLINE__ void ruleUpdatePreHook() {}; + virtual __INLINE__ void ruleUpdatePostHook() {}; // Current game state type stateType_t _stateType; diff --git a/source/hashDb.hpp b/source/hashDb.hpp index c93956f2..b3de3d8f 100644 --- a/source/hashDb.hpp +++ b/source/hashDb.hpp @@ -45,10 +45,10 @@ class HashDb final // Resizing counter vectors for (size_t i = 0; i < _maxStoreCount; i++) - { - _queryCounters.emplace_back(std::make_unique>(0)); - _collisionCounters.emplace_back(std::make_unique>(0)); - } + { + _queryCounters.emplace_back(std::make_unique>(0)); + _collisionCounters.emplace_back(std::make_unique>(0)); + } } ~HashDb() = default; @@ -68,18 +68,18 @@ class HashDb final auto itr = _hashStores.rbegin(); size_t curHashStoreIdx = 0; while (itr != _hashStores.rend()) - { - jaffarCommon::logger::log("[J+] + [%02lu] - Age: %lu, Entries: %.3f M, Size: %.3f Mb, Check Count: %lu, Collision Count: %lu (Rate %.3f%%)\n", - itr->id, - itr->age, - (double)itr->hashSet.size() / (1024.0 * 1024.0), - (_bytesPerEntry * (double)itr->hashSet.size()) / (1024.0 * 1024.0), - _queryCounters[curHashStoreIdx]->load(), - _collisionCounters[curHashStoreIdx]->load(), - 100.0 * (double)_collisionCounters[curHashStoreIdx]->load() / (double)_queryCounters[curHashStoreIdx]->load()); - itr++; - curHashStoreIdx++; - } + { + jaffarCommon::logger::log("[J+] + [%02lu] - Age: %lu, Entries: %.3f M, Size: %.3f Mb, Check Count: %lu, Collision Count: %lu (Rate %.3f%%)\n", + itr->id, + itr->age, + (double)itr->hashSet.size() / (1024.0 * 1024.0), + (_bytesPerEntry * (double)itr->hashSet.size()) / (1024.0 * 1024.0), + _queryCounters[curHashStoreIdx]->load(), + _collisionCounters[curHashStoreIdx]->load(), + 100.0 * (double)_collisionCounters[curHashStoreIdx]->load() / (double)_queryCounters[curHashStoreIdx]->load()); + itr++; + curHashStoreIdx++; + } } /** @@ -93,33 +93,33 @@ class HashDb final // Checking for the rest of the hash stores in reverse order, to increase chances of early collision detection while (itr != _hashStores.rend()) - { - // Increasing query count for this hash store position - _queryCounters[curHashStoreIdx]->operator++(); + { + // Increasing query count for this hash store position + _queryCounters[curHashStoreIdx]->operator++(); - // Flag to indicate whether a collision has been found - bool collisionFound = false; + // Flag to indicate whether a collision has been found + bool collisionFound = false; - // If it is the first hash db, check at the same time as we insert - if (curHashStoreIdx == 0) collisionFound = itr->hashSet.insert(hash).second == false; + // If it is the first hash db, check at the same time as we insert + if (curHashStoreIdx == 0) collisionFound = itr->hashSet.insert(hash).second == false; - // Otherwise, we simply check (no inserts) - if (curHashStoreIdx > 0) collisionFound = itr->hashSet.contains(hash); + // Otherwise, we simply check (no inserts) + if (curHashStoreIdx > 0) collisionFound = itr->hashSet.contains(hash); - // If collision is found, register it and return - if (collisionFound == true) - { - // Increasing counter for collisions - _collisionCounters[curHashStoreIdx]->operator++(); + // If collision is found, register it and return + if (collisionFound == true) + { + // Increasing counter for collisions + _collisionCounters[curHashStoreIdx]->operator++(); - // True means a collision was found - return true; - } + // True means a collision was found + return true; + } - // Increasing indexing - itr++; - curHashStoreIdx++; - } + // Increasing indexing + itr++; + curHashStoreIdx++; + } // If no hits, then it's not collided return false; @@ -151,12 +151,12 @@ class HashDb final // If the current hash store exceeds the entry limit, push put a new one in if (currentHashStore.hashSet.size() > _maxStoreEntries) - { - // First, if we already reached the maximum hash stores, then discard the oldest one first - if (_hashStores.size() == _maxStoreCount) _hashStores.pop_front(); + { + // First, if we already reached the maximum hash stores, then discard the oldest one first + if (_hashStores.size() == _maxStoreCount) _hashStores.pop_front(); - // Now create the new one, by pushing it from the back - _hashStores.push_back(hashStore_t({.id = _currentHashStoreId++, .age = _currentAge})); + // Now create the new one, by pushing it from the back + _hashStores.push_back(hashStore_t({.id = _currentHashStoreId++, .age = _currentAge})); } // Increasing age diff --git a/source/jaffar.cpp b/source/jaffar.cpp index 81a3c865..108b1b20 100644 --- a/source/jaffar.cpp +++ b/source/jaffar.cpp @@ -13,13 +13,13 @@ int main(int argc, char *argv[]) // Try to parse arguments try - { - program.parse_args(argc, argv); - } + { + program.parse_args(argc, argv); + } catch (const std::runtime_error &err) - { - JAFFAR_THROW_LOGIC("%s\n%s", err.what(), program.help().str().c_str()); - } + { + JAFFAR_THROW_LOGIC("%s\n%s", err.what(), program.help().str().c_str()); + } // Getting config file name const std::string configFile = program.get("configFile"); @@ -35,13 +35,13 @@ int main(int argc, char *argv[]) // Parsing JSON from script file nlohmann::json config; try - { - config = nlohmann::json::parse(configFileString); - } + { + config = nlohmann::json::parse(configFileString); + } catch (const std::exception &err) - { - JAFFAR_THROW_LOGIC("[ERROR] Parsing configuration file %s. Details:\n%s\n", configFile.c_str(), err.what()); - } + { + JAFFAR_THROW_LOGIC("[ERROR] Parsing configuration file %s. Details:\n%s\n", configFile.c_str(), err.what()); + } // Creating driver to run the Jaffar engine auto d = jaffarPlus::Driver::getDriver(config); diff --git a/source/playback.hpp b/source/playback.hpp index 0732d009..b6145d71 100644 --- a/source/playback.hpp +++ b/source/playback.hpp @@ -49,70 +49,70 @@ class Playback final { // For each input in the sequence, store the game's state for (size_t i = 0; i <= inputSequence.size(); i++) - { - // Creating new step - step_t step; + { + // Creating new step + step_t step; - // Checking if this is the end of the sequence - bool isEndOfSequence = i == inputSequence.size(); + // Checking if this is the end of the sequence + bool isEndOfSequence = i == inputSequence.size(); - // Setting step input string - step.inputString = isEndOfSequence == false ? inputSequence[i] : ""; + // Setting step input string + step.inputString = isEndOfSequence == false ? inputSequence[i] : ""; - // Checking if the input is allowed - step.isInputAllowed = _runner->isInputAllowed(step.inputString); + // Checking if the input is allowed + step.isInputAllowed = _runner->isInputAllowed(step.inputString); - // Getting input index - if (isEndOfSequence == true) step.inputIndex = 0; - if (isEndOfSequence == false && step.isInputAllowed == true) step.inputIndex = _runner->getInputIndex(step.inputString); - if (isEndOfSequence == false && step.isInputAllowed == false) step.inputIndex = _runner->registerInput(step.inputString); + // Getting input index + if (isEndOfSequence == true) step.inputIndex = 0; + if (isEndOfSequence == false && step.isInputAllowed == true) step.inputIndex = _runner->getInputIndex(step.inputString); + if (isEndOfSequence == false && step.isInputAllowed == false) step.inputIndex = _runner->registerInput(step.inputString); - // Getting state hash - step.stateHash = _runner->computeHash(); + // Getting state hash + step.stateHash = _runner->computeHash(); - // Allocating space for the game state data - step.gameStateData = malloc(_gameStateSize); + // Allocating space for the game state data + step.gameStateData = malloc(_gameStateSize); - // Serializing game state - jaffarCommon::serializer::Contiguous sg(step.gameStateData, _gameStateSize); - _runner->serializeState(sg); + // Serializing game state + jaffarCommon::serializer::Contiguous sg(step.gameStateData, _gameStateSize); + _runner->serializeState(sg); - // Allocating space for the renderer state data - step.rendererStateData = malloc(_rendererStateSize); + // Allocating space for the renderer state data + step.rendererStateData = malloc(_rendererStateSize); - // Updating renderer state - _runner->getGame()->getEmulator()->updateRendererState(i, step.inputString); + // Updating renderer state + _runner->getGame()->getEmulator()->updateRendererState(i, step.inputString); - // Serializing renderer state - jaffarCommon::serializer::Contiguous sr(step.rendererStateData, _rendererStateSize); - _runner->getGame()->getEmulator()->serializeRendererState(sr); + // Serializing renderer state + jaffarCommon::serializer::Contiguous sr(step.rendererStateData, _rendererStateSize); + _runner->getGame()->getEmulator()->serializeRendererState(sr); - // Advancing state - if (i < inputSequence.size()) _runner->advanceState(step.inputIndex); - if (i == inputSequence.size()) _runner->advanceState(0); + // Advancing state + if (i < inputSequence.size()) _runner->advanceState(step.inputIndex); + if (i == inputSequence.size()) _runner->advanceState(0); - // Evaluate game rules - _runner->getGame()->evaluateRules(); + // Evaluate game rules + _runner->getGame()->evaluateRules(); - // Determining new game state type - _runner->getGame()->updateGameStateType(); + // Determining new game state type + _runner->getGame()->updateGameStateType(); - // Updating game reward - _runner->getGame()->updateReward(); + // Updating game reward + _runner->getGame()->updateReward(); - // Adding step to the internal storage - _sequence.push_back(step); - } + // Adding step to the internal storage + _sequence.push_back(step); + } } ~Playback() { // Freeing up memory reserved during initialization for (const auto &step : _sequence) - { - free(step.gameStateData); - free(step.rendererStateData); - } + { + free(step.gameStateData); + free(step.rendererStateData); + } } __INLINE__ std::string getStateInputString(const size_t currentStep) const { return getStep(currentStep).inputString; } diff --git a/source/player.cpp b/source/player.cpp index 8d112f1b..b5bfa890 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -63,123 +63,123 @@ bool mainCycle(jaffarPlus::Runner &r, const std::string &solutionFile, bool disa // Interactive section while (isFinalize == false) - { - // Updating display - if (disableRender == false) p.renderFrame(currentStep); - - // Loading step data - p.loadStepData(currentStep); - - // Getting input string - const auto &inputString = p.getStateInputString(currentStep); - - // Getting input index - const auto &inputIndex = p.getStateInputIndex(currentStep); - - // Getting state hash - const auto hash = p.getStateHash(currentStep); - - // Printing data and commands - if (showFrameInfo) - { - jaffarCommon::logger::clearTerminal(); - - jaffarCommon::logger::log("[J+] ----------------------------------------------------------------\n"); - jaffarCommon::logger::log("[J+] Current Step #: %lu / %lu\n", currentStep + 1, sequenceLength); - jaffarCommon::logger::log("[J+] Playback: %s\n", isReproduce ? "Playing" : "Stopped"); - jaffarCommon::logger::log("[J+] On Finish: %s\n", isReload ? "Auto Reload" : "Stop"); - jaffarCommon::logger::log("[J+] Input: %s (0x%X)\n", inputString.c_str(), inputIndex); - jaffarCommon::logger::log("[J+] Game Name: '%s'\n", r.getGame()->getName().c_str()); - jaffarCommon::logger::log("[J+] Emulator Name: '%s'\n", r.getGame()->getEmulator()->getName().c_str()); - jaffarCommon::logger::log("[J+] State Hash: 0x%lX%lX\n", hash.first, hash.second); - jaffarCommon::logger::log("[J+] State Size: %lu\n", stateSize); - jaffarCommon::logger::log("[J+] Solution File: '%s'\n", solutionFile.c_str()); - jaffarCommon::logger::log("[J+] Sequence Length: %lu\n", sequenceLength); - jaffarCommon::logger::log("[J+] Frame Rate: %f (%u)\n", frameRate, inverseFrameRate); - p.printInfo(); - - // Only print commands if not in reproduce mode - jaffarCommon::logger::log("[J+] Commands: n: -1 m: +1 | h: -10 | j: +10 | y: -100 | u: +100 | k: -1000 | i: +1000 | s: quicksave | p: play | r: autoreload | q: quit\n"); - - jaffarCommon::logger::refreshTerminal(); - } - - // Resetting show frame info flag - showFrameInfo = true; - - // Specifies the command to execute next - int command = 0; - - // If it's reproducing, - if (isReproduce == true) - { - // Introducing sleep related to the frame rate - usleep(inverseFrameRate); - - // Advance to the next frame - currentStep++; - - // Get command without interrupting - command = jaffarCommon::logger::getKeyPress(); - } - - // If it's not reproducing, grab command with a wait - if (isReproduce == false && isUnattended == false) command = jaffarCommon::logger::waitForKeyPress(); - - // Advance/Rewind commands - if (command == 'n') currentStep = currentStep - 1; - if (command == 'm') currentStep = currentStep + 1; - if (command == 'h') currentStep = currentStep - 10; - if (command == 'j') currentStep = currentStep + 10; - if (command == 'y') currentStep = currentStep - 100; - if (command == 'u') currentStep = currentStep + 100; - if (command == 'k') currentStep = currentStep - 1000; - if (command == 'i') currentStep = currentStep + 1000; - - // Correct current step if requested more than possible - if (currentStep < 0) currentStep = 0; - - // If reloading on finish, do it now - if (currentStep > sequenceLength && isReload == true) break; - - // If exiting on finish, do it now - if (currentStep > sequenceLength && isExitOnEnd == true) break; - - // If not reloading on finish, simply stop - if (currentStep > sequenceLength) - { - currentStep = sequenceLength; - isReproduce = false; - } - - // Quicksave creation command - if (command == 's') { - // Storing state file - std::string saveFileName = "quicksave.state"; - - std::string saveData; - size_t stateSize = r.getGame()->getEmulator()->getStateSize(); - saveData.resize(stateSize); - jaffarCommon::serializer::Contiguous s(saveData.data(), stateSize); - r.getGame()->getEmulator()->serializeState(s); - if (jaffarCommon::file::saveStringToFile(saveData, saveFileName.c_str()) == false) JAFFAR_THROW_LOGIC("[ERROR] Could not save state file: %s\n", saveFileName.c_str()); - jaffarCommon::logger::log("[J+] Saved state to %s\n", saveFileName.c_str()); - - // Do no show frame info again after this action - showFrameInfo = false; + // Updating display + if (disableRender == false) p.renderFrame(currentStep); + + // Loading step data + p.loadStepData(currentStep); + + // Getting input string + const auto &inputString = p.getStateInputString(currentStep); + + // Getting input index + const auto &inputIndex = p.getStateInputIndex(currentStep); + + // Getting state hash + const auto hash = p.getStateHash(currentStep); + + // Printing data and commands + if (showFrameInfo) + { + jaffarCommon::logger::clearTerminal(); + + jaffarCommon::logger::log("[J+] ----------------------------------------------------------------\n"); + jaffarCommon::logger::log("[J+] Current Step #: %lu / %lu\n", currentStep + 1, sequenceLength); + jaffarCommon::logger::log("[J+] Playback: %s\n", isReproduce ? "Playing" : "Stopped"); + jaffarCommon::logger::log("[J+] On Finish: %s\n", isReload ? "Auto Reload" : "Stop"); + jaffarCommon::logger::log("[J+] Input: %s (0x%X)\n", inputString.c_str(), inputIndex); + jaffarCommon::logger::log("[J+] Game Name: '%s'\n", r.getGame()->getName().c_str()); + jaffarCommon::logger::log("[J+] Emulator Name: '%s'\n", r.getGame()->getEmulator()->getName().c_str()); + jaffarCommon::logger::log("[J+] State Hash: 0x%lX%lX\n", hash.first, hash.second); + jaffarCommon::logger::log("[J+] State Size: %lu\n", stateSize); + jaffarCommon::logger::log("[J+] Solution File: '%s'\n", solutionFile.c_str()); + jaffarCommon::logger::log("[J+] Sequence Length: %lu\n", sequenceLength); + jaffarCommon::logger::log("[J+] Frame Rate: %f (%u)\n", frameRate, inverseFrameRate); + p.printInfo(); + + // Only print commands if not in reproduce mode + jaffarCommon::logger::log("[J+] Commands: n: -1 m: +1 | h: -10 | j: +10 | y: -100 | u: +100 | k: -1000 | i: +1000 | s: quicksave | p: play | r: autoreload | q: quit\n"); + + jaffarCommon::logger::refreshTerminal(); + } + + // Resetting show frame info flag + showFrameInfo = true; + + // Specifies the command to execute next + int command = 0; + + // If it's reproducing, + if (isReproduce == true) + { + // Introducing sleep related to the frame rate + usleep(inverseFrameRate); + + // Advance to the next frame + currentStep++; + + // Get command without interrupting + command = jaffarCommon::logger::getKeyPress(); + } + + // If it's not reproducing, grab command with a wait + if (isReproduce == false && isUnattended == false) command = jaffarCommon::logger::waitForKeyPress(); + + // Advance/Rewind commands + if (command == 'n') currentStep = currentStep - 1; + if (command == 'm') currentStep = currentStep + 1; + if (command == 'h') currentStep = currentStep - 10; + if (command == 'j') currentStep = currentStep + 10; + if (command == 'y') currentStep = currentStep - 100; + if (command == 'u') currentStep = currentStep + 100; + if (command == 'k') currentStep = currentStep - 1000; + if (command == 'i') currentStep = currentStep + 1000; + + // Correct current step if requested more than possible + if (currentStep < 0) currentStep = 0; + + // If reloading on finish, do it now + if (currentStep > sequenceLength && isReload == true) break; + + // If exiting on finish, do it now + if (currentStep > sequenceLength && isExitOnEnd == true) break; + + // If not reloading on finish, simply stop + if (currentStep > sequenceLength) + { + currentStep = sequenceLength; + isReproduce = false; + } + + // Quicksave creation command + if (command == 's') + { + // Storing state file + std::string saveFileName = "quicksave.state"; + + std::string saveData; + size_t stateSize = r.getGame()->getEmulator()->getStateSize(); + saveData.resize(stateSize); + jaffarCommon::serializer::Contiguous s(saveData.data(), stateSize); + r.getGame()->getEmulator()->serializeState(s); + if (jaffarCommon::file::saveStringToFile(saveData, saveFileName.c_str()) == false) JAFFAR_THROW_LOGIC("[ERROR] Could not save state file: %s\n", saveFileName.c_str()); + jaffarCommon::logger::log("[J+] Saved state to %s\n", saveFileName.c_str()); + + // Do no show frame info again after this action + showFrameInfo = false; + } + + // Toggles playback from current point + if (command == 'p') isReproduce = !isReproduce; + + // Toggles Auto Reload + if (command == 'r') isReload = !isReload; + + // Triggers the exit + if (command == 'q') isFinalize = true; } - // Toggles playback from current point - if (command == 'p') isReproduce = !isReproduce; - - // Toggles Auto Reload - if (command == 'r') isReload = !isReload; - - // Triggers the exit - if (command == 'q') isFinalize = true; - } - // returning false on exit to trigger the finalization if (isFinalize) return false; @@ -208,13 +208,13 @@ int main(int argc, char *argv[]) // Try to parse arguments try - { - program.parse_args(argc, argv); - } + { + program.parse_args(argc, argv); + } catch (const std::runtime_error &err) - { - JAFFAR_THROW_LOGIC("%s\n%s", err.what(), program.help().str().c_str()); - } + { + JAFFAR_THROW_LOGIC("%s\n%s", err.what(), program.help().str().c_str()); + } // Parsing config file const std::string configFile = program.get("configFile"); @@ -254,13 +254,13 @@ int main(int argc, char *argv[]) // Parsing configuration file nlohmann::json config; try - { - config = nlohmann::json::parse(configFileString); - } + { + config = nlohmann::json::parse(configFileString); + } catch (const std::exception &err) - { - JAFFAR_THROW_LOGIC("[ERROR] Parsing configuration file %s. Details:\n%s\n", configFile.c_str(), err.what()); - } + { + JAFFAR_THROW_LOGIC("[ERROR] Parsing configuration file %s. Details:\n%s\n", configFile.c_str(), err.what()); + } // Getting component configurations auto emulatorConfig = jaffarCommon::json::getObject(config, "Emulator Configuration"); @@ -275,9 +275,9 @@ int main(int argc, char *argv[]) // Enabling rendering, if required if (disableRender == false) - { - r->getGame()->getEmulator()->initializeVideoOutput(); - r->getGame()->getEmulator()->enableRendering(); + { + r->getGame()->getEmulator()->initializeVideoOutput(); + r->getGame()->getEmulator()->enableRendering(); } // Getting game state size @@ -294,24 +294,24 @@ int main(int argc, char *argv[]) // Running main cycle bool continueRunning = true; while (continueRunning == true) - { - // Running main cycle - continueRunning = mainCycle(*r, solutionFile, disableRender); - - // If the exit-on-end flag is set, then do not repeat reproduction - if (exitOnEnd == true) break; - - // If the playback repeats, then sleep and restore the initial state - if (continueRunning == true) { - // If repeating, then wait a bit before repeating to prevent fast repetition of short movies - sleep(1); - - // Reloading the initial state - jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); - r->deserializeState(d); + // Running main cycle + continueRunning = mainCycle(*r, solutionFile, disableRender); + + // If the exit-on-end flag is set, then do not repeat reproduction + if (exitOnEnd == true) break; + + // If the playback repeats, then sleep and restore the initial state + if (continueRunning == true) + { + // If repeating, then wait a bit before repeating to prevent fast repetition of short movies + sleep(1); + + // Reloading the initial state + jaffarCommon::deserializer::Contiguous d(initialState.data(), initialState.size()); + r->deserializeState(d); + } } - } // If redering was enabled, finish it now if (disableRender == false) r->getGame()->getEmulator()->finalizeVideoOutput(); diff --git a/source/property.hpp b/source/property.hpp index d65339c7..a79e8126 100644 --- a/source/property.hpp +++ b/source/property.hpp @@ -71,19 +71,19 @@ class Property static __INLINE__ size_t getDatatypeSize(const datatype_t datatype) { switch (datatype) - { - case dt_uint8: return 1; - case dt_uint16: return 2; - case dt_uint32: return 4; - case dt_uint64: return 8; - case dt_int8: return 1; - case dt_int16: return 2; - case dt_int32: return 4; - case dt_int64: return 8; - case dt_bool: return 1; - case dt_float32: return 4; - case dt_float64: return 8; - } + { + case dt_uint8: return 1; + case dt_uint16: return 2; + case dt_uint32: return 4; + case dt_uint64: return 8; + case dt_int8: return 1; + case dt_int16: return 2; + case dt_int32: return 4; + case dt_int64: return 8; + case dt_bool: return 1; + case dt_float32: return 4; + case dt_float64: return 8; + } JAFFAR_THROW_LOGIC("Unidentified datatype %d\n", datatype); } @@ -105,27 +105,27 @@ class Property auto dBuf = (uint8_t *)&value; if (size == 1) { dBuf[0] = sBuf[0]; } if (size == 2) - { - dBuf[0] = sBuf[1]; - dBuf[1] = sBuf[0]; + { + dBuf[0] = sBuf[1]; + dBuf[1] = sBuf[0]; } if (size == 4) - { - dBuf[0] = sBuf[3]; - dBuf[1] = sBuf[2]; - dBuf[2] = sBuf[1]; - dBuf[3] = sBuf[0]; + { + dBuf[0] = sBuf[3]; + dBuf[1] = sBuf[2]; + dBuf[2] = sBuf[1]; + dBuf[3] = sBuf[0]; } if (size == 8) - { - dBuf[0] = sBuf[7]; - dBuf[1] = sBuf[6]; - dBuf[2] = sBuf[5]; - dBuf[3] = sBuf[4]; - dBuf[4] = sBuf[3]; - dBuf[5] = sBuf[2]; - dBuf[6] = sBuf[1]; - dBuf[7] = sBuf[0]; + { + dBuf[0] = sBuf[7]; + dBuf[1] = sBuf[6]; + dBuf[2] = sBuf[5]; + dBuf[3] = sBuf[4]; + dBuf[4] = sBuf[3]; + dBuf[5] = sBuf[2]; + dBuf[6] = sBuf[1]; + dBuf[7] = sBuf[0]; } return value; } diff --git a/source/runner.hpp b/source/runner.hpp index 2609ca5a..13ed9675 100644 --- a/source/runner.hpp +++ b/source/runner.hpp @@ -65,24 +65,24 @@ class Runner final // If storing input history, allocate input history storage if (_inputHistoryEnabled == true) - { - // Calculating bit storage for the possible inputs index - _inputIndexSizeBits = jaffarCommon::bitwise::getEncodingBitsForElementCount(_maxInputIndex); + { + // Calculating bit storage for the possible inputs index + _inputIndexSizeBits = jaffarCommon::bitwise::getEncodingBitsForElementCount(_maxInputIndex); - // Total size in bits for the input history - size_t inputHistorySizeBits = _inputHistoryMaxSize * _inputIndexSizeBits; + // Total size in bits for the input history + size_t inputHistorySizeBits = _inputHistoryMaxSize * _inputIndexSizeBits; - // Total size in bytes - size_t inputHistorySizeBytes = inputHistorySizeBits / 8; + // Total size in bytes + size_t inputHistorySizeBytes = inputHistorySizeBits / 8; - // Add one byte if not perfectly divisible by 8 - if (inputHistorySizeBits % 8 > 0) inputHistorySizeBytes++; + // Add one byte if not perfectly divisible by 8 + if (inputHistorySizeBits % 8 > 0) inputHistorySizeBytes++; - // Allocating storage now - _inputHistory.resize(inputHistorySizeBytes); + // Allocating storage now + _inputHistory.resize(inputHistorySizeBytes); - // Clearing storage (set to zero) - memset(_inputHistory.data(), 0, _inputHistory.size()); + // Clearing storage (set to zero) + memset(_inputHistory.data(), 0, _inputHistory.size()); } } @@ -120,7 +120,7 @@ class Runner final // Getting index for the new input InputSet::inputIndex_t inputIdx = _game->getEmulator()->registerInput(input); - + // Adding new input hash->index to the map _inputHashMap[inputHash] = inputIdx; @@ -145,14 +145,14 @@ class Runner final // For all registered input sets, see which ones satisfy their conditions and add them for (const auto &inputSet : inputSets) if (inputSet->evaluate() == true) - { - possibleInputs.insert(inputSet->getInputIndexes().begin(), inputSet->getInputIndexes().end()); + { + possibleInputs.insert(inputSet->getInputIndexes().begin(), inputSet->getInputIndexes().end()); - // Getting stop evaluating flag - bool stopEvaluating = inputSet->getStopInputEvaluationFlag(); + // Getting stop evaluating flag + bool stopEvaluating = inputSet->getStopInputEvaluationFlag(); - // If stop evaluation is set, then return now - if (stopEvaluating) break; + // If stop evaluation is set, then return now + if (stopEvaluating) break; } // Return possible inputs @@ -303,20 +303,20 @@ class Runner final // For each entry, add the input string up to the current step or the maximum size for (size_t i = 0; i < _currentInputCount && i < _inputHistoryMaxSize; i++) - { - // Getting input index - const auto inputIdx = getInput(i); + { + // Getting input index + const auto inputIdx = getInput(i); - // Safety check - if (_inputStringMap.contains(inputIdx) == false) JAFFAR_THROW_RUNTIME("Move Index %u not found in runner\n", inputIdx); + // Safety check + if (_inputStringMap.contains(inputIdx) == false) JAFFAR_THROW_RUNTIME("Move Index %u not found in runner\n", inputIdx); - // Getting input string - const std::string &inputString = _inputStringMap.at(inputIdx); + // Getting input string + const std::string &inputString = _inputStringMap.at(inputIdx); - // Adding it to the story - inputHistoryString += inputString; - inputHistoryString += "\n"; - } + // Adding it to the story + inputHistoryString += inputString; + inputHistoryString += "\n"; + } return inputHistoryString; } @@ -335,10 +335,10 @@ class Runner final // Memory usage jaffarCommon::logger::log("[J+] + Input History Enabled: %s\n", _inputHistoryEnabled ? "true" : "false"); if (_inputHistoryEnabled == true) - { - jaffarCommon::logger::log("[J+] + Possible Input Count: %u (Encoded in %lu bits)\n", _maxInputIndex, _inputIndexSizeBits); - jaffarCommon::logger::log( - "[J+] + Input History Size: %u steps (%lu Bytes, %lu Bits)\n", _inputHistoryMaxSize, _inputHistory.size(), _inputIndexSizeBits * _inputHistoryMaxSize); + { + jaffarCommon::logger::log("[J+] + Possible Input Count: %u (Encoded in %lu bits)\n", _maxInputIndex, _inputIndexSizeBits); + jaffarCommon::logger::log( + "[J+] + Input History Size: %u steps (%lu Bytes, %lu Bits)\n", _inputHistoryMaxSize, _inputHistory.size(), _inputIndexSizeBits * _inputHistoryMaxSize); } // Printing runner state @@ -348,21 +348,21 @@ class Runner final // Check whether we want to print inputs if (_showAllowedInputs == true) - { - // Getting allowed inputs - const auto &possibleInputs = getAllowedInputs(); - - // Printing them - jaffarCommon::logger::log("[J+] + Allowed Inputs:\n"); - - size_t currentInputIdx = 0; - for (const auto inputIdx : possibleInputs) { - jaffarCommon::logger::log("[J+] + '%s'\n", _inputStringMap.at(inputIdx).c_str()); - currentInputIdx++; - } - if (_showEmptyInputSlots) - for (; currentInputIdx < _largestInputSetSize; currentInputIdx++) jaffarCommon::logger::log("[J+] + ----- \n"); + // Getting allowed inputs + const auto &possibleInputs = getAllowedInputs(); + + // Printing them + jaffarCommon::logger::log("[J+] + Allowed Inputs:\n"); + + size_t currentInputIdx = 0; + for (const auto inputIdx : possibleInputs) + { + jaffarCommon::logger::log("[J+] + '%s'\n", _inputStringMap.at(inputIdx).c_str()); + currentInputIdx++; + } + if (_showEmptyInputSlots) + for (; currentInputIdx < _largestInputSetSize; currentInputIdx++) jaffarCommon::logger::log("[J+] + ----- \n"); } } diff --git a/source/stateDb/base.hpp b/source/stateDb/base.hpp index e9123740..dbc80240 100644 --- a/source/stateDb/base.hpp +++ b/source/stateDb/base.hpp @@ -89,22 +89,22 @@ class Base (double)_maxSize / (1024.0 * 1024.0 * 1024.0)); jaffarCommon::logger::log("[J+] + State Size Raw: %lu bytes\n", _stateSizeRaw); if (_useDifferentialCompression) - { - jaffarCommon::logger::log("[J+] + State Size Effective: %lu bytes (Diffential: %lu + Contiguous: %lu)\n", - _stateSizeEffective, - _maximumDifferentialSizeAllowed, - _stateSizeEffective - _maximumDifferentialSizeAllowed); + { + jaffarCommon::logger::log("[J+] + State Size Effective: %lu bytes (Diffential: %lu + Contiguous: %lu)\n", + _stateSizeEffective, + _maximumDifferentialSizeAllowed, + _stateSizeEffective - _maximumDifferentialSizeAllowed); } else - { - jaffarCommon::logger::log("[J+] + State Size Effective: %lu bytes\n", _stateSizeEffective); - } + { + jaffarCommon::logger::log("[J+] + State Size Effective: %lu bytes\n", _stateSizeEffective); + } jaffarCommon::logger::log("[J+] + State Size in DB: %lu bytes (%lu padding bytes to %u)\n", _stateSize, _stateSizePadding, _JAFFAR_STATE_PADDING_BYTES); jaffarCommon::logger::log("[J+] + Use Differential Compression: %s\n", _useDifferentialCompression ? "true" : "false"); if (_useDifferentialCompression) - { - jaffarCommon::logger::log("[J+] + Use Zlib Compression: %s\n", _useZlibCompression ? "true" : "false"); - jaffarCommon::logger::log("[J+] + Maximum State Size Found %lu bytes / Max Allowed: %lu bytes\n", _maximumStateSizeFound, _differentialStateSize); + { + jaffarCommon::logger::log("[J+] + Use Zlib Compression: %s\n", _useZlibCompression ? "true" : "false"); + jaffarCommon::logger::log("[J+] + Maximum State Size Found %lu bytes / Max Allowed: %lu bytes\n", _maximumStateSizeFound, _differentialStateSize); } printInfoImpl(); } @@ -149,14 +149,14 @@ class Base // Encoding internal runner state into the state pointer size_t stateSize = 0; try - { - stateSize = saveStateFromRunner(r, statePtr); - } + { + stateSize = saveStateFromRunner(r, statePtr); + } catch (const std::runtime_error &x) - { - // If failed return false - return false; - } + { + // If failed return false + return false; + } // If using differential compression, it is important to keep track of the current compression size _maximumStateSizeFound = std::max(_maximumStateSizeFound, stateSize); @@ -178,18 +178,18 @@ class Base // Serializing the runner state into the memory received (if using differential compression) if (_useDifferentialCompression == true) - { - jaffarCommon::serializer::Differential s(statePtr, _differentialStateSize, _currentReferenceData, _stateSizeRaw, _useZlibCompression); - r.serializeState(s); - serializedSize = s.getOutputSize(); + { + jaffarCommon::serializer::Differential s(statePtr, _differentialStateSize, _currentReferenceData, _stateSizeRaw, _useZlibCompression); + r.serializeState(s); + serializedSize = s.getOutputSize(); } // Serializing the runner state into the memory received (if no compression is used) if (_useDifferentialCompression == false) - { - jaffarCommon::serializer::Contiguous s(statePtr, _stateSizeRaw); - r.serializeState(s); - serializedSize = s.getOutputSize(); + { + jaffarCommon::serializer::Contiguous s(statePtr, _stateSizeRaw); + r.serializeState(s); + serializedSize = s.getOutputSize(); } return serializedSize; @@ -202,16 +202,16 @@ class Base { // Deserializing the runner state from the memory received (if using differential compression) if (_useDifferentialCompression == true) - { - jaffarCommon::deserializer::Differential d(statePtr, _differentialStateSize, _previousReferenceData, _stateSizeRaw, _useZlibCompression); - r.deserializeState(d); + { + jaffarCommon::deserializer::Differential d(statePtr, _differentialStateSize, _previousReferenceData, _stateSizeRaw, _useZlibCompression); + r.deserializeState(d); } // Deserializing the runner state from the memory received (if no compression is used) if (_useDifferentialCompression == false) - { - jaffarCommon::deserializer::Contiguous d(statePtr, _stateSizeRaw); - r.deserializeState(d); + { + jaffarCommon::deserializer::Contiguous d(statePtr, _stateSizeRaw); + r.deserializeState(d); } } diff --git a/source/stateDb/numa.hpp b/source/stateDb/numa.hpp index a94a510d..c791f6f9 100644 --- a/source/stateDb/numa.hpp +++ b/source/stateDb/numa.hpp @@ -60,21 +60,21 @@ class Numa : public stateDb::Base // Getting maximum state db size in Mb and bytes for (int i = 0; i < _numaCount; i++) - { - double sizeMb = _maxSizePerNumaMb[i]; - // For testing purposes, the maximum size can be overriden via environment variables - if (auto *value = std::getenv("JAFFAR_ENGINE_OVERRIDE_MAX_STATEDB_SIZE_MB")) sizeMb = (double)std::stoul(value) / (double)_numaCount; - _maxSizePerNuma.push_back(std::ceil((double)sizeMb * 1024.0 * 1024.0)); - } + { + double sizeMb = _maxSizePerNumaMb[i]; + // For testing purposes, the maximum size can be overriden via environment variables + if (auto *value = std::getenv("JAFFAR_ENGINE_OVERRIDE_MAX_STATEDB_SIZE_MB")) sizeMb = (double)std::stoul(value) / (double)_numaCount; + _maxSizePerNuma.push_back(std::ceil((double)sizeMb * 1024.0 * 1024.0)); + } // Getting maximum allocatable memory in each NUMA domain std::vector maxFreeMemoryPerNuma(_numaCount); for (int i = 0; i < _numaCount; i++) - { - size_t freeMemory = 0; - numa_node_size64(i, (long long *)&freeMemory); - maxFreeMemoryPerNuma[i] = freeMemory; - } + { + size_t freeMemory = 0; + numa_node_size64(i, (long long *)&freeMemory); + maxFreeMemoryPerNuma[i] = freeMemory; + } // Checking if this is enough memory to satisfy requirement for (int i = 0; i < _numaCount; i++) @@ -89,10 +89,10 @@ class Numa : public stateDb::Base _maxSize = 0; _maxStates = 0; for (int i = 0; i < _numaCount; i++) - { - _maxSize += _maxSizePerNuma[i]; - _maxStates += _maxStatesPerNuma[i]; - } + { + _maxSize += _maxSizePerNuma[i]; + _maxStates += _maxStatesPerNuma[i]; + } // Getting number of bytes to reserve for each NUMA domain _allocableBytesPerNuma.resize(_numaCount); @@ -102,11 +102,11 @@ class Numa : public stateDb::Base _internalBuffersStart.resize(_numaCount); _internalBuffersEnd.resize(_numaCount); for (int i = 0; i < _numaCount; i++) - { - _internalBuffersStart[i] = (uint8_t *)numa_alloc_onnode(_allocableBytesPerNuma[i], i); - if (_internalBuffersStart[i] == NULL) JAFFAR_THROW_RUNTIME("Error trying to allocate memory for numa domain %d\n", i); - _internalBuffersEnd[i] = &_internalBuffersStart[i][_allocableBytesPerNuma[i]]; - } + { + _internalBuffersStart[i] = (uint8_t *)numa_alloc_onnode(_allocableBytesPerNuma[i], i); + if (_internalBuffersStart[i] == NULL) JAFFAR_THROW_RUNTIME("Error trying to allocate memory for numa domain %d\n", i); + _internalBuffersEnd[i] = &_internalBuffersStart[i][_allocableBytesPerNuma[i]]; + } // Determining the preferred numa domain for each thread. This depends on OpenMP using always the same set of threads. JAFFAR_PARALLEL @@ -126,10 +126,10 @@ class Numa : public stateDb::Base // Adding the state pointers to the free state queues _freeStateQueues.resize(_numaCount); for (int numaNodeIdx = 0; numaNodeIdx < _numaCount; numaNodeIdx++) - { - _freeStateQueues[numaNodeIdx] = std::make_unique>(_maxStatesPerNuma[numaNodeIdx]); - for (size_t i = 0; i < _maxStatesPerNuma[numaNodeIdx]; i++) _freeStateQueues[numaNodeIdx]->try_push((void *)&_internalBuffersStart[numaNodeIdx][i * _stateSize]); - } + { + _freeStateQueues[numaNodeIdx] = std::make_unique>(_maxStatesPerNuma[numaNodeIdx]); + for (size_t i = 0; i < _maxStatesPerNuma[numaNodeIdx]; i++) _freeStateQueues[numaNodeIdx]->try_push((void *)&_internalBuffersStart[numaNodeIdx][i * _stateSize]); + } } // Function to print relevant information @@ -165,12 +165,12 @@ class Numa : public stateDb::Base // Trying all other free state queues now for (int i = 0; (size_t)i < _freeStateQueues.size(); i++) if (i != preferredNumaDomain) - { - // Trying to get free space for a new state - bool success = _freeStateQueues[i]->try_pop(stateSpace); + { + // Trying to get free space for a new state + bool success = _freeStateQueues[i]->try_pop(stateSpace); - // If successful, return the pointer immediately - if (success == true) return stateSpace; + // If successful, return the pointer immediately + if (success == true) return stateSpace; } // If failed, then try to get it from the back of the current state database @@ -217,59 +217,59 @@ class Numa : public stateDb::Base // Check the numa's scavenger queue first bool success = _scavengerQueues[preferredNumaDomain]->try_pop(statePtr); if (success == true) - { - _numaLocalFreeStateCount++; - return statePtr; + { + _numaLocalFreeStateCount++; + return statePtr; } // Starting scavenging process for (size_t i = 0; i < _scavengingDepth; i++) - { - // Trying to pop the next state from the current state database - success = _currentStateDb.pop_front_get(statePtr); + { + // Trying to pop the next state from the current state database + success = _currentStateDb.pop_front_get(statePtr); - // If no success, break cycle - if (success == false) break; + // If no success, break cycle + if (success == false) break; - // Otherwise, check whether state is in the preferred numa domain - const auto isPreferredNuma = isStateInNumaDomain(statePtr, preferredNumaDomain); + // Otherwise, check whether state is in the preferred numa domain + const auto isPreferredNuma = isStateInNumaDomain(statePtr, preferredNumaDomain); - // If its my preferred numa, return it immediately - if (isPreferredNuma == true) - { - _numaLocalFreeStateCount++; - return statePtr; - } + // If its my preferred numa, return it immediately + if (isPreferredNuma == true) + { + _numaLocalFreeStateCount++; + return statePtr; + } - // Otherwise, place it in the corresponding scavenge queue - if (isPreferredNuma == false) - { - // Get numa domain of state - const auto numaIdx = getStateNumaDomain(statePtr); + // Otherwise, place it in the corresponding scavenge queue + if (isPreferredNuma == false) + { + // Get numa domain of state + const auto numaIdx = getStateNumaDomain(statePtr); - // Push state into the appropriate scavenget queue - auto success = _scavengerQueues[numaIdx]->try_push(statePtr); + // Push state into the appropriate scavenget queue + auto success = _scavengerQueues[numaIdx]->try_push(statePtr); - // If the queue was full, then go ahead and run the state - if (success == false) return statePtr; + // If the queue was full, then go ahead and run the state + if (success == false) return statePtr; + } } - } // If still no success, check the other scavenger queues for (int i = 0; i < _numaCount; i++) if (i != preferredNumaDomain) - { - bool success = _scavengerQueues[i]->try_pop(statePtr); - if (success == true) { - // For statistics, get numa domain of state - const auto numaIdx = getStateNumaDomain(statePtr); + bool success = _scavengerQueues[i]->try_pop(statePtr); + if (success == true) + { + // For statistics, get numa domain of state + const auto numaIdx = getStateNumaDomain(statePtr); - if (numaIdx == preferredNumaDomain) _numaLocalFreeStateCount++; - if (numaIdx != preferredNumaDomain) _numaNonLocalFreeStateCount++; + if (numaIdx == preferredNumaDomain) _numaLocalFreeStateCount++; + if (numaIdx != preferredNumaDomain) _numaNonLocalFreeStateCount++; - return statePtr; - } + return statePtr; + } } // If no success at all, just return a nullptr