[openjk] 31/130: Split saved game class into the interface and the implementation

Simon McVittie smcv at debian.org
Fri Oct 28 11:09:14 UTC 2016


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 <bibendovsky at hotmail.com>
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



More information about the Pkg-games-commits mailing list