From 97b5778172572504c8dfbe173b18281e786270c0 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Fri, 25 Apr 2025 16:18:26 +0200 Subject: Initial commit --- qt-quick/adapter.cpp | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 qt-quick/adapter.cpp (limited to 'qt-quick/adapter.cpp') diff --git a/qt-quick/adapter.cpp b/qt-quick/adapter.cpp new file mode 100644 index 0000000..9594c56 --- /dev/null +++ b/qt-quick/adapter.cpp @@ -0,0 +1,163 @@ +#include "adapter.h" + +#include +#include +#include +#include +#include +#include + +const std::string tablesdir = "../nissy-core/tables/"; + +void logWrapper(const char *str, void *data) +{ + auto f = *reinterpret_cast*>(data); + f(std::string{str}); +} + +NissyAdapter::NissyAdapter() +{ + // TODO: this list must be kept in sync with UI code, it is a bit ugly + std::vector solverNames { + "h48h0k4", + "h48h1k2", + "h48h2k2", + "h48h3k2", + "h48h7k2", + }; + + for (auto s : solverNames) + initSolver(s); + + writeLog = [&](std::string str) { + emit appendLog(QString::fromStdString(str)); + }; + + nissy::set_logger(&logWrapper, &writeLog); +} + +void NissyAdapter::initSolver(const std::string& s) { + auto se = nissy::solver::get(s); + if (std::holds_alternative(se)) { + qDebug("Error loading solver!"); + return; + } + auto ss = std::get(se); + solvers.push_back(ss); +} + +bool NissyAdapter::loadSolverData(nissy::solver& solver) { + if (solver.data_checked) + return true; + + std::filesystem::path filePath(tablesdir + solver.id); + if (!std::filesystem::exists(filePath)) { + logLine("Data file for solver " + solver.name + " not found, " + "generating it..."); + auto err = solver.generate_data(); + if (!err.ok()) { + emit solverError(QString("Error generating data!")); + return false; + } + std::filesystem::create_directory(tablesdir); + std::ofstream ofs(filePath, std::ios::binary); + ofs.write(reinterpret_cast(solver.data.data()), + solver.size); + ofs.close(); + logLine("Data generated succesfully"); + } else { + logLine("Reading data for solver " + solver.name + + " from file"); + std::ifstream ifs(filePath, std::ios::binary); + solver.read_data(ifs); + ifs.close(); + logLine("Data loaded"); + } + + logLine("Checking data integrity " + "(this is done only once per solver per session)..."); + if (!solver.check_data().ok()) { + emit solverError(QString("Error reading data!")); + return false; + } + logLine("Data checked"); + + return true; +} + +Q_INVOKABLE bool NissyAdapter::isValidScramble(QString qscr) +{ + nissy::cube c; + return c.move(qscr.toStdString()).ok(); +} + +Q_INVOKABLE void NissyAdapter::requestSolve( + QString scramble, + QString solver, + int minmoves, + int maxmoves, + int maxsolutions, + int optimal +) +{ + nissy::cube c; + if (!c.move(scramble.toStdString()).ok()) { + emit solverError(QString("Unexpected error: invalid scramble")); + return; + } + + nissy::solver *ss = nullptr; + for (auto& s : solvers) + if (s.name == solver) + ss = &s; + if (ss == nullptr) { + std::string msg = "Error: solver '" + solver.toStdString() + + "' not available"; + emit solverError(QString::fromStdString(msg)); + return; + } + + SolveOptions opts{c, ss, (unsigned)minmoves, (unsigned)maxmoves, + (unsigned)maxsolutions, (unsigned)optimal}; + auto _ = QtConcurrent::run(&NissyAdapter::startSolve, this, opts); + return; +} + +void NissyAdapter::startSolve(SolveOptions opts) +{ + loadSolverData(*opts.solver); + + auto result = opts.solver->solve(opts.cube, nissy::nissflag::NORMAL, + opts.minmoves, opts.maxmoves, opts.maxsolutions, opts.optimal, 8); + + if (!result.err.ok()) { + std::string msg = "Error computing solutions: " + + std::to_string(result.err.value); + emit solverError(QString::fromStdString(msg)); + return; + } + + auto& sols = result.solutions; + if (sols.size() == 0) { + emit solutionsReady("No solution found", ""); + } else { + std::stringstream hs; + hs << "Found " << sols.size() << " solution" + << (sols.size() > 1 ? "s:" : ":"); + + std::stringstream ss; + for (auto s : sols) { + auto n = nissy::count_moves(s).value; + ss << s << " (" << n << ")" << std::endl; // TODO: remove last newline + } + emit solutionsReady(QString::fromStdString(hs.str()), + QString::fromStdString(ss.str())); + } +} + +void NissyAdapter::logLine(std::string str) +{ + std::stringstream ss; + ss << str << std::endl; + writeLog(ss.str()); +} -- cgit v1.3