This is an automated email from the git hooks/post-receive script. smcv pushed a commit to branch debian/master in repository openjk.
commit c9122352e786fe14a88e24e69908966038c38bdf Author: bibendovsky <[email protected]> Date: Sun Jul 10 17:03:44 2016 +0300 Split saved game class into the interface and the implementation --- code/CMakeLists.txt | 3 +- code/game/CMakeLists.txt | 6 +- code/rd-vanilla/CMakeLists.txt | 6 +- codeJK2/game/CMakeLists.txt | 6 +- .../{ojk_saved_game.h => ojk_i_saved_game.h} | 173 +++--- ...ojk_saved_game_fwd.h => ojk_i_saved_game_fwd.h} | 164 ++---- shared/qcommon/ojk_saved_game.cpp | 170 +++--- shared/qcommon/ojk_saved_game.h | 624 ++++----------------- 8 files changed, 298 insertions(+), 854 deletions(-) diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index 709601a..a0757fa 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -179,8 +179,9 @@ if(BuildSPEngine OR BuildJK2SPEngine) "${SharedDir}/qcommon/ojk_sg_wrappers_shared.h" "${SharedDir}/qcommon/ojk_exception.h" "${SharedDir}/qcommon/ojk_exception.cpp" + "${SharedDir}/qcommon/ojk_i_saved_game.h" + "${SharedDir}/qcommon/ojk_i_saved_game_fwd.h" "${SharedDir}/qcommon/ojk_saved_game.h" - "${SharedDir}/qcommon/ojk_saved_game_fwd.h" "${SharedDir}/qcommon/ojk_saved_game.cpp" "${SharedDir}/qcommon/ojk_saved_game_exception.h" "${SharedDir}/qcommon/ojk_saved_game_exception.cpp" diff --git a/code/game/CMakeLists.txt b/code/game/CMakeLists.txt index 7464fc5..a1cf3bf 100644 --- a/code/game/CMakeLists.txt +++ b/code/game/CMakeLists.txt @@ -268,10 +268,8 @@ set(SPGameCommonFiles "${SharedDir}/qcommon/ojk_sg_wrappers.h" "${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h" "${SharedDir}/qcommon/ojk_sg_wrappers_shared.h" - "${SharedDir}/qcommon/ojk_exception.h" - "${SharedDir}/qcommon/ojk_saved_game.h" - "${SharedDir}/qcommon/ojk_saved_game_fwd.h" - "${SharedDir}/qcommon/ojk_saved_game_exception.h" + "${SharedDir}/qcommon/ojk_i_saved_game.h" + "${SharedDir}/qcommon/ojk_i_saved_game_fwd.h" ${SharedCommonFiles} ) diff --git a/code/rd-vanilla/CMakeLists.txt b/code/rd-vanilla/CMakeLists.txt index 1de092b..02dbec0 100644 --- a/code/rd-vanilla/CMakeLists.txt +++ b/code/rd-vanilla/CMakeLists.txt @@ -81,10 +81,8 @@ if(BuildSPRdVanilla OR BuildJK2SPRdVanilla) "${SharedDir}/qcommon/ojk_sg_wrappers.h" "${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h" "${SharedDir}/qcommon/ojk_sg_wrappers_shared.h" - "${SharedDir}/qcommon/ojk_exception.h" - "${SharedDir}/qcommon/ojk_saved_game.h" - "${SharedDir}/qcommon/ojk_saved_game_fwd.h" - "${SharedDir}/qcommon/ojk_saved_game_exception.h" + "${SharedDir}/qcommon/ojk_i_saved_game.h" + "${SharedDir}/qcommon/ojk_i_saved_game_fwd.h" ${SharedCommonFiles} ) source_group("common" FILES ${SPRDVanillaCommonFiles}) diff --git a/codeJK2/game/CMakeLists.txt b/codeJK2/game/CMakeLists.txt index 0ae0b14..37d91eb 100644 --- a/codeJK2/game/CMakeLists.txt +++ b/codeJK2/game/CMakeLists.txt @@ -240,10 +240,8 @@ set(JK2SPGameCommonFiles "${SharedDir}/qcommon/ojk_sg_wrappers.h" "${SharedDir}/qcommon/ojk_sg_wrappers_fwd.h" "${SharedDir}/qcommon/ojk_sg_wrappers_shared.h" - "${SharedDir}/qcommon/ojk_exception.h" - "${SharedDir}/qcommon/ojk_saved_game.h" - "${SharedDir}/qcommon/ojk_saved_game_fwd.h" - "${SharedDir}/qcommon/ojk_saved_game_exception.h" + "${SharedDir}/qcommon/ojk_i_saved_game.h" + "${SharedDir}/qcommon/ojk_i_saved_game_fwd.h" ${SharedCommonFiles} ) diff --git a/shared/qcommon/ojk_saved_game.h b/shared/qcommon/ojk_i_saved_game.h similarity index 80% copy from shared/qcommon/ojk_saved_game.h copy to shared/qcommon/ojk_i_saved_game.h index d7c617a..368b7bd 100644 --- a/shared/qcommon/ojk_saved_game.h +++ b/shared/qcommon/ojk_i_saved_game.h @@ -1,31 +1,32 @@ // -// Saved game. +// Saved game interface. // -#ifndef OJK_SAVED_GAME_INCLUDED -#define OJK_SAVED_GAME_INCLUDED +#ifndef OJK_I_SAVED_GAME_INCLUDED +#define OJK_I_SAVED_GAME_INCLUDED #include <cstdint> -#include <algorithm> #include <type_traits> -#include "ojk_saved_game_fwd.h" +#include "ojk_i_saved_game_fwd.h" namespace ojk { // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// I/O buffer manipulation. +// Class stuff -template<typename T> -T SavedGame::cast_buffer() +ISavedGame::ISavedGame() { - return reinterpret_cast<T>(*get_current_data()); } -// I/O buffer manipulation. +ISavedGame::~ISavedGame() +{ +} + +// Class stuff // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -33,7 +34,7 @@ T SavedGame::cast_buffer() // read_chunk template<typename TSrc, typename TDst> -bool SavedGame::read_chunk( +bool ISavedGame::read_chunk( const ChunkId chunk_id, TDst& dst_value) { @@ -47,7 +48,7 @@ bool SavedGame::read_chunk( } template<typename TSrc, typename TDst> -bool SavedGame::read_chunk( +bool ISavedGame::read_chunk( const ChunkId chunk_id, TDst* dst_values, int dst_count) @@ -70,11 +71,11 @@ bool SavedGame::read_chunk( // write_chunk template<typename TDst, typename TSrc> -bool SavedGame::write_chunk( +bool ISavedGame::write_chunk( const ChunkId chunk_id, const TSrc& src_value) { - reset_io_buffer_offset(); + reset_buffer(); write<TDst>( src_value); @@ -84,12 +85,12 @@ bool SavedGame::write_chunk( } template<typename TDst, typename TSrc> -bool SavedGame::write_chunk( +bool ISavedGame::write_chunk( const ChunkId chunk_id, const TSrc* src_values, int src_count) { - reset_io_buffer_offset(); + reset_buffer(); write<TDst>( src_values, @@ -107,7 +108,7 @@ bool SavedGame::write_chunk( // read template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst& dst_value) { using Tag = typename std::conditional< @@ -146,45 +147,45 @@ void SavedGame::read( } template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst& dst_value, BooleanTag) { constexpr auto src_size = static_cast<int>(sizeof(TSrc)); - check_io_buffer( - src_size); + TSrc src_value; - dst_value = (cast_buffer<const TSrc&>() != 0); + raw_read( + &src_value, + static_cast<int>(sizeof(TSrc))); // FIXME Byte order // - advance_io_buffer( - src_size); + dst_value = (src_value != 0); } template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst& dst_value, NumericTag) { constexpr auto src_size = static_cast<int>(sizeof(TSrc)); - check_io_buffer( - src_size); + TSrc src_value; - dst_value = static_cast<TDst>(cast_buffer<const TSrc&>()); + raw_read( + &src_value, + src_size); // FIXME Byte order // - advance_io_buffer( - src_size); + dst_value = static_cast<TDst>(src_value); } template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst*& dst_value, PointerTag) { @@ -209,16 +210,16 @@ void SavedGame::read( } template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst& dst_value, ClassTag) { - throw_error( - "Not implemented."); + throw + "Not implemented."; } template<typename TSrc, typename TDst, int TCount> -void SavedGame::read( +void ISavedGame::read( TDst (&dst_values)[TCount], Array1dTag) { @@ -228,7 +229,7 @@ void SavedGame::read( } template<typename TSrc, typename TDst, int TCount1, int TCount2> -void SavedGame::read( +void ISavedGame::read( TDst(&dst_values)[TCount1][TCount2], Array2dTag) { @@ -245,7 +246,7 @@ void SavedGame::read( // read (C-array) template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst* dst_values, int dst_count) { @@ -256,20 +257,6 @@ void SavedGame::read( std::is_class<TDst>::value, "Unsupported types."); - if (!dst_values) { - throw_error( - "Null pointer."); - } - - if (dst_count < 0) { - throw_error( - "Negative count."); - } - - if (dst_count == 0) { - return; - } - using Src = typename std::conditional< std::is_same<TSrc, void>::value, TDst, @@ -306,32 +293,23 @@ void SavedGame::read( } template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst* dst_values, int dst_count, InplaceTag) { - constexpr auto dst_size = static_cast<int>(sizeof(TDst)); + constexpr auto dst_size = dst_count * static_cast<int>(sizeof(TDst)); - check_io_buffer( - dst_size, - dst_count); - - std::uninitialized_copy_n( - &cast_buffer<const TDst&>(), - dst_count, - dst_values); + raw_read( + dst_values, + dst_size); // FIXME Byte order // - - advance_io_buffer( - dst_size, - dst_count); } template<typename TSrc, typename TDst> -void SavedGame::read( +void ISavedGame::read( TDst* dst_values, int dst_count, CastTag) @@ -361,7 +339,7 @@ void SavedGame::read( // write template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc& src_value) { using Tag = typename std::conditional< @@ -396,26 +374,24 @@ void SavedGame::write( } template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc& src_value, NumericTag) { - constexpr auto src_size = static_cast<int>(sizeof(TSrc)); - - accomodate_io_buffer( - src_size); + constexpr auto dst_size = static_cast<int>(sizeof(TDst)); - cast_buffer<TDst&>() = static_cast<TDst>(src_value); + auto dst_value = static_cast<TDst>(src_value); // FIXME Byte order // - advance_io_buffer( - src_size); + raw_write( + &dst_value, + dst_size); } template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc*& src_value, PointerTag) { @@ -433,16 +409,16 @@ void SavedGame::write( } template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc& src_value, ClassTag) { - throw_error( - "Not implemented."); + throw + "Not implemented."; } template<typename TDst, typename TSrc, int TCount> -void SavedGame::write( +void ISavedGame::write( const TSrc (&src_values)[TCount], Array1dTag) { @@ -452,7 +428,7 @@ void SavedGame::write( } template<typename TDst, typename TSrc, int TCount1, int TCount2> -void SavedGame::write( +void ISavedGame::write( const TSrc(&src_values)[TCount1][TCount2], Array2dTag) { @@ -469,7 +445,7 @@ void SavedGame::write( // write (C-array) template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc* src_values, int src_count) { @@ -480,20 +456,6 @@ void SavedGame::write( std::is_class<TSrc>::value, "Unsupported types."); - if (!src_values) { - throw_error( - "Null pointer."); - } - - if (src_count < 0) { - throw_error( - "Negative count."); - } - - if (src_count == 0) { - return; - } - using Dst = typename std::conditional< std::is_same<TDst, void>::value, TSrc, @@ -530,32 +492,23 @@ void SavedGame::write( } template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc* src_values, int src_count, InplaceTag) { - constexpr auto src_size = static_cast<int>(sizeof(TSrc)); - - accomodate_io_buffer( - src_size, - src_count); + constexpr auto src_size = src_count * static_cast<int>(sizeof(TSrc)); - std::uninitialized_copy_n( + raw_write( src_values, - src_count, - &cast_buffer<TSrc&>()); + src_size); // FIXME Byte order // - - advance_io_buffer( - src_size, - src_count); } template<typename TDst, typename TSrc> -void SavedGame::write( +void ISavedGame::write( const TSrc* src_values, int src_count, CastTag) @@ -584,4 +537,4 @@ void SavedGame::write( } // ojk -#endif // OJK_SAVED_GAME_INCLUDED +#endif // OJK_I_SAVED_GAME_INCLUDED diff --git a/shared/qcommon/ojk_saved_game_fwd.h b/shared/qcommon/ojk_i_saved_game_fwd.h similarity index 56% rename from shared/qcommon/ojk_saved_game_fwd.h rename to shared/qcommon/ojk_i_saved_game_fwd.h index 937b8c6..35e59d9 100644 --- a/shared/qcommon/ojk_saved_game_fwd.h +++ b/shared/qcommon/ojk_i_saved_game_fwd.h @@ -1,11 +1,11 @@ // -// Saved game. +// Saved game interface. // (forward declaration) // -#ifndef OJK_SAVED_GAME_FWD_INCLUDED -#define OJK_SAVED_GAME_FWD_INCLUDED +#ifndef OJK_I_SAVED_GAME_FWD_INCLUDED +#define OJK_I_SAVED_GAME_FWD_INCLUDED #include <cstdint> @@ -16,39 +16,34 @@ namespace ojk { -class SavedGame +class ISavedGame { public: using ChunkId = uint32_t; using Buffer = std::vector<uint8_t>; - SavedGame(); + ISavedGame(); - SavedGame( - const SavedGame& that) = delete; + ISavedGame( + const ISavedGame& that) = delete; - SavedGame& operator=( - const SavedGame& that) = delete; + ISavedGame& operator=( + const ISavedGame& that) = delete; - ~SavedGame(); + virtual ~ISavedGame(); - // Creates a new saved game file for writing. - bool create( - const std::string& base_file_name); + // Returns true if the saved game opened for reading. + virtual bool is_readable() const = 0; - // Opens an existing saved game file for reading. - bool open( - const std::string& base_file_name); - - // Closes the current saved game file. - void close(); + // Returns true if the saved game opened for writing. + virtual bool is_writable() const = 0; // Reads a chunk from the file into the internal buffer. - bool read_chunk( - const ChunkId chunk_id); + virtual bool read_chunk( + const ChunkId chunk_id) = 0; // Reads a value or an array of values from the file via // the internal buffer. @@ -67,8 +62,8 @@ public: // Writes a chunk into the file from the internal buffer. - bool write_chunk( - const ChunkId chunk_id); + virtual bool write_chunk( + const ChunkId chunk_id) = 0; // Writes a value or an array of values into the file via // the internal buffer. @@ -86,6 +81,11 @@ public: int src_count); + // Reads a raw data from the internal buffer. + virtual void raw_read( + void* dst_data, + int dst_size) = 0; + // Reads a value or array of values from the internal buffer. template<typename TSrc = void, typename TDst = void> void read( @@ -98,6 +98,11 @@ public: int dst_count); + // Writes a raw data into the internal buffer. + virtual void raw_write( + const void* src_data, + int src_size) = 0; + // Writes a value or array of values into the internal buffer. template<typename TDst = void, typename TSrc = void> void write( @@ -111,41 +116,14 @@ public: // Returns an I/O buffer. - Buffer& get_buffer(); - - // Returns an I/O buffer. - const Buffer& get_buffer() const; - - // Returns an I/O buffer offset; - int get_buffer_offset() const; - - uint8_t* get_current_data(); - - const uint8_t* get_current_data() const; + virtual const Buffer& get_buffer() const = 0; - // Casts referenced data at current position into a specified type. - template<typename T> - T cast_buffer(); - - // Renames a saved game file. - static void rename( - const std::string& old_base_file_name, - const std::string& new_base_file_name); - - // Remove a saved game file. - static void remove( - const std::string& base_file_name); - - // Returns a default instance of the class. - static SavedGame& get_instance(); - - -private: - using BufferOffset = Buffer::size_type; - using Paths = std::vector<std::string>; + // Clears buffer and resets it's offset to the beginning. + virtual void reset_buffer() = 0; +protected: // Tags for dispatching. class BooleanTag { public: }; class NumericTag { public: }; @@ -157,76 +135,6 @@ private: class CastTag { public: }; - // A handle to a file. - int32_t file_handle_; - - // I/O buffer. - Buffer io_buffer_; - - // A current offset inside the I/O buffer. - BufferOffset io_buffer_offset_; - - // RLE codec buffer. - Buffer rle_buffer_; - - // Does not throws an exception on chunk reading if true. - bool is_preview_mode_; - - bool is_write_failed_; - - - // Throws an exception. - static void throw_error( - const char* message); - - // Throws an exception. - static void throw_error( - const std::string& message); - - - // Compresses data. - static void compress( - const Buffer& src_buffer, - Buffer& dst_buffer); - - // Decompresses data. - static void decompress( - const Buffer& src_buffer, - Buffer& dst_buffer); - - - static std::string generate_path( - const std::string& base_file_name); - - static std::string get_failed_to_open_message( - const std::string& file_name, - bool is_open); - - - // Returns a string representation of a chunk id. - static std::string get_chunk_id_string( - uint32_t chunk_id); - - - // Checks if there is enough data for reading in the I/O buffer. - void check_io_buffer( - int item_size, - int count = 1); - - // Resizes the I/O buffer according to desire size of data to write. - void accomodate_io_buffer( - int item_size, - int count = 1); - - // Advances the current I/O buffer offset. - void advance_io_buffer( - int item_size, - int count = 1); - - // Resets I/O buffer offset to zero. - void reset_io_buffer_offset(); - - template<typename TSrc, typename TDst> void read( TDst& dst_value, @@ -249,7 +157,7 @@ private: template<typename TSrc, typename TDst, int TCount> void read( - TDst (&dst_values)[TCount], + TDst(&dst_values)[TCount], Array1dTag); template<typename TSrc, typename TDst, int TCount1, int TCount2> @@ -288,7 +196,7 @@ private: template<typename TDst, typename TSrc, int TCount> void write( - const TSrc (&src_values)[TCount], + const TSrc(&src_values)[TCount], Array1dTag); template<typename TDst, typename TSrc, int TCount1, int TCount2> @@ -308,10 +216,10 @@ private: const TSrc* src_values, int src_count, CastTag); -}; // SavedGame +}; // ISavedGame } // ojk -#endif // OJK_SAVED_GAME_FWD_INCLUDED +#endif // OJK_I_SAVED_GAME_FWD_INCLUDED diff --git a/shared/qcommon/ojk_saved_game.cpp b/shared/qcommon/ojk_saved_game.cpp index db70802..fa254a2 100644 --- a/shared/qcommon/ojk_saved_game.cpp +++ b/shared/qcommon/ojk_saved_game.cpp @@ -12,6 +12,8 @@ SavedGame::SavedGame() : io_buffer_(), io_buffer_offset_(), rle_buffer_(), + is_readable_(), + is_writable_(), is_preview_mode_(), is_write_failed_() { @@ -56,7 +58,7 @@ bool SavedGame::open( int sg_version = -1; if (is_succeed) { - static_cast<void>(read_chunk<int32_t>( + static_cast<void>(ISavedGame::read_chunk<int32_t>( INT_ID('_', 'V', 'E', 'R'), sg_version)); @@ -71,7 +73,9 @@ bool SavedGame::open( } } - if (!is_succeed) { + if (is_succeed) { + is_readable_ = true; + } else { close(); } @@ -107,10 +111,12 @@ bool SavedGame::create( int sg_version = iSAVEGAME_VERSION; - static_cast<void>(write_chunk<int32_t>( + static_cast<void>(ISavedGame::write_chunk<int32_t>( INT_ID('_', 'V', 'E', 'R'), sg_version)); + is_writable_ = false; + return true; } @@ -124,9 +130,22 @@ void SavedGame::close() io_buffer_.clear(); io_buffer_offset_ = 0; + is_readable_ = false; + is_writable_ = false; + is_preview_mode_ = false; is_write_failed_ = false; } +bool SavedGame::is_readable() const +{ + return is_readable_; +} + +bool SavedGame::is_writable() const +{ + return is_writable_; +} + bool SavedGame::read_chunk( const SavedGame::ChunkId chunk_id) { @@ -364,29 +383,81 @@ bool SavedGame::write_chunk( return true; } -SavedGame::Buffer& SavedGame::get_buffer() +void SavedGame::raw_read( + void* dst_data, + int dst_size) { - return io_buffer_; -} + if (!dst_data) { + throw_error( + "Null pointer."); + } -const SavedGame::Buffer& SavedGame::get_buffer() const -{ - return io_buffer_; -} + if (dst_size < 0) { + throw_error( + "Negative size."); + } -int SavedGame::get_buffer_offset() const -{ - return static_cast<int>(io_buffer_offset_); + if (!is_readable_) { + throw_error( + "Not readable."); + } + + if (dst_size == 0) { + return; + } + + if ((io_buffer_offset_ + dst_size) > io_buffer_.size()) { + throw_error( + "Not enough data."); + } + + std::uninitialized_copy_n( + &io_buffer_[io_buffer_offset_], + dst_size, + static_cast<uint8_t*>(dst_data)); + + io_buffer_offset_ += dst_size; } -uint8_t* SavedGame::get_current_data() +void SavedGame::raw_write( + const void* src_data, + int src_size) { - return &io_buffer_[io_buffer_offset_]; + if (!src_data) { + throw_error( + "Null pointer."); + } + + if (src_size < 0) { + throw_error( + "Negative size."); + } + + if (!is_writable_) { + throw_error( + "Not writable."); + } + + if (src_size == 0) { + return; + } + + auto new_buffer_size = io_buffer_offset_ + src_size; + + io_buffer_.resize( + new_buffer_size); + + std::uninitialized_copy_n( + static_cast<const uint8_t*>(src_data), + src_size, + &io_buffer_[io_buffer_offset_]); + + io_buffer_offset_ = new_buffer_size; } -const uint8_t* SavedGame::get_current_data() const +const SavedGame::Buffer& SavedGame::get_buffer() const { - return &io_buffer_[io_buffer_offset_]; + return io_buffer_; } void SavedGame::rename( @@ -593,70 +664,9 @@ std::string SavedGame::get_chunk_id_string( return result; } -void SavedGame::check_io_buffer( - int item_size, - int count) -{ - if (item_size <= 0) { - throw SavedGameException( - "Zero or negative item size."); - } - - if (count <= 0) { - throw SavedGameException( - "Zero or negative count."); - } - - const auto data_size = item_size * count; - - if ((io_buffer_offset_ + data_size) > io_buffer_.size()) { - throw SavedGameException( - "Not enough data."); - } -} - -void SavedGame::accomodate_io_buffer( - int item_size, - int count) -{ - if (item_size <= 0) { - throw SavedGameException( - "Zero or negative item size."); - } - - if (count <= 0) { - throw SavedGameException( - "Zero or negative count."); - } - - const auto data_size = item_size * count; - - const auto new_buffer_size = io_buffer_offset_ + data_size; - - io_buffer_.resize( - new_buffer_size); -} - -void SavedGame::advance_io_buffer( - int item_size, - int count) -{ - if (item_size <= 0) { - throw SavedGameException( - "Zero or negative item size."); - } - - if (count <= 0) { - throw SavedGameException( - "Zero or negative count."); - } - - const auto data_size = item_size * count; - io_buffer_offset_ += data_size; -} - -void SavedGame::reset_io_buffer_offset() +void SavedGame::reset_buffer() { + io_buffer_.clear(); io_buffer_offset_ = 0; } diff --git a/shared/qcommon/ojk_saved_game.h b/shared/qcommon/ojk_saved_game.h index d7c617a..e108a29 100644 --- a/shared/qcommon/ojk_saved_game.h +++ b/shared/qcommon/ojk_saved_game.h @@ -1,587 +1,165 @@ // // Saved game. +// (forward declaration) // -#ifndef OJK_SAVED_GAME_INCLUDED -#define OJK_SAVED_GAME_INCLUDED +#ifndef OJK_SAVED_GAME_FWD_INCLUDED +#define OJK_SAVED_GAME_FWD_INCLUDED #include <cstdint> -#include <algorithm> -#include <type_traits> -#include "ojk_saved_game_fwd.h" +#include <string> +#include <vector> +#include "ojk_i_saved_game_fwd.h" namespace ojk { -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// I/O buffer manipulation. - -template<typename T> -T SavedGame::cast_buffer() +class SavedGame : + public ISavedGame { - return reinterpret_cast<T>(*get_current_data()); -} +public: + using ChunkId = uint32_t; + using Buffer = std::vector<uint8_t>; -// I/O buffer manipulation. -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + SavedGame(); -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// read_chunk + SavedGame( + const SavedGame& that) = delete; -template<typename TSrc, typename TDst> -bool SavedGame::read_chunk( - const ChunkId chunk_id, - TDst& dst_value) -{ - auto result = read_chunk( - chunk_id); + SavedGame& operator=( + const SavedGame& that) = delete; - read<TSrc>( - dst_value); + virtual ~SavedGame(); - return result; -} -template<typename TSrc, typename TDst> -bool SavedGame::read_chunk( - const ChunkId chunk_id, - TDst* dst_values, - int dst_count) -{ - auto result = read_chunk( - chunk_id); + // Creates a new saved game file for writing. + bool create( + const std::string& base_file_name); - read<TSrc>( - dst_values, - dst_count); + // Opens an existing saved game file for reading. + bool open( + const std::string& base_file_name); - return result; -} + // Closes the current saved game file. + void close(); -// read_chunk -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Returns true if the saved game opened for reading. + bool is_readable() const override; -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// write_chunk + // Returns true if the saved game opened for writing. + bool is_writable() const override; -template<typename TDst, typename TSrc> -bool SavedGame::write_chunk( - const ChunkId chunk_id, - const TSrc& src_value) -{ - reset_io_buffer_offset(); - write<TDst>( - src_value); + // Reads a chunk from the file into the internal buffer. + bool read_chunk( + const ChunkId chunk_id) override; - return write_chunk( - chunk_id); -} + // Writes a chunk into the file from the internal buffer. + bool write_chunk( + const ChunkId chunk_id) override; -template<typename TDst, typename TSrc> -bool SavedGame::write_chunk( - const ChunkId chunk_id, - const TSrc* src_values, - int src_count) -{ - reset_io_buffer_offset(); - write<TDst>( - src_values, - src_count); + // Reads a raw data from the internal buffer. + void raw_read( + void* dst_data, + int dst_size) override; - return write_chunk( - chunk_id); -} + // Writes a raw data into the internal buffer. + void raw_write( + const void* src_data, + int src_size) override; -// write_chunk -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Returns an I/O buffer. + const Buffer& get_buffer() const override; -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// read + // Clears buffer and resets it's offset to the beginning. + void reset_buffer() override; -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst& dst_value) -{ - using Tag = typename std::conditional< - std::is_same<TDst, bool>::value, - BooleanTag, - typename std::conditional< - std::is_arithmetic<TDst>::value || std::is_enum<TDst>::value, - NumericTag, - typename std::conditional< - std::is_pointer<TDst>::value, - PointerTag, - typename std::conditional< - std::is_class<TDst>::value, - ClassTag, - typename std::conditional< - std::rank<TDst>::value == 1, - Array1dTag, - typename std::conditional< - std::rank<TDst>::value == 2, - Array2dTag, - void - >::type - >::type - >::type - >::type - >::type - >::type; - - static_assert( - !std::is_same<Tag, void>::value, - "Unsupported type."); - - read<TSrc>( - dst_value, - Tag()); -} - -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst& dst_value, - BooleanTag) -{ - constexpr auto src_size = static_cast<int>(sizeof(TSrc)); - check_io_buffer( - src_size); + // Renames a saved game file. + static void rename( + const std::string& old_base_file_name, + const std::string& new_base_file_name); - dst_value = (cast_buffer<const TSrc&>() != 0); + // Remove a saved game file. + static void remove( + const std::string& base_file_name); - // FIXME Byte order - // + // Returns a default instance of the class. + static SavedGame& get_instance(); - advance_io_buffer( - src_size); -} -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst& dst_value, - NumericTag) -{ - constexpr auto src_size = static_cast<int>(sizeof(TSrc)); +private: + using BufferOffset = Buffer::size_type; + using Paths = std::vector<std::string>; - check_io_buffer( - src_size); - dst_value = static_cast<TDst>(cast_buffer<const TSrc&>()); + // A handle to a file. + int32_t file_handle_; - // FIXME Byte order - // + // I/O buffer. + Buffer io_buffer_; - advance_io_buffer( - src_size); -} + // A current offset inside the I/O buffer. + BufferOffset io_buffer_offset_; -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst*& dst_value, - PointerTag) -{ - static_assert( - std::is_arithmetic<TSrc>::value && - !std::is_same<TSrc, bool>::value, - "Unsupported types."); - - using DstNumeric = typename std::conditional< - std::is_signed<TSrc>::value, - std::intptr_t, - std::uintptr_t - >::type; - - auto dst_number = DstNumeric(); - - read<TSrc>( - dst_number, - NumericTag()); - - dst_value = reinterpret_cast<TDst*>(dst_number); -} - -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst& dst_value, - ClassTag) -{ - throw_error( - "Not implemented."); -} - -template<typename TSrc, typename TDst, int TCount> -void SavedGame::read( - TDst (&dst_values)[TCount], - Array1dTag) -{ - read<TSrc>( - &dst_values[0], - TCount); -} - -template<typename TSrc, typename TDst, int TCount1, int TCount2> -void SavedGame::read( - TDst(&dst_values)[TCount1][TCount2], - Array2dTag) -{ - read<TSrc>( - &dst_values[0][0], - TCount1 * TCount2); -} + // RLE codec buffer. + Buffer rle_buffer_; -// read -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // True if saved game opened for reading. + bool is_readable_; + // True if saved game opened for writing. + bool is_writable_; -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// read (C-array) + // Does not throws an exception on chunk reading if true. + bool is_preview_mode_; -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst* dst_values, - int dst_count) -{ - static_assert( - (std::is_arithmetic<TDst>::value && - !std::is_same<TDst, bool>::value && - !std::is_enum<TDst>::value) || - std::is_class<TDst>::value, - "Unsupported types."); - - if (!dst_values) { - throw_error( - "Null pointer."); - } - - if (dst_count < 0) { - throw_error( - "Negative count."); - } - - if (dst_count == 0) { - return; - } - - using Src = typename std::conditional< - std::is_same<TSrc, void>::value, - TDst, - TSrc>::type; - - constexpr auto is_src_pure_numeric = - std::is_arithmetic<Src>::value && - (!std::is_same<Src, bool>::value) && - (!std::is_enum<Src>::value); - - constexpr auto is_dst_pure_numeric = - std::is_arithmetic<TDst>::value && - (!std::is_same<TDst, bool>::value) && - (!std::is_enum<TDst>::value); - - constexpr auto has_same_size = - (sizeof(Src) == sizeof(TDst)); - - constexpr auto use_inplace = - is_src_pure_numeric && - is_dst_pure_numeric && - has_same_size; - - using Tag = typename std::conditional< - use_inplace, - InplaceTag, - CastTag - >::type; - - read<TSrc>( - dst_values, - dst_count, - Tag()); -} - -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst* dst_values, - int dst_count, - InplaceTag) -{ - constexpr auto dst_size = static_cast<int>(sizeof(TDst)); - - check_io_buffer( - dst_size, - dst_count); - - std::uninitialized_copy_n( - &cast_buffer<const TDst&>(), - dst_count, - dst_values); - - // FIXME Byte order - // - - advance_io_buffer( - dst_size, - dst_count); -} - -template<typename TSrc, typename TDst> -void SavedGame::read( - TDst* dst_values, - int dst_count, - CastTag) -{ - using Tag = typename std::conditional< - std::is_arithmetic<TDst>::value, - NumericTag, - typename std::conditional< - std::is_class<TDst>::value, - ClassTag, - void - >::type - >::type; - - for (int i = 0; i < dst_count; ++i) { - read<TSrc>( - dst_values[i], - Tag()); - } -} - -// read (C-array) -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> - - -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// write - -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc& src_value) -{ - using Tag = typename std::conditional< - std::is_arithmetic<TSrc>::value || std::is_enum<TSrc>::value, - NumericTag, - typename std::conditional< - std::is_pointer<TSrc>::value, - PointerTag, - typename std::conditional< - std::is_class<TSrc>::value, - ClassTag, - typename std::conditional< - std::rank<TSrc>::value == 1, - Array1dTag, - typename std::conditional< - std::rank<TSrc>::value == 2, - Array2dTag, - void - >::type - >::type - >::type - >::type - >::type; - - static_assert( - !std::is_same<Tag, void>::value, - "Unsupported type."); - - write<TDst>( - src_value, - Tag()); -} - -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc& src_value, - NumericTag) -{ - constexpr auto src_size = static_cast<int>(sizeof(TSrc)); + // True if any previous write operation failed. + bool is_write_failed_; - accomodate_io_buffer( - src_size); - cast_buffer<TDst&>() = static_cast<TDst>(src_value); + // Throws an exception. + static void throw_error( + const char* message); - // FIXME Byte order - // + // Throws an exception. + static void throw_error( + const std::string& message); - advance_io_buffer( - src_size); -} -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc*& src_value, - PointerTag) -{ - using DstNumeric = typename std::conditional< - std::is_signed<TSrc>::value, - std::intptr_t, - std::uintptr_t - >::type; - - auto dst_number = reinterpret_cast<DstNumeric>(src_value); - - write<TDst>( - dst_number, - NumericTag()); -} - -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc& src_value, - ClassTag) -{ - throw_error( - "Not implemented."); -} - -template<typename TDst, typename TSrc, int TCount> -void SavedGame::write( - const TSrc (&src_values)[TCount], - Array1dTag) -{ - write<TDst>( - &src_values[0], - TCount); -} - -template<typename TDst, typename TSrc, int TCount1, int TCount2> -void SavedGame::write( - const TSrc(&src_values)[TCount1][TCount2], - Array2dTag) -{ - write<TDst>( - &src_values[0][0], - TCount1 * TCount2); -} + // Compresses data. + static void compress( + const Buffer& src_buffer, + Buffer& dst_buffer); -// write -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + // Decompresses data. + static void decompress( + const Buffer& src_buffer, + Buffer& dst_buffer); -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -// write (C-array) + static std::string generate_path( + const std::string& base_file_name); -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc* src_values, - int src_count) -{ - static_assert( - (std::is_arithmetic<TSrc>::value && - !std::is_same<TSrc, bool>::value && - !std::is_enum<TSrc>::value) || - std::is_class<TSrc>::value, - "Unsupported types."); - - if (!src_values) { - throw_error( - "Null pointer."); - } - - if (src_count < 0) { - throw_error( - "Negative count."); - } - - if (src_count == 0) { - return; - } - - using Dst = typename std::conditional< - std::is_same<TDst, void>::value, - TSrc, - TDst>::type; - - constexpr auto is_src_pure_numeric = - std::is_arithmetic<TSrc>::value && - (!std::is_same<TSrc, bool>::value) && - (!std::is_enum<TSrc>::value); - - constexpr auto is_dst_pure_numeric = - std::is_arithmetic<Dst>::value && - (!std::is_same<Dst, bool>::value) && - (!std::is_enum<Dst>::value); - - constexpr auto has_same_size = - (sizeof(TSrc) == sizeof(Dst)); - - constexpr auto use_inplace = - is_src_pure_numeric && - is_dst_pure_numeric && - has_same_size; - - using Tag = typename std::conditional< - use_inplace, - InplaceTag, - CastTag - >::type; - - write<TDst>( - src_values, - src_count, - Tag()); -} - -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc* src_values, - int src_count, - InplaceTag) -{ - constexpr auto src_size = static_cast<int>(sizeof(TSrc)); - - accomodate_io_buffer( - src_size, - src_count); - - std::uninitialized_copy_n( - src_values, - src_count, - &cast_buffer<TSrc&>()); - - // FIXME Byte order - // - - advance_io_buffer( - src_size, - src_count); -} - -template<typename TDst, typename TSrc> -void SavedGame::write( - const TSrc* src_values, - int src_count, - CastTag) -{ - using Tag = typename std::conditional< - std::is_arithmetic<TSrc>::value, - NumericTag, - typename std::conditional< - std::is_class<TSrc>::value, - ClassTag, - void - >::type - >::type; - - for (int i = 0; i < src_count; ++i) { - write<TDst>( - src_values[i], - Tag()); - } -} - -// write (C-array) -// >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> + static std::string get_failed_to_open_message( + const std::string& file_name, + bool is_open); + + + // Returns a string representation of a chunk id. + static std::string get_chunk_id_string( + uint32_t chunk_id); +}; // SavedGame } // ojk -#endif // OJK_SAVED_GAME_INCLUDED +#endif // OJK_SAVED_GAME_FWD_INCLUDED -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/openjk.git _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

