You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/detournavigator/navmeshdb.hpp

193 lines
6.6 KiB
C++

#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHDB_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_NAVMESHDB_H
#include "tileposition.hpp"
#include <components/detournavigator/tilespositionsrange.hpp>
#include <components/misc/strongtypedef.hpp>
#include <components/sqlite3/db.hpp>
#include <components/sqlite3/statement.hpp>
#include <components/sqlite3/transaction.hpp>
#include <components/sqlite3/types.hpp>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <optional>
#include <stdexcept>
#include <string_view>
#include <tuple>
#include <utility>
#include <vector>
#include <memory>
struct sqlite3;
struct sqlite3_stmt;
namespace DetourNavigator
{
using TileId = Misc::StrongTypedef<std::int64_t, struct TiledIdTag>;
using TileRevision = Misc::StrongTypedef<std::int64_t, struct TileRevisionTag>;
using TileVersion = Misc::StrongTypedef<std::int64_t, struct TileVersionTag>;
using ShapeId = Misc::StrongTypedef<std::int64_t, struct ShapeIdTag>;
struct Tile
{
TileId mTileId;
TileVersion mVersion;
};
struct TileData
{
TileId mTileId;
TileVersion mVersion;
std::vector<std::byte> mData;
};
enum class ShapeType
{
Collision = 1,
Avoid = 2,
};
std::ostream& operator<<(std::ostream& stream, ShapeType value);
namespace DbQueries
{
struct GetMaxTileId
{
static std::string_view text() noexcept;
static void bind(sqlite3&, sqlite3_stmt&) {}
};
struct FindTile
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
const TilePosition& tilePosition, const std::vector<std::byte>& input);
};
struct GetTileData
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
const TilePosition& tilePosition, const std::vector<std::byte>& input);
};
struct InsertTile
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, std::string_view worldspace,
const TilePosition& tilePosition, TileVersion version, const std::vector<std::byte>& input,
const std::vector<std::byte>& data);
};
struct UpdateTile
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, TileVersion version,
const std::vector<std::byte>& data);
};
struct DeleteTilesAt
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
const TilePosition& tilePosition);
};
struct DeleteTilesAtExcept
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
const TilePosition& tilePosition, TileId excludeTileId);
};
struct DeleteTilesOutsideRange
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
const TilesPositionsRange& range);
};
struct GetMaxShapeId
{
static std::string_view text() noexcept;
static void bind(sqlite3&, sqlite3_stmt&) {}
};
struct FindShapeId
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view name,
ShapeType type, const Sqlite3::ConstBlob& hash);
};
struct InsertShape
{
static std::string_view text() noexcept;
static void bind(sqlite3& db, sqlite3_stmt& statement, ShapeId shapeId, std::string_view name,
ShapeType type, const Sqlite3::ConstBlob& hash);
};
struct Vacuum
{
static std::string_view text() noexcept;
static void bind(sqlite3&, sqlite3_stmt&) {}
};
}
class NavMeshDb
{
public:
explicit NavMeshDb(std::string_view path, std::uint64_t maxFileSize);
Sqlite3::Transaction startTransaction(Sqlite3::TransactionMode mode = Sqlite3::TransactionMode::Default);
TileId getMaxTileId();
std::optional<Tile> findTile(std::string_view worldspace,
const TilePosition& tilePosition, const std::vector<std::byte>& input);
std::optional<TileData> getTileData(std::string_view worldspace,
const TilePosition& tilePosition, const std::vector<std::byte>& input);
int insertTile(TileId tileId, std::string_view worldspace, const TilePosition& tilePosition,
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data);
int updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data);
int deleteTilesAt(std::string_view worldspace, const TilePosition& tilePosition);
int deleteTilesAtExcept(std::string_view worldspace, const TilePosition& tilePosition, TileId excludeTileId);
int deleteTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range);
ShapeId getMaxShapeId();
std::optional<ShapeId> findShapeId(std::string_view name, ShapeType type, const Sqlite3::ConstBlob& hash);
int insertShape(ShapeId shapeId, std::string_view name, ShapeType type, const Sqlite3::ConstBlob& hash);
void vacuum();
private:
Sqlite3::Db mDb;
Sqlite3::Statement<DbQueries::GetMaxTileId> mGetMaxTileId;
Sqlite3::Statement<DbQueries::FindTile> mFindTile;
Sqlite3::Statement<DbQueries::GetTileData> mGetTileData;
Sqlite3::Statement<DbQueries::InsertTile> mInsertTile;
Sqlite3::Statement<DbQueries::UpdateTile> mUpdateTile;
Sqlite3::Statement<DbQueries::DeleteTilesAt> mDeleteTilesAt;
Sqlite3::Statement<DbQueries::DeleteTilesAtExcept> mDeleteTilesAtExcept;
Sqlite3::Statement<DbQueries::DeleteTilesOutsideRange> mDeleteTilesOutsideRange;
Sqlite3::Statement<DbQueries::GetMaxShapeId> mGetMaxShapeId;
Sqlite3::Statement<DbQueries::FindShapeId> mFindShapeId;
Sqlite3::Statement<DbQueries::InsertShape> mInsertShape;
Sqlite3::Statement<DbQueries::Vacuum> mVacuum;
};
}
#endif