diff --git a/data/file_list.yml b/data/file_list.yml index 1365d94d..99bb5fbe 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -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': diff --git a/lib/al/Project/SaveData/SaveDataDirector.cpp b/lib/al/Project/SaveData/SaveDataDirector.cpp new file mode 100644 index 00000000..0af9ab2a --- /dev/null +++ b/lib/al/Project/SaveData/SaveDataDirector.cpp @@ -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; + + 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 diff --git a/lib/al/Project/SaveData/SaveDataDirector.h b/lib/al/Project/SaveData/SaveDataDirector.h index df99acd0..be826710 100644 --- a/lib/al/Project/SaveData/SaveDataDirector.h +++ b/lib/al/Project/SaveData/SaveDataDirector.h @@ -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 mBuffer;