Browse Source

Implemented DatStatus signature changes

Ivan Arkhipov 4 years ago
parent
commit
f1e17c6706

+ 29 - 20
include/DatSubsystems/DatStatus.h

@@ -3,7 +3,7 @@
 
 #include <string>
 #include <functional>
-#include <vector>
+#include <set>
 
 namespace LOTRO_DAT {
     class DatFile;
@@ -33,6 +33,9 @@ namespace LOTRO_DAT {
             E_FREE
         };
 
+        using Callback = std::function<void(DAT_STATUS, double, unsigned long long, unsigned long long, std::string)>; 
+        // Callback arguments: status, percentage, finished_items, total_items, debug message 
+        
         DatStatus() = delete;
 
         DatStatus(const DatStatus &other) = delete;
@@ -43,39 +46,45 @@ namespace LOTRO_DAT {
 
         explicit DatStatus(DatFile *datFilePtr);
 
-        void UpdateStatus(); 
-        
-        void SetPercentage();
+        void SetStatus(DAT_STATUS status);
 
         void SetFinishedParts(unsigned long long finished_parts);
 
         void SetTotalParts(unsigned long long total_parts);
 
-        unsigned GetPercentage();
-
         void SetDebugMessage(const std::string &message);
 
-        std::string GetDebugMessage();
+        DAT_STATUS GetStatus();
 
-        void SetStatus(DAT_STATUS status);
+        double GetPercentage();
 
-        DAT_STATUS GetStatus();
+        unsigned long long GetFinishedParts();
+
+        unsigned long long GetTotalParts(); 
+
+        std::string GetDebugMessage();
+
+        void SetDefaultStatus();
 
         bool CheckIfNotPatched();
+        
+        void AddStatusChangedCallbackFunction(Callback* func);
+
+        void RemoveStatusChangedCallbackFunction(Callback* func);
+
+        bool IsFunctionRegisteredAsCallback(Callback* func);
 
-        void ClearAll();
+        void EraseAllCallbackFunctions();
 
     private:
-        DatFile *dat;
-        double percentage_;
-        unsigned long long finished_parts_;
-        unsigned long long total_parts_;
-        DAT_STATUS status_;
-
-        using callback = std::function<void(double, unsigned long long, unsigned long long, DAT_STATUS)>;
-        std::vector<callback> callback_functions_lazy_;
-        std::vector<callback> callback_functions_unoptimized_;
-        std::string debug_message_;
+        DatFile *dat = nullptr;
+        DAT_STATUS status_ = DAT_STATUS::E_FREE;
+        unsigned long long finished_parts_ = 0;
+        unsigned long long total_parts_ = 0;
+        double percentage_ = 0;
+        std::string debug_message_ = "";
+
+        std::set<Callback*> callback_functions_;
     };
 }
 

+ 9 - 9
src/DatFile.cpp

@@ -107,27 +107,27 @@ namespace LOTRO_DAT {
         auto operation = io_->Init(filename);
         if (operation.result != SUCCESS) {
             Deinitialize();
-            status_->ClearAll();
+            status_->SetDefaultStatus();
             return DatOperationResult<>(ERROR, "DATINIT: Error, cannot initialize dat due to internal IO error");
         }
 
         operation = fileSystem_->Init();
         if (operation.result != SUCCESS) {
             Deinitialize();
-            status_->ClearAll();
+            status_->SetDefaultStatus();
             return DatOperationResult<>(ERROR, "DATINIT: Error, cannot initialize dat due to filesystem parsing error");
         }
 
         operation = localeManager_->Init();
         if (operation.result != SUCCESS) {
             Deinitialize();
-            status_->ClearAll();
+            status_->SetDefaultStatus();
             return DatOperationResult<>(ERROR, "DATINIT: Error, cannot initialize dat due to locale manager initialisation error");
         }
 
         initialized_ = true;
 
-        status_->ClearAll();
+        status_->SetDefaultStatus();
         return DatOperationResult<>();
     }
 
