[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