#ifndef OPENMW_COMPONENTS_ESM3_READERSCACHE_H #define OPENMW_COMPONENTS_ESM3_READERSCACHE_H #include "esmreader.hpp" #include <cstddef> #include <list> #include <map> #include <optional> #include <string> #include <components/to_utf8/to_utf8.hpp> namespace ESM { class ReadersCache { private: enum class State { Busy, Free, Closed, }; struct Item { State mState = State::Busy; ESMReader mReader; std::optional<std::filesystem::path> mName; Item() = default; }; public: class BusyItem { public: explicit BusyItem(ReadersCache& owner, std::list<Item>::iterator item) noexcept; BusyItem(const BusyItem& other) = delete; ~BusyItem() noexcept; BusyItem& operator=(const BusyItem& other) = delete; ESMReader& operator*() const noexcept { return mItem->mReader; } ESMReader* operator->() const noexcept { return &mItem->mReader; } private: ReadersCache& mOwner; std::list<Item>::iterator mItem; }; explicit ReadersCache(std::size_t capacity = 100); BusyItem get(std::size_t index); void setStatelessEncoder(const ToUTF8::StatelessUtf8Encoder& statelessEncoderPtr) { mStatelessEncoder.emplace(statelessEncoderPtr); } const ToUTF8::StatelessUtf8Encoder* getStatelessEncoder() { return mStatelessEncoder.has_value() ? &mStatelessEncoder.value() : nullptr; } private: const std::size_t mCapacity; std::map<std::size_t, std::list<Item>::iterator> mIndex; std::list<Item> mBusyItems; std::list<Item> mFreeItems; std::list<Item> mClosedItems; std::optional<ToUTF8::StatelessUtf8Encoder> mStatelessEncoder; inline void closeExtraReaders(); inline void releaseItem(std::list<Item>::iterator it) noexcept; }; } #endif