@@ -151,7 +151,7 @@ namespace LOTRO_DAT {
         localeManager_->PrintInformaion(out);
 
         fclose(out);
-        status_->ClearAll();
+        status_->SetDefaultStatus();
         return DatOperationResult<>(SUCCESS);
     }
 
@@ -160,24 +160,24 @@ namespace LOTRO_DAT {
 
         auto operation = localeManager_->DeInit();
         if (operation.result != SUCCESS) {
-            status_->ClearAll();
+            status_->SetDefaultStatus();
             return DatOperationResult<>(ERROR, "DATDEINIT: Error, cannot deinitialize. msg: " + operation.msg);
         }
 
         operation = fileSystem_->DeInit();
         if (operation.result != SUCCESS) {
-            status_->ClearAll();
+            status_->SetDefaultStatus();
             return DatOperationResult<>(ERROR, "DATDEINIT: Error, cannot deinitialize. msg: " + operation.msg);
         }
 
         operation = io_->DeInit();
         if (operation.result != SUCCESS) {
-            status_->ClearAll();
+            status_->SetDefaultStatus();
             return DatOperationResult<>(ERROR, "DATDEINIT: Error, cannot deinitialize. msg: " + operation.msg);
         }
 
         initialized_ = false;
-        status_->ClearAll();
+        status_->SetDefaultStatus();
         return DatOperationResult<>();
     }
 

+ 9 - 7
src/DatSubsystems/DatBackupManager.cpp

