184 lines
7.2 KiB
C++
184 lines
7.2 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: IRegistry.hpp
|
|
Date: 2021-6-11
|
|
Author: Reece
|
|
***/
|
|
#pragma once
|
|
|
|
namespace Aurora::Registry
|
|
{
|
|
using RegistryType = Data::EDataType;
|
|
using RegistryValue = Data::TypedValue;
|
|
|
|
struct AUKN_SYM IOPath
|
|
{
|
|
AU_COPY_MOVE(IOPath);
|
|
|
|
IOPath();
|
|
IOPath(const AuString &path);
|
|
|
|
bool isSpecified {};
|
|
|
|
// ERegistrySource::eFS
|
|
AuString filePath;
|
|
|
|
// [...]
|
|
|
|
bool operator ==(const IOPath &other) const;
|
|
operator bool() const;
|
|
};
|
|
|
|
|
|
/**
|
|
* This registry implementation is a fairly reliable, small scale, preference, and app variable database
|
|
* Do not consider this as a replacement for a "real" high performance kvp database, it is not, it's a small cache backed document serializer for user profiles
|
|
*
|
|
* Basic use case:--------------------------------------------------------------
|
|
* -> AllocRegistry()
|
|
* -> Read("~/Registry/MyApp/DefSettings.dat")
|
|
* -> Read("~/Registry/MyApp/UserSettings.dat")
|
|
* -> menu.color = GetOrSetKey("theme-color", {.13, .13, .13})
|
|
* -> menu.colorChanaged := SetKey("theme-color", color)
|
|
* -> app:onExit := SaveAll({})
|
|
* -----------------------------------------------------------------------------
|
|
*
|
|
* Arbitrary write use case:----------------------------------------------------
|
|
* -> AllocRegistry()
|
|
* -> OpenReadWriteback("~/Registry/MyApp/Settings.dat")
|
|
* -> menu.color = GetOrSetKey("theme-color", {.13, .13, .13})
|
|
* -> menu.colorChanaged := SetKey("theme-color", color)
|
|
* -----------------------------------------------------------------------------
|
|
*
|
|
* Implementing a protected registry:-------------------------------------------
|
|
* -> AllocRegistry()
|
|
* -> Read("~/Registry/MyApp/PlayerProfile.dat") will read disk template to the cache, including one "genuine-player-setting"
|
|
* -> SetWriteModeCache()
|
|
* -> WriteKey("dev-secret-menu-enabled", {0})
|
|
* -> LockKey("dev-secret-menu-enabled"), no user write may pass to 'dev-reserved'
|
|
* -> SetWriteModeCache()
|
|
* -> SetKey("dev-secret-menu-enabled", {1}) originating from an evil script will fail, returning false
|
|
* -> SetKey("genuine-ux-setting", {2, 2}) will successfully write to cache
|
|
* -> SetKey("genuine-player-setting", {2, 2}) will be assumed to be legitimate, write to cache
|
|
* -> GetKey("genuine-ux-setting") will return {2, 2} from the cache
|
|
* -> GetKey("genuine-player-setting") will return {2, 2} from the cache
|
|
* -> SetKey("some-leftover-magic", {.3, .4, .3}) will successfully write to cache
|
|
* -> GetKey("some-leftover-magic") will return {.3, .4, .3} from the cache
|
|
* -> OpenSave({})
|
|
* -> SetKey("genuine-ux-setting", GetKey("genuine-ux-setting")) will specifically write genuine-ux-setting to disk
|
|
* -> var userSetting = GetKey("genuine-player-setting") will return genuine-player-setting from the cache
|
|
* -> if (userSetting is inbounds of good constraints) then SetKey("genuine-player-setting", userSetting [=GetKey("genuine-ux-setting")]) will write the cached value back to disk
|
|
* -> --
|
|
* -> Unload(), some-leftover-magic will be lost
|
|
*
|
|
*
|
|
* -> Prevent malicious usage of development variables while ensuring spurious references work with read only reference values
|
|
* -> You may write to the registry the default safe [key:value]s; for instance, zeroing out debug options
|
|
* -> You may call `LockKey(...)` to ensure spurious writes, like an unchecked server server command or user request, will not overload the protected variable
|
|
*
|
|
* -> Some developers may wish to validate the registry dataset before locking the registry,
|
|
* -> A general purpose vaildator, schema vaildator, or similar may wish to reset values back to a known good state (`SetWriteModeCache` + `SetKey`) before locking (`SetWriteModeNone`) an otherwise read only database
|
|
*
|
|
* -----------------------------------------------------------------------------
|
|
*
|
|
*/
|
|
class IRegistry
|
|
{
|
|
public:
|
|
enum class EWriteMode
|
|
{
|
|
eWriteModeLocked, ///
|
|
eWriteModeFileBuffer, /// Write to cache only
|
|
eWriteModeFileStream, /// [Default] write database to disk on each set, saving to cache
|
|
};
|
|
|
|
enum class EReadType
|
|
{
|
|
eClearCacheAndStore,
|
|
eStoreNew,
|
|
eStoreAll
|
|
};
|
|
|
|
virtual bool Read(const IOPath &path, EReadType read) = 0;
|
|
|
|
/**
|
|
* Puts the registry in read only mode
|
|
*/
|
|
virtual void SetWriteModeNone() = 0; /// read only, eqiv of ForEach((key) => { LockKey(key) }; SetWriteModeCache();
|
|
|
|
/**
|
|
* Puts the registry in an in memory only mode.
|
|
* -> Permit local read/write updates
|
|
* -> Never allows SetKeys to write manipulated sates to an IO buffer or stream until sanitized or otherwise explicitly written back
|
|
*/
|
|
virtual void SetWriteModeCache() = 0;
|
|
|
|
|
|
/**
|
|
* Puts the registry in a live write mode
|
|
*/
|
|
virtual void SetWriteModeStream(const AuOptional<IOPath> &path) = 0;
|
|
|
|
/**
|
|
* Puts the registry in a write-back-like mode
|
|
*/
|
|
virtual void SetWriteModeBuffered(const AuOptional<IOPath> &path) = 0;
|
|
virtual void WriteAllCacheBack() = 0; /// eqiv of ForEach((key) => { WriteKey(key, GetKey(key)); }; writes all updated cache entries back to io buffer or stream
|
|
virtual void SaveBuffered() = 0;
|
|
|
|
/**
|
|
* Saves the current state of the registry
|
|
*/
|
|
virtual void SaveAll(const AuOptional<IOPath> &path) = 0;
|
|
|
|
/**
|
|
* Further calls to SetKeys will; update a database on write, if buffered; or write to a buffer and serialize on flush (`SaveBuffered`)
|
|
*/
|
|
virtual void OpenSave(const IOPath &path, bool buffered = false) = 0;
|
|
|
|
/**
|
|
* equiv Read(path, EReadType::eClearCacheAndStore)
|
|
*/
|
|
virtual void OpenRead(const IOPath &path) = 0;
|
|
|
|
/**
|
|
* equiv Read(path, EReadType::eClearCacheAndStore), OpenSave(path, false)
|
|
*/
|
|
virtual void OpenReadWriteback(const IOPath &path) = 0;
|
|
|
|
virtual void CloseSave() = 0;
|
|
|
|
virtual bool KeyExists(const AuString &key, RegistryType &type) = 0;
|
|
virtual bool GetOrCreateKey(const AuString &key, const RegistryValue &def, RegistryValue &value) = 0;
|
|
|
|
/**
|
|
* Write a key, to cache or to disk
|
|
*/
|
|
virtual bool SetKey(const AuString &key, const RegistryValue &value) = 0;
|
|
|
|
/**
|
|
* Read key from cache
|
|
*/
|
|
virtual bool GetKey(const AuString &key, RegistryValue &value) = 0;
|
|
|
|
virtual void LockKey(const AuString &str) = 0;
|
|
virtual void UnlockKey(const AuString &str) = 0;
|
|
|
|
/**
|
|
* @deprecated
|
|
*/
|
|
inline void Lock()
|
|
{
|
|
SetWriteModeCache();
|
|
}
|
|
|
|
/**
|
|
* @deprecated
|
|
*/
|
|
inline void Unlock()
|
|
{
|
|
OpenSave({}, false);
|
|
}
|
|
};
|
|
} |