Scripting: Add method to enable/disable storage bucket autoflushing

This commit is contained in:
Vicki Pfau 2023-02-08 20:37:19 -08:00
parent 466639ee31
commit 3cbfaa010d
2 changed files with 49 additions and 1 deletions

View File

@ -16,6 +16,7 @@
struct mScriptStorageBucket {
char* name;
struct mScriptValue* root;
bool autoflush;
bool dirty;
};
@ -33,6 +34,7 @@ static void mScriptStorageBucketSetFloat(struct mScriptStorageBucket* bucket, co
static void mScriptStorageBucketSetBool(struct mScriptStorageBucket* bucket, const char* key, bool value);
static bool mScriptStorageBucketReload(struct mScriptStorageBucket* bucket);
static bool mScriptStorageBucketFlush(struct mScriptStorageBucket* bucket);
static void mScriptStorageBucketEnableAutoFlush(struct mScriptStorageBucket* bucket, bool enable);
static void mScriptStorageContextDeinit(struct mScriptStorageContext*);
static void mScriptStorageContextFlushAll(struct mScriptStorageContext*);
@ -53,6 +55,7 @@ mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptStorageBucket, setTable, mScriptStorag
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptStorageBucket, setVoid, mScriptStorageBucketSetVoid, 2, CHARP, key, NUL, value);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptStorageBucket, BOOL, reload, mScriptStorageBucketReload, 0);
mSCRIPT_DECLARE_STRUCT_METHOD(mScriptStorageBucket, BOOL, flush, mScriptStorageBucketFlush, 0);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mScriptStorageBucket, enableAutoFlush, mScriptStorageBucketEnableAutoFlush, 1, BOOL, enable);
mSCRIPT_DEFINE_STRUCT(mScriptStorageBucket)
mSCRIPT_DEFINE_CLASS_DOCSTRING(
@ -76,6 +79,13 @@ mSCRIPT_DEFINE_STRUCT(mScriptStorageBucket)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptStorageBucket, reload)
mSCRIPT_DEFINE_DOCSTRING("Flush the bucket to disk manually")
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptStorageBucket, flush)
mSCRIPT_DEFINE_DOCSTRING(
"Enable or disable the automatic flushing of this bucket. This is good for ensuring buckets "
"don't get flushed in an inconsistent state. It will also disable flushing to disk when the "
"emulator is shut down, so make sure to either manually flush the bucket or re-enable "
"automatic flushing whenever you're done updating it if you do disable it prior."
)
mSCRIPT_DEFINE_STRUCT_METHOD(mScriptStorageBucket, enableAutoFlush)
mSCRIPT_DEFINE_END;
mSCRIPT_DECLARE_STRUCT(mScriptStorageContext);
@ -300,6 +310,10 @@ bool mScriptStorageBucketFlush(struct mScriptStorageBucket* bucket) {
return _mScriptStorageBucketFlushVF(bucket, vf);
}
void mScriptStorageBucketEnableAutoFlush(struct mScriptStorageBucket* bucket, bool enable) {
bucket->autoflush = enable;
}
bool mScriptStorageSaveBucketVF(struct mScriptContext* context, const char* bucketName, struct VFile* vf) {
struct mScriptValue* value = mScriptContextGetGlobal(context, "storage");
if (!value) {
@ -481,7 +495,9 @@ void mScriptStorageContextFlushAll(struct mScriptStorageContext* storage) {
if (HashTableIteratorStart(&storage->buckets, &iter)) {
do {
struct mScriptStorageBucket* bucket = HashTableIteratorGetValue(&storage->buckets, &iter);
mScriptStorageBucketFlush(bucket);
if (bucket->autoflush) {
mScriptStorageBucketFlush(bucket);
}
} while (HashTableIteratorNext(&storage->buckets, &iter));
}
}
@ -509,6 +525,7 @@ struct mScriptStorageBucket* mScriptStorageGetBucket(struct mScriptStorageContex
bucket = calloc(1, sizeof(*bucket));
bucket->name = strdup(name);
bucket->autoflush = true;
if (!mScriptStorageBucketReload(bucket)) {
bucket->root = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE);
}

View File

@ -522,6 +522,36 @@ M_TEST_DEFINE(structuredRoundTrip) {
mScriptContextDeinit(&context);
}
M_TEST_DEFINE(autoflush) {
SETUP_LUA;
TEST_PROGRAM("bucket = storage:getBucket('xtest')");
TEST_PROGRAM("assert(bucket)");
TEST_PROGRAM("assert(not bucket.a)");
TEST_PROGRAM("bucket:enableAutoFlush(true)")
TEST_PROGRAM("bucket.a = 1");
TEST_PROGRAM("storage:flushAll()");
TEST_PROGRAM("assert(bucket:reload())")
TEST_PROGRAM("assert(bucket.a == 1)");
TEST_PROGRAM("bucket:enableAutoFlush(false)")
TEST_PROGRAM("bucket.a = 2");
TEST_PROGRAM("storage:flushAll()");
TEST_PROGRAM("assert(bucket:reload())")
TEST_PROGRAM("assert(bucket.a == 1)");
TEST_PROGRAM("bucket:enableAutoFlush(false)")
TEST_PROGRAM("bucket.a = 3");
TEST_PROGRAM("storage:flushAll()");
TEST_PROGRAM("bucket:enableAutoFlush(true)")
TEST_PROGRAM("storage:flushAll()");
TEST_PROGRAM("assert(bucket:reload())")
TEST_PROGRAM("assert(bucket.a == 3)");
mScriptContextDeinit(&context);
}
M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptStorage,
cmocka_unit_test(basicInt),
cmocka_unit_test(basicFloat),
@ -551,4 +581,5 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(mScriptStorage,
cmocka_unit_test(deserializeNullByteString),
cmocka_unit_test(deserializeError),
cmocka_unit_test(structuredRoundTrip),
cmocka_unit_test(autoflush),
)