Library/SaveData: Implement SaveDataDirector (#870)

This commit is contained in:
Narr the Reg 2026-01-16 06:37:35 -06:00 committed by GitHub
parent aae5a8bf2b
commit 409bf2f3d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 197 additions and 19 deletions

View file

@ -295761,81 +295761,81 @@ Project/SaveData/SaveDataDirector.o:
label:
- _ZN2al16SaveDataDirectorC1Eji
- _ZN2al16SaveDataDirectorC2Eji
status: NotDecompiled
status: Matching
- offset: 0xa7ead8
size: 76
label: _ZN2al16SaveDataDirector10threadFuncEv
status: NotDecompiled
status: Matching
- offset: 0xa7eb24
size: 8
label: _ZN2al16SaveDataDirector17initCheckSaveDataEv
status: NotDecompiled
status: Matching
- offset: 0xa7eb2c
size: 252
label: _ZN2al16SaveDataDirector18requestInitSaveDirEPKcjj
status: NotDecompiled
status: Matching
- offset: 0xa7ec28
size: 292
label: _ZN2al16SaveDataDirector15initSaveDirSyncEPKcjj
status: NotDecompiled
status: Matching
- offset: 0xa7ed4c
size: 64
label: _ZN2al16SaveDataDirector13requestFormatEii
status: NotDecompiled
status: Matching
- offset: 0xa7ed8c
size: 112
label: _ZN2al16SaveDataDirector10formatSyncEii
status: NotDecompiled
status: Matching
- offset: 0xa7edfc
size: 252
label: _ZN2al16SaveDataDirector11requestReadEPKcjj
status: NotDecompiled
status: Matching
- offset: 0xa7eef8
size: 292
label: _ZN2al16SaveDataDirector8readSyncEPKcjj
status: NotDecompiled
status: Matching
- offset: 0xa7f01c
size: 268
label: _ZN2al16SaveDataDirector12requestWriteEPKcjjb
status: NotDecompiled
status: Matching
- offset: 0xa7f128
size: 72
label: _ZN2al16SaveDataDirector12requestFlushEv
status: NotDecompiled
status: Matching
- offset: 0xa7f170
size: 296
label: _ZN2al16SaveDataDirector9writeSyncEPKcjj
status: NotDecompiled
status: Matching
- offset: 0xa7f298
size: 64
label: _ZN2al16SaveDataDirector14updateSequenceEv
status: NotDecompiled
status: Matching
- offset: 0xa7f2d8
size: 32
label: _ZNK2al16SaveDataDirector14isDoneSequenceEv
status: NotDecompiled
status: Matching
- offset: 0xa7f2f8
size: 12
label: _ZN2al16SaveDataDirector13getWorkBufferEv
status: NotDecompiled
status: Matching
- offset: 0xa7f304
size: 8
label: _ZN2al16SaveDataDirector9getResultEv
status: NotDecompiled
status: Matching
- offset: 0xa7f30c
size: 28
label: _ZNK2al10FunctorV0MIPNS_16SaveDataDirectorEMS1_FvvEEclEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0xa7f328
size: 76
label: _ZNK2al10FunctorV0MIPNS_16SaveDataDirectorEMS1_FvvEE5cloneEv
status: NotDecompiled
status: Matching
lazy: true
- offset: 0xa7f374
size: 4
label: _ZN2al10FunctorV0MIPNS_16SaveDataDirectorEMS1_FvvEED0Ev
status: NotDecompiled
status: Matching
lazy: true
Project/SaveData/SaveDataFunction.o:
'.text':

View file

@ -0,0 +1,174 @@
#include "Project/SaveData/SaveDataDirector.h"
#include "Library/Thread/AsyncFunctorThread.h"
#include "Project/SaveData/SaveDataFunction.h"
#include "Project/SaveData/SaveDataSequenceFormat.h"
#include "Project/SaveData/SaveDataSequenceInitDir.h"
#include "Project/SaveData/SaveDataSequenceRead.h"
#include "Project/SaveData/SaveDataSequenceWrite.h"
namespace al {
SaveDataDirector::SaveDataDirector(u32 workBufferSize, s32 threadPriority) {
using SaveDataDirectorFunctor = FunctorV0M<SaveDataDirector*, void (SaveDataDirector::*)()>;
mInitDirSequence = new SaveDataSequenceInitDir(0);
mFormatSequence = new SaveDataSequenceFormat();
mReadSequence = new SaveDataSequenceRead(0);
mWriteSequence = new SaveDataSequenceWrite(0);
u32 bufferSize = workBufferSize + sizeof(SaveDataFunction::SaveDataHeader);
mBuffer.tryAllocBuffer(bufferSize, nullptr);
mSaveDataThread = new AsyncFunctorThread(
"セーブデータスレッド", SaveDataDirectorFunctor{this, &SaveDataDirector::threadFunc},
threadPriority, 0x2000, sead::CoreId::cMain);
initCheckSaveData();
}
void SaveDataDirector::threadFunc() {
mResult = mRunningSequence->threadFunc(mCurrentFileName.cstr());
}
void SaveDataDirector::initCheckSaveData() {
mIsInitialized = false;
}
bool SaveDataDirector::requestInitSaveDir(const char* fileName, u32 dirSize, u32 version) {
mCurrentFileName = fileName;
mInitDirSequence->start(mBuffer.getBufferPtr(),
dirSize + sizeof(SaveDataFunction::SaveDataHeader), version);
mRunningSequence = mInitDirSequence;
mResult = SaveDataFunction::makeInvalidResult();
mIsInitialized = true;
mSaveDataThread->start();
return true;
}
bool SaveDataDirector::initSaveDirSync(const char* fileName, u32 dirSize, u32 version) {
mCurrentFileName = fileName;
mInitDirSequence->start(mBuffer.getBufferPtr(),
dirSize + sizeof(SaveDataFunction::SaveDataHeader), version);
mRunningSequence = mInitDirSequence;
mResult = SaveDataFunction::makeInvalidResult();
mIsInitialized = true;
threadFunc();
mRunningSequence = nullptr;
return true;
}
bool SaveDataDirector::requestFormat(s32 a, s32 b) {
mFormatSequence->start(a, b);
mRunningSequence = mFormatSequence;
mResult = SaveDataFunction::makeInvalidResult();
mSaveDataThread->start();
return true;
}
bool SaveDataDirector::formatSync(s32 a, s32 b) {
mFormatSequence->start(a, b);
mRunningSequence = mFormatSequence;
mResult = SaveDataFunction::makeInvalidResult();
threadFunc();
mRunningSequence = nullptr;
return true;
}
bool SaveDataDirector::requestRead(const char* fileName, u32 readSize, u32 version) {
if (_29)
return true;
mCurrentFileName = fileName;
mReadSequence->start(mBuffer.getBufferPtr(),
readSize + sizeof(SaveDataFunction::SaveDataHeader), version);
mRunningSequence = mReadSequence;
mResult = SaveDataFunction::makeInvalidResult();
mSaveDataThread->start();
return true;
}
bool SaveDataDirector::readSync(const char* fileName, u32 readSize, u32 version) {
if (_29)
return true;
mCurrentFileName = fileName;
mReadSequence->start(mBuffer.getBufferPtr(),
readSize + sizeof(SaveDataFunction::SaveDataHeader), version);
mRunningSequence = mReadSequence;
mResult = SaveDataFunction::makeInvalidResult();
threadFunc();
mRunningSequence = nullptr;
return true;
}
bool SaveDataDirector::requestWrite(const char* fileName, u32 writeSize, u32 version,
bool isFlushNeeded) {
if (_29)
return true;
mCurrentFileName = fileName;
mWriteSequence->start(mBuffer.getBufferPtr(),
writeSize + sizeof(SaveDataFunction::SaveDataHeader), version,
isFlushNeeded);
mRunningSequence = mWriteSequence;
mResult = SaveDataFunction::makeInvalidResult();
mSaveDataThread->start();
return true;
}
bool SaveDataDirector::requestFlush() {
if (_29)
return true;
mWriteSequence->startFlushOnly();
mRunningSequence = mWriteSequence;
mResult = SaveDataFunction::makeInvalidResult();
mSaveDataThread->start();
return true;
}
bool SaveDataDirector::writeSync(const char* fileName, u32 writeSize, u32 version) {
if (_29)
return true;
mCurrentFileName = fileName;
mWriteSequence->start(mBuffer.getBufferPtr(),
writeSize + sizeof(SaveDataFunction::SaveDataHeader), version, true);
mRunningSequence = mWriteSequence;
mResult = SaveDataFunction::makeInvalidResult();
threadFunc();
mRunningSequence = nullptr;
return true;
}
bool SaveDataDirector::updateSequence() {
if (_29)
return true;
if (!mSaveDataThread->isDone())
return false;
mRunningSequence = nullptr;
return true;
}
bool SaveDataDirector::isDoneSequence() const {
return _29 || !mRunningSequence;
}
u8* SaveDataDirector::getWorkBuffer() {
return mBuffer.getBufferPtr() + sizeof(SaveDataFunction::SaveDataHeader);
}
s32 SaveDataDirector::getResult() {
return mResult;
}
} // namespace al

View file

@ -12,6 +12,8 @@ class SaveDataSequenceRead;
class SaveDataSequenceWrite;
class AsyncFunctorThread;
// NOTE: prone to race conditions. Requesting an action while another one is running drops the
// second request
class SaveDataDirector {
public:
SaveDataDirector(u32 workBufferSize, s32 threadPriority);
@ -20,6 +22,7 @@ public:
void initCheckSaveData();
bool requestInitSaveDir(const char* fileName, u32 dirSize, u32 version);
bool initSaveDirSync(const char* fileName, u32 dirSize, u32 version);
// TODO: add parameter names to requestFormat and formatSync
bool requestFormat(s32, s32);
bool formatSync(s32, s32);
bool requestRead(const char* fileName, u32 readSize, u32 version);
@ -44,6 +47,7 @@ private:
SaveDataSequenceFormat* mFormatSequence = nullptr;
SaveDataSequenceRead* mReadSequence = nullptr;
SaveDataSequenceWrite* mWriteSequence = nullptr;
// NOTE: initialization started, possibly still running
bool mIsInitialized = false;
bool _29 = false;
sead::Buffer<u8> mBuffer;