#pragma once #include #include #include #include #include #include #define BMAPINSP_L LibCmo #define BMAPINSP_C LibCmo::CK2 #define BMAPINSP_O LibCmo::CK2::ObjImpls namespace BMapInspector::Ruleset::Shared::DupCmp { #pragma region Hash Combiner /** * @brief FNV-1a Hash Combiner */ class Hasher { public: using ValueType = size_t; private: #if defined(YYCC_PTRSIZE_32) static constexpr ValueType FNV_OFFSET_BASIS = 2166136261U; static constexpr ValueType FNV_PRIME = 16777619U; #else static constexpr ValueType FNV_OFFSET_BASIS = 14695981039346656037ULL; static constexpr ValueType FNV_PRIME = 1099511628211ULL; #endif public: Hasher(); ~Hasher(); YYCC_DEFAULT_COPY_MOVE(Hasher) private: /** * @brief Update this hash combiner with new hash. * @param h */ void combine(ValueType h); public: /** * @brief Get final produced hash. * @return */ [[nodiscard]] ValueType finish() const noexcept { return this->seed; } template void update(const T& v) { std::hash hasher; combine(hasher(v)); } template void update_array(const T* addr, size_t cnt) { std::hash hasher; for (size_t i = 0; i < cnt; ++i) { combine(hasher(addr[i])); } } private: ValueType seed; }; #pragma endregion } // namespace BMapInspector::Ruleset::Shared::DupCmp namespace BMapInspector::Ruleset::Shared::DupCmp { #pragma region CKObject Hash and Equal struct CKTextureHash { [[nodiscard]] size_t operator()(const BMAPINSP_O::CKTexture* tex) const noexcept; }; struct CKMaterialHash { [[nodiscard]] size_t operator()(const BMAPINSP_O::CKMaterial* mtl) const noexcept; }; struct CKMeshHash { [[nodiscard]] size_t operator()(const BMAPINSP_O::CKMesh* _mesh) const noexcept; }; struct CKTextureEqualTo { [[nodiscard]] bool operator()(const BMAPINSP_O::CKTexture* lhs, const BMAPINSP_O::CKTexture* rhs) const; }; struct CKMaterialEqualTo { [[nodiscard]] bool operator()(const BMAPINSP_O::CKMaterial* lhs, const BMAPINSP_O::CKMaterial* rhs) const; }; struct CKMeshEqualTo { [[nodiscard]] bool operator()(const BMAPINSP_O::CKMesh* _lhs, const BMAPINSP_O::CKMesh* _rhs) const; }; #pragma endregion #pragma region CKObject Wrapper class CKTextureWrapper { public: CKTextureWrapper(BMAPINSP_O::CKTexture* texture); ~CKTextureWrapper(); YYCC_DEFAULT_COPY_MOVE(CKTextureWrapper) public: BMAPINSP_O::CKTexture* GetTexture() const; size_t GetHash() const; private: BMAPINSP_O::CKTexture* texture; CKTextureHash hasher; mutable std::optional hash; }; class CKMaterialWrapper { public: CKMaterialWrapper(BMAPINSP_O::CKMaterial* material); ~CKMaterialWrapper(); YYCC_DEFAULT_COPY_MOVE(CKMaterialWrapper) public: BMAPINSP_O::CKMaterial* GetMaterial() const; size_t GetHash() const; private: BMAPINSP_O::CKMaterial* material; CKMaterialHash hasher; mutable std::optional hash; }; class CKMeshWrapper { public: CKMeshWrapper(BMAPINSP_O::CKMesh* mesh); ~CKMeshWrapper(); YYCC_DEFAULT_COPY_MOVE(CKMeshWrapper) public: BMAPINSP_O::CKMesh* GetMesh() const; size_t GetHash() const; private: BMAPINSP_O::CKMesh* mesh; CKMeshHash hasher; mutable std::optional hash; }; #pragma endregion #pragma region CKObject Wrapper Hash and Equal struct CKTextureWrapperHash { [[nodiscard]] size_t operator()(const CKTextureWrapper& tex) const noexcept; }; struct CKMaterialWrapperHash { [[nodiscard]] size_t operator()(const CKMaterialWrapper& mtl) const noexcept; }; struct CKMeshWrapperHash { [[nodiscard]] size_t operator()(const CKMeshWrapper& mesh) const noexcept; }; struct CKTextureWrapperEqualTo { CKTextureEqualTo equal_to; [[nodiscard]] bool operator()(const CKTextureWrapper& lhs, const CKTextureWrapper& rhs) const; }; struct CKMaterialWrapperEqualTo { CKMaterialEqualTo equal_to; [[nodiscard]] bool operator()(const CKMaterialWrapper& lhs, const CKMaterialWrapper& rhs) const; }; struct CKMeshWrapperEqualTo { CKMeshEqualTo equal_to; [[nodiscard]] bool operator()(const CKMeshWrapper& lhs, const CKMeshWrapper& rhs) const; }; #pragma endregion } // namespace BMapInspector::Ruleset::Shared::DupCmp