mirror of
https://codeberg.org/StreamGraph/StreamGraph.git
synced 2024-11-13 19:49:55 +01:00
new renderer persistence class to save options and configuration easier per renderer
This commit is contained in:
parent
a421535f11
commit
1ebcef1d0e
1 changed files with 137 additions and 0 deletions
137
classes/deck/renderer_persistence.gd
Normal file
137
classes/deck/renderer_persistence.gd
Normal file
|
@ -0,0 +1,137 @@
|
|||
class_name RendererPersistence
|
||||
## An interface for per-renderer persistent data.
|
||||
##
|
||||
## Allows renderers to store key/value data, split into namespaces (usually the renderer name)
|
||||
## and channels (files on a filesystem). For every namespace, a folder is created,
|
||||
## and populated with JSON files named after the channel name.
|
||||
|
||||
|
||||
const _BASE_PATH := "user://renderer_persistence/"
|
||||
const _FILE_TEMPLATE := "{namespace}/{channel}.json"
|
||||
|
||||
# Dictionary[String -> namespace, Dictionary[String -> channel, Variant]]
|
||||
static var _data: Dictionary
|
||||
|
||||
#region API
|
||||
## Initializes a namespace. Returns [code]false[/code] if the folder for the namespace didn't exist
|
||||
## before, useful for initializing defaults.
|
||||
static func init_namespace(name_space: String) -> bool:
|
||||
var n := name_space.validate_filename()
|
||||
if _data.get(n) != null:
|
||||
return true
|
||||
|
||||
var err := _create_namespace_folder(n)
|
||||
if err != OK:
|
||||
print("Could not create namespace: error %s" % err)
|
||||
return false
|
||||
_data[name_space] = {}
|
||||
return false
|
||||
|
||||
|
||||
## Returns the corresponding value for the given [param key] in the [param channel] storage.
|
||||
## If the key does not exist, returns [param default], or [code]null[/code] if the parameter is omitted.
|
||||
static func get_value(name_space: String, channel: String, key: String, default: Variant) -> Variant:
|
||||
_lazy_load_channel(name_space, channel)
|
||||
var validated_name := name_space.validate_filename()
|
||||
var validated_channel := channel.validate_filename()
|
||||
|
||||
return (_data[validated_name][validated_channel] as Dictionary).get(key, default)
|
||||
|
||||
|
||||
## Sets the value in the [param channel] storage at [param key] to [param value].
|
||||
static func set_value(name_space: String, channel: String, key: String, value: Variant) -> void:
|
||||
_lazy_load_channel(name_space, channel)
|
||||
var validated_name := name_space.validate_filename()
|
||||
var validated_channel := channel.validate_filename()
|
||||
|
||||
_data[validated_name][validated_channel][key] = value
|
||||
|
||||
|
||||
## Returns the corresponding value for the given [param key] in the [param channel] storage.
|
||||
## If the key does not exist, creates it in the storage, initializes it to [param default]
|
||||
## and returns it.
|
||||
static func get_or_create(name_space: String, channel: String, key: String, default: Variant) -> Variant:
|
||||
_lazy_load_channel(name_space, channel)
|
||||
var validated_name := name_space.validate_filename()
|
||||
var validated_channel := channel.validate_filename()
|
||||
|
||||
var channel_data: Dictionary = _data[validated_name][validated_channel]
|
||||
return _get_or_create(channel_data, key, default)
|
||||
|
||||
|
||||
## Erases an entry in the store by [param key] and returns its previous value,
|
||||
## or [code]null[/code] if it didn't exist.
|
||||
static func erase(name_space: String, channel: String, key: String) -> Variant:
|
||||
_lazy_load_channel(name_space, channel)
|
||||
var validated_name := name_space.validate_filename()
|
||||
var validated_channel := channel.validate_filename()
|
||||
|
||||
var channel_data: Dictionary = _data[validated_name][validated_channel]
|
||||
var ret = channel_data.get(key)
|
||||
channel_data.erase(key)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
## Commits the [param channel] to the filesystem. If [param channel] is empty,
|
||||
## commits all channels in the [param name_space].
|
||||
static func commit(name_space: String, channel: String = "") -> void:
|
||||
if !channel.is_empty():
|
||||
_commit_channel(name_space, channel)
|
||||
else:
|
||||
for c: String in _data[name_space]:
|
||||
_commit_channel(name_space, c)
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
static func _get_or_create(d: Dictionary, key: String, default: Variant) -> Variant:
|
||||
var r = d.get(key)
|
||||
if r == null:
|
||||
r = default
|
||||
d[key] = r
|
||||
|
||||
return r
|
||||
|
||||
|
||||
static func _create_namespace_folder(name_space: String) -> Error:
|
||||
return DirAccess.make_dir_recursive_absolute(_BASE_PATH.path_join(name_space))
|
||||
|
||||
|
||||
static func _lazy_load_channel(name_space: String, channel: String) -> void:
|
||||
var validated_name := name_space.validate_filename()
|
||||
var validated_channel := channel.validate_filename()
|
||||
if !_data.has(validated_name):
|
||||
print("Namespace %s is not initialized" % name_space)
|
||||
return
|
||||
|
||||
if (_data[validated_name] as Dictionary).has(validated_channel):
|
||||
return
|
||||
|
||||
var path := _BASE_PATH.path_join(_FILE_TEMPLATE.format(
|
||||
{
|
||||
"namespace": validated_name,
|
||||
"channel": validated_channel
|
||||
}))
|
||||
|
||||
var f := FileAccess.open(path, FileAccess.READ)
|
||||
if f == null:
|
||||
_data[validated_name][validated_channel] = {}
|
||||
return
|
||||
|
||||
var data = JSON.parse_string(f.get_as_text())
|
||||
_data[validated_name][validated_channel] = data
|
||||
|
||||
|
||||
static func _commit_channel(name_space: String, channel: String) -> void:
|
||||
_lazy_load_channel(name_space, channel)
|
||||
var validated_name := name_space.validate_filename()
|
||||
var validated_channel := channel.validate_filename()
|
||||
|
||||
var path := _BASE_PATH.path_join(_FILE_TEMPLATE.format(
|
||||
{
|
||||
"namespace": validated_name,
|
||||
"channel": validated_channel
|
||||
}))
|
||||
var f := FileAccess.open(path, FileAccess.WRITE)
|
||||
f.store_string(JSON.stringify(_data[validated_name][validated_channel], "\t", false))
|
Loading…
Reference in a new issue