@@ -43,10 +43,9 @@ namespace LOTRO_DAT {
             return DatOperationResult<>(ERROR, "CREATEBACKUP: cannot open file " + backup_datname);
 
         dat->GetStatusModule().SetStatus(DatStatus::E_BACKUP_CREATING);
-        dat->GetStatusModule().SetPercentage(0);
         dat->GetStatusModule().SetDebugMessage("Creating backup " + backup_datname + " from " + dat->GetIO().GetFilename().value);
         auto operation = CopyDatFile(*dat, file);
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
 
         fclose(file);
 
@@ -78,10 +77,10 @@ namespace LOTRO_DAT {
             return DatOperationResult<>(ERROR, "RESTOREFROMBACKUP: cannot open file " + backup_datname);
 
         dat->GetStatusModule().SetStatus(DatStatus::E_BACKUP_RESTORING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
         dat->GetStatusModule().SetDebugMessage("Restoring file " + dat->GetIO().GetFilename().value +  " from backup " + backup_datname);
         auto operation = CopyDatFile(backup_file, file);
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
 
         fclose(file);
         if (operation.result == ERROR)
@@ -101,13 +100,14 @@ namespace LOTRO_DAT {
 
     DatOperationResult<> DatBackupManager::RemoveBackup(const std::string &backup_datname) {
         dat->GetStatusModule().SetStatus(DatStatus::E_BACKUP_REMOVING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
+        dat->GetStatusModule().SetTotalParts(1);
         dat->GetStatusModule().SetDebugMessage("Removing backup file " + backup_datname);
 
         if (remove(backup_datname.c_str()) != 0)
             LOG(INFO) << "Removed backup file " << backup_datname;
 
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         return DatOperationResult<>(SUCCESS);
     }
 
@@ -125,10 +125,12 @@ namespace LOTRO_DAT {
                 source.GetIO().GetActualDatSize().value / COPY_BLOCK_SIZE + (source.GetIO().GetActualDatSize().value % COPY_BLOCK_SIZE != 0);
         long long newfile_size = 0;
         unsigned elapsed_size = unsigned(source.GetIO().GetActualDatSize().value - newfile_size);
+        
+        dat->GetStatusModule().SetTotalParts(parts_count);
 
         BinaryData data(COPY_BLOCK_SIZE);
         for (unsigned i = 0; i < parts_count; i++) {
-            dat->GetStatusModule().SetPercentage(i * 100 / (unsigned)parts_count);
+            dat->GetStatusModule().SetFinishedParts(i);
 
             auto operation = source.GetIO().ReadData(data, std::min(COPY_BLOCK_SIZE, elapsed_size), newfile_size);
             if (operation.result == ERROR)

+ 21 - 16
src/DatSubsystems/DatExporter.cpp

@@ -29,13 +29,17 @@ namespace LOTRO_DAT {
         int iterated_files = 0;
 
         dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
+        dat->GetStatusModule().SetTotalParts(dat->GetFileSystem().GetInitialisedFilesNumber());
+
         dat->GetStatusModule().SetDebugMessage("Starting extracting files of type " + std::to_string(type) + ", this may take long time, please be patient!");
         LOG(INFO) << "Extracting files by type " + std::to_string(type) + "to database...";
 
         auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&iterated_files, &success_exported, this, type, &output_directory_path](std::shared_ptr<SubFile>& file) -> void {
             iterated_files++;
-            dat->GetStatusModule().SetPercentage(iterated_files * 100u / dat->GetFileSystem().GetInitialisedFilesNumber());
+            dat->GetStatusModule().SetFinishedParts(iterated_files);
+            dat->GetStatusModule().SetTotalParts(dat->GetFileSystem().GetInitialisedFilesNumber());
+
             if ((file->FileType() & type) == NO_TYPE)
                 return;
 
@@ -57,7 +61,7 @@ namespace LOTRO_DAT {
         });
 
         LOG(INFO) << "Extracting files: successfully exported " << success_exported << " files";
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         return DatOperationResult<int>(success_exported, SUCCESS);
     }
 
@@ -72,19 +76,20 @@ namespace LOTRO_DAT {
 
     DatOperationResult<> DatExporter::ExtractFileById(long long file_id, std::string output_filename) {
         dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
+        dat->GetStatusModule().SetTotalParts(1);
         dat->GetStatusModule().SetDebugMessage("Extracting file " + std::to_string(file_id) + " to file " + output_filename);
 
         auto operation_GetFile = dat->GetFileSystem().GetFile(file_id);
         if (operation_GetFile.result == ERROR) {
-            dat->GetStatusModule().ClearAll();
+            dat->GetStatusModule().SetDefaultStatus();
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: File not found! id = " + std::to_string(file_id));
         }
         std::shared_ptr<SubFile> file = operation_GetFile.value;
 
         auto operation_GetFileData = dat->GetFileSystem().GetFileData(*file, 8);
         if (operation_GetFileData.result == ERROR) {
-            dat->GetStatusModule().ClearAll();
+            dat->GetStatusModule().SetDefaultStatus();
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Can't get data for id = " + std::to_string(file_id));
         }
 
@@ -97,7 +102,7 @@ namespace LOTRO_DAT {
         else
             result = export_data.binary_data.WriteToFile(output_filename + file->Extension());
 
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         if (!result)
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYID: Cannot write to file" + output_filename + file->Extension());
 
@@ -121,7 +126,8 @@ namespace LOTRO_DAT {
             return DatOperationResult<int>(0, ERROR, "EXTRACTALLBYTYPETODB: database is nullptr");
 
         dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
+        dat->GetStatusModule().SetTotalParts(dat->GetFileSystem().GetInitialisedFilesNumber());
         dat->GetStatusModule().SetDebugMessage("Initialising extraction of files by type " + std::to_string(type) + "to database... This may take long time, please be patient!\"");
         LOG(INFO) << "Extracting files by type " + std::to_string(type) + "to database...";
 
@@ -130,7 +136,7 @@ namespace LOTRO_DAT {
 
         auto operation = dat->GetFileSystem().PerformOperationOnAllFiles([&success_exported, &iterated_files, this, type, db](std::shared_ptr<SubFile>& file) {
             iterated_files++;
-            dat->GetStatusModule().SetPercentage(iterated_files * 100u / dat->GetFileSystem().GetInitialisedFilesNumber());
+            dat->GetStatusModule().SetFinishedParts(iterated_files);
 
             if ((file->FileType() & type) == NO_TYPE)
                 return;
@@ -146,12 +152,10 @@ namespace LOTRO_DAT {
         });
 
         LOG(INFO) << "Extracting files: successfully exported " << success_exported << " files";
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         return DatOperationResult<int>(success_exported, SUCCESS);
     }
 
-
-
     /*!
      * \author Ivan Arkhipov
      * \date 21.10.2018
@@ -165,19 +169,20 @@ namespace LOTRO_DAT {
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYIDTODB: database is nullptr");
 
         dat->GetStatusModule().SetStatus(DatStatus::E_EXTRACTING);
-        dat->GetStatusModule().SetPercentage(50);
+        dat->GetStatusModule().SetFinishedParts(0);
+        dat->GetStatusModule().SetTotalParts(1);
         LOG(INFO) << "Extracting file with id = " << file_id << "to database...";
 
         auto operation_GetFile = dat->GetFileSystem().GetFile(file_id);
         if (operation_GetFile.result == ERROR) {
-            dat->GetStatusModule().ClearAll();
+            dat->GetStatusModule().SetDefaultStatus();
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYIDTODB: File not found! id = " + std::to_string(file_id));
         }
         std::shared_ptr<SubFile> file = operation_GetFile.value;
 
         auto operation_GetFileData = dat->GetFileSystem().GetFileData(*file, 8);
         if (operation_GetFileData.result == ERROR) {
-            dat->GetStatusModule().ClearAll();
+            dat->GetStatusModule().SetDefaultStatus();
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYIDTODB: Can't get data for id = " + std::to_string(file_id));
         }
 
@@ -185,7 +190,7 @@ namespace LOTRO_DAT {
 
         bool result = db->PushFile(export_data);
 
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         if (!result)
             return DatOperationResult<>(ERROR, "EXTRACTFILEBYIDTODB: Cannot export file" + std::to_string(file_id));
 

+ 12 - 10
src/DatSubsystems/DatLocaleManager.cpp

@@ -188,7 +188,7 @@ namespace LOTRO_DAT {
             LOG(INFO) << "Locale is already " << locale << ", nothing to do.";
 
             if (dat->GetStatusModule().GetStatus() == DatStatus::E_COMMITING)
-                dat->GetStatusModule().ClearAll();
+                dat->GetStatusModule().SetDefaultStatus();
 
             return DatOperationResult<>(SUCCESS);
         }
@@ -197,10 +197,11 @@ namespace LOTRO_DAT {
 
         size_t files_total = dict.size();
         size_t files_proceeded = 0;
+        dat->GetStatusModule().SetTotalParts(files_total);
 
         for (const auto &file : dict) {
             ++files_proceeded;
-            dat->GetStatusModule().SetPercentage(files_proceeded * 100 / files_total);
+            dat->GetStatusModule().SetFinishedParts(files_proceeded);
 
             if (CategoryIsInactive(file.second.category) && locale == PATCHED)
                 continue;
@@ -224,7 +225,7 @@ namespace LOTRO_DAT {
         current_locale_ = locale;
 
         if (dat->GetStatusModule().GetStatus() == DatStatus::E_COMMITING)
-            dat->GetStatusModule().ClearAll();
+            dat->GetStatusModule().SetDefaultStatus();
 
         return DatOperationResult<>(SUCCESS);
     }
@@ -569,44 +570,45 @@ namespace LOTRO_DAT {
     DatOperationResult<> DatLocaleManager::EnableCategory(long long category) {
         inactive_categories.erase(category);
         dat->GetStatusModule().SetStatus(DatStatus::E_COMMITING);
-        dat->GetStatusModule().SetPercentage(0);
-
+        
         size_t files_count = patch_dict_.size();
         size_t files_processed = 0;
+        dat->GetStatusModule().SetTotalParts(files_count);
 
         for (const auto& entry : patch_dict_) {
             SubFile file = entry.second;
             ++files_processed;
-            dat->GetStatusModule().SetPercentage(files_processed * 100 / files_count);
+            dat->GetStatusModule().SetFinishedParts(files_processed);
 
             if (file.category == category) {
                 dat->GetFileSystem().UpdateFileInfo(file);
             }
         }
 
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         return DatOperationResult<>(SUCCESS);
     }
 
     DatOperationResult<> DatLocaleManager::DisableCategory(long long category) {
         inactive_categories.insert(category);
         dat->GetStatusModule().SetStatus(DatStatus::E_COMMITING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
 
         size_t files_count = orig_dict_.size();
         size_t files_processed = 0;
+        dat->GetStatusModule().SetTotalParts(files_count);
 
         for (const auto& entry : orig_dict_) {
             SubFile file = entry.second;
             ++files_processed;
-            dat->GetStatusModule().SetPercentage(files_processed * 100 / files_count);
+            dat->GetStatusModule().SetFinishedParts(files_processed);
 
             if (file.category == category) {
                 dat->GetFileSystem().UpdateFileInfo(file);
             }
         }
 
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         return DatOperationResult<>(SUCCESS);
     }
 }

+ 18 - 12
src/DatSubsystems/DatPatcher.cpp

@@ -24,15 +24,17 @@ namespace LOTRO_DAT {
 
         if (single_file) {
             dat->GetStatusModule().SetStatus(DatStatus::E_PATCHING);
-            dat->GetStatusModule().SetPercentage(0);
+            dat->GetStatusModule().SetFinishedParts(0);
+            dat->GetStatusModule().SetTotalParts(1);
         }
 
         dat->GetStatusModule().SetDebugMessage("Patching file with id " + std::to_string(file_id));
 
         auto getfile_operation = dat->GetFileSystem().GetFile(file_id);
         if (getfile_operation.result == ERROR) {
-            if (single_file)
-                dat->GetStatusModule().ClearAll();
+            if (single_file) {
+                dat->GetStatusModule().SetDefaultStatus();
+            }
 
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: Unable to find file with id " + std::to_string(file_id));
@@ -57,8 +59,9 @@ namespace LOTRO_DAT {
         auto getdata_operation = dat->GetFileSystem().GetFileData(*file, 0);
 
         if (getdata_operation.result == ERROR) {
-            if (single_file)
-                dat->GetStatusModule().ClearAll();
+            if (single_file) {
+                dat->GetStatusModule().SetDefaultStatus();
+            }
 
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: can't get file data for id = " + std::to_string(file_id));
@@ -70,12 +73,14 @@ namespace LOTRO_DAT {
 
         auto result = ApplyFilePatch(file, patch_data);
 
-        if (single_file)
-            dat->GetStatusModule().ClearAll();
+        if (single_file) {
+            dat->GetStatusModule().SetDefaultStatus();
+        }
 
-        if (result.result == ERROR)
+        if (result.result == ERROR) {
             return DatOperationResult<>(ERROR,
                                         "PATCHSUBFILEDATA: applyfilepatch failed for id = " + std::to_string(file_id));
+        }
 
         return DatOperationResult<>(SUCCESS);
     }
@@ -94,7 +99,7 @@ namespace LOTRO_DAT {
             return DatOperationResult<int>(0, ERROR, "PATCHALLDATABASE: db is nullptr");
 
         dat->GetStatusModule().SetStatus(DatStatus::E_PATCHING);
-        dat->GetStatusModule().SetPercentage(0);
+        dat->GetStatusModule().SetFinishedParts(0);
         dat->GetStatusModule().SetDebugMessage("Patching database...");
 
         SubfileData data;
@@ -102,13 +107,14 @@ namespace LOTRO_DAT {
 
         int successfully_patched = 0;
         unsigned db_rows = db->CountRows();
+        dat->GetStatusModule().SetTotalParts(db_rows);
 
         for (unsigned i = 0; i < db_rows; ++i) {
             auto operation = PatchFile(data, false);
             if (operation.result == SUCCESS)
                 successfully_patched++;
-
-            dat->GetStatusModule().SetPercentage(i * 100 / db_rows);
+            
+            dat->GetStatusModule().SetFinishedParts(i);
 
             data = db->GetNextFile();
         }
@@ -116,7 +122,7 @@ namespace LOTRO_DAT {
         LOG(INFO) << "Database import success: patched " + std::to_string(successfully_patched) + " out of " +
                                                        std::to_string(db_rows) + " files";
 
-        dat->GetStatusModule().ClearAll();
+        dat->GetStatusModule().SetDefaultStatus();
         return DatOperationResult<int>(successfully_patched, SUCCESS);
     }
 

+ 58 - 18
src/DatSubsystems/DatStatus.cpp

@@ -1,42 +1,82 @@
 #include <DatSubsystems/DatStatus.h>
 #include <DatFile.h>
 
+#include <math.h>
+
 namespace LOTRO_DAT {
-    void DatStatus::SetPercentage(unsigned percent) {
-        percentage_ = std::min(100u, percent);
+    bool equalOfftoTwoDecimalPoints(double x, double y) {
+        return int(std::floor((x * 100.0) + .5) / 100.0) == int(std::floor((y * 100.0) + .5) / 100.0);
     }
 
-    unsigned DatStatus::GetPercentage() {
-        return percentage_;
+    DatStatus::DatStatus(DatFile *datFilePtr) : dat(datFilePtr) {
     }
 
-    bool DatStatus::CheckIfNotPatched() {
-        return dat->GetLocaleManager().patch_dict_.empty();
+    void DatStatus::SetStatus(DatStatus::DAT_STATUS status) {
+        status_ = status;
     }
-
-    DatStatus::DatStatus(DatFile *datFilePtr) : dat(datFilePtr), percentage_(0), status_(E_FREE) {
+        
+    void DatStatus::SetFinishedParts(unsigned long long finished_parts) {
+        finished_parts_ = finished_parts;
+        if (!equalOfftoTwoDecimalPoints(GetPercentage(), percentage_)) {
+            percentage_ = GetPercentage();
+            for (Callback* func : callback_functions_) {
+                (*func)(GetStatus(), GetPercentage(), GetFinishedParts(), GetTotalParts(), GetDebugMessage()); // evaluating callback functions, transfering all needed information.
+            }
+        }
     }
 
-    void DatStatus::ClearAll() {
-        debug_message = "";
-        status_ = E_FREE;
+    void DatStatus::SetTotalParts(unsigned long long total_parts) {
+        total_parts_ = total_parts;
     }
 
-    void DatStatus::SetStatus(DatStatus::DAT_STATUS status) {
-        status_ = status;
-
+    void DatStatus::SetDebugMessage(const std::string &message) {
+        debug_message_ = message;
     }
 
     DatStatus::DAT_STATUS DatStatus::GetStatus() {
         return status_;
     }
 
-    void DatStatus::SetDebugMessage(const std::string &message) {
-        debug_message = message;
+    double DatStatus::GetPercentage() {
+        return total_parts_ != 0 ? double(finished_parts_) / double(total_parts_) : 0;
+    }
+
+    unsigned long long DatStatus::GetFinishedParts() {
+        return finished_parts_;
+    }
 
+    unsigned long long DatStatus::GetTotalParts() {
+        return total_parts_;
     }
 
     std::string DatStatus::GetDebugMessage() {
-        return debug_message;
+        return debug_message_;
+    }
+    
+    void DatStatus::SetDefaultStatus() {
+        debug_message_ = "";
+        total_parts_ = 0;
+        finished_parts_ = 0;
+        status_ = E_FREE;
+    }
+
+    bool DatStatus::CheckIfNotPatched() {
+        return dat->GetLocaleManager().patch_dict_.empty();
+    }
+
+    void DatStatus::AddStatusChangedCallbackFunction(Callback* func) {
+        callback_functions_.insert(func);
+    }
+
+    void DatStatus::RemoveStatusChangedCallbackFunction(Callback* func) {
+        callback_functions_.erase(func);
+    }
+
+    bool DatStatus::IsFunctionRegisteredAsCallback(Callback* func) {
+        return callback_functions_.count(func);
+    }
+
+    void DatStatus::EraseAllCallbackFunctions() {
+        callback_functions_.clear();
     }
-}
+} // namespace LOTRO_DAT