mirror of https://github.com/PCSX2/pcsx2.git
SaveState: Simplify and convert to std::thread
This commit is contained in:
parent
3fdab1222b
commit
17c049d7e3
|
@ -1265,15 +1265,6 @@ set(pcsx2UtilitiesSources
|
||||||
set(pcsx2UtilitiesHeaders
|
set(pcsx2UtilitiesHeaders
|
||||||
Utilities/AsciiFile.h)
|
Utilities/AsciiFile.h)
|
||||||
|
|
||||||
# Zip tools utilies sources
|
|
||||||
set(pcsx2ZipToolsSources
|
|
||||||
ZipTools/thread_gzip.cpp
|
|
||||||
ZipTools/thread_lzma.cpp)
|
|
||||||
|
|
||||||
# Zip tools utilies headers
|
|
||||||
set(pcsx2ZipToolsHeaders
|
|
||||||
ZipTools/ThreadedZipTools.h)
|
|
||||||
|
|
||||||
|
|
||||||
# Windows sources
|
# Windows sources
|
||||||
set(pcsx2WindowsSources
|
set(pcsx2WindowsSources
|
||||||
|
@ -1408,9 +1399,7 @@ target_sources(PCSX2 PRIVATE
|
||||||
${pcsx2SystemSources}
|
${pcsx2SystemSources}
|
||||||
${pcsx2SystemHeaders}
|
${pcsx2SystemHeaders}
|
||||||
${pcsx2UtilitiesSources}
|
${pcsx2UtilitiesSources}
|
||||||
${pcsx2UtilitiesHeaders}
|
${pcsx2UtilitiesHeaders})
|
||||||
${pcsx2ZipToolsSources}
|
|
||||||
${pcsx2ZipToolsHeaders})
|
|
||||||
|
|
||||||
# platform sources
|
# platform sources
|
||||||
# Linux
|
# Linux
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
#include "Elfheader.h"
|
#include "Elfheader.h"
|
||||||
#include "Counters.h"
|
#include "Counters.h"
|
||||||
#include "Patch.h"
|
#include "Patch.h"
|
||||||
|
#include "System/SysThreads.h"
|
||||||
|
|
||||||
#include "ZipTools/ThreadedZipTools.h"
|
|
||||||
#include "common/pxStreams.h"
|
#include "common/pxStreams.h"
|
||||||
#include "common/SafeArray.inl"
|
#include "common/SafeArray.inl"
|
||||||
#include "SPU2/spu2.h"
|
#include "SPU2/spu2.h"
|
||||||
|
@ -44,6 +44,14 @@
|
||||||
|
|
||||||
#include "gui/ConsoleLogger.h"
|
#include "gui/ConsoleLogger.h"
|
||||||
|
|
||||||
|
#ifndef PCSX2_CORE
|
||||||
|
#include "gui/App.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "common/pxStreams.h"
|
||||||
|
#include <wx/wfstream.h>
|
||||||
|
#include <wx/zipstrm.h>
|
||||||
|
|
||||||
using namespace R5900;
|
using namespace R5900;
|
||||||
|
|
||||||
|
|
||||||
|
@ -663,7 +671,7 @@ static void CheckVersion(pxInputStream& thr)
|
||||||
|
|
||||||
void SaveState_DownloadState(ArchiveEntryList* destlist)
|
void SaveState_DownloadState(ArchiveEntryList* destlist)
|
||||||
{
|
{
|
||||||
if (!SysHasValidState())
|
if (!GetCoreThread().HasActiveMachine())
|
||||||
throw Exception::RuntimeError()
|
throw Exception::RuntimeError()
|
||||||
.SetDiagMsg(L"SysExecEvent_DownloadState: Cannot freeze/download an invalid VM state!")
|
.SetDiagMsg(L"SysExecEvent_DownloadState: Cannot freeze/download an invalid VM state!")
|
||||||
.SetUserMsg(_("There is no active virtual machine state to download or save."));
|
.SetUserMsg(_("There is no active virtual machine state to download or save."));
|
||||||
|
@ -691,54 +699,13 @@ void SaveState_DownloadState(ArchiveEntryList* destlist)
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// CompressThread_VmState
|
// CompressThread_VmState
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class VmStateCompressThread : public BaseCompressThread
|
static void ZipStateToDiskOnThread(std::unique_ptr<ArchiveEntryList> srclist, std::unique_ptr<wxFFileOutputStream> outbase, wxString filename, wxString tempfile)
|
||||||
{
|
{
|
||||||
typedef BaseCompressThread _parent;
|
#ifndef PCSX2_CORE
|
||||||
|
wxGetApp().StartPendingSave();
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
std::unique_ptr<pxOutputStream> out(new pxOutputStream(tempfile, new wxZipOutputStream(outbase.release())));
|
||||||
ScopedLock m_lock_Compress;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VmStateCompressThread()
|
|
||||||
{
|
|
||||||
m_lock_Compress.Assign(mtx_CompressToDisk);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~VmStateCompressThread() = default;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void OnStartInThread()
|
|
||||||
{
|
|
||||||
_parent::OnStartInThread();
|
|
||||||
m_lock_Compress.Acquire();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnCleanupInThread()
|
|
||||||
{
|
|
||||||
m_lock_Compress.Release();
|
|
||||||
_parent::OnCleanupInThread();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void SaveState_ZipToDisk(ArchiveEntryList* srclist, const wxString& filename)
|
|
||||||
{
|
|
||||||
// Provisionals for scoped cleanup, in case of exception:
|
|
||||||
std::unique_ptr<ArchiveEntryList> elist(srclist);
|
|
||||||
|
|
||||||
wxString tempfile(filename + L".tmp");
|
|
||||||
|
|
||||||
wxFFileOutputStream* woot = new wxFFileOutputStream(tempfile);
|
|
||||||
if (!woot->IsOk())
|
|
||||||
throw Exception::CannotCreateStream(tempfile);
|
|
||||||
|
|
||||||
// Scheduler hint (yield) -- creating and saving the file is low priority compared to
|
|
||||||
// the emulator/vm thread. Sleeping the executor thread briefly before doing file
|
|
||||||
// transactions should help reduce overhead. --air
|
|
||||||
|
|
||||||
pxYield(4);
|
|
||||||
|
|
||||||
// Write the version and screenshot:
|
|
||||||
std::unique_ptr<pxOutputStream> out(new pxOutputStream(tempfile, new wxZipOutputStream(woot)));
|
|
||||||
wxZipOutputStream* gzfp = (wxZipOutputStream*)out->GetWxStreamBase();
|
wxZipOutputStream* gzfp = (wxZipOutputStream*)out->GetWxStreamBase();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -749,8 +716,9 @@ void SaveState_ZipToDisk(ArchiveEntryList* srclist, const wxString& filename)
|
||||||
gzfp->CloseEntry();
|
gzfp->CloseEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// This was never actually initialized...
|
||||||
std::unique_ptr<wxImage> m_screenshot;
|
std::unique_ptr<wxImage> m_screenshot;
|
||||||
|
|
||||||
if (m_screenshot)
|
if (m_screenshot)
|
||||||
{
|
{
|
||||||
wxZipEntry* vent = new wxZipEntry(EntryFilename_Screenshot);
|
wxZipEntry* vent = new wxZipEntry(EntryFilename_Screenshot);
|
||||||
|
@ -759,16 +727,61 @@ void SaveState_ZipToDisk(ArchiveEntryList* srclist, const wxString& filename)
|
||||||
m_screenshot->SaveFile(*gzfp, wxBITMAP_TYPE_JPEG);
|
m_screenshot->SaveFile(*gzfp, wxBITMAP_TYPE_JPEG);
|
||||||
gzfp->CloseEntry();
|
gzfp->CloseEntry();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
(*new VmStateCompressThread())
|
uint listlen = srclist->GetLength();
|
||||||
.SetSource(srclist)
|
for (uint i = 0; i < listlen; ++i)
|
||||||
.SetOutStream(out.get())
|
{
|
||||||
.SetFinishedPath(filename)
|
const ArchiveEntry& entry = (*srclist)[i];
|
||||||
.Start();
|
if (!entry.GetDataSize())
|
||||||
|
continue;
|
||||||
|
|
||||||
// No errors? Release cleanup handlers:
|
gzfp->PutNextEntry(entry.GetFilename());
|
||||||
elist.release();
|
|
||||||
out.release();
|
static const uint BlockSize = 0x64000;
|
||||||
|
uint curidx = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint thisBlockSize = std::min(BlockSize, entry.GetDataSize() - curidx);
|
||||||
|
gzfp->Write(srclist->GetPtr(entry.GetDataIndex() + curidx), thisBlockSize);
|
||||||
|
curidx += thisBlockSize;
|
||||||
|
} while (curidx < entry.GetDataSize());
|
||||||
|
|
||||||
|
gzfp->CloseEntry();
|
||||||
|
}
|
||||||
|
|
||||||
|
gzfp->Close();
|
||||||
|
|
||||||
|
if (!wxRenameFile(out->GetStreamName(), filename, true))
|
||||||
|
{
|
||||||
|
Console.Error("Failed to rename save state '%s' to '%s'", static_cast<const char*>(out->GetStreamName().c_str()), static_cast<const char*>(filename.c_str()));
|
||||||
|
#ifndef PCSX2_CORE
|
||||||
|
Msgbox::Alert(_("The savestate was not properly saved. The temporary file was created successfully but could not be moved to its final resting place."));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Console.WriteLn("(gzipThread) Data saved to disk without error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef PCSX2_CORE
|
||||||
|
wxGetApp().ClearPendingSave();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveState_ZipToDisk(ArchiveEntryList* srclist, const wxString& filename)
|
||||||
|
{
|
||||||
|
// Provisionals for scoped cleanup, in case of exception:
|
||||||
|
std::unique_ptr<ArchiveEntryList> elist(srclist);
|
||||||
|
|
||||||
|
wxString tempfile(filename + L".tmp");
|
||||||
|
std::unique_ptr<wxFFileOutputStream> out = std::make_unique<wxFFileOutputStream>(tempfile);
|
||||||
|
if (!out->IsOk())
|
||||||
|
throw Exception::CannotCreateStream(tempfile);
|
||||||
|
|
||||||
|
std::thread threaded_save(ZipStateToDiskOnThread, std::move(elist), std::move(out), filename, tempfile);
|
||||||
|
threaded_save.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveState_UnzipFromDisk(const wxString& filename)
|
void SaveState_UnzipFromDisk(const wxString& filename)
|
||||||
|
|
|
@ -179,6 +179,124 @@ protected:
|
||||||
void InputRecordingFreeze();
|
void InputRecordingFreeze();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// ArchiveEntry
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
class ArchiveEntry
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
wxString m_filename;
|
||||||
|
uptr m_dataidx;
|
||||||
|
size_t m_datasize;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ArchiveEntry(const wxString& filename = wxEmptyString)
|
||||||
|
: m_filename(filename)
|
||||||
|
{
|
||||||
|
m_dataidx = 0;
|
||||||
|
m_datasize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~ArchiveEntry() = default;
|
||||||
|
|
||||||
|
ArchiveEntry& SetDataIndex(uptr idx)
|
||||||
|
{
|
||||||
|
m_dataidx = idx;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveEntry& SetDataSize(size_t size)
|
||||||
|
{
|
||||||
|
m_datasize = size;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString GetFilename() const
|
||||||
|
{
|
||||||
|
return m_filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
uptr GetDataIndex() const
|
||||||
|
{
|
||||||
|
return m_dataidx;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint GetDataSize() const
|
||||||
|
{
|
||||||
|
return m_datasize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SafeArray< u8 > ArchiveDataBuffer;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// ArchiveEntryList
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
class ArchiveEntryList
|
||||||
|
{
|
||||||
|
DeclareNoncopyableObject(ArchiveEntryList);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<ArchiveEntry> m_list;
|
||||||
|
std::unique_ptr<ArchiveDataBuffer> m_data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~ArchiveEntryList() = default;
|
||||||
|
|
||||||
|
ArchiveEntryList() {}
|
||||||
|
|
||||||
|
ArchiveEntryList(ArchiveDataBuffer* data)
|
||||||
|
: m_data(data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveEntryList(ArchiveDataBuffer& data)
|
||||||
|
: m_data(&data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const VmStateBuffer* GetBuffer() const
|
||||||
|
{
|
||||||
|
return m_data.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VmStateBuffer* GetBuffer()
|
||||||
|
{
|
||||||
|
return m_data.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* GetPtr(uint idx)
|
||||||
|
{
|
||||||
|
return &(*m_data)[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* GetPtr(uint idx) const
|
||||||
|
{
|
||||||
|
return &(*m_data)[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveEntryList& Add(const ArchiveEntry& src)
|
||||||
|
{
|
||||||
|
m_list.push_back(src);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t GetLength() const
|
||||||
|
{
|
||||||
|
return m_list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArchiveEntry& operator[](uint idx)
|
||||||
|
{
|
||||||
|
return m_list[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const ArchiveEntry& operator[](uint idx) const
|
||||||
|
{
|
||||||
|
return m_list[idx];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Saving and Loading Specialized Implementations...
|
// Saving and Loading Specialized Implementations...
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
|
|
||||||
-------------------
|
|
||||||
ZipTools (folder)
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
Contains C++ interfaces for zipping to/from various formats
|
|
||||||
(primarily gzip and 7zip).
|
|
||||||
|
|
||||||
Notice: This folder is intended to be moved to a utility folder
|
|
||||||
outside the main PCSX2 folders at a later date.
|
|
|
@ -1,209 +0,0 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
||||||
*
|
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/PersistentThread.h"
|
|
||||||
#include "common/pxStreams.h"
|
|
||||||
#include "wx/zipstrm.h"
|
|
||||||
|
|
||||||
using namespace Threading;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// ArchiveEntry
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
class ArchiveEntry
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
wxString m_filename;
|
|
||||||
uptr m_dataidx;
|
|
||||||
size_t m_datasize;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ArchiveEntry( const wxString& filename=wxEmptyString )
|
|
||||||
: m_filename( filename )
|
|
||||||
{
|
|
||||||
m_dataidx = 0;
|
|
||||||
m_datasize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~ArchiveEntry() = default;
|
|
||||||
|
|
||||||
ArchiveEntry& SetDataIndex( uptr idx )
|
|
||||||
{
|
|
||||||
m_dataidx = idx;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchiveEntry& SetDataSize( size_t size )
|
|
||||||
{
|
|
||||||
m_datasize = size;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString GetFilename() const
|
|
||||||
{
|
|
||||||
return m_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
uptr GetDataIndex() const
|
|
||||||
{
|
|
||||||
return m_dataidx;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint GetDataSize() const
|
|
||||||
{
|
|
||||||
return m_datasize;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef SafeArray< u8 > ArchiveDataBuffer;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// ArchiveEntryList
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
class ArchiveEntryList
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject( ArchiveEntryList );
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::vector<ArchiveEntry> m_list;
|
|
||||||
std::unique_ptr<ArchiveDataBuffer> m_data;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~ArchiveEntryList() = default;
|
|
||||||
|
|
||||||
ArchiveEntryList() {}
|
|
||||||
|
|
||||||
ArchiveEntryList( ArchiveDataBuffer* data )
|
|
||||||
: m_data(data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchiveEntryList( ArchiveDataBuffer& data )
|
|
||||||
: m_data(&data)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
const VmStateBuffer* GetBuffer() const
|
|
||||||
{
|
|
||||||
return m_data.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
VmStateBuffer* GetBuffer()
|
|
||||||
{
|
|
||||||
return m_data.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
u8* GetPtr( uint idx )
|
|
||||||
{
|
|
||||||
return &(*m_data)[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
const u8* GetPtr( uint idx ) const
|
|
||||||
{
|
|
||||||
return &(*m_data)[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchiveEntryList& Add( const ArchiveEntry& src )
|
|
||||||
{
|
|
||||||
m_list.push_back( src );
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t GetLength() const
|
|
||||||
{
|
|
||||||
return m_list.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
ArchiveEntry& operator[](uint idx)
|
|
||||||
{
|
|
||||||
return m_list[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
const ArchiveEntry& operator[](uint idx) const
|
|
||||||
{
|
|
||||||
return m_list[idx];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// BaseCompressThread
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
class BaseCompressThread
|
|
||||||
: public pxThread
|
|
||||||
{
|
|
||||||
typedef pxThread _parent;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
pxOutputStream* m_gzfp;
|
|
||||||
ArchiveEntryList* m_src_list;
|
|
||||||
bool m_PendingSaveFlag;
|
|
||||||
|
|
||||||
wxString m_final_filename;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~BaseCompressThread();
|
|
||||||
|
|
||||||
BaseCompressThread& SetSource( ArchiveEntryList* srcdata )
|
|
||||||
{
|
|
||||||
m_src_list = srcdata;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseCompressThread& SetSource( ArchiveEntryList& srcdata )
|
|
||||||
{
|
|
||||||
m_src_list = &srcdata;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseCompressThread& SetOutStream( pxOutputStream* out )
|
|
||||||
{
|
|
||||||
m_gzfp = out;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseCompressThread& SetOutStream( pxOutputStream& out )
|
|
||||||
{
|
|
||||||
m_gzfp = &out;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseCompressThread& SetFinishedPath( const wxString& path )
|
|
||||||
{
|
|
||||||
m_final_filename = path;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString GetStreamName() const { return m_gzfp->GetStreamName(); }
|
|
||||||
|
|
||||||
BaseCompressThread& SetTargetFilename(const wxString& filename)
|
|
||||||
{
|
|
||||||
m_final_filename = filename;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
BaseCompressThread()
|
|
||||||
{
|
|
||||||
m_gzfp = NULL;
|
|
||||||
m_src_list = NULL;
|
|
||||||
m_PendingSaveFlag = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetPendingSave();
|
|
||||||
void ExecuteTaskInThread();
|
|
||||||
void OnCleanupInThread();
|
|
||||||
};
|
|
|
@ -1,98 +0,0 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
||||||
*
|
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
|
||||||
|
|
||||||
#include "gui/App.h"
|
|
||||||
#include "SaveState.h"
|
|
||||||
#include "ThreadedZipTools.h"
|
|
||||||
#include "common/SafeArray.inl"
|
|
||||||
#include "wx/wfstream.h"
|
|
||||||
|
|
||||||
|
|
||||||
BaseCompressThread::~BaseCompressThread()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
_parent::Cancel();
|
|
||||||
if( m_PendingSaveFlag )
|
|
||||||
{
|
|
||||||
wxGetApp().ClearPendingSave();
|
|
||||||
m_PendingSaveFlag = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DESTRUCTOR_CATCHALL
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseCompressThread::SetPendingSave()
|
|
||||||
{
|
|
||||||
wxGetApp().StartPendingSave();
|
|
||||||
m_PendingSaveFlag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseCompressThread::ExecuteTaskInThread()
|
|
||||||
{
|
|
||||||
// TODO : Add an API to PersistentThread for this! :) --air
|
|
||||||
//SetThreadPriority( THREAD_PRIORITY_BELOW_NORMAL );
|
|
||||||
|
|
||||||
// Notes:
|
|
||||||
// * Safeguard against corruption by writing to a temp file, and then copying the final
|
|
||||||
// result over the original.
|
|
||||||
|
|
||||||
if( !m_src_list ) return;
|
|
||||||
SetPendingSave();
|
|
||||||
|
|
||||||
Yield( 3 );
|
|
||||||
|
|
||||||
uint listlen = m_src_list->GetLength();
|
|
||||||
for( uint i=0; i<listlen; ++i )
|
|
||||||
{
|
|
||||||
const ArchiveEntry& entry = (*m_src_list)[i];
|
|
||||||
if (!entry.GetDataSize()) continue;
|
|
||||||
|
|
||||||
wxArchiveOutputStream& woot = *(wxArchiveOutputStream*)m_gzfp->GetWxStreamBase();
|
|
||||||
woot.PutNextEntry( entry.GetFilename() );
|
|
||||||
|
|
||||||
static const uint BlockSize = 0x64000;
|
|
||||||
uint curidx = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
uint thisBlockSize = std::min( BlockSize, entry.GetDataSize() - curidx );
|
|
||||||
m_gzfp->Write(m_src_list->GetPtr( entry.GetDataIndex() + curidx ), thisBlockSize);
|
|
||||||
curidx += thisBlockSize;
|
|
||||||
Yield( 2 );
|
|
||||||
} while( curidx < entry.GetDataSize() );
|
|
||||||
|
|
||||||
woot.CloseEntry();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_gzfp->Close();
|
|
||||||
|
|
||||||
if( !wxRenameFile( m_gzfp->GetStreamName(), m_final_filename, true ) )
|
|
||||||
throw Exception::BadStream( m_final_filename )
|
|
||||||
.SetDiagMsg(L"Failed to move or copy the temporary archive to the destination filename.")
|
|
||||||
.SetUserMsg(_("The savestate was not properly saved. The temporary file was created successfully but could not be moved to its final resting place."));
|
|
||||||
|
|
||||||
Console.WriteLn( "(gzipThread) Data saved to disk without error." );
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseCompressThread::OnCleanupInThread()
|
|
||||||
{
|
|
||||||
_parent::OnCleanupInThread();
|
|
||||||
wxGetApp().DeleteThread( this );
|
|
||||||
|
|
||||||
safe_delete(m_gzfp);
|
|
||||||
safe_delete(m_src_list);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
||||||
*
|
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "SaveState.h"
|
#include "SaveState.h"
|
||||||
#include "VUmicro.h"
|
#include "VUmicro.h"
|
||||||
|
|
||||||
#include "ZipTools/ThreadedZipTools.h"
|
|
||||||
#include "common/pxStreams.h"
|
#include "common/pxStreams.h"
|
||||||
#include "SPU2/spu2.h"
|
#include "SPU2/spu2.h"
|
||||||
#include "USB/USB.h"
|
#include "USB/USB.h"
|
||||||
|
|
|
@ -697,8 +697,6 @@
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="gui\Saveslots.cpp" />
|
<ClCompile Include="gui\Saveslots.cpp" />
|
||||||
<ClCompile Include="gui\SysState.cpp" />
|
<ClCompile Include="gui\SysState.cpp" />
|
||||||
<ClCompile Include="ZipTools\thread_gzip.cpp" />
|
|
||||||
<ClCompile Include="ZipTools\thread_lzma.cpp" />
|
|
||||||
<ClCompile Include="windows\Optimus.cpp" />
|
<ClCompile Include="windows\Optimus.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1089,7 +1087,6 @@
|
||||||
<ClInclude Include="gui\RecentIsoList.h" />
|
<ClInclude Include="gui\RecentIsoList.h" />
|
||||||
<ClInclude Include="PathDefs.h" />
|
<ClInclude Include="PathDefs.h" />
|
||||||
<ClInclude Include="SysForwardDefs.h" />
|
<ClInclude Include="SysForwardDefs.h" />
|
||||||
<ClInclude Include="ZipTools\ThreadedZipTools.h" />
|
|
||||||
<ClInclude Include="cheatscpp.h" />
|
<ClInclude Include="cheatscpp.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -863,12 +863,6 @@
|
||||||
<ClCompile Include="gui\SysState.cpp">
|
<ClCompile Include="gui\SysState.cpp">
|
||||||
<Filter>AppHost</Filter>
|
<Filter>AppHost</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ZipTools\thread_gzip.cpp">
|
|
||||||
<Filter>Misc</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ZipTools\thread_lzma.cpp">
|
|
||||||
<Filter>Misc</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="GameDatabase.cpp">
|
<ClCompile Include="GameDatabase.cpp">
|
||||||
<Filter>Misc</Filter>
|
<Filter>Misc</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -2017,9 +2011,6 @@
|
||||||
<ClInclude Include="SysForwardDefs.h">
|
<ClInclude Include="SysForwardDefs.h">
|
||||||
<Filter>AppHost\Include</Filter>
|
<Filter>AppHost\Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ZipTools\ThreadedZipTools.h">
|
|
||||||
<Filter>Misc</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="GameDatabase.h">
|
<ClInclude Include="GameDatabase.h">
|
||||||
<Filter>Misc</Filter>
|
<Filter>Misc</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
Loading…
Reference in New Issue